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