summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorEric Fiselier <eric@efcs.ca>2017-02-10 07:43:08 +0000
committerEric Fiselier <eric@efcs.ca>2017-02-10 07:43:08 +0000
commitd3298ad74ee5d5dfaa94b50ac4beb0c8f7e577c1 (patch)
tree2115f74a96b4f4a502ae235ed1448908100dcb7b
parente1b6382ee31d987ba0af05c8cf586624745887ca (diff)
Revert "Split exception.cpp and new.cpp implementation into different files for different runtimes."
The compiler-rt CMake configuration needs some tweaking before this can land. git-svn-id: https://llvm.org/svn/llvm-project/libcxx/trunk@294727 91177308-0d34-0410-b5e6-96231b3b80d8
-rw-r--r--CMakeLists.txt3
-rw-r--r--cmake/Modules/HandleLibCXXABI.cmake8
-rw-r--r--include/exception6
-rw-r--r--include/new24
-rw-r--r--include/typeinfo7
-rw-r--r--src/exception.cpp326
-rw-r--r--src/new.cpp160
-rw-r--r--src/support/runtime/exception_fallback.ipp182
-rw-r--r--src/support/runtime/exception_glibcxx.ipp38
-rw-r--r--src/support/runtime/exception_libcxxabi.ipp28
-rw-r--r--src/support/runtime/exception_libcxxrt.ipp41
-rw-r--r--src/support/runtime/exception_msvc.ipp89
-rw-r--r--src/support/runtime/exception_pointer_cxxabi.ipp74
-rw-r--r--src/support/runtime/exception_pointer_glibcxx.ipp74
-rw-r--r--src/support/runtime/exception_pointer_unimplemented.ipp80
-rw-r--r--src/support/runtime/new_handler_fallback.ipp27
-rw-r--r--src/typeinfo.cpp65
17 files changed, 508 insertions, 724 deletions
diff --git a/CMakeLists.txt b/CMakeLists.txt
index da9322e9e..0ac7c8c14 100644
--- a/CMakeLists.txt
+++ b/CMakeLists.txt
@@ -125,9 +125,6 @@ if (LIBCXX_CXX_ABI STREQUAL "default")
if (LIBCXX_TARGETING_MSVC)
# FIXME: Figure out how to configure the ABI library on Windows.
set(LIBCXX_CXX_ABI_LIBNAME "vcruntime")
- elseif(APPLE)
- set(LIBCXX_CXX_ABI_LIBNAME "libcxxabi")
- set(LIBCXX_CXX_ABI_SYSTEM 1)
else()
set(LIBCXX_CXX_ABI_LIBNAME "default")
endif()
diff --git a/cmake/Modules/HandleLibCXXABI.cmake b/cmake/Modules/HandleLibCXXABI.cmake
index b404e36c1..182565f52 100644
--- a/cmake/Modules/HandleLibCXXABI.cmake
+++ b/cmake/Modules/HandleLibCXXABI.cmake
@@ -103,11 +103,9 @@ elseif ("${LIBCXX_CXX_ABI_LIBNAME}" STREQUAL "libcxxabi")
# Assume c++abi is installed in the system, rely on -lc++abi link flag.
set(CXXABI_LIBNAME "c++abi")
endif()
- set(HEADERS "cxxabi.h;__cxxabi_config.h")
- if (LIBCXX_CXX_ABI_SYSTEM)
- set(HEADERS "")
- endif()
- setup_abi_lib("-DLIBCXX_BUILDING_LIBCXXABI" ${CXXABI_LIBNAME} "${HEADERS}" "")
+ setup_abi_lib("-DLIBCXX_BUILDING_LIBCXXABI"
+ ${CXXABI_LIBNAME} "cxxabi.h;__cxxabi_config.h" ""
+ )
elseif ("${LIBCXX_CXX_ABI_LIBNAME}" STREQUAL "libcxxrt")
setup_abi_lib("-DLIBCXXRT"
"cxxrt" "cxxabi.h;unwind.h;unwind-arm.h;unwind-itanium.h" ""
diff --git a/include/exception b/include/exception
index db11c36d8..98e1f37f9 100644
--- a/include/exception
+++ b/include/exception
@@ -82,10 +82,6 @@ template <class E> void rethrow_if_nested(const E& e);
#include <cstdlib>
#include <type_traits>
-#if defined(_LIBCPP_ABI_MICROSOFT)
-#include <vcruntime_exception.h>
-#endif
-
#if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER)
#pragma GCC system_header
#endif
@@ -93,7 +89,6 @@ template <class E> void rethrow_if_nested(const E& e);
namespace std // purposefully not using versioning namespace
{
-#if !defined(_LIBCPP_ABI_MICROSOFT)
class _LIBCPP_EXCEPTION_ABI exception
{
public:
@@ -110,7 +105,6 @@ public:
virtual ~bad_exception() _NOEXCEPT;
virtual const char* what() const _NOEXCEPT;
};
-#endif // !_LIBCPP_ABI_MICROSOFT
typedef void (*unexpected_handler)();
_LIBCPP_FUNC_VIS unexpected_handler set_unexpected(unexpected_handler) _NOEXCEPT;
diff --git a/include/new b/include/new
index 7a2a498b0..86428f281 100644
--- a/include/new
+++ b/include/new
@@ -92,10 +92,6 @@ void operator delete[](void* ptr, void*) noexcept;
#include <cstdlib>
#endif
-#if defined(_LIBCPP_ABI_MICROSOFT)
-#include <new.h>
-#endif
-
#if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER)
#pragma GCC system_header
#endif
@@ -114,10 +110,6 @@ void operator delete[](void* ptr, void*) noexcept;
namespace std // purposefully not using versioning namespace
{
-#if !defined(_LIBCPP_ABI_MICROSOFT)
-struct _LIBCPP_TYPE_VIS nothrow_t {};
-extern _LIBCPP_FUNC_VIS const nothrow_t nothrow;
-
class _LIBCPP_EXCEPTION_ABI bad_alloc
: public exception
{
@@ -136,12 +128,6 @@ public:
virtual const char* what() const _NOEXCEPT;
};
-typedef void (*new_handler)();
-_LIBCPP_FUNC_VIS new_handler set_new_handler(new_handler) _NOEXCEPT;
-_LIBCPP_FUNC_VIS new_handler get_new_handler() _NOEXCEPT;
-
-#endif // !_LIBCPP_ABI_MICROSOFT
-
_LIBCPP_NORETURN _LIBCPP_FUNC_VIS void __throw_bad_alloc(); // not in C++ spec
#if defined(_LIBCPP_BUILDING_NEW) || (_LIBCPP_STD_VER > 11)
@@ -167,6 +153,12 @@ enum align_val_t { __zero = 0, __max = (size_t)-1 };
#endif
#endif
+struct _LIBCPP_TYPE_VIS nothrow_t {};
+extern _LIBCPP_FUNC_VIS const nothrow_t nothrow;
+typedef void (*new_handler)();
+_LIBCPP_FUNC_VIS new_handler set_new_handler(new_handler) _NOEXCEPT;
+_LIBCPP_FUNC_VIS new_handler get_new_handler() _NOEXCEPT;
+
} // std
#if defined(_LIBCPP_CXX03_LANG)
@@ -175,8 +167,6 @@ enum align_val_t { __zero = 0, __max = (size_t)-1 };
#define _THROW_BAD_ALLOC
#endif
-#if !defined(_LIBCPP_ABI_MICROSOFT)
-
_LIBCPP_OVERRIDABLE_FUNC_VIS void* operator new(std::size_t __sz) _THROW_BAD_ALLOC;
_LIBCPP_OVERRIDABLE_FUNC_VIS void* operator new(std::size_t __sz, const std::nothrow_t&) _NOEXCEPT _NOALIAS;
_LIBCPP_OVERRIDABLE_FUNC_VIS void operator delete(void* __p) _NOEXCEPT;
@@ -216,8 +206,6 @@ inline _LIBCPP_INLINE_VISIBILITY void* operator new[](std::size_t, void* __p) _N
inline _LIBCPP_INLINE_VISIBILITY void operator delete (void*, void*) _NOEXCEPT {}
inline _LIBCPP_INLINE_VISIBILITY void operator delete[](void*, void*) _NOEXCEPT {}
-#endif // !_LIBCPP_ABI_MICROSOFT
-
_LIBCPP_BEGIN_NAMESPACE_STD
inline _LIBCPP_INLINE_VISIBILITY void *__allocate(size_t __size) {
diff --git a/include/typeinfo b/include/typeinfo
index 4145ac1a3..fdc25c81e 100644
--- a/include/typeinfo
+++ b/include/typeinfo
@@ -69,9 +69,7 @@ public:
#pragma GCC system_header
#endif
-#if defined(_LIBCPP_ABI_MICROSOFT)
-#include <vcruntime_typeinfo.h>
-#elif defined(_LIBCPP_NONUNIQUE_RTTI_BIT)
+#if defined(_LIBCPP_NONUNIQUE_RTTI_BIT)
#define _LIBCPP_HAS_NONUNIQUE_TYPEINFO
#else
#define _LIBCPP_HAS_UNIQUE_TYPEINFO
@@ -80,7 +78,6 @@ public:
namespace std // purposefully not using versioning namespace
{
-#if !defined(_LIBCPP_ABI_MICROSOFT)
class _LIBCPP_EXCEPTION_ABI type_info
{
type_info& operator=(const type_info&);
@@ -190,8 +187,6 @@ public:
virtual const char* what() const _NOEXCEPT;
};
-#endif // !_LIBCPP_ABI_MICROSOFT
-
} // std
_LIBCPP_BEGIN_NAMESPACE_STD
diff --git a/src/exception.cpp b/src/exception.cpp
index 41d65f941..35a3a9aba 100644
--- a/src/exception.cpp
+++ b/src/exception.cpp
@@ -6,30 +6,328 @@
// Source Licenses. See LICENSE.TXT for details.
//
//===----------------------------------------------------------------------===//
+#include <stdlib.h>
+#include <stdio.h>
#include "exception"
#include "new"
-#if defined(LIBCXXRT) || defined(LIBCXX_BUILDING_LIBCXXABI) || \
- (defined(__APPLE__) && !defined(_LIBCPP_BUILDING_HAS_NO_ABI_LIBRARY))
+#if defined(_LIBCPP_ABI_MICROSOFT)
+#include <eh.h>
+#include <corecrt_terminate.h>
+#elif defined(__APPLE__) && !defined(LIBCXXRT) && \
+ !defined(_LIBCPP_BUILDING_HAS_NO_ABI_LIBRARY)
#include <cxxabi.h>
+
using namespace __cxxabiv1;
#define HAVE_DEPENDENT_EH_ABI 1
+ #ifndef _LIBCPPABI_VERSION
+ using namespace __cxxabiapple;
+ // On Darwin, there are two STL shared libraries and a lower level ABI
+ // shared library. The globals holding the current terminate handler and
+ // current unexpected handler are in the ABI library.
+ #define __terminate_handler __cxxabiapple::__cxa_terminate_handler
+ #define __unexpected_handler __cxxabiapple::__cxa_unexpected_handler
+ #endif // _LIBCPPABI_VERSION
+#elif defined(LIBCXXRT) || defined(LIBCXX_BUILDING_LIBCXXABI)
+ #include <cxxabi.h>
+ using namespace __cxxabiv1;
+ #if defined(LIBCXXRT) || defined(_LIBCPPABI_VERSION)
+ #define HAVE_DEPENDENT_EH_ABI 1
+ #endif
+#elif !defined(__GLIBCXX__) // defined(LIBCXX_BUILDING_LIBCXXABI)
+ _LIBCPP_SAFE_STATIC static std::terminate_handler __terminate_handler;
+ _LIBCPP_SAFE_STATIC static std::unexpected_handler __unexpected_handler;
+#endif // defined(LIBCXX_BUILDING_LIBCXXABI)
+
+namespace std
+{
+
+#if !defined(LIBCXXRT) && !defined(_LIBCPPABI_VERSION) && !defined(__GLIBCXX__)
+
+// libcxxrt provides implementations of these functions itself.
+unexpected_handler
+set_unexpected(unexpected_handler func) _NOEXCEPT
+{
+#if defined(_LIBCPP_ABI_MICROSOFT)
+ return ::set_unexpected(func);
+#else
+ return __sync_lock_test_and_set(&__unexpected_handler, func);
+#endif
+}
+
+unexpected_handler
+get_unexpected() _NOEXCEPT
+{
+#if defined(_LIBCPP_ABI_MICROSOFT)
+ return ::_get_unexpected();
+#else
+ return __sync_fetch_and_add(&__unexpected_handler, (unexpected_handler)0);
+#endif
+}
+
+_LIBCPP_NORETURN
+void
+unexpected()
+{
+ (*get_unexpected())();
+ // unexpected handler should not return
+ terminate();
+}
+
+terminate_handler
+set_terminate(terminate_handler func) _NOEXCEPT
+{
+#if defined(_LIBCPP_ABI_MICROSOFT)
+ return ::set_terminate(func);
+#else
+ return __sync_lock_test_and_set(&__terminate_handler, func);
#endif
+}
+terminate_handler
+get_terminate() _NOEXCEPT
+{
#if defined(_LIBCPP_ABI_MICROSOFT)
-#include "support/runtime/exception_msvc.ipp"
-#include "support/runtime/exception_pointer_unimplemented.ipp"
-#elif defined(_LIBCPPABI_VERSION)
-#include "support/runtime/exception_libcxxabi.ipp"
-#include "support/runtime/exception_pointer_cxxabi.ipp"
-#elif defined(LIBCXXRT)
-#include "support/runtime/exception_libcxxrt.ipp"
-#include "support/runtime/exception_pointer_cxxabi.ipp"
+ return ::_get_terminate();
+#else
+ return __sync_fetch_and_add(&__terminate_handler, (terminate_handler)0);
+#endif
+}
+
+#ifndef __EMSCRIPTEN__ // We provide this in JS
+_LIBCPP_NORETURN
+void
+terminate() _NOEXCEPT
+{
+#ifndef _LIBCPP_NO_EXCEPTIONS
+ try
+ {
+#endif // _LIBCPP_NO_EXCEPTIONS
+ (*get_terminate())();
+ // handler should not return
+ fprintf(stderr, "terminate_handler unexpectedly returned\n");
+ ::abort();
+#ifndef _LIBCPP_NO_EXCEPTIONS
+ }
+ catch (...)
+ {
+ // handler should not throw exception
+ fprintf(stderr, "terminate_handler unexpectedly threw an exception\n");
+ ::abort();
+ }
+#endif // _LIBCPP_NO_EXCEPTIONS
+}
+#endif // !__EMSCRIPTEN__
+#endif // !defined(LIBCXXRT) && !defined(_LIBCPPABI_VERSION)
+
+#if !defined(LIBCXXRT) && !defined(__GLIBCXX__) && !defined(__EMSCRIPTEN__)
+
+bool uncaught_exception() _NOEXCEPT { return uncaught_exceptions() > 0; }
+
+int uncaught_exceptions() _NOEXCEPT
+{
+#if !defined(_LIBCPP_BUILDING_HAS_NO_ABI_LIBRARY) && \
+ (defined(__APPLE__) || defined(_LIBCPPABI_VERSION))
+ // on Darwin, there is a helper function so __cxa_get_globals is private
+# if _LIBCPPABI_VERSION > 1101
+ return __cxa_uncaught_exceptions();
+# else
+ return __cxa_uncaught_exception() ? 1 : 0;
+# endif
+#elif defined(_LIBCPP_ABI_MICROSOFT)
+ return __uncaught_exceptions();
+#else
+# if defined(_LIBCPP_MSVC)
+ _LIBCPP_WARNING("uncaught_exceptions not yet implemented")
+# else
+# warning uncaught_exception not yet implemented
+# endif
+ fprintf(stderr, "uncaught_exceptions not yet implemented\n");
+ ::abort();
+#endif // __APPLE__
+}
+
+
+#ifndef _LIBCPPABI_VERSION
+
+exception::~exception() _NOEXCEPT
+{
+}
+
+const char* exception::what() const _NOEXCEPT
+{
+ return "std::exception";
+}
+
+#endif // _LIBCPPABI_VERSION
+#endif //LIBCXXRT
+#if !defined(_LIBCPPABI_VERSION) && !defined(__GLIBCXX__)
+
+bad_exception::~bad_exception() _NOEXCEPT
+{
+}
+
+const char* bad_exception::what() const _NOEXCEPT
+{
+ return "std::bad_exception";
+}
+
+#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(_LIBCPP_MSVC)
+ _LIBCPP_WARNING("exception_ptr not yet implemented")
+# else
+# warning exception_ptr not yet implemented
+# endif
+ fprintf(stderr, "exception_ptr not yet implemented\n");
+ ::abort();
+#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
+# if defined(_LIBCPP_MSVC)
+ _LIBCPP_WARNING("exception_ptr not yet implemented")
+# else
+# warning exception_ptr not yet implemented
+# endif
+ fprintf(stderr, "exception_ptr not yet implemented\n");
+ ::abort();
+#endif
+}
+
+exception_ptr& exception_ptr::operator=(const exception_ptr& other) _NOEXCEPT
+{
+#if HAVE_DEPENDENT_EH_ABI
+ if (__ptr_ != other.__ptr_)
+ {
+ __cxa_increment_exception_refcount(other.__ptr_);
+ __cxa_decrement_exception_refcount(__ptr_);
+ __ptr_ = other.__ptr_;
+ }
+ return *this;
+#elif defined(__GLIBCXX__)
+ *reinterpret_cast<__exception_ptr::exception_ptr*>(this) =
+ reinterpret_cast<const __exception_ptr::exception_ptr&>(other);
+ return *this;
+#else
+# if defined(_LIBCPP_MSVC)
+ _LIBCPP_WARNING("exception_ptr not yet implemented")
+# else
+# warning exception_ptr not yet implemented
+# endif
+ fprintf(stderr, "exception_ptr not yet implemented\n");
+ ::abort();
+#endif
+}
+
+nested_exception::nested_exception() _NOEXCEPT
+ : __ptr_(current_exception())
+{
+}
+
+#if !defined(__GLIBCXX__)
+
+nested_exception::~nested_exception() _NOEXCEPT
+{
+}
+
+#endif
+
+_LIBCPP_NORETURN
+void
+nested_exception::rethrow_nested() const
+{
+ if (__ptr_ == nullptr)
+ terminate();
+ rethrow_exception(__ptr_);
+}
+
+#if !defined(__GLIBCXX__)
+
+exception_ptr current_exception() _NOEXCEPT
+{
+#if HAVE_DEPENDENT_EH_ABI
+ // be nicer if there was a constructor that took a ptr, then
+ // this whole function would be just:
+ // return exception_ptr(__cxa_current_primary_exception());
+ exception_ptr ptr;
+ ptr.__ptr_ = __cxa_current_primary_exception();
+ return ptr;
+#else
+# if defined(_LIBCPP_MSVC)
+ _LIBCPP_WARNING( "exception_ptr not yet implemented" )
+# else
+# warning exception_ptr not yet implemented
+# endif
+ fprintf(stderr, "exception_ptr not yet implemented\n");
+ ::abort();
+#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();
#elif defined(__GLIBCXX__)
-#include "support/runtime/exception_glibcxx.ipp"
-#include "support/runtime/exception_pointer_glibcxx.ipp"
+ rethrow_exception(reinterpret_cast<__exception_ptr::exception_ptr&>(p));
#else
-#include "support/runtime/exception_fallback.ipp"
-#include "support/runtime/exception_pointer_unimplemented.ipp"
+# if defined(_LIBCPP_MSVC)
+ _LIBCPP_WARNING("exception_ptr not yet implemented")
+# else
+# warning exception_ptr not yet implemented
+# endif
+ fprintf(stderr, "exception_ptr not yet implemented\n");
+ ::abort();
#endif
+}
+} // std
diff --git a/src/new.cpp b/src/new.cpp
index 8e88d7f6c..b1e8ee324 100644
--- a/src/new.cpp
+++ b/src/new.cpp
@@ -13,45 +13,27 @@
#include "new"
-#if defined(_LIBCPP_ABI_MICROSOFT)
-// nothing todo
-#elif defined(LIBCXX_BUILDING_LIBCXXABI)
-#include <cxxabi.h>
-#elif defined(LIBCXXRT)
-#include <cxxabi.h>
-#include "new_handler_fallback.ipp"
-#elif defined(__GLIBCXX__)
-// nothing todo
-#elif defined(_LIBCPP_BUILDING_NO_ABI_LIBRARY)
-// nothing todo
-#else
-#error UNSUPPORTED configuration
+#if defined(__APPLE__) && !defined(LIBCXXRT) && \
+ !defined(_LIBCPP_BUILDING_HAS_NO_ABI_LIBRARY)
+ #include <cxxabi.h>
+
+ #ifndef _LIBCPPABI_VERSION
+ // On Darwin, there are two STL shared libraries and a lower level ABI
+ // shared library. The global holding the current new handler is
+ // in the ABI library and named __cxa_new_handler.
+ #define __new_handler __cxxabiapple::__cxa_new_handler
+ #endif
+#else // __APPLE__
+ #if defined(LIBCXXRT) || defined(LIBCXX_BUILDING_LIBCXXABI)
+ #include <cxxabi.h>
+ #endif // defined(LIBCXX_BUILDING_LIBCXXABI)
+ #if defined(_LIBCPP_BUILDING_HAS_NO_ABI_LIBRARY) || \
+ (!defined(_LIBCPPABI_VERSION) && !defined(__GLIBCXX__))
+ static std::new_handler __new_handler;
+ #endif // _LIBCPPABI_VERSION
#endif
-namespace std
-{
-
#ifndef __GLIBCXX__
-const nothrow_t nothrow = {};
-#endif
-
-#ifndef LIBSTDCXX
-
-void
-__throw_bad_alloc()
-{
-#ifndef _LIBCPP_NO_EXCEPTIONS
- throw bad_alloc();
-#else
- _VSTD::abort();
-#endif
-}
-
-#endif // !LIBSTDCXX
-
-} // std
-
-#if !defined(__GLIBCXX__) && !defined(_LIBCPP_ABI_MICROSOFT)
// Implement all new and delete operators as weak definitions
// in this shared library, so that they can be overridden by programs
@@ -295,5 +277,107 @@ operator delete[] (void* ptr, size_t, std::align_val_t alignment) _NOEXCEPT
::operator delete[](ptr, alignment);
}
-#endif // !_LIBCPP_HAS_NO_ALIGNED_ALLOCATION
-#endif // !__GLIBCXX__ && !_LIBCPP_ABI_MICROSOFT
+#endif // !defined(_LIBCPP_HAS_NO_ALIGNED_ALLOCATION)
+
+#endif // !__GLIBCXX__
+
+namespace std
+{
+
+#ifndef __GLIBCXX__
+const nothrow_t nothrow = {};
+#endif
+
+#ifndef _LIBCPPABI_VERSION
+
+#ifndef __GLIBCXX__
+
+new_handler
+set_new_handler(new_handler handler) _NOEXCEPT
+{
+ return __sync_lock_test_and_set(&__new_handler, handler);
+}
+
+new_handler
+get_new_handler() _NOEXCEPT
+{
+ return __sync_fetch_and_add(&__new_handler, nullptr);
+}
+
+#endif // !__GLIBCXX__
+
+#ifndef LIBCXXRT
+
+bad_alloc::bad_alloc() _NOEXCEPT
+{
+}
+
+#ifndef __GLIBCXX__
+
+bad_alloc::~bad_alloc() _NOEXCEPT
+{
+}
+
+const char*
+bad_alloc::what() const _NOEXCEPT
+{
+ return "std::bad_alloc";
+}
+
+#endif // !__GLIBCXX__
+
+bad_array_new_length::bad_array_new_length() _NOEXCEPT
+{
+}
+
+#ifndef __GLIBCXX__
+
+bad_array_new_length::~bad_array_new_length() _NOEXCEPT
+{
+}
+
+const char*
+bad_array_new_length::what() const _NOEXCEPT
+{
+ return "bad_array_new_length";
+}
+
+#endif // !__GLIBCXX__
+
+#endif //LIBCXXRT
+
+bad_array_length::bad_array_length() _NOEXCEPT
+{
+}
+
+#ifndef __GLIBCXX__
+
+bad_array_length::~bad_array_length() _NOEXCEPT
+{
+}
+
+const char*
+bad_array_length::what() const _NOEXCEPT
+{
+ return "bad_array_length";
+}
+
+#endif // !__GLIBCXX__
+
+#endif // _LIBCPPABI_VERSION
+
+#ifndef LIBSTDCXX
+
+void
+__throw_bad_alloc()
+{
+#ifndef _LIBCPP_NO_EXCEPTIONS
+ throw bad_alloc();
+#else
+ _VSTD::abort();
+#endif
+}
+
+#endif // !LIBSTDCXX
+
+} // std
diff --git a/src/support/runtime/exception_fallback.ipp b/src/support/runtime/exception_fallback.ipp
deleted file mode 100644
index c58edcc55..000000000
--- a/src/support/runtime/exception_fallback.ipp
+++ /dev/null
@@ -1,182 +0,0 @@
-// -*- C++ -*-
-//===----------------------------------------------------------------------===//
-//
-// The LLVM Compiler Infrastructure
-//
-// This file is dual licensed under the MIT and the University of Illinois Open
-// Source Licenses. See LICENSE.TXT for details.
-//
-//===----------------------------------------------------------------------===//
-
-namespace std {
-
-_LIBCPP_SAFE_STATIC static std::terminate_handler __terminate_handler;
-_LIBCPP_SAFE_STATIC static std::unexpected_handler __unexpected_handler;
-
-
-// libcxxrt provides implementations of these functions itself.
-unexpected_handler
-set_unexpected(unexpected_handler func) _NOEXCEPT
-{
- return __sync_lock_test_and_set(&__unexpected_handler, func);
-}
-
-unexpected_handler
-get_unexpected() _NOEXCEPT
-{
- return __sync_fetch_and_add(&__unexpected_handler, (unexpected_handler)0);
-
-}
-
-_LIBCPP_NORETURN
-void unexpected()
-{
- (*get_unexpected())();
- // unexpected handler should not return
- terminate();
-}
-
-terminate_handler
-set_terminate(terminate_handler func) _NOEXCEPT
-{
- return __sync_lock_test_and_set(&__terminate_handler, func);
-}
-
-terminate_handler
-get_terminate() _NOEXCEPT
-{
- return __sync_fetch_and_add(&__terminate_handler, (terminate_handler)0);
-
-}
-
-#ifndef __EMSCRIPTEN__ // We provide this in JS
-_LIBCPP_NORETURN
-void
-terminate() _NOEXCEPT
-{
-#ifndef _LIBCPP_NO_EXCEPTIONS
- try
- {
-#endif // _LIBCPP_NO_EXCEPTIONS
- (*get_terminate())();
- // handler should not return
- fprintf(stderr, "terminate_handler unexpectedly returned\n");
- ::abort();
-#ifndef _LIBCPP_NO_EXCEPTIONS
- }
- catch (...)
- {
- // handler should not throw exception
- fprintf(stderr, "terminate_handler unexpectedly threw an exception\n");
- ::abort();
- }
-#endif // _LIBCPP_NO_EXCEPTIONS
-}
-#endif // !__EMSCRIPTEN__
-
-#if !defined(__EMSCRIPTEN__)
-bool uncaught_exception() _NOEXCEPT { return uncaught_exceptions() > 0; }
-
-int uncaught_exceptions() _NOEXCEPT
-{
-#warning uncaught_exception not yet implemented
- fprintf(stderr, "uncaught_exceptions not yet implemented\n");
- ::abort();
-}
-#endif // !__EMSCRIPTEN__
-
-
-exception::~exception() _NOEXCEPT
-{
-}
-
-const char* exception::what() const _NOEXCEPT
-{
- return "std::exception";
-}
-
-bad_exception::~bad_exception() _NOEXCEPT
-{
-}
-
-const char* bad_exception::what() const _NOEXCEPT
-{
- return "std::bad_exception";
-}
-
-
-bad_alloc::bad_alloc() _NOEXCEPT
-{
-}
-
-bad_alloc::~bad_alloc() _NOEXCEPT
-{
-}
-
-const char*
-bad_alloc::what() const _NOEXCEPT
-{
- return "std::bad_alloc";
-}
-
-bad_array_new_length::bad_array_new_length() _NOEXCEPT
-{
-}
-
-bad_array_new_length::~bad_array_new_length() _NOEXCEPT
-{
-}
-
-const char*
-bad_array_new_length::what() const _NOEXCEPT
-{
- return "bad_array_new_length";
-}
-
-
-bad_array_length::bad_array_length() _NOEXCEPT
-{
-}
-
-bad_array_length::~bad_array_length() _NOEXCEPT
-{
-}
-
-const char*
-bad_array_length::what() const _NOEXCEPT
-{
- return "bad_array_length";
-}
-
-
-bad_cast::bad_cast() _NOEXCEPT
-{
-}
-
-bad_typeid::bad_typeid() _NOEXCEPT
-{
-}
-
-#ifndef __GLIBCXX__
-
-bad_cast::~bad_cast() _NOEXCEPT
-{
-}
-
-const char*
-bad_cast::what() const _NOEXCEPT
-{
- return "std::bad_cast";
-}
-
-bad_typeid::~bad_typeid() _NOEXCEPT
-{
-}
-
-const char*
-bad_typeid::what() const _NOEXCEPT
-{
- return "std::bad_typeid";
-}
-
-} // namespace std
diff --git a/src/support/runtime/exception_glibcxx.ipp b/src/support/runtime/exception_glibcxx.ipp
deleted file mode 100644
index 365dc40a7..000000000
--- a/src/support/runtime/exception_glibcxx.ipp
+++ /dev/null
@@ -1,38 +0,0 @@
-// -*- C++ -*-
-//===----------------------------------------------------------------------===//
-//
-// The LLVM Compiler Infrastructure
-//
-// This file is dual licensed under the MIT and the University of Illinois Open
-// Source Licenses. See LICENSE.TXT for details.
-//
-//===----------------------------------------------------------------------===//
-
-#ifndef __GLIBCXX__
-#error header can only be used when targeting libstdc++ or libsupc++
-#endif
-
-namespace std {
-
-bad_alloc::bad_alloc() _NOEXCEPT
-{
-}
-
-bad_array_new_length::bad_array_new_length() _NOEXCEPT
-{
-}
-
-bad_array_length::bad_array_length() _NOEXCEPT
-{
-}
-
-
-bad_cast::bad_cast() _NOEXCEPT
-{
-}
-
-bad_typeid::bad_typeid() _NOEXCEPT
-{
-}
-
-} // namespace
diff --git a/src/support/runtime/exception_libcxxabi.ipp b/src/support/runtime/exception_libcxxabi.ipp
deleted file mode 100644
index c3dcf1ec5..000000000
--- a/src/support/runtime/exception_libcxxabi.ipp
+++ /dev/null
@@ -1,28 +0,0 @@
-// -*- C++ -*-
-//===----------------------------------------------------------------------===//
-//
-// The LLVM Compiler Infrastructure
-//
-// This file is dual licensed under the MIT and the University of Illinois Open
-// Source Licenses. See LICENSE.TXT for details.
-//
-//===----------------------------------------------------------------------===//
-
-#ifndef _LIBCPPABI_VERSION
-#error this header can only be used with libc++abi
-#endif
-
-namespace std {
-
-bool uncaught_exception() _NOEXCEPT { return uncaught_exceptions() > 0; }
-
-int uncaught_exceptions() _NOEXCEPT
-{
-# if _LIBCPPABI_VERSION > 1101
- return __cxa_uncaught_exceptions();
-# else
- return __cxa_uncaught_exception() ? 1 : 0;
-# endif
-}
-
-} // namespace std
diff --git a/src/support/runtime/exception_libcxxrt.ipp b/src/support/runtime/exception_libcxxrt.ipp
deleted file mode 100644
index 6d9e0cff5..000000000
--- a/src/support/runtime/exception_libcxxrt.ipp
+++ /dev/null
@@ -1,41 +0,0 @@
-// -*- C++ -*-
-//===----------------------------------------------------------------------===//
-//
-// The LLVM Compiler Infrastructure
-//
-// This file is dual licensed under the MIT and the University of Illinois Open
-// Source Licenses. See LICENSE.TXT for details.
-//
-//===----------------------------------------------------------------------===//
-
-#ifndef LIBCXXRT
-#error this header may only be used when targeting libcxxrt
-#endif
-
-namespace std {
-
-bad_exception::~bad_exception() _NOEXCEPT
-{
-}
-
-const char* bad_exception::what() const _NOEXCEPT
-{
- return "std::bad_exception";
-}
-
-
-bad_array_length::bad_array_length() _NOEXCEPT
-{
-}
-
-bad_array_length::~bad_array_length() _NOEXCEPT
-{
-}
-
-const char*
-bad_array_length::what() const _NOEXCEPT
-{
- return "bad_array_length";
-}
-
-} // namespace std
diff --git a/src/support/runtime/exception_msvc.ipp b/src/support/runtime/exception_msvc.ipp
deleted file mode 100644
index 950ec0ceb..000000000
--- a/src/support/runtime/exception_msvc.ipp
+++ /dev/null
@@ -1,89 +0,0 @@
-// -*- C++ -*-
-//===----------------------------------------------------------------------===//
-//
-// The LLVM Compiler Infrastructure
-//
-// This file is dual licensed under the MIT and the University of Illinois Open
-// Source Licenses. See LICENSE.TXT for details.
-//
-//===----------------------------------------------------------------------===//
-
-#ifndef _LIBCPP_ABI_MICROSOFT
-#error this header can only be used when targeting the MSVC ABI
-#endif
-
-#include <stdio.h>
-#include <stdlib.h>
-#include <eh.h>
-#include <corecrt_terminate.h>
-
-namespace std {
-
-// libcxxrt provides implementations of these functions itself.
-unexpected_handler
-set_unexpected(unexpected_handler func) _NOEXCEPT {
- return ::set_unexpected(func);
-}
-
-unexpected_handler get_unexpected() _NOEXCEPT {
- return ::_get_unexpected();
-}
-
-_LIBCPP_NORETURN
-void unexpected() {
- (*get_unexpected())();
- // unexpected handler should not return
- terminate();
-}
-
-terminate_handler set_terminate(terminate_handler func) _NOEXCEPT {
- return ::set_terminate(func);
-}
-
-terminate_handler get_terminate() _NOEXCEPT {
- return ::_get_terminate();
-}
-
-_LIBCPP_NORETURN
-void terminate() _NOEXCEPT
-{
-#ifndef _LIBCPP_NO_EXCEPTIONS
- try
- {
-#endif // _LIBCPP_NO_EXCEPTIONS
- (*get_terminate())();
- // handler should not return
- fprintf(stderr, "terminate_handler unexpectedly returned\n");
- ::abort();
-#ifndef _LIBCPP_NO_EXCEPTIONS
- }
- catch (...)
- {
- // handler should not throw exception
- fprintf(stderr, "terminate_handler unexpectedly threw an exception\n");
- ::abort();
- }
-#endif // _LIBCPP_NO_EXCEPTIONS
-}
-
-bool uncaught_exception() _NOEXCEPT { return uncaught_exceptions() > 0; }
-
-int uncaught_exceptions() _NOEXCEPT {
- return __uncaught_exceptions();
-}
-
-bad_array_length::bad_array_length() _NOEXCEPT
-{
-}
-
-bad_array_length::~bad_array_length() _NOEXCEPT
-{
-}
-
-const char*
-bad_array_length::what() const _NOEXCEPT
-{
- return "bad_array_length";
-}
-
-} // namespace std
diff --git a/src/support/runtime/exception_pointer_cxxabi.ipp b/src/support/runtime/exception_pointer_cxxabi.ipp
deleted file mode 100644
index dfac8648c..000000000
--- a/src/support/runtime/exception_pointer_cxxabi.ipp
+++ /dev/null
@@ -1,74 +0,0 @@
-// -*- C++ -*-
-//===----------------------------------------------------------------------===//
-//
-// The LLVM Compiler Infrastructure
-//
-// This file is dual licensed under the MIT and the University of Illinois Open
-// Source Licenses. See LICENSE.TXT for details.
-//
-//===----------------------------------------------------------------------===//
-
-#ifndef HAVE_DEPENDENT_EH_ABI
-#error this header may only be used with libc++abi or libcxxrt
-#endif
-
-namespace std {
-
-exception_ptr::~exception_ptr() _NOEXCEPT {
- __cxa_decrement_exception_refcount(__ptr_);
-}
-
-exception_ptr::exception_ptr(const exception_ptr& other) _NOEXCEPT
- : __ptr_(other.__ptr_)
-{
- __cxa_increment_exception_refcount(__ptr_);
-}
-
-exception_ptr& exception_ptr::operator=(const exception_ptr& other) _NOEXCEPT
-{
- if (__ptr_ != other.__ptr_)
- {
- __cxa_increment_exception_refcount(other.__ptr_);
- __cxa_decrement_exception_refcount(__ptr_);
- __ptr_ = other.__ptr_;
- }
- return *this;
-}
-
-nested_exception::nested_exception() _NOEXCEPT
- : __ptr_(current_exception())
-{
-}
-
-nested_exception::~nested_exception() _NOEXCEPT
-{
-}
-
-_LIBCPP_NORETURN
-void
-nested_exception::rethrow_nested() const
-{
- if (__ptr_ == nullptr)
- terminate();
- rethrow_exception(__ptr_);
-}
-
-exception_ptr current_exception() _NOEXCEPT
-{
- // be nicer if there was a constructor that took a ptr, then
- // this whole function would be just:
- // return exception_ptr(__cxa_current_primary_exception());
- exception_ptr ptr;
- ptr.__ptr_ = __cxa_current_primary_exception();
- return ptr;
-}
-
-_LIBCPP_NORETURN
-void rethrow_exception(exception_ptr p)
-{
- __cxa_rethrow_primary_exception(p.__ptr_);
- // if p.__ptr_ is NULL, above returns so we terminate
- terminate();
-}
-
-} // namespace std
diff --git a/src/support/runtime/exception_pointer_glibcxx.ipp b/src/support/runtime/exception_pointer_glibcxx.ipp
deleted file mode 100644
index 30bd6b61f..000000000
--- a/src/support/runtime/exception_pointer_glibcxx.ipp
+++ /dev/null
@@ -1,74 +0,0 @@
-// -*- C++ -*-
-//===----------------------------------------------------------------------===//
-//
-// The LLVM Compiler Infrastructure
-//
-// This file is dual licensed under the MIT and the University of Illinois Open
-// Source Licenses. See LICENSE.TXT for details.
-//
-//===----------------------------------------------------------------------===//
-
-// 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);
-
-exception_ptr::~exception_ptr() _NOEXCEPT
-{
- reinterpret_cast<__exception_ptr::exception_ptr*>(this)->~exception_ptr();
-}
-
-exception_ptr::exception_ptr(const exception_ptr& other) _NOEXCEPT
- : __ptr_(other.__ptr_)
-{
- new (reinterpret_cast<void*>(this)) __exception_ptr::exception_ptr(
- reinterpret_cast<const __exception_ptr::exception_ptr&>(other));
-}
-
-exception_ptr& exception_ptr::operator=(const exception_ptr& other) _NOEXCEPT
-{
- *reinterpret_cast<__exception_ptr::exception_ptr*>(this) =
- reinterpret_cast<const __exception_ptr::exception_ptr&>(other);
- return *this;
-}
-
-nested_exception::nested_exception() _NOEXCEPT
- : __ptr_(current_exception())
-{
-}
-
-
-_LIBCPP_NORETURN
-void
-nested_exception::rethrow_nested() const
-{
- if (__ptr_ == nullptr)
- terminate();
- rethrow_exception(__ptr_);
-}
-
-_LIBCPP_NORETURN
-void rethrow_exception(exception_ptr p)
-{
- rethrow_exception(reinterpret_cast<__exception_ptr::exception_ptr&>(p));
-}
diff --git a/src/support/runtime/exception_pointer_unimplemented.ipp b/src/support/runtime/exception_pointer_unimplemented.ipp
deleted file mode 100644
index 21c182c85..000000000
--- a/src/support/runtime/exception_pointer_unimplemented.ipp
+++ /dev/null
@@ -1,80 +0,0 @@
-// -*- C++ -*-
-//===----------------------------------------------------------------------===//
-//
-// The LLVM Compiler Infrastructure
-//
-// This file is dual licensed under the MIT and the University of Illinois Open
-// Source Licenses. See LICENSE.TXT for details.
-//
-//===----------------------------------------------------------------------===//
-
-#include <stdio.h>
-#include <stdlib.h>
-
-namespace std {
-
-exception_ptr::~exception_ptr() _NOEXCEPT
-{
-# warning exception_ptr not yet implemented
- fprintf(stderr, "exception_ptr not yet implemented\n");
- ::abort();
-}
-
-exception_ptr::exception_ptr(const exception_ptr& other) _NOEXCEPT
- : __ptr_(other.__ptr_)
-{
-# warning exception_ptr not yet implemented
- fprintf(stderr, "exception_ptr not yet implemented\n");
- ::abort();
-}
-
-exception_ptr& exception_ptr::operator=(const exception_ptr& other) _NOEXCEPT
-{
-# warning exception_ptr not yet implemented
- fprintf(stderr, "exception_ptr not yet implemented\n");
- ::abort();
-}
-
-nested_exception::nested_exception() _NOEXCEPT
- : __ptr_(current_exception())
-{
-}
-
-#if !defined(__GLIBCXX__)
-
-nested_exception::~nested_exception() _NOEXCEPT
-{
-}
-
-#endif
-
-_LIBCPP_NORETURN
-void
-nested_exception::rethrow_nested() const
-{
-# warning exception_ptr not yet implemented
- fprintf(stderr, "exception_ptr not yet implemented\n");
- ::abort();
-#if 0
- if (__ptr_ == nullptr)
- terminate();
- rethrow_exception(__ptr_);
-#endif // FIXME
-}
-
-exception_ptr current_exception() _NOEXCEPT
-{
-# warning exception_ptr not yet implemented
- fprintf(stderr, "exception_ptr not yet implemented\n");
- ::abort();
-}
-
-_LIBCPP_NORETURN
-void rethrow_exception(exception_ptr p)
-{
-# warning exception_ptr not yet implemented
- fprintf(stderr, "exception_ptr not yet implemented\n");
- ::abort();
-}
-
-} // namespace std
diff --git a/src/support/runtime/new_handler_fallback.ipp b/src/support/runtime/new_handler_fallback.ipp
deleted file mode 100644
index b7092d542..000000000
--- a/src/support/runtime/new_handler_fallback.ipp
+++ /dev/null
@@ -1,27 +0,0 @@
-// -*- C++ -*-
-//===----------------------------------------------------------------------===//
-//
-// The LLVM Compiler Infrastructure
-//
-// This file is dual licensed under the MIT and the University of Illinois Open
-// Source Licenses. See LICENSE.TXT for details.
-//
-//===----------------------------------------------------------------------===//
-
-namespace std {
-
-_LIBCPP_SAFE_STATIC static std::new_handler __new_handler;
-
-new_handler
-set_new_handler(new_handler handler) _NOEXCEPT
-{
- return __sync_lock_test_and_set(&__new_handler, handler);
-}
-
-new_handler
-get_new_handler() _NOEXCEPT
-{
- return __sync_fetch_and_add(&__new_handler, nullptr);
-}
-
-} // namespace std
diff --git a/src/typeinfo.cpp b/src/typeinfo.cpp
index d58f1a8e3..8123606b1 100644
--- a/src/typeinfo.cpp
+++ b/src/typeinfo.cpp
@@ -6,11 +6,74 @@
// Source Licenses. See LICENSE.TXT for details.
//
//===----------------------------------------------------------------------===//
+#include <stdlib.h>
+
+#if !defined(_LIBCPP_BUILDING_HAS_NO_ABI_LIBRARY) && \
+ (defined(__APPLE__) || defined(LIBCXXRT) || defined(LIBCXX_BUILDING_LIBCXXABI))
+#include <cxxabi.h>
+#endif
#include "typeinfo"
-#if defined(_LIBCPP_BUILDING_HAS_NO_ABI_LIBRARY)
+#if defined(_LIBCPP_BUILDING_HAS_NO_ABI_LIBRARY) || \
+ defined(_LIBCPP_ABI_MICROSOFT) // FIXME: This is a temporary workaround
std::type_info::~type_info()
{
}
#endif
+
+#if !defined(LIBCXXRT) && !defined(_LIBCPPABI_VERSION)
+
+std::bad_cast::bad_cast() _NOEXCEPT
+{
+}
+
+std::bad_typeid::bad_typeid() _NOEXCEPT
+{
+}
+
+#ifndef __GLIBCXX__
+
+std::bad_cast::~bad_cast() _NOEXCEPT
+{
+}
+
+const char*
+std::bad_cast::what() const _NOEXCEPT
+{
+ return "std::bad_cast";
+}
+
+std::bad_typeid::~bad_typeid() _NOEXCEPT
+{
+}
+
+const char*
+std::bad_typeid::what() const _NOEXCEPT
+{
+ return "std::bad_typeid";
+}
+
+#if defined(__APPLE__) && !defined(_LIBCPP_BUILDING_HAS_NO_ABI_LIBRARY)
+ // On Darwin, the cxa_bad_* functions cannot be in the lower level library
+ // because bad_cast and bad_typeid are defined in his higher level library
+ void __cxxabiv1::__cxa_bad_typeid()
+ {
+#ifndef _LIBCPP_NO_EXCEPTIONS
+ throw std::bad_typeid();
+#else
+ _VSTD::abort();
+#endif
+ }
+ void __cxxabiv1::__cxa_bad_cast()
+ {
+#ifndef _LIBCPP_NO_EXCEPTIONS
+ throw std::bad_cast();
+#else
+ _VSTD::abort();
+#endif
+ }
+#endif
+
+#endif // !__GLIBCXX__
+#endif // !LIBCXXRT && !_LIBCPPABI_VERSION