[cfe-dev] Visibility in libc++
hhinnant at apple.com
Tue Jul 9 07:41:18 PDT 2013
On Jul 9, 2013, at 9:50 AM, Nico Rieck <nico.rieck at gmail.com> wrote:
> libc++ applies visibility default to all public types and functions, including templates. On Windows these visibility macros expand to dllexport/import which makes no sense for templates (If someone uses a vector<int> it is then expected that something else is exporting such a specialization).
> Before I send a patch I have two questions:
> 1. AFAICS the visibility attributes were added for cases when the
> libc++ headers are included inside of visibility scopes. Could
> someone clarify why visibility is needed on header-only templates?
On OS X, there is a flag -fvisibility=hidden that can be put on the command line. This makes everything not marked otherwise, private to a dynamic library.
Also on this platform exception catching/throwing, and dynamic_cast uses the type_info of each type in its implementation.
Furthermore, it is legal C++ to throw/catch *any* object.
So when -fvisibility=hidden is given on the command line, we want clients to still be able to catch / throw std::string and std::vector<int> across dylib boundaries. The _LIBCPP_TYPE_VIS marks each public type/template to make this work. It marks the type_info of these objects as "default" even though the client has asked us not to.
_LIBCPP_TYPE_VIS is used only for non-templated functions which are part of the public libc++ API. This ensures that this API is visible even when the client specifies -fvisibility=hidden.
_LIBCPP_INLINE_VISIBILITY is used to augment inline functions, templated or not. It is currently set to give hidden visibility and __always_inline__. The aim is to make inline functions never be outlined into the libc++.dylib and become part of its ABI. The aim is also to reduce the number of symbols with default visibility. But I'm having second thoughts on the __visibility__("hidden") part of this.
_LIBCPP_ALWAYS_INLINE and _LIBCPP_INLINE_VISIBILITY are currently synonyms, and this needs to be cleaned up (pick one and stick with it).
All of these macros are set up in such a way that the client can override their definition with a -D on the command line (at least on OS X, I notice now this is not true on Windows).
> 2. If these are indeed needed, then templates require a different macro
> that only expands to visibility. I currently use
> _LIBCPP_(TYPE|FUNC)_PUBLIC for both, and _LIBCPP_(TYPE|FUNC)_VIS for
> only visibility. Thoughts?
I don't know how Windows works, but others here do. I don't think exceptions are working yet with clang on Windows, but I could be wrong. It would be good to know how clang/exceptions are going to work on Windows before too much libc++ design on Windows happens. If we need some macro redesign work in libc++ in order to get libc++ working on Windows with clang, exceptions and visibility, I'm open to that. Naturally we can't break other platforms in the process. Someone who can test on Windows will have to drive it, and that isn't me.
More information about the cfe-dev