blob: 98b92b04a260f450e2258d483e2f0ec499701ffd [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 Pilkingtonbb7feae2018-03-19 15:18:23 +00001968 bool TryToParseTemplateArgs = true;
Erik Pilkington8a1cb332018-03-25 22:50:33 +00001969 bool PermitForwardTemplateReferences = false;
Erik Pilkingtonbb7feae2018-03-19 15:18:23 +00001970 bool ParsingLambdaParams = false;
1971
1972 BumpPointerAllocator ASTAllocator;
1973
1974 Db(const char *First_, const char *Last_) : First(First_), Last(Last_) {}
1975
Erik Pilkingtonf2a9b0f2018-04-12 20:41:06 +00001976 void reset(const char *First_, const char *Last_) {
1977 First = First_;
1978 Last = Last_;
1979 Names.clear();
1980 Subs.clear();
1981 TemplateParams.clear();
1982 ParsingLambdaParams = false;
1983 TryToParseTemplateArgs = true;
1984 PermitForwardTemplateReferences = false;
1985 ASTAllocator.reset();
1986 }
1987
Erik Pilkingtonbb7feae2018-03-19 15:18:23 +00001988 template <class T, class... Args> T *make(Args &&... args) {
1989 return new (ASTAllocator.allocate(sizeof(T)))
1990 T(std::forward<Args>(args)...);
1991 }
1992
1993 template <class It> NodeArray makeNodeArray(It begin, It end) {
1994 size_t sz = static_cast<size_t>(end - begin);
1995 void *mem = ASTAllocator.allocate(sizeof(Node *) * sz);
1996 Node **data = new (mem) Node *[sz];
1997 std::copy(begin, end, data);
1998 return NodeArray(data, sz);
1999 }
2000
2001 NodeArray popTrailingNodeArray(size_t FromPosition) {
2002 assert(FromPosition <= Names.size());
2003 NodeArray res =
2004 makeNodeArray(Names.begin() + (long)FromPosition, Names.end());
2005 Names.dropBack(FromPosition);
2006 return res;
2007 }
2008
2009 bool consumeIf(StringView S) {
2010 if (StringView(First, Last).startsWith(S)) {
2011 First += S.size();
2012 return true;
2013 }
2014 return false;
2015 }
2016
2017 bool consumeIf(char C) {
2018 if (First != Last && *First == C) {
2019 ++First;
2020 return true;
2021 }
2022 return false;
2023 }
2024
2025 char consume() { return First != Last ? *First++ : '\0'; }
2026
2027 char look(unsigned Lookahead = 0) {
2028 if (static_cast<size_t>(Last - First) <= Lookahead)
2029 return '\0';
2030 return First[Lookahead];
2031 }
2032
2033 size_t numLeft() const { return static_cast<size_t>(Last - First); }
2034
2035 StringView parseNumber(bool AllowNegative = false);
2036 Qualifiers parseCVQualifiers();
2037 bool parsePositiveInteger(size_t *Out);
2038 StringView parseBareSourceName();
2039
2040 bool parseSeqId(size_t *Out);
2041 Node *parseSubstitution();
2042 Node *parseTemplateParam();
Erik Pilkington8a1cb332018-03-25 22:50:33 +00002043 Node *parseTemplateArgs(bool TagTemplates = false);
Erik Pilkingtonbb7feae2018-03-19 15:18:23 +00002044 Node *parseTemplateArg();
2045
2046 /// Parse the <expr> production.
2047 Node *parseExpr();
2048 Node *parsePrefixExpr(StringView Kind);
2049 Node *parseBinaryExpr(StringView Kind);
2050 Node *parseIntegerLiteral(StringView Lit);
2051 Node *parseExprPrimary();
2052 template <class Float> Node *parseFloatingLiteral();
2053 Node *parseFunctionParam();
2054 Node *parseNewExpr();
2055 Node *parseConversionExpr();
2056 Node *parseBracedExpr();
Erik Pilkingtond43931d2018-04-09 18:33:01 +00002057 Node *parseFoldExpr();
Erik Pilkingtonbb7feae2018-03-19 15:18:23 +00002058
2059 /// Parse the <type> production.
2060 Node *parseType();
2061 Node *parseFunctionType();
2062 Node *parseVectorType();
2063 Node *parseDecltype();
2064 Node *parseArrayType();
2065 Node *parsePointerToMemberType();
2066 Node *parseClassEnumType();
2067 Node *parseQualifiedType();
2068
2069 Node *parseEncoding();
2070 bool parseCallOffset();
2071 Node *parseSpecialName();
2072
2073 /// Holds some extra information about a <name> that is being parsed. This
2074 /// information is only pertinent if the <name> refers to an <encoding>.
2075 struct NameState {
2076 bool CtorDtorConversion = false;
2077 bool EndsWithTemplateArgs = false;
2078 Qualifiers CVQualifiers = QualNone;
2079 FunctionRefQual ReferenceQualifier = FrefQualNone;
Erik Pilkington8a1cb332018-03-25 22:50:33 +00002080 size_t ForwardTemplateRefsBegin;
2081
2082 NameState(Db *Enclosing)
2083 : ForwardTemplateRefsBegin(Enclosing->ForwardTemplateRefs.size()) {}
Erik Pilkingtonbb7feae2018-03-19 15:18:23 +00002084 };
2085
Erik Pilkington8a1cb332018-03-25 22:50:33 +00002086 bool resolveForwardTemplateRefs(NameState &State) {
2087 size_t I = State.ForwardTemplateRefsBegin;
2088 size_t E = ForwardTemplateRefs.size();
2089 for (; I < E; ++I) {
2090 size_t Idx = ForwardTemplateRefs[I]->Index;
2091 if (Idx >= TemplateParams.size())
2092 return true;
2093 ForwardTemplateRefs[I]->Ref = TemplateParams[Idx];
2094 }
2095 ForwardTemplateRefs.dropBack(State.ForwardTemplateRefsBegin);
2096 return false;
2097 }
2098
Erik Pilkingtonbb7feae2018-03-19 15:18:23 +00002099 /// Parse the <name> production>
2100 Node *parseName(NameState *State = nullptr);
2101 Node *parseLocalName(NameState *State);
2102 Node *parseOperatorName(NameState *State);
2103 Node *parseUnqualifiedName(NameState *State);
2104 Node *parseUnnamedTypeName(NameState *State);
2105 Node *parseSourceName(NameState *State);
2106 Node *parseUnscopedName(NameState *State);
2107 Node *parseNestedName(NameState *State);
2108 Node *parseCtorDtorName(Node *&SoFar, NameState *State);
2109
2110 Node *parseAbiTags(Node *N);
2111
2112 /// Parse the <unresolved-name> production.
2113 Node *parseUnresolvedName();
2114 Node *parseSimpleId();
2115 Node *parseBaseUnresolvedName();
2116 Node *parseUnresolvedType();
2117 Node *parseDestructorName();
2118
2119 /// Top-level entry point into the parser.
2120 Node *parse();
2121};
2122
2123const char* parse_discriminator(const char* first, const char* last);
2124
2125// <name> ::= <nested-name> // N
2126// ::= <local-name> # See Scope Encoding below // Z
2127// ::= <unscoped-template-name> <template-args>
2128// ::= <unscoped-name>
2129//
2130// <unscoped-template-name> ::= <unscoped-name>
2131// ::= <substitution>
2132Node *Db::parseName(NameState *State) {
2133 consumeIf('L'); // extension
2134
2135 if (look() == 'N')
2136 return parseNestedName(State);
2137 if (look() == 'Z')
2138 return parseLocalName(State);
2139
2140 // ::= <unscoped-template-name> <template-args>
2141 if (look() == 'S' && look(1) != 't') {
2142 Node *S = parseSubstitution();
2143 if (S == nullptr)
2144 return nullptr;
2145 if (look() != 'I')
2146 return nullptr;
Erik Pilkington8a1cb332018-03-25 22:50:33 +00002147 Node *TA = parseTemplateArgs(State != nullptr);
Erik Pilkingtonbb7feae2018-03-19 15:18:23 +00002148 if (TA == nullptr)
2149 return nullptr;
2150 if (State) State->EndsWithTemplateArgs = true;
2151 return make<NameWithTemplateArgs>(S, TA);
2152 }
2153
2154 Node *N = parseUnscopedName(State);
2155 if (N == nullptr)
2156 return nullptr;
2157 // ::= <unscoped-template-name> <template-args>
2158 if (look() == 'I') {
2159 Subs.push_back(N);
Erik Pilkington8a1cb332018-03-25 22:50:33 +00002160 Node *TA = parseTemplateArgs(State != nullptr);
Erik Pilkingtonbb7feae2018-03-19 15:18:23 +00002161 if (TA == nullptr)
2162 return nullptr;
2163 if (State) State->EndsWithTemplateArgs = true;
2164 return make<NameWithTemplateArgs>(N, TA);
2165 }
2166 // ::= <unscoped-name>
2167 return N;
2168}
2169
2170// <local-name> := Z <function encoding> E <entity name> [<discriminator>]
2171// := Z <function encoding> E s [<discriminator>]
2172// := Z <function encoding> Ed [ <parameter number> ] _ <entity name>
2173Node *Db::parseLocalName(NameState *State) {
2174 if (!consumeIf('Z'))
2175 return nullptr;
2176 Node *Encoding = parseEncoding();
2177 if (Encoding == nullptr || !consumeIf('E'))
2178 return nullptr;
2179
2180 if (consumeIf('s')) {
2181 First = parse_discriminator(First, Last);
Erik Pilkingtonf2a9b0f2018-04-12 20:41:06 +00002182 return make<LocalName>(Encoding, make<NameType>("string literal"));
Erik Pilkingtonbb7feae2018-03-19 15:18:23 +00002183 }
2184
2185 if (consumeIf('d')) {
2186 parseNumber(true);
2187 if (!consumeIf('_'))
2188 return nullptr;
2189 Node *N = parseName(State);
2190 if (N == nullptr)
2191 return nullptr;
Erik Pilkingtonf2a9b0f2018-04-12 20:41:06 +00002192 return make<LocalName>(Encoding, N);
Erik Pilkingtonbb7feae2018-03-19 15:18:23 +00002193 }
2194
2195 Node *Entity = parseName(State);
2196 if (Entity == nullptr)
2197 return nullptr;
2198 First = parse_discriminator(First, Last);
Erik Pilkingtonf2a9b0f2018-04-12 20:41:06 +00002199 return make<LocalName>(Encoding, Entity);
Erik Pilkingtonbb7feae2018-03-19 15:18:23 +00002200}
2201
2202// <unscoped-name> ::= <unqualified-name>
2203// ::= St <unqualified-name> # ::std::
2204// extension ::= StL<unqualified-name>
2205Node *Db::parseUnscopedName(NameState *State) {
2206 if (consumeIf("StL") || consumeIf("St")) {
2207 Node *R = parseUnqualifiedName(State);
2208 if (R == nullptr)
2209 return nullptr;
2210 return make<StdQualifiedName>(R);
2211 }
2212 return parseUnqualifiedName(State);
2213}
2214
2215// <unqualified-name> ::= <operator-name> [abi-tags]
2216// ::= <ctor-dtor-name>
2217// ::= <source-name>
2218// ::= <unnamed-type-name>
2219// ::= DC <source-name>+ E # structured binding declaration
2220Node *Db::parseUnqualifiedName(NameState *State) {
2221 // <ctor-dtor-name>s are special-cased in parseNestedName().
2222 Node *Result;
2223 if (look() == 'U')
2224 Result = parseUnnamedTypeName(State);
2225 else if (look() >= '1' && look() <= '9')
2226 Result = parseSourceName(State);
2227 else if (consumeIf("DC")) {
2228 size_t BindingsBegin = Names.size();
2229 do {
2230 Node *Binding = parseSourceName(State);
2231 if (Binding == nullptr)
2232 return nullptr;
2233 Names.push_back(Binding);
2234 } while (!consumeIf('E'));
2235 Result = make<StructuredBindingName>(popTrailingNodeArray(BindingsBegin));
2236 } else
2237 Result = parseOperatorName(State);
2238 if (Result != nullptr)
2239 Result = parseAbiTags(Result);
2240 return Result;
2241}
2242
2243// <unnamed-type-name> ::= Ut [<nonnegative number>] _
2244// ::= <closure-type-name>
2245//
2246// <closure-type-name> ::= Ul <lambda-sig> E [ <nonnegative number> ] _
2247//
2248// <lambda-sig> ::= <parameter type>+ # Parameter types or "v" if the lambda has no parameters
2249Node *Db::parseUnnamedTypeName(NameState *) {
2250 if (consumeIf("Ut")) {
2251 StringView Count = parseNumber();
2252 if (!consumeIf('_'))
2253 return nullptr;
2254 return make<UnnamedTypeName>(Count);
2255 }
2256 if (consumeIf("Ul")) {
2257 NodeArray Params;
2258 SwapAndRestore<bool> SwapParams(ParsingLambdaParams, true);
2259 if (!consumeIf("vE")) {
2260 size_t ParamsBegin = Names.size();
2261 do {
2262 Node *P = parseType();
2263 if (P == nullptr)
2264 return nullptr;
2265 Names.push_back(P);
2266 } while (!consumeIf('E'));
2267 Params = popTrailingNodeArray(ParamsBegin);
2268 }
2269 StringView Count = parseNumber();
2270 if (!consumeIf('_'))
2271 return nullptr;
2272 return make<ClosureTypeName>(Params, Count);
2273 }
2274 return nullptr;
Rafael Espindolab940b662016-09-06 19:16:48 +00002275}
2276
2277// <source-name> ::= <positive length number> <identifier>
Erik Pilkingtonbb7feae2018-03-19 15:18:23 +00002278Node *Db::parseSourceName(NameState *) {
2279 size_t Length = 0;
2280 if (parsePositiveInteger(&Length))
2281 return nullptr;
2282 if (numLeft() < Length || Length == 0)
2283 return nullptr;
2284 StringView Name(First, First + Length);
2285 First += Length;
2286 if (Name.startsWith("_GLOBAL__N"))
2287 return make<NameType>("(anonymous namespace)");
2288 return make<NameType>(Name);
Rafael Espindolab940b662016-09-06 19:16:48 +00002289}
2290
Erik Pilkingtonbb7feae2018-03-19 15:18:23 +00002291// <operator-name> ::= aa # &&
Rafael Espindolab940b662016-09-06 19:16:48 +00002292// ::= ad # & (unary)
2293// ::= an # &
2294// ::= aN # &=
2295// ::= aS # =
2296// ::= cl # ()
2297// ::= cm # ,
2298// ::= co # ~
2299// ::= cv <type> # (cast)
2300// ::= da # delete[]
2301// ::= de # * (unary)
2302// ::= dl # delete
2303// ::= dv # /
2304// ::= dV # /=
2305// ::= eo # ^
2306// ::= eO # ^=
2307// ::= eq # ==
2308// ::= ge # >=
2309// ::= gt # >
2310// ::= ix # []
2311// ::= le # <=
2312// ::= li <source-name> # operator ""
2313// ::= ls # <<
2314// ::= lS # <<=
2315// ::= lt # <
2316// ::= mi # -
2317// ::= mI # -=
2318// ::= ml # *
2319// ::= mL # *=
2320// ::= mm # -- (postfix in <expression> context)
2321// ::= na # new[]
2322// ::= ne # !=
2323// ::= ng # - (unary)
2324// ::= nt # !
2325// ::= nw # new
2326// ::= oo # ||
2327// ::= or # |
2328// ::= oR # |=
2329// ::= pm # ->*
2330// ::= pl # +
2331// ::= pL # +=
2332// ::= pp # ++ (postfix in <expression> context)
2333// ::= ps # + (unary)
2334// ::= pt # ->
2335// ::= qu # ?
2336// ::= rm # %
2337// ::= rM # %=
2338// ::= rs # >>
2339// ::= rS # >>=
Erik Pilkingtonbb7feae2018-03-19 15:18:23 +00002340// ::= ss # <=> C++2a
2341// ::= v <digit> <source-name> # vendor extended operator
2342Node *Db::parseOperatorName(NameState *State) {
2343 switch (look()) {
2344 case 'a':
2345 switch (look(1)) {
Rafael Espindolab940b662016-09-06 19:16:48 +00002346 case 'a':
Erik Pilkingtonbb7feae2018-03-19 15:18:23 +00002347 First += 2;
2348 return make<NameType>("operator&&");
Rafael Espindolab940b662016-09-06 19:16:48 +00002349 case 'd':
Rafael Espindolab940b662016-09-06 19:16:48 +00002350 case 'n':
Erik Pilkingtonbb7feae2018-03-19 15:18:23 +00002351 First += 2;
2352 return make<NameType>("operator&");
2353 case 'N':
2354 First += 2;
2355 return make<NameType>("operator&=");
2356 case 'S':
2357 First += 2;
2358 return make<NameType>("operator=");
2359 }
2360 return nullptr;
2361 case 'c':
2362 switch (look(1)) {
2363 case 'l':
2364 First += 2;
2365 return make<NameType>("operator()");
2366 case 'm':
2367 First += 2;
2368 return make<NameType>("operator,");
Rafael Espindolab940b662016-09-06 19:16:48 +00002369 case 'o':
Erik Pilkingtonbb7feae2018-03-19 15:18:23 +00002370 First += 2;
2371 return make<NameType>("operator~");
2372 // ::= cv <type> # (cast)
2373 case 'v': {
Erik Pilkingtonbb7feae2018-03-19 15:18:23 +00002374 First += 2;
Erik Pilkington8a1cb332018-03-25 22:50:33 +00002375 SwapAndRestore<bool> SaveTemplate(TryToParseTemplateArgs, false);
2376 // If we're parsing an encoding, State != nullptr and the conversion
2377 // operators' <type> could have a <template-param> that refers to some
2378 // <template-arg>s further ahead in the mangled name.
2379 SwapAndRestore<bool> SavePermit(PermitForwardTemplateReferences,
2380 PermitForwardTemplateReferences ||
2381 State != nullptr);
2382 Node* Ty = parseType();
Erik Pilkingtonbb7feae2018-03-19 15:18:23 +00002383 if (Ty == nullptr)
2384 return nullptr;
2385 if (State) State->CtorDtorConversion = true;
2386 return make<ConversionOperatorType>(Ty);
2387 }
2388 }
2389 return nullptr;
2390 case 'd':
2391 switch (look(1)) {
2392 case 'a':
2393 First += 2;
2394 return make<NameType>("operator delete[]");
2395 case 'e':
2396 First += 2;
2397 return make<NameType>("operator*");
2398 case 'l':
2399 First += 2;
2400 return make<NameType>("operator delete");
Rafael Espindolab940b662016-09-06 19:16:48 +00002401 case 'v':
Erik Pilkingtonbb7feae2018-03-19 15:18:23 +00002402 First += 2;
2403 return make<NameType>("operator/");
2404 case 'V':
2405 First += 2;
2406 return make<NameType>("operator/=");
Rafael Espindolab940b662016-09-06 19:16:48 +00002407 }
Erik Pilkingtonbb7feae2018-03-19 15:18:23 +00002408 return nullptr;
2409 case 'e':
2410 switch (look(1)) {
Rafael Espindolab940b662016-09-06 19:16:48 +00002411 case 'o':
Erik Pilkingtonbb7feae2018-03-19 15:18:23 +00002412 First += 2;
2413 return make<NameType>("operator^");
2414 case 'O':
2415 First += 2;
2416 return make<NameType>("operator^=");
Rafael Espindolab940b662016-09-06 19:16:48 +00002417 case 'q':
Erik Pilkingtonbb7feae2018-03-19 15:18:23 +00002418 First += 2;
2419 return make<NameType>("operator==");
2420 }
2421 return nullptr;
2422 case 'g':
2423 switch (look(1)) {
2424 case 'e':
2425 First += 2;
2426 return make<NameType>("operator>=");
Rafael Espindolab940b662016-09-06 19:16:48 +00002427 case 't':
Erik Pilkingtonbb7feae2018-03-19 15:18:23 +00002428 First += 2;
2429 return make<NameType>("operator>");
Rafael Espindolab940b662016-09-06 19:16:48 +00002430 }
Erik Pilkingtonbb7feae2018-03-19 15:18:23 +00002431 return nullptr;
2432 case 'i':
2433 if (look(1) == 'x') {
2434 First += 2;
2435 return make<NameType>("operator[]");
2436 }
2437 return nullptr;
2438 case 'l':
2439 switch (look(1)) {
2440 case 'e':
2441 First += 2;
2442 return make<NameType>("operator<=");
2443 // ::= li <source-name> # operator ""
2444 case 'i': {
2445 First += 2;
2446 Node *SN = parseSourceName(State);
2447 if (SN == nullptr)
2448 return nullptr;
2449 return make<LiteralOperator>(SN);
2450 }
2451 case 's':
2452 First += 2;
2453 return make<NameType>("operator<<");
2454 case 'S':
2455 First += 2;
2456 return make<NameType>("operator<<=");
2457 case 't':
2458 First += 2;
2459 return make<NameType>("operator<");
2460 }
2461 return nullptr;
2462 case 'm':
2463 switch (look(1)) {
2464 case 'i':
2465 First += 2;
2466 return make<NameType>("operator-");
2467 case 'I':
2468 First += 2;
2469 return make<NameType>("operator-=");
2470 case 'l':
2471 First += 2;
2472 return make<NameType>("operator*");
Rafael Espindolab940b662016-09-06 19:16:48 +00002473 case 'L':
Erik Pilkingtonbb7feae2018-03-19 15:18:23 +00002474 First += 2;
2475 return make<NameType>("operator*=");
2476 case 'm':
2477 First += 2;
2478 return make<NameType>("operator--");
2479 }
2480 return nullptr;
2481 case 'n':
2482 switch (look(1)) {
2483 case 'a':
2484 First += 2;
2485 return make<NameType>("operator new[]");
2486 case 'e':
2487 First += 2;
2488 return make<NameType>("operator!=");
2489 case 'g':
2490 First += 2;
2491 return make<NameType>("operator-");
2492 case 't':
2493 First += 2;
2494 return make<NameType>("operator!");
2495 case 'w':
2496 First += 2;
2497 return make<NameType>("operator new");
2498 }
2499 return nullptr;
2500 case 'o':
2501 switch (look(1)) {
2502 case 'o':
2503 First += 2;
2504 return make<NameType>("operator||");
2505 case 'r':
2506 First += 2;
2507 return make<NameType>("operator|");
2508 case 'R':
2509 First += 2;
2510 return make<NameType>("operator|=");
2511 }
2512 return nullptr;
2513 case 'p':
2514 switch (look(1)) {
2515 case 'm':
2516 First += 2;
2517 return make<NameType>("operator->*");
2518 case 'l':
2519 First += 2;
2520 return make<NameType>("operator+");
2521 case 'L':
2522 First += 2;
2523 return make<NameType>("operator+=");
2524 case 'p':
2525 First += 2;
2526 return make<NameType>("operator++");
2527 case 's':
2528 First += 2;
2529 return make<NameType>("operator+");
2530 case 't':
2531 First += 2;
2532 return make<NameType>("operator->");
2533 }
2534 return nullptr;
2535 case 'q':
2536 if (look(1) == 'u') {
2537 First += 2;
2538 return make<NameType>("operator?");
2539 }
2540 return nullptr;
2541 case 'r':
2542 switch (look(1)) {
2543 case 'm':
2544 First += 2;
2545 return make<NameType>("operator%");
2546 case 'M':
2547 First += 2;
2548 return make<NameType>("operator%=");
2549 case 's':
2550 First += 2;
2551 return make<NameType>("operator>>");
2552 case 'S':
2553 First += 2;
2554 return make<NameType>("operator>>=");
2555 }
2556 return nullptr;
2557 case 's':
2558 if (look(1) == 's') {
2559 First += 2;
2560 return make<NameType>("operator<=>");
2561 }
2562 return nullptr;
2563 // ::= v <digit> <source-name> # vendor extended operator
2564 case 'v':
2565 if (std::isdigit(look(1))) {
2566 First += 2;
2567 Node *SN = parseSourceName(State);
2568 if (SN == nullptr)
2569 return nullptr;
2570 return make<ConversionOperatorType>(SN);
2571 }
2572 return nullptr;
2573 }
2574 return nullptr;
2575}
2576
2577// <ctor-dtor-name> ::= C1 # complete object constructor
2578// ::= C2 # base object constructor
2579// ::= C3 # complete object allocating constructor
2580// extension ::= C5 # ?
2581// ::= D0 # deleting destructor
2582// ::= D1 # complete object destructor
2583// ::= D2 # base object destructor
2584// extension ::= D5 # ?
2585Node *Db::parseCtorDtorName(Node *&SoFar, NameState *State) {
2586 if (SoFar->K == Node::KSpecialSubstitution) {
2587 auto SSK = static_cast<SpecialSubstitution *>(SoFar)->SSK;
2588 switch (SSK) {
2589 case SpecialSubKind::string:
2590 case SpecialSubKind::istream:
2591 case SpecialSubKind::ostream:
2592 case SpecialSubKind::iostream:
2593 SoFar = make<ExpandedSpecialSubstitution>(SSK);
Rafael Espindolab940b662016-09-06 19:16:48 +00002594 default:
Rafael Espindolab940b662016-09-06 19:16:48 +00002595 break;
2596 }
2597 }
Rafael Espindolab940b662016-09-06 19:16:48 +00002598
Erik Pilkingtonbb7feae2018-03-19 15:18:23 +00002599 if (consumeIf('C')) {
2600 bool IsInherited = consumeIf('I');
2601 if (look() != '1' && look() != '2' && look() != '3' && look() != '5')
2602 return nullptr;
2603 ++First;
2604 if (State) State->CtorDtorConversion = true;
2605 if (IsInherited) {
Erik Pilkington8a1cb332018-03-25 22:50:33 +00002606 if (parseName(State) == nullptr)
Erik Pilkingtonbb7feae2018-03-19 15:18:23 +00002607 return nullptr;
Rafael Espindolab940b662016-09-06 19:16:48 +00002608 }
Erik Pilkingtonbb7feae2018-03-19 15:18:23 +00002609 return make<CtorDtorName>(SoFar, false);
Rafael Espindolab940b662016-09-06 19:16:48 +00002610 }
Erik Pilkingtonbb7feae2018-03-19 15:18:23 +00002611
2612 if (look() == 'D' &&
2613 (look(1) == '0' || look(1) == '1' || look(1) == '2' || look(1) == '5')) {
2614 First += 2;
2615 if (State) State->CtorDtorConversion = true;
2616 return make<CtorDtorName>(SoFar, true);
2617 }
2618
2619 return nullptr;
Rafael Espindolab940b662016-09-06 19:16:48 +00002620}
2621
Erik Pilkingtonbb7feae2018-03-19 15:18:23 +00002622// <nested-name> ::= N [<CV-Qualifiers>] [<ref-qualifier>] <prefix> <unqualified-name> E
2623// ::= N [<CV-Qualifiers>] [<ref-qualifier>] <template-prefix> <template-args> E
Rafael Espindolab940b662016-09-06 19:16:48 +00002624//
2625// <prefix> ::= <prefix> <unqualified-name>
2626// ::= <template-prefix> <template-args>
2627// ::= <template-param>
2628// ::= <decltype>
2629// ::= # empty
2630// ::= <substitution>
2631// ::= <prefix> <data-member-prefix>
2632// extension ::= L
2633//
Erik Pilkington452e2ef2018-04-09 18:32:25 +00002634// <data-member-prefix> := <member source-name> [<template-args>] M
2635//
Rafael Espindolab940b662016-09-06 19:16:48 +00002636// <template-prefix> ::= <prefix> <template unqualified-name>
2637// ::= <template-param>
2638// ::= <substitution>
Erik Pilkingtonbb7feae2018-03-19 15:18:23 +00002639Node *Db::parseNestedName(NameState *State) {
2640 if (!consumeIf('N'))
2641 return nullptr;
Rafael Espindolab940b662016-09-06 19:16:48 +00002642
Erik Pilkingtonbb7feae2018-03-19 15:18:23 +00002643 Qualifiers CVTmp = parseCVQualifiers();
2644 if (State) State->CVQualifiers = CVTmp;
2645
2646 if (consumeIf('O')) {
2647 if (State) State->ReferenceQualifier = FrefQualRValue;
2648 } else if (consumeIf('R')) {
2649 if (State) State->ReferenceQualifier = FrefQualLValue;
2650 } else
2651 if (State) State->ReferenceQualifier = FrefQualNone;
2652
2653 Node *SoFar = nullptr;
2654 auto PushComponent = [&](Node *Comp) {
Erik Pilkingtonf2a9b0f2018-04-12 20:41:06 +00002655 if (SoFar) SoFar = make<NestedName>(SoFar, Comp);
Erik Pilkingtonbb7feae2018-03-19 15:18:23 +00002656 else SoFar = Comp;
2657 if (State) State->EndsWithTemplateArgs = false;
2658 };
2659
2660 if (consumeIf("St"))
2661 SoFar = make<NameType>("std");
2662
2663 while (!consumeIf('E')) {
2664 consumeIf('L'); // extension
2665
Erik Pilkington452e2ef2018-04-09 18:32:25 +00002666 // <data-member-prefix> := <member source-name> [<template-args>] M
2667 if (consumeIf('M')) {
2668 if (SoFar == nullptr)
2669 return nullptr;
2670 continue;
2671 }
2672
Erik Pilkingtonbb7feae2018-03-19 15:18:23 +00002673 // ::= <template-param>
2674 if (look() == 'T') {
2675 Node *TP = parseTemplateParam();
2676 if (TP == nullptr)
2677 return nullptr;
2678 PushComponent(TP);
2679 Subs.push_back(SoFar);
2680 continue;
Rafael Espindolab940b662016-09-06 19:16:48 +00002681 }
Erik Pilkingtonbb7feae2018-03-19 15:18:23 +00002682
2683 // ::= <template-prefix> <template-args>
2684 if (look() == 'I') {
Erik Pilkington8a1cb332018-03-25 22:50:33 +00002685 Node *TA = parseTemplateArgs(State != nullptr);
Erik Pilkingtonbb7feae2018-03-19 15:18:23 +00002686 if (TA == nullptr || SoFar == nullptr)
2687 return nullptr;
2688 SoFar = make<NameWithTemplateArgs>(SoFar, TA);
2689 if (State) State->EndsWithTemplateArgs = true;
2690 Subs.push_back(SoFar);
2691 continue;
Rafael Espindolab940b662016-09-06 19:16:48 +00002692 }
Erik Pilkingtonbb7feae2018-03-19 15:18:23 +00002693
2694 // ::= <decltype>
2695 if (look() == 'D' && (look(1) == 't' || look(1) == 'T')) {
2696 Node *DT = parseDecltype();
2697 if (DT == nullptr)
2698 return nullptr;
2699 PushComponent(DT);
2700 Subs.push_back(SoFar);
2701 continue;
Rafael Espindolab940b662016-09-06 19:16:48 +00002702 }
Erik Pilkingtonbb7feae2018-03-19 15:18:23 +00002703
2704 // ::= <substitution>
2705 if (look() == 'S' && look(1) != 't') {
2706 Node *S = parseSubstitution();
2707 if (S == nullptr)
2708 return nullptr;
2709 PushComponent(S);
2710 if (SoFar != S)
2711 Subs.push_back(S);
2712 continue;
Rafael Espindolab940b662016-09-06 19:16:48 +00002713 }
Erik Pilkingtonbb7feae2018-03-19 15:18:23 +00002714
2715 // Parse an <unqualified-name> thats actually a <ctor-dtor-name>.
2716 if (look() == 'C' || (look() == 'D' && look(1) != 'C')) {
2717 if (SoFar == nullptr)
2718 return nullptr;
2719 Node *CtorDtor = parseCtorDtorName(SoFar, State);
2720 if (CtorDtor == nullptr)
2721 return nullptr;
2722 PushComponent(CtorDtor);
2723 SoFar = parseAbiTags(SoFar);
2724 if (SoFar == nullptr)
2725 return nullptr;
2726 Subs.push_back(SoFar);
2727 continue;
2728 }
2729
2730 // ::= <prefix> <unqualified-name>
2731 Node *N = parseUnqualifiedName(State);
2732 if (N == nullptr)
2733 return nullptr;
2734 PushComponent(N);
2735 Subs.push_back(SoFar);
Rafael Espindolab940b662016-09-06 19:16:48 +00002736 }
Erik Pilkingtonbb7feae2018-03-19 15:18:23 +00002737
2738 if (SoFar == nullptr || Subs.empty())
2739 return nullptr;
2740
2741 Subs.pop_back();
2742 return SoFar;
Rafael Espindolab940b662016-09-06 19:16:48 +00002743}
2744
Erik Pilkingtonbb7feae2018-03-19 15:18:23 +00002745// <simple-id> ::= <source-name> [ <template-args> ]
2746Node *Db::parseSimpleId() {
2747 Node *SN = parseSourceName(/*NameState=*/nullptr);
2748 if (SN == nullptr)
2749 return nullptr;
2750 if (look() == 'I') {
2751 Node *TA = parseTemplateArgs();
2752 if (TA == nullptr)
2753 return nullptr;
2754 return make<NameWithTemplateArgs>(SN, TA);
Rafael Espindolab940b662016-09-06 19:16:48 +00002755 }
Erik Pilkingtonbb7feae2018-03-19 15:18:23 +00002756 return SN;
Rafael Espindolab940b662016-09-06 19:16:48 +00002757}
2758
Erik Pilkingtonbb7feae2018-03-19 15:18:23 +00002759// <destructor-name> ::= <unresolved-type> # e.g., ~T or ~decltype(f())
2760// ::= <simple-id> # e.g., ~A<2*N>
2761Node *Db::parseDestructorName() {
2762 Node *Result;
2763 if (std::isdigit(look()))
2764 Result = parseSimpleId();
2765 else
2766 Result = parseUnresolvedType();
2767 if (Result == nullptr)
2768 return nullptr;
2769 return make<DtorName>(Result);
Rafael Espindolab940b662016-09-06 19:16:48 +00002770}
2771
Erik Pilkingtonbb7feae2018-03-19 15:18:23 +00002772// <unresolved-type> ::= <template-param>
2773// ::= <decltype>
2774// ::= <substitution>
2775Node *Db::parseUnresolvedType() {
2776 if (look() == 'T') {
2777 Node *TP = parseTemplateParam();
2778 if (TP == nullptr)
2779 return nullptr;
2780 Subs.push_back(TP);
2781 return TP;
2782 }
2783 if (look() == 'D') {
2784 Node *DT = parseDecltype();
2785 if (DT == nullptr)
2786 return nullptr;
2787 Subs.push_back(DT);
2788 return DT;
2789 }
2790 return parseSubstitution();
2791}
Rafael Espindolab940b662016-09-06 19:16:48 +00002792
Erik Pilkingtonbb7feae2018-03-19 15:18:23 +00002793// <base-unresolved-name> ::= <simple-id> # unresolved name
2794// extension ::= <operator-name> # unresolved operator-function-id
2795// extension ::= <operator-name> <template-args> # unresolved operator template-id
2796// ::= on <operator-name> # unresolved operator-function-id
2797// ::= on <operator-name> <template-args> # unresolved operator template-id
2798// ::= dn <destructor-name> # destructor or pseudo-destructor;
2799// # e.g. ~X or ~X<N-1>
2800Node *Db::parseBaseUnresolvedName() {
2801 if (std::isdigit(look()))
2802 return parseSimpleId();
Rafael Espindolab940b662016-09-06 19:16:48 +00002803
Erik Pilkingtonbb7feae2018-03-19 15:18:23 +00002804 if (consumeIf("dn"))
2805 return parseDestructorName();
2806
2807 consumeIf("on");
2808
2809 Node *Oper = parseOperatorName(/*NameState=*/nullptr);
2810 if (Oper == nullptr)
2811 return nullptr;
2812 if (look() == 'I') {
2813 Node *TA = parseTemplateArgs();
2814 if (TA == nullptr)
2815 return nullptr;
2816 return make<NameWithTemplateArgs>(Oper, TA);
2817 }
2818 return Oper;
2819}
2820
2821// <unresolved-name>
2822// extension ::= srN <unresolved-type> [<template-args>] <unresolved-qualifier-level>* E <base-unresolved-name>
2823// ::= [gs] <base-unresolved-name> # x or (with "gs") ::x
Zachary Turnerfac2da12018-07-16 21:24:03 +00002824// ::= [gs] sr <unresolved-qualifier-level>+ E <base-unresolved-name>
Erik Pilkingtonbb7feae2018-03-19 15:18:23 +00002825// # A::x, N::y, A<T>::z; "gs" means leading "::"
2826// ::= sr <unresolved-type> <base-unresolved-name> # T::x / decltype(p)::x
2827// extension ::= sr <unresolved-type> <template-args> <base-unresolved-name>
2828// # T::N::x /decltype(p)::N::x
2829// (ignored) ::= srN <unresolved-type> <unresolved-qualifier-level>+ E <base-unresolved-name>
2830//
2831// <unresolved-qualifier-level> ::= <simple-id>
2832Node *Db::parseUnresolvedName() {
2833 Node *SoFar = nullptr;
2834
2835 // srN <unresolved-type> [<template-args>] <unresolved-qualifier-level>* E <base-unresolved-name>
2836 // srN <unresolved-type> <unresolved-qualifier-level>+ E <base-unresolved-name>
2837 if (consumeIf("srN")) {
2838 SoFar = parseUnresolvedType();
2839 if (SoFar == nullptr)
2840 return nullptr;
2841
2842 if (look() == 'I') {
2843 Node *TA = parseTemplateArgs();
2844 if (TA == nullptr)
2845 return nullptr;
2846 SoFar = make<NameWithTemplateArgs>(SoFar, TA);
2847 }
2848
2849 while (!consumeIf('E')) {
2850 Node *Qual = parseSimpleId();
2851 if (Qual == nullptr)
2852 return nullptr;
2853 SoFar = make<QualifiedName>(SoFar, Qual);
2854 }
2855
2856 Node *Base = parseBaseUnresolvedName();
2857 if (Base == nullptr)
2858 return nullptr;
2859 return make<QualifiedName>(SoFar, Base);
2860 }
2861
2862 bool Global = consumeIf("gs");
2863
2864 // [gs] <base-unresolved-name> # x or (with "gs") ::x
2865 if (!consumeIf("sr")) {
2866 SoFar = parseBaseUnresolvedName();
2867 if (SoFar == nullptr)
2868 return nullptr;
2869 if (Global)
2870 SoFar = make<GlobalQualifiedName>(SoFar);
2871 return SoFar;
2872 }
2873
Zachary Turnerfac2da12018-07-16 21:24:03 +00002874 // [gs] sr <unresolved-qualifier-level>+ E <base-unresolved-name>
Erik Pilkingtonbb7feae2018-03-19 15:18:23 +00002875 if (std::isdigit(look())) {
2876 do {
2877 Node *Qual = parseSimpleId();
2878 if (Qual == nullptr)
2879 return nullptr;
2880 if (SoFar)
2881 SoFar = make<QualifiedName>(SoFar, Qual);
2882 else if (Global)
2883 SoFar = make<GlobalQualifiedName>(Qual);
2884 else
2885 SoFar = Qual;
2886 } while (!consumeIf('E'));
2887 }
2888 // sr <unresolved-type> <base-unresolved-name>
2889 // sr <unresolved-type> <template-args> <base-unresolved-name>
2890 else {
2891 SoFar = parseUnresolvedType();
2892 if (SoFar == nullptr)
2893 return nullptr;
2894
2895 if (look() == 'I') {
2896 Node *TA = parseTemplateArgs();
2897 if (TA == nullptr)
2898 return nullptr;
2899 SoFar = make<NameWithTemplateArgs>(SoFar, TA);
2900 }
2901 }
2902
2903 assert(SoFar != nullptr);
2904
2905 Node *Base = parseBaseUnresolvedName();
2906 if (Base == nullptr)
2907 return nullptr;
2908 return make<QualifiedName>(SoFar, Base);
2909}
2910
2911// <abi-tags> ::= <abi-tag> [<abi-tags>]
2912// <abi-tag> ::= B <source-name>
2913Node *Db::parseAbiTags(Node *N) {
2914 while (consumeIf('B')) {
2915 StringView SN = parseBareSourceName();
2916 if (SN.empty())
2917 return nullptr;
2918 N = make<AbiTagAttr>(N, SN);
2919 }
2920 return N;
2921}
2922
2923// <number> ::= [n] <non-negative decimal integer>
2924StringView Db::parseNumber(bool AllowNegative) {
2925 const char *Tmp = First;
2926 if (AllowNegative)
2927 consumeIf('n');
2928 if (numLeft() == 0 || !std::isdigit(*First))
2929 return StringView();
2930 while (numLeft() != 0 && std::isdigit(*First))
2931 ++First;
2932 return StringView(Tmp, First);
2933}
2934
2935// <positive length number> ::= [0-9]*
2936bool Db::parsePositiveInteger(size_t *Out) {
2937 *Out = 0;
2938 if (look() < '0' || look() > '9')
2939 return true;
2940 while (look() >= '0' && look() <= '9') {
2941 *Out *= 10;
2942 *Out += static_cast<size_t>(consume() - '0');
2943 }
2944 return false;
2945}
2946
2947StringView Db::parseBareSourceName() {
2948 size_t Int = 0;
2949 if (parsePositiveInteger(&Int) || numLeft() < Int)
2950 return StringView();
2951 StringView R(First, First + Int);
2952 First += Int;
2953 return R;
2954}
2955
2956// <function-type> ::= [<CV-qualifiers>] [<exception-spec>] [Dx] F [Y] <bare-function-type> [<ref-qualifier>] E
2957//
2958// <exception-spec> ::= Do # non-throwing exception-specification (e.g., noexcept, throw())
2959// ::= DO <expression> E # computed (instantiation-dependent) noexcept
2960// ::= Dw <type>+ E # dynamic exception specification with instantiation-dependent types
2961//
2962// <ref-qualifier> ::= R # & ref-qualifier
2963// <ref-qualifier> ::= O # && ref-qualifier
2964Node *Db::parseFunctionType() {
2965 Qualifiers CVQuals = parseCVQualifiers();
2966
2967 Node *ExceptionSpec = nullptr;
2968 if (consumeIf("Do")) {
2969 ExceptionSpec = make<NameType>("noexcept");
2970 } else if (consumeIf("DO")) {
2971 Node *E = parseExpr();
2972 if (E == nullptr || !consumeIf('E'))
2973 return nullptr;
2974 ExceptionSpec = make<NoexceptSpec>(E);
2975 } else if (consumeIf("Dw")) {
2976 size_t SpecsBegin = Names.size();
2977 while (!consumeIf('E')) {
2978 Node *T = parseType();
2979 if (T == nullptr)
2980 return nullptr;
2981 Names.push_back(T);
2982 }
2983 ExceptionSpec =
2984 make<DynamicExceptionSpec>(popTrailingNodeArray(SpecsBegin));
2985 }
2986
2987 consumeIf("Dx"); // transaction safe
2988
2989 if (!consumeIf('F'))
2990 return nullptr;
2991 consumeIf('Y'); // extern "C"
2992 Node *ReturnType = parseType();
2993 if (ReturnType == nullptr)
2994 return nullptr;
2995
2996 FunctionRefQual ReferenceQualifier = FrefQualNone;
2997 size_t ParamsBegin = Names.size();
2998 while (true) {
2999 if (consumeIf('E'))
3000 break;
3001 if (consumeIf('v'))
3002 continue;
3003 if (consumeIf("RE")) {
3004 ReferenceQualifier = FrefQualLValue;
Rafael Espindolab940b662016-09-06 19:16:48 +00003005 break;
3006 }
Erik Pilkingtonbb7feae2018-03-19 15:18:23 +00003007 if (consumeIf("OE")) {
3008 ReferenceQualifier = FrefQualRValue;
Rafael Espindolab940b662016-09-06 19:16:48 +00003009 break;
3010 }
Erik Pilkingtonbb7feae2018-03-19 15:18:23 +00003011 Node *T = parseType();
3012 if (T == nullptr)
3013 return nullptr;
3014 Names.push_back(T);
3015 }
3016
3017 NodeArray Params = popTrailingNodeArray(ParamsBegin);
3018 return make<FunctionType>(ReturnType, Params, CVQuals,
3019 ReferenceQualifier, ExceptionSpec);
3020}
3021
3022// extension:
3023// <vector-type> ::= Dv <positive dimension number> _ <extended element type>
3024// ::= Dv [<dimension expression>] _ <element type>
3025// <extended element type> ::= <element type>
3026// ::= p # AltiVec vector pixel
3027Node *Db::parseVectorType() {
3028 if (!consumeIf("Dv"))
3029 return nullptr;
3030 if (look() >= '1' && look() <= '9') {
3031 StringView DimensionNumber = parseNumber();
3032 if (!consumeIf('_'))
3033 return nullptr;
3034 if (consumeIf('p'))
3035 return make<VectorType>(DimensionNumber);
3036 Node *ElemType = parseType();
3037 if (ElemType == nullptr)
3038 return nullptr;
3039 return make<VectorType>(ElemType, DimensionNumber);
3040 }
3041
3042 if (!consumeIf('_')) {
3043 Node *DimExpr = parseExpr();
3044 if (!DimExpr)
3045 return nullptr;
3046 if (!consumeIf('_'))
3047 return nullptr;
3048 Node *ElemType = parseType();
3049 if (!ElemType)
3050 return nullptr;
3051 return make<VectorType>(ElemType, DimExpr);
3052 }
3053 Node *ElemType = parseType();
3054 if (!ElemType)
3055 return nullptr;
3056 return make<VectorType>(ElemType, StringView());
3057}
3058
3059// <decltype> ::= Dt <expression> E # decltype of an id-expression or class member access (C++0x)
3060// ::= DT <expression> E # decltype of an expression (C++0x)
3061Node *Db::parseDecltype() {
3062 if (!consumeIf('D'))
3063 return nullptr;
3064 if (!consumeIf('t') && !consumeIf('T'))
3065 return nullptr;
3066 Node *E = parseExpr();
3067 if (E == nullptr)
3068 return nullptr;
3069 if (!consumeIf('E'))
3070 return nullptr;
3071 return make<EnclosingExpr>("decltype(", E, ")");
3072}
3073
3074// <array-type> ::= A <positive dimension number> _ <element type>
3075// ::= A [<dimension expression>] _ <element type>
3076Node *Db::parseArrayType() {
3077 if (!consumeIf('A'))
3078 return nullptr;
3079
3080 if (std::isdigit(look())) {
3081 StringView Dimension = parseNumber();
3082 if (!consumeIf('_'))
3083 return nullptr;
3084 Node *Ty = parseType();
3085 if (Ty == nullptr)
3086 return nullptr;
3087 return make<ArrayType>(Ty, Dimension);
3088 }
3089
3090 if (!consumeIf('_')) {
3091 Node *DimExpr = parseExpr();
3092 if (DimExpr == nullptr)
3093 return nullptr;
3094 if (!consumeIf('_'))
3095 return nullptr;
3096 Node *ElementType = parseType();
3097 if (ElementType == nullptr)
3098 return nullptr;
3099 return make<ArrayType>(ElementType, DimExpr);
3100 }
3101
3102 Node *Ty = parseType();
3103 if (Ty == nullptr)
3104 return nullptr;
3105 return make<ArrayType>(Ty);
3106}
3107
3108// <pointer-to-member-type> ::= M <class type> <member type>
3109Node *Db::parsePointerToMemberType() {
3110 if (!consumeIf('M'))
3111 return nullptr;
3112 Node *ClassType = parseType();
3113 if (ClassType == nullptr)
3114 return nullptr;
3115 Node *MemberType = parseType();
3116 if (MemberType == nullptr)
3117 return nullptr;
3118 return make<PointerToMemberType>(ClassType, MemberType);
3119}
3120
3121// <class-enum-type> ::= <name> # non-dependent type name, dependent type name, or dependent typename-specifier
3122// ::= Ts <name> # dependent elaborated type specifier using 'struct' or 'class'
3123// ::= Tu <name> # dependent elaborated type specifier using 'union'
3124// ::= Te <name> # dependent elaborated type specifier using 'enum'
3125Node *Db::parseClassEnumType() {
3126 StringView ElabSpef;
3127 if (consumeIf("Ts"))
3128 ElabSpef = "struct";
3129 else if (consumeIf("Tu"))
3130 ElabSpef = "union";
3131 else if (consumeIf("Te"))
3132 ElabSpef = "enum";
3133
3134 Node *Name = parseName();
3135 if (Name == nullptr)
3136 return nullptr;
3137
3138 if (!ElabSpef.empty())
3139 return make<ElaboratedTypeSpefType>(ElabSpef, Name);
3140
3141 return Name;
3142}
3143
3144// <qualified-type> ::= <qualifiers> <type>
3145// <qualifiers> ::= <extended-qualifier>* <CV-qualifiers>
3146// <extended-qualifier> ::= U <source-name> [<template-args>] # vendor extended type qualifier
3147Node *Db::parseQualifiedType() {
3148 if (consumeIf('U')) {
3149 StringView Qual = parseBareSourceName();
3150 if (Qual.empty())
3151 return nullptr;
3152
3153 // FIXME parse the optional <template-args> here!
3154
3155 // extension ::= U <objc-name> <objc-type> # objc-type<identifier>
3156 if (Qual.startsWith("objcproto")) {
3157 StringView ProtoSourceName = Qual.dropFront(std::strlen("objcproto"));
3158 StringView Proto;
3159 {
3160 SwapAndRestore<const char *> SaveFirst(First, ProtoSourceName.begin()),
3161 SaveLast(Last, ProtoSourceName.end());
3162 Proto = parseBareSourceName();
Rafael Espindolab940b662016-09-06 19:16:48 +00003163 }
Erik Pilkingtonbb7feae2018-03-19 15:18:23 +00003164 if (Proto.empty())
3165 return nullptr;
3166 Node *Child = parseQualifiedType();
3167 if (Child == nullptr)
3168 return nullptr;
3169 return make<ObjCProtoName>(Child, Proto);
3170 }
3171
3172 Node *Child = parseQualifiedType();
3173 if (Child == nullptr)
3174 return nullptr;
3175 return make<VendorExtQualType>(Child, Qual);
3176 }
3177
3178 Qualifiers Quals = parseCVQualifiers();
3179 Node *Ty = parseType();
3180 if (Ty == nullptr)
3181 return nullptr;
3182 if (Quals != QualNone)
3183 Ty = make<QualType>(Ty, Quals);
3184 return Ty;
3185}
3186
3187// <type> ::= <builtin-type>
3188// ::= <qualified-type>
3189// ::= <function-type>
3190// ::= <class-enum-type>
3191// ::= <array-type>
3192// ::= <pointer-to-member-type>
3193// ::= <template-param>
3194// ::= <template-template-param> <template-args>
3195// ::= <decltype>
3196// ::= P <type> # pointer
3197// ::= R <type> # l-value reference
3198// ::= O <type> # r-value reference (C++11)
3199// ::= C <type> # complex pair (C99)
3200// ::= G <type> # imaginary (C99)
3201// ::= <substitution> # See Compression below
3202// extension ::= U <objc-name> <objc-type> # objc-type<identifier>
3203// extension ::= <vector-type> # <vector-type> starts with Dv
3204//
3205// <objc-name> ::= <k0 number> objcproto <k1 number> <identifier> # k0 = 9 + <number of digits in k1> + k1
3206// <objc-type> ::= <source-name> # PU<11+>objcproto 11objc_object<source-name> 11objc_object -> id<source-name>
3207Node *Db::parseType() {
3208 Node *Result = nullptr;
3209
3210 switch (look()) {
3211 // ::= <qualified-type>
3212 case 'r':
3213 case 'V':
3214 case 'K': {
3215 unsigned AfterQuals = 0;
3216 if (look(AfterQuals) == 'r') ++AfterQuals;
3217 if (look(AfterQuals) == 'V') ++AfterQuals;
3218 if (look(AfterQuals) == 'K') ++AfterQuals;
3219
3220 if (look(AfterQuals) == 'F' ||
3221 (look(AfterQuals) == 'D' &&
3222 (look(AfterQuals + 1) == 'o' || look(AfterQuals + 1) == 'O' ||
3223 look(AfterQuals + 1) == 'w' || look(AfterQuals + 1) == 'x'))) {
3224 Result = parseFunctionType();
Rafael Espindolab940b662016-09-06 19:16:48 +00003225 break;
3226 }
Erik Pilkingtonbb7feae2018-03-19 15:18:23 +00003227 LLVM_FALLTHROUGH;
3228 }
3229 case 'U': {
3230 Result = parseQualifiedType();
3231 break;
3232 }
3233 // <builtin-type> ::= v # void
3234 case 'v':
3235 ++First;
3236 return make<NameType>("void");
3237 // ::= w # wchar_t
3238 case 'w':
3239 ++First;
3240 return make<NameType>("wchar_t");
3241 // ::= b # bool
3242 case 'b':
3243 ++First;
3244 return make<NameType>("bool");
3245 // ::= c # char
3246 case 'c':
3247 ++First;
3248 return make<NameType>("char");
3249 // ::= a # signed char
3250 case 'a':
3251 ++First;
3252 return make<NameType>("signed char");
3253 // ::= h # unsigned char
3254 case 'h':
3255 ++First;
3256 return make<NameType>("unsigned char");
3257 // ::= s # short
3258 case 's':
3259 ++First;
3260 return make<NameType>("short");
3261 // ::= t # unsigned short
3262 case 't':
3263 ++First;
3264 return make<NameType>("unsigned short");
3265 // ::= i # int
3266 case 'i':
3267 ++First;
3268 return make<NameType>("int");
3269 // ::= j # unsigned int
3270 case 'j':
3271 ++First;
3272 return make<NameType>("unsigned int");
3273 // ::= l # long
3274 case 'l':
3275 ++First;
3276 return make<NameType>("long");
3277 // ::= m # unsigned long
3278 case 'm':
3279 ++First;
3280 return make<NameType>("unsigned long");
3281 // ::= x # long long, __int64
3282 case 'x':
3283 ++First;
3284 return make<NameType>("long long");
3285 // ::= y # unsigned long long, __int64
3286 case 'y':
3287 ++First;
3288 return make<NameType>("unsigned long long");
3289 // ::= n # __int128
3290 case 'n':
3291 ++First;
3292 return make<NameType>("__int128");
3293 // ::= o # unsigned __int128
3294 case 'o':
3295 ++First;
3296 return make<NameType>("unsigned __int128");
3297 // ::= f # float
3298 case 'f':
3299 ++First;
3300 return make<NameType>("float");
3301 // ::= d # double
3302 case 'd':
3303 ++First;
3304 return make<NameType>("double");
3305 // ::= e # long double, __float80
3306 case 'e':
3307 ++First;
3308 return make<NameType>("long double");
3309 // ::= g # __float128
3310 case 'g':
3311 ++First;
3312 return make<NameType>("__float128");
3313 // ::= z # ellipsis
3314 case 'z':
3315 ++First;
3316 return make<NameType>("...");
3317
3318 // <builtin-type> ::= u <source-name> # vendor extended type
3319 case 'u': {
3320 ++First;
3321 StringView Res = parseBareSourceName();
3322 if (Res.empty())
3323 return nullptr;
3324 return make<NameType>(Res);
3325 }
3326 case 'D':
3327 switch (look(1)) {
3328 // ::= Dd # IEEE 754r decimal floating point (64 bits)
3329 case 'd':
3330 First += 2;
3331 return make<NameType>("decimal64");
3332 // ::= De # IEEE 754r decimal floating point (128 bits)
3333 case 'e':
3334 First += 2;
3335 return make<NameType>("decimal128");
3336 // ::= Df # IEEE 754r decimal floating point (32 bits)
3337 case 'f':
3338 First += 2;
3339 return make<NameType>("decimal32");
3340 // ::= Dh # IEEE 754r half-precision floating point (16 bits)
3341 case 'h':
3342 First += 2;
3343 return make<NameType>("decimal16");
3344 // ::= Di # char32_t
3345 case 'i':
3346 First += 2;
3347 return make<NameType>("char32_t");
3348 // ::= Ds # char16_t
3349 case 's':
3350 First += 2;
3351 return make<NameType>("char16_t");
3352 // ::= Da # auto (in dependent new-expressions)
3353 case 'a':
3354 First += 2;
3355 return make<NameType>("auto");
3356 // ::= Dc # decltype(auto)
3357 case 'c':
3358 First += 2;
3359 return make<NameType>("decltype(auto)");
3360 // ::= Dn # std::nullptr_t (i.e., decltype(nullptr))
3361 case 'n':
3362 First += 2;
3363 return make<NameType>("std::nullptr_t");
3364
3365 // ::= <decltype>
3366 case 't':
3367 case 'T': {
3368 Result = parseDecltype();
3369 break;
3370 }
3371 // extension ::= <vector-type> # <vector-type> starts with Dv
3372 case 'v': {
3373 Result = parseVectorType();
3374 break;
3375 }
3376 // ::= Dp <type> # pack expansion (C++0x)
3377 case 'p': {
3378 First += 2;
3379 Node *Child = parseType();
3380 if (!Child)
3381 return nullptr;
3382 Result = make<ParameterPackExpansion>(Child);
3383 break;
3384 }
3385 // Exception specifier on a function type.
3386 case 'o':
3387 case 'O':
3388 case 'w':
3389 // Transaction safe function type.
3390 case 'x':
3391 Result = parseFunctionType();
3392 break;
3393 }
3394 break;
3395 // ::= <function-type>
3396 case 'F': {
3397 Result = parseFunctionType();
3398 break;
3399 }
3400 // ::= <array-type>
3401 case 'A': {
3402 Result = parseArrayType();
3403 break;
3404 }
3405 // ::= <pointer-to-member-type>
3406 case 'M': {
3407 Result = parsePointerToMemberType();
3408 break;
3409 }
3410 // ::= <template-param>
3411 case 'T': {
3412 // This could be an elaborate type specifier on a <class-enum-type>.
3413 if (look(1) == 's' || look(1) == 'u' || look(1) == 'e') {
3414 Result = parseClassEnumType();
3415 break;
3416 }
3417
3418 Result = parseTemplateParam();
3419 if (Result == nullptr)
3420 return nullptr;
3421
3422 // Result could be either of:
3423 // <type> ::= <template-param>
3424 // <type> ::= <template-template-param> <template-args>
3425 //
3426 // <template-template-param> ::= <template-param>
3427 // ::= <substitution>
3428 //
3429 // If this is followed by some <template-args>, and we're permitted to
3430 // parse them, take the second production.
3431
3432 if (TryToParseTemplateArgs && look() == 'I') {
3433 Node *TA = parseTemplateArgs();
3434 if (TA == nullptr)
3435 return nullptr;
3436 Result = make<NameWithTemplateArgs>(Result, TA);
3437 }
3438 break;
3439 }
3440 // ::= P <type> # pointer
3441 case 'P': {
3442 ++First;
3443 Node *Ptr = parseType();
3444 if (Ptr == nullptr)
3445 return nullptr;
3446 Result = make<PointerType>(Ptr);
3447 break;
3448 }
3449 // ::= R <type> # l-value reference
3450 case 'R': {
3451 ++First;
3452 Node *Ref = parseType();
3453 if (Ref == nullptr)
3454 return nullptr;
Erik Pilkington3a6fed42018-07-27 17:27:40 +00003455 Result = make<ReferenceType>(Ref, ReferenceKind::LValue);
Erik Pilkingtonbb7feae2018-03-19 15:18:23 +00003456 break;
3457 }
3458 // ::= O <type> # r-value reference (C++11)
3459 case 'O': {
3460 ++First;
3461 Node *Ref = parseType();
3462 if (Ref == nullptr)
3463 return nullptr;
Erik Pilkington3a6fed42018-07-27 17:27:40 +00003464 Result = make<ReferenceType>(Ref, ReferenceKind::RValue);
Erik Pilkingtonbb7feae2018-03-19 15:18:23 +00003465 break;
3466 }
3467 // ::= C <type> # complex pair (C99)
3468 case 'C': {
3469 ++First;
3470 Node *P = parseType();
3471 if (P == nullptr)
3472 return nullptr;
3473 Result = make<PostfixQualifiedType>(P, " complex");
3474 break;
3475 }
3476 // ::= G <type> # imaginary (C99)
3477 case 'G': {
3478 ++First;
3479 Node *P = parseType();
3480 if (P == nullptr)
3481 return P;
3482 Result = make<PostfixQualifiedType>(P, " imaginary");
3483 break;
3484 }
3485 // ::= <substitution> # See Compression below
3486 case 'S': {
3487 if (look(1) && look(1) != 't') {
3488 Node *Sub = parseSubstitution();
3489 if (Sub == nullptr)
3490 return nullptr;
3491
3492 // Sub could be either of:
3493 // <type> ::= <substitution>
3494 // <type> ::= <template-template-param> <template-args>
3495 //
3496 // <template-template-param> ::= <template-param>
3497 // ::= <substitution>
3498 //
3499 // If this is followed by some <template-args>, and we're permitted to
3500 // parse them, take the second production.
3501
3502 if (TryToParseTemplateArgs && look() == 'I') {
3503 Node *TA = parseTemplateArgs();
3504 if (TA == nullptr)
3505 return nullptr;
3506 Result = make<NameWithTemplateArgs>(Sub, TA);
3507 break;
3508 }
3509
3510 // If all we parsed was a substitution, don't re-insert into the
3511 // substitution table.
3512 return Sub;
3513 }
3514 LLVM_FALLTHROUGH;
3515 }
3516 // ::= <class-enum-type>
3517 default: {
3518 Result = parseClassEnumType();
3519 break;
3520 }
3521 }
3522
3523 // If we parsed a type, insert it into the substitution table. Note that all
3524 // <builtin-type>s and <substitution>s have already bailed out, because they
3525 // don't get substitutions.
3526 if (Result != nullptr)
3527 Subs.push_back(Result);
3528 return Result;
3529}
3530
3531Node *Db::parsePrefixExpr(StringView Kind) {
3532 Node *E = parseExpr();
3533 if (E == nullptr)
3534 return nullptr;
3535 return make<PrefixExpr>(Kind, E);
3536}
3537
3538Node *Db::parseBinaryExpr(StringView Kind) {
3539 Node *LHS = parseExpr();
3540 if (LHS == nullptr)
3541 return nullptr;
3542 Node *RHS = parseExpr();
3543 if (RHS == nullptr)
3544 return nullptr;
3545 return make<BinaryExpr>(LHS, Kind, RHS);
3546}
3547
3548Node *Db::parseIntegerLiteral(StringView Lit) {
3549 StringView Tmp = parseNumber(true);
3550 if (!Tmp.empty() && consumeIf('E'))
3551 return make<IntegerExpr>(Lit, Tmp);
3552 return nullptr;
3553}
3554
3555// <CV-Qualifiers> ::= [r] [V] [K]
3556Qualifiers Db::parseCVQualifiers() {
3557 Qualifiers CVR = QualNone;
3558 if (consumeIf('r'))
3559 addQualifiers(CVR, QualRestrict);
3560 if (consumeIf('V'))
3561 addQualifiers(CVR, QualVolatile);
3562 if (consumeIf('K'))
3563 addQualifiers(CVR, QualConst);
3564 return CVR;
3565}
3566
3567// <function-param> ::= fp <top-level CV-Qualifiers> _ # L == 0, first parameter
3568// ::= fp <top-level CV-Qualifiers> <parameter-2 non-negative number> _ # L == 0, second and later parameters
3569// ::= fL <L-1 non-negative number> p <top-level CV-Qualifiers> _ # L > 0, first parameter
3570// ::= fL <L-1 non-negative number> p <top-level CV-Qualifiers> <parameter-2 non-negative number> _ # L > 0, second and later parameters
3571Node *Db::parseFunctionParam() {
3572 if (consumeIf("fp")) {
3573 parseCVQualifiers();
3574 StringView Num = parseNumber();
3575 if (!consumeIf('_'))
3576 return nullptr;
3577 return make<FunctionParam>(Num);
3578 }
3579 if (consumeIf("fL")) {
3580 if (parseNumber().empty())
3581 return nullptr;
3582 if (!consumeIf('p'))
3583 return nullptr;
3584 parseCVQualifiers();
3585 StringView Num = parseNumber();
3586 if (!consumeIf('_'))
3587 return nullptr;
3588 return make<FunctionParam>(Num);
3589 }
3590 return nullptr;
3591}
3592
3593// [gs] nw <expression>* _ <type> E # new (expr-list) type
3594// [gs] nw <expression>* _ <type> <initializer> # new (expr-list) type (init)
3595// [gs] na <expression>* _ <type> E # new[] (expr-list) type
3596// [gs] na <expression>* _ <type> <initializer> # new[] (expr-list) type (init)
3597// <initializer> ::= pi <expression>* E # parenthesized initialization
3598Node *Db::parseNewExpr() {
3599 bool Global = consumeIf("gs");
3600 bool IsArray = look(1) == 'a';
3601 if (!consumeIf("nw") && !consumeIf("na"))
3602 return nullptr;
3603 size_t Exprs = Names.size();
3604 while (!consumeIf('_')) {
3605 Node *Ex = parseExpr();
3606 if (Ex == nullptr)
3607 return nullptr;
3608 Names.push_back(Ex);
3609 }
3610 NodeArray ExprList = popTrailingNodeArray(Exprs);
3611 Node *Ty = parseType();
3612 if (Ty == nullptr)
3613 return Ty;
3614 if (consumeIf("pi")) {
3615 size_t InitsBegin = Names.size();
3616 while (!consumeIf('E')) {
3617 Node *Init = parseExpr();
3618 if (Init == nullptr)
3619 return Init;
3620 Names.push_back(Init);
3621 }
3622 NodeArray Inits = popTrailingNodeArray(InitsBegin);
3623 return make<NewExpr>(ExprList, Ty, Inits, Global, IsArray);
3624 } else if (!consumeIf('E'))
3625 return nullptr;
3626 return make<NewExpr>(ExprList, Ty, NodeArray(), Global, IsArray);
3627}
3628
3629// cv <type> <expression> # conversion with one argument
3630// cv <type> _ <expression>* E # conversion with a different number of arguments
3631Node *Db::parseConversionExpr() {
3632 if (!consumeIf("cv"))
3633 return nullptr;
3634 Node *Ty;
3635 {
3636 SwapAndRestore<bool> SaveTemp(TryToParseTemplateArgs, false);
3637 Ty = parseType();
3638 }
3639
3640 if (Ty == nullptr)
3641 return nullptr;
3642
3643 if (consumeIf('_')) {
3644 size_t ExprsBegin = Names.size();
3645 while (!consumeIf('E')) {
3646 Node *E = parseExpr();
3647 if (E == nullptr)
3648 return E;
3649 Names.push_back(E);
3650 }
3651 NodeArray Exprs = popTrailingNodeArray(ExprsBegin);
3652 return make<ConversionExpr>(Ty, Exprs);
3653 }
3654
3655 Node *E[1] = {parseExpr()};
3656 if (E[0] == nullptr)
3657 return nullptr;
3658 return make<ConversionExpr>(Ty, makeNodeArray(E, E + 1));
3659}
3660
3661// <expr-primary> ::= L <type> <value number> E # integer literal
3662// ::= L <type> <value float> E # floating literal
3663// ::= L <string type> E # string literal
3664// ::= L <nullptr type> E # nullptr literal (i.e., "LDnE")
3665// FIXME: ::= L <type> <real-part float> _ <imag-part float> E # complex floating point literal (C 2000)
3666// ::= L <mangled-name> E # external name
3667Node *Db::parseExprPrimary() {
3668 if (!consumeIf('L'))
3669 return nullptr;
3670 switch (look()) {
3671 case 'w':
3672 ++First;
3673 return parseIntegerLiteral("wchar_t");
3674 case 'b':
3675 if (consumeIf("b0E"))
3676 return make<BoolExpr>(0);
3677 if (consumeIf("b1E"))
3678 return make<BoolExpr>(1);
3679 return nullptr;
3680 case 'c':
3681 ++First;
3682 return parseIntegerLiteral("char");
3683 case 'a':
3684 ++First;
3685 return parseIntegerLiteral("signed char");
3686 case 'h':
3687 ++First;
3688 return parseIntegerLiteral("unsigned char");
3689 case 's':
3690 ++First;
3691 return parseIntegerLiteral("short");
3692 case 't':
3693 ++First;
3694 return parseIntegerLiteral("unsigned short");
3695 case 'i':
3696 ++First;
3697 return parseIntegerLiteral("");
3698 case 'j':
3699 ++First;
3700 return parseIntegerLiteral("u");
3701 case 'l':
3702 ++First;
3703 return parseIntegerLiteral("l");
3704 case 'm':
3705 ++First;
3706 return parseIntegerLiteral("ul");
3707 case 'x':
3708 ++First;
3709 return parseIntegerLiteral("ll");
3710 case 'y':
3711 ++First;
3712 return parseIntegerLiteral("ull");
3713 case 'n':
3714 ++First;
3715 return parseIntegerLiteral("__int128");
3716 case 'o':
3717 ++First;
3718 return parseIntegerLiteral("unsigned __int128");
3719 case 'f':
3720 ++First;
3721 return parseFloatingLiteral<float>();
3722 case 'd':
3723 ++First;
3724 return parseFloatingLiteral<double>();
3725 case 'e':
3726 ++First;
3727 return parseFloatingLiteral<long double>();
3728 case '_':
3729 if (consumeIf("_Z")) {
3730 Node *R = parseEncoding();
3731 if (R != nullptr && consumeIf('E'))
3732 return R;
3733 }
3734 return nullptr;
3735 case 'T':
3736 // Invalid mangled name per
3737 // http://sourcerytools.com/pipermail/cxx-abi-dev/2011-August/002422.html
3738 return nullptr;
3739 default: {
3740 // might be named type
3741 Node *T = parseType();
3742 if (T == nullptr)
3743 return nullptr;
3744 StringView N = parseNumber();
3745 if (!N.empty()) {
3746 if (!consumeIf('E'))
3747 return nullptr;
3748 return make<IntegerCastExpr>(T, N);
3749 }
3750 if (consumeIf('E'))
3751 return T;
3752 return nullptr;
3753 }
3754 }
3755}
3756
3757// <braced-expression> ::= <expression>
3758// ::= di <field source-name> <braced-expression> # .name = expr
3759// ::= dx <index expression> <braced-expression> # [expr] = expr
3760// ::= dX <range begin expression> <range end expression> <braced-expression>
3761Node *Db::parseBracedExpr() {
3762 if (look() == 'd') {
3763 switch (look(1)) {
3764 case 'i': {
3765 First += 2;
3766 Node *Field = parseSourceName(/*NameState=*/nullptr);
3767 if (Field == nullptr)
3768 return nullptr;
3769 Node *Init = parseBracedExpr();
3770 if (Init == nullptr)
3771 return nullptr;
3772 return make<BracedExpr>(Field, Init, /*isArray=*/false);
3773 }
3774 case 'x': {
3775 First += 2;
3776 Node *Index = parseExpr();
3777 if (Index == nullptr)
3778 return nullptr;
3779 Node *Init = parseBracedExpr();
3780 if (Init == nullptr)
3781 return nullptr;
3782 return make<BracedExpr>(Index, Init, /*isArray=*/true);
3783 }
3784 case 'X': {
3785 First += 2;
3786 Node *RangeBegin = parseExpr();
3787 if (RangeBegin == nullptr)
3788 return nullptr;
3789 Node *RangeEnd = parseExpr();
3790 if (RangeEnd == nullptr)
3791 return nullptr;
3792 Node *Init = parseBracedExpr();
3793 if (Init == nullptr)
3794 return nullptr;
3795 return make<BracedRangeExpr>(RangeBegin, RangeEnd, Init);
3796 }
Rafael Espindolab940b662016-09-06 19:16:48 +00003797 }
3798 }
Erik Pilkingtonbb7feae2018-03-19 15:18:23 +00003799 return parseExpr();
3800}
3801
Erik Pilkingtond43931d2018-04-09 18:33:01 +00003802// (not yet in the spec)
3803// <fold-expr> ::= fL <binary-operator-name> <expression> <expression>
3804// ::= fR <binary-operator-name> <expression> <expression>
3805// ::= fl <binary-operator-name> <expression>
3806// ::= fr <binary-operator-name> <expression>
3807Node *Db::parseFoldExpr() {
3808 if (!consumeIf('f'))
3809 return nullptr;
3810
3811 char FoldKind = look();
3812 bool IsLeftFold, HasInitializer;
3813 HasInitializer = FoldKind == 'L' || FoldKind == 'R';
3814 if (FoldKind == 'l' || FoldKind == 'L')
3815 IsLeftFold = true;
3816 else if (FoldKind == 'r' || FoldKind == 'R')
3817 IsLeftFold = false;
3818 else
3819 return nullptr;
3820 ++First;
3821
3822 // FIXME: This map is duplicated in parseOperatorName and parseExpr.
3823 StringView OperatorName;
3824 if (consumeIf("aa")) OperatorName = "&&";
3825 else if (consumeIf("an")) OperatorName = "&";
3826 else if (consumeIf("aN")) OperatorName = "&=";
3827 else if (consumeIf("aS")) OperatorName = "=";
3828 else if (consumeIf("cm")) OperatorName = ",";
3829 else if (consumeIf("ds")) OperatorName = ".*";
3830 else if (consumeIf("dv")) OperatorName = "/";
3831 else if (consumeIf("dV")) OperatorName = "/=";
3832 else if (consumeIf("eo")) OperatorName = "^";
3833 else if (consumeIf("eO")) OperatorName = "^=";
3834 else if (consumeIf("eq")) OperatorName = "==";
3835 else if (consumeIf("ge")) OperatorName = ">=";
3836 else if (consumeIf("gt")) OperatorName = ">";
3837 else if (consumeIf("le")) OperatorName = "<=";
3838 else if (consumeIf("ls")) OperatorName = "<<";
3839 else if (consumeIf("lS")) OperatorName = "<<=";
3840 else if (consumeIf("lt")) OperatorName = "<";
3841 else if (consumeIf("mi")) OperatorName = "-";
3842 else if (consumeIf("mI")) OperatorName = "-=";
3843 else if (consumeIf("ml")) OperatorName = "*";
3844 else if (consumeIf("mL")) OperatorName = "*=";
3845 else if (consumeIf("ne")) OperatorName = "!=";
3846 else if (consumeIf("oo")) OperatorName = "||";
3847 else if (consumeIf("or")) OperatorName = "|";
3848 else if (consumeIf("oR")) OperatorName = "|=";
3849 else if (consumeIf("pl")) OperatorName = "+";
3850 else if (consumeIf("pL")) OperatorName = "+=";
3851 else if (consumeIf("rm")) OperatorName = "%";
3852 else if (consumeIf("rM")) OperatorName = "%=";
3853 else if (consumeIf("rs")) OperatorName = ">>";
3854 else if (consumeIf("rS")) OperatorName = ">>=";
3855 else return nullptr;
3856
3857 Node *Pack = parseExpr(), *Init = nullptr;
3858 if (Pack == nullptr)
3859 return nullptr;
3860 if (HasInitializer) {
3861 Init = parseExpr();
3862 if (Init == nullptr)
3863 return nullptr;
3864 }
3865
3866 if (IsLeftFold && Init)
3867 std::swap(Pack, Init);
3868
3869 return make<FoldExpr>(IsLeftFold, OperatorName, Pack, Init);
3870}
3871
Erik Pilkingtonbb7feae2018-03-19 15:18:23 +00003872// <expression> ::= <unary operator-name> <expression>
3873// ::= <binary operator-name> <expression> <expression>
3874// ::= <ternary operator-name> <expression> <expression> <expression>
3875// ::= cl <expression>+ E # call
3876// ::= cv <type> <expression> # conversion with one argument
3877// ::= cv <type> _ <expression>* E # conversion with a different number of arguments
3878// ::= [gs] nw <expression>* _ <type> E # new (expr-list) type
3879// ::= [gs] nw <expression>* _ <type> <initializer> # new (expr-list) type (init)
3880// ::= [gs] na <expression>* _ <type> E # new[] (expr-list) type
3881// ::= [gs] na <expression>* _ <type> <initializer> # new[] (expr-list) type (init)
3882// ::= [gs] dl <expression> # delete expression
3883// ::= [gs] da <expression> # delete[] expression
3884// ::= pp_ <expression> # prefix ++
3885// ::= mm_ <expression> # prefix --
3886// ::= ti <type> # typeid (type)
3887// ::= te <expression> # typeid (expression)
3888// ::= dc <type> <expression> # dynamic_cast<type> (expression)
3889// ::= sc <type> <expression> # static_cast<type> (expression)
3890// ::= cc <type> <expression> # const_cast<type> (expression)
3891// ::= rc <type> <expression> # reinterpret_cast<type> (expression)
3892// ::= st <type> # sizeof (a type)
3893// ::= sz <expression> # sizeof (an expression)
3894// ::= at <type> # alignof (a type)
3895// ::= az <expression> # alignof (an expression)
3896// ::= nx <expression> # noexcept (expression)
3897// ::= <template-param>
3898// ::= <function-param>
3899// ::= dt <expression> <unresolved-name> # expr.name
3900// ::= pt <expression> <unresolved-name> # expr->name
3901// ::= ds <expression> <expression> # expr.*expr
3902// ::= sZ <template-param> # size of a parameter pack
3903// ::= sZ <function-param> # size of a function parameter pack
Erik Pilkington650130a2018-04-09 18:31:50 +00003904// ::= sP <template-arg>* E # sizeof...(T), size of a captured template parameter pack from an alias template
Erik Pilkingtonbb7feae2018-03-19 15:18:23 +00003905// ::= sp <expression> # pack expansion
3906// ::= tw <expression> # throw expression
3907// ::= tr # throw with no operand (rethrow)
3908// ::= <unresolved-name> # f(p), N::f(p), ::f(p),
3909// # freestanding dependent name (e.g., T::x),
3910// # objectless nonstatic member reference
3911// ::= fL <binary-operator-name> <expression> <expression>
3912// ::= fR <binary-operator-name> <expression> <expression>
3913// ::= fl <binary-operator-name> <expression>
3914// ::= fr <binary-operator-name> <expression>
3915// ::= <expr-primary>
3916Node *Db::parseExpr() {
3917 bool Global = consumeIf("gs");
3918 if (numLeft() < 2)
3919 return nullptr;
3920
3921 switch (*First) {
3922 case 'L':
3923 return parseExprPrimary();
3924 case 'T':
3925 return parseTemplateParam();
Erik Pilkingtond43931d2018-04-09 18:33:01 +00003926 case 'f': {
3927 // Disambiguate a fold expression from a <function-param>.
3928 if (look(1) == 'p' || (look(1) == 'L' && std::isdigit(look(2))))
3929 return parseFunctionParam();
3930 return parseFoldExpr();
3931 }
Erik Pilkingtonbb7feae2018-03-19 15:18:23 +00003932 case 'a':
3933 switch (First[1]) {
3934 case 'a':
3935 First += 2;
3936 return parseBinaryExpr("&&");
3937 case 'd':
3938 First += 2;
3939 return parsePrefixExpr("&");
3940 case 'n':
3941 First += 2;
3942 return parseBinaryExpr("&");
3943 case 'N':
3944 First += 2;
3945 return parseBinaryExpr("&=");
3946 case 'S':
3947 First += 2;
3948 return parseBinaryExpr("=");
3949 case 't': {
3950 First += 2;
3951 Node *Ty = parseType();
3952 if (Ty == nullptr)
3953 return nullptr;
3954 return make<EnclosingExpr>("alignof (", Ty, ")");
3955 }
3956 case 'z': {
3957 First += 2;
3958 Node *Ty = parseExpr();
3959 if (Ty == nullptr)
3960 return nullptr;
3961 return make<EnclosingExpr>("alignof (", Ty, ")");
3962 }
3963 }
3964 return nullptr;
3965 case 'c':
3966 switch (First[1]) {
3967 // cc <type> <expression> # const_cast<type>(expression)
3968 case 'c': {
3969 First += 2;
3970 Node *Ty = parseType();
3971 if (Ty == nullptr)
3972 return Ty;
3973 Node *Ex = parseExpr();
3974 if (Ex == nullptr)
3975 return Ex;
3976 return make<CastExpr>("const_cast", Ty, Ex);
3977 }
3978 // cl <expression>+ E # call
3979 case 'l': {
3980 First += 2;
3981 Node *Callee = parseExpr();
3982 if (Callee == nullptr)
3983 return Callee;
3984 size_t ExprsBegin = Names.size();
3985 while (!consumeIf('E')) {
3986 Node *E = parseExpr();
3987 if (E == nullptr)
3988 return E;
3989 Names.push_back(E);
3990 }
3991 return make<CallExpr>(Callee, popTrailingNodeArray(ExprsBegin));
3992 }
3993 case 'm':
3994 First += 2;
3995 return parseBinaryExpr(",");
3996 case 'o':
3997 First += 2;
3998 return parsePrefixExpr("~");
3999 case 'v':
4000 return parseConversionExpr();
4001 }
4002 return nullptr;
4003 case 'd':
4004 switch (First[1]) {
4005 case 'a': {
4006 First += 2;
4007 Node *Ex = parseExpr();
4008 if (Ex == nullptr)
4009 return Ex;
4010 return make<DeleteExpr>(Ex, Global, /*is_array=*/true);
4011 }
4012 case 'c': {
4013 First += 2;
4014 Node *T = parseType();
4015 if (T == nullptr)
4016 return T;
4017 Node *Ex = parseExpr();
4018 if (Ex == nullptr)
4019 return Ex;
4020 return make<CastExpr>("dynamic_cast", T, Ex);
4021 }
4022 case 'e':
4023 First += 2;
4024 return parsePrefixExpr("*");
4025 case 'l': {
4026 First += 2;
4027 Node *E = parseExpr();
4028 if (E == nullptr)
4029 return E;
4030 return make<DeleteExpr>(E, Global, /*is_array=*/false);
4031 }
4032 case 'n':
4033 return parseUnresolvedName();
4034 case 's': {
4035 First += 2;
4036 Node *LHS = parseExpr();
4037 if (LHS == nullptr)
4038 return nullptr;
4039 Node *RHS = parseExpr();
4040 if (RHS == nullptr)
4041 return nullptr;
4042 return make<MemberExpr>(LHS, ".*", RHS);
4043 }
4044 case 't': {
4045 First += 2;
4046 Node *LHS = parseExpr();
4047 if (LHS == nullptr)
4048 return LHS;
4049 Node *RHS = parseExpr();
4050 if (RHS == nullptr)
4051 return nullptr;
4052 return make<MemberExpr>(LHS, ".", RHS);
4053 }
4054 case 'v':
4055 First += 2;
4056 return parseBinaryExpr("/");
4057 case 'V':
4058 First += 2;
4059 return parseBinaryExpr("/=");
4060 }
4061 return nullptr;
4062 case 'e':
4063 switch (First[1]) {
4064 case 'o':
4065 First += 2;
4066 return parseBinaryExpr("^");
4067 case 'O':
4068 First += 2;
4069 return parseBinaryExpr("^=");
4070 case 'q':
4071 First += 2;
4072 return parseBinaryExpr("==");
4073 }
4074 return nullptr;
4075 case 'g':
4076 switch (First[1]) {
4077 case 'e':
4078 First += 2;
4079 return parseBinaryExpr(">=");
4080 case 't':
4081 First += 2;
4082 return parseBinaryExpr(">");
4083 }
4084 return nullptr;
4085 case 'i':
4086 switch (First[1]) {
4087 case 'x': {
4088 First += 2;
4089 Node *Base = parseExpr();
4090 if (Base == nullptr)
4091 return nullptr;
4092 Node *Index = parseExpr();
4093 if (Index == nullptr)
4094 return Index;
4095 return make<ArraySubscriptExpr>(Base, Index);
4096 }
4097 case 'l': {
4098 First += 2;
4099 size_t InitsBegin = Names.size();
4100 while (!consumeIf('E')) {
4101 Node *E = parseBracedExpr();
4102 if (E == nullptr)
4103 return nullptr;
4104 Names.push_back(E);
4105 }
4106 return make<InitListExpr>(nullptr, popTrailingNodeArray(InitsBegin));
4107 }
4108 }
4109 return nullptr;
4110 case 'l':
4111 switch (First[1]) {
4112 case 'e':
4113 First += 2;
4114 return parseBinaryExpr("<=");
4115 case 's':
4116 First += 2;
4117 return parseBinaryExpr("<<");
4118 case 'S':
4119 First += 2;
4120 return parseBinaryExpr("<<=");
4121 case 't':
4122 First += 2;
4123 return parseBinaryExpr("<");
4124 }
4125 return nullptr;
4126 case 'm':
4127 switch (First[1]) {
4128 case 'i':
4129 First += 2;
4130 return parseBinaryExpr("-");
4131 case 'I':
4132 First += 2;
4133 return parseBinaryExpr("-=");
4134 case 'l':
4135 First += 2;
4136 return parseBinaryExpr("*");
4137 case 'L':
4138 First += 2;
4139 return parseBinaryExpr("*=");
4140 case 'm':
4141 First += 2;
4142 if (consumeIf('_'))
4143 return parsePrefixExpr("--");
4144 Node *Ex = parseExpr();
4145 if (Ex == nullptr)
4146 return nullptr;
4147 return make<PostfixExpr>(Ex, "--");
4148 }
4149 return nullptr;
4150 case 'n':
4151 switch (First[1]) {
4152 case 'a':
4153 case 'w':
4154 return parseNewExpr();
4155 case 'e':
4156 First += 2;
4157 return parseBinaryExpr("!=");
4158 case 'g':
4159 First += 2;
4160 return parsePrefixExpr("-");
4161 case 't':
4162 First += 2;
4163 return parsePrefixExpr("!");
4164 case 'x':
4165 First += 2;
4166 Node *Ex = parseExpr();
4167 if (Ex == nullptr)
4168 return Ex;
4169 return make<EnclosingExpr>("noexcept (", Ex, ")");
4170 }
4171 return nullptr;
4172 case 'o':
4173 switch (First[1]) {
4174 case 'n':
4175 return parseUnresolvedName();
4176 case 'o':
4177 First += 2;
4178 return parseBinaryExpr("||");
4179 case 'r':
4180 First += 2;
4181 return parseBinaryExpr("|");
4182 case 'R':
4183 First += 2;
4184 return parseBinaryExpr("|=");
4185 }
4186 return nullptr;
4187 case 'p':
4188 switch (First[1]) {
4189 case 'm':
4190 First += 2;
4191 return parseBinaryExpr("->*");
4192 case 'l':
4193 First += 2;
4194 return parseBinaryExpr("+");
4195 case 'L':
4196 First += 2;
4197 return parseBinaryExpr("+=");
4198 case 'p': {
4199 First += 2;
4200 if (consumeIf('_'))
4201 return parsePrefixExpr("++");
4202 Node *Ex = parseExpr();
4203 if (Ex == nullptr)
4204 return Ex;
4205 return make<PostfixExpr>(Ex, "++");
4206 }
4207 case 's':
4208 First += 2;
4209 return parsePrefixExpr("+");
4210 case 't': {
4211 First += 2;
4212 Node *L = parseExpr();
4213 if (L == nullptr)
4214 return nullptr;
4215 Node *R = parseExpr();
4216 if (R == nullptr)
4217 return nullptr;
4218 return make<MemberExpr>(L, "->", R);
4219 }
4220 }
4221 return nullptr;
4222 case 'q':
4223 if (First[1] == 'u') {
4224 First += 2;
4225 Node *Cond = parseExpr();
4226 if (Cond == nullptr)
4227 return nullptr;
4228 Node *LHS = parseExpr();
4229 if (LHS == nullptr)
4230 return nullptr;
4231 Node *RHS = parseExpr();
4232 if (RHS == nullptr)
4233 return nullptr;
4234 return make<ConditionalExpr>(Cond, LHS, RHS);
4235 }
4236 return nullptr;
4237 case 'r':
4238 switch (First[1]) {
4239 case 'c': {
4240 First += 2;
4241 Node *T = parseType();
4242 if (T == nullptr)
4243 return T;
4244 Node *Ex = parseExpr();
4245 if (Ex == nullptr)
4246 return Ex;
4247 return make<CastExpr>("reinterpret_cast", T, Ex);
4248 }
4249 case 'm':
4250 First += 2;
4251 return parseBinaryExpr("%");
4252 case 'M':
4253 First += 2;
4254 return parseBinaryExpr("%=");
4255 case 's':
4256 First += 2;
4257 return parseBinaryExpr(">>");
4258 case 'S':
4259 First += 2;
4260 return parseBinaryExpr(">>=");
4261 }
4262 return nullptr;
4263 case 's':
4264 switch (First[1]) {
4265 case 'c': {
4266 First += 2;
4267 Node *T = parseType();
4268 if (T == nullptr)
4269 return T;
4270 Node *Ex = parseExpr();
4271 if (Ex == nullptr)
4272 return Ex;
4273 return make<CastExpr>("static_cast", T, Ex);
4274 }
4275 case 'p': {
4276 First += 2;
4277 Node *Child = parseExpr();
4278 if (Child == nullptr)
4279 return nullptr;
4280 return make<ParameterPackExpansion>(Child);
4281 }
4282 case 'r':
4283 return parseUnresolvedName();
4284 case 't': {
4285 First += 2;
4286 Node *Ty = parseType();
4287 if (Ty == nullptr)
4288 return Ty;
4289 return make<EnclosingExpr>("sizeof (", Ty, ")");
4290 }
4291 case 'z': {
4292 First += 2;
4293 Node *Ex = parseExpr();
4294 if (Ex == nullptr)
4295 return Ex;
4296 return make<EnclosingExpr>("sizeof (", Ex, ")");
4297 }
4298 case 'Z':
4299 First += 2;
4300 if (look() == 'T') {
4301 Node *R = parseTemplateParam();
4302 if (R == nullptr)
4303 return nullptr;
4304 return make<SizeofParamPackExpr>(R);
4305 } else if (look() == 'f') {
4306 Node *FP = parseFunctionParam();
4307 if (FP == nullptr)
4308 return nullptr;
Erik Pilkington650130a2018-04-09 18:31:50 +00004309 return make<EnclosingExpr>("sizeof... (", FP, ")");
Erik Pilkingtonbb7feae2018-03-19 15:18:23 +00004310 }
4311 return nullptr;
Erik Pilkington650130a2018-04-09 18:31:50 +00004312 case 'P': {
4313 First += 2;
4314 size_t ArgsBegin = Names.size();
4315 while (!consumeIf('E')) {
4316 Node *Arg = parseTemplateArg();
4317 if (Arg == nullptr)
4318 return nullptr;
4319 Names.push_back(Arg);
4320 }
4321 return make<EnclosingExpr>(
4322 "sizeof... (", make<NodeArrayNode>(popTrailingNodeArray(ArgsBegin)),
4323 ")");
4324 }
Erik Pilkingtonbb7feae2018-03-19 15:18:23 +00004325 }
4326 return nullptr;
4327 case 't':
4328 switch (First[1]) {
4329 case 'e': {
4330 First += 2;
4331 Node *Ex = parseExpr();
4332 if (Ex == nullptr)
4333 return Ex;
4334 return make<EnclosingExpr>("typeid (", Ex, ")");
4335 }
4336 case 'i': {
4337 First += 2;
4338 Node *Ty = parseType();
4339 if (Ty == nullptr)
4340 return Ty;
4341 return make<EnclosingExpr>("typeid (", Ty, ")");
4342 }
4343 case 'l': {
4344 First += 2;
4345 Node *Ty = parseType();
4346 if (Ty == nullptr)
4347 return nullptr;
4348 size_t InitsBegin = Names.size();
4349 while (!consumeIf('E')) {
4350 Node *E = parseBracedExpr();
4351 if (E == nullptr)
4352 return nullptr;
4353 Names.push_back(E);
4354 }
4355 return make<InitListExpr>(Ty, popTrailingNodeArray(InitsBegin));
4356 }
4357 case 'r':
4358 First += 2;
4359 return make<NameType>("throw");
4360 case 'w': {
4361 First += 2;
4362 Node *Ex = parseExpr();
4363 if (Ex == nullptr)
4364 return nullptr;
4365 return make<ThrowExpr>(Ex);
4366 }
4367 }
4368 return nullptr;
4369 case '1':
4370 case '2':
4371 case '3':
4372 case '4':
4373 case '5':
4374 case '6':
4375 case '7':
4376 case '8':
4377 case '9':
4378 return parseUnresolvedName();
4379 }
4380 return nullptr;
Rafael Espindolab940b662016-09-06 19:16:48 +00004381}
4382
4383// <call-offset> ::= h <nv-offset> _
4384// ::= v <v-offset> _
4385//
4386// <nv-offset> ::= <offset number>
4387// # non-virtual base override
4388//
4389// <v-offset> ::= <offset number> _ <virtual offset number>
4390// # virtual base override, with vcall offset
Erik Pilkingtonbb7feae2018-03-19 15:18:23 +00004391bool Db::parseCallOffset() {
4392 // Just scan through the call offset, we never add this information into the
4393 // output.
4394 if (consumeIf('h'))
4395 return parseNumber(true).empty() || !consumeIf('_');
4396 if (consumeIf('v'))
4397 return parseNumber(true).empty() || !consumeIf('_') ||
4398 parseNumber(true).empty() || !consumeIf('_');
4399 return true;
Rafael Espindolab940b662016-09-06 19:16:48 +00004400}
4401
4402// <special-name> ::= TV <type> # virtual table
4403// ::= TT <type> # VTT structure (construction vtable index)
4404// ::= TI <type> # typeinfo structure
4405// ::= TS <type> # typeinfo name (null-terminated byte string)
4406// ::= Tc <call-offset> <call-offset> <base encoding>
4407// # base is the nominal target function of thunk
4408// # first call-offset is 'this' adjustment
4409// # second call-offset is result adjustment
4410// ::= T <call-offset> <base encoding>
4411// # base is the nominal target function of thunk
Erik Pilkingtonbb7feae2018-03-19 15:18:23 +00004412// ::= GV <object name> # Guard variable for one-time initialization
Rafael Espindolab940b662016-09-06 19:16:48 +00004413// # No <type>
David Bozier60b80d22017-01-31 15:56:36 +00004414// ::= TW <object name> # Thread-local wrapper
4415// ::= TH <object name> # Thread-local initialization
Erik Pilkingtonbb7feae2018-03-19 15:18:23 +00004416// ::= GR <object name> _ # First temporary
4417// ::= GR <object name> <seq-id> _ # Subsequent temporaries
4418// extension ::= TC <first type> <number> _ <second type> # construction vtable for second-in-first
Rafael Espindolab940b662016-09-06 19:16:48 +00004419// extension ::= GR <object name> # reference temporary for object
Erik Pilkingtonbb7feae2018-03-19 15:18:23 +00004420Node *Db::parseSpecialName() {
4421 switch (look()) {
4422 case 'T':
4423 switch (look(1)) {
4424 // TV <type> # virtual table
4425 case 'V': {
4426 First += 2;
4427 Node *Ty = parseType();
4428 if (Ty == nullptr)
4429 return nullptr;
4430 return make<SpecialName>("vtable for ", Ty);
4431 }
4432 // TT <type> # VTT structure (construction vtable index)
4433 case 'T': {
4434 First += 2;
4435 Node *Ty = parseType();
4436 if (Ty == nullptr)
4437 return nullptr;
4438 return make<SpecialName>("VTT for ", Ty);
4439 }
4440 // TI <type> # typeinfo structure
4441 case 'I': {
4442 First += 2;
4443 Node *Ty = parseType();
4444 if (Ty == nullptr)
4445 return nullptr;
4446 return make<SpecialName>("typeinfo for ", Ty);
4447 }
4448 // TS <type> # typeinfo name (null-terminated byte string)
4449 case 'S': {
4450 First += 2;
4451 Node *Ty = parseType();
4452 if (Ty == nullptr)
4453 return nullptr;
4454 return make<SpecialName>("typeinfo name for ", Ty);
4455 }
4456 // Tc <call-offset> <call-offset> <base encoding>
4457 case 'c': {
4458 First += 2;
4459 if (parseCallOffset() || parseCallOffset())
4460 return nullptr;
4461 Node *Encoding = parseEncoding();
4462 if (Encoding == nullptr)
4463 return nullptr;
4464 return make<SpecialName>("covariant return thunk to ", Encoding);
4465 }
4466 // extension ::= TC <first type> <number> _ <second type>
4467 // # construction vtable for second-in-first
4468 case 'C': {
4469 First += 2;
4470 Node *FirstType = parseType();
4471 if (FirstType == nullptr)
4472 return nullptr;
4473 if (parseNumber(true).empty() || !consumeIf('_'))
4474 return nullptr;
4475 Node *SecondType = parseType();
4476 if (SecondType == nullptr)
4477 return nullptr;
4478 return make<CtorVtableSpecialName>(SecondType, FirstType);
4479 }
4480 // TW <object name> # Thread-local wrapper
4481 case 'W': {
4482 First += 2;
4483 Node *Name = parseName();
4484 if (Name == nullptr)
4485 return nullptr;
4486 return make<SpecialName>("thread-local wrapper routine for ", Name);
4487 }
4488 // TH <object name> # Thread-local initialization
4489 case 'H': {
4490 First += 2;
4491 Node *Name = parseName();
4492 if (Name == nullptr)
4493 return nullptr;
4494 return make<SpecialName>("thread-local initialization routine for ", Name);
4495 }
4496 // T <call-offset> <base encoding>
4497 default: {
4498 ++First;
4499 bool IsVirt = look() == 'v';
4500 if (parseCallOffset())
4501 return nullptr;
4502 Node *BaseEncoding = parseEncoding();
4503 if (BaseEncoding == nullptr)
4504 return nullptr;
4505 if (IsVirt)
4506 return make<SpecialName>("virtual thunk to ", BaseEncoding);
4507 else
4508 return make<SpecialName>("non-virtual thunk to ", BaseEncoding);
4509 }
4510 }
4511 case 'G':
4512 switch (look(1)) {
4513 // GV <object name> # Guard variable for one-time initialization
4514 case 'V': {
4515 First += 2;
4516 Node *Name = parseName();
4517 if (Name == nullptr)
4518 return nullptr;
4519 return make<SpecialName>("guard variable for ", Name);
4520 }
4521 // GR <object name> # reference temporary for object
4522 // GR <object name> _ # First temporary
4523 // GR <object name> <seq-id> _ # Subsequent temporaries
4524 case 'R': {
4525 First += 2;
4526 Node *Name = parseName();
4527 if (Name == nullptr)
4528 return nullptr;
4529 size_t Count;
4530 bool ParsedSeqId = !parseSeqId(&Count);
4531 if (!consumeIf('_') && ParsedSeqId)
4532 return nullptr;
4533 return make<SpecialName>("reference temporary for ", Name);
4534 }
Rafael Espindolab940b662016-09-06 19:16:48 +00004535 }
4536 }
Erik Pilkingtonbb7feae2018-03-19 15:18:23 +00004537 return nullptr;
Rafael Espindolab940b662016-09-06 19:16:48 +00004538}
4539
4540// <encoding> ::= <function name> <bare-function-type>
4541// ::= <data name>
4542// ::= <special-name>
Erik Pilkingtonbb7feae2018-03-19 15:18:23 +00004543Node *Db::parseEncoding() {
Erik Pilkingtonbb7feae2018-03-19 15:18:23 +00004544 if (look() == 'G' || look() == 'T')
4545 return parseSpecialName();
4546
4547 auto IsEndOfEncoding = [&] {
4548 // The set of chars that can potentially follow an <encoding> (none of which
4549 // can start a <type>). Enumerating these allows us to avoid speculative
4550 // parsing.
4551 return numLeft() == 0 || look() == 'E' || look() == '.' || look() == '_';
4552 };
4553
Erik Pilkington8a1cb332018-03-25 22:50:33 +00004554 NameState NameInfo(this);
Erik Pilkingtonbb7feae2018-03-19 15:18:23 +00004555 Node *Name = parseName(&NameInfo);
Erik Pilkington8a1cb332018-03-25 22:50:33 +00004556 if (Name == nullptr)
4557 return nullptr;
Erik Pilkingtonbb7feae2018-03-19 15:18:23 +00004558
Erik Pilkington8a1cb332018-03-25 22:50:33 +00004559 if (resolveForwardTemplateRefs(NameInfo))
4560 return nullptr;
4561
4562 if (IsEndOfEncoding())
4563 return Name;
Erik Pilkingtonbb7feae2018-03-19 15:18:23 +00004564
Erik Pilkingtonc7287862018-03-25 22:49:16 +00004565 Node *Attrs = nullptr;
4566 if (consumeIf("Ua9enable_ifI")) {
4567 size_t BeforeArgs = Names.size();
4568 while (!consumeIf('E')) {
4569 Node *Arg = parseTemplateArg();
4570 if (Arg == nullptr)
4571 return nullptr;
4572 Names.push_back(Arg);
4573 }
4574 Attrs = make<EnableIfAttr>(popTrailingNodeArray(BeforeArgs));
4575 }
4576
Erik Pilkingtonbb7feae2018-03-19 15:18:23 +00004577 Node *ReturnType = nullptr;
4578 if (!NameInfo.CtorDtorConversion && NameInfo.EndsWithTemplateArgs) {
4579 ReturnType = parseType();
4580 if (ReturnType == nullptr)
4581 return nullptr;
4582 }
4583
4584 if (consumeIf('v'))
4585 return make<FunctionEncoding>(ReturnType, Name, NodeArray(),
Erik Pilkingtonc7287862018-03-25 22:49:16 +00004586 Attrs, NameInfo.CVQualifiers,
Erik Pilkingtonbb7feae2018-03-19 15:18:23 +00004587 NameInfo.ReferenceQualifier);
4588
4589 size_t ParamsBegin = Names.size();
4590 do {
4591 Node *Ty = parseType();
4592 if (Ty == nullptr)
4593 return nullptr;
4594 Names.push_back(Ty);
4595 } while (!IsEndOfEncoding());
4596
4597 return make<FunctionEncoding>(ReturnType, Name,
4598 popTrailingNodeArray(ParamsBegin),
Erik Pilkingtonc7287862018-03-25 22:49:16 +00004599 Attrs, NameInfo.CVQualifiers,
Erik Pilkingtonbb7feae2018-03-19 15:18:23 +00004600 NameInfo.ReferenceQualifier);
4601}
4602
4603template <class Float>
4604struct FloatData;
4605
4606template <>
4607struct FloatData<float>
4608{
4609 static const size_t mangled_size = 8;
4610 static const size_t max_demangled_size = 24;
4611 static constexpr const char* spec = "%af";
4612};
4613
4614constexpr const char* FloatData<float>::spec;
4615
4616template <>
4617struct FloatData<double>
4618{
4619 static const size_t mangled_size = 16;
4620 static const size_t max_demangled_size = 32;
4621 static constexpr const char* spec = "%a";
4622};
4623
4624constexpr const char* FloatData<double>::spec;
4625
4626template <>
4627struct FloatData<long double>
4628{
4629#if defined(__mips__) && defined(__mips_n64) || defined(__aarch64__) || \
4630 defined(__wasm__)
4631 static const size_t mangled_size = 32;
4632#elif defined(__arm__) || defined(__mips__) || defined(__hexagon__)
4633 static const size_t mangled_size = 16;
4634#else
4635 static const size_t mangled_size = 20; // May need to be adjusted to 16 or 24 on other platforms
4636#endif
4637 static const size_t max_demangled_size = 40;
4638 static constexpr const char *spec = "%LaL";
4639};
4640
4641constexpr const char *FloatData<long double>::spec;
4642
4643template <class Float> Node *Db::parseFloatingLiteral() {
4644 const size_t N = FloatData<Float>::mangled_size;
4645 if (numLeft() <= N)
4646 return nullptr;
4647 StringView Data(First, First + N);
4648 for (char C : Data)
4649 if (!std::isxdigit(C))
4650 return nullptr;
4651 First += N;
4652 if (!consumeIf('E'))
4653 return nullptr;
4654 return make<FloatExpr<Float>>(Data);
4655}
4656
4657// <seq-id> ::= <0-9A-Z>+
4658bool Db::parseSeqId(size_t *Out) {
4659 if (!(look() >= '0' && look() <= '9') &&
4660 !(look() >= 'A' && look() <= 'Z'))
4661 return true;
4662
4663 size_t Id = 0;
4664 while (true) {
4665 if (look() >= '0' && look() <= '9') {
4666 Id *= 36;
4667 Id += static_cast<size_t>(look() - '0');
4668 } else if (look() >= 'A' && look() <= 'Z') {
4669 Id *= 36;
4670 Id += static_cast<size_t>(look() - 'A') + 10;
4671 } else {
4672 *Out = Id;
4673 return false;
4674 }
4675 ++First;
4676 }
4677}
4678
4679// <substitution> ::= S <seq-id> _
4680// ::= S_
4681// <substitution> ::= Sa # ::std::allocator
4682// <substitution> ::= Sb # ::std::basic_string
4683// <substitution> ::= Ss # ::std::basic_string < char,
4684// ::std::char_traits<char>,
4685// ::std::allocator<char> >
4686// <substitution> ::= Si # ::std::basic_istream<char, std::char_traits<char> >
4687// <substitution> ::= So # ::std::basic_ostream<char, std::char_traits<char> >
4688// <substitution> ::= Sd # ::std::basic_iostream<char, std::char_traits<char> >
4689Node *Db::parseSubstitution() {
4690 if (!consumeIf('S'))
4691 return nullptr;
4692
4693 if (std::islower(look())) {
4694 Node *SpecialSub;
4695 switch (look()) {
4696 case 'a':
4697 ++First;
4698 SpecialSub = make<SpecialSubstitution>(SpecialSubKind::allocator);
Rafael Espindolab940b662016-09-06 19:16:48 +00004699 break;
Erik Pilkingtonbb7feae2018-03-19 15:18:23 +00004700 case 'b':
4701 ++First;
4702 SpecialSub = make<SpecialSubstitution>(SpecialSubKind::basic_string);
4703 break;
4704 case 's':
4705 ++First;
4706 SpecialSub = make<SpecialSubstitution>(SpecialSubKind::string);
4707 break;
4708 case 'i':
4709 ++First;
4710 SpecialSub = make<SpecialSubstitution>(SpecialSubKind::istream);
4711 break;
4712 case 'o':
4713 ++First;
4714 SpecialSub = make<SpecialSubstitution>(SpecialSubKind::ostream);
4715 break;
4716 case 'd':
4717 ++First;
4718 SpecialSub = make<SpecialSubstitution>(SpecialSubKind::iostream);
4719 break;
4720 default:
4721 return nullptr;
4722 }
4723 // Itanium C++ ABI 5.1.2: If a name that would use a built-in <substitution>
4724 // has ABI tags, the tags are appended to the substitution; the result is a
4725 // substitutable component.
4726 Node *WithTags = parseAbiTags(SpecialSub);
4727 if (WithTags != SpecialSub) {
4728 Subs.push_back(WithTags);
4729 SpecialSub = WithTags;
4730 }
4731 return SpecialSub;
4732 }
Rafael Espindolab940b662016-09-06 19:16:48 +00004733
Erik Pilkingtonbb7feae2018-03-19 15:18:23 +00004734 // ::= S_
4735 if (consumeIf('_')) {
4736 if (Subs.empty())
4737 return nullptr;
4738 return Subs[0];
4739 }
4740
4741 // ::= S <seq-id> _
4742 size_t Index = 0;
4743 if (parseSeqId(&Index))
4744 return nullptr;
4745 ++Index;
4746 if (!consumeIf('_') || Index >= Subs.size())
4747 return nullptr;
4748 return Subs[Index];
4749}
4750
4751// <template-param> ::= T_ # first template parameter
4752// ::= T <parameter-2 non-negative number> _
4753Node *Db::parseTemplateParam() {
4754 if (!consumeIf('T'))
4755 return nullptr;
4756
4757 size_t Index = 0;
4758 if (!consumeIf('_')) {
4759 if (parsePositiveInteger(&Index))
4760 return nullptr;
4761 ++Index;
4762 if (!consumeIf('_'))
4763 return nullptr;
4764 }
4765
4766 // Itanium ABI 5.1.8: In a generic lambda, uses of auto in the parameter list
4767 // are mangled as the corresponding artificial template type parameter.
4768 if (ParsingLambdaParams)
4769 return make<NameType>("auto");
4770
Erik Pilkington8a1cb332018-03-25 22:50:33 +00004771 // If we're in a context where this <template-param> refers to a
4772 // <template-arg> further ahead in the mangled name (currently just conversion
4773 // operator types), then we should only look it up in the right context.
4774 if (PermitForwardTemplateReferences) {
4775 ForwardTemplateRefs.push_back(make<ForwardTemplateReference>(Index));
4776 return ForwardTemplateRefs.back();
Erik Pilkingtonbb7feae2018-03-19 15:18:23 +00004777 }
Erik Pilkington8a1cb332018-03-25 22:50:33 +00004778
4779 if (Index >= TemplateParams.size())
4780 return nullptr;
Erik Pilkingtonbb7feae2018-03-19 15:18:23 +00004781 return TemplateParams[Index];
4782}
4783
4784// <template-arg> ::= <type> # type or template
4785// ::= X <expression> E # expression
4786// ::= <expr-primary> # simple expressions
4787// ::= J <template-arg>* E # argument pack
4788// ::= LZ <encoding> E # extension
4789Node *Db::parseTemplateArg() {
4790 switch (look()) {
4791 case 'X': {
4792 ++First;
4793 Node *Arg = parseExpr();
4794 if (Arg == nullptr || !consumeIf('E'))
4795 return nullptr;
4796 return Arg;
4797 }
4798 case 'J': {
4799 ++First;
4800 size_t ArgsBegin = Names.size();
4801 while (!consumeIf('E')) {
4802 Node *Arg = parseTemplateArg();
4803 if (Arg == nullptr)
4804 return nullptr;
4805 Names.push_back(Arg);
4806 }
4807 NodeArray Args = popTrailingNodeArray(ArgsBegin);
4808 return make<TemplateArgumentPack>(Args);
4809 }
4810 case 'L': {
4811 // ::= LZ <encoding> E # extension
4812 if (look(1) == 'Z') {
4813 First += 2;
4814 Node *Arg = parseEncoding();
4815 if (Arg == nullptr || !consumeIf('E'))
4816 return nullptr;
4817 return Arg;
4818 }
4819 // ::= <expr-primary> # simple expressions
4820 return parseExprPrimary();
4821 }
4822 default:
4823 return parseType();
4824 }
4825}
4826
4827// <template-args> ::= I <template-arg>* E
4828// extension, the abi says <template-arg>+
Erik Pilkington8a1cb332018-03-25 22:50:33 +00004829Node *Db::parseTemplateArgs(bool TagTemplates) {
Erik Pilkingtonbb7feae2018-03-19 15:18:23 +00004830 if (!consumeIf('I'))
4831 return nullptr;
4832
4833 // <template-params> refer to the innermost <template-args>. Clear out any
4834 // outer args that we may have inserted into TemplateParams.
4835 if (TagTemplates)
4836 TemplateParams.clear();
4837
4838 size_t ArgsBegin = Names.size();
4839 while (!consumeIf('E')) {
4840 if (TagTemplates) {
4841 auto OldParams = std::move(TemplateParams);
4842 Node *Arg = parseTemplateArg();
4843 TemplateParams = std::move(OldParams);
4844 if (Arg == nullptr)
4845 return nullptr;
4846 Names.push_back(Arg);
4847 Node *TableEntry = Arg;
4848 if (Arg->getKind() == Node::KTemplateArgumentPack) {
4849 TableEntry = make<ParameterPack>(
4850 static_cast<TemplateArgumentPack*>(TableEntry)->getElements());
4851 }
4852 TemplateParams.push_back(TableEntry);
4853 } else {
4854 Node *Arg = parseTemplateArg();
4855 if (Arg == nullptr)
4856 return nullptr;
4857 Names.push_back(Arg);
4858 }
4859 }
4860 return make<TemplateArgs>(popTrailingNodeArray(ArgsBegin));
4861}
4862
4863// <discriminator> := _ <non-negative number> # when number < 10
4864// := __ <non-negative number> _ # when number >= 10
4865// extension := decimal-digit+ # at the end of string
4866
4867const char*
4868parse_discriminator(const char* first, const char* last)
4869{
4870 // parse but ignore discriminator
4871 if (first != last)
4872 {
4873 if (*first == '_')
4874 {
4875 const char* t1 = first+1;
4876 if (t1 != last)
4877 {
4878 if (std::isdigit(*t1))
4879 first = t1+1;
4880 else if (*t1 == '_')
4881 {
4882 for (++t1; t1 != last && std::isdigit(*t1); ++t1)
4883 ;
4884 if (t1 != last && *t1 == '_')
4885 first = t1 + 1;
Rafael Espindolab940b662016-09-06 19:16:48 +00004886 }
Rafael Espindolab940b662016-09-06 19:16:48 +00004887 }
Erik Pilkingtonbb7feae2018-03-19 15:18:23 +00004888 }
4889 else if (std::isdigit(*first))
4890 {
4891 const char* t1 = first+1;
4892 for (; t1 != last && std::isdigit(*t1); ++t1)
4893 ;
4894 if (t1 == last)
4895 first = last;
4896 }
Rafael Espindolab940b662016-09-06 19:16:48 +00004897 }
Erik Pilkingtonbb7feae2018-03-19 15:18:23 +00004898 return first;
Rafael Espindolab940b662016-09-06 19:16:48 +00004899}
4900
Erik Pilkingtonbb7feae2018-03-19 15:18:23 +00004901// <mangled-name> ::= _Z <encoding>
Rafael Espindolab940b662016-09-06 19:16:48 +00004902// ::= <type>
Erik Pilkingtonbb7feae2018-03-19 15:18:23 +00004903// extension ::= ___Z <encoding> _block_invoke
4904// extension ::= ___Z <encoding> _block_invoke<decimal-digit>+
4905// extension ::= ___Z <encoding> _block_invoke_<decimal-digit>+
4906Node *Db::parse() {
4907 if (consumeIf("_Z")) {
4908 Node *Encoding = parseEncoding();
4909 if (Encoding == nullptr)
4910 return nullptr;
4911 if (look() == '.') {
4912 Encoding = make<DotSuffix>(Encoding, StringView(First, Last));
4913 First = Last;
4914 }
4915 if (numLeft() != 0)
4916 return nullptr;
4917 return Encoding;
4918 }
Rafael Espindolab940b662016-09-06 19:16:48 +00004919
Erik Pilkingtonbb7feae2018-03-19 15:18:23 +00004920 if (consumeIf("___Z")) {
4921 Node *Encoding = parseEncoding();
4922 if (Encoding == nullptr || !consumeIf("_block_invoke"))
4923 return nullptr;
4924 bool RequireNumber = consumeIf('_');
4925 if (parseNumber().empty() && RequireNumber)
4926 return nullptr;
Erik Pilkington90dc82e2018-08-02 17:45:01 +00004927 if (look() == '.')
4928 First = Last;
Erik Pilkingtonbb7feae2018-03-19 15:18:23 +00004929 if (numLeft() != 0)
4930 return nullptr;
4931 return make<SpecialName>("invocation function for block in ", Encoding);
Rafael Espindolab940b662016-09-06 19:16:48 +00004932 }
Erik Pilkingtonbb7feae2018-03-19 15:18:23 +00004933
4934 Node *Ty = parseType();
4935 if (numLeft() != 0)
4936 return nullptr;
4937 return Ty;
Rafael Espindolab940b662016-09-06 19:16:48 +00004938}
Erik Pilkingtonf2a9b0f2018-04-12 20:41:06 +00004939
4940bool initializeOutputStream(char *Buf, size_t *N, OutputStream &S,
4941 size_t InitSize) {
4942 size_t BufferSize;
4943 if (Buf == nullptr) {
4944 Buf = static_cast<char *>(std::malloc(InitSize));
4945 if (Buf == nullptr)
4946 return true;
4947 BufferSize = InitSize;
4948 } else
4949 BufferSize = *N;
4950
4951 S.reset(Buf, BufferSize);
4952 return false;
4953}
4954
Erik Pilkingtonbb7feae2018-03-19 15:18:23 +00004955} // unnamed namespace
Rafael Espindolab940b662016-09-06 19:16:48 +00004956
Erik Pilkingtonbb7feae2018-03-19 15:18:23 +00004957char *llvm::itaniumDemangle(const char *MangledName, char *Buf,
4958 size_t *N, int *Status) {
4959 if (MangledName == nullptr || (Buf != nullptr && N == nullptr)) {
4960 if (Status)
Zachary Turner8a0efd02018-07-17 19:42:29 +00004961 *Status = demangle_invalid_args;
Rafael Espindolab940b662016-09-06 19:16:48 +00004962 return nullptr;
4963 }
Erik Pilkingtonbb7feae2018-03-19 15:18:23 +00004964
Zachary Turner8a0efd02018-07-17 19:42:29 +00004965 int InternalStatus = demangle_success;
Erik Pilkingtonf2a9b0f2018-04-12 20:41:06 +00004966 Db Parser(MangledName, MangledName + std::strlen(MangledName));
4967 OutputStream S;
Erik Pilkingtonbb7feae2018-03-19 15:18:23 +00004968
Erik Pilkingtonbb7feae2018-03-19 15:18:23 +00004969 Node *AST = Parser.parse();
4970
4971 if (AST == nullptr)
Zachary Turner8a0efd02018-07-17 19:42:29 +00004972 InternalStatus = demangle_invalid_mangled_name;
Erik Pilkingtonf2a9b0f2018-04-12 20:41:06 +00004973 else if (initializeOutputStream(Buf, N, S, 1024))
Zachary Turner8a0efd02018-07-17 19:42:29 +00004974 InternalStatus = demangle_memory_alloc_failure;
Erik Pilkingtonf2a9b0f2018-04-12 20:41:06 +00004975 else {
Erik Pilkington8a1cb332018-03-25 22:50:33 +00004976 assert(Parser.ForwardTemplateRefs.empty());
Erik Pilkingtonf2a9b0f2018-04-12 20:41:06 +00004977 AST->print(S);
4978 S += '\0';
4979 if (N != nullptr)
4980 *N = S.getCurrentPosition();
4981 Buf = S.getBuffer();
Erik Pilkingtonbb7feae2018-03-19 15:18:23 +00004982 }
4983
4984 if (Status)
4985 *Status = InternalStatus;
Zachary Turner8a0efd02018-07-17 19:42:29 +00004986 return InternalStatus == demangle_success ? Buf : nullptr;
Rafael Espindolab940b662016-09-06 19:16:48 +00004987}
Erik Pilkington67d82d62018-04-12 20:41:38 +00004988
4989namespace llvm {
4990
4991ItaniumPartialDemangler::ItaniumPartialDemangler()
4992 : RootNode(nullptr), Context(new Db{nullptr, nullptr}) {}
4993
4994ItaniumPartialDemangler::~ItaniumPartialDemangler() {
4995 delete static_cast<Db *>(Context);
4996}
4997
4998ItaniumPartialDemangler::ItaniumPartialDemangler(
4999 ItaniumPartialDemangler &&Other)
5000 : RootNode(Other.RootNode), Context(Other.Context) {
5001 Other.Context = Other.RootNode = nullptr;
5002}
5003
5004ItaniumPartialDemangler &ItaniumPartialDemangler::
5005operator=(ItaniumPartialDemangler &&Other) {
5006 std::swap(RootNode, Other.RootNode);
5007 std::swap(Context, Other.Context);
5008 return *this;
5009}
5010
5011// Demangle MangledName into an AST, storing it into this->RootNode.
5012bool ItaniumPartialDemangler::partialDemangle(const char *MangledName) {
5013 Db *Parser = static_cast<Db *>(Context);
5014 size_t Len = std::strlen(MangledName);
5015 Parser->reset(MangledName, MangledName + Len);
5016 RootNode = Parser->parse();
5017 return RootNode == nullptr;
5018}
5019
5020static char *printNode(Node *RootNode, char *Buf, size_t *N) {
5021 OutputStream S;
5022 if (initializeOutputStream(Buf, N, S, 128))
5023 return nullptr;
5024 RootNode->print(S);
5025 S += '\0';
5026 if (N != nullptr)
5027 *N = S.getCurrentPosition();
5028 return S.getBuffer();
5029}
5030
5031char *ItaniumPartialDemangler::getFunctionBaseName(char *Buf, size_t *N) const {
5032 if (!isFunction())
5033 return nullptr;
5034
5035 Node *Name = static_cast<FunctionEncoding *>(RootNode)->getName();
5036
5037 while (true) {
5038 switch (Name->getKind()) {
5039 case Node::KAbiTagAttr:
5040 Name = static_cast<AbiTagAttr *>(Name)->Base;
5041 continue;
5042 case Node::KStdQualifiedName:
5043 Name = static_cast<StdQualifiedName *>(Name)->Child;
5044 continue;
5045 case Node::KNestedName:
5046 Name = static_cast<NestedName *>(Name)->Name;
5047 continue;
5048 case Node::KLocalName:
5049 Name = static_cast<LocalName *>(Name)->Entity;
5050 continue;
5051 case Node::KNameWithTemplateArgs:
5052 Name = static_cast<NameWithTemplateArgs *>(Name)->Name;
5053 continue;
5054 default:
5055 return printNode(Name, Buf, N);
5056 }
5057 }
5058}
5059
5060char *ItaniumPartialDemangler::getFunctionDeclContextName(char *Buf,
5061 size_t *N) const {
5062 if (!isFunction())
5063 return nullptr;
5064 Node *Name = static_cast<FunctionEncoding *>(RootNode)->getName();
5065
5066 OutputStream S;
5067 if (initializeOutputStream(Buf, N, S, 128))
5068 return nullptr;
5069
5070 KeepGoingLocalFunction:
5071 while (true) {
5072 if (Name->getKind() == Node::KAbiTagAttr) {
5073 Name = static_cast<AbiTagAttr *>(Name)->Base;
5074 continue;
5075 }
5076 if (Name->getKind() == Node::KNameWithTemplateArgs) {
5077 Name = static_cast<NameWithTemplateArgs *>(Name)->Name;
5078 continue;
5079 }
5080 break;
5081 }
5082
5083 switch (Name->getKind()) {
5084 case Node::KStdQualifiedName:
5085 S += "std";
5086 break;
5087 case Node::KNestedName:
5088 static_cast<NestedName *>(Name)->Qual->print(S);
5089 break;
5090 case Node::KLocalName: {
5091 auto *LN = static_cast<LocalName *>(Name);
5092 LN->Encoding->print(S);
5093 S += "::";
5094 Name = LN->Entity;
5095 goto KeepGoingLocalFunction;
5096 }
5097 default:
5098 break;
5099 }
5100 S += '\0';
5101 if (N != nullptr)
5102 *N = S.getCurrentPosition();
5103 return S.getBuffer();
5104}
5105
5106char *ItaniumPartialDemangler::getFunctionName(char *Buf, size_t *N) const {
5107 if (!isFunction())
5108 return nullptr;
5109 auto *Name = static_cast<FunctionEncoding *>(RootNode)->getName();
5110 return printNode(Name, Buf, N);
5111}
5112
5113char *ItaniumPartialDemangler::getFunctionParameters(char *Buf,
5114 size_t *N) const {
5115 if (!isFunction())
5116 return nullptr;
5117 NodeArray Params = static_cast<FunctionEncoding *>(RootNode)->getParams();
5118
5119 OutputStream S;
5120 if (initializeOutputStream(Buf, N, S, 128))
5121 return nullptr;
5122
5123 S += '(';
5124 Params.printWithComma(S);
5125 S += ')';
5126 S += '\0';
5127 if (N != nullptr)
5128 *N = S.getCurrentPosition();
5129 return S.getBuffer();
5130}
5131
5132char *ItaniumPartialDemangler::getFunctionReturnType(
5133 char *Buf, size_t *N) const {
5134 if (!isFunction())
5135 return nullptr;
5136
5137 OutputStream S;
5138 if (initializeOutputStream(Buf, N, S, 128))
5139 return nullptr;
5140
5141 if (Node *Ret = static_cast<FunctionEncoding *>(RootNode)->getReturnType())
5142 Ret->print(S);
5143
5144 S += '\0';
5145 if (N != nullptr)
5146 *N = S.getCurrentPosition();
5147 return S.getBuffer();
5148}
5149
5150char *ItaniumPartialDemangler::finishDemangle(char *Buf, size_t *N) const {
5151 assert(RootNode != nullptr && "must call partialDemangle()");
5152 return printNode(static_cast<Node *>(RootNode), Buf, N);
5153}
5154
5155bool ItaniumPartialDemangler::hasFunctionQualifiers() const {
5156 assert(RootNode != nullptr && "must call partialDemangle()");
5157 if (!isFunction())
5158 return false;
5159 auto *E = static_cast<FunctionEncoding *>(RootNode);
5160 return E->getCVQuals() != QualNone || E->getRefQual() != FrefQualNone;
5161}
5162
Fangrui Song79420ac2018-05-24 06:57:57 +00005163bool ItaniumPartialDemangler::isCtorOrDtor() const {
5164 Node *N = static_cast<Node *>(RootNode);
5165 while (N) {
5166 switch (N->getKind()) {
5167 default:
5168 return false;
5169 case Node::KCtorDtorName:
5170 return true;
5171
5172 case Node::KAbiTagAttr:
5173 N = static_cast<AbiTagAttr *>(N)->Base;
5174 break;
5175 case Node::KFunctionEncoding:
5176 N = static_cast<FunctionEncoding *>(N)->getName();
5177 break;
5178 case Node::KLocalName:
5179 N = static_cast<LocalName *>(N)->Entity;
5180 break;
5181 case Node::KNameWithTemplateArgs:
5182 N = static_cast<NameWithTemplateArgs *>(N)->Name;
5183 break;
5184 case Node::KNestedName:
5185 N = static_cast<NestedName *>(N)->Name;
5186 break;
5187 case Node::KStdQualifiedName:
5188 N = static_cast<StdQualifiedName *>(N)->Child;
5189 break;
5190 }
5191 }
5192 return false;
5193}
5194
Erik Pilkington67d82d62018-04-12 20:41:38 +00005195bool ItaniumPartialDemangler::isFunction() const {
5196 assert(RootNode != nullptr && "must call partialDemangle()");
5197 return static_cast<Node *>(RootNode)->getKind() == Node::KFunctionEncoding;
5198}
5199
5200bool ItaniumPartialDemangler::isSpecialName() const {
5201 assert(RootNode != nullptr && "must call partialDemangle()");
5202 auto K = static_cast<Node *>(RootNode)->getKind();
5203 return K == Node::KSpecialName || K == Node::KCtorVtableSpecialName;
5204}
5205
5206bool ItaniumPartialDemangler::isData() const {
5207 return !isFunction() && !isSpecialName();
5208}
5209
5210}