[libc++] Fix extern template visibility for Windows
On Windows, marking an `extern template class` declaration as exported actually forces an instantiation, which is not the desired behavior. Instead, the actual explicit instantiations need to be exported. Differential Revision: https://reviews.llvm.org/D24679 git-svn-id: https://llvm.org/svn/llvm-project/libcxx/trunk@281925 91177308-0d34-0410-b5e6-96231b3b80d8
This commit is contained in:
@@ -71,6 +71,26 @@ Visibility Macros
|
|||||||
However since `_LIBCPP_TYPE_VIS_ONLY` is the same as `_LIBCPP_TYPE_VIS` the
|
However since `_LIBCPP_TYPE_VIS_ONLY` is the same as `_LIBCPP_TYPE_VIS` the
|
||||||
visibility is already correct. The macro has an empty definition with GCC.
|
visibility is already correct. The macro has an empty definition with GCC.
|
||||||
|
|
||||||
|
**Windows Behavior**: `extern template` and `dllexport` are fundamentally
|
||||||
|
incompatible *on a template class* on Windows; the former suppresses
|
||||||
|
instantiation, while the latter forces it. Specifying both on the same
|
||||||
|
declaration makes the template class be instantiated, which is not desirable
|
||||||
|
inside headers. This macro therefore expands to `dllimport` outside of libc++
|
||||||
|
but nothing inside of it (rather than expanding to `dllexport`); instead, the
|
||||||
|
explicit instantiations themselves are marked as exported. Note that this
|
||||||
|
applies *only* to extern template *classes*. Extern template *functions* obey
|
||||||
|
regular import/export semantics, and applying `dllexport` directly to the
|
||||||
|
extern template declaration is the correct thing to do for them.
|
||||||
|
|
||||||
|
**_LIBCPP_CLASS_TEMPLATE_INSTANTIATION_VIS**
|
||||||
|
Mark the member functions, typeinfo, and vtable of an explicit instantiation
|
||||||
|
of a class template as being exported by the libc++ library. This attribute
|
||||||
|
must be specified on all template class explicit instantiations.
|
||||||
|
|
||||||
|
It is only necessary to mark the explicit instantiation itself (as opposed to
|
||||||
|
the extern template declaration) as exported on Windows, as discussed above.
|
||||||
|
On all other platforms, this macro has an empty definition.
|
||||||
|
|
||||||
**_LIBCPP_EXTERN_TEMPLATE_INLINE_VISIBILITY**
|
**_LIBCPP_EXTERN_TEMPLATE_INLINE_VISIBILITY**
|
||||||
Mark a member function of a class template as hidden and inline except when
|
Mark a member function of a class template as hidden and inline except when
|
||||||
building the libc++ library where it marks the symbol as being exported by
|
building the libc++ library where it marks the symbol as being exported by
|
||||||
|
|||||||
@@ -551,15 +551,20 @@ namespace std {
|
|||||||
// only really useful for a DLL. _LIBCPP_DLL should be a compiler builtin define ideally...
|
// only really useful for a DLL. _LIBCPP_DLL should be a compiler builtin define ideally...
|
||||||
#if defined(_LIBCPP_DLL) && defined(cxx_EXPORTS)
|
#if defined(_LIBCPP_DLL) && defined(cxx_EXPORTS)
|
||||||
# define _LIBCPP_DLL_VIS __declspec(dllexport)
|
# define _LIBCPP_DLL_VIS __declspec(dllexport)
|
||||||
|
# define _LIBCPP_EXTERN_TEMPLATE_TYPE_VIS
|
||||||
|
# define _LIBCPP_CLASS_TEMPLATE_INSTANTIATION_VIS _LIBCPP_DLL_VIS
|
||||||
#elif defined(_LIBCPP_DLL)
|
#elif defined(_LIBCPP_DLL)
|
||||||
# define _LIBCPP_DLL_VIS __declspec(dllimport)
|
# define _LIBCPP_DLL_VIS __declspec(dllimport)
|
||||||
|
# define _LIBCPP_EXTERN_TEMPLATE_TYPE_VIS _LIBCPP_DLL_VIS
|
||||||
|
# define _LIBCPP_CLASS_TEMPLATE_INSTANTIATION_VIS
|
||||||
#else
|
#else
|
||||||
# define _LIBCPP_DLL_VIS
|
# define _LIBCPP_DLL_VIS
|
||||||
|
# define _LIBCPP_EXTERN_TEMPLATE_TYPE_VIS
|
||||||
|
# define _LIBCPP_CLASS_TEMPLATE_INSTANTIATION_VIS
|
||||||
#endif
|
#endif
|
||||||
#define _LIBCPP_TYPE_VIS _LIBCPP_DLL_VIS
|
#define _LIBCPP_TYPE_VIS _LIBCPP_DLL_VIS
|
||||||
#define _LIBCPP_FUNC_VIS _LIBCPP_DLL_VIS
|
#define _LIBCPP_FUNC_VIS _LIBCPP_DLL_VIS
|
||||||
#define _LIBCPP_EXCEPTION_ABI _LIBCPP_DLL_VIS
|
#define _LIBCPP_EXCEPTION_ABI _LIBCPP_DLL_VIS
|
||||||
#define _LIBCPP_EXTERN_TEMPLATE_TYPE_VIS _LIBCPP_DLL_VIS
|
|
||||||
#define _LIBCPP_HIDDEN
|
#define _LIBCPP_HIDDEN
|
||||||
#define _LIBCPP_TYPE_VIS_ONLY
|
#define _LIBCPP_TYPE_VIS_ONLY
|
||||||
#define _LIBCPP_FUNC_VIS_ONLY
|
#define _LIBCPP_FUNC_VIS_ONLY
|
||||||
@@ -619,6 +624,10 @@ namespace std {
|
|||||||
# endif
|
# endif
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
#ifndef _LIBCPP_CLASS_TEMPLATE_INSTANTIATION_VIS
|
||||||
|
# define _LIBCPP_CLASS_TEMPLATE_INSTANTIATION_VIS
|
||||||
|
#endif
|
||||||
|
|
||||||
#ifndef _LIBCPP_INLINE_VISIBILITY
|
#ifndef _LIBCPP_INLINE_VISIBILITY
|
||||||
#define _LIBCPP_INLINE_VISIBILITY __attribute__ ((__visibility__("hidden"), __always_inline__))
|
#define _LIBCPP_INLINE_VISIBILITY __attribute__ ((__visibility__("hidden"), __always_inline__))
|
||||||
#endif
|
#endif
|
||||||
|
|||||||
18
src/ios.cpp
18
src/ios.cpp
@@ -25,19 +25,19 @@
|
|||||||
|
|
||||||
_LIBCPP_BEGIN_NAMESPACE_STD
|
_LIBCPP_BEGIN_NAMESPACE_STD
|
||||||
|
|
||||||
template class basic_ios<char>;
|
template class _LIBCPP_CLASS_TEMPLATE_INSTANTIATION_VIS basic_ios<char>;
|
||||||
template class basic_ios<wchar_t>;
|
template class _LIBCPP_CLASS_TEMPLATE_INSTANTIATION_VIS basic_ios<wchar_t>;
|
||||||
|
|
||||||
template class basic_streambuf<char>;
|
template class _LIBCPP_CLASS_TEMPLATE_INSTANTIATION_VIS basic_streambuf<char>;
|
||||||
template class basic_streambuf<wchar_t>;
|
template class _LIBCPP_CLASS_TEMPLATE_INSTANTIATION_VIS basic_streambuf<wchar_t>;
|
||||||
|
|
||||||
template class basic_istream<char>;
|
template class _LIBCPP_CLASS_TEMPLATE_INSTANTIATION_VIS basic_istream<char>;
|
||||||
template class basic_istream<wchar_t>;
|
template class _LIBCPP_CLASS_TEMPLATE_INSTANTIATION_VIS basic_istream<wchar_t>;
|
||||||
|
|
||||||
template class basic_ostream<char>;
|
template class _LIBCPP_CLASS_TEMPLATE_INSTANTIATION_VIS basic_ostream<char>;
|
||||||
template class basic_ostream<wchar_t>;
|
template class _LIBCPP_CLASS_TEMPLATE_INSTANTIATION_VIS basic_ostream<wchar_t>;
|
||||||
|
|
||||||
template class basic_iostream<char>;
|
template class _LIBCPP_CLASS_TEMPLATE_INSTANTIATION_VIS basic_iostream<char>;
|
||||||
|
|
||||||
class _LIBCPP_HIDDEN __iostream_category
|
class _LIBCPP_HIDDEN __iostream_category
|
||||||
: public __do_message
|
: public __do_message
|
||||||
|
|||||||
@@ -6031,66 +6031,66 @@ void __throw_runtime_error(const char* msg)
|
|||||||
#endif
|
#endif
|
||||||
}
|
}
|
||||||
|
|
||||||
template class collate<char>;
|
template class _LIBCPP_CLASS_TEMPLATE_INSTANTIATION_VIS collate<char>;
|
||||||
template class collate<wchar_t>;
|
template class _LIBCPP_CLASS_TEMPLATE_INSTANTIATION_VIS collate<wchar_t>;
|
||||||
|
|
||||||
template class num_get<char>;
|
template class _LIBCPP_CLASS_TEMPLATE_INSTANTIATION_VIS num_get<char>;
|
||||||
template class num_get<wchar_t>;
|
template class _LIBCPP_CLASS_TEMPLATE_INSTANTIATION_VIS num_get<wchar_t>;
|
||||||
|
|
||||||
template struct __num_get<char>;
|
template struct _LIBCPP_CLASS_TEMPLATE_INSTANTIATION_VIS __num_get<char>;
|
||||||
template struct __num_get<wchar_t>;
|
template struct _LIBCPP_CLASS_TEMPLATE_INSTANTIATION_VIS __num_get<wchar_t>;
|
||||||
|
|
||||||
template class num_put<char>;
|
template class _LIBCPP_CLASS_TEMPLATE_INSTANTIATION_VIS num_put<char>;
|
||||||
template class num_put<wchar_t>;
|
template class _LIBCPP_CLASS_TEMPLATE_INSTANTIATION_VIS num_put<wchar_t>;
|
||||||
|
|
||||||
template struct __num_put<char>;
|
template struct _LIBCPP_CLASS_TEMPLATE_INSTANTIATION_VIS __num_put<char>;
|
||||||
template struct __num_put<wchar_t>;
|
template struct _LIBCPP_CLASS_TEMPLATE_INSTANTIATION_VIS __num_put<wchar_t>;
|
||||||
|
|
||||||
template class time_get<char>;
|
template class _LIBCPP_CLASS_TEMPLATE_INSTANTIATION_VIS time_get<char>;
|
||||||
template class time_get<wchar_t>;
|
template class _LIBCPP_CLASS_TEMPLATE_INSTANTIATION_VIS time_get<wchar_t>;
|
||||||
|
|
||||||
template class time_get_byname<char>;
|
template class _LIBCPP_CLASS_TEMPLATE_INSTANTIATION_VIS time_get_byname<char>;
|
||||||
template class time_get_byname<wchar_t>;
|
template class _LIBCPP_CLASS_TEMPLATE_INSTANTIATION_VIS time_get_byname<wchar_t>;
|
||||||
|
|
||||||
template class time_put<char>;
|
template class _LIBCPP_CLASS_TEMPLATE_INSTANTIATION_VIS time_put<char>;
|
||||||
template class time_put<wchar_t>;
|
template class _LIBCPP_CLASS_TEMPLATE_INSTANTIATION_VIS time_put<wchar_t>;
|
||||||
|
|
||||||
template class time_put_byname<char>;
|
template class _LIBCPP_CLASS_TEMPLATE_INSTANTIATION_VIS time_put_byname<char>;
|
||||||
template class time_put_byname<wchar_t>;
|
template class _LIBCPP_CLASS_TEMPLATE_INSTANTIATION_VIS time_put_byname<wchar_t>;
|
||||||
|
|
||||||
template class moneypunct<char, false>;
|
template class _LIBCPP_CLASS_TEMPLATE_INSTANTIATION_VIS moneypunct<char, false>;
|
||||||
template class moneypunct<char, true>;
|
template class _LIBCPP_CLASS_TEMPLATE_INSTANTIATION_VIS moneypunct<char, true>;
|
||||||
template class moneypunct<wchar_t, false>;
|
template class _LIBCPP_CLASS_TEMPLATE_INSTANTIATION_VIS moneypunct<wchar_t, false>;
|
||||||
template class moneypunct<wchar_t, true>;
|
template class _LIBCPP_CLASS_TEMPLATE_INSTANTIATION_VIS moneypunct<wchar_t, true>;
|
||||||
|
|
||||||
template class moneypunct_byname<char, false>;
|
template class _LIBCPP_CLASS_TEMPLATE_INSTANTIATION_VIS moneypunct_byname<char, false>;
|
||||||
template class moneypunct_byname<char, true>;
|
template class _LIBCPP_CLASS_TEMPLATE_INSTANTIATION_VIS moneypunct_byname<char, true>;
|
||||||
template class moneypunct_byname<wchar_t, false>;
|
template class _LIBCPP_CLASS_TEMPLATE_INSTANTIATION_VIS moneypunct_byname<wchar_t, false>;
|
||||||
template class moneypunct_byname<wchar_t, true>;
|
template class _LIBCPP_CLASS_TEMPLATE_INSTANTIATION_VIS moneypunct_byname<wchar_t, true>;
|
||||||
|
|
||||||
template class money_get<char>;
|
template class _LIBCPP_CLASS_TEMPLATE_INSTANTIATION_VIS money_get<char>;
|
||||||
template class money_get<wchar_t>;
|
template class _LIBCPP_CLASS_TEMPLATE_INSTANTIATION_VIS money_get<wchar_t>;
|
||||||
|
|
||||||
template class __money_get<char>;
|
template class _LIBCPP_CLASS_TEMPLATE_INSTANTIATION_VIS __money_get<char>;
|
||||||
template class __money_get<wchar_t>;
|
template class _LIBCPP_CLASS_TEMPLATE_INSTANTIATION_VIS __money_get<wchar_t>;
|
||||||
|
|
||||||
template class money_put<char>;
|
template class _LIBCPP_CLASS_TEMPLATE_INSTANTIATION_VIS money_put<char>;
|
||||||
template class money_put<wchar_t>;
|
template class _LIBCPP_CLASS_TEMPLATE_INSTANTIATION_VIS money_put<wchar_t>;
|
||||||
|
|
||||||
template class __money_put<char>;
|
template class _LIBCPP_CLASS_TEMPLATE_INSTANTIATION_VIS __money_put<char>;
|
||||||
template class __money_put<wchar_t>;
|
template class _LIBCPP_CLASS_TEMPLATE_INSTANTIATION_VIS __money_put<wchar_t>;
|
||||||
|
|
||||||
template class messages<char>;
|
template class _LIBCPP_CLASS_TEMPLATE_INSTANTIATION_VIS messages<char>;
|
||||||
template class messages<wchar_t>;
|
template class _LIBCPP_CLASS_TEMPLATE_INSTANTIATION_VIS messages<wchar_t>;
|
||||||
|
|
||||||
template class messages_byname<char>;
|
template class _LIBCPP_CLASS_TEMPLATE_INSTANTIATION_VIS messages_byname<char>;
|
||||||
template class messages_byname<wchar_t>;
|
template class _LIBCPP_CLASS_TEMPLATE_INSTANTIATION_VIS messages_byname<wchar_t>;
|
||||||
|
|
||||||
template class codecvt_byname<char, char, mbstate_t>;
|
template class _LIBCPP_CLASS_TEMPLATE_INSTANTIATION_VIS codecvt_byname<char, char, mbstate_t>;
|
||||||
template class codecvt_byname<wchar_t, char, mbstate_t>;
|
template class _LIBCPP_CLASS_TEMPLATE_INSTANTIATION_VIS codecvt_byname<wchar_t, char, mbstate_t>;
|
||||||
template class codecvt_byname<char16_t, char, mbstate_t>;
|
template class _LIBCPP_CLASS_TEMPLATE_INSTANTIATION_VIS codecvt_byname<char16_t, char, mbstate_t>;
|
||||||
template class codecvt_byname<char32_t, char, mbstate_t>;
|
template class _LIBCPP_CLASS_TEMPLATE_INSTANTIATION_VIS codecvt_byname<char32_t, char, mbstate_t>;
|
||||||
|
|
||||||
template class __vector_base_common<true>;
|
template class _LIBCPP_CLASS_TEMPLATE_INSTANTIATION_VIS __vector_base_common<true>;
|
||||||
|
|
||||||
_LIBCPP_END_NAMESPACE_STD
|
_LIBCPP_END_NAMESPACE_STD
|
||||||
|
|||||||
@@ -20,10 +20,10 @@
|
|||||||
|
|
||||||
_LIBCPP_BEGIN_NAMESPACE_STD
|
_LIBCPP_BEGIN_NAMESPACE_STD
|
||||||
|
|
||||||
template class __basic_string_common<true>;
|
template class _LIBCPP_CLASS_TEMPLATE_INSTANTIATION_VIS __basic_string_common<true>;
|
||||||
|
|
||||||
template class basic_string<char>;
|
template class _LIBCPP_CLASS_TEMPLATE_INSTANTIATION_VIS basic_string<char>;
|
||||||
template class basic_string<wchar_t>;
|
template class _LIBCPP_CLASS_TEMPLATE_INSTANTIATION_VIS basic_string<wchar_t>;
|
||||||
|
|
||||||
template
|
template
|
||||||
string
|
string
|
||||||
|
|||||||
Reference in New Issue
Block a user