Merge to upstream r293166. am: 467bf41d66 am: 444d5607de
am: 838ac37536

Change-Id: Ifad782f0eb70b3080b6c8e745339890a6c3f9b98
diff --git a/CMakeLists.txt b/CMakeLists.txt
index 5eb0109..8f23b7c 100644
--- a/CMakeLists.txt
+++ b/CMakeLists.txt
@@ -49,8 +49,20 @@
     set(LLVM_INCLUDE_DIR ${INCLUDE_DIR} CACHE PATH "Path to llvm/include")
     set(LLVM_BINARY_DIR ${LLVM_OBJ_ROOT} CACHE PATH "Path to LLVM build tree")
     set(LLVM_MAIN_SRC_DIR ${MAIN_SRC_DIR} CACHE PATH "Path to LLVM source tree")
-    set(LLVM_CMAKE_PATH "${LLVM_BINARY_DIR}/lib${LLVM_LIBDIR_SUFFIX}/cmake/llvm")
     set(LLVM_LIT_PATH "${LLVM_PATH}/utils/lit/lit.py")
+
+    # --cmakedir is supported since llvm r291218 (4.0 release)
+    execute_process(
+      COMMAND ${LLVM_CONFIG_PATH} --cmakedir
+      RESULT_VARIABLE HAD_ERROR
+      OUTPUT_VARIABLE CONFIG_OUTPUT
+      ERROR_QUIET)
+    if(NOT HAD_ERROR)
+      string(STRIP "${CONFIG_OUTPUT}" LLVM_CMAKE_PATH)
+    else()
+      set(LLVM_CMAKE_PATH
+          "${LLVM_BINARY_DIR}/lib${LLVM_LIBDIR_SUFFIX}/cmake/llvm")
+    endif()
   else()
     message(FATAL_ERROR "llvm-config not found and LLVM_MAIN_SRC_DIR not defined. "
                         "Reconfigure with -DLLVM_CONFIG_PATH=path/to/llvm-config "
@@ -66,10 +78,14 @@
   endif()
 
   set(PACKAGE_NAME libcxxabi)
-  set(PACKAGE_VERSION 4.0.0svn)
+  set(PACKAGE_VERSION 5.0.0svn)
   set(PACKAGE_STRING "${PACKAGE_NAME} ${PACKAGE_VERSION}")
   set(PACKAGE_BUGREPORT "llvm-bugs@lists.llvm.org")
 
+  if (NOT DEFINED LLVM_INCLUDE_TESTS)
+    set(LLVM_INCLUDE_TESTS ON)
+  endif()
+
   if(EXISTS ${LLVM_MAIN_SRC_DIR}/utils/lit/lit.py)
     set(LLVM_LIT ${LLVM_MAIN_SRC_DIR}/utils/lit/lit.py)
   else()
@@ -118,7 +134,14 @@
 option(LIBCXXABI_USE_COMPILER_RT "Use compiler-rt instead of libgcc" OFF)
 option(LIBCXXABI_ENABLE_THREADS "Build with threads enabled" ON)
 option(LIBCXXABI_HAS_PTHREAD_API "Ignore auto-detection and force use of pthread API" OFF)
+option(LIBCXXABI_HAS_EXTERNAL_THREAD_API
+  "Build libc++abi with an externalized threading API.
+  This option may only be set to ON when LIBCXXABI_ENABLE_THREADS=ON." OFF)
+option(LIBCXXABI_BUILD_EXTERNAL_THREAD_LIBRARY
+  "Build libc++abi with an externalized threading library.
+   This option may only be set to ON when LIBCXXABI_ENABLE_THREADS=ON" OFF)
 option(LIBCXXABI_BUILD_32_BITS "Build 32 bit libc++abi." ${LLVM_BUILD_32_BITS})
+option(LIBCXXABI_INCLUDE_TESTS "Generate build targets for the libc++abi unit tests." ${LLVM_INCLUDE_TESTS})
 set(LIBCXXABI_TARGET_TRIPLE "" CACHE STRING "Target triple for cross compiling.")
 set(LIBCXXABI_GCC_TOOLCHAIN "" CACHE PATH "GCC toolchain for cross compiling.")
 set(LIBCXXABI_SYSROOT "" CACHE PATH "Sysroot for cross compiling.")
@@ -347,18 +370,59 @@
   list(APPEND LIBCXXABI_COMPILE_FLAGS -D_LIBCPP_BUILD_STATIC)
 endif()
 
+# Threading
 if (NOT LIBCXXABI_ENABLE_THREADS)
   if (LIBCXXABI_HAS_PTHREAD_API)
     message(FATAL_ERROR "LIBCXXABI_HAS_PTHREAD_API can only"
                         " be set to ON when LIBCXXABI_ENABLE_THREADS"
                         " is also set to ON.")
   endif()
+  if (LIBCXXABI_HAS_EXTERNAL_THREAD_API)
+    message(FATAL_ERROR "LIBCXXABI_HAS_EXTERNAL_THREAD_API can only"
+                        " be set to ON when LIBCXXABI_ENABLE_THREADS"
+                        " is also set to ON.")
+  endif()
+  if (LIBCXXABI_BUILD_EXTERNAL_THREAD_LIBRARY)
+    message(FATAL_ERROR "LIBCXXABI_BUILD_EXTERNAL_THREAD_LIBRARY can only"
+                        " be set to ON when LIBCXXABI_ENABLE_THREADS"
+                        " is also set to ON.")
+  endif()
   add_definitions(-D_LIBCXXABI_HAS_NO_THREADS)
 endif()
 
+if (LIBCXXABI_HAS_EXTERNAL_THREAD_API)
+  if (LIBCXXABI_HAS_PTHREAD_API)
+    message(FATAL_ERROR "The options LIBCXXABI_HAS_EXTERNAL_THREAD_API"
+                        " and LIBCXXABI_HAS_PTHREAD_API cannot be both"
+                        " set to ON at the same time.")
+  endif()
+  if (LIBCXXABI_BUILD_EXTERNAL_THREAD_LIBRARY)
+    message(FATAL_ERROR "The options LIBCXXABI_BUILD_EXTERNAL_THREAD_LIBRARY"
+                        " and LIBCXXABI_HAS_EXTERNAL_THREAD_API cannot be both"
+                        " set to ON at the same time.")
+  endif()
+endif()
+
+if (LIBCXXABI_BUILD_EXTERNAL_THREAD_LIBRARY AND LIBCXXABI_ENABLE_SHARED)
+  # Need to allow unresolved symbols if this is to work with shared library builds
+  if (APPLE)
+    add_link_flags("-undefined dynamic_lookup")
+  else()
+    # Relax this restriction from HandleLLVMOptions
+    string(REPLACE "-Wl,-z,defs" "" CMAKE_SHARED_LINKER_FLAGS "${CMAKE_SHARED_LINKER_FLAGS}")
+  endif()
+endif()
+
 if (LIBCXXABI_HAS_PTHREAD_API)
   add_definitions(-D_LIBCPP_HAS_THREAD_API_PTHREAD)
-  add_definitions(-D_LIBCXXABI_USE_THREAD_API_PTHREAD)
+endif()
+
+if (LIBCXXABI_HAS_EXTERNAL_THREAD_API)
+  add_definitions(-D_LIBCPP_HAS_THREAD_API_EXTERNAL)
+endif()
+
+if (LIBCXXABI_BUILD_EXTERNAL_THREAD_LIBRARY)
+  add_definitions(-D_LIBCPP_HAS_THREAD_LIBRARY_EXTERNAL)
 endif()
 
 if (MSVC)
@@ -370,6 +434,10 @@
   add_definitions(-DLIBCXXABI_USE_LLVM_UNWINDER=1)
 endif()
 
+if (LIBCXXABI_SILENT_TERMINATE)
+  add_definitions(-DLIBCXXABI_SILENT_TERMINATE=1)
+endif()
+
 string(REPLACE ";" " " LIBCXXABI_CXX_FLAGS "${LIBCXXABI_CXX_FLAGS}")
 set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} ${LIBCXXABI_CXX_FLAGS}")
 set(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} ${LIBCXXABI_C_FLAGS}")
@@ -411,15 +479,19 @@
     set(LIBCXXABI_LIBUNWIND_SOURCES "")
   endif()
 
-  include_directories("${LIBCXXABI_LIBUNWIND_INCLUDES_INTERNAL}")
-  include_directories("${LIBCXXABI_LIBUNWIND_SOURCES}")
+  if (NOT LIBCXXABI_LIBUNWIND_INCLUDES_INTERNAL STREQUAL "LIBCXXABI_LIBUNWIND_INCLUDES_INTERNAL-NOTFOUND")
+    include_directories("${LIBCXXABI_LIBUNWIND_INCLUDES_INTERNAL}")
+  endif()
+  if (NOT LIBCXXABI_LIBUNWIND_SOURCES STREQUAL "")
+    include_directories("${LIBCXXABI_LIBUNWIND_SOURCES}")
+  endif()
 endif()
 
 # Add source code. This also contains all of the logic for deciding linker flags
 # soname, etc...
 add_subdirectory(src)
 
-if (LIBCXXABI_STANDALONE_BUILD AND NOT LIBCXXABI_ENABLE_SHARED)
+if (NOT LIBCXXABI_INCLUDE_TESTS OR (LIBCXXABI_STANDALONE_BUILD AND NOT LIBCXXABI_ENABLE_SHARED))
   # We can't reasonably test the system C++ library with a static libc++abi.
   # We either need to be able to replace libc++abi at run time (with a shared
   # libc++abi), or we need to be able to replace the C++ runtime (with a non-
@@ -432,4 +504,5 @@
                   "available!")
 else()
   add_subdirectory(test)
+  add_subdirectory(fuzz)
 endif()
diff --git a/LICENSE.TXT b/LICENSE.TXT
index 14fd39a..f333f1f 100644
--- a/LICENSE.TXT
+++ b/LICENSE.TXT
@@ -14,7 +14,7 @@
 University of Illinois/NCSA
 Open Source License
 
-Copyright (c) 2009-2016 by the contributors listed in CREDITS.TXT
+Copyright (c) 2009-2017 by the contributors listed in CREDITS.TXT
 
 All rights reserved.
 
diff --git a/fuzz/CMakeLists.txt b/fuzz/CMakeLists.txt
new file mode 100644
index 0000000..017427e
--- /dev/null
+++ b/fuzz/CMakeLists.txt
@@ -0,0 +1,11 @@
+# See http://llvm.org/docs/LibFuzzer.html
+if( LLVM_USE_SANITIZE_COVERAGE )
+  add_executable(cxa_demangle_fuzzer
+    cxa_demangle_fuzzer.cpp
+    ../src/cxa_demangle.cpp
+    )
+
+  target_link_libraries(cxa_demangle_fuzzer
+    LLVMFuzzer
+    )
+endif()
diff --git a/fuzz/cxa_demangle_fuzzer.cpp b/fuzz/cxa_demangle_fuzzer.cpp
new file mode 100644
index 0000000..cc9b193
--- /dev/null
+++ b/fuzz/cxa_demangle_fuzzer.cpp
@@ -0,0 +1,15 @@
+#include <stdint.h>
+#include <stddef.h>
+#include <string.h>
+#include <stdlib.h>
+extern "C" char *
+__cxa_demangle(const char *mangled_name, char *buf, size_t *n, int *status);
+
+extern "C" int LLVMFuzzerTestOneInput(const uint8_t *data, size_t size) {
+  char *str = new char[size+1];
+  memcpy(str, data, size);
+  str[size] = 0;
+  free(__cxa_demangle(str, 0, 0, 0));
+  delete [] str;
+  return 0;
+}
diff --git a/include/__cxxabi_config.h b/include/__cxxabi_config.h
index 0e7106e..2c58a22 100644
--- a/include/__cxxabi_config.h
+++ b/include/__cxxabi_config.h
@@ -22,7 +22,7 @@
 #endif
 
 #if defined(_WIN32)
- #if defined(_LIBCXXABI_DISABLE_DLL_IMPORT_EXPORT)
+ #if defined(_LIBCXXABI_DISABLE_VISIBILITY_ANNOTATIONS)
   #define _LIBCXXABI_HIDDEN
   #define _LIBCXXABI_DATA_VIS
   #define _LIBCXXABI_FUNC_VIS
@@ -39,13 +39,20 @@
   #define _LIBCXXABI_TYPE_VIS __declspec(dllimport)
  #endif
 #else
- #define _LIBCXXABI_HIDDEN __attribute__((__visibility__("hidden")))
- #define _LIBCXXABI_DATA_VIS __attribute__((__visibility__("default")))
- #define _LIBCXXABI_FUNC_VIS __attribute__((__visibility__("default")))
- #if __has_attribute(__type_visibility__)
-  #define _LIBCXXABI_TYPE_VIS __attribute__((__type_visibility__("default")))
+ #if !defined(_LIBCXXABI_DISABLE_VISIBILITY_ANNOTATIONS)
+  #define _LIBCXXABI_HIDDEN __attribute__((__visibility__("hidden")))
+  #define _LIBCXXABI_DATA_VIS __attribute__((__visibility__("default")))
+  #define _LIBCXXABI_FUNC_VIS __attribute__((__visibility__("default")))
+  #if __has_attribute(__type_visibility__)
+   #define _LIBCXXABI_TYPE_VIS __attribute__((__type_visibility__("default")))
+  #else
+   #define _LIBCXXABI_TYPE_VIS __attribute__((__visibility__("default")))
+  #endif
  #else
-  #define _LIBCXXABI_TYPE_VIS __attribute__((__visibility__("default")))
+  #define _LIBCXXABI_HIDDEN
+  #define _LIBCXXABI_DATA_VIS
+  #define _LIBCXXABI_FUNC_VIS
+  #define _LIBCXXABI_TYPE_VIS
  #endif
 #endif
 
diff --git a/src/CMakeLists.txt b/src/CMakeLists.txt
index e6bd381..efbea67 100644
--- a/src/CMakeLists.txt
+++ b/src/CMakeLists.txt
@@ -1,6 +1,6 @@
 # Get sources
 set(LIBCXXABI_SOURCES
-  abort_message.cpp
+  # C++ABI files
   cxa_aux_runtime.cpp
   cxa_default_handlers.cpp
   cxa_demangle.cpp
@@ -11,11 +11,14 @@
   cxa_unexpected.cpp
   cxa_vector.cpp
   cxa_virtual.cpp
-  exception.cpp
+  # C++ STL files
+  stdlib_exception.cpp
+  stdlib_stdexcept.cpp
+  stdlib_typeinfo.cpp
+  # Internal files
+  abort_message.cpp
   fallback_malloc.cpp
   private_typeinfo.cpp
-  stdexcept.cpp
-  typeinfo.cpp
 )
 
 if (LIBCXXABI_ENABLE_EXCEPTIONS)
diff --git a/src/config.h b/src/config.h
index 625ad1b..72a05e0 100644
--- a/src/config.h
+++ b/src/config.h
@@ -16,40 +16,6 @@
 
 #include <unistd.h>
 
-#ifndef __has_attribute
-  #define __has_attribute(x) 0
-#endif
-
-// Configure inline visibility attributes
-#if defined(_WIN32)
- #if defined(_MSC_VER) && !defined(__clang__)
-  // Using Microsoft Visual C++ compiler
-  #define _LIBCXXABI_INLINE_VISIBILITY __forceinline
- #else
-  #if __has_attribute(__internal_linkage__)
-   #define _LIBCXXABI_INLINE_VISIBILITY __attribute__ ((__internal_linkage__, __always_inline__))
-  #else
-   #define _LIBCXXABI_INLINE_VISIBILITY __attribute__ ((__always_inline__))
-  #endif
- #endif
-#else
- #if __has_attribute(__internal_linkage__)
-  #define _LIBCXXABI_INLINE_VISIBILITY __attribute__ ((__internal_linkage__, __always_inline__))
- #else
-  #define _LIBCXXABI_INLINE_VISIBILITY __attribute__ ((__visibility__("hidden"), __always_inline__))
- #endif
-#endif
-
-// Try and deduce a threading api if one has not been explicitly set.
-#if !defined(_LIBCXXABI_HAS_NO_THREADS) && \
-    !defined(_LIBCXXABI_USE_THREAD_API_PTHREAD)
-  #if defined(_POSIX_THREADS) && _POSIX_THREADS >= 0
-    #define _LIBCXXABI_USE_THREAD_API_PTHREAD
-  #else
-    #error "No thread API"
-  #endif
-#endif
-
 // Set this in the CXXFLAGS when you need it, because otherwise we'd have to
 // #if !defined(__linux__) && !defined(__APPLE__) && ...
 // and so-on for *every* platform.
@@ -57,4 +23,11 @@
 #  define LIBCXXABI_BAREMETAL 0
 #endif
 
+// The default terminate handler attempts to demangle uncaught exceptions, which
+// causes extra I/O and demangling code to be pulled in.
+// Set this to make the terminate handler default to a silent alternative.
+#ifndef LIBCXXABI_SILENT_TERMINATE
+#  define LIBCXXABI_SILENT_TERMINATE 0
+#endif
+
 #endif // LIBCXXABI_CONFIG_H
diff --git a/src/cxa_default_handlers.cpp b/src/cxa_default_handlers.cpp
index 09350e7..a1ea296 100644
--- a/src/cxa_default_handlers.cpp
+++ b/src/cxa_default_handlers.cpp
@@ -12,6 +12,7 @@
 #include <stdexcept>
 #include <new>
 #include <exception>
+#include <cstdlib>
 #include "abort_message.h"
 #include "config.h" // For __sync_swap
 #include "cxxabi.h"
@@ -22,7 +23,7 @@
 static const char* cause = "uncaught";
 
 __attribute__((noreturn))
-static void default_terminate_handler()
+static void demangling_terminate_handler()
 {
     // If there might be an uncaught exception
     using namespace __cxxabiv1;
@@ -78,12 +79,19 @@
 }
 
 __attribute__((noreturn))
-static void default_unexpected_handler() 
+static void demangling_unexpected_handler()
 {
     cause = "unexpected";
     std::terminate();
 }
 
+#if !LIBCXXABI_SILENT_TERMINATE
+static std::terminate_handler default_terminate_handler = demangling_terminate_handler;
+static std::terminate_handler default_unexpected_handler = demangling_unexpected_handler;
+#else
+static std::terminate_handler default_terminate_handler = std::abort;
+static std::terminate_handler default_unexpected_handler = std::abort;
+#endif
 
 //
 // Global variables that hold the pointers to the current handler
diff --git a/src/cxa_demangle.cpp b/src/cxa_demangle.cpp
index 4aeed1b..8f5cb30 100644
--- a/src/cxa_demangle.cpp
+++ b/src/cxa_demangle.cpp
@@ -1927,10 +1927,11 @@
                             if (is_function)
                             {
                                 size_t p = db.names[k].second.size();
-                                if (db.names[k].second[p-2] == '&')
-                                    p -= 3;
-                                else if (db.names[k].second.back() == '&')
+                                if (db.names[k].second[p - 2] == '&' &&
+                                    db.names[k].second[p - 1] == '&')
                                     p -= 2;
+                                else if (db.names[k].second.back() == '&')
+                                    p -= 1;
                                 if (cv & 1)
                                 {
                                     db.names[k].second.insert(p, " const");
@@ -3058,9 +3059,9 @@
             }
             if (t0 == last || *t0 != 'E')
             {
-              if(!db.names.empty())
+              if (!db.names.empty())
                 db.names.pop_back();
-                return first;
+              return first;
             }
             ++t0;
             if (t0 == last)
@@ -4952,13 +4953,13 @@
     sub_type names;
     template_param_type subs;
     Vector<template_param_type> template_param;
-    unsigned cv;
-    unsigned ref;
-    unsigned encoding_depth;
-    bool parsed_ctor_dtor_cv;
-    bool tag_templates;
-    bool fix_forward_references;
-    bool try_to_parse_template_args;
+    unsigned cv = 0;
+    unsigned ref = 0;
+    unsigned encoding_depth = 0;
+    bool parsed_ctor_dtor_cv = false;
+    bool tag_templates = true;
+    bool fix_forward_references = false;
+    bool try_to_parse_template_args = true;
 
     template <size_t N>
     Db(arena<N>& ar) :
@@ -4979,29 +4980,12 @@
         return nullptr;
     }
 
-    size_t len = std::strlen(mangled_name);
-    if (len < 2 || strncmp(mangled_name, "_Z", 2))
-    {
-        if (len < 4 || strncmp(mangled_name, "___Z", 4))
-        {
-            if (status)
-                *status = invalid_mangled_name;
-            return nullptr;
-        }
-    }
-
     size_t internal_size = buf != nullptr ? *n : 0;
     arena<bs> a;
     Db db(a);
-    db.cv = 0;
-    db.ref = 0;
-    db.encoding_depth = 0;
-    db.parsed_ctor_dtor_cv = false;
-    db.tag_templates = true;
     db.template_param.emplace_back(a);
-    db.fix_forward_references = false;
-    db.try_to_parse_template_args = true;
     int internal_status = success;
+    size_t len = std::strlen(mangled_name);
     demangle(mangled_name, mangled_name + len, db,
              internal_status);
     if (internal_status == success && db.fix_forward_references &&
diff --git a/src/cxa_exception.cpp b/src/cxa_exception.cpp
index f84c0e8..757b3d4 100644
--- a/src/cxa_exception.cpp
+++ b/src/cxa_exception.cpp
@@ -12,7 +12,6 @@
 //===----------------------------------------------------------------------===//
 
 #include "config.h"
-#include "threading_support.h"
 #include "cxxabi.h"
 
 #include <exception>        // for std::terminate
diff --git a/src/cxa_exception_storage.cpp b/src/cxa_exception_storage.cpp
index d18eb0f..549d747 100644
--- a/src/cxa_exception_storage.cpp
+++ b/src/cxa_exception_storage.cpp
@@ -14,7 +14,7 @@
 #include "cxa_exception.hpp"
 
 #include "config.h"
-#include "threading_support.h"
+#include <__threading_support>
 
 #if defined(_LIBCXXABI_HAS_NO_THREADS)
 
@@ -54,17 +54,17 @@
 
 namespace __cxxabiv1 {
 namespace {
-    __libcxxabi_tls_key key_;
-    __libcxxabi_exec_once_flag flag_ = _LIBCXXABI_EXEC_ONCE_INITIALIZER;
+    std::__libcpp_tls_key key_;
+    std::__libcpp_exec_once_flag flag_ = _LIBCPP_EXEC_ONCE_INITIALIZER;
 
     void destruct_ (void *p) {
         __free_with_fallback ( p );
-        if ( 0 != __libcxxabi_tls_set ( key_, NULL ) )	
+        if ( 0 != std::__libcpp_tls_set ( key_, NULL ) )
             abort_message("cannot zero out thread value for __cxa_get_globals()");
         }
 
     void construct_ () {
-        if ( 0 != __libcxxabi_tls_create ( &key_, destruct_ ) )
+        if ( 0 != std::__libcpp_tls_create ( &key_, destruct_ ) )
             abort_message("cannot create thread specific key for __cxa_get_globals()");
         }
 }   
@@ -80,8 +80,8 @@
                         (__calloc_with_fallback (1, sizeof (__cxa_eh_globals)));
             if ( NULL == retVal )
                 abort_message("cannot allocate __cxa_eh_globals");
-            if ( 0 != __libcxxabi_tls_set ( key_, retVal ) )
-               abort_message("__libcxxabi_tls_set failure in __cxa_get_globals()");
+            if ( 0 != std::__libcpp_tls_set ( key_, retVal ) )
+               abort_message("std::__libcpp_tls_set failure in __cxa_get_globals()");
            }
         return retVal;
         }
@@ -92,10 +92,10 @@
     // libc++abi.
     __cxa_eh_globals * __cxa_get_globals_fast () {
     //  First time through, create the key.
-        if (0 != __libcxxabi_execute_once(&flag_, construct_))
+        if (0 != std::__libcpp_execute_once(&flag_, construct_))
             abort_message("execute once failure in __cxa_get_globals_fast()");
 //        static int init = construct_();
-        return static_cast<__cxa_eh_globals*>(__libcxxabi_tls_get(key_));
+        return static_cast<__cxa_eh_globals*>(std::__libcpp_tls_get(key_));
         }
     
 }
