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