summaryrefslogtreecommitdiffstats
path: root/lld/ELF/Strings.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'lld/ELF/Strings.cpp')
-rw-r--r--lld/ELF/Strings.cpp28
1 files changed, 28 insertions, 0 deletions
diff --git a/lld/ELF/Strings.cpp b/lld/ELF/Strings.cpp
index 21d7f428e85..0c21e8819d6 100644
--- a/lld/ELF/Strings.cpp
+++ b/lld/ELF/Strings.cpp
@@ -11,8 +11,13 @@
#include "Error.h"
#include "llvm/ADT/StringRef.h"
#include "llvm/ADT/Twine.h"
+#include "llvm/Config/config.h"
#include <algorithm>
+#ifdef HAVE_CXXABI_H
+#include <cxxabi.h>
+#endif
+
using namespace llvm;
using namespace lld;
using namespace lld::elf;
@@ -68,3 +73,26 @@ bool elf::isValidCIdentifier(StringRef S) {
return !S.empty() && isAlpha(S[0]) &&
std::all_of(S.begin() + 1, S.end(), isAlnum);
}
+
+// Returns the demangled C++ symbol name for Name.
+std::string elf::demangle(StringRef Name) {
+#if !defined(HAVE_CXXABI_H)
+ return Name;
+#else
+ // __cxa_demangle can be used to demangle strings other than symbol
+ // names which do not necessarily start with "_Z". Name can be
+ // either a C or C++ symbol. Don't call __cxa_demangle if the name
+ // does not look like a C++ symbol name to avoid getting unexpected
+ // result for a C symbol that happens to match a mangled type name.
+ if (!Name.startswith("_Z"))
+ return Name;
+
+ char *Buf =
+ abi::__cxa_demangle(Name.str().c_str(), nullptr, nullptr, nullptr);
+ if (!Buf)
+ return Name;
+ std::string S(Buf);
+ free(Buf);
+ return S;
+#endif
+}
OpenPOWER on IntegriCloud