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