mirror of
https://github.com/fmtlib/fmt.git
synced 2025-11-20 17:30:29 +01:00
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:
committed by
Victor Zverovich
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,
|
||||
|
||||
Reference in New Issue
Block a user