diff --git a/src/cxa_guard.cpp b/src/cxa_guard.cpp
index 1c468ff..49f83ed 100644
--- a/src/cxa_guard.cpp
+++ b/src/cxa_guard.cpp
@@ -11,7 +11,7 @@
 
 #include "abort_message.h"
 #include "config.h"
-#include "threading_support.h"
+#include <__threading_support>
 
 #include <stdint.h>
 
@@ -20,8 +20,8 @@
     which will turn around and try to call __cxa_guard_acquire reentrantly.
     For this reason, the headers of this file are as restricted as possible.
     Previous implementations of this code for __APPLE__ have used
-    __libcxxabi_mutex_lock and the abort_message utility without problem.  This
-    implementation also uses __libcxxabi_condvar_wait which has tested
+    std::__libcpp_mutex_lock and the abort_message utility without problem. This
+    implementation also uses std::__libcpp_condvar_wait which has tested
     to not be a problem.
 */
 
@@ -67,8 +67,8 @@
 #endif
 
 #ifndef _LIBCXXABI_HAS_NO_THREADS
-__libcxxabi_mutex_t guard_mut = _LIBCXXABI_MUTEX_INITIALIZER;
-__libcxxabi_condvar_t guard_cv = _LIBCXXABI_CONDVAR_INITIALIZER;
+std::__libcpp_mutex_t guard_mut = _LIBCPP_MUTEX_INITIALIZER;
+std::__libcpp_condvar_t guard_cv = _LIBCPP_CONDVAR_INITIALIZER;
 #endif
 
 #if defined(__APPLE__) && !defined(__arm__)
