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