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//===----------------------------------------------------------------------===//
937b74a387bb3993387029859c2d9d051c41c724eStephen Hines#include "mcld/Config/Config.h"
1037b74a387bb3993387029859c2d9d051c41c724eStephen Hines#include "mcld/Support/CXADemangle.tcc"
1137b74a387bb3993387029859c2d9d051c41c724eStephen 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;
2937b74a387bb3993387029859c2d9d051c41c724eStephen Hines  char* buffer =
3037b74a387bb3993387029859c2d9d051c41c724eStephen Hines      abi::__cxa_demangle(pName.c_str(), /*buffer=*/0, &output_leng, &status);
3137b74a387bb3993387029859c2d9d051c41c724eStephen 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
4337b74a387bb3993387029859c2d9d051c41c724eStephen Hinesbool isCtorOrDtor(const char* pName, size_t pLength) {
440dea6bc96bb52346737966839ac68644f7939f58Stephen Hines  arena<bs> a;
450dea6bc96bb52346737966839ac68644f7939f58Stephen Hines  Db db(a);
460dea6bc96bb52346737966839ac68644f7939f58Stephen Hines  db.cv = 0;
470dea6bc96bb52346737966839ac68644f7939f58Stephen Hines  db.ref = 0;
480dea6bc96bb52346737966839ac68644f7939f58Stephen Hines  db.encoding_depth = 0;
490dea6bc96bb52346737966839ac68644f7939f58Stephen Hines  db.parsed_ctor_dtor_cv = false;
500dea6bc96bb52346737966839ac68644f7939f58Stephen Hines  db.tag_templates = true;
510dea6bc96bb52346737966839ac68644f7939f58Stephen Hines  db.template_param.emplace_back(a);
520dea6bc96bb52346737966839ac68644f7939f58Stephen Hines  db.fix_forward_references = false;
530dea6bc96bb52346737966839ac68644f7939f58Stephen Hines  db.try_to_parse_template_args = true;
540dea6bc96bb52346737966839ac68644f7939f58Stephen Hines  int internal_status = success;
550dea6bc96bb52346737966839ac68644f7939f58Stephen Hines  demangle(pName, pName + pLength, db, internal_status);
5637b74a387bb3993387029859c2d9d051c41c724eStephen Hines  if (internal_status == success && db.fix_forward_references &&
5737b74a387bb3993387029859c2d9d051c41c724eStephen Hines      !db.template_param.empty() && !db.template_param.front().empty()) {
580dea6bc96bb52346737966839ac68644f7939f58Stephen Hines    db.fix_forward_references = false;
590dea6bc96bb52346737966839ac68644f7939f58Stephen Hines    db.tag_templates = false;
600dea6bc96bb52346737966839ac68644f7939f58Stephen Hines    db.names.clear();
610dea6bc96bb52346737966839ac68644f7939f58Stephen Hines    db.subs.clear();
620dea6bc96bb52346737966839ac68644f7939f58Stephen Hines    demangle(pName, pName + pLength, db, internal_status);
630dea6bc96bb52346737966839ac68644f7939f58Stephen Hines    if (db.fix_forward_references)
640dea6bc96bb52346737966839ac68644f7939f58Stephen Hines      internal_status = invalid_mangled_name;
650dea6bc96bb52346737966839ac68644f7939f58Stephen Hines  }
660dea6bc96bb52346737966839ac68644f7939f58Stephen Hines
670dea6bc96bb52346737966839ac68644f7939f58Stephen Hines  if (internal_status != success) {
680dea6bc96bb52346737966839ac68644f7939f58Stephen Hines    db.parsed_ctor_dtor_cv = false;
690dea6bc96bb52346737966839ac68644f7939f58Stephen Hines  }
700dea6bc96bb52346737966839ac68644f7939f58Stephen Hines  return db.parsed_ctor_dtor_cv;
710dea6bc96bb52346737966839ac68644f7939f58Stephen Hines}
720dea6bc96bb52346737966839ac68644f7939f58Stephen Hines
7337b74a387bb3993387029859c2d9d051c41c724eStephen Hines}  // namespace mcld
74