1 // -*- C++ -*- 2 //===----------------------------------------------------------------------===// 3 // 4 // The LLVM Compiler Infrastructure 5 // 6 // This file is dual licensed under the MIT and the University of Illinois Open 7 // Source Licenses. See LICENSE.TXT for details. 8 // 9 //===----------------------------------------------------------------------===// 10 11 // libsupc++ does not implement the dependent EH ABI and the functionality 12 // it uses to implement std::exception_ptr (which it declares as an alias of 13 // std::__exception_ptr::exception_ptr) is not directly exported to clients. So 14 // we have little choice but to hijack std::__exception_ptr::exception_ptr's 15 // (which fortunately has the same layout as our std::exception_ptr) copy 16 // constructor, assignment operator and destructor (which are part of its 17 // stable ABI), and its rethrow_exception(std::__exception_ptr::exception_ptr) 18 // function. 19 20 namespace std { 21 22 namespace __exception_ptr 23 { 24 25 struct exception_ptr 26 { 27 void* __ptr_; 28 29 exception_ptr(const exception_ptr&) _NOEXCEPT; 30 exception_ptr& operator=(const exception_ptr&) _NOEXCEPT; 31 ~exception_ptr() _NOEXCEPT; 32 }; 33 34 } 35 36 _LIBCPP_NORETURN void rethrow_exception(__exception_ptr::exception_ptr); 37 38 exception_ptr::~exception_ptr() _NOEXCEPT 39 { 40 reinterpret_cast<__exception_ptr::exception_ptr*>(this)->~exception_ptr(); 41 } 42 43 exception_ptr::exception_ptr(const exception_ptr& other) _NOEXCEPT 44 : __ptr_(other.__ptr_) 45 { 46 new (reinterpret_cast<void*>(this)) __exception_ptr::exception_ptr( 47 reinterpret_cast<const __exception_ptr::exception_ptr&>(other)); 48 } 49 50 exception_ptr& exception_ptr::operator=(const exception_ptr& other) _NOEXCEPT 51 { 52 *reinterpret_cast<__exception_ptr::exception_ptr*>(this) = 53 reinterpret_cast<const __exception_ptr::exception_ptr&>(other); 54 return *this; 55 } 56 57 nested_exception::nested_exception() _NOEXCEPT 58 : __ptr_(current_exception()) 59 { 60 } 61 62 63 _LIBCPP_NORETURN 64 void 65 nested_exception::rethrow_nested() const 66 { 67 if (__ptr_ == nullptr) 68 terminate(); 69 rethrow_exception(__ptr_); 70 } 71 72 _LIBCPP_NORETURN 73 void rethrow_exception(exception_ptr p) 74 { 75 rethrow_exception(reinterpret_cast<__exception_ptr::exception_ptr&>(p)); 76 } 77 78 } // namespace std 79