diff --git a/llvm/test/tools/llvm-cxxfilt/delimiters.test b/llvm/test/tools/llvm-cxxfilt/delimiters.test --- a/llvm/test/tools/llvm-cxxfilt/delimiters.test +++ b/llvm/test/tools/llvm-cxxfilt/delimiters.test @@ -66,4 +66,4 @@ CHECK: Foo~,, CHECK: Foo⦙Bar CHECK: Foo,,Bar::Baz Foo,Bar:Baz -CHECK: _Z3Foo$ ._Z3Foo +CHECK: _Z3Foo$ .Foo diff --git a/llvm/test/tools/llvm-cxxfilt/prefix-dot.test b/llvm/test/tools/llvm-cxxfilt/prefix-dot.test new file mode 100644 --- /dev/null +++ b/llvm/test/tools/llvm-cxxfilt/prefix-dot.test @@ -0,0 +1,9 @@ +## Show that the llvm-cxxfilt does not consider the prefix dot to be part of the symbol name to be demangled. + +RUN: echo '._Z3Foo ._Z3f.0v' \ +RUN: '._ZL5func0v ._Z5func1i' > %t +RUN: llvm-cxxfilt -n < %t | FileCheck %s + +CHECK: .Foo .f.0() +CHECK: .func0() +CHECK: .func1(int) diff --git a/llvm/tools/llvm-cxxfilt/llvm-cxxfilt.cpp b/llvm/tools/llvm-cxxfilt/llvm-cxxfilt.cpp --- a/llvm/tools/llvm-cxxfilt/llvm-cxxfilt.cpp +++ b/llvm/tools/llvm-cxxfilt/llvm-cxxfilt.cpp @@ -67,13 +67,19 @@ static std::string demangle(const std::string &Mangled) { using llvm::itanium_demangle::starts_with; std::string_view DecoratedStr = Mangled; - if (StripUnderscore) - if (DecoratedStr[0] == '_') - DecoratedStr.remove_prefix(1); + std::string DotPrefix; + + if (StripUnderscore && DecoratedStr[0] == '_') + DecoratedStr.remove_prefix(1); + // Do not consider the prefix dot as part of the demangled symbol name. + else if (DecoratedStr[0] == '.') { + DecoratedStr.remove_prefix(1); + DotPrefix = "."; + } std::string Result; if (nonMicrosoftDemangle(DecoratedStr, Result)) - return Result; + return DotPrefix + Result; std::string Prefix; char *Undecorated = nullptr; @@ -86,7 +92,7 @@ Undecorated = itaniumDemangle(DecoratedStr.substr(6)); } - Result = Undecorated ? Prefix + Undecorated : Mangled; + Result = Undecorated ? DotPrefix + Prefix + Undecorated : Mangled; free(Undecorated); return Result; }