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