@@ -173,13 +173,25 @@
 #ifndef _LIBCXXABI_HAS_NO_THREADS
 _LIBCXXABI_FUNC_VIS int __cxa_guard_acquire(guard_type *guard_object) {
     char* initialized = (char*)guard_object;
-    if (__libcxxabi_mutex_lock(&guard_mut))
+    if (std::__libcpp_mutex_lock(&guard_mut))
         abort_message("__cxa_guard_acquire failed to acquire mutex");
     int result = *initialized == 0;
     if (result)
     {
 #if defined(__APPLE__) && !defined(__arm__)
-        const lock_type id = __libcxxabi_thread_get_port();
+        // This is a special-case pthread dependency for Mac. We can't pull this
+        // out into libcxx's threading API (__threading_support) because not all
+        // supported Mac environments provide this function (in pthread.h). To
+        // make it possible to build/use libcxx in those environments, we have to
+        // keep this pthread dependency local to libcxxabi. If there is some
+        // convenient way to detect precisely when pthread_mach_thread_np is
+        // available in a given Mac environment, it might still be possible to
+        // bury this dependency in __threading_support.
+        #ifdef _LIBCPP_HAS_THREAD_API_PTHREAD
+           const lock_type id = pthread_mach_thread_np(std::__libcpp_thread_get_current_id());
+        #else
+           #error "How do I pthread_mach_thread_np()?"
+        #endif
         lock_type lock = get_lock(*guard_object);
         if (lock)
         {
@@ -188,7 +200,7 @@
                 abort_message("__cxa_guard_acquire detected deadlock");
             do
             {
-                if (__libcxxabi_condvar_wait(&guard_cv, &guard_mut))
+                if (std::__libcpp_condvar_wait(&guard_cv, &guard_mut))
                     abort_message("__cxa_guard_acquire condition variable wait failed");
                 lock = get_lock(*guard_object);
             } while (lock);
@@ -200,36 +212,36 @@
             set_lock(*guard_object, id);
 #else  // !__APPLE__ || __arm__
         while (get_lock(*guard_object))
-            if (__libcxxabi_condvar_wait(&guard_cv, &guard_mut))
+            if (std::__libcpp_condvar_wait(&guard_cv, &guard_mut))
                 abort_message("__cxa_guard_acquire condition variable wait failed");
         result = *initialized == 0;
         if (result)
             set_lock(*guard_object, true);
 #endif  // !__APPLE__ || __arm__
     }
-    if (__libcxxabi_mutex_unlock(&guard_mut))
+    if (std::__libcpp_mutex_unlock(&guard_mut))
         abort_message("__cxa_guard_acquire failed to release mutex");
     return result;
 }
 
 _LIBCXXABI_FUNC_VIS void __cxa_guard_release(guard_type *guard_object) {
-    if (__libcxxabi_mutex_lock(&guard_mut))
+    if (std::__libcpp_mutex_lock(&guard_mut))
         abort_message("__cxa_guard_release failed to acquire mutex");
     *guard_object = 0;
     set_initialized(guard_object);
-    if (__libcxxabi_mutex_unlock(&guard_mut))
+    if (std::__libcpp_mutex_unlock(&guard_mut))
         abort_message("__cxa_guard_release failed to release mutex");
-    if (__libcxxabi_condvar_broadcast(&guard_cv))
+    if (std::__libcpp_condvar_broadcast(&guard_cv))
         abort_message("__cxa_guard_release failed to broadcast condition variable");
 }
 
 _LIBCXXABI_FUNC_VIS void __cxa_guard_abort(guard_type *guard_object) {
-    if (__libcxxabi_mutex_lock(&guard_mut))
+    if (std::__libcpp_mutex_lock(&guard_mut))
         abort_message("__cxa_guard_abort failed to acquire mutex");
     *guard_object = 0;
-    if (__libcxxabi_mutex_unlock(&guard_mut))
+    if (std::__libcpp_mutex_unlock(&guard_mut))
         abort_message("__cxa_guard_abort failed to release mutex");
-    if (__libcxxabi_condvar_broadcast(&guard_cv))
+    if (std::__libcpp_condvar_broadcast(&guard_cv))
         abort_message("__cxa_guard_abort failed to broadcast condition variable");
 }
 
diff --git a/src/cxa_handlers.cpp b/src/cxa_handlers.cpp
index 3f78131..ce2cfba 100644
--- a/src/cxa_handlers.cpp
+++ b/src/cxa_handlers.cpp
@@ -104,7 +104,9 @@
 
 // In the future this will become:
 // std::atomic<std::new_handler>  __cxa_new_handler(0);
-extern "C" _LIBCXXABI_DATA_VIS new_handler __cxa_new_handler = 0;
+extern "C" {
+_LIBCXXABI_DATA_VIS new_handler __cxa_new_handler = 0;
+}
 
 new_handler
 set_new_handler(new_handler handler) _NOEXCEPT
diff --git a/src/cxa_new_delete.cpp b/src/cxa_new_delete.cpp
index 7a2c864..7609d76 100644
--- a/src/cxa_new_delete.cpp
+++ b/src/cxa_new_delete.cpp
@@ -14,6 +14,11 @@
 #include <new>
 #include <cstdlib>
 
+#if !defined(_THROW_BAD_ALLOC) || !defined(_NOEXCEPT)
+#error _THROW_BAD_ALLOC and _NOEXCEPT libc++ macros must already be defined \
+       by libc++.
+#endif
+
 /*
 [new.delete.single]
 
@@ -33,10 +38,7 @@
 */
 __attribute__((__weak__, __visibility__("default")))
 void *
-operator new(std::size_t size)
-#if !__has_feature(cxx_noexcept)
-    throw(std::bad_alloc)
-#endif
+operator new(std::size_t size) _THROW_BAD_ALLOC
 {
     if (size == 0)
         size = 1;
@@ -70,12 +72,7 @@
 */
 __attribute__((__weak__, __visibility__("default")))
 void*
-operator new(size_t size, const std::nothrow_t&)
-#if __has_feature(cxx_noexcept)
-    noexcept
-#else
-    throw()
-#endif
+operator new(size_t size, const std::nothrow_t&) _NOEXCEPT
 {
     void* p = 0;
 #ifndef _LIBCXXABI_NO_EXCEPTIONS
@@ -99,10 +96,7 @@
 */
 __attribute__((__weak__, __visibility__("default")))
 void*
-operator new[](size_t size)
-#if !__has_feature(cxx_noexcept)
-    throw(std::bad_alloc)
-#endif
+operator new[](size_t size) _THROW_BAD_ALLOC
 {
     return ::operator new(size);
 }
@@ -115,12 +109,7 @@
 */
 __attribute__((__weak__, __visibility__("default")))
 void*
-operator new[](size_t size, const std::nothrow_t&)
-#if __has_feature(cxx_noexcept)
-    noexcept
-#else
-    throw()
-#endif
+operator new[](size_t size, const std::nothrow_t&) _NOEXCEPT
 {
     void* p = 0;
 #ifndef _LIBCXXABI_NO_EXCEPTIONS
@@ -145,12 +134,7 @@
 */
 __attribute__((__weak__, __visibility__("default")))
 void
-operator delete(void* ptr)
-#if __has_feature(cxx_noexcept)
-    noexcept
-#else
-    throw()
-#endif
+operator delete(void* ptr) _NOEXCEPT
 {
     if (ptr)
         std::free(ptr);
@@ -163,12 +147,7 @@
 */
 __attribute__((__weak__, __visibility__("default")))
 void
-operator delete(void* ptr, const std::nothrow_t&)
-#if __has_feature(cxx_noexcept)
-    noexcept
-#else
-    throw()
-#endif
+operator delete(void* ptr, const std::nothrow_t&) _NOEXCEPT
 {
     ::operator delete(ptr);
 }
@@ -180,12 +159,7 @@
 */
 __attribute__((__weak__, __visibility__("default")))
 void
-operator delete[] (void* ptr)
-#if __has_feature(cxx_noexcept)
-    noexcept
-#else
-    throw()
-#endif
+operator delete[] (void* ptr) _NOEXCEPT
 {
     ::operator delete(ptr);
 }
@@ -197,12 +171,7 @@
 */
 __attribute__((__weak__, __visibility__("default")))
 void
-operator delete[] (void* ptr, const std::nothrow_t&)
-#if __has_feature(cxx_noexcept)
-    noexcept
-#else
-    throw()
-#endif
+operator delete[] (void* ptr, const std::nothrow_t&) _NOEXCEPT
 {
     ::operator delete[](ptr);
 }
diff --git a/src/cxa_thread_atexit.cpp b/src/cxa_thread_atexit.cpp
index 3ddaf0c..748b0eb 100644
--- a/src/cxa_thread_atexit.cpp
+++ b/src/cxa_thread_atexit.cpp
@@ -9,7 +9,7 @@
 
 #include "abort_message.h"
 #include "cxxabi.h"
-#include "threading_support.h"
+#include <__threading_support>
 #include <cstdlib>
 
 namespace __cxxabiv1 {
@@ -39,7 +39,7 @@
   //   destructors of any objects with static storage duration.
   //
   // - thread_local destructors on non-main threads run on the first iteration
-  //   through the __libcxxabi_tls_key destructors.
+  //   through the __libccpp_tls_key destructors.
   //   std::notify_all_at_thread_exit() and similar functions must be careful to
   //   wait until the second iteration to provide their intended ordering
   //   guarantees.
@@ -66,7 +66,7 @@
   // True if the destructors are currently scheduled to run on this thread
   __thread bool dtors_alive = false;
   // Used to trigger destructors on thread exit; value is ignored
-  __libcxxabi_tls_key dtors_key;
+  std::__libcpp_tls_key dtors_key;
 
   void run_dtors(void*) {
     while (auto head = dtors) {
@@ -80,16 +80,16 @@
 
   struct DtorsManager {
     DtorsManager() {
-      // There is intentionally no matching __libcxxabi_tls_delete call, as
+      // There is intentionally no matching std::__libcpp_tls_delete call, as
       // __cxa_thread_atexit() may be called arbitrarily late (for example, from
       // global destructors or atexit() handlers).
-      if (__libcxxabi_tls_create(&dtors_key, run_dtors) != 0) {
-        abort_message("__libcxxabi_tls_create() failed in __cxa_thread_atexit()");
+      if (std::__libcpp_tls_create(&dtors_key, run_dtors) != 0) {
+        abort_message("std::__libcpp_tls_create() failed in __cxa_thread_atexit()");
       }
     }
 
     ~DtorsManager() {
-      // __libcxxabi_tls_key destructors do not run on threads that call exit()
+      // std::__libcpp_tls_key destructors do not run on threads that call exit()
       // (including when the main thread returns from main()), so we explicitly
       // call the destructor here.  This runs at exit time (potentially earlier
       // if libc++abi is dlclose()'d).  Any thread_locals initialized after this
@@ -110,12 +110,12 @@
     if (__cxa_thread_atexit_impl) {
       return __cxa_thread_atexit_impl(dtor, obj, dso_symbol);
     } else {
-      // Initialize the dtors __libcxxabi_tls_key (uses __cxa_guard_*() for
+      // Initialize the dtors std::__libcpp_tls_key (uses __cxa_guard_*() for
       // one-time initialization and __cxa_atexit() for destruction)
       static DtorsManager manager;
 
       if (!dtors_alive) {
-        if (__libcxxabi_tls_set(dtors_key, &dtors_key) != 0) {
+        if (std::__libcpp_tls_set(dtors_key, &dtors_key) != 0) {
           return -1;
         }
         dtors_alive = true;
diff --git a/src/fallback_malloc.cpp b/src/fallback_malloc.cpp
index 5f52ece..3f8441e 100644
--- a/src/fallback_malloc.cpp
+++ b/src/fallback_malloc.cpp
@@ -10,7 +10,7 @@
 #include "fallback_malloc.h"
 
 #include "config.h"
-#include "threading_support.h"
+#include <__threading_support>
 
 #include <cstdlib> // for malloc, calloc, free
 #include <cstring> // for memset
@@ -29,7 +29,8 @@
 
 // When POSIX threads are not available, make the mutex operations a nop
 #ifndef _LIBCXXABI_HAS_NO_THREADS
-static __libcxxabi_mutex_t heap_mutex = _LIBCXXABI_MUTEX_INITIALIZER;
+_LIBCPP_SAFE_STATIC
+static std::__libcpp_mutex_t heap_mutex = _LIBCPP_MUTEX_INITIALIZER;
 #else
 static void * heap_mutex = 0;
 #endif
@@ -37,8 +38,10 @@
 class mutexor {
 public:
 #ifndef _LIBCXXABI_HAS_NO_THREADS
-    mutexor ( __libcxxabi_mutex_t *m ) : mtx_(m) { __libcxxabi_mutex_lock ( mtx_ ); }
-    ~mutexor () { __libcxxabi_mutex_unlock ( mtx_ ); }
+    mutexor ( std::__libcpp_mutex_t *m ) : mtx_(m) {
+      std::__libcpp_mutex_lock ( mtx_ );
+    }
+    ~mutexor () { std::__libcpp_mutex_unlock ( mtx_ ); }
 #else
     mutexor ( void * ) {}
     ~mutexor () {}
@@ -47,9 +50,9 @@
     mutexor ( const mutexor &rhs );
     mutexor & operator = ( const mutexor &rhs );
 #ifndef _LIBCXXABI_HAS_NO_THREADS
-    __libcxxabi_mutex_t *mtx_;
+    std::__libcpp_mutex_t *mtx_;
 #endif
-    };
+};
 
 
 static const size_t HEAP_SIZE = 512;
diff --git a/src/private_typeinfo.cpp b/src/private_typeinfo.cpp
index 6112a1f..e7995ed 100644
--- a/src/private_typeinfo.cpp
+++ b/src/private_typeinfo.cpp
@@ -105,45 +105,6 @@
 {
 }
 
-// __qualified_function_type_info
-
-__qualified_function_type_info::~__qualified_function_type_info()
-{
-}
-
-// Determine if a function pointer conversion can convert a pointer (or pointer
-// to member) to type x into a pointer (or pointer to member) to type y.
-static bool is_function_pointer_conversion(const std::type_info* x,
-                                           const std::type_info* y)
-{
-    const unsigned int discardable_quals =
-        __qualified_function_type_info::__noexcept_mask |
-        __qualified_function_type_info::__transaction_safe_mask |
-        __qualified_function_type_info::__noreturn_mask;
-
-    // If x has only discardable qualifiers and y is unqualified, then
-    // conversion is permitted.
-    const __qualified_function_type_info* qual_x =
-        dynamic_cast<const __qualified_function_type_info *>(x);
-    if (!qual_x)
-        return false;
-    if ((qual_x->__qualifiers & ~discardable_quals) == 0 &&
-        is_equal(qual_x->__base_type, y, false))
-        return true;
-
-    // Otherwise, x's qualifiers must be the same as y's, plus some discardable
-    // ones.
-    const __qualified_function_type_info* qual_y =
-        dynamic_cast<const __qualified_function_type_info *>(y);
-    if (!qual_y)
-        return false;
-    if (qual_y->__qualifiers & ~qual_x->__qualifiers)
-        return false;
-    if (qual_x->__qualifiers & ~qual_y->__qualifiers & ~discardable_quals)
-        return false;
-    return is_equal(qual_x->__base_type, qual_y->__base_type, false);
-}
-
 // __enum_type_info
 
 __enum_type_info::~__enum_type_info()
@@ -429,15 +390,13 @@
     // Do the dereference adjustment
     if (adjustedPtr != NULL)
         adjustedPtr = *static_cast<void**>(adjustedPtr);
-    // bullet 3B
-    if (thrown_pointer_type->__flags & ~__flags)
+    // bullet 3B and 3C
+    if (thrown_pointer_type->__flags & ~__flags & __no_remove_flags_mask)
+        return false;
+    if (__flags & ~thrown_pointer_type->__flags & __no_add_flags_mask)
         return false;
     if (is_equal(__pointee, thrown_pointer_type->__pointee, false))
         return true;
-    // bullet 3C
-    if (is_function_pointer_conversion(thrown_pointer_type->__pointee,
-                                       __pointee))
-      return true;
     // bullet 3A
     if (is_equal(__pointee, &typeid(void), false)) {
         // pointers to functions cannot be converted to void*.
@@ -543,11 +502,11 @@
         dynamic_cast<const __pointer_to_member_type_info*>(thrown_type);
     if (thrown_pointer_type == 0)
         return false;
-    if (thrown_pointer_type->__flags & ~__flags)
+    if (thrown_pointer_type->__flags & ~__flags & __no_remove_flags_mask)
         return false;
-    if (!is_equal(__pointee, thrown_pointer_type->__pointee, false) &&
-        !is_function_pointer_conversion(thrown_pointer_type->__pointee,
-                                        __pointee))
+    if (__flags & ~thrown_pointer_type->__flags & __no_add_flags_mask)
+        return false;
+    if (!is_equal(__pointee, thrown_pointer_type->__pointee, false))
         return false;
     if (is_equal(__context, thrown_pointer_type->__context, false))
         return true;
diff --git a/src/private_typeinfo.h b/src/private_typeinfo.h
index fa6bd63..f3d3e1d 100644
--- a/src/private_typeinfo.h
+++ b/src/private_typeinfo.h
@@ -49,33 +49,6 @@
                                            void *&) const;
 };
 
-// This implements the following proposal from cxx-abi-dev (not yet part of the
-// ABI document):
-//
-//   http://sourcerytools.com/pipermail/cxx-abi-dev/2016-October/002988.html
-//
-// This is necessary for support of http://wg21.link/p0012, which permits throwing
-// noexcept function and member function pointers and catching them as non-noexcept
-// pointers.
-class _LIBCXXABI_TYPE_VIS __qualified_function_type_info : public __shim_type_info {
-public:
-  const __function_type_info* __base_type;
-  unsigned int __qualifiers;
-
-  enum __qualifiers_mask {
-    __const_mask = 0x01,
-    __volatile_mask = 0x02,
-    __restrict_mask = 0x04,
-    __lval_ref_mask = 0x08,
-    __rval_ref_mask = 0x10,
-    __noexcept_mask = 0x20,
-    __transaction_safe_mask = 0x40,
-    __noreturn_mask = 0x80
-  };
-
-  _LIBCXXABI_HIDDEN virtual ~__qualified_function_type_info();
-};
-
 class _LIBCXXABI_TYPE_VIS __enum_type_info : public __shim_type_info {
 public:
   _LIBCXXABI_HIDDEN virtual ~__enum_type_info();
@@ -233,7 +206,22 @@
     __volatile_mask = 0x2,
     __restrict_mask = 0x4,
     __incomplete_mask = 0x8,
-    __incomplete_class_mask = 0x10
+    __incomplete_class_mask = 0x10,
+    __transaction_safe_mask = 0x20,
+    // This implements the following proposal from cxx-abi-dev (not yet part of
+    // the ABI document):
+    //
+    //   http://sourcerytools.com/pipermail/cxx-abi-dev/2016-October/002986.html
+    //
+    // This is necessary for support of http://wg21.link/p0012, which permits
+    // throwing noexcept function and member function pointers and catching
+    // them as non-noexcept pointers.
+    __noexcept_mask = 0x40,
+
+    // Flags that cannot be removed by a standard conversion.
+    __no_remove_flags_mask = __const_mask | __volatile_mask | __restrict_mask,
+    // Flags that cannot be added by a standard conversion.
+    __no_add_flags_mask = __transaction_safe_mask | __noexcept_mask
   };
 
   _LIBCXXABI_HIDDEN virtual ~__pbase_type_info();
diff --git a/src/exception.cpp b/src/stdlib_exception.cpp
similarity index 100%
rename from src/exception.cpp
rename to src/stdlib_exception.cpp
diff --git a/src/stdexcept.cpp b/src/stdlib_stdexcept.cpp
similarity index 100%
rename from src/stdexcept.cpp
rename to src/stdlib_stdexcept.cpp
diff --git a/src/typeinfo.cpp b/src/stdlib_typeinfo.cpp
similarity index 100%
rename from src/typeinfo.cpp
rename to src/stdlib_typeinfo.cpp
diff --git a/src/threading_support.h b/src/threading_support.h
deleted file mode 100644
index 78a225f..0000000
--- a/src/threading_support.h
+++ /dev/null
@@ -1,107 +0,0 @@
-//===------------------------ threading_support.h -------------------------===//
-//
-//                     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 _LIBCXXABI_THREADING_SUPPORT_H
-#define _LIBCXXABI_THREADING_SUPPORT_H
-
-#include "__cxxabi_config.h"
-#include "config.h"
-
-#ifndef _LIBCXXABI_HAS_NO_THREADS
-
-#if defined(_LIBCXXABI_USE_THREAD_API_PTHREAD)
-#include <pthread.h>
-
-#define _LIBCXXABI_THREAD_ABI_VISIBILITY inline _LIBCXXABI_INLINE_VISIBILITY
-
-// Mutex
-typedef pthread_mutex_t __libcxxabi_mutex_t;
-#define _LIBCXXABI_MUTEX_INITIALIZER PTHREAD_MUTEX_INITIALIZER
-
-_LIBCXXABI_THREAD_ABI_VISIBILITY
-int __libcxxabi_mutex_lock(__libcxxabi_mutex_t *mutex) {
-  return pthread_mutex_lock(mutex);
-}
-
-_LIBCXXABI_THREAD_ABI_VISIBILITY
-int __libcxxabi_mutex_unlock(__libcxxabi_mutex_t *mutex) {
-  return pthread_mutex_unlock(mutex);
-}
-
-// Condition variable
-typedef pthread_cond_t __libcxxabi_condvar_t;
-#define _LIBCXXABI_CONDVAR_INITIALIZER PTHREAD_COND_INITIALIZER
-
-_LIBCXXABI_THREAD_ABI_VISIBILITY
-int __libcxxabi_condvar_wait(__libcxxabi_condvar_t *cv,
-                             __libcxxabi_mutex_t *mutex) {
-  return pthread_cond_wait(cv, mutex);
-}
-
-_LIBCXXABI_THREAD_ABI_VISIBILITY
-int __libcxxabi_condvar_broadcast(__libcxxabi_condvar_t *cv) {
-  return pthread_cond_broadcast(cv);
-}
-
-// Execute once
-typedef pthread_once_t __libcxxabi_exec_once_flag;
-#define _LIBCXXABI_EXEC_ONCE_INITIALIZER PTHREAD_ONCE_INIT
-
-_LIBCXXABI_THREAD_ABI_VISIBILITY
-int __libcxxabi_execute_once(__libcxxabi_exec_once_flag *flag,
-                             void (*init_routine)(void)) {
-  return pthread_once(flag, init_routine);
-}
-
-// Thread id
-#if defined(__APPLE__) && !defined(__arm__)
-_LIBCXXABI_THREAD_ABI_VISIBILITY
-mach_port_t __libcxxabi_thread_get_port()
-{
-    return pthread_mach_thread_np(pthread_self());
-}
-#endif
-
-// Thread
-typedef pthread_t __libcxxabi_thread_t;
-
-_LIBCXXABI_THREAD_ABI_VISIBILITY
-int __libcxxabi_thread_create(__libcxxabi_thread_t* __t,
-                           void* (*__func)(void*), void* __arg)
-{
-    return pthread_create(__t, 0, __func, __arg);
-}
-
-_LIBCXXABI_THREAD_ABI_VISIBILITY
-int __libcxxabi_thread_join(__libcxxabi_thread_t* __t)
-{
-    return pthread_join(*__t, 0);
-}
-
-// TLS
-typedef pthread_key_t __libcxxabi_tls_key;
-
-_LIBCXXABI_THREAD_ABI_VISIBILITY
-int __libcxxabi_tls_create(__libcxxabi_tls_key *key,
-                           void (*destructor)(void *)) {
-  return pthread_key_create(key, destructor);
-}
-
-_LIBCXXABI_THREAD_ABI_VISIBILITY
-void *__libcxxabi_tls_get(__libcxxabi_tls_key key) {
-  return pthread_getspecific(key);
-}
-
-_LIBCXXABI_THREAD_ABI_VISIBILITY
-int __libcxxabi_tls_set(__libcxxabi_tls_key key, void *value) {
-  return pthread_setspecific(key, value);
-}
-#endif // _LIBCXXABI_USE_THREAD_API_PTHREAD
-#endif // !_LIBCXXABI_HAS_NO_THREADS
-#endif // _LIBCXXABI_THREADING_SUPPORT_H
diff --git a/test/CMakeLists.txt b/test/CMakeLists.txt
index 85c6f60..c1819d7 100644
--- a/test/CMakeLists.txt
+++ b/test/CMakeLists.txt
@@ -17,6 +17,7 @@
 pythonize_bool(LIBCXXABI_ENABLE_THREADS)
 pythonize_bool(LIBCXXABI_ENABLE_EXCEPTIONS)
 pythonize_bool(LIBCXXABI_USE_LLVM_UNWINDER)
+pythonize_bool(LIBCXXABI_BUILD_EXTERNAL_THREAD_LIBRARY)
 set(LIBCXXABI_TARGET_INFO "libcxx.test.target_info.LocalTI" CACHE STRING
     "TargetInfo to use when setting up test environment.")
 set(LIBCXXABI_EXECUTOR "None" CACHE STRING
@@ -34,6 +35,10 @@
   set(LIBCXXABI_TEST_DEPS cxxabi_static)
 endif()
 
+if (LIBCXXABI_BUILD_EXTERNAL_THREAD_LIBRARY)
+  list(APPEND LIBCXXABI_TEST_DEPS cxx_external_threads)
+endif()
+
 if (NOT LIBCXXABI_STANDALONE_BUILD)
   list(APPEND LIBCXXABI_TEST_DEPS cxx)
   if (LIBCXXABI_USE_LLVM_UNWINDER)
diff --git a/test/backtrace_test.pass.cpp b/test/backtrace_test.pass.cpp
index 80346c0..b9388ff 100644
--- a/test/backtrace_test.pass.cpp
+++ b/test/backtrace_test.pass.cpp
@@ -14,7 +14,7 @@
 #include <unwind.h>
 
 extern "C" _Unwind_Reason_Code
-trace_function(struct _Unwind_Context* context, void* ntraced) {
+trace_function(struct _Unwind_Context*, void* ntraced) {
   (*reinterpret_cast<size_t*>(ntraced))++;
   // We should never have a call stack this deep...
   assert(*reinterpret_cast<size_t*>(ntraced) < 20);
diff --git a/test/catch_function_03.pass.cpp b/test/catch_function_03.pass.cpp
index 4118fde..bf817a9 100644
--- a/test/catch_function_03.pass.cpp
+++ b/test/catch_function_03.pass.cpp
@@ -8,8 +8,7 @@
 //===----------------------------------------------------------------------===//
 
 // Can a noexcept function pointer be caught by a non-noexcept catch clause?
-// UNSUPPORTED: c++98, c++03, c++11, c++14
-// UNSUPPORTED: libcxxabi-no-exceptions, libcxxabi-no-qualified-function-types
+// UNSUPPORTED: libcxxabi-no-exceptions, libcxxabi-no-noexcept-function-type
 
 #include <cassert>
 
diff --git a/test/catch_member_function_pointer_02.pass.cpp b/test/catch_member_function_pointer_02.pass.cpp
index 860d8ed..5ce2359 100644
--- a/test/catch_member_function_pointer_02.pass.cpp
+++ b/test/catch_member_function_pointer_02.pass.cpp
@@ -9,8 +9,7 @@
 
 // Can a noexcept member function pointer be caught by a non-noexcept catch
 // clause?
-// UNSUPPORTED: c++98, c++03, c++11, c++14
-// UNSUPPORTED: libcxxabi-no-exceptions, libcxxabi-no-qualified-function-types
+// UNSUPPORTED: libcxxabi-no-exceptions, libcxxabi-no-noexcept-function-type
 
 #include <cassert>
 
diff --git a/test/catch_reference_nullptr.pass.cpp b/test/catch_reference_nullptr.pass.cpp
index 3ab520f..82a49df 100644
--- a/test/catch_reference_nullptr.pass.cpp
+++ b/test/catch_reference_nullptr.pass.cpp
@@ -12,12 +12,6 @@
 #include <cassert>
 #include <cstdlib>
 
-// Clang emits a warning on converting an object of type nullptr_t to bool,
-// even in generic code. Suppress it.
-#if defined(__clang__)
-#pragma clang diagnostic ignored "-Wnull-conversion"
-#endif
-
 struct A {};
 
 template<typename T, bool CanCatchNullptr>
@@ -25,7 +19,7 @@
   try {
     throw nullptr;
   } catch (T &p) {
-    assert(CanCatchNullptr && !p);
+    assert(CanCatchNullptr && !static_cast<bool>(p));
   } catch (...) {
     assert(!CanCatchNullptr);
   }
diff --git a/test/cxa_bad_cast.pass.cpp b/test/cxa_bad_cast.pass.cpp
index c863d6f..d2c3bf9 100644
--- a/test/cxa_bad_cast.pass.cpp
+++ b/test/cxa_bad_cast.pass.cpp
@@ -40,6 +40,7 @@
 #endif
         Derived &d = test_bad_cast(gB);
         assert(false);
+        ((void)d);
 #ifndef LIBCXXABI_HAS_NO_EXCEPTIONS
     } catch (std::bad_cast) {
         // success
diff --git a/test/libcxxabi/test/config.py b/test/libcxxabi/test/config.py
index 7cb1e9b..e219961 100644
--- a/test/libcxxabi/test/config.py
+++ b/test/libcxxabi/test/config.py
@@ -33,12 +33,18 @@
         self.libcxxabi_obj_root = self.get_lit_conf('libcxxabi_obj_root')
         super(Configuration, self).configure_obj_root()
 
+    def has_cpp_feature(self, feature, required_value):
+        return int(self.cxx.dumpMacros().get('__cpp_' + feature, 0)) >= required_value
+
     def configure_features(self):
         super(Configuration, self).configure_features()
         if not self.get_lit_bool('enable_exceptions', True):
             self.config.available_features.add('libcxxabi-no-exceptions')
-        if not self.cxx.addCompileFlagIfSupported(['-Xclang', '-mqualified-function-type-info']):
-            self.config.available_features.add("libcxxabi-no-qualified-function-types")
+        if not self.has_cpp_feature('noexcept_function_type', 201510):
+            self.config.available_features.add('libcxxabi-no-noexcept-function-type')
+        # test_exception_storage_nodynmem.pass.cpp fails under this specific configuration
+        if self.get_lit_bool('cxx_ext_threads', False) and self.get_lit_bool('libcxxabi_shared', False):
+            self.config.available_features.add('libcxxabi-shared-externally-threaded')
 
     def configure_compile_flags(self):
         self.cxx.compile_flags += ['-DLIBCXXABI_NO_TIMER']
@@ -49,7 +55,7 @@
         if not self.get_lit_bool('enable_threads', True):
             self.cxx.compile_flags += ['-D_LIBCXXABI_HAS_NO_THREADS']
             self.config.available_features.add('libcxxabi-no-threads')
-        super(Configuration, self).configure_compile_flags()    
+        super(Configuration, self).configure_compile_flags()
     
     def configure_compile_flags_header_includes(self):
         self.configure_config_site_header()
diff --git a/test/lit.site.cfg.in b/test/lit.site.cfg.in
index b8fb35c..9c0fdf2 100644
--- a/test/lit.site.cfg.in
+++ b/test/lit.site.cfg.in
@@ -19,6 +19,7 @@
 config.host_triple              = "@LLVM_HOST_TRIPLE@"
 config.target_triple            = "@TARGET_TRIPLE@"
 config.use_target               = len("@LIBCXXABI_TARGET_TRIPLE@") > 0
+config.cxx_ext_threads          = "@LIBCXXABI_BUILD_EXTERNAL_THREAD_LIBRARY@"
 
 # Let the main config do the real work.
 lit_config.load_config(config, "@LIBCXXABI_SOURCE_DIR@/test/lit.cfg")
diff --git a/test/test_aux_runtime.pass.cpp b/test/test_aux_runtime.pass.cpp
index a9f240e..0c9a8f2 100644
--- a/test/test_aux_runtime.pass.cpp
+++ b/test/test_aux_runtime.pass.cpp
@@ -28,8 +28,8 @@
     class B { virtual void g() {}}; 
     
     B *bp = NULL;
-    try {bool b = typeid(*bp) == typeid (A); }
-    catch ( const std::bad_typeid &bc ) { return true; }
+    try {bool b = typeid(*bp) == typeid (A); ((void)b); }
+    catch ( const std::bad_typeid &) { return true; }
     return false;
     }
     
@@ -44,12 +44,12 @@
 
     D d;
     B *bp = (B*)&d;     // cast needed to break protection
-    try { D &dr = dynamic_cast<D&> (*bp); }
-    catch ( const std::bad_cast &bc ) { return true; }
+    try { D &dr = dynamic_cast<D&> (*bp); ((void)dr); }
+    catch ( const std::bad_cast & ) { return true; }
     return false;
     }
     
-int main ( int argc, char *argv [] ) {
+int main ( ) {
     int ret_val = 0;
     
     if ( !bad_typeid_test ()) {
diff --git a/test/test_aux_runtime_op_array_new.pass.cpp b/test/test_aux_runtime_op_array_new.pass.cpp
index 701a457..d4a63d7 100644
--- a/test/test_aux_runtime_op_array_new.pass.cpp
+++ b/test/test_aux_runtime_op_array_new.pass.cpp
@@ -28,7 +28,7 @@
     return false;
 }
 
-int main(int argc, char *argv []) {
+int main() {
     int ret_val = 0;
 
     if ( !bad_array_new_length_test ()) {
diff --git a/test/test_demangle.pass.cpp b/test/test_demangle.pass.cpp
index af16b56..4eb6a88 100644
--- a/test/test_demangle.pass.cpp
+++ b/test/test_demangle.pass.cpp
@@ -29594,6 +29594,14 @@
     // NOTE: disable this test since it is a negative test case, you cannot demangle a non-mangled symbol
     // {"\x6D", nullptr}, 	// This use to crash with ASAN
     {"_ZTIU4_farrVKPi", "typeinfo for int* const volatile restrict _far"},
+
+    // mangled names can include type manglings too, which don't start with _Z:
+    {"i", "int"},
+
+    {"PKFvRiE", "void (*)(int&) const"},
+    // FIXME(compnerd) pretty print this as void (*)(unsigned long &) volatile &&
+    {"PVFvRmOE", "void (*)(unsigned long&)  volatile&&"},
+    {"PFvRmOE", "void (*)(unsigned long&) &&"},
 };
 
 const unsigned N = sizeof(cases) / sizeof(cases[0]);
diff --git a/test/test_exception_storage.pass.cpp b/test/test_exception_storage.pass.cpp
index d509227..67ab51d 100644
--- a/test/test_exception_storage.pass.cpp
+++ b/test/test_exception_storage.pass.cpp
@@ -12,7 +12,7 @@
 #include <cstdlib>
 #include <algorithm>
 #include <iostream>
-#include "../src/threading_support.h"
+#include <__threading_support>
 #include <unistd.h>
 
 #include "../src/cxa_exception.hpp"
@@ -39,18 +39,18 @@
 #ifndef _LIBCXXABI_HAS_NO_THREADS
 #define NUMTHREADS  10
 size_t                 thread_globals [ NUMTHREADS ] = { 0 };
-__libcxxabi_thread_t   threads        [ NUMTHREADS ];
+std::__libcpp_thread_t   threads        [ NUMTHREADS ];
 #endif
 
-int main ( int argc, char *argv [] ) {
+int main () {
     int retVal = 0;
 
 #ifndef _LIBCXXABI_HAS_NO_THREADS
 //  Make the threads, let them run, and wait for them to finish
     for ( int i = 0; i < NUMTHREADS; ++i )
-        __libcxxabi_thread_create ( threads + i, thread_code, (void *) (thread_globals + i));
+        std::__libcpp_thread_create ( threads + i, thread_code, (void *) (thread_globals + i));
     for ( int i = 0; i < NUMTHREADS; ++i )
-        __libcxxabi_thread_join ( &threads [ i ] );
+        std::__libcpp_thread_join ( &threads [ i ] );
 
     for ( int i = 0; i < NUMTHREADS; ++i )
         if ( 0 == thread_globals [ i ] ) {
diff --git a/test/test_fallback_malloc.pass.cpp b/test/test_fallback_malloc.pass.cpp
index 250a738..e29e128 100644
--- a/test/test_fallback_malloc.pass.cpp
+++ b/test/test_fallback_malloc.pass.cpp
@@ -10,7 +10,7 @@
 #include <iostream>
 #include <deque>
 
-#include "../src/threading_support.h"
+#include <__threading_support>
 
 typedef std::deque<void *> container;
 
@@ -165,7 +165,7 @@
     }
 
     
-int main ( int argc, char *argv [] ) {
+int main () {
     print_free_list ();
 
     char *p = (char *) fallback_malloc ( 1024 );    // too big!
diff --git a/test/test_guard.pass.cpp b/test/test_guard.pass.cpp
index 2312b51..ef86717 100644
--- a/test/test_guard.pass.cpp
+++ b/test/test_guard.pass.cpp
@@ -25,11 +25,12 @@
     }
     void helper() {
         static int a = increment();
+        ((void)a);
     }
     void test() {
-        static int a = increment();
+        static int a = increment(); ((void)a);
         assert(run_count == 1);
-        static int b = increment();
+        static int b = increment(); ((void)b);
         assert(run_count == 2);
         helper();
         assert(run_count == 3);
@@ -50,7 +51,8 @@
     void helper() {
         try {
             static int a = increment();
-            assert(0);
+            assert(false);
+            ((void)a);
         } catch (...) {}
     }
     void test() {
@@ -71,12 +73,12 @@
     }
 
     int one() {
-        static int b = zero();
+        static int b = zero(); ((void)b);
         return 0;
     }
 
     void test() {
-        static int a = one();
+        static int a = one(); ((void)a);
     }
 }
 
@@ -91,7 +93,7 @@
     }
 
     void helper() {
-        static int a = increment();
+        static int a = increment(); ((void)a);
     }
 
     void test() {
@@ -112,16 +114,16 @@
     }
 
     int one() {
-        static int b = zero();
+        static int b = zero(); ((void)b);
         return 0;
     }
 
     void another_helper() {
-        static int a = one();
+        static int a = one(); ((void)a);
     }
 
     void helper() {
-        static int a = one();
+        static int a = one(); ((void)a);
         std::thread t(another_helper);
         t.join();
     }
diff --git a/test/test_vector1.pass.cpp b/test/test_vector1.pass.cpp
index 978ed3c..0f3acd2 100644
--- a/test/test_vector1.pass.cpp
+++ b/test/test_vector1.pass.cpp
@@ -25,36 +25,36 @@
     std::free ( p ); 
     }
 
-void my_dealloc3 ( void *p, size_t   sz   ) {
+void my_dealloc3 ( void *p, size_t ) {
 //  std::printf ( "Freeing %lx (size %ld)\n", (unsigned long) p, sz );  
     std::free ( p ); 
     }
 
-void my_construct ( void *p ) {
+void my_construct ( void * ) {
 //  std::printf ( "Constructing %lx\n", (unsigned long) p );
     }
 
-void my_destruct  ( void *p ) {
+void my_destruct  ( void * ) {
 //  std::printf ( "Destructing  %lx\n", (unsigned long) p );
     }
 
 int gCounter;
-void count_construct ( void *p ) { ++gCounter; }
-void count_destruct  ( void *p ) { --gCounter; }
+void count_construct ( void * ) { ++gCounter; }
+void count_destruct  ( void * ) { --gCounter; }
 
 
 int gConstructorCounter;
 int gConstructorThrowTarget;
 int gDestructorCounter;
 int gDestructorThrowTarget;
-void throw_construct ( void *p ) {
+void throw_construct ( void * ) {
 #ifndef LIBCXXABI_HAS_NO_EXCEPTIONS
     if ( gConstructorCounter   == gConstructorThrowTarget )
         throw 1;
     ++gConstructorCounter;
 #endif
 }
-void throw_destruct  ( void *p ) {
+void throw_destruct  ( void * ) {
 #ifndef LIBCXXABI_HAS_NO_EXCEPTIONS
     if ( ++gDestructorCounter  == gDestructorThrowTarget  )
         throw 2;
@@ -269,7 +269,7 @@
     }
 #endif
 
-int main ( int argc, char *argv [] ) {
+int main () {
     int retVal = 0;
     retVal += test_empty ();
     retVal += test_counted ();
diff --git a/test/test_vector2.pass.cpp b/test/test_vector2.pass.cpp
index 4bc279d..5a5ff06 100644
--- a/test/test_vector2.pass.cpp
+++ b/test/test_vector2.pass.cpp
@@ -28,30 +28,30 @@
     std::free ( p ); 
     }
 
-void my_dealloc3 ( void *p, size_t   sz   ) {
+void my_dealloc3 ( void *p, size_t ) {
 //  std::printf ( "Freeing %lx (size %ld)\n", (unsigned long) p, sz );  
     std::free ( p ); 
     }
 
-void my_construct ( void *p ) {
+void my_construct ( void *) {
 //  std::printf ( "Constructing %lx\n", (unsigned long) p );
     }
 
-void my_destruct  ( void *p ) {
+void my_destruct  ( void *) {
 //  std::printf ( "Destructing  %lx\n", (unsigned long) p );
     }
 
 int gCounter;
-void count_construct ( void *p ) { ++gCounter; }
-void count_destruct  ( void *p ) { --gCounter; }
+void count_construct ( void * ) { ++gCounter; }
+void count_destruct  ( void * ) { --gCounter; }
 
 
 int gConstructorCounter;
 int gConstructorThrowTarget;
 int gDestructorCounter;
 int gDestructorThrowTarget;
-void throw_construct ( void *p ) { if ( gConstructorCounter   == gConstructorThrowTarget ) throw 1; ++gConstructorCounter; }
-void throw_destruct  ( void *p ) { if ( ++gDestructorCounter  == gDestructorThrowTarget  ) throw 2; }
+void throw_construct ( void * ) { if ( gConstructorCounter   == gConstructorThrowTarget ) throw 1; ++gConstructorCounter; }
+void throw_destruct  ( void * ) { if ( ++gDestructorCounter  == gDestructorThrowTarget  ) throw 2; }
 
 struct vec_on_stack {
     void *storage;
@@ -78,7 +78,7 @@
 
 
 
-int main ( int argc, char *argv [] ) {
+int main () {
     std::set_terminate ( my_terminate );
     test_exception_in_destructor ();
     return 1;       // we failed if we get here
diff --git a/test/test_vector3.pass.cpp b/test/test_vector3.pass.cpp
index a817125..2f983ef 100644
--- a/test/test_vector3.pass.cpp
+++ b/test/test_vector3.pass.cpp
@@ -48,7 +48,7 @@
   t->~T();
 }
 
-int main( int argc, char *argv [])
+int main()
 {
   std::set_terminate(my_terminate);
   {
diff --git a/test/thread_local_destruction_order.pass.cpp b/test/thread_local_destruction_order.pass.cpp
index 23a0fdb..0bb359e 100644
--- a/test/thread_local_destruction_order.pass.cpp
+++ b/test/thread_local_destruction_order.pass.cpp
@@ -7,6 +7,10 @@
 //
 //===----------------------------------------------------------------------===//
 
+// Darwin TLV finalization routines fail when creating a thread-local variable
+// in the destructor for another thread-local variable:
+// http://lists.llvm.org/pipermail/cfe-dev/2016-November/051376.html
+// XFAIL: darwin
 // UNSUPPORTED: c++98, c++03
 // UNSUPPORTED: libcxxabi-no-threads
 
diff --git a/test/uncaught_exceptions.pass.cpp b/test/uncaught_exceptions.pass.cpp
index 0c64067..fe7374d 100644
--- a/test/uncaught_exceptions.pass.cpp
+++ b/test/uncaught_exceptions.pass.cpp
@@ -23,9 +23,9 @@
     };
 
 struct B {
-    B(int cnt) : data_(cnt) {}
+    B(unsigned cnt) : data_(cnt) {}
     ~B() { assert( data_ == __cxxabiv1::__cxa_uncaught_exceptions()); }
-    int data_;
+    unsigned data_;
     };
 
 int main ()
diff --git a/test/unwind_01.pass.cpp b/test/unwind_01.pass.cpp
index 1bf6cfd..2730fdd 100644
--- a/test/unwind_01.pass.cpp
+++ b/test/unwind_01.pass.cpp
@@ -11,6 +11,10 @@
 
 #include <assert.h>
 
+#if defined(__GNUC__)
+#pragma GCC diagnostic ignored "-Wunreachable-code"
+#endif
+
 struct A
 {
     static int count;
diff --git a/test/unwind_02.pass.cpp b/test/unwind_02.pass.cpp
index 90dc25a..2c6e1d6 100644
--- a/test/unwind_02.pass.cpp
+++ b/test/unwind_02.pass.cpp
@@ -8,9 +8,14 @@
 //===----------------------------------------------------------------------===//
 
 // UNSUPPORTED: libcxxabi-no-exceptions
+// REQUIRES: c++98 || c++03 || c++11 || c++14
 
 #include <assert.h>
 
+#if defined(__GNUC__)
+#pragma GCC diagnostic ignored "-Wunreachable-code"
+#endif
+
 struct A
 {
     static int count;
diff --git a/test/unwind_03.pass.cpp b/test/unwind_03.pass.cpp
index bda8c31..6bc16bd 100644
--- a/test/unwind_03.pass.cpp
+++ b/test/unwind_03.pass.cpp
@@ -8,11 +8,16 @@
 //===----------------------------------------------------------------------===//
 
 // UNSUPPORTED: libcxxabi-no-exceptions
+// REQUIRES: c++98 || c++03 || c++11 || c++14
 
 #include <exception>
 #include <stdlib.h>
 #include <assert.h>
 
+#if defined(__GNUC__)
+#pragma GCC diagnostic ignored "-Wunreachable-code"
+#endif
+
 struct A
 {
     static int count;
diff --git a/test/unwind_04.pass.cpp b/test/unwind_04.pass.cpp
index b5a08af..1b75994 100644
--- a/test/unwind_04.pass.cpp
+++ b/test/unwind_04.pass.cpp
@@ -8,11 +8,16 @@
 //===----------------------------------------------------------------------===//
 
 // UNSUPPORTED: libcxxabi-no-exceptions
+// REQUIRES: c++98 || c++03 || c++11 || c++14
 
 #include <exception>
 #include <stdlib.h>
 #include <assert.h>
 
+#if defined(__GNUC__)
+#pragma GCC diagnostic ignored "-Wunreachable-code"
+#endif
+
 struct A
 {
     static int count;
diff --git a/test/unwind_05.pass.cpp b/test/unwind_05.pass.cpp
index 3dea2aa..d1f5fcd 100644
--- a/test/unwind_05.pass.cpp
+++ b/test/unwind_05.pass.cpp
@@ -8,11 +8,16 @@
 //===----------------------------------------------------------------------===//
 
 // UNSUPPORTED: libcxxabi-no-exceptions
+// REQUIRES: c++98 || c++03 || c++11 || c++14
 
 #include <exception>
 #include <stdlib.h>
 #include <assert.h>
 
+#if defined(__GNUC__)
+#pragma GCC diagnostic ignored "-Wunreachable-code"
+#endif
+
 struct A
 {
     static int count;
diff --git a/test/unwind_06.pass.cpp b/test/unwind_06.pass.cpp
index a30efb1..e712566 100644
--- a/test/unwind_06.pass.cpp
+++ b/test/unwind_06.pass.cpp
@@ -101,9 +101,9 @@
   double g = get(0);
   double h = get(0);
   for (counter = 100; counter; --counter)
-    a += get(1) + b+c+d+e+f+g;
+    a += get(1) + b+c+d+e+f+g+h;
   if (v) throw 10;
-  return get(0)+a+b+c+d+e+f+g;
+  return get(0)+a+b+c+d+e+f+g+h;
 }
 
 double try8(bool v) {
@@ -117,9 +117,9 @@
   double h = get(0);
   double i = get(0);
   for (counter = 100; counter; --counter)
-    a += get(1) + b+c+d+e+f+g+i;
+    a += get(1) + b+c+d+e+f+g+h+i;
   if (v) throw 10;
-  return get(0)+a+b+c+d+e+f+g+i;
+  return get(0)+a+b+c+d+e+f+g+h+i;
 }