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 bool TryToParseTemplateArgs = true; 2166 bool PermitForwardTemplateReferences = false; 2167 bool ParsingLambdaParams = false; 2168 2169 Alloc ASTAllocator; 2170 2171 AbstractManglingParser(const char *First_, const char *Last_) 2172 : First(First_), Last(Last_) {} 2173 2174 Derived &getDerived() { return static_cast<Derived &>(*this); } 2175 2176 void reset(const char *First_, const char *Last_) { 2177 First = First_; 2178 Last = Last_; 2179 Names.clear(); 2180 Subs.clear(); 2181 TemplateParams.clear(); 2182 ParsingLambdaParams = false; 2183 TryToParseTemplateArgs = true; 2184 PermitForwardTemplateReferences = false; 2185 ASTAllocator.reset(); 2186 } 2187 2188 template <class T, class... Args> Node *make(Args &&... args) { 2189 return ASTAllocator.template makeNode<T>(std::forward<Args>(args)...); 2190 } 2191 2192 template <class It> NodeArray makeNodeArray(It begin, It end) { 2193 size_t sz = static_cast<size_t>(end - begin); 2194 void *mem = ASTAllocator.allocateNodeArray(sz); 2195 Node **data = new (mem) Node *[sz]; 2196 std::copy(begin, end, data); 2197 return NodeArray(data, sz); 2198 } 2199 2200 NodeArray popTrailingNodeArray(size_t FromPosition) { 2201 assert(FromPosition <= Names.size()); 2202 NodeArray res = 2203 makeNodeArray(Names.begin() + (long)FromPosition, Names.end()); 2204 Names.dropBack(FromPosition); 2205 return res; 2206 } 2207 2208 bool consumeIf(StringView S) { 2209 if (StringView(First, Last).startsWith(S)) { 2210 First += S.size(); 2211 return true; 2212 } 2213 return false; 2214 } 2215 2216 bool consumeIf(char C) { 2217 if (First != Last && *First == C) { 2218 ++First; 2219 return true; 2220 } 2221 return false; 2222 } 2223 2224 char consume() { return First != Last ? *First++ : '\0'; } 2225 2226 char look(unsigned Lookahead = 0) { 2227 if (static_cast<size_t>(Last - First) <= Lookahead) 2228 return '\0'; 2229 return First[Lookahead]; 2230 } 2231 2232 size_t numLeft() const { return static_cast<size_t>(Last - First); } 2233 2234 StringView parseNumber(bool AllowNegative = false); 2235 Qualifiers parseCVQualifiers(); 2236 bool parsePositiveInteger(size_t *Out); 2237 StringView parseBareSourceName(); 2238 2239 bool parseSeqId(size_t *Out); 2240 Node *parseSubstitution(); 2241 Node *parseTemplateParam(); 2242 Node *parseTemplateArgs(bool TagTemplates = false); 2243 Node *parseTemplateArg(); 2244 2245 /// Parse the <expr> production. 2246 Node *parseExpr(); 2247 Node *parsePrefixExpr(StringView Kind); 2248 Node *parseBinaryExpr(StringView Kind); 2249 Node *parseIntegerLiteral(StringView Lit); 2250 Node *parseExprPrimary(); 2251 template <class Float> Node *parseFloatingLiteral(); 2252 Node *parseFunctionParam(); 2253 Node *parseNewExpr(); 2254 Node *parseConversionExpr(); 2255 Node *parseBracedExpr(); 2256 Node *parseFoldExpr(); 2257 2258 /// Parse the <type> production. 2259 Node *parseType(); 2260 Node *parseFunctionType(); 2261 Node *parseVectorType(); 2262 Node *parseDecltype(); 2263 Node *parseArrayType(); 2264 Node *parsePointerToMemberType(); 2265 Node *parseClassEnumType(); 2266 Node *parseQualifiedType(); 2267 2268 Node *parseEncoding(); 2269 bool parseCallOffset(); 2270 Node *parseSpecialName(); 2271 2272 /// Holds some extra information about a <name> that is being parsed. This 2273 /// information is only pertinent if the <name> refers to an <encoding>. 2274 struct NameState { 2275 bool CtorDtorConversion = false; 2276 bool EndsWithTemplateArgs = false; 2277 Qualifiers CVQualifiers = QualNone; 2278 FunctionRefQual ReferenceQualifier = FrefQualNone; 2279 size_t ForwardTemplateRefsBegin; 2280 2281 NameState(AbstractManglingParser *Enclosing) 2282 : ForwardTemplateRefsBegin(Enclosing->ForwardTemplateRefs.size()) {} 2283 }; 2284 2285 bool resolveForwardTemplateRefs(NameState &State) { 2286 size_t I = State.ForwardTemplateRefsBegin; 2287 size_t E = ForwardTemplateRefs.size(); 2288 for (; I < E; ++I) { 2289 size_t Idx = ForwardTemplateRefs[I]->Index; 2290 if (Idx >= TemplateParams.size()) 2291 return true; 2292 ForwardTemplateRefs[I]->Ref = TemplateParams[Idx]; 2293 } 2294 ForwardTemplateRefs.dropBack(State.ForwardTemplateRefsBegin); 2295 return false; 2296 } 2297 2298 /// Parse the <name> production> 2299 Node *parseName(NameState *State = nullptr); 2300 Node *parseLocalName(NameState *State); 2301 Node *parseOperatorName(NameState *State); 2302 Node *parseUnqualifiedName(NameState *State); 2303 Node *parseUnnamedTypeName(NameState *State); 2304 Node *parseSourceName(NameState *State); 2305 Node *parseUnscopedName(NameState *State); 2306 Node *parseNestedName(NameState *State); 2307 Node *parseCtorDtorName(Node *&SoFar, NameState *State); 2308 2309 Node *parseAbiTags(Node *N); 2310 2311 /// Parse the <unresolved-name> production. 2312 Node *parseUnresolvedName(); 2313 Node *parseSimpleId(); 2314 Node *parseBaseUnresolvedName(); 2315 Node *parseUnresolvedType(); 2316 Node *parseDestructorName(); 2317 2318 /// Top-level entry point into the parser. 2319 Node *parse(); 2320 }; 2321 2322 const char* parse_discriminator(const char* first, const char* last); 2323 2324 // <name> ::= <nested-name> // N 2325 // ::= <local-name> # See Scope Encoding below // Z 2326 // ::= <unscoped-template-name> <template-args> 2327 // ::= <unscoped-name> 2328 // 2329 // <unscoped-template-name> ::= <unscoped-name> 2330 // ::= <substitution> 2331 template <typename Derived, typename Alloc> 2332 Node *AbstractManglingParser<Derived, Alloc>::parseName(NameState *State) { 2333 consumeIf('L'); // extension 2334 2335 if (look() == 'N') 2336 return getDerived().parseNestedName(State); 2337 if (look() == 'Z') 2338 return getDerived().parseLocalName(State); 2339 2340 // ::= <unscoped-template-name> <template-args> 2341 if (look() == 'S' && look(1) != 't') { 2342 Node *S = getDerived().parseSubstitution(); 2343 if (S == nullptr) 2344 return nullptr; 2345 if (look() != 'I') 2346 return nullptr; 2347 Node *TA = getDerived().parseTemplateArgs(State != nullptr); 2348 if (TA == nullptr) 2349 return nullptr; 2350 if (State) State->EndsWithTemplateArgs = true; 2351 return make<NameWithTemplateArgs>(S, TA); 2352 } 2353 2354 Node *N = getDerived().parseUnscopedName(State); 2355 if (N == nullptr) 2356 return nullptr; 2357 // ::= <unscoped-template-name> <template-args> 2358 if (look() == 'I') { 2359 Subs.push_back(N); 2360 Node *TA = getDerived().parseTemplateArgs(State != nullptr); 2361 if (TA == nullptr) 2362 return nullptr; 2363 if (State) State->EndsWithTemplateArgs = true; 2364 return make<NameWithTemplateArgs>(N, TA); 2365 } 2366 // ::= <unscoped-name> 2367 return N; 2368 } 2369 2370 // <local-name> := Z <function encoding> E <entity name> [<discriminator>] 2371 // := Z <function encoding> E s [<discriminator>] 2372 // := Z <function encoding> Ed [ <parameter number> ] _ <entity name> 2373 template <typename Derived, typename Alloc> 2374 Node *AbstractManglingParser<Derived, Alloc>::parseLocalName(NameState *State) { 2375 if (!consumeIf('Z')) 2376 return nullptr; 2377 Node *Encoding = getDerived().parseEncoding(); 2378 if (Encoding == nullptr || !consumeIf('E')) 2379 return nullptr; 2380 2381 if (consumeIf('s')) { 2382 First = parse_discriminator(First, Last); 2383 auto *StringLitName = make<NameType>("string literal"); 2384 if (!StringLitName) 2385 return nullptr; 2386 return make<LocalName>(Encoding, StringLitName); 2387 } 2388 2389 if (consumeIf('d')) { 2390 parseNumber(true); 2391 if (!consumeIf('_')) 2392 return nullptr; 2393 Node *N = getDerived().parseName(State); 2394 if (N == nullptr) 2395 return nullptr; 2396 return make<LocalName>(Encoding, N); 2397 } 2398 2399 Node *Entity = getDerived().parseName(State); 2400 if (Entity == nullptr) 2401 return nullptr; 2402 First = parse_discriminator(First, Last); 2403 return make<LocalName>(Encoding, Entity); 2404 } 2405 2406 // <unscoped-name> ::= <unqualified-name> 2407 // ::= St <unqualified-name> # ::std:: 2408 // extension ::= StL<unqualified-name> 2409 template <typename Derived, typename Alloc> 2410 Node * 2411 AbstractManglingParser<Derived, Alloc>::parseUnscopedName(NameState *State) { 2412 if (consumeIf("StL") || consumeIf("St")) { 2413 Node *R = getDerived().parseUnqualifiedName(State); 2414 if (R == nullptr) 2415 return nullptr; 2416 return make<StdQualifiedName>(R); 2417 } 2418 return getDerived().parseUnqualifiedName(State); 2419 } 2420 2421 // <unqualified-name> ::= <operator-name> [abi-tags] 2422 // ::= <ctor-dtor-name> 2423 // ::= <source-name> 2424 // ::= <unnamed-type-name> 2425 // ::= DC <source-name>+ E # structured binding declaration 2426 template <typename Derived, typename Alloc> 2427 Node * 2428 AbstractManglingParser<Derived, Alloc>::parseUnqualifiedName(NameState *State) { 2429 // <ctor-dtor-name>s are special-cased in parseNestedName(). 2430 Node *Result; 2431 if (look() == 'U') 2432 Result = getDerived().parseUnnamedTypeName(State); 2433 else if (look() >= '1' && look() <= '9') 2434 Result = getDerived().parseSourceName(State); 2435 else if (consumeIf("DC")) { 2436 size_t BindingsBegin = Names.size(); 2437 do { 2438 Node *Binding = getDerived().parseSourceName(State); 2439 if (Binding == nullptr) 2440 return nullptr; 2441 Names.push_back(Binding); 2442 } while (!consumeIf('E')); 2443 Result = make<StructuredBindingName>(popTrailingNodeArray(BindingsBegin)); 2444 } else 2445 Result = getDerived().parseOperatorName(State); 2446 if (Result != nullptr) 2447 Result = getDerived().parseAbiTags(Result); 2448 return Result; 2449 } 2450 2451 // <unnamed-type-name> ::= Ut [<nonnegative number>] _ 2452 // ::= <closure-type-name> 2453 // 2454 // <closure-type-name> ::= Ul <lambda-sig> E [ <nonnegative number> ] _ 2455 // 2456 // <lambda-sig> ::= <parameter type>+ # Parameter types or "v" if the lambda has no parameters 2457 template <typename Derived, typename Alloc> 2458 Node * 2459 AbstractManglingParser<Derived, Alloc>::parseUnnamedTypeName(NameState *) { 2460 if (consumeIf("Ut")) { 2461 StringView Count = parseNumber(); 2462 if (!consumeIf('_')) 2463 return nullptr; 2464 return make<UnnamedTypeName>(Count); 2465 } 2466 if (consumeIf("Ul")) { 2467 NodeArray Params; 2468 SwapAndRestore<bool> SwapParams(ParsingLambdaParams, true); 2469 if (!consumeIf("vE")) { 2470 size_t ParamsBegin = Names.size(); 2471 do { 2472 Node *P = getDerived().parseType(); 2473 if (P == nullptr) 2474 return nullptr; 2475 Names.push_back(P); 2476 } while (!consumeIf('E')); 2477 Params = popTrailingNodeArray(ParamsBegin); 2478 } 2479 StringView Count = parseNumber(); 2480 if (!consumeIf('_')) 2481 return nullptr; 2482 return make<ClosureTypeName>(Params, Count); 2483 } 2484 return nullptr; 2485 } 2486 2487 // <source-name> ::= <positive length number> <identifier> 2488 template <typename Derived, typename Alloc> 2489 Node *AbstractManglingParser<Derived, Alloc>::parseSourceName(NameState *) { 2490 size_t Length = 0; 2491 if (parsePositiveInteger(&Length)) 2492 return nullptr; 2493 if (numLeft() < Length || Length == 0) 2494 return nullptr; 2495 StringView Name(First, First + Length); 2496 First += Length; 2497 if (Name.startsWith("_GLOBAL__N")) 2498 return make<NameType>("(anonymous namespace)"); 2499 return make<NameType>(Name); 2500 } 2501 2502 // <operator-name> ::= aa # && 2503 // ::= ad # & (unary) 2504 // ::= an # & 2505 // ::= aN # &= 2506 // ::= aS # = 2507 // ::= cl # () 2508 // ::= cm # , 2509 // ::= co # ~ 2510 // ::= cv <type> # (cast) 2511 // ::= da # delete[] 2512 // ::= de # * (unary) 2513 // ::= dl # delete 2514 // ::= dv # / 2515 // ::= dV # /= 2516 // ::= eo # ^ 2517 // ::= eO # ^= 2518 // ::= eq # == 2519 // ::= ge # >= 2520 // ::= gt # > 2521 // ::= ix # [] 2522 // ::= le # <= 2523 // ::= li <source-name> # operator "" 2524 // ::= ls # << 2525 // ::= lS # <<= 2526 // ::= lt # < 2527 // ::= mi # - 2528 // ::= mI # -= 2529 // ::= ml # * 2530 // ::= mL # *= 2531 // ::= mm # -- (postfix in <expression> context) 2532 // ::= na # new[] 2533 // ::= ne # != 2534 // ::= ng # - (unary) 2535 // ::= nt # ! 2536 // ::= nw # new 2537 // ::= oo # || 2538 // ::= or # | 2539 // ::= oR # |= 2540 // ::= pm # ->* 2541 // ::= pl # + 2542 // ::= pL # += 2543 // ::= pp # ++ (postfix in <expression> context) 2544 // ::= ps # + (unary) 2545 // ::= pt # -> 2546 // ::= qu # ? 2547 // ::= rm # % 2548 // ::= rM # %= 2549 // ::= rs # >> 2550 // ::= rS # >>= 2551 // ::= ss # <=> C++2a 2552 // ::= v <digit> <source-name> # vendor extended operator 2553 template <typename Derived, typename Alloc> 2554 Node * 2555 AbstractManglingParser<Derived, Alloc>::parseOperatorName(NameState *State) { 2556 switch (look()) { 2557 case 'a': 2558 switch (look(1)) { 2559 case 'a': 2560 First += 2; 2561 return make<NameType>("operator&&"); 2562 case 'd': 2563 case 'n': 2564 First += 2; 2565 return make<NameType>("operator&"); 2566 case 'N': 2567 First += 2; 2568 return make<NameType>("operator&="); 2569 case 'S': 2570 First += 2; 2571 return make<NameType>("operator="); 2572 } 2573 return nullptr; 2574 case 'c': 2575 switch (look(1)) { 2576 case 'l': 2577 First += 2; 2578 return make<NameType>("operator()"); 2579 case 'm': 2580 First += 2; 2581 return make<NameType>("operator,"); 2582 case 'o': 2583 First += 2; 2584 return make<NameType>("operator~"); 2585 // ::= cv <type> # (cast) 2586 case 'v': { 2587 First += 2; 2588 SwapAndRestore<bool> SaveTemplate(TryToParseTemplateArgs, false); 2589 // If we're parsing an encoding, State != nullptr and the conversion 2590 // operators' <type> could have a <template-param> that refers to some 2591 // <template-arg>s further ahead in the mangled name. 2592 SwapAndRestore<bool> SavePermit(PermitForwardTemplateReferences, 2593 PermitForwardTemplateReferences || 2594 State != nullptr); 2595 Node *Ty = getDerived().parseType(); 2596 if (Ty == nullptr) 2597 return nullptr; 2598 if (State) State->CtorDtorConversion = true; 2599 return make<ConversionOperatorType>(Ty); 2600 } 2601 } 2602 return nullptr; 2603 case 'd': 2604 switch (look(1)) { 2605 case 'a': 2606 First += 2; 2607 return make<NameType>("operator delete[]"); 2608 case 'e': 2609 First += 2; 2610 return make<NameType>("operator*"); 2611 case 'l': 2612 First += 2; 2613 return make<NameType>("operator delete"); 2614 case 'v': 2615 First += 2; 2616 return make<NameType>("operator/"); 2617 case 'V': 2618 First += 2; 2619 return make<NameType>("operator/="); 2620 } 2621 return nullptr; 2622 case 'e': 2623 switch (look(1)) { 2624 case 'o': 2625 First += 2; 2626 return make<NameType>("operator^"); 2627 case 'O': 2628 First += 2; 2629 return make<NameType>("operator^="); 2630 case 'q': 2631 First += 2; 2632 return make<NameType>("operator=="); 2633 } 2634 return nullptr; 2635 case 'g': 2636 switch (look(1)) { 2637 case 'e': 2638 First += 2; 2639 return make<NameType>("operator>="); 2640 case 't': 2641 First += 2; 2642 return make<NameType>("operator>"); 2643 } 2644 return nullptr; 2645 case 'i': 2646 if (look(1) == 'x') { 2647 First += 2; 2648 return make<NameType>("operator[]"); 2649 } 2650 return nullptr; 2651 case 'l': 2652 switch (look(1)) { 2653 case 'e': 2654 First += 2; 2655 return make<NameType>("operator<="); 2656 // ::= li <source-name> # operator "" 2657 case 'i': { 2658 First += 2; 2659 Node *SN = getDerived().parseSourceName(State); 2660 if (SN == nullptr) 2661 return nullptr; 2662 return make<LiteralOperator>(SN); 2663 } 2664 case 's': 2665 First += 2; 2666 return make<NameType>("operator<<"); 2667 case 'S': 2668 First += 2; 2669 return make<NameType>("operator<<="); 2670 case 't': 2671 First += 2; 2672 return make<NameType>("operator<"); 2673 } 2674 return nullptr; 2675 case 'm': 2676 switch (look(1)) { 2677 case 'i': 2678 First += 2; 2679 return make<NameType>("operator-"); 2680 case 'I': 2681 First += 2; 2682 return make<NameType>("operator-="); 2683 case 'l': 2684 First += 2; 2685 return make<NameType>("operator*"); 2686 case 'L': 2687 First += 2; 2688 return make<NameType>("operator*="); 2689 case 'm': 2690 First += 2; 2691 return make<NameType>("operator--"); 2692 } 2693 return nullptr; 2694 case 'n': 2695 switch (look(1)) { 2696 case 'a': 2697 First += 2; 2698 return make<NameType>("operator new[]"); 2699 case 'e': 2700 First += 2; 2701 return make<NameType>("operator!="); 2702 case 'g': 2703 First += 2; 2704 return make<NameType>("operator-"); 2705 case 't': 2706 First += 2; 2707 return make<NameType>("operator!"); 2708 case 'w': 2709 First += 2; 2710 return make<NameType>("operator new"); 2711 } 2712 return nullptr; 2713 case 'o': 2714 switch (look(1)) { 2715 case 'o': 2716 First += 2; 2717 return make<NameType>("operator||"); 2718 case 'r': 2719 First += 2; 2720 return make<NameType>("operator|"); 2721 case 'R': 2722 First += 2; 2723 return make<NameType>("operator|="); 2724 } 2725 return nullptr; 2726 case 'p': 2727 switch (look(1)) { 2728 case 'm': 2729 First += 2; 2730 return make<NameType>("operator->*"); 2731 case 'l': 2732 First += 2; 2733 return make<NameType>("operator+"); 2734 case 'L': 2735 First += 2; 2736 return make<NameType>("operator+="); 2737 case 'p': 2738 First += 2; 2739 return make<NameType>("operator++"); 2740 case 's': 2741 First += 2; 2742 return make<NameType>("operator+"); 2743 case 't': 2744 First += 2; 2745 return make<NameType>("operator->"); 2746 } 2747 return nullptr; 2748 case 'q': 2749 if (look(1) == 'u') { 2750 First += 2; 2751 return make<NameType>("operator?"); 2752 } 2753 return nullptr; 2754 case 'r': 2755 switch (look(1)) { 2756 case 'm': 2757 First += 2; 2758 return make<NameType>("operator%"); 2759 case 'M': 2760 First += 2; 2761 return make<NameType>("operator%="); 2762 case 's': 2763 First += 2; 2764 return make<NameType>("operator>>"); 2765 case 'S': 2766 First += 2; 2767 return make<NameType>("operator>>="); 2768 } 2769 return nullptr; 2770 case 's': 2771 if (look(1) == 's') { 2772 First += 2; 2773 return make<NameType>("operator<=>"); 2774 } 2775 return nullptr; 2776 // ::= v <digit> <source-name> # vendor extended operator 2777 case 'v': 2778 if (std::isdigit(look(1))) { 2779 First += 2; 2780 Node *SN = getDerived().parseSourceName(State); 2781 if (SN == nullptr) 2782 return nullptr; 2783 return make<ConversionOperatorType>(SN); 2784 } 2785 return nullptr; 2786 } 2787 return nullptr; 2788 } 2789 2790 // <ctor-dtor-name> ::= C1 # complete object constructor 2791 // ::= C2 # base object constructor 2792 // ::= C3 # complete object allocating constructor 2793 // extension ::= C5 # ? 2794 // ::= D0 # deleting destructor 2795 // ::= D1 # complete object destructor 2796 // ::= D2 # base object destructor 2797 // extension ::= D5 # ? 2798 template <typename Derived, typename Alloc> 2799 Node * 2800 AbstractManglingParser<Derived, Alloc>::parseCtorDtorName(Node *&SoFar, 2801 NameState *State) { 2802 if (SoFar->getKind() == Node::KSpecialSubstitution) { 2803 auto SSK = static_cast<SpecialSubstitution *>(SoFar)->SSK; 2804 switch (SSK) { 2805 case SpecialSubKind::string: 2806 case SpecialSubKind::istream: 2807 case SpecialSubKind::ostream: 2808 case SpecialSubKind::iostream: 2809 SoFar = make<ExpandedSpecialSubstitution>(SSK); 2810 if (!SoFar) 2811 return nullptr; 2812 break; 2813 default: 2814 break; 2815 } 2816 } 2817 2818 if (consumeIf('C')) { 2819 bool IsInherited = consumeIf('I'); 2820 if (look() != '1' && look() != '2' && look() != '3' && look() != '5') 2821 return nullptr; 2822 int Variant = look() - '0'; 2823 ++First; 2824 if (State) State->CtorDtorConversion = true; 2825 if (IsInherited) { 2826 if (getDerived().parseName(State) == nullptr) 2827 return nullptr; 2828 } 2829 return make<CtorDtorName>(SoFar, false, Variant); 2830 } 2831 2832 if (look() == 'D' && 2833 (look(1) == '0' || look(1) == '1' || look(1) == '2' || look(1) == '5')) { 2834 int Variant = look(1) - '0'; 2835 First += 2; 2836 if (State) State->CtorDtorConversion = true; 2837 return make<CtorDtorName>(SoFar, true, Variant); 2838 } 2839 2840 return nullptr; 2841 } 2842 2843 // <nested-name> ::= N [<CV-Qualifiers>] [<ref-qualifier>] <prefix> <unqualified-name> E 2844 // ::= N [<CV-Qualifiers>] [<ref-qualifier>] <template-prefix> <template-args> E 2845 // 2846 // <prefix> ::= <prefix> <unqualified-name> 2847 // ::= <template-prefix> <template-args> 2848 // ::= <template-param> 2849 // ::= <decltype> 2850 // ::= # empty 2851 // ::= <substitution> 2852 // ::= <prefix> <data-member-prefix> 2853 // extension ::= L 2854 // 2855 // <data-member-prefix> := <member source-name> [<template-args>] M 2856 // 2857 // <template-prefix> ::= <prefix> <template unqualified-name> 2858 // ::= <template-param> 2859 // ::= <substitution> 2860 template <typename Derived, typename Alloc> 2861 Node * 2862 AbstractManglingParser<Derived, Alloc>::parseNestedName(NameState *State) { 2863 if (!consumeIf('N')) 2864 return nullptr; 2865 2866 Qualifiers CVTmp = parseCVQualifiers(); 2867 if (State) State->CVQualifiers = CVTmp; 2868 2869 if (consumeIf('O')) { 2870 if (State) State->ReferenceQualifier = FrefQualRValue; 2871 } else if (consumeIf('R')) { 2872 if (State) State->ReferenceQualifier = FrefQualLValue; 2873 } else 2874 if (State) State->ReferenceQualifier = FrefQualNone; 2875 2876 Node *SoFar = nullptr; 2877 auto PushComponent = [&](Node *Comp) { 2878 if (!Comp) return false; 2879 if (SoFar) SoFar = make<NestedName>(SoFar, Comp); 2880 else SoFar = Comp; 2881 if (State) State->EndsWithTemplateArgs = false; 2882 return SoFar != nullptr; 2883 }; 2884 2885 if (consumeIf("St")) { 2886 SoFar = make<NameType>("std"); 2887 if (!SoFar) 2888 return nullptr; 2889 } 2890 2891 while (!consumeIf('E')) { 2892 consumeIf('L'); // extension 2893 2894 // <data-member-prefix> := <member source-name> [<template-args>] M 2895 if (consumeIf('M')) { 2896 if (SoFar == nullptr) 2897 return nullptr; 2898 continue; 2899 } 2900 2901 // ::= <template-param> 2902 if (look() == 'T') { 2903 if (!PushComponent(getDerived().parseTemplateParam())) 2904 return nullptr; 2905 Subs.push_back(SoFar); 2906 continue; 2907 } 2908 2909 // ::= <template-prefix> <template-args> 2910 if (look() == 'I') { 2911 Node *TA = getDerived().parseTemplateArgs(State != nullptr); 2912 if (TA == nullptr || SoFar == nullptr) 2913 return nullptr; 2914 SoFar = make<NameWithTemplateArgs>(SoFar, TA); 2915 if (!SoFar) 2916 return nullptr; 2917 if (State) State->EndsWithTemplateArgs = true; 2918 Subs.push_back(SoFar); 2919 continue; 2920 } 2921 2922 // ::= <decltype> 2923 if (look() == 'D' && (look(1) == 't' || look(1) == 'T')) { 2924 if (!PushComponent(getDerived().parseDecltype())) 2925 return nullptr; 2926 Subs.push_back(SoFar); 2927 continue; 2928 } 2929 2930 // ::= <substitution> 2931 if (look() == 'S' && look(1) != 't') { 2932 Node *S = getDerived().parseSubstitution(); 2933 if (!PushComponent(S)) 2934 return nullptr; 2935 if (SoFar != S) 2936 Subs.push_back(S); 2937 continue; 2938 } 2939 2940 // Parse an <unqualified-name> thats actually a <ctor-dtor-name>. 2941 if (look() == 'C' || (look() == 'D' && look(1) != 'C')) { 2942 if (SoFar == nullptr) 2943 return nullptr; 2944 if (!PushComponent(getDerived().parseCtorDtorName(SoFar, State))) 2945 return nullptr; 2946 SoFar = getDerived().parseAbiTags(SoFar); 2947 if (SoFar == nullptr) 2948 return nullptr; 2949 Subs.push_back(SoFar); 2950 continue; 2951 } 2952 2953 // ::= <prefix> <unqualified-name> 2954 if (!PushComponent(getDerived().parseUnqualifiedName(State))) 2955 return nullptr; 2956 Subs.push_back(SoFar); 2957 } 2958 2959 if (SoFar == nullptr || Subs.empty()) 2960 return nullptr; 2961 2962 Subs.pop_back(); 2963 return SoFar; 2964 } 2965 2966 // <simple-id> ::= <source-name> [ <template-args> ] 2967 template <typename Derived, typename Alloc> 2968 Node *AbstractManglingParser<Derived, Alloc>::parseSimpleId() { 2969 Node *SN = getDerived().parseSourceName(/*NameState=*/nullptr); 2970 if (SN == nullptr) 2971 return nullptr; 2972 if (look() == 'I') { 2973 Node *TA = getDerived().parseTemplateArgs(); 2974 if (TA == nullptr) 2975 return nullptr; 2976 return make<NameWithTemplateArgs>(SN, TA); 2977 } 2978 return SN; 2979 } 2980 2981 // <destructor-name> ::= <unresolved-type> # e.g., ~T or ~decltype(f()) 2982 // ::= <simple-id> # e.g., ~A<2*N> 2983 template <typename Derived, typename Alloc> 2984 Node *AbstractManglingParser<Derived, Alloc>::parseDestructorName() { 2985 Node *Result; 2986 if (std::isdigit(look())) 2987 Result = getDerived().parseSimpleId(); 2988 else 2989 Result = getDerived().parseUnresolvedType(); 2990 if (Result == nullptr) 2991 return nullptr; 2992 return make<DtorName>(Result); 2993 } 2994 2995 // <unresolved-type> ::= <template-param> 2996 // ::= <decltype> 2997 // ::= <substitution> 2998 template <typename Derived, typename Alloc> 2999 Node *AbstractManglingParser<Derived, Alloc>::parseUnresolvedType() { 3000 if (look() == 'T') { 3001 Node *TP = getDerived().parseTemplateParam(); 3002 if (TP == nullptr) 3003 return nullptr; 3004 Subs.push_back(TP); 3005 return TP; 3006 } 3007 if (look() == 'D') { 3008 Node *DT = getDerived().parseDecltype(); 3009 if (DT == nullptr) 3010 return nullptr; 3011 Subs.push_back(DT); 3012 return DT; 3013 } 3014 return getDerived().parseSubstitution(); 3015 } 3016 3017 // <base-unresolved-name> ::= <simple-id> # unresolved name 3018 // extension ::= <operator-name> # unresolved operator-function-id 3019 // extension ::= <operator-name> <template-args> # unresolved operator template-id 3020 // ::= on <operator-name> # unresolved operator-function-id 3021 // ::= on <operator-name> <template-args> # unresolved operator template-id 3022 // ::= dn <destructor-name> # destructor or pseudo-destructor; 3023 // # e.g. ~X or ~X<N-1> 3024 template <typename Derived, typename Alloc> 3025 Node *AbstractManglingParser<Derived, Alloc>::parseBaseUnresolvedName() { 3026 if (std::isdigit(look())) 3027 return getDerived().parseSimpleId(); 3028 3029 if (consumeIf("dn")) 3030 return getDerived().parseDestructorName(); 3031 3032 consumeIf("on"); 3033 3034 Node *Oper = getDerived().parseOperatorName(/*NameState=*/nullptr); 3035 if (Oper == nullptr) 3036 return nullptr; 3037 if (look() == 'I') { 3038 Node *TA = getDerived().parseTemplateArgs(); 3039 if (TA == nullptr) 3040 return nullptr; 3041 return make<NameWithTemplateArgs>(Oper, TA); 3042 } 3043 return Oper; 3044 } 3045 3046 // <unresolved-name> 3047 // extension ::= srN <unresolved-type> [<template-args>] <unresolved-qualifier-level>* E <base-unresolved-name> 3048 // ::= [gs] <base-unresolved-name> # x or (with "gs") ::x 3049 // ::= [gs] sr <unresolved-qualifier-level>+ E <base-unresolved-name> 3050 // # A::x, N::y, A<T>::z; "gs" means leading "::" 3051 // ::= sr <unresolved-type> <base-unresolved-name> # T::x / decltype(p)::x 3052 // extension ::= sr <unresolved-type> <template-args> <base-unresolved-name> 3053 // # T::N::x /decltype(p)::N::x 3054 // (ignored) ::= srN <unresolved-type> <unresolved-qualifier-level>+ E <base-unresolved-name> 3055 // 3056 // <unresolved-qualifier-level> ::= <simple-id> 3057 template <typename Derived, typename Alloc> 3058 Node *AbstractManglingParser<Derived, Alloc>::parseUnresolvedName() { 3059 Node *SoFar = nullptr; 3060 3061 // srN <unresolved-type> [<template-args>] <unresolved-qualifier-level>* E <base-unresolved-name> 3062 // srN <unresolved-type> <unresolved-qualifier-level>+ E <base-unresolved-name> 3063 if (consumeIf("srN")) { 3064 SoFar = getDerived().parseUnresolvedType(); 3065 if (SoFar == nullptr) 3066 return nullptr; 3067 3068 if (look() == 'I') { 3069 Node *TA = getDerived().parseTemplateArgs(); 3070 if (TA == nullptr) 3071 return nullptr; 3072 SoFar = make<NameWithTemplateArgs>(SoFar, TA); 3073 if (!SoFar) 3074 return nullptr; 3075 } 3076 3077 while (!consumeIf('E')) { 3078 Node *Qual = getDerived().parseSimpleId(); 3079 if (Qual == nullptr) 3080 return nullptr; 3081 SoFar = make<QualifiedName>(SoFar, Qual); 3082 if (!SoFar) 3083 return nullptr; 3084 } 3085 3086 Node *Base = getDerived().parseBaseUnresolvedName(); 3087 if (Base == nullptr) 3088 return nullptr; 3089 return make<QualifiedName>(SoFar, Base); 3090 } 3091 3092 bool Global = consumeIf("gs"); 3093 3094 // [gs] <base-unresolved-name> # x or (with "gs") ::x 3095 if (!consumeIf("sr")) { 3096 SoFar = getDerived().parseBaseUnresolvedName(); 3097 if (SoFar == nullptr) 3098 return nullptr; 3099 if (Global) 3100 SoFar = make<GlobalQualifiedName>(SoFar); 3101 return SoFar; 3102 } 3103 3104 // [gs] sr <unresolved-qualifier-level>+ E <base-unresolved-name> 3105 if (std::isdigit(look())) { 3106 do { 3107 Node *Qual = getDerived().parseSimpleId(); 3108 if (Qual == nullptr) 3109 return nullptr; 3110 if (SoFar) 3111 SoFar = make<QualifiedName>(SoFar, Qual); 3112 else if (Global) 3113 SoFar = make<GlobalQualifiedName>(Qual); 3114 else 3115 SoFar = Qual; 3116 if (!SoFar) 3117 return nullptr; 3118 } while (!consumeIf('E')); 3119 } 3120 // sr <unresolved-type> <base-unresolved-name> 3121 // sr <unresolved-type> <template-args> <base-unresolved-name> 3122 else { 3123 SoFar = getDerived().parseUnresolvedType(); 3124 if (SoFar == nullptr) 3125 return nullptr; 3126 3127 if (look() == 'I') { 3128 Node *TA = getDerived().parseTemplateArgs(); 3129 if (TA == nullptr) 3130 return nullptr; 3131 SoFar = make<NameWithTemplateArgs>(SoFar, TA); 3132 if (!SoFar) 3133 return nullptr; 3134 } 3135 } 3136 3137 assert(SoFar != nullptr); 3138 3139 Node *Base = getDerived().parseBaseUnresolvedName(); 3140 if (Base == nullptr) 3141 return nullptr; 3142 return make<QualifiedName>(SoFar, Base); 3143 } 3144 3145 // <abi-tags> ::= <abi-tag> [<abi-tags>] 3146 // <abi-tag> ::= B <source-name> 3147 template <typename Derived, typename Alloc> 3148 Node *AbstractManglingParser<Derived, Alloc>::parseAbiTags(Node *N) { 3149 while (consumeIf('B')) { 3150 StringView SN = parseBareSourceName(); 3151 if (SN.empty()) 3152 return nullptr; 3153 N = make<AbiTagAttr>(N, SN); 3154 if (!N) 3155 return nullptr; 3156 } 3157 return N; 3158 } 3159 3160 // <number> ::= [n] <non-negative decimal integer> 3161 template <typename Alloc, typename Derived> 3162 StringView 3163 AbstractManglingParser<Alloc, Derived>::parseNumber(bool AllowNegative) { 3164 const char *Tmp = First; 3165 if (AllowNegative) 3166 consumeIf('n'); 3167 if (numLeft() == 0 || !std::isdigit(*First)) 3168 return StringView(); 3169 while (numLeft() != 0 && std::isdigit(*First)) 3170 ++First; 3171 return StringView(Tmp, First); 3172 } 3173 3174 // <positive length number> ::= [0-9]* 3175 template <typename Alloc, typename Derived> 3176 bool AbstractManglingParser<Alloc, Derived>::parsePositiveInteger(size_t *Out) { 3177 *Out = 0; 3178 if (look() < '0' || look() > '9') 3179 return true; 3180 while (look() >= '0' && look() <= '9') { 3181 *Out *= 10; 3182 *Out += static_cast<size_t>(consume() - '0'); 3183 } 3184 return false; 3185 } 3186 3187 template <typename Alloc, typename Derived> 3188 StringView AbstractManglingParser<Alloc, Derived>::parseBareSourceName() { 3189 size_t Int = 0; 3190 if (parsePositiveInteger(&Int) || numLeft() < Int) 3191 return StringView(); 3192 StringView R(First, First + Int); 3193 First += Int; 3194 return R; 3195 } 3196 3197 // <function-type> ::= [<CV-qualifiers>] [<exception-spec>] [Dx] F [Y] <bare-function-type> [<ref-qualifier>] E 3198 // 3199 // <exception-spec> ::= Do # non-throwing exception-specification (e.g., noexcept, throw()) 3200 // ::= DO <expression> E # computed (instantiation-dependent) noexcept 3201 // ::= Dw <type>+ E # dynamic exception specification with instantiation-dependent types 3202 // 3203 // <ref-qualifier> ::= R # & ref-qualifier 3204 // <ref-qualifier> ::= O # && ref-qualifier 3205 template <typename Derived, typename Alloc> 3206 Node *AbstractManglingParser<Derived, Alloc>::parseFunctionType() { 3207 Qualifiers CVQuals = parseCVQualifiers(); 3208 3209 Node *ExceptionSpec = nullptr; 3210 if (consumeIf("Do")) { 3211 ExceptionSpec = make<NameType>("noexcept"); 3212 if (!ExceptionSpec) 3213 return nullptr; 3214 } else if (consumeIf("DO")) { 3215 Node *E = getDerived().parseExpr(); 3216 if (E == nullptr || !consumeIf('E')) 3217 return nullptr; 3218 ExceptionSpec = make<NoexceptSpec>(E); 3219 if (!ExceptionSpec) 3220 return nullptr; 3221 } else if (consumeIf("Dw")) { 3222 size_t SpecsBegin = Names.size(); 3223 while (!consumeIf('E')) { 3224 Node *T = getDerived().parseType(); 3225 if (T == nullptr) 3226 return nullptr; 3227 Names.push_back(T); 3228 } 3229 ExceptionSpec = 3230 make<DynamicExceptionSpec>(popTrailingNodeArray(SpecsBegin)); 3231 if (!ExceptionSpec) 3232 return nullptr; 3233 } 3234 3235 consumeIf("Dx"); // transaction safe 3236 3237 if (!consumeIf('F')) 3238 return nullptr; 3239 consumeIf('Y'); // extern "C" 3240 Node *ReturnType = getDerived().parseType(); 3241 if (ReturnType == nullptr) 3242 return nullptr; 3243 3244 FunctionRefQual ReferenceQualifier = FrefQualNone; 3245 size_t ParamsBegin = Names.size(); 3246 while (true) { 3247 if (consumeIf('E')) 3248 break; 3249 if (consumeIf('v')) 3250 continue; 3251 if (consumeIf("RE")) { 3252 ReferenceQualifier = FrefQualLValue; 3253 break; 3254 } 3255 if (consumeIf("OE")) { 3256 ReferenceQualifier = FrefQualRValue; 3257 break; 3258 } 3259 Node *T = getDerived().parseType(); 3260 if (T == nullptr) 3261 return nullptr; 3262 Names.push_back(T); 3263 } 3264 3265 NodeArray Params = popTrailingNodeArray(ParamsBegin); 3266 return make<FunctionType>(ReturnType, Params, CVQuals, 3267 ReferenceQualifier, ExceptionSpec); 3268 } 3269 3270 // extension: 3271 // <vector-type> ::= Dv <positive dimension number> _ <extended element type> 3272 // ::= Dv [<dimension expression>] _ <element type> 3273 // <extended element type> ::= <element type> 3274 // ::= p # AltiVec vector pixel 3275 template <typename Derived, typename Alloc> 3276 Node *AbstractManglingParser<Derived, Alloc>::parseVectorType() { 3277 if (!consumeIf("Dv")) 3278 return nullptr; 3279 if (look() >= '1' && look() <= '9') { 3280 StringView DimensionNumber = parseNumber(); 3281 if (!consumeIf('_')) 3282 return nullptr; 3283 if (consumeIf('p')) 3284 return make<PixelVectorType>(DimensionNumber); 3285 Node *ElemType = getDerived().parseType(); 3286 if (ElemType == nullptr) 3287 return nullptr; 3288 return make<VectorType>(ElemType, DimensionNumber); 3289 } 3290 3291 if (!consumeIf('_')) { 3292 Node *DimExpr = getDerived().parseExpr(); 3293 if (!DimExpr) 3294 return nullptr; 3295 if (!consumeIf('_')) 3296 return nullptr; 3297 Node *ElemType = getDerived().parseType(); 3298 if (!ElemType) 3299 return nullptr; 3300 return make<VectorType>(ElemType, DimExpr); 3301 } 3302 Node *ElemType = getDerived().parseType(); 3303 if (!ElemType) 3304 return nullptr; 3305 return make<VectorType>(ElemType, StringView()); 3306 } 3307 3308 // <decltype> ::= Dt <expression> E # decltype of an id-expression or class member access (C++0x) 3309 // ::= DT <expression> E # decltype of an expression (C++0x) 3310 template <typename Derived, typename Alloc> 3311 Node *AbstractManglingParser<Derived, Alloc>::parseDecltype() { 3312 if (!consumeIf('D')) 3313 return nullptr; 3314 if (!consumeIf('t') && !consumeIf('T')) 3315 return nullptr; 3316 Node *E = getDerived().parseExpr(); 3317 if (E == nullptr) 3318 return nullptr; 3319 if (!consumeIf('E')) 3320 return nullptr; 3321 return make<EnclosingExpr>("decltype(", E, ")"); 3322 } 3323 3324 // <array-type> ::= A <positive dimension number> _ <element type> 3325 // ::= A [<dimension expression>] _ <element type> 3326 template <typename Derived, typename Alloc> 3327 Node *AbstractManglingParser<Derived, Alloc>::parseArrayType() { 3328 if (!consumeIf('A')) 3329 return nullptr; 3330 3331 NodeOrString Dimension; 3332 3333 if (std::isdigit(look())) { 3334 Dimension = parseNumber(); 3335 if (!consumeIf('_')) 3336 return nullptr; 3337 } else if (!consumeIf('_')) { 3338 Node *DimExpr = getDerived().parseExpr(); 3339 if (DimExpr == nullptr) 3340 return nullptr; 3341 if (!consumeIf('_')) 3342 return nullptr; 3343 Dimension = DimExpr; 3344 } 3345 3346 Node *Ty = getDerived().parseType(); 3347 if (Ty == nullptr) 3348 return nullptr; 3349 return make<ArrayType>(Ty, Dimension); 3350 } 3351 3352 // <pointer-to-member-type> ::= M <class type> <member type> 3353 template <typename Derived, typename Alloc> 3354 Node *AbstractManglingParser<Derived, Alloc>::parsePointerToMemberType() { 3355 if (!consumeIf('M')) 3356 return nullptr; 3357 Node *ClassType = getDerived().parseType(); 3358 if (ClassType == nullptr) 3359 return nullptr; 3360 Node *MemberType = getDerived().parseType(); 3361 if (MemberType == nullptr) 3362 return nullptr; 3363 return make<PointerToMemberType>(ClassType, MemberType); 3364 } 3365 3366 // <class-enum-type> ::= <name> # non-dependent type name, dependent type name, or dependent typename-specifier 3367 // ::= Ts <name> # dependent elaborated type specifier using 'struct' or 'class' 3368 // ::= Tu <name> # dependent elaborated type specifier using 'union' 3369 // ::= Te <name> # dependent elaborated type specifier using 'enum' 3370 template <typename Derived, typename Alloc> 3371 Node *AbstractManglingParser<Derived, Alloc>::parseClassEnumType() { 3372 StringView ElabSpef; 3373 if (consumeIf("Ts")) 3374 ElabSpef = "struct"; 3375 else if (consumeIf("Tu")) 3376 ElabSpef = "union"; 3377 else if (consumeIf("Te")) 3378 ElabSpef = "enum"; 3379 3380 Node *Name = getDerived().parseName(); 3381 if (Name == nullptr) 3382 return nullptr; 3383 3384 if (!ElabSpef.empty()) 3385 return make<ElaboratedTypeSpefType>(ElabSpef, Name); 3386 3387 return Name; 3388 } 3389 3390 // <qualified-type> ::= <qualifiers> <type> 3391 // <qualifiers> ::= <extended-qualifier>* <CV-qualifiers> 3392 // <extended-qualifier> ::= U <source-name> [<template-args>] # vendor extended type qualifier 3393 template <typename Derived, typename Alloc> 3394 Node *AbstractManglingParser<Derived, Alloc>::parseQualifiedType() { 3395 if (consumeIf('U')) { 3396 StringView Qual = parseBareSourceName(); 3397 if (Qual.empty()) 3398 return nullptr; 3399 3400 // FIXME parse the optional <template-args> here! 3401 3402 // extension ::= U <objc-name> <objc-type> # objc-type<identifier> 3403 if (Qual.startsWith("objcproto")) { 3404 StringView ProtoSourceName = Qual.dropFront(std::strlen("objcproto")); 3405 StringView Proto; 3406 { 3407 SwapAndRestore<const char *> SaveFirst(First, ProtoSourceName.begin()), 3408 SaveLast(Last, ProtoSourceName.end()); 3409 Proto = parseBareSourceName(); 3410 } 3411 if (Proto.empty()) 3412 return nullptr; 3413 Node *Child = getDerived().parseQualifiedType(); 3414 if (Child == nullptr) 3415 return nullptr; 3416 return make<ObjCProtoName>(Child, Proto); 3417 } 3418 3419 Node *Child = getDerived().parseQualifiedType(); 3420 if (Child == nullptr) 3421 return nullptr; 3422 return make<VendorExtQualType>(Child, Qual); 3423 } 3424 3425 Qualifiers Quals = parseCVQualifiers(); 3426 Node *Ty = getDerived().parseType(); 3427 if (Ty == nullptr) 3428 return nullptr; 3429 if (Quals != QualNone) 3430 Ty = make<QualType>(Ty, Quals); 3431 return Ty; 3432 } 3433 3434 // <type> ::= <builtin-type> 3435 // ::= <qualified-type> 3436 // ::= <function-type> 3437 // ::= <class-enum-type> 3438 // ::= <array-type> 3439 // ::= <pointer-to-member-type> 3440 // ::= <template-param> 3441 // ::= <template-template-param> <template-args> 3442 // ::= <decltype> 3443 // ::= P <type> # pointer 3444 // ::= R <type> # l-value reference 3445 // ::= O <type> # r-value reference (C++11) 3446 // ::= C <type> # complex pair (C99) 3447 // ::= G <type> # imaginary (C99) 3448 // ::= <substitution> # See Compression below 3449 // extension ::= U <objc-name> <objc-type> # objc-type<identifier> 3450 // extension ::= <vector-type> # <vector-type> starts with Dv 3451 // 3452 // <objc-name> ::= <k0 number> objcproto <k1 number> <identifier> # k0 = 9 + <number of digits in k1> + k1 3453 // <objc-type> ::= <source-name> # PU<11+>objcproto 11objc_object<source-name> 11objc_object -> id<source-name> 3454 template <typename Derived, typename Alloc> 3455 Node *AbstractManglingParser<Derived, Alloc>::parseType() { 3456 Node *Result = nullptr; 3457 3458 switch (look()) { 3459 // ::= <qualified-type> 3460 case 'r': 3461 case 'V': 3462 case 'K': { 3463 unsigned AfterQuals = 0; 3464 if (look(AfterQuals) == 'r') ++AfterQuals; 3465 if (look(AfterQuals) == 'V') ++AfterQuals; 3466 if (look(AfterQuals) == 'K') ++AfterQuals; 3467 3468 if (look(AfterQuals) == 'F' || 3469 (look(AfterQuals) == 'D' && 3470 (look(AfterQuals + 1) == 'o' || look(AfterQuals + 1) == 'O' || 3471 look(AfterQuals + 1) == 'w' || look(AfterQuals + 1) == 'x'))) { 3472 Result = getDerived().parseFunctionType(); 3473 break; 3474 } 3475 _LIBCPP_FALLTHROUGH(); 3476 } 3477 case 'U': { 3478 Result = getDerived().parseQualifiedType(); 3479 break; 3480 } 3481 // <builtin-type> ::= v # void 3482 case 'v': 3483 ++First; 3484 return make<NameType>("void"); 3485 // ::= w # wchar_t 3486 case 'w': 3487 ++First; 3488 return make<NameType>("wchar_t"); 3489 // ::= b # bool 3490 case 'b': 3491 ++First; 3492 return make<NameType>("bool"); 3493 // ::= c # char 3494 case 'c': 3495 ++First; 3496 return make<NameType>("char"); 3497 // ::= a # signed char 3498 case 'a': 3499 ++First; 3500 return make<NameType>("signed char"); 3501 // ::= h # unsigned char 3502 case 'h': 3503 ++First; 3504 return make<NameType>("unsigned char"); 3505 // ::= s # short 3506 case 's': 3507 ++First; 3508 return make<NameType>("short"); 3509 // ::= t # unsigned short 3510 case 't': 3511 ++First; 3512 return make<NameType>("unsigned short"); 3513 // ::= i # int 3514 case 'i': 3515 ++First; 3516 return make<NameType>("int"); 3517 // ::= j # unsigned int 3518 case 'j': 3519 ++First; 3520 return make<NameType>("unsigned int"); 3521 // ::= l # long 3522 case 'l': 3523 ++First; 3524 return make<NameType>("long"); 3525 // ::= m # unsigned long 3526 case 'm': 3527 ++First; 3528 return make<NameType>("unsigned long"); 3529 // ::= x # long long, __int64 3530 case 'x': 3531 ++First; 3532 return make<NameType>("long long"); 3533 // ::= y # unsigned long long, __int64 3534 case 'y': 3535 ++First; 3536 return make<NameType>("unsigned long long"); 3537 // ::= n # __int128 3538 case 'n': 3539 ++First; 3540 return make<NameType>("__int128"); 3541 // ::= o # unsigned __int128 3542 case 'o': 3543 ++First; 3544 return make<NameType>("unsigned __int128"); 3545 // ::= f # float 3546 case 'f': 3547 ++First; 3548 return make<NameType>("float"); 3549 // ::= d # double 3550 case 'd': 3551 ++First; 3552 return make<NameType>("double"); 3553 // ::= e # long double, __float80 3554 case 'e': 3555 ++First; 3556 return make<NameType>("long double"); 3557 // ::= g # __float128 3558 case 'g': 3559 ++First; 3560 return make<NameType>("__float128"); 3561 // ::= z # ellipsis 3562 case 'z': 3563 ++First; 3564 return make<NameType>("..."); 3565 3566 // <builtin-type> ::= u <source-name> # vendor extended type 3567 case 'u': { 3568 ++First; 3569 StringView Res = parseBareSourceName(); 3570 if (Res.empty()) 3571 return nullptr; 3572 return make<NameType>(Res); 3573 } 3574 case 'D': 3575 switch (look(1)) { 3576 // ::= Dd # IEEE 754r decimal floating point (64 bits) 3577 case 'd': 3578 First += 2; 3579 return make<NameType>("decimal64"); 3580 // ::= De # IEEE 754r decimal floating point (128 bits) 3581 case 'e': 3582 First += 2; 3583 return make<NameType>("decimal128"); 3584 // ::= Df # IEEE 754r decimal floating point (32 bits) 3585 case 'f': 3586 First += 2; 3587 return make<NameType>("decimal32"); 3588 // ::= Dh # IEEE 754r half-precision floating point (16 bits) 3589 case 'h': 3590 First += 2; 3591 return make<NameType>("decimal16"); 3592 // ::= Di # char32_t 3593 case 'i': 3594 First += 2; 3595 return make<NameType>("char32_t"); 3596 // ::= Ds # char16_t 3597 case 's': 3598 First += 2; 3599 return make<NameType>("char16_t"); 3600 // ::= Da # auto (in dependent new-expressions) 3601 case 'a': 3602 First += 2; 3603 return make<NameType>("auto"); 3604 // ::= Dc # decltype(auto) 3605 case 'c': 3606 First += 2; 3607 return make<NameType>("decltype(auto)"); 3608 // ::= Dn # std::nullptr_t (i.e., decltype(nullptr)) 3609 case 'n': 3610 First += 2; 3611 return make<NameType>("std::nullptr_t"); 3612 3613 // ::= <decltype> 3614 case 't': 3615 case 'T': { 3616 Result = getDerived().parseDecltype(); 3617 break; 3618 } 3619 // extension ::= <vector-type> # <vector-type> starts with Dv 3620 case 'v': { 3621 Result = getDerived().parseVectorType(); 3622 break; 3623 } 3624 // ::= Dp <type> # pack expansion (C++0x) 3625 case 'p': { 3626 First += 2; 3627 Node *Child = getDerived().parseType(); 3628 if (!Child) 3629 return nullptr; 3630 Result = make<ParameterPackExpansion>(Child); 3631 break; 3632 } 3633 // Exception specifier on a function type. 3634 case 'o': 3635 case 'O': 3636 case 'w': 3637 // Transaction safe function type. 3638 case 'x': 3639 Result = getDerived().parseFunctionType(); 3640 break; 3641 } 3642 break; 3643 // ::= <function-type> 3644 case 'F': { 3645 Result = getDerived().parseFunctionType(); 3646 break; 3647 } 3648 // ::= <array-type> 3649 case 'A': { 3650 Result = getDerived().parseArrayType(); 3651 break; 3652 } 3653 // ::= <pointer-to-member-type> 3654 case 'M': { 3655 Result = getDerived().parsePointerToMemberType(); 3656 break; 3657 } 3658 // ::= <template-param> 3659 case 'T': { 3660 // This could be an elaborate type specifier on a <class-enum-type>. 3661 if (look(1) == 's' || look(1) == 'u' || look(1) == 'e') { 3662 Result = getDerived().parseClassEnumType(); 3663 break; 3664 } 3665 3666 Result = getDerived().parseTemplateParam(); 3667 if (Result == nullptr) 3668 return nullptr; 3669 3670 // Result could be either of: 3671 // <type> ::= <template-param> 3672 // <type> ::= <template-template-param> <template-args> 3673 // 3674 // <template-template-param> ::= <template-param> 3675 // ::= <substitution> 3676 // 3677 // If this is followed by some <template-args>, and we're permitted to 3678 // parse them, take the second production. 3679 3680 if (TryToParseTemplateArgs && look() == 'I') { 3681 Node *TA = getDerived().parseTemplateArgs(); 3682 if (TA == nullptr) 3683 return nullptr; 3684 Result = make<NameWithTemplateArgs>(Result, TA); 3685 } 3686 break; 3687 } 3688 // ::= P <type> # pointer 3689 case 'P': { 3690 ++First; 3691 Node *Ptr = getDerived().parseType(); 3692 if (Ptr == nullptr) 3693 return nullptr; 3694 Result = make<PointerType>(Ptr); 3695 break; 3696 } 3697 // ::= R <type> # l-value reference 3698 case 'R': { 3699 ++First; 3700 Node *Ref = getDerived().parseType(); 3701 if (Ref == nullptr) 3702 return nullptr; 3703 Result = make<ReferenceType>(Ref, ReferenceKind::LValue); 3704 break; 3705 } 3706 // ::= O <type> # r-value reference (C++11) 3707 case 'O': { 3708 ++First; 3709 Node *Ref = getDerived().parseType(); 3710 if (Ref == nullptr) 3711 return nullptr; 3712 Result = make<ReferenceType>(Ref, ReferenceKind::RValue); 3713 break; 3714 } 3715 // ::= C <type> # complex pair (C99) 3716 case 'C': { 3717 ++First; 3718 Node *P = getDerived().parseType(); 3719 if (P == nullptr) 3720 return nullptr; 3721 Result = make<PostfixQualifiedType>(P, " complex"); 3722 break; 3723 } 3724 // ::= G <type> # imaginary (C99) 3725 case 'G': { 3726 ++First; 3727 Node *P = getDerived().parseType(); 3728 if (P == nullptr) 3729 return P; 3730 Result = make<PostfixQualifiedType>(P, " imaginary"); 3731 break; 3732 } 3733 // ::= <substitution> # See Compression below 3734 case 'S': { 3735 if (look(1) && look(1) != 't') { 3736 Node *Sub = getDerived().parseSubstitution(); 3737 if (Sub == nullptr) 3738 return nullptr; 3739 3740 // Sub could be either of: 3741 // <type> ::= <substitution> 3742 // <type> ::= <template-template-param> <template-args> 3743 // 3744 // <template-template-param> ::= <template-param> 3745 // ::= <substitution> 3746 // 3747 // If this is followed by some <template-args>, and we're permitted to 3748 // parse them, take the second production. 3749 3750 if (TryToParseTemplateArgs && look() == 'I') { 3751 Node *TA = getDerived().parseTemplateArgs(); 3752 if (TA == nullptr) 3753 return nullptr; 3754 Result = make<NameWithTemplateArgs>(Sub, TA); 3755 break; 3756 } 3757 3758 // If all we parsed was a substitution, don't re-insert into the 3759 // substitution table. 3760 return Sub; 3761 } 3762 _LIBCPP_FALLTHROUGH(); 3763 } 3764 // ::= <class-enum-type> 3765 default: { 3766 Result = getDerived().parseClassEnumType(); 3767 break; 3768 } 3769 } 3770 3771 // If we parsed a type, insert it into the substitution table. Note that all 3772 // <builtin-type>s and <substitution>s have already bailed out, because they 3773 // don't get substitutions. 3774 if (Result != nullptr) 3775 Subs.push_back(Result); 3776 return Result; 3777 } 3778 3779 template <typename Derived, typename Alloc> 3780 Node *AbstractManglingParser<Derived, Alloc>::parsePrefixExpr(StringView Kind) { 3781 Node *E = getDerived().parseExpr(); 3782 if (E == nullptr) 3783 return nullptr; 3784 return make<PrefixExpr>(Kind, E); 3785 } 3786 3787 template <typename Derived, typename Alloc> 3788 Node *AbstractManglingParser<Derived, Alloc>::parseBinaryExpr(StringView Kind) { 3789 Node *LHS = getDerived().parseExpr(); 3790 if (LHS == nullptr) 3791 return nullptr; 3792 Node *RHS = getDerived().parseExpr(); 3793 if (RHS == nullptr) 3794 return nullptr; 3795 return make<BinaryExpr>(LHS, Kind, RHS); 3796 } 3797 3798 template <typename Derived, typename Alloc> 3799 Node * 3800 AbstractManglingParser<Derived, Alloc>::parseIntegerLiteral(StringView Lit) { 3801 StringView Tmp = parseNumber(true); 3802 if (!Tmp.empty() && consumeIf('E')) 3803 return make<IntegerLiteral>(Lit, Tmp); 3804 return nullptr; 3805 } 3806 3807 // <CV-Qualifiers> ::= [r] [V] [K] 3808 template <typename Alloc, typename Derived> 3809 Qualifiers AbstractManglingParser<Alloc, Derived>::parseCVQualifiers() { 3810 Qualifiers CVR = QualNone; 3811 if (consumeIf('r')) 3812 CVR |= QualRestrict; 3813 if (consumeIf('V')) 3814 CVR |= QualVolatile; 3815 if (consumeIf('K')) 3816 CVR |= QualConst; 3817 return CVR; 3818 } 3819 3820 // <function-param> ::= fp <top-level CV-Qualifiers> _ # L == 0, first parameter 3821 // ::= fp <top-level CV-Qualifiers> <parameter-2 non-negative number> _ # L == 0, second and later parameters 3822 // ::= fL <L-1 non-negative number> p <top-level CV-Qualifiers> _ # L > 0, first parameter 3823 // ::= fL <L-1 non-negative number> p <top-level CV-Qualifiers> <parameter-2 non-negative number> _ # L > 0, second and later parameters 3824 template <typename Derived, typename Alloc> 3825 Node *AbstractManglingParser<Derived, Alloc>::parseFunctionParam() { 3826 if (consumeIf("fp")) { 3827 parseCVQualifiers(); 3828 StringView Num = parseNumber(); 3829 if (!consumeIf('_')) 3830 return nullptr; 3831 return make<FunctionParam>(Num); 3832 } 3833 if (consumeIf("fL")) { 3834 if (parseNumber().empty()) 3835 return nullptr; 3836 if (!consumeIf('p')) 3837 return nullptr; 3838 parseCVQualifiers(); 3839 StringView Num = parseNumber(); 3840 if (!consumeIf('_')) 3841 return nullptr; 3842 return make<FunctionParam>(Num); 3843 } 3844 return nullptr; 3845 } 3846 3847 // [gs] nw <expression>* _ <type> E # new (expr-list) type 3848 // [gs] nw <expression>* _ <type> <initializer> # new (expr-list) type (init) 3849 // [gs] na <expression>* _ <type> E # new[] (expr-list) type 3850 // [gs] na <expression>* _ <type> <initializer> # new[] (expr-list) type (init) 3851 // <initializer> ::= pi <expression>* E # parenthesized initialization 3852 template <typename Derived, typename Alloc> 3853 Node *AbstractManglingParser<Derived, Alloc>::parseNewExpr() { 3854 bool Global = consumeIf("gs"); 3855 bool IsArray = look(1) == 'a'; 3856 if (!consumeIf("nw") && !consumeIf("na")) 3857 return nullptr; 3858 size_t Exprs = Names.size(); 3859 while (!consumeIf('_')) { 3860 Node *Ex = getDerived().parseExpr(); 3861 if (Ex == nullptr) 3862 return nullptr; 3863 Names.push_back(Ex); 3864 } 3865 NodeArray ExprList = popTrailingNodeArray(Exprs); 3866 Node *Ty = getDerived().parseType(); 3867 if (Ty == nullptr) 3868 return Ty; 3869 if (consumeIf("pi")) { 3870 size_t InitsBegin = Names.size(); 3871 while (!consumeIf('E')) { 3872 Node *Init = getDerived().parseExpr(); 3873 if (Init == nullptr) 3874 return Init; 3875 Names.push_back(Init); 3876 } 3877 NodeArray Inits = popTrailingNodeArray(InitsBegin); 3878 return make<NewExpr>(ExprList, Ty, Inits, Global, IsArray); 3879 } else if (!consumeIf('E')) 3880 return nullptr; 3881 return make<NewExpr>(ExprList, Ty, NodeArray(), Global, IsArray); 3882 } 3883 3884 // cv <type> <expression> # conversion with one argument 3885 // cv <type> _ <expression>* E # conversion with a different number of arguments 3886 template <typename Derived, typename Alloc> 3887 Node *AbstractManglingParser<Derived, Alloc>::parseConversionExpr() { 3888 if (!consumeIf("cv")) 3889 return nullptr; 3890 Node *Ty; 3891 { 3892 SwapAndRestore<bool> SaveTemp(TryToParseTemplateArgs, false); 3893 Ty = getDerived().parseType(); 3894 } 3895 3896 if (Ty == nullptr) 3897 return nullptr; 3898 3899 if (consumeIf('_')) { 3900 size_t ExprsBegin = Names.size(); 3901 while (!consumeIf('E')) { 3902 Node *E = getDerived().parseExpr(); 3903 if (E == nullptr) 3904 return E; 3905 Names.push_back(E); 3906 } 3907 NodeArray Exprs = popTrailingNodeArray(ExprsBegin); 3908 return make<ConversionExpr>(Ty, Exprs); 3909 } 3910 3911 Node *E[1] = {getDerived().parseExpr()}; 3912 if (E[0] == nullptr) 3913 return nullptr; 3914 return make<ConversionExpr>(Ty, makeNodeArray(E, E + 1)); 3915 } 3916 3917 // <expr-primary> ::= L <type> <value number> E # integer literal 3918 // ::= L <type> <value float> E # floating literal 3919 // ::= L <string type> E # string literal 3920 // ::= L <nullptr type> E # nullptr literal (i.e., "LDnE") 3921 // FIXME: ::= L <type> <real-part float> _ <imag-part float> E # complex floating point literal (C 2000) 3922 // ::= L <mangled-name> E # external name 3923 template <typename Derived, typename Alloc> 3924 Node *AbstractManglingParser<Derived, Alloc>::parseExprPrimary() { 3925 if (!consumeIf('L')) 3926 return nullptr; 3927 switch (look()) { 3928 case 'w': 3929 ++First; 3930 return getDerived().parseIntegerLiteral("wchar_t"); 3931 case 'b': 3932 if (consumeIf("b0E")) 3933 return make<BoolExpr>(0); 3934 if (consumeIf("b1E")) 3935 return make<BoolExpr>(1); 3936 return nullptr; 3937 case 'c': 3938 ++First; 3939 return getDerived().parseIntegerLiteral("char"); 3940 case 'a': 3941 ++First; 3942 return getDerived().parseIntegerLiteral("signed char"); 3943 case 'h': 3944 ++First; 3945 return getDerived().parseIntegerLiteral("unsigned char"); 3946 case 's': 3947 ++First; 3948 return getDerived().parseIntegerLiteral("short"); 3949 case 't': 3950 ++First; 3951 return getDerived().parseIntegerLiteral("unsigned short"); 3952 case 'i': 3953 ++First; 3954 return getDerived().parseIntegerLiteral(""); 3955 case 'j': 3956 ++First; 3957 return getDerived().parseIntegerLiteral("u"); 3958 case 'l': 3959 ++First; 3960 return getDerived().parseIntegerLiteral("l"); 3961 case 'm': 3962 ++First; 3963 return getDerived().parseIntegerLiteral("ul"); 3964 case 'x': 3965 ++First; 3966 return getDerived().parseIntegerLiteral("ll"); 3967 case 'y': 3968 ++First; 3969 return getDerived().parseIntegerLiteral("ull"); 3970 case 'n': 3971 ++First; 3972 return getDerived().parseIntegerLiteral("__int128"); 3973 case 'o': 3974 ++First; 3975 return getDerived().parseIntegerLiteral("unsigned __int128"); 3976 case 'f': 3977 ++First; 3978 return getDerived().template parseFloatingLiteral<float>(); 3979 case 'd': 3980 ++First; 3981 return getDerived().template parseFloatingLiteral<double>(); 3982 case 'e': 3983 ++First; 3984 return getDerived().template parseFloatingLiteral<long double>(); 3985 case '_': 3986 if (consumeIf("_Z")) { 3987 Node *R = getDerived().parseEncoding(); 3988 if (R != nullptr && consumeIf('E')) 3989 return R; 3990 } 3991 return nullptr; 3992 case 'T': 3993 // Invalid mangled name per 3994 // http://sourcerytools.com/pipermail/cxx-abi-dev/2011-August/002422.html 3995 return nullptr; 3996 default: { 3997 // might be named type 3998 Node *T = getDerived().parseType(); 3999 if (T == nullptr) 4000 return nullptr; 4001 StringView N = parseNumber(); 4002 if (!N.empty()) { 4003 if (!consumeIf('E')) 4004 return nullptr; 4005 return make<IntegerCastExpr>(T, N); 4006 } 4007 if (consumeIf('E')) 4008 return T; 4009 return nullptr; 4010 } 4011 } 4012 } 4013 4014 // <braced-expression> ::= <expression> 4015 // ::= di <field source-name> <braced-expression> # .name = expr 4016 // ::= dx <index expression> <braced-expression> # [expr] = expr 4017 // ::= dX <range begin expression> <range end expression> <braced-expression> 4018 template <typename Derived, typename Alloc> 4019 Node *AbstractManglingParser<Derived, Alloc>::parseBracedExpr() { 4020 if (look() == 'd') { 4021 switch (look(1)) { 4022 case 'i': { 4023 First += 2; 4024 Node *Field = getDerived().parseSourceName(/*NameState=*/nullptr); 4025 if (Field == nullptr) 4026 return nullptr; 4027 Node *Init = getDerived().parseBracedExpr(); 4028 if (Init == nullptr) 4029 return nullptr; 4030 return make<BracedExpr>(Field, Init, /*isArray=*/false); 4031 } 4032 case 'x': { 4033 First += 2; 4034 Node *Index = getDerived().parseExpr(); 4035 if (Index == nullptr) 4036 return nullptr; 4037 Node *Init = getDerived().parseBracedExpr(); 4038 if (Init == nullptr) 4039 return nullptr; 4040 return make<BracedExpr>(Index, Init, /*isArray=*/true); 4041 } 4042 case 'X': { 4043 First += 2; 4044 Node *RangeBegin = getDerived().parseExpr(); 4045 if (RangeBegin == nullptr) 4046 return nullptr; 4047 Node *RangeEnd = getDerived().parseExpr(); 4048 if (RangeEnd == nullptr) 4049 return nullptr; 4050 Node *Init = getDerived().parseBracedExpr(); 4051 if (Init == nullptr) 4052 return nullptr; 4053 return make<BracedRangeExpr>(RangeBegin, RangeEnd, Init); 4054 } 4055 } 4056 } 4057 return getDerived().parseExpr(); 4058 } 4059 4060 // (not yet in the spec) 4061 // <fold-expr> ::= fL <binary-operator-name> <expression> <expression> 4062 // ::= fR <binary-operator-name> <expression> <expression> 4063 // ::= fl <binary-operator-name> <expression> 4064 // ::= fr <binary-operator-name> <expression> 4065 template <typename Derived, typename Alloc> 4066 Node *AbstractManglingParser<Derived, Alloc>::parseFoldExpr() { 4067 if (!consumeIf('f')) 4068 return nullptr; 4069 4070 char FoldKind = look(); 4071 bool IsLeftFold, HasInitializer; 4072 HasInitializer = FoldKind == 'L' || FoldKind == 'R'; 4073 if (FoldKind == 'l' || FoldKind == 'L') 4074 IsLeftFold = true; 4075 else if (FoldKind == 'r' || FoldKind == 'R') 4076 IsLeftFold = false; 4077 else 4078 return nullptr; 4079 ++First; 4080 4081 // FIXME: This map is duplicated in parseOperatorName and parseExpr. 4082 StringView OperatorName; 4083 if (consumeIf("aa")) OperatorName = "&&"; 4084 else if (consumeIf("an")) OperatorName = "&"; 4085 else if (consumeIf("aN")) OperatorName = "&="; 4086 else if (consumeIf("aS")) OperatorName = "="; 4087 else if (consumeIf("cm")) OperatorName = ","; 4088 else if (consumeIf("ds")) OperatorName = ".*"; 4089 else if (consumeIf("dv")) OperatorName = "/"; 4090 else if (consumeIf("dV")) OperatorName = "/="; 4091 else if (consumeIf("eo")) OperatorName = "^"; 4092 else if (consumeIf("eO")) OperatorName = "^="; 4093 else if (consumeIf("eq")) OperatorName = "=="; 4094 else if (consumeIf("ge")) OperatorName = ">="; 4095 else if (consumeIf("gt")) OperatorName = ">"; 4096 else if (consumeIf("le")) OperatorName = "<="; 4097 else if (consumeIf("ls")) OperatorName = "<<"; 4098 else if (consumeIf("lS")) OperatorName = "<<="; 4099 else if (consumeIf("lt")) OperatorName = "<"; 4100 else if (consumeIf("mi")) OperatorName = "-"; 4101 else if (consumeIf("mI")) OperatorName = "-="; 4102 else if (consumeIf("ml")) OperatorName = "*"; 4103 else if (consumeIf("mL")) OperatorName = "*="; 4104 else if (consumeIf("ne")) OperatorName = "!="; 4105 else if (consumeIf("oo")) OperatorName = "||"; 4106 else if (consumeIf("or")) OperatorName = "|"; 4107 else if (consumeIf("oR")) OperatorName = "|="; 4108 else if (consumeIf("pl")) OperatorName = "+"; 4109 else if (consumeIf("pL")) OperatorName = "+="; 4110 else if (consumeIf("rm")) OperatorName = "%"; 4111 else if (consumeIf("rM")) OperatorName = "%="; 4112 else if (consumeIf("rs")) OperatorName = ">>"; 4113 else if (consumeIf("rS")) OperatorName = ">>="; 4114 else return nullptr; 4115 4116 Node *Pack = getDerived().parseExpr(), *Init = nullptr; 4117 if (Pack == nullptr) 4118 return nullptr; 4119 if (HasInitializer) { 4120 Init = getDerived().parseExpr(); 4121 if (Init == nullptr) 4122 return nullptr; 4123 } 4124 4125 if (IsLeftFold && Init) 4126 std::swap(Pack, Init); 4127 4128 return make<FoldExpr>(IsLeftFold, OperatorName, Pack, Init); 4129 } 4130 4131 // <expression> ::= <unary operator-name> <expression> 4132 // ::= <binary operator-name> <expression> <expression> 4133 // ::= <ternary operator-name> <expression> <expression> <expression> 4134 // ::= cl <expression>+ E # call 4135 // ::= cv <type> <expression> # conversion with one argument 4136 // ::= cv <type> _ <expression>* E # conversion with a different number of arguments 4137 // ::= [gs] nw <expression>* _ <type> E # new (expr-list) type 4138 // ::= [gs] nw <expression>* _ <type> <initializer> # new (expr-list) type (init) 4139 // ::= [gs] na <expression>* _ <type> E # new[] (expr-list) type 4140 // ::= [gs] na <expression>* _ <type> <initializer> # new[] (expr-list) type (init) 4141 // ::= [gs] dl <expression> # delete expression 4142 // ::= [gs] da <expression> # delete[] expression 4143 // ::= pp_ <expression> # prefix ++ 4144 // ::= mm_ <expression> # prefix -- 4145 // ::= ti <type> # typeid (type) 4146 // ::= te <expression> # typeid (expression) 4147 // ::= dc <type> <expression> # dynamic_cast<type> (expression) 4148 // ::= sc <type> <expression> # static_cast<type> (expression) 4149 // ::= cc <type> <expression> # const_cast<type> (expression) 4150 // ::= rc <type> <expression> # reinterpret_cast<type> (expression) 4151 // ::= st <type> # sizeof (a type) 4152 // ::= sz <expression> # sizeof (an expression) 4153 // ::= at <type> # alignof (a type) 4154 // ::= az <expression> # alignof (an expression) 4155 // ::= nx <expression> # noexcept (expression) 4156 // ::= <template-param> 4157 // ::= <function-param> 4158 // ::= dt <expression> <unresolved-name> # expr.name 4159 // ::= pt <expression> <unresolved-name> # expr->name 4160 // ::= ds <expression> <expression> # expr.*expr 4161 // ::= sZ <template-param> # size of a parameter pack 4162 // ::= sZ <function-param> # size of a function parameter pack 4163 // ::= sP <template-arg>* E # sizeof...(T), size of a captured template parameter pack from an alias template 4164 // ::= sp <expression> # pack expansion 4165 // ::= tw <expression> # throw expression 4166 // ::= tr # throw with no operand (rethrow) 4167 // ::= <unresolved-name> # f(p), N::f(p), ::f(p), 4168 // # freestanding dependent name (e.g., T::x), 4169 // # objectless nonstatic member reference 4170 // ::= fL <binary-operator-name> <expression> <expression> 4171 // ::= fR <binary-operator-name> <expression> <expression> 4172 // ::= fl <binary-operator-name> <expression> 4173 // ::= fr <binary-operator-name> <expression> 4174 // ::= <expr-primary> 4175 template <typename Derived, typename Alloc> 4176 Node *AbstractManglingParser<Derived, Alloc>::parseExpr() { 4177 bool Global = consumeIf("gs"); 4178 if (numLeft() < 2) 4179 return nullptr; 4180 4181 switch (*First) { 4182 case 'L': 4183 return getDerived().parseExprPrimary(); 4184 case 'T': 4185 return getDerived().parseTemplateParam(); 4186 case 'f': { 4187 // Disambiguate a fold expression from a <function-param>. 4188 if (look(1) == 'p' || (look(1) == 'L' && std::isdigit(look(2)))) 4189 return getDerived().parseFunctionParam(); 4190 return getDerived().parseFoldExpr(); 4191 } 4192 case 'a': 4193 switch (First[1]) { 4194 case 'a': 4195 First += 2; 4196 return getDerived().parseBinaryExpr("&&"); 4197 case 'd': 4198 First += 2; 4199 return getDerived().parsePrefixExpr("&"); 4200 case 'n': 4201 First += 2; 4202 return getDerived().parseBinaryExpr("&"); 4203 case 'N': 4204 First += 2; 4205 return getDerived().parseBinaryExpr("&="); 4206 case 'S': 4207 First += 2; 4208 return getDerived().parseBinaryExpr("="); 4209 case 't': { 4210 First += 2; 4211 Node *Ty = getDerived().parseType(); 4212 if (Ty == nullptr) 4213 return nullptr; 4214 return make<EnclosingExpr>("alignof (", Ty, ")"); 4215 } 4216 case 'z': { 4217 First += 2; 4218 Node *Ty = getDerived().parseExpr(); 4219 if (Ty == nullptr) 4220 return nullptr; 4221 return make<EnclosingExpr>("alignof (", Ty, ")"); 4222 } 4223 } 4224 return nullptr; 4225 case 'c': 4226 switch (First[1]) { 4227 // cc <type> <expression> # const_cast<type>(expression) 4228 case 'c': { 4229 First += 2; 4230 Node *Ty = getDerived().parseType(); 4231 if (Ty == nullptr) 4232 return Ty; 4233 Node *Ex = getDerived().parseExpr(); 4234 if (Ex == nullptr) 4235 return Ex; 4236 return make<CastExpr>("const_cast", Ty, Ex); 4237 } 4238 // cl <expression>+ E # call 4239 case 'l': { 4240 First += 2; 4241 Node *Callee = getDerived().parseExpr(); 4242 if (Callee == nullptr) 4243 return Callee; 4244 size_t ExprsBegin = Names.size(); 4245 while (!consumeIf('E')) { 4246 Node *E = getDerived().parseExpr(); 4247 if (E == nullptr) 4248 return E; 4249 Names.push_back(E); 4250 } 4251 return make<CallExpr>(Callee, popTrailingNodeArray(ExprsBegin)); 4252 } 4253 case 'm': 4254 First += 2; 4255 return getDerived().parseBinaryExpr(","); 4256 case 'o': 4257 First += 2; 4258 return getDerived().parsePrefixExpr("~"); 4259 case 'v': 4260 return getDerived().parseConversionExpr(); 4261 } 4262 return nullptr; 4263 case 'd': 4264 switch (First[1]) { 4265 case 'a': { 4266 First += 2; 4267 Node *Ex = getDerived().parseExpr(); 4268 if (Ex == nullptr) 4269 return Ex; 4270 return make<DeleteExpr>(Ex, Global, /*is_array=*/true); 4271 } 4272 case 'c': { 4273 First += 2; 4274 Node *T = getDerived().parseType(); 4275 if (T == nullptr) 4276 return T; 4277 Node *Ex = getDerived().parseExpr(); 4278 if (Ex == nullptr) 4279 return Ex; 4280 return make<CastExpr>("dynamic_cast", T, Ex); 4281 } 4282 case 'e': 4283 First += 2; 4284 return getDerived().parsePrefixExpr("*"); 4285 case 'l': { 4286 First += 2; 4287 Node *E = getDerived().parseExpr(); 4288 if (E == nullptr) 4289 return E; 4290 return make<DeleteExpr>(E, Global, /*is_array=*/false); 4291 } 4292 case 'n': 4293 return getDerived().parseUnresolvedName(); 4294 case 's': { 4295 First += 2; 4296 Node *LHS = getDerived().parseExpr(); 4297 if (LHS == nullptr) 4298 return nullptr; 4299 Node *RHS = getDerived().parseExpr(); 4300 if (RHS == nullptr) 4301 return nullptr; 4302 return make<MemberExpr>(LHS, ".*", RHS); 4303 } 4304 case 't': { 4305 First += 2; 4306 Node *LHS = getDerived().parseExpr(); 4307 if (LHS == nullptr) 4308 return LHS; 4309 Node *RHS = getDerived().parseExpr(); 4310 if (RHS == nullptr) 4311 return nullptr; 4312 return make<MemberExpr>(LHS, ".", RHS); 4313 } 4314 case 'v': 4315 First += 2; 4316 return getDerived().parseBinaryExpr("/"); 4317 case 'V': 4318 First += 2; 4319 return getDerived().parseBinaryExpr("/="); 4320 } 4321 return nullptr; 4322 case 'e': 4323 switch (First[1]) { 4324 case 'o': 4325 First += 2; 4326 return getDerived().parseBinaryExpr("^"); 4327 case 'O': 4328 First += 2; 4329 return getDerived().parseBinaryExpr("^="); 4330 case 'q': 4331 First += 2; 4332 return getDerived().parseBinaryExpr("=="); 4333 } 4334 return nullptr; 4335 case 'g': 4336 switch (First[1]) { 4337 case 'e': 4338 First += 2; 4339 return getDerived().parseBinaryExpr(">="); 4340 case 't': 4341 First += 2; 4342 return getDerived().parseBinaryExpr(">"); 4343 } 4344 return nullptr; 4345 case 'i': 4346 switch (First[1]) { 4347 case 'x': { 4348 First += 2; 4349 Node *Base = getDerived().parseExpr(); 4350 if (Base == nullptr) 4351 return nullptr; 4352 Node *Index = getDerived().parseExpr(); 4353 if (Index == nullptr) 4354 return Index; 4355 return make<ArraySubscriptExpr>(Base, Index); 4356 } 4357 case 'l': { 4358 First += 2; 4359 size_t InitsBegin = Names.size(); 4360 while (!consumeIf('E')) { 4361 Node *E = getDerived().parseBracedExpr(); 4362 if (E == nullptr) 4363 return nullptr; 4364 Names.push_back(E); 4365 } 4366 return make<InitListExpr>(nullptr, popTrailingNodeArray(InitsBegin)); 4367 } 4368 } 4369 return nullptr; 4370 case 'l': 4371 switch (First[1]) { 4372 case 'e': 4373 First += 2; 4374 return getDerived().parseBinaryExpr("<="); 4375 case 's': 4376 First += 2; 4377 return getDerived().parseBinaryExpr("<<"); 4378 case 'S': 4379 First += 2; 4380 return getDerived().parseBinaryExpr("<<="); 4381 case 't': 4382 First += 2; 4383 return getDerived().parseBinaryExpr("<"); 4384 } 4385 return nullptr; 4386 case 'm': 4387 switch (First[1]) { 4388 case 'i': 4389 First += 2; 4390 return getDerived().parseBinaryExpr("-"); 4391 case 'I': 4392 First += 2; 4393 return getDerived().parseBinaryExpr("-="); 4394 case 'l': 4395 First += 2; 4396 return getDerived().parseBinaryExpr("*"); 4397 case 'L': 4398 First += 2; 4399 return getDerived().parseBinaryExpr("*="); 4400 case 'm': 4401 First += 2; 4402 if (consumeIf('_')) 4403 return getDerived().parsePrefixExpr("--"); 4404 Node *Ex = getDerived().parseExpr(); 4405 if (Ex == nullptr) 4406 return nullptr; 4407 return make<PostfixExpr>(Ex, "--"); 4408 } 4409 return nullptr; 4410 case 'n': 4411 switch (First[1]) { 4412 case 'a': 4413 case 'w': 4414 return getDerived().parseNewExpr(); 4415 case 'e': 4416 First += 2; 4417 return getDerived().parseBinaryExpr("!="); 4418 case 'g': 4419 First += 2; 4420 return getDerived().parsePrefixExpr("-"); 4421 case 't': 4422 First += 2; 4423 return getDerived().parsePrefixExpr("!"); 4424 case 'x': 4425 First += 2; 4426 Node *Ex = getDerived().parseExpr(); 4427 if (Ex == nullptr) 4428 return Ex; 4429 return make<EnclosingExpr>("noexcept (", Ex, ")"); 4430 } 4431 return nullptr; 4432 case 'o': 4433 switch (First[1]) { 4434 case 'n': 4435 return getDerived().parseUnresolvedName(); 4436 case 'o': 4437 First += 2; 4438 return getDerived().parseBinaryExpr("||"); 4439 case 'r': 4440 First += 2; 4441 return getDerived().parseBinaryExpr("|"); 4442 case 'R': 4443 First += 2; 4444 return getDerived().parseBinaryExpr("|="); 4445 } 4446 return nullptr; 4447 case 'p': 4448 switch (First[1]) { 4449 case 'm': 4450 First += 2; 4451 return getDerived().parseBinaryExpr("->*"); 4452 case 'l': 4453 First += 2; 4454 return getDerived().parseBinaryExpr("+"); 4455 case 'L': 4456 First += 2; 4457 return getDerived().parseBinaryExpr("+="); 4458 case 'p': { 4459 First += 2; 4460 if (consumeIf('_')) 4461 return getDerived().parsePrefixExpr("++"); 4462 Node *Ex = getDerived().parseExpr(); 4463 if (Ex == nullptr) 4464 return Ex; 4465 return make<PostfixExpr>(Ex, "++"); 4466 } 4467 case 's': 4468 First += 2; 4469 return getDerived().parsePrefixExpr("+"); 4470 case 't': { 4471 First += 2; 4472 Node *L = getDerived().parseExpr(); 4473 if (L == nullptr) 4474 return nullptr; 4475 Node *R = getDerived().parseExpr(); 4476 if (R == nullptr) 4477 return nullptr; 4478 return make<MemberExpr>(L, "->", R); 4479 } 4480 } 4481 return nullptr; 4482 case 'q': 4483 if (First[1] == 'u') { 4484 First += 2; 4485 Node *Cond = getDerived().parseExpr(); 4486 if (Cond == nullptr) 4487 return nullptr; 4488 Node *LHS = getDerived().parseExpr(); 4489 if (LHS == nullptr) 4490 return nullptr; 4491 Node *RHS = getDerived().parseExpr(); 4492 if (RHS == nullptr) 4493 return nullptr; 4494 return make<ConditionalExpr>(Cond, LHS, RHS); 4495 } 4496 return nullptr; 4497 case 'r': 4498 switch (First[1]) { 4499 case 'c': { 4500 First += 2; 4501 Node *T = getDerived().parseType(); 4502 if (T == nullptr) 4503 return T; 4504 Node *Ex = getDerived().parseExpr(); 4505 if (Ex == nullptr) 4506 return Ex; 4507 return make<CastExpr>("reinterpret_cast", T, Ex); 4508 } 4509 case 'm': 4510 First += 2; 4511 return getDerived().parseBinaryExpr("%"); 4512 case 'M': 4513 First += 2; 4514 return getDerived().parseBinaryExpr("%="); 4515 case 's': 4516 First += 2; 4517 return getDerived().parseBinaryExpr(">>"); 4518 case 'S': 4519 First += 2; 4520 return getDerived().parseBinaryExpr(">>="); 4521 } 4522 return nullptr; 4523 case 's': 4524 switch (First[1]) { 4525 case 'c': { 4526 First += 2; 4527 Node *T = getDerived().parseType(); 4528 if (T == nullptr) 4529 return T; 4530 Node *Ex = getDerived().parseExpr(); 4531 if (Ex == nullptr) 4532 return Ex; 4533 return make<CastExpr>("static_cast", T, Ex); 4534 } 4535 case 'p': { 4536 First += 2; 4537 Node *Child = getDerived().parseExpr(); 4538 if (Child == nullptr) 4539 return nullptr; 4540 return make<ParameterPackExpansion>(Child); 4541 } 4542 case 'r': 4543 return getDerived().parseUnresolvedName(); 4544 case 't': { 4545 First += 2; 4546 Node *Ty = getDerived().parseType(); 4547 if (Ty == nullptr) 4548 return Ty; 4549 return make<EnclosingExpr>("sizeof (", Ty, ")"); 4550 } 4551 case 'z': { 4552 First += 2; 4553 Node *Ex = getDerived().parseExpr(); 4554 if (Ex == nullptr) 4555 return Ex; 4556 return make<EnclosingExpr>("sizeof (", Ex, ")"); 4557 } 4558 case 'Z': 4559 First += 2; 4560 if (look() == 'T') { 4561 Node *R = getDerived().parseTemplateParam(); 4562 if (R == nullptr) 4563 return nullptr; 4564 return make<SizeofParamPackExpr>(R); 4565 } else if (look() == 'f') { 4566 Node *FP = getDerived().parseFunctionParam(); 4567 if (FP == nullptr) 4568 return nullptr; 4569 return make<EnclosingExpr>("sizeof... (", FP, ")"); 4570 } 4571 return nullptr; 4572 case 'P': { 4573 First += 2; 4574 size_t ArgsBegin = Names.size(); 4575 while (!consumeIf('E')) { 4576 Node *Arg = getDerived().parseTemplateArg(); 4577 if (Arg == nullptr) 4578 return nullptr; 4579 Names.push_back(Arg); 4580 } 4581 auto *Pack = make<NodeArrayNode>(popTrailingNodeArray(ArgsBegin)); 4582 if (!Pack) 4583 return nullptr; 4584 return make<EnclosingExpr>("sizeof... (", Pack, ")"); 4585 } 4586 } 4587 return nullptr; 4588 case 't': 4589 switch (First[1]) { 4590 case 'e': { 4591 First += 2; 4592 Node *Ex = getDerived().parseExpr(); 4593 if (Ex == nullptr) 4594 return Ex; 4595 return make<EnclosingExpr>("typeid (", Ex, ")"); 4596 } 4597 case 'i': { 4598 First += 2; 4599 Node *Ty = getDerived().parseType(); 4600 if (Ty == nullptr) 4601 return Ty; 4602 return make<EnclosingExpr>("typeid (", Ty, ")"); 4603 } 4604 case 'l': { 4605 First += 2; 4606 Node *Ty = getDerived().parseType(); 4607 if (Ty == nullptr) 4608 return nullptr; 4609 size_t InitsBegin = Names.size(); 4610 while (!consumeIf('E')) { 4611 Node *E = getDerived().parseBracedExpr(); 4612 if (E == nullptr) 4613 return nullptr; 4614 Names.push_back(E); 4615 } 4616 return make<InitListExpr>(Ty, popTrailingNodeArray(InitsBegin)); 4617 } 4618 case 'r': 4619 First += 2; 4620 return make<NameType>("throw"); 4621 case 'w': { 4622 First += 2; 4623 Node *Ex = getDerived().parseExpr(); 4624 if (Ex == nullptr) 4625 return nullptr; 4626 return make<ThrowExpr>(Ex); 4627 } 4628 } 4629 return nullptr; 4630 case '1': 4631 case '2': 4632 case '3': 4633 case '4': 4634 case '5': 4635 case '6': 4636 case '7': 4637 case '8': 4638 case '9': 4639 return getDerived().parseUnresolvedName(); 4640 } 4641 return nullptr; 4642 } 4643 4644 // <call-offset> ::= h <nv-offset> _ 4645 // ::= v <v-offset> _ 4646 // 4647 // <nv-offset> ::= <offset number> 4648 // # non-virtual base override 4649 // 4650 // <v-offset> ::= <offset number> _ <virtual offset number> 4651 // # virtual base override, with vcall offset 4652 template <typename Alloc, typename Derived> 4653 bool AbstractManglingParser<Alloc, Derived>::parseCallOffset() { 4654 // Just scan through the call offset, we never add this information into the 4655 // output. 4656 if (consumeIf('h')) 4657 return parseNumber(true).empty() || !consumeIf('_'); 4658 if (consumeIf('v')) 4659 return parseNumber(true).empty() || !consumeIf('_') || 4660 parseNumber(true).empty() || !consumeIf('_'); 4661 return true; 4662 } 4663 4664 // <special-name> ::= TV <type> # virtual table 4665 // ::= TT <type> # VTT structure (construction vtable index) 4666 // ::= TI <type> # typeinfo structure 4667 // ::= TS <type> # typeinfo name (null-terminated byte string) 4668 // ::= Tc <call-offset> <call-offset> <base encoding> 4669 // # base is the nominal target function of thunk 4670 // # first call-offset is 'this' adjustment 4671 // # second call-offset is result adjustment 4672 // ::= T <call-offset> <base encoding> 4673 // # base is the nominal target function of thunk 4674 // ::= GV <object name> # Guard variable for one-time initialization 4675 // # No <type> 4676 // ::= TW <object name> # Thread-local wrapper 4677 // ::= TH <object name> # Thread-local initialization 4678 // ::= GR <object name> _ # First temporary 4679 // ::= GR <object name> <seq-id> _ # Subsequent temporaries 4680 // extension ::= TC <first type> <number> _ <second type> # construction vtable for second-in-first 4681 // extension ::= GR <object name> # reference temporary for object 4682 template <typename Derived, typename Alloc> 4683 Node *AbstractManglingParser<Derived, Alloc>::parseSpecialName() { 4684 switch (look()) { 4685 case 'T': 4686 switch (look(1)) { 4687 // TV <type> # virtual table 4688 case 'V': { 4689 First += 2; 4690 Node *Ty = getDerived().parseType(); 4691 if (Ty == nullptr) 4692 return nullptr; 4693 return make<SpecialName>("vtable for ", Ty); 4694 } 4695 // TT <type> # VTT structure (construction vtable index) 4696 case 'T': { 4697 First += 2; 4698 Node *Ty = getDerived().parseType(); 4699 if (Ty == nullptr) 4700 return nullptr; 4701 return make<SpecialName>("VTT for ", Ty); 4702 } 4703 // TI <type> # typeinfo structure 4704 case 'I': { 4705 First += 2; 4706 Node *Ty = getDerived().parseType(); 4707 if (Ty == nullptr) 4708 return nullptr; 4709 return make<SpecialName>("typeinfo for ", Ty); 4710 } 4711 // TS <type> # typeinfo name (null-terminated byte string) 4712 case 'S': { 4713 First += 2; 4714 Node *Ty = getDerived().parseType(); 4715 if (Ty == nullptr) 4716 return nullptr; 4717 return make<SpecialName>("typeinfo name for ", Ty); 4718 } 4719 // Tc <call-offset> <call-offset> <base encoding> 4720 case 'c': { 4721 First += 2; 4722 if (parseCallOffset() || parseCallOffset()) 4723 return nullptr; 4724 Node *Encoding = getDerived().parseEncoding(); 4725 if (Encoding == nullptr) 4726 return nullptr; 4727 return make<SpecialName>("covariant return thunk to ", Encoding); 4728 } 4729 // extension ::= TC <first type> <number> _ <second type> 4730 // # construction vtable for second-in-first 4731 case 'C': { 4732 First += 2; 4733 Node *FirstType = getDerived().parseType(); 4734 if (FirstType == nullptr) 4735 return nullptr; 4736 if (parseNumber(true).empty() || !consumeIf('_')) 4737 return nullptr; 4738 Node *SecondType = getDerived().parseType(); 4739 if (SecondType == nullptr) 4740 return nullptr; 4741 return make<CtorVtableSpecialName>(SecondType, FirstType); 4742 } 4743 // TW <object name> # Thread-local wrapper 4744 case 'W': { 4745 First += 2; 4746 Node *Name = getDerived().parseName(); 4747 if (Name == nullptr) 4748 return nullptr; 4749 return make<SpecialName>("thread-local wrapper routine for ", Name); 4750 } 4751 // TH <object name> # Thread-local initialization 4752 case 'H': { 4753 First += 2; 4754 Node *Name = getDerived().parseName(); 4755 if (Name == nullptr) 4756 return nullptr; 4757 return make<SpecialName>("thread-local initialization routine for ", Name); 4758 } 4759 // T <call-offset> <base encoding> 4760 default: { 4761 ++First; 4762 bool IsVirt = look() == 'v'; 4763 if (parseCallOffset()) 4764 return nullptr; 4765 Node *BaseEncoding = getDerived().parseEncoding(); 4766 if (BaseEncoding == nullptr) 4767 return nullptr; 4768 if (IsVirt) 4769 return make<SpecialName>("virtual thunk to ", BaseEncoding); 4770 else 4771 return make<SpecialName>("non-virtual thunk to ", BaseEncoding); 4772 } 4773 } 4774 case 'G': 4775 switch (look(1)) { 4776 // GV <object name> # Guard variable for one-time initialization 4777 case 'V': { 4778 First += 2; 4779 Node *Name = getDerived().parseName(); 4780 if (Name == nullptr) 4781 return nullptr; 4782 return make<SpecialName>("guard variable for ", Name); 4783 } 4784 // GR <object name> # reference temporary for object 4785 // GR <object name> _ # First temporary 4786 // GR <object name> <seq-id> _ # Subsequent temporaries 4787 case 'R': { 4788 First += 2; 4789 Node *Name = getDerived().parseName(); 4790 if (Name == nullptr) 4791 return nullptr; 4792 size_t Count; 4793 bool ParsedSeqId = !parseSeqId(&Count); 4794 if (!consumeIf('_') && ParsedSeqId) 4795 return nullptr; 4796 return make<SpecialName>("reference temporary for ", Name); 4797 } 4798 } 4799 } 4800 return nullptr; 4801 } 4802 4803 // <encoding> ::= <function name> <bare-function-type> 4804 // ::= <data name> 4805 // ::= <special-name> 4806 template <typename Derived, typename Alloc> 4807 Node *AbstractManglingParser<Derived, Alloc>::parseEncoding() { 4808 if (look() == 'G' || look() == 'T') 4809 return getDerived().parseSpecialName(); 4810 4811 auto IsEndOfEncoding = [&] { 4812 // The set of chars that can potentially follow an <encoding> (none of which 4813 // can start a <type>). Enumerating these allows us to avoid speculative 4814 // parsing. 4815 return numLeft() == 0 || look() == 'E' || look() == '.' || look() == '_'; 4816 }; 4817 4818 NameState NameInfo(this); 4819 Node *Name = getDerived().parseName(&NameInfo); 4820 if (Name == nullptr) 4821 return nullptr; 4822 4823 if (resolveForwardTemplateRefs(NameInfo)) 4824 return nullptr; 4825 4826 if (IsEndOfEncoding()) 4827 return Name; 4828 4829 Node *Attrs = nullptr; 4830 if (consumeIf("Ua9enable_ifI")) { 4831 size_t BeforeArgs = Names.size(); 4832 while (!consumeIf('E')) { 4833 Node *Arg = getDerived().parseTemplateArg(); 4834 if (Arg == nullptr) 4835 return nullptr; 4836 Names.push_back(Arg); 4837 } 4838 Attrs = make<EnableIfAttr>(popTrailingNodeArray(BeforeArgs)); 4839 if (!Attrs) 4840 return nullptr; 4841 } 4842 4843 Node *ReturnType = nullptr; 4844 if (!NameInfo.CtorDtorConversion && NameInfo.EndsWithTemplateArgs) { 4845 ReturnType = getDerived().parseType(); 4846 if (ReturnType == nullptr) 4847 return nullptr; 4848 } 4849 4850 if (consumeIf('v')) 4851 return make<FunctionEncoding>(ReturnType, Name, NodeArray(), 4852 Attrs, NameInfo.CVQualifiers, 4853 NameInfo.ReferenceQualifier); 4854 4855 size_t ParamsBegin = Names.size(); 4856 do { 4857 Node *Ty = getDerived().parseType(); 4858 if (Ty == nullptr) 4859 return nullptr; 4860 Names.push_back(Ty); 4861 } while (!IsEndOfEncoding()); 4862 4863 return make<FunctionEncoding>(ReturnType, Name, 4864 popTrailingNodeArray(ParamsBegin), 4865 Attrs, NameInfo.CVQualifiers, 4866 NameInfo.ReferenceQualifier); 4867 } 4868 4869 template <class Float> 4870 struct FloatData; 4871 4872 template <> 4873 struct FloatData<float> 4874 { 4875 static const size_t mangled_size = 8; 4876 static const size_t max_demangled_size = 24; 4877 static constexpr const char* spec = "%af"; 4878 }; 4879 4880 template <> 4881 struct FloatData<double> 4882 { 4883 static const size_t mangled_size = 16; 4884 static const size_t max_demangled_size = 32; 4885 static constexpr const char* spec = "%a"; 4886 }; 4887 4888 template <> 4889 struct FloatData<long double> 4890 { 4891 #if defined(__mips__) && defined(__mips_n64) || defined(__aarch64__) || \ 4892 defined(__wasm__) 4893 static const size_t mangled_size = 32; 4894 #elif defined(__arm__) || defined(__mips__) || defined(__hexagon__) 4895 static const size_t mangled_size = 16; 4896 #else 4897 static const size_t mangled_size = 20; // May need to be adjusted to 16 or 24 on other platforms 4898 #endif 4899 static const size_t max_demangled_size = 40; 4900 static constexpr const char *spec = "%LaL"; 4901 }; 4902 4903 template <typename Alloc, typename Derived> 4904 template <class Float> 4905 Node *AbstractManglingParser<Alloc, Derived>::parseFloatingLiteral() { 4906 const size_t N = FloatData<Float>::mangled_size; 4907 if (numLeft() <= N) 4908 return nullptr; 4909 StringView Data(First, First + N); 4910 for (char C : Data) 4911 if (!std::isxdigit(C)) 4912 return nullptr; 4913 First += N; 4914 if (!consumeIf('E')) 4915 return nullptr; 4916 return make<FloatLiteralImpl<Float>>(Data); 4917 } 4918 4919 // <seq-id> ::= <0-9A-Z>+ 4920 template <typename Alloc, typename Derived> 4921 bool AbstractManglingParser<Alloc, Derived>::parseSeqId(size_t *Out) { 4922 if (!(look() >= '0' && look() <= '9') && 4923 !(look() >= 'A' && look() <= 'Z')) 4924 return true; 4925 4926 size_t Id = 0; 4927 while (true) { 4928 if (look() >= '0' && look() <= '9') { 4929 Id *= 36; 4930 Id += static_cast<size_t>(look() - '0'); 4931 } else if (look() >= 'A' && look() <= 'Z') { 4932 Id *= 36; 4933 Id += static_cast<size_t>(look() - 'A') + 10; 4934 } else { 4935 *Out = Id; 4936 return false; 4937 } 4938 ++First; 4939 } 4940 } 4941 4942 // <substitution> ::= S <seq-id> _ 4943 // ::= S_ 4944 // <substitution> ::= Sa # ::std::allocator 4945 // <substitution> ::= Sb # ::std::basic_string 4946 // <substitution> ::= Ss # ::std::basic_string < char, 4947 // ::std::char_traits<char>, 4948 // ::std::allocator<char> > 4949 // <substitution> ::= Si # ::std::basic_istream<char, std::char_traits<char> > 4950 // <substitution> ::= So # ::std::basic_ostream<char, std::char_traits<char> > 4951 // <substitution> ::= Sd # ::std::basic_iostream<char, std::char_traits<char> > 4952 template <typename Derived, typename Alloc> 4953 Node *AbstractManglingParser<Derived, Alloc>::parseSubstitution() { 4954 if (!consumeIf('S')) 4955 return nullptr; 4956 4957 if (std::islower(look())) { 4958 Node *SpecialSub; 4959 switch (look()) { 4960 case 'a': 4961 ++First; 4962 SpecialSub = make<SpecialSubstitution>(SpecialSubKind::allocator); 4963 break; 4964 case 'b': 4965 ++First; 4966 SpecialSub = make<SpecialSubstitution>(SpecialSubKind::basic_string); 4967 break; 4968 case 's': 4969 ++First; 4970 SpecialSub = make<SpecialSubstitution>(SpecialSubKind::string); 4971 break; 4972 case 'i': 4973 ++First; 4974 SpecialSub = make<SpecialSubstitution>(SpecialSubKind::istream); 4975 break; 4976 case 'o': 4977 ++First; 4978 SpecialSub = make<SpecialSubstitution>(SpecialSubKind::ostream); 4979 break; 4980 case 'd': 4981 ++First; 4982 SpecialSub = make<SpecialSubstitution>(SpecialSubKind::iostream); 4983 break; 4984 default: 4985 return nullptr; 4986 } 4987 if (!SpecialSub) 4988 return nullptr; 4989 // Itanium C++ ABI 5.1.2: If a name that would use a built-in <substitution> 4990 // has ABI tags, the tags are appended to the substitution; the result is a 4991 // substitutable component. 4992 Node *WithTags = getDerived().parseAbiTags(SpecialSub); 4993 if (WithTags != SpecialSub) { 4994 Subs.push_back(WithTags); 4995 SpecialSub = WithTags; 4996 } 4997 return SpecialSub; 4998 } 4999 5000 // ::= S_ 5001 if (consumeIf('_')) { 5002 if (Subs.empty()) 5003 return nullptr; 5004 return Subs[0]; 5005 } 5006 5007 // ::= S <seq-id> _ 5008 size_t Index = 0; 5009 if (parseSeqId(&Index)) 5010 return nullptr; 5011 ++Index; 5012 if (!consumeIf('_') || Index >= Subs.size()) 5013 return nullptr; 5014 return Subs[Index]; 5015 } 5016 5017 // <template-param> ::= T_ # first template parameter 5018 // ::= T <parameter-2 non-negative number> _ 5019 template <typename Derived, typename Alloc> 5020 Node *AbstractManglingParser<Derived, Alloc>::parseTemplateParam() { 5021 if (!consumeIf('T')) 5022 return nullptr; 5023 5024 size_t Index = 0; 5025 if (!consumeIf('_')) { 5026 if (parsePositiveInteger(&Index)) 5027 return nullptr; 5028 ++Index; 5029 if (!consumeIf('_')) 5030 return nullptr; 5031 } 5032 5033 // Itanium ABI 5.1.8: In a generic lambda, uses of auto in the parameter list 5034 // are mangled as the corresponding artificial template type parameter. 5035 if (ParsingLambdaParams) 5036 return make<NameType>("auto"); 5037 5038 // If we're in a context where this <template-param> refers to a 5039 // <template-arg> further ahead in the mangled name (currently just conversion 5040 // operator types), then we should only look it up in the right context. 5041 if (PermitForwardTemplateReferences) { 5042 Node *ForwardRef = make<ForwardTemplateReference>(Index); 5043 if (!ForwardRef) 5044 return nullptr; 5045 assert(ForwardRef->getKind() == Node::KForwardTemplateReference); 5046 ForwardTemplateRefs.push_back( 5047 static_cast<ForwardTemplateReference *>(ForwardRef)); 5048 return ForwardRef; 5049 } 5050 5051 if (Index >= TemplateParams.size()) 5052 return nullptr; 5053 return TemplateParams[Index]; 5054 } 5055 5056 // <template-arg> ::= <type> # type or template 5057 // ::= X <expression> E # expression 5058 // ::= <expr-primary> # simple expressions 5059 // ::= J <template-arg>* E # argument pack 5060 // ::= LZ <encoding> E # extension 5061 template <typename Derived, typename Alloc> 5062 Node *AbstractManglingParser<Derived, Alloc>::parseTemplateArg() { 5063 switch (look()) { 5064 case 'X': { 5065 ++First; 5066 Node *Arg = getDerived().parseExpr(); 5067 if (Arg == nullptr || !consumeIf('E')) 5068 return nullptr; 5069 return Arg; 5070 } 5071 case 'J': { 5072 ++First; 5073 size_t ArgsBegin = Names.size(); 5074 while (!consumeIf('E')) { 5075 Node *Arg = getDerived().parseTemplateArg(); 5076 if (Arg == nullptr) 5077 return nullptr; 5078 Names.push_back(Arg); 5079 } 5080 NodeArray Args = popTrailingNodeArray(ArgsBegin); 5081 return make<TemplateArgumentPack>(Args); 5082 } 5083 case 'L': { 5084 // ::= LZ <encoding> E # extension 5085 if (look(1) == 'Z') { 5086 First += 2; 5087 Node *Arg = getDerived().parseEncoding(); 5088 if (Arg == nullptr || !consumeIf('E')) 5089 return nullptr; 5090 return Arg; 5091 } 5092 // ::= <expr-primary> # simple expressions 5093 return getDerived().parseExprPrimary(); 5094 } 5095 default: 5096 return getDerived().parseType(); 5097 } 5098 } 5099 5100 // <template-args> ::= I <template-arg>* E 5101 // extension, the abi says <template-arg>+ 5102 template <typename Derived, typename Alloc> 5103 Node * 5104 AbstractManglingParser<Derived, Alloc>::parseTemplateArgs(bool TagTemplates) { 5105 if (!consumeIf('I')) 5106 return nullptr; 5107 5108 // <template-params> refer to the innermost <template-args>. Clear out any 5109 // outer args that we may have inserted into TemplateParams. 5110 if (TagTemplates) 5111 TemplateParams.clear(); 5112 5113 size_t ArgsBegin = Names.size(); 5114 while (!consumeIf('E')) { 5115 if (TagTemplates) { 5116 auto OldParams = std::move(TemplateParams); 5117 Node *Arg = getDerived().parseTemplateArg(); 5118 TemplateParams = std::move(OldParams); 5119 if (Arg == nullptr) 5120 return nullptr; 5121 Names.push_back(Arg); 5122 Node *TableEntry = Arg; 5123 if (Arg->getKind() == Node::KTemplateArgumentPack) { 5124 TableEntry = make<ParameterPack>( 5125 static_cast<TemplateArgumentPack*>(TableEntry)->getElements()); 5126 if (!TableEntry) 5127 return nullptr; 5128 } 5129 TemplateParams.push_back(TableEntry); 5130 } else { 5131 Node *Arg = getDerived().parseTemplateArg(); 5132 if (Arg == nullptr) 5133 return nullptr; 5134 Names.push_back(Arg); 5135 } 5136 } 5137 return make<TemplateArgs>(popTrailingNodeArray(ArgsBegin)); 5138 } 5139 5140 // <mangled-name> ::= _Z <encoding> 5141 // ::= <type> 5142 // extension ::= ___Z <encoding> _block_invoke 5143 // extension ::= ___Z <encoding> _block_invoke<decimal-digit>+ 5144 // extension ::= ___Z <encoding> _block_invoke_<decimal-digit>+ 5145 template <typename Derived, typename Alloc> 5146 Node *AbstractManglingParser<Derived, Alloc>::parse() { 5147 if (consumeIf("_Z")) { 5148 Node *Encoding = getDerived().parseEncoding(); 5149 if (Encoding == nullptr) 5150 return nullptr; 5151 if (look() == '.') { 5152 Encoding = make<DotSuffix>(Encoding, StringView(First, Last)); 5153 First = Last; 5154 } 5155 if (numLeft() != 0) 5156 return nullptr; 5157 return Encoding; 5158 } 5159 5160 if (consumeIf("___Z")) { 5161 Node *Encoding = getDerived().parseEncoding(); 5162 if (Encoding == nullptr || !consumeIf("_block_invoke")) 5163 return nullptr; 5164 bool RequireNumber = consumeIf('_'); 5165 if (parseNumber().empty() && RequireNumber) 5166 return nullptr; 5167 if (look() == '.') 5168 First = Last; 5169 if (numLeft() != 0) 5170 return nullptr; 5171 return make<SpecialName>("invocation function for block in ", Encoding); 5172 } 5173 5174 Node *Ty = getDerived().parseType(); 5175 if (numLeft() != 0) 5176 return nullptr; 5177 return Ty; 5178 } 5179 5180 template <typename Alloc> 5181 struct ManglingParser : AbstractManglingParser<ManglingParser<Alloc>, Alloc> { 5182 using AbstractManglingParser<ManglingParser<Alloc>, 5183 Alloc>::AbstractManglingParser; 5184 }; 5185 5186 } // namespace itanium_demangle 5187 } // namespace 5188 5189 #endif // LIBCXX_DEMANGLE_ITANIUMDEMANGLE_H 5190