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