//===- Demangle.cpp -------------------------------------------------------===//
//
// The MCLinker Project
//
// This file is distributed under the University of Illinois Open Source
// License. See LICENSE.TXT for details.
//
//===----------------------------------------------------------------------===//
#include <mcld/Config/Config.h>
#include <mcld/Support/CXADemangle.tcc>
#include <mcld/Support/Demangle.h>
#ifdef HAVE_CXXABI_H
#include <cxxabi.h>
#endif
namespace mcld {
std::string demangleName(const std::string& pName) {
#ifdef HAVE_CXXABI_H
// Spoil names of symbols with C linkage, so use an heuristic approach to
// check if the name should be demangled.
if (pName.substr(0, 2) != "_Z")
return pName;
// __cxa_demangle needs manually handle the memory release, so we wrap
// it into this helper function.
size_t output_leng;
int status;
char* buffer = abi::__cxa_demangle(pName.c_str(), /*buffer=*/0,
&output_leng, &status);
if (status != 0) { // Failed
return pName;
}
std::string result(buffer);
free(buffer);
return result;
#else
return pName;
#endif
}
bool isCtorOrDtor(const char* pName, size_t pLength)
{
arena<bs> a;
Db db(a);
db.cv = 0;
db.ref = 0;
db.encoding_depth = 0;
db.parsed_ctor_dtor_cv = false;
db.tag_templates = true;
db.template_param.emplace_back(a);
db.fix_forward_references = false;
db.try_to_parse_template_args = true;
int internal_status = success;
demangle(pName, pName + pLength, db, internal_status);
if (internal_status == success &&
db.fix_forward_references &&
!db.template_param.empty() &&
!db.template_param.front().empty()) {
db.fix_forward_references = false;
db.tag_templates = false;
db.names.clear();
db.subs.clear();
demangle(pName, pName + pLength, db, internal_status);
if (db.fix_forward_references)
internal_status = invalid_mangled_name;
}
if (internal_status != success) {
db.parsed_ctor_dtor_cv = false;
}
return db.parsed_ctor_dtor_cv;
}
} // namespace mcld