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