Reorganise explicit template instantiations so that it always happens in the .cxx file, while remaining backward compatible with MSVC's standards-breaking implementation

This commit is contained in:
rdb 2015-10-16 15:38:28 +02:00
parent 047e5cafcc
commit ddf8343590
29 changed files with 169 additions and 16 deletions

View File

@ -440,13 +440,23 @@
#define EXPORT_CLASS #define EXPORT_CLASS
#define IMPORT_CLASS #define IMPORT_CLASS
#endif #endif
/* "extern template" is now part of the C++11 standard. */ /* "extern template" is now part of the C++11 standard. */
#if !defined(CPPPARSER) && !defined(LINK_ALL_STATIC) #if defined(CPPPARSER) || defined(LINK_ALL_STATIC)
#define EXPORT_TEMPL
#define IMPORT_TEMPL
#elif defined(_MSC_VER)
/* Nowadays, we'd define both of these as "extern" in all cases, so that
the header file always marks the symbol as "extern" and the .cxx file
explicitly instantiates it. However, MSVC versions before 2013 break
the spec by explicitly disallowing it, so we have to instantiate the
class from the header file. Fortunately, its linker is okay with the
duplicate template instantiations that this causes. */
#define EXPORT_TEMPL #define EXPORT_TEMPL
#define IMPORT_TEMPL extern #define IMPORT_TEMPL extern
#else #else
#define EXPORT_TEMPL #define EXPORT_TEMPL extern
#define IMPORT_TEMPL #define IMPORT_TEMPL extern
#endif #endif
#ifdef __cplusplus #ifdef __cplusplus

View File

@ -127,16 +127,6 @@ INLINE ostream &operator << (ostream &out, NotifyCategoryProxy<GetCategory> &pro
#ifdef CPPPARSER #ifdef CPPPARSER
#define NotifyCategoryDecl(basename, expcl, exptp) #define NotifyCategoryDecl(basename, expcl, exptp)
#elif defined(WIN32_VC)
// MSVC's rules for extern template classes differ slightly.
#define NotifyCategoryDecl(basename, expcl, exptp) \
class expcl NotifyCategoryGetCategory_ ## basename { \
public: \
NotifyCategoryGetCategory_ ## basename(); \
static NotifyCategory *get_category(); \
}; \
EXPORT_TEMPLATE_CLASS(expcl, exptp, NotifyCategoryProxy<NotifyCategoryGetCategory_ ## basename>); \
extern expcl NotifyCategoryProxy<NotifyCategoryGetCategory_ ## basename> basename ## _cat;
#else #else
#define NotifyCategoryDecl(basename, expcl, exptp) \ #define NotifyCategoryDecl(basename, expcl, exptp) \
class expcl NotifyCategoryGetCategory_ ## basename { \ class expcl NotifyCategoryGetCategory_ ## basename { \
@ -144,7 +134,7 @@ INLINE ostream &operator << (ostream &out, NotifyCategoryProxy<GetCategory> &pro
NotifyCategoryGetCategory_ ## basename(); \ NotifyCategoryGetCategory_ ## basename(); \
static NotifyCategory *get_category(); \ static NotifyCategory *get_category(); \
}; \ }; \
EXPORT_TEMPLATE_CLASS(expcl, extern, NotifyCategoryProxy<NotifyCategoryGetCategory_ ## basename>); \ EXPORT_TEMPLATE_CLASS(expcl, exptp, NotifyCategoryProxy<NotifyCategoryGetCategory_ ## basename>); \
extern expcl NotifyCategoryProxy<NotifyCategoryGetCategory_ ## basename> basename ## _cat; extern expcl NotifyCategoryProxy<NotifyCategoryGetCategory_ ## basename> basename ## _cat;
#endif #endif

View File

@ -1650,8 +1650,6 @@ def CompileLink(dll, obj, opts):
else: else:
cmd += " -pthread" cmd += " -pthread"
cmd += " -Wl,-allow-multiple-definition"
if LDFLAGS != "": if LDFLAGS != "":
cmd += " " + LDFLAGS cmd += " " + LDFLAGS

View File

@ -22,6 +22,9 @@
#pragma implementation #pragma implementation
#endif #endif
template class AnimChannel<ACMatrixSwitchType>;
template class AnimChannel<ACScalarSwitchType>;
//////////////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////////////
// Function: ACMatrixSwitchType::output_value // Function: ACMatrixSwitchType::output_value
// Access: Public, Static // Access: Public, Static

View File

@ -28,6 +28,8 @@
#pragma implementation #pragma implementation
#endif #endif
template class MovingPart<ACMatrixSwitchType>;
TypeHandle MovingPartMatrix::_type_handle; TypeHandle MovingPartMatrix::_type_handle;
//////////////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////////////

View File

@ -26,6 +26,8 @@
#pragma implementation #pragma implementation
#endif #endif
template class MovingPart<ACScalarSwitchType>;
TypeHandle MovingPartScalar::_type_handle; TypeHandle MovingPartScalar::_type_handle;
//////////////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////////////

View File

@ -49,8 +49,12 @@ private:
Parameter _offset; Parameter _offset;
}; };
// I'd love to export these, but it produces a strange linker issue
// with Mac OS X's version of GCC. We'll do it only on Windows, then.
#ifdef _MSC_VER
EXPORT_TEMPLATE_CLASS(EXPCL_PANDAEGG, EXPTP_PANDAEGG, EggMorph<LVector3d>); EXPORT_TEMPLATE_CLASS(EXPCL_PANDAEGG, EXPTP_PANDAEGG, EggMorph<LVector3d>);
EXPORT_TEMPLATE_CLASS(EXPCL_PANDAEGG, EXPTP_PANDAEGG, EggMorph<LVector4>); EXPORT_TEMPLATE_CLASS(EXPCL_PANDAEGG, EXPTP_PANDAEGG, EggMorph<LVector4>);
#endif
typedef EggMorph<LVector3d> EggMorphVertex; typedef EggMorph<LVector3d> EggMorphVertex;
typedef EggMorph<LVector3d> EggMorphNormal; typedef EggMorph<LVector3d> EggMorphNormal;

