From 4bc4d51c18d5c087dfbdad1753c84bba8dbf3be0 Mon Sep 17 00:00:00 2001 From: Congcong Cai Date: Thu, 21 Sep 2023 14:23:58 +0800 Subject: [Demangle] demangle builtin type transformations (#65902) 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 | 9 +++++++++ 3 files changed, 36 insertions(+), 1 deletion(-) (limited to 'libcxxabi') diff --git a/libcxxabi/src/demangle/ItaniumDemangle.h b/libcxxabi/src/demangle/ItaniumDemangle.h index 6fdfe38..2336b84 100644 --- a/libcxxabi/src/demangle/ItaniumDemangle.h +++ b/libcxxabi/src/demangle/ItaniumDemangle.h @@ -534,6 +534,23 @@ public: } }; +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 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; @@ -4125,7 +4142,15 @@ Node *AbstractManglingParser::parseType() { // Typically, s are not considered substitution candidates, // but the exception to that exception is vendor extended types (Itanium C++ // ABI 5.9.1). - Result = make(Res); + if (consumeIf('I')) { + Node *BaseType = parseType(); + if (BaseType == nullptr) + return nullptr; + if (!consumeIf('E')) + return nullptr; + Result = make(Res, BaseType); + } else + Result = make(Res); break; } case 'D': diff --git a/libcxxabi/src/demangle/ItaniumNodes.def b/libcxxabi/src/demangle/ItaniumNodes.def index 74dc709..e27c111 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 47cc29b..df7bedc 100644 --- a/libcxxabi/test/test_demangle.pass.cpp +++ b/libcxxabi/test/test_demangle.pass.cpp @@ -30161,6 +30161,15 @@ const char* cases[][2] = " std::allocator>::basic_string()"}, {"_ZN1SB8ctor_tagC2Ev", "S[abi:ctor_tag]::S()"}, {"_ZN1SB8ctor_tagD2Ev", "S[abi:ctor_tag]::~S()"}, + + // clang builtin type transform + {"_Z2f5IiEvu22__add_lvalue_referenceIT_E", "void f5(__add_lvalue_reference(int))"}, + {"_Z2f5IiEvu13__add_pointerIT_E", "void f5(__add_pointer(int))"}, + {"_Z2f5IiEvu7__decayIT_E", "void f5(__decay(int))"}, + {"_Z2f5IjEvu13__make_signedIT_E", "void f5(__make_signed(unsigned int))"}, + {"_Z2f5IKiEvu14__remove_constIT_E", "void f5(__remove_const(int const))"}, + {"_Z2f5IPiEvu16__remove_pointerIT_E", "void f5(__remove_pointer(int*))"}, + {"_Z2f5IiEvu14__remove_cvrefIT_E", "void f5(__remove_cvref(int))"}, }; const unsigned N = sizeof(cases) / sizeof(cases[0]); -- cgit v1.1