138fd1498Szrj // Exception Handling support header (exception_ptr class) for -*- C++ -*- 238fd1498Szrj 338fd1498Szrj // Copyright (C) 2008-2018 Free Software Foundation, Inc. 438fd1498Szrj // 538fd1498Szrj // This file is part of GCC. 638fd1498Szrj // 738fd1498Szrj // GCC is free software; you can redistribute it and/or modify 838fd1498Szrj // it under the terms of the GNU General Public License as published by 938fd1498Szrj // the Free Software Foundation; either version 3, or (at your option) 1038fd1498Szrj // any later version. 1138fd1498Szrj // 1238fd1498Szrj // GCC is distributed in the hope that it will be useful, 1338fd1498Szrj // but WITHOUT ANY WARRANTY; without even the implied warranty of 1438fd1498Szrj // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 1538fd1498Szrj // GNU General Public License for more details. 1638fd1498Szrj // 1738fd1498Szrj // Under Section 7 of GPL version 3, you are granted additional 1838fd1498Szrj // permissions described in the GCC Runtime Library Exception, version 1938fd1498Szrj // 3.1, as published by the Free Software Foundation. 2038fd1498Szrj 2138fd1498Szrj // You should have received a copy of the GNU General Public License and 2238fd1498Szrj // a copy of the GCC Runtime Library Exception along with this program; 2338fd1498Szrj // see the files COPYING3 and COPYING.RUNTIME respectively. If not, see 2438fd1498Szrj // <http://www.gnu.org/licenses/>. 2538fd1498Szrj 2638fd1498Szrj /** @file bits/exception_ptr.h 2738fd1498Szrj * This is an internal header file, included by other library headers. 2838fd1498Szrj * Do not attempt to use it directly. @headername{exception} 2938fd1498Szrj */ 3038fd1498Szrj 3138fd1498Szrj #ifndef _EXCEPTION_PTR_H 3238fd1498Szrj #define _EXCEPTION_PTR_H 3338fd1498Szrj 3438fd1498Szrj #pragma GCC visibility push(default) 3538fd1498Szrj 3638fd1498Szrj #include <bits/c++config.h> 3738fd1498Szrj #include <bits/exception_defines.h> 3838fd1498Szrj #include <bits/cxxabi_init_exception.h> 3938fd1498Szrj #include <typeinfo> 4038fd1498Szrj #include <new> 4138fd1498Szrj 4238fd1498Szrj extern "C++" { 4338fd1498Szrj 4438fd1498Szrj namespace std 4538fd1498Szrj { 4638fd1498Szrj class type_info; 4738fd1498Szrj 4838fd1498Szrj /** 4938fd1498Szrj * @addtogroup exceptions 5038fd1498Szrj * @{ 5138fd1498Szrj */ 5238fd1498Szrj namespace __exception_ptr 5338fd1498Szrj { 5438fd1498Szrj class exception_ptr; 5538fd1498Szrj } 5638fd1498Szrj 5738fd1498Szrj using __exception_ptr::exception_ptr; 5838fd1498Szrj 5938fd1498Szrj /** Obtain an exception_ptr to the currently handled exception. If there 6038fd1498Szrj * is none, or the currently handled exception is foreign, return the null 6138fd1498Szrj * value. 6238fd1498Szrj */ 6338fd1498Szrj exception_ptr current_exception() _GLIBCXX_USE_NOEXCEPT; 6438fd1498Szrj 6538fd1498Szrj template<typename _Ex> 6638fd1498Szrj exception_ptr make_exception_ptr(_Ex) _GLIBCXX_USE_NOEXCEPT; 6738fd1498Szrj 6838fd1498Szrj /// Throw the object pointed to by the exception_ptr. 6938fd1498Szrj void rethrow_exception(exception_ptr) __attribute__ ((__noreturn__)); 7038fd1498Szrj 7138fd1498Szrj namespace __exception_ptr 7238fd1498Szrj { 7338fd1498Szrj using std::rethrow_exception; 7438fd1498Szrj 7538fd1498Szrj /** 7638fd1498Szrj * @brief An opaque pointer to an arbitrary exception. 7738fd1498Szrj * @ingroup exceptions 7838fd1498Szrj */ 7938fd1498Szrj class exception_ptr 8038fd1498Szrj { 8138fd1498Szrj void* _M_exception_object; 8238fd1498Szrj 8338fd1498Szrj explicit exception_ptr(void* __e) _GLIBCXX_USE_NOEXCEPT; 8438fd1498Szrj 8538fd1498Szrj void _M_addref() _GLIBCXX_USE_NOEXCEPT; 8638fd1498Szrj void _M_release() _GLIBCXX_USE_NOEXCEPT; 8738fd1498Szrj 8838fd1498Szrj void *_M_get() const _GLIBCXX_NOEXCEPT __attribute__ ((__pure__)); 8938fd1498Szrj 9038fd1498Szrj friend exception_ptr std::current_exception() _GLIBCXX_USE_NOEXCEPT; 9138fd1498Szrj friend void std::rethrow_exception(exception_ptr); 9238fd1498Szrj template<typename _Ex> 9338fd1498Szrj friend exception_ptr std::make_exception_ptr(_Ex) _GLIBCXX_USE_NOEXCEPT; 9438fd1498Szrj 9538fd1498Szrj public: 9638fd1498Szrj exception_ptr() _GLIBCXX_USE_NOEXCEPT; 9738fd1498Szrj 9838fd1498Szrj exception_ptr(const exception_ptr&) _GLIBCXX_USE_NOEXCEPT; 9938fd1498Szrj 10038fd1498Szrj #if __cplusplus >= 201103L exception_ptr(nullptr_t)10138fd1498Szrj exception_ptr(nullptr_t) noexcept 10238fd1498Szrj : _M_exception_object(0) 10338fd1498Szrj { } 10438fd1498Szrj exception_ptr(exception_ptr && __o)10538fd1498Szrj exception_ptr(exception_ptr&& __o) noexcept 10638fd1498Szrj : _M_exception_object(__o._M_exception_object) 10738fd1498Szrj { __o._M_exception_object = 0; } 10838fd1498Szrj #endif 10938fd1498Szrj 11038fd1498Szrj #if (__cplusplus < 201103L) || defined (_GLIBCXX_EH_PTR_COMPAT) 11138fd1498Szrj typedef void (exception_ptr::*__safe_bool)(); 11238fd1498Szrj 11338fd1498Szrj // For construction from nullptr or 0. 11438fd1498Szrj exception_ptr(__safe_bool) _GLIBCXX_USE_NOEXCEPT; 11538fd1498Szrj #endif 11638fd1498Szrj 11738fd1498Szrj exception_ptr& 11838fd1498Szrj operator=(const exception_ptr&) _GLIBCXX_USE_NOEXCEPT; 11938fd1498Szrj 12038fd1498Szrj #if __cplusplus >= 201103L 12138fd1498Szrj exception_ptr& 12238fd1498Szrj operator=(exception_ptr&& __o) noexcept 12338fd1498Szrj { 12438fd1498Szrj exception_ptr(static_cast<exception_ptr&&>(__o)).swap(*this); 12538fd1498Szrj return *this; 12638fd1498Szrj } 12738fd1498Szrj #endif 12838fd1498Szrj 12938fd1498Szrj ~exception_ptr() _GLIBCXX_USE_NOEXCEPT; 13038fd1498Szrj 13138fd1498Szrj void 13238fd1498Szrj swap(exception_ptr&) _GLIBCXX_USE_NOEXCEPT; 13338fd1498Szrj 13438fd1498Szrj #ifdef _GLIBCXX_EH_PTR_COMPAT 13538fd1498Szrj // Retained for compatibility with CXXABI_1.3. 13638fd1498Szrj void _M_safe_bool_dummy() _GLIBCXX_USE_NOEXCEPT 13738fd1498Szrj __attribute__ ((__const__)); 13838fd1498Szrj bool operator!() const _GLIBCXX_USE_NOEXCEPT 13938fd1498Szrj __attribute__ ((__pure__)); 14038fd1498Szrj operator __safe_bool() const _GLIBCXX_USE_NOEXCEPT; 14138fd1498Szrj #endif 14238fd1498Szrj 14338fd1498Szrj #if __cplusplus >= 201103L 14438fd1498Szrj explicit operator bool() const 14538fd1498Szrj { return _M_exception_object; } 14638fd1498Szrj #endif 14738fd1498Szrj 14838fd1498Szrj friend bool 14938fd1498Szrj operator==(const exception_ptr&, const exception_ptr&) 15038fd1498Szrj _GLIBCXX_USE_NOEXCEPT __attribute__ ((__pure__)); 15138fd1498Szrj 15238fd1498Szrj const class std::type_info* 15338fd1498Szrj __cxa_exception_type() const _GLIBCXX_USE_NOEXCEPT 15438fd1498Szrj __attribute__ ((__pure__)); 15538fd1498Szrj }; 15638fd1498Szrj 15738fd1498Szrj bool 15838fd1498Szrj operator==(const exception_ptr&, const exception_ptr&) 15938fd1498Szrj _GLIBCXX_USE_NOEXCEPT __attribute__ ((__pure__)); 16038fd1498Szrj 16138fd1498Szrj bool 16238fd1498Szrj operator!=(const exception_ptr&, const exception_ptr&) 16338fd1498Szrj _GLIBCXX_USE_NOEXCEPT __attribute__ ((__pure__)); 16438fd1498Szrj 16538fd1498Szrj inline void swap(exception_ptr & __lhs,exception_ptr & __rhs)16638fd1498Szrj swap(exception_ptr& __lhs, exception_ptr& __rhs) 16738fd1498Szrj { __lhs.swap(__rhs); } 16838fd1498Szrj 16938fd1498Szrj template<typename _Ex> 17038fd1498Szrj inline void __dest_thunk(void * __x)17138fd1498Szrj __dest_thunk(void* __x) 17238fd1498Szrj { static_cast<_Ex*>(__x)->~_Ex(); } 17338fd1498Szrj 17438fd1498Szrj } // namespace __exception_ptr 17538fd1498Szrj 17638fd1498Szrj /// Obtain an exception_ptr pointing to a copy of the supplied object. 17738fd1498Szrj template<typename _Ex> 17838fd1498Szrj exception_ptr make_exception_ptr(_Ex __ex)17938fd1498Szrj make_exception_ptr(_Ex __ex) _GLIBCXX_USE_NOEXCEPT 18038fd1498Szrj { 181*58e805e6Szrj #if __cpp_exceptions && __cpp_rtti && !_GLIBCXX_HAVE_CDTOR_CALLABI 18238fd1498Szrj void* __e = __cxxabiv1::__cxa_allocate_exception(sizeof(_Ex)); 18338fd1498Szrj (void) __cxxabiv1::__cxa_init_primary_exception( 18438fd1498Szrj __e, const_cast<std::type_info*>(&typeid(__ex)), 18538fd1498Szrj __exception_ptr::__dest_thunk<_Ex>); 186*58e805e6Szrj try 187*58e805e6Szrj { 18838fd1498Szrj ::new (__e) _Ex(__ex); 18938fd1498Szrj return exception_ptr(__e); 190*58e805e6Szrj } 191*58e805e6Szrj catch(...) 192*58e805e6Szrj { 193*58e805e6Szrj __cxxabiv1::__cxa_free_exception(__e); 194*58e805e6Szrj return current_exception(); 195*58e805e6Szrj } 196*58e805e6Szrj #elif __cpp_exceptions 197*58e805e6Szrj try 198*58e805e6Szrj { 19938fd1498Szrj throw __ex; 20038fd1498Szrj } 20138fd1498Szrj catch(...) 20238fd1498Szrj { 20338fd1498Szrj return current_exception(); 20438fd1498Szrj } 205*58e805e6Szrj #else // no RTTI and no exceptions 20638fd1498Szrj return exception_ptr(); 20738fd1498Szrj #endif 20838fd1498Szrj } 20938fd1498Szrj 21038fd1498Szrj // @} group exceptions 21138fd1498Szrj } // namespace std 21238fd1498Szrj 21338fd1498Szrj } // extern "C++" 21438fd1498Szrj 21538fd1498Szrj #pragma GCC visibility pop 21638fd1498Szrj 21738fd1498Szrj #endif 218