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