[libc++] Use exclude_from_explicit_instantiation instead of always_inline
authorLouis Dionne <ldionne@apple.com>
Mon, 29 Oct 2018 17:30:04 +0000 (17:30 +0000)
committerLouis Dionne <ldionne@apple.com>
Mon, 29 Oct 2018 17:30:04 +0000 (17:30 +0000)
Summary:
This commit adopts the exclude_from_explicit_instantiation attribute discussed
at [1] and reviewed in [2] in libc++ to supplant the use of __always_inline__
for visibility purposes.

This change means that users wanting to link together translation units built
with different versions of libc++'s headers into the same final linked image
MUST define the _LIBCPP_HIDE_FROM_ABI_PER_TU macro to 1 when building those
TUs. Doing otherwise will lead to ODR violations and ABI issues.

[1]: http://lists.llvm.org/pipermail/cfe-dev/2018-August/059024.html
[2]: https://reviews.llvm.org/D51789

Reviewers: rsmith, EricWF

Subscribers: dexonsmith, libcxx-commits

Differential Revision: https://reviews.llvm.org/D52405

llvm-svn: 345516

libcxx/docs/ReleaseNotes.rst
libcxx/include/__config

index 52d7a1ed42fd343955ed0a37fa4fff91283b5042..4cf5182a7f33cb2108391f9c05da371fdefdb690 100644 (file)
@@ -41,3 +41,10 @@ New Features
 API Changes
 -----------
 - Building libc++ for Mac OSX 10.6 is not supported anymore.
+- Starting with LLVM 8.0.0, users that wish to link together translation units
+  built with different versions of libc++'s headers into the same final linked
+  image MUST define the _LIBCPP_HIDE_FROM_ABI_PER_TU macro to 1 when building
+  those translation units. Not defining _LIBCPP_HIDE_FROM_ABI_PER_TU to 1 and
+  linking translation units built with different versions of libc++'s headers
+  together may lead to ODR violations and ABI issues. On the flipside, code
+  size improvements should be expected for everyone not defining the macro.
index f6020748e1bb16b705ae369dc92102aa8e313eb7..6f133b678a075dc2de0b976fa21c00d8d6f13914 100644 (file)
@@ -787,6 +787,15 @@ _LIBCPP_BEGIN_NAMESPACE_STD _LIBCPP_END_NAMESPACE_STD
 #  define _LIBCPP_INTERNAL_LINKAGE _LIBCPP_ALWAYS_INLINE
 #endif
 
+#if __has_attribute(exclude_from_explicit_instantiation)
+#  define _LIBCPP_EXCLUDE_FROM_EXPLICIT_INSTANTIATION __attribute__ ((__exclude_from_explicit_instantiation__))
+#else
+   // Try to approximate the effect of exclude_from_explicit_instantiation
+   // (which is that entities are not assumed to be provided by explicit
+   // template instantitations in the dylib) by always inlining those entities.
+#  define _LIBCPP_EXCLUDE_FROM_EXPLICIT_INSTANTIATION _LIBCPP_ALWAYS_INLINE
+#endif
+
 #ifndef _LIBCPP_HIDE_FROM_ABI_PER_TU
 #  ifndef _LIBCPP_HIDE_FROM_ABI_PER_TU_BY_DEFAULT
 #    define _LIBCPP_HIDE_FROM_ABI_PER_TU 0
@@ -799,7 +808,7 @@ _LIBCPP_BEGIN_NAMESPACE_STD _LIBCPP_END_NAMESPACE_STD
 #  if _LIBCPP_HIDE_FROM_ABI_PER_TU
 #    define _LIBCPP_HIDE_FROM_ABI _LIBCPP_HIDDEN _LIBCPP_INTERNAL_LINKAGE
 #  else
-#    define _LIBCPP_HIDE_FROM_ABI _LIBCPP_HIDDEN _LIBCPP_ALWAYS_INLINE
+#    define _LIBCPP_HIDE_FROM_ABI _LIBCPP_HIDDEN _LIBCPP_EXCLUDE_FROM_EXPLICIT_INSTANTIATION
 #  endif
 #endif