146035553Spatrick// -*- C++ -*- 246035553Spatrick//===----------------------------------------------------------------------===// 346035553Spatrick// 446035553Spatrick// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. 546035553Spatrick// See https://llvm.org/LICENSE.txt for license information. 646035553Spatrick// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception 746035553Spatrick// 846035553Spatrick//===----------------------------------------------------------------------===// 946035553Spatrick 1046035553Spatrick// libsupc++ does not implement the dependent EH ABI and the functionality 1146035553Spatrick// it uses to implement std::exception_ptr (which it declares as an alias of 1246035553Spatrick// std::__exception_ptr::exception_ptr) is not directly exported to clients. So 1346035553Spatrick// we have little choice but to hijack std::__exception_ptr::exception_ptr's 1446035553Spatrick// (which fortunately has the same layout as our std::exception_ptr) copy 1546035553Spatrick// constructor, assignment operator and destructor (which are part of its 1646035553Spatrick// stable ABI), and its rethrow_exception(std::__exception_ptr::exception_ptr) 1746035553Spatrick// function. 1846035553Spatrick 1946035553Spatricknamespace std { 2046035553Spatrick 2146035553Spatricknamespace __exception_ptr 2246035553Spatrick{ 2346035553Spatrick 2446035553Spatrickstruct exception_ptr 2546035553Spatrick{ 2646035553Spatrick void* __ptr_; 2746035553Spatrick 28*76d0caaeSpatrick exception_ptr(const exception_ptr&) noexcept; 29*76d0caaeSpatrick exception_ptr& operator=(const exception_ptr&) noexcept; 30*76d0caaeSpatrick ~exception_ptr() noexcept; 3146035553Spatrick}; 3246035553Spatrick 3346035553Spatrick} 3446035553Spatrick 3546035553Spatrick_LIBCPP_NORETURN void rethrow_exception(__exception_ptr::exception_ptr); 3646035553Spatrick 37*76d0caaeSpatrickexception_ptr::~exception_ptr() noexcept 3846035553Spatrick{ 3946035553Spatrick reinterpret_cast<__exception_ptr::exception_ptr*>(this)->~exception_ptr(); 4046035553Spatrick} 4146035553Spatrick 42*76d0caaeSpatrickexception_ptr::exception_ptr(const exception_ptr& other) noexcept 4346035553Spatrick : __ptr_(other.__ptr_) 4446035553Spatrick{ 4546035553Spatrick new (reinterpret_cast<void*>(this)) __exception_ptr::exception_ptr( 4646035553Spatrick reinterpret_cast<const __exception_ptr::exception_ptr&>(other)); 4746035553Spatrick} 4846035553Spatrick 49*76d0caaeSpatrickexception_ptr& exception_ptr::operator=(const exception_ptr& other) noexcept 5046035553Spatrick{ 5146035553Spatrick *reinterpret_cast<__exception_ptr::exception_ptr*>(this) = 5246035553Spatrick reinterpret_cast<const __exception_ptr::exception_ptr&>(other); 5346035553Spatrick return *this; 5446035553Spatrick} 5546035553Spatrick 56*76d0caaeSpatricknested_exception::nested_exception() noexcept 5746035553Spatrick : __ptr_(current_exception()) 5846035553Spatrick{ 5946035553Spatrick} 6046035553Spatrick 6146035553Spatrick 6246035553Spatrick_LIBCPP_NORETURN 6346035553Spatrickvoid 6446035553Spatricknested_exception::rethrow_nested() const 6546035553Spatrick{ 6646035553Spatrick if (__ptr_ == nullptr) 6746035553Spatrick terminate(); 6846035553Spatrick rethrow_exception(__ptr_); 6946035553Spatrick} 7046035553Spatrick 7146035553Spatrick_LIBCPP_NORETURN 7246035553Spatrickvoid rethrow_exception(exception_ptr p) 7346035553Spatrick{ 7446035553Spatrick rethrow_exception(reinterpret_cast<__exception_ptr::exception_ptr&>(p)); 7546035553Spatrick} 7646035553Spatrick 7746035553Spatrick} // namespace std 78