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 20namespace std { 21 22namespace __exception_ptr 23{ 24 25struct 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 38exception_ptr::~exception_ptr() _NOEXCEPT 39{ 40 reinterpret_cast<__exception_ptr::exception_ptr*>(this)->~exception_ptr(); 41} 42 43exception_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 50exception_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 57nested_exception::nested_exception() _NOEXCEPT 58 : __ptr_(current_exception()) 59{ 60} 61 62 63_LIBCPP_NORETURN 64void 65nested_exception::rethrow_nested() const 66{ 67 if (__ptr_ == nullptr) 68 terminate(); 69 rethrow_exception(__ptr_); 70} 71 72_LIBCPP_NORETURN 73void rethrow_exception(exception_ptr p) 74{ 75 rethrow_exception(reinterpret_cast<__exception_ptr::exception_ptr&>(p)); 76} 77 78} // namespace std 79