[llvm] [llvm] [Demangle] Fix MSVC demangling for placeholder return types (PR #106178)

Max Winkler via llvm-commits llvm-commits at lists.llvm.org
Tue Aug 27 19:32:08 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 1/3] 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)

>From e2f4fe4493095def53d42f3e56772f506fbd7c9f Mon Sep 17 00:00:00 2001
From: MaxEW707 <max.enrico.winkler at gmail.com>
Date: Tue, 27 Aug 2024 19:25:55 -0700
Subject: [PATCH 2/3] revert

---
 .../include/llvm/Demangle/MicrosoftDemangle.h |  1 -
 .../llvm/Demangle/MicrosoftDemangleNodes.h    | 19 +--------------
 llvm/lib/Demangle/MicrosoftDemangle.cpp       | 24 -------------------
 llvm/lib/Demangle/MicrosoftDemangleNodes.cpp  |  8 -------
 4 files changed, 1 insertion(+), 51 deletions(-)

diff --git a/llvm/include/llvm/Demangle/MicrosoftDemangle.h b/llvm/include/llvm/Demangle/MicrosoftDemangle.h
index 2e6a750e3abef9..6891185a28e57f 100644
--- a/llvm/include/llvm/Demangle/MicrosoftDemangle.h
+++ b/llvm/include/llvm/Demangle/MicrosoftDemangle.h
@@ -173,7 +173,6 @@ 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 18d6cdb7554934..30ca43d2bde020 100644
--- a/llvm/include/llvm/Demangle/MicrosoftDemangleNodes.h
+++ b/llvm/include/llvm/Demangle/MicrosoftDemangleNodes.h
@@ -106,11 +106,6 @@ enum class PrimitiveKind {
   Nullptr,
 };
 
-enum class PlaceholderKind {
-  Auto,
-  DecltypeAuto,
-};
-
 enum class CharKind {
   Char,
   Char16,
@@ -256,8 +251,7 @@ enum class NodeKind {
   LocalStaticGuardVariable,
   FunctionSymbol,
   VariableSymbol,
-  SpecialTableSymbol,
-  PlaceholderType,
+  SpecialTableSymbol
 };
 
 struct Node {
@@ -276,7 +270,6 @@ struct Node {
 
 struct TypeNode;
 struct PrimitiveTypeNode;
-struct PlaceholderTypeNode;
 struct FunctionSignatureNode;
 struct IdentifierNode;
 struct NamedIdentifierNode;
@@ -325,16 +318,6 @@ 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 4f2ff5735b569a..c5835e8c2e989d 100644
--- a/llvm/lib/Demangle/MicrosoftDemangle.cpp
+++ b/llvm/lib/Demangle/MicrosoftDemangle.cpp
@@ -241,11 +241,6 @@ 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'))
@@ -1870,8 +1865,6 @@ 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);
   }
@@ -1985,23 +1978,6 @@ 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 25c64d75450202..9a9c34ec6d348c 100644
--- a/llvm/lib/Demangle/MicrosoftDemangleNodes.cpp
+++ b/llvm/lib/Demangle/MicrosoftDemangleNodes.cpp
@@ -153,14 +153,6 @@ 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, ", ");
 }

>From bd260f11331ca6b4dfa07366727d077603844ad4 Mon Sep 17 00:00:00 2001
From: MaxEW707 <max.enrico.winkler at gmail.com>
Date: Tue, 27 Aug 2024 19:31:52 -0700
Subject: [PATCH 3/3] PR Feedback

---
 llvm/include/llvm/Demangle/MicrosoftDemangleNodes.h | 2 ++
 llvm/lib/Demangle/MicrosoftDemangle.cpp             | 4 ++++
 llvm/lib/Demangle/MicrosoftDemangleNodes.cpp        | 2 ++
 3 files changed, 8 insertions(+)

diff --git a/llvm/include/llvm/Demangle/MicrosoftDemangleNodes.h b/llvm/include/llvm/Demangle/MicrosoftDemangleNodes.h
index 30ca43d2bde020..09b9d947464ae9 100644
--- a/llvm/include/llvm/Demangle/MicrosoftDemangleNodes.h
+++ b/llvm/include/llvm/Demangle/MicrosoftDemangleNodes.h
@@ -104,6 +104,8 @@ enum class PrimitiveKind {
   Double,
   Ldouble,
   Nullptr,
+  Auto,
+  DecltypeAuto,
 };
 
 enum class CharKind {
diff --git a/llvm/lib/Demangle/MicrosoftDemangle.cpp b/llvm/lib/Demangle/MicrosoftDemangle.cpp
index c5835e8c2e989d..aa65f3be29da77 100644
--- a/llvm/lib/Demangle/MicrosoftDemangle.cpp
+++ b/llvm/lib/Demangle/MicrosoftDemangle.cpp
@@ -2035,6 +2035,10 @@ Demangler::demanglePrimitiveType(std::string_view &MangledName) {
       return Arena.alloc<PrimitiveTypeNode>(PrimitiveKind::Char16);
     case 'U':
       return Arena.alloc<PrimitiveTypeNode>(PrimitiveKind::Char32);
+    case 'P':
+      return Arena.alloc<PrimitiveTypeNode>(PrimitiveKind::Auto);
+    case 'T':
+      return Arena.alloc<PrimitiveTypeNode>(PrimitiveKind::DecltypeAuto);
     }
     break;
   }
diff --git a/llvm/lib/Demangle/MicrosoftDemangleNodes.cpp b/llvm/lib/Demangle/MicrosoftDemangleNodes.cpp
index 9a9c34ec6d348c..ec6e67058c6836 100644
--- a/llvm/lib/Demangle/MicrosoftDemangleNodes.cpp
+++ b/llvm/lib/Demangle/MicrosoftDemangleNodes.cpp
@@ -149,6 +149,8 @@ void PrimitiveTypeNode::outputPre(OutputBuffer &OB, OutputFlags Flags) const {
     OUTPUT_ENUM_CLASS_VALUE(PrimitiveKind, Double, "double");
     OUTPUT_ENUM_CLASS_VALUE(PrimitiveKind, Ldouble, "long double");
     OUTPUT_ENUM_CLASS_VALUE(PrimitiveKind, Nullptr, "std::nullptr_t");
+    OUTPUT_ENUM_CLASS_VALUE(PrimitiveKind, Auto, "auto");
+    OUTPUT_ENUM_CLASS_VALUE(PrimitiveKind, DecltypeAuto, "decltype(auto)");
   }
   outputQualifiers(OB, Quals, true, false);
 }



More information about the llvm-commits mailing list