blob: 1ab5a19520c1e79c1bd70f62c5e225b4ab4f9b46 [file] [log] [blame]
Nick Kledzikd1a61bb2010-05-14 20:19:37 +00001//===------------------------ exception.cpp -------------------------------===//
2//
3// The LLVM Compiler Infrastructure
4//
Howard Hinnantee11c312010-11-16 22:09:02 +00005// This file is dual licensed under the MIT and the University of Illinois Open
6// Source Licenses. See LICENSE.TXT for details.
Nick Kledzikd1a61bb2010-05-14 20:19:37 +00007//
8//===----------------------------------------------------------------------===//
9#include <stdlib.h>
10
11#include "exception"
12
13#if __APPLE__
14 #include <cxxabi.h>
15 using namespace __cxxabiv1;
16 // On Darwin, there are two STL shared libraries and a lower level ABI
17 // shared libray. The globals holding the current terminate handler and
18 // current unexpected handler are in the ABI library.
19 #define __terminate_handler __cxxabiapple::__cxa_terminate_handler
20 #define __unexpected_handler __cxxabiapple::__cxa_unexpected_handler
Howard Hinnantffb308e2010-08-22 00:03:27 +000021#else // __APPLE__
Nick Kledzikd1a61bb2010-05-14 20:19:37 +000022 static std::terminate_handler __terminate_handler;
23 static std::unexpected_handler __unexpected_handler;
Howard Hinnantffb308e2010-08-22 00:03:27 +000024#endif // __APPLE__
Nick Kledzikd1a61bb2010-05-14 20:19:37 +000025
Howard Hinnantffb308e2010-08-22 00:03:27 +000026std::unexpected_handler
Nick Kledzikd1a61bb2010-05-14 20:19:37 +000027std::set_unexpected(std::unexpected_handler func) throw()
28{
29 std::terminate_handler old = __unexpected_handler;
30 __unexpected_handler = func;
31 return old;
32}
33
34void
35std::unexpected()
36{
37 (*__unexpected_handler)();
Howard Hinnant34468d42010-08-22 13:53:14 +000038 // unexpected handler should not return
Nick Kledzikd1a61bb2010-05-14 20:19:37 +000039 std::terminate();
40}
41
Howard Hinnantffb308e2010-08-22 00:03:27 +000042std::terminate_handler
Nick Kledzikd1a61bb2010-05-14 20:19:37 +000043std::set_terminate(std::terminate_handler func) throw()
44{
45 std::terminate_handler old = __terminate_handler;
46 __terminate_handler = func;
47 return old;
48}
49
Nick Kledzikd1a61bb2010-05-14 20:19:37 +000050void
51std::terminate()
52{
Howard Hinnant72f73582010-08-11 17:04:31 +000053#ifndef _LIBCPP_NO_EXCEPTIONS
54 try
55 {
Howard Hinnantffb308e2010-08-22 00:03:27 +000056#endif // _LIBCPP_NO_EXCEPTIONS
Nick Kledzikd1a61bb2010-05-14 20:19:37 +000057 (*__terminate_handler)();
58 // handler should not return
59 ::abort ();
Howard Hinnant72f73582010-08-11 17:04:31 +000060#ifndef _LIBCPP_NO_EXCEPTIONS
Howard Hinnantffb308e2010-08-22 00:03:27 +000061 }
Howard Hinnant72f73582010-08-11 17:04:31 +000062 catch (...)
63 {
Nick Kledzikd1a61bb2010-05-14 20:19:37 +000064 // handler should not throw exception
65 ::abort ();
66 }
Howard Hinnantffb308e2010-08-22 00:03:27 +000067#endif // _LIBCPP_NO_EXCEPTIONS
Nick Kledzikd1a61bb2010-05-14 20:19:37 +000068}
69
Nick Kledzikd1a61bb2010-05-14 20:19:37 +000070bool std::uncaught_exception() throw()
71{
72#if __APPLE__
Howard Hinnant34468d42010-08-22 13:53:14 +000073 // on Darwin, there is a helper function so __cxa_get_globals is private
Nick Kledzikd1a61bb2010-05-14 20:19:37 +000074 return __cxxabiapple::__cxa_uncaught_exception();
Howard Hinnantffb308e2010-08-22 00:03:27 +000075#else // __APPLE__
Howard Hinnant155c2af2010-05-24 17:49:41 +000076 #warning uncaught_exception not yet implemented
77 ::abort();
78 // Not provided by Ubuntu gcc-4.2.4's cxxabi.h.
79 // __cxa_eh_globals * globals = __cxa_get_globals();
80 // return (globals->uncaughtExceptions != 0);
Howard Hinnantffb308e2010-08-22 00:03:27 +000081#endif // __APPLE__
Nick Kledzikd1a61bb2010-05-14 20:19:37 +000082}
83
Howard Hinnantffb308e2010-08-22 00:03:27 +000084namespace std
Nick Kledzikd1a61bb2010-05-14 20:19:37 +000085{
86
Howard Hinnantffb308e2010-08-22 00:03:27 +000087exception::~exception() throw()
88{
Nick Kledzikd1a61bb2010-05-14 20:19:37 +000089}
90
Howard Hinnantffb308e2010-08-22 00:03:27 +000091bad_exception::~bad_exception() throw()
92{
Nick Kledzikd1a61bb2010-05-14 20:19:37 +000093}
94
95const char* exception::what() const throw()
96{
97 return "std::exception";
98}
99
100const char* bad_exception::what() const throw()
101{
102 return "std::bad_exception";
103}
104
Nick Kledzikd1a61bb2010-05-14 20:19:37 +0000105exception_ptr::~exception_ptr()
106{
107#if __APPLE__
108 __cxxabiapple::__cxa_decrement_exception_refcount(__ptr_);
109#else
Howard Hinnant34468d42010-08-22 13:53:14 +0000110 #warning exception_ptr not yet implemented
111 ::abort();
Howard Hinnantffb308e2010-08-22 00:03:27 +0000112#endif // __APPLE__
Nick Kledzikd1a61bb2010-05-14 20:19:37 +0000113}
114
115exception_ptr::exception_ptr(const exception_ptr& other)
116 : __ptr_(other.__ptr_)
117{
118#if __APPLE__
119 __cxxabiapple::__cxa_increment_exception_refcount(__ptr_);
120#else
Howard Hinnant34468d42010-08-22 13:53:14 +0000121 #warning exception_ptr not yet implemented
122 ::abort();
Howard Hinnantffb308e2010-08-22 00:03:27 +0000123#endif // __APPLE__
Nick Kledzikd1a61bb2010-05-14 20:19:37 +0000124}
125
126exception_ptr& exception_ptr::operator=(const exception_ptr& other)
127{
128#if __APPLE__
129 if (__ptr_ != other.__ptr_)
130 {
131 __cxxabiapple::__cxa_increment_exception_refcount(other.__ptr_);
132 __cxxabiapple::__cxa_decrement_exception_refcount(__ptr_);
Howard Hinnant34468d42010-08-22 13:53:14 +0000133 __ptr_ = other.__ptr_;
134 }
Nick Kledzikd1a61bb2010-05-14 20:19:37 +0000135 return *this;
Howard Hinnantffb308e2010-08-22 00:03:27 +0000136#else // __APPLE__
Howard Hinnant34468d42010-08-22 13:53:14 +0000137 #warning exception_ptr not yet implemented
138 ::abort();
Howard Hinnantffb308e2010-08-22 00:03:27 +0000139#endif // __APPLE__
Nick Kledzikd1a61bb2010-05-14 20:19:37 +0000140}
141
Howard Hinnante4f92722010-05-27 17:06:52 +0000142nested_exception::nested_exception()
143 : __ptr_(current_exception())
144{
145}
146
147nested_exception::~nested_exception()
148{
149}
150
151void
152nested_exception::rethrow_nested /*[[noreturn]]*/ () const
153{
154 if (__ptr_ == nullptr)
155 terminate();
156 rethrow_exception(__ptr_);
157}
158
Nick Kledzikd1a61bb2010-05-14 20:19:37 +0000159} // std
160
Nick Kledzikd1a61bb2010-05-14 20:19:37 +0000161std::exception_ptr std::current_exception()
162{
163#if __APPLE__
Howard Hinnant34468d42010-08-22 13:53:14 +0000164 // be nicer if there was a constructor that took a ptr, then
165 // this whole function would be just:
166 // return exception_ptr(__cxa_current_primary_exception());
Nick Kledzikd1a61bb2010-05-14 20:19:37 +0000167 std::exception_ptr ptr;
Howard Hinnant34468d42010-08-22 13:53:14 +0000168 ptr.__ptr_ = __cxxabiapple::__cxa_current_primary_exception();
169 return ptr;
Howard Hinnantffb308e2010-08-22 00:03:27 +0000170#else // __APPLE__
Howard Hinnant34468d42010-08-22 13:53:14 +0000171 #warning exception_ptr not yet implemented
172 ::abort();
Howard Hinnantffb308e2010-08-22 00:03:27 +0000173#endif // __APPLE__
Nick Kledzikd1a61bb2010-05-14 20:19:37 +0000174}
175
176void std::rethrow_exception(exception_ptr p)
177{
178#if __APPLE__
Howard Hinnant34468d42010-08-22 13:53:14 +0000179 __cxxabiapple::__cxa_rethrow_primary_exception(p.__ptr_);
180 // if p.__ptr_ is NULL, above returns so we terminate
Howard Hinnantffb308e2010-08-22 00:03:27 +0000181 terminate();
182#else // __APPLE__
Howard Hinnant34468d42010-08-22 13:53:14 +0000183 #warning exception_ptr not yet implemented
184 ::abort();
Howard Hinnantffb308e2010-08-22 00:03:27 +0000185#endif // __APPLE__
Nick Kledzikd1a61bb2010-05-14 20:19:37 +0000186}