diff --git a/lld/COFF/Symbols.cpp b/lld/COFF/Symbols.cpp --- a/lld/COFF/Symbols.cpp +++ b/lld/COFF/Symbols.cpp @@ -36,9 +36,9 @@ StringRef demangleInput = prefixless; if (config->machine == I386) demangleInput.consume_front("_"); - std::string demangled = demangle(std::string(demangleInput)); + std::string demangled = demangle(demangleInput, true); if (demangled != demangleInput) - return prefix + demangle(std::string(demangleInput)); + return prefix + demangle(demangleInput, true); return (prefix + prefixless).str(); } return std::string(symName); diff --git a/lld/Common/Strings.cpp b/lld/Common/Strings.cpp --- a/lld/Common/Strings.cpp +++ b/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/FileSystem.h" #include "llvm/Support/GlobPattern.h" #include @@ -19,18 +18,6 @@ using namespace llvm; using namespace lld; -// Returns the demangled C++ symbol name for name. -std::string lld::demangleItanium(StringRef name) { - // demangleItanium() can be called for all symbols. Only demangle C++ symbols, - // to avoid getting unexpected result for a C symbol that happens to match a - // mangled type name such as "Pi" (which would demangle to "int*"). - if (!name.startswith("_Z") && !name.startswith("__Z") && - !name.startswith("___Z") && !name.startswith("____Z")) - return std::string(name); - - return demangle(std::string(name)); -} - SingleStringMatcher::SingleStringMatcher(StringRef Pattern) { if (Pattern.size() > 2 && Pattern.startswith("\"") && Pattern.endswith("\"")) { diff --git a/lld/ELF/SymbolTable.cpp b/lld/ELF/SymbolTable.cpp --- a/lld/ELF/SymbolTable.cpp +++ b/lld/ELF/SymbolTable.cpp @@ -142,12 +142,12 @@ StringRef name = sym->getName(); size_t pos = name.find('@'); if (pos == std::string::npos) - demangled = demangleItanium(name); + demangled = demangle(name, elf::config->demangle); else if (pos + 1 == name.size() || name[pos + 1] == '@') - demangled = demangleItanium(name.substr(0, pos)); + demangled = demangle(name.substr(0, pos), elf::config->demangle); else demangled = - (demangleItanium(name.substr(0, pos)) + name.substr(pos)).str(); + (demangle(name.substr(0, pos), elf::config->demangle) + name.substr(pos)).str(); (*demangledSyms)[demangled].push_back(sym); } } diff --git a/lld/ELF/Symbols.cpp b/lld/ELF/Symbols.cpp --- a/lld/ELF/Symbols.cpp +++ b/lld/ELF/Symbols.cpp @@ -26,16 +26,9 @@ using namespace lld; using namespace lld::elf; -// Returns a symbol for an error message. -static std::string demangle(StringRef symName) { - if (elf::config->demangle) - return demangleItanium(symName); - return std::string(symName); -} - std::string lld::toString(const elf::Symbol &sym) { StringRef name = sym.getName(); - std::string ret = demangle(name); + std::string ret = demangle(name, elf::config->demangle); const char *suffix = sym.getVersionSuffix(); if (*suffix == '@') @@ -44,7 +37,7 @@ } std::string lld::toELFString(const Archive::Symbol &b) { - return demangle(b.getName()); + return demangle(b.getName(), elf::config->demangle); } Defined *ElfSym::bss; diff --git a/lld/MachO/Symbols.cpp b/lld/MachO/Symbols.cpp --- a/lld/MachO/Symbols.cpp +++ b/lld/MachO/Symbols.cpp @@ -6,6 +6,7 @@ // //===----------------------------------------------------------------------===// +#include "lld/Common/Strings.h" #include "Symbols.h" #include "InputFiles.h" #include "SyntheticSections.h" @@ -27,17 +28,10 @@ static_assert(sizeof(SymbolUnion) == sizeof(Defined), "Defined should be the largest Symbol kind"); -// Returns a symbol for an error message. -static std::string demangle(StringRef symName) { - if (config->demangle) - return demangleItanium(symName); - return std::string(symName); -} - -std::string lld::toString(const Symbol &sym) { return demangle(sym.getName()); } +std::string lld::toString(const Symbol &sym) { return demangle(sym.getName(), config->demangle); } std::string lld::toMachOString(const object::Archive::Symbol &b) { - return demangle(b.getName()); + return demangle(b.getName(), config->demangle); } uint64_t Symbol::getStubVA() const { return in.stubs->getVA(stubsIndex); } diff --git a/lld/include/lld/Common/Strings.h b/lld/include/lld/Common/Strings.h --- a/lld/include/lld/Common/Strings.h +++ b/lld/include/lld/Common/Strings.h @@ -12,14 +12,25 @@ #include "llvm/ADT/ArrayRef.h" #include "llvm/ADT/Optional.h" #include "llvm/ADT/StringRef.h" +#include "llvm/Demangle/Demangle.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 name. -std::string demangleItanium(llvm::StringRef name); +/// Demangle a non-Microsoft mangled symbol. +/// +/// \param symName mangled symbol name +/// \param shouldDemangle flag to determine if the symbol should be demangled +/// +/// \returns Demagled symbol or symName if it is not a valid mangled name. +inline std::string demangle(llvm::StringRef symName, bool shouldDemangle) { + std::string result; + if (!shouldDemangle) + return std::string(symName); + + return llvm::demangle(symName.str().c_str()); +} std::vector parseHex(llvm::StringRef s); bool isValidCIdentifier(llvm::StringRef s); diff --git a/lld/test/ELF/undef.s b/lld/test/ELF/undef.s --- a/lld/test/ELF/undef.s +++ b/lld/test/ELF/undef.s @@ -31,6 +31,18 @@ # CHECK-NEXT: >>> referenced by undef.s # CHECK-NEXT: >>> {{.*}}:(.text+0x1A) +# CHECK: error: undefined symbol: Pi +# CHECK-NEXT: >>> referenced by undef.s +# CHECK-NEXT: >>> {{.*}}:(.text+0x1F) + +# CHECK: error: undefined symbol: D main +# CHECK-NEXT: >>> referenced by undef.s +# CHECK-NEXT: >>> {{.*}}:(.text+0x24) + +# CHECK: error: undefined symbol: a::main +# CHECK-NEXT: >>> referenced by undef.s +# CHECK-NEXT: >>> {{.*}}:(.text+0x29) + # CHECK: error: undefined symbol: zed2 # CHECK-NEXT: >>> referenced by {{.*}}.o:(.text+0x0) in archive {{.*}}2.a @@ -84,3 +96,6 @@ call _Z3fooi call _ZTV3Foo call __Z3fooi + call Pi + call _Dmain + call _RNvC1a4main diff --git a/lld/wasm/Symbols.cpp b/lld/wasm/Symbols.cpp --- a/lld/wasm/Symbols.cpp +++ b/lld/wasm/Symbols.cpp @@ -33,9 +33,8 @@ // `main` in the case where we need to pass it arguments. if (name == "__main_argc_argv") return "main"; - if (wasm::config->demangle) - return demangleItanium(name); - return std::string(name); + + return demangle(name, wasm::config->demangle); } std::string toString(wasm::Symbol::Kind kind) {