blob: 31cac48dcf3291beb85a681fed63be1a89383c9b [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() {
1764 char* NewMeta = new char[AllocSize];
1765 BlockList = new (NewMeta) BlockMeta{BlockList, 0};
1766 }
1767
1768 void* allocateMassive(size_t NBytes) {
1769 NBytes += sizeof(BlockMeta);
1770 BlockMeta* NewMeta = reinterpret_cast<BlockMeta*>(new char[NBytes]);
1771 BlockList->Next = new (NewMeta) BlockMeta{BlockList->Next, 0};
1772 return static_cast<void*>(NewMeta + 1);
1773 }
1774
1775public:
1776 BumpPointerAllocator()
1777 : BlockList(new (InitialBuffer) BlockMeta{nullptr, 0}) {}
1778
1779 void* allocate(size_t N) {
1780 N = (N + 15u) & ~15u;
1781 if (N + BlockList->Current >= UsableAllocSize) {
1782 if (N > UsableAllocSize)
1783 return allocateMassive(N);
1784 grow();
1785 }
1786 BlockList->Current += N;
1787 return static_cast<void*>(reinterpret_cast<char*>(BlockList + 1) +
1788 BlockList->Current - N);
1789 }
1790
Erik Pilkingtonf2a9b0f2018-04-12 20:41:06 +00001791 void reset() {
Erik Pilkingtonbb7feae2018-03-19 15:18:23 +00001792 while (BlockList) {
1793 BlockMeta* Tmp = BlockList;
1794 BlockList = BlockList->Next;
1795 if (reinterpret_cast<char*>(Tmp) != InitialBuffer)
1796 delete[] reinterpret_cast<char*>(Tmp);
1797 }
Erik Pilkingtonf2a9b0f2018-04-12 20:41:06 +00001798 BlockList = new (InitialBuffer) BlockMeta{nullptr, 0};
Erik Pilkingtonbb7feae2018-03-19 15:18:23 +00001799 }
Erik Pilkingtonf2a9b0f2018-04-12 20:41:06 +00001800
1801 ~BumpPointerAllocator() { reset(); }
Erik Pilkingtonbb7feae2018-03-19 15:18:23 +00001802};
1803
1804template <class T, size_t N>
1805class PODSmallVector {
1806 static_assert(std::is_pod<T>::value,
1807 "T is required to be a plain old data type");
1808
1809 T* First;
1810 T* Last;
1811 T* Cap;
1812 T Inline[N];
1813
1814 bool isInline() const { return First == Inline; }
1815
1816 void clearInline() {
1817 First = Inline;
1818 Last = Inline;
1819 Cap = Inline + N;
1820 }
1821
1822 void reserve(size_t NewCap) {
1823 size_t S = size();
1824 if (isInline()) {
Serge Pavlov1a095522018-05-29 07:05:41 +00001825 auto* Tmp = static_cast<T*>(std::malloc(NewCap * sizeof(T)));
Erik Pilkingtonbb7feae2018-03-19 15:18:23 +00001826 std::copy(First, Last, Tmp);
1827 First = Tmp;
1828 } else
Serge Pavlov1a095522018-05-29 07:05:41 +00001829 First = static_cast<T*>(std::realloc(First, NewCap * sizeof(T)));
Erik Pilkingtonbb7feae2018-03-19 15:18:23 +00001830 Last = First + S;
1831 Cap = First + NewCap;
1832 }
1833
1834public:
1835 PODSmallVector() : First(Inline), Last(First), Cap(Inline + N) {}
1836
1837 PODSmallVector(const PODSmallVector&) = delete;
1838 PODSmallVector& operator=(const PODSmallVector&) = delete;
1839
1840 PODSmallVector(PODSmallVector&& Other) : PODSmallVector() {
1841 if (Other.isInline()) {
1842 std::copy(Other.begin(), Other.end(), First);
1843 Last = First + Other.size();
1844 Other.clear();
1845 return;
1846 }
1847
1848 First = Other.First;
1849 Last = Other.Last;
1850 Cap = Other.Cap;
1851 Other.clearInline();
1852 }
1853
1854 PODSmallVector& operator=(PODSmallVector&& Other) {
1855 if (Other.isInline()) {
1856 if (!isInline()) {
1857 std::free(First);
1858 clearInline();
1859 }
1860 std::copy(Other.begin(), Other.end(), First);
1861 Last = First + Other.size();
1862 Other.clear();
1863 return *this;
1864 }
1865
1866 if (isInline()) {
1867 First = Other.First;
1868 Last = Other.Last;
1869 Cap = Other.Cap;
1870 Other.clearInline();
1871 return *this;
1872 }
1873
1874 std::swap(First, Other.First);
1875 std::swap(Last, Other.Last);
1876 std::swap(Cap, Other.Cap);
1877 Other.clear();
1878 return *this;
1879 }
1880
1881 void push_back(const T& Elem) {
1882 if (Last == Cap)
1883 reserve(size() * 2);
1884 *Last++ = Elem;
1885 }
1886
1887 void pop_back() {
1888 assert(Last != First && "Popping empty vector!");
1889 --Last;
1890 }
1891
1892 void dropBack(size_t Index) {
1893 assert(Index <= size() && "dropBack() can't expand!");
1894 Last = First + Index;
1895 }
1896
1897 T* begin() { return First; }
1898 T* end() { return Last; }
1899
1900 bool empty() const { return First == Last; }
1901 size_t size() const { return static_cast<size_t>(Last - First); }
1902 T& back() {
1903 assert(Last != First && "Calling back() on empty vector!");
1904 return *(Last - 1);
1905 }
1906 T& operator[](size_t Index) {
1907 assert(Index < size() && "Invalid access!");
1908 return *(begin() + Index);
1909 }
1910 void clear() { Last = First; }
1911
1912 ~PODSmallVector() {
1913 if (!isInline())
1914 std::free(First);
1915 }
1916};
1917
1918struct Db {
1919 const char *First;
1920 const char *Last;
1921
1922 // Name stack, this is used by the parser to hold temporary names that were
Simon Pilgrimcfe2f9d2018-06-26 14:06:23 +00001923 // parsed. The parser collapses multiple names into new nodes to construct
Erik Pilkingtonbb7feae2018-03-19 15:18:23 +00001924 // the AST. Once the parser is finished, names.size() == 1.
1925 PODSmallVector<Node *, 32> Names;
1926
1927 // Substitution table. Itanium supports name substitutions as a means of
1928 // compression. The string "S42_" refers to the 44nd entry (base-36) in this
1929 // table.
1930 PODSmallVector<Node *, 32> Subs;
1931
1932 // Template parameter table. Like the above, but referenced like "T42_".
1933 // This has a smaller size compared to Subs and Names because it can be
1934 // stored on the stack.
1935 PODSmallVector<Node *, 8> TemplateParams;
1936
Erik Pilkington8a1cb332018-03-25 22:50:33 +00001937 // Set of unresolved forward <template-param> references. These can occur in a
1938 // conversion operator's type, and are resolved in the enclosing <encoding>.
1939 PODSmallVector<ForwardTemplateReference *, 4> ForwardTemplateRefs;
1940
Erik Pilkingtonbb7feae2018-03-19 15:18:23 +00001941 bool TryToParseTemplateArgs = true;
Erik Pilkington8a1cb332018-03-25 22:50:33 +00001942 bool PermitForwardTemplateReferences = false;
Erik Pilkingtonbb7feae2018-03-19 15:18:23 +00001943 bool ParsingLambdaParams = false;
1944
1945 BumpPointerAllocator ASTAllocator;
1946
1947 Db(const char *First_, const char *Last_) : First(First_), Last(Last_) {}
1948
Erik Pilkingtonf2a9b0f2018-04-12 20:41:06 +00001949 void reset(const char *First_, const char *Last_) {
1950 First = First_;
1951 Last = Last_;
1952 Names.clear();
1953 Subs.clear();
1954 TemplateParams.clear();
1955 ParsingLambdaParams = false;
1956 TryToParseTemplateArgs = true;
1957 PermitForwardTemplateReferences = false;
1958 ASTAllocator.reset();
1959 }
1960
Erik Pilkingtonbb7feae2018-03-19 15:18:23 +00001961 template <class T, class... Args> T *make(Args &&... args) {
1962 return new (ASTAllocator.allocate(sizeof(T)))
1963 T(std::forward<Args>(args)...);
1964 }
1965
1966 template <class It> NodeArray makeNodeArray(It begin, It end) {
1967 size_t sz = static_cast<size_t>(end - begin);
1968 void *mem = ASTAllocator.allocate(sizeof(Node *) * sz);
1969 Node **data = new (mem) Node *[sz];
1970 std::copy(begin, end, data);
1971 return NodeArray(data, sz);
1972 }
1973
1974 NodeArray popTrailingNodeArray(size_t FromPosition) {
1975 assert(FromPosition <= Names.size());
1976 NodeArray res =
1977 makeNodeArray(Names.begin() + (long)FromPosition, Names.end());
1978 Names.dropBack(FromPosition);
1979 return res;
1980 }
1981
1982 bool consumeIf(StringView S) {
1983 if (StringView(First, Last).startsWith(S)) {
1984 First += S.size();
1985 return true;
1986 }
1987 return false;
1988 }
1989
1990 bool consumeIf(char C) {
1991 if (First != Last && *First == C) {
1992 ++First;
1993 return true;
1994 }
1995 return false;
1996 }
1997
1998 char consume() { return First != Last ? *First++ : '\0'; }
1999
2000 char look(unsigned Lookahead = 0) {
2001 if (static_cast<size_t>(Last - First) <= Lookahead)
2002 return '\0';
2003 return First[Lookahead];
2004 }
2005
2006 size_t numLeft() const { return static_cast<size_t>(Last - First); }
2007
2008 StringView parseNumber(bool AllowNegative = false);
2009 Qualifiers parseCVQualifiers();
2010 bool parsePositiveInteger(size_t *Out);
2011 StringView parseBareSourceName();
2012
2013 bool parseSeqId(size_t *Out);
2014 Node *parseSubstitution();
2015 Node *parseTemplateParam();
Erik Pilkington8a1cb332018-03-25 22:50:33 +00002016 Node *parseTemplateArgs(bool TagTemplates = false);
Erik Pilkingtonbb7feae2018-03-19 15:18:23 +00002017 Node *parseTemplateArg();
2018
2019 /// Parse the <expr> production.
2020 Node *parseExpr();
2021 Node *parsePrefixExpr(StringView Kind);
2022 Node *parseBinaryExpr(StringView Kind);
2023 Node *parseIntegerLiteral(StringView Lit);
2024 Node *parseExprPrimary();
2025 template <class Float> Node *parseFloatingLiteral();
2026 Node *parseFunctionParam();
2027 Node *parseNewExpr();
2028 Node *parseConversionExpr();
2029 Node *parseBracedExpr();
Erik Pilkingtond43931d2018-04-09 18:33:01 +00002030 Node *parseFoldExpr();
Erik Pilkingtonbb7feae2018-03-19 15:18:23 +00002031
2032 /// Parse the <type> production.
2033 Node *parseType();
2034 Node *parseFunctionType();
2035 Node *parseVectorType();
2036 Node *parseDecltype();
2037 Node *parseArrayType();
2038 Node *parsePointerToMemberType();
2039 Node *parseClassEnumType();
2040 Node *parseQualifiedType();
2041
2042 Node *parseEncoding();
2043 bool parseCallOffset();
2044 Node *parseSpecialName();
2045
2046 /// Holds some extra information about a <name> that is being parsed. This
2047 /// information is only pertinent if the <name> refers to an <encoding>.
2048 struct NameState {
2049 bool CtorDtorConversion = false;
2050 bool EndsWithTemplateArgs = false;
2051 Qualifiers CVQualifiers = QualNone;
2052 FunctionRefQual ReferenceQualifier = FrefQualNone;
Erik Pilkington8a1cb332018-03-25 22:50:33 +00002053 size_t ForwardTemplateRefsBegin;
2054
2055 NameState(Db *Enclosing)
2056 : ForwardTemplateRefsBegin(Enclosing->ForwardTemplateRefs.size()) {}
Erik Pilkingtonbb7feae2018-03-19 15:18:23 +00002057 };
2058
Erik Pilkington8a1cb332018-03-25 22:50:33 +00002059 bool resolveForwardTemplateRefs(NameState &State) {
2060 size_t I = State.ForwardTemplateRefsBegin;
2061 size_t E = ForwardTemplateRefs.size();
2062 for (; I < E; ++I) {
2063 size_t Idx = ForwardTemplateRefs[I]->Index;
2064 if (Idx >= TemplateParams.size())
2065 return true;
2066 ForwardTemplateRefs[I]->Ref = TemplateParams[Idx];
2067 }
2068 ForwardTemplateRefs.dropBack(State.ForwardTemplateRefsBegin);
2069 return false;
2070 }
2071
Erik Pilkingtonbb7feae2018-03-19 15:18:23 +00002072 /// Parse the <name> production>
2073 Node *parseName(NameState *State = nullptr);
2074 Node *parseLocalName(NameState *State);
2075 Node *parseOperatorName(NameState *State);
2076 Node *parseUnqualifiedName(NameState *State);
2077 Node *parseUnnamedTypeName(NameState *State);
2078 Node *parseSourceName(NameState *State);
2079 Node *parseUnscopedName(NameState *State);
2080 Node *parseNestedName(NameState *State);
2081 Node *parseCtorDtorName(Node *&SoFar, NameState *State);
2082
2083 Node *parseAbiTags(Node *N);
2084
2085 /// Parse the <unresolved-name> production.
2086 Node *parseUnresolvedName();
2087 Node *parseSimpleId();
2088 Node *parseBaseUnresolvedName();
2089 Node *parseUnresolvedType();
2090 Node *parseDestructorName();
2091
2092 /// Top-level entry point into the parser.
2093 Node *parse();
2094};
2095
2096const char* parse_discriminator(const char* first, const char* last);
2097
2098// <name> ::= <nested-name> // N
2099// ::= <local-name> # See Scope Encoding below // Z
2100// ::= <unscoped-template-name> <template-args>
2101// ::= <unscoped-name>
2102//
2103// <unscoped-template-name> ::= <unscoped-name>
2104// ::= <substitution>
2105Node *Db::parseName(NameState *State) {
2106 consumeIf('L'); // extension
2107
2108 if (look() == 'N')
2109 return parseNestedName(State);
2110 if (look() == 'Z')
2111 return parseLocalName(State);
2112
2113 // ::= <unscoped-template-name> <template-args>
2114 if (look() == 'S' && look(1) != 't') {
2115 Node *S = parseSubstitution();
2116 if (S == nullptr)
2117 return nullptr;
2118 if (look() != 'I')
2119 return nullptr;
Erik Pilkington8a1cb332018-03-25 22:50:33 +00002120 Node *TA = parseTemplateArgs(State != nullptr);
Erik Pilkingtonbb7feae2018-03-19 15:18:23 +00002121 if (TA == nullptr)
2122 return nullptr;
2123 if (State) State->EndsWithTemplateArgs = true;
2124 return make<NameWithTemplateArgs>(S, TA);
2125 }
2126
2127 Node *N = parseUnscopedName(State);
2128 if (N == nullptr)
2129 return nullptr;
2130 // ::= <unscoped-template-name> <template-args>
2131 if (look() == 'I') {
2132 Subs.push_back(N);
Erik Pilkington8a1cb332018-03-25 22:50:33 +00002133 Node *TA = parseTemplateArgs(State != nullptr);
Erik Pilkingtonbb7feae2018-03-19 15:18:23 +00002134 if (TA == nullptr)
2135 return nullptr;
2136 if (State) State->EndsWithTemplateArgs = true;
2137 return make<NameWithTemplateArgs>(N, TA);
2138 }
2139 // ::= <unscoped-name>
2140 return N;
2141}
2142
2143// <local-name> := Z <function encoding> E <entity name> [<discriminator>]
2144// := Z <function encoding> E s [<discriminator>]
2145// := Z <function encoding> Ed [ <parameter number> ] _ <entity name>
2146Node *Db::parseLocalName(NameState *State) {
2147 if (!consumeIf('Z'))
2148 return nullptr;
2149 Node *Encoding = parseEncoding();
2150 if (Encoding == nullptr || !consumeIf('E'))
2151 return nullptr;
2152
2153 if (consumeIf('s')) {
2154 First = parse_discriminator(First, Last);
Erik Pilkingtonf2a9b0f2018-04-12 20:41:06 +00002155 return make<LocalName>(Encoding, make<NameType>("string literal"));
Erik Pilkingtonbb7feae2018-03-19 15:18:23 +00002156 }
2157
2158 if (consumeIf('d')) {
2159 parseNumber(true);
2160 if (!consumeIf('_'))
2161 return nullptr;
2162 Node *N = parseName(State);
2163 if (N == nullptr)
2164 return nullptr;
Erik Pilkingtonf2a9b0f2018-04-12 20:41:06 +00002165 return make<LocalName>(Encoding, N);
Erik Pilkingtonbb7feae2018-03-19 15:18:23 +00002166 }
2167
2168 Node *Entity = parseName(State);
2169 if (Entity == nullptr)
2170 return nullptr;
2171 First = parse_discriminator(First, Last);
Erik Pilkingtonf2a9b0f2018-04-12 20:41:06 +00002172 return make<LocalName>(Encoding, Entity);
Erik Pilkingtonbb7feae2018-03-19 15:18:23 +00002173}
2174
2175// <unscoped-name> ::= <unqualified-name>
2176// ::= St <unqualified-name> # ::std::
2177// extension ::= StL<unqualified-name>
2178Node *Db::parseUnscopedName(NameState *State) {
2179 if (consumeIf("StL") || consumeIf("St")) {
2180 Node *R = parseUnqualifiedName(State);
2181 if (R == nullptr)
2182 return nullptr;
2183 return make<StdQualifiedName>(R);
2184 }
2185 return parseUnqualifiedName(State);
2186}
2187
2188// <unqualified-name> ::= <operator-name> [abi-tags]
2189// ::= <ctor-dtor-name>
2190// ::= <source-name>
2191// ::= <unnamed-type-name>
2192// ::= DC <source-name>+ E # structured binding declaration
2193Node *Db::parseUnqualifiedName(NameState *State) {
2194 // <ctor-dtor-name>s are special-cased in parseNestedName().
2195 Node *Result;
2196 if (look() == 'U')
2197 Result = parseUnnamedTypeName(State);
2198 else if (look() >= '1' && look() <= '9')
2199 Result = parseSourceName(State);
2200 else if (consumeIf("DC")) {
2201 size_t BindingsBegin = Names.size();
2202 do {
2203 Node *Binding = parseSourceName(State);
2204 if (Binding == nullptr)
2205 return nullptr;
2206 Names.push_back(Binding);
2207 } while (!consumeIf('E'));
2208 Result = make<StructuredBindingName>(popTrailingNodeArray(BindingsBegin));
2209 } else
2210 Result = parseOperatorName(State);
2211 if (Result != nullptr)
2212 Result = parseAbiTags(Result);
2213 return Result;
2214}
2215
2216// <unnamed-type-name> ::= Ut [<nonnegative number>] _
2217// ::= <closure-type-name>
2218//
2219// <closure-type-name> ::= Ul <lambda-sig> E [ <nonnegative number> ] _
2220//
2221// <lambda-sig> ::= <parameter type>+ # Parameter types or "v" if the lambda has no parameters
2222Node *Db::parseUnnamedTypeName(NameState *) {
2223 if (consumeIf("Ut")) {
2224 StringView Count = parseNumber();
2225 if (!consumeIf('_'))
2226 return nullptr;
2227 return make<UnnamedTypeName>(Count);
2228 }
2229 if (consumeIf("Ul")) {
2230 NodeArray Params;
2231 SwapAndRestore<bool> SwapParams(ParsingLambdaParams, true);
2232 if (!consumeIf("vE")) {
2233 size_t ParamsBegin = Names.size();
2234 do {
2235 Node *P = parseType();
2236 if (P == nullptr)
2237 return nullptr;
2238 Names.push_back(P);
2239 } while (!consumeIf('E'));
2240 Params = popTrailingNodeArray(ParamsBegin);
2241 }
2242 StringView Count = parseNumber();
2243 if (!consumeIf('_'))
2244 return nullptr;
2245 return make<ClosureTypeName>(Params, Count);
2246 }
2247 return nullptr;
Rafael Espindolab940b662016-09-06 19:16:48 +00002248}
2249
2250// <source-name> ::= <positive length number> <identifier>
Erik Pilkingtonbb7feae2018-03-19 15:18:23 +00002251Node *Db::parseSourceName(NameState *) {
2252 size_t Length = 0;
2253 if (parsePositiveInteger(&Length))
2254 return nullptr;
2255 if (numLeft() < Length || Length == 0)
2256 return nullptr;
2257 StringView Name(First, First + Length);
2258 First += Length;
2259 if (Name.startsWith("_GLOBAL__N"))
2260 return make<NameType>("(anonymous namespace)");
2261 return make<NameType>(Name);
Rafael Espindolab940b662016-09-06 19:16:48 +00002262}
2263
Erik Pilkingtonbb7feae2018-03-19 15:18:23 +00002264// <operator-name> ::= aa # &&
Rafael Espindolab940b662016-09-06 19:16:48 +00002265// ::= ad # & (unary)
2266// ::= an # &
2267// ::= aN # &=
2268// ::= aS # =
2269// ::= cl # ()
2270// ::= cm # ,
2271// ::= co # ~
2272// ::= cv <type> # (cast)
2273// ::= da # delete[]
2274// ::= de # * (unary)
2275// ::= dl # delete
2276// ::= dv # /
2277// ::= dV # /=
2278// ::= eo # ^
2279// ::= eO # ^=
2280// ::= eq # ==
2281// ::= ge # >=
2282// ::= gt # >
2283// ::= ix # []
2284// ::= le # <=
2285// ::= li <source-name> # operator ""
2286// ::= ls # <<
2287// ::= lS # <<=
2288// ::= lt # <
2289// ::= mi # -
2290// ::= mI # -=
2291// ::= ml # *
2292// ::= mL # *=
2293// ::= mm # -- (postfix in <expression> context)
2294// ::= na # new[]
2295// ::= ne # !=
2296// ::= ng # - (unary)
2297// ::= nt # !
2298// ::= nw # new
2299// ::= oo # ||
2300// ::= or # |
2301// ::= oR # |=
2302// ::= pm # ->*
2303// ::= pl # +
2304// ::= pL # +=
2305// ::= pp # ++ (postfix in <expression> context)
2306// ::= ps # + (unary)
2307// ::= pt # ->
2308// ::= qu # ?
2309// ::= rm # %
2310// ::= rM # %=
2311// ::= rs # >>
2312// ::= rS # >>=
Erik Pilkingtonbb7feae2018-03-19 15:18:23 +00002313// ::= ss # <=> C++2a
2314// ::= v <digit> <source-name> # vendor extended operator
2315Node *Db::parseOperatorName(NameState *State) {
2316 switch (look()) {
2317 case 'a':
2318 switch (look(1)) {
Rafael Espindolab940b662016-09-06 19:16:48 +00002319 case 'a':
Erik Pilkingtonbb7feae2018-03-19 15:18:23 +00002320 First += 2;
2321 return make<NameType>("operator&&");
Rafael Espindolab940b662016-09-06 19:16:48 +00002322 case 'd':
Rafael Espindolab940b662016-09-06 19:16:48 +00002323 case 'n':
Erik Pilkingtonbb7feae2018-03-19 15:18:23 +00002324 First += 2;
2325 return make<NameType>("operator&");
2326 case 'N':
2327 First += 2;
2328 return make<NameType>("operator&=");
2329 case 'S':
2330 First += 2;
2331 return make<NameType>("operator=");
2332 }
2333 return nullptr;
2334 case 'c':
2335 switch (look(1)) {
2336 case 'l':
2337 First += 2;
2338 return make<NameType>("operator()");
2339 case 'm':
2340 First += 2;
2341 return make<NameType>("operator,");
Rafael Espindolab940b662016-09-06 19:16:48 +00002342 case 'o':
Erik Pilkingtonbb7feae2018-03-19 15:18:23 +00002343 First += 2;
2344 return make<NameType>("operator~");
2345 // ::= cv <type> # (cast)
2346 case 'v': {
Erik Pilkingtonbb7feae2018-03-19 15:18:23 +00002347 First += 2;
Erik Pilkington8a1cb332018-03-25 22:50:33 +00002348 SwapAndRestore<bool> SaveTemplate(TryToParseTemplateArgs, false);
2349 // If we're parsing an encoding, State != nullptr and the conversion
2350 // operators' <type> could have a <template-param> that refers to some
2351 // <template-arg>s further ahead in the mangled name.
2352 SwapAndRestore<bool> SavePermit(PermitForwardTemplateReferences,
2353 PermitForwardTemplateReferences ||
2354 State != nullptr);
2355 Node* Ty = parseType();
Erik Pilkingtonbb7feae2018-03-19 15:18:23 +00002356 if (Ty == nullptr)
2357 return nullptr;
2358 if (State) State->CtorDtorConversion = true;
2359 return make<ConversionOperatorType>(Ty);
2360 }
2361 }
2362 return nullptr;
2363 case 'd':
2364 switch (look(1)) {
2365 case 'a':
2366 First += 2;
2367 return make<NameType>("operator delete[]");
2368 case 'e':
2369 First += 2;
2370 return make<NameType>("operator*");
2371 case 'l':
2372 First += 2;
2373 return make<NameType>("operator delete");
Rafael Espindolab940b662016-09-06 19:16:48 +00002374 case 'v':
Erik Pilkingtonbb7feae2018-03-19 15:18:23 +00002375 First += 2;
2376 return make<NameType>("operator/");
2377 case 'V':
2378 First += 2;
2379 return make<NameType>("operator/=");
Rafael Espindolab940b662016-09-06 19:16:48 +00002380 }
Erik Pilkingtonbb7feae2018-03-19 15:18:23 +00002381 return nullptr;
2382 case 'e':
2383 switch (look(1)) {
Rafael Espindolab940b662016-09-06 19:16:48 +00002384 case 'o':
Erik Pilkingtonbb7feae2018-03-19 15:18:23 +00002385 First += 2;
2386 return make<NameType>("operator^");
2387 case 'O':
2388 First += 2;
2389 return make<NameType>("operator^=");
Rafael Espindolab940b662016-09-06 19:16:48 +00002390 case 'q':
Erik Pilkingtonbb7feae2018-03-19 15:18:23 +00002391 First += 2;
2392 return make<NameType>("operator==");
2393 }
2394 return nullptr;
2395 case 'g':
2396 switch (look(1)) {
2397 case 'e':
2398 First += 2;
2399 return make<NameType>("operator>=");
Rafael Espindolab940b662016-09-06 19:16:48 +00002400 case 't':
Erik Pilkingtonbb7feae2018-03-19 15:18:23 +00002401 First += 2;
2402 return make<NameType>("operator>");
Rafael Espindolab940b662016-09-06 19:16:48 +00002403 }
Erik Pilkingtonbb7feae2018-03-19 15:18:23 +00002404 return nullptr;
2405 case 'i':
2406 if (look(1) == 'x') {
2407 First += 2;
2408 return make<NameType>("operator[]");
2409 }
2410 return nullptr;
2411 case 'l':
2412 switch (look(1)) {
2413 case 'e':
2414 First += 2;
2415 return make<NameType>("operator<=");
2416 // ::= li <source-name> # operator ""
2417 case 'i': {
2418 First += 2;
2419 Node *SN = parseSourceName(State);
2420 if (SN == nullptr)
2421 return nullptr;
2422 return make<LiteralOperator>(SN);
2423 }
2424 case 's':
2425 First += 2;
2426 return make<NameType>("operator<<");
2427 case 'S':
2428 First += 2;
2429 return make<NameType>("operator<<=");
2430 case 't':
2431 First += 2;
2432 return make<NameType>("operator<");
2433 }
2434 return nullptr;
2435 case 'm':
2436 switch (look(1)) {
2437 case 'i':
2438 First += 2;
2439 return make<NameType>("operator-");
2440 case 'I':
2441 First += 2;
2442 return make<NameType>("operator-=");
2443 case 'l':
2444 First += 2;
2445 return make<NameType>("operator*");
Rafael Espindolab940b662016-09-06 19:16:48 +00002446 case 'L':
Erik Pilkingtonbb7feae2018-03-19 15:18:23 +00002447 First += 2;
2448 return make<NameType>("operator*=");
2449 case 'm':
2450 First += 2;
2451 return make<NameType>("operator--");
2452 }
2453 return nullptr;
2454 case 'n':
2455 switch (look(1)) {
2456 case 'a':
2457 First += 2;
2458 return make<NameType>("operator new[]");
2459 case 'e':
2460 First += 2;
2461 return make<NameType>("operator!=");
2462 case 'g':
2463 First += 2;
2464 return make<NameType>("operator-");
2465 case 't':
2466 First += 2;
2467 return make<NameType>("operator!");
2468 case 'w':
2469 First += 2;
2470 return make<NameType>("operator new");
2471 }
2472 return nullptr;
2473 case 'o':
2474 switch (look(1)) {
2475 case 'o':
2476 First += 2;
2477 return make<NameType>("operator||");
2478 case 'r':
2479 First += 2;
2480 return make<NameType>("operator|");
2481 case 'R':
2482 First += 2;
2483 return make<NameType>("operator|=");
2484 }
2485 return nullptr;
2486 case 'p':
2487 switch (look(1)) {
2488 case 'm':
2489 First += 2;
2490 return make<NameType>("operator->*");
2491 case 'l':
2492 First += 2;
2493 return make<NameType>("operator+");
2494 case 'L':
2495 First += 2;
2496 return make<NameType>("operator+=");
2497 case 'p':
2498 First += 2;
2499 return make<NameType>("operator++");
2500 case 's':
2501 First += 2;
2502 return make<NameType>("operator+");
2503 case 't':
2504 First += 2;
2505 return make<NameType>("operator->");
2506 }
2507 return nullptr;
2508 case 'q':
2509 if (look(1) == 'u') {
2510 First += 2;
2511 return make<NameType>("operator?");
2512 }
2513 return nullptr;
2514 case 'r':
2515 switch (look(1)) {
2516 case 'm':
2517 First += 2;
2518 return make<NameType>("operator%");
2519 case 'M':
2520 First += 2;
2521 return make<NameType>("operator%=");
2522 case 's':
2523 First += 2;
2524 return make<NameType>("operator>>");
2525 case 'S':
2526 First += 2;
2527 return make<NameType>("operator>>=");
2528 }
2529 return nullptr;
2530 case 's':
2531 if (look(1) == 's') {
2532 First += 2;
2533 return make<NameType>("operator<=>");
2534 }
2535 return nullptr;
2536 // ::= v <digit> <source-name> # vendor extended operator
2537 case 'v':
2538 if (std::isdigit(look(1))) {
2539 First += 2;
2540 Node *SN = parseSourceName(State);
2541 if (SN == nullptr)
2542 return nullptr;
2543 return make<ConversionOperatorType>(SN);
2544 }
2545 return nullptr;
2546 }
2547 return nullptr;
2548}
2549
2550// <ctor-dtor-name> ::= C1 # complete object constructor
2551// ::= C2 # base object constructor
2552// ::= C3 # complete object allocating constructor
2553// extension ::= C5 # ?
2554// ::= D0 # deleting destructor
2555// ::= D1 # complete object destructor
2556// ::= D2 # base object destructor
2557// extension ::= D5 # ?
2558Node *Db::parseCtorDtorName(Node *&SoFar, NameState *State) {
2559 if (SoFar->K == Node::KSpecialSubstitution) {
2560 auto SSK = static_cast<SpecialSubstitution *>(SoFar)->SSK;
2561 switch (SSK) {
2562 case SpecialSubKind::string:
2563 case SpecialSubKind::istream:
2564 case SpecialSubKind::ostream:
2565 case SpecialSubKind::iostream:
2566 SoFar = make<ExpandedSpecialSubstitution>(SSK);
Rafael Espindolab940b662016-09-06 19:16:48 +00002567 default:
Rafael Espindolab940b662016-09-06 19:16:48 +00002568 break;
2569 }
2570 }
Rafael Espindolab940b662016-09-06 19:16:48 +00002571
Erik Pilkingtonbb7feae2018-03-19 15:18:23 +00002572 if (consumeIf('C')) {
2573 bool IsInherited = consumeIf('I');
2574 if (look() != '1' && look() != '2' && look() != '3' && look() != '5')
2575 return nullptr;
2576 ++First;
2577 if (State) State->CtorDtorConversion = true;
2578 if (IsInherited) {
Erik Pilkington8a1cb332018-03-25 22:50:33 +00002579 if (parseName(State) == nullptr)
Erik Pilkingtonbb7feae2018-03-19 15:18:23 +00002580 return nullptr;
Rafael Espindolab940b662016-09-06 19:16:48 +00002581 }
Erik Pilkingtonbb7feae2018-03-19 15:18:23 +00002582 return make<CtorDtorName>(SoFar, false);
Rafael Espindolab940b662016-09-06 19:16:48 +00002583 }
Erik Pilkingtonbb7feae2018-03-19 15:18:23 +00002584
2585 if (look() == 'D' &&
2586 (look(1) == '0' || look(1) == '1' || look(1) == '2' || look(1) == '5')) {
2587 First += 2;
2588 if (State) State->CtorDtorConversion = true;
2589 return make<CtorDtorName>(SoFar, true);
2590 }
2591
2592 return nullptr;
Rafael Espindolab940b662016-09-06 19:16:48 +00002593}
2594
Erik Pilkingtonbb7feae2018-03-19 15:18:23 +00002595// <nested-name> ::= N [<CV-Qualifiers>] [<ref-qualifier>] <prefix> <unqualified-name> E
2596// ::= N [<CV-Qualifiers>] [<ref-qualifier>] <template-prefix> <template-args> E
Rafael Espindolab940b662016-09-06 19:16:48 +00002597//
2598// <prefix> ::= <prefix> <unqualified-name>
2599// ::= <template-prefix> <template-args>
2600// ::= <template-param>
2601// ::= <decltype>
2602// ::= # empty
2603// ::= <substitution>
2604// ::= <prefix> <data-member-prefix>
2605// extension ::= L
2606//
Erik Pilkington452e2ef2018-04-09 18:32:25 +00002607// <data-member-prefix> := <member source-name> [<template-args>] M
2608//
Rafael Espindolab940b662016-09-06 19:16:48 +00002609// <template-prefix> ::= <prefix> <template unqualified-name>
2610// ::= <template-param>
2611// ::= <substitution>
Erik Pilkingtonbb7feae2018-03-19 15:18:23 +00002612Node *Db::parseNestedName(NameState *State) {
2613 if (!consumeIf('N'))
2614 return nullptr;
Rafael Espindolab940b662016-09-06 19:16:48 +00002615
Erik Pilkingtonbb7feae2018-03-19 15:18:23 +00002616 Qualifiers CVTmp = parseCVQualifiers();
2617 if (State) State->CVQualifiers = CVTmp;
2618
2619 if (consumeIf('O')) {
2620 if (State) State->ReferenceQualifier = FrefQualRValue;
2621 } else if (consumeIf('R')) {
2622 if (State) State->ReferenceQualifier = FrefQualLValue;
2623 } else
2624 if (State) State->ReferenceQualifier = FrefQualNone;
2625
2626 Node *SoFar = nullptr;
2627 auto PushComponent = [&](Node *Comp) {
Erik Pilkingtonf2a9b0f2018-04-12 20:41:06 +00002628 if (SoFar) SoFar = make<NestedName>(SoFar, Comp);
Erik Pilkingtonbb7feae2018-03-19 15:18:23 +00002629 else SoFar = Comp;
2630 if (State) State->EndsWithTemplateArgs = false;
2631 };
2632
2633 if (consumeIf("St"))
2634 SoFar = make<NameType>("std");
2635
2636 while (!consumeIf('E')) {
2637 consumeIf('L'); // extension
2638
Erik Pilkington452e2ef2018-04-09 18:32:25 +00002639 // <data-member-prefix> := <member source-name> [<template-args>] M
2640 if (consumeIf('M')) {
2641 if (SoFar == nullptr)
2642 return nullptr;
2643 continue;
2644 }
2645
Erik Pilkingtonbb7feae2018-03-19 15:18:23 +00002646 // ::= <template-param>
2647 if (look() == 'T') {
2648 Node *TP = parseTemplateParam();
2649 if (TP == nullptr)
2650 return nullptr;
2651 PushComponent(TP);
2652 Subs.push_back(SoFar);
2653 continue;
Rafael Espindolab940b662016-09-06 19:16:48 +00002654 }
Erik Pilkingtonbb7feae2018-03-19 15:18:23 +00002655
2656 // ::= <template-prefix> <template-args>
2657 if (look() == 'I') {
Erik Pilkington8a1cb332018-03-25 22:50:33 +00002658 Node *TA = parseTemplateArgs(State != nullptr);
Erik Pilkingtonbb7feae2018-03-19 15:18:23 +00002659 if (TA == nullptr || SoFar == nullptr)
2660 return nullptr;
2661 SoFar = make<NameWithTemplateArgs>(SoFar, TA);
2662 if (State) State->EndsWithTemplateArgs = true;
2663 Subs.push_back(SoFar);
2664 continue;
Rafael Espindolab940b662016-09-06 19:16:48 +00002665 }
Erik Pilkingtonbb7feae2018-03-19 15:18:23 +00002666
2667 // ::= <decltype>
2668 if (look() == 'D' && (look(1) == 't' || look(1) == 'T')) {
2669 Node *DT = parseDecltype();
2670 if (DT == nullptr)
2671 return nullptr;
2672 PushComponent(DT);
2673 Subs.push_back(SoFar);
2674 continue;
Rafael Espindolab940b662016-09-06 19:16:48 +00002675 }
Erik Pilkingtonbb7feae2018-03-19 15:18:23 +00002676
2677 // ::= <substitution>
2678 if (look() == 'S' && look(1) != 't') {
2679 Node *S = parseSubstitution();
2680 if (S == nullptr)
2681 return nullptr;
2682 PushComponent(S);
2683 if (SoFar != S)
2684 Subs.push_back(S);
2685 continue;
Rafael Espindolab940b662016-09-06 19:16:48 +00002686 }
Erik Pilkingtonbb7feae2018-03-19 15:18:23 +00002687
2688 // Parse an <unqualified-name> thats actually a <ctor-dtor-name>.
2689 if (look() == 'C' || (look() == 'D' && look(1) != 'C')) {
2690 if (SoFar == nullptr)
2691 return nullptr;
2692 Node *CtorDtor = parseCtorDtorName(SoFar, State);
2693 if (CtorDtor == nullptr)
2694 return nullptr;
2695 PushComponent(CtorDtor);
2696 SoFar = parseAbiTags(SoFar);
2697 if (SoFar == nullptr)
2698 return nullptr;
2699 Subs.push_back(SoFar);
2700 continue;
2701 }
2702
2703 // ::= <prefix> <unqualified-name>
2704 Node *N = parseUnqualifiedName(State);
2705 if (N == nullptr)
2706 return nullptr;
2707 PushComponent(N);
2708 Subs.push_back(SoFar);
Rafael Espindolab940b662016-09-06 19:16:48 +00002709 }
Erik Pilkingtonbb7feae2018-03-19 15:18:23 +00002710
2711 if (SoFar == nullptr || Subs.empty())
2712 return nullptr;
2713
2714 Subs.pop_back();
2715 return SoFar;
Rafael Espindolab940b662016-09-06 19:16:48 +00002716}
2717
Erik Pilkingtonbb7feae2018-03-19 15:18:23 +00002718// <simple-id> ::= <source-name> [ <template-args> ]
2719Node *Db::parseSimpleId() {
2720 Node *SN = parseSourceName(/*NameState=*/nullptr);
2721 if (SN == nullptr)
2722 return nullptr;
2723 if (look() == 'I') {
2724 Node *TA = parseTemplateArgs();
2725 if (TA == nullptr)
2726 return nullptr;
2727 return make<NameWithTemplateArgs>(SN, TA);
Rafael Espindolab940b662016-09-06 19:16:48 +00002728 }
Erik Pilkingtonbb7feae2018-03-19 15:18:23 +00002729 return SN;
Rafael Espindolab940b662016-09-06 19:16:48 +00002730}
2731
Erik Pilkingtonbb7feae2018-03-19 15:18:23 +00002732// <destructor-name> ::= <unresolved-type> # e.g., ~T or ~decltype(f())
2733// ::= <simple-id> # e.g., ~A<2*N>
2734Node *Db::parseDestructorName() {
2735 Node *Result;
2736 if (std::isdigit(look()))
2737 Result = parseSimpleId();
2738 else
2739 Result = parseUnresolvedType();
2740 if (Result == nullptr)
2741 return nullptr;
2742 return make<DtorName>(Result);
Rafael Espindolab940b662016-09-06 19:16:48 +00002743}
2744
Erik Pilkingtonbb7feae2018-03-19 15:18:23 +00002745// <unresolved-type> ::= <template-param>
2746// ::= <decltype>
2747// ::= <substitution>
2748Node *Db::parseUnresolvedType() {
2749 if (look() == 'T') {
2750 Node *TP = parseTemplateParam();
2751 if (TP == nullptr)
2752 return nullptr;
2753 Subs.push_back(TP);
2754 return TP;
2755 }
2756 if (look() == 'D') {
2757 Node *DT = parseDecltype();
2758 if (DT == nullptr)
2759 return nullptr;
2760 Subs.push_back(DT);
2761 return DT;
2762 }
2763 return parseSubstitution();
2764}
Rafael Espindolab940b662016-09-06 19:16:48 +00002765
Erik Pilkingtonbb7feae2018-03-19 15:18:23 +00002766// <base-unresolved-name> ::= <simple-id> # unresolved name
2767// extension ::= <operator-name> # unresolved operator-function-id
2768// extension ::= <operator-name> <template-args> # unresolved operator template-id
2769// ::= on <operator-name> # unresolved operator-function-id
2770// ::= on <operator-name> <template-args> # unresolved operator template-id
2771// ::= dn <destructor-name> # destructor or pseudo-destructor;
2772// # e.g. ~X or ~X<N-1>
2773Node *Db::parseBaseUnresolvedName() {
2774 if (std::isdigit(look()))
2775 return parseSimpleId();
Rafael Espindolab940b662016-09-06 19:16:48 +00002776
Erik Pilkingtonbb7feae2018-03-19 15:18:23 +00002777 if (consumeIf("dn"))
2778 return parseDestructorName();
2779
2780 consumeIf("on");
2781
2782 Node *Oper = parseOperatorName(/*NameState=*/nullptr);
2783 if (Oper == nullptr)
2784 return nullptr;
2785 if (look() == 'I') {
2786 Node *TA = parseTemplateArgs();
2787 if (TA == nullptr)
2788 return nullptr;
2789 return make<NameWithTemplateArgs>(Oper, TA);
2790 }
2791 return Oper;
2792}
2793
2794// <unresolved-name>
2795// extension ::= srN <unresolved-type> [<template-args>] <unresolved-qualifier-level>* E <base-unresolved-name>
2796// ::= [gs] <base-unresolved-name> # x or (with "gs") ::x
Zachary Turnerfac2da12018-07-16 21:24:03 +00002797// ::= [gs] sr <unresolved-qualifier-level>+ E <base-unresolved-name>
Erik Pilkingtonbb7feae2018-03-19 15:18:23 +00002798// # A::x, N::y, A<T>::z; "gs" means leading "::"
2799// ::= sr <unresolved-type> <base-unresolved-name> # T::x / decltype(p)::x
2800// extension ::= sr <unresolved-type> <template-args> <base-unresolved-name>
2801// # T::N::x /decltype(p)::N::x
2802// (ignored) ::= srN <unresolved-type> <unresolved-qualifier-level>+ E <base-unresolved-name>
2803//
2804// <unresolved-qualifier-level> ::= <simple-id>
2805Node *Db::parseUnresolvedName() {
2806 Node *SoFar = nullptr;
2807
2808 // srN <unresolved-type> [<template-args>] <unresolved-qualifier-level>* E <base-unresolved-name>
2809 // srN <unresolved-type> <unresolved-qualifier-level>+ E <base-unresolved-name>
2810 if (consumeIf("srN")) {
2811 SoFar = parseUnresolvedType();
2812 if (SoFar == nullptr)
2813 return nullptr;
2814
2815 if (look() == 'I') {
2816 Node *TA = parseTemplateArgs();
2817 if (TA == nullptr)
2818 return nullptr;
2819 SoFar = make<NameWithTemplateArgs>(SoFar, TA);
2820 }
2821
2822 while (!consumeIf('E')) {
2823 Node *Qual = parseSimpleId();
2824 if (Qual == nullptr)
2825 return nullptr;
2826 SoFar = make<QualifiedName>(SoFar, Qual);
2827 }
2828
2829 Node *Base = parseBaseUnresolvedName();
2830 if (Base == nullptr)
2831 return nullptr;
2832 return make<QualifiedName>(SoFar, Base);
2833 }
2834
2835 bool Global = consumeIf("gs");
2836
2837 // [gs] <base-unresolved-name> # x or (with "gs") ::x
2838 if (!consumeIf("sr")) {
2839 SoFar = parseBaseUnresolvedName();
2840 if (SoFar == nullptr)
2841 return nullptr;
2842 if (Global)
2843 SoFar = make<GlobalQualifiedName>(SoFar);
2844 return SoFar;
2845 }
2846
Zachary Turnerfac2da12018-07-16 21:24:03 +00002847 // [gs] sr <unresolved-qualifier-level>+ E <base-unresolved-name>
Erik Pilkingtonbb7feae2018-03-19 15:18:23 +00002848 if (std::isdigit(look())) {
2849 do {
2850 Node *Qual = parseSimpleId();
2851 if (Qual == nullptr)
2852 return nullptr;
2853 if (SoFar)
2854 SoFar = make<QualifiedName>(SoFar, Qual);
2855 else if (Global)
2856 SoFar = make<GlobalQualifiedName>(Qual);
2857 else
2858 SoFar = Qual;
2859 } while (!consumeIf('E'));
2860 }
2861 // sr <unresolved-type> <base-unresolved-name>
2862 // sr <unresolved-type> <template-args> <base-unresolved-name>
2863 else {
2864 SoFar = parseUnresolvedType();
2865 if (SoFar == nullptr)
2866 return nullptr;
2867
2868 if (look() == 'I') {
2869 Node *TA = parseTemplateArgs();
2870 if (TA == nullptr)
2871 return nullptr;
2872 SoFar = make<NameWithTemplateArgs>(SoFar, TA);
2873 }
2874 }
2875
2876 assert(SoFar != nullptr);
2877
2878 Node *Base = parseBaseUnresolvedName();
2879 if (Base == nullptr)
2880 return nullptr;
2881 return make<QualifiedName>(SoFar, Base);
2882}
2883
2884// <abi-tags> ::= <abi-tag> [<abi-tags>]
2885// <abi-tag> ::= B <source-name>
2886Node *Db::parseAbiTags(Node *N) {
2887 while (consumeIf('B')) {
2888 StringView SN = parseBareSourceName();
2889 if (SN.empty())
2890 return nullptr;
2891 N = make<AbiTagAttr>(N, SN);
2892 }
2893 return N;
2894}
2895
2896// <number> ::= [n] <non-negative decimal integer>
2897StringView Db::parseNumber(bool AllowNegative) {
2898 const char *Tmp = First;
2899 if (AllowNegative)
2900 consumeIf('n');
2901 if (numLeft() == 0 || !std::isdigit(*First))
2902 return StringView();
2903 while (numLeft() != 0 && std::isdigit(*First))
2904 ++First;
2905 return StringView(Tmp, First);
2906}
2907
2908// <positive length number> ::= [0-9]*
2909bool Db::parsePositiveInteger(size_t *Out) {
2910 *Out = 0;
2911 if (look() < '0' || look() > '9')
2912 return true;
2913 while (look() >= '0' && look() <= '9') {
2914 *Out *= 10;
2915 *Out += static_cast<size_t>(consume() - '0');
2916 }
2917 return false;
2918}
2919
2920StringView Db::parseBareSourceName() {
2921 size_t Int = 0;
2922 if (parsePositiveInteger(&Int) || numLeft() < Int)
2923 return StringView();
2924 StringView R(First, First + Int);
2925 First += Int;
2926 return R;
2927}
2928
2929// <function-type> ::= [<CV-qualifiers>] [<exception-spec>] [Dx] F [Y] <bare-function-type> [<ref-qualifier>] E
2930//
2931// <exception-spec> ::= Do # non-throwing exception-specification (e.g., noexcept, throw())
2932// ::= DO <expression> E # computed (instantiation-dependent) noexcept
2933// ::= Dw <type>+ E # dynamic exception specification with instantiation-dependent types
2934//
2935// <ref-qualifier> ::= R # & ref-qualifier
2936// <ref-qualifier> ::= O # && ref-qualifier
2937Node *Db::parseFunctionType() {
2938 Qualifiers CVQuals = parseCVQualifiers();
2939
2940 Node *ExceptionSpec = nullptr;
2941 if (consumeIf("Do")) {
2942 ExceptionSpec = make<NameType>("noexcept");
2943 } else if (consumeIf("DO")) {
2944 Node *E = parseExpr();
2945 if (E == nullptr || !consumeIf('E'))
2946 return nullptr;
2947 ExceptionSpec = make<NoexceptSpec>(E);
2948 } else if (consumeIf("Dw")) {
2949 size_t SpecsBegin = Names.size();
2950 while (!consumeIf('E')) {
2951 Node *T = parseType();
2952 if (T == nullptr)
2953 return nullptr;
2954 Names.push_back(T);
2955 }
2956 ExceptionSpec =
2957 make<DynamicExceptionSpec>(popTrailingNodeArray(SpecsBegin));
2958 }
2959
2960 consumeIf("Dx"); // transaction safe
2961
2962 if (!consumeIf('F'))
2963 return nullptr;
2964 consumeIf('Y'); // extern "C"
2965 Node *ReturnType = parseType();
2966 if (ReturnType == nullptr)
2967 return nullptr;
2968
2969 FunctionRefQual ReferenceQualifier = FrefQualNone;
2970 size_t ParamsBegin = Names.size();
2971 while (true) {
2972 if (consumeIf('E'))
2973 break;
2974 if (consumeIf('v'))
2975 continue;
2976 if (consumeIf("RE")) {
2977 ReferenceQualifier = FrefQualLValue;
Rafael Espindolab940b662016-09-06 19:16:48 +00002978 break;
2979 }
Erik Pilkingtonbb7feae2018-03-19 15:18:23 +00002980 if (consumeIf("OE")) {
2981 ReferenceQualifier = FrefQualRValue;
Rafael Espindolab940b662016-09-06 19:16:48 +00002982 break;
2983 }
Erik Pilkingtonbb7feae2018-03-19 15:18:23 +00002984 Node *T = parseType();
2985 if (T == nullptr)
2986 return nullptr;
2987 Names.push_back(T);
2988 }
2989
2990 NodeArray Params = popTrailingNodeArray(ParamsBegin);
2991 return make<FunctionType>(ReturnType, Params, CVQuals,
2992 ReferenceQualifier, ExceptionSpec);
2993}
2994
2995// extension:
2996// <vector-type> ::= Dv <positive dimension number> _ <extended element type>
2997// ::= Dv [<dimension expression>] _ <element type>
2998// <extended element type> ::= <element type>
2999// ::= p # AltiVec vector pixel
3000Node *Db::parseVectorType() {
3001 if (!consumeIf("Dv"))
3002 return nullptr;
3003 if (look() >= '1' && look() <= '9') {
3004 StringView DimensionNumber = parseNumber();
3005 if (!consumeIf('_'))
3006 return nullptr;
3007 if (consumeIf('p'))
3008 return make<VectorType>(DimensionNumber);
3009 Node *ElemType = parseType();
3010 if (ElemType == nullptr)
3011 return nullptr;
3012 return make<VectorType>(ElemType, DimensionNumber);
3013 }
3014
3015 if (!consumeIf('_')) {
3016 Node *DimExpr = parseExpr();
3017 if (!DimExpr)
3018 return nullptr;
3019 if (!consumeIf('_'))
3020 return nullptr;
3021 Node *ElemType = parseType();
3022 if (!ElemType)
3023 return nullptr;
3024 return make<VectorType>(ElemType, DimExpr);
3025 }
3026 Node *ElemType = parseType();
3027 if (!ElemType)
3028 return nullptr;
3029 return make<VectorType>(ElemType, StringView());
3030}
3031
3032// <decltype> ::= Dt <expression> E # decltype of an id-expression or class member access (C++0x)
3033// ::= DT <expression> E # decltype of an expression (C++0x)
3034Node *Db::parseDecltype() {
3035 if (!consumeIf('D'))
3036 return nullptr;
3037 if (!consumeIf('t') && !consumeIf('T'))
3038 return nullptr;
3039 Node *E = parseExpr();
3040 if (E == nullptr)
3041 return nullptr;
3042 if (!consumeIf('E'))
3043 return nullptr;
3044 return make<EnclosingExpr>("decltype(", E, ")");
3045}
3046
3047// <array-type> ::= A <positive dimension number> _ <element type>
3048// ::= A [<dimension expression>] _ <element type>
3049Node *Db::parseArrayType() {
3050 if (!consumeIf('A'))
3051 return nullptr;
3052
3053 if (std::isdigit(look())) {
3054 StringView Dimension = parseNumber();
3055 if (!consumeIf('_'))
3056 return nullptr;
3057 Node *Ty = parseType();
3058 if (Ty == nullptr)
3059 return nullptr;
3060 return make<ArrayType>(Ty, Dimension);
3061 }
3062
3063 if (!consumeIf('_')) {
3064 Node *DimExpr = parseExpr();
3065 if (DimExpr == nullptr)
3066 return nullptr;
3067 if (!consumeIf('_'))
3068 return nullptr;
3069 Node *ElementType = parseType();
3070 if (ElementType == nullptr)
3071 return nullptr;
3072 return make<ArrayType>(ElementType, DimExpr);
3073 }
3074
3075 Node *Ty = parseType();
3076 if (Ty == nullptr)
3077 return nullptr;
3078 return make<ArrayType>(Ty);
3079}
3080
3081// <pointer-to-member-type> ::= M <class type> <member type>
3082Node *Db::parsePointerToMemberType() {
3083 if (!consumeIf('M'))
3084 return nullptr;
3085 Node *ClassType = parseType();
3086 if (ClassType == nullptr)
3087 return nullptr;
3088 Node *MemberType = parseType();
3089 if (MemberType == nullptr)
3090 return nullptr;
3091 return make<PointerToMemberType>(ClassType, MemberType);
3092}
3093
3094// <class-enum-type> ::= <name> # non-dependent type name, dependent type name, or dependent typename-specifier
3095// ::= Ts <name> # dependent elaborated type specifier using 'struct' or 'class'
3096// ::= Tu <name> # dependent elaborated type specifier using 'union'
3097// ::= Te <name> # dependent elaborated type specifier using 'enum'
3098Node *Db::parseClassEnumType() {
3099 StringView ElabSpef;
3100 if (consumeIf("Ts"))
3101 ElabSpef = "struct";
3102 else if (consumeIf("Tu"))
3103 ElabSpef = "union";
3104 else if (consumeIf("Te"))
3105 ElabSpef = "enum";
3106
3107 Node *Name = parseName();
3108 if (Name == nullptr)
3109 return nullptr;
3110
3111 if (!ElabSpef.empty())
3112 return make<ElaboratedTypeSpefType>(ElabSpef, Name);
3113
3114 return Name;
3115}
3116
3117// <qualified-type> ::= <qualifiers> <type>
3118// <qualifiers> ::= <extended-qualifier>* <CV-qualifiers>
3119// <extended-qualifier> ::= U <source-name> [<template-args>] # vendor extended type qualifier
3120Node *Db::parseQualifiedType() {
3121 if (consumeIf('U')) {
3122 StringView Qual = parseBareSourceName();
3123 if (Qual.empty())
3124 return nullptr;
3125
3126 // FIXME parse the optional <template-args> here!
3127
3128 // extension ::= U <objc-name> <objc-type> # objc-type<identifier>
3129 if (Qual.startsWith("objcproto")) {
3130 StringView ProtoSourceName = Qual.dropFront(std::strlen("objcproto"));
3131 StringView Proto;
3132 {
3133 SwapAndRestore<const char *> SaveFirst(First, ProtoSourceName.begin()),
3134 SaveLast(Last, ProtoSourceName.end());
3135 Proto = parseBareSourceName();
Rafael Espindolab940b662016-09-06 19:16:48 +00003136 }
Erik Pilkingtonbb7feae2018-03-19 15:18:23 +00003137 if (Proto.empty())
3138 return nullptr;
3139 Node *Child = parseQualifiedType();
3140 if (Child == nullptr)
3141 return nullptr;
3142 return make<ObjCProtoName>(Child, Proto);
3143 }
3144
3145 Node *Child = parseQualifiedType();
3146 if (Child == nullptr)
3147 return nullptr;
3148 return make<VendorExtQualType>(Child, Qual);
3149 }
3150
3151 Qualifiers Quals = parseCVQualifiers();
3152 Node *Ty = parseType();
3153 if (Ty == nullptr)
3154 return nullptr;
3155 if (Quals != QualNone)
3156 Ty = make<QualType>(Ty, Quals);
3157 return Ty;
3158}
3159
3160// <type> ::= <builtin-type>
3161// ::= <qualified-type>
3162// ::= <function-type>
3163// ::= <class-enum-type>
3164// ::= <array-type>
3165// ::= <pointer-to-member-type>
3166// ::= <template-param>
3167// ::= <template-template-param> <template-args>
3168// ::= <decltype>
3169// ::= P <type> # pointer
3170// ::= R <type> # l-value reference
3171// ::= O <type> # r-value reference (C++11)
3172// ::= C <type> # complex pair (C99)
3173// ::= G <type> # imaginary (C99)
3174// ::= <substitution> # See Compression below
3175// extension ::= U <objc-name> <objc-type> # objc-type<identifier>
3176// extension ::= <vector-type> # <vector-type> starts with Dv
3177//
3178// <objc-name> ::= <k0 number> objcproto <k1 number> <identifier> # k0 = 9 + <number of digits in k1> + k1
3179// <objc-type> ::= <source-name> # PU<11+>objcproto 11objc_object<source-name> 11objc_object -> id<source-name>
3180Node *Db::parseType() {
3181 Node *Result = nullptr;
3182
3183 switch (look()) {
3184 // ::= <qualified-type>
3185 case 'r':
3186 case 'V':
3187 case 'K': {
3188 unsigned AfterQuals = 0;
3189 if (look(AfterQuals) == 'r') ++AfterQuals;
3190 if (look(AfterQuals) == 'V') ++AfterQuals;
3191 if (look(AfterQuals) == 'K') ++AfterQuals;
3192
3193 if (look(AfterQuals) == 'F' ||
3194 (look(AfterQuals) == 'D' &&
3195 (look(AfterQuals + 1) == 'o' || look(AfterQuals + 1) == 'O' ||
3196 look(AfterQuals + 1) == 'w' || look(AfterQuals + 1) == 'x'))) {
3197 Result = parseFunctionType();
Rafael Espindolab940b662016-09-06 19:16:48 +00003198 break;
3199 }
Erik Pilkingtonbb7feae2018-03-19 15:18:23 +00003200 LLVM_FALLTHROUGH;
3201 }
3202 case 'U': {
3203 Result = parseQualifiedType();
3204 break;
3205 }
3206 // <builtin-type> ::= v # void
3207 case 'v':
3208 ++First;
3209 return make<NameType>("void");
3210 // ::= w # wchar_t
3211 case 'w':
3212 ++First;
3213 return make<NameType>("wchar_t");
3214 // ::= b # bool
3215 case 'b':
3216 ++First;
3217 return make<NameType>("bool");
3218 // ::= c # char
3219 case 'c':
3220 ++First;
3221 return make<NameType>("char");
3222 // ::= a # signed char
3223 case 'a':
3224 ++First;
3225 return make<NameType>("signed char");
3226 // ::= h # unsigned char
3227 case 'h':
3228 ++First;
3229 return make<NameType>("unsigned char");
3230 // ::= s # short
3231 case 's':
3232 ++First;
3233 return make<NameType>("short");
3234 // ::= t # unsigned short
3235 case 't':
3236 ++First;
3237 return make<NameType>("unsigned short");
3238 // ::= i # int
3239 case 'i':
3240 ++First;
3241 return make<NameType>("int");
3242 // ::= j # unsigned int
3243 case 'j':
3244 ++First;
3245 return make<NameType>("unsigned int");
3246 // ::= l # long
3247 case 'l':
3248 ++First;
3249 return make<NameType>("long");
3250 // ::= m # unsigned long
3251 case 'm':
3252 ++First;
3253 return make<NameType>("unsigned long");
3254 // ::= x # long long, __int64
3255 case 'x':
3256 ++First;
3257 return make<NameType>("long long");
3258 // ::= y # unsigned long long, __int64
3259 case 'y':
3260 ++First;
3261 return make<NameType>("unsigned long long");
3262 // ::= n # __int128
3263 case 'n':
3264 ++First;
3265 return make<NameType>("__int128");
3266 // ::= o # unsigned __int128
3267 case 'o':
3268 ++First;
3269 return make<NameType>("unsigned __int128");
3270 // ::= f # float
3271 case 'f':
3272 ++First;
3273 return make<NameType>("float");
3274 // ::= d # double
3275 case 'd':
3276 ++First;
3277 return make<NameType>("double");
3278 // ::= e # long double, __float80
3279 case 'e':
3280 ++First;
3281 return make<NameType>("long double");
3282 // ::= g # __float128
3283 case 'g':
3284 ++First;
3285 return make<NameType>("__float128");
3286 // ::= z # ellipsis
3287 case 'z':
3288 ++First;
3289 return make<NameType>("...");
3290
3291 // <builtin-type> ::= u <source-name> # vendor extended type
3292 case 'u': {
3293 ++First;
3294 StringView Res = parseBareSourceName();
3295 if (Res.empty())
3296 return nullptr;
3297 return make<NameType>(Res);
3298 }
3299 case 'D':
3300 switch (look(1)) {
3301 // ::= Dd # IEEE 754r decimal floating point (64 bits)
3302 case 'd':
3303 First += 2;
3304 return make<NameType>("decimal64");
3305 // ::= De # IEEE 754r decimal floating point (128 bits)
3306 case 'e':
3307 First += 2;
3308 return make<NameType>("decimal128");
3309 // ::= Df # IEEE 754r decimal floating point (32 bits)
3310 case 'f':
3311 First += 2;
3312 return make<NameType>("decimal32");
3313 // ::= Dh # IEEE 754r half-precision floating point (16 bits)
3314 case 'h':
3315 First += 2;
3316 return make<NameType>("decimal16");
3317 // ::= Di # char32_t
3318 case 'i':
3319 First += 2;
3320 return make<NameType>("char32_t");
3321 // ::= Ds # char16_t
3322 case 's':
3323 First += 2;
3324 return make<NameType>("char16_t");
3325 // ::= Da # auto (in dependent new-expressions)
3326 case 'a':
3327 First += 2;
3328 return make<NameType>("auto");
3329 // ::= Dc # decltype(auto)
3330 case 'c':
3331 First += 2;
3332 return make<NameType>("decltype(auto)");
3333 // ::= Dn # std::nullptr_t (i.e., decltype(nullptr))
3334 case 'n':
3335 First += 2;
3336 return make<NameType>("std::nullptr_t");
3337
3338 // ::= <decltype>
3339 case 't':
3340 case 'T': {
3341 Result = parseDecltype();
3342 break;
3343 }
3344 // extension ::= <vector-type> # <vector-type> starts with Dv
3345 case 'v': {
3346 Result = parseVectorType();
3347 break;
3348 }
3349 // ::= Dp <type> # pack expansion (C++0x)
3350 case 'p': {
3351 First += 2;
3352 Node *Child = parseType();
3353 if (!Child)
3354 return nullptr;
3355 Result = make<ParameterPackExpansion>(Child);
3356 break;
3357 }
3358 // Exception specifier on a function type.
3359 case 'o':
3360 case 'O':
3361 case 'w':
3362 // Transaction safe function type.
3363 case 'x':
3364 Result = parseFunctionType();
3365 break;
3366 }
3367 break;
3368 // ::= <function-type>
3369 case 'F': {
3370 Result = parseFunctionType();
3371 break;
3372 }
3373 // ::= <array-type>
3374 case 'A': {
3375 Result = parseArrayType();
3376 break;
3377 }
3378 // ::= <pointer-to-member-type>
3379 case 'M': {
3380 Result = parsePointerToMemberType();
3381 break;
3382 }
3383 // ::= <template-param>
3384 case 'T': {
3385 // This could be an elaborate type specifier on a <class-enum-type>.
3386 if (look(1) == 's' || look(1) == 'u' || look(1) == 'e') {
3387 Result = parseClassEnumType();
3388 break;
3389 }
3390
3391 Result = parseTemplateParam();
3392 if (Result == nullptr)
3393 return nullptr;
3394
3395 // Result could be either of:
3396 // <type> ::= <template-param>
3397 // <type> ::= <template-template-param> <template-args>
3398 //
3399 // <template-template-param> ::= <template-param>
3400 // ::= <substitution>
3401 //
3402 // If this is followed by some <template-args>, and we're permitted to
3403 // parse them, take the second production.
3404
3405 if (TryToParseTemplateArgs && look() == 'I') {
3406 Node *TA = parseTemplateArgs();
3407 if (TA == nullptr)
3408 return nullptr;
3409 Result = make<NameWithTemplateArgs>(Result, TA);
3410 }
3411 break;
3412 }
3413 // ::= P <type> # pointer
3414 case 'P': {
3415 ++First;
3416 Node *Ptr = parseType();
3417 if (Ptr == nullptr)
3418 return nullptr;
3419 Result = make<PointerType>(Ptr);
3420 break;
3421 }
3422 // ::= R <type> # l-value reference
3423 case 'R': {
3424 ++First;
3425 Node *Ref = parseType();
3426 if (Ref == nullptr)
3427 return nullptr;
3428 Result = make<LValueReferenceType>(Ref);
3429 break;
3430 }
3431 // ::= O <type> # r-value reference (C++11)
3432 case 'O': {
3433 ++First;
3434 Node *Ref = parseType();
3435 if (Ref == nullptr)
3436 return nullptr;
3437 Result = make<RValueReferenceType>(Ref);
3438 break;
3439 }
3440 // ::= C <type> # complex pair (C99)
3441 case 'C': {
3442 ++First;
3443 Node *P = parseType();
3444 if (P == nullptr)
3445 return nullptr;
3446 Result = make<PostfixQualifiedType>(P, " complex");
3447 break;
3448 }
3449 // ::= G <type> # imaginary (C99)
3450 case 'G': {
3451 ++First;
3452 Node *P = parseType();
3453 if (P == nullptr)
3454 return P;
3455 Result = make<PostfixQualifiedType>(P, " imaginary");
3456 break;
3457 }
3458 // ::= <substitution> # See Compression below
3459 case 'S': {
3460 if (look(1) && look(1) != 't') {
3461 Node *Sub = parseSubstitution();
3462 if (Sub == nullptr)
3463 return nullptr;
3464
3465 // Sub could be either of:
3466 // <type> ::= <substitution>
3467 // <type> ::= <template-template-param> <template-args>
3468 //
3469 // <template-template-param> ::= <template-param>
3470 // ::= <substitution>
3471 //
3472 // If this is followed by some <template-args>, and we're permitted to
3473 // parse them, take the second production.
3474
3475 if (TryToParseTemplateArgs && look() == 'I') {
3476 Node *TA = parseTemplateArgs();
3477 if (TA == nullptr)
3478 return nullptr;
3479 Result = make<NameWithTemplateArgs>(Sub, TA);
3480 break;
3481 }
3482
3483 // If all we parsed was a substitution, don't re-insert into the
3484 // substitution table.
3485 return Sub;
3486 }
3487 LLVM_FALLTHROUGH;
3488 }
3489 // ::= <class-enum-type>
3490 default: {
3491 Result = parseClassEnumType();
3492 break;
3493 }
3494 }
3495
3496 // If we parsed a type, insert it into the substitution table. Note that all
3497 // <builtin-type>s and <substitution>s have already bailed out, because they
3498 // don't get substitutions.
3499 if (Result != nullptr)
3500 Subs.push_back(Result);
3501 return Result;
3502}
3503
3504Node *Db::parsePrefixExpr(StringView Kind) {
3505 Node *E = parseExpr();
3506 if (E == nullptr)
3507 return nullptr;
3508 return make<PrefixExpr>(Kind, E);
3509}
3510
3511Node *Db::parseBinaryExpr(StringView Kind) {
3512 Node *LHS = parseExpr();
3513 if (LHS == nullptr)
3514 return nullptr;
3515 Node *RHS = parseExpr();
3516 if (RHS == nullptr)
3517 return nullptr;
3518 return make<BinaryExpr>(LHS, Kind, RHS);
3519}
3520
3521Node *Db::parseIntegerLiteral(StringView Lit) {
3522 StringView Tmp = parseNumber(true);
3523 if (!Tmp.empty() && consumeIf('E'))
3524 return make<IntegerExpr>(Lit, Tmp);
3525 return nullptr;
3526}
3527
3528// <CV-Qualifiers> ::= [r] [V] [K]
3529Qualifiers Db::parseCVQualifiers() {
3530 Qualifiers CVR = QualNone;
3531 if (consumeIf('r'))
3532 addQualifiers(CVR, QualRestrict);
3533 if (consumeIf('V'))
3534 addQualifiers(CVR, QualVolatile);
3535 if (consumeIf('K'))
3536 addQualifiers(CVR, QualConst);
3537 return CVR;
3538}
3539
3540// <function-param> ::= fp <top-level CV-Qualifiers> _ # L == 0, first parameter
3541// ::= fp <top-level CV-Qualifiers> <parameter-2 non-negative number> _ # L == 0, second and later parameters
3542// ::= fL <L-1 non-negative number> p <top-level CV-Qualifiers> _ # L > 0, first parameter
3543// ::= fL <L-1 non-negative number> p <top-level CV-Qualifiers> <parameter-2 non-negative number> _ # L > 0, second and later parameters
3544Node *Db::parseFunctionParam() {
3545 if (consumeIf("fp")) {
3546 parseCVQualifiers();
3547 StringView Num = parseNumber();
3548 if (!consumeIf('_'))
3549 return nullptr;
3550 return make<FunctionParam>(Num);
3551 }
3552 if (consumeIf("fL")) {
3553 if (parseNumber().empty())
3554 return nullptr;
3555 if (!consumeIf('p'))
3556 return nullptr;
3557 parseCVQualifiers();
3558 StringView Num = parseNumber();
3559 if (!consumeIf('_'))
3560 return nullptr;
3561 return make<FunctionParam>(Num);
3562 }
3563 return nullptr;
3564}
3565
3566// [gs] nw <expression>* _ <type> E # new (expr-list) type
3567// [gs] nw <expression>* _ <type> <initializer> # new (expr-list) type (init)
3568// [gs] na <expression>* _ <type> E # new[] (expr-list) type
3569// [gs] na <expression>* _ <type> <initializer> # new[] (expr-list) type (init)
3570// <initializer> ::= pi <expression>* E # parenthesized initialization
3571Node *Db::parseNewExpr() {
3572 bool Global = consumeIf("gs");
3573 bool IsArray = look(1) == 'a';
3574 if (!consumeIf("nw") && !consumeIf("na"))
3575 return nullptr;
3576 size_t Exprs = Names.size();
3577 while (!consumeIf('_')) {
3578 Node *Ex = parseExpr();
3579 if (Ex == nullptr)
3580 return nullptr;
3581 Names.push_back(Ex);
3582 }
3583 NodeArray ExprList = popTrailingNodeArray(Exprs);
3584 Node *Ty = parseType();
3585 if (Ty == nullptr)
3586 return Ty;
3587 if (consumeIf("pi")) {
3588 size_t InitsBegin = Names.size();
3589 while (!consumeIf('E')) {
3590 Node *Init = parseExpr();
3591 if (Init == nullptr)
3592 return Init;
3593 Names.push_back(Init);
3594 }
3595 NodeArray Inits = popTrailingNodeArray(InitsBegin);
3596 return make<NewExpr>(ExprList, Ty, Inits, Global, IsArray);
3597 } else if (!consumeIf('E'))
3598 return nullptr;
3599 return make<NewExpr>(ExprList, Ty, NodeArray(), Global, IsArray);
3600}
3601
3602// cv <type> <expression> # conversion with one argument
3603// cv <type> _ <expression>* E # conversion with a different number of arguments
3604Node *Db::parseConversionExpr() {
3605 if (!consumeIf("cv"))
3606 return nullptr;
3607 Node *Ty;
3608 {
3609 SwapAndRestore<bool> SaveTemp(TryToParseTemplateArgs, false);
3610 Ty = parseType();
3611 }
3612
3613 if (Ty == nullptr)
3614 return nullptr;
3615
3616 if (consumeIf('_')) {
3617 size_t ExprsBegin = Names.size();
3618 while (!consumeIf('E')) {
3619 Node *E = parseExpr();
3620 if (E == nullptr)
3621 return E;
3622 Names.push_back(E);
3623 }
3624 NodeArray Exprs = popTrailingNodeArray(ExprsBegin);
3625 return make<ConversionExpr>(Ty, Exprs);
3626 }
3627
3628 Node *E[1] = {parseExpr()};
3629 if (E[0] == nullptr)
3630 return nullptr;
3631 return make<ConversionExpr>(Ty, makeNodeArray(E, E + 1));
3632}
3633
3634// <expr-primary> ::= L <type> <value number> E # integer literal
3635// ::= L <type> <value float> E # floating literal
3636// ::= L <string type> E # string literal
3637// ::= L <nullptr type> E # nullptr literal (i.e., "LDnE")
3638// FIXME: ::= L <type> <real-part float> _ <imag-part float> E # complex floating point literal (C 2000)
3639// ::= L <mangled-name> E # external name
3640Node *Db::parseExprPrimary() {
3641 if (!consumeIf('L'))
3642 return nullptr;
3643 switch (look()) {
3644 case 'w':
3645 ++First;
3646 return parseIntegerLiteral("wchar_t");
3647 case 'b':
3648 if (consumeIf("b0E"))
3649 return make<BoolExpr>(0);
3650 if (consumeIf("b1E"))
3651 return make<BoolExpr>(1);
3652 return nullptr;
3653 case 'c':
3654 ++First;
3655 return parseIntegerLiteral("char");
3656 case 'a':
3657 ++First;
3658 return parseIntegerLiteral("signed char");
3659 case 'h':
3660 ++First;
3661 return parseIntegerLiteral("unsigned char");
3662 case 's':
3663 ++First;
3664 return parseIntegerLiteral("short");
3665 case 't':
3666 ++First;
3667 return parseIntegerLiteral("unsigned short");
3668 case 'i':
3669 ++First;
3670 return parseIntegerLiteral("");
3671 case 'j':
3672 ++First;
3673 return parseIntegerLiteral("u");
3674 case 'l':
3675 ++First;
3676 return parseIntegerLiteral("l");
3677 case 'm':
3678 ++First;
3679 return parseIntegerLiteral("ul");
3680 case 'x':
3681 ++First;
3682 return parseIntegerLiteral("ll");
3683 case 'y':
3684 ++First;
3685 return parseIntegerLiteral("ull");
3686 case 'n':
3687 ++First;
3688 return parseIntegerLiteral("__int128");
3689 case 'o':
3690 ++First;
3691 return parseIntegerLiteral("unsigned __int128");
3692 case 'f':
3693 ++First;
3694 return parseFloatingLiteral<float>();
3695 case 'd':
3696 ++First;
3697 return parseFloatingLiteral<double>();
3698 case 'e':
3699 ++First;
3700 return parseFloatingLiteral<long double>();
3701 case '_':
3702 if (consumeIf("_Z")) {
3703 Node *R = parseEncoding();
3704 if (R != nullptr && consumeIf('E'))
3705 return R;
3706 }
3707 return nullptr;
3708 case 'T':
3709 // Invalid mangled name per
3710 // http://sourcerytools.com/pipermail/cxx-abi-dev/2011-August/002422.html
3711 return nullptr;
3712 default: {
3713 // might be named type
3714 Node *T = parseType();
3715 if (T == nullptr)
3716 return nullptr;
3717 StringView N = parseNumber();
3718 if (!N.empty()) {
3719 if (!consumeIf('E'))
3720 return nullptr;
3721 return make<IntegerCastExpr>(T, N);
3722 }
3723 if (consumeIf('E'))
3724 return T;
3725 return nullptr;
3726 }
3727 }
3728}
3729
3730// <braced-expression> ::= <expression>
3731// ::= di <field source-name> <braced-expression> # .name = expr
3732// ::= dx <index expression> <braced-expression> # [expr] = expr
3733// ::= dX <range begin expression> <range end expression> <braced-expression>
3734Node *Db::parseBracedExpr() {
3735 if (look() == 'd') {
3736 switch (look(1)) {
3737 case 'i': {
3738 First += 2;
3739 Node *Field = parseSourceName(/*NameState=*/nullptr);
3740 if (Field == nullptr)
3741 return nullptr;
3742 Node *Init = parseBracedExpr();
3743 if (Init == nullptr)
3744 return nullptr;
3745 return make<BracedExpr>(Field, Init, /*isArray=*/false);
3746 }
3747 case 'x': {
3748 First += 2;
3749 Node *Index = parseExpr();
3750 if (Index == nullptr)
3751 return nullptr;
3752 Node *Init = parseBracedExpr();
3753 if (Init == nullptr)
3754 return nullptr;
3755 return make<BracedExpr>(Index, Init, /*isArray=*/true);
3756 }
3757 case 'X': {
3758 First += 2;
3759 Node *RangeBegin = parseExpr();
3760 if (RangeBegin == nullptr)
3761 return nullptr;
3762 Node *RangeEnd = parseExpr();
3763 if (RangeEnd == nullptr)
3764 return nullptr;
3765 Node *Init = parseBracedExpr();
3766 if (Init == nullptr)
3767 return nullptr;
3768 return make<BracedRangeExpr>(RangeBegin, RangeEnd, Init);
3769 }
Rafael Espindolab940b662016-09-06 19:16:48 +00003770 }
3771 }
Erik Pilkingtonbb7feae2018-03-19 15:18:23 +00003772 return parseExpr();
3773}
3774
Erik Pilkingtond43931d2018-04-09 18:33:01 +00003775// (not yet in the spec)
3776// <fold-expr> ::= fL <binary-operator-name> <expression> <expression>
3777// ::= fR <binary-operator-name> <expression> <expression>
3778// ::= fl <binary-operator-name> <expression>
3779// ::= fr <binary-operator-name> <expression>
3780Node *Db::parseFoldExpr() {
3781 if (!consumeIf('f'))
3782 return nullptr;
3783
3784 char FoldKind = look();
3785 bool IsLeftFold, HasInitializer;
3786 HasInitializer = FoldKind == 'L' || FoldKind == 'R';
3787 if (FoldKind == 'l' || FoldKind == 'L')
3788 IsLeftFold = true;
3789 else if (FoldKind == 'r' || FoldKind == 'R')
3790 IsLeftFold = false;
3791 else
3792 return nullptr;
3793 ++First;
3794
3795 // FIXME: This map is duplicated in parseOperatorName and parseExpr.
3796 StringView OperatorName;
3797 if (consumeIf("aa")) OperatorName = "&&";
3798 else if (consumeIf("an")) OperatorName = "&";
3799 else if (consumeIf("aN")) OperatorName = "&=";
3800 else if (consumeIf("aS")) OperatorName = "=";
3801 else if (consumeIf("cm")) OperatorName = ",";
3802 else if (consumeIf("ds")) OperatorName = ".*";
3803 else if (consumeIf("dv")) OperatorName = "/";
3804 else if (consumeIf("dV")) OperatorName = "/=";
3805 else if (consumeIf("eo")) OperatorName = "^";
3806 else if (consumeIf("eO")) OperatorName = "^=";
3807 else if (consumeIf("eq")) OperatorName = "==";
3808 else if (consumeIf("ge")) OperatorName = ">=";
3809 else if (consumeIf("gt")) OperatorName = ">";
3810 else if (consumeIf("le")) OperatorName = "<=";
3811 else if (consumeIf("ls")) OperatorName = "<<";
3812 else if (consumeIf("lS")) OperatorName = "<<=";
3813 else if (consumeIf("lt")) OperatorName = "<";
3814 else if (consumeIf("mi")) OperatorName = "-";
3815 else if (consumeIf("mI")) OperatorName = "-=";
3816 else if (consumeIf("ml")) OperatorName = "*";
3817 else if (consumeIf("mL")) OperatorName = "*=";
3818 else if (consumeIf("ne")) OperatorName = "!=";
3819 else if (consumeIf("oo")) OperatorName = "||";
3820 else if (consumeIf("or")) OperatorName = "|";
3821 else if (consumeIf("oR")) OperatorName = "|=";
3822 else if (consumeIf("pl")) OperatorName = "+";
3823 else if (consumeIf("pL")) OperatorName = "+=";
3824 else if (consumeIf("rm")) OperatorName = "%";
3825 else if (consumeIf("rM")) OperatorName = "%=";
3826 else if (consumeIf("rs")) OperatorName = ">>";
3827 else if (consumeIf("rS")) OperatorName = ">>=";
3828 else return nullptr;
3829
3830 Node *Pack = parseExpr(), *Init = nullptr;
3831 if (Pack == nullptr)
3832 return nullptr;
3833 if (HasInitializer) {
3834 Init = parseExpr();
3835 if (Init == nullptr)
3836 return nullptr;
3837 }
3838
3839 if (IsLeftFold && Init)
3840 std::swap(Pack, Init);
3841
3842 return make<FoldExpr>(IsLeftFold, OperatorName, Pack, Init);
3843}
3844
Erik Pilkingtonbb7feae2018-03-19 15:18:23 +00003845// <expression> ::= <unary operator-name> <expression>
3846// ::= <binary operator-name> <expression> <expression>
3847// ::= <ternary operator-name> <expression> <expression> <expression>
3848// ::= cl <expression>+ E # call
3849// ::= cv <type> <expression> # conversion with one argument
3850// ::= cv <type> _ <expression>* E # conversion with a different number of arguments
3851// ::= [gs] nw <expression>* _ <type> E # new (expr-list) type
3852// ::= [gs] nw <expression>* _ <type> <initializer> # new (expr-list) type (init)
3853// ::= [gs] na <expression>* _ <type> E # new[] (expr-list) type
3854// ::= [gs] na <expression>* _ <type> <initializer> # new[] (expr-list) type (init)
3855// ::= [gs] dl <expression> # delete expression
3856// ::= [gs] da <expression> # delete[] expression
3857// ::= pp_ <expression> # prefix ++
3858// ::= mm_ <expression> # prefix --
3859// ::= ti <type> # typeid (type)
3860// ::= te <expression> # typeid (expression)
3861// ::= dc <type> <expression> # dynamic_cast<type> (expression)
3862// ::= sc <type> <expression> # static_cast<type> (expression)
3863// ::= cc <type> <expression> # const_cast<type> (expression)
3864// ::= rc <type> <expression> # reinterpret_cast<type> (expression)
3865// ::= st <type> # sizeof (a type)
3866// ::= sz <expression> # sizeof (an expression)
3867// ::= at <type> # alignof (a type)
3868// ::= az <expression> # alignof (an expression)
3869// ::= nx <expression> # noexcept (expression)
3870// ::= <template-param>
3871// ::= <function-param>
3872// ::= dt <expression> <unresolved-name> # expr.name
3873// ::= pt <expression> <unresolved-name> # expr->name
3874// ::= ds <expression> <expression> # expr.*expr
3875// ::= sZ <template-param> # size of a parameter pack
3876// ::= sZ <function-param> # size of a function parameter pack
Erik Pilkington650130a2018-04-09 18:31:50 +00003877// ::= sP <template-arg>* E # sizeof...(T), size of a captured template parameter pack from an alias template
Erik Pilkingtonbb7feae2018-03-19 15:18:23 +00003878// ::= sp <expression> # pack expansion
3879// ::= tw <expression> # throw expression
3880// ::= tr # throw with no operand (rethrow)
3881// ::= <unresolved-name> # f(p), N::f(p), ::f(p),
3882// # freestanding dependent name (e.g., T::x),
3883// # objectless nonstatic member reference
3884// ::= fL <binary-operator-name> <expression> <expression>
3885// ::= fR <binary-operator-name> <expression> <expression>
3886// ::= fl <binary-operator-name> <expression>
3887// ::= fr <binary-operator-name> <expression>
3888// ::= <expr-primary>
3889Node *Db::parseExpr() {
3890 bool Global = consumeIf("gs");
3891 if (numLeft() < 2)
3892 return nullptr;
3893
3894 switch (*First) {
3895 case 'L':
3896 return parseExprPrimary();
3897 case 'T':
3898 return parseTemplateParam();
Erik Pilkingtond43931d2018-04-09 18:33:01 +00003899 case 'f': {
3900 // Disambiguate a fold expression from a <function-param>.
3901 if (look(1) == 'p' || (look(1) == 'L' && std::isdigit(look(2))))
3902 return parseFunctionParam();
3903 return parseFoldExpr();
3904 }
Erik Pilkingtonbb7feae2018-03-19 15:18:23 +00003905 case 'a':
3906 switch (First[1]) {
3907 case 'a':
3908 First += 2;
3909 return parseBinaryExpr("&&");
3910 case 'd':
3911 First += 2;
3912 return parsePrefixExpr("&");
3913 case 'n':
3914 First += 2;
3915 return parseBinaryExpr("&");
3916 case 'N':
3917 First += 2;
3918 return parseBinaryExpr("&=");
3919 case 'S':
3920 First += 2;
3921 return parseBinaryExpr("=");
3922 case 't': {
3923 First += 2;
3924 Node *Ty = parseType();
3925 if (Ty == nullptr)
3926 return nullptr;
3927 return make<EnclosingExpr>("alignof (", Ty, ")");
3928 }
3929 case 'z': {
3930 First += 2;
3931 Node *Ty = parseExpr();
3932 if (Ty == nullptr)
3933 return nullptr;
3934 return make<EnclosingExpr>("alignof (", Ty, ")");
3935 }
3936 }
3937 return nullptr;
3938 case 'c':
3939 switch (First[1]) {
3940 // cc <type> <expression> # const_cast<type>(expression)
3941 case 'c': {
3942 First += 2;
3943 Node *Ty = parseType();
3944 if (Ty == nullptr)
3945 return Ty;
3946 Node *Ex = parseExpr();
3947 if (Ex == nullptr)
3948 return Ex;
3949 return make<CastExpr>("const_cast", Ty, Ex);
3950 }
3951 // cl <expression>+ E # call
3952 case 'l': {
3953 First += 2;
3954 Node *Callee = parseExpr();
3955 if (Callee == nullptr)
3956 return Callee;
3957 size_t ExprsBegin = Names.size();
3958 while (!consumeIf('E')) {
3959 Node *E = parseExpr();
3960 if (E == nullptr)
3961 return E;
3962 Names.push_back(E);
3963 }
3964 return make<CallExpr>(Callee, popTrailingNodeArray(ExprsBegin));
3965 }
3966 case 'm':
3967 First += 2;
3968 return parseBinaryExpr(",");
3969 case 'o':
3970 First += 2;
3971 return parsePrefixExpr("~");
3972 case 'v':
3973 return parseConversionExpr();
3974 }
3975 return nullptr;
3976 case 'd':
3977 switch (First[1]) {
3978 case 'a': {
3979 First += 2;
3980 Node *Ex = parseExpr();
3981 if (Ex == nullptr)
3982 return Ex;
3983 return make<DeleteExpr>(Ex, Global, /*is_array=*/true);
3984 }
3985 case 'c': {
3986 First += 2;
3987 Node *T = parseType();
3988 if (T == nullptr)
3989 return T;
3990 Node *Ex = parseExpr();
3991 if (Ex == nullptr)
3992 return Ex;
3993 return make<CastExpr>("dynamic_cast", T, Ex);
3994 }
3995 case 'e':
3996 First += 2;
3997 return parsePrefixExpr("*");
3998 case 'l': {
3999 First += 2;
4000 Node *E = parseExpr();
4001 if (E == nullptr)
4002 return E;
4003 return make<DeleteExpr>(E, Global, /*is_array=*/false);
4004 }
4005 case 'n':
4006 return parseUnresolvedName();
4007 case 's': {
4008 First += 2;
4009 Node *LHS = parseExpr();
4010 if (LHS == nullptr)
4011 return nullptr;
4012 Node *RHS = parseExpr();
4013 if (RHS == nullptr)
4014 return nullptr;
4015 return make<MemberExpr>(LHS, ".*", RHS);
4016 }
4017 case 't': {
4018 First += 2;
4019 Node *LHS = parseExpr();
4020 if (LHS == nullptr)
4021 return LHS;
4022 Node *RHS = parseExpr();
4023 if (RHS == nullptr)
4024 return nullptr;
4025 return make<MemberExpr>(LHS, ".", RHS);
4026 }
4027 case 'v':
4028 First += 2;
4029 return parseBinaryExpr("/");
4030 case 'V':
4031 First += 2;
4032 return parseBinaryExpr("/=");
4033 }
4034 return nullptr;
4035 case 'e':
4036 switch (First[1]) {
4037 case 'o':
4038 First += 2;
4039 return parseBinaryExpr("^");
4040 case 'O':
4041 First += 2;
4042 return parseBinaryExpr("^=");
4043 case 'q':
4044 First += 2;
4045 return parseBinaryExpr("==");
4046 }
4047 return nullptr;
4048 case 'g':
4049 switch (First[1]) {
4050 case 'e':
4051 First += 2;
4052 return parseBinaryExpr(">=");
4053 case 't':
4054 First += 2;
4055 return parseBinaryExpr(">");
4056 }
4057 return nullptr;
4058 case 'i':
4059 switch (First[1]) {
4060 case 'x': {
4061 First += 2;
4062 Node *Base = parseExpr();
4063 if (Base == nullptr)
4064 return nullptr;
4065 Node *Index = parseExpr();
4066 if (Index == nullptr)
4067 return Index;
4068 return make<ArraySubscriptExpr>(Base, Index);
4069 }
4070 case 'l': {
4071 First += 2;
4072 size_t InitsBegin = Names.size();
4073 while (!consumeIf('E')) {
4074 Node *E = parseBracedExpr();
4075 if (E == nullptr)
4076 return nullptr;
4077 Names.push_back(E);
4078 }
4079 return make<InitListExpr>(nullptr, popTrailingNodeArray(InitsBegin));
4080 }
4081 }
4082 return nullptr;
4083 case 'l':
4084 switch (First[1]) {
4085 case 'e':
4086 First += 2;
4087 return parseBinaryExpr("<=");
4088 case 's':
4089 First += 2;
4090 return parseBinaryExpr("<<");
4091 case 'S':
4092 First += 2;
4093 return parseBinaryExpr("<<=");
4094 case 't':
4095 First += 2;
4096 return parseBinaryExpr("<");
4097 }
4098 return nullptr;
4099 case 'm':
4100 switch (First[1]) {
4101 case 'i':
4102 First += 2;
4103 return parseBinaryExpr("-");
4104 case 'I':
4105 First += 2;
4106 return parseBinaryExpr("-=");
4107 case 'l':
4108 First += 2;
4109 return parseBinaryExpr("*");
4110 case 'L':
4111 First += 2;
4112 return parseBinaryExpr("*=");
4113 case 'm':
4114 First += 2;
4115 if (consumeIf('_'))
4116 return parsePrefixExpr("--");
4117 Node *Ex = parseExpr();
4118 if (Ex == nullptr)
4119 return nullptr;
4120 return make<PostfixExpr>(Ex, "--");
4121 }
4122 return nullptr;
4123 case 'n':
4124 switch (First[1]) {
4125 case 'a':
4126 case 'w':
4127 return parseNewExpr();
4128 case 'e':
4129 First += 2;
4130 return parseBinaryExpr("!=");
4131 case 'g':
4132 First += 2;
4133 return parsePrefixExpr("-");
4134 case 't':
4135 First += 2;
4136 return parsePrefixExpr("!");
4137 case 'x':
4138 First += 2;
4139 Node *Ex = parseExpr();
4140 if (Ex == nullptr)
4141 return Ex;
4142 return make<EnclosingExpr>("noexcept (", Ex, ")");
4143 }
4144 return nullptr;
4145 case 'o':
4146 switch (First[1]) {
4147 case 'n':
4148 return parseUnresolvedName();
4149 case 'o':
4150 First += 2;
4151 return parseBinaryExpr("||");
4152 case 'r':
4153 First += 2;
4154 return parseBinaryExpr("|");
4155 case 'R':
4156 First += 2;
4157 return parseBinaryExpr("|=");
4158 }
4159 return nullptr;
4160 case 'p':
4161 switch (First[1]) {
4162 case 'm':
4163 First += 2;
4164 return parseBinaryExpr("->*");
4165 case 'l':
4166 First += 2;
4167 return parseBinaryExpr("+");
4168 case 'L':
4169 First += 2;
4170 return parseBinaryExpr("+=");
4171 case 'p': {
4172 First += 2;
4173 if (consumeIf('_'))
4174 return parsePrefixExpr("++");
4175 Node *Ex = parseExpr();
4176 if (Ex == nullptr)
4177 return Ex;
4178 return make<PostfixExpr>(Ex, "++");
4179 }
4180 case 's':
4181 First += 2;
4182 return parsePrefixExpr("+");
4183 case 't': {
4184 First += 2;
4185 Node *L = parseExpr();
4186 if (L == nullptr)
4187 return nullptr;
4188 Node *R = parseExpr();
4189 if (R == nullptr)
4190 return nullptr;
4191 return make<MemberExpr>(L, "->", R);
4192 }
4193 }
4194 return nullptr;
4195 case 'q':
4196 if (First[1] == 'u') {
4197 First += 2;
4198 Node *Cond = parseExpr();
4199 if (Cond == nullptr)
4200 return nullptr;
4201 Node *LHS = parseExpr();
4202 if (LHS == nullptr)
4203 return nullptr;
4204 Node *RHS = parseExpr();
4205 if (RHS == nullptr)
4206 return nullptr;
4207 return make<ConditionalExpr>(Cond, LHS, RHS);
4208 }
4209 return nullptr;
4210 case 'r':
4211 switch (First[1]) {
4212 case 'c': {
4213 First += 2;
4214 Node *T = parseType();
4215 if (T == nullptr)
4216 return T;
4217 Node *Ex = parseExpr();
4218 if (Ex == nullptr)
4219 return Ex;
4220 return make<CastExpr>("reinterpret_cast", T, Ex);
4221 }
4222 case 'm':
4223 First += 2;
4224 return parseBinaryExpr("%");
4225 case 'M':
4226 First += 2;
4227 return parseBinaryExpr("%=");
4228 case 's':
4229 First += 2;
4230 return parseBinaryExpr(">>");
4231 case 'S':
4232 First += 2;
4233 return parseBinaryExpr(">>=");
4234 }
4235 return nullptr;
4236 case 's':
4237 switch (First[1]) {
4238 case 'c': {
4239 First += 2;
4240 Node *T = parseType();
4241 if (T == nullptr)
4242 return T;
4243 Node *Ex = parseExpr();
4244 if (Ex == nullptr)
4245 return Ex;
4246 return make<CastExpr>("static_cast", T, Ex);
4247 }
4248 case 'p': {
4249 First += 2;
4250 Node *Child = parseExpr();
4251 if (Child == nullptr)
4252 return nullptr;
4253 return make<ParameterPackExpansion>(Child);
4254 }
4255 case 'r':
4256 return parseUnresolvedName();
4257 case 't': {
4258 First += 2;
4259 Node *Ty = parseType();
4260 if (Ty == nullptr)
4261 return Ty;
4262 return make<EnclosingExpr>("sizeof (", Ty, ")");
4263 }
4264 case 'z': {
4265 First += 2;
4266 Node *Ex = parseExpr();
4267 if (Ex == nullptr)
4268 return Ex;
4269 return make<EnclosingExpr>("sizeof (", Ex, ")");
4270 }
4271 case 'Z':
4272 First += 2;
4273 if (look() == 'T') {
4274 Node *R = parseTemplateParam();
4275 if (R == nullptr)
4276 return nullptr;
4277 return make<SizeofParamPackExpr>(R);
4278 } else if (look() == 'f') {
4279 Node *FP = parseFunctionParam();
4280 if (FP == nullptr)
4281 return nullptr;
Erik Pilkington650130a2018-04-09 18:31:50 +00004282 return make<EnclosingExpr>("sizeof... (", FP, ")");
Erik Pilkingtonbb7feae2018-03-19 15:18:23 +00004283 }
4284 return nullptr;
Erik Pilkington650130a2018-04-09 18:31:50 +00004285 case 'P': {
4286 First += 2;
4287 size_t ArgsBegin = Names.size();
4288 while (!consumeIf('E')) {
4289 Node *Arg = parseTemplateArg();
4290 if (Arg == nullptr)
4291 return nullptr;
4292 Names.push_back(Arg);
4293 }
4294 return make<EnclosingExpr>(
4295 "sizeof... (", make<NodeArrayNode>(popTrailingNodeArray(ArgsBegin)),
4296 ")");
4297 }
Erik Pilkingtonbb7feae2018-03-19 15:18:23 +00004298 }
4299 return nullptr;
4300 case 't':
4301 switch (First[1]) {
4302 case 'e': {
4303 First += 2;
4304 Node *Ex = parseExpr();
4305 if (Ex == nullptr)
4306 return Ex;
4307 return make<EnclosingExpr>("typeid (", Ex, ")");
4308 }
4309 case 'i': {
4310 First += 2;
4311 Node *Ty = parseType();
4312 if (Ty == nullptr)
4313 return Ty;
4314 return make<EnclosingExpr>("typeid (", Ty, ")");
4315 }
4316 case 'l': {
4317 First += 2;
4318 Node *Ty = parseType();
4319 if (Ty == nullptr)
4320 return nullptr;
4321 size_t InitsBegin = Names.size();
4322 while (!consumeIf('E')) {
4323 Node *E = parseBracedExpr();
4324 if (E == nullptr)
4325 return nullptr;
4326 Names.push_back(E);
4327 }
4328 return make<InitListExpr>(Ty, popTrailingNodeArray(InitsBegin));
4329 }
4330 case 'r':
4331 First += 2;
4332 return make<NameType>("throw");
4333 case 'w': {
4334 First += 2;
4335 Node *Ex = parseExpr();
4336 if (Ex == nullptr)
4337 return nullptr;
4338 return make<ThrowExpr>(Ex);
4339 }
4340 }
4341 return nullptr;
4342 case '1':
4343 case '2':
4344 case '3':
4345 case '4':
4346 case '5':
4347 case '6':
4348 case '7':
4349 case '8':
4350 case '9':
4351 return parseUnresolvedName();
4352 }
4353 return nullptr;
Rafael Espindolab940b662016-09-06 19:16:48 +00004354}
4355
4356// <call-offset> ::= h <nv-offset> _
4357// ::= v <v-offset> _
4358//
4359// <nv-offset> ::= <offset number>
4360// # non-virtual base override
4361//
4362// <v-offset> ::= <offset number> _ <virtual offset number>
4363// # virtual base override, with vcall offset
Erik Pilkingtonbb7feae2018-03-19 15:18:23 +00004364bool Db::parseCallOffset() {
4365 // Just scan through the call offset, we never add this information into the
4366 // output.
4367 if (consumeIf('h'))
4368 return parseNumber(true).empty() || !consumeIf('_');
4369 if (consumeIf('v'))
4370 return parseNumber(true).empty() || !consumeIf('_') ||
4371 parseNumber(true).empty() || !consumeIf('_');
4372 return true;
Rafael Espindolab940b662016-09-06 19:16:48 +00004373}
4374
4375// <special-name> ::= TV <type> # virtual table
4376// ::= TT <type> # VTT structure (construction vtable index)
4377// ::= TI <type> # typeinfo structure
4378// ::= TS <type> # typeinfo name (null-terminated byte string)
4379// ::= Tc <call-offset> <call-offset> <base encoding>
4380// # base is the nominal target function of thunk
4381// # first call-offset is 'this' adjustment
4382// # second call-offset is result adjustment
4383// ::= T <call-offset> <base encoding>
4384// # base is the nominal target function of thunk
Erik Pilkingtonbb7feae2018-03-19 15:18:23 +00004385// ::= GV <object name> # Guard variable for one-time initialization
Rafael Espindolab940b662016-09-06 19:16:48 +00004386// # No <type>
David Bozier60b80d22017-01-31 15:56:36 +00004387// ::= TW <object name> # Thread-local wrapper
4388// ::= TH <object name> # Thread-local initialization
Erik Pilkingtonbb7feae2018-03-19 15:18:23 +00004389// ::= GR <object name> _ # First temporary
4390// ::= GR <object name> <seq-id> _ # Subsequent temporaries
4391// extension ::= TC <first type> <number> _ <second type> # construction vtable for second-in-first
Rafael Espindolab940b662016-09-06 19:16:48 +00004392// extension ::= GR <object name> # reference temporary for object
Erik Pilkingtonbb7feae2018-03-19 15:18:23 +00004393Node *Db::parseSpecialName() {
4394 switch (look()) {
4395 case 'T':
4396 switch (look(1)) {
4397 // TV <type> # virtual table
4398 case 'V': {
4399 First += 2;
4400 Node *Ty = parseType();
4401 if (Ty == nullptr)
4402 return nullptr;
4403 return make<SpecialName>("vtable for ", Ty);
4404 }
4405 // TT <type> # VTT structure (construction vtable index)
4406 case 'T': {
4407 First += 2;
4408 Node *Ty = parseType();
4409 if (Ty == nullptr)
4410 return nullptr;
4411 return make<SpecialName>("VTT for ", Ty);
4412 }
4413 // TI <type> # typeinfo structure
4414 case 'I': {
4415 First += 2;
4416 Node *Ty = parseType();
4417 if (Ty == nullptr)
4418 return nullptr;
4419 return make<SpecialName>("typeinfo for ", Ty);
4420 }
4421 // TS <type> # typeinfo name (null-terminated byte string)
4422 case 'S': {
4423 First += 2;
4424 Node *Ty = parseType();
4425 if (Ty == nullptr)
4426 return nullptr;
4427 return make<SpecialName>("typeinfo name for ", Ty);
4428 }
4429 // Tc <call-offset> <call-offset> <base encoding>
4430 case 'c': {
4431 First += 2;
4432 if (parseCallOffset() || parseCallOffset())
4433 return nullptr;
4434 Node *Encoding = parseEncoding();
4435 if (Encoding == nullptr)
4436 return nullptr;
4437 return make<SpecialName>("covariant return thunk to ", Encoding);
4438 }
4439 // extension ::= TC <first type> <number> _ <second type>
4440 // # construction vtable for second-in-first
4441 case 'C': {
4442 First += 2;
4443 Node *FirstType = parseType();
4444 if (FirstType == nullptr)
4445 return nullptr;
4446 if (parseNumber(true).empty() || !consumeIf('_'))
4447 return nullptr;
4448 Node *SecondType = parseType();
4449 if (SecondType == nullptr)
4450 return nullptr;
4451 return make<CtorVtableSpecialName>(SecondType, FirstType);
4452 }
4453 // TW <object name> # Thread-local wrapper
4454 case 'W': {
4455 First += 2;
4456 Node *Name = parseName();
4457 if (Name == nullptr)
4458 return nullptr;
4459 return make<SpecialName>("thread-local wrapper routine for ", Name);
4460 }
4461 // TH <object name> # Thread-local initialization
4462 case 'H': {
4463 First += 2;
4464 Node *Name = parseName();
4465 if (Name == nullptr)
4466 return nullptr;
4467 return make<SpecialName>("thread-local initialization routine for ", Name);
4468 }
4469 // T <call-offset> <base encoding>
4470 default: {
4471 ++First;
4472 bool IsVirt = look() == 'v';
4473 if (parseCallOffset())
4474 return nullptr;
4475 Node *BaseEncoding = parseEncoding();
4476 if (BaseEncoding == nullptr)
4477 return nullptr;
4478 if (IsVirt)
4479 return make<SpecialName>("virtual thunk to ", BaseEncoding);
4480 else
4481 return make<SpecialName>("non-virtual thunk to ", BaseEncoding);
4482 }
4483 }
4484 case 'G':
4485 switch (look(1)) {
4486 // GV <object name> # Guard variable for one-time initialization
4487 case 'V': {
4488 First += 2;
4489 Node *Name = parseName();
4490 if (Name == nullptr)
4491 return nullptr;
4492 return make<SpecialName>("guard variable for ", Name);
4493 }
4494 // GR <object name> # reference temporary for object
4495 // GR <object name> _ # First temporary
4496 // GR <object name> <seq-id> _ # Subsequent temporaries
4497 case 'R': {
4498 First += 2;
4499 Node *Name = parseName();
4500 if (Name == nullptr)
4501 return nullptr;
4502 size_t Count;
4503 bool ParsedSeqId = !parseSeqId(&Count);
4504 if (!consumeIf('_') && ParsedSeqId)
4505 return nullptr;
4506 return make<SpecialName>("reference temporary for ", Name);
4507 }
Rafael Espindolab940b662016-09-06 19:16:48 +00004508 }
4509 }
Erik Pilkingtonbb7feae2018-03-19 15:18:23 +00004510 return nullptr;
Rafael Espindolab940b662016-09-06 19:16:48 +00004511}
4512
4513// <encoding> ::= <function name> <bare-function-type>
4514// ::= <data name>
4515// ::= <special-name>
Erik Pilkingtonbb7feae2018-03-19 15:18:23 +00004516Node *Db::parseEncoding() {
Erik Pilkingtonbb7feae2018-03-19 15:18:23 +00004517 if (look() == 'G' || look() == 'T')
4518 return parseSpecialName();
4519
4520 auto IsEndOfEncoding = [&] {
4521 // The set of chars that can potentially follow an <encoding> (none of which
4522 // can start a <type>). Enumerating these allows us to avoid speculative
4523 // parsing.
4524 return numLeft() == 0 || look() == 'E' || look() == '.' || look() == '_';
4525 };
4526
Erik Pilkington8a1cb332018-03-25 22:50:33 +00004527 NameState NameInfo(this);
Erik Pilkingtonbb7feae2018-03-19 15:18:23 +00004528 Node *Name = parseName(&NameInfo);
Erik Pilkington8a1cb332018-03-25 22:50:33 +00004529 if (Name == nullptr)
4530 return nullptr;
Erik Pilkingtonbb7feae2018-03-19 15:18:23 +00004531
Erik Pilkington8a1cb332018-03-25 22:50:33 +00004532 if (resolveForwardTemplateRefs(NameInfo))
4533 return nullptr;
4534
4535 if (IsEndOfEncoding())
4536 return Name;
Erik Pilkingtonbb7feae2018-03-19 15:18:23 +00004537
Erik Pilkingtonc7287862018-03-25 22:49:16 +00004538 Node *Attrs = nullptr;
4539 if (consumeIf("Ua9enable_ifI")) {
4540 size_t BeforeArgs = Names.size();
4541 while (!consumeIf('E')) {
4542 Node *Arg = parseTemplateArg();
4543 if (Arg == nullptr)
4544 return nullptr;
4545 Names.push_back(Arg);
4546 }
4547 Attrs = make<EnableIfAttr>(popTrailingNodeArray(BeforeArgs));
4548 }
4549
Erik Pilkingtonbb7feae2018-03-19 15:18:23 +00004550 Node *ReturnType = nullptr;
4551 if (!NameInfo.CtorDtorConversion && NameInfo.EndsWithTemplateArgs) {
4552 ReturnType = parseType();
4553 if (ReturnType == nullptr)
4554 return nullptr;
4555 }
4556
4557 if (consumeIf('v'))
4558 return make<FunctionEncoding>(ReturnType, Name, NodeArray(),
Erik Pilkingtonc7287862018-03-25 22:49:16 +00004559 Attrs, NameInfo.CVQualifiers,
Erik Pilkingtonbb7feae2018-03-19 15:18:23 +00004560 NameInfo.ReferenceQualifier);
4561
4562 size_t ParamsBegin = Names.size();
4563 do {
4564 Node *Ty = parseType();
4565 if (Ty == nullptr)
4566 return nullptr;
4567 Names.push_back(Ty);
4568 } while (!IsEndOfEncoding());
4569
4570 return make<FunctionEncoding>(ReturnType, Name,
4571 popTrailingNodeArray(ParamsBegin),
Erik Pilkingtonc7287862018-03-25 22:49:16 +00004572 Attrs, NameInfo.CVQualifiers,
Erik Pilkingtonbb7feae2018-03-19 15:18:23 +00004573 NameInfo.ReferenceQualifier);
4574}
4575
4576template <class Float>
4577struct FloatData;
4578
4579template <>
4580struct FloatData<float>
4581{
4582 static const size_t mangled_size = 8;
4583 static const size_t max_demangled_size = 24;
4584 static constexpr const char* spec = "%af";
4585};
4586
4587constexpr const char* FloatData<float>::spec;
4588
4589template <>
4590struct FloatData<double>
4591{
4592 static const size_t mangled_size = 16;
4593 static const size_t max_demangled_size = 32;
4594 static constexpr const char* spec = "%a";
4595};
4596
4597constexpr const char* FloatData<double>::spec;
4598
4599template <>
4600struct FloatData<long double>
4601{
4602#if defined(__mips__) && defined(__mips_n64) || defined(__aarch64__) || \
4603 defined(__wasm__)
4604 static const size_t mangled_size = 32;
4605#elif defined(__arm__) || defined(__mips__) || defined(__hexagon__)
4606 static const size_t mangled_size = 16;
4607#else
4608 static const size_t mangled_size = 20; // May need to be adjusted to 16 or 24 on other platforms
4609#endif
4610 static const size_t max_demangled_size = 40;
4611 static constexpr const char *spec = "%LaL";
4612};
4613
4614constexpr const char *FloatData<long double>::spec;
4615
4616template <class Float> Node *Db::parseFloatingLiteral() {
4617 const size_t N = FloatData<Float>::mangled_size;
4618 if (numLeft() <= N)
4619 return nullptr;
4620 StringView Data(First, First + N);
4621 for (char C : Data)
4622 if (!std::isxdigit(C))
4623 return nullptr;
4624 First += N;
4625 if (!consumeIf('E'))
4626 return nullptr;
4627 return make<FloatExpr<Float>>(Data);
4628}
4629
4630// <seq-id> ::= <0-9A-Z>+
4631bool Db::parseSeqId(size_t *Out) {
4632 if (!(look() >= '0' && look() <= '9') &&
4633 !(look() >= 'A' && look() <= 'Z'))
4634 return true;
4635
4636 size_t Id = 0;
4637 while (true) {
4638 if (look() >= '0' && look() <= '9') {
4639 Id *= 36;
4640 Id += static_cast<size_t>(look() - '0');
4641 } else if (look() >= 'A' && look() <= 'Z') {
4642 Id *= 36;
4643 Id += static_cast<size_t>(look() - 'A') + 10;
4644 } else {
4645 *Out = Id;
4646 return false;
4647 }
4648 ++First;
4649 }
4650}
4651
4652// <substitution> ::= S <seq-id> _
4653// ::= S_
4654// <substitution> ::= Sa # ::std::allocator
4655// <substitution> ::= Sb # ::std::basic_string
4656// <substitution> ::= Ss # ::std::basic_string < char,
4657// ::std::char_traits<char>,
4658// ::std::allocator<char> >
4659// <substitution> ::= Si # ::std::basic_istream<char, std::char_traits<char> >
4660// <substitution> ::= So # ::std::basic_ostream<char, std::char_traits<char> >
4661// <substitution> ::= Sd # ::std::basic_iostream<char, std::char_traits<char> >
4662Node *Db::parseSubstitution() {
4663 if (!consumeIf('S'))
4664 return nullptr;
4665
4666 if (std::islower(look())) {
4667 Node *SpecialSub;
4668 switch (look()) {
4669 case 'a':
4670 ++First;
4671 SpecialSub = make<SpecialSubstitution>(SpecialSubKind::allocator);
Rafael Espindolab940b662016-09-06 19:16:48 +00004672 break;
Erik Pilkingtonbb7feae2018-03-19 15:18:23 +00004673 case 'b':
4674 ++First;
4675 SpecialSub = make<SpecialSubstitution>(SpecialSubKind::basic_string);
4676 break;
4677 case 's':
4678 ++First;
4679 SpecialSub = make<SpecialSubstitution>(SpecialSubKind::string);
4680 break;
4681 case 'i':
4682 ++First;
4683 SpecialSub = make<SpecialSubstitution>(SpecialSubKind::istream);
4684 break;
4685 case 'o':
4686 ++First;
4687 SpecialSub = make<SpecialSubstitution>(SpecialSubKind::ostream);
4688 break;
4689 case 'd':
4690 ++First;
4691 SpecialSub = make<SpecialSubstitution>(SpecialSubKind::iostream);
4692 break;
4693 default:
4694 return nullptr;
4695 }
4696 // Itanium C++ ABI 5.1.2: If a name that would use a built-in <substitution>
4697 // has ABI tags, the tags are appended to the substitution; the result is a
4698 // substitutable component.
4699 Node *WithTags = parseAbiTags(SpecialSub);
4700 if (WithTags != SpecialSub) {
4701 Subs.push_back(WithTags);
4702 SpecialSub = WithTags;
4703 }
4704 return SpecialSub;
4705 }
Rafael Espindolab940b662016-09-06 19:16:48 +00004706
Erik Pilkingtonbb7feae2018-03-19 15:18:23 +00004707 // ::= S_
4708 if (consumeIf('_')) {
4709 if (Subs.empty())
4710 return nullptr;
4711 return Subs[0];
4712 }
4713
4714 // ::= S <seq-id> _
4715 size_t Index = 0;
4716 if (parseSeqId(&Index))
4717 return nullptr;
4718 ++Index;
4719 if (!consumeIf('_') || Index >= Subs.size())
4720 return nullptr;
4721 return Subs[Index];
4722}
4723
4724// <template-param> ::= T_ # first template parameter
4725// ::= T <parameter-2 non-negative number> _
4726Node *Db::parseTemplateParam() {
4727 if (!consumeIf('T'))
4728 return nullptr;
4729
4730 size_t Index = 0;
4731 if (!consumeIf('_')) {
4732 if (parsePositiveInteger(&Index))
4733 return nullptr;
4734 ++Index;
4735 if (!consumeIf('_'))
4736 return nullptr;
4737 }
4738
4739 // Itanium ABI 5.1.8: In a generic lambda, uses of auto in the parameter list
4740 // are mangled as the corresponding artificial template type parameter.
4741 if (ParsingLambdaParams)
4742 return make<NameType>("auto");
4743
Erik Pilkington8a1cb332018-03-25 22:50:33 +00004744 // If we're in a context where this <template-param> refers to a
4745 // <template-arg> further ahead in the mangled name (currently just conversion
4746 // operator types), then we should only look it up in the right context.
4747 if (PermitForwardTemplateReferences) {
4748 ForwardTemplateRefs.push_back(make<ForwardTemplateReference>(Index));
4749 return ForwardTemplateRefs.back();
Erik Pilkingtonbb7feae2018-03-19 15:18:23 +00004750 }
Erik Pilkington8a1cb332018-03-25 22:50:33 +00004751
4752 if (Index >= TemplateParams.size())
4753 return nullptr;
Erik Pilkingtonbb7feae2018-03-19 15:18:23 +00004754 return TemplateParams[Index];
4755}
4756
4757// <template-arg> ::= <type> # type or template
4758// ::= X <expression> E # expression
4759// ::= <expr-primary> # simple expressions
4760// ::= J <template-arg>* E # argument pack
4761// ::= LZ <encoding> E # extension
4762Node *Db::parseTemplateArg() {
4763 switch (look()) {
4764 case 'X': {
4765 ++First;
4766 Node *Arg = parseExpr();
4767 if (Arg == nullptr || !consumeIf('E'))
4768 return nullptr;
4769 return Arg;
4770 }
4771 case 'J': {
4772 ++First;
4773 size_t ArgsBegin = Names.size();
4774 while (!consumeIf('E')) {
4775 Node *Arg = parseTemplateArg();
4776 if (Arg == nullptr)
4777 return nullptr;
4778 Names.push_back(Arg);
4779 }
4780 NodeArray Args = popTrailingNodeArray(ArgsBegin);
4781 return make<TemplateArgumentPack>(Args);
4782 }
4783 case 'L': {
4784 // ::= LZ <encoding> E # extension
4785 if (look(1) == 'Z') {
4786 First += 2;
4787 Node *Arg = parseEncoding();
4788 if (Arg == nullptr || !consumeIf('E'))
4789 return nullptr;
4790 return Arg;
4791 }
4792 // ::= <expr-primary> # simple expressions
4793 return parseExprPrimary();
4794 }
4795 default:
4796 return parseType();
4797 }
4798}
4799
4800// <template-args> ::= I <template-arg>* E
4801// extension, the abi says <template-arg>+
Erik Pilkington8a1cb332018-03-25 22:50:33 +00004802Node *Db::parseTemplateArgs(bool TagTemplates) {
Erik Pilkingtonbb7feae2018-03-19 15:18:23 +00004803 if (!consumeIf('I'))
4804 return nullptr;
4805
4806 // <template-params> refer to the innermost <template-args>. Clear out any
4807 // outer args that we may have inserted into TemplateParams.
4808 if (TagTemplates)
4809 TemplateParams.clear();
4810
4811 size_t ArgsBegin = Names.size();
4812 while (!consumeIf('E')) {
4813 if (TagTemplates) {
4814 auto OldParams = std::move(TemplateParams);
4815 Node *Arg = parseTemplateArg();
4816 TemplateParams = std::move(OldParams);
4817 if (Arg == nullptr)
4818 return nullptr;
4819 Names.push_back(Arg);
4820 Node *TableEntry = Arg;
4821 if (Arg->getKind() == Node::KTemplateArgumentPack) {
4822 TableEntry = make<ParameterPack>(
4823 static_cast<TemplateArgumentPack*>(TableEntry)->getElements());
4824 }
4825 TemplateParams.push_back(TableEntry);
4826 } else {
4827 Node *Arg = parseTemplateArg();
4828 if (Arg == nullptr)
4829 return nullptr;
4830 Names.push_back(Arg);
4831 }
4832 }
4833 return make<TemplateArgs>(popTrailingNodeArray(ArgsBegin));
4834}
4835
4836// <discriminator> := _ <non-negative number> # when number < 10
4837// := __ <non-negative number> _ # when number >= 10
4838// extension := decimal-digit+ # at the end of string
4839
4840const char*
4841parse_discriminator(const char* first, const char* last)
4842{
4843 // parse but ignore discriminator
4844 if (first != last)
4845 {
4846 if (*first == '_')
4847 {
4848 const char* t1 = first+1;
4849 if (t1 != last)
4850 {
4851 if (std::isdigit(*t1))
4852 first = t1+1;
4853 else if (*t1 == '_')
4854 {
4855 for (++t1; t1 != last && std::isdigit(*t1); ++t1)
4856 ;
4857 if (t1 != last && *t1 == '_')
4858 first = t1 + 1;
Rafael Espindolab940b662016-09-06 19:16:48 +00004859 }
Rafael Espindolab940b662016-09-06 19:16:48 +00004860 }
Erik Pilkingtonbb7feae2018-03-19 15:18:23 +00004861 }
4862 else if (std::isdigit(*first))
4863 {
4864 const char* t1 = first+1;
4865 for (; t1 != last && std::isdigit(*t1); ++t1)
4866 ;
4867 if (t1 == last)
4868 first = last;
4869 }
Rafael Espindolab940b662016-09-06 19:16:48 +00004870 }
Erik Pilkingtonbb7feae2018-03-19 15:18:23 +00004871 return first;
Rafael Espindolab940b662016-09-06 19:16:48 +00004872}
4873
Erik Pilkingtonbb7feae2018-03-19 15:18:23 +00004874// <mangled-name> ::= _Z <encoding>
Rafael Espindolab940b662016-09-06 19:16:48 +00004875// ::= <type>
Erik Pilkingtonbb7feae2018-03-19 15:18:23 +00004876// extension ::= ___Z <encoding> _block_invoke
4877// extension ::= ___Z <encoding> _block_invoke<decimal-digit>+
4878// extension ::= ___Z <encoding> _block_invoke_<decimal-digit>+
4879Node *Db::parse() {
4880 if (consumeIf("_Z")) {
4881 Node *Encoding = parseEncoding();
4882 if (Encoding == nullptr)
4883 return nullptr;
4884 if (look() == '.') {
4885 Encoding = make<DotSuffix>(Encoding, StringView(First, Last));
4886 First = Last;
4887 }
4888 if (numLeft() != 0)
4889 return nullptr;
4890 return Encoding;
4891 }
Rafael Espindolab940b662016-09-06 19:16:48 +00004892
Erik Pilkingtonbb7feae2018-03-19 15:18:23 +00004893 if (consumeIf("___Z")) {
4894 Node *Encoding = parseEncoding();
4895 if (Encoding == nullptr || !consumeIf("_block_invoke"))
4896 return nullptr;
4897 bool RequireNumber = consumeIf('_');
4898 if (parseNumber().empty() && RequireNumber)
4899 return nullptr;
4900 if (numLeft() != 0)
4901 return nullptr;
4902 return make<SpecialName>("invocation function for block in ", Encoding);
Rafael Espindolab940b662016-09-06 19:16:48 +00004903 }
Erik Pilkingtonbb7feae2018-03-19 15:18:23 +00004904
4905 Node *Ty = parseType();
4906 if (numLeft() != 0)
4907 return nullptr;
4908 return Ty;
Rafael Espindolab940b662016-09-06 19:16:48 +00004909}
Erik Pilkingtonf2a9b0f2018-04-12 20:41:06 +00004910
4911bool initializeOutputStream(char *Buf, size_t *N, OutputStream &S,
4912 size_t InitSize) {
4913 size_t BufferSize;
4914 if (Buf == nullptr) {
4915 Buf = static_cast<char *>(std::malloc(InitSize));
4916 if (Buf == nullptr)
4917 return true;
4918 BufferSize = InitSize;
4919 } else
4920 BufferSize = *N;
4921
4922 S.reset(Buf, BufferSize);
4923 return false;
4924}
4925
Erik Pilkingtonbb7feae2018-03-19 15:18:23 +00004926} // unnamed namespace
Rafael Espindolab940b662016-09-06 19:16:48 +00004927
Erik Pilkingtonbb7feae2018-03-19 15:18:23 +00004928enum {
4929 unknown_error = -4,
4930 invalid_args = -3,
4931 invalid_mangled_name = -2,
4932 memory_alloc_failure = -1,
4933 success = 0,
Rafael Espindolab940b662016-09-06 19:16:48 +00004934};
4935
Erik Pilkingtonbb7feae2018-03-19 15:18:23 +00004936char *llvm::itaniumDemangle(const char *MangledName, char *Buf,
4937 size_t *N, int *Status) {
4938 if (MangledName == nullptr || (Buf != nullptr && N == nullptr)) {
4939 if (Status)
4940 *Status = invalid_args;
Rafael Espindolab940b662016-09-06 19:16:48 +00004941 return nullptr;
4942 }
Erik Pilkingtonbb7feae2018-03-19 15:18:23 +00004943
Erik Pilkingtonbb7feae2018-03-19 15:18:23 +00004944 int InternalStatus = success;
Erik Pilkingtonf2a9b0f2018-04-12 20:41:06 +00004945 Db Parser(MangledName, MangledName + std::strlen(MangledName));
4946 OutputStream S;
Erik Pilkingtonbb7feae2018-03-19 15:18:23 +00004947
Erik Pilkingtonbb7feae2018-03-19 15:18:23 +00004948 Node *AST = Parser.parse();
4949
4950 if (AST == nullptr)
4951 InternalStatus = invalid_mangled_name;
Erik Pilkingtonf2a9b0f2018-04-12 20:41:06 +00004952 else if (initializeOutputStream(Buf, N, S, 1024))
4953 InternalStatus = memory_alloc_failure;
4954 else {
Erik Pilkington8a1cb332018-03-25 22:50:33 +00004955 assert(Parser.ForwardTemplateRefs.empty());
Erik Pilkingtonf2a9b0f2018-04-12 20:41:06 +00004956 AST->print(S);
4957 S += '\0';
4958 if (N != nullptr)
4959 *N = S.getCurrentPosition();
4960 Buf = S.getBuffer();
Erik Pilkingtonbb7feae2018-03-19 15:18:23 +00004961 }
4962
4963 if (Status)
4964 *Status = InternalStatus;
4965 return InternalStatus == success ? Buf : nullptr;
Rafael Espindolab940b662016-09-06 19:16:48 +00004966}
Erik Pilkington67d82d62018-04-12 20:41:38 +00004967
4968namespace llvm {
4969
4970ItaniumPartialDemangler::ItaniumPartialDemangler()
4971 : RootNode(nullptr), Context(new Db{nullptr, nullptr}) {}
4972
4973ItaniumPartialDemangler::~ItaniumPartialDemangler() {
4974 delete static_cast<Db *>(Context);
4975}
4976
4977ItaniumPartialDemangler::ItaniumPartialDemangler(
4978 ItaniumPartialDemangler &&Other)
4979 : RootNode(Other.RootNode), Context(Other.Context) {
4980 Other.Context = Other.RootNode = nullptr;
4981}
4982
4983ItaniumPartialDemangler &ItaniumPartialDemangler::
4984operator=(ItaniumPartialDemangler &&Other) {
4985 std::swap(RootNode, Other.RootNode);
4986 std::swap(Context, Other.Context);
4987 return *this;
4988}
4989
4990// Demangle MangledName into an AST, storing it into this->RootNode.
4991bool ItaniumPartialDemangler::partialDemangle(const char *MangledName) {
4992 Db *Parser = static_cast<Db *>(Context);
4993 size_t Len = std::strlen(MangledName);
4994 Parser->reset(MangledName, MangledName + Len);
4995 RootNode = Parser->parse();
4996 return RootNode == nullptr;
4997}
4998
4999static char *printNode(Node *RootNode, char *Buf, size_t *N) {
5000 OutputStream S;
5001 if (initializeOutputStream(Buf, N, S, 128))
5002 return nullptr;
5003 RootNode->print(S);
5004 S += '\0';
5005 if (N != nullptr)
5006 *N = S.getCurrentPosition();
5007 return S.getBuffer();
5008}
5009
5010char *ItaniumPartialDemangler::getFunctionBaseName(char *Buf, size_t *N) const {
5011 if (!isFunction())
5012 return nullptr;
5013
5014 Node *Name = static_cast<FunctionEncoding *>(RootNode)->getName();
5015
5016 while (true) {
5017 switch (Name->getKind()) {
5018 case Node::KAbiTagAttr:
5019 Name = static_cast<AbiTagAttr *>(Name)->Base;
5020 continue;
5021 case Node::KStdQualifiedName:
5022 Name = static_cast<StdQualifiedName *>(Name)->Child;
5023 continue;
5024 case Node::KNestedName:
5025 Name = static_cast<NestedName *>(Name)->Name;
5026 continue;
5027 case Node::KLocalName:
5028 Name = static_cast<LocalName *>(Name)->Entity;
5029 continue;
5030 case Node::KNameWithTemplateArgs:
5031 Name = static_cast<NameWithTemplateArgs *>(Name)->Name;
5032 continue;
5033 default:
5034 return printNode(Name, Buf, N);
5035 }
5036 }
5037}
5038
5039char *ItaniumPartialDemangler::getFunctionDeclContextName(char *Buf,
5040 size_t *N) const {
5041 if (!isFunction())
5042 return nullptr;
5043 Node *Name = static_cast<FunctionEncoding *>(RootNode)->getName();
5044
5045 OutputStream S;
5046 if (initializeOutputStream(Buf, N, S, 128))
5047 return nullptr;
5048
5049 KeepGoingLocalFunction:
5050 while (true) {
5051 if (Name->getKind() == Node::KAbiTagAttr) {
5052 Name = static_cast<AbiTagAttr *>(Name)->Base;
5053 continue;
5054 }
5055 if (Name->getKind() == Node::KNameWithTemplateArgs) {
5056 Name = static_cast<NameWithTemplateArgs *>(Name)->Name;
5057 continue;
5058 }
5059 break;
5060 }
5061
5062 switch (Name->getKind()) {
5063 case Node::KStdQualifiedName:
5064 S += "std";
5065 break;
5066 case Node::KNestedName:
5067 static_cast<NestedName *>(Name)->Qual->print(S);
5068 break;
5069 case Node::KLocalName: {
5070 auto *LN = static_cast<LocalName *>(Name);
5071 LN->Encoding->print(S);
5072 S += "::";
5073 Name = LN->Entity;
5074 goto KeepGoingLocalFunction;
5075 }
5076 default:
5077 break;
5078 }
5079 S += '\0';
5080 if (N != nullptr)
5081 *N = S.getCurrentPosition();
5082 return S.getBuffer();
5083}
5084
5085char *ItaniumPartialDemangler::getFunctionName(char *Buf, size_t *N) const {
5086 if (!isFunction())
5087 return nullptr;
5088 auto *Name = static_cast<FunctionEncoding *>(RootNode)->getName();
5089 return printNode(Name, Buf, N);
5090}
5091
5092char *ItaniumPartialDemangler::getFunctionParameters(char *Buf,
5093 size_t *N) const {
5094 if (!isFunction())
5095 return nullptr;
5096 NodeArray Params = static_cast<FunctionEncoding *>(RootNode)->getParams();
5097
5098 OutputStream S;
5099 if (initializeOutputStream(Buf, N, S, 128))
5100 return nullptr;
5101
5102 S += '(';
5103 Params.printWithComma(S);
5104 S += ')';
5105 S += '\0';
5106 if (N != nullptr)
5107 *N = S.getCurrentPosition();
5108 return S.getBuffer();
5109}
5110
5111char *ItaniumPartialDemangler::getFunctionReturnType(
5112 char *Buf, size_t *N) const {
5113 if (!isFunction())
5114 return nullptr;
5115
5116 OutputStream S;
5117 if (initializeOutputStream(Buf, N, S, 128))
5118 return nullptr;
5119
5120 if (Node *Ret = static_cast<FunctionEncoding *>(RootNode)->getReturnType())
5121 Ret->print(S);
5122
5123 S += '\0';
5124 if (N != nullptr)
5125 *N = S.getCurrentPosition();
5126 return S.getBuffer();
5127}
5128
5129char *ItaniumPartialDemangler::finishDemangle(char *Buf, size_t *N) const {
5130 assert(RootNode != nullptr && "must call partialDemangle()");
5131 return printNode(static_cast<Node *>(RootNode), Buf, N);
5132}
5133
5134bool ItaniumPartialDemangler::hasFunctionQualifiers() const {
5135 assert(RootNode != nullptr && "must call partialDemangle()");
5136 if (!isFunction())
5137 return false;
5138 auto *E = static_cast<FunctionEncoding *>(RootNode);
5139 return E->getCVQuals() != QualNone || E->getRefQual() != FrefQualNone;
5140}
5141
Fangrui Song79420ac2018-05-24 06:57:57 +00005142bool ItaniumPartialDemangler::isCtorOrDtor() const {
5143 Node *N = static_cast<Node *>(RootNode);
5144 while (N) {
5145 switch (N->getKind()) {
5146 default:
5147 return false;
5148 case Node::KCtorDtorName:
5149 return true;
5150
5151 case Node::KAbiTagAttr:
5152 N = static_cast<AbiTagAttr *>(N)->Base;
5153 break;
5154 case Node::KFunctionEncoding:
5155 N = static_cast<FunctionEncoding *>(N)->getName();
5156 break;
5157 case Node::KLocalName:
5158 N = static_cast<LocalName *>(N)->Entity;
5159 break;
5160 case Node::KNameWithTemplateArgs:
5161 N = static_cast<NameWithTemplateArgs *>(N)->Name;
5162 break;
5163 case Node::KNestedName:
5164 N = static_cast<NestedName *>(N)->Name;
5165 break;
5166 case Node::KStdQualifiedName:
5167 N = static_cast<StdQualifiedName *>(N)->Child;
5168 break;
5169 }
5170 }
5171 return false;
5172}
5173
Erik Pilkington67d82d62018-04-12 20:41:38 +00005174bool ItaniumPartialDemangler::isFunction() const {
5175 assert(RootNode != nullptr && "must call partialDemangle()");
5176 return static_cast<Node *>(RootNode)->getKind() == Node::KFunctionEncoding;
5177}
5178
5179bool ItaniumPartialDemangler::isSpecialName() const {
5180 assert(RootNode != nullptr && "must call partialDemangle()");
5181 auto K = static_cast<Node *>(RootNode)->getKind();
5182 return K == Node::KSpecialName || K == Node::KCtorVtableSpecialName;
5183}
5184
5185bool ItaniumPartialDemangler::isData() const {
5186 return !isFunction() && !isSpecialName();
5187}
5188
5189}