blob: e48e9c4901ec29d724081f84a68a60c24a2a3e0a [file] [log] [blame]
Nick Kledzik804b6e72010-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{
57 try {
58 (*__terminate_handler)();
59 // handler should not return
60 ::abort ();
61 }
62 catch (...) {
63 // handler should not throw exception
64 ::abort ();
65 }
66}
67
68
69bool std::uncaught_exception() throw()
70{
71#if __APPLE__
72 // on Darwin, there is a helper function so __cxa_get_globals is private
73 return __cxxabiapple::__cxa_uncaught_exception();
74#else
Howard Hinnantadff4892010-05-24 17:49:41 +000075 #warning uncaught_exception not yet implemented
76 ::abort();
77 // Not provided by Ubuntu gcc-4.2.4's cxxabi.h.
78 // __cxa_eh_globals * globals = __cxa_get_globals();
79 // return (globals->uncaughtExceptions != 0);
Nick Kledzik804b6e72010-05-14 20:19:37 +000080#endif
81}
82
83
84namespace std
85{
86
87
88exception::~exception() throw()
89{
90}
91
92bad_exception::~bad_exception() throw()
93{
94}
95
96const char* exception::what() const throw()
97{
98 return "std::exception";
99}
100
101const char* bad_exception::what() const throw()
102{
103 return "std::bad_exception";
104}
105
106
107
108exception_ptr::~exception_ptr()
109{
110#if __APPLE__
111 __cxxabiapple::__cxa_decrement_exception_refcount(__ptr_);
112#else
113 #warning exception_ptr not yet implemented
114 ::abort();
115#endif
116}
117
118exception_ptr::exception_ptr(const exception_ptr& other)
119 : __ptr_(other.__ptr_)
120{
121#if __APPLE__
122 __cxxabiapple::__cxa_increment_exception_refcount(__ptr_);
123#else
124 #warning exception_ptr not yet implemented
125 ::abort();
126#endif
127}
128
129exception_ptr& exception_ptr::operator=(const exception_ptr& other)
130{
131#if __APPLE__
132 if (__ptr_ != other.__ptr_)
133 {
134 __cxxabiapple::__cxa_increment_exception_refcount(other.__ptr_);
135 __cxxabiapple::__cxa_decrement_exception_refcount(__ptr_);
136 __ptr_ = other.__ptr_;
137 }
138 return *this;
139#else
140 #warning exception_ptr not yet implemented
141 ::abort();
142#endif
143}
144
145} // std
146
147
148std::exception_ptr std::current_exception()
149{
150#if __APPLE__
151 // be nicer if there was a constructor that took a ptr, then
152 // this whole function would be just:
153 // return exception_ptr(__cxa_current_primary_exception());
154 std::exception_ptr ptr;
155 ptr.__ptr_ = __cxxabiapple::__cxa_current_primary_exception();
156 return ptr;
157#else
158 #warning exception_ptr not yet implemented
159 ::abort();
160#endif
161}
162
163void std::rethrow_exception(exception_ptr p)
164{
165#if __APPLE__
166 __cxxabiapple::__cxa_rethrow_primary_exception(p.__ptr_);
167 // if p.__ptr_ is NULL, above returns so we terminate
168 terminate();
169#else
170 #warning exception_ptr not yet implemented
171 ::abort();
172#endif
173}