[libc++] Add visibility annotations to the std namespace with GCC (#133233)

This allows us to remove the need for `_LIBCPP_TEMPLATE_VIS` and fixes a
bunch of missing annotations for RTTI when used across dylib boundaries.
`_LIBCPP_TEMPLATE_VIS` itself will be removed in a separate patch, since
it touches a lot of code.

This patch is a no-op for Clang. Only GCC is affected.
This commit is contained in:
Nikolas Klauser
2025-04-02 22:12:59 +02:00
committed by GitHub
parent fb0e7b5f16
commit c59d3a2684
2 changed files with 13 additions and 11 deletions

View File

@@ -77,7 +77,10 @@ LLVM 22
ABI Affecting Changes
---------------------
- TODO
- When using GCC, the ``std`` namespace is now annotated with ``[[gnu::visibility("default")]]``. This may cause more
symbols to be exported from shared libraries when building with ``-fvisibility=hidden``. This also fixes RTTI
comparison between shared libraries, since all RTTI has the correct visibility now. There is no behaviour change on
Clang.
Build System Changes

View File

@@ -386,7 +386,7 @@ typedef __char32_t char32_t;
# define _LIBCPP_METHOD_TEMPLATE_IMPLICIT_INSTANTIATION_VIS
# define _LIBCPP_TEMPLATE_VIS
# define _LIBCPP_TEMPLATE_DATA_VIS
# define _LIBCPP_TYPE_VISIBILITY_DEFAULT
# define _LIBCPP_NAMESPACE_VISIBILITY
# else
@@ -414,17 +414,16 @@ typedef __char32_t char32_t;
# define _LIBCPP_METHOD_TEMPLATE_IMPLICIT_INSTANTIATION_VIS
# endif
// GCC doesn't support the type_visibility attribute, so we have to keep the visibility attribute on templates
# if !defined(_LIBCPP_DISABLE_VISIBILITY_ANNOTATIONS) && !__has_attribute(__type_visibility__)
# define _LIBCPP_TEMPLATE_VIS __attribute__((__visibility__("default")))
# else
# define _LIBCPP_TEMPLATE_VIS
# endif
// This is kept to avoid a huge library-wide diff in the first step.
// TODO: Remove this in a follow-up patch
# define _LIBCPP_TEMPLATE_VIS
# if !defined(_LIBCPP_DISABLE_VISIBILITY_ANNOTATIONS) && __has_attribute(__type_visibility__)
# define _LIBCPP_TYPE_VISIBILITY_DEFAULT __attribute__((__type_visibility__("default")))
# define _LIBCPP_NAMESPACE_VISIBILITY __attribute__((__type_visibility__("default")))
# elif !defined(_LIBCPP_DISABLE_VISIBILITY_ANNOTATIONS)
# define _LIBCPP_NAMESPACE_VISIBILITY __attribute__((__visibility__("default")))
# else
# define _LIBCPP_TYPE_VISIBILITY_DEFAULT
# define _LIBCPP_NAMESPACE_VISIBILITY
# endif
# endif // defined(_LIBCPP_OBJECT_FORMAT_COFF)
@@ -583,7 +582,7 @@ typedef __char32_t char32_t;
// If it's not clear whether using the unversioned namespace is the correct thing to do, it's not. The versioned
// namespace (_LIBCPP_BEGIN_NAMESPACE_STD) should almost always be used.
# define _LIBCPP_BEGIN_UNVERSIONED_NAMESPACE_STD \
_LIBCPP_PUSH_EXTENSION_DIAGNOSTICS namespace _LIBCPP_TYPE_VISIBILITY_DEFAULT std {
_LIBCPP_PUSH_EXTENSION_DIAGNOSTICS namespace _LIBCPP_NAMESPACE_VISIBILITY std {
# define _LIBCPP_END_UNVERSIONED_NAMESPACE_STD } _LIBCPP_POP_EXTENSION_DIAGNOSTICS