[PATCH] Implement std::exception_ptr under libsupc++.
Peter Collingbourne
peter at pcc.me.uk
Thu Oct 3 15:10:45 PDT 2013
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.
http://llvm-reviews.chandlerc.com/D1826
Files:
src/exception.cpp
Index: src/exception.cpp
===================================================================
--- src/exception.cpp
+++ src/exception.cpp
@@ -10,6 +10,7 @@
#include <stdio.h>
#include "exception"
+#include "new"
#ifndef __has_include
#define __has_include(inc) 0
@@ -143,28 +144,61 @@
#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
printf("exception_ptr not yet implemented\n");
::abort();
-#endif // __APPLE__
+#endif
}
exception_ptr::exception_ptr(const exception_ptr& other) _NOEXCEPT
: __ptr_(other.__ptr_)
{
#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
printf("exception_ptr not yet implemented\n");
::abort();
-#endif // __APPLE__
+#endif
}
exception_ptr& exception_ptr::operator=(const exception_ptr& other) _NOEXCEPT
@@ -177,11 +211,15 @@
__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
#warning exception_ptr not yet implemented
printf("exception_ptr not yet implemented\n");
::abort();
-#endif // __APPLE__
+#endif
}
nested_exception::nested_exception() _NOEXCEPT
@@ -202,6 +240,7 @@
rethrow_exception(__ptr_);
}
+#if !defined(__GLIBCXX__)
exception_ptr current_exception() _NOEXCEPT
{
@@ -212,24 +251,28 @@
exception_ptr ptr;
ptr.__ptr_ = __cxa_current_primary_exception();
return ptr;
-#else // __APPLE__
+#else
#warning exception_ptr not yet implemented
printf("exception_ptr not yet implemented\n");
::abort();
-#endif // __APPLE__
+#endif
}
+#endif // !__GLIBCXX__
+
_LIBCPP_NORETURN
void rethrow_exception(exception_ptr p)
{
#if HAVE_DEPENDENT_EH_ABI
__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
#warning exception_ptr not yet implemented
printf("exception_ptr not yet implemented\n");
::abort();
-#endif // __APPLE__
+#endif
}
} // std
-------------- next part --------------
A non-text attachment was scrubbed...
Name: D1826.1.patch
Type: text/x-patch
Size: 3643 bytes
Desc: not available
URL: <http://lists.llvm.org/pipermail/cfe-commits/attachments/20131003/4fe72f70/attachment.bin>
More information about the cfe-commits
mailing list