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