Demangle.cpp revision 0dea6bc96bb52346737966839ac68644f7939f58
10dea6bc96bb52346737966839ac68644f7939f58Stephen Hines//===- Demangle.cpp -------------------------------------------------------===//
20dea6bc96bb52346737966839ac68644f7939f58Stephen Hines//
30dea6bc96bb52346737966839ac68644f7939f58Stephen Hines//                     The MCLinker Project
40dea6bc96bb52346737966839ac68644f7939f58Stephen Hines//
50dea6bc96bb52346737966839ac68644f7939f58Stephen Hines// This file is distributed under the University of Illinois Open Source
60dea6bc96bb52346737966839ac68644f7939f58Stephen Hines// License. See LICENSE.TXT for details.
70dea6bc96bb52346737966839ac68644f7939f58Stephen Hines//
80dea6bc96bb52346737966839ac68644f7939f58Stephen Hines//===----------------------------------------------------------------------===//
90dea6bc96bb52346737966839ac68644f7939f58Stephen Hines#include <mcld/Config/Config.h>
100dea6bc96bb52346737966839ac68644f7939f58Stephen Hines#include <mcld/Support/CXADemangle.tcc>
110dea6bc96bb52346737966839ac68644f7939f58Stephen Hines#include <mcld/Support/Demangle.h>
120dea6bc96bb52346737966839ac68644f7939f58Stephen Hines
130dea6bc96bb52346737966839ac68644f7939f58Stephen Hines#ifdef HAVE_CXXABI_H
140dea6bc96bb52346737966839ac68644f7939f58Stephen Hines#include <cxxabi.h>
150dea6bc96bb52346737966839ac68644f7939f58Stephen Hines#endif
160dea6bc96bb52346737966839ac68644f7939f58Stephen Hines
170dea6bc96bb52346737966839ac68644f7939f58Stephen Hinesnamespace mcld {
180dea6bc96bb52346737966839ac68644f7939f58Stephen Hines
190dea6bc96bb52346737966839ac68644f7939f58Stephen Hinesstd::string demangleName(const std::string& pName) {
200dea6bc96bb52346737966839ac68644f7939f58Stephen Hines#ifdef HAVE_CXXABI_H
210dea6bc96bb52346737966839ac68644f7939f58Stephen Hines  // Spoil names of symbols with C linkage, so use an heuristic approach to
220dea6bc96bb52346737966839ac68644f7939f58Stephen Hines  // check if the name should be demangled.
230dea6bc96bb52346737966839ac68644f7939f58Stephen Hines  if (pName.substr(0, 2) != "_Z")
240dea6bc96bb52346737966839ac68644f7939f58Stephen Hines    return pName;
250dea6bc96bb52346737966839ac68644f7939f58Stephen Hines  // __cxa_demangle needs manually handle the memory release, so we wrap
260dea6bc96bb52346737966839ac68644f7939f58Stephen Hines  // it into this helper function.
270dea6bc96bb52346737966839ac68644f7939f58Stephen Hines  size_t output_leng;
280dea6bc96bb52346737966839ac68644f7939f58Stephen Hines  int status;
290dea6bc96bb52346737966839ac68644f7939f58Stephen Hines  char* buffer = abi::__cxa_demangle(pName.c_str(), /*buffer=*/0,
300dea6bc96bb52346737966839ac68644f7939f58Stephen Hines                                     &output_leng, &status);
310dea6bc96bb52346737966839ac68644f7939f58Stephen Hines  if (status != 0) { // Failed
320dea6bc96bb52346737966839ac68644f7939f58Stephen Hines    return pName;
330dea6bc96bb52346737966839ac68644f7939f58Stephen Hines  }
340dea6bc96bb52346737966839ac68644f7939f58Stephen Hines  std::string result(buffer);
350dea6bc96bb52346737966839ac68644f7939f58Stephen Hines  free(buffer);
360dea6bc96bb52346737966839ac68644f7939f58Stephen Hines
370dea6bc96bb52346737966839ac68644f7939f58Stephen Hines  return result;
380dea6bc96bb52346737966839ac68644f7939f58Stephen Hines#else
390dea6bc96bb52346737966839ac68644f7939f58Stephen Hines  return pName;
400dea6bc96bb52346737966839ac68644f7939f58Stephen Hines#endif
410dea6bc96bb52346737966839ac68644f7939f58Stephen Hines}
420dea6bc96bb52346737966839ac68644f7939f58Stephen Hines
430dea6bc96bb52346737966839ac68644f7939f58Stephen Hinesbool isCtorOrDtor(const char* pName, size_t pLength)
440dea6bc96bb52346737966839ac68644f7939f58Stephen Hines{
450dea6bc96bb52346737966839ac68644f7939f58Stephen Hines  arena<bs> a;
460dea6bc96bb52346737966839ac68644f7939f58Stephen Hines  Db db(a);
470dea6bc96bb52346737966839ac68644f7939f58Stephen Hines  db.cv = 0;
480dea6bc96bb52346737966839ac68644f7939f58Stephen Hines  db.ref = 0;
490dea6bc96bb52346737966839ac68644f7939f58Stephen Hines  db.encoding_depth = 0;
500dea6bc96bb52346737966839ac68644f7939f58Stephen Hines  db.parsed_ctor_dtor_cv = false;
510dea6bc96bb52346737966839ac68644f7939f58Stephen Hines  db.tag_templates = true;
520dea6bc96bb52346737966839ac68644f7939f58Stephen Hines  db.template_param.emplace_back(a);
530dea6bc96bb52346737966839ac68644f7939f58Stephen Hines  db.fix_forward_references = false;
540dea6bc96bb52346737966839ac68644f7939f58Stephen Hines  db.try_to_parse_template_args = true;
550dea6bc96bb52346737966839ac68644f7939f58Stephen Hines  int internal_status = success;
560dea6bc96bb52346737966839ac68644f7939f58Stephen Hines  demangle(pName, pName + pLength, db, internal_status);
570dea6bc96bb52346737966839ac68644f7939f58Stephen Hines  if (internal_status == success &&
580dea6bc96bb52346737966839ac68644f7939f58Stephen Hines      db.fix_forward_references &&
590dea6bc96bb52346737966839ac68644f7939f58Stephen Hines      !db.template_param.empty() &&
600dea6bc96bb52346737966839ac68644f7939f58Stephen Hines      !db.template_param.front().empty()) {
610dea6bc96bb52346737966839ac68644f7939f58Stephen Hines    db.fix_forward_references = false;
620dea6bc96bb52346737966839ac68644f7939f58Stephen Hines    db.tag_templates = false;
630dea6bc96bb52346737966839ac68644f7939f58Stephen Hines    db.names.clear();
640dea6bc96bb52346737966839ac68644f7939f58Stephen Hines    db.subs.clear();
650dea6bc96bb52346737966839ac68644f7939f58Stephen Hines    demangle(pName, pName + pLength, db, internal_status);
660dea6bc96bb52346737966839ac68644f7939f58Stephen Hines    if (db.fix_forward_references)
670dea6bc96bb52346737966839ac68644f7939f58Stephen Hines      internal_status = invalid_mangled_name;
680dea6bc96bb52346737966839ac68644f7939f58Stephen Hines  }
690dea6bc96bb52346737966839ac68644f7939f58Stephen Hines
700dea6bc96bb52346737966839ac68644f7939f58Stephen Hines  if (internal_status != success) {
710dea6bc96bb52346737966839ac68644f7939f58Stephen Hines    db.parsed_ctor_dtor_cv = false;
720dea6bc96bb52346737966839ac68644f7939f58Stephen Hines  }
730dea6bc96bb52346737966839ac68644f7939f58Stephen Hines  return db.parsed_ctor_dtor_cv;
740dea6bc96bb52346737966839ac68644f7939f58Stephen Hines}
750dea6bc96bb52346737966839ac68644f7939f58Stephen Hines
760dea6bc96bb52346737966839ac68644f7939f58Stephen Hines} // namespace mcld
77