• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 //===------------------------- ItaniumDemangle.h ----------------*- C++ -*-===//
2 //
3 //                     The LLVM Compiler Infrastructure
4 //
5 // This file is dual licensed under the MIT and the University of Illinois Open
6 // Source Licenses. See LICENSE.TXT for details.
7 //
8 //===----------------------------------------------------------------------===//
9 //
10 // WARNING: This file defines its contents within an anonymous namespace. It
11 // should not be included anywhere other than cxa_demangle.h.
12 //
13 //===----------------------------------------------------------------------===//
14 
15 #ifndef LIBCXX_DEMANGLE_ITANIUMDEMANGLE_H
16 #define LIBCXX_DEMANGLE_ITANIUMDEMANGLE_H
17 
18 // FIXME: (possibly) incomplete list of features that clang mangles that this
19 // file does not yet support:
20 //   - C++ modules TS
21 
22 #include "Compiler.h"
23 #include "StringView.h"
24 #include "Utility.h"
25 
26 #include <cassert>
27 #include <cctype>
28 #include <cstdio>
29 #include <cstdlib>
30 #include <cstring>
31 #include <numeric>
32 #include <utility>
33 
34 #define FOR_EACH_NODE_KIND(X) \
35     X(NodeArrayNode) \
36     X(DotSuffix) \
37     X(VendorExtQualType) \
38     X(QualType) \
39     X(ConversionOperatorType) \
40     X(PostfixQualifiedType) \
41     X(ElaboratedTypeSpefType) \
42     X(NameType) \
43     X(AbiTagAttr) \
44     X(EnableIfAttr) \
45     X(ObjCProtoName) \
46     X(PointerType) \
47     X(ReferenceType) \
48     X(PointerToMemberType) \
49     X(ArrayType) \
50     X(FunctionType) \
51     X(NoexceptSpec) \
52     X(DynamicExceptionSpec) \
53     X(FunctionEncoding) \
54     X(LiteralOperator) \
55     X(SpecialName) \
56     X(CtorVtableSpecialName) \
57     X(QualifiedName) \
58     X(NestedName) \
59     X(LocalName) \
60     X(VectorType) \
61     X(PixelVectorType) \
62     X(ParameterPack) \
63     X(TemplateArgumentPack) \
64     X(ParameterPackExpansion) \
65     X(TemplateArgs) \
66     X(ForwardTemplateReference) \
67     X(NameWithTemplateArgs) \
68     X(GlobalQualifiedName) \
69     X(StdQualifiedName) \
70     X(ExpandedSpecialSubstitution) \
71     X(SpecialSubstitution) \
72     X(CtorDtorName) \
73     X(DtorName) \
74     X(UnnamedTypeName) \
75     X(ClosureTypeName) \
76     X(StructuredBindingName) \
77     X(BinaryExpr) \
78     X(ArraySubscriptExpr) \
79     X(PostfixExpr) \
80     X(ConditionalExpr) \
81     X(MemberExpr) \
82     X(EnclosingExpr) \
83     X(CastExpr) \
84     X(SizeofParamPackExpr) \
85     X(CallExpr) \
86     X(NewExpr) \
87     X(DeleteExpr) \
88     X(PrefixExpr) \
89     X(FunctionParam) \
90     X(ConversionExpr) \
91     X(InitListExpr) \
92     X(FoldExpr) \
93     X(ThrowExpr) \
94     X(BoolExpr) \
95     X(IntegerCastExpr) \
96     X(IntegerLiteral) \
97     X(FloatLiteral) \
98     X(DoubleLiteral) \
99     X(LongDoubleLiteral) \
100     X(BracedExpr) \
101     X(BracedRangeExpr)
102 
103 namespace {
104 namespace itanium_demangle {
105 // Base class of all AST nodes. The AST is built by the parser, then is
106 // traversed by the printLeft/Right functions to produce a demangled string.
107 class Node {
108 public:
109   enum Kind : unsigned char {
110 #define ENUMERATOR(NodeKind) K ## NodeKind,
111     FOR_EACH_NODE_KIND(ENUMERATOR)
112 #undef ENUMERATOR
113   };
114 
115   /// Three-way bool to track a cached value. Unknown is possible if this node
116   /// has an unexpanded parameter pack below it that may affect this cache.
117   enum class Cache : unsigned char { Yes, No, Unknown, };
118 
119 private:
120   Kind K;
121 
122   // FIXME: Make these protected.
123 public:
124   /// Tracks if this node has a component on its right side, in which case we
125   /// need to call printRight.
126   Cache RHSComponentCache;
127 
128   /// Track if this node is a (possibly qualified) array type. This can affect
129   /// how we format the output string.
130   Cache ArrayCache;
131 
132   /// Track if this node is a (possibly qualified) function type. This can
133   /// affect how we format the output string.
134   Cache FunctionCache;
135 
136 public:
137   Node(Kind K_, Cache RHSComponentCache_ = Cache::No,
138        Cache ArrayCache_ = Cache::No, Cache FunctionCache_ = Cache::No)
K(K_)139       : K(K_), RHSComponentCache(RHSComponentCache_), ArrayCache(ArrayCache_),
140         FunctionCache(FunctionCache_) {}
141 
142   /// Visit the most-derived object corresponding to this object.
143   template<typename Fn> void visit(Fn F) const;
144 
145   // The following function is provided by all derived classes:
146   //
147   // Call F with arguments that, when passed to the constructor of this node,
148   // would construct an equivalent node.
149   //template<typename Fn> void match(Fn F) const;
150 
hasRHSComponent(OutputStream & S)151   bool hasRHSComponent(OutputStream &S) const {
152     if (RHSComponentCache != Cache::Unknown)
153       return RHSComponentCache == Cache::Yes;
154     return hasRHSComponentSlow(S);
155   }
156 
hasArray(OutputStream & S)157   bool hasArray(OutputStream &S) const {
158     if (ArrayCache != Cache::Unknown)
159       return ArrayCache == Cache::Yes;
160     return hasArraySlow(S);
161   }
162 
hasFunction(OutputStream & S)163   bool hasFunction(OutputStream &S) const {
164     if (FunctionCache != Cache::Unknown)
165       return FunctionCache == Cache::Yes;
166     return hasFunctionSlow(S);
167   }
168 
getKind()169   Kind getKind() const { return K; }
170 
hasRHSComponentSlow(OutputStream &)171   virtual bool hasRHSComponentSlow(OutputStream &) const { return false; }
hasArraySlow(OutputStream &)172   virtual bool hasArraySlow(OutputStream &) const { return false; }
hasFunctionSlow(OutputStream &)173   virtual bool hasFunctionSlow(OutputStream &) const { return false; }
174 
175   // Dig through "glue" nodes like ParameterPack and ForwardTemplateReference to
176   // get at a node that actually represents some concrete syntax.
getSyntaxNode(OutputStream &)177   virtual const Node *getSyntaxNode(OutputStream &) const {
178     return this;
179   }
180 
print(OutputStream & S)181   void print(OutputStream &S) const {
182     printLeft(S);
183     if (RHSComponentCache != Cache::No)
184       printRight(S);
185   }
186 
187   // Print the "left" side of this Node into OutputStream.
188   virtual void printLeft(OutputStream &) const = 0;
189 
190   // Print the "right". This distinction is necessary to represent C++ types
191   // that appear on the RHS of their subtype, such as arrays or functions.
192   // Since most types don't have such a component, provide a default
193   // implementation.
printRight(OutputStream &)194   virtual void printRight(OutputStream &) const {}
195 
getBaseName()196   virtual StringView getBaseName() const { return StringView(); }
197 
198   // Silence compiler warnings, this dtor will never be called.
199   virtual ~Node() = default;
200 
201 #ifndef NDEBUG
202   DUMP_METHOD void dump() const;
203 #endif
204 };
205 
206 class NodeArray {
207   Node **Elements;
208   size_t NumElements;
209 
210 public:
NodeArray()211   NodeArray() : Elements(nullptr), NumElements(0) {}
NodeArray(Node ** Elements_,size_t NumElements_)212   NodeArray(Node **Elements_, size_t NumElements_)
213       : Elements(Elements_), NumElements(NumElements_) {}
214 
empty()215   bool empty() const { return NumElements == 0; }
size()216   size_t size() const { return NumElements; }
217 
begin()218   Node **begin() const { return Elements; }
end()219   Node **end() const { return Elements + NumElements; }
220 
221   Node *operator[](size_t Idx) const { return Elements[Idx]; }
222 
printWithComma(OutputStream & S)223   void printWithComma(OutputStream &S) const {
224     bool FirstElement = true;
225     for (size_t Idx = 0; Idx != NumElements; ++Idx) {
226       size_t BeforeComma = S.getCurrentPosition();
227       if (!FirstElement)
228         S += ", ";
229       size_t AfterComma = S.getCurrentPosition();
230       Elements[Idx]->print(S);
231 
232       // Elements[Idx] is an empty parameter pack expansion, we should erase the
233       // comma we just printed.
234       if (AfterComma == S.getCurrentPosition()) {
235         S.setCurrentPosition(BeforeComma);
236         continue;
237       }
238 
239       FirstElement = false;
240     }
241   }
242 };
243 
244 struct NodeArrayNode : Node {
245   NodeArray Array;
NodeArrayNodeNodeArrayNode246   NodeArrayNode(NodeArray Array_) : Node(KNodeArrayNode), Array(Array_) {}
247 
matchNodeArrayNode248   template<typename Fn> void match(Fn F) const { F(Array); }
249 
printLeftNodeArrayNode250   void printLeft(OutputStream &S) const override {
251     Array.printWithComma(S);
252   }
253 };
254 
255 class DotSuffix final : public Node {
256   const Node *Prefix;
257   const StringView Suffix;
258 
259 public:
DotSuffix(const Node * Prefix_,StringView Suffix_)260   DotSuffix(const Node *Prefix_, StringView Suffix_)
261       : Node(KDotSuffix), Prefix(Prefix_), Suffix(Suffix_) {}
262 
match(Fn F)263   template<typename Fn> void match(Fn F) const { F(Prefix, Suffix); }
264 
printLeft(OutputStream & s)265   void printLeft(OutputStream &s) const override {
266     Prefix->print(s);
267     s += " (";
268     s += Suffix;
269     s += ")";
270   }
271 };
272 
273 class VendorExtQualType final : public Node {
274   const Node *Ty;
275   StringView Ext;
276 
277 public:
VendorExtQualType(const Node * Ty_,StringView Ext_)278   VendorExtQualType(const Node *Ty_, StringView Ext_)
279       : Node(KVendorExtQualType), Ty(Ty_), Ext(Ext_) {}
280 
match(Fn F)281   template<typename Fn> void match(Fn F) const { F(Ty, Ext); }
282 
printLeft(OutputStream & S)283   void printLeft(OutputStream &S) const override {
284     Ty->print(S);
285     S += " ";
286     S += Ext;
287   }
288 };
289 
290 enum FunctionRefQual : unsigned char {
291   FrefQualNone,
292   FrefQualLValue,
293   FrefQualRValue,
294 };
295 
296 enum Qualifiers {
297   QualNone = 0,
298   QualConst = 0x1,
299   QualVolatile = 0x2,
300   QualRestrict = 0x4,
301 };
302 
303 inline Qualifiers operator|=(Qualifiers &Q1, Qualifiers Q2) {
304   return Q1 = static_cast<Qualifiers>(Q1 | Q2);
305 }
306 
307 class QualType : public Node {
308 protected:
309   const Qualifiers Quals;
310   const Node *Child;
311 
printQuals(OutputStream & S)312   void printQuals(OutputStream &S) const {
313     if (Quals & QualConst)
314       S += " const";
315     if (Quals & QualVolatile)
316       S += " volatile";
317     if (Quals & QualRestrict)
318       S += " restrict";
319   }
320 
321 public:
QualType(const Node * Child_,Qualifiers Quals_)322   QualType(const Node *Child_, Qualifiers Quals_)
323       : Node(KQualType, Child_->RHSComponentCache,
324              Child_->ArrayCache, Child_->FunctionCache),
325         Quals(Quals_), Child(Child_) {}
326 
match(Fn F)327   template<typename Fn> void match(Fn F) const { F(Child, Quals); }
328 
hasRHSComponentSlow(OutputStream & S)329   bool hasRHSComponentSlow(OutputStream &S) const override {
330     return Child->hasRHSComponent(S);
331   }
hasArraySlow(OutputStream & S)332   bool hasArraySlow(OutputStream &S) const override {
333     return Child->hasArray(S);
334   }
hasFunctionSlow(OutputStream & S)335   bool hasFunctionSlow(OutputStream &S) const override {
336     return Child->hasFunction(S);
337   }
338 
printLeft(OutputStream & S)339   void printLeft(OutputStream &S) const override {
340     Child->printLeft(S);
341     printQuals(S);
342   }
343 
printRight(OutputStream & S)344   void printRight(OutputStream &S) const override { Child->printRight(S); }
345 };
346 
347 class ConversionOperatorType final : public Node {
348   const Node *Ty;
349 
350 public:
ConversionOperatorType(const Node * Ty_)351   ConversionOperatorType(const Node *Ty_)
352       : Node(KConversionOperatorType), Ty(Ty_) {}
353 
match(Fn F)354   template<typename Fn> void match(Fn F) const { F(Ty); }
355 
printLeft(OutputStream & S)356   void printLeft(OutputStream &S) const override {
357     S += "operator ";
358     Ty->print(S);
359   }
360 };
361 
362 class PostfixQualifiedType final : public Node {
363   const Node *Ty;
364   const StringView Postfix;
365 
366 public:
PostfixQualifiedType(Node * Ty_,StringView Postfix_)367   PostfixQualifiedType(Node *Ty_, StringView Postfix_)
368       : Node(KPostfixQualifiedType), Ty(Ty_), Postfix(Postfix_) {}
369 
match(Fn F)370   template<typename Fn> void match(Fn F) const { F(Ty, Postfix); }
371 
printLeft(OutputStream & s)372   void printLeft(OutputStream &s) const override {
373     Ty->printLeft(s);
374     s += Postfix;
375   }
376 };
377 
378 class NameType final : public Node {
379   const StringView Name;
380 
381 public:
NameType(StringView Name_)382   NameType(StringView Name_) : Node(KNameType), Name(Name_) {}
383 
match(Fn F)384   template<typename Fn> void match(Fn F) const { F(Name); }
385 
getName()386   StringView getName() const { return Name; }
getBaseName()387   StringView getBaseName() const override { return Name; }
388 
printLeft(OutputStream & s)389   void printLeft(OutputStream &s) const override { s += Name; }
390 };
391 
392 class ElaboratedTypeSpefType : public Node {
393   StringView Kind;
394   Node *Child;
395 public:
ElaboratedTypeSpefType(StringView Kind_,Node * Child_)396   ElaboratedTypeSpefType(StringView Kind_, Node *Child_)
397       : Node(KElaboratedTypeSpefType), Kind(Kind_), Child(Child_) {}
398 
match(Fn F)399   template<typename Fn> void match(Fn F) const { F(Kind, Child); }
400 
printLeft(OutputStream & S)401   void printLeft(OutputStream &S) const override {
402     S += Kind;
403     S += ' ';
404     Child->print(S);
405   }
406 };
407 
408 struct AbiTagAttr : Node {
409   Node *Base;
410   StringView Tag;
411 
AbiTagAttrAbiTagAttr412   AbiTagAttr(Node* Base_, StringView Tag_)
413       : Node(KAbiTagAttr, Base_->RHSComponentCache,
414              Base_->ArrayCache, Base_->FunctionCache),
415         Base(Base_), Tag(Tag_) {}
416 
matchAbiTagAttr417   template<typename Fn> void match(Fn F) const { F(Base, Tag); }
418 
printLeftAbiTagAttr419   void printLeft(OutputStream &S) const override {
420     Base->printLeft(S);
421     S += "[abi:";
422     S += Tag;
423     S += "]";
424   }
425 };
426 
427 class EnableIfAttr : public Node {
428   NodeArray Conditions;
429 public:
EnableIfAttr(NodeArray Conditions_)430   EnableIfAttr(NodeArray Conditions_)
431       : Node(KEnableIfAttr), Conditions(Conditions_) {}
432 
match(Fn F)433   template<typename Fn> void match(Fn F) const { F(Conditions); }
434 
printLeft(OutputStream & S)435   void printLeft(OutputStream &S) const override {
436     S += " [enable_if:";
437     Conditions.printWithComma(S);
438     S += ']';
439   }
440 };
441 
442 class ObjCProtoName : public Node {
443   const Node *Ty;
444   StringView Protocol;
445 
446   friend class PointerType;
447 
448 public:
ObjCProtoName(const Node * Ty_,StringView Protocol_)449   ObjCProtoName(const Node *Ty_, StringView Protocol_)
450       : Node(KObjCProtoName), Ty(Ty_), Protocol(Protocol_) {}
451 
match(Fn F)452   template<typename Fn> void match(Fn F) const { F(Ty, Protocol); }
453 
isObjCObject()454   bool isObjCObject() const {
455     return Ty->getKind() == KNameType &&
456            static_cast<const NameType *>(Ty)->getName() == "objc_object";
457   }
458 
printLeft(OutputStream & S)459   void printLeft(OutputStream &S) const override {
460     Ty->print(S);
461     S += "<";
462     S += Protocol;
463     S += ">";
464   }
465 };
466 
467 class PointerType final : public Node {
468   const Node *Pointee;
469 
470 public:
PointerType(const Node * Pointee_)471   PointerType(const Node *Pointee_)
472       : Node(KPointerType, Pointee_->RHSComponentCache),
473         Pointee(Pointee_) {}
474 
match(Fn F)475   template<typename Fn> void match(Fn F) const { F(Pointee); }
476 
hasRHSComponentSlow(OutputStream & S)477   bool hasRHSComponentSlow(OutputStream &S) const override {
478     return Pointee->hasRHSComponent(S);
479   }
480 
printLeft(OutputStream & s)481   void printLeft(OutputStream &s) const override {
482     // We rewrite objc_object<SomeProtocol>* into id<SomeProtocol>.
483     if (Pointee->getKind() != KObjCProtoName ||
484         !static_cast<const ObjCProtoName *>(Pointee)->isObjCObject()) {
485       Pointee->printLeft(s);
486       if (Pointee->hasArray(s))
487         s += " ";
488       if (Pointee->hasArray(s) || Pointee->hasFunction(s))
489         s += "(";
490       s += "*";
491     } else {
492       const auto *objcProto = static_cast<const ObjCProtoName *>(Pointee);
493       s += "id<";
494       s += objcProto->Protocol;
495       s += ">";
496     }
497   }
498 
printRight(OutputStream & s)499   void printRight(OutputStream &s) const override {
500     if (Pointee->getKind() != KObjCProtoName ||
501         !static_cast<const ObjCProtoName *>(Pointee)->isObjCObject()) {
502       if (Pointee->hasArray(s) || Pointee->hasFunction(s))
503         s += ")";
504       Pointee->printRight(s);
505     }
506   }
507 };
508 
509 enum class ReferenceKind {
510   LValue,
511   RValue,
512 };
513 
514 // Represents either a LValue or an RValue reference type.
515 class ReferenceType : public Node {
516   const Node *Pointee;
517   ReferenceKind RK;
518 
519   mutable bool Printing = false;
520 
521   // Dig through any refs to refs, collapsing the ReferenceTypes as we go. The
522   // rule here is rvalue ref to rvalue ref collapses to a rvalue ref, and any
523   // other combination collapses to a lvalue ref.
collapse(OutputStream & S)524   std::pair<ReferenceKind, const Node *> collapse(OutputStream &S) const {
525     auto SoFar = std::make_pair(RK, Pointee);
526     for (;;) {
527       const Node *SN = SoFar.second->getSyntaxNode(S);
528       if (SN->getKind() != KReferenceType)
529         break;
530       auto *RT = static_cast<const ReferenceType *>(SN);
531       SoFar.second = RT->Pointee;
532       SoFar.first = std::min(SoFar.first, RT->RK);
533     }
534     return SoFar;
535   }
536 
537 public:
ReferenceType(const Node * Pointee_,ReferenceKind RK_)538   ReferenceType(const Node *Pointee_, ReferenceKind RK_)
539       : Node(KReferenceType, Pointee_->RHSComponentCache),
540         Pointee(Pointee_), RK(RK_) {}
541 
match(Fn F)542   template<typename Fn> void match(Fn F) const { F(Pointee, RK); }
543 
hasRHSComponentSlow(OutputStream & S)544   bool hasRHSComponentSlow(OutputStream &S) const override {
545     return Pointee->hasRHSComponent(S);
546   }
547 
printLeft(OutputStream & s)548   void printLeft(OutputStream &s) const override {
549     if (Printing)
550       return;
551     SwapAndRestore<bool> SavePrinting(Printing, true);
552     std::pair<ReferenceKind, const Node *> Collapsed = collapse(s);
553     Collapsed.second->printLeft(s);
554     if (Collapsed.second->hasArray(s))
555       s += " ";
556     if (Collapsed.second->hasArray(s) || Collapsed.second->hasFunction(s))
557       s += "(";
558 
559     s += (Collapsed.first == ReferenceKind::LValue ? "&" : "&&");
560   }
printRight(OutputStream & s)561   void printRight(OutputStream &s) const override {
562     if (Printing)
563       return;
564     SwapAndRestore<bool> SavePrinting(Printing, true);
565     std::pair<ReferenceKind, const Node *> Collapsed = collapse(s);
566     if (Collapsed.second->hasArray(s) || Collapsed.second->hasFunction(s))
567       s += ")";
568     Collapsed.second->printRight(s);
569   }
570 };
571 
572 class PointerToMemberType final : public Node {
573   const Node *ClassType;
574   const Node *MemberType;
575 
576 public:
PointerToMemberType(const Node * ClassType_,const Node * MemberType_)577   PointerToMemberType(const Node *ClassType_, const Node *MemberType_)
578       : Node(KPointerToMemberType, MemberType_->RHSComponentCache),
579         ClassType(ClassType_), MemberType(MemberType_) {}
580 
match(Fn F)581   template<typename Fn> void match(Fn F) const { F(ClassType, MemberType); }
582 
hasRHSComponentSlow(OutputStream & S)583   bool hasRHSComponentSlow(OutputStream &S) const override {
584     return MemberType->hasRHSComponent(S);
585   }
586 
printLeft(OutputStream & s)587   void printLeft(OutputStream &s) const override {
588     MemberType->printLeft(s);
589     if (MemberType->hasArray(s) || MemberType->hasFunction(s))
590       s += "(";
591     else
592       s += " ";
593     ClassType->print(s);
594     s += "::*";
595   }
596 
printRight(OutputStream & s)597   void printRight(OutputStream &s) const override {
598     if (MemberType->hasArray(s) || MemberType->hasFunction(s))
599       s += ")";
600     MemberType->printRight(s);
601   }
602 };
603 
604 class NodeOrString {
605   const void *First;
606   const void *Second;
607 
608 public:
NodeOrString(StringView Str)609   /* implicit */ NodeOrString(StringView Str) {
610     const char *FirstChar = Str.begin();
611     const char *SecondChar = Str.end();
612     if (SecondChar == nullptr) {
613       assert(FirstChar == SecondChar);
614       ++FirstChar, ++SecondChar;
615     }
616     First = static_cast<const void *>(FirstChar);
617     Second = static_cast<const void *>(SecondChar);
618   }
619 
NodeOrString(Node * N)620   /* implicit */ NodeOrString(Node *N)
621       : First(static_cast<const void *>(N)), Second(nullptr) {}
NodeOrString()622   NodeOrString() : First(nullptr), Second(nullptr) {}
623 
isString()624   bool isString() const { return Second && First; }
isNode()625   bool isNode() const { return First && !Second; }
isEmpty()626   bool isEmpty() const { return !First && !Second; }
627 
asString()628   StringView asString() const {
629     assert(isString());
630     return StringView(static_cast<const char *>(First),
631                       static_cast<const char *>(Second));
632   }
633 
asNode()634   const Node *asNode() const {
635     assert(isNode());
636     return static_cast<const Node *>(First);
637   }
638 };
639 
640 class ArrayType final : public Node {
641   const Node *Base;
642   NodeOrString Dimension;
643 
644 public:
ArrayType(const Node * Base_,NodeOrString Dimension_)645   ArrayType(const Node *Base_, NodeOrString Dimension_)
646       : Node(KArrayType,
647              /*RHSComponentCache=*/Cache::Yes,
648              /*ArrayCache=*/Cache::Yes),
649         Base(Base_), Dimension(Dimension_) {}
650 
match(Fn F)651   template<typename Fn> void match(Fn F) const { F(Base, Dimension); }
652 
hasRHSComponentSlow(OutputStream &)653   bool hasRHSComponentSlow(OutputStream &) const override { return true; }
hasArraySlow(OutputStream &)654   bool hasArraySlow(OutputStream &) const override { return true; }
655 
printLeft(OutputStream & S)656   void printLeft(OutputStream &S) const override { Base->printLeft(S); }
657 
printRight(OutputStream & S)658   void printRight(OutputStream &S) const override {
659     if (S.back() != ']')
660       S += " ";
661     S += "[";
662     if (Dimension.isString())
663       S += Dimension.asString();
664     else if (Dimension.isNode())
665       Dimension.asNode()->print(S);
666     S += "]";
667     Base->printRight(S);
668   }
669 };
670 
671 class FunctionType final : public Node {
672   const Node *Ret;
673   NodeArray Params;
674   Qualifiers CVQuals;
675   FunctionRefQual RefQual;
676   const Node *ExceptionSpec;
677 
678 public:
FunctionType(const Node * Ret_,NodeArray Params_,Qualifiers CVQuals_,FunctionRefQual RefQual_,const Node * ExceptionSpec_)679   FunctionType(const Node *Ret_, NodeArray Params_, Qualifiers CVQuals_,
680                FunctionRefQual RefQual_, const Node *ExceptionSpec_)
681       : Node(KFunctionType,
682              /*RHSComponentCache=*/Cache::Yes, /*ArrayCache=*/Cache::No,
683              /*FunctionCache=*/Cache::Yes),
684         Ret(Ret_), Params(Params_), CVQuals(CVQuals_), RefQual(RefQual_),
685         ExceptionSpec(ExceptionSpec_) {}
686 
match(Fn F)687   template<typename Fn> void match(Fn F) const {
688     F(Ret, Params, CVQuals, RefQual, ExceptionSpec);
689   }
690 
hasRHSComponentSlow(OutputStream &)691   bool hasRHSComponentSlow(OutputStream &) const override { return true; }
hasFunctionSlow(OutputStream &)692   bool hasFunctionSlow(OutputStream &) const override { return true; }
693 
694   // Handle C++'s ... quirky decl grammar by using the left & right
695   // distinction. Consider:
696   //   int (*f(float))(char) {}
697   // f is a function that takes a float and returns a pointer to a function
698   // that takes a char and returns an int. If we're trying to print f, start
699   // by printing out the return types's left, then print our parameters, then
700   // finally print right of the return type.
printLeft(OutputStream & S)701   void printLeft(OutputStream &S) const override {
702     Ret->printLeft(S);
703     S += " ";
704   }
705 
printRight(OutputStream & S)706   void printRight(OutputStream &S) const override {
707     S += "(";
708     Params.printWithComma(S);
709     S += ")";
710     Ret->printRight(S);
711 
712     if (CVQuals & QualConst)
713       S += " const";
714     if (CVQuals & QualVolatile)
715       S += " volatile";
716     if (CVQuals & QualRestrict)
717       S += " restrict";
718 
719     if (RefQual == FrefQualLValue)
720       S += " &";
721     else if (RefQual == FrefQualRValue)
722       S += " &&";
723 
724     if (ExceptionSpec != nullptr) {
725       S += ' ';
726       ExceptionSpec->print(S);
727     }
728   }
729 };
730 
731 class NoexceptSpec : public Node {
732   const Node *E;
733 public:
NoexceptSpec(const Node * E_)734   NoexceptSpec(const Node *E_) : Node(KNoexceptSpec), E(E_) {}
735 
match(Fn F)736   template<typename Fn> void match(Fn F) const { F(E); }
737 
printLeft(OutputStream & S)738   void printLeft(OutputStream &S) const override {
739     S += "noexcept(";
740     E->print(S);
741     S += ")";
742   }
743 };
744 
745 class DynamicExceptionSpec : public Node {
746   NodeArray Types;
747 public:
DynamicExceptionSpec(NodeArray Types_)748   DynamicExceptionSpec(NodeArray Types_)
749       : Node(KDynamicExceptionSpec), Types(Types_) {}
750 
match(Fn F)751   template<typename Fn> void match(Fn F) const { F(Types); }
752 
printLeft(OutputStream & S)753   void printLeft(OutputStream &S) const override {
754     S += "throw(";
755     Types.printWithComma(S);
756     S += ')';
757   }
758 };
759 
760 class FunctionEncoding final : public Node {
761   const Node *Ret;
762   const Node *Name;
763   NodeArray Params;
764   const Node *Attrs;
765   Qualifiers CVQuals;
766   FunctionRefQual RefQual;
767 
768 public:
FunctionEncoding(const Node * Ret_,const Node * Name_,NodeArray Params_,const Node * Attrs_,Qualifiers CVQuals_,FunctionRefQual RefQual_)769   FunctionEncoding(const Node *Ret_, const Node *Name_, NodeArray Params_,
770                    const Node *Attrs_, Qualifiers CVQuals_,
771                    FunctionRefQual RefQual_)
772       : Node(KFunctionEncoding,
773              /*RHSComponentCache=*/Cache::Yes, /*ArrayCache=*/Cache::No,
774              /*FunctionCache=*/Cache::Yes),
775         Ret(Ret_), Name(Name_), Params(Params_), Attrs(Attrs_),
776         CVQuals(CVQuals_), RefQual(RefQual_) {}
777 
match(Fn F)778   template<typename Fn> void match(Fn F) const {
779     F(Ret, Name, Params, Attrs, CVQuals, RefQual);
780   }
781 
getCVQuals()782   Qualifiers getCVQuals() const { return CVQuals; }
getRefQual()783   FunctionRefQual getRefQual() const { return RefQual; }
getParams()784   NodeArray getParams() const { return Params; }
getReturnType()785   const Node *getReturnType() const { return Ret; }
786 
hasRHSComponentSlow(OutputStream &)787   bool hasRHSComponentSlow(OutputStream &) const override { return true; }
hasFunctionSlow(OutputStream &)788   bool hasFunctionSlow(OutputStream &) const override { return true; }
789 
getName()790   const Node *getName() const { return Name; }
791 
printLeft(OutputStream & S)792   void printLeft(OutputStream &S) const override {
793     if (Ret) {
794       Ret->printLeft(S);
795       if (!Ret->hasRHSComponent(S))
796         S += " ";
797     }
798     Name->print(S);
799   }
800 
printRight(OutputStream & S)801   void printRight(OutputStream &S) const override {
802     S += "(";
803     Params.printWithComma(S);
804     S += ")";
805     if (Ret)
806       Ret->printRight(S);
807 
808     if (CVQuals & QualConst)
809       S += " const";
810     if (CVQuals & QualVolatile)
811       S += " volatile";
812     if (CVQuals & QualRestrict)
813       S += " restrict";
814 
815     if (RefQual == FrefQualLValue)
816       S += " &";
817     else if (RefQual == FrefQualRValue)
818       S += " &&";
819 
820     if (Attrs != nullptr)
821       Attrs->print(S);
822   }
823 };
824 
825 class LiteralOperator : public Node {
826   const Node *OpName;
827 
828 public:
LiteralOperator(const Node * OpName_)829   LiteralOperator(const Node *OpName_)
830       : Node(KLiteralOperator), OpName(OpName_) {}
831 
match(Fn F)832   template<typename Fn> void match(Fn F) const { F(OpName); }
833 
printLeft(OutputStream & S)834   void printLeft(OutputStream &S) const override {
835     S += "operator\"\" ";
836     OpName->print(S);
837   }
838 };
839 
840 class SpecialName final : public Node {
841   const StringView Special;
842   const Node *Child;
843 
844 public:
SpecialName(StringView Special_,const Node * Child_)845   SpecialName(StringView Special_, const Node *Child_)
846       : Node(KSpecialName), Special(Special_), Child(Child_) {}
847 
match(Fn F)848   template<typename Fn> void match(Fn F) const { F(Special, Child); }
849 
printLeft(OutputStream & S)850   void printLeft(OutputStream &S) const override {
851     S += Special;
852     Child->print(S);
853   }
854 };
855 
856 class CtorVtableSpecialName final : public Node {
857   const Node *FirstType;
858   const Node *SecondType;
859 
860 public:
CtorVtableSpecialName(const Node * FirstType_,const Node * SecondType_)861   CtorVtableSpecialName(const Node *FirstType_, const Node *SecondType_)
862       : Node(KCtorVtableSpecialName),
863         FirstType(FirstType_), SecondType(SecondType_) {}
864 
match(Fn F)865   template<typename Fn> void match(Fn F) const { F(FirstType, SecondType); }
866 
printLeft(OutputStream & S)867   void printLeft(OutputStream &S) const override {
868     S += "construction vtable for ";
869     FirstType->print(S);
870     S += "-in-";
871     SecondType->print(S);
872   }
873 };
874 
875 struct NestedName : Node {
876   Node *Qual;
877   Node *Name;
878 
NestedNameNestedName879   NestedName(Node *Qual_, Node *Name_)
880       : Node(KNestedName), Qual(Qual_), Name(Name_) {}
881 
matchNestedName882   template<typename Fn> void match(Fn F) const { F(Qual, Name); }
883 
getBaseNameNestedName884   StringView getBaseName() const override { return Name->getBaseName(); }
885 
printLeftNestedName886   void printLeft(OutputStream &S) const override {
887     Qual->print(S);
888     S += "::";
889     Name->print(S);
890   }
891 };
892 
893 struct LocalName : Node {
894   Node *Encoding;
895   Node *Entity;
896 
LocalNameLocalName897   LocalName(Node *Encoding_, Node *Entity_)
898       : Node(KLocalName), Encoding(Encoding_), Entity(Entity_) {}
899 
matchLocalName900   template<typename Fn> void match(Fn F) const { F(Encoding, Entity); }
901 
printLeftLocalName902   void printLeft(OutputStream &S) const override {
903     Encoding->print(S);
904     S += "::";
905     Entity->print(S);
906   }
907 };
908 
909 class QualifiedName final : public Node {
910   // qualifier::name
911   const Node *Qualifier;
912   const Node *Name;
913 
914 public:
QualifiedName(const Node * Qualifier_,const Node * Name_)915   QualifiedName(const Node *Qualifier_, const Node *Name_)
916       : Node(KQualifiedName), Qualifier(Qualifier_), Name(Name_) {}
917 
match(Fn F)918   template<typename Fn> void match(Fn F) const { F(Qualifier, Name); }
919 
getBaseName()920   StringView getBaseName() const override { return Name->getBaseName(); }
921 
printLeft(OutputStream & S)922   void printLeft(OutputStream &S) const override {
923     Qualifier->print(S);
924     S += "::";
925     Name->print(S);
926   }
927 };
928 
929 class VectorType final : public Node {
930   const Node *BaseType;
931   const NodeOrString Dimension;
932 
933 public:
VectorType(const Node * BaseType_,NodeOrString Dimension_)934   VectorType(const Node *BaseType_, NodeOrString Dimension_)
935       : Node(KVectorType), BaseType(BaseType_),
936         Dimension(Dimension_) {}
937 
match(Fn F)938   template<typename Fn> void match(Fn F) const { F(BaseType, Dimension); }
939 
printLeft(OutputStream & S)940   void printLeft(OutputStream &S) const override {
941     BaseType->print(S);
942     S += " vector[";
943     if (Dimension.isNode())
944       Dimension.asNode()->print(S);
945     else if (Dimension.isString())
946       S += Dimension.asString();
947     S += "]";
948   }
949 };
950 
951 class PixelVectorType final : public Node {
952   const NodeOrString Dimension;
953 
954 public:
PixelVectorType(NodeOrString Dimension_)955   PixelVectorType(NodeOrString Dimension_)
956       : Node(KPixelVectorType), Dimension(Dimension_) {}
957 
match(Fn F)958   template<typename Fn> void match(Fn F) const { F(Dimension); }
959 
printLeft(OutputStream & S)960   void printLeft(OutputStream &S) const override {
961     // FIXME: This should demangle as "vector pixel".
962     S += "pixel vector[";
963     S += Dimension.asString();
964     S += "]";
965   }
966 };
967 
968 /// An unexpanded parameter pack (either in the expression or type context). If
969 /// this AST is correct, this node will have a ParameterPackExpansion node above
970 /// it.
971 ///
972 /// This node is created when some <template-args> are found that apply to an
973 /// <encoding>, and is stored in the TemplateParams table. In order for this to
974 /// appear in the final AST, it has to referenced via a <template-param> (ie,
975 /// T_).
976 class ParameterPack final : public Node {
977   NodeArray Data;
978 
979   // Setup OutputStream for a pack expansion unless we're already expanding one.
initializePackExpansion(OutputStream & S)980   void initializePackExpansion(OutputStream &S) const {
981     if (S.CurrentPackMax == std::numeric_limits<unsigned>::max()) {
982       S.CurrentPackMax = static_cast<unsigned>(Data.size());
983       S.CurrentPackIndex = 0;
984     }
985   }
986 
987 public:
ParameterPack(NodeArray Data_)988   ParameterPack(NodeArray Data_) : Node(KParameterPack), Data(Data_) {
989     ArrayCache = FunctionCache = RHSComponentCache = Cache::Unknown;
990     if (std::all_of(Data.begin(), Data.end(), [](Node* P) {
991           return P->ArrayCache == Cache::No;
992         }))
993       ArrayCache = Cache::No;
994     if (std::all_of(Data.begin(), Data.end(), [](Node* P) {
995           return P->FunctionCache == Cache::No;
996         }))
997       FunctionCache = Cache::No;
998     if (std::all_of(Data.begin(), Data.end(), [](Node* P) {
999           return P->RHSComponentCache == Cache::No;
1000         }))
1001       RHSComponentCache = Cache::No;
1002   }
1003 
match(Fn F)1004   template<typename Fn> void match(Fn F) const { F(Data); }
1005 
hasRHSComponentSlow(OutputStream & S)1006   bool hasRHSComponentSlow(OutputStream &S) const override {
1007     initializePackExpansion(S);
1008     size_t Idx = S.CurrentPackIndex;
1009     return Idx < Data.size() && Data[Idx]->hasRHSComponent(S);
1010   }
hasArraySlow(OutputStream & S)1011   bool hasArraySlow(OutputStream &S) const override {
1012     initializePackExpansion(S);
1013     size_t Idx = S.CurrentPackIndex;
1014     return Idx < Data.size() && Data[Idx]->hasArray(S);
1015   }
hasFunctionSlow(OutputStream & S)1016   bool hasFunctionSlow(OutputStream &S) const override {
1017     initializePackExpansion(S);
1018     size_t Idx = S.CurrentPackIndex;
1019     return Idx < Data.size() && Data[Idx]->hasFunction(S);
1020   }
getSyntaxNode(OutputStream & S)1021   const Node *getSyntaxNode(OutputStream &S) const override {
1022     initializePackExpansion(S);
1023     size_t Idx = S.CurrentPackIndex;
1024     return Idx < Data.size() ? Data[Idx]->getSyntaxNode(S) : this;
1025   }
1026 
printLeft(OutputStream & S)1027   void printLeft(OutputStream &S) const override {
1028     initializePackExpansion(S);
1029     size_t Idx = S.CurrentPackIndex;
1030     if (Idx < Data.size())
1031       Data[Idx]->printLeft(S);
1032   }
printRight(OutputStream & S)1033   void printRight(OutputStream &S) const override {
1034     initializePackExpansion(S);
1035     size_t Idx = S.CurrentPackIndex;
1036     if (Idx < Data.size())
1037       Data[Idx]->printRight(S);
1038   }
1039 };
1040 
1041 /// A variadic template argument. This node represents an occurrence of
1042 /// J<something>E in some <template-args>. It isn't itself unexpanded, unless
1043 /// one of it's Elements is. The parser inserts a ParameterPack into the
1044 /// TemplateParams table if the <template-args> this pack belongs to apply to an
1045 /// <encoding>.
1046 class TemplateArgumentPack final : public Node {
1047   NodeArray Elements;
1048 public:
TemplateArgumentPack(NodeArray Elements_)1049   TemplateArgumentPack(NodeArray Elements_)
1050       : Node(KTemplateArgumentPack), Elements(Elements_) {}
1051 
match(Fn F)1052   template<typename Fn> void match(Fn F) const { F(Elements); }
1053 
getElements()1054   NodeArray getElements() const { return Elements; }
1055 
printLeft(OutputStream & S)1056   void printLeft(OutputStream &S) const override {
1057     Elements.printWithComma(S);
1058   }
1059 };
1060 
1061 /// A pack expansion. Below this node, there are some unexpanded ParameterPacks
1062 /// which each have Child->ParameterPackSize elements.
1063 class ParameterPackExpansion final : public Node {
1064   const Node *Child;
1065 
1066 public:
ParameterPackExpansion(const Node * Child_)1067   ParameterPackExpansion(const Node *Child_)
1068       : Node(KParameterPackExpansion), Child(Child_) {}
1069 
match(Fn F)1070   template<typename Fn> void match(Fn F) const { F(Child); }
1071 
getChild()1072   const Node *getChild() const { return Child; }
1073 
printLeft(OutputStream & S)1074   void printLeft(OutputStream &S) const override {
1075     constexpr unsigned Max = std::numeric_limits<unsigned>::max();
1076     SwapAndRestore<unsigned> SavePackIdx(S.CurrentPackIndex, Max);
1077     SwapAndRestore<unsigned> SavePackMax(S.CurrentPackMax, Max);
1078     size_t StreamPos = S.getCurrentPosition();
1079 
1080     // Print the first element in the pack. If Child contains a ParameterPack,
1081     // it will set up S.CurrentPackMax and print the first element.
1082     Child->print(S);
1083 
1084     // No ParameterPack was found in Child. This can occur if we've found a pack
1085     // expansion on a <function-param>.
1086     if (S.CurrentPackMax == Max) {
1087       S += "...";
1088       return;
1089     }
1090 
1091     // We found a ParameterPack, but it has no elements. Erase whatever we may
1092     // of printed.
1093     if (S.CurrentPackMax == 0) {
1094       S.setCurrentPosition(StreamPos);
1095       return;
1096     }
1097 
1098     // Else, iterate through the rest of the elements in the pack.
1099     for (unsigned I = 1, E = S.CurrentPackMax; I < E; ++I) {
1100       S += ", ";
1101       S.CurrentPackIndex = I;
1102       Child->print(S);
1103     }
1104   }
1105 };
1106 
1107 class TemplateArgs final : public Node {
1108   NodeArray Params;
1109 
1110 public:
TemplateArgs(NodeArray Params_)1111   TemplateArgs(NodeArray Params_) : Node(KTemplateArgs), Params(Params_) {}
1112 
match(Fn F)1113   template<typename Fn> void match(Fn F) const { F(Params); }
1114 
getParams()1115   NodeArray getParams() { return Params; }
1116 
printLeft(OutputStream & S)1117   void printLeft(OutputStream &S) const override {
1118     S += "<";
1119     Params.printWithComma(S);
1120     if (S.back() == '>')
1121       S += " ";
1122     S += ">";
1123   }
1124 };
1125 
1126 /// A forward-reference to a template argument that was not known at the point
1127 /// where the template parameter name was parsed in a mangling.
1128 ///
1129 /// This is created when demangling the name of a specialization of a
1130 /// conversion function template:
1131 ///
1132 /// \code
1133 /// struct A {
1134 ///   template<typename T> operator T*();
1135 /// };
1136 /// \endcode
1137 ///
1138 /// When demangling a specialization of the conversion function template, we
1139 /// encounter the name of the template (including the \c T) before we reach
1140 /// the template argument list, so we cannot substitute the parameter name
1141 /// for the corresponding argument while parsing. Instead, we create a
1142 /// \c ForwardTemplateReference node that is resolved after we parse the
1143 /// template arguments.
1144 struct ForwardTemplateReference : Node {
1145   size_t Index;
1146   Node *Ref = nullptr;
1147 
1148   // If we're currently printing this node. It is possible (though invalid) for
1149   // a forward template reference to refer to itself via a substitution. This
1150   // creates a cyclic AST, which will stack overflow printing. To fix this, bail
1151   // out if more than one print* function is active.
1152   mutable bool Printing = false;
1153 
ForwardTemplateReferenceForwardTemplateReference1154   ForwardTemplateReference(size_t Index_)
1155       : Node(KForwardTemplateReference, Cache::Unknown, Cache::Unknown,
1156              Cache::Unknown),
1157         Index(Index_) {}
1158 
1159   // We don't provide a matcher for these, because the value of the node is
1160   // not determined by its construction parameters, and it generally needs
1161   // special handling.
1162   template<typename Fn> void match(Fn F) const = delete;
1163 
hasRHSComponentSlowForwardTemplateReference1164   bool hasRHSComponentSlow(OutputStream &S) const override {
1165     if (Printing)
1166       return false;
1167     SwapAndRestore<bool> SavePrinting(Printing, true);
1168     return Ref->hasRHSComponent(S);
1169   }
hasArraySlowForwardTemplateReference1170   bool hasArraySlow(OutputStream &S) const override {
1171     if (Printing)
1172       return false;
1173     SwapAndRestore<bool> SavePrinting(Printing, true);
1174     return Ref->hasArray(S);
1175   }
hasFunctionSlowForwardTemplateReference1176   bool hasFunctionSlow(OutputStream &S) const override {
1177     if (Printing)
1178       return false;
1179     SwapAndRestore<bool> SavePrinting(Printing, true);
1180     return Ref->hasFunction(S);
1181   }
getSyntaxNodeForwardTemplateReference1182   const Node *getSyntaxNode(OutputStream &S) const override {
1183     if (Printing)
1184       return this;
1185     SwapAndRestore<bool> SavePrinting(Printing, true);
1186     return Ref->getSyntaxNode(S);
1187   }
1188 
printLeftForwardTemplateReference1189   void printLeft(OutputStream &S) const override {
1190     if (Printing)
1191       return;
1192     SwapAndRestore<bool> SavePrinting(Printing, true);
1193     Ref->printLeft(S);
1194   }
printRightForwardTemplateReference1195   void printRight(OutputStream &S) const override {
1196     if (Printing)
1197       return;
1198     SwapAndRestore<bool> SavePrinting(Printing, true);
1199     Ref->printRight(S);
1200   }
1201 };
1202 
1203 struct NameWithTemplateArgs : Node {
1204   // name<template_args>
1205   Node *Name;
1206   Node *TemplateArgs;
1207 
NameWithTemplateArgsNameWithTemplateArgs1208   NameWithTemplateArgs(Node *Name_, Node *TemplateArgs_)
1209       : Node(KNameWithTemplateArgs), Name(Name_), TemplateArgs(TemplateArgs_) {}
1210 
matchNameWithTemplateArgs1211   template<typename Fn> void match(Fn F) const { F(Name, TemplateArgs); }
1212 
getBaseNameNameWithTemplateArgs1213   StringView getBaseName() const override { return Name->getBaseName(); }
1214 
printLeftNameWithTemplateArgs1215   void printLeft(OutputStream &S) const override {
1216     Name->print(S);
1217     TemplateArgs->print(S);
1218   }
1219 };
1220 
1221 class GlobalQualifiedName final : public Node {
1222   Node *Child;
1223 
1224 public:
GlobalQualifiedName(Node * Child_)1225   GlobalQualifiedName(Node* Child_)
1226       : Node(KGlobalQualifiedName), Child(Child_) {}
1227 
match(Fn F)1228   template<typename Fn> void match(Fn F) const { F(Child); }
1229 
getBaseName()1230   StringView getBaseName() const override { return Child->getBaseName(); }
1231 
printLeft(OutputStream & S)1232   void printLeft(OutputStream &S) const override {
1233     S += "::";
1234     Child->print(S);
1235   }
1236 };
1237 
1238 struct StdQualifiedName : Node {
1239   Node *Child;
1240 
StdQualifiedNameStdQualifiedName1241   StdQualifiedName(Node *Child_) : Node(KStdQualifiedName), Child(Child_) {}
1242 
matchStdQualifiedName1243   template<typename Fn> void match(Fn F) const { F(Child); }
1244 
getBaseNameStdQualifiedName1245   StringView getBaseName() const override { return Child->getBaseName(); }
1246 
printLeftStdQualifiedName1247   void printLeft(OutputStream &S) const override {
1248     S += "std::";
1249     Child->print(S);
1250   }
1251 };
1252 
1253 enum class SpecialSubKind {
1254   allocator,
1255   basic_string,
1256   string,
1257   istream,
1258   ostream,
1259   iostream,
1260 };
1261 
1262 class ExpandedSpecialSubstitution final : public Node {
1263   SpecialSubKind SSK;
1264 
1265 public:
ExpandedSpecialSubstitution(SpecialSubKind SSK_)1266   ExpandedSpecialSubstitution(SpecialSubKind SSK_)
1267       : Node(KExpandedSpecialSubstitution), SSK(SSK_) {}
1268 
match(Fn F)1269   template<typename Fn> void match(Fn F) const { F(SSK); }
1270 
getBaseName()1271   StringView getBaseName() const override {
1272     switch (SSK) {
1273     case SpecialSubKind::allocator:
1274       return StringView("allocator");
1275     case SpecialSubKind::basic_string:
1276       return StringView("basic_string");
1277     case SpecialSubKind::string:
1278       return StringView("basic_string");
1279     case SpecialSubKind::istream:
1280       return StringView("basic_istream");
1281     case SpecialSubKind::ostream:
1282       return StringView("basic_ostream");
1283     case SpecialSubKind::iostream:
1284       return StringView("basic_iostream");
1285     }
1286     _LIBCPP_UNREACHABLE();
1287   }
1288 
printLeft(OutputStream & S)1289   void printLeft(OutputStream &S) const override {
1290     switch (SSK) {
1291     case SpecialSubKind::allocator:
1292       S += "std::allocator";
1293       break;
1294     case SpecialSubKind::basic_string:
1295       S += "std::basic_string";
1296       break;
1297     case SpecialSubKind::string:
1298       S += "std::basic_string<char, std::char_traits<char>, "
1299            "std::allocator<char> >";
1300       break;
1301     case SpecialSubKind::istream:
1302       S += "std::basic_istream<char, std::char_traits<char> >";
1303       break;
1304     case SpecialSubKind::ostream:
1305       S += "std::basic_ostream<char, std::char_traits<char> >";
1306       break;
1307     case SpecialSubKind::iostream:
1308       S += "std::basic_iostream<char, std::char_traits<char> >";
1309       break;
1310     }
1311   }
1312 };
1313 
1314 class SpecialSubstitution final : public Node {
1315 public:
1316   SpecialSubKind SSK;
1317 
SpecialSubstitution(SpecialSubKind SSK_)1318   SpecialSubstitution(SpecialSubKind SSK_)
1319       : Node(KSpecialSubstitution), SSK(SSK_) {}
1320 
match(Fn F)1321   template<typename Fn> void match(Fn F) const { F(SSK); }
1322 
getBaseName()1323   StringView getBaseName() const override {
1324     switch (SSK) {
1325     case SpecialSubKind::allocator:
1326       return StringView("allocator");
1327     case SpecialSubKind::basic_string:
1328       return StringView("basic_string");
1329     case SpecialSubKind::string:
1330       return StringView("string");
1331     case SpecialSubKind::istream:
1332       return StringView("istream");
1333     case SpecialSubKind::ostream:
1334       return StringView("ostream");
1335     case SpecialSubKind::iostream:
1336       return StringView("iostream");
1337     }
1338     _LIBCPP_UNREACHABLE();
1339   }
1340 
printLeft(OutputStream & S)1341   void printLeft(OutputStream &S) const override {
1342     switch (SSK) {
1343     case SpecialSubKind::allocator:
1344       S += "std::allocator";
1345       break;
1346     case SpecialSubKind::basic_string:
1347       S += "std::basic_string";
1348       break;
1349     case SpecialSubKind::string:
1350       S += "std::string";
1351       break;
1352     case SpecialSubKind::istream:
1353       S += "std::istream";
1354       break;
1355     case SpecialSubKind::ostream:
1356       S += "std::ostream";
1357       break;
1358     case SpecialSubKind::iostream:
1359       S += "std::iostream";
1360       break;
1361     }
1362   }
1363 };
1364 
1365 class CtorDtorName final : public Node {
1366   const Node *Basename;
1367   const bool IsDtor;
1368   const int Variant;
1369 
1370 public:
CtorDtorName(const Node * Basename_,bool IsDtor_,int Variant_)1371   CtorDtorName(const Node *Basename_, bool IsDtor_, int Variant_)
1372       : Node(KCtorDtorName), Basename(Basename_), IsDtor(IsDtor_),
1373         Variant(Variant_) {}
1374 
match(Fn F)1375   template<typename Fn> void match(Fn F) const { F(Basename, IsDtor, Variant); }
1376 
printLeft(OutputStream & S)1377   void printLeft(OutputStream &S) const override {
1378     if (IsDtor)
1379       S += "~";
1380     S += Basename->getBaseName();
1381   }
1382 };
1383 
1384 class DtorName : public Node {
1385   const Node *Base;
1386 
1387 public:
DtorName(const Node * Base_)1388   DtorName(const Node *Base_) : Node(KDtorName), Base(Base_) {}
1389 
match(Fn F)1390   template<typename Fn> void match(Fn F) const { F(Base); }
1391 
printLeft(OutputStream & S)1392   void printLeft(OutputStream &S) const override {
1393     S += "~";
1394     Base->printLeft(S);
1395   }
1396 };
1397 
1398 class UnnamedTypeName : public Node {
1399   const StringView Count;
1400 
1401 public:
UnnamedTypeName(StringView Count_)1402   UnnamedTypeName(StringView Count_) : Node(KUnnamedTypeName), Count(Count_) {}
1403 
match(Fn F)1404   template<typename Fn> void match(Fn F) const { F(Count); }
1405 
printLeft(OutputStream & S)1406   void printLeft(OutputStream &S) const override {
1407     S += "'unnamed";
1408     S += Count;
1409     S += "\'";
1410   }
1411 };
1412 
1413 class ClosureTypeName : public Node {
1414   NodeArray Params;
1415   StringView Count;
1416 
1417 public:
ClosureTypeName(NodeArray Params_,StringView Count_)1418   ClosureTypeName(NodeArray Params_, StringView Count_)
1419       : Node(KClosureTypeName), Params(Params_), Count(Count_) {}
1420 
match(Fn F)1421   template<typename Fn> void match(Fn F) const { F(Params, Count); }
1422 
printLeft(OutputStream & S)1423   void printLeft(OutputStream &S) const override {
1424     S += "\'lambda";
1425     S += Count;
1426     S += "\'(";
1427     Params.printWithComma(S);
1428     S += ")";
1429   }
1430 };
1431 
1432 class StructuredBindingName : public Node {
1433   NodeArray Bindings;
1434 public:
StructuredBindingName(NodeArray Bindings_)1435   StructuredBindingName(NodeArray Bindings_)
1436       : Node(KStructuredBindingName), Bindings(Bindings_) {}
1437 
match(Fn F)1438   template<typename Fn> void match(Fn F) const { F(Bindings); }
1439 
printLeft(OutputStream & S)1440   void printLeft(OutputStream &S) const override {
1441     S += '[';
1442     Bindings.printWithComma(S);
1443     S += ']';
1444   }
1445 };
1446 
1447 // -- Expression Nodes --
1448 
1449 class BinaryExpr : public Node {
1450   const Node *LHS;
1451   const StringView InfixOperator;
1452   const Node *RHS;
1453 
1454 public:
BinaryExpr(const Node * LHS_,StringView InfixOperator_,const Node * RHS_)1455   BinaryExpr(const Node *LHS_, StringView InfixOperator_, const Node *RHS_)
1456       : Node(KBinaryExpr), LHS(LHS_), InfixOperator(InfixOperator_), RHS(RHS_) {
1457   }
1458 
match(Fn F)1459   template<typename Fn> void match(Fn F) const { F(LHS, InfixOperator, RHS); }
1460 
printLeft(OutputStream & S)1461   void printLeft(OutputStream &S) const override {
1462     // might be a template argument expression, then we need to disambiguate
1463     // with parens.
1464     if (InfixOperator == ">")
1465       S += "(";
1466 
1467     S += "(";
1468     LHS->print(S);
1469     S += ") ";
1470     S += InfixOperator;
1471     S += " (";
1472     RHS->print(S);
1473     S += ")";
1474 
1475     if (InfixOperator == ">")
1476       S += ")";
1477   }
1478 };
1479 
1480 class ArraySubscriptExpr : public Node {
1481   const Node *Op1;
1482   const Node *Op2;
1483 
1484 public:
ArraySubscriptExpr(const Node * Op1_,const Node * Op2_)1485   ArraySubscriptExpr(const Node *Op1_, const Node *Op2_)
1486       : Node(KArraySubscriptExpr), Op1(Op1_), Op2(Op2_) {}
1487 
match(Fn F)1488   template<typename Fn> void match(Fn F) const { F(Op1, Op2); }
1489 
printLeft(OutputStream & S)1490   void printLeft(OutputStream &S) const override {
1491     S += "(";
1492     Op1->print(S);
1493     S += ")[";
1494     Op2->print(S);
1495     S += "]";
1496   }
1497 };
1498 
1499 class PostfixExpr : public Node {
1500   const Node *Child;
1501   const StringView Operator;
1502 
1503 public:
PostfixExpr(const Node * Child_,StringView Operator_)1504   PostfixExpr(const Node *Child_, StringView Operator_)
1505       : Node(KPostfixExpr), Child(Child_), Operator(Operator_) {}
1506 
match(Fn F)1507   template<typename Fn> void match(Fn F) const { F(Child, Operator); }
1508 
printLeft(OutputStream & S)1509   void printLeft(OutputStream &S) const override {
1510     S += "(";
1511     Child->print(S);
1512     S += ")";
1513     S += Operator;
1514   }
1515 };
1516 
1517 class ConditionalExpr : public Node {
1518   const Node *Cond;
1519   const Node *Then;
1520   const Node *Else;
1521 
1522 public:
ConditionalExpr(const Node * Cond_,const Node * Then_,const Node * Else_)1523   ConditionalExpr(const Node *Cond_, const Node *Then_, const Node *Else_)
1524       : Node(KConditionalExpr), Cond(Cond_), Then(Then_), Else(Else_) {}
1525 
match(Fn F)1526   template<typename Fn> void match(Fn F) const { F(Cond, Then, Else); }
1527 
printLeft(OutputStream & S)1528   void printLeft(OutputStream &S) const override {
1529     S += "(";
1530     Cond->print(S);
1531     S += ") ? (";
1532     Then->print(S);
1533     S += ") : (";
1534     Else->print(S);
1535     S += ")";
1536   }
1537 };
1538 
1539 class MemberExpr : public Node {
1540   const Node *LHS;
1541   const StringView Kind;
1542   const Node *RHS;
1543 
1544 public:
MemberExpr(const Node * LHS_,StringView Kind_,const Node * RHS_)1545   MemberExpr(const Node *LHS_, StringView Kind_, const Node *RHS_)
1546       : Node(KMemberExpr), LHS(LHS_), Kind(Kind_), RHS(RHS_) {}
1547 
match(Fn F)1548   template<typename Fn> void match(Fn F) const { F(LHS, Kind, RHS); }
1549 
printLeft(OutputStream & S)1550   void printLeft(OutputStream &S) const override {
1551     LHS->print(S);
1552     S += Kind;
1553     RHS->print(S);
1554   }
1555 };
1556 
1557 class EnclosingExpr : public Node {
1558   const StringView Prefix;
1559   const Node *Infix;
1560   const StringView Postfix;
1561 
1562 public:
EnclosingExpr(StringView Prefix_,Node * Infix_,StringView Postfix_)1563   EnclosingExpr(StringView Prefix_, Node *Infix_, StringView Postfix_)
1564       : Node(KEnclosingExpr), Prefix(Prefix_), Infix(Infix_),
1565         Postfix(Postfix_) {}
1566 
match(Fn F)1567   template<typename Fn> void match(Fn F) const { F(Prefix, Infix, Postfix); }
1568 
printLeft(OutputStream & S)1569   void printLeft(OutputStream &S) const override {
1570     S += Prefix;
1571     Infix->print(S);
1572     S += Postfix;
1573   }
1574 };
1575 
1576 class CastExpr : public Node {
1577   // cast_kind<to>(from)
1578   const StringView CastKind;
1579   const Node *To;
1580   const Node *From;
1581 
1582 public:
CastExpr(StringView CastKind_,const Node * To_,const Node * From_)1583   CastExpr(StringView CastKind_, const Node *To_, const Node *From_)
1584       : Node(KCastExpr), CastKind(CastKind_), To(To_), From(From_) {}
1585 
match(Fn F)1586   template<typename Fn> void match(Fn F) const { F(CastKind, To, From); }
1587 
printLeft(OutputStream & S)1588   void printLeft(OutputStream &S) const override {
1589     S += CastKind;
1590     S += "<";
1591     To->printLeft(S);
1592     S += ">(";
1593     From->printLeft(S);
1594     S += ")";
1595   }
1596 };
1597 
1598 class SizeofParamPackExpr : public Node {
1599   const Node *Pack;
1600 
1601 public:
SizeofParamPackExpr(const Node * Pack_)1602   SizeofParamPackExpr(const Node *Pack_)
1603       : Node(KSizeofParamPackExpr), Pack(Pack_) {}
1604 
match(Fn F)1605   template<typename Fn> void match(Fn F) const { F(Pack); }
1606 
printLeft(OutputStream & S)1607   void printLeft(OutputStream &S) const override {
1608     S += "sizeof...(";
1609     ParameterPackExpansion PPE(Pack);
1610     PPE.printLeft(S);
1611     S += ")";
1612   }
1613 };
1614 
1615 class CallExpr : public Node {
1616   const Node *Callee;
1617   NodeArray Args;
1618 
1619 public:
CallExpr(const Node * Callee_,NodeArray Args_)1620   CallExpr(const Node *Callee_, NodeArray Args_)
1621       : Node(KCallExpr), Callee(Callee_), Args(Args_) {}
1622 
match(Fn F)1623   template<typename Fn> void match(Fn F) const { F(Callee, Args); }
1624 
printLeft(OutputStream & S)1625   void printLeft(OutputStream &S) const override {
1626     Callee->print(S);
1627     S += "(";
1628     Args.printWithComma(S);
1629     S += ")";
1630   }
1631 };
1632 
1633 class NewExpr : public Node {
1634   // new (expr_list) type(init_list)
1635   NodeArray ExprList;
1636   Node *Type;
1637   NodeArray InitList;
1638   bool IsGlobal; // ::operator new ?
1639   bool IsArray;  // new[] ?
1640 public:
NewExpr(NodeArray ExprList_,Node * Type_,NodeArray InitList_,bool IsGlobal_,bool IsArray_)1641   NewExpr(NodeArray ExprList_, Node *Type_, NodeArray InitList_, bool IsGlobal_,
1642           bool IsArray_)
1643       : Node(KNewExpr), ExprList(ExprList_), Type(Type_), InitList(InitList_),
1644         IsGlobal(IsGlobal_), IsArray(IsArray_) {}
1645 
match(Fn F)1646   template<typename Fn> void match(Fn F) const {
1647     F(ExprList, Type, InitList, IsGlobal, IsArray);
1648   }
1649 
printLeft(OutputStream & S)1650   void printLeft(OutputStream &S) const override {
1651     if (IsGlobal)
1652       S += "::operator ";
1653     S += "new";
1654     if (IsArray)
1655       S += "[]";
1656     S += ' ';
1657     if (!ExprList.empty()) {
1658       S += "(";
1659       ExprList.printWithComma(S);
1660       S += ")";
1661     }
1662     Type->print(S);
1663     if (!InitList.empty()) {
1664       S += "(";
1665       InitList.printWithComma(S);
1666       S += ")";
1667     }
1668 
1669   }
1670 };
1671 
1672 class DeleteExpr : public Node {
1673   Node *Op;
1674   bool IsGlobal;
1675   bool IsArray;
1676 
1677 public:
DeleteExpr(Node * Op_,bool IsGlobal_,bool IsArray_)1678   DeleteExpr(Node *Op_, bool IsGlobal_, bool IsArray_)
1679       : Node(KDeleteExpr), Op(Op_), IsGlobal(IsGlobal_), IsArray(IsArray_) {}
1680 
match(Fn F)1681   template<typename Fn> void match(Fn F) const { F(Op, IsGlobal, IsArray); }
1682 
printLeft(OutputStream & S)1683   void printLeft(OutputStream &S) const override {
1684     if (IsGlobal)
1685       S += "::";
1686     S += "delete";
1687     if (IsArray)
1688       S += "[] ";
1689     Op->print(S);
1690   }
1691 };
1692 
1693 class PrefixExpr : public Node {
1694   StringView Prefix;
1695   Node *Child;
1696 
1697 public:
PrefixExpr(StringView Prefix_,Node * Child_)1698   PrefixExpr(StringView Prefix_, Node *Child_)
1699       : Node(KPrefixExpr), Prefix(Prefix_), Child(Child_) {}
1700 
match(Fn F)1701   template<typename Fn> void match(Fn F) const { F(Prefix, Child); }
1702 
printLeft(OutputStream & S)1703   void printLeft(OutputStream &S) const override {
1704     S += Prefix;
1705     S += "(";
1706     Child->print(S);
1707     S += ")";
1708   }
1709 };
1710 
1711 class FunctionParam : public Node {
1712   StringView Number;
1713 
1714 public:
FunctionParam(StringView Number_)1715   FunctionParam(StringView Number_) : Node(KFunctionParam), Number(Number_) {}
1716 
match(Fn F)1717   template<typename Fn> void match(Fn F) const { F(Number); }
1718 
printLeft(OutputStream & S)1719   void printLeft(OutputStream &S) const override {
1720     S += "fp";
1721     S += Number;
1722   }
1723 };
1724 
1725 class ConversionExpr : public Node {
1726   const Node *Type;
1727   NodeArray Expressions;
1728 
1729 public:
ConversionExpr(const Node * Type_,NodeArray Expressions_)1730   ConversionExpr(const Node *Type_, NodeArray Expressions_)
1731       : Node(KConversionExpr), Type(Type_), Expressions(Expressions_) {}
1732 
match(Fn F)1733   template<typename Fn> void match(Fn F) const { F(Type, Expressions); }
1734 
printLeft(OutputStream & S)1735   void printLeft(OutputStream &S) const override {
1736     S += "(";
1737     Type->print(S);
1738     S += ")(";
1739     Expressions.printWithComma(S);
1740     S += ")";
1741   }
1742 };
1743 
1744 class InitListExpr : public Node {
1745   const Node *Ty;
1746   NodeArray Inits;
1747 public:
InitListExpr(const Node * Ty_,NodeArray Inits_)1748   InitListExpr(const Node *Ty_, NodeArray Inits_)
1749       : Node(KInitListExpr), Ty(Ty_), Inits(Inits_) {}
1750 
match(Fn F)1751   template<typename Fn> void match(Fn F) const { F(Ty, Inits); }
1752 
printLeft(OutputStream & S)1753   void printLeft(OutputStream &S) const override {
1754     if (Ty)
1755       Ty->print(S);
1756     S += '{';
1757     Inits.printWithComma(S);
1758     S += '}';
1759   }
1760 };
1761 
1762 class BracedExpr : public Node {
1763   const Node *Elem;
1764   const Node *Init;
1765   bool IsArray;
1766 public:
BracedExpr(const Node * Elem_,const Node * Init_,bool IsArray_)1767   BracedExpr(const Node *Elem_, const Node *Init_, bool IsArray_)
1768       : Node(KBracedExpr), Elem(Elem_), Init(Init_), IsArray(IsArray_) {}
1769 
match(Fn F)1770   template<typename Fn> void match(Fn F) const { F(Elem, Init, IsArray); }
1771 
printLeft(OutputStream & S)1772   void printLeft(OutputStream &S) const override {
1773     if (IsArray) {
1774       S += '[';
1775       Elem->print(S);
1776       S += ']';
1777     } else {
1778       S += '.';
1779       Elem->print(S);
1780     }
1781     if (Init->getKind() != KBracedExpr && Init->getKind() != KBracedRangeExpr)
1782       S += " = ";
1783     Init->print(S);
1784   }
1785 };
1786 
1787 class BracedRangeExpr : public Node {
1788   const Node *First;
1789   const Node *Last;
1790   const Node *Init;
1791 public:
BracedRangeExpr(const Node * First_,const Node * Last_,const Node * Init_)1792   BracedRangeExpr(const Node *First_, const Node *Last_, const Node *Init_)
1793       : Node(KBracedRangeExpr), First(First_), Last(Last_), Init(Init_) {}
1794 
match(Fn F)1795   template<typename Fn> void match(Fn F) const { F(First, Last, Init); }
1796 
printLeft(OutputStream & S)1797   void printLeft(OutputStream &S) const override {
1798     S += '[';
1799     First->print(S);
1800     S += " ... ";
1801     Last->print(S);
1802     S += ']';
1803     if (Init->getKind() != KBracedExpr && Init->getKind() != KBracedRangeExpr)
1804       S += " = ";
1805     Init->print(S);
1806   }
1807 };
1808 
1809 class FoldExpr : public Node {
1810   const Node *Pack, *Init;
1811   StringView OperatorName;
1812   bool IsLeftFold;
1813 
1814 public:
FoldExpr(bool IsLeftFold_,StringView OperatorName_,const Node * Pack_,const Node * Init_)1815   FoldExpr(bool IsLeftFold_, StringView OperatorName_, const Node *Pack_,
1816            const Node *Init_)
1817       : Node(KFoldExpr), Pack(Pack_), Init(Init_), OperatorName(OperatorName_),
1818         IsLeftFold(IsLeftFold_) {}
1819 
match(Fn F)1820   template<typename Fn> void match(Fn F) const {
1821     F(IsLeftFold, OperatorName, Pack, Init);
1822   }
1823 
printLeft(OutputStream & S)1824   void printLeft(OutputStream &S) const override {
1825     auto PrintPack = [&] {
1826       S += '(';
1827       ParameterPackExpansion(Pack).print(S);
1828       S += ')';
1829     };
1830 
1831     S += '(';
1832 
1833     if (IsLeftFold) {
1834       // init op ... op pack
1835       if (Init != nullptr) {
1836         Init->print(S);
1837         S += ' ';
1838         S += OperatorName;
1839         S += ' ';
1840       }
1841       // ... op pack
1842       S += "... ";
1843       S += OperatorName;
1844       S += ' ';
1845       PrintPack();
1846     } else { // !IsLeftFold
1847       // pack op ...
1848       PrintPack();
1849       S += ' ';
1850       S += OperatorName;
1851       S += " ...";
1852       // pack op ... op init
1853       if (Init != nullptr) {
1854         S += ' ';
1855         S += OperatorName;
1856         S += ' ';
1857         Init->print(S);
1858       }
1859     }
1860     S += ')';
1861   }
1862 };
1863 
1864 class ThrowExpr : public Node {
1865   const Node *Op;
1866 
1867 public:
ThrowExpr(const Node * Op_)1868   ThrowExpr(const Node *Op_) : Node(KThrowExpr), Op(Op_) {}
1869 
match(Fn F)1870   template<typename Fn> void match(Fn F) const { F(Op); }
1871 
printLeft(OutputStream & S)1872   void printLeft(OutputStream &S) const override {
1873     S += "throw ";
1874     Op->print(S);
1875   }
1876 };
1877 
1878 class BoolExpr : public Node {
1879   bool Value;
1880 
1881 public:
BoolExpr(bool Value_)1882   BoolExpr(bool Value_) : Node(KBoolExpr), Value(Value_) {}
1883 
match(Fn F)1884   template<typename Fn> void match(Fn F) const { F(Value); }
1885 
printLeft(OutputStream & S)1886   void printLeft(OutputStream &S) const override {
1887     S += Value ? StringView("true") : StringView("false");
1888   }
1889 };
1890 
1891 class IntegerCastExpr : public Node {
1892   // ty(integer)
1893   const Node *Ty;
1894   StringView Integer;
1895 
1896 public:
IntegerCastExpr(const Node * Ty_,StringView Integer_)1897   IntegerCastExpr(const Node *Ty_, StringView Integer_)
1898       : Node(KIntegerCastExpr), Ty(Ty_), Integer(Integer_) {}
1899 
match(Fn F)1900   template<typename Fn> void match(Fn F) const { F(Ty, Integer); }
1901 
printLeft(OutputStream & S)1902   void printLeft(OutputStream &S) const override {
1903     S += "(";
1904     Ty->print(S);
1905     S += ")";
1906     S += Integer;
1907   }
1908 };
1909 
1910 class IntegerLiteral : public Node {
1911   StringView Type;
1912   StringView Value;
1913 
1914 public:
IntegerLiteral(StringView Type_,StringView Value_)1915   IntegerLiteral(StringView Type_, StringView Value_)
1916       : Node(KIntegerLiteral), Type(Type_), Value(Value_) {}
1917 
match(Fn F)1918   template<typename Fn> void match(Fn F) const { F(Type, Value); }
1919 
printLeft(OutputStream & S)1920   void printLeft(OutputStream &S) const override {
1921     if (Type.size() > 3) {
1922       S += "(";
1923       S += Type;
1924       S += ")";
1925     }
1926 
1927     if (Value[0] == 'n') {
1928       S += "-";
1929       S += Value.dropFront(1);
1930     } else
1931       S += Value;
1932 
1933     if (Type.size() <= 3)
1934       S += Type;
1935   }
1936 };
1937 
1938 template <class Float> struct FloatData;
1939 
1940 namespace float_literal_impl {
getFloatLiteralKind(float *)1941 constexpr Node::Kind getFloatLiteralKind(float *) {
1942   return Node::KFloatLiteral;
1943 }
getFloatLiteralKind(double *)1944 constexpr Node::Kind getFloatLiteralKind(double *) {
1945   return Node::KDoubleLiteral;
1946 }
getFloatLiteralKind(long double *)1947 constexpr Node::Kind getFloatLiteralKind(long double *) {
1948   return Node::KLongDoubleLiteral;
1949 }
1950 }
1951 
1952 template <class Float> class FloatLiteralImpl : public Node {
1953   const StringView Contents;
1954 
1955   static constexpr Kind KindForClass =
1956       float_literal_impl::getFloatLiteralKind((Float *)nullptr);
1957 
1958 public:
FloatLiteralImpl(StringView Contents_)1959   FloatLiteralImpl(StringView Contents_)
1960       : Node(KindForClass), Contents(Contents_) {}
1961 
match(Fn F)1962   template<typename Fn> void match(Fn F) const { F(Contents); }
1963 
printLeft(OutputStream & s)1964   void printLeft(OutputStream &s) const override {
1965     const char *first = Contents.begin();
1966     const char *last = Contents.end() + 1;
1967 
1968     const size_t N = FloatData<Float>::mangled_size;
1969     if (static_cast<std::size_t>(last - first) > N) {
1970       last = first + N;
1971       union {
1972         Float value;
1973         char buf[sizeof(Float)];
1974       };
1975       const char *t = first;
1976       char *e = buf;
1977       for (; t != last; ++t, ++e) {
1978         unsigned d1 = isdigit(*t) ? static_cast<unsigned>(*t - '0')
1979                                   : static_cast<unsigned>(*t - 'a' + 10);
1980         ++t;
1981         unsigned d0 = isdigit(*t) ? static_cast<unsigned>(*t - '0')
1982                                   : static_cast<unsigned>(*t - 'a' + 10);
1983         *e = static_cast<char>((d1 << 4) + d0);
1984       }
1985 #if __BYTE_ORDER__ == __ORDER_LITTLE_ENDIAN__
1986       std::reverse(buf, e);
1987 #endif
1988       char num[FloatData<Float>::max_demangled_size] = {0};
1989       int n = snprintf(num, sizeof(num), FloatData<Float>::spec, value);
1990       s += StringView(num, num + n);
1991     }
1992   }
1993 };
1994 
1995 using FloatLiteral = FloatLiteralImpl<float>;
1996 using DoubleLiteral = FloatLiteralImpl<double>;
1997 using LongDoubleLiteral = FloatLiteralImpl<long double>;
1998 
1999 /// Visit the node. Calls \c F(P), where \c P is the node cast to the
2000 /// appropriate derived class.
2001 template<typename Fn>
visit(Fn F)2002 void Node::visit(Fn F) const {
2003   switch (K) {
2004 #define CASE(X) case K ## X: return F(static_cast<const X*>(this));
2005     FOR_EACH_NODE_KIND(CASE)
2006 #undef CASE
2007   }
2008   assert(0 && "unknown mangling node kind");
2009 }
2010 
2011 /// Determine the kind of a node from its type.
2012 template<typename NodeT> struct NodeKind;
2013 #define SPECIALIZATION(X) \
2014   template<> struct NodeKind<X> { \
2015     static constexpr Node::Kind Kind = Node::K##X; \
2016     static constexpr const char *name() { return #X; } \
2017   };
FOR_EACH_NODE_KIND(SPECIALIZATION)2018 FOR_EACH_NODE_KIND(SPECIALIZATION)
2019 #undef SPECIALIZATION
2020 
2021 #undef FOR_EACH_NODE_KIND
2022 
2023 template <class T, size_t N>
2024 class PODSmallVector {
2025   static_assert(std::is_pod<T>::value,
2026                 "T is required to be a plain old data type");
2027 
2028   T* First;
2029   T* Last;
2030   T* Cap;
2031   T Inline[N];
2032 
2033   bool isInline() const { return First == Inline; }
2034 
2035   void clearInline() {
2036     First = Inline;
2037     Last = Inline;
2038     Cap = Inline + N;
2039   }
2040 
2041   void reserve(size_t NewCap) {
2042     size_t S = size();
2043     if (isInline()) {
2044       auto* Tmp = static_cast<T*>(std::malloc(NewCap * sizeof(T)));
2045       if (Tmp == nullptr)
2046         std::terminate();
2047       std::copy(First, Last, Tmp);
2048       First = Tmp;
2049     } else {
2050       First = static_cast<T*>(std::realloc(First, NewCap * sizeof(T)));
2051       if (First == nullptr)
2052         std::terminate();
2053     }
2054     Last = First + S;
2055     Cap = First + NewCap;
2056   }
2057 
2058 public:
2059   PODSmallVector() : First(Inline), Last(First), Cap(Inline + N) {}
2060 
2061   PODSmallVector(const PODSmallVector&) = delete;
2062   PODSmallVector& operator=(const PODSmallVector&) = delete;
2063 
2064   PODSmallVector(PODSmallVector&& Other) : PODSmallVector() {
2065     if (Other.isInline()) {
2066       std::copy(Other.begin(), Other.end(), First);
2067       Last = First + Other.size();
2068       Other.clear();
2069       return;
2070     }
2071 
2072     First = Other.First;
2073     Last = Other.Last;
2074     Cap = Other.Cap;
2075     Other.clearInline();
2076   }
2077 
2078   PODSmallVector& operator=(PODSmallVector&& Other) {
2079     if (Other.isInline()) {
2080       if (!isInline()) {
2081         std::free(First);
2082         clearInline();
2083       }
2084       std::copy(Other.begin(), Other.end(), First);
2085       Last = First + Other.size();
2086       Other.clear();
2087       return *this;
2088     }
2089 
2090     if (isInline()) {
2091       First = Other.First;
2092       Last = Other.Last;
2093       Cap = Other.Cap;
2094       Other.clearInline();
2095       return *this;
2096     }
2097 
2098     std::swap(First, Other.First);
2099     std::swap(Last, Other.Last);
2100     std::swap(Cap, Other.Cap);
2101     Other.clear();
2102     return *this;
2103   }
2104 
2105   void push_back(const T& Elem) {
2106     if (Last == Cap)
2107       reserve(size() * 2);
2108     *Last++ = Elem;
2109   }
2110 
2111   void pop_back() {
2112     assert(Last != First && "Popping empty vector!");
2113     --Last;
2114   }
2115 
2116   void dropBack(size_t Index) {
2117     assert(Index <= size() && "dropBack() can't expand!");
2118     Last = First + Index;
2119   }
2120 
2121   T* begin() { return First; }
2122   T* end() { return Last; }
2123 
2124   bool empty() const { return First == Last; }
2125   size_t size() const { return static_cast<size_t>(Last - First); }
2126   T& back() {
2127     assert(Last != First && "Calling back() on empty vector!");
2128     return *(Last - 1);
2129   }
2130   T& operator[](size_t Index) {
2131     assert(Index < size() && "Invalid access!");
2132     return *(begin() + Index);
2133   }
2134   void clear() { Last = First; }
2135 
2136   ~PODSmallVector() {
2137     if (!isInline())
2138       std::free(First);
2139   }
2140 };
2141 
2142 template <typename Derived, typename Alloc> struct AbstractManglingParser {
2143   const char *First;
2144   const char *Last;
2145 
2146   // Name stack, this is used by the parser to hold temporary names that were
2147   // parsed. The parser collapses multiple names into new nodes to construct
2148   // the AST. Once the parser is finished, names.size() == 1.
2149   PODSmallVector<Node *, 32> Names;
2150 
2151   // Substitution table. Itanium supports name substitutions as a means of
2152   // compression. The string "S42_" refers to the 44nd entry (base-36) in this
2153   // table.
2154   PODSmallVector<Node *, 32> Subs;
2155 
2156   // Template parameter table. Like the above, but referenced like "T42_".
2157   // This has a smaller size compared to Subs and Names because it can be
2158   // stored on the stack.
2159   PODSmallVector<Node *, 8> TemplateParams;
2160 
2161   // Set of unresolved forward <template-param> references. These can occur in a
2162   // conversion operator's type, and are resolved in the enclosing <encoding>.
2163   PODSmallVector<ForwardTemplateReference *, 4> ForwardTemplateRefs;
2164 
2165   bool TryToParseTemplateArgs = true;
2166   bool PermitForwardTemplateReferences = false;
2167   bool ParsingLambdaParams = false;
2168 
2169   Alloc ASTAllocator;
2170 
AbstractManglingParserAbstractManglingParser2171   AbstractManglingParser(const char *First_, const char *Last_)
2172       : First(First_), Last(Last_) {}
2173 
getDerivedAbstractManglingParser2174   Derived &getDerived() { return static_cast<Derived &>(*this); }
2175 
resetAbstractManglingParser2176   void reset(const char *First_, const char *Last_) {
2177     First = First_;
2178     Last = Last_;
2179     Names.clear();
2180     Subs.clear();
2181     TemplateParams.clear();
2182     ParsingLambdaParams = false;
2183     TryToParseTemplateArgs = true;
2184     PermitForwardTemplateReferences = false;
2185     ASTAllocator.reset();
2186   }
2187 
makeAbstractManglingParser2188   template <class T, class... Args> Node *make(Args &&... args) {
2189     return ASTAllocator.template makeNode<T>(std::forward<Args>(args)...);
2190   }
2191 
makeNodeArrayAbstractManglingParser2192   template <class It> NodeArray makeNodeArray(It begin, It end) {
2193     size_t sz = static_cast<size_t>(end - begin);
2194     void *mem = ASTAllocator.allocateNodeArray(sz);
2195     Node **data = new (mem) Node *[sz];
2196     std::copy(begin, end, data);
2197     return NodeArray(data, sz);
2198   }
2199 
popTrailingNodeArrayAbstractManglingParser2200   NodeArray popTrailingNodeArray(size_t FromPosition) {
2201     assert(FromPosition <= Names.size());
2202     NodeArray res =
2203         makeNodeArray(Names.begin() + (long)FromPosition, Names.end());
2204     Names.dropBack(FromPosition);
2205     return res;
2206   }
2207 
consumeIfAbstractManglingParser2208   bool consumeIf(StringView S) {
2209     if (StringView(First, Last).startsWith(S)) {
2210       First += S.size();
2211       return true;
2212     }
2213     return false;
2214   }
2215 
consumeIfAbstractManglingParser2216   bool consumeIf(char C) {
2217     if (First != Last && *First == C) {
2218       ++First;
2219       return true;
2220     }
2221     return false;
2222   }
2223 
consumeAbstractManglingParser2224   char consume() { return First != Last ? *First++ : '\0'; }
2225 
2226   char look(unsigned Lookahead = 0) {
2227     if (static_cast<size_t>(Last - First) <= Lookahead)
2228       return '\0';
2229     return First[Lookahead];
2230   }
2231 
numLeftAbstractManglingParser2232   size_t numLeft() const { return static_cast<size_t>(Last - First); }
2233 
2234   StringView parseNumber(bool AllowNegative = false);
2235   Qualifiers parseCVQualifiers();
2236   bool parsePositiveInteger(size_t *Out);
2237   StringView parseBareSourceName();
2238 
2239   bool parseSeqId(size_t *Out);
2240   Node *parseSubstitution();
2241   Node *parseTemplateParam();
2242   Node *parseTemplateArgs(bool TagTemplates = false);
2243   Node *parseTemplateArg();
2244 
2245   /// Parse the <expr> production.
2246   Node *parseExpr();
2247   Node *parsePrefixExpr(StringView Kind);
2248   Node *parseBinaryExpr(StringView Kind);
2249   Node *parseIntegerLiteral(StringView Lit);
2250   Node *parseExprPrimary();
2251   template <class Float> Node *parseFloatingLiteral();
2252   Node *parseFunctionParam();
2253   Node *parseNewExpr();
2254   Node *parseConversionExpr();
2255   Node *parseBracedExpr();
2256   Node *parseFoldExpr();
2257 
2258   /// Parse the <type> production.
2259   Node *parseType();
2260   Node *parseFunctionType();
2261   Node *parseVectorType();
2262   Node *parseDecltype();
2263   Node *parseArrayType();
2264   Node *parsePointerToMemberType();
2265   Node *parseClassEnumType();
2266   Node *parseQualifiedType();
2267 
2268   Node *parseEncoding();
2269   bool parseCallOffset();
2270   Node *parseSpecialName();
2271 
2272   /// Holds some extra information about a <name> that is being parsed. This
2273   /// information is only pertinent if the <name> refers to an <encoding>.
2274   struct NameState {
2275     bool CtorDtorConversion = false;
2276     bool EndsWithTemplateArgs = false;
2277     Qualifiers CVQualifiers = QualNone;
2278     FunctionRefQual ReferenceQualifier = FrefQualNone;
2279     size_t ForwardTemplateRefsBegin;
2280 
NameStateAbstractManglingParser::NameState2281     NameState(AbstractManglingParser *Enclosing)
2282         : ForwardTemplateRefsBegin(Enclosing->ForwardTemplateRefs.size()) {}
2283   };
2284 
resolveForwardTemplateRefsAbstractManglingParser2285   bool resolveForwardTemplateRefs(NameState &State) {
2286     size_t I = State.ForwardTemplateRefsBegin;
2287     size_t E = ForwardTemplateRefs.size();
2288     for (; I < E; ++I) {
2289       size_t Idx = ForwardTemplateRefs[I]->Index;
2290       if (Idx >= TemplateParams.size())
2291         return true;
2292       ForwardTemplateRefs[I]->Ref = TemplateParams[Idx];
2293     }
2294     ForwardTemplateRefs.dropBack(State.ForwardTemplateRefsBegin);
2295     return false;
2296   }
2297 
2298   /// Parse the <name> production>
2299   Node *parseName(NameState *State = nullptr);
2300   Node *parseLocalName(NameState *State);
2301   Node *parseOperatorName(NameState *State);
2302   Node *parseUnqualifiedName(NameState *State);
2303   Node *parseUnnamedTypeName(NameState *State);
2304   Node *parseSourceName(NameState *State);
2305   Node *parseUnscopedName(NameState *State);
2306   Node *parseNestedName(NameState *State);
2307   Node *parseCtorDtorName(Node *&SoFar, NameState *State);
2308 
2309   Node *parseAbiTags(Node *N);
2310 
2311   /// Parse the <unresolved-name> production.
2312   Node *parseUnresolvedName();
2313   Node *parseSimpleId();
2314   Node *parseBaseUnresolvedName();
2315   Node *parseUnresolvedType();
2316   Node *parseDestructorName();
2317 
2318   /// Top-level entry point into the parser.
2319   Node *parse();
2320 };
2321 
2322 const char* parse_discriminator(const char* first, const char* last);
2323 
2324 // <name> ::= <nested-name> // N
2325 //        ::= <local-name> # See Scope Encoding below  // Z
2326 //        ::= <unscoped-template-name> <template-args>
2327 //        ::= <unscoped-name>
2328 //
2329 // <unscoped-template-name> ::= <unscoped-name>
2330 //                          ::= <substitution>
2331 template <typename Derived, typename Alloc>
parseName(NameState * State)2332 Node *AbstractManglingParser<Derived, Alloc>::parseName(NameState *State) {
2333   consumeIf('L'); // extension
2334 
2335   if (look() == 'N')
2336     return getDerived().parseNestedName(State);
2337   if (look() == 'Z')
2338     return getDerived().parseLocalName(State);
2339 
2340   //        ::= <unscoped-template-name> <template-args>
2341   if (look() == 'S' && look(1) != 't') {
2342     Node *S = getDerived().parseSubstitution();
2343     if (S == nullptr)
2344       return nullptr;
2345     if (look() != 'I')
2346       return nullptr;
2347     Node *TA = getDerived().parseTemplateArgs(State != nullptr);
2348     if (TA == nullptr)
2349       return nullptr;
2350     if (State) State->EndsWithTemplateArgs = true;
2351     return make<NameWithTemplateArgs>(S, TA);
2352   }
2353 
2354   Node *N = getDerived().parseUnscopedName(State);
2355   if (N == nullptr)
2356     return nullptr;
2357   //        ::= <unscoped-template-name> <template-args>
2358   if (look() == 'I') {
2359     Subs.push_back(N);
2360     Node *TA = getDerived().parseTemplateArgs(State != nullptr);
2361     if (TA == nullptr)
2362       return nullptr;
2363     if (State) State->EndsWithTemplateArgs = true;
2364     return make<NameWithTemplateArgs>(N, TA);
2365   }
2366   //        ::= <unscoped-name>
2367   return N;
2368 }
2369 
2370 // <local-name> := Z <function encoding> E <entity name> [<discriminator>]
2371 //              := Z <function encoding> E s [<discriminator>]
2372 //              := Z <function encoding> Ed [ <parameter number> ] _ <entity name>
2373 template <typename Derived, typename Alloc>
parseLocalName(NameState * State)2374 Node *AbstractManglingParser<Derived, Alloc>::parseLocalName(NameState *State) {
2375   if (!consumeIf('Z'))
2376     return nullptr;
2377   Node *Encoding = getDerived().parseEncoding();
2378   if (Encoding == nullptr || !consumeIf('E'))
2379     return nullptr;
2380 
2381   if (consumeIf('s')) {
2382     First = parse_discriminator(First, Last);
2383     auto *StringLitName = make<NameType>("string literal");
2384     if (!StringLitName)
2385       return nullptr;
2386     return make<LocalName>(Encoding, StringLitName);
2387   }
2388 
2389   if (consumeIf('d')) {
2390     parseNumber(true);
2391     if (!consumeIf('_'))
2392       return nullptr;
2393     Node *N = getDerived().parseName(State);
2394     if (N == nullptr)
2395       return nullptr;
2396     return make<LocalName>(Encoding, N);
2397   }
2398 
2399   Node *Entity = getDerived().parseName(State);
2400   if (Entity == nullptr)
2401     return nullptr;
2402   First = parse_discriminator(First, Last);
2403   return make<LocalName>(Encoding, Entity);
2404 }
2405 
2406 // <unscoped-name> ::= <unqualified-name>
2407 //                 ::= St <unqualified-name>   # ::std::
2408 // extension       ::= StL<unqualified-name>
2409 template <typename Derived, typename Alloc>
2410 Node *
parseUnscopedName(NameState * State)2411 AbstractManglingParser<Derived, Alloc>::parseUnscopedName(NameState *State) {
2412   if (consumeIf("StL") || consumeIf("St")) {
2413     Node *R = getDerived().parseUnqualifiedName(State);
2414     if (R == nullptr)
2415       return nullptr;
2416     return make<StdQualifiedName>(R);
2417   }
2418   return getDerived().parseUnqualifiedName(State);
2419 }
2420 
2421 // <unqualified-name> ::= <operator-name> [abi-tags]
2422 //                    ::= <ctor-dtor-name>
2423 //                    ::= <source-name>
2424 //                    ::= <unnamed-type-name>
2425 //                    ::= DC <source-name>+ E      # structured binding declaration
2426 template <typename Derived, typename Alloc>
2427 Node *
parseUnqualifiedName(NameState * State)2428 AbstractManglingParser<Derived, Alloc>::parseUnqualifiedName(NameState *State) {
2429   // <ctor-dtor-name>s are special-cased in parseNestedName().
2430   Node *Result;
2431   if (look() == 'U')
2432     Result = getDerived().parseUnnamedTypeName(State);
2433   else if (look() >= '1' && look() <= '9')
2434     Result = getDerived().parseSourceName(State);
2435   else if (consumeIf("DC")) {
2436     size_t BindingsBegin = Names.size();
2437     do {
2438       Node *Binding = getDerived().parseSourceName(State);
2439       if (Binding == nullptr)
2440         return nullptr;
2441       Names.push_back(Binding);
2442     } while (!consumeIf('E'));
2443     Result = make<StructuredBindingName>(popTrailingNodeArray(BindingsBegin));
2444   } else
2445     Result = getDerived().parseOperatorName(State);
2446   if (Result != nullptr)
2447     Result = getDerived().parseAbiTags(Result);
2448   return Result;
2449 }
2450 
2451 // <unnamed-type-name> ::= Ut [<nonnegative number>] _
2452 //                     ::= <closure-type-name>
2453 //
2454 // <closure-type-name> ::= Ul <lambda-sig> E [ <nonnegative number> ] _
2455 //
2456 // <lambda-sig> ::= <parameter type>+  # Parameter types or "v" if the lambda has no parameters
2457 template <typename Derived, typename Alloc>
2458 Node *
parseUnnamedTypeName(NameState *)2459 AbstractManglingParser<Derived, Alloc>::parseUnnamedTypeName(NameState *) {
2460   if (consumeIf("Ut")) {
2461     StringView Count = parseNumber();
2462     if (!consumeIf('_'))
2463       return nullptr;
2464     return make<UnnamedTypeName>(Count);
2465   }
2466   if (consumeIf("Ul")) {
2467     NodeArray Params;
2468     SwapAndRestore<bool> SwapParams(ParsingLambdaParams, true);
2469     if (!consumeIf("vE")) {
2470       size_t ParamsBegin = Names.size();
2471       do {
2472         Node *P = getDerived().parseType();
2473         if (P == nullptr)
2474           return nullptr;
2475         Names.push_back(P);
2476       } while (!consumeIf('E'));
2477       Params = popTrailingNodeArray(ParamsBegin);
2478     }
2479     StringView Count = parseNumber();
2480     if (!consumeIf('_'))
2481       return nullptr;
2482     return make<ClosureTypeName>(Params, Count);
2483   }
2484   return nullptr;
2485 }
2486 
2487 // <source-name> ::= <positive length number> <identifier>
2488 template <typename Derived, typename Alloc>
parseSourceName(NameState *)2489 Node *AbstractManglingParser<Derived, Alloc>::parseSourceName(NameState *) {
2490   size_t Length = 0;
2491   if (parsePositiveInteger(&Length))
2492     return nullptr;
2493   if (numLeft() < Length || Length == 0)
2494     return nullptr;
2495   StringView Name(First, First + Length);
2496   First += Length;
2497   if (Name.startsWith("_GLOBAL__N"))
2498     return make<NameType>("(anonymous namespace)");
2499   return make<NameType>(Name);
2500 }
2501 
2502 //   <operator-name> ::= aa    # &&
2503 //                   ::= ad    # & (unary)
2504 //                   ::= an    # &
2505 //                   ::= aN    # &=
2506 //                   ::= aS    # =
2507 //                   ::= cl    # ()
2508 //                   ::= cm    # ,
2509 //                   ::= co    # ~
2510 //                   ::= cv <type>    # (cast)
2511 //                   ::= da    # delete[]
2512 //                   ::= de    # * (unary)
2513 //                   ::= dl    # delete
2514 //                   ::= dv    # /
2515 //                   ::= dV    # /=
2516 //                   ::= eo    # ^
2517 //                   ::= eO    # ^=
2518 //                   ::= eq    # ==
2519 //                   ::= ge    # >=
2520 //                   ::= gt    # >
2521 //                   ::= ix    # []
2522 //                   ::= le    # <=
2523 //                   ::= li <source-name>  # operator ""
2524 //                   ::= ls    # <<
2525 //                   ::= lS    # <<=
2526 //                   ::= lt    # <
2527 //                   ::= mi    # -
2528 //                   ::= mI    # -=
2529 //                   ::= ml    # *
2530 //                   ::= mL    # *=
2531 //                   ::= mm    # -- (postfix in <expression> context)
2532 //                   ::= na    # new[]
2533 //                   ::= ne    # !=
2534 //                   ::= ng    # - (unary)
2535 //                   ::= nt    # !
2536 //                   ::= nw    # new
2537 //                   ::= oo    # ||
2538 //                   ::= or    # |
2539 //                   ::= oR    # |=
2540 //                   ::= pm    # ->*
2541 //                   ::= pl    # +
2542 //                   ::= pL    # +=
2543 //                   ::= pp    # ++ (postfix in <expression> context)
2544 //                   ::= ps    # + (unary)
2545 //                   ::= pt    # ->
2546 //                   ::= qu    # ?
2547 //                   ::= rm    # %
2548 //                   ::= rM    # %=
2549 //                   ::= rs    # >>
2550 //                   ::= rS    # >>=
2551 //                   ::= ss    # <=> C++2a
2552 //                   ::= v <digit> <source-name>        # vendor extended operator
2553 template <typename Derived, typename Alloc>
2554 Node *
parseOperatorName(NameState * State)2555 AbstractManglingParser<Derived, Alloc>::parseOperatorName(NameState *State) {
2556   switch (look()) {
2557   case 'a':
2558     switch (look(1)) {
2559     case 'a':
2560       First += 2;
2561       return make<NameType>("operator&&");
2562     case 'd':
2563     case 'n':
2564       First += 2;
2565       return make<NameType>("operator&");
2566     case 'N':
2567       First += 2;
2568       return make<NameType>("operator&=");
2569     case 'S':
2570       First += 2;
2571       return make<NameType>("operator=");
2572     }
2573     return nullptr;
2574   case 'c':
2575     switch (look(1)) {
2576     case 'l':
2577       First += 2;
2578       return make<NameType>("operator()");
2579     case 'm':
2580       First += 2;
2581       return make<NameType>("operator,");
2582     case 'o':
2583       First += 2;
2584       return make<NameType>("operator~");
2585     //                   ::= cv <type>    # (cast)
2586     case 'v': {
2587       First += 2;
2588       SwapAndRestore<bool> SaveTemplate(TryToParseTemplateArgs, false);
2589       // If we're parsing an encoding, State != nullptr and the conversion
2590       // operators' <type> could have a <template-param> that refers to some
2591       // <template-arg>s further ahead in the mangled name.
2592       SwapAndRestore<bool> SavePermit(PermitForwardTemplateReferences,
2593                                       PermitForwardTemplateReferences ||
2594                                           State != nullptr);
2595       Node *Ty = getDerived().parseType();
2596       if (Ty == nullptr)
2597         return nullptr;
2598       if (State) State->CtorDtorConversion = true;
2599       return make<ConversionOperatorType>(Ty);
2600     }
2601     }
2602     return nullptr;
2603   case 'd':
2604     switch (look(1)) {
2605     case 'a':
2606       First += 2;
2607       return make<NameType>("operator delete[]");
2608     case 'e':
2609       First += 2;
2610       return make<NameType>("operator*");
2611     case 'l':
2612       First += 2;
2613       return make<NameType>("operator delete");
2614     case 'v':
2615       First += 2;
2616       return make<NameType>("operator/");
2617     case 'V':
2618       First += 2;
2619       return make<NameType>("operator/=");
2620     }
2621     return nullptr;
2622   case 'e':
2623     switch (look(1)) {
2624     case 'o':
2625       First += 2;
2626       return make<NameType>("operator^");
2627     case 'O':
2628       First += 2;
2629       return make<NameType>("operator^=");
2630     case 'q':
2631       First += 2;
2632       return make<NameType>("operator==");
2633     }
2634     return nullptr;
2635   case 'g':
2636     switch (look(1)) {
2637     case 'e':
2638       First += 2;
2639       return make<NameType>("operator>=");
2640     case 't':
2641       First += 2;
2642       return make<NameType>("operator>");
2643     }
2644     return nullptr;
2645   case 'i':
2646     if (look(1) == 'x') {
2647       First += 2;
2648       return make<NameType>("operator[]");
2649     }
2650     return nullptr;
2651   case 'l':
2652     switch (look(1)) {
2653     case 'e':
2654       First += 2;
2655       return make<NameType>("operator<=");
2656     //                   ::= li <source-name>  # operator ""
2657     case 'i': {
2658       First += 2;
2659       Node *SN = getDerived().parseSourceName(State);
2660       if (SN == nullptr)
2661         return nullptr;
2662       return make<LiteralOperator>(SN);
2663     }
2664     case 's':
2665       First += 2;
2666       return make<NameType>("operator<<");
2667     case 'S':
2668       First += 2;
2669       return make<NameType>("operator<<=");
2670     case 't':
2671       First += 2;
2672       return make<NameType>("operator<");
2673     }
2674     return nullptr;
2675   case 'm':
2676     switch (look(1)) {
2677     case 'i':
2678       First += 2;
2679       return make<NameType>("operator-");
2680     case 'I':
2681       First += 2;
2682       return make<NameType>("operator-=");
2683     case 'l':
2684       First += 2;
2685       return make<NameType>("operator*");
2686     case 'L':
2687       First += 2;
2688       return make<NameType>("operator*=");
2689     case 'm':
2690       First += 2;
2691       return make<NameType>("operator--");
2692     }
2693     return nullptr;
2694   case 'n':
2695     switch (look(1)) {
2696     case 'a':
2697       First += 2;
2698       return make<NameType>("operator new[]");
2699     case 'e':
2700       First += 2;
2701       return make<NameType>("operator!=");
2702     case 'g':
2703       First += 2;
2704       return make<NameType>("operator-");
2705     case 't':
2706       First += 2;
2707       return make<NameType>("operator!");
2708     case 'w':
2709       First += 2;
2710       return make<NameType>("operator new");
2711     }
2712     return nullptr;
2713   case 'o':
2714     switch (look(1)) {
2715     case 'o':
2716       First += 2;
2717       return make<NameType>("operator||");
2718     case 'r':
2719       First += 2;
2720       return make<NameType>("operator|");
2721     case 'R':
2722       First += 2;
2723       return make<NameType>("operator|=");
2724     }
2725     return nullptr;
2726   case 'p':
2727     switch (look(1)) {
2728     case 'm':
2729       First += 2;
2730       return make<NameType>("operator->*");
2731     case 'l':
2732       First += 2;
2733       return make<NameType>("operator+");
2734     case 'L':
2735       First += 2;
2736       return make<NameType>("operator+=");
2737     case 'p':
2738       First += 2;
2739       return make<NameType>("operator++");
2740     case 's':
2741       First += 2;
2742       return make<NameType>("operator+");
2743     case 't':
2744       First += 2;
2745       return make<NameType>("operator->");
2746     }
2747     return nullptr;
2748   case 'q':
2749     if (look(1) == 'u') {
2750       First += 2;
2751       return make<NameType>("operator?");
2752     }
2753     return nullptr;
2754   case 'r':
2755     switch (look(1)) {
2756     case 'm':
2757       First += 2;
2758       return make<NameType>("operator%");
2759     case 'M':
2760       First += 2;
2761       return make<NameType>("operator%=");
2762     case 's':
2763       First += 2;
2764       return make<NameType>("operator>>");
2765     case 'S':
2766       First += 2;
2767       return make<NameType>("operator>>=");
2768     }
2769     return nullptr;
2770   case 's':
2771     if (look(1) == 's') {
2772       First += 2;
2773       return make<NameType>("operator<=>");
2774     }
2775     return nullptr;
2776   // ::= v <digit> <source-name>        # vendor extended operator
2777   case 'v':
2778     if (std::isdigit(look(1))) {
2779       First += 2;
2780       Node *SN = getDerived().parseSourceName(State);
2781       if (SN == nullptr)
2782         return nullptr;
2783       return make<ConversionOperatorType>(SN);
2784     }
2785     return nullptr;
2786   }
2787   return nullptr;
2788 }
2789 
2790 // <ctor-dtor-name> ::= C1  # complete object constructor
2791 //                  ::= C2  # base object constructor
2792 //                  ::= C3  # complete object allocating constructor
2793 //   extension      ::= C5    # ?
2794 //                  ::= D0  # deleting destructor
2795 //                  ::= D1  # complete object destructor
2796 //                  ::= D2  # base object destructor
2797 //   extension      ::= D5    # ?
2798 template <typename Derived, typename Alloc>
2799 Node *
parseCtorDtorName(Node * & SoFar,NameState * State)2800 AbstractManglingParser<Derived, Alloc>::parseCtorDtorName(Node *&SoFar,
2801                                                           NameState *State) {
2802   if (SoFar->getKind() == Node::KSpecialSubstitution) {
2803     auto SSK = static_cast<SpecialSubstitution *>(SoFar)->SSK;
2804     switch (SSK) {
2805     case SpecialSubKind::string:
2806     case SpecialSubKind::istream:
2807     case SpecialSubKind::ostream:
2808     case SpecialSubKind::iostream:
2809       SoFar = make<ExpandedSpecialSubstitution>(SSK);
2810       if (!SoFar)
2811         return nullptr;
2812       break;
2813     default:
2814       break;
2815     }
2816   }
2817 
2818   if (consumeIf('C')) {
2819     bool IsInherited = consumeIf('I');
2820     if (look() != '1' && look() != '2' && look() != '3' && look() != '5')
2821       return nullptr;
2822     int Variant = look() - '0';
2823     ++First;
2824     if (State) State->CtorDtorConversion = true;
2825     if (IsInherited) {
2826       if (getDerived().parseName(State) == nullptr)
2827         return nullptr;
2828     }
2829     return make<CtorDtorName>(SoFar, false, Variant);
2830   }
2831 
2832   if (look() == 'D' &&
2833       (look(1) == '0' || look(1) == '1' || look(1) == '2' || look(1) == '5')) {
2834     int Variant = look(1) - '0';
2835     First += 2;
2836     if (State) State->CtorDtorConversion = true;
2837     return make<CtorDtorName>(SoFar, true, Variant);
2838   }
2839 
2840   return nullptr;
2841 }
2842 
2843 // <nested-name> ::= N [<CV-Qualifiers>] [<ref-qualifier>] <prefix> <unqualified-name> E
2844 //               ::= N [<CV-Qualifiers>] [<ref-qualifier>] <template-prefix> <template-args> E
2845 //
2846 // <prefix> ::= <prefix> <unqualified-name>
2847 //          ::= <template-prefix> <template-args>
2848 //          ::= <template-param>
2849 //          ::= <decltype>
2850 //          ::= # empty
2851 //          ::= <substitution>
2852 //          ::= <prefix> <data-member-prefix>
2853 //  extension ::= L
2854 //
2855 // <data-member-prefix> := <member source-name> [<template-args>] M
2856 //
2857 // <template-prefix> ::= <prefix> <template unqualified-name>
2858 //                   ::= <template-param>
2859 //                   ::= <substitution>
2860 template <typename Derived, typename Alloc>
2861 Node *
parseNestedName(NameState * State)2862 AbstractManglingParser<Derived, Alloc>::parseNestedName(NameState *State) {
2863   if (!consumeIf('N'))
2864     return nullptr;
2865 
2866   Qualifiers CVTmp = parseCVQualifiers();
2867   if (State) State->CVQualifiers = CVTmp;
2868 
2869   if (consumeIf('O')) {
2870     if (State) State->ReferenceQualifier = FrefQualRValue;
2871   } else if (consumeIf('R')) {
2872     if (State) State->ReferenceQualifier = FrefQualLValue;
2873   } else
2874     if (State) State->ReferenceQualifier = FrefQualNone;
2875 
2876   Node *SoFar = nullptr;
2877   auto PushComponent = [&](Node *Comp) {
2878     if (!Comp) return false;
2879     if (SoFar) SoFar = make<NestedName>(SoFar, Comp);
2880     else       SoFar = Comp;
2881     if (State) State->EndsWithTemplateArgs = false;
2882     return SoFar != nullptr;
2883   };
2884 
2885   if (consumeIf("St")) {
2886     SoFar = make<NameType>("std");
2887     if (!SoFar)
2888       return nullptr;
2889   }
2890 
2891   while (!consumeIf('E')) {
2892     consumeIf('L'); // extension
2893 
2894     // <data-member-prefix> := <member source-name> [<template-args>] M
2895     if (consumeIf('M')) {
2896       if (SoFar == nullptr)
2897         return nullptr;
2898       continue;
2899     }
2900 
2901     //          ::= <template-param>
2902     if (look() == 'T') {
2903       if (!PushComponent(getDerived().parseTemplateParam()))
2904         return nullptr;
2905       Subs.push_back(SoFar);
2906       continue;
2907     }
2908 
2909     //          ::= <template-prefix> <template-args>
2910     if (look() == 'I') {
2911       Node *TA = getDerived().parseTemplateArgs(State != nullptr);
2912       if (TA == nullptr || SoFar == nullptr)
2913         return nullptr;
2914       SoFar = make<NameWithTemplateArgs>(SoFar, TA);
2915       if (!SoFar)
2916         return nullptr;
2917       if (State) State->EndsWithTemplateArgs = true;
2918       Subs.push_back(SoFar);
2919       continue;
2920     }
2921 
2922     //          ::= <decltype>
2923     if (look() == 'D' && (look(1) == 't' || look(1) == 'T')) {
2924       if (!PushComponent(getDerived().parseDecltype()))
2925         return nullptr;
2926       Subs.push_back(SoFar);
2927       continue;
2928     }
2929 
2930     //          ::= <substitution>
2931     if (look() == 'S' && look(1) != 't') {
2932       Node *S = getDerived().parseSubstitution();
2933       if (!PushComponent(S))
2934         return nullptr;
2935       if (SoFar != S)
2936         Subs.push_back(S);
2937       continue;
2938     }
2939 
2940     // Parse an <unqualified-name> thats actually a <ctor-dtor-name>.
2941     if (look() == 'C' || (look() == 'D' && look(1) != 'C')) {
2942       if (SoFar == nullptr)
2943         return nullptr;
2944       if (!PushComponent(getDerived().parseCtorDtorName(SoFar, State)))
2945         return nullptr;
2946       SoFar = getDerived().parseAbiTags(SoFar);
2947       if (SoFar == nullptr)
2948         return nullptr;
2949       Subs.push_back(SoFar);
2950       continue;
2951     }
2952 
2953     //          ::= <prefix> <unqualified-name>
2954     if (!PushComponent(getDerived().parseUnqualifiedName(State)))
2955       return nullptr;
2956     Subs.push_back(SoFar);
2957   }
2958 
2959   if (SoFar == nullptr || Subs.empty())
2960     return nullptr;
2961 
2962   Subs.pop_back();
2963   return SoFar;
2964 }
2965 
2966 // <simple-id> ::= <source-name> [ <template-args> ]
2967 template <typename Derived, typename Alloc>
parseSimpleId()2968 Node *AbstractManglingParser<Derived, Alloc>::parseSimpleId() {
2969   Node *SN = getDerived().parseSourceName(/*NameState=*/nullptr);
2970   if (SN == nullptr)
2971     return nullptr;
2972   if (look() == 'I') {
2973     Node *TA = getDerived().parseTemplateArgs();
2974     if (TA == nullptr)
2975       return nullptr;
2976     return make<NameWithTemplateArgs>(SN, TA);
2977   }
2978   return SN;
2979 }
2980 
2981 // <destructor-name> ::= <unresolved-type>  # e.g., ~T or ~decltype(f())
2982 //                   ::= <simple-id>        # e.g., ~A<2*N>
2983 template <typename Derived, typename Alloc>
parseDestructorName()2984 Node *AbstractManglingParser<Derived, Alloc>::parseDestructorName() {
2985   Node *Result;
2986   if (std::isdigit(look()))
2987     Result = getDerived().parseSimpleId();
2988   else
2989     Result = getDerived().parseUnresolvedType();
2990   if (Result == nullptr)
2991     return nullptr;
2992   return make<DtorName>(Result);
2993 }
2994 
2995 // <unresolved-type> ::= <template-param>
2996 //                   ::= <decltype>
2997 //                   ::= <substitution>
2998 template <typename Derived, typename Alloc>
parseUnresolvedType()2999 Node *AbstractManglingParser<Derived, Alloc>::parseUnresolvedType() {
3000   if (look() == 'T') {
3001     Node *TP = getDerived().parseTemplateParam();
3002     if (TP == nullptr)
3003       return nullptr;
3004     Subs.push_back(TP);
3005     return TP;
3006   }
3007   if (look() == 'D') {
3008     Node *DT = getDerived().parseDecltype();
3009     if (DT == nullptr)
3010       return nullptr;
3011     Subs.push_back(DT);
3012     return DT;
3013   }
3014   return getDerived().parseSubstitution();
3015 }
3016 
3017 // <base-unresolved-name> ::= <simple-id>                                # unresolved name
3018 //          extension     ::= <operator-name>                            # unresolved operator-function-id
3019 //          extension     ::= <operator-name> <template-args>            # unresolved operator template-id
3020 //                        ::= on <operator-name>                         # unresolved operator-function-id
3021 //                        ::= on <operator-name> <template-args>         # unresolved operator template-id
3022 //                        ::= dn <destructor-name>                       # destructor or pseudo-destructor;
3023 //                                                                         # e.g. ~X or ~X<N-1>
3024 template <typename Derived, typename Alloc>
parseBaseUnresolvedName()3025 Node *AbstractManglingParser<Derived, Alloc>::parseBaseUnresolvedName() {
3026   if (std::isdigit(look()))
3027     return getDerived().parseSimpleId();
3028 
3029   if (consumeIf("dn"))
3030     return getDerived().parseDestructorName();
3031 
3032   consumeIf("on");
3033 
3034   Node *Oper = getDerived().parseOperatorName(/*NameState=*/nullptr);
3035   if (Oper == nullptr)
3036     return nullptr;
3037   if (look() == 'I') {
3038     Node *TA = getDerived().parseTemplateArgs();
3039     if (TA == nullptr)
3040       return nullptr;
3041     return make<NameWithTemplateArgs>(Oper, TA);
3042   }
3043   return Oper;
3044 }
3045 
3046 // <unresolved-name>
3047 //  extension        ::= srN <unresolved-type> [<template-args>] <unresolved-qualifier-level>* E <base-unresolved-name>
3048 //                   ::= [gs] <base-unresolved-name>                     # x or (with "gs") ::x
3049 //                   ::= [gs] sr <unresolved-qualifier-level>+ E <base-unresolved-name>
3050 //                                                                       # A::x, N::y, A<T>::z; "gs" means leading "::"
3051 //                   ::= sr <unresolved-type> <base-unresolved-name>     # T::x / decltype(p)::x
3052 //  extension        ::= sr <unresolved-type> <template-args> <base-unresolved-name>
3053 //                                                                       # T::N::x /decltype(p)::N::x
3054 //  (ignored)        ::= srN <unresolved-type>  <unresolved-qualifier-level>+ E <base-unresolved-name>
3055 //
3056 // <unresolved-qualifier-level> ::= <simple-id>
3057 template <typename Derived, typename Alloc>
parseUnresolvedName()3058 Node *AbstractManglingParser<Derived, Alloc>::parseUnresolvedName() {
3059   Node *SoFar = nullptr;
3060 
3061   // srN <unresolved-type> [<template-args>] <unresolved-qualifier-level>* E <base-unresolved-name>
3062   // srN <unresolved-type>                   <unresolved-qualifier-level>+ E <base-unresolved-name>
3063   if (consumeIf("srN")) {
3064     SoFar = getDerived().parseUnresolvedType();
3065     if (SoFar == nullptr)
3066       return nullptr;
3067 
3068     if (look() == 'I') {
3069       Node *TA = getDerived().parseTemplateArgs();
3070       if (TA == nullptr)
3071         return nullptr;
3072       SoFar = make<NameWithTemplateArgs>(SoFar, TA);
3073       if (!SoFar)
3074         return nullptr;
3075     }
3076 
3077     while (!consumeIf('E')) {
3078       Node *Qual = getDerived().parseSimpleId();
3079       if (Qual == nullptr)
3080         return nullptr;
3081       SoFar = make<QualifiedName>(SoFar, Qual);
3082       if (!SoFar)
3083         return nullptr;
3084     }
3085 
3086     Node *Base = getDerived().parseBaseUnresolvedName();
3087     if (Base == nullptr)
3088       return nullptr;
3089     return make<QualifiedName>(SoFar, Base);
3090   }
3091 
3092   bool Global = consumeIf("gs");
3093 
3094   // [gs] <base-unresolved-name>                     # x or (with "gs") ::x
3095   if (!consumeIf("sr")) {
3096     SoFar = getDerived().parseBaseUnresolvedName();
3097     if (SoFar == nullptr)
3098       return nullptr;
3099     if (Global)
3100       SoFar = make<GlobalQualifiedName>(SoFar);
3101     return SoFar;
3102   }
3103 
3104   // [gs] sr <unresolved-qualifier-level>+ E   <base-unresolved-name>
3105   if (std::isdigit(look())) {
3106     do {
3107       Node *Qual = getDerived().parseSimpleId();
3108       if (Qual == nullptr)
3109         return nullptr;
3110       if (SoFar)
3111         SoFar = make<QualifiedName>(SoFar, Qual);
3112       else if (Global)
3113         SoFar = make<GlobalQualifiedName>(Qual);
3114       else
3115         SoFar = Qual;
3116       if (!SoFar)
3117         return nullptr;
3118     } while (!consumeIf('E'));
3119   }
3120   //      sr <unresolved-type>                 <base-unresolved-name>
3121   //      sr <unresolved-type> <template-args> <base-unresolved-name>
3122   else {
3123     SoFar = getDerived().parseUnresolvedType();
3124     if (SoFar == nullptr)
3125       return nullptr;
3126 
3127     if (look() == 'I') {
3128       Node *TA = getDerived().parseTemplateArgs();
3129       if (TA == nullptr)
3130         return nullptr;
3131       SoFar = make<NameWithTemplateArgs>(SoFar, TA);
3132       if (!SoFar)
3133         return nullptr;
3134     }
3135   }
3136 
3137   assert(SoFar != nullptr);
3138 
3139   Node *Base = getDerived().parseBaseUnresolvedName();
3140   if (Base == nullptr)
3141     return nullptr;
3142   return make<QualifiedName>(SoFar, Base);
3143 }
3144 
3145 // <abi-tags> ::= <abi-tag> [<abi-tags>]
3146 // <abi-tag> ::= B <source-name>
3147 template <typename Derived, typename Alloc>
parseAbiTags(Node * N)3148 Node *AbstractManglingParser<Derived, Alloc>::parseAbiTags(Node *N) {
3149   while (consumeIf('B')) {
3150     StringView SN = parseBareSourceName();
3151     if (SN.empty())
3152       return nullptr;
3153     N = make<AbiTagAttr>(N, SN);
3154     if (!N)
3155       return nullptr;
3156   }
3157   return N;
3158 }
3159 
3160 // <number> ::= [n] <non-negative decimal integer>
3161 template <typename Alloc, typename Derived>
3162 StringView
parseNumber(bool AllowNegative)3163 AbstractManglingParser<Alloc, Derived>::parseNumber(bool AllowNegative) {
3164   const char *Tmp = First;
3165   if (AllowNegative)
3166     consumeIf('n');
3167   if (numLeft() == 0 || !std::isdigit(*First))
3168     return StringView();
3169   while (numLeft() != 0 && std::isdigit(*First))
3170     ++First;
3171   return StringView(Tmp, First);
3172 }
3173 
3174 // <positive length number> ::= [0-9]*
3175 template <typename Alloc, typename Derived>
parsePositiveInteger(size_t * Out)3176 bool AbstractManglingParser<Alloc, Derived>::parsePositiveInteger(size_t *Out) {
3177   *Out = 0;
3178   if (look() < '0' || look() > '9')
3179     return true;
3180   while (look() >= '0' && look() <= '9') {
3181     *Out *= 10;
3182     *Out += static_cast<size_t>(consume() - '0');
3183   }
3184   return false;
3185 }
3186 
3187 template <typename Alloc, typename Derived>
parseBareSourceName()3188 StringView AbstractManglingParser<Alloc, Derived>::parseBareSourceName() {
3189   size_t Int = 0;
3190   if (parsePositiveInteger(&Int) || numLeft() < Int)
3191     return StringView();
3192   StringView R(First, First + Int);
3193   First += Int;
3194   return R;
3195 }
3196 
3197 // <function-type> ::= [<CV-qualifiers>] [<exception-spec>] [Dx] F [Y] <bare-function-type> [<ref-qualifier>] E
3198 //
3199 // <exception-spec> ::= Do                # non-throwing exception-specification (e.g., noexcept, throw())
3200 //                  ::= DO <expression> E # computed (instantiation-dependent) noexcept
3201 //                  ::= Dw <type>+ E      # dynamic exception specification with instantiation-dependent types
3202 //
3203 // <ref-qualifier> ::= R                   # & ref-qualifier
3204 // <ref-qualifier> ::= O                   # && ref-qualifier
3205 template <typename Derived, typename Alloc>
parseFunctionType()3206 Node *AbstractManglingParser<Derived, Alloc>::parseFunctionType() {
3207   Qualifiers CVQuals = parseCVQualifiers();
3208 
3209   Node *ExceptionSpec = nullptr;
3210   if (consumeIf("Do")) {
3211     ExceptionSpec = make<NameType>("noexcept");
3212     if (!ExceptionSpec)
3213       return nullptr;
3214   } else if (consumeIf("DO")) {
3215     Node *E = getDerived().parseExpr();
3216     if (E == nullptr || !consumeIf('E'))
3217       return nullptr;
3218     ExceptionSpec = make<NoexceptSpec>(E);
3219     if (!ExceptionSpec)
3220       return nullptr;
3221   } else if (consumeIf("Dw")) {
3222     size_t SpecsBegin = Names.size();
3223     while (!consumeIf('E')) {
3224       Node *T = getDerived().parseType();
3225       if (T == nullptr)
3226         return nullptr;
3227       Names.push_back(T);
3228     }
3229     ExceptionSpec =
3230       make<DynamicExceptionSpec>(popTrailingNodeArray(SpecsBegin));
3231     if (!ExceptionSpec)
3232       return nullptr;
3233   }
3234 
3235   consumeIf("Dx"); // transaction safe
3236 
3237   if (!consumeIf('F'))
3238     return nullptr;
3239   consumeIf('Y'); // extern "C"
3240   Node *ReturnType = getDerived().parseType();
3241   if (ReturnType == nullptr)
3242     return nullptr;
3243 
3244   FunctionRefQual ReferenceQualifier = FrefQualNone;
3245   size_t ParamsBegin = Names.size();
3246   while (true) {
3247     if (consumeIf('E'))
3248       break;
3249     if (consumeIf('v'))
3250       continue;
3251     if (consumeIf("RE")) {
3252       ReferenceQualifier = FrefQualLValue;
3253       break;
3254     }
3255     if (consumeIf("OE")) {
3256       ReferenceQualifier = FrefQualRValue;
3257       break;
3258     }
3259     Node *T = getDerived().parseType();
3260     if (T == nullptr)
3261       return nullptr;
3262     Names.push_back(T);
3263   }
3264 
3265   NodeArray Params = popTrailingNodeArray(ParamsBegin);
3266   return make<FunctionType>(ReturnType, Params, CVQuals,
3267                             ReferenceQualifier, ExceptionSpec);
3268 }
3269 
3270 // extension:
3271 // <vector-type>           ::= Dv <positive dimension number> _ <extended element type>
3272 //                         ::= Dv [<dimension expression>] _ <element type>
3273 // <extended element type> ::= <element type>
3274 //                         ::= p # AltiVec vector pixel
3275 template <typename Derived, typename Alloc>
parseVectorType()3276 Node *AbstractManglingParser<Derived, Alloc>::parseVectorType() {
3277   if (!consumeIf("Dv"))
3278     return nullptr;
3279   if (look() >= '1' && look() <= '9') {
3280     StringView DimensionNumber = parseNumber();
3281     if (!consumeIf('_'))
3282       return nullptr;
3283     if (consumeIf('p'))
3284       return make<PixelVectorType>(DimensionNumber);
3285     Node *ElemType = getDerived().parseType();
3286     if (ElemType == nullptr)
3287       return nullptr;
3288     return make<VectorType>(ElemType, DimensionNumber);
3289   }
3290 
3291   if (!consumeIf('_')) {
3292     Node *DimExpr = getDerived().parseExpr();
3293     if (!DimExpr)
3294       return nullptr;
3295     if (!consumeIf('_'))
3296       return nullptr;
3297     Node *ElemType = getDerived().parseType();
3298     if (!ElemType)
3299       return nullptr;
3300     return make<VectorType>(ElemType, DimExpr);
3301   }
3302   Node *ElemType = getDerived().parseType();
3303   if (!ElemType)
3304     return nullptr;
3305   return make<VectorType>(ElemType, StringView());
3306 }
3307 
3308 // <decltype>  ::= Dt <expression> E  # decltype of an id-expression or class member access (C++0x)
3309 //             ::= DT <expression> E  # decltype of an expression (C++0x)
3310 template <typename Derived, typename Alloc>
parseDecltype()3311 Node *AbstractManglingParser<Derived, Alloc>::parseDecltype() {
3312   if (!consumeIf('D'))
3313     return nullptr;
3314   if (!consumeIf('t') && !consumeIf('T'))
3315     return nullptr;
3316   Node *E = getDerived().parseExpr();
3317   if (E == nullptr)
3318     return nullptr;
3319   if (!consumeIf('E'))
3320     return nullptr;
3321   return make<EnclosingExpr>("decltype(", E, ")");
3322 }
3323 
3324 // <array-type> ::= A <positive dimension number> _ <element type>
3325 //              ::= A [<dimension expression>] _ <element type>
3326 template <typename Derived, typename Alloc>
parseArrayType()3327 Node *AbstractManglingParser<Derived, Alloc>::parseArrayType() {
3328   if (!consumeIf('A'))
3329     return nullptr;
3330 
3331   NodeOrString Dimension;
3332 
3333   if (std::isdigit(look())) {
3334     Dimension = parseNumber();
3335     if (!consumeIf('_'))
3336       return nullptr;
3337   } else if (!consumeIf('_')) {
3338     Node *DimExpr = getDerived().parseExpr();
3339     if (DimExpr == nullptr)
3340       return nullptr;
3341     if (!consumeIf('_'))
3342       return nullptr;
3343     Dimension = DimExpr;
3344   }
3345 
3346   Node *Ty = getDerived().parseType();
3347   if (Ty == nullptr)
3348     return nullptr;
3349   return make<ArrayType>(Ty, Dimension);
3350 }
3351 
3352 // <pointer-to-member-type> ::= M <class type> <member type>
3353 template <typename Derived, typename Alloc>
parsePointerToMemberType()3354 Node *AbstractManglingParser<Derived, Alloc>::parsePointerToMemberType() {
3355   if (!consumeIf('M'))
3356     return nullptr;
3357   Node *ClassType = getDerived().parseType();
3358   if (ClassType == nullptr)
3359     return nullptr;
3360   Node *MemberType = getDerived().parseType();
3361   if (MemberType == nullptr)
3362     return nullptr;
3363   return make<PointerToMemberType>(ClassType, MemberType);
3364 }
3365 
3366 // <class-enum-type> ::= <name>     # non-dependent type name, dependent type name, or dependent typename-specifier
3367 //                   ::= Ts <name>  # dependent elaborated type specifier using 'struct' or 'class'
3368 //                   ::= Tu <name>  # dependent elaborated type specifier using 'union'
3369 //                   ::= Te <name>  # dependent elaborated type specifier using 'enum'
3370 template <typename Derived, typename Alloc>
parseClassEnumType()3371 Node *AbstractManglingParser<Derived, Alloc>::parseClassEnumType() {
3372   StringView ElabSpef;
3373   if (consumeIf("Ts"))
3374     ElabSpef = "struct";
3375   else if (consumeIf("Tu"))
3376     ElabSpef = "union";
3377   else if (consumeIf("Te"))
3378     ElabSpef = "enum";
3379 
3380   Node *Name = getDerived().parseName();
3381   if (Name == nullptr)
3382     return nullptr;
3383 
3384   if (!ElabSpef.empty())
3385     return make<ElaboratedTypeSpefType>(ElabSpef, Name);
3386 
3387   return Name;
3388 }
3389 
3390 // <qualified-type>     ::= <qualifiers> <type>
3391 // <qualifiers> ::= <extended-qualifier>* <CV-qualifiers>
3392 // <extended-qualifier> ::= U <source-name> [<template-args>] # vendor extended type qualifier
3393 template <typename Derived, typename Alloc>
parseQualifiedType()3394 Node *AbstractManglingParser<Derived, Alloc>::parseQualifiedType() {
3395   if (consumeIf('U')) {
3396     StringView Qual = parseBareSourceName();
3397     if (Qual.empty())
3398       return nullptr;
3399 
3400     // FIXME parse the optional <template-args> here!
3401 
3402     // extension            ::= U <objc-name> <objc-type>  # objc-type<identifier>
3403     if (Qual.startsWith("objcproto")) {
3404       StringView ProtoSourceName = Qual.dropFront(std::strlen("objcproto"));
3405       StringView Proto;
3406       {
3407         SwapAndRestore<const char *> SaveFirst(First, ProtoSourceName.begin()),
3408                                      SaveLast(Last, ProtoSourceName.end());
3409         Proto = parseBareSourceName();
3410       }
3411       if (Proto.empty())
3412         return nullptr;
3413       Node *Child = getDerived().parseQualifiedType();
3414       if (Child == nullptr)
3415         return nullptr;
3416       return make<ObjCProtoName>(Child, Proto);
3417     }
3418 
3419     Node *Child = getDerived().parseQualifiedType();
3420     if (Child == nullptr)
3421       return nullptr;
3422     return make<VendorExtQualType>(Child, Qual);
3423   }
3424 
3425   Qualifiers Quals = parseCVQualifiers();
3426   Node *Ty = getDerived().parseType();
3427   if (Ty == nullptr)
3428     return nullptr;
3429   if (Quals != QualNone)
3430     Ty = make<QualType>(Ty, Quals);
3431   return Ty;
3432 }
3433 
3434 // <type>      ::= <builtin-type>
3435 //             ::= <qualified-type>
3436 //             ::= <function-type>
3437 //             ::= <class-enum-type>
3438 //             ::= <array-type>
3439 //             ::= <pointer-to-member-type>
3440 //             ::= <template-param>
3441 //             ::= <template-template-param> <template-args>
3442 //             ::= <decltype>
3443 //             ::= P <type>        # pointer
3444 //             ::= R <type>        # l-value reference
3445 //             ::= O <type>        # r-value reference (C++11)
3446 //             ::= C <type>        # complex pair (C99)
3447 //             ::= G <type>        # imaginary (C99)
3448 //             ::= <substitution>  # See Compression below
3449 // extension   ::= U <objc-name> <objc-type>  # objc-type<identifier>
3450 // extension   ::= <vector-type> # <vector-type> starts with Dv
3451 //
3452 // <objc-name> ::= <k0 number> objcproto <k1 number> <identifier>  # k0 = 9 + <number of digits in k1> + k1
3453 // <objc-type> ::= <source-name>  # PU<11+>objcproto 11objc_object<source-name> 11objc_object -> id<source-name>
3454 template <typename Derived, typename Alloc>
parseType()3455 Node *AbstractManglingParser<Derived, Alloc>::parseType() {
3456   Node *Result = nullptr;
3457 
3458   switch (look()) {
3459   //             ::= <qualified-type>
3460   case 'r':
3461   case 'V':
3462   case 'K': {
3463     unsigned AfterQuals = 0;
3464     if (look(AfterQuals) == 'r') ++AfterQuals;
3465     if (look(AfterQuals) == 'V') ++AfterQuals;
3466     if (look(AfterQuals) == 'K') ++AfterQuals;
3467 
3468     if (look(AfterQuals) == 'F' ||
3469         (look(AfterQuals) == 'D' &&
3470          (look(AfterQuals + 1) == 'o' || look(AfterQuals + 1) == 'O' ||
3471           look(AfterQuals + 1) == 'w' || look(AfterQuals + 1) == 'x'))) {
3472       Result = getDerived().parseFunctionType();
3473       break;
3474     }
3475     _LIBCPP_FALLTHROUGH();
3476   }
3477   case 'U': {
3478     Result = getDerived().parseQualifiedType();
3479     break;
3480   }
3481   // <builtin-type> ::= v    # void
3482   case 'v':
3483     ++First;
3484     return make<NameType>("void");
3485   //                ::= w    # wchar_t
3486   case 'w':
3487     ++First;
3488     return make<NameType>("wchar_t");
3489   //                ::= b    # bool
3490   case 'b':
3491     ++First;
3492     return make<NameType>("bool");
3493   //                ::= c    # char
3494   case 'c':
3495     ++First;
3496     return make<NameType>("char");
3497   //                ::= a    # signed char
3498   case 'a':
3499     ++First;
3500     return make<NameType>("signed char");
3501   //                ::= h    # unsigned char
3502   case 'h':
3503     ++First;
3504     return make<NameType>("unsigned char");
3505   //                ::= s    # short
3506   case 's':
3507     ++First;
3508     return make<NameType>("short");
3509   //                ::= t    # unsigned short
3510   case 't':
3511     ++First;
3512     return make<NameType>("unsigned short");
3513   //                ::= i    # int
3514   case 'i':
3515     ++First;
3516     return make<NameType>("int");
3517   //                ::= j    # unsigned int
3518   case 'j':
3519     ++First;
3520     return make<NameType>("unsigned int");
3521   //                ::= l    # long
3522   case 'l':
3523     ++First;
3524     return make<NameType>("long");
3525   //                ::= m    # unsigned long
3526   case 'm':
3527     ++First;
3528     return make<NameType>("unsigned long");
3529   //                ::= x    # long long, __int64
3530   case 'x':
3531     ++First;
3532     return make<NameType>("long long");
3533   //                ::= y    # unsigned long long, __int64
3534   case 'y':
3535     ++First;
3536     return make<NameType>("unsigned long long");
3537   //                ::= n    # __int128
3538   case 'n':
3539     ++First;
3540     return make<NameType>("__int128");
3541   //                ::= o    # unsigned __int128
3542   case 'o':
3543     ++First;
3544     return make<NameType>("unsigned __int128");
3545   //                ::= f    # float
3546   case 'f':
3547     ++First;
3548     return make<NameType>("float");
3549   //                ::= d    # double
3550   case 'd':
3551     ++First;
3552     return make<NameType>("double");
3553   //                ::= e    # long double, __float80
3554   case 'e':
3555     ++First;
3556     return make<NameType>("long double");
3557   //                ::= g    # __float128
3558   case 'g':
3559     ++First;
3560     return make<NameType>("__float128");
3561   //                ::= z    # ellipsis
3562   case 'z':
3563     ++First;
3564     return make<NameType>("...");
3565 
3566   // <builtin-type> ::= u <source-name>    # vendor extended type
3567   case 'u': {
3568     ++First;
3569     StringView Res = parseBareSourceName();
3570     if (Res.empty())
3571       return nullptr;
3572     return make<NameType>(Res);
3573   }
3574   case 'D':
3575     switch (look(1)) {
3576     //                ::= Dd   # IEEE 754r decimal floating point (64 bits)
3577     case 'd':
3578       First += 2;
3579       return make<NameType>("decimal64");
3580     //                ::= De   # IEEE 754r decimal floating point (128 bits)
3581     case 'e':
3582       First += 2;
3583       return make<NameType>("decimal128");
3584     //                ::= Df   # IEEE 754r decimal floating point (32 bits)
3585     case 'f':
3586       First += 2;
3587       return make<NameType>("decimal32");
3588     //                ::= Dh   # IEEE 754r half-precision floating point (16 bits)
3589     case 'h':
3590       First += 2;
3591       return make<NameType>("decimal16");
3592     //                ::= Di   # char32_t
3593     case 'i':
3594       First += 2;
3595       return make<NameType>("char32_t");
3596     //                ::= Ds   # char16_t
3597     case 's':
3598       First += 2;
3599       return make<NameType>("char16_t");
3600     //                ::= Da   # auto (in dependent new-expressions)
3601     case 'a':
3602       First += 2;
3603       return make<NameType>("auto");
3604     //                ::= Dc   # decltype(auto)
3605     case 'c':
3606       First += 2;
3607       return make<NameType>("decltype(auto)");
3608     //                ::= Dn   # std::nullptr_t (i.e., decltype(nullptr))
3609     case 'n':
3610       First += 2;
3611       return make<NameType>("std::nullptr_t");
3612 
3613     //             ::= <decltype>
3614     case 't':
3615     case 'T': {
3616       Result = getDerived().parseDecltype();
3617       break;
3618     }
3619     // extension   ::= <vector-type> # <vector-type> starts with Dv
3620     case 'v': {
3621       Result = getDerived().parseVectorType();
3622       break;
3623     }
3624     //           ::= Dp <type>       # pack expansion (C++0x)
3625     case 'p': {
3626       First += 2;
3627       Node *Child = getDerived().parseType();
3628       if (!Child)
3629         return nullptr;
3630       Result = make<ParameterPackExpansion>(Child);
3631       break;
3632     }
3633     // Exception specifier on a function type.
3634     case 'o':
3635     case 'O':
3636     case 'w':
3637     // Transaction safe function type.
3638     case 'x':
3639       Result = getDerived().parseFunctionType();
3640       break;
3641     }
3642     break;
3643   //             ::= <function-type>
3644   case 'F': {
3645     Result = getDerived().parseFunctionType();
3646     break;
3647   }
3648   //             ::= <array-type>
3649   case 'A': {
3650     Result = getDerived().parseArrayType();
3651     break;
3652   }
3653   //             ::= <pointer-to-member-type>
3654   case 'M': {
3655     Result = getDerived().parsePointerToMemberType();
3656     break;
3657   }
3658   //             ::= <template-param>
3659   case 'T': {
3660     // This could be an elaborate type specifier on a <class-enum-type>.
3661     if (look(1) == 's' || look(1) == 'u' || look(1) == 'e') {
3662       Result = getDerived().parseClassEnumType();
3663       break;
3664     }
3665 
3666     Result = getDerived().parseTemplateParam();
3667     if (Result == nullptr)
3668       return nullptr;
3669 
3670     // Result could be either of:
3671     //   <type>        ::= <template-param>
3672     //   <type>        ::= <template-template-param> <template-args>
3673     //
3674     //   <template-template-param> ::= <template-param>
3675     //                             ::= <substitution>
3676     //
3677     // If this is followed by some <template-args>, and we're permitted to
3678     // parse them, take the second production.
3679 
3680     if (TryToParseTemplateArgs && look() == 'I') {
3681       Node *TA = getDerived().parseTemplateArgs();
3682       if (TA == nullptr)
3683         return nullptr;
3684       Result = make<NameWithTemplateArgs>(Result, TA);
3685     }
3686     break;
3687   }
3688   //             ::= P <type>        # pointer
3689   case 'P': {
3690     ++First;
3691     Node *Ptr = getDerived().parseType();
3692     if (Ptr == nullptr)
3693       return nullptr;
3694     Result = make<PointerType>(Ptr);
3695     break;
3696   }
3697   //             ::= R <type>        # l-value reference
3698   case 'R': {
3699     ++First;
3700     Node *Ref = getDerived().parseType();
3701     if (Ref == nullptr)
3702       return nullptr;
3703     Result = make<ReferenceType>(Ref, ReferenceKind::LValue);
3704     break;
3705   }
3706   //             ::= O <type>        # r-value reference (C++11)
3707   case 'O': {
3708     ++First;
3709     Node *Ref = getDerived().parseType();
3710     if (Ref == nullptr)
3711       return nullptr;
3712     Result = make<ReferenceType>(Ref, ReferenceKind::RValue);
3713     break;
3714   }
3715   //             ::= C <type>        # complex pair (C99)
3716   case 'C': {
3717     ++First;
3718     Node *P = getDerived().parseType();
3719     if (P == nullptr)
3720       return nullptr;
3721     Result = make<PostfixQualifiedType>(P, " complex");
3722     break;
3723   }
3724   //             ::= G <type>        # imaginary (C99)
3725   case 'G': {
3726     ++First;
3727     Node *P = getDerived().parseType();
3728     if (P == nullptr)
3729       return P;
3730     Result = make<PostfixQualifiedType>(P, " imaginary");
3731     break;
3732   }
3733   //             ::= <substitution>  # See Compression below
3734   case 'S': {
3735     if (look(1) && look(1) != 't') {
3736       Node *Sub = getDerived().parseSubstitution();
3737       if (Sub == nullptr)
3738         return nullptr;
3739 
3740       // Sub could be either of:
3741       //   <type>        ::= <substitution>
3742       //   <type>        ::= <template-template-param> <template-args>
3743       //
3744       //   <template-template-param> ::= <template-param>
3745       //                             ::= <substitution>
3746       //
3747       // If this is followed by some <template-args>, and we're permitted to
3748       // parse them, take the second production.
3749 
3750       if (TryToParseTemplateArgs && look() == 'I') {
3751         Node *TA = getDerived().parseTemplateArgs();
3752         if (TA == nullptr)
3753           return nullptr;
3754         Result = make<NameWithTemplateArgs>(Sub, TA);
3755         break;
3756       }
3757 
3758       // If all we parsed was a substitution, don't re-insert into the
3759       // substitution table.
3760       return Sub;
3761     }
3762     _LIBCPP_FALLTHROUGH();
3763   }
3764   //        ::= <class-enum-type>
3765   default: {
3766     Result = getDerived().parseClassEnumType();
3767     break;
3768   }
3769   }
3770 
3771   // If we parsed a type, insert it into the substitution table. Note that all
3772   // <builtin-type>s and <substitution>s have already bailed out, because they
3773   // don't get substitutions.
3774   if (Result != nullptr)
3775     Subs.push_back(Result);
3776   return Result;
3777 }
3778 
3779 template <typename Derived, typename Alloc>
parsePrefixExpr(StringView Kind)3780 Node *AbstractManglingParser<Derived, Alloc>::parsePrefixExpr(StringView Kind) {
3781   Node *E = getDerived().parseExpr();
3782   if (E == nullptr)
3783     return nullptr;
3784   return make<PrefixExpr>(Kind, E);
3785 }
3786 
3787 template <typename Derived, typename Alloc>
parseBinaryExpr(StringView Kind)3788 Node *AbstractManglingParser<Derived, Alloc>::parseBinaryExpr(StringView Kind) {
3789   Node *LHS = getDerived().parseExpr();
3790   if (LHS == nullptr)
3791     return nullptr;
3792   Node *RHS = getDerived().parseExpr();
3793   if (RHS == nullptr)
3794     return nullptr;
3795   return make<BinaryExpr>(LHS, Kind, RHS);
3796 }
3797 
3798 template <typename Derived, typename Alloc>
3799 Node *
parseIntegerLiteral(StringView Lit)3800 AbstractManglingParser<Derived, Alloc>::parseIntegerLiteral(StringView Lit) {
3801   StringView Tmp = parseNumber(true);
3802   if (!Tmp.empty() && consumeIf('E'))
3803     return make<IntegerLiteral>(Lit, Tmp);
3804   return nullptr;
3805 }
3806 
3807 // <CV-Qualifiers> ::= [r] [V] [K]
3808 template <typename Alloc, typename Derived>
parseCVQualifiers()3809 Qualifiers AbstractManglingParser<Alloc, Derived>::parseCVQualifiers() {
3810   Qualifiers CVR = QualNone;
3811   if (consumeIf('r'))
3812     CVR |= QualRestrict;
3813   if (consumeIf('V'))
3814     CVR |= QualVolatile;
3815   if (consumeIf('K'))
3816     CVR |= QualConst;
3817   return CVR;
3818 }
3819 
3820 // <function-param> ::= fp <top-level CV-Qualifiers> _                                     # L == 0, first parameter
3821 //                  ::= fp <top-level CV-Qualifiers> <parameter-2 non-negative number> _   # L == 0, second and later parameters
3822 //                  ::= fL <L-1 non-negative number> p <top-level CV-Qualifiers> _         # L > 0, first parameter
3823 //                  ::= fL <L-1 non-negative number> p <top-level CV-Qualifiers> <parameter-2 non-negative number> _   # L > 0, second and later parameters
3824 template <typename Derived, typename Alloc>
parseFunctionParam()3825 Node *AbstractManglingParser<Derived, Alloc>::parseFunctionParam() {
3826   if (consumeIf("fp")) {
3827     parseCVQualifiers();
3828     StringView Num = parseNumber();
3829     if (!consumeIf('_'))
3830       return nullptr;
3831     return make<FunctionParam>(Num);
3832   }
3833   if (consumeIf("fL")) {
3834     if (parseNumber().empty())
3835       return nullptr;
3836     if (!consumeIf('p'))
3837       return nullptr;
3838     parseCVQualifiers();
3839     StringView Num = parseNumber();
3840     if (!consumeIf('_'))
3841       return nullptr;
3842     return make<FunctionParam>(Num);
3843   }
3844   return nullptr;
3845 }
3846 
3847 // [gs] nw <expression>* _ <type> E                     # new (expr-list) type
3848 // [gs] nw <expression>* _ <type> <initializer>         # new (expr-list) type (init)
3849 // [gs] na <expression>* _ <type> E                     # new[] (expr-list) type
3850 // [gs] na <expression>* _ <type> <initializer>         # new[] (expr-list) type (init)
3851 // <initializer> ::= pi <expression>* E                 # parenthesized initialization
3852 template <typename Derived, typename Alloc>
parseNewExpr()3853 Node *AbstractManglingParser<Derived, Alloc>::parseNewExpr() {
3854   bool Global = consumeIf("gs");
3855   bool IsArray = look(1) == 'a';
3856   if (!consumeIf("nw") && !consumeIf("na"))
3857     return nullptr;
3858   size_t Exprs = Names.size();
3859   while (!consumeIf('_')) {
3860     Node *Ex = getDerived().parseExpr();
3861     if (Ex == nullptr)
3862       return nullptr;
3863     Names.push_back(Ex);
3864   }
3865   NodeArray ExprList = popTrailingNodeArray(Exprs);
3866   Node *Ty = getDerived().parseType();
3867   if (Ty == nullptr)
3868     return Ty;
3869   if (consumeIf("pi")) {
3870     size_t InitsBegin = Names.size();
3871     while (!consumeIf('E')) {
3872       Node *Init = getDerived().parseExpr();
3873       if (Init == nullptr)
3874         return Init;
3875       Names.push_back(Init);
3876     }
3877     NodeArray Inits = popTrailingNodeArray(InitsBegin);
3878     return make<NewExpr>(ExprList, Ty, Inits, Global, IsArray);
3879   } else if (!consumeIf('E'))
3880     return nullptr;
3881   return make<NewExpr>(ExprList, Ty, NodeArray(), Global, IsArray);
3882 }
3883 
3884 // cv <type> <expression>                               # conversion with one argument
3885 // cv <type> _ <expression>* E                          # conversion with a different number of arguments
3886 template <typename Derived, typename Alloc>
parseConversionExpr()3887 Node *AbstractManglingParser<Derived, Alloc>::parseConversionExpr() {
3888   if (!consumeIf("cv"))
3889     return nullptr;
3890   Node *Ty;
3891   {
3892     SwapAndRestore<bool> SaveTemp(TryToParseTemplateArgs, false);
3893     Ty = getDerived().parseType();
3894   }
3895 
3896   if (Ty == nullptr)
3897     return nullptr;
3898 
3899   if (consumeIf('_')) {
3900     size_t ExprsBegin = Names.size();
3901     while (!consumeIf('E')) {
3902       Node *E = getDerived().parseExpr();
3903       if (E == nullptr)
3904         return E;
3905       Names.push_back(E);
3906     }
3907     NodeArray Exprs = popTrailingNodeArray(ExprsBegin);
3908     return make<ConversionExpr>(Ty, Exprs);
3909   }
3910 
3911   Node *E[1] = {getDerived().parseExpr()};
3912   if (E[0] == nullptr)
3913     return nullptr;
3914   return make<ConversionExpr>(Ty, makeNodeArray(E, E + 1));
3915 }
3916 
3917 // <expr-primary> ::= L <type> <value number> E                          # integer literal
3918 //                ::= L <type> <value float> E                           # floating literal
3919 //                ::= L <string type> E                                  # string literal
3920 //                ::= L <nullptr type> E                                 # nullptr literal (i.e., "LDnE")
3921 // FIXME:         ::= L <type> <real-part float> _ <imag-part float> E   # complex floating point literal (C 2000)
3922 //                ::= L <mangled-name> E                                 # external name
3923 template <typename Derived, typename Alloc>
parseExprPrimary()3924 Node *AbstractManglingParser<Derived, Alloc>::parseExprPrimary() {
3925   if (!consumeIf('L'))
3926     return nullptr;
3927   switch (look()) {
3928   case 'w':
3929     ++First;
3930     return getDerived().parseIntegerLiteral("wchar_t");
3931   case 'b':
3932     if (consumeIf("b0E"))
3933       return make<BoolExpr>(0);
3934     if (consumeIf("b1E"))
3935       return make<BoolExpr>(1);
3936     return nullptr;
3937   case 'c':
3938     ++First;
3939     return getDerived().parseIntegerLiteral("char");
3940   case 'a':
3941     ++First;
3942     return getDerived().parseIntegerLiteral("signed char");
3943   case 'h':
3944     ++First;
3945     return getDerived().parseIntegerLiteral("unsigned char");
3946   case 's':
3947     ++First;
3948     return getDerived().parseIntegerLiteral("short");
3949   case 't':
3950     ++First;
3951     return getDerived().parseIntegerLiteral("unsigned short");
3952   case 'i':
3953     ++First;
3954     return getDerived().parseIntegerLiteral("");
3955   case 'j':
3956     ++First;
3957     return getDerived().parseIntegerLiteral("u");
3958   case 'l':
3959     ++First;
3960     return getDerived().parseIntegerLiteral("l");
3961   case 'm':
3962     ++First;
3963     return getDerived().parseIntegerLiteral("ul");
3964   case 'x':
3965     ++First;
3966     return getDerived().parseIntegerLiteral("ll");
3967   case 'y':
3968     ++First;
3969     return getDerived().parseIntegerLiteral("ull");
3970   case 'n':
3971     ++First;
3972     return getDerived().parseIntegerLiteral("__int128");
3973   case 'o':
3974     ++First;
3975     return getDerived().parseIntegerLiteral("unsigned __int128");
3976   case 'f':
3977     ++First;
3978     return getDerived().template parseFloatingLiteral<float>();
3979   case 'd':
3980     ++First;
3981     return getDerived().template parseFloatingLiteral<double>();
3982   case 'e':
3983     ++First;
3984     return getDerived().template parseFloatingLiteral<long double>();
3985   case '_':
3986     if (consumeIf("_Z")) {
3987       Node *R = getDerived().parseEncoding();
3988       if (R != nullptr && consumeIf('E'))
3989         return R;
3990     }
3991     return nullptr;
3992   case 'T':
3993     // Invalid mangled name per
3994     //   http://sourcerytools.com/pipermail/cxx-abi-dev/2011-August/002422.html
3995     return nullptr;
3996   default: {
3997     // might be named type
3998     Node *T = getDerived().parseType();
3999     if (T == nullptr)
4000       return nullptr;
4001     StringView N = parseNumber();
4002     if (!N.empty()) {
4003       if (!consumeIf('E'))
4004         return nullptr;
4005       return make<IntegerCastExpr>(T, N);
4006     }
4007     if (consumeIf('E'))
4008       return T;
4009     return nullptr;
4010   }
4011   }
4012 }
4013 
4014 // <braced-expression> ::= <expression>
4015 //                     ::= di <field source-name> <braced-expression>    # .name = expr
4016 //                     ::= dx <index expression> <braced-expression>     # [expr] = expr
4017 //                     ::= dX <range begin expression> <range end expression> <braced-expression>
4018 template <typename Derived, typename Alloc>
parseBracedExpr()4019 Node *AbstractManglingParser<Derived, Alloc>::parseBracedExpr() {
4020   if (look() == 'd') {
4021     switch (look(1)) {
4022     case 'i': {
4023       First += 2;
4024       Node *Field = getDerived().parseSourceName(/*NameState=*/nullptr);
4025       if (Field == nullptr)
4026         return nullptr;
4027       Node *Init = getDerived().parseBracedExpr();
4028       if (Init == nullptr)
4029         return nullptr;
4030       return make<BracedExpr>(Field, Init, /*isArray=*/false);
4031     }
4032     case 'x': {
4033       First += 2;
4034       Node *Index = getDerived().parseExpr();
4035       if (Index == nullptr)
4036         return nullptr;
4037       Node *Init = getDerived().parseBracedExpr();
4038       if (Init == nullptr)
4039         return nullptr;
4040       return make<BracedExpr>(Index, Init, /*isArray=*/true);
4041     }
4042     case 'X': {
4043       First += 2;
4044       Node *RangeBegin = getDerived().parseExpr();
4045       if (RangeBegin == nullptr)
4046         return nullptr;
4047       Node *RangeEnd = getDerived().parseExpr();
4048       if (RangeEnd == nullptr)
4049         return nullptr;
4050       Node *Init = getDerived().parseBracedExpr();
4051       if (Init == nullptr)
4052         return nullptr;
4053       return make<BracedRangeExpr>(RangeBegin, RangeEnd, Init);
4054     }
4055     }
4056   }
4057   return getDerived().parseExpr();
4058 }
4059 
4060 // (not yet in the spec)
4061 // <fold-expr> ::= fL <binary-operator-name> <expression> <expression>
4062 //             ::= fR <binary-operator-name> <expression> <expression>
4063 //             ::= fl <binary-operator-name> <expression>
4064 //             ::= fr <binary-operator-name> <expression>
4065 template <typename Derived, typename Alloc>
parseFoldExpr()4066 Node *AbstractManglingParser<Derived, Alloc>::parseFoldExpr() {
4067   if (!consumeIf('f'))
4068     return nullptr;
4069 
4070   char FoldKind = look();
4071   bool IsLeftFold, HasInitializer;
4072   HasInitializer = FoldKind == 'L' || FoldKind == 'R';
4073   if (FoldKind == 'l' || FoldKind == 'L')
4074     IsLeftFold = true;
4075   else if (FoldKind == 'r' || FoldKind == 'R')
4076     IsLeftFold = false;
4077   else
4078     return nullptr;
4079   ++First;
4080 
4081   // FIXME: This map is duplicated in parseOperatorName and parseExpr.
4082   StringView OperatorName;
4083   if      (consumeIf("aa")) OperatorName = "&&";
4084   else if (consumeIf("an")) OperatorName = "&";
4085   else if (consumeIf("aN")) OperatorName = "&=";
4086   else if (consumeIf("aS")) OperatorName = "=";
4087   else if (consumeIf("cm")) OperatorName = ",";
4088   else if (consumeIf("ds")) OperatorName = ".*";
4089   else if (consumeIf("dv")) OperatorName = "/";
4090   else if (consumeIf("dV")) OperatorName = "/=";
4091   else if (consumeIf("eo")) OperatorName = "^";
4092   else if (consumeIf("eO")) OperatorName = "^=";
4093   else if (consumeIf("eq")) OperatorName = "==";
4094   else if (consumeIf("ge")) OperatorName = ">=";
4095   else if (consumeIf("gt")) OperatorName = ">";
4096   else if (consumeIf("le")) OperatorName = "<=";
4097   else if (consumeIf("ls")) OperatorName = "<<";
4098   else if (consumeIf("lS")) OperatorName = "<<=";
4099   else if (consumeIf("lt")) OperatorName = "<";
4100   else if (consumeIf("mi")) OperatorName = "-";
4101   else if (consumeIf("mI")) OperatorName = "-=";
4102   else if (consumeIf("ml")) OperatorName = "*";
4103   else if (consumeIf("mL")) OperatorName = "*=";
4104   else if (consumeIf("ne")) OperatorName = "!=";
4105   else if (consumeIf("oo")) OperatorName = "||";
4106   else if (consumeIf("or")) OperatorName = "|";
4107   else if (consumeIf("oR")) OperatorName = "|=";
4108   else if (consumeIf("pl")) OperatorName = "+";
4109   else if (consumeIf("pL")) OperatorName = "+=";
4110   else if (consumeIf("rm")) OperatorName = "%";
4111   else if (consumeIf("rM")) OperatorName = "%=";
4112   else if (consumeIf("rs")) OperatorName = ">>";
4113   else if (consumeIf("rS")) OperatorName = ">>=";
4114   else return nullptr;
4115 
4116   Node *Pack = getDerived().parseExpr(), *Init = nullptr;
4117   if (Pack == nullptr)
4118     return nullptr;
4119   if (HasInitializer) {
4120     Init = getDerived().parseExpr();
4121     if (Init == nullptr)
4122       return nullptr;
4123   }
4124 
4125   if (IsLeftFold && Init)
4126     std::swap(Pack, Init);
4127 
4128   return make<FoldExpr>(IsLeftFold, OperatorName, Pack, Init);
4129 }
4130 
4131 // <expression> ::= <unary operator-name> <expression>
4132 //              ::= <binary operator-name> <expression> <expression>
4133 //              ::= <ternary operator-name> <expression> <expression> <expression>
4134 //              ::= cl <expression>+ E                                   # call
4135 //              ::= cv <type> <expression>                               # conversion with one argument
4136 //              ::= cv <type> _ <expression>* E                          # conversion with a different number of arguments
4137 //              ::= [gs] nw <expression>* _ <type> E                     # new (expr-list) type
4138 //              ::= [gs] nw <expression>* _ <type> <initializer>         # new (expr-list) type (init)
4139 //              ::= [gs] na <expression>* _ <type> E                     # new[] (expr-list) type
4140 //              ::= [gs] na <expression>* _ <type> <initializer>         # new[] (expr-list) type (init)
4141 //              ::= [gs] dl <expression>                                 # delete expression
4142 //              ::= [gs] da <expression>                                 # delete[] expression
4143 //              ::= pp_ <expression>                                     # prefix ++
4144 //              ::= mm_ <expression>                                     # prefix --
4145 //              ::= ti <type>                                            # typeid (type)
4146 //              ::= te <expression>                                      # typeid (expression)
4147 //              ::= dc <type> <expression>                               # dynamic_cast<type> (expression)
4148 //              ::= sc <type> <expression>                               # static_cast<type> (expression)
4149 //              ::= cc <type> <expression>                               # const_cast<type> (expression)
4150 //              ::= rc <type> <expression>                               # reinterpret_cast<type> (expression)
4151 //              ::= st <type>                                            # sizeof (a type)
4152 //              ::= sz <expression>                                      # sizeof (an expression)
4153 //              ::= at <type>                                            # alignof (a type)
4154 //              ::= az <expression>                                      # alignof (an expression)
4155 //              ::= nx <expression>                                      # noexcept (expression)
4156 //              ::= <template-param>
4157 //              ::= <function-param>
4158 //              ::= dt <expression> <unresolved-name>                    # expr.name
4159 //              ::= pt <expression> <unresolved-name>                    # expr->name
4160 //              ::= ds <expression> <expression>                         # expr.*expr
4161 //              ::= sZ <template-param>                                  # size of a parameter pack
4162 //              ::= sZ <function-param>                                  # size of a function parameter pack
4163 //              ::= sP <template-arg>* E                                 # sizeof...(T), size of a captured template parameter pack from an alias template
4164 //              ::= sp <expression>                                      # pack expansion
4165 //              ::= tw <expression>                                      # throw expression
4166 //              ::= tr                                                   # throw with no operand (rethrow)
4167 //              ::= <unresolved-name>                                    # f(p), N::f(p), ::f(p),
4168 //                                                                       # freestanding dependent name (e.g., T::x),
4169 //                                                                       # objectless nonstatic member reference
4170 //              ::= fL <binary-operator-name> <expression> <expression>
4171 //              ::= fR <binary-operator-name> <expression> <expression>
4172 //              ::= fl <binary-operator-name> <expression>
4173 //              ::= fr <binary-operator-name> <expression>
4174 //              ::= <expr-primary>
4175 template <typename Derived, typename Alloc>
parseExpr()4176 Node *AbstractManglingParser<Derived, Alloc>::parseExpr() {
4177   bool Global = consumeIf("gs");
4178   if (numLeft() < 2)
4179     return nullptr;
4180 
4181   switch (*First) {
4182   case 'L':
4183     return getDerived().parseExprPrimary();
4184   case 'T':
4185     return getDerived().parseTemplateParam();
4186   case 'f': {
4187     // Disambiguate a fold expression from a <function-param>.
4188     if (look(1) == 'p' || (look(1) == 'L' && std::isdigit(look(2))))
4189       return getDerived().parseFunctionParam();
4190     return getDerived().parseFoldExpr();
4191   }
4192   case 'a':
4193     switch (First[1]) {
4194     case 'a':
4195       First += 2;
4196       return getDerived().parseBinaryExpr("&&");
4197     case 'd':
4198       First += 2;
4199       return getDerived().parsePrefixExpr("&");
4200     case 'n':
4201       First += 2;
4202       return getDerived().parseBinaryExpr("&");
4203     case 'N':
4204       First += 2;
4205       return getDerived().parseBinaryExpr("&=");
4206     case 'S':
4207       First += 2;
4208       return getDerived().parseBinaryExpr("=");
4209     case 't': {
4210       First += 2;
4211       Node *Ty = getDerived().parseType();
4212       if (Ty == nullptr)
4213         return nullptr;
4214       return make<EnclosingExpr>("alignof (", Ty, ")");
4215     }
4216     case 'z': {
4217       First += 2;
4218       Node *Ty = getDerived().parseExpr();
4219       if (Ty == nullptr)
4220         return nullptr;
4221       return make<EnclosingExpr>("alignof (", Ty, ")");
4222     }
4223     }
4224     return nullptr;
4225   case 'c':
4226     switch (First[1]) {
4227     // cc <type> <expression>                               # const_cast<type>(expression)
4228     case 'c': {
4229       First += 2;
4230       Node *Ty = getDerived().parseType();
4231       if (Ty == nullptr)
4232         return Ty;
4233       Node *Ex = getDerived().parseExpr();
4234       if (Ex == nullptr)
4235         return Ex;
4236       return make<CastExpr>("const_cast", Ty, Ex);
4237     }
4238     // cl <expression>+ E                                   # call
4239     case 'l': {
4240       First += 2;
4241       Node *Callee = getDerived().parseExpr();
4242       if (Callee == nullptr)
4243         return Callee;
4244       size_t ExprsBegin = Names.size();
4245       while (!consumeIf('E')) {
4246         Node *E = getDerived().parseExpr();
4247         if (E == nullptr)
4248           return E;
4249         Names.push_back(E);
4250       }
4251       return make<CallExpr>(Callee, popTrailingNodeArray(ExprsBegin));
4252     }
4253     case 'm':
4254       First += 2;
4255       return getDerived().parseBinaryExpr(",");
4256     case 'o':
4257       First += 2;
4258       return getDerived().parsePrefixExpr("~");
4259     case 'v':
4260       return getDerived().parseConversionExpr();
4261     }
4262     return nullptr;
4263   case 'd':
4264     switch (First[1]) {
4265     case 'a': {
4266       First += 2;
4267       Node *Ex = getDerived().parseExpr();
4268       if (Ex == nullptr)
4269         return Ex;
4270       return make<DeleteExpr>(Ex, Global, /*is_array=*/true);
4271     }
4272     case 'c': {
4273       First += 2;
4274       Node *T = getDerived().parseType();
4275       if (T == nullptr)
4276         return T;
4277       Node *Ex = getDerived().parseExpr();
4278       if (Ex == nullptr)
4279         return Ex;
4280       return make<CastExpr>("dynamic_cast", T, Ex);
4281     }
4282     case 'e':
4283       First += 2;
4284       return getDerived().parsePrefixExpr("*");
4285     case 'l': {
4286       First += 2;
4287       Node *E = getDerived().parseExpr();
4288       if (E == nullptr)
4289         return E;
4290       return make<DeleteExpr>(E, Global, /*is_array=*/false);
4291     }
4292     case 'n':
4293       return getDerived().parseUnresolvedName();
4294     case 's': {
4295       First += 2;
4296       Node *LHS = getDerived().parseExpr();
4297       if (LHS == nullptr)
4298         return nullptr;
4299       Node *RHS = getDerived().parseExpr();
4300       if (RHS == nullptr)
4301         return nullptr;
4302       return make<MemberExpr>(LHS, ".*", RHS);
4303     }
4304     case 't': {
4305       First += 2;
4306       Node *LHS = getDerived().parseExpr();
4307       if (LHS == nullptr)
4308         return LHS;
4309       Node *RHS = getDerived().parseExpr();
4310       if (RHS == nullptr)
4311         return nullptr;
4312       return make<MemberExpr>(LHS, ".", RHS);
4313     }
4314     case 'v':
4315       First += 2;
4316       return getDerived().parseBinaryExpr("/");
4317     case 'V':
4318       First += 2;
4319       return getDerived().parseBinaryExpr("/=");
4320     }
4321     return nullptr;
4322   case 'e':
4323     switch (First[1]) {
4324     case 'o':
4325       First += 2;
4326       return getDerived().parseBinaryExpr("^");
4327     case 'O':
4328       First += 2;
4329       return getDerived().parseBinaryExpr("^=");
4330     case 'q':
4331       First += 2;
4332       return getDerived().parseBinaryExpr("==");
4333     }
4334     return nullptr;
4335   case 'g':
4336     switch (First[1]) {
4337     case 'e':
4338       First += 2;
4339       return getDerived().parseBinaryExpr(">=");
4340     case 't':
4341       First += 2;
4342       return getDerived().parseBinaryExpr(">");
4343     }
4344     return nullptr;
4345   case 'i':
4346     switch (First[1]) {
4347     case 'x': {
4348       First += 2;
4349       Node *Base = getDerived().parseExpr();
4350       if (Base == nullptr)
4351         return nullptr;
4352       Node *Index = getDerived().parseExpr();
4353       if (Index == nullptr)
4354         return Index;
4355       return make<ArraySubscriptExpr>(Base, Index);
4356     }
4357     case 'l': {
4358       First += 2;
4359       size_t InitsBegin = Names.size();
4360       while (!consumeIf('E')) {
4361         Node *E = getDerived().parseBracedExpr();
4362         if (E == nullptr)
4363           return nullptr;
4364         Names.push_back(E);
4365       }
4366       return make<InitListExpr>(nullptr, popTrailingNodeArray(InitsBegin));
4367     }
4368     }
4369     return nullptr;
4370   case 'l':
4371     switch (First[1]) {
4372     case 'e':
4373       First += 2;
4374       return getDerived().parseBinaryExpr("<=");
4375     case 's':
4376       First += 2;
4377       return getDerived().parseBinaryExpr("<<");
4378     case 'S':
4379       First += 2;
4380       return getDerived().parseBinaryExpr("<<=");
4381     case 't':
4382       First += 2;
4383       return getDerived().parseBinaryExpr("<");
4384     }
4385     return nullptr;
4386   case 'm':
4387     switch (First[1]) {
4388     case 'i':
4389       First += 2;
4390       return getDerived().parseBinaryExpr("-");
4391     case 'I':
4392       First += 2;
4393       return getDerived().parseBinaryExpr("-=");
4394     case 'l':
4395       First += 2;
4396       return getDerived().parseBinaryExpr("*");
4397     case 'L':
4398       First += 2;
4399       return getDerived().parseBinaryExpr("*=");
4400     case 'm':
4401       First += 2;
4402       if (consumeIf('_'))
4403         return getDerived().parsePrefixExpr("--");
4404       Node *Ex = getDerived().parseExpr();
4405       if (Ex == nullptr)
4406         return nullptr;
4407       return make<PostfixExpr>(Ex, "--");
4408     }
4409     return nullptr;
4410   case 'n':
4411     switch (First[1]) {
4412     case 'a':
4413     case 'w':
4414       return getDerived().parseNewExpr();
4415     case 'e':
4416       First += 2;
4417       return getDerived().parseBinaryExpr("!=");
4418     case 'g':
4419       First += 2;
4420       return getDerived().parsePrefixExpr("-");
4421     case 't':
4422       First += 2;
4423       return getDerived().parsePrefixExpr("!");
4424     case 'x':
4425       First += 2;
4426       Node *Ex = getDerived().parseExpr();
4427       if (Ex == nullptr)
4428         return Ex;
4429       return make<EnclosingExpr>("noexcept (", Ex, ")");
4430     }
4431     return nullptr;
4432   case 'o':
4433     switch (First[1]) {
4434     case 'n':
4435       return getDerived().parseUnresolvedName();
4436     case 'o':
4437       First += 2;
4438       return getDerived().parseBinaryExpr("||");
4439     case 'r':
4440       First += 2;
4441       return getDerived().parseBinaryExpr("|");
4442     case 'R':
4443       First += 2;
4444       return getDerived().parseBinaryExpr("|=");
4445     }
4446     return nullptr;
4447   case 'p':
4448     switch (First[1]) {
4449     case 'm':
4450       First += 2;
4451       return getDerived().parseBinaryExpr("->*");
4452     case 'l':
4453       First += 2;
4454       return getDerived().parseBinaryExpr("+");
4455     case 'L':
4456       First += 2;
4457       return getDerived().parseBinaryExpr("+=");
4458     case 'p': {
4459       First += 2;
4460       if (consumeIf('_'))
4461         return getDerived().parsePrefixExpr("++");
4462       Node *Ex = getDerived().parseExpr();
4463       if (Ex == nullptr)
4464         return Ex;
4465       return make<PostfixExpr>(Ex, "++");
4466     }
4467     case 's':
4468       First += 2;
4469       return getDerived().parsePrefixExpr("+");
4470     case 't': {
4471       First += 2;
4472       Node *L = getDerived().parseExpr();
4473       if (L == nullptr)
4474         return nullptr;
4475       Node *R = getDerived().parseExpr();
4476       if (R == nullptr)
4477         return nullptr;
4478       return make<MemberExpr>(L, "->", R);
4479     }
4480     }
4481     return nullptr;
4482   case 'q':
4483     if (First[1] == 'u') {
4484       First += 2;
4485       Node *Cond = getDerived().parseExpr();
4486       if (Cond == nullptr)
4487         return nullptr;
4488       Node *LHS = getDerived().parseExpr();
4489       if (LHS == nullptr)
4490         return nullptr;
4491       Node *RHS = getDerived().parseExpr();
4492       if (RHS == nullptr)
4493         return nullptr;
4494       return make<ConditionalExpr>(Cond, LHS, RHS);
4495     }
4496     return nullptr;
4497   case 'r':
4498     switch (First[1]) {
4499     case 'c': {
4500       First += 2;
4501       Node *T = getDerived().parseType();
4502       if (T == nullptr)
4503         return T;
4504       Node *Ex = getDerived().parseExpr();
4505       if (Ex == nullptr)
4506         return Ex;
4507       return make<CastExpr>("reinterpret_cast", T, Ex);
4508     }
4509     case 'm':
4510       First += 2;
4511       return getDerived().parseBinaryExpr("%");
4512     case 'M':
4513       First += 2;
4514       return getDerived().parseBinaryExpr("%=");
4515     case 's':
4516       First += 2;
4517       return getDerived().parseBinaryExpr(">>");
4518     case 'S':
4519       First += 2;
4520       return getDerived().parseBinaryExpr(">>=");
4521     }
4522     return nullptr;
4523   case 's':
4524     switch (First[1]) {
4525     case 'c': {
4526       First += 2;
4527       Node *T = getDerived().parseType();
4528       if (T == nullptr)
4529         return T;
4530       Node *Ex = getDerived().parseExpr();
4531       if (Ex == nullptr)
4532         return Ex;
4533       return make<CastExpr>("static_cast", T, Ex);
4534     }
4535     case 'p': {
4536       First += 2;
4537       Node *Child = getDerived().parseExpr();
4538       if (Child == nullptr)
4539         return nullptr;
4540       return make<ParameterPackExpansion>(Child);
4541     }
4542     case 'r':
4543       return getDerived().parseUnresolvedName();
4544     case 't': {
4545       First += 2;
4546       Node *Ty = getDerived().parseType();
4547       if (Ty == nullptr)
4548         return Ty;
4549       return make<EnclosingExpr>("sizeof (", Ty, ")");
4550     }
4551     case 'z': {
4552       First += 2;
4553       Node *Ex = getDerived().parseExpr();
4554       if (Ex == nullptr)
4555         return Ex;
4556       return make<EnclosingExpr>("sizeof (", Ex, ")");
4557     }
4558     case 'Z':
4559       First += 2;
4560       if (look() == 'T') {
4561         Node *R = getDerived().parseTemplateParam();
4562         if (R == nullptr)
4563           return nullptr;
4564         return make<SizeofParamPackExpr>(R);
4565       } else if (look() == 'f') {
4566         Node *FP = getDerived().parseFunctionParam();
4567         if (FP == nullptr)
4568           return nullptr;
4569         return make<EnclosingExpr>("sizeof... (", FP, ")");
4570       }
4571       return nullptr;
4572     case 'P': {
4573       First += 2;
4574       size_t ArgsBegin = Names.size();
4575       while (!consumeIf('E')) {
4576         Node *Arg = getDerived().parseTemplateArg();
4577         if (Arg == nullptr)
4578           return nullptr;
4579         Names.push_back(Arg);
4580       }
4581       auto *Pack = make<NodeArrayNode>(popTrailingNodeArray(ArgsBegin));
4582       if (!Pack)
4583         return nullptr;
4584       return make<EnclosingExpr>("sizeof... (", Pack, ")");
4585     }
4586     }
4587     return nullptr;
4588   case 't':
4589     switch (First[1]) {
4590     case 'e': {
4591       First += 2;
4592       Node *Ex = getDerived().parseExpr();
4593       if (Ex == nullptr)
4594         return Ex;
4595       return make<EnclosingExpr>("typeid (", Ex, ")");
4596     }
4597     case 'i': {
4598       First += 2;
4599       Node *Ty = getDerived().parseType();
4600       if (Ty == nullptr)
4601         return Ty;
4602       return make<EnclosingExpr>("typeid (", Ty, ")");
4603     }
4604     case 'l': {
4605       First += 2;
4606       Node *Ty = getDerived().parseType();
4607       if (Ty == nullptr)
4608         return nullptr;
4609       size_t InitsBegin = Names.size();
4610       while (!consumeIf('E')) {
4611         Node *E = getDerived().parseBracedExpr();
4612         if (E == nullptr)
4613           return nullptr;
4614         Names.push_back(E);
4615       }
4616       return make<InitListExpr>(Ty, popTrailingNodeArray(InitsBegin));
4617     }
4618     case 'r':
4619       First += 2;
4620       return make<NameType>("throw");
4621     case 'w': {
4622       First += 2;
4623       Node *Ex = getDerived().parseExpr();
4624       if (Ex == nullptr)
4625         return nullptr;
4626       return make<ThrowExpr>(Ex);
4627     }
4628     }
4629     return nullptr;
4630   case '1':
4631   case '2':
4632   case '3':
4633   case '4':
4634   case '5':
4635   case '6':
4636   case '7':
4637   case '8':
4638   case '9':
4639     return getDerived().parseUnresolvedName();
4640   }
4641   return nullptr;
4642 }
4643 
4644 // <call-offset> ::= h <nv-offset> _
4645 //               ::= v <v-offset> _
4646 //
4647 // <nv-offset> ::= <offset number>
4648 //               # non-virtual base override
4649 //
4650 // <v-offset>  ::= <offset number> _ <virtual offset number>
4651 //               # virtual base override, with vcall offset
4652 template <typename Alloc, typename Derived>
parseCallOffset()4653 bool AbstractManglingParser<Alloc, Derived>::parseCallOffset() {
4654   // Just scan through the call offset, we never add this information into the
4655   // output.
4656   if (consumeIf('h'))
4657     return parseNumber(true).empty() || !consumeIf('_');
4658   if (consumeIf('v'))
4659     return parseNumber(true).empty() || !consumeIf('_') ||
4660            parseNumber(true).empty() || !consumeIf('_');
4661   return true;
4662 }
4663 
4664 // <special-name> ::= TV <type>    # virtual table
4665 //                ::= TT <type>    # VTT structure (construction vtable index)
4666 //                ::= TI <type>    # typeinfo structure
4667 //                ::= TS <type>    # typeinfo name (null-terminated byte string)
4668 //                ::= Tc <call-offset> <call-offset> <base encoding>
4669 //                    # base is the nominal target function of thunk
4670 //                    # first call-offset is 'this' adjustment
4671 //                    # second call-offset is result adjustment
4672 //                ::= T <call-offset> <base encoding>
4673 //                    # base is the nominal target function of thunk
4674 //                ::= GV <object name> # Guard variable for one-time initialization
4675 //                                     # No <type>
4676 //                ::= TW <object name> # Thread-local wrapper
4677 //                ::= TH <object name> # Thread-local initialization
4678 //                ::= GR <object name> _             # First temporary
4679 //                ::= GR <object name> <seq-id> _    # Subsequent temporaries
4680 //      extension ::= TC <first type> <number> _ <second type> # construction vtable for second-in-first
4681 //      extension ::= GR <object name> # reference temporary for object
4682 template <typename Derived, typename Alloc>
parseSpecialName()4683 Node *AbstractManglingParser<Derived, Alloc>::parseSpecialName() {
4684   switch (look()) {
4685   case 'T':
4686     switch (look(1)) {
4687     // TV <type>    # virtual table
4688     case 'V': {
4689       First += 2;
4690       Node *Ty = getDerived().parseType();
4691       if (Ty == nullptr)
4692         return nullptr;
4693       return make<SpecialName>("vtable for ", Ty);
4694     }
4695     // TT <type>    # VTT structure (construction vtable index)
4696     case 'T': {
4697       First += 2;
4698       Node *Ty = getDerived().parseType();
4699       if (Ty == nullptr)
4700         return nullptr;
4701       return make<SpecialName>("VTT for ", Ty);
4702     }
4703     // TI <type>    # typeinfo structure
4704     case 'I': {
4705       First += 2;
4706       Node *Ty = getDerived().parseType();
4707       if (Ty == nullptr)
4708         return nullptr;
4709       return make<SpecialName>("typeinfo for ", Ty);
4710     }
4711     // TS <type>    # typeinfo name (null-terminated byte string)
4712     case 'S': {
4713       First += 2;
4714       Node *Ty = getDerived().parseType();
4715       if (Ty == nullptr)
4716         return nullptr;
4717       return make<SpecialName>("typeinfo name for ", Ty);
4718     }
4719     // Tc <call-offset> <call-offset> <base encoding>
4720     case 'c': {
4721       First += 2;
4722       if (parseCallOffset() || parseCallOffset())
4723         return nullptr;
4724       Node *Encoding = getDerived().parseEncoding();
4725       if (Encoding == nullptr)
4726         return nullptr;
4727       return make<SpecialName>("covariant return thunk to ", Encoding);
4728     }
4729     // extension ::= TC <first type> <number> _ <second type>
4730     //               # construction vtable for second-in-first
4731     case 'C': {
4732       First += 2;
4733       Node *FirstType = getDerived().parseType();
4734       if (FirstType == nullptr)
4735         return nullptr;
4736       if (parseNumber(true).empty() || !consumeIf('_'))
4737         return nullptr;
4738       Node *SecondType = getDerived().parseType();
4739       if (SecondType == nullptr)
4740         return nullptr;
4741       return make<CtorVtableSpecialName>(SecondType, FirstType);
4742     }
4743     // TW <object name> # Thread-local wrapper
4744     case 'W': {
4745       First += 2;
4746       Node *Name = getDerived().parseName();
4747       if (Name == nullptr)
4748         return nullptr;
4749       return make<SpecialName>("thread-local wrapper routine for ", Name);
4750     }
4751     // TH <object name> # Thread-local initialization
4752     case 'H': {
4753       First += 2;
4754       Node *Name = getDerived().parseName();
4755       if (Name == nullptr)
4756         return nullptr;
4757       return make<SpecialName>("thread-local initialization routine for ", Name);
4758     }
4759     // T <call-offset> <base encoding>
4760     default: {
4761       ++First;
4762       bool IsVirt = look() == 'v';
4763       if (parseCallOffset())
4764         return nullptr;
4765       Node *BaseEncoding = getDerived().parseEncoding();
4766       if (BaseEncoding == nullptr)
4767         return nullptr;
4768       if (IsVirt)
4769         return make<SpecialName>("virtual thunk to ", BaseEncoding);
4770       else
4771         return make<SpecialName>("non-virtual thunk to ", BaseEncoding);
4772     }
4773     }
4774   case 'G':
4775     switch (look(1)) {
4776     // GV <object name> # Guard variable for one-time initialization
4777     case 'V': {
4778       First += 2;
4779       Node *Name = getDerived().parseName();
4780       if (Name == nullptr)
4781         return nullptr;
4782       return make<SpecialName>("guard variable for ", Name);
4783     }
4784     // GR <object name> # reference temporary for object
4785     // GR <object name> _             # First temporary
4786     // GR <object name> <seq-id> _    # Subsequent temporaries
4787     case 'R': {
4788       First += 2;
4789       Node *Name = getDerived().parseName();
4790       if (Name == nullptr)
4791         return nullptr;
4792       size_t Count;
4793       bool ParsedSeqId = !parseSeqId(&Count);
4794       if (!consumeIf('_') && ParsedSeqId)
4795         return nullptr;
4796       return make<SpecialName>("reference temporary for ", Name);
4797     }
4798     }
4799   }
4800   return nullptr;
4801 }
4802 
4803 // <encoding> ::= <function name> <bare-function-type>
4804 //            ::= <data name>
4805 //            ::= <special-name>
4806 template <typename Derived, typename Alloc>
parseEncoding()4807 Node *AbstractManglingParser<Derived, Alloc>::parseEncoding() {
4808   if (look() == 'G' || look() == 'T')
4809     return getDerived().parseSpecialName();
4810 
4811   auto IsEndOfEncoding = [&] {
4812     // The set of chars that can potentially follow an <encoding> (none of which
4813     // can start a <type>). Enumerating these allows us to avoid speculative
4814     // parsing.
4815     return numLeft() == 0 || look() == 'E' || look() == '.' || look() == '_';
4816   };
4817 
4818   NameState NameInfo(this);
4819   Node *Name = getDerived().parseName(&NameInfo);
4820   if (Name == nullptr)
4821     return nullptr;
4822 
4823   if (resolveForwardTemplateRefs(NameInfo))
4824     return nullptr;
4825 
4826   if (IsEndOfEncoding())
4827     return Name;
4828 
4829   Node *Attrs = nullptr;
4830   if (consumeIf("Ua9enable_ifI")) {
4831     size_t BeforeArgs = Names.size();
4832     while (!consumeIf('E')) {
4833       Node *Arg = getDerived().parseTemplateArg();
4834       if (Arg == nullptr)
4835         return nullptr;
4836       Names.push_back(Arg);
4837     }
4838     Attrs = make<EnableIfAttr>(popTrailingNodeArray(BeforeArgs));
4839     if (!Attrs)
4840       return nullptr;
4841   }
4842 
4843   Node *ReturnType = nullptr;
4844   if (!NameInfo.CtorDtorConversion && NameInfo.EndsWithTemplateArgs) {
4845     ReturnType = getDerived().parseType();
4846     if (ReturnType == nullptr)
4847       return nullptr;
4848   }
4849 
4850   if (consumeIf('v'))
4851     return make<FunctionEncoding>(ReturnType, Name, NodeArray(),
4852                                   Attrs, NameInfo.CVQualifiers,
4853                                   NameInfo.ReferenceQualifier);
4854 
4855   size_t ParamsBegin = Names.size();
4856   do {
4857     Node *Ty = getDerived().parseType();
4858     if (Ty == nullptr)
4859       return nullptr;
4860     Names.push_back(Ty);
4861   } while (!IsEndOfEncoding());
4862 
4863   return make<FunctionEncoding>(ReturnType, Name,
4864                                 popTrailingNodeArray(ParamsBegin),
4865                                 Attrs, NameInfo.CVQualifiers,
4866                                 NameInfo.ReferenceQualifier);
4867 }
4868 
4869 template <class Float>
4870 struct FloatData;
4871 
4872 template <>
4873 struct FloatData<float>
4874 {
4875     static const size_t mangled_size = 8;
4876     static const size_t max_demangled_size = 24;
4877     static constexpr const char* spec = "%af";
4878 };
4879 
4880 template <>
4881 struct FloatData<double>
4882 {
4883     static const size_t mangled_size = 16;
4884     static const size_t max_demangled_size = 32;
4885     static constexpr const char* spec = "%a";
4886 };
4887 
4888 template <>
4889 struct FloatData<long double>
4890 {
4891 #if defined(__mips__) && defined(__mips_n64) || defined(__aarch64__) || \
4892     defined(__wasm__)
4893     static const size_t mangled_size = 32;
4894 #elif defined(__arm__) || defined(__mips__) || defined(__hexagon__)
4895     static const size_t mangled_size = 16;
4896 #else
4897     static const size_t mangled_size = 20;  // May need to be adjusted to 16 or 24 on other platforms
4898 #endif
4899     static const size_t max_demangled_size = 41;
4900     static constexpr const char *spec = "%LaL";
4901 };
4902 
4903 template <typename Alloc, typename Derived>
4904 template <class Float>
4905 Node *AbstractManglingParser<Alloc, Derived>::parseFloatingLiteral() {
4906   const size_t N = FloatData<Float>::mangled_size;
4907   if (numLeft() <= N)
4908     return nullptr;
4909   StringView Data(First, First + N);
4910   for (char C : Data)
4911     if (!std::isxdigit(C))
4912       return nullptr;
4913   First += N;
4914   if (!consumeIf('E'))
4915     return nullptr;
4916   return make<FloatLiteralImpl<Float>>(Data);
4917 }
4918 
4919 // <seq-id> ::= <0-9A-Z>+
4920 template <typename Alloc, typename Derived>
4921 bool AbstractManglingParser<Alloc, Derived>::parseSeqId(size_t *Out) {
4922   if (!(look() >= '0' && look() <= '9') &&
4923       !(look() >= 'A' && look() <= 'Z'))
4924     return true;
4925 
4926   size_t Id = 0;
4927   while (true) {
4928     if (look() >= '0' && look() <= '9') {
4929       Id *= 36;
4930       Id += static_cast<size_t>(look() - '0');
4931     } else if (look() >= 'A' && look() <= 'Z') {
4932       Id *= 36;
4933       Id += static_cast<size_t>(look() - 'A') + 10;
4934     } else {
4935       *Out = Id;
4936       return false;
4937     }
4938     ++First;
4939   }
4940 }
4941 
4942 // <substitution> ::= S <seq-id> _
4943 //                ::= S_
4944 // <substitution> ::= Sa # ::std::allocator
4945 // <substitution> ::= Sb # ::std::basic_string
4946 // <substitution> ::= Ss # ::std::basic_string < char,
4947 //                                               ::std::char_traits<char>,
4948 //                                               ::std::allocator<char> >
4949 // <substitution> ::= Si # ::std::basic_istream<char,  std::char_traits<char> >
4950 // <substitution> ::= So # ::std::basic_ostream<char,  std::char_traits<char> >
4951 // <substitution> ::= Sd # ::std::basic_iostream<char, std::char_traits<char> >
4952 template <typename Derived, typename Alloc>
4953 Node *AbstractManglingParser<Derived, Alloc>::parseSubstitution() {
4954   if (!consumeIf('S'))
4955     return nullptr;
4956 
4957   if (std::islower(look())) {
4958     Node *SpecialSub;
4959     switch (look()) {
4960     case 'a':
4961       ++First;
4962       SpecialSub = make<SpecialSubstitution>(SpecialSubKind::allocator);
4963       break;
4964     case 'b':
4965       ++First;
4966       SpecialSub = make<SpecialSubstitution>(SpecialSubKind::basic_string);
4967       break;
4968     case 's':
4969       ++First;
4970       SpecialSub = make<SpecialSubstitution>(SpecialSubKind::string);
4971       break;
4972     case 'i':
4973       ++First;
4974       SpecialSub = make<SpecialSubstitution>(SpecialSubKind::istream);
4975       break;
4976     case 'o':
4977       ++First;
4978       SpecialSub = make<SpecialSubstitution>(SpecialSubKind::ostream);
4979       break;
4980     case 'd':
4981       ++First;
4982       SpecialSub = make<SpecialSubstitution>(SpecialSubKind::iostream);
4983       break;
4984     default:
4985       return nullptr;
4986     }
4987     if (!SpecialSub)
4988       return nullptr;
4989     // Itanium C++ ABI 5.1.2: If a name that would use a built-in <substitution>
4990     // has ABI tags, the tags are appended to the substitution; the result is a
4991     // substitutable component.
4992     Node *WithTags = getDerived().parseAbiTags(SpecialSub);
4993     if (WithTags != SpecialSub) {
4994       Subs.push_back(WithTags);
4995       SpecialSub = WithTags;
4996     }
4997     return SpecialSub;
4998   }
4999 
5000   //                ::= S_
5001   if (consumeIf('_')) {
5002     if (Subs.empty())
5003       return nullptr;
5004     return Subs[0];
5005   }
5006 
5007   //                ::= S <seq-id> _
5008   size_t Index = 0;
5009   if (parseSeqId(&Index))
5010     return nullptr;
5011   ++Index;
5012   if (!consumeIf('_') || Index >= Subs.size())
5013     return nullptr;
5014   return Subs[Index];
5015 }
5016 
5017 // <template-param> ::= T_    # first template parameter
5018 //                  ::= T <parameter-2 non-negative number> _
5019 template <typename Derived, typename Alloc>
5020 Node *AbstractManglingParser<Derived, Alloc>::parseTemplateParam() {
5021   if (!consumeIf('T'))
5022     return nullptr;
5023 
5024   size_t Index = 0;
5025   if (!consumeIf('_')) {
5026     if (parsePositiveInteger(&Index))
5027       return nullptr;
5028     ++Index;
5029     if (!consumeIf('_'))
5030       return nullptr;
5031   }
5032 
5033   // Itanium ABI 5.1.8: In a generic lambda, uses of auto in the parameter list
5034   // are mangled as the corresponding artificial template type parameter.
5035   if (ParsingLambdaParams)
5036     return make<NameType>("auto");
5037 
5038   // If we're in a context where this <template-param> refers to a
5039   // <template-arg> further ahead in the mangled name (currently just conversion
5040   // operator types), then we should only look it up in the right context.
5041   if (PermitForwardTemplateReferences) {
5042     Node *ForwardRef = make<ForwardTemplateReference>(Index);
5043     if (!ForwardRef)
5044       return nullptr;
5045     assert(ForwardRef->getKind() == Node::KForwardTemplateReference);
5046     ForwardTemplateRefs.push_back(
5047         static_cast<ForwardTemplateReference *>(ForwardRef));
5048     return ForwardRef;
5049   }
5050 
5051   if (Index >= TemplateParams.size())
5052     return nullptr;
5053   return TemplateParams[Index];
5054 }
5055 
5056 // <template-arg> ::= <type>                    # type or template
5057 //                ::= X <expression> E          # expression
5058 //                ::= <expr-primary>            # simple expressions
5059 //                ::= J <template-arg>* E       # argument pack
5060 //                ::= LZ <encoding> E           # extension
5061 template <typename Derived, typename Alloc>
5062 Node *AbstractManglingParser<Derived, Alloc>::parseTemplateArg() {
5063   switch (look()) {
5064   case 'X': {
5065     ++First;
5066     Node *Arg = getDerived().parseExpr();
5067     if (Arg == nullptr || !consumeIf('E'))
5068       return nullptr;
5069     return Arg;
5070   }
5071   case 'J': {
5072     ++First;
5073     size_t ArgsBegin = Names.size();
5074     while (!consumeIf('E')) {
5075       Node *Arg = getDerived().parseTemplateArg();
5076       if (Arg == nullptr)
5077         return nullptr;
5078       Names.push_back(Arg);
5079     }
5080     NodeArray Args = popTrailingNodeArray(ArgsBegin);
5081     return make<TemplateArgumentPack>(Args);
5082   }
5083   case 'L': {
5084     //                ::= LZ <encoding> E           # extension
5085     if (look(1) == 'Z') {
5086       First += 2;
5087       Node *Arg = getDerived().parseEncoding();
5088       if (Arg == nullptr || !consumeIf('E'))
5089         return nullptr;
5090       return Arg;
5091     }
5092     //                ::= <expr-primary>            # simple expressions
5093     return getDerived().parseExprPrimary();
5094   }
5095   default:
5096     return getDerived().parseType();
5097   }
5098 }
5099 
5100 // <template-args> ::= I <template-arg>* E
5101 //     extension, the abi says <template-arg>+
5102 template <typename Derived, typename Alloc>
5103 Node *
5104 AbstractManglingParser<Derived, Alloc>::parseTemplateArgs(bool TagTemplates) {
5105   if (!consumeIf('I'))
5106     return nullptr;
5107 
5108   // <template-params> refer to the innermost <template-args>. Clear out any
5109   // outer args that we may have inserted into TemplateParams.
5110   if (TagTemplates)
5111     TemplateParams.clear();
5112 
5113   size_t ArgsBegin = Names.size();
5114   while (!consumeIf('E')) {
5115     if (TagTemplates) {
5116       auto OldParams = std::move(TemplateParams);
5117       Node *Arg = getDerived().parseTemplateArg();
5118       TemplateParams = std::move(OldParams);
5119       if (Arg == nullptr)
5120         return nullptr;
5121       Names.push_back(Arg);
5122       Node *TableEntry = Arg;
5123       if (Arg->getKind() == Node::KTemplateArgumentPack) {
5124         TableEntry = make<ParameterPack>(
5125             static_cast<TemplateArgumentPack*>(TableEntry)->getElements());
5126         if (!TableEntry)
5127           return nullptr;
5128       }
5129       TemplateParams.push_back(TableEntry);
5130     } else {
5131       Node *Arg = getDerived().parseTemplateArg();
5132       if (Arg == nullptr)
5133         return nullptr;
5134       Names.push_back(Arg);
5135     }
5136   }
5137   return make<TemplateArgs>(popTrailingNodeArray(ArgsBegin));
5138 }
5139 
5140 // <mangled-name> ::= _Z <encoding>
5141 //                ::= <type>
5142 // extension      ::= ___Z <encoding> _block_invoke
5143 // extension      ::= ___Z <encoding> _block_invoke<decimal-digit>+
5144 // extension      ::= ___Z <encoding> _block_invoke_<decimal-digit>+
5145 template <typename Derived, typename Alloc>
5146 Node *AbstractManglingParser<Derived, Alloc>::parse() {
5147   if (consumeIf("_Z")) {
5148     Node *Encoding = getDerived().parseEncoding();
5149     if (Encoding == nullptr)
5150       return nullptr;
5151     if (look() == '.') {
5152       Encoding = make<DotSuffix>(Encoding, StringView(First, Last));
5153       First = Last;
5154     }
5155     if (numLeft() != 0)
5156       return nullptr;
5157     return Encoding;
5158   }
5159 
5160   if (consumeIf("___Z")) {
5161     Node *Encoding = getDerived().parseEncoding();
5162     if (Encoding == nullptr || !consumeIf("_block_invoke"))
5163       return nullptr;
5164     bool RequireNumber = consumeIf('_');
5165     if (parseNumber().empty() && RequireNumber)
5166       return nullptr;
5167     if (look() == '.')
5168       First = Last;
5169     if (numLeft() != 0)
5170       return nullptr;
5171     return make<SpecialName>("invocation function for block in ", Encoding);
5172   }
5173 
5174   Node *Ty = getDerived().parseType();
5175   if (numLeft() != 0)
5176     return nullptr;
5177   return Ty;
5178 }
5179 
5180 template <typename Alloc>
5181 struct ManglingParser : AbstractManglingParser<ManglingParser<Alloc>, Alloc> {
5182   using AbstractManglingParser<ManglingParser<Alloc>,
5183                                Alloc>::AbstractManglingParser;
5184 };
5185 
5186 }  // namespace itanium_demangle
5187 }  // namespace
5188 
5189 #endif // LIBCXX_DEMANGLE_ITANIUMDEMANGLE_H
5190