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