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) \
61 X(TemplateArgumentPack) \
62 X(ParameterPackExpansion) \
64 X(ForwardTemplateReference) \
65 X(NameWithTemplateArgs) \
66 X(GlobalQualifiedName) \
68 X(ExpandedSpecialSubstitution) \
69 X(SpecialSubstitution) \
74 X(StructuredBindingName) \
76 X(ArraySubscriptExpr) \
82 X(SizeofParamPackExpr) \
97 X(LongDoubleLiteral) \
101 DEMANGLE_NAMESPACE_BEGIN
103 // Base class of all AST nodes. The AST is built by the parser, then is
104 // traversed by the printLeft/Right functions to produce a demangled string.
107 enum Kind
: unsigned char {
108 #define ENUMERATOR(NodeKind) K ## NodeKind,
109 FOR_EACH_NODE_KIND(ENUMERATOR
)
113 /// Three-way bool to track a cached value. Unknown is possible if this node
114 /// has an unexpanded parameter pack below it that may affect this cache.
115 enum class Cache
: unsigned char { Yes
, No
, Unknown
, };
120 // FIXME: Make these protected.
122 /// Tracks if this node has a component on its right side, in which case we
123 /// need to call printRight.
124 Cache RHSComponentCache
;
126 /// Track if this node is a (possibly qualified) array type. This can affect
127 /// how we format the output string.
130 /// Track if this node is a (possibly qualified) function type. This can
131 /// affect how we format the output string.
135 Node(Kind K_
, Cache RHSComponentCache_
= Cache::No
,
136 Cache ArrayCache_
= Cache::No
, Cache FunctionCache_
= Cache::No
)
137 : K(K_
), RHSComponentCache(RHSComponentCache_
), ArrayCache(ArrayCache_
),
138 FunctionCache(FunctionCache_
) {}
140 /// Visit the most-derived object corresponding to this object.
141 template<typename Fn
> void visit(Fn F
) const;
143 // The following function is provided by all derived classes:
145 // Call F with arguments that, when passed to the constructor of this node,
146 // would construct an equivalent node.
147 //template<typename Fn> void match(Fn F) const;
149 bool hasRHSComponent(OutputStream
&S
) const {
150 if (RHSComponentCache
!= Cache::Unknown
)
151 return RHSComponentCache
== Cache::Yes
;
152 return hasRHSComponentSlow(S
);
155 bool hasArray(OutputStream
&S
) const {
156 if (ArrayCache
!= Cache::Unknown
)
157 return ArrayCache
== Cache::Yes
;
158 return hasArraySlow(S
);
161 bool hasFunction(OutputStream
&S
) const {
162 if (FunctionCache
!= Cache::Unknown
)
163 return FunctionCache
== Cache::Yes
;
164 return hasFunctionSlow(S
);
167 Kind
getKind() const { return K
; }
169 virtual bool hasRHSComponentSlow(OutputStream
&) const { return false; }
170 virtual bool hasArraySlow(OutputStream
&) const { return false; }
171 virtual bool hasFunctionSlow(OutputStream
&) const { return false; }
173 // Dig through "glue" nodes like ParameterPack and ForwardTemplateReference to
174 // get at a node that actually represents some concrete syntax.
175 virtual const Node
*getSyntaxNode(OutputStream
&) const {
179 void print(OutputStream
&S
) const {
181 if (RHSComponentCache
!= Cache::No
)
185 // Print the "left" side of this Node into OutputStream.
186 virtual void printLeft(OutputStream
&) const = 0;
188 // Print the "right". This distinction is necessary to represent C++ types
189 // that appear on the RHS of their subtype, such as arrays or functions.
190 // Since most types don't have such a component, provide a default
192 virtual void printRight(OutputStream
&) const {}
194 virtual StringView
getBaseName() const { return StringView(); }
196 // Silence compiler warnings, this dtor will never be called.
197 virtual ~Node() = default;
200 DEMANGLE_DUMP_METHOD
void dump() const;
209 NodeArray() : Elements(nullptr), NumElements(0) {}
210 NodeArray(Node
**Elements_
, size_t NumElements_
)
211 : Elements(Elements_
), NumElements(NumElements_
) {}
213 bool empty() const { return NumElements
== 0; }
214 size_t size() const { return NumElements
; }
216 Node
**begin() const { return Elements
; }
217 Node
**end() const { return Elements
+ NumElements
; }
219 Node
*operator[](size_t Idx
) const { return Elements
[Idx
]; }
221 void printWithComma(OutputStream
&S
) const {
222 bool FirstElement
= true;
223 for (size_t Idx
= 0; Idx
!= NumElements
; ++Idx
) {
224 size_t BeforeComma
= S
.getCurrentPosition();
227 size_t AfterComma
= S
.getCurrentPosition();
228 Elements
[Idx
]->print(S
);
230 // Elements[Idx] is an empty parameter pack expansion, we should erase the
231 // comma we just printed.
232 if (AfterComma
== S
.getCurrentPosition()) {
233 S
.setCurrentPosition(BeforeComma
);
237 FirstElement
= false;
242 struct NodeArrayNode
: Node
{
244 NodeArrayNode(NodeArray Array_
) : Node(KNodeArrayNode
), Array(Array_
) {}
246 template<typename Fn
> void match(Fn F
) const { F(Array
); }
248 void printLeft(OutputStream
&S
) const override
{
249 Array
.printWithComma(S
);
253 class DotSuffix final
: public Node
{
255 const StringView Suffix
;
258 DotSuffix(const Node
*Prefix_
, StringView Suffix_
)
259 : Node(KDotSuffix
), Prefix(Prefix_
), Suffix(Suffix_
) {}
261 template<typename Fn
> void match(Fn F
) const { F(Prefix
, Suffix
); }
263 void printLeft(OutputStream
&s
) const override
{
271 class VendorExtQualType final
: public Node
{
276 VendorExtQualType(const Node
*Ty_
, StringView Ext_
)
277 : Node(KVendorExtQualType
), Ty(Ty_
), Ext(Ext_
) {}
279 template<typename Fn
> void match(Fn F
) const { F(Ty
, Ext
); }
281 void printLeft(OutputStream
&S
) const override
{
288 enum FunctionRefQual
: unsigned char {
301 inline Qualifiers
operator|=(Qualifiers
&Q1
, Qualifiers Q2
) {
302 return Q1
= static_cast<Qualifiers
>(Q1
| Q2
);
305 class QualType
: public Node
{
307 const Qualifiers Quals
;
310 void printQuals(OutputStream
&S
) const {
311 if (Quals
& QualConst
)
313 if (Quals
& QualVolatile
)
315 if (Quals
& QualRestrict
)
320 QualType(const Node
*Child_
, Qualifiers Quals_
)
321 : Node(KQualType
, Child_
->RHSComponentCache
,
322 Child_
->ArrayCache
, Child_
->FunctionCache
),
323 Quals(Quals_
), Child(Child_
) {}
325 template<typename Fn
> void match(Fn F
) const { F(Child
, Quals
); }
327 bool hasRHSComponentSlow(OutputStream
&S
) const override
{
328 return Child
->hasRHSComponent(S
);
330 bool hasArraySlow(OutputStream
&S
) const override
{
331 return Child
->hasArray(S
);
333 bool hasFunctionSlow(OutputStream
&S
) const override
{
334 return Child
->hasFunction(S
);
337 void printLeft(OutputStream
&S
) const override
{
342 void printRight(OutputStream
&S
) const override
{ Child
->printRight(S
); }
345 class ConversionOperatorType final
: public Node
{
349 ConversionOperatorType(const Node
*Ty_
)
350 : Node(KConversionOperatorType
), Ty(Ty_
) {}
352 template<typename Fn
> void match(Fn F
) const { F(Ty
); }
354 void printLeft(OutputStream
&S
) const override
{
360 class PostfixQualifiedType final
: public Node
{
362 const StringView Postfix
;
365 PostfixQualifiedType(Node
*Ty_
, StringView Postfix_
)
366 : Node(KPostfixQualifiedType
), Ty(Ty_
), Postfix(Postfix_
) {}
368 template<typename Fn
> void match(Fn F
) const { F(Ty
, Postfix
); }
370 void printLeft(OutputStream
&s
) const override
{
376 class NameType final
: public Node
{
377 const StringView Name
;
380 NameType(StringView Name_
) : Node(KNameType
), Name(Name_
) {}
382 template<typename Fn
> void match(Fn F
) const { F(Name
); }
384 StringView
getName() const { return Name
; }
385 StringView
getBaseName() const override
{ return Name
; }
387 void printLeft(OutputStream
&s
) const override
{ s
+= Name
; }
390 class ElaboratedTypeSpefType
: public Node
{
394 ElaboratedTypeSpefType(StringView Kind_
, Node
*Child_
)
395 : Node(KElaboratedTypeSpefType
), Kind(Kind_
), Child(Child_
) {}
397 template<typename Fn
> void match(Fn F
) const { F(Kind
, Child
); }
399 void printLeft(OutputStream
&S
) const override
{
406 struct AbiTagAttr
: Node
{
410 AbiTagAttr(Node
* Base_
, StringView Tag_
)
411 : Node(KAbiTagAttr
, Base_
->RHSComponentCache
,
412 Base_
->ArrayCache
, Base_
->FunctionCache
),
413 Base(Base_
), Tag(Tag_
) {}
415 template<typename Fn
> void match(Fn F
) const { F(Base
, Tag
); }
417 void printLeft(OutputStream
&S
) const override
{
425 class EnableIfAttr
: public Node
{
426 NodeArray Conditions
;
428 EnableIfAttr(NodeArray Conditions_
)
429 : Node(KEnableIfAttr
), Conditions(Conditions_
) {}
431 template<typename Fn
> void match(Fn F
) const { F(Conditions
); }
433 void printLeft(OutputStream
&S
) const override
{
435 Conditions
.printWithComma(S
);
440 class ObjCProtoName
: public Node
{
444 friend class PointerType
;
447 ObjCProtoName(const Node
*Ty_
, StringView Protocol_
)
448 : Node(KObjCProtoName
), Ty(Ty_
), Protocol(Protocol_
) {}
450 template<typename Fn
> void match(Fn F
) const { F(Ty
, Protocol
); }
452 bool isObjCObject() const {
453 return Ty
->getKind() == KNameType
&&
454 static_cast<const NameType
*>(Ty
)->getName() == "objc_object";
457 void printLeft(OutputStream
&S
) const override
{
465 class PointerType final
: public Node
{
469 PointerType(const Node
*Pointee_
)
470 : Node(KPointerType
, Pointee_
->RHSComponentCache
),
473 template<typename Fn
> void match(Fn F
) const { F(Pointee
); }
475 bool hasRHSComponentSlow(OutputStream
&S
) const override
{
476 return Pointee
->hasRHSComponent(S
);
479 void printLeft(OutputStream
&s
) const override
{
480 // We rewrite objc_object<SomeProtocol>* into id<SomeProtocol>.
481 if (Pointee
->getKind() != KObjCProtoName
||
482 !static_cast<const ObjCProtoName
*>(Pointee
)->isObjCObject()) {
483 Pointee
->printLeft(s
);
484 if (Pointee
->hasArray(s
))
486 if (Pointee
->hasArray(s
) || Pointee
->hasFunction(s
))
490 const auto *objcProto
= static_cast<const ObjCProtoName
*>(Pointee
);
492 s
+= objcProto
->Protocol
;
497 void printRight(OutputStream
&s
) const override
{
498 if (Pointee
->getKind() != KObjCProtoName
||
499 !static_cast<const ObjCProtoName
*>(Pointee
)->isObjCObject()) {
500 if (Pointee
->hasArray(s
) || Pointee
->hasFunction(s
))
502 Pointee
->printRight(s
);
507 enum class ReferenceKind
{
512 // Represents either a LValue or an RValue reference type.
513 class ReferenceType
: public Node
{
517 mutable bool Printing
= false;
519 // Dig through any refs to refs, collapsing the ReferenceTypes as we go. The
520 // rule here is rvalue ref to rvalue ref collapses to a rvalue ref, and any
521 // other combination collapses to a lvalue ref.
522 std::pair
<ReferenceKind
, const Node
*> collapse(OutputStream
&S
) const {
523 auto SoFar
= std::make_pair(RK
, Pointee
);
525 const Node
*SN
= SoFar
.second
->getSyntaxNode(S
);
526 if (SN
->getKind() != KReferenceType
)
528 auto *RT
= static_cast<const ReferenceType
*>(SN
);
529 SoFar
.second
= RT
->Pointee
;
530 SoFar
.first
= std::min(SoFar
.first
, RT
->RK
);
536 ReferenceType(const Node
*Pointee_
, ReferenceKind RK_
)
537 : Node(KReferenceType
, Pointee_
->RHSComponentCache
),
538 Pointee(Pointee_
), RK(RK_
) {}
540 template<typename Fn
> void match(Fn F
) const { F(Pointee
, RK
); }
542 bool hasRHSComponentSlow(OutputStream
&S
) const override
{
543 return Pointee
->hasRHSComponent(S
);
546 void printLeft(OutputStream
&s
) const override
{
549 SwapAndRestore
<bool> SavePrinting(Printing
, true);
550 std::pair
<ReferenceKind
, const Node
*> Collapsed
= collapse(s
);
551 Collapsed
.second
->printLeft(s
);
552 if (Collapsed
.second
->hasArray(s
))
554 if (Collapsed
.second
->hasArray(s
) || Collapsed
.second
->hasFunction(s
))
557 s
+= (Collapsed
.first
== ReferenceKind::LValue
? "&" : "&&");
559 void printRight(OutputStream
&s
) const override
{
562 SwapAndRestore
<bool> SavePrinting(Printing
, true);
563 std::pair
<ReferenceKind
, const Node
*> Collapsed
= collapse(s
);
564 if (Collapsed
.second
->hasArray(s
) || Collapsed
.second
->hasFunction(s
))
566 Collapsed
.second
->printRight(s
);
570 class PointerToMemberType final
: public Node
{
571 const Node
*ClassType
;
572 const Node
*MemberType
;
575 PointerToMemberType(const Node
*ClassType_
, const Node
*MemberType_
)
576 : Node(KPointerToMemberType
, MemberType_
->RHSComponentCache
),
577 ClassType(ClassType_
), MemberType(MemberType_
) {}
579 template<typename Fn
> void match(Fn F
) const { F(ClassType
, MemberType
); }
581 bool hasRHSComponentSlow(OutputStream
&S
) const override
{
582 return MemberType
->hasRHSComponent(S
);
585 void printLeft(OutputStream
&s
) const override
{
586 MemberType
->printLeft(s
);
587 if (MemberType
->hasArray(s
) || MemberType
->hasFunction(s
))
595 void printRight(OutputStream
&s
) const override
{
596 if (MemberType
->hasArray(s
) || MemberType
->hasFunction(s
))
598 MemberType
->printRight(s
);
607 /* implicit */ NodeOrString(StringView Str
) {
608 const char *FirstChar
= Str
.begin();
609 const char *SecondChar
= Str
.end();
610 if (SecondChar
== nullptr) {
611 assert(FirstChar
== SecondChar
);
612 ++FirstChar
, ++SecondChar
;
614 First
= static_cast<const void *>(FirstChar
);
615 Second
= static_cast<const void *>(SecondChar
);
618 /* implicit */ NodeOrString(Node
*N
)
619 : First(static_cast<const void *>(N
)), Second(nullptr) {}
620 NodeOrString() : First(nullptr), Second(nullptr) {}
622 bool isString() const { return Second
&& First
; }
623 bool isNode() const { return First
&& !Second
; }
624 bool isEmpty() const { return !First
&& !Second
; }
626 StringView
asString() const {
628 return StringView(static_cast<const char *>(First
),
629 static_cast<const char *>(Second
));
632 const Node
*asNode() const {
634 return static_cast<const Node
*>(First
);
638 class ArrayType final
: public Node
{
640 NodeOrString Dimension
;
643 ArrayType(const Node
*Base_
, NodeOrString Dimension_
)
645 /*RHSComponentCache=*/Cache::Yes
,
646 /*ArrayCache=*/Cache::Yes
),
647 Base(Base_
), Dimension(Dimension_
) {}
649 template<typename Fn
> void match(Fn F
) const { F(Base
, Dimension
); }
651 bool hasRHSComponentSlow(OutputStream
&) const override
{ return true; }
652 bool hasArraySlow(OutputStream
&) const override
{ return true; }
654 void printLeft(OutputStream
&S
) const override
{ Base
->printLeft(S
); }
656 void printRight(OutputStream
&S
) const override
{
660 if (Dimension
.isString())
661 S
+= Dimension
.asString();
662 else if (Dimension
.isNode())
663 Dimension
.asNode()->print(S
);
669 class FunctionType final
: public Node
{
673 FunctionRefQual RefQual
;
674 const Node
*ExceptionSpec
;
677 FunctionType(const Node
*Ret_
, NodeArray Params_
, Qualifiers CVQuals_
,
678 FunctionRefQual RefQual_
, const Node
*ExceptionSpec_
)
679 : Node(KFunctionType
,
680 /*RHSComponentCache=*/Cache::Yes
, /*ArrayCache=*/Cache::No
,
681 /*FunctionCache=*/Cache::Yes
),
682 Ret(Ret_
), Params(Params_
), CVQuals(CVQuals_
), RefQual(RefQual_
),
683 ExceptionSpec(ExceptionSpec_
) {}
685 template<typename Fn
> void match(Fn F
) const {
686 F(Ret
, Params
, CVQuals
, RefQual
, ExceptionSpec
);
689 bool hasRHSComponentSlow(OutputStream
&) const override
{ return true; }
690 bool hasFunctionSlow(OutputStream
&) const override
{ return true; }
692 // Handle C++'s ... quirky decl grammar by using the left & right
693 // distinction. Consider:
694 // int (*f(float))(char) {}
695 // f is a function that takes a float and returns a pointer to a function
696 // that takes a char and returns an int. If we're trying to print f, start
697 // by printing out the return types's left, then print our parameters, then
698 // finally print right of the return type.
699 void printLeft(OutputStream
&S
) const override
{
704 void printRight(OutputStream
&S
) const override
{
706 Params
.printWithComma(S
);
710 if (CVQuals
& QualConst
)
712 if (CVQuals
& QualVolatile
)
714 if (CVQuals
& QualRestrict
)
717 if (RefQual
== FrefQualLValue
)
719 else if (RefQual
== FrefQualRValue
)
722 if (ExceptionSpec
!= nullptr) {
724 ExceptionSpec
->print(S
);
729 class NoexceptSpec
: public Node
{
732 NoexceptSpec(const Node
*E_
) : Node(KNoexceptSpec
), E(E_
) {}
734 template<typename Fn
> void match(Fn F
) const { F(E
); }
736 void printLeft(OutputStream
&S
) const override
{
743 class DynamicExceptionSpec
: public Node
{
746 DynamicExceptionSpec(NodeArray Types_
)
747 : Node(KDynamicExceptionSpec
), Types(Types_
) {}
749 template<typename Fn
> void match(Fn F
) const { F(Types
); }
751 void printLeft(OutputStream
&S
) const override
{
753 Types
.printWithComma(S
);
758 class FunctionEncoding final
: public Node
{
764 FunctionRefQual RefQual
;
767 FunctionEncoding(const Node
*Ret_
, const Node
*Name_
, NodeArray Params_
,
768 const Node
*Attrs_
, Qualifiers CVQuals_
,
769 FunctionRefQual RefQual_
)
770 : Node(KFunctionEncoding
,
771 /*RHSComponentCache=*/Cache::Yes
, /*ArrayCache=*/Cache::No
,
772 /*FunctionCache=*/Cache::Yes
),
773 Ret(Ret_
), Name(Name_
), Params(Params_
), Attrs(Attrs_
),
774 CVQuals(CVQuals_
), RefQual(RefQual_
) {}
776 template<typename Fn
> void match(Fn F
) const {
777 F(Ret
, Name
, Params
, Attrs
, CVQuals
, RefQual
);
780 Qualifiers
getCVQuals() const { return CVQuals
; }
781 FunctionRefQual
getRefQual() const { return RefQual
; }
782 NodeArray
getParams() const { return Params
; }
783 const Node
*getReturnType() const { return Ret
; }
785 bool hasRHSComponentSlow(OutputStream
&) const override
{ return true; }
786 bool hasFunctionSlow(OutputStream
&) const override
{ return true; }
788 const Node
*getName() const { return Name
; }
790 void printLeft(OutputStream
&S
) const override
{
793 if (!Ret
->hasRHSComponent(S
))
799 void printRight(OutputStream
&S
) const override
{
801 Params
.printWithComma(S
);
806 if (CVQuals
& QualConst
)
808 if (CVQuals
& QualVolatile
)
810 if (CVQuals
& QualRestrict
)
813 if (RefQual
== FrefQualLValue
)
815 else if (RefQual
== FrefQualRValue
)
818 if (Attrs
!= nullptr)
823 class LiteralOperator
: public Node
{
827 LiteralOperator(const Node
*OpName_
)
828 : Node(KLiteralOperator
), OpName(OpName_
) {}
830 template<typename Fn
> void match(Fn F
) const { F(OpName
); }
832 void printLeft(OutputStream
&S
) const override
{
833 S
+= "operator\"\" ";
838 class SpecialName final
: public Node
{
839 const StringView Special
;
843 SpecialName(StringView Special_
, const Node
*Child_
)
844 : Node(KSpecialName
), Special(Special_
), Child(Child_
) {}
846 template<typename Fn
> void match(Fn F
) const { F(Special
, Child
); }
848 void printLeft(OutputStream
&S
) const override
{
854 class CtorVtableSpecialName final
: public Node
{
855 const Node
*FirstType
;
856 const Node
*SecondType
;
859 CtorVtableSpecialName(const Node
*FirstType_
, const Node
*SecondType_
)
860 : Node(KCtorVtableSpecialName
),
861 FirstType(FirstType_
), SecondType(SecondType_
) {}
863 template<typename Fn
> void match(Fn F
) const { F(FirstType
, SecondType
); }
865 void printLeft(OutputStream
&S
) const override
{
866 S
+= "construction vtable for ";
869 SecondType
->print(S
);
873 struct NestedName
: Node
{
877 NestedName(Node
*Qual_
, Node
*Name_
)
878 : Node(KNestedName
), Qual(Qual_
), Name(Name_
) {}
880 template<typename Fn
> void match(Fn F
) const { F(Qual
, Name
); }
882 StringView
getBaseName() const override
{ return Name
->getBaseName(); }
884 void printLeft(OutputStream
&S
) const override
{
891 struct LocalName
: Node
{
895 LocalName(Node
*Encoding_
, Node
*Entity_
)
896 : Node(KLocalName
), Encoding(Encoding_
), Entity(Entity_
) {}
898 template<typename Fn
> void match(Fn F
) const { F(Encoding
, Entity
); }
900 void printLeft(OutputStream
&S
) const override
{
907 class QualifiedName final
: public Node
{
909 const Node
*Qualifier
;
913 QualifiedName(const Node
*Qualifier_
, const Node
*Name_
)
914 : Node(KQualifiedName
), Qualifier(Qualifier_
), Name(Name_
) {}
916 template<typename Fn
> void match(Fn F
) const { F(Qualifier
, Name
); }
918 StringView
getBaseName() const override
{ return Name
->getBaseName(); }
920 void printLeft(OutputStream
&S
) const override
{
927 class VectorType final
: public Node
{
928 const Node
*BaseType
;
929 const NodeOrString Dimension
;
932 VectorType(const Node
*BaseType_
, NodeOrString Dimension_
)
933 : Node(KVectorType
), BaseType(BaseType_
),
934 Dimension(Dimension_
) {}
936 template<typename Fn
> void match(Fn F
) const { F(BaseType
, Dimension
); }
938 void printLeft(OutputStream
&S
) const override
{
941 if (Dimension
.isNode())
942 Dimension
.asNode()->print(S
);
943 else if (Dimension
.isString())
944 S
+= Dimension
.asString();
949 class PixelVectorType final
: public Node
{
950 const NodeOrString Dimension
;
953 PixelVectorType(NodeOrString Dimension_
)
954 : Node(KPixelVectorType
), Dimension(Dimension_
) {}
956 template<typename Fn
> void match(Fn F
) const { F(Dimension
); }
958 void printLeft(OutputStream
&S
) const override
{
959 // FIXME: This should demangle as "vector pixel".
960 S
+= "pixel vector[";
961 S
+= Dimension
.asString();
966 /// An unexpanded parameter pack (either in the expression or type context). If
967 /// this AST is correct, this node will have a ParameterPackExpansion node above
970 /// This node is created when some <template-args> are found that apply to an
971 /// <encoding>, and is stored in the TemplateParams table. In order for this to
972 /// appear in the final AST, it has to referenced via a <template-param> (ie,
974 class ParameterPack final
: public Node
{
977 // Setup OutputStream for a pack expansion unless we're already expanding one.
978 void initializePackExpansion(OutputStream
&S
) const {
979 if (S
.CurrentPackMax
== std::numeric_limits
<unsigned>::max()) {
980 S
.CurrentPackMax
= static_cast<unsigned>(Data
.size());
981 S
.CurrentPackIndex
= 0;
986 ParameterPack(NodeArray Data_
) : Node(KParameterPack
), Data(Data_
) {
987 ArrayCache
= FunctionCache
= RHSComponentCache
= Cache::Unknown
;
988 if (std::all_of(Data
.begin(), Data
.end(), [](Node
* P
) {
989 return P
->ArrayCache
== Cache::No
;
991 ArrayCache
= Cache::No
;
992 if (std::all_of(Data
.begin(), Data
.end(), [](Node
* P
) {
993 return P
->FunctionCache
== Cache::No
;
995 FunctionCache
= Cache::No
;
996 if (std::all_of(Data
.begin(), Data
.end(), [](Node
* P
) {
997 return P
->RHSComponentCache
== Cache::No
;
999 RHSComponentCache
= Cache::No
;
1002 template<typename Fn
> void match(Fn F
) const { F(Data
); }
1004 bool hasRHSComponentSlow(OutputStream
&S
) const override
{
1005 initializePackExpansion(S
);
1006 size_t Idx
= S
.CurrentPackIndex
;
1007 return Idx
< Data
.size() && Data
[Idx
]->hasRHSComponent(S
);
1009 bool hasArraySlow(OutputStream
&S
) const override
{
1010 initializePackExpansion(S
);
1011 size_t Idx
= S
.CurrentPackIndex
;
1012 return Idx
< Data
.size() && Data
[Idx
]->hasArray(S
);
1014 bool hasFunctionSlow(OutputStream
&S
) const override
{
1015 initializePackExpansion(S
);
1016 size_t Idx
= S
.CurrentPackIndex
;
1017 return Idx
< Data
.size() && Data
[Idx
]->hasFunction(S
);
1019 const Node
*getSyntaxNode(OutputStream
&S
) const override
{
1020 initializePackExpansion(S
);
1021 size_t Idx
= S
.CurrentPackIndex
;
1022 return Idx
< Data
.size() ? Data
[Idx
]->getSyntaxNode(S
) : this;
1025 void printLeft(OutputStream
&S
) const override
{
1026 initializePackExpansion(S
);
1027 size_t Idx
= S
.CurrentPackIndex
;
1028 if (Idx
< Data
.size())
1029 Data
[Idx
]->printLeft(S
);
1031 void printRight(OutputStream
&S
) const override
{
1032 initializePackExpansion(S
);
1033 size_t Idx
= S
.CurrentPackIndex
;
1034 if (Idx
< Data
.size())
1035 Data
[Idx
]->printRight(S
);
1039 /// A variadic template argument. This node represents an occurrence of
1040 /// J<something>E in some <template-args>. It isn't itself unexpanded, unless
1041 /// one of it's Elements is. The parser inserts a ParameterPack into the
1042 /// TemplateParams table if the <template-args> this pack belongs to apply to an
1044 class TemplateArgumentPack final
: public Node
{
1047 TemplateArgumentPack(NodeArray Elements_
)
1048 : Node(KTemplateArgumentPack
), Elements(Elements_
) {}
1050 template<typename Fn
> void match(Fn F
) const { F(Elements
); }
1052 NodeArray
getElements() const { return Elements
; }
1054 void printLeft(OutputStream
&S
) const override
{
1055 Elements
.printWithComma(S
);
1059 /// A pack expansion. Below this node, there are some unexpanded ParameterPacks
1060 /// which each have Child->ParameterPackSize elements.
1061 class ParameterPackExpansion final
: public Node
{
1065 ParameterPackExpansion(const Node
*Child_
)
1066 : Node(KParameterPackExpansion
), Child(Child_
) {}
1068 template<typename Fn
> void match(Fn F
) const { F(Child
); }
1070 const Node
*getChild() const { return Child
; }
1072 void printLeft(OutputStream
&S
) const override
{
1073 constexpr unsigned Max
= std::numeric_limits
<unsigned>::max();
1074 SwapAndRestore
<unsigned> SavePackIdx(S
.CurrentPackIndex
, Max
);
1075 SwapAndRestore
<unsigned> SavePackMax(S
.CurrentPackMax
, Max
);
1076 size_t StreamPos
= S
.getCurrentPosition();
1078 // Print the first element in the pack. If Child contains a ParameterPack,
1079 // it will set up S.CurrentPackMax and print the first element.
1082 // No ParameterPack was found in Child. This can occur if we've found a pack
1083 // expansion on a <function-param>.
1084 if (S
.CurrentPackMax
== Max
) {
1089 // We found a ParameterPack, but it has no elements. Erase whatever we may
1091 if (S
.CurrentPackMax
== 0) {
1092 S
.setCurrentPosition(StreamPos
);
1096 // Else, iterate through the rest of the elements in the pack.
1097 for (unsigned I
= 1, E
= S
.CurrentPackMax
; I
< E
; ++I
) {
1099 S
.CurrentPackIndex
= I
;
1105 class TemplateArgs final
: public Node
{
1109 TemplateArgs(NodeArray Params_
) : Node(KTemplateArgs
), Params(Params_
) {}
1111 template<typename Fn
> void match(Fn F
) const { F(Params
); }
1113 NodeArray
getParams() { return Params
; }
1115 void printLeft(OutputStream
&S
) const override
{
1117 Params
.printWithComma(S
);
1118 if (S
.back() == '>')
1124 /// A forward-reference to a template argument that was not known at the point
1125 /// where the template parameter name was parsed in a mangling.
1127 /// This is created when demangling the name of a specialization of a
1128 /// conversion function template:
1132 /// template<typename T> operator T*();
1136 /// When demangling a specialization of the conversion function template, we
1137 /// encounter the name of the template (including the \c T) before we reach
1138 /// the template argument list, so we cannot substitute the parameter name
1139 /// for the corresponding argument while parsing. Instead, we create a
1140 /// \c ForwardTemplateReference node that is resolved after we parse the
1141 /// template arguments.
1142 struct ForwardTemplateReference
: Node
{
1144 Node
*Ref
= nullptr;
1146 // If we're currently printing this node. It is possible (though invalid) for
1147 // a forward template reference to refer to itself via a substitution. This
1148 // creates a cyclic AST, which will stack overflow printing. To fix this, bail
1149 // out if more than one print* function is active.
1150 mutable bool Printing
= false;
1152 ForwardTemplateReference(size_t Index_
)
1153 : Node(KForwardTemplateReference
, Cache::Unknown
, Cache::Unknown
,
1157 // We don't provide a matcher for these, because the value of the node is
1158 // not determined by its construction parameters, and it generally needs
1159 // special handling.
1160 template<typename Fn
> void match(Fn F
) const = delete;
1162 bool hasRHSComponentSlow(OutputStream
&S
) const override
{
1165 SwapAndRestore
<bool> SavePrinting(Printing
, true);
1166 return Ref
->hasRHSComponent(S
);
1168 bool hasArraySlow(OutputStream
&S
) const override
{
1171 SwapAndRestore
<bool> SavePrinting(Printing
, true);
1172 return Ref
->hasArray(S
);
1174 bool hasFunctionSlow(OutputStream
&S
) const override
{
1177 SwapAndRestore
<bool> SavePrinting(Printing
, true);
1178 return Ref
->hasFunction(S
);
1180 const Node
*getSyntaxNode(OutputStream
&S
) const override
{
1183 SwapAndRestore
<bool> SavePrinting(Printing
, true);
1184 return Ref
->getSyntaxNode(S
);
1187 void printLeft(OutputStream
&S
) const override
{
1190 SwapAndRestore
<bool> SavePrinting(Printing
, true);
1193 void printRight(OutputStream
&S
) const override
{
1196 SwapAndRestore
<bool> SavePrinting(Printing
, true);
1201 struct NameWithTemplateArgs
: Node
{
1202 // name<template_args>
1206 NameWithTemplateArgs(Node
*Name_
, Node
*TemplateArgs_
)
1207 : Node(KNameWithTemplateArgs
), Name(Name_
), TemplateArgs(TemplateArgs_
) {}
1209 template<typename Fn
> void match(Fn F
) const { F(Name
, TemplateArgs
); }
1211 StringView
getBaseName() const override
{ return Name
->getBaseName(); }
1213 void printLeft(OutputStream
&S
) const override
{
1215 TemplateArgs
->print(S
);
1219 class GlobalQualifiedName final
: public Node
{
1223 GlobalQualifiedName(Node
* Child_
)
1224 : Node(KGlobalQualifiedName
), Child(Child_
) {}
1226 template<typename Fn
> void match(Fn F
) const { F(Child
); }
1228 StringView
getBaseName() const override
{ return Child
->getBaseName(); }
1230 void printLeft(OutputStream
&S
) const override
{
1236 struct StdQualifiedName
: Node
{
1239 StdQualifiedName(Node
*Child_
) : Node(KStdQualifiedName
), Child(Child_
) {}
1241 template<typename Fn
> void match(Fn F
) const { F(Child
); }
1243 StringView
getBaseName() const override
{ return Child
->getBaseName(); }
1245 void printLeft(OutputStream
&S
) const override
{
1251 enum class SpecialSubKind
{
1260 class ExpandedSpecialSubstitution final
: public Node
{
1264 ExpandedSpecialSubstitution(SpecialSubKind SSK_
)
1265 : Node(KExpandedSpecialSubstitution
), SSK(SSK_
) {}
1267 template<typename Fn
> void match(Fn F
) const { F(SSK
); }
1269 StringView
getBaseName() const override
{
1271 case SpecialSubKind::allocator
:
1272 return StringView("allocator");
1273 case SpecialSubKind::basic_string
:
1274 return StringView("basic_string");
1275 case SpecialSubKind::string
:
1276 return StringView("basic_string");
1277 case SpecialSubKind::istream
:
1278 return StringView("basic_istream");
1279 case SpecialSubKind::ostream
:
1280 return StringView("basic_ostream");
1281 case SpecialSubKind::iostream
:
1282 return StringView("basic_iostream");
1284 DEMANGLE_UNREACHABLE
;
1287 void printLeft(OutputStream
&S
) const override
{
1289 case SpecialSubKind::allocator
:
1290 S
+= "std::allocator";
1292 case SpecialSubKind::basic_string
:
1293 S
+= "std::basic_string";
1295 case SpecialSubKind::string
:
1296 S
+= "std::basic_string<char, std::char_traits<char>, "
1297 "std::allocator<char> >";
1299 case SpecialSubKind::istream
:
1300 S
+= "std::basic_istream<char, std::char_traits<char> >";
1302 case SpecialSubKind::ostream
:
1303 S
+= "std::basic_ostream<char, std::char_traits<char> >";
1305 case SpecialSubKind::iostream
:
1306 S
+= "std::basic_iostream<char, std::char_traits<char> >";
1312 class SpecialSubstitution final
: public Node
{
1316 SpecialSubstitution(SpecialSubKind SSK_
)
1317 : Node(KSpecialSubstitution
), SSK(SSK_
) {}
1319 template<typename Fn
> void match(Fn F
) const { F(SSK
); }
1321 StringView
getBaseName() const override
{
1323 case SpecialSubKind::allocator
:
1324 return StringView("allocator");
1325 case SpecialSubKind::basic_string
:
1326 return StringView("basic_string");
1327 case SpecialSubKind::string
:
1328 return StringView("string");
1329 case SpecialSubKind::istream
:
1330 return StringView("istream");
1331 case SpecialSubKind::ostream
:
1332 return StringView("ostream");
1333 case SpecialSubKind::iostream
:
1334 return StringView("iostream");
1336 DEMANGLE_UNREACHABLE
;
1339 void printLeft(OutputStream
&S
) const override
{
1341 case SpecialSubKind::allocator
:
1342 S
+= "std::allocator";
1344 case SpecialSubKind::basic_string
:
1345 S
+= "std::basic_string";
1347 case SpecialSubKind::string
:
1350 case SpecialSubKind::istream
:
1351 S
+= "std::istream";
1353 case SpecialSubKind::ostream
:
1354 S
+= "std::ostream";
1356 case SpecialSubKind::iostream
:
1357 S
+= "std::iostream";
1363 class CtorDtorName final
: public Node
{
1364 const Node
*Basename
;
1369 CtorDtorName(const Node
*Basename_
, bool IsDtor_
, int Variant_
)
1370 : Node(KCtorDtorName
), Basename(Basename_
), IsDtor(IsDtor_
),
1371 Variant(Variant_
) {}
1373 template<typename Fn
> void match(Fn F
) const { F(Basename
, IsDtor
, Variant
); }
1375 void printLeft(OutputStream
&S
) const override
{
1378 S
+= Basename
->getBaseName();
1382 class DtorName
: public Node
{
1386 DtorName(const Node
*Base_
) : Node(KDtorName
), Base(Base_
) {}
1388 template<typename Fn
> void match(Fn F
) const { F(Base
); }
1390 void printLeft(OutputStream
&S
) const override
{
1396 class UnnamedTypeName
: public Node
{
1397 const StringView Count
;
1400 UnnamedTypeName(StringView Count_
) : Node(KUnnamedTypeName
), Count(Count_
) {}
1402 template<typename Fn
> void match(Fn F
) const { F(Count
); }
1404 void printLeft(OutputStream
&S
) const override
{
1411 class ClosureTypeName
: public Node
{
1416 ClosureTypeName(NodeArray Params_
, StringView Count_
)
1417 : Node(KClosureTypeName
), Params(Params_
), Count(Count_
) {}
1419 template<typename Fn
> void match(Fn F
) const { F(Params
, Count
); }
1421 void printLeft(OutputStream
&S
) const override
{
1425 Params
.printWithComma(S
);
1430 class StructuredBindingName
: public Node
{
1433 StructuredBindingName(NodeArray Bindings_
)
1434 : Node(KStructuredBindingName
), Bindings(Bindings_
) {}
1436 template<typename Fn
> void match(Fn F
) const { F(Bindings
); }
1438 void printLeft(OutputStream
&S
) const override
{
1440 Bindings
.printWithComma(S
);
1445 // -- Expression Nodes --
1447 class BinaryExpr
: public Node
{
1449 const StringView InfixOperator
;
1453 BinaryExpr(const Node
*LHS_
, StringView InfixOperator_
, const Node
*RHS_
)
1454 : Node(KBinaryExpr
), LHS(LHS_
), InfixOperator(InfixOperator_
), RHS(RHS_
) {
1457 template<typename Fn
> void match(Fn F
) const { F(LHS
, InfixOperator
, RHS
); }
1459 void printLeft(OutputStream
&S
) const override
{
1460 // might be a template argument expression, then we need to disambiguate
1462 if (InfixOperator
== ">")
1473 if (InfixOperator
== ">")
1478 class ArraySubscriptExpr
: public Node
{
1483 ArraySubscriptExpr(const Node
*Op1_
, const Node
*Op2_
)
1484 : Node(KArraySubscriptExpr
), Op1(Op1_
), Op2(Op2_
) {}
1486 template<typename Fn
> void match(Fn F
) const { F(Op1
, Op2
); }
1488 void printLeft(OutputStream
&S
) const override
{
1497 class PostfixExpr
: public Node
{
1499 const StringView Operator
;
1502 PostfixExpr(const Node
*Child_
, StringView Operator_
)
1503 : Node(KPostfixExpr
), Child(Child_
), Operator(Operator_
) {}
1505 template<typename Fn
> void match(Fn F
) const { F(Child
, Operator
); }
1507 void printLeft(OutputStream
&S
) const override
{
1515 class ConditionalExpr
: public Node
{
1521 ConditionalExpr(const Node
*Cond_
, const Node
*Then_
, const Node
*Else_
)
1522 : Node(KConditionalExpr
), Cond(Cond_
), Then(Then_
), Else(Else_
) {}
1524 template<typename Fn
> void match(Fn F
) const { F(Cond
, Then
, Else
); }
1526 void printLeft(OutputStream
&S
) const override
{
1537 class MemberExpr
: public Node
{
1539 const StringView Kind
;
1543 MemberExpr(const Node
*LHS_
, StringView Kind_
, const Node
*RHS_
)
1544 : Node(KMemberExpr
), LHS(LHS_
), Kind(Kind_
), RHS(RHS_
) {}
1546 template<typename Fn
> void match(Fn F
) const { F(LHS
, Kind
, RHS
); }
1548 void printLeft(OutputStream
&S
) const override
{
1555 class EnclosingExpr
: public Node
{
1556 const StringView Prefix
;
1558 const StringView Postfix
;
1561 EnclosingExpr(StringView Prefix_
, Node
*Infix_
, StringView Postfix_
)
1562 : Node(KEnclosingExpr
), Prefix(Prefix_
), Infix(Infix_
),
1563 Postfix(Postfix_
) {}
1565 template<typename Fn
> void match(Fn F
) const { F(Prefix
, Infix
, Postfix
); }
1567 void printLeft(OutputStream
&S
) const override
{
1574 class CastExpr
: public Node
{
1575 // cast_kind<to>(from)
1576 const StringView CastKind
;
1581 CastExpr(StringView CastKind_
, const Node
*To_
, const Node
*From_
)
1582 : Node(KCastExpr
), CastKind(CastKind_
), To(To_
), From(From_
) {}
1584 template<typename Fn
> void match(Fn F
) const { F(CastKind
, To
, From
); }
1586 void printLeft(OutputStream
&S
) const override
{
1596 class SizeofParamPackExpr
: public Node
{
1600 SizeofParamPackExpr(const Node
*Pack_
)
1601 : Node(KSizeofParamPackExpr
), Pack(Pack_
) {}
1603 template<typename Fn
> void match(Fn F
) const { F(Pack
); }
1605 void printLeft(OutputStream
&S
) const override
{
1607 ParameterPackExpansion
PPE(Pack
);
1613 class CallExpr
: public Node
{
1618 CallExpr(const Node
*Callee_
, NodeArray Args_
)
1619 : Node(KCallExpr
), Callee(Callee_
), Args(Args_
) {}
1621 template<typename Fn
> void match(Fn F
) const { F(Callee
, Args
); }
1623 void printLeft(OutputStream
&S
) const override
{
1626 Args
.printWithComma(S
);
1631 class NewExpr
: public Node
{
1632 // new (expr_list) type(init_list)
1636 bool IsGlobal
; // ::operator new ?
1637 bool IsArray
; // new[] ?
1639 NewExpr(NodeArray ExprList_
, Node
*Type_
, NodeArray InitList_
, bool IsGlobal_
,
1641 : Node(KNewExpr
), ExprList(ExprList_
), Type(Type_
), InitList(InitList_
),
1642 IsGlobal(IsGlobal_
), IsArray(IsArray_
) {}
1644 template<typename Fn
> void match(Fn F
) const {
1645 F(ExprList
, Type
, InitList
, IsGlobal
, IsArray
);
1648 void printLeft(OutputStream
&S
) const override
{
1655 if (!ExprList
.empty()) {
1657 ExprList
.printWithComma(S
);
1661 if (!InitList
.empty()) {
1663 InitList
.printWithComma(S
);
1670 class DeleteExpr
: public Node
{
1676 DeleteExpr(Node
*Op_
, bool IsGlobal_
, bool IsArray_
)
1677 : Node(KDeleteExpr
), Op(Op_
), IsGlobal(IsGlobal_
), IsArray(IsArray_
) {}
1679 template<typename Fn
> void match(Fn F
) const { F(Op
, IsGlobal
, IsArray
); }
1681 void printLeft(OutputStream
&S
) const override
{
1691 class PrefixExpr
: public Node
{
1696 PrefixExpr(StringView Prefix_
, Node
*Child_
)
1697 : Node(KPrefixExpr
), Prefix(Prefix_
), Child(Child_
) {}
1699 template<typename Fn
> void match(Fn F
) const { F(Prefix
, Child
); }
1701 void printLeft(OutputStream
&S
) const override
{
1709 class FunctionParam
: public Node
{
1713 FunctionParam(StringView Number_
) : Node(KFunctionParam
), Number(Number_
) {}
1715 template<typename Fn
> void match(Fn F
) const { F(Number
); }
1717 void printLeft(OutputStream
&S
) const override
{
1723 class ConversionExpr
: public Node
{
1725 NodeArray Expressions
;
1728 ConversionExpr(const Node
*Type_
, NodeArray Expressions_
)
1729 : Node(KConversionExpr
), Type(Type_
), Expressions(Expressions_
) {}
1731 template<typename Fn
> void match(Fn F
) const { F(Type
, Expressions
); }
1733 void printLeft(OutputStream
&S
) const override
{
1737 Expressions
.printWithComma(S
);
1742 class InitListExpr
: public Node
{
1746 InitListExpr(const Node
*Ty_
, NodeArray Inits_
)
1747 : Node(KInitListExpr
), Ty(Ty_
), Inits(Inits_
) {}
1749 template<typename Fn
> void match(Fn F
) const { F(Ty
, Inits
); }
1751 void printLeft(OutputStream
&S
) const override
{
1755 Inits
.printWithComma(S
);
1760 class BracedExpr
: public Node
{
1765 BracedExpr(const Node
*Elem_
, const Node
*Init_
, bool IsArray_
)
1766 : Node(KBracedExpr
), Elem(Elem_
), Init(Init_
), IsArray(IsArray_
) {}
1768 template<typename Fn
> void match(Fn F
) const { F(Elem
, Init
, IsArray
); }
1770 void printLeft(OutputStream
&S
) const override
{
1779 if (Init
->getKind() != KBracedExpr
&& Init
->getKind() != KBracedRangeExpr
)
1785 class BracedRangeExpr
: public Node
{
1790 BracedRangeExpr(const Node
*First_
, const Node
*Last_
, const Node
*Init_
)
1791 : Node(KBracedRangeExpr
), First(First_
), Last(Last_
), Init(Init_
) {}
1793 template<typename Fn
> void match(Fn F
) const { F(First
, Last
, Init
); }
1795 void printLeft(OutputStream
&S
) const override
{
1801 if (Init
->getKind() != KBracedExpr
&& Init
->getKind() != KBracedRangeExpr
)
1807 class FoldExpr
: public Node
{
1808 const Node
*Pack
, *Init
;
1809 StringView OperatorName
;
1813 FoldExpr(bool IsLeftFold_
, StringView OperatorName_
, const Node
*Pack_
,
1815 : Node(KFoldExpr
), Pack(Pack_
), Init(Init_
), OperatorName(OperatorName_
),
1816 IsLeftFold(IsLeftFold_
) {}
1818 template<typename Fn
> void match(Fn F
) const {
1819 F(IsLeftFold
, OperatorName
, Pack
, Init
);
1822 void printLeft(OutputStream
&S
) const override
{
1823 auto PrintPack
= [&] {
1825 ParameterPackExpansion(Pack
).print(S
);
1832 // init op ... op pack
1833 if (Init
!= nullptr) {
1844 } else { // !IsLeftFold
1850 // pack op ... op init
1851 if (Init
!= nullptr) {
1862 class ThrowExpr
: public Node
{
1866 ThrowExpr(const Node
*Op_
) : Node(KThrowExpr
), Op(Op_
) {}
1868 template<typename Fn
> void match(Fn F
) const { F(Op
); }
1870 void printLeft(OutputStream
&S
) const override
{
1876 class BoolExpr
: public Node
{
1880 BoolExpr(bool Value_
) : Node(KBoolExpr
), Value(Value_
) {}
1882 template<typename Fn
> void match(Fn F
) const { F(Value
); }
1884 void printLeft(OutputStream
&S
) const override
{
1885 S
+= Value
? StringView("true") : StringView("false");
1889 class IntegerCastExpr
: public Node
{
1895 IntegerCastExpr(const Node
*Ty_
, StringView Integer_
)
1896 : Node(KIntegerCastExpr
), Ty(Ty_
), Integer(Integer_
) {}
1898 template<typename Fn
> void match(Fn F
) const { F(Ty
, Integer
); }
1900 void printLeft(OutputStream
&S
) const override
{
1908 class IntegerLiteral
: public Node
{
1913 IntegerLiteral(StringView Type_
, StringView Value_
)
1914 : Node(KIntegerLiteral
), Type(Type_
), Value(Value_
) {}
1916 template<typename Fn
> void match(Fn F
) const { F(Type
, Value
); }
1918 void printLeft(OutputStream
&S
) const override
{
1919 if (Type
.size() > 3) {
1925 if (Value
[0] == 'n') {
1927 S
+= Value
.dropFront(1);
1931 if (Type
.size() <= 3)
1936 template <class Float
> struct FloatData
;
1938 namespace float_literal_impl
{
1939 constexpr Node::Kind
getFloatLiteralKind(float *) {
1940 return Node::KFloatLiteral
;
1942 constexpr Node::Kind
getFloatLiteralKind(double *) {
1943 return Node::KDoubleLiteral
;
1945 constexpr Node::Kind
getFloatLiteralKind(long double *) {
1946 return Node::KLongDoubleLiteral
;
1950 template <class Float
> class FloatLiteralImpl
: public Node
{
1951 const StringView Contents
;
1953 static constexpr Kind KindForClass
=
1954 float_literal_impl::getFloatLiteralKind((Float
*)nullptr);
1957 FloatLiteralImpl(StringView Contents_
)
1958 : Node(KindForClass
), Contents(Contents_
) {}
1960 template<typename Fn
> void match(Fn F
) const { F(Contents
); }
1962 void printLeft(OutputStream
&s
) const override
{
1963 const char *first
= Contents
.begin();
1964 const char *last
= Contents
.end() + 1;
1966 const size_t N
= FloatData
<Float
>::mangled_size
;
1967 if (static_cast<std::size_t>(last
- first
) > N
) {
1971 char buf
[sizeof(Float
)];
1973 const char *t
= first
;
1975 for (; t
!= last
; ++t
, ++e
) {
1976 unsigned d1
= isdigit(*t
) ? static_cast<unsigned>(*t
- '0')
1977 : static_cast<unsigned>(*t
- 'a' + 10);
1979 unsigned d0
= isdigit(*t
) ? static_cast<unsigned>(*t
- '0')
1980 : static_cast<unsigned>(*t
- 'a' + 10);
1981 *e
= static_cast<char>((d1
<< 4) + d0
);
1983 #if __BYTE_ORDER__ == __ORDER_LITTLE_ENDIAN__
1984 std::reverse(buf
, e
);
1986 char num
[FloatData
<Float
>::max_demangled_size
] = {0};
1987 int n
= snprintf(num
, sizeof(num
), FloatData
<Float
>::spec
, value
);
1988 s
+= StringView(num
, num
+ n
);
1993 using FloatLiteral
= FloatLiteralImpl
<float>;
1994 using DoubleLiteral
= FloatLiteralImpl
<double>;
1995 using LongDoubleLiteral
= FloatLiteralImpl
<long double>;
1997 /// Visit the node. Calls \c F(P), where \c P is the node cast to the
1998 /// appropriate derived class.
1999 template<typename Fn
>
2000 void Node::visit(Fn F
) const {
2002 #define CASE(X) case K ## X: return F(static_cast<const X*>(this));
2003 FOR_EACH_NODE_KIND(CASE
)
2006 assert(0 && "unknown mangling node kind");
2009 /// Determine the kind of a node from its type.
2010 template<typename NodeT
> struct NodeKind
;
2011 #define SPECIALIZATION(X) \
2012 template<> struct NodeKind<X> { \
2013 static constexpr Node::Kind Kind = Node::K##X; \
2014 static constexpr const char *name() { return #X; } \
2016 FOR_EACH_NODE_KIND(SPECIALIZATION
)
2017 #undef SPECIALIZATION
2019 #undef FOR_EACH_NODE_KIND
2021 template <class T
, size_t N
>
2022 class PODSmallVector
{
2023 static_assert(std::is_pod
<T
>::value
,
2024 "T is required to be a plain old data type");
2031 bool isInline() const { return First
== Inline
; }
2033 void clearInline() {
2039 void reserve(size_t NewCap
) {
2042 auto* Tmp
= static_cast<T
*>(std::malloc(NewCap
* sizeof(T
)));
2045 std::copy(First
, Last
, Tmp
);
2048 First
= static_cast<T
*>(std::realloc(First
, NewCap
* sizeof(T
)));
2049 if (First
== nullptr)
2053 Cap
= First
+ NewCap
;
2057 PODSmallVector() : First(Inline
), Last(First
), Cap(Inline
+ N
) {}
2059 PODSmallVector(const PODSmallVector
&) = delete;
2060 PODSmallVector
& operator=(const PODSmallVector
&) = delete;
2062 PODSmallVector(PODSmallVector
&& Other
) : PODSmallVector() {
2063 if (Other
.isInline()) {
2064 std::copy(Other
.begin(), Other
.end(), First
);
2065 Last
= First
+ Other
.size();
2070 First
= Other
.First
;
2073 Other
.clearInline();
2076 PODSmallVector
& operator=(PODSmallVector
&& Other
) {
2077 if (Other
.isInline()) {
2082 std::copy(Other
.begin(), Other
.end(), First
);
2083 Last
= First
+ Other
.size();
2089 First
= Other
.First
;
2092 Other
.clearInline();
2096 std::swap(First
, Other
.First
);
2097 std::swap(Last
, Other
.Last
);
2098 std::swap(Cap
, Other
.Cap
);
2103 void push_back(const T
& Elem
) {
2105 reserve(size() * 2);
2110 assert(Last
!= First
&& "Popping empty vector!");
2114 void dropBack(size_t Index
) {
2115 assert(Index
<= size() && "dropBack() can't expand!");
2116 Last
= First
+ Index
;
2119 T
* begin() { return First
; }
2120 T
* end() { return Last
; }
2122 bool empty() const { return First
== Last
; }
2123 size_t size() const { return static_cast<size_t>(Last
- First
); }
2125 assert(Last
!= First
&& "Calling back() on empty vector!");
2128 T
& operator[](size_t Index
) {
2129 assert(Index
< size() && "Invalid access!");
2130 return *(begin() + Index
);
2132 void clear() { Last
= First
; }
2140 template <typename Derived
, typename Alloc
> struct AbstractManglingParser
{
2144 // Name stack, this is used by the parser to hold temporary names that were
2145 // parsed. The parser collapses multiple names into new nodes to construct
2146 // the AST. Once the parser is finished, names.size() == 1.
2147 PODSmallVector
<Node
*, 32> Names
;
2149 // Substitution table. Itanium supports name substitutions as a means of
2150 // compression. The string "S42_" refers to the 44nd entry (base-36) in this
2152 PODSmallVector
<Node
*, 32> Subs
;
2154 // Template parameter table. Like the above, but referenced like "T42_".
2155 // This has a smaller size compared to Subs and Names because it can be
2156 // stored on the stack.
2157 PODSmallVector
<Node
*, 8> TemplateParams
;
2159 // Set of unresolved forward <template-param> references. These can occur in a
2160 // conversion operator's type, and are resolved in the enclosing <encoding>.
2161 PODSmallVector
<ForwardTemplateReference
*, 4> ForwardTemplateRefs
;
2163 bool TryToParseTemplateArgs
= true;
2164 bool PermitForwardTemplateReferences
= false;
2165 bool ParsingLambdaParams
= false;
2169 AbstractManglingParser(const char *First_
, const char *Last_
)
2170 : First(First_
), Last(Last_
) {}
2172 Derived
&getDerived() { return static_cast<Derived
&>(*this); }
2174 void reset(const char *First_
, const char *Last_
) {
2179 TemplateParams
.clear();
2180 ParsingLambdaParams
= false;
2181 TryToParseTemplateArgs
= true;
2182 PermitForwardTemplateReferences
= false;
2183 ASTAllocator
.reset();
2186 template <class T
, class... Args
> Node
*make(Args
&&... args
) {
2187 return ASTAllocator
.template makeNode
<T
>(std::forward
<Args
>(args
)...);
2190 template <class It
> NodeArray
makeNodeArray(It begin
, It end
) {
2191 size_t sz
= static_cast<size_t>(end
- begin
);
2192 void *mem
= ASTAllocator
.allocateNodeArray(sz
);
2193 Node
**data
= new (mem
) Node
*[sz
];
2194 std::copy(begin
, end
, data
);
2195 return NodeArray(data
, sz
);
2198 NodeArray
popTrailingNodeArray(size_t FromPosition
) {
2199 assert(FromPosition
<= Names
.size());
2201 makeNodeArray(Names
.begin() + (long)FromPosition
, Names
.end());
2202 Names
.dropBack(FromPosition
);
2206 bool consumeIf(StringView S
) {
2207 if (StringView(First
, Last
).startsWith(S
)) {
2214 bool consumeIf(char C
) {
2215 if (First
!= Last
&& *First
== C
) {
2222 char consume() { return First
!= Last
? *First
++ : '\0'; }
2224 char look(unsigned Lookahead
= 0) {
2225 if (static_cast<size_t>(Last
- First
) <= Lookahead
)
2227 return First
[Lookahead
];
2230 size_t numLeft() const { return static_cast<size_t>(Last
- First
); }
2232 StringView
parseNumber(bool AllowNegative
= false);
2233 Qualifiers
parseCVQualifiers();
2234 bool parsePositiveInteger(size_t *Out
);
2235 StringView
parseBareSourceName();
2237 bool parseSeqId(size_t *Out
);
2238 Node
*parseSubstitution();
2239 Node
*parseTemplateParam();
2240 Node
*parseTemplateArgs(bool TagTemplates
= false);
2241 Node
*parseTemplateArg();
2243 /// Parse the <expr> production.
2245 Node
*parsePrefixExpr(StringView Kind
);
2246 Node
*parseBinaryExpr(StringView Kind
);
2247 Node
*parseIntegerLiteral(StringView Lit
);
2248 Node
*parseExprPrimary();
2249 template <class Float
> Node
*parseFloatingLiteral();
2250 Node
*parseFunctionParam();
2251 Node
*parseNewExpr();
2252 Node
*parseConversionExpr();
2253 Node
*parseBracedExpr();
2254 Node
*parseFoldExpr();
2256 /// Parse the <type> production.
2258 Node
*parseFunctionType();
2259 Node
*parseVectorType();
2260 Node
*parseDecltype();
2261 Node
*parseArrayType();
2262 Node
*parsePointerToMemberType();
2263 Node
*parseClassEnumType();
2264 Node
*parseQualifiedType();
2266 Node
*parseEncoding();
2267 bool parseCallOffset();
2268 Node
*parseSpecialName();
2270 /// Holds some extra information about a <name> that is being parsed. This
2271 /// information is only pertinent if the <name> refers to an <encoding>.
2273 bool CtorDtorConversion
= false;
2274 bool EndsWithTemplateArgs
= false;
2275 Qualifiers CVQualifiers
= QualNone
;
2276 FunctionRefQual ReferenceQualifier
= FrefQualNone
;
2277 size_t ForwardTemplateRefsBegin
;
2279 NameState(AbstractManglingParser
*Enclosing
)
2280 : ForwardTemplateRefsBegin(Enclosing
->ForwardTemplateRefs
.size()) {}
2283 bool resolveForwardTemplateRefs(NameState
&State
) {
2284 size_t I
= State
.ForwardTemplateRefsBegin
;
2285 size_t E
= ForwardTemplateRefs
.size();
2286 for (; I
< E
; ++I
) {
2287 size_t Idx
= ForwardTemplateRefs
[I
]->Index
;
2288 if (Idx
>= TemplateParams
.size())
2290 ForwardTemplateRefs
[I
]->Ref
= TemplateParams
[Idx
];
2292 ForwardTemplateRefs
.dropBack(State
.ForwardTemplateRefsBegin
);
2296 /// Parse the <name> production>
2297 Node
*parseName(NameState
*State
= nullptr);
2298 Node
*parseLocalName(NameState
*State
);
2299 Node
*parseOperatorName(NameState
*State
);
2300 Node
*parseUnqualifiedName(NameState
*State
);
2301 Node
*parseUnnamedTypeName(NameState
*State
);
2302 Node
*parseSourceName(NameState
*State
);
2303 Node
*parseUnscopedName(NameState
*State
);
2304 Node
*parseNestedName(NameState
*State
);
2305 Node
*parseCtorDtorName(Node
*&SoFar
, NameState
*State
);
2307 Node
*parseAbiTags(Node
*N
);
2309 /// Parse the <unresolved-name> production.
2310 Node
*parseUnresolvedName();
2311 Node
*parseSimpleId();
2312 Node
*parseBaseUnresolvedName();
2313 Node
*parseUnresolvedType();
2314 Node
*parseDestructorName();
2316 /// Top-level entry point into the parser.
2320 const char* parse_discriminator(const char* first
, const char* last
);
2322 // <name> ::= <nested-name> // N
2323 // ::= <local-name> # See Scope Encoding below // Z
2324 // ::= <unscoped-template-name> <template-args>
2325 // ::= <unscoped-name>
2327 // <unscoped-template-name> ::= <unscoped-name>
2328 // ::= <substitution>
2329 template <typename Derived
, typename Alloc
>
2330 Node
*AbstractManglingParser
<Derived
, Alloc
>::parseName(NameState
*State
) {
2331 consumeIf('L'); // extension
2334 return getDerived().parseNestedName(State
);
2336 return getDerived().parseLocalName(State
);
2338 // ::= <unscoped-template-name> <template-args>
2339 if (look() == 'S' && look(1) != 't') {
2340 Node
*S
= getDerived().parseSubstitution();
2345 Node
*TA
= getDerived().parseTemplateArgs(State
!= nullptr);
2348 if (State
) State
->EndsWithTemplateArgs
= true;
2349 return make
<NameWithTemplateArgs
>(S
, TA
);
2352 Node
*N
= getDerived().parseUnscopedName(State
);
2355 // ::= <unscoped-template-name> <template-args>
2356 if (look() == 'I') {
2358 Node
*TA
= getDerived().parseTemplateArgs(State
!= nullptr);
2361 if (State
) State
->EndsWithTemplateArgs
= true;
2362 return make
<NameWithTemplateArgs
>(N
, TA
);
2364 // ::= <unscoped-name>
2368 // <local-name> := Z <function encoding> E <entity name> [<discriminator>]
2369 // := Z <function encoding> E s [<discriminator>]
2370 // := Z <function encoding> Ed [ <parameter number> ] _ <entity name>
2371 template <typename Derived
, typename Alloc
>
2372 Node
*AbstractManglingParser
<Derived
, Alloc
>::parseLocalName(NameState
*State
) {
2373 if (!consumeIf('Z'))
2375 Node
*Encoding
= getDerived().parseEncoding();
2376 if (Encoding
== nullptr || !consumeIf('E'))
2379 if (consumeIf('s')) {
2380 First
= parse_discriminator(First
, Last
);
2381 auto *StringLitName
= make
<NameType
>("string literal");
2384 return make
<LocalName
>(Encoding
, StringLitName
);
2387 if (consumeIf('d')) {
2389 if (!consumeIf('_'))
2391 Node
*N
= getDerived().parseName(State
);
2394 return make
<LocalName
>(Encoding
, N
);
2397 Node
*Entity
= getDerived().parseName(State
);
2398 if (Entity
== nullptr)
2400 First
= parse_discriminator(First
, Last
);
2401 return make
<LocalName
>(Encoding
, Entity
);
2404 // <unscoped-name> ::= <unqualified-name>
2405 // ::= St <unqualified-name> # ::std::
2406 // extension ::= StL<unqualified-name>
2407 template <typename Derived
, typename Alloc
>
2409 AbstractManglingParser
<Derived
, Alloc
>::parseUnscopedName(NameState
*State
) {
2410 if (consumeIf("StL") || consumeIf("St")) {
2411 Node
*R
= getDerived().parseUnqualifiedName(State
);
2414 return make
<StdQualifiedName
>(R
);
2416 return getDerived().parseUnqualifiedName(State
);
2419 // <unqualified-name> ::= <operator-name> [abi-tags]
2420 // ::= <ctor-dtor-name>
2421 // ::= <source-name>
2422 // ::= <unnamed-type-name>
2423 // ::= DC <source-name>+ E # structured binding declaration
2424 template <typename Derived
, typename Alloc
>
2426 AbstractManglingParser
<Derived
, Alloc
>::parseUnqualifiedName(NameState
*State
) {
2427 // <ctor-dtor-name>s are special-cased in parseNestedName().
2430 Result
= getDerived().parseUnnamedTypeName(State
);
2431 else if (look() >= '1' && look() <= '9')
2432 Result
= getDerived().parseSourceName(State
);
2433 else if (consumeIf("DC")) {
2434 size_t BindingsBegin
= Names
.size();
2436 Node
*Binding
= getDerived().parseSourceName(State
);
2437 if (Binding
== nullptr)
2439 Names
.push_back(Binding
);
2440 } while (!consumeIf('E'));
2441 Result
= make
<StructuredBindingName
>(popTrailingNodeArray(BindingsBegin
));
2443 Result
= getDerived().parseOperatorName(State
);
2444 if (Result
!= nullptr)
2445 Result
= getDerived().parseAbiTags(Result
);
2449 // <unnamed-type-name> ::= Ut [<nonnegative number>] _
2450 // ::= <closure-type-name>
2452 // <closure-type-name> ::= Ul <lambda-sig> E [ <nonnegative number> ] _
2454 // <lambda-sig> ::= <parameter type>+ # Parameter types or "v" if the lambda has no parameters
2455 template <typename Derived
, typename Alloc
>
2457 AbstractManglingParser
<Derived
, Alloc
>::parseUnnamedTypeName(NameState
*) {
2458 if (consumeIf("Ut")) {
2459 StringView Count
= parseNumber();
2460 if (!consumeIf('_'))
2462 return make
<UnnamedTypeName
>(Count
);
2464 if (consumeIf("Ul")) {
2466 SwapAndRestore
<bool> SwapParams(ParsingLambdaParams
, true);
2467 if (!consumeIf("vE")) {
2468 size_t ParamsBegin
= Names
.size();
2470 Node
*P
= getDerived().parseType();
2474 } while (!consumeIf('E'));
2475 Params
= popTrailingNodeArray(ParamsBegin
);
2477 StringView Count
= parseNumber();
2478 if (!consumeIf('_'))
2480 return make
<ClosureTypeName
>(Params
, Count
);
2482 if (consumeIf("Ub")) {
2483 (void)parseNumber();
2484 if (!consumeIf('_'))
2486 return make
<NameType
>("'block-literal'");
2491 // <source-name> ::= <positive length number> <identifier>
2492 template <typename Derived
, typename Alloc
>
2493 Node
*AbstractManglingParser
<Derived
, Alloc
>::parseSourceName(NameState
*) {
2495 if (parsePositiveInteger(&Length
))
2497 if (numLeft() < Length
|| Length
== 0)
2499 StringView
Name(First
, First
+ Length
);
2501 if (Name
.startsWith("_GLOBAL__N"))
2502 return make
<NameType
>("(anonymous namespace)");
2503 return make
<NameType
>(Name
);
2506 // <operator-name> ::= aa # &&
2507 // ::= ad # & (unary)
2514 // ::= cv <type> # (cast)
2515 // ::= da # delete[]
2516 // ::= de # * (unary)
2527 // ::= li <source-name> # operator ""
2535 // ::= mm # -- (postfix in <expression> context)
2538 // ::= ng # - (unary)
2547 // ::= pp # ++ (postfix in <expression> context)
2548 // ::= ps # + (unary)
2555 // ::= ss # <=> C++2a
2556 // ::= v <digit> <source-name> # vendor extended operator
2557 template <typename Derived
, typename Alloc
>
2559 AbstractManglingParser
<Derived
, Alloc
>::parseOperatorName(NameState
*State
) {
2565 return make
<NameType
>("operator&&");
2569 return make
<NameType
>("operator&");
2572 return make
<NameType
>("operator&=");
2575 return make
<NameType
>("operator=");
2582 return make
<NameType
>("operator()");
2585 return make
<NameType
>("operator,");
2588 return make
<NameType
>("operator~");
2589 // ::= cv <type> # (cast)
2592 SwapAndRestore
<bool> SaveTemplate(TryToParseTemplateArgs
, false);
2593 // If we're parsing an encoding, State != nullptr and the conversion
2594 // operators' <type> could have a <template-param> that refers to some
2595 // <template-arg>s further ahead in the mangled name.
2596 SwapAndRestore
<bool> SavePermit(PermitForwardTemplateReferences
,
2597 PermitForwardTemplateReferences
||
2599 Node
*Ty
= getDerived().parseType();
2602 if (State
) State
->CtorDtorConversion
= true;
2603 return make
<ConversionOperatorType
>(Ty
);
2611 return make
<NameType
>("operator delete[]");
2614 return make
<NameType
>("operator*");
2617 return make
<NameType
>("operator delete");
2620 return make
<NameType
>("operator/");
2623 return make
<NameType
>("operator/=");
2630 return make
<NameType
>("operator^");
2633 return make
<NameType
>("operator^=");
2636 return make
<NameType
>("operator==");
2643 return make
<NameType
>("operator>=");
2646 return make
<NameType
>("operator>");
2650 if (look(1) == 'x') {
2652 return make
<NameType
>("operator[]");
2659 return make
<NameType
>("operator<=");
2660 // ::= li <source-name> # operator ""
2663 Node
*SN
= getDerived().parseSourceName(State
);
2666 return make
<LiteralOperator
>(SN
);
2670 return make
<NameType
>("operator<<");
2673 return make
<NameType
>("operator<<=");
2676 return make
<NameType
>("operator<");
2683 return make
<NameType
>("operator-");
2686 return make
<NameType
>("operator-=");
2689 return make
<NameType
>("operator*");
2692 return make
<NameType
>("operator*=");
2695 return make
<NameType
>("operator--");
2702 return make
<NameType
>("operator new[]");
2705 return make
<NameType
>("operator!=");
2708 return make
<NameType
>("operator-");
2711 return make
<NameType
>("operator!");
2714 return make
<NameType
>("operator new");
2721 return make
<NameType
>("operator||");
2724 return make
<NameType
>("operator|");
2727 return make
<NameType
>("operator|=");
2734 return make
<NameType
>("operator->*");
2737 return make
<NameType
>("operator+");
2740 return make
<NameType
>("operator+=");
2743 return make
<NameType
>("operator++");
2746 return make
<NameType
>("operator+");
2749 return make
<NameType
>("operator->");
2753 if (look(1) == 'u') {
2755 return make
<NameType
>("operator?");
2762 return make
<NameType
>("operator%");
2765 return make
<NameType
>("operator%=");
2768 return make
<NameType
>("operator>>");
2771 return make
<NameType
>("operator>>=");
2775 if (look(1) == 's') {
2777 return make
<NameType
>("operator<=>");
2780 // ::= v <digit> <source-name> # vendor extended operator
2782 if (std::isdigit(look(1))) {
2784 Node
*SN
= getDerived().parseSourceName(State
);
2787 return make
<ConversionOperatorType
>(SN
);
2794 // <ctor-dtor-name> ::= C1 # complete object constructor
2795 // ::= C2 # base object constructor
2796 // ::= C3 # complete object allocating constructor
2797 // extension ::= C5 # ?
2798 // ::= D0 # deleting destructor
2799 // ::= D1 # complete object destructor
2800 // ::= D2 # base object destructor
2801 // extension ::= D5 # ?
2802 template <typename Derived
, typename Alloc
>
2804 AbstractManglingParser
<Derived
, Alloc
>::parseCtorDtorName(Node
*&SoFar
,
2806 if (SoFar
->getKind() == Node::KSpecialSubstitution
) {
2807 auto SSK
= static_cast<SpecialSubstitution
*>(SoFar
)->SSK
;
2809 case SpecialSubKind::string
:
2810 case SpecialSubKind::istream
:
2811 case SpecialSubKind::ostream
:
2812 case SpecialSubKind::iostream
:
2813 SoFar
= make
<ExpandedSpecialSubstitution
>(SSK
);
2822 if (consumeIf('C')) {
2823 bool IsInherited
= consumeIf('I');
2824 if (look() != '1' && look() != '2' && look() != '3' && look() != '5')
2826 int Variant
= look() - '0';
2828 if (State
) State
->CtorDtorConversion
= true;
2830 if (getDerived().parseName(State
) == nullptr)
2833 return make
<CtorDtorName
>(SoFar
, false, Variant
);
2836 if (look() == 'D' &&
2837 (look(1) == '0' || look(1) == '1' || look(1) == '2' || look(1) == '5')) {
2838 int Variant
= look(1) - '0';
2840 if (State
) State
->CtorDtorConversion
= true;
2841 return make
<CtorDtorName
>(SoFar
, true, Variant
);
2847 // <nested-name> ::= N [<CV-Qualifiers>] [<ref-qualifier>] <prefix> <unqualified-name> E
2848 // ::= N [<CV-Qualifiers>] [<ref-qualifier>] <template-prefix> <template-args> E
2850 // <prefix> ::= <prefix> <unqualified-name>
2851 // ::= <template-prefix> <template-args>
2852 // ::= <template-param>
2855 // ::= <substitution>
2856 // ::= <prefix> <data-member-prefix>
2859 // <data-member-prefix> := <member source-name> [<template-args>] M
2861 // <template-prefix> ::= <prefix> <template unqualified-name>
2862 // ::= <template-param>
2863 // ::= <substitution>
2864 template <typename Derived
, typename Alloc
>
2866 AbstractManglingParser
<Derived
, Alloc
>::parseNestedName(NameState
*State
) {
2867 if (!consumeIf('N'))
2870 Qualifiers CVTmp
= parseCVQualifiers();
2871 if (State
) State
->CVQualifiers
= CVTmp
;
2873 if (consumeIf('O')) {
2874 if (State
) State
->ReferenceQualifier
= FrefQualRValue
;
2875 } else if (consumeIf('R')) {
2876 if (State
) State
->ReferenceQualifier
= FrefQualLValue
;
2878 if (State
) State
->ReferenceQualifier
= FrefQualNone
;
2880 Node
*SoFar
= nullptr;
2881 auto PushComponent
= [&](Node
*Comp
) {
2882 if (!Comp
) return false;
2883 if (SoFar
) SoFar
= make
<NestedName
>(SoFar
, Comp
);
2885 if (State
) State
->EndsWithTemplateArgs
= false;
2886 return SoFar
!= nullptr;
2889 if (consumeIf("St")) {
2890 SoFar
= make
<NameType
>("std");
2895 while (!consumeIf('E')) {
2896 consumeIf('L'); // extension
2898 // <data-member-prefix> := <member source-name> [<template-args>] M
2899 if (consumeIf('M')) {
2900 if (SoFar
== nullptr)
2905 // ::= <template-param>
2906 if (look() == 'T') {
2907 if (!PushComponent(getDerived().parseTemplateParam()))
2909 Subs
.push_back(SoFar
);
2913 // ::= <template-prefix> <template-args>
2914 if (look() == 'I') {
2915 Node
*TA
= getDerived().parseTemplateArgs(State
!= nullptr);
2916 if (TA
== nullptr || SoFar
== nullptr)
2918 SoFar
= make
<NameWithTemplateArgs
>(SoFar
, TA
);
2921 if (State
) State
->EndsWithTemplateArgs
= true;
2922 Subs
.push_back(SoFar
);
2927 if (look() == 'D' && (look(1) == 't' || look(1) == 'T')) {
2928 if (!PushComponent(getDerived().parseDecltype()))
2930 Subs
.push_back(SoFar
);
2934 // ::= <substitution>
2935 if (look() == 'S' && look(1) != 't') {
2936 Node
*S
= getDerived().parseSubstitution();
2937 if (!PushComponent(S
))
2944 // Parse an <unqualified-name> thats actually a <ctor-dtor-name>.
2945 if (look() == 'C' || (look() == 'D' && look(1) != 'C')) {
2946 if (SoFar
== nullptr)
2948 if (!PushComponent(getDerived().parseCtorDtorName(SoFar
, State
)))
2950 SoFar
= getDerived().parseAbiTags(SoFar
);
2951 if (SoFar
== nullptr)
2953 Subs
.push_back(SoFar
);
2957 // ::= <prefix> <unqualified-name>
2958 if (!PushComponent(getDerived().parseUnqualifiedName(State
)))
2960 Subs
.push_back(SoFar
);
2963 if (SoFar
== nullptr || Subs
.empty())
2970 // <simple-id> ::= <source-name> [ <template-args> ]
2971 template <typename Derived
, typename Alloc
>
2972 Node
*AbstractManglingParser
<Derived
, Alloc
>::parseSimpleId() {
2973 Node
*SN
= getDerived().parseSourceName(/*NameState=*/nullptr);
2976 if (look() == 'I') {
2977 Node
*TA
= getDerived().parseTemplateArgs();
2980 return make
<NameWithTemplateArgs
>(SN
, TA
);
2985 // <destructor-name> ::= <unresolved-type> # e.g., ~T or ~decltype(f())
2986 // ::= <simple-id> # e.g., ~A<2*N>
2987 template <typename Derived
, typename Alloc
>
2988 Node
*AbstractManglingParser
<Derived
, Alloc
>::parseDestructorName() {
2990 if (std::isdigit(look()))
2991 Result
= getDerived().parseSimpleId();
2993 Result
= getDerived().parseUnresolvedType();
2994 if (Result
== nullptr)
2996 return make
<DtorName
>(Result
);
2999 // <unresolved-type> ::= <template-param>
3001 // ::= <substitution>
3002 template <typename Derived
, typename Alloc
>
3003 Node
*AbstractManglingParser
<Derived
, Alloc
>::parseUnresolvedType() {
3004 if (look() == 'T') {
3005 Node
*TP
= getDerived().parseTemplateParam();
3011 if (look() == 'D') {
3012 Node
*DT
= getDerived().parseDecltype();
3018 return getDerived().parseSubstitution();
3021 // <base-unresolved-name> ::= <simple-id> # unresolved name
3022 // extension ::= <operator-name> # unresolved operator-function-id
3023 // extension ::= <operator-name> <template-args> # unresolved operator template-id
3024 // ::= on <operator-name> # unresolved operator-function-id
3025 // ::= on <operator-name> <template-args> # unresolved operator template-id
3026 // ::= dn <destructor-name> # destructor or pseudo-destructor;
3027 // # e.g. ~X or ~X<N-1>
3028 template <typename Derived
, typename Alloc
>
3029 Node
*AbstractManglingParser
<Derived
, Alloc
>::parseBaseUnresolvedName() {
3030 if (std::isdigit(look()))
3031 return getDerived().parseSimpleId();
3033 if (consumeIf("dn"))
3034 return getDerived().parseDestructorName();
3038 Node
*Oper
= getDerived().parseOperatorName(/*NameState=*/nullptr);
3039 if (Oper
== nullptr)
3041 if (look() == 'I') {
3042 Node
*TA
= getDerived().parseTemplateArgs();
3045 return make
<NameWithTemplateArgs
>(Oper
, TA
);
3050 // <unresolved-name>
3051 // extension ::= srN <unresolved-type> [<template-args>] <unresolved-qualifier-level>* E <base-unresolved-name>
3052 // ::= [gs] <base-unresolved-name> # x or (with "gs") ::x
3053 // ::= [gs] sr <unresolved-qualifier-level>+ E <base-unresolved-name>
3054 // # A::x, N::y, A<T>::z; "gs" means leading "::"
3055 // ::= sr <unresolved-type> <base-unresolved-name> # T::x / decltype(p)::x
3056 // extension ::= sr <unresolved-type> <template-args> <base-unresolved-name>
3057 // # T::N::x /decltype(p)::N::x
3058 // (ignored) ::= srN <unresolved-type> <unresolved-qualifier-level>+ E <base-unresolved-name>
3060 // <unresolved-qualifier-level> ::= <simple-id>
3061 template <typename Derived
, typename Alloc
>
3062 Node
*AbstractManglingParser
<Derived
, Alloc
>::parseUnresolvedName() {
3063 Node
*SoFar
= nullptr;
3065 // srN <unresolved-type> [<template-args>] <unresolved-qualifier-level>* E <base-unresolved-name>
3066 // srN <unresolved-type> <unresolved-qualifier-level>+ E <base-unresolved-name>
3067 if (consumeIf("srN")) {
3068 SoFar
= getDerived().parseUnresolvedType();
3069 if (SoFar
== nullptr)
3072 if (look() == 'I') {
3073 Node
*TA
= getDerived().parseTemplateArgs();
3076 SoFar
= make
<NameWithTemplateArgs
>(SoFar
, TA
);
3081 while (!consumeIf('E')) {
3082 Node
*Qual
= getDerived().parseSimpleId();
3083 if (Qual
== nullptr)
3085 SoFar
= make
<QualifiedName
>(SoFar
, Qual
);
3090 Node
*Base
= getDerived().parseBaseUnresolvedName();
3091 if (Base
== nullptr)
3093 return make
<QualifiedName
>(SoFar
, Base
);
3096 bool Global
= consumeIf("gs");
3098 // [gs] <base-unresolved-name> # x or (with "gs") ::x
3099 if (!consumeIf("sr")) {
3100 SoFar
= getDerived().parseBaseUnresolvedName();
3101 if (SoFar
== nullptr)
3104 SoFar
= make
<GlobalQualifiedName
>(SoFar
);
3108 // [gs] sr <unresolved-qualifier-level>+ E <base-unresolved-name>
3109 if (std::isdigit(look())) {
3111 Node
*Qual
= getDerived().parseSimpleId();
3112 if (Qual
== nullptr)
3115 SoFar
= make
<QualifiedName
>(SoFar
, Qual
);
3117 SoFar
= make
<GlobalQualifiedName
>(Qual
);
3122 } while (!consumeIf('E'));
3124 // sr <unresolved-type> <base-unresolved-name>
3125 // sr <unresolved-type> <template-args> <base-unresolved-name>
3127 SoFar
= getDerived().parseUnresolvedType();
3128 if (SoFar
== nullptr)
3131 if (look() == 'I') {
3132 Node
*TA
= getDerived().parseTemplateArgs();
3135 SoFar
= make
<NameWithTemplateArgs
>(SoFar
, TA
);
3141 assert(SoFar
!= nullptr);
3143 Node
*Base
= getDerived().parseBaseUnresolvedName();
3144 if (Base
== nullptr)
3146 return make
<QualifiedName
>(SoFar
, Base
);
3149 // <abi-tags> ::= <abi-tag> [<abi-tags>]
3150 // <abi-tag> ::= B <source-name>
3151 template <typename Derived
, typename Alloc
>
3152 Node
*AbstractManglingParser
<Derived
, Alloc
>::parseAbiTags(Node
*N
) {
3153 while (consumeIf('B')) {
3154 StringView SN
= parseBareSourceName();
3157 N
= make
<AbiTagAttr
>(N
, SN
);
3164 // <number> ::= [n] <non-negative decimal integer>
3165 template <typename Alloc
, typename Derived
>
3167 AbstractManglingParser
<Alloc
, Derived
>::parseNumber(bool AllowNegative
) {
3168 const char *Tmp
= First
;
3171 if (numLeft() == 0 || !std::isdigit(*First
))
3172 return StringView();
3173 while (numLeft() != 0 && std::isdigit(*First
))
3175 return StringView(Tmp
, First
);
3178 // <positive length number> ::= [0-9]*
3179 template <typename Alloc
, typename Derived
>
3180 bool AbstractManglingParser
<Alloc
, Derived
>::parsePositiveInteger(size_t *Out
) {
3182 if (look() < '0' || look() > '9')
3184 while (look() >= '0' && look() <= '9') {
3186 *Out
+= static_cast<size_t>(consume() - '0');
3191 template <typename Alloc
, typename Derived
>
3192 StringView AbstractManglingParser
<Alloc
, Derived
>::parseBareSourceName() {
3194 if (parsePositiveInteger(&Int
) || numLeft() < Int
)
3195 return StringView();
3196 StringView
R(First
, First
+ Int
);
3201 // <function-type> ::= [<CV-qualifiers>] [<exception-spec>] [Dx] F [Y] <bare-function-type> [<ref-qualifier>] E
3203 // <exception-spec> ::= Do # non-throwing exception-specification (e.g., noexcept, throw())
3204 // ::= DO <expression> E # computed (instantiation-dependent) noexcept
3205 // ::= Dw <type>+ E # dynamic exception specification with instantiation-dependent types
3207 // <ref-qualifier> ::= R # & ref-qualifier
3208 // <ref-qualifier> ::= O # && ref-qualifier
3209 template <typename Derived
, typename Alloc
>
3210 Node
*AbstractManglingParser
<Derived
, Alloc
>::parseFunctionType() {
3211 Qualifiers CVQuals
= parseCVQualifiers();
3213 Node
*ExceptionSpec
= nullptr;
3214 if (consumeIf("Do")) {
3215 ExceptionSpec
= make
<NameType
>("noexcept");
3218 } else if (consumeIf("DO")) {
3219 Node
*E
= getDerived().parseExpr();
3220 if (E
== nullptr || !consumeIf('E'))
3222 ExceptionSpec
= make
<NoexceptSpec
>(E
);
3225 } else if (consumeIf("Dw")) {
3226 size_t SpecsBegin
= Names
.size();
3227 while (!consumeIf('E')) {
3228 Node
*T
= getDerived().parseType();
3234 make
<DynamicExceptionSpec
>(popTrailingNodeArray(SpecsBegin
));
3239 consumeIf("Dx"); // transaction safe
3241 if (!consumeIf('F'))
3243 consumeIf('Y'); // extern "C"
3244 Node
*ReturnType
= getDerived().parseType();
3245 if (ReturnType
== nullptr)
3248 FunctionRefQual ReferenceQualifier
= FrefQualNone
;
3249 size_t ParamsBegin
= Names
.size();
3255 if (consumeIf("RE")) {
3256 ReferenceQualifier
= FrefQualLValue
;
3259 if (consumeIf("OE")) {
3260 ReferenceQualifier
= FrefQualRValue
;
3263 Node
*T
= getDerived().parseType();
3269 NodeArray Params
= popTrailingNodeArray(ParamsBegin
);
3270 return make
<FunctionType
>(ReturnType
, Params
, CVQuals
,
3271 ReferenceQualifier
, ExceptionSpec
);
3275 // <vector-type> ::= Dv <positive dimension number> _ <extended element type>
3276 // ::= Dv [<dimension expression>] _ <element type>
3277 // <extended element type> ::= <element type>
3278 // ::= p # AltiVec vector pixel
3279 template <typename Derived
, typename Alloc
>
3280 Node
*AbstractManglingParser
<Derived
, Alloc
>::parseVectorType() {
3281 if (!consumeIf("Dv"))
3283 if (look() >= '1' && look() <= '9') {
3284 StringView DimensionNumber
= parseNumber();
3285 if (!consumeIf('_'))
3288 return make
<PixelVectorType
>(DimensionNumber
);
3289 Node
*ElemType
= getDerived().parseType();
3290 if (ElemType
== nullptr)
3292 return make
<VectorType
>(ElemType
, DimensionNumber
);
3295 if (!consumeIf('_')) {
3296 Node
*DimExpr
= getDerived().parseExpr();
3299 if (!consumeIf('_'))
3301 Node
*ElemType
= getDerived().parseType();
3304 return make
<VectorType
>(ElemType
, DimExpr
);
3306 Node
*ElemType
= getDerived().parseType();
3309 return make
<VectorType
>(ElemType
, StringView());
3312 // <decltype> ::= Dt <expression> E # decltype of an id-expression or class member access (C++0x)
3313 // ::= DT <expression> E # decltype of an expression (C++0x)
3314 template <typename Derived
, typename Alloc
>
3315 Node
*AbstractManglingParser
<Derived
, Alloc
>::parseDecltype() {
3316 if (!consumeIf('D'))
3318 if (!consumeIf('t') && !consumeIf('T'))
3320 Node
*E
= getDerived().parseExpr();
3323 if (!consumeIf('E'))
3325 return make
<EnclosingExpr
>("decltype(", E
, ")");
3328 // <array-type> ::= A <positive dimension number> _ <element type>
3329 // ::= A [<dimension expression>] _ <element type>
3330 template <typename Derived
, typename Alloc
>
3331 Node
*AbstractManglingParser
<Derived
, Alloc
>::parseArrayType() {
3332 if (!consumeIf('A'))
3335 NodeOrString Dimension
;
3337 if (std::isdigit(look())) {
3338 Dimension
= parseNumber();
3339 if (!consumeIf('_'))
3341 } else if (!consumeIf('_')) {
3342 Node
*DimExpr
= getDerived().parseExpr();
3343 if (DimExpr
== nullptr)
3345 if (!consumeIf('_'))
3347 Dimension
= DimExpr
;
3350 Node
*Ty
= getDerived().parseType();
3353 return make
<ArrayType
>(Ty
, Dimension
);
3356 // <pointer-to-member-type> ::= M <class type> <member type>
3357 template <typename Derived
, typename Alloc
>
3358 Node
*AbstractManglingParser
<Derived
, Alloc
>::parsePointerToMemberType() {
3359 if (!consumeIf('M'))
3361 Node
*ClassType
= getDerived().parseType();
3362 if (ClassType
== nullptr)
3364 Node
*MemberType
= getDerived().parseType();
3365 if (MemberType
== nullptr)
3367 return make
<PointerToMemberType
>(ClassType
, MemberType
);
3370 // <class-enum-type> ::= <name> # non-dependent type name, dependent type name, or dependent typename-specifier
3371 // ::= Ts <name> # dependent elaborated type specifier using 'struct' or 'class'
3372 // ::= Tu <name> # dependent elaborated type specifier using 'union'
3373 // ::= Te <name> # dependent elaborated type specifier using 'enum'
3374 template <typename Derived
, typename Alloc
>
3375 Node
*AbstractManglingParser
<Derived
, Alloc
>::parseClassEnumType() {
3376 StringView ElabSpef
;
3377 if (consumeIf("Ts"))
3378 ElabSpef
= "struct";
3379 else if (consumeIf("Tu"))
3381 else if (consumeIf("Te"))
3384 Node
*Name
= getDerived().parseName();
3385 if (Name
== nullptr)
3388 if (!ElabSpef
.empty())
3389 return make
<ElaboratedTypeSpefType
>(ElabSpef
, Name
);
3394 // <qualified-type> ::= <qualifiers> <type>
3395 // <qualifiers> ::= <extended-qualifier>* <CV-qualifiers>
3396 // <extended-qualifier> ::= U <source-name> [<template-args>] # vendor extended type qualifier
3397 template <typename Derived
, typename Alloc
>
3398 Node
*AbstractManglingParser
<Derived
, Alloc
>::parseQualifiedType() {
3399 if (consumeIf('U')) {
3400 StringView Qual
= parseBareSourceName();
3404 // FIXME parse the optional <template-args> here!
3406 // extension ::= U <objc-name> <objc-type> # objc-type<identifier>
3407 if (Qual
.startsWith("objcproto")) {
3408 StringView ProtoSourceName
= Qual
.dropFront(std::strlen("objcproto"));
3411 SwapAndRestore
<const char *> SaveFirst(First
, ProtoSourceName
.begin()),
3412 SaveLast(Last
, ProtoSourceName
.end());
3413 Proto
= parseBareSourceName();
3417 Node
*Child
= getDerived().parseQualifiedType();
3418 if (Child
== nullptr)
3420 return make
<ObjCProtoName
>(Child
, Proto
);
3423 Node
*Child
= getDerived().parseQualifiedType();
3424 if (Child
== nullptr)
3426 return make
<VendorExtQualType
>(Child
, Qual
);
3429 Qualifiers Quals
= parseCVQualifiers();
3430 Node
*Ty
= getDerived().parseType();
3433 if (Quals
!= QualNone
)
3434 Ty
= make
<QualType
>(Ty
, Quals
);
3438 // <type> ::= <builtin-type>
3439 // ::= <qualified-type>
3440 // ::= <function-type>
3441 // ::= <class-enum-type>
3443 // ::= <pointer-to-member-type>
3444 // ::= <template-param>
3445 // ::= <template-template-param> <template-args>
3447 // ::= P <type> # pointer
3448 // ::= R <type> # l-value reference
3449 // ::= O <type> # r-value reference (C++11)
3450 // ::= C <type> # complex pair (C99)
3451 // ::= G <type> # imaginary (C99)
3452 // ::= <substitution> # See Compression below
3453 // extension ::= U <objc-name> <objc-type> # objc-type<identifier>
3454 // extension ::= <vector-type> # <vector-type> starts with Dv
3456 // <objc-name> ::= <k0 number> objcproto <k1 number> <identifier> # k0 = 9 + <number of digits in k1> + k1
3457 // <objc-type> ::= <source-name> # PU<11+>objcproto 11objc_object<source-name> 11objc_object -> id<source-name>
3458 template <typename Derived
, typename Alloc
>
3459 Node
*AbstractManglingParser
<Derived
, Alloc
>::parseType() {
3460 Node
*Result
= nullptr;
3463 // ::= <qualified-type>
3467 unsigned AfterQuals
= 0;
3468 if (look(AfterQuals
) == 'r') ++AfterQuals
;
3469 if (look(AfterQuals
) == 'V') ++AfterQuals
;
3470 if (look(AfterQuals
) == 'K') ++AfterQuals
;
3472 if (look(AfterQuals
) == 'F' ||
3473 (look(AfterQuals
) == 'D' &&
3474 (look(AfterQuals
+ 1) == 'o' || look(AfterQuals
+ 1) == 'O' ||
3475 look(AfterQuals
+ 1) == 'w' || look(AfterQuals
+ 1) == 'x'))) {
3476 Result
= getDerived().parseFunctionType();
3479 DEMANGLE_FALLTHROUGH
;
3482 Result
= getDerived().parseQualifiedType();
3485 // <builtin-type> ::= v # void
3488 return make
<NameType
>("void");
3492 return make
<NameType
>("wchar_t");
3496 return make
<NameType
>("bool");
3500 return make
<NameType
>("char");
3501 // ::= a # signed char
3504 return make
<NameType
>("signed char");
3505 // ::= h # unsigned char
3508 return make
<NameType
>("unsigned char");
3512 return make
<NameType
>("short");
3513 // ::= t # unsigned short
3516 return make
<NameType
>("unsigned short");
3520 return make
<NameType
>("int");
3521 // ::= j # unsigned int
3524 return make
<NameType
>("unsigned int");
3528 return make
<NameType
>("long");
3529 // ::= m # unsigned long
3532 return make
<NameType
>("unsigned long");
3533 // ::= x # long long, __int64
3536 return make
<NameType
>("long long");
3537 // ::= y # unsigned long long, __int64
3540 return make
<NameType
>("unsigned long long");
3544 return make
<NameType
>("__int128");
3545 // ::= o # unsigned __int128
3548 return make
<NameType
>("unsigned __int128");
3552 return make
<NameType
>("float");
3556 return make
<NameType
>("double");
3557 // ::= e # long double, __float80
3560 return make
<NameType
>("long double");
3561 // ::= g # __float128
3564 return make
<NameType
>("__float128");
3568 return make
<NameType
>("...");
3570 // <builtin-type> ::= u <source-name> # vendor extended type
3573 StringView Res
= parseBareSourceName();
3576 return make
<NameType
>(Res
);
3580 // ::= Dd # IEEE 754r decimal floating point (64 bits)
3583 return make
<NameType
>("decimal64");
3584 // ::= De # IEEE 754r decimal floating point (128 bits)
3587 return make
<NameType
>("decimal128");
3588 // ::= Df # IEEE 754r decimal floating point (32 bits)
3591 return make
<NameType
>("decimal32");
3592 // ::= Dh # IEEE 754r half-precision floating point (16 bits)
3595 return make
<NameType
>("decimal16");
3596 // ::= Di # char32_t
3599 return make
<NameType
>("char32_t");
3600 // ::= Ds # char16_t
3603 return make
<NameType
>("char16_t");
3604 // ::= Da # auto (in dependent new-expressions)
3607 return make
<NameType
>("auto");
3608 // ::= Dc # decltype(auto)
3611 return make
<NameType
>("decltype(auto)");
3612 // ::= Dn # std::nullptr_t (i.e., decltype(nullptr))
3615 return make
<NameType
>("std::nullptr_t");
3620 Result
= getDerived().parseDecltype();
3623 // extension ::= <vector-type> # <vector-type> starts with Dv
3625 Result
= getDerived().parseVectorType();
3628 // ::= Dp <type> # pack expansion (C++0x)
3631 Node
*Child
= getDerived().parseType();
3634 Result
= make
<ParameterPackExpansion
>(Child
);
3637 // Exception specifier on a function type.
3641 // Transaction safe function type.
3643 Result
= getDerived().parseFunctionType();
3647 // ::= <function-type>
3649 Result
= getDerived().parseFunctionType();
3654 Result
= getDerived().parseArrayType();
3657 // ::= <pointer-to-member-type>
3659 Result
= getDerived().parsePointerToMemberType();
3662 // ::= <template-param>
3664 // This could be an elaborate type specifier on a <class-enum-type>.
3665 if (look(1) == 's' || look(1) == 'u' || look(1) == 'e') {
3666 Result
= getDerived().parseClassEnumType();
3670 Result
= getDerived().parseTemplateParam();
3671 if (Result
== nullptr)
3674 // Result could be either of:
3675 // <type> ::= <template-param>
3676 // <type> ::= <template-template-param> <template-args>
3678 // <template-template-param> ::= <template-param>
3679 // ::= <substitution>
3681 // If this is followed by some <template-args>, and we're permitted to
3682 // parse them, take the second production.
3684 if (TryToParseTemplateArgs
&& look() == 'I') {
3685 Node
*TA
= getDerived().parseTemplateArgs();
3688 Result
= make
<NameWithTemplateArgs
>(Result
, TA
);
3692 // ::= P <type> # pointer
3695 Node
*Ptr
= getDerived().parseType();
3698 Result
= make
<PointerType
>(Ptr
);
3701 // ::= R <type> # l-value reference
3704 Node
*Ref
= getDerived().parseType();
3707 Result
= make
<ReferenceType
>(Ref
, ReferenceKind::LValue
);
3710 // ::= O <type> # r-value reference (C++11)
3713 Node
*Ref
= getDerived().parseType();
3716 Result
= make
<ReferenceType
>(Ref
, ReferenceKind::RValue
);
3719 // ::= C <type> # complex pair (C99)
3722 Node
*P
= getDerived().parseType();
3725 Result
= make
<PostfixQualifiedType
>(P
, " complex");
3728 // ::= G <type> # imaginary (C99)
3731 Node
*P
= getDerived().parseType();
3734 Result
= make
<PostfixQualifiedType
>(P
, " imaginary");
3737 // ::= <substitution> # See Compression below
3739 if (look(1) && look(1) != 't') {
3740 Node
*Sub
= getDerived().parseSubstitution();
3744 // Sub could be either of:
3745 // <type> ::= <substitution>
3746 // <type> ::= <template-template-param> <template-args>
3748 // <template-template-param> ::= <template-param>
3749 // ::= <substitution>
3751 // If this is followed by some <template-args>, and we're permitted to
3752 // parse them, take the second production.
3754 if (TryToParseTemplateArgs
&& look() == 'I') {
3755 Node
*TA
= getDerived().parseTemplateArgs();
3758 Result
= make
<NameWithTemplateArgs
>(Sub
, TA
);
3762 // If all we parsed was a substitution, don't re-insert into the
3763 // substitution table.
3766 DEMANGLE_FALLTHROUGH
;
3768 // ::= <class-enum-type>
3770 Result
= getDerived().parseClassEnumType();
3775 // If we parsed a type, insert it into the substitution table. Note that all
3776 // <builtin-type>s and <substitution>s have already bailed out, because they
3777 // don't get substitutions.
3778 if (Result
!= nullptr)
3779 Subs
.push_back(Result
);
3783 template <typename Derived
, typename Alloc
>
3784 Node
*AbstractManglingParser
<Derived
, Alloc
>::parsePrefixExpr(StringView Kind
) {
3785 Node
*E
= getDerived().parseExpr();
3788 return make
<PrefixExpr
>(Kind
, E
);
3791 template <typename Derived
, typename Alloc
>
3792 Node
*AbstractManglingParser
<Derived
, Alloc
>::parseBinaryExpr(StringView Kind
) {
3793 Node
*LHS
= getDerived().parseExpr();
3796 Node
*RHS
= getDerived().parseExpr();
3799 return make
<BinaryExpr
>(LHS
, Kind
, RHS
);
3802 template <typename Derived
, typename Alloc
>
3804 AbstractManglingParser
<Derived
, Alloc
>::parseIntegerLiteral(StringView Lit
) {
3805 StringView Tmp
= parseNumber(true);
3806 if (!Tmp
.empty() && consumeIf('E'))
3807 return make
<IntegerLiteral
>(Lit
, Tmp
);
3811 // <CV-Qualifiers> ::= [r] [V] [K]
3812 template <typename Alloc
, typename Derived
>
3813 Qualifiers AbstractManglingParser
<Alloc
, Derived
>::parseCVQualifiers() {
3814 Qualifiers CVR
= QualNone
;
3816 CVR
|= QualRestrict
;
3818 CVR
|= QualVolatile
;
3824 // <function-param> ::= fp <top-level CV-Qualifiers> _ # L == 0, first parameter
3825 // ::= fp <top-level CV-Qualifiers> <parameter-2 non-negative number> _ # L == 0, second and later parameters
3826 // ::= fL <L-1 non-negative number> p <top-level CV-Qualifiers> _ # L > 0, first parameter
3827 // ::= fL <L-1 non-negative number> p <top-level CV-Qualifiers> <parameter-2 non-negative number> _ # L > 0, second and later parameters
3828 template <typename Derived
, typename Alloc
>
3829 Node
*AbstractManglingParser
<Derived
, Alloc
>::parseFunctionParam() {
3830 if (consumeIf("fp")) {
3831 parseCVQualifiers();
3832 StringView Num
= parseNumber();
3833 if (!consumeIf('_'))
3835 return make
<FunctionParam
>(Num
);
3837 if (consumeIf("fL")) {
3838 if (parseNumber().empty())
3840 if (!consumeIf('p'))
3842 parseCVQualifiers();
3843 StringView Num
= parseNumber();
3844 if (!consumeIf('_'))
3846 return make
<FunctionParam
>(Num
);
3851 // [gs] nw <expression>* _ <type> E # new (expr-list) type
3852 // [gs] nw <expression>* _ <type> <initializer> # new (expr-list) type (init)
3853 // [gs] na <expression>* _ <type> E # new[] (expr-list) type
3854 // [gs] na <expression>* _ <type> <initializer> # new[] (expr-list) type (init)
3855 // <initializer> ::= pi <expression>* E # parenthesized initialization
3856 template <typename Derived
, typename Alloc
>
3857 Node
*AbstractManglingParser
<Derived
, Alloc
>::parseNewExpr() {
3858 bool Global
= consumeIf("gs");
3859 bool IsArray
= look(1) == 'a';
3860 if (!consumeIf("nw") && !consumeIf("na"))
3862 size_t Exprs
= Names
.size();
3863 while (!consumeIf('_')) {
3864 Node
*Ex
= getDerived().parseExpr();
3867 Names
.push_back(Ex
);
3869 NodeArray ExprList
= popTrailingNodeArray(Exprs
);
3870 Node
*Ty
= getDerived().parseType();
3873 if (consumeIf("pi")) {
3874 size_t InitsBegin
= Names
.size();
3875 while (!consumeIf('E')) {
3876 Node
*Init
= getDerived().parseExpr();
3877 if (Init
== nullptr)
3879 Names
.push_back(Init
);
3881 NodeArray Inits
= popTrailingNodeArray(InitsBegin
);
3882 return make
<NewExpr
>(ExprList
, Ty
, Inits
, Global
, IsArray
);
3883 } else if (!consumeIf('E'))
3885 return make
<NewExpr
>(ExprList
, Ty
, NodeArray(), Global
, IsArray
);
3888 // cv <type> <expression> # conversion with one argument
3889 // cv <type> _ <expression>* E # conversion with a different number of arguments
3890 template <typename Derived
, typename Alloc
>
3891 Node
*AbstractManglingParser
<Derived
, Alloc
>::parseConversionExpr() {
3892 if (!consumeIf("cv"))
3896 SwapAndRestore
<bool> SaveTemp(TryToParseTemplateArgs
, false);
3897 Ty
= getDerived().parseType();
3903 if (consumeIf('_')) {
3904 size_t ExprsBegin
= Names
.size();
3905 while (!consumeIf('E')) {
3906 Node
*E
= getDerived().parseExpr();
3911 NodeArray Exprs
= popTrailingNodeArray(ExprsBegin
);
3912 return make
<ConversionExpr
>(Ty
, Exprs
);
3915 Node
*E
[1] = {getDerived().parseExpr()};
3916 if (E
[0] == nullptr)
3918 return make
<ConversionExpr
>(Ty
, makeNodeArray(E
, E
+ 1));
3921 // <expr-primary> ::= L <type> <value number> E # integer literal
3922 // ::= L <type> <value float> E # floating literal
3923 // ::= L <string type> E # string literal
3924 // ::= L <nullptr type> E # nullptr literal (i.e., "LDnE")
3925 // FIXME: ::= L <type> <real-part float> _ <imag-part float> E # complex floating point literal (C 2000)
3926 // ::= L <mangled-name> E # external name
3927 template <typename Derived
, typename Alloc
>
3928 Node
*AbstractManglingParser
<Derived
, Alloc
>::parseExprPrimary() {
3929 if (!consumeIf('L'))
3934 return getDerived().parseIntegerLiteral("wchar_t");
3936 if (consumeIf("b0E"))
3937 return make
<BoolExpr
>(0);
3938 if (consumeIf("b1E"))
3939 return make
<BoolExpr
>(1);
3943 return getDerived().parseIntegerLiteral("char");
3946 return getDerived().parseIntegerLiteral("signed char");
3949 return getDerived().parseIntegerLiteral("unsigned char");
3952 return getDerived().parseIntegerLiteral("short");
3955 return getDerived().parseIntegerLiteral("unsigned short");
3958 return getDerived().parseIntegerLiteral("");
3961 return getDerived().parseIntegerLiteral("u");
3964 return getDerived().parseIntegerLiteral("l");
3967 return getDerived().parseIntegerLiteral("ul");
3970 return getDerived().parseIntegerLiteral("ll");
3973 return getDerived().parseIntegerLiteral("ull");
3976 return getDerived().parseIntegerLiteral("__int128");
3979 return getDerived().parseIntegerLiteral("unsigned __int128");
3982 return getDerived().template parseFloatingLiteral
<float>();
3985 return getDerived().template parseFloatingLiteral
<double>();
3988 return getDerived().template parseFloatingLiteral
<long double>();
3990 if (consumeIf("_Z")) {
3991 Node
*R
= getDerived().parseEncoding();
3992 if (R
!= nullptr && consumeIf('E'))
3997 // Invalid mangled name per
3998 // http://sourcerytools.com/pipermail/cxx-abi-dev/2011-August/002422.html
4001 // might be named type
4002 Node
*T
= getDerived().parseType();
4005 StringView N
= parseNumber();
4007 if (!consumeIf('E'))
4009 return make
<IntegerCastExpr
>(T
, N
);
4018 // <braced-expression> ::= <expression>
4019 // ::= di <field source-name> <braced-expression> # .name = expr
4020 // ::= dx <index expression> <braced-expression> # [expr] = expr
4021 // ::= dX <range begin expression> <range end expression> <braced-expression>
4022 template <typename Derived
, typename Alloc
>
4023 Node
*AbstractManglingParser
<Derived
, Alloc
>::parseBracedExpr() {
4024 if (look() == 'd') {
4028 Node
*Field
= getDerived().parseSourceName(/*NameState=*/nullptr);
4029 if (Field
== nullptr)
4031 Node
*Init
= getDerived().parseBracedExpr();
4032 if (Init
== nullptr)
4034 return make
<BracedExpr
>(Field
, Init
, /*isArray=*/false);
4038 Node
*Index
= getDerived().parseExpr();
4039 if (Index
== nullptr)
4041 Node
*Init
= getDerived().parseBracedExpr();
4042 if (Init
== nullptr)
4044 return make
<BracedExpr
>(Index
, Init
, /*isArray=*/true);
4048 Node
*RangeBegin
= getDerived().parseExpr();
4049 if (RangeBegin
== nullptr)
4051 Node
*RangeEnd
= getDerived().parseExpr();
4052 if (RangeEnd
== nullptr)
4054 Node
*Init
= getDerived().parseBracedExpr();
4055 if (Init
== nullptr)
4057 return make
<BracedRangeExpr
>(RangeBegin
, RangeEnd
, Init
);
4061 return getDerived().parseExpr();
4064 // (not yet in the spec)
4065 // <fold-expr> ::= fL <binary-operator-name> <expression> <expression>
4066 // ::= fR <binary-operator-name> <expression> <expression>
4067 // ::= fl <binary-operator-name> <expression>
4068 // ::= fr <binary-operator-name> <expression>
4069 template <typename Derived
, typename Alloc
>
4070 Node
*AbstractManglingParser
<Derived
, Alloc
>::parseFoldExpr() {
4071 if (!consumeIf('f'))
4074 char FoldKind
= look();
4075 bool IsLeftFold
, HasInitializer
;
4076 HasInitializer
= FoldKind
== 'L' || FoldKind
== 'R';
4077 if (FoldKind
== 'l' || FoldKind
== 'L')
4079 else if (FoldKind
== 'r' || FoldKind
== 'R')
4085 // FIXME: This map is duplicated in parseOperatorName and parseExpr.
4086 StringView OperatorName
;
4087 if (consumeIf("aa")) OperatorName
= "&&";
4088 else if (consumeIf("an")) OperatorName
= "&";
4089 else if (consumeIf("aN")) OperatorName
= "&=";
4090 else if (consumeIf("aS")) OperatorName
= "=";
4091 else if (consumeIf("cm")) OperatorName
= ",";
4092 else if (consumeIf("ds")) OperatorName
= ".*";
4093 else if (consumeIf("dv")) OperatorName
= "/";
4094 else if (consumeIf("dV")) OperatorName
= "/=";
4095 else if (consumeIf("eo")) OperatorName
= "^";
4096 else if (consumeIf("eO")) OperatorName
= "^=";
4097 else if (consumeIf("eq")) OperatorName
= "==";
4098 else if (consumeIf("ge")) OperatorName
= ">=";
4099 else if (consumeIf("gt")) OperatorName
= ">";
4100 else if (consumeIf("le")) OperatorName
= "<=";
4101 else if (consumeIf("ls")) OperatorName
= "<<";
4102 else if (consumeIf("lS")) OperatorName
= "<<=";
4103 else if (consumeIf("lt")) OperatorName
= "<";
4104 else if (consumeIf("mi")) OperatorName
= "-";
4105 else if (consumeIf("mI")) OperatorName
= "-=";
4106 else if (consumeIf("ml")) OperatorName
= "*";
4107 else if (consumeIf("mL")) OperatorName
= "*=";
4108 else if (consumeIf("ne")) OperatorName
= "!=";
4109 else if (consumeIf("oo")) OperatorName
= "||";
4110 else if (consumeIf("or")) OperatorName
= "|";
4111 else if (consumeIf("oR")) OperatorName
= "|=";
4112 else if (consumeIf("pl")) OperatorName
= "+";
4113 else if (consumeIf("pL")) OperatorName
= "+=";
4114 else if (consumeIf("rm")) OperatorName
= "%";
4115 else if (consumeIf("rM")) OperatorName
= "%=";
4116 else if (consumeIf("rs")) OperatorName
= ">>";
4117 else if (consumeIf("rS")) OperatorName
= ">>=";
4118 else return nullptr;
4120 Node
*Pack
= getDerived().parseExpr(), *Init
= nullptr;
4121 if (Pack
== nullptr)
4123 if (HasInitializer
) {
4124 Init
= getDerived().parseExpr();
4125 if (Init
== nullptr)
4129 if (IsLeftFold
&& Init
)
4130 std::swap(Pack
, Init
);
4132 return make
<FoldExpr
>(IsLeftFold
, OperatorName
, Pack
, Init
);
4135 // <expression> ::= <unary operator-name> <expression>
4136 // ::= <binary operator-name> <expression> <expression>
4137 // ::= <ternary operator-name> <expression> <expression> <expression>
4138 // ::= cl <expression>+ E # call
4139 // ::= cv <type> <expression> # conversion with one argument
4140 // ::= cv <type> _ <expression>* E # conversion with a different number of arguments
4141 // ::= [gs] nw <expression>* _ <type> E # new (expr-list) type
4142 // ::= [gs] nw <expression>* _ <type> <initializer> # new (expr-list) type (init)
4143 // ::= [gs] na <expression>* _ <type> E # new[] (expr-list) type
4144 // ::= [gs] na <expression>* _ <type> <initializer> # new[] (expr-list) type (init)
4145 // ::= [gs] dl <expression> # delete expression
4146 // ::= [gs] da <expression> # delete[] expression
4147 // ::= pp_ <expression> # prefix ++
4148 // ::= mm_ <expression> # prefix --
4149 // ::= ti <type> # typeid (type)
4150 // ::= te <expression> # typeid (expression)
4151 // ::= dc <type> <expression> # dynamic_cast<type> (expression)
4152 // ::= sc <type> <expression> # static_cast<type> (expression)
4153 // ::= cc <type> <expression> # const_cast<type> (expression)
4154 // ::= rc <type> <expression> # reinterpret_cast<type> (expression)
4155 // ::= st <type> # sizeof (a type)
4156 // ::= sz <expression> # sizeof (an expression)
4157 // ::= at <type> # alignof (a type)
4158 // ::= az <expression> # alignof (an expression)
4159 // ::= nx <expression> # noexcept (expression)
4160 // ::= <template-param>
4161 // ::= <function-param>
4162 // ::= dt <expression> <unresolved-name> # expr.name
4163 // ::= pt <expression> <unresolved-name> # expr->name
4164 // ::= ds <expression> <expression> # expr.*expr
4165 // ::= sZ <template-param> # size of a parameter pack
4166 // ::= sZ <function-param> # size of a function parameter pack
4167 // ::= sP <template-arg>* E # sizeof...(T), size of a captured template parameter pack from an alias template
4168 // ::= sp <expression> # pack expansion
4169 // ::= tw <expression> # throw expression
4170 // ::= tr # throw with no operand (rethrow)
4171 // ::= <unresolved-name> # f(p), N::f(p), ::f(p),
4172 // # freestanding dependent name (e.g., T::x),
4173 // # objectless nonstatic member reference
4174 // ::= fL <binary-operator-name> <expression> <expression>
4175 // ::= fR <binary-operator-name> <expression> <expression>
4176 // ::= fl <binary-operator-name> <expression>
4177 // ::= fr <binary-operator-name> <expression>
4178 // ::= <expr-primary>
4179 template <typename Derived
, typename Alloc
>
4180 Node
*AbstractManglingParser
<Derived
, Alloc
>::parseExpr() {
4181 bool Global
= consumeIf("gs");
4187 return getDerived().parseExprPrimary();
4189 return getDerived().parseTemplateParam();
4191 // Disambiguate a fold expression from a <function-param>.
4192 if (look(1) == 'p' || (look(1) == 'L' && std::isdigit(look(2))))
4193 return getDerived().parseFunctionParam();
4194 return getDerived().parseFoldExpr();
4200 return getDerived().parseBinaryExpr("&&");
4203 return getDerived().parsePrefixExpr("&");
4206 return getDerived().parseBinaryExpr("&");
4209 return getDerived().parseBinaryExpr("&=");
4212 return getDerived().parseBinaryExpr("=");
4215 Node
*Ty
= getDerived().parseType();
4218 return make
<EnclosingExpr
>("alignof (", Ty
, ")");
4222 Node
*Ty
= getDerived().parseExpr();
4225 return make
<EnclosingExpr
>("alignof (", Ty
, ")");
4231 // cc <type> <expression> # const_cast<type>(expression)
4234 Node
*Ty
= getDerived().parseType();
4237 Node
*Ex
= getDerived().parseExpr();
4240 return make
<CastExpr
>("const_cast", Ty
, Ex
);
4242 // cl <expression>+ E # call
4245 Node
*Callee
= getDerived().parseExpr();
4246 if (Callee
== nullptr)
4248 size_t ExprsBegin
= Names
.size();
4249 while (!consumeIf('E')) {
4250 Node
*E
= getDerived().parseExpr();
4255 return make
<CallExpr
>(Callee
, popTrailingNodeArray(ExprsBegin
));
4259 return getDerived().parseBinaryExpr(",");
4262 return getDerived().parsePrefixExpr("~");
4264 return getDerived().parseConversionExpr();
4271 Node
*Ex
= getDerived().parseExpr();
4274 return make
<DeleteExpr
>(Ex
, Global
, /*is_array=*/true);
4278 Node
*T
= getDerived().parseType();
4281 Node
*Ex
= getDerived().parseExpr();
4284 return make
<CastExpr
>("dynamic_cast", T
, Ex
);
4288 return getDerived().parsePrefixExpr("*");
4291 Node
*E
= getDerived().parseExpr();
4294 return make
<DeleteExpr
>(E
, Global
, /*is_array=*/false);
4297 return getDerived().parseUnresolvedName();
4300 Node
*LHS
= getDerived().parseExpr();
4303 Node
*RHS
= getDerived().parseExpr();
4306 return make
<MemberExpr
>(LHS
, ".*", RHS
);
4310 Node
*LHS
= getDerived().parseExpr();
4313 Node
*RHS
= getDerived().parseExpr();
4316 return make
<MemberExpr
>(LHS
, ".", RHS
);
4320 return getDerived().parseBinaryExpr("/");
4323 return getDerived().parseBinaryExpr("/=");
4330 return getDerived().parseBinaryExpr("^");
4333 return getDerived().parseBinaryExpr("^=");
4336 return getDerived().parseBinaryExpr("==");
4343 return getDerived().parseBinaryExpr(">=");
4346 return getDerived().parseBinaryExpr(">");
4353 Node
*Base
= getDerived().parseExpr();
4354 if (Base
== nullptr)
4356 Node
*Index
= getDerived().parseExpr();
4357 if (Index
== nullptr)
4359 return make
<ArraySubscriptExpr
>(Base
, Index
);
4363 size_t InitsBegin
= Names
.size();
4364 while (!consumeIf('E')) {
4365 Node
*E
= getDerived().parseBracedExpr();
4370 return make
<InitListExpr
>(nullptr, popTrailingNodeArray(InitsBegin
));
4378 return getDerived().parseBinaryExpr("<=");
4381 return getDerived().parseBinaryExpr("<<");
4384 return getDerived().parseBinaryExpr("<<=");
4387 return getDerived().parseBinaryExpr("<");
4394 return getDerived().parseBinaryExpr("-");
4397 return getDerived().parseBinaryExpr("-=");
4400 return getDerived().parseBinaryExpr("*");
4403 return getDerived().parseBinaryExpr("*=");
4407 return getDerived().parsePrefixExpr("--");
4408 Node
*Ex
= getDerived().parseExpr();
4411 return make
<PostfixExpr
>(Ex
, "--");
4418 return getDerived().parseNewExpr();
4421 return getDerived().parseBinaryExpr("!=");
4424 return getDerived().parsePrefixExpr("-");
4427 return getDerived().parsePrefixExpr("!");
4430 Node
*Ex
= getDerived().parseExpr();
4433 return make
<EnclosingExpr
>("noexcept (", Ex
, ")");
4439 return getDerived().parseUnresolvedName();
4442 return getDerived().parseBinaryExpr("||");
4445 return getDerived().parseBinaryExpr("|");
4448 return getDerived().parseBinaryExpr("|=");
4455 return getDerived().parseBinaryExpr("->*");
4458 return getDerived().parseBinaryExpr("+");
4461 return getDerived().parseBinaryExpr("+=");
4465 return getDerived().parsePrefixExpr("++");
4466 Node
*Ex
= getDerived().parseExpr();
4469 return make
<PostfixExpr
>(Ex
, "++");
4473 return getDerived().parsePrefixExpr("+");
4476 Node
*L
= getDerived().parseExpr();
4479 Node
*R
= getDerived().parseExpr();
4482 return make
<MemberExpr
>(L
, "->", R
);
4487 if (First
[1] == 'u') {
4489 Node
*Cond
= getDerived().parseExpr();
4490 if (Cond
== nullptr)
4492 Node
*LHS
= getDerived().parseExpr();
4495 Node
*RHS
= getDerived().parseExpr();
4498 return make
<ConditionalExpr
>(Cond
, LHS
, RHS
);
4505 Node
*T
= getDerived().parseType();
4508 Node
*Ex
= getDerived().parseExpr();
4511 return make
<CastExpr
>("reinterpret_cast", T
, Ex
);
4515 return getDerived().parseBinaryExpr("%");
4518 return getDerived().parseBinaryExpr("%=");
4521 return getDerived().parseBinaryExpr(">>");
4524 return getDerived().parseBinaryExpr(">>=");
4531 Node
*T
= getDerived().parseType();
4534 Node
*Ex
= getDerived().parseExpr();
4537 return make
<CastExpr
>("static_cast", T
, Ex
);
4541 Node
*Child
= getDerived().parseExpr();
4542 if (Child
== nullptr)
4544 return make
<ParameterPackExpansion
>(Child
);
4547 return getDerived().parseUnresolvedName();
4550 Node
*Ty
= getDerived().parseType();
4553 return make
<EnclosingExpr
>("sizeof (", Ty
, ")");
4557 Node
*Ex
= getDerived().parseExpr();
4560 return make
<EnclosingExpr
>("sizeof (", Ex
, ")");
4564 if (look() == 'T') {
4565 Node
*R
= getDerived().parseTemplateParam();
4568 return make
<SizeofParamPackExpr
>(R
);
4569 } else if (look() == 'f') {
4570 Node
*FP
= getDerived().parseFunctionParam();
4573 return make
<EnclosingExpr
>("sizeof... (", FP
, ")");
4578 size_t ArgsBegin
= Names
.size();
4579 while (!consumeIf('E')) {
4580 Node
*Arg
= getDerived().parseTemplateArg();
4583 Names
.push_back(Arg
);
4585 auto *Pack
= make
<NodeArrayNode
>(popTrailingNodeArray(ArgsBegin
));
4588 return make
<EnclosingExpr
>("sizeof... (", Pack
, ")");
4596 Node
*Ex
= getDerived().parseExpr();
4599 return make
<EnclosingExpr
>("typeid (", Ex
, ")");
4603 Node
*Ty
= getDerived().parseType();
4606 return make
<EnclosingExpr
>("typeid (", Ty
, ")");
4610 Node
*Ty
= getDerived().parseType();
4613 size_t InitsBegin
= Names
.size();
4614 while (!consumeIf('E')) {
4615 Node
*E
= getDerived().parseBracedExpr();
4620 return make
<InitListExpr
>(Ty
, popTrailingNodeArray(InitsBegin
));
4624 return make
<NameType
>("throw");
4627 Node
*Ex
= getDerived().parseExpr();
4630 return make
<ThrowExpr
>(Ex
);
4643 return getDerived().parseUnresolvedName();
4648 // <call-offset> ::= h <nv-offset> _
4649 // ::= v <v-offset> _
4651 // <nv-offset> ::= <offset number>
4652 // # non-virtual base override
4654 // <v-offset> ::= <offset number> _ <virtual offset number>
4655 // # virtual base override, with vcall offset
4656 template <typename Alloc
, typename Derived
>
4657 bool AbstractManglingParser
<Alloc
, Derived
>::parseCallOffset() {
4658 // Just scan through the call offset, we never add this information into the
4661 return parseNumber(true).empty() || !consumeIf('_');
4663 return parseNumber(true).empty() || !consumeIf('_') ||
4664 parseNumber(true).empty() || !consumeIf('_');
4668 // <special-name> ::= TV <type> # virtual table
4669 // ::= TT <type> # VTT structure (construction vtable index)
4670 // ::= TI <type> # typeinfo structure
4671 // ::= TS <type> # typeinfo name (null-terminated byte string)
4672 // ::= Tc <call-offset> <call-offset> <base encoding>
4673 // # base is the nominal target function of thunk
4674 // # first call-offset is 'this' adjustment
4675 // # second call-offset is result adjustment
4676 // ::= T <call-offset> <base encoding>
4677 // # base is the nominal target function of thunk
4678 // ::= GV <object name> # Guard variable for one-time initialization
4680 // ::= TW <object name> # Thread-local wrapper
4681 // ::= TH <object name> # Thread-local initialization
4682 // ::= GR <object name> _ # First temporary
4683 // ::= GR <object name> <seq-id> _ # Subsequent temporaries
4684 // extension ::= TC <first type> <number> _ <second type> # construction vtable for second-in-first
4685 // extension ::= GR <object name> # reference temporary for object
4686 template <typename Derived
, typename Alloc
>
4687 Node
*AbstractManglingParser
<Derived
, Alloc
>::parseSpecialName() {
4691 // TV <type> # virtual table
4694 Node
*Ty
= getDerived().parseType();
4697 return make
<SpecialName
>("vtable for ", Ty
);
4699 // TT <type> # VTT structure (construction vtable index)
4702 Node
*Ty
= getDerived().parseType();
4705 return make
<SpecialName
>("VTT for ", Ty
);
4707 // TI <type> # typeinfo structure
4710 Node
*Ty
= getDerived().parseType();
4713 return make
<SpecialName
>("typeinfo for ", Ty
);
4715 // TS <type> # typeinfo name (null-terminated byte string)
4718 Node
*Ty
= getDerived().parseType();
4721 return make
<SpecialName
>("typeinfo name for ", Ty
);
4723 // Tc <call-offset> <call-offset> <base encoding>
4726 if (parseCallOffset() || parseCallOffset())
4728 Node
*Encoding
= getDerived().parseEncoding();
4729 if (Encoding
== nullptr)
4731 return make
<SpecialName
>("covariant return thunk to ", Encoding
);
4733 // extension ::= TC <first type> <number> _ <second type>
4734 // # construction vtable for second-in-first
4737 Node
*FirstType
= getDerived().parseType();
4738 if (FirstType
== nullptr)
4740 if (parseNumber(true).empty() || !consumeIf('_'))
4742 Node
*SecondType
= getDerived().parseType();
4743 if (SecondType
== nullptr)
4745 return make
<CtorVtableSpecialName
>(SecondType
, FirstType
);
4747 // TW <object name> # Thread-local wrapper
4750 Node
*Name
= getDerived().parseName();
4751 if (Name
== nullptr)
4753 return make
<SpecialName
>("thread-local wrapper routine for ", Name
);
4755 // TH <object name> # Thread-local initialization
4758 Node
*Name
= getDerived().parseName();
4759 if (Name
== nullptr)
4761 return make
<SpecialName
>("thread-local initialization routine for ", Name
);
4763 // T <call-offset> <base encoding>
4766 bool IsVirt
= look() == 'v';
4767 if (parseCallOffset())
4769 Node
*BaseEncoding
= getDerived().parseEncoding();
4770 if (BaseEncoding
== nullptr)
4773 return make
<SpecialName
>("virtual thunk to ", BaseEncoding
);
4775 return make
<SpecialName
>("non-virtual thunk to ", BaseEncoding
);
4780 // GV <object name> # Guard variable for one-time initialization
4783 Node
*Name
= getDerived().parseName();
4784 if (Name
== nullptr)
4786 return make
<SpecialName
>("guard variable for ", Name
);
4788 // GR <object name> # reference temporary for object
4789 // GR <object name> _ # First temporary
4790 // GR <object name> <seq-id> _ # Subsequent temporaries
4793 Node
*Name
= getDerived().parseName();
4794 if (Name
== nullptr)
4797 bool ParsedSeqId
= !parseSeqId(&Count
);
4798 if (!consumeIf('_') && ParsedSeqId
)
4800 return make
<SpecialName
>("reference temporary for ", Name
);
4807 // <encoding> ::= <function name> <bare-function-type>
4809 // ::= <special-name>
4810 template <typename Derived
, typename Alloc
>
4811 Node
*AbstractManglingParser
<Derived
, Alloc
>::parseEncoding() {
4812 if (look() == 'G' || look() == 'T')
4813 return getDerived().parseSpecialName();
4815 auto IsEndOfEncoding
= [&] {
4816 // The set of chars that can potentially follow an <encoding> (none of which
4817 // can start a <type>). Enumerating these allows us to avoid speculative
4819 return numLeft() == 0 || look() == 'E' || look() == '.' || look() == '_';
4822 NameState
NameInfo(this);
4823 Node
*Name
= getDerived().parseName(&NameInfo
);
4824 if (Name
== nullptr)
4827 if (resolveForwardTemplateRefs(NameInfo
))
4830 if (IsEndOfEncoding())
4833 Node
*Attrs
= nullptr;
4834 if (consumeIf("Ua9enable_ifI")) {
4835 size_t BeforeArgs
= Names
.size();
4836 while (!consumeIf('E')) {
4837 Node
*Arg
= getDerived().parseTemplateArg();
4840 Names
.push_back(Arg
);
4842 Attrs
= make
<EnableIfAttr
>(popTrailingNodeArray(BeforeArgs
));
4847 Node
*ReturnType
= nullptr;
4848 if (!NameInfo
.CtorDtorConversion
&& NameInfo
.EndsWithTemplateArgs
) {
4849 ReturnType
= getDerived().parseType();
4850 if (ReturnType
== nullptr)
4855 return make
<FunctionEncoding
>(ReturnType
, Name
, NodeArray(),
4856 Attrs
, NameInfo
.CVQualifiers
,
4857 NameInfo
.ReferenceQualifier
);
4859 size_t ParamsBegin
= Names
.size();
4861 Node
*Ty
= getDerived().parseType();
4864 Names
.push_back(Ty
);
4865 } while (!IsEndOfEncoding());
4867 return make
<FunctionEncoding
>(ReturnType
, Name
,
4868 popTrailingNodeArray(ParamsBegin
),
4869 Attrs
, NameInfo
.CVQualifiers
,
4870 NameInfo
.ReferenceQualifier
);
4873 template <class Float
>
4877 struct FloatData
<float>
4879 static const size_t mangled_size
= 8;
4880 static const size_t max_demangled_size
= 24;
4881 static constexpr const char* spec
= "%af";
4885 struct FloatData
<double>
4887 static const size_t mangled_size
= 16;
4888 static const size_t max_demangled_size
= 32;
4889 static constexpr const char* spec
= "%a";
4893 struct FloatData
<long double>
4895 #if defined(__mips__) && defined(__mips_n64) || defined(__aarch64__) || \
4897 static const size_t mangled_size
= 32;
4898 #elif defined(__arm__) || defined(__mips__) || defined(__hexagon__)
4899 static const size_t mangled_size
= 16;
4901 static const size_t mangled_size
= 20; // May need to be adjusted to 16 or 24 on other platforms
4903 static const size_t max_demangled_size
= 40;
4904 static constexpr const char *spec
= "%LaL";
4907 template <typename Alloc
, typename Derived
>
4908 template <class Float
>
4909 Node
*AbstractManglingParser
<Alloc
, Derived
>::parseFloatingLiteral() {
4910 const size_t N
= FloatData
<Float
>::mangled_size
;
4913 StringView
Data(First
, First
+ N
);
4915 if (!std::isxdigit(C
))
4918 if (!consumeIf('E'))
4920 return make
<FloatLiteralImpl
<Float
>>(Data
);
4923 // <seq-id> ::= <0-9A-Z>+
4924 template <typename Alloc
, typename Derived
>
4925 bool AbstractManglingParser
<Alloc
, Derived
>::parseSeqId(size_t *Out
) {
4926 if (!(look() >= '0' && look() <= '9') &&
4927 !(look() >= 'A' && look() <= 'Z'))
4932 if (look() >= '0' && look() <= '9') {
4934 Id
+= static_cast<size_t>(look() - '0');
4935 } else if (look() >= 'A' && look() <= 'Z') {
4937 Id
+= static_cast<size_t>(look() - 'A') + 10;
4946 // <substitution> ::= S <seq-id> _
4948 // <substitution> ::= Sa # ::std::allocator
4949 // <substitution> ::= Sb # ::std::basic_string
4950 // <substitution> ::= Ss # ::std::basic_string < char,
4951 // ::std::char_traits<char>,
4952 // ::std::allocator<char> >
4953 // <substitution> ::= Si # ::std::basic_istream<char, std::char_traits<char> >
4954 // <substitution> ::= So # ::std::basic_ostream<char, std::char_traits<char> >
4955 // <substitution> ::= Sd # ::std::basic_iostream<char, std::char_traits<char> >
4956 template <typename Derived
, typename Alloc
>
4957 Node
*AbstractManglingParser
<Derived
, Alloc
>::parseSubstitution() {
4958 if (!consumeIf('S'))
4961 if (std::islower(look())) {
4966 SpecialSub
= make
<SpecialSubstitution
>(SpecialSubKind::allocator
);
4970 SpecialSub
= make
<SpecialSubstitution
>(SpecialSubKind::basic_string
);
4974 SpecialSub
= make
<SpecialSubstitution
>(SpecialSubKind::string
);
4978 SpecialSub
= make
<SpecialSubstitution
>(SpecialSubKind::istream
);
4982 SpecialSub
= make
<SpecialSubstitution
>(SpecialSubKind::ostream
);
4986 SpecialSub
= make
<SpecialSubstitution
>(SpecialSubKind::iostream
);
4993 // Itanium C++ ABI 5.1.2: If a name that would use a built-in <substitution>
4994 // has ABI tags, the tags are appended to the substitution; the result is a
4995 // substitutable component.
4996 Node
*WithTags
= getDerived().parseAbiTags(SpecialSub
);
4997 if (WithTags
!= SpecialSub
) {
4998 Subs
.push_back(WithTags
);
4999 SpecialSub
= WithTags
;
5005 if (consumeIf('_')) {
5013 if (parseSeqId(&Index
))
5016 if (!consumeIf('_') || Index
>= Subs
.size())
5021 // <template-param> ::= T_ # first template parameter
5022 // ::= T <parameter-2 non-negative number> _
5023 template <typename Derived
, typename Alloc
>
5024 Node
*AbstractManglingParser
<Derived
, Alloc
>::parseTemplateParam() {
5025 if (!consumeIf('T'))
5029 if (!consumeIf('_')) {
5030 if (parsePositiveInteger(&Index
))
5033 if (!consumeIf('_'))
5037 // Itanium ABI 5.1.8: In a generic lambda, uses of auto in the parameter list
5038 // are mangled as the corresponding artificial template type parameter.
5039 if (ParsingLambdaParams
)
5040 return make
<NameType
>("auto");
5042 // If we're in a context where this <template-param> refers to a
5043 // <template-arg> further ahead in the mangled name (currently just conversion
5044 // operator types), then we should only look it up in the right context.
5045 if (PermitForwardTemplateReferences
) {
5046 Node
*ForwardRef
= make
<ForwardTemplateReference
>(Index
);
5049 assert(ForwardRef
->getKind() == Node::KForwardTemplateReference
);
5050 ForwardTemplateRefs
.push_back(
5051 static_cast<ForwardTemplateReference
*>(ForwardRef
));
5055 if (Index
>= TemplateParams
.size())
5057 return TemplateParams
[Index
];
5060 // <template-arg> ::= <type> # type or template
5061 // ::= X <expression> E # expression
5062 // ::= <expr-primary> # simple expressions
5063 // ::= J <template-arg>* E # argument pack
5064 // ::= LZ <encoding> E # extension
5065 template <typename Derived
, typename Alloc
>
5066 Node
*AbstractManglingParser
<Derived
, Alloc
>::parseTemplateArg() {
5070 Node
*Arg
= getDerived().parseExpr();
5071 if (Arg
== nullptr || !consumeIf('E'))
5077 size_t ArgsBegin
= Names
.size();
5078 while (!consumeIf('E')) {
5079 Node
*Arg
= getDerived().parseTemplateArg();
5082 Names
.push_back(Arg
);
5084 NodeArray Args
= popTrailingNodeArray(ArgsBegin
);
5085 return make
<TemplateArgumentPack
>(Args
);
5088 // ::= LZ <encoding> E # extension
5089 if (look(1) == 'Z') {
5091 Node
*Arg
= getDerived().parseEncoding();
5092 if (Arg
== nullptr || !consumeIf('E'))
5096 // ::= <expr-primary> # simple expressions
5097 return getDerived().parseExprPrimary();
5100 return getDerived().parseType();
5104 // <template-args> ::= I <template-arg>* E
5105 // extension, the abi says <template-arg>+
5106 template <typename Derived
, typename Alloc
>
5108 AbstractManglingParser
<Derived
, Alloc
>::parseTemplateArgs(bool TagTemplates
) {
5109 if (!consumeIf('I'))
5112 // <template-params> refer to the innermost <template-args>. Clear out any
5113 // outer args that we may have inserted into TemplateParams.
5115 TemplateParams
.clear();
5117 size_t ArgsBegin
= Names
.size();
5118 while (!consumeIf('E')) {
5120 auto OldParams
= std::move(TemplateParams
);
5121 Node
*Arg
= getDerived().parseTemplateArg();
5122 TemplateParams
= std::move(OldParams
);
5125 Names
.push_back(Arg
);
5126 Node
*TableEntry
= Arg
;
5127 if (Arg
->getKind() == Node::KTemplateArgumentPack
) {
5128 TableEntry
= make
<ParameterPack
>(
5129 static_cast<TemplateArgumentPack
*>(TableEntry
)->getElements());
5133 TemplateParams
.push_back(TableEntry
);
5135 Node
*Arg
= getDerived().parseTemplateArg();
5138 Names
.push_back(Arg
);
5141 return make
<TemplateArgs
>(popTrailingNodeArray(ArgsBegin
));
5144 // <mangled-name> ::= _Z <encoding>
5146 // extension ::= ___Z <encoding> _block_invoke
5147 // extension ::= ___Z <encoding> _block_invoke<decimal-digit>+
5148 // extension ::= ___Z <encoding> _block_invoke_<decimal-digit>+
5149 template <typename Derived
, typename Alloc
>
5150 Node
*AbstractManglingParser
<Derived
, Alloc
>::parse() {
5151 if (consumeIf("_Z") || consumeIf("__Z")) {
5152 Node
*Encoding
= getDerived().parseEncoding();
5153 if (Encoding
== nullptr)
5155 if (look() == '.') {
5156 Encoding
= make
<DotSuffix
>(Encoding
, StringView(First
, Last
));
5164 if (consumeIf("___Z") || consumeIf("____Z")) {
5165 Node
*Encoding
= getDerived().parseEncoding();
5166 if (Encoding
== nullptr || !consumeIf("_block_invoke"))
5168 bool RequireNumber
= consumeIf('_');
5169 if (parseNumber().empty() && RequireNumber
)
5175 return make
<SpecialName
>("invocation function for block in ", Encoding
);
5178 Node
*Ty
= getDerived().parseType();
5184 template <typename Alloc
>
5185 struct ManglingParser
: AbstractManglingParser
<ManglingParser
<Alloc
>, Alloc
> {
5186 using AbstractManglingParser
<ManglingParser
<Alloc
>,
5187 Alloc
>::AbstractManglingParser
;
5190 DEMANGLE_NAMESPACE_END
5192 #endif // DEMANGLE_ITANIUMDEMANGLE_H