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 @@ -280,17 +280,20 @@ class VendorExtQualType final : public Node { const Node *Ty; StringView Ext; + const Node *TA; public: - VendorExtQualType(const Node *Ty_, StringView Ext_) - : Node(KVendorExtQualType), Ty(Ty_), Ext(Ext_) {} + VendorExtQualType(const Node *Ty_, StringView Ext_, const Node *TA_) + : Node(KVendorExtQualType), Ty(Ty_), Ext(Ext_), TA(TA_) {} - template void match(Fn F) const { F(Ty, Ext); } + template void match(Fn F) const { F(Ty, Ext, TA); } void printLeft(OutputStream &S) const override { Ty->print(S); S += " "; S += Ext; + if (TA != nullptr) + TA->print(S); } }; @@ -3680,8 +3683,6 @@ if (Qual.empty()) return nullptr; - // FIXME parse the optional here! - // extension ::= U # objc-type if (Qual.startsWith("objcproto")) { StringView ProtoSourceName = Qual.dropFront(std::strlen("objcproto")); @@ -3699,10 +3700,17 @@ return make(Child, Proto); } + Node *TA = nullptr; + if (look() == 'I') { + TA = getDerived().parseTemplateArgs(); + if (TA == nullptr) + return nullptr; + } + Node *Child = getDerived().parseQualifiedType(); if (Child == nullptr) return nullptr; - return make(Child, Qual); + return make(Child, Qual, TA); } Qualifiers Quals = parseCVQualifiers(); diff --git a/llvm/test/tools/llvm-cxxfilt/ext-int.test b/llvm/test/tools/llvm-cxxfilt/ext-int.test new file mode 100644 --- /dev/null +++ b/llvm/test/tools/llvm-cxxfilt/ext-int.test @@ -0,0 +1,4 @@ +## Test vendor extended type qualifier with optional template args. +RUN: llvm-cxxfilt _Z29__spirv_ArbitraryFloatEQINTELILi79ELi79EEbU7_ExtIntIXT_EEiiU7_ExtIntIXT0_EEii | FileCheck %s + +CHECK: bool __spirv_ArbitraryFloatEQINTEL<79, 79>(int _ExtInt<79>, int, int _ExtInt<79>, int)