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
17 namespace mcld {
18
demangleName(const std::string & pName)19 std::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
isCtorOrDtor(const char * pName,size_t pLength)43 bool 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