• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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