Eric Fiselier | 1b57fa8 | 2016-09-15 22:27:07 +0000 | [diff] [blame] | 1 | ======================== |
| 2 | Symbol Visibility Macros |
| 3 | ======================== |
| 4 | |
| 5 | .. contents:: |
| 6 | :local: |
| 7 | |
Louis Dionne | a7e94a1 | 2021-07-19 12:34:56 -0400 | [diff] [blame] | 8 | .. _visibility-macros: |
| 9 | |
Eric Fiselier | 1b57fa8 | 2016-09-15 22:27:07 +0000 | [diff] [blame] | 10 | Overview |
| 11 | ======== |
| 12 | |
| 13 | Libc++ uses various "visibility" macros in order to provide a stable ABI in |
| 14 | both the library and the headers. These macros work by changing the |
| 15 | visibility and inlining characteristics of the symbols they are applied to. |
| 16 | |
| 17 | Visibility Macros |
| 18 | ================= |
| 19 | |
| 20 | **_LIBCPP_HIDDEN** |
| 21 | Mark a symbol as hidden so it will not be exported from shared libraries. |
| 22 | |
| 23 | **_LIBCPP_FUNC_VIS** |
| 24 | Mark a symbol as being exported by the libc++ library. This attribute must |
| 25 | be applied to the declaration of all functions exported by the libc++ dylib. |
| 26 | |
Louis Dionne | 5254b37 | 2018-10-25 12:13:43 +0000 | [diff] [blame] | 27 | **_LIBCPP_EXPORTED_FROM_ABI** |
Eric Fiselier | 9950507 | 2017-01-16 21:01:00 +0000 | [diff] [blame] | 28 | Mark a symbol as being exported by the libc++ library. This attribute may |
Louis Dionne | 5254b37 | 2018-10-25 12:13:43 +0000 | [diff] [blame] | 29 | only be applied to objects defined in the libc++ runtime library. On Windows, |
| 30 | this macro applies `dllimport`/`dllexport` to the symbol, and on other |
| 31 | platforms it gives the symbol default visibility. |
Eric Fiselier | 9950507 | 2017-01-16 21:01:00 +0000 | [diff] [blame] | 32 | |
Shoaib Meenai | 2d71db4 | 2016-11-16 22:18:10 +0000 | [diff] [blame] | 33 | **_LIBCPP_OVERRIDABLE_FUNC_VIS** |
| 34 | Mark a symbol as being exported by the libc++ library, but allow it to be |
| 35 | overridden locally. On non-Windows, this is equivalent to `_LIBCPP_FUNC_VIS`. |
| 36 | This macro is applied to all `operator new` and `operator delete` overloads. |
| 37 | |
| 38 | **Windows Behavior**: Any symbol marked `dllimport` cannot be overridden |
| 39 | locally, since `dllimport` indicates the symbol should be bound to a separate |
| 40 | DLL. All `operator new` and `operator delete` overloads are required to be |
| 41 | locally overridable, and therefore must not be marked `dllimport`. On Windows, |
| 42 | this macro therefore expands to `__declspec(dllexport)` when building the |
| 43 | library and has an empty definition otherwise. |
| 44 | |
Louis Dionne | 3a19799 | 2018-07-27 12:46:03 +0000 | [diff] [blame] | 45 | **_LIBCPP_HIDE_FROM_ABI** |
Louis Dionne | 16fe295 | 2018-07-11 23:14:33 +0000 | [diff] [blame] | 46 | Mark a function as not being part of the ABI of any final linked image that |
Louis Dionne | 1821de4 | 2018-08-16 12:44:28 +0000 | [diff] [blame] | 47 | uses it. |
Eric Fiselier | 1b57fa8 | 2016-09-15 22:27:07 +0000 | [diff] [blame] | 48 | |
Louis Dionne | a7e94a1 | 2021-07-19 12:34:56 -0400 | [diff] [blame] | 49 | **_LIBCPP_INLINE_VISIBILITY** |
| 50 | Historical predecessor of ``_LIBCPP_HIDE_FROM_ABI`` -- please use |
| 51 | ``_LIBCPP_HIDE_FROM_ABI`` instead. |
| 52 | |
Louis Dionne | d797b8d | 2018-08-06 14:11:50 +0000 | [diff] [blame] | 53 | **_LIBCPP_HIDE_FROM_ABI_AFTER_V1** |
| 54 | Mark a function as being hidden from the ABI (per `_LIBCPP_HIDE_FROM_ABI`) |
| 55 | when libc++ is built with an ABI version after ABI v1. This macro is used to |
| 56 | maintain ABI compatibility for symbols that have been historically exported |
| 57 | by libc++ in v1 of the ABI, but that we don't want to export in the future. |
| 58 | |
| 59 | This macro works as follows. When we build libc++, we either hide the symbol |
| 60 | from the ABI (if the symbol is not part of the ABI in the version we're |
| 61 | building), or we leave it included. From user code (i.e. when we're not |
| 62 | building libc++), the macro always marks symbols as internal so that programs |
| 63 | built using new libc++ headers stop relying on symbols that are removed from |
| 64 | the ABI in a future version. Each time we release a new stable version of the |
| 65 | ABI, we should create a new _LIBCPP_HIDE_FROM_ABI_AFTER_XXX macro, and we can |
| 66 | use it to start removing symbols from the ABI after that stable version. |
| 67 | |
Eric Fiselier | 1b57fa8 | 2016-09-15 22:27:07 +0000 | [diff] [blame] | 68 | **_LIBCPP_TYPE_VIS** |
Shoaib Meenai | 55f3a46 | 2017-03-02 03:22:18 +0000 | [diff] [blame] | 69 | Mark a type's typeinfo, vtable and members as having default visibility. |
| 70 | This attribute cannot be used on class templates. |
| 71 | |
| 72 | **_LIBCPP_TEMPLATE_VIS** |
Eric Fiselier | 1b57fa8 | 2016-09-15 22:27:07 +0000 | [diff] [blame] | 73 | Mark a type's typeinfo and vtable as having default visibility. |
Shoaib Meenai | 55f3a46 | 2017-03-02 03:22:18 +0000 | [diff] [blame] | 74 | This macro has no effect on the visibility of the type's member functions. |
Eric Fiselier | 1b57fa8 | 2016-09-15 22:27:07 +0000 | [diff] [blame] | 75 | |
| 76 | **GCC Behavior**: GCC does not support Clang's `type_visibility(...)` |
| 77 | attribute. With GCC the `visibility(...)` attribute is used and member |
| 78 | functions are affected. |
| 79 | |
Eric Fiselier | 1b57fa8 | 2016-09-15 22:27:07 +0000 | [diff] [blame] | 80 | **Windows Behavior**: DLLs do not support dllimport/export on class templates. |
| 81 | The macro has an empty definition on this platform. |
| 82 | |
Eric Fiselier | 1b57fa8 | 2016-09-15 22:27:07 +0000 | [diff] [blame] | 83 | |
| 84 | **_LIBCPP_ENUM_VIS** |
| 85 | Mark the typeinfo of an enum as having default visibility. This attribute |
| 86 | should be applied to all enum declarations. |
| 87 | |
| 88 | **Windows Behavior**: DLLs do not support importing or exporting enumeration |
| 89 | typeinfo. The macro has an empty definition on this platform. |
| 90 | |
| 91 | **GCC Behavior**: GCC un-hides the typeinfo for enumerations by default, even |
| 92 | if `-fvisibility=hidden` is specified. Additionally applying a visibility |
| 93 | attribute to an enum class results in a warning. The macro has an empty |
| 94 | definition with GCC. |
| 95 | |
| 96 | **_LIBCPP_EXTERN_TEMPLATE_TYPE_VIS** |
| 97 | Mark the member functions, typeinfo, and vtable of the type named in |
Louis Dionne | dc496ec | 2021-06-08 17:25:08 -0400 | [diff] [blame] | 98 | an extern template declaration as being exported by the libc++ library. |
Eric Fiselier | 1b57fa8 | 2016-09-15 22:27:07 +0000 | [diff] [blame] | 99 | This attribute must be specified on all extern class template declarations. |
| 100 | |
Eric Fiselier | b5eb1bf | 2017-01-04 23:56:00 +0000 | [diff] [blame] | 101 | This macro is used to override the `_LIBCPP_TEMPLATE_VIS` attribute |
Eric Fiselier | 1b57fa8 | 2016-09-15 22:27:07 +0000 | [diff] [blame] | 102 | specified on the primary template and to export the member functions produced |
| 103 | by the explicit instantiation in the dylib. |
| 104 | |
Shoaib Meenai | 5ac1067 | 2016-09-19 18:29:07 +0000 | [diff] [blame] | 105 | **Windows Behavior**: `extern template` and `dllexport` are fundamentally |
Shoaib Meenai | c0d2abd | 2017-07-13 20:47:24 +0000 | [diff] [blame] | 106 | incompatible *on a class template* on Windows; the former suppresses |
Shoaib Meenai | 5ac1067 | 2016-09-19 18:29:07 +0000 | [diff] [blame] | 107 | instantiation, while the latter forces it. Specifying both on the same |
Shoaib Meenai | c0d2abd | 2017-07-13 20:47:24 +0000 | [diff] [blame] | 108 | declaration makes the class template be instantiated, which is not desirable |
Shoaib Meenai | 5ac1067 | 2016-09-19 18:29:07 +0000 | [diff] [blame] | 109 | inside headers. This macro therefore expands to `dllimport` outside of libc++ |
| 110 | but nothing inside of it (rather than expanding to `dllexport`); instead, the |
| 111 | explicit instantiations themselves are marked as exported. Note that this |
Shoaib Meenai | c0d2abd | 2017-07-13 20:47:24 +0000 | [diff] [blame] | 112 | applies *only* to extern *class* templates. Extern *function* templates obey |
Shoaib Meenai | 5ac1067 | 2016-09-19 18:29:07 +0000 | [diff] [blame] | 113 | regular import/export semantics, and applying `dllexport` directly to the |
Shoaib Meenai | f9f98d1 | 2017-07-13 21:35:52 +0000 | [diff] [blame] | 114 | extern template declaration (i.e. using `_LIBCPP_FUNC_VIS`) is the correct |
| 115 | thing to do for them. |
Shoaib Meenai | 5ac1067 | 2016-09-19 18:29:07 +0000 | [diff] [blame] | 116 | |
| 117 | **_LIBCPP_CLASS_TEMPLATE_INSTANTIATION_VIS** |
| 118 | Mark the member functions, typeinfo, and vtable of an explicit instantiation |
| 119 | of a class template as being exported by the libc++ library. This attribute |
Shoaib Meenai | c391078 | 2017-07-13 22:08:59 +0000 | [diff] [blame] | 120 | must be specified on all class template explicit instantiations. |
Shoaib Meenai | 5ac1067 | 2016-09-19 18:29:07 +0000 | [diff] [blame] | 121 | |
| 122 | It is only necessary to mark the explicit instantiation itself (as opposed to |
| 123 | the extern template declaration) as exported on Windows, as discussed above. |
| 124 | On all other platforms, this macro has an empty definition. |
| 125 | |
Shoaib Meenai | 69c5741 | 2017-03-02 03:02:50 +0000 | [diff] [blame] | 126 | **_LIBCPP_METHOD_TEMPLATE_IMPLICIT_INSTANTIATION_VIS** |
| 127 | Mark a symbol as hidden so it will not be exported from shared libraries. This |
| 128 | is intended specifically for method templates of either classes marked with |
| 129 | `_LIBCPP_TYPE_VIS` or classes with an extern template instantiation |
| 130 | declaration marked with `_LIBCPP_EXTERN_TEMPLATE_TYPE_VIS`. |
| 131 | |
| 132 | When building libc++ with hidden visibility, we want explicit template |
| 133 | instantiations to export members, which is consistent with existing Windows |
| 134 | behavior. We also want classes annotated with `_LIBCPP_TYPE_VIS` to export |
| 135 | their members, which is again consistent with existing Windows behavior. |
| 136 | Both these changes are necessary for clients to be able to link against a |
| 137 | libc++ DSO built with hidden visibility without encountering missing symbols. |
| 138 | |
| 139 | An unfortunate side effect, however, is that method templates of classes |
| 140 | either marked `_LIBCPP_TYPE_VIS` or with extern template instantiation |
| 141 | declarations marked with `_LIBCPP_EXTERN_TEMPLATE_TYPE_VIS` also get default |
| 142 | visibility when instantiated. These methods are often implicitly instantiated |
| 143 | inside other libraries which use the libc++ headers, and will therefore end up |
| 144 | being exported from those libraries, since those implicit instantiations will |
| 145 | receive default visibility. This is not acceptable for libraries that wish to |
| 146 | control their visibility, and led to PR30642. |
| 147 | |
| 148 | Consequently, all such problematic method templates are explicitly marked |
| 149 | either hidden (via this macro) or inline, so that they don't leak into client |
| 150 | libraries. The problematic methods were found by running |
| 151 | `bad-visibility-finder <https://github.com/smeenai/bad-visibility-finder>`_ |
| 152 | against the libc++ headers after making `_LIBCPP_TYPE_VIS` and |
| 153 | `_LIBCPP_EXTERN_TEMPLATE_TYPE_VIS` expand to default visibility. |
| 154 | |
Eric Fiselier | 1b57fa8 | 2016-09-15 22:27:07 +0000 | [diff] [blame] | 155 | **_LIBCPP_EXCEPTION_ABI** |
| 156 | Mark the member functions, typeinfo, and vtable of the type as being exported |
| 157 | by the libc++ library. This macro must be applied to all *exception types*. |
Eric Fiselier | 0f47c38 | 2016-09-16 02:51:26 +0000 | [diff] [blame] | 158 | Exception types should be defined directly in namespace `std` and not the |
| 159 | versioning namespace. This allows throwing and catching some exception types |
| 160 | between libc++ and libstdc++. |
Eric Fiselier | 1b57fa8 | 2016-09-15 22:27:07 +0000 | [diff] [blame] | 161 | |
Eric Fiselier | 1b57fa8 | 2016-09-15 22:27:07 +0000 | [diff] [blame] | 162 | Links |
| 163 | ===== |
| 164 | |
| 165 | * `[cfe-dev] Visibility in libc++ - 1 <http://lists.llvm.org/pipermail/cfe-dev/2013-July/030610.html>`_ |
| 166 | * `[cfe-dev] Visibility in libc++ - 2 <http://lists.llvm.org/pipermail/cfe-dev/2013-August/031195.html>`_ |
| 167 | * `[libcxx] Visibility fixes for Windows <http://lists.llvm.org/pipermail/cfe-commits/Week-of-Mon-20130805/085461.html>`_ |