diff options
author | Peter Collingbourne <peter@pcc.me.uk> | 2013-10-06 22:13:21 +0000 |
---|---|---|
committer | Peter Collingbourne <peter@pcc.me.uk> | 2013-10-06 22:13:21 +0000 |
commit | 3b5d969293026eed9b6444eddb1ce48a8615a11f (patch) | |
tree | 024f58720d6762d4abc7e517a5e1522032225f0e /libcxx/src/exception.cpp | |
parent | 26dd09e57fffb23f5765ec6f7b9c0ef7b79afc82 (diff) | |
download | llvm-3b5d969293026eed9b6444eddb1ce48a8615a11f.zip llvm-3b5d969293026eed9b6444eddb1ce48a8615a11f.tar.gz llvm-3b5d969293026eed9b6444eddb1ce48a8615a11f.tar.bz2 |
Implement std::exception_ptr under libsupc++.
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.
Also, remove some out of date comments.
Differential Revision: http://llvm-reviews.chandlerc.com/D1826
llvm-svn: 192076
Diffstat (limited to 'libcxx/src/exception.cpp')
-rw-r--r-- | libcxx/src/exception.cpp | 63 |
1 files changed, 51 insertions, 12 deletions
diff --git a/libcxx/src/exception.cpp b/libcxx/src/exception.cpp index 3e3d40e..e080f7c 100644 --- a/libcxx/src/exception.cpp +++ b/libcxx/src/exception.cpp @@ -12,6 +12,7 @@ #include <stdio.h> #include "exception" +#include "new" #ifndef __has_include #define __has_include(inc) 0 @@ -154,11 +155,41 @@ 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 # if defined(_MSC_VER) && ! defined(__clang__) _LIBCPP_WARNING("exception_ptr not yet implemented") @@ -166,7 +197,7 @@ exception_ptr::~exception_ptr() _NOEXCEPT # warning exception_ptr not yet implemented # endif _libcpp_abort("exception_ptr not yet implemented\n"); -#endif // __APPLE__ +#endif } exception_ptr::exception_ptr(const exception_ptr& other) _NOEXCEPT @@ -174,16 +205,17 @@ 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 - # if defined(_MSC_VER) && ! defined(__clang__) _LIBCPP_WARNING("exception_ptr not yet implemented") # else # warning exception_ptr not yet implemented # endif _libcpp_abort("exception_ptr not yet implemented\n"); - -#endif // __APPLE__ +#endif } exception_ptr& exception_ptr::operator=(const exception_ptr& other) _NOEXCEPT @@ -196,16 +228,18 @@ exception_ptr& exception_ptr::operator=(const exception_ptr& other) _NOEXCEPT __ptr_ = other.__ptr_; } return *this; -#else // __APPLE__ - +#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 _libcpp_abort("exception_ptr not yet implemented\n"); - -#endif // __APPLE__ +#endif } nested_exception::nested_exception() _NOEXCEPT @@ -230,6 +264,7 @@ nested_exception::rethrow_nested() const rethrow_exception(__ptr_); } +#if !defined(__GLIBCXX__) exception_ptr current_exception() _NOEXCEPT { @@ -240,16 +275,18 @@ exception_ptr current_exception() _NOEXCEPT exception_ptr ptr; ptr.__ptr_ = __cxa_current_primary_exception(); return ptr; -#else // __APPLE__ +#else # if defined(_MSC_VER) && ! defined(__clang__) _LIBCPP_WARNING( "exception_ptr not yet implemented" ) # else # warning exception_ptr not yet implemented # endif _libcpp_abort("exception_ptr not yet implemented\n"); -#endif // __APPLE__ +#endif } +#endif // !__GLIBCXX__ + _LIBCPP_NORETURN void rethrow_exception(exception_ptr p) { @@ -257,13 +294,15 @@ 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__ +#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 _libcpp_abort("exception_ptr not yet implemented\n"); -#endif // __APPLE__ +#endif } } // std |