Fixes for FreeBSD, including some fairly obvious copy-and-paste errors.

libc++ now mostly works on FreeBSD with libcxxrt and this patch applied to the base system:

http://lists.freebsd.org/pipermail/freebsd-hackers/attachments/20110920/e666632c/xlocale-0001.obj

Summary of tests on FreeBSD:


****************************************************
Results for /root/libcxx/test:
using FreeBSD clang version 3.0 (trunk 135360) 20110717
Target: x86_64-unknown-freebsd9.0
Thread model: posix
with -std=c++0x -stdlib=libc++ -I/root/libcxx/include -L/root/libcxx/build/lib
----------------------------------------------------
sections without tests   : 1
sections with failures   : 48
sections without failures: 1015
                       +   ----
total number of sections : 1064
----------------------------------------------------
number of tests failed   : 145
number of tests passed   : 4179
                       +   ----
total number of tests    : 4324
****************************************************

(Many due to this clang version not supporting C++ atomics)

More fixes to follow...

llvm-svn: 140245
Cr-Mirrored-From: sso://chromium.googlesource.com/_direct/external/github.com/llvm/llvm-project
Cr-Mirrored-Commit: 89728139cbf9a73815aa3720d3bc0b740f1be197
diff --git a/src/exception.cpp b/src/exception.cpp
index 28d87b3..9a80d3e 100644
--- a/src/exception.cpp
+++ b/src/exception.cpp
@@ -13,16 +13,24 @@
 #if __APPLE__
   #include <cxxabi.h>
   using namespace __cxxabiv1;
+  using namespace __cxxabiv1::__cxxabiapple;
   // On Darwin, there are two STL shared libraries and a lower level ABI
   // shared libray.  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
+  #define HAVE_DEPENDENT_EH_ABI 1
+#elif defined(LIBCXXRT)
+  #include <cxxabi.h>
+  using namespace __cxxabiv1;
+  #define HAVE_DEPENDENT_EH_ABI 1
 #else  // __APPLE__
   static std::terminate_handler  __terminate_handler;
   static std::unexpected_handler __unexpected_handler;
 #endif  // __APPLE__
 
+#ifndef LIBCXXRT
+// libcxxrt provides implementations of these functions itself.
 std::unexpected_handler
 std::set_unexpected(std::unexpected_handler func) _NOEXCEPT
 {
@@ -76,18 +84,19 @@
     }
 #endif  // _LIBCPP_NO_EXCEPTIONS
 }
+#endif // LIBCXXRT
 
 bool std::uncaught_exception() _NOEXCEPT
 {
 #if __APPLE__
     // on Darwin, there is a helper function so __cxa_get_globals is private
     return __cxxabiapple::__cxa_uncaught_exception();
+#elif LIBCXXRT
+    __cxa_eh_globals * globals = __cxa_get_globals();
+    return (globals->uncaughtExceptions != 0);
 #else  // __APPLE__
     #warning uncaught_exception not yet implemented
     ::abort();
-    // Not provided by Ubuntu gcc-4.2.4's cxxabi.h.
-    // __cxa_eh_globals * globals = __cxa_get_globals();
-    // return (globals->uncaughtExceptions != 0);
 #endif  // __APPLE__
 }
 
@@ -114,8 +123,8 @@
 
 exception_ptr::~exception_ptr() _NOEXCEPT
 {
-#if __APPLE__
-    __cxxabiapple::__cxa_decrement_exception_refcount(__ptr_);
+#if HAVE_DEPENDENT_EH_ABI
+    __cxa_decrement_exception_refcount(__ptr_);
 #else
     #warning exception_ptr not yet implemented
     ::abort();
@@ -125,8 +134,8 @@
 exception_ptr::exception_ptr(const exception_ptr& other) _NOEXCEPT
     : __ptr_(other.__ptr_)
 {
-#if __APPLE__
-    __cxxabiapple::__cxa_increment_exception_refcount(__ptr_);
+#if HAVE_DEPENDENT_EH_ABI
+    __cxa_increment_exception_refcount(__ptr_);
 #else
     #warning exception_ptr not yet implemented
     ::abort();
@@ -135,11 +144,11 @@
 
 exception_ptr& exception_ptr::operator=(const exception_ptr& other) _NOEXCEPT
 {
-#if __APPLE__
+#if HAVE_DEPENDENT_EH_ABI
     if (__ptr_ != other.__ptr_)
     {
-        __cxxabiapple::__cxa_increment_exception_refcount(other.__ptr_);
-        __cxxabiapple::__cxa_decrement_exception_refcount(__ptr_);
+        __cxa_increment_exception_refcount(other.__ptr_);
+        __cxa_decrement_exception_refcount(__ptr_);
         __ptr_ = other.__ptr_;
     }
     return *this;
@@ -171,12 +180,12 @@
 
 std::exception_ptr std::current_exception() _NOEXCEPT
 {
-#if __APPLE__
+#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());
     std::exception_ptr ptr;
-    ptr.__ptr_ = __cxxabiapple::__cxa_current_primary_exception();
+    ptr.__ptr_ = __cxa_current_primary_exception();
     return ptr;
 #else  // __APPLE__
     #warning exception_ptr not yet implemented
@@ -186,8 +195,8 @@
 
 void std::rethrow_exception(exception_ptr p)
 {
-#if __APPLE__
-    __cxxabiapple::__cxa_rethrow_primary_exception(p.__ptr_);
+#if HAVE_DEPENDENT_EH_ABI
+    __cxa_rethrow_primary_exception(p.__ptr_);
     // if p.__ptr_ is NULL, above returns so we terminate
     terminate();
 #else  // __APPLE__