blob: e475197abf79e735e36ee18d37e884d4ffc5d977 [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:
645 ArrayType(const Node *Base_, NodeOrString Dimension_ = NodeOrString())
646 : 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;
1368
1369public:
1370 CtorDtorName(const Node *Basename_, bool IsDtor_)
1371 : Node(KCtorDtorName), Basename(Basename_), IsDtor(IsDtor_) {}
1372
1373 template<typename Fn> void match(Fn F) const { F(Basename, IsDtor); }
1374
1375 void printLeft(OutputStream &S) const override {
1376 if (IsDtor)
1377 S += "~";
1378 S += Basename->getBaseName();
1379 }
1380};
1381
1382class DtorName : public Node {
1383 const Node *Base;
1384
1385public:
1386 DtorName(const Node *Base_) : Node(KDtorName), Base(Base_) {}
1387
1388 template<typename Fn> void match(Fn F) const { F(Base); }
1389
1390 void printLeft(OutputStream &S) const override {
1391 S += "~";
1392 Base->printLeft(S);
1393 }
1394};
1395
1396class UnnamedTypeName : public Node {
1397 const StringView Count;
1398
1399public:
1400 UnnamedTypeName(StringView Count_) : Node(KUnnamedTypeName), Count(Count_) {}
1401
1402 template<typename Fn> void match(Fn F) const { F(Count); }
1403
1404 void printLeft(OutputStream &S) const override {
1405 S += "'unnamed";
1406 S += Count;
1407 S += "\'";
1408 }
1409};
1410
1411class ClosureTypeName : public Node {
1412 NodeArray Params;
1413 StringView Count;
1414
1415public:
1416 ClosureTypeName(NodeArray Params_, StringView Count_)
1417 : Node(KClosureTypeName), Params(Params_), Count(Count_) {}
1418
1419 template<typename Fn> void match(Fn F) const { F(Params, Count); }
1420
1421 void printLeft(OutputStream &S) const override {
1422 S += "\'lambda";
1423 S += Count;
1424 S += "\'(";
1425 Params.printWithComma(S);
1426 S += ")";
1427 }
1428};
1429
1430class StructuredBindingName : public Node {
1431 NodeArray Bindings;
1432public:
1433 StructuredBindingName(NodeArray Bindings_)
1434 : Node(KStructuredBindingName), Bindings(Bindings_) {}
1435
1436 template<typename Fn> void match(Fn F) const { F(Bindings); }
1437
1438 void printLeft(OutputStream &S) const override {
1439 S += '[';
1440 Bindings.printWithComma(S);
1441 S += ']';
1442 }
1443};
1444
1445// -- Expression Nodes --
1446
1447class BinaryExpr : public Node {
1448 const Node *LHS;
1449 const StringView InfixOperator;
1450 const Node *RHS;
1451
1452public:
1453 BinaryExpr(const Node *LHS_, StringView InfixOperator_, const Node *RHS_)
1454 : Node(KBinaryExpr), LHS(LHS_), InfixOperator(InfixOperator_), RHS(RHS_) {
1455 }
1456
1457 template<typename Fn> void match(Fn F) const { F(LHS, InfixOperator, RHS); }
1458
1459 void printLeft(OutputStream &S) const override {
1460 // might be a template argument expression, then we need to disambiguate
1461 // with parens.
1462 if (InfixOperator == ">")
1463 S += "(";
1464
1465 S += "(";
1466 LHS->print(S);
1467 S += ") ";
1468 S += InfixOperator;
1469 S += " (";
1470 RHS->print(S);
1471 S += ")";
1472
1473 if (InfixOperator == ">")
1474 S += ")";
1475 }
1476};
1477
1478class ArraySubscriptExpr : public Node {
1479 const Node *Op1;
1480 const Node *Op2;
1481
1482public:
1483 ArraySubscriptExpr(const Node *Op1_, const Node *Op2_)
1484 : Node(KArraySubscriptExpr), Op1(Op1_), Op2(Op2_) {}
1485
1486 template<typename Fn> void match(Fn F) const { F(Op1, Op2); }
1487
1488 void printLeft(OutputStream &S) const override {
1489 S += "(";
1490 Op1->print(S);
1491 S += ")[";
1492 Op2->print(S);
1493 S += "]";
1494 }
1495};
1496
1497class PostfixExpr : public Node {
1498 const Node *Child;
1499 const StringView Operator;
1500
1501public:
1502 PostfixExpr(const Node *Child_, StringView Operator_)
1503 : Node(KPostfixExpr), Child(Child_), Operator(Operator_) {}
1504
1505 template<typename Fn> void match(Fn F) const { F(Child, Operator); }
1506
1507 void printLeft(OutputStream &S) const override {
1508 S += "(";
1509 Child->print(S);
1510 S += ")";
1511 S += Operator;
1512 }
1513};
1514
1515class ConditionalExpr : public Node {
1516 const Node *Cond;
1517 const Node *Then;
1518 const Node *Else;
1519
1520public:
1521 ConditionalExpr(const Node *Cond_, const Node *Then_, const Node *Else_)
1522 : Node(KConditionalExpr), Cond(Cond_), Then(Then_), Else(Else_) {}
1523
1524 template<typename Fn> void match(Fn F) const { F(Cond, Then, Else); }
1525
1526 void printLeft(OutputStream &S) const override {
1527 S += "(";
1528 Cond->print(S);
1529 S += ") ? (";
1530 Then->print(S);
1531 S += ") : (";
1532 Else->print(S);
1533 S += ")";
1534 }
1535};
1536
1537class MemberExpr : public Node {
1538 const Node *LHS;
1539 const StringView Kind;
1540 const Node *RHS;
1541
1542public:
1543 MemberExpr(const Node *LHS_, StringView Kind_, const Node *RHS_)
1544 : Node(KMemberExpr), LHS(LHS_), Kind(Kind_), RHS(RHS_) {}
1545
1546 template<typename Fn> void match(Fn F) const { F(LHS, Kind, RHS); }
1547
1548 void printLeft(OutputStream &S) const override {
1549 LHS->print(S);
1550 S += Kind;
1551 RHS->print(S);
1552 }
1553};
1554
1555class EnclosingExpr : public Node {
1556 const StringView Prefix;
1557 const Node *Infix;
1558 const StringView Postfix;
1559
1560public:
1561 EnclosingExpr(StringView Prefix_, Node *Infix_, StringView Postfix_)
1562 : Node(KEnclosingExpr), Prefix(Prefix_), Infix(Infix_),
1563 Postfix(Postfix_) {}
1564
1565 template<typename Fn> void match(Fn F) const { F(Prefix, Infix, Postfix); }
1566
1567 void printLeft(OutputStream &S) const override {
1568 S += Prefix;
1569 Infix->print(S);
1570 S += Postfix;
1571 }
1572};
1573
1574class CastExpr : public Node {
1575 // cast_kind<to>(from)
1576 const StringView CastKind;
1577 const Node *To;
1578 const Node *From;
1579
1580public:
1581 CastExpr(StringView CastKind_, const Node *To_, const Node *From_)
1582 : Node(KCastExpr), CastKind(CastKind_), To(To_), From(From_) {}
1583
1584 template<typename Fn> void match(Fn F) const { F(CastKind, To, From); }
1585
1586 void printLeft(OutputStream &S) const override {
1587 S += CastKind;
1588 S += "<";
1589 To->printLeft(S);
1590 S += ">(";
1591 From->printLeft(S);
1592 S += ")";
1593 }
1594};
1595
1596class SizeofParamPackExpr : public Node {
1597 const Node *Pack;
1598
1599public:
1600 SizeofParamPackExpr(const Node *Pack_)
1601 : Node(KSizeofParamPackExpr), Pack(Pack_) {}
1602
1603 template<typename Fn> void match(Fn F) const { F(Pack); }
1604
1605 void printLeft(OutputStream &S) const override {
1606 S += "sizeof...(";
1607 ParameterPackExpansion PPE(Pack);
1608 PPE.printLeft(S);
1609 S += ")";
1610 }
1611};
1612
1613class CallExpr : public Node {
1614 const Node *Callee;
1615 NodeArray Args;
1616
1617public:
1618 CallExpr(const Node *Callee_, NodeArray Args_)
1619 : Node(KCallExpr), Callee(Callee_), Args(Args_) {}
1620
1621 template<typename Fn> void match(Fn F) const { F(Callee, Args); }
1622
1623 void printLeft(OutputStream &S) const override {
1624 Callee->print(S);
1625 S += "(";
1626 Args.printWithComma(S);
1627 S += ")";
1628 }
1629};
1630
1631class NewExpr : public Node {
1632 // new (expr_list) type(init_list)
1633 NodeArray ExprList;
1634 Node *Type;
1635 NodeArray InitList;
1636 bool IsGlobal; // ::operator new ?
1637 bool IsArray; // new[] ?
1638public:
1639 NewExpr(NodeArray ExprList_, Node *Type_, NodeArray InitList_, bool IsGlobal_,
1640 bool IsArray_)
1641 : Node(KNewExpr), ExprList(ExprList_), Type(Type_), InitList(InitList_),
1642 IsGlobal(IsGlobal_), IsArray(IsArray_) {}
1643
1644 template<typename Fn> void match(Fn F) const {
1645 F(ExprList, Type, InitList, IsGlobal, IsArray);
1646 }
1647
1648 void printLeft(OutputStream &S) const override {
1649 if (IsGlobal)
1650 S += "::operator ";
1651 S += "new";
1652 if (IsArray)
1653 S += "[]";
1654 S += ' ';
1655 if (!ExprList.empty()) {
1656 S += "(";
1657 ExprList.printWithComma(S);
1658 S += ")";
1659 }
1660 Type->print(S);
1661 if (!InitList.empty()) {
1662 S += "(";
1663 InitList.printWithComma(S);
1664 S += ")";
1665 }
1666
1667 }
1668};
1669
1670class DeleteExpr : public Node {
1671 Node *Op;
1672 bool IsGlobal;
1673 bool IsArray;
1674
1675public:
1676 DeleteExpr(Node *Op_, bool IsGlobal_, bool IsArray_)
1677 : Node(KDeleteExpr), Op(Op_), IsGlobal(IsGlobal_), IsArray(IsArray_) {}
1678
1679 template<typename Fn> void match(Fn F) const { F(Op, IsGlobal, IsArray); }
1680
1681 void printLeft(OutputStream &S) const override {
1682 if (IsGlobal)
1683 S += "::";
1684 S += "delete";
1685 if (IsArray)
1686 S += "[] ";
1687 Op->print(S);
1688 }
1689};
1690
1691class PrefixExpr : public Node {
1692 StringView Prefix;
1693 Node *Child;
1694
1695public:
1696 PrefixExpr(StringView Prefix_, Node *Child_)
1697 : Node(KPrefixExpr), Prefix(Prefix_), Child(Child_) {}
1698
1699 template<typename Fn> void match(Fn F) const { F(Prefix, Child); }
1700
1701 void printLeft(OutputStream &S) const override {
1702 S += Prefix;
1703 S += "(";
1704 Child->print(S);
1705 S += ")";
1706 }
1707};
1708
1709class FunctionParam : public Node {
1710 StringView Number;
1711
1712public:
1713 FunctionParam(StringView Number_) : Node(KFunctionParam), Number(Number_) {}
1714
1715 template<typename Fn> void match(Fn F) const { F(Number); }
1716
1717 void printLeft(OutputStream &S) const override {
1718 S += "fp";
1719 S += Number;
1720 }
1721};
1722
1723class ConversionExpr : public Node {
1724 const Node *Type;
1725 NodeArray Expressions;
1726
1727public:
1728 ConversionExpr(const Node *Type_, NodeArray Expressions_)
1729 : Node(KConversionExpr), Type(Type_), Expressions(Expressions_) {}
1730
1731 template<typename Fn> void match(Fn F) const { F(Type, Expressions); }
1732
1733 void printLeft(OutputStream &S) const override {
1734 S += "(";
1735 Type->print(S);
1736 S += ")(";
1737 Expressions.printWithComma(S);
1738 S += ")";
1739 }
1740};
1741
1742class InitListExpr : public Node {
1743 const Node *Ty;
1744 NodeArray Inits;
1745public:
1746 InitListExpr(const Node *Ty_, NodeArray Inits_)
1747 : Node(KInitListExpr), Ty(Ty_), Inits(Inits_) {}
1748
1749 template<typename Fn> void match(Fn F) const { F(Ty, Inits); }
1750
1751 void printLeft(OutputStream &S) const override {
1752 if (Ty)
1753 Ty->print(S);
1754 S += '{';
1755 Inits.printWithComma(S);
1756 S += '}';
1757 }
1758};
1759
1760class BracedExpr : public Node {
1761 const Node *Elem;
1762 const Node *Init;
1763 bool IsArray;
1764public:
1765 BracedExpr(const Node *Elem_, const Node *Init_, bool IsArray_)
1766 : Node(KBracedExpr), Elem(Elem_), Init(Init_), IsArray(IsArray_) {}
1767
1768 template<typename Fn> void match(Fn F) const { F(Elem, Init, IsArray); }
1769
1770 void printLeft(OutputStream &S) const override {
1771 if (IsArray) {
1772 S += '[';
1773 Elem->print(S);
1774 S += ']';
1775 } else {
1776 S += '.';
1777 Elem->print(S);
1778 }
1779 if (Init->getKind() != KBracedExpr && Init->getKind() != KBracedRangeExpr)
1780 S += " = ";
1781 Init->print(S);
1782 }
1783};
1784
1785class BracedRangeExpr : public Node {
1786 const Node *First;
1787 const Node *Last;
1788 const Node *Init;
1789public:
1790 BracedRangeExpr(const Node *First_, const Node *Last_, const Node *Init_)
1791 : Node(KBracedRangeExpr), First(First_), Last(Last_), Init(Init_) {}
1792
1793 template<typename Fn> void match(Fn F) const { F(First, Last, Init); }
1794
1795 void printLeft(OutputStream &S) const override {
1796 S += '[';
1797 First->print(S);
1798 S += " ... ";
1799 Last->print(S);
1800 S += ']';
1801 if (Init->getKind() != KBracedExpr && Init->getKind() != KBracedRangeExpr)
1802 S += " = ";
1803 Init->print(S);
1804 }
1805};
1806
1807class FoldExpr : public Node {
1808 const Node *Pack, *Init;
1809 StringView OperatorName;
1810 bool IsLeftFold;
1811
1812public:
1813 FoldExpr(bool IsLeftFold_, StringView OperatorName_, const Node *Pack_,
1814 const Node *Init_)
1815 : Node(KFoldExpr), Pack(Pack_), Init(Init_), OperatorName(OperatorName_),
1816 IsLeftFold(IsLeftFold_) {}
1817
1818 template<typename Fn> void match(Fn F) const {
1819 F(IsLeftFold, OperatorName, Pack, Init);
1820 }
1821
1822 void printLeft(OutputStream &S) const override {
1823 auto PrintPack = [&] {
1824 S += '(';
1825 ParameterPackExpansion(Pack).print(S);
1826 S += ')';
1827 };
1828
1829 S += '(';
1830
1831 if (IsLeftFold) {
1832 // init op ... op pack
1833 if (Init != nullptr) {
1834 Init->print(S);
1835 S += ' ';
1836 S += OperatorName;
1837 S += ' ';
1838 }
1839 // ... op pack
1840 S += "... ";
1841 S += OperatorName;
1842 S += ' ';
1843 PrintPack();
1844 } else { // !IsLeftFold
1845 // pack op ...
1846 PrintPack();
1847 S += ' ';
1848 S += OperatorName;
1849 S += " ...";
1850 // pack op ... op init
1851 if (Init != nullptr) {
1852 S += ' ';
1853 S += OperatorName;
1854 S += ' ';
1855 Init->print(S);
1856 }
1857 }
1858 S += ')';
1859 }
1860};
1861
1862class ThrowExpr : public Node {
1863 const Node *Op;
1864
1865public:
1866 ThrowExpr(const Node *Op_) : Node(KThrowExpr), Op(Op_) {}
1867
1868 template<typename Fn> void match(Fn F) const { F(Op); }
1869
1870 void printLeft(OutputStream &S) const override {
1871 S += "throw ";
1872 Op->print(S);
1873 }
1874};
1875
1876class BoolExpr : public Node {
1877 bool Value;
1878
1879public:
1880 BoolExpr(bool Value_) : Node(KBoolExpr), Value(Value_) {}
1881
1882 template<typename Fn> void match(Fn F) const { F(Value); }
1883
1884 void printLeft(OutputStream &S) const override {
1885 S += Value ? StringView("true") : StringView("false");
1886 }
1887};
1888
1889class IntegerCastExpr : public Node {
1890 // ty(integer)
1891 const Node *Ty;
1892 StringView Integer;
1893
1894public:
1895 IntegerCastExpr(const Node *Ty_, StringView Integer_)
1896 : Node(KIntegerCastExpr), Ty(Ty_), Integer(Integer_) {}
1897
1898 template<typename Fn> void match(Fn F) const { F(Ty, Integer); }
1899
1900 void printLeft(OutputStream &S) const override {
1901 S += "(";
1902 Ty->print(S);
1903 S += ")";
1904 S += Integer;
1905 }
1906};
1907
1908class IntegerLiteral : public Node {
1909 StringView Type;
1910 StringView Value;
1911
1912public:
1913 IntegerLiteral(StringView Type_, StringView Value_)
1914 : Node(KIntegerLiteral), Type(Type_), Value(Value_) {}
1915
1916 template<typename Fn> void match(Fn F) const { F(Type, Value); }
1917
1918 void printLeft(OutputStream &S) const override {
1919 if (Type.size() > 3) {
1920 S += "(";
1921 S += Type;
1922 S += ")";
1923 }
1924
1925 if (Value[0] == 'n') {
1926 S += "-";
1927 S += Value.dropFront(1);
1928 } else
1929 S += Value;
1930
1931 if (Type.size() <= 3)
1932 S += Type;
1933 }
1934};
1935
1936template <class Float> struct FloatData;
1937
1938namespace float_literal_impl {
1939constexpr Node::Kind getFloatLiteralKind(float *) {
1940 return Node::KFloatLiteral;
1941}
1942constexpr Node::Kind getFloatLiteralKind(double *) {
1943 return Node::KDoubleLiteral;
1944}
1945constexpr Node::Kind getFloatLiteralKind(long double *) {
1946 return Node::KLongDoubleLiteral;
1947}
1948}
1949
1950template <class Float> class FloatLiteralImpl : public Node {
1951 const StringView Contents;
1952
1953 static constexpr Kind KindForClass =
1954 float_literal_impl::getFloatLiteralKind((Float *)nullptr);
1955
1956public:
1957 FloatLiteralImpl(StringView Contents_)
1958 : Node(KindForClass), Contents(Contents_) {}
1959
1960 template<typename Fn> void match(Fn F) const { F(Contents); }
1961
1962 void printLeft(OutputStream &s) const override {
1963 const char *first = Contents.begin();
1964 const char *last = Contents.end() + 1;
1965
1966 const size_t N = FloatData<Float>::mangled_size;
1967 if (static_cast<std::size_t>(last - first) > N) {
1968 last = first + N;
1969 union {
1970 Float value;
1971 char buf[sizeof(Float)];
1972 };
1973 const char *t = first;
1974 char *e = buf;
1975 for (; t != last; ++t, ++e) {
1976 unsigned d1 = isdigit(*t) ? static_cast<unsigned>(*t - '0')
1977 : static_cast<unsigned>(*t - 'a' + 10);
1978 ++t;
1979 unsigned d0 = isdigit(*t) ? static_cast<unsigned>(*t - '0')
1980 : static_cast<unsigned>(*t - 'a' + 10);
1981 *e = static_cast<char>((d1 << 4) + d0);
1982 }
1983#if __BYTE_ORDER__ == __ORDER_LITTLE_ENDIAN__
1984 std::reverse(buf, e);
1985#endif
1986 char num[FloatData<Float>::max_demangled_size] = {0};
1987 int n = snprintf(num, sizeof(num), FloatData<Float>::spec, value);
1988 s += StringView(num, num + n);
1989 }
1990 }
1991};
1992
1993using FloatLiteral = FloatLiteralImpl<float>;
1994using DoubleLiteral = FloatLiteralImpl<double>;
1995using LongDoubleLiteral = FloatLiteralImpl<long double>;
1996
1997/// Visit the node. Calls \c F(P), where \c P is the node cast to the
1998/// appropriate derived class.
1999template<typename Fn>
2000void Node::visit(Fn F) const {
2001 switch (K) {
2002#define CASE(X) case K ## X: return F(static_cast<const X*>(this));
2003 FOR_EACH_NODE_KIND(CASE)
2004#undef CASE
2005 }
2006 assert(0 && "unknown mangling node kind");
2007}
2008
2009/// Determine the kind of a node from its type.
2010template<typename NodeT> struct NodeKind;
2011#define SPECIALIZATION(X) \
2012 template<> struct NodeKind<X> { \
2013 static constexpr Node::Kind Kind = Node::K##X; \
2014 static constexpr const char *name() { return #X; } \
2015 };
2016FOR_EACH_NODE_KIND(SPECIALIZATION)
2017#undef SPECIALIZATION
2018
2019#undef FOR_EACH_NODE_KIND
2020
2021template <class T, size_t N>
2022class PODSmallVector {
2023 static_assert(std::is_pod<T>::value,
2024 "T is required to be a plain old data type");
2025
2026 T* First;
2027 T* Last;
2028 T* Cap;
2029 T Inline[N];
2030
2031 bool isInline() const { return First == Inline; }
2032
2033 void clearInline() {
2034 First = Inline;
2035 Last = Inline;
2036 Cap = Inline + N;
2037 }
2038
2039 void reserve(size_t NewCap) {
2040 size_t S = size();
2041 if (isInline()) {
2042 auto* Tmp = static_cast<T*>(std::malloc(NewCap * sizeof(T)));
2043 if (Tmp == nullptr)
2044 std::terminate();
2045 std::copy(First, Last, Tmp);
2046 First = Tmp;
2047 } else {
2048 First = static_cast<T*>(std::realloc(First, NewCap * sizeof(T)));
2049 if (First == nullptr)
2050 std::terminate();
2051 }
2052 Last = First + S;
2053 Cap = First + NewCap;
2054 }
2055
2056public:
2057 PODSmallVector() : First(Inline), Last(First), Cap(Inline + N) {}
2058
2059 PODSmallVector(const PODSmallVector&) = delete;
2060 PODSmallVector& operator=(const PODSmallVector&) = delete;
2061
2062 PODSmallVector(PODSmallVector&& Other) : PODSmallVector() {
2063 if (Other.isInline()) {
2064 std::copy(Other.begin(), Other.end(), First);
2065 Last = First + Other.size();
2066 Other.clear();
2067 return;
2068 }
2069
2070 First = Other.First;
2071 Last = Other.Last;
2072 Cap = Other.Cap;
2073 Other.clearInline();
2074 }
2075
2076 PODSmallVector& operator=(PODSmallVector&& Other) {
2077 if (Other.isInline()) {
2078 if (!isInline()) {
2079 std::free(First);
2080 clearInline();
2081 }
2082 std::copy(Other.begin(), Other.end(), First);
2083 Last = First + Other.size();
2084 Other.clear();
2085 return *this;
2086 }
2087
2088 if (isInline()) {
2089 First = Other.First;
2090 Last = Other.Last;
2091 Cap = Other.Cap;
2092 Other.clearInline();
2093 return *this;
2094 }
2095
2096 std::swap(First, Other.First);
2097 std::swap(Last, Other.Last);
2098 std::swap(Cap, Other.Cap);
2099 Other.clear();
2100 return *this;
2101 }
2102
2103 void push_back(const T& Elem) {
2104 if (Last == Cap)
2105 reserve(size() * 2);
2106 *Last++ = Elem;
2107 }
2108
2109 void pop_back() {
2110 assert(Last != First && "Popping empty vector!");
2111 --Last;
2112 }
2113
2114 void dropBack(size_t Index) {
2115 assert(Index <= size() && "dropBack() can't expand!");
2116 Last = First + Index;
2117 }
2118
2119 T* begin() { return First; }
2120 T* end() { return Last; }
2121
2122 bool empty() const { return First == Last; }
2123 size_t size() const { return static_cast<size_t>(Last - First); }
2124 T& back() {
2125 assert(Last != First && "Calling back() on empty vector!");
2126 return *(Last - 1);
2127 }
2128 T& operator[](size_t Index) {
2129 assert(Index < size() && "Invalid access!");
2130 return *(begin() + Index);
2131 }
2132 void clear() { Last = First; }
2133
2134 ~PODSmallVector() {
2135 if (!isInline())
2136 std::free(First);
2137 }
2138};
2139
2140template <typename Alloc>
2141struct Db {
2142 const char *First;
2143 const char *Last;
2144
2145 // Name stack, this is used by the parser to hold temporary names that were
2146 // parsed. The parser collapses multiple names into new nodes to construct
2147 // the AST. Once the parser is finished, names.size() == 1.
2148 PODSmallVector<Node *, 32> Names;
2149
2150 // Substitution table. Itanium supports name substitutions as a means of
2151 // compression. The string "S42_" refers to the 44nd entry (base-36) in this
2152 // table.
2153 PODSmallVector<Node *, 32> Subs;
2154
2155 // Template parameter table. Like the above, but referenced like "T42_".
2156 // This has a smaller size compared to Subs and Names because it can be
2157 // stored on the stack.
2158 PODSmallVector<Node *, 8> TemplateParams;
2159
2160 // Set of unresolved forward <template-param> references. These can occur in a
2161 // conversion operator's type, and are resolved in the enclosing <encoding>.
2162 PODSmallVector<ForwardTemplateReference *, 4> ForwardTemplateRefs;
2163
2164 void (*TypeCallback)(void *, const char *) = nullptr;
2165 void *TypeCallbackContext = nullptr;
2166
2167 bool TryToParseTemplateArgs = true;
2168 bool PermitForwardTemplateReferences = false;
2169 bool ParsingLambdaParams = false;
2170
2171 Alloc ASTAllocator;
2172
2173 Db(const char *First_, const char *Last_) : First(First_), Last(Last_) {}
2174
2175 void reset(const char *First_, const char *Last_) {
2176 First = First_;
2177 Last = Last_;
2178 Names.clear();
2179 Subs.clear();
2180 TemplateParams.clear();
2181 ParsingLambdaParams = false;
2182 TryToParseTemplateArgs = true;
2183 PermitForwardTemplateReferences = false;
2184 ASTAllocator.reset();
2185 }
2186
Richard Smithb485b352018-08-24 23:30:26 +00002187 template <class T, class... Args> Node *make(Args &&... args) {
Richard Smithc20d1442018-08-20 20:14:49 +00002188 return ASTAllocator.template makeNode<T>(std::forward<Args>(args)...);
2189 }
2190
2191 template <class It> NodeArray makeNodeArray(It begin, It end) {
2192 size_t sz = static_cast<size_t>(end - begin);
2193 void *mem = ASTAllocator.allocateNodeArray(sz);
2194 Node **data = new (mem) Node *[sz];
2195 std::copy(begin, end, data);
2196 return NodeArray(data, sz);
2197 }
2198
2199 NodeArray popTrailingNodeArray(size_t FromPosition) {
2200 assert(FromPosition <= Names.size());
2201 NodeArray res =
2202 makeNodeArray(Names.begin() + (long)FromPosition, Names.end());
2203 Names.dropBack(FromPosition);
2204 return res;
2205 }
2206
2207 bool consumeIf(StringView S) {
2208 if (StringView(First, Last).startsWith(S)) {
2209 First += S.size();
2210 return true;
2211 }
2212 return false;
2213 }
2214
2215 bool consumeIf(char C) {
2216 if (First != Last && *First == C) {
2217 ++First;
2218 return true;
2219 }
2220 return false;
2221 }
2222
2223 char consume() { return First != Last ? *First++ : '\0'; }
2224
2225 char look(unsigned Lookahead = 0) {
2226 if (static_cast<size_t>(Last - First) <= Lookahead)
2227 return '\0';
2228 return First[Lookahead];
2229 }
2230
2231 size_t numLeft() const { return static_cast<size_t>(Last - First); }
2232
2233 StringView parseNumber(bool AllowNegative = false);
2234 Qualifiers parseCVQualifiers();
2235 bool parsePositiveInteger(size_t *Out);
2236 StringView parseBareSourceName();
2237
2238 bool parseSeqId(size_t *Out);
2239 Node *parseSubstitution();
2240 Node *parseTemplateParam();
2241 Node *parseTemplateArgs(bool TagTemplates = false);
2242 Node *parseTemplateArg();
2243
2244 /// Parse the <expr> production.
2245 Node *parseExpr();
2246 Node *parsePrefixExpr(StringView Kind);
2247 Node *parseBinaryExpr(StringView Kind);
2248 Node *parseIntegerLiteral(StringView Lit);
2249 Node *parseExprPrimary();
2250 template <class Float> Node *parseFloatingLiteral();
2251 Node *parseFunctionParam();
2252 Node *parseNewExpr();
2253 Node *parseConversionExpr();
2254 Node *parseBracedExpr();
2255 Node *parseFoldExpr();
2256
2257 /// Parse the <type> production.
2258 Node *parseType();
2259 Node *parseFunctionType();
2260 Node *parseVectorType();
2261 Node *parseDecltype();
2262 Node *parseArrayType();
2263 Node *parsePointerToMemberType();
2264 Node *parseClassEnumType();
2265 Node *parseQualifiedType();
2266
2267 Node *parseEncoding();
2268 bool parseCallOffset();
2269 Node *parseSpecialName();
2270
2271 /// Holds some extra information about a <name> that is being parsed. This
2272 /// information is only pertinent if the <name> refers to an <encoding>.
2273 struct NameState {
2274 bool CtorDtorConversion = false;
2275 bool EndsWithTemplateArgs = false;
2276 Qualifiers CVQualifiers = QualNone;
2277 FunctionRefQual ReferenceQualifier = FrefQualNone;
2278 size_t ForwardTemplateRefsBegin;
2279
2280 NameState(Db *Enclosing)
2281 : ForwardTemplateRefsBegin(Enclosing->ForwardTemplateRefs.size()) {}
2282 };
2283
2284 bool resolveForwardTemplateRefs(NameState &State) {
2285 size_t I = State.ForwardTemplateRefsBegin;
2286 size_t E = ForwardTemplateRefs.size();
2287 for (; I < E; ++I) {
2288 size_t Idx = ForwardTemplateRefs[I]->Index;
2289 if (Idx >= TemplateParams.size())
2290 return true;
2291 ForwardTemplateRefs[I]->Ref = TemplateParams[Idx];
2292 }
2293 ForwardTemplateRefs.dropBack(State.ForwardTemplateRefsBegin);
2294 return false;
2295 }
2296
2297 /// Parse the <name> production>
2298 Node *parseName(NameState *State = nullptr);
2299 Node *parseLocalName(NameState *State);
2300 Node *parseOperatorName(NameState *State);
2301 Node *parseUnqualifiedName(NameState *State);
2302 Node *parseUnnamedTypeName(NameState *State);
2303 Node *parseSourceName(NameState *State);
2304 Node *parseUnscopedName(NameState *State);
2305 Node *parseNestedName(NameState *State);
2306 Node *parseCtorDtorName(Node *&SoFar, NameState *State);
2307
2308 Node *parseAbiTags(Node *N);
2309
2310 /// Parse the <unresolved-name> production.
2311 Node *parseUnresolvedName();
2312 Node *parseSimpleId();
2313 Node *parseBaseUnresolvedName();
2314 Node *parseUnresolvedType();
2315 Node *parseDestructorName();
2316
2317 /// Top-level entry point into the parser.
2318 Node *parse();
2319};
2320
2321const char* parse_discriminator(const char* first, const char* last);
2322
2323// <name> ::= <nested-name> // N
2324// ::= <local-name> # See Scope Encoding below // Z
2325// ::= <unscoped-template-name> <template-args>
2326// ::= <unscoped-name>
2327//
2328// <unscoped-template-name> ::= <unscoped-name>
2329// ::= <substitution>
2330template<typename Alloc> Node *Db<Alloc>::parseName(NameState *State) {
2331 consumeIf('L'); // extension
2332
2333 if (look() == 'N')
2334 return parseNestedName(State);
2335 if (look() == 'Z')
2336 return parseLocalName(State);
2337
2338 // ::= <unscoped-template-name> <template-args>
2339 if (look() == 'S' && look(1) != 't') {
2340 Node *S = parseSubstitution();
2341 if (S == nullptr)
2342 return nullptr;
2343 if (look() != 'I')
2344 return nullptr;
2345 Node *TA = parseTemplateArgs(State != nullptr);
2346 if (TA == nullptr)
2347 return nullptr;
2348 if (State) State->EndsWithTemplateArgs = true;
2349 return make<NameWithTemplateArgs>(S, TA);
2350 }
2351
2352 Node *N = parseUnscopedName(State);
2353 if (N == nullptr)
2354 return nullptr;
2355 // ::= <unscoped-template-name> <template-args>
2356 if (look() == 'I') {
2357 Subs.push_back(N);
2358 Node *TA = parseTemplateArgs(State != nullptr);
2359 if (TA == nullptr)
2360 return nullptr;
2361 if (State) State->EndsWithTemplateArgs = true;
2362 return make<NameWithTemplateArgs>(N, TA);
2363 }
2364 // ::= <unscoped-name>
2365 return N;
2366}
2367
2368// <local-name> := Z <function encoding> E <entity name> [<discriminator>]
2369// := Z <function encoding> E s [<discriminator>]
2370// := Z <function encoding> Ed [ <parameter number> ] _ <entity name>
2371template<typename Alloc> Node *Db<Alloc>::parseLocalName(NameState *State) {
2372 if (!consumeIf('Z'))
2373 return nullptr;
2374 Node *Encoding = parseEncoding();
2375 if (Encoding == nullptr || !consumeIf('E'))
2376 return nullptr;
2377
2378 if (consumeIf('s')) {
2379 First = parse_discriminator(First, Last);
Richard Smithb485b352018-08-24 23:30:26 +00002380 auto *StringLitName = make<NameType>("string literal");
2381 if (!StringLitName)
2382 return nullptr;
2383 return make<LocalName>(Encoding, StringLitName);
Richard Smithc20d1442018-08-20 20:14:49 +00002384 }
2385
2386 if (consumeIf('d')) {
2387 parseNumber(true);
2388 if (!consumeIf('_'))
2389 return nullptr;
2390 Node *N = parseName(State);
2391 if (N == nullptr)
2392 return nullptr;
2393 return make<LocalName>(Encoding, N);
2394 }
2395
2396 Node *Entity = parseName(State);
2397 if (Entity == nullptr)
2398 return nullptr;
2399 First = parse_discriminator(First, Last);
2400 return make<LocalName>(Encoding, Entity);
2401}
2402
2403// <unscoped-name> ::= <unqualified-name>
2404// ::= St <unqualified-name> # ::std::
2405// extension ::= StL<unqualified-name>
2406template<typename Alloc> Node *Db<Alloc>::parseUnscopedName(NameState *State) {
2407 if (consumeIf("StL") || consumeIf("St")) {
2408 Node *R = parseUnqualifiedName(State);
2409 if (R == nullptr)
2410 return nullptr;
2411 return make<StdQualifiedName>(R);
2412 }
2413 return parseUnqualifiedName(State);
2414}
2415
2416// <unqualified-name> ::= <operator-name> [abi-tags]
2417// ::= <ctor-dtor-name>
2418// ::= <source-name>
2419// ::= <unnamed-type-name>
2420// ::= DC <source-name>+ E # structured binding declaration
2421template<typename Alloc>
2422Node *Db<Alloc>::parseUnqualifiedName(NameState *State) {
2423 // <ctor-dtor-name>s are special-cased in parseNestedName().
2424 Node *Result;
2425 if (look() == 'U')
2426 Result = parseUnnamedTypeName(State);
2427 else if (look() >= '1' && look() <= '9')
2428 Result = parseSourceName(State);
2429 else if (consumeIf("DC")) {
2430 size_t BindingsBegin = Names.size();
2431 do {
2432 Node *Binding = parseSourceName(State);
2433 if (Binding == nullptr)
2434 return nullptr;
2435 Names.push_back(Binding);
2436 } while (!consumeIf('E'));
2437 Result = make<StructuredBindingName>(popTrailingNodeArray(BindingsBegin));
2438 } else
2439 Result = parseOperatorName(State);
2440 if (Result != nullptr)
2441 Result = parseAbiTags(Result);
2442 return Result;
2443}
2444
2445// <unnamed-type-name> ::= Ut [<nonnegative number>] _
2446// ::= <closure-type-name>
2447//
2448// <closure-type-name> ::= Ul <lambda-sig> E [ <nonnegative number> ] _
2449//
2450// <lambda-sig> ::= <parameter type>+ # Parameter types or "v" if the lambda has no parameters
2451template<typename Alloc> Node *Db<Alloc>::parseUnnamedTypeName(NameState *) {
2452 if (consumeIf("Ut")) {
2453 StringView Count = parseNumber();
2454 if (!consumeIf('_'))
2455 return nullptr;
2456 return make<UnnamedTypeName>(Count);
2457 }
2458 if (consumeIf("Ul")) {
2459 NodeArray Params;
2460 SwapAndRestore<bool> SwapParams(ParsingLambdaParams, true);
2461 if (!consumeIf("vE")) {
2462 size_t ParamsBegin = Names.size();
2463 do {
2464 Node *P = parseType();
2465 if (P == nullptr)
2466 return nullptr;
2467 Names.push_back(P);
2468 } while (!consumeIf('E'));
2469 Params = popTrailingNodeArray(ParamsBegin);
2470 }
2471 StringView Count = parseNumber();
2472 if (!consumeIf('_'))
2473 return nullptr;
2474 return make<ClosureTypeName>(Params, Count);
2475 }
2476 return nullptr;
2477}
2478
2479// <source-name> ::= <positive length number> <identifier>
2480template<typename Alloc> Node *Db<Alloc>::parseSourceName(NameState *) {
2481 size_t Length = 0;
2482 if (parsePositiveInteger(&Length))
2483 return nullptr;
2484 if (numLeft() < Length || Length == 0)
2485 return nullptr;
2486 StringView Name(First, First + Length);
2487 First += Length;
2488 if (Name.startsWith("_GLOBAL__N"))
2489 return make<NameType>("(anonymous namespace)");
2490 return make<NameType>(Name);
2491}
2492
2493// <operator-name> ::= aa # &&
2494// ::= ad # & (unary)
2495// ::= an # &
2496// ::= aN # &=
2497// ::= aS # =
2498// ::= cl # ()
2499// ::= cm # ,
2500// ::= co # ~
2501// ::= cv <type> # (cast)
2502// ::= da # delete[]
2503// ::= de # * (unary)
2504// ::= dl # delete
2505// ::= dv # /
2506// ::= dV # /=
2507// ::= eo # ^
2508// ::= eO # ^=
2509// ::= eq # ==
2510// ::= ge # >=
2511// ::= gt # >
2512// ::= ix # []
2513// ::= le # <=
2514// ::= li <source-name> # operator ""
2515// ::= ls # <<
2516// ::= lS # <<=
2517// ::= lt # <
2518// ::= mi # -
2519// ::= mI # -=
2520// ::= ml # *
2521// ::= mL # *=
2522// ::= mm # -- (postfix in <expression> context)
2523// ::= na # new[]
2524// ::= ne # !=
2525// ::= ng # - (unary)
2526// ::= nt # !
2527// ::= nw # new
2528// ::= oo # ||
2529// ::= or # |
2530// ::= oR # |=
2531// ::= pm # ->*
2532// ::= pl # +
2533// ::= pL # +=
2534// ::= pp # ++ (postfix in <expression> context)
2535// ::= ps # + (unary)
2536// ::= pt # ->
2537// ::= qu # ?
2538// ::= rm # %
2539// ::= rM # %=
2540// ::= rs # >>
2541// ::= rS # >>=
2542// ::= ss # <=> C++2a
2543// ::= v <digit> <source-name> # vendor extended operator
2544template<typename Alloc> Node *Db<Alloc>::parseOperatorName(NameState *State) {
2545 switch (look()) {
2546 case 'a':
2547 switch (look(1)) {
2548 case 'a':
2549 First += 2;
2550 return make<NameType>("operator&&");
2551 case 'd':
2552 case 'n':
2553 First += 2;
2554 return make<NameType>("operator&");
2555 case 'N':
2556 First += 2;
2557 return make<NameType>("operator&=");
2558 case 'S':
2559 First += 2;
2560 return make<NameType>("operator=");
2561 }
2562 return nullptr;
2563 case 'c':
2564 switch (look(1)) {
2565 case 'l':
2566 First += 2;
2567 return make<NameType>("operator()");
2568 case 'm':
2569 First += 2;
2570 return make<NameType>("operator,");
2571 case 'o':
2572 First += 2;
2573 return make<NameType>("operator~");
2574 // ::= cv <type> # (cast)
2575 case 'v': {
2576 First += 2;
2577 SwapAndRestore<bool> SaveTemplate(TryToParseTemplateArgs, false);
2578 // If we're parsing an encoding, State != nullptr and the conversion
2579 // operators' <type> could have a <template-param> that refers to some
2580 // <template-arg>s further ahead in the mangled name.
2581 SwapAndRestore<bool> SavePermit(PermitForwardTemplateReferences,
2582 PermitForwardTemplateReferences ||
2583 State != nullptr);
2584 Node* Ty = parseType();
2585 if (Ty == nullptr)
2586 return nullptr;
2587 if (State) State->CtorDtorConversion = true;
2588 return make<ConversionOperatorType>(Ty);
2589 }
2590 }
2591 return nullptr;
2592 case 'd':
2593 switch (look(1)) {
2594 case 'a':
2595 First += 2;
2596 return make<NameType>("operator delete[]");
2597 case 'e':
2598 First += 2;
2599 return make<NameType>("operator*");
2600 case 'l':
2601 First += 2;
2602 return make<NameType>("operator delete");
2603 case 'v':
2604 First += 2;
2605 return make<NameType>("operator/");
2606 case 'V':
2607 First += 2;
2608 return make<NameType>("operator/=");
2609 }
2610 return nullptr;
2611 case 'e':
2612 switch (look(1)) {
2613 case 'o':
2614 First += 2;
2615 return make<NameType>("operator^");
2616 case 'O':
2617 First += 2;
2618 return make<NameType>("operator^=");
2619 case 'q':
2620 First += 2;
2621 return make<NameType>("operator==");
2622 }
2623 return nullptr;
2624 case 'g':
2625 switch (look(1)) {
2626 case 'e':
2627 First += 2;
2628 return make<NameType>("operator>=");
2629 case 't':
2630 First += 2;
2631 return make<NameType>("operator>");
2632 }
2633 return nullptr;
2634 case 'i':
2635 if (look(1) == 'x') {
2636 First += 2;
2637 return make<NameType>("operator[]");
2638 }
2639 return nullptr;
2640 case 'l':
2641 switch (look(1)) {
2642 case 'e':
2643 First += 2;
2644 return make<NameType>("operator<=");
2645 // ::= li <source-name> # operator ""
2646 case 'i': {
2647 First += 2;
2648 Node *SN = parseSourceName(State);
2649 if (SN == nullptr)
2650 return nullptr;
2651 return make<LiteralOperator>(SN);
2652 }
2653 case 's':
2654 First += 2;
2655 return make<NameType>("operator<<");
2656 case 'S':
2657 First += 2;
2658 return make<NameType>("operator<<=");
2659 case 't':
2660 First += 2;
2661 return make<NameType>("operator<");
2662 }
2663 return nullptr;
2664 case 'm':
2665 switch (look(1)) {
2666 case 'i':
2667 First += 2;
2668 return make<NameType>("operator-");
2669 case 'I':
2670 First += 2;
2671 return make<NameType>("operator-=");
2672 case 'l':
2673 First += 2;
2674 return make<NameType>("operator*");
2675 case 'L':
2676 First += 2;
2677 return make<NameType>("operator*=");
2678 case 'm':
2679 First += 2;
2680 return make<NameType>("operator--");
2681 }
2682 return nullptr;
2683 case 'n':
2684 switch (look(1)) {
2685 case 'a':
2686 First += 2;
2687 return make<NameType>("operator new[]");
2688 case 'e':
2689 First += 2;
2690 return make<NameType>("operator!=");
2691 case 'g':
2692 First += 2;
2693 return make<NameType>("operator-");
2694 case 't':
2695 First += 2;
2696 return make<NameType>("operator!");
2697 case 'w':
2698 First += 2;
2699 return make<NameType>("operator new");
2700 }
2701 return nullptr;
2702 case 'o':
2703 switch (look(1)) {
2704 case 'o':
2705 First += 2;
2706 return make<NameType>("operator||");
2707 case 'r':
2708 First += 2;
2709 return make<NameType>("operator|");
2710 case 'R':
2711 First += 2;
2712 return make<NameType>("operator|=");
2713 }
2714 return nullptr;
2715 case 'p':
2716 switch (look(1)) {
2717 case 'm':
2718 First += 2;
2719 return make<NameType>("operator->*");
2720 case 'l':
2721 First += 2;
2722 return make<NameType>("operator+");
2723 case 'L':
2724 First += 2;
2725 return make<NameType>("operator+=");
2726 case 'p':
2727 First += 2;
2728 return make<NameType>("operator++");
2729 case 's':
2730 First += 2;
2731 return make<NameType>("operator+");
2732 case 't':
2733 First += 2;
2734 return make<NameType>("operator->");
2735 }
2736 return nullptr;
2737 case 'q':
2738 if (look(1) == 'u') {
2739 First += 2;
2740 return make<NameType>("operator?");
2741 }
2742 return nullptr;
2743 case 'r':
2744 switch (look(1)) {
2745 case 'm':
2746 First += 2;
2747 return make<NameType>("operator%");
2748 case 'M':
2749 First += 2;
2750 return make<NameType>("operator%=");
2751 case 's':
2752 First += 2;
2753 return make<NameType>("operator>>");
2754 case 'S':
2755 First += 2;
2756 return make<NameType>("operator>>=");
2757 }
2758 return nullptr;
2759 case 's':
2760 if (look(1) == 's') {
2761 First += 2;
2762 return make<NameType>("operator<=>");
2763 }
2764 return nullptr;
2765 // ::= v <digit> <source-name> # vendor extended operator
2766 case 'v':
2767 if (std::isdigit(look(1))) {
2768 First += 2;
2769 Node *SN = parseSourceName(State);
2770 if (SN == nullptr)
2771 return nullptr;
2772 return make<ConversionOperatorType>(SN);
2773 }
2774 return nullptr;
2775 }
2776 return nullptr;
2777}
2778
2779// <ctor-dtor-name> ::= C1 # complete object constructor
2780// ::= C2 # base object constructor
2781// ::= C3 # complete object allocating constructor
2782// extension ::= C5 # ?
2783// ::= D0 # deleting destructor
2784// ::= D1 # complete object destructor
2785// ::= D2 # base object destructor
2786// extension ::= D5 # ?
2787template<typename Alloc>
2788Node *Db<Alloc>::parseCtorDtorName(Node *&SoFar, NameState *State) {
2789 if (SoFar->getKind() == Node::KSpecialSubstitution) {
2790 auto SSK = static_cast<SpecialSubstitution *>(SoFar)->SSK;
2791 switch (SSK) {
2792 case SpecialSubKind::string:
2793 case SpecialSubKind::istream:
2794 case SpecialSubKind::ostream:
2795 case SpecialSubKind::iostream:
2796 SoFar = make<ExpandedSpecialSubstitution>(SSK);
Richard Smithb485b352018-08-24 23:30:26 +00002797 if (!SoFar)
2798 return nullptr;
Richard Smithc20d1442018-08-20 20:14:49 +00002799 default:
2800 break;
2801 }
2802 }
2803
2804 if (consumeIf('C')) {
2805 bool IsInherited = consumeIf('I');
2806 if (look() != '1' && look() != '2' && look() != '3' && look() != '5')
2807 return nullptr;
2808 ++First;
2809 if (State) State->CtorDtorConversion = true;
2810 if (IsInherited) {
2811 if (parseName(State) == nullptr)
2812 return nullptr;
2813 }
2814 return make<CtorDtorName>(SoFar, false);
2815 }
2816
2817 if (look() == 'D' &&
2818 (look(1) == '0' || look(1) == '1' || look(1) == '2' || look(1) == '5')) {
2819 First += 2;
2820 if (State) State->CtorDtorConversion = true;
2821 return make<CtorDtorName>(SoFar, true);
2822 }
2823
2824 return nullptr;
2825}
2826
2827// <nested-name> ::= N [<CV-Qualifiers>] [<ref-qualifier>] <prefix> <unqualified-name> E
2828// ::= N [<CV-Qualifiers>] [<ref-qualifier>] <template-prefix> <template-args> E
2829//
2830// <prefix> ::= <prefix> <unqualified-name>
2831// ::= <template-prefix> <template-args>
2832// ::= <template-param>
2833// ::= <decltype>
2834// ::= # empty
2835// ::= <substitution>
2836// ::= <prefix> <data-member-prefix>
2837// extension ::= L
2838//
2839// <data-member-prefix> := <member source-name> [<template-args>] M
2840//
2841// <template-prefix> ::= <prefix> <template unqualified-name>
2842// ::= <template-param>
2843// ::= <substitution>
2844template<typename Alloc> Node *Db<Alloc>::parseNestedName(NameState *State) {
2845 if (!consumeIf('N'))
2846 return nullptr;
2847
2848 Qualifiers CVTmp = parseCVQualifiers();
2849 if (State) State->CVQualifiers = CVTmp;
2850
2851 if (consumeIf('O')) {
2852 if (State) State->ReferenceQualifier = FrefQualRValue;
2853 } else if (consumeIf('R')) {
2854 if (State) State->ReferenceQualifier = FrefQualLValue;
2855 } else
2856 if (State) State->ReferenceQualifier = FrefQualNone;
2857
2858 Node *SoFar = nullptr;
2859 auto PushComponent = [&](Node *Comp) {
Richard Smithb485b352018-08-24 23:30:26 +00002860 if (!Comp) return false;
Richard Smithc20d1442018-08-20 20:14:49 +00002861 if (SoFar) SoFar = make<NestedName>(SoFar, Comp);
2862 else SoFar = Comp;
2863 if (State) State->EndsWithTemplateArgs = false;
Richard Smithb485b352018-08-24 23:30:26 +00002864 return SoFar != nullptr;
Richard Smithc20d1442018-08-20 20:14:49 +00002865 };
2866
Richard Smithb485b352018-08-24 23:30:26 +00002867 if (consumeIf("St")) {
Richard Smithc20d1442018-08-20 20:14:49 +00002868 SoFar = make<NameType>("std");
Richard Smithb485b352018-08-24 23:30:26 +00002869 if (!SoFar)
2870 return nullptr;
2871 }
Richard Smithc20d1442018-08-20 20:14:49 +00002872
2873 while (!consumeIf('E')) {
2874 consumeIf('L'); // extension
2875
2876 // <data-member-prefix> := <member source-name> [<template-args>] M
2877 if (consumeIf('M')) {
2878 if (SoFar == nullptr)
2879 return nullptr;
2880 continue;
2881 }
2882
2883 // ::= <template-param>
2884 if (look() == 'T') {
Richard Smithb485b352018-08-24 23:30:26 +00002885 if (!PushComponent(parseTemplateParam()))
Richard Smithc20d1442018-08-20 20:14:49 +00002886 return nullptr;
Richard Smithc20d1442018-08-20 20:14:49 +00002887 Subs.push_back(SoFar);
2888 continue;
2889 }
2890
2891 // ::= <template-prefix> <template-args>
2892 if (look() == 'I') {
2893 Node *TA = parseTemplateArgs(State != nullptr);
2894 if (TA == nullptr || SoFar == nullptr)
2895 return nullptr;
2896 SoFar = make<NameWithTemplateArgs>(SoFar, TA);
Richard Smithb485b352018-08-24 23:30:26 +00002897 if (!SoFar)
2898 return nullptr;
Richard Smithc20d1442018-08-20 20:14:49 +00002899 if (State) State->EndsWithTemplateArgs = true;
2900 Subs.push_back(SoFar);
2901 continue;
2902 }
2903
2904 // ::= <decltype>
2905 if (look() == 'D' && (look(1) == 't' || look(1) == 'T')) {
Richard Smithb485b352018-08-24 23:30:26 +00002906 if (!PushComponent(parseDecltype()))
Richard Smithc20d1442018-08-20 20:14:49 +00002907 return nullptr;
Richard Smithc20d1442018-08-20 20:14:49 +00002908 Subs.push_back(SoFar);
2909 continue;
2910 }
2911
2912 // ::= <substitution>
2913 if (look() == 'S' && look(1) != 't') {
2914 Node *S = parseSubstitution();
Richard Smithb485b352018-08-24 23:30:26 +00002915 if (!PushComponent(S))
Richard Smithc20d1442018-08-20 20:14:49 +00002916 return nullptr;
Richard Smithc20d1442018-08-20 20:14:49 +00002917 if (SoFar != S)
2918 Subs.push_back(S);
2919 continue;
2920 }
2921
2922 // Parse an <unqualified-name> thats actually a <ctor-dtor-name>.
2923 if (look() == 'C' || (look() == 'D' && look(1) != 'C')) {
2924 if (SoFar == nullptr)
2925 return nullptr;
Richard Smithb485b352018-08-24 23:30:26 +00002926 if (!PushComponent(parseCtorDtorName(SoFar, State)))
Richard Smithc20d1442018-08-20 20:14:49 +00002927 return nullptr;
Richard Smithc20d1442018-08-20 20:14:49 +00002928 SoFar = parseAbiTags(SoFar);
2929 if (SoFar == nullptr)
2930 return nullptr;
2931 Subs.push_back(SoFar);
2932 continue;
2933 }
2934
2935 // ::= <prefix> <unqualified-name>
Richard Smithb485b352018-08-24 23:30:26 +00002936 if (!PushComponent(parseUnqualifiedName(State)))
Richard Smithc20d1442018-08-20 20:14:49 +00002937 return nullptr;
Richard Smithc20d1442018-08-20 20:14:49 +00002938 Subs.push_back(SoFar);
2939 }
2940
2941 if (SoFar == nullptr || Subs.empty())
2942 return nullptr;
2943
2944 Subs.pop_back();
2945 return SoFar;
2946}
2947
2948// <simple-id> ::= <source-name> [ <template-args> ]
2949template<typename Alloc> Node *Db<Alloc>::parseSimpleId() {
2950 Node *SN = parseSourceName(/*NameState=*/nullptr);
2951 if (SN == nullptr)
2952 return nullptr;
2953 if (look() == 'I') {
2954 Node *TA = parseTemplateArgs();
2955 if (TA == nullptr)
2956 return nullptr;
2957 return make<NameWithTemplateArgs>(SN, TA);
2958 }
2959 return SN;
2960}
2961
2962// <destructor-name> ::= <unresolved-type> # e.g., ~T or ~decltype(f())
2963// ::= <simple-id> # e.g., ~A<2*N>
2964template<typename Alloc> Node *Db<Alloc>::parseDestructorName() {
2965 Node *Result;
2966 if (std::isdigit(look()))
2967 Result = parseSimpleId();
2968 else
2969 Result = parseUnresolvedType();
2970 if (Result == nullptr)
2971 return nullptr;
2972 return make<DtorName>(Result);
2973}
2974
2975// <unresolved-type> ::= <template-param>
2976// ::= <decltype>
2977// ::= <substitution>
2978template<typename Alloc> Node *Db<Alloc>::parseUnresolvedType() {
2979 if (look() == 'T') {
2980 Node *TP = parseTemplateParam();
2981 if (TP == nullptr)
2982 return nullptr;
2983 Subs.push_back(TP);
2984 return TP;
2985 }
2986 if (look() == 'D') {
2987 Node *DT = parseDecltype();
2988 if (DT == nullptr)
2989 return nullptr;
2990 Subs.push_back(DT);
2991 return DT;
2992 }
2993 return parseSubstitution();
2994}
2995
2996// <base-unresolved-name> ::= <simple-id> # unresolved name
2997// extension ::= <operator-name> # unresolved operator-function-id
2998// extension ::= <operator-name> <template-args> # unresolved operator template-id
2999// ::= on <operator-name> # unresolved operator-function-id
3000// ::= on <operator-name> <template-args> # unresolved operator template-id
3001// ::= dn <destructor-name> # destructor or pseudo-destructor;
3002// # e.g. ~X or ~X<N-1>
3003template<typename Alloc> Node *Db<Alloc>::parseBaseUnresolvedName() {
3004 if (std::isdigit(look()))
3005 return parseSimpleId();
3006
3007 if (consumeIf("dn"))
3008 return parseDestructorName();
3009
3010 consumeIf("on");
3011
3012 Node *Oper = parseOperatorName(/*NameState=*/nullptr);
3013 if (Oper == nullptr)
3014 return nullptr;
3015 if (look() == 'I') {
3016 Node *TA = parseTemplateArgs();
3017 if (TA == nullptr)
3018 return nullptr;
3019 return make<NameWithTemplateArgs>(Oper, TA);
3020 }
3021 return Oper;
3022}
3023
3024// <unresolved-name>
3025// extension ::= srN <unresolved-type> [<template-args>] <unresolved-qualifier-level>* E <base-unresolved-name>
3026// ::= [gs] <base-unresolved-name> # x or (with "gs") ::x
3027// ::= [gs] sr <unresolved-qualifier-level>+ E <base-unresolved-name>
3028// # A::x, N::y, A<T>::z; "gs" means leading "::"
3029// ::= sr <unresolved-type> <base-unresolved-name> # T::x / decltype(p)::x
3030// extension ::= sr <unresolved-type> <template-args> <base-unresolved-name>
3031// # T::N::x /decltype(p)::N::x
3032// (ignored) ::= srN <unresolved-type> <unresolved-qualifier-level>+ E <base-unresolved-name>
3033//
3034// <unresolved-qualifier-level> ::= <simple-id>
3035template<typename Alloc> Node *Db<Alloc>::parseUnresolvedName() {
3036 Node *SoFar = nullptr;
3037
3038 // srN <unresolved-type> [<template-args>] <unresolved-qualifier-level>* E <base-unresolved-name>
3039 // srN <unresolved-type> <unresolved-qualifier-level>+ E <base-unresolved-name>
3040 if (consumeIf("srN")) {
3041 SoFar = parseUnresolvedType();
3042 if (SoFar == nullptr)
3043 return nullptr;
3044
3045 if (look() == 'I') {
3046 Node *TA = parseTemplateArgs();
3047 if (TA == nullptr)
3048 return nullptr;
3049 SoFar = make<NameWithTemplateArgs>(SoFar, TA);
Richard Smithb485b352018-08-24 23:30:26 +00003050 if (!SoFar)
3051 return nullptr;
Richard Smithc20d1442018-08-20 20:14:49 +00003052 }
3053
3054 while (!consumeIf('E')) {
3055 Node *Qual = parseSimpleId();
3056 if (Qual == nullptr)
3057 return nullptr;
3058 SoFar = make<QualifiedName>(SoFar, Qual);
Richard Smithb485b352018-08-24 23:30:26 +00003059 if (!SoFar)
3060 return nullptr;
Richard Smithc20d1442018-08-20 20:14:49 +00003061 }
3062
3063 Node *Base = parseBaseUnresolvedName();
3064 if (Base == nullptr)
3065 return nullptr;
3066 return make<QualifiedName>(SoFar, Base);
3067 }
3068
3069 bool Global = consumeIf("gs");
3070
3071 // [gs] <base-unresolved-name> # x or (with "gs") ::x
3072 if (!consumeIf("sr")) {
3073 SoFar = parseBaseUnresolvedName();
3074 if (SoFar == nullptr)
3075 return nullptr;
3076 if (Global)
3077 SoFar = make<GlobalQualifiedName>(SoFar);
3078 return SoFar;
3079 }
3080
3081 // [gs] sr <unresolved-qualifier-level>+ E <base-unresolved-name>
3082 if (std::isdigit(look())) {
3083 do {
3084 Node *Qual = parseSimpleId();
3085 if (Qual == nullptr)
3086 return nullptr;
3087 if (SoFar)
3088 SoFar = make<QualifiedName>(SoFar, Qual);
3089 else if (Global)
3090 SoFar = make<GlobalQualifiedName>(Qual);
3091 else
3092 SoFar = Qual;
Richard Smithb485b352018-08-24 23:30:26 +00003093 if (!SoFar)
3094 return nullptr;
Richard Smithc20d1442018-08-20 20:14:49 +00003095 } while (!consumeIf('E'));
3096 }
3097 // sr <unresolved-type> <base-unresolved-name>
3098 // sr <unresolved-type> <template-args> <base-unresolved-name>
3099 else {
3100 SoFar = parseUnresolvedType();
3101 if (SoFar == nullptr)
3102 return nullptr;
3103
3104 if (look() == 'I') {
3105 Node *TA = parseTemplateArgs();
3106 if (TA == nullptr)
3107 return nullptr;
3108 SoFar = make<NameWithTemplateArgs>(SoFar, TA);
Richard Smithb485b352018-08-24 23:30:26 +00003109 if (!SoFar)
3110 return nullptr;
Richard Smithc20d1442018-08-20 20:14:49 +00003111 }
3112 }
3113
3114 assert(SoFar != nullptr);
3115
3116 Node *Base = parseBaseUnresolvedName();
3117 if (Base == nullptr)
3118 return nullptr;
3119 return make<QualifiedName>(SoFar, Base);
3120}
3121
3122// <abi-tags> ::= <abi-tag> [<abi-tags>]
3123// <abi-tag> ::= B <source-name>
3124template<typename Alloc> Node *Db<Alloc>::parseAbiTags(Node *N) {
3125 while (consumeIf('B')) {
3126 StringView SN = parseBareSourceName();
3127 if (SN.empty())
3128 return nullptr;
3129 N = make<AbiTagAttr>(N, SN);
Richard Smithb485b352018-08-24 23:30:26 +00003130 if (!N)
3131 return nullptr;
Richard Smithc20d1442018-08-20 20:14:49 +00003132 }
3133 return N;
3134}
3135
3136// <number> ::= [n] <non-negative decimal integer>
3137template<typename Alloc>
3138StringView Db<Alloc>::parseNumber(bool AllowNegative) {
3139 const char *Tmp = First;
3140 if (AllowNegative)
3141 consumeIf('n');
3142 if (numLeft() == 0 || !std::isdigit(*First))
3143 return StringView();
3144 while (numLeft() != 0 && std::isdigit(*First))
3145 ++First;
3146 return StringView(Tmp, First);
3147}
3148
3149// <positive length number> ::= [0-9]*
3150template<typename Alloc> bool Db<Alloc>::parsePositiveInteger(size_t *Out) {
3151 *Out = 0;
3152 if (look() < '0' || look() > '9')
3153 return true;
3154 while (look() >= '0' && look() <= '9') {
3155 *Out *= 10;
3156 *Out += static_cast<size_t>(consume() - '0');
3157 }
3158 return false;
3159}
3160
3161template<typename Alloc> StringView Db<Alloc>::parseBareSourceName() {
3162 size_t Int = 0;
3163 if (parsePositiveInteger(&Int) || numLeft() < Int)
3164 return StringView();
3165 StringView R(First, First + Int);
3166 First += Int;
3167 return R;
3168}
3169
3170// <function-type> ::= [<CV-qualifiers>] [<exception-spec>] [Dx] F [Y] <bare-function-type> [<ref-qualifier>] E
3171//
3172// <exception-spec> ::= Do # non-throwing exception-specification (e.g., noexcept, throw())
3173// ::= DO <expression> E # computed (instantiation-dependent) noexcept
3174// ::= Dw <type>+ E # dynamic exception specification with instantiation-dependent types
3175//
3176// <ref-qualifier> ::= R # & ref-qualifier
3177// <ref-qualifier> ::= O # && ref-qualifier
3178template<typename Alloc> Node *Db<Alloc>::parseFunctionType() {
3179 Qualifiers CVQuals = parseCVQualifiers();
3180
3181 Node *ExceptionSpec = nullptr;
3182 if (consumeIf("Do")) {
3183 ExceptionSpec = make<NameType>("noexcept");
Richard Smithb485b352018-08-24 23:30:26 +00003184 if (!ExceptionSpec)
3185 return nullptr;
Richard Smithc20d1442018-08-20 20:14:49 +00003186 } else if (consumeIf("DO")) {
3187 Node *E = parseExpr();
3188 if (E == nullptr || !consumeIf('E'))
3189 return nullptr;
3190 ExceptionSpec = make<NoexceptSpec>(E);
Richard Smithb485b352018-08-24 23:30:26 +00003191 if (!ExceptionSpec)
3192 return nullptr;
Richard Smithc20d1442018-08-20 20:14:49 +00003193 } else if (consumeIf("Dw")) {
3194 size_t SpecsBegin = Names.size();
3195 while (!consumeIf('E')) {
3196 Node *T = parseType();
3197 if (T == nullptr)
3198 return nullptr;
3199 Names.push_back(T);
3200 }
3201 ExceptionSpec =
3202 make<DynamicExceptionSpec>(popTrailingNodeArray(SpecsBegin));
Richard Smithb485b352018-08-24 23:30:26 +00003203 if (!ExceptionSpec)
3204 return nullptr;
Richard Smithc20d1442018-08-20 20:14:49 +00003205 }
3206
3207 consumeIf("Dx"); // transaction safe
3208
3209 if (!consumeIf('F'))
3210 return nullptr;
3211 consumeIf('Y'); // extern "C"
3212 Node *ReturnType = parseType();
3213 if (ReturnType == nullptr)
3214 return nullptr;
3215
3216 FunctionRefQual ReferenceQualifier = FrefQualNone;
3217 size_t ParamsBegin = Names.size();
3218 while (true) {
3219 if (consumeIf('E'))
3220 break;
3221 if (consumeIf('v'))
3222 continue;
3223 if (consumeIf("RE")) {
3224 ReferenceQualifier = FrefQualLValue;
3225 break;
3226 }
3227 if (consumeIf("OE")) {
3228 ReferenceQualifier = FrefQualRValue;
3229 break;
3230 }
3231 Node *T = parseType();
3232 if (T == nullptr)
3233 return nullptr;
3234 Names.push_back(T);
3235 }
3236
3237 NodeArray Params = popTrailingNodeArray(ParamsBegin);
3238 return make<FunctionType>(ReturnType, Params, CVQuals,
3239 ReferenceQualifier, ExceptionSpec);
3240}
3241
3242// extension:
3243// <vector-type> ::= Dv <positive dimension number> _ <extended element type>
3244// ::= Dv [<dimension expression>] _ <element type>
3245// <extended element type> ::= <element type>
3246// ::= p # AltiVec vector pixel
3247template<typename Alloc> Node *Db<Alloc>::parseVectorType() {
3248 if (!consumeIf("Dv"))
3249 return nullptr;
3250 if (look() >= '1' && look() <= '9') {
3251 StringView DimensionNumber = parseNumber();
3252 if (!consumeIf('_'))
3253 return nullptr;
3254 if (consumeIf('p'))
3255 return make<PixelVectorType>(DimensionNumber);
3256 Node *ElemType = parseType();
3257 if (ElemType == nullptr)
3258 return nullptr;
3259 return make<VectorType>(ElemType, DimensionNumber);
3260 }
3261
3262 if (!consumeIf('_')) {
3263 Node *DimExpr = parseExpr();
3264 if (!DimExpr)
3265 return nullptr;
3266 if (!consumeIf('_'))
3267 return nullptr;
3268 Node *ElemType = parseType();
3269 if (!ElemType)
3270 return nullptr;
3271 return make<VectorType>(ElemType, DimExpr);
3272 }
3273 Node *ElemType = parseType();
3274 if (!ElemType)
3275 return nullptr;
3276 return make<VectorType>(ElemType, StringView());
3277}
3278
3279// <decltype> ::= Dt <expression> E # decltype of an id-expression or class member access (C++0x)
3280// ::= DT <expression> E # decltype of an expression (C++0x)
3281template<typename Alloc> Node *Db<Alloc>::parseDecltype() {
3282 if (!consumeIf('D'))
3283 return nullptr;
3284 if (!consumeIf('t') && !consumeIf('T'))
3285 return nullptr;
3286 Node *E = parseExpr();
3287 if (E == nullptr)
3288 return nullptr;
3289 if (!consumeIf('E'))
3290 return nullptr;
3291 return make<EnclosingExpr>("decltype(", E, ")");
3292}
3293
3294// <array-type> ::= A <positive dimension number> _ <element type>
3295// ::= A [<dimension expression>] _ <element type>
3296template<typename Alloc> Node *Db<Alloc>::parseArrayType() {
3297 if (!consumeIf('A'))
3298 return nullptr;
3299
3300 if (std::isdigit(look())) {
3301 StringView Dimension = parseNumber();
3302 if (!consumeIf('_'))
3303 return nullptr;
3304 Node *Ty = parseType();
3305 if (Ty == nullptr)
3306 return nullptr;
3307 return make<ArrayType>(Ty, Dimension);
3308 }
3309
3310 if (!consumeIf('_')) {
3311 Node *DimExpr = parseExpr();
3312 if (DimExpr == nullptr)
3313 return nullptr;
3314 if (!consumeIf('_'))
3315 return nullptr;
3316 Node *ElementType = parseType();
3317 if (ElementType == nullptr)
3318 return nullptr;
3319 return make<ArrayType>(ElementType, DimExpr);
3320 }
3321
3322 Node *Ty = parseType();
3323 if (Ty == nullptr)
3324 return nullptr;
3325 return make<ArrayType>(Ty);
3326}
3327
3328// <pointer-to-member-type> ::= M <class type> <member type>
3329template<typename Alloc> Node *Db<Alloc>::parsePointerToMemberType() {
3330 if (!consumeIf('M'))
3331 return nullptr;
3332 Node *ClassType = parseType();
3333 if (ClassType == nullptr)
3334 return nullptr;
3335 Node *MemberType = parseType();
3336 if (MemberType == nullptr)
3337 return nullptr;
3338 return make<PointerToMemberType>(ClassType, MemberType);
3339}
3340
3341// <class-enum-type> ::= <name> # non-dependent type name, dependent type name, or dependent typename-specifier
3342// ::= Ts <name> # dependent elaborated type specifier using 'struct' or 'class'
3343// ::= Tu <name> # dependent elaborated type specifier using 'union'
3344// ::= Te <name> # dependent elaborated type specifier using 'enum'
3345template<typename Alloc> Node *Db<Alloc>::parseClassEnumType() {
3346 StringView ElabSpef;
3347 if (consumeIf("Ts"))
3348 ElabSpef = "struct";
3349 else if (consumeIf("Tu"))
3350 ElabSpef = "union";
3351 else if (consumeIf("Te"))
3352 ElabSpef = "enum";
3353
3354 Node *Name = parseName();
3355 if (Name == nullptr)
3356 return nullptr;
3357
3358 if (!ElabSpef.empty())
3359 return make<ElaboratedTypeSpefType>(ElabSpef, Name);
3360
3361 return Name;
3362}
3363
3364// <qualified-type> ::= <qualifiers> <type>
3365// <qualifiers> ::= <extended-qualifier>* <CV-qualifiers>
3366// <extended-qualifier> ::= U <source-name> [<template-args>] # vendor extended type qualifier
3367template<typename Alloc> Node *Db<Alloc>::parseQualifiedType() {
3368 if (consumeIf('U')) {
3369 StringView Qual = parseBareSourceName();
3370 if (Qual.empty())
3371 return nullptr;
3372
3373 // FIXME parse the optional <template-args> here!
3374
3375 // extension ::= U <objc-name> <objc-type> # objc-type<identifier>
3376 if (Qual.startsWith("objcproto")) {
3377 StringView ProtoSourceName = Qual.dropFront(std::strlen("objcproto"));
3378 StringView Proto;
3379 {
3380 SwapAndRestore<const char *> SaveFirst(First, ProtoSourceName.begin()),
3381 SaveLast(Last, ProtoSourceName.end());
3382 Proto = parseBareSourceName();
3383 }
3384 if (Proto.empty())
3385 return nullptr;
3386 Node *Child = parseQualifiedType();
3387 if (Child == nullptr)
3388 return nullptr;
3389 return make<ObjCProtoName>(Child, Proto);
3390 }
3391
3392 Node *Child = parseQualifiedType();
3393 if (Child == nullptr)
3394 return nullptr;
3395 return make<VendorExtQualType>(Child, Qual);
3396 }
3397
3398 Qualifiers Quals = parseCVQualifiers();
3399 Node *Ty = parseType();
3400 if (Ty == nullptr)
3401 return nullptr;
3402 if (Quals != QualNone)
3403 Ty = make<QualType>(Ty, Quals);
3404 return Ty;
3405}
3406
3407// <type> ::= <builtin-type>
3408// ::= <qualified-type>
3409// ::= <function-type>
3410// ::= <class-enum-type>
3411// ::= <array-type>
3412// ::= <pointer-to-member-type>
3413// ::= <template-param>
3414// ::= <template-template-param> <template-args>
3415// ::= <decltype>
3416// ::= P <type> # pointer
3417// ::= R <type> # l-value reference
3418// ::= O <type> # r-value reference (C++11)
3419// ::= C <type> # complex pair (C99)
3420// ::= G <type> # imaginary (C99)
3421// ::= <substitution> # See Compression below
3422// extension ::= U <objc-name> <objc-type> # objc-type<identifier>
3423// extension ::= <vector-type> # <vector-type> starts with Dv
3424//
3425// <objc-name> ::= <k0 number> objcproto <k1 number> <identifier> # k0 = 9 + <number of digits in k1> + k1
3426// <objc-type> ::= <source-name> # PU<11+>objcproto 11objc_object<source-name> 11objc_object -> id<source-name>
3427template<typename Alloc> Node *Db<Alloc>::parseType() {
3428 Node *Result = nullptr;
3429
3430 if (TypeCallback != nullptr)
3431 TypeCallback(TypeCallbackContext, First);
3432
3433 switch (look()) {
3434 // ::= <qualified-type>
3435 case 'r':
3436 case 'V':
3437 case 'K': {
3438 unsigned AfterQuals = 0;
3439 if (look(AfterQuals) == 'r') ++AfterQuals;
3440 if (look(AfterQuals) == 'V') ++AfterQuals;
3441 if (look(AfterQuals) == 'K') ++AfterQuals;
3442
3443 if (look(AfterQuals) == 'F' ||
3444 (look(AfterQuals) == 'D' &&
3445 (look(AfterQuals + 1) == 'o' || look(AfterQuals + 1) == 'O' ||
3446 look(AfterQuals + 1) == 'w' || look(AfterQuals + 1) == 'x'))) {
3447 Result = parseFunctionType();
3448 break;
3449 }
3450 _LIBCPP_FALLTHROUGH();
3451 }
3452 case 'U': {
3453 Result = parseQualifiedType();
3454 break;
3455 }
3456 // <builtin-type> ::= v # void
3457 case 'v':
3458 ++First;
3459 return make<NameType>("void");
3460 // ::= w # wchar_t
3461 case 'w':
3462 ++First;
3463 return make<NameType>("wchar_t");
3464 // ::= b # bool
3465 case 'b':
3466 ++First;
3467 return make<NameType>("bool");
3468 // ::= c # char
3469 case 'c':
3470 ++First;
3471 return make<NameType>("char");
3472 // ::= a # signed char
3473 case 'a':
3474 ++First;
3475 return make<NameType>("signed char");
3476 // ::= h # unsigned char
3477 case 'h':
3478 ++First;
3479 return make<NameType>("unsigned char");
3480 // ::= s # short
3481 case 's':
3482 ++First;
3483 return make<NameType>("short");
3484 // ::= t # unsigned short
3485 case 't':
3486 ++First;
3487 return make<NameType>("unsigned short");
3488 // ::= i # int
3489 case 'i':
3490 ++First;
3491 return make<NameType>("int");
3492 // ::= j # unsigned int
3493 case 'j':
3494 ++First;
3495 return make<NameType>("unsigned int");
3496 // ::= l # long
3497 case 'l':
3498 ++First;
3499 return make<NameType>("long");
3500 // ::= m # unsigned long
3501 case 'm':
3502 ++First;
3503 return make<NameType>("unsigned long");
3504 // ::= x # long long, __int64
3505 case 'x':
3506 ++First;
3507 return make<NameType>("long long");
3508 // ::= y # unsigned long long, __int64
3509 case 'y':
3510 ++First;
3511 return make<NameType>("unsigned long long");
3512 // ::= n # __int128
3513 case 'n':
3514 ++First;
3515 return make<NameType>("__int128");
3516 // ::= o # unsigned __int128
3517 case 'o':
3518 ++First;
3519 return make<NameType>("unsigned __int128");
3520 // ::= f # float
3521 case 'f':
3522 ++First;
3523 return make<NameType>("float");
3524 // ::= d # double
3525 case 'd':
3526 ++First;
3527 return make<NameType>("double");
3528 // ::= e # long double, __float80
3529 case 'e':
3530 ++First;
3531 return make<NameType>("long double");
3532 // ::= g # __float128
3533 case 'g':
3534 ++First;
3535 return make<NameType>("__float128");
3536 // ::= z # ellipsis
3537 case 'z':
3538 ++First;
3539 return make<NameType>("...");
3540
3541 // <builtin-type> ::= u <source-name> # vendor extended type
3542 case 'u': {
3543 ++First;
3544 StringView Res = parseBareSourceName();
3545 if (Res.empty())
3546 return nullptr;
3547 return make<NameType>(Res);
3548 }
3549 case 'D':
3550 switch (look(1)) {
3551 // ::= Dd # IEEE 754r decimal floating point (64 bits)
3552 case 'd':
3553 First += 2;
3554 return make<NameType>("decimal64");
3555 // ::= De # IEEE 754r decimal floating point (128 bits)
3556 case 'e':
3557 First += 2;
3558 return make<NameType>("decimal128");
3559 // ::= Df # IEEE 754r decimal floating point (32 bits)
3560 case 'f':
3561 First += 2;
3562 return make<NameType>("decimal32");
3563 // ::= Dh # IEEE 754r half-precision floating point (16 bits)
3564 case 'h':
3565 First += 2;
3566 return make<NameType>("decimal16");
3567 // ::= Di # char32_t
3568 case 'i':
3569 First += 2;
3570 return make<NameType>("char32_t");
3571 // ::= Ds # char16_t
3572 case 's':
3573 First += 2;
3574 return make<NameType>("char16_t");
3575 // ::= Da # auto (in dependent new-expressions)
3576 case 'a':
3577 First += 2;
3578 return make<NameType>("auto");
3579 // ::= Dc # decltype(auto)
3580 case 'c':
3581 First += 2;
3582 return make<NameType>("decltype(auto)");
3583 // ::= Dn # std::nullptr_t (i.e., decltype(nullptr))
3584 case 'n':
3585 First += 2;
3586 return make<NameType>("std::nullptr_t");
3587
3588 // ::= <decltype>
3589 case 't':
3590 case 'T': {
3591 Result = parseDecltype();
3592 break;
3593 }
3594 // extension ::= <vector-type> # <vector-type> starts with Dv
3595 case 'v': {
3596 Result = parseVectorType();
3597 break;
3598 }
3599 // ::= Dp <type> # pack expansion (C++0x)
3600 case 'p': {
3601 First += 2;
3602 Node *Child = parseType();
3603 if (!Child)
3604 return nullptr;
3605 Result = make<ParameterPackExpansion>(Child);
3606 break;
3607 }
3608 // Exception specifier on a function type.
3609 case 'o':
3610 case 'O':
3611 case 'w':
3612 // Transaction safe function type.
3613 case 'x':
3614 Result = parseFunctionType();
3615 break;
3616 }
3617 break;
3618 // ::= <function-type>
3619 case 'F': {
3620 Result = parseFunctionType();
3621 break;
3622 }
3623 // ::= <array-type>
3624 case 'A': {
3625 Result = parseArrayType();
3626 break;
3627 }
3628 // ::= <pointer-to-member-type>
3629 case 'M': {
3630 Result = parsePointerToMemberType();
3631 break;
3632 }
3633 // ::= <template-param>
3634 case 'T': {
3635 // This could be an elaborate type specifier on a <class-enum-type>.
3636 if (look(1) == 's' || look(1) == 'u' || look(1) == 'e') {
3637 Result = parseClassEnumType();
3638 break;
3639 }
3640
3641 Result = parseTemplateParam();
3642 if (Result == nullptr)
3643 return nullptr;
3644
3645 // Result could be either of:
3646 // <type> ::= <template-param>
3647 // <type> ::= <template-template-param> <template-args>
3648 //
3649 // <template-template-param> ::= <template-param>
3650 // ::= <substitution>
3651 //
3652 // If this is followed by some <template-args>, and we're permitted to
3653 // parse them, take the second production.
3654
3655 if (TryToParseTemplateArgs && look() == 'I') {
3656 Node *TA = parseTemplateArgs();
3657 if (TA == nullptr)
3658 return nullptr;
3659 Result = make<NameWithTemplateArgs>(Result, TA);
3660 }
3661 break;
3662 }
3663 // ::= P <type> # pointer
3664 case 'P': {
3665 ++First;
3666 Node *Ptr = parseType();
3667 if (Ptr == nullptr)
3668 return nullptr;
3669 Result = make<PointerType>(Ptr);
3670 break;
3671 }
3672 // ::= R <type> # l-value reference
3673 case 'R': {
3674 ++First;
3675 Node *Ref = parseType();
3676 if (Ref == nullptr)
3677 return nullptr;
3678 Result = make<ReferenceType>(Ref, ReferenceKind::LValue);
3679 break;
3680 }
3681 // ::= O <type> # r-value reference (C++11)
3682 case 'O': {
3683 ++First;
3684 Node *Ref = parseType();
3685 if (Ref == nullptr)
3686 return nullptr;
3687 Result = make<ReferenceType>(Ref, ReferenceKind::RValue);
3688 break;
3689 }
3690 // ::= C <type> # complex pair (C99)
3691 case 'C': {
3692 ++First;
3693 Node *P = parseType();
3694 if (P == nullptr)
3695 return nullptr;
3696 Result = make<PostfixQualifiedType>(P, " complex");
3697 break;
3698 }
3699 // ::= G <type> # imaginary (C99)
3700 case 'G': {
3701 ++First;
3702 Node *P = parseType();
3703 if (P == nullptr)
3704 return P;
3705 Result = make<PostfixQualifiedType>(P, " imaginary");
3706 break;
3707 }
3708 // ::= <substitution> # See Compression below
3709 case 'S': {
3710 if (look(1) && look(1) != 't') {
3711 Node *Sub = parseSubstitution();
3712 if (Sub == nullptr)
3713 return nullptr;
3714
3715 // Sub could be either of:
3716 // <type> ::= <substitution>
3717 // <type> ::= <template-template-param> <template-args>
3718 //
3719 // <template-template-param> ::= <template-param>
3720 // ::= <substitution>
3721 //
3722 // If this is followed by some <template-args>, and we're permitted to
3723 // parse them, take the second production.
3724
3725 if (TryToParseTemplateArgs && look() == 'I') {
3726 Node *TA = parseTemplateArgs();
3727 if (TA == nullptr)
3728 return nullptr;
3729 Result = make<NameWithTemplateArgs>(Sub, TA);
3730 break;
3731 }
3732
3733 // If all we parsed was a substitution, don't re-insert into the
3734 // substitution table.
3735 return Sub;
3736 }
3737 _LIBCPP_FALLTHROUGH();
3738 }
3739 // ::= <class-enum-type>
3740 default: {
3741 Result = parseClassEnumType();
3742 break;
3743 }
3744 }
3745
3746 // If we parsed a type, insert it into the substitution table. Note that all
3747 // <builtin-type>s and <substitution>s have already bailed out, because they
3748 // don't get substitutions.
3749 if (Result != nullptr)
3750 Subs.push_back(Result);
3751 return Result;
3752}
3753
3754template<typename Alloc> Node *Db<Alloc>::parsePrefixExpr(StringView Kind) {
3755 Node *E = parseExpr();
3756 if (E == nullptr)
3757 return nullptr;
3758 return make<PrefixExpr>(Kind, E);
3759}
3760
3761template<typename Alloc> Node *Db<Alloc>::parseBinaryExpr(StringView Kind) {
3762 Node *LHS = parseExpr();
3763 if (LHS == nullptr)
3764 return nullptr;
3765 Node *RHS = parseExpr();
3766 if (RHS == nullptr)
3767 return nullptr;
3768 return make<BinaryExpr>(LHS, Kind, RHS);
3769}
3770
3771template<typename Alloc> Node *Db<Alloc>::parseIntegerLiteral(StringView Lit) {
3772 StringView Tmp = parseNumber(true);
3773 if (!Tmp.empty() && consumeIf('E'))
3774 return make<IntegerLiteral>(Lit, Tmp);
3775 return nullptr;
3776}
3777
3778// <CV-Qualifiers> ::= [r] [V] [K]
3779template<typename Alloc> Qualifiers Db<Alloc>::parseCVQualifiers() {
3780 Qualifiers CVR = QualNone;
3781 if (consumeIf('r'))
3782 CVR |= QualRestrict;
3783 if (consumeIf('V'))
3784 CVR |= QualVolatile;
3785 if (consumeIf('K'))
3786 CVR |= QualConst;
3787 return CVR;
3788}
3789
3790// <function-param> ::= fp <top-level CV-Qualifiers> _ # L == 0, first parameter
3791// ::= fp <top-level CV-Qualifiers> <parameter-2 non-negative number> _ # L == 0, second and later parameters
3792// ::= fL <L-1 non-negative number> p <top-level CV-Qualifiers> _ # L > 0, first parameter
3793// ::= fL <L-1 non-negative number> p <top-level CV-Qualifiers> <parameter-2 non-negative number> _ # L > 0, second and later parameters
3794template<typename Alloc> Node *Db<Alloc>::parseFunctionParam() {
3795 if (consumeIf("fp")) {
3796 parseCVQualifiers();
3797 StringView Num = parseNumber();
3798 if (!consumeIf('_'))
3799 return nullptr;
3800 return make<FunctionParam>(Num);
3801 }
3802 if (consumeIf("fL")) {
3803 if (parseNumber().empty())
3804 return nullptr;
3805 if (!consumeIf('p'))
3806 return nullptr;
3807 parseCVQualifiers();
3808 StringView Num = parseNumber();
3809 if (!consumeIf('_'))
3810 return nullptr;
3811 return make<FunctionParam>(Num);
3812 }
3813 return nullptr;
3814}
3815
3816// [gs] nw <expression>* _ <type> E # new (expr-list) type
3817// [gs] nw <expression>* _ <type> <initializer> # new (expr-list) type (init)
3818// [gs] na <expression>* _ <type> E # new[] (expr-list) type
3819// [gs] na <expression>* _ <type> <initializer> # new[] (expr-list) type (init)
3820// <initializer> ::= pi <expression>* E # parenthesized initialization
3821template<typename Alloc> Node *Db<Alloc>::parseNewExpr() {
3822 bool Global = consumeIf("gs");
3823 bool IsArray = look(1) == 'a';
3824 if (!consumeIf("nw") && !consumeIf("na"))
3825 return nullptr;
3826 size_t Exprs = Names.size();
3827 while (!consumeIf('_')) {
3828 Node *Ex = parseExpr();
3829 if (Ex == nullptr)
3830 return nullptr;
3831 Names.push_back(Ex);
3832 }
3833 NodeArray ExprList = popTrailingNodeArray(Exprs);
3834 Node *Ty = parseType();
3835 if (Ty == nullptr)
3836 return Ty;
3837 if (consumeIf("pi")) {
3838 size_t InitsBegin = Names.size();
3839 while (!consumeIf('E')) {
3840 Node *Init = parseExpr();
3841 if (Init == nullptr)
3842 return Init;
3843 Names.push_back(Init);
3844 }
3845 NodeArray Inits = popTrailingNodeArray(InitsBegin);
3846 return make<NewExpr>(ExprList, Ty, Inits, Global, IsArray);
3847 } else if (!consumeIf('E'))
3848 return nullptr;
3849 return make<NewExpr>(ExprList, Ty, NodeArray(), Global, IsArray);
3850}
3851
3852// cv <type> <expression> # conversion with one argument
3853// cv <type> _ <expression>* E # conversion with a different number of arguments
3854template<typename Alloc> Node *Db<Alloc>::parseConversionExpr() {
3855 if (!consumeIf("cv"))
3856 return nullptr;
3857 Node *Ty;
3858 {
3859 SwapAndRestore<bool> SaveTemp(TryToParseTemplateArgs, false);
3860 Ty = parseType();
3861 }
3862
3863 if (Ty == nullptr)
3864 return nullptr;
3865
3866 if (consumeIf('_')) {
3867 size_t ExprsBegin = Names.size();
3868 while (!consumeIf('E')) {
3869 Node *E = parseExpr();
3870 if (E == nullptr)
3871 return E;
3872 Names.push_back(E);
3873 }
3874 NodeArray Exprs = popTrailingNodeArray(ExprsBegin);
3875 return make<ConversionExpr>(Ty, Exprs);
3876 }
3877
3878 Node *E[1] = {parseExpr()};
3879 if (E[0] == nullptr)
3880 return nullptr;
3881 return make<ConversionExpr>(Ty, makeNodeArray(E, E + 1));
3882}
3883
3884// <expr-primary> ::= L <type> <value number> E # integer literal
3885// ::= L <type> <value float> E # floating literal
3886// ::= L <string type> E # string literal
3887// ::= L <nullptr type> E # nullptr literal (i.e., "LDnE")
3888// FIXME: ::= L <type> <real-part float> _ <imag-part float> E # complex floating point literal (C 2000)
3889// ::= L <mangled-name> E # external name
3890template<typename Alloc> Node *Db<Alloc>::parseExprPrimary() {
3891 if (!consumeIf('L'))
3892 return nullptr;
3893 switch (look()) {
3894 case 'w':
3895 ++First;
3896 return parseIntegerLiteral("wchar_t");
3897 case 'b':
3898 if (consumeIf("b0E"))
3899 return make<BoolExpr>(0);
3900 if (consumeIf("b1E"))
3901 return make<BoolExpr>(1);
3902 return nullptr;
3903 case 'c':
3904 ++First;
3905 return parseIntegerLiteral("char");
3906 case 'a':
3907 ++First;
3908 return parseIntegerLiteral("signed char");
3909 case 'h':
3910 ++First;
3911 return parseIntegerLiteral("unsigned char");
3912 case 's':
3913 ++First;
3914 return parseIntegerLiteral("short");
3915 case 't':
3916 ++First;
3917 return parseIntegerLiteral("unsigned short");
3918 case 'i':
3919 ++First;
3920 return parseIntegerLiteral("");
3921 case 'j':
3922 ++First;
3923 return parseIntegerLiteral("u");
3924 case 'l':
3925 ++First;
3926 return parseIntegerLiteral("l");
3927 case 'm':
3928 ++First;
3929 return parseIntegerLiteral("ul");
3930 case 'x':
3931 ++First;
3932 return parseIntegerLiteral("ll");
3933 case 'y':
3934 ++First;
3935 return parseIntegerLiteral("ull");
3936 case 'n':
3937 ++First;
3938 return parseIntegerLiteral("__int128");
3939 case 'o':
3940 ++First;
3941 return parseIntegerLiteral("unsigned __int128");
3942 case 'f':
3943 ++First;
3944 return parseFloatingLiteral<float>();
3945 case 'd':
3946 ++First;
3947 return parseFloatingLiteral<double>();
3948 case 'e':
3949 ++First;
3950 return parseFloatingLiteral<long double>();
3951 case '_':
3952 if (consumeIf("_Z")) {
3953 Node *R = parseEncoding();
3954 if (R != nullptr && consumeIf('E'))
3955 return R;
3956 }
3957 return nullptr;
3958 case 'T':
3959 // Invalid mangled name per
3960 // http://sourcerytools.com/pipermail/cxx-abi-dev/2011-August/002422.html
3961 return nullptr;
3962 default: {
3963 // might be named type
3964 Node *T = parseType();
3965 if (T == nullptr)
3966 return nullptr;
3967 StringView N = parseNumber();
3968 if (!N.empty()) {
3969 if (!consumeIf('E'))
3970 return nullptr;
3971 return make<IntegerCastExpr>(T, N);
3972 }
3973 if (consumeIf('E'))
3974 return T;
3975 return nullptr;
3976 }
3977 }
3978}
3979
3980// <braced-expression> ::= <expression>
3981// ::= di <field source-name> <braced-expression> # .name = expr
3982// ::= dx <index expression> <braced-expression> # [expr] = expr
3983// ::= dX <range begin expression> <range end expression> <braced-expression>
3984template<typename Alloc> Node *Db<Alloc>::parseBracedExpr() {
3985 if (look() == 'd') {
3986 switch (look(1)) {
3987 case 'i': {
3988 First += 2;
3989 Node *Field = parseSourceName(/*NameState=*/nullptr);
3990 if (Field == nullptr)
3991 return nullptr;
3992 Node *Init = parseBracedExpr();
3993 if (Init == nullptr)
3994 return nullptr;
3995 return make<BracedExpr>(Field, Init, /*isArray=*/false);
3996 }
3997 case 'x': {
3998 First += 2;
3999 Node *Index = parseExpr();
4000 if (Index == nullptr)
4001 return nullptr;
4002 Node *Init = parseBracedExpr();
4003 if (Init == nullptr)
4004 return nullptr;
4005 return make<BracedExpr>(Index, Init, /*isArray=*/true);
4006 }
4007 case 'X': {
4008 First += 2;
4009 Node *RangeBegin = parseExpr();
4010 if (RangeBegin == nullptr)
4011 return nullptr;
4012 Node *RangeEnd = parseExpr();
4013 if (RangeEnd == nullptr)
4014 return nullptr;
4015 Node *Init = parseBracedExpr();
4016 if (Init == nullptr)
4017 return nullptr;
4018 return make<BracedRangeExpr>(RangeBegin, RangeEnd, Init);
4019 }
4020 }
4021 }
4022 return parseExpr();
4023}
4024
4025// (not yet in the spec)
4026// <fold-expr> ::= fL <binary-operator-name> <expression> <expression>
4027// ::= fR <binary-operator-name> <expression> <expression>
4028// ::= fl <binary-operator-name> <expression>
4029// ::= fr <binary-operator-name> <expression>
4030template<typename Alloc> Node *Db<Alloc>::parseFoldExpr() {
4031 if (!consumeIf('f'))
4032 return nullptr;
4033
4034 char FoldKind = look();
4035 bool IsLeftFold, HasInitializer;
4036 HasInitializer = FoldKind == 'L' || FoldKind == 'R';
4037 if (FoldKind == 'l' || FoldKind == 'L')
4038 IsLeftFold = true;
4039 else if (FoldKind == 'r' || FoldKind == 'R')
4040 IsLeftFold = false;
4041 else
4042 return nullptr;
4043 ++First;
4044
4045 // FIXME: This map is duplicated in parseOperatorName and parseExpr.
4046 StringView OperatorName;
4047 if (consumeIf("aa")) OperatorName = "&&";
4048 else if (consumeIf("an")) OperatorName = "&";
4049 else if (consumeIf("aN")) OperatorName = "&=";
4050 else if (consumeIf("aS")) OperatorName = "=";
4051 else if (consumeIf("cm")) OperatorName = ",";
4052 else if (consumeIf("ds")) OperatorName = ".*";
4053 else if (consumeIf("dv")) OperatorName = "/";
4054 else if (consumeIf("dV")) OperatorName = "/=";
4055 else if (consumeIf("eo")) OperatorName = "^";
4056 else if (consumeIf("eO")) OperatorName = "^=";
4057 else if (consumeIf("eq")) OperatorName = "==";
4058 else if (consumeIf("ge")) OperatorName = ">=";
4059 else if (consumeIf("gt")) OperatorName = ">";
4060 else if (consumeIf("le")) OperatorName = "<=";
4061 else if (consumeIf("ls")) OperatorName = "<<";
4062 else if (consumeIf("lS")) OperatorName = "<<=";
4063 else if (consumeIf("lt")) OperatorName = "<";
4064 else if (consumeIf("mi")) OperatorName = "-";
4065 else if (consumeIf("mI")) OperatorName = "-=";
4066 else if (consumeIf("ml")) OperatorName = "*";
4067 else if (consumeIf("mL")) OperatorName = "*=";
4068 else if (consumeIf("ne")) OperatorName = "!=";
4069 else if (consumeIf("oo")) OperatorName = "||";
4070 else if (consumeIf("or")) OperatorName = "|";
4071 else if (consumeIf("oR")) OperatorName = "|=";
4072 else if (consumeIf("pl")) OperatorName = "+";
4073 else if (consumeIf("pL")) OperatorName = "+=";
4074 else if (consumeIf("rm")) OperatorName = "%";
4075 else if (consumeIf("rM")) OperatorName = "%=";
4076 else if (consumeIf("rs")) OperatorName = ">>";
4077 else if (consumeIf("rS")) OperatorName = ">>=";
4078 else return nullptr;
4079
4080 Node *Pack = parseExpr(), *Init = nullptr;
4081 if (Pack == nullptr)
4082 return nullptr;
4083 if (HasInitializer) {
4084 Init = parseExpr();
4085 if (Init == nullptr)
4086 return nullptr;
4087 }
4088
4089 if (IsLeftFold && Init)
4090 std::swap(Pack, Init);
4091
4092 return make<FoldExpr>(IsLeftFold, OperatorName, Pack, Init);
4093}
4094
4095// <expression> ::= <unary operator-name> <expression>
4096// ::= <binary operator-name> <expression> <expression>
4097// ::= <ternary operator-name> <expression> <expression> <expression>
4098// ::= cl <expression>+ E # call
4099// ::= cv <type> <expression> # conversion with one argument
4100// ::= cv <type> _ <expression>* E # conversion with a different number of arguments
4101// ::= [gs] nw <expression>* _ <type> E # new (expr-list) type
4102// ::= [gs] nw <expression>* _ <type> <initializer> # new (expr-list) type (init)
4103// ::= [gs] na <expression>* _ <type> E # new[] (expr-list) type
4104// ::= [gs] na <expression>* _ <type> <initializer> # new[] (expr-list) type (init)
4105// ::= [gs] dl <expression> # delete expression
4106// ::= [gs] da <expression> # delete[] expression
4107// ::= pp_ <expression> # prefix ++
4108// ::= mm_ <expression> # prefix --
4109// ::= ti <type> # typeid (type)
4110// ::= te <expression> # typeid (expression)
4111// ::= dc <type> <expression> # dynamic_cast<type> (expression)
4112// ::= sc <type> <expression> # static_cast<type> (expression)
4113// ::= cc <type> <expression> # const_cast<type> (expression)
4114// ::= rc <type> <expression> # reinterpret_cast<type> (expression)
4115// ::= st <type> # sizeof (a type)
4116// ::= sz <expression> # sizeof (an expression)
4117// ::= at <type> # alignof (a type)
4118// ::= az <expression> # alignof (an expression)
4119// ::= nx <expression> # noexcept (expression)
4120// ::= <template-param>
4121// ::= <function-param>
4122// ::= dt <expression> <unresolved-name> # expr.name
4123// ::= pt <expression> <unresolved-name> # expr->name
4124// ::= ds <expression> <expression> # expr.*expr
4125// ::= sZ <template-param> # size of a parameter pack
4126// ::= sZ <function-param> # size of a function parameter pack
4127// ::= sP <template-arg>* E # sizeof...(T), size of a captured template parameter pack from an alias template
4128// ::= sp <expression> # pack expansion
4129// ::= tw <expression> # throw expression
4130// ::= tr # throw with no operand (rethrow)
4131// ::= <unresolved-name> # f(p), N::f(p), ::f(p),
4132// # freestanding dependent name (e.g., T::x),
4133// # objectless nonstatic member reference
4134// ::= fL <binary-operator-name> <expression> <expression>
4135// ::= fR <binary-operator-name> <expression> <expression>
4136// ::= fl <binary-operator-name> <expression>
4137// ::= fr <binary-operator-name> <expression>
4138// ::= <expr-primary>
4139template<typename Alloc> Node *Db<Alloc>::parseExpr() {
4140 bool Global = consumeIf("gs");
4141 if (numLeft() < 2)
4142 return nullptr;
4143
4144 switch (*First) {
4145 case 'L':
4146 return parseExprPrimary();
4147 case 'T':
4148 return parseTemplateParam();
4149 case 'f': {
4150 // Disambiguate a fold expression from a <function-param>.
4151 if (look(1) == 'p' || (look(1) == 'L' && std::isdigit(look(2))))
4152 return parseFunctionParam();
4153 return parseFoldExpr();
4154 }
4155 case 'a':
4156 switch (First[1]) {
4157 case 'a':
4158 First += 2;
4159 return parseBinaryExpr("&&");
4160 case 'd':
4161 First += 2;
4162 return parsePrefixExpr("&");
4163 case 'n':
4164 First += 2;
4165 return parseBinaryExpr("&");
4166 case 'N':
4167 First += 2;
4168 return parseBinaryExpr("&=");
4169 case 'S':
4170 First += 2;
4171 return parseBinaryExpr("=");
4172 case 't': {
4173 First += 2;
4174 Node *Ty = parseType();
4175 if (Ty == nullptr)
4176 return nullptr;
4177 return make<EnclosingExpr>("alignof (", Ty, ")");
4178 }
4179 case 'z': {
4180 First += 2;
4181 Node *Ty = parseExpr();
4182 if (Ty == nullptr)
4183 return nullptr;
4184 return make<EnclosingExpr>("alignof (", Ty, ")");
4185 }
4186 }
4187 return nullptr;
4188 case 'c':
4189 switch (First[1]) {
4190 // cc <type> <expression> # const_cast<type>(expression)
4191 case 'c': {
4192 First += 2;
4193 Node *Ty = parseType();
4194 if (Ty == nullptr)
4195 return Ty;
4196 Node *Ex = parseExpr();
4197 if (Ex == nullptr)
4198 return Ex;
4199 return make<CastExpr>("const_cast", Ty, Ex);
4200 }
4201 // cl <expression>+ E # call
4202 case 'l': {
4203 First += 2;
4204 Node *Callee = parseExpr();
4205 if (Callee == nullptr)
4206 return Callee;
4207 size_t ExprsBegin = Names.size();
4208 while (!consumeIf('E')) {
4209 Node *E = parseExpr();
4210 if (E == nullptr)
4211 return E;
4212 Names.push_back(E);
4213 }
4214 return make<CallExpr>(Callee, popTrailingNodeArray(ExprsBegin));
4215 }
4216 case 'm':
4217 First += 2;
4218 return parseBinaryExpr(",");
4219 case 'o':
4220 First += 2;
4221 return parsePrefixExpr("~");
4222 case 'v':
4223 return parseConversionExpr();
4224 }
4225 return nullptr;
4226 case 'd':
4227 switch (First[1]) {
4228 case 'a': {
4229 First += 2;
4230 Node *Ex = parseExpr();
4231 if (Ex == nullptr)
4232 return Ex;
4233 return make<DeleteExpr>(Ex, Global, /*is_array=*/true);
4234 }
4235 case 'c': {
4236 First += 2;
4237 Node *T = parseType();
4238 if (T == nullptr)
4239 return T;
4240 Node *Ex = parseExpr();
4241 if (Ex == nullptr)
4242 return Ex;
4243 return make<CastExpr>("dynamic_cast", T, Ex);
4244 }
4245 case 'e':
4246 First += 2;
4247 return parsePrefixExpr("*");
4248 case 'l': {
4249 First += 2;
4250 Node *E = parseExpr();
4251 if (E == nullptr)
4252 return E;
4253 return make<DeleteExpr>(E, Global, /*is_array=*/false);
4254 }
4255 case 'n':
4256 return parseUnresolvedName();
4257 case 's': {
4258 First += 2;
4259 Node *LHS = parseExpr();
4260 if (LHS == nullptr)
4261 return nullptr;
4262 Node *RHS = parseExpr();
4263 if (RHS == nullptr)
4264 return nullptr;
4265 return make<MemberExpr>(LHS, ".*", RHS);
4266 }
4267 case 't': {
4268 First += 2;
4269 Node *LHS = parseExpr();
4270 if (LHS == nullptr)
4271 return LHS;
4272 Node *RHS = parseExpr();
4273 if (RHS == nullptr)
4274 return nullptr;
4275 return make<MemberExpr>(LHS, ".", RHS);
4276 }
4277 case 'v':
4278 First += 2;
4279 return parseBinaryExpr("/");
4280 case 'V':
4281 First += 2;
4282 return parseBinaryExpr("/=");
4283 }
4284 return nullptr;
4285 case 'e':
4286 switch (First[1]) {
4287 case 'o':
4288 First += 2;
4289 return parseBinaryExpr("^");
4290 case 'O':
4291 First += 2;
4292 return parseBinaryExpr("^=");
4293 case 'q':
4294 First += 2;
4295 return parseBinaryExpr("==");
4296 }
4297 return nullptr;
4298 case 'g':
4299 switch (First[1]) {
4300 case 'e':
4301 First += 2;
4302 return parseBinaryExpr(">=");
4303 case 't':
4304 First += 2;
4305 return parseBinaryExpr(">");
4306 }
4307 return nullptr;
4308 case 'i':
4309 switch (First[1]) {
4310 case 'x': {
4311 First += 2;
4312 Node *Base = parseExpr();
4313 if (Base == nullptr)
4314 return nullptr;
4315 Node *Index = parseExpr();
4316 if (Index == nullptr)
4317 return Index;
4318 return make<ArraySubscriptExpr>(Base, Index);
4319 }
4320 case 'l': {
4321 First += 2;
4322 size_t InitsBegin = Names.size();
4323 while (!consumeIf('E')) {
4324 Node *E = parseBracedExpr();
4325 if (E == nullptr)
4326 return nullptr;
4327 Names.push_back(E);
4328 }
4329 return make<InitListExpr>(nullptr, popTrailingNodeArray(InitsBegin));
4330 }
4331 }
4332 return nullptr;
4333 case 'l':
4334 switch (First[1]) {
4335 case 'e':
4336 First += 2;
4337 return parseBinaryExpr("<=");
4338 case 's':
4339 First += 2;
4340 return parseBinaryExpr("<<");
4341 case 'S':
4342 First += 2;
4343 return parseBinaryExpr("<<=");
4344 case 't':
4345 First += 2;
4346 return parseBinaryExpr("<");
4347 }
4348 return nullptr;
4349 case 'm':
4350 switch (First[1]) {
4351 case 'i':
4352 First += 2;
4353 return parseBinaryExpr("-");
4354 case 'I':
4355 First += 2;
4356 return parseBinaryExpr("-=");
4357 case 'l':
4358 First += 2;
4359 return parseBinaryExpr("*");
4360 case 'L':
4361 First += 2;
4362 return parseBinaryExpr("*=");
4363 case 'm':
4364 First += 2;
4365 if (consumeIf('_'))
4366 return parsePrefixExpr("--");
4367 Node *Ex = parseExpr();
4368 if (Ex == nullptr)
4369 return nullptr;
4370 return make<PostfixExpr>(Ex, "--");
4371 }
4372 return nullptr;
4373 case 'n':
4374 switch (First[1]) {
4375 case 'a':
4376 case 'w':
4377 return parseNewExpr();
4378 case 'e':
4379 First += 2;
4380 return parseBinaryExpr("!=");
4381 case 'g':
4382 First += 2;
4383 return parsePrefixExpr("-");
4384 case 't':
4385 First += 2;
4386 return parsePrefixExpr("!");
4387 case 'x':
4388 First += 2;
4389 Node *Ex = parseExpr();
4390 if (Ex == nullptr)
4391 return Ex;
4392 return make<EnclosingExpr>("noexcept (", Ex, ")");
4393 }
4394 return nullptr;
4395 case 'o':
4396 switch (First[1]) {
4397 case 'n':
4398 return parseUnresolvedName();
4399 case 'o':
4400 First += 2;
4401 return parseBinaryExpr("||");
4402 case 'r':
4403 First += 2;
4404 return parseBinaryExpr("|");
4405 case 'R':
4406 First += 2;
4407 return parseBinaryExpr("|=");
4408 }
4409 return nullptr;
4410 case 'p':
4411 switch (First[1]) {
4412 case 'm':
4413 First += 2;
4414 return parseBinaryExpr("->*");
4415 case 'l':
4416 First += 2;
4417 return parseBinaryExpr("+");
4418 case 'L':
4419 First += 2;
4420 return parseBinaryExpr("+=");
4421 case 'p': {
4422 First += 2;
4423 if (consumeIf('_'))
4424 return parsePrefixExpr("++");
4425 Node *Ex = parseExpr();
4426 if (Ex == nullptr)
4427 return Ex;
4428 return make<PostfixExpr>(Ex, "++");
4429 }
4430 case 's':
4431 First += 2;
4432 return parsePrefixExpr("+");
4433 case 't': {
4434 First += 2;
4435 Node *L = parseExpr();
4436 if (L == nullptr)
4437 return nullptr;
4438 Node *R = parseExpr();
4439 if (R == nullptr)
4440 return nullptr;
4441 return make<MemberExpr>(L, "->", R);
4442 }
4443 }
4444 return nullptr;
4445 case 'q':
4446 if (First[1] == 'u') {
4447 First += 2;
4448 Node *Cond = parseExpr();
4449 if (Cond == nullptr)
4450 return nullptr;
4451 Node *LHS = parseExpr();
4452 if (LHS == nullptr)
4453 return nullptr;
4454 Node *RHS = parseExpr();
4455 if (RHS == nullptr)
4456 return nullptr;
4457 return make<ConditionalExpr>(Cond, LHS, RHS);
4458 }
4459 return nullptr;
4460 case 'r':
4461 switch (First[1]) {
4462 case 'c': {
4463 First += 2;
4464 Node *T = parseType();
4465 if (T == nullptr)
4466 return T;
4467 Node *Ex = parseExpr();
4468 if (Ex == nullptr)
4469 return Ex;
4470 return make<CastExpr>("reinterpret_cast", T, Ex);
4471 }
4472 case 'm':
4473 First += 2;
4474 return parseBinaryExpr("%");
4475 case 'M':
4476 First += 2;
4477 return parseBinaryExpr("%=");
4478 case 's':
4479 First += 2;
4480 return parseBinaryExpr(">>");
4481 case 'S':
4482 First += 2;
4483 return parseBinaryExpr(">>=");
4484 }
4485 return nullptr;
4486 case 's':
4487 switch (First[1]) {
4488 case 'c': {
4489 First += 2;
4490 Node *T = parseType();
4491 if (T == nullptr)
4492 return T;
4493 Node *Ex = parseExpr();
4494 if (Ex == nullptr)
4495 return Ex;
4496 return make<CastExpr>("static_cast", T, Ex);
4497 }
4498 case 'p': {
4499 First += 2;
4500 Node *Child = parseExpr();
4501 if (Child == nullptr)
4502 return nullptr;
4503 return make<ParameterPackExpansion>(Child);
4504 }
4505 case 'r':
4506 return parseUnresolvedName();
4507 case 't': {
4508 First += 2;
4509 Node *Ty = parseType();
4510 if (Ty == nullptr)
4511 return Ty;
4512 return make<EnclosingExpr>("sizeof (", Ty, ")");
4513 }
4514 case 'z': {
4515 First += 2;
4516 Node *Ex = parseExpr();
4517 if (Ex == nullptr)
4518 return Ex;
4519 return make<EnclosingExpr>("sizeof (", Ex, ")");
4520 }
4521 case 'Z':
4522 First += 2;
4523 if (look() == 'T') {
4524 Node *R = parseTemplateParam();
4525 if (R == nullptr)
4526 return nullptr;
4527 return make<SizeofParamPackExpr>(R);
4528 } else if (look() == 'f') {
4529 Node *FP = parseFunctionParam();
4530 if (FP == nullptr)
4531 return nullptr;
4532 return make<EnclosingExpr>("sizeof... (", FP, ")");
4533 }
4534 return nullptr;
4535 case 'P': {
4536 First += 2;
4537 size_t ArgsBegin = Names.size();
4538 while (!consumeIf('E')) {
4539 Node *Arg = parseTemplateArg();
4540 if (Arg == nullptr)
4541 return nullptr;
4542 Names.push_back(Arg);
4543 }
Richard Smithb485b352018-08-24 23:30:26 +00004544 auto *Pack = make<NodeArrayNode>(popTrailingNodeArray(ArgsBegin));
4545 if (!Pack)
4546 return nullptr;
4547 return make<EnclosingExpr>("sizeof... (", Pack, ")");
Richard Smithc20d1442018-08-20 20:14:49 +00004548 }
4549 }
4550 return nullptr;
4551 case 't':
4552 switch (First[1]) {
4553 case 'e': {
4554 First += 2;
4555 Node *Ex = parseExpr();
4556 if (Ex == nullptr)
4557 return Ex;
4558 return make<EnclosingExpr>("typeid (", Ex, ")");
4559 }
4560 case 'i': {
4561 First += 2;
4562 Node *Ty = parseType();
4563 if (Ty == nullptr)
4564 return Ty;
4565 return make<EnclosingExpr>("typeid (", Ty, ")");
4566 }
4567 case 'l': {
4568 First += 2;
4569 Node *Ty = parseType();
4570 if (Ty == nullptr)
4571 return nullptr;
4572 size_t InitsBegin = Names.size();
4573 while (!consumeIf('E')) {
4574 Node *E = parseBracedExpr();
4575 if (E == nullptr)
4576 return nullptr;
4577 Names.push_back(E);
4578 }
4579 return make<InitListExpr>(Ty, popTrailingNodeArray(InitsBegin));
4580 }
4581 case 'r':
4582 First += 2;
4583 return make<NameType>("throw");
4584 case 'w': {
4585 First += 2;
4586 Node *Ex = parseExpr();
4587 if (Ex == nullptr)
4588 return nullptr;
4589 return make<ThrowExpr>(Ex);
4590 }
4591 }
4592 return nullptr;
4593 case '1':
4594 case '2':
4595 case '3':
4596 case '4':
4597 case '5':
4598 case '6':
4599 case '7':
4600 case '8':
4601 case '9':
4602 return parseUnresolvedName();
4603 }
4604 return nullptr;
4605}
4606
4607// <call-offset> ::= h <nv-offset> _
4608// ::= v <v-offset> _
4609//
4610// <nv-offset> ::= <offset number>
4611// # non-virtual base override
4612//
4613// <v-offset> ::= <offset number> _ <virtual offset number>
4614// # virtual base override, with vcall offset
4615template<typename Alloc> bool Db<Alloc>::parseCallOffset() {
4616 // Just scan through the call offset, we never add this information into the
4617 // output.
4618 if (consumeIf('h'))
4619 return parseNumber(true).empty() || !consumeIf('_');
4620 if (consumeIf('v'))
4621 return parseNumber(true).empty() || !consumeIf('_') ||
4622 parseNumber(true).empty() || !consumeIf('_');
4623 return true;
4624}
4625
4626// <special-name> ::= TV <type> # virtual table
4627// ::= TT <type> # VTT structure (construction vtable index)
4628// ::= TI <type> # typeinfo structure
4629// ::= TS <type> # typeinfo name (null-terminated byte string)
4630// ::= Tc <call-offset> <call-offset> <base encoding>
4631// # base is the nominal target function of thunk
4632// # first call-offset is 'this' adjustment
4633// # second call-offset is result adjustment
4634// ::= T <call-offset> <base encoding>
4635// # base is the nominal target function of thunk
4636// ::= GV <object name> # Guard variable for one-time initialization
4637// # No <type>
4638// ::= TW <object name> # Thread-local wrapper
4639// ::= TH <object name> # Thread-local initialization
4640// ::= GR <object name> _ # First temporary
4641// ::= GR <object name> <seq-id> _ # Subsequent temporaries
4642// extension ::= TC <first type> <number> _ <second type> # construction vtable for second-in-first
4643// extension ::= GR <object name> # reference temporary for object
4644template<typename Alloc> Node *Db<Alloc>::parseSpecialName() {
4645 switch (look()) {
4646 case 'T':
4647 switch (look(1)) {
4648 // TV <type> # virtual table
4649 case 'V': {
4650 First += 2;
4651 Node *Ty = parseType();
4652 if (Ty == nullptr)
4653 return nullptr;
4654 return make<SpecialName>("vtable for ", Ty);
4655 }
4656 // TT <type> # VTT structure (construction vtable index)
4657 case 'T': {
4658 First += 2;
4659 Node *Ty = parseType();
4660 if (Ty == nullptr)
4661 return nullptr;
4662 return make<SpecialName>("VTT for ", Ty);
4663 }
4664 // TI <type> # typeinfo structure
4665 case 'I': {
4666 First += 2;
4667 Node *Ty = parseType();
4668 if (Ty == nullptr)
4669 return nullptr;
4670 return make<SpecialName>("typeinfo for ", Ty);
4671 }
4672 // TS <type> # typeinfo name (null-terminated byte string)
4673 case 'S': {
4674 First += 2;
4675 Node *Ty = parseType();
4676 if (Ty == nullptr)
4677 return nullptr;
4678 return make<SpecialName>("typeinfo name for ", Ty);
4679 }
4680 // Tc <call-offset> <call-offset> <base encoding>
4681 case 'c': {
4682 First += 2;
4683 if (parseCallOffset() || parseCallOffset())
4684 return nullptr;
4685 Node *Encoding = parseEncoding();
4686 if (Encoding == nullptr)
4687 return nullptr;
4688 return make<SpecialName>("covariant return thunk to ", Encoding);
4689 }
4690 // extension ::= TC <first type> <number> _ <second type>
4691 // # construction vtable for second-in-first
4692 case 'C': {
4693 First += 2;
4694 Node *FirstType = parseType();
4695 if (FirstType == nullptr)
4696 return nullptr;
4697 if (parseNumber(true).empty() || !consumeIf('_'))
4698 return nullptr;
4699 Node *SecondType = parseType();
4700 if (SecondType == nullptr)
4701 return nullptr;
4702 return make<CtorVtableSpecialName>(SecondType, FirstType);
4703 }
4704 // TW <object name> # Thread-local wrapper
4705 case 'W': {
4706 First += 2;
4707 Node *Name = parseName();
4708 if (Name == nullptr)
4709 return nullptr;
4710 return make<SpecialName>("thread-local wrapper routine for ", Name);
4711 }
4712 // TH <object name> # Thread-local initialization
4713 case 'H': {
4714 First += 2;
4715 Node *Name = parseName();
4716 if (Name == nullptr)
4717 return nullptr;
4718 return make<SpecialName>("thread-local initialization routine for ", Name);
4719 }
4720 // T <call-offset> <base encoding>
4721 default: {
4722 ++First;
4723 bool IsVirt = look() == 'v';
4724 if (parseCallOffset())
4725 return nullptr;
4726 Node *BaseEncoding = parseEncoding();
4727 if (BaseEncoding == nullptr)
4728 return nullptr;
4729 if (IsVirt)
4730 return make<SpecialName>("virtual thunk to ", BaseEncoding);
4731 else
4732 return make<SpecialName>("non-virtual thunk to ", BaseEncoding);
4733 }
4734 }
4735 case 'G':
4736 switch (look(1)) {
4737 // GV <object name> # Guard variable for one-time initialization
4738 case 'V': {
4739 First += 2;
4740 Node *Name = parseName();
4741 if (Name == nullptr)
4742 return nullptr;
4743 return make<SpecialName>("guard variable for ", Name);
4744 }
4745 // GR <object name> # reference temporary for object
4746 // GR <object name> _ # First temporary
4747 // GR <object name> <seq-id> _ # Subsequent temporaries
4748 case 'R': {
4749 First += 2;
4750 Node *Name = parseName();
4751 if (Name == nullptr)
4752 return nullptr;
4753 size_t Count;
4754 bool ParsedSeqId = !parseSeqId(&Count);
4755 if (!consumeIf('_') && ParsedSeqId)
4756 return nullptr;
4757 return make<SpecialName>("reference temporary for ", Name);
4758 }
4759 }
4760 }
4761 return nullptr;
4762}
4763
4764// <encoding> ::= <function name> <bare-function-type>
4765// ::= <data name>
4766// ::= <special-name>
4767template<typename Alloc> Node *Db<Alloc>::parseEncoding() {
4768 if (look() == 'G' || look() == 'T')
4769 return parseSpecialName();
4770
4771 auto IsEndOfEncoding = [&] {
4772 // The set of chars that can potentially follow an <encoding> (none of which
4773 // can start a <type>). Enumerating these allows us to avoid speculative
4774 // parsing.
4775 return numLeft() == 0 || look() == 'E' || look() == '.' || look() == '_';
4776 };
4777
4778 NameState NameInfo(this);
4779 Node *Name = parseName(&NameInfo);
4780 if (Name == nullptr)
4781 return nullptr;
4782
4783 if (resolveForwardTemplateRefs(NameInfo))
4784 return nullptr;
4785
4786 if (IsEndOfEncoding())
4787 return Name;
4788
4789 Node *Attrs = nullptr;
4790 if (consumeIf("Ua9enable_ifI")) {
4791 size_t BeforeArgs = Names.size();
4792 while (!consumeIf('E')) {
4793 Node *Arg = parseTemplateArg();
4794 if (Arg == nullptr)
4795 return nullptr;
4796 Names.push_back(Arg);
4797 }
4798 Attrs = make<EnableIfAttr>(popTrailingNodeArray(BeforeArgs));
Richard Smithb485b352018-08-24 23:30:26 +00004799 if (!Attrs)
4800 return nullptr;
Richard Smithc20d1442018-08-20 20:14:49 +00004801 }
4802
4803 Node *ReturnType = nullptr;
4804 if (!NameInfo.CtorDtorConversion && NameInfo.EndsWithTemplateArgs) {
4805 ReturnType = parseType();
4806 if (ReturnType == nullptr)
4807 return nullptr;
4808 }
4809
4810 if (consumeIf('v'))
4811 return make<FunctionEncoding>(ReturnType, Name, NodeArray(),
4812 Attrs, NameInfo.CVQualifiers,
4813 NameInfo.ReferenceQualifier);
4814
4815 size_t ParamsBegin = Names.size();
4816 do {
4817 Node *Ty = parseType();
4818 if (Ty == nullptr)
4819 return nullptr;
4820 Names.push_back(Ty);
4821 } while (!IsEndOfEncoding());
4822
4823 return make<FunctionEncoding>(ReturnType, Name,
4824 popTrailingNodeArray(ParamsBegin),
4825 Attrs, NameInfo.CVQualifiers,
4826 NameInfo.ReferenceQualifier);
4827}
4828
4829template <class Float>
4830struct FloatData;
4831
4832template <>
4833struct FloatData<float>
4834{
4835 static const size_t mangled_size = 8;
4836 static const size_t max_demangled_size = 24;
4837 static constexpr const char* spec = "%af";
4838};
4839
4840template <>
4841struct FloatData<double>
4842{
4843 static const size_t mangled_size = 16;
4844 static const size_t max_demangled_size = 32;
4845 static constexpr const char* spec = "%a";
4846};
4847
4848template <>
4849struct FloatData<long double>
4850{
4851#if defined(__mips__) && defined(__mips_n64) || defined(__aarch64__) || \
4852 defined(__wasm__)
4853 static const size_t mangled_size = 32;
4854#elif defined(__arm__) || defined(__mips__) || defined(__hexagon__)
4855 static const size_t mangled_size = 16;
4856#else
4857 static const size_t mangled_size = 20; // May need to be adjusted to 16 or 24 on other platforms
4858#endif
4859 static const size_t max_demangled_size = 40;
4860 static constexpr const char *spec = "%LaL";
4861};
4862
4863template<typename Alloc>
4864template<class Float>
4865Node *Db<Alloc>::parseFloatingLiteral() {
4866 const size_t N = FloatData<Float>::mangled_size;
4867 if (numLeft() <= N)
4868 return nullptr;
4869 StringView Data(First, First + N);
4870 for (char C : Data)
4871 if (!std::isxdigit(C))
4872 return nullptr;
4873 First += N;
4874 if (!consumeIf('E'))
4875 return nullptr;
4876 return make<FloatLiteralImpl<Float>>(Data);
4877}
4878
4879// <seq-id> ::= <0-9A-Z>+
4880template<typename Alloc> bool Db<Alloc>::parseSeqId(size_t *Out) {
4881 if (!(look() >= '0' && look() <= '9') &&
4882 !(look() >= 'A' && look() <= 'Z'))
4883 return true;
4884
4885 size_t Id = 0;
4886 while (true) {
4887 if (look() >= '0' && look() <= '9') {
4888 Id *= 36;
4889 Id += static_cast<size_t>(look() - '0');
4890 } else if (look() >= 'A' && look() <= 'Z') {
4891 Id *= 36;
4892 Id += static_cast<size_t>(look() - 'A') + 10;
4893 } else {
4894 *Out = Id;
4895 return false;
4896 }
4897 ++First;
4898 }
4899}
4900
4901// <substitution> ::= S <seq-id> _
4902// ::= S_
4903// <substitution> ::= Sa # ::std::allocator
4904// <substitution> ::= Sb # ::std::basic_string
4905// <substitution> ::= Ss # ::std::basic_string < char,
4906// ::std::char_traits<char>,
4907// ::std::allocator<char> >
4908// <substitution> ::= Si # ::std::basic_istream<char, std::char_traits<char> >
4909// <substitution> ::= So # ::std::basic_ostream<char, std::char_traits<char> >
4910// <substitution> ::= Sd # ::std::basic_iostream<char, std::char_traits<char> >
4911template<typename Alloc> Node *Db<Alloc>::parseSubstitution() {
4912 if (!consumeIf('S'))
4913 return nullptr;
4914
4915 if (std::islower(look())) {
4916 Node *SpecialSub;
4917 switch (look()) {
4918 case 'a':
4919 ++First;
4920 SpecialSub = make<SpecialSubstitution>(SpecialSubKind::allocator);
4921 break;
4922 case 'b':
4923 ++First;
4924 SpecialSub = make<SpecialSubstitution>(SpecialSubKind::basic_string);
4925 break;
4926 case 's':
4927 ++First;
4928 SpecialSub = make<SpecialSubstitution>(SpecialSubKind::string);
4929 break;
4930 case 'i':
4931 ++First;
4932 SpecialSub = make<SpecialSubstitution>(SpecialSubKind::istream);
4933 break;
4934 case 'o':
4935 ++First;
4936 SpecialSub = make<SpecialSubstitution>(SpecialSubKind::ostream);
4937 break;
4938 case 'd':
4939 ++First;
4940 SpecialSub = make<SpecialSubstitution>(SpecialSubKind::iostream);
4941 break;
4942 default:
4943 return nullptr;
4944 }
Richard Smithb485b352018-08-24 23:30:26 +00004945 if (!SpecialSub)
4946 return nullptr;
Richard Smithc20d1442018-08-20 20:14:49 +00004947 // Itanium C++ ABI 5.1.2: If a name that would use a built-in <substitution>
4948 // has ABI tags, the tags are appended to the substitution; the result is a
4949 // substitutable component.
4950 Node *WithTags = parseAbiTags(SpecialSub);
4951 if (WithTags != SpecialSub) {
4952 Subs.push_back(WithTags);
4953 SpecialSub = WithTags;
4954 }
4955 return SpecialSub;
4956 }
4957
4958 // ::= S_
4959 if (consumeIf('_')) {
4960 if (Subs.empty())
4961 return nullptr;
4962 return Subs[0];
4963 }
4964
4965 // ::= S <seq-id> _
4966 size_t Index = 0;
4967 if (parseSeqId(&Index))
4968 return nullptr;
4969 ++Index;
4970 if (!consumeIf('_') || Index >= Subs.size())
4971 return nullptr;
4972 return Subs[Index];
4973}
4974
4975// <template-param> ::= T_ # first template parameter
4976// ::= T <parameter-2 non-negative number> _
4977template<typename Alloc> Node *Db<Alloc>::parseTemplateParam() {
4978 if (!consumeIf('T'))
4979 return nullptr;
4980
4981 size_t Index = 0;
4982 if (!consumeIf('_')) {
4983 if (parsePositiveInteger(&Index))
4984 return nullptr;
4985 ++Index;
4986 if (!consumeIf('_'))
4987 return nullptr;
4988 }
4989
4990 // Itanium ABI 5.1.8: In a generic lambda, uses of auto in the parameter list
4991 // are mangled as the corresponding artificial template type parameter.
4992 if (ParsingLambdaParams)
4993 return make<NameType>("auto");
4994
4995 // If we're in a context where this <template-param> refers to a
4996 // <template-arg> further ahead in the mangled name (currently just conversion
4997 // operator types), then we should only look it up in the right context.
4998 if (PermitForwardTemplateReferences) {
Richard Smithb485b352018-08-24 23:30:26 +00004999 Node *ForwardRef = make<ForwardTemplateReference>(Index);
5000 if (!ForwardRef)
5001 return nullptr;
5002 assert(ForwardRef->getKind() == Node::KForwardTemplateReference);
5003 ForwardTemplateRefs.push_back(
5004 static_cast<ForwardTemplateReference *>(ForwardRef));
5005 return ForwardRef;
Richard Smithc20d1442018-08-20 20:14:49 +00005006 }
5007
5008 if (Index >= TemplateParams.size())
5009 return nullptr;
5010 return TemplateParams[Index];
5011}
5012
5013// <template-arg> ::= <type> # type or template
5014// ::= X <expression> E # expression
5015// ::= <expr-primary> # simple expressions
5016// ::= J <template-arg>* E # argument pack
5017// ::= LZ <encoding> E # extension
5018template<typename Alloc> Node *Db<Alloc>::parseTemplateArg() {
5019 switch (look()) {
5020 case 'X': {
5021 ++First;
5022 Node *Arg = parseExpr();
5023 if (Arg == nullptr || !consumeIf('E'))
5024 return nullptr;
5025 return Arg;
5026 }
5027 case 'J': {
5028 ++First;
5029 size_t ArgsBegin = Names.size();
5030 while (!consumeIf('E')) {
5031 Node *Arg = parseTemplateArg();
5032 if (Arg == nullptr)
5033 return nullptr;
5034 Names.push_back(Arg);
5035 }
5036 NodeArray Args = popTrailingNodeArray(ArgsBegin);
5037 return make<TemplateArgumentPack>(Args);
5038 }
5039 case 'L': {
5040 // ::= LZ <encoding> E # extension
5041 if (look(1) == 'Z') {
5042 First += 2;
5043 Node *Arg = parseEncoding();
5044 if (Arg == nullptr || !consumeIf('E'))
5045 return nullptr;
5046 return Arg;
5047 }
5048 // ::= <expr-primary> # simple expressions
5049 return parseExprPrimary();
5050 }
5051 default:
5052 return parseType();
5053 }
5054}
5055
5056// <template-args> ::= I <template-arg>* E
5057// extension, the abi says <template-arg>+
5058template <typename Alloc>
5059Node *Db<Alloc>::parseTemplateArgs(bool TagTemplates) {
5060 if (!consumeIf('I'))
5061 return nullptr;
5062
5063 // <template-params> refer to the innermost <template-args>. Clear out any
5064 // outer args that we may have inserted into TemplateParams.
5065 if (TagTemplates)
5066 TemplateParams.clear();
5067
5068 size_t ArgsBegin = Names.size();
5069 while (!consumeIf('E')) {
5070 if (TagTemplates) {
5071 auto OldParams = std::move(TemplateParams);
5072 Node *Arg = parseTemplateArg();
5073 TemplateParams = std::move(OldParams);
5074 if (Arg == nullptr)
5075 return nullptr;
5076 Names.push_back(Arg);
5077 Node *TableEntry = Arg;
5078 if (Arg->getKind() == Node::KTemplateArgumentPack) {
5079 TableEntry = make<ParameterPack>(
5080 static_cast<TemplateArgumentPack*>(TableEntry)->getElements());
Richard Smithb485b352018-08-24 23:30:26 +00005081 if (!TableEntry)
5082 return nullptr;
Richard Smithc20d1442018-08-20 20:14:49 +00005083 }
5084 TemplateParams.push_back(TableEntry);
5085 } else {
5086 Node *Arg = parseTemplateArg();
5087 if (Arg == nullptr)
5088 return nullptr;
5089 Names.push_back(Arg);
5090 }
5091 }
5092 return make<TemplateArgs>(popTrailingNodeArray(ArgsBegin));
5093}
5094
5095// <mangled-name> ::= _Z <encoding>
5096// ::= <type>
5097// extension ::= ___Z <encoding> _block_invoke
5098// extension ::= ___Z <encoding> _block_invoke<decimal-digit>+
5099// extension ::= ___Z <encoding> _block_invoke_<decimal-digit>+
5100template<typename Alloc> Node *Db<Alloc>::parse() {
5101 if (consumeIf("_Z")) {
5102 Node *Encoding = parseEncoding();
5103 if (Encoding == nullptr)
5104 return nullptr;
5105 if (look() == '.') {
5106 Encoding = make<DotSuffix>(Encoding, StringView(First, Last));
5107 First = Last;
5108 }
5109 if (numLeft() != 0)
5110 return nullptr;
5111 return Encoding;
5112 }
5113
5114 if (consumeIf("___Z")) {
5115 Node *Encoding = parseEncoding();
5116 if (Encoding == nullptr || !consumeIf("_block_invoke"))
5117 return nullptr;
5118 bool RequireNumber = consumeIf('_');
5119 if (parseNumber().empty() && RequireNumber)
5120 return nullptr;
5121 if (look() == '.')
5122 First = Last;
5123 if (numLeft() != 0)
5124 return nullptr;
5125 return make<SpecialName>("invocation function for block in ", Encoding);
5126 }
5127
5128 Node *Ty = parseType();
5129 if (numLeft() != 0)
5130 return nullptr;
5131 return Ty;
5132}
5133
5134} // namespace itanium_demangle
5135} // namespace
5136
5137#endif // LIBCXX_DEMANGLE_ITANIUMDEMANGLE_H