blob: 887e9be9b4986e64d28f34d6355ea47a5a20f4ad [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
Erik Pilkington256db4b2018-07-28 04:06:30 +0000453 mutable bool Printing = false;
454
Erik Pilkington3a6fed42018-07-27 17:27:40 +0000455 // Dig through any refs to refs, collapsing the ReferenceTypes as we go. The
456 // rule here is rvalue ref to rvalue ref collapses to a rvalue ref, and any
457 // other combination collapses to a lvalue ref.
458 std::pair<ReferenceKind, const Node *> collapse(OutputStream &S) const {
459 auto SoFar = std::make_pair(RK, Pointee);
460 for (;;) {
461 const Node *SN = SoFar.second->getSyntaxNode(S);
462 if (SN->getKind() != KReferenceType)
463 break;
464 auto *RT = static_cast<const ReferenceType *>(SN);
465 SoFar.second = RT->Pointee;
466 SoFar.first = std::min(SoFar.first, RT->RK);
467 }
468 return SoFar;
469 }
Erik Pilkingtonbb7feae2018-03-19 15:18:23 +0000470
471public:
Erik Pilkington3a6fed42018-07-27 17:27:40 +0000472 ReferenceType(Node *Pointee_, ReferenceKind RK_)
473 : Node(KReferenceType, Pointee_->RHSComponentCache),
474 Pointee(Pointee_), RK(RK_) {}
Erik Pilkingtonbb7feae2018-03-19 15:18:23 +0000475
476 bool hasRHSComponentSlow(OutputStream &S) const override {
477 return Pointee->hasRHSComponent(S);
478 }
479
480 void printLeft(OutputStream &s) const override {
Erik Pilkington256db4b2018-07-28 04:06:30 +0000481 if (Printing)
482 return;
483 SwapAndRestore<bool> SavePrinting(Printing, true);
Erik Pilkington3a6fed42018-07-27 17:27:40 +0000484 std::pair<ReferenceKind, const Node *> Collapsed = collapse(s);
485 Collapsed.second->printLeft(s);
486 if (Collapsed.second->hasArray(s))
Erik Pilkingtonbb7feae2018-03-19 15:18:23 +0000487 s += " ";
Erik Pilkington3a6fed42018-07-27 17:27:40 +0000488 if (Collapsed.second->hasArray(s) || Collapsed.second->hasFunction(s))
489 s += "(";
Erik Pilkingtonbb7feae2018-03-19 15:18:23 +0000490
Erik Pilkington3a6fed42018-07-27 17:27:40 +0000491 s += (Collapsed.first == ReferenceKind::LValue ? "&" : "&&");
492 }
Erik Pilkingtonbb7feae2018-03-19 15:18:23 +0000493 void printRight(OutputStream &s) const override {
Erik Pilkington256db4b2018-07-28 04:06:30 +0000494 if (Printing)
495 return;
496 SwapAndRestore<bool> SavePrinting(Printing, true);
Erik Pilkington3a6fed42018-07-27 17:27:40 +0000497 std::pair<ReferenceKind, const Node *> Collapsed = collapse(s);
498 if (Collapsed.second->hasArray(s) || Collapsed.second->hasFunction(s))
Erik Pilkingtonbb7feae2018-03-19 15:18:23 +0000499 s += ")";
Erik Pilkington3a6fed42018-07-27 17:27:40 +0000500 Collapsed.second->printRight(s);
Erik Pilkingtonbb7feae2018-03-19 15:18:23 +0000501 }
502};
503
504class PointerToMemberType final : public Node {
505 const Node *ClassType;
506 const Node *MemberType;
507
508public:
509 PointerToMemberType(Node *ClassType_, Node *MemberType_)
Erik Pilkington8c7013d2018-03-25 22:49:57 +0000510 : Node(KPointerToMemberType, MemberType_->RHSComponentCache),
Erik Pilkingtonbb7feae2018-03-19 15:18:23 +0000511 ClassType(ClassType_), MemberType(MemberType_) {}
512
513 bool hasRHSComponentSlow(OutputStream &S) const override {
514 return MemberType->hasRHSComponent(S);
515 }
516
517 void printLeft(OutputStream &s) const override {
518 MemberType->printLeft(s);
519 if (MemberType->hasArray(s) || MemberType->hasFunction(s))
520 s += "(";
521 else
522 s += " ";
523 ClassType->print(s);
524 s += "::*";
525 }
526
527 void printRight(OutputStream &s) const override {
528 if (MemberType->hasArray(s) || MemberType->hasFunction(s))
529 s += ")";
530 MemberType->printRight(s);
531 }
532};
533
534class NodeOrString {
535 const void *First;
536 const void *Second;
537
538public:
539 /* implicit */ NodeOrString(StringView Str) {
540 const char *FirstChar = Str.begin();
541 const char *SecondChar = Str.end();
542 if (SecondChar == nullptr) {
543 assert(FirstChar == SecondChar);
544 ++FirstChar, ++SecondChar;
545 }
546 First = static_cast<const void *>(FirstChar);
547 Second = static_cast<const void *>(SecondChar);
548 }
549
550 /* implicit */ NodeOrString(Node *N)
551 : First(static_cast<const void *>(N)), Second(nullptr) {}
552 NodeOrString() : First(nullptr), Second(nullptr) {}
553
554 bool isString() const { return Second && First; }
555 bool isNode() const { return First && !Second; }
556 bool isEmpty() const { return !First && !Second; }
557
558 StringView asString() const {
559 assert(isString());
560 return StringView(static_cast<const char *>(First),
561 static_cast<const char *>(Second));
562 }
563
564 const Node *asNode() const {
565 assert(isNode());
566 return static_cast<const Node *>(First);
567 }
568};
569
570class ArrayType final : public Node {
571 Node *Base;
572 NodeOrString Dimension;
573
574public:
575 ArrayType(Node *Base_, NodeOrString Dimension_)
Erik Pilkington8c7013d2018-03-25 22:49:57 +0000576 : Node(KArrayType,
Erik Pilkingtonbb7feae2018-03-19 15:18:23 +0000577 /*RHSComponentCache=*/Cache::Yes,
578 /*ArrayCache=*/Cache::Yes),
Erik Pilkington8c7013d2018-03-25 22:49:57 +0000579 Base(Base_), Dimension(Dimension_) {}
Erik Pilkingtonbb7feae2018-03-19 15:18:23 +0000580
581 // Incomplete array type.
582 ArrayType(Node *Base_)
Erik Pilkington8c7013d2018-03-25 22:49:57 +0000583 : Node(KArrayType,
Erik Pilkingtonbb7feae2018-03-19 15:18:23 +0000584 /*RHSComponentCache=*/Cache::Yes,
585 /*ArrayCache=*/Cache::Yes),
586 Base(Base_) {}
587
588 bool hasRHSComponentSlow(OutputStream &) const override { return true; }
589 bool hasArraySlow(OutputStream &) const override { return true; }
590
591 void printLeft(OutputStream &S) const override { Base->printLeft(S); }
592
593 void printRight(OutputStream &S) const override {
594 if (S.back() != ']')
595 S += " ";
596 S += "[";
597 if (Dimension.isString())
598 S += Dimension.asString();
599 else if (Dimension.isNode())
600 Dimension.asNode()->print(S);
601 S += "]";
602 Base->printRight(S);
603 }
604};
605
606class FunctionType final : public Node {
607 Node *Ret;
608 NodeArray Params;
609 Qualifiers CVQuals;
610 FunctionRefQual RefQual;
611 Node *ExceptionSpec;
612
613public:
614 FunctionType(Node *Ret_, NodeArray Params_, Qualifiers CVQuals_,
615 FunctionRefQual RefQual_, Node *ExceptionSpec_)
Erik Pilkington8c7013d2018-03-25 22:49:57 +0000616 : Node(KFunctionType,
Erik Pilkingtonbb7feae2018-03-19 15:18:23 +0000617 /*RHSComponentCache=*/Cache::Yes, /*ArrayCache=*/Cache::No,
618 /*FunctionCache=*/Cache::Yes),
619 Ret(Ret_), Params(Params_), CVQuals(CVQuals_), RefQual(RefQual_),
Erik Pilkington8c7013d2018-03-25 22:49:57 +0000620 ExceptionSpec(ExceptionSpec_) {}
Erik Pilkingtonbb7feae2018-03-19 15:18:23 +0000621
622 bool hasRHSComponentSlow(OutputStream &) const override { return true; }
623 bool hasFunctionSlow(OutputStream &) const override { return true; }
624
Simon Pilgrimcfe2f9d2018-06-26 14:06:23 +0000625 // Handle C++'s ... quirky decl grammar by using the left & right
Erik Pilkingtonbb7feae2018-03-19 15:18:23 +0000626 // distinction. Consider:
627 // int (*f(float))(char) {}
628 // f is a function that takes a float and returns a pointer to a function
629 // that takes a char and returns an int. If we're trying to print f, start
630 // by printing out the return types's left, then print our parameters, then
631 // finally print right of the return type.
632 void printLeft(OutputStream &S) const override {
633 Ret->printLeft(S);
634 S += " ";
635 }
636
637 void printRight(OutputStream &S) const override {
638 S += "(";
639 Params.printWithComma(S);
640 S += ")";
641 Ret->printRight(S);
642
643 if (CVQuals & QualConst)
644 S += " const";
645 if (CVQuals & QualVolatile)
646 S += " volatile";
647 if (CVQuals & QualRestrict)
648 S += " restrict";
649
650 if (RefQual == FrefQualLValue)
651 S += " &";
652 else if (RefQual == FrefQualRValue)
653 S += " &&";
654
655 if (ExceptionSpec != nullptr) {
656 S += ' ';
657 ExceptionSpec->print(S);
658 }
659 }
660};
661
662class NoexceptSpec : public Node {
663 Node *E;
664public:
Erik Pilkington8c7013d2018-03-25 22:49:57 +0000665 NoexceptSpec(Node *E_) : Node(KNoexceptSpec), E(E_) {}
Erik Pilkingtonbb7feae2018-03-19 15:18:23 +0000666
667 void printLeft(OutputStream &S) const override {
668 S += "noexcept(";
669 E->print(S);
670 S += ")";
671 }
672};
673
674class DynamicExceptionSpec : public Node {
675 NodeArray Types;
676public:
677 DynamicExceptionSpec(NodeArray Types_)
Erik Pilkington8c7013d2018-03-25 22:49:57 +0000678 : Node(KDynamicExceptionSpec), Types(Types_) {}
Erik Pilkingtonbb7feae2018-03-19 15:18:23 +0000679
680 void printLeft(OutputStream &S) const override {
681 S += "throw(";
682 Types.printWithComma(S);
683 S += ')';
684 }
685};
686
687class FunctionEncoding final : public Node {
Erik Pilkingtonf2a9b0f2018-04-12 20:41:06 +0000688 Node *Ret;
689 Node *Name;
Erik Pilkingtonbb7feae2018-03-19 15:18:23 +0000690 NodeArray Params;
Erik Pilkingtonc7287862018-03-25 22:49:16 +0000691 Node *Attrs;
Erik Pilkingtonbb7feae2018-03-19 15:18:23 +0000692 Qualifiers CVQuals;
693 FunctionRefQual RefQual;
694
695public:
696 FunctionEncoding(Node *Ret_, Node *Name_, NodeArray Params_,
Erik Pilkingtonc7287862018-03-25 22:49:16 +0000697 Node *Attrs_, Qualifiers CVQuals_, FunctionRefQual RefQual_)
Erik Pilkington8c7013d2018-03-25 22:49:57 +0000698 : Node(KFunctionEncoding,
Erik Pilkingtonbb7feae2018-03-19 15:18:23 +0000699 /*RHSComponentCache=*/Cache::Yes, /*ArrayCache=*/Cache::No,
700 /*FunctionCache=*/Cache::Yes),
Erik Pilkingtonc7287862018-03-25 22:49:16 +0000701 Ret(Ret_), Name(Name_), Params(Params_), Attrs(Attrs_),
Erik Pilkington8c7013d2018-03-25 22:49:57 +0000702 CVQuals(CVQuals_), RefQual(RefQual_) {}
Erik Pilkingtonbb7feae2018-03-19 15:18:23 +0000703
Erik Pilkingtonf2a9b0f2018-04-12 20:41:06 +0000704 Qualifiers getCVQuals() const { return CVQuals; }
705 FunctionRefQual getRefQual() const { return RefQual; }
706 NodeArray getParams() const { return Params; }
707 Node *getReturnType() const { return Ret; }
708
Erik Pilkingtonbb7feae2018-03-19 15:18:23 +0000709 bool hasRHSComponentSlow(OutputStream &) const override { return true; }
710 bool hasFunctionSlow(OutputStream &) const override { return true; }
711
712 Node *getName() { return const_cast<Node *>(Name); }
713
714 void printLeft(OutputStream &S) const override {
715 if (Ret) {
716 Ret->printLeft(S);
717 if (!Ret->hasRHSComponent(S))
718 S += " ";
719 }
720 Name->print(S);
721 }
722
723 void printRight(OutputStream &S) const override {
724 S += "(";
725 Params.printWithComma(S);
726 S += ")";
727 if (Ret)
728 Ret->printRight(S);
729
730 if (CVQuals & QualConst)
731 S += " const";
732 if (CVQuals & QualVolatile)
733 S += " volatile";
734 if (CVQuals & QualRestrict)
735 S += " restrict";
736
737 if (RefQual == FrefQualLValue)
738 S += " &";
739 else if (RefQual == FrefQualRValue)
740 S += " &&";
Erik Pilkingtonc7287862018-03-25 22:49:16 +0000741
742 if (Attrs != nullptr)
743 Attrs->print(S);
Erik Pilkingtonbb7feae2018-03-19 15:18:23 +0000744 }
745};
746
747class LiteralOperator : public Node {
748 const Node *OpName;
749
750public:
Erik Pilkington8c7013d2018-03-25 22:49:57 +0000751 LiteralOperator(Node *OpName_) : Node(KLiteralOperator), OpName(OpName_) {}
Erik Pilkingtonbb7feae2018-03-19 15:18:23 +0000752
753 void printLeft(OutputStream &S) const override {
754 S += "operator\"\" ";
755 OpName->print(S);
756 }
757};
758
759class SpecialName final : public Node {
760 const StringView Special;
761 const Node *Child;
762
763public:
764 SpecialName(StringView Special_, Node* Child_)
Erik Pilkington8c7013d2018-03-25 22:49:57 +0000765 : Node(KSpecialName), Special(Special_), Child(Child_) {}
Erik Pilkingtonbb7feae2018-03-19 15:18:23 +0000766
767 void printLeft(OutputStream &S) const override {
768 S += Special;
769 Child->print(S);
770 }
771};
772
773class CtorVtableSpecialName final : public Node {
774 const Node *FirstType;
775 const Node *SecondType;
776
777public:
778 CtorVtableSpecialName(Node *FirstType_, Node *SecondType_)
Erik Pilkington8c7013d2018-03-25 22:49:57 +0000779 : Node(KCtorVtableSpecialName),
Erik Pilkingtonbb7feae2018-03-19 15:18:23 +0000780 FirstType(FirstType_), SecondType(SecondType_) {}
781
782 void printLeft(OutputStream &S) const override {
783 S += "construction vtable for ";
784 FirstType->print(S);
785 S += "-in-";
786 SecondType->print(S);
787 }
788};
789
Erik Pilkingtonf2a9b0f2018-04-12 20:41:06 +0000790struct NestedName : Node {
791 Node *Qual;
792 Node *Name;
793
794 NestedName(Node *Qual_, Node *Name_)
795 : Node(KNestedName), Qual(Qual_), Name(Name_) {}
796
797 StringView getBaseName() const override { return Name->getBaseName(); }
798
799 void printLeft(OutputStream &S) const override {
800 Qual->print(S);
801 S += "::";
802 Name->print(S);
803 }
804};
805
806struct LocalName : Node {
807 Node *Encoding;
808 Node *Entity;
809
810 LocalName(Node *Encoding_, Node *Entity_)
811 : Node(KLocalName), Encoding(Encoding_), Entity(Entity_) {}
812
813 void printLeft(OutputStream &S) const override {
814 Encoding->print(S);
815 S += "::";
816 Entity->print(S);
817 }
818};
819
Erik Pilkingtonbb7feae2018-03-19 15:18:23 +0000820class QualifiedName final : public Node {
821 // qualifier::name
822 const Node *Qualifier;
823 const Node *Name;
824
825public:
826 QualifiedName(Node* Qualifier_, Node* Name_)
Erik Pilkington8c7013d2018-03-25 22:49:57 +0000827 : Node(KQualifiedName), Qualifier(Qualifier_), Name(Name_) {}
Erik Pilkingtonbb7feae2018-03-19 15:18:23 +0000828
829 StringView getBaseName() const override { return Name->getBaseName(); }
830
831 void printLeft(OutputStream &S) const override {
832 Qualifier->print(S);
833 S += "::";
834 Name->print(S);
835 }
836};
837
Erik Pilkingtonbb7feae2018-03-19 15:18:23 +0000838class VectorType final : public Node {
839 const Node *BaseType;
840 const NodeOrString Dimension;
841 const bool IsPixel;
842
843public:
844 VectorType(NodeOrString Dimension_)
845 : Node(KVectorType), BaseType(nullptr), Dimension(Dimension_),
Erik Pilkington8c7013d2018-03-25 22:49:57 +0000846 IsPixel(true) {}
Erik Pilkingtonbb7feae2018-03-19 15:18:23 +0000847 VectorType(Node *BaseType_, NodeOrString Dimension_)
Erik Pilkington8c7013d2018-03-25 22:49:57 +0000848 : Node(KVectorType), BaseType(BaseType_),
849 Dimension(Dimension_), IsPixel(false) {}
Erik Pilkingtonbb7feae2018-03-19 15:18:23 +0000850
851 void printLeft(OutputStream &S) const override {
852 if (IsPixel) {
853 S += "pixel vector[";
854 S += Dimension.asString();
855 S += "]";
856 } else {
857 BaseType->print(S);
858 S += " vector[";
859 if (Dimension.isNode())
860 Dimension.asNode()->print(S);
861 else if (Dimension.isString())
862 S += Dimension.asString();
863 S += "]";
864 }
865 }
866};
867
868/// An unexpanded parameter pack (either in the expression or type context). If
869/// this AST is correct, this node will have a ParameterPackExpansion node above
870/// it.
871///
872/// This node is created when some <template-args> are found that apply to an
873/// <encoding>, and is stored in the TemplateParams table. In order for this to
874/// appear in the final AST, it has to referenced via a <template-param> (ie,
875/// T_).
876class ParameterPack final : public Node {
877 NodeArray Data;
Erik Pilkington8c7013d2018-03-25 22:49:57 +0000878
879 // Setup OutputStream for a pack expansion unless we're already expanding one.
880 void initializePackExpansion(OutputStream &S) const {
881 if (S.CurrentPackMax == std::numeric_limits<unsigned>::max()) {
882 S.CurrentPackMax = static_cast<unsigned>(Data.size());
883 S.CurrentPackIndex = 0;
884 }
885 }
886
Erik Pilkingtonbb7feae2018-03-19 15:18:23 +0000887public:
Erik Pilkington8c7013d2018-03-25 22:49:57 +0000888 ParameterPack(NodeArray Data_) : Node(KParameterPack), Data(Data_) {
Erik Pilkingtonbb7feae2018-03-19 15:18:23 +0000889 ArrayCache = FunctionCache = RHSComponentCache = Cache::Unknown;
890 if (std::all_of(Data.begin(), Data.end(), [](Node* P) {
891 return P->ArrayCache == Cache::No;
892 }))
893 ArrayCache = Cache::No;
894 if (std::all_of(Data.begin(), Data.end(), [](Node* P) {
895 return P->FunctionCache == Cache::No;
896 }))
897 FunctionCache = Cache::No;
898 if (std::all_of(Data.begin(), Data.end(), [](Node* P) {
899 return P->RHSComponentCache == Cache::No;
900 }))
901 RHSComponentCache = Cache::No;
902 }
903
904 bool hasRHSComponentSlow(OutputStream &S) const override {
Erik Pilkington8c7013d2018-03-25 22:49:57 +0000905 initializePackExpansion(S);
Erik Pilkingtonbb7feae2018-03-19 15:18:23 +0000906 size_t Idx = S.CurrentPackIndex;
907 return Idx < Data.size() && Data[Idx]->hasRHSComponent(S);
908 }
909 bool hasArraySlow(OutputStream &S) const override {
Erik Pilkington8c7013d2018-03-25 22:49:57 +0000910 initializePackExpansion(S);
Erik Pilkingtonbb7feae2018-03-19 15:18:23 +0000911 size_t Idx = S.CurrentPackIndex;
912 return Idx < Data.size() && Data[Idx]->hasArray(S);
913 }
914 bool hasFunctionSlow(OutputStream &S) const override {
Erik Pilkington8c7013d2018-03-25 22:49:57 +0000915 initializePackExpansion(S);
Erik Pilkingtonbb7feae2018-03-19 15:18:23 +0000916 size_t Idx = S.CurrentPackIndex;
917 return Idx < Data.size() && Data[Idx]->hasFunction(S);
918 }
Erik Pilkington3a6fed42018-07-27 17:27:40 +0000919 const Node *getSyntaxNode(OutputStream &S) const override {
920 initializePackExpansion(S);
921 size_t Idx = S.CurrentPackIndex;
922 return Idx < Data.size() ? Data[Idx]->getSyntaxNode(S) : this;
923 }
Erik Pilkingtonbb7feae2018-03-19 15:18:23 +0000924
925 void printLeft(OutputStream &S) const override {
Erik Pilkington8c7013d2018-03-25 22:49:57 +0000926 initializePackExpansion(S);
Erik Pilkingtonbb7feae2018-03-19 15:18:23 +0000927 size_t Idx = S.CurrentPackIndex;
928 if (Idx < Data.size())
929 Data[Idx]->printLeft(S);
930 }
931 void printRight(OutputStream &S) const override {
Erik Pilkington8c7013d2018-03-25 22:49:57 +0000932 initializePackExpansion(S);
Erik Pilkingtonbb7feae2018-03-19 15:18:23 +0000933 size_t Idx = S.CurrentPackIndex;
934 if (Idx < Data.size())
935 Data[Idx]->printRight(S);
936 }
937};
938
Simon Pilgrimcfe2f9d2018-06-26 14:06:23 +0000939/// A variadic template argument. This node represents an occurrence of
Erik Pilkingtonbb7feae2018-03-19 15:18:23 +0000940/// J<something>E in some <template-args>. It isn't itself unexpanded, unless
941/// one of it's Elements is. The parser inserts a ParameterPack into the
942/// TemplateParams table if the <template-args> this pack belongs to apply to an
943/// <encoding>.
944class TemplateArgumentPack final : public Node {
945 NodeArray Elements;
946public:
947 TemplateArgumentPack(NodeArray Elements_)
Erik Pilkington8c7013d2018-03-25 22:49:57 +0000948 : Node(KTemplateArgumentPack), Elements(Elements_) {}
Erik Pilkingtonbb7feae2018-03-19 15:18:23 +0000949
950 NodeArray getElements() const { return Elements; }
951
952 void printLeft(OutputStream &S) const override {
953 Elements.printWithComma(S);
954 }
955};
956
957/// A pack expansion. Below this node, there are some unexpanded ParameterPacks
958/// which each have Child->ParameterPackSize elements.
959class ParameterPackExpansion final : public Node {
960 const Node *Child;
961
962public:
963 ParameterPackExpansion(Node* Child_)
964 : Node(KParameterPackExpansion), Child(Child_) {}
965
966 const Node *getChild() const { return Child; }
967
968 void printLeft(OutputStream &S) const override {
Erik Pilkington8c7013d2018-03-25 22:49:57 +0000969 constexpr unsigned Max = std::numeric_limits<unsigned>::max();
970 SwapAndRestore<unsigned> SavePackIdx(S.CurrentPackIndex, Max);
971 SwapAndRestore<unsigned> SavePackMax(S.CurrentPackMax, Max);
972 size_t StreamPos = S.getCurrentPosition();
973
974 // Print the first element in the pack. If Child contains a ParameterPack,
975 // it will set up S.CurrentPackMax and print the first element.
976 Child->print(S);
977
978 // No ParameterPack was found in Child. This can occur if we've found a pack
979 // expansion on a <function-param>.
980 if (S.CurrentPackMax == Max) {
Erik Pilkingtonbb7feae2018-03-19 15:18:23 +0000981 S += "...";
982 return;
983 }
984
Erik Pilkington8c7013d2018-03-25 22:49:57 +0000985 // We found a ParameterPack, but it has no elements. Erase whatever we may
986 // of printed.
987 if (S.CurrentPackMax == 0) {
988 S.setCurrentPosition(StreamPos);
989 return;
990 }
991
992 // Else, iterate through the rest of the elements in the pack.
993 for (unsigned I = 1, E = S.CurrentPackMax; I < E; ++I) {
994 S += ", ";
Erik Pilkingtonbb7feae2018-03-19 15:18:23 +0000995 S.CurrentPackIndex = I;
996 Child->print(S);
997 }
998 }
999};
1000
Erik Pilkingtonbb7feae2018-03-19 15:18:23 +00001001class TemplateArgs final : public Node {
1002 NodeArray Params;
1003
1004public:
Erik Pilkington8c7013d2018-03-25 22:49:57 +00001005 TemplateArgs(NodeArray Params_) : Node(KTemplateArgs), Params(Params_) {}
Erik Pilkingtonbb7feae2018-03-19 15:18:23 +00001006
1007 NodeArray getParams() { return Params; }
1008
1009 void printLeft(OutputStream &S) const override {
1010 S += "<";
Erik Pilkington8c7013d2018-03-25 22:49:57 +00001011 Params.printWithComma(S);
Erik Pilkingtonbb7feae2018-03-19 15:18:23 +00001012 if (S.back() == '>')
1013 S += " ";
1014 S += ">";
1015 }
1016};
1017
Erik Pilkington8a1cb332018-03-25 22:50:33 +00001018struct ForwardTemplateReference : Node {
1019 size_t Index;
1020 Node *Ref = nullptr;
1021
Erik Pilkington615e7532018-03-26 15:34:36 +00001022 // If we're currently printing this node. It is possible (though invalid) for
1023 // a forward template reference to refer to itself via a substitution. This
1024 // creates a cyclic AST, which will stack overflow printing. To fix this, bail
1025 // out if more than one print* function is active.
1026 mutable bool Printing = false;
1027
Erik Pilkington8a1cb332018-03-25 22:50:33 +00001028 ForwardTemplateReference(size_t Index_)
1029 : Node(KForwardTemplateReference, Cache::Unknown, Cache::Unknown,
1030 Cache::Unknown),
1031 Index(Index_) {}
1032
1033 bool hasRHSComponentSlow(OutputStream &S) const override {
Erik Pilkington615e7532018-03-26 15:34:36 +00001034 if (Printing)
1035 return false;
1036 SwapAndRestore<bool> SavePrinting(Printing, true);
Erik Pilkington8a1cb332018-03-25 22:50:33 +00001037 return Ref->hasRHSComponent(S);
1038 }
1039 bool hasArraySlow(OutputStream &S) const override {
Erik Pilkington615e7532018-03-26 15:34:36 +00001040 if (Printing)
1041 return false;
1042 SwapAndRestore<bool> SavePrinting(Printing, true);
Erik Pilkington8a1cb332018-03-25 22:50:33 +00001043 return Ref->hasArray(S);
1044 }
1045 bool hasFunctionSlow(OutputStream &S) const override {
Erik Pilkington615e7532018-03-26 15:34:36 +00001046 if (Printing)
1047 return false;
1048 SwapAndRestore<bool> SavePrinting(Printing, true);
Erik Pilkington8a1cb332018-03-25 22:50:33 +00001049 return Ref->hasFunction(S);
1050 }
Erik Pilkington3a6fed42018-07-27 17:27:40 +00001051 const Node *getSyntaxNode(OutputStream &S) const override {
1052 if (Printing)
1053 return this;
1054 SwapAndRestore<bool> SavePrinting(Printing, true);
1055 return Ref->getSyntaxNode(S);
1056 }
Erik Pilkington8a1cb332018-03-25 22:50:33 +00001057
Erik Pilkington615e7532018-03-26 15:34:36 +00001058 void printLeft(OutputStream &S) const override {
1059 if (Printing)
1060 return;
1061 SwapAndRestore<bool> SavePrinting(Printing, true);
1062 Ref->printLeft(S);
1063 }
1064 void printRight(OutputStream &S) const override {
1065 if (Printing)
1066 return;
1067 SwapAndRestore<bool> SavePrinting(Printing, true);
1068 Ref->printRight(S);
1069 }
Erik Pilkington8a1cb332018-03-25 22:50:33 +00001070};
1071
Erik Pilkingtonf2a9b0f2018-04-12 20:41:06 +00001072struct NameWithTemplateArgs : Node {
Erik Pilkingtonbb7feae2018-03-19 15:18:23 +00001073 // name<template_args>
1074 Node *Name;
1075 Node *TemplateArgs;
1076
Erik Pilkingtonbb7feae2018-03-19 15:18:23 +00001077 NameWithTemplateArgs(Node *Name_, Node *TemplateArgs_)
Erik Pilkington8c7013d2018-03-25 22:49:57 +00001078 : Node(KNameWithTemplateArgs), Name(Name_), TemplateArgs(TemplateArgs_) {}
Erik Pilkingtonbb7feae2018-03-19 15:18:23 +00001079
1080 StringView getBaseName() const override { return Name->getBaseName(); }
1081
1082 void printLeft(OutputStream &S) const override {
1083 Name->print(S);
1084 TemplateArgs->print(S);
1085 }
1086};
1087
1088class GlobalQualifiedName final : public Node {
1089 Node *Child;
1090
1091public:
1092 GlobalQualifiedName(Node* Child_)
Erik Pilkington8c7013d2018-03-25 22:49:57 +00001093 : Node(KGlobalQualifiedName), Child(Child_) {}
Erik Pilkingtonbb7feae2018-03-19 15:18:23 +00001094
1095 StringView getBaseName() const override { return Child->getBaseName(); }
1096
1097 void printLeft(OutputStream &S) const override {
1098 S += "::";
1099 Child->print(S);
1100 }
1101};
1102
Erik Pilkingtonf2a9b0f2018-04-12 20:41:06 +00001103struct StdQualifiedName : Node {
Erik Pilkingtonbb7feae2018-03-19 15:18:23 +00001104 Node *Child;
1105
Erik Pilkington8c7013d2018-03-25 22:49:57 +00001106 StdQualifiedName(Node *Child_) : Node(KStdQualifiedName), Child(Child_) {}
Erik Pilkingtonbb7feae2018-03-19 15:18:23 +00001107
1108 StringView getBaseName() const override { return Child->getBaseName(); }
1109
1110 void printLeft(OutputStream &S) const override {
1111 S += "std::";
1112 Child->print(S);
1113 }
1114};
1115
1116enum class SpecialSubKind {
1117 allocator,
1118 basic_string,
1119 string,
1120 istream,
1121 ostream,
1122 iostream,
1123};
1124
1125class ExpandedSpecialSubstitution final : public Node {
1126 SpecialSubKind SSK;
1127
1128public:
1129 ExpandedSpecialSubstitution(SpecialSubKind SSK_)
1130 : Node(KExpandedSpecialSubstitution), SSK(SSK_) {}
1131
1132 StringView getBaseName() const override {
1133 switch (SSK) {
1134 case SpecialSubKind::allocator:
1135 return StringView("allocator");
1136 case SpecialSubKind::basic_string:
1137 return StringView("basic_string");
1138 case SpecialSubKind::string:
1139 return StringView("basic_string");
1140 case SpecialSubKind::istream:
1141 return StringView("basic_istream");
1142 case SpecialSubKind::ostream:
1143 return StringView("basic_ostream");
1144 case SpecialSubKind::iostream:
1145 return StringView("basic_iostream");
1146 }
1147 LLVM_BUILTIN_UNREACHABLE;
1148 }
1149
1150 void printLeft(OutputStream &S) const override {
1151 switch (SSK) {
1152 case SpecialSubKind::allocator:
1153 S += "std::basic_string<char, std::char_traits<char>, "
1154 "std::allocator<char> >";
1155 break;
1156 case SpecialSubKind::basic_string:
1157 case SpecialSubKind::string:
1158 S += "std::basic_string<char, std::char_traits<char>, "
1159 "std::allocator<char> >";
1160 break;
1161 case SpecialSubKind::istream:
1162 S += "std::basic_istream<char, std::char_traits<char> >";
1163 break;
1164 case SpecialSubKind::ostream:
1165 S += "std::basic_ostream<char, std::char_traits<char> >";
1166 break;
1167 case SpecialSubKind::iostream:
1168 S += "std::basic_iostream<char, std::char_traits<char> >";
1169 break;
1170 }
1171 }
1172};
1173
1174class SpecialSubstitution final : public Node {
1175public:
1176 SpecialSubKind SSK;
1177
1178 SpecialSubstitution(SpecialSubKind SSK_)
1179 : Node(KSpecialSubstitution), SSK(SSK_) {}
1180
1181 StringView getBaseName() const override {
1182 switch (SSK) {
1183 case SpecialSubKind::allocator:
1184 return StringView("allocator");
1185 case SpecialSubKind::basic_string:
1186 return StringView("basic_string");
1187 case SpecialSubKind::string:
1188 return StringView("string");
1189 case SpecialSubKind::istream:
1190 return StringView("istream");
1191 case SpecialSubKind::ostream:
1192 return StringView("ostream");
1193 case SpecialSubKind::iostream:
1194 return StringView("iostream");
1195 }
1196 LLVM_BUILTIN_UNREACHABLE;
1197 }
1198
1199 void printLeft(OutputStream &S) const override {
1200 switch (SSK) {
1201 case SpecialSubKind::allocator:
1202 S += "std::allocator";
1203 break;
1204 case SpecialSubKind::basic_string:
1205 S += "std::basic_string";
1206 break;
1207 case SpecialSubKind::string:
1208 S += "std::string";
1209 break;
1210 case SpecialSubKind::istream:
1211 S += "std::istream";
1212 break;
1213 case SpecialSubKind::ostream:
1214 S += "std::ostream";
1215 break;
1216 case SpecialSubKind::iostream:
1217 S += "std::iostream";
1218 break;
1219 }
1220 }
1221};
1222
1223class CtorDtorName final : public Node {
1224 const Node *Basename;
1225 const bool IsDtor;
1226
1227public:
1228 CtorDtorName(Node *Basename_, bool IsDtor_)
Erik Pilkington8c7013d2018-03-25 22:49:57 +00001229 : Node(KCtorDtorName), Basename(Basename_), IsDtor(IsDtor_) {}
Erik Pilkingtonbb7feae2018-03-19 15:18:23 +00001230
1231 void printLeft(OutputStream &S) const override {
1232 if (IsDtor)
1233 S += "~";
1234 S += Basename->getBaseName();
1235 }
1236};
1237
1238class DtorName : public Node {
1239 const Node *Base;
1240
1241public:
Erik Pilkington8c7013d2018-03-25 22:49:57 +00001242 DtorName(Node *Base_) : Node(KDtorName), Base(Base_) {}
Erik Pilkingtonbb7feae2018-03-19 15:18:23 +00001243
1244 void printLeft(OutputStream &S) const override {
1245 S += "~";
1246 Base->printLeft(S);
1247 }
1248};
1249
1250class UnnamedTypeName : public Node {
1251 const StringView Count;
1252
1253public:
1254 UnnamedTypeName(StringView Count_) : Node(KUnnamedTypeName), Count(Count_) {}
1255
1256 void printLeft(OutputStream &S) const override {
1257 S += "'unnamed";
1258 S += Count;
1259 S += "\'";
1260 }
1261};
1262
1263class ClosureTypeName : public Node {
1264 NodeArray Params;
1265 StringView Count;
1266
1267public:
1268 ClosureTypeName(NodeArray Params_, StringView Count_)
Erik Pilkington8c7013d2018-03-25 22:49:57 +00001269 : Node(KClosureTypeName), Params(Params_), Count(Count_) {}
Erik Pilkingtonbb7feae2018-03-19 15:18:23 +00001270
1271 void printLeft(OutputStream &S) const override {
1272 S += "\'lambda";
1273 S += Count;
1274 S += "\'(";
1275 Params.printWithComma(S);
1276 S += ")";
1277 }
1278};
1279
1280class StructuredBindingName : public Node {
1281 NodeArray Bindings;
1282public:
1283 StructuredBindingName(NodeArray Bindings_)
1284 : Node(KStructuredBindingName), Bindings(Bindings_) {}
1285
1286 void printLeft(OutputStream &S) const override {
1287 S += '[';
1288 Bindings.printWithComma(S);
1289 S += ']';
1290 }
1291};
1292
1293// -- Expression Nodes --
1294
1295struct Expr : public Node {
1296 Expr(Kind K = KExpr) : Node(K) {}
1297};
1298
1299class BinaryExpr : public Expr {
1300 const Node *LHS;
1301 const StringView InfixOperator;
1302 const Node *RHS;
1303
1304public:
1305 BinaryExpr(Node *LHS_, StringView InfixOperator_, Node *RHS_)
Erik Pilkington8c7013d2018-03-25 22:49:57 +00001306 : LHS(LHS_), InfixOperator(InfixOperator_), RHS(RHS_) {}
Erik Pilkingtonbb7feae2018-03-19 15:18:23 +00001307
1308 void printLeft(OutputStream &S) const override {
1309 // might be a template argument expression, then we need to disambiguate
1310 // with parens.
1311 if (InfixOperator == ">")
1312 S += "(";
1313
1314 S += "(";
1315 LHS->print(S);
1316 S += ") ";
1317 S += InfixOperator;
1318 S += " (";
1319 RHS->print(S);
1320 S += ")";
1321
1322 if (InfixOperator == ">")
1323 S += ")";
1324 }
1325};
1326
1327class ArraySubscriptExpr : public Expr {
1328 const Node *Op1;
1329 const Node *Op2;
1330
1331public:
Erik Pilkington8c7013d2018-03-25 22:49:57 +00001332 ArraySubscriptExpr(Node *Op1_, Node *Op2_) : Op1(Op1_), Op2(Op2_) {}
Erik Pilkingtonbb7feae2018-03-19 15:18:23 +00001333
1334 void printLeft(OutputStream &S) const override {
1335 S += "(";
1336 Op1->print(S);
1337 S += ")[";
1338 Op2->print(S);
1339 S += "]";
1340 }
1341};
1342
1343class PostfixExpr : public Expr {
1344 const Node *Child;
1345 const StringView Operand;
1346
1347public:
1348 PostfixExpr(Node *Child_, StringView Operand_)
Erik Pilkington8c7013d2018-03-25 22:49:57 +00001349 : Child(Child_), Operand(Operand_) {}
Erik Pilkingtonbb7feae2018-03-19 15:18:23 +00001350
1351 void printLeft(OutputStream &S) const override {
1352 S += "(";
1353 Child->print(S);
1354 S += ")";
1355 S += Operand;
1356 }
1357};
1358
1359class ConditionalExpr : public Expr {
1360 const Node *Cond;
1361 const Node *Then;
1362 const Node *Else;
1363
1364public:
1365 ConditionalExpr(Node *Cond_, Node *Then_, Node *Else_)
Erik Pilkington8c7013d2018-03-25 22:49:57 +00001366 : Cond(Cond_), Then(Then_), Else(Else_) {}
Erik Pilkingtonbb7feae2018-03-19 15:18:23 +00001367
1368 void printLeft(OutputStream &S) const override {
1369 S += "(";
1370 Cond->print(S);
1371 S += ") ? (";
1372 Then->print(S);
1373 S += ") : (";
1374 Else->print(S);
1375 S += ")";
1376 }
1377};
1378
1379class MemberExpr : public Expr {
1380 const Node *LHS;
1381 const StringView Kind;
1382 const Node *RHS;
1383
1384public:
1385 MemberExpr(Node *LHS_, StringView Kind_, Node *RHS_)
Erik Pilkington8c7013d2018-03-25 22:49:57 +00001386 : LHS(LHS_), Kind(Kind_), RHS(RHS_) {}
Erik Pilkingtonbb7feae2018-03-19 15:18:23 +00001387
1388 void printLeft(OutputStream &S) const override {
1389 LHS->print(S);
1390 S += Kind;
1391 RHS->print(S);
1392 }
1393};
1394
1395class EnclosingExpr : public Expr {
1396 const StringView Prefix;
1397 const Node *Infix;
1398 const StringView Postfix;
1399
1400public:
1401 EnclosingExpr(StringView Prefix_, Node *Infix_, StringView Postfix_)
Erik Pilkington8c7013d2018-03-25 22:49:57 +00001402 : Prefix(Prefix_), Infix(Infix_), Postfix(Postfix_) {}
Erik Pilkingtonbb7feae2018-03-19 15:18:23 +00001403
1404 void printLeft(OutputStream &S) const override {
1405 S += Prefix;
1406 Infix->print(S);
1407 S += Postfix;
1408 }
1409};
1410
1411class CastExpr : public Expr {
1412 // cast_kind<to>(from)
1413 const StringView CastKind;
1414 const Node *To;
1415 const Node *From;
1416
1417public:
1418 CastExpr(StringView CastKind_, Node *To_, Node *From_)
Erik Pilkington8c7013d2018-03-25 22:49:57 +00001419 : CastKind(CastKind_), To(To_), From(From_) {}
Erik Pilkingtonbb7feae2018-03-19 15:18:23 +00001420
1421 void printLeft(OutputStream &S) const override {
1422 S += CastKind;
1423 S += "<";
1424 To->printLeft(S);
1425 S += ">(";
1426 From->printLeft(S);
1427 S += ")";
1428 }
1429};
1430
1431class SizeofParamPackExpr : public Expr {
1432 Node *Pack;
1433
1434public:
1435 SizeofParamPackExpr(Node *Pack_) : Pack(Pack_) {}
1436
1437 void printLeft(OutputStream &S) const override {
1438 S += "sizeof...(";
1439 ParameterPackExpansion PPE(Pack);
1440 PPE.printLeft(S);
1441 S += ")";
1442 }
1443};
1444
1445class CallExpr : public Expr {
1446 const Node *Callee;
1447 NodeArray Args;
1448
1449public:
Erik Pilkington8c7013d2018-03-25 22:49:57 +00001450 CallExpr(Node *Callee_, NodeArray Args_) : Callee(Callee_), Args(Args_) {}
Erik Pilkingtonbb7feae2018-03-19 15:18:23 +00001451
1452 void printLeft(OutputStream &S) const override {
1453 Callee->print(S);
1454 S += "(";
1455 Args.printWithComma(S);
1456 S += ")";
1457 }
1458};
1459
1460class NewExpr : public Expr {
1461 // new (expr_list) type(init_list)
1462 NodeArray ExprList;
1463 Node *Type;
1464 NodeArray InitList;
1465 bool IsGlobal; // ::operator new ?
1466 bool IsArray; // new[] ?
1467public:
1468 NewExpr(NodeArray ExprList_, Node *Type_, NodeArray InitList_, bool IsGlobal_,
1469 bool IsArray_)
1470 : ExprList(ExprList_), Type(Type_), InitList(InitList_),
Erik Pilkington8c7013d2018-03-25 22:49:57 +00001471 IsGlobal(IsGlobal_), IsArray(IsArray_) {}
Erik Pilkingtonbb7feae2018-03-19 15:18:23 +00001472
1473 void printLeft(OutputStream &S) const override {
1474 if (IsGlobal)
1475 S += "::operator ";
1476 S += "new";
1477 if (IsArray)
1478 S += "[]";
1479 S += ' ';
1480 if (!ExprList.empty()) {
1481 S += "(";
1482 ExprList.printWithComma(S);
1483 S += ")";
1484 }
1485 Type->print(S);
1486 if (!InitList.empty()) {
1487 S += "(";
1488 InitList.printWithComma(S);
1489 S += ")";
1490 }
1491
1492 }
1493};
1494
1495class DeleteExpr : public Expr {
1496 Node *Op;
1497 bool IsGlobal;
1498 bool IsArray;
1499
1500public:
1501 DeleteExpr(Node *Op_, bool IsGlobal_, bool IsArray_)
Erik Pilkington8c7013d2018-03-25 22:49:57 +00001502 : Op(Op_), IsGlobal(IsGlobal_), IsArray(IsArray_) {}
Erik Pilkingtonbb7feae2018-03-19 15:18:23 +00001503
1504 void printLeft(OutputStream &S) const override {
1505 if (IsGlobal)
1506 S += "::";
1507 S += "delete";
1508 if (IsArray)
1509 S += "[] ";
1510 Op->print(S);
1511 }
1512};
1513
1514class PrefixExpr : public Expr {
1515 StringView Prefix;
1516 Node *Child;
1517
1518public:
Erik Pilkington8c7013d2018-03-25 22:49:57 +00001519 PrefixExpr(StringView Prefix_, Node *Child_) : Prefix(Prefix_), Child(Child_) {}
Erik Pilkingtonbb7feae2018-03-19 15:18:23 +00001520
1521 void printLeft(OutputStream &S) const override {
1522 S += Prefix;
1523 S += "(";
1524 Child->print(S);
1525 S += ")";
1526 }
1527};
1528
1529class FunctionParam : public Expr {
1530 StringView Number;
1531
1532public:
1533 FunctionParam(StringView Number_) : Number(Number_) {}
1534
1535 void printLeft(OutputStream &S) const override {
1536 S += "fp";
1537 S += Number;
1538 }
1539};
1540
1541class ConversionExpr : public Expr {
1542 const Node *Type;
1543 NodeArray Expressions;
1544
1545public:
1546 ConversionExpr(const Node *Type_, NodeArray Expressions_)
Erik Pilkington8c7013d2018-03-25 22:49:57 +00001547 : Type(Type_), Expressions(Expressions_) {}
Erik Pilkingtonbb7feae2018-03-19 15:18:23 +00001548
1549 void printLeft(OutputStream &S) const override {
1550 S += "(";
1551 Type->print(S);
1552 S += ")(";
1553 Expressions.printWithComma(S);
1554 S += ")";
1555 }
1556};
1557
1558class InitListExpr : public Expr {
1559 Node *Ty;
1560 NodeArray Inits;
1561public:
Erik Pilkington8c7013d2018-03-25 22:49:57 +00001562 InitListExpr(Node *Ty_, NodeArray Inits_) : Ty(Ty_), Inits(Inits_) {}
Erik Pilkingtonbb7feae2018-03-19 15:18:23 +00001563
1564 void printLeft(OutputStream &S) const override {
1565 if (Ty)
1566 Ty->print(S);
1567 S += '{';
1568 Inits.printWithComma(S);
1569 S += '}';
1570 }
1571};
1572
1573class BracedExpr : public Expr {
1574 Node *Elem;
1575 Node *Init;
1576 bool IsArray;
1577public:
1578 BracedExpr(Node *Elem_, Node *Init_, bool IsArray_)
1579 : Expr(KBracedExpr), Elem(Elem_), Init(Init_), IsArray(IsArray_) {}
1580
1581 void printLeft(OutputStream &S) const override {
1582 if (IsArray) {
1583 S += '[';
1584 Elem->print(S);
1585 S += ']';
1586 } else {
1587 S += '.';
1588 Elem->print(S);
1589 }
1590 if (Init->getKind() != KBracedExpr && Init->getKind() != KBracedRangeExpr)
1591 S += " = ";
1592 Init->print(S);
1593 }
1594};
1595
1596class BracedRangeExpr : public Expr {
1597 Node *First;
1598 Node *Last;
1599 Node *Init;
1600public:
1601 BracedRangeExpr(Node *First_, Node *Last_, Node *Init_)
1602 : Expr(KBracedRangeExpr), First(First_), Last(Last_), Init(Init_) {}
1603
1604 void printLeft(OutputStream &S) const override {
1605 S += '[';
1606 First->print(S);
1607 S += " ... ";
1608 Last->print(S);
1609 S += ']';
1610 if (Init->getKind() != KBracedExpr && Init->getKind() != KBracedRangeExpr)
1611 S += " = ";
1612 Init->print(S);
1613 }
1614};
1615
Erik Pilkingtond43931d2018-04-09 18:33:01 +00001616struct FoldExpr : Expr {
1617 Node *Pack, *Init;
1618 StringView OperatorName;
1619 bool IsLeftFold;
1620
1621 FoldExpr(bool IsLeftFold_, StringView OperatorName_, Node *Pack_, Node *Init_)
1622 : Pack(Pack_), Init(Init_), OperatorName(OperatorName_),
1623 IsLeftFold(IsLeftFold_) {}
1624
1625 void printLeft(OutputStream &S) const override {
1626 auto PrintPack = [&] {
1627 S += '(';
1628 ParameterPackExpansion(Pack).print(S);
1629 S += ')';
1630 };
1631
1632 S += '(';
1633
1634 if (IsLeftFold) {
1635 // init op ... op pack
1636 if (Init != nullptr) {
1637 Init->print(S);
1638 S += ' ';
1639 S += OperatorName;
1640 S += ' ';
1641 }
1642 // ... op pack
1643 S += "... ";
1644 S += OperatorName;
1645 S += ' ';
1646 PrintPack();
1647 } else { // !IsLeftFold
1648 // pack op ...
1649 PrintPack();
1650 S += ' ';
1651 S += OperatorName;
1652 S += " ...";
1653 // pack op ... op init
1654 if (Init != nullptr) {
1655 S += ' ';
1656 S += OperatorName;
1657 S += ' ';
1658 Init->print(S);
1659 }
1660 }
1661 S += ')';
1662 }
1663};
1664
Erik Pilkingtonbb7feae2018-03-19 15:18:23 +00001665class ThrowExpr : public Expr {
1666 const Node *Op;
1667
1668public:
Erik Pilkington8c7013d2018-03-25 22:49:57 +00001669 ThrowExpr(Node *Op_) : Op(Op_) {}
Erik Pilkingtonbb7feae2018-03-19 15:18:23 +00001670
1671 void printLeft(OutputStream &S) const override {
1672 S += "throw ";
1673 Op->print(S);
1674 }
1675};
1676
1677class BoolExpr : public Expr {
1678 bool Value;
1679
1680public:
1681 BoolExpr(bool Value_) : Value(Value_) {}
1682
1683 void printLeft(OutputStream &S) const override {
1684 S += Value ? StringView("true") : StringView("false");
1685 }
1686};
1687
1688class IntegerCastExpr : public Expr {
1689 // ty(integer)
1690 Node *Ty;
1691 StringView Integer;
1692
1693public:
Erik Pilkington8c7013d2018-03-25 22:49:57 +00001694 IntegerCastExpr(Node *Ty_, StringView Integer_)
1695 : Ty(Ty_), Integer(Integer_) {}
Erik Pilkingtonbb7feae2018-03-19 15:18:23 +00001696
1697 void printLeft(OutputStream &S) const override {
1698 S += "(";
1699 Ty->print(S);
1700 S += ")";
1701 S += Integer;
1702 }
1703};
1704
1705class IntegerExpr : public Expr {
1706 StringView Type;
1707 StringView Value;
1708
1709public:
1710 IntegerExpr(StringView Type_, StringView Value_) : Type(Type_), Value(Value_) {}
1711
1712 void printLeft(OutputStream &S) const override {
1713 if (Type.size() > 3) {
1714 S += "(";
1715 S += Type;
1716 S += ")";
1717 }
1718
1719 if (Value[0] == 'n') {
1720 S += "-";
1721 S += Value.dropFront(1);
1722 } else
1723 S += Value;
1724
1725 if (Type.size() <= 3)
1726 S += Type;
1727 }
1728};
1729
1730template <class Float> struct FloatData;
1731
1732template <class Float> class FloatExpr : public Expr {
1733 const StringView Contents;
1734
1735public:
1736 FloatExpr(StringView Contents_) : Contents(Contents_) {}
1737
1738 void printLeft(OutputStream &s) const override {
1739 const char *first = Contents.begin();
1740 const char *last = Contents.end() + 1;
1741
1742 const size_t N = FloatData<Float>::mangled_size;
1743 if (static_cast<std::size_t>(last - first) > N) {
1744 last = first + N;
1745 union {
1746 Float value;
1747 char buf[sizeof(Float)];
1748 };
1749 const char *t = first;
1750 char *e = buf;
1751 for (; t != last; ++t, ++e) {
1752 unsigned d1 = isdigit(*t) ? static_cast<unsigned>(*t - '0')
1753 : static_cast<unsigned>(*t - 'a' + 10);
1754 ++t;
1755 unsigned d0 = isdigit(*t) ? static_cast<unsigned>(*t - '0')
1756 : static_cast<unsigned>(*t - 'a' + 10);
1757 *e = static_cast<char>((d1 << 4) + d0);
1758 }
Rafael Espindolab940b662016-09-06 19:16:48 +00001759#if __BYTE_ORDER__ == __ORDER_LITTLE_ENDIAN__
1760 std::reverse(buf, e);
1761#endif
Erik Pilkingtonbb7feae2018-03-19 15:18:23 +00001762 char num[FloatData<Float>::max_demangled_size] = {0};
1763 int n = snprintf(num, sizeof(num), FloatData<Float>::spec, value);
1764 s += StringView(num, num + n);
Rafael Espindolab940b662016-09-06 19:16:48 +00001765 }
1766 }
Erik Pilkingtonbb7feae2018-03-19 15:18:23 +00001767};
1768
1769class BumpPointerAllocator {
1770 struct BlockMeta {
1771 BlockMeta* Next;
1772 size_t Current;
1773 };
1774
1775 static constexpr size_t AllocSize = 4096;
1776 static constexpr size_t UsableAllocSize = AllocSize - sizeof(BlockMeta);
1777
Serge Pavlov892bd812018-07-05 06:22:39 +00001778 alignas(long double) char InitialBuffer[AllocSize];
Erik Pilkingtonbb7feae2018-03-19 15:18:23 +00001779 BlockMeta* BlockList = nullptr;
1780
1781 void grow() {
Erik Pilkington28e08a02018-07-23 22:23:04 +00001782 char* NewMeta = static_cast<char *>(std::malloc(AllocSize));
1783 if (NewMeta == nullptr)
1784 std::terminate();
Erik Pilkingtonbb7feae2018-03-19 15:18:23 +00001785 BlockList = new (NewMeta) BlockMeta{BlockList, 0};
1786 }
1787
1788 void* allocateMassive(size_t NBytes) {
1789 NBytes += sizeof(BlockMeta);
Erik Pilkington28e08a02018-07-23 22:23:04 +00001790 BlockMeta* NewMeta = reinterpret_cast<BlockMeta*>(std::malloc(NBytes));
1791 if (NewMeta == nullptr)
1792 std::terminate();
Erik Pilkingtonbb7feae2018-03-19 15:18:23 +00001793 BlockList->Next = new (NewMeta) BlockMeta{BlockList->Next, 0};
1794 return static_cast<void*>(NewMeta + 1);
1795 }
1796
1797public:
1798 BumpPointerAllocator()
1799 : BlockList(new (InitialBuffer) BlockMeta{nullptr, 0}) {}
1800
1801 void* allocate(size_t N) {
1802 N = (N + 15u) & ~15u;
1803 if (N + BlockList->Current >= UsableAllocSize) {
1804 if (N > UsableAllocSize)
1805 return allocateMassive(N);
1806 grow();
1807 }
1808 BlockList->Current += N;
1809 return static_cast<void*>(reinterpret_cast<char*>(BlockList + 1) +
1810 BlockList->Current - N);
1811 }
1812
Erik Pilkingtonf2a9b0f2018-04-12 20:41:06 +00001813 void reset() {
Erik Pilkingtonbb7feae2018-03-19 15:18:23 +00001814 while (BlockList) {
1815 BlockMeta* Tmp = BlockList;
1816 BlockList = BlockList->Next;
1817 if (reinterpret_cast<char*>(Tmp) != InitialBuffer)
Erik Pilkington28e08a02018-07-23 22:23:04 +00001818 std::free(Tmp);
Erik Pilkingtonbb7feae2018-03-19 15:18:23 +00001819 }
Erik Pilkingtonf2a9b0f2018-04-12 20:41:06 +00001820 BlockList = new (InitialBuffer) BlockMeta{nullptr, 0};
Erik Pilkingtonbb7feae2018-03-19 15:18:23 +00001821 }
Erik Pilkingtonf2a9b0f2018-04-12 20:41:06 +00001822
1823 ~BumpPointerAllocator() { reset(); }
Erik Pilkingtonbb7feae2018-03-19 15:18:23 +00001824};
1825
1826template <class T, size_t N>
1827class PODSmallVector {
1828 static_assert(std::is_pod<T>::value,
1829 "T is required to be a plain old data type");
1830
1831 T* First;
1832 T* Last;
1833 T* Cap;
1834 T Inline[N];
1835
1836 bool isInline() const { return First == Inline; }
1837
1838 void clearInline() {
1839 First = Inline;
1840 Last = Inline;
1841 Cap = Inline + N;
1842 }
1843
1844 void reserve(size_t NewCap) {
1845 size_t S = size();
1846 if (isInline()) {
Serge Pavlov1a095522018-05-29 07:05:41 +00001847 auto* Tmp = static_cast<T*>(std::malloc(NewCap * sizeof(T)));
Erik Pilkington28e08a02018-07-23 22:23:04 +00001848 if (Tmp == nullptr)
1849 std::terminate();
Erik Pilkingtonbb7feae2018-03-19 15:18:23 +00001850 std::copy(First, Last, Tmp);
1851 First = Tmp;
Erik Pilkington28e08a02018-07-23 22:23:04 +00001852 } else {
Serge Pavlov1a095522018-05-29 07:05:41 +00001853 First = static_cast<T*>(std::realloc(First, NewCap * sizeof(T)));
Erik Pilkington28e08a02018-07-23 22:23:04 +00001854 if (First == nullptr)
1855 std::terminate();
1856 }
Erik Pilkingtonbb7feae2018-03-19 15:18:23 +00001857 Last = First + S;
1858 Cap = First + NewCap;
1859 }
1860
1861public:
1862 PODSmallVector() : First(Inline), Last(First), Cap(Inline + N) {}
1863
1864 PODSmallVector(const PODSmallVector&) = delete;
1865 PODSmallVector& operator=(const PODSmallVector&) = delete;
1866
1867 PODSmallVector(PODSmallVector&& Other) : PODSmallVector() {
1868 if (Other.isInline()) {
1869 std::copy(Other.begin(), Other.end(), First);
1870 Last = First + Other.size();
1871 Other.clear();
1872 return;
1873 }
1874
1875 First = Other.First;
1876 Last = Other.Last;
1877 Cap = Other.Cap;
1878 Other.clearInline();
1879 }
1880
1881 PODSmallVector& operator=(PODSmallVector&& Other) {
1882 if (Other.isInline()) {
1883 if (!isInline()) {
1884 std::free(First);
1885 clearInline();
1886 }
1887 std::copy(Other.begin(), Other.end(), First);
1888 Last = First + Other.size();
1889 Other.clear();
1890 return *this;
1891 }
1892
1893 if (isInline()) {
1894 First = Other.First;
1895 Last = Other.Last;
1896 Cap = Other.Cap;
1897 Other.clearInline();
1898 return *this;
1899 }
1900
1901 std::swap(First, Other.First);
1902 std::swap(Last, Other.Last);
1903 std::swap(Cap, Other.Cap);
1904 Other.clear();
1905 return *this;
1906 }
1907
1908 void push_back(const T& Elem) {
1909 if (Last == Cap)
1910 reserve(size() * 2);
1911 *Last++ = Elem;
1912 }
1913
1914 void pop_back() {
1915 assert(Last != First && "Popping empty vector!");
1916 --Last;
1917 }
1918
1919 void dropBack(size_t Index) {
1920 assert(Index <= size() && "dropBack() can't expand!");
1921 Last = First + Index;
1922 }
1923
1924 T* begin() { return First; }
1925 T* end() { return Last; }
1926
1927 bool empty() const { return First == Last; }
1928 size_t size() const { return static_cast<size_t>(Last - First); }
1929 T& back() {
1930 assert(Last != First && "Calling back() on empty vector!");
1931 return *(Last - 1);
1932 }
1933 T& operator[](size_t Index) {
1934 assert(Index < size() && "Invalid access!");
1935 return *(begin() + Index);
1936 }
1937 void clear() { Last = First; }
1938
1939 ~PODSmallVector() {
1940 if (!isInline())
1941 std::free(First);
1942 }
1943};
1944
1945struct Db {
1946 const char *First;
1947 const char *Last;
1948
1949 // Name stack, this is used by the parser to hold temporary names that were
Simon Pilgrimcfe2f9d2018-06-26 14:06:23 +00001950 // parsed. The parser collapses multiple names into new nodes to construct
Erik Pilkingtonbb7feae2018-03-19 15:18:23 +00001951 // the AST. Once the parser is finished, names.size() == 1.
1952 PODSmallVector<Node *, 32> Names;
1953
1954 // Substitution table. Itanium supports name substitutions as a means of
1955 // compression. The string "S42_" refers to the 44nd entry (base-36) in this
1956 // table.
1957 PODSmallVector<Node *, 32> Subs;
1958
1959 // Template parameter table. Like the above, but referenced like "T42_".
1960 // This has a smaller size compared to Subs and Names because it can be
1961 // stored on the stack.
1962 PODSmallVector<Node *, 8> TemplateParams;
1963
Erik Pilkington8a1cb332018-03-25 22:50:33 +00001964 // Set of unresolved forward <template-param> references. These can occur in a
1965 // conversion operator's type, and are resolved in the enclosing <encoding>.
1966 PODSmallVector<ForwardTemplateReference *, 4> ForwardTemplateRefs;
1967
Erik Pilkingtonac6a801c2018-08-13 16:37:47 +00001968 void (*TypeCallback)(void *, const char *) = nullptr;
1969 void *TypeCallbackContext = nullptr;
1970
Erik Pilkingtonbb7feae2018-03-19 15:18:23 +00001971 bool TryToParseTemplateArgs = true;
Erik Pilkington8a1cb332018-03-25 22:50:33 +00001972 bool PermitForwardTemplateReferences = false;
Erik Pilkingtonbb7feae2018-03-19 15:18:23 +00001973 bool ParsingLambdaParams = false;
1974
1975 BumpPointerAllocator ASTAllocator;
1976
1977 Db(const char *First_, const char *Last_) : First(First_), Last(Last_) {}
1978
Erik Pilkingtonf2a9b0f2018-04-12 20:41:06 +00001979 void reset(const char *First_, const char *Last_) {
1980 First = First_;
1981 Last = Last_;
1982 Names.clear();
1983 Subs.clear();
1984 TemplateParams.clear();
1985 ParsingLambdaParams = false;
1986 TryToParseTemplateArgs = true;
1987 PermitForwardTemplateReferences = false;
1988 ASTAllocator.reset();
1989 }
1990
Erik Pilkingtonbb7feae2018-03-19 15:18:23 +00001991 template <class T, class... Args> T *make(Args &&... args) {
1992 return new (ASTAllocator.allocate(sizeof(T)))
1993 T(std::forward<Args>(args)...);
1994 }
1995
1996 template <class It> NodeArray makeNodeArray(It begin, It end) {
1997 size_t sz = static_cast<size_t>(end - begin);
1998 void *mem = ASTAllocator.allocate(sizeof(Node *) * sz);
1999 Node **data = new (mem) Node *[sz];
2000 std::copy(begin, end, data);
2001 return NodeArray(data, sz);
2002 }
2003
2004 NodeArray popTrailingNodeArray(size_t FromPosition) {
2005 assert(FromPosition <= Names.size());
2006 NodeArray res =
2007 makeNodeArray(Names.begin() + (long)FromPosition, Names.end());
2008 Names.dropBack(FromPosition);
2009 return res;
2010 }
2011
2012 bool consumeIf(StringView S) {
2013 if (StringView(First, Last).startsWith(S)) {
2014 First += S.size();
2015 return true;
2016 }
2017 return false;
2018 }
2019
2020 bool consumeIf(char C) {
2021 if (First != Last && *First == C) {
2022 ++First;
2023 return true;
2024 }
2025 return false;
2026 }
2027
2028 char consume() { return First != Last ? *First++ : '\0'; }
2029
2030 char look(unsigned Lookahead = 0) {
2031 if (static_cast<size_t>(Last - First) <= Lookahead)
2032 return '\0';
2033 return First[Lookahead];
2034 }
2035
2036 size_t numLeft() const { return static_cast<size_t>(Last - First); }
2037
2038 StringView parseNumber(bool AllowNegative = false);
2039 Qualifiers parseCVQualifiers();
2040 bool parsePositiveInteger(size_t *Out);
2041 StringView parseBareSourceName();
2042
2043 bool parseSeqId(size_t *Out);
2044 Node *parseSubstitution();
2045 Node *parseTemplateParam();
Erik Pilkington8a1cb332018-03-25 22:50:33 +00002046 Node *parseTemplateArgs(bool TagTemplates = false);
Erik Pilkingtonbb7feae2018-03-19 15:18:23 +00002047 Node *parseTemplateArg();
2048
2049 /// Parse the <expr> production.
2050 Node *parseExpr();
2051 Node *parsePrefixExpr(StringView Kind);
2052 Node *parseBinaryExpr(StringView Kind);
2053 Node *parseIntegerLiteral(StringView Lit);
2054 Node *parseExprPrimary();
2055 template <class Float> Node *parseFloatingLiteral();
2056 Node *parseFunctionParam();
2057 Node *parseNewExpr();
2058 Node *parseConversionExpr();
2059 Node *parseBracedExpr();
Erik Pilkingtond43931d2018-04-09 18:33:01 +00002060 Node *parseFoldExpr();
Erik Pilkingtonbb7feae2018-03-19 15:18:23 +00002061
2062 /// Parse the <type> production.
2063 Node *parseType();
2064 Node *parseFunctionType();
2065 Node *parseVectorType();
2066 Node *parseDecltype();
2067 Node *parseArrayType();
2068 Node *parsePointerToMemberType();
2069 Node *parseClassEnumType();
2070 Node *parseQualifiedType();
2071
2072 Node *parseEncoding();
2073 bool parseCallOffset();
2074 Node *parseSpecialName();
2075
2076 /// Holds some extra information about a <name> that is being parsed. This
2077 /// information is only pertinent if the <name> refers to an <encoding>.
2078 struct NameState {
2079 bool CtorDtorConversion = false;
2080 bool EndsWithTemplateArgs = false;
2081 Qualifiers CVQualifiers = QualNone;
2082 FunctionRefQual ReferenceQualifier = FrefQualNone;
Erik Pilkington8a1cb332018-03-25 22:50:33 +00002083 size_t ForwardTemplateRefsBegin;
2084
2085 NameState(Db *Enclosing)
2086 : ForwardTemplateRefsBegin(Enclosing->ForwardTemplateRefs.size()) {}
Erik Pilkingtonbb7feae2018-03-19 15:18:23 +00002087 };
2088
Erik Pilkington8a1cb332018-03-25 22:50:33 +00002089 bool resolveForwardTemplateRefs(NameState &State) {
2090 size_t I = State.ForwardTemplateRefsBegin;
2091 size_t E = ForwardTemplateRefs.size();
2092 for (; I < E; ++I) {
2093 size_t Idx = ForwardTemplateRefs[I]->Index;
2094 if (Idx >= TemplateParams.size())
2095 return true;
2096 ForwardTemplateRefs[I]->Ref = TemplateParams[Idx];
2097 }
2098 ForwardTemplateRefs.dropBack(State.ForwardTemplateRefsBegin);
2099 return false;
2100 }
2101
Erik Pilkingtonbb7feae2018-03-19 15:18:23 +00002102 /// Parse the <name> production>
2103 Node *parseName(NameState *State = nullptr);
2104 Node *parseLocalName(NameState *State);
2105 Node *parseOperatorName(NameState *State);
2106 Node *parseUnqualifiedName(NameState *State);
2107 Node *parseUnnamedTypeName(NameState *State);
2108 Node *parseSourceName(NameState *State);
2109 Node *parseUnscopedName(NameState *State);
2110 Node *parseNestedName(NameState *State);
2111 Node *parseCtorDtorName(Node *&SoFar, NameState *State);
2112
2113 Node *parseAbiTags(Node *N);
2114
2115 /// Parse the <unresolved-name> production.
2116 Node *parseUnresolvedName();
2117 Node *parseSimpleId();
2118 Node *parseBaseUnresolvedName();
2119 Node *parseUnresolvedType();
2120 Node *parseDestructorName();
2121
2122 /// Top-level entry point into the parser.
2123 Node *parse();
2124};
2125
2126const char* parse_discriminator(const char* first, const char* last);
2127
2128// <name> ::= <nested-name> // N
2129// ::= <local-name> # See Scope Encoding below // Z
2130// ::= <unscoped-template-name> <template-args>
2131// ::= <unscoped-name>
2132//
2133// <unscoped-template-name> ::= <unscoped-name>
2134// ::= <substitution>
2135Node *Db::parseName(NameState *State) {
2136 consumeIf('L'); // extension
2137
2138 if (look() == 'N')
2139 return parseNestedName(State);
2140 if (look() == 'Z')
2141 return parseLocalName(State);
2142
2143 // ::= <unscoped-template-name> <template-args>
2144 if (look() == 'S' && look(1) != 't') {
2145 Node *S = parseSubstitution();
2146 if (S == nullptr)
2147 return nullptr;
2148 if (look() != 'I')
2149 return nullptr;
Erik Pilkington8a1cb332018-03-25 22:50:33 +00002150 Node *TA = parseTemplateArgs(State != nullptr);
Erik Pilkingtonbb7feae2018-03-19 15:18:23 +00002151 if (TA == nullptr)
2152 return nullptr;
2153 if (State) State->EndsWithTemplateArgs = true;
2154 return make<NameWithTemplateArgs>(S, TA);
2155 }
2156
2157 Node *N = parseUnscopedName(State);
2158 if (N == nullptr)
2159 return nullptr;
2160 // ::= <unscoped-template-name> <template-args>
2161 if (look() == 'I') {
2162 Subs.push_back(N);
Erik Pilkington8a1cb332018-03-25 22:50:33 +00002163 Node *TA = parseTemplateArgs(State != nullptr);
Erik Pilkingtonbb7feae2018-03-19 15:18:23 +00002164 if (TA == nullptr)
2165 return nullptr;
2166 if (State) State->EndsWithTemplateArgs = true;
2167 return make<NameWithTemplateArgs>(N, TA);
2168 }
2169 // ::= <unscoped-name>
2170 return N;
2171}
2172
2173// <local-name> := Z <function encoding> E <entity name> [<discriminator>]
2174// := Z <function encoding> E s [<discriminator>]
2175// := Z <function encoding> Ed [ <parameter number> ] _ <entity name>
2176Node *Db::parseLocalName(NameState *State) {
2177 if (!consumeIf('Z'))
2178 return nullptr;
2179 Node *Encoding = parseEncoding();
2180 if (Encoding == nullptr || !consumeIf('E'))
2181 return nullptr;
2182
2183 if (consumeIf('s')) {
2184 First = parse_discriminator(First, Last);
Erik Pilkingtonf2a9b0f2018-04-12 20:41:06 +00002185 return make<LocalName>(Encoding, make<NameType>("string literal"));
Erik Pilkingtonbb7feae2018-03-19 15:18:23 +00002186 }
2187
2188 if (consumeIf('d')) {
2189 parseNumber(true);
2190 if (!consumeIf('_'))
2191 return nullptr;
2192 Node *N = parseName(State);
2193 if (N == nullptr)
2194 return nullptr;
Erik Pilkingtonf2a9b0f2018-04-12 20:41:06 +00002195 return make<LocalName>(Encoding, N);
Erik Pilkingtonbb7feae2018-03-19 15:18:23 +00002196 }
2197
2198 Node *Entity = parseName(State);
2199 if (Entity == nullptr)
2200 return nullptr;
2201 First = parse_discriminator(First, Last);
Erik Pilkingtonf2a9b0f2018-04-12 20:41:06 +00002202 return make<LocalName>(Encoding, Entity);
Erik Pilkingtonbb7feae2018-03-19 15:18:23 +00002203}
2204
2205// <unscoped-name> ::= <unqualified-name>
2206// ::= St <unqualified-name> # ::std::
2207// extension ::= StL<unqualified-name>
2208Node *Db::parseUnscopedName(NameState *State) {
2209 if (consumeIf("StL") || consumeIf("St")) {
2210 Node *R = parseUnqualifiedName(State);
2211 if (R == nullptr)
2212 return nullptr;
2213 return make<StdQualifiedName>(R);
2214 }
2215 return parseUnqualifiedName(State);
2216}
2217
2218// <unqualified-name> ::= <operator-name> [abi-tags]
2219// ::= <ctor-dtor-name>
2220// ::= <source-name>
2221// ::= <unnamed-type-name>
2222// ::= DC <source-name>+ E # structured binding declaration
2223Node *Db::parseUnqualifiedName(NameState *State) {
2224 // <ctor-dtor-name>s are special-cased in parseNestedName().
2225 Node *Result;
2226 if (look() == 'U')
2227 Result = parseUnnamedTypeName(State);
2228 else if (look() >= '1' && look() <= '9')
2229 Result = parseSourceName(State);
2230 else if (consumeIf("DC")) {
2231 size_t BindingsBegin = Names.size();
2232 do {
2233 Node *Binding = parseSourceName(State);
2234 if (Binding == nullptr)
2235 return nullptr;
2236 Names.push_back(Binding);
2237 } while (!consumeIf('E'));
2238 Result = make<StructuredBindingName>(popTrailingNodeArray(BindingsBegin));
2239 } else
2240 Result = parseOperatorName(State);
2241 if (Result != nullptr)
2242 Result = parseAbiTags(Result);
2243 return Result;
2244}
2245
2246// <unnamed-type-name> ::= Ut [<nonnegative number>] _
2247// ::= <closure-type-name>
2248//
2249// <closure-type-name> ::= Ul <lambda-sig> E [ <nonnegative number> ] _
2250//
2251// <lambda-sig> ::= <parameter type>+ # Parameter types or "v" if the lambda has no parameters
2252Node *Db::parseUnnamedTypeName(NameState *) {
2253 if (consumeIf("Ut")) {
2254 StringView Count = parseNumber();
2255 if (!consumeIf('_'))
2256 return nullptr;
2257 return make<UnnamedTypeName>(Count);
2258 }
2259 if (consumeIf("Ul")) {
2260 NodeArray Params;
2261 SwapAndRestore<bool> SwapParams(ParsingLambdaParams, true);
2262 if (!consumeIf("vE")) {
2263 size_t ParamsBegin = Names.size();
2264 do {
2265 Node *P = parseType();
2266 if (P == nullptr)
2267 return nullptr;
2268 Names.push_back(P);
2269 } while (!consumeIf('E'));
2270 Params = popTrailingNodeArray(ParamsBegin);
2271 }
2272 StringView Count = parseNumber();
2273 if (!consumeIf('_'))
2274 return nullptr;
2275 return make<ClosureTypeName>(Params, Count);
2276 }
2277 return nullptr;
Rafael Espindolab940b662016-09-06 19:16:48 +00002278}
2279
2280// <source-name> ::= <positive length number> <identifier>
Erik Pilkingtonbb7feae2018-03-19 15:18:23 +00002281Node *Db::parseSourceName(NameState *) {
2282 size_t Length = 0;
2283 if (parsePositiveInteger(&Length))
2284 return nullptr;
2285 if (numLeft() < Length || Length == 0)
2286 return nullptr;
2287 StringView Name(First, First + Length);
2288 First += Length;
2289 if (Name.startsWith("_GLOBAL__N"))
2290 return make<NameType>("(anonymous namespace)");
2291 return make<NameType>(Name);
Rafael Espindolab940b662016-09-06 19:16:48 +00002292}
2293
Erik Pilkingtonbb7feae2018-03-19 15:18:23 +00002294// <operator-name> ::= aa # &&
Rafael Espindolab940b662016-09-06 19:16:48 +00002295// ::= ad # & (unary)
2296// ::= an # &
2297// ::= aN # &=
2298// ::= aS # =
2299// ::= cl # ()
2300// ::= cm # ,
2301// ::= co # ~
2302// ::= cv <type> # (cast)
2303// ::= da # delete[]
2304// ::= de # * (unary)
2305// ::= dl # delete
2306// ::= dv # /
2307// ::= dV # /=
2308// ::= eo # ^
2309// ::= eO # ^=
2310// ::= eq # ==
2311// ::= ge # >=
2312// ::= gt # >
2313// ::= ix # []
2314// ::= le # <=
2315// ::= li <source-name> # operator ""
2316// ::= ls # <<
2317// ::= lS # <<=
2318// ::= lt # <
2319// ::= mi # -
2320// ::= mI # -=
2321// ::= ml # *
2322// ::= mL # *=
2323// ::= mm # -- (postfix in <expression> context)
2324// ::= na # new[]
2325// ::= ne # !=
2326// ::= ng # - (unary)
2327// ::= nt # !
2328// ::= nw # new
2329// ::= oo # ||
2330// ::= or # |
2331// ::= oR # |=
2332// ::= pm # ->*
2333// ::= pl # +
2334// ::= pL # +=
2335// ::= pp # ++ (postfix in <expression> context)
2336// ::= ps # + (unary)
2337// ::= pt # ->
2338// ::= qu # ?
2339// ::= rm # %
2340// ::= rM # %=
2341// ::= rs # >>
2342// ::= rS # >>=
Erik Pilkingtonbb7feae2018-03-19 15:18:23 +00002343// ::= ss # <=> C++2a
2344// ::= v <digit> <source-name> # vendor extended operator
2345Node *Db::parseOperatorName(NameState *State) {
2346 switch (look()) {
2347 case 'a':
2348 switch (look(1)) {
Rafael Espindolab940b662016-09-06 19:16:48 +00002349 case 'a':
Erik Pilkingtonbb7feae2018-03-19 15:18:23 +00002350 First += 2;
2351 return make<NameType>("operator&&");
Rafael Espindolab940b662016-09-06 19:16:48 +00002352 case 'd':
Rafael Espindolab940b662016-09-06 19:16:48 +00002353 case 'n':
Erik Pilkingtonbb7feae2018-03-19 15:18:23 +00002354 First += 2;
2355 return make<NameType>("operator&");
2356 case 'N':
2357 First += 2;
2358 return make<NameType>("operator&=");
2359 case 'S':
2360 First += 2;
2361 return make<NameType>("operator=");
2362 }
2363 return nullptr;
2364 case 'c':
2365 switch (look(1)) {
2366 case 'l':
2367 First += 2;
2368 return make<NameType>("operator()");
2369 case 'm':
2370 First += 2;
2371 return make<NameType>("operator,");
Rafael Espindolab940b662016-09-06 19:16:48 +00002372 case 'o':
Erik Pilkingtonbb7feae2018-03-19 15:18:23 +00002373 First += 2;
2374 return make<NameType>("operator~");
2375 // ::= cv <type> # (cast)
2376 case 'v': {
Erik Pilkingtonbb7feae2018-03-19 15:18:23 +00002377 First += 2;
Erik Pilkington8a1cb332018-03-25 22:50:33 +00002378 SwapAndRestore<bool> SaveTemplate(TryToParseTemplateArgs, false);
2379 // If we're parsing an encoding, State != nullptr and the conversion
2380 // operators' <type> could have a <template-param> that refers to some
2381 // <template-arg>s further ahead in the mangled name.
2382 SwapAndRestore<bool> SavePermit(PermitForwardTemplateReferences,
2383 PermitForwardTemplateReferences ||
2384 State != nullptr);
2385 Node* Ty = parseType();
Erik Pilkingtonbb7feae2018-03-19 15:18:23 +00002386 if (Ty == nullptr)
2387 return nullptr;
2388 if (State) State->CtorDtorConversion = true;
2389 return make<ConversionOperatorType>(Ty);
2390 }
2391 }
2392 return nullptr;
2393 case 'd':
2394 switch (look(1)) {
2395 case 'a':
2396 First += 2;
2397 return make<NameType>("operator delete[]");
2398 case 'e':
2399 First += 2;
2400 return make<NameType>("operator*");
2401 case 'l':
2402 First += 2;
2403 return make<NameType>("operator delete");
Rafael Espindolab940b662016-09-06 19:16:48 +00002404 case 'v':
Erik Pilkingtonbb7feae2018-03-19 15:18:23 +00002405 First += 2;
2406 return make<NameType>("operator/");
2407 case 'V':
2408 First += 2;
2409 return make<NameType>("operator/=");
Rafael Espindolab940b662016-09-06 19:16:48 +00002410 }
Erik Pilkingtonbb7feae2018-03-19 15:18:23 +00002411 return nullptr;
2412 case 'e':
2413 switch (look(1)) {
Rafael Espindolab940b662016-09-06 19:16:48 +00002414 case 'o':
Erik Pilkingtonbb7feae2018-03-19 15:18:23 +00002415 First += 2;
2416 return make<NameType>("operator^");
2417 case 'O':
2418 First += 2;
2419 return make<NameType>("operator^=");
Rafael Espindolab940b662016-09-06 19:16:48 +00002420 case 'q':
Erik Pilkingtonbb7feae2018-03-19 15:18:23 +00002421 First += 2;
2422 return make<NameType>("operator==");
2423 }
2424 return nullptr;
2425 case 'g':
2426 switch (look(1)) {
2427 case 'e':
2428 First += 2;
2429 return make<NameType>("operator>=");
Rafael Espindolab940b662016-09-06 19:16:48 +00002430 case 't':
Erik Pilkingtonbb7feae2018-03-19 15:18:23 +00002431 First += 2;
2432 return make<NameType>("operator>");
Rafael Espindolab940b662016-09-06 19:16:48 +00002433 }
Erik Pilkingtonbb7feae2018-03-19 15:18:23 +00002434 return nullptr;
2435 case 'i':
2436 if (look(1) == 'x') {
2437 First += 2;
2438 return make<NameType>("operator[]");
2439 }
2440 return nullptr;
2441 case 'l':
2442 switch (look(1)) {
2443 case 'e':
2444 First += 2;
2445 return make<NameType>("operator<=");
2446 // ::= li <source-name> # operator ""
2447 case 'i': {
2448 First += 2;
2449 Node *SN = parseSourceName(State);
2450 if (SN == nullptr)
2451 return nullptr;
2452 return make<LiteralOperator>(SN);
2453 }
2454 case 's':
2455 First += 2;
2456 return make<NameType>("operator<<");
2457 case 'S':
2458 First += 2;
2459 return make<NameType>("operator<<=");
2460 case 't':
2461 First += 2;
2462 return make<NameType>("operator<");
2463 }
2464 return nullptr;
2465 case 'm':
2466 switch (look(1)) {
2467 case 'i':
2468 First += 2;
2469 return make<NameType>("operator-");
2470 case 'I':
2471 First += 2;
2472 return make<NameType>("operator-=");
2473 case 'l':
2474 First += 2;
2475 return make<NameType>("operator*");
Rafael Espindolab940b662016-09-06 19:16:48 +00002476 case 'L':
Erik Pilkingtonbb7feae2018-03-19 15:18:23 +00002477 First += 2;
2478 return make<NameType>("operator*=");
2479 case 'm':
2480 First += 2;
2481 return make<NameType>("operator--");
2482 }
2483 return nullptr;
2484 case 'n':
2485 switch (look(1)) {
2486 case 'a':
2487 First += 2;
2488 return make<NameType>("operator new[]");
2489 case 'e':
2490 First += 2;
2491 return make<NameType>("operator!=");
2492 case 'g':
2493 First += 2;
2494 return make<NameType>("operator-");
2495 case 't':
2496 First += 2;
2497 return make<NameType>("operator!");
2498 case 'w':
2499 First += 2;
2500 return make<NameType>("operator new");
2501 }
2502 return nullptr;
2503 case 'o':
2504 switch (look(1)) {
2505 case 'o':
2506 First += 2;
2507 return make<NameType>("operator||");
2508 case 'r':
2509 First += 2;
2510 return make<NameType>("operator|");
2511 case 'R':
2512 First += 2;
2513 return make<NameType>("operator|=");
2514 }
2515 return nullptr;
2516 case 'p':
2517 switch (look(1)) {
2518 case 'm':
2519 First += 2;
2520 return make<NameType>("operator->*");
2521 case 'l':
2522 First += 2;
2523 return make<NameType>("operator+");
2524 case 'L':
2525 First += 2;
2526 return make<NameType>("operator+=");
2527 case 'p':
2528 First += 2;
2529 return make<NameType>("operator++");
2530 case 's':
2531 First += 2;
2532 return make<NameType>("operator+");
2533 case 't':
2534 First += 2;
2535 return make<NameType>("operator->");
2536 }
2537 return nullptr;
2538 case 'q':
2539 if (look(1) == 'u') {
2540 First += 2;
2541 return make<NameType>("operator?");
2542 }
2543 return nullptr;
2544 case 'r':
2545 switch (look(1)) {
2546 case 'm':
2547 First += 2;
2548 return make<NameType>("operator%");
2549 case 'M':
2550 First += 2;
2551 return make<NameType>("operator%=");
2552 case 's':
2553 First += 2;
2554 return make<NameType>("operator>>");
2555 case 'S':
2556 First += 2;
2557 return make<NameType>("operator>>=");
2558 }
2559 return nullptr;
2560 case 's':
2561 if (look(1) == 's') {
2562 First += 2;
2563 return make<NameType>("operator<=>");
2564 }
2565 return nullptr;
2566 // ::= v <digit> <source-name> # vendor extended operator
2567 case 'v':
2568 if (std::isdigit(look(1))) {
2569 First += 2;
2570 Node *SN = parseSourceName(State);
2571 if (SN == nullptr)
2572 return nullptr;
2573 return make<ConversionOperatorType>(SN);
2574 }
2575 return nullptr;
2576 }
2577 return nullptr;
2578}
2579
2580// <ctor-dtor-name> ::= C1 # complete object constructor
2581// ::= C2 # base object constructor
2582// ::= C3 # complete object allocating constructor
2583// extension ::= C5 # ?
2584// ::= D0 # deleting destructor
2585// ::= D1 # complete object destructor
2586// ::= D2 # base object destructor
2587// extension ::= D5 # ?
2588Node *Db::parseCtorDtorName(Node *&SoFar, NameState *State) {
2589 if (SoFar->K == Node::KSpecialSubstitution) {
2590 auto SSK = static_cast<SpecialSubstitution *>(SoFar)->SSK;
2591 switch (SSK) {
2592 case SpecialSubKind::string:
2593 case SpecialSubKind::istream:
2594 case SpecialSubKind::ostream:
2595 case SpecialSubKind::iostream:
2596 SoFar = make<ExpandedSpecialSubstitution>(SSK);
Rafael Espindolab940b662016-09-06 19:16:48 +00002597 default:
Rafael Espindolab940b662016-09-06 19:16:48 +00002598 break;
2599 }
2600 }
Rafael Espindolab940b662016-09-06 19:16:48 +00002601
Erik Pilkingtonbb7feae2018-03-19 15:18:23 +00002602 if (consumeIf('C')) {
2603 bool IsInherited = consumeIf('I');
2604 if (look() != '1' && look() != '2' && look() != '3' && look() != '5')
2605 return nullptr;
2606 ++First;
2607 if (State) State->CtorDtorConversion = true;
2608 if (IsInherited) {
Erik Pilkington8a1cb332018-03-25 22:50:33 +00002609 if (parseName(State) == nullptr)
Erik Pilkingtonbb7feae2018-03-19 15:18:23 +00002610 return nullptr;
Rafael Espindolab940b662016-09-06 19:16:48 +00002611 }
Erik Pilkingtonbb7feae2018-03-19 15:18:23 +00002612 return make<CtorDtorName>(SoFar, false);
Rafael Espindolab940b662016-09-06 19:16:48 +00002613 }
Erik Pilkingtonbb7feae2018-03-19 15:18:23 +00002614
2615 if (look() == 'D' &&
2616 (look(1) == '0' || look(1) == '1' || look(1) == '2' || look(1) == '5')) {
2617 First += 2;
2618 if (State) State->CtorDtorConversion = true;
2619 return make<CtorDtorName>(SoFar, true);
2620 }
2621
2622 return nullptr;
Rafael Espindolab940b662016-09-06 19:16:48 +00002623}
2624
Erik Pilkingtonbb7feae2018-03-19 15:18:23 +00002625// <nested-name> ::= N [<CV-Qualifiers>] [<ref-qualifier>] <prefix> <unqualified-name> E
2626// ::= N [<CV-Qualifiers>] [<ref-qualifier>] <template-prefix> <template-args> E
Rafael Espindolab940b662016-09-06 19:16:48 +00002627//
2628// <prefix> ::= <prefix> <unqualified-name>
2629// ::= <template-prefix> <template-args>
2630// ::= <template-param>
2631// ::= <decltype>
2632// ::= # empty
2633// ::= <substitution>
2634// ::= <prefix> <data-member-prefix>
2635// extension ::= L
2636//
Erik Pilkington452e2ef2018-04-09 18:32:25 +00002637// <data-member-prefix> := <member source-name> [<template-args>] M
2638//
Rafael Espindolab940b662016-09-06 19:16:48 +00002639// <template-prefix> ::= <prefix> <template unqualified-name>
2640// ::= <template-param>
2641// ::= <substitution>
Erik Pilkingtonbb7feae2018-03-19 15:18:23 +00002642Node *Db::parseNestedName(NameState *State) {
2643 if (!consumeIf('N'))
2644 return nullptr;
Rafael Espindolab940b662016-09-06 19:16:48 +00002645
Erik Pilkingtonbb7feae2018-03-19 15:18:23 +00002646 Qualifiers CVTmp = parseCVQualifiers();
2647 if (State) State->CVQualifiers = CVTmp;
2648
2649 if (consumeIf('O')) {
2650 if (State) State->ReferenceQualifier = FrefQualRValue;
2651 } else if (consumeIf('R')) {
2652 if (State) State->ReferenceQualifier = FrefQualLValue;
2653 } else
2654 if (State) State->ReferenceQualifier = FrefQualNone;
2655
2656 Node *SoFar = nullptr;
2657 auto PushComponent = [&](Node *Comp) {
Erik Pilkingtonf2a9b0f2018-04-12 20:41:06 +00002658 if (SoFar) SoFar = make<NestedName>(SoFar, Comp);
Erik Pilkingtonbb7feae2018-03-19 15:18:23 +00002659 else SoFar = Comp;
2660 if (State) State->EndsWithTemplateArgs = false;
2661 };
2662
2663 if (consumeIf("St"))
2664 SoFar = make<NameType>("std");
2665
2666 while (!consumeIf('E')) {
2667 consumeIf('L'); // extension
2668
Erik Pilkington452e2ef2018-04-09 18:32:25 +00002669 // <data-member-prefix> := <member source-name> [<template-args>] M
2670 if (consumeIf('M')) {
2671 if (SoFar == nullptr)
2672 return nullptr;
2673 continue;
2674 }
2675
Erik Pilkingtonbb7feae2018-03-19 15:18:23 +00002676 // ::= <template-param>
2677 if (look() == 'T') {
2678 Node *TP = parseTemplateParam();
2679 if (TP == nullptr)
2680 return nullptr;
2681 PushComponent(TP);
2682 Subs.push_back(SoFar);
2683 continue;
Rafael Espindolab940b662016-09-06 19:16:48 +00002684 }
Erik Pilkingtonbb7feae2018-03-19 15:18:23 +00002685
2686 // ::= <template-prefix> <template-args>
2687 if (look() == 'I') {
Erik Pilkington8a1cb332018-03-25 22:50:33 +00002688 Node *TA = parseTemplateArgs(State != nullptr);
Erik Pilkingtonbb7feae2018-03-19 15:18:23 +00002689 if (TA == nullptr || SoFar == nullptr)
2690 return nullptr;
2691 SoFar = make<NameWithTemplateArgs>(SoFar, TA);
2692 if (State) State->EndsWithTemplateArgs = true;
2693 Subs.push_back(SoFar);
2694 continue;
Rafael Espindolab940b662016-09-06 19:16:48 +00002695 }
Erik Pilkingtonbb7feae2018-03-19 15:18:23 +00002696
2697 // ::= <decltype>
2698 if (look() == 'D' && (look(1) == 't' || look(1) == 'T')) {
2699 Node *DT = parseDecltype();
2700 if (DT == nullptr)
2701 return nullptr;
2702 PushComponent(DT);
2703 Subs.push_back(SoFar);
2704 continue;
Rafael Espindolab940b662016-09-06 19:16:48 +00002705 }
Erik Pilkingtonbb7feae2018-03-19 15:18:23 +00002706
2707 // ::= <substitution>
2708 if (look() == 'S' && look(1) != 't') {
2709 Node *S = parseSubstitution();
2710 if (S == nullptr)
2711 return nullptr;
2712 PushComponent(S);
2713 if (SoFar != S)
2714 Subs.push_back(S);
2715 continue;
Rafael Espindolab940b662016-09-06 19:16:48 +00002716 }
Erik Pilkingtonbb7feae2018-03-19 15:18:23 +00002717
2718 // Parse an <unqualified-name> thats actually a <ctor-dtor-name>.
2719 if (look() == 'C' || (look() == 'D' && look(1) != 'C')) {
2720 if (SoFar == nullptr)
2721 return nullptr;
2722 Node *CtorDtor = parseCtorDtorName(SoFar, State);
2723 if (CtorDtor == nullptr)
2724 return nullptr;
2725 PushComponent(CtorDtor);
2726 SoFar = parseAbiTags(SoFar);
2727 if (SoFar == nullptr)
2728 return nullptr;
2729 Subs.push_back(SoFar);
2730 continue;
2731 }
2732
2733 // ::= <prefix> <unqualified-name>
2734 Node *N = parseUnqualifiedName(State);
2735 if (N == nullptr)
2736 return nullptr;
2737 PushComponent(N);
2738 Subs.push_back(SoFar);
Rafael Espindolab940b662016-09-06 19:16:48 +00002739 }
Erik Pilkingtonbb7feae2018-03-19 15:18:23 +00002740
2741 if (SoFar == nullptr || Subs.empty())
2742 return nullptr;
2743
2744 Subs.pop_back();
2745 return SoFar;
Rafael Espindolab940b662016-09-06 19:16:48 +00002746}
2747
Erik Pilkingtonbb7feae2018-03-19 15:18:23 +00002748// <simple-id> ::= <source-name> [ <template-args> ]
2749Node *Db::parseSimpleId() {
2750 Node *SN = parseSourceName(/*NameState=*/nullptr);
2751 if (SN == nullptr)
2752 return nullptr;
2753 if (look() == 'I') {
2754 Node *TA = parseTemplateArgs();
2755 if (TA == nullptr)
2756 return nullptr;
2757 return make<NameWithTemplateArgs>(SN, TA);
Rafael Espindolab940b662016-09-06 19:16:48 +00002758 }
Erik Pilkingtonbb7feae2018-03-19 15:18:23 +00002759 return SN;
Rafael Espindolab940b662016-09-06 19:16:48 +00002760}
2761
Erik Pilkingtonbb7feae2018-03-19 15:18:23 +00002762// <destructor-name> ::= <unresolved-type> # e.g., ~T or ~decltype(f())
2763// ::= <simple-id> # e.g., ~A<2*N>
2764Node *Db::parseDestructorName() {
2765 Node *Result;
2766 if (std::isdigit(look()))
2767 Result = parseSimpleId();
2768 else
2769 Result = parseUnresolvedType();
2770 if (Result == nullptr)
2771 return nullptr;
2772 return make<DtorName>(Result);
Rafael Espindolab940b662016-09-06 19:16:48 +00002773}
2774
Erik Pilkingtonbb7feae2018-03-19 15:18:23 +00002775// <unresolved-type> ::= <template-param>
2776// ::= <decltype>
2777// ::= <substitution>
2778Node *Db::parseUnresolvedType() {
2779 if (look() == 'T') {
2780 Node *TP = parseTemplateParam();
2781 if (TP == nullptr)
2782 return nullptr;
2783 Subs.push_back(TP);
2784 return TP;
2785 }
2786 if (look() == 'D') {
2787 Node *DT = parseDecltype();
2788 if (DT == nullptr)
2789 return nullptr;
2790 Subs.push_back(DT);
2791 return DT;
2792 }
2793 return parseSubstitution();
2794}
Rafael Espindolab940b662016-09-06 19:16:48 +00002795
Erik Pilkingtonbb7feae2018-03-19 15:18:23 +00002796// <base-unresolved-name> ::= <simple-id> # unresolved name
2797// extension ::= <operator-name> # unresolved operator-function-id
2798// extension ::= <operator-name> <template-args> # unresolved operator template-id
2799// ::= on <operator-name> # unresolved operator-function-id
2800// ::= on <operator-name> <template-args> # unresolved operator template-id
2801// ::= dn <destructor-name> # destructor or pseudo-destructor;
2802// # e.g. ~X or ~X<N-1>
2803Node *Db::parseBaseUnresolvedName() {
2804 if (std::isdigit(look()))
2805 return parseSimpleId();
Rafael Espindolab940b662016-09-06 19:16:48 +00002806
Erik Pilkingtonbb7feae2018-03-19 15:18:23 +00002807 if (consumeIf("dn"))
2808 return parseDestructorName();
2809
2810 consumeIf("on");
2811
2812 Node *Oper = parseOperatorName(/*NameState=*/nullptr);
2813 if (Oper == nullptr)
2814 return nullptr;
2815 if (look() == 'I') {
2816 Node *TA = parseTemplateArgs();
2817 if (TA == nullptr)
2818 return nullptr;
2819 return make<NameWithTemplateArgs>(Oper, TA);
2820 }
2821 return Oper;
2822}
2823
2824// <unresolved-name>
2825// extension ::= srN <unresolved-type> [<template-args>] <unresolved-qualifier-level>* E <base-unresolved-name>
2826// ::= [gs] <base-unresolved-name> # x or (with "gs") ::x
Zachary Turnerfac2da12018-07-16 21:24:03 +00002827// ::= [gs] sr <unresolved-qualifier-level>+ E <base-unresolved-name>
Erik Pilkingtonbb7feae2018-03-19 15:18:23 +00002828// # A::x, N::y, A<T>::z; "gs" means leading "::"
2829// ::= sr <unresolved-type> <base-unresolved-name> # T::x / decltype(p)::x
2830// extension ::= sr <unresolved-type> <template-args> <base-unresolved-name>
2831// # T::N::x /decltype(p)::N::x
2832// (ignored) ::= srN <unresolved-type> <unresolved-qualifier-level>+ E <base-unresolved-name>
2833//
2834// <unresolved-qualifier-level> ::= <simple-id>
2835Node *Db::parseUnresolvedName() {
2836 Node *SoFar = nullptr;
2837
2838 // srN <unresolved-type> [<template-args>] <unresolved-qualifier-level>* E <base-unresolved-name>
2839 // srN <unresolved-type> <unresolved-qualifier-level>+ E <base-unresolved-name>
2840 if (consumeIf("srN")) {
2841 SoFar = parseUnresolvedType();
2842 if (SoFar == nullptr)
2843 return nullptr;
2844
2845 if (look() == 'I') {
2846 Node *TA = parseTemplateArgs();
2847 if (TA == nullptr)
2848 return nullptr;
2849 SoFar = make<NameWithTemplateArgs>(SoFar, TA);
2850 }
2851
2852 while (!consumeIf('E')) {
2853 Node *Qual = parseSimpleId();
2854 if (Qual == nullptr)
2855 return nullptr;
2856 SoFar = make<QualifiedName>(SoFar, Qual);
2857 }
2858
2859 Node *Base = parseBaseUnresolvedName();
2860 if (Base == nullptr)
2861 return nullptr;
2862 return make<QualifiedName>(SoFar, Base);
2863 }
2864
2865 bool Global = consumeIf("gs");
2866
2867 // [gs] <base-unresolved-name> # x or (with "gs") ::x
2868 if (!consumeIf("sr")) {
2869 SoFar = parseBaseUnresolvedName();
2870 if (SoFar == nullptr)
2871 return nullptr;
2872 if (Global)
2873 SoFar = make<GlobalQualifiedName>(SoFar);
2874 return SoFar;
2875 }
2876
Zachary Turnerfac2da12018-07-16 21:24:03 +00002877 // [gs] sr <unresolved-qualifier-level>+ E <base-unresolved-name>
Erik Pilkingtonbb7feae2018-03-19 15:18:23 +00002878 if (std::isdigit(look())) {
2879 do {
2880 Node *Qual = parseSimpleId();
2881 if (Qual == nullptr)
2882 return nullptr;
2883 if (SoFar)
2884 SoFar = make<QualifiedName>(SoFar, Qual);
2885 else if (Global)
2886 SoFar = make<GlobalQualifiedName>(Qual);
2887 else
2888 SoFar = Qual;
2889 } while (!consumeIf('E'));
2890 }
2891 // sr <unresolved-type> <base-unresolved-name>
2892 // sr <unresolved-type> <template-args> <base-unresolved-name>
2893 else {
2894 SoFar = parseUnresolvedType();
2895 if (SoFar == nullptr)
2896 return nullptr;
2897
2898 if (look() == 'I') {
2899 Node *TA = parseTemplateArgs();
2900 if (TA == nullptr)
2901 return nullptr;
2902 SoFar = make<NameWithTemplateArgs>(SoFar, TA);
2903 }
2904 }
2905
2906 assert(SoFar != nullptr);
2907
2908 Node *Base = parseBaseUnresolvedName();
2909 if (Base == nullptr)
2910 return nullptr;
2911 return make<QualifiedName>(SoFar, Base);
2912}
2913
2914// <abi-tags> ::= <abi-tag> [<abi-tags>]
2915// <abi-tag> ::= B <source-name>
2916Node *Db::parseAbiTags(Node *N) {
2917 while (consumeIf('B')) {
2918 StringView SN = parseBareSourceName();
2919 if (SN.empty())
2920 return nullptr;
2921 N = make<AbiTagAttr>(N, SN);
2922 }
2923 return N;
2924}
2925
2926// <number> ::= [n] <non-negative decimal integer>
2927StringView Db::parseNumber(bool AllowNegative) {
2928 const char *Tmp = First;
2929 if (AllowNegative)
2930 consumeIf('n');
2931 if (numLeft() == 0 || !std::isdigit(*First))
2932 return StringView();
2933 while (numLeft() != 0 && std::isdigit(*First))
2934 ++First;
2935 return StringView(Tmp, First);
2936}
2937
2938// <positive length number> ::= [0-9]*
2939bool Db::parsePositiveInteger(size_t *Out) {
2940 *Out = 0;
2941 if (look() < '0' || look() > '9')
2942 return true;
2943 while (look() >= '0' && look() <= '9') {
2944 *Out *= 10;
2945 *Out += static_cast<size_t>(consume() - '0');
2946 }
2947 return false;
2948}
2949
2950StringView Db::parseBareSourceName() {
2951 size_t Int = 0;
2952 if (parsePositiveInteger(&Int) || numLeft() < Int)
2953 return StringView();
2954 StringView R(First, First + Int);
2955 First += Int;
2956 return R;
2957}
2958
2959// <function-type> ::= [<CV-qualifiers>] [<exception-spec>] [Dx] F [Y] <bare-function-type> [<ref-qualifier>] E
2960//
2961// <exception-spec> ::= Do # non-throwing exception-specification (e.g., noexcept, throw())
2962// ::= DO <expression> E # computed (instantiation-dependent) noexcept
2963// ::= Dw <type>+ E # dynamic exception specification with instantiation-dependent types
2964//
2965// <ref-qualifier> ::= R # & ref-qualifier
2966// <ref-qualifier> ::= O # && ref-qualifier
2967Node *Db::parseFunctionType() {
2968 Qualifiers CVQuals = parseCVQualifiers();
2969
2970 Node *ExceptionSpec = nullptr;
2971 if (consumeIf("Do")) {
2972 ExceptionSpec = make<NameType>("noexcept");
2973 } else if (consumeIf("DO")) {
2974 Node *E = parseExpr();
2975 if (E == nullptr || !consumeIf('E'))
2976 return nullptr;
2977 ExceptionSpec = make<NoexceptSpec>(E);
2978 } else if (consumeIf("Dw")) {
2979 size_t SpecsBegin = Names.size();
2980 while (!consumeIf('E')) {
2981 Node *T = parseType();
2982 if (T == nullptr)
2983 return nullptr;
2984 Names.push_back(T);
2985 }
2986 ExceptionSpec =
2987 make<DynamicExceptionSpec>(popTrailingNodeArray(SpecsBegin));
2988 }
2989
2990 consumeIf("Dx"); // transaction safe
2991
2992 if (!consumeIf('F'))
2993 return nullptr;
2994 consumeIf('Y'); // extern "C"
2995 Node *ReturnType = parseType();
2996 if (ReturnType == nullptr)
2997 return nullptr;
2998
2999 FunctionRefQual ReferenceQualifier = FrefQualNone;
3000 size_t ParamsBegin = Names.size();
3001 while (true) {
3002 if (consumeIf('E'))
3003 break;
3004 if (consumeIf('v'))
3005 continue;
3006 if (consumeIf("RE")) {
3007 ReferenceQualifier = FrefQualLValue;
Rafael Espindolab940b662016-09-06 19:16:48 +00003008 break;
3009 }
Erik Pilkingtonbb7feae2018-03-19 15:18:23 +00003010 if (consumeIf("OE")) {
3011 ReferenceQualifier = FrefQualRValue;
Rafael Espindolab940b662016-09-06 19:16:48 +00003012 break;
3013 }
Erik Pilkingtonbb7feae2018-03-19 15:18:23 +00003014 Node *T = parseType();
3015 if (T == nullptr)
3016 return nullptr;
3017 Names.push_back(T);
3018 }
3019
3020 NodeArray Params = popTrailingNodeArray(ParamsBegin);
3021 return make<FunctionType>(ReturnType, Params, CVQuals,
3022 ReferenceQualifier, ExceptionSpec);
3023}
3024
3025// extension:
3026// <vector-type> ::= Dv <positive dimension number> _ <extended element type>
3027// ::= Dv [<dimension expression>] _ <element type>
3028// <extended element type> ::= <element type>
3029// ::= p # AltiVec vector pixel
3030Node *Db::parseVectorType() {
3031 if (!consumeIf("Dv"))
3032 return nullptr;
3033 if (look() >= '1' && look() <= '9') {
3034 StringView DimensionNumber = parseNumber();
3035 if (!consumeIf('_'))
3036 return nullptr;
3037 if (consumeIf('p'))
3038 return make<VectorType>(DimensionNumber);
3039 Node *ElemType = parseType();
3040 if (ElemType == nullptr)
3041 return nullptr;
3042 return make<VectorType>(ElemType, DimensionNumber);
3043 }
3044
3045 if (!consumeIf('_')) {
3046 Node *DimExpr = parseExpr();
3047 if (!DimExpr)
3048 return nullptr;
3049 if (!consumeIf('_'))
3050 return nullptr;
3051 Node *ElemType = parseType();
3052 if (!ElemType)
3053 return nullptr;
3054 return make<VectorType>(ElemType, DimExpr);
3055 }
3056 Node *ElemType = parseType();
3057 if (!ElemType)
3058 return nullptr;
3059 return make<VectorType>(ElemType, StringView());
3060}
3061
3062// <decltype> ::= Dt <expression> E # decltype of an id-expression or class member access (C++0x)
3063// ::= DT <expression> E # decltype of an expression (C++0x)
3064Node *Db::parseDecltype() {
3065 if (!consumeIf('D'))
3066 return nullptr;
3067 if (!consumeIf('t') && !consumeIf('T'))
3068 return nullptr;
3069 Node *E = parseExpr();
3070 if (E == nullptr)
3071 return nullptr;
3072 if (!consumeIf('E'))
3073 return nullptr;
3074 return make<EnclosingExpr>("decltype(", E, ")");
3075}
3076
3077// <array-type> ::= A <positive dimension number> _ <element type>
3078// ::= A [<dimension expression>] _ <element type>
3079Node *Db::parseArrayType() {
3080 if (!consumeIf('A'))
3081 return nullptr;
3082
3083 if (std::isdigit(look())) {
3084 StringView Dimension = parseNumber();
3085 if (!consumeIf('_'))
3086 return nullptr;
3087 Node *Ty = parseType();
3088 if (Ty == nullptr)
3089 return nullptr;
3090 return make<ArrayType>(Ty, Dimension);
3091 }
3092
3093 if (!consumeIf('_')) {
3094 Node *DimExpr = parseExpr();
3095 if (DimExpr == nullptr)
3096 return nullptr;
3097 if (!consumeIf('_'))
3098 return nullptr;
3099 Node *ElementType = parseType();
3100 if (ElementType == nullptr)
3101 return nullptr;
3102 return make<ArrayType>(ElementType, DimExpr);
3103 }
3104
3105 Node *Ty = parseType();
3106 if (Ty == nullptr)
3107 return nullptr;
3108 return make<ArrayType>(Ty);
3109}
3110
3111// <pointer-to-member-type> ::= M <class type> <member type>
3112Node *Db::parsePointerToMemberType() {
3113 if (!consumeIf('M'))
3114 return nullptr;
3115 Node *ClassType = parseType();
3116 if (ClassType == nullptr)
3117 return nullptr;
3118 Node *MemberType = parseType();
3119 if (MemberType == nullptr)
3120 return nullptr;
3121 return make<PointerToMemberType>(ClassType, MemberType);
3122}
3123
3124// <class-enum-type> ::= <name> # non-dependent type name, dependent type name, or dependent typename-specifier
3125// ::= Ts <name> # dependent elaborated type specifier using 'struct' or 'class'
3126// ::= Tu <name> # dependent elaborated type specifier using 'union'
3127// ::= Te <name> # dependent elaborated type specifier using 'enum'
3128Node *Db::parseClassEnumType() {
3129 StringView ElabSpef;
3130 if (consumeIf("Ts"))
3131 ElabSpef = "struct";
3132 else if (consumeIf("Tu"))
3133 ElabSpef = "union";
3134 else if (consumeIf("Te"))
3135 ElabSpef = "enum";
3136
3137 Node *Name = parseName();
3138 if (Name == nullptr)
3139 return nullptr;
3140
3141 if (!ElabSpef.empty())
3142 return make<ElaboratedTypeSpefType>(ElabSpef, Name);
3143
3144 return Name;
3145}
3146
3147// <qualified-type> ::= <qualifiers> <type>
3148// <qualifiers> ::= <extended-qualifier>* <CV-qualifiers>
3149// <extended-qualifier> ::= U <source-name> [<template-args>] # vendor extended type qualifier
3150Node *Db::parseQualifiedType() {
3151 if (consumeIf('U')) {
3152 StringView Qual = parseBareSourceName();
3153 if (Qual.empty())
3154 return nullptr;
3155
3156 // FIXME parse the optional <template-args> here!
3157
3158 // extension ::= U <objc-name> <objc-type> # objc-type<identifier>
3159 if (Qual.startsWith("objcproto")) {
3160 StringView ProtoSourceName = Qual.dropFront(std::strlen("objcproto"));
3161 StringView Proto;
3162 {
3163 SwapAndRestore<const char *> SaveFirst(First, ProtoSourceName.begin()),
3164 SaveLast(Last, ProtoSourceName.end());
3165 Proto = parseBareSourceName();
Rafael Espindolab940b662016-09-06 19:16:48 +00003166 }
Erik Pilkingtonbb7feae2018-03-19 15:18:23 +00003167 if (Proto.empty())
3168 return nullptr;
3169 Node *Child = parseQualifiedType();
3170 if (Child == nullptr)
3171 return nullptr;
3172 return make<ObjCProtoName>(Child, Proto);
3173 }
3174
3175 Node *Child = parseQualifiedType();
3176 if (Child == nullptr)
3177 return nullptr;
3178 return make<VendorExtQualType>(Child, Qual);
3179 }
3180
3181 Qualifiers Quals = parseCVQualifiers();
3182 Node *Ty = parseType();
3183 if (Ty == nullptr)
3184 return nullptr;
3185 if (Quals != QualNone)
3186 Ty = make<QualType>(Ty, Quals);
3187 return Ty;
3188}
3189
3190// <type> ::= <builtin-type>
3191// ::= <qualified-type>
3192// ::= <function-type>
3193// ::= <class-enum-type>
3194// ::= <array-type>
3195// ::= <pointer-to-member-type>
3196// ::= <template-param>
3197// ::= <template-template-param> <template-args>
3198// ::= <decltype>
3199// ::= P <type> # pointer
3200// ::= R <type> # l-value reference
3201// ::= O <type> # r-value reference (C++11)
3202// ::= C <type> # complex pair (C99)
3203// ::= G <type> # imaginary (C99)
3204// ::= <substitution> # See Compression below
3205// extension ::= U <objc-name> <objc-type> # objc-type<identifier>
3206// extension ::= <vector-type> # <vector-type> starts with Dv
3207//
3208// <objc-name> ::= <k0 number> objcproto <k1 number> <identifier> # k0 = 9 + <number of digits in k1> + k1
3209// <objc-type> ::= <source-name> # PU<11+>objcproto 11objc_object<source-name> 11objc_object -> id<source-name>
3210Node *Db::parseType() {
3211 Node *Result = nullptr;
3212
Erik Pilkingtonac6a801c2018-08-13 16:37:47 +00003213 if (TypeCallback != nullptr)
3214 TypeCallback(TypeCallbackContext, First);
3215
Erik Pilkingtonbb7feae2018-03-19 15:18:23 +00003216 switch (look()) {
3217 // ::= <qualified-type>
3218 case 'r':
3219 case 'V':
3220 case 'K': {
3221 unsigned AfterQuals = 0;
3222 if (look(AfterQuals) == 'r') ++AfterQuals;
3223 if (look(AfterQuals) == 'V') ++AfterQuals;
3224 if (look(AfterQuals) == 'K') ++AfterQuals;
3225
3226 if (look(AfterQuals) == 'F' ||
3227 (look(AfterQuals) == 'D' &&
3228 (look(AfterQuals + 1) == 'o' || look(AfterQuals + 1) == 'O' ||
3229 look(AfterQuals + 1) == 'w' || look(AfterQuals + 1) == 'x'))) {
3230 Result = parseFunctionType();
Rafael Espindolab940b662016-09-06 19:16:48 +00003231 break;
3232 }
Erik Pilkingtonbb7feae2018-03-19 15:18:23 +00003233 LLVM_FALLTHROUGH;
3234 }
3235 case 'U': {
3236 Result = parseQualifiedType();
3237 break;
3238 }
3239 // <builtin-type> ::= v # void
3240 case 'v':
3241 ++First;
3242 return make<NameType>("void");
3243 // ::= w # wchar_t
3244 case 'w':
3245 ++First;
3246 return make<NameType>("wchar_t");
3247 // ::= b # bool
3248 case 'b':
3249 ++First;
3250 return make<NameType>("bool");
3251 // ::= c # char
3252 case 'c':
3253 ++First;
3254 return make<NameType>("char");
3255 // ::= a # signed char
3256 case 'a':
3257 ++First;
3258 return make<NameType>("signed char");
3259 // ::= h # unsigned char
3260 case 'h':
3261 ++First;
3262 return make<NameType>("unsigned char");
3263 // ::= s # short
3264 case 's':
3265 ++First;
3266 return make<NameType>("short");
3267 // ::= t # unsigned short
3268 case 't':
3269 ++First;
3270 return make<NameType>("unsigned short");
3271 // ::= i # int
3272 case 'i':
3273 ++First;
3274 return make<NameType>("int");
3275 // ::= j # unsigned int
3276 case 'j':
3277 ++First;
3278 return make<NameType>("unsigned int");
3279 // ::= l # long
3280 case 'l':
3281 ++First;
3282 return make<NameType>("long");
3283 // ::= m # unsigned long
3284 case 'm':
3285 ++First;
3286 return make<NameType>("unsigned long");
3287 // ::= x # long long, __int64
3288 case 'x':
3289 ++First;
3290 return make<NameType>("long long");
3291 // ::= y # unsigned long long, __int64
3292 case 'y':
3293 ++First;
3294 return make<NameType>("unsigned long long");
3295 // ::= n # __int128
3296 case 'n':
3297 ++First;
3298 return make<NameType>("__int128");
3299 // ::= o # unsigned __int128
3300 case 'o':
3301 ++First;
3302 return make<NameType>("unsigned __int128");
3303 // ::= f # float
3304 case 'f':
3305 ++First;
3306 return make<NameType>("float");
3307 // ::= d # double
3308 case 'd':
3309 ++First;
3310 return make<NameType>("double");
3311 // ::= e # long double, __float80
3312 case 'e':
3313 ++First;
3314 return make<NameType>("long double");
3315 // ::= g # __float128
3316 case 'g':
3317 ++First;
3318 return make<NameType>("__float128");
3319 // ::= z # ellipsis
3320 case 'z':
3321 ++First;
3322 return make<NameType>("...");
3323
3324 // <builtin-type> ::= u <source-name> # vendor extended type
3325 case 'u': {
3326 ++First;
3327 StringView Res = parseBareSourceName();
3328 if (Res.empty())
3329 return nullptr;
3330 return make<NameType>(Res);
3331 }
3332 case 'D':
3333 switch (look(1)) {
3334 // ::= Dd # IEEE 754r decimal floating point (64 bits)
3335 case 'd':
3336 First += 2;
3337 return make<NameType>("decimal64");
3338 // ::= De # IEEE 754r decimal floating point (128 bits)
3339 case 'e':
3340 First += 2;
3341 return make<NameType>("decimal128");
3342 // ::= Df # IEEE 754r decimal floating point (32 bits)
3343 case 'f':
3344 First += 2;
3345 return make<NameType>("decimal32");
3346 // ::= Dh # IEEE 754r half-precision floating point (16 bits)
3347 case 'h':
3348 First += 2;
3349 return make<NameType>("decimal16");
3350 // ::= Di # char32_t
3351 case 'i':
3352 First += 2;
3353 return make<NameType>("char32_t");
3354 // ::= Ds # char16_t
3355 case 's':
3356 First += 2;
3357 return make<NameType>("char16_t");
3358 // ::= Da # auto (in dependent new-expressions)
3359 case 'a':
3360 First += 2;
3361 return make<NameType>("auto");
3362 // ::= Dc # decltype(auto)
3363 case 'c':
3364 First += 2;
3365 return make<NameType>("decltype(auto)");
3366 // ::= Dn # std::nullptr_t (i.e., decltype(nullptr))
3367 case 'n':
3368 First += 2;
3369 return make<NameType>("std::nullptr_t");
3370
3371 // ::= <decltype>
3372 case 't':
3373 case 'T': {
3374 Result = parseDecltype();
3375 break;
3376 }
3377 // extension ::= <vector-type> # <vector-type> starts with Dv
3378 case 'v': {
3379 Result = parseVectorType();
3380 break;
3381 }
3382 // ::= Dp <type> # pack expansion (C++0x)
3383 case 'p': {
3384 First += 2;
3385 Node *Child = parseType();
3386 if (!Child)
3387 return nullptr;
3388 Result = make<ParameterPackExpansion>(Child);
3389 break;
3390 }
3391 // Exception specifier on a function type.
3392 case 'o':
3393 case 'O':
3394 case 'w':
3395 // Transaction safe function type.
3396 case 'x':
3397 Result = parseFunctionType();
3398 break;
3399 }
3400 break;
3401 // ::= <function-type>
3402 case 'F': {
3403 Result = parseFunctionType();
3404 break;
3405 }
3406 // ::= <array-type>
3407 case 'A': {
3408 Result = parseArrayType();
3409 break;
3410 }
3411 // ::= <pointer-to-member-type>
3412 case 'M': {
3413 Result = parsePointerToMemberType();
3414 break;
3415 }
3416 // ::= <template-param>
3417 case 'T': {
3418 // This could be an elaborate type specifier on a <class-enum-type>.
3419 if (look(1) == 's' || look(1) == 'u' || look(1) == 'e') {
3420 Result = parseClassEnumType();
3421 break;
3422 }
3423
3424 Result = parseTemplateParam();
3425 if (Result == nullptr)
3426 return nullptr;
3427
3428 // Result could be either of:
3429 // <type> ::= <template-param>
3430 // <type> ::= <template-template-param> <template-args>
3431 //
3432 // <template-template-param> ::= <template-param>
3433 // ::= <substitution>
3434 //
3435 // If this is followed by some <template-args>, and we're permitted to
3436 // parse them, take the second production.
3437
3438 if (TryToParseTemplateArgs && look() == 'I') {
3439 Node *TA = parseTemplateArgs();
3440 if (TA == nullptr)
3441 return nullptr;
3442 Result = make<NameWithTemplateArgs>(Result, TA);
3443 }
3444 break;
3445 }
3446 // ::= P <type> # pointer
3447 case 'P': {
3448 ++First;
3449 Node *Ptr = parseType();
3450 if (Ptr == nullptr)
3451 return nullptr;
3452 Result = make<PointerType>(Ptr);
3453 break;
3454 }
3455 // ::= R <type> # l-value reference
3456 case 'R': {
3457 ++First;
3458 Node *Ref = parseType();
3459 if (Ref == nullptr)
3460 return nullptr;
Erik Pilkington3a6fed42018-07-27 17:27:40 +00003461 Result = make<ReferenceType>(Ref, ReferenceKind::LValue);
Erik Pilkingtonbb7feae2018-03-19 15:18:23 +00003462 break;
3463 }
3464 // ::= O <type> # r-value reference (C++11)
3465 case 'O': {
3466 ++First;
3467 Node *Ref = parseType();
3468 if (Ref == nullptr)
3469 return nullptr;
Erik Pilkington3a6fed42018-07-27 17:27:40 +00003470 Result = make<ReferenceType>(Ref, ReferenceKind::RValue);
Erik Pilkingtonbb7feae2018-03-19 15:18:23 +00003471 break;
3472 }
3473 // ::= C <type> # complex pair (C99)
3474 case 'C': {
3475 ++First;
3476 Node *P = parseType();
3477 if (P == nullptr)
3478 return nullptr;
3479 Result = make<PostfixQualifiedType>(P, " complex");
3480 break;
3481 }
3482 // ::= G <type> # imaginary (C99)
3483 case 'G': {
3484 ++First;
3485 Node *P = parseType();
3486 if (P == nullptr)
3487 return P;
3488 Result = make<PostfixQualifiedType>(P, " imaginary");
3489 break;
3490 }
3491 // ::= <substitution> # See Compression below
3492 case 'S': {
3493 if (look(1) && look(1) != 't') {
3494 Node *Sub = parseSubstitution();
3495 if (Sub == nullptr)
3496 return nullptr;
3497
3498 // Sub could be either of:
3499 // <type> ::= <substitution>
3500 // <type> ::= <template-template-param> <template-args>
3501 //
3502 // <template-template-param> ::= <template-param>
3503 // ::= <substitution>
3504 //
3505 // If this is followed by some <template-args>, and we're permitted to
3506 // parse them, take the second production.
3507
3508 if (TryToParseTemplateArgs && look() == 'I') {
3509 Node *TA = parseTemplateArgs();
3510 if (TA == nullptr)
3511 return nullptr;
3512 Result = make<NameWithTemplateArgs>(Sub, TA);
3513 break;
3514 }
3515
3516 // If all we parsed was a substitution, don't re-insert into the
3517 // substitution table.
3518 return Sub;
3519 }
3520 LLVM_FALLTHROUGH;
3521 }
3522 // ::= <class-enum-type>
3523 default: {
3524 Result = parseClassEnumType();
3525 break;
3526 }
3527 }
3528
3529 // If we parsed a type, insert it into the substitution table. Note that all
3530 // <builtin-type>s and <substitution>s have already bailed out, because they
3531 // don't get substitutions.
3532 if (Result != nullptr)
3533 Subs.push_back(Result);
3534 return Result;
3535}
3536
3537Node *Db::parsePrefixExpr(StringView Kind) {
3538 Node *E = parseExpr();
3539 if (E == nullptr)
3540 return nullptr;
3541 return make<PrefixExpr>(Kind, E);
3542}
3543
3544Node *Db::parseBinaryExpr(StringView Kind) {
3545 Node *LHS = parseExpr();
3546 if (LHS == nullptr)
3547 return nullptr;
3548 Node *RHS = parseExpr();
3549 if (RHS == nullptr)
3550 return nullptr;
3551 return make<BinaryExpr>(LHS, Kind, RHS);
3552}
3553
3554Node *Db::parseIntegerLiteral(StringView Lit) {
3555 StringView Tmp = parseNumber(true);
3556 if (!Tmp.empty() && consumeIf('E'))
3557 return make<IntegerExpr>(Lit, Tmp);
3558 return nullptr;
3559}
3560
3561// <CV-Qualifiers> ::= [r] [V] [K]
3562Qualifiers Db::parseCVQualifiers() {
3563 Qualifiers CVR = QualNone;
3564 if (consumeIf('r'))
3565 addQualifiers(CVR, QualRestrict);
3566 if (consumeIf('V'))
3567 addQualifiers(CVR, QualVolatile);
3568 if (consumeIf('K'))
3569 addQualifiers(CVR, QualConst);
3570 return CVR;
3571}
3572
3573// <function-param> ::= fp <top-level CV-Qualifiers> _ # L == 0, first parameter
3574// ::= fp <top-level CV-Qualifiers> <parameter-2 non-negative number> _ # L == 0, second and later parameters
3575// ::= fL <L-1 non-negative number> p <top-level CV-Qualifiers> _ # L > 0, first parameter
3576// ::= fL <L-1 non-negative number> p <top-level CV-Qualifiers> <parameter-2 non-negative number> _ # L > 0, second and later parameters
3577Node *Db::parseFunctionParam() {
3578 if (consumeIf("fp")) {
3579 parseCVQualifiers();
3580 StringView Num = parseNumber();
3581 if (!consumeIf('_'))
3582 return nullptr;
3583 return make<FunctionParam>(Num);
3584 }
3585 if (consumeIf("fL")) {
3586 if (parseNumber().empty())
3587 return nullptr;
3588 if (!consumeIf('p'))
3589 return nullptr;
3590 parseCVQualifiers();
3591 StringView Num = parseNumber();
3592 if (!consumeIf('_'))
3593 return nullptr;
3594 return make<FunctionParam>(Num);
3595 }
3596 return nullptr;
3597}
3598
3599// [gs] nw <expression>* _ <type> E # new (expr-list) type
3600// [gs] nw <expression>* _ <type> <initializer> # new (expr-list) type (init)
3601// [gs] na <expression>* _ <type> E # new[] (expr-list) type
3602// [gs] na <expression>* _ <type> <initializer> # new[] (expr-list) type (init)
3603// <initializer> ::= pi <expression>* E # parenthesized initialization
3604Node *Db::parseNewExpr() {
3605 bool Global = consumeIf("gs");
3606 bool IsArray = look(1) == 'a';
3607 if (!consumeIf("nw") && !consumeIf("na"))
3608 return nullptr;
3609 size_t Exprs = Names.size();
3610 while (!consumeIf('_')) {
3611 Node *Ex = parseExpr();
3612 if (Ex == nullptr)
3613 return nullptr;
3614 Names.push_back(Ex);
3615 }
3616 NodeArray ExprList = popTrailingNodeArray(Exprs);
3617 Node *Ty = parseType();
3618 if (Ty == nullptr)
3619 return Ty;
3620 if (consumeIf("pi")) {
3621 size_t InitsBegin = Names.size();
3622 while (!consumeIf('E')) {
3623 Node *Init = parseExpr();
3624 if (Init == nullptr)
3625 return Init;
3626 Names.push_back(Init);
3627 }
3628 NodeArray Inits = popTrailingNodeArray(InitsBegin);
3629 return make<NewExpr>(ExprList, Ty, Inits, Global, IsArray);
3630 } else if (!consumeIf('E'))
3631 return nullptr;
3632 return make<NewExpr>(ExprList, Ty, NodeArray(), Global, IsArray);
3633}
3634
3635// cv <type> <expression> # conversion with one argument
3636// cv <type> _ <expression>* E # conversion with a different number of arguments
3637Node *Db::parseConversionExpr() {
3638 if (!consumeIf("cv"))
3639 return nullptr;
3640 Node *Ty;
3641 {
3642 SwapAndRestore<bool> SaveTemp(TryToParseTemplateArgs, false);
3643 Ty = parseType();
3644 }
3645
3646 if (Ty == nullptr)
3647 return nullptr;
3648
3649 if (consumeIf('_')) {
3650 size_t ExprsBegin = Names.size();
3651 while (!consumeIf('E')) {
3652 Node *E = parseExpr();
3653 if (E == nullptr)
3654 return E;
3655 Names.push_back(E);
3656 }
3657 NodeArray Exprs = popTrailingNodeArray(ExprsBegin);
3658 return make<ConversionExpr>(Ty, Exprs);
3659 }
3660
3661 Node *E[1] = {parseExpr()};
3662 if (E[0] == nullptr)
3663 return nullptr;
3664 return make<ConversionExpr>(Ty, makeNodeArray(E, E + 1));
3665}
3666
3667// <expr-primary> ::= L <type> <value number> E # integer literal
3668// ::= L <type> <value float> E # floating literal
3669// ::= L <string type> E # string literal
3670// ::= L <nullptr type> E # nullptr literal (i.e., "LDnE")
3671// FIXME: ::= L <type> <real-part float> _ <imag-part float> E # complex floating point literal (C 2000)
3672// ::= L <mangled-name> E # external name
3673Node *Db::parseExprPrimary() {
3674 if (!consumeIf('L'))
3675 return nullptr;
3676 switch (look()) {
3677 case 'w':
3678 ++First;
3679 return parseIntegerLiteral("wchar_t");
3680 case 'b':
3681 if (consumeIf("b0E"))
3682 return make<BoolExpr>(0);
3683 if (consumeIf("b1E"))
3684 return make<BoolExpr>(1);
3685 return nullptr;
3686 case 'c':
3687 ++First;
3688 return parseIntegerLiteral("char");
3689 case 'a':
3690 ++First;
3691 return parseIntegerLiteral("signed char");
3692 case 'h':
3693 ++First;
3694 return parseIntegerLiteral("unsigned char");
3695 case 's':
3696 ++First;
3697 return parseIntegerLiteral("short");
3698 case 't':
3699 ++First;
3700 return parseIntegerLiteral("unsigned short");
3701 case 'i':
3702 ++First;
3703 return parseIntegerLiteral("");
3704 case 'j':
3705 ++First;
3706 return parseIntegerLiteral("u");
3707 case 'l':
3708 ++First;
3709 return parseIntegerLiteral("l");
3710 case 'm':
3711 ++First;
3712 return parseIntegerLiteral("ul");
3713 case 'x':
3714 ++First;
3715 return parseIntegerLiteral("ll");
3716 case 'y':
3717 ++First;
3718 return parseIntegerLiteral("ull");
3719 case 'n':
3720 ++First;
3721 return parseIntegerLiteral("__int128");
3722 case 'o':
3723 ++First;
3724 return parseIntegerLiteral("unsigned __int128");
3725 case 'f':
3726 ++First;
3727 return parseFloatingLiteral<float>();
3728 case 'd':
3729 ++First;
3730 return parseFloatingLiteral<double>();
3731 case 'e':
3732 ++First;
3733 return parseFloatingLiteral<long double>();
3734 case '_':
3735 if (consumeIf("_Z")) {
3736 Node *R = parseEncoding();
3737 if (R != nullptr && consumeIf('E'))
3738 return R;
3739 }
3740 return nullptr;
3741 case 'T':
3742 // Invalid mangled name per
3743 // http://sourcerytools.com/pipermail/cxx-abi-dev/2011-August/002422.html
3744 return nullptr;
3745 default: {
3746 // might be named type
3747 Node *T = parseType();
3748 if (T == nullptr)
3749 return nullptr;
3750 StringView N = parseNumber();
3751 if (!N.empty()) {
3752 if (!consumeIf('E'))
3753 return nullptr;
3754 return make<IntegerCastExpr>(T, N);
3755 }
3756 if (consumeIf('E'))
3757 return T;
3758 return nullptr;
3759 }
3760 }
3761}
3762
3763// <braced-expression> ::= <expression>
3764// ::= di <field source-name> <braced-expression> # .name = expr
3765// ::= dx <index expression> <braced-expression> # [expr] = expr
3766// ::= dX <range begin expression> <range end expression> <braced-expression>
3767Node *Db::parseBracedExpr() {
3768 if (look() == 'd') {
3769 switch (look(1)) {
3770 case 'i': {
3771 First += 2;
3772 Node *Field = parseSourceName(/*NameState=*/nullptr);
3773 if (Field == nullptr)
3774 return nullptr;
3775 Node *Init = parseBracedExpr();
3776 if (Init == nullptr)
3777 return nullptr;
3778 return make<BracedExpr>(Field, Init, /*isArray=*/false);
3779 }
3780 case 'x': {
3781 First += 2;
3782 Node *Index = parseExpr();
3783 if (Index == nullptr)
3784 return nullptr;
3785 Node *Init = parseBracedExpr();
3786 if (Init == nullptr)
3787 return nullptr;
3788 return make<BracedExpr>(Index, Init, /*isArray=*/true);
3789 }
3790 case 'X': {
3791 First += 2;
3792 Node *RangeBegin = parseExpr();
3793 if (RangeBegin == nullptr)
3794 return nullptr;
3795 Node *RangeEnd = parseExpr();
3796 if (RangeEnd == nullptr)
3797 return nullptr;
3798 Node *Init = parseBracedExpr();
3799 if (Init == nullptr)
3800 return nullptr;
3801 return make<BracedRangeExpr>(RangeBegin, RangeEnd, Init);
3802 }
Rafael Espindolab940b662016-09-06 19:16:48 +00003803 }
3804 }
Erik Pilkingtonbb7feae2018-03-19 15:18:23 +00003805 return parseExpr();
3806}
3807
Erik Pilkingtond43931d2018-04-09 18:33:01 +00003808// (not yet in the spec)
3809// <fold-expr> ::= fL <binary-operator-name> <expression> <expression>
3810// ::= fR <binary-operator-name> <expression> <expression>
3811// ::= fl <binary-operator-name> <expression>
3812// ::= fr <binary-operator-name> <expression>
3813Node *Db::parseFoldExpr() {
3814 if (!consumeIf('f'))
3815 return nullptr;
3816
3817 char FoldKind = look();
3818 bool IsLeftFold, HasInitializer;
3819 HasInitializer = FoldKind == 'L' || FoldKind == 'R';
3820 if (FoldKind == 'l' || FoldKind == 'L')
3821 IsLeftFold = true;
3822 else if (FoldKind == 'r' || FoldKind == 'R')
3823 IsLeftFold = false;
3824 else
3825 return nullptr;
3826 ++First;
3827
3828 // FIXME: This map is duplicated in parseOperatorName and parseExpr.
3829 StringView OperatorName;
3830 if (consumeIf("aa")) OperatorName = "&&";
3831 else if (consumeIf("an")) OperatorName = "&";
3832 else if (consumeIf("aN")) OperatorName = "&=";
3833 else if (consumeIf("aS")) OperatorName = "=";
3834 else if (consumeIf("cm")) OperatorName = ",";
3835 else if (consumeIf("ds")) OperatorName = ".*";
3836 else if (consumeIf("dv")) OperatorName = "/";
3837 else if (consumeIf("dV")) OperatorName = "/=";
3838 else if (consumeIf("eo")) OperatorName = "^";
3839 else if (consumeIf("eO")) OperatorName = "^=";
3840 else if (consumeIf("eq")) OperatorName = "==";
3841 else if (consumeIf("ge")) OperatorName = ">=";
3842 else if (consumeIf("gt")) OperatorName = ">";
3843 else if (consumeIf("le")) OperatorName = "<=";
3844 else if (consumeIf("ls")) OperatorName = "<<";
3845 else if (consumeIf("lS")) OperatorName = "<<=";
3846 else if (consumeIf("lt")) OperatorName = "<";
3847 else if (consumeIf("mi")) OperatorName = "-";
3848 else if (consumeIf("mI")) OperatorName = "-=";
3849 else if (consumeIf("ml")) OperatorName = "*";
3850 else if (consumeIf("mL")) OperatorName = "*=";
3851 else if (consumeIf("ne")) OperatorName = "!=";
3852 else if (consumeIf("oo")) OperatorName = "||";
3853 else if (consumeIf("or")) OperatorName = "|";
3854 else if (consumeIf("oR")) OperatorName = "|=";
3855 else if (consumeIf("pl")) OperatorName = "+";
3856 else if (consumeIf("pL")) OperatorName = "+=";
3857 else if (consumeIf("rm")) OperatorName = "%";
3858 else if (consumeIf("rM")) OperatorName = "%=";
3859 else if (consumeIf("rs")) OperatorName = ">>";
3860 else if (consumeIf("rS")) OperatorName = ">>=";
3861 else return nullptr;
3862
3863 Node *Pack = parseExpr(), *Init = nullptr;
3864 if (Pack == nullptr)
3865 return nullptr;
3866 if (HasInitializer) {
3867 Init = parseExpr();
3868 if (Init == nullptr)
3869 return nullptr;
3870 }
3871
3872 if (IsLeftFold && Init)
3873 std::swap(Pack, Init);
3874
3875 return make<FoldExpr>(IsLeftFold, OperatorName, Pack, Init);
3876}
3877
Erik Pilkingtonbb7feae2018-03-19 15:18:23 +00003878// <expression> ::= <unary operator-name> <expression>
3879// ::= <binary operator-name> <expression> <expression>
3880// ::= <ternary operator-name> <expression> <expression> <expression>
3881// ::= cl <expression>+ E # call
3882// ::= cv <type> <expression> # conversion with one argument
3883// ::= cv <type> _ <expression>* E # conversion with a different number of arguments
3884// ::= [gs] nw <expression>* _ <type> E # new (expr-list) type
3885// ::= [gs] nw <expression>* _ <type> <initializer> # new (expr-list) type (init)
3886// ::= [gs] na <expression>* _ <type> E # new[] (expr-list) type
3887// ::= [gs] na <expression>* _ <type> <initializer> # new[] (expr-list) type (init)
3888// ::= [gs] dl <expression> # delete expression
3889// ::= [gs] da <expression> # delete[] expression
3890// ::= pp_ <expression> # prefix ++
3891// ::= mm_ <expression> # prefix --
3892// ::= ti <type> # typeid (type)
3893// ::= te <expression> # typeid (expression)
3894// ::= dc <type> <expression> # dynamic_cast<type> (expression)
3895// ::= sc <type> <expression> # static_cast<type> (expression)
3896// ::= cc <type> <expression> # const_cast<type> (expression)
3897// ::= rc <type> <expression> # reinterpret_cast<type> (expression)
3898// ::= st <type> # sizeof (a type)
3899// ::= sz <expression> # sizeof (an expression)
3900// ::= at <type> # alignof (a type)
3901// ::= az <expression> # alignof (an expression)
3902// ::= nx <expression> # noexcept (expression)
3903// ::= <template-param>
3904// ::= <function-param>
3905// ::= dt <expression> <unresolved-name> # expr.name
3906// ::= pt <expression> <unresolved-name> # expr->name
3907// ::= ds <expression> <expression> # expr.*expr
3908// ::= sZ <template-param> # size of a parameter pack
3909// ::= sZ <function-param> # size of a function parameter pack
Erik Pilkington650130a2018-04-09 18:31:50 +00003910// ::= sP <template-arg>* E # sizeof...(T), size of a captured template parameter pack from an alias template
Erik Pilkingtonbb7feae2018-03-19 15:18:23 +00003911// ::= sp <expression> # pack expansion
3912// ::= tw <expression> # throw expression
3913// ::= tr # throw with no operand (rethrow)
3914// ::= <unresolved-name> # f(p), N::f(p), ::f(p),
3915// # freestanding dependent name (e.g., T::x),
3916// # objectless nonstatic member reference
3917// ::= fL <binary-operator-name> <expression> <expression>
3918// ::= fR <binary-operator-name> <expression> <expression>
3919// ::= fl <binary-operator-name> <expression>
3920// ::= fr <binary-operator-name> <expression>
3921// ::= <expr-primary>
3922Node *Db::parseExpr() {
3923 bool Global = consumeIf("gs");
3924 if (numLeft() < 2)
3925 return nullptr;
3926
3927 switch (*First) {
3928 case 'L':
3929 return parseExprPrimary();
3930 case 'T':
3931 return parseTemplateParam();
Erik Pilkingtond43931d2018-04-09 18:33:01 +00003932 case 'f': {
3933 // Disambiguate a fold expression from a <function-param>.
3934 if (look(1) == 'p' || (look(1) == 'L' && std::isdigit(look(2))))
3935 return parseFunctionParam();
3936 return parseFoldExpr();
3937 }
Erik Pilkingtonbb7feae2018-03-19 15:18:23 +00003938 case 'a':
3939 switch (First[1]) {
3940 case 'a':
3941 First += 2;
3942 return parseBinaryExpr("&&");
3943 case 'd':
3944 First += 2;
3945 return parsePrefixExpr("&");
3946 case 'n':
3947 First += 2;
3948 return parseBinaryExpr("&");
3949 case 'N':
3950 First += 2;
3951 return parseBinaryExpr("&=");
3952 case 'S':
3953 First += 2;
3954 return parseBinaryExpr("=");
3955 case 't': {
3956 First += 2;
3957 Node *Ty = parseType();
3958 if (Ty == nullptr)
3959 return nullptr;
3960 return make<EnclosingExpr>("alignof (", Ty, ")");
3961 }
3962 case 'z': {
3963 First += 2;
3964 Node *Ty = parseExpr();
3965 if (Ty == nullptr)
3966 return nullptr;
3967 return make<EnclosingExpr>("alignof (", Ty, ")");
3968 }
3969 }
3970 return nullptr;
3971 case 'c':
3972 switch (First[1]) {
3973 // cc <type> <expression> # const_cast<type>(expression)
3974 case 'c': {
3975 First += 2;
3976 Node *Ty = parseType();
3977 if (Ty == nullptr)
3978 return Ty;
3979 Node *Ex = parseExpr();
3980 if (Ex == nullptr)
3981 return Ex;
3982 return make<CastExpr>("const_cast", Ty, Ex);
3983 }
3984 // cl <expression>+ E # call
3985 case 'l': {
3986 First += 2;
3987 Node *Callee = parseExpr();
3988 if (Callee == nullptr)
3989 return Callee;
3990 size_t ExprsBegin = Names.size();
3991 while (!consumeIf('E')) {
3992 Node *E = parseExpr();
3993 if (E == nullptr)
3994 return E;
3995 Names.push_back(E);
3996 }
3997 return make<CallExpr>(Callee, popTrailingNodeArray(ExprsBegin));
3998 }
3999 case 'm':
4000 First += 2;
4001 return parseBinaryExpr(",");
4002 case 'o':
4003 First += 2;
4004 return parsePrefixExpr("~");
4005 case 'v':
4006 return parseConversionExpr();
4007 }
4008 return nullptr;
4009 case 'd':
4010 switch (First[1]) {
4011 case 'a': {
4012 First += 2;
4013 Node *Ex = parseExpr();
4014 if (Ex == nullptr)
4015 return Ex;
4016 return make<DeleteExpr>(Ex, Global, /*is_array=*/true);
4017 }
4018 case 'c': {
4019 First += 2;
4020 Node *T = parseType();
4021 if (T == nullptr)
4022 return T;
4023 Node *Ex = parseExpr();
4024 if (Ex == nullptr)
4025 return Ex;
4026 return make<CastExpr>("dynamic_cast", T, Ex);
4027 }
4028 case 'e':
4029 First += 2;
4030 return parsePrefixExpr("*");
4031 case 'l': {
4032 First += 2;
4033 Node *E = parseExpr();
4034 if (E == nullptr)
4035 return E;
4036 return make<DeleteExpr>(E, Global, /*is_array=*/false);
4037 }
4038 case 'n':
4039 return parseUnresolvedName();
4040 case 's': {
4041 First += 2;
4042 Node *LHS = parseExpr();
4043 if (LHS == nullptr)
4044 return nullptr;
4045 Node *RHS = parseExpr();
4046 if (RHS == nullptr)
4047 return nullptr;
4048 return make<MemberExpr>(LHS, ".*", RHS);
4049 }
4050 case 't': {
4051 First += 2;
4052 Node *LHS = parseExpr();
4053 if (LHS == nullptr)
4054 return LHS;
4055 Node *RHS = parseExpr();
4056 if (RHS == nullptr)
4057 return nullptr;
4058 return make<MemberExpr>(LHS, ".", RHS);
4059 }
4060 case 'v':
4061 First += 2;
4062 return parseBinaryExpr("/");
4063 case 'V':
4064 First += 2;
4065 return parseBinaryExpr("/=");
4066 }
4067 return nullptr;
4068 case 'e':
4069 switch (First[1]) {
4070 case 'o':
4071 First += 2;
4072 return parseBinaryExpr("^");
4073 case 'O':
4074 First += 2;
4075 return parseBinaryExpr("^=");
4076 case 'q':
4077 First += 2;
4078 return parseBinaryExpr("==");
4079 }
4080 return nullptr;
4081 case 'g':
4082 switch (First[1]) {
4083 case 'e':
4084 First += 2;
4085 return parseBinaryExpr(">=");
4086 case 't':
4087 First += 2;
4088 return parseBinaryExpr(">");
4089 }
4090 return nullptr;
4091 case 'i':
4092 switch (First[1]) {
4093 case 'x': {
4094 First += 2;
4095 Node *Base = parseExpr();
4096 if (Base == nullptr)
4097 return nullptr;
4098 Node *Index = parseExpr();
4099 if (Index == nullptr)
4100 return Index;
4101 return make<ArraySubscriptExpr>(Base, Index);
4102 }
4103 case 'l': {
4104 First += 2;
4105 size_t InitsBegin = Names.size();
4106 while (!consumeIf('E')) {
4107 Node *E = parseBracedExpr();
4108 if (E == nullptr)
4109 return nullptr;
4110 Names.push_back(E);
4111 }
4112 return make<InitListExpr>(nullptr, popTrailingNodeArray(InitsBegin));
4113 }
4114 }
4115 return nullptr;
4116 case 'l':
4117 switch (First[1]) {
4118 case 'e':
4119 First += 2;
4120 return parseBinaryExpr("<=");
4121 case 's':
4122 First += 2;
4123 return parseBinaryExpr("<<");
4124 case 'S':
4125 First += 2;
4126 return parseBinaryExpr("<<=");
4127 case 't':
4128 First += 2;
4129 return parseBinaryExpr("<");
4130 }
4131 return nullptr;
4132 case 'm':
4133 switch (First[1]) {
4134 case 'i':
4135 First += 2;
4136 return parseBinaryExpr("-");
4137 case 'I':
4138 First += 2;
4139 return parseBinaryExpr("-=");
4140 case 'l':
4141 First += 2;
4142 return parseBinaryExpr("*");
4143 case 'L':
4144 First += 2;
4145 return parseBinaryExpr("*=");
4146 case 'm':
4147 First += 2;
4148 if (consumeIf('_'))
4149 return parsePrefixExpr("--");
4150 Node *Ex = parseExpr();
4151 if (Ex == nullptr)
4152 return nullptr;
4153 return make<PostfixExpr>(Ex, "--");
4154 }
4155 return nullptr;
4156 case 'n':
4157 switch (First[1]) {
4158 case 'a':
4159 case 'w':
4160 return parseNewExpr();
4161 case 'e':
4162 First += 2;
4163 return parseBinaryExpr("!=");
4164 case 'g':
4165 First += 2;
4166 return parsePrefixExpr("-");
4167 case 't':
4168 First += 2;
4169 return parsePrefixExpr("!");
4170 case 'x':
4171 First += 2;
4172 Node *Ex = parseExpr();
4173 if (Ex == nullptr)
4174 return Ex;
4175 return make<EnclosingExpr>("noexcept (", Ex, ")");
4176 }
4177 return nullptr;
4178 case 'o':
4179 switch (First[1]) {
4180 case 'n':
4181 return parseUnresolvedName();
4182 case 'o':
4183 First += 2;
4184 return parseBinaryExpr("||");
4185 case 'r':
4186 First += 2;
4187 return parseBinaryExpr("|");
4188 case 'R':
4189 First += 2;
4190 return parseBinaryExpr("|=");
4191 }
4192 return nullptr;
4193 case 'p':
4194 switch (First[1]) {
4195 case 'm':
4196 First += 2;
4197 return parseBinaryExpr("->*");
4198 case 'l':
4199 First += 2;
4200 return parseBinaryExpr("+");
4201 case 'L':
4202 First += 2;
4203 return parseBinaryExpr("+=");
4204 case 'p': {
4205 First += 2;
4206 if (consumeIf('_'))
4207 return parsePrefixExpr("++");
4208 Node *Ex = parseExpr();
4209 if (Ex == nullptr)
4210 return Ex;
4211 return make<PostfixExpr>(Ex, "++");
4212 }
4213 case 's':
4214 First += 2;
4215 return parsePrefixExpr("+");
4216 case 't': {
4217 First += 2;
4218 Node *L = parseExpr();
4219 if (L == nullptr)
4220 return nullptr;
4221 Node *R = parseExpr();
4222 if (R == nullptr)
4223 return nullptr;
4224 return make<MemberExpr>(L, "->", R);
4225 }
4226 }
4227 return nullptr;
4228 case 'q':
4229 if (First[1] == 'u') {
4230 First += 2;
4231 Node *Cond = parseExpr();
4232 if (Cond == nullptr)
4233 return nullptr;
4234 Node *LHS = parseExpr();
4235 if (LHS == nullptr)
4236 return nullptr;
4237 Node *RHS = parseExpr();
4238 if (RHS == nullptr)
4239 return nullptr;
4240 return make<ConditionalExpr>(Cond, LHS, RHS);
4241 }
4242 return nullptr;
4243 case 'r':
4244 switch (First[1]) {
4245 case 'c': {
4246 First += 2;
4247 Node *T = parseType();
4248 if (T == nullptr)
4249 return T;
4250 Node *Ex = parseExpr();
4251 if (Ex == nullptr)
4252 return Ex;
4253 return make<CastExpr>("reinterpret_cast", T, Ex);
4254 }
4255 case 'm':
4256 First += 2;
4257 return parseBinaryExpr("%");
4258 case 'M':
4259 First += 2;
4260 return parseBinaryExpr("%=");
4261 case 's':
4262 First += 2;
4263 return parseBinaryExpr(">>");
4264 case 'S':
4265 First += 2;
4266 return parseBinaryExpr(">>=");
4267 }
4268 return nullptr;
4269 case 's':
4270 switch (First[1]) {
4271 case 'c': {
4272 First += 2;
4273 Node *T = parseType();
4274 if (T == nullptr)
4275 return T;
4276 Node *Ex = parseExpr();
4277 if (Ex == nullptr)
4278 return Ex;
4279 return make<CastExpr>("static_cast", T, Ex);
4280 }
4281 case 'p': {
4282 First += 2;
4283 Node *Child = parseExpr();
4284 if (Child == nullptr)
4285 return nullptr;
4286 return make<ParameterPackExpansion>(Child);
4287 }
4288 case 'r':
4289 return parseUnresolvedName();
4290 case 't': {
4291 First += 2;
4292 Node *Ty = parseType();
4293 if (Ty == nullptr)
4294 return Ty;
4295 return make<EnclosingExpr>("sizeof (", Ty, ")");
4296 }
4297 case 'z': {
4298 First += 2;
4299 Node *Ex = parseExpr();
4300 if (Ex == nullptr)
4301 return Ex;
4302 return make<EnclosingExpr>("sizeof (", Ex, ")");
4303 }
4304 case 'Z':
4305 First += 2;
4306 if (look() == 'T') {
4307 Node *R = parseTemplateParam();
4308 if (R == nullptr)
4309 return nullptr;
4310 return make<SizeofParamPackExpr>(R);
4311 } else if (look() == 'f') {
4312 Node *FP = parseFunctionParam();
4313 if (FP == nullptr)
4314 return nullptr;
Erik Pilkington650130a2018-04-09 18:31:50 +00004315 return make<EnclosingExpr>("sizeof... (", FP, ")");
Erik Pilkingtonbb7feae2018-03-19 15:18:23 +00004316 }
4317 return nullptr;
Erik Pilkington650130a2018-04-09 18:31:50 +00004318 case 'P': {
4319 First += 2;
4320 size_t ArgsBegin = Names.size();
4321 while (!consumeIf('E')) {
4322 Node *Arg = parseTemplateArg();
4323 if (Arg == nullptr)
4324 return nullptr;
4325 Names.push_back(Arg);
4326 }
4327 return make<EnclosingExpr>(
4328 "sizeof... (", make<NodeArrayNode>(popTrailingNodeArray(ArgsBegin)),
4329 ")");
4330 }
Erik Pilkingtonbb7feae2018-03-19 15:18:23 +00004331 }
4332 return nullptr;
4333 case 't':
4334 switch (First[1]) {
4335 case 'e': {
4336 First += 2;
4337 Node *Ex = parseExpr();
4338 if (Ex == nullptr)
4339 return Ex;
4340 return make<EnclosingExpr>("typeid (", Ex, ")");
4341 }
4342 case 'i': {
4343 First += 2;
4344 Node *Ty = parseType();
4345 if (Ty == nullptr)
4346 return Ty;
4347 return make<EnclosingExpr>("typeid (", Ty, ")");
4348 }
4349 case 'l': {
4350 First += 2;
4351 Node *Ty = parseType();
4352 if (Ty == nullptr)
4353 return nullptr;
4354 size_t InitsBegin = Names.size();
4355 while (!consumeIf('E')) {
4356 Node *E = parseBracedExpr();
4357 if (E == nullptr)
4358 return nullptr;
4359 Names.push_back(E);
4360 }
4361 return make<InitListExpr>(Ty, popTrailingNodeArray(InitsBegin));
4362 }
4363 case 'r':
4364 First += 2;
4365 return make<NameType>("throw");
4366 case 'w': {
4367 First += 2;
4368 Node *Ex = parseExpr();
4369 if (Ex == nullptr)
4370 return nullptr;
4371 return make<ThrowExpr>(Ex);
4372 }
4373 }
4374 return nullptr;
4375 case '1':
4376 case '2':
4377 case '3':
4378 case '4':
4379 case '5':
4380 case '6':
4381 case '7':
4382 case '8':
4383 case '9':
4384 return parseUnresolvedName();
4385 }
4386 return nullptr;
Rafael Espindolab940b662016-09-06 19:16:48 +00004387}
4388
4389// <call-offset> ::= h <nv-offset> _
4390// ::= v <v-offset> _
4391//
4392// <nv-offset> ::= <offset number>
4393// # non-virtual base override
4394//
4395// <v-offset> ::= <offset number> _ <virtual offset number>
4396// # virtual base override, with vcall offset
Erik Pilkingtonbb7feae2018-03-19 15:18:23 +00004397bool Db::parseCallOffset() {
4398 // Just scan through the call offset, we never add this information into the
4399 // output.
4400 if (consumeIf('h'))
4401 return parseNumber(true).empty() || !consumeIf('_');
4402 if (consumeIf('v'))
4403 return parseNumber(true).empty() || !consumeIf('_') ||
4404 parseNumber(true).empty() || !consumeIf('_');
4405 return true;
Rafael Espindolab940b662016-09-06 19:16:48 +00004406}
4407
4408// <special-name> ::= TV <type> # virtual table
4409// ::= TT <type> # VTT structure (construction vtable index)
4410// ::= TI <type> # typeinfo structure
4411// ::= TS <type> # typeinfo name (null-terminated byte string)
4412// ::= Tc <call-offset> <call-offset> <base encoding>
4413// # base is the nominal target function of thunk
4414// # first call-offset is 'this' adjustment
4415// # second call-offset is result adjustment
4416// ::= T <call-offset> <base encoding>
4417// # base is the nominal target function of thunk
Erik Pilkingtonbb7feae2018-03-19 15:18:23 +00004418// ::= GV <object name> # Guard variable for one-time initialization
Rafael Espindolab940b662016-09-06 19:16:48 +00004419// # No <type>
David Bozier60b80d22017-01-31 15:56:36 +00004420// ::= TW <object name> # Thread-local wrapper
4421// ::= TH <object name> # Thread-local initialization
Erik Pilkingtonbb7feae2018-03-19 15:18:23 +00004422// ::= GR <object name> _ # First temporary
4423// ::= GR <object name> <seq-id> _ # Subsequent temporaries
4424// extension ::= TC <first type> <number> _ <second type> # construction vtable for second-in-first
Rafael Espindolab940b662016-09-06 19:16:48 +00004425// extension ::= GR <object name> # reference temporary for object
Erik Pilkingtonbb7feae2018-03-19 15:18:23 +00004426Node *Db::parseSpecialName() {
4427 switch (look()) {
4428 case 'T':
4429 switch (look(1)) {
4430 // TV <type> # virtual table
4431 case 'V': {
4432 First += 2;
4433 Node *Ty = parseType();
4434 if (Ty == nullptr)
4435 return nullptr;
4436 return make<SpecialName>("vtable for ", Ty);
4437 }
4438 // TT <type> # VTT structure (construction vtable index)
4439 case 'T': {
4440 First += 2;
4441 Node *Ty = parseType();
4442 if (Ty == nullptr)
4443 return nullptr;
4444 return make<SpecialName>("VTT for ", Ty);
4445 }
4446 // TI <type> # typeinfo structure
4447 case 'I': {
4448 First += 2;
4449 Node *Ty = parseType();
4450 if (Ty == nullptr)
4451 return nullptr;
4452 return make<SpecialName>("typeinfo for ", Ty);
4453 }
4454 // TS <type> # typeinfo name (null-terminated byte string)
4455 case 'S': {
4456 First += 2;
4457 Node *Ty = parseType();
4458 if (Ty == nullptr)
4459 return nullptr;
4460 return make<SpecialName>("typeinfo name for ", Ty);
4461 }
4462 // Tc <call-offset> <call-offset> <base encoding>
4463 case 'c': {
4464 First += 2;
4465 if (parseCallOffset() || parseCallOffset())
4466 return nullptr;
4467 Node *Encoding = parseEncoding();
4468 if (Encoding == nullptr)
4469 return nullptr;
4470 return make<SpecialName>("covariant return thunk to ", Encoding);
4471 }
4472 // extension ::= TC <first type> <number> _ <second type>
4473 // # construction vtable for second-in-first
4474 case 'C': {
4475 First += 2;
4476 Node *FirstType = parseType();
4477 if (FirstType == nullptr)
4478 return nullptr;
4479 if (parseNumber(true).empty() || !consumeIf('_'))
4480 return nullptr;
4481 Node *SecondType = parseType();
4482 if (SecondType == nullptr)
4483 return nullptr;
4484 return make<CtorVtableSpecialName>(SecondType, FirstType);
4485 }
4486 // TW <object name> # Thread-local wrapper
4487 case 'W': {
4488 First += 2;
4489 Node *Name = parseName();
4490 if (Name == nullptr)
4491 return nullptr;
4492 return make<SpecialName>("thread-local wrapper routine for ", Name);
4493 }
4494 // TH <object name> # Thread-local initialization
4495 case 'H': {
4496 First += 2;
4497 Node *Name = parseName();
4498 if (Name == nullptr)
4499 return nullptr;
4500 return make<SpecialName>("thread-local initialization routine for ", Name);
4501 }
4502 // T <call-offset> <base encoding>
4503 default: {
4504 ++First;
4505 bool IsVirt = look() == 'v';
4506 if (parseCallOffset())
4507 return nullptr;
4508 Node *BaseEncoding = parseEncoding();
4509 if (BaseEncoding == nullptr)
4510 return nullptr;
4511 if (IsVirt)
4512 return make<SpecialName>("virtual thunk to ", BaseEncoding);
4513 else
4514 return make<SpecialName>("non-virtual thunk to ", BaseEncoding);
4515 }
4516 }
4517 case 'G':
4518 switch (look(1)) {
4519 // GV <object name> # Guard variable for one-time initialization
4520 case 'V': {
4521 First += 2;
4522 Node *Name = parseName();
4523 if (Name == nullptr)
4524 return nullptr;
4525 return make<SpecialName>("guard variable for ", Name);
4526 }
4527 // GR <object name> # reference temporary for object
4528 // GR <object name> _ # First temporary
4529 // GR <object name> <seq-id> _ # Subsequent temporaries
4530 case 'R': {
4531 First += 2;
4532 Node *Name = parseName();
4533 if (Name == nullptr)
4534 return nullptr;
4535 size_t Count;
4536 bool ParsedSeqId = !parseSeqId(&Count);
4537 if (!consumeIf('_') && ParsedSeqId)
4538 return nullptr;
4539 return make<SpecialName>("reference temporary for ", Name);
4540 }
Rafael Espindolab940b662016-09-06 19:16:48 +00004541 }
4542 }
Erik Pilkingtonbb7feae2018-03-19 15:18:23 +00004543 return nullptr;
Rafael Espindolab940b662016-09-06 19:16:48 +00004544}
4545
4546// <encoding> ::= <function name> <bare-function-type>
4547// ::= <data name>
4548// ::= <special-name>
Erik Pilkingtonbb7feae2018-03-19 15:18:23 +00004549Node *Db::parseEncoding() {
Erik Pilkingtonbb7feae2018-03-19 15:18:23 +00004550 if (look() == 'G' || look() == 'T')
4551 return parseSpecialName();
4552
4553 auto IsEndOfEncoding = [&] {
4554 // The set of chars that can potentially follow an <encoding> (none of which
4555 // can start a <type>). Enumerating these allows us to avoid speculative
4556 // parsing.
4557 return numLeft() == 0 || look() == 'E' || look() == '.' || look() == '_';
4558 };
4559
Erik Pilkington8a1cb332018-03-25 22:50:33 +00004560 NameState NameInfo(this);
Erik Pilkingtonbb7feae2018-03-19 15:18:23 +00004561 Node *Name = parseName(&NameInfo);
Erik Pilkington8a1cb332018-03-25 22:50:33 +00004562 if (Name == nullptr)
4563 return nullptr;
Erik Pilkingtonbb7feae2018-03-19 15:18:23 +00004564
Erik Pilkington8a1cb332018-03-25 22:50:33 +00004565 if (resolveForwardTemplateRefs(NameInfo))
4566 return nullptr;
4567
4568 if (IsEndOfEncoding())
4569 return Name;
Erik Pilkingtonbb7feae2018-03-19 15:18:23 +00004570
Erik Pilkingtonc7287862018-03-25 22:49:16 +00004571 Node *Attrs = nullptr;
4572 if (consumeIf("Ua9enable_ifI")) {
4573 size_t BeforeArgs = Names.size();
4574 while (!consumeIf('E')) {
4575 Node *Arg = parseTemplateArg();
4576 if (Arg == nullptr)
4577 return nullptr;
4578 Names.push_back(Arg);
4579 }
4580 Attrs = make<EnableIfAttr>(popTrailingNodeArray(BeforeArgs));
4581 }
4582
Erik Pilkingtonbb7feae2018-03-19 15:18:23 +00004583 Node *ReturnType = nullptr;
4584 if (!NameInfo.CtorDtorConversion && NameInfo.EndsWithTemplateArgs) {
4585 ReturnType = parseType();
4586 if (ReturnType == nullptr)
4587 return nullptr;
4588 }
4589
4590 if (consumeIf('v'))
4591 return make<FunctionEncoding>(ReturnType, Name, NodeArray(),
Erik Pilkingtonc7287862018-03-25 22:49:16 +00004592 Attrs, NameInfo.CVQualifiers,
Erik Pilkingtonbb7feae2018-03-19 15:18:23 +00004593 NameInfo.ReferenceQualifier);
4594
4595 size_t ParamsBegin = Names.size();
4596 do {
4597 Node *Ty = parseType();
4598 if (Ty == nullptr)
4599 return nullptr;
4600 Names.push_back(Ty);
4601 } while (!IsEndOfEncoding());
4602
4603 return make<FunctionEncoding>(ReturnType, Name,
4604 popTrailingNodeArray(ParamsBegin),
Erik Pilkingtonc7287862018-03-25 22:49:16 +00004605 Attrs, NameInfo.CVQualifiers,
Erik Pilkingtonbb7feae2018-03-19 15:18:23 +00004606 NameInfo.ReferenceQualifier);
4607}
4608
4609template <class Float>
4610struct FloatData;
4611
4612template <>
4613struct FloatData<float>
4614{
4615 static const size_t mangled_size = 8;
4616 static const size_t max_demangled_size = 24;
4617 static constexpr const char* spec = "%af";
4618};
4619
4620constexpr const char* FloatData<float>::spec;
4621
4622template <>
4623struct FloatData<double>
4624{
4625 static const size_t mangled_size = 16;
4626 static const size_t max_demangled_size = 32;
4627 static constexpr const char* spec = "%a";
4628};
4629
4630constexpr const char* FloatData<double>::spec;
4631
4632template <>
4633struct FloatData<long double>
4634{
4635#if defined(__mips__) && defined(__mips_n64) || defined(__aarch64__) || \
4636 defined(__wasm__)
4637 static const size_t mangled_size = 32;
4638#elif defined(__arm__) || defined(__mips__) || defined(__hexagon__)
4639 static const size_t mangled_size = 16;
4640#else
4641 static const size_t mangled_size = 20; // May need to be adjusted to 16 or 24 on other platforms
4642#endif
4643 static const size_t max_demangled_size = 40;
4644 static constexpr const char *spec = "%LaL";
4645};
4646
4647constexpr const char *FloatData<long double>::spec;
4648
4649template <class Float> Node *Db::parseFloatingLiteral() {
4650 const size_t N = FloatData<Float>::mangled_size;
4651 if (numLeft() <= N)
4652 return nullptr;
4653 StringView Data(First, First + N);
4654 for (char C : Data)
4655 if (!std::isxdigit(C))
4656 return nullptr;
4657 First += N;
4658 if (!consumeIf('E'))
4659 return nullptr;
4660 return make<FloatExpr<Float>>(Data);
4661}
4662
4663// <seq-id> ::= <0-9A-Z>+
4664bool Db::parseSeqId(size_t *Out) {
4665 if (!(look() >= '0' && look() <= '9') &&
4666 !(look() >= 'A' && look() <= 'Z'))
4667 return true;
4668
4669 size_t Id = 0;
4670 while (true) {
4671 if (look() >= '0' && look() <= '9') {
4672 Id *= 36;
4673 Id += static_cast<size_t>(look() - '0');
4674 } else if (look() >= 'A' && look() <= 'Z') {
4675 Id *= 36;
4676 Id += static_cast<size_t>(look() - 'A') + 10;
4677 } else {
4678 *Out = Id;
4679 return false;
4680 }
4681 ++First;
4682 }
4683}
4684
4685// <substitution> ::= S <seq-id> _
4686// ::= S_
4687// <substitution> ::= Sa # ::std::allocator
4688// <substitution> ::= Sb # ::std::basic_string
4689// <substitution> ::= Ss # ::std::basic_string < char,
4690// ::std::char_traits<char>,
4691// ::std::allocator<char> >
4692// <substitution> ::= Si # ::std::basic_istream<char, std::char_traits<char> >
4693// <substitution> ::= So # ::std::basic_ostream<char, std::char_traits<char> >
4694// <substitution> ::= Sd # ::std::basic_iostream<char, std::char_traits<char> >
4695Node *Db::parseSubstitution() {
4696 if (!consumeIf('S'))
4697 return nullptr;
4698
4699 if (std::islower(look())) {
4700 Node *SpecialSub;
4701 switch (look()) {
4702 case 'a':
4703 ++First;
4704 SpecialSub = make<SpecialSubstitution>(SpecialSubKind::allocator);
Rafael Espindolab940b662016-09-06 19:16:48 +00004705 break;
Erik Pilkingtonbb7feae2018-03-19 15:18:23 +00004706 case 'b':
4707 ++First;
4708 SpecialSub = make<SpecialSubstitution>(SpecialSubKind::basic_string);
4709 break;
4710 case 's':
4711 ++First;
4712 SpecialSub = make<SpecialSubstitution>(SpecialSubKind::string);
4713 break;
4714 case 'i':
4715 ++First;
4716 SpecialSub = make<SpecialSubstitution>(SpecialSubKind::istream);
4717 break;
4718 case 'o':
4719 ++First;
4720 SpecialSub = make<SpecialSubstitution>(SpecialSubKind::ostream);
4721 break;
4722 case 'd':
4723 ++First;
4724 SpecialSub = make<SpecialSubstitution>(SpecialSubKind::iostream);
4725 break;
4726 default:
4727 return nullptr;
4728 }
4729 // Itanium C++ ABI 5.1.2: If a name that would use a built-in <substitution>
4730 // has ABI tags, the tags are appended to the substitution; the result is a
4731 // substitutable component.
4732 Node *WithTags = parseAbiTags(SpecialSub);
4733 if (WithTags != SpecialSub) {
4734 Subs.push_back(WithTags);
4735 SpecialSub = WithTags;
4736 }
4737 return SpecialSub;
4738 }
Rafael Espindolab940b662016-09-06 19:16:48 +00004739
Erik Pilkingtonbb7feae2018-03-19 15:18:23 +00004740 // ::= S_
4741 if (consumeIf('_')) {
4742 if (Subs.empty())
4743 return nullptr;
4744 return Subs[0];
4745 }
4746
4747 // ::= S <seq-id> _
4748 size_t Index = 0;
4749 if (parseSeqId(&Index))
4750 return nullptr;
4751 ++Index;
4752 if (!consumeIf('_') || Index >= Subs.size())
4753 return nullptr;
4754 return Subs[Index];
4755}
4756
4757// <template-param> ::= T_ # first template parameter
4758// ::= T <parameter-2 non-negative number> _
4759Node *Db::parseTemplateParam() {
4760 if (!consumeIf('T'))
4761 return nullptr;
4762
4763 size_t Index = 0;
4764 if (!consumeIf('_')) {
4765 if (parsePositiveInteger(&Index))
4766 return nullptr;
4767 ++Index;
4768 if (!consumeIf('_'))
4769 return nullptr;
4770 }
4771
4772 // Itanium ABI 5.1.8: In a generic lambda, uses of auto in the parameter list
4773 // are mangled as the corresponding artificial template type parameter.
4774 if (ParsingLambdaParams)
4775 return make<NameType>("auto");
4776
Erik Pilkington8a1cb332018-03-25 22:50:33 +00004777 // If we're in a context where this <template-param> refers to a
4778 // <template-arg> further ahead in the mangled name (currently just conversion
4779 // operator types), then we should only look it up in the right context.
4780 if (PermitForwardTemplateReferences) {
4781 ForwardTemplateRefs.push_back(make<ForwardTemplateReference>(Index));
4782 return ForwardTemplateRefs.back();
Erik Pilkingtonbb7feae2018-03-19 15:18:23 +00004783 }
Erik Pilkington8a1cb332018-03-25 22:50:33 +00004784
4785 if (Index >= TemplateParams.size())
4786 return nullptr;
Erik Pilkingtonbb7feae2018-03-19 15:18:23 +00004787 return TemplateParams[Index];
4788}
4789
4790// <template-arg> ::= <type> # type or template
4791// ::= X <expression> E # expression
4792// ::= <expr-primary> # simple expressions
4793// ::= J <template-arg>* E # argument pack
4794// ::= LZ <encoding> E # extension
4795Node *Db::parseTemplateArg() {
4796 switch (look()) {
4797 case 'X': {
4798 ++First;
4799 Node *Arg = parseExpr();
4800 if (Arg == nullptr || !consumeIf('E'))
4801 return nullptr;
4802 return Arg;
4803 }
4804 case 'J': {
4805 ++First;
4806 size_t ArgsBegin = Names.size();
4807 while (!consumeIf('E')) {
4808 Node *Arg = parseTemplateArg();
4809 if (Arg == nullptr)
4810 return nullptr;
4811 Names.push_back(Arg);
4812 }
4813 NodeArray Args = popTrailingNodeArray(ArgsBegin);
4814 return make<TemplateArgumentPack>(Args);
4815 }
4816 case 'L': {
4817 // ::= LZ <encoding> E # extension
4818 if (look(1) == 'Z') {
4819 First += 2;
4820 Node *Arg = parseEncoding();
4821 if (Arg == nullptr || !consumeIf('E'))
4822 return nullptr;
4823 return Arg;
4824 }
4825 // ::= <expr-primary> # simple expressions
4826 return parseExprPrimary();
4827 }
4828 default:
4829 return parseType();
4830 }
4831}
4832
4833// <template-args> ::= I <template-arg>* E
4834// extension, the abi says <template-arg>+
Erik Pilkington8a1cb332018-03-25 22:50:33 +00004835Node *Db::parseTemplateArgs(bool TagTemplates) {
Erik Pilkingtonbb7feae2018-03-19 15:18:23 +00004836 if (!consumeIf('I'))
4837 return nullptr;
4838
4839 // <template-params> refer to the innermost <template-args>. Clear out any
4840 // outer args that we may have inserted into TemplateParams.
4841 if (TagTemplates)
4842 TemplateParams.clear();
4843
4844 size_t ArgsBegin = Names.size();
4845 while (!consumeIf('E')) {
4846 if (TagTemplates) {
4847 auto OldParams = std::move(TemplateParams);
4848 Node *Arg = parseTemplateArg();
4849 TemplateParams = std::move(OldParams);
4850 if (Arg == nullptr)
4851 return nullptr;
4852 Names.push_back(Arg);
4853 Node *TableEntry = Arg;
4854 if (Arg->getKind() == Node::KTemplateArgumentPack) {
4855 TableEntry = make<ParameterPack>(
4856 static_cast<TemplateArgumentPack*>(TableEntry)->getElements());
4857 }
4858 TemplateParams.push_back(TableEntry);
4859 } else {
4860 Node *Arg = parseTemplateArg();
4861 if (Arg == nullptr)
4862 return nullptr;
4863 Names.push_back(Arg);
4864 }
4865 }
4866 return make<TemplateArgs>(popTrailingNodeArray(ArgsBegin));
4867}
4868
4869// <discriminator> := _ <non-negative number> # when number < 10
4870// := __ <non-negative number> _ # when number >= 10
4871// extension := decimal-digit+ # at the end of string
4872
4873const char*
4874parse_discriminator(const char* first, const char* last)
4875{
4876 // parse but ignore discriminator
4877 if (first != last)
4878 {
4879 if (*first == '_')
4880 {
4881 const char* t1 = first+1;
4882 if (t1 != last)
4883 {
4884 if (std::isdigit(*t1))
4885 first = t1+1;
4886 else if (*t1 == '_')
4887 {
4888 for (++t1; t1 != last && std::isdigit(*t1); ++t1)
4889 ;
4890 if (t1 != last && *t1 == '_')
4891 first = t1 + 1;
Rafael Espindolab940b662016-09-06 19:16:48 +00004892 }
Rafael Espindolab940b662016-09-06 19:16:48 +00004893 }
Erik Pilkingtonbb7feae2018-03-19 15:18:23 +00004894 }
4895 else if (std::isdigit(*first))
4896 {
4897 const char* t1 = first+1;
4898 for (; t1 != last && std::isdigit(*t1); ++t1)
4899 ;
4900 if (t1 == last)
4901 first = last;
4902 }
Rafael Espindolab940b662016-09-06 19:16:48 +00004903 }
Erik Pilkingtonbb7feae2018-03-19 15:18:23 +00004904 return first;
Rafael Espindolab940b662016-09-06 19:16:48 +00004905}
4906
Erik Pilkingtonbb7feae2018-03-19 15:18:23 +00004907// <mangled-name> ::= _Z <encoding>
Rafael Espindolab940b662016-09-06 19:16:48 +00004908// ::= <type>
Erik Pilkingtonbb7feae2018-03-19 15:18:23 +00004909// extension ::= ___Z <encoding> _block_invoke
4910// extension ::= ___Z <encoding> _block_invoke<decimal-digit>+
4911// extension ::= ___Z <encoding> _block_invoke_<decimal-digit>+
4912Node *Db::parse() {
4913 if (consumeIf("_Z")) {
4914 Node *Encoding = parseEncoding();
4915 if (Encoding == nullptr)
4916 return nullptr;
4917 if (look() == '.') {
4918 Encoding = make<DotSuffix>(Encoding, StringView(First, Last));
4919 First = Last;
4920 }
4921 if (numLeft() != 0)
4922 return nullptr;
4923 return Encoding;
4924 }
Rafael Espindolab940b662016-09-06 19:16:48 +00004925
Erik Pilkingtonbb7feae2018-03-19 15:18:23 +00004926 if (consumeIf("___Z")) {
4927 Node *Encoding = parseEncoding();
4928 if (Encoding == nullptr || !consumeIf("_block_invoke"))
4929 return nullptr;
4930 bool RequireNumber = consumeIf('_');
4931 if (parseNumber().empty() && RequireNumber)
4932 return nullptr;
Erik Pilkington90dc82e2018-08-02 17:45:01 +00004933 if (look() == '.')
4934 First = Last;
Erik Pilkingtonbb7feae2018-03-19 15:18:23 +00004935 if (numLeft() != 0)
4936 return nullptr;
4937 return make<SpecialName>("invocation function for block in ", Encoding);
Rafael Espindolab940b662016-09-06 19:16:48 +00004938 }
Erik Pilkingtonbb7feae2018-03-19 15:18:23 +00004939
4940 Node *Ty = parseType();
4941 if (numLeft() != 0)
4942 return nullptr;
4943 return Ty;
Rafael Espindolab940b662016-09-06 19:16:48 +00004944}
Erik Pilkingtonf2a9b0f2018-04-12 20:41:06 +00004945
4946bool initializeOutputStream(char *Buf, size_t *N, OutputStream &S,
4947 size_t InitSize) {
4948 size_t BufferSize;
4949 if (Buf == nullptr) {
4950 Buf = static_cast<char *>(std::malloc(InitSize));
4951 if (Buf == nullptr)
4952 return true;
4953 BufferSize = InitSize;
4954 } else
4955 BufferSize = *N;
4956
4957 S.reset(Buf, BufferSize);
4958 return false;
4959}
4960
Erik Pilkingtonbb7feae2018-03-19 15:18:23 +00004961} // unnamed namespace
Rafael Espindolab940b662016-09-06 19:16:48 +00004962
Erik Pilkingtonbb7feae2018-03-19 15:18:23 +00004963char *llvm::itaniumDemangle(const char *MangledName, char *Buf,
4964 size_t *N, int *Status) {
4965 if (MangledName == nullptr || (Buf != nullptr && N == nullptr)) {
4966 if (Status)
Zachary Turner8a0efd02018-07-17 19:42:29 +00004967 *Status = demangle_invalid_args;
Rafael Espindolab940b662016-09-06 19:16:48 +00004968 return nullptr;
4969 }
Erik Pilkingtonbb7feae2018-03-19 15:18:23 +00004970
Zachary Turner8a0efd02018-07-17 19:42:29 +00004971 int InternalStatus = demangle_success;
Erik Pilkingtonf2a9b0f2018-04-12 20:41:06 +00004972 Db Parser(MangledName, MangledName + std::strlen(MangledName));
4973 OutputStream S;
Erik Pilkingtonbb7feae2018-03-19 15:18:23 +00004974
Erik Pilkingtonbb7feae2018-03-19 15:18:23 +00004975 Node *AST = Parser.parse();
4976
4977 if (AST == nullptr)
Zachary Turner8a0efd02018-07-17 19:42:29 +00004978 InternalStatus = demangle_invalid_mangled_name;
Erik Pilkingtonf2a9b0f2018-04-12 20:41:06 +00004979 else if (initializeOutputStream(Buf, N, S, 1024))
Zachary Turner8a0efd02018-07-17 19:42:29 +00004980 InternalStatus = demangle_memory_alloc_failure;
Erik Pilkingtonf2a9b0f2018-04-12 20:41:06 +00004981 else {
Erik Pilkington8a1cb332018-03-25 22:50:33 +00004982 assert(Parser.ForwardTemplateRefs.empty());
Erik Pilkingtonf2a9b0f2018-04-12 20:41:06 +00004983 AST->print(S);
4984 S += '\0';
4985 if (N != nullptr)
4986 *N = S.getCurrentPosition();
4987 Buf = S.getBuffer();
Erik Pilkingtonbb7feae2018-03-19 15:18:23 +00004988 }
4989
4990 if (Status)
4991 *Status = InternalStatus;
Zachary Turner8a0efd02018-07-17 19:42:29 +00004992 return InternalStatus == demangle_success ? Buf : nullptr;
Rafael Espindolab940b662016-09-06 19:16:48 +00004993}
Erik Pilkington67d82d62018-04-12 20:41:38 +00004994
Erik Pilkingtonac6a801c2018-08-13 16:37:47 +00004995bool llvm::itaniumFindTypesInMangledName(const char *MangledName, void *Ctx,
4996 void (*Callback)(void *,
4997 const char *)) {
4998 Db Parser(MangledName, MangledName + std::strlen(MangledName));
4999 Parser.TypeCallback = Callback;
5000 Parser.TypeCallbackContext = Ctx;
5001 return Parser.parse() == nullptr;
5002}
5003
Erik Pilkington67d82d62018-04-12 20:41:38 +00005004namespace llvm {
5005
5006ItaniumPartialDemangler::ItaniumPartialDemangler()
5007 : RootNode(nullptr), Context(new Db{nullptr, nullptr}) {}
5008
5009ItaniumPartialDemangler::~ItaniumPartialDemangler() {
5010 delete static_cast<Db *>(Context);
5011}
5012
5013ItaniumPartialDemangler::ItaniumPartialDemangler(
5014 ItaniumPartialDemangler &&Other)
5015 : RootNode(Other.RootNode), Context(Other.Context) {
5016 Other.Context = Other.RootNode = nullptr;
5017}
5018
5019ItaniumPartialDemangler &ItaniumPartialDemangler::
5020operator=(ItaniumPartialDemangler &&Other) {
5021 std::swap(RootNode, Other.RootNode);
5022 std::swap(Context, Other.Context);
5023 return *this;
5024}
5025
5026// Demangle MangledName into an AST, storing it into this->RootNode.
5027bool ItaniumPartialDemangler::partialDemangle(const char *MangledName) {
5028 Db *Parser = static_cast<Db *>(Context);
5029 size_t Len = std::strlen(MangledName);
5030 Parser->reset(MangledName, MangledName + Len);
5031 RootNode = Parser->parse();
5032 return RootNode == nullptr;
5033}
5034
5035static char *printNode(Node *RootNode, char *Buf, size_t *N) {
5036 OutputStream S;
5037 if (initializeOutputStream(Buf, N, S, 128))
5038 return nullptr;
5039 RootNode->print(S);
5040 S += '\0';
5041 if (N != nullptr)
5042 *N = S.getCurrentPosition();
5043 return S.getBuffer();
5044}
5045
5046char *ItaniumPartialDemangler::getFunctionBaseName(char *Buf, size_t *N) const {
5047 if (!isFunction())
5048 return nullptr;
5049
5050 Node *Name = static_cast<FunctionEncoding *>(RootNode)->getName();
5051
5052 while (true) {
5053 switch (Name->getKind()) {
5054 case Node::KAbiTagAttr:
5055 Name = static_cast<AbiTagAttr *>(Name)->Base;
5056 continue;
5057 case Node::KStdQualifiedName:
5058 Name = static_cast<StdQualifiedName *>(Name)->Child;
5059 continue;
5060 case Node::KNestedName:
5061 Name = static_cast<NestedName *>(Name)->Name;
5062 continue;
5063 case Node::KLocalName:
5064 Name = static_cast<LocalName *>(Name)->Entity;
5065 continue;
5066 case Node::KNameWithTemplateArgs:
5067 Name = static_cast<NameWithTemplateArgs *>(Name)->Name;
5068 continue;
5069 default:
5070 return printNode(Name, Buf, N);
5071 }
5072 }
5073}
5074
5075char *ItaniumPartialDemangler::getFunctionDeclContextName(char *Buf,
5076 size_t *N) const {
5077 if (!isFunction())
5078 return nullptr;
5079 Node *Name = static_cast<FunctionEncoding *>(RootNode)->getName();
5080
5081 OutputStream S;
5082 if (initializeOutputStream(Buf, N, S, 128))
5083 return nullptr;
5084
5085 KeepGoingLocalFunction:
5086 while (true) {
5087 if (Name->getKind() == Node::KAbiTagAttr) {
5088 Name = static_cast<AbiTagAttr *>(Name)->Base;
5089 continue;
5090 }
5091 if (Name->getKind() == Node::KNameWithTemplateArgs) {
5092 Name = static_cast<NameWithTemplateArgs *>(Name)->Name;
5093 continue;
5094 }
5095 break;
5096 }
5097
5098 switch (Name->getKind()) {
5099 case Node::KStdQualifiedName:
5100 S += "std";
5101 break;
5102 case Node::KNestedName:
5103 static_cast<NestedName *>(Name)->Qual->print(S);
5104 break;
5105 case Node::KLocalName: {
5106 auto *LN = static_cast<LocalName *>(Name);
5107 LN->Encoding->print(S);
5108 S += "::";
5109 Name = LN->Entity;
5110 goto KeepGoingLocalFunction;
5111 }
5112 default:
5113 break;
5114 }
5115 S += '\0';
5116 if (N != nullptr)
5117 *N = S.getCurrentPosition();
5118 return S.getBuffer();
5119}
5120
5121char *ItaniumPartialDemangler::getFunctionName(char *Buf, size_t *N) const {
5122 if (!isFunction())
5123 return nullptr;
5124 auto *Name = static_cast<FunctionEncoding *>(RootNode)->getName();
5125 return printNode(Name, Buf, N);
5126}
5127
5128char *ItaniumPartialDemangler::getFunctionParameters(char *Buf,
5129 size_t *N) const {
5130 if (!isFunction())
5131 return nullptr;
5132 NodeArray Params = static_cast<FunctionEncoding *>(RootNode)->getParams();
5133
5134 OutputStream S;
5135 if (initializeOutputStream(Buf, N, S, 128))
5136 return nullptr;
5137
5138 S += '(';
5139 Params.printWithComma(S);
5140 S += ')';
5141 S += '\0';
5142 if (N != nullptr)
5143 *N = S.getCurrentPosition();
5144 return S.getBuffer();
5145}
5146
5147char *ItaniumPartialDemangler::getFunctionReturnType(
5148 char *Buf, size_t *N) const {
5149 if (!isFunction())
5150 return nullptr;
5151
5152 OutputStream S;
5153 if (initializeOutputStream(Buf, N, S, 128))
5154 return nullptr;
5155
5156 if (Node *Ret = static_cast<FunctionEncoding *>(RootNode)->getReturnType())
5157 Ret->print(S);
5158
5159 S += '\0';
5160 if (N != nullptr)
5161 *N = S.getCurrentPosition();
5162 return S.getBuffer();
5163}
5164
5165char *ItaniumPartialDemangler::finishDemangle(char *Buf, size_t *N) const {
5166 assert(RootNode != nullptr && "must call partialDemangle()");
5167 return printNode(static_cast<Node *>(RootNode), Buf, N);
5168}
5169
5170bool ItaniumPartialDemangler::hasFunctionQualifiers() const {
5171 assert(RootNode != nullptr && "must call partialDemangle()");
5172 if (!isFunction())
5173 return false;
5174 auto *E = static_cast<FunctionEncoding *>(RootNode);
5175 return E->getCVQuals() != QualNone || E->getRefQual() != FrefQualNone;
5176}
5177
Fangrui Song79420ac2018-05-24 06:57:57 +00005178bool ItaniumPartialDemangler::isCtorOrDtor() const {
5179 Node *N = static_cast<Node *>(RootNode);
5180 while (N) {
5181 switch (N->getKind()) {
5182 default:
5183 return false;
5184 case Node::KCtorDtorName:
5185 return true;
5186
5187 case Node::KAbiTagAttr:
5188 N = static_cast<AbiTagAttr *>(N)->Base;
5189 break;
5190 case Node::KFunctionEncoding:
5191 N = static_cast<FunctionEncoding *>(N)->getName();
5192 break;
5193 case Node::KLocalName:
5194 N = static_cast<LocalName *>(N)->Entity;
5195 break;
5196 case Node::KNameWithTemplateArgs:
5197 N = static_cast<NameWithTemplateArgs *>(N)->Name;
5198 break;
5199 case Node::KNestedName:
5200 N = static_cast<NestedName *>(N)->Name;
5201 break;
5202 case Node::KStdQualifiedName:
5203 N = static_cast<StdQualifiedName *>(N)->Child;
5204 break;
5205 }
5206 }
5207 return false;
5208}
5209
Erik Pilkington67d82d62018-04-12 20:41:38 +00005210bool ItaniumPartialDemangler::isFunction() const {
5211 assert(RootNode != nullptr && "must call partialDemangle()");
5212 return static_cast<Node *>(RootNode)->getKind() == Node::KFunctionEncoding;
5213}
5214
5215bool ItaniumPartialDemangler::isSpecialName() const {
5216 assert(RootNode != nullptr && "must call partialDemangle()");
5217 auto K = static_cast<Node *>(RootNode)->getKind();
5218 return K == Node::KSpecialName || K == Node::KCtorVtableSpecialName;
5219}
5220
5221bool ItaniumPartialDemangler::isData() const {
5222 return !isFunction() && !isSpecialName();
5223}
Erik Pilkington67d82d62018-04-12 20:41:38 +00005224}