diff --git a/libcxx/CMakeLists.txt b/libcxx/CMakeLists.txt index c93a1e24f73e..f4c7c93cf750 100644 --- a/libcxx/CMakeLists.txt +++ b/libcxx/CMakeLists.txt @@ -120,6 +120,7 @@ set(LIBCXX_ABI_VERSION ${DEFAULT_ABI_VERSION} CACHE STRING "ABI version of libc+ option(LIBCXX_ABI_UNSTABLE "Unstable ABI of libc++." OFF) option(LIBCXX_ABI_FORCE_ITANIUM "Ignore auto-detection and force use of the Itanium ABI.") option(LIBCXX_ABI_FORCE_MICROSOFT "Ignore auto-detection and force use of the Microsoft ABI.") +option(LIBCXX_HIDE_FROM_ABI_PER_TU_BY_DEFAULT "Enable per TU ABI insulation by default. To be used by vendors." OFF) set(LIBCXX_ABI_DEFINES "" CACHE STRING "A semicolon separated list of ABI macros to define in the site config header.") option(LIBCXX_USE_COMPILER_RT "Use compiler-rt instead of libgcc" OFF) @@ -662,6 +663,7 @@ endif() config_define_if(LIBCXX_ABI_UNSTABLE _LIBCPP_ABI_UNSTABLE) config_define_if(LIBCXX_ABI_FORCE_ITANIUM _LIBCPP_ABI_FORCE_ITANIUM) config_define_if(LIBCXX_ABI_FORCE_MICROSOFT _LIBCPP_ABI_FORCE_MICROSOFT) +config_define_if(LIBCXX_HIDE_FROM_ABI_PER_TU_BY_DEFAULT _LIBCPP_HIDE_FROM_ABI_PER_TU_BY_DEFAULT) config_define_if_not(LIBCXX_ENABLE_GLOBAL_FILESYSTEM_NAMESPACE _LIBCPP_HAS_NO_GLOBAL_FILESYSTEM_NAMESPACE) config_define_if_not(LIBCXX_ENABLE_STDIN _LIBCPP_HAS_NO_STDIN) diff --git a/libcxx/docs/BuildingLibcxx.rst b/libcxx/docs/BuildingLibcxx.rst index d0b03c675c8b..daf9229a0d05 100644 --- a/libcxx/docs/BuildingLibcxx.rst +++ b/libcxx/docs/BuildingLibcxx.rst @@ -332,6 +332,15 @@ libc++ Feature Options Use the specified GCC toolchain and standard library when building the native stdlib benchmark tests. +.. option:: LIBCXX_HIDE_FROM_ABI_PER_TU_BY_DEFAULT:BOOL + + **Default**: ``OFF`` + + Pick the default for whether to constrain ABI-unstable symbols to + each individual translation unit. This setting controls whether + `_LIBCPP_HIDE_FROM_ABI_PER_TU_BY_DEFAULT` is defined by default -- + see the documentation of that macro for details. + libc++ ABI Feature Options -------------------------- diff --git a/libcxx/docs/DesignDocs/VisibilityMacros.rst b/libcxx/docs/DesignDocs/VisibilityMacros.rst index 493b445750e7..9a757ff53f38 100644 --- a/libcxx/docs/DesignDocs/VisibilityMacros.rst +++ b/libcxx/docs/DesignDocs/VisibilityMacros.rst @@ -42,9 +42,7 @@ Visibility Macros **_LIBCPP_HIDE_FROM_ABI** Mark a function as not being part of the ABI of any final linked image that - uses it, and also as being internal to each TU that uses that function. In - other words, the address of a function marked with this attribute is not - guaranteed to be the same across translation units. + uses it. **_LIBCPP_HIDE_FROM_ABI_AFTER_V1** Mark a function as being hidden from the ABI (per `_LIBCPP_HIDE_FROM_ABI`) @@ -61,6 +59,41 @@ Visibility Macros ABI, we should create a new _LIBCPP_HIDE_FROM_ABI_AFTER_XXX macro, and we can use it to start removing symbols from the ABI after that stable version. +**_LIBCPP_HIDE_FROM_ABI_PER_TU** + This macro controls whether symbols hidden from the ABI with `_LIBCPP_HIDE_FROM_ABI` + are local to each translation unit in addition to being local to each final + linked image. This macro is defined to either 0 or 1. When it is defined to + 1, translation units compiled with different versions of libc++ can be linked + together, since all non ABI-facing functions are local to each translation unit. + This allows static archives built with different versions of libc++ to be linked + together. This also means that functions marked with `_LIBCPP_HIDE_FROM_ABI` + are not guaranteed to have the same address across translation unit boundaries. + + When the macro is defined to 0, there is no guarantee that translation units + compiled with different versions of libc++ can interoperate. However, this + leads to code size improvements, since non ABI-facing functions can be + deduplicated across translation unit boundaries. + + This macro can be defined by users to control the behavior they want from + libc++. The default value of this macro (0 or 1) is controlled by whether + `_LIBCPP_HIDE_FROM_ABI_PER_TU_BY_DEFAULT` is defined, which is intended to + be used by vendors only (see below). + +**_LIBCPP_HIDE_FROM_ABI_PER_TU_BY_DEFAULT** + This macro controls the default value for `_LIBCPP_HIDE_FROM_ABI_PER_TU`. + When the macro is defined, per TU ABI insulation is enabled by default, and + `_LIBCPP_HIDE_FROM_ABI_PER_TU` is defined to 1 unless overriden by users. + Otherwise, per TU ABI insulation is disabled by default, and + `_LIBCPP_HIDE_FROM_ABI_PER_TU` is defined to 0 unless overriden by users. + + This macro is intended for vendors to control whether they want to ship + libc++ with per TU ABI insulation enabled by default. Users can always + control the behavior they want by defining `_LIBCPP_HIDE_FROM_ABI_PER_TU` + appropriately. + + By default, this macro is not defined, which means that per TU ABI insulation + is not provided unless explicitly overriden by users. + **_LIBCPP_TYPE_VIS** Mark a type's typeinfo, vtable and members as having default visibility. This attribute cannot be used on class templates. diff --git a/libcxx/include/__config b/libcxx/include/__config index 06af4dc61a39..b8c2c33ea891 100644 --- a/libcxx/include/__config +++ b/libcxx/include/__config @@ -798,8 +798,20 @@ namespace std { # define _LIBCPP_INTERNAL_LINKAGE _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 +# else +# define _LIBCPP_HIDE_FROM_ABI_PER_TU 1 +# endif +#endif + #ifndef _LIBCPP_HIDE_FROM_ABI -# define _LIBCPP_HIDE_FROM_ABI _LIBCPP_HIDDEN _LIBCPP_INTERNAL_LINKAGE +# 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 +# endif #endif #ifdef _LIBCPP_BUILDING_LIBRARY diff --git a/libcxx/include/__config_site.in b/libcxx/include/__config_site.in index 8d980ff57cc8..7c7c226c4922 100644 --- a/libcxx/include/__config_site.in +++ b/libcxx/include/__config_site.in @@ -14,6 +14,7 @@ #cmakedefine _LIBCPP_ABI_UNSTABLE #cmakedefine _LIBCPP_ABI_FORCE_ITANIUM #cmakedefine _LIBCPP_ABI_FORCE_MICROSOFT +#cmakedefine _LIBCPP_HIDE_FROM_ABI_PER_TU_BY_DEFAULT #cmakedefine _LIBCPP_HAS_NO_GLOBAL_FILESYSTEM_NAMESPACE #cmakedefine _LIBCPP_HAS_NO_STDIN #cmakedefine _LIBCPP_HAS_NO_STDOUT diff --git a/libcxx/utils/libcxx/test/config.py b/libcxx/utils/libcxx/test/config.py index 6542ceb6fb58..186a273a5b51 100644 --- a/libcxx/utils/libcxx/test/config.py +++ b/libcxx/utils/libcxx/test/config.py @@ -677,7 +677,8 @@ class Configuration(object): if feature_macros[m]: define += '=%s' % (feature_macros[m]) self.cxx.compile_flags += [define] - if m == '_LIBCPP_DISABLE_VISIBILITY_ANNOTATIONS': + if m == '_LIBCPP_DISABLE_VISIBILITY_ANNOTATIONS' or \ + m == '_LIBCPP_HIDE_FROM_ABI_PER_TU_BY_DEFAULT': continue if m == '_LIBCPP_ABI_VERSION': self.config.available_features.add('libcpp-abi-version-v%s'