Fix DLL visibility of explicit instantiation "declaration" of internal::basic_data<void> in header format.h and the explicit instantiation "definition" in format.cc (#1134)
* Update format.cc As the explicit instantiation *declaration* of `internal::basic_data<void>` in format.h, this explicit instantiation *definition* should mirror FMT_API also. * Mirror visibility of explicit instantiation declaration explicit instantiation declaration of internal::basic_data<void> should mirror visibility of FMT_API * Eliminate `__declspec(dllexport)` designation on extern template internal::basic_data<> when `extern` affected during exporting phase. * Add `FMT_EXTERN_TEMPLATE_API` for designate DLL export `extern template` When exporting DLL, do not designate `__declspec(dllexport)` any template that has any explicit class template declaration a.k.a. `extern template`. Instead, designate `__declspec(dllexport)` at single point where we have explicit class template definition a.k.a. normal instantiation without `extern` Note: this is a c++11 feature. * Delete whole `FMT_USE_EXTERN_TEMPLATES` block and its condition 1. Remove whole `FMT_USE_EXTERN_TEMPLATES` block (trailing `FMT_UDL_TEMPLATE` block) ```` #ifndef FMT_USE_EXTERN_TEMPLATES # ifndef FMT_HEADER_ONLY # define FMT_USE_EXTERN_TEMPLATES \ ((FMT_CLANG_VERSION >= 209 && __cplusplus >= 201103L) || \ (FMT_GCC_VERSION >= 303 && FMT_HAS_GXX_CXX11)) # else # define FMT_USE_EXTERN_TEMPLATES 0 # endif #endif ```` 2. Delete `FMT_USE_EXTERN_TEMPLATES` condition, only condition, that trailing basic_data class template definition. ```` #if FMT_USE_EXTERN_TEMPLATES extern template struct basic_data<void>; #endif ```` 3. Replace `FMT_API` with new `FMT_EXTERN_TEMPLATE_API` added in `core.h` for sake of extern template of `basic_data<void>` * Add `#define FMT_EXTERN extern` only when not `FMT_HEADER_ONLY` * Replace `extern` on basic_data<void> with the `FMT_EXTERN` condition in core.h * replace misspelled if !define() with ifndef
This commit is contained in:
parent
4a4d72f917
commit
29c10fbf6e
@ -189,11 +189,21 @@
|
||||
# define FMT_API __declspec(dllexport)
|
||||
# elif defined(FMT_SHARED)
|
||||
# define FMT_API __declspec(dllimport)
|
||||
# define FMT_EXTERN_TEMPLATE_API FMT_API
|
||||
# endif
|
||||
#endif
|
||||
#ifndef FMT_API
|
||||
# define FMT_API
|
||||
#endif
|
||||
#ifndef FMT_EXTERN_TEMPLATE_API
|
||||
# define FMT_EXTERN_TEMPLATE_API
|
||||
#endif
|
||||
|
||||
#ifndef FMT_HEADER_ONLY
|
||||
# define FMT_EXTERN extern
|
||||
#else
|
||||
# define FMT_EXTERN
|
||||
#endif
|
||||
|
||||
#ifndef FMT_ASSERT
|
||||
# define FMT_ASSERT(condition, message) assert((condition) && message)
|
||||
|
@ -159,16 +159,6 @@ FMT_END_NAMESPACE
|
||||
# define FMT_UDL_TEMPLATE 0
|
||||
#endif
|
||||
|
||||
#ifndef FMT_USE_EXTERN_TEMPLATES
|
||||
# ifndef FMT_HEADER_ONLY
|
||||
# define FMT_USE_EXTERN_TEMPLATES \
|
||||
((FMT_CLANG_VERSION >= 209 && __cplusplus >= 201103L) || \
|
||||
(FMT_GCC_VERSION >= 303 && FMT_HAS_GXX_CXX11))
|
||||
# else
|
||||
# define FMT_USE_EXTERN_TEMPLATES 0
|
||||
# endif
|
||||
#endif
|
||||
|
||||
#if FMT_HAS_GXX_CXX11 || FMT_HAS_FEATURE(cxx_trailing_return) || \
|
||||
FMT_MSC_VER >= 1600
|
||||
# define FMT_USE_TRAILING_RETURN 1
|
||||
@ -712,7 +702,7 @@ template <typename T> struct int_traits {
|
||||
|
||||
// Static data is placed in this class template to allow header-only
|
||||
// configuration.
|
||||
template <typename T = void> struct FMT_API basic_data {
|
||||
template <typename T = void> struct FMT_EXTERN_TEMPLATE_API basic_data {
|
||||
static const uint64_t POWERS_OF_10_64[];
|
||||
static const uint32_t ZERO_OR_POWERS_OF_10_32[];
|
||||
static const uint64_t ZERO_OR_POWERS_OF_10_64[];
|
||||
@ -726,9 +716,7 @@ template <typename T = void> struct FMT_API basic_data {
|
||||
static const wchar_t WRESET_COLOR[5];
|
||||
};
|
||||
|
||||
#if FMT_USE_EXTERN_TEMPLATES
|
||||
extern template struct basic_data<void>;
|
||||
#endif
|
||||
FMT_EXTERN template struct basic_data<void>;
|
||||
|
||||
// This is a struct rather than a typedef to avoid shadowing warnings in gcc.
|
||||
struct data : basic_data<> {};
|
||||
|
@ -8,7 +8,7 @@
|
||||
#include "fmt/format-inl.h"
|
||||
|
||||
FMT_BEGIN_NAMESPACE
|
||||
template struct internal::basic_data<void>;
|
||||
template struct FMT_API internal::basic_data<void>;
|
||||
|
||||
// Workaround a bug in MSVC2013 that prevents instantiation of grisu_format.
|
||||
bool (*instantiate_grisu_format)(double, internal::buffer<char>&, int, unsigned,
|
||||
|
Loading…
Reference in New Issue
Block a user