blob: 901db66b270045110a8bd4f0a9570e672e7ffea0 [file] [log] [blame]
Howard Hinnantd213ffd2011-05-05 15:27:28 +00001//===-------------------------- cxa_demangle.cpp --------------------------===//
2//
3// The LLVM Compiler Infrastructure
4//
5// This file is dual licensed under the MIT and the University of Illinois Open
6// Source Licenses. See LICENSE.TXT for details.
7//
8//===----------------------------------------------------------------------===//
9
Erik Pilkington1c300b92017-11-21 15:04:08 +000010// FIXME: (possibly) incomplete list of features that clang mangles that this
11// file does not yet support:
Erik Pilkington1c300b92017-11-21 15:04:08 +000012// - C++ modules TS
13
Howard Hinnant6c33e762013-06-17 18:10:34 +000014#define _LIBCPP_NO_EXCEPTIONS
Howard Hinnantd213ffd2011-05-05 15:27:28 +000015
Saleem Abdulrasoolb4ec5792015-12-04 02:14:58 +000016#include "__cxxabi_config.h"
17
Howard Hinnant6c33e762013-06-17 18:10:34 +000018#include <vector>
Howard Hinnantd213ffd2011-05-05 15:27:28 +000019#include <algorithm>
Howard Hinnant6c33e762013-06-17 18:10:34 +000020#include <numeric>
Erik Pilkington761e6b02018-01-31 20:17:06 +000021#include <cassert>
Erik Pilkington77101542017-07-28 00:53:30 +000022#include <cstdio>
Howard Hinnant6c33e762013-06-17 18:10:34 +000023#include <cstdlib>
24#include <cstring>
25#include <cctype>
Howard Hinnantd213ffd2011-05-05 15:27:28 +000026
Nico Weberb4c998b2015-09-20 18:10:46 +000027#ifdef _MSC_VER
28// snprintf is implemented in VS 2015
29#if _MSC_VER < 1900
30#define snprintf _snprintf_s
31#endif
32#endif
33
Erik Pilkington761e6b02018-01-31 20:17:06 +000034#ifndef NDEBUG
35#if __has_attribute(noinline) && __has_attribute(used)
36#define DUMP_METHOD __attribute__((noinline,used))
37#else
38#define DUMP_METHOD
39#endif
40#endif
Howard Hinnantd213ffd2011-05-05 15:27:28 +000041
Erik Pilkington761e6b02018-01-31 20:17:06 +000042namespace {
Howard Hinnantd213ffd2011-05-05 15:27:28 +000043
Erik Pilkington0024acd2017-07-28 00:43:49 +000044class StringView {
45 const char *First;
46 const char *Last;
47
48public:
49 template <size_t N>
50 StringView(const char (&Str)[N]) : First(Str), Last(Str + N - 1) {}
Erik Pilkington7de232a2017-08-10 02:48:13 +000051 StringView(const char *First_, const char *Last_) : First(First_), Last(Last_) {}
Erik Pilkington0024acd2017-07-28 00:43:49 +000052 StringView() : First(nullptr), Last(nullptr) {}
53
54 StringView substr(size_t From, size_t To) {
55 if (To >= size())
56 To = size() - 1;
57 if (From >= size())
58 From = size() - 1;
59 return StringView(First + From, First + To);
60 }
61
62 StringView dropFront(size_t N) const {
63 if (N >= size())
64 N = size() - 1;
65 return StringView(First + N, Last);
66 }
67
68 bool startsWith(StringView Str) const {
69 if (Str.size() > size())
70 return false;
71 return std::equal(Str.begin(), Str.end(), begin());
72 }
73
74 const char &operator[](size_t Idx) const { return *(begin() + Idx); }
75
76 const char *begin() const { return First; }
77 const char *end() const { return Last; }
78 size_t size() const { return static_cast<size_t>(Last - First); }
Erik Pilkington761e6b02018-01-31 20:17:06 +000079 bool empty() const { return First == Last; }
Erik Pilkington0024acd2017-07-28 00:43:49 +000080};
81
82bool operator==(const StringView &LHS, const StringView &RHS) {
83 return LHS.size() == RHS.size() &&
84 std::equal(LHS.begin(), LHS.end(), RHS.begin());
85}
86
87// Stream that AST nodes write their string representation into after the AST
88// has been parsed.
89class OutputStream {
90 char *Buffer;
91 size_t CurrentPosition;
92 size_t BufferCapacity;
93
94 // Ensure there is at least n more positions in buffer.
95 void grow(size_t N) {
96 if (N + CurrentPosition >= BufferCapacity) {
97 BufferCapacity *= 2;
98 if (BufferCapacity < N + CurrentPosition)
99 BufferCapacity = N + CurrentPosition;
100 Buffer = static_cast<char *>(std::realloc(Buffer, BufferCapacity));
101 }
102 }
103
104public:
105 OutputStream(char *StartBuf, size_t Size)
106 : Buffer(StartBuf), CurrentPosition(0), BufferCapacity(Size) {}
Erik Pilkington0df654b2018-04-12 20:41:06 +0000107 OutputStream() = default;
108 void reset(char *Buffer_, size_t BufferCapacity_) {
109 CurrentPosition = 0;
110 Buffer = Buffer_;
111 BufferCapacity = BufferCapacity_;
112 }
Erik Pilkington0024acd2017-07-28 00:43:49 +0000113
Erik Pilkington761e6b02018-01-31 20:17:06 +0000114 /// If a ParameterPackExpansion (or similar type) is encountered, the offset
115 /// into the pack that we're currently printing.
116 unsigned CurrentPackIndex = std::numeric_limits<unsigned>::max();
Erik Pilkington85619f52018-03-25 22:49:57 +0000117 unsigned CurrentPackMax = std::numeric_limits<unsigned>::max();
Erik Pilkington761e6b02018-01-31 20:17:06 +0000118
Erik Pilkington0024acd2017-07-28 00:43:49 +0000119 OutputStream &operator+=(StringView R) {
120 size_t Size = R.size();
121 if (Size == 0)
122 return *this;
123 grow(Size);
124 memmove(Buffer + CurrentPosition, R.begin(), Size);
125 CurrentPosition += Size;
126 return *this;
127 }
128
129 OutputStream &operator+=(char C) {
130 grow(1);
131 Buffer[CurrentPosition++] = C;
132 return *this;
133 }
134
Erik Pilkington85619f52018-03-25 22:49:57 +0000135 size_t getCurrentPosition() const { return CurrentPosition; }
136 void setCurrentPosition(size_t NewPos) { CurrentPosition = NewPos; }
Erik Pilkington0024acd2017-07-28 00:43:49 +0000137
138 char back() const {
139 return CurrentPosition ? Buffer[CurrentPosition - 1] : '\0';
140 }
141
142 bool empty() const { return CurrentPosition == 0; }
143
144 char *getBuffer() { return Buffer; }
145 char *getBufferEnd() { return Buffer + CurrentPosition - 1; }
146 size_t getBufferCapacity() { return BufferCapacity; }
147};
148
Erik Pilkington761e6b02018-01-31 20:17:06 +0000149template <class T>
150class SwapAndRestore {
151 T &Restore;
152 T OriginalValue;
153public:
154 SwapAndRestore(T& Restore_, T NewVal)
155 : Restore(Restore_), OriginalValue(Restore) {
156 Restore = std::move(NewVal);
157 }
158 ~SwapAndRestore() { Restore = std::move(OriginalValue); }
159
160 SwapAndRestore(const SwapAndRestore &) = delete;
161 SwapAndRestore &operator=(const SwapAndRestore &) = delete;
162};
163
Erik Pilkington0024acd2017-07-28 00:43:49 +0000164// Base class of all AST nodes. The AST is built by the parser, then is
165// traversed by the printLeft/Right functions to produce a demangled string.
166class Node {
167public:
168 enum Kind : unsigned char {
Erik Pilkington6a4e62b2018-04-09 18:31:50 +0000169 KNodeArrayNode,
Erik Pilkington0024acd2017-07-28 00:43:49 +0000170 KDotSuffix,
171 KVendorExtQualType,
172 KQualType,
173 KConversionOperatorType,
174 KPostfixQualifiedType,
Erik Pilkington13fb7dc2018-02-13 00:15:53 +0000175 KElaboratedTypeSpefType,
Erik Pilkington0024acd2017-07-28 00:43:49 +0000176 KNameType,
Erik Pilkington5bff4122017-11-22 20:38:22 +0000177 KAbiTagAttr,
Erik Pilkingtonbb80c5c2018-03-25 22:49:16 +0000178 KEnableIfAttr,
Erik Pilkington0024acd2017-07-28 00:43:49 +0000179 KObjCProtoName,
180 KPointerType,
181 KLValueReferenceType,
182 KRValueReferenceType,
183 KPointerToMemberType,
184 KArrayType,
185 KFunctionType,
Erik Pilkington7e027ac2018-02-14 01:08:20 +0000186 KNoexceptSpec,
187 KDynamicExceptionSpec,
Erik Pilkington761e6b02018-01-31 20:17:06 +0000188 KFunctionEncoding,
Erik Pilkington0024acd2017-07-28 00:43:49 +0000189 KLiteralOperator,
190 KSpecialName,
191 KCtorVtableSpecialName,
192 KQualifiedName,
Erik Pilkington0df654b2018-04-12 20:41:06 +0000193 KNestedName,
194 KLocalName,
Erik Pilkington0024acd2017-07-28 00:43:49 +0000195 KVectorType,
Erik Pilkington761e6b02018-01-31 20:17:06 +0000196 KParameterPack,
197 KTemplateArgumentPack,
198 KParameterPackExpansion,
199 KTemplateArgs,
Erik Pilkington04f39852018-03-25 22:50:33 +0000200 KForwardTemplateReference,
Erik Pilkington0024acd2017-07-28 00:43:49 +0000201 KNameWithTemplateArgs,
202 KGlobalQualifiedName,
203 KStdQualifiedName,
204 KExpandedSpecialSubstitution,
205 KSpecialSubstitution,
206 KCtorDtorName,
207 KDtorName,
208 KUnnamedTypeName,
Erik Pilkingtone1d61622018-03-05 16:35:06 +0000209 KClosureTypeName,
Erik Pilkingtondee4d0b2018-03-10 21:31:15 +0000210 KStructuredBindingName,
Erik Pilkington0024acd2017-07-28 00:43:49 +0000211 KExpr,
Erik Pilkington88a1cf62018-02-13 00:15:56 +0000212 KBracedExpr,
213 KBracedRangeExpr,
Erik Pilkington0024acd2017-07-28 00:43:49 +0000214 };
215
Erik Pilkington761e6b02018-01-31 20:17:06 +0000216 Kind K;
Erik Pilkington0024acd2017-07-28 00:43:49 +0000217
Erik Pilkington761e6b02018-01-31 20:17:06 +0000218 /// Three-way bool to track a cached value. Unknown is possible if this node
219 /// has an unexpanded parameter pack below it that may affect this cache.
220 enum class Cache : unsigned char { Yes, No, Unknown, };
Erik Pilkington0024acd2017-07-28 00:43:49 +0000221
Erik Pilkington761e6b02018-01-31 20:17:06 +0000222 /// Tracks if this node has a component on its right side, in which case we
223 /// need to call printRight.
224 Cache RHSComponentCache;
Erik Pilkington0024acd2017-07-28 00:43:49 +0000225
Erik Pilkington761e6b02018-01-31 20:17:06 +0000226 /// Track if this node is a (possibly qualified) array type. This can affect
227 /// how we format the output string.
228 Cache ArrayCache;
229
230 /// Track if this node is a (possibly qualified) function type. This can
231 /// affect how we format the output string.
232 Cache FunctionCache;
233
Erik Pilkington85619f52018-03-25 22:49:57 +0000234 Node(Kind K_, Cache RHSComponentCache_ = Cache::No,
235 Cache ArrayCache_ = Cache::No, Cache FunctionCache_ = Cache::No)
236 : K(K_), RHSComponentCache(RHSComponentCache_), ArrayCache(ArrayCache_),
Erik Pilkington761e6b02018-01-31 20:17:06 +0000237 FunctionCache(FunctionCache_) {}
238
Erik Pilkington761e6b02018-01-31 20:17:06 +0000239 bool hasRHSComponent(OutputStream &S) const {
240 if (RHSComponentCache != Cache::Unknown)
241 return RHSComponentCache == Cache::Yes;
242 return hasRHSComponentSlow(S);
243 }
244
245 bool hasArray(OutputStream &S) const {
246 if (ArrayCache != Cache::Unknown)
247 return ArrayCache == Cache::Yes;
248 return hasArraySlow(S);
249 }
250
251 bool hasFunction(OutputStream &S) const {
252 if (FunctionCache != Cache::Unknown)
253 return FunctionCache == Cache::Yes;
254 return hasFunctionSlow(S);
255 }
256
257 Kind getKind() const { return K; }
258
259 virtual bool hasRHSComponentSlow(OutputStream &) const { return false; }
260 virtual bool hasArraySlow(OutputStream &) const { return false; }
261 virtual bool hasFunctionSlow(OutputStream &) const { return false; }
262
Erik Pilkington761e6b02018-01-31 20:17:06 +0000263 void print(OutputStream &S) const {
264 printLeft(S);
265 if (RHSComponentCache != Cache::No)
266 printRight(S);
Erik Pilkington0024acd2017-07-28 00:43:49 +0000267 }
268
269 // Print the "left" side of this Node into OutputStream.
270 virtual void printLeft(OutputStream &) const = 0;
271
272 // Print the "right". This distinction is necessary to represent C++ types
273 // that appear on the RHS of their subtype, such as arrays or functions.
274 // Since most types don't have such a component, provide a default
275 // implemenation.
276 virtual void printRight(OutputStream &) const {}
277
278 virtual StringView getBaseName() const { return StringView(); }
279
280 // Silence compiler warnings, this dtor will never be called.
281 virtual ~Node() = default;
Erik Pilkington761e6b02018-01-31 20:17:06 +0000282
283#ifndef NDEBUG
284 DUMP_METHOD void dump() const {
285 char *Buffer = static_cast<char*>(std::malloc(1024));
286 OutputStream S(Buffer, 1024);
287 print(S);
288 S += '\0';
289 printf("Symbol dump for %p: %s\n", (const void*)this, S.getBuffer());
290 std::free(S.getBuffer());
291 }
292#endif
Erik Pilkington0024acd2017-07-28 00:43:49 +0000293};
294
295class NodeArray {
296 Node **Elements;
297 size_t NumElements;
298
299public:
Erik Pilkington761e6b02018-01-31 20:17:06 +0000300 NodeArray() : Elements(nullptr), NumElements(0) {}
Erik Pilkington414f1a52017-08-09 22:45:35 +0000301 NodeArray(Node **Elements_, size_t NumElements_)
302 : Elements(Elements_), NumElements(NumElements_) {}
Erik Pilkington0024acd2017-07-28 00:43:49 +0000303
304 bool empty() const { return NumElements == 0; }
305 size_t size() const { return NumElements; }
306
Erik Pilkington761e6b02018-01-31 20:17:06 +0000307 Node **begin() const { return Elements; }
308 Node **end() const { return Elements + NumElements; }
309
310 Node *operator[](size_t Idx) const { return Elements[Idx]; }
311
312 void printWithComma(OutputStream &S) const {
313 bool FirstElement = true;
Erik Pilkington0024acd2017-07-28 00:43:49 +0000314 for (size_t Idx = 0; Idx != NumElements; ++Idx) {
Erik Pilkington85619f52018-03-25 22:49:57 +0000315 size_t BeforeComma = S.getCurrentPosition();
Erik Pilkington761e6b02018-01-31 20:17:06 +0000316 if (!FirstElement)
317 S += ", ";
Erik Pilkington85619f52018-03-25 22:49:57 +0000318 size_t AfterComma = S.getCurrentPosition();
Erik Pilkington0024acd2017-07-28 00:43:49 +0000319 Elements[Idx]->print(S);
Erik Pilkington85619f52018-03-25 22:49:57 +0000320
321 // Elements[Idx] is an empty parameter pack expansion, we should erase the
322 // comma we just printed.
323 if (AfterComma == S.getCurrentPosition()) {
324 S.setCurrentPosition(BeforeComma);
325 continue;
326 }
327
328 FirstElement = false;
Erik Pilkington0024acd2017-07-28 00:43:49 +0000329 }
330 }
331};
332
Erik Pilkington6a4e62b2018-04-09 18:31:50 +0000333struct NodeArrayNode : Node {
334 NodeArray Array;
335 NodeArrayNode(NodeArray Array_) : Node(KNodeArrayNode), Array(Array_) {}
336 void printLeft(OutputStream &S) const override {
337 Array.printWithComma(S);
338 }
339};
340
Erik Pilkington0024acd2017-07-28 00:43:49 +0000341class DotSuffix final : public Node {
342 const Node *Prefix;
343 const StringView Suffix;
344
345public:
Erik Pilkington414f1a52017-08-09 22:45:35 +0000346 DotSuffix(Node *Prefix_, StringView Suffix_)
347 : Node(KDotSuffix), Prefix(Prefix_), Suffix(Suffix_) {}
Erik Pilkington0024acd2017-07-28 00:43:49 +0000348
349 void printLeft(OutputStream &s) const override {
350 Prefix->print(s);
351 s += " (";
352 s += Suffix;
353 s += ")";
354 }
355};
356
357class VendorExtQualType final : public Node {
Erik Pilkington0024acd2017-07-28 00:43:49 +0000358 const Node *Ty;
Erik Pilkingtonf23deca2018-02-05 22:41:20 +0000359 StringView Ext;
Erik Pilkington0024acd2017-07-28 00:43:49 +0000360
361public:
Erik Pilkingtonf23deca2018-02-05 22:41:20 +0000362 VendorExtQualType(Node *Ty_, StringView Ext_)
Erik Pilkington85619f52018-03-25 22:49:57 +0000363 : Node(KVendorExtQualType), Ty(Ty_), Ext(Ext_) {}
Erik Pilkington761e6b02018-01-31 20:17:06 +0000364
Erik Pilkington0024acd2017-07-28 00:43:49 +0000365 void printLeft(OutputStream &S) const override {
Erik Pilkington761e6b02018-01-31 20:17:06 +0000366 Ty->print(S);
Erik Pilkington0024acd2017-07-28 00:43:49 +0000367 S += " ";
Erik Pilkingtonf23deca2018-02-05 22:41:20 +0000368 S += Ext;
Erik Pilkington0024acd2017-07-28 00:43:49 +0000369 }
Erik Pilkington0024acd2017-07-28 00:43:49 +0000370};
371
Erik Pilkingtonbdaf8822018-02-14 01:08:17 +0000372enum FunctionRefQual : unsigned char {
373 FrefQualNone,
374 FrefQualLValue,
375 FrefQualRValue,
376};
377
Erik Pilkington0024acd2017-07-28 00:43:49 +0000378enum Qualifiers {
379 QualNone = 0,
380 QualConst = 0x1,
381 QualVolatile = 0x2,
382 QualRestrict = 0x4,
383};
384
385void addQualifiers(Qualifiers &Q1, Qualifiers Q2) {
386 Q1 = static_cast<Qualifiers>(Q1 | Q2);
387}
388
389class QualType : public Node {
390protected:
391 const Qualifiers Quals;
392 const Node *Child;
393
394 void printQuals(OutputStream &S) const {
395 if (Quals & QualConst)
396 S += " const";
397 if (Quals & QualVolatile)
398 S += " volatile";
399 if (Quals & QualRestrict)
400 S += " restrict";
401 }
402
403public:
Erik Pilkington414f1a52017-08-09 22:45:35 +0000404 QualType(Node *Child_, Qualifiers Quals_)
Erik Pilkington85619f52018-03-25 22:49:57 +0000405 : Node(KQualType, Child_->RHSComponentCache,
Erik Pilkington761e6b02018-01-31 20:17:06 +0000406 Child_->ArrayCache, Child_->FunctionCache),
Erik Pilkington414f1a52017-08-09 22:45:35 +0000407 Quals(Quals_), Child(Child_) {}
Erik Pilkington0024acd2017-07-28 00:43:49 +0000408
Erik Pilkington761e6b02018-01-31 20:17:06 +0000409 bool hasRHSComponentSlow(OutputStream &S) const override {
410 return Child->hasRHSComponent(S);
411 }
412 bool hasArraySlow(OutputStream &S) const override {
413 return Child->hasArray(S);
414 }
415 bool hasFunctionSlow(OutputStream &S) const override {
416 return Child->hasFunction(S);
417 }
Erik Pilkington0024acd2017-07-28 00:43:49 +0000418
419 void printLeft(OutputStream &S) const override {
420 Child->printLeft(S);
421 printQuals(S);
422 }
423
424 void printRight(OutputStream &S) const override { Child->printRight(S); }
425};
426
427class ConversionOperatorType final : public Node {
428 const Node *Ty;
429
430public:
Erik Pilkington761e6b02018-01-31 20:17:06 +0000431 ConversionOperatorType(Node *Ty_)
Erik Pilkington85619f52018-03-25 22:49:57 +0000432 : Node(KConversionOperatorType), Ty(Ty_) {}
Erik Pilkington0024acd2017-07-28 00:43:49 +0000433
434 void printLeft(OutputStream &S) const override {
435 S += "operator ";
436 Ty->print(S);
437 }
438};
439
440class PostfixQualifiedType final : public Node {
441 const Node *Ty;
442 const StringView Postfix;
443
444public:
Erik Pilkington414f1a52017-08-09 22:45:35 +0000445 PostfixQualifiedType(Node *Ty_, StringView Postfix_)
Erik Pilkington85619f52018-03-25 22:49:57 +0000446 : Node(KPostfixQualifiedType), Ty(Ty_), Postfix(Postfix_) {}
Erik Pilkington0024acd2017-07-28 00:43:49 +0000447
448 void printLeft(OutputStream &s) const override {
449 Ty->printLeft(s);
450 s += Postfix;
451 }
Erik Pilkington0024acd2017-07-28 00:43:49 +0000452};
453
454class NameType final : public Node {
455 const StringView Name;
456
457public:
Erik Pilkington414f1a52017-08-09 22:45:35 +0000458 NameType(StringView Name_) : Node(KNameType), Name(Name_) {}
Erik Pilkington0024acd2017-07-28 00:43:49 +0000459
460 StringView getName() const { return Name; }
461 StringView getBaseName() const override { return Name; }
462
463 void printLeft(OutputStream &s) const override { s += Name; }
464};
465
Erik Pilkington13fb7dc2018-02-13 00:15:53 +0000466class ElaboratedTypeSpefType : public Node {
467 StringView Kind;
468 Node *Child;
469public:
470 ElaboratedTypeSpefType(StringView Kind_, Node *Child_)
Erik Pilkington85619f52018-03-25 22:49:57 +0000471 : Node(KElaboratedTypeSpefType), Kind(Kind_), Child(Child_) {}
Erik Pilkington13fb7dc2018-02-13 00:15:53 +0000472
473 void printLeft(OutputStream &S) const override {
474 S += Kind;
475 S += ' ';
476 Child->print(S);
477 }
478};
479
Erik Pilkington0df654b2018-04-12 20:41:06 +0000480struct AbiTagAttr : Node {
481 Node *Base;
Erik Pilkington5bff4122017-11-22 20:38:22 +0000482 StringView Tag;
Erik Pilkington0df654b2018-04-12 20:41:06 +0000483
484 AbiTagAttr(Node* Base_, StringView Tag_)
Erik Pilkington85619f52018-03-25 22:49:57 +0000485 : Node(KAbiTagAttr, Base_->RHSComponentCache,
Erik Pilkington761e6b02018-01-31 20:17:06 +0000486 Base_->ArrayCache, Base_->FunctionCache),
487 Base(Base_), Tag(Tag_) {}
Erik Pilkington5bff4122017-11-22 20:38:22 +0000488
489 void printLeft(OutputStream &S) const override {
490 Base->printLeft(S);
491 S += "[abi:";
492 S += Tag;
493 S += "]";
494 }
495};
496
Erik Pilkingtonbb80c5c2018-03-25 22:49:16 +0000497class EnableIfAttr : public Node {
498 NodeArray Conditions;
499public:
500 EnableIfAttr(NodeArray Conditions_)
501 : Node(KEnableIfAttr), Conditions(Conditions_) {}
502
503 void printLeft(OutputStream &S) const override {
504 S += " [enable_if:";
505 Conditions.printWithComma(S);
506 S += ']';
507 }
508};
509
Erik Pilkington0024acd2017-07-28 00:43:49 +0000510class ObjCProtoName : public Node {
511 Node *Ty;
Erik Pilkingtonf23deca2018-02-05 22:41:20 +0000512 StringView Protocol;
Erik Pilkington0024acd2017-07-28 00:43:49 +0000513
514 friend class PointerType;
515
516public:
Erik Pilkingtonf23deca2018-02-05 22:41:20 +0000517 ObjCProtoName(Node *Ty_, StringView Protocol_)
Erik Pilkington414f1a52017-08-09 22:45:35 +0000518 : Node(KObjCProtoName), Ty(Ty_), Protocol(Protocol_) {}
Erik Pilkington0024acd2017-07-28 00:43:49 +0000519
520 bool isObjCObject() const {
Erik Pilkington761e6b02018-01-31 20:17:06 +0000521 return Ty->getKind() == KNameType &&
Erik Pilkington0024acd2017-07-28 00:43:49 +0000522 static_cast<NameType *>(Ty)->getName() == "objc_object";
523 }
524
525 void printLeft(OutputStream &S) const override {
Erik Pilkington761e6b02018-01-31 20:17:06 +0000526 Ty->print(S);
Erik Pilkington0024acd2017-07-28 00:43:49 +0000527 S += "<";
Erik Pilkingtonf23deca2018-02-05 22:41:20 +0000528 S += Protocol;
Erik Pilkington0024acd2017-07-28 00:43:49 +0000529 S += ">";
530 }
531};
532
533class PointerType final : public Node {
534 const Node *Pointee;
535
536public:
Erik Pilkington414f1a52017-08-09 22:45:35 +0000537 PointerType(Node *Pointee_)
Erik Pilkington85619f52018-03-25 22:49:57 +0000538 : Node(KPointerType, Pointee_->RHSComponentCache),
Erik Pilkington761e6b02018-01-31 20:17:06 +0000539 Pointee(Pointee_) {}
540
541 bool hasRHSComponentSlow(OutputStream &S) const override {
542 return Pointee->hasRHSComponent(S);
543 }
Erik Pilkington0024acd2017-07-28 00:43:49 +0000544
545 void printLeft(OutputStream &s) const override {
546 // We rewrite objc_object<SomeProtocol>* into id<SomeProtocol>.
Erik Pilkington761e6b02018-01-31 20:17:06 +0000547 if (Pointee->getKind() != KObjCProtoName ||
Erik Pilkington0024acd2017-07-28 00:43:49 +0000548 !static_cast<const ObjCProtoName *>(Pointee)->isObjCObject()) {
549 Pointee->printLeft(s);
Erik Pilkington761e6b02018-01-31 20:17:06 +0000550 if (Pointee->hasArray(s))
Erik Pilkington0024acd2017-07-28 00:43:49 +0000551 s += " ";
Erik Pilkington761e6b02018-01-31 20:17:06 +0000552 if (Pointee->hasArray(s) || Pointee->hasFunction(s))
Erik Pilkington0024acd2017-07-28 00:43:49 +0000553 s += "(";
554 s += "*";
555 } else {
556 const auto *objcProto = static_cast<const ObjCProtoName *>(Pointee);
557 s += "id<";
Erik Pilkingtonf23deca2018-02-05 22:41:20 +0000558 s += objcProto->Protocol;
Erik Pilkington0024acd2017-07-28 00:43:49 +0000559 s += ">";
560 }
561 }
562
563 void printRight(OutputStream &s) const override {
Erik Pilkington761e6b02018-01-31 20:17:06 +0000564 if (Pointee->getKind() != KObjCProtoName ||
Erik Pilkington0024acd2017-07-28 00:43:49 +0000565 !static_cast<const ObjCProtoName *>(Pointee)->isObjCObject()) {
Erik Pilkington761e6b02018-01-31 20:17:06 +0000566 if (Pointee->hasArray(s) || Pointee->hasFunction(s))
Erik Pilkington0024acd2017-07-28 00:43:49 +0000567 s += ")";
568 Pointee->printRight(s);
569 }
570 }
571};
572
573class LValueReferenceType final : public Node {
574 const Node *Pointee;
575
576public:
Erik Pilkington414f1a52017-08-09 22:45:35 +0000577 LValueReferenceType(Node *Pointee_)
Erik Pilkington85619f52018-03-25 22:49:57 +0000578 : Node(KLValueReferenceType, Pointee_->RHSComponentCache),
Erik Pilkington414f1a52017-08-09 22:45:35 +0000579 Pointee(Pointee_) {}
Erik Pilkington0024acd2017-07-28 00:43:49 +0000580
Erik Pilkington761e6b02018-01-31 20:17:06 +0000581 bool hasRHSComponentSlow(OutputStream &S) const override {
582 return Pointee->hasRHSComponent(S);
583 }
584
Erik Pilkington0024acd2017-07-28 00:43:49 +0000585 void printLeft(OutputStream &s) const override {
586 Pointee->printLeft(s);
Erik Pilkington761e6b02018-01-31 20:17:06 +0000587 if (Pointee->hasArray(s))
Erik Pilkington0024acd2017-07-28 00:43:49 +0000588 s += " ";
Erik Pilkington761e6b02018-01-31 20:17:06 +0000589 if (Pointee->hasArray(s) || Pointee->hasFunction(s))
Erik Pilkington0024acd2017-07-28 00:43:49 +0000590 s += "(&";
591 else
592 s += "&";
593 }
594 void printRight(OutputStream &s) const override {
Erik Pilkington761e6b02018-01-31 20:17:06 +0000595 if (Pointee->hasArray(s) || Pointee->hasFunction(s))
Erik Pilkington0024acd2017-07-28 00:43:49 +0000596 s += ")";
597 Pointee->printRight(s);
598 }
599};
600
601class RValueReferenceType final : public Node {
602 const Node *Pointee;
603
604public:
Erik Pilkington414f1a52017-08-09 22:45:35 +0000605 RValueReferenceType(Node *Pointee_)
Erik Pilkington85619f52018-03-25 22:49:57 +0000606 : Node(KRValueReferenceType, Pointee_->RHSComponentCache),
Erik Pilkington414f1a52017-08-09 22:45:35 +0000607 Pointee(Pointee_) {}
Erik Pilkington0024acd2017-07-28 00:43:49 +0000608
Erik Pilkington761e6b02018-01-31 20:17:06 +0000609 bool hasRHSComponentSlow(OutputStream &S) const override {
610 return Pointee->hasRHSComponent(S);
611 }
612
Erik Pilkington0024acd2017-07-28 00:43:49 +0000613 void printLeft(OutputStream &s) const override {
614 Pointee->printLeft(s);
Erik Pilkington761e6b02018-01-31 20:17:06 +0000615 if (Pointee->hasArray(s))
Erik Pilkington0024acd2017-07-28 00:43:49 +0000616 s += " ";
Erik Pilkington761e6b02018-01-31 20:17:06 +0000617 if (Pointee->hasArray(s) || Pointee->hasFunction(s))
Erik Pilkington0024acd2017-07-28 00:43:49 +0000618 s += "(&&";
619 else
620 s += "&&";
621 }
622
623 void printRight(OutputStream &s) const override {
Erik Pilkington761e6b02018-01-31 20:17:06 +0000624 if (Pointee->hasArray(s) || Pointee->hasFunction(s))
Erik Pilkington0024acd2017-07-28 00:43:49 +0000625 s += ")";
626 Pointee->printRight(s);
627 }
628};
629
630class PointerToMemberType final : public Node {
631 const Node *ClassType;
632 const Node *MemberType;
633
634public:
Erik Pilkington414f1a52017-08-09 22:45:35 +0000635 PointerToMemberType(Node *ClassType_, Node *MemberType_)
Erik Pilkington85619f52018-03-25 22:49:57 +0000636 : Node(KPointerToMemberType, MemberType_->RHSComponentCache),
Erik Pilkington414f1a52017-08-09 22:45:35 +0000637 ClassType(ClassType_), MemberType(MemberType_) {}
Erik Pilkington0024acd2017-07-28 00:43:49 +0000638
Erik Pilkington761e6b02018-01-31 20:17:06 +0000639 bool hasRHSComponentSlow(OutputStream &S) const override {
640 return MemberType->hasRHSComponent(S);
641 }
642
Erik Pilkington0024acd2017-07-28 00:43:49 +0000643 void printLeft(OutputStream &s) const override {
644 MemberType->printLeft(s);
Erik Pilkington761e6b02018-01-31 20:17:06 +0000645 if (MemberType->hasArray(s) || MemberType->hasFunction(s))
Erik Pilkington0024acd2017-07-28 00:43:49 +0000646 s += "(";
647 else
648 s += " ";
649 ClassType->print(s);
650 s += "::*";
651 }
652
653 void printRight(OutputStream &s) const override {
Erik Pilkington761e6b02018-01-31 20:17:06 +0000654 if (MemberType->hasArray(s) || MemberType->hasFunction(s))
Erik Pilkington0024acd2017-07-28 00:43:49 +0000655 s += ")";
656 MemberType->printRight(s);
657 }
658};
659
660class NodeOrString {
661 const void *First;
662 const void *Second;
663
664public:
665 /* implicit */ NodeOrString(StringView Str) {
666 const char *FirstChar = Str.begin();
667 const char *SecondChar = Str.end();
668 if (SecondChar == nullptr) {
669 assert(FirstChar == SecondChar);
670 ++FirstChar, ++SecondChar;
671 }
672 First = static_cast<const void *>(FirstChar);
673 Second = static_cast<const void *>(SecondChar);
674 }
675
676 /* implicit */ NodeOrString(Node *N)
677 : First(static_cast<const void *>(N)), Second(nullptr) {}
678 NodeOrString() : First(nullptr), Second(nullptr) {}
679
680 bool isString() const { return Second && First; }
681 bool isNode() const { return First && !Second; }
682 bool isEmpty() const { return !First && !Second; }
683
684 StringView asString() const {
685 assert(isString());
686 return StringView(static_cast<const char *>(First),
687 static_cast<const char *>(Second));
688 }
689
690 const Node *asNode() const {
691 assert(isNode());
692 return static_cast<const Node *>(First);
693 }
694};
695
696class ArrayType final : public Node {
697 Node *Base;
698 NodeOrString Dimension;
699
700public:
Erik Pilkington414f1a52017-08-09 22:45:35 +0000701 ArrayType(Node *Base_, NodeOrString Dimension_)
Erik Pilkington85619f52018-03-25 22:49:57 +0000702 : Node(KArrayType,
Erik Pilkington761e6b02018-01-31 20:17:06 +0000703 /*RHSComponentCache=*/Cache::Yes,
704 /*ArrayCache=*/Cache::Yes),
Erik Pilkington85619f52018-03-25 22:49:57 +0000705 Base(Base_), Dimension(Dimension_) {}
Erik Pilkington0024acd2017-07-28 00:43:49 +0000706
707 // Incomplete array type.
Erik Pilkington761e6b02018-01-31 20:17:06 +0000708 ArrayType(Node *Base_)
Erik Pilkington85619f52018-03-25 22:49:57 +0000709 : Node(KArrayType,
Erik Pilkington761e6b02018-01-31 20:17:06 +0000710 /*RHSComponentCache=*/Cache::Yes,
711 /*ArrayCache=*/Cache::Yes),
712 Base(Base_) {}
713
714 bool hasRHSComponentSlow(OutputStream &) const override { return true; }
715 bool hasArraySlow(OutputStream &) const override { return true; }
Erik Pilkington0024acd2017-07-28 00:43:49 +0000716
717 void printLeft(OutputStream &S) const override { Base->printLeft(S); }
718
719 void printRight(OutputStream &S) const override {
720 if (S.back() != ']')
721 S += " ";
722 S += "[";
723 if (Dimension.isString())
724 S += Dimension.asString();
725 else if (Dimension.isNode())
726 Dimension.asNode()->print(S);
727 S += "]";
728 Base->printRight(S);
729 }
730};
731
732class FunctionType final : public Node {
733 Node *Ret;
734 NodeArray Params;
Erik Pilkingtonbdaf8822018-02-14 01:08:17 +0000735 Qualifiers CVQuals;
736 FunctionRefQual RefQual;
Erik Pilkington7e027ac2018-02-14 01:08:20 +0000737 Node *ExceptionSpec;
Erik Pilkington0024acd2017-07-28 00:43:49 +0000738
739public:
Erik Pilkingtonbdaf8822018-02-14 01:08:17 +0000740 FunctionType(Node *Ret_, NodeArray Params_, Qualifiers CVQuals_,
Erik Pilkington7e027ac2018-02-14 01:08:20 +0000741 FunctionRefQual RefQual_, Node *ExceptionSpec_)
Erik Pilkington85619f52018-03-25 22:49:57 +0000742 : Node(KFunctionType,
Erik Pilkington761e6b02018-01-31 20:17:06 +0000743 /*RHSComponentCache=*/Cache::Yes, /*ArrayCache=*/Cache::No,
744 /*FunctionCache=*/Cache::Yes),
Erik Pilkington7e027ac2018-02-14 01:08:20 +0000745 Ret(Ret_), Params(Params_), CVQuals(CVQuals_), RefQual(RefQual_),
Erik Pilkington85619f52018-03-25 22:49:57 +0000746 ExceptionSpec(ExceptionSpec_) {}
Erik Pilkington761e6b02018-01-31 20:17:06 +0000747
748 bool hasRHSComponentSlow(OutputStream &) const override { return true; }
749 bool hasFunctionSlow(OutputStream &) const override { return true; }
Erik Pilkington0024acd2017-07-28 00:43:49 +0000750
751 // Handle C++'s ... quirky decl grammer by using the left & right
752 // distinction. Consider:
753 // int (*f(float))(char) {}
754 // f is a function that takes a float and returns a pointer to a function
755 // that takes a char and returns an int. If we're trying to print f, start
756 // by printing out the return types's left, then print our parameters, then
757 // finally print right of the return type.
758 void printLeft(OutputStream &S) const override {
759 Ret->printLeft(S);
760 S += " ";
761 }
762
763 void printRight(OutputStream &S) const override {
764 S += "(";
Erik Pilkington761e6b02018-01-31 20:17:06 +0000765 Params.printWithComma(S);
Erik Pilkington0024acd2017-07-28 00:43:49 +0000766 S += ")";
767 Ret->printRight(S);
Erik Pilkingtonbdaf8822018-02-14 01:08:17 +0000768
769 if (CVQuals & QualConst)
770 S += " const";
771 if (CVQuals & QualVolatile)
772 S += " volatile";
773 if (CVQuals & QualRestrict)
774 S += " restrict";
775
776 if (RefQual == FrefQualLValue)
777 S += " &";
778 else if (RefQual == FrefQualRValue)
779 S += " &&";
Erik Pilkington7e027ac2018-02-14 01:08:20 +0000780
781 if (ExceptionSpec != nullptr) {
782 S += ' ';
783 ExceptionSpec->print(S);
784 }
785 }
786};
787
788class NoexceptSpec : public Node {
789 Node *E;
790public:
Erik Pilkington85619f52018-03-25 22:49:57 +0000791 NoexceptSpec(Node *E_) : Node(KNoexceptSpec), E(E_) {}
Erik Pilkington7e027ac2018-02-14 01:08:20 +0000792
793 void printLeft(OutputStream &S) const override {
794 S += "noexcept(";
795 E->print(S);
796 S += ")";
797 }
798};
799
800class DynamicExceptionSpec : public Node {
801 NodeArray Types;
802public:
803 DynamicExceptionSpec(NodeArray Types_)
Erik Pilkington85619f52018-03-25 22:49:57 +0000804 : Node(KDynamicExceptionSpec), Types(Types_) {}
Erik Pilkington7e027ac2018-02-14 01:08:20 +0000805
806 void printLeft(OutputStream &S) const override {
807 S += "throw(";
808 Types.printWithComma(S);
809 S += ')';
Erik Pilkington0024acd2017-07-28 00:43:49 +0000810 }
811};
812
Erik Pilkington761e6b02018-01-31 20:17:06 +0000813class FunctionEncoding final : public Node {
Erik Pilkington0df654b2018-04-12 20:41:06 +0000814 Node *Ret;
815 Node *Name;
Erik Pilkington0024acd2017-07-28 00:43:49 +0000816 NodeArray Params;
Erik Pilkingtonbb80c5c2018-03-25 22:49:16 +0000817 Node *Attrs;
Erik Pilkingtonbdaf8822018-02-14 01:08:17 +0000818 Qualifiers CVQuals;
819 FunctionRefQual RefQual;
Erik Pilkington0024acd2017-07-28 00:43:49 +0000820
821public:
Erik Pilkingtonbdaf8822018-02-14 01:08:17 +0000822 FunctionEncoding(Node *Ret_, Node *Name_, NodeArray Params_,
Erik Pilkingtonbb80c5c2018-03-25 22:49:16 +0000823 Node *Attrs_, Qualifiers CVQuals_, FunctionRefQual RefQual_)
Erik Pilkington85619f52018-03-25 22:49:57 +0000824 : Node(KFunctionEncoding,
Erik Pilkington761e6b02018-01-31 20:17:06 +0000825 /*RHSComponentCache=*/Cache::Yes, /*ArrayCache=*/Cache::No,
826 /*FunctionCache=*/Cache::Yes),
Erik Pilkingtonbb80c5c2018-03-25 22:49:16 +0000827 Ret(Ret_), Name(Name_), Params(Params_), Attrs(Attrs_),
Erik Pilkington85619f52018-03-25 22:49:57 +0000828 CVQuals(CVQuals_), RefQual(RefQual_) {}
Erik Pilkington761e6b02018-01-31 20:17:06 +0000829
Erik Pilkington0df654b2018-04-12 20:41:06 +0000830 Qualifiers getCVQuals() const { return CVQuals; }
831 FunctionRefQual getRefQual() const { return RefQual; }
832 NodeArray getParams() const { return Params; }
833 Node *getReturnType() const { return Ret; }
834
Erik Pilkington761e6b02018-01-31 20:17:06 +0000835 bool hasRHSComponentSlow(OutputStream &) const override { return true; }
836 bool hasFunctionSlow(OutputStream &) const override { return true; }
837
838 Node *getName() { return const_cast<Node *>(Name); }
Erik Pilkington0024acd2017-07-28 00:43:49 +0000839
840 void printLeft(OutputStream &S) const override {
841 if (Ret) {
842 Ret->printLeft(S);
Erik Pilkington761e6b02018-01-31 20:17:06 +0000843 if (!Ret->hasRHSComponent(S))
Erik Pilkington0024acd2017-07-28 00:43:49 +0000844 S += " ";
845 }
846 Name->print(S);
847 }
848
849 void printRight(OutputStream &S) const override {
850 S += "(";
Erik Pilkington761e6b02018-01-31 20:17:06 +0000851 Params.printWithComma(S);
Erik Pilkington0024acd2017-07-28 00:43:49 +0000852 S += ")";
853 if (Ret)
854 Ret->printRight(S);
Erik Pilkington0024acd2017-07-28 00:43:49 +0000855
Erik Pilkingtonbdaf8822018-02-14 01:08:17 +0000856 if (CVQuals & QualConst)
857 S += " const";
858 if (CVQuals & QualVolatile)
859 S += " volatile";
860 if (CVQuals & QualRestrict)
861 S += " restrict";
Erik Pilkington0024acd2017-07-28 00:43:49 +0000862
Erik Pilkingtonbdaf8822018-02-14 01:08:17 +0000863 if (RefQual == FrefQualLValue)
Erik Pilkington0024acd2017-07-28 00:43:49 +0000864 S += " &";
Erik Pilkingtonbdaf8822018-02-14 01:08:17 +0000865 else if (RefQual == FrefQualRValue)
Erik Pilkington0024acd2017-07-28 00:43:49 +0000866 S += " &&";
Erik Pilkingtonbb80c5c2018-03-25 22:49:16 +0000867
868 if (Attrs != nullptr)
869 Attrs->print(S);
Erik Pilkington0024acd2017-07-28 00:43:49 +0000870 }
Erik Pilkington0024acd2017-07-28 00:43:49 +0000871};
872
873class LiteralOperator : public Node {
874 const Node *OpName;
875
876public:
Erik Pilkington85619f52018-03-25 22:49:57 +0000877 LiteralOperator(Node *OpName_) : Node(KLiteralOperator), OpName(OpName_) {}
Erik Pilkington0024acd2017-07-28 00:43:49 +0000878
879 void printLeft(OutputStream &S) const override {
880 S += "operator\"\" ";
881 OpName->print(S);
882 }
883};
884
885class SpecialName final : public Node {
886 const StringView Special;
887 const Node *Child;
888
889public:
Erik Pilkington761e6b02018-01-31 20:17:06 +0000890 SpecialName(StringView Special_, Node* Child_)
Erik Pilkington85619f52018-03-25 22:49:57 +0000891 : Node(KSpecialName), Special(Special_), Child(Child_) {}
Erik Pilkington0024acd2017-07-28 00:43:49 +0000892
893 void printLeft(OutputStream &S) const override {
894 S += Special;
895 Child->print(S);
896 }
897};
898
899class CtorVtableSpecialName final : public Node {
900 const Node *FirstType;
901 const Node *SecondType;
902
903public:
Erik Pilkington414f1a52017-08-09 22:45:35 +0000904 CtorVtableSpecialName(Node *FirstType_, Node *SecondType_)
Erik Pilkington85619f52018-03-25 22:49:57 +0000905 : Node(KCtorVtableSpecialName),
Erik Pilkington761e6b02018-01-31 20:17:06 +0000906 FirstType(FirstType_), SecondType(SecondType_) {}
Erik Pilkington0024acd2017-07-28 00:43:49 +0000907
908 void printLeft(OutputStream &S) const override {
909 S += "construction vtable for ";
910 FirstType->print(S);
911 S += "-in-";
912 SecondType->print(S);
913 }
914};
915
Erik Pilkington0df654b2018-04-12 20:41:06 +0000916struct NestedName : Node {
917 Node *Qual;
918 Node *Name;
919
920 NestedName(Node *Qual_, Node *Name_)
921 : Node(KNestedName), Qual(Qual_), Name(Name_) {}
922
923 StringView getBaseName() const override { return Name->getBaseName(); }
924
925 void printLeft(OutputStream &S) const override {
926 Qual->print(S);
927 S += "::";
928 Name->print(S);
929 }
930};
931
932struct LocalName : Node {
933 Node *Encoding;
934 Node *Entity;
935
936 LocalName(Node *Encoding_, Node *Entity_)
937 : Node(KLocalName), Encoding(Encoding_), Entity(Entity_) {}
938
939 void printLeft(OutputStream &S) const override {
940 Encoding->print(S);
941 S += "::";
942 Entity->print(S);
943 }
944};
945
Erik Pilkington0024acd2017-07-28 00:43:49 +0000946class QualifiedName final : public Node {
947 // qualifier::name
948 const Node *Qualifier;
949 const Node *Name;
950
Erik Pilkington0024acd2017-07-28 00:43:49 +0000951public:
Erik Pilkington761e6b02018-01-31 20:17:06 +0000952 QualifiedName(Node* Qualifier_, Node* Name_)
Erik Pilkington85619f52018-03-25 22:49:57 +0000953 : Node(KQualifiedName), Qualifier(Qualifier_), Name(Name_) {}
Erik Pilkington0024acd2017-07-28 00:43:49 +0000954
955 StringView getBaseName() const override { return Name->getBaseName(); }
956
957 void printLeft(OutputStream &S) const override {
Erik Pilkington761e6b02018-01-31 20:17:06 +0000958 Qualifier->print(S);
959 S += "::";
Erik Pilkington0024acd2017-07-28 00:43:49 +0000960 Name->print(S);
Erik Pilkington0024acd2017-07-28 00:43:49 +0000961 }
962};
963
Erik Pilkington0024acd2017-07-28 00:43:49 +0000964class VectorType final : public Node {
965 const Node *BaseType;
966 const NodeOrString Dimension;
967 const bool IsPixel;
968
969public:
Erik Pilkington414f1a52017-08-09 22:45:35 +0000970 VectorType(NodeOrString Dimension_)
971 : Node(KVectorType), BaseType(nullptr), Dimension(Dimension_),
Erik Pilkington85619f52018-03-25 22:49:57 +0000972 IsPixel(true) {}
Erik Pilkington414f1a52017-08-09 22:45:35 +0000973 VectorType(Node *BaseType_, NodeOrString Dimension_)
Erik Pilkington85619f52018-03-25 22:49:57 +0000974 : Node(KVectorType), BaseType(BaseType_),
975 Dimension(Dimension_), IsPixel(false) {}
Erik Pilkington0024acd2017-07-28 00:43:49 +0000976
977 void printLeft(OutputStream &S) const override {
978 if (IsPixel) {
979 S += "pixel vector[";
980 S += Dimension.asString();
981 S += "]";
982 } else {
983 BaseType->print(S);
984 S += " vector[";
985 if (Dimension.isNode())
986 Dimension.asNode()->print(S);
987 else if (Dimension.isString())
988 S += Dimension.asString();
989 S += "]";
990 }
991 }
992};
993
Erik Pilkington761e6b02018-01-31 20:17:06 +0000994/// An unexpanded parameter pack (either in the expression or type context). If
995/// this AST is correct, this node will have a ParameterPackExpansion node above
996/// it.
997///
998/// This node is created when some <template-args> are found that apply to an
999/// <encoding>, and is stored in the TemplateParams table. In order for this to
1000/// appear in the final AST, it has to referenced via a <template-param> (ie,
1001/// T_).
1002class ParameterPack final : public Node {
1003 NodeArray Data;
Erik Pilkington85619f52018-03-25 22:49:57 +00001004
1005 // Setup OutputStream for a pack expansion unless we're already expanding one.
1006 void initializePackExpansion(OutputStream &S) const {
1007 if (S.CurrentPackMax == std::numeric_limits<unsigned>::max()) {
1008 S.CurrentPackMax = static_cast<unsigned>(Data.size());
1009 S.CurrentPackIndex = 0;
1010 }
1011 }
1012
Erik Pilkington0024acd2017-07-28 00:43:49 +00001013public:
Erik Pilkington85619f52018-03-25 22:49:57 +00001014 ParameterPack(NodeArray Data_) : Node(KParameterPack), Data(Data_) {
Erik Pilkington761e6b02018-01-31 20:17:06 +00001015 ArrayCache = FunctionCache = RHSComponentCache = Cache::Unknown;
1016 if (std::all_of(Data.begin(), Data.end(), [](Node* P) {
1017 return P->ArrayCache == Cache::No;
1018 }))
1019 ArrayCache = Cache::No;
1020 if (std::all_of(Data.begin(), Data.end(), [](Node* P) {
1021 return P->FunctionCache == Cache::No;
1022 }))
1023 FunctionCache = Cache::No;
1024 if (std::all_of(Data.begin(), Data.end(), [](Node* P) {
1025 return P->RHSComponentCache == Cache::No;
1026 }))
1027 RHSComponentCache = Cache::No;
1028 }
1029
1030 bool hasRHSComponentSlow(OutputStream &S) const override {
Erik Pilkington85619f52018-03-25 22:49:57 +00001031 initializePackExpansion(S);
Erik Pilkington761e6b02018-01-31 20:17:06 +00001032 size_t Idx = S.CurrentPackIndex;
1033 return Idx < Data.size() && Data[Idx]->hasRHSComponent(S);
1034 }
1035 bool hasArraySlow(OutputStream &S) const override {
Erik Pilkington85619f52018-03-25 22:49:57 +00001036 initializePackExpansion(S);
Erik Pilkington761e6b02018-01-31 20:17:06 +00001037 size_t Idx = S.CurrentPackIndex;
1038 return Idx < Data.size() && Data[Idx]->hasArray(S);
1039 }
1040 bool hasFunctionSlow(OutputStream &S) const override {
Erik Pilkington85619f52018-03-25 22:49:57 +00001041 initializePackExpansion(S);
Erik Pilkington761e6b02018-01-31 20:17:06 +00001042 size_t Idx = S.CurrentPackIndex;
1043 return Idx < Data.size() && Data[Idx]->hasFunction(S);
1044 }
Erik Pilkington0024acd2017-07-28 00:43:49 +00001045
1046 void printLeft(OutputStream &S) const override {
Erik Pilkington85619f52018-03-25 22:49:57 +00001047 initializePackExpansion(S);
Erik Pilkington761e6b02018-01-31 20:17:06 +00001048 size_t Idx = S.CurrentPackIndex;
1049 if (Idx < Data.size())
1050 Data[Idx]->printLeft(S);
1051 }
1052 void printRight(OutputStream &S) const override {
Erik Pilkington85619f52018-03-25 22:49:57 +00001053 initializePackExpansion(S);
Erik Pilkington761e6b02018-01-31 20:17:06 +00001054 size_t Idx = S.CurrentPackIndex;
1055 if (Idx < Data.size())
1056 Data[Idx]->printRight(S);
1057 }
1058};
1059
1060/// A variadic template argument. This node represents an occurance of
1061/// J<something>E in some <template-args>. It isn't itself unexpanded, unless
1062/// one of it's Elements is. The parser inserts a ParameterPack into the
1063/// TemplateParams table if the <template-args> this pack belongs to apply to an
1064/// <encoding>.
1065class TemplateArgumentPack final : public Node {
1066 NodeArray Elements;
1067public:
1068 TemplateArgumentPack(NodeArray Elements_)
Erik Pilkington85619f52018-03-25 22:49:57 +00001069 : Node(KTemplateArgumentPack), Elements(Elements_) {}
Erik Pilkington761e6b02018-01-31 20:17:06 +00001070
1071 NodeArray getElements() const { return Elements; }
1072
1073 void printLeft(OutputStream &S) const override {
1074 Elements.printWithComma(S);
1075 }
1076};
1077
1078/// A pack expansion. Below this node, there are some unexpanded ParameterPacks
1079/// which each have Child->ParameterPackSize elements.
1080class ParameterPackExpansion final : public Node {
1081 const Node *Child;
1082
1083public:
1084 ParameterPackExpansion(Node* Child_)
1085 : Node(KParameterPackExpansion), Child(Child_) {}
1086
1087 const Node *getChild() const { return Child; }
1088
1089 void printLeft(OutputStream &S) const override {
Erik Pilkington85619f52018-03-25 22:49:57 +00001090 constexpr unsigned Max = std::numeric_limits<unsigned>::max();
1091 SwapAndRestore<unsigned> SavePackIdx(S.CurrentPackIndex, Max);
1092 SwapAndRestore<unsigned> SavePackMax(S.CurrentPackMax, Max);
1093 size_t StreamPos = S.getCurrentPosition();
1094
1095 // Print the first element in the pack. If Child contains a ParameterPack,
1096 // it will set up S.CurrentPackMax and print the first element.
1097 Child->print(S);
1098
1099 // No ParameterPack was found in Child. This can occur if we've found a pack
1100 // expansion on a <function-param>.
1101 if (S.CurrentPackMax == Max) {
Erik Pilkington761e6b02018-01-31 20:17:06 +00001102 S += "...";
Erik Pilkington0024acd2017-07-28 00:43:49 +00001103 return;
1104 }
1105
Erik Pilkington85619f52018-03-25 22:49:57 +00001106 // We found a ParameterPack, but it has no elements. Erase whatever we may
1107 // of printed.
1108 if (S.CurrentPackMax == 0) {
1109 S.setCurrentPosition(StreamPos);
1110 return;
1111 }
1112
1113 // Else, iterate through the rest of the elements in the pack.
1114 for (unsigned I = 1, E = S.CurrentPackMax; I < E; ++I) {
1115 S += ", ";
Erik Pilkington761e6b02018-01-31 20:17:06 +00001116 S.CurrentPackIndex = I;
1117 Child->print(S);
1118 }
1119 }
1120};
Erik Pilkington0024acd2017-07-28 00:43:49 +00001121
Erik Pilkington761e6b02018-01-31 20:17:06 +00001122class TemplateArgs final : public Node {
1123 NodeArray Params;
1124
1125public:
Erik Pilkington85619f52018-03-25 22:49:57 +00001126 TemplateArgs(NodeArray Params_) : Node(KTemplateArgs), Params(Params_) {}
Erik Pilkington761e6b02018-01-31 20:17:06 +00001127
1128 NodeArray getParams() { return Params; }
1129
1130 void printLeft(OutputStream &S) const override {
Erik Pilkington0024acd2017-07-28 00:43:49 +00001131 S += "<";
Erik Pilkington85619f52018-03-25 22:49:57 +00001132 Params.printWithComma(S);
Erik Pilkington0024acd2017-07-28 00:43:49 +00001133 if (S.back() == '>')
1134 S += " ";
1135 S += ">";
Erik Pilkington0024acd2017-07-28 00:43:49 +00001136 }
1137};
1138
Erik Pilkington04f39852018-03-25 22:50:33 +00001139struct ForwardTemplateReference : Node {
1140 size_t Index;
1141 Node *Ref = nullptr;
1142
Erik Pilkington565ba042018-03-26 15:34:36 +00001143 // If we're currently printing this node. It is possible (though invalid) for
1144 // a forward template reference to refer to itself via a substitution. This
1145 // creates a cyclic AST, which will stack overflow printing. To fix this, bail
1146 // out if more than one print* function is active.
1147 mutable bool Printing = false;
1148
Erik Pilkington04f39852018-03-25 22:50:33 +00001149 ForwardTemplateReference(size_t Index_)
1150 : Node(KForwardTemplateReference, Cache::Unknown, Cache::Unknown,
1151 Cache::Unknown),
1152 Index(Index_) {}
1153
1154 bool hasRHSComponentSlow(OutputStream &S) const override {
Erik Pilkington565ba042018-03-26 15:34:36 +00001155 if (Printing)
1156 return false;
1157 SwapAndRestore<bool> SavePrinting(Printing, true);
Erik Pilkington04f39852018-03-25 22:50:33 +00001158 return Ref->hasRHSComponent(S);
1159 }
1160 bool hasArraySlow(OutputStream &S) const override {
Erik Pilkington565ba042018-03-26 15:34:36 +00001161 if (Printing)
1162 return false;
1163 SwapAndRestore<bool> SavePrinting(Printing, true);
Erik Pilkington04f39852018-03-25 22:50:33 +00001164 return Ref->hasArray(S);
1165 }
1166 bool hasFunctionSlow(OutputStream &S) const override {
Erik Pilkington565ba042018-03-26 15:34:36 +00001167 if (Printing)
1168 return false;
1169 SwapAndRestore<bool> SavePrinting(Printing, true);
Erik Pilkington04f39852018-03-25 22:50:33 +00001170 return Ref->hasFunction(S);
1171 }
1172
Erik Pilkington565ba042018-03-26 15:34:36 +00001173 void printLeft(OutputStream &S) const override {
1174 if (Printing)
1175 return;
1176 SwapAndRestore<bool> SavePrinting(Printing, true);
1177 Ref->printLeft(S);
1178 }
1179 void printRight(OutputStream &S) const override {
1180 if (Printing)
1181 return;
1182 SwapAndRestore<bool> SavePrinting(Printing, true);
1183 Ref->printRight(S);
1184 }
Erik Pilkington04f39852018-03-25 22:50:33 +00001185};
1186
Erik Pilkington0df654b2018-04-12 20:41:06 +00001187struct NameWithTemplateArgs : Node {
Erik Pilkington0024acd2017-07-28 00:43:49 +00001188 // name<template_args>
1189 Node *Name;
1190 Node *TemplateArgs;
1191
Erik Pilkington414f1a52017-08-09 22:45:35 +00001192 NameWithTemplateArgs(Node *Name_, Node *TemplateArgs_)
Erik Pilkington85619f52018-03-25 22:49:57 +00001193 : Node(KNameWithTemplateArgs), Name(Name_), TemplateArgs(TemplateArgs_) {}
Erik Pilkington0024acd2017-07-28 00:43:49 +00001194
1195 StringView getBaseName() const override { return Name->getBaseName(); }
1196
1197 void printLeft(OutputStream &S) const override {
1198 Name->print(S);
1199 TemplateArgs->print(S);
1200 }
1201};
1202
1203class GlobalQualifiedName final : public Node {
1204 Node *Child;
1205
1206public:
Erik Pilkington761e6b02018-01-31 20:17:06 +00001207 GlobalQualifiedName(Node* Child_)
Erik Pilkington85619f52018-03-25 22:49:57 +00001208 : Node(KGlobalQualifiedName), Child(Child_) {}
Erik Pilkington0024acd2017-07-28 00:43:49 +00001209
1210 StringView getBaseName() const override { return Child->getBaseName(); }
1211
1212 void printLeft(OutputStream &S) const override {
1213 S += "::";
1214 Child->print(S);
1215 }
1216};
1217
Erik Pilkington0df654b2018-04-12 20:41:06 +00001218struct StdQualifiedName : Node {
Erik Pilkington0024acd2017-07-28 00:43:49 +00001219 Node *Child;
1220
Erik Pilkington85619f52018-03-25 22:49:57 +00001221 StdQualifiedName(Node *Child_) : Node(KStdQualifiedName), Child(Child_) {}
Erik Pilkington0024acd2017-07-28 00:43:49 +00001222
1223 StringView getBaseName() const override { return Child->getBaseName(); }
1224
1225 void printLeft(OutputStream &S) const override {
1226 S += "std::";
1227 Child->print(S);
1228 }
1229};
1230
1231enum class SpecialSubKind {
1232 allocator,
1233 basic_string,
1234 string,
1235 istream,
1236 ostream,
1237 iostream,
1238};
1239
1240class ExpandedSpecialSubstitution final : public Node {
1241 SpecialSubKind SSK;
1242
1243public:
Erik Pilkington414f1a52017-08-09 22:45:35 +00001244 ExpandedSpecialSubstitution(SpecialSubKind SSK_)
1245 : Node(KExpandedSpecialSubstitution), SSK(SSK_) {}
Erik Pilkington0024acd2017-07-28 00:43:49 +00001246
1247 StringView getBaseName() const override {
1248 switch (SSK) {
1249 case SpecialSubKind::allocator:
1250 return StringView("allocator");
1251 case SpecialSubKind::basic_string:
1252 return StringView("basic_string");
1253 case SpecialSubKind::string:
1254 return StringView("basic_string");
1255 case SpecialSubKind::istream:
1256 return StringView("basic_istream");
1257 case SpecialSubKind::ostream:
1258 return StringView("basic_ostream");
1259 case SpecialSubKind::iostream:
1260 return StringView("basic_iostream");
1261 }
Erik Pilkingtond25d9012017-08-01 02:38:40 +00001262 _LIBCPP_UNREACHABLE();
Erik Pilkington0024acd2017-07-28 00:43:49 +00001263 }
1264
1265 void printLeft(OutputStream &S) const override {
1266 switch (SSK) {
1267 case SpecialSubKind::allocator:
1268 S += "std::basic_string<char, std::char_traits<char>, "
1269 "std::allocator<char> >";
1270 break;
1271 case SpecialSubKind::basic_string:
1272 case SpecialSubKind::string:
1273 S += "std::basic_string<char, std::char_traits<char>, "
1274 "std::allocator<char> >";
1275 break;
1276 case SpecialSubKind::istream:
1277 S += "std::basic_istream<char, std::char_traits<char> >";
1278 break;
1279 case SpecialSubKind::ostream:
1280 S += "std::basic_ostream<char, std::char_traits<char> >";
1281 break;
1282 case SpecialSubKind::iostream:
1283 S += "std::basic_iostream<char, std::char_traits<char> >";
1284 break;
1285 }
1286 }
1287};
1288
1289class SpecialSubstitution final : public Node {
1290public:
1291 SpecialSubKind SSK;
1292
Erik Pilkington414f1a52017-08-09 22:45:35 +00001293 SpecialSubstitution(SpecialSubKind SSK_)
1294 : Node(KSpecialSubstitution), SSK(SSK_) {}
Erik Pilkington0024acd2017-07-28 00:43:49 +00001295
1296 StringView getBaseName() const override {
1297 switch (SSK) {
1298 case SpecialSubKind::allocator:
1299 return StringView("allocator");
1300 case SpecialSubKind::basic_string:
1301 return StringView("basic_string");
1302 case SpecialSubKind::string:
1303 return StringView("string");
1304 case SpecialSubKind::istream:
1305 return StringView("istream");
1306 case SpecialSubKind::ostream:
1307 return StringView("ostream");
1308 case SpecialSubKind::iostream:
1309 return StringView("iostream");
1310 }
Erik Pilkingtond25d9012017-08-01 02:38:40 +00001311 _LIBCPP_UNREACHABLE();
Erik Pilkington0024acd2017-07-28 00:43:49 +00001312 }
1313
1314 void printLeft(OutputStream &S) const override {
1315 switch (SSK) {
1316 case SpecialSubKind::allocator:
1317 S += "std::allocator";
1318 break;
1319 case SpecialSubKind::basic_string:
1320 S += "std::basic_string";
1321 break;
1322 case SpecialSubKind::string:
1323 S += "std::string";
1324 break;
1325 case SpecialSubKind::istream:
1326 S += "std::istream";
1327 break;
1328 case SpecialSubKind::ostream:
1329 S += "std::ostream";
1330 break;
1331 case SpecialSubKind::iostream:
1332 S += "std::iostream";
1333 break;
1334 }
1335 }
1336};
1337
1338class CtorDtorName final : public Node {
1339 const Node *Basename;
1340 const bool IsDtor;
1341
1342public:
Erik Pilkington414f1a52017-08-09 22:45:35 +00001343 CtorDtorName(Node *Basename_, bool IsDtor_)
Erik Pilkington85619f52018-03-25 22:49:57 +00001344 : Node(KCtorDtorName), Basename(Basename_), IsDtor(IsDtor_) {}
Erik Pilkington0024acd2017-07-28 00:43:49 +00001345
1346 void printLeft(OutputStream &S) const override {
1347 if (IsDtor)
1348 S += "~";
1349 S += Basename->getBaseName();
1350 }
1351};
1352
1353class DtorName : public Node {
1354 const Node *Base;
1355
1356public:
Erik Pilkington85619f52018-03-25 22:49:57 +00001357 DtorName(Node *Base_) : Node(KDtorName), Base(Base_) {}
Erik Pilkington0024acd2017-07-28 00:43:49 +00001358
1359 void printLeft(OutputStream &S) const override {
1360 S += "~";
1361 Base->printLeft(S);
1362 }
1363};
1364
1365class UnnamedTypeName : public Node {
1366 const StringView Count;
1367
1368public:
Erik Pilkington414f1a52017-08-09 22:45:35 +00001369 UnnamedTypeName(StringView Count_) : Node(KUnnamedTypeName), Count(Count_) {}
Erik Pilkington0024acd2017-07-28 00:43:49 +00001370
1371 void printLeft(OutputStream &S) const override {
1372 S += "'unnamed";
1373 S += Count;
1374 S += "\'";
1375 }
1376};
1377
Erik Pilkingtone1d61622018-03-05 16:35:06 +00001378class ClosureTypeName : public Node {
Erik Pilkington0024acd2017-07-28 00:43:49 +00001379 NodeArray Params;
1380 StringView Count;
1381
1382public:
Erik Pilkingtone1d61622018-03-05 16:35:06 +00001383 ClosureTypeName(NodeArray Params_, StringView Count_)
Erik Pilkington85619f52018-03-25 22:49:57 +00001384 : Node(KClosureTypeName), Params(Params_), Count(Count_) {}
Erik Pilkington0024acd2017-07-28 00:43:49 +00001385
1386 void printLeft(OutputStream &S) const override {
1387 S += "\'lambda";
1388 S += Count;
1389 S += "\'(";
Erik Pilkington761e6b02018-01-31 20:17:06 +00001390 Params.printWithComma(S);
Erik Pilkington0024acd2017-07-28 00:43:49 +00001391 S += ")";
1392 }
1393};
1394
Erik Pilkingtondee4d0b2018-03-10 21:31:15 +00001395class StructuredBindingName : public Node {
1396 NodeArray Bindings;
1397public:
1398 StructuredBindingName(NodeArray Bindings_)
1399 : Node(KStructuredBindingName), Bindings(Bindings_) {}
1400
1401 void printLeft(OutputStream &S) const override {
Erik Pilkingtonaa209d82018-03-10 22:33:49 +00001402 S += '[';
Erik Pilkingtondee4d0b2018-03-10 21:31:15 +00001403 Bindings.printWithComma(S);
1404 S += ']';
1405 }
1406};
1407
Erik Pilkington0024acd2017-07-28 00:43:49 +00001408// -- Expression Nodes --
1409
1410struct Expr : public Node {
Erik Pilkington88a1cf62018-02-13 00:15:56 +00001411 Expr(Kind K = KExpr) : Node(K) {}
Erik Pilkington0024acd2017-07-28 00:43:49 +00001412};
1413
1414class BinaryExpr : public Expr {
1415 const Node *LHS;
1416 const StringView InfixOperator;
1417 const Node *RHS;
1418
1419public:
Erik Pilkington414f1a52017-08-09 22:45:35 +00001420 BinaryExpr(Node *LHS_, StringView InfixOperator_, Node *RHS_)
Erik Pilkington85619f52018-03-25 22:49:57 +00001421 : LHS(LHS_), InfixOperator(InfixOperator_), RHS(RHS_) {}
Erik Pilkington0024acd2017-07-28 00:43:49 +00001422
1423 void printLeft(OutputStream &S) const override {
1424 // might be a template argument expression, then we need to disambiguate
1425 // with parens.
1426 if (InfixOperator == ">")
1427 S += "(";
1428
1429 S += "(";
1430 LHS->print(S);
1431 S += ") ";
1432 S += InfixOperator;
1433 S += " (";
1434 RHS->print(S);
1435 S += ")";
1436
1437 if (InfixOperator == ">")
1438 S += ")";
1439 }
1440};
1441
1442class ArraySubscriptExpr : public Expr {
1443 const Node *Op1;
1444 const Node *Op2;
1445
1446public:
Erik Pilkington85619f52018-03-25 22:49:57 +00001447 ArraySubscriptExpr(Node *Op1_, Node *Op2_) : Op1(Op1_), Op2(Op2_) {}
Erik Pilkington0024acd2017-07-28 00:43:49 +00001448
1449 void printLeft(OutputStream &S) const override {
1450 S += "(";
1451 Op1->print(S);
1452 S += ")[";
1453 Op2->print(S);
1454 S += "]";
1455 }
1456};
1457
1458class PostfixExpr : public Expr {
1459 const Node *Child;
1460 const StringView Operand;
1461
1462public:
Erik Pilkington414f1a52017-08-09 22:45:35 +00001463 PostfixExpr(Node *Child_, StringView Operand_)
Erik Pilkington85619f52018-03-25 22:49:57 +00001464 : Child(Child_), Operand(Operand_) {}
Erik Pilkington0024acd2017-07-28 00:43:49 +00001465
1466 void printLeft(OutputStream &S) const override {
1467 S += "(";
1468 Child->print(S);
1469 S += ")";
1470 S += Operand;
1471 }
1472};
1473
1474class ConditionalExpr : public Expr {
1475 const Node *Cond;
1476 const Node *Then;
1477 const Node *Else;
1478
1479public:
Erik Pilkington414f1a52017-08-09 22:45:35 +00001480 ConditionalExpr(Node *Cond_, Node *Then_, Node *Else_)
Erik Pilkington85619f52018-03-25 22:49:57 +00001481 : Cond(Cond_), Then(Then_), Else(Else_) {}
Erik Pilkington0024acd2017-07-28 00:43:49 +00001482
1483 void printLeft(OutputStream &S) const override {
1484 S += "(";
1485 Cond->print(S);
1486 S += ") ? (";
1487 Then->print(S);
1488 S += ") : (";
1489 Else->print(S);
1490 S += ")";
1491 }
1492};
1493
1494class MemberExpr : public Expr {
1495 const Node *LHS;
1496 const StringView Kind;
1497 const Node *RHS;
1498
1499public:
Erik Pilkington414f1a52017-08-09 22:45:35 +00001500 MemberExpr(Node *LHS_, StringView Kind_, Node *RHS_)
Erik Pilkington85619f52018-03-25 22:49:57 +00001501 : LHS(LHS_), Kind(Kind_), RHS(RHS_) {}
Erik Pilkington0024acd2017-07-28 00:43:49 +00001502
1503 void printLeft(OutputStream &S) const override {
1504 LHS->print(S);
1505 S += Kind;
1506 RHS->print(S);
1507 }
1508};
1509
1510class EnclosingExpr : public Expr {
1511 const StringView Prefix;
1512 const Node *Infix;
1513 const StringView Postfix;
1514
1515public:
Erik Pilkington414f1a52017-08-09 22:45:35 +00001516 EnclosingExpr(StringView Prefix_, Node *Infix_, StringView Postfix_)
Erik Pilkington85619f52018-03-25 22:49:57 +00001517 : Prefix(Prefix_), Infix(Infix_), Postfix(Postfix_) {}
Erik Pilkington0024acd2017-07-28 00:43:49 +00001518
1519 void printLeft(OutputStream &S) const override {
1520 S += Prefix;
1521 Infix->print(S);
1522 S += Postfix;
1523 }
1524};
1525
1526class CastExpr : public Expr {
1527 // cast_kind<to>(from)
1528 const StringView CastKind;
1529 const Node *To;
1530 const Node *From;
1531
1532public:
Erik Pilkington414f1a52017-08-09 22:45:35 +00001533 CastExpr(StringView CastKind_, Node *To_, Node *From_)
Erik Pilkington85619f52018-03-25 22:49:57 +00001534 : CastKind(CastKind_), To(To_), From(From_) {}
Erik Pilkington0024acd2017-07-28 00:43:49 +00001535
1536 void printLeft(OutputStream &S) const override {
1537 S += CastKind;
1538 S += "<";
1539 To->printLeft(S);
1540 S += ">(";
1541 From->printLeft(S);
1542 S += ")";
1543 }
1544};
1545
1546class SizeofParamPackExpr : public Expr {
Erik Pilkington761e6b02018-01-31 20:17:06 +00001547 Node *Pack;
Erik Pilkington0024acd2017-07-28 00:43:49 +00001548
1549public:
Erik Pilkington761e6b02018-01-31 20:17:06 +00001550 SizeofParamPackExpr(Node *Pack_) : Pack(Pack_) {}
Erik Pilkington0024acd2017-07-28 00:43:49 +00001551
1552 void printLeft(OutputStream &S) const override {
1553 S += "sizeof...(";
Erik Pilkington761e6b02018-01-31 20:17:06 +00001554 ParameterPackExpansion PPE(Pack);
1555 PPE.printLeft(S);
Erik Pilkington0024acd2017-07-28 00:43:49 +00001556 S += ")";
1557 }
1558};
1559
1560class CallExpr : public Expr {
1561 const Node *Callee;
1562 NodeArray Args;
1563
1564public:
Erik Pilkington85619f52018-03-25 22:49:57 +00001565 CallExpr(Node *Callee_, NodeArray Args_) : Callee(Callee_), Args(Args_) {}
Erik Pilkington0024acd2017-07-28 00:43:49 +00001566
1567 void printLeft(OutputStream &S) const override {
1568 Callee->print(S);
1569 S += "(";
Erik Pilkington761e6b02018-01-31 20:17:06 +00001570 Args.printWithComma(S);
Erik Pilkington0024acd2017-07-28 00:43:49 +00001571 S += ")";
1572 }
1573};
1574
1575class NewExpr : public Expr {
1576 // new (expr_list) type(init_list)
1577 NodeArray ExprList;
1578 Node *Type;
1579 NodeArray InitList;
1580 bool IsGlobal; // ::operator new ?
1581 bool IsArray; // new[] ?
1582public:
Erik Pilkington414f1a52017-08-09 22:45:35 +00001583 NewExpr(NodeArray ExprList_, Node *Type_, NodeArray InitList_, bool IsGlobal_,
1584 bool IsArray_)
Erik Pilkington761e6b02018-01-31 20:17:06 +00001585 : ExprList(ExprList_), Type(Type_), InitList(InitList_),
Erik Pilkington85619f52018-03-25 22:49:57 +00001586 IsGlobal(IsGlobal_), IsArray(IsArray_) {}
Erik Pilkington0024acd2017-07-28 00:43:49 +00001587
1588 void printLeft(OutputStream &S) const override {
1589 if (IsGlobal)
1590 S += "::operator ";
1591 S += "new";
1592 if (IsArray)
1593 S += "[]";
Erik Pilkingtonb679cfd2018-02-02 18:04:32 +00001594 S += ' ';
Erik Pilkington0024acd2017-07-28 00:43:49 +00001595 if (!ExprList.empty()) {
1596 S += "(";
Erik Pilkington761e6b02018-01-31 20:17:06 +00001597 ExprList.printWithComma(S);
Erik Pilkington0024acd2017-07-28 00:43:49 +00001598 S += ")";
1599 }
1600 Type->print(S);
1601 if (!InitList.empty()) {
1602 S += "(";
Erik Pilkington761e6b02018-01-31 20:17:06 +00001603 InitList.printWithComma(S);
Erik Pilkington0024acd2017-07-28 00:43:49 +00001604 S += ")";
1605 }
Erik Pilkington761e6b02018-01-31 20:17:06 +00001606
Erik Pilkington0024acd2017-07-28 00:43:49 +00001607 }
1608};
1609
1610class DeleteExpr : public Expr {
1611 Node *Op;
1612 bool IsGlobal;
1613 bool IsArray;
1614
1615public:
Erik Pilkington414f1a52017-08-09 22:45:35 +00001616 DeleteExpr(Node *Op_, bool IsGlobal_, bool IsArray_)
Erik Pilkington85619f52018-03-25 22:49:57 +00001617 : Op(Op_), IsGlobal(IsGlobal_), IsArray(IsArray_) {}
Erik Pilkington0024acd2017-07-28 00:43:49 +00001618
1619 void printLeft(OutputStream &S) const override {
1620 if (IsGlobal)
1621 S += "::";
1622 S += "delete";
1623 if (IsArray)
1624 S += "[] ";
1625 Op->print(S);
1626 }
1627};
1628
1629class PrefixExpr : public Expr {
1630 StringView Prefix;
1631 Node *Child;
1632
1633public:
Erik Pilkington85619f52018-03-25 22:49:57 +00001634 PrefixExpr(StringView Prefix_, Node *Child_) : Prefix(Prefix_), Child(Child_) {}
Erik Pilkington0024acd2017-07-28 00:43:49 +00001635
1636 void printLeft(OutputStream &S) const override {
1637 S += Prefix;
1638 S += "(";
1639 Child->print(S);
1640 S += ")";
1641 }
1642};
1643
1644class FunctionParam : public Expr {
1645 StringView Number;
1646
1647public:
Erik Pilkington414f1a52017-08-09 22:45:35 +00001648 FunctionParam(StringView Number_) : Number(Number_) {}
Erik Pilkington0024acd2017-07-28 00:43:49 +00001649
1650 void printLeft(OutputStream &S) const override {
1651 S += "fp";
1652 S += Number;
1653 }
1654};
1655
Erik Pilkington0024acd2017-07-28 00:43:49 +00001656class ConversionExpr : public Expr {
Erik Pilkington761e6b02018-01-31 20:17:06 +00001657 const Node *Type;
Erik Pilkington0024acd2017-07-28 00:43:49 +00001658 NodeArray Expressions;
Erik Pilkington0024acd2017-07-28 00:43:49 +00001659
1660public:
Erik Pilkington761e6b02018-01-31 20:17:06 +00001661 ConversionExpr(const Node *Type_, NodeArray Expressions_)
Erik Pilkington85619f52018-03-25 22:49:57 +00001662 : Type(Type_), Expressions(Expressions_) {}
Erik Pilkington0024acd2017-07-28 00:43:49 +00001663
1664 void printLeft(OutputStream &S) const override {
1665 S += "(";
Erik Pilkington761e6b02018-01-31 20:17:06 +00001666 Type->print(S);
Erik Pilkington0024acd2017-07-28 00:43:49 +00001667 S += ")(";
Erik Pilkington761e6b02018-01-31 20:17:06 +00001668 Expressions.printWithComma(S);
Erik Pilkington0024acd2017-07-28 00:43:49 +00001669 S += ")";
1670 }
1671};
1672
Erik Pilkington88a1cf62018-02-13 00:15:56 +00001673class InitListExpr : public Expr {
1674 Node *Ty;
1675 NodeArray Inits;
1676public:
Erik Pilkington85619f52018-03-25 22:49:57 +00001677 InitListExpr(Node *Ty_, NodeArray Inits_) : Ty(Ty_), Inits(Inits_) {}
Erik Pilkington88a1cf62018-02-13 00:15:56 +00001678
1679 void printLeft(OutputStream &S) const override {
1680 if (Ty)
1681 Ty->print(S);
1682 S += '{';
1683 Inits.printWithComma(S);
1684 S += '}';
1685 }
1686};
1687
1688class BracedExpr : public Expr {
1689 Node *Elem;
1690 Node *Init;
1691 bool IsArray;
1692public:
1693 BracedExpr(Node *Elem_, Node *Init_, bool IsArray_)
1694 : Expr(KBracedExpr), Elem(Elem_), Init(Init_), IsArray(IsArray_) {}
1695
1696 void printLeft(OutputStream &S) const override {
1697 if (IsArray) {
1698 S += '[';
1699 Elem->print(S);
1700 S += ']';
1701 } else {
1702 S += '.';
1703 Elem->print(S);
1704 }
1705 if (Init->getKind() != KBracedExpr && Init->getKind() != KBracedRangeExpr)
1706 S += " = ";
1707 Init->print(S);
1708 }
1709};
1710
1711class BracedRangeExpr : public Expr {
1712 Node *First;
1713 Node *Last;
1714 Node *Init;
1715public:
1716 BracedRangeExpr(Node *First_, Node *Last_, Node *Init_)
1717 : Expr(KBracedRangeExpr), First(First_), Last(Last_), Init(Init_) {}
1718
1719 void printLeft(OutputStream &S) const override {
1720 S += '[';
1721 First->print(S);
1722 S += " ... ";
1723 Last->print(S);
1724 S += ']';
1725 if (Init->getKind() != KBracedExpr && Init->getKind() != KBracedRangeExpr)
1726 S += " = ";
1727 Init->print(S);
1728 }
1729};
1730
Erik Pilkington967b00e2018-04-09 18:33:01 +00001731struct FoldExpr : Expr {
1732 Node *Pack, *Init;
1733 StringView OperatorName;
1734 bool IsLeftFold;
1735
1736 FoldExpr(bool IsLeftFold_, StringView OperatorName_, Node *Pack_, Node *Init_)
1737 : Pack(Pack_), Init(Init_), OperatorName(OperatorName_),
1738 IsLeftFold(IsLeftFold_) {}
1739
1740 void printLeft(OutputStream &S) const override {
1741 auto PrintPack = [&] {
1742 S += '(';
1743 ParameterPackExpansion(Pack).print(S);
1744 S += ')';
1745 };
1746
1747 S += '(';
1748
1749 if (IsLeftFold) {
1750 // init op ... op pack
1751 if (Init != nullptr) {
1752 Init->print(S);
1753 S += ' ';
1754 S += OperatorName;
1755 S += ' ';
1756 }
1757 // ... op pack
1758 S += "... ";
1759 S += OperatorName;
1760 S += ' ';
1761 PrintPack();
1762 } else { // !IsLeftFold
1763 // pack op ...
1764 PrintPack();
1765 S += ' ';
1766 S += OperatorName;
1767 S += " ...";
1768 // pack op ... op init
1769 if (Init != nullptr) {
1770 S += ' ';
1771 S += OperatorName;
1772 S += ' ';
1773 Init->print(S);
1774 }
1775 }
1776 S += ')';
1777 }
1778};
1779
Erik Pilkington0024acd2017-07-28 00:43:49 +00001780class ThrowExpr : public Expr {
1781 const Node *Op;
1782
1783public:
Erik Pilkington85619f52018-03-25 22:49:57 +00001784 ThrowExpr(Node *Op_) : Op(Op_) {}
Erik Pilkington0024acd2017-07-28 00:43:49 +00001785
1786 void printLeft(OutputStream &S) const override {
1787 S += "throw ";
1788 Op->print(S);
1789 }
1790};
1791
1792class BoolExpr : public Expr {
1793 bool Value;
1794
1795public:
Erik Pilkington414f1a52017-08-09 22:45:35 +00001796 BoolExpr(bool Value_) : Value(Value_) {}
Erik Pilkington0024acd2017-07-28 00:43:49 +00001797
1798 void printLeft(OutputStream &S) const override {
1799 S += Value ? StringView("true") : StringView("false");
1800 }
1801};
1802
1803class IntegerCastExpr : public Expr {
1804 // ty(integer)
1805 Node *Ty;
1806 StringView Integer;
1807
1808public:
Erik Pilkington85619f52018-03-25 22:49:57 +00001809 IntegerCastExpr(Node *Ty_, StringView Integer_)
1810 : Ty(Ty_), Integer(Integer_) {}
Erik Pilkington0024acd2017-07-28 00:43:49 +00001811
1812 void printLeft(OutputStream &S) const override {
1813 S += "(";
1814 Ty->print(S);
1815 S += ")";
1816 S += Integer;
1817 }
1818};
1819
1820class IntegerExpr : public Expr {
1821 StringView Type;
1822 StringView Value;
1823
1824public:
Erik Pilkington414f1a52017-08-09 22:45:35 +00001825 IntegerExpr(StringView Type_, StringView Value_) : Type(Type_), Value(Value_) {}
Erik Pilkington0024acd2017-07-28 00:43:49 +00001826
1827 void printLeft(OutputStream &S) const override {
1828 if (Type.size() > 3) {
1829 S += "(";
1830 S += Type;
1831 S += ")";
1832 }
1833
1834 if (Value[0] == 'n') {
1835 S += "-";
1836 S += Value.dropFront(1);
1837 } else
1838 S += Value;
1839
1840 if (Type.size() <= 3)
1841 S += Type;
1842 }
1843};
1844
1845template <class Float> struct FloatData;
1846
1847template <class Float> class FloatExpr : public Expr {
1848 const StringView Contents;
1849
1850public:
Erik Pilkington414f1a52017-08-09 22:45:35 +00001851 FloatExpr(StringView Contents_) : Contents(Contents_) {}
Erik Pilkington0024acd2017-07-28 00:43:49 +00001852
1853 void printLeft(OutputStream &s) const override {
1854 const char *first = Contents.begin();
1855 const char *last = Contents.end() + 1;
1856
1857 const size_t N = FloatData<Float>::mangled_size;
1858 if (static_cast<std::size_t>(last - first) > N) {
1859 last = first + N;
1860 union {
1861 Float value;
1862 char buf[sizeof(Float)];
1863 };
1864 const char *t = first;
1865 char *e = buf;
1866 for (; t != last; ++t, ++e) {
1867 unsigned d1 = isdigit(*t) ? static_cast<unsigned>(*t - '0')
1868 : static_cast<unsigned>(*t - 'a' + 10);
1869 ++t;
1870 unsigned d0 = isdigit(*t) ? static_cast<unsigned>(*t - '0')
1871 : static_cast<unsigned>(*t - 'a' + 10);
1872 *e = static_cast<char>((d1 << 4) + d0);
1873 }
1874#if __BYTE_ORDER__ == __ORDER_LITTLE_ENDIAN__
1875 std::reverse(buf, e);
1876#endif
1877 char num[FloatData<Float>::max_demangled_size] = {0};
1878 int n = snprintf(num, sizeof(num), FloatData<Float>::spec, value);
1879 s += StringView(num, num + n);
1880 }
1881 }
1882};
1883
Erik Pilkington0024acd2017-07-28 00:43:49 +00001884class BumpPointerAllocator {
1885 struct BlockMeta {
1886 BlockMeta* Next;
1887 size_t Current;
1888 };
Erik Pilkington9dd63d22017-07-08 18:54:07 +00001889
Erik Pilkington0024acd2017-07-28 00:43:49 +00001890 static constexpr size_t AllocSize = 4096;
1891 static constexpr size_t UsableAllocSize = AllocSize - sizeof(BlockMeta);
Erik Pilkington9dd63d22017-07-08 18:54:07 +00001892
Serge Pavlov047fb732018-07-05 06:24:29 +00001893 alignas(long double) char InitialBuffer[AllocSize];
Erik Pilkington0024acd2017-07-28 00:43:49 +00001894 BlockMeta* BlockList = nullptr;
1895
1896 void grow() {
1897 char* NewMeta = new char[AllocSize];
1898 BlockList = new (NewMeta) BlockMeta{BlockList, 0};
1899 }
1900
1901 void* allocateMassive(size_t NBytes) {
1902 NBytes += sizeof(BlockMeta);
1903 BlockMeta* NewMeta = reinterpret_cast<BlockMeta*>(new char[NBytes]);
1904 BlockList->Next = new (NewMeta) BlockMeta{BlockList->Next, 0};
1905 return static_cast<void*>(NewMeta + 1);
1906 }
1907
1908public:
1909 BumpPointerAllocator()
1910 : BlockList(new (InitialBuffer) BlockMeta{nullptr, 0}) {}
1911
1912 void* allocate(size_t N) {
1913 N = (N + 15u) & ~15u;
1914 if (N + BlockList->Current >= UsableAllocSize) {
1915 if (N > UsableAllocSize)
1916 return allocateMassive(N);
1917 grow();
1918 }
1919 BlockList->Current += N;
1920 return static_cast<void*>(reinterpret_cast<char*>(BlockList + 1) +
1921 BlockList->Current - N);
1922 }
1923
Erik Pilkington0df654b2018-04-12 20:41:06 +00001924 void reset() {
Erik Pilkington0024acd2017-07-28 00:43:49 +00001925 while (BlockList) {
1926 BlockMeta* Tmp = BlockList;
1927 BlockList = BlockList->Next;
1928 if (reinterpret_cast<char*>(Tmp) != InitialBuffer)
1929 delete[] reinterpret_cast<char*>(Tmp);
1930 }
Erik Pilkington0df654b2018-04-12 20:41:06 +00001931 BlockList = new (InitialBuffer) BlockMeta{nullptr, 0};
Erik Pilkington0024acd2017-07-28 00:43:49 +00001932 }
Erik Pilkington0df654b2018-04-12 20:41:06 +00001933
1934 ~BumpPointerAllocator() { reset(); }
Erik Pilkington9dd63d22017-07-08 18:54:07 +00001935};
1936
Erik Pilkingtonba34a242017-08-09 21:30:57 +00001937template <class T, size_t N>
1938class PODSmallVector {
1939 static_assert(std::is_pod<T>::value,
1940 "T is required to be a plain old data type");
1941
1942 T* First;
1943 T* Last;
1944 T* Cap;
1945 T Inline[N];
1946
1947 bool isInline() const { return First == Inline; }
1948
1949 void clearInline() {
1950 First = Inline;
1951 Last = Inline;
1952 Cap = Inline + N;
1953 }
1954
1955 void reserve(size_t NewCap) {
1956 size_t S = size();
1957 if (isInline()) {
1958 auto* Tmp = static_cast<T*>(std::malloc(NewCap * sizeof(T)));
1959 std::copy(First, Last, Tmp);
1960 First = Tmp;
1961 } else
1962 First = static_cast<T*>(std::realloc(First, NewCap * sizeof(T)));
1963 Last = First + S;
1964 Cap = First + NewCap;
1965 }
1966
1967public:
1968 PODSmallVector() : First(Inline), Last(First), Cap(Inline + N) {}
1969
1970 PODSmallVector(const PODSmallVector&) = delete;
1971 PODSmallVector& operator=(const PODSmallVector&) = delete;
1972
1973 PODSmallVector(PODSmallVector&& Other) : PODSmallVector() {
1974 if (Other.isInline()) {
1975 std::copy(Other.begin(), Other.end(), First);
1976 Last = First + Other.size();
1977 Other.clear();
1978 return;
1979 }
1980
1981 First = Other.First;
1982 Last = Other.Last;
1983 Cap = Other.Cap;
1984 Other.clearInline();
1985 }
1986
1987 PODSmallVector& operator=(PODSmallVector&& Other) {
1988 if (Other.isInline()) {
1989 if (!isInline()) {
1990 std::free(First);
1991 clearInline();
1992 }
1993 std::copy(Other.begin(), Other.end(), First);
1994 Last = First + Other.size();
1995 Other.clear();
1996 return *this;
1997 }
1998
1999 if (isInline()) {
2000 First = Other.First;
2001 Last = Other.Last;
2002 Cap = Other.Cap;
2003 Other.clearInline();
2004 return *this;
2005 }
2006
2007 std::swap(First, Other.First);
2008 std::swap(Last, Other.Last);
2009 std::swap(Cap, Other.Cap);
2010 Other.clear();
2011 return *this;
2012 }
2013
2014 void push_back(const T& Elem) {
2015 if (Last == Cap)
2016 reserve(size() * 2);
2017 *Last++ = Elem;
2018 }
2019
2020 void pop_back() {
2021 assert(Last != First && "Popping empty vector!");
2022 --Last;
2023 }
2024
2025 void dropBack(size_t Index) {
2026 assert(Index <= size() && "dropBack() can't expand!");
2027 Last = First + Index;
2028 }
2029
2030 T* begin() { return First; }
2031 T* end() { return Last; }
2032
2033 bool empty() const { return First == Last; }
2034 size_t size() const { return static_cast<size_t>(Last - First); }
2035 T& back() {
2036 assert(Last != First && "Calling back() on empty vector!");
2037 return *(Last - 1);
2038 }
2039 T& operator[](size_t Index) {
2040 assert(Index < size() && "Invalid access!");
2041 return *(begin() + Index);
2042 }
2043 void clear() { Last = First; }
2044
2045 ~PODSmallVector() {
2046 if (!isInline())
2047 std::free(First);
2048 }
2049};
2050
Erik Pilkingtonb679cfd2018-02-02 18:04:32 +00002051struct Db {
2052 const char *First;
2053 const char *Last;
Erik Pilkingtonba34a242017-08-09 21:30:57 +00002054
Erik Pilkingtonb679cfd2018-02-02 18:04:32 +00002055 // Name stack, this is used by the parser to hold temporary names that were
2056 // parsed. The parser colapses multiple names into new nodes to construct
2057 // the AST. Once the parser is finished, names.size() == 1.
2058 PODSmallVector<Node *, 32> Names;
Erik Pilkingtonba34a242017-08-09 21:30:57 +00002059
Erik Pilkingtonb679cfd2018-02-02 18:04:32 +00002060 // Substitution table. Itanium supports name substitutions as a means of
2061 // compression. The string "S42_" refers to the 44nd entry (base-36) in this
2062 // table.
2063 PODSmallVector<Node *, 32> Subs;
Erik Pilkingtonba34a242017-08-09 21:30:57 +00002064
Erik Pilkingtonb679cfd2018-02-02 18:04:32 +00002065 // Template parameter table. Like the above, but referenced like "T42_".
2066 // This has a smaller size compared to Subs and Names because it can be
2067 // stored on the stack.
2068 PODSmallVector<Node *, 8> TemplateParams;
Erik Pilkington9dd63d22017-07-08 18:54:07 +00002069
Erik Pilkington04f39852018-03-25 22:50:33 +00002070 // Set of unresolved forward <template-param> references. These can occur in a
2071 // conversion operator's type, and are resolved in the enclosing <encoding>.
2072 PODSmallVector<ForwardTemplateReference *, 4> ForwardTemplateRefs;
2073
Erik Pilkingtonb679cfd2018-02-02 18:04:32 +00002074 bool TryToParseTemplateArgs = true;
Erik Pilkington04f39852018-03-25 22:50:33 +00002075 bool PermitForwardTemplateReferences = false;
Erik Pilkington61966e52018-03-16 03:06:30 +00002076 bool ParsingLambdaParams = false;
Erik Pilkington0024acd2017-07-28 00:43:49 +00002077
Erik Pilkingtonb679cfd2018-02-02 18:04:32 +00002078 BumpPointerAllocator ASTAllocator;
2079
Erik Pilkingtonf26c8d12018-03-06 14:21:10 +00002080 Db(const char *First_, const char *Last_) : First(First_), Last(Last_) {}
2081
Erik Pilkington0df654b2018-04-12 20:41:06 +00002082 void reset(const char *First_, const char *Last_) {
2083 First = First_;
2084 Last = Last_;
2085 Names.clear();
2086 Subs.clear();
2087 TemplateParams.clear();
2088 ParsingLambdaParams = false;
2089 TryToParseTemplateArgs = true;
2090 PermitForwardTemplateReferences = false;
2091 ASTAllocator.reset();
2092 }
2093
Erik Pilkingtonb679cfd2018-02-02 18:04:32 +00002094 template <class T, class... Args> T *make(Args &&... args) {
2095 return new (ASTAllocator.allocate(sizeof(T)))
2096 T(std::forward<Args>(args)...);
2097 }
2098
2099 template <class It> NodeArray makeNodeArray(It begin, It end) {
2100 size_t sz = static_cast<size_t>(end - begin);
2101 void *mem = ASTAllocator.allocate(sizeof(Node *) * sz);
2102 Node **data = new (mem) Node *[sz];
2103 std::copy(begin, end, data);
2104 return NodeArray(data, sz);
2105 }
2106
2107 NodeArray popTrailingNodeArray(size_t FromPosition) {
2108 assert(FromPosition <= Names.size());
2109 NodeArray res =
2110 makeNodeArray(Names.begin() + (long)FromPosition, Names.end());
2111 Names.dropBack(FromPosition);
2112 return res;
2113 }
2114
2115 bool consumeIf(StringView S) {
2116 if (StringView(First, Last).startsWith(S)) {
2117 First += S.size();
2118 return true;
Erik Pilkington0024acd2017-07-28 00:43:49 +00002119 }
Erik Pilkingtonb679cfd2018-02-02 18:04:32 +00002120 return false;
2121 }
Erik Pilkington0024acd2017-07-28 00:43:49 +00002122
Erik Pilkingtonb679cfd2018-02-02 18:04:32 +00002123 bool consumeIf(char C) {
2124 if (First != Last && *First == C) {
2125 ++First;
2126 return true;
Erik Pilkington0024acd2017-07-28 00:43:49 +00002127 }
Erik Pilkingtonb679cfd2018-02-02 18:04:32 +00002128 return false;
2129 }
Erik Pilkington0024acd2017-07-28 00:43:49 +00002130
Erik Pilkingtonb679cfd2018-02-02 18:04:32 +00002131 char consume() { return First != Last ? *First++ : '\0'; }
2132
2133 char look(unsigned Lookahead = 0) {
2134 if (static_cast<size_t>(Last - First) <= Lookahead)
2135 return '\0';
2136 return First[Lookahead];
2137 }
2138
2139 size_t numLeft() const { return static_cast<size_t>(Last - First); }
2140
2141 StringView parseNumber(bool AllowNegative = false);
2142 Qualifiers parseCVQualifiers();
Erik Pilkingtonf23deca2018-02-05 22:41:20 +00002143 bool parsePositiveInteger(size_t *Out);
2144 StringView parseBareSourceName();
Erik Pilkingtonb679cfd2018-02-02 18:04:32 +00002145
Erik Pilkingtonf26c8d12018-03-06 14:21:10 +00002146 bool parseSeqId(size_t *Out);
2147 Node *parseSubstitution();
2148 Node *parseTemplateParam();
Erik Pilkington04f39852018-03-25 22:50:33 +00002149 Node *parseTemplateArgs(bool TagTemplates = false);
Erik Pilkingtonf26c8d12018-03-06 14:21:10 +00002150 Node *parseTemplateArg();
2151
Erik Pilkingtonb679cfd2018-02-02 18:04:32 +00002152 /// Parse the <expr> production.
2153 Node *parseExpr();
2154 Node *parsePrefixExpr(StringView Kind);
2155 Node *parseBinaryExpr(StringView Kind);
2156 Node *parseIntegerLiteral(StringView Lit);
2157 Node *parseExprPrimary();
2158 template <class Float> Node *parseFloatingLiteral();
2159 Node *parseFunctionParam();
2160 Node *parseNewExpr();
2161 Node *parseConversionExpr();
Erik Pilkington88a1cf62018-02-13 00:15:56 +00002162 Node *parseBracedExpr();
Erik Pilkington967b00e2018-04-09 18:33:01 +00002163 Node *parseFoldExpr();
Erik Pilkingtonb679cfd2018-02-02 18:04:32 +00002164
Erik Pilkingtonf23deca2018-02-05 22:41:20 +00002165 /// Parse the <type> production.
2166 Node *parseType();
2167 Node *parseFunctionType();
2168 Node *parseVectorType();
2169 Node *parseDecltype();
2170 Node *parseArrayType();
2171 Node *parsePointerToMemberType();
2172 Node *parseClassEnumType();
Erik Pilkingtonbdaf8822018-02-14 01:08:17 +00002173 Node *parseQualifiedType();
Erik Pilkingtonf23deca2018-02-05 22:41:20 +00002174
Erik Pilkingtone1d61622018-03-05 16:35:06 +00002175 Node *parseEncoding();
2176 bool parseCallOffset();
2177 Node *parseSpecialName();
2178
2179 /// Holds some extra information about a <name> that is being parsed. This
2180 /// information is only pertinent if the <name> refers to an <encoding>.
2181 struct NameState {
2182 bool CtorDtorConversion = false;
2183 bool EndsWithTemplateArgs = false;
2184 Qualifiers CVQualifiers = QualNone;
2185 FunctionRefQual ReferenceQualifier = FrefQualNone;
Erik Pilkington04f39852018-03-25 22:50:33 +00002186 size_t ForwardTemplateRefsBegin;
2187
2188 NameState(Db *Enclosing)
2189 : ForwardTemplateRefsBegin(Enclosing->ForwardTemplateRefs.size()) {}
Erik Pilkingtone1d61622018-03-05 16:35:06 +00002190 };
2191
Erik Pilkington04f39852018-03-25 22:50:33 +00002192 bool resolveForwardTemplateRefs(NameState &State) {
2193 size_t I = State.ForwardTemplateRefsBegin;
2194 size_t E = ForwardTemplateRefs.size();
2195 for (; I < E; ++I) {
2196 size_t Idx = ForwardTemplateRefs[I]->Index;
2197 if (Idx >= TemplateParams.size())
2198 return true;
2199 ForwardTemplateRefs[I]->Ref = TemplateParams[Idx];
2200 }
2201 ForwardTemplateRefs.dropBack(State.ForwardTemplateRefsBegin);
2202 return false;
2203 }
2204
Erik Pilkingtone1d61622018-03-05 16:35:06 +00002205 /// Parse the <name> production>
2206 Node *parseName(NameState *State = nullptr);
2207 Node *parseLocalName(NameState *State);
2208 Node *parseOperatorName(NameState *State);
2209 Node *parseUnqualifiedName(NameState *State);
2210 Node *parseUnnamedTypeName(NameState *State);
2211 Node *parseSourceName(NameState *State);
2212 Node *parseUnscopedName(NameState *State);
2213 Node *parseNestedName(NameState *State);
2214 Node *parseCtorDtorName(Node *&SoFar, NameState *State);
2215
Erik Pilkington2808f772018-02-13 17:09:03 +00002216 Node *parseAbiTags(Node *N);
2217
Erik Pilkingtond0dd97d2018-03-06 14:21:08 +00002218 /// Parse the <unresolved-name> production.
2219 Node *parseUnresolvedName();
2220 Node *parseSimpleId();
2221 Node *parseBaseUnresolvedName();
2222 Node *parseUnresolvedType();
2223 Node *parseDestructorName();
2224
Erik Pilkingtonf26c8d12018-03-06 14:21:10 +00002225 /// Top-level entry point into the parser.
2226 Node *parse();
Erik Pilkington0024acd2017-07-28 00:43:49 +00002227};
Erik Pilkingtonc3926622017-07-08 18:54:08 +00002228
Erik Pilkingtone1d61622018-03-05 16:35:06 +00002229const char* parse_discriminator(const char* first, const char* last);
Erik Pilkington2808f772018-02-13 17:09:03 +00002230
Erik Pilkingtone1d61622018-03-05 16:35:06 +00002231// <name> ::= <nested-name> // N
2232// ::= <local-name> # See Scope Encoding below // Z
2233// ::= <unscoped-template-name> <template-args>
2234// ::= <unscoped-name>
2235//
2236// <unscoped-template-name> ::= <unscoped-name>
2237// ::= <substitution>
2238Node *Db::parseName(NameState *State) {
2239 consumeIf('L'); // extension
2240
2241 if (look() == 'N')
2242 return parseNestedName(State);
2243 if (look() == 'Z')
2244 return parseLocalName(State);
2245
2246 // ::= <unscoped-template-name> <template-args>
2247 if (look() == 'S' && look(1) != 't') {
Erik Pilkingtonf26c8d12018-03-06 14:21:10 +00002248 Node *S = parseSubstitution();
2249 if (S == nullptr)
2250 return nullptr;
Erik Pilkingtone1d61622018-03-05 16:35:06 +00002251 if (look() != 'I')
2252 return nullptr;
Erik Pilkington04f39852018-03-25 22:50:33 +00002253 Node *TA = parseTemplateArgs(State != nullptr);
Erik Pilkingtone1d61622018-03-05 16:35:06 +00002254 if (TA == nullptr)
2255 return nullptr;
2256 if (State) State->EndsWithTemplateArgs = true;
2257 return make<NameWithTemplateArgs>(S, TA);
2258 }
2259
2260 Node *N = parseUnscopedName(State);
2261 if (N == nullptr)
2262 return nullptr;
2263 // ::= <unscoped-template-name> <template-args>
2264 if (look() == 'I') {
2265 Subs.push_back(N);
Erik Pilkington04f39852018-03-25 22:50:33 +00002266 Node *TA = parseTemplateArgs(State != nullptr);
Erik Pilkingtone1d61622018-03-05 16:35:06 +00002267 if (TA == nullptr)
2268 return nullptr;
2269 if (State) State->EndsWithTemplateArgs = true;
2270 return make<NameWithTemplateArgs>(N, TA);
2271 }
2272 // ::= <unscoped-name>
2273 return N;
2274}
2275
2276// <local-name> := Z <function encoding> E <entity name> [<discriminator>]
2277// := Z <function encoding> E s [<discriminator>]
2278// := Z <function encoding> Ed [ <parameter number> ] _ <entity name>
2279Node *Db::parseLocalName(NameState *State) {
2280 if (!consumeIf('Z'))
2281 return nullptr;
2282 Node *Encoding = parseEncoding();
2283 if (Encoding == nullptr || !consumeIf('E'))
2284 return nullptr;
2285
2286 if (consumeIf('s')) {
2287 First = parse_discriminator(First, Last);
Erik Pilkington0df654b2018-04-12 20:41:06 +00002288 return make<LocalName>(Encoding, make<NameType>("string literal"));
Erik Pilkingtone1d61622018-03-05 16:35:06 +00002289 }
2290
2291 if (consumeIf('d')) {
2292 parseNumber(true);
2293 if (!consumeIf('_'))
2294 return nullptr;
2295 Node *N = parseName(State);
2296 if (N == nullptr)
2297 return nullptr;
Erik Pilkington0df654b2018-04-12 20:41:06 +00002298 return make<LocalName>(Encoding, N);
Erik Pilkingtone1d61622018-03-05 16:35:06 +00002299 }
2300
2301 Node *Entity = parseName(State);
2302 if (Entity == nullptr)
2303 return nullptr;
2304 First = parse_discriminator(First, Last);
Erik Pilkington0df654b2018-04-12 20:41:06 +00002305 return make<LocalName>(Encoding, Entity);
Erik Pilkingtone1d61622018-03-05 16:35:06 +00002306}
2307
2308// <unscoped-name> ::= <unqualified-name>
2309// ::= St <unqualified-name> # ::std::
2310// extension ::= StL<unqualified-name>
2311Node *Db::parseUnscopedName(NameState *State) {
2312 if (consumeIf("StL") || consumeIf("St")) {
2313 Node *R = parseUnqualifiedName(State);
2314 if (R == nullptr)
2315 return nullptr;
2316 return make<StdQualifiedName>(R);
2317 }
2318 return parseUnqualifiedName(State);
2319}
2320
2321// <unqualified-name> ::= <operator-name> [abi-tags]
2322// ::= <ctor-dtor-name>
2323// ::= <source-name>
2324// ::= <unnamed-type-name>
Erik Pilkingtondee4d0b2018-03-10 21:31:15 +00002325// ::= DC <source-name>+ E # structured binding declaration
Erik Pilkingtone1d61622018-03-05 16:35:06 +00002326Node *Db::parseUnqualifiedName(NameState *State) {
2327 // <ctor-dtor-name>s are special-cased in parseNestedName().
2328 Node *Result;
2329 if (look() == 'U')
2330 Result = parseUnnamedTypeName(State);
2331 else if (look() >= '1' && look() <= '9')
2332 Result = parseSourceName(State);
Erik Pilkingtondee4d0b2018-03-10 21:31:15 +00002333 else if (consumeIf("DC")) {
2334 size_t BindingsBegin = Names.size();
2335 do {
2336 Node *Binding = parseSourceName(State);
2337 if (Binding == nullptr)
2338 return nullptr;
2339 Names.push_back(Binding);
2340 } while (!consumeIf('E'));
2341 Result = make<StructuredBindingName>(popTrailingNodeArray(BindingsBegin));
2342 } else
Erik Pilkingtone1d61622018-03-05 16:35:06 +00002343 Result = parseOperatorName(State);
2344 if (Result != nullptr)
2345 Result = parseAbiTags(Result);
2346 return Result;
2347}
2348
2349// <unnamed-type-name> ::= Ut [<nonnegative number>] _
2350// ::= <closure-type-name>
2351//
2352// <closure-type-name> ::= Ul <lambda-sig> E [ <nonnegative number> ] _
2353//
2354// <lambda-sig> ::= <parameter type>+ # Parameter types or "v" if the lambda has no parameters
2355Node *Db::parseUnnamedTypeName(NameState *) {
2356 if (consumeIf("Ut")) {
2357 StringView Count = parseNumber();
2358 if (!consumeIf('_'))
2359 return nullptr;
2360 return make<UnnamedTypeName>(Count);
2361 }
2362 if (consumeIf("Ul")) {
2363 NodeArray Params;
Erik Pilkington61966e52018-03-16 03:06:30 +00002364 SwapAndRestore<bool> SwapParams(ParsingLambdaParams, true);
Erik Pilkingtone1d61622018-03-05 16:35:06 +00002365 if (!consumeIf("vE")) {
2366 size_t ParamsBegin = Names.size();
2367 do {
2368 Node *P = parseType();
2369 if (P == nullptr)
2370 return nullptr;
2371 Names.push_back(P);
2372 } while (!consumeIf('E'));
2373 Params = popTrailingNodeArray(ParamsBegin);
2374 }
2375 StringView Count = parseNumber();
2376 if (!consumeIf('_'))
2377 return nullptr;
2378 return make<ClosureTypeName>(Params, Count);
2379 }
2380 return nullptr;
2381}
2382
2383// <source-name> ::= <positive length number> <identifier>
2384Node *Db::parseSourceName(NameState *) {
2385 size_t Length = 0;
2386 if (parsePositiveInteger(&Length))
2387 return nullptr;
2388 if (numLeft() < Length || Length == 0)
2389 return nullptr;
2390 StringView Name(First, First + Length);
2391 First += Length;
2392 if (Name.startsWith("_GLOBAL__N"))
2393 return make<NameType>("(anonymous namespace)");
2394 return make<NameType>(Name);
2395}
2396
2397// <operator-name> ::= aa # &&
2398// ::= ad # & (unary)
2399// ::= an # &
2400// ::= aN # &=
2401// ::= aS # =
2402// ::= cl # ()
2403// ::= cm # ,
2404// ::= co # ~
2405// ::= cv <type> # (cast)
2406// ::= da # delete[]
2407// ::= de # * (unary)
2408// ::= dl # delete
2409// ::= dv # /
2410// ::= dV # /=
2411// ::= eo # ^
2412// ::= eO # ^=
2413// ::= eq # ==
2414// ::= ge # >=
2415// ::= gt # >
2416// ::= ix # []
2417// ::= le # <=
2418// ::= li <source-name> # operator ""
2419// ::= ls # <<
2420// ::= lS # <<=
2421// ::= lt # <
2422// ::= mi # -
2423// ::= mI # -=
2424// ::= ml # *
2425// ::= mL # *=
2426// ::= mm # -- (postfix in <expression> context)
2427// ::= na # new[]
2428// ::= ne # !=
2429// ::= ng # - (unary)
2430// ::= nt # !
2431// ::= nw # new
2432// ::= oo # ||
2433// ::= or # |
2434// ::= oR # |=
2435// ::= pm # ->*
2436// ::= pl # +
2437// ::= pL # +=
2438// ::= pp # ++ (postfix in <expression> context)
2439// ::= ps # + (unary)
2440// ::= pt # ->
2441// ::= qu # ?
2442// ::= rm # %
2443// ::= rM # %=
2444// ::= rs # >>
2445// ::= rS # >>=
2446// ::= ss # <=> C++2a
2447// ::= v <digit> <source-name> # vendor extended operator
2448Node *Db::parseOperatorName(NameState *State) {
2449 switch (look()) {
2450 case 'a':
2451 switch (look(1)) {
2452 case 'a':
2453 First += 2;
2454 return make<NameType>("operator&&");
2455 case 'd':
2456 case 'n':
2457 First += 2;
2458 return make<NameType>("operator&");
2459 case 'N':
2460 First += 2;
2461 return make<NameType>("operator&=");
2462 case 'S':
2463 First += 2;
2464 return make<NameType>("operator=");
2465 }
2466 return nullptr;
2467 case 'c':
2468 switch (look(1)) {
2469 case 'l':
2470 First += 2;
2471 return make<NameType>("operator()");
2472 case 'm':
2473 First += 2;
2474 return make<NameType>("operator,");
2475 case 'o':
2476 First += 2;
2477 return make<NameType>("operator~");
2478 // ::= cv <type> # (cast)
2479 case 'v': {
Erik Pilkingtone1d61622018-03-05 16:35:06 +00002480 First += 2;
Erik Pilkington04f39852018-03-25 22:50:33 +00002481 SwapAndRestore<bool> SaveTemplate(TryToParseTemplateArgs, false);
2482 // If we're parsing an encoding, State != nullptr and the conversion
2483 // operators' <type> could have a <template-param> that refers to some
2484 // <template-arg>s further ahead in the mangled name.
2485 SwapAndRestore<bool> SavePermit(PermitForwardTemplateReferences,
2486 PermitForwardTemplateReferences ||
2487 State != nullptr);
2488 Node* Ty = parseType();
Erik Pilkingtone1d61622018-03-05 16:35:06 +00002489 if (Ty == nullptr)
2490 return nullptr;
2491 if (State) State->CtorDtorConversion = true;
2492 return make<ConversionOperatorType>(Ty);
2493 }
2494 }
2495 return nullptr;
2496 case 'd':
2497 switch (look(1)) {
2498 case 'a':
2499 First += 2;
2500 return make<NameType>("operator delete[]");
2501 case 'e':
2502 First += 2;
2503 return make<NameType>("operator*");
2504 case 'l':
2505 First += 2;
2506 return make<NameType>("operator delete");
2507 case 'v':
2508 First += 2;
2509 return make<NameType>("operator/");
2510 case 'V':
2511 First += 2;
2512 return make<NameType>("operator/=");
2513 }
2514 return nullptr;
2515 case 'e':
2516 switch (look(1)) {
2517 case 'o':
2518 First += 2;
2519 return make<NameType>("operator^");
2520 case 'O':
2521 First += 2;
2522 return make<NameType>("operator^=");
2523 case 'q':
2524 First += 2;
2525 return make<NameType>("operator==");
2526 }
2527 return nullptr;
2528 case 'g':
2529 switch (look(1)) {
2530 case 'e':
2531 First += 2;
2532 return make<NameType>("operator>=");
2533 case 't':
2534 First += 2;
2535 return make<NameType>("operator>");
2536 }
2537 return nullptr;
2538 case 'i':
2539 if (look(1) == 'x') {
2540 First += 2;
2541 return make<NameType>("operator[]");
2542 }
2543 return nullptr;
2544 case 'l':
2545 switch (look(1)) {
2546 case 'e':
2547 First += 2;
2548 return make<NameType>("operator<=");
2549 // ::= li <source-name> # operator ""
2550 case 'i': {
2551 First += 2;
2552 Node *SN = parseSourceName(State);
2553 if (SN == nullptr)
2554 return nullptr;
2555 return make<LiteralOperator>(SN);
2556 }
2557 case 's':
2558 First += 2;
2559 return make<NameType>("operator<<");
2560 case 'S':
2561 First += 2;
2562 return make<NameType>("operator<<=");
2563 case 't':
2564 First += 2;
2565 return make<NameType>("operator<");
2566 }
2567 return nullptr;
2568 case 'm':
2569 switch (look(1)) {
2570 case 'i':
2571 First += 2;
2572 return make<NameType>("operator-");
2573 case 'I':
2574 First += 2;
2575 return make<NameType>("operator-=");
2576 case 'l':
2577 First += 2;
2578 return make<NameType>("operator*");
2579 case 'L':
2580 First += 2;
2581 return make<NameType>("operator*=");
2582 case 'm':
2583 First += 2;
2584 return make<NameType>("operator--");
2585 }
2586 return nullptr;
2587 case 'n':
2588 switch (look(1)) {
2589 case 'a':
2590 First += 2;
2591 return make<NameType>("operator new[]");
2592 case 'e':
2593 First += 2;
2594 return make<NameType>("operator!=");
2595 case 'g':
2596 First += 2;
2597 return make<NameType>("operator-");
2598 case 't':
2599 First += 2;
2600 return make<NameType>("operator!");
2601 case 'w':
2602 First += 2;
2603 return make<NameType>("operator new");
2604 }
2605 return nullptr;
2606 case 'o':
2607 switch (look(1)) {
2608 case 'o':
2609 First += 2;
2610 return make<NameType>("operator||");
2611 case 'r':
2612 First += 2;
2613 return make<NameType>("operator|");
2614 case 'R':
2615 First += 2;
2616 return make<NameType>("operator|=");
2617 }
2618 return nullptr;
2619 case 'p':
2620 switch (look(1)) {
2621 case 'm':
2622 First += 2;
2623 return make<NameType>("operator->*");
2624 case 'l':
2625 First += 2;
2626 return make<NameType>("operator+");
2627 case 'L':
2628 First += 2;
2629 return make<NameType>("operator+=");
2630 case 'p':
2631 First += 2;
2632 return make<NameType>("operator++");
2633 case 's':
2634 First += 2;
2635 return make<NameType>("operator+");
2636 case 't':
2637 First += 2;
2638 return make<NameType>("operator->");
2639 }
2640 return nullptr;
2641 case 'q':
2642 if (look(1) == 'u') {
2643 First += 2;
2644 return make<NameType>("operator?");
2645 }
2646 return nullptr;
2647 case 'r':
2648 switch (look(1)) {
2649 case 'm':
2650 First += 2;
2651 return make<NameType>("operator%");
2652 case 'M':
2653 First += 2;
2654 return make<NameType>("operator%=");
2655 case 's':
2656 First += 2;
2657 return make<NameType>("operator>>");
2658 case 'S':
2659 First += 2;
2660 return make<NameType>("operator>>=");
2661 }
2662 return nullptr;
2663 case 's':
2664 if (look(1) == 's') {
2665 First += 2;
2666 return make<NameType>("operator<=>");
2667 }
2668 return nullptr;
2669 // ::= v <digit> <source-name> # vendor extended operator
2670 case 'v':
2671 if (std::isdigit(look(1))) {
2672 First += 2;
2673 Node *SN = parseSourceName(State);
2674 if (SN == nullptr)
2675 return nullptr;
2676 return make<ConversionOperatorType>(SN);
2677 }
2678 return nullptr;
2679 }
2680 return nullptr;
2681}
2682
Erik Pilkington2808f772018-02-13 17:09:03 +00002683// <ctor-dtor-name> ::= C1 # complete object constructor
2684// ::= C2 # base object constructor
2685// ::= C3 # complete object allocating constructor
2686// extension ::= C5 # ?
2687// ::= D0 # deleting destructor
2688// ::= D1 # complete object destructor
2689// ::= D2 # base object destructor
2690// extension ::= D5 # ?
Erik Pilkingtone1d61622018-03-05 16:35:06 +00002691Node *Db::parseCtorDtorName(Node *&SoFar, NameState *State) {
Erik Pilkington2808f772018-02-13 17:09:03 +00002692 if (SoFar->K == Node::KSpecialSubstitution) {
2693 auto SSK = static_cast<SpecialSubstitution *>(SoFar)->SSK;
2694 switch (SSK) {
2695 case SpecialSubKind::string:
2696 case SpecialSubKind::istream:
2697 case SpecialSubKind::ostream:
2698 case SpecialSubKind::iostream:
2699 SoFar = make<ExpandedSpecialSubstitution>(SSK);
2700 default:
2701 break;
2702 }
2703 }
2704
2705 if (consumeIf('C')) {
Erik Pilkington5f0867c2018-02-13 17:09:07 +00002706 bool IsInherited = consumeIf('I');
Erik Pilkington2808f772018-02-13 17:09:03 +00002707 if (look() != '1' && look() != '2' && look() != '3' && look() != '5')
2708 return nullptr;
2709 ++First;
Erik Pilkingtone1d61622018-03-05 16:35:06 +00002710 if (State) State->CtorDtorConversion = true;
Erik Pilkington5f0867c2018-02-13 17:09:07 +00002711 if (IsInherited) {
Erik Pilkington04f39852018-03-25 22:50:33 +00002712 if (parseName(State) == nullptr)
Erik Pilkington5f0867c2018-02-13 17:09:07 +00002713 return nullptr;
2714 }
Erik Pilkington2808f772018-02-13 17:09:03 +00002715 return make<CtorDtorName>(SoFar, false);
2716 }
2717
2718 if (look() == 'D' &&
2719 (look(1) == '0' || look(1) == '1' || look(1) == '2' || look(1) == '5')) {
2720 First += 2;
Erik Pilkingtone1d61622018-03-05 16:35:06 +00002721 if (State) State->CtorDtorConversion = true;
Erik Pilkington2808f772018-02-13 17:09:03 +00002722 return make<CtorDtorName>(SoFar, true);
2723 }
2724
2725 return nullptr;
2726}
2727
2728// <nested-name> ::= N [<CV-Qualifiers>] [<ref-qualifier>] <prefix> <unqualified-name> E
2729// ::= N [<CV-Qualifiers>] [<ref-qualifier>] <template-prefix> <template-args> E
2730//
2731// <prefix> ::= <prefix> <unqualified-name>
2732// ::= <template-prefix> <template-args>
2733// ::= <template-param>
2734// ::= <decltype>
2735// ::= # empty
2736// ::= <substitution>
2737// ::= <prefix> <data-member-prefix>
2738// extension ::= L
2739//
Erik Pilkington437202e2018-04-09 18:32:25 +00002740// <data-member-prefix> := <member source-name> [<template-args>] M
2741//
Erik Pilkington2808f772018-02-13 17:09:03 +00002742// <template-prefix> ::= <prefix> <template unqualified-name>
2743// ::= <template-param>
2744// ::= <substitution>
Erik Pilkingtone1d61622018-03-05 16:35:06 +00002745Node *Db::parseNestedName(NameState *State) {
Erik Pilkington2808f772018-02-13 17:09:03 +00002746 if (!consumeIf('N'))
2747 return nullptr;
2748
Erik Pilkingtone1d61622018-03-05 16:35:06 +00002749 Qualifiers CVTmp = parseCVQualifiers();
2750 if (State) State->CVQualifiers = CVTmp;
2751
2752 if (consumeIf('O')) {
2753 if (State) State->ReferenceQualifier = FrefQualRValue;
2754 } else if (consumeIf('R')) {
2755 if (State) State->ReferenceQualifier = FrefQualLValue;
2756 } else
2757 if (State) State->ReferenceQualifier = FrefQualNone;
Erik Pilkington2808f772018-02-13 17:09:03 +00002758
2759 Node *SoFar = nullptr;
2760 auto PushComponent = [&](Node *Comp) {
Erik Pilkington0df654b2018-04-12 20:41:06 +00002761 if (SoFar) SoFar = make<NestedName>(SoFar, Comp);
Erik Pilkington2808f772018-02-13 17:09:03 +00002762 else SoFar = Comp;
Erik Pilkingtone1d61622018-03-05 16:35:06 +00002763 if (State) State->EndsWithTemplateArgs = false;
Erik Pilkington2808f772018-02-13 17:09:03 +00002764 };
2765
2766 if (consumeIf("St"))
2767 SoFar = make<NameType>("std");
2768
2769 while (!consumeIf('E')) {
2770 consumeIf('L'); // extension
2771
Erik Pilkington437202e2018-04-09 18:32:25 +00002772 // <data-member-prefix> := <member source-name> [<template-args>] M
2773 if (consumeIf('M')) {
2774 if (SoFar == nullptr)
2775 return nullptr;
2776 continue;
2777 }
2778
Erik Pilkington2808f772018-02-13 17:09:03 +00002779 // ::= <template-param>
2780 if (look() == 'T') {
Erik Pilkingtonf26c8d12018-03-06 14:21:10 +00002781 Node *TP = parseTemplateParam();
Erik Pilkington2808f772018-02-13 17:09:03 +00002782 if (TP == nullptr)
2783 return nullptr;
2784 PushComponent(TP);
2785 Subs.push_back(SoFar);
2786 continue;
2787 }
2788
2789 // ::= <template-prefix> <template-args>
2790 if (look() == 'I') {
Erik Pilkington04f39852018-03-25 22:50:33 +00002791 Node *TA = parseTemplateArgs(State != nullptr);
Erik Pilkington2808f772018-02-13 17:09:03 +00002792 if (TA == nullptr || SoFar == nullptr)
2793 return nullptr;
2794 SoFar = make<NameWithTemplateArgs>(SoFar, TA);
Erik Pilkingtone1d61622018-03-05 16:35:06 +00002795 if (State) State->EndsWithTemplateArgs = true;
Erik Pilkington2808f772018-02-13 17:09:03 +00002796 Subs.push_back(SoFar);
2797 continue;
2798 }
2799
2800 // ::= <decltype>
2801 if (look() == 'D' && (look(1) == 't' || look(1) == 'T')) {
Erik Pilkingtone1d61622018-03-05 16:35:06 +00002802 Node *DT = parseDecltype();
Erik Pilkington2808f772018-02-13 17:09:03 +00002803 if (DT == nullptr)
2804 return nullptr;
2805 PushComponent(DT);
2806 Subs.push_back(SoFar);
2807 continue;
2808 }
2809
2810 // ::= <substitution>
2811 if (look() == 'S' && look(1) != 't') {
Erik Pilkingtonf26c8d12018-03-06 14:21:10 +00002812 Node *S = parseSubstitution();
Erik Pilkington2808f772018-02-13 17:09:03 +00002813 if (S == nullptr)
2814 return nullptr;
2815 PushComponent(S);
2816 if (SoFar != S)
2817 Subs.push_back(S);
2818 continue;
2819 }
2820
2821 // Parse an <unqualified-name> thats actually a <ctor-dtor-name>.
Erik Pilkingtondee4d0b2018-03-10 21:31:15 +00002822 if (look() == 'C' || (look() == 'D' && look(1) != 'C')) {
Erik Pilkington2808f772018-02-13 17:09:03 +00002823 if (SoFar == nullptr)
2824 return nullptr;
Erik Pilkingtone1d61622018-03-05 16:35:06 +00002825 Node *CtorDtor = parseCtorDtorName(SoFar, State);
Erik Pilkington2808f772018-02-13 17:09:03 +00002826 if (CtorDtor == nullptr)
2827 return nullptr;
2828 PushComponent(CtorDtor);
2829 SoFar = parseAbiTags(SoFar);
2830 if (SoFar == nullptr)
2831 return nullptr;
2832 Subs.push_back(SoFar);
2833 continue;
2834 }
2835
2836 // ::= <prefix> <unqualified-name>
Erik Pilkingtone1d61622018-03-05 16:35:06 +00002837 Node *N = parseUnqualifiedName(State);
Erik Pilkington2808f772018-02-13 17:09:03 +00002838 if (N == nullptr)
2839 return nullptr;
2840 PushComponent(N);
2841 Subs.push_back(SoFar);
2842 }
2843
2844 if (SoFar == nullptr || Subs.empty())
2845 return nullptr;
2846
2847 Subs.pop_back();
2848 return SoFar;
2849}
2850
Erik Pilkingtond0dd97d2018-03-06 14:21:08 +00002851// <simple-id> ::= <source-name> [ <template-args> ]
2852Node *Db::parseSimpleId() {
2853 Node *SN = parseSourceName(/*NameState=*/nullptr);
2854 if (SN == nullptr)
2855 return nullptr;
2856 if (look() == 'I') {
Erik Pilkingtonf26c8d12018-03-06 14:21:10 +00002857 Node *TA = parseTemplateArgs();
Erik Pilkingtond0dd97d2018-03-06 14:21:08 +00002858 if (TA == nullptr)
2859 return nullptr;
2860 return make<NameWithTemplateArgs>(SN, TA);
2861 }
2862 return SN;
2863}
2864
2865// <destructor-name> ::= <unresolved-type> # e.g., ~T or ~decltype(f())
2866// ::= <simple-id> # e.g., ~A<2*N>
2867Node *Db::parseDestructorName() {
2868 Node *Result;
2869 if (std::isdigit(look()))
2870 Result = parseSimpleId();
2871 else
2872 Result = parseUnresolvedType();
2873 if (Result == nullptr)
2874 return nullptr;
2875 return make<DtorName>(Result);
2876}
2877
2878// <unresolved-type> ::= <template-param>
2879// ::= <decltype>
2880// ::= <substitution>
2881Node *Db::parseUnresolvedType() {
2882 if (look() == 'T') {
Erik Pilkingtonf26c8d12018-03-06 14:21:10 +00002883 Node *TP = parseTemplateParam();
Erik Pilkingtond0dd97d2018-03-06 14:21:08 +00002884 if (TP == nullptr)
2885 return nullptr;
2886 Subs.push_back(TP);
2887 return TP;
2888 }
2889 if (look() == 'D') {
2890 Node *DT = parseDecltype();
2891 if (DT == nullptr)
2892 return nullptr;
2893 Subs.push_back(DT);
2894 return DT;
2895 }
Erik Pilkingtonf26c8d12018-03-06 14:21:10 +00002896 return parseSubstitution();
Erik Pilkingtond0dd97d2018-03-06 14:21:08 +00002897}
2898
2899// <base-unresolved-name> ::= <simple-id> # unresolved name
2900// extension ::= <operator-name> # unresolved operator-function-id
2901// extension ::= <operator-name> <template-args> # unresolved operator template-id
2902// ::= on <operator-name> # unresolved operator-function-id
2903// ::= on <operator-name> <template-args> # unresolved operator template-id
2904// ::= dn <destructor-name> # destructor or pseudo-destructor;
2905// # e.g. ~X or ~X<N-1>
2906Node *Db::parseBaseUnresolvedName() {
2907 if (std::isdigit(look()))
2908 return parseSimpleId();
2909
2910 if (consumeIf("dn"))
2911 return parseDestructorName();
2912
2913 consumeIf("on");
2914
2915 Node *Oper = parseOperatorName(/*NameState=*/nullptr);
2916 if (Oper == nullptr)
2917 return nullptr;
2918 if (look() == 'I') {
Erik Pilkingtonf26c8d12018-03-06 14:21:10 +00002919 Node *TA = parseTemplateArgs();
Erik Pilkingtond0dd97d2018-03-06 14:21:08 +00002920 if (TA == nullptr)
2921 return nullptr;
2922 return make<NameWithTemplateArgs>(Oper, TA);
2923 }
2924 return Oper;
2925}
2926
2927// <unresolved-name>
2928// extension ::= srN <unresolved-type> [<template-args>] <unresolved-qualifier-level>* E <base-unresolved-name>
2929// ::= [gs] <base-unresolved-name> # x or (with "gs") ::x
2930// ::= [gs] sr <unresolved-qualifier-level>+ E <base-unresolved-name>
2931// # A::x, N::y, A<T>::z; "gs" means leading "::"
2932// ::= sr <unresolved-type> <base-unresolved-name> # T::x / decltype(p)::x
2933// extension ::= sr <unresolved-type> <template-args> <base-unresolved-name>
2934// # T::N::x /decltype(p)::N::x
2935// (ignored) ::= srN <unresolved-type> <unresolved-qualifier-level>+ E <base-unresolved-name>
2936//
2937// <unresolved-qualifier-level> ::= <simple-id>
2938Node *Db::parseUnresolvedName() {
2939 Node *SoFar = nullptr;
2940
2941 // srN <unresolved-type> [<template-args>] <unresolved-qualifier-level>* E <base-unresolved-name>
2942 // srN <unresolved-type> <unresolved-qualifier-level>+ E <base-unresolved-name>
2943 if (consumeIf("srN")) {
2944 SoFar = parseUnresolvedType();
2945 if (SoFar == nullptr)
2946 return nullptr;
2947
2948 if (look() == 'I') {
Erik Pilkingtonf26c8d12018-03-06 14:21:10 +00002949 Node *TA = parseTemplateArgs();
Erik Pilkingtond0dd97d2018-03-06 14:21:08 +00002950 if (TA == nullptr)
2951 return nullptr;
2952 SoFar = make<NameWithTemplateArgs>(SoFar, TA);
2953 }
2954
2955 while (!consumeIf('E')) {
2956 Node *Qual = parseSimpleId();
2957 if (Qual == nullptr)
2958 return nullptr;
2959 SoFar = make<QualifiedName>(SoFar, Qual);
2960 }
2961
2962 Node *Base = parseBaseUnresolvedName();
2963 if (Base == nullptr)
2964 return nullptr;
2965 return make<QualifiedName>(SoFar, Base);
2966 }
2967
2968 bool Global = consumeIf("gs");
2969
2970 // [gs] <base-unresolved-name> # x or (with "gs") ::x
2971 if (!consumeIf("sr")) {
2972 SoFar = parseBaseUnresolvedName();
2973 if (SoFar == nullptr)
2974 return nullptr;
2975 if (Global)
2976 SoFar = make<GlobalQualifiedName>(SoFar);
2977 return SoFar;
2978 }
2979
2980 // [gs] sr <unresolved-qualifier-level>+ E <base-unresolved-name>
2981 if (std::isdigit(look())) {
2982 do {
2983 Node *Qual = parseSimpleId();
2984 if (Qual == nullptr)
2985 return nullptr;
2986 if (SoFar)
2987 SoFar = make<QualifiedName>(SoFar, Qual);
2988 else if (Global)
2989 SoFar = make<GlobalQualifiedName>(Qual);
2990 else
2991 SoFar = Qual;
2992 } while (!consumeIf('E'));
2993 }
2994 // sr <unresolved-type> <base-unresolved-name>
2995 // sr <unresolved-type> <template-args> <base-unresolved-name>
2996 else {
2997 SoFar = parseUnresolvedType();
2998 if (SoFar == nullptr)
2999 return nullptr;
3000
3001 if (look() == 'I') {
Erik Pilkingtonf26c8d12018-03-06 14:21:10 +00003002 Node *TA = parseTemplateArgs();
Erik Pilkingtond0dd97d2018-03-06 14:21:08 +00003003 if (TA == nullptr)
3004 return nullptr;
3005 SoFar = make<NameWithTemplateArgs>(SoFar, TA);
3006 }
3007 }
3008
3009 assert(SoFar != nullptr);
3010
3011 Node *Base = parseBaseUnresolvedName();
3012 if (Base == nullptr)
3013 return nullptr;
3014 return make<QualifiedName>(SoFar, Base);
3015}
3016
Erik Pilkington2808f772018-02-13 17:09:03 +00003017// <abi-tags> ::= <abi-tag> [<abi-tags>]
3018// <abi-tag> ::= B <source-name>
3019Node *Db::parseAbiTags(Node *N) {
3020 while (consumeIf('B')) {
3021 StringView SN = parseBareSourceName();
3022 if (SN.empty())
3023 return nullptr;
3024 N = make<AbiTagAttr>(N, SN);
3025 }
3026 return N;
3027}
3028
Erik Pilkingtonb679cfd2018-02-02 18:04:32 +00003029// <number> ::= [n] <non-negative decimal integer>
3030StringView Db::parseNumber(bool AllowNegative) {
3031 const char *Tmp = First;
3032 if (AllowNegative)
3033 consumeIf('n');
3034 if (numLeft() == 0 || !std::isdigit(*First))
3035 return StringView();
3036 while (numLeft() != 0 && std::isdigit(*First))
3037 ++First;
3038 return StringView(Tmp, First);
3039}
3040
Erik Pilkingtonf23deca2018-02-05 22:41:20 +00003041// <positive length number> ::= [0-9]*
3042bool Db::parsePositiveInteger(size_t *Out) {
3043 *Out = 0;
3044 if (look() < '0' || look() > '9')
3045 return true;
3046 while (look() >= '0' && look() <= '9') {
3047 *Out *= 10;
3048 *Out += static_cast<size_t>(consume() - '0');
3049 }
3050 return false;
3051}
3052
3053StringView Db::parseBareSourceName() {
3054 size_t Int = 0;
3055 if (parsePositiveInteger(&Int) || numLeft() < Int)
3056 return StringView();
3057 StringView R(First, First + Int);
3058 First += Int;
3059 return R;
3060}
3061
Erik Pilkingtonbdaf8822018-02-14 01:08:17 +00003062// <function-type> ::= [<CV-qualifiers>] [<exception-spec>] [Dx] F [Y] <bare-function-type> [<ref-qualifier>] E
Erik Pilkingtonf23deca2018-02-05 22:41:20 +00003063//
Erik Pilkingtonbdaf8822018-02-14 01:08:17 +00003064// <exception-spec> ::= Do # non-throwing exception-specification (e.g., noexcept, throw())
3065// ::= DO <expression> E # computed (instantiation-dependent) noexcept
3066// ::= Dw <type>+ E # dynamic exception specification with instantiation-dependent types
3067//
3068// <ref-qualifier> ::= R # & ref-qualifier
3069// <ref-qualifier> ::= O # && ref-qualifier
Erik Pilkingtonf23deca2018-02-05 22:41:20 +00003070Node *Db::parseFunctionType() {
Erik Pilkingtonbdaf8822018-02-14 01:08:17 +00003071 Qualifiers CVQuals = parseCVQualifiers();
Erik Pilkington7e027ac2018-02-14 01:08:20 +00003072
3073 Node *ExceptionSpec = nullptr;
3074 if (consumeIf("Do")) {
3075 ExceptionSpec = make<NameType>("noexcept");
3076 } else if (consumeIf("DO")) {
3077 Node *E = parseExpr();
3078 if (E == nullptr || !consumeIf('E'))
3079 return nullptr;
3080 ExceptionSpec = make<NoexceptSpec>(E);
3081 } else if (consumeIf("Dw")) {
3082 size_t SpecsBegin = Names.size();
3083 while (!consumeIf('E')) {
3084 Node *T = parseType();
3085 if (T == nullptr)
3086 return nullptr;
3087 Names.push_back(T);
3088 }
3089 ExceptionSpec =
3090 make<DynamicExceptionSpec>(popTrailingNodeArray(SpecsBegin));
3091 }
3092
3093 consumeIf("Dx"); // transaction safe
3094
Erik Pilkingtonf23deca2018-02-05 22:41:20 +00003095 if (!consumeIf('F'))
3096 return nullptr;
3097 consumeIf('Y'); // extern "C"
3098 Node *ReturnType = parseType();
3099 if (ReturnType == nullptr)
3100 return nullptr;
3101
3102 FunctionRefQual ReferenceQualifier = FrefQualNone;
3103 size_t ParamsBegin = Names.size();
3104 while (true) {
3105 if (consumeIf('E'))
3106 break;
3107 if (consumeIf('v'))
3108 continue;
3109 if (consumeIf("RE")) {
3110 ReferenceQualifier = FrefQualLValue;
3111 break;
3112 }
3113 if (consumeIf("OE")) {
3114 ReferenceQualifier = FrefQualRValue;
3115 break;
3116 }
3117 Node *T = parseType();
3118 if (T == nullptr)
3119 return nullptr;
3120 Names.push_back(T);
3121 }
3122
3123 NodeArray Params = popTrailingNodeArray(ParamsBegin);
Erik Pilkington7e027ac2018-02-14 01:08:20 +00003124 return make<FunctionType>(ReturnType, Params, CVQuals,
3125 ReferenceQualifier, ExceptionSpec);
Erik Pilkingtonf23deca2018-02-05 22:41:20 +00003126}
3127
3128// extension:
3129// <vector-type> ::= Dv <positive dimension number> _ <extended element type>
3130// ::= Dv [<dimension expression>] _ <element type>
3131// <extended element type> ::= <element type>
3132// ::= p # AltiVec vector pixel
3133Node *Db::parseVectorType() {
3134 if (!consumeIf("Dv"))
3135 return nullptr;
3136 if (look() >= '1' && look() <= '9') {
3137 StringView DimensionNumber = parseNumber();
3138 if (!consumeIf('_'))
3139 return nullptr;
3140 if (consumeIf('p'))
3141 return make<VectorType>(DimensionNumber);
3142 Node *ElemType = parseType();
3143 if (ElemType == nullptr)
3144 return nullptr;
3145 return make<VectorType>(ElemType, DimensionNumber);
3146 }
3147
3148 if (!consumeIf('_')) {
3149 Node *DimExpr = parseExpr();
3150 if (!DimExpr)
3151 return nullptr;
3152 if (!consumeIf('_'))
3153 return nullptr;
3154 Node *ElemType = parseType();
3155 if (!ElemType)
3156 return nullptr;
3157 return make<VectorType>(ElemType, DimExpr);
3158 }
3159 Node *ElemType = parseType();
3160 if (!ElemType)
3161 return nullptr;
3162 return make<VectorType>(ElemType, StringView());
3163}
3164
3165// <decltype> ::= Dt <expression> E # decltype of an id-expression or class member access (C++0x)
3166// ::= DT <expression> E # decltype of an expression (C++0x)
3167Node *Db::parseDecltype() {
3168 if (!consumeIf('D'))
3169 return nullptr;
3170 if (!consumeIf('t') && !consumeIf('T'))
3171 return nullptr;
3172 Node *E = parseExpr();
3173 if (E == nullptr)
3174 return nullptr;
3175 if (!consumeIf('E'))
3176 return nullptr;
3177 return make<EnclosingExpr>("decltype(", E, ")");
3178}
3179
3180// <array-type> ::= A <positive dimension number> _ <element type>
3181// ::= A [<dimension expression>] _ <element type>
3182Node *Db::parseArrayType() {
3183 if (!consumeIf('A'))
3184 return nullptr;
3185
3186 if (std::isdigit(look())) {
3187 StringView Dimension = parseNumber();
3188 if (!consumeIf('_'))
3189 return nullptr;
3190 Node *Ty = parseType();
3191 if (Ty == nullptr)
3192 return nullptr;
3193 return make<ArrayType>(Ty, Dimension);
3194 }
3195
3196 if (!consumeIf('_')) {
3197 Node *DimExpr = parseExpr();
3198 if (DimExpr == nullptr)
3199 return nullptr;
3200 if (!consumeIf('_'))
3201 return nullptr;
3202 Node *ElementType = parseType();
3203 if (ElementType == nullptr)
3204 return nullptr;
3205 return make<ArrayType>(ElementType, DimExpr);
3206 }
3207
3208 Node *Ty = parseType();
3209 if (Ty == nullptr)
3210 return nullptr;
3211 return make<ArrayType>(Ty);
3212}
3213
3214// <pointer-to-member-type> ::= M <class type> <member type>
3215Node *Db::parsePointerToMemberType() {
3216 if (!consumeIf('M'))
3217 return nullptr;
3218 Node *ClassType = parseType();
3219 if (ClassType == nullptr)
3220 return nullptr;
3221 Node *MemberType = parseType();
3222 if (MemberType == nullptr)
3223 return nullptr;
3224 return make<PointerToMemberType>(ClassType, MemberType);
3225}
3226
3227// <class-enum-type> ::= <name> # non-dependent type name, dependent type name, or dependent typename-specifier
3228// ::= Ts <name> # dependent elaborated type specifier using 'struct' or 'class'
3229// ::= Tu <name> # dependent elaborated type specifier using 'union'
3230// ::= Te <name> # dependent elaborated type specifier using 'enum'
3231Node *Db::parseClassEnumType() {
Erik Pilkington13fb7dc2018-02-13 00:15:53 +00003232 StringView ElabSpef;
3233 if (consumeIf("Ts"))
3234 ElabSpef = "struct";
3235 else if (consumeIf("Tu"))
3236 ElabSpef = "union";
3237 else if (consumeIf("Te"))
3238 ElabSpef = "enum";
3239
Erik Pilkingtone1d61622018-03-05 16:35:06 +00003240 Node *Name = parseName();
Erik Pilkington13fb7dc2018-02-13 00:15:53 +00003241 if (Name == nullptr)
3242 return nullptr;
3243
3244 if (!ElabSpef.empty())
3245 return make<ElaboratedTypeSpefType>(ElabSpef, Name);
3246
3247 return Name;
Erik Pilkingtonf23deca2018-02-05 22:41:20 +00003248}
3249
Erik Pilkingtoncf29d3b2018-02-13 00:15:46 +00003250// <qualified-type> ::= <qualifiers> <type>
3251// <qualifiers> ::= <extended-qualifier>* <CV-qualifiers>
3252// <extended-qualifier> ::= U <source-name> [<template-args>] # vendor extended type qualifier
Erik Pilkingtonbdaf8822018-02-14 01:08:17 +00003253Node *Db::parseQualifiedType() {
Erik Pilkingtoncf29d3b2018-02-13 00:15:46 +00003254 if (consumeIf('U')) {
3255 StringView Qual = parseBareSourceName();
3256 if (Qual.empty())
3257 return nullptr;
3258
3259 // FIXME parse the optional <template-args> here!
3260
3261 // extension ::= U <objc-name> <objc-type> # objc-type<identifier>
3262 if (Qual.startsWith("objcproto")) {
3263 StringView ProtoSourceName = Qual.dropFront(std::strlen("objcproto"));
3264 StringView Proto;
3265 {
3266 SwapAndRestore<const char *> SaveFirst(First, ProtoSourceName.begin()),
3267 SaveLast(Last, ProtoSourceName.end());
3268 Proto = parseBareSourceName();
3269 }
3270 if (Proto.empty())
3271 return nullptr;
Erik Pilkingtonbdaf8822018-02-14 01:08:17 +00003272 Node *Child = parseQualifiedType();
Erik Pilkingtoncf29d3b2018-02-13 00:15:46 +00003273 if (Child == nullptr)
3274 return nullptr;
3275 return make<ObjCProtoName>(Child, Proto);
3276 }
3277
Erik Pilkingtonbdaf8822018-02-14 01:08:17 +00003278 Node *Child = parseQualifiedType();
Erik Pilkingtoncf29d3b2018-02-13 00:15:46 +00003279 if (Child == nullptr)
3280 return nullptr;
3281 return make<VendorExtQualType>(Child, Qual);
3282 }
3283
3284 Qualifiers Quals = parseCVQualifiers();
Erik Pilkingtoncf29d3b2018-02-13 00:15:46 +00003285 Node *Ty = parseType();
3286 if (Ty == nullptr)
3287 return nullptr;
Erik Pilkingtonbdaf8822018-02-14 01:08:17 +00003288 if (Quals != QualNone)
3289 Ty = make<QualType>(Ty, Quals);
Erik Pilkingtoncf29d3b2018-02-13 00:15:46 +00003290 return Ty;
3291}
3292
Erik Pilkingtonf23deca2018-02-05 22:41:20 +00003293// <type> ::= <builtin-type>
3294// ::= <qualified-type>
3295// ::= <function-type>
3296// ::= <class-enum-type>
3297// ::= <array-type>
3298// ::= <pointer-to-member-type>
3299// ::= <template-param>
3300// ::= <template-template-param> <template-args>
3301// ::= <decltype>
3302// ::= P <type> # pointer
3303// ::= R <type> # l-value reference
3304// ::= O <type> # r-value reference (C++11)
3305// ::= C <type> # complex pair (C99)
3306// ::= G <type> # imaginary (C99)
3307// ::= <substitution> # See Compression below
3308// extension ::= U <objc-name> <objc-type> # objc-type<identifier>
3309// extension ::= <vector-type> # <vector-type> starts with Dv
3310//
3311// <objc-name> ::= <k0 number> objcproto <k1 number> <identifier> # k0 = 9 + <number of digits in k1> + k1
3312// <objc-type> ::= <source-name> # PU<11+>objcproto 11objc_object<source-name> 11objc_object -> id<source-name>
3313Node *Db::parseType() {
3314 Node *Result = nullptr;
3315
3316 switch (look()) {
3317 // ::= <qualified-type>
3318 case 'r':
3319 case 'V':
Erik Pilkingtonbdaf8822018-02-14 01:08:17 +00003320 case 'K': {
3321 unsigned AfterQuals = 0;
3322 if (look(AfterQuals) == 'r') ++AfterQuals;
3323 if (look(AfterQuals) == 'V') ++AfterQuals;
3324 if (look(AfterQuals) == 'K') ++AfterQuals;
Erik Pilkington7e027ac2018-02-14 01:08:20 +00003325
3326 if (look(AfterQuals) == 'F' ||
3327 (look(AfterQuals) == 'D' &&
3328 (look(AfterQuals + 1) == 'o' || look(AfterQuals + 1) == 'O' ||
3329 look(AfterQuals + 1) == 'w' || look(AfterQuals + 1) == 'x'))) {
Erik Pilkingtonbdaf8822018-02-14 01:08:17 +00003330 Result = parseFunctionType();
3331 break;
3332 }
3333 _LIBCPP_FALLTHROUGH();
3334 }
Erik Pilkingtoncf29d3b2018-02-13 00:15:46 +00003335 case 'U': {
Erik Pilkingtonbdaf8822018-02-14 01:08:17 +00003336 Result = parseQualifiedType();
Erik Pilkingtonf23deca2018-02-05 22:41:20 +00003337 break;
3338 }
Erik Pilkingtonf23deca2018-02-05 22:41:20 +00003339 // <builtin-type> ::= v # void
3340 case 'v':
3341 ++First;
3342 return make<NameType>("void");
3343 // ::= w # wchar_t
3344 case 'w':
3345 ++First;
3346 return make<NameType>("wchar_t");
3347 // ::= b # bool
3348 case 'b':
3349 ++First;
3350 return make<NameType>("bool");
3351 // ::= c # char
3352 case 'c':
3353 ++First;
3354 return make<NameType>("char");
3355 // ::= a # signed char
3356 case 'a':
3357 ++First;
3358 return make<NameType>("signed char");
3359 // ::= h # unsigned char
3360 case 'h':
3361 ++First;
3362 return make<NameType>("unsigned char");
3363 // ::= s # short
3364 case 's':
3365 ++First;
3366 return make<NameType>("short");
3367 // ::= t # unsigned short
3368 case 't':
3369 ++First;
3370 return make<NameType>("unsigned short");
3371 // ::= i # int
3372 case 'i':
3373 ++First;
3374 return make<NameType>("int");
3375 // ::= j # unsigned int
3376 case 'j':
3377 ++First;
3378 return make<NameType>("unsigned int");
3379 // ::= l # long
3380 case 'l':
3381 ++First;
3382 return make<NameType>("long");
3383 // ::= m # unsigned long
3384 case 'm':
3385 ++First;
3386 return make<NameType>("unsigned long");
3387 // ::= x # long long, __int64
3388 case 'x':
3389 ++First;
3390 return make<NameType>("long long");
3391 // ::= y # unsigned long long, __int64
3392 case 'y':
3393 ++First;
3394 return make<NameType>("unsigned long long");
3395 // ::= n # __int128
3396 case 'n':
3397 ++First;
3398 return make<NameType>("__int128");
3399 // ::= o # unsigned __int128
3400 case 'o':
3401 ++First;
3402 return make<NameType>("unsigned __int128");
3403 // ::= f # float
3404 case 'f':
3405 ++First;
3406 return make<NameType>("float");
3407 // ::= d # double
3408 case 'd':
3409 ++First;
3410 return make<NameType>("double");
3411 // ::= e # long double, __float80
3412 case 'e':
3413 ++First;
3414 return make<NameType>("long double");
3415 // ::= g # __float128
3416 case 'g':
3417 ++First;
3418 return make<NameType>("__float128");
3419 // ::= z # ellipsis
3420 case 'z':
3421 ++First;
3422 return make<NameType>("...");
3423
3424 // <builtin-type> ::= u <source-name> # vendor extended type
3425 case 'u': {
3426 ++First;
3427 StringView Res = parseBareSourceName();
3428 if (Res.empty())
3429 return nullptr;
3430 return make<NameType>(Res);
3431 }
3432 case 'D':
3433 switch (look(1)) {
3434 // ::= Dd # IEEE 754r decimal floating point (64 bits)
3435 case 'd':
3436 First += 2;
3437 return make<NameType>("decimal64");
3438 // ::= De # IEEE 754r decimal floating point (128 bits)
3439 case 'e':
3440 First += 2;
3441 return make<NameType>("decimal128");
3442 // ::= Df # IEEE 754r decimal floating point (32 bits)
3443 case 'f':
3444 First += 2;
3445 return make<NameType>("decimal32");
3446 // ::= Dh # IEEE 754r half-precision floating point (16 bits)
3447 case 'h':
3448 First += 2;
3449 return make<NameType>("decimal16");
3450 // ::= Di # char32_t
3451 case 'i':
3452 First += 2;
3453 return make<NameType>("char32_t");
3454 // ::= Ds # char16_t
3455 case 's':
3456 First += 2;
3457 return make<NameType>("char16_t");
3458 // ::= Da # auto (in dependent new-expressions)
3459 case 'a':
3460 First += 2;
3461 return make<NameType>("auto");
3462 // ::= Dc # decltype(auto)
3463 case 'c':
3464 First += 2;
3465 return make<NameType>("decltype(auto)");
3466 // ::= Dn # std::nullptr_t (i.e., decltype(nullptr))
3467 case 'n':
3468 First += 2;
3469 return make<NameType>("std::nullptr_t");
3470
3471 // ::= <decltype>
3472 case 't':
3473 case 'T': {
3474 Result = parseDecltype();
3475 break;
3476 }
3477 // extension ::= <vector-type> # <vector-type> starts with Dv
3478 case 'v': {
3479 Result = parseVectorType();
3480 break;
3481 }
3482 // ::= Dp <type> # pack expansion (C++0x)
3483 case 'p': {
3484 First += 2;
3485 Node *Child = parseType();
3486 if (!Child)
3487 return nullptr;
3488 Result = make<ParameterPackExpansion>(Child);
3489 break;
3490 }
Erik Pilkington7e027ac2018-02-14 01:08:20 +00003491 // Exception specifier on a function type.
3492 case 'o':
3493 case 'O':
3494 case 'w':
3495 // Transaction safe function type.
3496 case 'x':
3497 Result = parseFunctionType();
3498 break;
Erik Pilkingtonf23deca2018-02-05 22:41:20 +00003499 }
3500 break;
3501 // ::= <function-type>
3502 case 'F': {
3503 Result = parseFunctionType();
3504 break;
3505 }
3506 // ::= <array-type>
3507 case 'A': {
3508 Result = parseArrayType();
3509 break;
3510 }
3511 // ::= <pointer-to-member-type>
3512 case 'M': {
3513 Result = parsePointerToMemberType();
3514 break;
3515 }
3516 // ::= <template-param>
3517 case 'T': {
Erik Pilkington13fb7dc2018-02-13 00:15:53 +00003518 // This could be an elaborate type specifier on a <class-enum-type>.
3519 if (look(1) == 's' || look(1) == 'u' || look(1) == 'e') {
3520 Result = parseClassEnumType();
3521 break;
3522 }
3523
Erik Pilkingtonf26c8d12018-03-06 14:21:10 +00003524 Result = parseTemplateParam();
Erik Pilkingtonf23deca2018-02-05 22:41:20 +00003525 if (Result == nullptr)
3526 return nullptr;
3527
3528 // Result could be either of:
3529 // <type> ::= <template-param>
3530 // <type> ::= <template-template-param> <template-args>
3531 //
3532 // <template-template-param> ::= <template-param>
3533 // ::= <substitution>
3534 //
3535 // If this is followed by some <template-args>, and we're permitted to
3536 // parse them, take the second production.
3537
3538 if (TryToParseTemplateArgs && look() == 'I') {
Erik Pilkingtonf26c8d12018-03-06 14:21:10 +00003539 Node *TA = parseTemplateArgs();
Erik Pilkingtonf23deca2018-02-05 22:41:20 +00003540 if (TA == nullptr)
3541 return nullptr;
3542 Result = make<NameWithTemplateArgs>(Result, TA);
3543 }
3544 break;
3545 }
3546 // ::= P <type> # pointer
3547 case 'P': {
3548 ++First;
3549 Node *Ptr = parseType();
3550 if (Ptr == nullptr)
3551 return nullptr;
3552 Result = make<PointerType>(Ptr);
3553 break;
3554 }
3555 // ::= R <type> # l-value reference
3556 case 'R': {
3557 ++First;
3558 Node *Ref = parseType();
3559 if (Ref == nullptr)
3560 return nullptr;
3561 Result = make<LValueReferenceType>(Ref);
3562 break;
3563 }
3564 // ::= O <type> # r-value reference (C++11)
3565 case 'O': {
3566 ++First;
3567 Node *Ref = parseType();
3568 if (Ref == nullptr)
3569 return nullptr;
3570 Result = make<RValueReferenceType>(Ref);
3571 break;
3572 }
3573 // ::= C <type> # complex pair (C99)
3574 case 'C': {
3575 ++First;
3576 Node *P = parseType();
3577 if (P == nullptr)
3578 return nullptr;
3579 Result = make<PostfixQualifiedType>(P, " complex");
3580 break;
3581 }
3582 // ::= G <type> # imaginary (C99)
3583 case 'G': {
3584 ++First;
3585 Node *P = parseType();
3586 if (P == nullptr)
3587 return P;
3588 Result = make<PostfixQualifiedType>(P, " imaginary");
3589 break;
3590 }
3591 // ::= <substitution> # See Compression below
3592 case 'S': {
3593 if (look(1) && look(1) != 't') {
Erik Pilkingtonf26c8d12018-03-06 14:21:10 +00003594 Node *Sub = parseSubstitution();
Erik Pilkingtonf23deca2018-02-05 22:41:20 +00003595 if (Sub == nullptr)
3596 return nullptr;
3597
3598 // Sub could be either of:
3599 // <type> ::= <substitution>
3600 // <type> ::= <template-template-param> <template-args>
3601 //
3602 // <template-template-param> ::= <template-param>
3603 // ::= <substitution>
3604 //
3605 // If this is followed by some <template-args>, and we're permitted to
3606 // parse them, take the second production.
3607
3608 if (TryToParseTemplateArgs && look() == 'I') {
Erik Pilkingtonf26c8d12018-03-06 14:21:10 +00003609 Node *TA = parseTemplateArgs();
Erik Pilkingtonf23deca2018-02-05 22:41:20 +00003610 if (TA == nullptr)
3611 return nullptr;
3612 Result = make<NameWithTemplateArgs>(Sub, TA);
3613 break;
3614 }
3615
3616 // If all we parsed was a substitution, don't re-insert into the
3617 // substitution table.
3618 return Sub;
3619 }
3620 _LIBCPP_FALLTHROUGH();
3621 }
3622 // ::= <class-enum-type>
3623 default: {
3624 Result = parseClassEnumType();
3625 break;
3626 }
3627 }
3628
3629 // If we parsed a type, insert it into the substitution table. Note that all
3630 // <builtin-type>s and <substitution>s have already bailed out, because they
3631 // don't get substitutions.
3632 if (Result != nullptr)
3633 Subs.push_back(Result);
3634 return Result;
3635}
3636
Erik Pilkingtonb679cfd2018-02-02 18:04:32 +00003637Node *Db::parsePrefixExpr(StringView Kind) {
3638 Node *E = parseExpr();
3639 if (E == nullptr)
3640 return nullptr;
3641 return make<PrefixExpr>(Kind, E);
3642}
3643
3644Node *Db::parseBinaryExpr(StringView Kind) {
3645 Node *LHS = parseExpr();
3646 if (LHS == nullptr)
3647 return nullptr;
3648 Node *RHS = parseExpr();
3649 if (RHS == nullptr)
3650 return nullptr;
3651 return make<BinaryExpr>(LHS, Kind, RHS);
3652}
3653
3654Node *Db::parseIntegerLiteral(StringView Lit) {
3655 StringView Tmp = parseNumber(true);
3656 if (!Tmp.empty() && consumeIf('E'))
3657 return make<IntegerExpr>(Lit, Tmp);
3658 return nullptr;
3659}
3660
Erik Pilkington2808f772018-02-13 17:09:03 +00003661// <CV-Qualifiers> ::= [r] [V] [K]
Erik Pilkingtonb679cfd2018-02-02 18:04:32 +00003662Qualifiers Db::parseCVQualifiers() {
3663 Qualifiers CVR = QualNone;
3664 if (consumeIf('r'))
3665 addQualifiers(CVR, QualRestrict);
3666 if (consumeIf('V'))
3667 addQualifiers(CVR, QualVolatile);
3668 if (consumeIf('K'))
3669 addQualifiers(CVR, QualConst);
3670 return CVR;
3671}
3672
3673// <function-param> ::= fp <top-level CV-Qualifiers> _ # L == 0, first parameter
3674// ::= fp <top-level CV-Qualifiers> <parameter-2 non-negative number> _ # L == 0, second and later parameters
3675// ::= fL <L-1 non-negative number> p <top-level CV-Qualifiers> _ # L > 0, first parameter
3676// ::= fL <L-1 non-negative number> p <top-level CV-Qualifiers> <parameter-2 non-negative number> _ # L > 0, second and later parameters
3677Node *Db::parseFunctionParam() {
3678 if (consumeIf("fp")) {
3679 parseCVQualifiers();
3680 StringView Num = parseNumber();
3681 if (!consumeIf('_'))
3682 return nullptr;
3683 return make<FunctionParam>(Num);
3684 }
3685 if (consumeIf("fL")) {
3686 if (parseNumber().empty())
3687 return nullptr;
3688 if (!consumeIf('p'))
3689 return nullptr;
3690 parseCVQualifiers();
3691 StringView Num = parseNumber();
3692 if (!consumeIf('_'))
3693 return nullptr;
3694 return make<FunctionParam>(Num);
3695 }
3696 return nullptr;
3697}
3698
3699// [gs] nw <expression>* _ <type> E # new (expr-list) type
3700// [gs] nw <expression>* _ <type> <initializer> # new (expr-list) type (init)
3701// [gs] na <expression>* _ <type> E # new[] (expr-list) type
3702// [gs] na <expression>* _ <type> <initializer> # new[] (expr-list) type (init)
3703// <initializer> ::= pi <expression>* E # parenthesized initialization
3704Node *Db::parseNewExpr() {
3705 bool Global = consumeIf("gs");
3706 bool IsArray = look(1) == 'a';
3707 if (!consumeIf("nw") && !consumeIf("na"))
3708 return nullptr;
3709 size_t Exprs = Names.size();
3710 while (!consumeIf('_')) {
3711 Node *Ex = parseExpr();
3712 if (Ex == nullptr)
3713 return nullptr;
3714 Names.push_back(Ex);
3715 }
3716 NodeArray ExprList = popTrailingNodeArray(Exprs);
Erik Pilkingtonf23deca2018-02-05 22:41:20 +00003717 Node *Ty = parseType();
Erik Pilkingtonb679cfd2018-02-02 18:04:32 +00003718 if (Ty == nullptr)
3719 return Ty;
3720 if (consumeIf("pi")) {
3721 size_t InitsBegin = Names.size();
3722 while (!consumeIf('E')) {
3723 Node *Init = parseExpr();
3724 if (Init == nullptr)
3725 return Init;
3726 Names.push_back(Init);
3727 }
3728 NodeArray Inits = popTrailingNodeArray(InitsBegin);
3729 return make<NewExpr>(ExprList, Ty, Inits, Global, IsArray);
3730 } else if (!consumeIf('E'))
3731 return nullptr;
3732 return make<NewExpr>(ExprList, Ty, NodeArray(), Global, IsArray);
3733}
3734
3735// cv <type> <expression> # conversion with one argument
3736// cv <type> _ <expression>* E # conversion with a different number of arguments
3737Node *Db::parseConversionExpr() {
3738 if (!consumeIf("cv"))
3739 return nullptr;
3740 Node *Ty;
3741 {
3742 SwapAndRestore<bool> SaveTemp(TryToParseTemplateArgs, false);
Erik Pilkingtonf23deca2018-02-05 22:41:20 +00003743 Ty = parseType();
Erik Pilkingtonb679cfd2018-02-02 18:04:32 +00003744 }
3745
3746 if (Ty == nullptr)
3747 return nullptr;
3748
3749 if (consumeIf('_')) {
3750 size_t ExprsBegin = Names.size();
3751 while (!consumeIf('E')) {
3752 Node *E = parseExpr();
3753 if (E == nullptr)
3754 return E;
3755 Names.push_back(E);
3756 }
3757 NodeArray Exprs = popTrailingNodeArray(ExprsBegin);
3758 return make<ConversionExpr>(Ty, Exprs);
3759 }
3760
3761 Node *E[1] = {parseExpr()};
3762 if (E[0] == nullptr)
3763 return nullptr;
3764 return make<ConversionExpr>(Ty, makeNodeArray(E, E + 1));
3765}
3766
3767// <expr-primary> ::= L <type> <value number> E # integer literal
3768// ::= L <type> <value float> E # floating literal
3769// ::= L <string type> E # string literal
3770// ::= L <nullptr type> E # nullptr literal (i.e., "LDnE")
3771// FIXME: ::= L <type> <real-part float> _ <imag-part float> E # complex floating point literal (C 2000)
3772// ::= L <mangled-name> E # external name
3773Node *Db::parseExprPrimary() {
3774 if (!consumeIf('L'))
3775 return nullptr;
3776 switch (look()) {
3777 case 'w':
3778 ++First;
3779 return parseIntegerLiteral("wchar_t");
3780 case 'b':
3781 if (consumeIf("b0E"))
3782 return make<BoolExpr>(0);
3783 if (consumeIf("b1E"))
3784 return make<BoolExpr>(1);
3785 return nullptr;
3786 case 'c':
3787 ++First;
3788 return parseIntegerLiteral("char");
3789 case 'a':
3790 ++First;
3791 return parseIntegerLiteral("signed char");
3792 case 'h':
3793 ++First;
3794 return parseIntegerLiteral("unsigned char");
3795 case 's':
3796 ++First;
3797 return parseIntegerLiteral("short");
3798 case 't':
3799 ++First;
3800 return parseIntegerLiteral("unsigned short");
3801 case 'i':
3802 ++First;
3803 return parseIntegerLiteral("");
3804 case 'j':
3805 ++First;
3806 return parseIntegerLiteral("u");
3807 case 'l':
3808 ++First;
3809 return parseIntegerLiteral("l");
3810 case 'm':
3811 ++First;
3812 return parseIntegerLiteral("ul");
3813 case 'x':
3814 ++First;
3815 return parseIntegerLiteral("ll");
3816 case 'y':
3817 ++First;
3818 return parseIntegerLiteral("ull");
3819 case 'n':
3820 ++First;
3821 return parseIntegerLiteral("__int128");
3822 case 'o':
3823 ++First;
3824 return parseIntegerLiteral("unsigned __int128");
3825 case 'f':
3826 ++First;
3827 return parseFloatingLiteral<float>();
3828 case 'd':
3829 ++First;
3830 return parseFloatingLiteral<double>();
3831 case 'e':
3832 ++First;
3833 return parseFloatingLiteral<long double>();
3834 case '_':
3835 if (consumeIf("_Z")) {
Erik Pilkingtone1d61622018-03-05 16:35:06 +00003836 Node *R = parseEncoding();
Erik Pilkingtonb679cfd2018-02-02 18:04:32 +00003837 if (R != nullptr && consumeIf('E'))
3838 return R;
3839 }
3840 return nullptr;
3841 case 'T':
3842 // Invalid mangled name per
3843 // http://sourcerytools.com/pipermail/cxx-abi-dev/2011-August/002422.html
3844 return nullptr;
3845 default: {
3846 // might be named type
Erik Pilkingtonf23deca2018-02-05 22:41:20 +00003847 Node *T = parseType();
Erik Pilkingtonb679cfd2018-02-02 18:04:32 +00003848 if (T == nullptr)
3849 return nullptr;
3850 StringView N = parseNumber();
3851 if (!N.empty()) {
3852 if (!consumeIf('E'))
3853 return nullptr;
3854 return make<IntegerCastExpr>(T, N);
3855 }
3856 if (consumeIf('E'))
3857 return T;
3858 return nullptr;
3859 }
3860 }
3861}
3862
Erik Pilkington88a1cf62018-02-13 00:15:56 +00003863// <braced-expression> ::= <expression>
3864// ::= di <field source-name> <braced-expression> # .name = expr
3865// ::= dx <index expression> <braced-expression> # [expr] = expr
3866// ::= dX <range begin expression> <range end expression> <braced-expression>
3867Node *Db::parseBracedExpr() {
3868 if (look() == 'd') {
3869 switch (look(1)) {
3870 case 'i': {
3871 First += 2;
Erik Pilkingtone1d61622018-03-05 16:35:06 +00003872 Node *Field = parseSourceName(/*NameState=*/nullptr);
Erik Pilkington88a1cf62018-02-13 00:15:56 +00003873 if (Field == nullptr)
3874 return nullptr;
3875 Node *Init = parseBracedExpr();
3876 if (Init == nullptr)
3877 return nullptr;
3878 return make<BracedExpr>(Field, Init, /*isArray=*/false);
3879 }
3880 case 'x': {
3881 First += 2;
3882 Node *Index = parseExpr();
3883 if (Index == nullptr)
3884 return nullptr;
3885 Node *Init = parseBracedExpr();
3886 if (Init == nullptr)
3887 return nullptr;
3888 return make<BracedExpr>(Index, Init, /*isArray=*/true);
3889 }
3890 case 'X': {
3891 First += 2;
3892 Node *RangeBegin = parseExpr();
3893 if (RangeBegin == nullptr)
3894 return nullptr;
3895 Node *RangeEnd = parseExpr();
3896 if (RangeEnd == nullptr)
3897 return nullptr;
3898 Node *Init = parseBracedExpr();
3899 if (Init == nullptr)
3900 return nullptr;
3901 return make<BracedRangeExpr>(RangeBegin, RangeEnd, Init);
3902 }
3903 }
3904 }
3905 return parseExpr();
3906}
3907
Erik Pilkington967b00e2018-04-09 18:33:01 +00003908// (not yet in the spec)
3909// <fold-expr> ::= fL <binary-operator-name> <expression> <expression>
3910// ::= fR <binary-operator-name> <expression> <expression>
3911// ::= fl <binary-operator-name> <expression>
3912// ::= fr <binary-operator-name> <expression>
3913Node *Db::parseFoldExpr() {
3914 if (!consumeIf('f'))
3915 return nullptr;
3916
3917 char FoldKind = look();
3918 bool IsLeftFold, HasInitializer;
3919 HasInitializer = FoldKind == 'L' || FoldKind == 'R';
3920 if (FoldKind == 'l' || FoldKind == 'L')
3921 IsLeftFold = true;
3922 else if (FoldKind == 'r' || FoldKind == 'R')
3923 IsLeftFold = false;
3924 else
3925 return nullptr;
3926 ++First;
3927
3928 // FIXME: This map is duplicated in parseOperatorName and parseExpr.
3929 StringView OperatorName;
3930 if (consumeIf("aa")) OperatorName = "&&";
3931 else if (consumeIf("an")) OperatorName = "&";
3932 else if (consumeIf("aN")) OperatorName = "&=";
3933 else if (consumeIf("aS")) OperatorName = "=";
3934 else if (consumeIf("cm")) OperatorName = ",";
3935 else if (consumeIf("ds")) OperatorName = ".*";
3936 else if (consumeIf("dv")) OperatorName = "/";
3937 else if (consumeIf("dV")) OperatorName = "/=";
3938 else if (consumeIf("eo")) OperatorName = "^";
3939 else if (consumeIf("eO")) OperatorName = "^=";
3940 else if (consumeIf("eq")) OperatorName = "==";
3941 else if (consumeIf("ge")) OperatorName = ">=";
3942 else if (consumeIf("gt")) OperatorName = ">";
3943 else if (consumeIf("le")) OperatorName = "<=";
3944 else if (consumeIf("ls")) OperatorName = "<<";
3945 else if (consumeIf("lS")) OperatorName = "<<=";
3946 else if (consumeIf("lt")) OperatorName = "<";
3947 else if (consumeIf("mi")) OperatorName = "-";
3948 else if (consumeIf("mI")) OperatorName = "-=";
3949 else if (consumeIf("ml")) OperatorName = "*";
3950 else if (consumeIf("mL")) OperatorName = "*=";
3951 else if (consumeIf("ne")) OperatorName = "!=";
3952 else if (consumeIf("oo")) OperatorName = "||";
3953 else if (consumeIf("or")) OperatorName = "|";
3954 else if (consumeIf("oR")) OperatorName = "|=";
3955 else if (consumeIf("pl")) OperatorName = "+";
3956 else if (consumeIf("pL")) OperatorName = "+=";
3957 else if (consumeIf("rm")) OperatorName = "%";
3958 else if (consumeIf("rM")) OperatorName = "%=";
3959 else if (consumeIf("rs")) OperatorName = ">>";
3960 else if (consumeIf("rS")) OperatorName = ">>=";
3961 else return nullptr;
3962
3963 Node *Pack = parseExpr(), *Init = nullptr;
3964 if (Pack == nullptr)
3965 return nullptr;
3966 if (HasInitializer) {
3967 Init = parseExpr();
3968 if (Init == nullptr)
3969 return nullptr;
3970 }
3971
3972 if (IsLeftFold && Init)
3973 std::swap(Pack, Init);
3974
3975 return make<FoldExpr>(IsLeftFold, OperatorName, Pack, Init);
3976}
3977
Erik Pilkingtonb679cfd2018-02-02 18:04:32 +00003978// <expression> ::= <unary operator-name> <expression>
3979// ::= <binary operator-name> <expression> <expression>
3980// ::= <ternary operator-name> <expression> <expression> <expression>
3981// ::= cl <expression>+ E # call
3982// ::= cv <type> <expression> # conversion with one argument
3983// ::= cv <type> _ <expression>* E # conversion with a different number of arguments
3984// ::= [gs] nw <expression>* _ <type> E # new (expr-list) type
3985// ::= [gs] nw <expression>* _ <type> <initializer> # new (expr-list) type (init)
3986// ::= [gs] na <expression>* _ <type> E # new[] (expr-list) type
3987// ::= [gs] na <expression>* _ <type> <initializer> # new[] (expr-list) type (init)
3988// ::= [gs] dl <expression> # delete expression
3989// ::= [gs] da <expression> # delete[] expression
3990// ::= pp_ <expression> # prefix ++
3991// ::= mm_ <expression> # prefix --
3992// ::= ti <type> # typeid (type)
3993// ::= te <expression> # typeid (expression)
3994// ::= dc <type> <expression> # dynamic_cast<type> (expression)
3995// ::= sc <type> <expression> # static_cast<type> (expression)
3996// ::= cc <type> <expression> # const_cast<type> (expression)
3997// ::= rc <type> <expression> # reinterpret_cast<type> (expression)
3998// ::= st <type> # sizeof (a type)
3999// ::= sz <expression> # sizeof (an expression)
4000// ::= at <type> # alignof (a type)
4001// ::= az <expression> # alignof (an expression)
4002// ::= nx <expression> # noexcept (expression)
4003// ::= <template-param>
4004// ::= <function-param>
4005// ::= dt <expression> <unresolved-name> # expr.name
4006// ::= pt <expression> <unresolved-name> # expr->name
4007// ::= ds <expression> <expression> # expr.*expr
4008// ::= sZ <template-param> # size of a parameter pack
4009// ::= sZ <function-param> # size of a function parameter pack
Erik Pilkington6a4e62b2018-04-09 18:31:50 +00004010// ::= sP <template-arg>* E # sizeof...(T), size of a captured template parameter pack from an alias template
Erik Pilkingtonb679cfd2018-02-02 18:04:32 +00004011// ::= sp <expression> # pack expansion
4012// ::= tw <expression> # throw expression
4013// ::= tr # throw with no operand (rethrow)
4014// ::= <unresolved-name> # f(p), N::f(p), ::f(p),
4015// # freestanding dependent name (e.g., T::x),
4016// # objectless nonstatic member reference
4017// ::= fL <binary-operator-name> <expression> <expression>
4018// ::= fR <binary-operator-name> <expression> <expression>
4019// ::= fl <binary-operator-name> <expression>
4020// ::= fr <binary-operator-name> <expression>
4021// ::= <expr-primary>
4022Node *Db::parseExpr() {
4023 bool Global = consumeIf("gs");
4024 if (numLeft() < 2)
4025 return nullptr;
4026
4027 switch (*First) {
4028 case 'L':
4029 return parseExprPrimary();
4030 case 'T':
Erik Pilkingtonf26c8d12018-03-06 14:21:10 +00004031 return parseTemplateParam();
Erik Pilkington967b00e2018-04-09 18:33:01 +00004032 case 'f': {
4033 // Disambiguate a fold expression from a <function-param>.
4034 if (look(1) == 'p' || (look(1) == 'L' && std::isdigit(look(2))))
4035 return parseFunctionParam();
4036 return parseFoldExpr();
4037 }
Erik Pilkingtonb679cfd2018-02-02 18:04:32 +00004038 case 'a':
4039 switch (First[1]) {
4040 case 'a':
4041 First += 2;
4042 return parseBinaryExpr("&&");
4043 case 'd':
4044 First += 2;
4045 return parsePrefixExpr("&");
4046 case 'n':
4047 First += 2;
4048 return parseBinaryExpr("&");
4049 case 'N':
4050 First += 2;
4051 return parseBinaryExpr("&=");
4052 case 'S':
4053 First += 2;
4054 return parseBinaryExpr("=");
4055 case 't': {
4056 First += 2;
Erik Pilkingtonf23deca2018-02-05 22:41:20 +00004057 Node *Ty = parseType();
Erik Pilkingtonb679cfd2018-02-02 18:04:32 +00004058 if (Ty == nullptr)
4059 return nullptr;
4060 return make<EnclosingExpr>("alignof (", Ty, ")");
4061 }
4062 case 'z': {
4063 First += 2;
4064 Node *Ty = parseExpr();
4065 if (Ty == nullptr)
4066 return nullptr;
4067 return make<EnclosingExpr>("alignof (", Ty, ")");
4068 }
4069 }
4070 return nullptr;
4071 case 'c':
4072 switch (First[1]) {
4073 // cc <type> <expression> # const_cast<type>(expression)
4074 case 'c': {
4075 First += 2;
Erik Pilkingtonf23deca2018-02-05 22:41:20 +00004076 Node *Ty = parseType();
Erik Pilkingtonb679cfd2018-02-02 18:04:32 +00004077 if (Ty == nullptr)
4078 return Ty;
4079 Node *Ex = parseExpr();
4080 if (Ex == nullptr)
4081 return Ex;
4082 return make<CastExpr>("const_cast", Ty, Ex);
4083 }
4084 // cl <expression>+ E # call
4085 case 'l': {
4086 First += 2;
4087 Node *Callee = parseExpr();
4088 if (Callee == nullptr)
4089 return Callee;
4090 size_t ExprsBegin = Names.size();
4091 while (!consumeIf('E')) {
4092 Node *E = parseExpr();
4093 if (E == nullptr)
4094 return E;
4095 Names.push_back(E);
4096 }
4097 return make<CallExpr>(Callee, popTrailingNodeArray(ExprsBegin));
4098 }
4099 case 'm':
4100 First += 2;
4101 return parseBinaryExpr(",");
4102 case 'o':
4103 First += 2;
4104 return parsePrefixExpr("~");
4105 case 'v':
4106 return parseConversionExpr();
4107 }
4108 return nullptr;
4109 case 'd':
4110 switch (First[1]) {
4111 case 'a': {
4112 First += 2;
4113 Node *Ex = parseExpr();
4114 if (Ex == nullptr)
4115 return Ex;
4116 return make<DeleteExpr>(Ex, Global, /*is_array=*/true);
4117 }
4118 case 'c': {
4119 First += 2;
Erik Pilkingtonf23deca2018-02-05 22:41:20 +00004120 Node *T = parseType();
Erik Pilkingtonb679cfd2018-02-02 18:04:32 +00004121 if (T == nullptr)
4122 return T;
4123 Node *Ex = parseExpr();
4124 if (Ex == nullptr)
4125 return Ex;
4126 return make<CastExpr>("dynamic_cast", T, Ex);
4127 }
4128 case 'e':
4129 First += 2;
4130 return parsePrefixExpr("*");
4131 case 'l': {
4132 First += 2;
4133 Node *E = parseExpr();
4134 if (E == nullptr)
4135 return E;
4136 return make<DeleteExpr>(E, Global, /*is_array=*/false);
4137 }
4138 case 'n':
Erik Pilkingtond0dd97d2018-03-06 14:21:08 +00004139 return parseUnresolvedName();
Erik Pilkingtonb679cfd2018-02-02 18:04:32 +00004140 case 's': {
4141 First += 2;
4142 Node *LHS = parseExpr();
4143 if (LHS == nullptr)
4144 return nullptr;
4145 Node *RHS = parseExpr();
4146 if (RHS == nullptr)
4147 return nullptr;
4148 return make<MemberExpr>(LHS, ".*", RHS);
4149 }
4150 case 't': {
4151 First += 2;
4152 Node *LHS = parseExpr();
4153 if (LHS == nullptr)
4154 return LHS;
4155 Node *RHS = parseExpr();
4156 if (RHS == nullptr)
4157 return nullptr;
4158 return make<MemberExpr>(LHS, ".", RHS);
4159 }
4160 case 'v':
4161 First += 2;
4162 return parseBinaryExpr("/");
4163 case 'V':
4164 First += 2;
4165 return parseBinaryExpr("/=");
4166 }
4167 return nullptr;
4168 case 'e':
4169 switch (First[1]) {
4170 case 'o':
4171 First += 2;
4172 return parseBinaryExpr("^");
4173 case 'O':
4174 First += 2;
4175 return parseBinaryExpr("^=");
4176 case 'q':
4177 First += 2;
4178 return parseBinaryExpr("==");
4179 }
4180 return nullptr;
4181 case 'g':
4182 switch (First[1]) {
4183 case 'e':
4184 First += 2;
4185 return parseBinaryExpr(">=");
4186 case 't':
4187 First += 2;
4188 return parseBinaryExpr(">");
4189 }
4190 return nullptr;
4191 case 'i':
Erik Pilkington88a1cf62018-02-13 00:15:56 +00004192 switch (First[1]) {
4193 case 'x': {
Erik Pilkingtonb679cfd2018-02-02 18:04:32 +00004194 First += 2;
4195 Node *Base = parseExpr();
4196 if (Base == nullptr)
4197 return nullptr;
4198 Node *Index = parseExpr();
4199 if (Index == nullptr)
4200 return Index;
4201 return make<ArraySubscriptExpr>(Base, Index);
4202 }
Erik Pilkington88a1cf62018-02-13 00:15:56 +00004203 case 'l': {
4204 First += 2;
4205 size_t InitsBegin = Names.size();
4206 while (!consumeIf('E')) {
4207 Node *E = parseBracedExpr();
4208 if (E == nullptr)
4209 return nullptr;
4210 Names.push_back(E);
4211 }
4212 return make<InitListExpr>(nullptr, popTrailingNodeArray(InitsBegin));
4213 }
4214 }
Erik Pilkingtonb679cfd2018-02-02 18:04:32 +00004215 return nullptr;
4216 case 'l':
4217 switch (First[1]) {
4218 case 'e':
4219 First += 2;
4220 return parseBinaryExpr("<=");
4221 case 's':
4222 First += 2;
4223 return parseBinaryExpr("<<");
4224 case 'S':
4225 First += 2;
4226 return parseBinaryExpr("<<=");
4227 case 't':
4228 First += 2;
4229 return parseBinaryExpr("<");
4230 }
4231 return nullptr;
4232 case 'm':
4233 switch (First[1]) {
4234 case 'i':
4235 First += 2;
4236 return parseBinaryExpr("-");
4237 case 'I':
4238 First += 2;
4239 return parseBinaryExpr("-=");
4240 case 'l':
4241 First += 2;
4242 return parseBinaryExpr("*");
4243 case 'L':
4244 First += 2;
4245 return parseBinaryExpr("*=");
4246 case 'm':
4247 First += 2;
4248 if (consumeIf('_'))
4249 return parsePrefixExpr("--");
4250 Node *Ex = parseExpr();
4251 if (Ex == nullptr)
4252 return nullptr;
4253 return make<PostfixExpr>(Ex, "--");
4254 }
4255 return nullptr;
4256 case 'n':
4257 switch (First[1]) {
4258 case 'a':
4259 case 'w':
4260 return parseNewExpr();
4261 case 'e':
4262 First += 2;
4263 return parseBinaryExpr("!=");
4264 case 'g':
4265 First += 2;
4266 return parsePrefixExpr("-");
4267 case 't':
4268 First += 2;
4269 return parsePrefixExpr("!");
4270 case 'x':
4271 First += 2;
4272 Node *Ex = parseExpr();
4273 if (Ex == nullptr)
4274 return Ex;
4275 return make<EnclosingExpr>("noexcept (", Ex, ")");
4276 }
4277 return nullptr;
4278 case 'o':
4279 switch (First[1]) {
4280 case 'n':
Erik Pilkingtond0dd97d2018-03-06 14:21:08 +00004281 return parseUnresolvedName();
Erik Pilkingtonb679cfd2018-02-02 18:04:32 +00004282 case 'o':
4283 First += 2;
4284 return parseBinaryExpr("||");
4285 case 'r':
4286 First += 2;
4287 return parseBinaryExpr("|");
4288 case 'R':
4289 First += 2;
4290 return parseBinaryExpr("|=");
4291 }
4292 return nullptr;
4293 case 'p':
4294 switch (First[1]) {
4295 case 'm':
4296 First += 2;
4297 return parseBinaryExpr("->*");
4298 case 'l':
4299 First += 2;
4300 return parseBinaryExpr("+");
4301 case 'L':
4302 First += 2;
4303 return parseBinaryExpr("+=");
4304 case 'p': {
4305 First += 2;
4306 if (consumeIf('_'))
4307 return parsePrefixExpr("++");
4308 Node *Ex = parseExpr();
4309 if (Ex == nullptr)
4310 return Ex;
4311 return make<PostfixExpr>(Ex, "++");
4312 }
4313 case 's':
4314 First += 2;
4315 return parsePrefixExpr("+");
4316 case 't': {
4317 First += 2;
4318 Node *L = parseExpr();
4319 if (L == nullptr)
4320 return nullptr;
4321 Node *R = parseExpr();
4322 if (R == nullptr)
4323 return nullptr;
4324 return make<MemberExpr>(L, "->", R);
4325 }
4326 }
4327 return nullptr;
4328 case 'q':
4329 if (First[1] == 'u') {
4330 First += 2;
4331 Node *Cond = parseExpr();
Erik Pilkington24e8b732018-02-05 02:34:41 +00004332 if (Cond == nullptr)
4333 return nullptr;
Erik Pilkingtonb679cfd2018-02-02 18:04:32 +00004334 Node *LHS = parseExpr();
Erik Pilkington24e8b732018-02-05 02:34:41 +00004335 if (LHS == nullptr)
4336 return nullptr;
Erik Pilkingtonb679cfd2018-02-02 18:04:32 +00004337 Node *RHS = parseExpr();
Erik Pilkington24e8b732018-02-05 02:34:41 +00004338 if (RHS == nullptr)
4339 return nullptr;
4340 return make<ConditionalExpr>(Cond, LHS, RHS);
Erik Pilkingtonb679cfd2018-02-02 18:04:32 +00004341 }
4342 return nullptr;
4343 case 'r':
4344 switch (First[1]) {
4345 case 'c': {
4346 First += 2;
Erik Pilkingtonf23deca2018-02-05 22:41:20 +00004347 Node *T = parseType();
Erik Pilkingtonb679cfd2018-02-02 18:04:32 +00004348 if (T == nullptr)
4349 return T;
4350 Node *Ex = parseExpr();
4351 if (Ex == nullptr)
4352 return Ex;
4353 return make<CastExpr>("reinterpret_cast", T, Ex);
4354 }
4355 case 'm':
4356 First += 2;
4357 return parseBinaryExpr("%");
4358 case 'M':
4359 First += 2;
4360 return parseBinaryExpr("%=");
4361 case 's':
4362 First += 2;
4363 return parseBinaryExpr(">>");
4364 case 'S':
4365 First += 2;
4366 return parseBinaryExpr(">>=");
4367 }
4368 return nullptr;
4369 case 's':
4370 switch (First[1]) {
4371 case 'c': {
4372 First += 2;
Erik Pilkingtonf23deca2018-02-05 22:41:20 +00004373 Node *T = parseType();
Erik Pilkingtonb679cfd2018-02-02 18:04:32 +00004374 if (T == nullptr)
4375 return T;
4376 Node *Ex = parseExpr();
4377 if (Ex == nullptr)
4378 return Ex;
4379 return make<CastExpr>("static_cast", T, Ex);
4380 }
4381 case 'p': {
4382 First += 2;
4383 Node *Child = parseExpr();
4384 if (Child == nullptr)
4385 return nullptr;
4386 return make<ParameterPackExpansion>(Child);
4387 }
4388 case 'r':
Erik Pilkingtond0dd97d2018-03-06 14:21:08 +00004389 return parseUnresolvedName();
Erik Pilkingtonb679cfd2018-02-02 18:04:32 +00004390 case 't': {
4391 First += 2;
Erik Pilkingtonf23deca2018-02-05 22:41:20 +00004392 Node *Ty = parseType();
Erik Pilkingtonb679cfd2018-02-02 18:04:32 +00004393 if (Ty == nullptr)
4394 return Ty;
4395 return make<EnclosingExpr>("sizeof (", Ty, ")");
4396 }
4397 case 'z': {
4398 First += 2;
4399 Node *Ex = parseExpr();
4400 if (Ex == nullptr)
4401 return Ex;
4402 return make<EnclosingExpr>("sizeof (", Ex, ")");
4403 }
4404 case 'Z':
4405 First += 2;
4406 if (look() == 'T') {
Erik Pilkingtonf26c8d12018-03-06 14:21:10 +00004407 Node *R = parseTemplateParam();
Erik Pilkingtonb679cfd2018-02-02 18:04:32 +00004408 if (R == nullptr)
4409 return nullptr;
4410 return make<SizeofParamPackExpr>(R);
4411 } else if (look() == 'f') {
4412 Node *FP = parseFunctionParam();
4413 if (FP == nullptr)
4414 return nullptr;
Erik Pilkington6a4e62b2018-04-09 18:31:50 +00004415 return make<EnclosingExpr>("sizeof... (", FP, ")");
Erik Pilkingtonb679cfd2018-02-02 18:04:32 +00004416 }
4417 return nullptr;
Erik Pilkington6a4e62b2018-04-09 18:31:50 +00004418 case 'P': {
4419 First += 2;
4420 size_t ArgsBegin = Names.size();
4421 while (!consumeIf('E')) {
4422 Node *Arg = parseTemplateArg();
4423 if (Arg == nullptr)
4424 return nullptr;
4425 Names.push_back(Arg);
4426 }
4427 return make<EnclosingExpr>(
4428 "sizeof... (", make<NodeArrayNode>(popTrailingNodeArray(ArgsBegin)),
4429 ")");
4430 }
Erik Pilkingtonb679cfd2018-02-02 18:04:32 +00004431 }
4432 return nullptr;
4433 case 't':
4434 switch (First[1]) {
4435 case 'e': {
4436 First += 2;
4437 Node *Ex = parseExpr();
4438 if (Ex == nullptr)
4439 return Ex;
4440 return make<EnclosingExpr>("typeid (", Ex, ")");
4441 }
4442 case 'i': {
4443 First += 2;
Erik Pilkingtonf23deca2018-02-05 22:41:20 +00004444 Node *Ty = parseType();
Erik Pilkingtonb679cfd2018-02-02 18:04:32 +00004445 if (Ty == nullptr)
4446 return Ty;
4447 return make<EnclosingExpr>("typeid (", Ty, ")");
4448 }
Erik Pilkington88a1cf62018-02-13 00:15:56 +00004449 case 'l': {
4450 First += 2;
4451 Node *Ty = parseType();
4452 if (Ty == nullptr)
4453 return nullptr;
4454 size_t InitsBegin = Names.size();
4455 while (!consumeIf('E')) {
4456 Node *E = parseBracedExpr();
4457 if (E == nullptr)
4458 return nullptr;
4459 Names.push_back(E);
4460 }
4461 return make<InitListExpr>(Ty, popTrailingNodeArray(InitsBegin));
4462 }
Erik Pilkingtonb679cfd2018-02-02 18:04:32 +00004463 case 'r':
4464 First += 2;
4465 return make<NameType>("throw");
4466 case 'w': {
4467 First += 2;
4468 Node *Ex = parseExpr();
4469 if (Ex == nullptr)
4470 return nullptr;
4471 return make<ThrowExpr>(Ex);
4472 }
4473 }
4474 return nullptr;
4475 case '1':
4476 case '2':
4477 case '3':
4478 case '4':
4479 case '5':
4480 case '6':
4481 case '7':
4482 case '8':
4483 case '9':
Erik Pilkingtond0dd97d2018-03-06 14:21:08 +00004484 return parseUnresolvedName();
Erik Pilkingtonb679cfd2018-02-02 18:04:32 +00004485 }
4486 return nullptr;
4487}
Erik Pilkingtonc3926622017-07-08 18:54:08 +00004488
Erik Pilkingtone1d61622018-03-05 16:35:06 +00004489// <call-offset> ::= h <nv-offset> _
4490// ::= v <v-offset> _
4491//
4492// <nv-offset> ::= <offset number>
4493// # non-virtual base override
4494//
4495// <v-offset> ::= <offset number> _ <virtual offset number>
4496// # virtual base override, with vcall offset
4497bool Db::parseCallOffset() {
4498 // Just scan through the call offset, we never add this information into the
4499 // output.
4500 if (consumeIf('h'))
4501 return parseNumber(true).empty() || !consumeIf('_');
4502 if (consumeIf('v'))
4503 return parseNumber(true).empty() || !consumeIf('_') ||
4504 parseNumber(true).empty() || !consumeIf('_');
4505 return true;
4506}
Howard Hinnantd213ffd2011-05-05 15:27:28 +00004507
Erik Pilkingtone1d61622018-03-05 16:35:06 +00004508// <special-name> ::= TV <type> # virtual table
4509// ::= TT <type> # VTT structure (construction vtable index)
4510// ::= TI <type> # typeinfo structure
4511// ::= TS <type> # typeinfo name (null-terminated byte string)
4512// ::= Tc <call-offset> <call-offset> <base encoding>
4513// # base is the nominal target function of thunk
4514// # first call-offset is 'this' adjustment
4515// # second call-offset is result adjustment
4516// ::= T <call-offset> <base encoding>
4517// # base is the nominal target function of thunk
4518// ::= GV <object name> # Guard variable for one-time initialization
4519// # No <type>
4520// ::= TW <object name> # Thread-local wrapper
4521// ::= TH <object name> # Thread-local initialization
Erik Pilkingtond145e1f2018-03-10 21:31:22 +00004522// ::= GR <object name> _ # First temporary
4523// ::= GR <object name> <seq-id> _ # Subsequent temporaries
Erik Pilkingtone1d61622018-03-05 16:35:06 +00004524// extension ::= TC <first type> <number> _ <second type> # construction vtable for second-in-first
4525// extension ::= GR <object name> # reference temporary for object
4526Node *Db::parseSpecialName() {
4527 switch (look()) {
4528 case 'T':
4529 switch (look(1)) {
4530 // TV <type> # virtual table
4531 case 'V': {
4532 First += 2;
4533 Node *Ty = parseType();
4534 if (Ty == nullptr)
4535 return nullptr;
4536 return make<SpecialName>("vtable for ", Ty);
Howard Hinnantd213ffd2011-05-05 15:27:28 +00004537 }
Erik Pilkingtone1d61622018-03-05 16:35:06 +00004538 // TT <type> # VTT structure (construction vtable index)
4539 case 'T': {
4540 First += 2;
4541 Node *Ty = parseType();
4542 if (Ty == nullptr)
4543 return nullptr;
4544 return make<SpecialName>("VTT for ", Ty);
4545 }
4546 // TI <type> # typeinfo structure
4547 case 'I': {
4548 First += 2;
4549 Node *Ty = parseType();
4550 if (Ty == nullptr)
4551 return nullptr;
4552 return make<SpecialName>("typeinfo for ", Ty);
4553 }
4554 // TS <type> # typeinfo name (null-terminated byte string)
4555 case 'S': {
4556 First += 2;
4557 Node *Ty = parseType();
4558 if (Ty == nullptr)
4559 return nullptr;
4560 return make<SpecialName>("typeinfo name for ", Ty);
4561 }
4562 // Tc <call-offset> <call-offset> <base encoding>
4563 case 'c': {
4564 First += 2;
4565 if (parseCallOffset() || parseCallOffset())
4566 return nullptr;
4567 Node *Encoding = parseEncoding();
4568 if (Encoding == nullptr)
4569 return nullptr;
4570 return make<SpecialName>("covariant return thunk to ", Encoding);
4571 }
4572 // extension ::= TC <first type> <number> _ <second type>
4573 // # construction vtable for second-in-first
4574 case 'C': {
4575 First += 2;
4576 Node *FirstType = parseType();
4577 if (FirstType == nullptr)
4578 return nullptr;
4579 if (parseNumber(true).empty() || !consumeIf('_'))
4580 return nullptr;
4581 Node *SecondType = parseType();
4582 if (SecondType == nullptr)
4583 return nullptr;
4584 return make<CtorVtableSpecialName>(SecondType, FirstType);
4585 }
4586 // TW <object name> # Thread-local wrapper
4587 case 'W': {
4588 First += 2;
4589 Node *Name = parseName();
4590 if (Name == nullptr)
4591 return nullptr;
4592 return make<SpecialName>("thread-local wrapper routine for ", Name);
4593 }
4594 // TH <object name> # Thread-local initialization
4595 case 'H': {
4596 First += 2;
4597 Node *Name = parseName();
4598 if (Name == nullptr)
4599 return nullptr;
4600 return make<SpecialName>("thread-local initialization routine for ", Name);
4601 }
4602 // T <call-offset> <base encoding>
4603 default: {
4604 ++First;
4605 bool IsVirt = look() == 'v';
4606 if (parseCallOffset())
4607 return nullptr;
4608 Node *BaseEncoding = parseEncoding();
4609 if (BaseEncoding == nullptr)
4610 return nullptr;
4611 if (IsVirt)
4612 return make<SpecialName>("virtual thunk to ", BaseEncoding);
4613 else
4614 return make<SpecialName>("non-virtual thunk to ", BaseEncoding);
4615 }
4616 }
4617 case 'G':
4618 switch (look(1)) {
4619 // GV <object name> # Guard variable for one-time initialization
4620 case 'V': {
4621 First += 2;
4622 Node *Name = parseName();
4623 if (Name == nullptr)
4624 return nullptr;
4625 return make<SpecialName>("guard variable for ", Name);
4626 }
4627 // GR <object name> # reference temporary for object
Erik Pilkingtond145e1f2018-03-10 21:31:22 +00004628 // GR <object name> _ # First temporary
4629 // GR <object name> <seq-id> _ # Subsequent temporaries
Erik Pilkingtone1d61622018-03-05 16:35:06 +00004630 case 'R': {
4631 First += 2;
4632 Node *Name = parseName();
4633 if (Name == nullptr)
4634 return nullptr;
Erik Pilkingtond145e1f2018-03-10 21:31:22 +00004635 size_t Count;
4636 bool ParsedSeqId = !parseSeqId(&Count);
4637 if (!consumeIf('_') && ParsedSeqId)
4638 return nullptr;
Erik Pilkingtone1d61622018-03-05 16:35:06 +00004639 return make<SpecialName>("reference temporary for ", Name);
4640 }
4641 }
4642 }
4643 return nullptr;
4644}
4645
4646// <encoding> ::= <function name> <bare-function-type>
4647// ::= <data name>
4648// ::= <special-name>
4649Node *Db::parseEncoding() {
Erik Pilkingtone1d61622018-03-05 16:35:06 +00004650 if (look() == 'G' || look() == 'T')
4651 return parseSpecialName();
4652
4653 auto IsEndOfEncoding = [&] {
4654 // The set of chars that can potentially follow an <encoding> (none of which
4655 // can start a <type>). Enumerating these allows us to avoid speculative
4656 // parsing.
4657 return numLeft() == 0 || look() == 'E' || look() == '.' || look() == '_';
4658 };
4659
Erik Pilkington04f39852018-03-25 22:50:33 +00004660 NameState NameInfo(this);
Erik Pilkingtone1d61622018-03-05 16:35:06 +00004661 Node *Name = parseName(&NameInfo);
Erik Pilkington04f39852018-03-25 22:50:33 +00004662 if (Name == nullptr)
4663 return nullptr;
Erik Pilkingtone1d61622018-03-05 16:35:06 +00004664
Erik Pilkington04f39852018-03-25 22:50:33 +00004665 if (resolveForwardTemplateRefs(NameInfo))
4666 return nullptr;
4667
4668 if (IsEndOfEncoding())
4669 return Name;
Erik Pilkingtone1d61622018-03-05 16:35:06 +00004670
Erik Pilkingtonbb80c5c2018-03-25 22:49:16 +00004671 Node *Attrs = nullptr;
4672 if (consumeIf("Ua9enable_ifI")) {
4673 size_t BeforeArgs = Names.size();
4674 while (!consumeIf('E')) {
4675 Node *Arg = parseTemplateArg();
4676 if (Arg == nullptr)
4677 return nullptr;
4678 Names.push_back(Arg);
4679 }
4680 Attrs = make<EnableIfAttr>(popTrailingNodeArray(BeforeArgs));
4681 }
4682
Erik Pilkingtone1d61622018-03-05 16:35:06 +00004683 Node *ReturnType = nullptr;
4684 if (!NameInfo.CtorDtorConversion && NameInfo.EndsWithTemplateArgs) {
4685 ReturnType = parseType();
4686 if (ReturnType == nullptr)
4687 return nullptr;
4688 }
4689
4690 if (consumeIf('v'))
4691 return make<FunctionEncoding>(ReturnType, Name, NodeArray(),
Erik Pilkingtonbb80c5c2018-03-25 22:49:16 +00004692 Attrs, NameInfo.CVQualifiers,
Erik Pilkingtone1d61622018-03-05 16:35:06 +00004693 NameInfo.ReferenceQualifier);
4694
4695 size_t ParamsBegin = Names.size();
4696 do {
4697 Node *Ty = parseType();
4698 if (Ty == nullptr)
4699 return nullptr;
4700 Names.push_back(Ty);
4701 } while (!IsEndOfEncoding());
4702
4703 return make<FunctionEncoding>(ReturnType, Name,
4704 popTrailingNodeArray(ParamsBegin),
Erik Pilkingtonbb80c5c2018-03-25 22:49:16 +00004705 Attrs, NameInfo.CVQualifiers,
Erik Pilkingtone1d61622018-03-05 16:35:06 +00004706 NameInfo.ReferenceQualifier);
Howard Hinnant6c33e762013-06-17 18:10:34 +00004707}
4708
4709template <class Float>
Erik Pilkington0024acd2017-07-28 00:43:49 +00004710struct FloatData;
Howard Hinnant6c33e762013-06-17 18:10:34 +00004711
4712template <>
Erik Pilkington0024acd2017-07-28 00:43:49 +00004713struct FloatData<float>
Howard Hinnant6c33e762013-06-17 18:10:34 +00004714{
4715 static const size_t mangled_size = 8;
4716 static const size_t max_demangled_size = 24;
Howard Hinnantc62cbea2013-06-17 20:25:21 +00004717 static constexpr const char* spec = "%af";
Howard Hinnant6c33e762013-06-17 18:10:34 +00004718};
4719
Erik Pilkington0024acd2017-07-28 00:43:49 +00004720constexpr const char* FloatData<float>::spec;
Howard Hinnant6c33e762013-06-17 18:10:34 +00004721
4722template <>
Erik Pilkington0024acd2017-07-28 00:43:49 +00004723struct FloatData<double>
Howard Hinnant6c33e762013-06-17 18:10:34 +00004724{
4725 static const size_t mangled_size = 16;
4726 static const size_t max_demangled_size = 32;
4727 static constexpr const char* spec = "%a";
Howard Hinnant6c33e762013-06-17 18:10:34 +00004728};
4729
Erik Pilkington0024acd2017-07-28 00:43:49 +00004730constexpr const char* FloatData<double>::spec;
Howard Hinnant6c33e762013-06-17 18:10:34 +00004731
4732template <>
Erik Pilkington0024acd2017-07-28 00:43:49 +00004733struct FloatData<long double>
Howard Hinnant6c33e762013-06-17 18:10:34 +00004734{
Dan Gohmand04ecd02016-01-13 16:39:30 +00004735#if defined(__mips__) && defined(__mips_n64) || defined(__aarch64__) || \
4736 defined(__wasm__)
Daniel Sanders52cf98b2015-07-30 16:11:04 +00004737 static const size_t mangled_size = 32;
Ben Craig9ef2c6e2016-01-20 14:10:23 +00004738#elif defined(__arm__) || defined(__mips__) || defined(__hexagon__)
Logan Chien05d51bc2014-05-10 00:42:10 +00004739 static const size_t mangled_size = 16;
4740#else
Howard Hinnant6c33e762013-06-17 18:10:34 +00004741 static const size_t mangled_size = 20; // May need to be adjusted to 16 or 24 on other platforms
Logan Chien05d51bc2014-05-10 00:42:10 +00004742#endif
Howard Hinnant6c33e762013-06-17 18:10:34 +00004743 static const size_t max_demangled_size = 40;
Erik Pilkingtonb679cfd2018-02-02 18:04:32 +00004744 static constexpr const char *spec = "%LaL";
Howard Hinnant6c33e762013-06-17 18:10:34 +00004745};
4746
Erik Pilkingtonb679cfd2018-02-02 18:04:32 +00004747constexpr const char *FloatData<long double>::spec;
Howard Hinnant6c33e762013-06-17 18:10:34 +00004748
Erik Pilkingtonb679cfd2018-02-02 18:04:32 +00004749template <class Float> Node *Db::parseFloatingLiteral() {
4750 const size_t N = FloatData<Float>::mangled_size;
4751 if (numLeft() <= N)
4752 return nullptr;
4753 StringView Data(First, First + N);
4754 for (char C : Data)
4755 if (!std::isxdigit(C))
4756 return nullptr;
4757 First += N;
4758 if (!consumeIf('E'))
4759 return nullptr;
4760 return make<FloatExpr<Float>>(Data);
Howard Hinnant6c33e762013-06-17 18:10:34 +00004761}
4762
Erik Pilkingtonf26c8d12018-03-06 14:21:10 +00004763// <seq-id> ::= <0-9A-Z>+
4764bool Db::parseSeqId(size_t *Out) {
4765 if (!(look() >= '0' && look() <= '9') &&
4766 !(look() >= 'A' && look() <= 'Z'))
4767 return true;
4768
4769 size_t Id = 0;
4770 while (true) {
4771 if (look() >= '0' && look() <= '9') {
4772 Id *= 36;
4773 Id += static_cast<size_t>(look() - '0');
4774 } else if (look() >= 'A' && look() <= 'Z') {
4775 Id *= 36;
4776 Id += static_cast<size_t>(look() - 'A') + 10;
4777 } else {
4778 *Out = Id;
4779 return false;
4780 }
4781 ++First;
4782 }
4783}
4784
Howard Hinnant6c33e762013-06-17 18:10:34 +00004785// <substitution> ::= S <seq-id> _
4786// ::= S_
4787// <substitution> ::= Sa # ::std::allocator
4788// <substitution> ::= Sb # ::std::basic_string
4789// <substitution> ::= Ss # ::std::basic_string < char,
4790// ::std::char_traits<char>,
4791// ::std::allocator<char> >
4792// <substitution> ::= Si # ::std::basic_istream<char, std::char_traits<char> >
4793// <substitution> ::= So # ::std::basic_ostream<char, std::char_traits<char> >
4794// <substitution> ::= Sd # ::std::basic_iostream<char, std::char_traits<char> >
Erik Pilkingtonf26c8d12018-03-06 14:21:10 +00004795Node *Db::parseSubstitution() {
4796 if (!consumeIf('S'))
4797 return nullptr;
Howard Hinnant6c33e762013-06-17 18:10:34 +00004798
Erik Pilkingtonf26c8d12018-03-06 14:21:10 +00004799 if (std::islower(look())) {
4800 Node *SpecialSub;
4801 switch (look()) {
4802 case 'a':
4803 ++First;
4804 SpecialSub = make<SpecialSubstitution>(SpecialSubKind::allocator);
4805 break;
4806 case 'b':
4807 ++First;
4808 SpecialSub = make<SpecialSubstitution>(SpecialSubKind::basic_string);
4809 break;
4810 case 's':
4811 ++First;
4812 SpecialSub = make<SpecialSubstitution>(SpecialSubKind::string);
4813 break;
4814 case 'i':
4815 ++First;
4816 SpecialSub = make<SpecialSubstitution>(SpecialSubKind::istream);
4817 break;
4818 case 'o':
4819 ++First;
4820 SpecialSub = make<SpecialSubstitution>(SpecialSubKind::ostream);
4821 break;
4822 case 'd':
4823 ++First;
4824 SpecialSub = make<SpecialSubstitution>(SpecialSubKind::iostream);
4825 break;
4826 default:
4827 return nullptr;
Howard Hinnantd213ffd2011-05-05 15:27:28 +00004828 }
Erik Pilkingtonf26c8d12018-03-06 14:21:10 +00004829 // Itanium C++ ABI 5.1.2: If a name that would use a built-in <substitution>
4830 // has ABI tags, the tags are appended to the substitution; the result is a
4831 // substitutable component.
4832 Node *WithTags = parseAbiTags(SpecialSub);
4833 if (WithTags != SpecialSub) {
4834 Subs.push_back(WithTags);
4835 SpecialSub = WithTags;
4836 }
4837 return SpecialSub;
4838 }
4839
4840 // ::= S_
4841 if (consumeIf('_')) {
4842 if (Subs.empty())
4843 return nullptr;
4844 return Subs[0];
4845 }
4846
4847 // ::= S <seq-id> _
4848 size_t Index = 0;
4849 if (parseSeqId(&Index))
4850 return nullptr;
4851 ++Index;
4852 if (!consumeIf('_') || Index >= Subs.size())
4853 return nullptr;
4854 return Subs[Index];
Howard Hinnantd213ffd2011-05-05 15:27:28 +00004855}
4856
Howard Hinnant6c33e762013-06-17 18:10:34 +00004857// <template-param> ::= T_ # first template parameter
4858// ::= T <parameter-2 non-negative number> _
Erik Pilkingtonf26c8d12018-03-06 14:21:10 +00004859Node *Db::parseTemplateParam() {
4860 if (!consumeIf('T'))
4861 return nullptr;
Howard Hinnant6c33e762013-06-17 18:10:34 +00004862
Erik Pilkington61966e52018-03-16 03:06:30 +00004863 size_t Index = 0;
4864 if (!consumeIf('_')) {
4865 if (parsePositiveInteger(&Index))
4866 return nullptr;
4867 ++Index;
4868 if (!consumeIf('_'))
4869 return nullptr;
Erik Pilkingtonf26c8d12018-03-06 14:21:10 +00004870 }
4871
Erik Pilkington61966e52018-03-16 03:06:30 +00004872 // Itanium ABI 5.1.8: In a generic lambda, uses of auto in the parameter list
4873 // are mangled as the corresponding artificial template type parameter.
4874 if (ParsingLambdaParams)
4875 return make<NameType>("auto");
4876
Erik Pilkington04f39852018-03-25 22:50:33 +00004877 // If we're in a context where this <template-param> refers to a
4878 // <template-arg> further ahead in the mangled name (currently just conversion
4879 // operator types), then we should only look it up in the right context.
4880 if (PermitForwardTemplateReferences) {
4881 ForwardTemplateRefs.push_back(make<ForwardTemplateReference>(Index));
4882 return ForwardTemplateRefs.back();
Erik Pilkingtonf26c8d12018-03-06 14:21:10 +00004883 }
Erik Pilkington04f39852018-03-25 22:50:33 +00004884
4885 if (Index >= TemplateParams.size())
4886 return nullptr;
Erik Pilkingtonf26c8d12018-03-06 14:21:10 +00004887 return TemplateParams[Index];
Howard Hinnant6c33e762013-06-17 18:10:34 +00004888}
4889
Erik Pilkingtonf26c8d12018-03-06 14:21:10 +00004890// <template-arg> ::= <type> # type or template
4891// ::= X <expression> E # expression
4892// ::= <expr-primary> # simple expressions
4893// ::= J <template-arg>* E # argument pack
4894// ::= LZ <encoding> E # extension
4895Node *Db::parseTemplateArg() {
4896 switch (look()) {
4897 case 'X': {
4898 ++First;
4899 Node *Arg = parseExpr();
4900 if (Arg == nullptr || !consumeIf('E'))
4901 return nullptr;
4902 return Arg;
4903 }
4904 case 'J': {
4905 ++First;
4906 size_t ArgsBegin = Names.size();
4907 while (!consumeIf('E')) {
4908 Node *Arg = parseTemplateArg();
4909 if (Arg == nullptr)
4910 return nullptr;
4911 Names.push_back(Arg);
Howard Hinnant6c33e762013-06-17 18:10:34 +00004912 }
Erik Pilkingtonf26c8d12018-03-06 14:21:10 +00004913 NodeArray Args = popTrailingNodeArray(ArgsBegin);
4914 return make<TemplateArgumentPack>(Args);
4915 }
4916 case 'L': {
4917 // ::= LZ <encoding> E # extension
4918 if (look(1) == 'Z') {
4919 First += 2;
4920 Node *Arg = parseEncoding();
4921 if (Arg == nullptr || !consumeIf('E'))
4922 return nullptr;
4923 return Arg;
4924 }
4925 // ::= <expr-primary> # simple expressions
4926 return parseExprPrimary();
4927 }
4928 default:
4929 return parseType();
4930 }
Howard Hinnant6c33e762013-06-17 18:10:34 +00004931}
4932
4933// <template-args> ::= I <template-arg>* E
4934// extension, the abi says <template-arg>+
Erik Pilkington04f39852018-03-25 22:50:33 +00004935Node *Db::parseTemplateArgs(bool TagTemplates) {
Erik Pilkingtonf26c8d12018-03-06 14:21:10 +00004936 if (!consumeIf('I'))
4937 return nullptr;
4938
4939 // <template-params> refer to the innermost <template-args>. Clear out any
4940 // outer args that we may have inserted into TemplateParams.
4941 if (TagTemplates)
4942 TemplateParams.clear();
4943
4944 size_t ArgsBegin = Names.size();
4945 while (!consumeIf('E')) {
4946 if (TagTemplates) {
4947 auto OldParams = std::move(TemplateParams);
4948 Node *Arg = parseTemplateArg();
4949 TemplateParams = std::move(OldParams);
4950 if (Arg == nullptr)
4951 return nullptr;
4952 Names.push_back(Arg);
4953 Node *TableEntry = Arg;
4954 if (Arg->getKind() == Node::KTemplateArgumentPack) {
4955 TableEntry = make<ParameterPack>(
4956 static_cast<TemplateArgumentPack*>(TableEntry)->getElements());
4957 }
4958 TemplateParams.push_back(TableEntry);
4959 } else {
4960 Node *Arg = parseTemplateArg();
4961 if (Arg == nullptr)
4962 return nullptr;
4963 Names.push_back(Arg);
Howard Hinnant6c33e762013-06-17 18:10:34 +00004964 }
Erik Pilkingtonf26c8d12018-03-06 14:21:10 +00004965 }
4966 return make<TemplateArgs>(popTrailingNodeArray(ArgsBegin));
Howard Hinnant6c33e762013-06-17 18:10:34 +00004967}
4968
Howard Hinnant6c33e762013-06-17 18:10:34 +00004969// <discriminator> := _ <non-negative number> # when number < 10
4970// := __ <non-negative number> _ # when number >= 10
Marshall Clow6c6d9cb2015-10-08 03:02:09 +00004971// extension := decimal-digit+ # at the end of string
Howard Hinnant6c33e762013-06-17 18:10:34 +00004972
4973const char*
4974parse_discriminator(const char* first, const char* last)
4975{
4976 // parse but ignore discriminator
4977 if (first != last)
4978 {
4979 if (*first == '_')
4980 {
4981 const char* t1 = first+1;
4982 if (t1 != last)
4983 {
4984 if (std::isdigit(*t1))
4985 first = t1+1;
4986 else if (*t1 == '_')
4987 {
4988 for (++t1; t1 != last && std::isdigit(*t1); ++t1)
4989 ;
4990 if (t1 != last && *t1 == '_')
4991 first = t1 + 1;
4992 }
4993 }
4994 }
4995 else if (std::isdigit(*first))
4996 {
4997 const char* t1 = first+1;
4998 for (; t1 != last && std::isdigit(*t1); ++t1)
4999 ;
Marshall Clow6c6d9cb2015-10-08 03:02:09 +00005000 if (t1 == last)
5001 first = last;
Howard Hinnant6c33e762013-06-17 18:10:34 +00005002 }
5003 }
5004 return first;
5005}
5006
Erik Pilkingtonf26c8d12018-03-06 14:21:10 +00005007// <mangled-name> ::= _Z <encoding>
Howard Hinnantd213ffd2011-05-05 15:27:28 +00005008// ::= <type>
Erik Pilkingtonf26c8d12018-03-06 14:21:10 +00005009// extension ::= ___Z <encoding> _block_invoke
5010// extension ::= ___Z <encoding> _block_invoke<decimal-digit>+
5011// extension ::= ___Z <encoding> _block_invoke_<decimal-digit>+
5012Node *Db::parse() {
5013 if (consumeIf("_Z")) {
5014 Node *Encoding = parseEncoding();
5015 if (Encoding == nullptr)
5016 return nullptr;
5017 if (look() == '.') {
5018 Encoding = make<DotSuffix>(Encoding, StringView(First, Last));
5019 First = Last;
Howard Hinnantd213ffd2011-05-05 15:27:28 +00005020 }
Erik Pilkingtonf26c8d12018-03-06 14:21:10 +00005021 if (numLeft() != 0)
5022 return nullptr;
5023 return Encoding;
5024 }
Howard Hinnantd213ffd2011-05-05 15:27:28 +00005025
Erik Pilkingtonf26c8d12018-03-06 14:21:10 +00005026 if (consumeIf("___Z")) {
5027 Node *Encoding = parseEncoding();
5028 if (Encoding == nullptr || !consumeIf("_block_invoke"))
5029 return nullptr;
Erik Pilkington9eaf30b2018-03-07 04:29:33 +00005030 bool RequireNumber = consumeIf('_');
5031 if (parseNumber().empty() && RequireNumber)
Erik Pilkingtonf26c8d12018-03-06 14:21:10 +00005032 return nullptr;
5033 if (numLeft() != 0)
5034 return nullptr;
5035 return make<SpecialName>("invocation function for block in ", Encoding);
5036 }
5037
5038 Node *Ty = parseType();
5039 if (numLeft() != 0)
5040 return nullptr;
5041 return Ty;
5042}
Erik Pilkington0df654b2018-04-12 20:41:06 +00005043
5044bool initializeOutputStream(char *Buf, size_t *N, OutputStream &S,
5045 size_t InitSize) {
5046 size_t BufferSize;
5047 if (Buf == nullptr) {
5048 Buf = static_cast<char *>(std::malloc(InitSize));
5049 if (Buf == nullptr)
5050 return true;
5051 BufferSize = InitSize;
5052 } else
5053 BufferSize = *N;
5054
5055 S.reset(Buf, BufferSize);
5056 return false;
5057}
5058
Howard Hinnant6c33e762013-06-17 18:10:34 +00005059} // unnamed namespace
5060
Erik Pilkingtonf26c8d12018-03-06 14:21:10 +00005061enum {
5062 unknown_error = -4,
5063 invalid_args = -3,
5064 invalid_mangled_name = -2,
5065 memory_alloc_failure = -1,
5066 success = 0,
5067};
Erik Pilkington761e6b02018-01-31 20:17:06 +00005068
5069namespace __cxxabiv1 {
Saleem Abdulrasoolb4ec5792015-12-04 02:14:58 +00005070extern "C" _LIBCXXABI_FUNC_VIS char *
Erik Pilkingtonf26c8d12018-03-06 14:21:10 +00005071__cxa_demangle(const char *MangledName, char *Buf, size_t *N, int *Status) {
5072 if (MangledName == nullptr || (Buf != nullptr && N == nullptr)) {
5073 if (Status)
5074 *Status = invalid_args;
5075 return nullptr;
5076 }
5077
Erik Pilkingtonf26c8d12018-03-06 14:21:10 +00005078 int InternalStatus = success;
Erik Pilkington0df654b2018-04-12 20:41:06 +00005079 Db Parser(MangledName, MangledName + std::strlen(MangledName));
5080 OutputStream S;
Erik Pilkingtonf26c8d12018-03-06 14:21:10 +00005081
Erik Pilkingtonf26c8d12018-03-06 14:21:10 +00005082 Node *AST = Parser.parse();
5083
5084 if (AST == nullptr)
5085 InternalStatus = invalid_mangled_name;
Erik Pilkington0df654b2018-04-12 20:41:06 +00005086 else if (initializeOutputStream(Buf, N, S, 1024))
5087 InternalStatus = memory_alloc_failure;
5088 else {
Erik Pilkington04f39852018-03-25 22:50:33 +00005089 assert(Parser.ForwardTemplateRefs.empty());
Erik Pilkington0df654b2018-04-12 20:41:06 +00005090 AST->print(S);
5091 S += '\0';
5092 if (N != nullptr)
5093 *N = S.getCurrentPosition();
5094 Buf = S.getBuffer();
Erik Pilkingtonf26c8d12018-03-06 14:21:10 +00005095 }
Erik Pilkington0024acd2017-07-28 00:43:49 +00005096
Erik Pilkingtonf26c8d12018-03-06 14:21:10 +00005097 if (Status)
5098 *Status = InternalStatus;
5099 return InternalStatus == success ? Buf : nullptr;
Howard Hinnantd213ffd2011-05-05 15:27:28 +00005100}
Howard Hinnant6c33e762013-06-17 18:10:34 +00005101} // __cxxabiv1