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