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