| 1 | // Exception Handling support header (exception_ptr class) for -*- C++ -*- | 
| 2 |  | 
| 3 | // Copyright (C) 2008-2019 Free Software Foundation, Inc. | 
| 4 | // | 
| 5 | // This file is part of GCC. | 
| 6 | // | 
| 7 | // GCC is free software; you can redistribute it and/or modify | 
| 8 | // it under the terms of the GNU General Public License as published by | 
| 9 | // the Free Software Foundation; either version 3, or (at your option) | 
| 10 | // any later version. | 
| 11 | //  | 
| 12 | // GCC is distributed in the hope that it will be useful, | 
| 13 | // but WITHOUT ANY WARRANTY; without even the implied warranty of | 
| 14 | // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the | 
| 15 | // GNU General Public License for more details. | 
| 16 | //  | 
| 17 | // Under Section 7 of GPL version 3, you are granted additional | 
| 18 | // permissions described in the GCC Runtime Library Exception, version | 
| 19 | // 3.1, as published by the Free Software Foundation. | 
| 20 |  | 
| 21 | // You should have received a copy of the GNU General Public License and | 
| 22 | // a copy of the GCC Runtime Library Exception along with this program; | 
| 23 | // see the files COPYING3 and COPYING.RUNTIME respectively.  If not, see | 
| 24 | // <http://www.gnu.org/licenses/>. | 
| 25 |  | 
| 26 | /** @file bits/exception_ptr.h | 
| 27 |  *  This is an internal header file, included by other library headers. | 
| 28 |  *  Do not attempt to use it directly. @headername{exception} | 
| 29 |  */ | 
| 30 |  | 
| 31 | #ifndef _EXCEPTION_PTR_H | 
| 32 | #define _EXCEPTION_PTR_H | 
| 33 |  | 
| 34 | #pragma GCC visibility push(default) | 
| 35 |  | 
| 36 | #include <bits/c++config.h> | 
| 37 | #include <bits/exception_defines.h> | 
| 38 | #include <bits/cxxabi_init_exception.h> | 
| 39 | #include <typeinfo> | 
| 40 | #include <new> | 
| 41 |  | 
| 42 | extern "C++"  { | 
| 43 |  | 
| 44 | namespace std  | 
| 45 | { | 
| 46 |   class type_info; | 
| 47 |  | 
| 48 |   /** | 
| 49 |    * @addtogroup exceptions | 
| 50 |    * @{ | 
| 51 |    */ | 
| 52 |   namespace __exception_ptr | 
| 53 |   { | 
| 54 |     class exception_ptr; | 
| 55 |   } | 
| 56 |  | 
| 57 |   using __exception_ptr::exception_ptr; | 
| 58 |  | 
| 59 |   /** Obtain an exception_ptr to the currently handled exception. If there | 
| 60 |    *  is none, or the currently handled exception is foreign, return the null | 
| 61 |    *  value. | 
| 62 |    */ | 
| 63 |   exception_ptr current_exception() _GLIBCXX_USE_NOEXCEPT; | 
| 64 |  | 
| 65 |   template<typename _Ex> | 
| 66 |   exception_ptr make_exception_ptr(_Ex) _GLIBCXX_USE_NOEXCEPT; | 
| 67 |  | 
| 68 |   /// Throw the object pointed to by the exception_ptr. | 
| 69 |   void rethrow_exception(exception_ptr) __attribute__ ((__noreturn__)); | 
| 70 |  | 
| 71 |   namespace __exception_ptr | 
| 72 |   { | 
| 73 |     using std::rethrow_exception; | 
| 74 |  | 
| 75 |     /** | 
| 76 |      *  @brief An opaque pointer to an arbitrary exception. | 
| 77 |      *  @ingroup exceptions | 
| 78 |      */ | 
| 79 |     class exception_ptr | 
| 80 |     { | 
| 81 |       void* _M_exception_object; | 
| 82 |  | 
| 83 |       explicit exception_ptr(void* __e) _GLIBCXX_USE_NOEXCEPT; | 
| 84 |  | 
| 85 |       void _M_addref() _GLIBCXX_USE_NOEXCEPT; | 
| 86 |       void _M_release() _GLIBCXX_USE_NOEXCEPT; | 
| 87 |  | 
| 88 |       void *_M_get() const _GLIBCXX_NOEXCEPT __attribute__ ((__pure__)); | 
| 89 |  | 
| 90 |       friend exception_ptr std::current_exception() _GLIBCXX_USE_NOEXCEPT; | 
| 91 |       friend void std::rethrow_exception(exception_ptr); | 
| 92 |       template<typename _Ex> | 
| 93 |       friend exception_ptr std::make_exception_ptr(_Ex) _GLIBCXX_USE_NOEXCEPT; | 
| 94 |  | 
| 95 |     public: | 
| 96 |       exception_ptr() _GLIBCXX_USE_NOEXCEPT; | 
| 97 |  | 
| 98 |       exception_ptr(const exception_ptr&) _GLIBCXX_USE_NOEXCEPT; | 
| 99 |  | 
| 100 | #if __cplusplus >= 201103L | 
| 101 |       exception_ptr(nullptr_t) noexcept | 
| 102 |       : _M_exception_object(0) | 
| 103 |       { } | 
| 104 |  | 
| 105 |       exception_ptr(exception_ptr&& __o) noexcept | 
| 106 |       : _M_exception_object(__o._M_exception_object) | 
| 107 |       { __o._M_exception_object = 0; } | 
| 108 | #endif | 
| 109 |  | 
| 110 | #if (__cplusplus < 201103L) || defined (_GLIBCXX_EH_PTR_COMPAT) | 
| 111 |       typedef void (exception_ptr::*__safe_bool)(); | 
| 112 |  | 
| 113 |       // For construction from nullptr or 0. | 
| 114 |       exception_ptr(__safe_bool) _GLIBCXX_USE_NOEXCEPT; | 
| 115 | #endif | 
| 116 |  | 
| 117 |       exception_ptr&  | 
| 118 |       operator=(const exception_ptr&) _GLIBCXX_USE_NOEXCEPT; | 
| 119 |  | 
| 120 | #if __cplusplus >= 201103L | 
| 121 |       exception_ptr&  | 
| 122 |       operator=(exception_ptr&& __o) noexcept | 
| 123 |       { | 
| 124 |         exception_ptr(static_cast<exception_ptr&&>(__o)).swap(*this); | 
| 125 |         return *this; | 
| 126 |       } | 
| 127 | #endif | 
| 128 |  | 
| 129 |       ~exception_ptr() _GLIBCXX_USE_NOEXCEPT; | 
| 130 |  | 
| 131 |       void  | 
| 132 |       swap(exception_ptr&) _GLIBCXX_USE_NOEXCEPT; | 
| 133 |  | 
| 134 | #ifdef _GLIBCXX_EH_PTR_COMPAT | 
| 135 |       // Retained for compatibility with CXXABI_1.3. | 
| 136 |       void _M_safe_bool_dummy() _GLIBCXX_USE_NOEXCEPT | 
| 137 | 	__attribute__ ((__const__)); | 
| 138 |       bool operator!() const _GLIBCXX_USE_NOEXCEPT | 
| 139 | 	__attribute__ ((__pure__)); | 
| 140 |       operator __safe_bool() const _GLIBCXX_USE_NOEXCEPT; | 
| 141 | #endif | 
| 142 |  | 
| 143 | #if __cplusplus >= 201103L | 
| 144 |       explicit operator bool() const | 
| 145 |       { return _M_exception_object; } | 
| 146 | #endif | 
| 147 |  | 
| 148 |       friend bool  | 
| 149 |       operator==(const exception_ptr&, const exception_ptr&) | 
| 150 | 	_GLIBCXX_USE_NOEXCEPT __attribute__ ((__pure__)); | 
| 151 |  | 
| 152 |       const class std::type_info* | 
| 153 |       __cxa_exception_type() const _GLIBCXX_USE_NOEXCEPT | 
| 154 | 	__attribute__ ((__pure__)); | 
| 155 |     }; | 
| 156 |  | 
| 157 |     bool  | 
| 158 |     operator==(const exception_ptr&, const exception_ptr&) | 
| 159 |       _GLIBCXX_USE_NOEXCEPT __attribute__ ((__pure__)); | 
| 160 |  | 
| 161 |     bool  | 
| 162 |     operator!=(const exception_ptr&, const exception_ptr&) | 
| 163 |       _GLIBCXX_USE_NOEXCEPT __attribute__ ((__pure__)); | 
| 164 |  | 
| 165 |     inline void | 
| 166 |     swap(exception_ptr& __lhs, exception_ptr& __rhs) | 
| 167 |     { __lhs.swap(__rhs); } | 
| 168 |  | 
| 169 |     template<typename _Ex> | 
| 170 |       inline void | 
| 171 |       __dest_thunk(void* __x) | 
| 172 |       { static_cast<_Ex*>(__x)->~_Ex(); } | 
| 173 |  | 
| 174 |   } // namespace __exception_ptr | 
| 175 |  | 
| 176 |   /// Obtain an exception_ptr pointing to a copy of the supplied object. | 
| 177 |   template<typename _Ex> | 
| 178 |     exception_ptr  | 
| 179 |     make_exception_ptr(_Ex __ex) _GLIBCXX_USE_NOEXCEPT | 
| 180 |     { | 
| 181 | #if __cpp_exceptions && __cpp_rtti && !_GLIBCXX_HAVE_CDTOR_CALLABI | 
| 182 |       void* __e = __cxxabiv1::__cxa_allocate_exception(sizeof(_Ex)); | 
| 183 |       (void) __cxxabiv1::__cxa_init_primary_exception( | 
| 184 | 	  __e, const_cast<std::type_info*>(&typeid(__ex)), | 
| 185 | 	  __exception_ptr::__dest_thunk<_Ex>); | 
| 186 |       try | 
| 187 | 	{ | 
| 188 |           ::new (__e) _Ex(__ex); | 
| 189 |           return exception_ptr(__e); | 
| 190 | 	} | 
| 191 |       catch(...) | 
| 192 | 	{ | 
| 193 | 	  __cxxabiv1::__cxa_free_exception(__e); | 
| 194 | 	  return current_exception(); | 
| 195 | 	} | 
| 196 | #elif __cpp_exceptions | 
| 197 |       try | 
| 198 | 	{ | 
| 199 |           throw __ex; | 
| 200 | 	} | 
| 201 |       catch(...) | 
| 202 | 	{ | 
| 203 | 	  return current_exception(); | 
| 204 | 	} | 
| 205 | #else // no RTTI and no exceptions | 
| 206 |       return exception_ptr(); | 
| 207 | #endif | 
| 208 |     } | 
| 209 |  | 
| 210 |   // @} group exceptions | 
| 211 | } // namespace std | 
| 212 |  | 
| 213 | } // extern "C++" | 
| 214 |  | 
| 215 | #pragma GCC visibility pop | 
| 216 |  | 
| 217 | #endif | 
| 218 |  |