From e4bd8c1ef2c194c198aa2590595c2e03def0105e Mon Sep 17 00:00:00 2001 From: denchat <19730041+denchat@users.noreply.github.com> Date: Tue, 30 Apr 2019 15:09:02 +0700 Subject: [PATCH] Eliminate `__declspec(dllexport)` designation on extern template internal::basic_data<> when `extern` affected during exporting phase. --- include/fmt/format.h | 24 ++++++++++++++++++++++-- 1 file changed, 22 insertions(+), 2 deletions(-) diff --git a/include/fmt/format.h b/include/fmt/format.h index 59c4d913..238aa0b6 100644 --- a/include/fmt/format.h +++ b/include/fmt/format.h @@ -169,6 +169,26 @@ FMT_END_NAMESPACE # endif #endif +#if FMT_USE_EXTERN_TEMPLATES +# if !defined(FMT_HEADER_ONLY) && defined(_WIN32) +# ifdef FMT_EXPORT +// When DLL exporting an "explicit class template instantiation declaration", +// we should not designate __declspec(dllexport) at both +// - class template definition +// - explicit class template instantiation declaration. +// +// (Instead, designate __declspec(dllexport) somewhere else +// and only at a single point where we have +// the "explicit class template instantiation definition.") +# define FMT_EXTERN_TEMPLATE_HEADER_FILE_API +# endif +# endif +#endif +#ifndef FMT_EXTERN_TEMPLATE_HEADER_FILE_API +// In other cases, we can just follow FMT_API there. +# define FMT_EXTERN_TEMPLATE_HEADER_FILE_API FMT_API +#endif + #if FMT_HAS_GXX_CXX11 || FMT_HAS_FEATURE(cxx_trailing_return) || \ FMT_MSC_VER >= 1600 # define FMT_USE_TRAILING_RETURN 1 @@ -712,7 +732,7 @@ template struct int_traits { // Static data is placed in this class template to allow header-only // configuration. -template struct FMT_API basic_data { +template struct FMT_EXTERN_TEMPLATE_HEADER_FILE_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[]; @@ -727,7 +747,7 @@ template struct FMT_API basic_data { }; #if FMT_USE_EXTERN_TEMPLATES -extern template struct FMT_API basic_data; +extern template struct basic_data; #endif // This is a struct rather than a typedef to avoid shadowing warnings in gcc.