[llvm] Fix MSVC Demangling with auto NTTP mangled names for function pointer, pointer to data and integral types (PR #96590)
Max Winkler via llvm-commits
llvm-commits at lists.llvm.org
Mon Jun 24 23:33:28 PDT 2024
https://github.com/MaxEW707 updated https://github.com/llvm/llvm-project/pull/96590
>From 6bd70bb27894c7f24d82f238f97f8ca18653a30c Mon Sep 17 00:00:00 2001
From: MaxEW707 <max.enrico.winkler at gmail.com>
Date: Sat, 22 Jun 2024 22:59:23 -0700
Subject: [PATCH 1/4] Fix MSVC Demangling with auto NTTP mangled names for
function pointers and pointers to variables
---
llvm/lib/Demangle/MicrosoftDemangle.cpp | 17 +++++++++-
llvm/test/Demangle/ms-auto-templates.test | 39 +++++++++++++++++++++++
2 files changed, 55 insertions(+), 1 deletion(-)
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 cd7ff40d63a49..1c90c8553fb54 100644
--- a/llvm/lib/Demangle/MicrosoftDemangle.cpp
+++ b/llvm/lib/Demangle/MicrosoftDemangle.cpp
@@ -2269,12 +2269,27 @@ Demangler::demangleTemplateParameterList(std::string_view &MangledName) {
} 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")) {
+ llvm::itanium_demangle::starts_with(MangledName, "$J") ||
+ llvm::itanium_demangle::starts_with(MangledName, "$M")) {
// Pointer to member
TP.N = TPRN = Arena.alloc<TemplateParameterReferenceNode>();
TPRN->IsMemberPointer = true;
MangledName.remove_prefix(1);
+
+ // <auto-nttp> ::= $ M <type> 1? <mangled-name>
+ if (llvm::itanium_demangle::starts_with(MangledName, 'M')) {
+ MangledName.remove_prefix(1);
+
+ // 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;
+ }
+
// 1 - single inheritance <name>
// H - multiple inheritance <name> <number>
// I - virtual inheritance <name> <number> <number>
diff --git a/llvm/test/Demangle/ms-auto-templates.test b/llvm/test/Demangle/ms-auto-templates.test
new file mode 100644
index 0000000000000..039c150b06d48
--- /dev/null
+++ b/llvm/test/Demangle/ms-auto-templates.test
@@ -0,0 +1,39 @@
+; RUN: llvm-undname < %s | FileCheck %s
+
+; CHECK-NOT: Invalid mangled name
+
+??0?$AutoNTTPClass@$MPEAH1?i@@3HA@@QEAA at XZ
+; CHECK: public: __cdecl AutoNTTPClass<&int i>::AutoNTTPClass<&int i>(void)
+
+??0?$AutoNTTPClass@$1?i@@3HA@@QEAA at XZ
+; CHECK: public: __cdecl AutoNTTPClass<&int i>::AutoNTTPClass<&int i>(void)
+
+??0?$AutoNTTPClass@$MPEAH1?i@@3HA$MPEAH1?j@@3HA@@QEAA at XZ
+; CHECK: public: __cdecl AutoNTTPClass<&int i, &int j>::AutoNTTPClass<&int i, &int j>(void)
+
+??0?$AutoNTTPClass@$1?i@@3HA$1?j@@3HA@@QEAA at XZ
+; CHECK: public: __cdecl AutoNTTPClass<&int i, &int j>::AutoNTTPClass<&int i, &int j>(void)
+
+??0?$AutoNTTPClass@$MP6AHXZ1?Func@@YAHXZ@@QEAA at XZ
+; CHECK: public: __cdecl AutoNTTPClass<&int __cdecl Func(void)>::AutoNTTPClass<&int __cdecl Func(void)>(void)
+
+??0?$AutoNTTPClass@$1?Func@@YAHXZ@@QEAA at XZ
+; CHECK: public: __cdecl AutoNTTPClass<&int __cdecl Func(void)>::AutoNTTPClass<&int __cdecl Func(void)>(void)
+
+??0?$AutoNTTPClass@$MP6AHXZ1?Func@@YAHXZ$MP6AHXZ1?Func2@@YAHXZ@@QEAA at 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 at 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?<auto>@@XZ
+; CHECK: <auto> __cdecl AutoFunc<&int i>(void)
+
+??$AutoFunc@$1?i@@3HA@@YA?A?<auto>@@XZ
+; CHECK: <auto> __cdecl AutoFunc<&int i>(void)
+
+??$AutoFunc@$MP6AHXZ1?Func@@YAHXZ@@YA?A?<auto>@@XZ
+; CHECK: <auto> __cdecl AutoFunc<&int __cdecl Func(void)>(void)
+
+??$AutoFunc@$1?Func@@YAHXZ@@YA?A?<auto>@@XZ
+; CHECK: <auto> __cdecl AutoFunc<&int __cdecl Func(void)>(void)
>From 8c9ba63934bd8efef66ea8ec43870e07c900b8d0 Mon Sep 17 00:00:00 2001
From: MaxEW707 <max.enrico.winkler at gmail.com>
Date: Mon, 24 Jun 2024 18:37:12 -0700
Subject: [PATCH 2/4] Fix integer literals with auto nttp
---
llvm/lib/Demangle/MicrosoftDemangle.cpp | 57 +++++++++++++++--------
llvm/test/Demangle/ms-auto-templates.test | 18 +++++++
2 files changed, 55 insertions(+), 20 deletions(-)
diff --git a/llvm/lib/Demangle/MicrosoftDemangle.cpp b/llvm/lib/Demangle/MicrosoftDemangle.cpp
index 1c90c8553fb54..d0aafcc90d2d7 100644
--- a/llvm/lib/Demangle/MicrosoftDemangle.cpp
+++ b/llvm/lib/Demangle/MicrosoftDemangle.cpp
@@ -53,6 +53,24 @@ static bool consumeFront(std::string_view &S, std::string_view C) {
return true;
}
+static bool consumeFrontWithOrWithoutPrefix(std::string_view &S, std::string_view C, bool CheckWithout, size_t N) {
+ std::string_view CWithout = C.substr(N);
+ if (CheckWithout && llvm::itanium_demangle::starts_with(S, CWithout)) {
+ S.remove_prefix(CWithout.size());
+ return true;
+ }
+ if (!llvm::itanium_demangle::starts_with(S, C))
+ return false;
+ S.remove_prefix(C.size());
+ return true;
+}
+
+static bool startsWithOrWithoutPrefix(std::string_view S, std::string_view C, bool CheckWithout, size_t N) {
+ if (CheckWithout && llvm::itanium_demangle::starts_with(S, C.substr(N)))
+ return true;
+ return llvm::itanium_demangle::starts_with(S, C);
+}
+
static bool isMemberPointer(std::string_view MangledName, bool &Error) {
Error = false;
const char F = MangledName.front();
@@ -2256,6 +2274,18 @@ Demangler::demangleTemplateParameterList(std::string_view &MangledName) {
NodeList &TP = **Current;
+ // <auto-nttp> ::= $ M <type> <nttp>
+ 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,29 +2296,16 @@ 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") ||
- llvm::itanium_demangle::starts_with(MangledName, "$M")) {
+ } else if (startsWithOrWithoutPrefix(MangledName, "$1", IsAutoNTTP, 1) ||
+ startsWithOrWithoutPrefix(MangledName, "$H", IsAutoNTTP, 1) ||
+ startsWithOrWithoutPrefix(MangledName, "$I", IsAutoNTTP, 1) ||
+ startsWithOrWithoutPrefix(MangledName, "$J", IsAutoNTTP, 1)) {
// Pointer to member
TP.N = TPRN = Arena.alloc<TemplateParameterReferenceNode>();
TPRN->IsMemberPointer = true;
- MangledName.remove_prefix(1);
-
- // <auto-nttp> ::= $ M <type> 1? <mangled-name>
- if (llvm::itanium_demangle::starts_with(MangledName, 'M')) {
- MangledName.remove_prefix(1);
-
- // 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;
- }
+ if (!IsAutoNTTP)
+ MangledName.remove_prefix(1); // Remove leading '$'
// 1 - single inheritance <name>
// H - multiple inheritance <name> <number>
@@ -2357,7 +2374,7 @@ Demangler::demangleTemplateParameterList(std::string_view &MangledName) {
}
TPRN->IsMemberPointer = true;
- } else if (consumeFront(MangledName, "$0")) {
+ } else if (consumeFrontWithOrWithoutPrefix(MangledName, "$0", IsAutoNTTP, 1)) {
// 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
index 039c150b06d48..a90ffb69df558 100644
--- a/llvm/test/Demangle/ms-auto-templates.test
+++ b/llvm/test/Demangle/ms-auto-templates.test
@@ -37,3 +37,21 @@
??$AutoFunc@$1?Func@@YAHXZ@@YA?A?<auto>@@XZ
; CHECK: <auto> __cdecl AutoFunc<&int __cdecl Func(void)>(void)
+
+??$AutoFunc@$MH00@@YA?A?<auto>@@XZ
+; CHECK: <auto> __cdecl AutoFunc<1>(void)
+
+??$AutoFunc@$00@@YA?A?<auto>@@XZ
+; CHECK: <auto> __cdecl AutoFunc<1>(void)
+
+??0?$AutoNTTPClass@$0A@@@QEAA at XZ
+; CHECK: public: __cdecl AutoNTTPClass<0>::AutoNTTPClass<0>(void)
+
+??0?$AutoNTTPClass@$MH0A@@@QEAA at XZ
+; CHECK: public: __cdecl AutoNTTPClass<0>::AutoNTTPClass<0>(void)
+
+??0?$AutoNTTPClass@$0A@$0A@$0GB@@@QEAA at XZ
+; CHECK: public: __cdecl AutoNTTPClass<0, 0, 97>::AutoNTTPClass<0, 0, 97>(void)
+
+??0?$AutoNTTPClass@$MH0A@$M_N0A@$MD0GB@@@QEAA at XZ
+; CHECK: public: __cdecl AutoNTTPClass<0, 0, 97>::AutoNTTPClass<0, 0, 97>(void)
>From a9a489f7b116a8e74b0a4588dcda452604eb67a8 Mon Sep 17 00:00:00 2001
From: MaxEW707 <max.enrico.winkler at gmail.com>
Date: Mon, 24 Jun 2024 21:32:19 -0700
Subject: [PATCH 3/4] formatting
---
llvm/lib/Demangle/MicrosoftDemangle.cpp | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/llvm/lib/Demangle/MicrosoftDemangle.cpp b/llvm/lib/Demangle/MicrosoftDemangle.cpp
index d0aafcc90d2d7..12742185519e8 100644
--- a/llvm/lib/Demangle/MicrosoftDemangle.cpp
+++ b/llvm/lib/Demangle/MicrosoftDemangle.cpp
@@ -2305,7 +2305,7 @@ Demangler::demangleTemplateParameterList(std::string_view &MangledName) {
TPRN->IsMemberPointer = true;
if (!IsAutoNTTP)
- MangledName.remove_prefix(1); // Remove leading '$'
+ MangledName.remove_prefix(1); // Remove leading '$'
// 1 - single inheritance <name>
// H - multiple inheritance <name> <number>
>From 0fbc555c36c4bea3a81b1035aebe2db223881839 Mon Sep 17 00:00:00 2001
From: MaxEW707 <max.enrico.winkler at gmail.com>
Date: Mon, 24 Jun 2024 23:33:11 -0700
Subject: [PATCH 4/4] Change impl
---
llvm/lib/Demangle/MicrosoftDemangle.cpp | 30 ++++++++++---------------
1 file changed, 12 insertions(+), 18 deletions(-)
diff --git a/llvm/lib/Demangle/MicrosoftDemangle.cpp b/llvm/lib/Demangle/MicrosoftDemangle.cpp
index 12742185519e8..e2ab4ca1fbc69 100644
--- a/llvm/lib/Demangle/MicrosoftDemangle.cpp
+++ b/llvm/lib/Demangle/MicrosoftDemangle.cpp
@@ -53,21 +53,15 @@ static bool consumeFront(std::string_view &S, std::string_view C) {
return true;
}
-static bool consumeFrontWithOrWithoutPrefix(std::string_view &S, std::string_view C, bool CheckWithout, size_t N) {
- std::string_view CWithout = C.substr(N);
- if (CheckWithout && llvm::itanium_demangle::starts_with(S, CWithout)) {
- S.remove_prefix(CWithout.size());
- return true;
- }
- if (!llvm::itanium_demangle::starts_with(S, C))
- return false;
- S.remove_prefix(C.size());
- return true;
+static bool consumeFront(std::string_view &S, std::string_view CA,
+ std::string_view CB, bool A) {
+ const std::string_view &C = A ? CA : CB;
+ return consumeFront(S, C);
}
-static bool startsWithOrWithoutPrefix(std::string_view S, std::string_view C, bool CheckWithout, size_t N) {
- if (CheckWithout && llvm::itanium_demangle::starts_with(S, C.substr(N)))
- return true;
+static bool startsWith(std::string_view S, std::string_view CA,
+ std::string_view CB, bool A) {
+ const std::string_view &C = A ? CA : CB;
return llvm::itanium_demangle::starts_with(S, C);
}
@@ -2296,10 +2290,10 @@ Demangler::demangleTemplateParameterList(std::string_view &MangledName) {
} else if (consumeFront(MangledName, "$$C")) {
// Type has qualifiers.
TP.N = demangleType(MangledName, QualifierMangleMode::Mangle);
- } else if (startsWithOrWithoutPrefix(MangledName, "$1", IsAutoNTTP, 1) ||
- startsWithOrWithoutPrefix(MangledName, "$H", IsAutoNTTP, 1) ||
- startsWithOrWithoutPrefix(MangledName, "$I", IsAutoNTTP, 1) ||
- startsWithOrWithoutPrefix(MangledName, "$J", IsAutoNTTP, 1)) {
+ } 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<TemplateParameterReferenceNode>();
TPRN->IsMemberPointer = true;
@@ -2374,7 +2368,7 @@ Demangler::demangleTemplateParameterList(std::string_view &MangledName) {
}
TPRN->IsMemberPointer = true;
- } else if (consumeFrontWithOrWithoutPrefix(MangledName, "$0", IsAutoNTTP, 1)) {
+ } else if (consumeFront(MangledName, "$0", "0", !IsAutoNTTP)) {
// Integral non-type template parameter
bool IsNegative = false;
uint64_t Value = 0;
More information about the llvm-commits
mailing list