View File

@ -18,3 +18,7 @@
#ifdef __GNUC__ #ifdef __GNUC__
#pragma implementation #pragma implementation
#endif #endif
template class PointerToBase<EggMaterial>;
template class PointerTo<EggMaterial>;
template class ConstPointerTo<EggMaterial>;

View File

@ -18,3 +18,7 @@
#ifdef __GNUC__ #ifdef __GNUC__
#pragma implementation #pragma implementation
#endif #endif
template class PointerToBase<EggTexture>;
template class PointerTo<EggTexture>;
template class ConstPointerTo<EggTexture>;

View File

@ -18,3 +18,7 @@
#ifdef __GNUC__ #ifdef __GNUC__
#pragma implementation #pragma implementation
#endif #endif
template class PointerToBase<EggVertex>;
template class PointerTo<EggVertex>;
template class ConstPointerTo<EggVertex>;

View File

@ -20,6 +20,9 @@
#pragma implementation #pragma implementation
#endif #endif
template class ParamValue<int>;
template class ParamValue<double>;
//////////////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////////////
// Function: EventParameter::output // Function: EventParameter::output
// Access: Published // Access: Published

View File

@ -18,3 +18,7 @@
#ifdef __GNUC__ #ifdef __GNUC__
#pragma implementation #pragma implementation
#endif #endif
template class PointerToBase<Event>;
template class PointerTo<Event>;
template class ConstPointerTo<Event>;

View File

@ -18,3 +18,8 @@
#ifdef __GNUC__ #ifdef __GNUC__
#pragma implementation #pragma implementation
#endif #endif
template class PointerToBase<ReferenceCountedVector<double> >;
template class PointerToArrayBase<double>;
template class PointerToArray<double>;
template class ConstPointerToArray<double>;

View File

@ -18,3 +18,8 @@
#ifdef __GNUC__ #ifdef __GNUC__
#pragma implementation #pragma implementation
#endif #endif
template class PointerToBase<ReferenceCountedVector<float> >;
template class PointerToArrayBase<float>;
template class PointerToArray<float>;
template class ConstPointerToArray<float>;

