summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorShoaib Meenai <smeenai@fb.com>2017-03-28 19:33:31 +0000
committerShoaib Meenai <smeenai@fb.com>2017-03-28 19:33:31 +0000
commitc7cd73e8b89ae0a37ed056a9dbad9e6af42a255c (patch)
tree817ba7fa1d51727e96b8faee9912c0f13960ffa8
parentb5a46c1f45a7ecbcfc99b682000bbc8c0b7712a5 (diff)
downloadbcm5719-llvm-c7cd73e8b89ae0a37ed056a9dbad9e6af42a255c.tar.gz
bcm5719-llvm-c7cd73e8b89ae0a37ed056a9dbad9e6af42a255c.zip
[libc++] Add a key function for bad_function_call
Summary: bad_function_call is currently an empty class, so any object files using that class will end up with their own copy of its typeinfo, typeinfo name and vtable, leading to unnecessary duplication that has to be resolved by the dynamic linker. Instead, give bad_function_call a key function and put a definition for that key function in libc++ itself, to centralize the typeinfo and vtable. This is consistent with the behavior for other exception classes. The key functions are defined in libc++ rather than libc++abi since the class is defined in the libc++ versioning namespace, so ABI compatibility with libstdc++ is not a concern. Guard this change behind an ABI macro, since it isn't backwards compatible (i.e., clients built against the new libc++ headers wouldn't be able to run against an older libc++ library). Reviewers: mclow.lists, EricWF Subscribers: mgorny, cfe-commits Differential Revision: https://reviews.llvm.org/D27387 llvm-svn: 298937
-rw-r--r--libcxx/include/__config4
-rw-r--r--libcxx/include/functional6
-rw-r--r--libcxx/lib/CMakeLists.txt2
-rw-r--r--libcxx/src/functional.cpp26
4 files changed, 37 insertions, 1 deletions
diff --git a/libcxx/include/__config b/libcxx/include/__config
index 9b48a70ffd5..c847418602a 100644
--- a/libcxx/include/__config
+++ b/libcxx/include/__config
@@ -58,6 +58,10 @@
// `pointer_safety` and `get_pointer_safety()` will no longer be available
// in C++03.
#define _LIBCPP_ABI_POINTER_SAFETY_ENUM_TYPE
+// Define a key function for `bad_function_call` in the library, to centralize
+// its vtable and typeinfo to libc++ rather than having all other libraries
+// using that class define their own copies.
+#define _LIBCPP_ABI_BAD_FUNCTION_CALL_KEY_FUNCTION
#elif _LIBCPP_ABI_VERSION == 1
#if !defined(_WIN32)
// Enable compiling copies of now inline methods into the dylib to support
diff --git a/libcxx/include/functional b/libcxx/include/functional
index 977ada67f33..fecac4e41f8 100644
--- a/libcxx/include/functional
+++ b/libcxx/include/functional
@@ -1389,6 +1389,12 @@ mem_fn(_Rp _Tp::* __pm) _NOEXCEPT
class _LIBCPP_EXCEPTION_ABI bad_function_call
: public exception
{
+#ifdef _LIBCPP_ABI_BAD_FUNCTION_CALL_KEY_FUNCTION
+public:
+ virtual ~bad_function_call() _NOEXCEPT;
+
+ virtual const char* what() const _NOEXCEPT;
+#endif
};
_LIBCPP_NORETURN inline _LIBCPP_ALWAYS_INLINE
diff --git a/libcxx/lib/CMakeLists.txt b/libcxx/lib/CMakeLists.txt
index 66bb14c89a1..a8dd4eb8aef 100644
--- a/libcxx/lib/CMakeLists.txt
+++ b/libcxx/lib/CMakeLists.txt
@@ -177,7 +177,7 @@ endif()
split_list(LIBCXX_COMPILE_FLAGS)
split_list(LIBCXX_LINK_FLAGS)
-# Add a object library that contains the compiled source files.
+# Add an object library that contains the compiled source files.
add_library(cxx_objects OBJECT ${exclude_from_all} ${LIBCXX_SOURCES} ${LIBCXX_HEADERS})
if(WIN32 AND NOT MINGW)
target_compile_definitions(cxx_objects
diff --git a/libcxx/src/functional.cpp b/libcxx/src/functional.cpp
new file mode 100644
index 00000000000..5c2646f01b2
--- /dev/null
+++ b/libcxx/src/functional.cpp
@@ -0,0 +1,26 @@
+//===----------------------- functional.cpp -------------------------------===//
+//
+// The LLVM Compiler Infrastructure
+//
+// This file is dual licensed under the MIT and the University of Illinois Open
+// Source Licenses. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+
+#include "functional"
+
+_LIBCPP_BEGIN_NAMESPACE_STD
+
+#ifdef _LIBCPP_ABI_BAD_FUNCTION_CALL_KEY_FUNCTION
+bad_function_call::~bad_function_call() _NOEXCEPT
+{
+}
+
+const char*
+bad_function_call::what() const _NOEXCEPT
+{
+ return "std::bad_function_call";
+}
+#endif
+
+_LIBCPP_END_NAMESPACE_STD
OpenPOWER on IntegriCloud