[llvm] [Demangle] demangle builtin type transformations (PR #65902)

Congcong Cai via llvm-commits llvm-commits at lists.llvm.org
Sun Sep 10 18:40:42 PDT 2023


https://github.com/HerrCai0907 updated https://github.com/llvm/llvm-project/pull/65902:

>From 8efd20185735a2009e7d6698007af3a3cf3a8c54 Mon Sep 17 00:00:00 2001
From: Congcong Cai <congcongcai0907 at 163.com>
Date: Sun, 10 Sep 2023 23:55:42 +0800
Subject: [PATCH 1/2] [Demangle] demangle builtin type transformations

Fixed: https://github.com/llvm/llvm-project/issues/62127
https://reviews.llvm.org/D116203 introduced several compiler builtin
equivalents of the unary type traits. In some cases (e.g. template) those
builtin will be dependent and need to be mangle.
This patch add the check for `u{builtin}I{type}E` to demangle it.

Reviewed By: rjmccall

Differential Revision: https://reviews.llvm.org/D148465
---
 libcxxabi/src/demangle/ItaniumDemangle.h     | 27 +++++++++++++++++++-
 libcxxabi/src/demangle/ItaniumNodes.def      |  1 +
 libcxxabi/test/test_demangle.pass.cpp        |  3 +++
 llvm/include/llvm/Demangle/ItaniumDemangle.h | 27 +++++++++++++++++++-
 llvm/include/llvm/Demangle/ItaniumNodes.def  |  1 +
 5 files changed, 57 insertions(+), 2 deletions(-)

diff --git a/libcxxabi/src/demangle/ItaniumDemangle.h b/libcxxabi/src/demangle/ItaniumDemangle.h
index c80f343cc876e99..92573a26e3f1d30 100644
--- a/libcxxabi/src/demangle/ItaniumDemangle.h
+++ b/libcxxabi/src/demangle/ItaniumDemangle.h
@@ -534,6 +534,23 @@ class ElaboratedTypeSpefType : public Node {
   }
 };
 
+class TransformedType : public Node {
+  std::string_view Transform;
+  Node *BaseType;
+public:
+  TransformedType(std::string_view Transform_, Node *BaseType_)
+      : Node(KTransformedType), Transform(Transform_), BaseType(BaseType_) {}
+
+  template<typename Fn> void match(Fn F) const { F(Transform, BaseType); }
+
+  void printLeft(OutputBuffer &OB) const override {
+    OB += Transform;
+    OB += '(';
+    BaseType->print(OB);
+    OB += ')';
+  }
+};
+
 struct AbiTagAttr : Node {
   Node *Base;
   std::string_view Tag;
@@ -3894,7 +3911,15 @@ Node *AbstractManglingParser<Derived, Alloc>::parseType() {
     // Typically, <builtin-type>s are not considered substitution candidates,
     // but the exception to that exception is vendor extended types (Itanium C++
     // ABI 5.9.1).
-    Result = make<NameType>(Res);
+    if (consumeIf('I')) {
+      Node *BaseType = parseType();
+      if (BaseType == nullptr)
+        return nullptr;
+      if (!consumeIf('E'))
+        return nullptr;
+      Result = make<TransformedType>(Res, BaseType);
+    } else
+      Result = make<NameType>(Res);
     break;
   }
   case 'D':
diff --git a/libcxxabi/src/demangle/ItaniumNodes.def b/libcxxabi/src/demangle/ItaniumNodes.def
index f615cb9fadb05e8..a54ee370a935b7a 100644
--- a/libcxxabi/src/demangle/ItaniumNodes.def
+++ b/libcxxabi/src/demangle/ItaniumNodes.def
@@ -19,6 +19,7 @@ NODE(QualType)
 NODE(ConversionOperatorType)
 NODE(PostfixQualifiedType)
 NODE(ElaboratedTypeSpefType)
+NODE(TransformedType)
 NODE(NameType)
 NODE(AbiTagAttr)
 NODE(EnableIfAttr)
diff --git a/libcxxabi/test/test_demangle.pass.cpp b/libcxxabi/test/test_demangle.pass.cpp
index 471808db5d5b8fc..891bc8b43d1bd47 100644
--- a/libcxxabi/test/test_demangle.pass.cpp
+++ b/libcxxabi/test/test_demangle.pass.cpp
@@ -30114,6 +30114,9 @@ const char* cases[][2] =
      " std::allocator<char>>::basic_string()"},
     {"_ZN1SB8ctor_tagC2Ev", "S[abi:ctor_tag]::S()"},
     {"_ZN1SB8ctor_tagD2Ev", "S[abi:ctor_tag]::~S()"},
