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 //===----------------------------------------------------------------------===//
16 using namespace __cxxabiv1;
17 #define HAVE_DEPENDENT_EH_ABI 1
18 #ifndef _LIBCPPABI_VERSION
19 using namespace __cxxabiapple;
20 // On Darwin, there are two STL shared libraries and a lower level ABI
21 // shared libray. The globals holding the current terminate handler and
22 // current unexpected handler are in the ABI library.
23 #define __terminate_handler __cxxabiapple::__cxa_terminate_handler
24 #define __unexpected_handler __cxxabiapple::__cxa_unexpected_handler
25 #endif // _LIBCPPABI_VERSION
26 #elif defined(LIBCXXRT)
28 using namespace __cxxabiv1;
29 #define HAVE_DEPENDENT_EH_ABI 1
31 static std::terminate_handler __terminate_handler;
32 static std::unexpected_handler __unexpected_handler;
38 #if !defined(LIBCXXRT) && !defined(_LIBCPPABI_VERSION)
40 // libcxxrt provides implementations of these functions itself.
42 set_unexpected(unexpected_handler func) _NOEXCEPT
44 return __sync_lock_test_and_set(&__unexpected_handler, func);
48 get_unexpected() _NOEXCEPT
50 return __sync_fetch_and_add(&__unexpected_handler, (unexpected_handler)0);
57 (*get_unexpected())();
58 // unexpected handler should not return
63 set_terminate(terminate_handler func) _NOEXCEPT
65 return __sync_lock_test_and_set(&__terminate_handler, func);
69 get_terminate() _NOEXCEPT
71 return __sync_fetch_and_add(&__terminate_handler, (terminate_handler)0);
78 #ifndef _LIBCPP_NO_EXCEPTIONS
81 #endif // _LIBCPP_NO_EXCEPTIONS
83 // handler should not return
85 #ifndef _LIBCPP_NO_EXCEPTIONS
89 // handler should not throw exception
92 #endif // _LIBCPP_NO_EXCEPTIONS
94 #endif // !defined(LIBCXXRT) && !defined(_LIBCPPABI_VERSION)
97 bool uncaught_exception() _NOEXCEPT
100 // on Darwin, there is a helper function so __cxa_get_globals is private
101 return __cxa_uncaught_exception();
103 __cxa_eh_globals * globals = __cxa_get_globals();
104 return (globals->uncaughtExceptions != 0);
106 #warning uncaught_exception not yet implemented
111 #ifndef _LIBCPPABI_VERSION
113 exception::~exception() _NOEXCEPT
117 const char* exception::what() const _NOEXCEPT
119 return "std::exception";
122 #endif // _LIBCPPABI_VERSION
124 #ifndef _LIBCPPABI_VERSION
126 bad_exception::~bad_exception() _NOEXCEPT
130 const char* bad_exception::what() const _NOEXCEPT
132 return "std::bad_exception";
138 exception_ptr::~exception_ptr() _NOEXCEPT
140 #if HAVE_DEPENDENT_EH_ABI
141 __cxa_decrement_exception_refcount(__ptr_);
143 #warning exception_ptr not yet implemented
148 exception_ptr::exception_ptr(const exception_ptr& other) _NOEXCEPT
149 : __ptr_(other.__ptr_)
151 #if HAVE_DEPENDENT_EH_ABI
152 __cxa_increment_exception_refcount(__ptr_);
154 #warning exception_ptr not yet implemented
159 exception_ptr& exception_ptr::operator=(const exception_ptr& other) _NOEXCEPT
161 #if HAVE_DEPENDENT_EH_ABI
162 if (__ptr_ != other.__ptr_)
164 __cxa_increment_exception_refcount(other.__ptr_);
165 __cxa_decrement_exception_refcount(__ptr_);
166 __ptr_ = other.__ptr_;
170 #warning exception_ptr not yet implemented
175 nested_exception::nested_exception() _NOEXCEPT
176 : __ptr_(current_exception())
180 nested_exception::~nested_exception() _NOEXCEPT
186 nested_exception::rethrow_nested() const
188 if (__ptr_ == nullptr)
190 rethrow_exception(__ptr_);
194 exception_ptr current_exception() _NOEXCEPT
196 #if HAVE_DEPENDENT_EH_ABI
197 // be nicer if there was a constructor that took a ptr, then
198 // this whole function would be just:
199 // return exception_ptr(__cxa_current_primary_exception());
201 ptr.__ptr_ = __cxa_current_primary_exception();
204 #warning exception_ptr not yet implemented
210 void rethrow_exception(exception_ptr p)
212 #if HAVE_DEPENDENT_EH_ABI
213 __cxa_rethrow_primary_exception(p.__ptr_);
214 // if p.__ptr_ is NULL, above returns so we terminate
217 #warning exception_ptr not yet implemented