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