]> CyberLeo.Net >> Repos - FreeBSD/FreeBSD.git/blob - contrib/llvm-project/libcxx/src/support/runtime/exception_pointer_glibcxx.ipp
MFC r355940:
[FreeBSD/FreeBSD.git] / contrib / llvm-project / libcxx / src / support / runtime / exception_pointer_glibcxx.ipp
1 // -*- C++ -*-
2 //===----------------------------------------------------------------------===//
3 //
4 // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
5 // See https://llvm.org/LICENSE.txt for license information.
6 // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
7 //
8 //===----------------------------------------------------------------------===//
9
10 // libsupc++ does not implement the dependent EH ABI and the functionality
11 // it uses to implement std::exception_ptr (which it declares as an alias of
12 // std::__exception_ptr::exception_ptr) is not directly exported to clients. So
13 // we have little choice but to hijack std::__exception_ptr::exception_ptr's
14 // (which fortunately has the same layout as our std::exception_ptr) copy
15 // constructor, assignment operator and destructor (which are part of its
16 // stable ABI), and its rethrow_exception(std::__exception_ptr::exception_ptr)
17 // function.
18
19 namespace std {
20
21 namespace __exception_ptr
22 {
23
24 struct exception_ptr
25 {
26     void* __ptr_;
27
28     exception_ptr(const exception_ptr&) _NOEXCEPT;
29     exception_ptr& operator=(const exception_ptr&) _NOEXCEPT;
30     ~exception_ptr() _NOEXCEPT;
31 };
32
33 }
34
35 _LIBCPP_NORETURN void rethrow_exception(__exception_ptr::exception_ptr);
36
37 exception_ptr::~exception_ptr() _NOEXCEPT
38 {
39     reinterpret_cast<__exception_ptr::exception_ptr*>(this)->~exception_ptr();
40 }
41
42 exception_ptr::exception_ptr(const exception_ptr& other) _NOEXCEPT
43     : __ptr_(other.__ptr_)
44 {
45     new (reinterpret_cast<void*>(this)) __exception_ptr::exception_ptr(
46         reinterpret_cast<const __exception_ptr::exception_ptr&>(other));
47 }
48
49 exception_ptr& exception_ptr::operator=(const exception_ptr& other) _NOEXCEPT
50 {
51     *reinterpret_cast<__exception_ptr::exception_ptr*>(this) =
52         reinterpret_cast<const __exception_ptr::exception_ptr&>(other);
53     return *this;
54 }
55
56 nested_exception::nested_exception() _NOEXCEPT
57     : __ptr_(current_exception())
58 {
59 }
60
61
62 _LIBCPP_NORETURN
63 void
64 nested_exception::rethrow_nested() const
65 {
66     if (__ptr_ == nullptr)
67         terminate();
68     rethrow_exception(__ptr_);
69 }
70
71 _LIBCPP_NORETURN
72 void rethrow_exception(exception_ptr p)
73 {
74     rethrow_exception(reinterpret_cast<__exception_ptr::exception_ptr&>(p));
75 }
76
77 } // namespace std