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