LCOV - code coverage report
Current view: top level - include/llvm/Demangle - ItaniumDemangle.h (source / functions) Hit Total Coverage
Test: llvm-toolchain.info Lines: 1066 3431 31.1 %
Date: 2018-10-20 13:21:21 Functions: 121 519 23.3 %
Legend: Lines: hit not hit

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

Generated by: LCOV version 1.13