From ef067cf4b6d46cd48d2ed5cfe2300fe83b6bcc8a Mon Sep 17 00:00:00 2001 From: Max Winkler Date: Wed, 26 Jun 2024 22:24:28 -0700 Subject: Fix MSVC Demangling with auto NTTP mangled names for function pointer, pointer to data and integral types (#96590) As cited here, https://github.com/llvm/llvm-project/pull/92477, undname needs updating to support the new auto NTTP name mangling. In short the deduced type of the auto NTTP parameter is mangled as `$M `. However the deduced type is not printed for the undecorated name so the `$M ` is parsed but simply ignored when stringifying the generated AST. --- llvm/lib/Demangle/MicrosoftDemangle.cpp | 38 +++++++++++++++++---- llvm/test/Demangle/ms-auto-templates.test | 57 +++++++++++++++++++++++++++++++ 2 files changed, 89 insertions(+), 6 deletions(-) create mode 100644 llvm/test/Demangle/ms-auto-templates.test diff --git a/llvm/lib/Demangle/MicrosoftDemangle.cpp b/llvm/lib/Demangle/MicrosoftDemangle.cpp index cd7ff40..e18de9a 100644 --- a/llvm/lib/Demangle/MicrosoftDemangle.cpp +++ b/llvm/lib/Demangle/MicrosoftDemangle.cpp @@ -53,6 +53,18 @@ static bool consumeFront(std::string_view &S, std::string_view C) { return true; } +static bool consumeFront(std::string_view &S, std::string_view PrefixA, + std::string_view PrefixB, bool A) { + const std::string_view &Prefix = A ? PrefixA : PrefixB; + return consumeFront(S, Prefix); +} + +static bool startsWith(std::string_view S, std::string_view PrefixA, + std::string_view PrefixB, bool A) { + const std::string_view &Prefix = A ? PrefixA : PrefixB; + return llvm::itanium_demangle::starts_with(S, Prefix); +} + static bool isMemberPointer(std::string_view MangledName, bool &Error) { Error = false; const char F = MangledName.front(); @@ -2256,6 +2268,18 @@ Demangler::demangleTemplateParameterList(std::string_view &MangledName) { NodeList &TP = **Current; + // ::= $ M + const bool IsAutoNTTP = consumeFront(MangledName, "$M"); + if (IsAutoNTTP) { + // The deduced type of the auto NTTP parameter isn't printed so + // we want to ignore the AST created from demangling the type. + // + // TODO: Avoid the extra allocations to the bump allocator in this case. + (void)demangleType(MangledName, QualifierMangleMode::Drop); + if (Error) + return nullptr; + } + TemplateParameterReferenceNode *TPRN = nullptr; if (consumeFront(MangledName, "$$Y")) { // Template alias @@ -2266,15 +2290,17 @@ Demangler::demangleTemplateParameterList(std::string_view &MangledName) { } else if (consumeFront(MangledName, "$$C")) { // Type has qualifiers. TP.N = demangleType(MangledName, QualifierMangleMode::Mangle); - } else if (llvm::itanium_demangle::starts_with(MangledName, "$1") || - llvm::itanium_demangle::starts_with(MangledName, "$H") || - llvm::itanium_demangle::starts_with(MangledName, "$I") || - llvm::itanium_demangle::starts_with(MangledName, "$J")) { + } else if (startsWith(MangledName, "$1", "1", !IsAutoNTTP) || + startsWith(MangledName, "$H", "H", !IsAutoNTTP) || + startsWith(MangledName, "$I", "I", !IsAutoNTTP) || + startsWith(MangledName, "$J", "J", !IsAutoNTTP)) { // Pointer to member TP.N = TPRN = Arena.alloc(); TPRN->IsMemberPointer = true; - MangledName.remove_prefix(1); + if (!IsAutoNTTP) + MangledName.remove_prefix(1); // Remove leading '$' + // 1 - single inheritance // H - multiple inheritance // I - virtual inheritance @@ -2342,7 +2368,7 @@ Demangler::demangleTemplateParameterList(std::string_view &MangledName) { } TPRN->IsMemberPointer = true; - } else if (consumeFront(MangledName, "$0")) { + } else if (consumeFront(MangledName, "$0", "0", !IsAutoNTTP)) { // Integral non-type template parameter bool IsNegative = false; uint64_t Value = 0; diff --git a/llvm/test/Demangle/ms-auto-templates.test b/llvm/test/Demangle/ms-auto-templates.test new file mode 100644 index 0000000..a90ffb6 --- /dev/null +++ b/llvm/test/Demangle/ms-auto-templates.test @@ -0,0 +1,57 @@ +; RUN: llvm-undname < %s | FileCheck %s + +; CHECK-NOT: Invalid mangled name + +??0?$AutoNTTPClass@$MPEAH1?i@@3HA@@QEAA@XZ +; CHECK: public: __cdecl AutoNTTPClass<&int i>::AutoNTTPClass<&int i>(void) + +??0?$AutoNTTPClass@$1?i@@3HA@@QEAA@XZ +; CHECK: public: __cdecl AutoNTTPClass<&int i>::AutoNTTPClass<&int i>(void) + +??0?$AutoNTTPClass@$MPEAH1?i@@3HA$MPEAH1?j@@3HA@@QEAA@XZ +; CHECK: public: __cdecl AutoNTTPClass<&int i, &int j>::AutoNTTPClass<&int i, &int j>(void) + +??0?$AutoNTTPClass@$1?i@@3HA$1?j@@3HA@@QEAA@XZ +; CHECK: public: __cdecl AutoNTTPClass<&int i, &int j>::AutoNTTPClass<&int i, &int j>(void) + +??0?$AutoNTTPClass@$MP6AHXZ1?Func@@YAHXZ@@QEAA@XZ +; CHECK: public: __cdecl AutoNTTPClass<&int __cdecl Func(void)>::AutoNTTPClass<&int __cdecl Func(void)>(void) + +??0?$AutoNTTPClass@$1?Func@@YAHXZ@@QEAA@XZ +; CHECK: public: __cdecl AutoNTTPClass<&int __cdecl Func(void)>::AutoNTTPClass<&int __cdecl Func(void)>(void) + +??0?$AutoNTTPClass@$MP6AHXZ1?Func@@YAHXZ$MP6AHXZ1?Func2@@YAHXZ@@QEAA@XZ +; CHECK: public: __cdecl AutoNTTPClass<&int __cdecl Func(void), &int __cdecl Func2(void)>::AutoNTTPClass<&int __cdecl Func(void), &int __cdecl Func2(void)>(void) + +??0?$AutoNTTPClass@$1?Func@@YAHXZ$1?Func2@@YAHXZ@@QEAA@XZ +; CHECK: public: __cdecl AutoNTTPClass<&int __cdecl Func(void), &int __cdecl Func2(void)>::AutoNTTPClass<&int __cdecl Func(void), &int __cdecl Func2(void)>(void) + +??$AutoFunc@$MPEAH1?i@@3HA@@YA?A?@@XZ +; CHECK: __cdecl AutoFunc<&int i>(void) + +??$AutoFunc@$1?i@@3HA@@YA?A?@@XZ +; CHECK: __cdecl AutoFunc<&int i>(void) + +??$AutoFunc@$MP6AHXZ1?Func@@YAHXZ@@YA?A?@@XZ +; CHECK: __cdecl AutoFunc<&int __cdecl Func(void)>(void) + +??$AutoFunc@$1?Func@@YAHXZ@@YA?A?@@XZ +; CHECK: __cdecl AutoFunc<&int __cdecl Func(void)>(void) + +??$AutoFunc@$MH00@@YA?A?@@XZ +; CHECK: __cdecl AutoFunc<1>(void) + +??$AutoFunc@$00@@YA?A?@@XZ +; CHECK: __cdecl AutoFunc<1>(void) + +??0?$AutoNTTPClass@$0A@@@QEAA@XZ +; CHECK: public: __cdecl AutoNTTPClass<0>::AutoNTTPClass<0>(void) + +??0?$AutoNTTPClass@$MH0A@@@QEAA@XZ +; CHECK: public: __cdecl AutoNTTPClass<0>::AutoNTTPClass<0>(void) + +??0?$AutoNTTPClass@$0A@$0A@$0GB@@@QEAA@XZ +; CHECK: public: __cdecl AutoNTTPClass<0, 0, 97>::AutoNTTPClass<0, 0, 97>(void) + +??0?$AutoNTTPClass@$MH0A@$M_N0A@$MD0GB@@@QEAA@XZ +; CHECK: public: __cdecl AutoNTTPClass<0, 0, 97>::AutoNTTPClass<0, 0, 97>(void) -- cgit v1.1