diff --git a/llvm/lib/Demangle/Demangle.cpp b/llvm/lib/Demangle/Demangle.cpp index 117b849d1c784..f0f7eacac98e6 100644 --- a/llvm/lib/Demangle/Demangle.cpp +++ b/llvm/lib/Demangle/Demangle.cpp @@ -38,8 +38,9 @@ std::string llvm::demangle(std::string_view MangledName) { } static bool isItaniumEncoding(std::string_view S) { - // Itanium encoding requires 1 or 3 leading underscores, followed by 'Z'. - return starts_with(S, "_Z") || starts_with(S, "___Z"); + // Itanium demangler supports prefixes with 1-4 underscores. + const size_t Pos = S.find_first_not_of('_'); + return Pos > 0 && Pos <= 4 && S[Pos] == 'Z'; } static bool isRustEncoding(std::string_view S) { return starts_with(S, "_R"); } diff --git a/llvm/test/tools/llvm-cxxfilt/invalid.test b/llvm/test/tools/llvm-cxxfilt/invalid.test index 13866f3fb90eb..f1cf583936bcf 100644 --- a/llvm/test/tools/llvm-cxxfilt/invalid.test +++ b/llvm/test/tools/llvm-cxxfilt/invalid.test @@ -1,6 +1,8 @@ -RUN: llvm-cxxfilt -n _Z1fi __Z1fi f ___ZSt1ff_block_invoke | FileCheck %s +RUN: llvm-cxxfilt -n _Z1fi __Z1fi _____Z1fi f ___ZSt1ff_block_invoke ____ZSt1ff_block_invoke | FileCheck %s CHECK: f(int) -CHECK-NEXT: __Z1fi +CHECK-NEXT: f(int) +CHECK-NEXT: _____Z1fi CHECK-NEXT: f CHECK-NEXT: invocation function for block in std::f(float) +CHECK-NEXT: invocation function for block in std::f(float) diff --git a/llvm/test/tools/llvm-cxxfilt/strip-underscore-default-darwin.test b/llvm/test/tools/llvm-cxxfilt/strip-underscore-default-darwin.test deleted file mode 100644 index 7dcffa05a0488..0000000000000 --- a/llvm/test/tools/llvm-cxxfilt/strip-underscore-default-darwin.test +++ /dev/null @@ -1,7 +0,0 @@ -REQUIRES: system-darwin - -## Show that on darwin, the default is to strip the leading underscore. - -RUN: llvm-cxxfilt __Z1fv _Z2bav | FileCheck %s -CHECK: f() -CHECK: _Z2bav diff --git a/llvm/test/tools/llvm-cxxfilt/strip-underscore-default.test b/llvm/test/tools/llvm-cxxfilt/strip-underscore-default.test deleted file mode 100644 index 6d6fa51132b24..0000000000000 --- a/llvm/test/tools/llvm-cxxfilt/strip-underscore-default.test +++ /dev/null @@ -1,8 +0,0 @@ -UNSUPPORTED: system-darwin - -## Show that on non-darwin systems, the default is to strip the leading -## underscore. - -RUN: llvm-cxxfilt __Z1fv _Z2bav | FileCheck %s -CHECK: __Z1fv -CHECK: ba() diff --git a/llvm/test/tools/llvm-cxxfilt/strip-underscore.test b/llvm/test/tools/llvm-cxxfilt/strip-underscore.test index 2b7057fbfbae8..60c530acf0be4 100644 --- a/llvm/test/tools/llvm-cxxfilt/strip-underscore.test +++ b/llvm/test/tools/llvm-cxxfilt/strip-underscore.test @@ -1,17 +1,23 @@ -## Show the behaviour of --[no-]strip-underscore. This test does not test -## the platform-specific default behaviour. This is tested elsewhere. +## Show the behaviour of --[no-]strip-underscore. -RUN: llvm-cxxfilt -_ __ZN2ns1fE _ZSt1f _f _._Z3f.0v | FileCheck %s -check-prefix CHECK-STRIPPED -RUN: llvm-cxxfilt --strip-underscore __ZN2ns1fE _ZSt1f _f _._Z3f.0v | FileCheck %s -check-prefix CHECK-STRIPPED -RUN: llvm-cxxfilt -n __ZN2ns1fE _ZSt1f _f _._Z3f.0v | FileCheck %s -check-prefix CHECK-UNSTRIPPED -RUN: llvm-cxxfilt --no-strip-underscore __ZN2ns1fE _ZSt1f _f _._Z3f.0v | FileCheck %s -check-prefix CHECK-UNSTRIPPED +RUN: llvm-cxxfilt -_ ___ZN2ns1fE _____Z1fi_block_invoke _ZSt1f _f _._Z3f.0v | FileCheck %s -check-prefix CHECK-STRIPPED +RUN: llvm-cxxfilt --strip-underscore __ZN2ns1fE _____Z1fi_block_invoke _ZSt1f _f _._Z3f.0v | FileCheck %s -check-prefix CHECK-STRIPPED +RUN: llvm-cxxfilt -n ___ZN2ns1fE _____Z1fi_block_invoke _ZSt1f _f _._Z3f.0v | FileCheck %s -check-prefix CHECK-UNSTRIPPED +RUN: llvm-cxxfilt --no-strip-underscore ___ZN2ns1fE _____Z1fi_block_invoke _ZSt1f _f _._Z3f.0v | FileCheck %s -check-prefix CHECK-UNSTRIPPED +RUN: llvm-cxxfilt -n -_ _ZSt1f | FileCheck %s -check-prefix OVERRIDE-STRIPPED +RUN: llvm-cxxfilt -_ -n _ZSt1f | FileCheck %s -check-prefix OVERRIDE-UNSTRIPPED CHECK-STRIPPED: ns::f +CHECK-STRIPPED: invocation function for block in f(int) CHECK-STRIPPED: _ZSt1f CHECK-STRIPPED: _f CHECK-STRIPPED: ._Z3f.0v -CHECK-UNSTRIPPED: __ZN2ns1fE +CHECK-UNSTRIPPED: ___ZN2ns1fE +CHECK-UNSTRIPPED: _____Z1fi_block_invoke CHECK-UNSTRIPPED: std::f CHECK-UNSTRIPPED: _f CHECK-UNSTRIPPED: _._Z3f.0v + +OVERRIDE-STRIPPED: _ZSt1f +OVERRIDE-UNSTRIPPED: std::f diff --git a/llvm/tools/llvm-cxxfilt/llvm-cxxfilt.cpp b/llvm/tools/llvm-cxxfilt/llvm-cxxfilt.cpp index d63f507619a0e..f90adb6cacb99 100644 --- a/llvm/tools/llvm-cxxfilt/llvm-cxxfilt.cpp +++ b/llvm/tools/llvm-cxxfilt/llvm-cxxfilt.cpp @@ -165,13 +165,8 @@ int llvm_cxxfilt_main(int argc, char **argv, const llvm::ToolContext &) { return 0; } - // The default value depends on the default triple. Mach-O has symbols - // prefixed with "_", so strip by default. - if (opt::Arg *A = - Args.getLastArg(OPT_strip_underscore, OPT_no_strip_underscore)) - StripUnderscore = A->getOption().matches(OPT_strip_underscore); - else - StripUnderscore = Triple(sys::getProcessTriple()).isOSBinFormatMachO(); + StripUnderscore = + Args.hasFlag(OPT_strip_underscore, OPT_no_strip_underscore, false); ParseParams = !Args.hasArg(OPT_no_params);