xref: /openbsd-src/gnu/llvm/libcxx/src/support/runtime/exception_pointer_glibcxx.ipp (revision 76d0caaeb19ae0808d90af1d0b3b7b50b3e5383f)
146035553Spatrick// -*- C++ -*-
246035553Spatrick//===----------------------------------------------------------------------===//
346035553Spatrick//
446035553Spatrick// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
546035553Spatrick// See https://llvm.org/LICENSE.txt for license information.
646035553Spatrick// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
746035553Spatrick//
846035553Spatrick//===----------------------------------------------------------------------===//
946035553Spatrick
1046035553Spatrick// libsupc++ does not implement the dependent EH ABI and the functionality
1146035553Spatrick// it uses to implement std::exception_ptr (which it declares as an alias of
1246035553Spatrick// std::__exception_ptr::exception_ptr) is not directly exported to clients. So
1346035553Spatrick// we have little choice but to hijack std::__exception_ptr::exception_ptr's
1446035553Spatrick// (which fortunately has the same layout as our std::exception_ptr) copy
1546035553Spatrick// constructor, assignment operator and destructor (which are part of its
1646035553Spatrick// stable ABI), and its rethrow_exception(std::__exception_ptr::exception_ptr)
1746035553Spatrick// function.
1846035553Spatrick
1946035553Spatricknamespace std {
2046035553Spatrick
2146035553Spatricknamespace __exception_ptr
2246035553Spatrick{
2346035553Spatrick
2446035553Spatrickstruct exception_ptr
2546035553Spatrick{
2646035553Spatrick    void* __ptr_;
2746035553Spatrick
28*76d0caaeSpatrick    exception_ptr(const exception_ptr&) noexcept;
29*76d0caaeSpatrick    exception_ptr& operator=(const exception_ptr&) noexcept;
30*76d0caaeSpatrick    ~exception_ptr() noexcept;
3146035553Spatrick};
3246035553Spatrick
3346035553Spatrick}
3446035553Spatrick
3546035553Spatrick_LIBCPP_NORETURN void rethrow_exception(__exception_ptr::exception_ptr);
3646035553Spatrick
37*76d0caaeSpatrickexception_ptr::~exception_ptr() noexcept
3846035553Spatrick{
3946035553Spatrick    reinterpret_cast<__exception_ptr::exception_ptr*>(this)->~exception_ptr();
4046035553Spatrick}
4146035553Spatrick
42*76d0caaeSpatrickexception_ptr::exception_ptr(const exception_ptr& other) noexcept
4346035553Spatrick    : __ptr_(other.__ptr_)
4446035553Spatrick{
4546035553Spatrick    new (reinterpret_cast<void*>(this)) __exception_ptr::exception_ptr(
4646035553Spatrick        reinterpret_cast<const __exception_ptr::exception_ptr&>(other));
4746035553Spatrick}
4846035553Spatrick
49*76d0caaeSpatrickexception_ptr& exception_ptr::operator=(const exception_ptr& other) noexcept
5046035553Spatrick{
5146035553Spatrick    *reinterpret_cast<__exception_ptr::exception_ptr*>(this) =
5246035553Spatrick        reinterpret_cast<const __exception_ptr::exception_ptr&>(other);
5346035553Spatrick    return *this;
5446035553Spatrick}
5546035553Spatrick
56*76d0caaeSpatricknested_exception::nested_exception() noexcept
5746035553Spatrick    : __ptr_(current_exception())
5846035553Spatrick{
5946035553Spatrick}
6046035553Spatrick
6146035553Spatrick
6246035553Spatrick_LIBCPP_NORETURN
6346035553Spatrickvoid
6446035553Spatricknested_exception::rethrow_nested() const
6546035553Spatrick{
6646035553Spatrick    if (__ptr_ == nullptr)
6746035553Spatrick        terminate();
6846035553Spatrick    rethrow_exception(__ptr_);
6946035553Spatrick}
7046035553Spatrick
7146035553Spatrick_LIBCPP_NORETURN
7246035553Spatrickvoid rethrow_exception(exception_ptr p)
7346035553Spatrick{
7446035553Spatrick    rethrow_exception(reinterpret_cast<__exception_ptr::exception_ptr&>(p));
7546035553Spatrick}
7646035553Spatrick
7746035553Spatrick} // namespace std
78