Index: lld/COFF/CMakeLists.txt =================================================================== --- lld/COFF/CMakeLists.txt +++ lld/COFF/CMakeLists.txt @@ -30,6 +30,7 @@ DebugInfoCodeView DebugInfoMSF DebugInfoPDB + Demangle LibDriver LTO MC Index: lld/COFF/Symbols.cpp =================================================================== --- lld/COFF/Symbols.cpp +++ lld/COFF/Symbols.cpp @@ -12,6 +12,7 @@ #include "lld/Common/Memory.h" #include "lld/Common/Strings.h" #include "llvm/ADT/STLExtras.h" +#include "llvm/Demangle/Demangle.h" #include "llvm/Support/Debug.h" #include "llvm/Support/raw_ostream.h" @@ -26,26 +27,22 @@ "symbols should be optimized for memory usage"); // Returns a symbol name for an error message. -static std::string demangle(StringRef symName) { +static std::string maybeDemangleSymbol(StringRef symName) { if (config->demangle) { - if (Optional s = demangleMSVC(symName)) - return *s; - if (config->mingw) { - StringRef demangleInput = symName; - std::string prefix; - if (demangleInput.consume_front("__imp_")) - prefix = "__declspec(dllimport) "; - if (config->machine == I386) - demangleInput.consume_front("_"); - if (Optional s = demangleItanium(demangleInput)) - return prefix + *s; - } + std::string prefix; + StringRef demangleInput = symName; + if (demangleInput.consume_front("__imp_")) + prefix = "__declspec(dllimport) "; + if (Optional s = tryDemangle(demangleInput)) + return prefix + *s; } return symName; } -std::string toString(coff::Symbol &b) { return demangle(b.getName()); } +std::string toString(coff::Symbol &b) { + return maybeDemangleSymbol(b.getName()); +} std::string toCOFFString(const Archive::Symbol &b) { - return demangle(b.getName()); + return maybeDemangleSymbol(b.getName()); } namespace coff { Index: lld/Common/CMakeLists.txt =================================================================== --- lld/Common/CMakeLists.txt +++ lld/Common/CMakeLists.txt @@ -46,7 +46,6 @@ LINK_COMPONENTS Codegen Core - Demangle MC Option Support Index: lld/Common/Strings.cpp =================================================================== --- lld/Common/Strings.cpp +++ lld/Common/Strings.cpp @@ -9,7 +9,6 @@ #include "lld/Common/Strings.h" #include "lld/Common/ErrorHandler.h" #include "lld/Common/LLVM.h" -#include "llvm/Demangle/Demangle.h" #include "llvm/Support/GlobPattern.h" #include #include @@ -18,41 +17,6 @@ using namespace llvm; using namespace lld; -// Returns the demangled C++ symbol name for Name. -Optional lld::demangleItanium(StringRef name) { - // itaniumDemangle 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 itaniumDemangle 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 None; - - char *buf = itaniumDemangle(name.str().c_str(), nullptr, nullptr, nullptr); - if (!buf) - return None; - std::string s(buf); - free(buf); - return s; -} - -Optional lld::demangleMSVC(StringRef name) { - std::string prefix; - if (name.consume_front("__imp_")) - prefix = "__declspec(dllimport) "; - - // Demangle only C++ names. - if (!name.startswith("?")) - return None; - - char *buf = microsoftDemangle(name.str().c_str(), nullptr, nullptr, nullptr); - if (!buf) - return None; - std::string s(buf); - free(buf); - return prefix + s; -} - StringMatcher::StringMatcher(ArrayRef pat) { for (StringRef s : pat) { Expected pat = GlobPattern::create(s); Index: lld/ELF/CMakeLists.txt =================================================================== --- lld/ELF/CMakeLists.txt +++ lld/ELF/CMakeLists.txt @@ -51,6 +51,7 @@ BitWriter Core DebugInfoDWARF + Demangle LTO MC Object Index: lld/ELF/SymbolTable.cpp =================================================================== --- lld/ELF/SymbolTable.cpp +++ lld/ELF/SymbolTable.cpp @@ -22,6 +22,7 @@ #include "lld/Common/Memory.h" #include "lld/Common/Strings.h" #include "llvm/ADT/STLExtras.h" +#include "llvm/Demangle/Demangle.h" using namespace llvm; using namespace llvm::object; @@ -123,10 +124,7 @@ for (Symbol *sym : symVector) { if (!sym->isDefined() && !sym->isCommon()) continue; - if (Optional s = demangleItanium(sym->getName())) - (*demangledSyms)[*s].push_back(sym); - else - (*demangledSyms)[sym->getName()].push_back(sym); + (*demangledSyms)[demangle(sym->getName())].push_back(sym); } } return *demangledSyms; Index: lld/ELF/Symbols.cpp =================================================================== --- lld/ELF/Symbols.cpp +++ lld/ELF/Symbols.cpp @@ -16,6 +16,7 @@ #include "lld/Common/ErrorHandler.h" #include "lld/Common/Strings.h" #include "llvm/ADT/STLExtras.h" +#include "llvm/Demangle/Demangle.h" #include "llvm/Support/Path.h" #include @@ -43,16 +44,17 @@ Defined *ElfSym::tlsModuleBase; // Returns a symbol for an error message. -static std::string demangle(StringRef symName) { +static std::string maybeDemangleSymbol(StringRef symName) { if (config->demangle) - if (Optional s = demangleItanium(symName)) - return *s; + return demangle(symName); return symName; } namespace lld { -std::string toString(const Symbol &b) { return demangle(b.getName()); } +std::string toString(const Symbol &b) { + return maybeDemangleSymbol(b.getName()); +} std::string toELFString(const Archive::Symbol &b) { - return demangle(b.getName()); + return maybeDemangleSymbol(b.getName()); } } // namespace lld Index: lld/include/lld/Common/Strings.h =================================================================== --- lld/include/lld/Common/Strings.h +++ lld/include/lld/Common/Strings.h @@ -10,17 +10,12 @@ #define LLD_STRINGS_H #include "llvm/ADT/ArrayRef.h" -#include "llvm/ADT/Optional.h" #include "llvm/ADT/StringRef.h" #include "llvm/Support/GlobPattern.h" #include #include namespace lld { -// Returns a demangled C++ symbol name. If Name is not a mangled -// name, it returns Optional::None. -llvm::Optional demangleItanium(llvm::StringRef name); -llvm::Optional demangleMSVC(llvm::StringRef s); std::vector parseHex(llvm::StringRef s); bool isValidCIdentifier(llvm::StringRef s); Index: lld/wasm/Symbols.h =================================================================== --- lld/wasm/Symbols.h +++ lld/wasm/Symbols.h @@ -542,7 +542,6 @@ // Returns a symbol name for an error message. std::string toString(const wasm::Symbol &sym); std::string toString(wasm::Symbol::Kind kind); -std::string maybeDemangleSymbol(StringRef name); } // namespace lld Index: lld/wasm/Symbols.cpp =================================================================== --- lld/wasm/Symbols.cpp +++ lld/wasm/Symbols.cpp @@ -16,6 +16,7 @@ #include "OutputSegment.h" #include "lld/Common/ErrorHandler.h" #include "lld/Common/Strings.h" +#include "llvm/Demangle/Demangle.h" #define DEBUG_TYPE "lld" @@ -299,14 +300,7 @@ void LazySymbol::fetch() { cast(file)->addMember(&archiveSymbol); } std::string lld::toString(const wasm::Symbol &sym) { - return lld::maybeDemangleSymbol(sym.getName()); -} - -std::string lld::maybeDemangleSymbol(StringRef name) { - if (config->demangle) - if (Optional s = demangleItanium(name)) - return *s; - return name; + return demangle(sym.getName()); } std::string lld::toString(wasm::Symbol::Kind kind) { Index: lld/wasm/SyntheticSections.cpp =================================================================== --- lld/wasm/SyntheticSections.cpp +++ lld/wasm/SyntheticSections.cpp @@ -17,6 +17,7 @@ #include "InputGlobal.h" #include "OutputSegment.h" #include "SymbolTable.h" +#include "llvm/Demangle/Demangle.h" #include "llvm/Support/Path.h" using namespace llvm; @@ -524,7 +525,7 @@ if (!f->getDebugName().empty()) { writeStr(sub.os, f->getDebugName(), "symbol name"); } else { - writeStr(sub.os, maybeDemangleSymbol(f->getName()), "symbol name"); + writeStr(sub.os, demangle(f->getName()), "symbol name"); } } } Index: llvm/include/llvm/Demangle/Demangle.h =================================================================== --- llvm/include/llvm/Demangle/Demangle.h +++ llvm/include/llvm/Demangle/Demangle.h @@ -9,6 +9,7 @@ #ifndef LLVM_DEMANGLE_DEMANGLE_H #define LLVM_DEMANGLE_DEMANGLE_H +#include "llvm/ADT/Optional.h" #include #include @@ -43,6 +44,12 @@ /// demangling occurred. std::string demangle(const std::string &MangledName); +/// Attempt to demangle a string using different demangling schemes. +/// The function uses heuristics to determine which demangling scheme to use. +/// \param MangledName - reference to string to demangle. +/// \returns - an optional demangled string. +Optional tryDemangle(const std::string &MangledName); + /// "Partial" demangler. This supports demangling a string into an AST /// (typically an intermediate stage in itaniumDemangle) and querying certain /// properties or partially printing the demangled name. Index: llvm/lib/Demangle/Demangle.cpp =================================================================== --- llvm/lib/Demangle/Demangle.cpp +++ llvm/lib/Demangle/Demangle.cpp @@ -19,7 +19,7 @@ return Pos > 0 && Pos <= 4 && MangledName[Pos] == 'Z'; } -std::string llvm::demangle(const std::string &MangledName) { +llvm::Optional llvm::tryDemangle(const std::string &MangledName) { char *Demangled; if (isItaniumEncoding(MangledName)) Demangled = itaniumDemangle(MangledName.c_str(), nullptr, nullptr, nullptr); @@ -28,9 +28,16 @@ microsoftDemangle(MangledName.c_str(), nullptr, nullptr, nullptr); if (!Demangled) - return MangledName; + return None; std::string Ret = Demangled; free(Demangled); return Ret; } + +std::string llvm::demangle(const std::string &MangledName) { + llvm::Optional Ret = tryDemangle(MangledName); + if (!Ret) + return MangledName; + return *Ret; +}