blob: 7c5211534b454ca33b30093fd9f4be42bc1fd33a [file] [log] [blame]
Nick Kledzikd1a61bb2010-05-14 20:19:37 +00001//===------------------------ exception.cpp -------------------------------===//
2//
3// The LLVM Compiler Infrastructure
4//
5// This file is distributed under the University of Illinois Open Source
6// License. See LICENSE.TXT for details.
7//
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
21#else
22 static std::terminate_handler __terminate_handler;
23 static std::unexpected_handler __unexpected_handler;
24#endif
25
26
27
28std::unexpected_handler
29std::set_unexpected(std::unexpected_handler func) throw()
30{
31 std::terminate_handler old = __unexpected_handler;
32 __unexpected_handler = func;
33 return old;
34}
35
36void
37std::unexpected()
38{
39 (*__unexpected_handler)();
40 // unexpected handler should not return
41 std::terminate();
42}
43
44
45std::terminate_handler
46std::set_terminate(std::terminate_handler func) throw()
47{
48 std::terminate_handler old = __terminate_handler;
49 __terminate_handler = func;
50 return old;
51}
52
53
54void
55std::terminate()
56{
Howard Hinnant72f73582010-08-11 17:04:31 +000057#ifndef _LIBCPP_NO_EXCEPTIONS
58 try
59 {
60#endif
Nick Kledzikd1a61bb2010-05-14 20:19:37 +000061 (*__terminate_handler)();
62 // handler should not return
63 ::abort ();
Howard Hinnant72f73582010-08-11 17:04:31 +000064#ifndef _LIBCPP_NO_EXCEPTIONS
Nick Kledzikd1a61bb2010-05-14 20:19:37 +000065 }
Howard Hinnant72f73582010-08-11 17:04:31 +000066 catch (...)
67 {
Nick Kledzikd1a61bb2010-05-14 20:19:37 +000068 // handler should not throw exception
69 ::abort ();
70 }
Howard Hinnant72f73582010-08-11 17:04:31 +000071#endif
Nick Kledzikd1a61bb2010-05-14 20:19:37 +000072}
73
74
75bool std::uncaught_exception() throw()
76{
77#if __APPLE__
78 // on Darwin, there is a helper function so __cxa_get_globals is private
79 return __cxxabiapple::__cxa_uncaught_exception();
80#else
Howard Hinnant155c2af2010-05-24 17:49:41 +000081 #warning uncaught_exception not yet implemented
82 ::abort();
83 // Not provided by Ubuntu gcc-4.2.4's cxxabi.h.
84 // __cxa_eh_globals * globals = __cxa_get_globals();
85 // return (globals->uncaughtExceptions != 0);
Nick Kledzikd1a61bb2010-05-14 20:19:37 +000086#endif
87}
88
89
90namespace std
91{
92
93
94exception::~exception() throw()
95{
96}
97
98bad_exception::~bad_exception() throw()
99{
100}
101
102const char* exception::what() const throw()
103{
104 return "std::exception";
105}
106
107const char* bad_exception::what() const throw()
108{
109 return "std::bad_exception";
110}
111
112
113
114exception_ptr::~exception_ptr()
115{
116#if __APPLE__
117 __cxxabiapple::__cxa_decrement_exception_refcount(__ptr_);
118#else
119 #warning exception_ptr not yet implemented
120 ::abort();
121#endif
122}
123
124exception_ptr::exception_ptr(const exception_ptr& other)
125 : __ptr_(other.__ptr_)
126{
127#if __APPLE__
128 __cxxabiapple::__cxa_increment_exception_refcount(__ptr_);
129#else
130 #warning exception_ptr not yet implemented
131 ::abort();
132#endif
133}
134
135exception_ptr& exception_ptr::operator=(const exception_ptr& other)
136{
137#if __APPLE__
138 if (__ptr_ != other.__ptr_)
139 {
140 __cxxabiapple::__cxa_increment_exception_refcount(other.__ptr_);
141 __cxxabiapple::__cxa_decrement_exception_refcount(__ptr_);
142 __ptr_ = other.__ptr_;
143 }
144 return *this;
145#else
146 #warning exception_ptr not yet implemented
147 ::abort();
148#endif
149}
150
Howard Hinnante4f92722010-05-27 17:06:52 +0000151nested_exception::nested_exception()
152 : __ptr_(current_exception())
153{
154}
155
156nested_exception::~nested_exception()
157{
158}
159
160void
161nested_exception::rethrow_nested /*[[noreturn]]*/ () const
162{
163 if (__ptr_ == nullptr)
164 terminate();
165 rethrow_exception(__ptr_);
166}
167
Nick Kledzikd1a61bb2010-05-14 20:19:37 +0000168} // std
169
170
171std::exception_ptr std::current_exception()
172{
173#if __APPLE__
174 // be nicer if there was a constructor that took a ptr, then
175 // this whole function would be just:
176 // return exception_ptr(__cxa_current_primary_exception());
177 std::exception_ptr ptr;
178 ptr.__ptr_ = __cxxabiapple::__cxa_current_primary_exception();
179 return ptr;
180#else
181 #warning exception_ptr not yet implemented
182 ::abort();
183#endif
184}
185
186void std::rethrow_exception(exception_ptr p)
187{
188#if __APPLE__
189 __cxxabiapple::__cxa_rethrow_primary_exception(p.__ptr_);
190 // if p.__ptr_ is NULL, above returns so we terminate
191 terminate();
192#else
193 #warning exception_ptr not yet implemented
194 ::abort();
195#endif
196}