| author | |
| committer | |
| log | 9ddfacd8e62abd80b25619dd852ee811dad5f7b6 |
| tree | 441be2e6381f6e82b8e87d5f1773f7531f8e9912 |
| parent | 571a4c86c39d83b28a0c6f413f3fc259b48cf422 |
release/17.x branch, commit 8f4dd44097c9ae25dd203d5ac87f3b48f854bba813 files changed, 461 insertions(+), 408 deletions(-)
lib/libcxxabi/include/__cxxabi_config.h+1-1| ... | ... | @@ -32,7 +32,7 @@ |
| 32 | 32 | #endif |
| 33 | 33 | |
| 34 | 34 | #if defined(_WIN32) |
| 35 | #if defined(_LIBCXXABI_DISABLE_VISIBILITY_ANNOTATIONS) | |
| 35 | #if defined(_LIBCXXABI_DISABLE_VISIBILITY_ANNOTATIONS) || (defined(__MINGW32__) && !defined(_LIBCXXABI_BUILDING_LIBRARY)) | |
| 36 | 36 | #define _LIBCXXABI_HIDDEN |
| 37 | 37 | #define _LIBCXXABI_DATA_VIS |
| 38 | 38 | #define _LIBCXXABI_FUNC_VIS |
lib/libcxxabi/src/aix_state_tab_eh.inc+56-29| ... | ... | @@ -14,10 +14,6 @@ |
| 14 | 14 | #include <stdio.h> |
| 15 | 15 | #include <sys/debug.h> |
| 16 | 16 | |
| 17 | #if !__has_cpp_attribute(clang::optnone) | |
| 18 | #error This file requires clang::optnone attribute support | |
| 19 | #endif | |
| 20 | ||
| 21 | 17 | /* |
| 22 | 18 | The legacy IBM xlC and xlclang++ compilers use the state table for EH |
| 23 | 19 | instead of the range table. Destructors, or addresses of the possible catch |
| ... | ... | @@ -563,7 +559,8 @@ __xlcxx_personality_v0(int version, _Unwind_Action actions, uint64_t exceptionCl |
| 563 | 559 | uintptr_t *currentSP = reinterpret_cast<uintptr_t*>(_Unwind_GetGR(context, 1)); |
| 564 | 560 | uintptr_t *callersSP = reinterpret_cast<uintptr_t*>(currentSP[0]); |
| 565 | 561 | callersSP[3] = reinterpret_cast<uintptr_t>(unwind_exception); |
| 566 | _LIBCXXABI_TRACE_STATETAB("Handshake: set unwind_exception=%p in stack=%p\n", reinterpret_cast<void*>(unwind_exception), reinterpret_cast<void*>(callersSP)); | |
| 562 | _LIBCXXABI_TRACE_STATETAB("Handshake: save unwind_exception=%p in stack=%p\n", | |
| 563 | reinterpret_cast<void*>(unwind_exception), reinterpret_cast<void*>(callersSP)); | |
| 567 | 564 | // Jump to the handler. |
| 568 | 565 | _Unwind_SetIP(context, results.landingPad); |
| 569 | 566 | return _URC_INSTALL_CONTEXT; |
| ... | ... | @@ -641,38 +638,68 @@ _LIBCXXABI_FUNC_VIS void __xlc_throw_badexception() { |
| 641 | 638 | __cxa_throw(newexception, const_cast<std::type_info*>(&typeid(std::bad_exception)), 0); |
| 642 | 639 | } |
| 643 | 640 | |
| 644 | // force_a_stackframe | |
| 645 | // This function is called by __xlc_exception_handle() to ensure a stack frame | |
| 646 | // is created for __xlc_exception_handle(). | |
| 647 | __attribute__((noinline, optnone)) | |
| 648 | static void force_a_stackframe() {} | |
| 641 | // skip_non_cxx_eh_aware_frames | |
| 642 | // This function skips non-C++ EH aware stack frames by unwinding from the | |
| 643 | // stack frame pointed by 'Sp' and returns the first C++ EH aware stack frame | |
| 644 | // found. 'Pc' is an instruction address inside the function that owns the | |
| 645 | // stack frame pointed to by 'Sp'. | |
| 646 | static uintptr_t* skip_non_cxx_eh_aware_frames(uint32_t* Pc, uintptr_t* Sp) { | |
| 647 | uint32_t* currentPc = Pc; | |
| 648 | uintptr_t* currentStack = Sp; | |
| 649 | ||
| 650 | // Loop until a C++ EH aware frame is found or the return address is 0, | |
| 651 | // which is the return address of the startup function '__start'. | |
| 652 | while (currentPc != 0) { | |
| 653 | uint32_t* p = currentPc; | |
| 654 | ||
| 655 | // Keep looking forward until a word of 0 is found. The traceback | |
| 656 | // table starts at the following word. | |
| 657 | while (*p) | |
| 658 | ++p; | |
| 659 | tbtable* TBTable = reinterpret_cast<tbtable*>(p + 1); | |
| 660 | ||
| 661 | // A stack frame with a C++ state table is C++ EH aware. | |
| 662 | if (TBTable->tb.lang == TB_CPLUSPLUS && TBTable->tb.has_ctl) | |
| 663 | return currentStack; | |
| 664 | ||
| 665 | // Move up one stack frame. | |
| 666 | currentStack = reinterpret_cast<uintptr_t*>(currentStack[0]); | |
| 667 | // Get the value of the LR (saved, prior to incrementing the SP, by the | |
| 668 | // prolog of the function just inspected) from the frame. | |
| 669 | currentPc = reinterpret_cast<uint32_t*>(currentStack[2]); | |
| 670 | } | |
| 671 | // This should not happen. | |
| 672 | _LIBCXXABI_TRACE_STATETAB0("skip_non_cxx_eh_aware_frames() reached the end of stack frames, aborting\n"); | |
| 673 | abort(); | |
| 674 | } | |
| 649 | 675 | |
| 650 | 676 | // __xlc_exception_handle |
| 651 | 677 | // This function is for xlclang++. It returns the address of the exception |
| 652 | 678 | // object stored in the reserved field in the stack of the caller of the |
| 653 | 679 | // function that calls __xlc_exception_handle() (within the link area for the |
| 654 | 680 | // call to the latter). The address is stored by the personality routine for |
| 655 | // xlclang++ compiled code. The implementation of __xlc_exception_handle() | |
| 656 | // assumes a stack frame is created for it. The following ensures this | |
| 657 | // assumption holds true: 1) a call to force_a_stackframe() is made inside | |
| 658 | // __xlc_exception_handle() to make it non-leaf; and 2) optimizations are | |
| 659 | // disabled for this function with attribute 'optnone'. Note: this function | |
| 660 | // may not work as expected if these are changed. | |
| 661 | __attribute__((optnone)) | |
| 681 | // xlclang++ compiled code. If __xlc_exception_handle() is called by | |
| 682 | // non-C++ EH aware functions, their frames are skipped until a C++ EH aware | |
| 683 | // frame is found. | |
| 684 | // Note: make sure __xlc_excpetion_handle() is a non-leaf function. Currently | |
| 685 | // it calls skip_non_cxx_eh_aware_frames(), which in turn calls abort(). | |
| 662 | 686 | _LIBCXXABI_FUNC_VIS uintptr_t __xlc_exception_handle() { |
| 663 | // Make a call to force_a_stackframe() so that the compiler creates a stack | |
| 664 | // frame for this function. | |
| 665 | force_a_stackframe(); | |
| 666 | ||
| 667 | 687 | // Get the SP of this function, i.e., __xlc_exception_handle(). |
| 668 | uintptr_t *lastStack; | |
| 669 | asm("mr %0, 1" : "=r"(lastStack)); | |
| 670 | // Get the SP of the caller of __xlc_exception_handle(). | |
| 671 | uintptr_t *callerStack = reinterpret_cast<uintptr_t*>(lastStack[0]); | |
| 672 | // Get the SP of the caller of the caller. | |
| 673 | uintptr_t *callerStack2 = reinterpret_cast<uintptr_t*>(callerStack[0]); | |
| 674 | uintptr_t exceptionObject = callerStack2[3]; | |
| 675 | _LIBCXXABI_TRACE_STATETAB("Handshake: exceptionObject=%p from stack=%p\n", reinterpret_cast<void*>(exceptionObject), reinterpret_cast<void*>(callerStack2)); | |
| 688 | uintptr_t* lastStack = reinterpret_cast<uintptr_t*>(__builtin_frame_address(0)); | |
| 689 | // Move one frame up to the frame of the caller of __xlc_exception_handle(). | |
| 690 | lastStack = reinterpret_cast<uintptr_t*>(lastStack[0]); | |
| 691 | // Get the return address of this function, i.e., __xlc_exception_handle(). | |
| 692 | uint32_t* returnAddress = reinterpret_cast<uint32_t*>(__builtin_return_address(0)); | |
| 693 | ||
| 694 | // Skip non-C++ EH aware frames and get the first C++ EH aware frame. | |
| 695 | uintptr_t* callerStack = skip_non_cxx_eh_aware_frames(returnAddress, lastStack); | |
| 696 | ||
| 697 | // Get the SP of the caller of the C++ EH aware caller. | |
| 698 | callerStack = reinterpret_cast<uintptr_t*>(callerStack[0]); | |
| 699 | // Retrieve the exception object in the stack slot saved by the personality. | |
| 700 | uintptr_t exceptionObject = callerStack[3]; | |
| 701 | _LIBCXXABI_TRACE_STATETAB("Handshake: retrieve exceptionObject=%p from stack=%p\n", | |
| 702 | reinterpret_cast<void*>(exceptionObject), reinterpret_cast<void*>(callerStack)); | |
| 676 | 703 | return exceptionObject; |
| 677 | 704 | } |
| 678 | 705 |
lib/libcxxabi/src/cxa_aux_runtime.cpp+1| ... | ... | @@ -10,6 +10,7 @@ |
| 10 | 10 | //===----------------------------------------------------------------------===// |
| 11 | 11 | |
| 12 | 12 | #include "cxxabi.h" |
| 13 | #include <exception> | |
| 13 | 14 | #include <new> |
| 14 | 15 | #include <typeinfo> |
| 15 | 16 |
lib/libcxxabi/src/cxa_demangle.cpp+4-2| ... | ... | @@ -10,6 +10,7 @@ |
| 10 | 10 | // file does not yet support: |
| 11 | 11 | // - C++ modules TS |
| 12 | 12 | |
| 13 | #include "demangle/DemangleConfig.h" | |
| 13 | 14 | #include "demangle/ItaniumDemangle.h" |
| 14 | 15 | #include "__cxxabi_config.h" |
| 15 | 16 | #include <cassert> |
| ... | ... | @@ -19,6 +20,7 @@ |
| 19 | 20 | #include <cstring> |
| 20 | 21 | #include <functional> |
| 21 | 22 | #include <numeric> |
| 23 | #include <string_view> | |
| 22 | 24 | #include <utility> |
| 23 | 25 | |
| 24 | 26 | using namespace itanium_demangle; |
| ... | ... | @@ -77,8 +79,8 @@ struct DumpVisitor { |
| 77 | 79 | } |
| 78 | 80 | |
| 79 | 81 | void printStr(const char *S) { fprintf(stderr, "%s", S); } |
| 80 | void print(StringView SV) { | |
| 81 | fprintf(stderr, "\"%.*s\"", (int)SV.size(), SV.begin()); | |
| 82 | void print(std::string_view SV) { | |
| 83 | fprintf(stderr, "\"%.*s\"", (int)SV.size(), &*SV.begin()); | |
| 82 | 84 | } |
| 83 | 85 | void print(const Node *N) { |
| 84 | 86 | if (N) |
lib/libcxxabi/src/cxa_guard_impl.h+3-3| ... | ... | @@ -255,7 +255,7 @@ struct InitByteNoThreads { |
| 255 | 255 | if (*init_byte_address == COMPLETE_BIT) |
| 256 | 256 | return true; |
| 257 | 257 | if (*init_byte_address & PENDING_BIT) |
| 258 | ABORT_WITH_MESSAGE("__cxa_guard_acquire detected recursive initialization"); | |
| 258 | ABORT_WITH_MESSAGE("__cxa_guard_acquire detected recursive initialization: do you have a function-local static variable whose initialization depends on that function?"); | |
| 259 | 259 | *init_byte_address = PENDING_BIT; |
| 260 | 260 | return false; |
| 261 | 261 | } |
| ... | ... | @@ -325,7 +325,7 @@ public: |
| 325 | 325 | // Check for possible recursive initialization. |
| 326 | 326 | if (has_thread_id_support && (*init_byte_address & PENDING_BIT)) { |
| 327 | 327 | if (*thread_id_address == current_thread_id.get()) |
| 328 | ABORT_WITH_MESSAGE("__cxa_guard_acquire detected recursive initialization"); | |
| 328 | ABORT_WITH_MESSAGE("__cxa_guard_acquire detected recursive initialization: do you have a function-local static variable whose initialization depends on that function?"); | |
| 329 | 329 | } |
| 330 | 330 | |
| 331 | 331 | // Wait until the pending bit is not set. |
| ... | ... | @@ -460,7 +460,7 @@ public: |
| 460 | 460 | |
| 461 | 461 | // Check for recursive initialization |
| 462 | 462 | if (has_thread_id_support && thread_id.load(std::_AO_Relaxed) == current_thread_id.get()) { |
| 463 | ABORT_WITH_MESSAGE("__cxa_guard_acquire detected recursive initialization"); | |
| 463 | ABORT_WITH_MESSAGE("__cxa_guard_acquire detected recursive initialization: do you have a function-local static variable whose initialization depends on that function?"); | |
| 464 | 464 | } |
| 465 | 465 | |
| 466 | 466 | if ((last_val & WAITING_BIT) == 0) { |
lib/libcxxabi/src/demangle/DemangleConfig.h+8| ... | ... | @@ -11,6 +11,14 @@ |
| 11 | 11 | #ifndef LIBCXXABI_DEMANGLE_DEMANGLE_CONFIG_H |
| 12 | 12 | #define LIBCXXABI_DEMANGLE_DEMANGLE_CONFIG_H |
| 13 | 13 | |
| 14 | // Must be defined before pulling in headers from libc++. Allow downstream | |
| 15 | // build systems to override this value. | |
| 16 | // https://libcxx.llvm.org/UsingLibcxx.html#enabling-the-safe-libc-mode | |
| 17 | #ifndef _LIBCPP_VERBOSE_ABORT | |
| 18 | #define _LIBCPP_VERBOSE_ABORT(...) abort_message(__VA_ARGS__) | |
| 19 | #include "../abort_message.h" | |
| 20 | #endif | |
| 21 | ||
| 14 | 22 | #include <ciso646> |
| 15 | 23 | |
| 16 | 24 | #ifdef _MSC_VER |
lib/libcxxabi/src/demangle/ItaniumDemangle.h+154-134| ... | ... | @@ -17,8 +17,9 @@ |
| 17 | 17 | #define DEMANGLE_ITANIUMDEMANGLE_H |
| 18 | 18 | |
| 19 | 19 | #include "DemangleConfig.h" |
| 20 | #include "StringView.h" | |
| 20 | #include "StringViewExtras.h" | |
| 21 | 21 | #include "Utility.h" |
| 22 | #include <__cxxabi_config.h> | |
| 22 | 23 | #include <algorithm> |
| 23 | 24 | #include <cassert> |
| 24 | 25 | #include <cctype> |
| ... | ... | @@ -27,8 +28,15 @@ |
| 27 | 28 | #include <cstring> |
| 28 | 29 | #include <limits> |
| 29 | 30 | #include <new> |
| 31 | #include <string_view> | |
| 32 | #include <type_traits> | |
| 30 | 33 | #include <utility> |
| 31 | 34 | |
| 35 | #ifdef _LIBCXXABI_COMPILER_CLANG | |
| 36 | #pragma clang diagnostic push | |
| 37 | #pragma clang diagnostic ignored "-Wunused-template" | |
| 38 | #endif | |
| 39 | ||
| 32 | 40 | DEMANGLE_NAMESPACE_BEGIN |
| 33 | 41 | |
| 34 | 42 | template <class T, size_t N> class PODSmallVector { |
| ... | ... | @@ -286,7 +294,7 @@ public: |
| 286 | 294 | // implementation. |
| 287 | 295 | virtual void printRight(OutputBuffer &) const {} |
| 288 | 296 | |
| 289 | virtual StringView getBaseName() const { return StringView(); } | |
| 297 | virtual std::string_view getBaseName() const { return {}; } | |
| 290 | 298 | |
| 291 | 299 | // Silence compiler warnings, this dtor will never be called. |
| 292 | 300 | virtual ~Node() = default; |
| ... | ... | @@ -345,10 +353,10 @@ struct NodeArrayNode : Node { |
| 345 | 353 | |
| 346 | 354 | class DotSuffix final : public Node { |
| 347 | 355 | const Node *Prefix; |
| 348 | const StringView Suffix; | |
| 356 | const std::string_view Suffix; | |
| 349 | 357 | |
| 350 | 358 | public: |
| 351 | DotSuffix(const Node *Prefix_, StringView Suffix_) | |
| 359 | DotSuffix(const Node *Prefix_, std::string_view Suffix_) | |
| 352 | 360 | : Node(KDotSuffix), Prefix(Prefix_), Suffix(Suffix_) {} |
| 353 | 361 | |
| 354 | 362 | template<typename Fn> void match(Fn F) const { F(Prefix, Suffix); } |
| ... | ... | @@ -363,15 +371,15 @@ public: |
| 363 | 371 | |
| 364 | 372 | class VendorExtQualType final : public Node { |
| 365 | 373 | const Node *Ty; |
| 366 | StringView Ext; | |
| 374 | std::string_view Ext; | |
| 367 | 375 | const Node *TA; |
| 368 | 376 | |
| 369 | 377 | public: |
| 370 | VendorExtQualType(const Node *Ty_, StringView Ext_, const Node *TA_) | |
| 378 | VendorExtQualType(const Node *Ty_, std::string_view Ext_, const Node *TA_) | |
| 371 | 379 | : Node(KVendorExtQualType), Ty(Ty_), Ext(Ext_), TA(TA_) {} |
| 372 | 380 | |
| 373 | 381 | const Node *getTy() const { return Ty; } |
| 374 | StringView getExt() const { return Ext; } | |
| 382 | std::string_view getExt() const { return Ext; } | |
| 375 | 383 | const Node *getTA() const { return TA; } |
| 376 | 384 | |
| 377 | 385 | template <typename Fn> void match(Fn F) const { F(Ty, Ext, TA); } |
| ... | ... | @@ -462,10 +470,10 @@ public: |
| 462 | 470 | |
| 463 | 471 | class PostfixQualifiedType final : public Node { |
| 464 | 472 | const Node *Ty; |
| 465 | const StringView Postfix; | |
| 473 | const std::string_view Postfix; | |
| 466 | 474 | |
| 467 | 475 | public: |
| 468 | PostfixQualifiedType(const Node *Ty_, StringView Postfix_) | |
| 476 | PostfixQualifiedType(const Node *Ty_, std::string_view Postfix_) | |
| 469 | 477 | : Node(KPostfixQualifiedType), Ty(Ty_), Postfix(Postfix_) {} |
| 470 | 478 | |
| 471 | 479 | template<typename Fn> void match(Fn F) const { F(Ty, Postfix); } |
| ... | ... | @@ -477,15 +485,15 @@ public: |
| 477 | 485 | }; |
| 478 | 486 | |
| 479 | 487 | class NameType final : public Node { |
| 480 | const StringView Name; | |
| 488 | const std::string_view Name; | |
| 481 | 489 | |
| 482 | 490 | public: |
| 483 | NameType(StringView Name_) : Node(KNameType), Name(Name_) {} | |
| 491 | NameType(std::string_view Name_) : Node(KNameType), Name(Name_) {} | |
| 484 | 492 | |
| 485 | 493 | template<typename Fn> void match(Fn F) const { F(Name); } |
| 486 | 494 | |
| 487 | StringView getName() const { return Name; } | |
| 488 | StringView getBaseName() const override { return Name; } | |
| 495 | std::string_view getName() const { return Name; } | |
| 496 | std::string_view getBaseName() const override { return Name; } | |
| 489 | 497 | |
| 490 | 498 | void printLeft(OutputBuffer &OB) const override { OB += Name; } |
| 491 | 499 | }; |
| ... | ... | @@ -511,10 +519,10 @@ public: |
| 511 | 519 | }; |
| 512 | 520 | |
| 513 | 521 | class ElaboratedTypeSpefType : public Node { |
| 514 | StringView Kind; | |
| 522 | std::string_view Kind; | |
| 515 | 523 | Node *Child; |
| 516 | 524 | public: |
| 517 | ElaboratedTypeSpefType(StringView Kind_, Node *Child_) | |
| 525 | ElaboratedTypeSpefType(std::string_view Kind_, Node *Child_) | |
| 518 | 526 | : Node(KElaboratedTypeSpefType), Kind(Kind_), Child(Child_) {} |
| 519 | 527 | |
| 520 | 528 | template<typename Fn> void match(Fn F) const { F(Kind, Child); } |
| ... | ... | @@ -528,15 +536,17 @@ public: |
| 528 | 536 | |
| 529 | 537 | struct AbiTagAttr : Node { |
| 530 | 538 | Node *Base; |
| 531 | StringView Tag; | |
| 539 | std::string_view Tag; | |
| 532 | 540 | |
| 533 | AbiTagAttr(Node* Base_, StringView Tag_) | |
| 534 | : Node(KAbiTagAttr, Base_->RHSComponentCache, | |
| 535 | Base_->ArrayCache, Base_->FunctionCache), | |
| 541 | AbiTagAttr(Node *Base_, std::string_view Tag_) | |
| 542 | : Node(KAbiTagAttr, Base_->RHSComponentCache, Base_->ArrayCache, | |
| 543 | Base_->FunctionCache), | |
| 536 | 544 | Base(Base_), Tag(Tag_) {} |
| 537 | 545 | |
| 538 | 546 | template<typename Fn> void match(Fn F) const { F(Base, Tag); } |
| 539 | 547 | |
| 548 | std::string_view getBaseName() const override { return Base->getBaseName(); } | |
| 549 | ||
| 540 | 550 | void printLeft(OutputBuffer &OB) const override { |
| 541 | 551 | Base->printLeft(OB); |
| 542 | 552 | OB += "[abi:"; |
| ... | ... | @@ -562,12 +572,12 @@ public: |
| 562 | 572 | |
| 563 | 573 | class ObjCProtoName : public Node { |
| 564 | 574 | const Node *Ty; |
| 565 | StringView Protocol; | |
| 575 | std::string_view Protocol; | |
| 566 | 576 | |
| 567 | 577 | friend class PointerType; |
| 568 | 578 | |
| 569 | 579 | public: |
| 570 | ObjCProtoName(const Node *Ty_, StringView Protocol_) | |
| 580 | ObjCProtoName(const Node *Ty_, std::string_view Protocol_) | |
| 571 | 581 | : Node(KObjCProtoName), Ty(Ty_), Protocol(Protocol_) {} |
| 572 | 582 | |
| 573 | 583 | template<typename Fn> void match(Fn F) const { F(Ty, Protocol); } |
| ... | ... | @@ -944,11 +954,11 @@ public: |
| 944 | 954 | }; |
| 945 | 955 | |
| 946 | 956 | class SpecialName final : public Node { |
| 947 | const StringView Special; | |
| 957 | const std::string_view Special; | |
| 948 | 958 | const Node *Child; |
| 949 | 959 | |
| 950 | 960 | public: |
| 951 | SpecialName(StringView Special_, const Node *Child_) | |
| 961 | SpecialName(std::string_view Special_, const Node *Child_) | |
| 952 | 962 | : Node(KSpecialName), Special(Special_), Child(Child_) {} |
| 953 | 963 | |
| 954 | 964 | template<typename Fn> void match(Fn F) const { F(Special, Child); } |
| ... | ... | @@ -987,7 +997,7 @@ struct NestedName : Node { |
| 987 | 997 | |
| 988 | 998 | template<typename Fn> void match(Fn F) const { F(Qual, Name); } |
| 989 | 999 | |
| 990 | StringView getBaseName() const override { return Name->getBaseName(); } | |
| 1000 | std::string_view getBaseName() const override { return Name->getBaseName(); } | |
| 991 | 1001 | |
| 992 | 1002 | void printLeft(OutputBuffer &OB) const override { |
| 993 | 1003 | Qual->print(OB); |
| ... | ... | @@ -1027,7 +1037,7 @@ struct ModuleEntity : Node { |
| 1027 | 1037 | |
| 1028 | 1038 | template <typename Fn> void match(Fn F) const { F(Module, Name); } |
| 1029 | 1039 | |
| 1030 | StringView getBaseName() const override { return Name->getBaseName(); } | |
| 1040 | std::string_view getBaseName() const override { return Name->getBaseName(); } | |
| 1031 | 1041 | |
| 1032 | 1042 | void printLeft(OutputBuffer &OB) const override { |
| 1033 | 1043 | Name->print(OB); |
| ... | ... | @@ -1063,7 +1073,7 @@ public: |
| 1063 | 1073 | |
| 1064 | 1074 | template<typename Fn> void match(Fn F) const { F(Qualifier, Name); } |
| 1065 | 1075 | |
| 1066 | StringView getBaseName() const override { return Name->getBaseName(); } | |
| 1076 | std::string_view getBaseName() const override { return Name->getBaseName(); } | |
| 1067 | 1077 | |
| 1068 | 1078 | void printLeft(OutputBuffer &OB) const override { |
| 1069 | 1079 | Qualifier->print(OB); |
| ... | ... | @@ -1485,7 +1495,7 @@ struct NameWithTemplateArgs : Node { |
| 1485 | 1495 | |
| 1486 | 1496 | template<typename Fn> void match(Fn F) const { F(Name, TemplateArgs); } |
| 1487 | 1497 | |
| 1488 | StringView getBaseName() const override { return Name->getBaseName(); } | |
| 1498 | std::string_view getBaseName() const override { return Name->getBaseName(); } | |
| 1489 | 1499 | |
| 1490 | 1500 | void printLeft(OutputBuffer &OB) const override { |
| 1491 | 1501 | Name->print(OB); |
| ... | ... | @@ -1502,7 +1512,7 @@ public: |
| 1502 | 1512 | |
| 1503 | 1513 | template<typename Fn> void match(Fn F) const { F(Child); } |
| 1504 | 1514 | |
| 1505 | StringView getBaseName() const override { return Child->getBaseName(); } | |
| 1515 | std::string_view getBaseName() const override { return Child->getBaseName(); } | |
| 1506 | 1516 | |
| 1507 | 1517 | void printLeft(OutputBuffer &OB) const override { |
| 1508 | 1518 | OB += "::"; |
| ... | ... | @@ -1538,20 +1548,20 @@ protected: |
| 1538 | 1548 | return unsigned(SSK) >= unsigned(SpecialSubKind::string); |
| 1539 | 1549 | } |
| 1540 | 1550 | |
| 1541 | StringView getBaseName() const override { | |
| 1551 | std::string_view getBaseName() const override { | |
| 1542 | 1552 | switch (SSK) { |
| 1543 | 1553 | case SpecialSubKind::allocator: |
| 1544 | return StringView("allocator"); | |
| 1554 | return {"allocator"}; | |
| 1545 | 1555 | case SpecialSubKind::basic_string: |
| 1546 | return StringView("basic_string"); | |
| 1556 | return {"basic_string"}; | |
| 1547 | 1557 | case SpecialSubKind::string: |
| 1548 | return StringView("basic_string"); | |
| 1558 | return {"basic_string"}; | |
| 1549 | 1559 | case SpecialSubKind::istream: |
| 1550 | return StringView("basic_istream"); | |
| 1560 | return {"basic_istream"}; | |
| 1551 | 1561 | case SpecialSubKind::ostream: |
| 1552 | return StringView("basic_ostream"); | |
| 1562 | return {"basic_ostream"}; | |
| 1553 | 1563 | case SpecialSubKind::iostream: |
| 1554 | return StringView("basic_iostream"); | |
| 1564 | return {"basic_iostream"}; | |
| 1555 | 1565 | } |
| 1556 | 1566 | DEMANGLE_UNREACHABLE; |
| 1557 | 1567 | } |
| ... | ... | @@ -1575,12 +1585,12 @@ public: |
| 1575 | 1585 | |
| 1576 | 1586 | template<typename Fn> void match(Fn F) const { F(SSK); } |
| 1577 | 1587 | |
| 1578 | StringView getBaseName() const override { | |
| 1579 | auto SV = ExpandedSpecialSubstitution::getBaseName (); | |
| 1588 | std::string_view getBaseName() const override { | |
| 1589 | std::string_view SV = ExpandedSpecialSubstitution::getBaseName(); | |
| 1580 | 1590 | if (isInstantiation()) { |
| 1581 | 1591 | // The instantiations are typedefs that drop the "basic_" prefix. |
| 1582 | assert(SV.startsWith("basic_")); | |
| 1583 | SV = SV.dropFront(sizeof("basic_") - 1); | |
| 1592 | assert(starts_with(SV, "basic_")); | |
| 1593 | SV.remove_prefix(sizeof("basic_") - 1); | |
| 1584 | 1594 | } |
| 1585 | 1595 | return SV; |
| 1586 | 1596 | } |
| ... | ... | @@ -1628,10 +1638,11 @@ public: |
| 1628 | 1638 | }; |
| 1629 | 1639 | |
| 1630 | 1640 | class UnnamedTypeName : public Node { |
| 1631 | const StringView Count; | |
| 1641 | const std::string_view Count; | |
| 1632 | 1642 | |
| 1633 | 1643 | public: |
| 1634 | UnnamedTypeName(StringView Count_) : Node(KUnnamedTypeName), Count(Count_) {} | |
| 1644 | UnnamedTypeName(std::string_view Count_) | |
| 1645 | : Node(KUnnamedTypeName), Count(Count_) {} | |
| 1635 | 1646 | |
| 1636 | 1647 | template<typename Fn> void match(Fn F) const { F(Count); } |
| 1637 | 1648 | |
| ... | ... | @@ -1645,11 +1656,11 @@ public: |
| 1645 | 1656 | class ClosureTypeName : public Node { |
| 1646 | 1657 | NodeArray TemplateParams; |
| 1647 | 1658 | NodeArray Params; |
| 1648 | StringView Count; | |
| 1659 | std::string_view Count; | |
| 1649 | 1660 | |
| 1650 | 1661 | public: |
| 1651 | 1662 | ClosureTypeName(NodeArray TemplateParams_, NodeArray Params_, |
| 1652 | StringView Count_) | |
| 1663 | std::string_view Count_) | |
| 1653 | 1664 | : Node(KClosureTypeName), TemplateParams(TemplateParams_), |
| 1654 | 1665 | Params(Params_), Count(Count_) {} |
| 1655 | 1666 | |
| ... | ... | @@ -1696,12 +1707,12 @@ public: |
| 1696 | 1707 | |
| 1697 | 1708 | class BinaryExpr : public Node { |
| 1698 | 1709 | const Node *LHS; |
| 1699 | const StringView InfixOperator; | |
| 1710 | const std::string_view InfixOperator; | |
| 1700 | 1711 | const Node *RHS; |
| 1701 | 1712 | |
| 1702 | 1713 | public: |
| 1703 | BinaryExpr(const Node *LHS_, StringView InfixOperator_, const Node *RHS_, | |
| 1704 | Prec Prec_) | |
| 1714 | BinaryExpr(const Node *LHS_, std::string_view InfixOperator_, | |
| 1715 | const Node *RHS_, Prec Prec_) | |
| 1705 | 1716 | : Node(KBinaryExpr, Prec_), LHS(LHS_), InfixOperator(InfixOperator_), |
| 1706 | 1717 | RHS(RHS_) {} |
| 1707 | 1718 | |
| ... | ... | @@ -1750,10 +1761,10 @@ public: |
| 1750 | 1761 | |
| 1751 | 1762 | class PostfixExpr : public Node { |
| 1752 | 1763 | const Node *Child; |
| 1753 | const StringView Operator; | |
| 1764 | const std::string_view Operator; | |
| 1754 | 1765 | |
| 1755 | 1766 | public: |
| 1756 | PostfixExpr(const Node *Child_, StringView Operator_, Prec Prec_) | |
| 1767 | PostfixExpr(const Node *Child_, std::string_view Operator_, Prec Prec_) | |
| 1757 | 1768 | : Node(KPostfixExpr, Prec_), Child(Child_), Operator(Operator_) {} |
| 1758 | 1769 | |
| 1759 | 1770 | template <typename Fn> void match(Fn F) const { |
| ... | ... | @@ -1791,11 +1802,12 @@ public: |
| 1791 | 1802 | |
| 1792 | 1803 | class MemberExpr : public Node { |
| 1793 | 1804 | const Node *LHS; |
| 1794 | const StringView Kind; | |
| 1805 | const std::string_view Kind; | |
| 1795 | 1806 | const Node *RHS; |
| 1796 | 1807 | |
| 1797 | 1808 | public: |
| 1798 | MemberExpr(const Node *LHS_, StringView Kind_, const Node *RHS_, Prec Prec_) | |
| 1809 | MemberExpr(const Node *LHS_, std::string_view Kind_, const Node *RHS_, | |
| 1810 | Prec Prec_) | |
| 1799 | 1811 | : Node(KMemberExpr, Prec_), LHS(LHS_), Kind(Kind_), RHS(RHS_) {} |
| 1800 | 1812 | |
| 1801 | 1813 | template <typename Fn> void match(Fn F) const { |
| ... | ... | @@ -1812,13 +1824,14 @@ public: |
| 1812 | 1824 | class SubobjectExpr : public Node { |
| 1813 | 1825 | const Node *Type; |
| 1814 | 1826 | const Node *SubExpr; |
| 1815 | StringView Offset; | |
| 1827 | std::string_view Offset; | |
| 1816 | 1828 | NodeArray UnionSelectors; |
| 1817 | 1829 | bool OnePastTheEnd; |
| 1818 | 1830 | |
| 1819 | 1831 | public: |
| 1820 | SubobjectExpr(const Node *Type_, const Node *SubExpr_, StringView Offset_, | |
| 1821 | NodeArray UnionSelectors_, bool OnePastTheEnd_) | |
| 1832 | SubobjectExpr(const Node *Type_, const Node *SubExpr_, | |
| 1833 | std::string_view Offset_, NodeArray UnionSelectors_, | |
| 1834 | bool OnePastTheEnd_) | |
| 1822 | 1835 | : Node(KSubobjectExpr), Type(Type_), SubExpr(SubExpr_), Offset(Offset_), |
| 1823 | 1836 | UnionSelectors(UnionSelectors_), OnePastTheEnd(OnePastTheEnd_) {} |
| 1824 | 1837 | |
| ... | ... | @@ -1835,7 +1848,7 @@ public: |
| 1835 | 1848 | OB += "0"; |
| 1836 | 1849 | } else if (Offset[0] == 'n') { |
| 1837 | 1850 | OB += "-"; |
| 1838 | OB += Offset.dropFront(); | |
| 1851 | OB += std::string_view(Offset.data() + 1, Offset.size() - 1); | |
| 1839 | 1852 | } else { |
| 1840 | 1853 | OB += Offset; |
| 1841 | 1854 | } |
| ... | ... | @@ -1844,12 +1857,12 @@ public: |
| 1844 | 1857 | }; |
| 1845 | 1858 | |
| 1846 | 1859 | class EnclosingExpr : public Node { |
| 1847 | const StringView Prefix; | |
| 1860 | const std::string_view Prefix; | |
| 1848 | 1861 | const Node *Infix; |
| 1849 | const StringView Postfix; | |
| 1862 | const std::string_view Postfix; | |
| 1850 | 1863 | |
| 1851 | 1864 | public: |
| 1852 | EnclosingExpr(StringView Prefix_, const Node *Infix_, | |
| 1865 | EnclosingExpr(std::string_view Prefix_, const Node *Infix_, | |
| 1853 | 1866 | Prec Prec_ = Prec::Primary) |
| 1854 | 1867 | : Node(KEnclosingExpr, Prec_), Prefix(Prefix_), Infix(Infix_) {} |
| 1855 | 1868 | |
| ... | ... | @@ -1868,12 +1881,13 @@ public: |
| 1868 | 1881 | |
| 1869 | 1882 | class CastExpr : public Node { |
| 1870 | 1883 | // cast_kind<to>(from) |
| 1871 | const StringView CastKind; | |
| 1884 | const std::string_view CastKind; | |
| 1872 | 1885 | const Node *To; |
| 1873 | 1886 | const Node *From; |
| 1874 | 1887 | |
| 1875 | 1888 | public: |
| 1876 | CastExpr(StringView CastKind_, const Node *To_, const Node *From_, Prec Prec_) | |
| 1889 | CastExpr(std::string_view CastKind_, const Node *To_, const Node *From_, | |
| 1890 | Prec Prec_) | |
| 1877 | 1891 | : Node(KCastExpr, Prec_), CastKind(CastKind_), To(To_), From(From_) {} |
| 1878 | 1892 | |
| 1879 | 1893 | template <typename Fn> void match(Fn F) const { |
| ... | ... | @@ -1996,11 +2010,11 @@ public: |
| 1996 | 2010 | }; |
| 1997 | 2011 | |
| 1998 | 2012 | class PrefixExpr : public Node { |
| 1999 | StringView Prefix; | |
| 2013 | std::string_view Prefix; | |
| 2000 | 2014 | Node *Child; |
| 2001 | 2015 | |
| 2002 | 2016 | public: |
| 2003 | PrefixExpr(StringView Prefix_, Node *Child_, Prec Prec_) | |
| 2017 | PrefixExpr(std::string_view Prefix_, Node *Child_, Prec Prec_) | |
| 2004 | 2018 | : Node(KPrefixExpr, Prec_), Prefix(Prefix_), Child(Child_) {} |
| 2005 | 2019 | |
| 2006 | 2020 | template <typename Fn> void match(Fn F) const { |
| ... | ... | @@ -2014,10 +2028,11 @@ public: |
| 2014 | 2028 | }; |
| 2015 | 2029 | |
| 2016 | 2030 | class FunctionParam : public Node { |
| 2017 | StringView Number; | |
| 2031 | std::string_view Number; | |
| 2018 | 2032 | |
| 2019 | 2033 | public: |
| 2020 | FunctionParam(StringView Number_) : Node(KFunctionParam), Number(Number_) {} | |
| 2034 | FunctionParam(std::string_view Number_) | |
| 2035 | : Node(KFunctionParam), Number(Number_) {} | |
| 2021 | 2036 | |
| 2022 | 2037 | template<typename Fn> void match(Fn F) const { F(Number); } |
| 2023 | 2038 | |
| ... | ... | @@ -2052,11 +2067,11 @@ public: |
| 2052 | 2067 | class PointerToMemberConversionExpr : public Node { |
| 2053 | 2068 | const Node *Type; |
| 2054 | 2069 | const Node *SubExpr; |
| 2055 | StringView Offset; | |
| 2070 | std::string_view Offset; | |
| 2056 | 2071 | |
| 2057 | 2072 | public: |
| 2058 | 2073 | PointerToMemberConversionExpr(const Node *Type_, const Node *SubExpr_, |
| 2059 | StringView Offset_, Prec Prec_) | |
| 2074 | std::string_view Offset_, Prec Prec_) | |
| 2060 | 2075 | : Node(KPointerToMemberConversionExpr, Prec_), Type(Type_), |
| 2061 | 2076 | SubExpr(SubExpr_), Offset(Offset_) {} |
| 2062 | 2077 | |
| ... | ... | @@ -2141,11 +2156,11 @@ public: |
| 2141 | 2156 | |
| 2142 | 2157 | class FoldExpr : public Node { |
| 2143 | 2158 | const Node *Pack, *Init; |
| 2144 | StringView OperatorName; | |
| 2159 | std::string_view OperatorName; | |
| 2145 | 2160 | bool IsLeftFold; |
| 2146 | 2161 | |
| 2147 | 2162 | public: |
| 2148 | FoldExpr(bool IsLeftFold_, StringView OperatorName_, const Node *Pack_, | |
| 2163 | FoldExpr(bool IsLeftFold_, std::string_view OperatorName_, const Node *Pack_, | |
| 2149 | 2164 | const Node *Init_) |
| 2150 | 2165 | : Node(KFoldExpr), Pack(Pack_), Init(Init_), OperatorName(OperatorName_), |
| 2151 | 2166 | IsLeftFold(IsLeftFold_) {} |
| ... | ... | @@ -2209,7 +2224,7 @@ public: |
| 2209 | 2224 | template<typename Fn> void match(Fn F) const { F(Value); } |
| 2210 | 2225 | |
| 2211 | 2226 | void printLeft(OutputBuffer &OB) const override { |
| 2212 | OB += Value ? StringView("true") : StringView("false"); | |
| 2227 | OB += Value ? std::string_view("true") : std::string_view("false"); | |
| 2213 | 2228 | } |
| 2214 | 2229 | }; |
| 2215 | 2230 | |
| ... | ... | @@ -2247,10 +2262,10 @@ public: |
| 2247 | 2262 | class EnumLiteral : public Node { |
| 2248 | 2263 | // ty(integer) |
| 2249 | 2264 | const Node *Ty; |
| 2250 | StringView Integer; | |
| 2265 | std::string_view Integer; | |
| 2251 | 2266 | |
| 2252 | 2267 | public: |
| 2253 | EnumLiteral(const Node *Ty_, StringView Integer_) | |
| 2268 | EnumLiteral(const Node *Ty_, std::string_view Integer_) | |
| 2254 | 2269 | : Node(KEnumLiteral), Ty(Ty_), Integer(Integer_) {} |
| 2255 | 2270 | |
| 2256 | 2271 | template<typename Fn> void match(Fn F) const { F(Ty, Integer); } |
| ... | ... | @@ -2261,18 +2276,18 @@ public: |
| 2261 | 2276 | OB.printClose(); |
| 2262 | 2277 | |
| 2263 | 2278 | if (Integer[0] == 'n') |
| 2264 | OB << "-" << Integer.dropFront(1); | |
| 2279 | OB << '-' << std::string_view(Integer.data() + 1, Integer.size() - 1); | |
| 2265 | 2280 | else |
| 2266 | 2281 | OB << Integer; |
| 2267 | 2282 | } |
| 2268 | 2283 | }; |
| 2269 | 2284 | |
| 2270 | 2285 | class IntegerLiteral : public Node { |
| 2271 | StringView Type; | |
| 2272 | StringView Value; | |
| 2286 | std::string_view Type; | |
| 2287 | std::string_view Value; | |
| 2273 | 2288 | |
| 2274 | 2289 | public: |
| 2275 | IntegerLiteral(StringView Type_, StringView Value_) | |
| 2290 | IntegerLiteral(std::string_view Type_, std::string_view Value_) | |
| 2276 | 2291 | : Node(KIntegerLiteral), Type(Type_), Value(Value_) {} |
| 2277 | 2292 | |
| 2278 | 2293 | template<typename Fn> void match(Fn F) const { F(Type, Value); } |
| ... | ... | @@ -2284,10 +2299,9 @@ public: |
| 2284 | 2299 | OB.printClose(); |
| 2285 | 2300 | } |
| 2286 | 2301 | |
| 2287 | if (Value[0] == 'n') { | |
| 2288 | OB += '-'; | |
| 2289 | OB += Value.dropFront(1); | |
| 2290 | } else | |
| 2302 | if (Value[0] == 'n') | |
| 2303 | OB << '-' << std::string_view(Value.data() + 1, Value.size() - 1); | |
| 2304 | else | |
| 2291 | 2305 | OB += Value; |
| 2292 | 2306 | |
| 2293 | 2307 | if (Type.size() <= 3) |
| ... | ... | @@ -2310,29 +2324,26 @@ constexpr Node::Kind getFloatLiteralKind(long double *) { |
| 2310 | 2324 | } |
| 2311 | 2325 | |
| 2312 | 2326 | template <class Float> class FloatLiteralImpl : public Node { |
| 2313 | const StringView Contents; | |
| 2327 | const std::string_view Contents; | |
| 2314 | 2328 | |
| 2315 | 2329 | static constexpr Kind KindForClass = |
| 2316 | 2330 | float_literal_impl::getFloatLiteralKind((Float *)nullptr); |
| 2317 | 2331 | |
| 2318 | 2332 | public: |
| 2319 | FloatLiteralImpl(StringView Contents_) | |
| 2333 | FloatLiteralImpl(std::string_view Contents_) | |
| 2320 | 2334 | : Node(KindForClass), Contents(Contents_) {} |
| 2321 | 2335 | |
| 2322 | 2336 | template<typename Fn> void match(Fn F) const { F(Contents); } |
| 2323 | 2337 | |
| 2324 | 2338 | void printLeft(OutputBuffer &OB) const override { |
| 2325 | const char *first = Contents.begin(); | |
| 2326 | const char *last = Contents.end() + 1; | |
| 2327 | ||
| 2328 | 2339 | const size_t N = FloatData<Float>::mangled_size; |
| 2329 | if (static_cast<std::size_t>(last - first) > N) { | |
| 2330 | last = first + N; | |
| 2340 | if (Contents.size() >= N) { | |
| 2331 | 2341 | union { |
| 2332 | 2342 | Float value; |
| 2333 | 2343 | char buf[sizeof(Float)]; |
| 2334 | 2344 | }; |
| 2335 | const char *t = first; | |
| 2345 | const char *t = Contents.data(); | |
| 2346 | const char *last = t + N; | |
| 2336 | 2347 | char *e = buf; |
| 2337 | 2348 | for (; t != last; ++t, ++e) { |
| 2338 | 2349 | unsigned d1 = isdigit(*t) ? static_cast<unsigned>(*t - '0') |
| ... | ... | @@ -2347,7 +2358,7 @@ public: |
| 2347 | 2358 | #endif |
| 2348 | 2359 | char num[FloatData<Float>::max_demangled_size] = {0}; |
| 2349 | 2360 | int n = snprintf(num, sizeof(num), FloatData<Float>::spec, value); |
| 2350 | OB += StringView(num, num + n); | |
| 2361 | OB += std::string_view(num, n); | |
| 2351 | 2362 | } |
| 2352 | 2363 | } |
| 2353 | 2364 | }; |
| ... | ... | @@ -2474,8 +2485,8 @@ template <typename Derived, typename Alloc> struct AbstractManglingParser { |
| 2474 | 2485 | return res; |
| 2475 | 2486 | } |
| 2476 | 2487 | |
| 2477 | bool consumeIf(StringView S) { | |
| 2478 | if (StringView(First, Last).startsWith(S)) { | |
| 2488 | bool consumeIf(std::string_view S) { | |
| 2489 | if (starts_with(std::string_view(First, Last - First), S)) { | |
| 2479 | 2490 | First += S.size(); |
| 2480 | 2491 | return true; |
| 2481 | 2492 | } |
| ... | ... | @@ -2500,10 +2511,10 @@ template <typename Derived, typename Alloc> struct AbstractManglingParser { |
| 2500 | 2511 | |
| 2501 | 2512 | size_t numLeft() const { return static_cast<size_t>(Last - First); } |
| 2502 | 2513 | |
| 2503 | StringView parseNumber(bool AllowNegative = false); | |
| 2514 | std::string_view parseNumber(bool AllowNegative = false); | |
| 2504 | 2515 | Qualifiers parseCVQualifiers(); |
| 2505 | 2516 | bool parsePositiveInteger(size_t *Out); |
| 2506 | StringView parseBareSourceName(); | |
| 2517 | std::string_view parseBareSourceName(); | |
| 2507 | 2518 | |
| 2508 | 2519 | bool parseSeqId(size_t *Out); |
| 2509 | 2520 | Node *parseSubstitution(); |
| ... | ... | @@ -2514,9 +2525,9 @@ template <typename Derived, typename Alloc> struct AbstractManglingParser { |
| 2514 | 2525 | |
| 2515 | 2526 | /// Parse the <expr> production. |
| 2516 | 2527 | Node *parseExpr(); |
| 2517 | Node *parsePrefixExpr(StringView Kind, Node::Prec Prec); | |
| 2518 | Node *parseBinaryExpr(StringView Kind, Node::Prec Prec); | |
| 2519 | Node *parseIntegerLiteral(StringView Lit); | |
| 2528 | Node *parsePrefixExpr(std::string_view Kind, Node::Prec Prec); | |
| 2529 | Node *parseBinaryExpr(std::string_view Kind, Node::Prec Prec); | |
| 2530 | Node *parseIntegerLiteral(std::string_view Lit); | |
| 2520 | 2531 | Node *parseExprPrimary(); |
| 2521 | 2532 | template <class Float> Node *parseFloatingLiteral(); |
| 2522 | 2533 | Node *parseFunctionParam(); |
| ... | ... | @@ -2624,17 +2635,18 @@ template <typename Derived, typename Alloc> struct AbstractManglingParser { |
| 2624 | 2635 | bool operator!=(const char *Peek) const { return !this->operator==(Peek); } |
| 2625 | 2636 | |
| 2626 | 2637 | public: |
| 2627 | StringView getSymbol() const { | |
| 2628 | StringView Res = Name; | |
| 2638 | std::string_view getSymbol() const { | |
| 2639 | std::string_view Res = Name; | |
| 2629 | 2640 | if (Kind < Unnameable) { |
| 2630 | assert(Res.startsWith("operator") && | |
| 2641 | assert(starts_with(Res, "operator") && | |
| 2631 | 2642 | "operator name does not start with 'operator'"); |
| 2632 | Res = Res.dropFront(sizeof("operator") - 1); | |
| 2633 | Res.consumeFront(' '); | |
| 2643 | Res.remove_prefix(sizeof("operator") - 1); | |
| 2644 | if (starts_with(Res, ' ')) | |
| 2645 | Res.remove_prefix(1); | |
| 2634 | 2646 | } |
| 2635 | 2647 | return Res; |
| 2636 | 2648 | } |
| 2637 | StringView getName() const { return Name; } | |
| 2649 | std::string_view getName() const { return Name; } | |
| 2638 | 2650 | OIKind getKind() const { return Kind; } |
| 2639 | 2651 | bool getFlag() const { return Flag; } |
| 2640 | 2652 | Node::Prec getPrecedence() const { return Prec; } |
| ... | ... | @@ -2854,7 +2866,7 @@ AbstractManglingParser<Derived, Alloc>::parseUnnamedTypeName(NameState *State) { |
| 2854 | 2866 | TemplateParams.clear(); |
| 2855 | 2867 | |
| 2856 | 2868 | if (consumeIf("Ut")) { |
| 2857 | StringView Count = parseNumber(); | |
| 2869 | std::string_view Count = parseNumber(); | |
| 2858 | 2870 | if (!consumeIf('_')) |
| 2859 | 2871 | return nullptr; |
| 2860 | 2872 | return make<UnnamedTypeName>(Count); |
| ... | ... | @@ -2866,7 +2878,7 @@ AbstractManglingParser<Derived, Alloc>::parseUnnamedTypeName(NameState *State) { |
| 2866 | 2878 | |
| 2867 | 2879 | size_t ParamsBegin = Names.size(); |
| 2868 | 2880 | while (look() == 'T' && |
| 2869 | StringView("yptn").find(look(1)) != StringView::npos) { | |
| 2881 | std::string_view("yptn").find(look(1)) != std::string_view::npos) { | |
| 2870 | 2882 | Node *T = parseTemplateParamDecl(); |
| 2871 | 2883 | if (!T) |
| 2872 | 2884 | return nullptr; |
| ... | ... | @@ -2909,7 +2921,7 @@ AbstractManglingParser<Derived, Alloc>::parseUnnamedTypeName(NameState *State) { |
| 2909 | 2921 | } |
| 2910 | 2922 | NodeArray Params = popTrailingNodeArray(ParamsBegin); |
| 2911 | 2923 | |
| 2912 | StringView Count = parseNumber(); | |
| 2924 | std::string_view Count = parseNumber(); | |
| 2913 | 2925 | if (!consumeIf('_')) |
| 2914 | 2926 | return nullptr; |
| 2915 | 2927 | return make<ClosureTypeName>(TempParams, Params, Count); |
| ... | ... | @@ -2931,9 +2943,9 @@ Node *AbstractManglingParser<Derived, Alloc>::parseSourceName(NameState *) { |
| 2931 | 2943 | return nullptr; |
| 2932 | 2944 | if (numLeft() < Length || Length == 0) |
| 2933 | 2945 | return nullptr; |
| 2934 | StringView Name(First, First + Length); | |
| 2946 | std::string_view Name(First, Length); | |
| 2935 | 2947 | First += Length; |
| 2936 | if (Name.startsWith("_GLOBAL__N")) | |
| 2948 | if (starts_with(Name, "_GLOBAL__N")) | |
| 2937 | 2949 | return make<NameType>("(anonymous namespace)"); |
| 2938 | 2950 | return make<NameType>(Name); |
| 2939 | 2951 | } |
| ... | ... | @@ -3447,7 +3459,7 @@ Node *AbstractManglingParser<Derived, Alloc>::parseUnresolvedName(bool Global) { |
| 3447 | 3459 | template <typename Derived, typename Alloc> |
| 3448 | 3460 | Node *AbstractManglingParser<Derived, Alloc>::parseAbiTags(Node *N) { |
| 3449 | 3461 | while (consumeIf('B')) { |
| 3450 | StringView SN = parseBareSourceName(); | |
| 3462 | std::string_view SN = parseBareSourceName(); | |
| 3451 | 3463 | if (SN.empty()) |
| 3452 | 3464 | return nullptr; |
| 3453 | 3465 | N = make<AbiTagAttr>(N, SN); |
| ... | ... | @@ -3459,16 +3471,16 @@ Node *AbstractManglingParser<Derived, Alloc>::parseAbiTags(Node *N) { |
| 3459 | 3471 | |
| 3460 | 3472 | // <number> ::= [n] <non-negative decimal integer> |
| 3461 | 3473 | template <typename Alloc, typename Derived> |
| 3462 | StringView | |
| 3474 | std::string_view | |
| 3463 | 3475 | AbstractManglingParser<Alloc, Derived>::parseNumber(bool AllowNegative) { |
| 3464 | 3476 | const char *Tmp = First; |
| 3465 | 3477 | if (AllowNegative) |
| 3466 | 3478 | consumeIf('n'); |
| 3467 | 3479 | if (numLeft() == 0 || !std::isdigit(*First)) |
| 3468 | return StringView(); | |
| 3480 | return std::string_view(); | |
| 3469 | 3481 | while (numLeft() != 0 && std::isdigit(*First)) |
| 3470 | 3482 | ++First; |
| 3471 | return StringView(Tmp, First); | |
| 3483 | return std::string_view(Tmp, First - Tmp); | |
| 3472 | 3484 | } |
| 3473 | 3485 | |
| 3474 | 3486 | // <positive length number> ::= [0-9]* |
| ... | ... | @@ -3485,11 +3497,11 @@ bool AbstractManglingParser<Alloc, Derived>::parsePositiveInteger(size_t *Out) { |
| 3485 | 3497 | } |
| 3486 | 3498 | |
| 3487 | 3499 | template <typename Alloc, typename Derived> |
| 3488 | StringView AbstractManglingParser<Alloc, Derived>::parseBareSourceName() { | |
| 3500 | std::string_view AbstractManglingParser<Alloc, Derived>::parseBareSourceName() { | |
| 3489 | 3501 | size_t Int = 0; |
| 3490 | 3502 | if (parsePositiveInteger(&Int) || numLeft() < Int) |
| 3491 | return StringView(); | |
| 3492 | StringView R(First, First + Int); | |
| 3503 | return {}; | |
| 3504 | std::string_view R(First, Int); | |
| 3493 | 3505 | First += Int; |
| 3494 | 3506 | return R; |
| 3495 | 3507 | } |
| ... | ... | @@ -3673,7 +3685,7 @@ Node *AbstractManglingParser<Derived, Alloc>::parsePointerToMemberType() { |
| 3673 | 3685 | // ::= Te <name> # dependent elaborated type specifier using 'enum' |
| 3674 | 3686 | template <typename Derived, typename Alloc> |
| 3675 | 3687 | Node *AbstractManglingParser<Derived, Alloc>::parseClassEnumType() { |
| 3676 | StringView ElabSpef; | |
| 3688 | std::string_view ElabSpef; | |
| 3677 | 3689 | if (consumeIf("Ts")) |
| 3678 | 3690 | ElabSpef = "struct"; |
| 3679 | 3691 | else if (consumeIf("Tu")) |
| ... | ... | @@ -3697,17 +3709,18 @@ Node *AbstractManglingParser<Derived, Alloc>::parseClassEnumType() { |
| 3697 | 3709 | template <typename Derived, typename Alloc> |
| 3698 | 3710 | Node *AbstractManglingParser<Derived, Alloc>::parseQualifiedType() { |
| 3699 | 3711 | if (consumeIf('U')) { |
| 3700 | StringView Qual = parseBareSourceName(); | |
| 3712 | std::string_view Qual = parseBareSourceName(); | |
| 3701 | 3713 | if (Qual.empty()) |
| 3702 | 3714 | return nullptr; |
| 3703 | 3715 | |
| 3704 | 3716 | // extension ::= U <objc-name> <objc-type> # objc-type<identifier> |
| 3705 | if (Qual.startsWith("objcproto")) { | |
| 3706 | StringView ProtoSourceName = Qual.dropFront(std::strlen("objcproto")); | |
| 3707 | StringView Proto; | |
| 3717 | if (starts_with(Qual, "objcproto")) { | |
| 3718 | constexpr size_t Len = sizeof("objcproto") - 1; | |
| 3719 | std::string_view ProtoSourceName(Qual.data() + Len, Qual.size() - Len); | |
| 3720 | std::string_view Proto; | |
| 3708 | 3721 | { |
| 3709 | ScopedOverride<const char *> SaveFirst(First, ProtoSourceName.begin()), | |
| 3710 | SaveLast(Last, ProtoSourceName.end()); | |
| 3722 | ScopedOverride<const char *> SaveFirst(First, ProtoSourceName.data()), | |
| 3723 | SaveLast(Last, &*ProtoSourceName.rbegin() + 1); | |
| 3711 | 3724 | Proto = parseBareSourceName(); |
| 3712 | 3725 | } |
| 3713 | 3726 | if (Proto.empty()) |
| ... | ... | @@ -3875,7 +3888,7 @@ Node *AbstractManglingParser<Derived, Alloc>::parseType() { |
| 3875 | 3888 | // <builtin-type> ::= u <source-name> # vendor extended type |
| 3876 | 3889 | case 'u': { |
| 3877 | 3890 | ++First; |
| 3878 | StringView Res = parseBareSourceName(); | |
| 3891 | std::string_view Res = parseBareSourceName(); | |
| 3879 | 3892 | if (Res.empty()) |
| 3880 | 3893 | return nullptr; |
| 3881 | 3894 | // Typically, <builtin-type>s are not considered substitution candidates, |
| ... | ... | @@ -4123,8 +4136,9 @@ Node *AbstractManglingParser<Derived, Alloc>::parseType() { |
| 4123 | 4136 | } |
| 4124 | 4137 | |
| 4125 | 4138 | template <typename Derived, typename Alloc> |
| 4126 | Node *AbstractManglingParser<Derived, Alloc>::parsePrefixExpr(StringView Kind, | |
| 4127 | Node::Prec Prec) { | |
| 4139 | Node * | |
| 4140 | AbstractManglingParser<Derived, Alloc>::parsePrefixExpr(std::string_view Kind, | |
| 4141 | Node::Prec Prec) { | |
| 4128 | 4142 | Node *E = getDerived().parseExpr(); |
| 4129 | 4143 | if (E == nullptr) |
| 4130 | 4144 | return nullptr; |
| ... | ... | @@ -4132,8 +4146,9 @@ Node *AbstractManglingParser<Derived, Alloc>::parsePrefixExpr(StringView Kind, |
| 4132 | 4146 | } |
| 4133 | 4147 | |
| 4134 | 4148 | template <typename Derived, typename Alloc> |
| 4135 | Node *AbstractManglingParser<Derived, Alloc>::parseBinaryExpr(StringView Kind, | |
| 4136 | Node::Prec Prec) { | |
| 4149 | Node * | |
| 4150 | AbstractManglingParser<Derived, Alloc>::parseBinaryExpr(std::string_view Kind, | |
| 4151 | Node::Prec Prec) { | |
| 4137 | 4152 | Node *LHS = getDerived().parseExpr(); |
| 4138 | 4153 | if (LHS == nullptr) |
| 4139 | 4154 | return nullptr; |
| ... | ... | @@ -4144,9 +4159,9 @@ Node *AbstractManglingParser<Derived, Alloc>::parseBinaryExpr(StringView Kind, |
| 4144 | 4159 | } |
| 4145 | 4160 | |
| 4146 | 4161 | template <typename Derived, typename Alloc> |
| 4147 | Node * | |
| 4148 | AbstractManglingParser<Derived, Alloc>::parseIntegerLiteral(StringView Lit) { | |
| 4149 | StringView Tmp = parseNumber(true); | |
| 4162 | Node *AbstractManglingParser<Derived, Alloc>::parseIntegerLiteral( | |
| 4163 | std::string_view Lit) { | |
| 4164 | std::string_view Tmp = parseNumber(true); | |
| 4150 | 4165 | if (!Tmp.empty() && consumeIf('E')) |
| 4151 | 4166 | return make<IntegerLiteral>(Lit, Tmp); |
| 4152 | 4167 | return nullptr; |
| ... | ... | @@ -4176,7 +4191,7 @@ Node *AbstractManglingParser<Derived, Alloc>::parseFunctionParam() { |
| 4176 | 4191 | return make<NameType>("this"); |
| 4177 | 4192 | if (consumeIf("fp")) { |
| 4178 | 4193 | parseCVQualifiers(); |
| 4179 | StringView Num = parseNumber(); | |
| 4194 | std::string_view Num = parseNumber(); | |
| 4180 | 4195 | if (!consumeIf('_')) |
| 4181 | 4196 | return nullptr; |
| 4182 | 4197 | return make<FunctionParam>(Num); |
| ... | ... | @@ -4187,7 +4202,7 @@ Node *AbstractManglingParser<Derived, Alloc>::parseFunctionParam() { |
| 4187 | 4202 | if (!consumeIf('p')) |
| 4188 | 4203 | return nullptr; |
| 4189 | 4204 | parseCVQualifiers(); |
| 4190 | StringView Num = parseNumber(); | |
| 4205 | std::string_view Num = parseNumber(); | |
| 4191 | 4206 | if (!consumeIf('_')) |
| 4192 | 4207 | return nullptr; |
| 4193 | 4208 | return make<FunctionParam>(Num); |
| ... | ... | @@ -4341,7 +4356,7 @@ Node *AbstractManglingParser<Derived, Alloc>::parseExprPrimary() { |
| 4341 | 4356 | Node *T = getDerived().parseType(); |
| 4342 | 4357 | if (T == nullptr) |
| 4343 | 4358 | return nullptr; |
| 4344 | StringView N = parseNumber(/*AllowNegative=*/true); | |
| 4359 | std::string_view N = parseNumber(/*AllowNegative=*/true); | |
| 4345 | 4360 | if (N.empty()) |
| 4346 | 4361 | return nullptr; |
| 4347 | 4362 | if (!consumeIf('E')) |
| ... | ... | @@ -4464,7 +4479,7 @@ AbstractManglingParser<Derived, Alloc>::parsePointerToMemberConversionExpr( |
| 4464 | 4479 | Node *Expr = getDerived().parseExpr(); |
| 4465 | 4480 | if (!Expr) |
| 4466 | 4481 | return nullptr; |
| 4467 | StringView Offset = getDerived().parseNumber(true); | |
| 4482 | std::string_view Offset = getDerived().parseNumber(true); | |
| 4468 | 4483 | if (!consumeIf('E')) |
| 4469 | 4484 | return nullptr; |
| 4470 | 4485 | return make<PointerToMemberConversionExpr>(Ty, Expr, Offset, Prec); |
| ... | ... | @@ -4482,7 +4497,7 @@ Node *AbstractManglingParser<Derived, Alloc>::parseSubobjectExpr() { |
| 4482 | 4497 | Node *Expr = getDerived().parseExpr(); |
| 4483 | 4498 | if (!Expr) |
| 4484 | 4499 | return nullptr; |
| 4485 | StringView Offset = getDerived().parseNumber(true); | |
| 4500 | std::string_view Offset = getDerived().parseNumber(true); | |
| 4486 | 4501 | size_t SelectorsBegin = Names.size(); |
| 4487 | 4502 | while (consumeIf('_')) { |
| 4488 | 4503 | Node *Selector = make<NameType>(parseNumber()); |
| ... | ... | @@ -5141,7 +5156,7 @@ Node *AbstractManglingParser<Alloc, Derived>::parseFloatingLiteral() { |
| 5141 | 5156 | const size_t N = FloatData<Float>::mangled_size; |
| 5142 | 5157 | if (numLeft() <= N) |
| 5143 | 5158 | return nullptr; |
| 5144 | StringView Data(First, First + N); | |
| 5159 | std::string_view Data(First, N); | |
| 5145 | 5160 | for (char C : Data) |
| 5146 | 5161 | if (!std::isxdigit(C)) |
| 5147 | 5162 | return nullptr; |
| ... | ... | @@ -5461,7 +5476,8 @@ Node *AbstractManglingParser<Derived, Alloc>::parse() { |
| 5461 | 5476 | if (Encoding == nullptr) |
| 5462 | 5477 | return nullptr; |
| 5463 | 5478 | if (look() == '.') { |
| 5464 | Encoding = make<DotSuffix>(Encoding, StringView(First, Last)); | |
| 5479 | Encoding = | |
| 5480 | make<DotSuffix>(Encoding, std::string_view(First, Last - First)); | |
| 5465 | 5481 | First = Last; |
| 5466 | 5482 | } |
| 5467 | 5483 | if (numLeft() != 0) |
| ... | ... | @@ -5497,4 +5513,8 @@ struct ManglingParser : AbstractManglingParser<ManglingParser<Alloc>, Alloc> { |
| 5497 | 5513 | |
| 5498 | 5514 | DEMANGLE_NAMESPACE_END |
| 5499 | 5515 | |
| 5516 | #ifdef _LIBCXXABI_COMPILER_CLANG | |
| 5517 | #pragma clang diagnostic pop | |
| 5518 | #endif | |
| 5519 | ||
| 5500 | 5520 | #endif // DEMANGLE_ITANIUMDEMANGLE_H |
lib/libcxxabi/src/demangle/StringView.h deleted-122| ... | ... | @@ -1,122 +0,0 @@ |
| 1 | //===--- StringView.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 | // FIXME: Use std::string_view instead when we support C++17. | |
| 10 | // There are two copies of this file in the source tree. The one under | |
| 11 | // libcxxabi is the original and the one under llvm is the copy. Use | |
| 12 | // cp-to-llvm.sh to update the copy. See README.txt for more details. | |
| 13 | // | |
| 14 | //===----------------------------------------------------------------------===// | |
| 15 | ||
| 16 | #ifndef DEMANGLE_STRINGVIEW_H | |
| 17 | #define DEMANGLE_STRINGVIEW_H | |
| 18 | ||
| 19 | #include "DemangleConfig.h" | |
| 20 | #include <cassert> | |
| 21 | #include <cstring> | |
| 22 | ||
| 23 | DEMANGLE_NAMESPACE_BEGIN | |
| 24 | ||
| 25 | class StringView { | |
| 26 | const char *First; | |
| 27 | const char *Last; | |
| 28 | ||
| 29 | public: | |
| 30 | static const size_t npos = ~size_t(0); | |
| 31 | ||
| 32 | template <size_t N> | |
| 33 | StringView(const char (&Str)[N]) : First(Str), Last(Str + N - 1) {} | |
| 34 | StringView(const char *First_, const char *Last_) | |
| 35 | : First(First_), Last(Last_) {} | |
| 36 | StringView(const char *First_, size_t Len) | |
| 37 | : First(First_), Last(First_ + Len) {} | |
| 38 | StringView(const char *Str) : First(Str), Last(Str + std::strlen(Str)) {} | |
| 39 | StringView() : First(nullptr), Last(nullptr) {} | |
| 40 | ||
| 41 | StringView substr(size_t Pos, size_t Len = npos) const { | |
| 42 | assert(Pos <= size()); | |
| 43 | if (Len > size() - Pos) | |
| 44 | Len = size() - Pos; | |
| 45 | return StringView(begin() + Pos, Len); | |
| 46 | } | |
| 47 | ||
| 48 | size_t find(char C, size_t From = 0) const { | |
| 49 | // Avoid calling memchr with nullptr. | |
| 50 | if (From < size()) { | |
| 51 | // Just forward to memchr, which is faster than a hand-rolled loop. | |
| 52 | if (const void *P = ::memchr(First + From, C, size() - From)) | |
| 53 | return size_t(static_cast<const char *>(P) - First); | |
| 54 | } | |
| 55 | return npos; | |
| 56 | } | |
| 57 | ||
| 58 | StringView dropFront(size_t N = 1) const { | |
| 59 | if (N >= size()) | |
| 60 | N = size(); | |
| 61 | return StringView(First + N, Last); | |
| 62 | } | |
| 63 | ||
| 64 | StringView dropBack(size_t N = 1) const { | |
| 65 | if (N >= size()) | |
| 66 | N = size(); | |
| 67 | return StringView(First, Last - N); | |
| 68 | } | |
| 69 | ||
| 70 | char front() const { | |
| 71 | assert(!empty()); | |
| 72 | return *begin(); | |
| 73 | } | |
| 74 | ||
| 75 | char back() const { | |
| 76 | assert(!empty()); | |
| 77 | return *(end() - 1); | |
| 78 | } | |
| 79 | ||
| 80 | char popFront() { | |
| 81 | assert(!empty()); | |
| 82 | return *First++; | |
| 83 | } | |
| 84 | ||
| 85 | bool consumeFront(char C) { | |
| 86 | if (!startsWith(C)) | |
| 87 | return false; | |
| 88 | *this = dropFront(1); | |
| 89 | return true; | |
| 90 | } | |
| 91 | ||
| 92 | bool consumeFront(StringView S) { | |
| 93 | if (!startsWith(S)) | |
| 94 | return false; | |
| 95 | *this = dropFront(S.size()); | |
| 96 | return true; | |
| 97 | } | |
| 98 | ||
| 99 | bool startsWith(char C) const { return !empty() && *begin() == C; } | |
| 100 | ||
| 101 | bool startsWith(StringView Str) const { | |
| 102 | if (Str.size() > size()) | |
| 103 | return false; | |
| 104 | return std::strncmp(Str.begin(), begin(), Str.size()) == 0; | |
| 105 | } | |
| 106 | ||
| 107 | const char &operator[](size_t Idx) const { return *(begin() + Idx); } | |
| 108 | ||
| 109 | const char *begin() const { return First; } | |
| 110 | const char *end() const { return Last; } | |
| 111 | size_t size() const { return static_cast<size_t>(Last - First); } | |
| 112 | bool empty() const { return First == Last; } | |
| 113 | }; | |
| 114 | ||
| 115 | inline bool operator==(const StringView &LHS, const StringView &RHS) { | |
| 116 | return LHS.size() == RHS.size() && | |
| 117 | std::strncmp(LHS.begin(), RHS.begin(), LHS.size()) == 0; | |
| 118 | } | |
| 119 | ||
| 120 | DEMANGLE_NAMESPACE_END | |
| 121 | ||
| 122 | #endif |
lib/libcxxabi/src/demangle/StringViewExtras.h created+38| ... | ... | @@ -0,0 +1,38 @@ |
| 1 | //===--- StringViewExtras.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 | // There are two copies of this file in the source tree. The one under | |
| 10 | // libcxxabi is the original and the one under llvm is the copy. Use | |
| 11 | // cp-to-llvm.sh to update the copy. See README.txt for more details. | |
| 12 | // | |
| 13 | //===----------------------------------------------------------------------===// | |
| 14 | ||
| 15 | #ifndef DEMANGLE_STRINGVIEW_H | |
| 16 | #define DEMANGLE_STRINGVIEW_H | |
| 17 | ||
| 18 | #include "DemangleConfig.h" | |
| 19 | ||
| 20 | #include <string_view> | |
| 21 | ||
| 22 | DEMANGLE_NAMESPACE_BEGIN | |
| 23 | ||
| 24 | inline bool starts_with(std::string_view self, char C) noexcept { | |
| 25 | return !self.empty() && *self.begin() == C; | |
| 26 | } | |
| 27 | ||
| 28 | inline bool starts_with(std::string_view haystack, | |
| 29 | std::string_view needle) noexcept { | |
| 30 | if (needle.size() > haystack.size()) | |
| 31 | return false; | |
| 32 | haystack.remove_suffix(haystack.size() - needle.size()); | |
| 33 | return haystack == needle; | |
| 34 | } | |
| 35 | ||
| 36 | DEMANGLE_NAMESPACE_END | |
| 37 | ||
| 38 | #endif |
lib/libcxxabi/src/demangle/Utility.h+14-8| ... | ... | @@ -16,13 +16,16 @@ |
| 16 | 16 | #ifndef DEMANGLE_UTILITY_H |
| 17 | 17 | #define DEMANGLE_UTILITY_H |
| 18 | 18 | |
| 19 | #include "StringView.h" | |
| 19 | #include "DemangleConfig.h" | |
| 20 | ||
| 20 | 21 | #include <array> |
| 22 | #include <cassert> | |
| 21 | 23 | #include <cstdint> |
| 22 | 24 | #include <cstdlib> |
| 23 | 25 | #include <cstring> |
| 24 | 26 | #include <exception> |
| 25 | 27 | #include <limits> |
| 28 | #include <string_view> | |
| 26 | 29 | |
| 27 | 30 | DEMANGLE_NAMESPACE_BEGIN |
| 28 | 31 | |
| ... | ... | @@ -64,7 +67,8 @@ class OutputBuffer { |
| 64 | 67 | if (isNeg) |
| 65 | 68 | *--TempPtr = '-'; |
| 66 | 69 | |
| 67 | return operator+=(StringView(TempPtr, Temp.data() + Temp.size())); | |
| 70 | return operator+=( | |
| 71 | std::string_view(TempPtr, Temp.data() + Temp.size() - TempPtr)); | |
| 68 | 72 | } |
| 69 | 73 | |
| 70 | 74 | public: |
| ... | ... | @@ -77,7 +81,9 @@ public: |
| 77 | 81 | OutputBuffer(const OutputBuffer &) = delete; |
| 78 | 82 | OutputBuffer &operator=(const OutputBuffer &) = delete; |
| 79 | 83 | |
| 80 | operator StringView() const { return StringView(Buffer, CurrentPosition); } | |
| 84 | operator std::string_view() const { | |
| 85 | return std::string_view(Buffer, CurrentPosition); | |
| 86 | } | |
| 81 | 87 | |
| 82 | 88 | /// If a ParameterPackExpansion (or similar type) is encountered, the offset |
| 83 | 89 | /// into the pack that we're currently printing. |
| ... | ... | @@ -99,10 +105,10 @@ public: |
| 99 | 105 | *this += Close; |
| 100 | 106 | } |
| 101 | 107 | |
| 102 | OutputBuffer &operator+=(StringView R) { | |
| 108 | OutputBuffer &operator+=(std::string_view R) { | |
| 103 | 109 | if (size_t Size = R.size()) { |
| 104 | 110 | grow(Size); |
| 105 | std::memcpy(Buffer + CurrentPosition, R.begin(), Size); | |
| 111 | std::memcpy(Buffer + CurrentPosition, &*R.begin(), Size); | |
| 106 | 112 | CurrentPosition += Size; |
| 107 | 113 | } |
| 108 | 114 | return *this; |
| ... | ... | @@ -114,18 +120,18 @@ public: |
| 114 | 120 | return *this; |
| 115 | 121 | } |
| 116 | 122 | |
| 117 | OutputBuffer &prepend(StringView R) { | |
| 123 | OutputBuffer &prepend(std::string_view R) { | |
| 118 | 124 | size_t Size = R.size(); |
| 119 | 125 | |
| 120 | 126 | grow(Size); |
| 121 | 127 | std::memmove(Buffer + Size, Buffer, CurrentPosition); |
| 122 | std::memcpy(Buffer, R.begin(), Size); | |
| 128 | std::memcpy(Buffer, &*R.begin(), Size); | |
| 123 | 129 | CurrentPosition += Size; |
| 124 | 130 | |
| 125 | 131 | return *this; |
| 126 | 132 | } |
| 127 | 133 | |
| 128 | OutputBuffer &operator<<(StringView R) { return (*this += R); } | |
| 134 | OutputBuffer &operator<<(std::string_view R) { return (*this += R); } | |
| 129 | 135 | |
| 130 | 136 | OutputBuffer &operator<<(char C) { return (*this += C); } |
| 131 | 137 |
lib/libcxxabi/src/fallback_malloc.cpp+1-1| ... | ... | @@ -15,10 +15,10 @@ |
| 15 | 15 | #endif |
| 16 | 16 | #endif |
| 17 | 17 | |
| 18 | #include <__memory/aligned_alloc.h> | |
| 18 | 19 | #include <assert.h> |
| 19 | 20 | #include <stdlib.h> // for malloc, calloc, free |
| 20 | 21 | #include <string.h> // for memset |
| 21 | #include <new> // for std::__libcpp_aligned_{alloc,free} | |
| 22 | 22 | |
| 23 | 23 | // A small, simple heap manager based (loosely) on |
| 24 | 24 | // the startup heap manager from FreeBSD, optimized for space. |
lib/libcxxabi/src/private_typeinfo.cpp+124-62| ... | ... | @@ -41,6 +41,7 @@ |
| 41 | 41 | // Defining _LIBCXXABI_FORGIVING_DYNAMIC_CAST does not help since can_catch() calls |
| 42 | 42 | // is_equal() with use_strcmp=false so the string names are not compared. |
| 43 | 43 | |
| 44 | #include <cstdint> | |
| 44 | 45 | #include <string.h> |
| 45 | 46 | |
| 46 | 47 | #ifdef _LIBCXXABI_FORGIVING_DYNAMIC_CAST |
| ... | ... | @@ -656,77 +657,138 @@ __dynamic_cast(const void *static_ptr, const __class_type_info *static_type, |
| 656 | 657 | // Find out if we can use a giant short cut in the search |
| 657 | 658 | if (is_equal(dynamic_type, dst_type, false)) |
| 658 | 659 | { |
| 659 | // Using giant short cut. Add that information to info. | |
| 660 | info.number_of_dst_type = 1; | |
| 661 | // Do the search | |
| 662 | dynamic_type->search_above_dst(&info, dynamic_ptr, dynamic_ptr, public_path, false); | |
| 663 | #ifdef _LIBCXXABI_FORGIVING_DYNAMIC_CAST | |
| 664 | // The following if should always be false because we should definitely | |
| 665 | // find (static_ptr, static_type), either on a public or private path | |
| 666 | if (info.path_dst_ptr_to_static_ptr == unknown) | |
| 660 | // We're downcasting from src_type to the complete object's dynamic | |
| 661 | // type. This is a really hot path that can be further optimized | |
| 662 | // with the `src2dst_offset` hint. | |
| 663 | // In such a case, dynamic_ptr already gives the casting result if the | |
| 664 | // casting ever succeeds. All we have to do now is to check | |
| 665 | // static_ptr points to a public base sub-object of dynamic_ptr. | |
| 666 | ||
| 667 | if (src2dst_offset >= 0) | |
| 667 | 668 | { |
| 668 | // We get here only if there is some kind of visibility problem | |
| 669 | // in client code. | |
| 670 | static_assert(std::atomic<size_t>::is_always_lock_free, ""); | |
| 671 | static std::atomic<size_t> error_count(0); | |
| 672 | size_t error_count_snapshot = error_count.fetch_add(1, std::memory_order_relaxed); | |
| 673 | if ((error_count_snapshot & (error_count_snapshot-1)) == 0) | |
| 674 | syslog(LOG_ERR, "dynamic_cast error 1: Both of the following type_info's " | |
| 675 | "should have public visibility. At least one of them is hidden. %s" | |
| 676 | ", %s.\n", static_type->name(), dynamic_type->name()); | |
| 677 | // Redo the search comparing type_info's using strcmp | |
| 678 | info = {dst_type, static_ptr, static_type, src2dst_offset, 0}; | |
| 679 | info.number_of_dst_type = 1; | |
| 680 | dynamic_type->search_above_dst(&info, dynamic_ptr, dynamic_ptr, public_path, true); | |
| 669 | // The static type is a unique public non-virtual base type of | |
| 670 | // dst_type at offset `src2dst_offset` from the origin of dst. | |
| 671 | // Note that there might be other non-public static_type bases. The | |
| 672 | // hint only guarantees that the public base is non-virtual and | |
| 673 | // unique. So we have to check whether static_ptr points to that | |
| 674 | // unique public base sub-object. | |
| 675 | if (offset_to_derived == -src2dst_offset) | |
| 676 | dst_ptr = dynamic_ptr; | |
| 677 | } | |
| 678 | else if (src2dst_offset == -2) | |
| 679 | { | |
| 680 | // static_type is not a public base of dst_type. | |
| 681 | dst_ptr = nullptr; | |
| 681 | 682 | } |
| 683 | else | |
| 684 | { | |
| 685 | // If src2dst_offset == -3, then: | |
| 686 | // src_type is a multiple public base type but never a virtual | |
| 687 | // base type. We can't conclude that static_ptr points to those | |
| 688 | // public base sub-objects because there might be other non- | |
| 689 | // public static_type bases. The search is inevitable. | |
| 690 | ||
| 691 | // Fallback to the slow path to check that static_type is a public | |
| 692 | // base type of dynamic_type. | |
| 693 | // Using giant short cut. Add that information to info. | |
| 694 | info.number_of_dst_type = 1; | |
| 695 | // Do the search | |
| 696 | dynamic_type->search_above_dst(&info, dynamic_ptr, dynamic_ptr, public_path, false); | |
| 697 | #ifdef _LIBCXXABI_FORGIVING_DYNAMIC_CAST | |
| 698 | // The following if should always be false because we should | |
| 699 | // definitely find (static_ptr, static_type), either on a public | |
| 700 | // or private path | |
| 701 | if (info.path_dst_ptr_to_static_ptr == unknown) | |
| 702 | { | |
| 703 | // We get here only if there is some kind of visibility problem | |
| 704 | // in client code. | |
| 705 | static_assert(std::atomic<size_t>::is_always_lock_free, ""); | |
| 706 | static std::atomic<size_t> error_count(0); | |
| 707 | size_t error_count_snapshot = error_count.fetch_add(1, std::memory_order_relaxed); | |
| 708 | if ((error_count_snapshot & (error_count_snapshot-1)) == 0) | |
| 709 | syslog(LOG_ERR, "dynamic_cast error 1: Both of the following type_info's " | |
| 710 | "should have public visibility. At least one of them is hidden. %s" | |
| 711 | ", %s.\n", static_type->name(), dynamic_type->name()); | |
| 712 | // Redo the search comparing type_info's using strcmp | |
| 713 | info = {dst_type, static_ptr, static_type, src2dst_offset, 0}; | |
| 714 | info.number_of_dst_type = 1; | |
| 715 | dynamic_type->search_above_dst(&info, dynamic_ptr, dynamic_ptr, public_path, true); | |
| 716 | } | |
| 682 | 717 | #endif // _LIBCXXABI_FORGIVING_DYNAMIC_CAST |
| 683 | // Query the search. | |
| 684 | if (info.path_dst_ptr_to_static_ptr == public_path) | |
| 685 | dst_ptr = dynamic_ptr; | |
| 718 | // Query the search. | |
| 719 | if (info.path_dst_ptr_to_static_ptr == public_path) | |
| 720 | dst_ptr = dynamic_ptr; | |
| 721 | } | |
| 686 | 722 | } |
| 687 | 723 | else |
| 688 | 724 | { |
| 689 | // Not using giant short cut. Do the search | |
| 690 | dynamic_type->search_below_dst(&info, dynamic_ptr, public_path, false); | |
| 691 | #ifdef _LIBCXXABI_FORGIVING_DYNAMIC_CAST | |
| 692 | // The following if should always be false because we should definitely | |
| 693 | // find (static_ptr, static_type), either on a public or private path | |
| 694 | if (info.path_dst_ptr_to_static_ptr == unknown && | |
| 695 | info.path_dynamic_ptr_to_static_ptr == unknown) | |
| 725 | if (src2dst_offset >= 0) | |
| 696 | 726 | { |
| 697 | static_assert(std::atomic<size_t>::is_always_lock_free, ""); | |
| 698 | static std::atomic<size_t> error_count(0); | |
| 699 | size_t error_count_snapshot = error_count.fetch_add(1, std::memory_order_relaxed); | |
| 700 | if ((error_count_snapshot & (error_count_snapshot-1)) == 0) | |
| 701 | syslog(LOG_ERR, "dynamic_cast error 2: One or more of the following type_info's " | |
| 702 | "has hidden visibility or is defined in more than one translation " | |
| 703 | "unit. They should all have public visibility. " | |
| 704 | "%s, %s, %s.\n", static_type->name(), dynamic_type->name(), | |
| 705 | dst_type->name()); | |
| 706 | // Redo the search comparing type_info's using strcmp | |
| 707 | info = {dst_type, static_ptr, static_type, src2dst_offset, 0}; | |
| 708 | dynamic_type->search_below_dst(&info, dynamic_ptr, public_path, true); | |
| 727 | // Optimize toward downcasting: dst_type has one unique public | |
| 728 | // static_type bases. Let's first try to do a downcast before | |
| 729 | // falling back to the slow path. The downcast succeeds if there | |
| 730 | // is at least one path regardless of visibility from | |
| 731 | // dynamic_type to dst_type. | |
| 732 | const void* dst_ptr_to_static = reinterpret_cast<const char*>(static_ptr) - src2dst_offset; | |
| 733 | if (reinterpret_cast<std::intptr_t>(dst_ptr_to_static) >= reinterpret_cast<std::intptr_t>(dynamic_ptr)) | |
| 734 | { | |
| 735 | // Try to search a path from dynamic_type to dst_type. | |
| 736 | __dynamic_cast_info dynamic_to_dst_info = {dynamic_type, dst_ptr_to_static, dst_type, src2dst_offset}; | |
| 737 | dynamic_to_dst_info.number_of_dst_type = 1; | |
| 738 | dynamic_type->search_above_dst(&dynamic_to_dst_info, dynamic_ptr, dynamic_ptr, public_path, false); | |
| 739 | if (dynamic_to_dst_info.path_dst_ptr_to_static_ptr != unknown) { | |
| 740 | // We have found at least one path from dynamic_ptr to | |
| 741 | // dst_ptr. The downcast can succeed. | |
| 742 | dst_ptr = dst_ptr_to_static; | |
| 743 | } | |
| 744 | } | |
| 709 | 745 | } |
| 710 | #endif // _LIBCXXABI_FORGIVING_DYNAMIC_CAST | |
| 711 | // Query the search. | |
| 712 | switch (info.number_to_static_ptr) | |
| 746 | ||
| 747 | if (!dst_ptr) | |
| 713 | 748 | { |
| 714 | case 0: | |
| 715 | if (info.number_to_dst_ptr == 1 && | |
| 716 | info.path_dynamic_ptr_to_static_ptr == public_path && | |
| 717 | info.path_dynamic_ptr_to_dst_ptr == public_path) | |
| 718 | dst_ptr = info.dst_ptr_not_leading_to_static_ptr; | |
| 719 | break; | |
| 720 | case 1: | |
| 721 | if (info.path_dst_ptr_to_static_ptr == public_path || | |
| 722 | ( | |
| 723 | info.number_to_dst_ptr == 0 && | |
| 724 | info.path_dynamic_ptr_to_static_ptr == public_path && | |
| 725 | info.path_dynamic_ptr_to_dst_ptr == public_path | |
| 726 | ) | |
| 727 | ) | |
| 728 | dst_ptr = info.dst_ptr_leading_to_static_ptr; | |
| 729 | break; | |
| 749 | // Not using giant short cut. Do the search | |
| 750 | dynamic_type->search_below_dst(&info, dynamic_ptr, public_path, false); | |
| 751 | #ifdef _LIBCXXABI_FORGIVING_DYNAMIC_CAST | |
| 752 | // The following if should always be false because we should | |
| 753 | // definitely find (static_ptr, static_type), either on a public | |
| 754 | // or private path | |
| 755 | if (info.path_dst_ptr_to_static_ptr == unknown && | |
| 756 | info.path_dynamic_ptr_to_static_ptr == unknown) | |
| 757 | { | |
| 758 | static_assert(std::atomic<size_t>::is_always_lock_free, ""); | |
| 759 | static std::atomic<size_t> error_count(0); | |
| 760 | size_t error_count_snapshot = error_count.fetch_add(1, std::memory_order_relaxed); | |
| 761 | if ((error_count_snapshot & (error_count_snapshot-1)) == 0) | |
| 762 | syslog(LOG_ERR, "dynamic_cast error 2: One or more of the following type_info's " | |
| 763 | "has hidden visibility or is defined in more than one translation " | |
| 764 | "unit. They should all have public visibility. " | |
| 765 | "%s, %s, %s.\n", static_type->name(), dynamic_type->name(), | |
| 766 | dst_type->name()); | |
| 767 | // Redo the search comparing type_info's using strcmp | |
| 768 | info = {dst_type, static_ptr, static_type, src2dst_offset, 0}; | |
| 769 | dynamic_type->search_below_dst(&info, dynamic_ptr, public_path, true); | |
| 770 | } | |
| 771 | #endif // _LIBCXXABI_FORGIVING_DYNAMIC_CAST | |
| 772 | // Query the search. | |
| 773 | switch (info.number_to_static_ptr) | |
| 774 | { | |
| 775 | case 0: | |
| 776 | if (info.number_to_dst_ptr == 1 && | |
| 777 | info.path_dynamic_ptr_to_static_ptr == public_path && | |
| 778 | info.path_dynamic_ptr_to_dst_ptr == public_path) | |
| 779 | dst_ptr = info.dst_ptr_not_leading_to_static_ptr; | |
| 780 | break; | |
| 781 | case 1: | |
| 782 | if (info.path_dst_ptr_to_static_ptr == public_path || | |
| 783 | ( | |
| 784 | info.number_to_dst_ptr == 0 && | |
| 785 | info.path_dynamic_ptr_to_static_ptr == public_path && | |
| 786 | info.path_dynamic_ptr_to_dst_ptr == public_path | |
| 787 | ) | |
| 788 | ) | |
| 789 | dst_ptr = info.dst_ptr_leading_to_static_ptr; | |
| 790 | break; | |
| 791 | } | |
| 730 | 792 | } |
| 731 | 793 | } |
| 732 | 794 | return const_cast<void*>(dst_ptr); |
lib/libcxxabi/src/stdlib_new_delete.cpp+57-46| ... | ... | @@ -4,30 +4,40 @@ |
| 4 | 4 | // See https://llvm.org/LICENSE.txt for license information. |
| 5 | 5 | // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception |
| 6 | 6 | // |
| 7 | // | |
| 8 | // This file implements the new and delete operators. | |
| 9 | 7 | //===----------------------------------------------------------------------===// |
| 10 | 8 | |
| 11 | 9 | #include "__cxxabi_config.h" |
| 12 | #include <new> | |
| 10 | #include <__memory/aligned_alloc.h> | |
| 13 | 11 | #include <cstdlib> |
| 12 | #include <new> | |
| 13 | ||
| 14 | // Perform a few sanity checks on libc++ and libc++abi macros to ensure that | |
| 15 | // the code below can be an exact copy of the code in libcxx/src/new.cpp. | |
| 16 | #if !defined(_THROW_BAD_ALLOC) | |
| 17 | # error The _THROW_BAD_ALLOC macro should be already defined by libc++ | |
| 18 | #endif | |
| 19 | ||
| 20 | #ifndef _LIBCPP_WEAK | |
| 21 | # error The _LIBCPP_WEAK macro should be already defined by libc++ | |
| 22 | #endif | |
| 14 | 23 | |
| 15 | #if !defined(_THROW_BAD_ALLOC) || !defined(_LIBCXXABI_WEAK) | |
| 16 | #error The _THROW_BAD_ALLOC and _LIBCXXABI_WEAK libc++ macros must \ | |
| 17 | already be defined by libc++. | |
| 24 | #if defined(_LIBCXXABI_NO_EXCEPTIONS) != defined(_LIBCPP_HAS_NO_EXCEPTIONS) | |
| 25 | # error libc++ and libc++abi seem to disagree on whether exceptions are enabled | |
| 18 | 26 | #endif |
| 27 | ||
| 28 | // ------------------ BEGIN COPY ------------------ | |
| 19 | 29 | // Implement all new and delete operators as weak definitions |
| 20 | 30 | // in this shared library, so that they can be overridden by programs |
| 21 | 31 | // that define non-weak copies of the functions. |
| 22 | 32 | |
| 23 | _LIBCXXABI_WEAK | |
| 33 | _LIBCPP_WEAK | |
| 24 | 34 | void * |
| 25 | 35 | operator new(std::size_t size) _THROW_BAD_ALLOC |
| 26 | 36 | { |
| 27 | 37 | if (size == 0) |
| 28 | 38 | size = 1; |
| 29 | 39 | void* p; |
| 30 | while ((p = ::malloc(size)) == nullptr) | |
| 40 | while ((p = std::malloc(size)) == nullptr) | |
| 31 | 41 | { |
| 32 | 42 | // If malloc fails and there is a new_handler, |
| 33 | 43 | // call it to try free up memory. |
| ... | ... | @@ -35,7 +45,7 @@ operator new(std::size_t size) _THROW_BAD_ALLOC |
| 35 | 45 | if (nh) |
| 36 | 46 | nh(); |
| 37 | 47 | else |
| 38 | #ifndef _LIBCXXABI_NO_EXCEPTIONS | |
| 48 | #ifndef _LIBCPP_HAS_NO_EXCEPTIONS | |
| 39 | 49 | throw std::bad_alloc(); |
| 40 | 50 | #else |
| 41 | 51 | break; |
| ... | ... | @@ -44,87 +54,87 @@ operator new(std::size_t size) _THROW_BAD_ALLOC |
| 44 | 54 | return p; |
| 45 | 55 | } |
| 46 | 56 | |
| 47 | _LIBCXXABI_WEAK | |
| 57 | _LIBCPP_WEAK | |
| 48 | 58 | void* |
| 49 | 59 | operator new(size_t size, const std::nothrow_t&) noexcept |
| 50 | 60 | { |
| 51 | 61 | void* p = nullptr; |
| 52 | #ifndef _LIBCXXABI_NO_EXCEPTIONS | |
| 62 | #ifndef _LIBCPP_HAS_NO_EXCEPTIONS | |
| 53 | 63 | try |
| 54 | 64 | { |
| 55 | #endif // _LIBCXXABI_NO_EXCEPTIONS | |
| 65 | #endif // _LIBCPP_HAS_NO_EXCEPTIONS | |
| 56 | 66 | p = ::operator new(size); |
| 57 | #ifndef _LIBCXXABI_NO_EXCEPTIONS | |
| 67 | #ifndef _LIBCPP_HAS_NO_EXCEPTIONS | |
| 58 | 68 | } |
| 59 | 69 | catch (...) |
| 60 | 70 | { |
| 61 | 71 | } |
| 62 | #endif // _LIBCXXABI_NO_EXCEPTIONS | |
| 72 | #endif // _LIBCPP_HAS_NO_EXCEPTIONS | |
| 63 | 73 | return p; |
| 64 | 74 | } |
| 65 | 75 | |
| 66 | _LIBCXXABI_WEAK | |
| 76 | _LIBCPP_WEAK | |
| 67 | 77 | void* |
| 68 | 78 | operator new[](size_t size) _THROW_BAD_ALLOC |
| 69 | 79 | { |
| 70 | 80 | return ::operator new(size); |
| 71 | 81 | } |
| 72 | 82 | |
| 73 | _LIBCXXABI_WEAK | |
| 83 | _LIBCPP_WEAK | |
| 74 | 84 | void* |
| 75 | 85 | operator new[](size_t size, const std::nothrow_t&) noexcept |
| 76 | 86 | { |
| 77 | 87 | void* p = nullptr; |
| 78 | #ifndef _LIBCXXABI_NO_EXCEPTIONS | |
| 88 | #ifndef _LIBCPP_HAS_NO_EXCEPTIONS | |
| 79 | 89 | try |
| 80 | 90 | { |
| 81 | #endif // _LIBCXXABI_NO_EXCEPTIONS | |
| 91 | #endif // _LIBCPP_HAS_NO_EXCEPTIONS | |
| 82 | 92 | p = ::operator new[](size); |
| 83 | #ifndef _LIBCXXABI_NO_EXCEPTIONS | |
| 93 | #ifndef _LIBCPP_HAS_NO_EXCEPTIONS | |
| 84 | 94 | } |
| 85 | 95 | catch (...) |
| 86 | 96 | { |
| 87 | 97 | } |
| 88 | #endif // _LIBCXXABI_NO_EXCEPTIONS | |
| 98 | #endif // _LIBCPP_HAS_NO_EXCEPTIONS | |
| 89 | 99 | return p; |
| 90 | 100 | } |
| 91 | 101 | |
| 92 | _LIBCXXABI_WEAK | |
| 102 | _LIBCPP_WEAK | |
| 93 | 103 | void |
| 94 | 104 | operator delete(void* ptr) noexcept |
| 95 | 105 | { |
| 96 | ::free(ptr); | |
| 106 | std::free(ptr); | |
| 97 | 107 | } |
| 98 | 108 | |
| 99 | _LIBCXXABI_WEAK | |
| 109 | _LIBCPP_WEAK | |
| 100 | 110 | void |
| 101 | 111 | operator delete(void* ptr, const std::nothrow_t&) noexcept |
| 102 | 112 | { |
| 103 | 113 | ::operator delete(ptr); |
| 104 | 114 | } |
| 105 | 115 | |
| 106 | _LIBCXXABI_WEAK | |
| 116 | _LIBCPP_WEAK | |
| 107 | 117 | void |
| 108 | 118 | operator delete(void* ptr, size_t) noexcept |
| 109 | 119 | { |
| 110 | 120 | ::operator delete(ptr); |
| 111 | 121 | } |
| 112 | 122 | |
| 113 | _LIBCXXABI_WEAK | |
| 123 | _LIBCPP_WEAK | |
| 114 | 124 | void |
| 115 | 125 | operator delete[] (void* ptr) noexcept |
| 116 | 126 | { |
| 117 | 127 | ::operator delete(ptr); |
| 118 | 128 | } |
| 119 | 129 | |
| 120 | _LIBCXXABI_WEAK | |
| 130 | _LIBCPP_WEAK | |
| 121 | 131 | void |
| 122 | 132 | operator delete[] (void* ptr, const std::nothrow_t&) noexcept |
| 123 | 133 | { |
| 124 | 134 | ::operator delete[](ptr); |
| 125 | 135 | } |
| 126 | 136 | |
| 127 | _LIBCXXABI_WEAK | |
| 137 | _LIBCPP_WEAK | |
| 128 | 138 | void |
| 129 | 139 | operator delete[] (void* ptr, size_t) noexcept |
| 130 | 140 | { |
| ... | ... | @@ -133,7 +143,7 @@ operator delete[] (void* ptr, size_t) noexcept |
| 133 | 143 | |
| 134 | 144 | #if !defined(_LIBCPP_HAS_NO_LIBRARY_ALIGNED_ALLOCATION) |
| 135 | 145 | |
| 136 | _LIBCXXABI_WEAK | |
| 146 | _LIBCPP_WEAK | |
| 137 | 147 | void * |
| 138 | 148 | operator new(std::size_t size, std::align_val_t alignment) _THROW_BAD_ALLOC |
| 139 | 149 | { |
| ... | ... | @@ -155,7 +165,7 @@ operator new(std::size_t size, std::align_val_t alignment) _THROW_BAD_ALLOC |
| 155 | 165 | if (nh) |
| 156 | 166 | nh(); |
| 157 | 167 | else { |
| 158 | #ifndef _LIBCXXABI_NO_EXCEPTIONS | |
| 168 | #ifndef _LIBCPP_HAS_NO_EXCEPTIONS | |
| 159 | 169 | throw std::bad_alloc(); |
| 160 | 170 | #else |
| 161 | 171 | break; |
| ... | ... | @@ -165,87 +175,87 @@ operator new(std::size_t size, std::align_val_t alignment) _THROW_BAD_ALLOC |
| 165 | 175 | return p; |
| 166 | 176 | } |
| 167 | 177 | |
| 168 | _LIBCXXABI_WEAK | |
| 178 | _LIBCPP_WEAK | |
| 169 | 179 | void* |
| 170 | 180 | operator new(size_t size, std::align_val_t alignment, const std::nothrow_t&) noexcept |
| 171 | 181 | { |
| 172 | 182 | void* p = nullptr; |
| 173 | #ifndef _LIBCXXABI_NO_EXCEPTIONS | |
| 183 | #ifndef _LIBCPP_HAS_NO_EXCEPTIONS | |
| 174 | 184 | try |
| 175 | 185 | { |
| 176 | #endif // _LIBCXXABI_NO_EXCEPTIONS | |
| 186 | #endif // _LIBCPP_HAS_NO_EXCEPTIONS | |
| 177 | 187 | p = ::operator new(size, alignment); |
| 178 | #ifndef _LIBCXXABI_NO_EXCEPTIONS | |
| 188 | #ifndef _LIBCPP_HAS_NO_EXCEPTIONS | |
| 179 | 189 | } |
| 180 | 190 | catch (...) |
| 181 | 191 | { |
| 182 | 192 | } |
| 183 | #endif // _LIBCXXABI_NO_EXCEPTIONS | |
| 193 | #endif // _LIBCPP_HAS_NO_EXCEPTIONS | |
| 184 | 194 | return p; |
| 185 | 195 | } |
| 186 | 196 | |
| 187 | _LIBCXXABI_WEAK | |
| 197 | _LIBCPP_WEAK | |
| 188 | 198 | void* |
| 189 | 199 | operator new[](size_t size, std::align_val_t alignment) _THROW_BAD_ALLOC |
| 190 | 200 | { |
| 191 | 201 | return ::operator new(size, alignment); |
| 192 | 202 | } |
| 193 | 203 | |
| 194 | _LIBCXXABI_WEAK | |
| 204 | _LIBCPP_WEAK | |
| 195 | 205 | void* |
| 196 | 206 | operator new[](size_t size, std::align_val_t alignment, const std::nothrow_t&) noexcept |
| 197 | 207 | { |
| 198 | 208 | void* p = nullptr; |
| 199 | #ifndef _LIBCXXABI_NO_EXCEPTIONS | |
| 209 | #ifndef _LIBCPP_HAS_NO_EXCEPTIONS | |
| 200 | 210 | try |
| 201 | 211 | { |
| 202 | #endif // _LIBCXXABI_NO_EXCEPTIONS | |
| 212 | #endif // _LIBCPP_HAS_NO_EXCEPTIONS | |
| 203 | 213 | p = ::operator new[](size, alignment); |
| 204 | #ifndef _LIBCXXABI_NO_EXCEPTIONS | |
| 214 | #ifndef _LIBCPP_HAS_NO_EXCEPTIONS | |
| 205 | 215 | } |
| 206 | 216 | catch (...) |
| 207 | 217 | { |
| 208 | 218 | } |
| 209 | #endif // _LIBCXXABI_NO_EXCEPTIONS | |
| 219 | #endif // _LIBCPP_HAS_NO_EXCEPTIONS | |
| 210 | 220 | return p; |
| 211 | 221 | } |
| 212 | 222 | |
| 213 | _LIBCXXABI_WEAK | |
| 223 | _LIBCPP_WEAK | |
| 214 | 224 | void |
| 215 | 225 | operator delete(void* ptr, std::align_val_t) noexcept |
| 216 | 226 | { |
| 217 | 227 | std::__libcpp_aligned_free(ptr); |
| 218 | 228 | } |
| 219 | 229 | |
| 220 | _LIBCXXABI_WEAK | |
| 230 | _LIBCPP_WEAK | |
| 221 | 231 | void |
| 222 | 232 | operator delete(void* ptr, std::align_val_t alignment, const std::nothrow_t&) noexcept |
| 223 | 233 | { |
| 224 | 234 | ::operator delete(ptr, alignment); |
| 225 | 235 | } |
| 226 | 236 | |
| 227 | _LIBCXXABI_WEAK | |
| 237 | _LIBCPP_WEAK | |
| 228 | 238 | void |
| 229 | 239 | operator delete(void* ptr, size_t, std::align_val_t alignment) noexcept |
| 230 | 240 | { |
| 231 | 241 | ::operator delete(ptr, alignment); |
| 232 | 242 | } |
| 233 | 243 | |
| 234 | _LIBCXXABI_WEAK | |
| 244 | _LIBCPP_WEAK | |
| 235 | 245 | void |
| 236 | 246 | operator delete[] (void* ptr, std::align_val_t alignment) noexcept |
| 237 | 247 | { |
| 238 | 248 | ::operator delete(ptr, alignment); |
| 239 | 249 | } |
| 240 | 250 | |
| 241 | _LIBCXXABI_WEAK | |
| 251 | _LIBCPP_WEAK | |
| 242 | 252 | void |
| 243 | 253 | operator delete[] (void* ptr, std::align_val_t alignment, const std::nothrow_t&) noexcept |
| 244 | 254 | { |
| 245 | 255 | ::operator delete[](ptr, alignment); |
| 246 | 256 | } |
| 247 | 257 | |
| 248 | _LIBCXXABI_WEAK | |
| 258 | _LIBCPP_WEAK | |
| 249 | 259 | void |
| 250 | 260 | operator delete[] (void* ptr, size_t, std::align_val_t alignment) noexcept |
| 251 | 261 | { |
| ... | ... | @@ -253,3 +263,4 @@ operator delete[] (void* ptr, size_t, std::align_val_t alignment) noexcept |
| 253 | 263 | } |
| 254 | 264 | |
| 255 | 265 | #endif // !_LIBCPP_HAS_NO_LIBRARY_ALIGNED_ALLOCATION |
| 266 | // ------------------ END COPY ------------------ |