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