1a790f0a8f3175183bea088389b3e4ae41813e192Stephen Hines//===- Demangle.cpp -------------------------------------------------------===//
2a790f0a8f3175183bea088389b3e4ae41813e192Stephen Hines//
3a790f0a8f3175183bea088389b3e4ae41813e192Stephen Hines//                     The MCLinker Project
4a790f0a8f3175183bea088389b3e4ae41813e192Stephen Hines//
5a790f0a8f3175183bea088389b3e4ae41813e192Stephen Hines// This file is distributed under the University of Illinois Open Source
6a790f0a8f3175183bea088389b3e4ae41813e192Stephen Hines// License. See LICENSE.TXT for details.
7a790f0a8f3175183bea088389b3e4ae41813e192Stephen Hines//
8a790f0a8f3175183bea088389b3e4ae41813e192Stephen Hines//===----------------------------------------------------------------------===//
9a790f0a8f3175183bea088389b3e4ae41813e192Stephen Hines#include <mcld/Config/Config.h>
10a790f0a8f3175183bea088389b3e4ae41813e192Stephen Hines#include <mcld/Support/CXADemangle.tcc>
11a790f0a8f3175183bea088389b3e4ae41813e192Stephen Hines#include <mcld/Support/Demangle.h>
12a790f0a8f3175183bea088389b3e4ae41813e192Stephen Hines
13a790f0a8f3175183bea088389b3e4ae41813e192Stephen Hines#ifdef HAVE_CXXABI_H
14a790f0a8f3175183bea088389b3e4ae41813e192Stephen Hines#include <cxxabi.h>
15a790f0a8f3175183bea088389b3e4ae41813e192Stephen Hines#endif
16a790f0a8f3175183bea088389b3e4ae41813e192Stephen Hines
17a790f0a8f3175183bea088389b3e4ae41813e192Stephen Hinesnamespace mcld {
18a790f0a8f3175183bea088389b3e4ae41813e192Stephen Hines
19a790f0a8f3175183bea088389b3e4ae41813e192Stephen Hinesstd::string demangleName(const std::string& pName) {
20a790f0a8f3175183bea088389b3e4ae41813e192Stephen Hines#ifdef HAVE_CXXABI_H
21a790f0a8f3175183bea088389b3e4ae41813e192Stephen Hines  // Spoil names of symbols with C linkage, so use an heuristic approach to
22a790f0a8f3175183bea088389b3e4ae41813e192Stephen Hines  // check if the name should be demangled.
23a790f0a8f3175183bea088389b3e4ae41813e192Stephen Hines  if (pName.substr(0, 2) != "_Z")
24a790f0a8f3175183bea088389b3e4ae41813e192Stephen Hines    return pName;
25a790f0a8f3175183bea088389b3e4ae41813e192Stephen Hines  // __cxa_demangle needs manually handle the memory release, so we wrap
26a790f0a8f3175183bea088389b3e4ae41813e192Stephen Hines  // it into this helper function.
27a790f0a8f3175183bea088389b3e4ae41813e192Stephen Hines  size_t output_leng;
28a790f0a8f3175183bea088389b3e4ae41813e192Stephen Hines  int status;
29a790f0a8f3175183bea088389b3e4ae41813e192Stephen Hines  char* buffer = abi::__cxa_demangle(pName.c_str(), /*buffer=*/0,
30a790f0a8f3175183bea088389b3e4ae41813e192Stephen Hines                                     &output_leng, &status);
31a790f0a8f3175183bea088389b3e4ae41813e192Stephen Hines  if (status != 0) { // Failed
32a790f0a8f3175183bea088389b3e4ae41813e192Stephen Hines    return pName;
33a790f0a8f3175183bea088389b3e4ae41813e192Stephen Hines  }
34a790f0a8f3175183bea088389b3e4ae41813e192Stephen Hines  std::string result(buffer);
35a790f0a8f3175183bea088389b3e4ae41813e192Stephen Hines  free(buffer);
36a790f0a8f3175183bea088389b3e4ae41813e192Stephen Hines
37a790f0a8f3175183bea088389b3e4ae41813e192Stephen Hines  return result;
38a790f0a8f3175183bea088389b3e4ae41813e192Stephen Hines#else
39a790f0a8f3175183bea088389b3e4ae41813e192Stephen Hines  return pName;
40a790f0a8f3175183bea088389b3e4ae41813e192Stephen Hines#endif
41a790f0a8f3175183bea088389b3e4ae41813e192Stephen Hines}
42a790f0a8f3175183bea088389b3e4ae41813e192Stephen Hines
43a790f0a8f3175183bea088389b3e4ae41813e192Stephen Hinesbool isCtorOrDtor(const char* pName, size_t pLength)
44a790f0a8f3175183bea088389b3e4ae41813e192Stephen Hines{
45a790f0a8f3175183bea088389b3e4ae41813e192Stephen Hines  arena<bs> a;
46a790f0a8f3175183bea088389b3e4ae41813e192Stephen Hines  Db db(a);
47a790f0a8f3175183bea088389b3e4ae41813e192Stephen Hines  db.cv = 0;
48a790f0a8f3175183bea088389b3e4ae41813e192Stephen Hines  db.ref = 0;
49a790f0a8f3175183bea088389b3e4ae41813e192Stephen Hines  db.encoding_depth = 0;
50a790f0a8f3175183bea088389b3e4ae41813e192Stephen Hines  db.parsed_ctor_dtor_cv = false;
51a790f0a8f3175183bea088389b3e4ae41813e192Stephen Hines  db.tag_templates = true;
52a790f0a8f3175183bea088389b3e4ae41813e192Stephen Hines  db.template_param.emplace_back(a);
53a790f0a8f3175183bea088389b3e4ae41813e192Stephen Hines  db.fix_forward_references = false;
54a790f0a8f3175183bea088389b3e4ae41813e192Stephen Hines  db.try_to_parse_template_args = true;
55a790f0a8f3175183bea088389b3e4ae41813e192Stephen Hines  int internal_status = success;
56a790f0a8f3175183bea088389b3e4ae41813e192Stephen Hines  demangle(pName, pName + pLength, db, internal_status);
57a790f0a8f3175183bea088389b3e4ae41813e192Stephen Hines  if (internal_status == success &&
58a790f0a8f3175183bea088389b3e4ae41813e192Stephen Hines      db.fix_forward_references &&
59a790f0a8f3175183bea088389b3e4ae41813e192Stephen Hines      !db.template_param.empty() &&
60a790f0a8f3175183bea088389b3e4ae41813e192Stephen Hines      !db.template_param.front().empty()) {
61a790f0a8f3175183bea088389b3e4ae41813e192Stephen Hines    db.fix_forward_references = false;
62a790f0a8f3175183bea088389b3e4ae41813e192Stephen Hines    db.tag_templates = false;
63a790f0a8f3175183bea088389b3e4ae41813e192Stephen Hines    db.names.clear();
64a790f0a8f3175183bea088389b3e4ae41813e192Stephen Hines    db.subs.clear();
65a790f0a8f3175183bea088389b3e4ae41813e192Stephen Hines    demangle(pName, pName + pLength, db, internal_status);
66a790f0a8f3175183bea088389b3e4ae41813e192Stephen Hines    if (db.fix_forward_references)
67a790f0a8f3175183bea088389b3e4ae41813e192Stephen Hines      internal_status = invalid_mangled_name;
68a790f0a8f3175183bea088389b3e4ae41813e192Stephen Hines  }
69a790f0a8f3175183bea088389b3e4ae41813e192Stephen Hines
70a790f0a8f3175183bea088389b3e4ae41813e192Stephen Hines  if (internal_status != success) {
71a790f0a8f3175183bea088389b3e4ae41813e192Stephen Hines    db.parsed_ctor_dtor_cv = false;
72a790f0a8f3175183bea088389b3e4ae41813e192Stephen Hines  }
73a790f0a8f3175183bea088389b3e4ae41813e192Stephen Hines  return db.parsed_ctor_dtor_cv;
74a790f0a8f3175183bea088389b3e4ae41813e192Stephen Hines}
75a790f0a8f3175183bea088389b3e4ae41813e192Stephen Hines
76a790f0a8f3175183bea088389b3e4ae41813e192Stephen Hines} // namespace mcld
77