Skip to content

Commit f7d7506

Browse files
committed
Fix mangling for placeholder return types
1 parent 0ef8e71 commit f7d7506

File tree

5 files changed

+69
-1
lines changed

5 files changed

+69
-1
lines changed

llvm/include/llvm/Demangle/MicrosoftDemangle.h

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -173,6 +173,7 @@ class Demangler {
173173
TypeNode *demangleType(std::string_view &MangledName,
174174
QualifierMangleMode QMM);
175175
PrimitiveTypeNode *demanglePrimitiveType(std::string_view &MangledName);
176+
PlaceholderTypeNode *demanglePlaceholderType(std::string_view &MangledName);
176177
CustomTypeNode *demangleCustomType(std::string_view &MangledName);
177178
TagTypeNode *demangleClassType(std::string_view &MangledName);
178179
PointerTypeNode *demanglePointerType(std::string_view &MangledName);

llvm/include/llvm/Demangle/MicrosoftDemangleNodes.h

Lines changed: 18 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -106,6 +106,11 @@ enum class PrimitiveKind {
106106
Nullptr,
107107
};
108108

109+
enum class PlaceholderKind {
110+
Auto,
111+
DecltypeAuto,
112+
};
113+
109114
enum class CharKind {
110115
Char,
111116
Char16,
@@ -251,7 +256,8 @@ enum class NodeKind {
251256
LocalStaticGuardVariable,
252257
FunctionSymbol,
253258
VariableSymbol,
254-
SpecialTableSymbol
259+
SpecialTableSymbol,
260+
PlaceholderType,
255261
};
256262

257263
struct Node {
@@ -270,6 +276,7 @@ struct Node {
270276

271277
struct TypeNode;
272278
struct PrimitiveTypeNode;
279+
struct PlaceholderTypeNode;
273280
struct FunctionSignatureNode;
274281
struct IdentifierNode;
275282
struct NamedIdentifierNode;
@@ -318,6 +325,16 @@ struct PrimitiveTypeNode : public TypeNode {
318325
PrimitiveKind PrimKind;
319326
};
320327

328+
struct PlaceholderTypeNode : public TypeNode {
329+
explicit PlaceholderTypeNode(PlaceholderKind K)
330+
: TypeNode(NodeKind::PlaceholderType), PlaceholderKind(K) {}
331+
332+
void outputPre(OutputBuffer &OB, OutputFlags Flags) const override;
333+
void outputPost(OutputBuffer &OB, OutputFlags Flags) const override {}
334+
335+
PlaceholderKind PlaceholderKind;
336+
};
337+
321338
struct FunctionSignatureNode : public TypeNode {
322339
explicit FunctionSignatureNode(NodeKind K) : TypeNode(K) {}
323340
FunctionSignatureNode() : TypeNode(NodeKind::FunctionSignature) {}

llvm/lib/Demangle/MicrosoftDemangle.cpp

Lines changed: 24 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -241,6 +241,11 @@ static bool isFunctionType(std::string_view S) {
241241
llvm::itanium_demangle::starts_with(S, "$$A6");
242242
}
243243

244+
static bool isPlaceholderType(std::string_view S) {
245+
return llvm::itanium_demangle::starts_with(S, "_P") ||
246+
llvm::itanium_demangle::starts_with(S, "_T");
247+
}
248+
244249
static FunctionRefQualifier
245250
demangleFunctionRefQualifier(std::string_view &MangledName) {
246251
if (consumeFront(MangledName, 'G'))
@@ -1865,6 +1870,8 @@ TypeNode *Demangler::demangleType(std::string_view &MangledName,
18651870
}
18661871
} else if (isCustomType(MangledName)) {
18671872
Ty = demangleCustomType(MangledName);
1873+
} else if (isPlaceholderType(MangledName)) {
1874+
Ty = demanglePlaceholderType(MangledName);
18681875
} else {
18691876
Ty = demanglePrimitiveType(MangledName);
18701877
}
@@ -1978,6 +1985,23 @@ CustomTypeNode *Demangler::demangleCustomType(std::string_view &MangledName) {
19781985
return CTN;
19791986
}
19801987

1988+
PlaceholderTypeNode *
1989+
Demangler::demanglePlaceholderType(std::string_view &MangledName) {
1990+
assert(MangledName.front() == '_');
1991+
1992+
MangledName.remove_prefix(1);
1993+
const char F = MangledName.front();
1994+
MangledName.remove_prefix(1);
1995+
switch (F) {
1996+
case 'P':
1997+
return Arena.alloc<PlaceholderTypeNode>(PlaceholderKind::Auto);
1998+
case 'T':
1999+
return Arena.alloc<PlaceholderTypeNode>(PlaceholderKind::DecltypeAuto);
2000+
}
2001+
Error = true;
2002+
return nullptr;
2003+
}
2004+
19812005
// Reads a primitive type.
19822006
PrimitiveTypeNode *
19832007
Demangler::demanglePrimitiveType(std::string_view &MangledName) {

llvm/lib/Demangle/MicrosoftDemangleNodes.cpp

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -153,6 +153,14 @@ void PrimitiveTypeNode::outputPre(OutputBuffer &OB, OutputFlags Flags) const {
153153
outputQualifiers(OB, Quals, true, false);
154154
}
155155

156+
void PlaceholderTypeNode::outputPre(OutputBuffer &OB, OutputFlags Flags) const {
157+
switch (PlaceholderKind) {
158+
OUTPUT_ENUM_CLASS_VALUE(PlaceholderKind, Auto, "auto");
159+
OUTPUT_ENUM_CLASS_VALUE(PlaceholderKind, DecltypeAuto, "decltype(auto)");
160+
};
161+
outputQualifiers(OB, Quals, true, false);
162+
}
163+
156164
void NodeArrayNode::output(OutputBuffer &OB, OutputFlags Flags) const {
157165
output(OB, Flags, ", ");
158166
}
Lines changed: 18 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,18 @@
1+
; RUN: llvm-undname < %s | FileCheck %s
2+
3+
; CHECK-NOT: Invalid mangled name
4+
5+
?TestNonTemplateAuto@@YA@XZ
6+
; CHECK: __cdecl TestNonTemplateAuto(void)
7+
8+
??$AutoT@X@@YA?A_PXZ
9+
; CHECK: auto __cdecl AutoT<void>(void)
10+
11+
??$AutoT@X@@YA?B_PXZ
12+
; CHECK: auto const __cdecl AutoT<void>(void)
13+
14+
??$AutoT@X@@YA?A_TXZ
15+
; CHECK: decltype(auto) __cdecl AutoT<void>(void)
16+
17+
??$AutoT@X@@YA?B_TXZ
18+
; CHECK: decltype(auto) const __cdecl AutoT<void>(void)

0 commit comments

Comments
 (0)