View File

@ -18,3 +18,8 @@
#ifdef __GNUC__ #ifdef __GNUC__
#pragma implementation #pragma implementation
#endif #endif
template class PointerToBase<ReferenceCountedVector<int> >;
template class PointerToArrayBase<int>;
template class PointerToArray<int>;
template class ConstPointerToArray<int>;

View File

@ -18,3 +18,8 @@
#ifdef __GNUC__ #ifdef __GNUC__
#pragma implementation #pragma implementation
#endif #endif
template class PointerToBase<ReferenceCountedVector<uchar> >;
template class PointerToArrayBase<uchar>;
template class PointerToArray<unsigned char>;
template class ConstPointerToArray<unsigned char>;

View File

@ -18,3 +18,13 @@
#ifdef __GNUC__ #ifdef __GNUC__
#pragma implementation #pragma implementation
#endif #endif
template class PointerToBase<ReferenceCountedVector<LMatrix3f> >;
template class PointerToArrayBase<LMatrix3f>;
template class PointerToArray<LMatrix3f>;
template class ConstPointerToArray<LMatrix3f>;
template class PointerToBase<ReferenceCountedVector<LMatrix3d> >;
template class PointerToArrayBase<LMatrix3d>;
template class PointerToArray<LMatrix3d>;
template class ConstPointerToArray<LMatrix3d>;

View File

@ -18,3 +18,13 @@
#ifdef __GNUC__ #ifdef __GNUC__
#pragma implementation #pragma implementation
#endif #endif
template class PointerToBase<ReferenceCountedVector<UnalignedLMatrix4f> >;
template class PointerToArrayBase<UnalignedLMatrix4f>;
template class PointerToArray<UnalignedLMatrix4f>;
template class ConstPointerToArray<UnalignedLMatrix4f>;
template class PointerToBase<ReferenceCountedVector<UnalignedLMatrix4d> >;
template class PointerToArrayBase<UnalignedLMatrix4d>;
template class PointerToArray<UnalignedLMatrix4d>;
template class ConstPointerToArray<UnalignedLMatrix4d>;

View File

@ -18,3 +18,18 @@
#ifdef __GNUC__ #ifdef __GNUC__
#pragma implementation #pragma implementation
#endif #endif
template class PointerToBase<ReferenceCountedVector<LVecBase2f> >;
template class PointerToArrayBase<LVecBase2f>;
template class PointerToArray<LVecBase2f>;
template class ConstPointerToArray<LVecBase2f>;
template class PointerToBase<ReferenceCountedVector<LVecBase2d> >;
template class PointerToArrayBase<LVecBase2d>;
template class PointerToArray<LVecBase2d>;
template class ConstPointerToArray<LVecBase2d>;
template class PointerToBase<ReferenceCountedVector<LVecBase2i> >;
template class PointerToArrayBase<LVecBase2i>;
template class PointerToArray<LVecBase2i>;
template class ConstPointerToArray<LVecBase2i>;

View File

@ -18,3 +18,18 @@
#ifdef __GNUC__ #ifdef __GNUC__
#pragma implementation #pragma implementation
#endif #endif
template class PointerToBase<ReferenceCountedVector<LVecBase3f> >;
template class PointerToArrayBase<LVecBase3f>;
template class PointerToArray<LVecBase3f>;
template class ConstPointerToArray<LVecBase3f>;
template class PointerToBase<ReferenceCountedVector<LVecBase3d> >;
template class PointerToArrayBase<LVecBase3d>;
template class PointerToArray<LVecBase3d>;
template class ConstPointerToArray<LVecBase3d>;
template class PointerToBase<ReferenceCountedVector<LVecBase3i> >;
template class PointerToArrayBase<LVecBase3i>;
template class PointerToArray<LVecBase3i>;
template class ConstPointerToArray<LVecBase3i>;

View File

