Bump version to 19.1.0 (final)
[llvm-project.git] / libcxxabi / src / demangle / ItaniumDemangle.h
blob36bf454636366a6d00987d37b4f5f7d4f0ccbec8
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 <cctype>
25 #include <cstdio>
26 #include <cstdlib>
27 #include <cstring>
28 #include <limits>
29 #include <new>
30 #include <string_view>
31 #include <type_traits>
32 #include <utility>
34 #ifdef _LIBCXXABI_COMPILER_CLANG
35 #pragma clang diagnostic push
36 #pragma clang diagnostic ignored "-Wunused-template"
37 #endif
39 DEMANGLE_NAMESPACE_BEGIN
41 template <class T, size_t N> class PODSmallVector {
42 static_assert(std::is_trivial<T>::value,
43 "T is required to be a trivial type");
44 T *First = nullptr;
45 T *Last = nullptr;
46 T *Cap = nullptr;
47 T Inline[N] = {};
49 bool isInline() const { return First == Inline; }
51 void clearInline() {
52 First = Inline;
53 Last = Inline;
54 Cap = Inline + N;
57 void reserve(size_t NewCap) {
58 size_t S = size();
59 if (isInline()) {
60 auto *Tmp = static_cast<T *>(std::malloc(NewCap * sizeof(T)));
61 if (Tmp == nullptr)
62 std::abort();
63 std::copy(First, Last, Tmp);
64 First = Tmp;
65 } else {
66 First = static_cast<T *>(std::realloc(First, NewCap * sizeof(T)));
67 if (First == nullptr)
68 std::abort();
70 Last = First + S;
71 Cap = First + NewCap;
74 public:
75 PODSmallVector() : First(Inline), Last(First), Cap(Inline + N) {}
77 PODSmallVector(const PODSmallVector &) = delete;
78 PODSmallVector &operator=(const PODSmallVector &) = delete;
80 PODSmallVector(PODSmallVector &&Other) : PODSmallVector() {
81 if (Other.isInline()) {
82 std::copy(Other.begin(), Other.end(), First);
83 Last = First + Other.size();
84 Other.clear();
85 return;
88 First = Other.First;
89 Last = Other.Last;
90 Cap = Other.Cap;
91 Other.clearInline();
94 PODSmallVector &operator=(PODSmallVector &&Other) {
95 if (Other.isInline()) {
96 if (!isInline()) {
97 std::free(First);
98 clearInline();
100 std::copy(Other.begin(), Other.end(), First);
101 Last = First + Other.size();
102 Other.clear();
103 return *this;
106 if (isInline()) {
107 First = Other.First;
108 Last = Other.Last;
109 Cap = Other.Cap;
110 Other.clearInline();
111 return *this;
114 std::swap(First, Other.First);
115 std::swap(Last, Other.Last);
116 std::swap(Cap, Other.Cap);
117 Other.clear();
118 return *this;
121 // NOLINTNEXTLINE(readability-identifier-naming)
122 void push_back(const T &Elem) {
123 if (Last == Cap)
124 reserve(size() * 2);
125 *Last++ = Elem;
128 // NOLINTNEXTLINE(readability-identifier-naming)
129 void pop_back() {
130 DEMANGLE_ASSERT(Last != First, "Popping empty vector!");
131 --Last;
134 void shrinkToSize(size_t Index) {
135 DEMANGLE_ASSERT(Index <= size(), "shrinkToSize() can't expand!");
136 Last = First + Index;
139 T *begin() { return First; }
140 T *end() { return Last; }
142 bool empty() const { return First == Last; }
143 size_t size() const { return static_cast<size_t>(Last - First); }
144 T &back() {
145 DEMANGLE_ASSERT(Last != First, "Calling back() on empty vector!");
146 return *(Last - 1);
148 T &operator[](size_t Index) {
149 DEMANGLE_ASSERT(Index < size(), "Invalid access!");
150 return *(begin() + Index);
152 void clear() { Last = First; }
154 ~PODSmallVector() {
155 if (!isInline())
156 std::free(First);
160 // Base class of all AST nodes. The AST is built by the parser, then is
161 // traversed by the printLeft/Right functions to produce a demangled string.
162 class Node {
163 public:
164 enum Kind : unsigned char {
165 #define NODE(NodeKind) K##NodeKind,
166 #include "ItaniumNodes.def"
169 /// Three-way bool to track a cached value. Unknown is possible if this node
170 /// has an unexpanded parameter pack below it that may affect this cache.
171 enum class Cache : unsigned char { Yes, No, Unknown, };
173 /// Operator precedence for expression nodes. Used to determine required
174 /// parens in expression emission.
175 enum class Prec {
176 Primary,
177 Postfix,
178 Unary,
179 Cast,
180 PtrMem,
181 Multiplicative,
182 Additive,
183 Shift,
184 Spaceship,
185 Relational,
186 Equality,
187 And,
188 Xor,
189 Ior,
190 AndIf,
191 OrIf,
192 Conditional,
193 Assign,
194 Comma,
195 Default,
198 private:
199 Kind K;
201 Prec Precedence : 6;
203 // FIXME: Make these protected.
204 public:
205 /// Tracks if this node has a component on its right side, in which case we
206 /// need to call printRight.
207 Cache RHSComponentCache : 2;
209 /// Track if this node is a (possibly qualified) array type. This can affect
210 /// how we format the output string.
211 Cache ArrayCache : 2;
213 /// Track if this node is a (possibly qualified) function type. This can
214 /// affect how we format the output string.
215 Cache FunctionCache : 2;
217 public:
218 Node(Kind K_, Prec Precedence_ = Prec::Primary,
219 Cache RHSComponentCache_ = Cache::No, Cache ArrayCache_ = Cache::No,
220 Cache FunctionCache_ = Cache::No)
221 : K(K_), Precedence(Precedence_), RHSComponentCache(RHSComponentCache_),
222 ArrayCache(ArrayCache_), FunctionCache(FunctionCache_) {}
223 Node(Kind K_, Cache RHSComponentCache_, Cache ArrayCache_ = Cache::No,
224 Cache FunctionCache_ = Cache::No)
225 : Node(K_, Prec::Primary, RHSComponentCache_, ArrayCache_,
226 FunctionCache_) {}
228 /// Visit the most-derived object corresponding to this object.
229 template<typename Fn> void visit(Fn F) const;
231 // The following function is provided by all derived classes:
233 // Call F with arguments that, when passed to the constructor of this node,
234 // would construct an equivalent node.
235 //template<typename Fn> void match(Fn F) const;
237 bool hasRHSComponent(OutputBuffer &OB) const {
238 if (RHSComponentCache != Cache::Unknown)
239 return RHSComponentCache == Cache::Yes;
240 return hasRHSComponentSlow(OB);
243 bool hasArray(OutputBuffer &OB) const {
244 if (ArrayCache != Cache::Unknown)
245 return ArrayCache == Cache::Yes;
246 return hasArraySlow(OB);
249 bool hasFunction(OutputBuffer &OB) const {
250 if (FunctionCache != Cache::Unknown)
251 return FunctionCache == Cache::Yes;
252 return hasFunctionSlow(OB);
255 Kind getKind() const { return K; }
257 Prec getPrecedence() const { return Precedence; }
259 virtual bool hasRHSComponentSlow(OutputBuffer &) const { return false; }
260 virtual bool hasArraySlow(OutputBuffer &) const { return false; }
261 virtual bool hasFunctionSlow(OutputBuffer &) const { return false; }
263 // Dig through "glue" nodes like ParameterPack and ForwardTemplateReference to
264 // get at a node that actually represents some concrete syntax.
265 virtual const Node *getSyntaxNode(OutputBuffer &) const { return this; }
267 // Print this node as an expression operand, surrounding it in parentheses if
268 // its precedence is [Strictly] weaker than P.
269 void printAsOperand(OutputBuffer &OB, Prec P = Prec::Default,
270 bool StrictlyWorse = false) const {
271 bool Paren =
272 unsigned(getPrecedence()) >= unsigned(P) + unsigned(StrictlyWorse);
273 if (Paren)
274 OB.printOpen();
275 print(OB);
276 if (Paren)
277 OB.printClose();
280 void print(OutputBuffer &OB) const {
281 printLeft(OB);
282 if (RHSComponentCache != Cache::No)
283 printRight(OB);
286 // Print the "left" side of this Node into OutputBuffer.
287 virtual void printLeft(OutputBuffer &) const = 0;
289 // Print the "right". This distinction is necessary to represent C++ types
290 // that appear on the RHS of their subtype, such as arrays or functions.
291 // Since most types don't have such a component, provide a default
292 // implementation.
293 virtual void printRight(OutputBuffer &) const {}
295 virtual std::string_view getBaseName() const { return {}; }
297 // Silence compiler warnings, this dtor will never be called.
298 virtual ~Node() = default;
300 #ifndef NDEBUG
301 DEMANGLE_DUMP_METHOD void dump() const;
302 #endif
305 class NodeArray {
306 Node **Elements;
307 size_t NumElements;
309 public:
310 NodeArray() : Elements(nullptr), NumElements(0) {}
311 NodeArray(Node **Elements_, size_t NumElements_)
312 : Elements(Elements_), NumElements(NumElements_) {}
314 bool empty() const { return NumElements == 0; }
315 size_t size() const { return NumElements; }
317 Node **begin() const { return Elements; }
318 Node **end() const { return Elements + NumElements; }
320 Node *operator[](size_t Idx) const { return Elements[Idx]; }
322 void printWithComma(OutputBuffer &OB) const {
323 bool FirstElement = true;
324 for (size_t Idx = 0; Idx != NumElements; ++Idx) {
325 size_t BeforeComma = OB.getCurrentPosition();
326 if (!FirstElement)
327 OB += ", ";
328 size_t AfterComma = OB.getCurrentPosition();
329 Elements[Idx]->printAsOperand(OB, Node::Prec::Comma);
331 // Elements[Idx] is an empty parameter pack expansion, we should erase the
332 // comma we just printed.
333 if (AfterComma == OB.getCurrentPosition()) {
334 OB.setCurrentPosition(BeforeComma);
335 continue;
338 FirstElement = false;
343 struct NodeArrayNode : Node {
344 NodeArray Array;
345 NodeArrayNode(NodeArray Array_) : Node(KNodeArrayNode), Array(Array_) {}
347 template<typename Fn> void match(Fn F) const { F(Array); }
349 void printLeft(OutputBuffer &OB) const override { Array.printWithComma(OB); }
352 class DotSuffix final : public Node {
353 const Node *Prefix;
354 const std::string_view Suffix;
356 public:
357 DotSuffix(const Node *Prefix_, std::string_view Suffix_)
358 : Node(KDotSuffix), Prefix(Prefix_), Suffix(Suffix_) {}
360 template<typename Fn> void match(Fn F) const { F(Prefix, Suffix); }
362 void printLeft(OutputBuffer &OB) const override {
363 Prefix->print(OB);
364 OB += " (";
365 OB += Suffix;
366 OB += ")";
370 class VendorExtQualType final : public Node {
371 const Node *Ty;
372 std::string_view Ext;
373 const Node *TA;
375 public:
376 VendorExtQualType(const Node *Ty_, std::string_view Ext_, const Node *TA_)
377 : Node(KVendorExtQualType), Ty(Ty_), Ext(Ext_), TA(TA_) {}
379 const Node *getTy() const { return Ty; }
380 std::string_view getExt() const { return Ext; }
381 const Node *getTA() const { return TA; }
383 template <typename Fn> void match(Fn F) const { F(Ty, Ext, TA); }
385 void printLeft(OutputBuffer &OB) const override {
386 Ty->print(OB);
387 OB += " ";
388 OB += Ext;
389 if (TA != nullptr)
390 TA->print(OB);
394 enum FunctionRefQual : unsigned char {
395 FrefQualNone,
396 FrefQualLValue,
397 FrefQualRValue,
400 enum Qualifiers {
401 QualNone = 0,
402 QualConst = 0x1,
403 QualVolatile = 0x2,
404 QualRestrict = 0x4,
407 inline Qualifiers operator|=(Qualifiers &Q1, Qualifiers Q2) {
408 return Q1 = static_cast<Qualifiers>(Q1 | Q2);
411 class QualType final : public Node {
412 protected:
413 const Qualifiers Quals;
414 const Node *Child;
416 void printQuals(OutputBuffer &OB) const {
417 if (Quals & QualConst)
418 OB += " const";
419 if (Quals & QualVolatile)
420 OB += " volatile";
421 if (Quals & QualRestrict)
422 OB += " restrict";
425 public:
426 QualType(const Node *Child_, Qualifiers Quals_)
427 : Node(KQualType, Child_->RHSComponentCache,
428 Child_->ArrayCache, Child_->FunctionCache),
429 Quals(Quals_), Child(Child_) {}
431 Qualifiers getQuals() const { return Quals; }
432 const Node *getChild() const { return Child; }
434 template<typename Fn> void match(Fn F) const { F(Child, Quals); }
436 bool hasRHSComponentSlow(OutputBuffer &OB) const override {
437 return Child->hasRHSComponent(OB);
439 bool hasArraySlow(OutputBuffer &OB) const override {
440 return Child->hasArray(OB);
442 bool hasFunctionSlow(OutputBuffer &OB) const override {
443 return Child->hasFunction(OB);
446 void printLeft(OutputBuffer &OB) const override {
447 Child->printLeft(OB);
448 printQuals(OB);
451 void printRight(OutputBuffer &OB) const override { Child->printRight(OB); }
454 class ConversionOperatorType final : public Node {
455 const Node *Ty;
457 public:
458 ConversionOperatorType(const Node *Ty_)
459 : Node(KConversionOperatorType), Ty(Ty_) {}
461 template<typename Fn> void match(Fn F) const { F(Ty); }
463 void printLeft(OutputBuffer &OB) const override {
464 OB += "operator ";
465 Ty->print(OB);
469 class PostfixQualifiedType final : public Node {
470 const Node *Ty;
471 const std::string_view Postfix;
473 public:
474 PostfixQualifiedType(const Node *Ty_, std::string_view Postfix_)
475 : Node(KPostfixQualifiedType), Ty(Ty_), Postfix(Postfix_) {}
477 template<typename Fn> void match(Fn F) const { F(Ty, Postfix); }
479 void printLeft(OutputBuffer &OB) const override {
480 Ty->printLeft(OB);
481 OB += Postfix;
485 class NameType final : public Node {
486 const std::string_view Name;
488 public:
489 NameType(std::string_view Name_) : Node(KNameType), Name(Name_) {}
491 template<typename Fn> void match(Fn F) const { F(Name); }
493 std::string_view getName() const { return Name; }
494 std::string_view getBaseName() const override { return Name; }
496 void printLeft(OutputBuffer &OB) const override { OB += Name; }
499 class BitIntType final : public Node {
500 const Node *Size;
501 bool Signed;
503 public:
504 BitIntType(const Node *Size_, bool Signed_)
505 : Node(KBitIntType), Size(Size_), Signed(Signed_) {}
507 template <typename Fn> void match(Fn F) const { F(Size, Signed); }
509 void printLeft(OutputBuffer &OB) const override {
510 if (!Signed)
511 OB += "unsigned ";
512 OB += "_BitInt";
513 OB.printOpen();
514 Size->printAsOperand(OB);
515 OB.printClose();
519 class ElaboratedTypeSpefType : public Node {
520 std::string_view Kind;
521 Node *Child;
522 public:
523 ElaboratedTypeSpefType(std::string_view Kind_, Node *Child_)
524 : Node(KElaboratedTypeSpefType), Kind(Kind_), Child(Child_) {}
526 template<typename Fn> void match(Fn F) const { F(Kind, Child); }
528 void printLeft(OutputBuffer &OB) const override {
529 OB += Kind;
530 OB += ' ';
531 Child->print(OB);
535 class TransformedType : public Node {
536 std::string_view Transform;
537 Node *BaseType;
538 public:
539 TransformedType(std::string_view Transform_, Node *BaseType_)
540 : Node(KTransformedType), Transform(Transform_), BaseType(BaseType_) {}
542 template<typename Fn> void match(Fn F) const { F(Transform, BaseType); }
544 void printLeft(OutputBuffer &OB) const override {
545 OB += Transform;
546 OB += '(';
547 BaseType->print(OB);
548 OB += ')';
552 struct AbiTagAttr : Node {
553 Node *Base;
554 std::string_view Tag;
556 AbiTagAttr(Node *Base_, std::string_view Tag_)
557 : Node(KAbiTagAttr, Base_->RHSComponentCache, Base_->ArrayCache,
558 Base_->FunctionCache),
559 Base(Base_), Tag(Tag_) {}
561 template<typename Fn> void match(Fn F) const { F(Base, Tag); }
563 std::string_view getBaseName() const override { return Base->getBaseName(); }
565 void printLeft(OutputBuffer &OB) const override {
566 Base->printLeft(OB);
567 OB += "[abi:";
568 OB += Tag;
569 OB += "]";
573 class EnableIfAttr : public Node {
574 NodeArray Conditions;
575 public:
576 EnableIfAttr(NodeArray Conditions_)
577 : Node(KEnableIfAttr), Conditions(Conditions_) {}
579 template<typename Fn> void match(Fn F) const { F(Conditions); }
581 void printLeft(OutputBuffer &OB) const override {
582 OB += " [enable_if:";
583 Conditions.printWithComma(OB);
584 OB += ']';
588 class ObjCProtoName : public Node {
589 const Node *Ty;
590 std::string_view Protocol;
592 friend class PointerType;
594 public:
595 ObjCProtoName(const Node *Ty_, std::string_view Protocol_)
596 : Node(KObjCProtoName), Ty(Ty_), Protocol(Protocol_) {}
598 template<typename Fn> void match(Fn F) const { F(Ty, Protocol); }
600 bool isObjCObject() const {
601 return Ty->getKind() == KNameType &&
602 static_cast<const NameType *>(Ty)->getName() == "objc_object";
605 void printLeft(OutputBuffer &OB) const override {
606 Ty->print(OB);
607 OB += "<";
608 OB += Protocol;
609 OB += ">";
613 class PointerType final : public Node {
614 const Node *Pointee;
616 public:
617 PointerType(const Node *Pointee_)
618 : Node(KPointerType, Pointee_->RHSComponentCache),
619 Pointee(Pointee_) {}
621 const Node *getPointee() const { return Pointee; }
623 template<typename Fn> void match(Fn F) const { F(Pointee); }
625 bool hasRHSComponentSlow(OutputBuffer &OB) const override {
626 return Pointee->hasRHSComponent(OB);
629 void printLeft(OutputBuffer &OB) const override {
630 // We rewrite objc_object<SomeProtocol>* into id<SomeProtocol>.
631 if (Pointee->getKind() != KObjCProtoName ||
632 !static_cast<const ObjCProtoName *>(Pointee)->isObjCObject()) {
633 Pointee->printLeft(OB);
634 if (Pointee->hasArray(OB))
635 OB += " ";
636 if (Pointee->hasArray(OB) || Pointee->hasFunction(OB))
637 OB += "(";
638 OB += "*";
639 } else {
640 const auto *objcProto = static_cast<const ObjCProtoName *>(Pointee);
641 OB += "id<";
642 OB += objcProto->Protocol;
643 OB += ">";
647 void printRight(OutputBuffer &OB) const override {
648 if (Pointee->getKind() != KObjCProtoName ||
649 !static_cast<const ObjCProtoName *>(Pointee)->isObjCObject()) {
650 if (Pointee->hasArray(OB) || Pointee->hasFunction(OB))
651 OB += ")";
652 Pointee->printRight(OB);
657 enum class ReferenceKind {
658 LValue,
659 RValue,
662 // Represents either a LValue or an RValue reference type.
663 class ReferenceType : public Node {
664 const Node *Pointee;
665 ReferenceKind RK;
667 mutable bool Printing = false;
669 // Dig through any refs to refs, collapsing the ReferenceTypes as we go. The
670 // rule here is rvalue ref to rvalue ref collapses to a rvalue ref, and any
671 // other combination collapses to a lvalue ref.
673 // A combination of a TemplateForwardReference and a back-ref Substitution
674 // from an ill-formed string may have created a cycle; use cycle detection to
675 // avoid looping forever.
676 std::pair<ReferenceKind, const Node *> collapse(OutputBuffer &OB) const {
677 auto SoFar = std::make_pair(RK, Pointee);
678 // Track the chain of nodes for the Floyd's 'tortoise and hare'
679 // cycle-detection algorithm, since getSyntaxNode(S) is impure
680 PODSmallVector<const Node *, 8> Prev;
681 for (;;) {
682 const Node *SN = SoFar.second->getSyntaxNode(OB);
683 if (SN->getKind() != KReferenceType)
684 break;
685 auto *RT = static_cast<const ReferenceType *>(SN);
686 SoFar.second = RT->Pointee;
687 SoFar.first = std::min(SoFar.first, RT->RK);
689 // The middle of Prev is the 'slow' pointer moving at half speed
690 Prev.push_back(SoFar.second);
691 if (Prev.size() > 1 && SoFar.second == Prev[(Prev.size() - 1) / 2]) {
692 // Cycle detected
693 SoFar.second = nullptr;
694 break;
697 return SoFar;
700 public:
701 ReferenceType(const Node *Pointee_, ReferenceKind RK_)
702 : Node(KReferenceType, Pointee_->RHSComponentCache),
703 Pointee(Pointee_), RK(RK_) {}
705 template<typename Fn> void match(Fn F) const { F(Pointee, RK); }
707 bool hasRHSComponentSlow(OutputBuffer &OB) const override {
708 return Pointee->hasRHSComponent(OB);
711 void printLeft(OutputBuffer &OB) const override {
712 if (Printing)
713 return;
714 ScopedOverride<bool> SavePrinting(Printing, true);
715 std::pair<ReferenceKind, const Node *> Collapsed = collapse(OB);
716 if (!Collapsed.second)
717 return;
718 Collapsed.second->printLeft(OB);
719 if (Collapsed.second->hasArray(OB))
720 OB += " ";
721 if (Collapsed.second->hasArray(OB) || Collapsed.second->hasFunction(OB))
722 OB += "(";
724 OB += (Collapsed.first == ReferenceKind::LValue ? "&" : "&&");
726 void printRight(OutputBuffer &OB) const override {
727 if (Printing)
728 return;
729 ScopedOverride<bool> SavePrinting(Printing, true);
730 std::pair<ReferenceKind, const Node *> Collapsed = collapse(OB);
731 if (!Collapsed.second)
732 return;
733 if (Collapsed.second->hasArray(OB) || Collapsed.second->hasFunction(OB))
734 OB += ")";
735 Collapsed.second->printRight(OB);
739 class PointerToMemberType final : public Node {
740 const Node *ClassType;
741 const Node *MemberType;
743 public:
744 PointerToMemberType(const Node *ClassType_, const Node *MemberType_)
745 : Node(KPointerToMemberType, MemberType_->RHSComponentCache),
746 ClassType(ClassType_), MemberType(MemberType_) {}
748 template<typename Fn> void match(Fn F) const { F(ClassType, MemberType); }
750 bool hasRHSComponentSlow(OutputBuffer &OB) const override {
751 return MemberType->hasRHSComponent(OB);
754 void printLeft(OutputBuffer &OB) const override {
755 MemberType->printLeft(OB);
756 if (MemberType->hasArray(OB) || MemberType->hasFunction(OB))
757 OB += "(";
758 else
759 OB += " ";
760 ClassType->print(OB);
761 OB += "::*";
764 void printRight(OutputBuffer &OB) const override {
765 if (MemberType->hasArray(OB) || MemberType->hasFunction(OB))
766 OB += ")";
767 MemberType->printRight(OB);
771 class ArrayType final : public Node {
772 const Node *Base;
773 Node *Dimension;
775 public:
776 ArrayType(const Node *Base_, Node *Dimension_)
777 : Node(KArrayType,
778 /*RHSComponentCache=*/Cache::Yes,
779 /*ArrayCache=*/Cache::Yes),
780 Base(Base_), Dimension(Dimension_) {}
782 template<typename Fn> void match(Fn F) const { F(Base, Dimension); }
784 bool hasRHSComponentSlow(OutputBuffer &) const override { return true; }
785 bool hasArraySlow(OutputBuffer &) const override { return true; }
787 void printLeft(OutputBuffer &OB) const override { Base->printLeft(OB); }
789 void printRight(OutputBuffer &OB) const override {
790 if (OB.back() != ']')
791 OB += " ";
792 OB += "[";
793 if (Dimension)
794 Dimension->print(OB);
795 OB += "]";
796 Base->printRight(OB);
800 class FunctionType final : public Node {
801 const Node *Ret;
802 NodeArray Params;
803 Qualifiers CVQuals;
804 FunctionRefQual RefQual;
805 const Node *ExceptionSpec;
807 public:
808 FunctionType(const Node *Ret_, NodeArray Params_, Qualifiers CVQuals_,
809 FunctionRefQual RefQual_, const Node *ExceptionSpec_)
810 : Node(KFunctionType,
811 /*RHSComponentCache=*/Cache::Yes, /*ArrayCache=*/Cache::No,
812 /*FunctionCache=*/Cache::Yes),
813 Ret(Ret_), Params(Params_), CVQuals(CVQuals_), RefQual(RefQual_),
814 ExceptionSpec(ExceptionSpec_) {}
816 template<typename Fn> void match(Fn F) const {
817 F(Ret, Params, CVQuals, RefQual, ExceptionSpec);
820 bool hasRHSComponentSlow(OutputBuffer &) const override { return true; }
821 bool hasFunctionSlow(OutputBuffer &) const override { return true; }
823 // Handle C++'s ... quirky decl grammar by using the left & right
824 // distinction. Consider:
825 // int (*f(float))(char) {}
826 // f is a function that takes a float and returns a pointer to a function
827 // that takes a char and returns an int. If we're trying to print f, start
828 // by printing out the return types's left, then print our parameters, then
829 // finally print right of the return type.
830 void printLeft(OutputBuffer &OB) const override {
831 Ret->printLeft(OB);
832 OB += " ";
835 void printRight(OutputBuffer &OB) const override {
836 OB.printOpen();
837 Params.printWithComma(OB);
838 OB.printClose();
839 Ret->printRight(OB);
841 if (CVQuals & QualConst)
842 OB += " const";
843 if (CVQuals & QualVolatile)
844 OB += " volatile";
845 if (CVQuals & QualRestrict)
846 OB += " restrict";
848 if (RefQual == FrefQualLValue)
849 OB += " &";
850 else if (RefQual == FrefQualRValue)
851 OB += " &&";
853 if (ExceptionSpec != nullptr) {
854 OB += ' ';
855 ExceptionSpec->print(OB);
860 class NoexceptSpec : public Node {
861 const Node *E;
862 public:
863 NoexceptSpec(const Node *E_) : Node(KNoexceptSpec), E(E_) {}
865 template<typename Fn> void match(Fn F) const { F(E); }
867 void printLeft(OutputBuffer &OB) const override {
868 OB += "noexcept";
869 OB.printOpen();
870 E->printAsOperand(OB);
871 OB.printClose();
875 class DynamicExceptionSpec : public Node {
876 NodeArray Types;
877 public:
878 DynamicExceptionSpec(NodeArray Types_)
879 : Node(KDynamicExceptionSpec), Types(Types_) {}
881 template<typename Fn> void match(Fn F) const { F(Types); }
883 void printLeft(OutputBuffer &OB) const override {
884 OB += "throw";
885 OB.printOpen();
886 Types.printWithComma(OB);
887 OB.printClose();
891 /// Represents the explicitly named object parameter.
892 /// E.g.,
893 /// \code{.cpp}
894 /// struct Foo {
895 /// void bar(this Foo && self);
896 /// };
897 /// \endcode
898 class ExplicitObjectParameter final : public Node {
899 Node *Base;
901 public:
902 ExplicitObjectParameter(Node *Base_)
903 : Node(KExplicitObjectParameter), Base(Base_) {
904 DEMANGLE_ASSERT(
905 Base != nullptr,
906 "Creating an ExplicitObjectParameter without a valid Base Node.");
909 template <typename Fn> void match(Fn F) const { F(Base); }
911 void printLeft(OutputBuffer &OB) const override {
912 OB += "this ";
913 Base->print(OB);
917 class FunctionEncoding final : public Node {
918 const Node *Ret;
919 const Node *Name;
920 NodeArray Params;
921 const Node *Attrs;
922 const Node *Requires;
923 Qualifiers CVQuals;
924 FunctionRefQual RefQual;
926 public:
927 FunctionEncoding(const Node *Ret_, const Node *Name_, NodeArray Params_,
928 const Node *Attrs_, const Node *Requires_,
929 Qualifiers CVQuals_, FunctionRefQual RefQual_)
930 : Node(KFunctionEncoding,
931 /*RHSComponentCache=*/Cache::Yes, /*ArrayCache=*/Cache::No,
932 /*FunctionCache=*/Cache::Yes),
933 Ret(Ret_), Name(Name_), Params(Params_), Attrs(Attrs_),
934 Requires(Requires_), CVQuals(CVQuals_), RefQual(RefQual_) {}
936 template<typename Fn> void match(Fn F) const {
937 F(Ret, Name, Params, Attrs, Requires, CVQuals, RefQual);
940 Qualifiers getCVQuals() const { return CVQuals; }
941 FunctionRefQual getRefQual() const { return RefQual; }
942 NodeArray getParams() const { return Params; }
943 const Node *getReturnType() const { return Ret; }
945 bool hasRHSComponentSlow(OutputBuffer &) const override { return true; }
946 bool hasFunctionSlow(OutputBuffer &) const override { return true; }
948 const Node *getName() const { return Name; }
950 void printLeft(OutputBuffer &OB) const override {
951 if (Ret) {
952 Ret->printLeft(OB);
953 if (!Ret->hasRHSComponent(OB))
954 OB += " ";
956 Name->print(OB);
959 void printRight(OutputBuffer &OB) const override {
960 OB.printOpen();
961 Params.printWithComma(OB);
962 OB.printClose();
963 if (Ret)
964 Ret->printRight(OB);
966 if (CVQuals & QualConst)
967 OB += " const";
968 if (CVQuals & QualVolatile)
969 OB += " volatile";
970 if (CVQuals & QualRestrict)
971 OB += " restrict";
973 if (RefQual == FrefQualLValue)
974 OB += " &";
975 else if (RefQual == FrefQualRValue)
976 OB += " &&";
978 if (Attrs != nullptr)
979 Attrs->print(OB);
981 if (Requires != nullptr) {
982 OB += " requires ";
983 Requires->print(OB);
988 class LiteralOperator : public Node {
989 const Node *OpName;
991 public:
992 LiteralOperator(const Node *OpName_)
993 : Node(KLiteralOperator), OpName(OpName_) {}
995 template<typename Fn> void match(Fn F) const { F(OpName); }
997 void printLeft(OutputBuffer &OB) const override {
998 OB += "operator\"\" ";
999 OpName->print(OB);
1003 class SpecialName final : public Node {
1004 const std::string_view Special;
1005 const Node *Child;
1007 public:
1008 SpecialName(std::string_view Special_, const Node *Child_)
1009 : Node(KSpecialName), Special(Special_), Child(Child_) {}
1011 template<typename Fn> void match(Fn F) const { F(Special, Child); }
1013 void printLeft(OutputBuffer &OB) const override {
1014 OB += Special;
1015 Child->print(OB);
1019 class CtorVtableSpecialName final : public Node {
1020 const Node *FirstType;
1021 const Node *SecondType;
1023 public:
1024 CtorVtableSpecialName(const Node *FirstType_, const Node *SecondType_)
1025 : Node(KCtorVtableSpecialName),
1026 FirstType(FirstType_), SecondType(SecondType_) {}
1028 template<typename Fn> void match(Fn F) const { F(FirstType, SecondType); }
1030 void printLeft(OutputBuffer &OB) const override {
1031 OB += "construction vtable for ";
1032 FirstType->print(OB);
1033 OB += "-in-";
1034 SecondType->print(OB);
1038 struct NestedName : Node {
1039 Node *Qual;
1040 Node *Name;
1042 NestedName(Node *Qual_, Node *Name_)
1043 : Node(KNestedName), Qual(Qual_), Name(Name_) {}
1045 template<typename Fn> void match(Fn F) const { F(Qual, Name); }
1047 std::string_view getBaseName() const override { return Name->getBaseName(); }
1049 void printLeft(OutputBuffer &OB) const override {
1050 Qual->print(OB);
1051 OB += "::";
1052 Name->print(OB);
1056 struct MemberLikeFriendName : Node {
1057 Node *Qual;
1058 Node *Name;
1060 MemberLikeFriendName(Node *Qual_, Node *Name_)
1061 : Node(KMemberLikeFriendName), Qual(Qual_), Name(Name_) {}
1063 template<typename Fn> void match(Fn F) const { F(Qual, Name); }
1065 std::string_view getBaseName() const override { return Name->getBaseName(); }
1067 void printLeft(OutputBuffer &OB) const override {
1068 Qual->print(OB);
1069 OB += "::friend ";
1070 Name->print(OB);
1074 struct ModuleName : Node {
1075 ModuleName *Parent;
1076 Node *Name;
1077 bool IsPartition;
1079 ModuleName(ModuleName *Parent_, Node *Name_, bool IsPartition_ = false)
1080 : Node(KModuleName), Parent(Parent_), Name(Name_),
1081 IsPartition(IsPartition_) {}
1083 template <typename Fn> void match(Fn F) const {
1084 F(Parent, Name, IsPartition);
1087 void printLeft(OutputBuffer &OB) const override {
1088 if (Parent)
1089 Parent->print(OB);
1090 if (Parent || IsPartition)
1091 OB += IsPartition ? ':' : '.';
1092 Name->print(OB);
1096 struct ModuleEntity : Node {
1097 ModuleName *Module;
1098 Node *Name;
1100 ModuleEntity(ModuleName *Module_, Node *Name_)
1101 : Node(KModuleEntity), Module(Module_), Name(Name_) {}
1103 template <typename Fn> void match(Fn F) const { F(Module, Name); }
1105 std::string_view getBaseName() const override { return Name->getBaseName(); }
1107 void printLeft(OutputBuffer &OB) const override {
1108 Name->print(OB);
1109 OB += '@';
1110 Module->print(OB);
1114 struct LocalName : Node {
1115 Node *Encoding;
1116 Node *Entity;
1118 LocalName(Node *Encoding_, Node *Entity_)
1119 : Node(KLocalName), Encoding(Encoding_), Entity(Entity_) {}
1121 template<typename Fn> void match(Fn F) const { F(Encoding, Entity); }
1123 void printLeft(OutputBuffer &OB) const override {
1124 Encoding->print(OB);
1125 OB += "::";
1126 Entity->print(OB);
1130 class QualifiedName final : public Node {
1131 // qualifier::name
1132 const Node *Qualifier;
1133 const Node *Name;
1135 public:
1136 QualifiedName(const Node *Qualifier_, const Node *Name_)
1137 : Node(KQualifiedName), Qualifier(Qualifier_), Name(Name_) {}
1139 template<typename Fn> void match(Fn F) const { F(Qualifier, Name); }
1141 std::string_view getBaseName() const override { return Name->getBaseName(); }
1143 void printLeft(OutputBuffer &OB) const override {
1144 Qualifier->print(OB);
1145 OB += "::";
1146 Name->print(OB);
1150 class VectorType final : public Node {
1151 const Node *BaseType;
1152 const Node *Dimension;
1154 public:
1155 VectorType(const Node *BaseType_, const Node *Dimension_)
1156 : Node(KVectorType), BaseType(BaseType_), Dimension(Dimension_) {}
1158 const Node *getBaseType() const { return BaseType; }
1159 const Node *getDimension() const { return Dimension; }
1161 template<typename Fn> void match(Fn F) const { F(BaseType, Dimension); }
1163 void printLeft(OutputBuffer &OB) const override {
1164 BaseType->print(OB);
1165 OB += " vector[";
1166 if (Dimension)
1167 Dimension->print(OB);
1168 OB += "]";
1172 class PixelVectorType final : public Node {
1173 const Node *Dimension;
1175 public:
1176 PixelVectorType(const Node *Dimension_)
1177 : Node(KPixelVectorType), Dimension(Dimension_) {}
1179 template<typename Fn> void match(Fn F) const { F(Dimension); }
1181 void printLeft(OutputBuffer &OB) const override {
1182 // FIXME: This should demangle as "vector pixel".
1183 OB += "pixel vector[";
1184 Dimension->print(OB);
1185 OB += "]";
1189 class BinaryFPType final : public Node {
1190 const Node *Dimension;
1192 public:
1193 BinaryFPType(const Node *Dimension_)
1194 : Node(KBinaryFPType), Dimension(Dimension_) {}
1196 template<typename Fn> void match(Fn F) const { F(Dimension); }
1198 void printLeft(OutputBuffer &OB) const override {
1199 OB += "_Float";
1200 Dimension->print(OB);
1204 enum class TemplateParamKind { Type, NonType, Template };
1206 /// An invented name for a template parameter for which we don't have a
1207 /// corresponding template argument.
1209 /// This node is created when parsing the <lambda-sig> for a lambda with
1210 /// explicit template arguments, which might be referenced in the parameter
1211 /// types appearing later in the <lambda-sig>.
1212 class SyntheticTemplateParamName final : public Node {
1213 TemplateParamKind Kind;
1214 unsigned Index;
1216 public:
1217 SyntheticTemplateParamName(TemplateParamKind Kind_, unsigned Index_)
1218 : Node(KSyntheticTemplateParamName), Kind(Kind_), Index(Index_) {}
1220 template<typename Fn> void match(Fn F) const { F(Kind, Index); }
1222 void printLeft(OutputBuffer &OB) const override {
1223 switch (Kind) {
1224 case TemplateParamKind::Type:
1225 OB += "$T";
1226 break;
1227 case TemplateParamKind::NonType:
1228 OB += "$N";
1229 break;
1230 case TemplateParamKind::Template:
1231 OB += "$TT";
1232 break;
1234 if (Index > 0)
1235 OB << Index - 1;
1239 class TemplateParamQualifiedArg final : public Node {
1240 Node *Param;
1241 Node *Arg;
1243 public:
1244 TemplateParamQualifiedArg(Node *Param_, Node *Arg_)
1245 : Node(KTemplateParamQualifiedArg), Param(Param_), Arg(Arg_) {}
1247 template <typename Fn> void match(Fn F) const { F(Param, Arg); }
1249 Node *getArg() { return Arg; }
1251 void printLeft(OutputBuffer &OB) const override {
1252 // Don't print Param to keep the output consistent.
1253 Arg->print(OB);
1257 /// A template type parameter declaration, 'typename T'.
1258 class TypeTemplateParamDecl final : public Node {
1259 Node *Name;
1261 public:
1262 TypeTemplateParamDecl(Node *Name_)
1263 : Node(KTypeTemplateParamDecl, Cache::Yes), Name(Name_) {}
1265 template<typename Fn> void match(Fn F) const { F(Name); }
1267 void printLeft(OutputBuffer &OB) const override { OB += "typename "; }
1269 void printRight(OutputBuffer &OB) const override { Name->print(OB); }
1272 /// A constrained template type parameter declaration, 'C<U> T'.
1273 class ConstrainedTypeTemplateParamDecl final : public Node {
1274 Node *Constraint;
1275 Node *Name;
1277 public:
1278 ConstrainedTypeTemplateParamDecl(Node *Constraint_, Node *Name_)
1279 : Node(KConstrainedTypeTemplateParamDecl, Cache::Yes),
1280 Constraint(Constraint_), Name(Name_) {}
1282 template<typename Fn> void match(Fn F) const { F(Constraint, Name); }
1284 void printLeft(OutputBuffer &OB) const override {
1285 Constraint->print(OB);
1286 OB += " ";
1289 void printRight(OutputBuffer &OB) const override { Name->print(OB); }
1292 /// A non-type template parameter declaration, 'int N'.
1293 class NonTypeTemplateParamDecl final : public Node {
1294 Node *Name;
1295 Node *Type;
1297 public:
1298 NonTypeTemplateParamDecl(Node *Name_, Node *Type_)
1299 : Node(KNonTypeTemplateParamDecl, Cache::Yes), Name(Name_), Type(Type_) {}
1301 template<typename Fn> void match(Fn F) const { F(Name, Type); }
1303 void printLeft(OutputBuffer &OB) const override {
1304 Type->printLeft(OB);
1305 if (!Type->hasRHSComponent(OB))
1306 OB += " ";
1309 void printRight(OutputBuffer &OB) const override {
1310 Name->print(OB);
1311 Type->printRight(OB);
1315 /// A template template parameter declaration,
1316 /// 'template<typename T> typename N'.
1317 class TemplateTemplateParamDecl final : public Node {
1318 Node *Name;
1319 NodeArray Params;
1320 Node *Requires;
1322 public:
1323 TemplateTemplateParamDecl(Node *Name_, NodeArray Params_, Node *Requires_)
1324 : Node(KTemplateTemplateParamDecl, Cache::Yes), Name(Name_),
1325 Params(Params_), Requires(Requires_) {}
1327 template <typename Fn> void match(Fn F) const { F(Name, Params, Requires); }
1329 void printLeft(OutputBuffer &OB) const override {
1330 ScopedOverride<unsigned> LT(OB.GtIsGt, 0);
1331 OB += "template<";
1332 Params.printWithComma(OB);
1333 OB += "> typename ";
1336 void printRight(OutputBuffer &OB) const override {
1337 Name->print(OB);
1338 if (Requires != nullptr) {
1339 OB += " requires ";
1340 Requires->print(OB);
1345 /// A template parameter pack declaration, 'typename ...T'.
1346 class TemplateParamPackDecl final : public Node {
1347 Node *Param;
1349 public:
1350 TemplateParamPackDecl(Node *Param_)
1351 : Node(KTemplateParamPackDecl, Cache::Yes), Param(Param_) {}
1353 template<typename Fn> void match(Fn F) const { F(Param); }
1355 void printLeft(OutputBuffer &OB) const override {
1356 Param->printLeft(OB);
1357 OB += "...";
1360 void printRight(OutputBuffer &OB) const override { Param->printRight(OB); }
1363 /// An unexpanded parameter pack (either in the expression or type context). If
1364 /// this AST is correct, this node will have a ParameterPackExpansion node above
1365 /// it.
1367 /// This node is created when some <template-args> are found that apply to an
1368 /// <encoding>, and is stored in the TemplateParams table. In order for this to
1369 /// appear in the final AST, it has to referenced via a <template-param> (ie,
1370 /// T_).
1371 class ParameterPack final : public Node {
1372 NodeArray Data;
1374 // Setup OutputBuffer for a pack expansion, unless we're already expanding
1375 // one.
1376 void initializePackExpansion(OutputBuffer &OB) const {
1377 if (OB.CurrentPackMax == std::numeric_limits<unsigned>::max()) {
1378 OB.CurrentPackMax = static_cast<unsigned>(Data.size());
1379 OB.CurrentPackIndex = 0;
1383 public:
1384 ParameterPack(NodeArray Data_) : Node(KParameterPack), Data(Data_) {
1385 ArrayCache = FunctionCache = RHSComponentCache = Cache::Unknown;
1386 if (std::all_of(Data.begin(), Data.end(), [](Node* P) {
1387 return P->ArrayCache == Cache::No;
1389 ArrayCache = Cache::No;
1390 if (std::all_of(Data.begin(), Data.end(), [](Node* P) {
1391 return P->FunctionCache == Cache::No;
1393 FunctionCache = Cache::No;
1394 if (std::all_of(Data.begin(), Data.end(), [](Node* P) {
1395 return P->RHSComponentCache == Cache::No;
1397 RHSComponentCache = Cache::No;
1400 template<typename Fn> void match(Fn F) const { F(Data); }
1402 bool hasRHSComponentSlow(OutputBuffer &OB) const override {
1403 initializePackExpansion(OB);
1404 size_t Idx = OB.CurrentPackIndex;
1405 return Idx < Data.size() && Data[Idx]->hasRHSComponent(OB);
1407 bool hasArraySlow(OutputBuffer &OB) const override {
1408 initializePackExpansion(OB);
1409 size_t Idx = OB.CurrentPackIndex;
1410 return Idx < Data.size() && Data[Idx]->hasArray(OB);
1412 bool hasFunctionSlow(OutputBuffer &OB) const override {
1413 initializePackExpansion(OB);
1414 size_t Idx = OB.CurrentPackIndex;
1415 return Idx < Data.size() && Data[Idx]->hasFunction(OB);
1417 const Node *getSyntaxNode(OutputBuffer &OB) const override {
1418 initializePackExpansion(OB);
1419 size_t Idx = OB.CurrentPackIndex;
1420 return Idx < Data.size() ? Data[Idx]->getSyntaxNode(OB) : this;
1423 void printLeft(OutputBuffer &OB) const override {
1424 initializePackExpansion(OB);
1425 size_t Idx = OB.CurrentPackIndex;
1426 if (Idx < Data.size())
1427 Data[Idx]->printLeft(OB);
1429 void printRight(OutputBuffer &OB) const override {
1430 initializePackExpansion(OB);
1431 size_t Idx = OB.CurrentPackIndex;
1432 if (Idx < Data.size())
1433 Data[Idx]->printRight(OB);
1437 /// A variadic template argument. This node represents an occurrence of
1438 /// J<something>E in some <template-args>. It isn't itself unexpanded, unless
1439 /// one of its Elements is. The parser inserts a ParameterPack into the
1440 /// TemplateParams table if the <template-args> this pack belongs to apply to an
1441 /// <encoding>.
1442 class TemplateArgumentPack final : public Node {
1443 NodeArray Elements;
1444 public:
1445 TemplateArgumentPack(NodeArray Elements_)
1446 : Node(KTemplateArgumentPack), Elements(Elements_) {}
1448 template<typename Fn> void match(Fn F) const { F(Elements); }
1450 NodeArray getElements() const { return Elements; }
1452 void printLeft(OutputBuffer &OB) const override {
1453 Elements.printWithComma(OB);
1457 /// A pack expansion. Below this node, there are some unexpanded ParameterPacks
1458 /// which each have Child->ParameterPackSize elements.
1459 class ParameterPackExpansion final : public Node {
1460 const Node *Child;
1462 public:
1463 ParameterPackExpansion(const Node *Child_)
1464 : Node(KParameterPackExpansion), Child(Child_) {}
1466 template<typename Fn> void match(Fn F) const { F(Child); }
1468 const Node *getChild() const { return Child; }
1470 void printLeft(OutputBuffer &OB) const override {
1471 constexpr unsigned Max = std::numeric_limits<unsigned>::max();
1472 ScopedOverride<unsigned> SavePackIdx(OB.CurrentPackIndex, Max);
1473 ScopedOverride<unsigned> SavePackMax(OB.CurrentPackMax, Max);
1474 size_t StreamPos = OB.getCurrentPosition();
1476 // Print the first element in the pack. If Child contains a ParameterPack,
1477 // it will set up S.CurrentPackMax and print the first element.
1478 Child->print(OB);
1480 // No ParameterPack was found in Child. This can occur if we've found a pack
1481 // expansion on a <function-param>.
1482 if (OB.CurrentPackMax == Max) {
1483 OB += "...";
1484 return;
1487 // We found a ParameterPack, but it has no elements. Erase whatever we may
1488 // of printed.
1489 if (OB.CurrentPackMax == 0) {
1490 OB.setCurrentPosition(StreamPos);
1491 return;
1494 // Else, iterate through the rest of the elements in the pack.
1495 for (unsigned I = 1, E = OB.CurrentPackMax; I < E; ++I) {
1496 OB += ", ";
1497 OB.CurrentPackIndex = I;
1498 Child->print(OB);
1503 class TemplateArgs final : public Node {
1504 NodeArray Params;
1505 Node *Requires;
1507 public:
1508 TemplateArgs(NodeArray Params_, Node *Requires_)
1509 : Node(KTemplateArgs), Params(Params_), Requires(Requires_) {}
1511 template<typename Fn> void match(Fn F) const { F(Params, Requires); }
1513 NodeArray getParams() { return Params; }
1515 void printLeft(OutputBuffer &OB) const override {
1516 ScopedOverride<unsigned> LT(OB.GtIsGt, 0);
1517 OB += "<";
1518 Params.printWithComma(OB);
1519 OB += ">";
1520 // Don't print the requires clause to keep the output simple.
1524 /// A forward-reference to a template argument that was not known at the point
1525 /// where the template parameter name was parsed in a mangling.
1527 /// This is created when demangling the name of a specialization of a
1528 /// conversion function template:
1530 /// \code
1531 /// struct A {
1532 /// template<typename T> operator T*();
1533 /// };
1534 /// \endcode
1536 /// When demangling a specialization of the conversion function template, we
1537 /// encounter the name of the template (including the \c T) before we reach
1538 /// the template argument list, so we cannot substitute the parameter name
1539 /// for the corresponding argument while parsing. Instead, we create a
1540 /// \c ForwardTemplateReference node that is resolved after we parse the
1541 /// template arguments.
1542 struct ForwardTemplateReference : Node {
1543 size_t Index;
1544 Node *Ref = nullptr;
1546 // If we're currently printing this node. It is possible (though invalid) for
1547 // a forward template reference to refer to itself via a substitution. This
1548 // creates a cyclic AST, which will stack overflow printing. To fix this, bail
1549 // out if more than one print* function is active.
1550 mutable bool Printing = false;
1552 ForwardTemplateReference(size_t Index_)
1553 : Node(KForwardTemplateReference, Cache::Unknown, Cache::Unknown,
1554 Cache::Unknown),
1555 Index(Index_) {}
1557 // We don't provide a matcher for these, because the value of the node is
1558 // not determined by its construction parameters, and it generally needs
1559 // special handling.
1560 template<typename Fn> void match(Fn F) const = delete;
1562 bool hasRHSComponentSlow(OutputBuffer &OB) const override {
1563 if (Printing)
1564 return false;
1565 ScopedOverride<bool> SavePrinting(Printing, true);
1566 return Ref->hasRHSComponent(OB);
1568 bool hasArraySlow(OutputBuffer &OB) const override {
1569 if (Printing)
1570 return false;
1571 ScopedOverride<bool> SavePrinting(Printing, true);
1572 return Ref->hasArray(OB);
1574 bool hasFunctionSlow(OutputBuffer &OB) const override {
1575 if (Printing)
1576 return false;
1577 ScopedOverride<bool> SavePrinting(Printing, true);
1578 return Ref->hasFunction(OB);
1580 const Node *getSyntaxNode(OutputBuffer &OB) const override {
1581 if (Printing)
1582 return this;
1583 ScopedOverride<bool> SavePrinting(Printing, true);
1584 return Ref->getSyntaxNode(OB);
1587 void printLeft(OutputBuffer &OB) const override {
1588 if (Printing)
1589 return;
1590 ScopedOverride<bool> SavePrinting(Printing, true);
1591 Ref->printLeft(OB);
1593 void printRight(OutputBuffer &OB) const override {
1594 if (Printing)
1595 return;
1596 ScopedOverride<bool> SavePrinting(Printing, true);
1597 Ref->printRight(OB);
1601 struct NameWithTemplateArgs : Node {
1602 // name<template_args>
1603 Node *Name;
1604 Node *TemplateArgs;
1606 NameWithTemplateArgs(Node *Name_, Node *TemplateArgs_)
1607 : Node(KNameWithTemplateArgs), Name(Name_), TemplateArgs(TemplateArgs_) {}
1609 template<typename Fn> void match(Fn F) const { F(Name, TemplateArgs); }
1611 std::string_view getBaseName() const override { return Name->getBaseName(); }
1613 void printLeft(OutputBuffer &OB) const override {
1614 Name->print(OB);
1615 TemplateArgs->print(OB);
1619 class GlobalQualifiedName final : public Node {
1620 Node *Child;
1622 public:
1623 GlobalQualifiedName(Node* Child_)
1624 : Node(KGlobalQualifiedName), Child(Child_) {}
1626 template<typename Fn> void match(Fn F) const { F(Child); }
1628 std::string_view getBaseName() const override { return Child->getBaseName(); }
1630 void printLeft(OutputBuffer &OB) const override {
1631 OB += "::";
1632 Child->print(OB);
1636 enum class SpecialSubKind {
1637 allocator,
1638 basic_string,
1639 string,
1640 istream,
1641 ostream,
1642 iostream,
1645 class SpecialSubstitution;
1646 class ExpandedSpecialSubstitution : public Node {
1647 protected:
1648 SpecialSubKind SSK;
1650 ExpandedSpecialSubstitution(SpecialSubKind SSK_, Kind K_)
1651 : Node(K_), SSK(SSK_) {}
1652 public:
1653 ExpandedSpecialSubstitution(SpecialSubKind SSK_)
1654 : ExpandedSpecialSubstitution(SSK_, KExpandedSpecialSubstitution) {}
1655 inline ExpandedSpecialSubstitution(SpecialSubstitution const *);
1657 template<typename Fn> void match(Fn F) const { F(SSK); }
1659 protected:
1660 bool isInstantiation() const {
1661 return unsigned(SSK) >= unsigned(SpecialSubKind::string);
1664 std::string_view getBaseName() const override {
1665 switch (SSK) {
1666 case SpecialSubKind::allocator:
1667 return {"allocator"};
1668 case SpecialSubKind::basic_string:
1669 return {"basic_string"};
1670 case SpecialSubKind::string:
1671 return {"basic_string"};
1672 case SpecialSubKind::istream:
1673 return {"basic_istream"};
1674 case SpecialSubKind::ostream:
1675 return {"basic_ostream"};
1676 case SpecialSubKind::iostream:
1677 return {"basic_iostream"};
1679 DEMANGLE_UNREACHABLE;
1682 private:
1683 void printLeft(OutputBuffer &OB) const override {
1684 OB << "std::" << getBaseName();
1685 if (isInstantiation()) {
1686 OB << "<char, std::char_traits<char>";
1687 if (SSK == SpecialSubKind::string)
1688 OB << ", std::allocator<char>";
1689 OB << ">";
1694 class SpecialSubstitution final : public ExpandedSpecialSubstitution {
1695 public:
1696 SpecialSubstitution(SpecialSubKind SSK_)
1697 : ExpandedSpecialSubstitution(SSK_, KSpecialSubstitution) {}
1699 template<typename Fn> void match(Fn F) const { F(SSK); }
1701 std::string_view getBaseName() const override {
1702 std::string_view SV = ExpandedSpecialSubstitution::getBaseName();
1703 if (isInstantiation()) {
1704 // The instantiations are typedefs that drop the "basic_" prefix.
1705 DEMANGLE_ASSERT(starts_with(SV, "basic_"), "");
1706 SV.remove_prefix(sizeof("basic_") - 1);
1708 return SV;
1711 void printLeft(OutputBuffer &OB) const override {
1712 OB << "std::" << getBaseName();
1716 inline ExpandedSpecialSubstitution::ExpandedSpecialSubstitution(
1717 SpecialSubstitution const *SS)
1718 : ExpandedSpecialSubstitution(SS->SSK) {}
1720 class CtorDtorName final : public Node {
1721 const Node *Basename;
1722 const bool IsDtor;
1723 const int Variant;
1725 public:
1726 CtorDtorName(const Node *Basename_, bool IsDtor_, int Variant_)
1727 : Node(KCtorDtorName), Basename(Basename_), IsDtor(IsDtor_),
1728 Variant(Variant_) {}
1730 template<typename Fn> void match(Fn F) const { F(Basename, IsDtor, Variant); }
1732 void printLeft(OutputBuffer &OB) const override {
1733 if (IsDtor)
1734 OB += "~";
1735 OB += Basename->getBaseName();
1739 class DtorName : public Node {
1740 const Node *Base;
1742 public:
1743 DtorName(const Node *Base_) : Node(KDtorName), Base(Base_) {}
1745 template<typename Fn> void match(Fn F) const { F(Base); }
1747 void printLeft(OutputBuffer &OB) const override {
1748 OB += "~";
1749 Base->printLeft(OB);
1753 class UnnamedTypeName : public Node {
1754 const std::string_view Count;
1756 public:
1757 UnnamedTypeName(std::string_view Count_)
1758 : Node(KUnnamedTypeName), Count(Count_) {}
1760 template<typename Fn> void match(Fn F) const { F(Count); }
1762 void printLeft(OutputBuffer &OB) const override {
1763 OB += "'unnamed";
1764 OB += Count;
1765 OB += "\'";
1769 class ClosureTypeName : public Node {
1770 NodeArray TemplateParams;
1771 const Node *Requires1;
1772 NodeArray Params;
1773 const Node *Requires2;
1774 std::string_view Count;
1776 public:
1777 ClosureTypeName(NodeArray TemplateParams_, const Node *Requires1_,
1778 NodeArray Params_, const Node *Requires2_,
1779 std::string_view Count_)
1780 : Node(KClosureTypeName), TemplateParams(TemplateParams_),
1781 Requires1(Requires1_), Params(Params_), Requires2(Requires2_),
1782 Count(Count_) {}
1784 template<typename Fn> void match(Fn F) const {
1785 F(TemplateParams, Requires1, Params, Requires2, Count);
1788 void printDeclarator(OutputBuffer &OB) const {
1789 if (!TemplateParams.empty()) {
1790 ScopedOverride<unsigned> LT(OB.GtIsGt, 0);
1791 OB += "<";
1792 TemplateParams.printWithComma(OB);
1793 OB += ">";
1795 if (Requires1 != nullptr) {
1796 OB += " requires ";
1797 Requires1->print(OB);
1798 OB += " ";
1800 OB.printOpen();
1801 Params.printWithComma(OB);
1802 OB.printClose();
1803 if (Requires2 != nullptr) {
1804 OB += " requires ";
1805 Requires2->print(OB);
1809 void printLeft(OutputBuffer &OB) const override {
1810 // FIXME: This demangling is not particularly readable.
1811 OB += "\'lambda";
1812 OB += Count;
1813 OB += "\'";
1814 printDeclarator(OB);
1818 class StructuredBindingName : public Node {
1819 NodeArray Bindings;
1820 public:
1821 StructuredBindingName(NodeArray Bindings_)
1822 : Node(KStructuredBindingName), Bindings(Bindings_) {}
1824 template<typename Fn> void match(Fn F) const { F(Bindings); }
1826 void printLeft(OutputBuffer &OB) const override {
1827 OB.printOpen('[');
1828 Bindings.printWithComma(OB);
1829 OB.printClose(']');
1833 // -- Expression Nodes --
1835 class BinaryExpr : public Node {
1836 const Node *LHS;
1837 const std::string_view InfixOperator;
1838 const Node *RHS;
1840 public:
1841 BinaryExpr(const Node *LHS_, std::string_view InfixOperator_,
1842 const Node *RHS_, Prec Prec_)
1843 : Node(KBinaryExpr, Prec_), LHS(LHS_), InfixOperator(InfixOperator_),
1844 RHS(RHS_) {}
1846 template <typename Fn> void match(Fn F) const {
1847 F(LHS, InfixOperator, RHS, getPrecedence());
1850 void printLeft(OutputBuffer &OB) const override {
1851 bool ParenAll = OB.isGtInsideTemplateArgs() &&
1852 (InfixOperator == ">" || InfixOperator == ">>");
1853 if (ParenAll)
1854 OB.printOpen();
1855 // Assignment is right associative, with special LHS precedence.
1856 bool IsAssign = getPrecedence() == Prec::Assign;
1857 LHS->printAsOperand(OB, IsAssign ? Prec::OrIf : getPrecedence(), !IsAssign);
1858 // No space before comma operator
1859 if (!(InfixOperator == ","))
1860 OB += " ";
1861 OB += InfixOperator;
1862 OB += " ";
1863 RHS->printAsOperand(OB, getPrecedence(), IsAssign);
1864 if (ParenAll)
1865 OB.printClose();
1869 class ArraySubscriptExpr : public Node {
1870 const Node *Op1;
1871 const Node *Op2;
1873 public:
1874 ArraySubscriptExpr(const Node *Op1_, const Node *Op2_, Prec Prec_)
1875 : Node(KArraySubscriptExpr, Prec_), Op1(Op1_), Op2(Op2_) {}
1877 template <typename Fn> void match(Fn F) const {
1878 F(Op1, Op2, getPrecedence());
1881 void printLeft(OutputBuffer &OB) const override {
1882 Op1->printAsOperand(OB, getPrecedence());
1883 OB.printOpen('[');
1884 Op2->printAsOperand(OB);
1885 OB.printClose(']');
1889 class PostfixExpr : public Node {
1890 const Node *Child;
1891 const std::string_view Operator;
1893 public:
1894 PostfixExpr(const Node *Child_, std::string_view Operator_, Prec Prec_)
1895 : Node(KPostfixExpr, Prec_), Child(Child_), Operator(Operator_) {}
1897 template <typename Fn> void match(Fn F) const {
1898 F(Child, Operator, getPrecedence());
1901 void printLeft(OutputBuffer &OB) const override {
1902 Child->printAsOperand(OB, getPrecedence(), true);
1903 OB += Operator;
1907 class ConditionalExpr : public Node {
1908 const Node *Cond;
1909 const Node *Then;
1910 const Node *Else;
1912 public:
1913 ConditionalExpr(const Node *Cond_, const Node *Then_, const Node *Else_,
1914 Prec Prec_)
1915 : Node(KConditionalExpr, Prec_), Cond(Cond_), Then(Then_), Else(Else_) {}
1917 template <typename Fn> void match(Fn F) const {
1918 F(Cond, Then, Else, getPrecedence());
1921 void printLeft(OutputBuffer &OB) const override {
1922 Cond->printAsOperand(OB, getPrecedence());
1923 OB += " ? ";
1924 Then->printAsOperand(OB);
1925 OB += " : ";
1926 Else->printAsOperand(OB, Prec::Assign, true);
1930 class MemberExpr : public Node {
1931 const Node *LHS;
1932 const std::string_view Kind;
1933 const Node *RHS;
1935 public:
1936 MemberExpr(const Node *LHS_, std::string_view Kind_, const Node *RHS_,
1937 Prec Prec_)
1938 : Node(KMemberExpr, Prec_), LHS(LHS_), Kind(Kind_), RHS(RHS_) {}
1940 template <typename Fn> void match(Fn F) const {
1941 F(LHS, Kind, RHS, getPrecedence());
1944 void printLeft(OutputBuffer &OB) const override {
1945 LHS->printAsOperand(OB, getPrecedence(), true);
1946 OB += Kind;
1947 RHS->printAsOperand(OB, getPrecedence(), false);
1951 class SubobjectExpr : public Node {
1952 const Node *Type;
1953 const Node *SubExpr;
1954 std::string_view Offset;
1955 NodeArray UnionSelectors;
1956 bool OnePastTheEnd;
1958 public:
1959 SubobjectExpr(const Node *Type_, const Node *SubExpr_,
1960 std::string_view Offset_, NodeArray UnionSelectors_,
1961 bool OnePastTheEnd_)
1962 : Node(KSubobjectExpr), Type(Type_), SubExpr(SubExpr_), Offset(Offset_),
1963 UnionSelectors(UnionSelectors_), OnePastTheEnd(OnePastTheEnd_) {}
1965 template<typename Fn> void match(Fn F) const {
1966 F(Type, SubExpr, Offset, UnionSelectors, OnePastTheEnd);
1969 void printLeft(OutputBuffer &OB) const override {
1970 SubExpr->print(OB);
1971 OB += ".<";
1972 Type->print(OB);
1973 OB += " at offset ";
1974 if (Offset.empty()) {
1975 OB += "0";
1976 } else if (Offset[0] == 'n') {
1977 OB += "-";
1978 OB += std::string_view(Offset.data() + 1, Offset.size() - 1);
1979 } else {
1980 OB += Offset;
1982 OB += ">";
1986 class EnclosingExpr : public Node {
1987 const std::string_view Prefix;
1988 const Node *Infix;
1989 const std::string_view Postfix;
1991 public:
1992 EnclosingExpr(std::string_view Prefix_, const Node *Infix_,
1993 Prec Prec_ = Prec::Primary)
1994 : Node(KEnclosingExpr, Prec_), Prefix(Prefix_), Infix(Infix_) {}
1996 template <typename Fn> void match(Fn F) const {
1997 F(Prefix, Infix, getPrecedence());
2000 void printLeft(OutputBuffer &OB) const override {
2001 OB += Prefix;
2002 OB.printOpen();
2003 Infix->print(OB);
2004 OB.printClose();
2005 OB += Postfix;
2009 class CastExpr : public Node {
2010 // cast_kind<to>(from)
2011 const std::string_view CastKind;
2012 const Node *To;
2013 const Node *From;
2015 public:
2016 CastExpr(std::string_view CastKind_, const Node *To_, const Node *From_,
2017 Prec Prec_)
2018 : Node(KCastExpr, Prec_), CastKind(CastKind_), To(To_), From(From_) {}
2020 template <typename Fn> void match(Fn F) const {
2021 F(CastKind, To, From, getPrecedence());
2024 void printLeft(OutputBuffer &OB) const override {
2025 OB += CastKind;
2027 ScopedOverride<unsigned> LT(OB.GtIsGt, 0);
2028 OB += "<";
2029 To->printLeft(OB);
2030 OB += ">";
2032 OB.printOpen();
2033 From->printAsOperand(OB);
2034 OB.printClose();
2038 class SizeofParamPackExpr : public Node {
2039 const Node *Pack;
2041 public:
2042 SizeofParamPackExpr(const Node *Pack_)
2043 : Node(KSizeofParamPackExpr), Pack(Pack_) {}
2045 template<typename Fn> void match(Fn F) const { F(Pack); }
2047 void printLeft(OutputBuffer &OB) const override {
2048 OB += "sizeof...";
2049 OB.printOpen();
2050 ParameterPackExpansion PPE(Pack);
2051 PPE.printLeft(OB);
2052 OB.printClose();
2056 class CallExpr : public Node {
2057 const Node *Callee;
2058 NodeArray Args;
2060 public:
2061 CallExpr(const Node *Callee_, NodeArray Args_, Prec Prec_)
2062 : Node(KCallExpr, Prec_), Callee(Callee_), Args(Args_) {}
2064 template <typename Fn> void match(Fn F) const {
2065 F(Callee, Args, getPrecedence());
2068 void printLeft(OutputBuffer &OB) const override {
2069 Callee->print(OB);
2070 OB.printOpen();
2071 Args.printWithComma(OB);
2072 OB.printClose();
2076 class NewExpr : public Node {
2077 // new (expr_list) type(init_list)
2078 NodeArray ExprList;
2079 Node *Type;
2080 NodeArray InitList;
2081 bool IsGlobal; // ::operator new ?
2082 bool IsArray; // new[] ?
2083 public:
2084 NewExpr(NodeArray ExprList_, Node *Type_, NodeArray InitList_, bool IsGlobal_,
2085 bool IsArray_, Prec Prec_)
2086 : Node(KNewExpr, Prec_), ExprList(ExprList_), Type(Type_),
2087 InitList(InitList_), IsGlobal(IsGlobal_), IsArray(IsArray_) {}
2089 template<typename Fn> void match(Fn F) const {
2090 F(ExprList, Type, InitList, IsGlobal, IsArray, getPrecedence());
2093 void printLeft(OutputBuffer &OB) const override {
2094 if (IsGlobal)
2095 OB += "::";
2096 OB += "new";
2097 if (IsArray)
2098 OB += "[]";
2099 if (!ExprList.empty()) {
2100 OB.printOpen();
2101 ExprList.printWithComma(OB);
2102 OB.printClose();
2104 OB += " ";
2105 Type->print(OB);
2106 if (!InitList.empty()) {
2107 OB.printOpen();
2108 InitList.printWithComma(OB);
2109 OB.printClose();
2114 class DeleteExpr : public Node {
2115 Node *Op;
2116 bool IsGlobal;
2117 bool IsArray;
2119 public:
2120 DeleteExpr(Node *Op_, bool IsGlobal_, bool IsArray_, Prec Prec_)
2121 : Node(KDeleteExpr, Prec_), Op(Op_), IsGlobal(IsGlobal_),
2122 IsArray(IsArray_) {}
2124 template <typename Fn> void match(Fn F) const {
2125 F(Op, IsGlobal, IsArray, getPrecedence());
2128 void printLeft(OutputBuffer &OB) const override {
2129 if (IsGlobal)
2130 OB += "::";
2131 OB += "delete";
2132 if (IsArray)
2133 OB += "[]";
2134 OB += ' ';
2135 Op->print(OB);
2139 class PrefixExpr : public Node {
2140 std::string_view Prefix;
2141 Node *Child;
2143 public:
2144 PrefixExpr(std::string_view Prefix_, Node *Child_, Prec Prec_)
2145 : Node(KPrefixExpr, Prec_), Prefix(Prefix_), Child(Child_) {}
2147 template <typename Fn> void match(Fn F) const {
2148 F(Prefix, Child, getPrecedence());
2151 void printLeft(OutputBuffer &OB) const override {
2152 OB += Prefix;
2153 Child->printAsOperand(OB, getPrecedence());
2157 class FunctionParam : public Node {
2158 std::string_view Number;
2160 public:
2161 FunctionParam(std::string_view Number_)
2162 : Node(KFunctionParam), Number(Number_) {}
2164 template<typename Fn> void match(Fn F) const { F(Number); }
2166 void printLeft(OutputBuffer &OB) const override {
2167 OB += "fp";
2168 OB += Number;
2172 class ConversionExpr : public Node {
2173 const Node *Type;
2174 NodeArray Expressions;
2176 public:
2177 ConversionExpr(const Node *Type_, NodeArray Expressions_, Prec Prec_)
2178 : Node(KConversionExpr, Prec_), Type(Type_), Expressions(Expressions_) {}
2180 template <typename Fn> void match(Fn F) const {
2181 F(Type, Expressions, getPrecedence());
2184 void printLeft(OutputBuffer &OB) const override {
2185 OB.printOpen();
2186 Type->print(OB);
2187 OB.printClose();
2188 OB.printOpen();
2189 Expressions.printWithComma(OB);
2190 OB.printClose();
2194 class PointerToMemberConversionExpr : public Node {
2195 const Node *Type;
2196 const Node *SubExpr;
2197 std::string_view Offset;
2199 public:
2200 PointerToMemberConversionExpr(const Node *Type_, const Node *SubExpr_,
2201 std::string_view Offset_, Prec Prec_)
2202 : Node(KPointerToMemberConversionExpr, Prec_), Type(Type_),
2203 SubExpr(SubExpr_), Offset(Offset_) {}
2205 template <typename Fn> void match(Fn F) const {
2206 F(Type, SubExpr, Offset, getPrecedence());
2209 void printLeft(OutputBuffer &OB) const override {
2210 OB.printOpen();
2211 Type->print(OB);
2212 OB.printClose();
2213 OB.printOpen();
2214 SubExpr->print(OB);
2215 OB.printClose();
2219 class InitListExpr : public Node {
2220 const Node *Ty;
2221 NodeArray Inits;
2222 public:
2223 InitListExpr(const Node *Ty_, NodeArray Inits_)
2224 : Node(KInitListExpr), Ty(Ty_), Inits(Inits_) {}
2226 template<typename Fn> void match(Fn F) const { F(Ty, Inits); }
2228 void printLeft(OutputBuffer &OB) const override {
2229 if (Ty)
2230 Ty->print(OB);
2231 OB += '{';
2232 Inits.printWithComma(OB);
2233 OB += '}';
2237 class BracedExpr : public Node {
2238 const Node *Elem;
2239 const Node *Init;
2240 bool IsArray;
2241 public:
2242 BracedExpr(const Node *Elem_, const Node *Init_, bool IsArray_)
2243 : Node(KBracedExpr), Elem(Elem_), Init(Init_), IsArray(IsArray_) {}
2245 template<typename Fn> void match(Fn F) const { F(Elem, Init, IsArray); }
2247 void printLeft(OutputBuffer &OB) const override {
2248 if (IsArray) {
2249 OB += '[';
2250 Elem->print(OB);
2251 OB += ']';
2252 } else {
2253 OB += '.';
2254 Elem->print(OB);
2256 if (Init->getKind() != KBracedExpr && Init->getKind() != KBracedRangeExpr)
2257 OB += " = ";
2258 Init->print(OB);
2262 class BracedRangeExpr : public Node {
2263 const Node *First;
2264 const Node *Last;
2265 const Node *Init;
2266 public:
2267 BracedRangeExpr(const Node *First_, const Node *Last_, const Node *Init_)
2268 : Node(KBracedRangeExpr), First(First_), Last(Last_), Init(Init_) {}
2270 template<typename Fn> void match(Fn F) const { F(First, Last, Init); }
2272 void printLeft(OutputBuffer &OB) const override {
2273 OB += '[';
2274 First->print(OB);
2275 OB += " ... ";
2276 Last->print(OB);
2277 OB += ']';
2278 if (Init->getKind() != KBracedExpr && Init->getKind() != KBracedRangeExpr)
2279 OB += " = ";
2280 Init->print(OB);
2284 class FoldExpr : public Node {
2285 const Node *Pack, *Init;
2286 std::string_view OperatorName;
2287 bool IsLeftFold;
2289 public:
2290 FoldExpr(bool IsLeftFold_, std::string_view OperatorName_, const Node *Pack_,
2291 const Node *Init_)
2292 : Node(KFoldExpr), Pack(Pack_), Init(Init_), OperatorName(OperatorName_),
2293 IsLeftFold(IsLeftFold_) {}
2295 template<typename Fn> void match(Fn F) const {
2296 F(IsLeftFold, OperatorName, Pack, Init);
2299 void printLeft(OutputBuffer &OB) const override {
2300 auto PrintPack = [&] {
2301 OB.printOpen();
2302 ParameterPackExpansion(Pack).print(OB);
2303 OB.printClose();
2306 OB.printOpen();
2307 // Either '[init op ]... op pack' or 'pack op ...[ op init]'
2308 // Refactored to '[(init|pack) op ]...[ op (pack|init)]'
2309 // Fold expr operands are cast-expressions
2310 if (!IsLeftFold || Init != nullptr) {
2311 // '(init|pack) op '
2312 if (IsLeftFold)
2313 Init->printAsOperand(OB, Prec::Cast, true);
2314 else
2315 PrintPack();
2316 OB << " " << OperatorName << " ";
2318 OB << "...";
2319 if (IsLeftFold || Init != nullptr) {
2320 // ' op (init|pack)'
2321 OB << " " << OperatorName << " ";
2322 if (IsLeftFold)
2323 PrintPack();
2324 else
2325 Init->printAsOperand(OB, Prec::Cast, true);
2327 OB.printClose();
2331 class ThrowExpr : public Node {
2332 const Node *Op;
2334 public:
2335 ThrowExpr(const Node *Op_) : Node(KThrowExpr), Op(Op_) {}
2337 template<typename Fn> void match(Fn F) const { F(Op); }
2339 void printLeft(OutputBuffer &OB) const override {
2340 OB += "throw ";
2341 Op->print(OB);
2345 class BoolExpr : public Node {
2346 bool Value;
2348 public:
2349 BoolExpr(bool Value_) : Node(KBoolExpr), Value(Value_) {}
2351 template<typename Fn> void match(Fn F) const { F(Value); }
2353 void printLeft(OutputBuffer &OB) const override {
2354 OB += Value ? std::string_view("true") : std::string_view("false");
2358 class StringLiteral : public Node {
2359 const Node *Type;
2361 public:
2362 StringLiteral(const Node *Type_) : Node(KStringLiteral), Type(Type_) {}
2364 template<typename Fn> void match(Fn F) const { F(Type); }
2366 void printLeft(OutputBuffer &OB) const override {
2367 OB += "\"<";
2368 Type->print(OB);
2369 OB += ">\"";
2373 class LambdaExpr : public Node {
2374 const Node *Type;
2376 public:
2377 LambdaExpr(const Node *Type_) : Node(KLambdaExpr), Type(Type_) {}
2379 template<typename Fn> void match(Fn F) const { F(Type); }
2381 void printLeft(OutputBuffer &OB) const override {
2382 OB += "[]";
2383 if (Type->getKind() == KClosureTypeName)
2384 static_cast<const ClosureTypeName *>(Type)->printDeclarator(OB);
2385 OB += "{...}";
2389 class EnumLiteral : public Node {
2390 // ty(integer)
2391 const Node *Ty;
2392 std::string_view Integer;
2394 public:
2395 EnumLiteral(const Node *Ty_, std::string_view Integer_)
2396 : Node(KEnumLiteral), Ty(Ty_), Integer(Integer_) {}
2398 template<typename Fn> void match(Fn F) const { F(Ty, Integer); }
2400 void printLeft(OutputBuffer &OB) const override {
2401 OB.printOpen();
2402 Ty->print(OB);
2403 OB.printClose();
2405 if (Integer[0] == 'n')
2406 OB << '-' << std::string_view(Integer.data() + 1, Integer.size() - 1);
2407 else
2408 OB << Integer;
2412 class IntegerLiteral : public Node {
2413 std::string_view Type;
2414 std::string_view Value;
2416 public:
2417 IntegerLiteral(std::string_view Type_, std::string_view Value_)
2418 : Node(KIntegerLiteral), Type(Type_), Value(Value_) {}
2420 template<typename Fn> void match(Fn F) const { F(Type, Value); }
2422 void printLeft(OutputBuffer &OB) const override {
2423 if (Type.size() > 3) {
2424 OB.printOpen();
2425 OB += Type;
2426 OB.printClose();
2429 if (Value[0] == 'n')
2430 OB << '-' << std::string_view(Value.data() + 1, Value.size() - 1);
2431 else
2432 OB += Value;
2434 if (Type.size() <= 3)
2435 OB += Type;
2439 class RequiresExpr : public Node {
2440 NodeArray Parameters;
2441 NodeArray Requirements;
2442 public:
2443 RequiresExpr(NodeArray Parameters_, NodeArray Requirements_)
2444 : Node(KRequiresExpr), Parameters(Parameters_),
2445 Requirements(Requirements_) {}
2447 template<typename Fn> void match(Fn F) const { F(Parameters, Requirements); }
2449 void printLeft(OutputBuffer &OB) const override {
2450 OB += "requires";
2451 if (!Parameters.empty()) {
2452 OB += ' ';
2453 OB.printOpen();
2454 Parameters.printWithComma(OB);
2455 OB.printClose();
2457 OB += ' ';
2458 OB.printOpen('{');
2459 for (const Node *Req : Requirements) {
2460 Req->print(OB);
2462 OB += ' ';
2463 OB.printClose('}');
2467 class ExprRequirement : public Node {
2468 const Node *Expr;
2469 bool IsNoexcept;
2470 const Node *TypeConstraint;
2471 public:
2472 ExprRequirement(const Node *Expr_, bool IsNoexcept_,
2473 const Node *TypeConstraint_)
2474 : Node(KExprRequirement), Expr(Expr_), IsNoexcept(IsNoexcept_),
2475 TypeConstraint(TypeConstraint_) {}
2477 template <typename Fn> void match(Fn F) const {
2478 F(Expr, IsNoexcept, TypeConstraint);
2481 void printLeft(OutputBuffer &OB) const override {
2482 OB += " ";
2483 if (IsNoexcept || TypeConstraint)
2484 OB.printOpen('{');
2485 Expr->print(OB);
2486 if (IsNoexcept || TypeConstraint)
2487 OB.printClose('}');
2488 if (IsNoexcept)
2489 OB += " noexcept";
2490 if (TypeConstraint) {
2491 OB += " -> ";
2492 TypeConstraint->print(OB);
2494 OB += ';';
2498 class TypeRequirement : public Node {
2499 const Node *Type;
2500 public:
2501 TypeRequirement(const Node *Type_)
2502 : Node(KTypeRequirement), Type(Type_) {}
2504 template <typename Fn> void match(Fn F) const { F(Type); }
2506 void printLeft(OutputBuffer &OB) const override {
2507 OB += " typename ";
2508 Type->print(OB);
2509 OB += ';';
2513 class NestedRequirement : public Node {
2514 const Node *Constraint;
2515 public:
2516 NestedRequirement(const Node *Constraint_)
2517 : Node(KNestedRequirement), Constraint(Constraint_) {}
2519 template <typename Fn> void match(Fn F) const { F(Constraint); }
2521 void printLeft(OutputBuffer &OB) const override {
2522 OB += " requires ";
2523 Constraint->print(OB);
2524 OB += ';';
2528 template <class Float> struct FloatData;
2530 namespace float_literal_impl {
2531 constexpr Node::Kind getFloatLiteralKind(float *) {
2532 return Node::KFloatLiteral;
2534 constexpr Node::Kind getFloatLiteralKind(double *) {
2535 return Node::KDoubleLiteral;
2537 constexpr Node::Kind getFloatLiteralKind(long double *) {
2538 return Node::KLongDoubleLiteral;
2542 template <class Float> class FloatLiteralImpl : public Node {
2543 const std::string_view Contents;
2545 static constexpr Kind KindForClass =
2546 float_literal_impl::getFloatLiteralKind((Float *)nullptr);
2548 public:
2549 FloatLiteralImpl(std::string_view Contents_)
2550 : Node(KindForClass), Contents(Contents_) {}
2552 template<typename Fn> void match(Fn F) const { F(Contents); }
2554 void printLeft(OutputBuffer &OB) const override {
2555 const size_t N = FloatData<Float>::mangled_size;
2556 if (Contents.size() >= N) {
2557 union {
2558 Float value;
2559 char buf[sizeof(Float)];
2561 const char *t = Contents.data();
2562 const char *last = t + N;
2563 char *e = buf;
2564 for (; t != last; ++t, ++e) {
2565 unsigned d1 = isdigit(*t) ? static_cast<unsigned>(*t - '0')
2566 : static_cast<unsigned>(*t - 'a' + 10);
2567 ++t;
2568 unsigned d0 = isdigit(*t) ? static_cast<unsigned>(*t - '0')
2569 : static_cast<unsigned>(*t - 'a' + 10);
2570 *e = static_cast<char>((d1 << 4) + d0);
2572 #if __BYTE_ORDER__ == __ORDER_LITTLE_ENDIAN__
2573 std::reverse(buf, e);
2574 #endif
2575 char num[FloatData<Float>::max_demangled_size] = {0};
2576 int n = snprintf(num, sizeof(num), FloatData<Float>::spec, value);
2577 OB += std::string_view(num, n);
2582 using FloatLiteral = FloatLiteralImpl<float>;
2583 using DoubleLiteral = FloatLiteralImpl<double>;
2584 using LongDoubleLiteral = FloatLiteralImpl<long double>;
2586 /// Visit the node. Calls \c F(P), where \c P is the node cast to the
2587 /// appropriate derived class.
2588 template<typename Fn>
2589 void Node::visit(Fn F) const {
2590 switch (K) {
2591 #define NODE(X) \
2592 case K##X: \
2593 return F(static_cast<const X *>(this));
2594 #include "ItaniumNodes.def"
2596 DEMANGLE_ASSERT(0, "unknown mangling node kind");
2599 /// Determine the kind of a node from its type.
2600 template<typename NodeT> struct NodeKind;
2601 #define NODE(X) \
2602 template <> struct NodeKind<X> { \
2603 static constexpr Node::Kind Kind = Node::K##X; \
2604 static constexpr const char *name() { return #X; } \
2606 #include "ItaniumNodes.def"
2608 template <typename Derived, typename Alloc> struct AbstractManglingParser {
2609 const char *First;
2610 const char *Last;
2612 // Name stack, this is used by the parser to hold temporary names that were
2613 // parsed. The parser collapses multiple names into new nodes to construct
2614 // the AST. Once the parser is finished, names.size() == 1.
2615 PODSmallVector<Node *, 32> Names;
2617 // Substitution table. Itanium supports name substitutions as a means of
2618 // compression. The string "S42_" refers to the 44nd entry (base-36) in this
2619 // table.
2620 PODSmallVector<Node *, 32> Subs;
2622 // A list of template argument values corresponding to a template parameter
2623 // list.
2624 using TemplateParamList = PODSmallVector<Node *, 8>;
2626 class ScopedTemplateParamList {
2627 AbstractManglingParser *Parser;
2628 size_t OldNumTemplateParamLists;
2629 TemplateParamList Params;
2631 public:
2632 ScopedTemplateParamList(AbstractManglingParser *TheParser)
2633 : Parser(TheParser),
2634 OldNumTemplateParamLists(TheParser->TemplateParams.size()) {
2635 Parser->TemplateParams.push_back(&Params);
2637 ~ScopedTemplateParamList() {
2638 DEMANGLE_ASSERT(Parser->TemplateParams.size() >= OldNumTemplateParamLists,
2639 "");
2640 Parser->TemplateParams.shrinkToSize(OldNumTemplateParamLists);
2642 TemplateParamList *params() { return &Params; }
2645 // Template parameter table. Like the above, but referenced like "T42_".
2646 // This has a smaller size compared to Subs and Names because it can be
2647 // stored on the stack.
2648 TemplateParamList OuterTemplateParams;
2650 // Lists of template parameters indexed by template parameter depth,
2651 // referenced like "TL2_4_". If nonempty, element 0 is always
2652 // OuterTemplateParams; inner elements are always template parameter lists of
2653 // lambda expressions. For a generic lambda with no explicit template
2654 // parameter list, the corresponding parameter list pointer will be null.
2655 PODSmallVector<TemplateParamList *, 4> TemplateParams;
2657 class SaveTemplateParams {
2658 AbstractManglingParser *Parser;
2659 decltype(TemplateParams) OldParams;
2660 decltype(OuterTemplateParams) OldOuterParams;
2662 public:
2663 SaveTemplateParams(AbstractManglingParser *TheParser) : Parser(TheParser) {
2664 OldParams = std::move(Parser->TemplateParams);
2665 OldOuterParams = std::move(Parser->OuterTemplateParams);
2666 Parser->TemplateParams.clear();
2667 Parser->OuterTemplateParams.clear();
2669 ~SaveTemplateParams() {
2670 Parser->TemplateParams = std::move(OldParams);
2671 Parser->OuterTemplateParams = std::move(OldOuterParams);
2675 // Set of unresolved forward <template-param> references. These can occur in a
2676 // conversion operator's type, and are resolved in the enclosing <encoding>.
2677 PODSmallVector<ForwardTemplateReference *, 4> ForwardTemplateRefs;
2679 bool TryToParseTemplateArgs = true;
2680 bool PermitForwardTemplateReferences = false;
2681 bool InConstraintExpr = false;
2682 size_t ParsingLambdaParamsAtLevel = (size_t)-1;
2684 unsigned NumSyntheticTemplateParameters[3] = {};
2686 Alloc ASTAllocator;
2688 AbstractManglingParser(const char *First_, const char *Last_)
2689 : First(First_), Last(Last_) {}
2691 Derived &getDerived() { return static_cast<Derived &>(*this); }
2693 void reset(const char *First_, const char *Last_) {
2694 First = First_;
2695 Last = Last_;
2696 Names.clear();
2697 Subs.clear();
2698 TemplateParams.clear();
2699 ParsingLambdaParamsAtLevel = (size_t)-1;
2700 TryToParseTemplateArgs = true;
2701 PermitForwardTemplateReferences = false;
2702 for (int I = 0; I != 3; ++I)
2703 NumSyntheticTemplateParameters[I] = 0;
2704 ASTAllocator.reset();
2707 template <class T, class... Args> Node *make(Args &&... args) {
2708 return ASTAllocator.template makeNode<T>(std::forward<Args>(args)...);
2711 template <class It> NodeArray makeNodeArray(It begin, It end) {
2712 size_t sz = static_cast<size_t>(end - begin);
2713 void *mem = ASTAllocator.allocateNodeArray(sz);
2714 Node **data = new (mem) Node *[sz];
2715 std::copy(begin, end, data);
2716 return NodeArray(data, sz);
2719 NodeArray popTrailingNodeArray(size_t FromPosition) {
2720 DEMANGLE_ASSERT(FromPosition <= Names.size(), "");
2721 NodeArray res =
2722 makeNodeArray(Names.begin() + (long)FromPosition, Names.end());
2723 Names.shrinkToSize(FromPosition);
2724 return res;
2727 bool consumeIf(std::string_view S) {
2728 if (starts_with(std::string_view(First, Last - First), S)) {
2729 First += S.size();
2730 return true;
2732 return false;
2735 bool consumeIf(char C) {
2736 if (First != Last && *First == C) {
2737 ++First;
2738 return true;
2740 return false;
2743 char consume() { return First != Last ? *First++ : '\0'; }
2745 char look(unsigned Lookahead = 0) const {
2746 if (static_cast<size_t>(Last - First) <= Lookahead)
2747 return '\0';
2748 return First[Lookahead];
2751 size_t numLeft() const { return static_cast<size_t>(Last - First); }
2753 std::string_view parseNumber(bool AllowNegative = false);
2754 Qualifiers parseCVQualifiers();
2755 bool parsePositiveInteger(size_t *Out);
2756 std::string_view parseBareSourceName();
2758 bool parseSeqId(size_t *Out);
2759 Node *parseSubstitution();
2760 Node *parseTemplateParam();
2761 Node *parseTemplateParamDecl(TemplateParamList *Params);
2762 Node *parseTemplateArgs(bool TagTemplates = false);
2763 Node *parseTemplateArg();
2765 bool isTemplateParamDecl() {
2766 return look() == 'T' &&
2767 std::string_view("yptnk").find(look(1)) != std::string_view::npos;
2770 /// Parse the <expression> production.
2771 Node *parseExpr();
2772 Node *parsePrefixExpr(std::string_view Kind, Node::Prec Prec);
2773 Node *parseBinaryExpr(std::string_view Kind, Node::Prec Prec);
2774 Node *parseIntegerLiteral(std::string_view Lit);
2775 Node *parseExprPrimary();
2776 template <class Float> Node *parseFloatingLiteral();
2777 Node *parseFunctionParam();
2778 Node *parseConversionExpr();
2779 Node *parseBracedExpr();
2780 Node *parseFoldExpr();
2781 Node *parsePointerToMemberConversionExpr(Node::Prec Prec);
2782 Node *parseSubobjectExpr();
2783 Node *parseConstraintExpr();
2784 Node *parseRequiresExpr();
2786 /// Parse the <type> production.
2787 Node *parseType();
2788 Node *parseFunctionType();
2789 Node *parseVectorType();
2790 Node *parseDecltype();
2791 Node *parseArrayType();
2792 Node *parsePointerToMemberType();
2793 Node *parseClassEnumType();
2794 Node *parseQualifiedType();
2796 Node *parseEncoding(bool ParseParams = true);
2797 bool parseCallOffset();
2798 Node *parseSpecialName();
2800 /// Holds some extra information about a <name> that is being parsed. This
2801 /// information is only pertinent if the <name> refers to an <encoding>.
2802 struct NameState {
2803 bool CtorDtorConversion = false;
2804 bool EndsWithTemplateArgs = false;
2805 Qualifiers CVQualifiers = QualNone;
2806 FunctionRefQual ReferenceQualifier = FrefQualNone;
2807 size_t ForwardTemplateRefsBegin;
2808 bool HasExplicitObjectParameter = false;
2810 NameState(AbstractManglingParser *Enclosing)
2811 : ForwardTemplateRefsBegin(Enclosing->ForwardTemplateRefs.size()) {}
2814 bool resolveForwardTemplateRefs(NameState &State) {
2815 size_t I = State.ForwardTemplateRefsBegin;
2816 size_t E = ForwardTemplateRefs.size();
2817 for (; I < E; ++I) {
2818 size_t Idx = ForwardTemplateRefs[I]->Index;
2819 if (TemplateParams.empty() || !TemplateParams[0] ||
2820 Idx >= TemplateParams[0]->size())
2821 return true;
2822 ForwardTemplateRefs[I]->Ref = (*TemplateParams[0])[Idx];
2824 ForwardTemplateRefs.shrinkToSize(State.ForwardTemplateRefsBegin);
2825 return false;
2828 /// Parse the <name> production>
2829 Node *parseName(NameState *State = nullptr);
2830 Node *parseLocalName(NameState *State);
2831 Node *parseOperatorName(NameState *State);
2832 bool parseModuleNameOpt(ModuleName *&Module);
2833 Node *parseUnqualifiedName(NameState *State, Node *Scope, ModuleName *Module);
2834 Node *parseUnnamedTypeName(NameState *State);
2835 Node *parseSourceName(NameState *State);
2836 Node *parseUnscopedName(NameState *State, bool *isSubstName);
2837 Node *parseNestedName(NameState *State);
2838 Node *parseCtorDtorName(Node *&SoFar, NameState *State);
2840 Node *parseAbiTags(Node *N);
2842 struct OperatorInfo {
2843 enum OIKind : unsigned char {
2844 Prefix, // Prefix unary: @ expr
2845 Postfix, // Postfix unary: expr @
2846 Binary, // Binary: lhs @ rhs
2847 Array, // Array index: lhs [ rhs ]
2848 Member, // Member access: lhs @ rhs
2849 New, // New
2850 Del, // Delete
2851 Call, // Function call: expr (expr*)
2852 CCast, // C cast: (type)expr
2853 Conditional, // Conditional: expr ? expr : expr
2854 NameOnly, // Overload only, not allowed in expression.
2855 // Below do not have operator names
2856 NamedCast, // Named cast, @<type>(expr)
2857 OfIdOp, // alignof, sizeof, typeid
2859 Unnameable = NamedCast,
2861 char Enc[2]; // Encoding
2862 OIKind Kind; // Kind of operator
2863 bool Flag : 1; // Entry-specific flag
2864 Node::Prec Prec : 7; // Precedence
2865 const char *Name; // Spelling
2867 public:
2868 constexpr OperatorInfo(const char (&E)[3], OIKind K, bool F, Node::Prec P,
2869 const char *N)
2870 : Enc{E[0], E[1]}, Kind{K}, Flag{F}, Prec{P}, Name{N} {}
2872 public:
2873 bool operator<(const OperatorInfo &Other) const {
2874 return *this < Other.Enc;
2876 bool operator<(const char *Peek) const {
2877 return Enc[0] < Peek[0] || (Enc[0] == Peek[0] && Enc[1] < Peek[1]);
2879 bool operator==(const char *Peek) const {
2880 return Enc[0] == Peek[0] && Enc[1] == Peek[1];
2882 bool operator!=(const char *Peek) const { return !this->operator==(Peek); }
2884 public:
2885 std::string_view getSymbol() const {
2886 std::string_view Res = Name;
2887 if (Kind < Unnameable) {
2888 DEMANGLE_ASSERT(starts_with(Res, "operator"),
2889 "operator name does not start with 'operator'");
2890 Res.remove_prefix(sizeof("operator") - 1);
2891 if (starts_with(Res, ' '))
2892 Res.remove_prefix(1);
2894 return Res;
2896 std::string_view getName() const { return Name; }
2897 OIKind getKind() const { return Kind; }
2898 bool getFlag() const { return Flag; }
2899 Node::Prec getPrecedence() const { return Prec; }
2901 static const OperatorInfo Ops[];
2902 static const size_t NumOps;
2903 const OperatorInfo *parseOperatorEncoding();
2905 /// Parse the <unresolved-name> production.
2906 Node *parseUnresolvedName(bool Global);
2907 Node *parseSimpleId();
2908 Node *parseBaseUnresolvedName();
2909 Node *parseUnresolvedType();
2910 Node *parseDestructorName();
2912 /// Top-level entry point into the parser.
2913 Node *parse(bool ParseParams = true);
2916 const char* parse_discriminator(const char* first, const char* last);
2918 // <name> ::= <nested-name> // N
2919 // ::= <local-name> # See Scope Encoding below // Z
2920 // ::= <unscoped-template-name> <template-args>
2921 // ::= <unscoped-name>
2923 // <unscoped-template-name> ::= <unscoped-name>
2924 // ::= <substitution>
2925 template <typename Derived, typename Alloc>
2926 Node *AbstractManglingParser<Derived, Alloc>::parseName(NameState *State) {
2927 if (look() == 'N')
2928 return getDerived().parseNestedName(State);
2929 if (look() == 'Z')
2930 return getDerived().parseLocalName(State);
2932 Node *Result = nullptr;
2933 bool IsSubst = false;
2935 Result = getDerived().parseUnscopedName(State, &IsSubst);
2936 if (!Result)
2937 return nullptr;
2939 if (look() == 'I') {
2940 // ::= <unscoped-template-name> <template-args>
2941 if (!IsSubst)
2942 // An unscoped-template-name is substitutable.
2943 Subs.push_back(Result);
2944 Node *TA = getDerived().parseTemplateArgs(State != nullptr);
2945 if (TA == nullptr)
2946 return nullptr;
2947 if (State)
2948 State->EndsWithTemplateArgs = true;
2949 Result = make<NameWithTemplateArgs>(Result, TA);
2950 } else if (IsSubst) {
2951 // The substitution case must be followed by <template-args>.
2952 return nullptr;
2955 return Result;
2958 // <local-name> := Z <function encoding> E <entity name> [<discriminator>]
2959 // := Z <function encoding> E s [<discriminator>]
2960 // := Z <function encoding> Ed [ <parameter number> ] _ <entity name>
2961 template <typename Derived, typename Alloc>
2962 Node *AbstractManglingParser<Derived, Alloc>::parseLocalName(NameState *State) {
2963 if (!consumeIf('Z'))
2964 return nullptr;
2965 Node *Encoding = getDerived().parseEncoding();
2966 if (Encoding == nullptr || !consumeIf('E'))
2967 return nullptr;
2969 if (consumeIf('s')) {
2970 First = parse_discriminator(First, Last);
2971 auto *StringLitName = make<NameType>("string literal");
2972 if (!StringLitName)
2973 return nullptr;
2974 return make<LocalName>(Encoding, StringLitName);
2977 // The template parameters of the inner name are unrelated to those of the
2978 // enclosing context.
2979 SaveTemplateParams SaveTemplateParamsScope(this);
2981 if (consumeIf('d')) {
2982 parseNumber(true);
2983 if (!consumeIf('_'))
2984 return nullptr;
2985 Node *N = getDerived().parseName(State);
2986 if (N == nullptr)
2987 return nullptr;
2988 return make<LocalName>(Encoding, N);
2991 Node *Entity = getDerived().parseName(State);
2992 if (Entity == nullptr)
2993 return nullptr;
2994 First = parse_discriminator(First, Last);
2995 return make<LocalName>(Encoding, Entity);
2998 // <unscoped-name> ::= <unqualified-name>
2999 // ::= St <unqualified-name> # ::std::
3000 // [*] extension
3001 template <typename Derived, typename Alloc>
3002 Node *
3003 AbstractManglingParser<Derived, Alloc>::parseUnscopedName(NameState *State,
3004 bool *IsSubst) {
3006 Node *Std = nullptr;
3007 if (consumeIf("St")) {
3008 Std = make<NameType>("std");
3009 if (Std == nullptr)
3010 return nullptr;
3013 Node *Res = nullptr;
3014 ModuleName *Module = nullptr;
3015 if (look() == 'S') {
3016 Node *S = getDerived().parseSubstitution();
3017 if (!S)
3018 return nullptr;
3019 if (S->getKind() == Node::KModuleName)
3020 Module = static_cast<ModuleName *>(S);
3021 else if (IsSubst && Std == nullptr) {
3022 Res = S;
3023 *IsSubst = true;
3024 } else {
3025 return nullptr;
3029 if (Res == nullptr || Std != nullptr) {
3030 Res = getDerived().parseUnqualifiedName(State, Std, Module);
3033 return Res;
3036 // <unqualified-name> ::= [<module-name>] F? L? <operator-name> [<abi-tags>]
3037 // ::= [<module-name>] <ctor-dtor-name> [<abi-tags>]
3038 // ::= [<module-name>] F? L? <source-name> [<abi-tags>]
3039 // ::= [<module-name>] L? <unnamed-type-name> [<abi-tags>]
3040 // # structured binding declaration
3041 // ::= [<module-name>] L? DC <source-name>+ E
3042 template <typename Derived, typename Alloc>
3043 Node *AbstractManglingParser<Derived, Alloc>::parseUnqualifiedName(
3044 NameState *State, Node *Scope, ModuleName *Module) {
3045 if (getDerived().parseModuleNameOpt(Module))
3046 return nullptr;
3048 bool IsMemberLikeFriend = Scope && consumeIf('F');
3050 consumeIf('L');
3052 Node *Result;
3053 if (look() >= '1' && look() <= '9') {
3054 Result = getDerived().parseSourceName(State);
3055 } else if (look() == 'U') {
3056 Result = getDerived().parseUnnamedTypeName(State);
3057 } else if (consumeIf("DC")) {
3058 // Structured binding
3059 size_t BindingsBegin = Names.size();
3060 do {
3061 Node *Binding = getDerived().parseSourceName(State);
3062 if (Binding == nullptr)
3063 return nullptr;
3064 Names.push_back(Binding);
3065 } while (!consumeIf('E'));
3066 Result = make<StructuredBindingName>(popTrailingNodeArray(BindingsBegin));
3067 } else if (look() == 'C' || look() == 'D') {
3068 // A <ctor-dtor-name>.
3069 if (Scope == nullptr || Module != nullptr)
3070 return nullptr;
3071 Result = getDerived().parseCtorDtorName(Scope, State);
3072 } else {
3073 Result = getDerived().parseOperatorName(State);
3076 if (Result != nullptr && Module != nullptr)
3077 Result = make<ModuleEntity>(Module, Result);
3078 if (Result != nullptr)
3079 Result = getDerived().parseAbiTags(Result);
3080 if (Result != nullptr && IsMemberLikeFriend)
3081 Result = make<MemberLikeFriendName>(Scope, Result);
3082 else if (Result != nullptr && Scope != nullptr)
3083 Result = make<NestedName>(Scope, Result);
3085 return Result;
3088 // <module-name> ::= <module-subname>
3089 // ::= <module-name> <module-subname>
3090 // ::= <substitution> # passed in by caller
3091 // <module-subname> ::= W <source-name>
3092 // ::= W P <source-name>
3093 template <typename Derived, typename Alloc>
3094 bool AbstractManglingParser<Derived, Alloc>::parseModuleNameOpt(
3095 ModuleName *&Module) {
3096 while (consumeIf('W')) {
3097 bool IsPartition = consumeIf('P');
3098 Node *Sub = getDerived().parseSourceName(nullptr);
3099 if (!Sub)
3100 return true;
3101 Module =
3102 static_cast<ModuleName *>(make<ModuleName>(Module, Sub, IsPartition));
3103 Subs.push_back(Module);
3106 return false;
3109 // <unnamed-type-name> ::= Ut [<nonnegative number>] _
3110 // ::= <closure-type-name>
3112 // <closure-type-name> ::= Ul <lambda-sig> E [ <nonnegative number> ] _
3114 // <lambda-sig> ::= <template-param-decl>* [Q <requires-clause expression>]
3115 // <parameter type>+ # or "v" if the lambda has no parameters
3116 template <typename Derived, typename Alloc>
3117 Node *
3118 AbstractManglingParser<Derived, Alloc>::parseUnnamedTypeName(NameState *State) {
3119 // <template-params> refer to the innermost <template-args>. Clear out any
3120 // outer args that we may have inserted into TemplateParams.
3121 if (State != nullptr)
3122 TemplateParams.clear();
3124 if (consumeIf("Ut")) {
3125 std::string_view Count = parseNumber();
3126 if (!consumeIf('_'))
3127 return nullptr;
3128 return make<UnnamedTypeName>(Count);
3130 if (consumeIf("Ul")) {
3131 ScopedOverride<size_t> SwapParams(ParsingLambdaParamsAtLevel,
3132 TemplateParams.size());
3133 ScopedTemplateParamList LambdaTemplateParams(this);
3135 size_t ParamsBegin = Names.size();
3136 while (getDerived().isTemplateParamDecl()) {
3137 Node *T =
3138 getDerived().parseTemplateParamDecl(LambdaTemplateParams.params());
3139 if (T == nullptr)
3140 return nullptr;
3141 Names.push_back(T);
3143 NodeArray TempParams = popTrailingNodeArray(ParamsBegin);
3145 // FIXME: If TempParams is empty and none of the function parameters
3146 // includes 'auto', we should remove LambdaTemplateParams from the
3147 // TemplateParams list. Unfortunately, we don't find out whether there are
3148 // any 'auto' parameters until too late in an example such as:
3150 // template<typename T> void f(
3151 // decltype([](decltype([]<typename T>(T v) {}),
3152 // auto) {})) {}
3153 // template<typename T> void f(
3154 // decltype([](decltype([]<typename T>(T w) {}),
3155 // int) {})) {}
3157 // Here, the type of v is at level 2 but the type of w is at level 1. We
3158 // don't find this out until we encounter the type of the next parameter.
3160 // However, compilers can't actually cope with the former example in
3161 // practice, and it's likely to be made ill-formed in future, so we don't
3162 // need to support it here.
3164 // If we encounter an 'auto' in the function parameter types, we will
3165 // recreate a template parameter scope for it, but any intervening lambdas
3166 // will be parsed in the 'wrong' template parameter depth.
3167 if (TempParams.empty())
3168 TemplateParams.pop_back();
3170 Node *Requires1 = nullptr;
3171 if (consumeIf('Q')) {
3172 Requires1 = getDerived().parseConstraintExpr();
3173 if (Requires1 == nullptr)
3174 return nullptr;
3177 if (!consumeIf("v")) {
3178 do {
3179 Node *P = getDerived().parseType();
3180 if (P == nullptr)
3181 return nullptr;
3182 Names.push_back(P);
3183 } while (look() != 'E' && look() != 'Q');
3185 NodeArray Params = popTrailingNodeArray(ParamsBegin);
3187 Node *Requires2 = nullptr;
3188 if (consumeIf('Q')) {
3189 Requires2 = getDerived().parseConstraintExpr();
3190 if (Requires2 == nullptr)
3191 return nullptr;
3194 if (!consumeIf('E'))
3195 return nullptr;
3197 std::string_view Count = parseNumber();
3198 if (!consumeIf('_'))
3199 return nullptr;
3200 return make<ClosureTypeName>(TempParams, Requires1, Params, Requires2,
3201 Count);
3203 if (consumeIf("Ub")) {
3204 (void)parseNumber();
3205 if (!consumeIf('_'))
3206 return nullptr;
3207 return make<NameType>("'block-literal'");
3209 return nullptr;
3212 // <source-name> ::= <positive length number> <identifier>
3213 template <typename Derived, typename Alloc>
3214 Node *AbstractManglingParser<Derived, Alloc>::parseSourceName(NameState *) {
3215 size_t Length = 0;
3216 if (parsePositiveInteger(&Length))
3217 return nullptr;
3218 if (numLeft() < Length || Length == 0)
3219 return nullptr;
3220 std::string_view Name(First, Length);
3221 First += Length;
3222 if (starts_with(Name, "_GLOBAL__N"))
3223 return make<NameType>("(anonymous namespace)");
3224 return make<NameType>(Name);
3227 // Operator encodings
3228 template <typename Derived, typename Alloc>
3229 const typename AbstractManglingParser<
3230 Derived, Alloc>::OperatorInfo AbstractManglingParser<Derived,
3231 Alloc>::Ops[] = {
3232 // Keep ordered by encoding
3233 {"aN", OperatorInfo::Binary, false, Node::Prec::Assign, "operator&="},
3234 {"aS", OperatorInfo::Binary, false, Node::Prec::Assign, "operator="},
3235 {"aa", OperatorInfo::Binary, false, Node::Prec::AndIf, "operator&&"},
3236 {"ad", OperatorInfo::Prefix, false, Node::Prec::Unary, "operator&"},
3237 {"an", OperatorInfo::Binary, false, Node::Prec::And, "operator&"},
3238 {"at", OperatorInfo::OfIdOp, /*Type*/ true, Node::Prec::Unary, "alignof "},
3239 {"aw", OperatorInfo::NameOnly, false, Node::Prec::Primary,
3240 "operator co_await"},
3241 {"az", OperatorInfo::OfIdOp, /*Type*/ false, Node::Prec::Unary, "alignof "},
3242 {"cc", OperatorInfo::NamedCast, false, Node::Prec::Postfix, "const_cast"},
3243 {"cl", OperatorInfo::Call, false, Node::Prec::Postfix, "operator()"},
3244 {"cm", OperatorInfo::Binary, false, Node::Prec::Comma, "operator,"},
3245 {"co", OperatorInfo::Prefix, false, Node::Prec::Unary, "operator~"},
3246 {"cv", OperatorInfo::CCast, false, Node::Prec::Cast, "operator"}, // C Cast
3247 {"dV", OperatorInfo::Binary, false, Node::Prec::Assign, "operator/="},
3248 {"da", OperatorInfo::Del, /*Ary*/ true, Node::Prec::Unary,
3249 "operator delete[]"},
3250 {"dc", OperatorInfo::NamedCast, false, Node::Prec::Postfix, "dynamic_cast"},
3251 {"de", OperatorInfo::Prefix, false, Node::Prec::Unary, "operator*"},
3252 {"dl", OperatorInfo::Del, /*Ary*/ false, Node::Prec::Unary,
3253 "operator delete"},
3254 {"ds", OperatorInfo::Member, /*Named*/ false, Node::Prec::PtrMem,
3255 "operator.*"},
3256 {"dt", OperatorInfo::Member, /*Named*/ false, Node::Prec::Postfix,
3257 "operator."},
3258 {"dv", OperatorInfo::Binary, false, Node::Prec::Assign, "operator/"},
3259 {"eO", OperatorInfo::Binary, false, Node::Prec::Assign, "operator^="},
3260 {"eo", OperatorInfo::Binary, false, Node::Prec::Xor, "operator^"},
3261 {"eq", OperatorInfo::Binary, false, Node::Prec::Equality, "operator=="},
3262 {"ge", OperatorInfo::Binary, false, Node::Prec::Relational, "operator>="},
3263 {"gt", OperatorInfo::Binary, false, Node::Prec::Relational, "operator>"},
3264 {"ix", OperatorInfo::Array, false, Node::Prec::Postfix, "operator[]"},
3265 {"lS", OperatorInfo::Binary, false, Node::Prec::Assign, "operator<<="},
3266 {"le", OperatorInfo::Binary, false, Node::Prec::Relational, "operator<="},
3267 {"ls", OperatorInfo::Binary, false, Node::Prec::Shift, "operator<<"},
3268 {"lt", OperatorInfo::Binary, false, Node::Prec::Relational, "operator<"},
3269 {"mI", OperatorInfo::Binary, false, Node::Prec::Assign, "operator-="},
3270 {"mL", OperatorInfo::Binary, false, Node::Prec::Assign, "operator*="},
3271 {"mi", OperatorInfo::Binary, false, Node::Prec::Additive, "operator-"},
3272 {"ml", OperatorInfo::Binary, false, Node::Prec::Multiplicative,
3273 "operator*"},
3274 {"mm", OperatorInfo::Postfix, false, Node::Prec::Postfix, "operator--"},
3275 {"na", OperatorInfo::New, /*Ary*/ true, Node::Prec::Unary,
3276 "operator new[]"},
3277 {"ne", OperatorInfo::Binary, false, Node::Prec::Equality, "operator!="},
3278 {"ng", OperatorInfo::Prefix, false, Node::Prec::Unary, "operator-"},
3279 {"nt", OperatorInfo::Prefix, false, Node::Prec::Unary, "operator!"},
3280 {"nw", OperatorInfo::New, /*Ary*/ false, Node::Prec::Unary, "operator new"},
3281 {"oR", OperatorInfo::Binary, false, Node::Prec::Assign, "operator|="},
3282 {"oo", OperatorInfo::Binary, false, Node::Prec::OrIf, "operator||"},
3283 {"or", OperatorInfo::Binary, false, Node::Prec::Ior, "operator|"},
3284 {"pL", OperatorInfo::Binary, false, Node::Prec::Assign, "operator+="},
3285 {"pl", OperatorInfo::Binary, false, Node::Prec::Additive, "operator+"},
3286 {"pm", OperatorInfo::Member, /*Named*/ false, Node::Prec::PtrMem,
3287 "operator->*"},
3288 {"pp", OperatorInfo::Postfix, false, Node::Prec::Postfix, "operator++"},
3289 {"ps", OperatorInfo::Prefix, false, Node::Prec::Unary, "operator+"},
3290 {"pt", OperatorInfo::Member, /*Named*/ true, Node::Prec::Postfix,
3291 "operator->"},
3292 {"qu", OperatorInfo::Conditional, false, Node::Prec::Conditional,
3293 "operator?"},
3294 {"rM", OperatorInfo::Binary, false, Node::Prec::Assign, "operator%="},
3295 {"rS", OperatorInfo::Binary, false, Node::Prec::Assign, "operator>>="},
3296 {"rc", OperatorInfo::NamedCast, false, Node::Prec::Postfix,
3297 "reinterpret_cast"},
3298 {"rm", OperatorInfo::Binary, false, Node::Prec::Multiplicative,
3299 "operator%"},
3300 {"rs", OperatorInfo::Binary, false, Node::Prec::Shift, "operator>>"},
3301 {"sc", OperatorInfo::NamedCast, false, Node::Prec::Postfix, "static_cast"},
3302 {"ss", OperatorInfo::Binary, false, Node::Prec::Spaceship, "operator<=>"},
3303 {"st", OperatorInfo::OfIdOp, /*Type*/ true, Node::Prec::Unary, "sizeof "},
3304 {"sz", OperatorInfo::OfIdOp, /*Type*/ false, Node::Prec::Unary, "sizeof "},
3305 {"te", OperatorInfo::OfIdOp, /*Type*/ false, Node::Prec::Postfix,
3306 "typeid "},
3307 {"ti", OperatorInfo::OfIdOp, /*Type*/ true, Node::Prec::Postfix, "typeid "},
3309 template <typename Derived, typename Alloc>
3310 const size_t AbstractManglingParser<Derived, Alloc>::NumOps = sizeof(Ops) /
3311 sizeof(Ops[0]);
3313 // If the next 2 chars are an operator encoding, consume them and return their
3314 // OperatorInfo. Otherwise return nullptr.
3315 template <typename Derived, typename Alloc>
3316 const typename AbstractManglingParser<Derived, Alloc>::OperatorInfo *
3317 AbstractManglingParser<Derived, Alloc>::parseOperatorEncoding() {
3318 if (numLeft() < 2)
3319 return nullptr;
3321 // We can't use lower_bound as that can link to symbols in the C++ library,
3322 // and this must remain independant of that.
3323 size_t lower = 0u, upper = NumOps - 1; // Inclusive bounds.
3324 while (upper != lower) {
3325 size_t middle = (upper + lower) / 2;
3326 if (Ops[middle] < First)
3327 lower = middle + 1;
3328 else
3329 upper = middle;
3331 if (Ops[lower] != First)
3332 return nullptr;
3334 First += 2;
3335 return &Ops[lower];
3338 // <operator-name> ::= See parseOperatorEncoding()
3339 // ::= li <source-name> # operator ""
3340 // ::= v <digit> <source-name> # vendor extended operator
3341 template <typename Derived, typename Alloc>
3342 Node *
3343 AbstractManglingParser<Derived, Alloc>::parseOperatorName(NameState *State) {
3344 if (const auto *Op = parseOperatorEncoding()) {
3345 if (Op->getKind() == OperatorInfo::CCast) {
3346 // ::= cv <type> # (cast)
3347 ScopedOverride<bool> SaveTemplate(TryToParseTemplateArgs, false);
3348 // If we're parsing an encoding, State != nullptr and the conversion
3349 // operators' <type> could have a <template-param> that refers to some
3350 // <template-arg>s further ahead in the mangled name.
3351 ScopedOverride<bool> SavePermit(PermitForwardTemplateReferences,
3352 PermitForwardTemplateReferences ||
3353 State != nullptr);
3354 Node *Ty = getDerived().parseType();
3355 if (Ty == nullptr)
3356 return nullptr;
3357 if (State) State->CtorDtorConversion = true;
3358 return make<ConversionOperatorType>(Ty);
3361 if (Op->getKind() >= OperatorInfo::Unnameable)
3362 /* Not a nameable operator. */
3363 return nullptr;
3364 if (Op->getKind() == OperatorInfo::Member && !Op->getFlag())
3365 /* Not a nameable MemberExpr */
3366 return nullptr;
3368 return make<NameType>(Op->getName());
3371 if (consumeIf("li")) {
3372 // ::= li <source-name> # operator ""
3373 Node *SN = getDerived().parseSourceName(State);
3374 if (SN == nullptr)
3375 return nullptr;
3376 return make<LiteralOperator>(SN);
3379 if (consumeIf('v')) {
3380 // ::= v <digit> <source-name> # vendor extended operator
3381 if (look() >= '0' && look() <= '9') {
3382 First++;
3383 Node *SN = getDerived().parseSourceName(State);
3384 if (SN == nullptr)
3385 return nullptr;
3386 return make<ConversionOperatorType>(SN);
3388 return nullptr;
3391 return nullptr;
3394 // <ctor-dtor-name> ::= C1 # complete object constructor
3395 // ::= C2 # base object constructor
3396 // ::= C3 # complete object allocating constructor
3397 // extension ::= C4 # gcc old-style "[unified]" constructor
3398 // extension ::= C5 # the COMDAT used for ctors
3399 // ::= D0 # deleting destructor
3400 // ::= D1 # complete object destructor
3401 // ::= D2 # base object destructor
3402 // extension ::= D4 # gcc old-style "[unified]" destructor
3403 // extension ::= D5 # the COMDAT used for dtors
3404 template <typename Derived, typename Alloc>
3405 Node *
3406 AbstractManglingParser<Derived, Alloc>::parseCtorDtorName(Node *&SoFar,
3407 NameState *State) {
3408 if (SoFar->getKind() == Node::KSpecialSubstitution) {
3409 // Expand the special substitution.
3410 SoFar = make<ExpandedSpecialSubstitution>(
3411 static_cast<SpecialSubstitution *>(SoFar));
3412 if (!SoFar)
3413 return nullptr;
3416 if (consumeIf('C')) {
3417 bool IsInherited = consumeIf('I');
3418 if (look() != '1' && look() != '2' && look() != '3' && look() != '4' &&
3419 look() != '5')
3420 return nullptr;
3421 int Variant = look() - '0';
3422 ++First;
3423 if (State) State->CtorDtorConversion = true;
3424 if (IsInherited) {
3425 if (getDerived().parseName(State) == nullptr)
3426 return nullptr;
3428 return make<CtorDtorName>(SoFar, /*IsDtor=*/false, Variant);
3431 if (look() == 'D' && (look(1) == '0' || look(1) == '1' || look(1) == '2' ||
3432 look(1) == '4' || look(1) == '5')) {
3433 int Variant = look(1) - '0';
3434 First += 2;
3435 if (State) State->CtorDtorConversion = true;
3436 return make<CtorDtorName>(SoFar, /*IsDtor=*/true, Variant);
3439 return nullptr;
3442 // <nested-name> ::= N [<CV-Qualifiers>] [<ref-qualifier>] <prefix>
3443 // <unqualified-name> E
3444 // ::= N [<CV-Qualifiers>] [<ref-qualifier>] <template-prefix>
3445 // <template-args> E
3447 // <prefix> ::= <prefix> <unqualified-name>
3448 // ::= <template-prefix> <template-args>
3449 // ::= <template-param>
3450 // ::= <decltype>
3451 // ::= # empty
3452 // ::= <substitution>
3453 // ::= <prefix> <data-member-prefix>
3454 // [*] extension
3456 // <data-member-prefix> := <member source-name> [<template-args>] M
3458 // <template-prefix> ::= <prefix> <template unqualified-name>
3459 // ::= <template-param>
3460 // ::= <substitution>
3461 template <typename Derived, typename Alloc>
3462 Node *
3463 AbstractManglingParser<Derived, Alloc>::parseNestedName(NameState *State) {
3464 if (!consumeIf('N'))
3465 return nullptr;
3467 // 'H' specifies that the encoding that follows
3468 // has an explicit object parameter.
3469 if (!consumeIf('H')) {
3470 Qualifiers CVTmp = parseCVQualifiers();
3471 if (State)
3472 State->CVQualifiers = CVTmp;
3474 if (consumeIf('O')) {
3475 if (State)
3476 State->ReferenceQualifier = FrefQualRValue;
3477 } else if (consumeIf('R')) {
3478 if (State)
3479 State->ReferenceQualifier = FrefQualLValue;
3480 } else {
3481 if (State)
3482 State->ReferenceQualifier = FrefQualNone;
3484 } else if (State) {
3485 State->HasExplicitObjectParameter = true;
3488 Node *SoFar = nullptr;
3489 while (!consumeIf('E')) {
3490 if (State)
3491 // Only set end-with-template on the case that does that.
3492 State->EndsWithTemplateArgs = false;
3494 if (look() == 'T') {
3495 // ::= <template-param>
3496 if (SoFar != nullptr)
3497 return nullptr; // Cannot have a prefix.
3498 SoFar = getDerived().parseTemplateParam();
3499 } else if (look() == 'I') {
3500 // ::= <template-prefix> <template-args>
3501 if (SoFar == nullptr)
3502 return nullptr; // Must have a prefix.
3503 Node *TA = getDerived().parseTemplateArgs(State != nullptr);
3504 if (TA == nullptr)
3505 return nullptr;
3506 if (SoFar->getKind() == Node::KNameWithTemplateArgs)
3507 // Semantically <template-args> <template-args> cannot be generated by a
3508 // C++ entity. There will always be [something like] a name between
3509 // them.
3510 return nullptr;
3511 if (State)
3512 State->EndsWithTemplateArgs = true;
3513 SoFar = make<NameWithTemplateArgs>(SoFar, TA);
3514 } else if (look() == 'D' && (look(1) == 't' || look(1) == 'T')) {
3515 // ::= <decltype>
3516 if (SoFar != nullptr)
3517 return nullptr; // Cannot have a prefix.
3518 SoFar = getDerived().parseDecltype();
3519 } else {
3520 ModuleName *Module = nullptr;
3522 if (look() == 'S') {
3523 // ::= <substitution>
3524 Node *S = nullptr;
3525 if (look(1) == 't') {
3526 First += 2;
3527 S = make<NameType>("std");
3528 } else {
3529 S = getDerived().parseSubstitution();
3531 if (!S)
3532 return nullptr;
3533 if (S->getKind() == Node::KModuleName) {
3534 Module = static_cast<ModuleName *>(S);
3535 } else if (SoFar != nullptr) {
3536 return nullptr; // Cannot have a prefix.
3537 } else {
3538 SoFar = S;
3539 continue; // Do not push a new substitution.
3543 // ::= [<prefix>] <unqualified-name>
3544 SoFar = getDerived().parseUnqualifiedName(State, SoFar, Module);
3547 if (SoFar == nullptr)
3548 return nullptr;
3549 Subs.push_back(SoFar);
3551 // No longer used.
3552 // <data-member-prefix> := <member source-name> [<template-args>] M
3553 consumeIf('M');
3556 if (SoFar == nullptr || Subs.empty())
3557 return nullptr;
3559 Subs.pop_back();
3560 return SoFar;
3563 // <simple-id> ::= <source-name> [ <template-args> ]
3564 template <typename Derived, typename Alloc>
3565 Node *AbstractManglingParser<Derived, Alloc>::parseSimpleId() {
3566 Node *SN = getDerived().parseSourceName(/*NameState=*/nullptr);
3567 if (SN == nullptr)
3568 return nullptr;
3569 if (look() == 'I') {
3570 Node *TA = getDerived().parseTemplateArgs();
3571 if (TA == nullptr)
3572 return nullptr;
3573 return make<NameWithTemplateArgs>(SN, TA);
3575 return SN;
3578 // <destructor-name> ::= <unresolved-type> # e.g., ~T or ~decltype(f())
3579 // ::= <simple-id> # e.g., ~A<2*N>
3580 template <typename Derived, typename Alloc>
3581 Node *AbstractManglingParser<Derived, Alloc>::parseDestructorName() {
3582 Node *Result;
3583 if (std::isdigit(look()))
3584 Result = getDerived().parseSimpleId();
3585 else
3586 Result = getDerived().parseUnresolvedType();
3587 if (Result == nullptr)
3588 return nullptr;
3589 return make<DtorName>(Result);
3592 // <unresolved-type> ::= <template-param>
3593 // ::= <decltype>
3594 // ::= <substitution>
3595 template <typename Derived, typename Alloc>
3596 Node *AbstractManglingParser<Derived, Alloc>::parseUnresolvedType() {
3597 if (look() == 'T') {
3598 Node *TP = getDerived().parseTemplateParam();
3599 if (TP == nullptr)
3600 return nullptr;
3601 Subs.push_back(TP);
3602 return TP;
3604 if (look() == 'D') {
3605 Node *DT = getDerived().parseDecltype();
3606 if (DT == nullptr)
3607 return nullptr;
3608 Subs.push_back(DT);
3609 return DT;
3611 return getDerived().parseSubstitution();
3614 // <base-unresolved-name> ::= <simple-id> # unresolved name
3615 // extension ::= <operator-name> # unresolved operator-function-id
3616 // extension ::= <operator-name> <template-args> # unresolved operator template-id
3617 // ::= on <operator-name> # unresolved operator-function-id
3618 // ::= on <operator-name> <template-args> # unresolved operator template-id
3619 // ::= dn <destructor-name> # destructor or pseudo-destructor;
3620 // # e.g. ~X or ~X<N-1>
3621 template <typename Derived, typename Alloc>
3622 Node *AbstractManglingParser<Derived, Alloc>::parseBaseUnresolvedName() {
3623 if (std::isdigit(look()))
3624 return getDerived().parseSimpleId();
3626 if (consumeIf("dn"))
3627 return getDerived().parseDestructorName();
3629 consumeIf("on");
3631 Node *Oper = getDerived().parseOperatorName(/*NameState=*/nullptr);
3632 if (Oper == nullptr)
3633 return nullptr;
3634 if (look() == 'I') {
3635 Node *TA = getDerived().parseTemplateArgs();
3636 if (TA == nullptr)
3637 return nullptr;
3638 return make<NameWithTemplateArgs>(Oper, TA);
3640 return Oper;
3643 // <unresolved-name>
3644 // extension ::= srN <unresolved-type> [<template-args>] <unresolved-qualifier-level>* E <base-unresolved-name>
3645 // ::= [gs] <base-unresolved-name> # x or (with "gs") ::x
3646 // ::= [gs] sr <unresolved-qualifier-level>+ E <base-unresolved-name>
3647 // # A::x, N::y, A<T>::z; "gs" means leading "::"
3648 // [gs] has been parsed by caller.
3649 // ::= sr <unresolved-type> <base-unresolved-name> # T::x / decltype(p)::x
3650 // extension ::= sr <unresolved-type> <template-args> <base-unresolved-name>
3651 // # T::N::x /decltype(p)::N::x
3652 // (ignored) ::= srN <unresolved-type> <unresolved-qualifier-level>+ E <base-unresolved-name>
3654 // <unresolved-qualifier-level> ::= <simple-id>
3655 template <typename Derived, typename Alloc>
3656 Node *AbstractManglingParser<Derived, Alloc>::parseUnresolvedName(bool Global) {
3657 Node *SoFar = nullptr;
3659 // srN <unresolved-type> [<template-args>] <unresolved-qualifier-level>* E <base-unresolved-name>
3660 // srN <unresolved-type> <unresolved-qualifier-level>+ E <base-unresolved-name>
3661 if (consumeIf("srN")) {
3662 SoFar = getDerived().parseUnresolvedType();
3663 if (SoFar == nullptr)
3664 return nullptr;
3666 if (look() == 'I') {
3667 Node *TA = getDerived().parseTemplateArgs();
3668 if (TA == nullptr)
3669 return nullptr;
3670 SoFar = make<NameWithTemplateArgs>(SoFar, TA);
3671 if (!SoFar)
3672 return nullptr;
3675 while (!consumeIf('E')) {
3676 Node *Qual = getDerived().parseSimpleId();
3677 if (Qual == nullptr)
3678 return nullptr;
3679 SoFar = make<QualifiedName>(SoFar, Qual);
3680 if (!SoFar)
3681 return nullptr;
3684 Node *Base = getDerived().parseBaseUnresolvedName();
3685 if (Base == nullptr)
3686 return nullptr;
3687 return make<QualifiedName>(SoFar, Base);
3690 // [gs] <base-unresolved-name> # x or (with "gs") ::x
3691 if (!consumeIf("sr")) {
3692 SoFar = getDerived().parseBaseUnresolvedName();
3693 if (SoFar == nullptr)
3694 return nullptr;
3695 if (Global)
3696 SoFar = make<GlobalQualifiedName>(SoFar);
3697 return SoFar;
3700 // [gs] sr <unresolved-qualifier-level>+ E <base-unresolved-name>
3701 if (std::isdigit(look())) {
3702 do {
3703 Node *Qual = getDerived().parseSimpleId();
3704 if (Qual == nullptr)
3705 return nullptr;
3706 if (SoFar)
3707 SoFar = make<QualifiedName>(SoFar, Qual);
3708 else if (Global)
3709 SoFar = make<GlobalQualifiedName>(Qual);
3710 else
3711 SoFar = Qual;
3712 if (!SoFar)
3713 return nullptr;
3714 } while (!consumeIf('E'));
3716 // sr <unresolved-type> <base-unresolved-name>
3717 // sr <unresolved-type> <template-args> <base-unresolved-name>
3718 else {
3719 SoFar = getDerived().parseUnresolvedType();
3720 if (SoFar == nullptr)
3721 return nullptr;
3723 if (look() == 'I') {
3724 Node *TA = getDerived().parseTemplateArgs();
3725 if (TA == nullptr)
3726 return nullptr;
3727 SoFar = make<NameWithTemplateArgs>(SoFar, TA);
3728 if (!SoFar)
3729 return nullptr;
3733 DEMANGLE_ASSERT(SoFar != nullptr, "");
3735 Node *Base = getDerived().parseBaseUnresolvedName();
3736 if (Base == nullptr)
3737 return nullptr;
3738 return make<QualifiedName>(SoFar, Base);
3741 // <abi-tags> ::= <abi-tag> [<abi-tags>]
3742 // <abi-tag> ::= B <source-name>
3743 template <typename Derived, typename Alloc>
3744 Node *AbstractManglingParser<Derived, Alloc>::parseAbiTags(Node *N) {
3745 while (consumeIf('B')) {
3746 std::string_view SN = parseBareSourceName();
3747 if (SN.empty())
3748 return nullptr;
3749 N = make<AbiTagAttr>(N, SN);
3750 if (!N)
3751 return nullptr;
3753 return N;
3756 // <number> ::= [n] <non-negative decimal integer>
3757 template <typename Alloc, typename Derived>
3758 std::string_view
3759 AbstractManglingParser<Alloc, Derived>::parseNumber(bool AllowNegative) {
3760 const char *Tmp = First;
3761 if (AllowNegative)
3762 consumeIf('n');
3763 if (numLeft() == 0 || !std::isdigit(*First))
3764 return std::string_view();
3765 while (numLeft() != 0 && std::isdigit(*First))
3766 ++First;
3767 return std::string_view(Tmp, First - Tmp);
3770 // <positive length number> ::= [0-9]*
3771 template <typename Alloc, typename Derived>
3772 bool AbstractManglingParser<Alloc, Derived>::parsePositiveInteger(size_t *Out) {
3773 *Out = 0;
3774 if (look() < '0' || look() > '9')
3775 return true;
3776 while (look() >= '0' && look() <= '9') {
3777 *Out *= 10;
3778 *Out += static_cast<size_t>(consume() - '0');
3780 return false;
3783 template <typename Alloc, typename Derived>
3784 std::string_view AbstractManglingParser<Alloc, Derived>::parseBareSourceName() {
3785 size_t Int = 0;
3786 if (parsePositiveInteger(&Int) || numLeft() < Int)
3787 return {};
3788 std::string_view R(First, Int);
3789 First += Int;
3790 return R;
3793 // <function-type> ::= [<CV-qualifiers>] [<exception-spec>] [Dx] F [Y] <bare-function-type> [<ref-qualifier>] E
3795 // <exception-spec> ::= Do # non-throwing exception-specification (e.g., noexcept, throw())
3796 // ::= DO <expression> E # computed (instantiation-dependent) noexcept
3797 // ::= Dw <type>+ E # dynamic exception specification with instantiation-dependent types
3799 // <ref-qualifier> ::= R # & ref-qualifier
3800 // <ref-qualifier> ::= O # && ref-qualifier
3801 template <typename Derived, typename Alloc>
3802 Node *AbstractManglingParser<Derived, Alloc>::parseFunctionType() {
3803 Qualifiers CVQuals = parseCVQualifiers();
3805 Node *ExceptionSpec = nullptr;
3806 if (consumeIf("Do")) {
3807 ExceptionSpec = make<NameType>("noexcept");
3808 if (!ExceptionSpec)
3809 return nullptr;
3810 } else if (consumeIf("DO")) {
3811 Node *E = getDerived().parseExpr();
3812 if (E == nullptr || !consumeIf('E'))
3813 return nullptr;
3814 ExceptionSpec = make<NoexceptSpec>(E);
3815 if (!ExceptionSpec)
3816 return nullptr;
3817 } else if (consumeIf("Dw")) {
3818 size_t SpecsBegin = Names.size();
3819 while (!consumeIf('E')) {
3820 Node *T = getDerived().parseType();
3821 if (T == nullptr)
3822 return nullptr;
3823 Names.push_back(T);
3825 ExceptionSpec =
3826 make<DynamicExceptionSpec>(popTrailingNodeArray(SpecsBegin));
3827 if (!ExceptionSpec)
3828 return nullptr;
3831 consumeIf("Dx"); // transaction safe
3833 if (!consumeIf('F'))
3834 return nullptr;
3835 consumeIf('Y'); // extern "C"
3836 Node *ReturnType = getDerived().parseType();
3837 if (ReturnType == nullptr)
3838 return nullptr;
3840 FunctionRefQual ReferenceQualifier = FrefQualNone;
3841 size_t ParamsBegin = Names.size();
3842 while (true) {
3843 if (consumeIf('E'))
3844 break;
3845 if (consumeIf('v'))
3846 continue;
3847 if (consumeIf("RE")) {
3848 ReferenceQualifier = FrefQualLValue;
3849 break;
3851 if (consumeIf("OE")) {
3852 ReferenceQualifier = FrefQualRValue;
3853 break;
3855 Node *T = getDerived().parseType();
3856 if (T == nullptr)
3857 return nullptr;
3858 Names.push_back(T);
3861 NodeArray Params = popTrailingNodeArray(ParamsBegin);
3862 return make<FunctionType>(ReturnType, Params, CVQuals,
3863 ReferenceQualifier, ExceptionSpec);
3866 // extension:
3867 // <vector-type> ::= Dv <positive dimension number> _ <extended element type>
3868 // ::= Dv [<dimension expression>] _ <element type>
3869 // <extended element type> ::= <element type>
3870 // ::= p # AltiVec vector pixel
3871 template <typename Derived, typename Alloc>
3872 Node *AbstractManglingParser<Derived, Alloc>::parseVectorType() {
3873 if (!consumeIf("Dv"))
3874 return nullptr;
3875 if (look() >= '1' && look() <= '9') {
3876 Node *DimensionNumber = make<NameType>(parseNumber());
3877 if (!DimensionNumber)
3878 return nullptr;
3879 if (!consumeIf('_'))
3880 return nullptr;
3881 if (consumeIf('p'))
3882 return make<PixelVectorType>(DimensionNumber);
3883 Node *ElemType = getDerived().parseType();
3884 if (ElemType == nullptr)
3885 return nullptr;
3886 return make<VectorType>(ElemType, DimensionNumber);
3889 if (!consumeIf('_')) {
3890 Node *DimExpr = getDerived().parseExpr();
3891 if (!DimExpr)
3892 return nullptr;
3893 if (!consumeIf('_'))
3894 return nullptr;
3895 Node *ElemType = getDerived().parseType();
3896 if (!ElemType)
3897 return nullptr;
3898 return make<VectorType>(ElemType, DimExpr);
3900 Node *ElemType = getDerived().parseType();
3901 if (!ElemType)
3902 return nullptr;
3903 return make<VectorType>(ElemType, /*Dimension=*/nullptr);
3906 // <decltype> ::= Dt <expression> E # decltype of an id-expression or class member access (C++0x)
3907 // ::= DT <expression> E # decltype of an expression (C++0x)
3908 template <typename Derived, typename Alloc>
3909 Node *AbstractManglingParser<Derived, Alloc>::parseDecltype() {
3910 if (!consumeIf('D'))
3911 return nullptr;
3912 if (!consumeIf('t') && !consumeIf('T'))
3913 return nullptr;
3914 Node *E = getDerived().parseExpr();
3915 if (E == nullptr)
3916 return nullptr;
3917 if (!consumeIf('E'))
3918 return nullptr;
3919 return make<EnclosingExpr>("decltype", E);
3922 // <array-type> ::= A <positive dimension number> _ <element type>
3923 // ::= A [<dimension expression>] _ <element type>
3924 template <typename Derived, typename Alloc>
3925 Node *AbstractManglingParser<Derived, Alloc>::parseArrayType() {
3926 if (!consumeIf('A'))
3927 return nullptr;
3929 Node *Dimension = nullptr;
3931 if (std::isdigit(look())) {
3932 Dimension = make<NameType>(parseNumber());
3933 if (!Dimension)
3934 return nullptr;
3935 if (!consumeIf('_'))
3936 return nullptr;
3937 } else if (!consumeIf('_')) {
3938 Node *DimExpr = getDerived().parseExpr();
3939 if (DimExpr == nullptr)
3940 return nullptr;
3941 if (!consumeIf('_'))
3942 return nullptr;
3943 Dimension = DimExpr;
3946 Node *Ty = getDerived().parseType();
3947 if (Ty == nullptr)
3948 return nullptr;
3949 return make<ArrayType>(Ty, Dimension);
3952 // <pointer-to-member-type> ::= M <class type> <member type>
3953 template <typename Derived, typename Alloc>
3954 Node *AbstractManglingParser<Derived, Alloc>::parsePointerToMemberType() {
3955 if (!consumeIf('M'))
3956 return nullptr;
3957 Node *ClassType = getDerived().parseType();
3958 if (ClassType == nullptr)
3959 return nullptr;
3960 Node *MemberType = getDerived().parseType();
3961 if (MemberType == nullptr)
3962 return nullptr;
3963 return make<PointerToMemberType>(ClassType, MemberType);
3966 // <class-enum-type> ::= <name> # non-dependent type name, dependent type name, or dependent typename-specifier
3967 // ::= Ts <name> # dependent elaborated type specifier using 'struct' or 'class'
3968 // ::= Tu <name> # dependent elaborated type specifier using 'union'
3969 // ::= Te <name> # dependent elaborated type specifier using 'enum'
3970 template <typename Derived, typename Alloc>
3971 Node *AbstractManglingParser<Derived, Alloc>::parseClassEnumType() {
3972 std::string_view ElabSpef;
3973 if (consumeIf("Ts"))
3974 ElabSpef = "struct";
3975 else if (consumeIf("Tu"))
3976 ElabSpef = "union";
3977 else if (consumeIf("Te"))
3978 ElabSpef = "enum";
3980 Node *Name = getDerived().parseName();
3981 if (Name == nullptr)
3982 return nullptr;
3984 if (!ElabSpef.empty())
3985 return make<ElaboratedTypeSpefType>(ElabSpef, Name);
3987 return Name;
3990 // <qualified-type> ::= <qualifiers> <type>
3991 // <qualifiers> ::= <extended-qualifier>* <CV-qualifiers>
3992 // <extended-qualifier> ::= U <source-name> [<template-args>] # vendor extended type qualifier
3993 template <typename Derived, typename Alloc>
3994 Node *AbstractManglingParser<Derived, Alloc>::parseQualifiedType() {
3995 if (consumeIf('U')) {
3996 std::string_view Qual = parseBareSourceName();
3997 if (Qual.empty())
3998 return nullptr;
4000 // extension ::= U <objc-name> <objc-type> # objc-type<identifier>
4001 if (starts_with(Qual, "objcproto")) {
4002 constexpr size_t Len = sizeof("objcproto") - 1;
4003 std::string_view ProtoSourceName(Qual.data() + Len, Qual.size() - Len);
4004 std::string_view Proto;
4006 ScopedOverride<const char *> SaveFirst(First, ProtoSourceName.data()),
4007 SaveLast(Last, &*ProtoSourceName.rbegin() + 1);
4008 Proto = parseBareSourceName();
4010 if (Proto.empty())
4011 return nullptr;
4012 Node *Child = getDerived().parseQualifiedType();
4013 if (Child == nullptr)
4014 return nullptr;
4015 return make<ObjCProtoName>(Child, Proto);
4018 Node *TA = nullptr;
4019 if (look() == 'I') {
4020 TA = getDerived().parseTemplateArgs();
4021 if (TA == nullptr)
4022 return nullptr;
4025 Node *Child = getDerived().parseQualifiedType();
4026 if (Child == nullptr)
4027 return nullptr;
4028 return make<VendorExtQualType>(Child, Qual, TA);
4031 Qualifiers Quals = parseCVQualifiers();
4032 Node *Ty = getDerived().parseType();
4033 if (Ty == nullptr)
4034 return nullptr;
4035 if (Quals != QualNone)
4036 Ty = make<QualType>(Ty, Quals);
4037 return Ty;
4040 // <type> ::= <builtin-type>
4041 // ::= <qualified-type>
4042 // ::= <function-type>
4043 // ::= <class-enum-type>
4044 // ::= <array-type>
4045 // ::= <pointer-to-member-type>
4046 // ::= <template-param>
4047 // ::= <template-template-param> <template-args>
4048 // ::= <decltype>
4049 // ::= P <type> # pointer
4050 // ::= R <type> # l-value reference
4051 // ::= O <type> # r-value reference (C++11)
4052 // ::= C <type> # complex pair (C99)
4053 // ::= G <type> # imaginary (C99)
4054 // ::= <substitution> # See Compression below
4055 // extension ::= U <objc-name> <objc-type> # objc-type<identifier>
4056 // extension ::= <vector-type> # <vector-type> starts with Dv
4058 // <objc-name> ::= <k0 number> objcproto <k1 number> <identifier> # k0 = 9 + <number of digits in k1> + k1
4059 // <objc-type> ::= <source-name> # PU<11+>objcproto 11objc_object<source-name> 11objc_object -> id<source-name>
4060 template <typename Derived, typename Alloc>
4061 Node *AbstractManglingParser<Derived, Alloc>::parseType() {
4062 Node *Result = nullptr;
4064 switch (look()) {
4065 // ::= <qualified-type>
4066 case 'r':
4067 case 'V':
4068 case 'K': {
4069 unsigned AfterQuals = 0;
4070 if (look(AfterQuals) == 'r') ++AfterQuals;
4071 if (look(AfterQuals) == 'V') ++AfterQuals;
4072 if (look(AfterQuals) == 'K') ++AfterQuals;
4074 if (look(AfterQuals) == 'F' ||
4075 (look(AfterQuals) == 'D' &&
4076 (look(AfterQuals + 1) == 'o' || look(AfterQuals + 1) == 'O' ||
4077 look(AfterQuals + 1) == 'w' || look(AfterQuals + 1) == 'x'))) {
4078 Result = getDerived().parseFunctionType();
4079 break;
4081 DEMANGLE_FALLTHROUGH;
4083 case 'U': {
4084 Result = getDerived().parseQualifiedType();
4085 break;
4087 // <builtin-type> ::= v # void
4088 case 'v':
4089 ++First;
4090 return make<NameType>("void");
4091 // ::= w # wchar_t
4092 case 'w':
4093 ++First;
4094 return make<NameType>("wchar_t");
4095 // ::= b # bool
4096 case 'b':
4097 ++First;
4098 return make<NameType>("bool");
4099 // ::= c # char
4100 case 'c':
4101 ++First;
4102 return make<NameType>("char");
4103 // ::= a # signed char
4104 case 'a':
4105 ++First;
4106 return make<NameType>("signed char");
4107 // ::= h # unsigned char
4108 case 'h':
4109 ++First;
4110 return make<NameType>("unsigned char");
4111 // ::= s # short
4112 case 's':
4113 ++First;
4114 return make<NameType>("short");
4115 // ::= t # unsigned short
4116 case 't':
4117 ++First;
4118 return make<NameType>("unsigned short");
4119 // ::= i # int
4120 case 'i':
4121 ++First;
4122 return make<NameType>("int");
4123 // ::= j # unsigned int
4124 case 'j':
4125 ++First;
4126 return make<NameType>("unsigned int");
4127 // ::= l # long
4128 case 'l':
4129 ++First;
4130 return make<NameType>("long");
4131 // ::= m # unsigned long
4132 case 'm':
4133 ++First;
4134 return make<NameType>("unsigned long");
4135 // ::= x # long long, __int64
4136 case 'x':
4137 ++First;
4138 return make<NameType>("long long");
4139 // ::= y # unsigned long long, __int64
4140 case 'y':
4141 ++First;
4142 return make<NameType>("unsigned long long");
4143 // ::= n # __int128
4144 case 'n':
4145 ++First;
4146 return make<NameType>("__int128");
4147 // ::= o # unsigned __int128
4148 case 'o':
4149 ++First;
4150 return make<NameType>("unsigned __int128");
4151 // ::= f # float
4152 case 'f':
4153 ++First;
4154 return make<NameType>("float");
4155 // ::= d # double
4156 case 'd':
4157 ++First;
4158 return make<NameType>("double");
4159 // ::= e # long double, __float80
4160 case 'e':
4161 ++First;
4162 return make<NameType>("long double");
4163 // ::= g # __float128
4164 case 'g':
4165 ++First;
4166 return make<NameType>("__float128");
4167 // ::= z # ellipsis
4168 case 'z':
4169 ++First;
4170 return make<NameType>("...");
4172 // <builtin-type> ::= u <source-name> # vendor extended type
4173 case 'u': {
4174 ++First;
4175 std::string_view Res = parseBareSourceName();
4176 if (Res.empty())
4177 return nullptr;
4178 // Typically, <builtin-type>s are not considered substitution candidates,
4179 // but the exception to that exception is vendor extended types (Itanium C++
4180 // ABI 5.9.1).
4181 if (consumeIf('I')) {
4182 Node *BaseType = parseType();
4183 if (BaseType == nullptr)
4184 return nullptr;
4185 if (!consumeIf('E'))
4186 return nullptr;
4187 Result = make<TransformedType>(Res, BaseType);
4188 } else
4189 Result = make<NameType>(Res);
4190 break;
4192 case 'D':
4193 switch (look(1)) {
4194 // ::= Dd # IEEE 754r decimal floating point (64 bits)
4195 case 'd':
4196 First += 2;
4197 return make<NameType>("decimal64");
4198 // ::= De # IEEE 754r decimal floating point (128 bits)
4199 case 'e':
4200 First += 2;
4201 return make<NameType>("decimal128");
4202 // ::= Df # IEEE 754r decimal floating point (32 bits)
4203 case 'f':
4204 First += 2;
4205 return make<NameType>("decimal32");
4206 // ::= Dh # IEEE 754r half-precision floating point (16 bits)
4207 case 'h':
4208 First += 2;
4209 return make<NameType>("half");
4210 // ::= DF <number> _ # ISO/IEC TS 18661 binary floating point (N bits)
4211 case 'F': {
4212 First += 2;
4213 Node *DimensionNumber = make<NameType>(parseNumber());
4214 if (!DimensionNumber)
4215 return nullptr;
4216 if (!consumeIf('_'))
4217 return nullptr;
4218 return make<BinaryFPType>(DimensionNumber);
4220 // ::= DB <number> _ # C23 signed _BitInt(N)
4221 // ::= DB <instantiation-dependent expression> _ # C23 signed _BitInt(N)
4222 // ::= DU <number> _ # C23 unsigned _BitInt(N)
4223 // ::= DU <instantiation-dependent expression> _ # C23 unsigned _BitInt(N)
4224 case 'B':
4225 case 'U': {
4226 bool Signed = look(1) == 'B';
4227 First += 2;
4228 Node *Size = std::isdigit(look()) ? make<NameType>(parseNumber())
4229 : getDerived().parseExpr();
4230 if (!Size)
4231 return nullptr;
4232 if (!consumeIf('_'))
4233 return nullptr;
4234 return make<BitIntType>(Size, Signed);
4236 // ::= Di # char32_t
4237 case 'i':
4238 First += 2;
4239 return make<NameType>("char32_t");
4240 // ::= Ds # char16_t
4241 case 's':
4242 First += 2;
4243 return make<NameType>("char16_t");
4244 // ::= Du # char8_t (C++2a, not yet in the Itanium spec)
4245 case 'u':
4246 First += 2;
4247 return make<NameType>("char8_t");
4248 // ::= Da # auto (in dependent new-expressions)
4249 case 'a':
4250 First += 2;
4251 return make<NameType>("auto");
4252 // ::= Dc # decltype(auto)
4253 case 'c':
4254 First += 2;
4255 return make<NameType>("decltype(auto)");
4256 // ::= Dk <type-constraint> # constrained auto
4257 // ::= DK <type-constraint> # constrained decltype(auto)
4258 case 'k':
4259 case 'K': {
4260 std::string_view Kind = look(1) == 'k' ? " auto" : " decltype(auto)";
4261 First += 2;
4262 Node *Constraint = getDerived().parseName();
4263 if (!Constraint)
4264 return nullptr;
4265 return make<PostfixQualifiedType>(Constraint, Kind);
4267 // ::= Dn # std::nullptr_t (i.e., decltype(nullptr))
4268 case 'n':
4269 First += 2;
4270 return make<NameType>("std::nullptr_t");
4272 // ::= <decltype>
4273 case 't':
4274 case 'T': {
4275 Result = getDerived().parseDecltype();
4276 break;
4278 // extension ::= <vector-type> # <vector-type> starts with Dv
4279 case 'v': {
4280 Result = getDerived().parseVectorType();
4281 break;
4283 // ::= Dp <type> # pack expansion (C++0x)
4284 case 'p': {
4285 First += 2;
4286 Node *Child = getDerived().parseType();
4287 if (!Child)
4288 return nullptr;
4289 Result = make<ParameterPackExpansion>(Child);
4290 break;
4292 // Exception specifier on a function type.
4293 case 'o':
4294 case 'O':
4295 case 'w':
4296 // Transaction safe function type.
4297 case 'x':
4298 Result = getDerived().parseFunctionType();
4299 break;
4301 break;
4302 // ::= <function-type>
4303 case 'F': {
4304 Result = getDerived().parseFunctionType();
4305 break;
4307 // ::= <array-type>
4308 case 'A': {
4309 Result = getDerived().parseArrayType();
4310 break;
4312 // ::= <pointer-to-member-type>
4313 case 'M': {
4314 Result = getDerived().parsePointerToMemberType();
4315 break;
4317 // ::= <template-param>
4318 case 'T': {
4319 // This could be an elaborate type specifier on a <class-enum-type>.
4320 if (look(1) == 's' || look(1) == 'u' || look(1) == 'e') {
4321 Result = getDerived().parseClassEnumType();
4322 break;
4325 Result = getDerived().parseTemplateParam();
4326 if (Result == nullptr)
4327 return nullptr;
4329 // Result could be either of:
4330 // <type> ::= <template-param>
4331 // <type> ::= <template-template-param> <template-args>
4333 // <template-template-param> ::= <template-param>
4334 // ::= <substitution>
4336 // If this is followed by some <template-args>, and we're permitted to
4337 // parse them, take the second production.
4339 if (TryToParseTemplateArgs && look() == 'I') {
4340 Node *TA = getDerived().parseTemplateArgs();
4341 if (TA == nullptr)
4342 return nullptr;
4343 Result = make<NameWithTemplateArgs>(Result, TA);
4345 break;
4347 // ::= P <type> # pointer
4348 case 'P': {
4349 ++First;
4350 Node *Ptr = getDerived().parseType();
4351 if (Ptr == nullptr)
4352 return nullptr;
4353 Result = make<PointerType>(Ptr);
4354 break;
4356 // ::= R <type> # l-value reference
4357 case 'R': {
4358 ++First;
4359 Node *Ref = getDerived().parseType();
4360 if (Ref == nullptr)
4361 return nullptr;
4362 Result = make<ReferenceType>(Ref, ReferenceKind::LValue);
4363 break;
4365 // ::= O <type> # r-value reference (C++11)
4366 case 'O': {
4367 ++First;
4368 Node *Ref = getDerived().parseType();
4369 if (Ref == nullptr)
4370 return nullptr;
4371 Result = make<ReferenceType>(Ref, ReferenceKind::RValue);
4372 break;
4374 // ::= C <type> # complex pair (C99)
4375 case 'C': {
4376 ++First;
4377 Node *P = getDerived().parseType();
4378 if (P == nullptr)
4379 return nullptr;
4380 Result = make<PostfixQualifiedType>(P, " complex");
4381 break;
4383 // ::= G <type> # imaginary (C99)
4384 case 'G': {
4385 ++First;
4386 Node *P = getDerived().parseType();
4387 if (P == nullptr)
4388 return P;
4389 Result = make<PostfixQualifiedType>(P, " imaginary");
4390 break;
4392 // ::= <substitution> # See Compression below
4393 case 'S': {
4394 if (look(1) != 't') {
4395 bool IsSubst = false;
4396 Result = getDerived().parseUnscopedName(nullptr, &IsSubst);
4397 if (!Result)
4398 return nullptr;
4400 // Sub could be either of:
4401 // <type> ::= <substitution>
4402 // <type> ::= <template-template-param> <template-args>
4404 // <template-template-param> ::= <template-param>
4405 // ::= <substitution>
4407 // If this is followed by some <template-args>, and we're permitted to
4408 // parse them, take the second production.
4410 if (look() == 'I' && (!IsSubst || TryToParseTemplateArgs)) {
4411 if (!IsSubst)
4412 Subs.push_back(Result);
4413 Node *TA = getDerived().parseTemplateArgs();
4414 if (TA == nullptr)
4415 return nullptr;
4416 Result = make<NameWithTemplateArgs>(Result, TA);
4417 } else if (IsSubst) {
4418 // If all we parsed was a substitution, don't re-insert into the
4419 // substitution table.
4420 return Result;
4422 break;
4424 DEMANGLE_FALLTHROUGH;
4426 // ::= <class-enum-type>
4427 default: {
4428 Result = getDerived().parseClassEnumType();
4429 break;
4433 // If we parsed a type, insert it into the substitution table. Note that all
4434 // <builtin-type>s and <substitution>s have already bailed out, because they
4435 // don't get substitutions.
4436 if (Result != nullptr)
4437 Subs.push_back(Result);
4438 return Result;
4441 template <typename Derived, typename Alloc>
4442 Node *
4443 AbstractManglingParser<Derived, Alloc>::parsePrefixExpr(std::string_view Kind,
4444 Node::Prec Prec) {
4445 Node *E = getDerived().parseExpr();
4446 if (E == nullptr)
4447 return nullptr;
4448 return make<PrefixExpr>(Kind, E, Prec);
4451 template <typename Derived, typename Alloc>
4452 Node *
4453 AbstractManglingParser<Derived, Alloc>::parseBinaryExpr(std::string_view Kind,
4454 Node::Prec Prec) {
4455 Node *LHS = getDerived().parseExpr();
4456 if (LHS == nullptr)
4457 return nullptr;
4458 Node *RHS = getDerived().parseExpr();
4459 if (RHS == nullptr)
4460 return nullptr;
4461 return make<BinaryExpr>(LHS, Kind, RHS, Prec);
4464 template <typename Derived, typename Alloc>
4465 Node *AbstractManglingParser<Derived, Alloc>::parseIntegerLiteral(
4466 std::string_view Lit) {
4467 std::string_view Tmp = parseNumber(true);
4468 if (!Tmp.empty() && consumeIf('E'))
4469 return make<IntegerLiteral>(Lit, Tmp);
4470 return nullptr;
4473 // <CV-Qualifiers> ::= [r] [V] [K]
4474 template <typename Alloc, typename Derived>
4475 Qualifiers AbstractManglingParser<Alloc, Derived>::parseCVQualifiers() {
4476 Qualifiers CVR = QualNone;
4477 if (consumeIf('r'))
4478 CVR |= QualRestrict;
4479 if (consumeIf('V'))
4480 CVR |= QualVolatile;
4481 if (consumeIf('K'))
4482 CVR |= QualConst;
4483 return CVR;
4486 // <function-param> ::= fp <top-level CV-Qualifiers> _ # L == 0, first parameter
4487 // ::= fp <top-level CV-Qualifiers> <parameter-2 non-negative number> _ # L == 0, second and later parameters
4488 // ::= fL <L-1 non-negative number> p <top-level CV-Qualifiers> _ # L > 0, first parameter
4489 // ::= fL <L-1 non-negative number> p <top-level CV-Qualifiers> <parameter-2 non-negative number> _ # L > 0, second and later parameters
4490 // ::= fpT # 'this' expression (not part of standard?)
4491 template <typename Derived, typename Alloc>
4492 Node *AbstractManglingParser<Derived, Alloc>::parseFunctionParam() {
4493 if (consumeIf("fpT"))
4494 return make<NameType>("this");
4495 if (consumeIf("fp")) {
4496 parseCVQualifiers();
4497 std::string_view Num = parseNumber();
4498 if (!consumeIf('_'))
4499 return nullptr;
4500 return make<FunctionParam>(Num);
4502 if (consumeIf("fL")) {
4503 if (parseNumber().empty())
4504 return nullptr;
4505 if (!consumeIf('p'))
4506 return nullptr;
4507 parseCVQualifiers();
4508 std::string_view Num = parseNumber();
4509 if (!consumeIf('_'))
4510 return nullptr;
4511 return make<FunctionParam>(Num);
4513 return nullptr;
4516 // cv <type> <expression> # conversion with one argument
4517 // cv <type> _ <expression>* E # conversion with a different number of arguments
4518 template <typename Derived, typename Alloc>
4519 Node *AbstractManglingParser<Derived, Alloc>::parseConversionExpr() {
4520 if (!consumeIf("cv"))
4521 return nullptr;
4522 Node *Ty;
4524 ScopedOverride<bool> SaveTemp(TryToParseTemplateArgs, false);
4525 Ty = getDerived().parseType();
4528 if (Ty == nullptr)
4529 return nullptr;
4531 if (consumeIf('_')) {
4532 size_t ExprsBegin = Names.size();
4533 while (!consumeIf('E')) {
4534 Node *E = getDerived().parseExpr();
4535 if (E == nullptr)
4536 return E;
4537 Names.push_back(E);
4539 NodeArray Exprs = popTrailingNodeArray(ExprsBegin);
4540 return make<ConversionExpr>(Ty, Exprs);
4543 Node *E[1] = {getDerived().parseExpr()};
4544 if (E[0] == nullptr)
4545 return nullptr;
4546 return make<ConversionExpr>(Ty, makeNodeArray(E, E + 1));
4549 // <expr-primary> ::= L <type> <value number> E # integer literal
4550 // ::= L <type> <value float> E # floating literal
4551 // ::= L <string type> E # string literal
4552 // ::= L <nullptr type> E # nullptr literal (i.e., "LDnE")
4553 // ::= L <lambda type> E # lambda expression
4554 // FIXME: ::= L <type> <real-part float> _ <imag-part float> E # complex floating point literal (C 2000)
4555 // ::= L <mangled-name> E # external name
4556 template <typename Derived, typename Alloc>
4557 Node *AbstractManglingParser<Derived, Alloc>::parseExprPrimary() {
4558 if (!consumeIf('L'))
4559 return nullptr;
4560 switch (look()) {
4561 case 'w':
4562 ++First;
4563 return getDerived().parseIntegerLiteral("wchar_t");
4564 case 'b':
4565 if (consumeIf("b0E"))
4566 return make<BoolExpr>(0);
4567 if (consumeIf("b1E"))
4568 return make<BoolExpr>(1);
4569 return nullptr;
4570 case 'c':
4571 ++First;
4572 return getDerived().parseIntegerLiteral("char");
4573 case 'a':
4574 ++First;
4575 return getDerived().parseIntegerLiteral("signed char");
4576 case 'h':
4577 ++First;
4578 return getDerived().parseIntegerLiteral("unsigned char");
4579 case 's':
4580 ++First;
4581 return getDerived().parseIntegerLiteral("short");
4582 case 't':
4583 ++First;
4584 return getDerived().parseIntegerLiteral("unsigned short");
4585 case 'i':
4586 ++First;
4587 return getDerived().parseIntegerLiteral("");
4588 case 'j':
4589 ++First;
4590 return getDerived().parseIntegerLiteral("u");
4591 case 'l':
4592 ++First;
4593 return getDerived().parseIntegerLiteral("l");
4594 case 'm':
4595 ++First;
4596 return getDerived().parseIntegerLiteral("ul");
4597 case 'x':
4598 ++First;
4599 return getDerived().parseIntegerLiteral("ll");
4600 case 'y':
4601 ++First;
4602 return getDerived().parseIntegerLiteral("ull");
4603 case 'n':
4604 ++First;
4605 return getDerived().parseIntegerLiteral("__int128");
4606 case 'o':
4607 ++First;
4608 return getDerived().parseIntegerLiteral("unsigned __int128");
4609 case 'f':
4610 ++First;
4611 return getDerived().template parseFloatingLiteral<float>();
4612 case 'd':
4613 ++First;
4614 return getDerived().template parseFloatingLiteral<double>();
4615 case 'e':
4616 ++First;
4617 #if defined(__powerpc__) || defined(__s390__)
4618 // Handle cases where long doubles encoded with e have the same size
4619 // and representation as doubles.
4620 return getDerived().template parseFloatingLiteral<double>();
4621 #else
4622 return getDerived().template parseFloatingLiteral<long double>();
4623 #endif
4624 case '_':
4625 if (consumeIf("_Z")) {
4626 Node *R = getDerived().parseEncoding();
4627 if (R != nullptr && consumeIf('E'))
4628 return R;
4630 return nullptr;
4631 case 'A': {
4632 Node *T = getDerived().parseType();
4633 if (T == nullptr)
4634 return nullptr;
4635 // FIXME: We need to include the string contents in the mangling.
4636 if (consumeIf('E'))
4637 return make<StringLiteral>(T);
4638 return nullptr;
4640 case 'D':
4641 if (consumeIf("Dn") && (consumeIf('0'), consumeIf('E')))
4642 return make<NameType>("nullptr");
4643 return nullptr;
4644 case 'T':
4645 // Invalid mangled name per
4646 // http://sourcerytools.com/pipermail/cxx-abi-dev/2011-August/002422.html
4647 return nullptr;
4648 case 'U': {
4649 // FIXME: Should we support LUb... for block literals?
4650 if (look(1) != 'l')
4651 return nullptr;
4652 Node *T = parseUnnamedTypeName(nullptr);
4653 if (!T || !consumeIf('E'))
4654 return nullptr;
4655 return make<LambdaExpr>(T);
4657 default: {
4658 // might be named type
4659 Node *T = getDerived().parseType();
4660 if (T == nullptr)
4661 return nullptr;
4662 std::string_view N = parseNumber(/*AllowNegative=*/true);
4663 if (N.empty())
4664 return nullptr;
4665 if (!consumeIf('E'))
4666 return nullptr;
4667 return make<EnumLiteral>(T, N);
4672 // <braced-expression> ::= <expression>
4673 // ::= di <field source-name> <braced-expression> # .name = expr
4674 // ::= dx <index expression> <braced-expression> # [expr] = expr
4675 // ::= dX <range begin expression> <range end expression> <braced-expression>
4676 template <typename Derived, typename Alloc>
4677 Node *AbstractManglingParser<Derived, Alloc>::parseBracedExpr() {
4678 if (look() == 'd') {
4679 switch (look(1)) {
4680 case 'i': {
4681 First += 2;
4682 Node *Field = getDerived().parseSourceName(/*NameState=*/nullptr);
4683 if (Field == nullptr)
4684 return nullptr;
4685 Node *Init = getDerived().parseBracedExpr();
4686 if (Init == nullptr)
4687 return nullptr;
4688 return make<BracedExpr>(Field, Init, /*isArray=*/false);
4690 case 'x': {
4691 First += 2;
4692 Node *Index = getDerived().parseExpr();
4693 if (Index == nullptr)
4694 return nullptr;
4695 Node *Init = getDerived().parseBracedExpr();
4696 if (Init == nullptr)
4697 return nullptr;
4698 return make<BracedExpr>(Index, Init, /*isArray=*/true);
4700 case 'X': {
4701 First += 2;
4702 Node *RangeBegin = getDerived().parseExpr();
4703 if (RangeBegin == nullptr)
4704 return nullptr;
4705 Node *RangeEnd = getDerived().parseExpr();
4706 if (RangeEnd == nullptr)
4707 return nullptr;
4708 Node *Init = getDerived().parseBracedExpr();
4709 if (Init == nullptr)
4710 return nullptr;
4711 return make<BracedRangeExpr>(RangeBegin, RangeEnd, Init);
4715 return getDerived().parseExpr();
4718 // (not yet in the spec)
4719 // <fold-expr> ::= fL <binary-operator-name> <expression> <expression>
4720 // ::= fR <binary-operator-name> <expression> <expression>
4721 // ::= fl <binary-operator-name> <expression>
4722 // ::= fr <binary-operator-name> <expression>
4723 template <typename Derived, typename Alloc>
4724 Node *AbstractManglingParser<Derived, Alloc>::parseFoldExpr() {
4725 if (!consumeIf('f'))
4726 return nullptr;
4728 bool IsLeftFold = false, HasInitializer = false;
4729 switch (look()) {
4730 default:
4731 return nullptr;
4732 case 'L':
4733 IsLeftFold = true;
4734 HasInitializer = true;
4735 break;
4736 case 'R':
4737 HasInitializer = true;
4738 break;
4739 case 'l':
4740 IsLeftFold = true;
4741 break;
4742 case 'r':
4743 break;
4745 ++First;
4747 const auto *Op = parseOperatorEncoding();
4748 if (!Op)
4749 return nullptr;
4750 if (!(Op->getKind() == OperatorInfo::Binary
4751 || (Op->getKind() == OperatorInfo::Member
4752 && Op->getName().back() == '*')))
4753 return nullptr;
4755 Node *Pack = getDerived().parseExpr();
4756 if (Pack == nullptr)
4757 return nullptr;
4759 Node *Init = nullptr;
4760 if (HasInitializer) {
4761 Init = getDerived().parseExpr();
4762 if (Init == nullptr)
4763 return nullptr;
4766 if (IsLeftFold && Init)
4767 std::swap(Pack, Init);
4769 return make<FoldExpr>(IsLeftFold, Op->getSymbol(), Pack, Init);
4772 // <expression> ::= mc <parameter type> <expr> [<offset number>] E
4774 // Not yet in the spec: https://github.com/itanium-cxx-abi/cxx-abi/issues/47
4775 template <typename Derived, typename Alloc>
4776 Node *
4777 AbstractManglingParser<Derived, Alloc>::parsePointerToMemberConversionExpr(
4778 Node::Prec Prec) {
4779 Node *Ty = getDerived().parseType();
4780 if (!Ty)
4781 return nullptr;
4782 Node *Expr = getDerived().parseExpr();
4783 if (!Expr)
4784 return nullptr;
4785 std::string_view Offset = getDerived().parseNumber(true);
4786 if (!consumeIf('E'))
4787 return nullptr;
4788 return make<PointerToMemberConversionExpr>(Ty, Expr, Offset, Prec);
4791 // <expression> ::= so <referent type> <expr> [<offset number>] <union-selector>* [p] E
4792 // <union-selector> ::= _ [<number>]
4794 // Not yet in the spec: https://github.com/itanium-cxx-abi/cxx-abi/issues/47
4795 template <typename Derived, typename Alloc>
4796 Node *AbstractManglingParser<Derived, Alloc>::parseSubobjectExpr() {
4797 Node *Ty = getDerived().parseType();
4798 if (!Ty)
4799 return nullptr;
4800 Node *Expr = getDerived().parseExpr();
4801 if (!Expr)
4802 return nullptr;
4803 std::string_view Offset = getDerived().parseNumber(true);
4804 size_t SelectorsBegin = Names.size();
4805 while (consumeIf('_')) {
4806 Node *Selector = make<NameType>(parseNumber());
4807 if (!Selector)
4808 return nullptr;
4809 Names.push_back(Selector);
4811 bool OnePastTheEnd = consumeIf('p');
4812 if (!consumeIf('E'))
4813 return nullptr;
4814 return make<SubobjectExpr>(
4815 Ty, Expr, Offset, popTrailingNodeArray(SelectorsBegin), OnePastTheEnd);
4818 template <typename Derived, typename Alloc>
4819 Node *AbstractManglingParser<Derived, Alloc>::parseConstraintExpr() {
4820 // Within this expression, all enclosing template parameter lists are in
4821 // scope.
4822 ScopedOverride<bool> SaveInConstraintExpr(InConstraintExpr, true);
4823 return getDerived().parseExpr();
4826 template <typename Derived, typename Alloc>
4827 Node *AbstractManglingParser<Derived, Alloc>::parseRequiresExpr() {
4828 NodeArray Params;
4829 if (consumeIf("rQ")) {
4830 // <expression> ::= rQ <bare-function-type> _ <requirement>+ E
4831 size_t ParamsBegin = Names.size();
4832 while (!consumeIf('_')) {
4833 Node *Type = getDerived().parseType();
4834 if (Type == nullptr)
4835 return nullptr;
4836 Names.push_back(Type);
4838 Params = popTrailingNodeArray(ParamsBegin);
4839 } else if (!consumeIf("rq")) {
4840 // <expression> ::= rq <requirement>+ E
4841 return nullptr;
4844 size_t ReqsBegin = Names.size();
4845 do {
4846 Node *Constraint = nullptr;
4847 if (consumeIf('X')) {
4848 // <requirement> ::= X <expression> [N] [R <type-constraint>]
4849 Node *Expr = getDerived().parseExpr();
4850 if (Expr == nullptr)
4851 return nullptr;
4852 bool Noexcept = consumeIf('N');
4853 Node *TypeReq = nullptr;
4854 if (consumeIf('R')) {
4855 TypeReq = getDerived().parseName();
4856 if (TypeReq == nullptr)
4857 return nullptr;
4859 Constraint = make<ExprRequirement>(Expr, Noexcept, TypeReq);
4860 } else if (consumeIf('T')) {
4861 // <requirement> ::= T <type>
4862 Node *Type = getDerived().parseType();
4863 if (Type == nullptr)
4864 return nullptr;
4865 Constraint = make<TypeRequirement>(Type);
4866 } else if (consumeIf('Q')) {
4867 // <requirement> ::= Q <constraint-expression>
4869 // FIXME: We use <expression> instead of <constraint-expression>. Either
4870 // the requires expression is already inside a constraint expression, in
4871 // which case it makes no difference, or we're in a requires-expression
4872 // that might be partially-substituted, where the language behavior is
4873 // not yet settled and clang mangles after substitution.
4874 Node *NestedReq = getDerived().parseExpr();
4875 if (NestedReq == nullptr)
4876 return nullptr;
4877 Constraint = make<NestedRequirement>(NestedReq);
4879 if (Constraint == nullptr)
4880 return nullptr;
4881 Names.push_back(Constraint);
4882 } while (!consumeIf('E'));
4884 return make<RequiresExpr>(Params, popTrailingNodeArray(ReqsBegin));
4887 // <expression> ::= <unary operator-name> <expression>
4888 // ::= <binary operator-name> <expression> <expression>
4889 // ::= <ternary operator-name> <expression> <expression> <expression>
4890 // ::= cl <expression>+ E # call
4891 // ::= cv <type> <expression> # conversion with one argument
4892 // ::= cv <type> _ <expression>* E # conversion with a different number of arguments
4893 // ::= [gs] nw <expression>* _ <type> E # new (expr-list) type
4894 // ::= [gs] nw <expression>* _ <type> <initializer> # new (expr-list) type (init)
4895 // ::= [gs] na <expression>* _ <type> E # new[] (expr-list) type
4896 // ::= [gs] na <expression>* _ <type> <initializer> # new[] (expr-list) type (init)
4897 // ::= [gs] dl <expression> # delete expression
4898 // ::= [gs] da <expression> # delete[] expression
4899 // ::= pp_ <expression> # prefix ++
4900 // ::= mm_ <expression> # prefix --
4901 // ::= ti <type> # typeid (type)
4902 // ::= te <expression> # typeid (expression)
4903 // ::= dc <type> <expression> # dynamic_cast<type> (expression)
4904 // ::= sc <type> <expression> # static_cast<type> (expression)
4905 // ::= cc <type> <expression> # const_cast<type> (expression)
4906 // ::= rc <type> <expression> # reinterpret_cast<type> (expression)
4907 // ::= st <type> # sizeof (a type)
4908 // ::= sz <expression> # sizeof (an expression)
4909 // ::= at <type> # alignof (a type)
4910 // ::= az <expression> # alignof (an expression)
4911 // ::= nx <expression> # noexcept (expression)
4912 // ::= <template-param>
4913 // ::= <function-param>
4914 // ::= dt <expression> <unresolved-name> # expr.name
4915 // ::= pt <expression> <unresolved-name> # expr->name
4916 // ::= ds <expression> <expression> # expr.*expr
4917 // ::= sZ <template-param> # size of a parameter pack
4918 // ::= sZ <function-param> # size of a function parameter pack
4919 // ::= sP <template-arg>* E # sizeof...(T), size of a captured template parameter pack from an alias template
4920 // ::= sp <expression> # pack expansion
4921 // ::= tw <expression> # throw expression
4922 // ::= tr # throw with no operand (rethrow)
4923 // ::= <unresolved-name> # f(p), N::f(p), ::f(p),
4924 // # freestanding dependent name (e.g., T::x),
4925 // # objectless nonstatic member reference
4926 // ::= fL <binary-operator-name> <expression> <expression>
4927 // ::= fR <binary-operator-name> <expression> <expression>
4928 // ::= fl <binary-operator-name> <expression>
4929 // ::= fr <binary-operator-name> <expression>
4930 // ::= <expr-primary>
4931 template <typename Derived, typename Alloc>
4932 Node *AbstractManglingParser<Derived, Alloc>::parseExpr() {
4933 bool Global = consumeIf("gs");
4935 const auto *Op = parseOperatorEncoding();
4936 if (Op) {
4937 auto Sym = Op->getSymbol();
4938 switch (Op->getKind()) {
4939 case OperatorInfo::Binary:
4940 // Binary operator: lhs @ rhs
4941 return getDerived().parseBinaryExpr(Sym, Op->getPrecedence());
4942 case OperatorInfo::Prefix:
4943 // Prefix unary operator: @ expr
4944 return getDerived().parsePrefixExpr(Sym, Op->getPrecedence());
4945 case OperatorInfo::Postfix: {
4946 // Postfix unary operator: expr @
4947 if (consumeIf('_'))
4948 return getDerived().parsePrefixExpr(Sym, Op->getPrecedence());
4949 Node *Ex = getDerived().parseExpr();
4950 if (Ex == nullptr)
4951 return nullptr;
4952 return make<PostfixExpr>(Ex, Sym, Op->getPrecedence());
4954 case OperatorInfo::Array: {
4955 // Array Index: lhs [ rhs ]
4956 Node *Base = getDerived().parseExpr();
4957 if (Base == nullptr)
4958 return nullptr;
4959 Node *Index = getDerived().parseExpr();
4960 if (Index == nullptr)
4961 return nullptr;
4962 return make<ArraySubscriptExpr>(Base, Index, Op->getPrecedence());
4964 case OperatorInfo::Member: {
4965 // Member access lhs @ rhs
4966 Node *LHS = getDerived().parseExpr();
4967 if (LHS == nullptr)
4968 return nullptr;
4969 Node *RHS = getDerived().parseExpr();
4970 if (RHS == nullptr)
4971 return nullptr;
4972 return make<MemberExpr>(LHS, Sym, RHS, Op->getPrecedence());
4974 case OperatorInfo::New: {
4975 // New
4976 // # new (expr-list) type [(init)]
4977 // [gs] nw <expression>* _ <type> [pi <expression>*] E
4978 // # new[] (expr-list) type [(init)]
4979 // [gs] na <expression>* _ <type> [pi <expression>*] E
4980 size_t Exprs = Names.size();
4981 while (!consumeIf('_')) {
4982 Node *Ex = getDerived().parseExpr();
4983 if (Ex == nullptr)
4984 return nullptr;
4985 Names.push_back(Ex);
4987 NodeArray ExprList = popTrailingNodeArray(Exprs);
4988 Node *Ty = getDerived().parseType();
4989 if (Ty == nullptr)
4990 return nullptr;
4991 bool HaveInits = consumeIf("pi");
4992 size_t InitsBegin = Names.size();
4993 while (!consumeIf('E')) {
4994 if (!HaveInits)
4995 return nullptr;
4996 Node *Init = getDerived().parseExpr();
4997 if (Init == nullptr)
4998 return Init;
4999 Names.push_back(Init);
5001 NodeArray Inits = popTrailingNodeArray(InitsBegin);
5002 return make<NewExpr>(ExprList, Ty, Inits, Global,
5003 /*IsArray=*/Op->getFlag(), Op->getPrecedence());
5005 case OperatorInfo::Del: {
5006 // Delete
5007 Node *Ex = getDerived().parseExpr();
5008 if (Ex == nullptr)
5009 return nullptr;
5010 return make<DeleteExpr>(Ex, Global, /*IsArray=*/Op->getFlag(),
5011 Op->getPrecedence());
5013 case OperatorInfo::Call: {
5014 // Function Call
5015 Node *Callee = getDerived().parseExpr();
5016 if (Callee == nullptr)
5017 return nullptr;
5018 size_t ExprsBegin = Names.size();
5019 while (!consumeIf('E')) {
5020 Node *E = getDerived().parseExpr();
5021 if (E == nullptr)
5022 return nullptr;
5023 Names.push_back(E);
5025 return make<CallExpr>(Callee, popTrailingNodeArray(ExprsBegin),
5026 Op->getPrecedence());
5028 case OperatorInfo::CCast: {
5029 // C Cast: (type)expr
5030 Node *Ty;
5032 ScopedOverride<bool> SaveTemp(TryToParseTemplateArgs, false);
5033 Ty = getDerived().parseType();
5035 if (Ty == nullptr)
5036 return nullptr;
5038 size_t ExprsBegin = Names.size();
5039 bool IsMany = consumeIf('_');
5040 while (!consumeIf('E')) {
5041 Node *E = getDerived().parseExpr();
5042 if (E == nullptr)
5043 return E;
5044 Names.push_back(E);
5045 if (!IsMany)
5046 break;
5048 NodeArray Exprs = popTrailingNodeArray(ExprsBegin);
5049 if (!IsMany && Exprs.size() != 1)
5050 return nullptr;
5051 return make<ConversionExpr>(Ty, Exprs, Op->getPrecedence());
5053 case OperatorInfo::Conditional: {
5054 // Conditional operator: expr ? expr : expr
5055 Node *Cond = getDerived().parseExpr();
5056 if (Cond == nullptr)
5057 return nullptr;
5058 Node *LHS = getDerived().parseExpr();
5059 if (LHS == nullptr)
5060 return nullptr;
5061 Node *RHS = getDerived().parseExpr();
5062 if (RHS == nullptr)
5063 return nullptr;
5064 return make<ConditionalExpr>(Cond, LHS, RHS, Op->getPrecedence());
5066 case OperatorInfo::NamedCast: {
5067 // Named cast operation, @<type>(expr)
5068 Node *Ty = getDerived().parseType();
5069 if (Ty == nullptr)
5070 return nullptr;
5071 Node *Ex = getDerived().parseExpr();
5072 if (Ex == nullptr)
5073 return nullptr;
5074 return make<CastExpr>(Sym, Ty, Ex, Op->getPrecedence());
5076 case OperatorInfo::OfIdOp: {
5077 // [sizeof/alignof/typeid] ( <type>|<expr> )
5078 Node *Arg =
5079 Op->getFlag() ? getDerived().parseType() : getDerived().parseExpr();
5080 if (!Arg)
5081 return nullptr;
5082 return make<EnclosingExpr>(Sym, Arg, Op->getPrecedence());
5084 case OperatorInfo::NameOnly: {
5085 // Not valid as an expression operand.
5086 return nullptr;
5089 DEMANGLE_UNREACHABLE;
5092 if (numLeft() < 2)
5093 return nullptr;
5095 if (look() == 'L')
5096 return getDerived().parseExprPrimary();
5097 if (look() == 'T')
5098 return getDerived().parseTemplateParam();
5099 if (look() == 'f') {
5100 // Disambiguate a fold expression from a <function-param>.
5101 if (look(1) == 'p' || (look(1) == 'L' && std::isdigit(look(2))))
5102 return getDerived().parseFunctionParam();
5103 return getDerived().parseFoldExpr();
5105 if (consumeIf("il")) {
5106 size_t InitsBegin = Names.size();
5107 while (!consumeIf('E')) {
5108 Node *E = getDerived().parseBracedExpr();
5109 if (E == nullptr)
5110 return nullptr;
5111 Names.push_back(E);
5113 return make<InitListExpr>(nullptr, popTrailingNodeArray(InitsBegin));
5115 if (consumeIf("mc"))
5116 return parsePointerToMemberConversionExpr(Node::Prec::Unary);
5117 if (consumeIf("nx")) {
5118 Node *Ex = getDerived().parseExpr();
5119 if (Ex == nullptr)
5120 return Ex;
5121 return make<EnclosingExpr>("noexcept ", Ex, Node::Prec::Unary);
5123 if (look() == 'r' && (look(1) == 'q' || look(1) == 'Q'))
5124 return parseRequiresExpr();
5125 if (consumeIf("so"))
5126 return parseSubobjectExpr();
5127 if (consumeIf("sp")) {
5128 Node *Child = getDerived().parseExpr();
5129 if (Child == nullptr)
5130 return nullptr;
5131 return make<ParameterPackExpansion>(Child);
5133 if (consumeIf("sZ")) {
5134 if (look() == 'T') {
5135 Node *R = getDerived().parseTemplateParam();
5136 if (R == nullptr)
5137 return nullptr;
5138 return make<SizeofParamPackExpr>(R);
5140 Node *FP = getDerived().parseFunctionParam();
5141 if (FP == nullptr)
5142 return nullptr;
5143 return make<EnclosingExpr>("sizeof... ", FP);
5145 if (consumeIf("sP")) {
5146 size_t ArgsBegin = Names.size();
5147 while (!consumeIf('E')) {
5148 Node *Arg = getDerived().parseTemplateArg();
5149 if (Arg == nullptr)
5150 return nullptr;
5151 Names.push_back(Arg);
5153 auto *Pack = make<NodeArrayNode>(popTrailingNodeArray(ArgsBegin));
5154 if (!Pack)
5155 return nullptr;
5156 return make<EnclosingExpr>("sizeof... ", Pack);
5158 if (consumeIf("tl")) {
5159 Node *Ty = getDerived().parseType();
5160 if (Ty == nullptr)
5161 return nullptr;
5162 size_t InitsBegin = Names.size();
5163 while (!consumeIf('E')) {
5164 Node *E = getDerived().parseBracedExpr();
5165 if (E == nullptr)
5166 return nullptr;
5167 Names.push_back(E);
5169 return make<InitListExpr>(Ty, popTrailingNodeArray(InitsBegin));
5171 if (consumeIf("tr"))
5172 return make<NameType>("throw");
5173 if (consumeIf("tw")) {
5174 Node *Ex = getDerived().parseExpr();
5175 if (Ex == nullptr)
5176 return nullptr;
5177 return make<ThrowExpr>(Ex);
5179 if (consumeIf('u')) {
5180 Node *Name = getDerived().parseSourceName(/*NameState=*/nullptr);
5181 if (!Name)
5182 return nullptr;
5183 // Special case legacy __uuidof mangling. The 't' and 'z' appear where the
5184 // standard encoding expects a <template-arg>, and would be otherwise be
5185 // interpreted as <type> node 'short' or 'ellipsis'. However, neither
5186 // __uuidof(short) nor __uuidof(...) can actually appear, so there is no
5187 // actual conflict here.
5188 bool IsUUID = false;
5189 Node *UUID = nullptr;
5190 if (Name->getBaseName() == "__uuidof") {
5191 if (consumeIf('t')) {
5192 UUID = getDerived().parseType();
5193 IsUUID = true;
5194 } else if (consumeIf('z')) {
5195 UUID = getDerived().parseExpr();
5196 IsUUID = true;
5199 size_t ExprsBegin = Names.size();
5200 if (IsUUID) {
5201 if (UUID == nullptr)
5202 return nullptr;
5203 Names.push_back(UUID);
5204 } else {
5205 while (!consumeIf('E')) {
5206 Node *E = getDerived().parseTemplateArg();
5207 if (E == nullptr)
5208 return E;
5209 Names.push_back(E);
5212 return make<CallExpr>(Name, popTrailingNodeArray(ExprsBegin),
5213 Node::Prec::Postfix);
5216 // Only unresolved names remain.
5217 return getDerived().parseUnresolvedName(Global);
5220 // <call-offset> ::= h <nv-offset> _
5221 // ::= v <v-offset> _
5223 // <nv-offset> ::= <offset number>
5224 // # non-virtual base override
5226 // <v-offset> ::= <offset number> _ <virtual offset number>
5227 // # virtual base override, with vcall offset
5228 template <typename Alloc, typename Derived>
5229 bool AbstractManglingParser<Alloc, Derived>::parseCallOffset() {
5230 // Just scan through the call offset, we never add this information into the
5231 // output.
5232 if (consumeIf('h'))
5233 return parseNumber(true).empty() || !consumeIf('_');
5234 if (consumeIf('v'))
5235 return parseNumber(true).empty() || !consumeIf('_') ||
5236 parseNumber(true).empty() || !consumeIf('_');
5237 return true;
5240 // <special-name> ::= TV <type> # virtual table
5241 // ::= TT <type> # VTT structure (construction vtable index)
5242 // ::= TI <type> # typeinfo structure
5243 // ::= TS <type> # typeinfo name (null-terminated byte string)
5244 // ::= Tc <call-offset> <call-offset> <base encoding>
5245 // # base is the nominal target function of thunk
5246 // # first call-offset is 'this' adjustment
5247 // # second call-offset is result adjustment
5248 // ::= T <call-offset> <base encoding>
5249 // # base is the nominal target function of thunk
5250 // # Guard variable for one-time initialization
5251 // ::= GV <object name>
5252 // # No <type>
5253 // ::= TW <object name> # Thread-local wrapper
5254 // ::= TH <object name> # Thread-local initialization
5255 // ::= GR <object name> _ # First temporary
5256 // ::= GR <object name> <seq-id> _ # Subsequent temporaries
5257 // # construction vtable for second-in-first
5258 // extension ::= TC <first type> <number> _ <second type>
5259 // extension ::= GR <object name> # reference temporary for object
5260 // extension ::= GI <module name> # module global initializer
5261 template <typename Derived, typename Alloc>
5262 Node *AbstractManglingParser<Derived, Alloc>::parseSpecialName() {
5263 switch (look()) {
5264 case 'T':
5265 switch (look(1)) {
5266 // TA <template-arg> # template parameter object
5268 // Not yet in the spec: https://github.com/itanium-cxx-abi/cxx-abi/issues/63
5269 case 'A': {
5270 First += 2;
5271 Node *Arg = getDerived().parseTemplateArg();
5272 if (Arg == nullptr)
5273 return nullptr;
5274 return make<SpecialName>("template parameter object for ", Arg);
5276 // TV <type> # virtual table
5277 case 'V': {
5278 First += 2;
5279 Node *Ty = getDerived().parseType();
5280 if (Ty == nullptr)
5281 return nullptr;
5282 return make<SpecialName>("vtable for ", Ty);
5284 // TT <type> # VTT structure (construction vtable index)
5285 case 'T': {
5286 First += 2;
5287 Node *Ty = getDerived().parseType();
5288 if (Ty == nullptr)
5289 return nullptr;
5290 return make<SpecialName>("VTT for ", Ty);
5292 // TI <type> # typeinfo structure
5293 case 'I': {
5294 First += 2;
5295 Node *Ty = getDerived().parseType();
5296 if (Ty == nullptr)
5297 return nullptr;
5298 return make<SpecialName>("typeinfo for ", Ty);
5300 // TS <type> # typeinfo name (null-terminated byte string)
5301 case 'S': {
5302 First += 2;
5303 Node *Ty = getDerived().parseType();
5304 if (Ty == nullptr)
5305 return nullptr;
5306 return make<SpecialName>("typeinfo name for ", Ty);
5308 // Tc <call-offset> <call-offset> <base encoding>
5309 case 'c': {
5310 First += 2;
5311 if (parseCallOffset() || parseCallOffset())
5312 return nullptr;
5313 Node *Encoding = getDerived().parseEncoding();
5314 if (Encoding == nullptr)
5315 return nullptr;
5316 return make<SpecialName>("covariant return thunk to ", Encoding);
5318 // extension ::= TC <first type> <number> _ <second type>
5319 // # construction vtable for second-in-first
5320 case 'C': {
5321 First += 2;
5322 Node *FirstType = getDerived().parseType();
5323 if (FirstType == nullptr)
5324 return nullptr;
5325 if (parseNumber(true).empty() || !consumeIf('_'))
5326 return nullptr;
5327 Node *SecondType = getDerived().parseType();
5328 if (SecondType == nullptr)
5329 return nullptr;
5330 return make<CtorVtableSpecialName>(SecondType, FirstType);
5332 // TW <object name> # Thread-local wrapper
5333 case 'W': {
5334 First += 2;
5335 Node *Name = getDerived().parseName();
5336 if (Name == nullptr)
5337 return nullptr;
5338 return make<SpecialName>("thread-local wrapper routine for ", Name);
5340 // TH <object name> # Thread-local initialization
5341 case 'H': {
5342 First += 2;
5343 Node *Name = getDerived().parseName();
5344 if (Name == nullptr)
5345 return nullptr;
5346 return make<SpecialName>("thread-local initialization routine for ", Name);
5348 // T <call-offset> <base encoding>
5349 default: {
5350 ++First;
5351 bool IsVirt = look() == 'v';
5352 if (parseCallOffset())
5353 return nullptr;
5354 Node *BaseEncoding = getDerived().parseEncoding();
5355 if (BaseEncoding == nullptr)
5356 return nullptr;
5357 if (IsVirt)
5358 return make<SpecialName>("virtual thunk to ", BaseEncoding);
5359 else
5360 return make<SpecialName>("non-virtual thunk to ", BaseEncoding);
5363 case 'G':
5364 switch (look(1)) {
5365 // GV <object name> # Guard variable for one-time initialization
5366 case 'V': {
5367 First += 2;
5368 Node *Name = getDerived().parseName();
5369 if (Name == nullptr)
5370 return nullptr;
5371 return make<SpecialName>("guard variable for ", Name);
5373 // GR <object name> # reference temporary for object
5374 // GR <object name> _ # First temporary
5375 // GR <object name> <seq-id> _ # Subsequent temporaries
5376 case 'R': {
5377 First += 2;
5378 Node *Name = getDerived().parseName();
5379 if (Name == nullptr)
5380 return nullptr;
5381 size_t Count;
5382 bool ParsedSeqId = !parseSeqId(&Count);
5383 if (!consumeIf('_') && ParsedSeqId)
5384 return nullptr;
5385 return make<SpecialName>("reference temporary for ", Name);
5387 // GI <module-name> v
5388 case 'I': {
5389 First += 2;
5390 ModuleName *Module = nullptr;
5391 if (getDerived().parseModuleNameOpt(Module))
5392 return nullptr;
5393 if (Module == nullptr)
5394 return nullptr;
5395 return make<SpecialName>("initializer for module ", Module);
5399 return nullptr;
5402 // <encoding> ::= <function name> <bare-function-type>
5403 // [`Q` <requires-clause expr>]
5404 // ::= <data name>
5405 // ::= <special-name>
5406 template <typename Derived, typename Alloc>
5407 Node *AbstractManglingParser<Derived, Alloc>::parseEncoding(bool ParseParams) {
5408 // The template parameters of an encoding are unrelated to those of the
5409 // enclosing context.
5410 SaveTemplateParams SaveTemplateParamsScope(this);
5412 if (look() == 'G' || look() == 'T')
5413 return getDerived().parseSpecialName();
5415 auto IsEndOfEncoding = [&] {
5416 // The set of chars that can potentially follow an <encoding> (none of which
5417 // can start a <type>). Enumerating these allows us to avoid speculative
5418 // parsing.
5419 return numLeft() == 0 || look() == 'E' || look() == '.' || look() == '_';
5422 NameState NameInfo(this);
5423 Node *Name = getDerived().parseName(&NameInfo);
5424 if (Name == nullptr)
5425 return nullptr;
5427 if (resolveForwardTemplateRefs(NameInfo))
5428 return nullptr;
5430 if (IsEndOfEncoding())
5431 return Name;
5433 // ParseParams may be false at the top level only, when called from parse().
5434 // For example in the mangled name _Z3fooILZ3BarEET_f, ParseParams may be
5435 // false when demangling 3fooILZ3BarEET_f but is always true when demangling
5436 // 3Bar.
5437 if (!ParseParams) {
5438 while (consume())
5440 return Name;
5443 Node *Attrs = nullptr;
5444 if (consumeIf("Ua9enable_ifI")) {
5445 size_t BeforeArgs = Names.size();
5446 while (!consumeIf('E')) {
5447 Node *Arg = getDerived().parseTemplateArg();
5448 if (Arg == nullptr)
5449 return nullptr;
5450 Names.push_back(Arg);
5452 Attrs = make<EnableIfAttr>(popTrailingNodeArray(BeforeArgs));
5453 if (!Attrs)
5454 return nullptr;
5457 Node *ReturnType = nullptr;
5458 if (!NameInfo.CtorDtorConversion && NameInfo.EndsWithTemplateArgs) {
5459 ReturnType = getDerived().parseType();
5460 if (ReturnType == nullptr)
5461 return nullptr;
5464 NodeArray Params;
5465 if (!consumeIf('v')) {
5466 size_t ParamsBegin = Names.size();
5467 do {
5468 Node *Ty = getDerived().parseType();
5469 if (Ty == nullptr)
5470 return nullptr;
5472 const bool IsFirstParam = ParamsBegin == Names.size();
5473 if (NameInfo.HasExplicitObjectParameter && IsFirstParam)
5474 Ty = make<ExplicitObjectParameter>(Ty);
5476 if (Ty == nullptr)
5477 return nullptr;
5479 Names.push_back(Ty);
5480 } while (!IsEndOfEncoding() && look() != 'Q');
5481 Params = popTrailingNodeArray(ParamsBegin);
5484 Node *Requires = nullptr;
5485 if (consumeIf('Q')) {
5486 Requires = getDerived().parseConstraintExpr();
5487 if (!Requires)
5488 return nullptr;
5491 return make<FunctionEncoding>(ReturnType, Name, Params, Attrs, Requires,
5492 NameInfo.CVQualifiers,
5493 NameInfo.ReferenceQualifier);
5496 template <class Float>
5497 struct FloatData;
5499 template <>
5500 struct FloatData<float>
5502 static const size_t mangled_size = 8;
5503 static const size_t max_demangled_size = 24;
5504 static constexpr const char* spec = "%af";
5507 template <>
5508 struct FloatData<double>
5510 static const size_t mangled_size = 16;
5511 static const size_t max_demangled_size = 32;
5512 static constexpr const char* spec = "%a";
5515 template <>
5516 struct FloatData<long double>
5518 #if defined(__mips__) && defined(__mips_n64) || defined(__aarch64__) || \
5519 defined(__wasm__) || defined(__riscv) || defined(__loongarch__) || \
5520 defined(__ve__)
5521 static const size_t mangled_size = 32;
5522 #elif defined(__arm__) || defined(__mips__) || defined(__hexagon__)
5523 static const size_t mangled_size = 16;
5524 #else
5525 static const size_t mangled_size = 20; // May need to be adjusted to 16 or 24 on other platforms
5526 #endif
5527 // `-0x1.ffffffffffffffffffffffffffffp+16383` + 'L' + '\0' == 42 bytes.
5528 // 28 'f's * 4 bits == 112 bits, which is the number of mantissa bits.
5529 // Negatives are one character longer than positives.
5530 // `0x1.` and `p` are constant, and exponents `+16383` and `-16382` are the
5531 // same length. 1 sign bit, 112 mantissa bits, and 15 exponent bits == 128.
5532 static const size_t max_demangled_size = 42;
5533 static constexpr const char *spec = "%LaL";
5536 template <typename Alloc, typename Derived>
5537 template <class Float>
5538 Node *AbstractManglingParser<Alloc, Derived>::parseFloatingLiteral() {
5539 const size_t N = FloatData<Float>::mangled_size;
5540 if (numLeft() <= N)
5541 return nullptr;
5542 std::string_view Data(First, N);
5543 for (char C : Data)
5544 if (!(C >= '0' && C <= '9') && !(C >= 'a' && C <= 'f'))
5545 return nullptr;
5546 First += N;
5547 if (!consumeIf('E'))
5548 return nullptr;
5549 return make<FloatLiteralImpl<Float>>(Data);
5552 // <seq-id> ::= <0-9A-Z>+
5553 template <typename Alloc, typename Derived>
5554 bool AbstractManglingParser<Alloc, Derived>::parseSeqId(size_t *Out) {
5555 if (!(look() >= '0' && look() <= '9') &&
5556 !(look() >= 'A' && look() <= 'Z'))
5557 return true;
5559 size_t Id = 0;
5560 while (true) {
5561 if (look() >= '0' && look() <= '9') {
5562 Id *= 36;
5563 Id += static_cast<size_t>(look() - '0');
5564 } else if (look() >= 'A' && look() <= 'Z') {
5565 Id *= 36;
5566 Id += static_cast<size_t>(look() - 'A') + 10;
5567 } else {
5568 *Out = Id;
5569 return false;
5571 ++First;
5575 // <substitution> ::= S <seq-id> _
5576 // ::= S_
5577 // <substitution> ::= Sa # ::std::allocator
5578 // <substitution> ::= Sb # ::std::basic_string
5579 // <substitution> ::= Ss # ::std::basic_string < char,
5580 // ::std::char_traits<char>,
5581 // ::std::allocator<char> >
5582 // <substitution> ::= Si # ::std::basic_istream<char, std::char_traits<char> >
5583 // <substitution> ::= So # ::std::basic_ostream<char, std::char_traits<char> >
5584 // <substitution> ::= Sd # ::std::basic_iostream<char, std::char_traits<char> >
5585 // The St case is handled specially in parseNestedName.
5586 template <typename Derived, typename Alloc>
5587 Node *AbstractManglingParser<Derived, Alloc>::parseSubstitution() {
5588 if (!consumeIf('S'))
5589 return nullptr;
5591 if (look() >= 'a' && look() <= 'z') {
5592 SpecialSubKind Kind;
5593 switch (look()) {
5594 case 'a':
5595 Kind = SpecialSubKind::allocator;
5596 break;
5597 case 'b':
5598 Kind = SpecialSubKind::basic_string;
5599 break;
5600 case 'd':
5601 Kind = SpecialSubKind::iostream;
5602 break;
5603 case 'i':
5604 Kind = SpecialSubKind::istream;
5605 break;
5606 case 'o':
5607 Kind = SpecialSubKind::ostream;
5608 break;
5609 case 's':
5610 Kind = SpecialSubKind::string;
5611 break;
5612 default:
5613 return nullptr;
5615 ++First;
5616 auto *SpecialSub = make<SpecialSubstitution>(Kind);
5617 if (!SpecialSub)
5618 return nullptr;
5620 // Itanium C++ ABI 5.1.2: If a name that would use a built-in <substitution>
5621 // has ABI tags, the tags are appended to the substitution; the result is a
5622 // substitutable component.
5623 Node *WithTags = getDerived().parseAbiTags(SpecialSub);
5624 if (WithTags != SpecialSub) {
5625 Subs.push_back(WithTags);
5626 SpecialSub = WithTags;
5628 return SpecialSub;
5631 // ::= S_
5632 if (consumeIf('_')) {
5633 if (Subs.empty())
5634 return nullptr;
5635 return Subs[0];
5638 // ::= S <seq-id> _
5639 size_t Index = 0;
5640 if (parseSeqId(&Index))
5641 return nullptr;
5642 ++Index;
5643 if (!consumeIf('_') || Index >= Subs.size())
5644 return nullptr;
5645 return Subs[Index];
5648 // <template-param> ::= T_ # first template parameter
5649 // ::= T <parameter-2 non-negative number> _
5650 // ::= TL <level-1> __
5651 // ::= TL <level-1> _ <parameter-2 non-negative number> _
5652 template <typename Derived, typename Alloc>
5653 Node *AbstractManglingParser<Derived, Alloc>::parseTemplateParam() {
5654 const char *Begin = First;
5655 if (!consumeIf('T'))
5656 return nullptr;
5658 size_t Level = 0;
5659 if (consumeIf('L')) {
5660 if (parsePositiveInteger(&Level))
5661 return nullptr;
5662 ++Level;
5663 if (!consumeIf('_'))
5664 return nullptr;
5667 size_t Index = 0;
5668 if (!consumeIf('_')) {
5669 if (parsePositiveInteger(&Index))
5670 return nullptr;
5671 ++Index;
5672 if (!consumeIf('_'))
5673 return nullptr;
5676 // We don't track enclosing template parameter levels well enough to reliably
5677 // substitute them all within a <constraint-expression>, so print the
5678 // parameter numbering instead for now.
5679 // TODO: Track all enclosing template parameters and substitute them here.
5680 if (InConstraintExpr) {
5681 return make<NameType>(std::string_view(Begin, First - 1 - Begin));
5684 // If we're in a context where this <template-param> refers to a
5685 // <template-arg> further ahead in the mangled name (currently just conversion
5686 // operator types), then we should only look it up in the right context.
5687 // This can only happen at the outermost level.
5688 if (PermitForwardTemplateReferences && Level == 0) {
5689 Node *ForwardRef = make<ForwardTemplateReference>(Index);
5690 if (!ForwardRef)
5691 return nullptr;
5692 DEMANGLE_ASSERT(ForwardRef->getKind() == Node::KForwardTemplateReference,
5693 "");
5694 ForwardTemplateRefs.push_back(
5695 static_cast<ForwardTemplateReference *>(ForwardRef));
5696 return ForwardRef;
5699 if (Level >= TemplateParams.size() || !TemplateParams[Level] ||
5700 Index >= TemplateParams[Level]->size()) {
5701 // Itanium ABI 5.1.8: In a generic lambda, uses of auto in the parameter
5702 // list are mangled as the corresponding artificial template type parameter.
5703 if (ParsingLambdaParamsAtLevel == Level && Level <= TemplateParams.size()) {
5704 // This will be popped by the ScopedTemplateParamList in
5705 // parseUnnamedTypeName.
5706 if (Level == TemplateParams.size())
5707 TemplateParams.push_back(nullptr);
5708 return make<NameType>("auto");
5711 return nullptr;
5714 return (*TemplateParams[Level])[Index];
5717 // <template-param-decl> ::= Ty # type parameter
5718 // ::= Tk <concept name> [<template-args>] # constrained type parameter
5719 // ::= Tn <type> # non-type parameter
5720 // ::= Tt <template-param-decl>* E # template parameter
5721 // ::= Tp <template-param-decl> # parameter pack
5722 template <typename Derived, typename Alloc>
5723 Node *AbstractManglingParser<Derived, Alloc>::parseTemplateParamDecl(
5724 TemplateParamList *Params) {
5725 auto InventTemplateParamName = [&](TemplateParamKind Kind) {
5726 unsigned Index = NumSyntheticTemplateParameters[(int)Kind]++;
5727 Node *N = make<SyntheticTemplateParamName>(Kind, Index);
5728 if (N && Params)
5729 Params->push_back(N);
5730 return N;
5733 if (consumeIf("Ty")) {
5734 Node *Name = InventTemplateParamName(TemplateParamKind::Type);
5735 if (!Name)
5736 return nullptr;
5737 return make<TypeTemplateParamDecl>(Name);
5740 if (consumeIf("Tk")) {
5741 Node *Constraint = getDerived().parseName();
5742 if (!Constraint)
5743 return nullptr;
5744 Node *Name = InventTemplateParamName(TemplateParamKind::Type);
5745 if (!Name)
5746 return nullptr;
5747 return make<ConstrainedTypeTemplateParamDecl>(Constraint, Name);
5750 if (consumeIf("Tn")) {
5751 Node *Name = InventTemplateParamName(TemplateParamKind::NonType);
5752 if (!Name)
5753 return nullptr;
5754 Node *Type = parseType();
5755 if (!Type)
5756 return nullptr;
5757 return make<NonTypeTemplateParamDecl>(Name, Type);
5760 if (consumeIf("Tt")) {
5761 Node *Name = InventTemplateParamName(TemplateParamKind::Template);
5762 if (!Name)
5763 return nullptr;
5764 size_t ParamsBegin = Names.size();
5765 ScopedTemplateParamList TemplateTemplateParamParams(this);
5766 Node *Requires = nullptr;
5767 while (!consumeIf('E')) {
5768 Node *P = parseTemplateParamDecl(TemplateTemplateParamParams.params());
5769 if (!P)
5770 return nullptr;
5771 Names.push_back(P);
5772 if (consumeIf('Q')) {
5773 Requires = getDerived().parseConstraintExpr();
5774 if (Requires == nullptr || !consumeIf('E'))
5775 return nullptr;
5776 break;
5779 NodeArray InnerParams = popTrailingNodeArray(ParamsBegin);
5780 return make<TemplateTemplateParamDecl>(Name, InnerParams, Requires);
5783 if (consumeIf("Tp")) {
5784 Node *P = parseTemplateParamDecl(Params);
5785 if (!P)
5786 return nullptr;
5787 return make<TemplateParamPackDecl>(P);
5790 return nullptr;
5793 // <template-arg> ::= <type> # type or template
5794 // ::= X <expression> E # expression
5795 // ::= <expr-primary> # simple expressions
5796 // ::= J <template-arg>* E # argument pack
5797 // ::= LZ <encoding> E # extension
5798 // ::= <template-param-decl> <template-arg>
5799 template <typename Derived, typename Alloc>
5800 Node *AbstractManglingParser<Derived, Alloc>::parseTemplateArg() {
5801 switch (look()) {
5802 case 'X': {
5803 ++First;
5804 Node *Arg = getDerived().parseExpr();
5805 if (Arg == nullptr || !consumeIf('E'))
5806 return nullptr;
5807 return Arg;
5809 case 'J': {
5810 ++First;
5811 size_t ArgsBegin = Names.size();
5812 while (!consumeIf('E')) {
5813 Node *Arg = getDerived().parseTemplateArg();
5814 if (Arg == nullptr)
5815 return nullptr;
5816 Names.push_back(Arg);
5818 NodeArray Args = popTrailingNodeArray(ArgsBegin);
5819 return make<TemplateArgumentPack>(Args);
5821 case 'L': {
5822 // ::= LZ <encoding> E # extension
5823 if (look(1) == 'Z') {
5824 First += 2;
5825 Node *Arg = getDerived().parseEncoding();
5826 if (Arg == nullptr || !consumeIf('E'))
5827 return nullptr;
5828 return Arg;
5830 // ::= <expr-primary> # simple expressions
5831 return getDerived().parseExprPrimary();
5833 case 'T': {
5834 // Either <template-param> or a <template-param-decl> <template-arg>.
5835 if (!getDerived().isTemplateParamDecl())
5836 return getDerived().parseType();
5837 Node *Param = getDerived().parseTemplateParamDecl(nullptr);
5838 if (!Param)
5839 return nullptr;
5840 Node *Arg = getDerived().parseTemplateArg();
5841 if (!Arg)
5842 return nullptr;
5843 return make<TemplateParamQualifiedArg>(Param, Arg);
5845 default:
5846 return getDerived().parseType();
5850 // <template-args> ::= I <template-arg>* [Q <requires-clause expr>] E
5851 // extension, the abi says <template-arg>+
5852 template <typename Derived, typename Alloc>
5853 Node *
5854 AbstractManglingParser<Derived, Alloc>::parseTemplateArgs(bool TagTemplates) {
5855 if (!consumeIf('I'))
5856 return nullptr;
5858 // <template-params> refer to the innermost <template-args>. Clear out any
5859 // outer args that we may have inserted into TemplateParams.
5860 if (TagTemplates) {
5861 TemplateParams.clear();
5862 TemplateParams.push_back(&OuterTemplateParams);
5863 OuterTemplateParams.clear();
5866 size_t ArgsBegin = Names.size();
5867 Node *Requires = nullptr;
5868 while (!consumeIf('E')) {
5869 if (TagTemplates) {
5870 Node *Arg = getDerived().parseTemplateArg();
5871 if (Arg == nullptr)
5872 return nullptr;
5873 Names.push_back(Arg);
5874 Node *TableEntry = Arg;
5875 if (Arg->getKind() == Node::KTemplateParamQualifiedArg) {
5876 TableEntry =
5877 static_cast<TemplateParamQualifiedArg *>(TableEntry)->getArg();
5879 if (Arg->getKind() == Node::KTemplateArgumentPack) {
5880 TableEntry = make<ParameterPack>(
5881 static_cast<TemplateArgumentPack*>(TableEntry)->getElements());
5882 if (!TableEntry)
5883 return nullptr;
5885 OuterTemplateParams.push_back(TableEntry);
5886 } else {
5887 Node *Arg = getDerived().parseTemplateArg();
5888 if (Arg == nullptr)
5889 return nullptr;
5890 Names.push_back(Arg);
5892 if (consumeIf('Q')) {
5893 Requires = getDerived().parseConstraintExpr();
5894 if (!Requires || !consumeIf('E'))
5895 return nullptr;
5896 break;
5899 return make<TemplateArgs>(popTrailingNodeArray(ArgsBegin), Requires);
5902 // <mangled-name> ::= _Z <encoding>
5903 // ::= <type>
5904 // extension ::= ___Z <encoding> _block_invoke
5905 // extension ::= ___Z <encoding> _block_invoke<decimal-digit>+
5906 // extension ::= ___Z <encoding> _block_invoke_<decimal-digit>+
5907 template <typename Derived, typename Alloc>
5908 Node *AbstractManglingParser<Derived, Alloc>::parse(bool ParseParams) {
5909 if (consumeIf("_Z") || consumeIf("__Z")) {
5910 Node *Encoding = getDerived().parseEncoding(ParseParams);
5911 if (Encoding == nullptr)
5912 return nullptr;
5913 if (look() == '.') {
5914 Encoding =
5915 make<DotSuffix>(Encoding, std::string_view(First, Last - First));
5916 First = Last;
5918 if (numLeft() != 0)
5919 return nullptr;
5920 return Encoding;
5923 if (consumeIf("___Z") || consumeIf("____Z")) {
5924 Node *Encoding = getDerived().parseEncoding(ParseParams);
5925 if (Encoding == nullptr || !consumeIf("_block_invoke"))
5926 return nullptr;
5927 bool RequireNumber = consumeIf('_');
5928 if (parseNumber().empty() && RequireNumber)
5929 return nullptr;
5930 if (look() == '.')
5931 First = Last;
5932 if (numLeft() != 0)
5933 return nullptr;
5934 return make<SpecialName>("invocation function for block in ", Encoding);
5937 Node *Ty = getDerived().parseType();
5938 if (numLeft() != 0)
5939 return nullptr;
5940 return Ty;
5943 template <typename Alloc>
5944 struct ManglingParser : AbstractManglingParser<ManglingParser<Alloc>, Alloc> {
5945 using AbstractManglingParser<ManglingParser<Alloc>,
5946 Alloc>::AbstractManglingParser;
5949 DEMANGLE_NAMESPACE_END
5951 #ifdef _LIBCXXABI_COMPILER_CLANG
5952 #pragma clang diagnostic pop
5953 #endif
5955 #endif // DEMANGLE_ITANIUMDEMANGLE_H