Skip to content

Commit e0427a3

Browse files
MaxEW707AlexisPerry
authored andcommitted
Fix MSVC Demangling with auto NTTP mangled names for function pointer, pointer to data and integral types (llvm#96590)
As cited here, llvm#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 <type> <nttp-param>`. However the deduced type is not printed for the undecorated name so the `$M <type>` is parsed but simply ignored when stringifying the generated AST.
1 parent 3263be5 commit e0427a3

File tree

2 files changed

+89
-6
lines changed

2 files changed

+89
-6
lines changed

llvm/lib/Demangle/MicrosoftDemangle.cpp

Lines changed: 32 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -53,6 +53,18 @@ static bool consumeFront(std::string_view &S, std::string_view C) {
5353
return true;
5454
}
5555

56+
static bool consumeFront(std::string_view &S, std::string_view PrefixA,
57+
std::string_view PrefixB, bool A) {
58+
const std::string_view &Prefix = A ? PrefixA : PrefixB;
59+
return consumeFront(S, Prefix);
60+
}
61+
62+
static bool startsWith(std::string_view S, std::string_view PrefixA,
63+
std::string_view PrefixB, bool A) {
64+
const std::string_view &Prefix = A ? PrefixA : PrefixB;
65+
return llvm::itanium_demangle::starts_with(S, Prefix);
66+
}
67+
5668
static bool isMemberPointer(std::string_view MangledName, bool &Error) {
5769
Error = false;
5870
const char F = MangledName.front();
@@ -2256,6 +2268,18 @@ Demangler::demangleTemplateParameterList(std::string_view &MangledName) {
22562268

22572269
NodeList &TP = **Current;
22582270

2271+
// <auto-nttp> ::= $ M <type> <nttp>
2272+
const bool IsAutoNTTP = consumeFront(MangledName, "$M");
2273+
if (IsAutoNTTP) {
2274+
// The deduced type of the auto NTTP parameter isn't printed so
2275+
// we want to ignore the AST created from demangling the type.
2276+
//
2277+
// TODO: Avoid the extra allocations to the bump allocator in this case.
2278+
(void)demangleType(MangledName, QualifierMangleMode::Drop);
2279+
if (Error)
2280+
return nullptr;
2281+
}
2282+
22592283
TemplateParameterReferenceNode *TPRN = nullptr;
22602284
if (consumeFront(MangledName, "$$Y")) {
22612285
// Template alias
@@ -2266,15 +2290,17 @@ Demangler::demangleTemplateParameterList(std::string_view &MangledName) {
22662290
} else if (consumeFront(MangledName, "$$C")) {
22672291
// Type has qualifiers.
22682292
TP.N = demangleType(MangledName, QualifierMangleMode::Mangle);
2269-
} else if (llvm::itanium_demangle::starts_with(MangledName, "$1") ||
2270-
llvm::itanium_demangle::starts_with(MangledName, "$H") ||
2271-
llvm::itanium_demangle::starts_with(MangledName, "$I") ||
2272-
llvm::itanium_demangle::starts_with(MangledName, "$J")) {
2293+
} else if (startsWith(MangledName, "$1", "1", !IsAutoNTTP) ||
2294+
startsWith(MangledName, "$H", "H", !IsAutoNTTP) ||
2295+
startsWith(MangledName, "$I", "I", !IsAutoNTTP) ||
2296+
startsWith(MangledName, "$J", "J", !IsAutoNTTP)) {
22732297
// Pointer to member
22742298
TP.N = TPRN = Arena.alloc<TemplateParameterReferenceNode>();
22752299
TPRN->IsMemberPointer = true;
22762300

2277-
MangledName.remove_prefix(1);
2301+
if (!IsAutoNTTP)
2302+
MangledName.remove_prefix(1); // Remove leading '$'
2303+
22782304
// 1 - single inheritance <name>
22792305
// H - multiple inheritance <name> <number>
22802306
// I - virtual inheritance <name> <number> <number>
@@ -2342,7 +2368,7 @@ Demangler::demangleTemplateParameterList(std::string_view &MangledName) {
23422368
}
23432369
TPRN->IsMemberPointer = true;
23442370

2345-
} else if (consumeFront(MangledName, "$0")) {
2371+
} else if (consumeFront(MangledName, "$0", "0", !IsAutoNTTP)) {
23462372
// Integral non-type template parameter
23472373
bool IsNegative = false;
23482374
uint64_t Value = 0;
Lines changed: 57 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,57 @@
1+
; RUN: llvm-undname < %s | FileCheck %s
2+
3+
; CHECK-NOT: Invalid mangled name
4+
5+
??0?$AutoNTTPClass@$MPEAH1?i@@3HA@@QEAA@XZ
6+
; CHECK: public: __cdecl AutoNTTPClass<&int i>::AutoNTTPClass<&int i>(void)
7+
8+
??0?$AutoNTTPClass@$1?i@@3HA@@QEAA@XZ
9+
; CHECK: public: __cdecl AutoNTTPClass<&int i>::AutoNTTPClass<&int i>(void)
10+
11+
??0?$AutoNTTPClass@$MPEAH1?i@@3HA$MPEAH1?j@@3HA@@QEAA@XZ
12+
; CHECK: public: __cdecl AutoNTTPClass<&int i, &int j>::AutoNTTPClass<&int i, &int j>(void)
13+
14+
??0?$AutoNTTPClass@$1?i@@3HA$1?j@@3HA@@QEAA@XZ
15+
; CHECK: public: __cdecl AutoNTTPClass<&int i, &int j>::AutoNTTPClass<&int i, &int j>(void)
16+
17+
??0?$AutoNTTPClass@$MP6AHXZ1?Func@@YAHXZ@@QEAA@XZ
18+
; CHECK: public: __cdecl AutoNTTPClass<&int __cdecl Func(void)>::AutoNTTPClass<&int __cdecl Func(void)>(void)
19+
20+
??0?$AutoNTTPClass@$1?Func@@YAHXZ@@QEAA@XZ
21+
; CHECK: public: __cdecl AutoNTTPClass<&int __cdecl Func(void)>::AutoNTTPClass<&int __cdecl Func(void)>(void)
22+
23+
??0?$AutoNTTPClass@$MP6AHXZ1?Func@@YAHXZ$MP6AHXZ1?Func2@@YAHXZ@@QEAA@XZ
24+
; CHECK: public: __cdecl AutoNTTPClass<&int __cdecl Func(void), &int __cdecl Func2(void)>::AutoNTTPClass<&int __cdecl Func(void), &int __cdecl Func2(void)>(void)
25+
26+
??0?$AutoNTTPClass@$1?Func@@YAHXZ$1?Func2@@YAHXZ@@QEAA@XZ
27+
; CHECK: public: __cdecl AutoNTTPClass<&int __cdecl Func(void), &int __cdecl Func2(void)>::AutoNTTPClass<&int __cdecl Func(void), &int __cdecl Func2(void)>(void)
28+
29+
??$AutoFunc@$MPEAH1?i@@3HA@@YA?A?<auto>@@XZ
30+
; CHECK: <auto> __cdecl AutoFunc<&int i>(void)
31+
32+
??$AutoFunc@$1?i@@3HA@@YA?A?<auto>@@XZ
33+
; CHECK: <auto> __cdecl AutoFunc<&int i>(void)
34+
35+
??$AutoFunc@$MP6AHXZ1?Func@@YAHXZ@@YA?A?<auto>@@XZ
36+
; CHECK: <auto> __cdecl AutoFunc<&int __cdecl Func(void)>(void)
37+
38+
??$AutoFunc@$1?Func@@YAHXZ@@YA?A?<auto>@@XZ
39+
; CHECK: <auto> __cdecl AutoFunc<&int __cdecl Func(void)>(void)
40+
41+
??$AutoFunc@$MH00@@YA?A?<auto>@@XZ
42+
; CHECK: <auto> __cdecl AutoFunc<1>(void)
43+
44+
??$AutoFunc@$00@@YA?A?<auto>@@XZ
45+
; CHECK: <auto> __cdecl AutoFunc<1>(void)
46+
47+
??0?$AutoNTTPClass@$0A@@@QEAA@XZ
48+
; CHECK: public: __cdecl AutoNTTPClass<0>::AutoNTTPClass<0>(void)
49+
50+
??0?$AutoNTTPClass@$MH0A@@@QEAA@XZ
51+
; CHECK: public: __cdecl AutoNTTPClass<0>::AutoNTTPClass<0>(void)
52+
53+
??0?$AutoNTTPClass@$0A@$0A@$0GB@@@QEAA@XZ
54+
; CHECK: public: __cdecl AutoNTTPClass<0, 0, 97>::AutoNTTPClass<0, 0, 97>(void)
55+
56+
??0?$AutoNTTPClass@$MH0A@$M_N0A@$MD0GB@@@QEAA@XZ
57+
; CHECK: public: __cdecl AutoNTTPClass<0, 0, 97>::AutoNTTPClass<0, 0, 97>(void)

0 commit comments

Comments
 (0)