EricWF updated this revision to Diff 87944.
EricWF added a comment.

Merge with upstream.


https://reviews.llvm.org/D28785

Files:
  CMakeLists.txt
  include/exception
  include/new
  include/typeinfo
  src/exception.cpp
  src/new.cpp
  src/support/runtime/exception_fallback.ipp
  src/support/runtime/exception_glibcxx.ipp
  src/support/runtime/exception_libcxxabi.ipp
  src/support/runtime/exception_libcxxrt.ipp
  src/support/runtime/exception_msvc.ipp
  src/support/runtime/exception_pointer_cxxabi.ipp
  src/support/runtime/exception_pointer_glibcxx.ipp
  src/support/runtime/exception_pointer_unimplemented.ipp
  src/support/runtime/new_handler_fallback.ipp
  src/typeinfo.cpp

Index: src/typeinfo.cpp
===================================================================
--- src/typeinfo.cpp
+++ src/typeinfo.cpp
@@ -6,74 +6,11 @@
 // 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) || \
-    defined(_LIBCPP_ABI_MICROSOFT) // FIXME: This is a temporary workaround
+#if defined(_LIBCPP_BUILDING_HAS_NO_ABI_LIBRARY)
 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
Index: src/support/runtime/new_handler_fallback.ipp
===================================================================
--- /dev/null
+++ src/support/runtime/new_handler_fallback.ipp
@@ -0,0 +1,27 @@
+// -*- 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
Index: src/support/runtime/exception_pointer_unimplemented.ipp
===================================================================
--- /dev/null
+++ src/support/runtime/exception_pointer_unimplemented.ipp
@@ -0,0 +1,80 @@
+// -*- 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
Index: src/support/runtime/exception_pointer_glibcxx.ipp
===================================================================
--- /dev/null
+++ src/support/runtime/exception_pointer_glibcxx.ipp
@@ -0,0 +1,74 @@
+// -*- 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));
+}
Index: src/support/runtime/exception_pointer_cxxabi.ipp
===================================================================
--- /dev/null
+++ src/support/runtime/exception_pointer_cxxabi.ipp
@@ -0,0 +1,74 @@
+// -*- 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
Index: src/support/runtime/exception_msvc.ipp
===================================================================
--- /dev/null
+++ src/support/runtime/exception_msvc.ipp
@@ -0,0 +1,89 @@
+// -*- 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
Index: src/support/runtime/exception_libcxxrt.ipp
===================================================================
--- /dev/null
+++ src/support/runtime/exception_libcxxrt.ipp
@@ -0,0 +1,41 @@
+// -*- 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
Index: src/support/runtime/exception_libcxxabi.ipp
===================================================================
--- /dev/null
+++ src/support/runtime/exception_libcxxabi.ipp
@@ -0,0 +1,28 @@
+// -*- 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
Index: src/support/runtime/exception_glibcxx.ipp
===================================================================
--- /dev/null
+++ src/support/runtime/exception_glibcxx.ipp
@@ -0,0 +1,38 @@
+// -*- 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
Index: src/support/runtime/exception_fallback.ipp
===================================================================
--- /dev/null
+++ src/support/runtime/exception_fallback.ipp
@@ -0,0 +1,182 @@
+// -*- 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
Index: src/new.cpp
===================================================================
--- src/new.cpp
+++ src/new.cpp
@@ -13,27 +13,45 @@
 
 #include "new"
 
-#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
+#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
 #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
@@ -277,107 +295,5 @@
     ::operator delete[](ptr, alignment);
 }
 
-#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
+#endif // !_LIBCPP_HAS_NO_ALIGNED_ALLOCATION
+#endif // !__GLIBCXX__ && !_LIBCPP_ABI_MICROSOFT
Index: src/exception.cpp
===================================================================
--- src/exception.cpp
+++ src/exception.cpp
@@ -6,328 +6,30 @@
 // Source Licenses. See LICENSE.TXT for details.
 //
 //===----------------------------------------------------------------------===//
-#include <stdlib.h>
-#include <stdio.h>
 
 #include "exception"
 #include "new"
 
