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 //===----------------------------------------------------------------------===//
15 using namespace __cxxabiv1;
16 using namespace __cxxabiapple;
17 // On Darwin, there are two STL shared libraries and a lower level ABI
18 // shared libray. The globals holding the current terminate handler and
19 // current unexpected handler are in the ABI library.
20 #define __terminate_handler __cxxabiapple::__cxa_terminate_handler
21 #define __unexpected_handler __cxxabiapple::__cxa_unexpected_handler
22 #define HAVE_DEPENDENT_EH_ABI 1
23 #elif defined(LIBCXXRT)
25 using namespace __cxxabiv1;
26 #define HAVE_DEPENDENT_EH_ABI 1
28 static std::terminate_handler __terminate_handler;
29 static std::unexpected_handler __unexpected_handler;
33 // libcxxrt provides implementations of these functions itself.
34 std::unexpected_handler
35 std::set_unexpected(std::unexpected_handler func) _NOEXCEPT
37 return __sync_lock_test_and_set(&__unexpected_handler, func);
40 std::unexpected_handler
41 std::get_unexpected() _NOEXCEPT
43 return __sync_fetch_and_add(&__unexpected_handler, (std::unexpected_handler)0);
50 (*std::get_unexpected())();
51 // unexpected handler should not return
55 std::terminate_handler
56 std::set_terminate(std::terminate_handler func) _NOEXCEPT
58 return __sync_lock_test_and_set(&__terminate_handler, func);
61 std::terminate_handler
62 std::get_terminate() _NOEXCEPT
64 return __sync_fetch_and_add(&__terminate_handler, (std::terminate_handler)0);
69 std::terminate() _NOEXCEPT
71 #ifndef _LIBCPP_NO_EXCEPTIONS
74 #endif // _LIBCPP_NO_EXCEPTIONS
75 (*std::get_terminate())();
76 // handler should not return
78 #ifndef _LIBCPP_NO_EXCEPTIONS
82 // handler should not throw exception
85 #endif // _LIBCPP_NO_EXCEPTIONS
89 bool std::uncaught_exception() _NOEXCEPT
92 // on Darwin, there is a helper function so __cxa_get_globals is private
93 return __cxxabiapple::__cxa_uncaught_exception();
95 __cxa_eh_globals * globals = __cxa_get_globals();
96 return (globals->uncaughtExceptions != 0);
98 #warning uncaught_exception not yet implemented
106 exception::~exception() _NOEXCEPT
110 bad_exception::~bad_exception() _NOEXCEPT
114 const char* exception::what() const _NOEXCEPT
116 return "std::exception";
119 const char* bad_exception::what() const _NOEXCEPT
121 return "std::bad_exception";
124 exception_ptr::~exception_ptr() _NOEXCEPT
126 #if HAVE_DEPENDENT_EH_ABI
127 __cxa_decrement_exception_refcount(__ptr_);
129 #warning exception_ptr not yet implemented
134 exception_ptr::exception_ptr(const exception_ptr& other) _NOEXCEPT
135 : __ptr_(other.__ptr_)
137 #if HAVE_DEPENDENT_EH_ABI
138 __cxa_increment_exception_refcount(__ptr_);
140 #warning exception_ptr not yet implemented
145 exception_ptr& exception_ptr::operator=(const exception_ptr& other) _NOEXCEPT
147 #if HAVE_DEPENDENT_EH_ABI
148 if (__ptr_ != other.__ptr_)
150 __cxa_increment_exception_refcount(other.__ptr_);
151 __cxa_decrement_exception_refcount(__ptr_);
152 __ptr_ = other.__ptr_;
156 #warning exception_ptr not yet implemented
161 nested_exception::nested_exception() _NOEXCEPT
162 : __ptr_(current_exception())
166 nested_exception::~nested_exception() _NOEXCEPT
172 nested_exception::rethrow_nested() const
174 if (__ptr_ == nullptr)
176 rethrow_exception(__ptr_);
181 std::exception_ptr std::current_exception() _NOEXCEPT
183 #if HAVE_DEPENDENT_EH_ABI
184 // be nicer if there was a constructor that took a ptr, then
185 // this whole function would be just:
186 // return exception_ptr(__cxa_current_primary_exception());
187 std::exception_ptr ptr;
188 ptr.__ptr_ = __cxa_current_primary_exception();
191 #warning exception_ptr not yet implemented
196 void std::rethrow_exception(exception_ptr p)
198 #if HAVE_DEPENDENT_EH_ABI
199 __cxa_rethrow_primary_exception(p.__ptr_);
200 // if p.__ptr_ is NULL, above returns so we terminate
203 #warning exception_ptr not yet implemented