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 TemplateArgs final : public Node {
1541 NodeArray Params;
1542 Node *Requires;
1543
1544public:
1545 TemplateArgs(NodeArray Params_, Node *Requires_)
1546 : Node(KTemplateArgs), Params(Params_), Requires(Requires_) {}
1547
1548 template<typename Fn> void match(Fn F) const { F(Params, Requires); }
1549
1550 NodeArray getParams() { return Params; }
1551
1552 void printLeft(OutputBuffer &OB) const override {
1553 ScopedOverride<bool> LT(OB.TemplateTracker.InsideTemplate, true);
1554 OB += "<";
1555 Params.printWithComma(OB);
1556 OB += ">";
1557 // Don't print the requires clause to keep the output simple.
1558 }
1559};
1560
1561/// A forward-reference to a template argument that was not known at the point
1562/// where the template parameter name was parsed in a mangling.
1563///
1564/// This is created when demangling the name of a specialization of a
1565/// conversion function template:
1566///
1567/// \code
1568/// struct A {
1569/// template<typename T> operator T*();
1570/// };
1571/// \endcode
1572///
1573/// When demangling a specialization of the conversion function template, we
1574/// encounter the name of the template (including the \c T) before we reach
1575/// the template argument list, so we cannot substitute the parameter name
1576/// for the corresponding argument while parsing. Instead, we create a
1577/// \c ForwardTemplateReference node that is resolved after we parse the
1578/// template arguments.
1579struct ForwardTemplateReference : Node {
1580 size_t Index;
1581 Node *Ref = nullptr;
1582
1583 // If we're currently printing this node. It is possible (though invalid) for
1584 // a forward template reference to refer to itself via a substitution. This
1585 // creates a cyclic AST, which will stack overflow printing. To fix this, bail
1586 // out if more than one print* function is active.
1587 mutable bool Printing = false;
1588
1589 ForwardTemplateReference(size_t Index_)
1590 : Node(KForwardTemplateReference, Cache::Unknown, Cache::Unknown,
1591 Cache::Unknown),
1592 Index(Index_) {}
1593
1594 // We don't provide a matcher for these, because the value of the node is
1595 // not determined by its construction parameters, and it generally needs
1596 // special handling.
1597 template<typename Fn> void match(Fn F) const = delete;
1598
1599 bool hasRHSComponentSlow(OutputBuffer &OB) const override {
1600 if (Printing)
1601 return false;
1602 ScopedOverride<bool> SavePrinting(Printing, true);
1603 return Ref->hasRHSComponent(OB);
1604 }
1605 bool hasArraySlow(OutputBuffer &OB) const override {
1606 if (Printing)
1607 return false;
1608 ScopedOverride<bool> SavePrinting(Printing, true);
1609 return Ref->hasArray(OB);
1610 }
1611 bool hasFunctionSlow(OutputBuffer &OB) const override {
1612 if (Printing)
1613 return false;
1614 ScopedOverride<bool> SavePrinting(Printing, true);
1615 return Ref->hasFunction(OB);
1616 }
1617 const Node *getSyntaxNode(OutputBuffer &OB) const override {
1618 if (Printing)
1619 return this;
1620 ScopedOverride<bool> SavePrinting(Printing, true);
1621 return Ref->getSyntaxNode(OB);
1622 }
1623
1624 void printLeft(OutputBuffer &OB) const override {
1625 if (Printing)
1626 return;
1627 ScopedOverride<bool> SavePrinting(Printing, true);
1628 OB.printLeft(N: *Ref);
1629 }
1630 void printRight(OutputBuffer &OB) const override {
1631 if (Printing)
1632 return;
1633 ScopedOverride<bool> SavePrinting(Printing, true);
1634 OB.printRight(N: *Ref);
1635 }
1636};
1637
1638struct NameWithTemplateArgs : Node {
1639 // name<template_args>
1640 Node *Name;
1641 Node *TemplateArgs;
1642
1643 NameWithTemplateArgs(Node *Name_, Node *TemplateArgs_)
1644 : Node(KNameWithTemplateArgs), Name(Name_), TemplateArgs(TemplateArgs_) {}
1645
1646 template<typename Fn> void match(Fn F) const { F(Name, TemplateArgs); }
1647
1648 std::string_view getBaseName() const override { return Name->getBaseName(); }
1649
1650 void printLeft(OutputBuffer &OB) const override {
1651 Name->print(OB);
1652 TemplateArgs->print(OB);
1653 }
1654};
1655
1656class GlobalQualifiedName final : public Node {
1657 Node *Child;
1658
1659public:
1660 GlobalQualifiedName(Node* Child_)
1661 : Node(KGlobalQualifiedName), Child(Child_) {}
1662
1663 template<typename Fn> void match(Fn F) const { F(Child); }
1664
1665 std::string_view getBaseName() const override { return Child->getBaseName(); }
1666
1667 void printLeft(OutputBuffer &OB) const override {
1668 OB += "::";
1669 Child->print(OB);
1670 }
1671};
1672
1673enum class SpecialSubKind {
1674 allocator,
1675 basic_string,
1676 string,
1677 istream,
1678 ostream,
1679 iostream,
1680};
1681
1682class SpecialSubstitution;
1683class ExpandedSpecialSubstitution : public Node {
1684protected:
1685 SpecialSubKind SSK;
1686
1687 ExpandedSpecialSubstitution(SpecialSubKind SSK_, Kind K_)
1688 : Node(K_), SSK(SSK_) {}
1689public:
1690 ExpandedSpecialSubstitution(SpecialSubKind SSK_)
1691 : ExpandedSpecialSubstitution(SSK_, KExpandedSpecialSubstitution) {}
1692 inline ExpandedSpecialSubstitution(SpecialSubstitution const *);
1693
1694 template<typename Fn> void match(Fn F) const { F(SSK); }
1695
1696protected:
1697 bool isInstantiation() const {
1698 return unsigned(SSK) >= unsigned(SpecialSubKind::string);
1699 }
1700
1701 std::string_view getBaseName() const override {
1702 switch (SSK) {
1703 case SpecialSubKind::allocator:
1704 return {"allocator"};
1705 case SpecialSubKind::basic_string:
1706 return {"basic_string"};
1707 case SpecialSubKind::string:
1708 return {"basic_string"};
1709 case SpecialSubKind::istream:
1710 return {"basic_istream"};
1711 case SpecialSubKind::ostream:
1712 return {"basic_ostream"};
1713 case SpecialSubKind::iostream:
1714 return {"basic_iostream"};
1715 }
1716 DEMANGLE_UNREACHABLE;
1717 }
1718
1719private:
1720 void printLeft(OutputBuffer &OB) const override {
1721 OB << "std::" << getBaseName();
1722 if (isInstantiation()) {
1723 OB << "<char, std::char_traits<char>";
1724 if (SSK == SpecialSubKind::string)
1725 OB << ", std::allocator<char>";
1726 OB << ">";
1727 }
1728 }
1729};
1730
1731class SpecialSubstitution final : public ExpandedSpecialSubstitution {
1732public:
1733 SpecialSubstitution(SpecialSubKind SSK_)
1734 : ExpandedSpecialSubstitution(SSK_, KSpecialSubstitution) {}
1735
1736 template<typename Fn> void match(Fn F) const { F(SSK); }
1737
1738 std::string_view getBaseName() const override {
1739 std::string_view SV = ExpandedSpecialSubstitution::getBaseName();
1740 if (isInstantiation()) {
1741 // The instantiations are typedefs that drop the "basic_" prefix.
1742 DEMANGLE_ASSERT(starts_with(SV, "basic_"), "");
1743 SV.remove_prefix(n: sizeof("basic_") - 1);
1744 }
1745 return SV;
1746 }
1747
1748 void printLeft(OutputBuffer &OB) const override {
1749 OB << "std::" << getBaseName();
1750 }
1751};
1752
1753inline ExpandedSpecialSubstitution::ExpandedSpecialSubstitution(
1754 SpecialSubstitution const *SS)
1755 : ExpandedSpecialSubstitution(SS->SSK) {}
1756
1757class CtorDtorName final : public Node {
1758 const Node *Basename;
1759 const bool IsDtor;
1760 const int Variant;
1761
1762public:
1763 CtorDtorName(const Node *Basename_, bool IsDtor_, int Variant_)
1764 : Node(KCtorDtorName), Basename(Basename_), IsDtor(IsDtor_),
1765 Variant(Variant_) {}
1766
1767 template<typename Fn> void match(Fn F) const { F(Basename, IsDtor, Variant); }
1768
1769 void printLeft(OutputBuffer &OB) const override {
1770 if (IsDtor)
1771 OB += "~";
1772 OB += Basename->getBaseName();
1773 }
1774};
1775
1776class DtorName : public Node {
1777 const Node *Base;
1778
1779public:
1780 DtorName(const Node *Base_) : Node(KDtorName), Base(Base_) {}
1781
1782 template<typename Fn> void match(Fn F) const { F(Base); }
1783
1784 void printLeft(OutputBuffer &OB) const override {
1785 OB += "~";
1786 OB.printLeft(N: *Base);
1787 }
1788};
1789
1790class UnnamedTypeName : public Node {
1791 const std::string_view Count;
1792
1793public:
1794 UnnamedTypeName(std::string_view Count_)
1795 : Node(KUnnamedTypeName), Count(Count_) {}
1796
1797 template<typename Fn> void match(Fn F) const { F(Count); }
1798
1799 void printLeft(OutputBuffer &OB) const override {
1800 OB += "'unnamed";
1801 OB += Count;
1802 OB += "\'";
1803 }
1804};
1805
1806class ClosureTypeName : public Node {
1807 NodeArray TemplateParams;
1808 const Node *Requires1;
1809 NodeArray Params;
1810 const Node *Requires2;
1811 std::string_view Count;
1812
1813public:
1814 ClosureTypeName(NodeArray TemplateParams_, const Node *Requires1_,
1815 NodeArray Params_, const Node *Requires2_,
1816 std::string_view Count_)
1817 : Node(KClosureTypeName), TemplateParams(TemplateParams_),
1818 Requires1(Requires1_), Params(Params_), Requires2(Requires2_),
1819 Count(Count_) {}
1820
1821 template<typename Fn> void match(Fn F) const {
1822 F(TemplateParams, Requires1, Params, Requires2, Count);
1823 }
1824
1825 void printDeclarator(OutputBuffer &OB) const {
1826 if (!TemplateParams.empty()) {
1827 ScopedOverride<bool> LT(OB.TemplateTracker.InsideTemplate, true);
1828 OB += "<";
1829 TemplateParams.printWithComma(OB);
1830 OB += ">";
1831 }
1832 if (Requires1 != nullptr) {
1833 OB += " requires ";
1834 Requires1->print(OB);
1835 OB += " ";
1836 }
1837 OB.printOpen();
1838 Params.printWithComma(OB);
1839 OB.printClose();
1840 if (Requires2 != nullptr) {
1841 OB += " requires ";
1842 Requires2->print(OB);
1843 }
1844 }
1845
1846 void printLeft(OutputBuffer &OB) const override {
1847 // FIXME: This demangling is not particularly readable.
1848 OB += "\'lambda";
1849 OB += Count;
1850 OB += "\'";
1851 printDeclarator(OB);
1852 }
1853};
1854
1855class StructuredBindingName : public Node {
1856 NodeArray Bindings;
1857public:
1858 StructuredBindingName(NodeArray Bindings_)
1859 : Node(KStructuredBindingName), Bindings(Bindings_) {}
1860
1861 template<typename Fn> void match(Fn F) const { F(Bindings); }
1862
1863 void printLeft(OutputBuffer &OB) const override {
1864 OB.printOpen(Open: '[');
1865 Bindings.printWithComma(OB);
1866 OB.printClose(Close: ']');
1867 }
1868};
1869
1870// -- Expression Nodes --
1871
1872class BinaryExpr : public Node {
1873 const Node *LHS;
1874 const std::string_view InfixOperator;
1875 const Node *RHS;
1876
1877public:
1878 BinaryExpr(const Node *LHS_, std::string_view InfixOperator_,
1879 const Node *RHS_, Prec Prec_)
1880 : Node(KBinaryExpr, Prec_), LHS(LHS_), InfixOperator(InfixOperator_),
1881 RHS(RHS_) {}
1882
1883 template <typename Fn> void match(Fn F) const {
1884 F(LHS, InfixOperator, RHS, getPrecedence());
1885 }
1886
1887 void printLeft(OutputBuffer &OB) const override {
1888 // If we're printing a '<' inside of a template argument, and we haven't
1889 // yet parenthesized the expression, do so now.
1890 bool ParenAll = !OB.isInParensInTemplateArgs() &&
1891 (InfixOperator == ">" || InfixOperator == ">>");
1892 if (ParenAll)
1893 OB.printOpen();
1894 // Assignment is right associative, with special LHS precedence.
1895 bool IsAssign = getPrecedence() == Prec::Assign;
1896 LHS->printAsOperand(OB, P: IsAssign ? Prec::OrIf : getPrecedence(), StrictlyWorse: !IsAssign);
1897 // No space before comma operator
1898 if (!(InfixOperator == ","))
1899 OB += " ";
1900 OB += InfixOperator;
1901 OB += " ";
1902 RHS->printAsOperand(OB, P: getPrecedence(), StrictlyWorse: IsAssign);
1903 if (ParenAll)
1904 OB.printClose();
1905 }
1906};
1907
1908class ArraySubscriptExpr : public Node {
1909 const Node *Op1;
1910 const Node *Op2;
1911
1912public:
1913 ArraySubscriptExpr(const Node *Op1_, const Node *Op2_, Prec Prec_)
1914 : Node(KArraySubscriptExpr, Prec_), Op1(Op1_), Op2(Op2_) {}
1915
1916 template <typename Fn> void match(Fn F) const {
1917 F(Op1, Op2, getPrecedence());
1918 }
1919
1920 void printLeft(OutputBuffer &OB) const override {
1921 Op1->printAsOperand(OB, P: getPrecedence());
1922 OB.printOpen(Open: '[');
1923 Op2->printAsOperand(OB);
1924 OB.printClose(Close: ']');
1925 }
1926};
1927
1928class PostfixExpr : public Node {
1929 const Node *Child;
1930 const std::string_view Operator;
1931
1932public:
1933 PostfixExpr(const Node *Child_, std::string_view Operator_, Prec Prec_)
1934 : Node(KPostfixExpr, Prec_), Child(Child_), Operator(Operator_) {}
1935
1936 template <typename Fn> void match(Fn F) const {
1937 F(Child, Operator, getPrecedence());
1938 }
1939
1940 void printLeft(OutputBuffer &OB) const override {
1941 Child->printAsOperand(OB, P: getPrecedence(), StrictlyWorse: true);
1942 OB += Operator;
1943 }
1944};
1945
1946class ConditionalExpr : public Node {
1947 const Node *Cond;
1948 const Node *Then;
1949 const Node *Else;
1950
1951public:
1952 ConditionalExpr(const Node *Cond_, const Node *Then_, const Node *Else_,
1953 Prec Prec_)
1954 : Node(KConditionalExpr, Prec_), Cond(Cond_), Then(Then_), Else(Else_) {}
1955
1956 template <typename Fn> void match(Fn F) const {
1957 F(Cond, Then, Else, getPrecedence());
1958 }
1959
1960 void printLeft(OutputBuffer &OB) const override {
1961 Cond->printAsOperand(OB, P: getPrecedence());
1962 OB += " ? ";
1963 Then->printAsOperand(OB);
1964 OB += " : ";
1965 Else->printAsOperand(OB, P: Prec::Assign, StrictlyWorse: true);
1966 }
1967};
1968
1969class MemberExpr : public Node {
1970 const Node *LHS;
1971 const std::string_view Kind;
1972 const Node *RHS;
1973
1974public:
1975 MemberExpr(const Node *LHS_, std::string_view Kind_, const Node *RHS_,
1976 Prec Prec_)
1977 : Node(KMemberExpr, Prec_), LHS(LHS_), Kind(Kind_), RHS(RHS_) {}
1978
1979 template <typename Fn> void match(Fn F) const {
1980 F(LHS, Kind, RHS, getPrecedence());
1981 }
1982
1983 void printLeft(OutputBuffer &OB) const override {
1984 LHS->printAsOperand(OB, P: getPrecedence(), StrictlyWorse: true);
1985 OB += Kind;
1986 RHS->printAsOperand(OB, P: getPrecedence(), StrictlyWorse: false);
1987 }
1988};
1989
1990class SubobjectExpr : public Node {
1991 const Node *Type;
1992 const Node *SubExpr;
1993 std::string_view Offset;
1994 NodeArray UnionSelectors;
1995 bool OnePastTheEnd;
1996
1997public:
1998 SubobjectExpr(const Node *Type_, const Node *SubExpr_,
1999 std::string_view Offset_, NodeArray UnionSelectors_,
2000 bool OnePastTheEnd_)
2001 : Node(KSubobjectExpr), Type(Type_), SubExpr(SubExpr_), Offset(Offset_),
2002 UnionSelectors(UnionSelectors_), OnePastTheEnd(OnePastTheEnd_) {}
2003
2004 template<typename Fn> void match(Fn F) const {
2005 F(Type, SubExpr, Offset, UnionSelectors, OnePastTheEnd);
2006 }
2007
2008 void printLeft(OutputBuffer &OB) const override {
2009 SubExpr->print(OB);
2010 OB += ".<";
2011 Type->print(OB);
2012 OB += " at offset ";
2013 if (Offset.empty()) {
2014 OB += "0";
2015 } else if (Offset[0] == 'n') {
2016 OB += "-";
2017 OB += std::string_view(Offset.data() + 1, Offset.size() - 1);
2018 } else {
2019 OB += Offset;
2020 }
2021 OB += ">";
2022 }
2023};
2024
2025class EnclosingExpr : public Node {
2026 const std::string_view Prefix;
2027 const Node *Infix;
2028 const std::string_view Postfix;
2029
2030public:
2031 EnclosingExpr(std::string_view Prefix_, const Node *Infix_,
2032 Prec Prec_ = Prec::Primary)
2033 : Node(KEnclosingExpr, Prec_), Prefix(Prefix_), Infix(Infix_) {}
2034
2035 template <typename Fn> void match(Fn F) const {
2036 F(Prefix, Infix, getPrecedence());
2037 }
2038
2039 void printLeft(OutputBuffer &OB) const override {
2040 OB += Prefix;
2041 OB.printOpen();
2042 Infix->print(OB);
2043 OB.printClose();
2044 OB += Postfix;
2045 }
2046};
2047
2048class CastExpr : public Node {
2049 // cast_kind<to>(from)
2050 const std::string_view CastKind;
2051 const Node *To;
2052 const Node *From;
2053
2054public:
2055 CastExpr(std::string_view CastKind_, const Node *To_, const Node *From_,
2056 Prec Prec_)
2057 : Node(KCastExpr, Prec_), CastKind(CastKind_), To(To_), From(From_) {}
2058
2059 template <typename Fn> void match(Fn F) const {
2060 F(CastKind, To, From, getPrecedence());
2061 }
2062
2063 void printLeft(OutputBuffer &OB) const override {
2064 OB += CastKind;
2065 {
2066 ScopedOverride<bool> LT(OB.TemplateTracker.InsideTemplate, true);
2067 OB += "<";
2068 OB.printLeft(N: *To);
2069 OB += ">";
2070 }
2071 OB.printOpen();
2072 From->printAsOperand(OB);
2073 OB.printClose();
2074 }
2075};
2076
2077class SizeofParamPackExpr : public Node {
2078 const Node *Pack;
2079
2080public:
2081 SizeofParamPackExpr(const Node *Pack_)
2082 : Node(KSizeofParamPackExpr), Pack(Pack_) {}
2083
2084 template<typename Fn> void match(Fn F) const { F(Pack); }
2085
2086 void printLeft(OutputBuffer &OB) const override {
2087 OB += "sizeof...";
2088 OB.printOpen();
2089 ParameterPackExpansion PPE(Pack);
2090 PPE.printLeft(OB);
2091 OB.printClose();
2092 }
2093};
2094
2095class CallExpr : public Node {
2096 const Node *Callee;
2097 NodeArray Args;
2098 bool IsParen; // (func)(args ...) ?
2099
2100public:
2101 CallExpr(const Node *Callee_, NodeArray Args_, bool IsParen_, Prec Prec_)
2102 : Node(KCallExpr, Prec_), Callee(Callee_), Args(Args_),
2103 IsParen(IsParen_) {}
2104
2105 template <typename Fn> void match(Fn F) const {
2106 F(Callee, Args, IsParen, getPrecedence());
2107 }
2108
2109 void printLeft(OutputBuffer &OB) const override {
2110 if (IsParen)
2111 OB.printOpen();
2112 Callee->print(OB);
2113 if (IsParen)
2114 OB.printClose();
2115 OB.printOpen();
2116 Args.printWithComma(OB);
2117 OB.printClose();
2118 }
2119};
2120
2121class NewExpr : public Node {
2122 // new (expr_list) type(init_list)
2123 NodeArray ExprList;
2124 Node *Type;
2125 NodeArray InitList;
2126 bool IsGlobal; // ::operator new ?
2127 bool IsArray; // new[] ?
2128public:
2129 NewExpr(NodeArray ExprList_, Node *Type_, NodeArray InitList_, bool IsGlobal_,
2130 bool IsArray_, Prec Prec_)
2131 : Node(KNewExpr, Prec_), ExprList(ExprList_), Type(Type_),
2132 InitList(InitList_), IsGlobal(IsGlobal_), IsArray(IsArray_) {}
2133
2134 template<typename Fn> void match(Fn F) const {
2135 F(ExprList, Type, InitList, IsGlobal, IsArray, getPrecedence());
2136 }
2137
2138 void printLeft(OutputBuffer &OB) const override {
2139 if (IsGlobal)
2140 OB += "::";
2141 OB += "new";
2142 if (IsArray)
2143 OB += "[]";
2144 if (!ExprList.empty()) {
2145 OB.printOpen();
2146 ExprList.printWithComma(OB);
2147 OB.printClose();
2148 }
2149 OB += " ";
2150 Type->print(OB);
2151 if (!InitList.empty()) {
2152 OB.printOpen();
2153 InitList.printWithComma(OB);
2154 OB.printClose();
2155 }
2156 }
2157};
2158
2159class DeleteExpr : public Node {
2160 Node *Op;
2161 bool IsGlobal;
2162 bool IsArray;
2163
2164public:
2165 DeleteExpr(Node *Op_, bool IsGlobal_, bool IsArray_, Prec Prec_)
2166 : Node(KDeleteExpr, Prec_), Op(Op_), IsGlobal(IsGlobal_),
2167 IsArray(IsArray_) {}
2168
2169 template <typename Fn> void match(Fn F) const {
2170 F(Op, IsGlobal, IsArray, getPrecedence());
2171 }
2172
2173 void printLeft(OutputBuffer &OB) const override {
2174 if (IsGlobal)
2175 OB += "::";
2176 OB += "delete";
2177 if (IsArray)
2178 OB += "[]";
2179 OB += ' ';
2180 Op->print(OB);
2181 }
2182};
2183
2184class PrefixExpr : public Node {
2185 std::string_view Prefix;
2186 Node *Child;
2187
2188public:
2189 PrefixExpr(std::string_view Prefix_, Node *Child_, Prec Prec_)
2190 : Node(KPrefixExpr, Prec_), Prefix(Prefix_), Child(Child_) {}
2191
2192 template <typename Fn> void match(Fn F) const {
2193 F(Prefix, Child, getPrecedence());
2194 }
2195
2196 void printLeft(OutputBuffer &OB) const override {
2197 OB += Prefix;
2198 Child->printAsOperand(OB, P: getPrecedence());
2199 }
2200};
2201
2202class FunctionParam : public Node {
2203 std::string_view Number;
2204
2205public:
2206 FunctionParam(std::string_view Number_)
2207 : Node(KFunctionParam), Number(Number_) {}
2208
2209 template<typename Fn> void match(Fn F) const { F(Number); }
2210
2211 void printLeft(OutputBuffer &OB) const override {
2212 OB += "fp";
2213 OB += Number;
2214 }
2215};
2216
2217class ConversionExpr : public Node {
2218 const Node *Type;
2219 NodeArray Expressions;
2220
2221public:
2222 ConversionExpr(const Node *Type_, NodeArray Expressions_, Prec Prec_)
2223 : Node(KConversionExpr, Prec_), Type(Type_), Expressions(Expressions_) {}
2224
2225 template <typename Fn> void match(Fn F) const {
2226 F(Type, Expressions, getPrecedence());
2227 }
2228
2229 void printLeft(OutputBuffer &OB) const override {
2230 OB.printOpen();
2231 Type->print(OB);
2232 OB.printClose();
2233 OB.printOpen();
2234 Expressions.printWithComma(OB);
2235 OB.printClose();
2236 }
2237};
2238
2239class PointerToMemberConversionExpr : public Node {
2240 const Node *Type;
2241 const Node *SubExpr;
2242 std::string_view Offset;
2243
2244public:
2245 PointerToMemberConversionExpr(const Node *Type_, const Node *SubExpr_,
2246 std::string_view Offset_, Prec Prec_)
2247 : Node(KPointerToMemberConversionExpr, Prec_), Type(Type_),
2248 SubExpr(SubExpr_), Offset(Offset_) {}
2249
2250 template <typename Fn> void match(Fn F) const {
2251 F(Type, SubExpr, Offset, getPrecedence());
2252 }
2253
2254 void printLeft(OutputBuffer &OB) const override {
2255 OB.printOpen();
2256 Type->print(OB);
2257 OB.printClose();
2258 OB.printOpen();
2259 SubExpr->print(OB);
2260 OB.printClose();
2261 }
2262};
2263
2264class InitListExpr : public Node {
2265 const Node *Ty;
2266 NodeArray Inits;
2267public:
2268 InitListExpr(const Node *Ty_, NodeArray Inits_)
2269 : Node(KInitListExpr), Ty(Ty_), Inits(Inits_) {}
2270
2271 template<typename Fn> void match(Fn F) const { F(Ty, Inits); }
2272
2273 void printLeft(OutputBuffer &OB) const override {
2274 if (Ty) {
2275 if (Ty->printInitListAsType(OB, Inits))
2276 return;
2277 Ty->print(OB);
2278 }
2279 OB += '{';
2280 Inits.printWithComma(OB);
2281 OB += '}';
2282 }
2283};
2284
2285class BracedExpr : public Node {
2286 const Node *Elem;
2287 const Node *Init;
2288 bool IsArray;
2289public:
2290 BracedExpr(const Node *Elem_, const Node *Init_, bool IsArray_)
2291 : Node(KBracedExpr), Elem(Elem_), Init(Init_), IsArray(IsArray_) {}
2292
2293 template<typename Fn> void match(Fn F) const { F(Elem, Init, IsArray); }
2294
2295 void printLeft(OutputBuffer &OB) const override {
2296 if (IsArray) {
2297 OB += '[';
2298 Elem->print(OB);
2299 OB += ']';
2300 } else {
2301 OB += '.';
2302 Elem->print(OB);
2303 }
2304 if (Init->getKind() != KBracedExpr && Init->getKind() != KBracedRangeExpr)
2305 OB += " = ";
2306 Init->print(OB);
2307 }
2308};
2309
2310class BracedRangeExpr : public Node {
2311 const Node *First;
2312 const Node *Last;
2313 const Node *Init;
2314public:
2315 BracedRangeExpr(const Node *First_, const Node *Last_, const Node *Init_)
2316 : Node(KBracedRangeExpr), First(First_), Last(Last_), Init(Init_) {}
2317
2318 template<typename Fn> void match(Fn F) const { F(First, Last, Init); }
2319
2320 void printLeft(OutputBuffer &OB) const override {
2321 OB += '[';
2322 First->print(OB);
2323 OB += " ... ";
2324 Last->print(OB);
2325 OB += ']';
2326 if (Init->getKind() != KBracedExpr && Init->getKind() != KBracedRangeExpr)
2327 OB += " = ";
2328 Init->print(OB);
2329 }
2330};
2331
2332class FoldExpr : public Node {
2333 const Node *Pack, *Init;
2334 std::string_view OperatorName;
2335 bool IsLeftFold;
2336
2337public:
2338 FoldExpr(bool IsLeftFold_, std::string_view OperatorName_, const Node *Pack_,
2339 const Node *Init_)
2340 : Node(KFoldExpr), Pack(Pack_), Init(Init_), OperatorName(OperatorName_),
2341 IsLeftFold(IsLeftFold_) {}
2342
2343 template<typename Fn> void match(Fn F) const {
2344 F(IsLeftFold, OperatorName, Pack, Init);
2345 }
2346
2347 void printLeft(OutputBuffer &OB) const override {
2348 auto PrintPack = [&] {
2349 OB.printOpen();
2350 ParameterPackExpansion(Pack).print(OB);
2351 OB.printClose();
2352 };
2353
2354 OB.printOpen();
2355 // Either '[init op ]... op pack' or 'pack op ...[ op init]'
2356 // Refactored to '[(init|pack) op ]...[ op (pack|init)]'
2357 // Fold expr operands are cast-expressions
2358 if (!IsLeftFold || Init != nullptr) {
2359 // '(init|pack) op '
2360 if (IsLeftFold)
2361 Init->printAsOperand(OB, P: Prec::Cast, StrictlyWorse: true);
2362 else
2363 PrintPack();
2364 OB << " " << OperatorName << " ";
2365 }
2366 OB << "...";
2367 if (IsLeftFold || Init != nullptr) {
2368 // ' op (init|pack)'
2369 OB << " " << OperatorName << " ";
2370 if (IsLeftFold)
2371 PrintPack();
2372 else
2373 Init->printAsOperand(OB, P: Prec::Cast, StrictlyWorse: true);
2374 }
2375 OB.printClose();
2376 }
2377};
2378
2379class ThrowExpr : public Node {
2380 const Node *Op;
2381
2382public:
2383 ThrowExpr(const Node *Op_) : Node(KThrowExpr), Op(Op_) {}
2384
2385 template<typename Fn> void match(Fn F) const { F(Op); }
2386
2387 void printLeft(OutputBuffer &OB) const override {
2388 OB += "throw ";
2389 Op->print(OB);
2390 }
2391};
2392
2393class BoolExpr : public Node {
2394 bool Value;
2395
2396public:
2397 BoolExpr(bool Value_) : Node(KBoolExpr), Value(Value_) {}
2398
2399 template<typename Fn> void match(Fn F) const { F(Value); }
2400
2401 void printLeft(OutputBuffer &OB) const override {
2402 OB += Value ? std::string_view("true") : std::string_view("false");
2403 }
2404};
2405
2406class StringLiteral : public Node {
2407 const Node *Type;
2408
2409public:
2410 StringLiteral(const Node *Type_) : Node(KStringLiteral), Type(Type_) {}
2411
2412 template<typename Fn> void match(Fn F) const { F(Type); }
2413
2414 void printLeft(OutputBuffer &OB) const override {
2415 OB += "\"<";
2416 Type->print(OB);
2417 OB += ">\"";
2418 }
2419};
2420
2421class LambdaExpr : public Node {
2422 const Node *Type;
2423
2424public:
2425 LambdaExpr(const Node *Type_) : Node(KLambdaExpr), Type(Type_) {}
2426
2427 template<typename Fn> void match(Fn F) const { F(Type); }
2428
2429 void printLeft(OutputBuffer &OB) const override {
2430 OB += "[]";
2431 if (Type->getKind() == KClosureTypeName)
2432 static_cast<const ClosureTypeName *>(Type)->printDeclarator(OB);
2433 OB += "{...}";
2434 }
2435};
2436
2437class EnumLiteral : public Node {
2438 // ty(integer)
2439 const Node *Ty;
2440 std::string_view Integer;
2441
2442public:
2443 EnumLiteral(const Node *Ty_, std::string_view Integer_)
2444 : Node(KEnumLiteral), Ty(Ty_), Integer(Integer_) {}
2445
2446 template<typename Fn> void match(Fn F) const { F(Ty, Integer); }
2447
2448 void printLeft(OutputBuffer &OB) const override {
2449 OB.printOpen();
2450 Ty->print(OB);
2451 OB.printClose();
2452
2453 if (Integer[0] == 'n')
2454 OB << '-' << std::string_view(Integer.data() + 1, Integer.size() - 1);
2455 else
2456 OB << Integer;
2457 }
2458};
2459
2460class IntegerLiteral : public Node {
2461 std::string_view Type;
2462 std::string_view Value;
2463
2464public:
2465 IntegerLiteral(std::string_view Type_, std::string_view Value_)
2466 : Node(KIntegerLiteral), Type(Type_), Value(Value_) {}
2467
2468 template<typename Fn> void match(Fn F) const { F(Type, Value); }
2469
2470 void printLeft(OutputBuffer &OB) const override {
2471 if (Type.size() > 3) {
2472 OB.printOpen();
2473 OB += Type;
2474 OB.printClose();
2475 }
2476
2477 if (Value[0] == 'n')
2478 OB << '-' << std::string_view(Value.data() + 1, Value.size() - 1);
2479 else
2480 OB += Value;
2481
2482 if (Type.size() <= 3)
2483 OB += Type;
2484 }
2485
2486 std::string_view value() const { return Value; }
2487};
2488
2489class RequiresExpr : public Node {
2490 NodeArray Parameters;
2491 NodeArray Requirements;
2492public:
2493 RequiresExpr(NodeArray Parameters_, NodeArray Requirements_)
2494 : Node(KRequiresExpr), Parameters(Parameters_),
2495 Requirements(Requirements_) {}
2496
2497 template<typename Fn> void match(Fn F) const { F(Parameters, Requirements); }
2498
2499 void printLeft(OutputBuffer &OB) const override {
2500 OB += "requires";
2501 if (!Parameters.empty()) {
2502 OB += ' ';
2503 OB.printOpen();
2504 Parameters.printWithComma(OB);
2505 OB.printClose();
2506 }
2507 OB += ' ';
2508 OB.printOpen(Open: '{');
2509 for (const Node *Req : Requirements) {
2510 Req->print(OB);
2511 }
2512 OB += ' ';
2513 OB.printClose(Close: '}');
2514 }
2515};
2516
2517class ExprRequirement : public Node {
2518 const Node *Expr;
2519 bool IsNoexcept;
2520 const Node *TypeConstraint;
2521public:
2522 ExprRequirement(const Node *Expr_, bool IsNoexcept_,
2523 const Node *TypeConstraint_)
2524 : Node(KExprRequirement), Expr(Expr_), IsNoexcept(IsNoexcept_),
2525 TypeConstraint(TypeConstraint_) {}
2526
2527 template <typename Fn> void match(Fn F) const {
2528 F(Expr, IsNoexcept, TypeConstraint);
2529 }
2530
2531 void printLeft(OutputBuffer &OB) const override {
2532 OB += " ";
2533 if (IsNoexcept || TypeConstraint)
2534 OB.printOpen(Open: '{');
2535 Expr->print(OB);
2536 if (IsNoexcept || TypeConstraint)
2537 OB.printClose(Close: '}');
2538 if (IsNoexcept)
2539 OB += " noexcept";
2540 if (TypeConstraint) {
2541 OB += " -> ";
2542 TypeConstraint->print(OB);
2543 }
2544 OB += ';';
2545 }
2546};
2547
2548class TypeRequirement : public Node {
2549 const Node *Type;
2550public:
2551 TypeRequirement(const Node *Type_)
2552 : Node(KTypeRequirement), Type(Type_) {}
2553
2554 template <typename Fn> void match(Fn F) const { F(Type); }
2555
2556 void printLeft(OutputBuffer &OB) const override {
2557 OB += " typename ";
2558 Type->print(OB);
2559 OB += ';';
2560 }
2561};
2562
2563class NestedRequirement : public Node {
2564 const Node *Constraint;
2565public:
2566 NestedRequirement(const Node *Constraint_)
2567 : Node(KNestedRequirement), Constraint(Constraint_) {}
2568
2569 template <typename Fn> void match(Fn F) const { F(Constraint); }
2570
2571 void printLeft(OutputBuffer &OB) const override {
2572 OB += " requires ";
2573 Constraint->print(OB);
2574 OB += ';';
2575 }
2576};
2577
2578template <class Float> struct FloatData;
2579
2580namespace float_literal_impl {
2581constexpr Node::Kind getFloatLiteralKind(float *) {
2582 return Node::KFloatLiteral;
2583}
2584constexpr Node::Kind getFloatLiteralKind(double *) {
2585 return Node::KDoubleLiteral;
2586}
2587constexpr Node::Kind getFloatLiteralKind(long double *) {
2588 return Node::KLongDoubleLiteral;
2589}
2590}
2591
2592template <class Float> class FloatLiteralImpl : public Node {
2593 const std::string_view Contents;
2594
2595 static constexpr Kind KindForClass =
2596 float_literal_impl::getFloatLiteralKind((Float *)nullptr);
2597
2598public:
2599 FloatLiteralImpl(std::string_view Contents_)
2600 : Node(KindForClass), Contents(Contents_) {}
2601
2602 template<typename Fn> void match(Fn F) const { F(Contents); }
2603
2604 void printLeft(OutputBuffer &OB) const override {
2605 const size_t N = FloatData<Float>::mangled_size;
2606 if (Contents.size() >= N) {
2607 union {
2608 Float value;
2609 char buf[sizeof(Float)];
2610 };
2611 const char *t = Contents.data();
2612 const char *last = t + N;
2613 char *e = buf;
2614 for (; t != last; ++t, ++e) {
2615 unsigned d1 = isdigit(c: *t) ? static_cast<unsigned>(*t - '0')
2616 : static_cast<unsigned>(*t - 'a' + 10);
2617 ++t;
2618 unsigned d0 = isdigit(c: *t) ? static_cast<unsigned>(*t - '0')
2619 : static_cast<unsigned>(*t - 'a' + 10);
2620 *e = static_cast<char>((d1 << 4) + d0);
2621 }
2622#if __BYTE_ORDER__ == __ORDER_LITTLE_ENDIAN__
2623 std::reverse(buf, e);
2624#endif
2625 char num[FloatData<Float>::max_demangled_size] = {0};
2626 int n = snprintf(num, sizeof(num), FloatData<Float>::spec, value);
2627 OB += std::string_view(num, n);
2628 }
2629 }
2630};
2631
2632using FloatLiteral = FloatLiteralImpl<float>;
2633using DoubleLiteral = FloatLiteralImpl<double>;
2634using LongDoubleLiteral = FloatLiteralImpl<long double>;
2635
2636/// Visit the node. Calls \c F(P), where \c P is the node cast to the
2637/// appropriate derived class.
2638template<typename Fn>
2639void Node::visit(Fn F) const {
2640 switch (K) {
2641#define NODE(X) \
2642 case K##X: \
2643 return F(static_cast<const X *>(this));
2644#include "ItaniumNodes.def"
2645 }
2646 DEMANGLE_ASSERT(0, "unknown mangling node kind");
2647}
2648
2649/// Determine the kind of a node from its type.
2650template<typename NodeT> struct NodeKind;
2651#define NODE(X) \
2652 template <> struct NodeKind<X> { \
2653 static constexpr Node::Kind Kind = Node::K##X; \
2654 static constexpr const char *name() { return #X; } \
2655 };
2656#include "ItaniumNodes.def"
2657
2658inline bool NodeArray::printAsString(OutputBuffer &OB) const {
2659 auto StartPos = OB.getCurrentPosition();
2660 auto Fail = [&OB, StartPos] {
2661 OB.setCurrentPosition(StartPos);
2662 return false;
2663 };
2664
2665 OB += '"';
2666 bool LastWasNumericEscape = false;
2667 for (const Node *Element : *this) {
2668 if (Element->getKind() != Node::KIntegerLiteral)
2669 return Fail();
2670 int integer_value = 0;
2671 for (char c : static_cast<const IntegerLiteral *>(Element)->value()) {
2672 if (c < '0' || c > '9' || integer_value > 25)
2673 return Fail();
2674 integer_value *= 10;
2675 integer_value += c - '0';
2676 }
2677 if (integer_value > 255)
2678 return Fail();
2679
2680 // Insert a `""` to avoid accidentally extending a numeric escape.
2681 if (LastWasNumericEscape) {
2682 if ((integer_value >= '0' && integer_value <= '9') ||
2683 (integer_value >= 'a' && integer_value <= 'f') ||
2684 (integer_value >= 'A' && integer_value <= 'F')) {
2685 OB += "\"\"";
2686 }
2687 }
2688
2689 LastWasNumericEscape = false;
2690
2691 // Determine how to print this character.
2692 switch (integer_value) {
2693 case '\a':
2694 OB += "\\a";
2695 break;
2696 case '\b':
2697 OB += "\\b";
2698 break;
2699 case '\f':
2700 OB += "\\f";
2701 break;
2702 case '\n':
2703 OB += "\\n";
2704 break;
2705 case '\r':
2706 OB += "\\r";
2707 break;
2708 case '\t':
2709 OB += "\\t";
2710 break;
2711 case '\v':
2712 OB += "\\v";
2713 break;
2714
2715 case '"':
2716 OB += "\\\"";
2717 break;
2718 case '\\':
2719 OB += "\\\\";
2720 break;
2721
2722 default:
2723 // We assume that the character is ASCII, and use a numeric escape for all
2724 // remaining non-printable ASCII characters.
2725 if (integer_value < 32 || integer_value == 127) {
2726 constexpr char Hex[] = "0123456789ABCDEF";
2727 OB += '\\';
2728 if (integer_value > 7)
2729 OB += 'x';
2730 if (integer_value >= 16)
2731 OB += Hex[integer_value >> 4];
2732 OB += Hex[integer_value & 0xF];
2733 LastWasNumericEscape = true;
2734 break;
2735 }
2736
2737 // Assume all remaining characters are directly printable.
2738 OB += (char)integer_value;
2739 break;
2740 }
2741 }
2742 OB += '"';
2743 return true;
2744}
2745
2746template <typename Derived, typename Alloc> struct AbstractManglingParser {
2747 const char *First;
2748 const char *Last;
2749
2750 // Name stack, this is used by the parser to hold temporary names that were
2751 // parsed. The parser collapses multiple names into new nodes to construct
2752 // the AST. Once the parser is finished, names.size() == 1.
2753 PODSmallVector<Node *, 32> Names;
2754
2755 // Substitution table. Itanium supports name substitutions as a means of
2756 // compression. The string "S42_" refers to the 44nd entry (base-36) in this
2757 // table.
2758 PODSmallVector<Node *, 32> Subs;
2759
2760 // A list of template argument values corresponding to a template parameter
2761 // list.
2762 using TemplateParamList = PODSmallVector<Node *, 8>;
2763
2764 class ScopedTemplateParamList {
2765 AbstractManglingParser *Parser;
2766 size_t OldNumTemplateParamLists;
2767 TemplateParamList Params;
2768
2769 public:
2770 ScopedTemplateParamList(AbstractManglingParser *TheParser)
2771 : Parser(TheParser),
2772 OldNumTemplateParamLists(TheParser->TemplateParams.size()) {
2773 Parser->TemplateParams.push_back(&Params);
2774 }
2775 ~ScopedTemplateParamList() {
2776 DEMANGLE_ASSERT(Parser->TemplateParams.size() >= OldNumTemplateParamLists,
2777 "");
2778 Parser->TemplateParams.shrinkToSize(OldNumTemplateParamLists);
2779 }
2780 TemplateParamList *params() { return &Params; }
2781 };
2782
2783 // Template parameter table. Like the above, but referenced like "T42_".
2784 // This has a smaller size compared to Subs and Names because it can be
2785 // stored on the stack.
2786 TemplateParamList OuterTemplateParams;
2787
2788 // Lists of template parameters indexed by template parameter depth,
2789 // referenced like "TL2_4_". If nonempty, element 0 is always
2790 // OuterTemplateParams; inner elements are always template parameter lists of
2791 // lambda expressions. For a generic lambda with no explicit template
2792 // parameter list, the corresponding parameter list pointer will be null.
2793 PODSmallVector<TemplateParamList *, 4> TemplateParams;
2794
2795 class SaveTemplateParams {
2796 AbstractManglingParser *Parser;
2797 decltype(TemplateParams) OldParams;
2798 decltype(OuterTemplateParams) OldOuterParams;
2799
2800 public:
2801 SaveTemplateParams(AbstractManglingParser *TheParser) : Parser(TheParser) {
2802 OldParams = std::move(Parser->TemplateParams);
2803 OldOuterParams = std::move(Parser->OuterTemplateParams);
2804 Parser->TemplateParams.clear();
2805 Parser->OuterTemplateParams.clear();
2806 }
2807 ~SaveTemplateParams() {
2808 Parser->TemplateParams = std::move(OldParams);
2809 Parser->OuterTemplateParams = std::move(OldOuterParams);
2810 }
2811 };
2812
2813 // Set of unresolved forward <template-param> references. These can occur in a
2814 // conversion operator's type, and are resolved in the enclosing <encoding>.
2815 PODSmallVector<ForwardTemplateReference *, 4> ForwardTemplateRefs;
2816
2817 bool TryToParseTemplateArgs = true;
2818 bool PermitForwardTemplateReferences = false;
2819 bool HasIncompleteTemplateParameterTracking = false;
2820 size_t ParsingLambdaParamsAtLevel = (size_t)-1;
2821
2822 unsigned NumSyntheticTemplateParameters[3] = {};
2823
2824 Alloc ASTAllocator;
2825
2826 AbstractManglingParser(const char *First_, const char *Last_)
2827 : First(First_), Last(Last_) {}
2828
2829 Derived &getDerived() { return static_cast<Derived &>(*this); }
2830
2831 void reset(const char *First_, const char *Last_) {
2832 First = First_;
2833 Last = Last_;
2834 Names.clear();
2835 Subs.clear();
2836 TemplateParams.clear();
2837 ParsingLambdaParamsAtLevel = (size_t)-1;
2838 TryToParseTemplateArgs = true;
2839 PermitForwardTemplateReferences = false;
2840 for (int I = 0; I != 3; ++I)
2841 NumSyntheticTemplateParameters[I] = 0;
2842 ASTAllocator.reset();
2843 }
2844
2845 template <class T, class... Args> Node *make(Args &&... args) {
2846 return ASTAllocator.template makeNode<T>(std::forward<Args>(args)...);
2847 }
2848
2849 template <class It> NodeArray makeNodeArray(It begin, It end) {
2850 size_t sz = static_cast<size_t>(end - begin);
2851 void *mem = ASTAllocator.allocateNodeArray(sz);
2852 Node **data = new (mem) Node *[sz];
2853 std::copy(begin, end, data);
2854 return NodeArray(data, sz);
2855 }
2856
2857 NodeArray popTrailingNodeArray(size_t FromPosition) {
2858 DEMANGLE_ASSERT(FromPosition <= Names.size(), "");
2859 NodeArray res =
2860 makeNodeArray(Names.begin() + (long)FromPosition, Names.end());
2861 Names.shrinkToSize(Index: FromPosition);
2862 return res;
2863 }
2864
2865 bool consumeIf(std::string_view S) {
2866 if (starts_with(haystack: std::string_view(First, Last - First), needle: S)) {
2867 First += S.size();
2868 return true;
2869 }
2870 return false;
2871 }
2872
2873 bool consumeIf(char C) {
2874 if (First != Last && *First == C) {
2875 ++First;
2876 return true;
2877 }
2878 return false;
2879 }
2880
2881 char consume() { return First != Last ? *First++ : '\0'; }
2882
2883 char look(unsigned Lookahead = 0) const {
2884 if (static_cast<size_t>(Last - First) <= Lookahead)
2885 return '\0';
2886 return First[Lookahead];
2887 }
2888
2889 size_t numLeft() const { return static_cast<size_t>(Last - First); }
2890
2891 std::string_view parseNumber(bool AllowNegative = false);
2892 Qualifiers parseCVQualifiers();
2893 bool parsePositiveInteger(size_t *Out);
2894 std::string_view parseBareSourceName();
2895
2896 bool parseSeqId(size_t *Out);
2897 Node *parseSubstitution();
2898 Node *parseTemplateParam();
2899 Node *parseTemplateParamDecl(TemplateParamList *Params);
2900 Node *parseTemplateArgs(bool TagTemplates = false);
2901 Node *parseTemplateArg();
2902
2903 bool isTemplateParamDecl() {
2904 return look() == 'T' &&
2905 std::string_view("yptnk").find(look(Lookahead: 1)) != std::string_view::npos;
2906 }
2907
2908 /// Parse the <expression> production.
2909 Node *parseExpr();
2910 Node *parsePrefixExpr(std::string_view Kind, Node::Prec Prec);
2911 Node *parseBinaryExpr(std::string_view Kind, Node::Prec Prec);
2912 Node *parseIntegerLiteral(std::string_view Lit);
2913 Node *parseExprPrimary();
2914 template <class Float> Node *parseFloatingLiteral();
2915 Node *parseFunctionParam();
2916 Node *parseConversionExpr();
2917 Node *parseBracedExpr();
2918 Node *parseFoldExpr();
2919 Node *parsePointerToMemberConversionExpr(Node::Prec Prec);
2920 Node *parseSubobjectExpr();
2921 Node *parseConstraintExpr();
2922 Node *parseRequiresExpr();
2923
2924 /// Parse the <type> production.
2925 Node *parseType();
2926 Node *parseFunctionType();
2927 Node *parseVectorType();
2928 Node *parseDecltype();
2929 Node *parseArrayType();
2930 Node *parsePointerToMemberType();
2931 Node *parseClassEnumType();
2932 Node *parseQualifiedType();
2933
2934 Node *parseEncoding(bool ParseParams = true);
2935 bool parseCallOffset();
2936 Node *parseSpecialName();
2937
2938 /// Holds some extra information about a <name> that is being parsed. This
2939 /// information is only pertinent if the <name> refers to an <encoding>.
2940 struct NameState {
2941 bool CtorDtorConversion = false;
2942 bool EndsWithTemplateArgs = false;
2943 Qualifiers CVQualifiers = QualNone;
2944 FunctionRefQual ReferenceQualifier = FrefQualNone;
2945 size_t ForwardTemplateRefsBegin;
2946 bool HasExplicitObjectParameter = false;
2947
2948 NameState(AbstractManglingParser *Enclosing)
2949 : ForwardTemplateRefsBegin(Enclosing->ForwardTemplateRefs.size()) {}
2950 };
2951
2952 bool resolveForwardTemplateRefs(NameState &State) {
2953 size_t I = State.ForwardTemplateRefsBegin;
2954 size_t E = ForwardTemplateRefs.size();
2955 for (; I < E; ++I) {
2956 size_t Idx = ForwardTemplateRefs[I]->Index;
2957 if (TemplateParams.empty() || !TemplateParams[0] ||
2958 Idx >= TemplateParams[0]->size())
2959 return true;
2960 ForwardTemplateRefs[I]->Ref = (*TemplateParams[0])[Idx];
2961 }
2962 ForwardTemplateRefs.shrinkToSize(Index: State.ForwardTemplateRefsBegin);
2963 return false;
2964 }
2965
2966 /// Parse the <name> production>
2967 Node *parseName(NameState *State = nullptr);
2968 Node *parseLocalName(NameState *State);
2969 Node *parseOperatorName(NameState *State);
2970 bool parseModuleNameOpt(ModuleName *&Module);
2971 Node *parseUnqualifiedName(NameState *State, Node *Scope, ModuleName *Module);
2972 Node *parseUnnamedTypeName(NameState *State);
2973 Node *parseSourceName(NameState *State);
2974 Node *parseUnscopedName(NameState *State, bool *isSubstName);
2975 Node *parseNestedName(NameState *State);
2976 Node *parseCtorDtorName(Node *&SoFar, NameState *State);
2977
2978 Node *parseAbiTags(Node *N);
2979
2980 struct OperatorInfo {
2981 enum OIKind : unsigned char {
2982 Prefix, // Prefix unary: @ expr
2983 Postfix, // Postfix unary: expr @
2984 Binary, // Binary: lhs @ rhs
2985 Array, // Array index: lhs [ rhs ]
2986 Member, // Member access: lhs @ rhs
2987 New, // New
2988 Del, // Delete
2989 Call, // Function call: expr (expr*)
2990 CCast, // C cast: (type)expr
2991 Conditional, // Conditional: expr ? expr : expr
2992 NameOnly, // Overload only, not allowed in expression.
2993 // Below do not have operator names
2994 NamedCast, // Named cast, @<type>(expr)
2995 OfIdOp, // alignof, sizeof, typeid
2996
2997 Unnameable = NamedCast,
2998 };
2999 char Enc[2]; // Encoding
3000 OIKind Kind; // Kind of operator
3001 bool Flag : 1; // Entry-specific flag
3002 Node::Prec Prec : 7; // Precedence
3003 const char *Name; // Spelling
3004
3005 public:
3006 constexpr OperatorInfo(const char (&E)[3], OIKind K, bool F, Node::Prec P,
3007 const char *N)
3008 : Enc{E[0], E[1]}, Kind{K}, Flag{F}, Prec{P}, Name{N} {}
3009
3010 public:
3011 bool operator<(const OperatorInfo &Other) const {
3012 return *this < Other.Enc;
3013 }
3014 bool operator<(const char *Peek) const {
3015 return Enc[0] < Peek[0] || (Enc[0] == Peek[0] && Enc[1] < Peek[1]);
3016 }
3017 bool operator==(const char *Peek) const {
3018 return Enc[0] == Peek[0] && Enc[1] == Peek[1];
3019 }
3020 bool operator!=(const char *Peek) const { return !this->operator==(Peek); }
3021
3022 public:
3023 std::string_view getSymbol() const {
3024 std::string_view Res = Name;
3025 if (Kind < Unnameable) {
3026 DEMANGLE_ASSERT(starts_with(Res, "operator"),
3027 "operator name does not start with 'operator'");
3028 Res.remove_prefix(n: sizeof("operator") - 1);
3029 if (starts_with(self: Res, C: ' '))
3030 Res.remove_prefix(n: 1);
3031 }
3032 return Res;
3033 }
3034 std::string_view getName() const { return Name; }
3035 OIKind getKind() const { return Kind; }
3036 bool getFlag() const { return Flag; }
3037 Node::Prec getPrecedence() const { return Prec; }
3038 };
3039 static const OperatorInfo Ops[];
3040 static const size_t NumOps;
3041 const OperatorInfo *parseOperatorEncoding();
3042
3043 /// Parse the <unresolved-name> production.
3044 Node *parseUnresolvedName(bool Global);
3045 Node *parseSimpleId();
3046 Node *parseBaseUnresolvedName();
3047 Node *parseUnresolvedType();
3048 Node *parseDestructorName();
3049
3050 /// Top-level entry point into the parser.
3051 Node *parse(bool ParseParams = true);
3052};
3053
3054DEMANGLE_ABI const char *parse_discriminator(const char *first,
3055 const char *last);
3056
3057// <name> ::= <nested-name> // N
3058// ::= <local-name> # See Scope Encoding below // Z
3059// ::= <unscoped-template-name> <template-args>
3060// ::= <unscoped-name>
3061//
3062// <unscoped-template-name> ::= <unscoped-name>
3063// ::= <substitution>
3064template <typename Derived, typename Alloc>
3065Node *AbstractManglingParser<Derived, Alloc>::parseName(NameState *State) {
3066 if (look() == 'N')
3067 return getDerived().parseNestedName(State);
3068 if (look() == 'Z')
3069 return getDerived().parseLocalName(State);
3070
3071 Node *Result = nullptr;
3072 bool IsSubst = false;
3073
3074 Result = getDerived().parseUnscopedName(State, &IsSubst);
3075 if (!Result)
3076 return nullptr;
3077
3078 if (look() == 'I') {
3079 // ::= <unscoped-template-name> <template-args>
3080 if (!IsSubst)
3081 // An unscoped-template-name is substitutable.
3082 Subs.push_back(Elem: Result);
3083 Node *TA = getDerived().parseTemplateArgs(State != nullptr);
3084 if (TA == nullptr)
3085 return nullptr;
3086 if (State)
3087 State->EndsWithTemplateArgs = true;
3088 Result = make<NameWithTemplateArgs>(Result, TA);
3089 } else if (IsSubst) {
3090 // The substitution case must be followed by <template-args>.
3091 return nullptr;
3092 }
3093
3094 return Result;
3095}
3096
3097// <local-name> := Z <function encoding> E <entity name> [<discriminator>]
3098// := Z <function encoding> E s [<discriminator>]
3099// := Z <function encoding> Ed [ <parameter number> ] _ <entity name>
3100template <typename Derived, typename Alloc>
3101Node *AbstractManglingParser<Derived, Alloc>::parseLocalName(NameState *State) {
3102 if (!consumeIf('Z'))
3103 return nullptr;
3104 Node *Encoding = getDerived().parseEncoding();
3105 if (Encoding == nullptr || !consumeIf('E'))
3106 return nullptr;
3107
3108 if (consumeIf('s')) {
3109 First = parse_discriminator(first: First, last: Last);
3110 auto *StringLitName = make<NameType>("string literal");
3111 if (!StringLitName)
3112 return nullptr;
3113 return make<LocalName>(Encoding, StringLitName);
3114 }
3115
3116 // The template parameters of the inner name are unrelated to those of the
3117 // enclosing context.
3118 SaveTemplateParams SaveTemplateParamsScope(this);
3119
3120 if (consumeIf('d')) {
3121 parseNumber(AllowNegative: true);
3122 if (!consumeIf('_'))
3123 return nullptr;
3124 Node *N = getDerived().parseName(State);
3125 if (N == nullptr)
3126 return nullptr;
3127 return make<LocalName>(Encoding, N);
3128 }
3129
3130 Node *Entity = getDerived().parseName(State);
3131 if (Entity == nullptr)
3132 return nullptr;
3133 First = parse_discriminator(first: First, last: Last);
3134 return make<LocalName>(Encoding, Entity);
3135}
3136
3137// <unscoped-name> ::= <unqualified-name>
3138// ::= St <unqualified-name> # ::std::
3139// [*] extension
3140template <typename Derived, typename Alloc>
3141Node *
3142AbstractManglingParser<Derived, Alloc>::parseUnscopedName(NameState *State,
3143 bool *IsSubst) {
3144
3145 Node *Std = nullptr;
3146 if (consumeIf("St")) {
3147 Std = make<NameType>("std");
3148 if (Std == nullptr)
3149 return nullptr;
3150 }
3151
3152 Node *Res = nullptr;
3153 ModuleName *Module = nullptr;
3154 if (look() == 'S') {
3155 Node *S = getDerived().parseSubstitution();
3156 if (!S)
3157 return nullptr;
3158 if (S->getKind() == Node::KModuleName)
3159 Module = static_cast<ModuleName *>(S);
3160 else if (IsSubst && Std == nullptr) {
3161 Res = S;
3162 *IsSubst = true;
3163 } else {
3164 return nullptr;
3165 }
3166 }
3167
3168 if (Res == nullptr || Std != nullptr) {
3169 Res = getDerived().parseUnqualifiedName(State, Std, Module);
3170 }
3171
3172 return Res;
3173}
3174
3175// <unqualified-name> ::= [<module-name>] F? L? <operator-name> [<abi-tags>]
3176// ::= [<module-name>] <ctor-dtor-name> [<abi-tags>]
3177// ::= [<module-name>] F? L? <source-name> [<abi-tags>]
3178// ::= [<module-name>] L? <unnamed-type-name> [<abi-tags>]
3179// # structured binding declaration
3180// ::= [<module-name>] L? DC <source-name>+ E
3181template <typename Derived, typename Alloc>
3182Node *AbstractManglingParser<Derived, Alloc>::parseUnqualifiedName(
3183 NameState *State, Node *Scope, ModuleName *Module) {
3184 if (getDerived().parseModuleNameOpt(Module))
3185 return nullptr;
3186
3187 bool IsMemberLikeFriend = Scope && consumeIf('F');
3188
3189 consumeIf('L');
3190
3191 Node *Result;
3192 if (look() >= '1' && look() <= '9') {
3193 Result = getDerived().parseSourceName(State);
3194 } else if (look() == 'U') {
3195 Result = getDerived().parseUnnamedTypeName(State);
3196 } else if (consumeIf("DC")) {
3197 // Structured binding
3198 size_t BindingsBegin = Names.size();
3199 do {
3200 Node *Binding = getDerived().parseSourceName(State);
3201 if (Binding == nullptr)
3202 return nullptr;
3203 Names.push_back(Elem: Binding);
3204 } while (!consumeIf('E'));
3205 Result = make<StructuredBindingName>(popTrailingNodeArray(FromPosition: BindingsBegin));
3206 } else if (look() == 'C' || look() == 'D') {
3207 // A <ctor-dtor-name>.
3208 if (Scope == nullptr || Module != nullptr)
3209 return nullptr;
3210 Result = getDerived().parseCtorDtorName(Scope, State);
3211 } else {
3212 Result = getDerived().parseOperatorName(State);
3213 }
3214
3215 if (Result != nullptr && Module != nullptr)
3216 Result = make<ModuleEntity>(Module, Result);
3217 if (Result != nullptr)
3218 Result = getDerived().parseAbiTags(Result);
3219 if (Result != nullptr && IsMemberLikeFriend)
3220 Result = make<MemberLikeFriendName>(Scope, Result);
3221 else if (Result != nullptr && Scope != nullptr)
3222 Result = make<NestedName>(Scope, Result);
3223
3224 return Result;
3225}
3226
3227// <module-name> ::= <module-subname>
3228// ::= <module-name> <module-subname>
3229// ::= <substitution> # passed in by caller
3230// <module-subname> ::= W <source-name>
3231// ::= W P <source-name>
3232template <typename Derived, typename Alloc>
3233bool AbstractManglingParser<Derived, Alloc>::parseModuleNameOpt(
3234 ModuleName *&Module) {
3235 while (consumeIf('W')) {
3236 bool IsPartition = consumeIf('P');
3237 Node *Sub = getDerived().parseSourceName(nullptr);
3238 if (!Sub)
3239 return true;
3240 Module =
3241 static_cast<ModuleName *>(make<ModuleName>(Module, Sub, IsPartition));
3242 Subs.push_back(Elem: Module);
3243 }
3244
3245 return false;
3246}
3247
3248// <unnamed-type-name> ::= Ut [<nonnegative number>] _
3249// ::= <closure-type-name>
3250//
3251// <closure-type-name> ::= Ul <lambda-sig> E [ <nonnegative number> ] _
3252//
3253// <lambda-sig> ::= <template-param-decl>* [Q <requires-clause expression>]
3254// <parameter type>+ # or "v" if the lambda has no parameters
3255template <typename Derived, typename Alloc>
3256Node *
3257AbstractManglingParser<Derived, Alloc>::parseUnnamedTypeName(NameState *State) {
3258 // <template-params> refer to the innermost <template-args>. Clear out any
3259 // outer args that we may have inserted into TemplateParams.
3260 if (State != nullptr)
3261 TemplateParams.clear();
3262
3263 if (consumeIf("Ut")) {
3264 std::string_view Count = parseNumber();
3265 if (!consumeIf('_'))
3266 return nullptr;
3267 return make<UnnamedTypeName>(Count);
3268 }
3269 if (consumeIf("Ul")) {
3270 ScopedOverride<size_t> SwapParams(ParsingLambdaParamsAtLevel,
3271 TemplateParams.size());
3272 ScopedTemplateParamList LambdaTemplateParams(this);
3273
3274 size_t ParamsBegin = Names.size();
3275 while (getDerived().isTemplateParamDecl()) {
3276 Node *T =
3277 getDerived().parseTemplateParamDecl(LambdaTemplateParams.params());
3278 if (T == nullptr)
3279 return nullptr;
3280 Names.push_back(Elem: T);
3281 }
3282 NodeArray TempParams = popTrailingNodeArray(FromPosition: ParamsBegin);
3283
3284 // FIXME: If TempParams is empty and none of the function parameters
3285 // includes 'auto', we should remove LambdaTemplateParams from the
3286 // TemplateParams list. Unfortunately, we don't find out whether there are
3287 // any 'auto' parameters until too late in an example such as:
3288 //
3289 // template<typename T> void f(
3290 // decltype([](decltype([]<typename T>(T v) {}),
3291 // auto) {})) {}
3292 // template<typename T> void f(
3293 // decltype([](decltype([]<typename T>(T w) {}),
3294 // int) {})) {}
3295 //
3296 // Here, the type of v is at level 2 but the type of w is at level 1. We
3297 // don't find this out until we encounter the type of the next parameter.
3298 //
3299 // However, compilers can't actually cope with the former example in
3300 // practice, and it's likely to be made ill-formed in future, so we don't
3301 // need to support it here.
3302 //
3303 // If we encounter an 'auto' in the function parameter types, we will
3304 // recreate a template parameter scope for it, but any intervening lambdas
3305 // will be parsed in the 'wrong' template parameter depth.
3306 if (TempParams.empty())
3307 TemplateParams.pop_back();
3308
3309 Node *Requires1 = nullptr;
3310 if (consumeIf('Q')) {
3311 Requires1 = getDerived().parseConstraintExpr();
3312 if (Requires1 == nullptr)
3313 return nullptr;
3314 }
3315
3316 if (!consumeIf("v")) {
3317 do {
3318 Node *P = getDerived().parseType();
3319 if (P == nullptr)
3320 return nullptr;
3321 Names.push_back(Elem: P);
3322 } while (look() != 'E' && look() != 'Q');
3323 }
3324 NodeArray Params = popTrailingNodeArray(FromPosition: ParamsBegin);
3325
3326 Node *Requires2 = nullptr;
3327 if (consumeIf('Q')) {
3328 Requires2 = getDerived().parseConstraintExpr();
3329 if (Requires2 == nullptr)
3330 return nullptr;
3331 }
3332
3333 if (!consumeIf('E'))
3334 return nullptr;
3335
3336 std::string_view Count = parseNumber();
3337 if (!consumeIf('_'))
3338 return nullptr;
3339 return make<ClosureTypeName>(TempParams, Requires1, Params, Requires2,
3340 Count);
3341 }
3342 if (consumeIf("Ub")) {
3343 (void)parseNumber();
3344 if (!consumeIf('_'))
3345 return nullptr;
3346 return make<NameType>("'block-literal'");
3347 }
3348 return nullptr;
3349}
3350
3351// <source-name> ::= <positive length number> <identifier>
3352template <typename Derived, typename Alloc>
3353Node *AbstractManglingParser<Derived, Alloc>::parseSourceName(NameState *) {
3354 size_t Length = 0;
3355 if (parsePositiveInteger(Out: &Length))
3356 return nullptr;
3357 if (numLeft() < Length || Length == 0)
3358 return nullptr;
3359 std::string_view Name(First, Length);
3360 First += Length;
3361 if (starts_with(haystack: Name, needle: "_GLOBAL__N"))
3362 return make<NameType>("(anonymous namespace)");
3363 return make<NameType>(Name);
3364}
3365
3366// Operator encodings
3367template <typename Derived, typename Alloc>
3368const typename AbstractManglingParser<
3369 Derived, Alloc>::OperatorInfo AbstractManglingParser<Derived,
3370 Alloc>::Ops[] = {
3371 // Keep ordered by encoding
3372 {"aN", OperatorInfo::Binary, false, Node::Prec::Assign, "operator&="},
3373 {"aS", OperatorInfo::Binary, false, Node::Prec::Assign, "operator="},
3374 {"aa", OperatorInfo::Binary, false, Node::Prec::AndIf, "operator&&"},
3375 {"ad", OperatorInfo::Prefix, false, Node::Prec::Unary, "operator&"},
3376 {"an", OperatorInfo::Binary, false, Node::Prec::And, "operator&"},
3377 {"at", OperatorInfo::OfIdOp, /*Type*/ true, Node::Prec::Unary, "alignof "},
3378 {"aw", OperatorInfo::NameOnly, false, Node::Prec::Primary,
3379 "operator co_await"},
3380 {"az", OperatorInfo::OfIdOp, /*Type*/ false, Node::Prec::Unary, "alignof "},
3381 {"cc", OperatorInfo::NamedCast, false, Node::Prec::Postfix, "const_cast"},
3382 {"cl", OperatorInfo::Call, /*Paren*/ false, Node::Prec::Postfix,
3383 "operator()"},
3384 {"cm", OperatorInfo::Binary, false, Node::Prec::Comma, "operator,"},
3385 {"co", OperatorInfo::Prefix, false, Node::Prec::Unary, "operator~"},
3386 {"cp", OperatorInfo::Call, /*Paren*/ true, Node::Prec::Postfix,
3387 "operator()"},
3388 {"cv", OperatorInfo::CCast, false, Node::Prec::Cast, "operator"}, // C Cast
3389 {"dV", OperatorInfo::Binary, false, Node::Prec::Assign, "operator/="},
3390 {"da", OperatorInfo::Del, /*Ary*/ true, Node::Prec::Unary,
3391 "operator delete[]"},
3392 {"dc", OperatorInfo::NamedCast, false, Node::Prec::Postfix, "dynamic_cast"},
3393 {"de", OperatorInfo::Prefix, false, Node::Prec::Unary, "operator*"},
3394 {"dl", OperatorInfo::Del, /*Ary*/ false, Node::Prec::Unary,
3395 "operator delete"},
3396 {"ds", OperatorInfo::Member, /*Named*/ false, Node::Prec::PtrMem,
3397 "operator.*"},
3398 {"dt", OperatorInfo::Member, /*Named*/ false, Node::Prec::Postfix,
3399 "operator."},
3400 {"dv", OperatorInfo::Binary, false, Node::Prec::Assign, "operator/"},
3401 {"eO", OperatorInfo::Binary, false, Node::Prec::Assign, "operator^="},
3402 {"eo", OperatorInfo::Binary, false, Node::Prec::Xor, "operator^"},
3403 {"eq", OperatorInfo::Binary, false, Node::Prec::Equality, "operator=="},
3404 {"ge", OperatorInfo::Binary, false, Node::Prec::Relational, "operator>="},
3405 {"gt", OperatorInfo::Binary, false, Node::Prec::Relational, "operator>"},
3406 {"ix", OperatorInfo::Array, false, Node::Prec::Postfix, "operator[]"},
3407 {"lS", OperatorInfo::Binary, false, Node::Prec::Assign, "operator<<="},
3408 {"le", OperatorInfo::Binary, false, Node::Prec::Relational, "operator<="},
3409 {"ls", OperatorInfo::Binary, false, Node::Prec::Shift, "operator<<"},
3410 {"lt", OperatorInfo::Binary, false, Node::Prec::Relational, "operator<"},
3411 {"mI", OperatorInfo::Binary, false, Node::Prec::Assign, "operator-="},
3412 {"mL", OperatorInfo::Binary, false, Node::Prec::Assign, "operator*="},
3413 {"mi", OperatorInfo::Binary, false, Node::Prec::Additive, "operator-"},
3414 {"ml", OperatorInfo::Binary, false, Node::Prec::Multiplicative,
3415 "operator*"},
3416 {"mm", OperatorInfo::Postfix, false, Node::Prec::Postfix, "operator--"},
3417 {"na", OperatorInfo::New, /*Ary*/ true, Node::Prec::Unary,
3418 "operator new[]"},
3419 {"ne", OperatorInfo::Binary, false, Node::Prec::Equality, "operator!="},
3420 {"ng", OperatorInfo::Prefix, false, Node::Prec::Unary, "operator-"},
3421 {"nt", OperatorInfo::Prefix, false, Node::Prec::Unary, "operator!"},
3422 {"nw", OperatorInfo::New, /*Ary*/ false, Node::Prec::Unary, "operator new"},
3423 {"oR", OperatorInfo::Binary, false, Node::Prec::Assign, "operator|="},
3424 {"oo", OperatorInfo::Binary, false, Node::Prec::OrIf, "operator||"},
3425 {"or", OperatorInfo::Binary, false, Node::Prec::Ior, "operator|"},
3426 {"pL", OperatorInfo::Binary, false, Node::Prec::Assign, "operator+="},
3427 {"pl", OperatorInfo::Binary, false, Node::Prec::Additive, "operator+"},
3428 {"pm", OperatorInfo::Member, /*Named*/ true, Node::Prec::PtrMem,
3429 "operator->*"},
3430 {"pp", OperatorInfo::Postfix, false, Node::Prec::Postfix, "operator++"},
3431 {"ps", OperatorInfo::Prefix, false, Node::Prec::Unary, "operator+"},
3432 {"pt", OperatorInfo::Member, /*Named*/ true, Node::Prec::Postfix,
3433 "operator->"},
3434 {"qu", OperatorInfo::Conditional, false, Node::Prec::Conditional,
3435 "operator?"},
3436 {"rM", OperatorInfo::Binary, false, Node::Prec::Assign, "operator%="},
3437 {"rS", OperatorInfo::Binary, false, Node::Prec::Assign, "operator>>="},
3438 {"rc", OperatorInfo::NamedCast, false, Node::Prec::Postfix,
3439 "reinterpret_cast"},
3440 {"rm", OperatorInfo::Binary, false, Node::Prec::Multiplicative,
3441 "operator%"},
3442 {"rs", OperatorInfo::Binary, false, Node::Prec::Shift, "operator>>"},
3443 {"sc", OperatorInfo::NamedCast, false, Node::Prec::Postfix, "static_cast"},
3444 {"ss", OperatorInfo::Binary, false, Node::Prec::Spaceship, "operator<=>"},
3445 {"st", OperatorInfo::OfIdOp, /*Type*/ true, Node::Prec::Unary, "sizeof "},
3446 {"sz", OperatorInfo::OfIdOp, /*Type*/ false, Node::Prec::Unary, "sizeof "},
3447 {"te", OperatorInfo::OfIdOp, /*Type*/ false, Node::Prec::Postfix,
3448 "typeid "},
3449 {"ti", OperatorInfo::OfIdOp, /*Type*/ true, Node::Prec::Postfix, "typeid "},
3450};
3451template <typename Derived, typename Alloc>
3452const size_t AbstractManglingParser<Derived, Alloc>::NumOps = sizeof(Ops) /
3453 sizeof(Ops[0]);
3454
3455// If the next 2 chars are an operator encoding, consume them and return their
3456// OperatorInfo. Otherwise return nullptr.
3457template <typename Derived, typename Alloc>
3458const typename AbstractManglingParser<Derived, Alloc>::OperatorInfo *
3459AbstractManglingParser<Derived, Alloc>::parseOperatorEncoding() {
3460 if (numLeft() < 2)
3461 return nullptr;
3462
3463 // We can't use lower_bound as that can link to symbols in the C++ library,
3464 // and this must remain independent of that.
3465 size_t lower = 0u, upper = NumOps - 1; // Inclusive bounds.
3466 while (upper != lower) {
3467 size_t middle = (upper + lower) / 2;
3468 if (Ops[middle] < First)
3469 lower = middle + 1;
3470 else
3471 upper = middle;
3472 }
3473 if (Ops[lower] != First)
3474 return nullptr;
3475
3476 First += 2;
3477 return &Ops[lower];
3478}
3479
3480// <operator-name> ::= See parseOperatorEncoding()
3481// ::= li <source-name> # operator ""
3482// ::= v <digit> <source-name> # vendor extended operator
3483template <typename Derived, typename Alloc>
3484Node *
3485AbstractManglingParser<Derived, Alloc>::parseOperatorName(NameState *State) {
3486 if (const auto *Op = parseOperatorEncoding()) {
3487 if (Op->getKind() == OperatorInfo::CCast) {
3488 // ::= cv <type> # (cast)
3489 ScopedOverride<bool> SaveTemplate(TryToParseTemplateArgs, false);
3490 // If we're parsing an encoding, State != nullptr and the conversion
3491 // operators' <type> could have a <template-param> that refers to some
3492 // <template-arg>s further ahead in the mangled name.
3493 ScopedOverride<bool> SavePermit(PermitForwardTemplateReferences,
3494 PermitForwardTemplateReferences ||
3495 State != nullptr);
3496 Node *Ty = getDerived().parseType();
3497 if (Ty == nullptr)
3498 return nullptr;
3499 if (State) State->CtorDtorConversion = true;
3500 return make<ConversionOperatorType>(Ty);
3501 }
3502
3503 if (Op->getKind() >= OperatorInfo::Unnameable)
3504 /* Not a nameable operator. */
3505 return nullptr;
3506 if (Op->getKind() == OperatorInfo::Member && !Op->getFlag())
3507 /* Not a nameable MemberExpr */
3508 return nullptr;
3509
3510 return make<NameType>(Op->getName());
3511 }
3512
3513 if (consumeIf("li")) {
3514 // ::= li <source-name> # operator ""
3515 Node *SN = getDerived().parseSourceName(State);
3516 if (SN == nullptr)
3517 return nullptr;
3518 return make<LiteralOperator>(SN);
3519 }
3520
3521 if (consumeIf('v')) {
3522 // ::= v <digit> <source-name> # vendor extended operator
3523 if (look() >= '0' && look() <= '9') {
3524 First++;
3525 Node *SN = getDerived().parseSourceName(State);
3526 if (SN == nullptr)
3527 return nullptr;
3528 return make<ConversionOperatorType>(SN);
3529 }
3530 return nullptr;
3531 }
3532
3533 return nullptr;
3534}
3535
3536// <ctor-dtor-name> ::= C1 # complete object constructor
3537// ::= C2 # base object constructor
3538// ::= C3 # complete object allocating constructor
3539// extension ::= C4 # gcc old-style "[unified]" constructor
3540// extension ::= C5 # the COMDAT used for ctors
3541// ::= D0 # deleting destructor
3542// ::= D1 # complete object destructor
3543// ::= D2 # base object destructor
3544// extension ::= D4 # gcc old-style "[unified]" destructor
3545// extension ::= D5 # the COMDAT used for dtors
3546template <typename Derived, typename Alloc>
3547Node *
3548AbstractManglingParser<Derived, Alloc>::parseCtorDtorName(Node *&SoFar,
3549 NameState *State) {
3550 if (SoFar->getKind() == Node::KSpecialSubstitution) {
3551 // Expand the special substitution.
3552 SoFar = make<ExpandedSpecialSubstitution>(
3553 static_cast<SpecialSubstitution *>(SoFar));
3554 if (!SoFar)
3555 return nullptr;
3556 }
3557
3558 if (consumeIf('C')) {
3559 bool IsInherited = consumeIf('I');
3560 if (look() != '1' && look() != '2' && look() != '3' && look() != '4' &&
3561 look() != '5')
3562 return nullptr;
3563 int Variant = look() - '0';
3564 ++First;
3565 if (State) State->CtorDtorConversion = true;
3566 if (IsInherited) {
3567 if (getDerived().parseName(State) == nullptr)
3568 return nullptr;
3569 }
3570 return make<CtorDtorName>(SoFar, /*IsDtor=*/false, Variant);
3571 }
3572
3573 if (look() == 'D' && (look(Lookahead: 1) == '0' || look(Lookahead: 1) == '1' || look(Lookahead: 1) == '2' ||
3574 look(Lookahead: 1) == '4' || look(Lookahead: 1) == '5')) {
3575 int Variant = look(Lookahead: 1) - '0';
3576 First += 2;
3577 if (State) State->CtorDtorConversion = true;
3578 return make<CtorDtorName>(SoFar, /*IsDtor=*/true, Variant);
3579 }
3580
3581 return nullptr;
3582}
3583
3584// <nested-name> ::= N [<CV-Qualifiers>] [<ref-qualifier>] <prefix>
3585// <unqualified-name> E
3586// ::= N [<CV-Qualifiers>] [<ref-qualifier>] <template-prefix>
3587// <template-args> E
3588//
3589// <prefix> ::= <prefix> <unqualified-name>
3590// ::= <template-prefix> <template-args>
3591// ::= <template-param>
3592// ::= <decltype>
3593// ::= # empty
3594// ::= <substitution>
3595// ::= <prefix> <data-member-prefix>
3596// [*] extension
3597//
3598// <data-member-prefix> := <member source-name> [<template-args>] M
3599//
3600// <template-prefix> ::= <prefix> <template unqualified-name>
3601// ::= <template-param>
3602// ::= <substitution>
3603template <typename Derived, typename Alloc>
3604Node *
3605AbstractManglingParser<Derived, Alloc>::parseNestedName(NameState *State) {
3606 if (!consumeIf('N'))
3607 return nullptr;
3608
3609 // 'H' specifies that the encoding that follows
3610 // has an explicit object parameter.
3611 if (!consumeIf('H')) {
3612 Qualifiers CVTmp = parseCVQualifiers();
3613 if (State)
3614 State->CVQualifiers = CVTmp;
3615
3616 if (consumeIf('O')) {
3617 if (State)
3618 State->ReferenceQualifier = FrefQualRValue;
3619 } else if (consumeIf('R')) {
3620 if (State)
3621 State->ReferenceQualifier = FrefQualLValue;
3622 } else {
3623 if (State)
3624 State->ReferenceQualifier = FrefQualNone;
3625 }
3626 } else if (State) {
3627 State->HasExplicitObjectParameter = true;
3628 }
3629
3630 Node *SoFar = nullptr;
3631 while (!consumeIf('E')) {
3632 if (State)
3633 // Only set end-with-template on the case that does that.
3634 State->EndsWithTemplateArgs = false;
3635
3636 if (look() == 'T') {
3637 // ::= <template-param>
3638 if (SoFar != nullptr)
3639 return nullptr; // Cannot have a prefix.
3640 SoFar = getDerived().parseTemplateParam();
3641 } else if (look() == 'I') {
3642 // ::= <template-prefix> <template-args>
3643 if (SoFar == nullptr)
3644 return nullptr; // Must have a prefix.
3645 Node *TA = getDerived().parseTemplateArgs(State != nullptr);
3646 if (TA == nullptr)
3647 return nullptr;
3648 if (SoFar->getKind() == Node::KNameWithTemplateArgs)
3649 // Semantically <template-args> <template-args> cannot be generated by a
3650 // C++ entity. There will always be [something like] a name between
3651 // them.
3652 return nullptr;
3653 if (State)
3654 State->EndsWithTemplateArgs = true;
3655 SoFar = make<NameWithTemplateArgs>(SoFar, TA);
3656 } else if (look() == 'D' && (look(Lookahead: 1) == 't' || look(Lookahead: 1) == 'T')) {
3657 // ::= <decltype>
3658 if (SoFar != nullptr)
3659 return nullptr; // Cannot have a prefix.
3660 SoFar = getDerived().parseDecltype();
3661 } else {
3662 ModuleName *Module = nullptr;
3663
3664 if (look() == 'S') {
3665 // ::= <substitution>
3666 Node *S = nullptr;
3667 if (look(Lookahead: 1) == 't') {
3668 First += 2;
3669 S = make<NameType>("std");
3670 } else {
3671 S = getDerived().parseSubstitution();
3672 }
3673 if (!S)
3674 return nullptr;
3675 if (S->getKind() == Node::KModuleName) {
3676 Module = static_cast<ModuleName *>(S);
3677 } else if (SoFar != nullptr) {
3678 return nullptr; // Cannot have a prefix.
3679 } else {
3680 SoFar = S;
3681 continue; // Do not push a new substitution.
3682 }
3683 }
3684
3685 // ::= [<prefix>] <unqualified-name>
3686 SoFar = getDerived().parseUnqualifiedName(State, SoFar, Module);
3687 }
3688
3689 if (SoFar == nullptr)
3690 return nullptr;
3691 Subs.push_back(Elem: SoFar);
3692
3693 // No longer used.
3694 // <data-member-prefix> := <member source-name> [<template-args>] M
3695 consumeIf('M');
3696 }
3697
3698 if (SoFar == nullptr || Subs.empty())
3699 return nullptr;
3700
3701 Subs.pop_back();
3702 return SoFar;
3703}
3704
3705// <simple-id> ::= <source-name> [ <template-args> ]
3706template <typename Derived, typename Alloc>
3707Node *AbstractManglingParser<Derived, Alloc>::parseSimpleId() {
3708 Node *SN = getDerived().parseSourceName(/*NameState=*/nullptr);
3709 if (SN == nullptr)
3710 return nullptr;
3711 if (look() == 'I') {
3712 Node *TA = getDerived().parseTemplateArgs();
3713 if (TA == nullptr)
3714 return nullptr;
3715 return make<NameWithTemplateArgs>(SN, TA);
3716 }
3717 return SN;
3718}
3719
3720// <destructor-name> ::= <unresolved-type> # e.g., ~T or ~decltype(f())
3721// ::= <simple-id> # e.g., ~A<2*N>
3722template <typename Derived, typename Alloc>
3723Node *AbstractManglingParser<Derived, Alloc>::parseDestructorName() {
3724 Node *Result;
3725 if (std::isdigit(c: look()))
3726 Result = getDerived().parseSimpleId();
3727 else
3728 Result = getDerived().parseUnresolvedType();
3729 if (Result == nullptr)
3730 return nullptr;
3731 return make<DtorName>(Result);
3732}
3733
3734// <unresolved-type> ::= <template-param>
3735// ::= <decltype>
3736// ::= <substitution>
3737template <typename Derived, typename Alloc>
3738Node *AbstractManglingParser<Derived, Alloc>::parseUnresolvedType() {
3739 if (look() == 'T') {
3740 Node *TP = getDerived().parseTemplateParam();
3741 if (TP == nullptr)
3742 return nullptr;
3743 Subs.push_back(Elem: TP);
3744 return TP;
3745 }
3746 if (look() == 'D') {
3747 Node *DT = getDerived().parseDecltype();
3748 if (DT == nullptr)
3749 return nullptr;
3750 Subs.push_back(Elem: DT);
3751 return DT;
3752 }
3753 return getDerived().parseSubstitution();
3754}
3755
3756// <base-unresolved-name> ::= <simple-id> # unresolved name
3757// extension ::= <operator-name> # unresolved operator-function-id
3758// extension ::= <operator-name> <template-args> # unresolved operator template-id
3759// ::= on <operator-name> # unresolved operator-function-id
3760// ::= on <operator-name> <template-args> # unresolved operator template-id
3761// ::= dn <destructor-name> # destructor or pseudo-destructor;
3762// # e.g. ~X or ~X<N-1>
3763template <typename Derived, typename Alloc>
3764Node *AbstractManglingParser<Derived, Alloc>::parseBaseUnresolvedName() {
3765 if (std::isdigit(c: look()))
3766 return getDerived().parseSimpleId();
3767
3768 if (consumeIf("dn"))
3769 return getDerived().parseDestructorName();
3770
3771 consumeIf("on");
3772
3773 Node *Oper = getDerived().parseOperatorName(/*NameState=*/nullptr);
3774 if (Oper == nullptr)
3775 return nullptr;
3776 if (look() == 'I') {
3777 Node *TA = getDerived().parseTemplateArgs();
3778 if (TA == nullptr)
3779 return nullptr;
3780 return make<NameWithTemplateArgs>(Oper, TA);
3781 }
3782 return Oper;
3783}
3784
3785// <unresolved-name>
3786// extension ::= srN <unresolved-type> [<template-args>] <unresolved-qualifier-level>* E <base-unresolved-name>
3787// ::= [gs] <base-unresolved-name> # x or (with "gs") ::x
3788// ::= [gs] sr <unresolved-qualifier-level>+ E <base-unresolved-name>
3789// # A::x, N::y, A<T>::z; "gs" means leading "::"
3790// [gs] has been parsed by caller.
3791// ::= sr <unresolved-type> <base-unresolved-name> # T::x / decltype(p)::x
3792// extension ::= sr <unresolved-type> <template-args> <base-unresolved-name>
3793// # T::N::x /decltype(p)::N::x
3794// (ignored) ::= srN <unresolved-type> <unresolved-qualifier-level>+ E <base-unresolved-name>
3795//
3796// <unresolved-qualifier-level> ::= <simple-id>
3797template <typename Derived, typename Alloc>
3798Node *AbstractManglingParser<Derived, Alloc>::parseUnresolvedName(bool Global) {
3799 Node *SoFar = nullptr;
3800
3801 // srN <unresolved-type> [<template-args>] <unresolved-qualifier-level>* E <base-unresolved-name>
3802 // srN <unresolved-type> <unresolved-qualifier-level>+ E <base-unresolved-name>
3803 if (consumeIf("srN")) {
3804 SoFar = getDerived().parseUnresolvedType();
3805 if (SoFar == nullptr)
3806 return nullptr;
3807
3808 if (look() == 'I') {
3809 Node *TA = getDerived().parseTemplateArgs();
3810 if (TA == nullptr)
3811 return nullptr;
3812 SoFar = make<NameWithTemplateArgs>(SoFar, TA);
3813 if (!SoFar)
3814 return nullptr;
3815 }
3816
3817 while (!consumeIf('E')) {
3818 Node *Qual = getDerived().parseSimpleId();
3819 if (Qual == nullptr)
3820 return nullptr;
3821 SoFar = make<QualifiedName>(SoFar, Qual);
3822 if (!SoFar)
3823 return nullptr;
3824 }
3825
3826 Node *Base = getDerived().parseBaseUnresolvedName();
3827 if (Base == nullptr)
3828 return nullptr;
3829 return make<QualifiedName>(SoFar, Base);
3830 }
3831
3832 // [gs] <base-unresolved-name> # x or (with "gs") ::x
3833 if (!consumeIf("sr")) {
3834 SoFar = getDerived().parseBaseUnresolvedName();
3835 if (SoFar == nullptr)
3836 return nullptr;
3837 if (Global)
3838 SoFar = make<GlobalQualifiedName>(SoFar);
3839 return SoFar;
3840 }
3841
3842 // [gs] sr <unresolved-qualifier-level>+ E <base-unresolved-name>
3843 if (std::isdigit(c: look())) {
3844 do {
3845 Node *Qual = getDerived().parseSimpleId();
3846 if (Qual == nullptr)
3847 return nullptr;
3848 if (SoFar)
3849 SoFar = make<QualifiedName>(SoFar, Qual);
3850 else if (Global)
3851 SoFar = make<GlobalQualifiedName>(Qual);
3852 else
3853 SoFar = Qual;
3854 if (!SoFar)
3855 return nullptr;
3856 } while (!consumeIf('E'));
3857 }
3858 // sr <unresolved-type> <base-unresolved-name>
3859 // sr <unresolved-type> <template-args> <base-unresolved-name>
3860 else {
3861 SoFar = getDerived().parseUnresolvedType();
3862 if (SoFar == nullptr)
3863 return nullptr;
3864
3865 if (look() == 'I') {
3866 Node *TA = getDerived().parseTemplateArgs();
3867 if (TA == nullptr)
3868 return nullptr;
3869 SoFar = make<NameWithTemplateArgs>(SoFar, TA);
3870 if (!SoFar)
3871 return nullptr;
3872 }
3873 }
3874
3875 DEMANGLE_ASSERT(SoFar != nullptr, "");
3876
3877 Node *Base = getDerived().parseBaseUnresolvedName();
3878 if (Base == nullptr)
3879 return nullptr;
3880 return make<QualifiedName>(SoFar, Base);
3881}
3882
3883// <abi-tags> ::= <abi-tag> [<abi-tags>]
3884// <abi-tag> ::= B <source-name>
3885template <typename Derived, typename Alloc>
3886Node *AbstractManglingParser<Derived, Alloc>::parseAbiTags(Node *N) {
3887 while (consumeIf('B')) {
3888 std::string_view SN = parseBareSourceName();
3889 if (SN.empty())
3890 return nullptr;
3891 N = make<AbiTagAttr>(N, SN);
3892 if (!N)
3893 return nullptr;
3894 }
3895 return N;
3896}
3897
3898// <number> ::= [n] <non-negative decimal integer>
3899template <typename Alloc, typename Derived>
3900std::string_view
3901AbstractManglingParser<Alloc, Derived>::parseNumber(bool AllowNegative) {
3902 const char *Tmp = First;
3903 if (AllowNegative)
3904 consumeIf('n');
3905 if (numLeft() == 0 || !std::isdigit(c: *First))
3906 return std::string_view();
3907 while (numLeft() != 0 && std::isdigit(c: *First))
3908 ++First;
3909 return std::string_view(Tmp, First - Tmp);
3910}
3911
3912// <positive length number> ::= [0-9]*
3913template <typename Alloc, typename Derived>
3914bool AbstractManglingParser<Alloc, Derived>::parsePositiveInteger(size_t *Out) {
3915 *Out = 0;
3916 if (look() < '0' || look() > '9')
3917 return true;
3918 while (look() >= '0' && look() <= '9') {
3919 *Out *= 10;
3920 *Out += static_cast<size_t>(consume() - '0');
3921 }
3922 return false;
3923}
3924
3925template <typename Alloc, typename Derived>
3926std::string_view AbstractManglingParser<Alloc, Derived>::parseBareSourceName() {
3927 size_t Int = 0;
3928 if (parsePositiveInteger(Out: &Int) || numLeft() < Int)
3929 return {};
3930 std::string_view R(First, Int);
3931 First += Int;
3932 return R;
3933}
3934
3935// <function-type> ::= [<CV-qualifiers>] [<exception-spec>] [Dx] F [Y] <bare-function-type> [<ref-qualifier>] E
3936//
3937// <exception-spec> ::= Do # non-throwing exception-specification (e.g., noexcept, throw())
3938// ::= DO <expression> E # computed (instantiation-dependent) noexcept
3939// ::= Dw <type>+ E # dynamic exception specification with instantiation-dependent types
3940//
3941// <ref-qualifier> ::= R # & ref-qualifier
3942// <ref-qualifier> ::= O # && ref-qualifier
3943template <typename Derived, typename Alloc>
3944Node *AbstractManglingParser<Derived, Alloc>::parseFunctionType() {
3945 Qualifiers CVQuals = parseCVQualifiers();
3946
3947 Node *ExceptionSpec = nullptr;
3948 if (consumeIf("Do")) {
3949 ExceptionSpec = make<NameType>("noexcept");
3950 if (!ExceptionSpec)
3951 return nullptr;
3952 } else if (consumeIf("DO")) {
3953 Node *E = getDerived().parseExpr();
3954 if (E == nullptr || !consumeIf('E'))
3955 return nullptr;
3956 ExceptionSpec = make<NoexceptSpec>(E);
3957 if (!ExceptionSpec)
3958 return nullptr;
3959 } else if (consumeIf("Dw")) {
3960 size_t SpecsBegin = Names.size();
3961 while (!consumeIf('E')) {
3962 Node *T = getDerived().parseType();
3963 if (T == nullptr)
3964 return nullptr;
3965 Names.push_back(Elem: T);
3966 }
3967 ExceptionSpec =
3968 make<DynamicExceptionSpec>(popTrailingNodeArray(FromPosition: SpecsBegin));
3969 if (!ExceptionSpec)
3970 return nullptr;
3971 }
3972
3973 consumeIf("Dx"); // transaction safe
3974
3975 if (!consumeIf('F'))
3976 return nullptr;
3977 consumeIf('Y'); // extern "C"
3978 Node *ReturnType = getDerived().parseType();
3979 if (ReturnType == nullptr)
3980 return nullptr;
3981
3982 FunctionRefQual ReferenceQualifier = FrefQualNone;
3983 size_t ParamsBegin = Names.size();
3984 while (true) {
3985 if (consumeIf('E'))
3986 break;
3987 if (consumeIf('v'))
3988 continue;
3989 if (consumeIf("RE")) {
3990 ReferenceQualifier = FrefQualLValue;
3991 break;
3992 }
3993 if (consumeIf("OE")) {
3994 ReferenceQualifier = FrefQualRValue;
3995 break;
3996 }
3997 Node *T = getDerived().parseType();
3998 if (T == nullptr)
3999 return nullptr;
4000 Names.push_back(Elem: T);
4001 }
4002
4003 NodeArray Params = popTrailingNodeArray(FromPosition: ParamsBegin);
4004 return make<FunctionType>(ReturnType, Params, CVQuals,
4005 ReferenceQualifier, ExceptionSpec);
4006}
4007
4008// extension:
4009// <vector-type> ::= Dv <positive dimension number> _ <extended element type>
4010// ::= Dv [<dimension expression>] _ <element type>
4011// <extended element type> ::= <element type>
4012// ::= p # AltiVec vector pixel
4013template <typename Derived, typename Alloc>
4014Node *AbstractManglingParser<Derived, Alloc>::parseVectorType() {
4015 if (!consumeIf("Dv"))
4016 return nullptr;
4017 if (look() >= '1' && look() <= '9') {
4018 Node *DimensionNumber = make<NameType>(parseNumber());
4019 if (!DimensionNumber)
4020 return nullptr;
4021 if (!consumeIf('_'))
4022 return nullptr;
4023 if (consumeIf('p'))
4024 return make<PixelVectorType>(DimensionNumber);
4025 Node *ElemType = getDerived().parseType();
4026 if (ElemType == nullptr)
4027 return nullptr;
4028 return make<VectorType>(ElemType, DimensionNumber);
4029 }
4030
4031 if (!consumeIf('_')) {
4032 Node *DimExpr = getDerived().parseExpr();
4033 if (!DimExpr)
4034 return nullptr;
4035 if (!consumeIf('_'))
4036 return nullptr;
4037 Node *ElemType = getDerived().parseType();
4038 if (!ElemType)
4039 return nullptr;
4040 return make<VectorType>(ElemType, DimExpr);
4041 }
4042 Node *ElemType = getDerived().parseType();
4043 if (!ElemType)
4044 return nullptr;
4045 return make<VectorType>(ElemType, /*Dimension=*/nullptr);
4046}
4047
4048// <decltype> ::= Dt <expression> E # decltype of an id-expression or class member access (C++0x)
4049// ::= DT <expression> E # decltype of an expression (C++0x)
4050template <typename Derived, typename Alloc>
4051Node *AbstractManglingParser<Derived, Alloc>::parseDecltype() {
4052 if (!consumeIf('D'))
4053 return nullptr;
4054 if (!consumeIf('t') && !consumeIf('T'))
4055 return nullptr;
4056 Node *E = getDerived().parseExpr();
4057 if (E == nullptr)
4058 return nullptr;
4059 if (!consumeIf('E'))
4060 return nullptr;
4061 return make<EnclosingExpr>("decltype", E);
4062}
4063
4064// <array-type> ::= A <positive dimension number> _ <element type>
4065// ::= A [<dimension expression>] _ <element type>
4066template <typename Derived, typename Alloc>
4067Node *AbstractManglingParser<Derived, Alloc>::parseArrayType() {
4068 if (!consumeIf('A'))
4069 return nullptr;
4070
4071 Node *Dimension = nullptr;
4072
4073 if (std::isdigit(c: look())) {
4074 Dimension = make<NameType>(parseNumber());
4075 if (!Dimension)
4076 return nullptr;
4077 if (!consumeIf('_'))
4078 return nullptr;
4079 } else if (!consumeIf('_')) {
4080 Node *DimExpr = getDerived().parseExpr();
4081 if (DimExpr == nullptr)
4082 return nullptr;
4083 if (!consumeIf('_'))
4084 return nullptr;
4085 Dimension = DimExpr;
4086 }
4087
4088 Node *Ty = getDerived().parseType();
4089 if (Ty == nullptr)
4090 return nullptr;
4091 return make<ArrayType>(Ty, Dimension);
4092}
4093
4094// <pointer-to-member-type> ::= M <class type> <member type>
4095template <typename Derived, typename Alloc>
4096Node *AbstractManglingParser<Derived, Alloc>::parsePointerToMemberType() {
4097 if (!consumeIf('M'))
4098 return nullptr;
4099 Node *ClassType = getDerived().parseType();
4100 if (ClassType == nullptr)
4101 return nullptr;
4102 Node *MemberType = getDerived().parseType();
4103 if (MemberType == nullptr)
4104 return nullptr;
4105 return make<PointerToMemberType>(ClassType, MemberType);
4106}
4107
4108// <class-enum-type> ::= <name> # non-dependent type name, dependent type name, or dependent typename-specifier
4109// ::= Ts <name> # dependent elaborated type specifier using 'struct' or 'class'
4110// ::= Tu <name> # dependent elaborated type specifier using 'union'
4111// ::= Te <name> # dependent elaborated type specifier using 'enum'
4112template <typename Derived, typename Alloc>
4113Node *AbstractManglingParser<Derived, Alloc>::parseClassEnumType() {
4114 std::string_view ElabSpef;
4115 if (consumeIf("Ts"))
4116 ElabSpef = "struct";
4117 else if (consumeIf("Tu"))
4118 ElabSpef = "union";
4119 else if (consumeIf("Te"))
4120 ElabSpef = "enum";
4121
4122 Node *Name = getDerived().parseName();
4123 if (Name == nullptr)
4124 return nullptr;
4125
4126 if (!ElabSpef.empty())
4127 return make<ElaboratedTypeSpefType>(ElabSpef, Name);
4128
4129 return Name;
4130}
4131
4132// <qualified-type> ::= <qualifiers> <type>
4133// <qualifiers> ::= <extended-qualifier>* <CV-qualifiers>
4134// <extended-qualifier> ::= U <source-name> [<template-args>] # vendor extended type qualifier
4135template <typename Derived, typename Alloc>
4136Node *AbstractManglingParser<Derived, Alloc>::parseQualifiedType() {
4137 if (consumeIf('U')) {
4138 std::string_view Qual = parseBareSourceName();
4139 if (Qual.empty())
4140 return nullptr;
4141
4142 // extension ::= U <objc-name> <objc-type> # objc-type<identifier>
4143 if (starts_with(haystack: Qual, needle: "objcproto")) {
4144 constexpr size_t Len = sizeof("objcproto") - 1;
4145 std::string_view ProtoSourceName(Qual.data() + Len, Qual.size() - Len);
4146 std::string_view Proto;
4147 {
4148 ScopedOverride<const char *> SaveFirst(First, ProtoSourceName.data()),
4149 SaveLast(Last, &*ProtoSourceName.rbegin() + 1);
4150 Proto = parseBareSourceName();
4151 }
4152 if (Proto.empty())
4153 return nullptr;
4154 Node *Child = getDerived().parseQualifiedType();
4155 if (Child == nullptr)
4156 return nullptr;
4157 return make<ObjCProtoName>(Child, Proto);
4158 }
4159
4160 Node *TA = nullptr;
4161 if (look() == 'I') {
4162 TA = getDerived().parseTemplateArgs();
4163 if (TA == nullptr)
4164 return nullptr;
4165 }
4166
4167 Node *Child = getDerived().parseQualifiedType();
4168 if (Child == nullptr)
4169 return nullptr;
4170 return make<VendorExtQualType>(Child, Qual, TA);
4171 }
4172
4173 Qualifiers Quals = parseCVQualifiers();
4174 Node *Ty = getDerived().parseType();
4175 if (Ty == nullptr)
4176 return nullptr;
4177 if (Quals != QualNone)
4178 Ty = make<QualType>(Ty, Quals);
4179 return Ty;
4180}
4181
4182// <type> ::= <builtin-type>
4183// ::= <qualified-type>
4184// ::= <function-type>
4185// ::= <class-enum-type>
4186// ::= <array-type>
4187// ::= <pointer-to-member-type>
4188// ::= <template-param>
4189// ::= <template-template-param> <template-args>
4190// ::= <decltype>
4191// ::= P <type> # pointer
4192// ::= R <type> # l-value reference
4193// ::= O <type> # r-value reference (C++11)
4194// ::= C <type> # complex pair (C99)
4195// ::= G <type> # imaginary (C99)
4196// ::= <substitution> # See Compression below
4197// extension ::= U <objc-name> <objc-type> # objc-type<identifier>
4198// extension ::= <vector-type> # <vector-type> starts with Dv
4199//
4200// <objc-name> ::= <k0 number> objcproto <k1 number> <identifier> # k0 = 9 + <number of digits in k1> + k1
4201// <objc-type> ::= <source-name> # PU<11+>objcproto 11objc_object<source-name> 11objc_object -> id<source-name>
4202template <typename Derived, typename Alloc>
4203Node *AbstractManglingParser<Derived, Alloc>::parseType() {
4204 Node *Result = nullptr;
4205
4206 switch (look()) {
4207 // ::= <qualified-type>
4208 case 'r':
4209 case 'V':
4210 case 'K': {
4211 unsigned AfterQuals = 0;
4212 if (look(Lookahead: AfterQuals) == 'r') ++AfterQuals;
4213 if (look(Lookahead: AfterQuals) == 'V') ++AfterQuals;
4214 if (look(Lookahead: AfterQuals) == 'K') ++AfterQuals;
4215
4216 if (look(Lookahead: AfterQuals) == 'F' ||
4217 (look(Lookahead: AfterQuals) == 'D' &&
4218 (look(Lookahead: AfterQuals + 1) == 'o' || look(Lookahead: AfterQuals + 1) == 'O' ||
4219 look(Lookahead: AfterQuals + 1) == 'w' || look(Lookahead: AfterQuals + 1) == 'x'))) {
4220 Result = getDerived().parseFunctionType();
4221 break;
4222 }
4223 DEMANGLE_FALLTHROUGH;
4224 }
4225 case 'U': {
4226 Result = getDerived().parseQualifiedType();
4227 break;
4228 }
4229 // <builtin-type> ::= v # void
4230 case 'v':
4231 ++First;
4232 return make<NameType>("void");
4233 // ::= w # wchar_t
4234 case 'w':
4235 ++First;
4236 return make<NameType>("wchar_t");
4237 // ::= b # bool
4238 case 'b':
4239 ++First;
4240 return make<NameType>("bool");
4241 // ::= c # char
4242 case 'c':
4243 ++First;
4244 return make<NameType>("char");
4245 // ::= a # signed char
4246 case 'a':
4247 ++First;
4248 return make<NameType>("signed char");
4249 // ::= h # unsigned char
4250 case 'h':
4251 ++First;
4252 return make<NameType>("unsigned char");
4253 // ::= s # short
4254 case 's':
4255 ++First;
4256 return make<NameType>("short");
4257 // ::= t # unsigned short
4258 case 't':
4259 ++First;
4260 return make<NameType>("unsigned short");
4261 // ::= i # int
4262 case 'i':
4263 ++First;
4264 return make<NameType>("int");
4265 // ::= j # unsigned int
4266 case 'j':
4267 ++First;
4268 return make<NameType>("unsigned int");
4269 // ::= l # long
4270 case 'l':
4271 ++First;
4272 return make<NameType>("long");
4273 // ::= m # unsigned long
4274 case 'm':
4275 ++First;
4276 return make<NameType>("unsigned long");
4277 // ::= x # long long, __int64
4278 case 'x':
4279 ++First;
4280 return make<NameType>("long long");
4281 // ::= y # unsigned long long, __int64
4282 case 'y':
4283 ++First;
4284 return make<NameType>("unsigned long long");
4285 // ::= n # __int128
4286 case 'n':
4287 ++First;
4288 return make<NameType>("__int128");
4289 // ::= o # unsigned __int128
4290 case 'o':
4291 ++First;
4292 return make<NameType>("unsigned __int128");
4293 // ::= f # float
4294 case 'f':
4295 ++First;
4296 return make<NameType>("float");
4297 // ::= d # double
4298 case 'd':
4299 ++First;
4300 return make<NameType>("double");
4301 // ::= e # long double, __float80
4302 case 'e':
4303 ++First;
4304 return make<NameType>("long double");
4305 // ::= g # __float128
4306 case 'g':
4307 ++First;
4308 return make<NameType>("__float128");
4309 // ::= z # ellipsis
4310 case 'z':
4311 ++First;
4312 return make<NameType>("...");
4313
4314 // <builtin-type> ::= u <source-name> # vendor extended type
4315 case 'u': {
4316 ++First;
4317 std::string_view Res = parseBareSourceName();
4318 if (Res.empty())
4319 return nullptr;
4320 // Typically, <builtin-type>s are not considered substitution candidates,
4321 // but the exception to that exception is vendor extended types (Itanium C++
4322 // ABI 5.9.1).
4323 if (consumeIf('I')) {
4324 Node *BaseType = parseType();
4325 if (BaseType == nullptr)
4326 return nullptr;
4327 if (!consumeIf('E'))
4328 return nullptr;
4329 Result = make<TransformedType>(Res, BaseType);
4330 } else
4331 Result = make<NameType>(Res);
4332 break;
4333 }
4334 case 'D':
4335 switch (look(Lookahead: 1)) {
4336 // ::= Dd # IEEE 754r decimal floating point (64 bits)
4337 case 'd':
4338 First += 2;
4339 return make<NameType>("decimal64");
4340 // ::= De # IEEE 754r decimal floating point (128 bits)
4341 case 'e':
4342 First += 2;
4343 return make<NameType>("decimal128");
4344 // ::= Df # IEEE 754r decimal floating point (32 bits)
4345 case 'f':
4346 First += 2;
4347 return make<NameType>("decimal32");
4348 // ::= Dh # IEEE 754r half-precision floating point (16 bits)
4349 case 'h':
4350 First += 2;
4351 return make<NameType>("half");
4352 // ::= DF16b # C++23 std::bfloat16_t
4353 // ::= DF <number> _ # ISO/IEC TS 18661 binary floating point (N bits)
4354 case 'F': {
4355 First += 2;
4356 if (consumeIf("16b"))
4357 return make<NameType>("std::bfloat16_t");
4358 Node *DimensionNumber = make<NameType>(parseNumber());
4359 if (!DimensionNumber)
4360 return nullptr;
4361 if (!consumeIf('_'))
4362 return nullptr;
4363 return make<BinaryFPType>(DimensionNumber);
4364 }
4365 // ::= [DS] DA # N1169 fixed-point [_Sat] T _Accum
4366 // ::= [DS] DR # N1169 fixed-point [_Sat] T _Frac
4367 // <fixed-point-size>
4368 // ::= s # short
4369 // ::= t # unsigned short
4370 // ::= i # plain
4371 // ::= j # unsigned
4372 // ::= l # long
4373 // ::= m # unsigned long
4374 case 'A': {
4375 char c = look(Lookahead: 2);
4376 First += 3;
4377 switch (c) {
4378 case 's':
4379 return make<NameType>("short _Accum");
4380 case 't':
4381 return make<NameType>("unsigned short _Accum");
4382 case 'i':
4383 return make<NameType>("_Accum");
4384 case 'j':
4385 return make<NameType>("unsigned _Accum");
4386 case 'l':
4387 return make<NameType>("long _Accum");
4388 case 'm':
4389 return make<NameType>("unsigned long _Accum");
4390 default:
4391 return nullptr;
4392 }
4393 }
4394 case 'R': {
4395 char c = look(Lookahead: 2);
4396 First += 3;
4397 switch (c) {
4398 case 's':
4399 return make<NameType>("short _Fract");
4400 case 't':
4401 return make<NameType>("unsigned short _Fract");
4402 case 'i':
4403 return make<NameType>("_Fract");
4404 case 'j':
4405 return make<NameType>("unsigned _Fract");
4406 case 'l':
4407 return make<NameType>("long _Fract");
4408 case 'm':
4409 return make<NameType>("unsigned long _Fract");
4410 default:
4411 return nullptr;
4412 }
4413 }
4414 case 'S': {
4415 First += 2;
4416 if (look() != 'D')
4417 return nullptr;
4418 if (look(Lookahead: 1) == 'A') {
4419 char c = look(Lookahead: 2);
4420 First += 3;
4421 switch (c) {
4422 case 's':
4423 return make<NameType>("_Sat short _Accum");
4424 case 't':
4425 return make<NameType>("_Sat unsigned short _Accum");
4426 case 'i':
4427 return make<NameType>("_Sat _Accum");
4428 case 'j':
4429 return make<NameType>("_Sat unsigned _Accum");
4430 case 'l':
4431 return make<NameType>("_Sat long _Accum");
4432 case 'm':
4433 return make<NameType>("_Sat unsigned long _Accum");
4434 default:
4435 return nullptr;
4436 }
4437 }
4438 if (look(Lookahead: 1) == 'R') {
4439 char c = look(Lookahead: 2);
4440 First += 3;
4441 switch (c) {
4442 case 's':
4443 return make<NameType>("_Sat short _Fract");
4444 case 't':
4445 return make<NameType>("_Sat unsigned short _Fract");
4446 case 'i':
4447 return make<NameType>("_Sat _Fract");
4448 case 'j':
4449 return make<NameType>("_Sat unsigned _Fract");
4450 case 'l':
4451 return make<NameType>("_Sat long _Fract");
4452 case 'm':
4453 return make<NameType>("_Sat unsigned long _Fract");
4454 default:
4455 return nullptr;
4456 }
4457 }
4458 return nullptr;
4459 }
4460 // ::= DB <number> _ # C23 signed _BitInt(N)
4461 // ::= DB <instantiation-dependent expression> _ # C23 signed _BitInt(N)
4462 // ::= DU <number> _ # C23 unsigned _BitInt(N)
4463 // ::= DU <instantiation-dependent expression> _ # C23 unsigned _BitInt(N)
4464 case 'B':
4465 case 'U': {
4466 bool Signed = look(Lookahead: 1) == 'B';
4467 First += 2;
4468 Node *Size = std::isdigit(c: look()) ? make<NameType>(parseNumber())
4469 : getDerived().parseExpr();
4470 if (!Size)
4471 return nullptr;
4472 if (!consumeIf('_'))
4473 return nullptr;
4474 // The front end expects this to be available for Substitution
4475 Result = make<BitIntType>(Size, Signed);
4476 break;
4477 }
4478 // ::= Di # char32_t
4479 case 'i':
4480 First += 2;
4481 return make<NameType>("char32_t");
4482 // ::= Ds # char16_t
4483 case 's':
4484 First += 2;
4485 return make<NameType>("char16_t");
4486 // ::= Du # char8_t (C++2a, not yet in the Itanium spec)
4487 case 'u':
4488 First += 2;
4489 return make<NameType>("char8_t");
4490 // ::= Da # auto (in dependent new-expressions)
4491 case 'a':
4492 First += 2;
4493 return make<NameType>("auto");
4494 // ::= Dc # decltype(auto)
4495 case 'c':
4496 First += 2;
4497 return make<NameType>("decltype(auto)");
4498 // ::= Dk <type-constraint> # constrained auto
4499 // ::= DK <type-constraint> # constrained decltype(auto)
4500 case 'k':
4501 case 'K': {
4502 std::string_view Kind = look(Lookahead: 1) == 'k' ? " auto" : " decltype(auto)";
4503 First += 2;
4504 Node *Constraint = getDerived().parseName();
4505 if (!Constraint)
4506 return nullptr;
4507 return make<PostfixQualifiedType>(Constraint, Kind);
4508 }
4509 // ::= Dn # std::nullptr_t (i.e., decltype(nullptr))
4510 case 'n':
4511 First += 2;
4512 return make<NameType>("std::nullptr_t");
4513
4514 // ::= <decltype>
4515 case 't':
4516 case 'T': {
4517 Result = getDerived().parseDecltype();
4518 break;
4519 }
4520 // extension ::= <vector-type> # <vector-type> starts with Dv
4521 case 'v': {
4522 Result = getDerived().parseVectorType();
4523 break;
4524 }
4525 // ::= Dp <type> # pack expansion (C++0x)
4526 case 'p': {
4527 First += 2;
4528 Node *Child = getDerived().parseType();
4529 if (!Child)
4530 return nullptr;
4531 Result = make<ParameterPackExpansion>(Child);
4532 break;
4533 }
4534 // Exception specifier on a function type.
4535 case 'o':
4536 case 'O':
4537 case 'w':
4538 // Transaction safe function type.
4539 case 'x':
4540 Result = getDerived().parseFunctionType();
4541 break;
4542 }
4543 break;
4544 // ::= <function-type>
4545 case 'F': {
4546 Result = getDerived().parseFunctionType();
4547 break;
4548 }
4549 // ::= <array-type>
4550 case 'A': {
4551 Result = getDerived().parseArrayType();
4552 break;
4553 }
4554 // ::= <pointer-to-member-type>
4555 case 'M': {
4556 Result = getDerived().parsePointerToMemberType();
4557 break;
4558 }
4559 // ::= <template-param>
4560 case 'T': {
4561 // This could be an elaborate type specifier on a <class-enum-type>.
4562 if (look(Lookahead: 1) == 's' || look(Lookahead: 1) == 'u' || look(Lookahead: 1) == 'e') {
4563 Result = getDerived().parseClassEnumType();
4564 break;
4565 }
4566
4567 Result = getDerived().parseTemplateParam();
4568 if (Result == nullptr)
4569 return nullptr;
4570
4571 // Result could be either of:
4572 // <type> ::= <template-param>
4573 // <type> ::= <template-template-param> <template-args>
4574 //
4575 // <template-template-param> ::= <template-param>
4576 // ::= <substitution>
4577 //
4578 // If this is followed by some <template-args>, and we're permitted to
4579 // parse them, take the second production.
4580
4581 if (TryToParseTemplateArgs && look() == 'I') {
4582 Subs.push_back(Elem: Result);
4583 Node *TA = getDerived().parseTemplateArgs();
4584 if (TA == nullptr)
4585 return nullptr;
4586 Result = make<NameWithTemplateArgs>(Result, TA);
4587 }
4588 break;
4589 }
4590 // ::= P <type> # pointer
4591 case 'P': {
4592 ++First;
4593 Node *Ptr = getDerived().parseType();
4594 if (Ptr == nullptr)
4595 return nullptr;
4596 Result = make<PointerType>(Ptr);
4597 break;
4598 }
4599 // ::= R <type> # l-value reference
4600 case 'R': {
4601 ++First;
4602 Node *Ref = getDerived().parseType();
4603 if (Ref == nullptr)
4604 return nullptr;
4605 Result = make<ReferenceType>(Ref, ReferenceKind::LValue);
4606 break;
4607 }
4608 // ::= O <type> # r-value reference (C++11)
4609 case 'O': {
4610 ++First;
4611 Node *Ref = getDerived().parseType();
4612 if (Ref == nullptr)
4613 return nullptr;
4614 Result = make<ReferenceType>(Ref, ReferenceKind::RValue);
4615 break;
4616 }
4617 // ::= C <type> # complex pair (C99)
4618 case 'C': {
4619 ++First;
4620 Node *P = getDerived().parseType();
4621 if (P == nullptr)
4622 return nullptr;
4623 Result = make<PostfixQualifiedType>(P, " complex");
4624 break;
4625 }
4626 // ::= G <type> # imaginary (C99)
4627 case 'G': {
4628 ++First;
4629 Node *P = getDerived().parseType();
4630 if (P == nullptr)
4631 return P;
4632 Result = make<PostfixQualifiedType>(P, " imaginary");
4633 break;
4634 }
4635 // ::= <substitution> # See Compression below
4636 case 'S': {
4637 if (look(Lookahead: 1) != 't') {
4638 bool IsSubst = false;
4639 Result = getDerived().parseUnscopedName(nullptr, &IsSubst);
4640 if (!Result)
4641 return nullptr;
4642
4643 // Sub could be either of:
4644 // <type> ::= <substitution>
4645 // <type> ::= <template-template-param> <template-args>
4646 //
4647 // <template-template-param> ::= <template-param>
4648 // ::= <substitution>
4649 //
4650 // If this is followed by some <template-args>, and we're permitted to
4651 // parse them, take the second production.
4652
4653 if (look() == 'I' && (!IsSubst || TryToParseTemplateArgs)) {
4654 if (!IsSubst)
4655 Subs.push_back(Elem: Result);
4656 Node *TA = getDerived().parseTemplateArgs();
4657 if (TA == nullptr)
4658 return nullptr;
4659 Result = make<NameWithTemplateArgs>(Result, TA);
4660 } else if (IsSubst) {
4661 // If all we parsed was a substitution, don't re-insert into the
4662 // substitution table.
4663 return Result;
4664 }
4665 break;
4666 }
4667 DEMANGLE_FALLTHROUGH;
4668 }
4669 // ::= <class-enum-type>
4670 default: {
4671 Result = getDerived().parseClassEnumType();
4672 break;
4673 }
4674 }
4675
4676 // If we parsed a type, insert it into the substitution table. Note that all
4677 // <builtin-type>s and <substitution>s have already bailed out, because they
4678 // don't get substitutions.
4679 if (Result != nullptr)
4680 Subs.push_back(Elem: Result);
4681 return Result;
4682}
4683
4684template <typename Derived, typename Alloc>
4685Node *
4686AbstractManglingParser<Derived, Alloc>::parsePrefixExpr(std::string_view Kind,
4687 Node::Prec Prec) {
4688 Node *E = getDerived().parseExpr();
4689 if (E == nullptr)
4690 return nullptr;
4691 return make<PrefixExpr>(Kind, E, Prec);
4692}
4693
4694template <typename Derived, typename Alloc>
4695Node *
4696AbstractManglingParser<Derived, Alloc>::parseBinaryExpr(std::string_view Kind,
4697 Node::Prec Prec) {
4698 Node *LHS = getDerived().parseExpr();
4699 if (LHS == nullptr)
4700 return nullptr;
4701 Node *RHS = getDerived().parseExpr();
4702 if (RHS == nullptr)
4703 return nullptr;
4704 return make<BinaryExpr>(LHS, Kind, RHS, Prec);
4705}
4706
4707template <typename Derived, typename Alloc>
4708Node *AbstractManglingParser<Derived, Alloc>::parseIntegerLiteral(
4709 std::string_view Lit) {
4710 std::string_view Tmp = parseNumber(AllowNegative: true);
4711 if (!Tmp.empty() && consumeIf('E'))
4712 return make<IntegerLiteral>(Lit, Tmp);
4713 return nullptr;
4714}
4715
4716// <CV-Qualifiers> ::= [r] [V] [K]
4717template <typename Alloc, typename Derived>
4718Qualifiers AbstractManglingParser<Alloc, Derived>::parseCVQualifiers() {
4719 Qualifiers CVR = QualNone;
4720 if (consumeIf('r'))
4721 CVR |= QualRestrict;
4722 if (consumeIf('V'))
4723 CVR |= QualVolatile;
4724 if (consumeIf('K'))
4725 CVR |= QualConst;
4726 return CVR;
4727}
4728
4729// <function-param> ::= fp <top-level CV-Qualifiers> _ # L == 0, first parameter
4730// ::= fp <top-level CV-Qualifiers> <parameter-2 non-negative number> _ # L == 0, second and later parameters
4731// ::= fL <L-1 non-negative number> p <top-level CV-Qualifiers> _ # L > 0, first parameter
4732// ::= fL <L-1 non-negative number> p <top-level CV-Qualifiers> <parameter-2 non-negative number> _ # L > 0, second and later parameters
4733// ::= fpT # 'this' expression (not part of standard?)
4734template <typename Derived, typename Alloc>
4735Node *AbstractManglingParser<Derived, Alloc>::parseFunctionParam() {
4736 if (consumeIf("fpT"))
4737 return make<NameType>("this");
4738 if (consumeIf("fp")) {
4739 parseCVQualifiers();
4740 std::string_view Num = parseNumber();
4741 if (!consumeIf('_'))
4742 return nullptr;
4743 return make<FunctionParam>(Num);
4744 }
4745 if (consumeIf("fL")) {
4746 if (parseNumber().empty())
4747 return nullptr;
4748 if (!consumeIf('p'))
4749 return nullptr;
4750 parseCVQualifiers();
4751 std::string_view Num = parseNumber();
4752 if (!consumeIf('_'))
4753 return nullptr;
4754 return make<FunctionParam>(Num);
4755 }
4756 return nullptr;
4757}
4758
4759// cv <type> <expression> # conversion with one argument
4760// cv <type> _ <expression>* E # conversion with a different number of arguments
4761template <typename Derived, typename Alloc>
4762Node *AbstractManglingParser<Derived, Alloc>::parseConversionExpr() {
4763 if (!consumeIf("cv"))
4764 return nullptr;
4765 Node *Ty;
4766 {
4767 ScopedOverride<bool> SaveTemp(TryToParseTemplateArgs, false);
4768 Ty = getDerived().parseType();
4769 }
4770
4771 if (Ty == nullptr)
4772 return nullptr;
4773
4774 if (consumeIf('_')) {
4775 size_t ExprsBegin = Names.size();
4776 while (!consumeIf('E')) {
4777 Node *E = getDerived().parseExpr();
4778 if (E == nullptr)
4779 return E;
4780 Names.push_back(Elem: E);
4781 }
4782 NodeArray Exprs = popTrailingNodeArray(FromPosition: ExprsBegin);
4783 return make<ConversionExpr>(Ty, Exprs);
4784 }
4785
4786 Node *E[1] = {getDerived().parseExpr()};
4787 if (E[0] == nullptr)
4788 return nullptr;
4789 return make<ConversionExpr>(Ty, makeNodeArray(E, E + 1));
4790}
4791
4792// <expr-primary> ::= L <type> <value number> E # integer literal
4793// ::= L <type> <value float> E # floating literal
4794// ::= L <string type> E # string literal
4795// ::= L <nullptr type> E # nullptr literal (i.e., "LDnE")
4796// ::= L <lambda type> E # lambda expression
4797// FIXME: ::= L <type> <real-part float> _ <imag-part float> E # complex floating point literal (C 2000)
4798// ::= L <mangled-name> E # external name
4799template <typename Derived, typename Alloc>
4800Node *AbstractManglingParser<Derived, Alloc>::parseExprPrimary() {
4801 if (!consumeIf('L'))
4802 return nullptr;
4803 switch (look()) {
4804 case 'w':
4805 ++First;
4806 return getDerived().parseIntegerLiteral("wchar_t");
4807 case 'b':
4808 if (consumeIf("b0E"))
4809 return make<BoolExpr>(0);
4810 if (consumeIf("b1E"))
4811 return make<BoolExpr>(1);
4812 return nullptr;
4813 case 'c':
4814 ++First;
4815 return getDerived().parseIntegerLiteral("char");
4816 case 'a':
4817 ++First;
4818 return getDerived().parseIntegerLiteral("signed char");
4819 case 'h':
4820 ++First;
4821 return getDerived().parseIntegerLiteral("unsigned char");
4822 case 's':
4823 ++First;
4824 return getDerived().parseIntegerLiteral("short");
4825 case 't':
4826 ++First;
4827 return getDerived().parseIntegerLiteral("unsigned short");
4828 case 'i':
4829 ++First;
4830 return getDerived().parseIntegerLiteral("");
4831 case 'j':
4832 ++First;
4833 return getDerived().parseIntegerLiteral("u");
4834 case 'l':
4835 ++First;
4836 return getDerived().parseIntegerLiteral("l");
4837 case 'm':
4838 ++First;
4839 return getDerived().parseIntegerLiteral("ul");
4840 case 'x':
4841 ++First;
4842 return getDerived().parseIntegerLiteral("ll");
4843 case 'y':
4844 ++First;
4845 return getDerived().parseIntegerLiteral("ull");
4846 case 'n':
4847 ++First;
4848 return getDerived().parseIntegerLiteral("__int128");
4849 case 'o':
4850 ++First;
4851 return getDerived().parseIntegerLiteral("unsigned __int128");
4852 case 'f':
4853 ++First;
4854 return getDerived().template parseFloatingLiteral<float>();
4855 case 'd':
4856 ++First;
4857 return getDerived().template parseFloatingLiteral<double>();
4858 case 'e':
4859 ++First;
4860#if defined(__powerpc__) || defined(__s390__)
4861 // Handle cases where long doubles encoded with e have the same size
4862 // and representation as doubles.
4863 return getDerived().template parseFloatingLiteral<double>();
4864#else
4865 return getDerived().template parseFloatingLiteral<long double>();
4866#endif
4867 case '_':
4868 if (consumeIf("_Z")) {
4869 Node *R = getDerived().parseEncoding();
4870 if (R != nullptr && consumeIf('E'))
4871 return R;
4872 }
4873 return nullptr;
4874 case 'A': {
4875 Node *T = getDerived().parseType();
4876 if (T == nullptr)
4877 return nullptr;
4878 // FIXME: We need to include the string contents in the mangling.
4879 if (consumeIf('E'))
4880 return make<StringLiteral>(T);
4881 return nullptr;
4882 }
4883 case 'D':
4884 if (consumeIf("Dn") && (consumeIf('0'), consumeIf('E')))
4885 return make<NameType>("nullptr");
4886 return nullptr;
4887 case 'T':
4888 // Invalid mangled name per
4889 // http://sourcerytools.com/pipermail/cxx-abi-dev/2011-August/002422.html
4890 return nullptr;
4891 case 'U': {
4892 // FIXME: Should we support LUb... for block literals?
4893 if (look(Lookahead: 1) != 'l')
4894 return nullptr;
4895 Node *T = parseUnnamedTypeName(State: nullptr);
4896 if (!T || !consumeIf('E'))
4897 return nullptr;
4898 return make<LambdaExpr>(T);
4899 }
4900 default: {
4901 // might be named type
4902 Node *T = getDerived().parseType();
4903 if (T == nullptr)
4904 return nullptr;
4905 std::string_view N = parseNumber(/*AllowNegative=*/AllowNegative: true);
4906 if (N.empty())
4907 return nullptr;
4908 if (!consumeIf('E'))
4909 return nullptr;
4910 return make<EnumLiteral>(T, N);
4911 }
4912 }
4913}
4914
4915// <braced-expression> ::= <expression>
4916// ::= di <field source-name> <braced-expression> # .name = expr
4917// ::= dx <index expression> <braced-expression> # [expr] = expr
4918// ::= dX <range begin expression> <range end expression> <braced-expression>
4919template <typename Derived, typename Alloc>
4920Node *AbstractManglingParser<Derived, Alloc>::parseBracedExpr() {
4921 if (look() == 'd') {
4922 switch (look(Lookahead: 1)) {
4923 case 'i': {
4924 First += 2;
4925 Node *Field = getDerived().parseSourceName(/*NameState=*/nullptr);
4926 if (Field == nullptr)
4927 return nullptr;
4928 Node *Init = getDerived().parseBracedExpr();
4929 if (Init == nullptr)
4930 return nullptr;
4931 return make<BracedExpr>(Field, Init, /*isArray=*/false);
4932 }
4933 case 'x': {
4934 First += 2;
4935 Node *Index = getDerived().parseExpr();
4936 if (Index == nullptr)
4937 return nullptr;
4938 Node *Init = getDerived().parseBracedExpr();
4939 if (Init == nullptr)
4940 return nullptr;
4941 return make<BracedExpr>(Index, Init, /*isArray=*/true);
4942 }
4943 case 'X': {
4944 First += 2;
4945 Node *RangeBegin = getDerived().parseExpr();
4946 if (RangeBegin == nullptr)
4947 return nullptr;
4948 Node *RangeEnd = getDerived().parseExpr();
4949 if (RangeEnd == nullptr)
4950 return nullptr;
4951 Node *Init = getDerived().parseBracedExpr();
4952 if (Init == nullptr)
4953 return nullptr;
4954 return make<BracedRangeExpr>(RangeBegin, RangeEnd, Init);
4955 }
4956 }
4957 }
4958 return getDerived().parseExpr();
4959}
4960
4961// (not yet in the spec)
4962// <fold-expr> ::= fL <binary-operator-name> <expression> <expression>
4963// ::= fR <binary-operator-name> <expression> <expression>
4964// ::= fl <binary-operator-name> <expression>
4965// ::= fr <binary-operator-name> <expression>
4966template <typename Derived, typename Alloc>
4967Node *AbstractManglingParser<Derived, Alloc>::parseFoldExpr() {
4968 if (!consumeIf('f'))
4969 return nullptr;
4970
4971 bool IsLeftFold = false, HasInitializer = false;
4972 switch (look()) {
4973 default:
4974 return nullptr;
4975 case 'L':
4976 IsLeftFold = true;
4977 HasInitializer = true;
4978 break;
4979 case 'R':
4980 HasInitializer = true;
4981 break;
4982 case 'l':
4983 IsLeftFold = true;
4984 break;
4985 case 'r':
4986 break;
4987 }
4988 ++First;
4989
4990 const auto *Op = parseOperatorEncoding();
4991 if (!Op)
4992 return nullptr;
4993 if (!(Op->getKind() == OperatorInfo::Binary
4994 || (Op->getKind() == OperatorInfo::Member
4995 && Op->getName().back() == '*')))
4996 return nullptr;
4997
4998 Node *Pack = getDerived().parseExpr();
4999 if (Pack == nullptr)
5000 return nullptr;
5001
5002 Node *Init = nullptr;
5003 if (HasInitializer) {
5004 Init = getDerived().parseExpr();
5005 if (Init == nullptr)
5006 return nullptr;
5007 }
5008
5009 if (IsLeftFold && Init)
5010 std::swap(x&: Pack, y&: Init);
5011
5012 return make<FoldExpr>(IsLeftFold, Op->getSymbol(), Pack, Init);
5013}
5014
5015// <expression> ::= mc <parameter type> <expr> [<offset number>] E
5016//
5017// Not yet in the spec: https://github.com/itanium-cxx-abi/cxx-abi/issues/47
5018template <typename Derived, typename Alloc>
5019Node *
5020AbstractManglingParser<Derived, Alloc>::parsePointerToMemberConversionExpr(
5021 Node::Prec Prec) {
5022 Node *Ty = getDerived().parseType();
5023 if (!Ty)
5024 return nullptr;
5025 Node *Expr = getDerived().parseExpr();
5026 if (!Expr)
5027 return nullptr;
5028 std::string_view Offset = getDerived().parseNumber(true);
5029 if (!consumeIf('E'))
5030 return nullptr;
5031 return make<PointerToMemberConversionExpr>(Ty, Expr, Offset, Prec);
5032}
5033
5034// <expression> ::= so <referent type> <expr> [<offset number>] <union-selector>* [p] E
5035// <union-selector> ::= _ [<number>]
5036//
5037// Not yet in the spec: https://github.com/itanium-cxx-abi/cxx-abi/issues/47
5038template <typename Derived, typename Alloc>
5039Node *AbstractManglingParser<Derived, Alloc>::parseSubobjectExpr() {
5040 Node *Ty = getDerived().parseType();
5041 if (!Ty)
5042 return nullptr;
5043 Node *Expr = getDerived().parseExpr();
5044 if (!Expr)
5045 return nullptr;
5046 std::string_view Offset = getDerived().parseNumber(true);
5047 size_t SelectorsBegin = Names.size();
5048 while (consumeIf('_')) {
5049 Node *Selector = make<NameType>(parseNumber());
5050 if (!Selector)
5051 return nullptr;
5052 Names.push_back(Elem: Selector);
5053 }
5054 bool OnePastTheEnd = consumeIf('p');
5055 if (!consumeIf('E'))
5056 return nullptr;
5057 return make<SubobjectExpr>(
5058 Ty, Expr, Offset, popTrailingNodeArray(FromPosition: SelectorsBegin), OnePastTheEnd);
5059}
5060
5061template <typename Derived, typename Alloc>
5062Node *AbstractManglingParser<Derived, Alloc>::parseConstraintExpr() {
5063 // Within this expression, all enclosing template parameter lists are in
5064 // scope.
5065 ScopedOverride<bool> SaveIncompleteTemplateParameterTracking(
5066 HasIncompleteTemplateParameterTracking, true);
5067 return getDerived().parseExpr();
5068}
5069
5070template <typename Derived, typename Alloc>
5071Node *AbstractManglingParser<Derived, Alloc>::parseRequiresExpr() {
5072 NodeArray Params;
5073 if (consumeIf("rQ")) {
5074 // <expression> ::= rQ <bare-function-type> _ <requirement>+ E
5075 size_t ParamsBegin = Names.size();
5076 while (!consumeIf('_')) {
5077 Node *Type = getDerived().parseType();
5078 if (Type == nullptr)
5079 return nullptr;
5080 Names.push_back(Elem: Type);
5081 }
5082 Params = popTrailingNodeArray(FromPosition: ParamsBegin);
5083 } else if (!consumeIf("rq")) {
5084 // <expression> ::= rq <requirement>+ E
5085 return nullptr;
5086 }
5087
5088 size_t ReqsBegin = Names.size();
5089 do {
5090 Node *Constraint = nullptr;
5091 if (consumeIf('X')) {
5092 // <requirement> ::= X <expression> [N] [R <type-constraint>]
5093 Node *Expr = getDerived().parseExpr();
5094 if (Expr == nullptr)
5095 return nullptr;
5096 bool Noexcept = consumeIf('N');
5097 Node *TypeReq = nullptr;
5098 if (consumeIf('R')) {
5099 TypeReq = getDerived().parseName();
5100 if (TypeReq == nullptr)
5101 return nullptr;
5102 }
5103 Constraint = make<ExprRequirement>(Expr, Noexcept, TypeReq);
5104 } else if (consumeIf('T')) {
5105 // <requirement> ::= T <type>
5106 Node *Type = getDerived().parseType();
5107 if (Type == nullptr)
5108 return nullptr;
5109 Constraint = make<TypeRequirement>(Type);
5110 } else if (consumeIf('Q')) {
5111 // <requirement> ::= Q <constraint-expression>
5112 //
5113 // FIXME: We use <expression> instead of <constraint-expression>. Either
5114 // the requires expression is already inside a constraint expression, in
5115 // which case it makes no difference, or we're in a requires-expression
5116 // that might be partially-substituted, where the language behavior is
5117 // not yet settled and clang mangles after substitution.
5118 Node *NestedReq = getDerived().parseExpr();
5119 if (NestedReq == nullptr)
5120 return nullptr;
5121 Constraint = make<NestedRequirement>(NestedReq);
5122 }
5123 if (Constraint == nullptr)
5124 return nullptr;
5125 Names.push_back(Elem: Constraint);
5126 } while (!consumeIf('E'));
5127
5128 return make<RequiresExpr>(Params, popTrailingNodeArray(FromPosition: ReqsBegin));
5129}
5130
5131// <expression> ::= <unary operator-name> <expression>
5132// ::= <binary operator-name> <expression> <expression>
5133// ::= <ternary operator-name> <expression> <expression> <expression>
5134// ::= cl <expression>+ E # call
5135// ::= cp <base-unresolved-name> <expression>* E # (name) (expr-list), call that would use argument-dependent lookup but for the parentheses
5136// ::= cv <type> <expression> # conversion with one argument
5137// ::= cv <type> _ <expression>* E # conversion with a different number of arguments
5138// ::= [gs] nw <expression>* _ <type> E # new (expr-list) type
5139// ::= [gs] nw <expression>* _ <type> <initializer> # new (expr-list) type (init)
5140// ::= [gs] na <expression>* _ <type> E # new[] (expr-list) type
5141// ::= [gs] na <expression>* _ <type> <initializer> # new[] (expr-list) type (init)
5142// ::= [gs] dl <expression> # delete expression
5143// ::= [gs] da <expression> # delete[] expression
5144// ::= pp_ <expression> # prefix ++
5145// ::= mm_ <expression> # prefix --
5146// ::= ti <type> # typeid (type)
5147// ::= te <expression> # typeid (expression)
5148// ::= dc <type> <expression> # dynamic_cast<type> (expression)
5149// ::= sc <type> <expression> # static_cast<type> (expression)
5150// ::= cc <type> <expression> # const_cast<type> (expression)
5151// ::= rc <type> <expression> # reinterpret_cast<type> (expression)
5152// ::= st <type> # sizeof (a type)
5153// ::= sz <expression> # sizeof (an expression)
5154// ::= at <type> # alignof (a type)
5155// ::= az <expression> # alignof (an expression)
5156// ::= nx <expression> # noexcept (expression)
5157// ::= <template-param>
5158// ::= <function-param>
5159// ::= dt <expression> <unresolved-name> # expr.name
5160// ::= pt <expression> <unresolved-name> # expr->name
5161// ::= ds <expression> <expression> # expr.*expr
5162// ::= sZ <template-param> # size of a parameter pack
5163// ::= sZ <function-param> # size of a function parameter pack
5164// ::= sP <template-arg>* E # sizeof...(T), size of a captured template parameter pack from an alias template
5165// ::= sp <expression> # pack expansion
5166// ::= tw <expression> # throw expression
5167// ::= tr # throw with no operand (rethrow)
5168// ::= <unresolved-name> # f(p), N::f(p), ::f(p),
5169// # freestanding dependent name (e.g., T::x),
5170// # objectless nonstatic member reference
5171// ::= fL <binary-operator-name> <expression> <expression>
5172// ::= fR <binary-operator-name> <expression> <expression>
5173// ::= fl <binary-operator-name> <expression>
5174// ::= fr <binary-operator-name> <expression>
5175// ::= <expr-primary>
5176template <typename Derived, typename Alloc>
5177Node *AbstractManglingParser<Derived, Alloc>::parseExpr() {
5178 bool Global = consumeIf("gs");
5179
5180 const auto *Op = parseOperatorEncoding();
5181 if (Op) {
5182 auto Sym = Op->getSymbol();
5183 switch (Op->getKind()) {
5184 case OperatorInfo::Binary:
5185 // Binary operator: lhs @ rhs
5186 return getDerived().parseBinaryExpr(Sym, Op->getPrecedence());
5187 case OperatorInfo::Prefix:
5188 // Prefix unary operator: @ expr
5189 return getDerived().parsePrefixExpr(Sym, Op->getPrecedence());
5190 case OperatorInfo::Postfix: {
5191 // Postfix unary operator: expr @
5192 if (consumeIf('_'))
5193 return getDerived().parsePrefixExpr(Sym, Op->getPrecedence());
5194 Node *Ex = getDerived().parseExpr();
5195 if (Ex == nullptr)
5196 return nullptr;
5197 return make<PostfixExpr>(Ex, Sym, Op->getPrecedence());
5198 }
5199 case OperatorInfo::Array: {
5200 // Array Index: lhs [ rhs ]
5201 Node *Base = getDerived().parseExpr();
5202 if (Base == nullptr)
5203 return nullptr;
5204 Node *Index = getDerived().parseExpr();
5205 if (Index == nullptr)
5206 return nullptr;
5207 return make<ArraySubscriptExpr>(Base, Index, Op->getPrecedence());
5208 }
5209 case OperatorInfo::Member: {
5210 // Member access lhs @ rhs
5211 Node *LHS = getDerived().parseExpr();
5212 if (LHS == nullptr)
5213 return nullptr;
5214 Node *RHS = getDerived().parseExpr();
5215 if (RHS == nullptr)
5216 return nullptr;
5217 return make<MemberExpr>(LHS, Sym, RHS, Op->getPrecedence());
5218 }
5219 case OperatorInfo::New: {
5220 // New
5221 // # new (expr-list) type [(init)]
5222 // [gs] nw <expression>* _ <type> [pi <expression>*] E
5223 // # new[] (expr-list) type [(init)]
5224 // [gs] na <expression>* _ <type> [pi <expression>*] E
5225 size_t Exprs = Names.size();
5226 while (!consumeIf('_')) {
5227 Node *Ex = getDerived().parseExpr();
5228 if (Ex == nullptr)
5229 return nullptr;
5230 Names.push_back(Elem: Ex);
5231 }
5232 NodeArray ExprList = popTrailingNodeArray(FromPosition: Exprs);
5233 Node *Ty = getDerived().parseType();
5234 if (Ty == nullptr)
5235 return nullptr;
5236 bool HaveInits = consumeIf("pi");
5237 size_t InitsBegin = Names.size();
5238 while (!consumeIf('E')) {
5239 if (!HaveInits)
5240 return nullptr;
5241 Node *Init = getDerived().parseExpr();
5242 if (Init == nullptr)
5243 return Init;
5244 Names.push_back(Elem: Init);
5245 }
5246 NodeArray Inits = popTrailingNodeArray(FromPosition: InitsBegin);
5247 return make<NewExpr>(ExprList, Ty, Inits, Global,
5248 /*IsArray=*/Op->getFlag(), Op->getPrecedence());
5249 }
5250 case OperatorInfo::Del: {
5251 // Delete
5252 Node *Ex = getDerived().parseExpr();
5253 if (Ex == nullptr)
5254 return nullptr;
5255 return make<DeleteExpr>(Ex, Global, /*IsArray=*/Op->getFlag(),
5256 Op->getPrecedence());
5257 }
5258 case OperatorInfo::Call: {
5259 // Function Call
5260 Node *Callee = getDerived().parseExpr();
5261 if (Callee == nullptr)
5262 return nullptr;
5263 size_t ExprsBegin = Names.size();
5264 while (!consumeIf('E')) {
5265 Node *E = getDerived().parseExpr();
5266 if (E == nullptr)
5267 return nullptr;
5268 Names.push_back(Elem: E);
5269 }
5270 return make<CallExpr>(Callee, popTrailingNodeArray(FromPosition: ExprsBegin),
5271 /*IsParen=*/Op->getFlag(), Op->getPrecedence());
5272 }
5273 case OperatorInfo::CCast: {
5274 // C Cast: (type)expr
5275 Node *Ty;
5276 {
5277 ScopedOverride<bool> SaveTemp(TryToParseTemplateArgs, false);
5278 Ty = getDerived().parseType();
5279 }
5280 if (Ty == nullptr)
5281 return nullptr;
5282
5283 size_t ExprsBegin = Names.size();
5284 bool IsMany = consumeIf('_');
5285 while (!consumeIf('E')) {
5286 Node *E = getDerived().parseExpr();
5287 if (E == nullptr)
5288 return E;
5289 Names.push_back(Elem: E);
5290 if (!IsMany)
5291 break;
5292 }
5293 NodeArray Exprs = popTrailingNodeArray(FromPosition: ExprsBegin);
5294 if (!IsMany && Exprs.size() != 1)
5295 return nullptr;
5296 return make<ConversionExpr>(Ty, Exprs, Op->getPrecedence());
5297 }
5298 case OperatorInfo::Conditional: {
5299 // Conditional operator: expr ? expr : expr
5300 Node *Cond = getDerived().parseExpr();
5301 if (Cond == nullptr)
5302 return nullptr;
5303 Node *LHS = getDerived().parseExpr();
5304 if (LHS == nullptr)
5305 return nullptr;
5306 Node *RHS = getDerived().parseExpr();
5307 if (RHS == nullptr)
5308 return nullptr;
5309 return make<ConditionalExpr>(Cond, LHS, RHS, Op->getPrecedence());
5310 }
5311 case OperatorInfo::NamedCast: {
5312 // Named cast operation, @<type>(expr)
5313 Node *Ty = getDerived().parseType();
5314 if (Ty == nullptr)
5315 return nullptr;
5316 Node *Ex = getDerived().parseExpr();
5317 if (Ex == nullptr)
5318 return nullptr;
5319 return make<CastExpr>(Sym, Ty, Ex, Op->getPrecedence());
5320 }
5321 case OperatorInfo::OfIdOp: {
5322 // [sizeof/alignof/typeid] ( <type>|<expr> )
5323 Node *Arg =
5324 Op->getFlag() ? getDerived().parseType() : getDerived().parseExpr();
5325 if (!Arg)
5326 return nullptr;
5327 return make<EnclosingExpr>(Sym, Arg, Op->getPrecedence());
5328 }
5329 case OperatorInfo::NameOnly: {
5330 // Not valid as an expression operand.
5331 return nullptr;
5332 }
5333 }
5334 DEMANGLE_UNREACHABLE;
5335 }
5336
5337 if (numLeft() < 2)
5338 return nullptr;
5339
5340 if (look() == 'L')
5341 return getDerived().parseExprPrimary();
5342 if (look() == 'T')
5343 return getDerived().parseTemplateParam();
5344 if (look() == 'f') {
5345 // Disambiguate a fold expression from a <function-param>.
5346 if (look(Lookahead: 1) == 'p' || (look(Lookahead: 1) == 'L' && std::isdigit(c: look(Lookahead: 2))))
5347 return getDerived().parseFunctionParam();
5348 return getDerived().parseFoldExpr();
5349 }
5350 if (consumeIf("il")) {
5351 size_t InitsBegin = Names.size();
5352 while (!consumeIf('E')) {
5353 Node *E = getDerived().parseBracedExpr();
5354 if (E == nullptr)
5355 return nullptr;
5356 Names.push_back(Elem: E);
5357 }
5358 return make<InitListExpr>(nullptr, popTrailingNodeArray(FromPosition: InitsBegin));
5359 }
5360 if (consumeIf("mc"))
5361 return parsePointerToMemberConversionExpr(Prec: Node::Prec::Unary);
5362 if (consumeIf("nx")) {
5363 Node *Ex = getDerived().parseExpr();
5364 if (Ex == nullptr)
5365 return Ex;
5366 return make<EnclosingExpr>("noexcept ", Ex, Node::Prec::Unary);
5367 }
5368 if (look() == 'r' && (look(Lookahead: 1) == 'q' || look(Lookahead: 1) == 'Q'))
5369 return parseRequiresExpr();
5370 if (consumeIf("so"))
5371 return parseSubobjectExpr();
5372 if (consumeIf("sp")) {
5373 Node *Child = getDerived().parseExpr();
5374 if (Child == nullptr)
5375 return nullptr;
5376 return make<ParameterPackExpansion>(Child);
5377 }
5378 if (consumeIf("sZ")) {
5379 if (look() == 'T') {
5380 Node *R = getDerived().parseTemplateParam();
5381 if (R == nullptr)
5382 return nullptr;
5383 return make<SizeofParamPackExpr>(R);
5384 }
5385 Node *FP = getDerived().parseFunctionParam();
5386 if (FP == nullptr)
5387 return nullptr;
5388 return make<EnclosingExpr>("sizeof... ", FP);
5389 }
5390 if (consumeIf("sP")) {
5391 size_t ArgsBegin = Names.size();
5392 while (!consumeIf('E')) {
5393 Node *Arg = getDerived().parseTemplateArg();
5394 if (Arg == nullptr)
5395 return nullptr;
5396 Names.push_back(Elem: Arg);
5397 }
5398 auto *Pack = make<NodeArrayNode>(popTrailingNodeArray(FromPosition: ArgsBegin));
5399 if (!Pack)
5400 return nullptr;
5401 return make<EnclosingExpr>("sizeof... ", Pack);
5402 }
5403 if (consumeIf("tl")) {
5404 Node *Ty = getDerived().parseType();
5405 if (Ty == nullptr)
5406 return nullptr;
5407 size_t InitsBegin = Names.size();
5408 while (!consumeIf('E')) {
5409 Node *E = getDerived().parseBracedExpr();
5410 if (E == nullptr)
5411 return nullptr;
5412 Names.push_back(Elem: E);
5413 }
5414 return make<InitListExpr>(Ty, popTrailingNodeArray(FromPosition: InitsBegin));
5415 }
5416 if (consumeIf("tr"))
5417 return make<NameType>("throw");
5418 if (consumeIf("tw")) {
5419 Node *Ex = getDerived().parseExpr();
5420 if (Ex == nullptr)
5421 return nullptr;
5422 return make<ThrowExpr>(Ex);
5423 }
5424 if (consumeIf('u')) {
5425 Node *Name = getDerived().parseSourceName(/*NameState=*/nullptr);
5426 if (!Name)
5427 return nullptr;
5428 // Special case legacy __uuidof mangling. The 't' and 'z' appear where the
5429 // standard encoding expects a <template-arg>, and would be otherwise be
5430 // interpreted as <type> node 'short' or 'ellipsis'. However, neither
5431 // __uuidof(short) nor __uuidof(...) can actually appear, so there is no
5432 // actual conflict here.
5433 bool IsUUID = false;
5434 Node *UUID = nullptr;
5435 if (Name->getBaseName() == "__uuidof") {
5436 if (consumeIf('t')) {
5437 UUID = getDerived().parseType();
5438 IsUUID = true;
5439 } else if (consumeIf('z')) {
5440 UUID = getDerived().parseExpr();
5441 IsUUID = true;
5442 }
5443 }
5444 size_t ExprsBegin = Names.size();
5445 if (IsUUID) {
5446 if (UUID == nullptr)
5447 return nullptr;
5448 Names.push_back(Elem: UUID);
5449 } else {
5450 while (!consumeIf('E')) {
5451 Node *E = getDerived().parseTemplateArg();
5452 if (E == nullptr)
5453 return E;
5454 Names.push_back(Elem: E);
5455 }
5456 }
5457 return make<CallExpr>(Name, popTrailingNodeArray(FromPosition: ExprsBegin),
5458 /*IsParen=*/false, Node::Prec::Postfix);
5459 }
5460
5461 // Only unresolved names remain.
5462 return getDerived().parseUnresolvedName(Global);
5463}
5464
5465// <call-offset> ::= h <nv-offset> _
5466// ::= v <v-offset> _
5467//
5468// <nv-offset> ::= <offset number>
5469// # non-virtual base override
5470//
5471// <v-offset> ::= <offset number> _ <virtual offset number>
5472// # virtual base override, with vcall offset
5473template <typename Alloc, typename Derived>
5474bool AbstractManglingParser<Alloc, Derived>::parseCallOffset() {
5475 // Just scan through the call offset, we never add this information into the
5476 // output.
5477 if (consumeIf('h'))
5478 return parseNumber(AllowNegative: true).empty() || !consumeIf('_');
5479 if (consumeIf('v'))
5480 return parseNumber(AllowNegative: true).empty() || !consumeIf('_') ||
5481 parseNumber(AllowNegative: true).empty() || !consumeIf('_');
5482 return true;
5483}
5484
5485// <special-name> ::= TV <type> # virtual table
5486// ::= TT <type> # VTT structure (construction vtable index)
5487// ::= TI <type> # typeinfo structure
5488// ::= TS <type> # typeinfo name (null-terminated byte string)
5489// ::= Tc <call-offset> <call-offset> <base encoding>
5490// # base is the nominal target function of thunk
5491// # first call-offset is 'this' adjustment
5492// # second call-offset is result adjustment
5493// ::= T <call-offset> <base encoding>
5494// # base is the nominal target function of thunk
5495// # Guard variable for one-time initialization
5496// ::= GV <object name>
5497// # No <type>
5498// ::= TW <object name> # Thread-local wrapper
5499// ::= TH <object name> # Thread-local initialization
5500// ::= GR <object name> _ # First temporary
5501// ::= GR <object name> <seq-id> _ # Subsequent temporaries
5502// # construction vtable for second-in-first
5503// extension ::= TC <first type> <number> _ <second type>
5504// extension ::= GR <object name> # reference temporary for object
5505// extension ::= GI <module name> # module global initializer
5506template <typename Derived, typename Alloc>
5507Node *AbstractManglingParser<Derived, Alloc>::parseSpecialName() {
5508 switch (look()) {
5509 case 'T':
5510 switch (look(Lookahead: 1)) {
5511 // TA <template-arg> # template parameter object
5512 //
5513 // Not yet in the spec: https://github.com/itanium-cxx-abi/cxx-abi/issues/63
5514 case 'A': {
5515 First += 2;
5516 Node *Arg = getDerived().parseTemplateArg();
5517 if (Arg == nullptr)
5518 return nullptr;
5519 return make<SpecialName>("template parameter object for ", Arg);
5520 }
5521 // TV <type> # virtual table
5522 case 'V': {
5523 First += 2;
5524 Node *Ty = getDerived().parseType();
5525 if (Ty == nullptr)
5526 return nullptr;
5527 return make<SpecialName>("vtable for ", Ty);
5528 }
5529 // TT <type> # VTT structure (construction vtable index)
5530 case 'T': {
5531 First += 2;
5532 Node *Ty = getDerived().parseType();
5533 if (Ty == nullptr)
5534 return nullptr;
5535 return make<SpecialName>("VTT for ", Ty);
5536 }
5537 // TI <type> # typeinfo structure
5538 case 'I': {
5539 First += 2;
5540 Node *Ty = getDerived().parseType();
5541 if (Ty == nullptr)
5542 return nullptr;
5543 return make<SpecialName>("typeinfo for ", Ty);
5544 }
5545 // TS <type> # typeinfo name (null-terminated byte string)
5546 case 'S': {
5547 First += 2;
5548 Node *Ty = getDerived().parseType();
5549 if (Ty == nullptr)
5550 return nullptr;
5551 return make<SpecialName>("typeinfo name for ", Ty);
5552 }
5553 // Tc <call-offset> <call-offset> <base encoding>
5554 case 'c': {
5555 First += 2;
5556 if (parseCallOffset() || parseCallOffset())
5557 return nullptr;
5558 Node *Encoding = getDerived().parseEncoding();
5559 if (Encoding == nullptr)
5560 return nullptr;
5561 return make<SpecialName>("covariant return thunk to ", Encoding);
5562 }
5563 // extension ::= TC <first type> <number> _ <second type>
5564 // # construction vtable for second-in-first
5565 case 'C': {
5566 First += 2;
5567 Node *FirstType = getDerived().parseType();
5568 if (FirstType == nullptr)
5569 return nullptr;
5570 if (parseNumber(AllowNegative: true).empty() || !consumeIf('_'))
5571 return nullptr;
5572 Node *SecondType = getDerived().parseType();
5573 if (SecondType == nullptr)
5574 return nullptr;
5575 return make<CtorVtableSpecialName>(SecondType, FirstType);
5576 }
5577 // TW <object name> # Thread-local wrapper
5578 case 'W': {
5579 First += 2;
5580 Node *Name = getDerived().parseName();
5581 if (Name == nullptr)
5582 return nullptr;
5583 return make<SpecialName>("thread-local wrapper routine for ", Name);
5584 }
5585 // TH <object name> # Thread-local initialization
5586 case 'H': {
5587 First += 2;
5588 Node *Name = getDerived().parseName();
5589 if (Name == nullptr)
5590 return nullptr;
5591 return make<SpecialName>("thread-local initialization routine for ", Name);
5592 }
5593 // T <call-offset> <base encoding>
5594 default: {
5595 ++First;
5596 bool IsVirt = look() == 'v';
5597 if (parseCallOffset())
5598 return nullptr;
5599 Node *BaseEncoding = getDerived().parseEncoding();
5600 if (BaseEncoding == nullptr)
5601 return nullptr;
5602 if (IsVirt)
5603 return make<SpecialName>("virtual thunk to ", BaseEncoding);
5604 else
5605 return make<SpecialName>("non-virtual thunk to ", BaseEncoding);
5606 }
5607 }
5608 case 'G':
5609 switch (look(Lookahead: 1)) {
5610 // GV <object name> # Guard variable for one-time initialization
5611 case 'V': {
5612 First += 2;
5613 Node *Name = getDerived().parseName();
5614 if (Name == nullptr)
5615 return nullptr;
5616 return make<SpecialName>("guard variable for ", Name);
5617 }
5618 // GR <object name> # reference temporary for object
5619 // GR <object name> _ # First temporary
5620 // GR <object name> <seq-id> _ # Subsequent temporaries
5621 case 'R': {
5622 First += 2;
5623 Node *Name = getDerived().parseName();
5624 if (Name == nullptr)
5625 return nullptr;
5626 size_t Count;
5627 bool ParsedSeqId = !parseSeqId(Out: &Count);
5628 if (!consumeIf('_') && ParsedSeqId)
5629 return nullptr;
5630 return make<SpecialName>("reference temporary for ", Name);
5631 }
5632 // GI <module-name> v
5633 case 'I': {
5634 First += 2;
5635 ModuleName *Module = nullptr;
5636 if (getDerived().parseModuleNameOpt(Module))
5637 return nullptr;
5638 if (Module == nullptr)
5639 return nullptr;
5640 return make<SpecialName>("initializer for module ", Module);
5641 }
5642 }
5643 }
5644 return nullptr;
5645}
5646
5647// <encoding> ::= <function name> <bare-function-type>
5648// [`Q` <requires-clause expr>]
5649// ::= <data name>
5650// ::= <special-name>
5651template <typename Derived, typename Alloc>
5652Node *AbstractManglingParser<Derived, Alloc>::parseEncoding(bool ParseParams) {
5653 // The template parameters of an encoding are unrelated to those of the
5654 // enclosing context.
5655 SaveTemplateParams SaveTemplateParamsScope(this);
5656
5657 if (look() == 'G' || look() == 'T')
5658 return getDerived().parseSpecialName();
5659
5660 auto IsEndOfEncoding = [&] {
5661 // The set of chars that can potentially follow an <encoding> (none of which
5662 // can start a <type>). Enumerating these allows us to avoid speculative
5663 // parsing.
5664 return numLeft() == 0 || look() == 'E' || look() == '.' || look() == '_';
5665 };
5666
5667 NameState NameInfo(this);
5668 Node *Name = getDerived().parseName(&NameInfo);
5669 if (Name == nullptr)
5670 return nullptr;
5671
5672 if (resolveForwardTemplateRefs(State&: NameInfo))
5673 return nullptr;
5674
5675 if (IsEndOfEncoding())
5676 return Name;
5677
5678 // ParseParams may be false at the top level only, when called from parse().
5679 // For example in the mangled name _Z3fooILZ3BarEET_f, ParseParams may be
5680 // false when demangling 3fooILZ3BarEET_f but is always true when demangling
5681 // 3Bar.
5682 if (!ParseParams) {
5683 while (consume())
5684 ;
5685 return Name;
5686 }
5687
5688 Node *Attrs = nullptr;
5689 if (consumeIf("Ua9enable_ifI")) {
5690 size_t BeforeArgs = Names.size();
5691 while (!consumeIf('E')) {
5692 Node *Arg = getDerived().parseTemplateArg();
5693 if (Arg == nullptr)
5694 return nullptr;
5695 Names.push_back(Elem: Arg);
5696 }
5697 Attrs = make<EnableIfAttr>(popTrailingNodeArray(FromPosition: BeforeArgs));
5698 if (!Attrs)
5699 return nullptr;
5700 }
5701
5702 Node *ReturnType = nullptr;
5703 if (!NameInfo.CtorDtorConversion && NameInfo.EndsWithTemplateArgs) {
5704 ReturnType = getDerived().parseType();
5705 if (ReturnType == nullptr)
5706 return nullptr;
5707 }
5708
5709 NodeArray Params;
5710 if (!consumeIf('v')) {
5711 size_t ParamsBegin = Names.size();
5712 do {
5713 Node *Ty = getDerived().parseType();
5714 if (Ty == nullptr)
5715 return nullptr;
5716
5717 const bool IsFirstParam = ParamsBegin == Names.size();
5718 if (NameInfo.HasExplicitObjectParameter && IsFirstParam)
5719 Ty = make<ExplicitObjectParameter>(Ty);
5720
5721 if (Ty == nullptr)
5722 return nullptr;
5723
5724 Names.push_back(Elem: Ty);
5725 } while (!IsEndOfEncoding() && look() != 'Q');
5726 Params = popTrailingNodeArray(FromPosition: ParamsBegin);
5727 }
5728
5729 Node *Requires = nullptr;
5730 if (consumeIf('Q')) {
5731 Requires = getDerived().parseConstraintExpr();
5732 if (!Requires)
5733 return nullptr;
5734 }
5735
5736 return make<FunctionEncoding>(ReturnType, Name, Params, Attrs, Requires,
5737 NameInfo.CVQualifiers,
5738 NameInfo.ReferenceQualifier);
5739}
5740
5741template <class Float>
5742struct FloatData;
5743
5744template <>
5745struct FloatData<float>
5746{
5747 static const size_t mangled_size = 8;
5748 static const size_t max_demangled_size = 24;
5749 static constexpr const char* spec = "%af";
5750};
5751
5752template <>
5753struct FloatData<double>
5754{
5755 static const size_t mangled_size = 16;
5756 static const size_t max_demangled_size = 32;
5757 static constexpr const char* spec = "%a";
5758};
5759
5760template <>
5761struct FloatData<long double>
5762{
5763#if __LDBL_MANT_DIG__ == 113 || __LDBL_MANT_DIG__ == 106
5764 static const size_t mangled_size = 32;
5765#elif __LDBL_MANT_DIG__ == 53 || defined(_MSC_VER)
5766 // MSVC doesn't define __LDBL_MANT_DIG__, but it has long double equal to
5767 // regular double on all current architectures.
5768 static const size_t mangled_size = 16;
5769#elif __LDBL_MANT_DIG__ == 64
5770 static const size_t mangled_size = 20;
5771#else
5772#error Unknown size for __LDBL_MANT_DIG__
5773#endif
5774 // `-0x1.ffffffffffffffffffffffffffffp+16383` + 'L' + '\0' == 42 bytes.
5775 // 28 'f's * 4 bits == 112 bits, which is the number of mantissa bits.
5776 // Negatives are one character longer than positives.
5777 // `0x1.` and `p` are constant, and exponents `+16383` and `-16382` are the
5778 // same length. 1 sign bit, 112 mantissa bits, and 15 exponent bits == 128.
5779 static const size_t max_demangled_size = 42;
5780 static constexpr const char *spec = "%LaL";
5781};
5782
5783template <typename Alloc, typename Derived>
5784template <class Float>
5785Node *AbstractManglingParser<Alloc, Derived>::parseFloatingLiteral() {
5786 const size_t N = FloatData<Float>::mangled_size;
5787 if (numLeft() <= N)
5788 return nullptr;
5789 std::string_view Data(First, N);
5790 for (char C : Data)
5791 if (!(C >= '0' && C <= '9') && !(C >= 'a' && C <= 'f'))
5792 return nullptr;
5793 First += N;
5794 if (!consumeIf('E'))
5795 return nullptr;
5796 return make<FloatLiteralImpl<Float>>(Data);
5797}
5798
5799// <seq-id> ::= <0-9A-Z>+
5800template <typename Alloc, typename Derived>
5801bool AbstractManglingParser<Alloc, Derived>::parseSeqId(size_t *Out) {
5802 if (!(look() >= '0' && look() <= '9') &&
5803 !(look() >= 'A' && look() <= 'Z'))
5804 return true;
5805
5806 size_t Id = 0;
5807 while (true) {
5808 if (look() >= '0' && look() <= '9') {
5809 Id *= 36;
5810 Id += static_cast<size_t>(look() - '0');
5811 } else if (look() >= 'A' && look() <= 'Z') {
5812 Id *= 36;
5813 Id += static_cast<size_t>(look() - 'A') + 10;
5814 } else {
5815 *Out = Id;
5816 return false;
5817 }
5818 ++First;
5819 }
5820}
5821
5822// <substitution> ::= S <seq-id> _
5823// ::= S_
5824// <substitution> ::= Sa # ::std::allocator
5825// <substitution> ::= Sb # ::std::basic_string
5826// <substitution> ::= Ss # ::std::basic_string < char,
5827// ::std::char_traits<char>,
5828// ::std::allocator<char> >
5829// <substitution> ::= Si # ::std::basic_istream<char, std::char_traits<char> >
5830// <substitution> ::= So # ::std::basic_ostream<char, std::char_traits<char> >
5831// <substitution> ::= Sd # ::std::basic_iostream<char, std::char_traits<char> >
5832// The St case is handled specially in parseNestedName.
5833template <typename Derived, typename Alloc>
5834Node *AbstractManglingParser<Derived, Alloc>::parseSubstitution() {
5835 if (!consumeIf('S'))
5836 return nullptr;
5837
5838 if (look() >= 'a' && look() <= 'z') {
5839 SpecialSubKind Kind;
5840 switch (look()) {
5841 case 'a':
5842 Kind = SpecialSubKind::allocator;
5843 break;
5844 case 'b':
5845 Kind = SpecialSubKind::basic_string;
5846 break;
5847 case 'd':
5848 Kind = SpecialSubKind::iostream;
5849 break;
5850 case 'i':
5851 Kind = SpecialSubKind::istream;
5852 break;
5853 case 'o':
5854 Kind = SpecialSubKind::ostream;
5855 break;
5856 case 's':
5857 Kind = SpecialSubKind::string;
5858 break;
5859 default:
5860 return nullptr;
5861 }
5862 ++First;
5863 auto *SpecialSub = make<SpecialSubstitution>(Kind);
5864 if (!SpecialSub)
5865 return nullptr;
5866
5867 // Itanium C++ ABI 5.1.2: If a name that would use a built-in <substitution>
5868 // has ABI tags, the tags are appended to the substitution; the result is a
5869 // substitutable component.
5870 Node *WithTags = getDerived().parseAbiTags(SpecialSub);
5871 if (WithTags != SpecialSub) {
5872 Subs.push_back(Elem: WithTags);
5873 SpecialSub = WithTags;
5874 }
5875 return SpecialSub;
5876 }
5877
5878 // ::= S_
5879 if (consumeIf('_')) {
5880 if (Subs.empty())
5881 return nullptr;
5882 return Subs[0];
5883 }
5884
5885 // ::= S <seq-id> _
5886 size_t Index = 0;
5887 if (parseSeqId(Out: &Index))
5888 return nullptr;
5889 ++Index;
5890 if (!consumeIf('_') || Index >= Subs.size())
5891 return nullptr;
5892 return Subs[Index];
5893}
5894
5895// <template-param> ::= T_ # first template parameter
5896// ::= T <parameter-2 non-negative number> _
5897// ::= TL <level-1> __
5898// ::= TL <level-1> _ <parameter-2 non-negative number> _
5899template <typename Derived, typename Alloc>
5900Node *AbstractManglingParser<Derived, Alloc>::parseTemplateParam() {
5901 const char *Begin = First;
5902 if (!consumeIf('T'))
5903 return nullptr;
5904
5905 size_t Level = 0;
5906 if (consumeIf('L')) {
5907 if (parsePositiveInteger(Out: &Level))
5908 return nullptr;
5909 ++Level;
5910 if (!consumeIf('_'))
5911 return nullptr;
5912 }
5913
5914 size_t Index = 0;
5915 if (!consumeIf('_')) {
5916 if (parsePositiveInteger(Out: &Index))
5917 return nullptr;
5918 ++Index;
5919 if (!consumeIf('_'))
5920 return nullptr;
5921 }
5922
5923 // We don't track enclosing template parameter levels well enough to reliably
5924 // substitute them all within a <constraint-expression>, so print the
5925 // parameter numbering instead for now.
5926 // TODO: Track all enclosing template parameters and substitute them here.
5927 if (HasIncompleteTemplateParameterTracking) {
5928 return make<NameType>(std::string_view(Begin, First - 1 - Begin));
5929 }
5930
5931 // If we're in a context where this <template-param> refers to a
5932 // <template-arg> further ahead in the mangled name (currently just conversion
5933 // operator types), then we should only look it up in the right context.
5934 // This can only happen at the outermost level.
5935 if (PermitForwardTemplateReferences && Level == 0) {
5936 Node *ForwardRef = make<ForwardTemplateReference>(Index);
5937 if (!ForwardRef)
5938 return nullptr;
5939 DEMANGLE_ASSERT(ForwardRef->getKind() == Node::KForwardTemplateReference,
5940 "");
5941 ForwardTemplateRefs.push_back(
5942 Elem: static_cast<ForwardTemplateReference *>(ForwardRef));
5943 return ForwardRef;
5944 }
5945
5946 if (Level >= TemplateParams.size() || !TemplateParams[Level] ||
5947 Index >= TemplateParams[Level]->size()) {
5948 // Itanium ABI 5.1.8: In a generic lambda, uses of auto in the parameter
5949 // list are mangled as the corresponding artificial template type parameter.
5950 if (ParsingLambdaParamsAtLevel == Level && Level <= TemplateParams.size()) {
5951 // This will be popped by the ScopedTemplateParamList in
5952 // parseUnnamedTypeName.
5953 if (Level == TemplateParams.size())
5954 TemplateParams.push_back(Elem: nullptr);
5955 return make<NameType>("auto");
5956 }
5957
5958 return nullptr;
5959 }
5960
5961 return (*TemplateParams[Level])[Index];
5962}
5963
5964// <template-param-decl> ::= Ty # type parameter
5965// ::= Tk <concept name> [<template-args>] # constrained type parameter
5966// ::= Tn <type> # non-type parameter
5967// ::= Tt <template-param-decl>* E # template parameter
5968// ::= Tp <template-param-decl> # parameter pack
5969template <typename Derived, typename Alloc>
5970Node *AbstractManglingParser<Derived, Alloc>::parseTemplateParamDecl(
5971 TemplateParamList *Params) {
5972 auto InventTemplateParamName = [&](TemplateParamKind Kind) {
5973 unsigned Index = NumSyntheticTemplateParameters[(int)Kind]++;
5974 Node *N = make<SyntheticTemplateParamName>(Kind, Index);
5975 if (N && Params)
5976 Params->push_back(Elem: N);
5977 return N;
5978 };
5979
5980 if (consumeIf("Ty")) {
5981 Node *Name = InventTemplateParamName(TemplateParamKind::Type);
5982 if (!Name)
5983 return nullptr;
5984 return make<TypeTemplateParamDecl>(Name);
5985 }
5986
5987 if (consumeIf("Tk")) {
5988 // We don't track enclosing template parameter levels well enough to
5989 // reliably demangle template parameter substitutions, so print an arbitrary
5990 // string in place of a parameter for now.
5991 // TODO: Track all enclosing template parameters and demangle substitutions.
5992 ScopedOverride<bool> SaveIncompleteTemplateParameterTrackingExpr(
5993 HasIncompleteTemplateParameterTracking, true);
5994 Node *Constraint = getDerived().parseName();
5995 if (!Constraint)
5996 return nullptr;
5997 Node *Name = InventTemplateParamName(TemplateParamKind::Type);
5998 if (!Name)
5999 return nullptr;
6000 return make<ConstrainedTypeTemplateParamDecl>(Constraint, Name);
6001 }
6002
6003 if (consumeIf("Tn")) {
6004 Node *Name = InventTemplateParamName(TemplateParamKind::NonType);
6005 if (!Name)
6006 return nullptr;
6007 Node *Type = parseType();
6008 if (!Type)
6009 return nullptr;
6010 return make<NonTypeTemplateParamDecl>(Name, Type);
6011 }
6012
6013 if (consumeIf("Tt")) {
6014 Node *Name = InventTemplateParamName(TemplateParamKind::Template);
6015 if (!Name)
6016 return nullptr;
6017 size_t ParamsBegin = Names.size();
6018 ScopedTemplateParamList TemplateTemplateParamParams(this);
6019 Node *Requires = nullptr;
6020 while (!consumeIf('E')) {
6021 Node *P = parseTemplateParamDecl(Params: TemplateTemplateParamParams.params());
6022 if (!P)
6023 return nullptr;
6024 Names.push_back(Elem: P);
6025 if (consumeIf('Q')) {
6026 Requires = getDerived().parseConstraintExpr();
6027 if (Requires == nullptr || !consumeIf('E'))
6028 return nullptr;
6029 break;
6030 }
6031 }
6032 NodeArray InnerParams = popTrailingNodeArray(FromPosition: ParamsBegin);
6033 return make<TemplateTemplateParamDecl>(Name, InnerParams, Requires);
6034 }
6035
6036 if (consumeIf("Tp")) {
6037 Node *P = parseTemplateParamDecl(Params);
6038 if (!P)
6039 return nullptr;
6040 return make<TemplateParamPackDecl>(P);
6041 }
6042
6043 return nullptr;
6044}
6045
6046// <template-arg> ::= <type> # type or template
6047// ::= X <expression> E # expression
6048// ::= <expr-primary> # simple expressions
6049// ::= J <template-arg>* E # argument pack
6050// ::= LZ <encoding> E # extension
6051// ::= <template-param-decl> <template-arg>
6052template <typename Derived, typename Alloc>
6053Node *AbstractManglingParser<Derived, Alloc>::parseTemplateArg() {
6054 switch (look()) {
6055 case 'X': {
6056 ++First;
6057 Node *Arg = getDerived().parseExpr();
6058 if (Arg == nullptr || !consumeIf('E'))
6059 return nullptr;
6060 return Arg;
6061 }
6062 case 'J': {
6063 ++First;
6064 size_t ArgsBegin = Names.size();
6065 while (!consumeIf('E')) {
6066 Node *Arg = getDerived().parseTemplateArg();
6067 if (Arg == nullptr)
6068 return nullptr;
6069 Names.push_back(Elem: Arg);
6070 }
6071 NodeArray Args = popTrailingNodeArray(FromPosition: ArgsBegin);
6072 return make<TemplateArgumentPack>(Args);
6073 }
6074 case 'L': {
6075 // ::= LZ <encoding> E # extension
6076 if (look(Lookahead: 1) == 'Z') {
6077 First += 2;
6078 Node *Arg = getDerived().parseEncoding();
6079 if (Arg == nullptr || !consumeIf('E'))
6080 return nullptr;
6081 return Arg;
6082 }
6083 // ::= <expr-primary> # simple expressions
6084 return getDerived().parseExprPrimary();
6085 }
6086 case 'T': {
6087 // Either <template-param> or a <template-param-decl> <template-arg>.
6088 if (!getDerived().isTemplateParamDecl())
6089 return getDerived().parseType();
6090 Node *Param = getDerived().parseTemplateParamDecl(nullptr);
6091 if (!Param)
6092 return nullptr;
6093 Node *Arg = getDerived().parseTemplateArg();
6094 if (!Arg)
6095 return nullptr;
6096 return make<TemplateParamQualifiedArg>(Param, Arg);
6097 }
6098 default:
6099 return getDerived().parseType();
6100 }
6101}
6102
6103// <template-args> ::= I <template-arg>* [Q <requires-clause expr>] E
6104// extension, the abi says <template-arg>+
6105template <typename Derived, typename Alloc>
6106Node *
6107AbstractManglingParser<Derived, Alloc>::parseTemplateArgs(bool TagTemplates) {
6108 if (!consumeIf('I'))
6109 return nullptr;
6110
6111 // <template-params> refer to the innermost <template-args>. Clear out any
6112 // outer args that we may have inserted into TemplateParams.
6113 if (TagTemplates) {
6114 TemplateParams.clear();
6115 TemplateParams.push_back(Elem: &OuterTemplateParams);
6116 OuterTemplateParams.clear();
6117 }
6118
6119 size_t ArgsBegin = Names.size();
6120 Node *Requires = nullptr;
6121 while (!consumeIf('E')) {
6122 if (TagTemplates) {
6123 Node *Arg = getDerived().parseTemplateArg();
6124 if (Arg == nullptr)
6125 return nullptr;
6126 Names.push_back(Elem: Arg);
6127 Node *TableEntry = Arg;
6128 if (Arg->getKind() == Node::KTemplateParamQualifiedArg) {
6129 TableEntry =
6130 static_cast<TemplateParamQualifiedArg *>(TableEntry)->getArg();
6131 }
6132 if (Arg->getKind() == Node::KTemplateArgumentPack) {
6133 TableEntry = make<ParameterPack>(
6134 static_cast<TemplateArgumentPack*>(TableEntry)->getElements());
6135 if (!TableEntry)
6136 return nullptr;
6137 }
6138 OuterTemplateParams.push_back(Elem: TableEntry);
6139 } else {
6140 Node *Arg = getDerived().parseTemplateArg();
6141 if (Arg == nullptr)
6142 return nullptr;
6143 Names.push_back(Elem: Arg);
6144 }
6145 if (consumeIf('Q')) {
6146 Requires = getDerived().parseConstraintExpr();
6147 if (!Requires || !consumeIf('E'))
6148 return nullptr;
6149 break;
6150 }
6151 }
6152 return make<TemplateArgs>(popTrailingNodeArray(FromPosition: ArgsBegin), Requires);
6153}
6154
6155// <mangled-name> ::= _Z <encoding>
6156// ::= <type>
6157// extension ::= ___Z <encoding> _block_invoke
6158// extension ::= ___Z <encoding> _block_invoke<decimal-digit>+
6159// extension ::= ___Z <encoding> _block_invoke_<decimal-digit>+
6160template <typename Derived, typename Alloc>
6161Node *AbstractManglingParser<Derived, Alloc>::parse(bool ParseParams) {
6162 if (consumeIf("_Z") || consumeIf("__Z")) {
6163 Node *Encoding = getDerived().parseEncoding(ParseParams);
6164 if (Encoding == nullptr)
6165 return nullptr;
6166 if (look() == '.') {
6167 Encoding =
6168 make<DotSuffix>(Encoding, std::string_view(First, Last - First));
6169 First = Last;
6170 }
6171 if (numLeft() != 0)
6172 return nullptr;
6173 return Encoding;
6174 }
6175
6176 if (consumeIf("___Z") || consumeIf("____Z")) {
6177 Node *Encoding = getDerived().parseEncoding(ParseParams);
6178 if (Encoding == nullptr || !consumeIf("_block_invoke"))
6179 return nullptr;
6180 bool RequireNumber = consumeIf('_');
6181 if (parseNumber().empty() && RequireNumber)
6182 return nullptr;
6183 if (look() == '.')
6184 First = Last;
6185 if (numLeft() != 0)
6186 return nullptr;
6187 return make<SpecialName>("invocation function for block in ", Encoding);
6188 }
6189
6190 Node *Ty = getDerived().parseType();
6191 if (numLeft() != 0)
6192 return nullptr;
6193 return Ty;
6194}
6195
6196template <typename Alloc>
6197struct ManglingParser : AbstractManglingParser<ManglingParser<Alloc>, Alloc> {
6198 using AbstractManglingParser<ManglingParser<Alloc>,
6199 Alloc>::AbstractManglingParser;
6200};
6201
6202inline void OutputBuffer::printLeft(const Node &N) { N.printLeft(*this); }
6203
6204inline void OutputBuffer::printRight(const Node &N) { N.printRight(*this); }
6205
6206DEMANGLE_NAMESPACE_END
6207
6208#if defined(__clang__)
6209#pragma clang diagnostic pop
6210#endif
6211
6212#endif // DEMANGLE_ITANIUMDEMANGLE_H
6213