add headers and implementation for <new>, <exception>, and <typeinfo>

llvm-svn: 103795
Cr-Mirrored-From: sso://chromium.googlesource.com/_direct/external/github.com/llvm/llvm-project
Cr-Mirrored-Commit: 111e0cbe5159e1bb23c3beb60e959b656b509eab
diff --git a/src/exception.cpp b/src/exception.cpp
new file mode 100644
index 0000000..336527d
--- /dev/null
+++ b/src/exception.cpp
@@ -0,0 +1,171 @@
+//===------------------------ exception.cpp -------------------------------===//
+//
+//                     The LLVM Compiler Infrastructure
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+#include <stdlib.h>
+
+#include "exception"
+
+#if __APPLE__
+  #include <cxxabi.h>
+  using namespace __cxxabiv1;
+  // 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
+#else
+  static std::terminate_handler  __terminate_handler;
+  static std::unexpected_handler __unexpected_handler;
+#endif
+
+
+
+std::unexpected_handler 
+std::set_unexpected(std::unexpected_handler func) throw()
+{
+    std::terminate_handler old = __unexpected_handler;
+    __unexpected_handler = func;
+    return old;
+}
+
+void
+std::unexpected()
+{
+    (*__unexpected_handler)();
+	// unexpected handler should not return
+    std::terminate();
+}
+
+
+std::terminate_handler 
+std::set_terminate(std::terminate_handler func) throw()
+{
+    std::terminate_handler old = __terminate_handler;
+    __terminate_handler = func;
+    return old;
+}
+
+
+void
+std::terminate()
+{
+    try {
+        (*__terminate_handler)();
+        // handler should not return
+        ::abort ();
+    } 
+    catch (...) {
+        // handler should not throw exception
+        ::abort ();
+    }
+}
+
+
+bool std::uncaught_exception() throw()
+{
+#if __APPLE__
+	// on Darwin, there is a helper function so __cxa_get_globals is private
+    return __cxxabiapple::__cxa_uncaught_exception();
+#else
+    __cxa_eh_globals * globals = __cxa_get_globals();
+    return (globals->uncaughtExceptions != 0);
+#endif
+}
+
+
+namespace std 
+{
+
+
+exception::~exception() throw() 
+{ 
+}
+
+bad_exception::~bad_exception() throw() 
+{ 
+}
+
+const char* exception::what() const throw()
+{
+  return "std::exception";
+}
+
+const char* bad_exception::what() const throw()
+{
+  return "std::bad_exception";
+}
+
+
+
+exception_ptr::~exception_ptr()
+{
+#if __APPLE__
+    __cxxabiapple::__cxa_decrement_exception_refcount(__ptr_);
+#else
+	#warning exception_ptr not yet implemented
+	::abort();
+#endif
+}
+
+exception_ptr::exception_ptr(const exception_ptr& other)
+    : __ptr_(other.__ptr_)
+{
+#if __APPLE__
+    __cxxabiapple::__cxa_increment_exception_refcount(__ptr_);
+#else
+	#warning exception_ptr not yet implemented
+	::abort();
+#endif
+}
+
+exception_ptr& exception_ptr::operator=(const exception_ptr& other)
+{
+#if __APPLE__
+    if (__ptr_ != other.__ptr_)
+    {
+        __cxxabiapple::__cxa_increment_exception_refcount(other.__ptr_);
+        __cxxabiapple::__cxa_decrement_exception_refcount(__ptr_);
+		__ptr_ = other.__ptr_;
+	}
+    return *this;
+#else
+	#warning exception_ptr not yet implemented
+	::abort();
+#endif
+}
+
+} // std
+
+
+std::exception_ptr std::current_exception()
+{
+#if __APPLE__
+	// 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();
+	return ptr;
+#else
+	#warning exception_ptr not yet implemented
+	::abort();
+#endif
+}
+
+void std::rethrow_exception(exception_ptr p)
+{
+#if __APPLE__
+	__cxxabiapple::__cxa_rethrow_primary_exception(p.__ptr_); 
+	// if p.__ptr_ is NULL, above returns so we terminate
+    terminate(); 
+#else
+	#warning exception_ptr not yet implemented
+	::abort();
+#endif
+}
+
diff --git a/src/new.cpp b/src/new.cpp
index 32e0cbd..bc105cc 100644
--- a/src/new.cpp
+++ b/src/new.cpp
@@ -7,11 +7,136 @@
 //
 //===----------------------------------------------------------------------===//
 
