[llvm] [llvm] [Demangle] Fix MSVC demangling for placeholder return types (PR #106178)
Max Winkler via llvm-commits
llvm-commits at lists.llvm.org
Mon Aug 26 22:45:09 PDT 2024
https://github.com/MaxEW707 updated https://github.com/llvm/llvm-project/pull/106178
>From f7d7506efe4210cf286d7ddada98a908c553d670 Mon Sep 17 00:00:00 2001
From: MaxEW707 <max.enrico.winkler at gmail.com>
Date: Sun, 25 Aug 2024 10:40:16 -0700
Subject: [PATCH] Fix mangling for placeholder return types
---
.../include/llvm/Demangle/MicrosoftDemangle.h | 1 +
.../llvm/Demangle/MicrosoftDemangleNodes.h | 19 ++++++++++++++-
llvm/lib/Demangle/MicrosoftDemangle.cpp | 24 +++++++++++++++++++
llvm/lib/Demangle/MicrosoftDemangleNodes.cpp | 8 +++++++
.../Demangle/ms-placeholder-return-type.test | 18 ++++++++++++++
5 files changed, 69 insertions(+), 1 deletion(-)
create mode 100644 llvm/test/Demangle/ms-placeholder-return-type.test
diff --git a/llvm/include/llvm/Demangle/MicrosoftDemangle.h b/llvm/include/llvm/Demangle/MicrosoftDemangle.h
index 6891185a28e57f..2e6a750e3abef9 100644
--- a/llvm/include/llvm/Demangle/MicrosoftDemangle.h
+++ b/llvm/include/llvm/Demangle/MicrosoftDemangle.h
@@ -173,6 +173,7 @@ class Demangler {
TypeNode *demangleType(std::string_view &MangledName,
QualifierMangleMode QMM);
PrimitiveTypeNode *demanglePrimitiveType(std::string_view &MangledName);
+ PlaceholderTypeNode *demanglePlaceholderType(std::string_view &MangledName);
CustomTypeNode *demangleCustomType(std::string_view &MangledName);
TagTypeNode *demangleClassType(std::string_view &MangledName);
PointerTypeNode *demanglePointerType(std::string_view &MangledName);
diff --git a/llvm/include/llvm/Demangle/MicrosoftDemangleNodes.h b/llvm/include/llvm/Demangle/MicrosoftDemangleNodes.h
index 30ca43d2bde020..18d6cdb7554934 100644
--- a/llvm/include/llvm/Demangle/MicrosoftDemangleNodes.h
+++ b/llvm/include/llvm/Demangle/MicrosoftDemangleNodes.h
@@ -106,6 +106,11 @@ enum class PrimitiveKind {
Nullptr,
};
+enum class PlaceholderKind {
+ Auto,
+ DecltypeAuto,
+};
+
enum class CharKind {
Char,
Char16,
@@ -251,7 +256,8 @@ enum class NodeKind {
LocalStaticGuardVariable,
FunctionSymbol,
VariableSymbol,
- SpecialTableSymbol
+ SpecialTableSymbol,
+ PlaceholderType,
};
struct Node {
@@ -270,6 +276,7 @@ struct Node {
struct TypeNode;
struct PrimitiveTypeNode;
+struct PlaceholderTypeNode;
struct FunctionSignatureNode;
struct IdentifierNode;
struct NamedIdentifierNode;
@@ -318,6 +325,16 @@ struct PrimitiveTypeNode : public TypeNode {
PrimitiveKind PrimKind;
};
+struct PlaceholderTypeNode : public TypeNode {
+ explicit PlaceholderTypeNode(PlaceholderKind K)
+ : TypeNode(NodeKind::PlaceholderType), PlaceholderKind(K) {}
+
+ void outputPre(OutputBuffer &OB, OutputFlags Flags) const override;
+ void outputPost(OutputBuffer &OB, OutputFlags Flags) const override {}
+
+ PlaceholderKind PlaceholderKind;
+};
+
struct FunctionSignatureNode : public TypeNode {
explicit FunctionSignatureNode(NodeKind K) : TypeNode(K) {}
FunctionSignatureNode() : TypeNode(NodeKind::FunctionSignature) {}
diff --git a/llvm/lib/Demangle/MicrosoftDemangle.cpp b/llvm/lib/Demangle/MicrosoftDemangle.cpp
index c5835e8c2e989d..4f2ff5735b569a 100644
--- a/llvm/lib/Demangle/MicrosoftDemangle.cpp
+++ b/llvm/lib/Demangle/MicrosoftDemangle.cpp
@@ -241,6 +241,11 @@ static bool isFunctionType(std::string_view S) {
llvm::itanium_demangle::starts_with(S, "$$A6");
}
+static bool isPlaceholderType(std::string_view S) {
+ return llvm::itanium_demangle::starts_with(S, "_P") ||
+ llvm::itanium_demangle::starts_with(S, "_T");
+}
+
static FunctionRefQualifier
demangleFunctionRefQualifier(std::string_view &MangledName) {
if (consumeFront(MangledName, 'G'))
@@ -1865,6 +1870,8 @@ TypeNode *Demangler::demangleType(std::string_view &MangledName,
}
} else if (isCustomType(MangledName)) {
Ty = demangleCustomType(MangledName);
+ } else if (isPlaceholderType(MangledName)) {
+ Ty = demanglePlaceholderType(MangledName);
} else {
Ty = demanglePrimitiveType(MangledName);
}
@@ -1978,6 +1985,23 @@ CustomTypeNode *Demangler::demangleCustomType(std::string_view &MangledName) {
return CTN;
}
+PlaceholderTypeNode *
+Demangler::demanglePlaceholderType(std::string_view &MangledName) {
+ assert(MangledName.front() == '_');
+
+ MangledName.remove_prefix(1);
+ const char F = MangledName.front();
+ MangledName.remove_prefix(1);
+ switch (F) {
+ case 'P':
+ return Arena.alloc<PlaceholderTypeNode>(PlaceholderKind::Auto);
+ case 'T':
+ return Arena.alloc<PlaceholderTypeNode>(PlaceholderKind::DecltypeAuto);
+ }
+ Error = true;
+ return nullptr;
+}
+
// Reads a primitive type.
PrimitiveTypeNode *
Demangler::demanglePrimitiveType(std::string_view &MangledName) {
diff --git a/llvm/lib/Demangle/MicrosoftDemangleNodes.cpp b/llvm/lib/Demangle/MicrosoftDemangleNodes.cpp
index 9a9c34ec6d348c..25c64d75450202 100644
--- a/llvm/lib/Demangle/MicrosoftDemangleNodes.cpp
+++ b/llvm/lib/Demangle/MicrosoftDemangleNodes.cpp
@@ -153,6 +153,14 @@ void PrimitiveTypeNode::outputPre(OutputBuffer &OB, OutputFlags Flags) const {
outputQualifiers(OB, Quals, true, false);
}
+void PlaceholderTypeNode::outputPre(OutputBuffer &OB, OutputFlags Flags) const {
+ switch (PlaceholderKind) {
+ OUTPUT_ENUM_CLASS_VALUE(PlaceholderKind, Auto, "auto");
+ OUTPUT_ENUM_CLASS_VALUE(PlaceholderKind, DecltypeAuto, "decltype(auto)");
+ };
+ outputQualifiers(OB, Quals, true, false);
+}
+
void NodeArrayNode::output(OutputBuffer &OB, OutputFlags Flags) const {
output(OB, Flags, ", ");
}
diff --git a/llvm/test/Demangle/ms-placeholder-return-type.test b/llvm/test/Demangle/ms-placeholder-return-type.test
new file mode 100644
index 00000000000000..18038e636c8d5a
--- /dev/null
+++ b/llvm/test/Demangle/ms-placeholder-return-type.test
@@ -0,0 +1,18 @@
+; RUN: llvm-undname < %s | FileCheck %s
+
+; CHECK-NOT: Invalid mangled name
+
+?TestNonTemplateAuto@@YA at XZ
+; CHECK: __cdecl TestNonTemplateAuto(void)
+
+??$AutoT at X@@YA?A_PXZ
+; CHECK: auto __cdecl AutoT<void>(void)
+
+??$AutoT at X@@YA?B_PXZ
+; CHECK: auto const __cdecl AutoT<void>(void)
+
+??$AutoT at X@@YA?A_TXZ
+; CHECK: decltype(auto) __cdecl AutoT<void>(void)
+
+??$AutoT at X@@YA?B_TXZ
+; CHECK: decltype(auto) const __cdecl AutoT<void>(void)
More information about the llvm-commits
mailing list