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