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