+
+    // clang builtin type transform
+    {"_Z2f5IiEvu7__decayIT_E", "void f5<int>(__decay(int))"},
 };
 
 const unsigned N = sizeof(cases) / sizeof(cases[0]);
diff --git a/llvm/include/llvm/Demangle/ItaniumDemangle.h b/llvm/include/llvm/Demangle/ItaniumDemangle.h
index 26acd38f8ae8476..4fe203d0adab52c 100644
--- a/llvm/include/llvm/Demangle/ItaniumDemangle.h
+++ b/llvm/include/llvm/Demangle/ItaniumDemangle.h
@@ -528,6 +528,23 @@ class ElaboratedTypeSpefType : public Node {
   }
 };
 
+class TransformedType : public Node {
+  std::string_view Transform;
+  Node *BaseType;
+public:
+  TransformedType(std::string_view Transform_, Node *BaseType_)
+      : Node(KTransformedType), Transform(Transform_), BaseType(BaseType_) {}
+
+  template<typename Fn> void match(Fn F) const { F(Transform, BaseType); }
+
+  void printLeft(OutputBuffer &OB) const override {
+    OB += Transform;
+    OB += '(';
+    BaseType->print(OB);
+    OB += ')';
+  }
+};
+
 struct AbiTagAttr : Node {
   Node *Base;
   std::string_view Tag;
@@ -3889,7 +3906,15 @@ Node *AbstractManglingParser<Derived, Alloc>::parseType() {
     // Typically, <builtin-type>s are not considered substitution candidates,
     // but the exception to that exception is vendor extended types (Itanium C++
     // ABI 5.9.1).
-    Result = make<NameType>(Res);
+    if (consumeIf('I')) {
+      Node *BaseType = parseType();
+      if (BaseType == nullptr)
+        return nullptr;
+      if (!consumeIf('E'))
+        return nullptr;
+      Result = make<TransformedType>(Res, BaseType);
+    } else
+      Result = make<NameType>(Res);
     break;
   }
   case 'D':
diff --git a/llvm/include/llvm/Demangle/ItaniumNodes.def b/llvm/include/llvm/Demangle/ItaniumNodes.def
index c0e277d554ccfad..dafce502ce9e900 100644
--- a/llvm/include/llvm/Demangle/ItaniumNodes.def
+++ b/llvm/include/llvm/Demangle/ItaniumNodes.def
@@ -19,6 +19,7 @@ NODE(QualType)
 NODE(ConversionOperatorType)
 NODE(PostfixQualifiedType)
 NODE(ElaboratedTypeSpefType)
+NODE(TransformedType)
 NODE(NameType)
 NODE(AbiTagAttr)
 NODE(EnableIfAttr)

>From 6787f44f471b7fa4981f1a90ad4b4567dcba2c3f Mon Sep 17 00:00:00 2001
From: Congcong Cai <congcongcai0907 at 163.com>
Date: Mon, 11 Sep 2023 09:40:21 +0800
Subject: [PATCH 2/2] add test

---
 libcxxabi/test/test_demangle.pass.cpp | 6 ++++++
 1 file changed, 6 insertions(+)

diff --git a/libcxxabi/test/test_demangle.pass.cpp b/libcxxabi/test/test_demangle.pass.cpp
index 891bc8b43d1bd47..15e93d70ccbab44 100644
--- a/libcxxabi/test/test_demangle.pass.cpp
+++ b/libcxxabi/test/test_demangle.pass.cpp
@@ -30116,7 +30116,13 @@ const char* cases[][2] =
     {"_ZN1SB8ctor_tagD2Ev", "S[abi:ctor_tag]::~S()"},
 
     // clang builtin type transform
+    {"_Z2f5IiEvu22__add_lvalue_referenceIT_E", "void f5<int>(__add_lvalue_reference(int))"},
+    {"_Z2f5IiEvu13__add_pointerIT_E", "void f5<int>(__add_pointer(int))"},
     {"_Z2f5IiEvu7__decayIT_E", "void f5<int>(__decay(int))"},
+    {"_Z2f5IjEvu13__make_signedIT_E", "void f5<unsigned int>(__make_signed(unsigned int))"},
+    {"_Z2f5IKiEvu14__remove_constIT_E", "void f5<int const>(__remove_const(int const))"},
+    {"_Z2f5IPiEvu16__remove_pointerIT_E", "void f5<int*>(__remove_pointer(int*))"},
+    {"_Z2f5IiEvu14__remove_cvrefIT_E", "void f5<int>(__remove_cvref(int))"},
 };
 
 const unsigned N = sizeof(cases) / sizeof(cases[0]);



More information about the llvm-commits mailing list