@ -18,3 +18,18 @@
#ifdef __GNUC__ #ifdef __GNUC__
#pragma implementation #pragma implementation
#endif #endif
template class PointerToBase<ReferenceCountedVector<UnalignedLVecBase4f> >;
template class PointerToArrayBase<UnalignedLVecBase4f>;
template class PointerToArray<UnalignedLVecBase4f>;
template class ConstPointerToArray<UnalignedLVecBase4f>;
template class PointerToBase<ReferenceCountedVector<UnalignedLVecBase4d> >;
template class PointerToArrayBase<UnalignedLVecBase4d>;
template class PointerToArray<UnalignedLVecBase4d>;
template class ConstPointerToArray<UnalignedLVecBase4d>;
template class PointerToBase<ReferenceCountedVector<UnalignedLVecBase4i> >;
template class PointerToArrayBase<UnalignedLVecBase4i>;
template class PointerToArray<UnalignedLVecBase4i>;
template class ConstPointerToArray<UnalignedLVecBase4i>;

View File

@ -18,6 +18,8 @@
#include "mutexHolder.h" #include "mutexHolder.h"
#include "lightMutexHolder.h" #include "lightMutexHolder.h"
template class QueuedReturn<Datagram>;
//////////////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////////////
// Function: DatagramGeneratorNet::Constructor // Function: DatagramGeneratorNet::Constructor
// Access: Published // Access: Published

View File

@ -15,6 +15,8 @@
#include "queuedConnectionListener.h" #include "queuedConnectionListener.h"
#include "config_net.h" #include "config_net.h"
template class QueuedReturn<ConnectionListenerData>;
//////////////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////////////
// Function: QueuedConnectionListener::Constructor // Function: QueuedConnectionListener::Constructor
// Access: Public // Access: Public

View File

@ -16,6 +16,8 @@
#include <algorithm> #include <algorithm>
template class QueuedReturn< PT(Connection) >;
//////////////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////////////
// Function: QueuedConnectionManager::Constructor // Function: QueuedConnectionManager::Constructor
// Access: Public // Access: Public

View File

@ -17,6 +17,8 @@
#include "trueClock.h" #include "trueClock.h"
#include "lightMutexHolder.h" #include "lightMutexHolder.h"
template class QueuedReturn<NetDatagram>;
//////////////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////////////
// Function: QueuedConnectionReader::Constructor // Function: QueuedConnectionReader::Constructor
// Access: Published // Access: Published

View File

@ -18,3 +18,7 @@
#ifdef __GNUC__ #ifdef __GNUC__
#pragma implementation #pragma implementation
#endif #endif
template class BitMask<PN_uint16, 16>;
template class BitMask<PN_uint32, 32>;
template class BitMask<PN_uint64, 64>;

View File

@ -19,3 +19,5 @@
#pragma implementation #pragma implementation
#endif #endif
template class DoubleBitMask<BitMaskNative>;
template class DoubleBitMask<DoubleBitMaskNative>;

View File

@ -20,6 +20,27 @@
#pragma implementation #pragma implementation
#endif #endif
template class ParamValue<std::string>;
template class ParamValue<std::wstring>;
template class ParamValue<LVecBase2d>;
template class ParamValue<LVecBase2f>;
template class ParamValue<LVecBase2i>;
template class ParamValue<LVecBase3d>;
template class ParamValue<LVecBase3f>;
template class ParamValue<LVecBase3i>;
template class ParamValue<LVecBase4d>;
template class ParamValue<LVecBase4f>;
template class ParamValue<LVecBase4i>;
template class ParamValue<LMatrix3d>;
template class ParamValue<LMatrix3f>;
template class ParamValue<LMatrix4d>;
template class ParamValue<LMatrix4f>;
TypeHandle ParamValueBase::_type_handle; TypeHandle ParamValueBase::_type_handle;
TypeHandle ParamTypedRefCount::_type_handle; TypeHandle ParamTypedRefCount::_type_handle;

View File

@ -18,3 +18,8 @@
#ifdef __GNUC__ #ifdef __GNUC__
#pragma implementation #pragma implementation
#endif #endif
template class PointerToBase<ReferenceCountedVector<ushort> >;
template class PointerToArrayBase<ushort>;
template class PointerToArray<unsigned short>;
template class ConstPointerToArray<unsigned short>;