Home | History | Annotate | Download | only in runtime
      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