Use __attribute__((internal_linkage)) when available.

Summary:
This patch has been a long time coming (Thanks @eugenis). It changes `_LIBCPP_INLINE_VISIBILITY` to use `__attribute__((internal_linkage))` instead of `__attribute__((visibility("hidden"), always_inline))`.

The point of `_LIBCPP_INLINE_VISIBILITY` is to prevent inline functions from being exported from both the libc++ library and from user libraries. This helps libc++ better manage it's ABI.
Previously this was done by forcing inlining and modifying the symbols visibility. However inlining isn't guaranteed and symbol visibility only affects shared libraries making this an imperfect solution.  `internal_linkage` improves this situation by making all symbols local to the TU they are emitted in, regardless of inlining or visibility. IIRC the effect of applying `__attribute__((internal_linkage))` to an inline function is the same as applying `static`.

For more information about the attribute see: http://lists.llvm.org/pipermail/cfe-dev/2015-October/045580.html

Most of the work for this patch was done by @eugenis.


Reviewers: mclow.lists, eugenis

Subscribers: eugenis, cfe-commits

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

git-svn-id: https://llvm.org/svn/llvm-project/libcxx/trunk@282345 91177308-0d34-0410-b5e6-96231b3b80d8
This commit is contained in:
Eric Fiselier
2016-09-25 03:14:13 +00:00
parent 1277962876
commit 1deaf196f4
2 changed files with 35 additions and 2 deletions

View File

@@ -29,6 +29,29 @@ template
string
operator+<char, char_traits<char>, allocator<char> >(char const*, string const&);
// These external instantiations are required to maintain dylib compatibility
// for ABI v1 when using __attribute__((internal_linkage)) as opposed to
// __attribute__((visibility("hidden"), always_inline)).
#if _LIBCPP_ABI_EXTERN_TEMPLATE_SYMBOLS_VERSION == 1
template basic_string<char>::iterator
basic_string<char>::insert(basic_string<char>::const_iterator,
char const *, char const *);
template basic_string<wchar_t>::iterator
basic_string<wchar_t>::insert(basic_string<wchar_t>::const_iterator,
wchar_t const *, wchar_t const *);
template basic_string<char> &
basic_string<char>::replace(basic_string<char>::const_iterator,
basic_string<char>::const_iterator,
char const *, char const *);
template basic_string<wchar_t> &
basic_string<wchar_t>::replace(basic_string<wchar_t>::const_iterator,
basic_string<wchar_t>::const_iterator,
wchar_t const *, wchar_t const *);
#endif // _LIBCPP_ABI_EXTERN_TEMPLATE_SYMBOLS_VERSION
namespace
{