1 //===------------------------ exception.cpp -------------------------------===//
3 // The LLVM Compiler Infrastructure
5 // This file is dual licensed under the MIT and the University of Illinois Open
6 // Source Licenses. See LICENSE.TXT for details.
8 //===----------------------------------------------------------------------===//
14 #define __has_include(inc) 0
20 using namespace __cxxabiv1;
21 #define HAVE_DEPENDENT_EH_ABI 1
22 #ifndef _LIBCPPABI_VERSION
23 using namespace __cxxabiapple;
24 // On Darwin, there are two STL shared libraries and a lower level ABI
25 // shared libray. The globals holding the current terminate handler and
26 // current unexpected handler are in the ABI library.
27 #define __terminate_handler __cxxabiapple::__cxa_terminate_handler
28 #define __unexpected_handler __cxxabiapple::__cxa_unexpected_handler
29 #endif // _LIBCPPABI_VERSION
30 #elif defined(LIBCXXRT) || __has_include(<cxxabi.h>)
32 using namespace __cxxabiv1;
33 #if defined(LIBCXXRT) || defined(_LIBCPPABI_VERSION)
34 #define HAVE_DEPENDENT_EH_ABI 1
36 #elif !defined(__GLIBCXX__) // __has_include(<cxxabi.h>)
37 static std::terminate_handler __terminate_handler;
38 static std::unexpected_handler __unexpected_handler;
39 #endif // __has_include(<cxxabi.h>)
44 #if !defined(LIBCXXRT) && !defined(_LIBCPPABI_VERSION) && !defined(__GLIBCXX__)
46 // libcxxrt provides implementations of these functions itself.
48 set_unexpected(unexpected_handler func) _NOEXCEPT
50 return __sync_lock_test_and_set(&__unexpected_handler, func);
54 get_unexpected() _NOEXCEPT
56 return __sync_fetch_and_add(&__unexpected_handler, (unexpected_handler)0);
63 (*get_unexpected())();
64 // unexpected handler should not return
69 set_terminate(terminate_handler func) _NOEXCEPT
71 return __sync_lock_test_and_set(&__terminate_handler, func);
75 get_terminate() _NOEXCEPT
77 return __sync_fetch_and_add(&__terminate_handler, (terminate_handler)0);
80 #ifndef EMSCRIPTEN // We provide this in JS
85 #ifndef _LIBCPP_NO_EXCEPTIONS
88 #endif // _LIBCPP_NO_EXCEPTIONS
90 // handler should not return
92 #ifndef _LIBCPP_NO_EXCEPTIONS
96 // handler should not throw exception
99 #endif // _LIBCPP_NO_EXCEPTIONS
101 #endif // !EMSCRIPTEN
102 #endif // !defined(LIBCXXRT) && !defined(_LIBCPPABI_VERSION)
104 #if !defined(LIBCXXRT) && !defined(__GLIBCXX__) && !defined(EMSCRIPTEN)
105 bool uncaught_exception() _NOEXCEPT
107 #if defined(__APPLE__) || defined(_LIBCPPABI_VERSION)
108 // on Darwin, there is a helper function so __cxa_get_globals is private
109 return __cxa_uncaught_exception();
111 #warning uncaught_exception not yet implemented
116 #ifndef _LIBCPPABI_VERSION
118 exception::~exception() _NOEXCEPT
122 const char* exception::what() const _NOEXCEPT
124 return "std::exception";
127 #endif // _LIBCPPABI_VERSION
129 #if !defined(_LIBCPPABI_VERSION) && !defined(__GLIBCXX__)
131 bad_exception::~bad_exception() _NOEXCEPT
135 const char* bad_exception::what() const _NOEXCEPT
137 return "std::bad_exception";
143 exception_ptr::~exception_ptr() _NOEXCEPT
145 #if HAVE_DEPENDENT_EH_ABI
146 __cxa_decrement_exception_refcount(__ptr_);
148 #warning exception_ptr not yet implemented
153 exception_ptr::exception_ptr(const exception_ptr& other) _NOEXCEPT
154 : __ptr_(other.__ptr_)
156 #if HAVE_DEPENDENT_EH_ABI
157 __cxa_increment_exception_refcount(__ptr_);
159 #warning exception_ptr not yet implemented
164 exception_ptr& exception_ptr::operator=(const exception_ptr& other) _NOEXCEPT
166 #if HAVE_DEPENDENT_EH_ABI
167 if (__ptr_ != other.__ptr_)
169 __cxa_increment_exception_refcount(other.__ptr_);
170 __cxa_decrement_exception_refcount(__ptr_);
171 __ptr_ = other.__ptr_;
175 #warning exception_ptr not yet implemented
180 nested_exception::nested_exception() _NOEXCEPT
181 : __ptr_(current_exception())
185 nested_exception::~nested_exception() _NOEXCEPT
191 nested_exception::rethrow_nested() const
193 if (__ptr_ == nullptr)
195 rethrow_exception(__ptr_);
199 exception_ptr current_exception() _NOEXCEPT
201 #if HAVE_DEPENDENT_EH_ABI
202 // be nicer if there was a constructor that took a ptr, then
203 // this whole function would be just:
204 // return exception_ptr(__cxa_current_primary_exception());
206 ptr.__ptr_ = __cxa_current_primary_exception();
209 #warning exception_ptr not yet implemented
215 void rethrow_exception(exception_ptr p)
217 #if HAVE_DEPENDENT_EH_ABI
218 __cxa_rethrow_primary_exception(p.__ptr_);
219 // if p.__ptr_ is NULL, above returns so we terminate
222 #warning exception_ptr not yet implemented