File indexing completed on 2026-05-10 08:43:48
0001
0002
0003
0004
0005
0006
0007
0008
0009
0010
0011
0012
0013
0014
0015
0016 #ifndef DEMANGLE_ITANIUMDEMANGLE_H
0017 #define DEMANGLE_ITANIUMDEMANGLE_H
0018
0019 #include "DemangleConfig.h"
0020 #include "StringViewExtras.h"
0021 #include "Utility.h"
0022 #include <algorithm>
0023 #include <cctype>
0024 #include <cstdio>
0025 #include <cstdlib>
0026 #include <cstring>
0027 #include <limits>
0028 #include <new>
0029 #include <string_view>
0030 #include <type_traits>
0031 #include <utility>
0032
0033 #if defined(__clang__)
0034 #pragma clang diagnostic push
0035 #pragma clang diagnostic ignored "-Wunused-template"
0036 #endif
0037
0038 DEMANGLE_NAMESPACE_BEGIN
0039
0040 template <class T, size_t N> class PODSmallVector {
0041 static_assert(std::is_trivial<T>::value,
0042 "T is required to be a trivial type");
0043 T *First = nullptr;
0044 T *Last = nullptr;
0045 T *Cap = nullptr;
0046 T Inline[N] = {};
0047
0048 bool isInline() const { return First == Inline; }
0049
0050 void clearInline() {
0051 First = Inline;
0052 Last = Inline;
0053 Cap = Inline + N;
0054 }
0055
0056 void reserve(size_t NewCap) {
0057 size_t S = size();
0058 if (isInline()) {
0059 auto *Tmp = static_cast<T *>(std::malloc(NewCap * sizeof(T)));
0060 if (Tmp == nullptr)
0061 std::abort();
0062 std::copy(First, Last, Tmp);
0063 First = Tmp;
0064 } else {
0065 First = static_cast<T *>(std::realloc(First, NewCap * sizeof(T)));
0066 if (First == nullptr)
0067 std::abort();
0068 }
0069 Last = First + S;
0070 Cap = First + NewCap;
0071 }
0072
0073 public:
0074 PODSmallVector() : First(Inline), Last(First), Cap(Inline + N) {}
0075
0076 PODSmallVector(const PODSmallVector &) = delete;
0077 PODSmallVector &operator=(const PODSmallVector &) = delete;
0078
0079 PODSmallVector(PODSmallVector &&Other) : PODSmallVector() {
0080 if (Other.isInline()) {
0081 std::copy(Other.begin(), Other.end(), First);
0082 Last = First + Other.size();
0083 Other.clear();
0084 return;
0085 }
0086
0087 First = Other.First;
0088 Last = Other.Last;
0089 Cap = Other.Cap;
0090 Other.clearInline();
0091 }
0092
0093 PODSmallVector &operator=(PODSmallVector &&Other) {
0094 if (Other.isInline()) {
0095 if (!isInline()) {
0096 std::free(First);
0097 clearInline();
0098 }
0099 std::copy(Other.begin(), Other.end(), First);
0100 Last = First + Other.size();
0101 Other.clear();
0102 return *this;
0103 }
0104
0105 if (isInline()) {
0106 First = Other.First;
0107 Last = Other.Last;
0108 Cap = Other.Cap;
0109 Other.clearInline();
0110 return *this;
0111 }
0112
0113 std::swap(First, Other.First);
0114 std::swap(Last, Other.Last);
0115 std::swap(Cap, Other.Cap);
0116 Other.clear();
0117 return *this;
0118 }
0119
0120
0121 void push_back(const T &Elem) {
0122 if (Last == Cap)
0123 reserve(size() * 2);
0124 *Last++ = Elem;
0125 }
0126
0127
0128 void pop_back() {
0129 DEMANGLE_ASSERT(Last != First, "Popping empty vector!");
0130 --Last;
0131 }
0132
0133 void shrinkToSize(size_t Index) {
0134 DEMANGLE_ASSERT(Index <= size(), "shrinkToSize() can't expand!");
0135 Last = First + Index;
0136 }
0137
0138 T *begin() { return First; }
0139 T *end() { return Last; }
0140
0141 bool empty() const { return First == Last; }
0142 size_t size() const { return static_cast<size_t>(Last - First); }
0143 T &back() {
0144 DEMANGLE_ASSERT(Last != First, "Calling back() on empty vector!");
0145 return *(Last - 1);
0146 }
0147 T &operator[](size_t Index) {
0148 DEMANGLE_ASSERT(Index < size(), "Invalid access!");
0149 return *(begin() + Index);
0150 }
0151 void clear() { Last = First; }
0152
0153 ~PODSmallVector() {
0154 if (!isInline())
0155 std::free(First);
0156 }
0157 };
0158
0159 class NodeArray;
0160
0161
0162
0163 class Node {
0164 public:
0165 enum Kind : unsigned char {
0166 #define NODE(NodeKind) K##NodeKind,
0167 #include "ItaniumNodes.def"
0168 };
0169
0170
0171
0172 enum class Cache : unsigned char { Yes, No, Unknown, };
0173
0174
0175
0176 enum class Prec {
0177 Primary,
0178 Postfix,
0179 Unary,
0180 Cast,
0181 PtrMem,
0182 Multiplicative,
0183 Additive,
0184 Shift,
0185 Spaceship,
0186 Relational,
0187 Equality,
0188 And,
0189 Xor,
0190 Ior,
0191 AndIf,
0192 OrIf,
0193 Conditional,
0194 Assign,
0195 Comma,
0196 Default,
0197 };
0198
0199 private:
0200 Kind K;
0201
0202 Prec Precedence : 6;
0203
0204 protected:
0205
0206
0207 Cache RHSComponentCache : 2;
0208
0209
0210
0211 Cache ArrayCache : 2;
0212
0213
0214
0215 Cache FunctionCache : 2;
0216
0217 public:
0218 Node(Kind K_, Prec Precedence_ = Prec::Primary,
0219 Cache RHSComponentCache_ = Cache::No, Cache ArrayCache_ = Cache::No,
0220 Cache FunctionCache_ = Cache::No)
0221 : K(K_), Precedence(Precedence_), RHSComponentCache(RHSComponentCache_),
0222 ArrayCache(ArrayCache_), FunctionCache(FunctionCache_) {}
0223 Node(Kind K_, Cache RHSComponentCache_, Cache ArrayCache_ = Cache::No,
0224 Cache FunctionCache_ = Cache::No)
0225 : Node(K_, Prec::Primary, RHSComponentCache_, ArrayCache_,
0226 FunctionCache_) {}
0227
0228
0229 template<typename Fn> void visit(Fn F) const;
0230
0231
0232
0233
0234
0235
0236
0237 bool hasRHSComponent(OutputBuffer &OB) const {
0238 if (RHSComponentCache != Cache::Unknown)
0239 return RHSComponentCache == Cache::Yes;
0240 return hasRHSComponentSlow(OB);
0241 }
0242
0243 bool hasArray(OutputBuffer &OB) const {
0244 if (ArrayCache != Cache::Unknown)
0245 return ArrayCache == Cache::Yes;
0246 return hasArraySlow(OB);
0247 }
0248
0249 bool hasFunction(OutputBuffer &OB) const {
0250 if (FunctionCache != Cache::Unknown)
0251 return FunctionCache == Cache::Yes;
0252 return hasFunctionSlow(OB);
0253 }
0254
0255 Kind getKind() const { return K; }
0256
0257 Prec getPrecedence() const { return Precedence; }
0258 Cache getRHSComponentCache() const { return RHSComponentCache; }
0259 Cache getArrayCache() const { return ArrayCache; }
0260 Cache getFunctionCache() const { return FunctionCache; }
0261
0262 virtual bool hasRHSComponentSlow(OutputBuffer &) const { return false; }
0263 virtual bool hasArraySlow(OutputBuffer &) const { return false; }
0264 virtual bool hasFunctionSlow(OutputBuffer &) const { return false; }
0265
0266
0267
0268 virtual const Node *getSyntaxNode(OutputBuffer &) const { return this; }
0269
0270
0271
0272 void printAsOperand(OutputBuffer &OB, Prec P = Prec::Default,
0273 bool StrictlyWorse = false) const {
0274 bool Paren =
0275 unsigned(getPrecedence()) >= unsigned(P) + unsigned(StrictlyWorse);
0276 if (Paren)
0277 OB.printOpen();
0278 print(OB);
0279 if (Paren)
0280 OB.printClose();
0281 }
0282
0283 void print(OutputBuffer &OB) const {
0284 printLeft(OB);
0285 if (RHSComponentCache != Cache::No)
0286 printRight(OB);
0287 }
0288
0289
0290 virtual void printLeft(OutputBuffer &) const = 0;
0291
0292
0293
0294
0295
0296 virtual void printRight(OutputBuffer &) const {}
0297
0298
0299
0300
0301 virtual bool printInitListAsType(OutputBuffer &, const NodeArray &) const {
0302 return false;
0303 }
0304
0305 virtual std::string_view getBaseName() const { return {}; }
0306
0307
0308 virtual ~Node() = default;
0309
0310 #ifndef NDEBUG
0311 DEMANGLE_DUMP_METHOD void dump() const;
0312 #endif
0313 };
0314
0315 class NodeArray {
0316 Node **Elements;
0317 size_t NumElements;
0318
0319 public:
0320 NodeArray() : Elements(nullptr), NumElements(0) {}
0321 NodeArray(Node **Elements_, size_t NumElements_)
0322 : Elements(Elements_), NumElements(NumElements_) {}
0323
0324 bool empty() const { return NumElements == 0; }
0325 size_t size() const { return NumElements; }
0326
0327 Node **begin() const { return Elements; }
0328 Node **end() const { return Elements + NumElements; }
0329
0330 Node *operator[](size_t Idx) const { return Elements[Idx]; }
0331
0332 void printWithComma(OutputBuffer &OB) const {
0333 bool FirstElement = true;
0334 for (size_t Idx = 0; Idx != NumElements; ++Idx) {
0335 size_t BeforeComma = OB.getCurrentPosition();
0336 if (!FirstElement)
0337 OB += ", ";
0338 size_t AfterComma = OB.getCurrentPosition();
0339 Elements[Idx]->printAsOperand(OB, Node::Prec::Comma);
0340
0341
0342
0343 if (AfterComma == OB.getCurrentPosition()) {
0344 OB.setCurrentPosition(BeforeComma);
0345 continue;
0346 }
0347
0348 FirstElement = false;
0349 }
0350 }
0351
0352
0353
0354 bool printAsString(OutputBuffer &OB) const;
0355 };
0356
0357 struct NodeArrayNode : Node {
0358 NodeArray Array;
0359 NodeArrayNode(NodeArray Array_) : Node(KNodeArrayNode), Array(Array_) {}
0360
0361 template<typename Fn> void match(Fn F) const { F(Array); }
0362
0363 void printLeft(OutputBuffer &OB) const override { Array.printWithComma(OB); }
0364 };
0365
0366 class DotSuffix final : public Node {
0367 const Node *Prefix;
0368 const std::string_view Suffix;
0369
0370 public:
0371 DotSuffix(const Node *Prefix_, std::string_view Suffix_)
0372 : Node(KDotSuffix), Prefix(Prefix_), Suffix(Suffix_) {}
0373
0374 template<typename Fn> void match(Fn F) const { F(Prefix, Suffix); }
0375
0376 void printLeft(OutputBuffer &OB) const override {
0377 Prefix->print(OB);
0378 OB += " (";
0379 OB += Suffix;
0380 OB += ")";
0381 }
0382 };
0383
0384 class VendorExtQualType final : public Node {
0385 const Node *Ty;
0386 std::string_view Ext;
0387 const Node *TA;
0388
0389 public:
0390 VendorExtQualType(const Node *Ty_, std::string_view Ext_, const Node *TA_)
0391 : Node(KVendorExtQualType), Ty(Ty_), Ext(Ext_), TA(TA_) {}
0392
0393 const Node *getTy() const { return Ty; }
0394 std::string_view getExt() const { return Ext; }
0395 const Node *getTA() const { return TA; }
0396
0397 template <typename Fn> void match(Fn F) const { F(Ty, Ext, TA); }
0398
0399 void printLeft(OutputBuffer &OB) const override {
0400 Ty->print(OB);
0401 OB += " ";
0402 OB += Ext;
0403 if (TA != nullptr)
0404 TA->print(OB);
0405 }
0406 };
0407
0408 enum FunctionRefQual : unsigned char {
0409 FrefQualNone,
0410 FrefQualLValue,
0411 FrefQualRValue,
0412 };
0413
0414 enum Qualifiers {
0415 QualNone = 0,
0416 QualConst = 0x1,
0417 QualVolatile = 0x2,
0418 QualRestrict = 0x4,
0419 };
0420
0421 inline Qualifiers operator|=(Qualifiers &Q1, Qualifiers Q2) {
0422 return Q1 = static_cast<Qualifiers>(Q1 | Q2);
0423 }
0424
0425 class QualType final : public Node {
0426 protected:
0427 const Qualifiers Quals;
0428 const Node *Child;
0429
0430 void printQuals(OutputBuffer &OB) const {
0431 if (Quals & QualConst)
0432 OB += " const";
0433 if (Quals & QualVolatile)
0434 OB += " volatile";
0435 if (Quals & QualRestrict)
0436 OB += " restrict";
0437 }
0438
0439 public:
0440 QualType(const Node *Child_, Qualifiers Quals_)
0441 : Node(KQualType, Child_->getRHSComponentCache(), Child_->getArrayCache(),
0442 Child_->getFunctionCache()),
0443 Quals(Quals_), Child(Child_) {}
0444
0445 Qualifiers getQuals() const { return Quals; }
0446 const Node *getChild() const { return Child; }
0447
0448 template<typename Fn> void match(Fn F) const { F(Child, Quals); }
0449
0450 bool hasRHSComponentSlow(OutputBuffer &OB) const override {
0451 return Child->hasRHSComponent(OB);
0452 }
0453 bool hasArraySlow(OutputBuffer &OB) const override {
0454 return Child->hasArray(OB);
0455 }
0456 bool hasFunctionSlow(OutputBuffer &OB) const override {
0457 return Child->hasFunction(OB);
0458 }
0459
0460 void printLeft(OutputBuffer &OB) const override {
0461 Child->printLeft(OB);
0462 printQuals(OB);
0463 }
0464
0465 void printRight(OutputBuffer &OB) const override { Child->printRight(OB); }
0466 };
0467
0468 class ConversionOperatorType final : public Node {
0469 const Node *Ty;
0470
0471 public:
0472 ConversionOperatorType(const Node *Ty_)
0473 : Node(KConversionOperatorType), Ty(Ty_) {}
0474
0475 template<typename Fn> void match(Fn F) const { F(Ty); }
0476
0477 void printLeft(OutputBuffer &OB) const override {
0478 OB += "operator ";
0479 Ty->print(OB);
0480 }
0481 };
0482
0483 class PostfixQualifiedType final : public Node {
0484 const Node *Ty;
0485 const std::string_view Postfix;
0486
0487 public:
0488 PostfixQualifiedType(const Node *Ty_, std::string_view Postfix_)
0489 : Node(KPostfixQualifiedType), Ty(Ty_), Postfix(Postfix_) {}
0490
0491 template<typename Fn> void match(Fn F) const { F(Ty, Postfix); }
0492
0493 void printLeft(OutputBuffer &OB) const override {
0494 Ty->printLeft(OB);
0495 OB += Postfix;
0496 }
0497 };
0498
0499 class NameType final : public Node {
0500 const std::string_view Name;
0501
0502 public:
0503 NameType(std::string_view Name_) : Node(KNameType), Name(Name_) {}
0504
0505 template<typename Fn> void match(Fn F) const { F(Name); }
0506
0507 std::string_view getName() const { return Name; }
0508 std::string_view getBaseName() const override { return Name; }
0509
0510 void printLeft(OutputBuffer &OB) const override { OB += Name; }
0511 };
0512
0513 class BitIntType final : public Node {
0514 const Node *Size;
0515 bool Signed;
0516
0517 public:
0518 BitIntType(const Node *Size_, bool Signed_)
0519 : Node(KBitIntType), Size(Size_), Signed(Signed_) {}
0520
0521 template <typename Fn> void match(Fn F) const { F(Size, Signed); }
0522
0523 void printLeft(OutputBuffer &OB) const override {
0524 if (!Signed)
0525 OB += "unsigned ";
0526 OB += "_BitInt";
0527 OB.printOpen();
0528 Size->printAsOperand(OB);
0529 OB.printClose();
0530 }
0531 };
0532
0533 class ElaboratedTypeSpefType : public Node {
0534 std::string_view Kind;
0535 Node *Child;
0536 public:
0537 ElaboratedTypeSpefType(std::string_view Kind_, Node *Child_)
0538 : Node(KElaboratedTypeSpefType), Kind(Kind_), Child(Child_) {}
0539
0540 template<typename Fn> void match(Fn F) const { F(Kind, Child); }
0541
0542 void printLeft(OutputBuffer &OB) const override {
0543 OB += Kind;
0544 OB += ' ';
0545 Child->print(OB);
0546 }
0547 };
0548
0549 class TransformedType : public Node {
0550 std::string_view Transform;
0551 Node *BaseType;
0552 public:
0553 TransformedType(std::string_view Transform_, Node *BaseType_)
0554 : Node(KTransformedType), Transform(Transform_), BaseType(BaseType_) {}
0555
0556 template<typename Fn> void match(Fn F) const { F(Transform, BaseType); }
0557
0558 void printLeft(OutputBuffer &OB) const override {
0559 OB += Transform;
0560 OB += '(';
0561 BaseType->print(OB);
0562 OB += ')';
0563 }
0564 };
0565
0566 struct AbiTagAttr : Node {
0567 Node *Base;
0568 std::string_view Tag;
0569
0570 AbiTagAttr(Node *Base_, std::string_view Tag_)
0571 : Node(KAbiTagAttr, Base_->getRHSComponentCache(), Base_->getArrayCache(),
0572 Base_->getFunctionCache()),
0573 Base(Base_), Tag(Tag_) {}
0574
0575 template<typename Fn> void match(Fn F) const { F(Base, Tag); }
0576
0577 std::string_view getBaseName() const override { return Base->getBaseName(); }
0578
0579 void printLeft(OutputBuffer &OB) const override {
0580 Base->printLeft(OB);
0581 OB += "[abi:";
0582 OB += Tag;
0583 OB += "]";
0584 }
0585 };
0586
0587 class EnableIfAttr : public Node {
0588 NodeArray Conditions;
0589 public:
0590 EnableIfAttr(NodeArray Conditions_)
0591 : Node(KEnableIfAttr), Conditions(Conditions_) {}
0592
0593 template<typename Fn> void match(Fn F) const { F(Conditions); }
0594
0595 void printLeft(OutputBuffer &OB) const override {
0596 OB += " [enable_if:";
0597 Conditions.printWithComma(OB);
0598 OB += ']';
0599 }
0600 };
0601
0602 class ObjCProtoName : public Node {
0603 const Node *Ty;
0604 std::string_view Protocol;
0605
0606 friend class PointerType;
0607
0608 public:
0609 ObjCProtoName(const Node *Ty_, std::string_view Protocol_)
0610 : Node(KObjCProtoName), Ty(Ty_), Protocol(Protocol_) {}
0611
0612 template<typename Fn> void match(Fn F) const { F(Ty, Protocol); }
0613
0614 bool isObjCObject() const {
0615 return Ty->getKind() == KNameType &&
0616 static_cast<const NameType *>(Ty)->getName() == "objc_object";
0617 }
0618
0619 void printLeft(OutputBuffer &OB) const override {
0620 Ty->print(OB);
0621 OB += "<";
0622 OB += Protocol;
0623 OB += ">";
0624 }
0625 };
0626
0627 class PointerType final : public Node {
0628 const Node *Pointee;
0629
0630 public:
0631 PointerType(const Node *Pointee_)
0632 : Node(KPointerType, Pointee_->getRHSComponentCache()),
0633 Pointee(Pointee_) {}
0634
0635 const Node *getPointee() const { return Pointee; }
0636
0637 template<typename Fn> void match(Fn F) const { F(Pointee); }
0638
0639 bool hasRHSComponentSlow(OutputBuffer &OB) const override {
0640 return Pointee->hasRHSComponent(OB);
0641 }
0642
0643 void printLeft(OutputBuffer &OB) const override {
0644
0645 if (Pointee->getKind() != KObjCProtoName ||
0646 !static_cast<const ObjCProtoName *>(Pointee)->isObjCObject()) {
0647 Pointee->printLeft(OB);
0648 if (Pointee->hasArray(OB))
0649 OB += " ";
0650 if (Pointee->hasArray(OB) || Pointee->hasFunction(OB))
0651 OB += "(";
0652 OB += "*";
0653 } else {
0654 const auto *objcProto = static_cast<const ObjCProtoName *>(Pointee);
0655 OB += "id<";
0656 OB += objcProto->Protocol;
0657 OB += ">";
0658 }
0659 }
0660
0661 void printRight(OutputBuffer &OB) const override {
0662 if (Pointee->getKind() != KObjCProtoName ||
0663 !static_cast<const ObjCProtoName *>(Pointee)->isObjCObject()) {
0664 if (Pointee->hasArray(OB) || Pointee->hasFunction(OB))
0665 OB += ")";
0666 Pointee->printRight(OB);
0667 }
0668 }
0669 };
0670
0671 enum class ReferenceKind {
0672 LValue,
0673 RValue,
0674 };
0675
0676
0677 class ReferenceType : public Node {
0678 const Node *Pointee;
0679 ReferenceKind RK;
0680
0681 mutable bool Printing = false;
0682
0683
0684
0685
0686
0687
0688
0689
0690 std::pair<ReferenceKind, const Node *> collapse(OutputBuffer &OB) const {
0691 auto SoFar = std::make_pair(RK, Pointee);
0692
0693
0694 PODSmallVector<const Node *, 8> Prev;
0695 for (;;) {
0696 const Node *SN = SoFar.second->getSyntaxNode(OB);
0697 if (SN->getKind() != KReferenceType)
0698 break;
0699 auto *RT = static_cast<const ReferenceType *>(SN);
0700 SoFar.second = RT->Pointee;
0701 SoFar.first = std::min(SoFar.first, RT->RK);
0702
0703
0704 Prev.push_back(SoFar.second);
0705 if (Prev.size() > 1 && SoFar.second == Prev[(Prev.size() - 1) / 2]) {
0706
0707 SoFar.second = nullptr;
0708 break;
0709 }
0710 }
0711 return SoFar;
0712 }
0713
0714 public:
0715 ReferenceType(const Node *Pointee_, ReferenceKind RK_)
0716 : Node(KReferenceType, Pointee_->getRHSComponentCache()),
0717 Pointee(Pointee_), RK(RK_) {}
0718
0719 template<typename Fn> void match(Fn F) const { F(Pointee, RK); }
0720
0721 bool hasRHSComponentSlow(OutputBuffer &OB) const override {
0722 return Pointee->hasRHSComponent(OB);
0723 }
0724
0725 void printLeft(OutputBuffer &OB) const override {
0726 if (Printing)
0727 return;
0728 ScopedOverride<bool> SavePrinting(Printing, true);
0729 std::pair<ReferenceKind, const Node *> Collapsed = collapse(OB);
0730 if (!Collapsed.second)
0731 return;
0732 Collapsed.second->printLeft(OB);
0733 if (Collapsed.second->hasArray(OB))
0734 OB += " ";
0735 if (Collapsed.second->hasArray(OB) || Collapsed.second->hasFunction(OB))
0736 OB += "(";
0737
0738 OB += (Collapsed.first == ReferenceKind::LValue ? "&" : "&&");
0739 }
0740 void printRight(OutputBuffer &OB) const override {
0741 if (Printing)
0742 return;
0743 ScopedOverride<bool> SavePrinting(Printing, true);
0744 std::pair<ReferenceKind, const Node *> Collapsed = collapse(OB);
0745 if (!Collapsed.second)
0746 return;
0747 if (Collapsed.second->hasArray(OB) || Collapsed.second->hasFunction(OB))
0748 OB += ")";
0749 Collapsed.second->printRight(OB);
0750 }
0751 };
0752
0753 class PointerToMemberType final : public Node {
0754 const Node *ClassType;
0755 const Node *MemberType;
0756
0757 public:
0758 PointerToMemberType(const Node *ClassType_, const Node *MemberType_)
0759 : Node(KPointerToMemberType, MemberType_->getRHSComponentCache()),
0760 ClassType(ClassType_), MemberType(MemberType_) {}
0761
0762 template<typename Fn> void match(Fn F) const { F(ClassType, MemberType); }
0763
0764 bool hasRHSComponentSlow(OutputBuffer &OB) const override {
0765 return MemberType->hasRHSComponent(OB);
0766 }
0767
0768 void printLeft(OutputBuffer &OB) const override {
0769 MemberType->printLeft(OB);
0770 if (MemberType->hasArray(OB) || MemberType->hasFunction(OB))
0771 OB += "(";
0772 else
0773 OB += " ";
0774 ClassType->print(OB);
0775 OB += "::*";
0776 }
0777
0778 void printRight(OutputBuffer &OB) const override {
0779 if (MemberType->hasArray(OB) || MemberType->hasFunction(OB))
0780 OB += ")";
0781 MemberType->printRight(OB);
0782 }
0783 };
0784
0785 class ArrayType final : public Node {
0786 const Node *Base;
0787 Node *Dimension;
0788
0789 public:
0790 ArrayType(const Node *Base_, Node *Dimension_)
0791 : Node(KArrayType,
0792 Cache::Yes,
0793 Cache::Yes),
0794 Base(Base_), Dimension(Dimension_) {}
0795
0796 template<typename Fn> void match(Fn F) const { F(Base, Dimension); }
0797
0798 bool hasRHSComponentSlow(OutputBuffer &) const override { return true; }
0799 bool hasArraySlow(OutputBuffer &) const override { return true; }
0800
0801 void printLeft(OutputBuffer &OB) const override { Base->printLeft(OB); }
0802
0803 void printRight(OutputBuffer &OB) const override {
0804 if (OB.back() != ']')
0805 OB += " ";
0806 OB += "[";
0807 if (Dimension)
0808 Dimension->print(OB);
0809 OB += "]";
0810 Base->printRight(OB);
0811 }
0812
0813 bool printInitListAsType(OutputBuffer &OB,
0814 const NodeArray &Elements) const override {
0815 if (Base->getKind() == KNameType &&
0816 static_cast<const NameType *>(Base)->getName() == "char") {
0817 return Elements.printAsString(OB);
0818 }
0819 return false;
0820 }
0821 };
0822
0823 class FunctionType final : public Node {
0824 const Node *Ret;
0825 NodeArray Params;
0826 Qualifiers CVQuals;
0827 FunctionRefQual RefQual;
0828 const Node *ExceptionSpec;
0829
0830 public:
0831 FunctionType(const Node *Ret_, NodeArray Params_, Qualifiers CVQuals_,
0832 FunctionRefQual RefQual_, const Node *ExceptionSpec_)
0833 : Node(KFunctionType,
0834 Cache::Yes, Cache::No,
0835 Cache::Yes),
0836 Ret(Ret_), Params(Params_), CVQuals(CVQuals_), RefQual(RefQual_),
0837 ExceptionSpec(ExceptionSpec_) {}
0838
0839 template<typename Fn> void match(Fn F) const {
0840 F(Ret, Params, CVQuals, RefQual, ExceptionSpec);
0841 }
0842
0843 bool hasRHSComponentSlow(OutputBuffer &) const override { return true; }
0844 bool hasFunctionSlow(OutputBuffer &) const override { return true; }
0845
0846
0847
0848
0849
0850
0851
0852
0853 void printLeft(OutputBuffer &OB) const override {
0854 Ret->printLeft(OB);
0855 OB += " ";
0856 }
0857
0858 void printRight(OutputBuffer &OB) const override {
0859 OB.printOpen();
0860 Params.printWithComma(OB);
0861 OB.printClose();
0862 Ret->printRight(OB);
0863
0864 if (CVQuals & QualConst)
0865 OB += " const";
0866 if (CVQuals & QualVolatile)
0867 OB += " volatile";
0868 if (CVQuals & QualRestrict)
0869 OB += " restrict";
0870
0871 if (RefQual == FrefQualLValue)
0872 OB += " &";
0873 else if (RefQual == FrefQualRValue)
0874 OB += " &&";
0875
0876 if (ExceptionSpec != nullptr) {
0877 OB += ' ';
0878 ExceptionSpec->print(OB);
0879 }
0880 }
0881 };
0882
0883 class NoexceptSpec : public Node {
0884 const Node *E;
0885 public:
0886 NoexceptSpec(const Node *E_) : Node(KNoexceptSpec), E(E_) {}
0887
0888 template<typename Fn> void match(Fn F) const { F(E); }
0889
0890 void printLeft(OutputBuffer &OB) const override {
0891 OB += "noexcept";
0892 OB.printOpen();
0893 E->printAsOperand(OB);
0894 OB.printClose();
0895 }
0896 };
0897
0898 class DynamicExceptionSpec : public Node {
0899 NodeArray Types;
0900 public:
0901 DynamicExceptionSpec(NodeArray Types_)
0902 : Node(KDynamicExceptionSpec), Types(Types_) {}
0903
0904 template<typename Fn> void match(Fn F) const { F(Types); }
0905
0906 void printLeft(OutputBuffer &OB) const override {
0907 OB += "throw";
0908 OB.printOpen();
0909 Types.printWithComma(OB);
0910 OB.printClose();
0911 }
0912 };
0913
0914
0915
0916
0917
0918
0919
0920
0921 class ExplicitObjectParameter final : public Node {
0922 Node *Base;
0923
0924 public:
0925 ExplicitObjectParameter(Node *Base_)
0926 : Node(KExplicitObjectParameter), Base(Base_) {
0927 DEMANGLE_ASSERT(
0928 Base != nullptr,
0929 "Creating an ExplicitObjectParameter without a valid Base Node.");
0930 }
0931
0932 template <typename Fn> void match(Fn F) const { F(Base); }
0933
0934 void printLeft(OutputBuffer &OB) const override {
0935 OB += "this ";
0936 Base->print(OB);
0937 }
0938 };
0939
0940 class FunctionEncoding final : public Node {
0941 const Node *Ret;
0942 const Node *Name;
0943 NodeArray Params;
0944 const Node *Attrs;
0945 const Node *Requires;
0946 Qualifiers CVQuals;
0947 FunctionRefQual RefQual;
0948
0949 public:
0950 FunctionEncoding(const Node *Ret_, const Node *Name_, NodeArray Params_,
0951 const Node *Attrs_, const Node *Requires_,
0952 Qualifiers CVQuals_, FunctionRefQual RefQual_)
0953 : Node(KFunctionEncoding,
0954 Cache::Yes, Cache::No,
0955 Cache::Yes),
0956 Ret(Ret_), Name(Name_), Params(Params_), Attrs(Attrs_),
0957 Requires(Requires_), CVQuals(CVQuals_), RefQual(RefQual_) {}
0958
0959 template<typename Fn> void match(Fn F) const {
0960 F(Ret, Name, Params, Attrs, Requires, CVQuals, RefQual);
0961 }
0962
0963 Qualifiers getCVQuals() const { return CVQuals; }
0964 FunctionRefQual getRefQual() const { return RefQual; }
0965 NodeArray getParams() const { return Params; }
0966 const Node *getReturnType() const { return Ret; }
0967
0968 bool hasRHSComponentSlow(OutputBuffer &) const override { return true; }
0969 bool hasFunctionSlow(OutputBuffer &) const override { return true; }
0970
0971 const Node *getName() const { return Name; }
0972
0973 void printLeft(OutputBuffer &OB) const override {
0974 if (Ret) {
0975 Ret->printLeft(OB);
0976 if (!Ret->hasRHSComponent(OB))
0977 OB += " ";
0978 }
0979 Name->print(OB);
0980 }
0981
0982 void printRight(OutputBuffer &OB) const override {
0983 OB.printOpen();
0984 Params.printWithComma(OB);
0985 OB.printClose();
0986 if (Ret)
0987 Ret->printRight(OB);
0988
0989 if (CVQuals & QualConst)
0990 OB += " const";
0991 if (CVQuals & QualVolatile)
0992 OB += " volatile";
0993 if (CVQuals & QualRestrict)
0994 OB += " restrict";
0995
0996 if (RefQual == FrefQualLValue)
0997 OB += " &";
0998 else if (RefQual == FrefQualRValue)
0999 OB += " &&";
1000
1001 if (Attrs != nullptr)
1002 Attrs->print(OB);
1003
1004 if (Requires != nullptr) {
1005 OB += " requires ";
1006 Requires->print(OB);
1007 }
1008 }
1009 };
1010
1011 class LiteralOperator : public Node {
1012 const Node *OpName;
1013
1014 public:
1015 LiteralOperator(const Node *OpName_)
1016 : Node(KLiteralOperator), OpName(OpName_) {}
1017
1018 template<typename Fn> void match(Fn F) const { F(OpName); }
1019
1020 void printLeft(OutputBuffer &OB) const override {
1021 OB += "operator\"\" ";
1022 OpName->print(OB);
1023 }
1024 };
1025
1026 class SpecialName final : public Node {
1027 const std::string_view Special;
1028 const Node *Child;
1029
1030 public:
1031 SpecialName(std::string_view Special_, const Node *Child_)
1032 : Node(KSpecialName), Special(Special_), Child(Child_) {}
1033
1034 template<typename Fn> void match(Fn F) const { F(Special, Child); }
1035
1036 void printLeft(OutputBuffer &OB) const override {
1037 OB += Special;
1038 Child->print(OB);
1039 }
1040 };
1041
1042 class CtorVtableSpecialName final : public Node {
1043 const Node *FirstType;
1044 const Node *SecondType;
1045
1046 public:
1047 CtorVtableSpecialName(const Node *FirstType_, const Node *SecondType_)
1048 : Node(KCtorVtableSpecialName),
1049 FirstType(FirstType_), SecondType(SecondType_) {}
1050
1051 template<typename Fn> void match(Fn F) const { F(FirstType, SecondType); }
1052
1053 void printLeft(OutputBuffer &OB) const override {
1054 OB += "construction vtable for ";
1055 FirstType->print(OB);
1056 OB += "-in-";
1057 SecondType->print(OB);
1058 }
1059 };
1060
1061 struct NestedName : Node {
1062 Node *Qual;
1063 Node *Name;
1064
1065 NestedName(Node *Qual_, Node *Name_)
1066 : Node(KNestedName), Qual(Qual_), Name(Name_) {}
1067
1068 template<typename Fn> void match(Fn F) const { F(Qual, Name); }
1069
1070 std::string_view getBaseName() const override { return Name->getBaseName(); }
1071
1072 void printLeft(OutputBuffer &OB) const override {
1073 Qual->print(OB);
1074 OB += "::";
1075 Name->print(OB);
1076 }
1077 };
1078
1079 struct MemberLikeFriendName : Node {
1080 Node *Qual;
1081 Node *Name;
1082
1083 MemberLikeFriendName(Node *Qual_, Node *Name_)
1084 : Node(KMemberLikeFriendName), Qual(Qual_), Name(Name_) {}
1085
1086 template<typename Fn> void match(Fn F) const { F(Qual, Name); }
1087
1088 std::string_view getBaseName() const override { return Name->getBaseName(); }
1089
1090 void printLeft(OutputBuffer &OB) const override {
1091 Qual->print(OB);
1092 OB += "::friend ";
1093 Name->print(OB);
1094 }
1095 };
1096
1097 struct ModuleName : Node {
1098 ModuleName *Parent;
1099 Node *Name;
1100 bool IsPartition;
1101
1102 ModuleName(ModuleName *Parent_, Node *Name_, bool IsPartition_ = false)
1103 : Node(KModuleName), Parent(Parent_), Name(Name_),
1104 IsPartition(IsPartition_) {}
1105
1106 template <typename Fn> void match(Fn F) const {
1107 F(Parent, Name, IsPartition);
1108 }
1109
1110 void printLeft(OutputBuffer &OB) const override {
1111 if (Parent)
1112 Parent->print(OB);
1113 if (Parent || IsPartition)
1114 OB += IsPartition ? ':' : '.';
1115 Name->print(OB);
1116 }
1117 };
1118
1119 struct ModuleEntity : Node {
1120 ModuleName *Module;
1121 Node *Name;
1122
1123 ModuleEntity(ModuleName *Module_, Node *Name_)
1124 : Node(KModuleEntity), Module(Module_), Name(Name_) {}
1125
1126 template <typename Fn> void match(Fn F) const { F(Module, Name); }
1127
1128 std::string_view getBaseName() const override { return Name->getBaseName(); }
1129
1130 void printLeft(OutputBuffer &OB) const override {
1131 Name->print(OB);
1132 OB += '@';
1133 Module->print(OB);
1134 }
1135 };
1136
1137 struct LocalName : Node {
1138 Node *Encoding;
1139 Node *Entity;
1140
1141 LocalName(Node *Encoding_, Node *Entity_)
1142 : Node(KLocalName), Encoding(Encoding_), Entity(Entity_) {}
1143
1144 template<typename Fn> void match(Fn F) const { F(Encoding, Entity); }
1145
1146 void printLeft(OutputBuffer &OB) const override {
1147 Encoding->print(OB);
1148 OB += "::";
1149 Entity->print(OB);
1150 }
1151 };
1152
1153 class QualifiedName final : public Node {
1154
1155 const Node *Qualifier;
1156 const Node *Name;
1157
1158 public:
1159 QualifiedName(const Node *Qualifier_, const Node *Name_)
1160 : Node(KQualifiedName), Qualifier(Qualifier_), Name(Name_) {}
1161
1162 template<typename Fn> void match(Fn F) const { F(Qualifier, Name); }
1163
1164 std::string_view getBaseName() const override { return Name->getBaseName(); }
1165
1166 void printLeft(OutputBuffer &OB) const override {
1167 Qualifier->print(OB);
1168 OB += "::";
1169 Name->print(OB);
1170 }
1171 };
1172
1173 class VectorType final : public Node {
1174 const Node *BaseType;
1175 const Node *Dimension;
1176
1177 public:
1178 VectorType(const Node *BaseType_, const Node *Dimension_)
1179 : Node(KVectorType), BaseType(BaseType_), Dimension(Dimension_) {}
1180
1181 const Node *getBaseType() const { return BaseType; }
1182 const Node *getDimension() const { return Dimension; }
1183
1184 template<typename Fn> void match(Fn F) const { F(BaseType, Dimension); }
1185
1186 void printLeft(OutputBuffer &OB) const override {
1187 BaseType->print(OB);
1188 OB += " vector[";
1189 if (Dimension)
1190 Dimension->print(OB);
1191 OB += "]";
1192 }
1193 };
1194
1195 class PixelVectorType final : public Node {
1196 const Node *Dimension;
1197
1198 public:
1199 PixelVectorType(const Node *Dimension_)
1200 : Node(KPixelVectorType), Dimension(Dimension_) {}
1201
1202 template<typename Fn> void match(Fn F) const { F(Dimension); }
1203
1204 void printLeft(OutputBuffer &OB) const override {
1205
1206 OB += "pixel vector[";
1207 Dimension->print(OB);
1208 OB += "]";
1209 }
1210 };
1211
1212 class BinaryFPType final : public Node {
1213 const Node *Dimension;
1214
1215 public:
1216 BinaryFPType(const Node *Dimension_)
1217 : Node(KBinaryFPType), Dimension(Dimension_) {}
1218
1219 template<typename Fn> void match(Fn F) const { F(Dimension); }
1220
1221 void printLeft(OutputBuffer &OB) const override {
1222 OB += "_Float";
1223 Dimension->print(OB);
1224 }
1225 };
1226
1227 enum class TemplateParamKind { Type, NonType, Template };
1228
1229
1230
1231
1232
1233
1234
1235 class SyntheticTemplateParamName final : public Node {
1236 TemplateParamKind Kind;
1237 unsigned Index;
1238
1239 public:
1240 SyntheticTemplateParamName(TemplateParamKind Kind_, unsigned Index_)
1241 : Node(KSyntheticTemplateParamName), Kind(Kind_), Index(Index_) {}
1242
1243 template<typename Fn> void match(Fn F) const { F(Kind, Index); }
1244
1245 void printLeft(OutputBuffer &OB) const override {
1246 switch (Kind) {
1247 case TemplateParamKind::Type:
1248 OB += "$T";
1249 break;
1250 case TemplateParamKind::NonType:
1251 OB += "$N";
1252 break;
1253 case TemplateParamKind::Template:
1254 OB += "$TT";
1255 break;
1256 }
1257 if (Index > 0)
1258 OB << Index - 1;
1259 }
1260 };
1261
1262 class TemplateParamQualifiedArg final : public Node {
1263 Node *Param;
1264 Node *Arg;
1265
1266 public:
1267 TemplateParamQualifiedArg(Node *Param_, Node *Arg_)
1268 : Node(KTemplateParamQualifiedArg), Param(Param_), Arg(Arg_) {}
1269
1270 template <typename Fn> void match(Fn F) const { F(Param, Arg); }
1271
1272 Node *getArg() { return Arg; }
1273
1274 void printLeft(OutputBuffer &OB) const override {
1275
1276 Arg->print(OB);
1277 }
1278 };
1279
1280
1281 class TypeTemplateParamDecl final : public Node {
1282 Node *Name;
1283
1284 public:
1285 TypeTemplateParamDecl(Node *Name_)
1286 : Node(KTypeTemplateParamDecl, Cache::Yes), Name(Name_) {}
1287
1288 template<typename Fn> void match(Fn F) const { F(Name); }
1289
1290 void printLeft(OutputBuffer &OB) const override { OB += "typename "; }
1291
1292 void printRight(OutputBuffer &OB) const override { Name->print(OB); }
1293 };
1294
1295
1296 class ConstrainedTypeTemplateParamDecl final : public Node {
1297 Node *Constraint;
1298 Node *Name;
1299
1300 public:
1301 ConstrainedTypeTemplateParamDecl(Node *Constraint_, Node *Name_)
1302 : Node(KConstrainedTypeTemplateParamDecl, Cache::Yes),
1303 Constraint(Constraint_), Name(Name_) {}
1304
1305 template<typename Fn> void match(Fn F) const { F(Constraint, Name); }
1306
1307 void printLeft(OutputBuffer &OB) const override {
1308 Constraint->print(OB);
1309 OB += " ";
1310 }
1311
1312 void printRight(OutputBuffer &OB) const override { Name->print(OB); }
1313 };
1314
1315
1316 class NonTypeTemplateParamDecl final : public Node {
1317 Node *Name;
1318 Node *Type;
1319
1320 public:
1321 NonTypeTemplateParamDecl(Node *Name_, Node *Type_)
1322 : Node(KNonTypeTemplateParamDecl, Cache::Yes), Name(Name_), Type(Type_) {}
1323
1324 template<typename Fn> void match(Fn F) const { F(Name, Type); }
1325
1326 void printLeft(OutputBuffer &OB) const override {
1327 Type->printLeft(OB);
1328 if (!Type->hasRHSComponent(OB))
1329 OB += " ";
1330 }
1331
1332 void printRight(OutputBuffer &OB) const override {
1333 Name->print(OB);
1334 Type->printRight(OB);
1335 }
1336 };
1337
1338
1339
1340 class TemplateTemplateParamDecl final : public Node {
1341 Node *Name;
1342 NodeArray Params;
1343 Node *Requires;
1344
1345 public:
1346 TemplateTemplateParamDecl(Node *Name_, NodeArray Params_, Node *Requires_)
1347 : Node(KTemplateTemplateParamDecl, Cache::Yes), Name(Name_),
1348 Params(Params_), Requires(Requires_) {}
1349
1350 template <typename Fn> void match(Fn F) const { F(Name, Params, Requires); }
1351
1352 void printLeft(OutputBuffer &OB) const override {
1353 ScopedOverride<unsigned> LT(OB.GtIsGt, 0);
1354 OB += "template<";
1355 Params.printWithComma(OB);
1356 OB += "> typename ";
1357 }
1358
1359 void printRight(OutputBuffer &OB) const override {
1360 Name->print(OB);
1361 if (Requires != nullptr) {
1362 OB += " requires ";
1363 Requires->print(OB);
1364 }
1365 }
1366 };
1367
1368
1369 class TemplateParamPackDecl final : public Node {
1370 Node *Param;
1371
1372 public:
1373 TemplateParamPackDecl(Node *Param_)
1374 : Node(KTemplateParamPackDecl, Cache::Yes), Param(Param_) {}
1375
1376 template<typename Fn> void match(Fn F) const { F(Param); }
1377
1378 void printLeft(OutputBuffer &OB) const override {
1379 Param->printLeft(OB);
1380 OB += "...";
1381 }
1382
1383 void printRight(OutputBuffer &OB) const override { Param->printRight(OB); }
1384 };
1385
1386
1387
1388
1389
1390
1391
1392
1393
1394 class ParameterPack final : public Node {
1395 NodeArray Data;
1396
1397
1398
1399 void initializePackExpansion(OutputBuffer &OB) const {
1400 if (OB.CurrentPackMax == std::numeric_limits<unsigned>::max()) {
1401 OB.CurrentPackMax = static_cast<unsigned>(Data.size());
1402 OB.CurrentPackIndex = 0;
1403 }
1404 }
1405
1406 public:
1407 ParameterPack(NodeArray Data_) : Node(KParameterPack), Data(Data_) {
1408 ArrayCache = FunctionCache = RHSComponentCache = Cache::Unknown;
1409 if (std::all_of(Data.begin(), Data.end(),
1410 [](Node *P) { return P->getArrayCache() == Cache::No; }))
1411 ArrayCache = Cache::No;
1412 if (std::all_of(Data.begin(), Data.end(),
1413 [](Node *P) { return P->getFunctionCache() == Cache::No; }))
1414 FunctionCache = Cache::No;
1415 if (std::all_of(Data.begin(), Data.end(), [](Node *P) {
1416 return P->getRHSComponentCache() == Cache::No;
1417 }))
1418 RHSComponentCache = Cache::No;
1419 }
1420
1421 template<typename Fn> void match(Fn F) const { F(Data); }
1422
1423 bool hasRHSComponentSlow(OutputBuffer &OB) const override {
1424 initializePackExpansion(OB);
1425 size_t Idx = OB.CurrentPackIndex;
1426 return Idx < Data.size() && Data[Idx]->hasRHSComponent(OB);
1427 }
1428 bool hasArraySlow(OutputBuffer &OB) const override {
1429 initializePackExpansion(OB);
1430 size_t Idx = OB.CurrentPackIndex;
1431 return Idx < Data.size() && Data[Idx]->hasArray(OB);
1432 }
1433 bool hasFunctionSlow(OutputBuffer &OB) const override {
1434 initializePackExpansion(OB);
1435 size_t Idx = OB.CurrentPackIndex;
1436 return Idx < Data.size() && Data[Idx]->hasFunction(OB);
1437 }
1438 const Node *getSyntaxNode(OutputBuffer &OB) const override {
1439 initializePackExpansion(OB);
1440 size_t Idx = OB.CurrentPackIndex;
1441 return Idx < Data.size() ? Data[Idx]->getSyntaxNode(OB) : this;
1442 }
1443
1444 void printLeft(OutputBuffer &OB) const override {
1445 initializePackExpansion(OB);
1446 size_t Idx = OB.CurrentPackIndex;
1447 if (Idx < Data.size())
1448 Data[Idx]->printLeft(OB);
1449 }
1450 void printRight(OutputBuffer &OB) const override {
1451 initializePackExpansion(OB);
1452 size_t Idx = OB.CurrentPackIndex;
1453 if (Idx < Data.size())
1454 Data[Idx]->printRight(OB);
1455 }
1456 };
1457
1458
1459
1460
1461
1462
1463 class TemplateArgumentPack final : public Node {
1464 NodeArray Elements;
1465 public:
1466 TemplateArgumentPack(NodeArray Elements_)
1467 : Node(KTemplateArgumentPack), Elements(Elements_) {}
1468
1469 template<typename Fn> void match(Fn F) const { F(Elements); }
1470
1471 NodeArray getElements() const { return Elements; }
1472
1473 void printLeft(OutputBuffer &OB) const override {
1474 Elements.printWithComma(OB);
1475 }
1476 };
1477
1478
1479
1480 class ParameterPackExpansion final : public Node {
1481 const Node *Child;
1482
1483 public:
1484 ParameterPackExpansion(const Node *Child_)
1485 : Node(KParameterPackExpansion), Child(Child_) {}
1486
1487 template<typename Fn> void match(Fn F) const { F(Child); }
1488
1489 const Node *getChild() const { return Child; }
1490
1491 void printLeft(OutputBuffer &OB) const override {
1492 constexpr unsigned Max = std::numeric_limits<unsigned>::max();
1493 ScopedOverride<unsigned> SavePackIdx(OB.CurrentPackIndex, Max);
1494 ScopedOverride<unsigned> SavePackMax(OB.CurrentPackMax, Max);
1495 size_t StreamPos = OB.getCurrentPosition();
1496
1497
1498
1499 Child->print(OB);
1500
1501
1502
1503 if (OB.CurrentPackMax == Max) {
1504 OB += "...";
1505 return;
1506 }
1507
1508
1509
1510 if (OB.CurrentPackMax == 0) {
1511 OB.setCurrentPosition(StreamPos);
1512 return;
1513 }
1514
1515
1516 for (unsigned I = 1, E = OB.CurrentPackMax; I < E; ++I) {
1517 OB += ", ";
1518 OB.CurrentPackIndex = I;
1519 Child->print(OB);
1520 }
1521 }
1522 };
1523
1524 class TemplateArgs final : public Node {
1525 NodeArray Params;
1526 Node *Requires;
1527
1528 public:
1529 TemplateArgs(NodeArray Params_, Node *Requires_)
1530 : Node(KTemplateArgs), Params(Params_), Requires(Requires_) {}
1531
1532 template<typename Fn> void match(Fn F) const { F(Params, Requires); }
1533
1534 NodeArray getParams() { return Params; }
1535
1536 void printLeft(OutputBuffer &OB) const override {
1537 ScopedOverride<unsigned> LT(OB.GtIsGt, 0);
1538 OB += "<";
1539 Params.printWithComma(OB);
1540 OB += ">";
1541
1542 }
1543 };
1544
1545
1546
1547
1548
1549
1550
1551
1552
1553
1554
1555
1556
1557
1558
1559
1560
1561
1562
1563 struct ForwardTemplateReference : Node {
1564 size_t Index;
1565 Node *Ref = nullptr;
1566
1567
1568
1569
1570
1571 mutable bool Printing = false;
1572
1573 ForwardTemplateReference(size_t Index_)
1574 : Node(KForwardTemplateReference, Cache::Unknown, Cache::Unknown,
1575 Cache::Unknown),
1576 Index(Index_) {}
1577
1578
1579
1580
1581 template<typename Fn> void match(Fn F) const = delete;
1582
1583 bool hasRHSComponentSlow(OutputBuffer &OB) const override {
1584 if (Printing)
1585 return false;
1586 ScopedOverride<bool> SavePrinting(Printing, true);
1587 return Ref->hasRHSComponent(OB);
1588 }
1589 bool hasArraySlow(OutputBuffer &OB) const override {
1590 if (Printing)
1591 return false;
1592 ScopedOverride<bool> SavePrinting(Printing, true);
1593 return Ref->hasArray(OB);
1594 }
1595 bool hasFunctionSlow(OutputBuffer &OB) const override {
1596 if (Printing)
1597 return false;
1598 ScopedOverride<bool> SavePrinting(Printing, true);
1599 return Ref->hasFunction(OB);
1600 }
1601 const Node *getSyntaxNode(OutputBuffer &OB) const override {
1602 if (Printing)
1603 return this;
1604 ScopedOverride<bool> SavePrinting(Printing, true);
1605 return Ref->getSyntaxNode(OB);
1606 }
1607
1608 void printLeft(OutputBuffer &OB) const override {
1609 if (Printing)
1610 return;
1611 ScopedOverride<bool> SavePrinting(Printing, true);
1612 Ref->printLeft(OB);
1613 }
1614 void printRight(OutputBuffer &OB) const override {
1615 if (Printing)
1616 return;
1617 ScopedOverride<bool> SavePrinting(Printing, true);
1618 Ref->printRight(OB);
1619 }
1620 };
1621
1622 struct NameWithTemplateArgs : Node {
1623
1624 Node *Name;
1625 Node *TemplateArgs;
1626
1627 NameWithTemplateArgs(Node *Name_, Node *TemplateArgs_)
1628 : Node(KNameWithTemplateArgs), Name(Name_), TemplateArgs(TemplateArgs_) {}
1629
1630 template<typename Fn> void match(Fn F) const { F(Name, TemplateArgs); }
1631
1632 std::string_view getBaseName() const override { return Name->getBaseName(); }
1633
1634 void printLeft(OutputBuffer &OB) const override {
1635 Name->print(OB);
1636 TemplateArgs->print(OB);
1637 }
1638 };
1639
1640 class GlobalQualifiedName final : public Node {
1641 Node *Child;
1642
1643 public:
1644 GlobalQualifiedName(Node* Child_)
1645 : Node(KGlobalQualifiedName), Child(Child_) {}
1646
1647 template<typename Fn> void match(Fn F) const { F(Child); }
1648
1649 std::string_view getBaseName() const override { return Child->getBaseName(); }
1650
1651 void printLeft(OutputBuffer &OB) const override {
1652 OB += "::";
1653 Child->print(OB);
1654 }
1655 };
1656
1657 enum class SpecialSubKind {
1658 allocator,
1659 basic_string,
1660 string,
1661 istream,
1662 ostream,
1663 iostream,
1664 };
1665
1666 class SpecialSubstitution;
1667 class ExpandedSpecialSubstitution : public Node {
1668 protected:
1669 SpecialSubKind SSK;
1670
1671 ExpandedSpecialSubstitution(SpecialSubKind SSK_, Kind K_)
1672 : Node(K_), SSK(SSK_) {}
1673 public:
1674 ExpandedSpecialSubstitution(SpecialSubKind SSK_)
1675 : ExpandedSpecialSubstitution(SSK_, KExpandedSpecialSubstitution) {}
1676 inline ExpandedSpecialSubstitution(SpecialSubstitution const *);
1677
1678 template<typename Fn> void match(Fn F) const { F(SSK); }
1679
1680 protected:
1681 bool isInstantiation() const {
1682 return unsigned(SSK) >= unsigned(SpecialSubKind::string);
1683 }
1684
1685 std::string_view getBaseName() const override {
1686 switch (SSK) {
1687 case SpecialSubKind::allocator:
1688 return {"allocator"};
1689 case SpecialSubKind::basic_string:
1690 return {"basic_string"};
1691 case SpecialSubKind::string:
1692 return {"basic_string"};
1693 case SpecialSubKind::istream:
1694 return {"basic_istream"};
1695 case SpecialSubKind::ostream:
1696 return {"basic_ostream"};
1697 case SpecialSubKind::iostream:
1698 return {"basic_iostream"};
1699 }
1700 DEMANGLE_UNREACHABLE;
1701 }
1702
1703 private:
1704 void printLeft(OutputBuffer &OB) const override {
1705 OB << "std::" << getBaseName();
1706 if (isInstantiation()) {
1707 OB << "<char, std::char_traits<char>";
1708 if (SSK == SpecialSubKind::string)
1709 OB << ", std::allocator<char>";
1710 OB << ">";
1711 }
1712 }
1713 };
1714
1715 class SpecialSubstitution final : public ExpandedSpecialSubstitution {
1716 public:
1717 SpecialSubstitution(SpecialSubKind SSK_)
1718 : ExpandedSpecialSubstitution(SSK_, KSpecialSubstitution) {}
1719
1720 template<typename Fn> void match(Fn F) const { F(SSK); }
1721
1722 std::string_view getBaseName() const override {
1723 std::string_view SV = ExpandedSpecialSubstitution::getBaseName();
1724 if (isInstantiation()) {
1725
1726 DEMANGLE_ASSERT(starts_with(SV, "basic_"), "");
1727 SV.remove_prefix(sizeof("basic_") - 1);
1728 }
1729 return SV;
1730 }
1731
1732 void printLeft(OutputBuffer &OB) const override {
1733 OB << "std::" << getBaseName();
1734 }
1735 };
1736
1737 inline ExpandedSpecialSubstitution::ExpandedSpecialSubstitution(
1738 SpecialSubstitution const *SS)
1739 : ExpandedSpecialSubstitution(SS->SSK) {}
1740
1741 class CtorDtorName final : public Node {
1742 const Node *Basename;
1743 const bool IsDtor;
1744 const int Variant;
1745
1746 public:
1747 CtorDtorName(const Node *Basename_, bool IsDtor_, int Variant_)
1748 : Node(KCtorDtorName), Basename(Basename_), IsDtor(IsDtor_),
1749 Variant(Variant_) {}
1750
1751 template<typename Fn> void match(Fn F) const { F(Basename, IsDtor, Variant); }
1752
1753 void printLeft(OutputBuffer &OB) const override {
1754 if (IsDtor)
1755 OB += "~";
1756 OB += Basename->getBaseName();
1757 }
1758 };
1759
1760 class DtorName : public Node {
1761 const Node *Base;
1762
1763 public:
1764 DtorName(const Node *Base_) : Node(KDtorName), Base(Base_) {}
1765
1766 template<typename Fn> void match(Fn F) const { F(Base); }
1767
1768 void printLeft(OutputBuffer &OB) const override {
1769 OB += "~";
1770 Base->printLeft(OB);
1771 }
1772 };
1773
1774 class UnnamedTypeName : public Node {
1775 const std::string_view Count;
1776
1777 public:
1778 UnnamedTypeName(std::string_view Count_)
1779 : Node(KUnnamedTypeName), Count(Count_) {}
1780
1781 template<typename Fn> void match(Fn F) const { F(Count); }
1782
1783 void printLeft(OutputBuffer &OB) const override {
1784 OB += "'unnamed";
1785 OB += Count;
1786 OB += "\'";
1787 }
1788 };
1789
1790 class ClosureTypeName : public Node {
1791 NodeArray TemplateParams;
1792 const Node *Requires1;
1793 NodeArray Params;
1794 const Node *Requires2;
1795 std::string_view Count;
1796
1797 public:
1798 ClosureTypeName(NodeArray TemplateParams_, const Node *Requires1_,
1799 NodeArray Params_, const Node *Requires2_,
1800 std::string_view Count_)
1801 : Node(KClosureTypeName), TemplateParams(TemplateParams_),
1802 Requires1(Requires1_), Params(Params_), Requires2(Requires2_),
1803 Count(Count_) {}
1804
1805 template<typename Fn> void match(Fn F) const {
1806 F(TemplateParams, Requires1, Params, Requires2, Count);
1807 }
1808
1809 void printDeclarator(OutputBuffer &OB) const {
1810 if (!TemplateParams.empty()) {
1811 ScopedOverride<unsigned> LT(OB.GtIsGt, 0);
1812 OB += "<";
1813 TemplateParams.printWithComma(OB);
1814 OB += ">";
1815 }
1816 if (Requires1 != nullptr) {
1817 OB += " requires ";
1818 Requires1->print(OB);
1819 OB += " ";
1820 }
1821 OB.printOpen();
1822 Params.printWithComma(OB);
1823 OB.printClose();
1824 if (Requires2 != nullptr) {
1825 OB += " requires ";
1826 Requires2->print(OB);
1827 }
1828 }
1829
1830 void printLeft(OutputBuffer &OB) const override {
1831
1832 OB += "\'lambda";
1833 OB += Count;
1834 OB += "\'";
1835 printDeclarator(OB);
1836 }
1837 };
1838
1839 class StructuredBindingName : public Node {
1840 NodeArray Bindings;
1841 public:
1842 StructuredBindingName(NodeArray Bindings_)
1843 : Node(KStructuredBindingName), Bindings(Bindings_) {}
1844
1845 template<typename Fn> void match(Fn F) const { F(Bindings); }
1846
1847 void printLeft(OutputBuffer &OB) const override {
1848 OB.printOpen('[');
1849 Bindings.printWithComma(OB);
1850 OB.printClose(']');
1851 }
1852 };
1853
1854
1855
1856 class BinaryExpr : public Node {
1857 const Node *LHS;
1858 const std::string_view InfixOperator;
1859 const Node *RHS;
1860
1861 public:
1862 BinaryExpr(const Node *LHS_, std::string_view InfixOperator_,
1863 const Node *RHS_, Prec Prec_)
1864 : Node(KBinaryExpr, Prec_), LHS(LHS_), InfixOperator(InfixOperator_),
1865 RHS(RHS_) {}
1866
1867 template <typename Fn> void match(Fn F) const {
1868 F(LHS, InfixOperator, RHS, getPrecedence());
1869 }
1870
1871 void printLeft(OutputBuffer &OB) const override {
1872 bool ParenAll = OB.isGtInsideTemplateArgs() &&
1873 (InfixOperator == ">" || InfixOperator == ">>");
1874 if (ParenAll)
1875 OB.printOpen();
1876
1877 bool IsAssign = getPrecedence() == Prec::Assign;
1878 LHS->printAsOperand(OB, IsAssign ? Prec::OrIf : getPrecedence(), !IsAssign);
1879
1880 if (!(InfixOperator == ","))
1881 OB += " ";
1882 OB += InfixOperator;
1883 OB += " ";
1884 RHS->printAsOperand(OB, getPrecedence(), IsAssign);
1885 if (ParenAll)
1886 OB.printClose();
1887 }
1888 };
1889
1890 class ArraySubscriptExpr : public Node {
1891 const Node *Op1;
1892 const Node *Op2;
1893
1894 public:
1895 ArraySubscriptExpr(const Node *Op1_, const Node *Op2_, Prec Prec_)
1896 : Node(KArraySubscriptExpr, Prec_), Op1(Op1_), Op2(Op2_) {}
1897
1898 template <typename Fn> void match(Fn F) const {
1899 F(Op1, Op2, getPrecedence());
1900 }
1901
1902 void printLeft(OutputBuffer &OB) const override {
1903 Op1->printAsOperand(OB, getPrecedence());
1904 OB.printOpen('[');
1905 Op2->printAsOperand(OB);
1906 OB.printClose(']');
1907 }
1908 };
1909
1910 class PostfixExpr : public Node {
1911 const Node *Child;
1912 const std::string_view Operator;
1913
1914 public:
1915 PostfixExpr(const Node *Child_, std::string_view Operator_, Prec Prec_)
1916 : Node(KPostfixExpr, Prec_), Child(Child_), Operator(Operator_) {}
1917
1918 template <typename Fn> void match(Fn F) const {
1919 F(Child, Operator, getPrecedence());
1920 }
1921
1922 void printLeft(OutputBuffer &OB) const override {
1923 Child->printAsOperand(OB, getPrecedence(), true);
1924 OB += Operator;
1925 }
1926 };
1927
1928 class ConditionalExpr : public Node {
1929 const Node *Cond;
1930 const Node *Then;
1931 const Node *Else;
1932
1933 public:
1934 ConditionalExpr(const Node *Cond_, const Node *Then_, const Node *Else_,
1935 Prec Prec_)
1936 : Node(KConditionalExpr, Prec_), Cond(Cond_), Then(Then_), Else(Else_) {}
1937
1938 template <typename Fn> void match(Fn F) const {
1939 F(Cond, Then, Else, getPrecedence());
1940 }
1941
1942 void printLeft(OutputBuffer &OB) const override {
1943 Cond->printAsOperand(OB, getPrecedence());
1944 OB += " ? ";
1945 Then->printAsOperand(OB);
1946 OB += " : ";
1947 Else->printAsOperand(OB, Prec::Assign, true);
1948 }
1949 };
1950
1951 class MemberExpr : public Node {
1952 const Node *LHS;
1953 const std::string_view Kind;
1954 const Node *RHS;
1955
1956 public:
1957 MemberExpr(const Node *LHS_, std::string_view Kind_, const Node *RHS_,
1958 Prec Prec_)
1959 : Node(KMemberExpr, Prec_), LHS(LHS_), Kind(Kind_), RHS(RHS_) {}
1960
1961 template <typename Fn> void match(Fn F) const {
1962 F(LHS, Kind, RHS, getPrecedence());
1963 }
1964
1965 void printLeft(OutputBuffer &OB) const override {
1966 LHS->printAsOperand(OB, getPrecedence(), true);
1967 OB += Kind;
1968 RHS->printAsOperand(OB, getPrecedence(), false);
1969 }
1970 };
1971
1972 class SubobjectExpr : public Node {
1973 const Node *Type;
1974 const Node *SubExpr;
1975 std::string_view Offset;
1976 NodeArray UnionSelectors;
1977 bool OnePastTheEnd;
1978
1979 public:
1980 SubobjectExpr(const Node *Type_, const Node *SubExpr_,
1981 std::string_view Offset_, NodeArray UnionSelectors_,
1982 bool OnePastTheEnd_)
1983 : Node(KSubobjectExpr), Type(Type_), SubExpr(SubExpr_), Offset(Offset_),
1984 UnionSelectors(UnionSelectors_), OnePastTheEnd(OnePastTheEnd_) {}
1985
1986 template<typename Fn> void match(Fn F) const {
1987 F(Type, SubExpr, Offset, UnionSelectors, OnePastTheEnd);
1988 }
1989
1990 void printLeft(OutputBuffer &OB) const override {
1991 SubExpr->print(OB);
1992 OB += ".<";
1993 Type->print(OB);
1994 OB += " at offset ";
1995 if (Offset.empty()) {
1996 OB += "0";
1997 } else if (Offset[0] == 'n') {
1998 OB += "-";
1999 OB += std::string_view(Offset.data() + 1, Offset.size() - 1);
2000 } else {
2001 OB += Offset;
2002 }
2003 OB += ">";
2004 }
2005 };
2006
2007 class EnclosingExpr : public Node {
2008 const std::string_view Prefix;
2009 const Node *Infix;
2010 const std::string_view Postfix;
2011
2012 public:
2013 EnclosingExpr(std::string_view Prefix_, const Node *Infix_,
2014 Prec Prec_ = Prec::Primary)
2015 : Node(KEnclosingExpr, Prec_), Prefix(Prefix_), Infix(Infix_) {}
2016
2017 template <typename Fn> void match(Fn F) const {
2018 F(Prefix, Infix, getPrecedence());
2019 }
2020
2021 void printLeft(OutputBuffer &OB) const override {
2022 OB += Prefix;
2023 OB.printOpen();
2024 Infix->print(OB);
2025 OB.printClose();
2026 OB += Postfix;
2027 }
2028 };
2029
2030 class CastExpr : public Node {
2031
2032 const std::string_view CastKind;
2033 const Node *To;
2034 const Node *From;
2035
2036 public:
2037 CastExpr(std::string_view CastKind_, const Node *To_, const Node *From_,
2038 Prec Prec_)
2039 : Node(KCastExpr, Prec_), CastKind(CastKind_), To(To_), From(From_) {}
2040
2041 template <typename Fn> void match(Fn F) const {
2042 F(CastKind, To, From, getPrecedence());
2043 }
2044
2045 void printLeft(OutputBuffer &OB) const override {
2046 OB += CastKind;
2047 {
2048 ScopedOverride<unsigned> LT(OB.GtIsGt, 0);
2049 OB += "<";
2050 To->printLeft(OB);
2051 OB += ">";
2052 }
2053 OB.printOpen();
2054 From->printAsOperand(OB);
2055 OB.printClose();
2056 }
2057 };
2058
2059 class SizeofParamPackExpr : public Node {
2060 const Node *Pack;
2061
2062 public:
2063 SizeofParamPackExpr(const Node *Pack_)
2064 : Node(KSizeofParamPackExpr), Pack(Pack_) {}
2065
2066 template<typename Fn> void match(Fn F) const { F(Pack); }
2067
2068 void printLeft(OutputBuffer &OB) const override {
2069 OB += "sizeof...";
2070 OB.printOpen();
2071 ParameterPackExpansion PPE(Pack);
2072 PPE.printLeft(OB);
2073 OB.printClose();
2074 }
2075 };
2076
2077 class CallExpr : public Node {
2078 const Node *Callee;
2079 NodeArray Args;
2080 bool IsParen;
2081
2082 public:
2083 CallExpr(const Node *Callee_, NodeArray Args_, bool IsParen_, Prec Prec_)
2084 : Node(KCallExpr, Prec_), Callee(Callee_), Args(Args_),
2085 IsParen(IsParen_) {}
2086
2087 template <typename Fn> void match(Fn F) const {
2088 F(Callee, Args, IsParen, getPrecedence());
2089 }
2090
2091 void printLeft(OutputBuffer &OB) const override {
2092 if (IsParen)
2093 OB.printOpen();
2094 Callee->print(OB);
2095 if (IsParen)
2096 OB.printClose();
2097 OB.printOpen();
2098 Args.printWithComma(OB);
2099 OB.printClose();
2100 }
2101 };
2102
2103 class NewExpr : public Node {
2104
2105 NodeArray ExprList;
2106 Node *Type;
2107 NodeArray InitList;
2108 bool IsGlobal;
2109 bool IsArray;
2110 public:
2111 NewExpr(NodeArray ExprList_, Node *Type_, NodeArray InitList_, bool IsGlobal_,
2112 bool IsArray_, Prec Prec_)
2113 : Node(KNewExpr, Prec_), ExprList(ExprList_), Type(Type_),
2114 InitList(InitList_), IsGlobal(IsGlobal_), IsArray(IsArray_) {}
2115
2116 template<typename Fn> void match(Fn F) const {
2117 F(ExprList, Type, InitList, IsGlobal, IsArray, getPrecedence());
2118 }
2119
2120 void printLeft(OutputBuffer &OB) const override {
2121 if (IsGlobal)
2122 OB += "::";
2123 OB += "new";
2124 if (IsArray)
2125 OB += "[]";
2126 if (!ExprList.empty()) {
2127 OB.printOpen();
2128 ExprList.printWithComma(OB);
2129 OB.printClose();
2130 }
2131 OB += " ";
2132 Type->print(OB);
2133 if (!InitList.empty()) {
2134 OB.printOpen();
2135 InitList.printWithComma(OB);
2136 OB.printClose();
2137 }
2138 }
2139 };
2140
2141 class DeleteExpr : public Node {
2142 Node *Op;
2143 bool IsGlobal;
2144 bool IsArray;
2145
2146 public:
2147 DeleteExpr(Node *Op_, bool IsGlobal_, bool IsArray_, Prec Prec_)
2148 : Node(KDeleteExpr, Prec_), Op(Op_), IsGlobal(IsGlobal_),
2149 IsArray(IsArray_) {}
2150
2151 template <typename Fn> void match(Fn F) const {
2152 F(Op, IsGlobal, IsArray, getPrecedence());
2153 }
2154
2155 void printLeft(OutputBuffer &OB) const override {
2156 if (IsGlobal)
2157 OB += "::";
2158 OB += "delete";
2159 if (IsArray)
2160 OB += "[]";
2161 OB += ' ';
2162 Op->print(OB);
2163 }
2164 };
2165
2166 class PrefixExpr : public Node {
2167 std::string_view Prefix;
2168 Node *Child;
2169
2170 public:
2171 PrefixExpr(std::string_view Prefix_, Node *Child_, Prec Prec_)
2172 : Node(KPrefixExpr, Prec_), Prefix(Prefix_), Child(Child_) {}
2173
2174 template <typename Fn> void match(Fn F) const {
2175 F(Prefix, Child, getPrecedence());
2176 }
2177
2178 void printLeft(OutputBuffer &OB) const override {
2179 OB += Prefix;
2180 Child->printAsOperand(OB, getPrecedence());
2181 }
2182 };
2183
2184 class FunctionParam : public Node {
2185 std::string_view Number;
2186
2187 public:
2188 FunctionParam(std::string_view Number_)
2189 : Node(KFunctionParam), Number(Number_) {}
2190
2191 template<typename Fn> void match(Fn F) const { F(Number); }
2192
2193 void printLeft(OutputBuffer &OB) const override {
2194 OB += "fp";
2195 OB += Number;
2196 }
2197 };
2198
2199 class ConversionExpr : public Node {
2200 const Node *Type;
2201 NodeArray Expressions;
2202
2203 public:
2204 ConversionExpr(const Node *Type_, NodeArray Expressions_, Prec Prec_)
2205 : Node(KConversionExpr, Prec_), Type(Type_), Expressions(Expressions_) {}
2206
2207 template <typename Fn> void match(Fn F) const {
2208 F(Type, Expressions, getPrecedence());
2209 }
2210
2211 void printLeft(OutputBuffer &OB) const override {
2212 OB.printOpen();
2213 Type->print(OB);
2214 OB.printClose();
2215 OB.printOpen();
2216 Expressions.printWithComma(OB);
2217 OB.printClose();
2218 }
2219 };
2220
2221 class PointerToMemberConversionExpr : public Node {
2222 const Node *Type;
2223 const Node *SubExpr;
2224 std::string_view Offset;
2225
2226 public:
2227 PointerToMemberConversionExpr(const Node *Type_, const Node *SubExpr_,
2228 std::string_view Offset_, Prec Prec_)
2229 : Node(KPointerToMemberConversionExpr, Prec_), Type(Type_),
2230 SubExpr(SubExpr_), Offset(Offset_) {}
2231
2232 template <typename Fn> void match(Fn F) const {
2233 F(Type, SubExpr, Offset, getPrecedence());
2234 }
2235
2236 void printLeft(OutputBuffer &OB) const override {
2237 OB.printOpen();
2238 Type->print(OB);
2239 OB.printClose();
2240 OB.printOpen();
2241 SubExpr->print(OB);
2242 OB.printClose();
2243 }
2244 };
2245
2246 class InitListExpr : public Node {
2247 const Node *Ty;
2248 NodeArray Inits;
2249 public:
2250 InitListExpr(const Node *Ty_, NodeArray Inits_)
2251 : Node(KInitListExpr), Ty(Ty_), Inits(Inits_) {}
2252
2253 template<typename Fn> void match(Fn F) const { F(Ty, Inits); }
2254
2255 void printLeft(OutputBuffer &OB) const override {
2256 if (Ty) {
2257 if (Ty->printInitListAsType(OB, Inits))
2258 return;
2259 Ty->print(OB);
2260 }
2261 OB += '{';
2262 Inits.printWithComma(OB);
2263 OB += '}';
2264 }
2265 };
2266
2267 class BracedExpr : public Node {
2268 const Node *Elem;
2269 const Node *Init;
2270 bool IsArray;
2271 public:
2272 BracedExpr(const Node *Elem_, const Node *Init_, bool IsArray_)
2273 : Node(KBracedExpr), Elem(Elem_), Init(Init_), IsArray(IsArray_) {}
2274
2275 template<typename Fn> void match(Fn F) const { F(Elem, Init, IsArray); }
2276
2277 void printLeft(OutputBuffer &OB) const override {
2278 if (IsArray) {
2279 OB += '[';
2280 Elem->print(OB);
2281 OB += ']';
2282 } else {
2283 OB += '.';
2284 Elem->print(OB);
2285 }
2286 if (Init->getKind() != KBracedExpr && Init->getKind() != KBracedRangeExpr)
2287 OB += " = ";
2288 Init->print(OB);
2289 }
2290 };
2291
2292 class BracedRangeExpr : public Node {
2293 const Node *First;
2294 const Node *Last;
2295 const Node *Init;
2296 public:
2297 BracedRangeExpr(const Node *First_, const Node *Last_, const Node *Init_)
2298 : Node(KBracedRangeExpr), First(First_), Last(Last_), Init(Init_) {}
2299
2300 template<typename Fn> void match(Fn F) const { F(First, Last, Init); }
2301
2302 void printLeft(OutputBuffer &OB) const override {
2303 OB += '[';
2304 First->print(OB);
2305 OB += " ... ";
2306 Last->print(OB);
2307 OB += ']';
2308 if (Init->getKind() != KBracedExpr && Init->getKind() != KBracedRangeExpr)
2309 OB += " = ";
2310 Init->print(OB);
2311 }
2312 };
2313
2314 class FoldExpr : public Node {
2315 const Node *Pack, *Init;
2316 std::string_view OperatorName;
2317 bool IsLeftFold;
2318
2319 public:
2320 FoldExpr(bool IsLeftFold_, std::string_view OperatorName_, const Node *Pack_,
2321 const Node *Init_)
2322 : Node(KFoldExpr), Pack(Pack_), Init(Init_), OperatorName(OperatorName_),
2323 IsLeftFold(IsLeftFold_) {}
2324
2325 template<typename Fn> void match(Fn F) const {
2326 F(IsLeftFold, OperatorName, Pack, Init);
2327 }
2328
2329 void printLeft(OutputBuffer &OB) const override {
2330 auto PrintPack = [&] {
2331 OB.printOpen();
2332 ParameterPackExpansion(Pack).print(OB);
2333 OB.printClose();
2334 };
2335
2336 OB.printOpen();
2337
2338
2339
2340 if (!IsLeftFold || Init != nullptr) {
2341
2342 if (IsLeftFold)
2343 Init->printAsOperand(OB, Prec::Cast, true);
2344 else
2345 PrintPack();
2346 OB << " " << OperatorName << " ";
2347 }
2348 OB << "...";
2349 if (IsLeftFold || Init != nullptr) {
2350
2351 OB << " " << OperatorName << " ";
2352 if (IsLeftFold)
2353 PrintPack();
2354 else
2355 Init->printAsOperand(OB, Prec::Cast, true);
2356 }
2357 OB.printClose();
2358 }
2359 };
2360
2361 class ThrowExpr : public Node {
2362 const Node *Op;
2363
2364 public:
2365 ThrowExpr(const Node *Op_) : Node(KThrowExpr), Op(Op_) {}
2366
2367 template<typename Fn> void match(Fn F) const { F(Op); }
2368
2369 void printLeft(OutputBuffer &OB) const override {
2370 OB += "throw ";
2371 Op->print(OB);
2372 }
2373 };
2374
2375 class BoolExpr : public Node {
2376 bool Value;
2377
2378 public:
2379 BoolExpr(bool Value_) : Node(KBoolExpr), Value(Value_) {}
2380
2381 template<typename Fn> void match(Fn F) const { F(Value); }
2382
2383 void printLeft(OutputBuffer &OB) const override {
2384 OB += Value ? std::string_view("true") : std::string_view("false");
2385 }
2386 };
2387
2388 class StringLiteral : public Node {
2389 const Node *Type;
2390
2391 public:
2392 StringLiteral(const Node *Type_) : Node(KStringLiteral), Type(Type_) {}
2393
2394 template<typename Fn> void match(Fn F) const { F(Type); }
2395
2396 void printLeft(OutputBuffer &OB) const override {
2397 OB += "\"<";
2398 Type->print(OB);
2399 OB += ">\"";
2400 }
2401 };
2402
2403 class LambdaExpr : public Node {
2404 const Node *Type;
2405
2406 public:
2407 LambdaExpr(const Node *Type_) : Node(KLambdaExpr), Type(Type_) {}
2408
2409 template<typename Fn> void match(Fn F) const { F(Type); }
2410
2411 void printLeft(OutputBuffer &OB) const override {
2412 OB += "[]";
2413 if (Type->getKind() == KClosureTypeName)
2414 static_cast<const ClosureTypeName *>(Type)->printDeclarator(OB);
2415 OB += "{...}";
2416 }
2417 };
2418
2419 class EnumLiteral : public Node {
2420
2421 const Node *Ty;
2422 std::string_view Integer;
2423
2424 public:
2425 EnumLiteral(const Node *Ty_, std::string_view Integer_)
2426 : Node(KEnumLiteral), Ty(Ty_), Integer(Integer_) {}
2427
2428 template<typename Fn> void match(Fn F) const { F(Ty, Integer); }
2429
2430 void printLeft(OutputBuffer &OB) const override {
2431 OB.printOpen();
2432 Ty->print(OB);
2433 OB.printClose();
2434
2435 if (Integer[0] == 'n')
2436 OB << '-' << std::string_view(Integer.data() + 1, Integer.size() - 1);
2437 else
2438 OB << Integer;
2439 }
2440 };
2441
2442 class IntegerLiteral : public Node {
2443 std::string_view Type;
2444 std::string_view Value;
2445
2446 public:
2447 IntegerLiteral(std::string_view Type_, std::string_view Value_)
2448 : Node(KIntegerLiteral), Type(Type_), Value(Value_) {}
2449
2450 template<typename Fn> void match(Fn F) const { F(Type, Value); }
2451
2452 void printLeft(OutputBuffer &OB) const override {
2453 if (Type.size() > 3) {
2454 OB.printOpen();
2455 OB += Type;
2456 OB.printClose();
2457 }
2458
2459 if (Value[0] == 'n')
2460 OB << '-' << std::string_view(Value.data() + 1, Value.size() - 1);
2461 else
2462 OB += Value;
2463
2464 if (Type.size() <= 3)
2465 OB += Type;
2466 }
2467
2468 std::string_view value() const { return Value; }
2469 };
2470
2471 class RequiresExpr : public Node {
2472 NodeArray Parameters;
2473 NodeArray Requirements;
2474 public:
2475 RequiresExpr(NodeArray Parameters_, NodeArray Requirements_)
2476 : Node(KRequiresExpr), Parameters(Parameters_),
2477 Requirements(Requirements_) {}
2478
2479 template<typename Fn> void match(Fn F) const { F(Parameters, Requirements); }
2480
2481 void printLeft(OutputBuffer &OB) const override {
2482 OB += "requires";
2483 if (!Parameters.empty()) {
2484 OB += ' ';
2485 OB.printOpen();
2486 Parameters.printWithComma(OB);
2487 OB.printClose();
2488 }
2489 OB += ' ';
2490 OB.printOpen('{');
2491 for (const Node *Req : Requirements) {
2492 Req->print(OB);
2493 }
2494 OB += ' ';
2495 OB.printClose('}');
2496 }
2497 };
2498
2499 class ExprRequirement : public Node {
2500 const Node *Expr;
2501 bool IsNoexcept;
2502 const Node *TypeConstraint;
2503 public:
2504 ExprRequirement(const Node *Expr_, bool IsNoexcept_,
2505 const Node *TypeConstraint_)
2506 : Node(KExprRequirement), Expr(Expr_), IsNoexcept(IsNoexcept_),
2507 TypeConstraint(TypeConstraint_) {}
2508
2509 template <typename Fn> void match(Fn F) const {
2510 F(Expr, IsNoexcept, TypeConstraint);
2511 }
2512
2513 void printLeft(OutputBuffer &OB) const override {
2514 OB += " ";
2515 if (IsNoexcept || TypeConstraint)
2516 OB.printOpen('{');
2517 Expr->print(OB);
2518 if (IsNoexcept || TypeConstraint)
2519 OB.printClose('}');
2520 if (IsNoexcept)
2521 OB += " noexcept";
2522 if (TypeConstraint) {
2523 OB += " -> ";
2524 TypeConstraint->print(OB);
2525 }
2526 OB += ';';
2527 }
2528 };
2529
2530 class TypeRequirement : public Node {
2531 const Node *Type;
2532 public:
2533 TypeRequirement(const Node *Type_)
2534 : Node(KTypeRequirement), Type(Type_) {}
2535
2536 template <typename Fn> void match(Fn F) const { F(Type); }
2537
2538 void printLeft(OutputBuffer &OB) const override {
2539 OB += " typename ";
2540 Type->print(OB);
2541 OB += ';';
2542 }
2543 };
2544
2545 class NestedRequirement : public Node {
2546 const Node *Constraint;
2547 public:
2548 NestedRequirement(const Node *Constraint_)
2549 : Node(KNestedRequirement), Constraint(Constraint_) {}
2550
2551 template <typename Fn> void match(Fn F) const { F(Constraint); }
2552
2553 void printLeft(OutputBuffer &OB) const override {
2554 OB += " requires ";
2555 Constraint->print(OB);
2556 OB += ';';
2557 }
2558 };
2559
2560 template <class Float> struct FloatData;
2561
2562 namespace float_literal_impl {
2563 constexpr Node::Kind getFloatLiteralKind(float *) {
2564 return Node::KFloatLiteral;
2565 }
2566 constexpr Node::Kind getFloatLiteralKind(double *) {
2567 return Node::KDoubleLiteral;
2568 }
2569 constexpr Node::Kind getFloatLiteralKind(long double *) {
2570 return Node::KLongDoubleLiteral;
2571 }
2572 }
2573
2574 template <class Float> class FloatLiteralImpl : public Node {
2575 const std::string_view Contents;
2576
2577 static constexpr Kind KindForClass =
2578 float_literal_impl::getFloatLiteralKind((Float *)nullptr);
2579
2580 public:
2581 FloatLiteralImpl(std::string_view Contents_)
2582 : Node(KindForClass), Contents(Contents_) {}
2583
2584 template<typename Fn> void match(Fn F) const { F(Contents); }
2585
2586 void printLeft(OutputBuffer &OB) const override {
2587 const size_t N = FloatData<Float>::mangled_size;
2588 if (Contents.size() >= N) {
2589 union {
2590 Float value;
2591 char buf[sizeof(Float)];
2592 };
2593 const char *t = Contents.data();
2594 const char *last = t + N;
2595 char *e = buf;
2596 for (; t != last; ++t, ++e) {
2597 unsigned d1 = isdigit(*t) ? static_cast<unsigned>(*t - '0')
2598 : static_cast<unsigned>(*t - 'a' + 10);
2599 ++t;
2600 unsigned d0 = isdigit(*t) ? static_cast<unsigned>(*t - '0')
2601 : static_cast<unsigned>(*t - 'a' + 10);
2602 *e = static_cast<char>((d1 << 4) + d0);
2603 }
2604 #if __BYTE_ORDER__ == __ORDER_LITTLE_ENDIAN__
2605 std::reverse(buf, e);
2606 #endif
2607 char num[FloatData<Float>::max_demangled_size] = {0};
2608 int n = snprintf(num, sizeof(num), FloatData<Float>::spec, value);
2609 OB += std::string_view(num, n);
2610 }
2611 }
2612 };
2613
2614 using FloatLiteral = FloatLiteralImpl<float>;
2615 using DoubleLiteral = FloatLiteralImpl<double>;
2616 using LongDoubleLiteral = FloatLiteralImpl<long double>;
2617
2618
2619
2620 template<typename Fn>
2621 void Node::visit(Fn F) const {
2622 switch (K) {
2623 #define NODE(X) \
2624 case K##X: \
2625 return F(static_cast<const X *>(this));
2626 #include "ItaniumNodes.def"
2627 }
2628 DEMANGLE_ASSERT(0, "unknown mangling node kind");
2629 }
2630
2631
2632 template<typename NodeT> struct NodeKind;
2633 #define NODE(X) \
2634 template <> struct NodeKind<X> { \
2635 static constexpr Node::Kind Kind = Node::K##X; \
2636 static constexpr const char *name() { return #X; } \
2637 };
2638 #include "ItaniumNodes.def"
2639
2640 inline bool NodeArray::printAsString(OutputBuffer &OB) const {
2641 auto StartPos = OB.getCurrentPosition();
2642 auto Fail = [&OB, StartPos] {
2643 OB.setCurrentPosition(StartPos);
2644 return false;
2645 };
2646
2647 OB += '"';
2648 bool LastWasNumericEscape = false;
2649 for (const Node *Element : *this) {
2650 if (Element->getKind() != Node::KIntegerLiteral)
2651 return Fail();
2652 int integer_value = 0;
2653 for (char c : static_cast<const IntegerLiteral *>(Element)->value()) {
2654 if (c < '0' || c > '9' || integer_value > 25)
2655 return Fail();
2656 integer_value *= 10;
2657 integer_value += c - '0';
2658 }
2659 if (integer_value > 255)
2660 return Fail();
2661
2662
2663 if (LastWasNumericEscape) {
2664 if ((integer_value >= '0' && integer_value <= '9') ||
2665 (integer_value >= 'a' && integer_value <= 'f') ||
2666 (integer_value >= 'A' && integer_value <= 'F')) {
2667 OB += "\"\"";
2668 }
2669 }
2670
2671 LastWasNumericEscape = false;
2672
2673
2674 switch (integer_value) {
2675 case '\a':
2676 OB += "\\a";
2677 break;
2678 case '\b':
2679 OB += "\\b";
2680 break;
2681 case '\f':
2682 OB += "\\f";
2683 break;
2684 case '\n':
2685 OB += "\\n";
2686 break;
2687 case '\r':
2688 OB += "\\r";
2689 break;
2690 case '\t':
2691 OB += "\\t";
2692 break;
2693 case '\v':
2694 OB += "\\v";
2695 break;
2696
2697 case '"':
2698 OB += "\\\"";
2699 break;
2700 case '\\':
2701 OB += "\\\\";
2702 break;
2703
2704 default:
2705
2706
2707 if (integer_value < 32 || integer_value == 127) {
2708 constexpr char Hex[] = "0123456789ABCDEF";
2709 OB += '\\';
2710 if (integer_value > 7)
2711 OB += 'x';
2712 if (integer_value >= 16)
2713 OB += Hex[integer_value >> 4];
2714 OB += Hex[integer_value & 0xF];
2715 LastWasNumericEscape = true;
2716 break;
2717 }
2718
2719
2720 OB += (char)integer_value;
2721 break;
2722 }
2723 }
2724 OB += '"';
2725 return true;
2726 }
2727
2728 template <typename Derived, typename Alloc> struct AbstractManglingParser {
2729 const char *First;
2730 const char *Last;
2731
2732
2733
2734
2735 PODSmallVector<Node *, 32> Names;
2736
2737
2738
2739
2740 PODSmallVector<Node *, 32> Subs;
2741
2742
2743
2744 using TemplateParamList = PODSmallVector<Node *, 8>;
2745
2746 class ScopedTemplateParamList {
2747 AbstractManglingParser *Parser;
2748 size_t OldNumTemplateParamLists;
2749 TemplateParamList Params;
2750
2751 public:
2752 ScopedTemplateParamList(AbstractManglingParser *TheParser)
2753 : Parser(TheParser),
2754 OldNumTemplateParamLists(TheParser->TemplateParams.size()) {
2755 Parser->TemplateParams.push_back(&Params);
2756 }
2757 ~ScopedTemplateParamList() {
2758 DEMANGLE_ASSERT(Parser->TemplateParams.size() >= OldNumTemplateParamLists,
2759 "");
2760 Parser->TemplateParams.shrinkToSize(OldNumTemplateParamLists);
2761 }
2762 TemplateParamList *params() { return &Params; }
2763 };
2764
2765
2766
2767
2768 TemplateParamList OuterTemplateParams;
2769
2770
2771
2772
2773
2774
2775 PODSmallVector<TemplateParamList *, 4> TemplateParams;
2776
2777 class SaveTemplateParams {
2778 AbstractManglingParser *Parser;
2779 decltype(TemplateParams) OldParams;
2780 decltype(OuterTemplateParams) OldOuterParams;
2781
2782 public:
2783 SaveTemplateParams(AbstractManglingParser *TheParser) : Parser(TheParser) {
2784 OldParams = std::move(Parser->TemplateParams);
2785 OldOuterParams = std::move(Parser->OuterTemplateParams);
2786 Parser->TemplateParams.clear();
2787 Parser->OuterTemplateParams.clear();
2788 }
2789 ~SaveTemplateParams() {
2790 Parser->TemplateParams = std::move(OldParams);
2791 Parser->OuterTemplateParams = std::move(OldOuterParams);
2792 }
2793 };
2794
2795
2796
2797 PODSmallVector<ForwardTemplateReference *, 4> ForwardTemplateRefs;
2798
2799 bool TryToParseTemplateArgs = true;
2800 bool PermitForwardTemplateReferences = false;
2801 bool HasIncompleteTemplateParameterTracking = false;
2802 size_t ParsingLambdaParamsAtLevel = (size_t)-1;
2803
2804 unsigned NumSyntheticTemplateParameters[3] = {};
2805
2806 Alloc ASTAllocator;
2807
2808 AbstractManglingParser(const char *First_, const char *Last_)
2809 : First(First_), Last(Last_) {}
2810
2811 Derived &getDerived() { return static_cast<Derived &>(*this); }
2812
2813 void reset(const char *First_, const char *Last_) {
2814 First = First_;
2815 Last = Last_;
2816 Names.clear();
2817 Subs.clear();
2818 TemplateParams.clear();
2819 ParsingLambdaParamsAtLevel = (size_t)-1;
2820 TryToParseTemplateArgs = true;
2821 PermitForwardTemplateReferences = false;
2822 for (int I = 0; I != 3; ++I)
2823 NumSyntheticTemplateParameters[I] = 0;
2824 ASTAllocator.reset();
2825 }
2826
2827 template <class T, class... Args> Node *make(Args &&... args) {
2828 return ASTAllocator.template makeNode<T>(std::forward<Args>(args)...);
2829 }
2830
2831 template <class It> NodeArray makeNodeArray(It begin, It end) {
2832 size_t sz = static_cast<size_t>(end - begin);
2833 void *mem = ASTAllocator.allocateNodeArray(sz);
2834 Node **data = new (mem) Node *[sz];
2835 std::copy(begin, end, data);
2836 return NodeArray(data, sz);
2837 }
2838
2839 NodeArray popTrailingNodeArray(size_t FromPosition) {
2840 DEMANGLE_ASSERT(FromPosition <= Names.size(), "");
2841 NodeArray res =
2842 makeNodeArray(Names.begin() + (long)FromPosition, Names.end());
2843 Names.shrinkToSize(FromPosition);
2844 return res;
2845 }
2846
2847 bool consumeIf(std::string_view S) {
2848 if (starts_with(std::string_view(First, Last - First), S)) {
2849 First += S.size();
2850 return true;
2851 }
2852 return false;
2853 }
2854
2855 bool consumeIf(char C) {
2856 if (First != Last && *First == C) {
2857 ++First;
2858 return true;
2859 }
2860 return false;
2861 }
2862
2863 char consume() { return First != Last ? *First++ : '\0'; }
2864
2865 char look(unsigned Lookahead = 0) const {
2866 if (static_cast<size_t>(Last - First) <= Lookahead)
2867 return '\0';
2868 return First[Lookahead];
2869 }
2870
2871 size_t numLeft() const { return static_cast<size_t>(Last - First); }
2872
2873 std::string_view parseNumber(bool AllowNegative = false);
2874 Qualifiers parseCVQualifiers();
2875 bool parsePositiveInteger(size_t *Out);
2876 std::string_view parseBareSourceName();
2877
2878 bool parseSeqId(size_t *Out);
2879 Node *parseSubstitution();
2880 Node *parseTemplateParam();
2881 Node *parseTemplateParamDecl(TemplateParamList *Params);
2882 Node *parseTemplateArgs(bool TagTemplates = false);
2883 Node *parseTemplateArg();
2884
2885 bool isTemplateParamDecl() {
2886 return look() == 'T' &&
2887 std::string_view("yptnk").find(look(1)) != std::string_view::npos;
2888 }
2889
2890
2891 Node *parseExpr();
2892 Node *parsePrefixExpr(std::string_view Kind, Node::Prec Prec);
2893 Node *parseBinaryExpr(std::string_view Kind, Node::Prec Prec);
2894 Node *parseIntegerLiteral(std::string_view Lit);
2895 Node *parseExprPrimary();
2896 template <class Float> Node *parseFloatingLiteral();
2897 Node *parseFunctionParam();
2898 Node *parseConversionExpr();
2899 Node *parseBracedExpr();
2900 Node *parseFoldExpr();
2901 Node *parsePointerToMemberConversionExpr(Node::Prec Prec);
2902 Node *parseSubobjectExpr();
2903 Node *parseConstraintExpr();
2904 Node *parseRequiresExpr();
2905
2906
2907 Node *parseType();
2908 Node *parseFunctionType();
2909 Node *parseVectorType();
2910 Node *parseDecltype();
2911 Node *parseArrayType();
2912 Node *parsePointerToMemberType();
2913 Node *parseClassEnumType();
2914 Node *parseQualifiedType();
2915
2916 Node *parseEncoding(bool ParseParams = true);
2917 bool parseCallOffset();
2918 Node *parseSpecialName();
2919
2920
2921
2922 struct NameState {
2923 bool CtorDtorConversion = false;
2924 bool EndsWithTemplateArgs = false;
2925 Qualifiers CVQualifiers = QualNone;
2926 FunctionRefQual ReferenceQualifier = FrefQualNone;
2927 size_t ForwardTemplateRefsBegin;
2928 bool HasExplicitObjectParameter = false;
2929
2930 NameState(AbstractManglingParser *Enclosing)
2931 : ForwardTemplateRefsBegin(Enclosing->ForwardTemplateRefs.size()) {}
2932 };
2933
2934 bool resolveForwardTemplateRefs(NameState &State) {
2935 size_t I = State.ForwardTemplateRefsBegin;
2936 size_t E = ForwardTemplateRefs.size();
2937 for (; I < E; ++I) {
2938 size_t Idx = ForwardTemplateRefs[I]->Index;
2939 if (TemplateParams.empty() || !TemplateParams[0] ||
2940 Idx >= TemplateParams[0]->size())
2941 return true;
2942 ForwardTemplateRefs[I]->Ref = (*TemplateParams[0])[Idx];
2943 }
2944 ForwardTemplateRefs.shrinkToSize(State.ForwardTemplateRefsBegin);
2945 return false;
2946 }
2947
2948
2949 Node *parseName(NameState *State = nullptr);
2950 Node *parseLocalName(NameState *State);
2951 Node *parseOperatorName(NameState *State);
2952 bool parseModuleNameOpt(ModuleName *&Module);
2953 Node *parseUnqualifiedName(NameState *State, Node *Scope, ModuleName *Module);
2954 Node *parseUnnamedTypeName(NameState *State);
2955 Node *parseSourceName(NameState *State);
2956 Node *parseUnscopedName(NameState *State, bool *isSubstName);
2957 Node *parseNestedName(NameState *State);
2958 Node *parseCtorDtorName(Node *&SoFar, NameState *State);
2959
2960 Node *parseAbiTags(Node *N);
2961
2962 struct OperatorInfo {
2963 enum OIKind : unsigned char {
2964 Prefix,
2965 Postfix,
2966 Binary,
2967 Array,
2968 Member,
2969 New,
2970 Del,
2971 Call,
2972 CCast,
2973 Conditional,
2974 NameOnly,
2975
2976 NamedCast,
2977 OfIdOp,
2978
2979 Unnameable = NamedCast,
2980 };
2981 char Enc[2];
2982 OIKind Kind;
2983 bool Flag : 1;
2984 Node::Prec Prec : 7;
2985 const char *Name;
2986
2987 public:
2988 constexpr OperatorInfo(const char (&E)[3], OIKind K, bool F, Node::Prec P,
2989 const char *N)
2990 : Enc{E[0], E[1]}, Kind{K}, Flag{F}, Prec{P}, Name{N} {}
2991
2992 public:
2993 bool operator<(const OperatorInfo &Other) const {
2994 return *this < Other.Enc;
2995 }
2996 bool operator<(const char *Peek) const {
2997 return Enc[0] < Peek[0] || (Enc[0] == Peek[0] && Enc[1] < Peek[1]);
2998 }
2999 bool operator==(const char *Peek) const {
3000 return Enc[0] == Peek[0] && Enc[1] == Peek[1];
3001 }
3002 bool operator!=(const char *Peek) const { return !this->operator==(Peek); }
3003
3004 public:
3005 std::string_view getSymbol() const {
3006 std::string_view Res = Name;
3007 if (Kind < Unnameable) {
3008 DEMANGLE_ASSERT(starts_with(Res, "operator"),
3009 "operator name does not start with 'operator'");
3010 Res.remove_prefix(sizeof("operator") - 1);
3011 if (starts_with(Res, ' '))
3012 Res.remove_prefix(1);
3013 }
3014 return Res;
3015 }
3016 std::string_view getName() const { return Name; }
3017 OIKind getKind() const { return Kind; }
3018 bool getFlag() const { return Flag; }
3019 Node::Prec getPrecedence() const { return Prec; }
3020 };
3021 static const OperatorInfo Ops[];
3022 static const size_t NumOps;
3023 const OperatorInfo *parseOperatorEncoding();
3024
3025
3026 Node *parseUnresolvedName(bool Global);
3027 Node *parseSimpleId();
3028 Node *parseBaseUnresolvedName();
3029 Node *parseUnresolvedType();
3030 Node *parseDestructorName();
3031
3032
3033 Node *parse(bool ParseParams = true);
3034 };
3035
3036 const char* parse_discriminator(const char* first, const char* last);
3037
3038
3039
3040
3041
3042
3043
3044
3045 template <typename Derived, typename Alloc>
3046 Node *AbstractManglingParser<Derived, Alloc>::parseName(NameState *State) {
3047 if (look() == 'N')
3048 return getDerived().parseNestedName(State);
3049 if (look() == 'Z')
3050 return getDerived().parseLocalName(State);
3051
3052 Node *Result = nullptr;
3053 bool IsSubst = false;
3054
3055 Result = getDerived().parseUnscopedName(State, &IsSubst);
3056 if (!Result)
3057 return nullptr;
3058
3059 if (look() == 'I') {
3060
3061 if (!IsSubst)
3062
3063 Subs.push_back(Result);
3064 Node *TA = getDerived().parseTemplateArgs(State != nullptr);
3065 if (TA == nullptr)
3066 return nullptr;
3067 if (State)
3068 State->EndsWithTemplateArgs = true;
3069 Result = make<NameWithTemplateArgs>(Result, TA);
3070 } else if (IsSubst) {
3071
3072 return nullptr;
3073 }
3074
3075 return Result;
3076 }
3077
3078
3079
3080
3081 template <typename Derived, typename Alloc>
3082 Node *AbstractManglingParser<Derived, Alloc>::parseLocalName(NameState *State) {
3083 if (!consumeIf('Z'))
3084 return nullptr;
3085 Node *Encoding = getDerived().parseEncoding();
3086 if (Encoding == nullptr || !consumeIf('E'))
3087 return nullptr;
3088
3089 if (consumeIf('s')) {
3090 First = parse_discriminator(First, Last);
3091 auto *StringLitName = make<NameType>("string literal");
3092 if (!StringLitName)
3093 return nullptr;
3094 return make<LocalName>(Encoding, StringLitName);
3095 }
3096
3097
3098
3099 SaveTemplateParams SaveTemplateParamsScope(this);
3100
3101 if (consumeIf('d')) {
3102 parseNumber(true);
3103 if (!consumeIf('_'))
3104 return nullptr;
3105 Node *N = getDerived().parseName(State);
3106 if (N == nullptr)
3107 return nullptr;
3108 return make<LocalName>(Encoding, N);
3109 }
3110
3111 Node *Entity = getDerived().parseName(State);
3112 if (Entity == nullptr)
3113 return nullptr;
3114 First = parse_discriminator(First, Last);
3115 return make<LocalName>(Encoding, Entity);
3116 }
3117
3118
3119
3120
3121 template <typename Derived, typename Alloc>
3122 Node *
3123 AbstractManglingParser<Derived, Alloc>::parseUnscopedName(NameState *State,
3124 bool *IsSubst) {
3125
3126 Node *Std = nullptr;
3127 if (consumeIf("St")) {
3128 Std = make<NameType>("std");
3129 if (Std == nullptr)
3130 return nullptr;
3131 }
3132
3133 Node *Res = nullptr;
3134 ModuleName *Module = nullptr;
3135 if (look() == 'S') {
3136 Node *S = getDerived().parseSubstitution();
3137 if (!S)
3138 return nullptr;
3139 if (S->getKind() == Node::KModuleName)
3140 Module = static_cast<ModuleName *>(S);
3141 else if (IsSubst && Std == nullptr) {
3142 Res = S;
3143 *IsSubst = true;
3144 } else {
3145 return nullptr;
3146 }
3147 }
3148
3149 if (Res == nullptr || Std != nullptr) {
3150 Res = getDerived().parseUnqualifiedName(State, Std, Module);
3151 }
3152
3153 return Res;
3154 }
3155
3156
3157
3158
3159
3160
3161
3162 template <typename Derived, typename Alloc>
3163 Node *AbstractManglingParser<Derived, Alloc>::parseUnqualifiedName(
3164 NameState *State, Node *Scope, ModuleName *Module) {
3165 if (getDerived().parseModuleNameOpt(Module))
3166 return nullptr;
3167
3168 bool IsMemberLikeFriend = Scope && consumeIf('F');
3169
3170 consumeIf('L');
3171
3172 Node *Result;
3173 if (look() >= '1' && look() <= '9') {
3174 Result = getDerived().parseSourceName(State);
3175 } else if (look() == 'U') {
3176 Result = getDerived().parseUnnamedTypeName(State);
3177 } else if (consumeIf("DC")) {
3178
3179 size_t BindingsBegin = Names.size();
3180 do {
3181 Node *Binding = getDerived().parseSourceName(State);
3182 if (Binding == nullptr)
3183 return nullptr;
3184 Names.push_back(Binding);
3185 } while (!consumeIf('E'));
3186 Result = make<StructuredBindingName>(popTrailingNodeArray(BindingsBegin));
3187 } else if (look() == 'C' || look() == 'D') {
3188
3189 if (Scope == nullptr || Module != nullptr)
3190 return nullptr;
3191 Result = getDerived().parseCtorDtorName(Scope, State);
3192 } else {
3193 Result = getDerived().parseOperatorName(State);
3194 }
3195
3196 if (Result != nullptr && Module != nullptr)
3197 Result = make<ModuleEntity>(Module, Result);
3198 if (Result != nullptr)
3199 Result = getDerived().parseAbiTags(Result);
3200 if (Result != nullptr && IsMemberLikeFriend)
3201 Result = make<MemberLikeFriendName>(Scope, Result);
3202 else if (Result != nullptr && Scope != nullptr)
3203 Result = make<NestedName>(Scope, Result);
3204
3205 return Result;
3206 }
3207
3208
3209
3210
3211
3212
3213 template <typename Derived, typename Alloc>
3214 bool AbstractManglingParser<Derived, Alloc>::parseModuleNameOpt(
3215 ModuleName *&Module) {
3216 while (consumeIf('W')) {
3217 bool IsPartition = consumeIf('P');
3218 Node *Sub = getDerived().parseSourceName(nullptr);
3219 if (!Sub)
3220 return true;
3221 Module =
3222 static_cast<ModuleName *>(make<ModuleName>(Module, Sub, IsPartition));
3223 Subs.push_back(Module);
3224 }
3225
3226 return false;
3227 }
3228
3229
3230
3231
3232
3233
3234
3235
3236 template <typename Derived, typename Alloc>
3237 Node *
3238 AbstractManglingParser<Derived, Alloc>::parseUnnamedTypeName(NameState *State) {
3239
3240
3241 if (State != nullptr)
3242 TemplateParams.clear();
3243
3244 if (consumeIf("Ut")) {
3245 std::string_view Count = parseNumber();
3246 if (!consumeIf('_'))
3247 return nullptr;
3248 return make<UnnamedTypeName>(Count);
3249 }
3250 if (consumeIf("Ul")) {
3251 ScopedOverride<size_t> SwapParams(ParsingLambdaParamsAtLevel,
3252 TemplateParams.size());
3253 ScopedTemplateParamList LambdaTemplateParams(this);
3254
3255 size_t ParamsBegin = Names.size();
3256 while (getDerived().isTemplateParamDecl()) {
3257 Node *T =
3258 getDerived().parseTemplateParamDecl(LambdaTemplateParams.params());
3259 if (T == nullptr)
3260 return nullptr;
3261 Names.push_back(T);
3262 }
3263 NodeArray TempParams = popTrailingNodeArray(ParamsBegin);
3264
3265
3266
3267
3268
3269
3270
3271
3272
3273
3274
3275
3276
3277
3278
3279
3280
3281
3282
3283
3284
3285
3286
3287 if (TempParams.empty())
3288 TemplateParams.pop_back();
3289
3290 Node *Requires1 = nullptr;
3291 if (consumeIf('Q')) {
3292 Requires1 = getDerived().parseConstraintExpr();
3293 if (Requires1 == nullptr)
3294 return nullptr;
3295 }
3296
3297 if (!consumeIf("v")) {
3298 do {
3299 Node *P = getDerived().parseType();
3300 if (P == nullptr)
3301 return nullptr;
3302 Names.push_back(P);
3303 } while (look() != 'E' && look() != 'Q');
3304 }
3305 NodeArray Params = popTrailingNodeArray(ParamsBegin);
3306
3307 Node *Requires2 = nullptr;
3308 if (consumeIf('Q')) {
3309 Requires2 = getDerived().parseConstraintExpr();
3310 if (Requires2 == nullptr)
3311 return nullptr;
3312 }
3313
3314 if (!consumeIf('E'))
3315 return nullptr;
3316
3317 std::string_view Count = parseNumber();
3318 if (!consumeIf('_'))
3319 return nullptr;
3320 return make<ClosureTypeName>(TempParams, Requires1, Params, Requires2,
3321 Count);
3322 }
3323 if (consumeIf("Ub")) {
3324 (void)parseNumber();
3325 if (!consumeIf('_'))
3326 return nullptr;
3327 return make<NameType>("'block-literal'");
3328 }
3329 return nullptr;
3330 }
3331
3332
3333 template <typename Derived, typename Alloc>
3334 Node *AbstractManglingParser<Derived, Alloc>::parseSourceName(NameState *) {
3335 size_t Length = 0;
3336 if (parsePositiveInteger(&Length))
3337 return nullptr;
3338 if (numLeft() < Length || Length == 0)
3339 return nullptr;
3340 std::string_view Name(First, Length);
3341 First += Length;
3342 if (starts_with(Name, "_GLOBAL__N"))
3343 return make<NameType>("(anonymous namespace)");
3344 return make<NameType>(Name);
3345 }
3346
3347
3348 template <typename Derived, typename Alloc>
3349 const typename AbstractManglingParser<
3350 Derived, Alloc>::OperatorInfo AbstractManglingParser<Derived,
3351 Alloc>::Ops[] = {
3352
3353 {"aN", OperatorInfo::Binary, false, Node::Prec::Assign, "operator&="},
3354 {"aS", OperatorInfo::Binary, false, Node::Prec::Assign, "operator="},
3355 {"aa", OperatorInfo::Binary, false, Node::Prec::AndIf, "operator&&"},
3356 {"ad", OperatorInfo::Prefix, false, Node::Prec::Unary, "operator&"},
3357 {"an", OperatorInfo::Binary, false, Node::Prec::And, "operator&"},
3358 {"at", OperatorInfo::OfIdOp, true, Node::Prec::Unary, "alignof "},
3359 {"aw", OperatorInfo::NameOnly, false, Node::Prec::Primary,
3360 "operator co_await"},
3361 {"az", OperatorInfo::OfIdOp, false, Node::Prec::Unary, "alignof "},
3362 {"cc", OperatorInfo::NamedCast, false, Node::Prec::Postfix, "const_cast"},
3363 {"cl", OperatorInfo::Call, false, Node::Prec::Postfix,
3364 "operator()"},
3365 {"cm", OperatorInfo::Binary, false, Node::Prec::Comma, "operator,"},
3366 {"co", OperatorInfo::Prefix, false, Node::Prec::Unary, "operator~"},
3367 {"cp", OperatorInfo::Call, true, Node::Prec::Postfix,
3368 "operator()"},
3369 {"cv", OperatorInfo::CCast, false, Node::Prec::Cast, "operator"},
3370 {"dV", OperatorInfo::Binary, false, Node::Prec::Assign, "operator/="},
3371 {"da", OperatorInfo::Del, true, Node::Prec::Unary,
3372 "operator delete[]"},
3373 {"dc", OperatorInfo::NamedCast, false, Node::Prec::Postfix, "dynamic_cast"},
3374 {"de", OperatorInfo::Prefix, false, Node::Prec::Unary, "operator*"},
3375 {"dl", OperatorInfo::Del, false, Node::Prec::Unary,
3376 "operator delete"},
3377 {"ds", OperatorInfo::Member, false, Node::Prec::PtrMem,
3378 "operator.*"},
3379 {"dt", OperatorInfo::Member, false, Node::Prec::Postfix,
3380 "operator."},
3381 {"dv", OperatorInfo::Binary, false, Node::Prec::Assign, "operator/"},
3382 {"eO", OperatorInfo::Binary, false, Node::Prec::Assign, "operator^="},
3383 {"eo", OperatorInfo::Binary, false, Node::Prec::Xor, "operator^"},
3384 {"eq", OperatorInfo::Binary, false, Node::Prec::Equality, "operator=="},
3385 {"ge", OperatorInfo::Binary, false, Node::Prec::Relational, "operator>="},
3386 {"gt", OperatorInfo::Binary, false, Node::Prec::Relational, "operator>"},
3387 {"ix", OperatorInfo::Array, false, Node::Prec::Postfix, "operator[]"},
3388 {"lS", OperatorInfo::Binary, false, Node::Prec::Assign, "operator<<="},
3389 {"le", OperatorInfo::Binary, false, Node::Prec::Relational, "operator<="},
3390 {"ls", OperatorInfo::Binary, false, Node::Prec::Shift, "operator<<"},
3391 {"lt", OperatorInfo::Binary, false, Node::Prec::Relational, "operator<"},
3392 {"mI", OperatorInfo::Binary, false, Node::Prec::Assign, "operator-="},
3393 {"mL", OperatorInfo::Binary, false, Node::Prec::Assign, "operator*="},
3394 {"mi", OperatorInfo::Binary, false, Node::Prec::Additive, "operator-"},
3395 {"ml", OperatorInfo::Binary, false, Node::Prec::Multiplicative,
3396 "operator*"},
3397 {"mm", OperatorInfo::Postfix, false, Node::Prec::Postfix, "operator--"},
3398 {"na", OperatorInfo::New, true, Node::Prec::Unary,
3399 "operator new[]"},
3400 {"ne", OperatorInfo::Binary, false, Node::Prec::Equality, "operator!="},
3401 {"ng", OperatorInfo::Prefix, false, Node::Prec::Unary, "operator-"},
3402 {"nt", OperatorInfo::Prefix, false, Node::Prec::Unary, "operator!"},
3403 {"nw", OperatorInfo::New, false, Node::Prec::Unary, "operator new"},
3404 {"oR", OperatorInfo::Binary, false, Node::Prec::Assign, "operator|="},
3405 {"oo", OperatorInfo::Binary, false, Node::Prec::OrIf, "operator||"},
3406 {"or", OperatorInfo::Binary, false, Node::Prec::Ior, "operator|"},
3407 {"pL", OperatorInfo::Binary, false, Node::Prec::Assign, "operator+="},
3408 {"pl", OperatorInfo::Binary, false, Node::Prec::Additive, "operator+"},
3409 {"pm", OperatorInfo::Member, false, Node::Prec::PtrMem,
3410 "operator->*"},
3411 {"pp", OperatorInfo::Postfix, false, Node::Prec::Postfix, "operator++"},
3412 {"ps", OperatorInfo::Prefix, false, Node::Prec::Unary, "operator+"},
3413 {"pt", OperatorInfo::Member, true, Node::Prec::Postfix,
3414 "operator->"},
3415 {"qu", OperatorInfo::Conditional, false, Node::Prec::Conditional,
3416 "operator?"},
3417 {"rM", OperatorInfo::Binary, false, Node::Prec::Assign, "operator%="},
3418 {"rS", OperatorInfo::Binary, false, Node::Prec::Assign, "operator>>="},
3419 {"rc", OperatorInfo::NamedCast, false, Node::Prec::Postfix,
3420 "reinterpret_cast"},
3421 {"rm", OperatorInfo::Binary, false, Node::Prec::Multiplicative,
3422 "operator%"},
3423 {"rs", OperatorInfo::Binary, false, Node::Prec::Shift, "operator>>"},
3424 {"sc", OperatorInfo::NamedCast, false, Node::Prec::Postfix, "static_cast"},
3425 {"ss", OperatorInfo::Binary, false, Node::Prec::Spaceship, "operator<=>"},
3426 {"st", OperatorInfo::OfIdOp, true, Node::Prec::Unary, "sizeof "},
3427 {"sz", OperatorInfo::OfIdOp, false, Node::Prec::Unary, "sizeof "},
3428 {"te", OperatorInfo::OfIdOp, false, Node::Prec::Postfix,
3429 "typeid "},
3430 {"ti", OperatorInfo::OfIdOp, true, Node::Prec::Postfix, "typeid "},
3431 };
3432 template <typename Derived, typename Alloc>
3433 const size_t AbstractManglingParser<Derived, Alloc>::NumOps = sizeof(Ops) /
3434 sizeof(Ops[0]);
3435
3436
3437
3438 template <typename Derived, typename Alloc>
3439 const typename AbstractManglingParser<Derived, Alloc>::OperatorInfo *
3440 AbstractManglingParser<Derived, Alloc>::parseOperatorEncoding() {
3441 if (numLeft() < 2)
3442 return nullptr;
3443
3444
3445
3446 size_t lower = 0u, upper = NumOps - 1;
3447 while (upper != lower) {
3448 size_t middle = (upper + lower) / 2;
3449 if (Ops[middle] < First)
3450 lower = middle + 1;
3451 else
3452 upper = middle;
3453 }
3454 if (Ops[lower] != First)
3455 return nullptr;
3456
3457 First += 2;
3458 return &Ops[lower];
3459 }
3460
3461
3462
3463
3464 template <typename Derived, typename Alloc>
3465 Node *
3466 AbstractManglingParser<Derived, Alloc>::parseOperatorName(NameState *State) {
3467 if (const auto *Op = parseOperatorEncoding()) {
3468 if (Op->getKind() == OperatorInfo::CCast) {
3469
3470 ScopedOverride<bool> SaveTemplate(TryToParseTemplateArgs, false);
3471
3472
3473
3474 ScopedOverride<bool> SavePermit(PermitForwardTemplateReferences,
3475 PermitForwardTemplateReferences ||
3476 State != nullptr);
3477 Node *Ty = getDerived().parseType();
3478 if (Ty == nullptr)
3479 return nullptr;
3480 if (State) State->CtorDtorConversion = true;
3481 return make<ConversionOperatorType>(Ty);
3482 }
3483
3484 if (Op->getKind() >= OperatorInfo::Unnameable)
3485
3486 return nullptr;
3487 if (Op->getKind() == OperatorInfo::Member && !Op->getFlag())
3488
3489 return nullptr;
3490
3491 return make<NameType>(Op->getName());
3492 }
3493
3494 if (consumeIf("li")) {
3495
3496 Node *SN = getDerived().parseSourceName(State);
3497 if (SN == nullptr)
3498 return nullptr;
3499 return make<LiteralOperator>(SN);
3500 }
3501
3502 if (consumeIf('v')) {
3503
3504 if (look() >= '0' && look() <= '9') {
3505 First++;
3506 Node *SN = getDerived().parseSourceName(State);
3507 if (SN == nullptr)
3508 return nullptr;
3509 return make<ConversionOperatorType>(SN);
3510 }
3511 return nullptr;
3512 }
3513
3514 return nullptr;
3515 }
3516
3517
3518
3519
3520
3521
3522
3523
3524
3525
3526
3527 template <typename Derived, typename Alloc>
3528 Node *
3529 AbstractManglingParser<Derived, Alloc>::parseCtorDtorName(Node *&SoFar,
3530 NameState *State) {
3531 if (SoFar->getKind() == Node::KSpecialSubstitution) {
3532
3533 SoFar = make<ExpandedSpecialSubstitution>(
3534 static_cast<SpecialSubstitution *>(SoFar));
3535 if (!SoFar)
3536 return nullptr;
3537 }
3538
3539 if (consumeIf('C')) {
3540 bool IsInherited = consumeIf('I');
3541 if (look() != '1' && look() != '2' && look() != '3' && look() != '4' &&
3542 look() != '5')
3543 return nullptr;
3544 int Variant = look() - '0';
3545 ++First;
3546 if (State) State->CtorDtorConversion = true;
3547 if (IsInherited) {
3548 if (getDerived().parseName(State) == nullptr)
3549 return nullptr;
3550 }
3551 return make<CtorDtorName>(SoFar, false, Variant);
3552 }
3553
3554 if (look() == 'D' && (look(1) == '0' || look(1) == '1' || look(1) == '2' ||
3555 look(1) == '4' || look(1) == '5')) {
3556 int Variant = look(1) - '0';
3557 First += 2;
3558 if (State) State->CtorDtorConversion = true;
3559 return make<CtorDtorName>(SoFar, true, Variant);
3560 }
3561
3562 return nullptr;
3563 }
3564
3565
3566
3567
3568
3569
3570
3571
3572
3573
3574
3575
3576
3577
3578
3579
3580
3581
3582
3583
3584 template <typename Derived, typename Alloc>
3585 Node *
3586 AbstractManglingParser<Derived, Alloc>::parseNestedName(NameState *State) {
3587 if (!consumeIf('N'))
3588 return nullptr;
3589
3590
3591
3592 if (!consumeIf('H')) {
3593 Qualifiers CVTmp = parseCVQualifiers();
3594 if (State)
3595 State->CVQualifiers = CVTmp;
3596
3597 if (consumeIf('O')) {
3598 if (State)
3599 State->ReferenceQualifier = FrefQualRValue;
3600 } else if (consumeIf('R')) {
3601 if (State)
3602 State->ReferenceQualifier = FrefQualLValue;
3603 } else {
3604 if (State)
3605 State->ReferenceQualifier = FrefQualNone;
3606 }
3607 } else if (State) {
3608 State->HasExplicitObjectParameter = true;
3609 }
3610
3611 Node *SoFar = nullptr;
3612 while (!consumeIf('E')) {
3613 if (State)
3614
3615 State->EndsWithTemplateArgs = false;
3616
3617 if (look() == 'T') {
3618
3619 if (SoFar != nullptr)
3620 return nullptr;
3621 SoFar = getDerived().parseTemplateParam();
3622 } else if (look() == 'I') {
3623
3624 if (SoFar == nullptr)
3625 return nullptr;
3626 Node *TA = getDerived().parseTemplateArgs(State != nullptr);
3627 if (TA == nullptr)
3628 return nullptr;
3629 if (SoFar->getKind() == Node::KNameWithTemplateArgs)
3630
3631
3632
3633 return nullptr;
3634 if (State)
3635 State->EndsWithTemplateArgs = true;
3636 SoFar = make<NameWithTemplateArgs>(SoFar, TA);
3637 } else if (look() == 'D' && (look(1) == 't' || look(1) == 'T')) {
3638
3639 if (SoFar != nullptr)
3640 return nullptr;
3641 SoFar = getDerived().parseDecltype();
3642 } else {
3643 ModuleName *Module = nullptr;
3644
3645 if (look() == 'S') {
3646
3647 Node *S = nullptr;
3648 if (look(1) == 't') {
3649 First += 2;
3650 S = make<NameType>("std");
3651 } else {
3652 S = getDerived().parseSubstitution();
3653 }
3654 if (!S)
3655 return nullptr;
3656 if (S->getKind() == Node::KModuleName) {
3657 Module = static_cast<ModuleName *>(S);
3658 } else if (SoFar != nullptr) {
3659 return nullptr;
3660 } else {
3661 SoFar = S;
3662 continue;
3663 }
3664 }
3665
3666
3667 SoFar = getDerived().parseUnqualifiedName(State, SoFar, Module);
3668 }
3669
3670 if (SoFar == nullptr)
3671 return nullptr;
3672 Subs.push_back(SoFar);
3673
3674
3675
3676 consumeIf('M');
3677 }
3678
3679 if (SoFar == nullptr || Subs.empty())
3680 return nullptr;
3681
3682 Subs.pop_back();
3683 return SoFar;
3684 }
3685
3686
3687 template <typename Derived, typename Alloc>
3688 Node *AbstractManglingParser<Derived, Alloc>::parseSimpleId() {
3689 Node *SN = getDerived().parseSourceName(nullptr);
3690 if (SN == nullptr)
3691 return nullptr;
3692 if (look() == 'I') {
3693 Node *TA = getDerived().parseTemplateArgs();
3694 if (TA == nullptr)
3695 return nullptr;
3696 return make<NameWithTemplateArgs>(SN, TA);
3697 }
3698 return SN;
3699 }
3700
3701
3702
3703 template <typename Derived, typename Alloc>
3704 Node *AbstractManglingParser<Derived, Alloc>::parseDestructorName() {
3705 Node *Result;
3706 if (std::isdigit(look()))
3707 Result = getDerived().parseSimpleId();
3708 else
3709 Result = getDerived().parseUnresolvedType();
3710 if (Result == nullptr)
3711 return nullptr;
3712 return make<DtorName>(Result);
3713 }
3714
3715
3716
3717
3718 template <typename Derived, typename Alloc>
3719 Node *AbstractManglingParser<Derived, Alloc>::parseUnresolvedType() {
3720 if (look() == 'T') {
3721 Node *TP = getDerived().parseTemplateParam();
3722 if (TP == nullptr)
3723 return nullptr;
3724 Subs.push_back(TP);
3725 return TP;
3726 }
3727 if (look() == 'D') {
3728 Node *DT = getDerived().parseDecltype();
3729 if (DT == nullptr)
3730 return nullptr;
3731 Subs.push_back(DT);
3732 return DT;
3733 }
3734 return getDerived().parseSubstitution();
3735 }
3736
3737
3738
3739
3740
3741
3742
3743
3744 template <typename Derived, typename Alloc>
3745 Node *AbstractManglingParser<Derived, Alloc>::parseBaseUnresolvedName() {
3746 if (std::isdigit(look()))
3747 return getDerived().parseSimpleId();
3748
3749 if (consumeIf("dn"))
3750 return getDerived().parseDestructorName();
3751
3752 consumeIf("on");
3753
3754 Node *Oper = getDerived().parseOperatorName(nullptr);
3755 if (Oper == nullptr)
3756 return nullptr;
3757 if (look() == 'I') {
3758 Node *TA = getDerived().parseTemplateArgs();
3759 if (TA == nullptr)
3760 return nullptr;
3761 return make<NameWithTemplateArgs>(Oper, TA);
3762 }
3763 return Oper;
3764 }
3765
3766
3767
3768
3769
3770
3771
3772
3773
3774
3775
3776
3777
3778 template <typename Derived, typename Alloc>
3779 Node *AbstractManglingParser<Derived, Alloc>::parseUnresolvedName(bool Global) {
3780 Node *SoFar = nullptr;
3781
3782
3783
3784 if (consumeIf("srN")) {
3785 SoFar = getDerived().parseUnresolvedType();
3786 if (SoFar == nullptr)
3787 return nullptr;
3788
3789 if (look() == 'I') {
3790 Node *TA = getDerived().parseTemplateArgs();
3791 if (TA == nullptr)
3792 return nullptr;
3793 SoFar = make<NameWithTemplateArgs>(SoFar, TA);
3794 if (!SoFar)
3795 return nullptr;
3796 }
3797
3798 while (!consumeIf('E')) {
3799 Node *Qual = getDerived().parseSimpleId();
3800 if (Qual == nullptr)
3801 return nullptr;
3802 SoFar = make<QualifiedName>(SoFar, Qual);
3803 if (!SoFar)
3804 return nullptr;
3805 }
3806
3807 Node *Base = getDerived().parseBaseUnresolvedName();
3808 if (Base == nullptr)
3809 return nullptr;
3810 return make<QualifiedName>(SoFar, Base);
3811 }
3812
3813
3814 if (!consumeIf("sr")) {
3815 SoFar = getDerived().parseBaseUnresolvedName();
3816 if (SoFar == nullptr)
3817 return nullptr;
3818 if (Global)
3819 SoFar = make<GlobalQualifiedName>(SoFar);
3820 return SoFar;
3821 }
3822
3823
3824 if (std::isdigit(look())) {
3825 do {
3826 Node *Qual = getDerived().parseSimpleId();
3827 if (Qual == nullptr)
3828 return nullptr;
3829 if (SoFar)
3830 SoFar = make<QualifiedName>(SoFar, Qual);
3831 else if (Global)
3832 SoFar = make<GlobalQualifiedName>(Qual);
3833 else
3834 SoFar = Qual;
3835 if (!SoFar)
3836 return nullptr;
3837 } while (!consumeIf('E'));
3838 }
3839
3840
3841 else {
3842 SoFar = getDerived().parseUnresolvedType();
3843 if (SoFar == nullptr)
3844 return nullptr;
3845
3846 if (look() == 'I') {
3847 Node *TA = getDerived().parseTemplateArgs();
3848 if (TA == nullptr)
3849 return nullptr;
3850 SoFar = make<NameWithTemplateArgs>(SoFar, TA);
3851 if (!SoFar)
3852 return nullptr;
3853 }
3854 }
3855
3856 DEMANGLE_ASSERT(SoFar != nullptr, "");
3857
3858 Node *Base = getDerived().parseBaseUnresolvedName();
3859 if (Base == nullptr)
3860 return nullptr;
3861 return make<QualifiedName>(SoFar, Base);
3862 }
3863
3864
3865
3866 template <typename Derived, typename Alloc>
3867 Node *AbstractManglingParser<Derived, Alloc>::parseAbiTags(Node *N) {
3868 while (consumeIf('B')) {
3869 std::string_view SN = parseBareSourceName();
3870 if (SN.empty())
3871 return nullptr;
3872 N = make<AbiTagAttr>(N, SN);
3873 if (!N)
3874 return nullptr;
3875 }
3876 return N;
3877 }
3878
3879
3880 template <typename Alloc, typename Derived>
3881 std::string_view
3882 AbstractManglingParser<Alloc, Derived>::parseNumber(bool AllowNegative) {
3883 const char *Tmp = First;
3884 if (AllowNegative)
3885 consumeIf('n');
3886 if (numLeft() == 0 || !std::isdigit(*First))
3887 return std::string_view();
3888 while (numLeft() != 0 && std::isdigit(*First))
3889 ++First;
3890 return std::string_view(Tmp, First - Tmp);
3891 }
3892
3893
3894 template <typename Alloc, typename Derived>
3895 bool AbstractManglingParser<Alloc, Derived>::parsePositiveInteger(size_t *Out) {
3896 *Out = 0;
3897 if (look() < '0' || look() > '9')
3898 return true;
3899 while (look() >= '0' && look() <= '9') {
3900 *Out *= 10;
3901 *Out += static_cast<size_t>(consume() - '0');
3902 }
3903 return false;
3904 }
3905
3906 template <typename Alloc, typename Derived>
3907 std::string_view AbstractManglingParser<Alloc, Derived>::parseBareSourceName() {
3908 size_t Int = 0;
3909 if (parsePositiveInteger(&Int) || numLeft() < Int)
3910 return {};
3911 std::string_view R(First, Int);
3912 First += Int;
3913 return R;
3914 }
3915
3916
3917
3918
3919
3920
3921
3922
3923
3924 template <typename Derived, typename Alloc>
3925 Node *AbstractManglingParser<Derived, Alloc>::parseFunctionType() {
3926 Qualifiers CVQuals = parseCVQualifiers();
3927
3928 Node *ExceptionSpec = nullptr;
3929 if (consumeIf("Do")) {
3930 ExceptionSpec = make<NameType>("noexcept");
3931 if (!ExceptionSpec)
3932 return nullptr;
3933 } else if (consumeIf("DO")) {
3934 Node *E = getDerived().parseExpr();
3935 if (E == nullptr || !consumeIf('E'))
3936 return nullptr;
3937 ExceptionSpec = make<NoexceptSpec>(E);
3938 if (!ExceptionSpec)
3939 return nullptr;
3940 } else if (consumeIf("Dw")) {
3941 size_t SpecsBegin = Names.size();
3942 while (!consumeIf('E')) {
3943 Node *T = getDerived().parseType();
3944 if (T == nullptr)
3945 return nullptr;
3946 Names.push_back(T);
3947 }
3948 ExceptionSpec =
3949 make<DynamicExceptionSpec>(popTrailingNodeArray(SpecsBegin));
3950 if (!ExceptionSpec)
3951 return nullptr;
3952 }
3953
3954 consumeIf("Dx");
3955
3956 if (!consumeIf('F'))
3957 return nullptr;
3958 consumeIf('Y');
3959 Node *ReturnType = getDerived().parseType();
3960 if (ReturnType == nullptr)
3961 return nullptr;
3962
3963 FunctionRefQual ReferenceQualifier = FrefQualNone;
3964 size_t ParamsBegin = Names.size();
3965 while (true) {
3966 if (consumeIf('E'))
3967 break;
3968 if (consumeIf('v'))
3969 continue;
3970 if (consumeIf("RE")) {
3971 ReferenceQualifier = FrefQualLValue;
3972 break;
3973 }
3974 if (consumeIf("OE")) {
3975 ReferenceQualifier = FrefQualRValue;
3976 break;
3977 }
3978 Node *T = getDerived().parseType();
3979 if (T == nullptr)
3980 return nullptr;
3981 Names.push_back(T);
3982 }
3983
3984 NodeArray Params = popTrailingNodeArray(ParamsBegin);
3985 return make<FunctionType>(ReturnType, Params, CVQuals,
3986 ReferenceQualifier, ExceptionSpec);
3987 }
3988
3989
3990
3991
3992
3993
3994 template <typename Derived, typename Alloc>
3995 Node *AbstractManglingParser<Derived, Alloc>::parseVectorType() {
3996 if (!consumeIf("Dv"))
3997 return nullptr;
3998 if (look() >= '1' && look() <= '9') {
3999 Node *DimensionNumber = make<NameType>(parseNumber());
4000 if (!DimensionNumber)
4001 return nullptr;
4002 if (!consumeIf('_'))
4003 return nullptr;
4004 if (consumeIf('p'))
4005 return make<PixelVectorType>(DimensionNumber);
4006 Node *ElemType = getDerived().parseType();
4007 if (ElemType == nullptr)
4008 return nullptr;
4009 return make<VectorType>(ElemType, DimensionNumber);
4010 }
4011
4012 if (!consumeIf('_')) {
4013 Node *DimExpr = getDerived().parseExpr();
4014 if (!DimExpr)
4015 return nullptr;
4016 if (!consumeIf('_'))
4017 return nullptr;
4018 Node *ElemType = getDerived().parseType();
4019 if (!ElemType)
4020 return nullptr;
4021 return make<VectorType>(ElemType, DimExpr);
4022 }
4023 Node *ElemType = getDerived().parseType();
4024 if (!ElemType)
4025 return nullptr;
4026 return make<VectorType>(ElemType, nullptr);
4027 }
4028
4029
4030
4031 template <typename Derived, typename Alloc>
4032 Node *AbstractManglingParser<Derived, Alloc>::parseDecltype() {
4033 if (!consumeIf('D'))
4034 return nullptr;
4035 if (!consumeIf('t') && !consumeIf('T'))
4036 return nullptr;
4037 Node *E = getDerived().parseExpr();
4038 if (E == nullptr)
4039 return nullptr;
4040 if (!consumeIf('E'))
4041 return nullptr;
4042 return make<EnclosingExpr>("decltype", E);
4043 }
4044
4045
4046
4047 template <typename Derived, typename Alloc>
4048 Node *AbstractManglingParser<Derived, Alloc>::parseArrayType() {
4049 if (!consumeIf('A'))
4050 return nullptr;
4051
4052 Node *Dimension = nullptr;
4053
4054 if (std::isdigit(look())) {
4055 Dimension = make<NameType>(parseNumber());
4056 if (!Dimension)
4057 return nullptr;
4058 if (!consumeIf('_'))
4059 return nullptr;
4060 } else if (!consumeIf('_')) {
4061 Node *DimExpr = getDerived().parseExpr();
4062 if (DimExpr == nullptr)
4063 return nullptr;
4064 if (!consumeIf('_'))
4065 return nullptr;
4066 Dimension = DimExpr;
4067 }
4068
4069 Node *Ty = getDerived().parseType();
4070 if (Ty == nullptr)
4071 return nullptr;
4072 return make<ArrayType>(Ty, Dimension);
4073 }
4074
4075
4076 template <typename Derived, typename Alloc>
4077 Node *AbstractManglingParser<Derived, Alloc>::parsePointerToMemberType() {
4078 if (!consumeIf('M'))
4079 return nullptr;
4080 Node *ClassType = getDerived().parseType();
4081 if (ClassType == nullptr)
4082 return nullptr;
4083 Node *MemberType = getDerived().parseType();
4084 if (MemberType == nullptr)
4085 return nullptr;
4086 return make<PointerToMemberType>(ClassType, MemberType);
4087 }
4088
4089
4090
4091
4092
4093 template <typename Derived, typename Alloc>
4094 Node *AbstractManglingParser<Derived, Alloc>::parseClassEnumType() {
4095 std::string_view ElabSpef;
4096 if (consumeIf("Ts"))
4097 ElabSpef = "struct";
4098 else if (consumeIf("Tu"))
4099 ElabSpef = "union";
4100 else if (consumeIf("Te"))
4101 ElabSpef = "enum";
4102
4103 Node *Name = getDerived().parseName();
4104 if (Name == nullptr)
4105 return nullptr;
4106
4107 if (!ElabSpef.empty())
4108 return make<ElaboratedTypeSpefType>(ElabSpef, Name);
4109
4110 return Name;
4111 }
4112
4113
4114
4115
4116 template <typename Derived, typename Alloc>
4117 Node *AbstractManglingParser<Derived, Alloc>::parseQualifiedType() {
4118 if (consumeIf('U')) {
4119 std::string_view Qual = parseBareSourceName();
4120 if (Qual.empty())
4121 return nullptr;
4122
4123
4124 if (starts_with(Qual, "objcproto")) {
4125 constexpr size_t Len = sizeof("objcproto") - 1;
4126 std::string_view ProtoSourceName(Qual.data() + Len, Qual.size() - Len);
4127 std::string_view Proto;
4128 {
4129 ScopedOverride<const char *> SaveFirst(First, ProtoSourceName.data()),
4130 SaveLast(Last, &*ProtoSourceName.rbegin() + 1);
4131 Proto = parseBareSourceName();
4132 }
4133 if (Proto.empty())
4134 return nullptr;
4135 Node *Child = getDerived().parseQualifiedType();
4136 if (Child == nullptr)
4137 return nullptr;
4138 return make<ObjCProtoName>(Child, Proto);
4139 }
4140
4141 Node *TA = nullptr;
4142 if (look() == 'I') {
4143 TA = getDerived().parseTemplateArgs();
4144 if (TA == nullptr)
4145 return nullptr;
4146 }
4147
4148 Node *Child = getDerived().parseQualifiedType();
4149 if (Child == nullptr)
4150 return nullptr;
4151 return make<VendorExtQualType>(Child, Qual, TA);
4152 }
4153
4154 Qualifiers Quals = parseCVQualifiers();
4155 Node *Ty = getDerived().parseType();
4156 if (Ty == nullptr)
4157 return nullptr;
4158 if (Quals != QualNone)
4159 Ty = make<QualType>(Ty, Quals);
4160 return Ty;
4161 }
4162
4163
4164
4165
4166
4167
4168
4169
4170
4171
4172
4173
4174
4175
4176
4177
4178
4179
4180
4181
4182
4183 template <typename Derived, typename Alloc>
4184 Node *AbstractManglingParser<Derived, Alloc>::parseType() {
4185 Node *Result = nullptr;
4186
4187 switch (look()) {
4188
4189 case 'r':
4190 case 'V':
4191 case 'K': {
4192 unsigned AfterQuals = 0;
4193 if (look(AfterQuals) == 'r') ++AfterQuals;
4194 if (look(AfterQuals) == 'V') ++AfterQuals;
4195 if (look(AfterQuals) == 'K') ++AfterQuals;
4196
4197 if (look(AfterQuals) == 'F' ||
4198 (look(AfterQuals) == 'D' &&
4199 (look(AfterQuals + 1) == 'o' || look(AfterQuals + 1) == 'O' ||
4200 look(AfterQuals + 1) == 'w' || look(AfterQuals + 1) == 'x'))) {
4201 Result = getDerived().parseFunctionType();
4202 break;
4203 }
4204 DEMANGLE_FALLTHROUGH;
4205 }
4206 case 'U': {
4207 Result = getDerived().parseQualifiedType();
4208 break;
4209 }
4210
4211 case 'v':
4212 ++First;
4213 return make<NameType>("void");
4214
4215 case 'w':
4216 ++First;
4217 return make<NameType>("wchar_t");
4218
4219 case 'b':
4220 ++First;
4221 return make<NameType>("bool");
4222
4223 case 'c':
4224 ++First;
4225 return make<NameType>("char");
4226
4227 case 'a':
4228 ++First;
4229 return make<NameType>("signed char");
4230
4231 case 'h':
4232 ++First;
4233 return make<NameType>("unsigned char");
4234
4235 case 's':
4236 ++First;
4237 return make<NameType>("short");
4238
4239 case 't':
4240 ++First;
4241 return make<NameType>("unsigned short");
4242
4243 case 'i':
4244 ++First;
4245 return make<NameType>("int");
4246
4247 case 'j':
4248 ++First;
4249 return make<NameType>("unsigned int");
4250
4251 case 'l':
4252 ++First;
4253 return make<NameType>("long");
4254
4255 case 'm':
4256 ++First;
4257 return make<NameType>("unsigned long");
4258
4259 case 'x':
4260 ++First;
4261 return make<NameType>("long long");
4262
4263 case 'y':
4264 ++First;
4265 return make<NameType>("unsigned long long");
4266
4267 case 'n':
4268 ++First;
4269 return make<NameType>("__int128");
4270
4271 case 'o':
4272 ++First;
4273 return make<NameType>("unsigned __int128");
4274
4275 case 'f':
4276 ++First;
4277 return make<NameType>("float");
4278
4279 case 'd':
4280 ++First;
4281 return make<NameType>("double");
4282
4283 case 'e':
4284 ++First;
4285 return make<NameType>("long double");
4286
4287 case 'g':
4288 ++First;
4289 return make<NameType>("__float128");
4290
4291 case 'z':
4292 ++First;
4293 return make<NameType>("...");
4294
4295
4296 case 'u': {
4297 ++First;
4298 std::string_view Res = parseBareSourceName();
4299 if (Res.empty())
4300 return nullptr;
4301
4302
4303
4304 if (consumeIf('I')) {
4305 Node *BaseType = parseType();
4306 if (BaseType == nullptr)
4307 return nullptr;
4308 if (!consumeIf('E'))
4309 return nullptr;
4310 Result = make<TransformedType>(Res, BaseType);
4311 } else
4312 Result = make<NameType>(Res);
4313 break;
4314 }
4315 case 'D':
4316 switch (look(1)) {
4317
4318 case 'd':
4319 First += 2;
4320 return make<NameType>("decimal64");
4321
4322 case 'e':
4323 First += 2;
4324 return make<NameType>("decimal128");
4325
4326 case 'f':
4327 First += 2;
4328 return make<NameType>("decimal32");
4329
4330 case 'h':
4331 First += 2;
4332 return make<NameType>("half");
4333
4334
4335 case 'F': {
4336 First += 2;
4337 if (consumeIf("16b"))
4338 return make<NameType>("std::bfloat16_t");
4339 Node *DimensionNumber = make<NameType>(parseNumber());
4340 if (!DimensionNumber)
4341 return nullptr;
4342 if (!consumeIf('_'))
4343 return nullptr;
4344 return make<BinaryFPType>(DimensionNumber);
4345 }
4346
4347
4348
4349
4350
4351
4352
4353
4354
4355 case 'A': {
4356 char c = look(2);
4357 First += 3;
4358 switch (c) {
4359 case 's':
4360 return make<NameType>("short _Accum");
4361 case 't':
4362 return make<NameType>("unsigned short _Accum");
4363 case 'i':
4364 return make<NameType>("_Accum");
4365 case 'j':
4366 return make<NameType>("unsigned _Accum");
4367 case 'l':
4368 return make<NameType>("long _Accum");
4369 case 'm':
4370 return make<NameType>("unsigned long _Accum");
4371 default:
4372 return nullptr;
4373 }
4374 }
4375 case 'R': {
4376 char c = look(2);
4377 First += 3;
4378 switch (c) {
4379 case 's':
4380 return make<NameType>("short _Fract");
4381 case 't':
4382 return make<NameType>("unsigned short _Fract");
4383 case 'i':
4384 return make<NameType>("_Fract");
4385 case 'j':
4386 return make<NameType>("unsigned _Fract");
4387 case 'l':
4388 return make<NameType>("long _Fract");
4389 case 'm':
4390 return make<NameType>("unsigned long _Fract");
4391 default:
4392 return nullptr;
4393 }
4394 }
4395 case 'S': {
4396 First += 2;
4397 if (look() != 'D')
4398 return nullptr;
4399 if (look(1) == 'A') {
4400 char c = look(2);
4401 First += 3;
4402 switch (c) {
4403 case 's':
4404 return make<NameType>("_Sat short _Accum");
4405 case 't':
4406 return make<NameType>("_Sat unsigned short _Accum");
4407 case 'i':
4408 return make<NameType>("_Sat _Accum");
4409 case 'j':
4410 return make<NameType>("_Sat unsigned _Accum");
4411 case 'l':
4412 return make<NameType>("_Sat long _Accum");
4413 case 'm':
4414 return make<NameType>("_Sat unsigned long _Accum");
4415 default:
4416 return nullptr;
4417 }
4418 }
4419 if (look(1) == 'R') {
4420 char c = look(2);
4421 First += 3;
4422 switch (c) {
4423 case 's':
4424 return make<NameType>("_Sat short _Fract");
4425 case 't':
4426 return make<NameType>("_Sat unsigned short _Fract");
4427 case 'i':
4428 return make<NameType>("_Sat _Fract");
4429 case 'j':
4430 return make<NameType>("_Sat unsigned _Fract");
4431 case 'l':
4432 return make<NameType>("_Sat long _Fract");
4433 case 'm':
4434 return make<NameType>("_Sat unsigned long _Fract");
4435 default:
4436 return nullptr;
4437 }
4438 }
4439 return nullptr;
4440 }
4441
4442
4443
4444
4445 case 'B':
4446 case 'U': {
4447 bool Signed = look(1) == 'B';
4448 First += 2;
4449 Node *Size = std::isdigit(look()) ? make<NameType>(parseNumber())
4450 : getDerived().parseExpr();
4451 if (!Size)
4452 return nullptr;
4453 if (!consumeIf('_'))
4454 return nullptr;
4455 return make<BitIntType>(Size, Signed);
4456 }
4457
4458 case 'i':
4459 First += 2;
4460 return make<NameType>("char32_t");
4461
4462 case 's':
4463 First += 2;
4464 return make<NameType>("char16_t");
4465
4466 case 'u':
4467 First += 2;
4468 return make<NameType>("char8_t");
4469
4470 case 'a':
4471 First += 2;
4472 return make<NameType>("auto");
4473
4474 case 'c':
4475 First += 2;
4476 return make<NameType>("decltype(auto)");
4477
4478
4479 case 'k':
4480 case 'K': {
4481 std::string_view Kind = look(1) == 'k' ? " auto" : " decltype(auto)";
4482 First += 2;
4483 Node *Constraint = getDerived().parseName();
4484 if (!Constraint)
4485 return nullptr;
4486 return make<PostfixQualifiedType>(Constraint, Kind);
4487 }
4488
4489 case 'n':
4490 First += 2;
4491 return make<NameType>("std::nullptr_t");
4492
4493
4494 case 't':
4495 case 'T': {
4496 Result = getDerived().parseDecltype();
4497 break;
4498 }
4499
4500 case 'v': {
4501 Result = getDerived().parseVectorType();
4502 break;
4503 }
4504
4505 case 'p': {
4506 First += 2;
4507 Node *Child = getDerived().parseType();
4508 if (!Child)
4509 return nullptr;
4510 Result = make<ParameterPackExpansion>(Child);
4511 break;
4512 }
4513
4514 case 'o':
4515 case 'O':
4516 case 'w':
4517
4518 case 'x':
4519 Result = getDerived().parseFunctionType();
4520 break;
4521 }
4522 break;
4523
4524 case 'F': {
4525 Result = getDerived().parseFunctionType();
4526 break;
4527 }
4528
4529 case 'A': {
4530 Result = getDerived().parseArrayType();
4531 break;
4532 }
4533
4534 case 'M': {
4535 Result = getDerived().parsePointerToMemberType();
4536 break;
4537 }
4538
4539 case 'T': {
4540
4541 if (look(1) == 's' || look(1) == 'u' || look(1) == 'e') {
4542 Result = getDerived().parseClassEnumType();
4543 break;
4544 }
4545
4546 Result = getDerived().parseTemplateParam();
4547 if (Result == nullptr)
4548 return nullptr;
4549
4550
4551
4552
4553
4554
4555
4556
4557
4558
4559
4560 if (TryToParseTemplateArgs && look() == 'I') {
4561 Subs.push_back(Result);
4562 Node *TA = getDerived().parseTemplateArgs();
4563 if (TA == nullptr)
4564 return nullptr;
4565 Result = make<NameWithTemplateArgs>(Result, TA);
4566 }
4567 break;
4568 }
4569
4570 case 'P': {
4571 ++First;
4572 Node *Ptr = getDerived().parseType();
4573 if (Ptr == nullptr)
4574 return nullptr;
4575 Result = make<PointerType>(Ptr);
4576 break;
4577 }
4578
4579 case 'R': {
4580 ++First;
4581 Node *Ref = getDerived().parseType();
4582 if (Ref == nullptr)
4583 return nullptr;
4584 Result = make<ReferenceType>(Ref, ReferenceKind::LValue);
4585 break;
4586 }
4587
4588 case 'O': {
4589 ++First;
4590 Node *Ref = getDerived().parseType();
4591 if (Ref == nullptr)
4592 return nullptr;
4593 Result = make<ReferenceType>(Ref, ReferenceKind::RValue);
4594 break;
4595 }
4596
4597 case 'C': {
4598 ++First;
4599 Node *P = getDerived().parseType();
4600 if (P == nullptr)
4601 return nullptr;
4602 Result = make<PostfixQualifiedType>(P, " complex");
4603 break;
4604 }
4605
4606 case 'G': {
4607 ++First;
4608 Node *P = getDerived().parseType();
4609 if (P == nullptr)
4610 return P;
4611 Result = make<PostfixQualifiedType>(P, " imaginary");
4612 break;
4613 }
4614
4615 case 'S': {
4616 if (look(1) != 't') {
4617 bool IsSubst = false;
4618 Result = getDerived().parseUnscopedName(nullptr, &IsSubst);
4619 if (!Result)
4620 return nullptr;
4621
4622
4623
4624
4625
4626
4627
4628
4629
4630
4631
4632 if (look() == 'I' && (!IsSubst || TryToParseTemplateArgs)) {
4633 if (!IsSubst)
4634 Subs.push_back(Result);
4635 Node *TA = getDerived().parseTemplateArgs();
4636 if (TA == nullptr)
4637 return nullptr;
4638 Result = make<NameWithTemplateArgs>(Result, TA);
4639 } else if (IsSubst) {
4640
4641
4642 return Result;
4643 }
4644 break;
4645 }
4646 DEMANGLE_FALLTHROUGH;
4647 }
4648
4649 default: {
4650 Result = getDerived().parseClassEnumType();
4651 break;
4652 }
4653 }
4654
4655
4656
4657
4658 if (Result != nullptr)
4659 Subs.push_back(Result);
4660 return Result;
4661 }
4662
4663 template <typename Derived, typename Alloc>
4664 Node *
4665 AbstractManglingParser<Derived, Alloc>::parsePrefixExpr(std::string_view Kind,
4666 Node::Prec Prec) {
4667 Node *E = getDerived().parseExpr();
4668 if (E == nullptr)
4669 return nullptr;
4670 return make<PrefixExpr>(Kind, E, Prec);
4671 }
4672
4673 template <typename Derived, typename Alloc>
4674 Node *
4675 AbstractManglingParser<Derived, Alloc>::parseBinaryExpr(std::string_view Kind,
4676 Node::Prec Prec) {
4677 Node *LHS = getDerived().parseExpr();
4678 if (LHS == nullptr)
4679 return nullptr;
4680 Node *RHS = getDerived().parseExpr();
4681 if (RHS == nullptr)
4682 return nullptr;
4683 return make<BinaryExpr>(LHS, Kind, RHS, Prec);
4684 }
4685
4686 template <typename Derived, typename Alloc>
4687 Node *AbstractManglingParser<Derived, Alloc>::parseIntegerLiteral(
4688 std::string_view Lit) {
4689 std::string_view Tmp = parseNumber(true);
4690 if (!Tmp.empty() && consumeIf('E'))
4691 return make<IntegerLiteral>(Lit, Tmp);
4692 return nullptr;
4693 }
4694
4695
4696 template <typename Alloc, typename Derived>
4697 Qualifiers AbstractManglingParser<Alloc, Derived>::parseCVQualifiers() {
4698 Qualifiers CVR = QualNone;
4699 if (consumeIf('r'))
4700 CVR |= QualRestrict;
4701 if (consumeIf('V'))
4702 CVR |= QualVolatile;
4703 if (consumeIf('K'))
4704 CVR |= QualConst;
4705 return CVR;
4706 }
4707
4708
4709
4710
4711
4712
4713 template <typename Derived, typename Alloc>
4714 Node *AbstractManglingParser<Derived, Alloc>::parseFunctionParam() {
4715 if (consumeIf("fpT"))
4716 return make<NameType>("this");
4717 if (consumeIf("fp")) {
4718 parseCVQualifiers();
4719 std::string_view Num = parseNumber();
4720 if (!consumeIf('_'))
4721 return nullptr;
4722 return make<FunctionParam>(Num);
4723 }
4724 if (consumeIf("fL")) {
4725 if (parseNumber().empty())
4726 return nullptr;
4727 if (!consumeIf('p'))
4728 return nullptr;
4729 parseCVQualifiers();
4730 std::string_view Num = parseNumber();
4731 if (!consumeIf('_'))
4732 return nullptr;
4733 return make<FunctionParam>(Num);
4734 }
4735 return nullptr;
4736 }
4737
4738
4739
4740 template <typename Derived, typename Alloc>
4741 Node *AbstractManglingParser<Derived, Alloc>::parseConversionExpr() {
4742 if (!consumeIf("cv"))
4743 return nullptr;
4744 Node *Ty;
4745 {
4746 ScopedOverride<bool> SaveTemp(TryToParseTemplateArgs, false);
4747 Ty = getDerived().parseType();
4748 }
4749
4750 if (Ty == nullptr)
4751 return nullptr;
4752
4753 if (consumeIf('_')) {
4754 size_t ExprsBegin = Names.size();
4755 while (!consumeIf('E')) {
4756 Node *E = getDerived().parseExpr();
4757 if (E == nullptr)
4758 return E;
4759 Names.push_back(E);
4760 }
4761 NodeArray Exprs = popTrailingNodeArray(ExprsBegin);
4762 return make<ConversionExpr>(Ty, Exprs);
4763 }
4764
4765 Node *E[1] = {getDerived().parseExpr()};
4766 if (E[0] == nullptr)
4767 return nullptr;
4768 return make<ConversionExpr>(Ty, makeNodeArray(E, E + 1));
4769 }
4770
4771
4772
4773
4774
4775
4776
4777
4778 template <typename Derived, typename Alloc>
4779 Node *AbstractManglingParser<Derived, Alloc>::parseExprPrimary() {
4780 if (!consumeIf('L'))
4781 return nullptr;
4782 switch (look()) {
4783 case 'w':
4784 ++First;
4785 return getDerived().parseIntegerLiteral("wchar_t");
4786 case 'b':
4787 if (consumeIf("b0E"))
4788 return make<BoolExpr>(0);
4789 if (consumeIf("b1E"))
4790 return make<BoolExpr>(1);
4791 return nullptr;
4792 case 'c':
4793 ++First;
4794 return getDerived().parseIntegerLiteral("char");
4795 case 'a':
4796 ++First;
4797 return getDerived().parseIntegerLiteral("signed char");
4798 case 'h':
4799 ++First;
4800 return getDerived().parseIntegerLiteral("unsigned char");
4801 case 's':
4802 ++First;
4803 return getDerived().parseIntegerLiteral("short");
4804 case 't':
4805 ++First;
4806 return getDerived().parseIntegerLiteral("unsigned short");
4807 case 'i':
4808 ++First;
4809 return getDerived().parseIntegerLiteral("");
4810 case 'j':
4811 ++First;
4812 return getDerived().parseIntegerLiteral("u");
4813 case 'l':
4814 ++First;
4815 return getDerived().parseIntegerLiteral("l");
4816 case 'm':
4817 ++First;
4818 return getDerived().parseIntegerLiteral("ul");
4819 case 'x':
4820 ++First;
4821 return getDerived().parseIntegerLiteral("ll");
4822 case 'y':
4823 ++First;
4824 return getDerived().parseIntegerLiteral("ull");
4825 case 'n':
4826 ++First;
4827 return getDerived().parseIntegerLiteral("__int128");
4828 case 'o':
4829 ++First;
4830 return getDerived().parseIntegerLiteral("unsigned __int128");
4831 case 'f':
4832 ++First;
4833 return getDerived().template parseFloatingLiteral<float>();
4834 case 'd':
4835 ++First;
4836 return getDerived().template parseFloatingLiteral<double>();
4837 case 'e':
4838 ++First;
4839 #if defined(__powerpc__) || defined(__s390__)
4840
4841
4842 return getDerived().template parseFloatingLiteral<double>();
4843 #else
4844 return getDerived().template parseFloatingLiteral<long double>();
4845 #endif
4846 case '_':
4847 if (consumeIf("_Z")) {
4848 Node *R = getDerived().parseEncoding();
4849 if (R != nullptr && consumeIf('E'))
4850 return R;
4851 }
4852 return nullptr;
4853 case 'A': {
4854 Node *T = getDerived().parseType();
4855 if (T == nullptr)
4856 return nullptr;
4857
4858 if (consumeIf('E'))
4859 return make<StringLiteral>(T);
4860 return nullptr;
4861 }
4862 case 'D':
4863 if (consumeIf("Dn") && (consumeIf('0'), consumeIf('E')))
4864 return make<NameType>("nullptr");
4865 return nullptr;
4866 case 'T':
4867
4868
4869 return nullptr;
4870 case 'U': {
4871
4872 if (look(1) != 'l')
4873 return nullptr;
4874 Node *T = parseUnnamedTypeName(nullptr);
4875 if (!T || !consumeIf('E'))
4876 return nullptr;
4877 return make<LambdaExpr>(T);
4878 }
4879 default: {
4880
4881 Node *T = getDerived().parseType();
4882 if (T == nullptr)
4883 return nullptr;
4884 std::string_view N = parseNumber(true);
4885 if (N.empty())
4886 return nullptr;
4887 if (!consumeIf('E'))
4888 return nullptr;
4889 return make<EnumLiteral>(T, N);
4890 }
4891 }
4892 }
4893
4894
4895
4896
4897
4898 template <typename Derived, typename Alloc>
4899 Node *AbstractManglingParser<Derived, Alloc>::parseBracedExpr() {
4900 if (look() == 'd') {
4901 switch (look(1)) {
4902 case 'i': {
4903 First += 2;
4904 Node *Field = getDerived().parseSourceName(nullptr);
4905 if (Field == nullptr)
4906 return nullptr;
4907 Node *Init = getDerived().parseBracedExpr();
4908 if (Init == nullptr)
4909 return nullptr;
4910 return make<BracedExpr>(Field, Init, false);
4911 }
4912 case 'x': {
4913 First += 2;
4914 Node *Index = getDerived().parseExpr();
4915 if (Index == nullptr)
4916 return nullptr;
4917 Node *Init = getDerived().parseBracedExpr();
4918 if (Init == nullptr)
4919 return nullptr;
4920 return make<BracedExpr>(Index, Init, true);
4921 }
4922 case 'X': {
4923 First += 2;
4924 Node *RangeBegin = getDerived().parseExpr();
4925 if (RangeBegin == nullptr)
4926 return nullptr;
4927 Node *RangeEnd = getDerived().parseExpr();
4928 if (RangeEnd == nullptr)
4929 return nullptr;
4930 Node *Init = getDerived().parseBracedExpr();
4931 if (Init == nullptr)
4932 return nullptr;
4933 return make<BracedRangeExpr>(RangeBegin, RangeEnd, Init);
4934 }
4935 }
4936 }
4937 return getDerived().parseExpr();
4938 }
4939
4940
4941
4942
4943
4944
4945 template <typename Derived, typename Alloc>
4946 Node *AbstractManglingParser<Derived, Alloc>::parseFoldExpr() {
4947 if (!consumeIf('f'))
4948 return nullptr;
4949
4950 bool IsLeftFold = false, HasInitializer = false;
4951 switch (look()) {
4952 default:
4953 return nullptr;
4954 case 'L':
4955 IsLeftFold = true;
4956 HasInitializer = true;
4957 break;
4958 case 'R':
4959 HasInitializer = true;
4960 break;
4961 case 'l':
4962 IsLeftFold = true;
4963 break;
4964 case 'r':
4965 break;
4966 }
4967 ++First;
4968
4969 const auto *Op = parseOperatorEncoding();
4970 if (!Op)
4971 return nullptr;
4972 if (!(Op->getKind() == OperatorInfo::Binary
4973 || (Op->getKind() == OperatorInfo::Member
4974 && Op->getName().back() == '*')))
4975 return nullptr;
4976
4977 Node *Pack = getDerived().parseExpr();
4978 if (Pack == nullptr)
4979 return nullptr;
4980
4981 Node *Init = nullptr;
4982 if (HasInitializer) {
4983 Init = getDerived().parseExpr();
4984 if (Init == nullptr)
4985 return nullptr;
4986 }
4987
4988 if (IsLeftFold && Init)
4989 std::swap(Pack, Init);
4990
4991 return make<FoldExpr>(IsLeftFold, Op->getSymbol(), Pack, Init);
4992 }
4993
4994
4995
4996
4997 template <typename Derived, typename Alloc>
4998 Node *
4999 AbstractManglingParser<Derived, Alloc>::parsePointerToMemberConversionExpr(
5000 Node::Prec Prec) {
5001 Node *Ty = getDerived().parseType();
5002 if (!Ty)
5003 return nullptr;
5004 Node *Expr = getDerived().parseExpr();
5005 if (!Expr)
5006 return nullptr;
5007 std::string_view Offset = getDerived().parseNumber(true);
5008 if (!consumeIf('E'))
5009 return nullptr;
5010 return make<PointerToMemberConversionExpr>(Ty, Expr, Offset, Prec);
5011 }
5012
5013
5014
5015
5016
5017 template <typename Derived, typename Alloc>
5018 Node *AbstractManglingParser<Derived, Alloc>::parseSubobjectExpr() {
5019 Node *Ty = getDerived().parseType();
5020 if (!Ty)
5021 return nullptr;
5022 Node *Expr = getDerived().parseExpr();
5023 if (!Expr)
5024 return nullptr;
5025 std::string_view Offset = getDerived().parseNumber(true);
5026 size_t SelectorsBegin = Names.size();
5027 while (consumeIf('_')) {
5028 Node *Selector = make<NameType>(parseNumber());
5029 if (!Selector)
5030 return nullptr;
5031 Names.push_back(Selector);
5032 }
5033 bool OnePastTheEnd = consumeIf('p');
5034 if (!consumeIf('E'))
5035 return nullptr;
5036 return make<SubobjectExpr>(
5037 Ty, Expr, Offset, popTrailingNodeArray(SelectorsBegin), OnePastTheEnd);
5038 }
5039
5040 template <typename Derived, typename Alloc>
5041 Node *AbstractManglingParser<Derived, Alloc>::parseConstraintExpr() {
5042
5043
5044 ScopedOverride<bool> SaveIncompleteTemplateParameterTracking(
5045 HasIncompleteTemplateParameterTracking, true);
5046 return getDerived().parseExpr();
5047 }
5048
5049 template <typename Derived, typename Alloc>
5050 Node *AbstractManglingParser<Derived, Alloc>::parseRequiresExpr() {
5051 NodeArray Params;
5052 if (consumeIf("rQ")) {
5053
5054 size_t ParamsBegin = Names.size();
5055 while (!consumeIf('_')) {
5056 Node *Type = getDerived().parseType();
5057 if (Type == nullptr)
5058 return nullptr;
5059 Names.push_back(Type);
5060 }
5061 Params = popTrailingNodeArray(ParamsBegin);
5062 } else if (!consumeIf("rq")) {
5063
5064 return nullptr;
5065 }
5066
5067 size_t ReqsBegin = Names.size();
5068 do {
5069 Node *Constraint = nullptr;
5070 if (consumeIf('X')) {
5071
5072 Node *Expr = getDerived().parseExpr();
5073 if (Expr == nullptr)
5074 return nullptr;
5075 bool Noexcept = consumeIf('N');
5076 Node *TypeReq = nullptr;
5077 if (consumeIf('R')) {
5078 TypeReq = getDerived().parseName();
5079 if (TypeReq == nullptr)
5080 return nullptr;
5081 }
5082 Constraint = make<ExprRequirement>(Expr, Noexcept, TypeReq);
5083 } else if (consumeIf('T')) {
5084
5085 Node *Type = getDerived().parseType();
5086 if (Type == nullptr)
5087 return nullptr;
5088 Constraint = make<TypeRequirement>(Type);
5089 } else if (consumeIf('Q')) {
5090
5091
5092
5093
5094
5095
5096
5097 Node *NestedReq = getDerived().parseExpr();
5098 if (NestedReq == nullptr)
5099 return nullptr;
5100 Constraint = make<NestedRequirement>(NestedReq);
5101 }
5102 if (Constraint == nullptr)
5103 return nullptr;
5104 Names.push_back(Constraint);
5105 } while (!consumeIf('E'));
5106
5107 return make<RequiresExpr>(Params, popTrailingNodeArray(ReqsBegin));
5108 }
5109
5110
5111
5112
5113
5114
5115
5116
5117
5118
5119
5120
5121
5122
5123
5124
5125
5126
5127
5128
5129
5130
5131
5132
5133
5134
5135
5136
5137
5138
5139
5140
5141
5142
5143
5144
5145
5146
5147
5148
5149
5150
5151
5152
5153
5154
5155 template <typename Derived, typename Alloc>
5156 Node *AbstractManglingParser<Derived, Alloc>::parseExpr() {
5157 bool Global = consumeIf("gs");
5158
5159 const auto *Op = parseOperatorEncoding();
5160 if (Op) {
5161 auto Sym = Op->getSymbol();
5162 switch (Op->getKind()) {
5163 case OperatorInfo::Binary:
5164
5165 return getDerived().parseBinaryExpr(Sym, Op->getPrecedence());
5166 case OperatorInfo::Prefix:
5167
5168 return getDerived().parsePrefixExpr(Sym, Op->getPrecedence());
5169 case OperatorInfo::Postfix: {
5170
5171 if (consumeIf('_'))
5172 return getDerived().parsePrefixExpr(Sym, Op->getPrecedence());
5173 Node *Ex = getDerived().parseExpr();
5174 if (Ex == nullptr)
5175 return nullptr;
5176 return make<PostfixExpr>(Ex, Sym, Op->getPrecedence());
5177 }
5178 case OperatorInfo::Array: {
5179
5180 Node *Base = getDerived().parseExpr();
5181 if (Base == nullptr)
5182 return nullptr;
5183 Node *Index = getDerived().parseExpr();
5184 if (Index == nullptr)
5185 return nullptr;
5186 return make<ArraySubscriptExpr>(Base, Index, Op->getPrecedence());
5187 }
5188 case OperatorInfo::Member: {
5189
5190 Node *LHS = getDerived().parseExpr();
5191 if (LHS == nullptr)
5192 return nullptr;
5193 Node *RHS = getDerived().parseExpr();
5194 if (RHS == nullptr)
5195 return nullptr;
5196 return make<MemberExpr>(LHS, Sym, RHS, Op->getPrecedence());
5197 }
5198 case OperatorInfo::New: {
5199
5200
5201
5202
5203
5204 size_t Exprs = Names.size();
5205 while (!consumeIf('_')) {
5206 Node *Ex = getDerived().parseExpr();
5207 if (Ex == nullptr)
5208 return nullptr;
5209 Names.push_back(Ex);
5210 }
5211 NodeArray ExprList = popTrailingNodeArray(Exprs);
5212 Node *Ty = getDerived().parseType();
5213 if (Ty == nullptr)
5214 return nullptr;
5215 bool HaveInits = consumeIf("pi");
5216 size_t InitsBegin = Names.size();
5217 while (!consumeIf('E')) {
5218 if (!HaveInits)
5219 return nullptr;
5220 Node *Init = getDerived().parseExpr();
5221 if (Init == nullptr)
5222 return Init;
5223 Names.push_back(Init);
5224 }
5225 NodeArray Inits = popTrailingNodeArray(InitsBegin);
5226 return make<NewExpr>(ExprList, Ty, Inits, Global,
5227 Op->getFlag(), Op->getPrecedence());
5228 }
5229 case OperatorInfo::Del: {
5230
5231 Node *Ex = getDerived().parseExpr();
5232 if (Ex == nullptr)
5233 return nullptr;
5234 return make<DeleteExpr>(Ex, Global, Op->getFlag(),
5235 Op->getPrecedence());
5236 }
5237 case OperatorInfo::Call: {
5238
5239 Node *Callee = getDerived().parseExpr();
5240 if (Callee == nullptr)
5241 return nullptr;
5242 size_t ExprsBegin = Names.size();
5243 while (!consumeIf('E')) {
5244 Node *E = getDerived().parseExpr();
5245 if (E == nullptr)
5246 return nullptr;
5247 Names.push_back(E);
5248 }
5249 return make<CallExpr>(Callee, popTrailingNodeArray(ExprsBegin),
5250 Op->getFlag(), Op->getPrecedence());
5251 }
5252 case OperatorInfo::CCast: {
5253
5254 Node *Ty;
5255 {
5256 ScopedOverride<bool> SaveTemp(TryToParseTemplateArgs, false);
5257 Ty = getDerived().parseType();
5258 }
5259 if (Ty == nullptr)
5260 return nullptr;
5261
5262 size_t ExprsBegin = Names.size();
5263 bool IsMany = consumeIf('_');
5264 while (!consumeIf('E')) {
5265 Node *E = getDerived().parseExpr();
5266 if (E == nullptr)
5267 return E;
5268 Names.push_back(E);
5269 if (!IsMany)
5270 break;
5271 }
5272 NodeArray Exprs = popTrailingNodeArray(ExprsBegin);
5273 if (!IsMany && Exprs.size() != 1)
5274 return nullptr;
5275 return make<ConversionExpr>(Ty, Exprs, Op->getPrecedence());
5276 }
5277 case OperatorInfo::Conditional: {
5278
5279 Node *Cond = getDerived().parseExpr();
5280 if (Cond == nullptr)
5281 return nullptr;
5282 Node *LHS = getDerived().parseExpr();
5283 if (LHS == nullptr)
5284 return nullptr;
5285 Node *RHS = getDerived().parseExpr();
5286 if (RHS == nullptr)
5287 return nullptr;
5288 return make<ConditionalExpr>(Cond, LHS, RHS, Op->getPrecedence());
5289 }
5290 case OperatorInfo::NamedCast: {
5291
5292 Node *Ty = getDerived().parseType();
5293 if (Ty == nullptr)
5294 return nullptr;
5295 Node *Ex = getDerived().parseExpr();
5296 if (Ex == nullptr)
5297 return nullptr;
5298 return make<CastExpr>(Sym, Ty, Ex, Op->getPrecedence());
5299 }
5300 case OperatorInfo::OfIdOp: {
5301
5302 Node *Arg =
5303 Op->getFlag() ? getDerived().parseType() : getDerived().parseExpr();
5304 if (!Arg)
5305 return nullptr;
5306 return make<EnclosingExpr>(Sym, Arg, Op->getPrecedence());
5307 }
5308 case OperatorInfo::NameOnly: {
5309
5310 return nullptr;
5311 }
5312 }
5313 DEMANGLE_UNREACHABLE;
5314 }
5315
5316 if (numLeft() < 2)
5317 return nullptr;
5318
5319 if (look() == 'L')
5320 return getDerived().parseExprPrimary();
5321 if (look() == 'T')
5322 return getDerived().parseTemplateParam();
5323 if (look() == 'f') {
5324
5325 if (look(1) == 'p' || (look(1) == 'L' && std::isdigit(look(2))))
5326 return getDerived().parseFunctionParam();
5327 return getDerived().parseFoldExpr();
5328 }
5329 if (consumeIf("il")) {
5330 size_t InitsBegin = Names.size();
5331 while (!consumeIf('E')) {
5332 Node *E = getDerived().parseBracedExpr();
5333 if (E == nullptr)
5334 return nullptr;
5335 Names.push_back(E);
5336 }
5337 return make<InitListExpr>(nullptr, popTrailingNodeArray(InitsBegin));
5338 }
5339 if (consumeIf("mc"))
5340 return parsePointerToMemberConversionExpr(Node::Prec::Unary);
5341 if (consumeIf("nx")) {
5342 Node *Ex = getDerived().parseExpr();
5343 if (Ex == nullptr)
5344 return Ex;
5345 return make<EnclosingExpr>("noexcept ", Ex, Node::Prec::Unary);
5346 }
5347 if (look() == 'r' && (look(1) == 'q' || look(1) == 'Q'))
5348 return parseRequiresExpr();
5349 if (consumeIf("so"))
5350 return parseSubobjectExpr();
5351 if (consumeIf("sp")) {
5352 Node *Child = getDerived().parseExpr();
5353 if (Child == nullptr)
5354 return nullptr;
5355 return make<ParameterPackExpansion>(Child);
5356 }
5357 if (consumeIf("sZ")) {
5358 if (look() == 'T') {
5359 Node *R = getDerived().parseTemplateParam();
5360 if (R == nullptr)
5361 return nullptr;
5362 return make<SizeofParamPackExpr>(R);
5363 }
5364 Node *FP = getDerived().parseFunctionParam();
5365 if (FP == nullptr)
5366 return nullptr;
5367 return make<EnclosingExpr>("sizeof... ", FP);
5368 }
5369 if (consumeIf("sP")) {
5370 size_t ArgsBegin = Names.size();
5371 while (!consumeIf('E')) {
5372 Node *Arg = getDerived().parseTemplateArg();
5373 if (Arg == nullptr)
5374 return nullptr;
5375 Names.push_back(Arg);
5376 }
5377 auto *Pack = make<NodeArrayNode>(popTrailingNodeArray(ArgsBegin));
5378 if (!Pack)
5379 return nullptr;
5380 return make<EnclosingExpr>("sizeof... ", Pack);
5381 }
5382 if (consumeIf("tl")) {
5383 Node *Ty = getDerived().parseType();
5384 if (Ty == nullptr)
5385 return nullptr;
5386 size_t InitsBegin = Names.size();
5387 while (!consumeIf('E')) {
5388 Node *E = getDerived().parseBracedExpr();
5389 if (E == nullptr)
5390 return nullptr;
5391 Names.push_back(E);
5392 }
5393 return make<InitListExpr>(Ty, popTrailingNodeArray(InitsBegin));
5394 }
5395 if (consumeIf("tr"))
5396 return make<NameType>("throw");
5397 if (consumeIf("tw")) {
5398 Node *Ex = getDerived().parseExpr();
5399 if (Ex == nullptr)
5400 return nullptr;
5401 return make<ThrowExpr>(Ex);
5402 }
5403 if (consumeIf('u')) {
5404 Node *Name = getDerived().parseSourceName(nullptr);
5405 if (!Name)
5406 return nullptr;
5407
5408
5409
5410
5411
5412 bool IsUUID = false;
5413 Node *UUID = nullptr;
5414 if (Name->getBaseName() == "__uuidof") {
5415 if (consumeIf('t')) {
5416 UUID = getDerived().parseType();
5417 IsUUID = true;
5418 } else if (consumeIf('z')) {
5419 UUID = getDerived().parseExpr();
5420 IsUUID = true;
5421 }
5422 }
5423 size_t ExprsBegin = Names.size();
5424 if (IsUUID) {
5425 if (UUID == nullptr)
5426 return nullptr;
5427 Names.push_back(UUID);
5428 } else {
5429 while (!consumeIf('E')) {
5430 Node *E = getDerived().parseTemplateArg();
5431 if (E == nullptr)
5432 return E;
5433 Names.push_back(E);
5434 }
5435 }
5436 return make<CallExpr>(Name, popTrailingNodeArray(ExprsBegin),
5437 false, Node::Prec::Postfix);
5438 }
5439
5440
5441 return getDerived().parseUnresolvedName(Global);
5442 }
5443
5444
5445
5446
5447
5448
5449
5450
5451
5452 template <typename Alloc, typename Derived>
5453 bool AbstractManglingParser<Alloc, Derived>::parseCallOffset() {
5454
5455
5456 if (consumeIf('h'))
5457 return parseNumber(true).empty() || !consumeIf('_');
5458 if (consumeIf('v'))
5459 return parseNumber(true).empty() || !consumeIf('_') ||
5460 parseNumber(true).empty() || !consumeIf('_');
5461 return true;
5462 }
5463
5464
5465
5466
5467
5468
5469
5470
5471
5472
5473
5474
5475
5476
5477
5478
5479
5480
5481
5482
5483
5484
5485 template <typename Derived, typename Alloc>
5486 Node *AbstractManglingParser<Derived, Alloc>::parseSpecialName() {
5487 switch (look()) {
5488 case 'T':
5489 switch (look(1)) {
5490
5491
5492
5493 case 'A': {
5494 First += 2;
5495 Node *Arg = getDerived().parseTemplateArg();
5496 if (Arg == nullptr)
5497 return nullptr;
5498 return make<SpecialName>("template parameter object for ", Arg);
5499 }
5500
5501 case 'V': {
5502 First += 2;
5503 Node *Ty = getDerived().parseType();
5504 if (Ty == nullptr)
5505 return nullptr;
5506 return make<SpecialName>("vtable for ", Ty);
5507 }
5508
5509 case 'T': {
5510 First += 2;
5511 Node *Ty = getDerived().parseType();
5512 if (Ty == nullptr)
5513 return nullptr;
5514 return make<SpecialName>("VTT for ", Ty);
5515 }
5516
5517 case 'I': {
5518 First += 2;
5519 Node *Ty = getDerived().parseType();
5520 if (Ty == nullptr)
5521 return nullptr;
5522 return make<SpecialName>("typeinfo for ", Ty);
5523 }
5524
5525 case 'S': {
5526 First += 2;
5527 Node *Ty = getDerived().parseType();
5528 if (Ty == nullptr)
5529 return nullptr;
5530 return make<SpecialName>("typeinfo name for ", Ty);
5531 }
5532
5533 case 'c': {
5534 First += 2;
5535 if (parseCallOffset() || parseCallOffset())
5536 return nullptr;
5537 Node *Encoding = getDerived().parseEncoding();
5538 if (Encoding == nullptr)
5539 return nullptr;
5540 return make<SpecialName>("covariant return thunk to ", Encoding);
5541 }
5542
5543
5544 case 'C': {
5545 First += 2;
5546 Node *FirstType = getDerived().parseType();
5547 if (FirstType == nullptr)
5548 return nullptr;
5549 if (parseNumber(true).empty() || !consumeIf('_'))
5550 return nullptr;
5551 Node *SecondType = getDerived().parseType();
5552 if (SecondType == nullptr)
5553 return nullptr;
5554 return make<CtorVtableSpecialName>(SecondType, FirstType);
5555 }
5556
5557 case 'W': {
5558 First += 2;
5559 Node *Name = getDerived().parseName();
5560 if (Name == nullptr)
5561 return nullptr;
5562 return make<SpecialName>("thread-local wrapper routine for ", Name);
5563 }
5564
5565 case 'H': {
5566 First += 2;
5567 Node *Name = getDerived().parseName();
5568 if (Name == nullptr)
5569 return nullptr;
5570 return make<SpecialName>("thread-local initialization routine for ", Name);
5571 }
5572
5573 default: {
5574 ++First;
5575 bool IsVirt = look() == 'v';
5576 if (parseCallOffset())
5577 return nullptr;
5578 Node *BaseEncoding = getDerived().parseEncoding();
5579 if (BaseEncoding == nullptr)
5580 return nullptr;
5581 if (IsVirt)
5582 return make<SpecialName>("virtual thunk to ", BaseEncoding);
5583 else
5584 return make<SpecialName>("non-virtual thunk to ", BaseEncoding);
5585 }
5586 }
5587 case 'G':
5588 switch (look(1)) {
5589
5590 case 'V': {
5591 First += 2;
5592 Node *Name = getDerived().parseName();
5593 if (Name == nullptr)
5594 return nullptr;
5595 return make<SpecialName>("guard variable for ", Name);
5596 }
5597
5598
5599
5600 case 'R': {
5601 First += 2;
5602 Node *Name = getDerived().parseName();
5603 if (Name == nullptr)
5604 return nullptr;
5605 size_t Count;
5606 bool ParsedSeqId = !parseSeqId(&Count);
5607 if (!consumeIf('_') && ParsedSeqId)
5608 return nullptr;
5609 return make<SpecialName>("reference temporary for ", Name);
5610 }
5611
5612 case 'I': {
5613 First += 2;
5614 ModuleName *Module = nullptr;
5615 if (getDerived().parseModuleNameOpt(Module))
5616 return nullptr;
5617 if (Module == nullptr)
5618 return nullptr;
5619 return make<SpecialName>("initializer for module ", Module);
5620 }
5621 }
5622 }
5623 return nullptr;
5624 }
5625
5626
5627
5628
5629
5630 template <typename Derived, typename Alloc>
5631 Node *AbstractManglingParser<Derived, Alloc>::parseEncoding(bool ParseParams) {
5632
5633
5634 SaveTemplateParams SaveTemplateParamsScope(this);
5635
5636 if (look() == 'G' || look() == 'T')
5637 return getDerived().parseSpecialName();
5638
5639 auto IsEndOfEncoding = [&] {
5640
5641
5642
5643 return numLeft() == 0 || look() == 'E' || look() == '.' || look() == '_';
5644 };
5645
5646 NameState NameInfo(this);
5647 Node *Name = getDerived().parseName(&NameInfo);
5648 if (Name == nullptr)
5649 return nullptr;
5650
5651 if (resolveForwardTemplateRefs(NameInfo))
5652 return nullptr;
5653
5654 if (IsEndOfEncoding())
5655 return Name;
5656
5657
5658
5659
5660
5661 if (!ParseParams) {
5662 while (consume())
5663 ;
5664 return Name;
5665 }
5666
5667 Node *Attrs = nullptr;
5668 if (consumeIf("Ua9enable_ifI")) {
5669 size_t BeforeArgs = Names.size();
5670 while (!consumeIf('E')) {
5671 Node *Arg = getDerived().parseTemplateArg();
5672 if (Arg == nullptr)
5673 return nullptr;
5674 Names.push_back(Arg);
5675 }
5676 Attrs = make<EnableIfAttr>(popTrailingNodeArray(BeforeArgs));
5677 if (!Attrs)
5678 return nullptr;
5679 }
5680
5681 Node *ReturnType = nullptr;
5682 if (!NameInfo.CtorDtorConversion && NameInfo.EndsWithTemplateArgs) {
5683 ReturnType = getDerived().parseType();
5684 if (ReturnType == nullptr)
5685 return nullptr;
5686 }
5687
5688 NodeArray Params;
5689 if (!consumeIf('v')) {
5690 size_t ParamsBegin = Names.size();
5691 do {
5692 Node *Ty = getDerived().parseType();
5693 if (Ty == nullptr)
5694 return nullptr;
5695
5696 const bool IsFirstParam = ParamsBegin == Names.size();
5697 if (NameInfo.HasExplicitObjectParameter && IsFirstParam)
5698 Ty = make<ExplicitObjectParameter>(Ty);
5699
5700 if (Ty == nullptr)
5701 return nullptr;
5702
5703 Names.push_back(Ty);
5704 } while (!IsEndOfEncoding() && look() != 'Q');
5705 Params = popTrailingNodeArray(ParamsBegin);
5706 }
5707
5708 Node *Requires = nullptr;
5709 if (consumeIf('Q')) {
5710 Requires = getDerived().parseConstraintExpr();
5711 if (!Requires)
5712 return nullptr;
5713 }
5714
5715 return make<FunctionEncoding>(ReturnType, Name, Params, Attrs, Requires,
5716 NameInfo.CVQualifiers,
5717 NameInfo.ReferenceQualifier);
5718 }
5719
5720 template <class Float>
5721 struct FloatData;
5722
5723 template <>
5724 struct FloatData<float>
5725 {
5726 static const size_t mangled_size = 8;
5727 static const size_t max_demangled_size = 24;
5728 static constexpr const char* spec = "%af";
5729 };
5730
5731 template <>
5732 struct FloatData<double>
5733 {
5734 static const size_t mangled_size = 16;
5735 static const size_t max_demangled_size = 32;
5736 static constexpr const char* spec = "%a";
5737 };
5738
5739 template <>
5740 struct FloatData<long double>
5741 {
5742 #if defined(__mips__) && defined(__mips_n64) || defined(__aarch64__) || \
5743 defined(__wasm__) || defined(__riscv) || defined(__loongarch__) || \
5744 defined(__ve__)
5745 static const size_t mangled_size = 32;
5746 #elif defined(__arm__) || defined(__mips__) || defined(__hexagon__)
5747 static const size_t mangled_size = 16;
5748 #else
5749 static const size_t mangled_size = 20;
5750 #endif
5751
5752
5753
5754
5755
5756 static const size_t max_demangled_size = 42;
5757 static constexpr const char *spec = "%LaL";
5758 };
5759
5760 template <typename Alloc, typename Derived>
5761 template <class Float>
5762 Node *AbstractManglingParser<Alloc, Derived>::parseFloatingLiteral() {
5763 const size_t N = FloatData<Float>::mangled_size;
5764 if (numLeft() <= N)
5765 return nullptr;
5766 std::string_view Data(First, N);
5767 for (char C : Data)
5768 if (!(C >= '0' && C <= '9') && !(C >= 'a' && C <= 'f'))
5769 return nullptr;
5770 First += N;
5771 if (!consumeIf('E'))
5772 return nullptr;
5773 return make<FloatLiteralImpl<Float>>(Data);
5774 }
5775
5776
5777 template <typename Alloc, typename Derived>
5778 bool AbstractManglingParser<Alloc, Derived>::parseSeqId(size_t *Out) {
5779 if (!(look() >= '0' && look() <= '9') &&
5780 !(look() >= 'A' && look() <= 'Z'))
5781 return true;
5782
5783 size_t Id = 0;
5784 while (true) {
5785 if (look() >= '0' && look() <= '9') {
5786 Id *= 36;
5787 Id += static_cast<size_t>(look() - '0');
5788 } else if (look() >= 'A' && look() <= 'Z') {
5789 Id *= 36;
5790 Id += static_cast<size_t>(look() - 'A') + 10;
5791 } else {
5792 *Out = Id;
5793 return false;
5794 }
5795 ++First;
5796 }
5797 }
5798
5799
5800
5801
5802
5803
5804
5805
5806
5807
5808
5809
5810 template <typename Derived, typename Alloc>
5811 Node *AbstractManglingParser<Derived, Alloc>::parseSubstitution() {
5812 if (!consumeIf('S'))
5813 return nullptr;
5814
5815 if (look() >= 'a' && look() <= 'z') {
5816 SpecialSubKind Kind;
5817 switch (look()) {
5818 case 'a':
5819 Kind = SpecialSubKind::allocator;
5820 break;
5821 case 'b':
5822 Kind = SpecialSubKind::basic_string;
5823 break;
5824 case 'd':
5825 Kind = SpecialSubKind::iostream;
5826 break;
5827 case 'i':
5828 Kind = SpecialSubKind::istream;
5829 break;
5830 case 'o':
5831 Kind = SpecialSubKind::ostream;
5832 break;
5833 case 's':
5834 Kind = SpecialSubKind::string;
5835 break;
5836 default:
5837 return nullptr;
5838 }
5839 ++First;
5840 auto *SpecialSub = make<SpecialSubstitution>(Kind);
5841 if (!SpecialSub)
5842 return nullptr;
5843
5844
5845
5846
5847 Node *WithTags = getDerived().parseAbiTags(SpecialSub);
5848 if (WithTags != SpecialSub) {
5849 Subs.push_back(WithTags);
5850 SpecialSub = WithTags;
5851 }
5852 return SpecialSub;
5853 }
5854
5855
5856 if (consumeIf('_')) {
5857 if (Subs.empty())
5858 return nullptr;
5859 return Subs[0];
5860 }
5861
5862
5863 size_t Index = 0;
5864 if (parseSeqId(&Index))
5865 return nullptr;
5866 ++Index;
5867 if (!consumeIf('_') || Index >= Subs.size())
5868 return nullptr;
5869 return Subs[Index];
5870 }
5871
5872
5873
5874
5875
5876 template <typename Derived, typename Alloc>
5877 Node *AbstractManglingParser<Derived, Alloc>::parseTemplateParam() {
5878 const char *Begin = First;
5879 if (!consumeIf('T'))
5880 return nullptr;
5881
5882 size_t Level = 0;
5883 if (consumeIf('L')) {
5884 if (parsePositiveInteger(&Level))
5885 return nullptr;
5886 ++Level;
5887 if (!consumeIf('_'))
5888 return nullptr;
5889 }
5890
5891 size_t Index = 0;
5892 if (!consumeIf('_')) {
5893 if (parsePositiveInteger(&Index))
5894 return nullptr;
5895 ++Index;
5896 if (!consumeIf('_'))
5897 return nullptr;
5898 }
5899
5900
5901
5902
5903
5904 if (HasIncompleteTemplateParameterTracking) {
5905 return make<NameType>(std::string_view(Begin, First - 1 - Begin));
5906 }
5907
5908
5909
5910
5911
5912 if (PermitForwardTemplateReferences && Level == 0) {
5913 Node *ForwardRef = make<ForwardTemplateReference>(Index);
5914 if (!ForwardRef)
5915 return nullptr;
5916 DEMANGLE_ASSERT(ForwardRef->getKind() == Node::KForwardTemplateReference,
5917 "");
5918 ForwardTemplateRefs.push_back(
5919 static_cast<ForwardTemplateReference *>(ForwardRef));
5920 return ForwardRef;
5921 }
5922
5923 if (Level >= TemplateParams.size() || !TemplateParams[Level] ||
5924 Index >= TemplateParams[Level]->size()) {
5925
5926
5927 if (ParsingLambdaParamsAtLevel == Level && Level <= TemplateParams.size()) {
5928
5929
5930 if (Level == TemplateParams.size())
5931 TemplateParams.push_back(nullptr);
5932 return make<NameType>("auto");
5933 }
5934
5935 return nullptr;
5936 }
5937
5938 return (*TemplateParams[Level])[Index];
5939 }
5940
5941
5942
5943
5944
5945
5946 template <typename Derived, typename Alloc>
5947 Node *AbstractManglingParser<Derived, Alloc>::parseTemplateParamDecl(
5948 TemplateParamList *Params) {
5949 auto InventTemplateParamName = [&](TemplateParamKind Kind) {
5950 unsigned Index = NumSyntheticTemplateParameters[(int)Kind]++;
5951 Node *N = make<SyntheticTemplateParamName>(Kind, Index);
5952 if (N && Params)
5953 Params->push_back(N);
5954 return N;
5955 };
5956
5957 if (consumeIf("Ty")) {
5958 Node *Name = InventTemplateParamName(TemplateParamKind::Type);
5959 if (!Name)
5960 return nullptr;
5961 return make<TypeTemplateParamDecl>(Name);
5962 }
5963
5964 if (consumeIf("Tk")) {
5965
5966
5967
5968
5969 ScopedOverride<bool> SaveIncompleteTemplateParameterTrackingExpr(
5970 HasIncompleteTemplateParameterTracking, true);
5971 Node *Constraint = getDerived().parseName();
5972 if (!Constraint)
5973 return nullptr;
5974 Node *Name = InventTemplateParamName(TemplateParamKind::Type);
5975 if (!Name)
5976 return nullptr;
5977 return make<ConstrainedTypeTemplateParamDecl>(Constraint, Name);
5978 }
5979
5980 if (consumeIf("Tn")) {
5981 Node *Name = InventTemplateParamName(TemplateParamKind::NonType);
5982 if (!Name)
5983 return nullptr;
5984 Node *Type = parseType();
5985 if (!Type)
5986 return nullptr;
5987 return make<NonTypeTemplateParamDecl>(Name, Type);
5988 }
5989
5990 if (consumeIf("Tt")) {
5991 Node *Name = InventTemplateParamName(TemplateParamKind::Template);
5992 if (!Name)
5993 return nullptr;
5994 size_t ParamsBegin = Names.size();
5995 ScopedTemplateParamList TemplateTemplateParamParams(this);
5996 Node *Requires = nullptr;
5997 while (!consumeIf('E')) {
5998 Node *P = parseTemplateParamDecl(TemplateTemplateParamParams.params());
5999 if (!P)
6000 return nullptr;
6001 Names.push_back(P);
6002 if (consumeIf('Q')) {
6003 Requires = getDerived().parseConstraintExpr();
6004 if (Requires == nullptr || !consumeIf('E'))
6005 return nullptr;
6006 break;
6007 }
6008 }
6009 NodeArray InnerParams = popTrailingNodeArray(ParamsBegin);
6010 return make<TemplateTemplateParamDecl>(Name, InnerParams, Requires);
6011 }
6012
6013 if (consumeIf("Tp")) {
6014 Node *P = parseTemplateParamDecl(Params);
6015 if (!P)
6016 return nullptr;
6017 return make<TemplateParamPackDecl>(P);
6018 }
6019
6020 return nullptr;
6021 }
6022
6023
6024
6025
6026
6027
6028
6029 template <typename Derived, typename Alloc>
6030 Node *AbstractManglingParser<Derived, Alloc>::parseTemplateArg() {
6031 switch (look()) {
6032 case 'X': {
6033 ++First;
6034 Node *Arg = getDerived().parseExpr();
6035 if (Arg == nullptr || !consumeIf('E'))
6036 return nullptr;
6037 return Arg;
6038 }
6039 case 'J': {
6040 ++First;
6041 size_t ArgsBegin = Names.size();
6042 while (!consumeIf('E')) {
6043 Node *Arg = getDerived().parseTemplateArg();
6044 if (Arg == nullptr)
6045 return nullptr;
6046 Names.push_back(Arg);
6047 }
6048 NodeArray Args = popTrailingNodeArray(ArgsBegin);
6049 return make<TemplateArgumentPack>(Args);
6050 }
6051 case 'L': {
6052
6053 if (look(1) == 'Z') {
6054 First += 2;
6055 Node *Arg = getDerived().parseEncoding();
6056 if (Arg == nullptr || !consumeIf('E'))
6057 return nullptr;
6058 return Arg;
6059 }
6060
6061 return getDerived().parseExprPrimary();
6062 }
6063 case 'T': {
6064
6065 if (!getDerived().isTemplateParamDecl())
6066 return getDerived().parseType();
6067 Node *Param = getDerived().parseTemplateParamDecl(nullptr);
6068 if (!Param)
6069 return nullptr;
6070 Node *Arg = getDerived().parseTemplateArg();
6071 if (!Arg)
6072 return nullptr;
6073 return make<TemplateParamQualifiedArg>(Param, Arg);
6074 }
6075 default:
6076 return getDerived().parseType();
6077 }
6078 }
6079
6080
6081
6082 template <typename Derived, typename Alloc>
6083 Node *
6084 AbstractManglingParser<Derived, Alloc>::parseTemplateArgs(bool TagTemplates) {
6085 if (!consumeIf('I'))
6086 return nullptr;
6087
6088
6089
6090 if (TagTemplates) {
6091 TemplateParams.clear();
6092 TemplateParams.push_back(&OuterTemplateParams);
6093 OuterTemplateParams.clear();
6094 }
6095
6096 size_t ArgsBegin = Names.size();
6097 Node *Requires = nullptr;
6098 while (!consumeIf('E')) {
6099 if (TagTemplates) {
6100 Node *Arg = getDerived().parseTemplateArg();
6101 if (Arg == nullptr)
6102 return nullptr;
6103 Names.push_back(Arg);
6104 Node *TableEntry = Arg;
6105 if (Arg->getKind() == Node::KTemplateParamQualifiedArg) {
6106 TableEntry =
6107 static_cast<TemplateParamQualifiedArg *>(TableEntry)->getArg();
6108 }
6109 if (Arg->getKind() == Node::KTemplateArgumentPack) {
6110 TableEntry = make<ParameterPack>(
6111 static_cast<TemplateArgumentPack*>(TableEntry)->getElements());
6112 if (!TableEntry)
6113 return nullptr;
6114 }
6115 OuterTemplateParams.push_back(TableEntry);
6116 } else {
6117 Node *Arg = getDerived().parseTemplateArg();
6118 if (Arg == nullptr)
6119 return nullptr;
6120 Names.push_back(Arg);
6121 }
6122 if (consumeIf('Q')) {
6123 Requires = getDerived().parseConstraintExpr();
6124 if (!Requires || !consumeIf('E'))
6125 return nullptr;
6126 break;
6127 }
6128 }
6129 return make<TemplateArgs>(popTrailingNodeArray(ArgsBegin), Requires);
6130 }
6131
6132
6133
6134
6135
6136
6137 template <typename Derived, typename Alloc>
6138 Node *AbstractManglingParser<Derived, Alloc>::parse(bool ParseParams) {
6139 if (consumeIf("_Z") || consumeIf("__Z")) {
6140 Node *Encoding = getDerived().parseEncoding(ParseParams);
6141 if (Encoding == nullptr)
6142 return nullptr;
6143 if (look() == '.') {
6144 Encoding =
6145 make<DotSuffix>(Encoding, std::string_view(First, Last - First));
6146 First = Last;
6147 }
6148 if (numLeft() != 0)
6149 return nullptr;
6150 return Encoding;
6151 }
6152
6153 if (consumeIf("___Z") || consumeIf("____Z")) {
6154 Node *Encoding = getDerived().parseEncoding(ParseParams);
6155 if (Encoding == nullptr || !consumeIf("_block_invoke"))
6156 return nullptr;
6157 bool RequireNumber = consumeIf('_');
6158 if (parseNumber().empty() && RequireNumber)
6159 return nullptr;
6160 if (look() == '.')
6161 First = Last;
6162 if (numLeft() != 0)
6163 return nullptr;
6164 return make<SpecialName>("invocation function for block in ", Encoding);
6165 }
6166
6167 Node *Ty = getDerived().parseType();
6168 if (numLeft() != 0)
6169 return nullptr;
6170 return Ty;
6171 }
6172
6173 template <typename Alloc>
6174 struct ManglingParser : AbstractManglingParser<ManglingParser<Alloc>, Alloc> {
6175 using AbstractManglingParser<ManglingParser<Alloc>,
6176 Alloc>::AbstractManglingParser;
6177 };
6178
6179 DEMANGLE_NAMESPACE_END
6180
6181 #if defined(__clang__)
6182 #pragma clang diagnostic pop
6183 #endif
6184
6185 #endif