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