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