summaryrefslogtreecommitdiffstats
path: root/src/corelib/kernel
diff options
context:
space:
mode:
authorMarc Mutz <marc.mutz@kdab.com>2012-07-25 09:08:33 +0200
committerThe Qt Project <gerrit-noreply@qt-project.org>2012-12-11 11:12:08 +0100
commit98b77f9faa14822479deb20cd6fe0ce4fe9b56da (patch)
tree8f1df1dea05ec907eb7ce86dd42e574ff5b724d9 /src/corelib/kernel
parent90c3340356e641958528007e838eab981f090fdf (diff)
QMetaType: remember whether a type was registered with Q_DECLARE_METATYPE
There are two ways to register a type: using Q_DECLARE_METATYPE(T) and using qRegisterMetaType<T>("T"). Doing one thing in one translation unit and another thing in another TU constitutes an ODR violation, because the value of QMetaTypeId<T>::Defined will differ in the two TUs. By adding the information whether a type was declared with Q_DECLARE_METATYPE to the typeFlags(), such a use will trigger the existing binary-incompatibility failure that checks for equality of the incoming type flags with the stored ones (if any). I had to encode the type as a defaulted function argument in order to avoid the linker merging instantiations of the function templates and therefore rendering the detection moot. Change-Id: I82017caf300458b411cc8ac2f6653536fac64117 Reviewed-by: Lars Knoll <lars.knoll@digia.com>
Diffstat (limited to 'src/corelib/kernel')
-rw-r--r--src/corelib/kernel/qmetatype.h17
1 files changed, 15 insertions, 2 deletions
diff --git a/src/corelib/kernel/qmetatype.h b/src/corelib/kernel/qmetatype.h
index 06d325f383..09c641e4a3 100644
--- a/src/corelib/kernel/qmetatype.h
+++ b/src/corelib/kernel/qmetatype.h
@@ -252,7 +252,8 @@ public:
IsEnumeration = 0x10,
SharedPointerToQObject = 0x20,
WeakPointerToQObject = 0x40,
- TrackingPointerToQObject = 0x80
+ TrackingPointerToQObject = 0x80,
+ WasDeclaredAsMetaType = 0x100
};
Q_DECLARE_FLAGS(TypeFlags, TypeFlag)
@@ -563,12 +564,19 @@ namespace QtPrivate {
| (Q_IS_ENUM(T) ? QMetaType::IsEnumeration : 0)
};
};
+
+ template<typename T, bool defined>
+ struct MetaTypeDefinedHelper
+ {
+ enum DefinedType { Defined = defined };
+ };
}
template <typename T>
int qRegisterNormalizedMetaType(const QT_PREPEND_NAMESPACE(QByteArray) &normalizedTypeName
#ifndef qdoc
, T * dummy = 0
+ , typename QtPrivate::MetaTypeDefinedHelper<T, QMetaTypeId2<T>::Defined && !QMetaTypeId2<T>::IsBuiltIn>::DefinedType defined = QtPrivate::MetaTypeDefinedHelper<T, QMetaTypeId2<T>::Defined && !QMetaTypeId2<T>::IsBuiltIn>::Defined
#endif
)
{
@@ -580,6 +588,10 @@ int qRegisterNormalizedMetaType(const QT_PREPEND_NAMESPACE(QByteArray) &normaliz
return QMetaType::registerNormalizedTypedef(normalizedTypeName, typedefOf);
QMetaType::TypeFlags flags(QtPrivate::QMetaTypeTypeFlags<T>::Flags);
+
+ if (defined)
+ flags |= QMetaType::WasDeclaredAsMetaType;
+
return QMetaType::registerNormalizedType(normalizedTypeName,
QtMetaTypePrivate::QMetaTypeFunctionHelper<T>::Delete,
QtMetaTypePrivate::QMetaTypeFunctionHelper<T>::Create,
@@ -594,6 +606,7 @@ template <typename T>
int qRegisterMetaType(const char *typeName
#ifndef qdoc
, T * dummy = 0
+ , typename QtPrivate::MetaTypeDefinedHelper<T, QMetaTypeId2<T>::Defined && !QMetaTypeId2<T>::IsBuiltIn>::DefinedType defined = QtPrivate::MetaTypeDefinedHelper<T, QMetaTypeId2<T>::Defined && !QMetaTypeId2<T>::IsBuiltIn>::Defined
#endif
)
{
@@ -602,7 +615,7 @@ int qRegisterMetaType(const char *typeName
#else
QT_PREPEND_NAMESPACE(QByteArray) normalizedTypeName = QMetaObject::normalizedType(typeName);
#endif
- return qRegisterNormalizedMetaType<T>(normalizedTypeName, dummy);
+ return qRegisterNormalizedMetaType<T>(normalizedTypeName, dummy, defined);
}
#ifndef QT_NO_DATASTREAM