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 IMPORT_CLASS
#endif
/* "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 IMPORT_TEMPL extern
#else
#define EXPORT_TEMPL
#define IMPORT_TEMPL
#define EXPORT_TEMPL extern
#define IMPORT_TEMPL extern
#endif
#ifdef __cplusplus

View File

@ -127,16 +127,6 @@ INLINE ostream &operator << (ostream &out, NotifyCategoryProxy<GetCategory> &pro
#ifdef CPPPARSER
#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
#define NotifyCategoryDecl(basename, expcl, exptp) \
class expcl NotifyCategoryGetCategory_ ## basename { \
@ -144,7 +134,7 @@ INLINE ostream &operator << (ostream &out, NotifyCategoryProxy<GetCategory> &pro
NotifyCategoryGetCategory_ ## basename(); \
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;
#endif

View File

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

View File

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

View File

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

View File

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

View File

@ -49,8 +49,12 @@ private:
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<LVector4>);
#endif
typedef EggMorph<LVector3d> EggMorphVertex;
typedef EggMorph<LVector3d> EggMorphNormal;

View File

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

View File

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

View File

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

View File

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

View File

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

View File

@ -18,3 +18,8 @@
#ifdef __GNUC__
#pragma implementation
#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__
#pragma implementation
#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__
#pragma implementation
#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__
#pragma implementation
#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__
#pragma implementation
#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__
#pragma implementation
#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__
#pragma implementation
#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__
#pragma implementation
#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__
#pragma implementation
#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 "lightMutexHolder.h"
template class QueuedReturn<Datagram>;
////////////////////////////////////////////////////////////////////
// Function: DatagramGeneratorNet::Constructor
// Access: Published

View File

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

View File

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

View File

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

View File

@ -18,3 +18,7 @@
#ifdef __GNUC__
#pragma implementation
#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
#endif
template class DoubleBitMask<BitMaskNative>;
template class DoubleBitMask<DoubleBitMaskNative>;

View File

@ -20,6 +20,27 @@
#pragma implementation
#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 ParamTypedRefCount::_type_handle;

View File

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