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 22 static std::terminate_handler __terminate_handler; 23 static std::unexpected_handler __unexpected_handler; 24 #endif 25 26 27 28 std::unexpected_handler 29 std::set_unexpected(std::unexpected_handler func) throw() 30 { 31 std::terminate_handler old = __unexpected_handler; 32 __unexpected_handler = func; 33 return old; 34 } 35 36 void 37 std::unexpected() 38 { 39 (*__unexpected_handler)(); 40 // unexpected handler should not return 41 std::terminate(); 42 } 43 44 45 std::terminate_handler 46 std::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 54 void 55 std::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 69 bool 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 75 #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); 80 #endif 81 } 82 83 84 namespace std 85 { 86 87 88 exception::~exception() throw() 89 { 90 } 91 92 bad_exception::~bad_exception() throw() 93 { 94 } 95 96 const char* exception::what() const throw() 97 { 98 return "std::exception"; 99 } 100 101 const char* bad_exception::what() const throw() 102 { 103 return "std::bad_exception"; 104 } 105 106 107 108 exception_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 118 exception_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 129 exception_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 nested_exception::nested_exception() 146 : __ptr_(current_exception()) 147 { 148 } 149 150 nested_exception::~nested_exception() 151 { 152 } 153 154 void 155 nested_exception::rethrow_nested /*[[noreturn]]*/ () const 156 { 157 if (__ptr_ == nullptr) 158 terminate(); 159 rethrow_exception(__ptr_); 160 } 161 162 } // std 163 164 165 std::exception_ptr std::current_exception() 166 { 167 #if __APPLE__ 168 // be nicer if there was a constructor that took a ptr, then 169 // this whole function would be just: 170 // return exception_ptr(__cxa_current_primary_exception()); 171 std::exception_ptr ptr; 172 ptr.__ptr_ = __cxxabiapple::__cxa_current_primary_exception(); 173 return ptr; 174 #else 175 #warning exception_ptr not yet implemented 176 ::abort(); 177 #endif 178 } 179 180 void std::rethrow_exception(exception_ptr p) 181 { 182 #if __APPLE__ 183 __cxxabiapple::__cxa_rethrow_primary_exception(p.__ptr_); 184 // if p.__ptr_ is NULL, above returns so we terminate 185 terminate(); 186 #else 187 #warning exception_ptr not yet implemented 188 ::abort(); 189 #endif 190 } 191