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) \
98 X(LongDoubleLiteral) \
102 DEMANGLE_NAMESPACE_BEGIN
104 // Base class of all AST nodes. The AST is built by the parser, then is
105 // traversed by the printLeft/Right functions to produce a demangled string.
108 enum Kind
: unsigned char {
109 #define ENUMERATOR(NodeKind) K ## NodeKind,
110 FOR_EACH_NODE_KIND(ENUMERATOR
)
114 /// Three-way bool to track a cached value. Unknown is possible if this node
115 /// has an unexpanded parameter pack below it that may affect this cache.
116 enum class Cache
: unsigned char { Yes
, No
, Unknown
, };
121 // FIXME: Make these protected.
123 /// Tracks if this node has a component on its right side, in which case we
124 /// need to call printRight.
125 Cache RHSComponentCache
;
127 /// Track if this node is a (possibly qualified) array type. This can affect
128 /// how we format the output string.
131 /// Track if this node is a (possibly qualified) function type. This can
132 /// affect how we format the output string.
136 Node(Kind K_
, Cache RHSComponentCache_
= Cache::No
,
137 Cache ArrayCache_
= Cache::No
, Cache FunctionCache_
= Cache::No
)
138 : K(K_
), RHSComponentCache(RHSComponentCache_
), ArrayCache(ArrayCache_
),
139 FunctionCache(FunctionCache_
) {}
141 /// Visit the most-derived object corresponding to this object.
142 template<typename Fn
> void visit(Fn F
) const;
144 // The following function is provided by all derived classes:
146 // Call F with arguments that, when passed to the constructor of this node,
147 // would construct an equivalent node.
148 //template<typename Fn> void match(Fn F) const;
150 bool hasRHSComponent(OutputStream
&S
) const {
151 if (RHSComponentCache
!= Cache::Unknown
)
152 return RHSComponentCache
== Cache::Yes
;
153 return hasRHSComponentSlow(S
);
156 bool hasArray(OutputStream
&S
) const {
157 if (ArrayCache
!= Cache::Unknown
)
158 return ArrayCache
== Cache::Yes
;
159 return hasArraySlow(S
);
162 bool hasFunction(OutputStream
&S
) const {
163 if (FunctionCache
!= Cache::Unknown
)
164 return FunctionCache
== Cache::Yes
;
165 return hasFunctionSlow(S
);
168 Kind
getKind() const { return K
; }
170 virtual bool hasRHSComponentSlow(OutputStream
&) const { return false; }
171 virtual bool hasArraySlow(OutputStream
&) const { return false; }
172 virtual bool hasFunctionSlow(OutputStream
&) const { return false; }
174 // Dig through "glue" nodes like ParameterPack and ForwardTemplateReference to
175 // get at a node that actually represents some concrete syntax.
176 virtual const Node
*getSyntaxNode(OutputStream
&) const {
180 void print(OutputStream
&S
) const {
182 if (RHSComponentCache
!= Cache::No
)
186 // Print the "left" side of this Node into OutputStream.
187 virtual void printLeft(OutputStream
&) const = 0;
189 // Print the "right". This distinction is necessary to represent C++ types
190 // that appear on the RHS of their subtype, such as arrays or functions.
191 // Since most types don't have such a component, provide a default
193 virtual void printRight(OutputStream
&) const {}
195 virtual StringView
getBaseName() const { return StringView(); }
197 // Silence compiler warnings, this dtor will never be called.
198 virtual ~Node() = default;
201 DEMANGLE_DUMP_METHOD
void dump() const;
210 NodeArray() : Elements(nullptr), NumElements(0) {}
211 NodeArray(Node
**Elements_
, size_t NumElements_
)
212 : Elements(Elements_
), NumElements(NumElements_
) {}
214 bool empty() const { return NumElements
== 0; }
215 size_t size() const { return NumElements
; }
217 Node
**begin() const { return Elements
; }
218 Node
**end() const { return Elements
+ NumElements
; }
220 Node
*operator[](size_t Idx
) const { return Elements
[Idx
]; }
222 void printWithComma(OutputStream
&S
) const {
223 bool FirstElement
= true;
224 for (size_t Idx
= 0; Idx
!= NumElements
; ++Idx
) {
225 size_t BeforeComma
= S
.getCurrentPosition();
228 size_t AfterComma
= S
.getCurrentPosition();
229 Elements
[Idx
]->print(S
);
231 // Elements[Idx] is an empty parameter pack expansion, we should erase the
232 // comma we just printed.
233 if (AfterComma
== S
.getCurrentPosition()) {
234 S
.setCurrentPosition(BeforeComma
);
238 FirstElement
= false;
243 struct NodeArrayNode
: Node
{
245 NodeArrayNode(NodeArray Array_
) : Node(KNodeArrayNode
), Array(Array_
) {}
247 template<typename Fn
> void match(Fn F
) const { F(Array
); }
249 void printLeft(OutputStream
&S
) const override
{
250 Array
.printWithComma(S
);
254 class DotSuffix final
: public Node
{
256 const StringView Suffix
;
259 DotSuffix(const Node
*Prefix_
, StringView Suffix_
)
260 : Node(KDotSuffix
), Prefix(Prefix_
), Suffix(Suffix_
) {}
262 template<typename Fn
> void match(Fn F
) const { F(Prefix
, Suffix
); }
264 void printLeft(OutputStream
&s
) const override
{
272 class VendorExtQualType final
: public Node
{
277 VendorExtQualType(const Node
*Ty_
, StringView Ext_
)
278 : Node(KVendorExtQualType
), Ty(Ty_
), Ext(Ext_
) {}
280 template<typename Fn
> void match(Fn F
) const { F(Ty
, Ext
); }
282 void printLeft(OutputStream
&S
) const override
{
289 enum FunctionRefQual
: unsigned char {
302 inline Qualifiers
operator|=(Qualifiers
&Q1
, Qualifiers Q2
) {
303 return Q1
= static_cast<Qualifiers
>(Q1
| Q2
);
306 class QualType
: public Node
{
308 const Qualifiers Quals
;
311 void printQuals(OutputStream
&S
) const {
312 if (Quals
& QualConst
)
314 if (Quals
& QualVolatile
)
316 if (Quals
& QualRestrict
)
321 QualType(const Node
*Child_
, Qualifiers Quals_
)
322 : Node(KQualType
, Child_
->RHSComponentCache
,
323 Child_
->ArrayCache
, Child_
->FunctionCache
),
324 Quals(Quals_
), Child(Child_
) {}
326 template<typename Fn
> void match(Fn F
) const { F(Child
, Quals
); }
328 bool hasRHSComponentSlow(OutputStream
&S
) const override
{
329 return Child
->hasRHSComponent(S
);
331 bool hasArraySlow(OutputStream
&S
) const override
{
332 return Child
->hasArray(S
);
334 bool hasFunctionSlow(OutputStream
&S
) const override
{
335 return Child
->hasFunction(S
);
338 void printLeft(OutputStream
&S
) const override
{
343 void printRight(OutputStream
&S
) const override
{ Child
->printRight(S
); }
346 class ConversionOperatorType final
: public Node
{
350 ConversionOperatorType(const Node
*Ty_
)
351 : Node(KConversionOperatorType
), Ty(Ty_
) {}
353 template<typename Fn
> void match(Fn F
) const { F(Ty
); }
355 void printLeft(OutputStream
&S
) const override
{
361 class PostfixQualifiedType final
: public Node
{
363 const StringView Postfix
;
366 PostfixQualifiedType(Node
*Ty_
, StringView Postfix_
)
367 : Node(KPostfixQualifiedType
), Ty(Ty_
), Postfix(Postfix_
) {}
369 template<typename Fn
> void match(Fn F
) const { F(Ty
, Postfix
); }
371 void printLeft(OutputStream
&s
) const override
{
377 class NameType final
: public Node
{
378 const StringView Name
;
381 NameType(StringView Name_
) : Node(KNameType
), Name(Name_
) {}
383 template<typename Fn
> void match(Fn F
) const { F(Name
); }
385 StringView
getName() const { return Name
; }
386 StringView
getBaseName() const override
{ return Name
; }
388 void printLeft(OutputStream
&s
) const override
{ s
+= Name
; }
391 class ElaboratedTypeSpefType
: public Node
{
395 ElaboratedTypeSpefType(StringView Kind_
, Node
*Child_
)
396 : Node(KElaboratedTypeSpefType
), Kind(Kind_
), Child(Child_
) {}
398 template<typename Fn
> void match(Fn F
) const { F(Kind
, Child
); }
400 void printLeft(OutputStream
&S
) const override
{
407 struct AbiTagAttr
: Node
{
411 AbiTagAttr(Node
* Base_
, StringView Tag_
)
412 : Node(KAbiTagAttr
, Base_
->RHSComponentCache
,
413 Base_
->ArrayCache
, Base_
->FunctionCache
),
414 Base(Base_
), Tag(Tag_
) {}
416 template<typename Fn
> void match(Fn F
) const { F(Base
, Tag
); }
418 void printLeft(OutputStream
&S
) const override
{
426 class EnableIfAttr
: public Node
{
427 NodeArray Conditions
;
429 EnableIfAttr(NodeArray Conditions_
)
430 : Node(KEnableIfAttr
), Conditions(Conditions_
) {}
432 template<typename Fn
> void match(Fn F
) const { F(Conditions
); }
434 void printLeft(OutputStream
&S
) const override
{
436 Conditions
.printWithComma(S
);
441 class ObjCProtoName
: public Node
{
445 friend class PointerType
;
448 ObjCProtoName(const Node
*Ty_
, StringView Protocol_
)
449 : Node(KObjCProtoName
), Ty(Ty_
), Protocol(Protocol_
) {}
451 template<typename Fn
> void match(Fn F
) const { F(Ty
, Protocol
); }
453 bool isObjCObject() const {
454 return Ty
->getKind() == KNameType
&&
455 static_cast<const NameType
*>(Ty
)->getName() == "objc_object";
458 void printLeft(OutputStream
&S
) const override
{
466 class PointerType final
: public Node
{
470 PointerType(const Node
*Pointee_
)
471 : Node(KPointerType
, Pointee_
->RHSComponentCache
),
474 template<typename Fn
> void match(Fn F
) const { F(Pointee
); }
476 bool hasRHSComponentSlow(OutputStream
&S
) const override
{
477 return Pointee
->hasRHSComponent(S
);
480 void printLeft(OutputStream
&s
) const override
{
481 // We rewrite objc_object<SomeProtocol>* into id<SomeProtocol>.
482 if (Pointee
->getKind() != KObjCProtoName
||
483 !static_cast<const ObjCProtoName
*>(Pointee
)->isObjCObject()) {
484 Pointee
->printLeft(s
);
485 if (Pointee
->hasArray(s
))
487 if (Pointee
->hasArray(s
) || Pointee
->hasFunction(s
))
491 const auto *objcProto
= static_cast<const ObjCProtoName
*>(Pointee
);
493 s
+= objcProto
->Protocol
;
498 void printRight(OutputStream
&s
) const override
{
499 if (Pointee
->getKind() != KObjCProtoName
||
500 !static_cast<const ObjCProtoName
*>(Pointee
)->isObjCObject()) {
501 if (Pointee
->hasArray(s
) || Pointee
->hasFunction(s
))
503 Pointee
->printRight(s
);
508 enum class ReferenceKind
{
513 // Represents either a LValue or an RValue reference type.
514 class ReferenceType
: public Node
{
518 mutable bool Printing
= false;
520 // Dig through any refs to refs, collapsing the ReferenceTypes as we go. The
521 // rule here is rvalue ref to rvalue ref collapses to a rvalue ref, and any
522 // other combination collapses to a lvalue ref.
523 std::pair
<ReferenceKind
, const Node
*> collapse(OutputStream
&S
) const {
524 auto SoFar
= std::make_pair(RK
, Pointee
);
526 const Node
*SN
= SoFar
.second
->getSyntaxNode(S
);
527 if (SN
->getKind() != KReferenceType
)
529 auto *RT
= static_cast<const ReferenceType
*>(SN
);
530 SoFar
.second
= RT
->Pointee
;
531 SoFar
.first
= std::min(SoFar
.first
, RT
->RK
);
537 ReferenceType(const Node
*Pointee_
, ReferenceKind RK_
)
538 : Node(KReferenceType
, Pointee_
->RHSComponentCache
),
539 Pointee(Pointee_
), RK(RK_
) {}
541 template<typename Fn
> void match(Fn F
) const { F(Pointee
, RK
); }
543 bool hasRHSComponentSlow(OutputStream
&S
) const override
{
544 return Pointee
->hasRHSComponent(S
);
547 void printLeft(OutputStream
&s
) const override
{
550 SwapAndRestore
<bool> SavePrinting(Printing
, true);
551 std::pair
<ReferenceKind
, const Node
*> Collapsed
= collapse(s
);
552 Collapsed
.second
->printLeft(s
);
553 if (Collapsed
.second
->hasArray(s
))
555 if (Collapsed
.second
->hasArray(s
) || Collapsed
.second
->hasFunction(s
))
558 s
+= (Collapsed
.first
== ReferenceKind::LValue
? "&" : "&&");
560 void printRight(OutputStream
&s
) const override
{
563 SwapAndRestore
<bool> SavePrinting(Printing
, true);
564 std::pair
<ReferenceKind
, const Node
*> Collapsed
= collapse(s
);
565 if (Collapsed
.second
->hasArray(s
) || Collapsed
.second
->hasFunction(s
))
567 Collapsed
.second
->printRight(s
);
571 class PointerToMemberType final
: public Node
{
572 const Node
*ClassType
;
573 const Node
*MemberType
;
576 PointerToMemberType(const Node
*ClassType_
, const Node
*MemberType_
)
577 : Node(KPointerToMemberType
, MemberType_
->RHSComponentCache
),
578 ClassType(ClassType_
), MemberType(MemberType_
) {}
580 template<typename Fn
> void match(Fn F
) const { F(ClassType
, MemberType
); }
582 bool hasRHSComponentSlow(OutputStream
&S
) const override
{
583 return MemberType
->hasRHSComponent(S
);
586 void printLeft(OutputStream
&s
) const override
{
587 MemberType
->printLeft(s
);
588 if (MemberType
->hasArray(s
) || MemberType
->hasFunction(s
))
596 void printRight(OutputStream
&s
) const override
{
597 if (MemberType
->hasArray(s
) || MemberType
->hasFunction(s
))
599 MemberType
->printRight(s
);
608 /* implicit */ NodeOrString(StringView Str
) {
609 const char *FirstChar
= Str
.begin();
610 const char *SecondChar
= Str
.end();
611 if (SecondChar
== nullptr) {
612 assert(FirstChar
== SecondChar
);
613 ++FirstChar
, ++SecondChar
;
615 First
= static_cast<const void *>(FirstChar
);
616 Second
= static_cast<const void *>(SecondChar
);
619 /* implicit */ NodeOrString(Node
*N
)
620 : First(static_cast<const void *>(N
)), Second(nullptr) {}
621 NodeOrString() : First(nullptr), Second(nullptr) {}
623 bool isString() const { return Second
&& First
; }
624 bool isNode() const { return First
&& !Second
; }
625 bool isEmpty() const { return !First
&& !Second
; }
627 StringView
asString() const {
629 return StringView(static_cast<const char *>(First
),
630 static_cast<const char *>(Second
));
633 const Node
*asNode() const {
635 return static_cast<const Node
*>(First
);
639 class ArrayType final
: public Node
{
641 NodeOrString Dimension
;
644 ArrayType(const Node
*Base_
, NodeOrString Dimension_
)
646 /*RHSComponentCache=*/Cache::Yes
,
647 /*ArrayCache=*/Cache::Yes
),
648 Base(Base_
), Dimension(Dimension_
) {}
650 template<typename Fn
> void match(Fn F
) const { F(Base
, Dimension
); }
652 bool hasRHSComponentSlow(OutputStream
&) const override
{ return true; }
653 bool hasArraySlow(OutputStream
&) const override
{ return true; }
655 void printLeft(OutputStream
&S
) const override
{ Base
->printLeft(S
); }
657 void printRight(OutputStream
&S
) const override
{
661 if (Dimension
.isString())
662 S
+= Dimension
.asString();
663 else if (Dimension
.isNode())
664 Dimension
.asNode()->print(S
);
670 class FunctionType final
: public Node
{
674 FunctionRefQual RefQual
;
675 const Node
*ExceptionSpec
;
678 FunctionType(const Node
*Ret_
, NodeArray Params_
, Qualifiers CVQuals_
,
679 FunctionRefQual RefQual_
, const Node
*ExceptionSpec_
)
680 : Node(KFunctionType
,
681 /*RHSComponentCache=*/Cache::Yes
, /*ArrayCache=*/Cache::No
,
682 /*FunctionCache=*/Cache::Yes
),
683 Ret(Ret_
), Params(Params_
), CVQuals(CVQuals_
), RefQual(RefQual_
),
684 ExceptionSpec(ExceptionSpec_
) {}
686 template<typename Fn
> void match(Fn F
) const {
687 F(Ret
, Params
, CVQuals
, RefQual
, ExceptionSpec
);
690 bool hasRHSComponentSlow(OutputStream
&) const override
{ return true; }
691 bool hasFunctionSlow(OutputStream
&) const override
{ return true; }
693 // Handle C++'s ... quirky decl grammar by using the left & right
694 // distinction. Consider:
695 // int (*f(float))(char) {}
696 // f is a function that takes a float and returns a pointer to a function
697 // that takes a char and returns an int. If we're trying to print f, start
698 // by printing out the return types's left, then print our parameters, then
699 // finally print right of the return type.
700 void printLeft(OutputStream
&S
) const override
{
705 void printRight(OutputStream
&S
) const override
{
707 Params
.printWithComma(S
);
711 if (CVQuals
& QualConst
)
713 if (CVQuals
& QualVolatile
)
715 if (CVQuals
& QualRestrict
)
718 if (RefQual
== FrefQualLValue
)
720 else if (RefQual
== FrefQualRValue
)
723 if (ExceptionSpec
!= nullptr) {
725 ExceptionSpec
->print(S
);
730 class NoexceptSpec
: public Node
{
733 NoexceptSpec(const Node
*E_
) : Node(KNoexceptSpec
), E(E_
) {}
735 template<typename Fn
> void match(Fn F
) const { F(E
); }
737 void printLeft(OutputStream
&S
) const override
{
744 class DynamicExceptionSpec
: public Node
{
747 DynamicExceptionSpec(NodeArray Types_
)
748 : Node(KDynamicExceptionSpec
), Types(Types_
) {}
750 template<typename Fn
> void match(Fn F
) const { F(Types
); }
752 void printLeft(OutputStream
&S
) const override
{
754 Types
.printWithComma(S
);
759 class FunctionEncoding final
: public Node
{
765 FunctionRefQual RefQual
;
768 FunctionEncoding(const Node
*Ret_
, const Node
*Name_
, NodeArray Params_
,
769 const Node
*Attrs_
, Qualifiers CVQuals_
,
770 FunctionRefQual RefQual_
)
771 : Node(KFunctionEncoding
,
772 /*RHSComponentCache=*/Cache::Yes
, /*ArrayCache=*/Cache::No
,
773 /*FunctionCache=*/Cache::Yes
),
774 Ret(Ret_
), Name(Name_
), Params(Params_
), Attrs(Attrs_
),
775 CVQuals(CVQuals_
), RefQual(RefQual_
) {}
777 template<typename Fn
> void match(Fn F
) const {
778 F(Ret
, Name
, Params
, Attrs
, CVQuals
, RefQual
);
781 Qualifiers
getCVQuals() const { return CVQuals
; }
782 FunctionRefQual
getRefQual() const { return RefQual
; }
783 NodeArray
getParams() const { return Params
; }
784 const Node
*getReturnType() const { return Ret
; }
786 bool hasRHSComponentSlow(OutputStream
&) const override
{ return true; }
787 bool hasFunctionSlow(OutputStream
&) const override
{ return true; }
789 const Node
*getName() const { return Name
; }
791 void printLeft(OutputStream
&S
) const override
{
794 if (!Ret
->hasRHSComponent(S
))
800 void printRight(OutputStream
&S
) const override
{
802 Params
.printWithComma(S
);
807 if (CVQuals
& QualConst
)
809 if (CVQuals
& QualVolatile
)
811 if (CVQuals
& QualRestrict
)
814 if (RefQual
== FrefQualLValue
)
816 else if (RefQual
== FrefQualRValue
)
819 if (Attrs
!= nullptr)
824 class LiteralOperator
: public Node
{
828 LiteralOperator(const Node
*OpName_
)
829 : Node(KLiteralOperator
), OpName(OpName_
) {}
831 template<typename Fn
> void match(Fn F
) const { F(OpName
); }
833 void printLeft(OutputStream
&S
) const override
{
834 S
+= "operator\"\" ";
839 class SpecialName final
: public Node
{
840 const StringView Special
;
844 SpecialName(StringView Special_
, const Node
*Child_
)
845 : Node(KSpecialName
), Special(Special_
), Child(Child_
) {}
847 template<typename Fn
> void match(Fn F
) const { F(Special
, Child
); }
849 void printLeft(OutputStream
&S
) const override
{
855 class CtorVtableSpecialName final
: public Node
{
856 const Node
*FirstType
;
857 const Node
*SecondType
;
860 CtorVtableSpecialName(const Node
*FirstType_
, const Node
*SecondType_
)
861 : Node(KCtorVtableSpecialName
),
862 FirstType(FirstType_
), SecondType(SecondType_
) {}
864 template<typename Fn
> void match(Fn F
) const { F(FirstType
, SecondType
); }
866 void printLeft(OutputStream
&S
) const override
{
867 S
+= "construction vtable for ";
870 SecondType
->print(S
);
874 struct NestedName
: Node
{
878 NestedName(Node
*Qual_
, Node
*Name_
)
879 : Node(KNestedName
), Qual(Qual_
), Name(Name_
) {}
881 template<typename Fn
> void match(Fn F
) const { F(Qual
, Name
); }
883 StringView
getBaseName() const override
{ return Name
->getBaseName(); }
885 void printLeft(OutputStream
&S
) const override
{
892 struct LocalName
: Node
{
896 LocalName(Node
*Encoding_
, Node
*Entity_
)
897 : Node(KLocalName
), Encoding(Encoding_
), Entity(Entity_
) {}
899 template<typename Fn
> void match(Fn F
) const { F(Encoding
, Entity
); }
901 void printLeft(OutputStream
&S
) const override
{
908 class QualifiedName final
: public Node
{
910 const Node
*Qualifier
;
914 QualifiedName(const Node
*Qualifier_
, const Node
*Name_
)
915 : Node(KQualifiedName
), Qualifier(Qualifier_
), Name(Name_
) {}
917 template<typename Fn
> void match(Fn F
) const { F(Qualifier
, Name
); }
919 StringView
getBaseName() const override
{ return Name
->getBaseName(); }
921 void printLeft(OutputStream
&S
) const override
{
928 class VectorType final
: public Node
{
929 const Node
*BaseType
;
930 const NodeOrString Dimension
;
933 VectorType(const Node
*BaseType_
, NodeOrString Dimension_
)
934 : Node(KVectorType
), BaseType(BaseType_
),
935 Dimension(Dimension_
) {}
937 template<typename Fn
> void match(Fn F
) const { F(BaseType
, Dimension
); }
939 void printLeft(OutputStream
&S
) const override
{
942 if (Dimension
.isNode())
943 Dimension
.asNode()->print(S
);
944 else if (Dimension
.isString())
945 S
+= Dimension
.asString();
950 class PixelVectorType final
: public Node
{
951 const NodeOrString Dimension
;
954 PixelVectorType(NodeOrString Dimension_
)
955 : Node(KPixelVectorType
), Dimension(Dimension_
) {}
957 template<typename Fn
> void match(Fn F
) const { F(Dimension
); }
959 void printLeft(OutputStream
&S
) const override
{
960 // FIXME: This should demangle as "vector pixel".
961 S
+= "pixel vector[";
962 S
+= Dimension
.asString();
967 /// An unexpanded parameter pack (either in the expression or type context). If
968 /// this AST is correct, this node will have a ParameterPackExpansion node above
971 /// This node is created when some <template-args> are found that apply to an
972 /// <encoding>, and is stored in the TemplateParams table. In order for this to
973 /// appear in the final AST, it has to referenced via a <template-param> (ie,
975 class ParameterPack final
: public Node
{
978 // Setup OutputStream for a pack expansion unless we're already expanding one.
979 void initializePackExpansion(OutputStream
&S
) const {
980 if (S
.CurrentPackMax
== std::numeric_limits
<unsigned>::max()) {
981 S
.CurrentPackMax
= static_cast<unsigned>(Data
.size());
982 S
.CurrentPackIndex
= 0;
987 ParameterPack(NodeArray Data_
) : Node(KParameterPack
), Data(Data_
) {
988 ArrayCache
= FunctionCache
= RHSComponentCache
= Cache::Unknown
;
989 if (std::all_of(Data
.begin(), Data
.end(), [](Node
* P
) {
990 return P
->ArrayCache
== Cache::No
;
992 ArrayCache
= Cache::No
;
993 if (std::all_of(Data
.begin(), Data
.end(), [](Node
* P
) {
994 return P
->FunctionCache
== Cache::No
;
996 FunctionCache
= Cache::No
;
997 if (std::all_of(Data
.begin(), Data
.end(), [](Node
* P
) {
998 return P
->RHSComponentCache
== Cache::No
;
1000 RHSComponentCache
= Cache::No
;
1003 template<typename Fn
> void match(Fn F
) const { F(Data
); }
1005 bool hasRHSComponentSlow(OutputStream
&S
) const override
{
1006 initializePackExpansion(S
);
1007 size_t Idx
= S
.CurrentPackIndex
;
1008 return Idx
< Data
.size() && Data
[Idx
]->hasRHSComponent(S
);
1010 bool hasArraySlow(OutputStream
&S
) const override
{
1011 initializePackExpansion(S
);
1012 size_t Idx
= S
.CurrentPackIndex
;
1013 return Idx
< Data
.size() && Data
[Idx
]->hasArray(S
);
1015 bool hasFunctionSlow(OutputStream
&S
) const override
{
1016 initializePackExpansion(S
);
1017 size_t Idx
= S
.CurrentPackIndex
;
1018 return Idx
< Data
.size() && Data
[Idx
]->hasFunction(S
);
1020 const Node
*getSyntaxNode(OutputStream
&S
) const override
{
1021 initializePackExpansion(S
);
1022 size_t Idx
= S
.CurrentPackIndex
;
1023 return Idx
< Data
.size() ? Data
[Idx
]->getSyntaxNode(S
) : this;
1026 void printLeft(OutputStream
&S
) const override
{
1027 initializePackExpansion(S
);
1028 size_t Idx
= S
.CurrentPackIndex
;
1029 if (Idx
< Data
.size())
1030 Data
[Idx
]->printLeft(S
);
1032 void printRight(OutputStream
&S
) const override
{
1033 initializePackExpansion(S
);
1034 size_t Idx
= S
.CurrentPackIndex
;
1035 if (Idx
< Data
.size())
1036 Data
[Idx
]->printRight(S
);
1040 /// A variadic template argument. This node represents an occurrence of
1041 /// J<something>E in some <template-args>. It isn't itself unexpanded, unless
1042 /// one of it's Elements is. The parser inserts a ParameterPack into the
1043 /// TemplateParams table if the <template-args> this pack belongs to apply to an
1045 class TemplateArgumentPack final
: public Node
{
1048 TemplateArgumentPack(NodeArray Elements_
)
1049 : Node(KTemplateArgumentPack
), Elements(Elements_
) {}
1051 template<typename Fn
> void match(Fn F
) const { F(Elements
); }
1053 NodeArray
getElements() const { return Elements
; }
1055 void printLeft(OutputStream
&S
) const override
{
1056 Elements
.printWithComma(S
);
1060 /// A pack expansion. Below this node, there are some unexpanded ParameterPacks
1061 /// which each have Child->ParameterPackSize elements.
1062 class ParameterPackExpansion final
: public Node
{
1066 ParameterPackExpansion(const Node
*Child_
)
1067 : Node(KParameterPackExpansion
), Child(Child_
) {}
1069 template<typename Fn
> void match(Fn F
) const { F(Child
); }
1071 const Node
*getChild() const { return Child
; }
1073 void printLeft(OutputStream
&S
) const override
{
1074 constexpr unsigned Max
= std::numeric_limits
<unsigned>::max();
1075 SwapAndRestore
<unsigned> SavePackIdx(S
.CurrentPackIndex
, Max
);
1076 SwapAndRestore
<unsigned> SavePackMax(S
.CurrentPackMax
, Max
);
1077 size_t StreamPos
= S
.getCurrentPosition();
1079 // Print the first element in the pack. If Child contains a ParameterPack,
1080 // it will set up S.CurrentPackMax and print the first element.
1083 // No ParameterPack was found in Child. This can occur if we've found a pack
1084 // expansion on a <function-param>.
1085 if (S
.CurrentPackMax
== Max
) {
1090 // We found a ParameterPack, but it has no elements. Erase whatever we may
1092 if (S
.CurrentPackMax
== 0) {
1093 S
.setCurrentPosition(StreamPos
);
1097 // Else, iterate through the rest of the elements in the pack.
1098 for (unsigned I
= 1, E
= S
.CurrentPackMax
; I
< E
; ++I
) {
1100 S
.CurrentPackIndex
= I
;
1106 class TemplateArgs final
: public Node
{
1110 TemplateArgs(NodeArray Params_
) : Node(KTemplateArgs
), Params(Params_
) {}
1112 template<typename Fn
> void match(Fn F
) const { F(Params
); }
1114 NodeArray
getParams() { return Params
; }
1116 void printLeft(OutputStream
&S
) const override
{
1118 Params
.printWithComma(S
);
1119 if (S
.back() == '>')
1125 /// A forward-reference to a template argument that was not known at the point
1126 /// where the template parameter name was parsed in a mangling.
1128 /// This is created when demangling the name of a specialization of a
1129 /// conversion function template:
1133 /// template<typename T> operator T*();
1137 /// When demangling a specialization of the conversion function template, we
1138 /// encounter the name of the template (including the \c T) before we reach
1139 /// the template argument list, so we cannot substitute the parameter name
1140 /// for the corresponding argument while parsing. Instead, we create a
1141 /// \c ForwardTemplateReference node that is resolved after we parse the
1142 /// template arguments.
1143 struct ForwardTemplateReference
: Node
{
1145 Node
*Ref
= nullptr;
1147 // If we're currently printing this node. It is possible (though invalid) for
1148 // a forward template reference to refer to itself via a substitution. This
1149 // creates a cyclic AST, which will stack overflow printing. To fix this, bail
1150 // out if more than one print* function is active.
1151 mutable bool Printing
= false;
1153 ForwardTemplateReference(size_t Index_
)
1154 : Node(KForwardTemplateReference
, Cache::Unknown
, Cache::Unknown
,
1158 // We don't provide a matcher for these, because the value of the node is
1159 // not determined by its construction parameters, and it generally needs
1160 // special handling.
1161 template<typename Fn
> void match(Fn F
) const = delete;
1163 bool hasRHSComponentSlow(OutputStream
&S
) const override
{
1166 SwapAndRestore
<bool> SavePrinting(Printing
, true);
1167 return Ref
->hasRHSComponent(S
);
1169 bool hasArraySlow(OutputStream
&S
) const override
{
1172 SwapAndRestore
<bool> SavePrinting(Printing
, true);
1173 return Ref
->hasArray(S
);
1175 bool hasFunctionSlow(OutputStream
&S
) const override
{
1178 SwapAndRestore
<bool> SavePrinting(Printing
, true);
1179 return Ref
->hasFunction(S
);
1181 const Node
*getSyntaxNode(OutputStream
&S
) const override
{
1184 SwapAndRestore
<bool> SavePrinting(Printing
, true);
1185 return Ref
->getSyntaxNode(S
);
1188 void printLeft(OutputStream
&S
) const override
{
1191 SwapAndRestore
<bool> SavePrinting(Printing
, true);
1194 void printRight(OutputStream
&S
) const override
{
1197 SwapAndRestore
<bool> SavePrinting(Printing
, true);
1202 struct NameWithTemplateArgs
: Node
{
1203 // name<template_args>
1207 NameWithTemplateArgs(Node
*Name_
, Node
*TemplateArgs_
)
1208 : Node(KNameWithTemplateArgs
), Name(Name_
), TemplateArgs(TemplateArgs_
) {}
1210 template<typename Fn
> void match(Fn F
) const { F(Name
, TemplateArgs
); }
1212 StringView
getBaseName() const override
{ return Name
->getBaseName(); }
1214 void printLeft(OutputStream
&S
) const override
{
1216 TemplateArgs
->print(S
);
1220 class GlobalQualifiedName final
: public Node
{
1224 GlobalQualifiedName(Node
* Child_
)
1225 : Node(KGlobalQualifiedName
), Child(Child_
) {}
1227 template<typename Fn
> void match(Fn F
) const { F(Child
); }
1229 StringView
getBaseName() const override
{ return Child
->getBaseName(); }
1231 void printLeft(OutputStream
&S
) const override
{
1237 struct StdQualifiedName
: Node
{
1240 StdQualifiedName(Node
*Child_
) : Node(KStdQualifiedName
), Child(Child_
) {}
1242 template<typename Fn
> void match(Fn F
) const { F(Child
); }
1244 StringView
getBaseName() const override
{ return Child
->getBaseName(); }
1246 void printLeft(OutputStream
&S
) const override
{
1252 enum class SpecialSubKind
{
1261 class ExpandedSpecialSubstitution final
: public Node
{
1265 ExpandedSpecialSubstitution(SpecialSubKind SSK_
)
1266 : Node(KExpandedSpecialSubstitution
), SSK(SSK_
) {}
1268 template<typename Fn
> void match(Fn F
) const { F(SSK
); }
1270 StringView
getBaseName() const override
{
1272 case SpecialSubKind::allocator
:
1273 return StringView("allocator");
1274 case SpecialSubKind::basic_string
:
1275 return StringView("basic_string");
1276 case SpecialSubKind::string
:
1277 return StringView("basic_string");
1278 case SpecialSubKind::istream
:
1279 return StringView("basic_istream");
1280 case SpecialSubKind::ostream
:
1281 return StringView("basic_ostream");
1282 case SpecialSubKind::iostream
:
1283 return StringView("basic_iostream");
1285 DEMANGLE_UNREACHABLE
;
1288 void printLeft(OutputStream
&S
) const override
{
1290 case SpecialSubKind::allocator
:
1291 S
+= "std::allocator";
1293 case SpecialSubKind::basic_string
:
1294 S
+= "std::basic_string";
1296 case SpecialSubKind::string
:
1297 S
+= "std::basic_string<char, std::char_traits<char>, "
1298 "std::allocator<char> >";
1300 case SpecialSubKind::istream
:
1301 S
+= "std::basic_istream<char, std::char_traits<char> >";
1303 case SpecialSubKind::ostream
:
1304 S
+= "std::basic_ostream<char, std::char_traits<char> >";
1306 case SpecialSubKind::iostream
:
1307 S
+= "std::basic_iostream<char, std::char_traits<char> >";
1313 class SpecialSubstitution final
: public Node
{
1317 SpecialSubstitution(SpecialSubKind SSK_
)
1318 : Node(KSpecialSubstitution
), SSK(SSK_
) {}
1320 template<typename Fn
> void match(Fn F
) const { F(SSK
); }
1322 StringView
getBaseName() const override
{
1324 case SpecialSubKind::allocator
:
1325 return StringView("allocator");
1326 case SpecialSubKind::basic_string
:
1327 return StringView("basic_string");
1328 case SpecialSubKind::string
:
1329 return StringView("string");
1330 case SpecialSubKind::istream
:
1331 return StringView("istream");
1332 case SpecialSubKind::ostream
:
1333 return StringView("ostream");
1334 case SpecialSubKind::iostream
:
1335 return StringView("iostream");
1337 DEMANGLE_UNREACHABLE
;
1340 void printLeft(OutputStream
&S
) const override
{
1342 case SpecialSubKind::allocator
:
1343 S
+= "std::allocator";
1345 case SpecialSubKind::basic_string
:
1346 S
+= "std::basic_string";
1348 case SpecialSubKind::string
:
1351 case SpecialSubKind::istream
:
1352 S
+= "std::istream";
1354 case SpecialSubKind::ostream
:
1355 S
+= "std::ostream";
1357 case SpecialSubKind::iostream
:
1358 S
+= "std::iostream";
1364 class CtorDtorName final
: public Node
{
1365 const Node
*Basename
;
1370 CtorDtorName(const Node
*Basename_
, bool IsDtor_
, int Variant_
)
1371 : Node(KCtorDtorName
), Basename(Basename_
), IsDtor(IsDtor_
),
1372 Variant(Variant_
) {}
1374 template<typename Fn
> void match(Fn F
) const { F(Basename
, IsDtor
, Variant
); }
1376 void printLeft(OutputStream
&S
) const override
{
1379 S
+= Basename
->getBaseName();
1383 class DtorName
: public Node
{
1387 DtorName(const Node
*Base_
) : Node(KDtorName
), Base(Base_
) {}
1389 template<typename Fn
> void match(Fn F
) const { F(Base
); }
1391 void printLeft(OutputStream
&S
) const override
{
1397 class UnnamedTypeName
: public Node
{
1398 const StringView Count
;
1401 UnnamedTypeName(StringView Count_
) : Node(KUnnamedTypeName
), Count(Count_
) {}
1403 template<typename Fn
> void match(Fn F
) const { F(Count
); }
1405 void printLeft(OutputStream
&S
) const override
{
1412 class ClosureTypeName
: public Node
{
1417 ClosureTypeName(NodeArray Params_
, StringView Count_
)
1418 : Node(KClosureTypeName
), Params(Params_
), Count(Count_
) {}
1420 template<typename Fn
> void match(Fn F
) const { F(Params
, Count
); }
1422 void printLeft(OutputStream
&S
) const override
{
1426 Params
.printWithComma(S
);
1431 class StructuredBindingName
: public Node
{
1434 StructuredBindingName(NodeArray Bindings_
)
1435 : Node(KStructuredBindingName
), Bindings(Bindings_
) {}
1437 template<typename Fn
> void match(Fn F
) const { F(Bindings
); }
1439 void printLeft(OutputStream
&S
) const override
{
1441 Bindings
.printWithComma(S
);
1446 // -- Expression Nodes --
1448 class BinaryExpr
: public Node
{
1450 const StringView InfixOperator
;
1454 BinaryExpr(const Node
*LHS_
, StringView InfixOperator_
, const Node
*RHS_
)
1455 : Node(KBinaryExpr
), LHS(LHS_
), InfixOperator(InfixOperator_
), RHS(RHS_
) {
1458 template<typename Fn
> void match(Fn F
) const { F(LHS
, InfixOperator
, RHS
); }
1460 void printLeft(OutputStream
&S
) const override
{
1461 // might be a template argument expression, then we need to disambiguate
1463 if (InfixOperator
== ">")
1474 if (InfixOperator
== ">")
1479 class ArraySubscriptExpr
: public Node
{
1484 ArraySubscriptExpr(const Node
*Op1_
, const Node
*Op2_
)
1485 : Node(KArraySubscriptExpr
), Op1(Op1_
), Op2(Op2_
) {}
1487 template<typename Fn
> void match(Fn F
) const { F(Op1
, Op2
); }
1489 void printLeft(OutputStream
&S
) const override
{
1498 class PostfixExpr
: public Node
{
1500 const StringView Operator
;
1503 PostfixExpr(const Node
*Child_
, StringView Operator_
)
1504 : Node(KPostfixExpr
), Child(Child_
), Operator(Operator_
) {}
1506 template<typename Fn
> void match(Fn F
) const { F(Child
, Operator
); }
1508 void printLeft(OutputStream
&S
) const override
{
1516 class ConditionalExpr
: public Node
{
1522 ConditionalExpr(const Node
*Cond_
, const Node
*Then_
, const Node
*Else_
)
1523 : Node(KConditionalExpr
), Cond(Cond_
), Then(Then_
), Else(Else_
) {}
1525 template<typename Fn
> void match(Fn F
) const { F(Cond
, Then
, Else
); }
1527 void printLeft(OutputStream
&S
) const override
{
1538 class MemberExpr
: public Node
{
1540 const StringView Kind
;
1544 MemberExpr(const Node
*LHS_
, StringView Kind_
, const Node
*RHS_
)
1545 : Node(KMemberExpr
), LHS(LHS_
), Kind(Kind_
), RHS(RHS_
) {}
1547 template<typename Fn
> void match(Fn F
) const { F(LHS
, Kind
, RHS
); }
1549 void printLeft(OutputStream
&S
) const override
{
1556 class EnclosingExpr
: public Node
{
1557 const StringView Prefix
;
1559 const StringView Postfix
;
1562 EnclosingExpr(StringView Prefix_
, Node
*Infix_
, StringView Postfix_
)
1563 : Node(KEnclosingExpr
), Prefix(Prefix_
), Infix(Infix_
),
1564 Postfix(Postfix_
) {}
1566 template<typename Fn
> void match(Fn F
) const { F(Prefix
, Infix
, Postfix
); }
1568 void printLeft(OutputStream
&S
) const override
{
1575 class CastExpr
: public Node
{
1576 // cast_kind<to>(from)
1577 const StringView CastKind
;
1582 CastExpr(StringView CastKind_
, const Node
*To_
, const Node
*From_
)
1583 : Node(KCastExpr
), CastKind(CastKind_
), To(To_
), From(From_
) {}
1585 template<typename Fn
> void match(Fn F
) const { F(CastKind
, To
, From
); }
1587 void printLeft(OutputStream
&S
) const override
{
1597 class SizeofParamPackExpr
: public Node
{
1601 SizeofParamPackExpr(const Node
*Pack_
)
1602 : Node(KSizeofParamPackExpr
), Pack(Pack_
) {}
1604 template<typename Fn
> void match(Fn F
) const { F(Pack
); }
1606 void printLeft(OutputStream
&S
) const override
{
1608 ParameterPackExpansion
PPE(Pack
);
1614 class CallExpr
: public Node
{
1619 CallExpr(const Node
*Callee_
, NodeArray Args_
)
1620 : Node(KCallExpr
), Callee(Callee_
), Args(Args_
) {}
1622 template<typename Fn
> void match(Fn F
) const { F(Callee
, Args
); }
1624 void printLeft(OutputStream
&S
) const override
{
1627 Args
.printWithComma(S
);
1632 class NewExpr
: public Node
{
1633 // new (expr_list) type(init_list)
1637 bool IsGlobal
; // ::operator new ?
1638 bool IsArray
; // new[] ?
1640 NewExpr(NodeArray ExprList_
, Node
*Type_
, NodeArray InitList_
, bool IsGlobal_
,
1642 : Node(KNewExpr
), ExprList(ExprList_
), Type(Type_
), InitList(InitList_
),
1643 IsGlobal(IsGlobal_
), IsArray(IsArray_
) {}
1645 template<typename Fn
> void match(Fn F
) const {
1646 F(ExprList
, Type
, InitList
, IsGlobal
, IsArray
);
1649 void printLeft(OutputStream
&S
) const override
{
1656 if (!ExprList
.empty()) {
1658 ExprList
.printWithComma(S
);
1662 if (!InitList
.empty()) {
1664 InitList
.printWithComma(S
);
1671 class DeleteExpr
: public Node
{
1677 DeleteExpr(Node
*Op_
, bool IsGlobal_
, bool IsArray_
)
1678 : Node(KDeleteExpr
), Op(Op_
), IsGlobal(IsGlobal_
), IsArray(IsArray_
) {}
1680 template<typename Fn
> void match(Fn F
) const { F(Op
, IsGlobal
, IsArray
); }
1682 void printLeft(OutputStream
&S
) const override
{
1692 class PrefixExpr
: public Node
{
1697 PrefixExpr(StringView Prefix_
, Node
*Child_
)
1698 : Node(KPrefixExpr
), Prefix(Prefix_
), Child(Child_
) {}
1700 template<typename Fn
> void match(Fn F
) const { F(Prefix
, Child
); }
1702 void printLeft(OutputStream
&S
) const override
{
1710 class FunctionParam
: public Node
{
1714 FunctionParam(StringView Number_
) : Node(KFunctionParam
), Number(Number_
) {}
1716 template<typename Fn
> void match(Fn F
) const { F(Number
); }
1718 void printLeft(OutputStream
&S
) const override
{
1724 class ConversionExpr
: public Node
{
1726 NodeArray Expressions
;
1729 ConversionExpr(const Node
*Type_
, NodeArray Expressions_
)
1730 : Node(KConversionExpr
), Type(Type_
), Expressions(Expressions_
) {}
1732 template<typename Fn
> void match(Fn F
) const { F(Type
, Expressions
); }
1734 void printLeft(OutputStream
&S
) const override
{
1738 Expressions
.printWithComma(S
);
1743 class InitListExpr
: public Node
{
1747 InitListExpr(const Node
*Ty_
, NodeArray Inits_
)
1748 : Node(KInitListExpr
), Ty(Ty_
), Inits(Inits_
) {}
1750 template<typename Fn
> void match(Fn F
) const { F(Ty
, Inits
); }
1752 void printLeft(OutputStream
&S
) const override
{
1756 Inits
.printWithComma(S
);
1761 class BracedExpr
: public Node
{
1766 BracedExpr(const Node
*Elem_
, const Node
*Init_
, bool IsArray_
)
1767 : Node(KBracedExpr
), Elem(Elem_
), Init(Init_
), IsArray(IsArray_
) {}
1769 template<typename Fn
> void match(Fn F
) const { F(Elem
, Init
, IsArray
); }
1771 void printLeft(OutputStream
&S
) const override
{
1780 if (Init
->getKind() != KBracedExpr
&& Init
->getKind() != KBracedRangeExpr
)
1786 class BracedRangeExpr
: public Node
{
1791 BracedRangeExpr(const Node
*First_
, const Node
*Last_
, const Node
*Init_
)
1792 : Node(KBracedRangeExpr
), First(First_
), Last(Last_
), Init(Init_
) {}
1794 template<typename Fn
> void match(Fn F
) const { F(First
, Last
, Init
); }
1796 void printLeft(OutputStream
&S
) const override
{
1802 if (Init
->getKind() != KBracedExpr
&& Init
->getKind() != KBracedRangeExpr
)
1808 class FoldExpr
: public Node
{
1809 const Node
*Pack
, *Init
;
1810 StringView OperatorName
;
1814 FoldExpr(bool IsLeftFold_
, StringView OperatorName_
, const Node
*Pack_
,
1816 : Node(KFoldExpr
), Pack(Pack_
), Init(Init_
), OperatorName(OperatorName_
),
1817 IsLeftFold(IsLeftFold_
) {}
1819 template<typename Fn
> void match(Fn F
) const {
1820 F(IsLeftFold
, OperatorName
, Pack
, Init
);
1823 void printLeft(OutputStream
&S
) const override
{
1824 auto PrintPack
= [&] {
1826 ParameterPackExpansion(Pack
).print(S
);
1833 // init op ... op pack
1834 if (Init
!= nullptr) {
1845 } else { // !IsLeftFold
1851 // pack op ... op init
1852 if (Init
!= nullptr) {
1863 class ThrowExpr
: public Node
{
1867 ThrowExpr(const Node
*Op_
) : Node(KThrowExpr
), Op(Op_
) {}
1869 template<typename Fn
> void match(Fn F
) const { F(Op
); }
1871 void printLeft(OutputStream
&S
) const override
{
1877 // MSVC __uuidof extension, generated by clang in -fms-extensions mode.
1878 class UUIDOfExpr
: public Node
{
1881 UUIDOfExpr(Node
*Operand_
) : Node(KUUIDOfExpr
), Operand(Operand_
) {}
1883 template<typename Fn
> void match(Fn F
) const { F(Operand
); }
1885 void printLeft(OutputStream
&S
) const override
{
1892 class BoolExpr
: public Node
{
1896 BoolExpr(bool Value_
) : Node(KBoolExpr
), Value(Value_
) {}
1898 template<typename Fn
> void match(Fn F
) const { F(Value
); }
1900 void printLeft(OutputStream
&S
) const override
{
1901 S
+= Value
? StringView("true") : StringView("false");
1905 class IntegerCastExpr
: public Node
{
1911 IntegerCastExpr(const Node
*Ty_
, StringView Integer_
)
1912 : Node(KIntegerCastExpr
), Ty(Ty_
), Integer(Integer_
) {}
1914 template<typename Fn
> void match(Fn F
) const { F(Ty
, Integer
); }
1916 void printLeft(OutputStream
&S
) const override
{
1924 class IntegerLiteral
: public Node
{
1929 IntegerLiteral(StringView Type_
, StringView Value_
)
1930 : Node(KIntegerLiteral
), Type(Type_
), Value(Value_
) {}
1932 template<typename Fn
> void match(Fn F
) const { F(Type
, Value
); }
1934 void printLeft(OutputStream
&S
) const override
{
1935 if (Type
.size() > 3) {
1941 if (Value
[0] == 'n') {
1943 S
+= Value
.dropFront(1);
1947 if (Type
.size() <= 3)
1952 template <class Float
> struct FloatData
;
1954 namespace float_literal_impl
{
1955 constexpr Node::Kind
getFloatLiteralKind(float *) {
1956 return Node::KFloatLiteral
;
1958 constexpr Node::Kind
getFloatLiteralKind(double *) {
1959 return Node::KDoubleLiteral
;
1961 constexpr Node::Kind
getFloatLiteralKind(long double *) {
1962 return Node::KLongDoubleLiteral
;
1966 template <class Float
> class FloatLiteralImpl
: public Node
{
1967 const StringView Contents
;
1969 static constexpr Kind KindForClass
=
1970 float_literal_impl::getFloatLiteralKind((Float
*)nullptr);
1973 FloatLiteralImpl(StringView Contents_
)
1974 : Node(KindForClass
), Contents(Contents_
) {}
1976 template<typename Fn
> void match(Fn F
) const { F(Contents
); }
1978 void printLeft(OutputStream
&s
) const override
{
1979 const char *first
= Contents
.begin();
1980 const char *last
= Contents
.end() + 1;
1982 const size_t N
= FloatData
<Float
>::mangled_size
;
1983 if (static_cast<std::size_t>(last
- first
) > N
) {
1987 char buf
[sizeof(Float
)];
1989 const char *t
= first
;
1991 for (; t
!= last
; ++t
, ++e
) {
1992 unsigned d1
= isdigit(*t
) ? static_cast<unsigned>(*t
- '0')
1993 : static_cast<unsigned>(*t
- 'a' + 10);
1995 unsigned d0
= isdigit(*t
) ? static_cast<unsigned>(*t
- '0')
1996 : static_cast<unsigned>(*t
- 'a' + 10);
1997 *e
= static_cast<char>((d1
<< 4) + d0
);
1999 #if __BYTE_ORDER__ == __ORDER_LITTLE_ENDIAN__
2000 std::reverse(buf
, e
);
2002 char num
[FloatData
<Float
>::max_demangled_size
] = {0};
2003 int n
= snprintf(num
, sizeof(num
), FloatData
<Float
>::spec
, value
);
2004 s
+= StringView(num
, num
+ n
);
2009 using FloatLiteral
= FloatLiteralImpl
<float>;
2010 using DoubleLiteral
= FloatLiteralImpl
<double>;
2011 using LongDoubleLiteral
= FloatLiteralImpl
<long double>;
2013 /// Visit the node. Calls \c F(P), where \c P is the node cast to the
2014 /// appropriate derived class.
2015 template<typename Fn
>
2016 void Node::visit(Fn F
) const {
2018 #define CASE(X) case K ## X: return F(static_cast<const X*>(this));
2019 FOR_EACH_NODE_KIND(CASE
)
2022 assert(0 && "unknown mangling node kind");
2025 /// Determine the kind of a node from its type.
2026 template<typename NodeT
> struct NodeKind
;
2027 #define SPECIALIZATION(X) \
2028 template<> struct NodeKind<X> { \
2029 static constexpr Node::Kind Kind = Node::K##X; \
2030 static constexpr const char *name() { return #X; } \
2032 FOR_EACH_NODE_KIND(SPECIALIZATION
)
2033 #undef SPECIALIZATION
2035 #undef FOR_EACH_NODE_KIND
2037 template <class T
, size_t N
>
2038 class PODSmallVector
{
2039 static_assert(std::is_pod
<T
>::value
,
2040 "T is required to be a plain old data type");
2047 bool isInline() const { return First
== Inline
; }
2049 void clearInline() {
2055 void reserve(size_t NewCap
) {
2058 auto* Tmp
= static_cast<T
*>(std::malloc(NewCap
* sizeof(T
)));
2061 std::copy(First
, Last
, Tmp
);
2064 First
= static_cast<T
*>(std::realloc(First
, NewCap
* sizeof(T
)));
2065 if (First
== nullptr)
2069 Cap
= First
+ NewCap
;
2073 PODSmallVector() : First(Inline
), Last(First
), Cap(Inline
+ N
) {}
2075 PODSmallVector(const PODSmallVector
&) = delete;
2076 PODSmallVector
& operator=(const PODSmallVector
&) = delete;
2078 PODSmallVector(PODSmallVector
&& Other
) : PODSmallVector() {
2079 if (Other
.isInline()) {
2080 std::copy(Other
.begin(), Other
.end(), First
);
2081 Last
= First
+ Other
.size();
2086 First
= Other
.First
;
2089 Other
.clearInline();
2092 PODSmallVector
& operator=(PODSmallVector
&& Other
) {
2093 if (Other
.isInline()) {
2098 std::copy(Other
.begin(), Other
.end(), First
);
2099 Last
= First
+ Other
.size();
2105 First
= Other
.First
;
2108 Other
.clearInline();
2112 std::swap(First
, Other
.First
);
2113 std::swap(Last
, Other
.Last
);
2114 std::swap(Cap
, Other
.Cap
);
2119 void push_back(const T
& Elem
) {
2121 reserve(size() * 2);
2126 assert(Last
!= First
&& "Popping empty vector!");
2130 void dropBack(size_t Index
) {
2131 assert(Index
<= size() && "dropBack() can't expand!");
2132 Last
= First
+ Index
;
2135 T
* begin() { return First
; }
2136 T
* end() { return Last
; }
2138 bool empty() const { return First
== Last
; }
2139 size_t size() const { return static_cast<size_t>(Last
- First
); }
2141 assert(Last
!= First
&& "Calling back() on empty vector!");
2144 T
& operator[](size_t Index
) {
2145 assert(Index
< size() && "Invalid access!");
2146 return *(begin() + Index
);
2148 void clear() { Last
= First
; }
2156 template <typename Derived
, typename Alloc
> struct AbstractManglingParser
{
2160 // Name stack, this is used by the parser to hold temporary names that were
2161 // parsed. The parser collapses multiple names into new nodes to construct
2162 // the AST. Once the parser is finished, names.size() == 1.
2163 PODSmallVector
<Node
*, 32> Names
;
2165 // Substitution table. Itanium supports name substitutions as a means of
2166 // compression. The string "S42_" refers to the 44nd entry (base-36) in this
2168 PODSmallVector
<Node
*, 32> Subs
;
2170 // Template parameter table. Like the above, but referenced like "T42_".
2171 // This has a smaller size compared to Subs and Names because it can be
2172 // stored on the stack.
2173 PODSmallVector
<Node
*, 8> TemplateParams
;
2175 // Set of unresolved forward <template-param> references. These can occur in a
2176 // conversion operator's type, and are resolved in the enclosing <encoding>.
2177 PODSmallVector
<ForwardTemplateReference
*, 4> ForwardTemplateRefs
;
2179 bool TryToParseTemplateArgs
= true;
2180 bool PermitForwardTemplateReferences
= false;
2181 bool ParsingLambdaParams
= false;
2185 AbstractManglingParser(const char *First_
, const char *Last_
)
2186 : First(First_
), Last(Last_
) {}
2188 Derived
&getDerived() { return static_cast<Derived
&>(*this); }
2190 void reset(const char *First_
, const char *Last_
) {
2195 TemplateParams
.clear();
2196 ParsingLambdaParams
= false;
2197 TryToParseTemplateArgs
= true;
2198 PermitForwardTemplateReferences
= false;
2199 ASTAllocator
.reset();
2202 template <class T
, class... Args
> Node
*make(Args
&&... args
) {
2203 return ASTAllocator
.template makeNode
<T
>(std::forward
<Args
>(args
)...);
2206 template <class It
> NodeArray
makeNodeArray(It begin
, It end
) {
2207 size_t sz
= static_cast<size_t>(end
- begin
);
2208 void *mem
= ASTAllocator
.allocateNodeArray(sz
);
2209 Node
**data
= new (mem
) Node
*[sz
];
2210 std::copy(begin
, end
, data
);
2211 return NodeArray(data
, sz
);
2214 NodeArray
popTrailingNodeArray(size_t FromPosition
) {
2215 assert(FromPosition
<= Names
.size());
2217 makeNodeArray(Names
.begin() + (long)FromPosition
, Names
.end());
2218 Names
.dropBack(FromPosition
);
2222 bool consumeIf(StringView S
) {
2223 if (StringView(First
, Last
).startsWith(S
)) {
2230 bool consumeIf(char C
) {
2231 if (First
!= Last
&& *First
== C
) {
2238 char consume() { return First
!= Last
? *First
++ : '\0'; }
2240 char look(unsigned Lookahead
= 0) {
2241 if (static_cast<size_t>(Last
- First
) <= Lookahead
)
2243 return First
[Lookahead
];
2246 size_t numLeft() const { return static_cast<size_t>(Last
- First
); }
2248 StringView
parseNumber(bool AllowNegative
= false);
2249 Qualifiers
parseCVQualifiers();
2250 bool parsePositiveInteger(size_t *Out
);
2251 StringView
parseBareSourceName();
2253 bool parseSeqId(size_t *Out
);
2254 Node
*parseSubstitution();
2255 Node
*parseTemplateParam();
2256 Node
*parseTemplateArgs(bool TagTemplates
= false);
2257 Node
*parseTemplateArg();
2259 /// Parse the <expr> production.
2261 Node
*parsePrefixExpr(StringView Kind
);
2262 Node
*parseBinaryExpr(StringView Kind
);
2263 Node
*parseIntegerLiteral(StringView Lit
);
2264 Node
*parseExprPrimary();
2265 template <class Float
> Node
*parseFloatingLiteral();
2266 Node
*parseFunctionParam();
2267 Node
*parseNewExpr();
2268 Node
*parseConversionExpr();
2269 Node
*parseBracedExpr();
2270 Node
*parseFoldExpr();
2272 /// Parse the <type> production.
2274 Node
*parseFunctionType();
2275 Node
*parseVectorType();
2276 Node
*parseDecltype();
2277 Node
*parseArrayType();
2278 Node
*parsePointerToMemberType();
2279 Node
*parseClassEnumType();
2280 Node
*parseQualifiedType();
2282 Node
*parseEncoding();
2283 bool parseCallOffset();
2284 Node
*parseSpecialName();
2286 /// Holds some extra information about a <name> that is being parsed. This
2287 /// information is only pertinent if the <name> refers to an <encoding>.
2289 bool CtorDtorConversion
= false;
2290 bool EndsWithTemplateArgs
= false;
2291 Qualifiers CVQualifiers
= QualNone
;
2292 FunctionRefQual ReferenceQualifier
= FrefQualNone
;
2293 size_t ForwardTemplateRefsBegin
;
2295 NameState(AbstractManglingParser
*Enclosing
)
2296 : ForwardTemplateRefsBegin(Enclosing
->ForwardTemplateRefs
.size()) {}
2299 bool resolveForwardTemplateRefs(NameState
&State
) {
2300 size_t I
= State
.ForwardTemplateRefsBegin
;
2301 size_t E
= ForwardTemplateRefs
.size();
2302 for (; I
< E
; ++I
) {
2303 size_t Idx
= ForwardTemplateRefs
[I
]->Index
;
2304 if (Idx
>= TemplateParams
.size())
2306 ForwardTemplateRefs
[I
]->Ref
= TemplateParams
[Idx
];
2308 ForwardTemplateRefs
.dropBack(State
.ForwardTemplateRefsBegin
);
2312 /// Parse the <name> production>
2313 Node
*parseName(NameState
*State
= nullptr);
2314 Node
*parseLocalName(NameState
*State
);
2315 Node
*parseOperatorName(NameState
*State
);
2316 Node
*parseUnqualifiedName(NameState
*State
);
2317 Node
*parseUnnamedTypeName(NameState
*State
);
2318 Node
*parseSourceName(NameState
*State
);
2319 Node
*parseUnscopedName(NameState
*State
);
2320 Node
*parseNestedName(NameState
*State
);
2321 Node
*parseCtorDtorName(Node
*&SoFar
, NameState
*State
);
2323 Node
*parseAbiTags(Node
*N
);
2325 /// Parse the <unresolved-name> production.
2326 Node
*parseUnresolvedName();
2327 Node
*parseSimpleId();
2328 Node
*parseBaseUnresolvedName();
2329 Node
*parseUnresolvedType();
2330 Node
*parseDestructorName();
2332 /// Top-level entry point into the parser.
2336 const char* parse_discriminator(const char* first
, const char* last
);
2338 // <name> ::= <nested-name> // N
2339 // ::= <local-name> # See Scope Encoding below // Z
2340 // ::= <unscoped-template-name> <template-args>
2341 // ::= <unscoped-name>
2343 // <unscoped-template-name> ::= <unscoped-name>
2344 // ::= <substitution>
2345 template <typename Derived
, typename Alloc
>
2346 Node
*AbstractManglingParser
<Derived
, Alloc
>::parseName(NameState
*State
) {
2347 consumeIf('L'); // extension
2350 return getDerived().parseNestedName(State
);
2352 return getDerived().parseLocalName(State
);
2354 // ::= <unscoped-template-name> <template-args>
2355 if (look() == 'S' && look(1) != 't') {
2356 Node
*S
= getDerived().parseSubstitution();
2361 Node
*TA
= getDerived().parseTemplateArgs(State
!= nullptr);
2364 if (State
) State
->EndsWithTemplateArgs
= true;
2365 return make
<NameWithTemplateArgs
>(S
, TA
);
2368 Node
*N
= getDerived().parseUnscopedName(State
);
2371 // ::= <unscoped-template-name> <template-args>
2372 if (look() == 'I') {
2374 Node
*TA
= getDerived().parseTemplateArgs(State
!= nullptr);
2377 if (State
) State
->EndsWithTemplateArgs
= true;
2378 return make
<NameWithTemplateArgs
>(N
, TA
);
2380 // ::= <unscoped-name>
2384 // <local-name> := Z <function encoding> E <entity name> [<discriminator>]
2385 // := Z <function encoding> E s [<discriminator>]
2386 // := Z <function encoding> Ed [ <parameter number> ] _ <entity name>
2387 template <typename Derived
, typename Alloc
>
2388 Node
*AbstractManglingParser
<Derived
, Alloc
>::parseLocalName(NameState
*State
) {
2389 if (!consumeIf('Z'))
2391 Node
*Encoding
= getDerived().parseEncoding();
2392 if (Encoding
== nullptr || !consumeIf('E'))
2395 if (consumeIf('s')) {
2396 First
= parse_discriminator(First
, Last
);
2397 auto *StringLitName
= make
<NameType
>("string literal");
2400 return make
<LocalName
>(Encoding
, StringLitName
);
2403 if (consumeIf('d')) {
2405 if (!consumeIf('_'))
2407 Node
*N
= getDerived().parseName(State
);
2410 return make
<LocalName
>(Encoding
, N
);
2413 Node
*Entity
= getDerived().parseName(State
);
2414 if (Entity
== nullptr)
2416 First
= parse_discriminator(First
, Last
);
2417 return make
<LocalName
>(Encoding
, Entity
);
2420 // <unscoped-name> ::= <unqualified-name>
2421 // ::= St <unqualified-name> # ::std::
2422 // extension ::= StL<unqualified-name>
2423 template <typename Derived
, typename Alloc
>
2425 AbstractManglingParser
<Derived
, Alloc
>::parseUnscopedName(NameState
*State
) {
2426 if (consumeIf("StL") || consumeIf("St")) {
2427 Node
*R
= getDerived().parseUnqualifiedName(State
);
2430 return make
<StdQualifiedName
>(R
);
2432 return getDerived().parseUnqualifiedName(State
);
2435 // <unqualified-name> ::= <operator-name> [abi-tags]
2436 // ::= <ctor-dtor-name>
2437 // ::= <source-name>
2438 // ::= <unnamed-type-name>
2439 // ::= DC <source-name>+ E # structured binding declaration
2440 template <typename Derived
, typename Alloc
>
2442 AbstractManglingParser
<Derived
, Alloc
>::parseUnqualifiedName(NameState
*State
) {
2443 // <ctor-dtor-name>s are special-cased in parseNestedName().
2446 Result
= getDerived().parseUnnamedTypeName(State
);
2447 else if (look() >= '1' && look() <= '9')
2448 Result
= getDerived().parseSourceName(State
);
2449 else if (consumeIf("DC")) {
2450 size_t BindingsBegin
= Names
.size();
2452 Node
*Binding
= getDerived().parseSourceName(State
);
2453 if (Binding
== nullptr)
2455 Names
.push_back(Binding
);
2456 } while (!consumeIf('E'));
2457 Result
= make
<StructuredBindingName
>(popTrailingNodeArray(BindingsBegin
));
2459 Result
= getDerived().parseOperatorName(State
);
2460 if (Result
!= nullptr)
2461 Result
= getDerived().parseAbiTags(Result
);
2465 // <unnamed-type-name> ::= Ut [<nonnegative number>] _
2466 // ::= <closure-type-name>
2468 // <closure-type-name> ::= Ul <lambda-sig> E [ <nonnegative number> ] _
2470 // <lambda-sig> ::= <parameter type>+ # Parameter types or "v" if the lambda has no parameters
2471 template <typename Derived
, typename Alloc
>
2473 AbstractManglingParser
<Derived
, Alloc
>::parseUnnamedTypeName(NameState
*) {
2474 if (consumeIf("Ut")) {
2475 StringView Count
= parseNumber();
2476 if (!consumeIf('_'))
2478 return make
<UnnamedTypeName
>(Count
);
2480 if (consumeIf("Ul")) {
2482 SwapAndRestore
<bool> SwapParams(ParsingLambdaParams
, true);
2483 if (!consumeIf("vE")) {
2484 size_t ParamsBegin
= Names
.size();
2486 Node
*P
= getDerived().parseType();
2490 } while (!consumeIf('E'));
2491 Params
= popTrailingNodeArray(ParamsBegin
);
2493 StringView Count
= parseNumber();
2494 if (!consumeIf('_'))
2496 return make
<ClosureTypeName
>(Params
, Count
);
2498 if (consumeIf("Ub")) {
2499 (void)parseNumber();
2500 if (!consumeIf('_'))
2502 return make
<NameType
>("'block-literal'");
2507 // <source-name> ::= <positive length number> <identifier>
2508 template <typename Derived
, typename Alloc
>
2509 Node
*AbstractManglingParser
<Derived
, Alloc
>::parseSourceName(NameState
*) {
2511 if (parsePositiveInteger(&Length
))
2513 if (numLeft() < Length
|| Length
== 0)
2515 StringView
Name(First
, First
+ Length
);
2517 if (Name
.startsWith("_GLOBAL__N"))
2518 return make
<NameType
>("(anonymous namespace)");
2519 return make
<NameType
>(Name
);
2522 // <operator-name> ::= aa # &&
2523 // ::= ad # & (unary)
2530 // ::= cv <type> # (cast)
2531 // ::= da # delete[]
2532 // ::= de # * (unary)
2543 // ::= li <source-name> # operator ""
2551 // ::= mm # -- (postfix in <expression> context)
2554 // ::= ng # - (unary)
2563 // ::= pp # ++ (postfix in <expression> context)
2564 // ::= ps # + (unary)
2571 // ::= ss # <=> C++2a
2572 // ::= v <digit> <source-name> # vendor extended operator
2573 template <typename Derived
, typename Alloc
>
2575 AbstractManglingParser
<Derived
, Alloc
>::parseOperatorName(NameState
*State
) {
2581 return make
<NameType
>("operator&&");
2585 return make
<NameType
>("operator&");
2588 return make
<NameType
>("operator&=");
2591 return make
<NameType
>("operator=");
2598 return make
<NameType
>("operator()");
2601 return make
<NameType
>("operator,");
2604 return make
<NameType
>("operator~");
2605 // ::= cv <type> # (cast)
2608 SwapAndRestore
<bool> SaveTemplate(TryToParseTemplateArgs
, false);
2609 // If we're parsing an encoding, State != nullptr and the conversion
2610 // operators' <type> could have a <template-param> that refers to some
2611 // <template-arg>s further ahead in the mangled name.
2612 SwapAndRestore
<bool> SavePermit(PermitForwardTemplateReferences
,
2613 PermitForwardTemplateReferences
||
2615 Node
*Ty
= getDerived().parseType();
2618 if (State
) State
->CtorDtorConversion
= true;
2619 return make
<ConversionOperatorType
>(Ty
);
2627 return make
<NameType
>("operator delete[]");
2630 return make
<NameType
>("operator*");
2633 return make
<NameType
>("operator delete");
2636 return make
<NameType
>("operator/");
2639 return make
<NameType
>("operator/=");
2646 return make
<NameType
>("operator^");
2649 return make
<NameType
>("operator^=");
2652 return make
<NameType
>("operator==");
2659 return make
<NameType
>("operator>=");
2662 return make
<NameType
>("operator>");
2666 if (look(1) == 'x') {
2668 return make
<NameType
>("operator[]");
2675 return make
<NameType
>("operator<=");
2676 // ::= li <source-name> # operator ""
2679 Node
*SN
= getDerived().parseSourceName(State
);
2682 return make
<LiteralOperator
>(SN
);
2686 return make
<NameType
>("operator<<");
2689 return make
<NameType
>("operator<<=");
2692 return make
<NameType
>("operator<");
2699 return make
<NameType
>("operator-");
2702 return make
<NameType
>("operator-=");
2705 return make
<NameType
>("operator*");
2708 return make
<NameType
>("operator*=");
2711 return make
<NameType
>("operator--");
2718 return make
<NameType
>("operator new[]");
2721 return make
<NameType
>("operator!=");
2724 return make
<NameType
>("operator-");
2727 return make
<NameType
>("operator!");
2730 return make
<NameType
>("operator new");
2737 return make
<NameType
>("operator||");
2740 return make
<NameType
>("operator|");
2743 return make
<NameType
>("operator|=");
2750 return make
<NameType
>("operator->*");
2753 return make
<NameType
>("operator+");
2756 return make
<NameType
>("operator+=");
2759 return make
<NameType
>("operator++");
2762 return make
<NameType
>("operator+");
2765 return make
<NameType
>("operator->");
2769 if (look(1) == 'u') {
2771 return make
<NameType
>("operator?");
2778 return make
<NameType
>("operator%");
2781 return make
<NameType
>("operator%=");
2784 return make
<NameType
>("operator>>");
2787 return make
<NameType
>("operator>>=");
2791 if (look(1) == 's') {
2793 return make
<NameType
>("operator<=>");
2796 // ::= v <digit> <source-name> # vendor extended operator
2798 if (std::isdigit(look(1))) {
2800 Node
*SN
= getDerived().parseSourceName(State
);
2803 return make
<ConversionOperatorType
>(SN
);
2810 // <ctor-dtor-name> ::= C1 # complete object constructor
2811 // ::= C2 # base object constructor
2812 // ::= C3 # complete object allocating constructor
2813 // extension ::= C4 # gcc old-style "[unified]" constructor
2814 // extension ::= C5 # the COMDAT used for ctors
2815 // ::= D0 # deleting destructor
2816 // ::= D1 # complete object destructor
2817 // ::= D2 # base object destructor
2818 // extension ::= D4 # gcc old-style "[unified]" destructor
2819 // extension ::= D5 # the COMDAT used for dtors
2820 template <typename Derived
, typename Alloc
>
2822 AbstractManglingParser
<Derived
, Alloc
>::parseCtorDtorName(Node
*&SoFar
,
2824 if (SoFar
->getKind() == Node::KSpecialSubstitution
) {
2825 auto SSK
= static_cast<SpecialSubstitution
*>(SoFar
)->SSK
;
2827 case SpecialSubKind::string
:
2828 case SpecialSubKind::istream
:
2829 case SpecialSubKind::ostream
:
2830 case SpecialSubKind::iostream
:
2831 SoFar
= make
<ExpandedSpecialSubstitution
>(SSK
);
2840 if (consumeIf('C')) {
2841 bool IsInherited
= consumeIf('I');
2842 if (look() != '1' && look() != '2' && look() != '3' && look() != '4' &&
2845 int Variant
= look() - '0';
2847 if (State
) State
->CtorDtorConversion
= true;
2849 if (getDerived().parseName(State
) == nullptr)
2852 return make
<CtorDtorName
>(SoFar
, /*IsDtor=*/false, Variant
);
2855 if (look() == 'D' && (look(1) == '0' || look(1) == '1' || look(1) == '2' ||
2856 look(1) == '4' || look(1) == '5')) {
2857 int Variant
= look(1) - '0';
2859 if (State
) State
->CtorDtorConversion
= true;
2860 return make
<CtorDtorName
>(SoFar
, /*IsDtor=*/true, Variant
);
2866 // <nested-name> ::= N [<CV-Qualifiers>] [<ref-qualifier>] <prefix> <unqualified-name> E
2867 // ::= N [<CV-Qualifiers>] [<ref-qualifier>] <template-prefix> <template-args> E
2869 // <prefix> ::= <prefix> <unqualified-name>
2870 // ::= <template-prefix> <template-args>
2871 // ::= <template-param>
2874 // ::= <substitution>
2875 // ::= <prefix> <data-member-prefix>
2878 // <data-member-prefix> := <member source-name> [<template-args>] M
2880 // <template-prefix> ::= <prefix> <template unqualified-name>
2881 // ::= <template-param>
2882 // ::= <substitution>
2883 template <typename Derived
, typename Alloc
>
2885 AbstractManglingParser
<Derived
, Alloc
>::parseNestedName(NameState
*State
) {
2886 if (!consumeIf('N'))
2889 Qualifiers CVTmp
= parseCVQualifiers();
2890 if (State
) State
->CVQualifiers
= CVTmp
;
2892 if (consumeIf('O')) {
2893 if (State
) State
->ReferenceQualifier
= FrefQualRValue
;
2894 } else if (consumeIf('R')) {
2895 if (State
) State
->ReferenceQualifier
= FrefQualLValue
;
2897 if (State
) State
->ReferenceQualifier
= FrefQualNone
;
2899 Node
*SoFar
= nullptr;
2900 auto PushComponent
= [&](Node
*Comp
) {
2901 if (!Comp
) return false;
2902 if (SoFar
) SoFar
= make
<NestedName
>(SoFar
, Comp
);
2904 if (State
) State
->EndsWithTemplateArgs
= false;
2905 return SoFar
!= nullptr;
2908 if (consumeIf("St")) {
2909 SoFar
= make
<NameType
>("std");
2914 while (!consumeIf('E')) {
2915 consumeIf('L'); // extension
2917 // <data-member-prefix> := <member source-name> [<template-args>] M
2918 if (consumeIf('M')) {
2919 if (SoFar
== nullptr)
2924 // ::= <template-param>
2925 if (look() == 'T') {
2926 if (!PushComponent(getDerived().parseTemplateParam()))
2928 Subs
.push_back(SoFar
);
2932 // ::= <template-prefix> <template-args>
2933 if (look() == 'I') {
2934 Node
*TA
= getDerived().parseTemplateArgs(State
!= nullptr);
2935 if (TA
== nullptr || SoFar
== nullptr)
2937 SoFar
= make
<NameWithTemplateArgs
>(SoFar
, TA
);
2940 if (State
) State
->EndsWithTemplateArgs
= true;
2941 Subs
.push_back(SoFar
);
2946 if (look() == 'D' && (look(1) == 't' || look(1) == 'T')) {
2947 if (!PushComponent(getDerived().parseDecltype()))
2949 Subs
.push_back(SoFar
);
2953 // ::= <substitution>
2954 if (look() == 'S' && look(1) != 't') {
2955 Node
*S
= getDerived().parseSubstitution();
2956 if (!PushComponent(S
))
2963 // Parse an <unqualified-name> thats actually a <ctor-dtor-name>.
2964 if (look() == 'C' || (look() == 'D' && look(1) != 'C')) {
2965 if (SoFar
== nullptr)
2967 if (!PushComponent(getDerived().parseCtorDtorName(SoFar
, State
)))
2969 SoFar
= getDerived().parseAbiTags(SoFar
);
2970 if (SoFar
== nullptr)
2972 Subs
.push_back(SoFar
);
2976 // ::= <prefix> <unqualified-name>
2977 if (!PushComponent(getDerived().parseUnqualifiedName(State
)))
2979 Subs
.push_back(SoFar
);
2982 if (SoFar
== nullptr || Subs
.empty())
2989 // <simple-id> ::= <source-name> [ <template-args> ]
2990 template <typename Derived
, typename Alloc
>
2991 Node
*AbstractManglingParser
<Derived
, Alloc
>::parseSimpleId() {
2992 Node
*SN
= getDerived().parseSourceName(/*NameState=*/nullptr);
2995 if (look() == 'I') {
2996 Node
*TA
= getDerived().parseTemplateArgs();
2999 return make
<NameWithTemplateArgs
>(SN
, TA
);
3004 // <destructor-name> ::= <unresolved-type> # e.g., ~T or ~decltype(f())
3005 // ::= <simple-id> # e.g., ~A<2*N>
3006 template <typename Derived
, typename Alloc
>
3007 Node
*AbstractManglingParser
<Derived
, Alloc
>::parseDestructorName() {
3009 if (std::isdigit(look()))
3010 Result
= getDerived().parseSimpleId();
3012 Result
= getDerived().parseUnresolvedType();
3013 if (Result
== nullptr)
3015 return make
<DtorName
>(Result
);
3018 // <unresolved-type> ::= <template-param>
3020 // ::= <substitution>
3021 template <typename Derived
, typename Alloc
>
3022 Node
*AbstractManglingParser
<Derived
, Alloc
>::parseUnresolvedType() {
3023 if (look() == 'T') {
3024 Node
*TP
= getDerived().parseTemplateParam();
3030 if (look() == 'D') {
3031 Node
*DT
= getDerived().parseDecltype();
3037 return getDerived().parseSubstitution();
3040 // <base-unresolved-name> ::= <simple-id> # unresolved name
3041 // extension ::= <operator-name> # unresolved operator-function-id
3042 // extension ::= <operator-name> <template-args> # unresolved operator template-id
3043 // ::= on <operator-name> # unresolved operator-function-id
3044 // ::= on <operator-name> <template-args> # unresolved operator template-id
3045 // ::= dn <destructor-name> # destructor or pseudo-destructor;
3046 // # e.g. ~X or ~X<N-1>
3047 template <typename Derived
, typename Alloc
>
3048 Node
*AbstractManglingParser
<Derived
, Alloc
>::parseBaseUnresolvedName() {
3049 if (std::isdigit(look()))
3050 return getDerived().parseSimpleId();
3052 if (consumeIf("dn"))
3053 return getDerived().parseDestructorName();
3057 Node
*Oper
= getDerived().parseOperatorName(/*NameState=*/nullptr);
3058 if (Oper
== nullptr)
3060 if (look() == 'I') {
3061 Node
*TA
= getDerived().parseTemplateArgs();
3064 return make
<NameWithTemplateArgs
>(Oper
, TA
);
3069 // <unresolved-name>
3070 // extension ::= srN <unresolved-type> [<template-args>] <unresolved-qualifier-level>* E <base-unresolved-name>
3071 // ::= [gs] <base-unresolved-name> # x or (with "gs") ::x
3072 // ::= [gs] sr <unresolved-qualifier-level>+ E <base-unresolved-name>
3073 // # A::x, N::y, A<T>::z; "gs" means leading "::"
3074 // ::= sr <unresolved-type> <base-unresolved-name> # T::x / decltype(p)::x
3075 // extension ::= sr <unresolved-type> <template-args> <base-unresolved-name>
3076 // # T::N::x /decltype(p)::N::x
3077 // (ignored) ::= srN <unresolved-type> <unresolved-qualifier-level>+ E <base-unresolved-name>
3079 // <unresolved-qualifier-level> ::= <simple-id>
3080 template <typename Derived
, typename Alloc
>
3081 Node
*AbstractManglingParser
<Derived
, Alloc
>::parseUnresolvedName() {
3082 Node
*SoFar
= nullptr;
3084 // srN <unresolved-type> [<template-args>] <unresolved-qualifier-level>* E <base-unresolved-name>
3085 // srN <unresolved-type> <unresolved-qualifier-level>+ E <base-unresolved-name>
3086 if (consumeIf("srN")) {
3087 SoFar
= getDerived().parseUnresolvedType();
3088 if (SoFar
== nullptr)
3091 if (look() == 'I') {
3092 Node
*TA
= getDerived().parseTemplateArgs();
3095 SoFar
= make
<NameWithTemplateArgs
>(SoFar
, TA
);
3100 while (!consumeIf('E')) {
3101 Node
*Qual
= getDerived().parseSimpleId();
3102 if (Qual
== nullptr)
3104 SoFar
= make
<QualifiedName
>(SoFar
, Qual
);
3109 Node
*Base
= getDerived().parseBaseUnresolvedName();
3110 if (Base
== nullptr)
3112 return make
<QualifiedName
>(SoFar
, Base
);
3115 bool Global
= consumeIf("gs");
3117 // [gs] <base-unresolved-name> # x or (with "gs") ::x
3118 if (!consumeIf("sr")) {
3119 SoFar
= getDerived().parseBaseUnresolvedName();
3120 if (SoFar
== nullptr)
3123 SoFar
= make
<GlobalQualifiedName
>(SoFar
);
3127 // [gs] sr <unresolved-qualifier-level>+ E <base-unresolved-name>
3128 if (std::isdigit(look())) {
3130 Node
*Qual
= getDerived().parseSimpleId();
3131 if (Qual
== nullptr)
3134 SoFar
= make
<QualifiedName
>(SoFar
, Qual
);
3136 SoFar
= make
<GlobalQualifiedName
>(Qual
);
3141 } while (!consumeIf('E'));
3143 // sr <unresolved-type> <base-unresolved-name>
3144 // sr <unresolved-type> <template-args> <base-unresolved-name>
3146 SoFar
= getDerived().parseUnresolvedType();
3147 if (SoFar
== nullptr)
3150 if (look() == 'I') {
3151 Node
*TA
= getDerived().parseTemplateArgs();
3154 SoFar
= make
<NameWithTemplateArgs
>(SoFar
, TA
);
3160 assert(SoFar
!= nullptr);
3162 Node
*Base
= getDerived().parseBaseUnresolvedName();
3163 if (Base
== nullptr)
3165 return make
<QualifiedName
>(SoFar
, Base
);
3168 // <abi-tags> ::= <abi-tag> [<abi-tags>]
3169 // <abi-tag> ::= B <source-name>
3170 template <typename Derived
, typename Alloc
>
3171 Node
*AbstractManglingParser
<Derived
, Alloc
>::parseAbiTags(Node
*N
) {
3172 while (consumeIf('B')) {
3173 StringView SN
= parseBareSourceName();
3176 N
= make
<AbiTagAttr
>(N
, SN
);
3183 // <number> ::= [n] <non-negative decimal integer>
3184 template <typename Alloc
, typename Derived
>
3186 AbstractManglingParser
<Alloc
, Derived
>::parseNumber(bool AllowNegative
) {
3187 const char *Tmp
= First
;
3190 if (numLeft() == 0 || !std::isdigit(*First
))
3191 return StringView();
3192 while (numLeft() != 0 && std::isdigit(*First
))
3194 return StringView(Tmp
, First
);
3197 // <positive length number> ::= [0-9]*
3198 template <typename Alloc
, typename Derived
>
3199 bool AbstractManglingParser
<Alloc
, Derived
>::parsePositiveInteger(size_t *Out
) {
3201 if (look() < '0' || look() > '9')
3203 while (look() >= '0' && look() <= '9') {
3205 *Out
+= static_cast<size_t>(consume() - '0');
3210 template <typename Alloc
, typename Derived
>
3211 StringView AbstractManglingParser
<Alloc
, Derived
>::parseBareSourceName() {
3213 if (parsePositiveInteger(&Int
) || numLeft() < Int
)
3214 return StringView();
3215 StringView
R(First
, First
+ Int
);
3220 // <function-type> ::= [<CV-qualifiers>] [<exception-spec>] [Dx] F [Y] <bare-function-type> [<ref-qualifier>] E
3222 // <exception-spec> ::= Do # non-throwing exception-specification (e.g., noexcept, throw())
3223 // ::= DO <expression> E # computed (instantiation-dependent) noexcept
3224 // ::= Dw <type>+ E # dynamic exception specification with instantiation-dependent types
3226 // <ref-qualifier> ::= R # & ref-qualifier
3227 // <ref-qualifier> ::= O # && ref-qualifier
3228 template <typename Derived
, typename Alloc
>
3229 Node
*AbstractManglingParser
<Derived
, Alloc
>::parseFunctionType() {
3230 Qualifiers CVQuals
= parseCVQualifiers();
3232 Node
*ExceptionSpec
= nullptr;
3233 if (consumeIf("Do")) {
3234 ExceptionSpec
= make
<NameType
>("noexcept");
3237 } else if (consumeIf("DO")) {
3238 Node
*E
= getDerived().parseExpr();
3239 if (E
== nullptr || !consumeIf('E'))
3241 ExceptionSpec
= make
<NoexceptSpec
>(E
);
3244 } else if (consumeIf("Dw")) {
3245 size_t SpecsBegin
= Names
.size();
3246 while (!consumeIf('E')) {
3247 Node
*T
= getDerived().parseType();
3253 make
<DynamicExceptionSpec
>(popTrailingNodeArray(SpecsBegin
));
3258 consumeIf("Dx"); // transaction safe
3260 if (!consumeIf('F'))
3262 consumeIf('Y'); // extern "C"
3263 Node
*ReturnType
= getDerived().parseType();
3264 if (ReturnType
== nullptr)
3267 FunctionRefQual ReferenceQualifier
= FrefQualNone
;
3268 size_t ParamsBegin
= Names
.size();
3274 if (consumeIf("RE")) {
3275 ReferenceQualifier
= FrefQualLValue
;
3278 if (consumeIf("OE")) {
3279 ReferenceQualifier
= FrefQualRValue
;
3282 Node
*T
= getDerived().parseType();
3288 NodeArray Params
= popTrailingNodeArray(ParamsBegin
);
3289 return make
<FunctionType
>(ReturnType
, Params
, CVQuals
,
3290 ReferenceQualifier
, ExceptionSpec
);
3294 // <vector-type> ::= Dv <positive dimension number> _ <extended element type>
3295 // ::= Dv [<dimension expression>] _ <element type>
3296 // <extended element type> ::= <element type>
3297 // ::= p # AltiVec vector pixel
3298 template <typename Derived
, typename Alloc
>
3299 Node
*AbstractManglingParser
<Derived
, Alloc
>::parseVectorType() {
3300 if (!consumeIf("Dv"))
3302 if (look() >= '1' && look() <= '9') {
3303 StringView DimensionNumber
= parseNumber();
3304 if (!consumeIf('_'))
3307 return make
<PixelVectorType
>(DimensionNumber
);
3308 Node
*ElemType
= getDerived().parseType();
3309 if (ElemType
== nullptr)
3311 return make
<VectorType
>(ElemType
, DimensionNumber
);
3314 if (!consumeIf('_')) {
3315 Node
*DimExpr
= getDerived().parseExpr();
3318 if (!consumeIf('_'))
3320 Node
*ElemType
= getDerived().parseType();
3323 return make
<VectorType
>(ElemType
, DimExpr
);
3325 Node
*ElemType
= getDerived().parseType();
3328 return make
<VectorType
>(ElemType
, StringView());
3331 // <decltype> ::= Dt <expression> E # decltype of an id-expression or class member access (C++0x)
3332 // ::= DT <expression> E # decltype of an expression (C++0x)
3333 template <typename Derived
, typename Alloc
>
3334 Node
*AbstractManglingParser
<Derived
, Alloc
>::parseDecltype() {
3335 if (!consumeIf('D'))
3337 if (!consumeIf('t') && !consumeIf('T'))
3339 Node
*E
= getDerived().parseExpr();
3342 if (!consumeIf('E'))
3344 return make
<EnclosingExpr
>("decltype(", E
, ")");
3347 // <array-type> ::= A <positive dimension number> _ <element type>
3348 // ::= A [<dimension expression>] _ <element type>
3349 template <typename Derived
, typename Alloc
>
3350 Node
*AbstractManglingParser
<Derived
, Alloc
>::parseArrayType() {
3351 if (!consumeIf('A'))
3354 NodeOrString Dimension
;
3356 if (std::isdigit(look())) {
3357 Dimension
= parseNumber();
3358 if (!consumeIf('_'))
3360 } else if (!consumeIf('_')) {
3361 Node
*DimExpr
= getDerived().parseExpr();
3362 if (DimExpr
== nullptr)
3364 if (!consumeIf('_'))
3366 Dimension
= DimExpr
;
3369 Node
*Ty
= getDerived().parseType();
3372 return make
<ArrayType
>(Ty
, Dimension
);
3375 // <pointer-to-member-type> ::= M <class type> <member type>
3376 template <typename Derived
, typename Alloc
>
3377 Node
*AbstractManglingParser
<Derived
, Alloc
>::parsePointerToMemberType() {
3378 if (!consumeIf('M'))
3380 Node
*ClassType
= getDerived().parseType();
3381 if (ClassType
== nullptr)
3383 Node
*MemberType
= getDerived().parseType();
3384 if (MemberType
== nullptr)
3386 return make
<PointerToMemberType
>(ClassType
, MemberType
);
3389 // <class-enum-type> ::= <name> # non-dependent type name, dependent type name, or dependent typename-specifier
3390 // ::= Ts <name> # dependent elaborated type specifier using 'struct' or 'class'
3391 // ::= Tu <name> # dependent elaborated type specifier using 'union'
3392 // ::= Te <name> # dependent elaborated type specifier using 'enum'
3393 template <typename Derived
, typename Alloc
>
3394 Node
*AbstractManglingParser
<Derived
, Alloc
>::parseClassEnumType() {
3395 StringView ElabSpef
;
3396 if (consumeIf("Ts"))
3397 ElabSpef
= "struct";
3398 else if (consumeIf("Tu"))
3400 else if (consumeIf("Te"))
3403 Node
*Name
= getDerived().parseName();
3404 if (Name
== nullptr)
3407 if (!ElabSpef
.empty())
3408 return make
<ElaboratedTypeSpefType
>(ElabSpef
, Name
);
3413 // <qualified-type> ::= <qualifiers> <type>
3414 // <qualifiers> ::= <extended-qualifier>* <CV-qualifiers>
3415 // <extended-qualifier> ::= U <source-name> [<template-args>] # vendor extended type qualifier
3416 template <typename Derived
, typename Alloc
>
3417 Node
*AbstractManglingParser
<Derived
, Alloc
>::parseQualifiedType() {
3418 if (consumeIf('U')) {
3419 StringView Qual
= parseBareSourceName();
3423 // FIXME parse the optional <template-args> here!
3425 // extension ::= U <objc-name> <objc-type> # objc-type<identifier>
3426 if (Qual
.startsWith("objcproto")) {
3427 StringView ProtoSourceName
= Qual
.dropFront(std::strlen("objcproto"));
3430 SwapAndRestore
<const char *> SaveFirst(First
, ProtoSourceName
.begin()),
3431 SaveLast(Last
, ProtoSourceName
.end());
3432 Proto
= parseBareSourceName();
3436 Node
*Child
= getDerived().parseQualifiedType();
3437 if (Child
== nullptr)
3439 return make
<ObjCProtoName
>(Child
, Proto
);
3442 Node
*Child
= getDerived().parseQualifiedType();
3443 if (Child
== nullptr)
3445 return make
<VendorExtQualType
>(Child
, Qual
);
3448 Qualifiers Quals
= parseCVQualifiers();
3449 Node
*Ty
= getDerived().parseType();
3452 if (Quals
!= QualNone
)
3453 Ty
= make
<QualType
>(Ty
, Quals
);
3457 // <type> ::= <builtin-type>
3458 // ::= <qualified-type>
3459 // ::= <function-type>
3460 // ::= <class-enum-type>
3462 // ::= <pointer-to-member-type>
3463 // ::= <template-param>
3464 // ::= <template-template-param> <template-args>
3466 // ::= P <type> # pointer
3467 // ::= R <type> # l-value reference
3468 // ::= O <type> # r-value reference (C++11)
3469 // ::= C <type> # complex pair (C99)
3470 // ::= G <type> # imaginary (C99)
3471 // ::= <substitution> # See Compression below
3472 // extension ::= U <objc-name> <objc-type> # objc-type<identifier>
3473 // extension ::= <vector-type> # <vector-type> starts with Dv
3475 // <objc-name> ::= <k0 number> objcproto <k1 number> <identifier> # k0 = 9 + <number of digits in k1> + k1
3476 // <objc-type> ::= <source-name> # PU<11+>objcproto 11objc_object<source-name> 11objc_object -> id<source-name>
3477 template <typename Derived
, typename Alloc
>
3478 Node
*AbstractManglingParser
<Derived
, Alloc
>::parseType() {
3479 Node
*Result
= nullptr;
3482 // ::= <qualified-type>
3486 unsigned AfterQuals
= 0;
3487 if (look(AfterQuals
) == 'r') ++AfterQuals
;
3488 if (look(AfterQuals
) == 'V') ++AfterQuals
;
3489 if (look(AfterQuals
) == 'K') ++AfterQuals
;
3491 if (look(AfterQuals
) == 'F' ||
3492 (look(AfterQuals
) == 'D' &&
3493 (look(AfterQuals
+ 1) == 'o' || look(AfterQuals
+ 1) == 'O' ||
3494 look(AfterQuals
+ 1) == 'w' || look(AfterQuals
+ 1) == 'x'))) {
3495 Result
= getDerived().parseFunctionType();
3498 DEMANGLE_FALLTHROUGH
;
3501 Result
= getDerived().parseQualifiedType();
3504 // <builtin-type> ::= v # void
3507 return make
<NameType
>("void");
3511 return make
<NameType
>("wchar_t");
3515 return make
<NameType
>("bool");
3519 return make
<NameType
>("char");
3520 // ::= a # signed char
3523 return make
<NameType
>("signed char");
3524 // ::= h # unsigned char
3527 return make
<NameType
>("unsigned char");
3531 return make
<NameType
>("short");
3532 // ::= t # unsigned short
3535 return make
<NameType
>("unsigned short");
3539 return make
<NameType
>("int");
3540 // ::= j # unsigned int
3543 return make
<NameType
>("unsigned int");
3547 return make
<NameType
>("long");
3548 // ::= m # unsigned long
3551 return make
<NameType
>("unsigned long");
3552 // ::= x # long long, __int64
3555 return make
<NameType
>("long long");
3556 // ::= y # unsigned long long, __int64
3559 return make
<NameType
>("unsigned long long");
3563 return make
<NameType
>("__int128");
3564 // ::= o # unsigned __int128
3567 return make
<NameType
>("unsigned __int128");
3571 return make
<NameType
>("float");
3575 return make
<NameType
>("double");
3576 // ::= e # long double, __float80
3579 return make
<NameType
>("long double");
3580 // ::= g # __float128
3583 return make
<NameType
>("__float128");
3587 return make
<NameType
>("...");
3589 // <builtin-type> ::= u <source-name> # vendor extended type
3592 StringView Res
= parseBareSourceName();
3595 // Typically, <builtin-type>s are not considered substitution candidates,
3596 // but the exception to that exception is vendor extended types (Itanium C++
3598 Result
= make
<NameType
>(Res
);
3603 // ::= Dd # IEEE 754r decimal floating point (64 bits)
3606 return make
<NameType
>("decimal64");
3607 // ::= De # IEEE 754r decimal floating point (128 bits)
3610 return make
<NameType
>("decimal128");
3611 // ::= Df # IEEE 754r decimal floating point (32 bits)
3614 return make
<NameType
>("decimal32");
3615 // ::= Dh # IEEE 754r half-precision floating point (16 bits)
3618 return make
<NameType
>("decimal16");
3619 // ::= Di # char32_t
3622 return make
<NameType
>("char32_t");
3623 // ::= Ds # char16_t
3626 return make
<NameType
>("char16_t");
3627 // ::= Du # char8_t (C++2a, not yet in the Itanium spec)
3630 return make
<NameType
>("char8_t");
3631 // ::= Da # auto (in dependent new-expressions)
3634 return make
<NameType
>("auto");
3635 // ::= Dc # decltype(auto)
3638 return make
<NameType
>("decltype(auto)");
3639 // ::= Dn # std::nullptr_t (i.e., decltype(nullptr))
3642 return make
<NameType
>("std::nullptr_t");
3647 Result
= getDerived().parseDecltype();
3650 // extension ::= <vector-type> # <vector-type> starts with Dv
3652 Result
= getDerived().parseVectorType();
3655 // ::= Dp <type> # pack expansion (C++0x)
3658 Node
*Child
= getDerived().parseType();
3661 Result
= make
<ParameterPackExpansion
>(Child
);
3664 // Exception specifier on a function type.
3668 // Transaction safe function type.
3670 Result
= getDerived().parseFunctionType();
3674 // ::= <function-type>
3676 Result
= getDerived().parseFunctionType();
3681 Result
= getDerived().parseArrayType();
3684 // ::= <pointer-to-member-type>
3686 Result
= getDerived().parsePointerToMemberType();
3689 // ::= <template-param>
3691 // This could be an elaborate type specifier on a <class-enum-type>.
3692 if (look(1) == 's' || look(1) == 'u' || look(1) == 'e') {
3693 Result
= getDerived().parseClassEnumType();
3697 Result
= getDerived().parseTemplateParam();
3698 if (Result
== nullptr)
3701 // Result could be either of:
3702 // <type> ::= <template-param>
3703 // <type> ::= <template-template-param> <template-args>
3705 // <template-template-param> ::= <template-param>
3706 // ::= <substitution>
3708 // If this is followed by some <template-args>, and we're permitted to
3709 // parse them, take the second production.
3711 if (TryToParseTemplateArgs
&& look() == 'I') {
3712 Node
*TA
= getDerived().parseTemplateArgs();
3715 Result
= make
<NameWithTemplateArgs
>(Result
, TA
);
3719 // ::= P <type> # pointer
3722 Node
*Ptr
= getDerived().parseType();
3725 Result
= make
<PointerType
>(Ptr
);
3728 // ::= R <type> # l-value reference
3731 Node
*Ref
= getDerived().parseType();
3734 Result
= make
<ReferenceType
>(Ref
, ReferenceKind::LValue
);
3737 // ::= O <type> # r-value reference (C++11)
3740 Node
*Ref
= getDerived().parseType();
3743 Result
= make
<ReferenceType
>(Ref
, ReferenceKind::RValue
);
3746 // ::= C <type> # complex pair (C99)
3749 Node
*P
= getDerived().parseType();
3752 Result
= make
<PostfixQualifiedType
>(P
, " complex");
3755 // ::= G <type> # imaginary (C99)
3758 Node
*P
= getDerived().parseType();
3761 Result
= make
<PostfixQualifiedType
>(P
, " imaginary");
3764 // ::= <substitution> # See Compression below
3766 if (look(1) && look(1) != 't') {
3767 Node
*Sub
= getDerived().parseSubstitution();
3771 // Sub could be either of:
3772 // <type> ::= <substitution>
3773 // <type> ::= <template-template-param> <template-args>
3775 // <template-template-param> ::= <template-param>
3776 // ::= <substitution>
3778 // If this is followed by some <template-args>, and we're permitted to
3779 // parse them, take the second production.
3781 if (TryToParseTemplateArgs
&& look() == 'I') {
3782 Node
*TA
= getDerived().parseTemplateArgs();
3785 Result
= make
<NameWithTemplateArgs
>(Sub
, TA
);
3789 // If all we parsed was a substitution, don't re-insert into the
3790 // substitution table.
3793 DEMANGLE_FALLTHROUGH
;
3795 // ::= <class-enum-type>
3797 Result
= getDerived().parseClassEnumType();
3802 // If we parsed a type, insert it into the substitution table. Note that all
3803 // <builtin-type>s and <substitution>s have already bailed out, because they
3804 // don't get substitutions.
3805 if (Result
!= nullptr)
3806 Subs
.push_back(Result
);
3810 template <typename Derived
, typename Alloc
>
3811 Node
*AbstractManglingParser
<Derived
, Alloc
>::parsePrefixExpr(StringView Kind
) {
3812 Node
*E
= getDerived().parseExpr();
3815 return make
<PrefixExpr
>(Kind
, E
);
3818 template <typename Derived
, typename Alloc
>
3819 Node
*AbstractManglingParser
<Derived
, Alloc
>::parseBinaryExpr(StringView Kind
) {
3820 Node
*LHS
= getDerived().parseExpr();
3823 Node
*RHS
= getDerived().parseExpr();
3826 return make
<BinaryExpr
>(LHS
, Kind
, RHS
);
3829 template <typename Derived
, typename Alloc
>
3831 AbstractManglingParser
<Derived
, Alloc
>::parseIntegerLiteral(StringView Lit
) {
3832 StringView Tmp
= parseNumber(true);
3833 if (!Tmp
.empty() && consumeIf('E'))
3834 return make
<IntegerLiteral
>(Lit
, Tmp
);
3838 // <CV-Qualifiers> ::= [r] [V] [K]
3839 template <typename Alloc
, typename Derived
>
3840 Qualifiers AbstractManglingParser
<Alloc
, Derived
>::parseCVQualifiers() {
3841 Qualifiers CVR
= QualNone
;
3843 CVR
|= QualRestrict
;
3845 CVR
|= QualVolatile
;
3851 // <function-param> ::= fp <top-level CV-Qualifiers> _ # L == 0, first parameter
3852 // ::= fp <top-level CV-Qualifiers> <parameter-2 non-negative number> _ # L == 0, second and later parameters
3853 // ::= fL <L-1 non-negative number> p <top-level CV-Qualifiers> _ # L > 0, first parameter
3854 // ::= fL <L-1 non-negative number> p <top-level CV-Qualifiers> <parameter-2 non-negative number> _ # L > 0, second and later parameters
3855 template <typename Derived
, typename Alloc
>
3856 Node
*AbstractManglingParser
<Derived
, Alloc
>::parseFunctionParam() {
3857 if (consumeIf("fp")) {
3858 parseCVQualifiers();
3859 StringView Num
= parseNumber();
3860 if (!consumeIf('_'))
3862 return make
<FunctionParam
>(Num
);
3864 if (consumeIf("fL")) {
3865 if (parseNumber().empty())
3867 if (!consumeIf('p'))
3869 parseCVQualifiers();
3870 StringView Num
= parseNumber();
3871 if (!consumeIf('_'))
3873 return make
<FunctionParam
>(Num
);
3878 // [gs] nw <expression>* _ <type> E # new (expr-list) type
3879 // [gs] nw <expression>* _ <type> <initializer> # new (expr-list) type (init)
3880 // [gs] na <expression>* _ <type> E # new[] (expr-list) type
3881 // [gs] na <expression>* _ <type> <initializer> # new[] (expr-list) type (init)
3882 // <initializer> ::= pi <expression>* E # parenthesized initialization
3883 template <typename Derived
, typename Alloc
>
3884 Node
*AbstractManglingParser
<Derived
, Alloc
>::parseNewExpr() {
3885 bool Global
= consumeIf("gs");
3886 bool IsArray
= look(1) == 'a';
3887 if (!consumeIf("nw") && !consumeIf("na"))
3889 size_t Exprs
= Names
.size();
3890 while (!consumeIf('_')) {
3891 Node
*Ex
= getDerived().parseExpr();
3894 Names
.push_back(Ex
);
3896 NodeArray ExprList
= popTrailingNodeArray(Exprs
);
3897 Node
*Ty
= getDerived().parseType();
3900 if (consumeIf("pi")) {
3901 size_t InitsBegin
= Names
.size();
3902 while (!consumeIf('E')) {
3903 Node
*Init
= getDerived().parseExpr();
3904 if (Init
== nullptr)
3906 Names
.push_back(Init
);
3908 NodeArray Inits
= popTrailingNodeArray(InitsBegin
);
3909 return make
<NewExpr
>(ExprList
, Ty
, Inits
, Global
, IsArray
);
3910 } else if (!consumeIf('E'))
3912 return make
<NewExpr
>(ExprList
, Ty
, NodeArray(), Global
, IsArray
);
3915 // cv <type> <expression> # conversion with one argument
3916 // cv <type> _ <expression>* E # conversion with a different number of arguments
3917 template <typename Derived
, typename Alloc
>
3918 Node
*AbstractManglingParser
<Derived
, Alloc
>::parseConversionExpr() {
3919 if (!consumeIf("cv"))
3923 SwapAndRestore
<bool> SaveTemp(TryToParseTemplateArgs
, false);
3924 Ty
= getDerived().parseType();
3930 if (consumeIf('_')) {
3931 size_t ExprsBegin
= Names
.size();
3932 while (!consumeIf('E')) {
3933 Node
*E
= getDerived().parseExpr();
3938 NodeArray Exprs
= popTrailingNodeArray(ExprsBegin
);
3939 return make
<ConversionExpr
>(Ty
, Exprs
);
3942 Node
*E
[1] = {getDerived().parseExpr()};
3943 if (E
[0] == nullptr)
3945 return make
<ConversionExpr
>(Ty
, makeNodeArray(E
, E
+ 1));
3948 // <expr-primary> ::= L <type> <value number> E # integer literal
3949 // ::= L <type> <value float> E # floating literal
3950 // ::= L <string type> E # string literal
3951 // ::= L <nullptr type> E # nullptr literal (i.e., "LDnE")
3952 // FIXME: ::= L <type> <real-part float> _ <imag-part float> E # complex floating point literal (C 2000)
3953 // ::= L <mangled-name> E # external name
3954 template <typename Derived
, typename Alloc
>
3955 Node
*AbstractManglingParser
<Derived
, Alloc
>::parseExprPrimary() {
3956 if (!consumeIf('L'))
3961 return getDerived().parseIntegerLiteral("wchar_t");
3963 if (consumeIf("b0E"))
3964 return make
<BoolExpr
>(0);
3965 if (consumeIf("b1E"))
3966 return make
<BoolExpr
>(1);
3970 return getDerived().parseIntegerLiteral("char");
3973 return getDerived().parseIntegerLiteral("signed char");
3976 return getDerived().parseIntegerLiteral("unsigned char");
3979 return getDerived().parseIntegerLiteral("short");
3982 return getDerived().parseIntegerLiteral("unsigned short");
3985 return getDerived().parseIntegerLiteral("");
3988 return getDerived().parseIntegerLiteral("u");
3991 return getDerived().parseIntegerLiteral("l");
3994 return getDerived().parseIntegerLiteral("ul");
3997 return getDerived().parseIntegerLiteral("ll");
4000 return getDerived().parseIntegerLiteral("ull");
4003 return getDerived().parseIntegerLiteral("__int128");
4006 return getDerived().parseIntegerLiteral("unsigned __int128");
4009 return getDerived().template parseFloatingLiteral
<float>();
4012 return getDerived().template parseFloatingLiteral
<double>();
4015 return getDerived().template parseFloatingLiteral
<long double>();
4017 if (consumeIf("_Z")) {
4018 Node
*R
= getDerived().parseEncoding();
4019 if (R
!= nullptr && consumeIf('E'))
4024 // Invalid mangled name per
4025 // http://sourcerytools.com/pipermail/cxx-abi-dev/2011-August/002422.html
4028 // might be named type
4029 Node
*T
= getDerived().parseType();
4032 StringView N
= parseNumber();
4034 if (!consumeIf('E'))
4036 return make
<IntegerCastExpr
>(T
, N
);
4045 // <braced-expression> ::= <expression>
4046 // ::= di <field source-name> <braced-expression> # .name = expr
4047 // ::= dx <index expression> <braced-expression> # [expr] = expr
4048 // ::= dX <range begin expression> <range end expression> <braced-expression>
4049 template <typename Derived
, typename Alloc
>
4050 Node
*AbstractManglingParser
<Derived
, Alloc
>::parseBracedExpr() {
4051 if (look() == 'd') {
4055 Node
*Field
= getDerived().parseSourceName(/*NameState=*/nullptr);
4056 if (Field
== nullptr)
4058 Node
*Init
= getDerived().parseBracedExpr();
4059 if (Init
== nullptr)
4061 return make
<BracedExpr
>(Field
, Init
, /*isArray=*/false);
4065 Node
*Index
= getDerived().parseExpr();
4066 if (Index
== nullptr)
4068 Node
*Init
= getDerived().parseBracedExpr();
4069 if (Init
== nullptr)
4071 return make
<BracedExpr
>(Index
, Init
, /*isArray=*/true);
4075 Node
*RangeBegin
= getDerived().parseExpr();
4076 if (RangeBegin
== nullptr)
4078 Node
*RangeEnd
= getDerived().parseExpr();
4079 if (RangeEnd
== nullptr)
4081 Node
*Init
= getDerived().parseBracedExpr();
4082 if (Init
== nullptr)
4084 return make
<BracedRangeExpr
>(RangeBegin
, RangeEnd
, Init
);
4088 return getDerived().parseExpr();
4091 // (not yet in the spec)
4092 // <fold-expr> ::= fL <binary-operator-name> <expression> <expression>
4093 // ::= fR <binary-operator-name> <expression> <expression>
4094 // ::= fl <binary-operator-name> <expression>
4095 // ::= fr <binary-operator-name> <expression>
4096 template <typename Derived
, typename Alloc
>
4097 Node
*AbstractManglingParser
<Derived
, Alloc
>::parseFoldExpr() {
4098 if (!consumeIf('f'))
4101 char FoldKind
= look();
4102 bool IsLeftFold
, HasInitializer
;
4103 HasInitializer
= FoldKind
== 'L' || FoldKind
== 'R';
4104 if (FoldKind
== 'l' || FoldKind
== 'L')
4106 else if (FoldKind
== 'r' || FoldKind
== 'R')
4112 // FIXME: This map is duplicated in parseOperatorName and parseExpr.
4113 StringView OperatorName
;
4114 if (consumeIf("aa")) OperatorName
= "&&";
4115 else if (consumeIf("an")) OperatorName
= "&";
4116 else if (consumeIf("aN")) OperatorName
= "&=";
4117 else if (consumeIf("aS")) OperatorName
= "=";
4118 else if (consumeIf("cm")) OperatorName
= ",";
4119 else if (consumeIf("ds")) OperatorName
= ".*";
4120 else if (consumeIf("dv")) OperatorName
= "/";
4121 else if (consumeIf("dV")) OperatorName
= "/=";
4122 else if (consumeIf("eo")) OperatorName
= "^";
4123 else if (consumeIf("eO")) OperatorName
= "^=";
4124 else if (consumeIf("eq")) OperatorName
= "==";
4125 else if (consumeIf("ge")) OperatorName
= ">=";
4126 else if (consumeIf("gt")) OperatorName
= ">";
4127 else if (consumeIf("le")) OperatorName
= "<=";
4128 else if (consumeIf("ls")) OperatorName
= "<<";
4129 else if (consumeIf("lS")) OperatorName
= "<<=";
4130 else if (consumeIf("lt")) OperatorName
= "<";
4131 else if (consumeIf("mi")) OperatorName
= "-";
4132 else if (consumeIf("mI")) OperatorName
= "-=";
4133 else if (consumeIf("ml")) OperatorName
= "*";
4134 else if (consumeIf("mL")) OperatorName
= "*=";
4135 else if (consumeIf("ne")) OperatorName
= "!=";
4136 else if (consumeIf("oo")) OperatorName
= "||";
4137 else if (consumeIf("or")) OperatorName
= "|";
4138 else if (consumeIf("oR")) OperatorName
= "|=";
4139 else if (consumeIf("pl")) OperatorName
= "+";
4140 else if (consumeIf("pL")) OperatorName
= "+=";
4141 else if (consumeIf("rm")) OperatorName
= "%";
4142 else if (consumeIf("rM")) OperatorName
= "%=";
4143 else if (consumeIf("rs")) OperatorName
= ">>";
4144 else if (consumeIf("rS")) OperatorName
= ">>=";
4145 else return nullptr;
4147 Node
*Pack
= getDerived().parseExpr(), *Init
= nullptr;
4148 if (Pack
== nullptr)
4150 if (HasInitializer
) {
4151 Init
= getDerived().parseExpr();
4152 if (Init
== nullptr)
4156 if (IsLeftFold
&& Init
)
4157 std::swap(Pack
, Init
);
4159 return make
<FoldExpr
>(IsLeftFold
, OperatorName
, Pack
, Init
);
4162 // <expression> ::= <unary operator-name> <expression>
4163 // ::= <binary operator-name> <expression> <expression>
4164 // ::= <ternary operator-name> <expression> <expression> <expression>
4165 // ::= cl <expression>+ E # call
4166 // ::= cv <type> <expression> # conversion with one argument
4167 // ::= cv <type> _ <expression>* E # conversion with a different number of arguments
4168 // ::= [gs] nw <expression>* _ <type> E # new (expr-list) type
4169 // ::= [gs] nw <expression>* _ <type> <initializer> # new (expr-list) type (init)
4170 // ::= [gs] na <expression>* _ <type> E # new[] (expr-list) type
4171 // ::= [gs] na <expression>* _ <type> <initializer> # new[] (expr-list) type (init)
4172 // ::= [gs] dl <expression> # delete expression
4173 // ::= [gs] da <expression> # delete[] expression
4174 // ::= pp_ <expression> # prefix ++
4175 // ::= mm_ <expression> # prefix --
4176 // ::= ti <type> # typeid (type)
4177 // ::= te <expression> # typeid (expression)
4178 // ::= dc <type> <expression> # dynamic_cast<type> (expression)
4179 // ::= sc <type> <expression> # static_cast<type> (expression)
4180 // ::= cc <type> <expression> # const_cast<type> (expression)
4181 // ::= rc <type> <expression> # reinterpret_cast<type> (expression)
4182 // ::= st <type> # sizeof (a type)
4183 // ::= sz <expression> # sizeof (an expression)
4184 // ::= at <type> # alignof (a type)
4185 // ::= az <expression> # alignof (an expression)
4186 // ::= nx <expression> # noexcept (expression)
4187 // ::= <template-param>
4188 // ::= <function-param>
4189 // ::= dt <expression> <unresolved-name> # expr.name
4190 // ::= pt <expression> <unresolved-name> # expr->name
4191 // ::= ds <expression> <expression> # expr.*expr
4192 // ::= sZ <template-param> # size of a parameter pack
4193 // ::= sZ <function-param> # size of a function parameter pack
4194 // ::= sP <template-arg>* E # sizeof...(T), size of a captured template parameter pack from an alias template
4195 // ::= sp <expression> # pack expansion
4196 // ::= tw <expression> # throw expression
4197 // ::= tr # throw with no operand (rethrow)
4198 // ::= <unresolved-name> # f(p), N::f(p), ::f(p),
4199 // # freestanding dependent name (e.g., T::x),
4200 // # objectless nonstatic member reference
4201 // ::= fL <binary-operator-name> <expression> <expression>
4202 // ::= fR <binary-operator-name> <expression> <expression>
4203 // ::= fl <binary-operator-name> <expression>
4204 // ::= fr <binary-operator-name> <expression>
4205 // ::= <expr-primary>
4206 template <typename Derived
, typename Alloc
>
4207 Node
*AbstractManglingParser
<Derived
, Alloc
>::parseExpr() {
4208 bool Global
= consumeIf("gs");
4214 return getDerived().parseExprPrimary();
4216 return getDerived().parseTemplateParam();
4218 // Disambiguate a fold expression from a <function-param>.
4219 if (look(1) == 'p' || (look(1) == 'L' && std::isdigit(look(2))))
4220 return getDerived().parseFunctionParam();
4221 return getDerived().parseFoldExpr();
4227 return getDerived().parseBinaryExpr("&&");
4230 return getDerived().parsePrefixExpr("&");
4233 return getDerived().parseBinaryExpr("&");
4236 return getDerived().parseBinaryExpr("&=");
4239 return getDerived().parseBinaryExpr("=");
4242 Node
*Ty
= getDerived().parseType();
4245 return make
<EnclosingExpr
>("alignof (", Ty
, ")");
4249 Node
*Ty
= getDerived().parseExpr();
4252 return make
<EnclosingExpr
>("alignof (", Ty
, ")");
4258 // cc <type> <expression> # const_cast<type>(expression)
4261 Node
*Ty
= getDerived().parseType();
4264 Node
*Ex
= getDerived().parseExpr();
4267 return make
<CastExpr
>("const_cast", Ty
, Ex
);
4269 // cl <expression>+ E # call
4272 Node
*Callee
= getDerived().parseExpr();
4273 if (Callee
== nullptr)
4275 size_t ExprsBegin
= Names
.size();
4276 while (!consumeIf('E')) {
4277 Node
*E
= getDerived().parseExpr();
4282 return make
<CallExpr
>(Callee
, popTrailingNodeArray(ExprsBegin
));
4286 return getDerived().parseBinaryExpr(",");
4289 return getDerived().parsePrefixExpr("~");
4291 return getDerived().parseConversionExpr();
4298 Node
*Ex
= getDerived().parseExpr();
4301 return make
<DeleteExpr
>(Ex
, Global
, /*is_array=*/true);
4305 Node
*T
= getDerived().parseType();
4308 Node
*Ex
= getDerived().parseExpr();
4311 return make
<CastExpr
>("dynamic_cast", T
, Ex
);
4315 return getDerived().parsePrefixExpr("*");
4318 Node
*E
= getDerived().parseExpr();
4321 return make
<DeleteExpr
>(E
, Global
, /*is_array=*/false);
4324 return getDerived().parseUnresolvedName();
4327 Node
*LHS
= getDerived().parseExpr();
4330 Node
*RHS
= getDerived().parseExpr();
4333 return make
<MemberExpr
>(LHS
, ".*", RHS
);
4337 Node
*LHS
= getDerived().parseExpr();
4340 Node
*RHS
= getDerived().parseExpr();
4343 return make
<MemberExpr
>(LHS
, ".", RHS
);
4347 return getDerived().parseBinaryExpr("/");
4350 return getDerived().parseBinaryExpr("/=");
4357 return getDerived().parseBinaryExpr("^");
4360 return getDerived().parseBinaryExpr("^=");
4363 return getDerived().parseBinaryExpr("==");
4370 return getDerived().parseBinaryExpr(">=");
4373 return getDerived().parseBinaryExpr(">");
4380 Node
*Base
= getDerived().parseExpr();
4381 if (Base
== nullptr)
4383 Node
*Index
= getDerived().parseExpr();
4384 if (Index
== nullptr)
4386 return make
<ArraySubscriptExpr
>(Base
, Index
);
4390 size_t InitsBegin
= Names
.size();
4391 while (!consumeIf('E')) {
4392 Node
*E
= getDerived().parseBracedExpr();
4397 return make
<InitListExpr
>(nullptr, popTrailingNodeArray(InitsBegin
));
4405 return getDerived().parseBinaryExpr("<=");
4408 return getDerived().parseBinaryExpr("<<");
4411 return getDerived().parseBinaryExpr("<<=");
4414 return getDerived().parseBinaryExpr("<");
4421 return getDerived().parseBinaryExpr("-");
4424 return getDerived().parseBinaryExpr("-=");
4427 return getDerived().parseBinaryExpr("*");
4430 return getDerived().parseBinaryExpr("*=");
4434 return getDerived().parsePrefixExpr("--");
4435 Node
*Ex
= getDerived().parseExpr();
4438 return make
<PostfixExpr
>(Ex
, "--");
4445 return getDerived().parseNewExpr();
4448 return getDerived().parseBinaryExpr("!=");
4451 return getDerived().parsePrefixExpr("-");
4454 return getDerived().parsePrefixExpr("!");
4457 Node
*Ex
= getDerived().parseExpr();
4460 return make
<EnclosingExpr
>("noexcept (", Ex
, ")");
4466 return getDerived().parseUnresolvedName();
4469 return getDerived().parseBinaryExpr("||");
4472 return getDerived().parseBinaryExpr("|");
4475 return getDerived().parseBinaryExpr("|=");
4482 return getDerived().parseBinaryExpr("->*");
4485 return getDerived().parseBinaryExpr("+");
4488 return getDerived().parseBinaryExpr("+=");
4492 return getDerived().parsePrefixExpr("++");
4493 Node
*Ex
= getDerived().parseExpr();
4496 return make
<PostfixExpr
>(Ex
, "++");
4500 return getDerived().parsePrefixExpr("+");
4503 Node
*L
= getDerived().parseExpr();
4506 Node
*R
= getDerived().parseExpr();
4509 return make
<MemberExpr
>(L
, "->", R
);
4514 if (First
[1] == 'u') {
4516 Node
*Cond
= getDerived().parseExpr();
4517 if (Cond
== nullptr)
4519 Node
*LHS
= getDerived().parseExpr();
4522 Node
*RHS
= getDerived().parseExpr();
4525 return make
<ConditionalExpr
>(Cond
, LHS
, RHS
);
4532 Node
*T
= getDerived().parseType();
4535 Node
*Ex
= getDerived().parseExpr();
4538 return make
<CastExpr
>("reinterpret_cast", T
, Ex
);
4542 return getDerived().parseBinaryExpr("%");
4545 return getDerived().parseBinaryExpr("%=");
4548 return getDerived().parseBinaryExpr(">>");
4551 return getDerived().parseBinaryExpr(">>=");
4558 Node
*T
= getDerived().parseType();
4561 Node
*Ex
= getDerived().parseExpr();
4564 return make
<CastExpr
>("static_cast", T
, Ex
);
4568 Node
*Child
= getDerived().parseExpr();
4569 if (Child
== nullptr)
4571 return make
<ParameterPackExpansion
>(Child
);
4574 return getDerived().parseUnresolvedName();
4577 Node
*Ty
= getDerived().parseType();
4580 return make
<EnclosingExpr
>("sizeof (", Ty
, ")");
4584 Node
*Ex
= getDerived().parseExpr();
4587 return make
<EnclosingExpr
>("sizeof (", Ex
, ")");
4591 if (look() == 'T') {
4592 Node
*R
= getDerived().parseTemplateParam();
4595 return make
<SizeofParamPackExpr
>(R
);
4596 } else if (look() == 'f') {
4597 Node
*FP
= getDerived().parseFunctionParam();
4600 return make
<EnclosingExpr
>("sizeof... (", FP
, ")");
4605 size_t ArgsBegin
= Names
.size();
4606 while (!consumeIf('E')) {
4607 Node
*Arg
= getDerived().parseTemplateArg();
4610 Names
.push_back(Arg
);
4612 auto *Pack
= make
<NodeArrayNode
>(popTrailingNodeArray(ArgsBegin
));
4615 return make
<EnclosingExpr
>("sizeof... (", Pack
, ")");
4623 Node
*Ex
= getDerived().parseExpr();
4626 return make
<EnclosingExpr
>("typeid (", Ex
, ")");
4630 Node
*Ty
= getDerived().parseType();
4633 return make
<EnclosingExpr
>("typeid (", Ty
, ")");
4637 Node
*Ty
= getDerived().parseType();
4640 size_t InitsBegin
= Names
.size();
4641 while (!consumeIf('E')) {
4642 Node
*E
= getDerived().parseBracedExpr();
4647 return make
<InitListExpr
>(Ty
, popTrailingNodeArray(InitsBegin
));
4651 return make
<NameType
>("throw");
4654 Node
*Ex
= getDerived().parseExpr();
4657 return make
<ThrowExpr
>(Ex
);
4670 return getDerived().parseUnresolvedName();
4673 if (consumeIf("u8__uuidoft")) {
4674 Node
*Ty
= getDerived().parseType();
4677 return make
<UUIDOfExpr
>(Ty
);
4680 if (consumeIf("u8__uuidofz")) {
4681 Node
*Ex
= getDerived().parseExpr();
4684 return make
<UUIDOfExpr
>(Ex
);
4690 // <call-offset> ::= h <nv-offset> _
4691 // ::= v <v-offset> _
4693 // <nv-offset> ::= <offset number>
4694 // # non-virtual base override
4696 // <v-offset> ::= <offset number> _ <virtual offset number>
4697 // # virtual base override, with vcall offset
4698 template <typename Alloc
, typename Derived
>
4699 bool AbstractManglingParser
<Alloc
, Derived
>::parseCallOffset() {
4700 // Just scan through the call offset, we never add this information into the
4703 return parseNumber(true).empty() || !consumeIf('_');
4705 return parseNumber(true).empty() || !consumeIf('_') ||
4706 parseNumber(true).empty() || !consumeIf('_');
4710 // <special-name> ::= TV <type> # virtual table
4711 // ::= TT <type> # VTT structure (construction vtable index)
4712 // ::= TI <type> # typeinfo structure
4713 // ::= TS <type> # typeinfo name (null-terminated byte string)
4714 // ::= Tc <call-offset> <call-offset> <base encoding>
4715 // # base is the nominal target function of thunk
4716 // # first call-offset is 'this' adjustment
4717 // # second call-offset is result adjustment
4718 // ::= T <call-offset> <base encoding>
4719 // # base is the nominal target function of thunk
4720 // ::= GV <object name> # Guard variable for one-time initialization
4722 // ::= TW <object name> # Thread-local wrapper
4723 // ::= TH <object name> # Thread-local initialization
4724 // ::= GR <object name> _ # First temporary
4725 // ::= GR <object name> <seq-id> _ # Subsequent temporaries
4726 // extension ::= TC <first type> <number> _ <second type> # construction vtable for second-in-first
4727 // extension ::= GR <object name> # reference temporary for object
4728 template <typename Derived
, typename Alloc
>
4729 Node
*AbstractManglingParser
<Derived
, Alloc
>::parseSpecialName() {
4733 // TV <type> # virtual table
4736 Node
*Ty
= getDerived().parseType();
4739 return make
<SpecialName
>("vtable for ", Ty
);
4741 // TT <type> # VTT structure (construction vtable index)
4744 Node
*Ty
= getDerived().parseType();
4747 return make
<SpecialName
>("VTT for ", Ty
);
4749 // TI <type> # typeinfo structure
4752 Node
*Ty
= getDerived().parseType();
4755 return make
<SpecialName
>("typeinfo for ", Ty
);
4757 // TS <type> # typeinfo name (null-terminated byte string)
4760 Node
*Ty
= getDerived().parseType();
4763 return make
<SpecialName
>("typeinfo name for ", Ty
);
4765 // Tc <call-offset> <call-offset> <base encoding>
4768 if (parseCallOffset() || parseCallOffset())
4770 Node
*Encoding
= getDerived().parseEncoding();
4771 if (Encoding
== nullptr)
4773 return make
<SpecialName
>("covariant return thunk to ", Encoding
);
4775 // extension ::= TC <first type> <number> _ <second type>
4776 // # construction vtable for second-in-first
4779 Node
*FirstType
= getDerived().parseType();
4780 if (FirstType
== nullptr)
4782 if (parseNumber(true).empty() || !consumeIf('_'))
4784 Node
*SecondType
= getDerived().parseType();
4785 if (SecondType
== nullptr)
4787 return make
<CtorVtableSpecialName
>(SecondType
, FirstType
);
4789 // TW <object name> # Thread-local wrapper
4792 Node
*Name
= getDerived().parseName();
4793 if (Name
== nullptr)
4795 return make
<SpecialName
>("thread-local wrapper routine for ", Name
);
4797 // TH <object name> # Thread-local initialization
4800 Node
*Name
= getDerived().parseName();
4801 if (Name
== nullptr)
4803 return make
<SpecialName
>("thread-local initialization routine for ", Name
);
4805 // T <call-offset> <base encoding>
4808 bool IsVirt
= look() == 'v';
4809 if (parseCallOffset())
4811 Node
*BaseEncoding
= getDerived().parseEncoding();
4812 if (BaseEncoding
== nullptr)
4815 return make
<SpecialName
>("virtual thunk to ", BaseEncoding
);
4817 return make
<SpecialName
>("non-virtual thunk to ", BaseEncoding
);
4822 // GV <object name> # Guard variable for one-time initialization
4825 Node
*Name
= getDerived().parseName();
4826 if (Name
== nullptr)
4828 return make
<SpecialName
>("guard variable for ", Name
);
4830 // GR <object name> # reference temporary for object
4831 // GR <object name> _ # First temporary
4832 // GR <object name> <seq-id> _ # Subsequent temporaries
4835 Node
*Name
= getDerived().parseName();
4836 if (Name
== nullptr)
4839 bool ParsedSeqId
= !parseSeqId(&Count
);
4840 if (!consumeIf('_') && ParsedSeqId
)
4842 return make
<SpecialName
>("reference temporary for ", Name
);
4849 // <encoding> ::= <function name> <bare-function-type>
4851 // ::= <special-name>
4852 template <typename Derived
, typename Alloc
>
4853 Node
*AbstractManglingParser
<Derived
, Alloc
>::parseEncoding() {
4854 if (look() == 'G' || look() == 'T')
4855 return getDerived().parseSpecialName();
4857 auto IsEndOfEncoding
= [&] {
4858 // The set of chars that can potentially follow an <encoding> (none of which
4859 // can start a <type>). Enumerating these allows us to avoid speculative
4861 return numLeft() == 0 || look() == 'E' || look() == '.' || look() == '_';
4864 NameState
NameInfo(this);
4865 Node
*Name
= getDerived().parseName(&NameInfo
);
4866 if (Name
== nullptr)
4869 if (resolveForwardTemplateRefs(NameInfo
))
4872 if (IsEndOfEncoding())
4875 Node
*Attrs
= nullptr;
4876 if (consumeIf("Ua9enable_ifI")) {
4877 size_t BeforeArgs
= Names
.size();
4878 while (!consumeIf('E')) {
4879 Node
*Arg
= getDerived().parseTemplateArg();
4882 Names
.push_back(Arg
);
4884 Attrs
= make
<EnableIfAttr
>(popTrailingNodeArray(BeforeArgs
));
4889 Node
*ReturnType
= nullptr;
4890 if (!NameInfo
.CtorDtorConversion
&& NameInfo
.EndsWithTemplateArgs
) {
4891 ReturnType
= getDerived().parseType();
4892 if (ReturnType
== nullptr)
4897 return make
<FunctionEncoding
>(ReturnType
, Name
, NodeArray(),
4898 Attrs
, NameInfo
.CVQualifiers
,
4899 NameInfo
.ReferenceQualifier
);
4901 size_t ParamsBegin
= Names
.size();
4903 Node
*Ty
= getDerived().parseType();
4906 Names
.push_back(Ty
);
4907 } while (!IsEndOfEncoding());
4909 return make
<FunctionEncoding
>(ReturnType
, Name
,
4910 popTrailingNodeArray(ParamsBegin
),
4911 Attrs
, NameInfo
.CVQualifiers
,
4912 NameInfo
.ReferenceQualifier
);
4915 template <class Float
>
4919 struct FloatData
<float>
4921 static const size_t mangled_size
= 8;
4922 static const size_t max_demangled_size
= 24;
4923 static constexpr const char* spec
= "%af";
4927 struct FloatData
<double>
4929 static const size_t mangled_size
= 16;
4930 static const size_t max_demangled_size
= 32;
4931 static constexpr const char* spec
= "%a";
4935 struct FloatData
<long double>
4937 #if defined(__mips__) && defined(__mips_n64) || defined(__aarch64__) || \
4939 static const size_t mangled_size
= 32;
4940 #elif defined(__arm__) || defined(__mips__) || defined(__hexagon__)
4941 static const size_t mangled_size
= 16;
4943 static const size_t mangled_size
= 20; // May need to be adjusted to 16 or 24 on other platforms
4945 static const size_t max_demangled_size
= 40;
4946 static constexpr const char *spec
= "%LaL";
4949 template <typename Alloc
, typename Derived
>
4950 template <class Float
>
4951 Node
*AbstractManglingParser
<Alloc
, Derived
>::parseFloatingLiteral() {
4952 const size_t N
= FloatData
<Float
>::mangled_size
;
4955 StringView
Data(First
, First
+ N
);
4957 if (!std::isxdigit(C
))
4960 if (!consumeIf('E'))
4962 return make
<FloatLiteralImpl
<Float
>>(Data
);
4965 // <seq-id> ::= <0-9A-Z>+
4966 template <typename Alloc
, typename Derived
>
4967 bool AbstractManglingParser
<Alloc
, Derived
>::parseSeqId(size_t *Out
) {
4968 if (!(look() >= '0' && look() <= '9') &&
4969 !(look() >= 'A' && look() <= 'Z'))
4974 if (look() >= '0' && look() <= '9') {
4976 Id
+= static_cast<size_t>(look() - '0');
4977 } else if (look() >= 'A' && look() <= 'Z') {
4979 Id
+= static_cast<size_t>(look() - 'A') + 10;
4988 // <substitution> ::= S <seq-id> _
4990 // <substitution> ::= Sa # ::std::allocator
4991 // <substitution> ::= Sb # ::std::basic_string
4992 // <substitution> ::= Ss # ::std::basic_string < char,
4993 // ::std::char_traits<char>,
4994 // ::std::allocator<char> >
4995 // <substitution> ::= Si # ::std::basic_istream<char, std::char_traits<char> >
4996 // <substitution> ::= So # ::std::basic_ostream<char, std::char_traits<char> >
4997 // <substitution> ::= Sd # ::std::basic_iostream<char, std::char_traits<char> >
4998 template <typename Derived
, typename Alloc
>
4999 Node
*AbstractManglingParser
<Derived
, Alloc
>::parseSubstitution() {
5000 if (!consumeIf('S'))
5003 if (std::islower(look())) {
5008 SpecialSub
= make
<SpecialSubstitution
>(SpecialSubKind::allocator
);
5012 SpecialSub
= make
<SpecialSubstitution
>(SpecialSubKind::basic_string
);
5016 SpecialSub
= make
<SpecialSubstitution
>(SpecialSubKind::string
);
5020 SpecialSub
= make
<SpecialSubstitution
>(SpecialSubKind::istream
);
5024 SpecialSub
= make
<SpecialSubstitution
>(SpecialSubKind::ostream
);
5028 SpecialSub
= make
<SpecialSubstitution
>(SpecialSubKind::iostream
);
5035 // Itanium C++ ABI 5.1.2: If a name that would use a built-in <substitution>
5036 // has ABI tags, the tags are appended to the substitution; the result is a
5037 // substitutable component.
5038 Node
*WithTags
= getDerived().parseAbiTags(SpecialSub
);
5039 if (WithTags
!= SpecialSub
) {
5040 Subs
.push_back(WithTags
);
5041 SpecialSub
= WithTags
;
5047 if (consumeIf('_')) {
5055 if (parseSeqId(&Index
))
5058 if (!consumeIf('_') || Index
>= Subs
.size())
5063 // <template-param> ::= T_ # first template parameter
5064 // ::= T <parameter-2 non-negative number> _
5065 template <typename Derived
, typename Alloc
>
5066 Node
*AbstractManglingParser
<Derived
, Alloc
>::parseTemplateParam() {
5067 if (!consumeIf('T'))
5071 if (!consumeIf('_')) {
5072 if (parsePositiveInteger(&Index
))
5075 if (!consumeIf('_'))
5079 // Itanium ABI 5.1.8: In a generic lambda, uses of auto in the parameter list
5080 // are mangled as the corresponding artificial template type parameter.
5081 if (ParsingLambdaParams
)
5082 return make
<NameType
>("auto");
5084 // If we're in a context where this <template-param> refers to a
5085 // <template-arg> further ahead in the mangled name (currently just conversion
5086 // operator types), then we should only look it up in the right context.
5087 if (PermitForwardTemplateReferences
) {
5088 Node
*ForwardRef
= make
<ForwardTemplateReference
>(Index
);
5091 assert(ForwardRef
->getKind() == Node::KForwardTemplateReference
);
5092 ForwardTemplateRefs
.push_back(
5093 static_cast<ForwardTemplateReference
*>(ForwardRef
));
5097 if (Index
>= TemplateParams
.size())
5099 return TemplateParams
[Index
];
5102 // <template-arg> ::= <type> # type or template
5103 // ::= X <expression> E # expression
5104 // ::= <expr-primary> # simple expressions
5105 // ::= J <template-arg>* E # argument pack
5106 // ::= LZ <encoding> E # extension
5107 template <typename Derived
, typename Alloc
>
5108 Node
*AbstractManglingParser
<Derived
, Alloc
>::parseTemplateArg() {
5112 Node
*Arg
= getDerived().parseExpr();
5113 if (Arg
== nullptr || !consumeIf('E'))
5119 size_t ArgsBegin
= Names
.size();
5120 while (!consumeIf('E')) {
5121 Node
*Arg
= getDerived().parseTemplateArg();
5124 Names
.push_back(Arg
);
5126 NodeArray Args
= popTrailingNodeArray(ArgsBegin
);
5127 return make
<TemplateArgumentPack
>(Args
);
5130 // ::= LZ <encoding> E # extension
5131 if (look(1) == 'Z') {
5133 Node
*Arg
= getDerived().parseEncoding();
5134 if (Arg
== nullptr || !consumeIf('E'))
5138 // ::= <expr-primary> # simple expressions
5139 return getDerived().parseExprPrimary();
5142 return getDerived().parseType();
5146 // <template-args> ::= I <template-arg>* E
5147 // extension, the abi says <template-arg>+
5148 template <typename Derived
, typename Alloc
>
5150 AbstractManglingParser
<Derived
, Alloc
>::parseTemplateArgs(bool TagTemplates
) {
5151 if (!consumeIf('I'))
5154 // <template-params> refer to the innermost <template-args>. Clear out any
5155 // outer args that we may have inserted into TemplateParams.
5157 TemplateParams
.clear();
5159 size_t ArgsBegin
= Names
.size();
5160 while (!consumeIf('E')) {
5162 auto OldParams
= std::move(TemplateParams
);
5163 Node
*Arg
= getDerived().parseTemplateArg();
5164 TemplateParams
= std::move(OldParams
);
5167 Names
.push_back(Arg
);
5168 Node
*TableEntry
= Arg
;
5169 if (Arg
->getKind() == Node::KTemplateArgumentPack
) {
5170 TableEntry
= make
<ParameterPack
>(
5171 static_cast<TemplateArgumentPack
*>(TableEntry
)->getElements());
5175 TemplateParams
.push_back(TableEntry
);
5177 Node
*Arg
= getDerived().parseTemplateArg();
5180 Names
.push_back(Arg
);
5183 return make
<TemplateArgs
>(popTrailingNodeArray(ArgsBegin
));
5186 // <mangled-name> ::= _Z <encoding>
5188 // extension ::= ___Z <encoding> _block_invoke
5189 // extension ::= ___Z <encoding> _block_invoke<decimal-digit>+
5190 // extension ::= ___Z <encoding> _block_invoke_<decimal-digit>+
5191 template <typename Derived
, typename Alloc
>
5192 Node
*AbstractManglingParser
<Derived
, Alloc
>::parse() {
5193 if (consumeIf("_Z") || consumeIf("__Z")) {
5194 Node
*Encoding
= getDerived().parseEncoding();
5195 if (Encoding
== nullptr)
5197 if (look() == '.') {
5198 Encoding
= make
<DotSuffix
>(Encoding
, StringView(First
, Last
));
5206 if (consumeIf("___Z") || consumeIf("____Z")) {
5207 Node
*Encoding
= getDerived().parseEncoding();
5208 if (Encoding
== nullptr || !consumeIf("_block_invoke"))
5210 bool RequireNumber
= consumeIf('_');
5211 if (parseNumber().empty() && RequireNumber
)
5217 return make
<SpecialName
>("invocation function for block in ", Encoding
);
5220 Node
*Ty
= getDerived().parseType();
5226 template <typename Alloc
>
5227 struct ManglingParser
: AbstractManglingParser
<ManglingParser
<Alloc
>, Alloc
> {
5228 using AbstractManglingParser
<ManglingParser
<Alloc
>,
5229 Alloc
>::AbstractManglingParser
;
5232 DEMANGLE_NAMESPACE_END
5234 #endif // DEMANGLE_ITANIUMDEMANGLE_H