diff options
Diffstat (limited to 'system/lib/libcxx/exception.cpp')
-rw-r--r-- | system/lib/libcxx/exception.cpp | 104 |
1 files changed, 88 insertions, 16 deletions
diff --git a/system/lib/libcxx/exception.cpp b/system/lib/libcxx/exception.cpp index 3487bd8b..83f6fd19 100644 --- a/system/lib/libcxx/exception.cpp +++ b/system/lib/libcxx/exception.cpp @@ -10,6 +10,7 @@ #include <stdio.h> #include "exception" +#include "new" #ifndef __has_include #define __has_include(inc) 0 @@ -90,14 +91,14 @@ terminate() _NOEXCEPT (*get_terminate())(); // handler should not return printf("terminate_handler unexpectedly returned\n"); - ::abort (); + ::abort(); #ifndef _LIBCPP_NO_EXCEPTIONS } catch (...) { // handler should not throw exception printf("terminate_handler unexpectedly threw an exception\n"); - ::abort (); + ::abort(); } #endif // _LIBCPP_NO_EXCEPTIONS } @@ -111,12 +112,17 @@ bool uncaught_exception() _NOEXCEPT // on Darwin, there is a helper function so __cxa_get_globals is private return __cxa_uncaught_exception(); #else // __APPLE__ - #warning uncaught_exception not yet implemented +# if defined(_MSC_VER) && ! defined(__clang__) + _LIBCPP_WARNING("uncaught_exception not yet implemented") +# else +# warning uncaught_exception not yet implemented +# endif printf("uncaught_exception not yet implemented\n"); ::abort(); #endif // __APPLE__ } + #ifndef _LIBCPPABI_VERSION exception::~exception() _NOEXCEPT @@ -143,16 +149,50 @@ const char* bad_exception::what() const _NOEXCEPT #endif +#if defined(__GLIBCXX__) + +// libsupc++ does not implement the dependent EH ABI and the functionality +// it uses to implement std::exception_ptr (which it declares as an alias of +// std::__exception_ptr::exception_ptr) is not directly exported to clients. So +// we have little choice but to hijack std::__exception_ptr::exception_ptr's +// (which fortunately has the same layout as our std::exception_ptr) copy +// constructor, assignment operator and destructor (which are part of its +// stable ABI), and its rethrow_exception(std::__exception_ptr::exception_ptr) +// function. + +namespace __exception_ptr +{ + +struct exception_ptr +{ + void* __ptr_; + + exception_ptr(const exception_ptr&) _NOEXCEPT; + exception_ptr& operator=(const exception_ptr&) _NOEXCEPT; + ~exception_ptr() _NOEXCEPT; +}; + +} + +_LIBCPP_NORETURN void rethrow_exception(__exception_ptr::exception_ptr); + +#endif exception_ptr::~exception_ptr() _NOEXCEPT { #if HAVE_DEPENDENT_EH_ABI __cxa_decrement_exception_refcount(__ptr_); +#elif defined(__GLIBCXX__) + reinterpret_cast<__exception_ptr::exception_ptr*>(this)->~exception_ptr(); #else - #warning exception_ptr not yet implemented +# if defined(_MSC_VER) && ! defined(__clang__) + _LIBCPP_WARNING("exception_ptr not yet implemented") +# else +# warning exception_ptr not yet implemented +# endif printf("exception_ptr not yet implemented\n"); ::abort(); -#endif // __APPLE__ +#endif } exception_ptr::exception_ptr(const exception_ptr& other) _NOEXCEPT @@ -160,11 +200,18 @@ exception_ptr::exception_ptr(const exception_ptr& other) _NOEXCEPT { #if HAVE_DEPENDENT_EH_ABI __cxa_increment_exception_refcount(__ptr_); +#elif defined(__GLIBCXX__) + new (reinterpret_cast<void*>(this)) __exception_ptr::exception_ptr( + reinterpret_cast<const __exception_ptr::exception_ptr&>(other)); #else - #warning exception_ptr not yet implemented +# if defined(_MSC_VER) && ! defined(__clang__) + _LIBCPP_WARNING("exception_ptr not yet implemented") +# else +# warning exception_ptr not yet implemented +# endif printf("exception_ptr not yet implemented\n"); ::abort(); -#endif // __APPLE__ +#endif } exception_ptr& exception_ptr::operator=(const exception_ptr& other) _NOEXCEPT @@ -177,11 +224,19 @@ exception_ptr& exception_ptr::operator=(const exception_ptr& other) _NOEXCEPT __ptr_ = other.__ptr_; } return *this; -#else // __APPLE__ - #warning exception_ptr not yet implemented +#elif defined(__GLIBCXX__) + *reinterpret_cast<__exception_ptr::exception_ptr*>(this) = + reinterpret_cast<const __exception_ptr::exception_ptr&>(other); + return *this; +#else +# if defined(_MSC_VER) && ! defined(__clang__) + _LIBCPP_WARNING("exception_ptr not yet implemented") +# else +# warning exception_ptr not yet implemented +# endif printf("exception_ptr not yet implemented\n"); ::abort(); -#endif // __APPLE__ +#endif } nested_exception::nested_exception() _NOEXCEPT @@ -189,10 +244,14 @@ nested_exception::nested_exception() _NOEXCEPT { } +#if !defined(__GLIBCXX__) + nested_exception::~nested_exception() _NOEXCEPT { } +#endif + _LIBCPP_NORETURN void nested_exception::rethrow_nested() const @@ -202,6 +261,7 @@ nested_exception::rethrow_nested() const rethrow_exception(__ptr_); } +#if !defined(__GLIBCXX__) exception_ptr current_exception() _NOEXCEPT { @@ -212,13 +272,19 @@ exception_ptr current_exception() _NOEXCEPT exception_ptr ptr; ptr.__ptr_ = __cxa_current_primary_exception(); return ptr; -#else // __APPLE__ - #warning exception_ptr not yet implemented +#else +# if defined(_MSC_VER) && ! defined(__clang__) + _LIBCPP_WARNING( "exception_ptr not yet implemented" ) +# else +# warning exception_ptr not yet implemented +# endif printf("exception_ptr not yet implemented\n"); ::abort(); -#endif // __APPLE__ +#endif } +#endif // !__GLIBCXX__ + _LIBCPP_NORETURN void rethrow_exception(exception_ptr p) { @@ -226,10 +292,16 @@ void rethrow_exception(exception_ptr p) __cxa_rethrow_primary_exception(p.__ptr_); // if p.__ptr_ is NULL, above returns so we terminate terminate(); -#else // __APPLE__ - #warning exception_ptr not yet implemented +#elif defined(__GLIBCXX__) + rethrow_exception(reinterpret_cast<__exception_ptr::exception_ptr&>(p)); +#else +# if defined(_MSC_VER) && ! defined(__clang__) + _LIBCPP_WARNING("exception_ptr not yet implemented") +# else +# warning exception_ptr not yet implemented +# endif printf("exception_ptr not yet implemented\n"); ::abort(); -#endif // __APPLE__ +#endif } } // std |