Run DCE after a LoopFlatten test to reduce spurious output [nfc]
[llvm-project.git] / libcxxabi / src / demangle / ItaniumDemangle.h
blob2336b84da293bcc73fe40663a26fed987090e8d8
1 //===------------------------- ItaniumDemangle.h ----------------*- C++ -*-===//
2 //
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.
14 //===----------------------------------------------------------------------===//
16 #ifndef DEMANGLE_ITANIUMDEMANGLE_H
17 #define DEMANGLE_ITANIUMDEMANGLE_H
19 #include "DemangleConfig.h"
20 #include "StringViewExtras.h"
21 #include "Utility.h"
22 #include <__cxxabi_config.h>
23 #include <algorithm>
24 #include <cassert>
25 #include <cctype>
26 #include <cstdio>
27 #include <cstdlib>
28 #include <cstring>
29 #include <limits>
30 #include <new>
31 #include <string_view>
32 #include <type_traits>
33 #include <utility>
35 #ifdef _LIBCXXABI_COMPILER_CLANG
36 #pragma clang diagnostic push
37 #pragma clang diagnostic ignored "-Wunused-template"
38 #endif
40 DEMANGLE_NAMESPACE_BEGIN
42 template <class T, size_t N> class PODSmallVector {
43 static_assert(std::is_pod<T>::value,
44 "T is required to be a plain old data type");
46 T *First = nullptr;
47 T *Last = nullptr;
48 T *Cap = nullptr;
49 T Inline[N] = {0};
51 bool isInline() const { return First == Inline; }
53 void clearInline() {
54 First = Inline;
55 Last = Inline;
56 Cap = Inline + N;
59 void reserve(size_t NewCap) {
60 size_t S = size();
61 if (isInline()) {
62 auto *Tmp = static_cast<T *>(std::malloc(NewCap * sizeof(T)));
63 if (Tmp == nullptr)
64 std::abort();
65 std::copy(First, Last, Tmp);
66 First = Tmp;
67 } else {
68 First = static_cast<T *>(std::realloc(First, NewCap * sizeof(T)));
69 if (First == nullptr)
70 std::abort();
72 Last = First + S;
73 Cap = First + NewCap;
76 public:
77 PODSmallVector() : First(Inline), Last(First), Cap(Inline + N) {}
79 PODSmallVector(const PODSmallVector &) = delete;
80 PODSmallVector &operator=(const PODSmallVector &) = delete;
82 PODSmallVector(PODSmallVector &&Other) : PODSmallVector() {
83 if (Other.isInline()) {
84 std::copy(Other.begin(), Other.end(), First);
85 Last = First + Other.size();
86 Other.clear();
87 return;
90 First = Other.First;
91 Last = Other.Last;
92 Cap = Other.Cap;
93 Other.clearInline();
96 PODSmallVector &operator=(PODSmallVector &&Other) {
97 if (Other.isInline()) {
98 if (!isInline()) {
99 std::free(First);
100 clearInline();
102 std::copy(Other.begin(), Other.end(), First);
103 Last = First + Other.size();
104 Other.clear();
105 return *this;
108 if (isInline()) {
109 First = Other.First;
110 Last = Other.Last;
111 Cap = Other.Cap;
112 Other.clearInline();
113 return *this;
116 std::swap(First, Other.First);
117 std::swap(Last, Other.Last);
118 std::swap(Cap, Other.Cap);
119 Other.clear();
120 return *this;
123 // NOLINTNEXTLINE(readability-identifier-naming)
124 void push_back(const T &Elem) {
125 if (Last == Cap)
126 reserve(size() * 2);
127 *Last++ = Elem;
130 // NOLINTNEXTLINE(readability-identifier-naming)
131 void pop_back() {
132 assert(Last != First && "Popping empty vector!");
133 --Last;
136 void shrinkToSize(size_t Index) {
137 assert(Index <= size() && "shrinkToSize() can't expand!");
138 Last = First + Index;
141 T *begin() { return First; }
142 T *end() { return Last; }
144 bool empty() const { return First == Last; }
145 size_t size() const { return static_cast<size_t>(Last - First); }
146 T &back() {
147 assert(Last != First && "Calling back() on empty vector!");
148 return *(Last - 1);
150 T &operator[](size_t Index) {
151 assert(Index < size() && "Invalid access!");
152 return *(begin() + Index);
154 void clear() { Last = First; }
156 ~PODSmallVector() {
157 if (!isInline())
158 std::free(First);
162 // Base class of all AST nodes. The AST is built by the parser, then is
163 // traversed by the printLeft/Right functions to produce a demangled string.
164 class Node {
165 public:
166 enum Kind : unsigned char {
167 #define NODE(NodeKind) K##NodeKind,
168 #include "ItaniumNodes.def"
171 /// Three-way bool to track a cached value. Unknown is possible if this node
172 /// has an unexpanded parameter pack below it that may affect this cache.
173 enum class Cache : unsigned char { Yes, No, Unknown, };
175 /// Operator precedence for expression nodes. Used to determine required
176 /// parens in expression emission.
177 enum class Prec {
178 Primary,
179 Postfix,
180 Unary,
181 Cast,
182 PtrMem,
183 Multiplicative,
184 Additive,
185 Shift,
186 Spaceship,
187 Relational,
188 Equality,
189 And,
190 Xor,
191 Ior,
192 AndIf,
193 OrIf,
194 Conditional,
195 Assign,
196 Comma,
197 Default,
200 private:
201 Kind K;
203 Prec Precedence : 6;
205 // FIXME: Make these protected.
206 public:
207 /// Tracks if this node has a component on its right side, in which case we
208 /// need to call printRight.
209 Cache RHSComponentCache : 2;
211 /// Track if this node is a (possibly qualified) array type. This can affect
212 /// how we format the output string.
213 Cache ArrayCache : 2;
215 /// Track if this node is a (possibly qualified) function type. This can
216 /// affect how we format the output string.
217 Cache FunctionCache : 2;
219 public:
220 Node(Kind K_, Prec Precedence_ = Prec::Primary,
221 Cache RHSComponentCache_ = Cache::No, Cache ArrayCache_ = Cache::No,
222 Cache FunctionCache_ = Cache::No)
223 : K(K_), Precedence(Precedence_), RHSComponentCache(RHSComponentCache_),
224 ArrayCache(ArrayCache_), FunctionCache(FunctionCache_) {}
225 Node(Kind K_, Cache RHSComponentCache_, Cache ArrayCache_ = Cache::No,
226 Cache FunctionCache_ = Cache::No)
227 : Node(K_, Prec::Primary, RHSComponentCache_, ArrayCache_,
228 FunctionCache_) {}
230 /// Visit the most-derived object corresponding to this object.
231 template<typename Fn> void visit(Fn F) const;
233 // The following function is provided by all derived classes:
235 // Call F with arguments that, when passed to the constructor of this node,
236 // would construct an equivalent node.
237 //template<typename Fn> void match(Fn F) const;
239 bool hasRHSComponent(OutputBuffer &OB) const {
240 if (RHSComponentCache != Cache::Unknown)
241 return RHSComponentCache == Cache::Yes;
242 return hasRHSComponentSlow(OB);
245 bool hasArray(OutputBuffer &OB) const {
246 if (ArrayCache != Cache::Unknown)
247 return ArrayCache == Cache::Yes;
248 return hasArraySlow(OB);
251 bool hasFunction(OutputBuffer &OB) const {
252 if (FunctionCache != Cache::Unknown)
253 return FunctionCache == Cache::Yes;
254 return hasFunctionSlow(OB);
257 Kind getKind() const { return K; }
259 Prec getPrecedence() const { return Precedence; }
261 virtual bool hasRHSComponentSlow(OutputBuffer &) const { return false; }
262 virtual bool hasArraySlow(OutputBuffer &) const { return false; }
263 virtual bool hasFunctionSlow(OutputBuffer &) const { return false; }
265 // Dig through "glue" nodes like ParameterPack and ForwardTemplateReference to
266 // get at a node that actually represents some concrete syntax.
267 virtual const Node *getSyntaxNode(OutputBuffer &) const { return this; }
269 // Print this node as an expression operand, surrounding it in parentheses if
270 // its precedence is [Strictly] weaker than P.
271 void printAsOperand(OutputBuffer &OB, Prec P = Prec::Default,
272 bool StrictlyWorse = false) const {
273 bool Paren =
274 unsigned(getPrecedence()) >= unsigned(P) + unsigned(StrictlyWorse);
275 if (Paren)
276 OB.printOpen();
277 print(OB);
278 if (Paren)
279 OB.printClose();
282 void print(OutputBuffer &OB) const {
283 printLeft(OB);
284 if (RHSComponentCache != Cache::No)
285 printRight(OB);
288 // Print the "left" side of this Node into OutputBuffer.
289 virtual void printLeft(OutputBuffer &) const = 0;
291 // Print the "right". This distinction is necessary to represent C++ types
292 // that appear on the RHS of their subtype, such as arrays or functions.
293 // Since most types don't have such a component, provide a default
294 // implementation.
295 virtual void printRight(OutputBuffer &) const {}
297 virtual std::string_view getBaseName() const { return {}; }
299 // Silence compiler warnings, this dtor will never be called.
300 virtual ~Node() = default;
302 #ifndef NDEBUG
303 DEMANGLE_DUMP_METHOD void dump() const;
304 #endif
307 class NodeArray {
308 Node **Elements;
309 size_t NumElements;
311 public:
312 NodeArray() : Elements(nullptr), NumElements(0) {}
313 NodeArray(Node **Elements_, size_t NumElements_)
314 : Elements(Elements_), NumElements(NumElements_) {}
316 bool empty() const { return NumElements == 0; }
317 size_t size() const { return NumElements; }
319 Node **begin() const { return Elements; }
320 Node **end() const { return Elements + NumElements; }
322 Node *operator[](size_t Idx) const { return Elements[Idx]; }
324 void printWithComma(OutputBuffer &OB) const {
325 bool FirstElement = true;
326 for (size_t Idx = 0; Idx != NumElements; ++Idx) {
327 size_t BeforeComma = OB.getCurrentPosition();
328 if (!FirstElement)
329 OB += ", ";
330 size_t AfterComma = OB.getCurrentPosition();
331 Elements[Idx]->printAsOperand(OB, Node::Prec::Comma);
333 // Elements[Idx] is an empty parameter pack expansion, we should erase the
334 // comma we just printed.
335 if (AfterComma == OB.getCurrentPosition()) {
336 OB.setCurrentPosition(BeforeComma);
337 continue;
340 FirstElement = false;
345 struct NodeArrayNode : Node {
346 NodeArray Array;
347 NodeArrayNode(NodeArray Array_) : Node(KNodeArrayNode), Array(Array_) {}
349 template<typename Fn> void match(Fn F) const { F(Array); }
351 void printLeft(OutputBuffer &OB) const override { Array.printWithComma(OB); }
354 class DotSuffix final : public Node {
355 const Node *Prefix;
356 const std::string_view Suffix;
358 public:
359 DotSuffix(const Node *Prefix_, std::string_view Suffix_)
360 : Node(KDotSuffix), Prefix(Prefix_), Suffix(Suffix_) {}
362 template<typename Fn> void match(Fn F) const { F(Prefix, Suffix); }
364 void printLeft(OutputBuffer &OB) const override {
365 Prefix->print(OB);
366 OB += " (";
367 OB += Suffix;
368 OB += ")";
372 class VendorExtQualType final : public Node {
373 const Node *Ty;
374 std::string_view Ext;
375 const Node *TA;
377 public:
378 VendorExtQualType(const Node *Ty_, std::string_view Ext_, const Node *TA_)
379 : Node(KVendorExtQualType), Ty(Ty_), Ext(Ext_), TA(TA_) {}
381 const Node *getTy() const { return Ty; }
382 std::string_view getExt() const { return Ext; }
383 const Node *getTA() const { return TA; }
385 template <typename Fn> void match(Fn F) const { F(Ty, Ext, TA); }
387 void printLeft(OutputBuffer &OB) const override {
388 Ty->print(OB);
389 OB += " ";
390 OB += Ext;
391 if (TA != nullptr)
392 TA->print(OB);
396 enum FunctionRefQual : unsigned char {
397 FrefQualNone,
398 FrefQualLValue,
399 FrefQualRValue,
402 enum Qualifiers {
403 QualNone = 0,
404 QualConst = 0x1,
405 QualVolatile = 0x2,
406 QualRestrict = 0x4,
409 inline Qualifiers operator|=(Qualifiers &Q1, Qualifiers Q2) {
410 return Q1 = static_cast<Qualifiers>(Q1 | Q2);
413 class QualType final : public Node {
414 protected:
415 const Qualifiers Quals;
416 const Node *Child;
418 void printQuals(OutputBuffer &OB) const {
419 if (Quals & QualConst)
420 OB += " const";
421 if (Quals & QualVolatile)
422 OB += " volatile";
423 if (Quals & QualRestrict)
424 OB += " restrict";
427 public:
428 QualType(const Node *Child_, Qualifiers Quals_)
429 : Node(KQualType, Child_->RHSComponentCache,
430 Child_->ArrayCache, Child_->FunctionCache),
431 Quals(Quals_), Child(Child_) {}
433 Qualifiers getQuals() const { return Quals; }
434 const Node *getChild() const { return Child; }
436 template<typename Fn> void match(Fn F) const { F(Child, Quals); }
438 bool hasRHSComponentSlow(OutputBuffer &OB) const override {
439 return Child->hasRHSComponent(OB);
441 bool hasArraySlow(OutputBuffer &OB) const override {
442 return Child->hasArray(OB);
444 bool hasFunctionSlow(OutputBuffer &OB) const override {
445 return Child->hasFunction(OB);
448 void printLeft(OutputBuffer &OB) const override {
449 Child->printLeft(OB);
450 printQuals(OB);
453 void printRight(OutputBuffer &OB) const override { Child->printRight(OB); }
456 class ConversionOperatorType final : public Node {
457 const Node *Ty;
459 public:
460 ConversionOperatorType(const Node *Ty_)
461 : Node(KConversionOperatorType), Ty(Ty_) {}
463 template<typename Fn> void match(Fn F) const { F(Ty); }
465 void printLeft(OutputBuffer &OB) const override {
466 OB += "operator ";
467 Ty->print(OB);
471 class PostfixQualifiedType final : public Node {
472 const Node *Ty;
473 const std::string_view Postfix;
475 public:
476 PostfixQualifiedType(const Node *Ty_, std::string_view Postfix_)
477 : Node(KPostfixQualifiedType), Ty(Ty_), Postfix(Postfix_) {}
479 template<typename Fn> void match(Fn F) const { F(Ty, Postfix); }
481 void printLeft(OutputBuffer &OB) const override {
482 Ty->printLeft(OB);
483 OB += Postfix;
487 class NameType final : public Node {
488 const std::string_view Name;
490 public:
491 NameType(std::string_view Name_) : Node(KNameType), Name(Name_) {}
493 template<typename Fn> void match(Fn F) const { F(Name); }
495 std::string_view getName() const { return Name; }
496 std::string_view getBaseName() const override { return Name; }
498 void printLeft(OutputBuffer &OB) const override { OB += Name; }
501 class BitIntType final : public Node {
502 const Node *Size;
503 bool Signed;
505 public:
506 BitIntType(const Node *Size_, bool Signed_)
507 : Node(KBitIntType), Size(Size_), Signed(Signed_) {}
509 template <typename Fn> void match(Fn F) const { F(Size, Signed); }
511 void printLeft(OutputBuffer &OB) const override {
512 if (!Signed)
513 OB += "unsigned ";
514 OB += "_BitInt";
515 OB.printOpen();
516 Size->printAsOperand(OB);
517 OB.printClose();
521 class ElaboratedTypeSpefType : public Node {
522 std::string_view Kind;
523 Node *Child;
524 public:
525 ElaboratedTypeSpefType(std::string_view Kind_, Node *Child_)
526 : Node(KElaboratedTypeSpefType), Kind(Kind_), Child(Child_) {}
528 template<typename Fn> void match(Fn F) const { F(Kind, Child); }
530 void printLeft(OutputBuffer &OB) const override {
531 OB += Kind;
532 OB += ' ';
533 Child->print(OB);
537 class TransformedType : public Node {
538 std::string_view Transform;
539 Node *BaseType;
540 public:
541 TransformedType(std::string_view Transform_, Node *BaseType_)
542 : Node(KTransformedType), Transform(Transform_), BaseType(BaseType_) {}
544 template<typename Fn> void match(Fn F) const { F(Transform, BaseType); }
546 void printLeft(OutputBuffer &OB) const override {
547 OB += Transform;
548 OB += '(';
549 BaseType->print(OB);
550 OB += ')';
554 struct AbiTagAttr : Node {
555 Node *Base;
556 std::string_view Tag;
558 AbiTagAttr(Node *Base_, std::string_view Tag_)
559 : Node(KAbiTagAttr, Base_->RHSComponentCache, Base_->ArrayCache,
560 Base_->FunctionCache),
561 Base(Base_), Tag(Tag_) {}
563 template<typename Fn> void match(Fn F) const { F(Base, Tag); }
565 std::string_view getBaseName() const override { return Base->getBaseName(); }
567 void printLeft(OutputBuffer &OB) const override {
568 Base->printLeft(OB);
569 OB += "[abi:";
570 OB += Tag;
571 OB += "]";
575 class EnableIfAttr : public Node {
576 NodeArray Conditions;
577 public:
578 EnableIfAttr(NodeArray Conditions_)
579 : Node(KEnableIfAttr), Conditions(Conditions_) {}
581 template<typename Fn> void match(Fn F) const { F(Conditions); }
583 void printLeft(OutputBuffer &OB) const override {
584 OB += " [enable_if:";
585 Conditions.printWithComma(OB);
586 OB += ']';
590 class ObjCProtoName : public Node {
591 const Node *Ty;
592 std::string_view Protocol;
594 friend class PointerType;
596 public:
597 ObjCProtoName(const Node *Ty_, std::string_view Protocol_)
598 : Node(KObjCProtoName), Ty(Ty_), Protocol(Protocol_) {}
600 template<typename Fn> void match(Fn F) const { F(Ty, Protocol); }
602 bool isObjCObject() const {
603 return Ty->getKind() == KNameType &&
604 static_cast<const NameType *>(Ty)->getName() == "objc_object";
607 void printLeft(OutputBuffer &OB) const override {
608 Ty->print(OB);
609 OB += "<";
610 OB += Protocol;
611 OB += ">";
615 class PointerType final : public Node {
616 const Node *Pointee;
618 public:
619 PointerType(const Node *Pointee_)
620 : Node(KPointerType, Pointee_->RHSComponentCache),
621 Pointee(Pointee_) {}
623 const Node *getPointee() const { return Pointee; }
625 template<typename Fn> void match(Fn F) const { F(Pointee); }
627 bool hasRHSComponentSlow(OutputBuffer &OB) const override {
628 return Pointee->hasRHSComponent(OB);
631 void printLeft(OutputBuffer &OB) const override {
632 // We rewrite objc_object<SomeProtocol>* into id<SomeProtocol>.
633 if (Pointee->getKind() != KObjCProtoName ||
634 !static_cast<const ObjCProtoName *>(Pointee)->isObjCObject()) {
635 Pointee->printLeft(OB);
636 if (Pointee->hasArray(OB))
637 OB += " ";
638 if (Pointee->hasArray(OB) || Pointee->hasFunction(OB))
639 OB += "(";
640 OB += "*";
641 } else {
642 const auto *objcProto = static_cast<const ObjCProtoName *>(Pointee);
643 OB += "id<";
644 OB += objcProto->Protocol;
645 OB += ">";
649 void printRight(OutputBuffer &OB) const override {
650 if (Pointee->getKind() != KObjCProtoName ||
651 !static_cast<const ObjCProtoName *>(Pointee)->isObjCObject()) {
652 if (Pointee->hasArray(OB) || Pointee->hasFunction(OB))
653 OB += ")";
654 Pointee->printRight(OB);
659 enum class ReferenceKind {
660 LValue,
661 RValue,
664 // Represents either a LValue or an RValue reference type.
665 class ReferenceType : public Node {
666 const Node *Pointee;
667 ReferenceKind RK;
669 mutable bool Printing = false;
671 // Dig through any refs to refs, collapsing the ReferenceTypes as we go. The
672 // rule here is rvalue ref to rvalue ref collapses to a rvalue ref, and any
673 // other combination collapses to a lvalue ref.
675 // A combination of a TemplateForwardReference and a back-ref Substitution
676 // from an ill-formed string may have created a cycle; use cycle detection to
677 // avoid looping forever.
678 std::pair<ReferenceKind, const Node *> collapse(OutputBuffer &OB) const {
679 auto SoFar = std::make_pair(RK, Pointee);
680 // Track the chain of nodes for the Floyd's 'tortoise and hare'
681 // cycle-detection algorithm, since getSyntaxNode(S) is impure
682 PODSmallVector<const Node *, 8> Prev;
683 for (;;) {
684 const Node *SN = SoFar.second->getSyntaxNode(OB);
685 if (SN->getKind() != KReferenceType)
686 break;
687 auto *RT = static_cast<const ReferenceType *>(SN);
688 SoFar.second = RT->Pointee;
689 SoFar.first = std::min(SoFar.first, RT->RK);
691 // The middle of Prev is the 'slow' pointer moving at half speed
692 Prev.push_back(SoFar.second);
693 if (Prev.size() > 1 && SoFar.second == Prev[(Prev.size() - 1) / 2]) {
694 // Cycle detected
695 SoFar.second = nullptr;
696 break;
699 return SoFar;
702 public:
703 ReferenceType(const Node *Pointee_, ReferenceKind RK_)
704 : Node(KReferenceType, Pointee_->RHSComponentCache),
705 Pointee(Pointee_), RK(RK_) {}
707 template<typename Fn> void match(Fn F) const { F(Pointee, RK); }
709 bool hasRHSComponentSlow(OutputBuffer &OB) const override {
710 return Pointee->hasRHSComponent(OB);
713 void printLeft(OutputBuffer &OB) const override {
714 if (Printing)
715 return;
716 ScopedOverride<bool> SavePrinting(Printing, true);
717 std::pair<ReferenceKind, const Node *> Collapsed = collapse(OB);
718 if (!Collapsed.second)
719 return;
720 Collapsed.second->printLeft(OB);
721 if (Collapsed.second->hasArray(OB))
722 OB += " ";
723 if (Collapsed.second->hasArray(OB) || Collapsed.second->hasFunction(OB))
724 OB += "(";
726 OB += (Collapsed.first == ReferenceKind::LValue ? "&" : "&&");
728 void printRight(OutputBuffer &OB) const override {
729 if (Printing)
730 return;
731 ScopedOverride<bool> SavePrinting(Printing, true);
732 std::pair<ReferenceKind, const Node *> Collapsed = collapse(OB);
733 if (!Collapsed.second)
734 return;
735 if (Collapsed.second->hasArray(OB) || Collapsed.second->hasFunction(OB))
736 OB += ")";
737 Collapsed.second->printRight(OB);
741 class PointerToMemberType final : public Node {
742 const Node *ClassType;
743 const Node *MemberType;
745 public:
746 PointerToMemberType(const Node *ClassType_, const Node *MemberType_)
747 : Node(KPointerToMemberType, MemberType_->RHSComponentCache),
748 ClassType(ClassType_), MemberType(MemberType_) {}
750 template<typename Fn> void match(Fn F) const { F(ClassType, MemberType); }
752 bool hasRHSComponentSlow(OutputBuffer &OB) const override {
753 return MemberType->hasRHSComponent(OB);
756 void printLeft(OutputBuffer &OB) const override {
757 MemberType->printLeft(OB);
758 if (MemberType->hasArray(OB) || MemberType->hasFunction(OB))
759 OB += "(";
760 else
761 OB += " ";
762 ClassType->print(OB);
763 OB += "::*";
766 void printRight(OutputBuffer &OB) const override {
767 if (MemberType->hasArray(OB) || MemberType->hasFunction(OB))
768 OB += ")";
769 MemberType->printRight(OB);
773 class ArrayType final : public Node {
774 const Node *Base;
775 Node *Dimension;
777 public:
778 ArrayType(const Node *Base_, Node *Dimension_)
779 : Node(KArrayType,
780 /*RHSComponentCache=*/Cache::Yes,
781 /*ArrayCache=*/Cache::Yes),
782 Base(Base_), Dimension(Dimension_) {}
784 template<typename Fn> void match(Fn F) const { F(Base, Dimension); }
786 bool hasRHSComponentSlow(OutputBuffer &) const override { return true; }
787 bool hasArraySlow(OutputBuffer &) const override { return true; }
789 void printLeft(OutputBuffer &OB) const override { Base->printLeft(OB); }
791 void printRight(OutputBuffer &OB) const override {
792 if (OB.back() != ']')
793 OB += " ";
794 OB += "[";
795 if (Dimension)
796 Dimension->print(OB);
797 OB += "]";
798 Base->printRight(OB);
802 class FunctionType final : public Node {
803 const Node *Ret;
804 NodeArray Params;
805 Qualifiers CVQuals;
806 FunctionRefQual RefQual;
807 const Node *ExceptionSpec;
809 public:
810 FunctionType(const Node *Ret_, NodeArray Params_, Qualifiers CVQuals_,
811 FunctionRefQual RefQual_, const Node *ExceptionSpec_)
812 : Node(KFunctionType,
813 /*RHSComponentCache=*/Cache::Yes, /*ArrayCache=*/Cache::No,
814 /*FunctionCache=*/Cache::Yes),
815 Ret(Ret_), Params(Params_), CVQuals(CVQuals_), RefQual(RefQual_),
816 ExceptionSpec(ExceptionSpec_) {}
818 template<typename Fn> void match(Fn F) const {
819 F(Ret, Params, CVQuals, RefQual, ExceptionSpec);
822 bool hasRHSComponentSlow(OutputBuffer &) const override { return true; }
823 bool hasFunctionSlow(OutputBuffer &) const override { return true; }
825 // Handle C++'s ... quirky decl grammar by using the left & right
826 // distinction. Consider:
827 // int (*f(float))(char) {}
828 // f is a function that takes a float and returns a pointer to a function
829 // that takes a char and returns an int. If we're trying to print f, start
830 // by printing out the return types's left, then print our parameters, then
831 // finally print right of the return type.
832 void printLeft(OutputBuffer &OB) const override {
833 Ret->printLeft(OB);
834 OB += " ";
837 void printRight(OutputBuffer &OB) const override {
838 OB.printOpen();
839 Params.printWithComma(OB);
840 OB.printClose();
841 Ret->printRight(OB);
843 if (CVQuals & QualConst)
844 OB += " const";
845 if (CVQuals & QualVolatile)
846 OB += " volatile";
847 if (CVQuals & QualRestrict)
848 OB += " restrict";
850 if (RefQual == FrefQualLValue)
851 OB += " &";
852 else if (RefQual == FrefQualRValue)
853 OB += " &&";
855 if (ExceptionSpec != nullptr) {
856 OB += ' ';
857 ExceptionSpec->print(OB);
862 class NoexceptSpec : public Node {
863 const Node *E;
864 public:
865 NoexceptSpec(const Node *E_) : Node(KNoexceptSpec), E(E_) {}
867 template<typename Fn> void match(Fn F) const { F(E); }
869 void printLeft(OutputBuffer &OB) const override {
870 OB += "noexcept";
871 OB.printOpen();
872 E->printAsOperand(OB);
873 OB.printClose();
877 class DynamicExceptionSpec : public Node {
878 NodeArray Types;
879 public:
880 DynamicExceptionSpec(NodeArray Types_)
881 : Node(KDynamicExceptionSpec), Types(Types_) {}
883 template<typename Fn> void match(Fn F) const { F(Types); }
885 void printLeft(OutputBuffer &OB) const override {
886 OB += "throw";
887 OB.printOpen();
888 Types.printWithComma(OB);
889 OB.printClose();
893 class FunctionEncoding final : public Node {
894 const Node *Ret;
895 const Node *Name;
896 NodeArray Params;
897 const Node *Attrs;
898 const Node *Requires;
899 Qualifiers CVQuals;
900 FunctionRefQual RefQual;
902 public:
903 FunctionEncoding(const Node *Ret_, const Node *Name_, NodeArray Params_,
904 const Node *Attrs_, const Node *Requires_,
905 Qualifiers CVQuals_, FunctionRefQual RefQual_)
906 : Node(KFunctionEncoding,
907 /*RHSComponentCache=*/Cache::Yes, /*ArrayCache=*/Cache::No,
908 /*FunctionCache=*/Cache::Yes),
909 Ret(Ret_), Name(Name_), Params(Params_), Attrs(Attrs_),
910 Requires(Requires_), CVQuals(CVQuals_), RefQual(RefQual_) {}
912 template<typename Fn> void match(Fn F) const {
913 F(Ret, Name, Params, Attrs, Requires, CVQuals, RefQual);
916 Qualifiers getCVQuals() const { return CVQuals; }
917 FunctionRefQual getRefQual() const { return RefQual; }
918 NodeArray getParams() const { return Params; }
919 const Node *getReturnType() const { return Ret; }
921 bool hasRHSComponentSlow(OutputBuffer &) const override { return true; }
922 bool hasFunctionSlow(OutputBuffer &) const override { return true; }
924 const Node *getName() const { return Name; }
926 void printLeft(OutputBuffer &OB) const override {
927 if (Ret) {
928 Ret->printLeft(OB);
929 if (!Ret->hasRHSComponent(OB))
930 OB += " ";
932 Name->print(OB);
935 void printRight(OutputBuffer &OB) const override {
936 OB.printOpen();
937 Params.printWithComma(OB);
938 OB.printClose();
939 if (Ret)
940 Ret->printRight(OB);
942 if (CVQuals & QualConst)
943 OB += " const";
944 if (CVQuals & QualVolatile)
945 OB += " volatile";
946 if (CVQuals & QualRestrict)
947 OB += " restrict";
949 if (RefQual == FrefQualLValue)
950 OB += " &";
951 else if (RefQual == FrefQualRValue)
952 OB += " &&";
954 if (Attrs != nullptr)
955 Attrs->print(OB);
957 if (Requires != nullptr) {
958 OB += " requires ";
959 Requires->print(OB);
964 class LiteralOperator : public Node {
965 const Node *OpName;
967 public:
968 LiteralOperator(const Node *OpName_)
969 : Node(KLiteralOperator), OpName(OpName_) {}
971 template<typename Fn> void match(Fn F) const { F(OpName); }
973 void printLeft(OutputBuffer &OB) const override {
974 OB += "operator\"\" ";
975 OpName->print(OB);
979 class SpecialName final : public Node {
980 const std::string_view Special;
981 const Node *Child;
983 public:
984 SpecialName(std::string_view Special_, const Node *Child_)
985 : Node(KSpecialName), Special(Special_), Child(Child_) {}
987 template<typename Fn> void match(Fn F) const { F(Special, Child); }
989 void printLeft(OutputBuffer &OB) const override {
990 OB += Special;
991 Child->print(OB);
995 class CtorVtableSpecialName final : public Node {
996 const Node *FirstType;
997 const Node *SecondType;
999 public:
1000 CtorVtableSpecialName(const Node *FirstType_, const Node *SecondType_)
1001 : Node(KCtorVtableSpecialName),
1002 FirstType(FirstType_), SecondType(SecondType_) {}
1004 template<typename Fn> void match(Fn F) const { F(FirstType, SecondType); }
1006 void printLeft(OutputBuffer &OB) const override {
1007 OB += "construction vtable for ";
1008 FirstType->print(OB);
1009 OB += "-in-";
1010 SecondType->print(OB);
1014 struct NestedName : Node {
1015 Node *Qual;
1016 Node *Name;
1018 NestedName(Node *Qual_, Node *Name_)
1019 : Node(KNestedName), Qual(Qual_), Name(Name_) {}
1021 template<typename Fn> void match(Fn F) const { F(Qual, Name); }
1023 std::string_view getBaseName() const override { return Name->getBaseName(); }
1025 void printLeft(OutputBuffer &OB) const override {
1026 Qual->print(OB);
1027 OB += "::";
1028 Name->print(OB);
1032 struct MemberLikeFriendName : Node {
1033 Node *Qual;
1034 Node *Name;
1036 MemberLikeFriendName(Node *Qual_, Node *Name_)
1037 : Node(KMemberLikeFriendName), Qual(Qual_), Name(Name_) {}
1039 template<typename Fn> void match(Fn F) const { F(Qual, Name); }
1041 std::string_view getBaseName() const override { return Name->getBaseName(); }
1043 void printLeft(OutputBuffer &OB) const override {
1044 Qual->print(OB);
1045 OB += "::friend ";
1046 Name->print(OB);
1050 struct ModuleName : Node {
1051 ModuleName *Parent;
1052 Node *Name;
1053 bool IsPartition;
1055 ModuleName(ModuleName *Parent_, Node *Name_, bool IsPartition_ = false)
1056 : Node(KModuleName), Parent(Parent_), Name(Name_),
1057 IsPartition(IsPartition_) {}
1059 template <typename Fn> void match(Fn F) const {
1060 F(Parent, Name, IsPartition);
1063 void printLeft(OutputBuffer &OB) const override {
1064 if (Parent)
1065 Parent->print(OB);
1066 if (Parent || IsPartition)
1067 OB += IsPartition ? ':' : '.';
1068 Name->print(OB);
1072 struct ModuleEntity : Node {
1073 ModuleName *Module;
1074 Node *Name;
1076 ModuleEntity(ModuleName *Module_, Node *Name_)
1077 : Node(KModuleEntity), Module(Module_), Name(Name_) {}
1079 template <typename Fn> void match(Fn F) const { F(Module, Name); }
1081 std::string_view getBaseName() const override { return Name->getBaseName(); }
1083 void printLeft(OutputBuffer &OB) const override {
1084 Name->print(OB);
1085 OB += '@';
1086 Module->print(OB);
1090 struct LocalName : Node {
1091 Node *Encoding;
1092 Node *Entity;
1094 LocalName(Node *Encoding_, Node *Entity_)
1095 : Node(KLocalName), Encoding(Encoding_), Entity(Entity_) {}
1097 template<typename Fn> void match(Fn F) const { F(Encoding, Entity); }
1099 void printLeft(OutputBuffer &OB) const override {
1100 Encoding->print(OB);
1101 OB += "::";
1102 Entity->print(OB);
1106 class QualifiedName final : public Node {
1107 // qualifier::name
1108 const Node *Qualifier;
1109 const Node *Name;
1111 public:
1112 QualifiedName(const Node *Qualifier_, const Node *Name_)
1113 : Node(KQualifiedName), Qualifier(Qualifier_), Name(Name_) {}
1115 template<typename Fn> void match(Fn F) const { F(Qualifier, Name); }
1117 std::string_view getBaseName() const override { return Name->getBaseName(); }
1119 void printLeft(OutputBuffer &OB) const override {
1120 Qualifier->print(OB);
1121 OB += "::";
1122 Name->print(OB);
1126 class VectorType final : public Node {
1127 const Node *BaseType;
1128 const Node *Dimension;
1130 public:
1131 VectorType(const Node *BaseType_, const Node *Dimension_)
1132 : Node(KVectorType), BaseType(BaseType_), Dimension(Dimension_) {}
1134 const Node *getBaseType() const { return BaseType; }
1135 const Node *getDimension() const { return Dimension; }
1137 template<typename Fn> void match(Fn F) const { F(BaseType, Dimension); }
1139 void printLeft(OutputBuffer &OB) const override {
1140 BaseType->print(OB);
1141 OB += " vector[";
1142 if (Dimension)
1143 Dimension->print(OB);
1144 OB += "]";
1148 class PixelVectorType final : public Node {
1149 const Node *Dimension;
1151 public:
1152 PixelVectorType(const Node *Dimension_)
1153 : Node(KPixelVectorType), Dimension(Dimension_) {}
1155 template<typename Fn> void match(Fn F) const { F(Dimension); }
1157 void printLeft(OutputBuffer &OB) const override {
1158 // FIXME: This should demangle as "vector pixel".
1159 OB += "pixel vector[";
1160 Dimension->print(OB);
1161 OB += "]";
1165 class BinaryFPType final : public Node {
1166 const Node *Dimension;
1168 public:
1169 BinaryFPType(const Node *Dimension_)
1170 : Node(KBinaryFPType), Dimension(Dimension_) {}
1172 template<typename Fn> void match(Fn F) const { F(Dimension); }
1174 void printLeft(OutputBuffer &OB) const override {
1175 OB += "_Float";
1176 Dimension->print(OB);
1180 enum class TemplateParamKind { Type, NonType, Template };
1182 /// An invented name for a template parameter for which we don't have a
1183 /// corresponding template argument.
1185 /// This node is created when parsing the <lambda-sig> for a lambda with
1186 /// explicit template arguments, which might be referenced in the parameter
1187 /// types appearing later in the <lambda-sig>.
1188 class SyntheticTemplateParamName final : public Node {
1189 TemplateParamKind Kind;
1190 unsigned Index;
1192 public:
1193 SyntheticTemplateParamName(TemplateParamKind Kind_, unsigned Index_)
1194 : Node(KSyntheticTemplateParamName), Kind(Kind_), Index(Index_) {}
1196 template<typename Fn> void match(Fn F) const { F(Kind, Index); }
1198 void printLeft(OutputBuffer &OB) const override {
1199 switch (Kind) {
1200 case TemplateParamKind::Type:
1201 OB += "$T";
1202 break;
1203 case TemplateParamKind::NonType:
1204 OB += "$N";
1205 break;
1206 case TemplateParamKind::Template:
1207 OB += "$TT";
1208 break;
1210 if (Index > 0)
1211 OB << Index - 1;
1215 class TemplateParamQualifiedArg final : public Node {
1216 Node *Param;
1217 Node *Arg;
1219 public:
1220 TemplateParamQualifiedArg(Node *Param_, Node *Arg_)
1221 : Node(KTemplateParamQualifiedArg), Param(Param_), Arg(Arg_) {}
1223 template <typename Fn> void match(Fn F) const { F(Param, Arg); }
1225 Node *getArg() { return Arg; }
1227 void printLeft(OutputBuffer &OB) const override {
1228 // Don't print Param to keep the output consistent.
1229 Arg->print(OB);
1233 /// A template type parameter declaration, 'typename T'.
1234 class TypeTemplateParamDecl final : public Node {
1235 Node *Name;
1237 public:
1238 TypeTemplateParamDecl(Node *Name_)
1239 : Node(KTypeTemplateParamDecl, Cache::Yes), Name(Name_) {}
1241 template<typename Fn> void match(Fn F) const { F(Name); }
1243 void printLeft(OutputBuffer &OB) const override { OB += "typename "; }
1245 void printRight(OutputBuffer &OB) const override { Name->print(OB); }
1248 /// A constrained template type parameter declaration, 'C<U> T'.
1249 class ConstrainedTypeTemplateParamDecl final : public Node {
1250 Node *Constraint;
1251 Node *Name;
1253 public:
1254 ConstrainedTypeTemplateParamDecl(Node *Constraint_, Node *Name_)
1255 : Node(KConstrainedTypeTemplateParamDecl, Cache::Yes),
1256 Constraint(Constraint_), Name(Name_) {}
1258 template<typename Fn> void match(Fn F) const { F(Constraint, Name); }
1260 void printLeft(OutputBuffer &OB) const override {
1261 Constraint->print(OB);
1262 OB += " ";
1265 void printRight(OutputBuffer &OB) const override { Name->print(OB); }
1268 /// A non-type template parameter declaration, 'int N'.
1269 class NonTypeTemplateParamDecl final : public Node {
1270 Node *Name;
1271 Node *Type;
1273 public:
1274 NonTypeTemplateParamDecl(Node *Name_, Node *Type_)
1275 : Node(KNonTypeTemplateParamDecl, Cache::Yes), Name(Name_), Type(Type_) {}
1277 template<typename Fn> void match(Fn F) const { F(Name, Type); }
1279 void printLeft(OutputBuffer &OB) const override {
1280 Type->printLeft(OB);
1281 if (!Type->hasRHSComponent(OB))
1282 OB += " ";
1285 void printRight(OutputBuffer &OB) const override {
1286 Name->print(OB);
1287 Type->printRight(OB);
1291 /// A template template parameter declaration,
1292 /// 'template<typename T> typename N'.
1293 class TemplateTemplateParamDecl final : public Node {
1294 Node *Name;
1295 NodeArray Params;
1296 Node *Requires;
1298 public:
1299 TemplateTemplateParamDecl(Node *Name_, NodeArray Params_, Node *Requires_)
1300 : Node(KTemplateTemplateParamDecl, Cache::Yes), Name(Name_),
1301 Params(Params_), Requires(Requires_) {}
1303 template <typename Fn> void match(Fn F) const { F(Name, Params, Requires); }
1305 void printLeft(OutputBuffer &OB) const override {
1306 ScopedOverride<unsigned> LT(OB.GtIsGt, 0);
1307 OB += "template<";
1308 Params.printWithComma(OB);
1309 OB += "> typename ";
1312 void printRight(OutputBuffer &OB) const override {
1313 Name->print(OB);
1314 if (Requires != nullptr) {
1315 OB += " requires ";
1316 Requires->print(OB);
1321 /// A template parameter pack declaration, 'typename ...T'.
1322 class TemplateParamPackDecl final : public Node {
1323 Node *Param;
1325 public:
1326 TemplateParamPackDecl(Node *Param_)
1327 : Node(KTemplateParamPackDecl, Cache::Yes), Param(Param_) {}
1329 template<typename Fn> void match(Fn F) const { F(Param); }
1331 void printLeft(OutputBuffer &OB) const override {
1332 Param->printLeft(OB);
1333 OB += "...";
1336 void printRight(OutputBuffer &OB) const override { Param->printRight(OB); }
1339 /// An unexpanded parameter pack (either in the expression or type context). If
1340 /// this AST is correct, this node will have a ParameterPackExpansion node above
1341 /// it.
1343 /// This node is created when some <template-args> are found that apply to an
1344 /// <encoding>, and is stored in the TemplateParams table. In order for this to
1345 /// appear in the final AST, it has to referenced via a <template-param> (ie,
1346 /// T_).
1347 class ParameterPack final : public Node {
1348 NodeArray Data;
1350 // Setup OutputBuffer for a pack expansion, unless we're already expanding
1351 // one.
1352 void initializePackExpansion(OutputBuffer &OB) const {
1353 if (OB.CurrentPackMax == std::numeric_limits<unsigned>::max()) {
1354 OB.CurrentPackMax = static_cast<unsigned>(Data.size());
1355 OB.CurrentPackIndex = 0;
1359 public:
1360 ParameterPack(NodeArray Data_) : Node(KParameterPack), Data(Data_) {
1361 ArrayCache = FunctionCache = RHSComponentCache = Cache::Unknown;
1362 if (std::all_of(Data.begin(), Data.end(), [](Node* P) {
1363 return P->ArrayCache == Cache::No;
1365 ArrayCache = Cache::No;
1366 if (std::all_of(Data.begin(), Data.end(), [](Node* P) {
1367 return P->FunctionCache == Cache::No;
1369 FunctionCache = Cache::No;
1370 if (std::all_of(Data.begin(), Data.end(), [](Node* P) {
1371 return P->RHSComponentCache == Cache::No;
1373 RHSComponentCache = Cache::No;
1376 template<typename Fn> void match(Fn F) const { F(Data); }
1378 bool hasRHSComponentSlow(OutputBuffer &OB) const override {
1379 initializePackExpansion(OB);
1380 size_t Idx = OB.CurrentPackIndex;
1381 return Idx < Data.size() && Data[Idx]->hasRHSComponent(OB);
1383 bool hasArraySlow(OutputBuffer &OB) const override {
1384 initializePackExpansion(OB);
1385 size_t Idx = OB.CurrentPackIndex;
1386 return Idx < Data.size() && Data[Idx]->hasArray(OB);
1388 bool hasFunctionSlow(OutputBuffer &OB) const override {
1389 initializePackExpansion(OB);
1390 size_t Idx = OB.CurrentPackIndex;
1391 return Idx < Data.size() && Data[Idx]->hasFunction(OB);
1393 const Node *getSyntaxNode(OutputBuffer &OB) const override {
1394 initializePackExpansion(OB);
1395 size_t Idx = OB.CurrentPackIndex;
1396 return Idx < Data.size() ? Data[Idx]->getSyntaxNode(OB) : this;
1399 void printLeft(OutputBuffer &OB) const override {
1400 initializePackExpansion(OB);
1401 size_t Idx = OB.CurrentPackIndex;
1402 if (Idx < Data.size())
1403 Data[Idx]->printLeft(OB);
1405 void printRight(OutputBuffer &OB) const override {
1406 initializePackExpansion(OB);
1407 size_t Idx = OB.CurrentPackIndex;
1408 if (Idx < Data.size())
1409 Data[Idx]->printRight(OB);
1413 /// A variadic template argument. This node represents an occurrence of
1414 /// J<something>E in some <template-args>. It isn't itself unexpanded, unless
1415 /// one of its Elements is. The parser inserts a ParameterPack into the
1416 /// TemplateParams table if the <template-args> this pack belongs to apply to an
1417 /// <encoding>.
1418 class TemplateArgumentPack final : public Node {
1419 NodeArray Elements;
1420 public:
1421 TemplateArgumentPack(NodeArray Elements_)
1422 : Node(KTemplateArgumentPack), Elements(Elements_) {}
1424 template<typename Fn> void match(Fn F) const { F(Elements); }
1426 NodeArray getElements() const { return Elements; }
1428 void printLeft(OutputBuffer &OB) const override {
1429 Elements.printWithComma(OB);
1433 /// A pack expansion. Below this node, there are some unexpanded ParameterPacks
1434 /// which each have Child->ParameterPackSize elements.
1435 class ParameterPackExpansion final : public Node {
1436 const Node *Child;
1438 public:
1439 ParameterPackExpansion(const Node *Child_)
1440 : Node(KParameterPackExpansion), Child(Child_) {}
1442 template<typename Fn> void match(Fn F) const { F(Child); }
1444 const Node *getChild() const { return Child; }
1446 void printLeft(OutputBuffer &OB) const override {
1447 constexpr unsigned Max = std::numeric_limits<unsigned>::max();
1448 ScopedOverride<unsigned> SavePackIdx(OB.CurrentPackIndex, Max);
1449 ScopedOverride<unsigned> SavePackMax(OB.CurrentPackMax, Max);
1450 size_t StreamPos = OB.getCurrentPosition();
1452 // Print the first element in the pack. If Child contains a ParameterPack,
1453 // it will set up S.CurrentPackMax and print the first element.
1454 Child->print(OB);
1456 // No ParameterPack was found in Child. This can occur if we've found a pack
1457 // expansion on a <function-param>.
1458 if (OB.CurrentPackMax == Max) {
1459 OB += "...";
1460 return;
1463 // We found a ParameterPack, but it has no elements. Erase whatever we may
1464 // of printed.
1465 if (OB.CurrentPackMax == 0) {
1466 OB.setCurrentPosition(StreamPos);
1467 return;
1470 // Else, iterate through the rest of the elements in the pack.
1471 for (unsigned I = 1, E = OB.CurrentPackMax; I < E; ++I) {
1472 OB += ", ";
1473 OB.CurrentPackIndex = I;
1474 Child->print(OB);
1479 class TemplateArgs final : public Node {
1480 NodeArray Params;
1481 Node *Requires;
1483 public:
1484 TemplateArgs(NodeArray Params_, Node *Requires_)
1485 : Node(KTemplateArgs), Params(Params_), Requires(Requires_) {}
1487 template<typename Fn> void match(Fn F) const { F(Params, Requires); }
1489 NodeArray getParams() { return Params; }
1491 void printLeft(OutputBuffer &OB) const override {
1492 ScopedOverride<unsigned> LT(OB.GtIsGt, 0);
1493 OB += "<";
1494 Params.printWithComma(OB);
1495 OB += ">";
1496 // Don't print the requires clause to keep the output simple.
1500 /// A forward-reference to a template argument that was not known at the point
1501 /// where the template parameter name was parsed in a mangling.
1503 /// This is created when demangling the name of a specialization of a
1504 /// conversion function template:
1506 /// \code
1507 /// struct A {
1508 /// template<typename T> operator T*();
1509 /// };
1510 /// \endcode
1512 /// When demangling a specialization of the conversion function template, we
1513 /// encounter the name of the template (including the \c T) before we reach
1514 /// the template argument list, so we cannot substitute the parameter name
1515 /// for the corresponding argument while parsing. Instead, we create a
1516 /// \c ForwardTemplateReference node that is resolved after we parse the
1517 /// template arguments.
1518 struct ForwardTemplateReference : Node {
1519 size_t Index;
1520 Node *Ref = nullptr;
1522 // If we're currently printing this node. It is possible (though invalid) for
1523 // a forward template reference to refer to itself via a substitution. This
1524 // creates a cyclic AST, which will stack overflow printing. To fix this, bail
1525 // out if more than one print* function is active.
1526 mutable bool Printing = false;
1528 ForwardTemplateReference(size_t Index_)
1529 : Node(KForwardTemplateReference, Cache::Unknown, Cache::Unknown,
1530 Cache::Unknown),
1531 Index(Index_) {}
1533 // We don't provide a matcher for these, because the value of the node is
1534 // not determined by its construction parameters, and it generally needs
1535 // special handling.
1536 template<typename Fn> void match(Fn F) const = delete;
1538 bool hasRHSComponentSlow(OutputBuffer &OB) const override {
1539 if (Printing)
1540 return false;
1541 ScopedOverride<bool> SavePrinting(Printing, true);
1542 return Ref->hasRHSComponent(OB);
1544 bool hasArraySlow(OutputBuffer &OB) const override {
1545 if (Printing)
1546 return false;
1547 ScopedOverride<bool> SavePrinting(Printing, true);
1548 return Ref->hasArray(OB);
1550 bool hasFunctionSlow(OutputBuffer &OB) const override {
1551 if (Printing)
1552 return false;
1553 ScopedOverride<bool> SavePrinting(Printing, true);
1554 return Ref->hasFunction(OB);
1556 const Node *getSyntaxNode(OutputBuffer &OB) const override {
1557 if (Printing)
1558 return this;
1559 ScopedOverride<bool> SavePrinting(Printing, true);
1560 return Ref->getSyntaxNode(OB);
1563 void printLeft(OutputBuffer &OB) const override {
1564 if (Printing)
1565 return;
1566 ScopedOverride<bool> SavePrinting(Printing, true);
1567 Ref->printLeft(OB);
1569 void printRight(OutputBuffer &OB) const override {
1570 if (Printing)
1571 return;
1572 ScopedOverride<bool> SavePrinting(Printing, true);
1573 Ref->printRight(OB);
1577 struct NameWithTemplateArgs : Node {
1578 // name<template_args>
1579 Node *Name;
1580 Node *TemplateArgs;
1582 NameWithTemplateArgs(Node *Name_, Node *TemplateArgs_)
1583 : Node(KNameWithTemplateArgs), Name(Name_), TemplateArgs(TemplateArgs_) {}
1585 template<typename Fn> void match(Fn F) const { F(Name, TemplateArgs); }
1587 std::string_view getBaseName() const override { return Name->getBaseName(); }
1589 void printLeft(OutputBuffer &OB) const override {
1590 Name->print(OB);
1591 TemplateArgs->print(OB);
1595 class GlobalQualifiedName final : public Node {
1596 Node *Child;
1598 public:
1599 GlobalQualifiedName(Node* Child_)
1600 : Node(KGlobalQualifiedName), Child(Child_) {}
1602 template<typename Fn> void match(Fn F) const { F(Child); }
1604 std::string_view getBaseName() const override { return Child->getBaseName(); }
1606 void printLeft(OutputBuffer &OB) const override {
1607 OB += "::";
1608 Child->print(OB);
1612 enum class SpecialSubKind {
1613 allocator,
1614 basic_string,
1615 string,
1616 istream,
1617 ostream,
1618 iostream,
1621 class SpecialSubstitution;
1622 class ExpandedSpecialSubstitution : public Node {
1623 protected:
1624 SpecialSubKind SSK;
1626 ExpandedSpecialSubstitution(SpecialSubKind SSK_, Kind K_)
1627 : Node(K_), SSK(SSK_) {}
1628 public:
1629 ExpandedSpecialSubstitution(SpecialSubKind SSK_)
1630 : ExpandedSpecialSubstitution(SSK_, KExpandedSpecialSubstitution) {}
1631 inline ExpandedSpecialSubstitution(SpecialSubstitution const *);
1633 template<typename Fn> void match(Fn F) const { F(SSK); }
1635 protected:
1636 bool isInstantiation() const {
1637 return unsigned(SSK) >= unsigned(SpecialSubKind::string);
1640 std::string_view getBaseName() const override {
1641 switch (SSK) {
1642 case SpecialSubKind::allocator:
1643 return {"allocator"};
1644 case SpecialSubKind::basic_string:
1645 return {"basic_string"};
1646 case SpecialSubKind::string:
1647 return {"basic_string"};
1648 case SpecialSubKind::istream:
1649 return {"basic_istream"};
1650 case SpecialSubKind::ostream:
1651 return {"basic_ostream"};
1652 case SpecialSubKind::iostream:
1653 return {"basic_iostream"};
1655 DEMANGLE_UNREACHABLE;
1658 private:
1659 void printLeft(OutputBuffer &OB) const override {
1660 OB << "std::" << getBaseName();
1661 if (isInstantiation()) {
1662 OB << "<char, std::char_traits<char>";
1663 if (SSK == SpecialSubKind::string)
1664 OB << ", std::allocator<char>";
1665 OB << ">";
1670 class SpecialSubstitution final : public ExpandedSpecialSubstitution {
1671 public:
1672 SpecialSubstitution(SpecialSubKind SSK_)
1673 : ExpandedSpecialSubstitution(SSK_, KSpecialSubstitution) {}
1675 template<typename Fn> void match(Fn F) const { F(SSK); }
1677 std::string_view getBaseName() const override {
1678 std::string_view SV = ExpandedSpecialSubstitution::getBaseName();
1679 if (isInstantiation()) {
1680 // The instantiations are typedefs that drop the "basic_" prefix.
1681 assert(starts_with(SV, "basic_"));
1682 SV.remove_prefix(sizeof("basic_") - 1);
1684 return SV;
1687 void printLeft(OutputBuffer &OB) const override {
1688 OB << "std::" << getBaseName();
1692 inline ExpandedSpecialSubstitution::ExpandedSpecialSubstitution(
1693 SpecialSubstitution const *SS)
1694 : ExpandedSpecialSubstitution(SS->SSK) {}
1696 class CtorDtorName final : public Node {
1697 const Node *Basename;
1698 const bool IsDtor;
1699 const int Variant;
1701 public:
1702 CtorDtorName(const Node *Basename_, bool IsDtor_, int Variant_)
1703 : Node(KCtorDtorName), Basename(Basename_), IsDtor(IsDtor_),
1704 Variant(Variant_) {}
1706 template<typename Fn> void match(Fn F) const { F(Basename, IsDtor, Variant); }
1708 void printLeft(OutputBuffer &OB) const override {
1709 if (IsDtor)
1710 OB += "~";
1711 OB += Basename->getBaseName();
1715 class DtorName : public Node {
1716 const Node *Base;
1718 public:
1719 DtorName(const Node *Base_) : Node(KDtorName), Base(Base_) {}
1721 template<typename Fn> void match(Fn F) const { F(Base); }
1723 void printLeft(OutputBuffer &OB) const override {
1724 OB += "~";
1725 Base->printLeft(OB);
1729 class UnnamedTypeName : public Node {
1730 const std::string_view Count;
1732 public:
1733 UnnamedTypeName(std::string_view Count_)
1734 : Node(KUnnamedTypeName), Count(Count_) {}
1736 template<typename Fn> void match(Fn F) const { F(Count); }
1738 void printLeft(OutputBuffer &OB) const override {
1739 OB += "'unnamed";
1740 OB += Count;
1741 OB += "\'";
1745 class ClosureTypeName : public Node {
1746 NodeArray TemplateParams;
1747 const Node *Requires1;
1748 NodeArray Params;
1749 const Node *Requires2;
1750 std::string_view Count;
1752 public:
1753 ClosureTypeName(NodeArray TemplateParams_, const Node *Requires1_,
1754 NodeArray Params_, const Node *Requires2_,
1755 std::string_view Count_)
1756 : Node(KClosureTypeName), TemplateParams(TemplateParams_),
1757 Requires1(Requires1_), Params(Params_), Requires2(Requires2_),
1758 Count(Count_) {}
1760 template<typename Fn> void match(Fn F) const {
1761 F(TemplateParams, Requires1, Params, Requires2, Count);
1764 void printDeclarator(OutputBuffer &OB) const {
1765 if (!TemplateParams.empty()) {
1766 ScopedOverride<unsigned> LT(OB.GtIsGt, 0);
1767 OB += "<";
1768 TemplateParams.printWithComma(OB);
1769 OB += ">";
1771 if (Requires1 != nullptr) {
1772 OB += " requires ";
1773 Requires1->print(OB);
1774 OB += " ";
1776 OB.printOpen();
1777 Params.printWithComma(OB);
1778 OB.printClose();
1779 if (Requires2 != nullptr) {
1780 OB += " requires ";
1781 Requires2->print(OB);
1785 void printLeft(OutputBuffer &OB) const override {
1786 // FIXME: This demangling is not particularly readable.
1787 OB += "\'lambda";
1788 OB += Count;
1789 OB += "\'";
1790 printDeclarator(OB);
1794 class StructuredBindingName : public Node {
1795 NodeArray Bindings;
1796 public:
1797 StructuredBindingName(NodeArray Bindings_)
1798 : Node(KStructuredBindingName), Bindings(Bindings_) {}
1800 template<typename Fn> void match(Fn F) const { F(Bindings); }
1802 void printLeft(OutputBuffer &OB) const override {
1803 OB.printOpen('[');
1804 Bindings.printWithComma(OB);
1805 OB.printClose(']');
1809 // -- Expression Nodes --
1811 class BinaryExpr : public Node {
1812 const Node *LHS;
1813 const std::string_view InfixOperator;
1814 const Node *RHS;
1816 public:
1817 BinaryExpr(const Node *LHS_, std::string_view InfixOperator_,
1818 const Node *RHS_, Prec Prec_)
1819 : Node(KBinaryExpr, Prec_), LHS(LHS_), InfixOperator(InfixOperator_),
1820 RHS(RHS_) {}
1822 template <typename Fn> void match(Fn F) const {
1823 F(LHS, InfixOperator, RHS, getPrecedence());
1826 void printLeft(OutputBuffer &OB) const override {
1827 bool ParenAll = OB.isGtInsideTemplateArgs() &&
1828 (InfixOperator == ">" || InfixOperator == ">>");
1829 if (ParenAll)
1830 OB.printOpen();
1831 // Assignment is right associative, with special LHS precedence.
1832 bool IsAssign = getPrecedence() == Prec::Assign;
1833 LHS->printAsOperand(OB, IsAssign ? Prec::OrIf : getPrecedence(), !IsAssign);
1834 // No space before comma operator
1835 if (!(InfixOperator == ","))
1836 OB += " ";
1837 OB += InfixOperator;
1838 OB += " ";
1839 RHS->printAsOperand(OB, getPrecedence(), IsAssign);
1840 if (ParenAll)
1841 OB.printClose();
1845 class ArraySubscriptExpr : public Node {
1846 const Node *Op1;
1847 const Node *Op2;
1849 public:
1850 ArraySubscriptExpr(const Node *Op1_, const Node *Op2_, Prec Prec_)
1851 : Node(KArraySubscriptExpr, Prec_), Op1(Op1_), Op2(Op2_) {}
1853 template <typename Fn> void match(Fn F) const {
1854 F(Op1, Op2, getPrecedence());
1857 void printLeft(OutputBuffer &OB) const override {
1858 Op1->printAsOperand(OB, getPrecedence());
1859 OB.printOpen('[');
1860 Op2->printAsOperand(OB);
1861 OB.printClose(']');
1865 class PostfixExpr : public Node {
1866 const Node *Child;
1867 const std::string_view Operator;
1869 public:
1870 PostfixExpr(const Node *Child_, std::string_view Operator_, Prec Prec_)
1871 : Node(KPostfixExpr, Prec_), Child(Child_), Operator(Operator_) {}
1873 template <typename Fn> void match(Fn F) const {
1874 F(Child, Operator, getPrecedence());
1877 void printLeft(OutputBuffer &OB) const override {
1878 Child->printAsOperand(OB, getPrecedence(), true);
1879 OB += Operator;
1883 class ConditionalExpr : public Node {
1884 const Node *Cond;
1885 const Node *Then;
1886 const Node *Else;
1888 public:
1889 ConditionalExpr(const Node *Cond_, const Node *Then_, const Node *Else_,
1890 Prec Prec_)
1891 : Node(KConditionalExpr, Prec_), Cond(Cond_), Then(Then_), Else(Else_) {}
1893 template <typename Fn> void match(Fn F) const {
1894 F(Cond, Then, Else, getPrecedence());
1897 void printLeft(OutputBuffer &OB) const override {
1898 Cond->printAsOperand(OB, getPrecedence());
1899 OB += " ? ";
1900 Then->printAsOperand(OB);
1901 OB += " : ";
1902 Else->printAsOperand(OB, Prec::Assign, true);
1906 class MemberExpr : public Node {
1907 const Node *LHS;
1908 const std::string_view Kind;
1909 const Node *RHS;
1911 public:
1912 MemberExpr(const Node *LHS_, std::string_view Kind_, const Node *RHS_,
1913 Prec Prec_)
1914 : Node(KMemberExpr, Prec_), LHS(LHS_), Kind(Kind_), RHS(RHS_) {}
1916 template <typename Fn> void match(Fn F) const {
1917 F(LHS, Kind, RHS, getPrecedence());
1920 void printLeft(OutputBuffer &OB) const override {
1921 LHS->printAsOperand(OB, getPrecedence(), true);
1922 OB += Kind;
1923 RHS->printAsOperand(OB, getPrecedence(), false);
1927 class SubobjectExpr : public Node {
1928 const Node *Type;
1929 const Node *SubExpr;
1930 std::string_view Offset;
1931 NodeArray UnionSelectors;
1932 bool OnePastTheEnd;
1934 public:
1935 SubobjectExpr(const Node *Type_, const Node *SubExpr_,
1936 std::string_view Offset_, NodeArray UnionSelectors_,
1937 bool OnePastTheEnd_)
1938 : Node(KSubobjectExpr), Type(Type_), SubExpr(SubExpr_), Offset(Offset_),
1939 UnionSelectors(UnionSelectors_), OnePastTheEnd(OnePastTheEnd_) {}
1941 template<typename Fn> void match(Fn F) const {
1942 F(Type, SubExpr, Offset, UnionSelectors, OnePastTheEnd);
1945 void printLeft(OutputBuffer &OB) const override {
1946 SubExpr->print(OB);
1947 OB += ".<";
1948 Type->print(OB);
1949 OB += " at offset ";
1950 if (Offset.empty()) {
1951 OB += "0";
1952 } else if (Offset[0] == 'n') {
1953 OB += "-";
1954 OB += std::string_view(Offset.data() + 1, Offset.size() - 1);
1955 } else {
1956 OB += Offset;
1958 OB += ">";
1962 class EnclosingExpr : public Node {
1963 const std::string_view Prefix;
1964 const Node *Infix;
1965 const std::string_view Postfix;
1967 public:
1968 EnclosingExpr(std::string_view Prefix_, const Node *Infix_,
1969 Prec Prec_ = Prec::Primary)
1970 : Node(KEnclosingExpr, Prec_), Prefix(Prefix_), Infix(Infix_) {}
1972 template <typename Fn> void match(Fn F) const {
1973 F(Prefix, Infix, getPrecedence());
1976 void printLeft(OutputBuffer &OB) const override {
1977 OB += Prefix;
1978 OB.printOpen();
1979 Infix->print(OB);
1980 OB.printClose();
1981 OB += Postfix;
1985 class CastExpr : public Node {
1986 // cast_kind<to>(from)
1987 const std::string_view CastKind;
1988 const Node *To;
1989 const Node *From;
1991 public:
1992 CastExpr(std::string_view CastKind_, const Node *To_, const Node *From_,
1993 Prec Prec_)
1994 : Node(KCastExpr, Prec_), CastKind(CastKind_), To(To_), From(From_) {}
1996 template <typename Fn> void match(Fn F) const {
1997 F(CastKind, To, From, getPrecedence());
2000 void printLeft(OutputBuffer &OB) const override {
2001 OB += CastKind;
2003 ScopedOverride<unsigned> LT(OB.GtIsGt, 0);
2004 OB += "<";
2005 To->printLeft(OB);
2006 OB += ">";
2008 OB.printOpen();
2009 From->printAsOperand(OB);
2010 OB.printClose();
2014 class SizeofParamPackExpr : public Node {
2015 const Node *Pack;
2017 public:
2018 SizeofParamPackExpr(const Node *Pack_)
2019 : Node(KSizeofParamPackExpr), Pack(Pack_) {}
2021 template<typename Fn> void match(Fn F) const { F(Pack); }
2023 void printLeft(OutputBuffer &OB) const override {
2024 OB += "sizeof...";
2025 OB.printOpen();
2026 ParameterPackExpansion PPE(Pack);
2027 PPE.printLeft(OB);
2028 OB.printClose();
2032 class CallExpr : public Node {
2033 const Node *Callee;
2034 NodeArray Args;
2036 public:
2037 CallExpr(const Node *Callee_, NodeArray Args_, Prec Prec_)
2038 : Node(KCallExpr, Prec_), Callee(Callee_), Args(Args_) {}
2040 template <typename Fn> void match(Fn F) const {
2041 F(Callee, Args, getPrecedence());
2044 void printLeft(OutputBuffer &OB) const override {
2045 Callee->print(OB);
2046 OB.printOpen();
2047 Args.printWithComma(OB);
2048 OB.printClose();
2052 class NewExpr : public Node {
2053 // new (expr_list) type(init_list)
2054 NodeArray ExprList;
2055 Node *Type;
2056 NodeArray InitList;
2057 bool IsGlobal; // ::operator new ?
2058 bool IsArray; // new[] ?
2059 public:
2060 NewExpr(NodeArray ExprList_, Node *Type_, NodeArray InitList_, bool IsGlobal_,
2061 bool IsArray_, Prec Prec_)
2062 : Node(KNewExpr, Prec_), ExprList(ExprList_), Type(Type_),
2063 InitList(InitList_), IsGlobal(IsGlobal_), IsArray(IsArray_) {}
2065 template<typename Fn> void match(Fn F) const {
2066 F(ExprList, Type, InitList, IsGlobal, IsArray, getPrecedence());
2069 void printLeft(OutputBuffer &OB) const override {
2070 if (IsGlobal)
2071 OB += "::";
2072 OB += "new";
2073 if (IsArray)
2074 OB += "[]";
2075 if (!ExprList.empty()) {
2076 OB.printOpen();
2077 ExprList.printWithComma(OB);
2078 OB.printClose();
2080 OB += " ";
2081 Type->print(OB);
2082 if (!InitList.empty()) {
2083 OB.printOpen();
2084 InitList.printWithComma(OB);
2085 OB.printClose();
2090 class DeleteExpr : public Node {
2091 Node *Op;
2092 bool IsGlobal;
2093 bool IsArray;
2095 public:
2096 DeleteExpr(Node *Op_, bool IsGlobal_, bool IsArray_, Prec Prec_)
2097 : Node(KDeleteExpr, Prec_), Op(Op_), IsGlobal(IsGlobal_),
2098 IsArray(IsArray_) {}
2100 template <typename Fn> void match(Fn F) const {
2101 F(Op, IsGlobal, IsArray, getPrecedence());
2104 void printLeft(OutputBuffer &OB) const override {
2105 if (IsGlobal)
2106 OB += "::";
2107 OB += "delete";
2108 if (IsArray)
2109 OB += "[]";
2110 OB += ' ';
2111 Op->print(OB);
2115 class PrefixExpr : public Node {
2116 std::string_view Prefix;
2117 Node *Child;
2119 public:
2120 PrefixExpr(std::string_view Prefix_, Node *Child_, Prec Prec_)
2121 : Node(KPrefixExpr, Prec_), Prefix(Prefix_), Child(Child_) {}
2123 template <typename Fn> void match(Fn F) const {
2124 F(Prefix, Child, getPrecedence());
2127 void printLeft(OutputBuffer &OB) const override {
2128 OB += Prefix;
2129 Child->printAsOperand(OB, getPrecedence());
2133 class FunctionParam : public Node {
2134 std::string_view Number;
2136 public:
2137 FunctionParam(std::string_view Number_)
2138 : Node(KFunctionParam), Number(Number_) {}
2140 template<typename Fn> void match(Fn F) const { F(Number); }
2142 void printLeft(OutputBuffer &OB) const override {
2143 OB += "fp";
2144 OB += Number;
2148 class ConversionExpr : public Node {
2149 const Node *Type;
2150 NodeArray Expressions;
2152 public:
2153 ConversionExpr(const Node *Type_, NodeArray Expressions_, Prec Prec_)
2154 : Node(KConversionExpr, Prec_), Type(Type_), Expressions(Expressions_) {}
2156 template <typename Fn> void match(Fn F) const {
2157 F(Type, Expressions, getPrecedence());
2160 void printLeft(OutputBuffer &OB) const override {
2161 OB.printOpen();
2162 Type->print(OB);
2163 OB.printClose();
2164 OB.printOpen();
2165 Expressions.printWithComma(OB);
2166 OB.printClose();
2170 class PointerToMemberConversionExpr : public Node {
2171 const Node *Type;
2172 const Node *SubExpr;
2173 std::string_view Offset;
2175 public:
2176 PointerToMemberConversionExpr(const Node *Type_, const Node *SubExpr_,
2177 std::string_view Offset_, Prec Prec_)
2178 : Node(KPointerToMemberConversionExpr, Prec_), Type(Type_),
2179 SubExpr(SubExpr_), Offset(Offset_) {}
2181 template <typename Fn> void match(Fn F) const {
2182 F(Type, SubExpr, Offset, getPrecedence());
2185 void printLeft(OutputBuffer &OB) const override {
2186 OB.printOpen();
2187 Type->print(OB);
2188 OB.printClose();
2189 OB.printOpen();
2190 SubExpr->print(OB);
2191 OB.printClose();
2195 class InitListExpr : public Node {
2196 const Node *Ty;
2197 NodeArray Inits;
2198 public:
2199 InitListExpr(const Node *Ty_, NodeArray Inits_)
2200 : Node(KInitListExpr), Ty(Ty_), Inits(Inits_) {}
2202 template<typename Fn> void match(Fn F) const { F(Ty, Inits); }
2204 void printLeft(OutputBuffer &OB) const override {
2205 if (Ty)
2206 Ty->print(OB);
2207 OB += '{';
2208 Inits.printWithComma(OB);
2209 OB += '}';
2213 class BracedExpr : public Node {
2214 const Node *Elem;
2215 const Node *Init;
2216 bool IsArray;
2217 public:
2218 BracedExpr(const Node *Elem_, const Node *Init_, bool IsArray_)
2219 : Node(KBracedExpr), Elem(Elem_), Init(Init_), IsArray(IsArray_) {}
2221 template<typename Fn> void match(Fn F) const { F(Elem, Init, IsArray); }
2223 void printLeft(OutputBuffer &OB) const override {
2224 if (IsArray) {
2225 OB += '[';
2226 Elem->print(OB);
2227 OB += ']';
2228 } else {
2229 OB += '.';
2230 Elem->print(OB);
2232 if (Init->getKind() != KBracedExpr && Init->getKind() != KBracedRangeExpr)
2233 OB += " = ";
2234 Init->print(OB);
2238 class BracedRangeExpr : public Node {
2239 const Node *First;
2240 const Node *Last;
2241 const Node *Init;
2242 public:
2243 BracedRangeExpr(const Node *First_, const Node *Last_, const Node *Init_)
2244 : Node(KBracedRangeExpr), First(First_), Last(Last_), Init(Init_) {}
2246 template<typename Fn> void match(Fn F) const { F(First, Last, Init); }
2248 void printLeft(OutputBuffer &OB) const override {
2249 OB += '[';
2250 First->print(OB);
2251 OB += " ... ";
2252 Last->print(OB);
2253 OB += ']';
2254 if (Init->getKind() != KBracedExpr && Init->getKind() != KBracedRangeExpr)
2255 OB += " = ";
2256 Init->print(OB);
2260 class FoldExpr : public Node {
2261 const Node *Pack, *Init;
2262 std::string_view OperatorName;
2263 bool IsLeftFold;
2265 public:
2266 FoldExpr(bool IsLeftFold_, std::string_view OperatorName_, const Node *Pack_,
2267 const Node *Init_)
2268 : Node(KFoldExpr), Pack(Pack_), Init(Init_), OperatorName(OperatorName_),
2269 IsLeftFold(IsLeftFold_) {}
2271 template<typename Fn> void match(Fn F) const {
2272 F(IsLeftFold, OperatorName, Pack, Init);
2275 void printLeft(OutputBuffer &OB) const override {
2276 auto PrintPack = [&] {
2277 OB.printOpen();
2278 ParameterPackExpansion(Pack).print(OB);
2279 OB.printClose();
2282 OB.printOpen();
2283 // Either '[init op ]... op pack' or 'pack op ...[ op init]'
2284 // Refactored to '[(init|pack) op ]...[ op (pack|init)]'
2285 // Fold expr operands are cast-expressions
2286 if (!IsLeftFold || Init != nullptr) {
2287 // '(init|pack) op '
2288 if (IsLeftFold)
2289 Init->printAsOperand(OB, Prec::Cast, true);
2290 else
2291 PrintPack();
2292 OB << " " << OperatorName << " ";
2294 OB << "...";
2295 if (IsLeftFold || Init != nullptr) {
2296 // ' op (init|pack)'
2297 OB << " " << OperatorName << " ";
2298 if (IsLeftFold)
2299 PrintPack();
2300 else
2301 Init->printAsOperand(OB, Prec::Cast, true);
2303 OB.printClose();
2307 class ThrowExpr : public Node {
2308 const Node *Op;
2310 public:
2311 ThrowExpr(const Node *Op_) : Node(KThrowExpr), Op(Op_) {}
2313 template<typename Fn> void match(Fn F) const { F(Op); }
2315 void printLeft(OutputBuffer &OB) const override {
2316 OB += "throw ";
2317 Op->print(OB);
2321 class BoolExpr : public Node {
2322 bool Value;
2324 public:
2325 BoolExpr(bool Value_) : Node(KBoolExpr), Value(Value_) {}
2327 template<typename Fn> void match(Fn F) const { F(Value); }
2329 void printLeft(OutputBuffer &OB) const override {
2330 OB += Value ? std::string_view("true") : std::string_view("false");
2334 class StringLiteral : public Node {
2335 const Node *Type;
2337 public:
2338 StringLiteral(const Node *Type_) : Node(KStringLiteral), Type(Type_) {}
2340 template<typename Fn> void match(Fn F) const { F(Type); }
2342 void printLeft(OutputBuffer &OB) const override {
2343 OB += "\"<";
2344 Type->print(OB);
2345 OB += ">\"";
2349 class LambdaExpr : public Node {
2350 const Node *Type;
2352 public:
2353 LambdaExpr(const Node *Type_) : Node(KLambdaExpr), Type(Type_) {}
2355 template<typename Fn> void match(Fn F) const { F(Type); }
2357 void printLeft(OutputBuffer &OB) const override {
2358 OB += "[]";
2359 if (Type->getKind() == KClosureTypeName)
2360 static_cast<const ClosureTypeName *>(Type)->printDeclarator(OB);
2361 OB += "{...}";
2365 class EnumLiteral : public Node {
2366 // ty(integer)
2367 const Node *Ty;
2368 std::string_view Integer;
2370 public:
2371 EnumLiteral(const Node *Ty_, std::string_view Integer_)
2372 : Node(KEnumLiteral), Ty(Ty_), Integer(Integer_) {}
2374 template<typename Fn> void match(Fn F) const { F(Ty, Integer); }
2376 void printLeft(OutputBuffer &OB) const override {
2377 OB.printOpen();
2378 Ty->print(OB);
2379 OB.printClose();
2381 if (Integer[0] == 'n')
2382 OB << '-' << std::string_view(Integer.data() + 1, Integer.size() - 1);
2383 else
2384 OB << Integer;
2388 class IntegerLiteral : public Node {
2389 std::string_view Type;
2390 std::string_view Value;
2392 public:
2393 IntegerLiteral(std::string_view Type_, std::string_view Value_)
2394 : Node(KIntegerLiteral), Type(Type_), Value(Value_) {}
2396 template<typename Fn> void match(Fn F) const { F(Type, Value); }
2398 void printLeft(OutputBuffer &OB) const override {
2399 if (Type.size() > 3) {
2400 OB.printOpen();
2401 OB += Type;
2402 OB.printClose();
2405 if (Value[0] == 'n')
2406 OB << '-' << std::string_view(Value.data() + 1, Value.size() - 1);
2407 else
2408 OB += Value;
2410 if (Type.size() <= 3)
2411 OB += Type;
2415 class RequiresExpr : public Node {
2416 NodeArray Parameters;
2417 NodeArray Requirements;
2418 public:
2419 RequiresExpr(NodeArray Parameters_, NodeArray Requirements_)
2420 : Node(KRequiresExpr), Parameters(Parameters_),
2421 Requirements(Requirements_) {}
2423 template<typename Fn> void match(Fn F) const { F(Parameters, Requirements); }
2425 void printLeft(OutputBuffer &OB) const override {
2426 OB += "requires";
2427 if (!Parameters.empty()) {
2428 OB += ' ';
2429 OB.printOpen();
2430 Parameters.printWithComma(OB);
2431 OB.printClose();
2433 OB += ' ';
2434 OB.printOpen('{');
2435 for (const Node *Req : Requirements) {
2436 Req->print(OB);
2438 OB += ' ';
2439 OB.printClose('}');
2443 class ExprRequirement : public Node {
2444 const Node *Expr;
2445 bool IsNoexcept;
2446 const Node *TypeConstraint;
2447 public:
2448 ExprRequirement(const Node *Expr_, bool IsNoexcept_,
2449 const Node *TypeConstraint_)
2450 : Node(KExprRequirement), Expr(Expr_), IsNoexcept(IsNoexcept_),
2451 TypeConstraint(TypeConstraint_) {}
2453 template <typename Fn> void match(Fn F) const {
2454 F(Expr, IsNoexcept, TypeConstraint);
2457 void printLeft(OutputBuffer &OB) const override {
2458 OB += " ";
2459 if (IsNoexcept || TypeConstraint)
2460 OB.printOpen('{');
2461 Expr->print(OB);
2462 if (IsNoexcept || TypeConstraint)
2463 OB.printClose('}');
2464 if (IsNoexcept)
2465 OB += " noexcept";
2466 if (TypeConstraint) {
2467 OB += " -> ";
2468 TypeConstraint->print(OB);
2470 OB += ';';
2474 class TypeRequirement : public Node {
2475 const Node *Type;
2476 public:
2477 TypeRequirement(const Node *Type_)
2478 : Node(KTypeRequirement), Type(Type_) {}
2480 template <typename Fn> void match(Fn F) const { F(Type); }
2482 void printLeft(OutputBuffer &OB) const override {
2483 OB += " typename ";
2484 Type->print(OB);
2485 OB += ';';
2489 class NestedRequirement : public Node {
2490 const Node *Constraint;
2491 public:
2492 NestedRequirement(const Node *Constraint_)
2493 : Node(KNestedRequirement), Constraint(Constraint_) {}
2495 template <typename Fn> void match(Fn F) const { F(Constraint); }
2497 void printLeft(OutputBuffer &OB) const override {
2498 OB += " requires ";
2499 Constraint->print(OB);
2500 OB += ';';
2504 template <class Float> struct FloatData;
2506 namespace float_literal_impl {
2507 constexpr Node::Kind getFloatLiteralKind(float *) {
2508 return Node::KFloatLiteral;
2510 constexpr Node::Kind getFloatLiteralKind(double *) {
2511 return Node::KDoubleLiteral;
2513 constexpr Node::Kind getFloatLiteralKind(long double *) {
2514 return Node::KLongDoubleLiteral;
2518 template <class Float> class FloatLiteralImpl : public Node {
2519 const std::string_view Contents;
2521 static constexpr Kind KindForClass =
2522 float_literal_impl::getFloatLiteralKind((Float *)nullptr);
2524 public:
2525 FloatLiteralImpl(std::string_view Contents_)
2526 : Node(KindForClass), Contents(Contents_) {}
2528 template<typename Fn> void match(Fn F) const { F(Contents); }
2530 void printLeft(OutputBuffer &OB) const override {
2531 const size_t N = FloatData<Float>::mangled_size;
2532 if (Contents.size() >= N) {
2533 union {
2534 Float value;
2535 char buf[sizeof(Float)];
2537 const char *t = Contents.data();
2538 const char *last = t + N;
2539 char *e = buf;
2540 for (; t != last; ++t, ++e) {
2541 unsigned d1 = isdigit(*t) ? static_cast<unsigned>(*t - '0')
2542 : static_cast<unsigned>(*t - 'a' + 10);
2543 ++t;
2544 unsigned d0 = isdigit(*t) ? static_cast<unsigned>(*t - '0')
2545 : static_cast<unsigned>(*t - 'a' + 10);
2546 *e = static_cast<char>((d1 << 4) + d0);
2548 #if __BYTE_ORDER__ == __ORDER_LITTLE_ENDIAN__
2549 std::reverse(buf, e);
2550 #endif
2551 char num[FloatData<Float>::max_demangled_size] = {0};
2552 int n = snprintf(num, sizeof(num), FloatData<Float>::spec, value);
2553 OB += std::string_view(num, n);
2558 using FloatLiteral = FloatLiteralImpl<float>;
2559 using DoubleLiteral = FloatLiteralImpl<double>;
2560 using LongDoubleLiteral = FloatLiteralImpl<long double>;
2562 /// Visit the node. Calls \c F(P), where \c P is the node cast to the
2563 /// appropriate derived class.
2564 template<typename Fn>
2565 void Node::visit(Fn F) const {
2566 switch (K) {
2567 #define NODE(X) \
2568 case K##X: \
2569 return F(static_cast<const X *>(this));
2570 #include "ItaniumNodes.def"
2572 assert(0 && "unknown mangling node kind");
2575 /// Determine the kind of a node from its type.
2576 template<typename NodeT> struct NodeKind;
2577 #define NODE(X) \
2578 template <> struct NodeKind<X> { \
2579 static constexpr Node::Kind Kind = Node::K##X; \
2580 static constexpr const char *name() { return #X; } \
2582 #include "ItaniumNodes.def"
2584 template <typename Derived, typename Alloc> struct AbstractManglingParser {
2585 const char *First;
2586 const char *Last;
2588 // Name stack, this is used by the parser to hold temporary names that were
2589 // parsed. The parser collapses multiple names into new nodes to construct
2590 // the AST. Once the parser is finished, names.size() == 1.
2591 PODSmallVector<Node *, 32> Names;
2593 // Substitution table. Itanium supports name substitutions as a means of
2594 // compression. The string "S42_" refers to the 44nd entry (base-36) in this
2595 // table.
2596 PODSmallVector<Node *, 32> Subs;
2598 // A list of template argument values corresponding to a template parameter
2599 // list.
2600 using TemplateParamList = PODSmallVector<Node *, 8>;
2602 class ScopedTemplateParamList {
2603 AbstractManglingParser *Parser;
2604 size_t OldNumTemplateParamLists;
2605 TemplateParamList Params;
2607 public:
2608 ScopedTemplateParamList(AbstractManglingParser *TheParser)
2609 : Parser(TheParser),
2610 OldNumTemplateParamLists(TheParser->TemplateParams.size()) {
2611 Parser->TemplateParams.push_back(&Params);
2613 ~ScopedTemplateParamList() {
2614 assert(Parser->TemplateParams.size() >= OldNumTemplateParamLists);
2615 Parser->TemplateParams.shrinkToSize(OldNumTemplateParamLists);
2617 TemplateParamList *params() { return &Params; }
2620 // Template parameter table. Like the above, but referenced like "T42_".
2621 // This has a smaller size compared to Subs and Names because it can be
2622 // stored on the stack.
2623 TemplateParamList OuterTemplateParams;
2625 // Lists of template parameters indexed by template parameter depth,
2626 // referenced like "TL2_4_". If nonempty, element 0 is always
2627 // OuterTemplateParams; inner elements are always template parameter lists of
2628 // lambda expressions. For a generic lambda with no explicit template
2629 // parameter list, the corresponding parameter list pointer will be null.
2630 PODSmallVector<TemplateParamList *, 4> TemplateParams;
2632 class SaveTemplateParams {
2633 AbstractManglingParser *Parser;
2634 decltype(TemplateParams) OldParams;
2635 decltype(OuterTemplateParams) OldOuterParams;
2637 public:
2638 SaveTemplateParams(AbstractManglingParser *TheParser) : Parser(TheParser) {
2639 OldParams = std::move(Parser->TemplateParams);
2640 OldOuterParams = std::move(Parser->OuterTemplateParams);
2641 Parser->TemplateParams.clear();
2642 Parser->OuterTemplateParams.clear();
2644 ~SaveTemplateParams() {
2645 Parser->TemplateParams = std::move(OldParams);
2646 Parser->OuterTemplateParams = std::move(OldOuterParams);
2650 // Set of unresolved forward <template-param> references. These can occur in a
2651 // conversion operator's type, and are resolved in the enclosing <encoding>.
2652 PODSmallVector<ForwardTemplateReference *, 4> ForwardTemplateRefs;
2654 bool TryToParseTemplateArgs = true;
2655 bool PermitForwardTemplateReferences = false;
2656 bool InConstraintExpr = false;
2657 size_t ParsingLambdaParamsAtLevel = (size_t)-1;
2659 unsigned NumSyntheticTemplateParameters[3] = {};
2661 Alloc ASTAllocator;
2663 AbstractManglingParser(const char *First_, const char *Last_)
2664 : First(First_), Last(Last_) {}
2666 Derived &getDerived() { return static_cast<Derived &>(*this); }
2668 void reset(const char *First_, const char *Last_) {
2669 First = First_;
2670 Last = Last_;
2671 Names.clear();
2672 Subs.clear();
2673 TemplateParams.clear();
2674 ParsingLambdaParamsAtLevel = (size_t)-1;
2675 TryToParseTemplateArgs = true;
2676 PermitForwardTemplateReferences = false;
2677 for (int I = 0; I != 3; ++I)
2678 NumSyntheticTemplateParameters[I] = 0;
2679 ASTAllocator.reset();
2682 template <class T, class... Args> Node *make(Args &&... args) {
2683 return ASTAllocator.template makeNode<T>(std::forward<Args>(args)...);
2686 template <class It> NodeArray makeNodeArray(It begin, It end) {
2687 size_t sz = static_cast<size_t>(end - begin);
2688 void *mem = ASTAllocator.allocateNodeArray(sz);
2689 Node **data = new (mem) Node *[sz];
2690 std::copy(begin, end, data);
2691 return NodeArray(data, sz);
2694 NodeArray popTrailingNodeArray(size_t FromPosition) {
2695 assert(FromPosition <= Names.size());
2696 NodeArray res =
2697 makeNodeArray(Names.begin() + (long)FromPosition, Names.end());
2698 Names.shrinkToSize(FromPosition);
2699 return res;
2702 bool consumeIf(std::string_view S) {
2703 if (starts_with(std::string_view(First, Last - First), S)) {
2704 First += S.size();
2705 return true;
2707 return false;
2710 bool consumeIf(char C) {
2711 if (First != Last && *First == C) {
2712 ++First;
2713 return true;
2715 return false;
2718 char consume() { return First != Last ? *First++ : '\0'; }
2720 char look(unsigned Lookahead = 0) const {
2721 if (static_cast<size_t>(Last - First) <= Lookahead)
2722 return '\0';
2723 return First[Lookahead];
2726 size_t numLeft() const { return static_cast<size_t>(Last - First); }
2728 std::string_view parseNumber(bool AllowNegative = false);
2729 Qualifiers parseCVQualifiers();
2730 bool parsePositiveInteger(size_t *Out);
2731 std::string_view parseBareSourceName();
2733 bool parseSeqId(size_t *Out);
2734 Node *parseSubstitution();
2735 Node *parseTemplateParam();
2736 Node *parseTemplateParamDecl(TemplateParamList *Params);
2737 Node *parseTemplateArgs(bool TagTemplates = false);
2738 Node *parseTemplateArg();
2740 bool isTemplateParamDecl() {
2741 return look() == 'T' &&
2742 std::string_view("yptnk").find(look(1)) != std::string_view::npos;
2745 /// Parse the <expression> production.
2746 Node *parseExpr();
2747 Node *parsePrefixExpr(std::string_view Kind, Node::Prec Prec);
2748 Node *parseBinaryExpr(std::string_view Kind, Node::Prec Prec);
2749 Node *parseIntegerLiteral(std::string_view Lit);
2750 Node *parseExprPrimary();
2751 template <class Float> Node *parseFloatingLiteral();
2752 Node *parseFunctionParam();
2753 Node *parseConversionExpr();
2754 Node *parseBracedExpr();
2755 Node *parseFoldExpr();
2756 Node *parsePointerToMemberConversionExpr(Node::Prec Prec);
2757 Node *parseSubobjectExpr();
2758 Node *parseConstraintExpr();
2759 Node *parseRequiresExpr();
2761 /// Parse the <type> production.
2762 Node *parseType();
2763 Node *parseFunctionType();
2764 Node *parseVectorType();
2765 Node *parseDecltype();
2766 Node *parseArrayType();
2767 Node *parsePointerToMemberType();
2768 Node *parseClassEnumType();
2769 Node *parseQualifiedType();
2771 Node *parseEncoding();
2772 bool parseCallOffset();
2773 Node *parseSpecialName();
2775 /// Holds some extra information about a <name> that is being parsed. This
2776 /// information is only pertinent if the <name> refers to an <encoding>.
2777 struct NameState {
2778 bool CtorDtorConversion = false;
2779 bool EndsWithTemplateArgs = false;
2780 Qualifiers CVQualifiers = QualNone;
2781 FunctionRefQual ReferenceQualifier = FrefQualNone;
2782 size_t ForwardTemplateRefsBegin;
2784 NameState(AbstractManglingParser *Enclosing)
2785 : ForwardTemplateRefsBegin(Enclosing->ForwardTemplateRefs.size()) {}
2788 bool resolveForwardTemplateRefs(NameState &State) {
2789 size_t I = State.ForwardTemplateRefsBegin;
2790 size_t E = ForwardTemplateRefs.size();
2791 for (; I < E; ++I) {
2792 size_t Idx = ForwardTemplateRefs[I]->Index;
2793 if (TemplateParams.empty() || !TemplateParams[0] ||
2794 Idx >= TemplateParams[0]->size())
2795 return true;
2796 ForwardTemplateRefs[I]->Ref = (*TemplateParams[0])[Idx];
2798 ForwardTemplateRefs.shrinkToSize(State.ForwardTemplateRefsBegin);
2799 return false;
2802 /// Parse the <name> production>
2803 Node *parseName(NameState *State = nullptr);
2804 Node *parseLocalName(NameState *State);
2805 Node *parseOperatorName(NameState *State);
2806 bool parseModuleNameOpt(ModuleName *&Module);
2807 Node *parseUnqualifiedName(NameState *State, Node *Scope, ModuleName *Module);
2808 Node *parseUnnamedTypeName(NameState *State);
2809 Node *parseSourceName(NameState *State);
2810 Node *parseUnscopedName(NameState *State, bool *isSubstName);
2811 Node *parseNestedName(NameState *State);
2812 Node *parseCtorDtorName(Node *&SoFar, NameState *State);
2814 Node *parseAbiTags(Node *N);
2816 struct OperatorInfo {
2817 enum OIKind : unsigned char {
2818 Prefix, // Prefix unary: @ expr
2819 Postfix, // Postfix unary: expr @
2820 Binary, // Binary: lhs @ rhs
2821 Array, // Array index: lhs [ rhs ]
2822 Member, // Member access: lhs @ rhs
2823 New, // New
2824 Del, // Delete
2825 Call, // Function call: expr (expr*)
2826 CCast, // C cast: (type)expr
2827 Conditional, // Conditional: expr ? expr : expr
2828 NameOnly, // Overload only, not allowed in expression.
2829 // Below do not have operator names
2830 NamedCast, // Named cast, @<type>(expr)
2831 OfIdOp, // alignof, sizeof, typeid
2833 Unnameable = NamedCast,
2835 char Enc[2]; // Encoding
2836 OIKind Kind; // Kind of operator
2837 bool Flag : 1; // Entry-specific flag
2838 Node::Prec Prec : 7; // Precedence
2839 const char *Name; // Spelling
2841 public:
2842 constexpr OperatorInfo(const char (&E)[3], OIKind K, bool F, Node::Prec P,
2843 const char *N)
2844 : Enc{E[0], E[1]}, Kind{K}, Flag{F}, Prec{P}, Name{N} {}
2846 public:
2847 bool operator<(const OperatorInfo &Other) const {
2848 return *this < Other.Enc;
2850 bool operator<(const char *Peek) const {
2851 return Enc[0] < Peek[0] || (Enc[0] == Peek[0] && Enc[1] < Peek[1]);
2853 bool operator==(const char *Peek) const {
2854 return Enc[0] == Peek[0] && Enc[1] == Peek[1];
2856 bool operator!=(const char *Peek) const { return !this->operator==(Peek); }
2858 public:
2859 std::string_view getSymbol() const {
2860 std::string_view Res = Name;
2861 if (Kind < Unnameable) {
2862 assert(starts_with(Res, "operator") &&
2863 "operator name does not start with 'operator'");
2864 Res.remove_prefix(sizeof("operator") - 1);
2865 if (starts_with(Res, ' '))
2866 Res.remove_prefix(1);
2868 return Res;
2870 std::string_view getName() const { return Name; }
2871 OIKind getKind() const { return Kind; }
2872 bool getFlag() const { return Flag; }
2873 Node::Prec getPrecedence() const { return Prec; }
2875 static const OperatorInfo Ops[];
2876 static const size_t NumOps;
2877 const OperatorInfo *parseOperatorEncoding();
2879 /// Parse the <unresolved-name> production.
2880 Node *parseUnresolvedName(bool Global);
2881 Node *parseSimpleId();
2882 Node *parseBaseUnresolvedName();
2883 Node *parseUnresolvedType();
2884 Node *parseDestructorName();
2886 /// Top-level entry point into the parser.
2887 Node *parse();
2890 const char* parse_discriminator(const char* first, const char* last);
2892 // <name> ::= <nested-name> // N
2893 // ::= <local-name> # See Scope Encoding below // Z
2894 // ::= <unscoped-template-name> <template-args>
2895 // ::= <unscoped-name>
2897 // <unscoped-template-name> ::= <unscoped-name>
2898 // ::= <substitution>
2899 template <typename Derived, typename Alloc>
2900 Node *AbstractManglingParser<Derived, Alloc>::parseName(NameState *State) {
2901 if (look() == 'N')
2902 return getDerived().parseNestedName(State);
2903 if (look() == 'Z')
2904 return getDerived().parseLocalName(State);
2906 Node *Result = nullptr;
2907 bool IsSubst = false;
2909 Result = getDerived().parseUnscopedName(State, &IsSubst);
2910 if (!Result)
2911 return nullptr;
2913 if (look() == 'I') {
2914 // ::= <unscoped-template-name> <template-args>
2915 if (!IsSubst)
2916 // An unscoped-template-name is substitutable.
2917 Subs.push_back(Result);
2918 Node *TA = getDerived().parseTemplateArgs(State != nullptr);
2919 if (TA == nullptr)
2920 return nullptr;
2921 if (State)
2922 State->EndsWithTemplateArgs = true;
2923 Result = make<NameWithTemplateArgs>(Result, TA);
2924 } else if (IsSubst) {
2925 // The substitution case must be followed by <template-args>.
2926 return nullptr;
2929 return Result;
2932 // <local-name> := Z <function encoding> E <entity name> [<discriminator>]
2933 // := Z <function encoding> E s [<discriminator>]
2934 // := Z <function encoding> Ed [ <parameter number> ] _ <entity name>
2935 template <typename Derived, typename Alloc>
2936 Node *AbstractManglingParser<Derived, Alloc>::parseLocalName(NameState *State) {
2937 if (!consumeIf('Z'))
2938 return nullptr;
2939 Node *Encoding = getDerived().parseEncoding();
2940 if (Encoding == nullptr || !consumeIf('E'))
2941 return nullptr;
2943 if (consumeIf('s')) {
2944 First = parse_discriminator(First, Last);
2945 auto *StringLitName = make<NameType>("string literal");
2946 if (!StringLitName)
2947 return nullptr;
2948 return make<LocalName>(Encoding, StringLitName);
2951 // The template parameters of the inner name are unrelated to those of the
2952 // enclosing context.
2953 SaveTemplateParams SaveTemplateParamsScope(this);
2955 if (consumeIf('d')) {
2956 parseNumber(true);
2957 if (!consumeIf('_'))
2958 return nullptr;
2959 Node *N = getDerived().parseName(State);
2960 if (N == nullptr)
2961 return nullptr;
2962 return make<LocalName>(Encoding, N);
2965 Node *Entity = getDerived().parseName(State);
2966 if (Entity == nullptr)
2967 return nullptr;
2968 First = parse_discriminator(First, Last);
2969 return make<LocalName>(Encoding, Entity);
2972 // <unscoped-name> ::= <unqualified-name>
2973 // ::= St <unqualified-name> # ::std::
2974 // [*] extension
2975 template <typename Derived, typename Alloc>
2976 Node *
2977 AbstractManglingParser<Derived, Alloc>::parseUnscopedName(NameState *State,
2978 bool *IsSubst) {
2980 Node *Std = nullptr;
2981 if (consumeIf("St")) {
2982 Std = make<NameType>("std");
2983 if (Std == nullptr)
2984 return nullptr;
2987 Node *Res = nullptr;
2988 ModuleName *Module = nullptr;
2989 if (look() == 'S') {
2990 Node *S = getDerived().parseSubstitution();
2991 if (!S)
2992 return nullptr;
2993 if (S->getKind() == Node::KModuleName)
2994 Module = static_cast<ModuleName *>(S);
2995 else if (IsSubst && Std == nullptr) {
2996 Res = S;
2997 *IsSubst = true;
2998 } else {
2999 return nullptr;
3003 if (Res == nullptr || Std != nullptr) {
3004 Res = getDerived().parseUnqualifiedName(State, Std, Module);
3007 return Res;
3010 // <unqualified-name> ::= [<module-name>] F? L? <operator-name> [<abi-tags>]
3011 // ::= [<module-name>] <ctor-dtor-name> [<abi-tags>]
3012 // ::= [<module-name>] F? L? <source-name> [<abi-tags>]
3013 // ::= [<module-name>] L? <unnamed-type-name> [<abi-tags>]
3014 // # structured binding declaration
3015 // ::= [<module-name>] L? DC <source-name>+ E
3016 template <typename Derived, typename Alloc>
3017 Node *AbstractManglingParser<Derived, Alloc>::parseUnqualifiedName(
3018 NameState *State, Node *Scope, ModuleName *Module) {
3019 if (getDerived().parseModuleNameOpt(Module))
3020 return nullptr;
3022 bool IsMemberLikeFriend = Scope && consumeIf('F');
3024 consumeIf('L');
3026 Node *Result;
3027 if (look() >= '1' && look() <= '9') {
3028 Result = getDerived().parseSourceName(State);
3029 } else if (look() == 'U') {
3030 Result = getDerived().parseUnnamedTypeName(State);
3031 } else if (consumeIf("DC")) {
3032 // Structured binding
3033 size_t BindingsBegin = Names.size();
3034 do {
3035 Node *Binding = getDerived().parseSourceName(State);
3036 if (Binding == nullptr)
3037 return nullptr;
3038 Names.push_back(Binding);
3039 } while (!consumeIf('E'));
3040 Result = make<StructuredBindingName>(popTrailingNodeArray(BindingsBegin));
3041 } else if (look() == 'C' || look() == 'D') {
3042 // A <ctor-dtor-name>.
3043 if (Scope == nullptr || Module != nullptr)
3044 return nullptr;
3045 Result = getDerived().parseCtorDtorName(Scope, State);
3046 } else {
3047 Result = getDerived().parseOperatorName(State);
3050 if (Result != nullptr && Module != nullptr)
3051 Result = make<ModuleEntity>(Module, Result);
3052 if (Result != nullptr)
3053 Result = getDerived().parseAbiTags(Result);
3054 if (Result != nullptr && IsMemberLikeFriend)
3055 Result = make<MemberLikeFriendName>(Scope, Result);
3056 else if (Result != nullptr && Scope != nullptr)
3057 Result = make<NestedName>(Scope, Result);
3059 return Result;
3062 // <module-name> ::= <module-subname>
3063 // ::= <module-name> <module-subname>
3064 // ::= <substitution> # passed in by caller
3065 // <module-subname> ::= W <source-name>
3066 // ::= W P <source-name>
3067 template <typename Derived, typename Alloc>
3068 bool AbstractManglingParser<Derived, Alloc>::parseModuleNameOpt(
3069 ModuleName *&Module) {
3070 while (consumeIf('W')) {
3071 bool IsPartition = consumeIf('P');
3072 Node *Sub = getDerived().parseSourceName(nullptr);
3073 if (!Sub)
3074 return true;
3075 Module =
3076 static_cast<ModuleName *>(make<ModuleName>(Module, Sub, IsPartition));
3077 Subs.push_back(Module);
3080 return false;
3083 // <unnamed-type-name> ::= Ut [<nonnegative number>] _
3084 // ::= <closure-type-name>
3086 // <closure-type-name> ::= Ul <lambda-sig> E [ <nonnegative number> ] _
3088 // <lambda-sig> ::= <template-param-decl>* [Q <requires-clause expression>]
3089 // <parameter type>+ # or "v" if the lambda has no parameters
3090 template <typename Derived, typename Alloc>
3091 Node *
3092 AbstractManglingParser<Derived, Alloc>::parseUnnamedTypeName(NameState *State) {
3093 // <template-params> refer to the innermost <template-args>. Clear out any
3094 // outer args that we may have inserted into TemplateParams.
3095 if (State != nullptr)
3096 TemplateParams.clear();
3098 if (consumeIf("Ut")) {
3099 std::string_view Count = parseNumber();
3100 if (!consumeIf('_'))
3101 return nullptr;
3102 return make<UnnamedTypeName>(Count);
3104 if (consumeIf("Ul")) {
3105 ScopedOverride<size_t> SwapParams(ParsingLambdaParamsAtLevel,
3106 TemplateParams.size());
3107 ScopedTemplateParamList LambdaTemplateParams(this);
3109 size_t ParamsBegin = Names.size();
3110 while (getDerived().isTemplateParamDecl()) {
3111 Node *T =
3112 getDerived().parseTemplateParamDecl(LambdaTemplateParams.params());
3113 if (T == nullptr)
3114 return nullptr;
3115 Names.push_back(T);
3117 NodeArray TempParams = popTrailingNodeArray(ParamsBegin);
3119 // FIXME: If TempParams is empty and none of the function parameters
3120 // includes 'auto', we should remove LambdaTemplateParams from the
3121 // TemplateParams list. Unfortunately, we don't find out whether there are
3122 // any 'auto' parameters until too late in an example such as:
3124 // template<typename T> void f(
3125 // decltype([](decltype([]<typename T>(T v) {}),
3126 // auto) {})) {}
3127 // template<typename T> void f(
3128 // decltype([](decltype([]<typename T>(T w) {}),
3129 // int) {})) {}
3131 // Here, the type of v is at level 2 but the type of w is at level 1. We
3132 // don't find this out until we encounter the type of the next parameter.
3134 // However, compilers can't actually cope with the former example in
3135 // practice, and it's likely to be made ill-formed in future, so we don't
3136 // need to support it here.
3138 // If we encounter an 'auto' in the function parameter types, we will
3139 // recreate a template parameter scope for it, but any intervening lambdas
3140 // will be parsed in the 'wrong' template parameter depth.
3141 if (TempParams.empty())
3142 TemplateParams.pop_back();
3144 Node *Requires1 = nullptr;
3145 if (consumeIf('Q')) {
3146 Requires1 = getDerived().parseConstraintExpr();
3147 if (Requires1 == nullptr)
3148 return nullptr;
3151 if (!consumeIf("v")) {
3152 do {
3153 Node *P = getDerived().parseType();
3154 if (P == nullptr)
3155 return nullptr;
3156 Names.push_back(P);
3157 } while (look() != 'E' && look() != 'Q');
3159 NodeArray Params = popTrailingNodeArray(ParamsBegin);
3161 Node *Requires2 = nullptr;
3162 if (consumeIf('Q')) {
3163 Requires2 = getDerived().parseConstraintExpr();
3164 if (Requires2 == nullptr)
3165 return nullptr;
3168 if (!consumeIf('E'))
3169 return nullptr;
3171 std::string_view Count = parseNumber();
3172 if (!consumeIf('_'))
3173 return nullptr;
3174 return make<ClosureTypeName>(TempParams, Requires1, Params, Requires2,
3175 Count);
3177 if (consumeIf("Ub")) {
3178 (void)parseNumber();
3179 if (!consumeIf('_'))
3180 return nullptr;
3181 return make<NameType>("'block-literal'");
3183 return nullptr;
3186 // <source-name> ::= <positive length number> <identifier>
3187 template <typename Derived, typename Alloc>
3188 Node *AbstractManglingParser<Derived, Alloc>::parseSourceName(NameState *) {
3189 size_t Length = 0;
3190 if (parsePositiveInteger(&Length))
3191 return nullptr;
3192 if (numLeft() < Length || Length == 0)
3193 return nullptr;
3194 std::string_view Name(First, Length);
3195 First += Length;
3196 if (starts_with(Name, "_GLOBAL__N"))
3197 return make<NameType>("(anonymous namespace)");
3198 return make<NameType>(Name);
3201 // Operator encodings
3202 template <typename Derived, typename Alloc>
3203 const typename AbstractManglingParser<
3204 Derived, Alloc>::OperatorInfo AbstractManglingParser<Derived,
3205 Alloc>::Ops[] = {
3206 // Keep ordered by encoding
3207 {"aN", OperatorInfo::Binary, false, Node::Prec::Assign, "operator&="},
3208 {"aS", OperatorInfo::Binary, false, Node::Prec::Assign, "operator="},
3209 {"aa", OperatorInfo::Binary, false, Node::Prec::AndIf, "operator&&"},
3210 {"ad", OperatorInfo::Prefix, false, Node::Prec::Unary, "operator&"},
3211 {"an", OperatorInfo::Binary, false, Node::Prec::And, "operator&"},
3212 {"at", OperatorInfo::OfIdOp, /*Type*/ true, Node::Prec::Unary, "alignof "},
3213 {"aw", OperatorInfo::NameOnly, false, Node::Prec::Primary,
3214 "operator co_await"},
3215 {"az", OperatorInfo::OfIdOp, /*Type*/ false, Node::Prec::Unary, "alignof "},
3216 {"cc", OperatorInfo::NamedCast, false, Node::Prec::Postfix, "const_cast"},
3217 {"cl", OperatorInfo::Call, false, Node::Prec::Postfix, "operator()"},
3218 {"cm", OperatorInfo::Binary, false, Node::Prec::Comma, "operator,"},
3219 {"co", OperatorInfo::Prefix, false, Node::Prec::Unary, "operator~"},
3220 {"cv", OperatorInfo::CCast, false, Node::Prec::Cast, "operator"}, // C Cast
3221 {"dV", OperatorInfo::Binary, false, Node::Prec::Assign, "operator/="},
3222 {"da", OperatorInfo::Del, /*Ary*/ true, Node::Prec::Unary,
3223 "operator delete[]"},
3224 {"dc", OperatorInfo::NamedCast, false, Node::Prec::Postfix, "dynamic_cast"},
3225 {"de", OperatorInfo::Prefix, false, Node::Prec::Unary, "operator*"},
3226 {"dl", OperatorInfo::Del, /*Ary*/ false, Node::Prec::Unary,
3227 "operator delete"},
3228 {"ds", OperatorInfo::Member, /*Named*/ false, Node::Prec::PtrMem,
3229 "operator.*"},
3230 {"dt", OperatorInfo::Member, /*Named*/ false, Node::Prec::Postfix,
3231 "operator."},
3232 {"dv", OperatorInfo::Binary, false, Node::Prec::Assign, "operator/"},
3233 {"eO", OperatorInfo::Binary, false, Node::Prec::Assign, "operator^="},
3234 {"eo", OperatorInfo::Binary, false, Node::Prec::Xor, "operator^"},
3235 {"eq", OperatorInfo::Binary, false, Node::Prec::Equality, "operator=="},
3236 {"ge", OperatorInfo::Binary, false, Node::Prec::Relational, "operator>="},
3237 {"gt", OperatorInfo::Binary, false, Node::Prec::Relational, "operator>"},
3238 {"ix", OperatorInfo::Array, false, Node::Prec::Postfix, "operator[]"},
3239 {"lS", OperatorInfo::Binary, false, Node::Prec::Assign, "operator<<="},
3240 {"le", OperatorInfo::Binary, false, Node::Prec::Relational, "operator<="},
3241 {"ls", OperatorInfo::Binary, false, Node::Prec::Shift, "operator<<"},
3242 {"lt", OperatorInfo::Binary, false, Node::Prec::Relational, "operator<"},
3243 {"mI", OperatorInfo::Binary, false, Node::Prec::Assign, "operator-="},
3244 {"mL", OperatorInfo::Binary, false, Node::Prec::Assign, "operator*="},
3245 {"mi", OperatorInfo::Binary, false, Node::Prec::Additive, "operator-"},
3246 {"ml", OperatorInfo::Binary, false, Node::Prec::Multiplicative,
3247 "operator*"},
3248 {"mm", OperatorInfo::Postfix, false, Node::Prec::Postfix, "operator--"},
3249 {"na", OperatorInfo::New, /*Ary*/ true, Node::Prec::Unary,
3250 "operator new[]"},
3251 {"ne", OperatorInfo::Binary, false, Node::Prec::Equality, "operator!="},
3252 {"ng", OperatorInfo::Prefix, false, Node::Prec::Unary, "operator-"},
3253 {"nt", OperatorInfo::Prefix, false, Node::Prec::Unary, "operator!"},
3254 {"nw", OperatorInfo::New, /*Ary*/ false, Node::Prec::Unary, "operator new"},
3255 {"oR", OperatorInfo::Binary, false, Node::Prec::Assign, "operator|="},
3256 {"oo", OperatorInfo::Binary, false, Node::Prec::OrIf, "operator||"},
3257 {"or", OperatorInfo::Binary, false, Node::Prec::Ior, "operator|"},
3258 {"pL", OperatorInfo::Binary, false, Node::Prec::Assign, "operator+="},
3259 {"pl", OperatorInfo::Binary, false, Node::Prec::Additive, "operator+"},
3260 {"pm", OperatorInfo::Member, /*Named*/ false, Node::Prec::PtrMem,
3261 "operator->*"},
3262 {"pp", OperatorInfo::Postfix, false, Node::Prec::Postfix, "operator++"},
3263 {"ps", OperatorInfo::Prefix, false, Node::Prec::Unary, "operator+"},
3264 {"pt", OperatorInfo::Member, /*Named*/ true, Node::Prec::Postfix,
3265 "operator->"},
3266 {"qu", OperatorInfo::Conditional, false, Node::Prec::Conditional,
3267 "operator?"},
3268 {"rM", OperatorInfo::Binary, false, Node::Prec::Assign, "operator%="},
3269 {"rS", OperatorInfo::Binary, false, Node::Prec::Assign, "operator>>="},
3270 {"rc", OperatorInfo::NamedCast, false, Node::Prec::Postfix,
3271 "reinterpret_cast"},
3272 {"rm", OperatorInfo::Binary, false, Node::Prec::Multiplicative,
3273 "operator%"},
3274 {"rs", OperatorInfo::Binary, false, Node::Prec::Shift, "operator>>"},
3275 {"sc", OperatorInfo::NamedCast, false, Node::Prec::Postfix, "static_cast"},
3276 {"ss", OperatorInfo::Binary, false, Node::Prec::Spaceship, "operator<=>"},
3277 {"st", OperatorInfo::OfIdOp, /*Type*/ true, Node::Prec::Unary, "sizeof "},
3278 {"sz", OperatorInfo::OfIdOp, /*Type*/ false, Node::Prec::Unary, "sizeof "},
3279 {"te", OperatorInfo::OfIdOp, /*Type*/ false, Node::Prec::Postfix,
3280 "typeid "},
3281 {"ti", OperatorInfo::OfIdOp, /*Type*/ true, Node::Prec::Postfix, "typeid "},
3283 template <typename Derived, typename Alloc>
3284 const size_t AbstractManglingParser<Derived, Alloc>::NumOps = sizeof(Ops) /
3285 sizeof(Ops[0]);
3287 // If the next 2 chars are an operator encoding, consume them and return their
3288 // OperatorInfo. Otherwise return nullptr.
3289 template <typename Derived, typename Alloc>
3290 const typename AbstractManglingParser<Derived, Alloc>::OperatorInfo *
3291 AbstractManglingParser<Derived, Alloc>::parseOperatorEncoding() {
3292 if (numLeft() < 2)
3293 return nullptr;
3295 // We can't use lower_bound as that can link to symbols in the C++ library,
3296 // and this must remain independant of that.
3297 size_t lower = 0u, upper = NumOps - 1; // Inclusive bounds.
3298 while (upper != lower) {
3299 size_t middle = (upper + lower) / 2;
3300 if (Ops[middle] < First)
3301 lower = middle + 1;
3302 else
3303 upper = middle;
3305 if (Ops[lower] != First)
3306 return nullptr;
3308 First += 2;
3309 return &Ops[lower];
3312 // <operator-name> ::= See parseOperatorEncoding()
3313 // ::= li <source-name> # operator ""
3314 // ::= v <digit> <source-name> # vendor extended operator
3315 template <typename Derived, typename Alloc>
3316 Node *
3317 AbstractManglingParser<Derived, Alloc>::parseOperatorName(NameState *State) {
3318 if (const auto *Op = parseOperatorEncoding()) {
3319 if (Op->getKind() == OperatorInfo::CCast) {
3320 // ::= cv <type> # (cast)
3321 ScopedOverride<bool> SaveTemplate(TryToParseTemplateArgs, false);
3322 // If we're parsing an encoding, State != nullptr and the conversion
3323 // operators' <type> could have a <template-param> that refers to some
3324 // <template-arg>s further ahead in the mangled name.
3325 ScopedOverride<bool> SavePermit(PermitForwardTemplateReferences,
3326 PermitForwardTemplateReferences ||
3327 State != nullptr);
3328 Node *Ty = getDerived().parseType();
3329 if (Ty == nullptr)
3330 return nullptr;
3331 if (State) State->CtorDtorConversion = true;
3332 return make<ConversionOperatorType>(Ty);
3335 if (Op->getKind() >= OperatorInfo::Unnameable)
3336 /* Not a nameable operator. */
3337 return nullptr;
3338 if (Op->getKind() == OperatorInfo::Member && !Op->getFlag())
3339 /* Not a nameable MemberExpr */
3340 return nullptr;
3342 return make<NameType>(Op->getName());
3345 if (consumeIf("li")) {
3346 // ::= li <source-name> # operator ""
3347 Node *SN = getDerived().parseSourceName(State);
3348 if (SN == nullptr)
3349 return nullptr;
3350 return make<LiteralOperator>(SN);
3353 if (consumeIf('v')) {
3354 // ::= v <digit> <source-name> # vendor extended operator
3355 if (look() >= '0' && look() <= '9') {
3356 First++;
3357 Node *SN = getDerived().parseSourceName(State);
3358 if (SN == nullptr)
3359 return nullptr;
3360 return make<ConversionOperatorType>(SN);
3362 return nullptr;
3365 return nullptr;
3368 // <ctor-dtor-name> ::= C1 # complete object constructor
3369 // ::= C2 # base object constructor
3370 // ::= C3 # complete object allocating constructor
3371 // extension ::= C4 # gcc old-style "[unified]" constructor
3372 // extension ::= C5 # the COMDAT used for ctors
3373 // ::= D0 # deleting destructor
3374 // ::= D1 # complete object destructor
3375 // ::= D2 # base object destructor
3376 // extension ::= D4 # gcc old-style "[unified]" destructor
3377 // extension ::= D5 # the COMDAT used for dtors
3378 template <typename Derived, typename Alloc>
3379 Node *
3380 AbstractManglingParser<Derived, Alloc>::parseCtorDtorName(Node *&SoFar,
3381 NameState *State) {
3382 if (SoFar->getKind() == Node::KSpecialSubstitution) {
3383 // Expand the special substitution.
3384 SoFar = make<ExpandedSpecialSubstitution>(
3385 static_cast<SpecialSubstitution *>(SoFar));
3386 if (!SoFar)
3387 return nullptr;
3390 if (consumeIf('C')) {
3391 bool IsInherited = consumeIf('I');
3392 if (look() != '1' && look() != '2' && look() != '3' && look() != '4' &&
3393 look() != '5')
3394 return nullptr;
3395 int Variant = look() - '0';
3396 ++First;
3397 if (State) State->CtorDtorConversion = true;
3398 if (IsInherited) {
3399 if (getDerived().parseName(State) == nullptr)
3400 return nullptr;
3402 return make<CtorDtorName>(SoFar, /*IsDtor=*/false, Variant);
3405 if (look() == 'D' && (look(1) == '0' || look(1) == '1' || look(1) == '2' ||
3406 look(1) == '4' || look(1) == '5')) {
3407 int Variant = look(1) - '0';
3408 First += 2;
3409 if (State) State->CtorDtorConversion = true;
3410 return make<CtorDtorName>(SoFar, /*IsDtor=*/true, Variant);
3413 return nullptr;
3416 // <nested-name> ::= N [<CV-Qualifiers>] [<ref-qualifier>] <prefix>
3417 // <unqualified-name> E
3418 // ::= N [<CV-Qualifiers>] [<ref-qualifier>] <template-prefix>
3419 // <template-args> E
3421 // <prefix> ::= <prefix> <unqualified-name>
3422 // ::= <template-prefix> <template-args>
3423 // ::= <template-param>
3424 // ::= <decltype>
3425 // ::= # empty
3426 // ::= <substitution>
3427 // ::= <prefix> <data-member-prefix>
3428 // [*] extension
3430 // <data-member-prefix> := <member source-name> [<template-args>] M
3432 // <template-prefix> ::= <prefix> <template unqualified-name>
3433 // ::= <template-param>
3434 // ::= <substitution>
3435 template <typename Derived, typename Alloc>
3436 Node *
3437 AbstractManglingParser<Derived, Alloc>::parseNestedName(NameState *State) {
3438 if (!consumeIf('N'))
3439 return nullptr;
3441 Qualifiers CVTmp = parseCVQualifiers();
3442 if (State) State->CVQualifiers = CVTmp;
3444 if (consumeIf('O')) {
3445 if (State) State->ReferenceQualifier = FrefQualRValue;
3446 } else if (consumeIf('R')) {
3447 if (State) State->ReferenceQualifier = FrefQualLValue;
3448 } else {
3449 if (State) State->ReferenceQualifier = FrefQualNone;
3452 Node *SoFar = nullptr;
3453 while (!consumeIf('E')) {
3454 if (State)
3455 // Only set end-with-template on the case that does that.
3456 State->EndsWithTemplateArgs = false;
3458 if (look() == 'T') {
3459 // ::= <template-param>
3460 if (SoFar != nullptr)
3461 return nullptr; // Cannot have a prefix.
3462 SoFar = getDerived().parseTemplateParam();
3463 } else if (look() == 'I') {
3464 // ::= <template-prefix> <template-args>
3465 if (SoFar == nullptr)
3466 return nullptr; // Must have a prefix.
3467 Node *TA = getDerived().parseTemplateArgs(State != nullptr);
3468 if (TA == nullptr)
3469 return nullptr;
3470 if (SoFar->getKind() == Node::KNameWithTemplateArgs)
3471 // Semantically <template-args> <template-args> cannot be generated by a
3472 // C++ entity. There will always be [something like] a name between
3473 // them.
3474 return nullptr;
3475 if (State)
3476 State->EndsWithTemplateArgs = true;
3477 SoFar = make<NameWithTemplateArgs>(SoFar, TA);
3478 } else if (look() == 'D' && (look(1) == 't' || look(1) == 'T')) {
3479 // ::= <decltype>
3480 if (SoFar != nullptr)
3481 return nullptr; // Cannot have a prefix.
3482 SoFar = getDerived().parseDecltype();
3483 } else {
3484 ModuleName *Module = nullptr;
3486 if (look() == 'S') {
3487 // ::= <substitution>
3488 Node *S = nullptr;
3489 if (look(1) == 't') {
3490 First += 2;
3491 S = make<NameType>("std");
3492 } else {
3493 S = getDerived().parseSubstitution();
3495 if (!S)
3496 return nullptr;
3497 if (S->getKind() == Node::KModuleName) {
3498 Module = static_cast<ModuleName *>(S);
3499 } else if (SoFar != nullptr) {
3500 return nullptr; // Cannot have a prefix.
3501 } else {
3502 SoFar = S;
3503 continue; // Do not push a new substitution.
3507 // ::= [<prefix>] <unqualified-name>
3508 SoFar = getDerived().parseUnqualifiedName(State, SoFar, Module);
3511 if (SoFar == nullptr)
3512 return nullptr;
3513 Subs.push_back(SoFar);
3515 // No longer used.
3516 // <data-member-prefix> := <member source-name> [<template-args>] M
3517 consumeIf('M');
3520 if (SoFar == nullptr || Subs.empty())
3521 return nullptr;
3523 Subs.pop_back();
3524 return SoFar;
3527 // <simple-id> ::= <source-name> [ <template-args> ]
3528 template <typename Derived, typename Alloc>
3529 Node *AbstractManglingParser<Derived, Alloc>::parseSimpleId() {
3530 Node *SN = getDerived().parseSourceName(/*NameState=*/nullptr);
3531 if (SN == nullptr)
3532 return nullptr;
3533 if (look() == 'I') {
3534 Node *TA = getDerived().parseTemplateArgs();
3535 if (TA == nullptr)
3536 return nullptr;
3537 return make<NameWithTemplateArgs>(SN, TA);
3539 return SN;
3542 // <destructor-name> ::= <unresolved-type> # e.g., ~T or ~decltype(f())
3543 // ::= <simple-id> # e.g., ~A<2*N>
3544 template <typename Derived, typename Alloc>
3545 Node *AbstractManglingParser<Derived, Alloc>::parseDestructorName() {
3546 Node *Result;
3547 if (std::isdigit(look()))
3548 Result = getDerived().parseSimpleId();
3549 else
3550 Result = getDerived().parseUnresolvedType();
3551 if (Result == nullptr)
3552 return nullptr;
3553 return make<DtorName>(Result);
3556 // <unresolved-type> ::= <template-param>
3557 // ::= <decltype>
3558 // ::= <substitution>
3559 template <typename Derived, typename Alloc>
3560 Node *AbstractManglingParser<Derived, Alloc>::parseUnresolvedType() {
3561 if (look() == 'T') {
3562 Node *TP = getDerived().parseTemplateParam();
3563 if (TP == nullptr)
3564 return nullptr;
3565 Subs.push_back(TP);
3566 return TP;
3568 if (look() == 'D') {
3569 Node *DT = getDerived().parseDecltype();
3570 if (DT == nullptr)
3571 return nullptr;
3572 Subs.push_back(DT);
3573 return DT;
3575 return getDerived().parseSubstitution();
3578 // <base-unresolved-name> ::= <simple-id> # unresolved name
3579 // extension ::= <operator-name> # unresolved operator-function-id
3580 // extension ::= <operator-name> <template-args> # unresolved operator template-id
3581 // ::= on <operator-name> # unresolved operator-function-id
3582 // ::= on <operator-name> <template-args> # unresolved operator template-id
3583 // ::= dn <destructor-name> # destructor or pseudo-destructor;
3584 // # e.g. ~X or ~X<N-1>
3585 template <typename Derived, typename Alloc>
3586 Node *AbstractManglingParser<Derived, Alloc>::parseBaseUnresolvedName() {
3587 if (std::isdigit(look()))
3588 return getDerived().parseSimpleId();
3590 if (consumeIf("dn"))
3591 return getDerived().parseDestructorName();
3593 consumeIf("on");
3595 Node *Oper = getDerived().parseOperatorName(/*NameState=*/nullptr);
3596 if (Oper == nullptr)
3597 return nullptr;
3598 if (look() == 'I') {
3599 Node *TA = getDerived().parseTemplateArgs();
3600 if (TA == nullptr)
3601 return nullptr;
3602 return make<NameWithTemplateArgs>(Oper, TA);
3604 return Oper;
3607 // <unresolved-name>
3608 // extension ::= srN <unresolved-type> [<template-args>] <unresolved-qualifier-level>* E <base-unresolved-name>
3609 // ::= [gs] <base-unresolved-name> # x or (with "gs") ::x
3610 // ::= [gs] sr <unresolved-qualifier-level>+ E <base-unresolved-name>
3611 // # A::x, N::y, A<T>::z; "gs" means leading "::"
3612 // [gs] has been parsed by caller.
3613 // ::= sr <unresolved-type> <base-unresolved-name> # T::x / decltype(p)::x
3614 // extension ::= sr <unresolved-type> <template-args> <base-unresolved-name>
3615 // # T::N::x /decltype(p)::N::x
3616 // (ignored) ::= srN <unresolved-type> <unresolved-qualifier-level>+ E <base-unresolved-name>
3618 // <unresolved-qualifier-level> ::= <simple-id>
3619 template <typename Derived, typename Alloc>
3620 Node *AbstractManglingParser<Derived, Alloc>::parseUnresolvedName(bool Global) {
3621 Node *SoFar = nullptr;
3623 // srN <unresolved-type> [<template-args>] <unresolved-qualifier-level>* E <base-unresolved-name>
3624 // srN <unresolved-type> <unresolved-qualifier-level>+ E <base-unresolved-name>
3625 if (consumeIf("srN")) {
3626 SoFar = getDerived().parseUnresolvedType();
3627 if (SoFar == nullptr)
3628 return nullptr;
3630 if (look() == 'I') {
3631 Node *TA = getDerived().parseTemplateArgs();
3632 if (TA == nullptr)
3633 return nullptr;
3634 SoFar = make<NameWithTemplateArgs>(SoFar, TA);
3635 if (!SoFar)
3636 return nullptr;
3639 while (!consumeIf('E')) {
3640 Node *Qual = getDerived().parseSimpleId();
3641 if (Qual == nullptr)
3642 return nullptr;
3643 SoFar = make<QualifiedName>(SoFar, Qual);
3644 if (!SoFar)
3645 return nullptr;
3648 Node *Base = getDerived().parseBaseUnresolvedName();
3649 if (Base == nullptr)
3650 return nullptr;
3651 return make<QualifiedName>(SoFar, Base);
3654 // [gs] <base-unresolved-name> # x or (with "gs") ::x
3655 if (!consumeIf("sr")) {
3656 SoFar = getDerived().parseBaseUnresolvedName();
3657 if (SoFar == nullptr)
3658 return nullptr;
3659 if (Global)
3660 SoFar = make<GlobalQualifiedName>(SoFar);
3661 return SoFar;
3664 // [gs] sr <unresolved-qualifier-level>+ E <base-unresolved-name>
3665 if (std::isdigit(look())) {
3666 do {
3667 Node *Qual = getDerived().parseSimpleId();
3668 if (Qual == nullptr)
3669 return nullptr;
3670 if (SoFar)
3671 SoFar = make<QualifiedName>(SoFar, Qual);
3672 else if (Global)
3673 SoFar = make<GlobalQualifiedName>(Qual);
3674 else
3675 SoFar = Qual;
3676 if (!SoFar)
3677 return nullptr;
3678 } while (!consumeIf('E'));
3680 // sr <unresolved-type> <base-unresolved-name>
3681 // sr <unresolved-type> <template-args> <base-unresolved-name>
3682 else {
3683 SoFar = getDerived().parseUnresolvedType();
3684 if (SoFar == nullptr)
3685 return nullptr;
3687 if (look() == 'I') {
3688 Node *TA = getDerived().parseTemplateArgs();
3689 if (TA == nullptr)
3690 return nullptr;
3691 SoFar = make<NameWithTemplateArgs>(SoFar, TA);
3692 if (!SoFar)
3693 return nullptr;
3697 assert(SoFar != nullptr);
3699 Node *Base = getDerived().parseBaseUnresolvedName();
3700 if (Base == nullptr)
3701 return nullptr;
3702 return make<QualifiedName>(SoFar, Base);
3705 // <abi-tags> ::= <abi-tag> [<abi-tags>]
3706 // <abi-tag> ::= B <source-name>
3707 template <typename Derived, typename Alloc>
3708 Node *AbstractManglingParser<Derived, Alloc>::parseAbiTags(Node *N) {
3709 while (consumeIf('B')) {
3710 std::string_view SN = parseBareSourceName();
3711 if (SN.empty())
3712 return nullptr;
3713 N = make<AbiTagAttr>(N, SN);
3714 if (!N)
3715 return nullptr;
3717 return N;
3720 // <number> ::= [n] <non-negative decimal integer>
3721 template <typename Alloc, typename Derived>
3722 std::string_view
3723 AbstractManglingParser<Alloc, Derived>::parseNumber(bool AllowNegative) {
3724 const char *Tmp = First;
3725 if (AllowNegative)
3726 consumeIf('n');
3727 if (numLeft() == 0 || !std::isdigit(*First))
3728 return std::string_view();
3729 while (numLeft() != 0 && std::isdigit(*First))
3730 ++First;
3731 return std::string_view(Tmp, First - Tmp);
3734 // <positive length number> ::= [0-9]*
3735 template <typename Alloc, typename Derived>
3736 bool AbstractManglingParser<Alloc, Derived>::parsePositiveInteger(size_t *Out) {
3737 *Out = 0;
3738 if (look() < '0' || look() > '9')
3739 return true;
3740 while (look() >= '0' && look() <= '9') {
3741 *Out *= 10;
3742 *Out += static_cast<size_t>(consume() - '0');
3744 return false;
3747 template <typename Alloc, typename Derived>
3748 std::string_view AbstractManglingParser<Alloc, Derived>::parseBareSourceName() {
3749 size_t Int = 0;
3750 if (parsePositiveInteger(&Int) || numLeft() < Int)
3751 return {};
3752 std::string_view R(First, Int);
3753 First += Int;
3754 return R;
3757 // <function-type> ::= [<CV-qualifiers>] [<exception-spec>] [Dx] F [Y] <bare-function-type> [<ref-qualifier>] E
3759 // <exception-spec> ::= Do # non-throwing exception-specification (e.g., noexcept, throw())
3760 // ::= DO <expression> E # computed (instantiation-dependent) noexcept
3761 // ::= Dw <type>+ E # dynamic exception specification with instantiation-dependent types
3763 // <ref-qualifier> ::= R # & ref-qualifier
3764 // <ref-qualifier> ::= O # && ref-qualifier
3765 template <typename Derived, typename Alloc>
3766 Node *AbstractManglingParser<Derived, Alloc>::parseFunctionType() {
3767 Qualifiers CVQuals = parseCVQualifiers();
3769 Node *ExceptionSpec = nullptr;
3770 if (consumeIf("Do")) {
3771 ExceptionSpec = make<NameType>("noexcept");
3772 if (!ExceptionSpec)
3773 return nullptr;
3774 } else if (consumeIf("DO")) {
3775 Node *E = getDerived().parseExpr();
3776 if (E == nullptr || !consumeIf('E'))
3777 return nullptr;
3778 ExceptionSpec = make<NoexceptSpec>(E);
3779 if (!ExceptionSpec)
3780 return nullptr;
3781 } else if (consumeIf("Dw")) {
3782 size_t SpecsBegin = Names.size();
3783 while (!consumeIf('E')) {
3784 Node *T = getDerived().parseType();
3785 if (T == nullptr)
3786 return nullptr;
3787 Names.push_back(T);
3789 ExceptionSpec =
3790 make<DynamicExceptionSpec>(popTrailingNodeArray(SpecsBegin));
3791 if (!ExceptionSpec)
3792 return nullptr;
3795 consumeIf("Dx"); // transaction safe
3797 if (!consumeIf('F'))
3798 return nullptr;
3799 consumeIf('Y'); // extern "C"
3800 Node *ReturnType = getDerived().parseType();
3801 if (ReturnType == nullptr)
3802 return nullptr;
3804 FunctionRefQual ReferenceQualifier = FrefQualNone;
3805 size_t ParamsBegin = Names.size();
3806 while (true) {
3807 if (consumeIf('E'))
3808 break;
3809 if (consumeIf('v'))
3810 continue;
3811 if (consumeIf("RE")) {
3812 ReferenceQualifier = FrefQualLValue;
3813 break;
3815 if (consumeIf("OE")) {
3816 ReferenceQualifier = FrefQualRValue;
3817 break;
3819 Node *T = getDerived().parseType();
3820 if (T == nullptr)
3821 return nullptr;
3822 Names.push_back(T);
3825 NodeArray Params = popTrailingNodeArray(ParamsBegin);
3826 return make<FunctionType>(ReturnType, Params, CVQuals,
3827 ReferenceQualifier, ExceptionSpec);
3830 // extension:
3831 // <vector-type> ::= Dv <positive dimension number> _ <extended element type>
3832 // ::= Dv [<dimension expression>] _ <element type>
3833 // <extended element type> ::= <element type>
3834 // ::= p # AltiVec vector pixel
3835 template <typename Derived, typename Alloc>
3836 Node *AbstractManglingParser<Derived, Alloc>::parseVectorType() {
3837 if (!consumeIf("Dv"))
3838 return nullptr;
3839 if (look() >= '1' && look() <= '9') {
3840 Node *DimensionNumber = make<NameType>(parseNumber());
3841 if (!DimensionNumber)
3842 return nullptr;
3843 if (!consumeIf('_'))
3844 return nullptr;
3845 if (consumeIf('p'))
3846 return make<PixelVectorType>(DimensionNumber);
3847 Node *ElemType = getDerived().parseType();
3848 if (ElemType == nullptr)
3849 return nullptr;
3850 return make<VectorType>(ElemType, DimensionNumber);
3853 if (!consumeIf('_')) {
3854 Node *DimExpr = getDerived().parseExpr();
3855 if (!DimExpr)
3856 return nullptr;
3857 if (!consumeIf('_'))
3858 return nullptr;
3859 Node *ElemType = getDerived().parseType();
3860 if (!ElemType)
3861 return nullptr;
3862 return make<VectorType>(ElemType, DimExpr);
3864 Node *ElemType = getDerived().parseType();
3865 if (!ElemType)
3866 return nullptr;
3867 return make<VectorType>(ElemType, /*Dimension=*/nullptr);
3870 // <decltype> ::= Dt <expression> E # decltype of an id-expression or class member access (C++0x)
3871 // ::= DT <expression> E # decltype of an expression (C++0x)
3872 template <typename Derived, typename Alloc>
3873 Node *AbstractManglingParser<Derived, Alloc>::parseDecltype() {
3874 if (!consumeIf('D'))
3875 return nullptr;
3876 if (!consumeIf('t') && !consumeIf('T'))
3877 return nullptr;
3878 Node *E = getDerived().parseExpr();
3879 if (E == nullptr)
3880 return nullptr;
3881 if (!consumeIf('E'))
3882 return nullptr;
3883 return make<EnclosingExpr>("decltype", E);
3886 // <array-type> ::= A <positive dimension number> _ <element type>
3887 // ::= A [<dimension expression>] _ <element type>
3888 template <typename Derived, typename Alloc>
3889 Node *AbstractManglingParser<Derived, Alloc>::parseArrayType() {
3890 if (!consumeIf('A'))
3891 return nullptr;
3893 Node *Dimension = nullptr;
3895 if (std::isdigit(look())) {
3896 Dimension = make<NameType>(parseNumber());
3897 if (!Dimension)
3898 return nullptr;
3899 if (!consumeIf('_'))
3900 return nullptr;
3901 } else if (!consumeIf('_')) {
3902 Node *DimExpr = getDerived().parseExpr();
3903 if (DimExpr == nullptr)
3904 return nullptr;
3905 if (!consumeIf('_'))
3906 return nullptr;
3907 Dimension = DimExpr;
3910 Node *Ty = getDerived().parseType();
3911 if (Ty == nullptr)
3912 return nullptr;
3913 return make<ArrayType>(Ty, Dimension);
3916 // <pointer-to-member-type> ::= M <class type> <member type>
3917 template <typename Derived, typename Alloc>
3918 Node *AbstractManglingParser<Derived, Alloc>::parsePointerToMemberType() {
3919 if (!consumeIf('M'))
3920 return nullptr;
3921 Node *ClassType = getDerived().parseType();
3922 if (ClassType == nullptr)
3923 return nullptr;
3924 Node *MemberType = getDerived().parseType();
3925 if (MemberType == nullptr)
3926 return nullptr;
3927 return make<PointerToMemberType>(ClassType, MemberType);
3930 // <class-enum-type> ::= <name> # non-dependent type name, dependent type name, or dependent typename-specifier
3931 // ::= Ts <name> # dependent elaborated type specifier using 'struct' or 'class'
3932 // ::= Tu <name> # dependent elaborated type specifier using 'union'
3933 // ::= Te <name> # dependent elaborated type specifier using 'enum'
3934 template <typename Derived, typename Alloc>
3935 Node *AbstractManglingParser<Derived, Alloc>::parseClassEnumType() {
3936 std::string_view ElabSpef;
3937 if (consumeIf("Ts"))
3938 ElabSpef = "struct";
3939 else if (consumeIf("Tu"))
3940 ElabSpef = "union";
3941 else if (consumeIf("Te"))
3942 ElabSpef = "enum";
3944 Node *Name = getDerived().parseName();
3945 if (Name == nullptr)
3946 return nullptr;
3948 if (!ElabSpef.empty())
3949 return make<ElaboratedTypeSpefType>(ElabSpef, Name);
3951 return Name;
3954 // <qualified-type> ::= <qualifiers> <type>
3955 // <qualifiers> ::= <extended-qualifier>* <CV-qualifiers>
3956 // <extended-qualifier> ::= U <source-name> [<template-args>] # vendor extended type qualifier
3957 template <typename Derived, typename Alloc>
3958 Node *AbstractManglingParser<Derived, Alloc>::parseQualifiedType() {
3959 if (consumeIf('U')) {
3960 std::string_view Qual = parseBareSourceName();
3961 if (Qual.empty())
3962 return nullptr;
3964 // extension ::= U <objc-name> <objc-type> # objc-type<identifier>
3965 if (starts_with(Qual, "objcproto")) {
3966 constexpr size_t Len = sizeof("objcproto") - 1;
3967 std::string_view ProtoSourceName(Qual.data() + Len, Qual.size() - Len);
3968 std::string_view Proto;
3970 ScopedOverride<const char *> SaveFirst(First, ProtoSourceName.data()),
3971 SaveLast(Last, &*ProtoSourceName.rbegin() + 1);
3972 Proto = parseBareSourceName();
3974 if (Proto.empty())
3975 return nullptr;
3976 Node *Child = getDerived().parseQualifiedType();
3977 if (Child == nullptr)
3978 return nullptr;
3979 return make<ObjCProtoName>(Child, Proto);
3982 Node *TA = nullptr;
3983 if (look() == 'I') {
3984 TA = getDerived().parseTemplateArgs();
3985 if (TA == nullptr)
3986 return nullptr;
3989 Node *Child = getDerived().parseQualifiedType();
3990 if (Child == nullptr)
3991 return nullptr;
3992 return make<VendorExtQualType>(Child, Qual, TA);
3995 Qualifiers Quals = parseCVQualifiers();
3996 Node *Ty = getDerived().parseType();
3997 if (Ty == nullptr)
3998 return nullptr;
3999 if (Quals != QualNone)
4000 Ty = make<QualType>(Ty, Quals);
4001 return Ty;
4004 // <type> ::= <builtin-type>
4005 // ::= <qualified-type>
4006 // ::= <function-type>
4007 // ::= <class-enum-type>
4008 // ::= <array-type>
4009 // ::= <pointer-to-member-type>
4010 // ::= <template-param>
4011 // ::= <template-template-param> <template-args>
4012 // ::= <decltype>
4013 // ::= P <type> # pointer
4014 // ::= R <type> # l-value reference
4015 // ::= O <type> # r-value reference (C++11)
4016 // ::= C <type> # complex pair (C99)
4017 // ::= G <type> # imaginary (C99)
4018 // ::= <substitution> # See Compression below
4019 // extension ::= U <objc-name> <objc-type> # objc-type<identifier>
4020 // extension ::= <vector-type> # <vector-type> starts with Dv
4022 // <objc-name> ::= <k0 number> objcproto <k1 number> <identifier> # k0 = 9 + <number of digits in k1> + k1
4023 // <objc-type> ::= <source-name> # PU<11+>objcproto 11objc_object<source-name> 11objc_object -> id<source-name>
4024 template <typename Derived, typename Alloc>
4025 Node *AbstractManglingParser<Derived, Alloc>::parseType() {
4026 Node *Result = nullptr;
4028 switch (look()) {
4029 // ::= <qualified-type>
4030 case 'r':
4031 case 'V':
4032 case 'K': {
4033 unsigned AfterQuals = 0;
4034 if (look(AfterQuals) == 'r') ++AfterQuals;
4035 if (look(AfterQuals) == 'V') ++AfterQuals;
4036 if (look(AfterQuals) == 'K') ++AfterQuals;
4038 if (look(AfterQuals) == 'F' ||
4039 (look(AfterQuals) == 'D' &&
4040 (look(AfterQuals + 1) == 'o' || look(AfterQuals + 1) == 'O' ||
4041 look(AfterQuals + 1) == 'w' || look(AfterQuals + 1) == 'x'))) {
4042 Result = getDerived().parseFunctionType();
4043 break;
4045 DEMANGLE_FALLTHROUGH;
4047 case 'U': {
4048 Result = getDerived().parseQualifiedType();
4049 break;
4051 // <builtin-type> ::= v # void
4052 case 'v':
4053 ++First;
4054 return make<NameType>("void");
4055 // ::= w # wchar_t
4056 case 'w':
4057 ++First;
4058 return make<NameType>("wchar_t");
4059 // ::= b # bool
4060 case 'b':
4061 ++First;
4062 return make<NameType>("bool");
4063 // ::= c # char
4064 case 'c':
4065 ++First;
4066 return make<NameType>("char");
4067 // ::= a # signed char
4068 case 'a':
4069 ++First;
4070 return make<NameType>("signed char");
4071 // ::= h # unsigned char
4072 case 'h':
4073 ++First;
4074 return make<NameType>("unsigned char");
4075 // ::= s # short
4076 case 's':
4077 ++First;
4078 return make<NameType>("short");
4079 // ::= t # unsigned short
4080 case 't':
4081 ++First;
4082 return make<NameType>("unsigned short");
4083 // ::= i # int
4084 case 'i':
4085 ++First;
4086 return make<NameType>("int");
4087 // ::= j # unsigned int
4088 case 'j':
4089 ++First;
4090 return make<NameType>("unsigned int");
4091 // ::= l # long
4092 case 'l':
4093 ++First;
4094 return make<NameType>("long");
4095 // ::= m # unsigned long
4096 case 'm':
4097 ++First;
4098 return make<NameType>("unsigned long");
4099 // ::= x # long long, __int64
4100 case 'x':
4101 ++First;
4102 return make<NameType>("long long");
4103 // ::= y # unsigned long long, __int64
4104 case 'y':
4105 ++First;
4106 return make<NameType>("unsigned long long");
4107 // ::= n # __int128
4108 case 'n':
4109 ++First;
4110 return make<NameType>("__int128");
4111 // ::= o # unsigned __int128
4112 case 'o':
4113 ++First;
4114 return make<NameType>("unsigned __int128");
4115 // ::= f # float
4116 case 'f':
4117 ++First;
4118 return make<NameType>("float");
4119 // ::= d # double
4120 case 'd':
4121 ++First;
4122 return make<NameType>("double");
4123 // ::= e # long double, __float80
4124 case 'e':
4125 ++First;
4126 return make<NameType>("long double");
4127 // ::= g # __float128
4128 case 'g':
4129 ++First;
4130 return make<NameType>("__float128");
4131 // ::= z # ellipsis
4132 case 'z':
4133 ++First;
4134 return make<NameType>("...");
4136 // <builtin-type> ::= u <source-name> # vendor extended type
4137 case 'u': {
4138 ++First;
4139 std::string_view Res = parseBareSourceName();
4140 if (Res.empty())
4141 return nullptr;
4142 // Typically, <builtin-type>s are not considered substitution candidates,
4143 // but the exception to that exception is vendor extended types (Itanium C++
4144 // ABI 5.9.1).
4145 if (consumeIf('I')) {
4146 Node *BaseType = parseType();
4147 if (BaseType == nullptr)
4148 return nullptr;
4149 if (!consumeIf('E'))
4150 return nullptr;
4151 Result = make<TransformedType>(Res, BaseType);
4152 } else
4153 Result = make<NameType>(Res);
4154 break;
4156 case 'D':
4157 switch (look(1)) {
4158 // ::= Dd # IEEE 754r decimal floating point (64 bits)
4159 case 'd':
4160 First += 2;
4161 return make<NameType>("decimal64");
4162 // ::= De # IEEE 754r decimal floating point (128 bits)
4163 case 'e':
4164 First += 2;
4165 return make<NameType>("decimal128");
4166 // ::= Df # IEEE 754r decimal floating point (32 bits)
4167 case 'f':
4168 First += 2;
4169 return make<NameType>("decimal32");
4170 // ::= Dh # IEEE 754r half-precision floating point (16 bits)
4171 case 'h':
4172 First += 2;
4173 return make<NameType>("half");
4174 // ::= DF <number> _ # ISO/IEC TS 18661 binary floating point (N bits)
4175 case 'F': {
4176 First += 2;
4177 Node *DimensionNumber = make<NameType>(parseNumber());
4178 if (!DimensionNumber)
4179 return nullptr;
4180 if (!consumeIf('_'))
4181 return nullptr;
4182 return make<BinaryFPType>(DimensionNumber);
4184 // ::= DB <number> _ # C23 signed _BitInt(N)
4185 // ::= DB <instantiation-dependent expression> _ # C23 signed _BitInt(N)
4186 // ::= DU <number> _ # C23 unsigned _BitInt(N)
4187 // ::= DU <instantiation-dependent expression> _ # C23 unsigned _BitInt(N)
4188 case 'B':
4189 case 'U': {
4190 bool Signed = look(1) == 'B';
4191 First += 2;
4192 Node *Size = std::isdigit(look()) ? make<NameType>(parseNumber())
4193 : getDerived().parseExpr();
4194 if (!Size)
4195 return nullptr;
4196 if (!consumeIf('_'))
4197 return nullptr;
4198 return make<BitIntType>(Size, Signed);
4200 // ::= Di # char32_t
4201 case 'i':
4202 First += 2;
4203 return make<NameType>("char32_t");
4204 // ::= Ds # char16_t
4205 case 's':
4206 First += 2;
4207 return make<NameType>("char16_t");
4208 // ::= Du # char8_t (C++2a, not yet in the Itanium spec)
4209 case 'u':
4210 First += 2;
4211 return make<NameType>("char8_t");
4212 // ::= Da # auto (in dependent new-expressions)
4213 case 'a':
4214 First += 2;
4215 return make<NameType>("auto");
4216 // ::= Dc # decltype(auto)
4217 case 'c':
4218 First += 2;
4219 return make<NameType>("decltype(auto)");
4220 // ::= Dk <type-constraint> # constrained auto
4221 // ::= DK <type-constraint> # constrained decltype(auto)
4222 case 'k':
4223 case 'K': {
4224 std::string_view Kind = look(1) == 'k' ? " auto" : " decltype(auto)";
4225 First += 2;
4226 Node *Constraint = getDerived().parseName();
4227 if (!Constraint)
4228 return nullptr;
4229 return make<PostfixQualifiedType>(Constraint, Kind);
4231 // ::= Dn # std::nullptr_t (i.e., decltype(nullptr))
4232 case 'n':
4233 First += 2;
4234 return make<NameType>("std::nullptr_t");
4236 // ::= <decltype>
4237 case 't':
4238 case 'T': {
4239 Result = getDerived().parseDecltype();
4240 break;
4242 // extension ::= <vector-type> # <vector-type> starts with Dv
4243 case 'v': {
4244 Result = getDerived().parseVectorType();
4245 break;
4247 // ::= Dp <type> # pack expansion (C++0x)
4248 case 'p': {
4249 First += 2;
4250 Node *Child = getDerived().parseType();
4251 if (!Child)
4252 return nullptr;
4253 Result = make<ParameterPackExpansion>(Child);
4254 break;
4256 // Exception specifier on a function type.
4257 case 'o':
4258 case 'O':
4259 case 'w':
4260 // Transaction safe function type.
4261 case 'x':
4262 Result = getDerived().parseFunctionType();
4263 break;
4265 break;
4266 // ::= <function-type>
4267 case 'F': {
4268 Result = getDerived().parseFunctionType();
4269 break;
4271 // ::= <array-type>
4272 case 'A': {
4273 Result = getDerived().parseArrayType();
4274 break;
4276 // ::= <pointer-to-member-type>
4277 case 'M': {
4278 Result = getDerived().parsePointerToMemberType();
4279 break;
4281 // ::= <template-param>
4282 case 'T': {
4283 // This could be an elaborate type specifier on a <class-enum-type>.
4284 if (look(1) == 's' || look(1) == 'u' || look(1) == 'e') {
4285 Result = getDerived().parseClassEnumType();
4286 break;
4289 Result = getDerived().parseTemplateParam();
4290 if (Result == nullptr)
4291 return nullptr;
4293 // Result could be either of:
4294 // <type> ::= <template-param>
4295 // <type> ::= <template-template-param> <template-args>
4297 // <template-template-param> ::= <template-param>
4298 // ::= <substitution>
4300 // If this is followed by some <template-args>, and we're permitted to
4301 // parse them, take the second production.
4303 if (TryToParseTemplateArgs && look() == 'I') {
4304 Node *TA = getDerived().parseTemplateArgs();
4305 if (TA == nullptr)
4306 return nullptr;
4307 Result = make<NameWithTemplateArgs>(Result, TA);
4309 break;
4311 // ::= P <type> # pointer
4312 case 'P': {
4313 ++First;
4314 Node *Ptr = getDerived().parseType();
4315 if (Ptr == nullptr)
4316 return nullptr;
4317 Result = make<PointerType>(Ptr);
4318 break;
4320 // ::= R <type> # l-value reference
4321 case 'R': {
4322 ++First;
4323 Node *Ref = getDerived().parseType();
4324 if (Ref == nullptr)
4325 return nullptr;
4326 Result = make<ReferenceType>(Ref, ReferenceKind::LValue);
4327 break;
4329 // ::= O <type> # r-value reference (C++11)
4330 case 'O': {
4331 ++First;
4332 Node *Ref = getDerived().parseType();
4333 if (Ref == nullptr)
4334 return nullptr;
4335 Result = make<ReferenceType>(Ref, ReferenceKind::RValue);
4336 break;
4338 // ::= C <type> # complex pair (C99)
4339 case 'C': {
4340 ++First;
4341 Node *P = getDerived().parseType();
4342 if (P == nullptr)
4343 return nullptr;
4344 Result = make<PostfixQualifiedType>(P, " complex");
4345 break;
4347 // ::= G <type> # imaginary (C99)
4348 case 'G': {
4349 ++First;
4350 Node *P = getDerived().parseType();
4351 if (P == nullptr)
4352 return P;
4353 Result = make<PostfixQualifiedType>(P, " imaginary");
4354 break;
4356 // ::= <substitution> # See Compression below
4357 case 'S': {
4358 if (look(1) != 't') {
4359 bool IsSubst = false;
4360 Result = getDerived().parseUnscopedName(nullptr, &IsSubst);
4361 if (!Result)
4362 return nullptr;
4364 // Sub could be either of:
4365 // <type> ::= <substitution>
4366 // <type> ::= <template-template-param> <template-args>
4368 // <template-template-param> ::= <template-param>
4369 // ::= <substitution>
4371 // If this is followed by some <template-args>, and we're permitted to
4372 // parse them, take the second production.
4374 if (look() == 'I' && (!IsSubst || TryToParseTemplateArgs)) {
4375 if (!IsSubst)
4376 Subs.push_back(Result);
4377 Node *TA = getDerived().parseTemplateArgs();
4378 if (TA == nullptr)
4379 return nullptr;
4380 Result = make<NameWithTemplateArgs>(Result, TA);
4381 } else if (IsSubst) {
4382 // If all we parsed was a substitution, don't re-insert into the
4383 // substitution table.
4384 return Result;
4386 break;
4388 DEMANGLE_FALLTHROUGH;
4390 // ::= <class-enum-type>
4391 default: {
4392 Result = getDerived().parseClassEnumType();
4393 break;
4397 // If we parsed a type, insert it into the substitution table. Note that all
4398 // <builtin-type>s and <substitution>s have already bailed out, because they
4399 // don't get substitutions.
4400 if (Result != nullptr)
4401 Subs.push_back(Result);
4402 return Result;
4405 template <typename Derived, typename Alloc>
4406 Node *
4407 AbstractManglingParser<Derived, Alloc>::parsePrefixExpr(std::string_view Kind,
4408 Node::Prec Prec) {
4409 Node *E = getDerived().parseExpr();
4410 if (E == nullptr)
4411 return nullptr;
4412 return make<PrefixExpr>(Kind, E, Prec);
4415 template <typename Derived, typename Alloc>
4416 Node *
4417 AbstractManglingParser<Derived, Alloc>::parseBinaryExpr(std::string_view Kind,
4418 Node::Prec Prec) {
4419 Node *LHS = getDerived().parseExpr();
4420 if (LHS == nullptr)
4421 return nullptr;
4422 Node *RHS = getDerived().parseExpr();
4423 if (RHS == nullptr)
4424 return nullptr;
4425 return make<BinaryExpr>(LHS, Kind, RHS, Prec);
4428 template <typename Derived, typename Alloc>
4429 Node *AbstractManglingParser<Derived, Alloc>::parseIntegerLiteral(
4430 std::string_view Lit) {
4431 std::string_view Tmp = parseNumber(true);
4432 if (!Tmp.empty() && consumeIf('E'))
4433 return make<IntegerLiteral>(Lit, Tmp);
4434 return nullptr;
4437 // <CV-Qualifiers> ::= [r] [V] [K]
4438 template <typename Alloc, typename Derived>
4439 Qualifiers AbstractManglingParser<Alloc, Derived>::parseCVQualifiers() {
4440 Qualifiers CVR = QualNone;
4441 if (consumeIf('r'))
4442 CVR |= QualRestrict;
4443 if (consumeIf('V'))
4444 CVR |= QualVolatile;
4445 if (consumeIf('K'))
4446 CVR |= QualConst;
4447 return CVR;
4450 // <function-param> ::= fp <top-level CV-Qualifiers> _ # L == 0, first parameter
4451 // ::= fp <top-level CV-Qualifiers> <parameter-2 non-negative number> _ # L == 0, second and later parameters
4452 // ::= fL <L-1 non-negative number> p <top-level CV-Qualifiers> _ # L > 0, first parameter
4453 // ::= fL <L-1 non-negative number> p <top-level CV-Qualifiers> <parameter-2 non-negative number> _ # L > 0, second and later parameters
4454 // ::= fpT # 'this' expression (not part of standard?)
4455 template <typename Derived, typename Alloc>
4456 Node *AbstractManglingParser<Derived, Alloc>::parseFunctionParam() {
4457 if (consumeIf("fpT"))
4458 return make<NameType>("this");
4459 if (consumeIf("fp")) {
4460 parseCVQualifiers();
4461 std::string_view Num = parseNumber();
4462 if (!consumeIf('_'))
4463 return nullptr;
4464 return make<FunctionParam>(Num);
4466 if (consumeIf("fL")) {
4467 if (parseNumber().empty())
4468 return nullptr;
4469 if (!consumeIf('p'))
4470 return nullptr;
4471 parseCVQualifiers();
4472 std::string_view Num = parseNumber();
4473 if (!consumeIf('_'))
4474 return nullptr;
4475 return make<FunctionParam>(Num);
4477 return nullptr;
4480 // cv <type> <expression> # conversion with one argument
4481 // cv <type> _ <expression>* E # conversion with a different number of arguments
4482 template <typename Derived, typename Alloc>
4483 Node *AbstractManglingParser<Derived, Alloc>::parseConversionExpr() {
4484 if (!consumeIf("cv"))
4485 return nullptr;
4486 Node *Ty;
4488 ScopedOverride<bool> SaveTemp(TryToParseTemplateArgs, false);
4489 Ty = getDerived().parseType();
4492 if (Ty == nullptr)
4493 return nullptr;
4495 if (consumeIf('_')) {
4496 size_t ExprsBegin = Names.size();
4497 while (!consumeIf('E')) {
4498 Node *E = getDerived().parseExpr();
4499 if (E == nullptr)
4500 return E;
4501 Names.push_back(E);
4503 NodeArray Exprs = popTrailingNodeArray(ExprsBegin);
4504 return make<ConversionExpr>(Ty, Exprs);
4507 Node *E[1] = {getDerived().parseExpr()};
4508 if (E[0] == nullptr)
4509 return nullptr;
4510 return make<ConversionExpr>(Ty, makeNodeArray(E, E + 1));
4513 // <expr-primary> ::= L <type> <value number> E # integer literal
4514 // ::= L <type> <value float> E # floating literal
4515 // ::= L <string type> E # string literal
4516 // ::= L <nullptr type> E # nullptr literal (i.e., "LDnE")
4517 // ::= L <lambda type> E # lambda expression
4518 // FIXME: ::= L <type> <real-part float> _ <imag-part float> E # complex floating point literal (C 2000)
4519 // ::= L <mangled-name> E # external name
4520 template <typename Derived, typename Alloc>
4521 Node *AbstractManglingParser<Derived, Alloc>::parseExprPrimary() {
4522 if (!consumeIf('L'))
4523 return nullptr;
4524 switch (look()) {
4525 case 'w':
4526 ++First;
4527 return getDerived().parseIntegerLiteral("wchar_t");
4528 case 'b':
4529 if (consumeIf("b0E"))
4530 return make<BoolExpr>(0);
4531 if (consumeIf("b1E"))
4532 return make<BoolExpr>(1);
4533 return nullptr;
4534 case 'c':
4535 ++First;
4536 return getDerived().parseIntegerLiteral("char");
4537 case 'a':
4538 ++First;
4539 return getDerived().parseIntegerLiteral("signed char");
4540 case 'h':
4541 ++First;
4542 return getDerived().parseIntegerLiteral("unsigned char");
4543 case 's':
4544 ++First;
4545 return getDerived().parseIntegerLiteral("short");
4546 case 't':
4547 ++First;
4548 return getDerived().parseIntegerLiteral("unsigned short");
4549 case 'i':
4550 ++First;
4551 return getDerived().parseIntegerLiteral("");
4552 case 'j':
4553 ++First;
4554 return getDerived().parseIntegerLiteral("u");
4555 case 'l':
4556 ++First;
4557 return getDerived().parseIntegerLiteral("l");
4558 case 'm':
4559 ++First;
4560 return getDerived().parseIntegerLiteral("ul");
4561 case 'x':
4562 ++First;
4563 return getDerived().parseIntegerLiteral("ll");
4564 case 'y':
4565 ++First;
4566 return getDerived().parseIntegerLiteral("ull");
4567 case 'n':
4568 ++First;
4569 return getDerived().parseIntegerLiteral("__int128");
4570 case 'o':
4571 ++First;
4572 return getDerived().parseIntegerLiteral("unsigned __int128");
4573 case 'f':
4574 ++First;
4575 return getDerived().template parseFloatingLiteral<float>();
4576 case 'd':
4577 ++First;
4578 return getDerived().template parseFloatingLiteral<double>();
4579 case 'e':
4580 ++First;
4581 #if defined(__powerpc__) || defined(__s390__)
4582 // Handle cases where long doubles encoded with e have the same size
4583 // and representation as doubles.
4584 return getDerived().template parseFloatingLiteral<double>();
4585 #else
4586 return getDerived().template parseFloatingLiteral<long double>();
4587 #endif
4588 case '_':
4589 if (consumeIf("_Z")) {
4590 Node *R = getDerived().parseEncoding();
4591 if (R != nullptr && consumeIf('E'))
4592 return R;
4594 return nullptr;
4595 case 'A': {
4596 Node *T = getDerived().parseType();
4597 if (T == nullptr)
4598 return nullptr;
4599 // FIXME: We need to include the string contents in the mangling.
4600 if (consumeIf('E'))
4601 return make<StringLiteral>(T);
4602 return nullptr;
4604 case 'D':
4605 if (consumeIf("Dn") && (consumeIf('0'), consumeIf('E')))
4606 return make<NameType>("nullptr");
4607 return nullptr;
4608 case 'T':
4609 // Invalid mangled name per
4610 // http://sourcerytools.com/pipermail/cxx-abi-dev/2011-August/002422.html
4611 return nullptr;
4612 case 'U': {
4613 // FIXME: Should we support LUb... for block literals?
4614 if (look(1) != 'l')
4615 return nullptr;
4616 Node *T = parseUnnamedTypeName(nullptr);
4617 if (!T || !consumeIf('E'))
4618 return nullptr;
4619 return make<LambdaExpr>(T);
4621 default: {
4622 // might be named type
4623 Node *T = getDerived().parseType();
4624 if (T == nullptr)
4625 return nullptr;
4626 std::string_view N = parseNumber(/*AllowNegative=*/true);
4627 if (N.empty())
4628 return nullptr;
4629 if (!consumeIf('E'))
4630 return nullptr;
4631 return make<EnumLiteral>(T, N);
4636 // <braced-expression> ::= <expression>
4637 // ::= di <field source-name> <braced-expression> # .name = expr
4638 // ::= dx <index expression> <braced-expression> # [expr] = expr
4639 // ::= dX <range begin expression> <range end expression> <braced-expression>
4640 template <typename Derived, typename Alloc>
4641 Node *AbstractManglingParser<Derived, Alloc>::parseBracedExpr() {
4642 if (look() == 'd') {
4643 switch (look(1)) {
4644 case 'i': {
4645 First += 2;
4646 Node *Field = getDerived().parseSourceName(/*NameState=*/nullptr);
4647 if (Field == nullptr)
4648 return nullptr;
4649 Node *Init = getDerived().parseBracedExpr();
4650 if (Init == nullptr)
4651 return nullptr;
4652 return make<BracedExpr>(Field, Init, /*isArray=*/false);
4654 case 'x': {
4655 First += 2;
4656 Node *Index = getDerived().parseExpr();
4657 if (Index == nullptr)
4658 return nullptr;
4659 Node *Init = getDerived().parseBracedExpr();
4660 if (Init == nullptr)
4661 return nullptr;
4662 return make<BracedExpr>(Index, Init, /*isArray=*/true);
4664 case 'X': {
4665 First += 2;
4666 Node *RangeBegin = getDerived().parseExpr();
4667 if (RangeBegin == nullptr)
4668 return nullptr;
4669 Node *RangeEnd = getDerived().parseExpr();
4670 if (RangeEnd == nullptr)
4671 return nullptr;
4672 Node *Init = getDerived().parseBracedExpr();
4673 if (Init == nullptr)
4674 return nullptr;
4675 return make<BracedRangeExpr>(RangeBegin, RangeEnd, Init);
4679 return getDerived().parseExpr();
4682 // (not yet in the spec)
4683 // <fold-expr> ::= fL <binary-operator-name> <expression> <expression>
4684 // ::= fR <binary-operator-name> <expression> <expression>
4685 // ::= fl <binary-operator-name> <expression>
4686 // ::= fr <binary-operator-name> <expression>
4687 template <typename Derived, typename Alloc>
4688 Node *AbstractManglingParser<Derived, Alloc>::parseFoldExpr() {
4689 if (!consumeIf('f'))
4690 return nullptr;
4692 bool IsLeftFold = false, HasInitializer = false;
4693 switch (look()) {
4694 default:
4695 return nullptr;
4696 case 'L':
4697 IsLeftFold = true;
4698 HasInitializer = true;
4699 break;
4700 case 'R':
4701 HasInitializer = true;
4702 break;
4703 case 'l':
4704 IsLeftFold = true;
4705 break;
4706 case 'r':
4707 break;
4709 ++First;
4711 const auto *Op = parseOperatorEncoding();
4712 if (!Op)
4713 return nullptr;
4714 if (!(Op->getKind() == OperatorInfo::Binary
4715 || (Op->getKind() == OperatorInfo::Member
4716 && Op->getName().back() == '*')))
4717 return nullptr;
4719 Node *Pack = getDerived().parseExpr();
4720 if (Pack == nullptr)
4721 return nullptr;
4723 Node *Init = nullptr;
4724 if (HasInitializer) {
4725 Init = getDerived().parseExpr();
4726 if (Init == nullptr)
4727 return nullptr;
4730 if (IsLeftFold && Init)
4731 std::swap(Pack, Init);
4733 return make<FoldExpr>(IsLeftFold, Op->getSymbol(), Pack, Init);
4736 // <expression> ::= mc <parameter type> <expr> [<offset number>] E
4738 // Not yet in the spec: https://github.com/itanium-cxx-abi/cxx-abi/issues/47
4739 template <typename Derived, typename Alloc>
4740 Node *
4741 AbstractManglingParser<Derived, Alloc>::parsePointerToMemberConversionExpr(
4742 Node::Prec Prec) {
4743 Node *Ty = getDerived().parseType();
4744 if (!Ty)
4745 return nullptr;
4746 Node *Expr = getDerived().parseExpr();
4747 if (!Expr)
4748 return nullptr;
4749 std::string_view Offset = getDerived().parseNumber(true);
4750 if (!consumeIf('E'))
4751 return nullptr;
4752 return make<PointerToMemberConversionExpr>(Ty, Expr, Offset, Prec);
4755 // <expression> ::= so <referent type> <expr> [<offset number>] <union-selector>* [p] E
4756 // <union-selector> ::= _ [<number>]
4758 // Not yet in the spec: https://github.com/itanium-cxx-abi/cxx-abi/issues/47
4759 template <typename Derived, typename Alloc>
4760 Node *AbstractManglingParser<Derived, Alloc>::parseSubobjectExpr() {
4761 Node *Ty = getDerived().parseType();
4762 if (!Ty)
4763 return nullptr;
4764 Node *Expr = getDerived().parseExpr();
4765 if (!Expr)
4766 return nullptr;
4767 std::string_view Offset = getDerived().parseNumber(true);
4768 size_t SelectorsBegin = Names.size();
4769 while (consumeIf('_')) {
4770 Node *Selector = make<NameType>(parseNumber());
4771 if (!Selector)
4772 return nullptr;
4773 Names.push_back(Selector);
4775 bool OnePastTheEnd = consumeIf('p');
4776 if (!consumeIf('E'))
4777 return nullptr;
4778 return make<SubobjectExpr>(
4779 Ty, Expr, Offset, popTrailingNodeArray(SelectorsBegin), OnePastTheEnd);
4782 template <typename Derived, typename Alloc>
4783 Node *AbstractManglingParser<Derived, Alloc>::parseConstraintExpr() {
4784 // Within this expression, all enclosing template parameter lists are in
4785 // scope.
4786 ScopedOverride<bool> SaveInConstraintExpr(InConstraintExpr, true);
4787 return getDerived().parseExpr();
4790 template <typename Derived, typename Alloc>
4791 Node *AbstractManglingParser<Derived, Alloc>::parseRequiresExpr() {
4792 NodeArray Params;
4793 if (consumeIf("rQ")) {
4794 // <expression> ::= rQ <bare-function-type> _ <requirement>+ E
4795 size_t ParamsBegin = Names.size();
4796 while (!consumeIf('_')) {
4797 Node *Type = getDerived().parseType();
4798 if (Type == nullptr)
4799 return nullptr;
4800 Names.push_back(Type);
4802 Params = popTrailingNodeArray(ParamsBegin);
4803 } else if (!consumeIf("rq")) {
4804 // <expression> ::= rq <requirement>+ E
4805 return nullptr;
4808 size_t ReqsBegin = Names.size();
4809 do {
4810 Node *Constraint = nullptr;
4811 if (consumeIf('X')) {
4812 // <requirement> ::= X <expression> [N] [R <type-constraint>]
4813 Node *Expr = getDerived().parseExpr();
4814 if (Expr == nullptr)
4815 return nullptr;
4816 bool Noexcept = consumeIf('N');
4817 Node *TypeReq = nullptr;
4818 if (consumeIf('R')) {
4819 TypeReq = getDerived().parseName();
4820 if (TypeReq == nullptr)
4821 return nullptr;
4823 Constraint = make<ExprRequirement>(Expr, Noexcept, TypeReq);
4824 } else if (consumeIf('T')) {
4825 // <requirement> ::= T <type>
4826 Node *Type = getDerived().parseType();
4827 if (Type == nullptr)
4828 return nullptr;
4829 Constraint = make<TypeRequirement>(Type);
4830 } else if (consumeIf('Q')) {
4831 // <requirement> ::= Q <constraint-expression>
4833 // FIXME: We use <expression> instead of <constraint-expression>. Either
4834 // the requires expression is already inside a constraint expression, in
4835 // which case it makes no difference, or we're in a requires-expression
4836 // that might be partially-substituted, where the language behavior is
4837 // not yet settled and clang mangles after substitution.
4838 Node *NestedReq = getDerived().parseExpr();
4839 if (NestedReq == nullptr)
4840 return nullptr;
4841 Constraint = make<NestedRequirement>(NestedReq);
4843 if (Constraint == nullptr)
4844 return nullptr;
4845 Names.push_back(Constraint);
4846 } while (!consumeIf('E'));
4848 return make<RequiresExpr>(Params, popTrailingNodeArray(ReqsBegin));
4851 // <expression> ::= <unary operator-name> <expression>
4852 // ::= <binary operator-name> <expression> <expression>
4853 // ::= <ternary operator-name> <expression> <expression> <expression>
4854 // ::= cl <expression>+ E # call
4855 // ::= cv <type> <expression> # conversion with one argument
4856 // ::= cv <type> _ <expression>* E # conversion with a different number of arguments
4857 // ::= [gs] nw <expression>* _ <type> E # new (expr-list) type
4858 // ::= [gs] nw <expression>* _ <type> <initializer> # new (expr-list) type (init)
4859 // ::= [gs] na <expression>* _ <type> E # new[] (expr-list) type
4860 // ::= [gs] na <expression>* _ <type> <initializer> # new[] (expr-list) type (init)
4861 // ::= [gs] dl <expression> # delete expression
4862 // ::= [gs] da <expression> # delete[] expression
4863 // ::= pp_ <expression> # prefix ++
4864 // ::= mm_ <expression> # prefix --
4865 // ::= ti <type> # typeid (type)
4866 // ::= te <expression> # typeid (expression)
4867 // ::= dc <type> <expression> # dynamic_cast<type> (expression)
4868 // ::= sc <type> <expression> # static_cast<type> (expression)
4869 // ::= cc <type> <expression> # const_cast<type> (expression)
4870 // ::= rc <type> <expression> # reinterpret_cast<type> (expression)
4871 // ::= st <type> # sizeof (a type)
4872 // ::= sz <expression> # sizeof (an expression)
4873 // ::= at <type> # alignof (a type)
4874 // ::= az <expression> # alignof (an expression)
4875 // ::= nx <expression> # noexcept (expression)
4876 // ::= <template-param>
4877 // ::= <function-param>
4878 // ::= dt <expression> <unresolved-name> # expr.name
4879 // ::= pt <expression> <unresolved-name> # expr->name
4880 // ::= ds <expression> <expression> # expr.*expr
4881 // ::= sZ <template-param> # size of a parameter pack
4882 // ::= sZ <function-param> # size of a function parameter pack
4883 // ::= sP <template-arg>* E # sizeof...(T), size of a captured template parameter pack from an alias template
4884 // ::= sp <expression> # pack expansion
4885 // ::= tw <expression> # throw expression
4886 // ::= tr # throw with no operand (rethrow)
4887 // ::= <unresolved-name> # f(p), N::f(p), ::f(p),
4888 // # freestanding dependent name (e.g., T::x),
4889 // # objectless nonstatic member reference
4890 // ::= fL <binary-operator-name> <expression> <expression>
4891 // ::= fR <binary-operator-name> <expression> <expression>
4892 // ::= fl <binary-operator-name> <expression>
4893 // ::= fr <binary-operator-name> <expression>
4894 // ::= <expr-primary>
4895 template <typename Derived, typename Alloc>
4896 Node *AbstractManglingParser<Derived, Alloc>::parseExpr() {
4897 bool Global = consumeIf("gs");
4899 const auto *Op = parseOperatorEncoding();
4900 if (Op) {
4901 auto Sym = Op->getSymbol();
4902 switch (Op->getKind()) {
4903 case OperatorInfo::Binary:
4904 // Binary operator: lhs @ rhs
4905 return getDerived().parseBinaryExpr(Sym, Op->getPrecedence());
4906 case OperatorInfo::Prefix:
4907 // Prefix unary operator: @ expr
4908 return getDerived().parsePrefixExpr(Sym, Op->getPrecedence());
4909 case OperatorInfo::Postfix: {
4910 // Postfix unary operator: expr @
4911 if (consumeIf('_'))
4912 return getDerived().parsePrefixExpr(Sym, Op->getPrecedence());
4913 Node *Ex = getDerived().parseExpr();
4914 if (Ex == nullptr)
4915 return nullptr;
4916 return make<PostfixExpr>(Ex, Sym, Op->getPrecedence());
4918 case OperatorInfo::Array: {
4919 // Array Index: lhs [ rhs ]
4920 Node *Base = getDerived().parseExpr();
4921 if (Base == nullptr)
4922 return nullptr;
4923 Node *Index = getDerived().parseExpr();
4924 if (Index == nullptr)
4925 return nullptr;
4926 return make<ArraySubscriptExpr>(Base, Index, Op->getPrecedence());
4928 case OperatorInfo::Member: {
4929 // Member access lhs @ rhs
4930 Node *LHS = getDerived().parseExpr();
4931 if (LHS == nullptr)
4932 return nullptr;
4933 Node *RHS = getDerived().parseExpr();
4934 if (RHS == nullptr)
4935 return nullptr;
4936 return make<MemberExpr>(LHS, Sym, RHS, Op->getPrecedence());
4938 case OperatorInfo::New: {
4939 // New
4940 // # new (expr-list) type [(init)]
4941 // [gs] nw <expression>* _ <type> [pi <expression>*] E
4942 // # new[] (expr-list) type [(init)]
4943 // [gs] na <expression>* _ <type> [pi <expression>*] E
4944 size_t Exprs = Names.size();
4945 while (!consumeIf('_')) {
4946 Node *Ex = getDerived().parseExpr();
4947 if (Ex == nullptr)
4948 return nullptr;
4949 Names.push_back(Ex);
4951 NodeArray ExprList = popTrailingNodeArray(Exprs);
4952 Node *Ty = getDerived().parseType();
4953 if (Ty == nullptr)
4954 return nullptr;
4955 bool HaveInits = consumeIf("pi");
4956 size_t InitsBegin = Names.size();
4957 while (!consumeIf('E')) {
4958 if (!HaveInits)
4959 return nullptr;
4960 Node *Init = getDerived().parseExpr();
4961 if (Init == nullptr)
4962 return Init;
4963 Names.push_back(Init);
4965 NodeArray Inits = popTrailingNodeArray(InitsBegin);
4966 return make<NewExpr>(ExprList, Ty, Inits, Global,
4967 /*IsArray=*/Op->getFlag(), Op->getPrecedence());
4969 case OperatorInfo::Del: {
4970 // Delete
4971 Node *Ex = getDerived().parseExpr();
4972 if (Ex == nullptr)
4973 return nullptr;
4974 return make<DeleteExpr>(Ex, Global, /*IsArray=*/Op->getFlag(),
4975 Op->getPrecedence());
4977 case OperatorInfo::Call: {
4978 // Function Call
4979 Node *Callee = getDerived().parseExpr();
4980 if (Callee == nullptr)
4981 return nullptr;
4982 size_t ExprsBegin = Names.size();
4983 while (!consumeIf('E')) {
4984 Node *E = getDerived().parseExpr();
4985 if (E == nullptr)
4986 return nullptr;
4987 Names.push_back(E);
4989 return make<CallExpr>(Callee, popTrailingNodeArray(ExprsBegin),
4990 Op->getPrecedence());
4992 case OperatorInfo::CCast: {
4993 // C Cast: (type)expr
4994 Node *Ty;
4996 ScopedOverride<bool> SaveTemp(TryToParseTemplateArgs, false);
4997 Ty = getDerived().parseType();
4999 if (Ty == nullptr)
5000 return nullptr;
5002 size_t ExprsBegin = Names.size();
5003 bool IsMany = consumeIf('_');
5004 while (!consumeIf('E')) {
5005 Node *E = getDerived().parseExpr();
5006 if (E == nullptr)
5007 return E;
5008 Names.push_back(E);
5009 if (!IsMany)
5010 break;
5012 NodeArray Exprs = popTrailingNodeArray(ExprsBegin);
5013 if (!IsMany && Exprs.size() != 1)
5014 return nullptr;
5015 return make<ConversionExpr>(Ty, Exprs, Op->getPrecedence());
5017 case OperatorInfo::Conditional: {
5018 // Conditional operator: expr ? expr : expr
5019 Node *Cond = getDerived().parseExpr();
5020 if (Cond == nullptr)
5021 return nullptr;
5022 Node *LHS = getDerived().parseExpr();
5023 if (LHS == nullptr)
5024 return nullptr;
5025 Node *RHS = getDerived().parseExpr();
5026 if (RHS == nullptr)
5027 return nullptr;
5028 return make<ConditionalExpr>(Cond, LHS, RHS, Op->getPrecedence());
5030 case OperatorInfo::NamedCast: {
5031 // Named cast operation, @<type>(expr)
5032 Node *Ty = getDerived().parseType();
5033 if (Ty == nullptr)
5034 return nullptr;
5035 Node *Ex = getDerived().parseExpr();
5036 if (Ex == nullptr)
5037 return nullptr;
5038 return make<CastExpr>(Sym, Ty, Ex, Op->getPrecedence());
5040 case OperatorInfo::OfIdOp: {
5041 // [sizeof/alignof/typeid] ( <type>|<expr> )
5042 Node *Arg =
5043 Op->getFlag() ? getDerived().parseType() : getDerived().parseExpr();
5044 if (!Arg)
5045 return nullptr;
5046 return make<EnclosingExpr>(Sym, Arg, Op->getPrecedence());
5048 case OperatorInfo::NameOnly: {
5049 // Not valid as an expression operand.
5050 return nullptr;
5053 DEMANGLE_UNREACHABLE;
5056 if (numLeft() < 2)
5057 return nullptr;
5059 if (look() == 'L')
5060 return getDerived().parseExprPrimary();
5061 if (look() == 'T')
5062 return getDerived().parseTemplateParam();
5063 if (look() == 'f') {
5064 // Disambiguate a fold expression from a <function-param>.
5065 if (look(1) == 'p' || (look(1) == 'L' && std::isdigit(look(2))))
5066 return getDerived().parseFunctionParam();
5067 return getDerived().parseFoldExpr();
5069 if (consumeIf("il")) {
5070 size_t InitsBegin = Names.size();
5071 while (!consumeIf('E')) {
5072 Node *E = getDerived().parseBracedExpr();
5073 if (E == nullptr)
5074 return nullptr;
5075 Names.push_back(E);
5077 return make<InitListExpr>(nullptr, popTrailingNodeArray(InitsBegin));
5079 if (consumeIf("mc"))
5080 return parsePointerToMemberConversionExpr(Node::Prec::Unary);
5081 if (consumeIf("nx")) {
5082 Node *Ex = getDerived().parseExpr();
5083 if (Ex == nullptr)
5084 return Ex;
5085 return make<EnclosingExpr>("noexcept ", Ex, Node::Prec::Unary);
5087 if (look() == 'r' && (look(1) == 'q' || look(1) == 'Q'))
5088 return parseRequiresExpr();
5089 if (consumeIf("so"))
5090 return parseSubobjectExpr();
5091 if (consumeIf("sp")) {
5092 Node *Child = getDerived().parseExpr();
5093 if (Child == nullptr)
5094 return nullptr;
5095 return make<ParameterPackExpansion>(Child);
5097 if (consumeIf("sZ")) {
5098 if (look() == 'T') {
5099 Node *R = getDerived().parseTemplateParam();
5100 if (R == nullptr)
5101 return nullptr;
5102 return make<SizeofParamPackExpr>(R);
5104 Node *FP = getDerived().parseFunctionParam();
5105 if (FP == nullptr)
5106 return nullptr;
5107 return make<EnclosingExpr>("sizeof... ", FP);
5109 if (consumeIf("sP")) {
5110 size_t ArgsBegin = Names.size();
5111 while (!consumeIf('E')) {
5112 Node *Arg = getDerived().parseTemplateArg();
5113 if (Arg == nullptr)
5114 return nullptr;
5115 Names.push_back(Arg);
5117 auto *Pack = make<NodeArrayNode>(popTrailingNodeArray(ArgsBegin));
5118 if (!Pack)
5119 return nullptr;
5120 return make<EnclosingExpr>("sizeof... ", Pack);
5122 if (consumeIf("tl")) {
5123 Node *Ty = getDerived().parseType();
5124 if (Ty == nullptr)
5125 return nullptr;
5126 size_t InitsBegin = Names.size();
5127 while (!consumeIf('E')) {
5128 Node *E = getDerived().parseBracedExpr();
5129 if (E == nullptr)
5130 return nullptr;
5131 Names.push_back(E);
5133 return make<InitListExpr>(Ty, popTrailingNodeArray(InitsBegin));
5135 if (consumeIf("tr"))
5136 return make<NameType>("throw");
5137 if (consumeIf("tw")) {
5138 Node *Ex = getDerived().parseExpr();
5139 if (Ex == nullptr)
5140 return nullptr;
5141 return make<ThrowExpr>(Ex);
5143 if (consumeIf('u')) {
5144 Node *Name = getDerived().parseSourceName(/*NameState=*/nullptr);
5145 if (!Name)
5146 return nullptr;
5147 // Special case legacy __uuidof mangling. The 't' and 'z' appear where the
5148 // standard encoding expects a <template-arg>, and would be otherwise be
5149 // interpreted as <type> node 'short' or 'ellipsis'. However, neither
5150 // __uuidof(short) nor __uuidof(...) can actually appear, so there is no
5151 // actual conflict here.
5152 bool IsUUID = false;
5153 Node *UUID = nullptr;
5154 if (Name->getBaseName() == "__uuidof") {
5155 if (consumeIf('t')) {
5156 UUID = getDerived().parseType();
5157 IsUUID = true;
5158 } else if (consumeIf('z')) {
5159 UUID = getDerived().parseExpr();
5160 IsUUID = true;
5163 size_t ExprsBegin = Names.size();
5164 if (IsUUID) {
5165 if (UUID == nullptr)
5166 return nullptr;
5167 Names.push_back(UUID);
5168 } else {
5169 while (!consumeIf('E')) {
5170 Node *E = getDerived().parseTemplateArg();
5171 if (E == nullptr)
5172 return E;
5173 Names.push_back(E);
5176 return make<CallExpr>(Name, popTrailingNodeArray(ExprsBegin),
5177 Node::Prec::Postfix);
5180 // Only unresolved names remain.
5181 return getDerived().parseUnresolvedName(Global);
5184 // <call-offset> ::= h <nv-offset> _
5185 // ::= v <v-offset> _
5187 // <nv-offset> ::= <offset number>
5188 // # non-virtual base override
5190 // <v-offset> ::= <offset number> _ <virtual offset number>
5191 // # virtual base override, with vcall offset
5192 template <typename Alloc, typename Derived>
5193 bool AbstractManglingParser<Alloc, Derived>::parseCallOffset() {
5194 // Just scan through the call offset, we never add this information into the
5195 // output.
5196 if (consumeIf('h'))
5197 return parseNumber(true).empty() || !consumeIf('_');
5198 if (consumeIf('v'))
5199 return parseNumber(true).empty() || !consumeIf('_') ||
5200 parseNumber(true).empty() || !consumeIf('_');
5201 return true;
5204 // <special-name> ::= TV <type> # virtual table
5205 // ::= TT <type> # VTT structure (construction vtable index)
5206 // ::= TI <type> # typeinfo structure
5207 // ::= TS <type> # typeinfo name (null-terminated byte string)
5208 // ::= Tc <call-offset> <call-offset> <base encoding>
5209 // # base is the nominal target function of thunk
5210 // # first call-offset is 'this' adjustment
5211 // # second call-offset is result adjustment
5212 // ::= T <call-offset> <base encoding>
5213 // # base is the nominal target function of thunk
5214 // # Guard variable for one-time initialization
5215 // ::= GV <object name>
5216 // # No <type>
5217 // ::= TW <object name> # Thread-local wrapper
5218 // ::= TH <object name> # Thread-local initialization
5219 // ::= GR <object name> _ # First temporary
5220 // ::= GR <object name> <seq-id> _ # Subsequent temporaries
5221 // # construction vtable for second-in-first
5222 // extension ::= TC <first type> <number> _ <second type>
5223 // extension ::= GR <object name> # reference temporary for object
5224 // extension ::= GI <module name> # module global initializer
5225 template <typename Derived, typename Alloc>
5226 Node *AbstractManglingParser<Derived, Alloc>::parseSpecialName() {
5227 switch (look()) {
5228 case 'T':
5229 switch (look(1)) {
5230 // TA <template-arg> # template parameter object
5232 // Not yet in the spec: https://github.com/itanium-cxx-abi/cxx-abi/issues/63
5233 case 'A': {
5234 First += 2;
5235 Node *Arg = getDerived().parseTemplateArg();
5236 if (Arg == nullptr)
5237 return nullptr;
5238 return make<SpecialName>("template parameter object for ", Arg);
5240 // TV <type> # virtual table
5241 case 'V': {
5242 First += 2;
5243 Node *Ty = getDerived().parseType();
5244 if (Ty == nullptr)
5245 return nullptr;
5246 return make<SpecialName>("vtable for ", Ty);
5248 // TT <type> # VTT structure (construction vtable index)
5249 case 'T': {
5250 First += 2;
5251 Node *Ty = getDerived().parseType();
5252 if (Ty == nullptr)
5253 return nullptr;
5254 return make<SpecialName>("VTT for ", Ty);
5256 // TI <type> # typeinfo structure
5257 case 'I': {
5258 First += 2;
5259 Node *Ty = getDerived().parseType();
5260 if (Ty == nullptr)
5261 return nullptr;
5262 return make<SpecialName>("typeinfo for ", Ty);
5264 // TS <type> # typeinfo name (null-terminated byte string)
5265 case 'S': {
5266 First += 2;
5267 Node *Ty = getDerived().parseType();
5268 if (Ty == nullptr)
5269 return nullptr;
5270 return make<SpecialName>("typeinfo name for ", Ty);
5272 // Tc <call-offset> <call-offset> <base encoding>
5273 case 'c': {
5274 First += 2;
5275 if (parseCallOffset() || parseCallOffset())
5276 return nullptr;
5277 Node *Encoding = getDerived().parseEncoding();
5278 if (Encoding == nullptr)
5279 return nullptr;
5280 return make<SpecialName>("covariant return thunk to ", Encoding);
5282 // extension ::= TC <first type> <number> _ <second type>
5283 // # construction vtable for second-in-first
5284 case 'C': {
5285 First += 2;
5286 Node *FirstType = getDerived().parseType();
5287 if (FirstType == nullptr)
5288 return nullptr;
5289 if (parseNumber(true).empty() || !consumeIf('_'))
5290 return nullptr;
5291 Node *SecondType = getDerived().parseType();
5292 if (SecondType == nullptr)
5293 return nullptr;
5294 return make<CtorVtableSpecialName>(SecondType, FirstType);
5296 // TW <object name> # Thread-local wrapper
5297 case 'W': {
5298 First += 2;
5299 Node *Name = getDerived().parseName();
5300 if (Name == nullptr)
5301 return nullptr;
5302 return make<SpecialName>("thread-local wrapper routine for ", Name);
5304 // TH <object name> # Thread-local initialization
5305 case 'H': {
5306 First += 2;
5307 Node *Name = getDerived().parseName();
5308 if (Name == nullptr)
5309 return nullptr;
5310 return make<SpecialName>("thread-local initialization routine for ", Name);
5312 // T <call-offset> <base encoding>
5313 default: {
5314 ++First;
5315 bool IsVirt = look() == 'v';
5316 if (parseCallOffset())
5317 return nullptr;
5318 Node *BaseEncoding = getDerived().parseEncoding();
5319 if (BaseEncoding == nullptr)
5320 return nullptr;
5321 if (IsVirt)
5322 return make<SpecialName>("virtual thunk to ", BaseEncoding);
5323 else
5324 return make<SpecialName>("non-virtual thunk to ", BaseEncoding);
5327 case 'G':
5328 switch (look(1)) {
5329 // GV <object name> # Guard variable for one-time initialization
5330 case 'V': {
5331 First += 2;
5332 Node *Name = getDerived().parseName();
5333 if (Name == nullptr)
5334 return nullptr;
5335 return make<SpecialName>("guard variable for ", Name);
5337 // GR <object name> # reference temporary for object
5338 // GR <object name> _ # First temporary
5339 // GR <object name> <seq-id> _ # Subsequent temporaries
5340 case 'R': {
5341 First += 2;
5342 Node *Name = getDerived().parseName();
5343 if (Name == nullptr)
5344 return nullptr;
5345 size_t Count;
5346 bool ParsedSeqId = !parseSeqId(&Count);
5347 if (!consumeIf('_') && ParsedSeqId)
5348 return nullptr;
5349 return make<SpecialName>("reference temporary for ", Name);
5351 // GI <module-name> v
5352 case 'I': {
5353 First += 2;
5354 ModuleName *Module = nullptr;
5355 if (getDerived().parseModuleNameOpt(Module))
5356 return nullptr;
5357 if (Module == nullptr)
5358 return nullptr;
5359 return make<SpecialName>("initializer for module ", Module);
5363 return nullptr;
5366 // <encoding> ::= <function name> <bare-function-type>
5367 // [`Q` <requires-clause expr>]
5368 // ::= <data name>
5369 // ::= <special-name>
5370 template <typename Derived, typename Alloc>
5371 Node *AbstractManglingParser<Derived, Alloc>::parseEncoding() {
5372 // The template parameters of an encoding are unrelated to those of the
5373 // enclosing context.
5374 SaveTemplateParams SaveTemplateParamsScope(this);
5376 if (look() == 'G' || look() == 'T')
5377 return getDerived().parseSpecialName();
5379 auto IsEndOfEncoding = [&] {
5380 // The set of chars that can potentially follow an <encoding> (none of which
5381 // can start a <type>). Enumerating these allows us to avoid speculative
5382 // parsing.
5383 return numLeft() == 0 || look() == 'E' || look() == '.' || look() == '_';
5386 NameState NameInfo(this);
5387 Node *Name = getDerived().parseName(&NameInfo);
5388 if (Name == nullptr)
5389 return nullptr;
5391 if (resolveForwardTemplateRefs(NameInfo))
5392 return nullptr;
5394 if (IsEndOfEncoding())
5395 return Name;
5397 Node *Attrs = nullptr;
5398 if (consumeIf("Ua9enable_ifI")) {
5399 size_t BeforeArgs = Names.size();
5400 while (!consumeIf('E')) {
5401 Node *Arg = getDerived().parseTemplateArg();
5402 if (Arg == nullptr)
5403 return nullptr;
5404 Names.push_back(Arg);
5406 Attrs = make<EnableIfAttr>(popTrailingNodeArray(BeforeArgs));
5407 if (!Attrs)
5408 return nullptr;
5411 Node *ReturnType = nullptr;
5412 if (!NameInfo.CtorDtorConversion && NameInfo.EndsWithTemplateArgs) {
5413 ReturnType = getDerived().parseType();
5414 if (ReturnType == nullptr)
5415 return nullptr;
5418 NodeArray Params;
5419 if (!consumeIf('v')) {
5420 size_t ParamsBegin = Names.size();
5421 do {
5422 Node *Ty = getDerived().parseType();
5423 if (Ty == nullptr)
5424 return nullptr;
5425 Names.push_back(Ty);
5426 } while (!IsEndOfEncoding() && look() != 'Q');
5427 Params = popTrailingNodeArray(ParamsBegin);
5430 Node *Requires = nullptr;
5431 if (consumeIf('Q')) {
5432 Requires = getDerived().parseConstraintExpr();
5433 if (!Requires)
5434 return nullptr;
5437 return make<FunctionEncoding>(ReturnType, Name, Params, Attrs, Requires,
5438 NameInfo.CVQualifiers,
5439 NameInfo.ReferenceQualifier);
5442 template <class Float>
5443 struct FloatData;
5445 template <>
5446 struct FloatData<float>
5448 static const size_t mangled_size = 8;
5449 static const size_t max_demangled_size = 24;
5450 static constexpr const char* spec = "%af";
5453 template <>
5454 struct FloatData<double>
5456 static const size_t mangled_size = 16;
5457 static const size_t max_demangled_size = 32;
5458 static constexpr const char* spec = "%a";
5461 template <>
5462 struct FloatData<long double>
5464 #if defined(__mips__) && defined(__mips_n64) || defined(__aarch64__) || \
5465 defined(__wasm__) || defined(__riscv) || defined(__loongarch__) || \
5466 defined(__ve__)
5467 static const size_t mangled_size = 32;
5468 #elif defined(__arm__) || defined(__mips__) || defined(__hexagon__)
5469 static const size_t mangled_size = 16;
5470 #else
5471 static const size_t mangled_size = 20; // May need to be adjusted to 16 or 24 on other platforms
5472 #endif
5473 // `-0x1.ffffffffffffffffffffffffffffp+16383` + 'L' + '\0' == 42 bytes.
5474 // 28 'f's * 4 bits == 112 bits, which is the number of mantissa bits.
5475 // Negatives are one character longer than positives.
5476 // `0x1.` and `p` are constant, and exponents `+16383` and `-16382` are the
5477 // same length. 1 sign bit, 112 mantissa bits, and 15 exponent bits == 128.
5478 static const size_t max_demangled_size = 42;
5479 static constexpr const char *spec = "%LaL";
5482 template <typename Alloc, typename Derived>
5483 template <class Float>
5484 Node *AbstractManglingParser<Alloc, Derived>::parseFloatingLiteral() {
5485 const size_t N = FloatData<Float>::mangled_size;
5486 if (numLeft() <= N)
5487 return nullptr;
5488 std::string_view Data(First, N);
5489 for (char C : Data)
5490 if (!std::isxdigit(C))
5491 return nullptr;
5492 First += N;
5493 if (!consumeIf('E'))
5494 return nullptr;
5495 return make<FloatLiteralImpl<Float>>(Data);
5498 // <seq-id> ::= <0-9A-Z>+
5499 template <typename Alloc, typename Derived>
5500 bool AbstractManglingParser<Alloc, Derived>::parseSeqId(size_t *Out) {
5501 if (!(look() >= '0' && look() <= '9') &&
5502 !(look() >= 'A' && look() <= 'Z'))
5503 return true;
5505 size_t Id = 0;
5506 while (true) {
5507 if (look() >= '0' && look() <= '9') {
5508 Id *= 36;
5509 Id += static_cast<size_t>(look() - '0');
5510 } else if (look() >= 'A' && look() <= 'Z') {
5511 Id *= 36;
5512 Id += static_cast<size_t>(look() - 'A') + 10;
5513 } else {
5514 *Out = Id;
5515 return false;
5517 ++First;
5521 // <substitution> ::= S <seq-id> _
5522 // ::= S_
5523 // <substitution> ::= Sa # ::std::allocator
5524 // <substitution> ::= Sb # ::std::basic_string
5525 // <substitution> ::= Ss # ::std::basic_string < char,
5526 // ::std::char_traits<char>,
5527 // ::std::allocator<char> >
5528 // <substitution> ::= Si # ::std::basic_istream<char, std::char_traits<char> >
5529 // <substitution> ::= So # ::std::basic_ostream<char, std::char_traits<char> >
5530 // <substitution> ::= Sd # ::std::basic_iostream<char, std::char_traits<char> >
5531 // The St case is handled specially in parseNestedName.
5532 template <typename Derived, typename Alloc>
5533 Node *AbstractManglingParser<Derived, Alloc>::parseSubstitution() {
5534 if (!consumeIf('S'))
5535 return nullptr;
5537 if (look() >= 'a' && look() <= 'z') {
5538 SpecialSubKind Kind;
5539 switch (look()) {
5540 case 'a':
5541 Kind = SpecialSubKind::allocator;
5542 break;
5543 case 'b':
5544 Kind = SpecialSubKind::basic_string;
5545 break;
5546 case 'd':
5547 Kind = SpecialSubKind::iostream;
5548 break;
5549 case 'i':
5550 Kind = SpecialSubKind::istream;
5551 break;
5552 case 'o':
5553 Kind = SpecialSubKind::ostream;
5554 break;
5555 case 's':
5556 Kind = SpecialSubKind::string;
5557 break;
5558 default:
5559 return nullptr;
5561 ++First;
5562 auto *SpecialSub = make<SpecialSubstitution>(Kind);
5563 if (!SpecialSub)
5564 return nullptr;
5566 // Itanium C++ ABI 5.1.2: If a name that would use a built-in <substitution>
5567 // has ABI tags, the tags are appended to the substitution; the result is a
5568 // substitutable component.
5569 Node *WithTags = getDerived().parseAbiTags(SpecialSub);
5570 if (WithTags != SpecialSub) {
5571 Subs.push_back(WithTags);
5572 SpecialSub = WithTags;
5574 return SpecialSub;
5577 // ::= S_
5578 if (consumeIf('_')) {
5579 if (Subs.empty())
5580 return nullptr;
5581 return Subs[0];
5584 // ::= S <seq-id> _
5585 size_t Index = 0;
5586 if (parseSeqId(&Index))
5587 return nullptr;
5588 ++Index;
5589 if (!consumeIf('_') || Index >= Subs.size())
5590 return nullptr;
5591 return Subs[Index];
5594 // <template-param> ::= T_ # first template parameter
5595 // ::= T <parameter-2 non-negative number> _
5596 // ::= TL <level-1> __
5597 // ::= TL <level-1> _ <parameter-2 non-negative number> _
5598 template <typename Derived, typename Alloc>
5599 Node *AbstractManglingParser<Derived, Alloc>::parseTemplateParam() {
5600 const char *Begin = First;
5601 if (!consumeIf('T'))
5602 return nullptr;
5604 size_t Level = 0;
5605 if (consumeIf('L')) {
5606 if (parsePositiveInteger(&Level))
5607 return nullptr;
5608 ++Level;
5609 if (!consumeIf('_'))
5610 return nullptr;
5613 size_t Index = 0;
5614 if (!consumeIf('_')) {
5615 if (parsePositiveInteger(&Index))
5616 return nullptr;
5617 ++Index;
5618 if (!consumeIf('_'))
5619 return nullptr;
5622 // We don't track enclosing template parameter levels well enough to reliably
5623 // substitute them all within a <constraint-expression>, so print the
5624 // parameter numbering instead for now.
5625 // TODO: Track all enclosing template parameters and substitute them here.
5626 if (InConstraintExpr) {
5627 return make<NameType>(std::string_view(Begin, First - 1 - Begin));
5630 // If we're in a context where this <template-param> refers to a
5631 // <template-arg> further ahead in the mangled name (currently just conversion
5632 // operator types), then we should only look it up in the right context.
5633 // This can only happen at the outermost level.
5634 if (PermitForwardTemplateReferences && Level == 0) {
5635 Node *ForwardRef = make<ForwardTemplateReference>(Index);
5636 if (!ForwardRef)
5637 return nullptr;
5638 assert(ForwardRef->getKind() == Node::KForwardTemplateReference);
5639 ForwardTemplateRefs.push_back(
5640 static_cast<ForwardTemplateReference *>(ForwardRef));
5641 return ForwardRef;
5644 if (Level >= TemplateParams.size() || !TemplateParams[Level] ||
5645 Index >= TemplateParams[Level]->size()) {
5646 // Itanium ABI 5.1.8: In a generic lambda, uses of auto in the parameter
5647 // list are mangled as the corresponding artificial template type parameter.
5648 if (ParsingLambdaParamsAtLevel == Level && Level <= TemplateParams.size()) {
5649 // This will be popped by the ScopedTemplateParamList in
5650 // parseUnnamedTypeName.
5651 if (Level == TemplateParams.size())
5652 TemplateParams.push_back(nullptr);
5653 return make<NameType>("auto");
5656 return nullptr;
5659 return (*TemplateParams[Level])[Index];
5662 // <template-param-decl> ::= Ty # type parameter
5663 // ::= Tn <type> # non-type parameter
5664 // ::= Tt <template-param-decl>* E # template parameter
5665 // ::= Tp <template-param-decl> # parameter pack
5666 template <typename Derived, typename Alloc>
5667 Node *AbstractManglingParser<Derived, Alloc>::parseTemplateParamDecl(
5668 TemplateParamList *Params) {
5669 auto InventTemplateParamName = [&](TemplateParamKind Kind) {
5670 unsigned Index = NumSyntheticTemplateParameters[(int)Kind]++;
5671 Node *N = make<SyntheticTemplateParamName>(Kind, Index);
5672 if (N && Params)
5673 Params->push_back(N);
5674 return N;
5677 if (consumeIf("Ty")) {
5678 Node *Name = InventTemplateParamName(TemplateParamKind::Type);
5679 if (!Name)
5680 return nullptr;
5681 return make<TypeTemplateParamDecl>(Name);
5684 if (consumeIf("Tk")) {
5685 Node *Constraint = getDerived().parseName();
5686 if (!Constraint)
5687 return nullptr;
5688 Node *Name = InventTemplateParamName(TemplateParamKind::Type);
5689 if (!Name)
5690 return nullptr;
5691 return make<ConstrainedTypeTemplateParamDecl>(Constraint, Name);
5694 if (consumeIf("Tn")) {
5695 Node *Name = InventTemplateParamName(TemplateParamKind::NonType);
5696 if (!Name)
5697 return nullptr;
5698 Node *Type = parseType();
5699 if (!Type)
5700 return nullptr;
5701 return make<NonTypeTemplateParamDecl>(Name, Type);
5704 if (consumeIf("Tt")) {
5705 Node *Name = InventTemplateParamName(TemplateParamKind::Template);
5706 if (!Name)
5707 return nullptr;
5708 size_t ParamsBegin = Names.size();
5709 ScopedTemplateParamList TemplateTemplateParamParams(this);
5710 Node *Requires = nullptr;
5711 while (!consumeIf('E')) {
5712 Node *P = parseTemplateParamDecl(TemplateTemplateParamParams.params());
5713 if (!P)
5714 return nullptr;
5715 Names.push_back(P);
5716 if (consumeIf('Q')) {
5717 Requires = getDerived().parseConstraintExpr();
5718 if (Requires == nullptr || !consumeIf('E'))
5719 return nullptr;
5720 break;
5723 NodeArray InnerParams = popTrailingNodeArray(ParamsBegin);
5724 return make<TemplateTemplateParamDecl>(Name, InnerParams, Requires);
5727 if (consumeIf("Tp")) {
5728 Node *P = parseTemplateParamDecl(Params);
5729 if (!P)
5730 return nullptr;
5731 return make<TemplateParamPackDecl>(P);
5734 return nullptr;
5737 // <template-arg> ::= <type> # type or template
5738 // ::= X <expression> E # expression
5739 // ::= <expr-primary> # simple expressions
5740 // ::= J <template-arg>* E # argument pack
5741 // ::= LZ <encoding> E # extension
5742 // ::= <template-param-decl> <template-arg>
5743 template <typename Derived, typename Alloc>
5744 Node *AbstractManglingParser<Derived, Alloc>::parseTemplateArg() {
5745 switch (look()) {
5746 case 'X': {
5747 ++First;
5748 Node *Arg = getDerived().parseExpr();
5749 if (Arg == nullptr || !consumeIf('E'))
5750 return nullptr;
5751 return Arg;
5753 case 'J': {
5754 ++First;
5755 size_t ArgsBegin = Names.size();
5756 while (!consumeIf('E')) {
5757 Node *Arg = getDerived().parseTemplateArg();
5758 if (Arg == nullptr)
5759 return nullptr;
5760 Names.push_back(Arg);
5762 NodeArray Args = popTrailingNodeArray(ArgsBegin);
5763 return make<TemplateArgumentPack>(Args);
5765 case 'L': {
5766 // ::= LZ <encoding> E # extension
5767 if (look(1) == 'Z') {
5768 First += 2;
5769 Node *Arg = getDerived().parseEncoding();
5770 if (Arg == nullptr || !consumeIf('E'))
5771 return nullptr;
5772 return Arg;
5774 // ::= <expr-primary> # simple expressions
5775 return getDerived().parseExprPrimary();
5777 case 'T': {
5778 // Either <template-param> or a <template-param-decl> <template-arg>.
5779 if (!getDerived().isTemplateParamDecl())
5780 return getDerived().parseType();
5781 Node *Param = getDerived().parseTemplateParamDecl(nullptr);
5782 if (!Param)
5783 return nullptr;
5784 Node *Arg = getDerived().parseTemplateArg();
5785 if (!Arg)
5786 return nullptr;
5787 return make<TemplateParamQualifiedArg>(Param, Arg);
5789 default:
5790 return getDerived().parseType();
5794 // <template-args> ::= I <template-arg>* E
5795 // extension, the abi says <template-arg>+
5796 template <typename Derived, typename Alloc>
5797 Node *
5798 AbstractManglingParser<Derived, Alloc>::parseTemplateArgs(bool TagTemplates) {
5799 if (!consumeIf('I'))
5800 return nullptr;
5802 // <template-params> refer to the innermost <template-args>. Clear out any
5803 // outer args that we may have inserted into TemplateParams.
5804 if (TagTemplates) {
5805 TemplateParams.clear();
5806 TemplateParams.push_back(&OuterTemplateParams);
5807 OuterTemplateParams.clear();
5810 size_t ArgsBegin = Names.size();
5811 Node *Requires = nullptr;
5812 while (!consumeIf('E')) {
5813 if (TagTemplates) {
5814 Node *Arg = getDerived().parseTemplateArg();
5815 if (Arg == nullptr)
5816 return nullptr;
5817 Names.push_back(Arg);
5818 Node *TableEntry = Arg;
5819 if (Arg->getKind() == Node::KTemplateParamQualifiedArg) {
5820 TableEntry =
5821 static_cast<TemplateParamQualifiedArg *>(TableEntry)->getArg();
5823 if (Arg->getKind() == Node::KTemplateArgumentPack) {
5824 TableEntry = make<ParameterPack>(
5825 static_cast<TemplateArgumentPack*>(TableEntry)->getElements());
5826 if (!TableEntry)
5827 return nullptr;
5829 OuterTemplateParams.push_back(TableEntry);
5830 } else {
5831 Node *Arg = getDerived().parseTemplateArg();
5832 if (Arg == nullptr)
5833 return nullptr;
5834 Names.push_back(Arg);
5836 if (consumeIf('Q')) {
5837 Requires = getDerived().parseConstraintExpr();
5838 if (!Requires || !consumeIf('E'))
5839 return nullptr;
5840 break;
5843 return make<TemplateArgs>(popTrailingNodeArray(ArgsBegin), Requires);
5846 // <mangled-name> ::= _Z <encoding>
5847 // ::= <type>
5848 // extension ::= ___Z <encoding> _block_invoke
5849 // extension ::= ___Z <encoding> _block_invoke<decimal-digit>+
5850 // extension ::= ___Z <encoding> _block_invoke_<decimal-digit>+
5851 template <typename Derived, typename Alloc>
5852 Node *AbstractManglingParser<Derived, Alloc>::parse() {
5853 if (consumeIf("_Z") || consumeIf("__Z")) {
5854 Node *Encoding = getDerived().parseEncoding();
5855 if (Encoding == nullptr)
5856 return nullptr;
5857 if (look() == '.') {
5858 Encoding =
5859 make<DotSuffix>(Encoding, std::string_view(First, Last - First));
5860 First = Last;
5862 if (numLeft() != 0)
5863 return nullptr;
5864 return Encoding;
5867 if (consumeIf("___Z") || consumeIf("____Z")) {
5868 Node *Encoding = getDerived().parseEncoding();
5869 if (Encoding == nullptr || !consumeIf("_block_invoke"))
5870 return nullptr;
5871 bool RequireNumber = consumeIf('_');
5872 if (parseNumber().empty() && RequireNumber)
5873 return nullptr;
5874 if (look() == '.')
5875 First = Last;
5876 if (numLeft() != 0)
5877 return nullptr;
5878 return make<SpecialName>("invocation function for block in ", Encoding);
5881 Node *Ty = getDerived().parseType();
5882 if (numLeft() != 0)
5883 return nullptr;
5884 return Ty;
5887 template <typename Alloc>
5888 struct ManglingParser : AbstractManglingParser<ManglingParser<Alloc>, Alloc> {
5889 using AbstractManglingParser<ManglingParser<Alloc>,
5890 Alloc>::AbstractManglingParser;
5893 DEMANGLE_NAMESPACE_END
5895 #ifdef _LIBCXXABI_COMPILER_CLANG
5896 #pragma clang diagnostic pop
5897 #endif
5899 #endif // DEMANGLE_ITANIUMDEMANGLE_H