1 //===------------------------- ItaniumDemangle.h ----------------*- C++ -*-===//
3 // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
4 // See https://llvm.org/LICENSE.txt for license information.
5 // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
7 //===----------------------------------------------------------------------===//
9 // Generic itanium demangler library. This file has two byte-per-byte identical
10 // copies in the source tree, one in libcxxabi, and the other in llvm.
12 //===----------------------------------------------------------------------===//
14 #ifndef DEMANGLE_ITANIUMDEMANGLE_H
15 #define DEMANGLE_ITANIUMDEMANGLE_H
17 // FIXME: (possibly) incomplete list of features that clang mangles that this
18 // file does not yet support:
21 #include "DemangleConfig.h"
22 #include "StringView.h"
32 #define FOR_EACH_NODE_KIND(X) \
35 X(VendorExtQualType) \
37 X(ConversionOperatorType) \
38 X(PostfixQualifiedType) \
39 X(ElaboratedTypeSpefType) \
46 X(PointerToMemberType) \
50 X(DynamicExceptionSpec) \
54 X(CtorVtableSpecialName) \
60 X(SyntheticTemplateParamName) \
61 X(TypeTemplateParamDecl) \
62 X(NonTypeTemplateParamDecl) \
63 X(TemplateTemplateParamDecl) \
64 X(TemplateParamPackDecl) \
66 X(TemplateArgumentPack) \
67 X(ParameterPackExpansion) \
69 X(ForwardTemplateReference) \
70 X(NameWithTemplateArgs) \
71 X(GlobalQualifiedName) \
73 X(ExpandedSpecialSubstitution) \
74 X(SpecialSubstitution) \
79 X(StructuredBindingName) \
81 X(ArraySubscriptExpr) \
87 X(SizeofParamPackExpr) \
105 X(LongDoubleLiteral) \
109 DEMANGLE_NAMESPACE_BEGIN
111 // Base class of all AST nodes. The AST is built by the parser, then is
112 // traversed by the printLeft/Right functions to produce a demangled string.
115 enum Kind
: unsigned char {
116 #define ENUMERATOR(NodeKind) K ## NodeKind,
117 FOR_EACH_NODE_KIND(ENUMERATOR
)
121 /// Three-way bool to track a cached value. Unknown is possible if this node
122 /// has an unexpanded parameter pack below it that may affect this cache.
123 enum class Cache
: unsigned char { Yes
, No
, Unknown
, };
128 // FIXME: Make these protected.
130 /// Tracks if this node has a component on its right side, in which case we
131 /// need to call printRight.
132 Cache RHSComponentCache
;
134 /// Track if this node is a (possibly qualified) array type. This can affect
135 /// how we format the output string.
138 /// Track if this node is a (possibly qualified) function type. This can
139 /// affect how we format the output string.
143 Node(Kind K_
, Cache RHSComponentCache_
= Cache::No
,
144 Cache ArrayCache_
= Cache::No
, Cache FunctionCache_
= Cache::No
)
145 : K(K_
), RHSComponentCache(RHSComponentCache_
), ArrayCache(ArrayCache_
),
146 FunctionCache(FunctionCache_
) {}
148 /// Visit the most-derived object corresponding to this object.
149 template<typename Fn
> void visit(Fn F
) const;
151 // The following function is provided by all derived classes:
153 // Call F with arguments that, when passed to the constructor of this node,
154 // would construct an equivalent node.
155 //template<typename Fn> void match(Fn F) const;
157 bool hasRHSComponent(OutputStream
&S
) const {
158 if (RHSComponentCache
!= Cache::Unknown
)
159 return RHSComponentCache
== Cache::Yes
;
160 return hasRHSComponentSlow(S
);
163 bool hasArray(OutputStream
&S
) const {
164 if (ArrayCache
!= Cache::Unknown
)
165 return ArrayCache
== Cache::Yes
;
166 return hasArraySlow(S
);
169 bool hasFunction(OutputStream
&S
) const {
170 if (FunctionCache
!= Cache::Unknown
)
171 return FunctionCache
== Cache::Yes
;
172 return hasFunctionSlow(S
);
175 Kind
getKind() const { return K
; }
177 virtual bool hasRHSComponentSlow(OutputStream
&) const { return false; }
178 virtual bool hasArraySlow(OutputStream
&) const { return false; }
179 virtual bool hasFunctionSlow(OutputStream
&) const { return false; }
181 // Dig through "glue" nodes like ParameterPack and ForwardTemplateReference to
182 // get at a node that actually represents some concrete syntax.
183 virtual const Node
*getSyntaxNode(OutputStream
&) const {
187 void print(OutputStream
&S
) const {
189 if (RHSComponentCache
!= Cache::No
)
193 // Print the "left" side of this Node into OutputStream.
194 virtual void printLeft(OutputStream
&) const = 0;
196 // Print the "right". This distinction is necessary to represent C++ types
197 // that appear on the RHS of their subtype, such as arrays or functions.
198 // Since most types don't have such a component, provide a default
200 virtual void printRight(OutputStream
&) const {}
202 virtual StringView
getBaseName() const { return StringView(); }
204 // Silence compiler warnings, this dtor will never be called.
205 virtual ~Node() = default;
208 DEMANGLE_DUMP_METHOD
void dump() const;
217 NodeArray() : Elements(nullptr), NumElements(0) {}
218 NodeArray(Node
**Elements_
, size_t NumElements_
)
219 : Elements(Elements_
), NumElements(NumElements_
) {}
221 bool empty() const { return NumElements
== 0; }
222 size_t size() const { return NumElements
; }
224 Node
**begin() const { return Elements
; }
225 Node
**end() const { return Elements
+ NumElements
; }
227 Node
*operator[](size_t Idx
) const { return Elements
[Idx
]; }
229 void printWithComma(OutputStream
&S
) const {
230 bool FirstElement
= true;
231 for (size_t Idx
= 0; Idx
!= NumElements
; ++Idx
) {
232 size_t BeforeComma
= S
.getCurrentPosition();
235 size_t AfterComma
= S
.getCurrentPosition();
236 Elements
[Idx
]->print(S
);
238 // Elements[Idx] is an empty parameter pack expansion, we should erase the
239 // comma we just printed.
240 if (AfterComma
== S
.getCurrentPosition()) {
241 S
.setCurrentPosition(BeforeComma
);
245 FirstElement
= false;
250 struct NodeArrayNode
: Node
{
252 NodeArrayNode(NodeArray Array_
) : Node(KNodeArrayNode
), Array(Array_
) {}
254 template<typename Fn
> void match(Fn F
) const { F(Array
); }
256 void printLeft(OutputStream
&S
) const override
{
257 Array
.printWithComma(S
);
261 class DotSuffix final
: public Node
{
263 const StringView Suffix
;
266 DotSuffix(const Node
*Prefix_
, StringView Suffix_
)
267 : Node(KDotSuffix
), Prefix(Prefix_
), Suffix(Suffix_
) {}
269 template<typename Fn
> void match(Fn F
) const { F(Prefix
, Suffix
); }
271 void printLeft(OutputStream
&s
) const override
{
279 class VendorExtQualType final
: public Node
{
284 VendorExtQualType(const Node
*Ty_
, StringView Ext_
)
285 : Node(KVendorExtQualType
), Ty(Ty_
), Ext(Ext_
) {}
287 template<typename Fn
> void match(Fn F
) const { F(Ty
, Ext
); }
289 void printLeft(OutputStream
&S
) const override
{
296 enum FunctionRefQual
: unsigned char {
309 inline Qualifiers
operator|=(Qualifiers
&Q1
, Qualifiers Q2
) {
310 return Q1
= static_cast<Qualifiers
>(Q1
| Q2
);
313 class QualType final
: public Node
{
315 const Qualifiers Quals
;
318 void printQuals(OutputStream
&S
) const {
319 if (Quals
& QualConst
)
321 if (Quals
& QualVolatile
)
323 if (Quals
& QualRestrict
)
328 QualType(const Node
*Child_
, Qualifiers Quals_
)
329 : Node(KQualType
, Child_
->RHSComponentCache
,
330 Child_
->ArrayCache
, Child_
->FunctionCache
),
331 Quals(Quals_
), Child(Child_
) {}
333 template<typename Fn
> void match(Fn F
) const { F(Child
, Quals
); }
335 bool hasRHSComponentSlow(OutputStream
&S
) const override
{
336 return Child
->hasRHSComponent(S
);
338 bool hasArraySlow(OutputStream
&S
) const override
{
339 return Child
->hasArray(S
);
341 bool hasFunctionSlow(OutputStream
&S
) const override
{
342 return Child
->hasFunction(S
);
345 void printLeft(OutputStream
&S
) const override
{
350 void printRight(OutputStream
&S
) const override
{ Child
->printRight(S
); }
353 class ConversionOperatorType final
: public Node
{
357 ConversionOperatorType(const Node
*Ty_
)
358 : Node(KConversionOperatorType
), Ty(Ty_
) {}
360 template<typename Fn
> void match(Fn F
) const { F(Ty
); }
362 void printLeft(OutputStream
&S
) const override
{
368 class PostfixQualifiedType final
: public Node
{
370 const StringView Postfix
;
373 PostfixQualifiedType(Node
*Ty_
, StringView Postfix_
)
374 : Node(KPostfixQualifiedType
), Ty(Ty_
), Postfix(Postfix_
) {}
376 template<typename Fn
> void match(Fn F
) const { F(Ty
, Postfix
); }
378 void printLeft(OutputStream
&s
) const override
{
384 class NameType final
: public Node
{
385 const StringView Name
;
388 NameType(StringView Name_
) : Node(KNameType
), Name(Name_
) {}
390 template<typename Fn
> void match(Fn F
) const { F(Name
); }
392 StringView
getName() const { return Name
; }
393 StringView
getBaseName() const override
{ return Name
; }
395 void printLeft(OutputStream
&s
) const override
{ s
+= Name
; }
398 class ElaboratedTypeSpefType
: public Node
{
402 ElaboratedTypeSpefType(StringView Kind_
, Node
*Child_
)
403 : Node(KElaboratedTypeSpefType
), Kind(Kind_
), Child(Child_
) {}
405 template<typename Fn
> void match(Fn F
) const { F(Kind
, Child
); }
407 void printLeft(OutputStream
&S
) const override
{
414 struct AbiTagAttr
: Node
{
418 AbiTagAttr(Node
* Base_
, StringView Tag_
)
419 : Node(KAbiTagAttr
, Base_
->RHSComponentCache
,
420 Base_
->ArrayCache
, Base_
->FunctionCache
),
421 Base(Base_
), Tag(Tag_
) {}
423 template<typename Fn
> void match(Fn F
) const { F(Base
, Tag
); }
425 void printLeft(OutputStream
&S
) const override
{
433 class EnableIfAttr
: public Node
{
434 NodeArray Conditions
;
436 EnableIfAttr(NodeArray Conditions_
)
437 : Node(KEnableIfAttr
), Conditions(Conditions_
) {}
439 template<typename Fn
> void match(Fn F
) const { F(Conditions
); }
441 void printLeft(OutputStream
&S
) const override
{
443 Conditions
.printWithComma(S
);
448 class ObjCProtoName
: public Node
{
452 friend class PointerType
;
455 ObjCProtoName(const Node
*Ty_
, StringView Protocol_
)
456 : Node(KObjCProtoName
), Ty(Ty_
), Protocol(Protocol_
) {}
458 template<typename Fn
> void match(Fn F
) const { F(Ty
, Protocol
); }
460 bool isObjCObject() const {
461 return Ty
->getKind() == KNameType
&&
462 static_cast<const NameType
*>(Ty
)->getName() == "objc_object";
465 void printLeft(OutputStream
&S
) const override
{
473 class PointerType final
: public Node
{
477 PointerType(const Node
*Pointee_
)
478 : Node(KPointerType
, Pointee_
->RHSComponentCache
),
481 template<typename Fn
> void match(Fn F
) const { F(Pointee
); }
483 bool hasRHSComponentSlow(OutputStream
&S
) const override
{
484 return Pointee
->hasRHSComponent(S
);
487 void printLeft(OutputStream
&s
) const override
{
488 // We rewrite objc_object<SomeProtocol>* into id<SomeProtocol>.
489 if (Pointee
->getKind() != KObjCProtoName
||
490 !static_cast<const ObjCProtoName
*>(Pointee
)->isObjCObject()) {
491 Pointee
->printLeft(s
);
492 if (Pointee
->hasArray(s
))
494 if (Pointee
->hasArray(s
) || Pointee
->hasFunction(s
))
498 const auto *objcProto
= static_cast<const ObjCProtoName
*>(Pointee
);
500 s
+= objcProto
->Protocol
;
505 void printRight(OutputStream
&s
) const override
{
506 if (Pointee
->getKind() != KObjCProtoName
||
507 !static_cast<const ObjCProtoName
*>(Pointee
)->isObjCObject()) {
508 if (Pointee
->hasArray(s
) || Pointee
->hasFunction(s
))
510 Pointee
->printRight(s
);
515 enum class ReferenceKind
{
520 // Represents either a LValue or an RValue reference type.
521 class ReferenceType
: public Node
{
525 mutable bool Printing
= false;
527 // Dig through any refs to refs, collapsing the ReferenceTypes as we go. The
528 // rule here is rvalue ref to rvalue ref collapses to a rvalue ref, and any
529 // other combination collapses to a lvalue ref.
530 std::pair
<ReferenceKind
, const Node
*> collapse(OutputStream
&S
) const {
531 auto SoFar
= std::make_pair(RK
, Pointee
);
533 const Node
*SN
= SoFar
.second
->getSyntaxNode(S
);
534 if (SN
->getKind() != KReferenceType
)
536 auto *RT
= static_cast<const ReferenceType
*>(SN
);
537 SoFar
.second
= RT
->Pointee
;
538 SoFar
.first
= std::min(SoFar
.first
, RT
->RK
);
544 ReferenceType(const Node
*Pointee_
, ReferenceKind RK_
)
545 : Node(KReferenceType
, Pointee_
->RHSComponentCache
),
546 Pointee(Pointee_
), RK(RK_
) {}
548 template<typename Fn
> void match(Fn F
) const { F(Pointee
, RK
); }
550 bool hasRHSComponentSlow(OutputStream
&S
) const override
{
551 return Pointee
->hasRHSComponent(S
);
554 void printLeft(OutputStream
&s
) const override
{
557 SwapAndRestore
<bool> SavePrinting(Printing
, true);
558 std::pair
<ReferenceKind
, const Node
*> Collapsed
= collapse(s
);
559 Collapsed
.second
->printLeft(s
);
560 if (Collapsed
.second
->hasArray(s
))
562 if (Collapsed
.second
->hasArray(s
) || Collapsed
.second
->hasFunction(s
))
565 s
+= (Collapsed
.first
== ReferenceKind::LValue
? "&" : "&&");
567 void printRight(OutputStream
&s
) const override
{
570 SwapAndRestore
<bool> SavePrinting(Printing
, true);
571 std::pair
<ReferenceKind
, const Node
*> Collapsed
= collapse(s
);
572 if (Collapsed
.second
->hasArray(s
) || Collapsed
.second
->hasFunction(s
))
574 Collapsed
.second
->printRight(s
);
578 class PointerToMemberType final
: public Node
{
579 const Node
*ClassType
;
580 const Node
*MemberType
;
583 PointerToMemberType(const Node
*ClassType_
, const Node
*MemberType_
)
584 : Node(KPointerToMemberType
, MemberType_
->RHSComponentCache
),
585 ClassType(ClassType_
), MemberType(MemberType_
) {}
587 template<typename Fn
> void match(Fn F
) const { F(ClassType
, MemberType
); }
589 bool hasRHSComponentSlow(OutputStream
&S
) const override
{
590 return MemberType
->hasRHSComponent(S
);
593 void printLeft(OutputStream
&s
) const override
{
594 MemberType
->printLeft(s
);
595 if (MemberType
->hasArray(s
) || MemberType
->hasFunction(s
))
603 void printRight(OutputStream
&s
) const override
{
604 if (MemberType
->hasArray(s
) || MemberType
->hasFunction(s
))
606 MemberType
->printRight(s
);
615 /* implicit */ NodeOrString(StringView Str
) {
616 const char *FirstChar
= Str
.begin();
617 const char *SecondChar
= Str
.end();
618 if (SecondChar
== nullptr) {
619 assert(FirstChar
== SecondChar
);
620 ++FirstChar
, ++SecondChar
;
622 First
= static_cast<const void *>(FirstChar
);
623 Second
= static_cast<const void *>(SecondChar
);
626 /* implicit */ NodeOrString(Node
*N
)
627 : First(static_cast<const void *>(N
)), Second(nullptr) {}
628 NodeOrString() : First(nullptr), Second(nullptr) {}
630 bool isString() const { return Second
&& First
; }
631 bool isNode() const { return First
&& !Second
; }
632 bool isEmpty() const { return !First
&& !Second
; }
634 StringView
asString() const {
636 return StringView(static_cast<const char *>(First
),
637 static_cast<const char *>(Second
));
640 const Node
*asNode() const {
642 return static_cast<const Node
*>(First
);
646 class ArrayType final
: public Node
{
648 NodeOrString Dimension
;
651 ArrayType(const Node
*Base_
, NodeOrString Dimension_
)
653 /*RHSComponentCache=*/Cache::Yes
,
654 /*ArrayCache=*/Cache::Yes
),
655 Base(Base_
), Dimension(Dimension_
) {}
657 template<typename Fn
> void match(Fn F
) const { F(Base
, Dimension
); }
659 bool hasRHSComponentSlow(OutputStream
&) const override
{ return true; }
660 bool hasArraySlow(OutputStream
&) const override
{ return true; }
662 void printLeft(OutputStream
&S
) const override
{ Base
->printLeft(S
); }
664 void printRight(OutputStream
&S
) const override
{
668 if (Dimension
.isString())
669 S
+= Dimension
.asString();
670 else if (Dimension
.isNode())
671 Dimension
.asNode()->print(S
);
677 class FunctionType final
: public Node
{
681 FunctionRefQual RefQual
;
682 const Node
*ExceptionSpec
;
685 FunctionType(const Node
*Ret_
, NodeArray Params_
, Qualifiers CVQuals_
,
686 FunctionRefQual RefQual_
, const Node
*ExceptionSpec_
)
687 : Node(KFunctionType
,
688 /*RHSComponentCache=*/Cache::Yes
, /*ArrayCache=*/Cache::No
,
689 /*FunctionCache=*/Cache::Yes
),
690 Ret(Ret_
), Params(Params_
), CVQuals(CVQuals_
), RefQual(RefQual_
),
691 ExceptionSpec(ExceptionSpec_
) {}
693 template<typename Fn
> void match(Fn F
) const {
694 F(Ret
, Params
, CVQuals
, RefQual
, ExceptionSpec
);
697 bool hasRHSComponentSlow(OutputStream
&) const override
{ return true; }
698 bool hasFunctionSlow(OutputStream
&) const override
{ return true; }
700 // Handle C++'s ... quirky decl grammar by using the left & right
701 // distinction. Consider:
702 // int (*f(float))(char) {}
703 // f is a function that takes a float and returns a pointer to a function
704 // that takes a char and returns an int. If we're trying to print f, start
705 // by printing out the return types's left, then print our parameters, then
706 // finally print right of the return type.
707 void printLeft(OutputStream
&S
) const override
{
712 void printRight(OutputStream
&S
) const override
{
714 Params
.printWithComma(S
);
718 if (CVQuals
& QualConst
)
720 if (CVQuals
& QualVolatile
)
722 if (CVQuals
& QualRestrict
)
725 if (RefQual
== FrefQualLValue
)
727 else if (RefQual
== FrefQualRValue
)
730 if (ExceptionSpec
!= nullptr) {
732 ExceptionSpec
->print(S
);
737 class NoexceptSpec
: public Node
{
740 NoexceptSpec(const Node
*E_
) : Node(KNoexceptSpec
), E(E_
) {}
742 template<typename Fn
> void match(Fn F
) const { F(E
); }
744 void printLeft(OutputStream
&S
) const override
{
751 class DynamicExceptionSpec
: public Node
{
754 DynamicExceptionSpec(NodeArray Types_
)
755 : Node(KDynamicExceptionSpec
), Types(Types_
) {}
757 template<typename Fn
> void match(Fn F
) const { F(Types
); }
759 void printLeft(OutputStream
&S
) const override
{
761 Types
.printWithComma(S
);
766 class FunctionEncoding final
: public Node
{
772 FunctionRefQual RefQual
;
775 FunctionEncoding(const Node
*Ret_
, const Node
*Name_
, NodeArray Params_
,
776 const Node
*Attrs_
, Qualifiers CVQuals_
,
777 FunctionRefQual RefQual_
)
778 : Node(KFunctionEncoding
,
779 /*RHSComponentCache=*/Cache::Yes
, /*ArrayCache=*/Cache::No
,
780 /*FunctionCache=*/Cache::Yes
),
781 Ret(Ret_
), Name(Name_
), Params(Params_
), Attrs(Attrs_
),
782 CVQuals(CVQuals_
), RefQual(RefQual_
) {}
784 template<typename Fn
> void match(Fn F
) const {
785 F(Ret
, Name
, Params
, Attrs
, CVQuals
, RefQual
);
788 Qualifiers
getCVQuals() const { return CVQuals
; }
789 FunctionRefQual
getRefQual() const { return RefQual
; }
790 NodeArray
getParams() const { return Params
; }
791 const Node
*getReturnType() const { return Ret
; }
793 bool hasRHSComponentSlow(OutputStream
&) const override
{ return true; }
794 bool hasFunctionSlow(OutputStream
&) const override
{ return true; }
796 const Node
*getName() const { return Name
; }
798 void printLeft(OutputStream
&S
) const override
{
801 if (!Ret
->hasRHSComponent(S
))
807 void printRight(OutputStream
&S
) const override
{
809 Params
.printWithComma(S
);
814 if (CVQuals
& QualConst
)
816 if (CVQuals
& QualVolatile
)
818 if (CVQuals
& QualRestrict
)
821 if (RefQual
== FrefQualLValue
)
823 else if (RefQual
== FrefQualRValue
)
826 if (Attrs
!= nullptr)
831 class LiteralOperator
: public Node
{
835 LiteralOperator(const Node
*OpName_
)
836 : Node(KLiteralOperator
), OpName(OpName_
) {}
838 template<typename Fn
> void match(Fn F
) const { F(OpName
); }
840 void printLeft(OutputStream
&S
) const override
{
841 S
+= "operator\"\" ";
846 class SpecialName final
: public Node
{
847 const StringView Special
;
851 SpecialName(StringView Special_
, const Node
*Child_
)
852 : Node(KSpecialName
), Special(Special_
), Child(Child_
) {}
854 template<typename Fn
> void match(Fn F
) const { F(Special
, Child
); }
856 void printLeft(OutputStream
&S
) const override
{
862 class CtorVtableSpecialName final
: public Node
{
863 const Node
*FirstType
;
864 const Node
*SecondType
;
867 CtorVtableSpecialName(const Node
*FirstType_
, const Node
*SecondType_
)
868 : Node(KCtorVtableSpecialName
),
869 FirstType(FirstType_
), SecondType(SecondType_
) {}
871 template<typename Fn
> void match(Fn F
) const { F(FirstType
, SecondType
); }
873 void printLeft(OutputStream
&S
) const override
{
874 S
+= "construction vtable for ";
877 SecondType
->print(S
);
881 struct NestedName
: Node
{
885 NestedName(Node
*Qual_
, Node
*Name_
)
886 : Node(KNestedName
), Qual(Qual_
), Name(Name_
) {}
888 template<typename Fn
> void match(Fn F
) const { F(Qual
, Name
); }
890 StringView
getBaseName() const override
{ return Name
->getBaseName(); }
892 void printLeft(OutputStream
&S
) const override
{
899 struct LocalName
: Node
{
903 LocalName(Node
*Encoding_
, Node
*Entity_
)
904 : Node(KLocalName
), Encoding(Encoding_
), Entity(Entity_
) {}
906 template<typename Fn
> void match(Fn F
) const { F(Encoding
, Entity
); }
908 void printLeft(OutputStream
&S
) const override
{
915 class QualifiedName final
: public Node
{
917 const Node
*Qualifier
;
921 QualifiedName(const Node
*Qualifier_
, const Node
*Name_
)
922 : Node(KQualifiedName
), Qualifier(Qualifier_
), Name(Name_
) {}
924 template<typename Fn
> void match(Fn F
) const { F(Qualifier
, Name
); }
926 StringView
getBaseName() const override
{ return Name
->getBaseName(); }
928 void printLeft(OutputStream
&S
) const override
{
935 class VectorType final
: public Node
{
936 const Node
*BaseType
;
937 const NodeOrString Dimension
;
940 VectorType(const Node
*BaseType_
, NodeOrString Dimension_
)
941 : Node(KVectorType
), BaseType(BaseType_
),
942 Dimension(Dimension_
) {}
944 template<typename Fn
> void match(Fn F
) const { F(BaseType
, Dimension
); }
946 void printLeft(OutputStream
&S
) const override
{
949 if (Dimension
.isNode())
950 Dimension
.asNode()->print(S
);
951 else if (Dimension
.isString())
952 S
+= Dimension
.asString();
957 class PixelVectorType final
: public Node
{
958 const NodeOrString Dimension
;
961 PixelVectorType(NodeOrString Dimension_
)
962 : Node(KPixelVectorType
), Dimension(Dimension_
) {}
964 template<typename Fn
> void match(Fn F
) const { F(Dimension
); }
966 void printLeft(OutputStream
&S
) const override
{
967 // FIXME: This should demangle as "vector pixel".
968 S
+= "pixel vector[";
969 S
+= Dimension
.asString();
974 enum class TemplateParamKind
{ Type
, NonType
, Template
};
976 /// An invented name for a template parameter for which we don't have a
977 /// corresponding template argument.
979 /// This node is created when parsing the <lambda-sig> for a lambda with
980 /// explicit template arguments, which might be referenced in the parameter
981 /// types appearing later in the <lambda-sig>.
982 class SyntheticTemplateParamName final
: public Node
{
983 TemplateParamKind Kind
;
987 SyntheticTemplateParamName(TemplateParamKind Kind_
, unsigned Index_
)
988 : Node(KSyntheticTemplateParamName
), Kind(Kind_
), Index(Index_
) {}
990 template<typename Fn
> void match(Fn F
) const { F(Kind
, Index
); }
992 void printLeft(OutputStream
&S
) const override
{
994 case TemplateParamKind::Type
:
997 case TemplateParamKind::NonType
:
1000 case TemplateParamKind::Template
:
1009 /// A template type parameter declaration, 'typename T'.
1010 class TypeTemplateParamDecl final
: public Node
{
1014 TypeTemplateParamDecl(Node
*Name_
)
1015 : Node(KTypeTemplateParamDecl
, Cache::Yes
), Name(Name_
) {}
1017 template<typename Fn
> void match(Fn F
) const { F(Name
); }
1019 void printLeft(OutputStream
&S
) const override
{
1023 void printRight(OutputStream
&S
) const override
{
1028 /// A non-type template parameter declaration, 'int N'.
1029 class NonTypeTemplateParamDecl final
: public Node
{
1034 NonTypeTemplateParamDecl(Node
*Name_
, Node
*Type_
)
1035 : Node(KNonTypeTemplateParamDecl
, Cache::Yes
), Name(Name_
), Type(Type_
) {}
1037 template<typename Fn
> void match(Fn F
) const { F(Name
, Type
); }
1039 void printLeft(OutputStream
&S
) const override
{
1041 if (!Type
->hasRHSComponent(S
))
1045 void printRight(OutputStream
&S
) const override
{
1047 Type
->printRight(S
);
1051 /// A template template parameter declaration,
1052 /// 'template<typename T> typename N'.
1053 class TemplateTemplateParamDecl final
: public Node
{
1058 TemplateTemplateParamDecl(Node
*Name_
, NodeArray Params_
)
1059 : Node(KTemplateTemplateParamDecl
, Cache::Yes
), Name(Name_
),
1062 template<typename Fn
> void match(Fn F
) const { F(Name
, Params
); }
1064 void printLeft(OutputStream
&S
) const override
{
1066 Params
.printWithComma(S
);
1070 void printRight(OutputStream
&S
) const override
{
1075 /// A template parameter pack declaration, 'typename ...T'.
1076 class TemplateParamPackDecl final
: public Node
{
1080 TemplateParamPackDecl(Node
*Param_
)
1081 : Node(KTemplateParamPackDecl
, Cache::Yes
), Param(Param_
) {}
1083 template<typename Fn
> void match(Fn F
) const { F(Param
); }
1085 void printLeft(OutputStream
&S
) const override
{
1086 Param
->printLeft(S
);
1090 void printRight(OutputStream
&S
) const override
{
1091 Param
->printRight(S
);
1095 /// An unexpanded parameter pack (either in the expression or type context). If
1096 /// this AST is correct, this node will have a ParameterPackExpansion node above
1099 /// This node is created when some <template-args> are found that apply to an
1100 /// <encoding>, and is stored in the TemplateParams table. In order for this to
1101 /// appear in the final AST, it has to referenced via a <template-param> (ie,
1103 class ParameterPack final
: public Node
{
1106 // Setup OutputStream for a pack expansion unless we're already expanding one.
1107 void initializePackExpansion(OutputStream
&S
) const {
1108 if (S
.CurrentPackMax
== std::numeric_limits
<unsigned>::max()) {
1109 S
.CurrentPackMax
= static_cast<unsigned>(Data
.size());
1110 S
.CurrentPackIndex
= 0;
1115 ParameterPack(NodeArray Data_
) : Node(KParameterPack
), Data(Data_
) {
1116 ArrayCache
= FunctionCache
= RHSComponentCache
= Cache::Unknown
;
1117 if (std::all_of(Data
.begin(), Data
.end(), [](Node
* P
) {
1118 return P
->ArrayCache
== Cache::No
;
1120 ArrayCache
= Cache::No
;
1121 if (std::all_of(Data
.begin(), Data
.end(), [](Node
* P
) {
1122 return P
->FunctionCache
== Cache::No
;
1124 FunctionCache
= Cache::No
;
1125 if (std::all_of(Data
.begin(), Data
.end(), [](Node
* P
) {
1126 return P
->RHSComponentCache
== Cache::No
;
1128 RHSComponentCache
= Cache::No
;
1131 template<typename Fn
> void match(Fn F
) const { F(Data
); }
1133 bool hasRHSComponentSlow(OutputStream
&S
) const override
{
1134 initializePackExpansion(S
);
1135 size_t Idx
= S
.CurrentPackIndex
;
1136 return Idx
< Data
.size() && Data
[Idx
]->hasRHSComponent(S
);
1138 bool hasArraySlow(OutputStream
&S
) const override
{
1139 initializePackExpansion(S
);
1140 size_t Idx
= S
.CurrentPackIndex
;
1141 return Idx
< Data
.size() && Data
[Idx
]->hasArray(S
);
1143 bool hasFunctionSlow(OutputStream
&S
) const override
{
1144 initializePackExpansion(S
);
1145 size_t Idx
= S
.CurrentPackIndex
;
1146 return Idx
< Data
.size() && Data
[Idx
]->hasFunction(S
);
1148 const Node
*getSyntaxNode(OutputStream
&S
) const override
{
1149 initializePackExpansion(S
);
1150 size_t Idx
= S
.CurrentPackIndex
;
1151 return Idx
< Data
.size() ? Data
[Idx
]->getSyntaxNode(S
) : this;
1154 void printLeft(OutputStream
&S
) const override
{
1155 initializePackExpansion(S
);
1156 size_t Idx
= S
.CurrentPackIndex
;
1157 if (Idx
< Data
.size())
1158 Data
[Idx
]->printLeft(S
);
1160 void printRight(OutputStream
&S
) const override
{
1161 initializePackExpansion(S
);
1162 size_t Idx
= S
.CurrentPackIndex
;
1163 if (Idx
< Data
.size())
1164 Data
[Idx
]->printRight(S
);
1168 /// A variadic template argument. This node represents an occurrence of
1169 /// J<something>E in some <template-args>. It isn't itself unexpanded, unless
1170 /// one of it's Elements is. The parser inserts a ParameterPack into the
1171 /// TemplateParams table if the <template-args> this pack belongs to apply to an
1173 class TemplateArgumentPack final
: public Node
{
1176 TemplateArgumentPack(NodeArray Elements_
)
1177 : Node(KTemplateArgumentPack
), Elements(Elements_
) {}
1179 template<typename Fn
> void match(Fn F
) const { F(Elements
); }
1181 NodeArray
getElements() const { return Elements
; }
1183 void printLeft(OutputStream
&S
) const override
{
1184 Elements
.printWithComma(S
);
1188 /// A pack expansion. Below this node, there are some unexpanded ParameterPacks
1189 /// which each have Child->ParameterPackSize elements.
1190 class ParameterPackExpansion final
: public Node
{
1194 ParameterPackExpansion(const Node
*Child_
)
1195 : Node(KParameterPackExpansion
), Child(Child_
) {}
1197 template<typename Fn
> void match(Fn F
) const { F(Child
); }
1199 const Node
*getChild() const { return Child
; }
1201 void printLeft(OutputStream
&S
) const override
{
1202 constexpr unsigned Max
= std::numeric_limits
<unsigned>::max();
1203 SwapAndRestore
<unsigned> SavePackIdx(S
.CurrentPackIndex
, Max
);
1204 SwapAndRestore
<unsigned> SavePackMax(S
.CurrentPackMax
, Max
);
1205 size_t StreamPos
= S
.getCurrentPosition();
1207 // Print the first element in the pack. If Child contains a ParameterPack,
1208 // it will set up S.CurrentPackMax and print the first element.
1211 // No ParameterPack was found in Child. This can occur if we've found a pack
1212 // expansion on a <function-param>.
1213 if (S
.CurrentPackMax
== Max
) {
1218 // We found a ParameterPack, but it has no elements. Erase whatever we may
1220 if (S
.CurrentPackMax
== 0) {
1221 S
.setCurrentPosition(StreamPos
);
1225 // Else, iterate through the rest of the elements in the pack.
1226 for (unsigned I
= 1, E
= S
.CurrentPackMax
; I
< E
; ++I
) {
1228 S
.CurrentPackIndex
= I
;
1234 class TemplateArgs final
: public Node
{
1238 TemplateArgs(NodeArray Params_
) : Node(KTemplateArgs
), Params(Params_
) {}
1240 template<typename Fn
> void match(Fn F
) const { F(Params
); }
1242 NodeArray
getParams() { return Params
; }
1244 void printLeft(OutputStream
&S
) const override
{
1246 Params
.printWithComma(S
);
1247 if (S
.back() == '>')
1253 /// A forward-reference to a template argument that was not known at the point
1254 /// where the template parameter name was parsed in a mangling.
1256 /// This is created when demangling the name of a specialization of a
1257 /// conversion function template:
1261 /// template<typename T> operator T*();
1265 /// When demangling a specialization of the conversion function template, we
1266 /// encounter the name of the template (including the \c T) before we reach
1267 /// the template argument list, so we cannot substitute the parameter name
1268 /// for the corresponding argument while parsing. Instead, we create a
1269 /// \c ForwardTemplateReference node that is resolved after we parse the
1270 /// template arguments.
1271 struct ForwardTemplateReference
: Node
{
1273 Node
*Ref
= nullptr;
1275 // If we're currently printing this node. It is possible (though invalid) for
1276 // a forward template reference to refer to itself via a substitution. This
1277 // creates a cyclic AST, which will stack overflow printing. To fix this, bail
1278 // out if more than one print* function is active.
1279 mutable bool Printing
= false;
1281 ForwardTemplateReference(size_t Index_
)
1282 : Node(KForwardTemplateReference
, Cache::Unknown
, Cache::Unknown
,
1286 // We don't provide a matcher for these, because the value of the node is
1287 // not determined by its construction parameters, and it generally needs
1288 // special handling.
1289 template<typename Fn
> void match(Fn F
) const = delete;
1291 bool hasRHSComponentSlow(OutputStream
&S
) const override
{
1294 SwapAndRestore
<bool> SavePrinting(Printing
, true);
1295 return Ref
->hasRHSComponent(S
);
1297 bool hasArraySlow(OutputStream
&S
) const override
{
1300 SwapAndRestore
<bool> SavePrinting(Printing
, true);
1301 return Ref
->hasArray(S
);
1303 bool hasFunctionSlow(OutputStream
&S
) const override
{
1306 SwapAndRestore
<bool> SavePrinting(Printing
, true);
1307 return Ref
->hasFunction(S
);
1309 const Node
*getSyntaxNode(OutputStream
&S
) const override
{
1312 SwapAndRestore
<bool> SavePrinting(Printing
, true);
1313 return Ref
->getSyntaxNode(S
);
1316 void printLeft(OutputStream
&S
) const override
{
1319 SwapAndRestore
<bool> SavePrinting(Printing
, true);
1322 void printRight(OutputStream
&S
) const override
{
1325 SwapAndRestore
<bool> SavePrinting(Printing
, true);
1330 struct NameWithTemplateArgs
: Node
{
1331 // name<template_args>
1335 NameWithTemplateArgs(Node
*Name_
, Node
*TemplateArgs_
)
1336 : Node(KNameWithTemplateArgs
), Name(Name_
), TemplateArgs(TemplateArgs_
) {}
1338 template<typename Fn
> void match(Fn F
) const { F(Name
, TemplateArgs
); }
1340 StringView
getBaseName() const override
{ return Name
->getBaseName(); }
1342 void printLeft(OutputStream
&S
) const override
{
1344 TemplateArgs
->print(S
);
1348 class GlobalQualifiedName final
: public Node
{
1352 GlobalQualifiedName(Node
* Child_
)
1353 : Node(KGlobalQualifiedName
), Child(Child_
) {}
1355 template<typename Fn
> void match(Fn F
) const { F(Child
); }
1357 StringView
getBaseName() const override
{ return Child
->getBaseName(); }
1359 void printLeft(OutputStream
&S
) const override
{
1365 struct StdQualifiedName
: Node
{
1368 StdQualifiedName(Node
*Child_
) : Node(KStdQualifiedName
), Child(Child_
) {}
1370 template<typename Fn
> void match(Fn F
) const { F(Child
); }
1372 StringView
getBaseName() const override
{ return Child
->getBaseName(); }
1374 void printLeft(OutputStream
&S
) const override
{
1380 enum class SpecialSubKind
{
1389 class ExpandedSpecialSubstitution final
: public Node
{
1393 ExpandedSpecialSubstitution(SpecialSubKind SSK_
)
1394 : Node(KExpandedSpecialSubstitution
), SSK(SSK_
) {}
1396 template<typename Fn
> void match(Fn F
) const { F(SSK
); }
1398 StringView
getBaseName() const override
{
1400 case SpecialSubKind::allocator
:
1401 return StringView("allocator");
1402 case SpecialSubKind::basic_string
:
1403 return StringView("basic_string");
1404 case SpecialSubKind::string
:
1405 return StringView("basic_string");
1406 case SpecialSubKind::istream
:
1407 return StringView("basic_istream");
1408 case SpecialSubKind::ostream
:
1409 return StringView("basic_ostream");
1410 case SpecialSubKind::iostream
:
1411 return StringView("basic_iostream");
1413 DEMANGLE_UNREACHABLE
;
1416 void printLeft(OutputStream
&S
) const override
{
1418 case SpecialSubKind::allocator
:
1419 S
+= "std::allocator";
1421 case SpecialSubKind::basic_string
:
1422 S
+= "std::basic_string";
1424 case SpecialSubKind::string
:
1425 S
+= "std::basic_string<char, std::char_traits<char>, "
1426 "std::allocator<char> >";
1428 case SpecialSubKind::istream
:
1429 S
+= "std::basic_istream<char, std::char_traits<char> >";
1431 case SpecialSubKind::ostream
:
1432 S
+= "std::basic_ostream<char, std::char_traits<char> >";
1434 case SpecialSubKind::iostream
:
1435 S
+= "std::basic_iostream<char, std::char_traits<char> >";
1441 class SpecialSubstitution final
: public Node
{
1445 SpecialSubstitution(SpecialSubKind SSK_
)
1446 : Node(KSpecialSubstitution
), SSK(SSK_
) {}
1448 template<typename Fn
> void match(Fn F
) const { F(SSK
); }
1450 StringView
getBaseName() const override
{
1452 case SpecialSubKind::allocator
:
1453 return StringView("allocator");
1454 case SpecialSubKind::basic_string
:
1455 return StringView("basic_string");
1456 case SpecialSubKind::string
:
1457 return StringView("string");
1458 case SpecialSubKind::istream
:
1459 return StringView("istream");
1460 case SpecialSubKind::ostream
:
1461 return StringView("ostream");
1462 case SpecialSubKind::iostream
:
1463 return StringView("iostream");
1465 DEMANGLE_UNREACHABLE
;
1468 void printLeft(OutputStream
&S
) const override
{
1470 case SpecialSubKind::allocator
:
1471 S
+= "std::allocator";
1473 case SpecialSubKind::basic_string
:
1474 S
+= "std::basic_string";
1476 case SpecialSubKind::string
:
1479 case SpecialSubKind::istream
:
1480 S
+= "std::istream";
1482 case SpecialSubKind::ostream
:
1483 S
+= "std::ostream";
1485 case SpecialSubKind::iostream
:
1486 S
+= "std::iostream";
1492 class CtorDtorName final
: public Node
{
1493 const Node
*Basename
;
1498 CtorDtorName(const Node
*Basename_
, bool IsDtor_
, int Variant_
)
1499 : Node(KCtorDtorName
), Basename(Basename_
), IsDtor(IsDtor_
),
1500 Variant(Variant_
) {}
1502 template<typename Fn
> void match(Fn F
) const { F(Basename
, IsDtor
, Variant
); }
1504 void printLeft(OutputStream
&S
) const override
{
1507 S
+= Basename
->getBaseName();
1511 class DtorName
: public Node
{
1515 DtorName(const Node
*Base_
) : Node(KDtorName
), Base(Base_
) {}
1517 template<typename Fn
> void match(Fn F
) const { F(Base
); }
1519 void printLeft(OutputStream
&S
) const override
{
1525 class UnnamedTypeName
: public Node
{
1526 const StringView Count
;
1529 UnnamedTypeName(StringView Count_
) : Node(KUnnamedTypeName
), Count(Count_
) {}
1531 template<typename Fn
> void match(Fn F
) const { F(Count
); }
1533 void printLeft(OutputStream
&S
) const override
{
1540 class ClosureTypeName
: public Node
{
1541 NodeArray TemplateParams
;
1546 ClosureTypeName(NodeArray TemplateParams_
, NodeArray Params_
,
1548 : Node(KClosureTypeName
), TemplateParams(TemplateParams_
),
1549 Params(Params_
), Count(Count_
) {}
1551 template<typename Fn
> void match(Fn F
) const {
1552 F(TemplateParams
, Params
, Count
);
1555 void printDeclarator(OutputStream
&S
) const {
1556 if (!TemplateParams
.empty()) {
1558 TemplateParams
.printWithComma(S
);
1562 Params
.printWithComma(S
);
1566 void printLeft(OutputStream
&S
) const override
{
1574 class StructuredBindingName
: public Node
{
1577 StructuredBindingName(NodeArray Bindings_
)
1578 : Node(KStructuredBindingName
), Bindings(Bindings_
) {}
1580 template<typename Fn
> void match(Fn F
) const { F(Bindings
); }
1582 void printLeft(OutputStream
&S
) const override
{
1584 Bindings
.printWithComma(S
);
1589 // -- Expression Nodes --
1591 class BinaryExpr
: public Node
{
1593 const StringView InfixOperator
;
1597 BinaryExpr(const Node
*LHS_
, StringView InfixOperator_
, const Node
*RHS_
)
1598 : Node(KBinaryExpr
), LHS(LHS_
), InfixOperator(InfixOperator_
), RHS(RHS_
) {
1601 template<typename Fn
> void match(Fn F
) const { F(LHS
, InfixOperator
, RHS
); }
1603 void printLeft(OutputStream
&S
) const override
{
1604 // might be a template argument expression, then we need to disambiguate
1606 if (InfixOperator
== ">")
1617 if (InfixOperator
== ">")
1622 class ArraySubscriptExpr
: public Node
{
1627 ArraySubscriptExpr(const Node
*Op1_
, const Node
*Op2_
)
1628 : Node(KArraySubscriptExpr
), Op1(Op1_
), Op2(Op2_
) {}
1630 template<typename Fn
> void match(Fn F
) const { F(Op1
, Op2
); }
1632 void printLeft(OutputStream
&S
) const override
{
1641 class PostfixExpr
: public Node
{
1643 const StringView Operator
;
1646 PostfixExpr(const Node
*Child_
, StringView Operator_
)
1647 : Node(KPostfixExpr
), Child(Child_
), Operator(Operator_
) {}
1649 template<typename Fn
> void match(Fn F
) const { F(Child
, Operator
); }
1651 void printLeft(OutputStream
&S
) const override
{
1659 class ConditionalExpr
: public Node
{
1665 ConditionalExpr(const Node
*Cond_
, const Node
*Then_
, const Node
*Else_
)
1666 : Node(KConditionalExpr
), Cond(Cond_
), Then(Then_
), Else(Else_
) {}
1668 template<typename Fn
> void match(Fn F
) const { F(Cond
, Then
, Else
); }
1670 void printLeft(OutputStream
&S
) const override
{
1681 class MemberExpr
: public Node
{
1683 const StringView Kind
;
1687 MemberExpr(const Node
*LHS_
, StringView Kind_
, const Node
*RHS_
)
1688 : Node(KMemberExpr
), LHS(LHS_
), Kind(Kind_
), RHS(RHS_
) {}
1690 template<typename Fn
> void match(Fn F
) const { F(LHS
, Kind
, RHS
); }
1692 void printLeft(OutputStream
&S
) const override
{
1699 class EnclosingExpr
: public Node
{
1700 const StringView Prefix
;
1702 const StringView Postfix
;
1705 EnclosingExpr(StringView Prefix_
, Node
*Infix_
, StringView Postfix_
)
1706 : Node(KEnclosingExpr
), Prefix(Prefix_
), Infix(Infix_
),
1707 Postfix(Postfix_
) {}
1709 template<typename Fn
> void match(Fn F
) const { F(Prefix
, Infix
, Postfix
); }
1711 void printLeft(OutputStream
&S
) const override
{
1718 class CastExpr
: public Node
{
1719 // cast_kind<to>(from)
1720 const StringView CastKind
;
1725 CastExpr(StringView CastKind_
, const Node
*To_
, const Node
*From_
)
1726 : Node(KCastExpr
), CastKind(CastKind_
), To(To_
), From(From_
) {}
1728 template<typename Fn
> void match(Fn F
) const { F(CastKind
, To
, From
); }
1730 void printLeft(OutputStream
&S
) const override
{
1740 class SizeofParamPackExpr
: public Node
{
1744 SizeofParamPackExpr(const Node
*Pack_
)
1745 : Node(KSizeofParamPackExpr
), Pack(Pack_
) {}
1747 template<typename Fn
> void match(Fn F
) const { F(Pack
); }
1749 void printLeft(OutputStream
&S
) const override
{
1751 ParameterPackExpansion
PPE(Pack
);
1757 class CallExpr
: public Node
{
1762 CallExpr(const Node
*Callee_
, NodeArray Args_
)
1763 : Node(KCallExpr
), Callee(Callee_
), Args(Args_
) {}
1765 template<typename Fn
> void match(Fn F
) const { F(Callee
, Args
); }
1767 void printLeft(OutputStream
&S
) const override
{
1770 Args
.printWithComma(S
);
1775 class NewExpr
: public Node
{
1776 // new (expr_list) type(init_list)
1780 bool IsGlobal
; // ::operator new ?
1781 bool IsArray
; // new[] ?
1783 NewExpr(NodeArray ExprList_
, Node
*Type_
, NodeArray InitList_
, bool IsGlobal_
,
1785 : Node(KNewExpr
), ExprList(ExprList_
), Type(Type_
), InitList(InitList_
),
1786 IsGlobal(IsGlobal_
), IsArray(IsArray_
) {}
1788 template<typename Fn
> void match(Fn F
) const {
1789 F(ExprList
, Type
, InitList
, IsGlobal
, IsArray
);
1792 void printLeft(OutputStream
&S
) const override
{
1799 if (!ExprList
.empty()) {
1801 ExprList
.printWithComma(S
);
1805 if (!InitList
.empty()) {
1807 InitList
.printWithComma(S
);
1814 class DeleteExpr
: public Node
{
1820 DeleteExpr(Node
*Op_
, bool IsGlobal_
, bool IsArray_
)
1821 : Node(KDeleteExpr
), Op(Op_
), IsGlobal(IsGlobal_
), IsArray(IsArray_
) {}
1823 template<typename Fn
> void match(Fn F
) const { F(Op
, IsGlobal
, IsArray
); }
1825 void printLeft(OutputStream
&S
) const override
{
1835 class PrefixExpr
: public Node
{
1840 PrefixExpr(StringView Prefix_
, Node
*Child_
)
1841 : Node(KPrefixExpr
), Prefix(Prefix_
), Child(Child_
) {}
1843 template<typename Fn
> void match(Fn F
) const { F(Prefix
, Child
); }
1845 void printLeft(OutputStream
&S
) const override
{
1853 class FunctionParam
: public Node
{
1857 FunctionParam(StringView Number_
) : Node(KFunctionParam
), Number(Number_
) {}
1859 template<typename Fn
> void match(Fn F
) const { F(Number
); }
1861 void printLeft(OutputStream
&S
) const override
{
1867 class ConversionExpr
: public Node
{
1869 NodeArray Expressions
;
1872 ConversionExpr(const Node
*Type_
, NodeArray Expressions_
)
1873 : Node(KConversionExpr
), Type(Type_
), Expressions(Expressions_
) {}
1875 template<typename Fn
> void match(Fn F
) const { F(Type
, Expressions
); }
1877 void printLeft(OutputStream
&S
) const override
{
1881 Expressions
.printWithComma(S
);
1886 class InitListExpr
: public Node
{
1890 InitListExpr(const Node
*Ty_
, NodeArray Inits_
)
1891 : Node(KInitListExpr
), Ty(Ty_
), Inits(Inits_
) {}
1893 template<typename Fn
> void match(Fn F
) const { F(Ty
, Inits
); }
1895 void printLeft(OutputStream
&S
) const override
{
1899 Inits
.printWithComma(S
);
1904 class BracedExpr
: public Node
{
1909 BracedExpr(const Node
*Elem_
, const Node
*Init_
, bool IsArray_
)
1910 : Node(KBracedExpr
), Elem(Elem_
), Init(Init_
), IsArray(IsArray_
) {}
1912 template<typename Fn
> void match(Fn F
) const { F(Elem
, Init
, IsArray
); }
1914 void printLeft(OutputStream
&S
) const override
{
1923 if (Init
->getKind() != KBracedExpr
&& Init
->getKind() != KBracedRangeExpr
)
1929 class BracedRangeExpr
: public Node
{
1934 BracedRangeExpr(const Node
*First_
, const Node
*Last_
, const Node
*Init_
)
1935 : Node(KBracedRangeExpr
), First(First_
), Last(Last_
), Init(Init_
) {}
1937 template<typename Fn
> void match(Fn F
) const { F(First
, Last
, Init
); }
1939 void printLeft(OutputStream
&S
) const override
{
1945 if (Init
->getKind() != KBracedExpr
&& Init
->getKind() != KBracedRangeExpr
)
1951 class FoldExpr
: public Node
{
1952 const Node
*Pack
, *Init
;
1953 StringView OperatorName
;
1957 FoldExpr(bool IsLeftFold_
, StringView OperatorName_
, const Node
*Pack_
,
1959 : Node(KFoldExpr
), Pack(Pack_
), Init(Init_
), OperatorName(OperatorName_
),
1960 IsLeftFold(IsLeftFold_
) {}
1962 template<typename Fn
> void match(Fn F
) const {
1963 F(IsLeftFold
, OperatorName
, Pack
, Init
);
1966 void printLeft(OutputStream
&S
) const override
{
1967 auto PrintPack
= [&] {
1969 ParameterPackExpansion(Pack
).print(S
);
1976 // init op ... op pack
1977 if (Init
!= nullptr) {
1988 } else { // !IsLeftFold
1994 // pack op ... op init
1995 if (Init
!= nullptr) {
2006 class ThrowExpr
: public Node
{
2010 ThrowExpr(const Node
*Op_
) : Node(KThrowExpr
), Op(Op_
) {}
2012 template<typename Fn
> void match(Fn F
) const { F(Op
); }
2014 void printLeft(OutputStream
&S
) const override
{
2020 // MSVC __uuidof extension, generated by clang in -fms-extensions mode.
2021 class UUIDOfExpr
: public Node
{
2024 UUIDOfExpr(Node
*Operand_
) : Node(KUUIDOfExpr
), Operand(Operand_
) {}
2026 template<typename Fn
> void match(Fn F
) const { F(Operand
); }
2028 void printLeft(OutputStream
&S
) const override
{
2035 class BoolExpr
: public Node
{
2039 BoolExpr(bool Value_
) : Node(KBoolExpr
), Value(Value_
) {}
2041 template<typename Fn
> void match(Fn F
) const { F(Value
); }
2043 void printLeft(OutputStream
&S
) const override
{
2044 S
+= Value
? StringView("true") : StringView("false");
2048 class StringLiteral
: public Node
{
2052 StringLiteral(const Node
*Type_
) : Node(KStringLiteral
), Type(Type_
) {}
2054 template<typename Fn
> void match(Fn F
) const { F(Type
); }
2056 void printLeft(OutputStream
&S
) const override
{
2063 class LambdaExpr
: public Node
{
2067 LambdaExpr(const Node
*Type_
) : Node(KLambdaExpr
), Type(Type_
) {}
2069 template<typename Fn
> void match(Fn F
) const { F(Type
); }
2071 void printLeft(OutputStream
&S
) const override
{
2073 if (Type
->getKind() == KClosureTypeName
)
2074 static_cast<const ClosureTypeName
*>(Type
)->printDeclarator(S
);
2079 class IntegerCastExpr
: public Node
{
2085 IntegerCastExpr(const Node
*Ty_
, StringView Integer_
)
2086 : Node(KIntegerCastExpr
), Ty(Ty_
), Integer(Integer_
) {}
2088 template<typename Fn
> void match(Fn F
) const { F(Ty
, Integer
); }
2090 void printLeft(OutputStream
&S
) const override
{
2098 class IntegerLiteral
: public Node
{
2103 IntegerLiteral(StringView Type_
, StringView Value_
)
2104 : Node(KIntegerLiteral
), Type(Type_
), Value(Value_
) {}
2106 template<typename Fn
> void match(Fn F
) const { F(Type
, Value
); }
2108 void printLeft(OutputStream
&S
) const override
{
2109 if (Type
.size() > 3) {
2115 if (Value
[0] == 'n') {
2117 S
+= Value
.dropFront(1);
2121 if (Type
.size() <= 3)
2126 template <class Float
> struct FloatData
;
2128 namespace float_literal_impl
{
2129 constexpr Node::Kind
getFloatLiteralKind(float *) {
2130 return Node::KFloatLiteral
;
2132 constexpr Node::Kind
getFloatLiteralKind(double *) {
2133 return Node::KDoubleLiteral
;
2135 constexpr Node::Kind
getFloatLiteralKind(long double *) {
2136 return Node::KLongDoubleLiteral
;
2140 template <class Float
> class FloatLiteralImpl
: public Node
{
2141 const StringView Contents
;
2143 static constexpr Kind KindForClass
=
2144 float_literal_impl::getFloatLiteralKind((Float
*)nullptr);
2147 FloatLiteralImpl(StringView Contents_
)
2148 : Node(KindForClass
), Contents(Contents_
) {}
2150 template<typename Fn
> void match(Fn F
) const { F(Contents
); }
2152 void printLeft(OutputStream
&s
) const override
{
2153 const char *first
= Contents
.begin();
2154 const char *last
= Contents
.end() + 1;
2156 const size_t N
= FloatData
<Float
>::mangled_size
;
2157 if (static_cast<std::size_t>(last
- first
) > N
) {
2161 char buf
[sizeof(Float
)];
2163 const char *t
= first
;
2165 for (; t
!= last
; ++t
, ++e
) {
2166 unsigned d1
= isdigit(*t
) ? static_cast<unsigned>(*t
- '0')
2167 : static_cast<unsigned>(*t
- 'a' + 10);
2169 unsigned d0
= isdigit(*t
) ? static_cast<unsigned>(*t
- '0')
2170 : static_cast<unsigned>(*t
- 'a' + 10);
2171 *e
= static_cast<char>((d1
<< 4) + d0
);
2173 #if __BYTE_ORDER__ == __ORDER_LITTLE_ENDIAN__
2174 std::reverse(buf
, e
);
2176 char num
[FloatData
<Float
>::max_demangled_size
] = {0};
2177 int n
= snprintf(num
, sizeof(num
), FloatData
<Float
>::spec
, value
);
2178 s
+= StringView(num
, num
+ n
);
2183 using FloatLiteral
= FloatLiteralImpl
<float>;
2184 using DoubleLiteral
= FloatLiteralImpl
<double>;
2185 using LongDoubleLiteral
= FloatLiteralImpl
<long double>;
2187 /// Visit the node. Calls \c F(P), where \c P is the node cast to the
2188 /// appropriate derived class.
2189 template<typename Fn
>
2190 void Node::visit(Fn F
) const {
2192 #define CASE(X) case K ## X: return F(static_cast<const X*>(this));
2193 FOR_EACH_NODE_KIND(CASE
)
2196 assert(0 && "unknown mangling node kind");
2199 /// Determine the kind of a node from its type.
2200 template<typename NodeT
> struct NodeKind
;
2201 #define SPECIALIZATION(X) \
2202 template<> struct NodeKind<X> { \
2203 static constexpr Node::Kind Kind = Node::K##X; \
2204 static constexpr const char *name() { return #X; } \
2206 FOR_EACH_NODE_KIND(SPECIALIZATION
)
2207 #undef SPECIALIZATION
2209 #undef FOR_EACH_NODE_KIND
2211 template <class T
, size_t N
>
2212 class PODSmallVector
{
2213 static_assert(std::is_pod
<T
>::value
,
2214 "T is required to be a plain old data type");
2221 bool isInline() const { return First
== Inline
; }
2223 void clearInline() {
2229 void reserve(size_t NewCap
) {
2232 auto* Tmp
= static_cast<T
*>(std::malloc(NewCap
* sizeof(T
)));
2235 std::copy(First
, Last
, Tmp
);
2238 First
= static_cast<T
*>(std::realloc(First
, NewCap
* sizeof(T
)));
2239 if (First
== nullptr)
2243 Cap
= First
+ NewCap
;
2247 PODSmallVector() : First(Inline
), Last(First
), Cap(Inline
+ N
) {}
2249 PODSmallVector(const PODSmallVector
&) = delete;
2250 PODSmallVector
& operator=(const PODSmallVector
&) = delete;
2252 PODSmallVector(PODSmallVector
&& Other
) : PODSmallVector() {
2253 if (Other
.isInline()) {
2254 std::copy(Other
.begin(), Other
.end(), First
);
2255 Last
= First
+ Other
.size();
2260 First
= Other
.First
;
2263 Other
.clearInline();
2266 PODSmallVector
& operator=(PODSmallVector
&& Other
) {
2267 if (Other
.isInline()) {
2272 std::copy(Other
.begin(), Other
.end(), First
);
2273 Last
= First
+ Other
.size();
2279 First
= Other
.First
;
2282 Other
.clearInline();
2286 std::swap(First
, Other
.First
);
2287 std::swap(Last
, Other
.Last
);
2288 std::swap(Cap
, Other
.Cap
);
2293 void push_back(const T
& Elem
) {
2295 reserve(size() * 2);
2300 assert(Last
!= First
&& "Popping empty vector!");
2304 void dropBack(size_t Index
) {
2305 assert(Index
<= size() && "dropBack() can't expand!");
2306 Last
= First
+ Index
;
2309 T
* begin() { return First
; }
2310 T
* end() { return Last
; }
2312 bool empty() const { return First
== Last
; }
2313 size_t size() const { return static_cast<size_t>(Last
- First
); }
2315 assert(Last
!= First
&& "Calling back() on empty vector!");
2318 T
& operator[](size_t Index
) {
2319 assert(Index
< size() && "Invalid access!");
2320 return *(begin() + Index
);
2322 void clear() { Last
= First
; }
2330 template <typename Derived
, typename Alloc
> struct AbstractManglingParser
{
2334 // Name stack, this is used by the parser to hold temporary names that were
2335 // parsed. The parser collapses multiple names into new nodes to construct
2336 // the AST. Once the parser is finished, names.size() == 1.
2337 PODSmallVector
<Node
*, 32> Names
;
2339 // Substitution table. Itanium supports name substitutions as a means of
2340 // compression. The string "S42_" refers to the 44nd entry (base-36) in this
2342 PODSmallVector
<Node
*, 32> Subs
;
2344 using TemplateParamList
= PODSmallVector
<Node
*, 8>;
2346 class ScopedTemplateParamList
{
2347 AbstractManglingParser
*Parser
;
2348 size_t OldNumTemplateParamLists
;
2349 TemplateParamList Params
;
2352 ScopedTemplateParamList(AbstractManglingParser
*Parser
)
2354 OldNumTemplateParamLists(Parser
->TemplateParams
.size()) {
2355 Parser
->TemplateParams
.push_back(&Params
);
2357 ~ScopedTemplateParamList() {
2358 assert(Parser
->TemplateParams
.size() >= OldNumTemplateParamLists
);
2359 Parser
->TemplateParams
.dropBack(OldNumTemplateParamLists
);
2363 // Template parameter table. Like the above, but referenced like "T42_".
2364 // This has a smaller size compared to Subs and Names because it can be
2365 // stored on the stack.
2366 TemplateParamList OuterTemplateParams
;
2368 // Lists of template parameters indexed by template parameter depth,
2369 // referenced like "TL2_4_". If nonempty, element 0 is always
2370 // OuterTemplateParams; inner elements are always template parameter lists of
2371 // lambda expressions. For a generic lambda with no explicit template
2372 // parameter list, the corresponding parameter list pointer will be null.
2373 PODSmallVector
<TemplateParamList
*, 4> TemplateParams
;
2375 // Set of unresolved forward <template-param> references. These can occur in a
2376 // conversion operator's type, and are resolved in the enclosing <encoding>.
2377 PODSmallVector
<ForwardTemplateReference
*, 4> ForwardTemplateRefs
;
2379 bool TryToParseTemplateArgs
= true;
2380 bool PermitForwardTemplateReferences
= false;
2381 size_t ParsingLambdaParamsAtLevel
= (size_t)-1;
2383 unsigned NumSyntheticTemplateParameters
[3] = {};
2387 AbstractManglingParser(const char *First_
, const char *Last_
)
2388 : First(First_
), Last(Last_
) {}
2390 Derived
&getDerived() { return static_cast<Derived
&>(*this); }
2392 void reset(const char *First_
, const char *Last_
) {
2397 TemplateParams
.clear();
2398 ParsingLambdaParamsAtLevel
= (size_t)-1;
2399 TryToParseTemplateArgs
= true;
2400 PermitForwardTemplateReferences
= false;
2401 for (int I
= 0; I
!= 3; ++I
)
2402 NumSyntheticTemplateParameters
[I
] = 0;
2403 ASTAllocator
.reset();
2406 template <class T
, class... Args
> Node
*make(Args
&&... args
) {
2407 return ASTAllocator
.template makeNode
<T
>(std::forward
<Args
>(args
)...);
2410 template <class It
> NodeArray
makeNodeArray(It begin
, It end
) {
2411 size_t sz
= static_cast<size_t>(end
- begin
);
2412 void *mem
= ASTAllocator
.allocateNodeArray(sz
);
2413 Node
**data
= new (mem
) Node
*[sz
];
2414 std::copy(begin
, end
, data
);
2415 return NodeArray(data
, sz
);
2418 NodeArray
popTrailingNodeArray(size_t FromPosition
) {
2419 assert(FromPosition
<= Names
.size());
2421 makeNodeArray(Names
.begin() + (long)FromPosition
, Names
.end());
2422 Names
.dropBack(FromPosition
);
2426 bool consumeIf(StringView S
) {
2427 if (StringView(First
, Last
).startsWith(S
)) {
2434 bool consumeIf(char C
) {
2435 if (First
!= Last
&& *First
== C
) {
2442 char consume() { return First
!= Last
? *First
++ : '\0'; }
2444 char look(unsigned Lookahead
= 0) {
2445 if (static_cast<size_t>(Last
- First
) <= Lookahead
)
2447 return First
[Lookahead
];
2450 size_t numLeft() const { return static_cast<size_t>(Last
- First
); }
2452 StringView
parseNumber(bool AllowNegative
= false);
2453 Qualifiers
parseCVQualifiers();
2454 bool parsePositiveInteger(size_t *Out
);
2455 StringView
parseBareSourceName();
2457 bool parseSeqId(size_t *Out
);
2458 Node
*parseSubstitution();
2459 Node
*parseTemplateParam();
2460 Node
*parseTemplateParamDecl();
2461 Node
*parseTemplateArgs(bool TagTemplates
= false);
2462 Node
*parseTemplateArg();
2464 /// Parse the <expr> production.
2466 Node
*parsePrefixExpr(StringView Kind
);
2467 Node
*parseBinaryExpr(StringView Kind
);
2468 Node
*parseIntegerLiteral(StringView Lit
);
2469 Node
*parseExprPrimary();
2470 template <class Float
> Node
*parseFloatingLiteral();
2471 Node
*parseFunctionParam();
2472 Node
*parseNewExpr();
2473 Node
*parseConversionExpr();
2474 Node
*parseBracedExpr();
2475 Node
*parseFoldExpr();
2477 /// Parse the <type> production.
2479 Node
*parseFunctionType();
2480 Node
*parseVectorType();
2481 Node
*parseDecltype();
2482 Node
*parseArrayType();
2483 Node
*parsePointerToMemberType();
2484 Node
*parseClassEnumType();
2485 Node
*parseQualifiedType();
2487 Node
*parseEncoding();
2488 bool parseCallOffset();
2489 Node
*parseSpecialName();
2491 /// Holds some extra information about a <name> that is being parsed. This
2492 /// information is only pertinent if the <name> refers to an <encoding>.
2494 bool CtorDtorConversion
= false;
2495 bool EndsWithTemplateArgs
= false;
2496 Qualifiers CVQualifiers
= QualNone
;
2497 FunctionRefQual ReferenceQualifier
= FrefQualNone
;
2498 size_t ForwardTemplateRefsBegin
;
2500 NameState(AbstractManglingParser
*Enclosing
)
2501 : ForwardTemplateRefsBegin(Enclosing
->ForwardTemplateRefs
.size()) {}
2504 bool resolveForwardTemplateRefs(NameState
&State
) {
2505 size_t I
= State
.ForwardTemplateRefsBegin
;
2506 size_t E
= ForwardTemplateRefs
.size();
2507 for (; I
< E
; ++I
) {
2508 size_t Idx
= ForwardTemplateRefs
[I
]->Index
;
2509 if (TemplateParams
.empty() || !TemplateParams
[0] ||
2510 Idx
>= TemplateParams
[0]->size())
2512 ForwardTemplateRefs
[I
]->Ref
= (*TemplateParams
[0])[Idx
];
2514 ForwardTemplateRefs
.dropBack(State
.ForwardTemplateRefsBegin
);
2518 /// Parse the <name> production>
2519 Node
*parseName(NameState
*State
= nullptr);
2520 Node
*parseLocalName(NameState
*State
);
2521 Node
*parseOperatorName(NameState
*State
);
2522 Node
*parseUnqualifiedName(NameState
*State
);
2523 Node
*parseUnnamedTypeName(NameState
*State
);
2524 Node
*parseSourceName(NameState
*State
);
2525 Node
*parseUnscopedName(NameState
*State
);
2526 Node
*parseNestedName(NameState
*State
);
2527 Node
*parseCtorDtorName(Node
*&SoFar
, NameState
*State
);
2529 Node
*parseAbiTags(Node
*N
);
2531 /// Parse the <unresolved-name> production.
2532 Node
*parseUnresolvedName();
2533 Node
*parseSimpleId();
2534 Node
*parseBaseUnresolvedName();
2535 Node
*parseUnresolvedType();
2536 Node
*parseDestructorName();
2538 /// Top-level entry point into the parser.
2542 const char* parse_discriminator(const char* first
, const char* last
);
2544 // <name> ::= <nested-name> // N
2545 // ::= <local-name> # See Scope Encoding below // Z
2546 // ::= <unscoped-template-name> <template-args>
2547 // ::= <unscoped-name>
2549 // <unscoped-template-name> ::= <unscoped-name>
2550 // ::= <substitution>
2551 template <typename Derived
, typename Alloc
>
2552 Node
*AbstractManglingParser
<Derived
, Alloc
>::parseName(NameState
*State
) {
2553 consumeIf('L'); // extension
2556 return getDerived().parseNestedName(State
);
2558 return getDerived().parseLocalName(State
);
2560 // ::= <unscoped-template-name> <template-args>
2561 if (look() == 'S' && look(1) != 't') {
2562 Node
*S
= getDerived().parseSubstitution();
2567 Node
*TA
= getDerived().parseTemplateArgs(State
!= nullptr);
2570 if (State
) State
->EndsWithTemplateArgs
= true;
2571 return make
<NameWithTemplateArgs
>(S
, TA
);
2574 Node
*N
= getDerived().parseUnscopedName(State
);
2577 // ::= <unscoped-template-name> <template-args>
2578 if (look() == 'I') {
2580 Node
*TA
= getDerived().parseTemplateArgs(State
!= nullptr);
2583 if (State
) State
->EndsWithTemplateArgs
= true;
2584 return make
<NameWithTemplateArgs
>(N
, TA
);
2586 // ::= <unscoped-name>
2590 // <local-name> := Z <function encoding> E <entity name> [<discriminator>]
2591 // := Z <function encoding> E s [<discriminator>]
2592 // := Z <function encoding> Ed [ <parameter number> ] _ <entity name>
2593 template <typename Derived
, typename Alloc
>
2594 Node
*AbstractManglingParser
<Derived
, Alloc
>::parseLocalName(NameState
*State
) {
2595 if (!consumeIf('Z'))
2597 Node
*Encoding
= getDerived().parseEncoding();
2598 if (Encoding
== nullptr || !consumeIf('E'))
2601 if (consumeIf('s')) {
2602 First
= parse_discriminator(First
, Last
);
2603 auto *StringLitName
= make
<NameType
>("string literal");
2606 return make
<LocalName
>(Encoding
, StringLitName
);
2609 if (consumeIf('d')) {
2611 if (!consumeIf('_'))
2613 Node
*N
= getDerived().parseName(State
);
2616 return make
<LocalName
>(Encoding
, N
);
2619 Node
*Entity
= getDerived().parseName(State
);
2620 if (Entity
== nullptr)
2622 First
= parse_discriminator(First
, Last
);
2623 return make
<LocalName
>(Encoding
, Entity
);
2626 // <unscoped-name> ::= <unqualified-name>
2627 // ::= St <unqualified-name> # ::std::
2628 // extension ::= StL<unqualified-name>
2629 template <typename Derived
, typename Alloc
>
2631 AbstractManglingParser
<Derived
, Alloc
>::parseUnscopedName(NameState
*State
) {
2632 if (consumeIf("StL") || consumeIf("St")) {
2633 Node
*R
= getDerived().parseUnqualifiedName(State
);
2636 return make
<StdQualifiedName
>(R
);
2638 return getDerived().parseUnqualifiedName(State
);
2641 // <unqualified-name> ::= <operator-name> [abi-tags]
2642 // ::= <ctor-dtor-name>
2643 // ::= <source-name>
2644 // ::= <unnamed-type-name>
2645 // ::= DC <source-name>+ E # structured binding declaration
2646 template <typename Derived
, typename Alloc
>
2648 AbstractManglingParser
<Derived
, Alloc
>::parseUnqualifiedName(NameState
*State
) {
2649 // <ctor-dtor-name>s are special-cased in parseNestedName().
2652 Result
= getDerived().parseUnnamedTypeName(State
);
2653 else if (look() >= '1' && look() <= '9')
2654 Result
= getDerived().parseSourceName(State
);
2655 else if (consumeIf("DC")) {
2656 size_t BindingsBegin
= Names
.size();
2658 Node
*Binding
= getDerived().parseSourceName(State
);
2659 if (Binding
== nullptr)
2661 Names
.push_back(Binding
);
2662 } while (!consumeIf('E'));
2663 Result
= make
<StructuredBindingName
>(popTrailingNodeArray(BindingsBegin
));
2665 Result
= getDerived().parseOperatorName(State
);
2666 if (Result
!= nullptr)
2667 Result
= getDerived().parseAbiTags(Result
);
2671 // <unnamed-type-name> ::= Ut [<nonnegative number>] _
2672 // ::= <closure-type-name>
2674 // <closure-type-name> ::= Ul <lambda-sig> E [ <nonnegative number> ] _
2676 // <lambda-sig> ::= <parameter type>+ # Parameter types or "v" if the lambda has no parameters
2677 template <typename Derived
, typename Alloc
>
2679 AbstractManglingParser
<Derived
, Alloc
>::parseUnnamedTypeName(NameState
*State
) {
2680 // <template-params> refer to the innermost <template-args>. Clear out any
2681 // outer args that we may have inserted into TemplateParams.
2682 if (State
!= nullptr)
2683 TemplateParams
.clear();
2685 if (consumeIf("Ut")) {
2686 StringView Count
= parseNumber();
2687 if (!consumeIf('_'))
2689 return make
<UnnamedTypeName
>(Count
);
2691 if (consumeIf("Ul")) {
2692 SwapAndRestore
<size_t> SwapParams(ParsingLambdaParamsAtLevel
,
2693 TemplateParams
.size());
2694 ScopedTemplateParamList
LambdaTemplateParams(this);
2696 size_t ParamsBegin
= Names
.size();
2697 while (look() == 'T' &&
2698 StringView("yptn").find(look(1)) != StringView::npos
) {
2699 Node
*T
= parseTemplateParamDecl();
2704 NodeArray TempParams
= popTrailingNodeArray(ParamsBegin
);
2706 // FIXME: If TempParams is empty and none of the function parameters
2707 // includes 'auto', we should remove LambdaTemplateParams from the
2708 // TemplateParams list. Unfortunately, we don't find out whether there are
2709 // any 'auto' parameters until too late in an example such as:
2711 // template<typename T> void f(
2712 // decltype([](decltype([]<typename T>(T v) {}),
2714 // template<typename T> void f(
2715 // decltype([](decltype([]<typename T>(T w) {}),
2718 // Here, the type of v is at level 2 but the type of w is at level 1. We
2719 // don't find this out until we encounter the type of the next parameter.
2721 // However, compilers can't actually cope with the former example in
2722 // practice, and it's likely to be made ill-formed in future, so we don't
2723 // need to support it here.
2725 // If we encounter an 'auto' in the function parameter types, we will
2726 // recreate a template parameter scope for it, but any intervening lambdas
2727 // will be parsed in the 'wrong' template parameter depth.
2728 if (TempParams
.empty())
2729 TemplateParams
.pop_back();
2731 if (!consumeIf("vE")) {
2733 Node
*P
= getDerived().parseType();
2737 } while (!consumeIf('E'));
2739 NodeArray Params
= popTrailingNodeArray(ParamsBegin
);
2741 StringView Count
= parseNumber();
2742 if (!consumeIf('_'))
2744 return make
<ClosureTypeName
>(TempParams
, Params
, Count
);
2746 if (consumeIf("Ub")) {
2747 (void)parseNumber();
2748 if (!consumeIf('_'))
2750 return make
<NameType
>("'block-literal'");
2755 // <source-name> ::= <positive length number> <identifier>
2756 template <typename Derived
, typename Alloc
>
2757 Node
*AbstractManglingParser
<Derived
, Alloc
>::parseSourceName(NameState
*) {
2759 if (parsePositiveInteger(&Length
))
2761 if (numLeft() < Length
|| Length
== 0)
2763 StringView
Name(First
, First
+ Length
);
2765 if (Name
.startsWith("_GLOBAL__N"))
2766 return make
<NameType
>("(anonymous namespace)");
2767 return make
<NameType
>(Name
);
2770 // <operator-name> ::= aa # &&
2771 // ::= ad # & (unary)
2778 // ::= cv <type> # (cast)
2779 // ::= da # delete[]
2780 // ::= de # * (unary)
2791 // ::= li <source-name> # operator ""
2799 // ::= mm # -- (postfix in <expression> context)
2802 // ::= ng # - (unary)
2811 // ::= pp # ++ (postfix in <expression> context)
2812 // ::= ps # + (unary)
2819 // ::= ss # <=> C++2a
2820 // ::= v <digit> <source-name> # vendor extended operator
2821 template <typename Derived
, typename Alloc
>
2823 AbstractManglingParser
<Derived
, Alloc
>::parseOperatorName(NameState
*State
) {
2829 return make
<NameType
>("operator&&");
2833 return make
<NameType
>("operator&");
2836 return make
<NameType
>("operator&=");
2839 return make
<NameType
>("operator=");
2846 return make
<NameType
>("operator()");
2849 return make
<NameType
>("operator,");
2852 return make
<NameType
>("operator~");
2853 // ::= cv <type> # (cast)
2856 SwapAndRestore
<bool> SaveTemplate(TryToParseTemplateArgs
, false);
2857 // If we're parsing an encoding, State != nullptr and the conversion
2858 // operators' <type> could have a <template-param> that refers to some
2859 // <template-arg>s further ahead in the mangled name.
2860 SwapAndRestore
<bool> SavePermit(PermitForwardTemplateReferences
,
2861 PermitForwardTemplateReferences
||
2863 Node
*Ty
= getDerived().parseType();
2866 if (State
) State
->CtorDtorConversion
= true;
2867 return make
<ConversionOperatorType
>(Ty
);
2875 return make
<NameType
>("operator delete[]");
2878 return make
<NameType
>("operator*");
2881 return make
<NameType
>("operator delete");
2884 return make
<NameType
>("operator/");
2887 return make
<NameType
>("operator/=");
2894 return make
<NameType
>("operator^");
2897 return make
<NameType
>("operator^=");
2900 return make
<NameType
>("operator==");
2907 return make
<NameType
>("operator>=");
2910 return make
<NameType
>("operator>");
2914 if (look(1) == 'x') {
2916 return make
<NameType
>("operator[]");
2923 return make
<NameType
>("operator<=");
2924 // ::= li <source-name> # operator ""
2927 Node
*SN
= getDerived().parseSourceName(State
);
2930 return make
<LiteralOperator
>(SN
);
2934 return make
<NameType
>("operator<<");
2937 return make
<NameType
>("operator<<=");
2940 return make
<NameType
>("operator<");
2947 return make
<NameType
>("operator-");
2950 return make
<NameType
>("operator-=");
2953 return make
<NameType
>("operator*");
2956 return make
<NameType
>("operator*=");
2959 return make
<NameType
>("operator--");
2966 return make
<NameType
>("operator new[]");
2969 return make
<NameType
>("operator!=");
2972 return make
<NameType
>("operator-");
2975 return make
<NameType
>("operator!");
2978 return make
<NameType
>("operator new");
2985 return make
<NameType
>("operator||");
2988 return make
<NameType
>("operator|");
2991 return make
<NameType
>("operator|=");
2998 return make
<NameType
>("operator->*");
3001 return make
<NameType
>("operator+");
3004 return make
<NameType
>("operator+=");
3007 return make
<NameType
>("operator++");
3010 return make
<NameType
>("operator+");
3013 return make
<NameType
>("operator->");
3017 if (look(1) == 'u') {
3019 return make
<NameType
>("operator?");
3026 return make
<NameType
>("operator%");
3029 return make
<NameType
>("operator%=");
3032 return make
<NameType
>("operator>>");
3035 return make
<NameType
>("operator>>=");
3039 if (look(1) == 's') {
3041 return make
<NameType
>("operator<=>");
3044 // ::= v <digit> <source-name> # vendor extended operator
3046 if (std::isdigit(look(1))) {
3048 Node
*SN
= getDerived().parseSourceName(State
);
3051 return make
<ConversionOperatorType
>(SN
);
3058 // <ctor-dtor-name> ::= C1 # complete object constructor
3059 // ::= C2 # base object constructor
3060 // ::= C3 # complete object allocating constructor
3061 // extension ::= C4 # gcc old-style "[unified]" constructor
3062 // extension ::= C5 # the COMDAT used for ctors
3063 // ::= D0 # deleting destructor
3064 // ::= D1 # complete object destructor
3065 // ::= D2 # base object destructor
3066 // extension ::= D4 # gcc old-style "[unified]" destructor
3067 // extension ::= D5 # the COMDAT used for dtors
3068 template <typename Derived
, typename Alloc
>
3070 AbstractManglingParser
<Derived
, Alloc
>::parseCtorDtorName(Node
*&SoFar
,
3072 if (SoFar
->getKind() == Node::KSpecialSubstitution
) {
3073 auto SSK
= static_cast<SpecialSubstitution
*>(SoFar
)->SSK
;
3075 case SpecialSubKind::string
:
3076 case SpecialSubKind::istream
:
3077 case SpecialSubKind::ostream
:
3078 case SpecialSubKind::iostream
:
3079 SoFar
= make
<ExpandedSpecialSubstitution
>(SSK
);
3088 if (consumeIf('C')) {
3089 bool IsInherited
= consumeIf('I');
3090 if (look() != '1' && look() != '2' && look() != '3' && look() != '4' &&
3093 int Variant
= look() - '0';
3095 if (State
) State
->CtorDtorConversion
= true;
3097 if (getDerived().parseName(State
) == nullptr)
3100 return make
<CtorDtorName
>(SoFar
, /*IsDtor=*/false, Variant
);
3103 if (look() == 'D' && (look(1) == '0' || look(1) == '1' || look(1) == '2' ||
3104 look(1) == '4' || look(1) == '5')) {
3105 int Variant
= look(1) - '0';
3107 if (State
) State
->CtorDtorConversion
= true;
3108 return make
<CtorDtorName
>(SoFar
, /*IsDtor=*/true, Variant
);
3114 // <nested-name> ::= N [<CV-Qualifiers>] [<ref-qualifier>] <prefix> <unqualified-name> E
3115 // ::= N [<CV-Qualifiers>] [<ref-qualifier>] <template-prefix> <template-args> E
3117 // <prefix> ::= <prefix> <unqualified-name>
3118 // ::= <template-prefix> <template-args>
3119 // ::= <template-param>
3122 // ::= <substitution>
3123 // ::= <prefix> <data-member-prefix>
3126 // <data-member-prefix> := <member source-name> [<template-args>] M
3128 // <template-prefix> ::= <prefix> <template unqualified-name>
3129 // ::= <template-param>
3130 // ::= <substitution>
3131 template <typename Derived
, typename Alloc
>
3133 AbstractManglingParser
<Derived
, Alloc
>::parseNestedName(NameState
*State
) {
3134 if (!consumeIf('N'))
3137 Qualifiers CVTmp
= parseCVQualifiers();
3138 if (State
) State
->CVQualifiers
= CVTmp
;
3140 if (consumeIf('O')) {
3141 if (State
) State
->ReferenceQualifier
= FrefQualRValue
;
3142 } else if (consumeIf('R')) {
3143 if (State
) State
->ReferenceQualifier
= FrefQualLValue
;
3145 if (State
) State
->ReferenceQualifier
= FrefQualNone
;
3147 Node
*SoFar
= nullptr;
3148 auto PushComponent
= [&](Node
*Comp
) {
3149 if (!Comp
) return false;
3150 if (SoFar
) SoFar
= make
<NestedName
>(SoFar
, Comp
);
3152 if (State
) State
->EndsWithTemplateArgs
= false;
3153 return SoFar
!= nullptr;
3156 if (consumeIf("St")) {
3157 SoFar
= make
<NameType
>("std");
3162 while (!consumeIf('E')) {
3163 consumeIf('L'); // extension
3165 // <data-member-prefix> := <member source-name> [<template-args>] M
3166 if (consumeIf('M')) {
3167 if (SoFar
== nullptr)
3172 // ::= <template-param>
3173 if (look() == 'T') {
3174 if (!PushComponent(getDerived().parseTemplateParam()))
3176 Subs
.push_back(SoFar
);
3180 // ::= <template-prefix> <template-args>
3181 if (look() == 'I') {
3182 Node
*TA
= getDerived().parseTemplateArgs(State
!= nullptr);
3183 if (TA
== nullptr || SoFar
== nullptr)
3185 SoFar
= make
<NameWithTemplateArgs
>(SoFar
, TA
);
3188 if (State
) State
->EndsWithTemplateArgs
= true;
3189 Subs
.push_back(SoFar
);
3194 if (look() == 'D' && (look(1) == 't' || look(1) == 'T')) {
3195 if (!PushComponent(getDerived().parseDecltype()))
3197 Subs
.push_back(SoFar
);
3201 // ::= <substitution>
3202 if (look() == 'S' && look(1) != 't') {
3203 Node
*S
= getDerived().parseSubstitution();
3204 if (!PushComponent(S
))
3211 // Parse an <unqualified-name> thats actually a <ctor-dtor-name>.
3212 if (look() == 'C' || (look() == 'D' && look(1) != 'C')) {
3213 if (SoFar
== nullptr)
3215 if (!PushComponent(getDerived().parseCtorDtorName(SoFar
, State
)))
3217 SoFar
= getDerived().parseAbiTags(SoFar
);
3218 if (SoFar
== nullptr)
3220 Subs
.push_back(SoFar
);
3224 // ::= <prefix> <unqualified-name>
3225 if (!PushComponent(getDerived().parseUnqualifiedName(State
)))
3227 Subs
.push_back(SoFar
);
3230 if (SoFar
== nullptr || Subs
.empty())
3237 // <simple-id> ::= <source-name> [ <template-args> ]
3238 template <typename Derived
, typename Alloc
>
3239 Node
*AbstractManglingParser
<Derived
, Alloc
>::parseSimpleId() {
3240 Node
*SN
= getDerived().parseSourceName(/*NameState=*/nullptr);
3243 if (look() == 'I') {
3244 Node
*TA
= getDerived().parseTemplateArgs();
3247 return make
<NameWithTemplateArgs
>(SN
, TA
);
3252 // <destructor-name> ::= <unresolved-type> # e.g., ~T or ~decltype(f())
3253 // ::= <simple-id> # e.g., ~A<2*N>
3254 template <typename Derived
, typename Alloc
>
3255 Node
*AbstractManglingParser
<Derived
, Alloc
>::parseDestructorName() {
3257 if (std::isdigit(look()))
3258 Result
= getDerived().parseSimpleId();
3260 Result
= getDerived().parseUnresolvedType();
3261 if (Result
== nullptr)
3263 return make
<DtorName
>(Result
);
3266 // <unresolved-type> ::= <template-param>
3268 // ::= <substitution>
3269 template <typename Derived
, typename Alloc
>
3270 Node
*AbstractManglingParser
<Derived
, Alloc
>::parseUnresolvedType() {
3271 if (look() == 'T') {
3272 Node
*TP
= getDerived().parseTemplateParam();
3278 if (look() == 'D') {
3279 Node
*DT
= getDerived().parseDecltype();
3285 return getDerived().parseSubstitution();
3288 // <base-unresolved-name> ::= <simple-id> # unresolved name
3289 // extension ::= <operator-name> # unresolved operator-function-id
3290 // extension ::= <operator-name> <template-args> # unresolved operator template-id
3291 // ::= on <operator-name> # unresolved operator-function-id
3292 // ::= on <operator-name> <template-args> # unresolved operator template-id
3293 // ::= dn <destructor-name> # destructor or pseudo-destructor;
3294 // # e.g. ~X or ~X<N-1>
3295 template <typename Derived
, typename Alloc
>
3296 Node
*AbstractManglingParser
<Derived
, Alloc
>::parseBaseUnresolvedName() {
3297 if (std::isdigit(look()))
3298 return getDerived().parseSimpleId();
3300 if (consumeIf("dn"))
3301 return getDerived().parseDestructorName();
3305 Node
*Oper
= getDerived().parseOperatorName(/*NameState=*/nullptr);
3306 if (Oper
== nullptr)
3308 if (look() == 'I') {
3309 Node
*TA
= getDerived().parseTemplateArgs();
3312 return make
<NameWithTemplateArgs
>(Oper
, TA
);
3317 // <unresolved-name>
3318 // extension ::= srN <unresolved-type> [<template-args>] <unresolved-qualifier-level>* E <base-unresolved-name>
3319 // ::= [gs] <base-unresolved-name> # x or (with "gs") ::x
3320 // ::= [gs] sr <unresolved-qualifier-level>+ E <base-unresolved-name>
3321 // # A::x, N::y, A<T>::z; "gs" means leading "::"
3322 // ::= sr <unresolved-type> <base-unresolved-name> # T::x / decltype(p)::x
3323 // extension ::= sr <unresolved-type> <template-args> <base-unresolved-name>
3324 // # T::N::x /decltype(p)::N::x
3325 // (ignored) ::= srN <unresolved-type> <unresolved-qualifier-level>+ E <base-unresolved-name>
3327 // <unresolved-qualifier-level> ::= <simple-id>
3328 template <typename Derived
, typename Alloc
>
3329 Node
*AbstractManglingParser
<Derived
, Alloc
>::parseUnresolvedName() {
3330 Node
*SoFar
= nullptr;
3332 // srN <unresolved-type> [<template-args>] <unresolved-qualifier-level>* E <base-unresolved-name>
3333 // srN <unresolved-type> <unresolved-qualifier-level>+ E <base-unresolved-name>
3334 if (consumeIf("srN")) {
3335 SoFar
= getDerived().parseUnresolvedType();
3336 if (SoFar
== nullptr)
3339 if (look() == 'I') {
3340 Node
*TA
= getDerived().parseTemplateArgs();
3343 SoFar
= make
<NameWithTemplateArgs
>(SoFar
, TA
);
3348 while (!consumeIf('E')) {
3349 Node
*Qual
= getDerived().parseSimpleId();
3350 if (Qual
== nullptr)
3352 SoFar
= make
<QualifiedName
>(SoFar
, Qual
);
3357 Node
*Base
= getDerived().parseBaseUnresolvedName();
3358 if (Base
== nullptr)
3360 return make
<QualifiedName
>(SoFar
, Base
);
3363 bool Global
= consumeIf("gs");
3365 // [gs] <base-unresolved-name> # x or (with "gs") ::x
3366 if (!consumeIf("sr")) {
3367 SoFar
= getDerived().parseBaseUnresolvedName();
3368 if (SoFar
== nullptr)
3371 SoFar
= make
<GlobalQualifiedName
>(SoFar
);
3375 // [gs] sr <unresolved-qualifier-level>+ E <base-unresolved-name>
3376 if (std::isdigit(look())) {
3378 Node
*Qual
= getDerived().parseSimpleId();
3379 if (Qual
== nullptr)
3382 SoFar
= make
<QualifiedName
>(SoFar
, Qual
);
3384 SoFar
= make
<GlobalQualifiedName
>(Qual
);
3389 } while (!consumeIf('E'));
3391 // sr <unresolved-type> <base-unresolved-name>
3392 // sr <unresolved-type> <template-args> <base-unresolved-name>
3394 SoFar
= getDerived().parseUnresolvedType();
3395 if (SoFar
== nullptr)
3398 if (look() == 'I') {
3399 Node
*TA
= getDerived().parseTemplateArgs();
3402 SoFar
= make
<NameWithTemplateArgs
>(SoFar
, TA
);
3408 assert(SoFar
!= nullptr);
3410 Node
*Base
= getDerived().parseBaseUnresolvedName();
3411 if (Base
== nullptr)
3413 return make
<QualifiedName
>(SoFar
, Base
);
3416 // <abi-tags> ::= <abi-tag> [<abi-tags>]
3417 // <abi-tag> ::= B <source-name>
3418 template <typename Derived
, typename Alloc
>
3419 Node
*AbstractManglingParser
<Derived
, Alloc
>::parseAbiTags(Node
*N
) {
3420 while (consumeIf('B')) {
3421 StringView SN
= parseBareSourceName();
3424 N
= make
<AbiTagAttr
>(N
, SN
);
3431 // <number> ::= [n] <non-negative decimal integer>
3432 template <typename Alloc
, typename Derived
>
3434 AbstractManglingParser
<Alloc
, Derived
>::parseNumber(bool AllowNegative
) {
3435 const char *Tmp
= First
;
3438 if (numLeft() == 0 || !std::isdigit(*First
))
3439 return StringView();
3440 while (numLeft() != 0 && std::isdigit(*First
))
3442 return StringView(Tmp
, First
);
3445 // <positive length number> ::= [0-9]*
3446 template <typename Alloc
, typename Derived
>
3447 bool AbstractManglingParser
<Alloc
, Derived
>::parsePositiveInteger(size_t *Out
) {
3449 if (look() < '0' || look() > '9')
3451 while (look() >= '0' && look() <= '9') {
3453 *Out
+= static_cast<size_t>(consume() - '0');
3458 template <typename Alloc
, typename Derived
>
3459 StringView AbstractManglingParser
<Alloc
, Derived
>::parseBareSourceName() {
3461 if (parsePositiveInteger(&Int
) || numLeft() < Int
)
3462 return StringView();
3463 StringView
R(First
, First
+ Int
);
3468 // <function-type> ::= [<CV-qualifiers>] [<exception-spec>] [Dx] F [Y] <bare-function-type> [<ref-qualifier>] E
3470 // <exception-spec> ::= Do # non-throwing exception-specification (e.g., noexcept, throw())
3471 // ::= DO <expression> E # computed (instantiation-dependent) noexcept
3472 // ::= Dw <type>+ E # dynamic exception specification with instantiation-dependent types
3474 // <ref-qualifier> ::= R # & ref-qualifier
3475 // <ref-qualifier> ::= O # && ref-qualifier
3476 template <typename Derived
, typename Alloc
>
3477 Node
*AbstractManglingParser
<Derived
, Alloc
>::parseFunctionType() {
3478 Qualifiers CVQuals
= parseCVQualifiers();
3480 Node
*ExceptionSpec
= nullptr;
3481 if (consumeIf("Do")) {
3482 ExceptionSpec
= make
<NameType
>("noexcept");
3485 } else if (consumeIf("DO")) {
3486 Node
*E
= getDerived().parseExpr();
3487 if (E
== nullptr || !consumeIf('E'))
3489 ExceptionSpec
= make
<NoexceptSpec
>(E
);
3492 } else if (consumeIf("Dw")) {
3493 size_t SpecsBegin
= Names
.size();
3494 while (!consumeIf('E')) {
3495 Node
*T
= getDerived().parseType();
3501 make
<DynamicExceptionSpec
>(popTrailingNodeArray(SpecsBegin
));
3506 consumeIf("Dx"); // transaction safe
3508 if (!consumeIf('F'))
3510 consumeIf('Y'); // extern "C"
3511 Node
*ReturnType
= getDerived().parseType();
3512 if (ReturnType
== nullptr)
3515 FunctionRefQual ReferenceQualifier
= FrefQualNone
;
3516 size_t ParamsBegin
= Names
.size();
3522 if (consumeIf("RE")) {
3523 ReferenceQualifier
= FrefQualLValue
;
3526 if (consumeIf("OE")) {
3527 ReferenceQualifier
= FrefQualRValue
;
3530 Node
*T
= getDerived().parseType();
3536 NodeArray Params
= popTrailingNodeArray(ParamsBegin
);
3537 return make
<FunctionType
>(ReturnType
, Params
, CVQuals
,
3538 ReferenceQualifier
, ExceptionSpec
);
3542 // <vector-type> ::= Dv <positive dimension number> _ <extended element type>
3543 // ::= Dv [<dimension expression>] _ <element type>
3544 // <extended element type> ::= <element type>
3545 // ::= p # AltiVec vector pixel
3546 template <typename Derived
, typename Alloc
>
3547 Node
*AbstractManglingParser
<Derived
, Alloc
>::parseVectorType() {
3548 if (!consumeIf("Dv"))
3550 if (look() >= '1' && look() <= '9') {
3551 StringView DimensionNumber
= parseNumber();
3552 if (!consumeIf('_'))
3555 return make
<PixelVectorType
>(DimensionNumber
);
3556 Node
*ElemType
= getDerived().parseType();
3557 if (ElemType
== nullptr)
3559 return make
<VectorType
>(ElemType
, DimensionNumber
);
3562 if (!consumeIf('_')) {
3563 Node
*DimExpr
= getDerived().parseExpr();
3566 if (!consumeIf('_'))
3568 Node
*ElemType
= getDerived().parseType();
3571 return make
<VectorType
>(ElemType
, DimExpr
);
3573 Node
*ElemType
= getDerived().parseType();
3576 return make
<VectorType
>(ElemType
, StringView());
3579 // <decltype> ::= Dt <expression> E # decltype of an id-expression or class member access (C++0x)
3580 // ::= DT <expression> E # decltype of an expression (C++0x)
3581 template <typename Derived
, typename Alloc
>
3582 Node
*AbstractManglingParser
<Derived
, Alloc
>::parseDecltype() {
3583 if (!consumeIf('D'))
3585 if (!consumeIf('t') && !consumeIf('T'))
3587 Node
*E
= getDerived().parseExpr();
3590 if (!consumeIf('E'))
3592 return make
<EnclosingExpr
>("decltype(", E
, ")");
3595 // <array-type> ::= A <positive dimension number> _ <element type>
3596 // ::= A [<dimension expression>] _ <element type>
3597 template <typename Derived
, typename Alloc
>
3598 Node
*AbstractManglingParser
<Derived
, Alloc
>::parseArrayType() {
3599 if (!consumeIf('A'))
3602 NodeOrString Dimension
;
3604 if (std::isdigit(look())) {
3605 Dimension
= parseNumber();
3606 if (!consumeIf('_'))
3608 } else if (!consumeIf('_')) {
3609 Node
*DimExpr
= getDerived().parseExpr();
3610 if (DimExpr
== nullptr)
3612 if (!consumeIf('_'))
3614 Dimension
= DimExpr
;
3617 Node
*Ty
= getDerived().parseType();
3620 return make
<ArrayType
>(Ty
, Dimension
);
3623 // <pointer-to-member-type> ::= M <class type> <member type>
3624 template <typename Derived
, typename Alloc
>
3625 Node
*AbstractManglingParser
<Derived
, Alloc
>::parsePointerToMemberType() {
3626 if (!consumeIf('M'))
3628 Node
*ClassType
= getDerived().parseType();
3629 if (ClassType
== nullptr)
3631 Node
*MemberType
= getDerived().parseType();
3632 if (MemberType
== nullptr)
3634 return make
<PointerToMemberType
>(ClassType
, MemberType
);
3637 // <class-enum-type> ::= <name> # non-dependent type name, dependent type name, or dependent typename-specifier
3638 // ::= Ts <name> # dependent elaborated type specifier using 'struct' or 'class'
3639 // ::= Tu <name> # dependent elaborated type specifier using 'union'
3640 // ::= Te <name> # dependent elaborated type specifier using 'enum'
3641 template <typename Derived
, typename Alloc
>
3642 Node
*AbstractManglingParser
<Derived
, Alloc
>::parseClassEnumType() {
3643 StringView ElabSpef
;
3644 if (consumeIf("Ts"))
3645 ElabSpef
= "struct";
3646 else if (consumeIf("Tu"))
3648 else if (consumeIf("Te"))
3651 Node
*Name
= getDerived().parseName();
3652 if (Name
== nullptr)
3655 if (!ElabSpef
.empty())
3656 return make
<ElaboratedTypeSpefType
>(ElabSpef
, Name
);
3661 // <qualified-type> ::= <qualifiers> <type>
3662 // <qualifiers> ::= <extended-qualifier>* <CV-qualifiers>
3663 // <extended-qualifier> ::= U <source-name> [<template-args>] # vendor extended type qualifier
3664 template <typename Derived
, typename Alloc
>
3665 Node
*AbstractManglingParser
<Derived
, Alloc
>::parseQualifiedType() {
3666 if (consumeIf('U')) {
3667 StringView Qual
= parseBareSourceName();
3671 // FIXME parse the optional <template-args> here!
3673 // extension ::= U <objc-name> <objc-type> # objc-type<identifier>
3674 if (Qual
.startsWith("objcproto")) {
3675 StringView ProtoSourceName
= Qual
.dropFront(std::strlen("objcproto"));
3678 SwapAndRestore
<const char *> SaveFirst(First
, ProtoSourceName
.begin()),
3679 SaveLast(Last
, ProtoSourceName
.end());
3680 Proto
= parseBareSourceName();
3684 Node
*Child
= getDerived().parseQualifiedType();
3685 if (Child
== nullptr)
3687 return make
<ObjCProtoName
>(Child
, Proto
);
3690 Node
*Child
= getDerived().parseQualifiedType();
3691 if (Child
== nullptr)
3693 return make
<VendorExtQualType
>(Child
, Qual
);
3696 Qualifiers Quals
= parseCVQualifiers();
3697 Node
*Ty
= getDerived().parseType();
3700 if (Quals
!= QualNone
)
3701 Ty
= make
<QualType
>(Ty
, Quals
);
3705 // <type> ::= <builtin-type>
3706 // ::= <qualified-type>
3707 // ::= <function-type>
3708 // ::= <class-enum-type>
3710 // ::= <pointer-to-member-type>
3711 // ::= <template-param>
3712 // ::= <template-template-param> <template-args>
3714 // ::= P <type> # pointer
3715 // ::= R <type> # l-value reference
3716 // ::= O <type> # r-value reference (C++11)
3717 // ::= C <type> # complex pair (C99)
3718 // ::= G <type> # imaginary (C99)
3719 // ::= <substitution> # See Compression below
3720 // extension ::= U <objc-name> <objc-type> # objc-type<identifier>
3721 // extension ::= <vector-type> # <vector-type> starts with Dv
3723 // <objc-name> ::= <k0 number> objcproto <k1 number> <identifier> # k0 = 9 + <number of digits in k1> + k1
3724 // <objc-type> ::= <source-name> # PU<11+>objcproto 11objc_object<source-name> 11objc_object -> id<source-name>
3725 template <typename Derived
, typename Alloc
>
3726 Node
*AbstractManglingParser
<Derived
, Alloc
>::parseType() {
3727 Node
*Result
= nullptr;
3730 // ::= <qualified-type>
3734 unsigned AfterQuals
= 0;
3735 if (look(AfterQuals
) == 'r') ++AfterQuals
;
3736 if (look(AfterQuals
) == 'V') ++AfterQuals
;
3737 if (look(AfterQuals
) == 'K') ++AfterQuals
;
3739 if (look(AfterQuals
) == 'F' ||
3740 (look(AfterQuals
) == 'D' &&
3741 (look(AfterQuals
+ 1) == 'o' || look(AfterQuals
+ 1) == 'O' ||
3742 look(AfterQuals
+ 1) == 'w' || look(AfterQuals
+ 1) == 'x'))) {
3743 Result
= getDerived().parseFunctionType();
3746 DEMANGLE_FALLTHROUGH
;
3749 Result
= getDerived().parseQualifiedType();
3752 // <builtin-type> ::= v # void
3755 return make
<NameType
>("void");
3759 return make
<NameType
>("wchar_t");
3763 return make
<NameType
>("bool");
3767 return make
<NameType
>("char");
3768 // ::= a # signed char
3771 return make
<NameType
>("signed char");
3772 // ::= h # unsigned char
3775 return make
<NameType
>("unsigned char");
3779 return make
<NameType
>("short");
3780 // ::= t # unsigned short
3783 return make
<NameType
>("unsigned short");
3787 return make
<NameType
>("int");
3788 // ::= j # unsigned int
3791 return make
<NameType
>("unsigned int");
3795 return make
<NameType
>("long");
3796 // ::= m # unsigned long
3799 return make
<NameType
>("unsigned long");
3800 // ::= x # long long, __int64
3803 return make
<NameType
>("long long");
3804 // ::= y # unsigned long long, __int64
3807 return make
<NameType
>("unsigned long long");
3811 return make
<NameType
>("__int128");
3812 // ::= o # unsigned __int128
3815 return make
<NameType
>("unsigned __int128");
3819 return make
<NameType
>("float");
3823 return make
<NameType
>("double");
3824 // ::= e # long double, __float80
3827 return make
<NameType
>("long double");
3828 // ::= g # __float128
3831 return make
<NameType
>("__float128");
3835 return make
<NameType
>("...");
3837 // <builtin-type> ::= u <source-name> # vendor extended type
3840 StringView Res
= parseBareSourceName();
3843 // Typically, <builtin-type>s are not considered substitution candidates,
3844 // but the exception to that exception is vendor extended types (Itanium C++
3846 Result
= make
<NameType
>(Res
);
3851 // ::= Dd # IEEE 754r decimal floating point (64 bits)
3854 return make
<NameType
>("decimal64");
3855 // ::= De # IEEE 754r decimal floating point (128 bits)
3858 return make
<NameType
>("decimal128");
3859 // ::= Df # IEEE 754r decimal floating point (32 bits)
3862 return make
<NameType
>("decimal32");
3863 // ::= Dh # IEEE 754r half-precision floating point (16 bits)
3866 return make
<NameType
>("decimal16");
3867 // ::= Di # char32_t
3870 return make
<NameType
>("char32_t");
3871 // ::= Ds # char16_t
3874 return make
<NameType
>("char16_t");
3875 // ::= Du # char8_t (C++2a, not yet in the Itanium spec)
3878 return make
<NameType
>("char8_t");
3879 // ::= Da # auto (in dependent new-expressions)
3882 return make
<NameType
>("auto");
3883 // ::= Dc # decltype(auto)
3886 return make
<NameType
>("decltype(auto)");
3887 // ::= Dn # std::nullptr_t (i.e., decltype(nullptr))
3890 return make
<NameType
>("std::nullptr_t");
3895 Result
= getDerived().parseDecltype();
3898 // extension ::= <vector-type> # <vector-type> starts with Dv
3900 Result
= getDerived().parseVectorType();
3903 // ::= Dp <type> # pack expansion (C++0x)
3906 Node
*Child
= getDerived().parseType();
3909 Result
= make
<ParameterPackExpansion
>(Child
);
3912 // Exception specifier on a function type.
3916 // Transaction safe function type.
3918 Result
= getDerived().parseFunctionType();
3922 // ::= <function-type>
3924 Result
= getDerived().parseFunctionType();
3929 Result
= getDerived().parseArrayType();
3932 // ::= <pointer-to-member-type>
3934 Result
= getDerived().parsePointerToMemberType();
3937 // ::= <template-param>
3939 // This could be an elaborate type specifier on a <class-enum-type>.
3940 if (look(1) == 's' || look(1) == 'u' || look(1) == 'e') {
3941 Result
= getDerived().parseClassEnumType();
3945 Result
= getDerived().parseTemplateParam();
3946 if (Result
== nullptr)
3949 // Result could be either of:
3950 // <type> ::= <template-param>
3951 // <type> ::= <template-template-param> <template-args>
3953 // <template-template-param> ::= <template-param>
3954 // ::= <substitution>
3956 // If this is followed by some <template-args>, and we're permitted to
3957 // parse them, take the second production.
3959 if (TryToParseTemplateArgs
&& look() == 'I') {
3960 Node
*TA
= getDerived().parseTemplateArgs();
3963 Result
= make
<NameWithTemplateArgs
>(Result
, TA
);
3967 // ::= P <type> # pointer
3970 Node
*Ptr
= getDerived().parseType();
3973 Result
= make
<PointerType
>(Ptr
);
3976 // ::= R <type> # l-value reference
3979 Node
*Ref
= getDerived().parseType();
3982 Result
= make
<ReferenceType
>(Ref
, ReferenceKind::LValue
);
3985 // ::= O <type> # r-value reference (C++11)
3988 Node
*Ref
= getDerived().parseType();
3991 Result
= make
<ReferenceType
>(Ref
, ReferenceKind::RValue
);
3994 // ::= C <type> # complex pair (C99)
3997 Node
*P
= getDerived().parseType();
4000 Result
= make
<PostfixQualifiedType
>(P
, " complex");
4003 // ::= G <type> # imaginary (C99)
4006 Node
*P
= getDerived().parseType();
4009 Result
= make
<PostfixQualifiedType
>(P
, " imaginary");
4012 // ::= <substitution> # See Compression below
4014 if (look(1) && look(1) != 't') {
4015 Node
*Sub
= getDerived().parseSubstitution();
4019 // Sub could be either of:
4020 // <type> ::= <substitution>
4021 // <type> ::= <template-template-param> <template-args>
4023 // <template-template-param> ::= <template-param>
4024 // ::= <substitution>
4026 // If this is followed by some <template-args>, and we're permitted to
4027 // parse them, take the second production.
4029 if (TryToParseTemplateArgs
&& look() == 'I') {
4030 Node
*TA
= getDerived().parseTemplateArgs();
4033 Result
= make
<NameWithTemplateArgs
>(Sub
, TA
);
4037 // If all we parsed was a substitution, don't re-insert into the
4038 // substitution table.
4041 DEMANGLE_FALLTHROUGH
;
4043 // ::= <class-enum-type>
4045 Result
= getDerived().parseClassEnumType();
4050 // If we parsed a type, insert it into the substitution table. Note that all
4051 // <builtin-type>s and <substitution>s have already bailed out, because they
4052 // don't get substitutions.
4053 if (Result
!= nullptr)
4054 Subs
.push_back(Result
);
4058 template <typename Derived
, typename Alloc
>
4059 Node
*AbstractManglingParser
<Derived
, Alloc
>::parsePrefixExpr(StringView Kind
) {
4060 Node
*E
= getDerived().parseExpr();
4063 return make
<PrefixExpr
>(Kind
, E
);
4066 template <typename Derived
, typename Alloc
>
4067 Node
*AbstractManglingParser
<Derived
, Alloc
>::parseBinaryExpr(StringView Kind
) {
4068 Node
*LHS
= getDerived().parseExpr();
4071 Node
*RHS
= getDerived().parseExpr();
4074 return make
<BinaryExpr
>(LHS
, Kind
, RHS
);
4077 template <typename Derived
, typename Alloc
>
4079 AbstractManglingParser
<Derived
, Alloc
>::parseIntegerLiteral(StringView Lit
) {
4080 StringView Tmp
= parseNumber(true);
4081 if (!Tmp
.empty() && consumeIf('E'))
4082 return make
<IntegerLiteral
>(Lit
, Tmp
);
4086 // <CV-Qualifiers> ::= [r] [V] [K]
4087 template <typename Alloc
, typename Derived
>
4088 Qualifiers AbstractManglingParser
<Alloc
, Derived
>::parseCVQualifiers() {
4089 Qualifiers CVR
= QualNone
;
4091 CVR
|= QualRestrict
;
4093 CVR
|= QualVolatile
;
4099 // <function-param> ::= fp <top-level CV-Qualifiers> _ # L == 0, first parameter
4100 // ::= fp <top-level CV-Qualifiers> <parameter-2 non-negative number> _ # L == 0, second and later parameters
4101 // ::= fL <L-1 non-negative number> p <top-level CV-Qualifiers> _ # L > 0, first parameter
4102 // ::= fL <L-1 non-negative number> p <top-level CV-Qualifiers> <parameter-2 non-negative number> _ # L > 0, second and later parameters
4103 template <typename Derived
, typename Alloc
>
4104 Node
*AbstractManglingParser
<Derived
, Alloc
>::parseFunctionParam() {
4105 if (consumeIf("fp")) {
4106 parseCVQualifiers();
4107 StringView Num
= parseNumber();
4108 if (!consumeIf('_'))
4110 return make
<FunctionParam
>(Num
);
4112 if (consumeIf("fL")) {
4113 if (parseNumber().empty())
4115 if (!consumeIf('p'))
4117 parseCVQualifiers();
4118 StringView Num
= parseNumber();
4119 if (!consumeIf('_'))
4121 return make
<FunctionParam
>(Num
);
4126 // [gs] nw <expression>* _ <type> E # new (expr-list) type
4127 // [gs] nw <expression>* _ <type> <initializer> # new (expr-list) type (init)
4128 // [gs] na <expression>* _ <type> E # new[] (expr-list) type
4129 // [gs] na <expression>* _ <type> <initializer> # new[] (expr-list) type (init)
4130 // <initializer> ::= pi <expression>* E # parenthesized initialization
4131 template <typename Derived
, typename Alloc
>
4132 Node
*AbstractManglingParser
<Derived
, Alloc
>::parseNewExpr() {
4133 bool Global
= consumeIf("gs");
4134 bool IsArray
= look(1) == 'a';
4135 if (!consumeIf("nw") && !consumeIf("na"))
4137 size_t Exprs
= Names
.size();
4138 while (!consumeIf('_')) {
4139 Node
*Ex
= getDerived().parseExpr();
4142 Names
.push_back(Ex
);
4144 NodeArray ExprList
= popTrailingNodeArray(Exprs
);
4145 Node
*Ty
= getDerived().parseType();
4148 if (consumeIf("pi")) {
4149 size_t InitsBegin
= Names
.size();
4150 while (!consumeIf('E')) {
4151 Node
*Init
= getDerived().parseExpr();
4152 if (Init
== nullptr)
4154 Names
.push_back(Init
);
4156 NodeArray Inits
= popTrailingNodeArray(InitsBegin
);
4157 return make
<NewExpr
>(ExprList
, Ty
, Inits
, Global
, IsArray
);
4158 } else if (!consumeIf('E'))
4160 return make
<NewExpr
>(ExprList
, Ty
, NodeArray(), Global
, IsArray
);
4163 // cv <type> <expression> # conversion with one argument
4164 // cv <type> _ <expression>* E # conversion with a different number of arguments
4165 template <typename Derived
, typename Alloc
>
4166 Node
*AbstractManglingParser
<Derived
, Alloc
>::parseConversionExpr() {
4167 if (!consumeIf("cv"))
4171 SwapAndRestore
<bool> SaveTemp(TryToParseTemplateArgs
, false);
4172 Ty
= getDerived().parseType();
4178 if (consumeIf('_')) {
4179 size_t ExprsBegin
= Names
.size();
4180 while (!consumeIf('E')) {
4181 Node
*E
= getDerived().parseExpr();
4186 NodeArray Exprs
= popTrailingNodeArray(ExprsBegin
);
4187 return make
<ConversionExpr
>(Ty
, Exprs
);
4190 Node
*E
[1] = {getDerived().parseExpr()};
4191 if (E
[0] == nullptr)
4193 return make
<ConversionExpr
>(Ty
, makeNodeArray(E
, E
+ 1));
4196 // <expr-primary> ::= L <type> <value number> E # integer literal
4197 // ::= L <type> <value float> E # floating literal
4198 // ::= L <string type> E # string literal
4199 // ::= L <nullptr type> E # nullptr literal (i.e., "LDnE")
4200 // ::= L <lambda type> E # lambda expression
4201 // FIXME: ::= L <type> <real-part float> _ <imag-part float> E # complex floating point literal (C 2000)
4202 // ::= L <mangled-name> E # external name
4203 template <typename Derived
, typename Alloc
>
4204 Node
*AbstractManglingParser
<Derived
, Alloc
>::parseExprPrimary() {
4205 if (!consumeIf('L'))
4210 return getDerived().parseIntegerLiteral("wchar_t");
4212 if (consumeIf("b0E"))
4213 return make
<BoolExpr
>(0);
4214 if (consumeIf("b1E"))
4215 return make
<BoolExpr
>(1);
4219 return getDerived().parseIntegerLiteral("char");
4222 return getDerived().parseIntegerLiteral("signed char");
4225 return getDerived().parseIntegerLiteral("unsigned char");
4228 return getDerived().parseIntegerLiteral("short");
4231 return getDerived().parseIntegerLiteral("unsigned short");
4234 return getDerived().parseIntegerLiteral("");
4237 return getDerived().parseIntegerLiteral("u");
4240 return getDerived().parseIntegerLiteral("l");
4243 return getDerived().parseIntegerLiteral("ul");
4246 return getDerived().parseIntegerLiteral("ll");
4249 return getDerived().parseIntegerLiteral("ull");
4252 return getDerived().parseIntegerLiteral("__int128");
4255 return getDerived().parseIntegerLiteral("unsigned __int128");
4258 return getDerived().template parseFloatingLiteral
<float>();
4261 return getDerived().template parseFloatingLiteral
<double>();
4264 return getDerived().template parseFloatingLiteral
<long double>();
4266 if (consumeIf("_Z")) {
4267 Node
*R
= getDerived().parseEncoding();
4268 if (R
!= nullptr && consumeIf('E'))
4273 Node
*T
= getDerived().parseType();
4276 // FIXME: We need to include the string contents in the mangling.
4278 return make
<StringLiteral
>(T
);
4282 if (consumeIf("DnE"))
4283 return make
<NameType
>("nullptr");
4286 // Invalid mangled name per
4287 // http://sourcerytools.com/pipermail/cxx-abi-dev/2011-August/002422.html
4290 // FIXME: Should we support LUb... for block literals?
4293 Node
*T
= parseUnnamedTypeName(nullptr);
4294 if (!T
|| !consumeIf('E'))
4296 return make
<LambdaExpr
>(T
);
4299 // might be named type
4300 Node
*T
= getDerived().parseType();
4303 StringView N
= parseNumber();
4306 if (!consumeIf('E'))
4308 return make
<IntegerCastExpr
>(T
, N
);
4313 // <braced-expression> ::= <expression>
4314 // ::= di <field source-name> <braced-expression> # .name = expr
4315 // ::= dx <index expression> <braced-expression> # [expr] = expr
4316 // ::= dX <range begin expression> <range end expression> <braced-expression>
4317 template <typename Derived
, typename Alloc
>
4318 Node
*AbstractManglingParser
<Derived
, Alloc
>::parseBracedExpr() {
4319 if (look() == 'd') {
4323 Node
*Field
= getDerived().parseSourceName(/*NameState=*/nullptr);
4324 if (Field
== nullptr)
4326 Node
*Init
= getDerived().parseBracedExpr();
4327 if (Init
== nullptr)
4329 return make
<BracedExpr
>(Field
, Init
, /*isArray=*/false);
4333 Node
*Index
= getDerived().parseExpr();
4334 if (Index
== nullptr)
4336 Node
*Init
= getDerived().parseBracedExpr();
4337 if (Init
== nullptr)
4339 return make
<BracedExpr
>(Index
, Init
, /*isArray=*/true);
4343 Node
*RangeBegin
= getDerived().parseExpr();
4344 if (RangeBegin
== nullptr)
4346 Node
*RangeEnd
= getDerived().parseExpr();
4347 if (RangeEnd
== nullptr)
4349 Node
*Init
= getDerived().parseBracedExpr();
4350 if (Init
== nullptr)
4352 return make
<BracedRangeExpr
>(RangeBegin
, RangeEnd
, Init
);
4356 return getDerived().parseExpr();
4359 // (not yet in the spec)
4360 // <fold-expr> ::= fL <binary-operator-name> <expression> <expression>
4361 // ::= fR <binary-operator-name> <expression> <expression>
4362 // ::= fl <binary-operator-name> <expression>
4363 // ::= fr <binary-operator-name> <expression>
4364 template <typename Derived
, typename Alloc
>
4365 Node
*AbstractManglingParser
<Derived
, Alloc
>::parseFoldExpr() {
4366 if (!consumeIf('f'))
4369 char FoldKind
= look();
4370 bool IsLeftFold
, HasInitializer
;
4371 HasInitializer
= FoldKind
== 'L' || FoldKind
== 'R';
4372 if (FoldKind
== 'l' || FoldKind
== 'L')
4374 else if (FoldKind
== 'r' || FoldKind
== 'R')
4380 // FIXME: This map is duplicated in parseOperatorName and parseExpr.
4381 StringView OperatorName
;
4382 if (consumeIf("aa")) OperatorName
= "&&";
4383 else if (consumeIf("an")) OperatorName
= "&";
4384 else if (consumeIf("aN")) OperatorName
= "&=";
4385 else if (consumeIf("aS")) OperatorName
= "=";
4386 else if (consumeIf("cm")) OperatorName
= ",";
4387 else if (consumeIf("ds")) OperatorName
= ".*";
4388 else if (consumeIf("dv")) OperatorName
= "/";
4389 else if (consumeIf("dV")) OperatorName
= "/=";
4390 else if (consumeIf("eo")) OperatorName
= "^";
4391 else if (consumeIf("eO")) OperatorName
= "^=";
4392 else if (consumeIf("eq")) OperatorName
= "==";
4393 else if (consumeIf("ge")) OperatorName
= ">=";
4394 else if (consumeIf("gt")) OperatorName
= ">";
4395 else if (consumeIf("le")) OperatorName
= "<=";
4396 else if (consumeIf("ls")) OperatorName
= "<<";
4397 else if (consumeIf("lS")) OperatorName
= "<<=";
4398 else if (consumeIf("lt")) OperatorName
= "<";
4399 else if (consumeIf("mi")) OperatorName
= "-";
4400 else if (consumeIf("mI")) OperatorName
= "-=";
4401 else if (consumeIf("ml")) OperatorName
= "*";
4402 else if (consumeIf("mL")) OperatorName
= "*=";
4403 else if (consumeIf("ne")) OperatorName
= "!=";
4404 else if (consumeIf("oo")) OperatorName
= "||";
4405 else if (consumeIf("or")) OperatorName
= "|";
4406 else if (consumeIf("oR")) OperatorName
= "|=";
4407 else if (consumeIf("pl")) OperatorName
= "+";
4408 else if (consumeIf("pL")) OperatorName
= "+=";
4409 else if (consumeIf("rm")) OperatorName
= "%";
4410 else if (consumeIf("rM")) OperatorName
= "%=";
4411 else if (consumeIf("rs")) OperatorName
= ">>";
4412 else if (consumeIf("rS")) OperatorName
= ">>=";
4413 else return nullptr;
4415 Node
*Pack
= getDerived().parseExpr(), *Init
= nullptr;
4416 if (Pack
== nullptr)
4418 if (HasInitializer
) {
4419 Init
= getDerived().parseExpr();
4420 if (Init
== nullptr)
4424 if (IsLeftFold
&& Init
)
4425 std::swap(Pack
, Init
);
4427 return make
<FoldExpr
>(IsLeftFold
, OperatorName
, Pack
, Init
);
4430 // <expression> ::= <unary operator-name> <expression>
4431 // ::= <binary operator-name> <expression> <expression>
4432 // ::= <ternary operator-name> <expression> <expression> <expression>
4433 // ::= cl <expression>+ E # call
4434 // ::= cv <type> <expression> # conversion with one argument
4435 // ::= cv <type> _ <expression>* E # conversion with a different number of arguments
4436 // ::= [gs] nw <expression>* _ <type> E # new (expr-list) type
4437 // ::= [gs] nw <expression>* _ <type> <initializer> # new (expr-list) type (init)
4438 // ::= [gs] na <expression>* _ <type> E # new[] (expr-list) type
4439 // ::= [gs] na <expression>* _ <type> <initializer> # new[] (expr-list) type (init)
4440 // ::= [gs] dl <expression> # delete expression
4441 // ::= [gs] da <expression> # delete[] expression
4442 // ::= pp_ <expression> # prefix ++
4443 // ::= mm_ <expression> # prefix --
4444 // ::= ti <type> # typeid (type)
4445 // ::= te <expression> # typeid (expression)
4446 // ::= dc <type> <expression> # dynamic_cast<type> (expression)
4447 // ::= sc <type> <expression> # static_cast<type> (expression)
4448 // ::= cc <type> <expression> # const_cast<type> (expression)
4449 // ::= rc <type> <expression> # reinterpret_cast<type> (expression)
4450 // ::= st <type> # sizeof (a type)
4451 // ::= sz <expression> # sizeof (an expression)
4452 // ::= at <type> # alignof (a type)
4453 // ::= az <expression> # alignof (an expression)
4454 // ::= nx <expression> # noexcept (expression)
4455 // ::= <template-param>
4456 // ::= <function-param>
4457 // ::= dt <expression> <unresolved-name> # expr.name
4458 // ::= pt <expression> <unresolved-name> # expr->name
4459 // ::= ds <expression> <expression> # expr.*expr
4460 // ::= sZ <template-param> # size of a parameter pack
4461 // ::= sZ <function-param> # size of a function parameter pack
4462 // ::= sP <template-arg>* E # sizeof...(T), size of a captured template parameter pack from an alias template
4463 // ::= sp <expression> # pack expansion
4464 // ::= tw <expression> # throw expression
4465 // ::= tr # throw with no operand (rethrow)
4466 // ::= <unresolved-name> # f(p), N::f(p), ::f(p),
4467 // # freestanding dependent name (e.g., T::x),
4468 // # objectless nonstatic member reference
4469 // ::= fL <binary-operator-name> <expression> <expression>
4470 // ::= fR <binary-operator-name> <expression> <expression>
4471 // ::= fl <binary-operator-name> <expression>
4472 // ::= fr <binary-operator-name> <expression>
4473 // ::= <expr-primary>
4474 template <typename Derived
, typename Alloc
>
4475 Node
*AbstractManglingParser
<Derived
, Alloc
>::parseExpr() {
4476 bool Global
= consumeIf("gs");
4482 return getDerived().parseExprPrimary();
4484 return getDerived().parseTemplateParam();
4486 // Disambiguate a fold expression from a <function-param>.
4487 if (look(1) == 'p' || (look(1) == 'L' && std::isdigit(look(2))))
4488 return getDerived().parseFunctionParam();
4489 return getDerived().parseFoldExpr();
4495 return getDerived().parseBinaryExpr("&&");
4498 return getDerived().parsePrefixExpr("&");
4501 return getDerived().parseBinaryExpr("&");
4504 return getDerived().parseBinaryExpr("&=");
4507 return getDerived().parseBinaryExpr("=");
4510 Node
*Ty
= getDerived().parseType();
4513 return make
<EnclosingExpr
>("alignof (", Ty
, ")");
4517 Node
*Ty
= getDerived().parseExpr();
4520 return make
<EnclosingExpr
>("alignof (", Ty
, ")");
4526 // cc <type> <expression> # const_cast<type>(expression)
4529 Node
*Ty
= getDerived().parseType();
4532 Node
*Ex
= getDerived().parseExpr();
4535 return make
<CastExpr
>("const_cast", Ty
, Ex
);
4537 // cl <expression>+ E # call
4540 Node
*Callee
= getDerived().parseExpr();
4541 if (Callee
== nullptr)
4543 size_t ExprsBegin
= Names
.size();
4544 while (!consumeIf('E')) {
4545 Node
*E
= getDerived().parseExpr();
4550 return make
<CallExpr
>(Callee
, popTrailingNodeArray(ExprsBegin
));
4554 return getDerived().parseBinaryExpr(",");
4557 return getDerived().parsePrefixExpr("~");
4559 return getDerived().parseConversionExpr();
4566 Node
*Ex
= getDerived().parseExpr();
4569 return make
<DeleteExpr
>(Ex
, Global
, /*is_array=*/true);
4573 Node
*T
= getDerived().parseType();
4576 Node
*Ex
= getDerived().parseExpr();
4579 return make
<CastExpr
>("dynamic_cast", T
, Ex
);
4583 return getDerived().parsePrefixExpr("*");
4586 Node
*E
= getDerived().parseExpr();
4589 return make
<DeleteExpr
>(E
, Global
, /*is_array=*/false);
4592 return getDerived().parseUnresolvedName();
4595 Node
*LHS
= getDerived().parseExpr();
4598 Node
*RHS
= getDerived().parseExpr();
4601 return make
<MemberExpr
>(LHS
, ".*", RHS
);
4605 Node
*LHS
= getDerived().parseExpr();
4608 Node
*RHS
= getDerived().parseExpr();
4611 return make
<MemberExpr
>(LHS
, ".", RHS
);
4615 return getDerived().parseBinaryExpr("/");
4618 return getDerived().parseBinaryExpr("/=");
4625 return getDerived().parseBinaryExpr("^");
4628 return getDerived().parseBinaryExpr("^=");
4631 return getDerived().parseBinaryExpr("==");
4638 return getDerived().parseBinaryExpr(">=");
4641 return getDerived().parseBinaryExpr(">");
4648 Node
*Base
= getDerived().parseExpr();
4649 if (Base
== nullptr)
4651 Node
*Index
= getDerived().parseExpr();
4652 if (Index
== nullptr)
4654 return make
<ArraySubscriptExpr
>(Base
, Index
);
4658 size_t InitsBegin
= Names
.size();
4659 while (!consumeIf('E')) {
4660 Node
*E
= getDerived().parseBracedExpr();
4665 return make
<InitListExpr
>(nullptr, popTrailingNodeArray(InitsBegin
));
4673 return getDerived().parseBinaryExpr("<=");
4676 return getDerived().parseBinaryExpr("<<");
4679 return getDerived().parseBinaryExpr("<<=");
4682 return getDerived().parseBinaryExpr("<");
4689 return getDerived().parseBinaryExpr("-");
4692 return getDerived().parseBinaryExpr("-=");
4695 return getDerived().parseBinaryExpr("*");
4698 return getDerived().parseBinaryExpr("*=");
4702 return getDerived().parsePrefixExpr("--");
4703 Node
*Ex
= getDerived().parseExpr();
4706 return make
<PostfixExpr
>(Ex
, "--");
4713 return getDerived().parseNewExpr();
4716 return getDerived().parseBinaryExpr("!=");
4719 return getDerived().parsePrefixExpr("-");
4722 return getDerived().parsePrefixExpr("!");
4725 Node
*Ex
= getDerived().parseExpr();
4728 return make
<EnclosingExpr
>("noexcept (", Ex
, ")");
4734 return getDerived().parseUnresolvedName();
4737 return getDerived().parseBinaryExpr("||");
4740 return getDerived().parseBinaryExpr("|");
4743 return getDerived().parseBinaryExpr("|=");
4750 return getDerived().parseBinaryExpr("->*");
4753 return getDerived().parseBinaryExpr("+");
4756 return getDerived().parseBinaryExpr("+=");
4760 return getDerived().parsePrefixExpr("++");
4761 Node
*Ex
= getDerived().parseExpr();
4764 return make
<PostfixExpr
>(Ex
, "++");
4768 return getDerived().parsePrefixExpr("+");
4771 Node
*L
= getDerived().parseExpr();
4774 Node
*R
= getDerived().parseExpr();
4777 return make
<MemberExpr
>(L
, "->", R
);
4782 if (First
[1] == 'u') {
4784 Node
*Cond
= getDerived().parseExpr();
4785 if (Cond
== nullptr)
4787 Node
*LHS
= getDerived().parseExpr();
4790 Node
*RHS
= getDerived().parseExpr();
4793 return make
<ConditionalExpr
>(Cond
, LHS
, RHS
);
4800 Node
*T
= getDerived().parseType();
4803 Node
*Ex
= getDerived().parseExpr();
4806 return make
<CastExpr
>("reinterpret_cast", T
, Ex
);
4810 return getDerived().parseBinaryExpr("%");
4813 return getDerived().parseBinaryExpr("%=");
4816 return getDerived().parseBinaryExpr(">>");
4819 return getDerived().parseBinaryExpr(">>=");
4826 Node
*T
= getDerived().parseType();
4829 Node
*Ex
= getDerived().parseExpr();
4832 return make
<CastExpr
>("static_cast", T
, Ex
);
4836 Node
*Child
= getDerived().parseExpr();
4837 if (Child
== nullptr)
4839 return make
<ParameterPackExpansion
>(Child
);
4842 return getDerived().parseUnresolvedName();
4845 Node
*Ty
= getDerived().parseType();
4848 return make
<EnclosingExpr
>("sizeof (", Ty
, ")");
4852 Node
*Ex
= getDerived().parseExpr();
4855 return make
<EnclosingExpr
>("sizeof (", Ex
, ")");
4859 if (look() == 'T') {
4860 Node
*R
= getDerived().parseTemplateParam();
4863 return make
<SizeofParamPackExpr
>(R
);
4864 } else if (look() == 'f') {
4865 Node
*FP
= getDerived().parseFunctionParam();
4868 return make
<EnclosingExpr
>("sizeof... (", FP
, ")");
4873 size_t ArgsBegin
= Names
.size();
4874 while (!consumeIf('E')) {
4875 Node
*Arg
= getDerived().parseTemplateArg();
4878 Names
.push_back(Arg
);
4880 auto *Pack
= make
<NodeArrayNode
>(popTrailingNodeArray(ArgsBegin
));
4883 return make
<EnclosingExpr
>("sizeof... (", Pack
, ")");
4891 Node
*Ex
= getDerived().parseExpr();
4894 return make
<EnclosingExpr
>("typeid (", Ex
, ")");
4898 Node
*Ty
= getDerived().parseType();
4901 return make
<EnclosingExpr
>("typeid (", Ty
, ")");
4905 Node
*Ty
= getDerived().parseType();
4908 size_t InitsBegin
= Names
.size();
4909 while (!consumeIf('E')) {
4910 Node
*E
= getDerived().parseBracedExpr();
4915 return make
<InitListExpr
>(Ty
, popTrailingNodeArray(InitsBegin
));
4919 return make
<NameType
>("throw");
4922 Node
*Ex
= getDerived().parseExpr();
4925 return make
<ThrowExpr
>(Ex
);
4938 return getDerived().parseUnresolvedName();
4941 if (consumeIf("u8__uuidoft")) {
4942 Node
*Ty
= getDerived().parseType();
4945 return make
<UUIDOfExpr
>(Ty
);
4948 if (consumeIf("u8__uuidofz")) {
4949 Node
*Ex
= getDerived().parseExpr();
4952 return make
<UUIDOfExpr
>(Ex
);
4958 // <call-offset> ::= h <nv-offset> _
4959 // ::= v <v-offset> _
4961 // <nv-offset> ::= <offset number>
4962 // # non-virtual base override
4964 // <v-offset> ::= <offset number> _ <virtual offset number>
4965 // # virtual base override, with vcall offset
4966 template <typename Alloc
, typename Derived
>
4967 bool AbstractManglingParser
<Alloc
, Derived
>::parseCallOffset() {
4968 // Just scan through the call offset, we never add this information into the
4971 return parseNumber(true).empty() || !consumeIf('_');
4973 return parseNumber(true).empty() || !consumeIf('_') ||
4974 parseNumber(true).empty() || !consumeIf('_');
4978 // <special-name> ::= TV <type> # virtual table
4979 // ::= TT <type> # VTT structure (construction vtable index)
4980 // ::= TI <type> # typeinfo structure
4981 // ::= TS <type> # typeinfo name (null-terminated byte string)
4982 // ::= Tc <call-offset> <call-offset> <base encoding>
4983 // # base is the nominal target function of thunk
4984 // # first call-offset is 'this' adjustment
4985 // # second call-offset is result adjustment
4986 // ::= T <call-offset> <base encoding>
4987 // # base is the nominal target function of thunk
4988 // ::= GV <object name> # Guard variable for one-time initialization
4990 // ::= TW <object name> # Thread-local wrapper
4991 // ::= TH <object name> # Thread-local initialization
4992 // ::= GR <object name> _ # First temporary
4993 // ::= GR <object name> <seq-id> _ # Subsequent temporaries
4994 // extension ::= TC <first type> <number> _ <second type> # construction vtable for second-in-first
4995 // extension ::= GR <object name> # reference temporary for object
4996 template <typename Derived
, typename Alloc
>
4997 Node
*AbstractManglingParser
<Derived
, Alloc
>::parseSpecialName() {
5001 // TV <type> # virtual table
5004 Node
*Ty
= getDerived().parseType();
5007 return make
<SpecialName
>("vtable for ", Ty
);
5009 // TT <type> # VTT structure (construction vtable index)
5012 Node
*Ty
= getDerived().parseType();
5015 return make
<SpecialName
>("VTT for ", Ty
);
5017 // TI <type> # typeinfo structure
5020 Node
*Ty
= getDerived().parseType();
5023 return make
<SpecialName
>("typeinfo for ", Ty
);
5025 // TS <type> # typeinfo name (null-terminated byte string)
5028 Node
*Ty
= getDerived().parseType();
5031 return make
<SpecialName
>("typeinfo name for ", Ty
);
5033 // Tc <call-offset> <call-offset> <base encoding>
5036 if (parseCallOffset() || parseCallOffset())
5038 Node
*Encoding
= getDerived().parseEncoding();
5039 if (Encoding
== nullptr)
5041 return make
<SpecialName
>("covariant return thunk to ", Encoding
);
5043 // extension ::= TC <first type> <number> _ <second type>
5044 // # construction vtable for second-in-first
5047 Node
*FirstType
= getDerived().parseType();
5048 if (FirstType
== nullptr)
5050 if (parseNumber(true).empty() || !consumeIf('_'))
5052 Node
*SecondType
= getDerived().parseType();
5053 if (SecondType
== nullptr)
5055 return make
<CtorVtableSpecialName
>(SecondType
, FirstType
);
5057 // TW <object name> # Thread-local wrapper
5060 Node
*Name
= getDerived().parseName();
5061 if (Name
== nullptr)
5063 return make
<SpecialName
>("thread-local wrapper routine for ", Name
);
5065 // TH <object name> # Thread-local initialization
5068 Node
*Name
= getDerived().parseName();
5069 if (Name
== nullptr)
5071 return make
<SpecialName
>("thread-local initialization routine for ", Name
);
5073 // T <call-offset> <base encoding>
5076 bool IsVirt
= look() == 'v';
5077 if (parseCallOffset())
5079 Node
*BaseEncoding
= getDerived().parseEncoding();
5080 if (BaseEncoding
== nullptr)
5083 return make
<SpecialName
>("virtual thunk to ", BaseEncoding
);
5085 return make
<SpecialName
>("non-virtual thunk to ", BaseEncoding
);
5090 // GV <object name> # Guard variable for one-time initialization
5093 Node
*Name
= getDerived().parseName();
5094 if (Name
== nullptr)
5096 return make
<SpecialName
>("guard variable for ", Name
);
5098 // GR <object name> # reference temporary for object
5099 // GR <object name> _ # First temporary
5100 // GR <object name> <seq-id> _ # Subsequent temporaries
5103 Node
*Name
= getDerived().parseName();
5104 if (Name
== nullptr)
5107 bool ParsedSeqId
= !parseSeqId(&Count
);
5108 if (!consumeIf('_') && ParsedSeqId
)
5110 return make
<SpecialName
>("reference temporary for ", Name
);
5117 // <encoding> ::= <function name> <bare-function-type>
5119 // ::= <special-name>
5120 template <typename Derived
, typename Alloc
>
5121 Node
*AbstractManglingParser
<Derived
, Alloc
>::parseEncoding() {
5122 if (look() == 'G' || look() == 'T')
5123 return getDerived().parseSpecialName();
5125 auto IsEndOfEncoding
= [&] {
5126 // The set of chars that can potentially follow an <encoding> (none of which
5127 // can start a <type>). Enumerating these allows us to avoid speculative
5129 return numLeft() == 0 || look() == 'E' || look() == '.' || look() == '_';
5132 NameState
NameInfo(this);
5133 Node
*Name
= getDerived().parseName(&NameInfo
);
5134 if (Name
== nullptr)
5137 if (resolveForwardTemplateRefs(NameInfo
))
5140 if (IsEndOfEncoding())
5143 Node
*Attrs
= nullptr;
5144 if (consumeIf("Ua9enable_ifI")) {
5145 size_t BeforeArgs
= Names
.size();
5146 while (!consumeIf('E')) {
5147 Node
*Arg
= getDerived().parseTemplateArg();
5150 Names
.push_back(Arg
);
5152 Attrs
= make
<EnableIfAttr
>(popTrailingNodeArray(BeforeArgs
));
5157 Node
*ReturnType
= nullptr;
5158 if (!NameInfo
.CtorDtorConversion
&& NameInfo
.EndsWithTemplateArgs
) {
5159 ReturnType
= getDerived().parseType();
5160 if (ReturnType
== nullptr)
5165 return make
<FunctionEncoding
>(ReturnType
, Name
, NodeArray(),
5166 Attrs
, NameInfo
.CVQualifiers
,
5167 NameInfo
.ReferenceQualifier
);
5169 size_t ParamsBegin
= Names
.size();
5171 Node
*Ty
= getDerived().parseType();
5174 Names
.push_back(Ty
);
5175 } while (!IsEndOfEncoding());
5177 return make
<FunctionEncoding
>(ReturnType
, Name
,
5178 popTrailingNodeArray(ParamsBegin
),
5179 Attrs
, NameInfo
.CVQualifiers
,
5180 NameInfo
.ReferenceQualifier
);
5183 template <class Float
>
5187 struct FloatData
<float>
5189 static const size_t mangled_size
= 8;
5190 static const size_t max_demangled_size
= 24;
5191 static constexpr const char* spec
= "%af";
5195 struct FloatData
<double>
5197 static const size_t mangled_size
= 16;
5198 static const size_t max_demangled_size
= 32;
5199 static constexpr const char* spec
= "%a";
5203 struct FloatData
<long double>
5205 #if defined(__mips__) && defined(__mips_n64) || defined(__aarch64__) || \
5207 static const size_t mangled_size
= 32;
5208 #elif defined(__arm__) || defined(__mips__) || defined(__hexagon__)
5209 static const size_t mangled_size
= 16;
5211 static const size_t mangled_size
= 20; // May need to be adjusted to 16 or 24 on other platforms
5213 static const size_t max_demangled_size
= 40;
5214 static constexpr const char *spec
= "%LaL";
5217 template <typename Alloc
, typename Derived
>
5218 template <class Float
>
5219 Node
*AbstractManglingParser
<Alloc
, Derived
>::parseFloatingLiteral() {
5220 const size_t N
= FloatData
<Float
>::mangled_size
;
5223 StringView
Data(First
, First
+ N
);
5225 if (!std::isxdigit(C
))
5228 if (!consumeIf('E'))
5230 return make
<FloatLiteralImpl
<Float
>>(Data
);
5233 // <seq-id> ::= <0-9A-Z>+
5234 template <typename Alloc
, typename Derived
>
5235 bool AbstractManglingParser
<Alloc
, Derived
>::parseSeqId(size_t *Out
) {
5236 if (!(look() >= '0' && look() <= '9') &&
5237 !(look() >= 'A' && look() <= 'Z'))
5242 if (look() >= '0' && look() <= '9') {
5244 Id
+= static_cast<size_t>(look() - '0');
5245 } else if (look() >= 'A' && look() <= 'Z') {
5247 Id
+= static_cast<size_t>(look() - 'A') + 10;
5256 // <substitution> ::= S <seq-id> _
5258 // <substitution> ::= Sa # ::std::allocator
5259 // <substitution> ::= Sb # ::std::basic_string
5260 // <substitution> ::= Ss # ::std::basic_string < char,
5261 // ::std::char_traits<char>,
5262 // ::std::allocator<char> >
5263 // <substitution> ::= Si # ::std::basic_istream<char, std::char_traits<char> >
5264 // <substitution> ::= So # ::std::basic_ostream<char, std::char_traits<char> >
5265 // <substitution> ::= Sd # ::std::basic_iostream<char, std::char_traits<char> >
5266 template <typename Derived
, typename Alloc
>
5267 Node
*AbstractManglingParser
<Derived
, Alloc
>::parseSubstitution() {
5268 if (!consumeIf('S'))
5271 if (std::islower(look())) {
5276 SpecialSub
= make
<SpecialSubstitution
>(SpecialSubKind::allocator
);
5280 SpecialSub
= make
<SpecialSubstitution
>(SpecialSubKind::basic_string
);
5284 SpecialSub
= make
<SpecialSubstitution
>(SpecialSubKind::string
);
5288 SpecialSub
= make
<SpecialSubstitution
>(SpecialSubKind::istream
);
5292 SpecialSub
= make
<SpecialSubstitution
>(SpecialSubKind::ostream
);
5296 SpecialSub
= make
<SpecialSubstitution
>(SpecialSubKind::iostream
);
5303 // Itanium C++ ABI 5.1.2: If a name that would use a built-in <substitution>
5304 // has ABI tags, the tags are appended to the substitution; the result is a
5305 // substitutable component.
5306 Node
*WithTags
= getDerived().parseAbiTags(SpecialSub
);
5307 if (WithTags
!= SpecialSub
) {
5308 Subs
.push_back(WithTags
);
5309 SpecialSub
= WithTags
;
5315 if (consumeIf('_')) {
5323 if (parseSeqId(&Index
))
5326 if (!consumeIf('_') || Index
>= Subs
.size())
5331 // <template-param> ::= T_ # first template parameter
5332 // ::= T <parameter-2 non-negative number> _
5333 // ::= TL <level-1> __
5334 // ::= TL <level-1> _ <parameter-2 non-negative number> _
5335 template <typename Derived
, typename Alloc
>
5336 Node
*AbstractManglingParser
<Derived
, Alloc
>::parseTemplateParam() {
5337 if (!consumeIf('T'))
5341 if (consumeIf('L')) {
5342 if (parsePositiveInteger(&Level
))
5345 if (!consumeIf('_'))
5350 if (!consumeIf('_')) {
5351 if (parsePositiveInteger(&Index
))
5354 if (!consumeIf('_'))
5358 // If we're in a context where this <template-param> refers to a
5359 // <template-arg> further ahead in the mangled name (currently just conversion
5360 // operator types), then we should only look it up in the right context.
5361 // This can only happen at the outermost level.
5362 if (PermitForwardTemplateReferences
&& Level
== 0) {
5363 Node
*ForwardRef
= make
<ForwardTemplateReference
>(Index
);
5366 assert(ForwardRef
->getKind() == Node::KForwardTemplateReference
);
5367 ForwardTemplateRefs
.push_back(
5368 static_cast<ForwardTemplateReference
*>(ForwardRef
));
5372 if (Level
>= TemplateParams
.size() || !TemplateParams
[Level
] ||
5373 Index
>= TemplateParams
[Level
]->size()) {
5374 // Itanium ABI 5.1.8: In a generic lambda, uses of auto in the parameter
5375 // list are mangled as the corresponding artificial template type parameter.
5376 if (ParsingLambdaParamsAtLevel
== Level
&& Level
<= TemplateParams
.size()) {
5377 // This will be popped by the ScopedTemplateParamList in
5378 // parseUnnamedTypeName.
5379 if (Level
== TemplateParams
.size())
5380 TemplateParams
.push_back(nullptr);
5381 return make
<NameType
>("auto");
5387 return (*TemplateParams
[Level
])[Index
];
5390 // <template-param-decl> ::= Ty # type parameter
5391 // ::= Tn <type> # non-type parameter
5392 // ::= Tt <template-param-decl>* E # template parameter
5393 // ::= Tp <template-param-decl> # parameter pack
5394 template <typename Derived
, typename Alloc
>
5395 Node
*AbstractManglingParser
<Derived
, Alloc
>::parseTemplateParamDecl() {
5396 auto InventTemplateParamName
= [&](TemplateParamKind Kind
) {
5397 unsigned Index
= NumSyntheticTemplateParameters
[(int)Kind
]++;
5398 Node
*N
= make
<SyntheticTemplateParamName
>(Kind
, Index
);
5399 if (N
) TemplateParams
.back()->push_back(N
);
5403 if (consumeIf("Ty")) {
5404 Node
*Name
= InventTemplateParamName(TemplateParamKind::Type
);
5407 return make
<TypeTemplateParamDecl
>(Name
);
5410 if (consumeIf("Tn")) {
5411 Node
*Name
= InventTemplateParamName(TemplateParamKind::NonType
);
5414 Node
*Type
= parseType();
5417 return make
<NonTypeTemplateParamDecl
>(Name
, Type
);
5420 if (consumeIf("Tt")) {
5421 Node
*Name
= InventTemplateParamName(TemplateParamKind::Template
);
5424 size_t ParamsBegin
= Names
.size();
5425 ScopedTemplateParamList
TemplateTemplateParamParams(this);
5426 while (!consumeIf("E")) {
5427 Node
*P
= parseTemplateParamDecl();
5432 NodeArray Params
= popTrailingNodeArray(ParamsBegin
);
5433 return make
<TemplateTemplateParamDecl
>(Name
, Params
);
5436 if (consumeIf("Tp")) {
5437 Node
*P
= parseTemplateParamDecl();
5440 return make
<TemplateParamPackDecl
>(P
);
5446 // <template-arg> ::= <type> # type or template
5447 // ::= X <expression> E # expression
5448 // ::= <expr-primary> # simple expressions
5449 // ::= J <template-arg>* E # argument pack
5450 // ::= LZ <encoding> E # extension
5451 template <typename Derived
, typename Alloc
>
5452 Node
*AbstractManglingParser
<Derived
, Alloc
>::parseTemplateArg() {
5456 Node
*Arg
= getDerived().parseExpr();
5457 if (Arg
== nullptr || !consumeIf('E'))
5463 size_t ArgsBegin
= Names
.size();
5464 while (!consumeIf('E')) {
5465 Node
*Arg
= getDerived().parseTemplateArg();
5468 Names
.push_back(Arg
);
5470 NodeArray Args
= popTrailingNodeArray(ArgsBegin
);
5471 return make
<TemplateArgumentPack
>(Args
);
5474 // ::= LZ <encoding> E # extension
5475 if (look(1) == 'Z') {
5477 Node
*Arg
= getDerived().parseEncoding();
5478 if (Arg
== nullptr || !consumeIf('E'))
5482 // ::= <expr-primary> # simple expressions
5483 return getDerived().parseExprPrimary();
5486 return getDerived().parseType();
5490 // <template-args> ::= I <template-arg>* E
5491 // extension, the abi says <template-arg>+
5492 template <typename Derived
, typename Alloc
>
5494 AbstractManglingParser
<Derived
, Alloc
>::parseTemplateArgs(bool TagTemplates
) {
5495 if (!consumeIf('I'))
5498 // <template-params> refer to the innermost <template-args>. Clear out any
5499 // outer args that we may have inserted into TemplateParams.
5501 TemplateParams
.clear();
5502 TemplateParams
.push_back(&OuterTemplateParams
);
5503 OuterTemplateParams
.clear();
5506 size_t ArgsBegin
= Names
.size();
5507 while (!consumeIf('E')) {
5509 auto OldParams
= std::move(TemplateParams
);
5510 Node
*Arg
= getDerived().parseTemplateArg();
5511 TemplateParams
= std::move(OldParams
);
5514 Names
.push_back(Arg
);
5515 Node
*TableEntry
= Arg
;
5516 if (Arg
->getKind() == Node::KTemplateArgumentPack
) {
5517 TableEntry
= make
<ParameterPack
>(
5518 static_cast<TemplateArgumentPack
*>(TableEntry
)->getElements());
5522 TemplateParams
.back()->push_back(TableEntry
);
5524 Node
*Arg
= getDerived().parseTemplateArg();
5527 Names
.push_back(Arg
);
5530 return make
<TemplateArgs
>(popTrailingNodeArray(ArgsBegin
));
5533 // <mangled-name> ::= _Z <encoding>
5535 // extension ::= ___Z <encoding> _block_invoke
5536 // extension ::= ___Z <encoding> _block_invoke<decimal-digit>+
5537 // extension ::= ___Z <encoding> _block_invoke_<decimal-digit>+
5538 template <typename Derived
, typename Alloc
>
5539 Node
*AbstractManglingParser
<Derived
, Alloc
>::parse() {
5540 if (consumeIf("_Z") || consumeIf("__Z")) {
5541 Node
*Encoding
= getDerived().parseEncoding();
5542 if (Encoding
== nullptr)
5544 if (look() == '.') {
5545 Encoding
= make
<DotSuffix
>(Encoding
, StringView(First
, Last
));
5553 if (consumeIf("___Z") || consumeIf("____Z")) {
5554 Node
*Encoding
= getDerived().parseEncoding();
5555 if (Encoding
== nullptr || !consumeIf("_block_invoke"))
5557 bool RequireNumber
= consumeIf('_');
5558 if (parseNumber().empty() && RequireNumber
)
5564 return make
<SpecialName
>("invocation function for block in ", Encoding
);
5567 Node
*Ty
= getDerived().parseType();
5573 template <typename Alloc
>
5574 struct ManglingParser
: AbstractManglingParser
<ManglingParser
<Alloc
>, Alloc
> {
5575 using AbstractManglingParser
<ManglingParser
<Alloc
>,
5576 Alloc
>::AbstractManglingParser
;
5579 DEMANGLE_NAMESPACE_END
5581 #endif // DEMANGLE_ITANIUMDEMANGLE_H