brintos

brintos / llvm-project-archived public Read only

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