-#if defined(_LIBCPP_ABI_MICROSOFT)
-#include <eh.h>
-#include <corecrt_terminate.h>
-#elif defined(__APPLE__) && !defined(LIBCXXRT) && \
-    !defined(_LIBCPP_BUILDING_HAS_NO_ABI_LIBRARY)
+#if defined(LIBCXXRT) || defined(LIBCXX_BUILDING_LIBCXXABI) || \
+  (defined(__APPLE__) && !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)
-  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();
+#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"
 #elif defined(__GLIBCXX__)
-    rethrow_exception(reinterpret_cast<__exception_ptr::exception_ptr&>(p));
+#include "support/runtime/exception_glibcxx.ipp"
+#include "support/runtime/exception_pointer_glibcxx.ipp"
 #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();
+#include "support/runtime/exception_fallback.ipp"
+#include "support/runtime/exception_pointer_unimplemented.ipp"
 #endif
-}
-} // std
Index: include/typeinfo
===================================================================
--- include/typeinfo
+++ include/typeinfo
@@ -69,15 +69,18 @@
 #pragma GCC system_header
 #endif
 
-#if defined(_LIBCPP_NONUNIQUE_RTTI_BIT)
+#if defined(_LIBCPP_ABI_MICROSOFT)
+#include <vcruntime_typeinfo.h>
+#elif defined(_LIBCPP_NONUNIQUE_RTTI_BIT)
 #define _LIBCPP_HAS_NONUNIQUE_TYPEINFO
 #else
 #define _LIBCPP_HAS_UNIQUE_TYPEINFO
 #endif
 
 namespace std  // purposefully not using versioning namespace
 {
 
+#if !defined(_LIBCPP_ABI_MICROSOFT)
 class _LIBCPP_EXCEPTION_ABI type_info
 {
     type_info& operator=(const type_info&);
@@ -187,6 +190,8 @@
     virtual const char* what() const _NOEXCEPT;
 };
 
+#endif // !_LIBCPP_ABI_MICROSOFT
+
 }  // std
 
 _LIBCPP_BEGIN_NAMESPACE_STD
Index: include/new
===================================================================
--- include/new
+++ include/new
@@ -92,6 +92,10 @@
 #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
@@ -110,6 +114,10 @@
 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
 {
@@ -128,6 +136,12 @@
     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)
@@ -153,20 +167,16 @@
 #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)
 #define _THROW_BAD_ALLOC throw(std::bad_alloc)
 #else
 #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;
@@ -206,6 +216,8 @@
 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) {
Index: include/exception
===================================================================
--- include/exception
+++ include/exception
@@ -82,13 +82,18 @@
 #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
 
 namespace std  // purposefully not using versioning namespace
 {
 
+#if !defined(_LIBCPP_ABI_MICROSOFT)
 class _LIBCPP_EXCEPTION_ABI exception
 {
 public:
@@ -105,6 +110,7 @@
     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;
Index: CMakeLists.txt
===================================================================
--- CMakeLists.txt
+++ CMakeLists.txt
@@ -116,11 +116,19 @@
           ${LLVM_MAIN_SRC_DIR}/runtimes/libcxxabi/include
     NO_DEFAULT_PATH
   )
+  find_path(
+    LIBCXX_LIBCXXABI_INCLUDES_EXTERNAL
+    cxxabi.h
+    PATHS /usr/include
+  )
   if ((NOT LIBCXX_STANDALONE_BUILD OR HAVE_LIBCXXABI) AND
       IS_DIRECTORY "${LIBCXX_LIBCXXABI_INCLUDES_INTERNAL}")
     set(LIBCXX_CXX_ABI_LIBNAME "libcxxabi")
     set(LIBCXX_CXX_ABI_INCLUDE_PATHS "${LIBCXX_LIBCXXABI_INCLUDES_INTERNAL}")
     set(LIBCXX_CXX_ABI_INTREE 1)
+  elseif(APPLE AND IS_DIRECTORY "${LIBCXX_LIBCXXABI_INCLUDES_INTERNAL}")
+    set(LIBCXX_CXX_ABI_LIBNAME "libcxxabi")
+    set(LIBCXX_CXX_ABI_INCLUDE_PATHS "${LIBCXX_LIBCXXABI_INCLUDES_INTERNAL}")
   else()
     if (LIBCXX_TARGETING_MSVC)
       # FIXME: Figure out how to configure the ABI library on Windows.
_______________________________________________
cfe-commits mailing list
cfe-commits@lists.llvm.org
http://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits

Reply via email to