diff --git a/llvm/include/llvm/Demangle/ItaniumDemangle.h b/llvm/include/llvm/Demangle/ItaniumDemangle.h --- a/llvm/include/llvm/Demangle/ItaniumDemangle.h +++ b/llvm/include/llvm/Demangle/ItaniumDemangle.h @@ -527,6 +527,23 @@ } }; +class TransformedType : public Node { + StringView Transform; + Node *BaseType; +public: + TransformedType(StringView 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; StringView Tag; @@ -3884,7 +3901,15 @@ // 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/llvm/include/llvm/Demangle/ItaniumNodes.def b/llvm/include/llvm/Demangle/ItaniumNodes.def --- a/llvm/include/llvm/Demangle/ItaniumNodes.def +++ b/llvm/include/llvm/Demangle/ItaniumNodes.def @@ -19,6 +19,7 @@ NODE(ConversionOperatorType) NODE(PostfixQualifiedType) NODE(ElaboratedTypeSpefType) +NODE(TransformedType) NODE(NameType) NODE(AbiTagAttr) NODE(EnableIfAttr) diff --git a/llvm/unittests/Demangle/ItaniumDemangleTest.cpp b/llvm/unittests/Demangle/ItaniumDemangleTest.cpp --- a/llvm/unittests/Demangle/ItaniumDemangleTest.cpp +++ b/llvm/unittests/Demangle/ItaniumDemangleTest.cpp @@ -56,6 +56,11 @@ } } // namespace NodeMatcher +static std::string toString(OutputBuffer &OB) { + StringView SV = OB; + return {SV.begin(), SV.end()}; +} + // Verify Operator table is ordered TEST(ItaniumDemangle, OperatorOrdering) { struct TestParser : AbstractManglingParser {}; @@ -82,9 +87,24 @@ EXPECT_THAT(Parser.Types, testing::ElementsAre('i', 'j', 'l')); } -static std::string toString(OutputBuffer &OB) { - StringView SV = OB; - return {SV.begin(), SV.end()}; +TEST(ItaniumDemangle, TransformedType) { + struct TestParser : AbstractManglingParser { + std::vector Types; + TestParser(const char *Str) + : AbstractManglingParser(Str, Str + strlen(Str)) {} + Node *parseType() { + Node *N = AbstractManglingParser::parseType(); + OutputBuffer OB; + N->print(OB); + Types.push_back(toString(OB)); + return N; + } + }; + + TestParser Parser("_Z2f5IiEvu7__decayIT_E"); + ASSERT_NE(nullptr, Parser.parse()); + EXPECT_THAT(Parser.Types, + testing::ElementsAre("int", "void", "__decay(int)")); } TEST(ItaniumDemangle, HalfType) {