11debfc3dSmrg // Exception Handling support header (exception_ptr class) for -*- C++ -*- 21debfc3dSmrg 3*8feb0f0bSmrg // Copyright (C) 2008-2020 Free Software Foundation, Inc. 41debfc3dSmrg // 51debfc3dSmrg // This file is part of GCC. 61debfc3dSmrg // 71debfc3dSmrg // GCC is free software; you can redistribute it and/or modify 81debfc3dSmrg // it under the terms of the GNU General Public License as published by 91debfc3dSmrg // the Free Software Foundation; either version 3, or (at your option) 101debfc3dSmrg // any later version. 111debfc3dSmrg // 121debfc3dSmrg // GCC is distributed in the hope that it will be useful, 131debfc3dSmrg // but WITHOUT ANY WARRANTY; without even the implied warranty of 141debfc3dSmrg // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 151debfc3dSmrg // GNU General Public License for more details. 161debfc3dSmrg // 171debfc3dSmrg // Under Section 7 of GPL version 3, you are granted additional 181debfc3dSmrg // permissions described in the GCC Runtime Library Exception, version 191debfc3dSmrg // 3.1, as published by the Free Software Foundation. 201debfc3dSmrg 211debfc3dSmrg // You should have received a copy of the GNU General Public License and 221debfc3dSmrg // a copy of the GCC Runtime Library Exception along with this program; 231debfc3dSmrg // see the files COPYING3 and COPYING.RUNTIME respectively. If not, see 241debfc3dSmrg // <http://www.gnu.org/licenses/>. 251debfc3dSmrg 261debfc3dSmrg /** @file bits/exception_ptr.h 271debfc3dSmrg * This is an internal header file, included by other library headers. 281debfc3dSmrg * Do not attempt to use it directly. @headername{exception} 291debfc3dSmrg */ 301debfc3dSmrg 311debfc3dSmrg #ifndef _EXCEPTION_PTR_H 321debfc3dSmrg #define _EXCEPTION_PTR_H 331debfc3dSmrg 341debfc3dSmrg #pragma GCC visibility push(default) 351debfc3dSmrg 361debfc3dSmrg #include <bits/c++config.h> 371debfc3dSmrg #include <bits/exception_defines.h> 381debfc3dSmrg #include <bits/cxxabi_init_exception.h> 391debfc3dSmrg #include <typeinfo> 401debfc3dSmrg #include <new> 411debfc3dSmrg 42*8feb0f0bSmrg #if __cplusplus >= 201103L 43*8feb0f0bSmrg # include <bits/move.h> 44*8feb0f0bSmrg #endif 45*8feb0f0bSmrg 461debfc3dSmrg extern "C++" { 471debfc3dSmrg 481debfc3dSmrg namespace std 491debfc3dSmrg { 501debfc3dSmrg class type_info; 511debfc3dSmrg 521debfc3dSmrg /** 531debfc3dSmrg * @addtogroup exceptions 541debfc3dSmrg * @{ 551debfc3dSmrg */ 56*8feb0f0bSmrg 571debfc3dSmrg namespace __exception_ptr 581debfc3dSmrg { 591debfc3dSmrg class exception_ptr; 601debfc3dSmrg } 611debfc3dSmrg 621debfc3dSmrg using __exception_ptr::exception_ptr; 631debfc3dSmrg 641debfc3dSmrg /** Obtain an exception_ptr to the currently handled exception. If there 651debfc3dSmrg * is none, or the currently handled exception is foreign, return the null 661debfc3dSmrg * value. 671debfc3dSmrg */ 681debfc3dSmrg exception_ptr current_exception() _GLIBCXX_USE_NOEXCEPT; 691debfc3dSmrg 701debfc3dSmrg template<typename _Ex> 711debfc3dSmrg exception_ptr make_exception_ptr(_Ex) _GLIBCXX_USE_NOEXCEPT; 721debfc3dSmrg 731debfc3dSmrg /// Throw the object pointed to by the exception_ptr. 741debfc3dSmrg void rethrow_exception(exception_ptr) __attribute__ ((__noreturn__)); 751debfc3dSmrg 761debfc3dSmrg namespace __exception_ptr 771debfc3dSmrg { 781debfc3dSmrg using std::rethrow_exception; 791debfc3dSmrg 801debfc3dSmrg /** 811debfc3dSmrg * @brief An opaque pointer to an arbitrary exception. 821debfc3dSmrg * @ingroup exceptions 831debfc3dSmrg */ 841debfc3dSmrg class exception_ptr 851debfc3dSmrg { 861debfc3dSmrg void* _M_exception_object; 871debfc3dSmrg 881debfc3dSmrg explicit exception_ptr(void* __e) _GLIBCXX_USE_NOEXCEPT; 891debfc3dSmrg 901debfc3dSmrg void _M_addref() _GLIBCXX_USE_NOEXCEPT; 911debfc3dSmrg void _M_release() _GLIBCXX_USE_NOEXCEPT; 921debfc3dSmrg 931debfc3dSmrg void *_M_get() const _GLIBCXX_NOEXCEPT __attribute__ ((__pure__)); 941debfc3dSmrg 951debfc3dSmrg friend exception_ptr std::current_exception() _GLIBCXX_USE_NOEXCEPT; 961debfc3dSmrg friend void std::rethrow_exception(exception_ptr); 971debfc3dSmrg template<typename _Ex> 981debfc3dSmrg friend exception_ptr std::make_exception_ptr(_Ex) _GLIBCXX_USE_NOEXCEPT; 991debfc3dSmrg 1001debfc3dSmrg public: 1011debfc3dSmrg exception_ptr() _GLIBCXX_USE_NOEXCEPT; 1021debfc3dSmrg 1031debfc3dSmrg exception_ptr(const exception_ptr&) _GLIBCXX_USE_NOEXCEPT; 1041debfc3dSmrg 1051debfc3dSmrg #if __cplusplus >= 201103L exception_ptr(nullptr_t)1061debfc3dSmrg exception_ptr(nullptr_t) noexcept 1071debfc3dSmrg : _M_exception_object(0) 1081debfc3dSmrg { } 1091debfc3dSmrg exception_ptr(exception_ptr && __o)1101debfc3dSmrg exception_ptr(exception_ptr&& __o) noexcept 1111debfc3dSmrg : _M_exception_object(__o._M_exception_object) 1121debfc3dSmrg { __o._M_exception_object = 0; } 1131debfc3dSmrg #endif 1141debfc3dSmrg 1151debfc3dSmrg #if (__cplusplus < 201103L) || defined (_GLIBCXX_EH_PTR_COMPAT) 1161debfc3dSmrg typedef void (exception_ptr::*__safe_bool)(); 1171debfc3dSmrg 1181debfc3dSmrg // For construction from nullptr or 0. 1191debfc3dSmrg exception_ptr(__safe_bool) _GLIBCXX_USE_NOEXCEPT; 1201debfc3dSmrg #endif 1211debfc3dSmrg 1221debfc3dSmrg exception_ptr& 1231debfc3dSmrg operator=(const exception_ptr&) _GLIBCXX_USE_NOEXCEPT; 1241debfc3dSmrg 1251debfc3dSmrg #if __cplusplus >= 201103L 1261debfc3dSmrg exception_ptr& 1271debfc3dSmrg operator=(exception_ptr&& __o) noexcept 1281debfc3dSmrg { 1291debfc3dSmrg exception_ptr(static_cast<exception_ptr&&>(__o)).swap(*this); 1301debfc3dSmrg return *this; 1311debfc3dSmrg } 1321debfc3dSmrg #endif 1331debfc3dSmrg 1341debfc3dSmrg ~exception_ptr() _GLIBCXX_USE_NOEXCEPT; 1351debfc3dSmrg 1361debfc3dSmrg void 1371debfc3dSmrg swap(exception_ptr&) _GLIBCXX_USE_NOEXCEPT; 1381debfc3dSmrg 1391debfc3dSmrg #ifdef _GLIBCXX_EH_PTR_COMPAT 1401debfc3dSmrg // Retained for compatibility with CXXABI_1.3. 1411debfc3dSmrg void _M_safe_bool_dummy() _GLIBCXX_USE_NOEXCEPT 1421debfc3dSmrg __attribute__ ((__const__)); 1431debfc3dSmrg bool operator!() const _GLIBCXX_USE_NOEXCEPT 1441debfc3dSmrg __attribute__ ((__pure__)); 1451debfc3dSmrg operator __safe_bool() const _GLIBCXX_USE_NOEXCEPT; 1461debfc3dSmrg #endif 1471debfc3dSmrg 1481debfc3dSmrg #if __cplusplus >= 201103L 1491debfc3dSmrg explicit operator bool() const 1501debfc3dSmrg { return _M_exception_object; } 1511debfc3dSmrg #endif 1521debfc3dSmrg 1531debfc3dSmrg friend bool 1541debfc3dSmrg operator==(const exception_ptr&, const exception_ptr&) 1551debfc3dSmrg _GLIBCXX_USE_NOEXCEPT __attribute__ ((__pure__)); 1561debfc3dSmrg 1571debfc3dSmrg const class std::type_info* 1581debfc3dSmrg __cxa_exception_type() const _GLIBCXX_USE_NOEXCEPT 1591debfc3dSmrg __attribute__ ((__pure__)); 1601debfc3dSmrg }; 1611debfc3dSmrg 162*8feb0f0bSmrg /// @relates exception_ptr @{ 163*8feb0f0bSmrg 1641debfc3dSmrg bool 1651debfc3dSmrg operator==(const exception_ptr&, const exception_ptr&) 1661debfc3dSmrg _GLIBCXX_USE_NOEXCEPT __attribute__ ((__pure__)); 1671debfc3dSmrg 1681debfc3dSmrg bool 1691debfc3dSmrg operator!=(const exception_ptr&, const exception_ptr&) 1701debfc3dSmrg _GLIBCXX_USE_NOEXCEPT __attribute__ ((__pure__)); 1711debfc3dSmrg 1721debfc3dSmrg inline void swap(exception_ptr & __lhs,exception_ptr & __rhs)1731debfc3dSmrg swap(exception_ptr& __lhs, exception_ptr& __rhs) 1741debfc3dSmrg { __lhs.swap(__rhs); } 1751debfc3dSmrg 176*8feb0f0bSmrg // @} 177*8feb0f0bSmrg 178*8feb0f0bSmrg /// @cond undocumented 1791debfc3dSmrg template<typename _Ex> 1801debfc3dSmrg inline void __dest_thunk(void * __x)1811debfc3dSmrg __dest_thunk(void* __x) 1821debfc3dSmrg { static_cast<_Ex*>(__x)->~_Ex(); } 183*8feb0f0bSmrg /// @endcond 1841debfc3dSmrg 1851debfc3dSmrg } // namespace __exception_ptr 1861debfc3dSmrg 1871debfc3dSmrg /// Obtain an exception_ptr pointing to a copy of the supplied object. 1881debfc3dSmrg template<typename _Ex> 1891debfc3dSmrg exception_ptr make_exception_ptr(_Ex __ex)1901debfc3dSmrg make_exception_ptr(_Ex __ex) _GLIBCXX_USE_NOEXCEPT 1911debfc3dSmrg { 192*8feb0f0bSmrg #if __cpp_exceptions && __cpp_rtti && !_GLIBCXX_HAVE_CDTOR_CALLABI \ 193*8feb0f0bSmrg && __cplusplus >= 201103L 194*8feb0f0bSmrg using _Ex2 = typename remove_reference<_Ex>::type; 1951debfc3dSmrg void* __e = __cxxabiv1::__cxa_allocate_exception(sizeof(_Ex)); 1961debfc3dSmrg (void) __cxxabiv1::__cxa_init_primary_exception( 197*8feb0f0bSmrg __e, const_cast<std::type_info*>(&typeid(_Ex)), 198*8feb0f0bSmrg __exception_ptr::__dest_thunk<_Ex2>); 1991debfc3dSmrg try 2001debfc3dSmrg { 201*8feb0f0bSmrg ::new (__e) _Ex2(std::forward<_Ex>(__ex)); 2021debfc3dSmrg return exception_ptr(__e); 2031debfc3dSmrg } 2041debfc3dSmrg catch(...) 2051debfc3dSmrg { 2061debfc3dSmrg __cxxabiv1::__cxa_free_exception(__e); 2071debfc3dSmrg return current_exception(); 2081debfc3dSmrg } 2091debfc3dSmrg #elif __cpp_exceptions 2101debfc3dSmrg try 2111debfc3dSmrg { 2121debfc3dSmrg throw __ex; 2131debfc3dSmrg } 2141debfc3dSmrg catch(...) 2151debfc3dSmrg { 2161debfc3dSmrg return current_exception(); 2171debfc3dSmrg } 2181debfc3dSmrg #else // no RTTI and no exceptions 2191debfc3dSmrg return exception_ptr(); 2201debfc3dSmrg #endif 2211debfc3dSmrg } 2221debfc3dSmrg 223*8feb0f0bSmrg /// @} group exceptions 2241debfc3dSmrg } // namespace std 2251debfc3dSmrg 2261debfc3dSmrg } // extern "C++" 2271debfc3dSmrg 2281debfc3dSmrg #pragma GCC visibility pop 2291debfc3dSmrg 2301debfc3dSmrg #endif 231