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