1 //===------------------------ 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 // __APPLE__ 22 static std::terminate_handler __terminate_handler; 23 static std::unexpected_handler __unexpected_handler; 24 #endif // __APPLE__ 25 26 std::unexpected_handler 27 std::set_unexpected(std::unexpected_handler func) throw() 28 { 29 std::terminate_handler old = __unexpected_handler; 30 __unexpected_handler = func; 31 return old; 32 } 33 34 void 35 std::unexpected() 36 { 37 (*__unexpected_handler)(); 38 // unexpected handler should not return 39 std::terminate(); 40 } 41 42 std::terminate_handler 43 std::set_terminate(std::terminate_handler func) throw() 44 { 45 std::terminate_handler old = __terminate_handler; 46 __terminate_handler = func; 47 return old; 48 } 49 50 void 51 std::terminate() 52 { 53 #ifndef _LIBCPP_NO_EXCEPTIONS 54 try 55 { 56 #endif // _LIBCPP_NO_EXCEPTIONS 57 (*__terminate_handler)(); 58 // handler should not return 59 ::abort (); 60 #ifndef _LIBCPP_NO_EXCEPTIONS 61 } 62 catch (...) 63 { 64 // handler should not throw exception 65 ::abort (); 66 } 67 #endif // _LIBCPP_NO_EXCEPTIONS 68 } 69 70 bool std::uncaught_exception() throw() 71 { 72 #if __APPLE__ 73 // on Darwin, there is a helper function so __cxa_get_globals is private 74 return __cxxabiapple::__cxa_uncaught_exception(); 75 #else // __APPLE__ 76 #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); 81 #endif // __APPLE__ 82 } 83 84 namespace std 85 { 86 87 exception::~exception() throw() 88 { 89 } 90 91 bad_exception::~bad_exception() throw() 92 { 93 } 94 95 const char* exception::what() const throw() 96 { 97 return "std::exception"; 98 } 99 100 const char* bad_exception::what() const throw() 101 { 102 return "std::bad_exception"; 103 } 104 105 exception_ptr::~exception_ptr() 106 { 107 #if __APPLE__ 108 __cxxabiapple::__cxa_decrement_exception_refcount(__ptr_); 109 #else 110 #warning exception_ptr not yet implemented 111 ::abort(); 112 #endif // __APPLE__ 113 } 114 115 exception_ptr::exception_ptr(const exception_ptr& other) 116 : __ptr_(other.__ptr_) 117 { 118 #if __APPLE__ 119 __cxxabiapple::__cxa_increment_exception_refcount(__ptr_); 120 #else 121 #warning exception_ptr not yet implemented 122 ::abort(); 123 #endif // __APPLE__ 124 } 125 126 exception_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_); 133 __ptr_ = other.__ptr_; 134 } 135 return *this; 136 #else // __APPLE__ 137 #warning exception_ptr not yet implemented 138 ::abort(); 139 #endif // __APPLE__ 140 } 141 142 nested_exception::nested_exception() 143 : __ptr_(current_exception()) 144 { 145 } 146 147 nested_exception::~nested_exception() 148 { 149 } 150 151 void 152 nested_exception::rethrow_nested /*[[noreturn]]*/ () const 153 { 154 if (__ptr_ == nullptr) 155 terminate(); 156 rethrow_exception(__ptr_); 157 } 158 159 } // std 160 161 std::exception_ptr std::current_exception() 162 { 163 #if __APPLE__ 164 // 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()); 167 std::exception_ptr ptr; 168 ptr.__ptr_ = __cxxabiapple::__cxa_current_primary_exception(); 169 return ptr; 170 #else // __APPLE__ 171 #warning exception_ptr not yet implemented 172 ::abort(); 173 #endif // __APPLE__ 174 } 175 176 void std::rethrow_exception(exception_ptr p) 177 { 178 #if __APPLE__ 179 __cxxabiapple::__cxa_rethrow_primary_exception(p.__ptr_); 180 // if p.__ptr_ is NULL, above returns so we terminate 181 terminate(); 182 #else // __APPLE__ 183 #warning exception_ptr not yet implemented 184 ::abort(); 185 #endif // __APPLE__ 186 } 187