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