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.
13//
14//===----------------------------------------------------------------------===//
15
16#ifndef DEMANGLE_ITANIUMDEMANGLE_H
17#define DEMANGLE_ITANIUMDEMANGLE_H
18
19#include "DemangleConfig.h"
20#include "StringViewExtras.h"
21#include "Utility.h"
22#include <algorithm>
23#include <cctype>
24#include <cstdint>
25#include <cstdio>
26#include <cstdlib>
27#include <cstring>
28#include <limits>
29#include <new>
30#include <string_view>
31#include <type_traits>
32#include <utility>
33
34#if defined(__clang__)
35#pragma clang diagnostic push
36#pragma clang diagnostic ignored "-Wunused-template"
37#endif
38
39DEMANGLE_NAMESPACE_BEGIN
40
41template <class T, size_t N> class PODSmallVector {
42 static_assert(std::is_trivially_copyable<T>::value,
43 "T is required to be a trivially copyable type");
44 static_assert(std::is_trivially_default_constructible<T>::value,
45 "T is required to be trivially default constructible");
46 static_assert(N > 0, "PODSmallVector requires a non-zero inline capacity");
47 T *First = nullptr;
48 T *Last = nullptr;
49 T *Cap = nullptr;
50 T Inline[N] = {};
51
52 bool isInline() const { return First == Inline; }
53
54 void clearInline() {
55 First = Inline;
56 Last = Inline;
57 Cap = Inline + N;
58 }
59
60 void reserve(size_t NewCap) {
61 size_t S = size();
62 if (isInline()) {
63 auto *Tmp = static_cast<T *>(std::malloc(size: NewCap * sizeof(T)));
64 if (Tmp == nullptr)
65 std::abort();
66 std::copy(First, Last, Tmp);
67 First = Tmp;
68 } else {
69 First = static_cast<T *>(std::realloc(ptr: First, size: NewCap * sizeof(T)));
70 if (First == nullptr)
71 std::abort();
72 }
73 Last = First + S;
74 Cap = First + NewCap;
75 }
76
77public:
78 PODSmallVector() : First(Inline), Last(First), Cap(Inline + N) {}
79
80 PODSmallVector(const PODSmallVector &) = delete;
81 PODSmallVector &operator=(const PODSmallVector &) = delete;
82
83 PODSmallVector(PODSmallVector &&Other) : PODSmallVector() {
84 if (Other.isInline()) {
85 std::copy(Other.begin(), Other.end(), First);
86 Last = First + Other.size();
87 Other.clear();
88 return;
89 }
90
91 First = Other.First;
92 Last = Other.Last;
93 Cap = Other.Cap;
94 Other.clearInline();
95 }
96
97 PODSmallVector &operator=(PODSmallVector &&Other) {
98 if (Other.isInline()) {
99 if (!isInline()) {
100 std::free(ptr: First);
101 clearInline();
102 }
103 std::copy(Other.begin(), Other.end(), First);
104 Last = First + Other.size();
105 Other.clear();
106 return *this;
107 }
108
109 if (isInline()) {
110 First = Other.First;
111 Last = Other.Last;
112 Cap = Other.Cap;
113 Other.clearInline();
114 return *this;
115 }
116
117 std::swap(First, Other.First);
118 std::swap(Last, Other.Last);
119 std::swap(Cap, Other.Cap);
120 Other.clear();
121 return *this;
122 }
123
124 // NOLINTNEXTLINE(readability-identifier-naming)
125 void push_back(const T &Elem) {
126 if (Last == Cap)
127 reserve(NewCap: size() * 2);
128 *Last++ = Elem;
129 }
130
131 // NOLINTNEXTLINE(readability-identifier-naming)
132 void pop_back() {
133 DEMANGLE_ASSERT(Last != First, "Popping empty vector!");
134 --Last;
135 }
136
137 void shrinkToSize(size_t Index) {
138 DEMANGLE_ASSERT(Index <= size(), "shrinkToSize() can't expand!");
139 Last = First + Index;
140 }
141
142 T *begin() { return First; }
143 T *end() { return Last; }
144
145 bool empty() const { return First == Last; }
146 size_t size() const { return static_cast<size_t>(Last - First); }
147 T &back() {
148 DEMANGLE_ASSERT(Last != First, "Calling back() on empty vector!");
149 return *(Last - 1);
150 }
151 T &operator[](size_t Index) {
152 DEMANGLE_ASSERT(Index < size(), "Invalid access!");
153 return *(begin() + Index);
154 }
155 void clear() { Last = First; }
156
157 ~PODSmallVector() {
158 if (!isInline())
159 std::free(ptr: First);
160 }
161};
162
163class NodeArray;
164
165// Base class of all AST nodes. The AST is built by the parser, then is
166// traversed by the printLeft/Right functions to produce a demangled string.
167class Node {
168public:
169 enum Kind : uint8_t {
170#define NODE(NodeKind) K##NodeKind,
171#include "ItaniumNodes.def"
172 };
173
174 /// Three-way bool to track a cached value. Unknown is possible if this node
175 /// has an unexpanded parameter pack below it that may affect this cache.
176 enum class Cache : uint8_t { Yes, No, Unknown, };
177
178 /// Operator precedence for expression nodes. Used to determine required
179 /// parens in expression emission.
180 enum class Prec : uint8_t {
181 Primary,
182 Postfix,
183 Unary,
184 Cast,
185 PtrMem,
186 Multiplicative,
187 Additive,
188 Shift,
189 Spaceship,
190 Relational,
191 Equality,
192 And,
193 Xor,
194 Ior,
195 AndIf,
196 OrIf,
197 Conditional,
198 Assign,
199 Comma,
200 Default,
201 };
202
203private:
204 Kind K;
205
206 Prec Precedence : 6;
207
208protected:
209 /// Tracks if this node has a component on its right side, in which case we
210 /// need to call printRight.
211 Cache RHSComponentCache : 2;
212
213 /// Track if this node is a (possibly qualified) array type. This can affect
214 /// how we format the output string.
215 Cache ArrayCache : 2;
216
217 /// Track if this node is a (possibly qualified) function type. This can
218 /// affect how we format the output string.
219 Cache FunctionCache : 2;
220
221public:
222 Node(Kind K_, Prec Precedence_ = Prec::Primary,
223 Cache RHSComponentCache_ = Cache::No, Cache ArrayCache_ = Cache::No,
224 Cache FunctionCache_ = Cache::No)
225 : K(K_), Precedence(Precedence_), RHSComponentCache(RHSComponentCache_),
226 ArrayCache(ArrayCache_), FunctionCache(FunctionCache_) {}
227 Node(Kind K_, Cache RHSComponentCache_, Cache ArrayCache_ = Cache::No,
228 Cache FunctionCache_ = Cache::No)
229 : Node(K_, Prec::Primary, RHSComponentCache_, ArrayCache_,
230 FunctionCache_) {}
231
232 /// Visit the most-derived object corresponding to this object.
233 template<typename Fn> void visit(Fn F) const;
234
235 // The following function is provided by all derived classes:
236 //
237 // Call F with arguments that, when passed to the constructor of this node,
238 // would construct an equivalent node.
239 //template<typename Fn> void match(Fn F) const;
240
241 bool hasRHSComponent(OutputBuffer &OB) const {
242 if (RHSComponentCache != Cache::Unknown)
243 return RHSComponentCache == Cache::Yes;
244 return hasRHSComponentSlow(OB);
245 }
246
247 bool hasArray(OutputBuffer &OB) const {
248 if (ArrayCache != Cache::Unknown)
249 return ArrayCache == Cache::Yes;
250 return hasArraySlow(OB);
251 }
252
253 bool hasFunction(OutputBuffer &OB) const {
254 if (FunctionCache != Cache::Unknown)
255 return FunctionCache == Cache::Yes;
256 return hasFunctionSlow(OB);
257 }
258
259 Kind getKind() const { return K; }
260
261 Prec getPrecedence() const { return Precedence; }
262 Cache getRHSComponentCache() const { return RHSComponentCache; }
263 Cache getArrayCache() const { return ArrayCache; }
264 Cache getFunctionCache() const { return FunctionCache; }
265
266 virtual bool hasRHSComponentSlow(OutputBuffer &) const { return false; }
267 virtual bool hasArraySlow(OutputBuffer &) const { return false; }
268 virtual bool hasFunctionSlow(OutputBuffer &) const { return false; }
269
270 // Dig through "glue" nodes like ParameterPack and ForwardTemplateReference to
271 // get at a node that actually represents some concrete syntax.
272 virtual const Node *getSyntaxNode(OutputBuffer &) const { return this; }
273
274 // Print this node as an expression operand, surrounding it in parentheses if
275 // its precedence is [Strictly] weaker than P.
276 void printAsOperand(OutputBuffer &OB, Prec P = Prec::Default,
277 bool StrictlyWorse = false) const {
278 bool Paren =
279 unsigned(getPrecedence()) >= unsigned(P) + unsigned(StrictlyWorse);
280 if (Paren)
281 OB.printOpen();
282 print(OB);
283 if (Paren)
284 OB.printClose();
285 }
286
287 void print(OutputBuffer &OB) const {
288 OB.printLeft(N: *this);
289 if (RHSComponentCache != Cache::No)
290 OB.printRight(N: *this);
291 }
292
293 // Print an initializer list of this type. Returns true if we printed a custom
294 // representation, false if nothing has been printed and the default
295 // representation should be used.
296 virtual bool printInitListAsType(OutputBuffer &, const NodeArray &) const {
297 return false;
298 }
299
300 virtual std::string_view getBaseName() const { return {}; }
301
302 // Silence compiler warnings, this dtor will never be called.
303 virtual ~Node() = default;
304
305#ifndef NDEBUG
306 DEMANGLE_DUMP_METHOD void dump() const;
307#endif
308
309private:
310 friend class OutputBuffer;
311
312 // Print the "left" side of this Node into OutputBuffer.
313 //
314 // Note, should only be called from OutputBuffer implementations.
315 // Call \ref OutputBuffer::printLeft instead.
316 virtual void printLeft(OutputBuffer &) const = 0;
317
318 // Print the "right". This distinction is necessary to represent C++ types
319 // that appear on the RHS of their subtype, such as arrays or functions.
320 // Since most types don't have such a component, provide a default
321 // implementation.
322 //
323 // Note, should only be called from OutputBuffer implementations.
324 // Call \ref OutputBuffer::printRight instead.
325 virtual void printRight(OutputBuffer &) const {}
326};
327
328class NodeArray {
329 Node **Elements;
330 size_t NumElements;
331
332public:
333 NodeArray() : Elements(nullptr), NumElements(0) {}
334 NodeArray(Node **Elements_, size_t NumElements_)
335 : Elements(Elements_), NumElements(NumElements_) {}
336
337 bool empty() const { return NumElements == 0; }
338 size_t size() const { return NumElements; }
339
340 Node **begin() const { return Elements; }
341 Node **end() const { return Elements + NumElements; }
342
343 Node *operator[](size_t Idx) const { return Elements[Idx]; }
344
345 void printWithComma(OutputBuffer &OB) const {
346 bool FirstElement = true;
347 for (size_t Idx = 0; Idx != NumElements; ++Idx) {
348 size_t BeforeComma = OB.getCurrentPosition();
349 if (!FirstElement)
350 OB += ", ";
351 size_t AfterComma = OB.getCurrentPosition();
352 Elements[Idx]->printAsOperand(OB, P: Node::Prec::Comma);
353
354 // Elements[Idx] is an empty parameter pack expansion, we should erase the
355 // comma we just printed.
356 if (AfterComma == OB.getCurrentPosition()) {
357 OB.setCurrentPosition(BeforeComma);
358 continue;
359 }
360
361 FirstElement = false;
362 }
363 }
364
365 // Print an array of integer literals as a string literal. Returns whether we
366 // could do so.
367 bool printAsString(OutputBuffer &OB) const;
368};
369
370struct NodeArrayNode : Node {
371 NodeArray Array;
372 NodeArrayNode(NodeArray Array_) : Node(KNodeArrayNode), Array(Array_) {}
373
374 template<typename Fn> void match(Fn F) const { F(Array); }
375
376 void printLeft(OutputBuffer &OB) const override { Array.printWithComma(OB); }
377};
378
379class DotSuffix final : public Node {
380 const Node *Prefix;
381 const std::string_view Suffix;
382
383public:
384 DotSuffix(const Node *Prefix_, std::string_view Suffix_)
385 : Node(KDotSuffix), Prefix(Prefix_), Suffix(Suffix_) {}
386
387 template<typename Fn> void match(Fn F) const { F(Prefix, Suffix); }
388
389 void printLeft(OutputBuffer &OB) const override {
390 Prefix->print(OB);
391 OB += " (";
392 OB += Suffix;
393 OB += ")";
394 }
395};
396
397class VendorExtQualType final : public Node {
398 const Node *Ty;
399 std::string_view Ext;
400 const Node *TA;
401
402public:
403 VendorExtQualType(const Node *Ty_, std::string_view Ext_, const Node *TA_)
404 : Node(KVendorExtQualType), Ty(Ty_), Ext(Ext_), TA(TA_) {}
405
406 const Node *getTy() const { return Ty; }
407 std::string_view getExt() const { return Ext; }
408 const Node *getTA() const { return TA; }
409
410 template <typename Fn> void match(Fn F) const { F(Ty, Ext, TA); }
411
412 void printLeft(OutputBuffer &OB) const override {
413 Ty->print(OB);
414 OB += " ";
415 OB += Ext;
416 if (TA != nullptr)
417 TA->print(OB);
418 }
419};
420
421enum FunctionRefQual : unsigned char {
422 FrefQualNone,
423 FrefQualLValue,
424 FrefQualRValue,
425};
426
427enum Qualifiers {
428 QualNone = 0,
429 QualConst = 0x1,
430 QualVolatile = 0x2,
431 QualRestrict = 0x4,
432};
433
434inline Qualifiers operator|=(Qualifiers &Q1, Qualifiers Q2) {
435 return Q1 = static_cast<Qualifiers>(Q1 | Q2);
436}
437
438class QualType final : public Node {
439protected:
440 const Qualifiers Quals;
441 const Node *Child;
442
443 void printQuals(OutputBuffer &OB) const {
444 if (Quals & QualConst)
445 OB += " const";
446 if (Quals & QualVolatile)
447 OB += " volatile";
448 if (Quals & QualRestrict)
449 OB += " restrict";
450 }
451
452public:
453 QualType(const Node *Child_, Qualifiers Quals_)
454 : Node(KQualType, Child_->getRHSComponentCache(), Child_->getArrayCache(),
455 Child_->getFunctionCache()),
456 Quals(Quals_), Child(Child_) {}
457
458 Qualifiers getQuals() const { return Quals; }
459 const Node *getChild() const { return Child; }
460
461 template<typename Fn> void match(Fn F) const { F(Child, Quals); }
462
463 bool hasRHSComponentSlow(OutputBuffer &OB) const override {
464 return Child->hasRHSComponent(OB);
465 }
466 bool hasArraySlow(OutputBuffer &OB) const override {
467 return Child->hasArray(OB);
468 }
469 bool hasFunctionSlow(OutputBuffer &OB) const override {
470 return Child->hasFunction(OB);
471 }
472
473 void printLeft(OutputBuffer &OB) const override {
474 OB.printLeft(N: *Child);
475 printQuals(OB);
476 }
477
478 void printRight(OutputBuffer &OB) const override { OB.printRight(N: *Child); }
479};
480
481class ConversionOperatorType final : public Node {
482 const Node *Ty;
483
484public:
485 ConversionOperatorType(const Node *Ty_)
486 : Node(KConversionOperatorType), Ty(Ty_) {}
487
488 template<typename Fn> void match(Fn F) const { F(Ty); }
489
490 void printLeft(OutputBuffer &OB) const override {
491 OB += "operator ";
492 Ty->print(OB);
493 }
494};
495
496class PostfixQualifiedType final : public Node {
497 const Node *Ty;
498 const std::string_view Postfix;
499
500public:
501 PostfixQualifiedType(const Node *Ty_, std::string_view Postfix_)
502 : Node(KPostfixQualifiedType), Ty(Ty_), Postfix(Postfix_) {}
503
504 template<typename Fn> void match(Fn F) const { F(Ty, Postfix); }
505
506 void printLeft(OutputBuffer &OB) const override {
507 OB.printLeft(N: *Ty);
508 OB += Postfix;
509 }
510};
511
512class NameType final : public Node {
513 const std::string_view Name;
514
515public:
516 NameType(std::string_view Name_) : Node(KNameType), Name(Name_) {}
517
518 template<typename Fn> void match(Fn F) const { F(Name); }
519
520 std::string_view getName() const { return Name; }
521 std::string_view getBaseName() const override { return Name; }
522
523 void printLeft(OutputBuffer &OB) const override { OB += Name; }
524};
525
526class BitIntType final : public Node {
527 const Node *Size;
528 bool Signed;
529
530public:
531 BitIntType(const Node *Size_, bool Signed_)
532 : Node(KBitIntType), Size(Size_), Signed(Signed_) {}
533
534 template <typename Fn> void match(Fn F) const { F(Size, Signed); }
535
536 void printLeft(OutputBuffer &OB) const override {
537 if (!Signed)
538 OB += "unsigned ";
539 OB += "_BitInt";
540 OB.printOpen();
541 Size->printAsOperand(OB);
542 OB.printClose();
543 }
544};
545
546class ElaboratedTypeSpefType : public Node {
547 std::string_view Kind;
548 Node *Child;
549public:
550 ElaboratedTypeSpefType(std::string_view Kind_, Node *Child_)
551 : Node(KElaboratedTypeSpefType), Kind(Kind_), Child(Child_) {}
552
553 template<typename Fn> void match(Fn F) const { F(Kind, Child); }
554
555 void printLeft(OutputBuffer &OB) const override {
556 OB += Kind;
557 OB += ' ';
558 Child->print(OB);
559 }
560};
561
562class TransformedType : public Node {
563 std::string_view Transform;
564 Node *BaseType;
565public:
566 TransformedType(std::string_view Transform_, Node *BaseType_)
567 : Node(KTransformedType), Transform(Transform_), BaseType(BaseType_) {}
568
569 template<typename Fn> void match(Fn F) const { F(Transform, BaseType); }
570
571 void printLeft(OutputBuffer &OB) const override {
572 OB += Transform;
573 OB += '(';
574 BaseType->print(OB);
575 OB += ')';
576 }
577};
578
579struct AbiTagAttr : Node {
580 Node *Base;
581 std::string_view Tag;
582
583 AbiTagAttr(Node *Base_, std::string_view Tag_)
584 : Node(KAbiTagAttr, Base_->getRHSComponentCache(), Base_->getArrayCache(),
585 Base_->getFunctionCache()),
586 Base(Base_), Tag(Tag_) {}
587
588 template<typename Fn> void match(Fn F) const { F(Base, Tag); }
589
590 std::string_view getBaseName() const override { return Base->getBaseName(); }
591
592 void printLeft(OutputBuffer &OB) const override {
593 OB.printLeft(N: *Base);
594 OB += "[abi:";
595 OB += Tag;
596 OB += "]";
597 }
598};
599
600class EnableIfAttr : public Node {
601 NodeArray Conditions;
602public:
603 EnableIfAttr(NodeArray Conditions_)
604 : Node(KEnableIfAttr), Conditions(Conditions_) {}
605
606 template<typename Fn> void match(Fn F) const { F(Conditions); }
607
608 void printLeft(OutputBuffer &OB) const override {
609 OB += " [enable_if:";
610 Conditions.printWithComma(OB);
611 OB += ']';
612 }
613};
614
615class ObjCProtoName : public Node {
616 const Node *Ty;
617 std::string_view Protocol;
618
619public:
620 ObjCProtoName(const Node *Ty_, std::string_view Protocol_)
621 : Node(KObjCProtoName), Ty(Ty_), Protocol(Protocol_) {}
622
623 template<typename Fn> void match(Fn F) const { F(Ty, Protocol); }
624
625 bool isObjCObject() const {
626 return Ty->getKind() == KNameType &&
627 static_cast<const NameType *>(Ty)->getName() == "objc_object";
628 }
629
630 std::string_view getProtocol() const { return Protocol; }
631
632 void printLeft(OutputBuffer &OB) const override {
633 Ty->print(OB);
634 OB += "<";
635 OB += Protocol;
636 OB += ">";
637 }
638};
639
640class PointerType final : public Node {
641 const Node *Pointee;
642
643public:
644 PointerType(const Node *Pointee_)
645 : Node(KPointerType, Pointee_->getRHSComponentCache()),
646 Pointee(Pointee_) {}
647
648 const Node *getPointee() const { return Pointee; }
649
650 template<typename Fn> void match(Fn F) const { F(Pointee); }
651
652 bool hasRHSComponentSlow(OutputBuffer &OB) const override {
653 return Pointee->hasRHSComponent(OB);
654 }
655
656 void printLeft(OutputBuffer &OB) const override {
657 // We rewrite objc_object<SomeProtocol>* into id<SomeProtocol>.
658 if (Pointee->getKind() != KObjCProtoName ||
659 !static_cast<const ObjCProtoName *>(Pointee)->isObjCObject()) {
660 OB.printLeft(N: *Pointee);
661 if (Pointee->hasArray(OB))
662 OB += " ";
663 if (Pointee->hasArray(OB) || Pointee->hasFunction(OB))
664 OB += "(";
665 OB += "*";
666 } else {
667 const auto *objcProto = static_cast<const ObjCProtoName *>(Pointee);
668 OB += "id<";
669 OB += objcProto->getProtocol();
670 OB += ">";
671 }
672 }
673
674 void printRight(OutputBuffer &OB) const override {
675 if (Pointee->getKind() != KObjCProtoName ||
676 !static_cast<const ObjCProtoName *>(Pointee)->isObjCObject()) {
677 if (Pointee->hasArray(OB) || Pointee->hasFunction(OB))
678 OB += ")";
679 OB.printRight(N: *Pointee);
680 }
681 }
682};
683
684enum class ReferenceKind {
685 LValue,
686 RValue,
687};
688
689// Represents either a LValue or an RValue reference type.
690class ReferenceType : public Node {
691 const Node *Pointee;
692 ReferenceKind RK;
693
694 mutable bool Printing = false;
695
696 // Dig through any refs to refs, collapsing the ReferenceTypes as we go. The
697 // rule here is rvalue ref to rvalue ref collapses to a rvalue ref, and any
698 // other combination collapses to a lvalue ref.
699 //
700 // A combination of a TemplateForwardReference and a back-ref Substitution
701 // from an ill-formed string may have created a cycle; use cycle detection to
702 // avoid looping forever.
703 std::pair<ReferenceKind, const Node *> collapse(OutputBuffer &OB) const {
704 auto SoFar = std::make_pair(t1: RK, t2: Pointee);
705 // Track the chain of nodes for the Floyd's 'tortoise and hare'
706 // cycle-detection algorithm, since getSyntaxNode(S) is impure
707 PODSmallVector<const Node *, 8> Prev;
708 for (;;) {
709 const Node *SN = SoFar.second->getSyntaxNode(OB);
710 if (SN->getKind() != KReferenceType)
711 break;
712 auto *RT = static_cast<const ReferenceType *>(SN);
713 SoFar.second = RT->Pointee;
714 SoFar.first = std::min(a: SoFar.first, b: RT->RK);
715
716 // The middle of Prev is the 'slow' pointer moving at half speed
717 Prev.push_back(Elem: SoFar.second);
718 if (Prev.size() > 1 && SoFar.second == Prev[(Prev.size() - 1) / 2]) {
719 // Cycle detected
720 SoFar.second = nullptr;
721 break;
722 }
723 }
724 return SoFar;
725 }
726
727public:
728 ReferenceType(const Node *Pointee_, ReferenceKind RK_)
729 : Node(KReferenceType, Pointee_->getRHSComponentCache()),
730 Pointee(Pointee_), RK(RK_) {}
731
732 template<typename Fn> void match(Fn F) const { F(Pointee, RK); }
733
734 bool hasRHSComponentSlow(OutputBuffer &OB) const override {
735 return Pointee->hasRHSComponent(OB);
736 }
737
738 void printLeft(OutputBuffer &OB) const override {
739 if (Printing)
740 return;
741 ScopedOverride<bool> SavePrinting(Printing, true);
742 std::pair<ReferenceKind, const Node *> Collapsed = collapse(OB);
743 if (!Collapsed.second)
744 return;
745 OB.printLeft(N: *Collapsed.second);
746 if (Collapsed.second->hasArray(OB))
747 OB += " ";
748 if (Collapsed.second->hasArray(OB) || Collapsed.second->hasFunction(OB))
749 OB += "(";
750
751 OB += (Collapsed.first == ReferenceKind::LValue ? "&" : "&&");
752 }
753 void printRight(OutputBuffer &OB) const override {
754 if (Printing)
755 return;
756 ScopedOverride<bool> SavePrinting(Printing, true);
757 std::pair<ReferenceKind, const Node *> Collapsed = collapse(OB);
758 if (!Collapsed.second)
759 return;
760 if (Collapsed.second->hasArray(OB) || Collapsed.second->hasFunction(OB))
761 OB += ")";
762 OB.printRight(N: *Collapsed.second);
763 }
764};
765
766class PointerToMemberType final : public Node {
767 const Node *ClassType;
768 const Node *MemberType;
769
770public:
771 PointerToMemberType(const Node *ClassType_, const Node *MemberType_)
772 : Node(KPointerToMemberType, MemberType_->getRHSComponentCache()),
773 ClassType(ClassType_), MemberType(MemberType_) {}
774
775 template<typename Fn> void match(Fn F) const { F(ClassType, MemberType); }
776
777 bool hasRHSComponentSlow(OutputBuffer &OB) const override {
778 return MemberType->hasRHSComponent(OB);
779 }
780
781 void printLeft(OutputBuffer &OB) const override {
782 OB.printLeft(N: *MemberType);
783 if (MemberType->hasArray(OB) || MemberType->hasFunction(OB))
784 OB += "(";
785 else
786 OB += " ";
787 ClassType->print(OB);
788 OB += "::*";
789 }
790
791 void printRight(OutputBuffer &OB) const override {
792 if (MemberType->hasArray(OB) || MemberType->hasFunction(OB))
793 OB += ")";
794 OB.printRight(N: *MemberType);
795 }
796};
797
798class ArrayType final : public Node {
799 const Node *Base;
800 Node *Dimension;
801
802public:
803 ArrayType(const Node *Base_, Node *Dimension_)
804 : Node(KArrayType,
805 /*RHSComponentCache=*/Cache::Yes,
806 /*ArrayCache=*/Cache::Yes),
807 Base(Base_), Dimension(Dimension_) {}
808
809 template<typename Fn> void match(Fn F) const { F(Base, Dimension); }
810
811 bool hasRHSComponentSlow(OutputBuffer &) const override { return true; }
812 bool hasArraySlow(OutputBuffer &) const override { return true; }
813
814 void printLeft(OutputBuffer &OB) const override { OB.printLeft(N: *Base); }
815
816 void printRight(OutputBuffer &OB) const override {
817 if (OB.back() != ']')
818 OB += " ";
819 OB += "[";
820 if (Dimension)
821 Dimension->print(OB);
822 OB += "]";
823 OB.printRight(N: *Base);
824 }
825
826 bool printInitListAsType(OutputBuffer &OB,
827 const NodeArray &Elements) const override {
828 if (Base->getKind() == KNameType &&
829 static_cast<const NameType *>(Base)->getName() == "char") {
830 return Elements.printAsString(OB);
831 }
832 return false;
833 }
834};
835
836class FunctionType final : public Node {
837 const Node *Ret;
838 NodeArray Params;
839 Qualifiers CVQuals;
840 FunctionRefQual RefQual;
841 const Node *ExceptionSpec;
842
843public:
844 FunctionType(const Node *Ret_, NodeArray Params_, Qualifiers CVQuals_,
845 FunctionRefQual RefQual_, const Node *ExceptionSpec_)
846 : Node(KFunctionType,
847 /*RHSComponentCache=*/Cache::Yes, /*ArrayCache=*/Cache::No,
848 /*FunctionCache=*/Cache::Yes),
849 Ret(Ret_), Params(Params_), CVQuals(CVQuals_), RefQual(RefQual_),
850 ExceptionSpec(ExceptionSpec_) {}
851
852 template<typename Fn> void match(Fn F) const {
853 F(Ret, Params, CVQuals, RefQual, ExceptionSpec);
854 }
855
856 bool hasRHSComponentSlow(OutputBuffer &) const override { return true; }
857 bool hasFunctionSlow(OutputBuffer &) const override { return true; }
858
859 // Handle C++'s ... quirky decl grammar by using the left & right
860 // distinction. Consider:
861 // int (*f(float))(char) {}
862 // f is a function that takes a float and returns a pointer to a function
863 // that takes a char and returns an int. If we're trying to print f, start
864 // by printing out the return types's left, then print our parameters, then
865 // finally print right of the return type.
866 void printLeft(OutputBuffer &OB) const override {
867 OB.printLeft(N: *Ret);
868 OB += " ";
869 }
870
871 void printRight(OutputBuffer &OB) const override {
872 OB.printOpen();
873 Params.printWithComma(OB);
874 OB.printClose();
875 OB.printRight(N: *Ret);
876
877 if (CVQuals & QualConst)
878 OB += " const";
879 if (CVQuals & QualVolatile)
880 OB += " volatile";
881 if (CVQuals & QualRestrict)
882 OB += " restrict";
883
884 if (RefQual == FrefQualLValue)
885 OB += " &";
886 else if (RefQual == FrefQualRValue)
887 OB += " &&";
888
889 if (ExceptionSpec != nullptr) {
890 OB += ' ';
891 ExceptionSpec->print(OB);
892 }
893 }
894};
895
896class NoexceptSpec : public Node {
897 const Node *E;
898public:
899 NoexceptSpec(const Node *E_) : Node(KNoexceptSpec), E(E_) {}
900
901 template<typename Fn> void match(Fn F) const { F(E); }
902
903 void printLeft(OutputBuffer &OB) const override {
904 OB += "noexcept";
905 OB.printOpen();
906 E->printAsOperand(OB);
907 OB.printClose();
908 }
909};
910
911class DynamicExceptionSpec : public Node {
912 NodeArray Types;
913public:
914 DynamicExceptionSpec(NodeArray Types_)
915 : Node(KDynamicExceptionSpec), Types(Types_) {}
916
917 template<typename Fn> void match(Fn F) const { F(Types); }
918
919 void printLeft(OutputBuffer &OB) const override {
920 OB += "throw";
921 OB.printOpen();
922 Types.printWithComma(OB);
923 OB.printClose();
924 }
925};
926
927/// Represents the explicitly named object parameter.
928/// E.g.,
929/// \code{.cpp}
930/// struct Foo {
931/// void bar(this Foo && self);
932/// };
933/// \endcode
934class ExplicitObjectParameter final : public Node {
935 Node *Base;
936
937public:
938 ExplicitObjectParameter(Node *Base_)
939 : Node(KExplicitObjectParameter), Base(Base_) {
940 DEMANGLE_ASSERT(
941 Base != nullptr,
942 "Creating an ExplicitObjectParameter without a valid Base Node.");
943 }
944
945 template <typename Fn> void match(Fn F) const { F(Base); }
946
947 void printLeft(OutputBuffer &OB) const override {
948 OB += "this ";
949 Base->print(OB);
950 }
951};
952
953class FunctionEncoding final : public Node {
954 const Node *Ret;
955 const Node *Name;
956 NodeArray Params;
957 const Node *Attrs;
958 const Node *Requires;
959 Qualifiers CVQuals;
960 FunctionRefQual RefQual;
961
962public:
963 FunctionEncoding(const Node *Ret_, const Node *Name_, NodeArray Params_,
964 const Node *Attrs_, const Node *Requires_,
965 Qualifiers CVQuals_, FunctionRefQual RefQual_)
966 : Node(KFunctionEncoding,
967 /*RHSComponentCache=*/Cache::Yes, /*ArrayCache=*/Cache::No,
968 /*FunctionCache=*/Cache::Yes),
969 Ret(Ret_), Name(Name_), Params(Params_), Attrs(Attrs_),
970 Requires(Requires_), CVQuals(CVQuals_), RefQual(RefQual_) {}
971
972 template<typename Fn> void match(Fn F) const {
973 F(Ret, Name, Params, Attrs, Requires, CVQuals, RefQual);
974 }
975
976 Qualifiers getCVQuals() const { return CVQuals; }
977 FunctionRefQual getRefQual() const { return RefQual; }
978 NodeArray getParams() const { return Params; }
979 const Node *getReturnType() const { return Ret; }
980 const Node *getAttrs() const { return Attrs; }
981 const Node *getRequires() const { return Requires; }
982
983 bool hasRHSComponentSlow(OutputBuffer &) const override { return true; }
984 bool hasFunctionSlow(OutputBuffer &) const override { return true; }
985
986 const Node *getName() const { return Name; }
987
988 void printLeft(OutputBuffer &OB) const override {
989 if (Ret) {
990 OB.printLeft(N: *Ret);
991 if (!Ret->hasRHSComponent(OB))
992 OB += " ";
993 }
994
995 Name->print(OB);
996 }
997
998 void printRight(OutputBuffer &OB) const override {
999 OB.printOpen();
1000 Params.printWithComma(OB);
1001 OB.printClose();
1002
1003 if (Ret)
1004 OB.printRight(N: *Ret);
1005
1006 if (CVQuals & QualConst)
1007 OB += " const";
1008 if (CVQuals & QualVolatile)
1009 OB += " volatile";
1010 if (CVQuals & QualRestrict)
1011 OB += " restrict";
1012
1013 if (RefQual == FrefQualLValue)
1014 OB += " &";
1015 else if (RefQual == FrefQualRValue)
1016 OB += " &&";
1017
1018 if (Attrs != nullptr)
1019 Attrs->print(OB);
1020
1021 if (Requires != nullptr) {
1022 OB += " requires ";
1023 Requires->print(OB);
1024 }
1025 }
1026};
1027
1028class LiteralOperator : public Node {
1029 const Node *OpName;
1030
1031public:
1032 LiteralOperator(const Node *OpName_)
1033 : Node(KLiteralOperator), OpName(OpName_) {}
1034
1035 template<typename Fn> void match(Fn F) const { F(OpName); }
1036
1037 void printLeft(OutputBuffer &OB) const override {
1038 OB += "operator\"\" ";
1039 OpName->print(OB);
1040 }
1041};
1042
1043class SpecialName final : public Node {
1044 const std::string_view Special;
1045 const Node *Child;
1046
1047public:
1048 SpecialName(std::string_view Special_, const Node *Child_)
1049 : Node(KSpecialName), Special(Special_), Child(Child_) {}
1050
1051 template<typename Fn> void match(Fn F) const { F(Special, Child); }
1052
1053 void printLeft(OutputBuffer &OB) const override {
1054 OB += Special;
1055 Child->print(OB);
1056 }
1057};
1058
1059class CtorVtableSpecialName final : public Node {
1060 const Node *FirstType;
1061 const Node *SecondType;
1062
1063public:
1064 CtorVtableSpecialName(const Node *FirstType_, const Node *SecondType_)
1065 : Node(KCtorVtableSpecialName),
1066 FirstType(FirstType_), SecondType(SecondType_) {}
1067
1068 template<typename Fn> void match(Fn F) const { F(FirstType, SecondType); }
1069
1070 void printLeft(OutputBuffer &OB) const override {
1071 OB += "construction vtable for ";
1072 FirstType->print(OB);
1073 OB += "-in-";
1074 SecondType->print(OB);
1075 }
1076};
1077
1078struct NestedName : Node {
1079 Node *Qual;
1080 Node *Name;
1081
1082 NestedName(Node *Qual_, Node *Name_)
1083 : Node(KNestedName), Qual(Qual_), Name(Name_) {}
1084
1085 template<typename Fn> void match(Fn F) const { F(Qual, Name); }
1086
1087 std::string_view getBaseName() const override { return Name->getBaseName(); }
1088
1089 void printLeft(OutputBuffer &OB) const override {
1090 Qual->print(OB);
1091 OB += "::";
1092 Name->print(OB);
1093 }
1094};
1095
1096struct MemberLikeFriendName : Node {
1097 Node *Qual;
1098 Node *Name;
1099
1100 MemberLikeFriendName(Node *Qual_, Node *Name_)
1101 : Node(KMemberLikeFriendName), Qual(Qual_), Name(Name_) {}
1102
1103 template<typename Fn> void match(Fn F) const { F(Qual, Name); }
1104
1105 std::string_view getBaseName() const override { return Name->getBaseName(); }
1106
1107 void printLeft(OutputBuffer &OB) const override {
1108 Qual->print(OB);
1109 OB += "::friend ";
1110 Name->print(OB);
1111 }
1112};
1113
1114struct ModuleName : Node {
1115 ModuleName *Parent;
1116 Node *Name;
1117 bool IsPartition;
1118
1119 ModuleName(ModuleName *Parent_, Node *Name_, bool IsPartition_ = false)
1120 : Node(KModuleName), Parent(Parent_), Name(Name_),
1121 IsPartition(IsPartition_) {}
1122
1123 template <typename Fn> void match(Fn F) const {
1124 F(Parent, Name, IsPartition);
1125 }
1126
1127 void printLeft(OutputBuffer &OB) const override {
1128 if (Parent)
1129 Parent->print(OB);
1130 if (Parent || IsPartition)
1131 OB += IsPartition ? ':' : '.';
1132 Name->print(OB);
1133 }
1134};
1135
1136struct ModuleEntity : Node {
1137 ModuleName *Module;
1138 Node *Name;
1139
1140 ModuleEntity(ModuleName *Module_, Node *Name_)
1141 : Node(KModuleEntity), Module(Module_), Name(Name_) {}
1142
1143 template <typename Fn> void match(Fn F) const { F(Module, Name); }
1144
1145 std::string_view getBaseName() const override { return Name->getBaseName(); }
1146
1147 void printLeft(OutputBuffer &OB) const override {
1148 Name->print(OB);
1149 OB += '@';
1150 Module->print(OB);
1151 }
1152};
1153
1154struct LocalName : Node {
1155 Node *Encoding;
1156 Node *Entity;
1157
1158 LocalName(Node *Encoding_, Node *Entity_)
1159 : Node(KLocalName), Encoding(Encoding_), Entity(Entity_) {}
1160
1161 template<typename Fn> void match(Fn F) const { F(Encoding, Entity); }
1162
1163 void printLeft(OutputBuffer &OB) const override {
1164 Encoding->print(OB);
1165 OB += "::";
1166 Entity->print(OB);
1167 }
1168};
1169
1170class QualifiedName final : public Node {
1171 // qualifier::name
1172 const Node *Qualifier;
1173 const Node *Name;
1174
1175public:
1176 QualifiedName(const Node *Qualifier_, const Node *Name_)
1177 : Node(KQualifiedName), Qualifier(Qualifier_), Name(Name_) {}
1178
1179 template<typename Fn> void match(Fn F) const { F(Qualifier, Name); }
1180
1181 std::string_view getBaseName() const override { return Name->getBaseName(); }
1182
1183 void printLeft(OutputBuffer &OB) const override {
1184 Qualifier->print(OB);
1185 OB += "::";
1186 Name->print(OB);
1187 }
1188};
1189
1190class VectorType final : public Node {
1191 const Node *BaseType;
1192 const Node *Dimension;
1193
1194public:
1195 VectorType(const Node *BaseType_, const Node *Dimension_)
1196 : Node(KVectorType), BaseType(BaseType_), Dimension(Dimension_) {}
1197
1198 const Node *getBaseType() const { return BaseType; }
1199 const Node *getDimension() const { return Dimension; }
1200
1201 template<typename Fn> void match(Fn F) const { F(BaseType, Dimension); }
1202
1203 void printLeft(OutputBuffer &OB) const override {
1204 BaseType->print(OB);
1205 OB += " vector[";
1206 if (Dimension)
1207 Dimension->print(OB);
1208 OB += "]";
1209 }
1210};
1211
1212class PixelVectorType final : public Node {
1213 const Node *Dimension;
1214
1215public:
1216 PixelVectorType(const Node *Dimension_)
1217 : Node(KPixelVectorType), Dimension(Dimension_) {}
1218
1219 template<typename Fn> void match(Fn F) const { F(Dimension); }
1220
1221 void printLeft(OutputBuffer &OB) const override {
1222 // FIXME: This should demangle as "vector pixel".
1223 OB += "pixel vector[";
1224 Dimension->print(OB);
1225 OB += "]";
1226 }
1227};
1228
1229class BinaryFPType final : public Node {
1230 const Node *Dimension;
1231
1232public:
1233 BinaryFPType(const Node *Dimension_)
1234 : Node(KBinaryFPType), Dimension(Dimension_) {}
1235
1236 template<typename Fn> void match(Fn F) const { F(Dimension); }
1237
1238 void printLeft(OutputBuffer &OB) const override {
1239 OB += "_Float";
1240 Dimension->print(OB);
1241 }
1242};
1243
1244enum class TemplateParamKind { Type, NonType, Template };
1245
1246/// An invented name for a template parameter for which we don't have a
1247/// corresponding template argument.
1248///
1249/// This node is created when parsing the <lambda-sig> for a lambda with
1250/// explicit template arguments, which might be referenced in the parameter
1251/// types appearing later in the <lambda-sig>.
1252class SyntheticTemplateParamName final : public Node {
1253 TemplateParamKind Kind;
1254 unsigned Index;
1255
1256public:
1257 SyntheticTemplateParamName(TemplateParamKind Kind_, unsigned Index_)
1258 : Node(KSyntheticTemplateParamName), Kind(Kind_), Index(Index_) {}
1259
1260 template<typename Fn> void match(Fn F) const { F(Kind, Index); }
1261
1262 void printLeft(OutputBuffer &OB) const override {
1263 switch (Kind) {
1264 case TemplateParamKind::Type:
1265 OB += "$T";
1266 break;
1267 case TemplateParamKind::NonType:
1268 OB += "$N";
1269 break;
1270 case TemplateParamKind::Template:
1271 OB += "$TT";
1272 break;
1273 }
1274 if (Index > 0)
1275 OB << Index - 1;
1276 }
1277};
1278
1279class TemplateParamQualifiedArg final : public Node {
1280 Node *Param;
1281 Node *Arg;
1282
1283public:
1284 TemplateParamQualifiedArg(Node *Param_, Node *Arg_)
1285 : Node(KTemplateParamQualifiedArg), Param(Param_), Arg(Arg_) {}
1286
1287 template <typename Fn> void match(Fn F) const { F(Param, Arg); }
1288
1289 Node *getArg() { return Arg; }
1290
1291 void printLeft(OutputBuffer &OB) const override {
1292 // Don't print Param to keep the output consistent.
1293 Arg->print(OB);
1294 }
1295};
1296
1297/// A template type parameter declaration, 'typename T'.
1298class TypeTemplateParamDecl final : public Node {
1299 Node *Name;
1300
1301public:
1302 TypeTemplateParamDecl(Node *Name_)
1303 : Node(KTypeTemplateParamDecl, Cache::Yes), Name(Name_) {}
1304
1305 template<typename Fn> void match(Fn F) const { F(Name); }
1306
1307 void printLeft(OutputBuffer &OB) const override { OB += "typename "; }
1308
1309 void printRight(OutputBuffer &OB) const override { Name->print(OB); }
1310};
1311
1312/// A constrained template type parameter declaration, 'C<U> T'.
1313class ConstrainedTypeTemplateParamDecl final : public Node {
1314 Node *Constraint;
1315 Node *Name;
1316
1317public:
1318 ConstrainedTypeTemplateParamDecl(Node *Constraint_, Node *Name_)
1319 : Node(KConstrainedTypeTemplateParamDecl, Cache::Yes),
1320 Constraint(Constraint_), Name(Name_) {}
1321
1322 template<typename Fn> void match(Fn F) const { F(Constraint, Name); }
1323
1324 void printLeft(OutputBuffer &OB) const override {
1325 Constraint->print(OB);
1326 OB += " ";
1327 }
1328
1329 void printRight(OutputBuffer &OB) const override { Name->print(OB); }
1330};
1331
1332/// A non-type template parameter declaration, 'int N'.
1333class NonTypeTemplateParamDecl final : public Node {
1334 Node *Name;
1335 Node *Type;
1336
1337public:
1338 NonTypeTemplateParamDecl(Node *Name_, Node *Type_)
1339 : Node(KNonTypeTemplateParamDecl, Cache::Yes), Name(Name_), Type(Type_) {}
1340
1341 template<typename Fn> void match(Fn F) const { F(Name, Type); }
1342
1343 void printLeft(OutputBuffer &OB) const override {
1344 OB.printLeft(N: *Type);
1345 if (!Type->hasRHSComponent(OB))
1346 OB += " ";
1347 }
1348
1349 void printRight(OutputBuffer &OB) const override {
1350 Name->print(OB);
1351 OB.printRight(N: *Type);
1352 }
1353};
1354
1355/// A template template parameter declaration,
1356/// 'template<typename T> typename N'.
1357class TemplateTemplateParamDecl final : public Node {
1358 Node *Name;
1359 NodeArray Params;
1360 Node *Requires;
1361
1362public:
1363 TemplateTemplateParamDecl(Node *Name_, NodeArray Params_, Node *Requires_)
1364 : Node(KTemplateTemplateParamDecl, Cache::Yes), Name(Name_),
1365 Params(Params_), Requires(Requires_) {}
1366
1367 template <typename Fn> void match(Fn F) const { F(Name, Params, Requires); }
1368
1369 void printLeft(OutputBuffer &OB) const override {
1370 ScopedOverride<bool> LT(OB.TemplateTracker.InsideTemplate, true);
1371 OB += "template<";
1372 Params.printWithComma(OB);
1373 OB += "> typename ";
1374 }
1375
1376 void printRight(OutputBuffer &OB) const override {
1377 Name->print(OB);
1378 if (Requires != nullptr) {
1379 OB += " requires ";
1380 Requires->print(OB);
1381 }
1382 }
1383};
1384
1385/// A template parameter pack declaration, 'typename ...T'.
1386class TemplateParamPackDecl final : public Node {
1387 Node *Param;
1388
1389public:
1390 TemplateParamPackDecl(Node *Param_)
1391 : Node(KTemplateParamPackDecl, Cache::Yes), Param(Param_) {}
1392
1393 template<typename Fn> void match(Fn F) const { F(Param); }
1394
1395 void printLeft(OutputBuffer &OB) const override {
1396 OB.printLeft(N: *Param);
1397 OB += "...";
1398 }
1399
1400 void printRight(OutputBuffer &OB) const override { OB.printRight(N: *Param); }
1401};
1402
1403/// An unexpanded parameter pack (either in the expression or type context). If
1404/// this AST is correct, this node will have a ParameterPackExpansion node above
1405/// it.
1406///
1407/// This node is created when some <template-args> are found that apply to an
1408/// <encoding>, and is stored in the TemplateParams table. In order for this to
1409/// appear in the final AST, it has to referenced via a <template-param> (ie,
1410/// T_).
1411class ParameterPack final : public Node {
1412 NodeArray Data;
1413
1414 // Setup OutputBuffer for a pack expansion, unless we're already expanding
1415 // one.
1416 void initializePackExpansion(OutputBuffer &OB) const {
1417 if (OB.CurrentPackMax == std::numeric_limits<unsigned>::max()) {
1418 OB.CurrentPackMax = static_cast<unsigned>(Data.size());
1419 OB.CurrentPackIndex = 0;
1420 }
1421 }
1422
1423public:
1424 ParameterPack(NodeArray Data_) : Node(KParameterPack), Data(Data_) {
1425 ArrayCache = FunctionCache = RHSComponentCache = Cache::Unknown;
1426 if (std::all_of(first: Data.begin(), last: Data.end(),
1427 pred: [](Node *P) { return P->getArrayCache() == Cache::No; }))
1428 ArrayCache = Cache::No;
1429 if (std::all_of(first: Data.begin(), last: Data.end(),
1430 pred: [](Node *P) { return P->getFunctionCache() == Cache::No; }))
1431 FunctionCache = Cache::No;
1432 if (std::all_of(first: Data.begin(), last: Data.end(), pred: [](Node *P) {
1433 return P->getRHSComponentCache() == Cache::No;
1434 }))
1435 RHSComponentCache = Cache::No;
1436 }
1437
1438 template<typename Fn> void match(Fn F) const { F(Data); }
1439
1440 bool hasRHSComponentSlow(OutputBuffer &OB) const override {
1441 initializePackExpansion(OB);
1442 size_t Idx = OB.CurrentPackIndex;
1443 return Idx < Data.size() && Data[Idx]->hasRHSComponent(OB);
1444 }
1445 bool hasArraySlow(OutputBuffer &OB) const override {
1446 initializePackExpansion(OB);
1447 size_t Idx = OB.CurrentPackIndex;
1448 return Idx < Data.size() && Data[Idx]->hasArray(OB);
1449 }
1450 bool hasFunctionSlow(OutputBuffer &OB) const override {
1451 initializePackExpansion(OB);
1452 size_t Idx = OB.CurrentPackIndex;
1453 return Idx < Data.size() && Data[Idx]->hasFunction(OB);
1454 }
1455 const Node *getSyntaxNode(OutputBuffer &OB) const override {
1456 initializePackExpansion(OB);
1457 size_t Idx = OB.CurrentPackIndex;
1458 return Idx < Data.size() ? Data[Idx]->getSyntaxNode(OB) : this;
1459 }
1460
1461 void printLeft(OutputBuffer &OB) const override {
1462 initializePackExpansion(OB);
1463 size_t Idx = OB.CurrentPackIndex;
1464 if (Idx < Data.size())
1465 OB.printLeft(N: *Data[Idx]);
1466 }
1467 void printRight(OutputBuffer &OB) const override {
1468 initializePackExpansion(OB);
1469 size_t Idx = OB.CurrentPackIndex;
1470 if (Idx < Data.size())
1471 OB.printRight(N: *Data[Idx]);
1472 }
1473};
1474
1475/// A variadic template argument. This node represents an occurrence of
1476/// J<something>E in some <template-args>. It isn't itself unexpanded, unless
1477/// one of its Elements is. The parser inserts a ParameterPack into the
1478/// TemplateParams table if the <template-args> this pack belongs to apply to an
1479/// <encoding>.
1480class TemplateArgumentPack final : public Node {
1481 NodeArray Elements;
1482public:
1483 TemplateArgumentPack(NodeArray Elements_)
1484 : Node(KTemplateArgumentPack), Elements(Elements_) {}
1485
1486 template<typename Fn> void match(Fn F) const { F(Elements); }
1487
1488 NodeArray getElements() const { return Elements; }
1489
1490 void printLeft(OutputBuffer &OB) const override {
1491 Elements.printWithComma(OB);
1492 }
1493};
1494
1495/// A pack expansion. Below this node, there are some unexpanded ParameterPacks
1496/// which each have Child->ParameterPackSize elements.
1497class ParameterPackExpansion final : public Node {
1498 const Node *Child;
1499
1500public:
1501 ParameterPackExpansion(const Node *Child_)
1502 : Node(KParameterPackExpansion), Child(Child_) {}
1503
1504 template<typename Fn> void match(Fn F) const { F(Child); }
1505
1506 const Node *getChild() const { return Child; }
1507
1508 void printLeft(OutputBuffer &OB) const override {
1509 constexpr unsigned Max = std::numeric_limits<unsigned>::max();
1510 ScopedOverride<unsigned> SavePackIdx(OB.CurrentPackIndex, Max);
1511 ScopedOverride<unsigned> SavePackMax(OB.CurrentPackMax, Max);
1512 size_t StreamPos = OB.getCurrentPosition();
1513
1514 // Print the first element in the pack. If Child contains a ParameterPack,
1515 // it will set up S.CurrentPackMax and print the first element.
1516 Child->print(OB);
1517
1518 // No ParameterPack was found in Child. This can occur if we've found a pack
1519 // expansion on a <function-param>.
1520 if (OB.CurrentPackMax == Max) {
1521 OB += "...";
1522 return;
1523 }
1524
1525 // We found a ParameterPack, but it has no elements. Erase whatever we may
1526 // of printed.
1527 if (OB.CurrentPackMax == 0) {
1528 OB.setCurrentPosition(StreamPos);
1529 return;
1530 }
1531
1532 // Else, iterate through the rest of the elements in the pack.
1533 for (unsigned I = 1, E = OB.CurrentPackMax; I < E; ++I) {
1534 OB += ", ";
1535 OB.CurrentPackIndex = I;
1536 Child->print(OB);
1537 }
1538 }
1539};
1540
1541class PackIndexing final : public Node {
1542 const Node *Pattern;
1543 const Node *Index;
1544
1545public:
1546 PackIndexing(const Node *Pattern_, const Node *Index_)
1547 : Node(KPackIndexing), Pattern(Pattern_), Index(Index_) {}
1548
1549 template <typename Fn> void match(Fn F) const { F(Pattern, Index); }
1550
1551 void printLeft(OutputBuffer &OB) const override {
1552 OB.printOpen(Open: '(');
1553 ParameterPackExpansion PPE(Pattern);
1554 PPE.printLeft(OB);
1555 OB.printClose(Close: ')');
1556 OB.printOpen(Open: '[');
1557 OB.printLeft(N: *Index);
1558 OB.printClose(Close: ']');
1559 }
1560};
1561
1562class TemplateArgs final : public Node {
1563 NodeArray Params;
1564 Node *Requires;
1565
1566public:
1567 TemplateArgs(NodeArray Params_, Node *Requires_)
1568 : Node(KTemplateArgs), Params(Params_), Requires(Requires_) {}
1569
1570 template<typename Fn> void match(Fn F) const { F(Params, Requires); }
1571
1572 NodeArray getParams() { return Params; }
1573
1574 void printLeft(OutputBuffer &OB) const override {
1575 ScopedOverride<bool> LT(OB.TemplateTracker.InsideTemplate, true);
1576 OB += "<";
1577 Params.printWithComma(OB);
1578 OB += ">";
1579 // Don't print the requires clause to keep the output simple.
1580 }
1581};
1582
1583/// A forward-reference to a template argument that was not known at the point
1584/// where the template parameter name was parsed in a mangling.
1585///
1586/// This is created when demangling the name of a specialization of a
1587/// conversion function template:
1588///
1589/// \code
1590/// struct A {
1591/// template<typename T> operator T*();
1592/// };
1593/// \endcode
1594///
1595/// When demangling a specialization of the conversion function template, we
1596/// encounter the name of the template (including the \c T) before we reach
1597/// the template argument list, so we cannot substitute the parameter name
1598/// for the corresponding argument while parsing. Instead, we create a
1599/// \c ForwardTemplateReference node that is resolved after we parse the
1600/// template arguments.
1601struct ForwardTemplateReference : Node {
1602 size_t Index;
1603 Node *Ref = nullptr;
1604
1605 // If we're currently printing this node. It is possible (though invalid) for
1606 // a forward template reference to refer to itself via a substitution. This
1607 // creates a cyclic AST, which will stack overflow printing. To fix this, bail
1608 // out if more than one print* function is active.
1609 mutable bool Printing = false;
1610
1611 ForwardTemplateReference(size_t Index_)
1612 : Node(KForwardTemplateReference, Cache::Unknown, Cache::Unknown,
1613 Cache::Unknown),
1614 Index(Index_) {}
1615
1616 // We don't provide a matcher for these, because the value of the node is
1617 // not determined by its construction parameters, and it generally needs
1618 // special handling.
1619 template<typename Fn> void match(Fn F) const = delete;
1620
1621 bool hasRHSComponentSlow(OutputBuffer &OB) const override {
1622 if (Printing)
1623 return false;
1624 ScopedOverride<bool> SavePrinting(Printing, true);
1625 return Ref->hasRHSComponent(OB);
1626 }
1627 bool hasArraySlow(OutputBuffer &OB) const override {
1628 if (Printing)
1629 return false;
1630 ScopedOverride<bool> SavePrinting(Printing, true);
1631 return Ref->hasArray(OB);
1632 }
1633 bool hasFunctionSlow(OutputBuffer &OB) const override {
1634 if (Printing)
1635 return false;
1636 ScopedOverride<bool> SavePrinting(Printing, true);
1637 return Ref->hasFunction(OB);
1638 }
1639 const Node *getSyntaxNode(OutputBuffer &OB) const override {
1640 if (Printing)
1641 return this;
1642 ScopedOverride<bool> SavePrinting(Printing, true);
1643 return Ref->getSyntaxNode(OB);
1644 }
1645
1646 void printLeft(OutputBuffer &OB) const override {
1647 if (Printing)
1648 return;
1649 ScopedOverride<bool> SavePrinting(Printing, true);
1650 OB.printLeft(N: *Ref);
1651 }
1652 void printRight(OutputBuffer &OB) const override {
1653 if (Printing)
1654 return;
1655 ScopedOverride<bool> SavePrinting(Printing, true);
1656 OB.printRight(N: *Ref);
1657 }
1658};
1659
1660struct NameWithTemplateArgs : Node {
1661 // name<template_args>
1662 Node *Name;
1663 Node *TemplateArgs;
1664
1665 NameWithTemplateArgs(Node *Name_, Node *TemplateArgs_)
1666 : Node(KNameWithTemplateArgs), Name(Name_), TemplateArgs(TemplateArgs_) {}
1667
1668 template<typename Fn> void match(Fn F) const { F(Name, TemplateArgs); }
1669
1670 std::string_view getBaseName() const override { return Name->getBaseName(); }
1671
1672 void printLeft(OutputBuffer &OB) const override {
1673 Name->print(OB);
1674 TemplateArgs->print(OB);
1675 }
1676};
1677
1678class GlobalQualifiedName final : public Node {
1679 Node *Child;
1680
1681public:
1682 GlobalQualifiedName(Node* Child_)
1683 : Node(KGlobalQualifiedName), Child(Child_) {}
1684
1685 template<typename Fn> void match(Fn F) const { F(Child); }
1686
1687 std::string_view getBaseName() const override { return Child->getBaseName(); }
1688
1689 void printLeft(OutputBuffer &OB) const override {
1690 OB += "::";
1691 Child->print(OB);
1692 }
1693};
1694
1695enum class SpecialSubKind {
1696 allocator,
1697 basic_string,
1698 string,
1699 istream,
1700 ostream,
1701 iostream,
1702};
1703
1704class SpecialSubstitution;
1705class ExpandedSpecialSubstitution : public Node {
1706protected:
1707 SpecialSubKind SSK;
1708
1709 ExpandedSpecialSubstitution(SpecialSubKind SSK_, Kind K_)
1710 : Node(K_), SSK(SSK_) {}
1711public:
1712 ExpandedSpecialSubstitution(SpecialSubKind SSK_)
1713 : ExpandedSpecialSubstitution(SSK_, KExpandedSpecialSubstitution) {}
1714 inline ExpandedSpecialSubstitution(SpecialSubstitution const *);
1715
1716 template<typename Fn> void match(Fn F) const { F(SSK); }
1717
1718protected:
1719 bool isInstantiation() const {
1720 return unsigned(SSK) >= unsigned(SpecialSubKind::string);
1721 }
1722
1723 std::string_view getBaseName() const override {
1724 switch (SSK) {
1725 case SpecialSubKind::allocator:
1726 return {"allocator"};
1727 case SpecialSubKind::basic_string:
1728 return {"basic_string"};
1729 case SpecialSubKind::string:
1730 return {"basic_string"};
1731 case SpecialSubKind::istream:
1732 return {"basic_istream"};
1733 case SpecialSubKind::ostream:
1734 return {"basic_ostream"};
1735 case SpecialSubKind::iostream:
1736 return {"basic_iostream"};
1737 }
1738 DEMANGLE_UNREACHABLE;
1739 }
1740
1741private:
1742 void printLeft(OutputBuffer &OB) const override {
1743 OB << "std::" << getBaseName();
1744 if (isInstantiation()) {
1745 OB << "<char, std::char_traits<char>";
1746 if (SSK == SpecialSubKind::string)
1747 OB << ", std::allocator<char>";
1748 OB << ">";
1749 }
1750 }
1751};
1752
1753class SpecialSubstitution final : public ExpandedSpecialSubstitution {
1754public:
1755 SpecialSubstitution(SpecialSubKind SSK_)
1756 : ExpandedSpecialSubstitution(SSK_, KSpecialSubstitution) {}
1757
1758 template<typename Fn> void match(Fn F) const { F(SSK); }
1759
1760 std::string_view getBaseName() const override {
1761 std::string_view SV = ExpandedSpecialSubstitution::getBaseName();
1762 if (isInstantiation()) {
1763 // The instantiations are typedefs that drop the "basic_" prefix.
1764 DEMANGLE_ASSERT(starts_with(SV, "basic_"), "");
1765 SV.remove_prefix(n: sizeof("basic_") - 1);
1766 }
1767 return SV;
1768 }
1769
1770 void printLeft(OutputBuffer &OB) const override {
1771 OB << "std::" << getBaseName();
1772 }
1773};
1774
1775inline ExpandedSpecialSubstitution::ExpandedSpecialSubstitution(
1776 SpecialSubstitution const *SS)
1777 : ExpandedSpecialSubstitution(SS->SSK) {}
1778
1779class CtorDtorName final : public Node {
1780 const Node *Basename;
1781 const bool IsDtor;
1782 const int Variant;
1783
1784public:
1785 CtorDtorName(const Node *Basename_, bool IsDtor_, int Variant_)
1786 : Node(KCtorDtorName), Basename(Basename_), IsDtor(IsDtor_),
1787 Variant(Variant_) {}
1788
1789 template<typename Fn> void match(Fn F) const { F(Basename, IsDtor, Variant); }
1790
1791 void printLeft(OutputBuffer &OB) const override {
1792 if (IsDtor)
1793 OB += "~";
1794 OB += Basename->getBaseName();
1795 }
1796};
1797
1798class DtorName : public Node {
1799 const Node *Base;
1800
1801public:
1802 DtorName(const Node *Base_) : Node(KDtorName), Base(Base_) {}
1803
1804 template<typename Fn> void match(Fn F) const { F(Base); }
1805
1806 void printLeft(OutputBuffer &OB) const override {
1807 OB += "~";
1808 OB.printLeft(N: *Base);
1809 }
1810};
1811
1812class UnnamedTypeName : public Node {
1813 const std::string_view Count;
1814
1815public:
1816 UnnamedTypeName(std::string_view Count_)
1817 : Node(KUnnamedTypeName), Count(Count_) {}
1818
1819 template<typename Fn> void match(Fn F) const { F(Count); }
1820
1821 void printLeft(OutputBuffer &OB) const override {
1822 OB += "'unnamed";
1823 OB += Count;
1824 OB += "\'";
1825 }
1826};
1827
1828class ClosureTypeName : public Node {
1829 NodeArray TemplateParams;
1830 const Node *Requires1;
1831 NodeArray Params;
1832 const Node *Requires2;
1833 std::string_view Count;
1834
1835public:
1836 ClosureTypeName(NodeArray TemplateParams_, const Node *Requires1_,
1837 NodeArray Params_, const Node *Requires2_,
1838 std::string_view Count_)
1839 : Node(KClosureTypeName), TemplateParams(TemplateParams_),
1840 Requires1(Requires1_), Params(Params_), Requires2(Requires2_),
1841 Count(Count_) {}
1842
1843 template<typename Fn> void match(Fn F) const {
1844 F(TemplateParams, Requires1, Params, Requires2, Count);
1845 }
1846
1847 void printDeclarator(OutputBuffer &OB) const {
1848 if (!TemplateParams.empty()) {
1849 ScopedOverride<bool> LT(OB.TemplateTracker.InsideTemplate, true);
1850 OB += "<";
1851 TemplateParams.printWithComma(OB);
1852 OB += ">";
1853 }
1854 if (Requires1 != nullptr) {
1855 OB += " requires ";
1856 Requires1->print(OB);
1857 OB += " ";
1858 }
1859 OB.printOpen();
1860 Params.printWithComma(OB);
1861 OB.printClose();
1862 if (Requires2 != nullptr) {
1863 OB += " requires ";
1864 Requires2->print(OB);
1865 }
1866 }
1867
1868 void printLeft(OutputBuffer &OB) const override {
1869 // FIXME: This demangling is not particularly readable.
1870 OB += "\'lambda";
1871 OB += Count;
1872 OB += "\'";
1873 printDeclarator(OB);
1874 }
1875};
1876
1877class StructuredBindingName : public Node {
1878 NodeArray Bindings;
1879public:
1880 StructuredBindingName(NodeArray Bindings_)
1881 : Node(KStructuredBindingName), Bindings(Bindings_) {}
1882
1883 template<typename Fn> void match(Fn F) const { F(Bindings); }
1884
1885 void printLeft(OutputBuffer &OB) const override {
1886 OB.printOpen(Open: '[');
1887 Bindings.printWithComma(OB);
1888 OB.printClose(Close: ']');
1889 }
1890};
1891
1892// -- Expression Nodes --
1893
1894class BinaryExpr : public Node {
1895 const Node *LHS;
1896 const std::string_view InfixOperator;
1897 const Node *RHS;
1898
1899public:
1900 BinaryExpr(const Node *LHS_, std::string_view InfixOperator_,
1901 const Node *RHS_, Prec Prec_)
1902 : Node(KBinaryExpr, Prec_), LHS(LHS_), InfixOperator(InfixOperator_),
1903 RHS(RHS_) {}
1904
1905 template <typename Fn> void match(Fn F) const {
1906 F(LHS, InfixOperator, RHS, getPrecedence());
1907 }
1908
1909 void printLeft(OutputBuffer &OB) const override {
1910 // If we're printing a '<' inside of a template argument, and we haven't
1911 // yet parenthesized the expression, do so now.
1912 bool ParenAll = !OB.isInParensInTemplateArgs() &&
1913 (InfixOperator == ">" || InfixOperator == ">>");
1914 if (ParenAll)
1915 OB.printOpen();
1916 // Assignment is right associative, with special LHS precedence.
1917 bool IsAssign = getPrecedence() == Prec::Assign;
1918 LHS->printAsOperand(OB, P: IsAssign ? Prec::OrIf : getPrecedence(), StrictlyWorse: !IsAssign);
1919 // No space before comma operator
1920 if (!(InfixOperator == ","))
1921 OB += " ";
1922 OB += InfixOperator;
1923 OB += " ";
1924 RHS->printAsOperand(OB, P: getPrecedence(), StrictlyWorse: IsAssign);
1925 if (ParenAll)
1926 OB.printClose();
1927 }
1928};
1929
1930class ArraySubscriptExpr : public Node {
1931 const Node *Op1;
1932 const Node *Op2;
1933
1934public:
1935 ArraySubscriptExpr(const Node *Op1_, const Node *Op2_, Prec Prec_)
1936 : Node(KArraySubscriptExpr, Prec_), Op1(Op1_), Op2(Op2_) {}
1937
1938 template <typename Fn> void match(Fn F) const {
1939 F(Op1, Op2, getPrecedence());
1940 }
1941
1942 void printLeft(OutputBuffer &OB) const override {
1943 Op1->printAsOperand(OB, P: getPrecedence());
1944 OB.printOpen(Open: '[');
1945 Op2->printAsOperand(OB);
1946 OB.printClose(Close: ']');
1947 }
1948};
1949
1950class PostfixExpr : public Node {
1951 const Node *Child;
1952 const std::string_view Operator;
1953
1954public:
1955 PostfixExpr(const Node *Child_, std::string_view Operator_, Prec Prec_)
1956 : Node(KPostfixExpr, Prec_), Child(Child_), Operator(Operator_) {}
1957
1958 template <typename Fn> void match(Fn F) const {
1959 F(Child, Operator, getPrecedence());
1960 }
1961
1962 void printLeft(OutputBuffer &OB) const override {
1963 Child->printAsOperand(OB, P: getPrecedence(), StrictlyWorse: true);
1964 OB += Operator;
1965 }
1966};
1967
1968class ConditionalExpr : public Node {
1969 const Node *Cond;
1970 const Node *Then;
1971 const Node *Else;
1972
1973public:
1974 ConditionalExpr(const Node *Cond_, const Node *Then_, const Node *Else_,
1975 Prec Prec_)
1976 : Node(KConditionalExpr, Prec_), Cond(Cond_), Then(Then_), Else(Else_) {}
1977
1978 template <typename Fn> void match(Fn F) const {
1979 F(Cond, Then, Else, getPrecedence());
1980 }
1981
1982 void printLeft(OutputBuffer &OB) const override {
1983 Cond->printAsOperand(OB, P: getPrecedence());
1984 OB += " ? ";
1985 Then->printAsOperand(OB);
1986 OB += " : ";
1987 Else->printAsOperand(OB, P: Prec::Assign, StrictlyWorse: true);
1988 }
1989};
1990
1991class MemberExpr : public Node {
1992 const Node *LHS;
1993 const std::string_view Kind;
1994 const Node *RHS;
1995
1996public:
1997 MemberExpr(const Node *LHS_, std::string_view Kind_, const Node *RHS_,
1998 Prec Prec_)
1999 : Node(KMemberExpr, Prec_), LHS(LHS_), Kind(Kind_), RHS(RHS_) {}
2000
2001 template <typename Fn> void match(Fn F) const {
2002 F(LHS, Kind, RHS, getPrecedence());
2003 }
2004
2005 void printLeft(OutputBuffer &OB) const override {
2006 LHS->printAsOperand(OB, P: getPrecedence(), StrictlyWorse: true);
2007 OB += Kind;
2008 RHS->printAsOperand(OB, P: getPrecedence(), StrictlyWorse: false);
2009 }
2010};
2011
2012class SubobjectExpr : public Node {
2013 const Node *Type;
2014 const Node *SubExpr;
2015 std::string_view Offset;
2016 NodeArray UnionSelectors;
2017 bool OnePastTheEnd;
2018
2019public:
2020 SubobjectExpr(const Node *Type_, const Node *SubExpr_,
2021 std::string_view Offset_, NodeArray UnionSelectors_,
2022 bool OnePastTheEnd_)
2023 : Node(KSubobjectExpr), Type(Type_), SubExpr(SubExpr_), Offset(Offset_),
2024 UnionSelectors(UnionSelectors_), OnePastTheEnd(OnePastTheEnd_) {}
2025
2026 template<typename Fn> void match(Fn F) const {
2027 F(Type, SubExpr, Offset, UnionSelectors, OnePastTheEnd);
2028 }
2029
2030 void printLeft(OutputBuffer &OB) const override {
2031 SubExpr->print(OB);
2032 OB += ".<";
2033 Type->print(OB);
2034 OB += " at offset ";
2035 if (Offset.empty()) {
2036 OB += "0";
2037 } else if (Offset[0] == 'n') {
2038 OB += "-";
2039 OB += std::string_view(Offset.data() + 1, Offset.size() - 1);
2040 } else {
2041 OB += Offset;
2042 }
2043 OB += ">";
2044 }
2045};
2046
2047class EnclosingExpr : public Node {
2048 const std::string_view Prefix;
2049 const Node *Infix;
2050 const std::string_view Postfix;
2051
2052public:
2053 EnclosingExpr(std::string_view Prefix_, const Node *Infix_,
2054 Prec Prec_ = Prec::Primary)
2055 : Node(KEnclosingExpr, Prec_), Prefix(Prefix_), Infix(Infix_) {}
2056
2057 template <typename Fn> void match(Fn F) const {
2058 F(Prefix, Infix, getPrecedence());
2059 }
2060
2061 void printLeft(OutputBuffer &OB) const override {
2062 OB += Prefix;
2063 OB.printOpen();
2064 Infix->print(OB);
2065 OB.printClose();
2066 OB += Postfix;
2067 }
2068};
2069
2070class CastExpr : public Node {
2071 // cast_kind<to>(from)
2072 const std::string_view CastKind;
2073 const Node *To;
2074 const Node *From;
2075
2076public:
2077 CastExpr(std::string_view CastKind_, const Node *To_, const Node *From_,
2078 Prec Prec_)
2079 : Node(KCastExpr, Prec_), CastKind(CastKind_), To(To_), From(From_) {}
2080
2081 template <typename Fn> void match(Fn F) const {
2082 F(CastKind, To, From, getPrecedence());
2083 }
2084
2085 void printLeft(OutputBuffer &OB) const override {
2086 OB += CastKind;
2087 {
2088 ScopedOverride<bool> LT(OB.TemplateTracker.InsideTemplate, true);
2089 OB += "<";
2090 OB.printLeft(N: *To);
2091 OB += ">";
2092 }
2093 OB.printOpen();
2094 From->printAsOperand(OB);
2095 OB.printClose();
2096 }
2097};
2098
2099class SizeofParamPackExpr : public Node {
2100 const Node *Pack;
2101
2102public:
2103 SizeofParamPackExpr(const Node *Pack_)
2104 : Node(KSizeofParamPackExpr), Pack(Pack_) {}
2105
2106 template<typename Fn> void match(Fn F) const { F(Pack); }
2107
2108 void printLeft(OutputBuffer &OB) const override {
2109 OB += "sizeof...";
2110 OB.printOpen();
2111 ParameterPackExpansion PPE(Pack);
2112 PPE.printLeft(OB);
2113 OB.printClose();
2114 }
2115};
2116
2117class CallExpr : public Node {
2118 const Node *Callee;
2119 NodeArray Args;
2120 bool IsParen; // (func)(args ...) ?
2121
2122public:
2123 CallExpr(const Node *Callee_, NodeArray Args_, bool IsParen_, Prec Prec_)
2124 : Node(KCallExpr, Prec_), Callee(Callee_), Args(Args_),
2125 IsParen(IsParen_) {}
2126
2127 template <typename Fn> void match(Fn F) const {
2128 F(Callee, Args, IsParen, getPrecedence());
2129 }
2130
2131 void printLeft(OutputBuffer &OB) const override {
2132 if (IsParen)
2133 OB.printOpen();
2134 Callee->print(OB);
2135 if (IsParen)
2136 OB.printClose();
2137 OB.printOpen();
2138 Args.printWithComma(OB);
2139 OB.printClose();
2140 }
2141};
2142
2143class NewExpr : public Node {
2144 // new (expr_list) type(init_list)
2145 NodeArray ExprList;
2146 Node *Type;
2147 NodeArray InitList;
2148 bool IsGlobal; // ::operator new ?
2149 bool IsArray; // new[] ?
2150public:
2151 NewExpr(NodeArray ExprList_, Node *Type_, NodeArray InitList_, bool IsGlobal_,
2152 bool IsArray_, Prec Prec_)
2153 : Node(KNewExpr, Prec_), ExprList(ExprList_), Type(Type_),
2154 InitList(InitList_), IsGlobal(IsGlobal_), IsArray(IsArray_) {}
2155
2156 template<typename Fn> void match(Fn F) const {
2157 F(ExprList, Type, InitList, IsGlobal, IsArray, getPrecedence());
2158 }
2159
2160 void printLeft(OutputBuffer &OB) const override {
2161 if (IsGlobal)
2162 OB += "::";
2163 OB += "new";
2164 if (IsArray)
2165 OB += "[]";
2166 if (!ExprList.empty()) {
2167 OB.printOpen();
2168 ExprList.printWithComma(OB);
2169 OB.printClose();
2170 }
2171 OB += " ";
2172 Type->print(OB);
2173 if (!InitList.empty()) {
2174 OB.printOpen();
2175 InitList.printWithComma(OB);
2176 OB.printClose();
2177 }
2178 }
2179};
2180
2181class DeleteExpr : public Node {
2182 Node *Op;
2183 bool IsGlobal;
2184 bool IsArray;
2185
2186public:
2187 DeleteExpr(Node *Op_, bool IsGlobal_, bool IsArray_, Prec Prec_)
2188 : Node(KDeleteExpr, Prec_), Op(Op_), IsGlobal(IsGlobal_),
2189 IsArray(IsArray_) {}
2190
2191 template <typename Fn> void match(Fn F) const {
2192 F(Op, IsGlobal, IsArray, getPrecedence());
2193 }
2194
2195 void printLeft(OutputBuffer &OB) const override {
2196 if (IsGlobal)
2197 OB += "::";
2198 OB += "delete";
2199 if (IsArray)
2200 OB += "[]";
2201 OB += ' ';
2202 Op->print(OB);
2203 }
2204};
2205
2206class PrefixExpr : public Node {
2207 std::string_view Prefix;
2208 Node *Child;
2209
2210public:
2211 PrefixExpr(std::string_view Prefix_, Node *Child_, Prec Prec_)
2212 : Node(KPrefixExpr, Prec_), Prefix(Prefix_), Child(Child_) {}
2213
2214 template <typename Fn> void match(Fn F) const {
2215 F(Prefix, Child, getPrecedence());
2216 }
2217
2218 void printLeft(OutputBuffer &OB) const override {
2219 OB += Prefix;
2220 Child->printAsOperand(OB, P: getPrecedence());
2221 }
2222};
2223
2224class FunctionParam : public Node {
2225 std::string_view Number;
2226
2227public:
2228 FunctionParam(std::string_view Number_)
2229 : Node(KFunctionParam), Number(Number_) {}
2230
2231 template<typename Fn> void match(Fn F) const { F(Number); }
2232
2233 void printLeft(OutputBuffer &OB) const override {
2234 OB += "fp";
2235 OB += Number;
2236 }
2237};
2238
2239class ConversionExpr : public Node {
2240 const Node *Type;
2241 NodeArray Expressions;
2242
2243public:
2244 ConversionExpr(const Node *Type_, NodeArray Expressions_, Prec Prec_)
2245 : Node(KConversionExpr, Prec_), Type(Type_), Expressions(Expressions_) {}
2246
2247 template <typename Fn> void match(Fn F) const {
2248 F(Type, Expressions, getPrecedence());
2249 }
2250
2251 void printLeft(OutputBuffer &OB) const override {
2252 OB.printOpen();
2253 Type->print(OB);
2254 OB.printClose();
2255 OB.printOpen();
2256 Expressions.printWithComma(OB);
2257 OB.printClose();
2258 }
2259};
2260
2261class PointerToMemberConversionExpr : public Node {
2262 const Node *Type;
2263 const Node *SubExpr;
2264 std::string_view Offset;
2265
2266public:
2267 PointerToMemberConversionExpr(const Node *Type_, const Node *SubExpr_,
2268 std::string_view Offset_, Prec Prec_)
2269 : Node(KPointerToMemberConversionExpr, Prec_), Type(Type_),
2270 SubExpr(SubExpr_), Offset(Offset_) {}
2271
2272 template <typename Fn> void match(Fn F) const {
2273 F(Type, SubExpr, Offset, getPrecedence());
2274 }
2275
2276 void printLeft(OutputBuffer &OB) const override {
2277 OB.printOpen();
2278 Type->print(OB);
2279 OB.printClose();
2280 OB.printOpen();
2281 SubExpr->print(OB);
2282 OB.printClose();
2283 }
2284};
2285
2286class InitListExpr : public Node {
2287 const Node *Ty;
2288 NodeArray Inits;
2289public:
2290 InitListExpr(const Node *Ty_, NodeArray Inits_)
2291 : Node(KInitListExpr), Ty(Ty_), Inits(Inits_) {}
2292
2293 template<typename Fn> void match(Fn F) const { F(Ty, Inits); }
2294
2295 void printLeft(OutputBuffer &OB) const override {
2296 if (Ty) {
2297 if (Ty->printInitListAsType(OB, Inits))
2298 return;
2299 Ty->print(OB);
2300 }
2301 OB += '{';
2302 Inits.printWithComma(OB);
2303 OB += '}';
2304 }
2305};
2306
2307class BracedExpr : public Node {
2308 const Node *Elem;
2309 const Node *Init;
2310 bool IsArray;
2311public:
2312 BracedExpr(const Node *Elem_, const Node *Init_, bool IsArray_)
2313 : Node(KBracedExpr), Elem(Elem_), Init(Init_), IsArray(IsArray_) {}
2314
2315 template<typename Fn> void match(Fn F) const { F(Elem, Init, IsArray); }
2316
2317 void printLeft(OutputBuffer &OB) const override {
2318 if (IsArray) {
2319 OB += '[';
2320 Elem->print(OB);
2321 OB += ']';
2322 } else {
2323 OB += '.';
2324 Elem->print(OB);
2325 }
2326 if (Init->getKind() != KBracedExpr && Init->getKind() != KBracedRangeExpr)
2327 OB += " = ";
2328 Init->print(OB);
2329 }
2330};
2331
2332class BracedRangeExpr : public Node {
2333 const Node *First;
2334 const Node *Last;
2335 const Node *Init;
2336public:
2337 BracedRangeExpr(const Node *First_, const Node *Last_, const Node *Init_)
2338 : Node(KBracedRangeExpr), First(First_), Last(Last_), Init(Init_) {}
2339
2340 template<typename Fn> void match(Fn F) const { F(First, Last, Init); }
2341
2342 void printLeft(OutputBuffer &OB) const override {
2343 OB += '[';
2344 First->print(OB);
2345 OB += " ... ";
2346 Last->print(OB);
2347 OB += ']';
2348 if (Init->getKind() != KBracedExpr && Init->getKind() != KBracedRangeExpr)
2349 OB += " = ";
2350 Init->print(OB);
2351 }
2352};
2353
2354class FoldExpr : public Node {
2355 const Node *Pack, *Init;
2356 std::string_view OperatorName;
2357 bool IsLeftFold;
2358
2359public:
2360 FoldExpr(bool IsLeftFold_, std::string_view OperatorName_, const Node *Pack_,
2361 const Node *Init_)
2362 : Node(KFoldExpr), Pack(Pack_), Init(Init_), OperatorName(OperatorName_),
2363 IsLeftFold(IsLeftFold_) {}
2364
2365 template<typename Fn> void match(Fn F) const {
2366 F(IsLeftFold, OperatorName, Pack, Init);
2367 }
2368
2369 void printLeft(OutputBuffer &OB) const override {
2370 auto PrintPack = [&] {
2371 OB.printOpen();
2372 ParameterPackExpansion(Pack).print(OB);
2373 OB.printClose();
2374 };
2375
2376 OB.printOpen();
2377 // Either '[init op ]... op pack' or 'pack op ...[ op init]'
2378 // Refactored to '[(init|pack) op ]...[ op (pack|init)]'
2379 // Fold expr operands are cast-expressions
2380 if (!IsLeftFold || Init != nullptr) {
2381 // '(init|pack) op '
2382 if (IsLeftFold)
2383 Init->printAsOperand(OB, P: Prec::Cast, StrictlyWorse: true);
2384 else
2385 PrintPack();
2386 OB << " " << OperatorName << " ";
2387 }
2388 OB << "...";
2389 if (IsLeftFold || Init != nullptr) {
2390 // ' op (init|pack)'
2391 OB << " " << OperatorName << " ";
2392 if (IsLeftFold)
2393 PrintPack();
2394 else
2395 Init->printAsOperand(OB, P: Prec::Cast, StrictlyWorse: true);
2396 }
2397 OB.printClose();
2398 }
2399};
2400
2401class ThrowExpr : public Node {
2402 const Node *Op;
2403
2404public:
2405 ThrowExpr(const Node *Op_) : Node(KThrowExpr), Op(Op_) {}
2406
2407 template<typename Fn> void match(Fn F) const { F(Op); }
2408
2409 void printLeft(OutputBuffer &OB) const override {
2410 OB += "throw ";
2411 Op->print(OB);
2412 }
2413};
2414
2415class BoolExpr : public Node {
2416 bool Value;
2417
2418public:
2419 BoolExpr(bool Value_) : Node(KBoolExpr), Value(Value_) {}
2420
2421 template<typename Fn> void match(Fn F) const { F(Value); }
2422
2423 void printLeft(OutputBuffer &OB) const override {
2424 OB += Value ? std::string_view("true") : std::string_view("false");
2425 }
2426};
2427
2428class StringLiteral : public Node {
2429 const Node *Type;
2430
2431public:
2432 StringLiteral(const Node *Type_) : Node(KStringLiteral), Type(Type_) {}
2433
2434 template<typename Fn> void match(Fn F) const { F(Type); }
2435
2436 void printLeft(OutputBuffer &OB) const override {
2437 OB += "\"<";
2438 Type->print(OB);
2439 OB += ">\"";
2440 }
2441};
2442
2443class LambdaExpr : public Node {
2444 const Node *Type;
2445
2446public:
2447 LambdaExpr(const Node *Type_) : Node(KLambdaExpr), Type(Type_) {}
2448
2449 template<typename Fn> void match(Fn F) const { F(Type); }
2450
2451 void printLeft(OutputBuffer &OB) const override {
2452 OB += "[]";
2453 if (Type->getKind() == KClosureTypeName)
2454 static_cast<const ClosureTypeName *>(Type)->printDeclarator(OB);
2455 OB += "{...}";
2456 }
2457};
2458
2459class EnumLiteral : public Node {
2460 // ty(integer)
2461 const Node *Ty;
2462 std::string_view Integer;
2463
2464public:
2465 EnumLiteral(const Node *Ty_, std::string_view Integer_)
2466 : Node(KEnumLiteral), Ty(Ty_), Integer(Integer_) {}
2467
2468 template<typename Fn> void match(Fn F) const { F(Ty, Integer); }
2469
2470 void printLeft(OutputBuffer &OB) const override {
2471 OB.printOpen();
2472 Ty->print(OB);
2473 OB.printClose();
2474
2475 if (Integer[0] == 'n')
2476 OB << '-' << std::string_view(Integer.data() + 1, Integer.size() - 1);
2477 else
2478 OB << Integer;
2479 }
2480};
2481
2482class IntegerLiteral : public Node {
2483 std::string_view Type;
2484 std::string_view Value;
2485
2486public:
2487 IntegerLiteral(std::string_view Type_, std::string_view Value_)
2488 : Node(KIntegerLiteral), Type(Type_), Value(Value_) {}
2489
2490 template<typename Fn> void match(Fn F) const { F(Type, Value); }
2491
2492 void printLeft(OutputBuffer &OB) const override {
2493 if (Type.size() > 3) {
2494 OB.printOpen();
2495 OB += Type;
2496 OB.printClose();
2497 }
2498
2499 if (Value[0] == 'n')
2500 OB << '-' << std::string_view(Value.data() + 1, Value.size() - 1);
2501 else
2502 OB += Value;
2503
2504 if (Type.size() <= 3)
2505 OB += Type;
2506 }
2507
2508 std::string_view value() const { return Value; }
2509};
2510
2511class RequiresExpr : public Node {
2512 NodeArray Parameters;
2513 NodeArray Requirements;
2514public:
2515 RequiresExpr(NodeArray Parameters_, NodeArray Requirements_)
2516 : Node(KRequiresExpr), Parameters(Parameters_),
2517 Requirements(Requirements_) {}
2518
2519 template<typename Fn> void match(Fn F) const { F(Parameters, Requirements); }
2520
2521 void printLeft(OutputBuffer &OB) const override {
2522 OB += "requires";
2523 if (!Parameters.empty()) {
2524 OB += ' ';
2525 OB.printOpen();
2526 Parameters.printWithComma(OB);
2527 OB.printClose();
2528 }
2529 OB += ' ';
2530 OB.printOpen(Open: '{');
2531 for (const Node *Req : Requirements) {
2532 Req->print(OB);
2533 }
2534 OB += ' ';
2535 OB.printClose(Close: '}');
2536 }
2537};
2538
2539class ExprRequirement : public Node {
2540 const Node *Expr;
2541 bool IsNoexcept;
2542 const Node *TypeConstraint;
2543public:
2544 ExprRequirement(const Node *Expr_, bool IsNoexcept_,
2545 const Node *TypeConstraint_)
2546 : Node(KExprRequirement), Expr(Expr_), IsNoexcept(IsNoexcept_),
2547 TypeConstraint(TypeConstraint_) {}
2548
2549 template <typename Fn> void match(Fn F) const {
2550 F(Expr, IsNoexcept, TypeConstraint);
2551 }
2552
2553 void printLeft(OutputBuffer &OB) const override {
2554 OB += " ";
2555 if (IsNoexcept || TypeConstraint)
2556 OB.printOpen(Open: '{');
2557 Expr->print(OB);
2558 if (IsNoexcept || TypeConstraint)
2559 OB.printClose(Close: '}');
2560 if (IsNoexcept)
2561 OB += " noexcept";
2562 if (TypeConstraint) {
2563 OB += " -> ";
2564 TypeConstraint->print(OB);
2565 }
2566 OB += ';';
2567 }
2568};
2569
2570class TypeRequirement : public Node {
2571 const Node *Type;
2572public:
2573 TypeRequirement(const Node *Type_)
2574 : Node(KTypeRequirement), Type(Type_) {}
2575
2576 template <typename Fn> void match(Fn F) const { F(Type); }
2577
2578 void printLeft(OutputBuffer &OB) const override {
2579 OB += " typename ";
2580 Type->print(OB);
2581 OB += ';';
2582 }
2583};
2584
2585class NestedRequirement : public Node {
2586 const Node *Constraint;
2587public:
2588 NestedRequirement(const Node *Constraint_)
2589 : Node(KNestedRequirement), Constraint(Constraint_) {}
2590
2591 template <typename Fn> void match(Fn F) const { F(Constraint); }
2592
2593 void printLeft(OutputBuffer &OB) const override {
2594 OB += " requires ";
2595 Constraint->print(OB);
2596 OB += ';';
2597 }
2598};
2599
2600template <class Float> struct FloatData;
2601
2602namespace float_literal_impl {
2603constexpr Node::Kind getFloatLiteralKind(float *) {
2604 return Node::KFloatLiteral;
2605}
2606constexpr Node::Kind getFloatLiteralKind(double *) {
2607 return Node::KDoubleLiteral;
2608}
2609constexpr Node::Kind getFloatLiteralKind(long double *) {
2610 return Node::KLongDoubleLiteral;
2611}
2612}
2613
2614template <class Float> class FloatLiteralImpl : public Node {
2615 const std::string_view Contents;
2616
2617 static constexpr Kind KindForClass =
2618 float_literal_impl::getFloatLiteralKind((Float *)nullptr);
2619
2620public:
2621 FloatLiteralImpl(std::string_view Contents_)
2622 : Node(KindForClass), Contents(Contents_) {}
2623
2624 template<typename Fn> void match(Fn F) const { F(Contents); }
2625
2626 void printLeft(OutputBuffer &OB) const override {
2627 const size_t N = FloatData<Float>::mangled_size;
2628 if (Contents.size() >= N) {
2629 union {
2630 Float value;
2631 char buf[sizeof(Float)];
2632 };
2633 const char *t = Contents.data();
2634 const char *last = t + N;
2635 char *e = buf;
2636 for (; t != last; ++t, ++e) {
2637 unsigned d1 = isdigit(c: *t) ? static_cast<unsigned>(*t - '0')
2638 : static_cast<unsigned>(*t - 'a' + 10);
2639 ++t;
2640 unsigned d0 = isdigit(c: *t) ? static_cast<unsigned>(*t - '0')
2641 : static_cast<unsigned>(*t - 'a' + 10);
2642 *e = static_cast<char>((d1 << 4) + d0);
2643 }
2644#if __BYTE_ORDER__ == __ORDER_LITTLE_ENDIAN__
2645 std::reverse(buf, e);
2646#endif
2647 char num[FloatData<Float>::max_demangled_size] = {0};
2648 int n = snprintf(num, sizeof(num), FloatData<Float>::spec, value);
2649 OB += std::string_view(num, n);
2650 }
2651 }
2652};
2653
2654using FloatLiteral = FloatLiteralImpl<float>;
2655using DoubleLiteral = FloatLiteralImpl<double>;
2656using LongDoubleLiteral = FloatLiteralImpl<long double>;
2657
2658/// Visit the node. Calls \c F(P), where \c P is the node cast to the
2659/// appropriate derived class.
2660template<typename Fn>
2661void Node::visit(Fn F) const {
2662 switch (K) {
2663#define NODE(X) \
2664 case K##X: \
2665 return F(static_cast<const X *>(this));
2666#include "ItaniumNodes.def"
2667 }
2668 DEMANGLE_ASSERT(0, "unknown mangling node kind");
2669}
2670
2671/// Determine the kind of a node from its type.
2672template<typename NodeT> struct NodeKind;
2673#define NODE(X) \
2674 template <> struct NodeKind<X> { \
2675 static constexpr Node::Kind Kind = Node::K##X; \
2676 static constexpr const char *name() { return #X; } \
2677 };
2678#include "ItaniumNodes.def"
2679
2680inline bool NodeArray::printAsString(OutputBuffer &OB) const {
2681 auto StartPos = OB.getCurrentPosition();
2682 auto Fail = [&OB, StartPos] {
2683 OB.setCurrentPosition(StartPos);
2684 return false;
2685 };
2686
2687 OB += '"';
2688 bool LastWasNumericEscape = false;
2689 for (const Node *Element : *this) {
2690 if (Element->getKind() != Node::KIntegerLiteral)
2691 return Fail();
2692 int integer_value = 0;
2693 for (char c : static_cast<const IntegerLiteral *>(Element)->value()) {
2694 if (c < '0' || c > '9' || integer_value > 25)
2695 return Fail();
2696 integer_value *= 10;
2697 integer_value += c - '0';
2698 }
2699 if (integer_value > 255)
2700 return Fail();
2701
2702 // Insert a `""` to avoid accidentally extending a numeric escape.
2703 if (LastWasNumericEscape) {
2704 if ((integer_value >= '0' && integer_value <= '9') ||
2705 (integer_value >= 'a' && integer_value <= 'f') ||
2706 (integer_value >= 'A' && integer_value <= 'F')) {
2707 OB += "\"\"";
2708 }
2709 }
2710
2711 LastWasNumericEscape = false;
2712
2713 // Determine how to print this character.
2714 switch (integer_value) {
2715 case '\a':
2716 OB += "\\a";
2717 break;
2718 case '\b':
2719 OB += "\\b";
2720 break;
2721 case '\f':
2722 OB += "\\f";
2723 break;
2724 case '\n':
2725 OB += "\\n";
2726 break;
2727 case '\r':
2728 OB += "\\r";
2729 break;
2730 case '\t':
2731 OB += "\\t";
2732 break;
2733 case '\v':
2734 OB += "\\v";
2735 break;
2736
2737 case '"':
2738 OB += "\\\"";
2739 break;
2740 case '\\':
2741 OB += "\\\\";
2742 break;
2743
2744 default:
2745 // We assume that the character is ASCII, and use a numeric escape for all
2746 // remaining non-printable ASCII characters.
2747 if (integer_value < 32 || integer_value == 127) {
2748 constexpr char Hex[] = "0123456789ABCDEF";
2749 OB += '\\';
2750 if (integer_value > 7)
2751 OB += 'x';
2752 if (integer_value >= 16)
2753 OB += Hex[integer_value >> 4];
2754 OB += Hex[integer_value & 0xF];
2755 LastWasNumericEscape = true;
2756 break;
2757 }
2758
2759 // Assume all remaining characters are directly printable.
2760 OB += (char)integer_value;
2761 break;
2762 }
2763 }
2764 OB += '"';
2765 return true;
2766}
2767
2768template <typename Derived, typename Alloc> struct AbstractManglingParser {
2769 const char *First;
2770 const char *Last;
2771
2772 // Name stack, this is used by the parser to hold temporary names that were
2773 // parsed. The parser collapses multiple names into new nodes to construct
2774 // the AST. Once the parser is finished, names.size() == 1.
2775 PODSmallVector<Node *, 32> Names;
2776
2777 // Substitution table. Itanium supports name substitutions as a means of
2778 // compression. The string "S42_" refers to the 44nd entry (base-36) in this
2779 // table.
2780 PODSmallVector<Node *, 32> Subs;
2781
2782 // A list of template argument values corresponding to a template parameter
2783 // list.
2784 using TemplateParamList = PODSmallVector<Node *, 8>;
2785
2786 class ScopedTemplateParamList {
2787 AbstractManglingParser *Parser;
2788 size_t OldNumTemplateParamLists;
2789 TemplateParamList Params;
2790
2791 public:
2792 ScopedTemplateParamList(AbstractManglingParser *TheParser)
2793 : Parser(TheParser),
2794 OldNumTemplateParamLists(TheParser->TemplateParams.size()) {
2795 Parser->TemplateParams.push_back(Elem: &Params);
2796 }
2797 ~ScopedTemplateParamList() {
2798 DEMANGLE_ASSERT(Parser->TemplateParams.size() >= OldNumTemplateParamLists,
2799 "");
2800 Parser->TemplateParams.shrinkToSize(Index: OldNumTemplateParamLists);
2801 }
2802 TemplateParamList *params() { return &Params; }
2803 };
2804
2805 // Template parameter table. Like the above, but referenced like "T42_".
2806 // This has a smaller size compared to Subs and Names because it can be
2807 // stored on the stack.
2808 TemplateParamList OuterTemplateParams;
2809
2810 // Lists of template parameters indexed by template parameter depth,
2811 // referenced like "TL2_4_". If nonempty, element 0 is always
2812 // OuterTemplateParams; inner elements are always template parameter lists of
2813 // lambda expressions. For a generic lambda with no explicit template
2814 // parameter list, the corresponding parameter list pointer will be null.
2815 PODSmallVector<TemplateParamList *, 4> TemplateParams;
2816
2817 class SaveTemplateParams {
2818 AbstractManglingParser *Parser;
2819 decltype(TemplateParams) OldParams;
2820 decltype(OuterTemplateParams) OldOuterParams;
2821
2822 public:
2823 SaveTemplateParams(AbstractManglingParser *TheParser) : Parser(TheParser) {
2824 OldParams = std::move(Parser->TemplateParams);
2825 OldOuterParams = std::move(Parser->OuterTemplateParams);
2826 Parser->TemplateParams.clear();
2827 Parser->OuterTemplateParams.clear();
2828 }
2829 ~SaveTemplateParams() {
2830 Parser->TemplateParams = std::move(OldParams);
2831 Parser->OuterTemplateParams = std::move(OldOuterParams);
2832 }
2833 };
2834
2835 // Set of unresolved forward <template-param> references. These can occur in a
2836 // conversion operator's type, and are resolved in the enclosing <encoding>.
2837 PODSmallVector<ForwardTemplateReference *, 4> ForwardTemplateRefs;
2838
2839 bool TryToParseTemplateArgs = true;
2840 bool PermitForwardTemplateReferences = false;
2841 bool HasIncompleteTemplateParameterTracking = false;
2842 size_t ParsingLambdaParamsAtLevel = (size_t)-1;
2843
2844 unsigned NumSyntheticTemplateParameters[3] = {};
2845
2846 Alloc ASTAllocator;
2847
2848 AbstractManglingParser(const char *First_, const char *Last_)
2849 : First(First_), Last(Last_) {}
2850
2851 Derived &getDerived() { return static_cast<Derived &>(*this); }
2852
2853 void reset(const char *First_, const char *Last_) {
2854 First = First_;
2855 Last = Last_;
2856 Names.clear();
2857 Subs.clear();
2858 TemplateParams.clear();
2859 ParsingLambdaParamsAtLevel = (size_t)-1;
2860 TryToParseTemplateArgs = true;
2861 PermitForwardTemplateReferences = false;
2862 for (unsigned int & NumSyntheticTemplateParameter : NumSyntheticTemplateParameters)
2863 NumSyntheticTemplateParameter = 0;
2864 ASTAllocator.reset();
2865 }
2866
2867 template <class T, class... Args> Node *make(Args &&... args) {
2868 return ASTAllocator.template makeNode<T>(std::forward<Args>(args)...);
2869 }
2870
2871 template <class It> NodeArray makeNodeArray(It begin, It end) {
2872 size_t sz = static_cast<size_t>(end - begin);
2873 void *mem = ASTAllocator.allocateNodeArray(sz);
2874 Node **data = new (mem) Node *[sz];
2875 std::copy(begin, end, data);
2876 return NodeArray(data, sz);
2877 }
2878
2879 NodeArray popTrailingNodeArray(size_t FromPosition) {
2880 DEMANGLE_ASSERT(FromPosition <= Names.size(), "");
2881 NodeArray res =
2882 makeNodeArray(Names.begin() + (long)FromPosition, Names.end());
2883 Names.shrinkToSize(Index: FromPosition);
2884 return res;
2885 }
2886
2887 bool consumeIf(std::string_view S) {
2888 if (starts_with(haystack: std::string_view(First, Last - First), needle: S)) {
2889 First += S.size();
2890 return true;
2891 }
2892 return false;
2893 }
2894
2895 bool consumeIf(char C) {
2896 if (First != Last && *First == C) {
2897 ++First;
2898 return true;
2899 }
2900 return false;
2901 }
2902
2903 char consume() { return First != Last ? *First++ : '\0'; }
2904
2905 char look(unsigned Lookahead = 0) const {
2906 if (static_cast<size_t>(Last - First) <= Lookahead)
2907 return '\0';
2908 return First[Lookahead];
2909 }
2910
2911 size_t numLeft() const { return static_cast<size_t>(Last - First); }
2912
2913 std::string_view parseNumber(bool AllowNegative = false);
2914 Qualifiers parseCVQualifiers();
2915 bool parsePositiveInteger(size_t *Out);
2916 std::string_view parseBareSourceName();
2917
2918 bool parseSeqId(size_t *Out);
2919 Node *parseSubstitution();
2920 Node *parseTemplateParam();
2921 Node *parseTemplateParamDecl(TemplateParamList *Params);
2922 Node *parseTemplateArgs(bool TagTemplates = false);
2923 Node *parseTemplateArg();
2924
2925 bool isTemplateParamDecl() {
2926 return look() == 'T' &&
2927 std::string_view("yptnk").find(look(Lookahead: 1)) != std::string_view::npos;
2928 }
2929
2930 /// Parse the <expression> production.
2931 Node *parseExpr();
2932 Node *parsePrefixExpr(std::string_view Kind, Node::Prec Prec);
2933 Node *parseBinaryExpr(std::string_view Kind, Node::Prec Prec);
2934 Node *parseIntegerLiteral(std::string_view Lit);
2935 Node *parseExprPrimary();
2936 template <class Float> Node *parseFloatingLiteral();
2937 Node *parseFunctionParam();
2938 Node *parseConversionExpr();
2939 Node *parseBracedExpr();
2940 Node *parseFoldExpr();
2941 Node *parsePointerToMemberConversionExpr(Node::Prec Prec);
2942 Node *parseSubobjectExpr();
2943 Node *parseConstraintExpr();
2944 Node *parseRequiresExpr();
2945
2946 /// Parse the <type> production.
2947 Node *parseType();
2948 Node *parseFunctionType();
2949 Node *parseVectorType();
2950 Node *parseDecltype();
2951 Node *parseArrayType();
2952 Node *parsePointerToMemberType();
2953 Node *parseClassEnumType();
2954 Node *parseQualifiedType();
2955
2956 Node *parseEncoding(bool ParseParams = true);
2957 bool parseCallOffset();
2958 Node *parseSpecialName();
2959
2960 /// Holds some extra information about a <name> that is being parsed. This
2961 /// information is only pertinent if the <name> refers to an <encoding>.
2962 struct NameState {
2963 bool CtorDtorConversion = false;
2964 bool EndsWithTemplateArgs = false;
2965 Qualifiers CVQualifiers = QualNone;
2966 FunctionRefQual ReferenceQualifier = FrefQualNone;
2967 size_t ForwardTemplateRefsBegin;
2968 bool HasExplicitObjectParameter = false;
2969
2970 NameState(AbstractManglingParser *Enclosing)
2971 : ForwardTemplateRefsBegin(Enclosing->ForwardTemplateRefs.size()) {}
2972 };
2973
2974 bool resolveForwardTemplateRefs(NameState &State) {
2975 size_t I = State.ForwardTemplateRefsBegin;
2976 size_t E = ForwardTemplateRefs.size();
2977 for (; I < E; ++I) {
2978 size_t Idx = ForwardTemplateRefs[I]->Index;
2979 if (TemplateParams.empty() || !TemplateParams[0] ||
2980 Idx >= TemplateParams[0]->size())
2981 return true;
2982 ForwardTemplateRefs[I]->Ref = (*TemplateParams[0])[Idx];
2983 }
2984 ForwardTemplateRefs.shrinkToSize(Index: State.ForwardTemplateRefsBegin);
2985 return false;
2986 }
2987
2988 /// Parse the <name> production>
2989 Node *parseName(NameState *State = nullptr);
2990 Node *parseLocalName(NameState *State);
2991 Node *parseOperatorName(NameState *State);
2992 bool parseModuleNameOpt(ModuleName *&Module);
2993 Node *parseUnqualifiedName(NameState *State, Node *Scope, ModuleName *Module);
2994 Node *parseUnnamedTypeName(NameState *State);
2995 Node *parseSourceName(NameState *State);
2996 Node *parseUnscopedName(NameState *State, bool *isSubstName);
2997 Node *parseNestedName(NameState *State);
2998 Node *parseCtorDtorName(Node *&SoFar, NameState *State);
2999
3000 Node *parseAbiTags(Node *N);
3001
3002 struct OperatorInfo {
3003 enum OIKind : unsigned char {
3004 Prefix, // Prefix unary: @ expr
3005 Postfix, // Postfix unary: expr @
3006 Binary, // Binary: lhs @ rhs
3007 Array, // Array index: lhs [ rhs ]
3008 Member, // Member access: lhs @ rhs
3009 New, // New
3010 Del, // Delete
3011 Call, // Function call: expr (expr*)
3012 CCast, // C cast: (type)expr
3013 Conditional, // Conditional: expr ? expr : expr
3014 NameOnly, // Overload only, not allowed in expression.
3015 // Below do not have operator names
3016 NamedCast, // Named cast, @<type>(expr)
3017 OfIdOp, // alignof, sizeof, typeid
3018
3019 Unnameable = NamedCast,
3020 };
3021 char Enc[2]; // Encoding
3022 OIKind Kind; // Kind of operator
3023 bool Flag : 1; // Entry-specific flag
3024 Node::Prec Prec : 7; // Precedence
3025 const char *Name; // Spelling
3026
3027 public:
3028 constexpr OperatorInfo(const char (&E)[3], OIKind K, bool F, Node::Prec P,
3029 const char *N)
3030 : Enc{E[0], E[1]}, Kind{K}, Flag{F}, Prec{P}, Name{N} {}
3031
3032 public:
3033 bool operator<(const OperatorInfo &Other) const {
3034 return *this < Other.Enc;
3035 }
3036 bool operator<(const char *Peek) const {
3037 return Enc[0] < Peek[0] || (Enc[0] == Peek[0] && Enc[1] < Peek[1]);
3038 }
3039 bool operator==(const char *Peek) const {
3040 return Enc[0] == Peek[0] && Enc[1] == Peek[1];
3041 }
3042 bool operator!=(const char *Peek) const { return !this->operator==(Peek); }
3043
3044 public:
3045 std::string_view getSymbol() const {
3046 std::string_view Res = Name;
3047 if (Kind < Unnameable) {
3048 DEMANGLE_ASSERT(starts_with(Res, "operator"),
3049 "operator name does not start with 'operator'");
3050 Res.remove_prefix(n: sizeof("operator") - 1);
3051 if (starts_with(self: Res, C: ' '))
3052 Res.remove_prefix(n: 1);
3053 }
3054 return Res;
3055 }
3056 std::string_view getName() const { return Name; }
3057 OIKind getKind() const { return Kind; }
3058 bool getFlag() const { return Flag; }
3059 Node::Prec getPrecedence() const { return Prec; }
3060 };
3061 static const OperatorInfo Ops[];
3062 static const size_t NumOps;
3063 const OperatorInfo *parseOperatorEncoding();
3064
3065 /// Parse the <unresolved-name> production.
3066 Node *parseUnresolvedName(bool Global);
3067 Node *parseSimpleId();
3068 Node *parseBaseUnresolvedName();
3069 Node *parseUnresolvedType();
3070 Node *parseDestructorName();
3071
3072 /// Top-level entry point into the parser.
3073 Node *parse(bool ParseParams = true);
3074};
3075
3076DEMANGLE_ABI const char *parse_discriminator(const char *first,
3077 const char *last);
3078
3079// <name> ::= <nested-name> // N
3080// ::= <local-name> # See Scope Encoding below // Z
3081// ::= <unscoped-template-name> <template-args>
3082// ::= <unscoped-name>
3083//
3084// <unscoped-template-name> ::= <unscoped-name>
3085// ::= <substitution>
3086template <typename Derived, typename Alloc>
3087Node *AbstractManglingParser<Derived, Alloc>::parseName(NameState *State) {
3088 if (look() == 'N')
3089 return getDerived().parseNestedName(State);
3090 if (look() == 'Z')
3091 return getDerived().parseLocalName(State);
3092
3093 Node *Result = nullptr;
3094 bool IsSubst = false;
3095
3096 Result = getDerived().parseUnscopedName(State, &IsSubst);
3097 if (!Result)
3098 return nullptr;
3099
3100 if (look() == 'I') {
3101 // ::= <unscoped-template-name> <template-args>
3102 if (!IsSubst)
3103 // An unscoped-template-name is substitutable.
3104 Subs.push_back(Elem: Result);
3105 Node *TA = getDerived().parseTemplateArgs(State != nullptr);
3106 if (TA == nullptr)
3107 return nullptr;
3108 if (State)
3109 State->EndsWithTemplateArgs = true;
3110 Result = make<NameWithTemplateArgs>(Result, TA);
3111 } else if (IsSubst) {
3112 // The substitution case must be followed by <template-args>.
3113 return nullptr;
3114 }
3115
3116 return Result;
3117}
3118
3119// <local-name> := Z <function encoding> E <entity name> [<discriminator>]
3120// := Z <function encoding> E s [<discriminator>]
3121// := Z <function encoding> Ed [ <parameter number> ] _ <entity name>
3122template <typename Derived, typename Alloc>
3123Node *AbstractManglingParser<Derived, Alloc>::parseLocalName(NameState *State) {
3124 if (!consumeIf('Z'))
3125 return nullptr;
3126 Node *Encoding = getDerived().parseEncoding();
3127 if (Encoding == nullptr || !consumeIf('E'))
3128 return nullptr;
3129
3130 if (consumeIf('s')) {
3131 First = parse_discriminator(first: First, last: Last);
3132 auto *StringLitName = make<NameType>("string literal");
3133 if (!StringLitName)
3134 return nullptr;
3135 return make<LocalName>(Encoding, StringLitName);
3136 }
3137
3138 // The template parameters of the inner name are unrelated to those of the
3139 // enclosing context.
3140 SaveTemplateParams SaveTemplateParamsScope(this);
3141
3142 if (consumeIf('d')) {
3143 parseNumber(AllowNegative: true);
3144 if (!consumeIf('_'))
3145 return nullptr;
3146 Node *N = getDerived().parseName(State);
3147 if (N == nullptr)
3148 return nullptr;
3149 return make<LocalName>(Encoding, N);
3150 }
3151
3152 Node *Entity = getDerived().parseName(State);
3153 if (Entity == nullptr)
3154 return nullptr;
3155 First = parse_discriminator(first: First, last: Last);
3156 return make<LocalName>(Encoding, Entity);
3157}
3158
3159// <unscoped-name> ::= <unqualified-name>
3160// ::= St <unqualified-name> # ::std::
3161// [*] extension
3162template <typename Derived, typename Alloc>
3163Node *
3164AbstractManglingParser<Derived, Alloc>::parseUnscopedName(NameState *State,
3165 bool *IsSubst) {
3166
3167 Node *Std = nullptr;
3168 if (consumeIf("St")) {
3169 Std = make<NameType>("std");
3170 if (Std == nullptr)
3171 return nullptr;
3172 }
3173
3174 Node *Res = nullptr;
3175 ModuleName *Module = nullptr;
3176 if (look() == 'S') {
3177 Node *S = getDerived().parseSubstitution();
3178 if (!S)
3179 return nullptr;
3180 if (S->getKind() == Node::KModuleName)
3181 Module = static_cast<ModuleName *>(S);
3182 else if (IsSubst && Std == nullptr) {
3183 Res = S;
3184 *IsSubst = true;
3185 } else {
3186 return nullptr;
3187 }
3188 }
3189
3190 if (Res == nullptr || Std != nullptr) {
3191 Res = getDerived().parseUnqualifiedName(State, Std, Module);
3192 }
3193
3194 return Res;
3195}
3196
3197// <unqualified-name> ::= [<module-name>] F? L? <operator-name> [<abi-tags>]
3198// ::= [<module-name>] <ctor-dtor-name> [<abi-tags>]
3199// ::= [<module-name>] F? L? <source-name> [<abi-tags>]
3200// ::= [<module-name>] L? <unnamed-type-name> [<abi-tags>]
3201// # structured binding declaration
3202// ::= [<module-name>] L? DC <source-name>+ E
3203template <typename Derived, typename Alloc>
3204Node *AbstractManglingParser<Derived, Alloc>::parseUnqualifiedName(
3205 NameState *State, Node *Scope, ModuleName *Module) {
3206 if (getDerived().parseModuleNameOpt(Module))
3207 return nullptr;
3208
3209 bool IsMemberLikeFriend = Scope && consumeIf('F');
3210
3211 consumeIf('L');
3212
3213 Node *Result;
3214 if (look() >= '1' && look() <= '9') {
3215 Result = getDerived().parseSourceName(State);
3216 } else if (look() == 'U') {
3217 Result = getDerived().parseUnnamedTypeName(State);
3218 } else if (consumeIf("DC")) {
3219 // Structured binding
3220 size_t BindingsBegin = Names.size();
3221 do {
3222 Node *Binding = getDerived().parseSourceName(State);
3223 if (Binding == nullptr)
3224 return nullptr;
3225 Names.push_back(Elem: Binding);
3226 } while (!consumeIf('E'));
3227 Result = make<StructuredBindingName>(popTrailingNodeArray(FromPosition: BindingsBegin));
3228 } else if (look() == 'C' || look() == 'D') {
3229 // A <ctor-dtor-name>.
3230 if (Scope == nullptr || Module != nullptr)
3231 return nullptr;
3232 Result = getDerived().parseCtorDtorName(Scope, State);
3233 } else {
3234 Result = getDerived().parseOperatorName(State);
3235 }
3236
3237 if (Result != nullptr && Module != nullptr)
3238 Result = make<ModuleEntity>(Module, Result);
3239 if (Result != nullptr)
3240 Result = getDerived().parseAbiTags(Result);
3241 if (Result != nullptr && IsMemberLikeFriend)
3242 Result = make<MemberLikeFriendName>(Scope, Result);
3243 else if (Result != nullptr && Scope != nullptr)
3244 Result = make<NestedName>(Scope, Result);
3245
3246 return Result;
3247}
3248
3249// <module-name> ::= <module-subname>
3250// ::= <module-name> <module-subname>
3251// ::= <substitution> # passed in by caller
3252// <module-subname> ::= W <source-name>
3253// ::= W P <source-name>
3254template <typename Derived, typename Alloc>
3255bool AbstractManglingParser<Derived, Alloc>::parseModuleNameOpt(
3256 ModuleName *&Module) {
3257 while (consumeIf('W')) {
3258 bool IsPartition = consumeIf('P');
3259 Node *Sub = getDerived().parseSourceName(nullptr);
3260 if (!Sub)
3261 return true;
3262 Module =
3263 static_cast<ModuleName *>(make<ModuleName>(Module, Sub, IsPartition));
3264 Subs.push_back(Elem: Module);
3265 }
3266
3267 return false;
3268}
3269
3270// <unnamed-type-name> ::= Ut [<nonnegative number>] _
3271// ::= <closure-type-name>
3272//
3273// <closure-type-name> ::= Ul <lambda-sig> E [ <nonnegative number> ] _
3274//
3275// <lambda-sig> ::= <template-param-decl>* [Q <requires-clause expression>]
3276// <parameter type>+ # or "v" if the lambda has no parameters
3277template <typename Derived, typename Alloc>
3278Node *
3279AbstractManglingParser<Derived, Alloc>::parseUnnamedTypeName(NameState *State) {
3280 // <template-params> refer to the innermost <template-args>. Clear out any
3281 // outer args that we may have inserted into TemplateParams.
3282 if (State != nullptr)
3283 TemplateParams.clear();
3284
3285 if (consumeIf("Ut")) {
3286 std::string_view Count = parseNumber();
3287 if (!consumeIf('_'))
3288 return nullptr;
3289 return make<UnnamedTypeName>(Count);
3290 }
3291 if (consumeIf("Ul")) {
3292 ScopedOverride<size_t> SwapParams(ParsingLambdaParamsAtLevel,
3293 TemplateParams.size());
3294 ScopedTemplateParamList LambdaTemplateParams(this);
3295
3296 size_t ParamsBegin = Names.size();
3297 while (getDerived().isTemplateParamDecl()) {
3298 Node *T =
3299 getDerived().parseTemplateParamDecl(LambdaTemplateParams.params());
3300 if (T == nullptr)
3301 return nullptr;
3302 Names.push_back(Elem: T);
3303 }
3304 NodeArray TempParams = popTrailingNodeArray(FromPosition: ParamsBegin);
3305
3306 // FIXME: If TempParams is empty and none of the function parameters
3307 // includes 'auto', we should remove LambdaTemplateParams from the
3308 // TemplateParams list. Unfortunately, we don't find out whether there are
3309 // any 'auto' parameters until too late in an example such as:
3310 //
3311 // template<typename T> void f(
3312 // decltype([](decltype([]<typename T>(T v) {}),
3313 // auto) {})) {}
3314 // template<typename T> void f(
3315 // decltype([](decltype([]<typename T>(T w) {}),
3316 // int) {})) {}
3317 //
3318 // Here, the type of v is at level 2 but the type of w is at level 1. We
3319 // don't find this out until we encounter the type of the next parameter.
3320 //
3321 // However, compilers can't actually cope with the former example in
3322 // practice, and it's likely to be made ill-formed in future, so we don't
3323 // need to support it here.
3324 //
3325 // If we encounter an 'auto' in the function parameter types, we will
3326 // recreate a template parameter scope for it, but any intervening lambdas
3327 // will be parsed in the 'wrong' template parameter depth.
3328 if (TempParams.empty())
3329 TemplateParams.pop_back();
3330
3331 Node *Requires1 = nullptr;
3332 if (consumeIf('Q')) {
3333 Requires1 = getDerived().parseConstraintExpr();
3334 if (Requires1 == nullptr)
3335 return nullptr;
3336 }
3337
3338 if (!consumeIf("v")) {
3339 do {
3340 Node *P = getDerived().parseType();
3341 if (P == nullptr)
3342 return nullptr;
3343 Names.push_back(Elem: P);
3344 } while (look() != 'E' && look() != 'Q');
3345 }
3346 NodeArray Params = popTrailingNodeArray(FromPosition: ParamsBegin);
3347
3348 Node *Requires2 = nullptr;
3349 if (consumeIf('Q')) {
3350 Requires2 = getDerived().parseConstraintExpr();
3351 if (Requires2 == nullptr)
3352 return nullptr;
3353 }
3354
3355 if (!consumeIf('E'))
3356 return nullptr;
3357
3358 std::string_view Count = parseNumber();
3359 if (!consumeIf('_'))
3360 return nullptr;
3361 return make<ClosureTypeName>(TempParams, Requires1, Params, Requires2,
3362 Count);
3363 }
3364 if (consumeIf("Ub")) {
3365 (void)parseNumber();
3366 if (!consumeIf('_'))
3367 return nullptr;
3368 return make<NameType>("'block-literal'");
3369 }
3370 return nullptr;
3371}
3372
3373// <source-name> ::= <positive length number> <identifier>
3374template <typename Derived, typename Alloc>
3375Node *AbstractManglingParser<Derived, Alloc>::parseSourceName(NameState *) {
3376 size_t Length = 0;
3377 if (parsePositiveInteger(Out: &Length))
3378 return nullptr;
3379 if (numLeft() < Length || Length == 0)
3380 return nullptr;
3381 std::string_view Name(First, Length);
3382 First += Length;
3383 if (starts_with(haystack: Name, needle: "_GLOBAL__N"))
3384 return make<NameType>("(anonymous namespace)");
3385 return make<NameType>(Name);
3386}
3387
3388// Operator encodings
3389template <typename Derived, typename Alloc>
3390const typename AbstractManglingParser<
3391 Derived, Alloc>::OperatorInfo AbstractManglingParser<Derived,
3392 Alloc>::Ops[] = {
3393 // Keep ordered by encoding
3394 {"aN", OperatorInfo::Binary, false, Node::Prec::Assign, "operator&="},
3395 {"aS", OperatorInfo::Binary, false, Node::Prec::Assign, "operator="},
3396 {"aa", OperatorInfo::Binary, false, Node::Prec::AndIf, "operator&&"},
3397 {"ad", OperatorInfo::Prefix, false, Node::Prec::Unary, "operator&"},
3398 {"an", OperatorInfo::Binary, false, Node::Prec::And, "operator&"},
3399 {"at", OperatorInfo::OfIdOp, /*Type*/ true, Node::Prec::Unary, "alignof "},
3400 {"aw", OperatorInfo::NameOnly, false, Node::Prec::Primary,
3401 "operator co_await"},
3402 {"az", OperatorInfo::OfIdOp, /*Type*/ false, Node::Prec::Unary, "alignof "},
3403 {"cc", OperatorInfo::NamedCast, false, Node::Prec::Postfix, "const_cast"},
3404 {"cl", OperatorInfo::Call, /*Paren*/ false, Node::Prec::Postfix,
3405 "operator()"},
3406 {"cm", OperatorInfo::Binary, false, Node::Prec::Comma, "operator,"},
3407 {"co", OperatorInfo::Prefix, false, Node::Prec::Unary, "operator~"},
3408 {"cp", OperatorInfo::Call, /*Paren*/ true, Node::Prec::Postfix,
3409 "operator()"},
3410 {"cv", OperatorInfo::CCast, false, Node::Prec::Cast, "operator"}, // C Cast
3411 {"dV", OperatorInfo::Binary, false, Node::Prec::Assign, "operator/="},
3412 {"da", OperatorInfo::Del, /*Ary*/ true, Node::Prec::Unary,
3413 "operator delete[]"},
3414 {"dc", OperatorInfo::NamedCast, false, Node::Prec::Postfix, "dynamic_cast"},
3415 {"de", OperatorInfo::Prefix, false, Node::Prec::Unary, "operator*"},
3416 {"dl", OperatorInfo::Del, /*Ary*/ false, Node::Prec::Unary,
3417 "operator delete"},
3418 {"ds", OperatorInfo::Member, /*Named*/ false, Node::Prec::PtrMem,
3419 "operator.*"},
3420 {"dt", OperatorInfo::Member, /*Named*/ false, Node::Prec::Postfix,
3421 "operator."},
3422 {"dv", OperatorInfo::Binary, false, Node::Prec::Assign, "operator/"},
3423 {"eO", OperatorInfo::Binary, false, Node::Prec::Assign, "operator^="},
3424 {"eo", OperatorInfo::Binary, false, Node::Prec::Xor, "operator^"},
3425 {"eq", OperatorInfo::Binary, false, Node::Prec::Equality, "operator=="},
3426 {"ge", OperatorInfo::Binary, false, Node::Prec::Relational, "operator>="},
3427 {"gt", OperatorInfo::Binary, false, Node::Prec::Relational, "operator>"},
3428 {"ix", OperatorInfo::Array, false, Node::Prec::Postfix, "operator[]"},
3429 {"lS", OperatorInfo::Binary, false, Node::Prec::Assign, "operator<<="},
3430 {"le", OperatorInfo::Binary, false, Node::Prec::Relational, "operator<="},
3431 {"ls", OperatorInfo::Binary, false, Node::Prec::Shift, "operator<<"},
3432 {"lt", OperatorInfo::Binary, false, Node::Prec::Relational, "operator<"},
3433 {"mI", OperatorInfo::Binary, false, Node::Prec::Assign, "operator-="},
3434 {"mL", OperatorInfo::Binary, false, Node::Prec::Assign, "operator*="},
3435 {"mi", OperatorInfo::Binary, false, Node::Prec::Additive, "operator-"},
3436 {"ml", OperatorInfo::Binary, false, Node::Prec::Multiplicative,
3437 "operator*"},
3438 {"mm", OperatorInfo::Postfix, false, Node::Prec::Postfix, "operator--"},
3439 {"na", OperatorInfo::New, /*Ary*/ true, Node::Prec::Unary,
3440 "operator new[]"},
3441 {"ne", OperatorInfo::Binary, false, Node::Prec::Equality, "operator!="},
3442 {"ng", OperatorInfo::Prefix, false, Node::Prec::Unary, "operator-"},
3443 {"nt", OperatorInfo::Prefix, false, Node::Prec::Unary, "operator!"},
3444 {"nw", OperatorInfo::New, /*Ary*/ false, Node::Prec::Unary, "operator new"},
3445 {"oR", OperatorInfo::Binary, false, Node::Prec::Assign, "operator|="},
3446 {"oo", OperatorInfo::Binary, false, Node::Prec::OrIf, "operator||"},
3447 {"or", OperatorInfo::Binary, false, Node::Prec::Ior, "operator|"},
3448 {"pL", OperatorInfo::Binary, false, Node::Prec::Assign, "operator+="},
3449 {"pl", OperatorInfo::Binary, false, Node::Prec::Additive, "operator+"},
3450 {"pm", OperatorInfo::Member, /*Named*/ true, Node::Prec::PtrMem,
3451 "operator->*"},
3452 {"pp", OperatorInfo::Postfix, false, Node::Prec::Postfix, "operator++"},
3453 {"ps", OperatorInfo::Prefix, false, Node::Prec::Unary, "operator+"},
3454 {"pt", OperatorInfo::Member, /*Named*/ true, Node::Prec::Postfix,
3455 "operator->"},
3456 {"qu", OperatorInfo::Conditional, false, Node::Prec::Conditional,
3457 "operator?"},
3458 {"rM", OperatorInfo::Binary, false, Node::Prec::Assign, "operator%="},
3459 {"rS", OperatorInfo::Binary, false, Node::Prec::Assign, "operator>>="},
3460 {"rc", OperatorInfo::NamedCast, false, Node::Prec::Postfix,
3461 "reinterpret_cast"},
3462 {"rm", OperatorInfo::Binary, false, Node::Prec::Multiplicative,
3463 "operator%"},
3464 {"rs", OperatorInfo::Binary, false, Node::Prec::Shift, "operator>>"},
3465 {"sc", OperatorInfo::NamedCast, false, Node::Prec::Postfix, "static_cast"},
3466 {"ss", OperatorInfo::Binary, false, Node::Prec::Spaceship, "operator<=>"},
3467 {"st", OperatorInfo::OfIdOp, /*Type*/ true, Node::Prec::Unary, "sizeof "},
3468 {"sz", OperatorInfo::OfIdOp, /*Type*/ false, Node::Prec::Unary, "sizeof "},
3469 {"te", OperatorInfo::OfIdOp, /*Type*/ false, Node::Prec::Postfix,
3470 "typeid "},
3471 {"ti", OperatorInfo::OfIdOp, /*Type*/ true, Node::Prec::Postfix, "typeid "},
3472};
3473template <typename Derived, typename Alloc>
3474const size_t AbstractManglingParser<Derived, Alloc>::NumOps = sizeof(Ops) /
3475 sizeof(Ops[0]);
3476
3477// If the next 2 chars are an operator encoding, consume them and return their
3478// OperatorInfo. Otherwise return nullptr.
3479template <typename Derived, typename Alloc>
3480const typename AbstractManglingParser<Derived, Alloc>::OperatorInfo *
3481AbstractManglingParser<Derived, Alloc>::parseOperatorEncoding() {
3482 if (numLeft() < 2)
3483 return nullptr;
3484
3485 // We can't use lower_bound as that can link to symbols in the C++ library,
3486 // and this must remain independent of that.
3487 size_t lower = 0u, upper = NumOps - 1; // Inclusive bounds.
3488 while (upper != lower) {
3489 size_t middle = (upper + lower) / 2;
3490 if (Ops[middle] < First)
3491 lower = middle + 1;
3492 else
3493 upper = middle;
3494 }
3495 if (Ops[lower] != First)
3496 return nullptr;
3497
3498 First += 2;
3499 return &Ops[lower];
3500}
3501
3502// <operator-name> ::= See parseOperatorEncoding()
3503// ::= li <source-name> # operator ""
3504// ::= v <digit> <source-name> # vendor extended operator
3505template <typename Derived, typename Alloc>
3506Node *
3507AbstractManglingParser<Derived, Alloc>::parseOperatorName(NameState *State) {
3508 if (const auto *Op = parseOperatorEncoding()) {
3509 if (Op->getKind() == OperatorInfo::CCast) {
3510 // ::= cv <type> # (cast)
3511 ScopedOverride<bool> SaveTemplate(TryToParseTemplateArgs, false);
3512 // If we're parsing an encoding, State != nullptr and the conversion
3513 // operators' <type> could have a <template-param> that refers to some
3514 // <template-arg>s further ahead in the mangled name.
3515 ScopedOverride<bool> SavePermit(PermitForwardTemplateReferences,
3516 PermitForwardTemplateReferences ||
3517 State != nullptr);
3518 Node *Ty = getDerived().parseType();
3519 if (Ty == nullptr)
3520 return nullptr;
3521 if (State) State->CtorDtorConversion = true;
3522 return make<ConversionOperatorType>(Ty);
3523 }
3524
3525 if (Op->getKind() >= OperatorInfo::Unnameable)
3526 /* Not a nameable operator. */
3527 return nullptr;
3528 if (Op->getKind() == OperatorInfo::Member && !Op->getFlag())
3529 /* Not a nameable MemberExpr */
3530 return nullptr;
3531
3532 return make<NameType>(Op->getName());
3533 }
3534
3535 if (consumeIf("li")) {
3536 // ::= li <source-name> # operator ""
3537 Node *SN = getDerived().parseSourceName(State);
3538 if (SN == nullptr)
3539 return nullptr;
3540 return make<LiteralOperator>(SN);
3541 }
3542
3543 if (consumeIf('v')) {
3544 // ::= v <digit> <source-name> # vendor extended operator
3545 if (look() >= '0' && look() <= '9') {
3546 First++;
3547 Node *SN = getDerived().parseSourceName(State);
3548 if (SN == nullptr)
3549 return nullptr;
3550 return make<ConversionOperatorType>(SN);
3551 }
3552 return nullptr;
3553 }
3554
3555 return nullptr;
3556}
3557
3558// <ctor-dtor-name> ::= C1 # complete object constructor
3559// ::= C2 # base object constructor
3560// ::= C3 # complete object allocating constructor
3561// extension ::= C4 # gcc old-style "[unified]" constructor
3562// extension ::= C5 # the COMDAT used for ctors
3563// ::= D0 # deleting destructor
3564// ::= D1 # complete object destructor
3565// ::= D2 # base object destructor
3566// extension ::= D4 # gcc old-style "[unified]" destructor
3567// extension ::= D5 # the COMDAT used for dtors
3568template <typename Derived, typename Alloc>
3569Node *
3570AbstractManglingParser<Derived, Alloc>::parseCtorDtorName(Node *&SoFar,
3571 NameState *State) {
3572 if (SoFar->getKind() == Node::KSpecialSubstitution) {
3573 // Expand the special substitution.
3574 SoFar = make<ExpandedSpecialSubstitution>(
3575 static_cast<SpecialSubstitution *>(SoFar));
3576 if (!SoFar)
3577 return nullptr;
3578 }
3579
3580 if (consumeIf('C')) {
3581 bool IsInherited = consumeIf('I');
3582 if (look() != '1' && look() != '2' && look() != '3' && look() != '4' &&
3583 look() != '5')
3584 return nullptr;
3585 int Variant = look() - '0';
3586 ++First;
3587 if (State) State->CtorDtorConversion = true;
3588 if (IsInherited) {
3589 if (getDerived().parseName(State) == nullptr)
3590 return nullptr;
3591 }
3592 return make<CtorDtorName>(SoFar, /*IsDtor=*/false, Variant);
3593 }
3594
3595 if (look() == 'D' && (look(Lookahead: 1) == '0' || look(Lookahead: 1) == '1' || look(Lookahead: 1) == '2' ||
3596 look(Lookahead: 1) == '4' || look(Lookahead: 1) == '5')) {
3597 int Variant = look(Lookahead: 1) - '0';
3598 First += 2;
3599 if (State) State->CtorDtorConversion = true;
3600 return make<CtorDtorName>(SoFar, /*IsDtor=*/true, Variant);
3601 }
3602
3603 return nullptr;
3604}
3605
3606// <nested-name> ::= N [<CV-Qualifiers>] [<ref-qualifier>] <prefix>
3607// <unqualified-name> E
3608// ::= N [<CV-Qualifiers>] [<ref-qualifier>] <template-prefix>
3609// <template-args> E
3610//
3611// <prefix> ::= <prefix> <unqualified-name>
3612// ::= <template-prefix> <template-args>
3613// ::= <template-param>
3614// ::= <decltype>
3615// ::= # empty
3616// ::= <substitution>
3617// ::= <prefix> <data-member-prefix>
3618// [*] extension
3619//
3620// <data-member-prefix> := <member source-name> [<template-args>] M
3621//
3622// <template-prefix> ::= <prefix> <template unqualified-name>
3623// ::= <template-param>
3624// ::= <substitution>
3625template <typename Derived, typename Alloc>
3626Node *
3627AbstractManglingParser<Derived, Alloc>::parseNestedName(NameState *State) {
3628 if (!consumeIf('N'))
3629 return nullptr;
3630
3631 // 'H' specifies that the encoding that follows
3632 // has an explicit object parameter.
3633 if (!consumeIf('H')) {
3634 Qualifiers CVTmp = parseCVQualifiers();
3635 if (State)
3636 State->CVQualifiers = CVTmp;
3637
3638 if (consumeIf('O')) {
3639 if (State)
3640 State->ReferenceQualifier = FrefQualRValue;
3641 } else if (consumeIf('R')) {
3642 if (State)
3643 State->ReferenceQualifier = FrefQualLValue;
3644 } else {
3645 if (State)
3646 State->ReferenceQualifier = FrefQualNone;
3647 }
3648 } else if (State) {
3649 State->HasExplicitObjectParameter = true;
3650 }
3651
3652 Node *SoFar = nullptr;
3653 while (!consumeIf('E')) {
3654 if (State)
3655 // Only set end-with-template on the case that does that.
3656 State->EndsWithTemplateArgs = false;
3657
3658 if (look() == 'T') {
3659 // ::= <template-param>
3660 if (SoFar != nullptr)
3661 return nullptr; // Cannot have a prefix.
3662 SoFar = getDerived().parseTemplateParam();
3663 } else if (look() == 'I') {
3664 // ::= <template-prefix> <template-args>
3665 if (SoFar == nullptr)
3666 return nullptr; // Must have a prefix.
3667 Node *TA = getDerived().parseTemplateArgs(State != nullptr);
3668 if (TA == nullptr)
3669 return nullptr;
3670 if (SoFar->getKind() == Node::KNameWithTemplateArgs)
3671 // Semantically <template-args> <template-args> cannot be generated by a
3672 // C++ entity. There will always be [something like] a name between
3673 // them.
3674 return nullptr;
3675 if (State)
3676 State->EndsWithTemplateArgs = true;
3677 SoFar = make<NameWithTemplateArgs>(SoFar, TA);
3678 } else if (look() == 'D' && (look(Lookahead: 1) == 't' || look(Lookahead: 1) == 'T')) {
3679 // ::= <decltype>
3680 if (SoFar != nullptr)
3681 return nullptr; // Cannot have a prefix.
3682 SoFar = getDerived().parseDecltype();
3683 } else {
3684 ModuleName *Module = nullptr;
3685
3686 if (look() == 'S') {
3687 // ::= <substitution>
3688 Node *S = nullptr;
3689 if (look(Lookahead: 1) == 't') {
3690 First += 2;
3691 S = make<NameType>("std");
3692 } else {
3693 S = getDerived().parseSubstitution();
3694 }
3695 if (!S)
3696 return nullptr;
3697 if (S->getKind() == Node::KModuleName) {
3698 Module = static_cast<ModuleName *>(S);
3699 } else if (SoFar != nullptr) {
3700 return nullptr; // Cannot have a prefix.
3701 } else {
3702 SoFar = S;
3703 continue; // Do not push a new substitution.
3704 }
3705 }
3706
3707 // ::= [<prefix>] <unqualified-name>
3708 SoFar = getDerived().parseUnqualifiedName(State, SoFar, Module);
3709 }
3710
3711 if (SoFar == nullptr)
3712 return nullptr;
3713 Subs.push_back(Elem: SoFar);
3714
3715 // No longer used.
3716 // <data-member-prefix> := <member source-name> [<template-args>] M
3717 consumeIf('M');
3718 }
3719
3720 if (SoFar == nullptr || Subs.empty())
3721 return nullptr;
3722
3723 Subs.pop_back();
3724 return SoFar;
3725}
3726
3727// <simple-id> ::= <source-name> [ <template-args> ]
3728template <typename Derived, typename Alloc>
3729Node *AbstractManglingParser<Derived, Alloc>::parseSimpleId() {
3730 Node *SN = getDerived().parseSourceName(/*NameState=*/nullptr);
3731 if (SN == nullptr)
3732 return nullptr;
3733 if (look() == 'I') {
3734 Node *TA = getDerived().parseTemplateArgs();
3735 if (TA == nullptr)
3736 return nullptr;
3737 return make<NameWithTemplateArgs>(SN, TA);
3738 }
3739 return SN;
3740}
3741
3742// <destructor-name> ::= <unresolved-type> # e.g., ~T or ~decltype(f())
3743// ::= <simple-id> # e.g., ~A<2*N>
3744template <typename Derived, typename Alloc>
3745Node *AbstractManglingParser<Derived, Alloc>::parseDestructorName() {
3746 Node *Result;
3747 if (std::isdigit(c: look()))
3748 Result = getDerived().parseSimpleId();
3749 else
3750 Result = getDerived().parseUnresolvedType();
3751 if (Result == nullptr)
3752 return nullptr;
3753 return make<DtorName>(Result);
3754}
3755
3756// <unresolved-type> ::= <template-param>
3757// ::= <decltype>
3758// ::= <substitution>
3759template <typename Derived, typename Alloc>
3760Node *AbstractManglingParser<Derived, Alloc>::parseUnresolvedType() {
3761 if (look() == 'T') {
3762 Node *TP = getDerived().parseTemplateParam();
3763 if (TP == nullptr)
3764 return nullptr;
3765 Subs.push_back(Elem: TP);
3766 return TP;
3767 }
3768 if (look() == 'D') {
3769 Node *DT = getDerived().parseDecltype();
3770 if (DT == nullptr)
3771 return nullptr;
3772 Subs.push_back(Elem: DT);
3773 return DT;
3774 }
3775 return getDerived().parseSubstitution();
3776}
3777
3778// <base-unresolved-name> ::= <simple-id> # unresolved name
3779// extension ::= <operator-name> # unresolved operator-function-id
3780// extension ::= <operator-name> <template-args> # unresolved operator template-id
3781// ::= on <operator-name> # unresolved operator-function-id
3782// ::= on <operator-name> <template-args> # unresolved operator template-id
3783// ::= dn <destructor-name> # destructor or pseudo-destructor;
3784// # e.g. ~X or ~X<N-1>
3785template <typename Derived, typename Alloc>
3786Node *AbstractManglingParser<Derived, Alloc>::parseBaseUnresolvedName() {
3787 if (std::isdigit(c: look()))
3788 return getDerived().parseSimpleId();
3789
3790 if (consumeIf("dn"))
3791 return getDerived().parseDestructorName();
3792
3793 consumeIf("on");
3794
3795 Node *Oper = getDerived().parseOperatorName(/*NameState=*/nullptr);
3796 if (Oper == nullptr)
3797 return nullptr;
3798 if (look() == 'I') {
3799 Node *TA = getDerived().parseTemplateArgs();
3800 if (TA == nullptr)
3801 return nullptr;
3802 return make<NameWithTemplateArgs>(Oper, TA);
3803 }
3804 return Oper;
3805}
3806
3807// <unresolved-name>
3808// extension ::= srN <unresolved-type> [<template-args>] <unresolved-qualifier-level>* E <base-unresolved-name>
3809// ::= [gs] <base-unresolved-name> # x or (with "gs") ::x
3810// ::= [gs] sr <unresolved-qualifier-level>+ E <base-unresolved-name>
3811// # A::x, N::y, A<T>::z; "gs" means leading "::"
3812// [gs] has been parsed by caller.
3813// ::= sr <unresolved-type> <base-unresolved-name> # T::x / decltype(p)::x
3814// extension ::= sr <unresolved-type> <template-args> <base-unresolved-name>
3815// # T::N::x /decltype(p)::N::x
3816// (ignored) ::= srN <unresolved-type> <unresolved-qualifier-level>+ E <base-unresolved-name>
3817//
3818// <unresolved-qualifier-level> ::= <simple-id>
3819template <typename Derived, typename Alloc>
3820Node *AbstractManglingParser<Derived, Alloc>::parseUnresolvedName(bool Global) {
3821 Node *SoFar = nullptr;
3822
3823 // srN <unresolved-type> [<template-args>] <unresolved-qualifier-level>* E <base-unresolved-name>
3824 // srN <unresolved-type> <unresolved-qualifier-level>+ E <base-unresolved-name>
3825 if (consumeIf("srN")) {
3826 SoFar = getDerived().parseUnresolvedType();
3827 if (SoFar == nullptr)
3828 return nullptr;
3829
3830 if (look() == 'I') {
3831 Node *TA = getDerived().parseTemplateArgs();
3832 if (TA == nullptr)
3833 return nullptr;
3834 SoFar = make<NameWithTemplateArgs>(SoFar, TA);
3835 if (!SoFar)
3836 return nullptr;
3837 }
3838
3839 while (!consumeIf('E')) {
3840 Node *Qual = getDerived().parseSimpleId();
3841 if (Qual == nullptr)
3842 return nullptr;
3843 SoFar = make<QualifiedName>(SoFar, Qual);
3844 if (!SoFar)
3845 return nullptr;
3846 }
3847
3848 Node *Base = getDerived().parseBaseUnresolvedName();
3849 if (Base == nullptr)
3850 return nullptr;
3851 return make<QualifiedName>(SoFar, Base);
3852 }
3853
3854 // [gs] <base-unresolved-name> # x or (with "gs") ::x
3855 if (!consumeIf("sr")) {
3856 SoFar = getDerived().parseBaseUnresolvedName();
3857 if (SoFar == nullptr)
3858 return nullptr;
3859 if (Global)
3860 SoFar = make<GlobalQualifiedName>(SoFar);
3861 return SoFar;
3862 }
3863
3864 // [gs] sr <unresolved-qualifier-level>+ E <base-unresolved-name>
3865 if (std::isdigit(c: look())) {
3866 do {
3867 Node *Qual = getDerived().parseSimpleId();
3868 if (Qual == nullptr)
3869 return nullptr;
3870 if (SoFar)
3871 SoFar = make<QualifiedName>(SoFar, Qual);
3872 else if (Global)
3873 SoFar = make<GlobalQualifiedName>(Qual);
3874 else
3875 SoFar = Qual;
3876 if (!SoFar)
3877 return nullptr;
3878 } while (!consumeIf('E'));
3879 }
3880 // sr <unresolved-type> <base-unresolved-name>
3881 // sr <unresolved-type> <template-args> <base-unresolved-name>
3882 else {
3883 SoFar = getDerived().parseUnresolvedType();
3884 if (SoFar == nullptr)
3885 return nullptr;
3886
3887 if (look() == 'I') {
3888 Node *TA = getDerived().parseTemplateArgs();
3889 if (TA == nullptr)
3890 return nullptr;
3891 SoFar = make<NameWithTemplateArgs>(SoFar, TA);
3892 if (!SoFar)
3893 return nullptr;
3894 }
3895 }
3896
3897 DEMANGLE_ASSERT(SoFar != nullptr, "");
3898
3899 Node *Base = getDerived().parseBaseUnresolvedName();
3900 if (Base == nullptr)
3901 return nullptr;
3902 return make<QualifiedName>(SoFar, Base);
3903}
3904
3905// <abi-tags> ::= <abi-tag> [<abi-tags>]
3906// <abi-tag> ::= B <source-name>
3907template <typename Derived, typename Alloc>
3908Node *AbstractManglingParser<Derived, Alloc>::parseAbiTags(Node *N) {
3909 while (consumeIf('B')) {
3910 std::string_view SN = parseBareSourceName();
3911 if (SN.empty())
3912 return nullptr;
3913 N = make<AbiTagAttr>(N, SN);
3914 if (!N)
3915 return nullptr;
3916 }
3917 return N;
3918}
3919
3920// <number> ::= [n] <non-negative decimal integer>
3921template <typename Alloc, typename Derived>
3922std::string_view
3923AbstractManglingParser<Alloc, Derived>::parseNumber(bool AllowNegative) {
3924 const char *Tmp = First;
3925 if (AllowNegative)
3926 consumeIf('n');
3927 if (numLeft() == 0 || !std::isdigit(c: *First))
3928 return std::string_view();
3929 while (numLeft() != 0 && std::isdigit(c: *First))
3930 ++First;
3931 return std::string_view(Tmp, First - Tmp);
3932}
3933
3934// <positive length number> ::= [0-9]*
3935template <typename Alloc, typename Derived>
3936bool AbstractManglingParser<Alloc, Derived>::parsePositiveInteger(size_t *Out) {
3937 *Out = 0;
3938 if (look() < '0' || look() > '9')
3939 return true;
3940 while (look() >= '0' && look() <= '9') {
3941 *Out *= 10;
3942 *Out += static_cast<size_t>(consume() - '0');
3943 }
3944 return false;
3945}
3946
3947template <typename Alloc, typename Derived>
3948std::string_view AbstractManglingParser<Alloc, Derived>::parseBareSourceName() {
3949 size_t Int = 0;
3950 if (parsePositiveInteger(Out: &Int) || numLeft() < Int)
3951 return {};
3952 std::string_view R(First, Int);
3953 First += Int;
3954 return R;
3955}
3956
3957// <function-type> ::= [<CV-qualifiers>] [<exception-spec>] [Dx] F [Y] <bare-function-type> [<ref-qualifier>] E
3958//
3959// <exception-spec> ::= Do # non-throwing exception-specification (e.g., noexcept, throw())
3960// ::= DO <expression> E # computed (instantiation-dependent) noexcept
3961// ::= Dw <type>+ E # dynamic exception specification with instantiation-dependent types
3962//
3963// <ref-qualifier> ::= R # & ref-qualifier
3964// <ref-qualifier> ::= O # && ref-qualifier
3965template <typename Derived, typename Alloc>
3966Node *AbstractManglingParser<Derived, Alloc>::parseFunctionType() {
3967 Qualifiers CVQuals = parseCVQualifiers();
3968
3969 Node *ExceptionSpec = nullptr;
3970 if (consumeIf("Do")) {
3971 ExceptionSpec = make<NameType>("noexcept");
3972 if (!ExceptionSpec)
3973 return nullptr;
3974 } else if (consumeIf("DO")) {
3975 Node *E = getDerived().parseExpr();
3976 if (E == nullptr || !consumeIf('E'))
3977 return nullptr;
3978 ExceptionSpec = make<NoexceptSpec>(E);
3979 if (!ExceptionSpec)
3980 return nullptr;
3981 } else if (consumeIf("Dw")) {
3982 size_t SpecsBegin = Names.size();
3983 while (!consumeIf('E')) {
3984 Node *T = getDerived().parseType();
3985 if (T == nullptr)
3986 return nullptr;
3987 Names.push_back(Elem: T);
3988 }
3989 ExceptionSpec =
3990 make<DynamicExceptionSpec>(popTrailingNodeArray(FromPosition: SpecsBegin));
3991 if (!ExceptionSpec)
3992 return nullptr;
3993 }
3994
3995 consumeIf("Dx"); // transaction safe
3996
3997 if (!consumeIf('F'))
3998 return nullptr;
3999 consumeIf('Y'); // extern "C"
4000 Node *ReturnType = getDerived().parseType();
4001 if (ReturnType == nullptr)
4002 return nullptr;
4003
4004 FunctionRefQual ReferenceQualifier = FrefQualNone;
4005 size_t ParamsBegin = Names.size();
4006 while (true) {
4007 if (consumeIf('E'))
4008 break;
4009 if (consumeIf('v'))
4010 continue;
4011 if (consumeIf("RE")) {
4012 ReferenceQualifier = FrefQualLValue;
4013 break;
4014 }
4015 if (consumeIf("OE")) {
4016 ReferenceQualifier = FrefQualRValue;
4017 break;
4018 }
4019 Node *T = getDerived().parseType();
4020 if (T == nullptr)
4021 return nullptr;
4022 Names.push_back(Elem: T);
4023 }
4024
4025 NodeArray Params = popTrailingNodeArray(FromPosition: ParamsBegin);
4026 return make<FunctionType>(ReturnType, Params, CVQuals,
4027 ReferenceQualifier, ExceptionSpec);
4028}
4029
4030// extension:
4031// <vector-type> ::= Dv <positive dimension number> _ <extended element type>
4032// ::= Dv [<dimension expression>] _ <element type>
4033// <extended element type> ::= <element type>
4034// ::= p # AltiVec vector pixel
4035template <typename Derived, typename Alloc>
4036Node *AbstractManglingParser<Derived, Alloc>::parseVectorType() {
4037 if (!consumeIf("Dv"))
4038 return nullptr;
4039 if (look() >= '1' && look() <= '9') {
4040 Node *DimensionNumber = make<NameType>(parseNumber());
4041 if (!DimensionNumber)
4042 return nullptr;
4043 if (!consumeIf('_'))
4044 return nullptr;
4045 if (consumeIf('p'))
4046 return make<PixelVectorType>(DimensionNumber);
4047 Node *ElemType = getDerived().parseType();
4048 if (ElemType == nullptr)
4049 return nullptr;
4050 return make<VectorType>(ElemType, DimensionNumber);
4051 }
4052
4053 if (!consumeIf('_')) {
4054 Node *DimExpr = getDerived().parseExpr();
4055 if (!DimExpr)
4056 return nullptr;
4057 if (!consumeIf('_'))
4058 return nullptr;
4059 Node *ElemType = getDerived().parseType();
4060 if (!ElemType)
4061 return nullptr;
4062 return make<VectorType>(ElemType, DimExpr);
4063 }
4064 Node *ElemType = getDerived().parseType();
4065 if (!ElemType)
4066 return nullptr;
4067 return make<VectorType>(ElemType, /*Dimension=*/nullptr);
4068}
4069
4070// <decltype> ::= Dt <expression> E # decltype of an id-expression or class member access (C++0x)
4071// ::= DT <expression> E # decltype of an expression (C++0x)
4072template <typename Derived, typename Alloc>
4073Node *AbstractManglingParser<Derived, Alloc>::parseDecltype() {
4074 if (!consumeIf('D'))
4075 return nullptr;
4076 if (!consumeIf('t') && !consumeIf('T'))
4077 return nullptr;
4078 Node *E = getDerived().parseExpr();
4079 if (E == nullptr)
4080 return nullptr;
4081 if (!consumeIf('E'))
4082 return nullptr;
4083 return make<EnclosingExpr>("decltype", E);
4084}
4085
4086// <array-type> ::= A <positive dimension number> _ <element type>
4087// ::= A [<dimension expression>] _ <element type>
4088template <typename Derived, typename Alloc>
4089Node *AbstractManglingParser<Derived, Alloc>::parseArrayType() {
4090 if (!consumeIf('A'))
4091 return nullptr;
4092
4093 Node *Dimension = nullptr;
4094
4095 if (std::isdigit(c: look())) {
4096 Dimension = make<NameType>(parseNumber());
4097 if (!Dimension)
4098 return nullptr;
4099 if (!consumeIf('_'))
4100 return nullptr;
4101 } else if (!consumeIf('_')) {
4102 Node *DimExpr = getDerived().parseExpr();
4103 if (DimExpr == nullptr)
4104 return nullptr;
4105 if (!consumeIf('_'))
4106 return nullptr;
4107 Dimension = DimExpr;
4108 }
4109
4110 Node *Ty = getDerived().parseType();
4111 if (Ty == nullptr)
4112 return nullptr;
4113 return make<ArrayType>(Ty, Dimension);
4114}
4115
4116// <pointer-to-member-type> ::= M <class type> <member type>
4117template <typename Derived, typename Alloc>
4118Node *AbstractManglingParser<Derived, Alloc>::parsePointerToMemberType() {
4119 if (!consumeIf('M'))
4120 return nullptr;
4121 Node *ClassType = getDerived().parseType();
4122 if (ClassType == nullptr)
4123 return nullptr;
4124 Node *MemberType = getDerived().parseType();
4125 if (MemberType == nullptr)
4126 return nullptr;
4127 return make<PointerToMemberType>(ClassType, MemberType);
4128}
4129
4130// <class-enum-type> ::= <name> # non-dependent type name, dependent type name, or dependent typename-specifier
4131// ::= Ts <name> # dependent elaborated type specifier using 'struct' or 'class'
4132// ::= Tu <name> # dependent elaborated type specifier using 'union'
4133// ::= Te <name> # dependent elaborated type specifier using 'enum'
4134template <typename Derived, typename Alloc>
4135Node *AbstractManglingParser<Derived, Alloc>::parseClassEnumType() {
4136 std::string_view ElabSpef;
4137 if (consumeIf("Ts"))
4138 ElabSpef = "struct";
4139 else if (consumeIf("Tu"))
4140 ElabSpef = "union";
4141 else if (consumeIf("Te"))
4142 ElabSpef = "enum";
4143
4144 Node *Name = getDerived().parseName();
4145 if (Name == nullptr)
4146 return nullptr;
4147
4148 if (!ElabSpef.empty())
4149 return make<ElaboratedTypeSpefType>(ElabSpef, Name);
4150
4151 return Name;
4152}
4153
4154// <qualified-type> ::= <qualifiers> <type>
4155// <qualifiers> ::= <extended-qualifier>* <CV-qualifiers>
4156// <extended-qualifier> ::= U <source-name> [<template-args>] # vendor extended type qualifier
4157template <typename Derived, typename Alloc>
4158Node *AbstractManglingParser<Derived, Alloc>::parseQualifiedType() {
4159 if (consumeIf('U')) {
4160 std::string_view Qual = parseBareSourceName();
4161 if (Qual.empty())
4162 return nullptr;
4163
4164 // extension ::= U <objc-name> <objc-type> # objc-type<identifier>
4165 if (starts_with(haystack: Qual, needle: "objcproto")) {
4166 constexpr size_t Len = sizeof("objcproto") - 1;
4167 std::string_view ProtoSourceName(Qual.data() + Len, Qual.size() - Len);
4168 std::string_view Proto;
4169 {
4170 ScopedOverride<const char *> SaveFirst(First, ProtoSourceName.data()),
4171 SaveLast(Last, &*ProtoSourceName.rbegin() + 1);
4172 Proto = parseBareSourceName();
4173 }
4174 if (Proto.empty())
4175 return nullptr;
4176 Node *Child = getDerived().parseQualifiedType();
4177 if (Child == nullptr)
4178 return nullptr;
4179 return make<ObjCProtoName>(Child, Proto);
4180 }
4181
4182 Node *TA = nullptr;
4183 if (look() == 'I') {
4184 TA = getDerived().parseTemplateArgs();
4185 if (TA == nullptr)
4186 return nullptr;
4187 }
4188
4189 Node *Child = getDerived().parseQualifiedType();
4190 if (Child == nullptr)
4191 return nullptr;
4192 return make<VendorExtQualType>(Child, Qual, TA);
4193 }
4194
4195 Qualifiers Quals = parseCVQualifiers();
4196 Node *Ty = getDerived().parseType();
4197 if (Ty == nullptr)
4198 return nullptr;
4199 if (Quals != QualNone)
4200 Ty = make<QualType>(Ty, Quals);
4201 return Ty;
4202}
4203
4204// <type> ::= <builtin-type>
4205// ::= <qualified-type>
4206// ::= <function-type>
4207// ::= <class-enum-type>
4208// ::= <array-type>
4209// ::= <pointer-to-member-type>
4210// ::= <template-param>
4211// ::= <template-template-param> <template-args>
4212// ::= <decltype>
4213// ::= P <type> # pointer
4214// ::= R <type> # l-value reference
4215// ::= O <type> # r-value reference (C++11)
4216// ::= C <type> # complex pair (C99)
4217// ::= G <type> # imaginary (C99)
4218// ::= <substitution> # See Compression below
4219// extension ::= U <objc-name> <objc-type> # objc-type<identifier>
4220// extension ::= <vector-type> # <vector-type> starts with Dv
4221//
4222// <objc-name> ::= <k0 number> objcproto <k1 number> <identifier> # k0 = 9 + <number of digits in k1> + k1
4223// <objc-type> ::= <source-name> # PU<11+>objcproto 11objc_object<source-name> 11objc_object -> id<source-name>
4224template <typename Derived, typename Alloc>
4225Node *AbstractManglingParser<Derived, Alloc>::parseType() {
4226 Node *Result = nullptr;
4227
4228 switch (look()) {
4229 // ::= <qualified-type>
4230 case 'r':
4231 case 'V':
4232 case 'K': {
4233 unsigned AfterQuals = 0;
4234 if (look(Lookahead: AfterQuals) == 'r') ++AfterQuals;
4235 if (look(Lookahead: AfterQuals) == 'V') ++AfterQuals;
4236 if (look(Lookahead: AfterQuals) == 'K') ++AfterQuals;
4237
4238 if (look(Lookahead: AfterQuals) == 'F' ||
4239 (look(Lookahead: AfterQuals) == 'D' &&
4240 (look(Lookahead: AfterQuals + 1) == 'o' || look(Lookahead: AfterQuals + 1) == 'O' ||
4241 look(Lookahead: AfterQuals + 1) == 'w' || look(Lookahead: AfterQuals + 1) == 'x'))) {
4242 Result = getDerived().parseFunctionType();
4243 break;
4244 }
4245 DEMANGLE_FALLTHROUGH;
4246 }
4247 case 'U': {
4248 Result = getDerived().parseQualifiedType();
4249 break;
4250 }
4251 // <builtin-type> ::= v # void
4252 case 'v':
4253 ++First;
4254 return make<NameType>("void");
4255 // ::= w # wchar_t
4256 case 'w':
4257 ++First;
4258 return make<NameType>("wchar_t");
4259 // ::= b # bool
4260 case 'b':
4261 ++First;
4262 return make<NameType>("bool");
4263 // ::= c # char
4264 case 'c':
4265 ++First;
4266 return make<NameType>("char");
4267 // ::= a # signed char
4268 case 'a':
4269 ++First;
4270 return make<NameType>("signed char");
4271 // ::= h # unsigned char
4272 case 'h':
4273 ++First;
4274 return make<NameType>("unsigned char");
4275 // ::= s # short
4276 case 's':
4277 ++First;
4278 return make<NameType>("short");
4279 // ::= t # unsigned short
4280 case 't':
4281 ++First;
4282 return make<NameType>("unsigned short");
4283 // ::= i # int
4284 case 'i':
4285 ++First;
4286 return make<NameType>("int");
4287 // ::= j # unsigned int
4288 case 'j':
4289 ++First;
4290 return make<NameType>("unsigned int");
4291 // ::= l # long
4292 case 'l':
4293 ++First;
4294 return make<NameType>("long");
4295 // ::= m # unsigned long
4296 case 'm':
4297 ++First;
4298 return make<NameType>("unsigned long");
4299 // ::= x # long long, __int64
4300 case 'x':
4301 ++First;
4302 return make<NameType>("long long");
4303 // ::= y # unsigned long long, __int64
4304 case 'y':
4305 ++First;
4306 return make<NameType>("unsigned long long");
4307 // ::= n # __int128
4308 case 'n':
4309 ++First;
4310 return make<NameType>("__int128");
4311 // ::= o # unsigned __int128
4312 case 'o':
4313 ++First;
4314 return make<NameType>("unsigned __int128");
4315 // ::= f # float
4316 case 'f':
4317 ++First;
4318 return make<NameType>("float");
4319 // ::= d # double
4320 case 'd':
4321 ++First;
4322 return make<NameType>("double");
4323 // ::= e # long double, __float80
4324 case 'e':
4325 ++First;
4326 return make<NameType>("long double");
4327 // ::= g # __float128
4328 case 'g':
4329 ++First;
4330 return make<NameType>("__float128");
4331 // ::= z # ellipsis
4332 case 'z':
4333 ++First;
4334 return make<NameType>("...");
4335
4336 // <builtin-type> ::= u <source-name> # vendor extended type
4337 case 'u': {
4338 ++First;
4339 std::string_view Res = parseBareSourceName();
4340 if (Res.empty())
4341 return nullptr;
4342 // Typically, <builtin-type>s are not considered substitution candidates,
4343 // but the exception to that exception is vendor extended types (Itanium C++
4344 // ABI 5.9.1).
4345 if (consumeIf('I')) {
4346 Node *BaseType = parseType();
4347 if (BaseType == nullptr)
4348 return nullptr;
4349 if (!consumeIf('E'))
4350 return nullptr;
4351 Result = make<TransformedType>(Res, BaseType);
4352 } else
4353 Result = make<NameType>(Res);
4354 break;
4355 }
4356 case 'D':
4357 switch (look(Lookahead: 1)) {
4358 // ::= Dd # IEEE 754r decimal floating point (64 bits)
4359 case 'd':
4360 First += 2;
4361 return make<NameType>("decimal64");
4362 // ::= De # IEEE 754r decimal floating point (128 bits)
4363 case 'e':
4364 First += 2;
4365 return make<NameType>("decimal128");
4366 // ::= Df # IEEE 754r decimal floating point (32 bits)
4367 case 'f':
4368 First += 2;
4369 return make<NameType>("decimal32");
4370 // ::= Dh # IEEE 754r half-precision floating point (16 bits)
4371 case 'h':
4372 First += 2;
4373 return make<NameType>("half");
4374 // ::= DF16b # C++23 std::bfloat16_t
4375 // ::= DF <number> _ # ISO/IEC TS 18661 binary floating point (N bits)
4376 case 'F': {
4377 First += 2;
4378 if (consumeIf("16b"))
4379 return make<NameType>("std::bfloat16_t");
4380 Node *DimensionNumber = make<NameType>(parseNumber());
4381 if (!DimensionNumber)
4382 return nullptr;
4383 if (!consumeIf('_'))
4384 return nullptr;
4385 return make<BinaryFPType>(DimensionNumber);
4386 }
4387 // ::= [DS] DA # N1169 fixed-point [_Sat] T _Accum
4388 // ::= [DS] DR # N1169 fixed-point [_Sat] T _Frac
4389 // <fixed-point-size>
4390 // ::= s # short
4391 // ::= t # unsigned short
4392 // ::= i # plain
4393 // ::= j # unsigned
4394 // ::= l # long
4395 // ::= m # unsigned long
4396 case 'A': {
4397 char c = look(Lookahead: 2);
4398 First += 3;
4399 switch (c) {
4400 case 's':
4401 return make<NameType>("short _Accum");
4402 case 't':
4403 return make<NameType>("unsigned short _Accum");
4404 case 'i':
4405 return make<NameType>("_Accum");
4406 case 'j':
4407 return make<NameType>("unsigned _Accum");
4408 case 'l':
4409 return make<NameType>("long _Accum");
4410 case 'm':
4411 return make<NameType>("unsigned long _Accum");
4412 default:
4413 return nullptr;
4414 }
4415 }
4416 case 'R': {
4417 char c = look(Lookahead: 2);
4418 First += 3;
4419 switch (c) {
4420 case 's':
4421 return make<NameType>("short _Fract");
4422 case 't':
4423 return make<NameType>("unsigned short _Fract");
4424 case 'i':
4425 return make<NameType>("_Fract");
4426 case 'j':
4427 return make<NameType>("unsigned _Fract");
4428 case 'l':
4429 return make<NameType>("long _Fract");
4430 case 'm':
4431 return make<NameType>("unsigned long _Fract");
4432 default:
4433 return nullptr;
4434 }
4435 }
4436 case 'S': {
4437 First += 2;
4438 if (look() != 'D')
4439 return nullptr;
4440 if (look(Lookahead: 1) == 'A') {
4441 char c = look(Lookahead: 2);
4442 First += 3;
4443 switch (c) {
4444 case 's':
4445 return make<NameType>("_Sat short _Accum");
4446 case 't':
4447 return make<NameType>("_Sat unsigned short _Accum");
4448 case 'i':
4449 return make<NameType>("_Sat _Accum");
4450 case 'j':
4451 return make<NameType>("_Sat unsigned _Accum");
4452 case 'l':
4453 return make<NameType>("_Sat long _Accum");
4454 case 'm':
4455 return make<NameType>("_Sat unsigned long _Accum");
4456 default:
4457 return nullptr;
4458 }
4459 }
4460 if (look(Lookahead: 1) == 'R') {
4461 char c = look(Lookahead: 2);
4462 First += 3;
4463 switch (c) {
4464 case 's':
4465 return make<NameType>("_Sat short _Fract");
4466 case 't':
4467 return make<NameType>("_Sat unsigned short _Fract");
4468 case 'i':
4469 return make<NameType>("_Sat _Fract");
4470 case 'j':
4471 return make<NameType>("_Sat unsigned _Fract");
4472 case 'l':
4473 return make<NameType>("_Sat long _Fract");
4474 case 'm':
4475 return make<NameType>("_Sat unsigned long _Fract");
4476 default:
4477 return nullptr;
4478 }
4479 }
4480 return nullptr;
4481 }
4482 // ::= DB <number> _ # C23 signed _BitInt(N)
4483 // ::= DB <instantiation-dependent expression> _ # C23 signed _BitInt(N)
4484 // ::= DU <number> _ # C23 unsigned _BitInt(N)
4485 // ::= DU <instantiation-dependent expression> _ # C23 unsigned _BitInt(N)
4486 case 'B':
4487 case 'U': {
4488 bool Signed = look(Lookahead: 1) == 'B';
4489 First += 2;
4490 Node *Size = std::isdigit(c: look()) ? make<NameType>(parseNumber())
4491 : getDerived().parseExpr();
4492 if (!Size)
4493 return nullptr;
4494 if (!consumeIf('_'))
4495 return nullptr;
4496 // The front end expects this to be available for Substitution
4497 Result = make<BitIntType>(Size, Signed);
4498 break;
4499 }
4500 // ::= Di # char32_t
4501 case 'i':
4502 First += 2;
4503 return make<NameType>("char32_t");
4504 // ::= Ds # char16_t
4505 case 's':
4506 First += 2;
4507 return make<NameType>("char16_t");
4508 // ::= Du # char8_t (C++2a, not yet in the Itanium spec)
4509 case 'u':
4510 First += 2;
4511 return make<NameType>("char8_t");
4512 // ::= Da # auto (in dependent new-expressions)
4513 case 'a':
4514 First += 2;
4515 return make<NameType>("auto");
4516 // ::= Dc # decltype(auto)
4517 case 'c':
4518 First += 2;
4519 return make<NameType>("decltype(auto)");
4520 // ::= Dk <type-constraint> # constrained auto
4521 // ::= DK <type-constraint> # constrained decltype(auto)
4522 case 'k':
4523 case 'K': {
4524 std::string_view Kind = look(Lookahead: 1) == 'k' ? " auto" : " decltype(auto)";
4525 First += 2;
4526 Node *Constraint = getDerived().parseName();
4527 if (!Constraint)
4528 return nullptr;
4529 return make<PostfixQualifiedType>(Constraint, Kind);
4530 }
4531 // ::= Dn # std::nullptr_t (i.e., decltype(nullptr))
4532 case 'n':
4533 First += 2;
4534 return make<NameType>("std::nullptr_t");
4535
4536 // ::= <decltype>
4537 case 't':
4538 case 'T': {
4539 Result = getDerived().parseDecltype();
4540 break;
4541 }
4542 // extension ::= <vector-type> # <vector-type> starts with Dv
4543 case 'v': {
4544 Result = getDerived().parseVectorType();
4545 break;
4546 }
4547 // ::= Dp <type> # pack expansion (C++0x)
4548 case 'p': {
4549 First += 2;
4550 Node *Child = getDerived().parseType();
4551 if (!Child)
4552 return nullptr;
4553 Result = make<ParameterPackExpansion>(Child);
4554 break;
4555 }
4556 // ::= Dy <type> <expression> # pack indexing (C++26)
4557 case 'y': {
4558 First += 2;
4559 Node *Pattern = getDerived().parseType();
4560 if (!Pattern)
4561 return nullptr;
4562 Node *Index = getDerived().parseExpr();
4563 if (!Index)
4564 return nullptr;
4565 Result = make<PackIndexing>(Pattern, Index);
4566 break;
4567 }
4568 // Exception specifier on a function type.
4569 case 'o':
4570 case 'O':
4571 case 'w':
4572 // Transaction safe function type.
4573 case 'x':
4574 Result = getDerived().parseFunctionType();
4575 break;
4576 }
4577 break;
4578 // ::= <function-type>
4579 case 'F': {
4580 Result = getDerived().parseFunctionType();
4581 break;
4582 }
4583 // ::= <array-type>
4584 case 'A': {
4585 Result = getDerived().parseArrayType();
4586 break;
4587 }
4588 // ::= <pointer-to-member-type>
4589 case 'M': {
4590 Result = getDerived().parsePointerToMemberType();
4591 break;
4592 }
4593 // ::= <template-param>
4594 case 'T': {
4595 // This could be an elaborate type specifier on a <class-enum-type>.
4596 if (look(Lookahead: 1) == 's' || look(Lookahead: 1) == 'u' || look(Lookahead: 1) == 'e') {
4597 Result = getDerived().parseClassEnumType();
4598 break;
4599 }
4600
4601 Result = getDerived().parseTemplateParam();
4602 if (Result == nullptr)
4603 return nullptr;
4604
4605 // Result could be either of:
4606 // <type> ::= <template-param>
4607 // <type> ::= <template-template-param> <template-args>
4608 //
4609 // <template-template-param> ::= <template-param>
4610 // ::= <substitution>
4611 //
4612 // If this is followed by some <template-args>, and we're permitted to
4613 // parse them, take the second production.
4614
4615 if (TryToParseTemplateArgs && look() == 'I') {
4616 Subs.push_back(Elem: Result);
4617 Node *TA = getDerived().parseTemplateArgs();
4618 if (TA == nullptr)
4619 return nullptr;
4620 Result = make<NameWithTemplateArgs>(Result, TA);
4621 }
4622 break;
4623 }
4624 // ::= P <type> # pointer
4625 case 'P': {
4626 ++First;
4627 Node *Ptr = getDerived().parseType();
4628 if (Ptr == nullptr)
4629 return nullptr;
4630 Result = make<PointerType>(Ptr);
4631 break;
4632 }
4633 // ::= R <type> # l-value reference
4634 case 'R': {
4635 ++First;
4636 Node *Ref = getDerived().parseType();
4637 if (Ref == nullptr)
4638 return nullptr;
4639 Result = make<ReferenceType>(Ref, ReferenceKind::LValue);
4640 break;
4641 }
4642 // ::= O <type> # r-value reference (C++11)
4643 case 'O': {
4644 ++First;
4645 Node *Ref = getDerived().parseType();
4646 if (Ref == nullptr)
4647 return nullptr;
4648 Result = make<ReferenceType>(Ref, ReferenceKind::RValue);
4649 break;
4650 }
4651 // ::= C <type> # complex pair (C99)
4652 case 'C': {
4653 ++First;
4654 Node *P = getDerived().parseType();
4655 if (P == nullptr)
4656 return nullptr;
4657 Result = make<PostfixQualifiedType>(P, " complex");
4658 break;
4659 }
4660 // ::= G <type> # imaginary (C99)
4661 case 'G': {
4662 ++First;
4663 Node *P = getDerived().parseType();
4664 if (P == nullptr)
4665 return P;
4666 Result = make<PostfixQualifiedType>(P, " imaginary");
4667 break;
4668 }
4669 // ::= <substitution> # See Compression below
4670 case 'S': {
4671 if (look(Lookahead: 1) != 't') {
4672 bool IsSubst = false;
4673 Result = getDerived().parseUnscopedName(nullptr, &IsSubst);
4674 if (!Result)
4675 return nullptr;
4676
4677 // Sub could be either of:
4678 // <type> ::= <substitution>
4679 // <type> ::= <template-template-param> <template-args>
4680 //
4681 // <template-template-param> ::= <template-param>
4682 // ::= <substitution>
4683 //
4684 // If this is followed by some <template-args>, and we're permitted to
4685 // parse them, take the second production.
4686
4687 if (look() == 'I' && (!IsSubst || TryToParseTemplateArgs)) {
4688 if (!IsSubst)
4689 Subs.push_back(Elem: Result);
4690 Node *TA = getDerived().parseTemplateArgs();
4691 if (TA == nullptr)
4692 return nullptr;
4693 Result = make<NameWithTemplateArgs>(Result, TA);
4694 } else if (IsSubst) {
4695 // If all we parsed was a substitution, don't re-insert into the
4696 // substitution table.
4697 return Result;
4698 }
4699 break;
4700 }
4701 DEMANGLE_FALLTHROUGH;
4702 }
4703 // ::= <class-enum-type>
4704 default: {
4705 Result = getDerived().parseClassEnumType();
4706 break;
4707 }
4708 }
4709
4710 // If we parsed a type, insert it into the substitution table. Note that all
4711 // <builtin-type>s and <substitution>s have already bailed out, because they
4712 // don't get substitutions.
4713 if (Result != nullptr)
4714 Subs.push_back(Elem: Result);
4715 return Result;
4716}
4717
4718template <typename Derived, typename Alloc>
4719Node *
4720AbstractManglingParser<Derived, Alloc>::parsePrefixExpr(std::string_view Kind,
4721 Node::Prec Prec) {
4722 Node *E = getDerived().parseExpr();
4723 if (E == nullptr)
4724 return nullptr;
4725 return make<PrefixExpr>(Kind, E, Prec);
4726}
4727
4728template <typename Derived, typename Alloc>
4729Node *
4730AbstractManglingParser<Derived, Alloc>::parseBinaryExpr(std::string_view Kind,
4731 Node::Prec Prec) {
4732 Node *LHS = getDerived().parseExpr();
4733 if (LHS == nullptr)
4734 return nullptr;
4735 Node *RHS = getDerived().parseExpr();
4736 if (RHS == nullptr)
4737 return nullptr;
4738 return make<BinaryExpr>(LHS, Kind, RHS, Prec);
4739}
4740
4741template <typename Derived, typename Alloc>
4742Node *AbstractManglingParser<Derived, Alloc>::parseIntegerLiteral(
4743 std::string_view Lit) {
4744 std::string_view Tmp = parseNumber(AllowNegative: true);
4745 if (!Tmp.empty() && consumeIf('E'))
4746 return make<IntegerLiteral>(Lit, Tmp);
4747 return nullptr;
4748}
4749
4750// <CV-Qualifiers> ::= [r] [V] [K]
4751template <typename Alloc, typename Derived>
4752Qualifiers AbstractManglingParser<Alloc, Derived>::parseCVQualifiers() {
4753 Qualifiers CVR = QualNone;
4754 if (consumeIf('r'))
4755 CVR |= QualRestrict;
4756 if (consumeIf('V'))
4757 CVR |= QualVolatile;
4758 if (consumeIf('K'))
4759 CVR |= QualConst;
4760 return CVR;
4761}
4762
4763// <function-param> ::= fp <top-level CV-Qualifiers> _ # L == 0, first parameter
4764// ::= fp <top-level CV-Qualifiers> <parameter-2 non-negative number> _ # L == 0, second and later parameters
4765// ::= fL <L-1 non-negative number> p <top-level CV-Qualifiers> _ # L > 0, first parameter
4766// ::= fL <L-1 non-negative number> p <top-level CV-Qualifiers> <parameter-2 non-negative number> _ # L > 0, second and later parameters
4767// ::= fpT # 'this' expression (not part of standard?)
4768template <typename Derived, typename Alloc>
4769Node *AbstractManglingParser<Derived, Alloc>::parseFunctionParam() {
4770 if (consumeIf("fpT"))
4771 return make<NameType>("this");
4772 if (consumeIf("fp")) {
4773 parseCVQualifiers();
4774 std::string_view Num = parseNumber();
4775 if (!consumeIf('_'))
4776 return nullptr;
4777 return make<FunctionParam>(Num);
4778 }
4779 if (consumeIf("fL")) {
4780 if (parseNumber().empty())
4781 return nullptr;
4782 if (!consumeIf('p'))
4783 return nullptr;
4784 parseCVQualifiers();
4785 std::string_view Num = parseNumber();
4786 if (!consumeIf('_'))
4787 return nullptr;
4788 return make<FunctionParam>(Num);
4789 }
4790 return nullptr;
4791}
4792
4793// cv <type> <expression> # conversion with one argument
4794// cv <type> _ <expression>* E # conversion with a different number of arguments
4795template <typename Derived, typename Alloc>
4796Node *AbstractManglingParser<Derived, Alloc>::parseConversionExpr() {
4797 if (!consumeIf("cv"))
4798 return nullptr;
4799 Node *Ty;
4800 {
4801 ScopedOverride<bool> SaveTemp(TryToParseTemplateArgs, false);
4802 Ty = getDerived().parseType();
4803 }
4804
4805 if (Ty == nullptr)
4806 return nullptr;
4807
4808 if (consumeIf('_')) {
4809 size_t ExprsBegin = Names.size();
4810 while (!consumeIf('E')) {
4811 Node *E = getDerived().parseExpr();
4812 if (E == nullptr)
4813 return E;
4814 Names.push_back(Elem: E);
4815 }
4816 NodeArray Exprs = popTrailingNodeArray(FromPosition: ExprsBegin);
4817 return make<ConversionExpr>(Ty, Exprs);
4818 }
4819
4820 Node *E[1] = {getDerived().parseExpr()};
4821 if (E[0] == nullptr)
4822 return nullptr;
4823 return make<ConversionExpr>(Ty, makeNodeArray(E, E + 1));
4824}
4825
4826// <expr-primary> ::= L <type> <value number> E # integer literal
4827// ::= L <type> <value float> E # floating literal
4828// ::= L <string type> E # string literal
4829// ::= L <nullptr type> E # nullptr literal (i.e., "LDnE")
4830// ::= L <lambda type> E # lambda expression
4831// FIXME: ::= L <type> <real-part float> _ <imag-part float> E # complex floating point literal (C 2000)
4832// ::= L <mangled-name> E # external name
4833template <typename Derived, typename Alloc>
4834Node *AbstractManglingParser<Derived, Alloc>::parseExprPrimary() {
4835 if (!consumeIf('L'))
4836 return nullptr;
4837 switch (look()) {
4838 case 'w':
4839 ++First;
4840 return getDerived().parseIntegerLiteral("wchar_t");
4841 case 'b':
4842 if (consumeIf("b0E"))
4843 return make<BoolExpr>(0);
4844 if (consumeIf("b1E"))
4845 return make<BoolExpr>(1);
4846 return nullptr;
4847 case 'c':
4848 ++First;
4849 return getDerived().parseIntegerLiteral("char");
4850 case 'a':
4851 ++First;
4852 return getDerived().parseIntegerLiteral("signed char");
4853 case 'h':
4854 ++First;
4855 return getDerived().parseIntegerLiteral("unsigned char");
4856 case 's':
4857 ++First;
4858 return getDerived().parseIntegerLiteral("short");
4859 case 't':
4860 ++First;
4861 return getDerived().parseIntegerLiteral("unsigned short");
4862 case 'i':
4863 ++First;
4864 return getDerived().parseIntegerLiteral("");
4865 case 'j':
4866 ++First;
4867 return getDerived().parseIntegerLiteral("u");
4868 case 'l':
4869 ++First;
4870 return getDerived().parseIntegerLiteral("l");
4871 case 'm':
4872 ++First;
4873 return getDerived().parseIntegerLiteral("ul");
4874 case 'x':
4875 ++First;
4876 return getDerived().parseIntegerLiteral("ll");
4877 case 'y':
4878 ++First;
4879 return getDerived().parseIntegerLiteral("ull");
4880 case 'n':
4881 ++First;
4882 return getDerived().parseIntegerLiteral("__int128");
4883 case 'o':
4884 ++First;
4885 return getDerived().parseIntegerLiteral("unsigned __int128");
4886 case 'f':
4887 ++First;
4888 return getDerived().template parseFloatingLiteral<float>();
4889 case 'd':
4890 ++First;
4891 return getDerived().template parseFloatingLiteral<double>();
4892 case 'e':
4893 ++First;
4894#if defined(__powerpc__) || defined(__s390__)
4895 // Handle cases where long doubles encoded with e have the same size
4896 // and representation as doubles.
4897 return getDerived().template parseFloatingLiteral<double>();
4898#else
4899 return getDerived().template parseFloatingLiteral<long double>();
4900#endif
4901 case '_':
4902 if (consumeIf("_Z")) {
4903 Node *R = getDerived().parseEncoding();
4904 if (R != nullptr && consumeIf('E'))
4905 return R;
4906 }
4907 return nullptr;
4908 case 'A': {
4909 Node *T = getDerived().parseType();
4910 if (T == nullptr)
4911 return nullptr;
4912 // FIXME: We need to include the string contents in the mangling.
4913 if (consumeIf('E'))
4914 return make<StringLiteral>(T);
4915 return nullptr;
4916 }
4917 case 'D':
4918 if (consumeIf("Dn") && (consumeIf('0'), consumeIf('E')))
4919 return make<NameType>("nullptr");
4920 return nullptr;
4921 case 'T':
4922 // Invalid mangled name per
4923 // http://sourcerytools.com/pipermail/cxx-abi-dev/2011-August/002422.html
4924 return nullptr;
4925 case 'U': {
4926 // FIXME: Should we support LUb... for block literals?
4927 if (look(Lookahead: 1) != 'l')
4928 return nullptr;
4929 Node *T = parseUnnamedTypeName(State: nullptr);
4930 if (!T || !consumeIf('E'))
4931 return nullptr;
4932 return make<LambdaExpr>(T);
4933 }
4934 default: {
4935 // might be named type
4936 Node *T = getDerived().parseType();
4937 if (T == nullptr)
4938 return nullptr;
4939 std::string_view N = parseNumber(/*AllowNegative=*/AllowNegative: true);
4940 if (N.empty())
4941 return nullptr;
4942 if (!consumeIf('E'))
4943 return nullptr;
4944 return make<EnumLiteral>(T, N);
4945 }
4946 }
4947}
4948
4949// <braced-expression> ::= <expression>
4950// ::= di <field source-name> <braced-expression> # .name = expr
4951// ::= dx <index expression> <braced-expression> # [expr] = expr
4952// ::= dX <range begin expression> <range end expression> <braced-expression>
4953template <typename Derived, typename Alloc>
4954Node *AbstractManglingParser<Derived, Alloc>::parseBracedExpr() {
4955 if (look() == 'd') {
4956 switch (look(Lookahead: 1)) {
4957 case 'i': {
4958 First += 2;
4959 Node *Field = getDerived().parseSourceName(/*NameState=*/nullptr);
4960 if (Field == nullptr)
4961 return nullptr;
4962 Node *Init = getDerived().parseBracedExpr();
4963 if (Init == nullptr)
4964 return nullptr;
4965 return make<BracedExpr>(Field, Init, /*isArray=*/false);
4966 }
4967 case 'x': {
4968 First += 2;
4969 Node *Index = getDerived().parseExpr();
4970 if (Index == nullptr)
4971 return nullptr;
4972 Node *Init = getDerived().parseBracedExpr();
4973 if (Init == nullptr)
4974 return nullptr;
4975 return make<BracedExpr>(Index, Init, /*isArray=*/true);
4976 }
4977 case 'X': {
4978 First += 2;
4979 Node *RangeBegin = getDerived().parseExpr();
4980 if (RangeBegin == nullptr)
4981 return nullptr;
4982 Node *RangeEnd = getDerived().parseExpr();
4983 if (RangeEnd == nullptr)
4984 return nullptr;
4985 Node *Init = getDerived().parseBracedExpr();
4986 if (Init == nullptr)
4987 return nullptr;
4988 return make<BracedRangeExpr>(RangeBegin, RangeEnd, Init);
4989 }
4990 }
4991 }
4992 return getDerived().parseExpr();
4993}
4994
4995// (not yet in the spec)
4996// <fold-expr> ::= fL <binary-operator-name> <expression> <expression>
4997// ::= fR <binary-operator-name> <expression> <expression>
4998// ::= fl <binary-operator-name> <expression>
4999// ::= fr <binary-operator-name> <expression>
5000template <typename Derived, typename Alloc>
5001Node *AbstractManglingParser<Derived, Alloc>::parseFoldExpr() {
5002 if (!consumeIf('f'))
5003 return nullptr;
5004
5005 bool IsLeftFold = false, HasInitializer = false;
5006 switch (look()) {
5007 default:
5008 return nullptr;
5009 case 'L':
5010 IsLeftFold = true;
5011 HasInitializer = true;
5012 break;
5013 case 'R':
5014 HasInitializer = true;
5015 break;
5016 case 'l':
5017 IsLeftFold = true;
5018 break;
5019 case 'r':
5020 break;
5021 }
5022 ++First;
5023
5024 const auto *Op = parseOperatorEncoding();
5025 if (!Op)
5026 return nullptr;
5027 if (!(Op->getKind() == OperatorInfo::Binary
5028 || (Op->getKind() == OperatorInfo::Member
5029 && Op->getName().back() == '*')))
5030 return nullptr;
5031
5032 Node *Pack = getDerived().parseExpr();
5033 if (Pack == nullptr)
5034 return nullptr;
5035
5036 Node *Init = nullptr;
5037 if (HasInitializer) {
5038 Init = getDerived().parseExpr();
5039 if (Init == nullptr)
5040 return nullptr;
5041 }
5042
5043 if (IsLeftFold && Init)
5044 std::swap(x&: Pack, y&: Init);
5045
5046 return make<FoldExpr>(IsLeftFold, Op->getSymbol(), Pack, Init);
5047}
5048
5049// <expression> ::= mc <parameter type> <expr> [<offset number>] E
5050//
5051// Not yet in the spec: https://github.com/itanium-cxx-abi/cxx-abi/issues/47
5052template <typename Derived, typename Alloc>
5053Node *
5054AbstractManglingParser<Derived, Alloc>::parsePointerToMemberConversionExpr(
5055 Node::Prec Prec) {
5056 Node *Ty = getDerived().parseType();
5057 if (!Ty)
5058 return nullptr;
5059 Node *Expr = getDerived().parseExpr();
5060 if (!Expr)
5061 return nullptr;
5062 std::string_view Offset = getDerived().parseNumber(true);
5063 if (!consumeIf('E'))
5064 return nullptr;
5065 return make<PointerToMemberConversionExpr>(Ty, Expr, Offset, Prec);
5066}
5067
5068// <expression> ::= so <referent type> <expr> [<offset number>] <union-selector>* [p] E
5069// <union-selector> ::= _ [<number>]
5070//
5071// Not yet in the spec: https://github.com/itanium-cxx-abi/cxx-abi/issues/47
5072template <typename Derived, typename Alloc>
5073Node *AbstractManglingParser<Derived, Alloc>::parseSubobjectExpr() {
5074 Node *Ty = getDerived().parseType();
5075 if (!Ty)
5076 return nullptr;
5077 Node *Expr = getDerived().parseExpr();
5078 if (!Expr)
5079 return nullptr;
5080 std::string_view Offset = getDerived().parseNumber(true);
5081 size_t SelectorsBegin = Names.size();
5082 while (consumeIf('_')) {
5083 Node *Selector = make<NameType>(parseNumber());
5084 if (!Selector)
5085 return nullptr;
5086 Names.push_back(Elem: Selector);
5087 }
5088 bool OnePastTheEnd = consumeIf('p');
5089 if (!consumeIf('E'))
5090 return nullptr;
5091 return make<SubobjectExpr>(
5092 Ty, Expr, Offset, popTrailingNodeArray(FromPosition: SelectorsBegin), OnePastTheEnd);
5093}
5094
5095template <typename Derived, typename Alloc>
5096Node *AbstractManglingParser<Derived, Alloc>::parseConstraintExpr() {
5097 // Within this expression, all enclosing template parameter lists are in
5098 // scope.
5099 ScopedOverride<bool> SaveIncompleteTemplateParameterTracking(
5100 HasIncompleteTemplateParameterTracking, true);
5101 return getDerived().parseExpr();
5102}
5103
5104template <typename Derived, typename Alloc>
5105Node *AbstractManglingParser<Derived, Alloc>::parseRequiresExpr() {
5106 NodeArray Params;
5107 if (consumeIf("rQ")) {
5108 // <expression> ::= rQ <bare-function-type> _ <requirement>+ E
5109 size_t ParamsBegin = Names.size();
5110 while (!consumeIf('_')) {
5111 Node *Type = getDerived().parseType();
5112 if (Type == nullptr)
5113 return nullptr;
5114 Names.push_back(Elem: Type);
5115 }
5116 Params = popTrailingNodeArray(FromPosition: ParamsBegin);
5117 } else if (!consumeIf("rq")) {
5118 // <expression> ::= rq <requirement>+ E
5119 return nullptr;
5120 }
5121
5122 size_t ReqsBegin = Names.size();
5123 do {
5124 Node *Constraint = nullptr;
5125 if (consumeIf('X')) {
5126 // <requirement> ::= X <expression> [N] [R <type-constraint>]
5127 Node *Expr = getDerived().parseExpr();
5128 if (Expr == nullptr)
5129 return nullptr;
5130 bool Noexcept = consumeIf('N');
5131 Node *TypeReq = nullptr;
5132 if (consumeIf('R')) {
5133 TypeReq = getDerived().parseName();
5134 if (TypeReq == nullptr)
5135 return nullptr;
5136 }
5137 Constraint = make<ExprRequirement>(Expr, Noexcept, TypeReq);
5138 } else if (consumeIf('T')) {
5139 // <requirement> ::= T <type>
5140 Node *Type = getDerived().parseType();
5141 if (Type == nullptr)
5142 return nullptr;
5143 Constraint = make<TypeRequirement>(Type);
5144 } else if (consumeIf('Q')) {
5145 // <requirement> ::= Q <constraint-expression>
5146 //
5147 // FIXME: We use <expression> instead of <constraint-expression>. Either
5148 // the requires expression is already inside a constraint expression, in
5149 // which case it makes no difference, or we're in a requires-expression
5150 // that might be partially-substituted, where the language behavior is
5151 // not yet settled and clang mangles after substitution.
5152 Node *NestedReq = getDerived().parseExpr();
5153 if (NestedReq == nullptr)
5154 return nullptr;
5155 Constraint = make<NestedRequirement>(NestedReq);
5156 }
5157 if (Constraint == nullptr)
5158 return nullptr;
5159 Names.push_back(Elem: Constraint);
5160 } while (!consumeIf('E'));
5161
5162 return make<RequiresExpr>(Params, popTrailingNodeArray(FromPosition: ReqsBegin));
5163}
5164
5165// <expression> ::= <unary operator-name> <expression>
5166// ::= <binary operator-name> <expression> <expression>
5167// ::= <ternary operator-name> <expression> <expression> <expression>
5168// ::= cl <expression>+ E # call
5169// ::= cp <base-unresolved-name> <expression>* E # (name) (expr-list), call that would use argument-dependent lookup but for the parentheses
5170// ::= cv <type> <expression> # conversion with one argument
5171// ::= cv <type> _ <expression>* E # conversion with a different number of arguments
5172// ::= [gs] nw <expression>* _ <type> E # new (expr-list) type
5173// ::= [gs] nw <expression>* _ <type> <initializer> # new (expr-list) type (init)
5174// ::= [gs] na <expression>* _ <type> E # new[] (expr-list) type
5175// ::= [gs] na <expression>* _ <type> <initializer> # new[] (expr-list) type (init)
5176// ::= [gs] dl <expression> # delete expression
5177// ::= [gs] da <expression> # delete[] expression
5178// ::= pp_ <expression> # prefix ++
5179// ::= mm_ <expression> # prefix --
5180// ::= ti <type> # typeid (type)
5181// ::= te <expression> # typeid (expression)
5182// ::= dc <type> <expression> # dynamic_cast<type> (expression)
5183// ::= sc <type> <expression> # static_cast<type> (expression)
5184// ::= cc <type> <expression> # const_cast<type> (expression)
5185// ::= rc <type> <expression> # reinterpret_cast<type> (expression)
5186// ::= st <type> # sizeof (a type)
5187// ::= sz <expression> # sizeof (an expression)
5188// ::= at <type> # alignof (a type)
5189// ::= az <expression> # alignof (an expression)
5190// ::= nx <expression> # noexcept (expression)
5191// ::= <template-param>
5192// ::= <function-param>
5193// ::= dt <expression> <unresolved-name> # expr.name
5194// ::= pt <expression> <unresolved-name> # expr->name
5195// ::= ds <expression> <expression> # expr.*expr
5196// ::= sZ <template-param> # size of a parameter pack
5197// ::= sZ <function-param> # size of a function parameter pack
5198// ::= sP <template-arg>* E # sizeof...(T), size of a captured template parameter pack from an alias template
5199// ::= sp <expression> # pack expansion
5200// ::= tw <expression> # throw expression
5201// ::= tr # throw with no operand (rethrow)
5202// ::= <unresolved-name> # f(p), N::f(p), ::f(p),
5203// # freestanding dependent name (e.g., T::x),
5204// # objectless nonstatic member reference
5205// ::= fL <binary-operator-name> <expression> <expression>
5206// ::= fR <binary-operator-name> <expression> <expression>
5207// ::= fl <binary-operator-name> <expression>
5208// ::= fr <binary-operator-name> <expression>
5209// ::= <expr-primary>
5210template <typename Derived, typename Alloc>
5211Node *AbstractManglingParser<Derived, Alloc>::parseExpr() {
5212 bool Global = consumeIf("gs");
5213
5214 const auto *Op = parseOperatorEncoding();
5215 if (Op) {
5216 auto Sym = Op->getSymbol();
5217 switch (Op->getKind()) {
5218 case OperatorInfo::Binary:
5219 // Binary operator: lhs @ rhs
5220 return getDerived().parseBinaryExpr(Sym, Op->getPrecedence());
5221 case OperatorInfo::Prefix:
5222 // Prefix unary operator: @ expr
5223 return getDerived().parsePrefixExpr(Sym, Op->getPrecedence());
5224 case OperatorInfo::Postfix: {
5225 // Postfix unary operator: expr @
5226 if (consumeIf('_'))
5227 return getDerived().parsePrefixExpr(Sym, Op->getPrecedence());
5228 Node *Ex = getDerived().parseExpr();
5229 if (Ex == nullptr)
5230 return nullptr;
5231 return make<PostfixExpr>(Ex, Sym, Op->getPrecedence());
5232 }
5233 case OperatorInfo::Array: {
5234 // Array Index: lhs [ rhs ]
5235 Node *Base = getDerived().parseExpr();
5236 if (Base == nullptr)
5237 return nullptr;
5238 Node *Index = getDerived().parseExpr();
5239 if (Index == nullptr)
5240 return nullptr;
5241 return make<ArraySubscriptExpr>(Base, Index, Op->getPrecedence());
5242 }
5243 case OperatorInfo::Member: {
5244 // Member access lhs @ rhs
5245 Node *LHS = getDerived().parseExpr();
5246 if (LHS == nullptr)
5247 return nullptr;
5248 Node *RHS = getDerived().parseExpr();
5249 if (RHS == nullptr)
5250 return nullptr;
5251 return make<MemberExpr>(LHS, Sym, RHS, Op->getPrecedence());
5252 }
5253 case OperatorInfo::New: {
5254 // New
5255 // # new (expr-list) type [(init)]
5256 // [gs] nw <expression>* _ <type> [pi <expression>*] E
5257 // # new[] (expr-list) type [(init)]
5258 // [gs] na <expression>* _ <type> [pi <expression>*] E
5259 size_t Exprs = Names.size();
5260 while (!consumeIf('_')) {
5261 Node *Ex = getDerived().parseExpr();
5262 if (Ex == nullptr)
5263 return nullptr;
5264 Names.push_back(Elem: Ex);
5265 }
5266 NodeArray ExprList = popTrailingNodeArray(FromPosition: Exprs);
5267 Node *Ty = getDerived().parseType();
5268 if (Ty == nullptr)
5269 return nullptr;
5270 bool HaveInits = consumeIf("pi");
5271 size_t InitsBegin = Names.size();
5272 while (!consumeIf('E')) {
5273 if (!HaveInits)
5274 return nullptr;
5275 Node *Init = getDerived().parseExpr();
5276 if (Init == nullptr)
5277 return Init;
5278 Names.push_back(Elem: Init);
5279 }
5280 NodeArray Inits = popTrailingNodeArray(FromPosition: InitsBegin);
5281 return make<NewExpr>(ExprList, Ty, Inits, Global,
5282 /*IsArray=*/Op->getFlag(), Op->getPrecedence());
5283 }
5284 case OperatorInfo::Del: {
5285 // Delete
5286 Node *Ex = getDerived().parseExpr();
5287 if (Ex == nullptr)
5288 return nullptr;
5289 return make<DeleteExpr>(Ex, Global, /*IsArray=*/Op->getFlag(),
5290 Op->getPrecedence());
5291 }
5292 case OperatorInfo::Call: {
5293 // Function Call
5294 Node *Callee = getDerived().parseExpr();
5295 if (Callee == nullptr)
5296 return nullptr;
5297 size_t ExprsBegin = Names.size();
5298 while (!consumeIf('E')) {
5299 Node *E = getDerived().parseExpr();
5300 if (E == nullptr)
5301 return nullptr;
5302 Names.push_back(Elem: E);
5303 }
5304 return make<CallExpr>(Callee, popTrailingNodeArray(FromPosition: ExprsBegin),
5305 /*IsParen=*/Op->getFlag(), Op->getPrecedence());
5306 }
5307 case OperatorInfo::CCast: {
5308 // C Cast: (type)expr
5309 Node *Ty;
5310 {
5311 ScopedOverride<bool> SaveTemp(TryToParseTemplateArgs, false);
5312 Ty = getDerived().parseType();
5313 }
5314 if (Ty == nullptr)
5315 return nullptr;
5316
5317 size_t ExprsBegin = Names.size();
5318 bool IsMany = consumeIf('_');
5319 while (!consumeIf('E')) {
5320 Node *E = getDerived().parseExpr();
5321 if (E == nullptr)
5322 return E;
5323 Names.push_back(Elem: E);
5324 if (!IsMany)
5325 break;
5326 }
5327 NodeArray Exprs = popTrailingNodeArray(FromPosition: ExprsBegin);
5328 if (!IsMany && Exprs.size() != 1)
5329 return nullptr;
5330 return make<ConversionExpr>(Ty, Exprs, Op->getPrecedence());
5331 }
5332 case OperatorInfo::Conditional: {
5333 // Conditional operator: expr ? expr : expr
5334 Node *Cond = getDerived().parseExpr();
5335 if (Cond == nullptr)
5336 return nullptr;
5337 Node *LHS = getDerived().parseExpr();
5338 if (LHS == nullptr)
5339 return nullptr;
5340 Node *RHS = getDerived().parseExpr();
5341 if (RHS == nullptr)
5342 return nullptr;
5343 return make<ConditionalExpr>(Cond, LHS, RHS, Op->getPrecedence());
5344 }
5345 case OperatorInfo::NamedCast: {
5346 // Named cast operation, @<type>(expr)
5347 Node *Ty = getDerived().parseType();
5348 if (Ty == nullptr)
5349 return nullptr;
5350 Node *Ex = getDerived().parseExpr();
5351 if (Ex == nullptr)
5352 return nullptr;
5353 return make<CastExpr>(Sym, Ty, Ex, Op->getPrecedence());
5354 }
5355 case OperatorInfo::OfIdOp: {
5356 // [sizeof/alignof/typeid] ( <type>|<expr> )
5357 Node *Arg =
5358 Op->getFlag() ? getDerived().parseType() : getDerived().parseExpr();
5359 if (!Arg)
5360 return nullptr;
5361 return make<EnclosingExpr>(Sym, Arg, Op->getPrecedence());
5362 }
5363 case OperatorInfo::NameOnly: {
5364 // Not valid as an expression operand.
5365 return nullptr;
5366 }
5367 }
5368 DEMANGLE_UNREACHABLE;
5369 }
5370
5371 if (numLeft() < 2)
5372 return nullptr;
5373
5374 if (look() == 'L')
5375 return getDerived().parseExprPrimary();
5376 if (look() == 'T')
5377 return getDerived().parseTemplateParam();
5378 if (look() == 'f') {
5379 // Disambiguate a fold expression from a <function-param>.
5380 if (look(Lookahead: 1) == 'p' || (look(Lookahead: 1) == 'L' && std::isdigit(c: look(Lookahead: 2))))
5381 return getDerived().parseFunctionParam();
5382 return getDerived().parseFoldExpr();
5383 }
5384 if (consumeIf("il")) {
5385 size_t InitsBegin = Names.size();
5386 while (!consumeIf('E')) {
5387 Node *E = getDerived().parseBracedExpr();
5388 if (E == nullptr)
5389 return nullptr;
5390 Names.push_back(Elem: E);
5391 }
5392 return make<InitListExpr>(nullptr, popTrailingNodeArray(FromPosition: InitsBegin));
5393 }
5394 if (consumeIf("mc"))
5395 return parsePointerToMemberConversionExpr(Prec: Node::Prec::Unary);
5396 if (consumeIf("nx")) {
5397 Node *Ex = getDerived().parseExpr();
5398 if (Ex == nullptr)
5399 return Ex;
5400 return make<EnclosingExpr>("noexcept ", Ex, Node::Prec::Unary);
5401 }
5402 if (look() == 'r' && (look(Lookahead: 1) == 'q' || look(Lookahead: 1) == 'Q'))
5403 return parseRequiresExpr();
5404 if (consumeIf("so"))
5405 return parseSubobjectExpr();
5406 if (consumeIf("sp")) {
5407 Node *Child = getDerived().parseExpr();
5408 if (Child == nullptr)
5409 return nullptr;
5410 return make<ParameterPackExpansion>(Child);
5411 }
5412 if (consumeIf("sy")) {
5413 Node *Pattern = look() == 'T' ? getDerived().parseTemplateParam()
5414 : getDerived().parseFunctionParam();
5415 if (Pattern == nullptr)
5416 return nullptr;
5417 Node *Index = getDerived().parseExpr();
5418 if (Index == nullptr)
5419 return nullptr;
5420 return make<PackIndexing>(Pattern, Index);
5421 }
5422 if (consumeIf("sZ")) {
5423 if (look() == 'T') {
5424 Node *R = getDerived().parseTemplateParam();
5425 if (R == nullptr)
5426 return nullptr;
5427 return make<SizeofParamPackExpr>(R);
5428 }
5429 Node *FP = getDerived().parseFunctionParam();
5430 if (FP == nullptr)
5431 return nullptr;
5432 return make<EnclosingExpr>("sizeof... ", FP);
5433 }
5434 if (consumeIf("sP")) {
5435 size_t ArgsBegin = Names.size();
5436 while (!consumeIf('E')) {
5437 Node *Arg = getDerived().parseTemplateArg();
5438 if (Arg == nullptr)
5439 return nullptr;
5440 Names.push_back(Elem: Arg);
5441 }
5442 auto *Pack = make<NodeArrayNode>(popTrailingNodeArray(FromPosition: ArgsBegin));
5443 if (!Pack)
5444 return nullptr;
5445 return make<EnclosingExpr>("sizeof... ", Pack);
5446 }
5447 if (consumeIf("tl")) {
5448 Node *Ty = getDerived().parseType();
5449 if (Ty == nullptr)
5450 return nullptr;
5451 size_t InitsBegin = Names.size();
5452 while (!consumeIf('E')) {
5453 Node *E = getDerived().parseBracedExpr();
5454 if (E == nullptr)
5455 return nullptr;
5456 Names.push_back(Elem: E);
5457 }
5458 return make<InitListExpr>(Ty, popTrailingNodeArray(FromPosition: InitsBegin));
5459 }
5460 if (consumeIf("tr"))
5461 return make<NameType>("throw");
5462 if (consumeIf("tw")) {
5463 Node *Ex = getDerived().parseExpr();
5464 if (Ex == nullptr)
5465 return nullptr;
5466 return make<ThrowExpr>(Ex);
5467 }
5468 if (consumeIf('u')) {
5469 Node *Name = getDerived().parseSourceName(/*NameState=*/nullptr);
5470 if (!Name)
5471 return nullptr;
5472 // Special case legacy __uuidof mangling. The 't' and 'z' appear where the
5473 // standard encoding expects a <template-arg>, and would be otherwise be
5474 // interpreted as <type> node 'short' or 'ellipsis'. However, neither
5475 // __uuidof(short) nor __uuidof(...) can actually appear, so there is no
5476 // actual conflict here.
5477 bool IsUUID = false;
5478 Node *UUID = nullptr;
5479 if (Name->getBaseName() == "__uuidof") {
5480 if (consumeIf('t')) {
5481 UUID = getDerived().parseType();
5482 IsUUID = true;
5483 } else if (consumeIf('z')) {
5484 UUID = getDerived().parseExpr();
5485 IsUUID = true;
5486 }
5487 }
5488 size_t ExprsBegin = Names.size();
5489 if (IsUUID) {
5490 if (UUID == nullptr)
5491 return nullptr;
5492 Names.push_back(Elem: UUID);
5493 } else {
5494 while (!consumeIf('E')) {
5495 Node *E = getDerived().parseTemplateArg();
5496 if (E == nullptr)
5497 return E;
5498 Names.push_back(Elem: E);
5499 }
5500 }
5501 return make<CallExpr>(Name, popTrailingNodeArray(FromPosition: ExprsBegin),
5502 /*IsParen=*/false, Node::Prec::Postfix);
5503 }
5504
5505 // Only unresolved names remain.
5506 return getDerived().parseUnresolvedName(Global);
5507}
5508
5509// <call-offset> ::= h <nv-offset> _
5510// ::= v <v-offset> _
5511//
5512// <nv-offset> ::= <offset number>
5513// # non-virtual base override
5514//
5515// <v-offset> ::= <offset number> _ <virtual offset number>
5516// # virtual base override, with vcall offset
5517template <typename Alloc, typename Derived>
5518bool AbstractManglingParser<Alloc, Derived>::parseCallOffset() {
5519 // Just scan through the call offset, we never add this information into the
5520 // output.
5521 if (consumeIf('h'))
5522 return parseNumber(AllowNegative: true).empty() || !consumeIf('_');
5523 if (consumeIf('v'))
5524 return parseNumber(AllowNegative: true).empty() || !consumeIf('_') ||
5525 parseNumber(AllowNegative: true).empty() || !consumeIf('_');
5526 return true;
5527}
5528
5529// <special-name> ::= TV <type> # virtual table
5530// ::= TT <type> # VTT structure (construction vtable index)
5531// ::= TI <type> # typeinfo structure
5532// ::= TS <type> # typeinfo name (null-terminated byte string)
5533// ::= Tc <call-offset> <call-offset> <base encoding>
5534// # base is the nominal target function of thunk
5535// # first call-offset is 'this' adjustment
5536// # second call-offset is result adjustment
5537// ::= T <call-offset> <base encoding>
5538// # base is the nominal target function of thunk
5539// # Guard variable for one-time initialization
5540// ::= GV <object name>
5541// # No <type>
5542// ::= TW <object name> # Thread-local wrapper
5543// ::= TH <object name> # Thread-local initialization
5544// ::= GR <object name> _ # First temporary
5545// ::= GR <object name> <seq-id> _ # Subsequent temporaries
5546// # construction vtable for second-in-first
5547// extension ::= TC <first type> <number> _ <second type>
5548// extension ::= GR <object name> # reference temporary for object
5549// extension ::= GI <module name> # module global initializer
5550template <typename Derived, typename Alloc>
5551Node *AbstractManglingParser<Derived, Alloc>::parseSpecialName() {
5552 switch (look()) {
5553 case 'T':
5554 switch (look(Lookahead: 1)) {
5555 // TA <template-arg> # template parameter object
5556 //
5557 // Not yet in the spec: https://github.com/itanium-cxx-abi/cxx-abi/issues/63
5558 case 'A': {
5559 First += 2;
5560 Node *Arg = getDerived().parseTemplateArg();
5561 if (Arg == nullptr)
5562 return nullptr;
5563 return make<SpecialName>("template parameter object for ", Arg);
5564 }
5565 // TV <type> # virtual table
5566 case 'V': {
5567 First += 2;
5568 Node *Ty = getDerived().parseType();
5569 if (Ty == nullptr)
5570 return nullptr;
5571 return make<SpecialName>("vtable for ", Ty);
5572 }
5573 // TT <type> # VTT structure (construction vtable index)
5574 case 'T': {
5575 First += 2;
5576 Node *Ty = getDerived().parseType();
5577 if (Ty == nullptr)
5578 return nullptr;
5579 return make<SpecialName>("VTT for ", Ty);
5580 }
5581 // TI <type> # typeinfo structure
5582 case 'I': {
5583 First += 2;
5584 Node *Ty = getDerived().parseType();
5585 if (Ty == nullptr)
5586 return nullptr;
5587 return make<SpecialName>("typeinfo for ", Ty);
5588 }
5589 // TS <type> # typeinfo name (null-terminated byte string)
5590 case 'S': {
5591 First += 2;
5592 Node *Ty = getDerived().parseType();
5593 if (Ty == nullptr)
5594 return nullptr;
5595 return make<SpecialName>("typeinfo name for ", Ty);
5596 }
5597 // Tc <call-offset> <call-offset> <base encoding>
5598 case 'c': {
5599 First += 2;
5600 if (parseCallOffset() || parseCallOffset())
5601 return nullptr;
5602 Node *Encoding = getDerived().parseEncoding();
5603 if (Encoding == nullptr)
5604 return nullptr;
5605 return make<SpecialName>("covariant return thunk to ", Encoding);
5606 }
5607 // extension ::= TC <first type> <number> _ <second type>
5608 // # construction vtable for second-in-first
5609 case 'C': {
5610 First += 2;
5611 Node *FirstType = getDerived().parseType();
5612 if (FirstType == nullptr)
5613 return nullptr;
5614 if (parseNumber(AllowNegative: true).empty() || !consumeIf('_'))
5615 return nullptr;
5616 Node *SecondType = getDerived().parseType();
5617 if (SecondType == nullptr)
5618 return nullptr;
5619 return make<CtorVtableSpecialName>(SecondType, FirstType);
5620 }
5621 // TW <object name> # Thread-local wrapper
5622 case 'W': {
5623 First += 2;
5624 Node *Name = getDerived().parseName();
5625 if (Name == nullptr)
5626 return nullptr;
5627 return make<SpecialName>("thread-local wrapper routine for ", Name);
5628 }
5629 // TH <object name> # Thread-local initialization
5630 case 'H': {
5631 First += 2;
5632 Node *Name = getDerived().parseName();
5633 if (Name == nullptr)
5634 return nullptr;
5635 return make<SpecialName>("thread-local initialization routine for ", Name);
5636 }
5637 // T <call-offset> <base encoding>
5638 default: {
5639 ++First;
5640 bool IsVirt = look() == 'v';
5641 if (parseCallOffset())
5642 return nullptr;
5643 Node *BaseEncoding = getDerived().parseEncoding();
5644 if (BaseEncoding == nullptr)
5645 return nullptr;
5646 if (IsVirt)
5647 return make<SpecialName>("virtual thunk to ", BaseEncoding);
5648 else
5649 return make<SpecialName>("non-virtual thunk to ", BaseEncoding);
5650 }
5651 }
5652 case 'G':
5653 switch (look(Lookahead: 1)) {
5654 // GV <object name> # Guard variable for one-time initialization
5655 case 'V': {
5656 First += 2;
5657 Node *Name = getDerived().parseName();
5658 if (Name == nullptr)
5659 return nullptr;
5660 return make<SpecialName>("guard variable for ", Name);
5661 }
5662 // GR <object name> # reference temporary for object
5663 // GR <object name> _ # First temporary
5664 // GR <object name> <seq-id> _ # Subsequent temporaries
5665 case 'R': {
5666 First += 2;
5667 Node *Name = getDerived().parseName();
5668 if (Name == nullptr)
5669 return nullptr;
5670 size_t Count;
5671 bool ParsedSeqId = !parseSeqId(Out: &Count);
5672 if (!consumeIf('_') && ParsedSeqId)
5673 return nullptr;
5674 return make<SpecialName>("reference temporary for ", Name);
5675 }
5676 // GI <module-name> v
5677 case 'I': {
5678 First += 2;
5679 ModuleName *Module = nullptr;
5680 if (getDerived().parseModuleNameOpt(Module))
5681 return nullptr;
5682 if (Module == nullptr)
5683 return nullptr;
5684 return make<SpecialName>("initializer for module ", Module);
5685 }
5686 }
5687 }
5688 return nullptr;
5689}
5690
5691// <encoding> ::= <function name> <bare-function-type>
5692// [`Q` <requires-clause expr>]
5693// ::= <data name>
5694// ::= <special-name>
5695template <typename Derived, typename Alloc>
5696Node *AbstractManglingParser<Derived, Alloc>::parseEncoding(bool ParseParams) {
5697 // The template parameters of an encoding are unrelated to those of the
5698 // enclosing context.
5699 SaveTemplateParams SaveTemplateParamsScope(this);
5700
5701 if (look() == 'G' || look() == 'T')
5702 return getDerived().parseSpecialName();
5703
5704 auto IsEndOfEncoding = [&] {
5705 // The set of chars that can potentially follow an <encoding> (none of which
5706 // can start a <type>). Enumerating these allows us to avoid speculative
5707 // parsing.
5708 return numLeft() == 0 || look() == 'E' || look() == '.' || look() == '_';
5709 };
5710
5711 NameState NameInfo(this);
5712 Node *Name = getDerived().parseName(&NameInfo);
5713 if (Name == nullptr)
5714 return nullptr;
5715
5716 if (resolveForwardTemplateRefs(State&: NameInfo))
5717 return nullptr;
5718
5719 if (IsEndOfEncoding())
5720 return Name;
5721
5722 // ParseParams may be false at the top level only, when called from parse().
5723 // For example in the mangled name _Z3fooILZ3BarEET_f, ParseParams may be
5724 // false when demangling 3fooILZ3BarEET_f but is always true when demangling
5725 // 3Bar.
5726 if (!ParseParams) {
5727 while (consume())
5728 ;
5729 return Name;
5730 }
5731
5732 Node *Attrs = nullptr;
5733 if (consumeIf("Ua9enable_ifI")) {
5734 size_t BeforeArgs = Names.size();
5735 while (!consumeIf('E')) {
5736 Node *Arg = getDerived().parseTemplateArg();
5737 if (Arg == nullptr)
5738 return nullptr;
5739 Names.push_back(Elem: Arg);
5740 }
5741 Attrs = make<EnableIfAttr>(popTrailingNodeArray(FromPosition: BeforeArgs));
5742 if (!Attrs)
5743 return nullptr;
5744 }
5745
5746 Node *ReturnType = nullptr;
5747 if (!NameInfo.CtorDtorConversion && NameInfo.EndsWithTemplateArgs) {
5748 ReturnType = getDerived().parseType();
5749 if (ReturnType == nullptr)
5750 return nullptr;
5751 }
5752
5753 NodeArray Params;
5754 if (!consumeIf('v')) {
5755 size_t ParamsBegin = Names.size();
5756 do {
5757 Node *Ty = getDerived().parseType();
5758 if (Ty == nullptr)
5759 return nullptr;
5760
5761 const bool IsFirstParam = ParamsBegin == Names.size();
5762 if (NameInfo.HasExplicitObjectParameter && IsFirstParam)
5763 Ty = make<ExplicitObjectParameter>(Ty);
5764
5765 if (Ty == nullptr)
5766 return nullptr;
5767
5768 Names.push_back(Elem: Ty);
5769 } while (!IsEndOfEncoding() && look() != 'Q');
5770 Params = popTrailingNodeArray(FromPosition: ParamsBegin);
5771 }
5772
5773 Node *Requires = nullptr;
5774 if (consumeIf('Q')) {
5775 Requires = getDerived().parseConstraintExpr();
5776 if (!Requires)
5777 return nullptr;
5778 }
5779
5780 return make<FunctionEncoding>(ReturnType, Name, Params, Attrs, Requires,
5781 NameInfo.CVQualifiers,
5782 NameInfo.ReferenceQualifier);
5783}
5784
5785template <class Float>
5786struct FloatData;
5787
5788template <>
5789struct FloatData<float>
5790{
5791 static const size_t mangled_size = 8;
5792 static const size_t max_demangled_size = 24;
5793 static constexpr const char* spec = "%af";
5794};
5795
5796template <>
5797struct FloatData<double>
5798{
5799 static const size_t mangled_size = 16;
5800 static const size_t max_demangled_size = 32;
5801 static constexpr const char* spec = "%a";
5802};
5803
5804template <>
5805struct FloatData<long double>
5806{
5807#if __LDBL_MANT_DIG__ == 113 || __LDBL_MANT_DIG__ == 106
5808 static const size_t mangled_size = 32;
5809#elif __LDBL_MANT_DIG__ == 53 || defined(_MSC_VER)
5810 // MSVC doesn't define __LDBL_MANT_DIG__, but it has long double equal to
5811 // regular double on all current architectures.
5812 static const size_t mangled_size = 16;
5813#elif __LDBL_MANT_DIG__ == 64
5814 static const size_t mangled_size = 20;
5815#else
5816#error Unknown size for __LDBL_MANT_DIG__
5817#endif
5818 // `-0x1.ffffffffffffffffffffffffffffp+16383` + 'L' + '\0' == 42 bytes.
5819 // 28 'f's * 4 bits == 112 bits, which is the number of mantissa bits.
5820 // Negatives are one character longer than positives.
5821 // `0x1.` and `p` are constant, and exponents `+16383` and `-16382` are the
5822 // same length. 1 sign bit, 112 mantissa bits, and 15 exponent bits == 128.
5823 static const size_t max_demangled_size = 42;
5824 static constexpr const char *spec = "%LaL";
5825};
5826
5827template <typename Alloc, typename Derived>
5828template <class Float>
5829Node *AbstractManglingParser<Alloc, Derived>::parseFloatingLiteral() {
5830 const size_t N = FloatData<Float>::mangled_size;
5831 if (numLeft() <= N)
5832 return nullptr;
5833 std::string_view Data(First, N);
5834 for (char C : Data)
5835 if (!(C >= '0' && C <= '9') && !(C >= 'a' && C <= 'f'))
5836 return nullptr;
5837 First += N;
5838 if (!consumeIf('E'))
5839 return nullptr;
5840 return make<FloatLiteralImpl<Float>>(Data);
5841}
5842
5843// <seq-id> ::= <0-9A-Z>+
5844template <typename Alloc, typename Derived>
5845bool AbstractManglingParser<Alloc, Derived>::parseSeqId(size_t *Out) {
5846 if (!(look() >= '0' && look() <= '9') &&
5847 !(look() >= 'A' && look() <= 'Z'))
5848 return true;
5849
5850 size_t Id = 0;
5851 while (true) {
5852 if (look() >= '0' && look() <= '9') {
5853 Id *= 36;
5854 Id += static_cast<size_t>(look() - '0');
5855 } else if (look() >= 'A' && look() <= 'Z') {
5856 Id *= 36;
5857 Id += static_cast<size_t>(look() - 'A') + 10;
5858 } else {
5859 *Out = Id;
5860 return false;
5861 }
5862 ++First;
5863 }
5864}
5865
5866// <substitution> ::= S <seq-id> _
5867// ::= S_
5868// <substitution> ::= Sa # ::std::allocator
5869// <substitution> ::= Sb # ::std::basic_string
5870// <substitution> ::= Ss # ::std::basic_string < char,
5871// ::std::char_traits<char>,
5872// ::std::allocator<char> >
5873// <substitution> ::= Si # ::std::basic_istream<char, std::char_traits<char> >
5874// <substitution> ::= So # ::std::basic_ostream<char, std::char_traits<char> >
5875// <substitution> ::= Sd # ::std::basic_iostream<char, std::char_traits<char> >
5876// The St case is handled specially in parseNestedName.
5877template <typename Derived, typename Alloc>
5878Node *AbstractManglingParser<Derived, Alloc>::parseSubstitution() {
5879 if (!consumeIf('S'))
5880 return nullptr;
5881
5882 if (look() >= 'a' && look() <= 'z') {
5883 SpecialSubKind Kind;
5884 switch (look()) {
5885 case 'a':
5886 Kind = SpecialSubKind::allocator;
5887 break;
5888 case 'b':
5889 Kind = SpecialSubKind::basic_string;
5890 break;
5891 case 'd':
5892 Kind = SpecialSubKind::iostream;
5893 break;
5894 case 'i':
5895 Kind = SpecialSubKind::istream;
5896 break;
5897 case 'o':
5898 Kind = SpecialSubKind::ostream;
5899 break;
5900 case 's':
5901 Kind = SpecialSubKind::string;
5902 break;
5903 default:
5904 return nullptr;
5905 }
5906 ++First;
5907 auto *SpecialSub = make<SpecialSubstitution>(Kind);
5908 if (!SpecialSub)
5909 return nullptr;
5910
5911 // Itanium C++ ABI 5.1.2: If a name that would use a built-in <substitution>
5912 // has ABI tags, the tags are appended to the substitution; the result is a
5913 // substitutable component.
5914 Node *WithTags = getDerived().parseAbiTags(SpecialSub);
5915 if (WithTags != SpecialSub) {
5916 Subs.push_back(Elem: WithTags);
5917 SpecialSub = WithTags;
5918 }
5919 return SpecialSub;
5920 }
5921
5922 // ::= S_
5923 if (consumeIf('_')) {
5924 if (Subs.empty())
5925 return nullptr;
5926 return Subs[0];
5927 }
5928
5929 // ::= S <seq-id> _
5930 size_t Index = 0;
5931 if (parseSeqId(Out: &Index))
5932 return nullptr;
5933 ++Index;
5934 if (!consumeIf('_') || Index >= Subs.size())
5935 return nullptr;
5936 return Subs[Index];
5937}
5938
5939// <template-param> ::= T_ # first template parameter
5940// ::= T <parameter-2 non-negative number> _
5941// ::= TL <level-1> __
5942// ::= TL <level-1> _ <parameter-2 non-negative number> _
5943template <typename Derived, typename Alloc>
5944Node *AbstractManglingParser<Derived, Alloc>::parseTemplateParam() {
5945 const char *Begin = First;
5946 if (!consumeIf('T'))
5947 return nullptr;
5948
5949 size_t Level = 0;
5950 if (consumeIf('L')) {
5951 if (parsePositiveInteger(Out: &Level))
5952 return nullptr;
5953 ++Level;
5954 if (!consumeIf('_'))
5955 return nullptr;
5956 }
5957
5958 size_t Index = 0;
5959 if (!consumeIf('_')) {
5960 if (parsePositiveInteger(Out: &Index))
5961 return nullptr;
5962 ++Index;
5963 if (!consumeIf('_'))
5964 return nullptr;
5965 }
5966
5967 // We don't track enclosing template parameter levels well enough to reliably
5968 // substitute them all within a <constraint-expression>, so print the
5969 // parameter numbering instead for now.
5970 // TODO: Track all enclosing template parameters and substitute them here.
5971 if (HasIncompleteTemplateParameterTracking) {
5972 return make<NameType>(std::string_view(Begin, First - 1 - Begin));
5973 }
5974
5975 // If we're in a context where this <template-param> refers to a
5976 // <template-arg> further ahead in the mangled name (currently just conversion
5977 // operator types), then we should only look it up in the right context.
5978 // This can only happen at the outermost level.
5979 if (PermitForwardTemplateReferences && Level == 0) {
5980 Node *ForwardRef = make<ForwardTemplateReference>(Index);
5981 if (!ForwardRef)
5982 return nullptr;
5983 DEMANGLE_ASSERT(ForwardRef->getKind() == Node::KForwardTemplateReference,
5984 "");
5985 ForwardTemplateRefs.push_back(
5986 Elem: static_cast<ForwardTemplateReference *>(ForwardRef));
5987 return ForwardRef;
5988 }
5989
5990 if (Level >= TemplateParams.size() || !TemplateParams[Level] ||
5991 Index >= TemplateParams[Level]->size()) {
5992 // Itanium ABI 5.1.8: In a generic lambda, uses of auto in the parameter
5993 // list are mangled as the corresponding artificial template type parameter.
5994 if (ParsingLambdaParamsAtLevel == Level && Level <= TemplateParams.size()) {
5995 // This will be popped by the ScopedTemplateParamList in
5996 // parseUnnamedTypeName.
5997 if (Level == TemplateParams.size())
5998 TemplateParams.push_back(Elem: nullptr);
5999 return make<NameType>("auto");
6000 }
6001
6002 return nullptr;
6003 }
6004
6005 return (*TemplateParams[Level])[Index];
6006}
6007
6008// <template-param-decl> ::= Ty # type parameter
6009// ::= Tk <concept name> [<template-args>] # constrained type parameter
6010// ::= Tn <type> # non-type parameter
6011// ::= Tt <template-param-decl>* E # template parameter
6012// ::= Tp <template-param-decl> # parameter pack
6013template <typename Derived, typename Alloc>
6014Node *AbstractManglingParser<Derived, Alloc>::parseTemplateParamDecl(
6015 TemplateParamList *Params) {
6016 auto InventTemplateParamName = [&](TemplateParamKind Kind) {
6017 unsigned Index = NumSyntheticTemplateParameters[(int)Kind]++;
6018 Node *N = make<SyntheticTemplateParamName>(Kind, Index);
6019 if (N && Params)
6020 Params->push_back(Elem: N);
6021 return N;
6022 };
6023
6024 if (consumeIf("Ty")) {
6025 Node *Name = InventTemplateParamName(TemplateParamKind::Type);
6026 if (!Name)
6027 return nullptr;
6028 return make<TypeTemplateParamDecl>(Name);
6029 }
6030
6031 if (consumeIf("Tk")) {
6032 // We don't track enclosing template parameter levels well enough to
6033 // reliably demangle template parameter substitutions, so print an arbitrary
6034 // string in place of a parameter for now.
6035 // TODO: Track all enclosing template parameters and demangle substitutions.
6036 ScopedOverride<bool> SaveIncompleteTemplateParameterTrackingExpr(
6037 HasIncompleteTemplateParameterTracking, true);
6038 Node *Constraint = getDerived().parseName();
6039 if (!Constraint)
6040 return nullptr;
6041 Node *Name = InventTemplateParamName(TemplateParamKind::Type);
6042 if (!Name)
6043 return nullptr;
6044 return make<ConstrainedTypeTemplateParamDecl>(Constraint, Name);
6045 }
6046
6047 if (consumeIf("Tn")) {
6048 Node *Name = InventTemplateParamName(TemplateParamKind::NonType);
6049 if (!Name)
6050 return nullptr;
6051 Node *Type = parseType();
6052 if (!Type)
6053 return nullptr;
6054 return make<NonTypeTemplateParamDecl>(Name, Type);
6055 }
6056
6057 if (consumeIf("Tt")) {
6058 Node *Name = InventTemplateParamName(TemplateParamKind::Template);
6059 if (!Name)
6060 return nullptr;
6061 size_t ParamsBegin = Names.size();
6062 ScopedTemplateParamList TemplateTemplateParamParams(this);
6063 Node *Requires = nullptr;
6064 while (!consumeIf('E')) {
6065 Node *P = parseTemplateParamDecl(Params: TemplateTemplateParamParams.params());
6066 if (!P)
6067 return nullptr;
6068 Names.push_back(Elem: P);
6069 if (consumeIf('Q')) {
6070 Requires = getDerived().parseConstraintExpr();
6071 if (Requires == nullptr || !consumeIf('E'))
6072 return nullptr;
6073 break;
6074 }
6075 }
6076 NodeArray InnerParams = popTrailingNodeArray(FromPosition: ParamsBegin);
6077 return make<TemplateTemplateParamDecl>(Name, InnerParams, Requires);
6078 }
6079
6080 if (consumeIf("Tp")) {
6081 Node *P = parseTemplateParamDecl(Params);
6082 if (!P)
6083 return nullptr;
6084 return make<TemplateParamPackDecl>(P);
6085 }
6086
6087 return nullptr;
6088}
6089
6090// <template-arg> ::= <type> # type or template
6091// ::= X <expression> E # expression
6092// ::= <expr-primary> # simple expressions
6093// ::= J <template-arg>* E # argument pack
6094// ::= LZ <encoding> E # extension
6095// ::= <template-param-decl> <template-arg>
6096template <typename Derived, typename Alloc>
6097Node *AbstractManglingParser<Derived, Alloc>::parseTemplateArg() {
6098 switch (look()) {
6099 case 'X': {
6100 ++First;
6101 Node *Arg = getDerived().parseExpr();
6102 if (Arg == nullptr || !consumeIf('E'))
6103 return nullptr;
6104 return Arg;
6105 }
6106 case 'J': {
6107 ++First;
6108 size_t ArgsBegin = Names.size();
6109 while (!consumeIf('E')) {
6110 Node *Arg = getDerived().parseTemplateArg();
6111 if (Arg == nullptr)
6112 return nullptr;
6113 Names.push_back(Elem: Arg);
6114 }
6115 NodeArray Args = popTrailingNodeArray(FromPosition: ArgsBegin);
6116 return make<TemplateArgumentPack>(Args);
6117 }
6118 case 'L': {
6119 // ::= LZ <encoding> E # extension
6120 if (look(Lookahead: 1) == 'Z') {
6121 First += 2;
6122 Node *Arg = getDerived().parseEncoding();
6123 if (Arg == nullptr || !consumeIf('E'))
6124 return nullptr;
6125 return Arg;
6126 }
6127 // ::= <expr-primary> # simple expressions
6128 return getDerived().parseExprPrimary();
6129 }
6130 case 'T': {
6131 // Either <template-param> or a <template-param-decl> <template-arg>.
6132 if (!getDerived().isTemplateParamDecl())
6133 return getDerived().parseType();
6134 Node *Param = getDerived().parseTemplateParamDecl(nullptr);
6135 if (!Param)
6136 return nullptr;
6137 Node *Arg = getDerived().parseTemplateArg();
6138 if (!Arg)
6139 return nullptr;
6140 return make<TemplateParamQualifiedArg>(Param, Arg);
6141 }
6142 default:
6143 return getDerived().parseType();
6144 }
6145}
6146
6147// <template-args> ::= I <template-arg>* [Q <requires-clause expr>] E
6148// extension, the abi says <template-arg>+
6149template <typename Derived, typename Alloc>
6150Node *
6151AbstractManglingParser<Derived, Alloc>::parseTemplateArgs(bool TagTemplates) {
6152 if (!consumeIf('I'))
6153 return nullptr;
6154
6155 // <template-params> refer to the innermost <template-args>. Clear out any
6156 // outer args that we may have inserted into TemplateParams.
6157 if (TagTemplates) {
6158 TemplateParams.clear();
6159 TemplateParams.push_back(Elem: &OuterTemplateParams);
6160 OuterTemplateParams.clear();
6161 }
6162
6163 size_t ArgsBegin = Names.size();
6164 Node *Requires = nullptr;
6165 while (!consumeIf('E')) {
6166 if (TagTemplates) {
6167 Node *Arg = getDerived().parseTemplateArg();
6168 if (Arg == nullptr)
6169 return nullptr;
6170 Names.push_back(Elem: Arg);
6171 Node *TableEntry = Arg;
6172 if (Arg->getKind() == Node::KTemplateParamQualifiedArg) {
6173 TableEntry =
6174 static_cast<TemplateParamQualifiedArg *>(TableEntry)->getArg();
6175 }
6176 if (Arg->getKind() == Node::KTemplateArgumentPack) {
6177 TableEntry = make<ParameterPack>(
6178 static_cast<TemplateArgumentPack*>(TableEntry)->getElements());
6179 if (!TableEntry)
6180 return nullptr;
6181 }
6182 OuterTemplateParams.push_back(Elem: TableEntry);
6183 } else {
6184 Node *Arg = getDerived().parseTemplateArg();
6185 if (Arg == nullptr)
6186 return nullptr;
6187 Names.push_back(Elem: Arg);
6188 }
6189 if (consumeIf('Q')) {
6190 Requires = getDerived().parseConstraintExpr();
6191 if (!Requires || !consumeIf('E'))
6192 return nullptr;
6193 break;
6194 }
6195 }
6196 return make<TemplateArgs>(popTrailingNodeArray(FromPosition: ArgsBegin), Requires);
6197}
6198
6199// <mangled-name> ::= _Z <encoding>
6200// ::= <type>
6201// extension ::= ___Z <encoding> _block_invoke
6202// extension ::= ___Z <encoding> _block_invoke<decimal-digit>+
6203// extension ::= ___Z <encoding> _block_invoke_<decimal-digit>+
6204// extension ::= __alloc_token__Z <encoding>
6205// extension ::= __alloc_token_<decimal-digit>+__Z <encoding>
6206template <typename Derived, typename Alloc>
6207Node *AbstractManglingParser<Derived, Alloc>::parse(bool ParseParams) {
6208 bool AllocToken = consumeIf("__alloc_token_");
6209 if (AllocToken) {
6210 const char *Saved = First;
6211 if (parseNumber().empty() || !consumeIf('_'))
6212 First = Saved;
6213 }
6214
6215 if (consumeIf("_Z") || consumeIf("__Z")) {
6216 Node *Encoding = getDerived().parseEncoding(ParseParams);
6217 if (Encoding == nullptr)
6218 return nullptr;
6219 if (look() == '.') {
6220 Encoding =
6221 make<DotSuffix>(Encoding, std::string_view(First, Last - First));
6222 First = Last;
6223 }
6224 if (AllocToken)
6225 Encoding = make<DotSuffix>(Encoding, ".alloc_token");
6226 if (numLeft() != 0)
6227 return nullptr;
6228 return Encoding;
6229 }
6230
6231 if (consumeIf("___Z") || consumeIf("____Z")) {
6232 Node *Encoding = getDerived().parseEncoding(ParseParams);
6233 if (Encoding == nullptr || !consumeIf("_block_invoke"))
6234 return nullptr;
6235 bool RequireNumber = consumeIf('_');
6236 if (parseNumber().empty() && RequireNumber)
6237 return nullptr;
6238 if (look() == '.')
6239 First = Last;
6240 if (numLeft() != 0)
6241 return nullptr;
6242 return make<SpecialName>("invocation function for block in ", Encoding);
6243 }
6244
6245 Node *Ty = getDerived().parseType();
6246 if (numLeft() != 0)
6247 return nullptr;
6248 return Ty;
6249}
6250
6251template <typename Alloc>
6252struct ManglingParser : AbstractManglingParser<ManglingParser<Alloc>, Alloc> {
6253 using AbstractManglingParser<ManglingParser<Alloc>,
6254 Alloc>::AbstractManglingParser;
6255};
6256
6257inline void OutputBuffer::printLeft(const Node &N) { N.printLeft(*this); }
6258
6259inline void OutputBuffer::printRight(const Node &N) { N.printRight(*this); }
6260
6261DEMANGLE_NAMESPACE_END
6262
6263#if defined(__clang__)
6264#pragma clang diagnostic pop
6265#endif
6266
6267#endif // DEMANGLE_ITANIUMDEMANGLE_H
6268