+#include <stdlib.h> 
+#include <cxxabi.h> 
+
 #include "new"
 
+
+#if __APPLE__
+    // On Darwin, there are two STL shared libraries and a lower level ABI
+	// shared libray.  The global holding the current new handler is
+    // in the ABI library and named __cxa_new_handler.
+    #define __new_handler __cxxabiapple::__cxa_new_handler
+#else
+	static std::new_handler __new_handler;
+#endif
+
+
+// Implement all new and delete operators as weak definitions
+// in this shared library, so that they can be overriden by programs
+// that define non-weak copies of the functions.
+
+
+__attribute__((__weak__, __visibility__("default")))
+void *
+operator new(std::size_t size) throw (std::bad_alloc)
+{
+    if (size == 0)
+        size = 1;
+    void* p;
+    while ((p = ::malloc(size)) == 0)
+    {
+		// If malloc fails and there is a new_handler, 
+		// call it to try free up memory.
+        if (__new_handler)
+            __new_handler();
+        else
+            throw std::bad_alloc();
+    }
+    return p;
+}
+
+__attribute__((__weak__, __visibility__("default")))
+void*
+operator new(size_t size, const std::nothrow_t&) throw()
+{
+    void* p = 0;
+    try
+    {
+        p = ::operator new(size);
+    }
+    catch (...)
+    {
+    }
+    return p;
+}
+
+__attribute__((__weak__, __visibility__("default")))
+void*
+operator new[](size_t size) throw (std::bad_alloc)
+{
+    return ::operator new(size);
+}
+
+__attribute__((__weak__, __visibility__("default")))
+void*
+operator new[](size_t size, const std::nothrow_t& nothrow) throw()
+{
+    void* p = 0;
+    try
+    {
+        p = ::operator new[](size);
+    }
+    catch (...)
+    {
+    }
+    return p;
+}
+
+__attribute__((__weak__, __visibility__("default")))
+void
+operator delete(void* ptr) throw ()
+{
+    if (ptr)
+        ::free(ptr);
+}
+
+__attribute__((__weak__, __visibility__("default")))
+void
+operator delete(void* ptr, const std::nothrow_t&) throw ()
+{
+    ::operator delete(ptr);
+}
+
+
+__attribute__((__weak__, __visibility__("default")))
+void
+operator delete[] (void* ptr) throw ()
+{
+    ::operator delete (ptr);
+}
+
+__attribute__((__weak__, __visibility__("default")))
+void
+operator delete[] (void* ptr, const std::nothrow_t&) throw ()
+{
+    ::operator delete[](ptr);
+}
+
+
 namespace std
 {
 
+bad_alloc::bad_alloc() throw() 
+{ 
+}
+
+bad_alloc::~bad_alloc() throw() 
+{ 
+}
+
+const char* 
+bad_alloc::what() const throw()
+{
+    return "std::bad_alloc";
+}
+
+
+bad_array_new_length::bad_array_new_length() throw()
+{
+}
+
 bad_array_new_length::~bad_array_new_length() throw()
 {
 }
@@ -22,6 +147,8 @@
     return "bad_array_new_length";
 }
 
+
+
 void
 __throw_bad_alloc()
 {
diff --git a/src/typeinfo.cpp b/src/typeinfo.cpp
new file mode 100644
index 0000000..8606897
--- /dev/null
+++ b/src/typeinfo.cpp
@@ -0,0 +1,41 @@
+//===------------------------- typeinfo.cpp -------------------------------===//
+//
+//                     The LLVM Compiler Infrastructure
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+#include <stdlib.h>
+
+#include "typeinfo"
+
+std::bad_cast::bad_cast() throw() 
+{ 
+}
+
+std::bad_cast::~bad_cast() throw() 
+{ 
+}
+
+const char* 
+std::bad_cast::what() const throw()
+{
+  return "std::bad_cast";
+}
+
+
+std::bad_typeid::bad_typeid() throw() 
+{ 
+}
+
+std::bad_typeid::~bad_typeid() throw() 
+{
+}
+
+const char* 
+std::bad_typeid::what() const throw()
+{
+  return "std::bad_typeid";
+}
+