int QMetaType::registerNormalizedType(const NS
(QByteArray) &normalizedTypeName, Deleter deleter,
Creator creator,
Destructor destructor,
Constructor constructor,
int size, TypeFlags flags,
const QMetaObject *metaObject
) {
QVector<QCustomTypeInfo> *ct = customTypes();
if (!ct || normalizedTypeName.isEmpty() || !deleter || !creator || !destructor || !constructor)
return -1;
int idx = qMetaTypeStaticType(normalizedTypeName.constData(),
normalizedTypeName.size());
int previousSize = 0;
int previousFlags = 0;
if (idx == UnknownType) {
idx = qMetaTypeCustomType_unlocked(normalizedTypeName.constData(),
normalizedTypeName.size());
if (idx == UnknownType) {
QCustomTypeInfo inf;
inf.typeName = normalizedTypeName;
inf.creator = creator;
inf.deleter = deleter;
#ifndef QT_NO_DATASTREAM
inf.loadOp = 0;
inf.saveOp = 0;
#endif
inf.alias = -1;
inf.constructor = constructor;
inf.destructor = destructor;
inf.size = size;
inf.flags = flags;
inf.metaObject = metaObject;
idx = ct->size() + User;
ct->append(inf);
return idx;
}
if (idx >= User) {
/* NEW CODE */
QCustomTypeInfo ttt = ct->at(idx - User);
previousSize = ttt.size;
previousFlags = ttt.flags;
ttt.creator = creator;
ttt.deleter = deleter;
ttt.constructor = constructor;
ttt.destructor = destructor;
ct->replace(idx - User, ttt);[/B]
/* OLD CODE
previousSize = ct->at(idx - User).size;
previousFlags = ct->at(idx - User).flags;
*/
}
}
if (idx < User) {
}
if (previousSize != size) {
qFatal("QMetaType::registerType: Binary compatibility break "
"-- Size mismatch for type '%s' [%i]. Previously registered "
"size %i, now registering size %i.",
normalizedTypeName.constData(), idx, previousSize, size);
}
// Ignore WasDeclaredAsMetaType inconsitency, to many users were hitting the problem
previousFlags |= WasDeclaredAsMetaType;
flags |= WasDeclaredAsMetaType;
if (previousFlags != flags) {
const int maskForTypeInfo = NeedsConstruction | NeedsDestruction | MovableType;
const char *msg = "QMetaType::registerType: Binary compatibility break. "
"\nType flags for type '%s' [%i] don't match. Previously "
"registered TypeFlags(0x%x), now registering TypeFlags(0x%x). "
"This is an ODR break, which means that your application depends on a C++ undefined behavior."
"\nHint: %s";
if ((previousFlags & maskForTypeInfo) != (flags & maskForTypeInfo)) {
hint += "\nIt seems that the type was registered at least twice in a different translation units, "
"but Q_DECLARE_TYPEINFO is not visible from all the translations unit or different flags were used."
"Remember that Q_DECLARE_TYPEINFO should be declared before QMetaType registration, "
"preferably it should be placed just after the type declaration and before Q_DECLARE_METATYPE";
}
qFatal(msg, normalizedTypeName.constData(), idx, previousFlags, int(flags), hint.constData());
}
return idx;
}
int QMetaType::registerNormalizedType(const NS(QByteArray) &normalizedTypeName, Deleter deleter,
Creator creator,
Destructor destructor,
Constructor constructor,
int size, TypeFlags flags, const QMetaObject *metaObject)
{
QVector<QCustomTypeInfo> *ct = customTypes();
if (!ct || normalizedTypeName.isEmpty() || !deleter || !creator || !destructor || !constructor)
return -1;
int idx = qMetaTypeStaticType(normalizedTypeName.constData(),
normalizedTypeName.size());
int previousSize = 0;
int previousFlags = 0;
if (idx == UnknownType) {
QWriteLocker locker(customTypesLock());
idx = qMetaTypeCustomType_unlocked(normalizedTypeName.constData(),
normalizedTypeName.size());
if (idx == UnknownType) {
QCustomTypeInfo inf;
inf.typeName = normalizedTypeName;
inf.creator = creator;
inf.deleter = deleter;
#ifndef QT_NO_DATASTREAM
inf.loadOp = 0;
inf.saveOp = 0;
#endif
inf.alias = -1;
inf.constructor = constructor;
inf.destructor = destructor;
inf.size = size;
inf.flags = flags;
inf.metaObject = metaObject;
idx = ct->size() + User;
ct->append(inf);
return idx;
}
if (idx >= User) {
/* NEW CODE */
QCustomTypeInfo ttt = ct->at(idx - User);
previousSize = ttt.size;
previousFlags = ttt.flags;
ttt.creator = creator;
ttt.deleter = deleter;
ttt.constructor = constructor;
ttt.destructor = destructor;
ct->replace(idx - User, ttt);[/B]
/* OLD CODE
previousSize = ct->at(idx - User).size;
previousFlags = ct->at(idx - User).flags;
*/
}
}
if (idx < User) {
previousSize = QMetaType::sizeOf(idx);
previousFlags = QMetaType::typeFlags(idx);
}
if (previousSize != size) {
qFatal("QMetaType::registerType: Binary compatibility break "
"-- Size mismatch for type '%s' [%i]. Previously registered "
"size %i, now registering size %i.",
normalizedTypeName.constData(), idx, previousSize, size);
}
// Ignore WasDeclaredAsMetaType inconsitency, to many users were hitting the problem
previousFlags |= WasDeclaredAsMetaType;
flags |= WasDeclaredAsMetaType;
if (previousFlags != flags) {
const int maskForTypeInfo = NeedsConstruction | NeedsDestruction | MovableType;
const char *msg = "QMetaType::registerType: Binary compatibility break. "
"\nType flags for type '%s' [%i] don't match. Previously "
"registered TypeFlags(0x%x), now registering TypeFlags(0x%x). "
"This is an ODR break, which means that your application depends on a C++ undefined behavior."
"\nHint: %s";
QT_PREPEND_NAMESPACE(QByteArray) hint;
if ((previousFlags & maskForTypeInfo) != (flags & maskForTypeInfo)) {
hint += "\nIt seems that the type was registered at least twice in a different translation units, "
"but Q_DECLARE_TYPEINFO is not visible from all the translations unit or different flags were used."
"Remember that Q_DECLARE_TYPEINFO should be declared before QMetaType registration, "
"preferably it should be placed just after the type declaration and before Q_DECLARE_METATYPE";
}
qFatal(msg, normalizedTypeName.constData(), idx, previousFlags, int(flags), hint.constData());
}
return idx;
}
To copy to clipboard, switch view to plain text mode
Bookmarks