Demangle.cpp revision a790f0a8f3175183bea088389b3e4ae41813e192
1//===- Demangle.cpp -------------------------------------------------------===//
2//
3//                     The MCLinker Project
4//
5// This file is distributed under the University of Illinois Open Source
6// License. See LICENSE.TXT for details.
7//
8//===----------------------------------------------------------------------===//
9#include <mcld/Config/Config.h>
10#include <mcld/Support/CXADemangle.tcc>
11#include <mcld/Support/Demangle.h>
12
13#ifdef HAVE_CXXABI_H
14#include <cxxabi.h>
15#endif
16
17namespace mcld {
18
19std::string demangleName(const std::string& pName) {
20#ifdef HAVE_CXXABI_H
21  // Spoil names of symbols with C linkage, so use an heuristic approach to
22  // check if the name should be demangled.
23  if (pName.substr(0, 2) != "_Z")
24    return pName;
25  // __cxa_demangle needs manually handle the memory release, so we wrap
26  // it into this helper function.
27  size_t output_leng;
28  int status;
29  char* buffer = abi::__cxa_demangle(pName.c_str(), /*buffer=*/0,
30                                     &output_leng, &status);
31  if (status != 0) { // Failed
32    return pName;
33  }
34  std::string result(buffer);
35  free(buffer);
36
37  return result;
38#else
39  return pName;
40#endif
41}
42
43bool isCtorOrDtor(const char* pName, size_t pLength)
44{
45  arena<bs> a;
46  Db db(a);
47  db.cv = 0;
48  db.ref = 0;
49  db.encoding_depth = 0;
50  db.parsed_ctor_dtor_cv = false;
51  db.tag_templates = true;
52  db.template_param.emplace_back(a);
53  db.fix_forward_references = false;
54  db.try_to_parse_template_args = true;
55  int internal_status = success;
56  demangle(pName, pName + pLength, db, internal_status);
57  if (internal_status == success &&
58      db.fix_forward_references &&
59      !db.template_param.empty() &&
60      !db.template_param.front().empty()) {
61    db.fix_forward_references = false;
62    db.tag_templates = false;
63    db.names.clear();
64    db.subs.clear();
65    demangle(pName, pName + pLength, db, internal_status);
66    if (db.fix_forward_references)
67      internal_status = invalid_mangled_name;
68  }
69
70  if (internal_status != success) {
71    db.parsed_ctor_dtor_cv = false;
72  }
73  return db.parsed_ctor_dtor_cv;
74}
75
76} // namespace mcld
77