blob: 28d87b34050940d3068a41faa099274baee48200 [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
Howard Hinnant1bc52cf2011-05-26 18:23:59 +000027std::set_unexpected(std::unexpected_handler func) _NOEXCEPT
Nick Kledzikd1a61bb2010-05-14 20:19:37 +000028{
Howard Hinnante65e8e32010-12-02 16:45:21 +000029 return __sync_lock_test_and_set(&__unexpected_handler, func);
30}
31
32std::unexpected_handler
Howard Hinnant1bc52cf2011-05-26 18:23:59 +000033std::get_unexpected() _NOEXCEPT
Howard Hinnante65e8e32010-12-02 16:45:21 +000034{
35 return __sync_fetch_and_add(&__unexpected_handler, (std::unexpected_handler)0);
Nick Kledzikd1a61bb2010-05-14 20:19:37 +000036}
37
Howard Hinnant8df96292011-05-26 17:07:32 +000038_ATTRIBUTE(noreturn)
Nick Kledzikd1a61bb2010-05-14 20:19:37 +000039void
40std::unexpected()
41{
Howard Hinnante60478c2010-12-06 15:11:48 +000042 (*std::get_unexpected())();
Howard Hinnant34468d42010-08-22 13:53:14 +000043 // unexpected handler should not return
Nick Kledzikd1a61bb2010-05-14 20:19:37 +000044 std::terminate();
45}
46
Howard Hinnantffb308e2010-08-22 00:03:27 +000047std::terminate_handler
Howard Hinnant1bc52cf2011-05-26 18:23:59 +000048std::set_terminate(std::terminate_handler func) _NOEXCEPT
Nick Kledzikd1a61bb2010-05-14 20:19:37 +000049{
Howard Hinnante65e8e32010-12-02 16:45:21 +000050 return __sync_lock_test_and_set(&__terminate_handler, func);
51}
52
53std::terminate_handler
Howard Hinnant1bc52cf2011-05-26 18:23:59 +000054std::get_terminate() _NOEXCEPT
Howard Hinnante65e8e32010-12-02 16:45:21 +000055{
56 return __sync_fetch_and_add(&__terminate_handler, (std::terminate_handler)0);
Nick Kledzikd1a61bb2010-05-14 20:19:37 +000057}
58
Howard Hinnant986832c2011-07-29 21:35:53 +000059_ATTRIBUTE(noreturn)
Nick Kledzikd1a61bb2010-05-14 20:19:37 +000060void
Howard Hinnant8df96292011-05-26 17:07:32 +000061std::terminate() _NOEXCEPT
Nick Kledzikd1a61bb2010-05-14 20:19:37 +000062{
Howard Hinnant72f73582010-08-11 17:04:31 +000063#ifndef _LIBCPP_NO_EXCEPTIONS
64 try
65 {
Howard Hinnantffb308e2010-08-22 00:03:27 +000066#endif // _LIBCPP_NO_EXCEPTIONS
Howard Hinnante60478c2010-12-06 15:11:48 +000067 (*std::get_terminate())();
Nick Kledzikd1a61bb2010-05-14 20:19:37 +000068 // handler should not return
69 ::abort ();
Howard Hinnant72f73582010-08-11 17:04:31 +000070#ifndef _LIBCPP_NO_EXCEPTIONS
Howard Hinnantffb308e2010-08-22 00:03:27 +000071 }
Howard Hinnant72f73582010-08-11 17:04:31 +000072 catch (...)
73 {
Nick Kledzikd1a61bb2010-05-14 20:19:37 +000074 // handler should not throw exception
75 ::abort ();
76 }
Howard Hinnantffb308e2010-08-22 00:03:27 +000077#endif // _LIBCPP_NO_EXCEPTIONS
Nick Kledzikd1a61bb2010-05-14 20:19:37 +000078}
79
Howard Hinnant1bc52cf2011-05-26 18:23:59 +000080bool std::uncaught_exception() _NOEXCEPT
Nick Kledzikd1a61bb2010-05-14 20:19:37 +000081{
82#if __APPLE__
Howard Hinnant34468d42010-08-22 13:53:14 +000083 // on Darwin, there is a helper function so __cxa_get_globals is private
Nick Kledzikd1a61bb2010-05-14 20:19:37 +000084 return __cxxabiapple::__cxa_uncaught_exception();
Howard Hinnantffb308e2010-08-22 00:03:27 +000085#else // __APPLE__
Howard Hinnant155c2af2010-05-24 17:49:41 +000086 #warning uncaught_exception not yet implemented
87 ::abort();
88 // Not provided by Ubuntu gcc-4.2.4's cxxabi.h.
89 // __cxa_eh_globals * globals = __cxa_get_globals();
90 // return (globals->uncaughtExceptions != 0);
Howard Hinnantffb308e2010-08-22 00:03:27 +000091#endif // __APPLE__
Nick Kledzikd1a61bb2010-05-14 20:19:37 +000092}
93
Howard Hinnantffb308e2010-08-22 00:03:27 +000094namespace std
Nick Kledzikd1a61bb2010-05-14 20:19:37 +000095{
96
Howard Hinnant1bc52cf2011-05-26 18:23:59 +000097exception::~exception() _NOEXCEPT
Howard Hinnantffb308e2010-08-22 00:03:27 +000098{
Nick Kledzikd1a61bb2010-05-14 20:19:37 +000099}
100
Howard Hinnant1bc52cf2011-05-26 18:23:59 +0000101bad_exception::~bad_exception() _NOEXCEPT
Howard Hinnantffb308e2010-08-22 00:03:27 +0000102{
Nick Kledzikd1a61bb2010-05-14 20:19:37 +0000103}
104
Howard Hinnant1bc52cf2011-05-26 18:23:59 +0000105const char* exception::what() const _NOEXCEPT
Nick Kledzikd1a61bb2010-05-14 20:19:37 +0000106{
107 return "std::exception";
108}
109
Howard Hinnant1bc52cf2011-05-26 18:23:59 +0000110const char* bad_exception::what() const _NOEXCEPT
Nick Kledzikd1a61bb2010-05-14 20:19:37 +0000111{
112 return "std::bad_exception";
113}
114
Howard Hinnant1bc52cf2011-05-26 18:23:59 +0000115exception_ptr::~exception_ptr() _NOEXCEPT
Nick Kledzikd1a61bb2010-05-14 20:19:37 +0000116{
117#if __APPLE__
118 __cxxabiapple::__cxa_decrement_exception_refcount(__ptr_);
119#else
Howard Hinnant34468d42010-08-22 13:53:14 +0000120 #warning exception_ptr not yet implemented
121 ::abort();
Howard Hinnantffb308e2010-08-22 00:03:27 +0000122#endif // __APPLE__
Nick Kledzikd1a61bb2010-05-14 20:19:37 +0000123}
124
Howard Hinnant1bc52cf2011-05-26 18:23:59 +0000125exception_ptr::exception_ptr(const exception_ptr& other) _NOEXCEPT
Nick Kledzikd1a61bb2010-05-14 20:19:37 +0000126 : __ptr_(other.__ptr_)
127{
128#if __APPLE__
129 __cxxabiapple::__cxa_increment_exception_refcount(__ptr_);
130#else
Howard Hinnant34468d42010-08-22 13:53:14 +0000131 #warning exception_ptr not yet implemented
132 ::abort();
Howard Hinnantffb308e2010-08-22 00:03:27 +0000133#endif // __APPLE__
Nick Kledzikd1a61bb2010-05-14 20:19:37 +0000134}
135
Howard Hinnant1bc52cf2011-05-26 18:23:59 +0000136exception_ptr& exception_ptr::operator=(const exception_ptr& other) _NOEXCEPT
Nick Kledzikd1a61bb2010-05-14 20:19:37 +0000137{
138#if __APPLE__
139 if (__ptr_ != other.__ptr_)
140 {
141 __cxxabiapple::__cxa_increment_exception_refcount(other.__ptr_);
142 __cxxabiapple::__cxa_decrement_exception_refcount(__ptr_);
Howard Hinnant34468d42010-08-22 13:53:14 +0000143 __ptr_ = other.__ptr_;
144 }
Nick Kledzikd1a61bb2010-05-14 20:19:37 +0000145 return *this;
Howard Hinnantffb308e2010-08-22 00:03:27 +0000146#else // __APPLE__
Howard Hinnant34468d42010-08-22 13:53:14 +0000147 #warning exception_ptr not yet implemented
148 ::abort();
Howard Hinnantffb308e2010-08-22 00:03:27 +0000149#endif // __APPLE__
Nick Kledzikd1a61bb2010-05-14 20:19:37 +0000150}
151
Howard Hinnant1bc52cf2011-05-26 18:23:59 +0000152nested_exception::nested_exception() _NOEXCEPT
Howard Hinnante4f92722010-05-27 17:06:52 +0000153 : __ptr_(current_exception())
154{
155}
156
Howard Hinnant1bc52cf2011-05-26 18:23:59 +0000157nested_exception::~nested_exception() _NOEXCEPT
Howard Hinnante4f92722010-05-27 17:06:52 +0000158{
159}
160
Howard Hinnant8df96292011-05-26 17:07:32 +0000161_ATTRIBUTE(noreturn)
Howard Hinnante4f92722010-05-27 17:06:52 +0000162void
Howard Hinnant8df96292011-05-26 17:07:32 +0000163nested_exception::rethrow_nested() const
Howard Hinnante4f92722010-05-27 17:06:52 +0000164{
165 if (__ptr_ == nullptr)
166 terminate();
167 rethrow_exception(__ptr_);
168}
169
Nick Kledzikd1a61bb2010-05-14 20:19:37 +0000170} // std
171
Howard Hinnant1bc52cf2011-05-26 18:23:59 +0000172std::exception_ptr std::current_exception() _NOEXCEPT
Nick Kledzikd1a61bb2010-05-14 20:19:37 +0000173{
174#if __APPLE__
Howard Hinnant34468d42010-08-22 13:53:14 +0000175 // be nicer if there was a constructor that took a ptr, then
176 // this whole function would be just:
177 // return exception_ptr(__cxa_current_primary_exception());
Nick Kledzikd1a61bb2010-05-14 20:19:37 +0000178 std::exception_ptr ptr;
Howard Hinnant34468d42010-08-22 13:53:14 +0000179 ptr.__ptr_ = __cxxabiapple::__cxa_current_primary_exception();
180 return ptr;
Howard Hinnantffb308e2010-08-22 00:03:27 +0000181#else // __APPLE__
Howard Hinnant34468d42010-08-22 13:53:14 +0000182 #warning exception_ptr not yet implemented
183 ::abort();
Howard Hinnantffb308e2010-08-22 00:03:27 +0000184#endif // __APPLE__
Nick Kledzikd1a61bb2010-05-14 20:19:37 +0000185}
186
187void std::rethrow_exception(exception_ptr p)
188{
189#if __APPLE__
Howard Hinnant34468d42010-08-22 13:53:14 +0000190 __cxxabiapple::__cxa_rethrow_primary_exception(p.__ptr_);
191 // if p.__ptr_ is NULL, above returns so we terminate
Howard Hinnantffb308e2010-08-22 00:03:27 +0000192 terminate();
193#else // __APPLE__
Howard Hinnant34468d42010-08-22 13:53:14 +0000194 #warning exception_ptr not yet implemented
195 ::abort();
Howard Hinnantffb308e2010-08-22 00:03:27 +0000196#endif // __APPLE__
Nick Kledzikd1a61bb2010-05-14 20:19:37 +0000197}