• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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