Merge "Push the test executables just before we run it."
diff --git a/build/tools/build-gcc.sh b/build/tools/build-gcc.sh
index 5cd3411..55504a7 100755
--- a/build/tools/build-gcc.sh
+++ b/build/tools/build-gcc.sh
@@ -84,8 +84,8 @@
set_parameters ()
{
- SRC_DIR="$1"
- NDK_DIR="$2"
+ SRC_DIR=`cd $1; pwd`
+ NDK_DIR=`cd $2; pwd`
TOOLCHAIN="$3"
# Check source directory
diff --git a/build/tools/build-gnu-libstdc++.sh b/build/tools/build-gnu-libstdc++.sh
index 927cb86..a6b0c62 100755
--- a/build/tools/build-gnu-libstdc++.sh
+++ b/build/tools/build-gnu-libstdc++.sh
@@ -165,6 +165,7 @@
fi
export CFLAGS="-fPIC $CFLAGS --sysroot=$SYSROOT -fexceptions -funwind-tables -D__BIONIC__ -O2 $EXTRA_FLAGS"
export CXXFLAGS="-fPIC $CXXFLAGS --sysroot=$SYSROOT -fexceptions -frtti -funwind-tables -D__BIONIC__ -O2 $EXTRA_FLAGS"
+ export CPPFLAGS="$CPPFLAGS --sysroot=$SYSROOT"
export CC=${BINPREFIX}gcc
export CXX=${BINPREFIX}g++
diff --git a/build/tools/build-llvm.sh b/build/tools/build-llvm.sh
index 0b98c91..b80db6f 100755
--- a/build/tools/build-llvm.sh
+++ b/build/tools/build-llvm.sh
@@ -69,8 +69,8 @@
set_parameters ()
{
- SRC_DIR="$1"
- NDK_DIR="$2"
+ SRC_DIR=`cd $1; pwd`
+ NDK_DIR=`cd $2; pwd`
TOOLCHAIN="$3"
# Check source directory
diff --git a/build/tools/build-stlport.sh b/build/tools/build-stlport.sh
index c319849..c84f71d 100755
--- a/build/tools/build-stlport.sh
+++ b/build/tools/build-stlport.sh
@@ -155,6 +155,7 @@
local BUILDDIR="$2"
local TYPE="$3"
local DSTDIR="$4"
+ local DEFAULT_CFLAGS DEFAULT_CXXLAGS
local SRC OBJ OBJECTS CFLAGS CXXFLAGS
mkdir -p "$BUILDDIR"
@@ -171,23 +172,26 @@
builder_set_dstdir "$DSTDIR"
builder_set_srcdir "$GABIXX_SRCDIR"
- builder_cflags "$GABIXX_CFLAGS"
+ builder_reset_cflags DEFAULT_CFLAGS
+
+ builder_cflags "$DEFAULT_CFLAGS $GABIXX_CFLAGS"
+ builder_reset_cxxflags DEFAULT_CXXLAGS
if [ "$TYPE" = "static" -a -z "$VISIBLE_LIBSTLPORT_STATIC" ]; then
- builder_cxxflags "$GABIXX_CXXFLAGS -fvisibility=hidden -fvisibility-inlines-hidden"
+ builder_cxxflags "$DEFAULT_CXXLAGS $GABIXX_CXXFLAGS -fvisibility=hidden -fvisibility-inlines-hidden"
else
- builder_cxxflags "$GABIXX_CXXFLAGS"
+ builder_cxxflags "$DEFAULT_CXXLAGS $GABIXX_CXXFLAGS"
fi
builder_ldflags "$GABIXX_LDFLAGS"
builder_sources $GABIXX_SOURCES
builder_set_srcdir "$STLPORT_SRCDIR"
builder_reset_cflags
- builder_cflags "$STLPORT_CFLAGS"
+ builder_cflags "$DEFAULT_CFLAGS $STLPORT_CFLAGS"
builder_reset_cxxflags
if [ "$TYPE" = "static" -a -z "$VISIBLE_LIBSTLPORT_STATIC" ]; then
- builder_cxxflags "$STLPORT_CXXFLAGS -fvisibility=hidden -fvisibility-inlines-hidden"
+ builder_cxxflags "$DEFAULT_CXXLAGS $STLPORT_CXXFLAGS -fvisibility=hidden -fvisibility-inlines-hidden"
else
- builder_cxxflags "$STLPORT_CXXFLAGS"
+ builder_cxxflags "$DEFAULT_CXXLAGS $STLPORT_CXXFLAGS"
fi
builder_sources $STLPORT_SOURCES
diff --git a/build/tools/builder-funcs.sh b/build/tools/builder-funcs.sh
index 2c0a6c4..5afc054 100644
--- a/build/tools/builder-funcs.sh
+++ b/build/tools/builder-funcs.sh
@@ -171,18 +171,33 @@
_builder_varadd _BUILD_C_INCLUDES "$@"
}
+# $1: optional var to hold the original cflags before reset
builder_reset_cflags ()
{
+ local _varname="$1"
+ if [ -n "$_varname" ] ; then
+ eval $_varname=\"$_BUILD_CFLAGS\"
+ fi
_BUILD_CFLAGS=
}
+# $1: optional var to hold the original cxxflags before reset
builder_reset_cxxflags ()
{
+ local _varname="$1"
+ if [ -n "$_varname" ] ; then
+ eval $_varname=\"$_BUILD_CXXFLAGS\"
+ fi
_BUILD_CXXFLAGS=
}
+# $1: optional var to hold the original c_includes before reset
builder_reset_c_includes ()
{
+ local _varname="$1"
+ if [ -n "$_varname" ] ; then
+ eval $_varname=\"$_BUILD_C_INCLUDES\"
+ fi
_BUILD_C_INCLUDES=
}
@@ -460,7 +475,7 @@
;;
armeabi-v7a)
builder_cflags "-mthumb -march=armv7-a -mfloat-abi=softfp -mfpu=vfpv3-d16"
- builder_ldflags "-Wl,--fix-cortex-a8"
+ builder_ldflags "-march=armv7-a -Wl,--fix-cortex-a8"
;;
esac
}
diff --git a/sources/cxx-stl/gabi++/include/cxxabi.h b/sources/cxx-stl/gabi++/include/cxxabi.h
index c6a4f8a..958a9de 100644
--- a/sources/cxx-stl/gabi++/include/cxxabi.h
+++ b/sources/cxx-stl/gabi++/include/cxxabi.h
@@ -37,39 +37,47 @@
{
// Derived types of type_info below are based on 2.9.5 of C++ ABI.
+ class __shim_type_info : public std::type_info
+ {
+ public:
+ virtual ~__shim_type_info();
+ virtual bool can_catch(const __shim_type_info* thrown_type,
+ void*& adjustedPtr) const = 0;
+ };
+
// Typeinfo for fundamental types.
- class __fundamental_type_info : public std::type_info
+ class __fundamental_type_info : public __shim_type_info
{
public:
virtual ~__fundamental_type_info();
- virtual bool can_catch(const std::type_info* thrown_type,
+ virtual bool can_catch(const __shim_type_info* thrown_type,
void*& adjustedPtr) const;
};
// Typeinfo for array types.
- class __array_type_info : public std::type_info
+ class __array_type_info : public __shim_type_info
{
public:
virtual ~__array_type_info();
- virtual bool can_catch(const std::type_info* thrown_type,
+ virtual bool can_catch(const __shim_type_info* thrown_type,
void*& adjustedPtr) const;
};
// Typeinfo for function types.
- class __function_type_info : public std::type_info
+ class __function_type_info : public __shim_type_info
{
public:
virtual ~__function_type_info();
- virtual bool can_catch(const std::type_info* thrown_type,
+ virtual bool can_catch(const __shim_type_info* thrown_type,
void*& adjustedPtr) const;
};
// Typeinfo for enum types.
- class __enum_type_info : public std::type_info
+ class __enum_type_info : public __shim_type_info
{
public:
virtual ~__enum_type_info();
- virtual bool can_catch(const std::type_info* thrown_type,
+ virtual bool can_catch(const __shim_type_info* thrown_type,
void*& adjustedPtr) const;
};
@@ -127,12 +135,12 @@
};
// Typeinfo for classes with no bases.
- class __class_type_info : public std::type_info
+ class __class_type_info : public __shim_type_info
{
public:
virtual ~__class_type_info();
- virtual bool can_catch(const std::type_info* thrown_type,
- void*& adjustedPtr) const;
+ virtual bool can_catch(const __shim_type_info* thrown_type,
+ void*& adjustedPtr) const;
enum class_type_info_code {
CLASS_TYPE_INFO_CODE,
@@ -193,14 +201,14 @@
__UpcastInfo& info) const;
};
- class __pbase_type_info : public std::type_info
+ class __pbase_type_info : public __shim_type_info
{
public:
virtual ~__pbase_type_info();
- virtual bool can_catch(const std::type_info* thrown_type,
- void*& adjustedPtr) const;
+ virtual bool can_catch(const __shim_type_info* thrown_type,
+ void*& adjustedPtr) const;
unsigned int __flags;
- const std::type_info *__pointee;
+ const __shim_type_info* __pointee;
enum __masks {
__const_mask = 0x1,
@@ -211,7 +219,7 @@
};
- virtual bool can_catch_typeinfo_wrapper(const std::type_info* thrown_type,
+ virtual bool can_catch_typeinfo_wrapper(const __shim_type_info* thrown_type,
void*& adjustedPtr,
unsigned tracker) const;
@@ -271,6 +279,8 @@
// TODO: Support C++0x exception propagation
// http://sourcery.mentor.com/archives/cxx-abi-dev/msg01924.html
struct __cxa_exception {
+ size_t referenceCount;
+
std::type_info* exceptionType;
void (*exceptionDestructor)(void*);
std::unexpected_handler unexpectedHandler;
@@ -334,18 +344,12 @@
void __cxa_pure_virtual();
-#ifdef __arm__
- typedef enum {
- ctm_failed = 0,
- ctm_succeeded = 1,
- ctm_succeeded_with_ptr_to_base = 2
- } __cxa_type_match_result;
-
- __cxa_type_match_result __cxa_type_match(_Unwind_Control_Block* ucbp,
- const std::type_info* rttip,
- bool is_reference_type,
- void** matched_object);
-#endif
+ // Missing libcxxabi functions.
+ bool __cxa_uncaught_exception() throw();
+ void __cxa_decrement_exception_refcount(void* exceptionObject) throw();
+ void __cxa_increment_exception_refcount(void* exceptionObject) throw();
+ void __cxa_rethrow_primary_exception(void* exceptionObject);
+ void* __cxa_current_primary_exception() throw();
} // extern "C"
diff --git a/sources/cxx-stl/gabi++/include/exception b/sources/cxx-stl/gabi++/include/exception
index 53b1ab9..d4019ce 100644
--- a/sources/cxx-stl/gabi++/include/exception
+++ b/sources/cxx-stl/gabi++/include/exception
@@ -28,6 +28,8 @@
#ifndef __GABIXX_EXCEPTION__
#define __GABIXX_EXCEPTION__
+#if !defined(GABIXX_LIBCXX)
+
namespace std {
class exception {
@@ -56,18 +58,8 @@
bool uncaught_exception() throw();
- /*
- * Below APIs are used internally
- */
- void __terminate(terminate_handler);
- void __unexpected(unexpected_handler);
-
- extern terminate_handler default_terminate_fn;
- extern terminate_handler current_terminate_fn;
-
- extern unexpected_handler default_unexpected_fn;
- extern unexpected_handler current_unexpected_fn;
-
} // namespace std
+#endif // !defined(GABIXX_LIBCXX)
+
#endif // __GABIXX_EXCEPTION__
diff --git a/sources/cxx-stl/gabi++/include/new b/sources/cxx-stl/gabi++/include/new
index f026b1c..d66fef7 100644
--- a/sources/cxx-stl/gabi++/include/new
+++ b/sources/cxx-stl/gabi++/include/new
@@ -30,6 +30,8 @@
#ifndef __GABIXX_NEW__
#define __GABIXX_NEW__
+#if !defined(GABIXX_LIBCXX)
+
#include <cstddef>
#include <exception>
@@ -46,6 +48,9 @@
virtual const char* what() const throw();
};
+typedef void (*new_handler)();
+new_handler set_new_handler(new_handler) throw();
+
}
void* operator new(std::size_t size) throw(std::bad_alloc);
@@ -63,4 +68,6 @@
inline void operator delete(void*, void*) throw() {}
inline void operator delete[](void*, void*) throw() {}
+#endif // !defined(GABIXX_LIBCXX)
+
#endif // __GABIXX_NEW__
diff --git a/sources/cxx-stl/gabi++/include/typeinfo b/sources/cxx-stl/gabi++/include/typeinfo
index 3d03179..486eb40 100644
--- a/sources/cxx-stl/gabi++/include/typeinfo
+++ b/sources/cxx-stl/gabi++/include/typeinfo
@@ -35,6 +35,8 @@
#ifndef __GABIXX_TYPEINFO__
#define __GABIXX_TYPEINFO__
+#if !defined(GABIXX_LIBCXX)
+
#include <exception>
namespace std
@@ -63,9 +65,6 @@
return (__type_name[0] == '*') ? __type_name + 1 : __type_name;
}
- virtual bool can_catch(const type_info* thrown_type,
- void*& adjustedPtr) const = 0;
-
private:
// Assignment of type_info is not allowed.
type_info (const type_info& rhs);
@@ -94,4 +93,6 @@
} // namespace std
+#endif // !defined(GABIXX_LIBCXX)
+
#endif // _GABIXX_TYPEINFO_
diff --git a/sources/cxx-stl/gabi++/src/array_type_info.cc b/sources/cxx-stl/gabi++/src/array_type_info.cc
index 7eb11a6..302c5ae 100644
--- a/sources/cxx-stl/gabi++/src/array_type_info.cc
+++ b/sources/cxx-stl/gabi++/src/array_type_info.cc
@@ -35,7 +35,7 @@
{
}
- bool __array_type_info::can_catch(const std::type_info* thrown_type,
+ bool __array_type_info::can_catch(const __shim_type_info* thrown_type,
void*& adjustedPtr) const {
// Thrown array will be decayed to pointer, we cannot convert it back
return false;
diff --git a/sources/cxx-stl/gabi++/src/call_unexpected.cc b/sources/cxx-stl/gabi++/src/call_unexpected.cc
index 28c7076..ae5bd4c 100644
--- a/sources/cxx-stl/gabi++/src/call_unexpected.cc
+++ b/sources/cxx-stl/gabi++/src/call_unexpected.cc
@@ -63,6 +63,7 @@
*/
+#include <cstdlib>
#include <cxxabi.h>
#include <unwind.h>
#include "dwarf_helper.h"
@@ -71,34 +72,65 @@
namespace __cxxabiv1 {
#ifdef __arm__
- extern "C" __cxa_type_match_result __cxa_type_match(_Unwind_Exception* ucbp,
- const std::type_info* rttip,
- bool is_reference_type,
- void** matched_object) {
- __cxa_exception* header = reinterpret_cast<__cxa_exception*>(ucbp+1)-1;
- __cxa_type_match_result result = ctm_succeeded;
+extern "C" enum type_match_result {
+ ctm_failed = 0,
+ ctm_succeeded = 1,
+ ctm_succeeded_with_ptr_to_base = 2
+};
- void* adjustedPtr = header+1;
- if (dynamic_cast<const __pointer_type_info*>(header->exceptionType)) {
- adjustedPtr = *reinterpret_cast<void**>(adjustedPtr);
- result = ctm_succeeded_with_ptr_to_base;
- }
- const std::type_info* catch_type = rttip;
- const std::type_info* thrown_type = header->exceptionType;
- if (!catch_type || !thrown_type) {
- return ctm_failed;
- }
+extern "C" type_match_result __attribute__((visibility("default")))
+__cxa_type_match(_Unwind_Exception* ucbp,
+ const __shim_type_info* rttip,
+ bool is_reference_type,
+ void** matched_object) {
- if (catch_type->can_catch(thrown_type, adjustedPtr)) {
- *matched_object = adjustedPtr;
- return result;
- }
+ __cxa_exception* header = reinterpret_cast<__cxa_exception*>(ucbp+1)-1;
+ type_match_result result = ctm_succeeded;
+ void* adjustedPtr = header+1;
+ if (dynamic_cast<const __pointer_type_info*>(header->exceptionType)) {
+ adjustedPtr = *reinterpret_cast<void**>(adjustedPtr);
+ result = ctm_succeeded_with_ptr_to_base;
+ }
+
+ const __shim_type_info* catch_type = rttip;
+ const __shim_type_info* thrown_type =
+ static_cast<const __shim_type_info*>(header->exceptionType);
+ if (!catch_type || !thrown_type) {
return ctm_failed;
}
- extern "C" bool __cxa_begin_cleanup(_Unwind_Exception* exc) {
+ if (catch_type->can_catch(thrown_type, adjustedPtr)) {
+ *matched_object = adjustedPtr;
+ return result;
+ }
+
+ return ctm_failed;
+}
+#endif // __arm__
+
+namespace {
+
+void terminate_helper(std::terminate_handler t_handler) {
+ try {
+ t_handler();
+ abort();
+ } catch (...) {
+ abort();
+ }
+}
+
+void unexpected_helper(std::unexpected_handler u_handler) {
+ u_handler();
+ std::terminate();
+}
+
+} // namespace
+
+#ifdef __arm__
+ extern "C" bool __attribute__((visibility("default")))
+ __cxa_begin_cleanup(_Unwind_Exception* exc) {
__cxa_eh_globals *globals = __cxa_get_globals();
__cxa_exception *header = reinterpret_cast<__cxa_exception*>(exc+1)-1;
bool native = header->unwindHeader.exception_class == __gxx_exception_class;
@@ -150,7 +182,8 @@
".popsection \n"
);
- extern "C" void __cxa_call_unexpected(void* arg) {
+ extern "C" void __attribute__((visibility("default")))
+ __cxa_call_unexpected(void* arg) {
_Unwind_Exception* unwind_exception = static_cast<_Unwind_Exception*>(arg);
__cxa_exception* header = reinterpret_cast<__cxa_exception*>(unwind_exception+1)-1;
bool native_exception = unwind_exception->exception_class == __gxx_exception_class;
@@ -174,7 +207,7 @@
__cxa_begin_catch(unwind_exception); // unexpected is also a handler
try {
- std::__unexpected(header->unexpectedHandler);
+ unexpected_helper(header->unexpectedHandler);
} catch (...) {
// A new exception thrown when calling unexpected.
bool allow_bad_exception = false;
@@ -182,7 +215,7 @@
for (uint32_t i = 0; i != count; ++i) {
uint32_t offset = reinterpret_cast<uint32_t>(&list[i * (stride >> 2)]);
offset = decodeRelocTarget2(offset);
- const std::type_info* catch_type = reinterpret_cast<const std::type_info*>(offset);
+ const __shim_type_info* catch_type = reinterpret_cast<const __shim_type_info*>(offset);
__cxa_exception* new_header = __cxa_get_globals()->caughtExceptions;
void* adjustedPtr = new_header + 1;
@@ -194,7 +227,9 @@
}
void* null_adjustedPtr = NULL;
- if (catch_type->can_catch(&typeid(std::bad_exception), null_adjustedPtr)) {
+ const __shim_type_info* bad_excp =
+ static_cast<const __shim_type_info*>(&typeid(std::bad_exception));
+ if (catch_type->can_catch(bad_excp, null_adjustedPtr)) {
allow_bad_exception = true;
}
}
@@ -206,11 +241,12 @@
throw std::bad_exception();
}
- std::__terminate(header->terminateHandler);
+ terminate_helper(header->terminateHandler);
}
}
#else // ! __arm__
- extern "C" void __cxa_call_unexpected(void* arg) {
+ extern "C" void __attribute__((visibility("default")))
+ __cxa_call_unexpected(void* arg) {
_Unwind_Exception* unwind_exception = static_cast<_Unwind_Exception*>(arg);
if (unwind_exception == 0) {
call_terminate(unwind_exception);
@@ -227,7 +263,7 @@
old_exception_header = reinterpret_cast<__cxa_exception*>(unwind_exception+1)-1;
t_handler = old_exception_header->terminateHandler;
u_handler = old_exception_header->unexpectedHandler;
- // If std::__unexpected(u_handler) rethrows the same exception,
+ // If unexpected_helper(u_handler) rethrows the same exception,
// these values get overwritten by the rethrow. So save them now:
ttypeIndex = old_exception_header->handlerSwitchValue;
lsda = old_exception_header->languageSpecificData;
@@ -237,7 +273,7 @@
}
try {
- std::__unexpected(u_handler);
+ unexpected_helper(u_handler);
} catch (...) {
// A new exception thrown when calling unexpected.
@@ -248,14 +284,14 @@
const uint8_t* lpStart = (const uint8_t*)readEncodedPointer(&lsda, lpStartEncoding);
uint8_t ttypeEncoding = *lsda++;
if (ttypeEncoding == DW_EH_PE_omit) {
- std::__terminate(t_handler);
+ terminate_helper(t_handler);
}
uintptr_t classInfoOffset = readULEB128(&lsda);
const uint8_t* classInfo = lsda + classInfoOffset;
__cxa_eh_globals* globals = __cxa_get_globals_fast();
__cxa_exception* new_exception_header = globals->caughtExceptions;
if (new_exception_header == 0) { // This shouldn't be able to happen!
- std::__terminate(t_handler);
+ terminate_helper(t_handler);
}
bool native_new_exception =
new_exception_header->unwindHeader.exception_class == __gxx_exception_class;
@@ -289,7 +325,7 @@
} // catch (...)
// Call terminate after unexpected normally done
- std::__terminate(t_handler);
+ terminate_helper(t_handler);
}
#endif // __arm__
diff --git a/sources/cxx-stl/gabi++/src/class_type_info.cc b/sources/cxx-stl/gabi++/src/class_type_info.cc
index 6131fce..c2eabfa 100644
--- a/sources/cxx-stl/gabi++/src/class_type_info.cc
+++ b/sources/cxx-stl/gabi++/src/class_type_info.cc
@@ -35,7 +35,7 @@
{
}
- bool __class_type_info::can_catch(const std::type_info* thrown_type,
+ bool __class_type_info::can_catch(const __shim_type_info* thrown_type,
void*& adjustedPtr) const {
if (*this == *thrown_type) {
return true;
diff --git a/sources/cxx-stl/gabi++/src/cxxabi.cc b/sources/cxx-stl/gabi++/src/cxxabi.cc
index 60d1884..318fe5b 100644
--- a/sources/cxx-stl/gabi++/src/cxxabi.cc
+++ b/sources/cxx-stl/gabi++/src/cxxabi.cc
@@ -112,11 +112,11 @@
__cxa_thread_info *info = CxaThreadKey::getSlow();
header->unexpectedHandler = info->unexpectedHandler;
if (!header->unexpectedHandler) {
- header->unexpectedHandler = std::current_unexpected_fn;
+ header->unexpectedHandler = std::get_unexpected();
}
header->terminateHandler = info->terminateHandler;
if (!header->terminateHandler) {
- header->terminateHandler = std::current_terminate_fn;
+ header->terminateHandler = std::get_terminate();
}
info->globals.uncaughtExceptions += 1;
@@ -130,6 +130,8 @@
namespace __cxxabiv1 {
+ __shim_type_info::~__shim_type_info() {
+ }
extern "C" void __cxa_pure_virtual() {
fatalError("Pure virtual function called!");
@@ -268,4 +270,51 @@
return header->adjustedPtr;
}
+ extern "C" bool __cxa_uncaught_exception() throw() {
+ __cxa_eh_globals* globals = __cxa_get_globals();
+ if (globals == NULL)
+ return false;
+ return globals->uncaughtExceptions == 0;
+ }
+
+ extern "C" void __cxa_decrement_exception_refcount(void* exceptionObject) throw() {
+ if (exceptionObject != NULL)
+ {
+ __cxa_exception* header =
+ reinterpret_cast<__cxa_exception*>(
+ reinterpret_cast<_Unwind_Exception *>(exceptionObject)+1)-1;
+ if (__sync_sub_and_fetch(&header->referenceCount, 1) == 0) {
+ if (header->exceptionDestructor)
+ header->exceptionDestructor(exceptionObject);
+ __cxa_free_exception(exceptionObject);
+ }
+ }
+ }
+
+ extern "C" void __cxa_increment_exception_refcount(void* exceptionObject) throw() {
+ if (exceptionObject != NULL)
+ {
+ __cxa_exception* header =
+ reinterpret_cast<__cxa_exception*>(
+ reinterpret_cast<_Unwind_Exception *>(exceptionObject)+1)-1;
+ __sync_add_and_fetch(&header->referenceCount, 1);
+ }
+ }
+
+ extern "C" void __cxa_rethrow_primary_exception(void* primary_exception) {
+#if defined(GABIXX_LIBCXX)
+// Only warn if we're building for libcxx since other libraries do not use
+// this.
+#warning "not implemented."
+#endif /* defined(GABIXX_LIBCXX) */
+ }
+
+ extern "C" void* __cxa_current_primary_exception() throw() {
+#if defined(GABIXX_LIBCXX)
+// Only warn if we're building for libcxx since other libraries do not use
+// this.
+#warning "not implemented."
+#endif /* defined(GABIXX_LIBCXX) */
+ }
+
} // namespace __cxxabiv1
diff --git a/sources/cxx-stl/gabi++/src/enum_type_info.cc b/sources/cxx-stl/gabi++/src/enum_type_info.cc
index f6bb61b..c99b4c5 100644
--- a/sources/cxx-stl/gabi++/src/enum_type_info.cc
+++ b/sources/cxx-stl/gabi++/src/enum_type_info.cc
@@ -35,8 +35,8 @@
{
}
- bool __enum_type_info::can_catch(const std::type_info* thrown_type,
- void*& adjustedPtr) const {
+ bool __enum_type_info::can_catch(const __shim_type_info* thrown_type,
+ void*& adjustedPtr) const {
return *this == *thrown_type;
}
} // namespace __cxxabiv1
diff --git a/sources/cxx-stl/gabi++/src/function_type_info.cc b/sources/cxx-stl/gabi++/src/function_type_info.cc
index ca0daa6..a8d7164 100644
--- a/sources/cxx-stl/gabi++/src/function_type_info.cc
+++ b/sources/cxx-stl/gabi++/src/function_type_info.cc
@@ -35,8 +35,8 @@
{
}
- bool __function_type_info::can_catch(const std::type_info* thrown_type,
- void*& adjustedPtr) const {
+ bool __function_type_info::can_catch(const __shim_type_info* thrown_type,
+ void*& adjustedPtr) const {
// Thrown function will be converted to pointer, cannot convert it back
return false;
}
diff --git a/sources/cxx-stl/gabi++/src/fundamental_type_info.cc b/sources/cxx-stl/gabi++/src/fundamental_type_info.cc
index 6b28d2c..026a87a 100644
--- a/sources/cxx-stl/gabi++/src/fundamental_type_info.cc
+++ b/sources/cxx-stl/gabi++/src/fundamental_type_info.cc
@@ -35,7 +35,7 @@
{
}
- bool __fundamental_type_info::can_catch(const std::type_info* thrown_type,
+ bool __fundamental_type_info::can_catch(const __shim_type_info* thrown_type,
void*& adjustedPtr) const {
return *this == *thrown_type;
}
diff --git a/sources/cxx-stl/gabi++/src/helper_func_internal.cc b/sources/cxx-stl/gabi++/src/helper_func_internal.cc
index 8425327..848f8de 100644
--- a/sources/cxx-stl/gabi++/src/helper_func_internal.cc
+++ b/sources/cxx-stl/gabi++/src/helper_func_internal.cc
@@ -48,6 +48,11 @@
namespace __cxxabiv1 {
+ const __shim_type_info* getTypePtr(uint64_t ttypeIndex,
+ const uint8_t* classInfo,
+ uint8_t ttypeEncoding,
+ _Unwind_Exception* unwind_exception);
+
void call_terminate(_Unwind_Exception* unwind_exception) {
__cxa_begin_catch(unwind_exception); // terminate is also a handler
std::terminate();
@@ -147,7 +152,7 @@
if (ttypeIndex > 0) {
// Found a catch, does it actually catch?
// First check for catch (...)
- const std::type_info* catchType =
+ const __shim_type_info* catchType =
getTypePtr(static_cast<uint64_t>(ttypeIndex),
classInfo, ttypeEncoding, unwind_exception);
if (catchType == 0) {
@@ -171,7 +176,8 @@
} else if (native_exception) {
__cxa_exception* exception_header = (__cxa_exception*)(unwind_exception+1) - 1;
void* adjustedPtr = unwind_exception+1;
- const std::type_info* excpType = exception_header->exceptionType;
+ const __shim_type_info* excpType =
+ static_cast<const __shim_type_info*>(exception_header->exceptionType);
if (adjustedPtr == 0 || excpType == 0) {
// Such a disaster! What's wrong?
call_terminate(unwind_exception);
@@ -297,15 +303,15 @@
return tmp;
}
- const std::type_info* getTypePtr(uint64_t ttypeIndex,
- const uint8_t* classInfo,
- uint8_t ttypeEncoding,
- _Unwind_Exception* unwind_exception) {
+ const __shim_type_info* getTypePtr(uint64_t ttypeIndex,
+ const uint8_t* classInfo,
+ uint8_t ttypeEncoding,
+ _Unwind_Exception* unwind_exception) {
if (classInfo == 0) { // eh table corrupted!
call_terminate(unwind_exception);
}
const uint8_t* ptr = classInfo - ttypeIndex * 4;
- return (const std::type_info*)decodeRelocTarget2((uint32_t)ptr);
+ return (const __shim_type_info*)decodeRelocTarget2((uint32_t)ptr);
}
bool canExceptionSpecCatch(int64_t specIndex,
@@ -329,9 +335,10 @@
}
ttypeIndex = decodeRelocTarget2((uint32_t)temp);
temp += 1;
- const std::type_info* catchType = (const std::type_info*) ttypeIndex;
+ const __shim_type_info* catchType = (const __shim_type_info*) ttypeIndex;
void* tempPtr = adjustedPtr;
- if (catchType->can_catch(excpType, tempPtr)) {
+ if (catchType->can_catch(
+ static_cast<const __shim_type_info*>(excpType), tempPtr)) {
return false;
}
} // while
@@ -409,10 +416,10 @@
#else // ! __arm__
- const std::type_info* getTypePtr(uint64_t ttypeIndex,
- const uint8_t* classInfo,
- uint8_t ttypeEncoding,
- _Unwind_Exception* unwind_exception) {
+ const __shim_type_info* getTypePtr(uint64_t ttypeIndex,
+ const uint8_t* classInfo,
+ uint8_t ttypeEncoding,
+ _Unwind_Exception* unwind_exception) {
if (classInfo == 0) { // eh table corrupted!
call_terminate(unwind_exception);
}
@@ -438,7 +445,7 @@
call_terminate(unwind_exception);
}
classInfo -= ttypeIndex;
- return (const std::type_info*)readEncodedPointer(&classInfo, ttypeEncoding);
+ return (const __shim_type_info*)readEncodedPointer(&classInfo, ttypeEncoding);
}
bool canExceptionSpecCatch(int64_t specIndex,
@@ -460,12 +467,13 @@
if (ttypeIndex == 0) {
break;
}
- const std::type_info* catchType = getTypePtr(ttypeIndex,
- classInfo,
- ttypeEncoding,
- unwind_exception);
+ const __shim_type_info* catchType = getTypePtr(ttypeIndex,
+ classInfo,
+ ttypeEncoding,
+ unwind_exception);
void* tempPtr = adjustedPtr;
- if (catchType->can_catch(excpType, tempPtr)) {
+ if (catchType->can_catch(
+ static_cast<const __shim_type_info*>(excpType), tempPtr)) {
return false;
}
} // while
diff --git a/sources/cxx-stl/gabi++/src/helper_func_internal.h b/sources/cxx-stl/gabi++/src/helper_func_internal.h
index 2b0a189..c01681e 100644
--- a/sources/cxx-stl/gabi++/src/helper_func_internal.h
+++ b/sources/cxx-stl/gabi++/src/helper_func_internal.h
@@ -42,11 +42,6 @@
uint32_t decodeRelocTarget2 (uint32_t ptr);
#endif
- const std::type_info* getTypePtr(uint64_t ttypeIndex,
- const uint8_t* classInfo,
- uint8_t ttypeEncoding,
- _Unwind_Exception* unwind_exception);
-
// An exception spec acts like a catch handler, but in reverse.
// If any catchType in the list can catch an excpType,
// then this exception spec does not catch the excpType.
diff --git a/sources/cxx-stl/gabi++/src/new.cc b/sources/cxx-stl/gabi++/src/new.cc
index 6008900..f65a291 100644
--- a/sources/cxx-stl/gabi++/src/new.cc
+++ b/sources/cxx-stl/gabi++/src/new.cc
@@ -29,9 +29,16 @@
#include <stdlib.h>
#include <new>
+using std::new_handler;
+namespace {
+ new_handler cur_handler;
+}
+
namespace std {
+#if !defined(GABIXX_LIBCXX)
const nothrow_t nothrow = {};
+#endif // !defined(GABIXX_LIBCXX)
bad_alloc::bad_alloc() throw() {
}
@@ -43,21 +50,37 @@
return "std::bad_alloc";
}
+ new_handler set_new_handler(new_handler next_handler) throw() {
+ new_handler old_handler = cur_handler;
+ cur_handler = next_handler;
+ return old_handler;
+ }
+
} // namespace std
__attribute__ ((weak))
void* operator new(std::size_t size) throw(std::bad_alloc) {
- void* space = ::operator new(size, std::nothrow_t());
- if (space) {
- return space;
- } else {
- throw std::bad_alloc();
- }
+ void* space;
+ do {
+ space = malloc(size);
+ if (space) {
+ return space;
+ }
+ new_handler handler = cur_handler;
+ if (handler == NULL) {
+ throw std::bad_alloc();
+ }
+ handler();
+ } while (space == 0);
}
__attribute__ ((weak))
void* operator new(std::size_t size, const std::nothrow_t& no) throw() {
- return malloc(size);
+ try {
+ ::operator new(size);
+ } catch (const std::bad_alloc&) {
+ return 0;
+ }
}
__attribute__ ((weak))
@@ -67,5 +90,5 @@
__attribute__ ((weak))
void* operator new[](std::size_t size, const std::nothrow_t& no) throw() {
- return ::operator new[](size, no);
+ return ::operator new(size, no);
}
diff --git a/sources/cxx-stl/gabi++/src/pbase_type_info.cc b/sources/cxx-stl/gabi++/src/pbase_type_info.cc
index 09e8e2e..3169b57 100644
--- a/sources/cxx-stl/gabi++/src/pbase_type_info.cc
+++ b/sources/cxx-stl/gabi++/src/pbase_type_info.cc
@@ -35,13 +35,13 @@
{
}
- bool __pbase_type_info::can_catch(const std::type_info* thr_type,
+ bool __pbase_type_info::can_catch(const __shim_type_info* thr_type,
void*& adjustedPtr) const {
unsigned tracker = first_time_init;
return can_catch_typeinfo_wrapper(thr_type, adjustedPtr, tracker);
}
- bool __pbase_type_info::can_catch_typeinfo_wrapper(const std::type_info* thr_type,
+ bool __pbase_type_info::can_catch_typeinfo_wrapper(const __shim_type_info* thr_type,
void*& adjustedPtr,
unsigned tracker) const {
if (*this == *thr_type) {
diff --git a/sources/cxx-stl/gabi++/src/terminate.cc b/sources/cxx-stl/gabi++/src/terminate.cc
index 17435f9..2e70d35 100644
--- a/sources/cxx-stl/gabi++/src/terminate.cc
+++ b/sources/cxx-stl/gabi++/src/terminate.cc
@@ -31,43 +31,43 @@
namespace std {
- // The default std::terminate() implementation will crash the process.
- // This is done to help debugging, i.e.:
- // - When running the program in a debugger, it's trivial to get
- // a complete stack trace explaining the failure.
- //
- // - Otherwise, the default SIGSEGV handler will generate a stack
- // trace in the log, that can later be processed with ndk-stack
- // and other tools.
- //
- // - Finally, this also works when a custom SIGSEGV handler has been
- // installed. E.g. when using Google Breakpad, the termination will
- // be recorded in a Minidump, which contains a stack trace to be
- // later analyzed.
- //
- // The C++ specification states that the default std::terminate()
- // handler is library-specific, even though most implementation simply
- // choose to call abort() in this case.
- //
- static void default_terminate(void) {
- // The crash address is just a "magic" constant that can be used to
- // identify stack traces (like 0xdeadbaad is used when heap corruption
- // is detected in the C library). 'cab1' stands for "C++ ABI" :-)
- *(reinterpret_cast<char*>(0xdeadcab1)) = 0;
+ namespace {
+ // The default std::terminate() implementation will crash the process.
+ // This is done to help debugging, i.e.:
+ // - When running the program in a debugger, it's trivial to get
+ // a complete stack trace explaining the failure.
+ //
+ // - Otherwise, the default SIGSEGV handler will generate a stack
+ // trace in the log, that can later be processed with ndk-stack
+ // and other tools.
+ //
+ // - Finally, this also works when a custom SIGSEGV handler has been
+ // installed. E.g. when using Google Breakpad, the termination will
+ // be recorded in a Minidump, which contains a stack trace to be
+ // later analyzed.
+ //
+ // The C++ specification states that the default std::terminate()
+ // handler is library-specific, even though most implementation simply
+ // choose to call abort() in this case.
+ //
+ void default_terminate(void) {
+ // The crash address is just a "magic" constant that can be used to
+ // identify stack traces (like 0xdeadbaad is used when heap corruption
+ // is detected in the C library). 'cab1' stands for "C++ ABI" :-)
+ *(reinterpret_cast<char*>(0xdeadcab1)) = 0;
- // should not be here, but just in case.
- abort();
- }
+ // should not be here, but just in case.
+ abort();
+ }
- terminate_handler default_terminate_fn = default_terminate;
- terminate_handler current_terminate_fn = default_terminate_fn;
+ terminate_handler current_terminate_fn = default_terminate;
+ unexpected_handler current_unexpected_fn = terminate;
+ } // namespace
- unexpected_handler default_unexpected_fn = terminate;
- unexpected_handler current_unexpected_fn = default_unexpected_fn;
-
-
+#if !defined(GABIXX_LIBCXX)
exception::exception() throw() {
}
+#endif // !defined(GABIXX_LIBCXX)
exception::~exception() throw() {
}
@@ -76,6 +76,7 @@
return "std::exception";
}
+#if !defined(GABIXX_LIBCXX)
bad_exception::bad_exception() throw() {
}
@@ -85,6 +86,7 @@
const char* bad_exception::what() const throw() {
return "std::bad_exception";
}
+#endif // !defined(GABIXX_LIBCXX)
bad_cast::bad_cast() throw() {
}
@@ -140,20 +142,6 @@
terminate();
}
- void __terminate(terminate_handler t_handler) {
- try {
- t_handler();
- abort();
- } catch (...) {
- abort();
- }
- }
-
- void __unexpected(unexpected_handler u_handler) {
- u_handler();
- terminate();
- }
-
bool uncaught_exception() throw() {
using namespace __cxxabiv1;
diff --git a/sources/cxx-stl/gabi++/src/type_info.cc b/sources/cxx-stl/gabi++/src/type_info.cc
index 69b9f3a..fedc144 100644
--- a/sources/cxx-stl/gabi++/src/type_info.cc
+++ b/sources/cxx-stl/gabi++/src/type_info.cc
@@ -43,6 +43,7 @@
{
}
+#if !defined(GABIXX_LIBCXX)
bool
type_info::operator==(const type_info& rhs) const
{
@@ -72,4 +73,6 @@
return this < &rhs;
#endif
}
+
+#endif // !defined(GABIXX_LIBCXX)
} // end namespace std
diff --git a/sources/cxx-stl/llvm-libc++/android/llvm-libc++/Android.mk b/sources/cxx-stl/llvm-libc++/android/llvm-libc++/Android.mk
index 0a178bc..191bfb8 100644
--- a/sources/cxx-stl/llvm-libc++/android/llvm-libc++/Android.mk
+++ b/sources/cxx-stl/llvm-libc++/android/llvm-libc++/Android.mk
@@ -33,28 +33,37 @@
llvm_libc++_sources += \
support/android/locale_support.c \
- support/android/wchar_support.c
+ support/android/nl_types_support.c \
+ support/android/stdlib_support.c \
+ support/android/wchar_support.c \
+ support/android/wctype_support.c
llvm_libc++_sources := $(llvm_libc++_sources:%=src/%)
-llvm_libc++_cxxflags := -std=c++11
+llvm_libc++_export_cxxflags := -std=c++11
+llvm_libc++_cxxflags := $(llvm_libc++_export_cxxflags) \
+ -DGABIXX_LIBCXX=1 -DLIBCXXRT=1
+
+include $(dir $(LOCAL_PATH))../../gabi++/sources.mk
+llvm_libc++_includes += $(libgabi++_c_includes)
include $(CLEAR_VARS)
LOCAL_MODULE := llvm_libc++_static
LOCAL_SRC_FILES := $(llvm_libc++_sources)
+LOCAL_SRC_FILES += $(libgabi++_src_files:%=../gabi++/%)
LOCAL_C_INCLUDES := $(llvm_libc++_includes)
LOCAL_CPPFLAGS := $(llvm_libc++_cxxflags)
+LOCAL_CPP_FEATURES := rtti exceptions
LOCAL_EXPORT_C_INCLUDES := $(llvm_libc++_export_includes)
-LOCAL_EXPORT_STATIC_LIBRARIES := libgabi++_static
+LOCAL_EXPORT_CPPFLAGS := $(llvm_libc++_export_cxxflags)
include $(BUILD_STATIC_LIBRARY)
include $(CLEAR_VARS)
LOCAL_MODULE := llvm_libc++_shared
LOCAL_SRC_FILES := $(llvm_libc++_sources)
+LOCAL_SRC_FILES += $(libgabi++_src_files:%=../gabi++/%)
LOCAL_C_INCLUDES := $(llvm_libc++_includes)
-LOCAL_CPPFLAGS := $(llvm_libc++_cxxflags)
+LOCAL_CPPFLAGS := $(llvm_libc++_cxxflags) -DGABIXX_LIBCXX=1 -DLIBCXXRT=1
+LOCAL_CPP_FEATURES := rtti exceptions
LOCAL_EXPORT_C_INCLUDES := $(llvm_libc++_export_includes)
-LOCAL_WHOLE_STATIC_LIBRARIES := libgabi++_static
+LOCAL_EXPORT_CPPFLAGS := $(llvm_libc++_export_cxxflags)
include $(BUILD_SHARED_LIBRARY)
-
-$(call import-module,cxx-stl/gabi++)
-
diff --git a/sources/cxx-stl/llvm-libc++/android/test/jni/Android.mk b/sources/cxx-stl/llvm-libc++/android/test/jni/Android.mk
index 345dfb6..aff740c 100644
--- a/sources/cxx-stl/llvm-libc++/android/test/jni/Android.mk
+++ b/sources/cxx-stl/llvm-libc++/android/test/jni/Android.mk
@@ -13,7 +13,7 @@
include $(CLEAR_VARS)
LOCAL_MODULE := test_1_static
LOCAL_SRC_FILES := test_1.cc
-LOCAL_SHARED_LIBRARIES := llvm_libc++_static
+LOCAL_STATIC_LIBRARIES := llvm_libc++_static
include $(BUILD_EXECUTABLE)
include $(LOCAL_PATH)/../../llvm-libc++/Android.mk
diff --git a/sources/cxx-stl/llvm-libc++/android/test/jni/Application.mk b/sources/cxx-stl/llvm-libc++/android/test/jni/Application.mk
index 0da80f3..091cc9f 100644
--- a/sources/cxx-stl/llvm-libc++/android/test/jni/Application.mk
+++ b/sources/cxx-stl/llvm-libc++/android/test/jni/Application.mk
@@ -1,4 +1,6 @@
# This file is dual licensed under the MIT and the University of Illinois Open
# Source Licenses. See LICENSE.TXT for details.
+APP_OPTIM := debug
APP_ABI := all
+APP_STL := none
diff --git a/sources/cxx-stl/llvm-libc++/android/test/jni/test_1.cc b/sources/cxx-stl/llvm-libc++/android/test/jni/test_1.cc
index 963d8a1..7ed5af3 100644
--- a/sources/cxx-stl/llvm-libc++/android/test/jni/test_1.cc
+++ b/sources/cxx-stl/llvm-libc++/android/test/jni/test_1.cc
@@ -9,8 +9,14 @@
//===----------------------------------------------------------------------===//
#include <iostream>
+#include <locale>
int main(void) {
- std::cout << "Hello World\n" << std::endl;
+ // TODO(ajwong): This imbue should not be required. There is a problem with
+ // the module initialization code that causes the default "C" locale to not
+ // be created correctly. The manual imbue allows us to proceed with
+ // development for now.
+ std::cout.imbue(std::locale("C"));
+ std::cout << "Hello World" << std::endl;
return 0;
}
diff --git a/sources/cxx-stl/llvm-libc++/include/__locale b/sources/cxx-stl/llvm-libc++/include/__locale
index 4176720..64e350b 100644
--- a/sources/cxx-stl/llvm-libc++/include/__locale
+++ b/sources/cxx-stl/llvm-libc++/include/__locale
@@ -367,6 +367,20 @@
static const mask punct = _ISPUNCT;
static const mask xdigit = _ISXDIGIT;
static const mask blank = _ISBLANK;
+#elif __ANDROID__
+ typedef char mask;
+ static const mask space = _S;
+ static const mask print = _P | _U | _L | _N | _B;
+ static const mask cntrl = _C;
+ static const mask upper = _U;
+ static const mask lower = _L;
+ static const mask alpha = _U | _L;
+ static const mask digit = _N;
+ static const mask punct = _P;
+ static const mask xdigit = _N | _X;
+
+ // TODO(ajwong): bionic doesn't have a blank mask
+ static const mask blank = 0;
#else // __GLIBC__ || _WIN32 || __APPLE__ || __FreeBSD__ || __sun__
typedef unsigned long mask;
static const mask space = 1<<0;
@@ -585,6 +599,8 @@
#ifdef _CACHED_RUNES
static const size_t table_size = _CACHED_RUNES;
+#elif __ANDROID__
+ static const size_t table_size = __ctype_c_mask_table_size;
#else
static const size_t table_size = 256; // FIXME: Don't hardcode this.
#endif
diff --git a/sources/cxx-stl/llvm-libc++/include/regex b/sources/cxx-stl/llvm-libc++/include/regex
index 982500f..85f3882 100644
--- a/sources/cxx-stl/llvm-libc++/include/regex
+++ b/sources/cxx-stl/llvm-libc++/include/regex
@@ -933,7 +933,7 @@
typedef locale locale_type;
typedef ctype_base::mask char_class_type;
- static const char_class_type __regex_word = 0x80;
+ static const char_class_type __regex_word;
private:
locale __loc_;
const ctype<char_type>* __ct_;
@@ -1008,6 +1008,8 @@
int __value(wchar_t __ch, int __radix) const;
};
+template <class _CharT> const typename regex_traits<_CharT>::char_class_type regex_traits<_CharT>::__regex_word = 0x80;
+
template <class _CharT>
regex_traits<_CharT>::regex_traits()
{
diff --git a/sources/cxx-stl/llvm-libc++/include/support/android/locale.h b/sources/cxx-stl/llvm-libc++/include/support/android/locale.h
index 01c834f..ab099aa 100644
--- a/sources/cxx-stl/llvm-libc++/include/support/android/locale.h
+++ b/sources/cxx-stl/llvm-libc++/include/support/android/locale.h
@@ -85,6 +85,11 @@
struct lconv* localeconv(void);
+// Used to implement the std::ctype<char> specialization.
+extern const char * const __ctype_c_mask_table;
+// TODO(ajwong): Make this based on some exported bionic constant.
+const int __ctype_c_mask_table_size = 256;
+
#ifdef __cplusplus
} // extern "C"
#endif
diff --git a/sources/cxx-stl/llvm-libc++/include/support/android/stdlib.h b/sources/cxx-stl/llvm-libc++/include/support/android/stdlib.h
index bafbfe5..35d21c9 100644
--- a/sources/cxx-stl/llvm-libc++/include/support/android/stdlib.h
+++ b/sources/cxx-stl/llvm-libc++/include/support/android/stdlib.h
@@ -28,6 +28,8 @@
unsigned long long strtoull_l(const char *nptr, char **endptr, int base, locale_t loc);
long double strtold_l (const char *nptr, char **endptr, locale_t loc);
+int mbtowc(wchar_t *pwc, const char *pmb, size_t max);
+
#ifdef __cplusplus
} // extern "C"
#endif
diff --git a/sources/cxx-stl/llvm-libc++/src/locale.cpp b/sources/cxx-stl/llvm-libc++/src/locale.cpp
index 53a8a4c..e4c40de 100644
--- a/sources/cxx-stl/llvm-libc++/src/locale.cpp
+++ b/sources/cxx-stl/llvm-libc++/src/locale.cpp
@@ -978,6 +978,11 @@
return _DefaultRuneLocale.__runetype;
#elif defined(__GLIBC__)
return __cloc()->__ctype_b;
+#elif defined(__ANDROID__)
+ // TODO(ajwong): Should the actual traits functions delegate to the
+ // bionic ctype variants? Or should we do something similar to how we
+ // handle glibc where we use the _tolower_tab_ and _toupper_tab_ directly?
+ return __ctype_c_mask_table;
#elif __sun__
return __ctype_mask;
#elif _WIN32
diff --git a/sources/cxx-stl/llvm-libc++/src/support/android/locale_support.c b/sources/cxx-stl/llvm-libc++/src/support/android/locale_support.c
index 7bad7ec..8aa2919 100644
--- a/sources/cxx-stl/llvm-libc++/src/support/android/locale_support.c
+++ b/sources/cxx-stl/llvm-libc++/src/support/android/locale_support.c
@@ -51,6 +51,49 @@
define_char_wrapper_l (tolower)
define_char_wrapper_l (toupper)
+// TODO(ajwong): This table is copied from bionic's ctype implementation.
+// It doesn't support signed chars and will index out of bounds. The best way
+// to fix is to patch bionic's ctype array to support both signed and
+// unsigned char and then just directly reference it.
+static char const real_ctype_c_mask_table[256] = {
+ 0,
+ _C, _C, _C, _C, _C, _C, _C, _C,
+ _C, _C|_S, _C|_S, _C|_S, _C|_S, _C|_S, _C, _C,
+ _C, _C, _C, _C, _C, _C, _C, _C,
+ _C, _C, _C, _C, _C, _C, _C, _C,
+ _S|(char)_B, _P, _P, _P, _P, _P, _P, _P,
+ _P, _P, _P, _P, _P, _P, _P, _P,
+ _N, _N, _N, _N, _N, _N, _N, _N,
+ _N, _N, _P, _P, _P, _P, _P, _P,
+ _P, _U|_X, _U|_X, _U|_X, _U|_X, _U|_X, _U|_X, _U,
+ _U, _U, _U, _U, _U, _U, _U, _U,
+ _U, _U, _U, _U, _U, _U, _U, _U,
+ _U, _U, _U, _P, _P, _P, _P, _P,
+ _P, _L|_X, _L|_X, _L|_X, _L|_X, _L|_X, _L|_X, _L,
+ _L, _L, _L, _L, _L, _L, _L, _L,
+ _L, _L, _L, _L, _L, _L, _L, _L,
+ /* determine printability based on the IS0 8859 8-bit standard */
+ _L, _L, _L, _P, _P, _P, _P, _C,
+
+ _C, _C, _C, _C, _C, _C, _C, _C, /* 80 */
+ _C, _C, _C, _C, _C, _C, _C, _C, /* 88 */
+ _C, _C, _C, _C, _C, _C, _C, _C, /* 90 */
+ _C, _C, _C, _C, _C, _C, _C, _C, /* 98 */
+ _P, _P, _P, _P, _P, _P, _P, _P, /* A0 */
+ _P, _P, _P, _P, _P, _P, _P, _P, /* A8 */
+ _P, _P, _P, _P, _P, _P, _P, _P, /* B0 */
+ _P, _P, _P, _P, _P, _P, _P, _P, /* B8 */
+ _P, _P, _P, _P, _P, _P, _P, _P, /* C0 */
+ _P, _P, _P, _P, _P, _P, _P, _P, /* C8 */
+ _P, _P, _P, _P, _P, _P, _P, _P, /* D0 */
+ _P, _P, _P, _P, _P, _P, _P, _P, /* D8 */
+ _P, _P, _P, _P, _P, _P, _P, _P, /* E0 */
+ _P, _P, _P, _P, _P, _P, _P, _P, /* E8 */
+ _P, _P, _P, _P, _P, _P, _P, _P, /* F0 */
+ _P, _P, _P, _P, _P, _P, _P, _P /* F8 */
+};
+char const* const __ctype_c_mask_table = &real_ctype_c_mask_table[0];
+
///////////////////////////////////////////////////////////////////////
// stdio.h declarations
@@ -209,7 +252,6 @@
return copy;
}
-
// Static mutable variable because setlocale() is supposed to return
// a pointer to a writable C string.
static char g_C_LOCALE_SETTING[] = "C";
diff --git a/sources/cxx-stl/llvm-libc++/src/support/android/nl_types_support.c b/sources/cxx-stl/llvm-libc++/src/support/android/nl_types_support.c
new file mode 100644
index 0000000..b30e0e6
--- /dev/null
+++ b/sources/cxx-stl/llvm-libc++/src/support/android/nl_types_support.c
@@ -0,0 +1,20 @@
+// Contains an implementation of nl_types functions missing from bionic.
+//
+// TODO(ajwong): Make these work.
+
+#include <nl_types.h>
+
+nl_catd catopen(const char* name, int oflag) {
+#warning Not implemented
+ return 0;
+}
+
+char* catgets(nl_catd catd, int set_id, int msg_id, const char* s) {
+#warning Not implemented
+ return 0;
+}
+
+int catclose(nl_catd catd) {
+#warning Not implemented
+ return 0;
+}
diff --git a/sources/cxx-stl/llvm-libc++/src/support/android/stdlib_support.c b/sources/cxx-stl/llvm-libc++/src/support/android/stdlib_support.c
new file mode 100644
index 0000000..9cea38d
--- /dev/null
+++ b/sources/cxx-stl/llvm-libc++/src/support/android/stdlib_support.c
@@ -0,0 +1,15 @@
+// Contains an implementation of all stdlib functions missing from bionic.
+//
+// TODO(ajwong): Make these work.
+
+#include <stdlib.h>
+
+long double strtold(const char* nptr, char** endptr) {
+#warning Not implemented
+ return 0;
+}
+
+int mbtowc(wchar_t *pwc, const char *pmb, size_t max) {
+#warning Not implemented
+ return 0;
+}
diff --git a/sources/cxx-stl/llvm-libc++/src/support/android/wchar_support.c b/sources/cxx-stl/llvm-libc++/src/support/android/wchar_support.c
index 5227382..748f5d4 100644
--- a/sources/cxx-stl/llvm-libc++/src/support/android/wchar_support.c
+++ b/sources/cxx-stl/llvm-libc++/src/support/android/wchar_support.c
@@ -382,3 +382,42 @@
return s;
}
+float wcstof(const wchar_t* nptr, wchar_t** endptr) {
+#warning Not implemented
+ return 0;
+}
+
+long wcstol(const wchar_t* nptr, wchar_t** endptr, int base) {
+#warning Not implemented
+ return 0;
+}
+
+long double wcstold(const wchar_t* nptr, wchar_t** endptr) {
+#warning Not implemented
+ return 0;
+}
+
+long long wcstoll(const wchar_t* nptr, wchar_t** endptr, int base) {
+#warning Not implemented
+ return 0;
+}
+
+unsigned long long wcstoull(const wchar_t* nptr, wchar_t** endptr, int base) {
+#warning Not implemented
+ return 0;
+}
+
+size_t wcsnrtombs(char *dst,
+ const wchar_t **src,
+ size_t nwc, size_t len,
+ mbstate_t *ps) {
+#warning Not implemented
+ return 0;
+}
+
+size_t mbsnrtowcs(wchar_t *dst,
+ const char **src, size_t nmc,
+ size_t len, mbstate_t *ps) {
+#warning Not implemented
+ return 0;
+}
diff --git a/sources/cxx-stl/llvm-libc++/src/support/android/wctype_support.c b/sources/cxx-stl/llvm-libc++/src/support/android/wctype_support.c
new file mode 100644
index 0000000..1961459
--- /dev/null
+++ b/sources/cxx-stl/llvm-libc++/src/support/android/wctype_support.c
@@ -0,0 +1,9 @@
+// Contains an implementation of stdlib functions missing from bionic.
+//
+// TODO(ajwong): Make these work.
+
+#include <wctype.h>
+
+int iswblank(wint_t c) {
+ return 0;
+}
diff --git a/tests/build/b8247455-hidden-cxa/jni/Android.mk b/tests/build/b8247455-hidden-cxa/jni/Android.mk
new file mode 100644
index 0000000..e3ffba4
--- /dev/null
+++ b/tests/build/b8247455-hidden-cxa/jni/Android.mk
@@ -0,0 +1,30 @@
+# This test is to demostrate the issue:
+#
+# hidden symbol '__cxa_begin_cleanup' in ./obj/local/armeabi/libgnustl_static.a(eh_arm.o)
+# is referenced by DSO ./obj/local/armeabi/libidiv.so
+# hidden symbol '__cxa_type_match' in ./obj/local/armeabi/libgnustl_static.a(eh_arm.o)
+# is referenced by DSO ./obj/local/armeabi/libidiv.so
+#
+# File idiv.cpp contains code potentially causes divide-by-zero exception. libidiv.so
+# is built with libgnustl_static.a which provides __cxa_begin_cleanup and
+# __cxa_type_match needed by unwinder in libgcc.a. Unfortunately both are built
+# with hidden visibility, and causes warnings as the above when libidiv.so is used
+# to link other binaries.
+#
+# The fix is to unhide both __cxa_begin_cleanup and __cxa_type_match
+#
+
+LOCAL_PATH := $(call my-dir)
+
+include $(CLEAR_VARS)
+LOCAL_MODULE := libidiv
+LOCAL_SRC_FILES:= idiv.cpp
+LOCAL_CFLAGS := -Wall -Werror -Wno-unused-parameter
+include $(BUILD_SHARED_LIBRARY)
+
+include $(CLEAR_VARS)
+LOCAL_MODULE := libthrow
+LOCAL_SRC_FILES:= throw.cpp
+LOCAL_CFLAGS := -Wall -Werror -frtti -fexceptions
+LOCAL_SHARED_LIBRARIES = libidiv
+include $(BUILD_SHARED_LIBRARY)
\ No newline at end of file
diff --git a/tests/build/b8247455-hidden-cxa/jni/Application.mk b/tests/build/b8247455-hidden-cxa/jni/Application.mk
new file mode 100644
index 0000000..3563119
--- /dev/null
+++ b/tests/build/b8247455-hidden-cxa/jni/Application.mk
@@ -0,0 +1,2 @@
+APP_ABI := all
+APP_STL := gnustl_static
diff --git a/tests/build/b8247455-hidden-cxa/jni/idiv.cpp b/tests/build/b8247455-hidden-cxa/jni/idiv.cpp
new file mode 100644
index 0000000..b80920d
--- /dev/null
+++ b/tests/build/b8247455-hidden-cxa/jni/idiv.cpp
@@ -0,0 +1,4 @@
+int my_idiv (int a, int b)
+{
+ return a / b;
+}
diff --git a/tests/build/b8247455-hidden-cxa/jni/throw.cpp b/tests/build/b8247455-hidden-cxa/jni/throw.cpp
new file mode 100644
index 0000000..ac61371
--- /dev/null
+++ b/tests/build/b8247455-hidden-cxa/jni/throw.cpp
@@ -0,0 +1,6 @@
+extern int my_idiv(int a, int b);
+int my_thorw()
+{
+ my_idiv(3, 5);
+ throw 20;
+}
diff --git a/tests/device/test-openmp/jni/Android.mk b/tests/device/test-openmp/jni/Android.mk
index ed7f548..96e24b4 100644
--- a/tests/device/test-openmp/jni/Android.mk
+++ b/tests/device/test-openmp/jni/Android.mk
@@ -7,3 +7,17 @@
LOCAL_LDFLAGS += -fopenmp
include $(BUILD_EXECUTABLE)
+include $(CLEAR_VARS)
+LOCAL_MODULE := openmp2
+LOCAL_SRC_FILES := openmp2.c
+LOCAL_CFLAGS += -fopenmp
+LOCAL_LDFLAGS += -fopenmp
+include $(BUILD_EXECUTABLE)
+
+include $(CLEAR_VARS)
+LOCAL_MODULE := fib
+LOCAL_SRC_FILES := fib.c
+LOCAL_CFLAGS += -fopenmp
+LOCAL_LDFLAGS += -fopenmp
+include $(BUILD_EXECUTABLE)
+
diff --git a/tests/device/test-openmp/jni/fib.c b/tests/device/test-openmp/jni/fib.c
new file mode 100644
index 0000000..c2ec2e9
--- /dev/null
+++ b/tests/device/test-openmp/jni/fib.c
@@ -0,0 +1,56 @@
+#include <stdio.h>
+#include <stdlib.h>
+#include <math.h>
+#include <omp.h>
+#include <unistd.h>
+#define MAX 33 //41
+int Fibonacci(int n)
+{ int x, y;
+ if (n < 2)
+ return n;
+ else {
+ x = Fibonacci(n - 1);
+ y = Fibonacci(n - 2);
+ return (x + y);
+} }
+int FibonacciTask(int n)
+{ int x, y;
+ if (n < 2)
+ return n;
+ else {
+#pragma omp task shared(x)
+ x = Fibonacci(n - 1);
+#pragma omp task shared(y)
+ y = Fibonacci(n - 2);
+#pragma omp taskwait
+ return (x + y);
+ } }
+
+int main(int argc, char * argv[])
+{int FibNumber[MAX] = {0};
+ struct timeval time_start, time_end;
+ int i = 0;
+ // openmp related print message
+ printf("CPU_ONLN= %d\n", sysconf(_SC_NPROCESSORS_ONLN));
+ printf("Number of CPUs=%d\n", omp_get_num_procs());
+ printf("Number of max threads=%d\n", omp_get_max_threads());
+ printf("Number of executing thread=%d\n", omp_get_thread_num());
+ printf("Number of threads=%d\n", omp_get_num_threads());
+ omp_set_num_threads( omp_get_num_procs() );
+ gettimeofday(&time_start, NULL);
+#pragma omp parallel
+ {
+#pragma omp single private(i)
+ for(i = 1; i < MAX; i++) {
+ FibNumber[i] = FibonacciTask(i);
+ } }
+ gettimeofday(&time_end, NULL);
+ time_end.tv_usec = time_end.tv_usec-time_start.tv_usec;
+ time_end.tv_sec = time_end.tv_sec-time_start.tv_sec;
+ time_end.tv_usec += (time_end.tv_sec*1000000);
+ printf("Time of Fibonacci with OpenMP : %lf sec\n", time_end.tv_usec / 1000000.0);
+ for(i = 0; i < MAX; i++)
+ printf("%d ", FibNumber[i]);
+ printf("\n-------------------------------\n");
+ return 0;
+}
diff --git a/tests/device/test-openmp/jni/openmp2.c b/tests/device/test-openmp/jni/openmp2.c
new file mode 100644
index 0000000..c1788ce
--- /dev/null
+++ b/tests/device/test-openmp/jni/openmp2.c
@@ -0,0 +1,25 @@
+#include <stdio.h>
+#include <stdlib.h>
+#include <omp.h>
+#include <sys/sysconf.h>
+
+int main (int argc, char *argv[])
+{
+ int nthreads, tid;
+ printf("SC_NPROCESSORS_ONLN: %d\n", sysconf (_SC_NPROCESSORS_ONLN));
+ #pragma omp parallel default(shared) private(nthreads, tid)
+ /* Fork a team of threads giving them their own copies of variables */
+ {
+ /* Obtain thread number */
+ tid = omp_get_thread_num();
+ printf("Hello World from thread = %d\n", tid);
+ /* Only master thread does this */
+ if (tid == 0)
+ {
+ nthreads = omp_get_num_threads();
+ printf("Number of threads = %d\n", nthreads);
+ }
+ } /* All threads join master thread and disband */
+
+ return 0;
+}
diff --git a/tests/device/test-stlport_shared-exception/jni/new1_3.cpp b/tests/device/test-stlport_shared-exception/jni/new1_3.cpp
index 502c4f4..9ae9336 100644
--- a/tests/device/test-stlport_shared-exception/jni/new1_3.cpp
+++ b/tests/device/test-stlport_shared-exception/jni/new1_3.cpp
@@ -1,7 +1,25 @@
// { dg-do run }
-//Lifetime of temporaries:
-//egcs 2.92 performs cleanup for temporaries inside new expressions
-//after the new is complete, not at the end of the full expression.
+//
+// Purpose: Check the lifetime of the temporaries.
+//
+// Lifetime of temporaries:
+// egcs 2.92 performs cleanup for temporaries inside new expressions
+// after the new is complete, not at the end of the full expression.
+//
+// In GCC, the operands are computed first. If no exception is raised, then
+// the result should be "ctor, new, func, dtor". If the new operator throws
+// the exception, then the result should be "ctor, new, dtor". If the
+// constructor of the temporary throws the exception, then the result should
+// be "ctor".
+//
+// In Clang, the new operator is called first. If no exception is raised,
+// then the result should be "new, ctor, func, dtor". If the new operator
+// throws the exception, then the result should be "new". If the constructor
+// of the temporary throws the exception, then the result should be
+// "new, ctor, delete".
+//
+// Both of them are allowed by the C++ language specification, so we are using
+// #ifdef for different compilers.
#include <new>
#include <cstdlib>
@@ -71,11 +89,21 @@
func(new B(A(10).addr()));
}catch(int){
}
+#if defined(__clang__)
+ CHECK(new_done==1);
+ CHECK(ctor_done==2);
+ CHECK(func_done==3);
+ CHECK(dtor_done==4);
+ CHECK(delete_done==0);
+#elif defined(__GNUC__)
CHECK(ctor_done==1);
CHECK(new_done==2);
CHECK(func_done==3);
CHECK(dtor_done==4);
CHECK(delete_done==0);
+#else
+#error "Unknown compiler"
+#endif
}
void test2()
@@ -86,11 +114,21 @@
func(new B(A(10).addr()));
}catch(int){
}
+#if defined(__clang__)
+ CHECK(new_done==1);
+ CHECK(ctor_done==0);
+ CHECK(func_done==0);
+ CHECK(dtor_done==0);
+ CHECK(delete_done==0);
+#elif defined(__GNUC__)
CHECK(ctor_done==1);
CHECK(new_done==2);
CHECK(func_done==0);
CHECK(dtor_done==3);
CHECK(delete_done==0);
+#else
+#error "Unknown compiler"
+#endif
}
void test3()
@@ -101,11 +139,21 @@
func(new B(A(10).addr()));
}catch(int){
}
+#if defined(__clang__)
+ CHECK(new_done==1);
+ CHECK(ctor_done==2);
+ CHECK(func_done==0);
+ CHECK(dtor_done==0);
+ CHECK(delete_done==3);
+#elif defined(__GNUC__)
CHECK(new_done==0);
CHECK(ctor_done==1);
CHECK(func_done==0);
CHECK(dtor_done==0);
CHECK(delete_done==0);
+#else
+#error "Unknown compiler"
+#endif
}
int main()
diff --git a/tests/device/test-stlport_shared-exception/jni/pr23299.cpp b/tests/device/test-stlport_shared-exception/jni/pr23299.cpp
index 94a414a..844d68c 100644
--- a/tests/device/test-stlport_shared-exception/jni/pr23299.cpp
+++ b/tests/device/test-stlport_shared-exception/jni/pr23299.cpp
@@ -6,16 +6,19 @@
struct A
{
- virtual int a () {}
+ virtual int a () { return 0; }
};
+
struct B : public A
{
- virtual int b () {}
+ virtual int b () { return 0; }
};
+
struct C : public A
{
- virtual int c () {}
+ virtual int c () { return 0; }
};
+
struct D
{
D () { d = 64; }
@@ -24,6 +27,7 @@
};
int x;
+
D::~D ()
{
x |= 1;
@@ -44,16 +48,15 @@
int r = c ();
}
-int
-E::c ()
+int E::c ()
{
if (x > 10)
throw 1;
x |= 2;
+ return 0;
}
-int
-main (void)
+int main (void)
{
{
E e;
diff --git a/tests/device/test-stlport_static-exception/jni/new1_3.cpp b/tests/device/test-stlport_static-exception/jni/new1_3.cpp
index 502c4f4..9ae9336 100644
--- a/tests/device/test-stlport_static-exception/jni/new1_3.cpp
+++ b/tests/device/test-stlport_static-exception/jni/new1_3.cpp
@@ -1,7 +1,25 @@
// { dg-do run }
-//Lifetime of temporaries:
-//egcs 2.92 performs cleanup for temporaries inside new expressions
-//after the new is complete, not at the end of the full expression.
+//
+// Purpose: Check the lifetime of the temporaries.
+//
+// Lifetime of temporaries:
+// egcs 2.92 performs cleanup for temporaries inside new expressions
+// after the new is complete, not at the end of the full expression.
+//
+// In GCC, the operands are computed first. If no exception is raised, then
+// the result should be "ctor, new, func, dtor". If the new operator throws
+// the exception, then the result should be "ctor, new, dtor". If the
+// constructor of the temporary throws the exception, then the result should
+// be "ctor".
+//
+// In Clang, the new operator is called first. If no exception is raised,
+// then the result should be "new, ctor, func, dtor". If the new operator
+// throws the exception, then the result should be "new". If the constructor
+// of the temporary throws the exception, then the result should be
+// "new, ctor, delete".
+//
+// Both of them are allowed by the C++ language specification, so we are using
+// #ifdef for different compilers.
#include <new>
#include <cstdlib>
@@ -71,11 +89,21 @@
func(new B(A(10).addr()));
}catch(int){
}
+#if defined(__clang__)
+ CHECK(new_done==1);
+ CHECK(ctor_done==2);
+ CHECK(func_done==3);
+ CHECK(dtor_done==4);
+ CHECK(delete_done==0);
+#elif defined(__GNUC__)
CHECK(ctor_done==1);
CHECK(new_done==2);
CHECK(func_done==3);
CHECK(dtor_done==4);
CHECK(delete_done==0);
+#else
+#error "Unknown compiler"
+#endif
}
void test2()
@@ -86,11 +114,21 @@
func(new B(A(10).addr()));
}catch(int){
}
+#if defined(__clang__)
+ CHECK(new_done==1);
+ CHECK(ctor_done==0);
+ CHECK(func_done==0);
+ CHECK(dtor_done==0);
+ CHECK(delete_done==0);
+#elif defined(__GNUC__)
CHECK(ctor_done==1);
CHECK(new_done==2);
CHECK(func_done==0);
CHECK(dtor_done==3);
CHECK(delete_done==0);
+#else
+#error "Unknown compiler"
+#endif
}
void test3()
@@ -101,11 +139,21 @@
func(new B(A(10).addr()));
}catch(int){
}
+#if defined(__clang__)
+ CHECK(new_done==1);
+ CHECK(ctor_done==2);
+ CHECK(func_done==0);
+ CHECK(dtor_done==0);
+ CHECK(delete_done==3);
+#elif defined(__GNUC__)
CHECK(new_done==0);
CHECK(ctor_done==1);
CHECK(func_done==0);
CHECK(dtor_done==0);
CHECK(delete_done==0);
+#else
+#error "Unknown compiler"
+#endif
}
int main()
diff --git a/tests/device/test-stlport_static-exception/jni/pr23299.cpp b/tests/device/test-stlport_static-exception/jni/pr23299.cpp
index 94a414a..844d68c 100644
--- a/tests/device/test-stlport_static-exception/jni/pr23299.cpp
+++ b/tests/device/test-stlport_static-exception/jni/pr23299.cpp
@@ -6,16 +6,19 @@
struct A
{
- virtual int a () {}
+ virtual int a () { return 0; }
};
+
struct B : public A
{
- virtual int b () {}
+ virtual int b () { return 0; }
};
+
struct C : public A
{
- virtual int c () {}
+ virtual int c () { return 0; }
};
+
struct D
{
D () { d = 64; }
@@ -24,6 +27,7 @@
};
int x;
+
D::~D ()
{
x |= 1;
@@ -44,16 +48,15 @@
int r = c ();
}
-int
-E::c ()
+int E::c ()
{
if (x > 10)
throw 1;
x |= 2;
+ return 0;
}
-int
-main (void)
+int main (void)
{
{
E e;