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 =
30       abi::__cxa_demangle(pName.c_str(), /*buffer=*/0, &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   arena<bs> a;
45   Db db(a);
46   db.cv = 0;
47   db.ref = 0;
48   db.encoding_depth = 0;
49   db.parsed_ctor_dtor_cv = false;
50   db.tag_templates = true;
51   db.template_param.emplace_back(a);
52   db.fix_forward_references = false;
53   db.try_to_parse_template_args = true;
54   int internal_status = success;
55   demangle(pName, pName + pLength, db, internal_status);
56   if (internal_status == success && db.fix_forward_references &&
57       !db.template_param.empty() && !db.template_param.front().empty()) {
58     db.fix_forward_references = false;
59     db.tag_templates = false;
60     db.names.clear();
61     db.subs.clear();
62     demangle(pName, pName + pLength, db, internal_status);
63     if (db.fix_forward_references)
64       internal_status = invalid_mangled_name;
65   }
66 
67   if (internal_status != success) {
68     db.parsed_ctor_dtor_cv = false;
69   }
70   return db.parsed_ctor_dtor_cv;
71 }
72 
73 }  // namespace mcld
74