| ... | ... | @@ -21,6 +21,7 @@ |
| 21 | 21 | #include "Utility.h" |
| 22 | 22 | #include <algorithm> |
| 23 | 23 | #include <cctype> |
| 24 | #include <cstdint> |
| 24 | 25 | #include <cstdio> |
| 25 | 26 | #include <cstdlib> |
| 26 | 27 | #include <cstring> |
| ... | ... | @@ -38,8 +39,10 @@ |
| 38 | 39 | DEMANGLE_NAMESPACE_BEGIN |
| 39 | 40 | |
| 40 | 41 | template <class T, size_t N> class PODSmallVector { |
| 41 | | static_assert(std::is_trivial<T>::value, |
| 42 | | "T is required to be a trivial type"); |
| 42 | static_assert(std::is_trivially_copyable<T>::value, |
| 43 | "T is required to be a trivially copyable type"); |
| 44 | static_assert(std::is_trivially_default_constructible<T>::value, |
| 45 | "T is required to be trivially default constructible"); |
| 43 | 46 | T *First = nullptr; |
| 44 | 47 | T *Last = nullptr; |
| 45 | 48 | T *Cap = nullptr; |
| ... | ... | @@ -162,18 +165,18 @@ class NodeArray; |
| 162 | 165 | // traversed by the printLeft/Right functions to produce a demangled string. |
| 163 | 166 | class Node { |
| 164 | 167 | public: |
| 165 | | enum Kind : unsigned char { |
| 168 | enum Kind : uint8_t { |
| 166 | 169 | #define NODE(NodeKind) K##NodeKind, |
| 167 | 170 | #include "ItaniumNodes.def" |
| 168 | 171 | }; |
| 169 | 172 | |
| 170 | 173 | /// Three-way bool to track a cached value. Unknown is possible if this node |
| 171 | 174 | /// has an unexpanded parameter pack below it that may affect this cache. |
| 172 | | enum class Cache : unsigned char { Yes, No, Unknown, }; |
| 175 | enum class Cache : uint8_t { Yes, No, Unknown, }; |
| 173 | 176 | |
| 174 | 177 | /// Operator precedence for expression nodes. Used to determine required |
| 175 | 178 | /// parens in expression emission. |
| 176 | | enum class Prec { |
| 179 | enum class Prec : uint8_t { |
| 177 | 180 | Primary, |
| 178 | 181 | Postfix, |
| 179 | 182 | Unary, |
| ... | ... | @@ -281,20 +284,11 @@ public: |
| 281 | 284 | } |
| 282 | 285 | |
| 283 | 286 | void print(OutputBuffer &OB) const { |
| 284 | | printLeft(OB); |
| 287 | OB.printLeft(*this); |
| 285 | 288 | if (RHSComponentCache != Cache::No) |
| 286 | | printRight(OB); |
| 289 | OB.printRight(*this); |
| 287 | 290 | } |
| 288 | 291 | |
| 289 | | // Print the "left" side of this Node into OutputBuffer. |
| 290 | | virtual void printLeft(OutputBuffer &) const = 0; |
| 291 | | |
| 292 | | // Print the "right". This distinction is necessary to represent C++ types |
| 293 | | // that appear on the RHS of their subtype, such as arrays or functions. |
| 294 | | // Since most types don't have such a component, provide a default |
| 295 | | // implementation. |
| 296 | | virtual void printRight(OutputBuffer &) const {} |
| 297 | | |
| 298 | 292 | // Print an initializer list of this type. Returns true if we printed a custom |
| 299 | 293 | // representation, false if nothing has been printed and the default |
| 300 | 294 | // representation should be used. |
| ... | ... | @@ -310,6 +304,24 @@ public: |
| 310 | 304 | #ifndef NDEBUG |
| 311 | 305 | DEMANGLE_DUMP_METHOD void dump() const; |
| 312 | 306 | #endif |
| 307 | |
| 308 | private: |
| 309 | friend class OutputBuffer; |
| 310 | |
| 311 | // Print the "left" side of this Node into OutputBuffer. |
| 312 | // |
| 313 | // Note, should only be called from OutputBuffer implementations. |
| 314 | // Call \ref OutputBuffer::printLeft instead. |
| 315 | virtual void printLeft(OutputBuffer &) const = 0; |
| 316 | |
| 317 | // Print the "right". This distinction is necessary to represent C++ types |
| 318 | // that appear on the RHS of their subtype, such as arrays or functions. |
| 319 | // Since most types don't have such a component, provide a default |
| 320 | // implementation. |
| 321 | // |
| 322 | // Note, should only be called from OutputBuffer implementations. |
| 323 | // Call \ref OutputBuffer::printRight instead. |
| 324 | virtual void printRight(OutputBuffer &) const {} |
| 313 | 325 | }; |
| 314 | 326 | |
| 315 | 327 | class NodeArray { |
| ... | ... | @@ -458,11 +470,11 @@ public: |
| 458 | 470 | } |
| 459 | 471 | |
| 460 | 472 | void printLeft(OutputBuffer &OB) const override { |
| 461 | | Child->printLeft(OB); |
| 473 | OB.printLeft(*Child); |
| 462 | 474 | printQuals(OB); |
| 463 | 475 | } |
| 464 | 476 | |
| 465 | | void printRight(OutputBuffer &OB) const override { Child->printRight(OB); } |
| 477 | void printRight(OutputBuffer &OB) const override { OB.printRight(*Child); } |
| 466 | 478 | }; |
| 467 | 479 | |
| 468 | 480 | class ConversionOperatorType final : public Node { |
| ... | ... | @@ -491,7 +503,7 @@ public: |
| 491 | 503 | template<typename Fn> void match(Fn F) const { F(Ty, Postfix); } |
| 492 | 504 | |
| 493 | 505 | void printLeft(OutputBuffer &OB) const override { |
| 494 | | Ty->printLeft(OB); |
| 506 | OB.printLeft(*Ty); |
| 495 | 507 | OB += Postfix; |
| 496 | 508 | } |
| 497 | 509 | }; |
| ... | ... | @@ -577,7 +589,7 @@ struct AbiTagAttr : Node { |
| 577 | 589 | std::string_view getBaseName() const override { return Base->getBaseName(); } |
| 578 | 590 | |
| 579 | 591 | void printLeft(OutputBuffer &OB) const override { |
| 580 | | Base->printLeft(OB); |
| 592 | OB.printLeft(*Base); |
| 581 | 593 | OB += "[abi:"; |
| 582 | 594 | OB += Tag; |
| 583 | 595 | OB += "]"; |
| ... | ... | @@ -603,8 +615,6 @@ class ObjCProtoName : public Node { |
| 603 | 615 | const Node *Ty; |
| 604 | 616 | std::string_view Protocol; |
| 605 | 617 | |
| 606 | | friend class PointerType; |
| 607 | | |
| 608 | 618 | public: |
| 609 | 619 | ObjCProtoName(const Node *Ty_, std::string_view Protocol_) |
| 610 | 620 | : Node(KObjCProtoName), Ty(Ty_), Protocol(Protocol_) {} |
| ... | ... | @@ -616,6 +626,8 @@ public: |
| 616 | 626 | static_cast<const NameType *>(Ty)->getName() == "objc_object"; |
| 617 | 627 | } |
| 618 | 628 | |
| 629 | std::string_view getProtocol() const { return Protocol; } |
| 630 | |
| 619 | 631 | void printLeft(OutputBuffer &OB) const override { |
| 620 | 632 | Ty->print(OB); |
| 621 | 633 | OB += "<"; |
| ... | ... | @@ -644,7 +656,7 @@ public: |
| 644 | 656 | // We rewrite objc_object<SomeProtocol>* into id<SomeProtocol>. |
| 645 | 657 | if (Pointee->getKind() != KObjCProtoName || |
| 646 | 658 | !static_cast<const ObjCProtoName *>(Pointee)->isObjCObject()) { |
| 647 | | Pointee->printLeft(OB); |
| 659 | OB.printLeft(*Pointee); |
| 648 | 660 | if (Pointee->hasArray(OB)) |
| 649 | 661 | OB += " "; |
| 650 | 662 | if (Pointee->hasArray(OB) || Pointee->hasFunction(OB)) |
| ... | ... | @@ -653,7 +665,7 @@ public: |
| 653 | 665 | } else { |
| 654 | 666 | const auto *objcProto = static_cast<const ObjCProtoName *>(Pointee); |
| 655 | 667 | OB += "id<"; |
| 656 | | OB += objcProto->Protocol; |
| 668 | OB += objcProto->getProtocol(); |
| 657 | 669 | OB += ">"; |
| 658 | 670 | } |
| 659 | 671 | } |
| ... | ... | @@ -663,7 +675,7 @@ public: |
| 663 | 675 | !static_cast<const ObjCProtoName *>(Pointee)->isObjCObject()) { |
| 664 | 676 | if (Pointee->hasArray(OB) || Pointee->hasFunction(OB)) |
| 665 | 677 | OB += ")"; |
| 666 | | Pointee->printRight(OB); |
| 678 | OB.printRight(*Pointee); |
| 667 | 679 | } |
| 668 | 680 | } |
| 669 | 681 | }; |
| ... | ... | @@ -729,7 +741,7 @@ public: |
| 729 | 741 | std::pair<ReferenceKind, const Node *> Collapsed = collapse(OB); |
| 730 | 742 | if (!Collapsed.second) |
| 731 | 743 | return; |
| 732 | | Collapsed.second->printLeft(OB); |
| 744 | OB.printLeft(*Collapsed.second); |
| 733 | 745 | if (Collapsed.second->hasArray(OB)) |
| 734 | 746 | OB += " "; |
| 735 | 747 | if (Collapsed.second->hasArray(OB) || Collapsed.second->hasFunction(OB)) |
| ... | ... | @@ -746,7 +758,7 @@ public: |
| 746 | 758 | return; |
| 747 | 759 | if (Collapsed.second->hasArray(OB) || Collapsed.second->hasFunction(OB)) |
| 748 | 760 | OB += ")"; |
| 749 | | Collapsed.second->printRight(OB); |
| 761 | OB.printRight(*Collapsed.second); |
| 750 | 762 | } |
| 751 | 763 | }; |
| 752 | 764 | |
| ... | ... | @@ -766,7 +778,7 @@ public: |
| 766 | 778 | } |
| 767 | 779 | |
| 768 | 780 | void printLeft(OutputBuffer &OB) const override { |
| 769 | | MemberType->printLeft(OB); |
| 781 | OB.printLeft(*MemberType); |
| 770 | 782 | if (MemberType->hasArray(OB) || MemberType->hasFunction(OB)) |
| 771 | 783 | OB += "("; |
| 772 | 784 | else |
| ... | ... | @@ -778,7 +790,7 @@ public: |
| 778 | 790 | void printRight(OutputBuffer &OB) const override { |
| 779 | 791 | if (MemberType->hasArray(OB) || MemberType->hasFunction(OB)) |
| 780 | 792 | OB += ")"; |
| 781 | | MemberType->printRight(OB); |
| 793 | OB.printRight(*MemberType); |
| 782 | 794 | } |
| 783 | 795 | }; |
| 784 | 796 | |
| ... | ... | @@ -798,7 +810,7 @@ public: |
| 798 | 810 | bool hasRHSComponentSlow(OutputBuffer &) const override { return true; } |
| 799 | 811 | bool hasArraySlow(OutputBuffer &) const override { return true; } |
| 800 | 812 | |
| 801 | | void printLeft(OutputBuffer &OB) const override { Base->printLeft(OB); } |
| 813 | void printLeft(OutputBuffer &OB) const override { OB.printLeft(*Base); } |
| 802 | 814 | |
| 803 | 815 | void printRight(OutputBuffer &OB) const override { |
| 804 | 816 | if (OB.back() != ']') |
| ... | ... | @@ -807,7 +819,7 @@ public: |
| 807 | 819 | if (Dimension) |
| 808 | 820 | Dimension->print(OB); |
| 809 | 821 | OB += "]"; |
| 810 | | Base->printRight(OB); |
| 822 | OB.printRight(*Base); |
| 811 | 823 | } |
| 812 | 824 | |
| 813 | 825 | bool printInitListAsType(OutputBuffer &OB, |
| ... | ... | @@ -851,7 +863,7 @@ public: |
| 851 | 863 | // by printing out the return types's left, then print our parameters, then |
| 852 | 864 | // finally print right of the return type. |
| 853 | 865 | void printLeft(OutputBuffer &OB) const override { |
| 854 | | Ret->printLeft(OB); |
| 866 | OB.printLeft(*Ret); |
| 855 | 867 | OB += " "; |
| 856 | 868 | } |
| 857 | 869 | |
| ... | ... | @@ -859,7 +871,7 @@ public: |
| 859 | 871 | OB.printOpen(); |
| 860 | 872 | Params.printWithComma(OB); |
| 861 | 873 | OB.printClose(); |
| 862 | | Ret->printRight(OB); |
| 874 | OB.printRight(*Ret); |
| 863 | 875 | |
| 864 | 876 | if (CVQuals & QualConst) |
| 865 | 877 | OB += " const"; |
| ... | ... | @@ -964,6 +976,8 @@ public: |
| 964 | 976 | FunctionRefQual getRefQual() const { return RefQual; } |
| 965 | 977 | NodeArray getParams() const { return Params; } |
| 966 | 978 | const Node *getReturnType() const { return Ret; } |
| 979 | const Node *getAttrs() const { return Attrs; } |
| 980 | const Node *getRequires() const { return Requires; } |
| 967 | 981 | |
| 968 | 982 | bool hasRHSComponentSlow(OutputBuffer &) const override { return true; } |
| 969 | 983 | bool hasFunctionSlow(OutputBuffer &) const override { return true; } |
| ... | ... | @@ -972,10 +986,11 @@ public: |
| 972 | 986 | |
| 973 | 987 | void printLeft(OutputBuffer &OB) const override { |
| 974 | 988 | if (Ret) { |
| 975 | | Ret->printLeft(OB); |
| 989 | OB.printLeft(*Ret); |
| 976 | 990 | if (!Ret->hasRHSComponent(OB)) |
| 977 | 991 | OB += " "; |
| 978 | 992 | } |
| 993 | |
| 979 | 994 | Name->print(OB); |
| 980 | 995 | } |
| 981 | 996 | |
| ... | ... | @@ -983,8 +998,9 @@ public: |
| 983 | 998 | OB.printOpen(); |
| 984 | 999 | Params.printWithComma(OB); |
| 985 | 1000 | OB.printClose(); |
| 1001 | |
| 986 | 1002 | if (Ret) |
| 987 | | Ret->printRight(OB); |
| 1003 | OB.printRight(*Ret); |
| 988 | 1004 | |
| 989 | 1005 | if (CVQuals & QualConst) |
| 990 | 1006 | OB += " const"; |
| ... | ... | @@ -1324,14 +1340,14 @@ public: |
| 1324 | 1340 | template<typename Fn> void match(Fn F) const { F(Name, Type); } |
| 1325 | 1341 | |
| 1326 | 1342 | void printLeft(OutputBuffer &OB) const override { |
| 1327 | | Type->printLeft(OB); |
| 1343 | OB.printLeft(*Type); |
| 1328 | 1344 | if (!Type->hasRHSComponent(OB)) |
| 1329 | 1345 | OB += " "; |
| 1330 | 1346 | } |
| 1331 | 1347 | |
| 1332 | 1348 | void printRight(OutputBuffer &OB) const override { |
| 1333 | 1349 | Name->print(OB); |
| 1334 | | Type->printRight(OB); |
| 1350 | OB.printRight(*Type); |
| 1335 | 1351 | } |
| 1336 | 1352 | }; |
| 1337 | 1353 | |
| ... | ... | @@ -1376,11 +1392,11 @@ public: |
| 1376 | 1392 | template<typename Fn> void match(Fn F) const { F(Param); } |
| 1377 | 1393 | |
| 1378 | 1394 | void printLeft(OutputBuffer &OB) const override { |
| 1379 | | Param->printLeft(OB); |
| 1395 | OB.printLeft(*Param); |
| 1380 | 1396 | OB += "..."; |
| 1381 | 1397 | } |
| 1382 | 1398 | |
| 1383 | | void printRight(OutputBuffer &OB) const override { Param->printRight(OB); } |
| 1399 | void printRight(OutputBuffer &OB) const override { OB.printRight(*Param); } |
| 1384 | 1400 | }; |
| 1385 | 1401 | |
| 1386 | 1402 | /// An unexpanded parameter pack (either in the expression or type context). If |
| ... | ... | @@ -1445,13 +1461,13 @@ public: |
| 1445 | 1461 | initializePackExpansion(OB); |
| 1446 | 1462 | size_t Idx = OB.CurrentPackIndex; |
| 1447 | 1463 | if (Idx < Data.size()) |
| 1448 | | Data[Idx]->printLeft(OB); |
| 1464 | OB.printLeft(*Data[Idx]); |
| 1449 | 1465 | } |
| 1450 | 1466 | void printRight(OutputBuffer &OB) const override { |
| 1451 | 1467 | initializePackExpansion(OB); |
| 1452 | 1468 | size_t Idx = OB.CurrentPackIndex; |
| 1453 | 1469 | if (Idx < Data.size()) |
| 1454 | | Data[Idx]->printRight(OB); |
| 1470 | OB.printRight(*Data[Idx]); |
| 1455 | 1471 | } |
| 1456 | 1472 | }; |
| 1457 | 1473 | |
| ... | ... | @@ -1609,13 +1625,13 @@ struct ForwardTemplateReference : Node { |
| 1609 | 1625 | if (Printing) |
| 1610 | 1626 | return; |
| 1611 | 1627 | ScopedOverride<bool> SavePrinting(Printing, true); |
| 1612 | | Ref->printLeft(OB); |
| 1628 | OB.printLeft(*Ref); |
| 1613 | 1629 | } |
| 1614 | 1630 | void printRight(OutputBuffer &OB) const override { |
| 1615 | 1631 | if (Printing) |
| 1616 | 1632 | return; |
| 1617 | 1633 | ScopedOverride<bool> SavePrinting(Printing, true); |
| 1618 | | Ref->printRight(OB); |
| 1634 | OB.printRight(*Ref); |
| 1619 | 1635 | } |
| 1620 | 1636 | }; |
| 1621 | 1637 | |
| ... | ... | @@ -1767,7 +1783,7 @@ public: |
| 1767 | 1783 | |
| 1768 | 1784 | void printLeft(OutputBuffer &OB) const override { |
| 1769 | 1785 | OB += "~"; |
| 1770 | | Base->printLeft(OB); |
| 1786 | OB.printLeft(*Base); |
| 1771 | 1787 | } |
| 1772 | 1788 | }; |
| 1773 | 1789 | |
| ... | ... | @@ -2047,7 +2063,7 @@ public: |
| 2047 | 2063 | { |
| 2048 | 2064 | ScopedOverride<unsigned> LT(OB.GtIsGt, 0); |
| 2049 | 2065 | OB += "<"; |
| 2050 | | To->printLeft(OB); |
| 2066 | OB.printLeft(*To); |
| 2051 | 2067 | OB += ">"; |
| 2052 | 2068 | } |
| 2053 | 2069 | OB.printOpen(); |
| ... | ... | @@ -3406,7 +3422,7 @@ const typename AbstractManglingParser< |
| 3406 | 3422 | {"or", OperatorInfo::Binary, false, Node::Prec::Ior, "operator|"}, |
| 3407 | 3423 | {"pL", OperatorInfo::Binary, false, Node::Prec::Assign, "operator+="}, |
| 3408 | 3424 | {"pl", OperatorInfo::Binary, false, Node::Prec::Additive, "operator+"}, |
| 3409 | | {"pm", OperatorInfo::Member, /*Named*/ false, Node::Prec::PtrMem, |
| 3425 | {"pm", OperatorInfo::Member, /*Named*/ true, Node::Prec::PtrMem, |
| 3410 | 3426 | "operator->*"}, |
| 3411 | 3427 | {"pp", OperatorInfo::Postfix, false, Node::Prec::Postfix, "operator++"}, |
| 3412 | 3428 | {"ps", OperatorInfo::Prefix, false, Node::Prec::Unary, "operator+"}, |
| ... | ... | @@ -4452,7 +4468,9 @@ Node *AbstractManglingParser<Derived, Alloc>::parseType() { |
| 4452 | 4468 | return nullptr; |
| 4453 | 4469 | if (!consumeIf('_')) |
| 4454 | 4470 | return nullptr; |
| 4455 | | return make<BitIntType>(Size, Signed); |
| 4471 | // The front end expects this to be available for Substitution |
| 4472 | Result = make<BitIntType>(Size, Signed); |
| 4473 | break; |
| 4456 | 4474 | } |
| 4457 | 4475 | // ::= Di # char32_t |
| 4458 | 4476 | case 'i': |
| ... | ... | @@ -5739,14 +5757,16 @@ struct FloatData<double> |
| 5739 | 5757 | template <> |
| 5740 | 5758 | struct FloatData<long double> |
| 5741 | 5759 | { |
| 5742 | | #if defined(__mips__) && defined(__mips_n64) || defined(__aarch64__) || \ |
| 5743 | | defined(__wasm__) || defined(__riscv) || defined(__loongarch__) || \ |
| 5744 | | defined(__ve__) |
| 5745 | | static const size_t mangled_size = 32; |
| 5746 | | #elif defined(__arm__) || defined(__mips__) || defined(__hexagon__) |
| 5747 | | static const size_t mangled_size = 16; |
| 5760 | #if __LDBL_MANT_DIG__ == 113 || __LDBL_MANT_DIG__ == 106 |
| 5761 | static const size_t mangled_size = 32; |
| 5762 | #elif __LDBL_MANT_DIG__ == 53 || defined(_MSC_VER) |
| 5763 | // MSVC doesn't define __LDBL_MANT_DIG__, but it has long double equal to |
| 5764 | // regular double on all current architectures. |
| 5765 | static const size_t mangled_size = 16; |
| 5766 | #elif __LDBL_MANT_DIG__ == 64 |
| 5767 | static const size_t mangled_size = 20; |
| 5748 | 5768 | #else |
| 5749 | | static const size_t mangled_size = 20; // May need to be adjusted to 16 or 24 on other platforms |
| 5769 | #error Unknown size for __LDBL_MANT_DIG__ |
| 5750 | 5770 | #endif |
| 5751 | 5771 | // `-0x1.ffffffffffffffffffffffffffffp+16383` + 'L' + '\0' == 42 bytes. |
| 5752 | 5772 | // 28 'f's * 4 bits == 112 bits, which is the number of mantissa bits. |
| ... | ... | @@ -6176,6 +6196,10 @@ struct ManglingParser : AbstractManglingParser<ManglingParser<Alloc>, Alloc> { |
| 6176 | 6196 | Alloc>::AbstractManglingParser; |
| 6177 | 6197 | }; |
| 6178 | 6198 | |
| 6199 | inline void OutputBuffer::printLeft(const Node &N) { N.printLeft(*this); } |
| 6200 | |
| 6201 | inline void OutputBuffer::printRight(const Node &N) { N.printRight(*this); } |
| 6202 | |
| 6179 | 6203 | DEMANGLE_NAMESPACE_END |
| 6180 | 6204 | |
| 6181 | 6205 | #if defined(__clang__) |