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