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