Home | History | Annotate | Download | only in Support
      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 
     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 
     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