From 362bde8e8eef41fc6a338ed8fbe6cbf7e9996019 Mon Sep 17 00:00:00 2001 From: =?utf8?q?J=C4=99drzej=20Nowacki?= Date: Mon, 13 Feb 2012 16:26:35 +0100 Subject: [PATCH] Introduce QMetaType::UnknownType. QMetaType::Void was ambiguous, it was pointing to a valid type (void) and in the same time it was signaling errors in QMetaType. There was no clean way to check if returned type was valid void or some unregistered type. This feature will be used by new QMetaObject revision which will store type ids instead of type names. So it will be easy to distinguish between: void mySlot(); MyUnregisteredType mySlot(); Change-Id: I73ff097f75585a95e12df74d50c6f3141153e771 Reviewed-by: Kent Hansen Reviewed-by: Olivier Goffart --- dist/changes-5.0.0 | 14 +++++ .../snippets/code/src_corelib_kernel_qmetatype.cpp | 2 +- src/corelib/kernel/qmetaobject.cpp | 36 ++++++------- src/corelib/kernel/qmetatype.cpp | 62 ++++++++++++---------- src/corelib/kernel/qmetatype.h | 9 ++-- src/corelib/kernel/qmetatypeswitcher_p.h | 7 ++- src/corelib/kernel/qvariant.cpp | 2 +- src/corelib/kernel/qvariant.h | 2 +- src/corelib/kernel/qvariant_p.h | 29 +++++++--- src/dbus/qdbusintegrator.cpp | 4 +- src/dbus/qdbusmetaobject.cpp | 10 ++-- src/dbus/qdbusmetatype.cpp | 4 +- src/dbus/qdbusmisc.cpp | 2 +- src/testlib/qsignaldumper.cpp | 3 +- src/testlib/qsignalspy.h | 4 +- src/tools/moc/generator.cpp | 20 +++---- src/tools/moc/moc.cpp | 4 +- .../corelib/kernel/qmetamethod/tst_qmetamethod.cpp | 17 +++--- .../corelib/kernel/qmetatype/tst_qmetatype.cpp | 4 ++ .../auto/corelib/kernel/qvariant/tst_qvariant.cpp | 12 ++++- 20 files changed, 152 insertions(+), 95 deletions(-) diff --git a/dist/changes-5.0.0 b/dist/changes-5.0.0 index cb1f8f4..95dbe0b 100644 --- a/dist/changes-5.0.0 +++ b/dist/changes-5.0.0 @@ -516,6 +516,20 @@ Qt for Windows CE QMetaType::User, which means that it points to the first registered custom type, instead of a nonexistent type. +- QMetaType + + * Interpretation of QMetaType::Void was changed. Before, in some cases + it was returned as an invalid type id, but sometimes it was used as a valid + type (C++ "void"). In Qt5, new QMetaType::UnknownType was introduced to + distinguish between these two. QMetaType::UnknownType is an invalid type id + signaling that a type is unknown to QMetaType, and QMetaType::Void + is a valid type id of C++ void type. The difference will be visible for + example in call to QMetaType::typeName(), this function will return null for + QMetaType::UnknownType and a pointer to "void" string for + QMetaType::Void. + Please, notice that QMetaType::UnknownType has value 0, which previously was + reserved for QMetaType::Void. + - QMessageBox diff --git a/doc/src/snippets/code/src_corelib_kernel_qmetatype.cpp b/doc/src/snippets/code/src_corelib_kernel_qmetatype.cpp index 9d72c42..d0a7a69 100644 --- a/doc/src/snippets/code/src_corelib_kernel_qmetatype.cpp +++ b/doc/src/snippets/code/src_corelib_kernel_qmetatype.cpp @@ -73,7 +73,7 @@ MyStruct s2 = var.value(); //! [3] int id = QMetaType::type("MyClass"); -if (id != 0) { +if (id != QMetaType::UnknownType) { void *myClassPtr = QMetaType::create(id); ... QMetaType::destroy(id, myClassPtr); diff --git a/src/corelib/kernel/qmetaobject.cpp b/src/corelib/kernel/qmetaobject.cpp index b38e7f9..e446d8b 100644 --- a/src/corelib/kernel/qmetaobject.cpp +++ b/src/corelib/kernel/qmetaobject.cpp @@ -1792,14 +1792,14 @@ QByteArray QMetaMethod::name() const Returns the return type of this method. The return value is one of the types that are registered - with QMetaType, or 0 if the type is not registered. + with QMetaType, or QMetaType::UnknownType if the type is not registered. \sa parameterType(), QMetaType, typeName() */ int QMetaMethod::returnType() const { if (!mobj) - return 0; + return QMetaType::UnknownType; return QMetaMethodPrivate::get(this)->returnType(); } @@ -1823,16 +1823,16 @@ int QMetaMethod::parameterCount() const Returns the type of the parameter at the given \a index. The return value is one of the types that are registered - with QMetaType, or 0 if the type is not registered. + with QMetaType, or QMetaType::UnknownType if the type is not registered. \sa parameterCount(), returnType(), QMetaType */ int QMetaMethod::parameterType(int index) const { if (!mobj || index < 0) - return 0; + return QMetaType::UnknownType; if (index >= QMetaMethodPrivate::get(this)->parameterCount()) - return 0; + return QMetaType::UnknownType; return QMetaMethodPrivate::get(this)->parameterType(index); } @@ -2241,7 +2241,7 @@ bool QMetaMethod::invoke(QObject *object, for (int i = 1; i < paramCount; ++i) { types[i] = QMetaType::type(typeNames[i]); - if (types[i]) { + if (types[i] != QMetaType::UnknownType) { args[i] = QMetaType::create(types[i], param[i]); ++nargs; } else if (param[i]) { @@ -2715,11 +2715,11 @@ QVariant::Type QMetaProperty::type() const uint flags = mobj->d.data[handle + 2]; type = flags >> 24; } - if (type) + if (type != QMetaType::UnknownType) return QVariant::Type(type); if (isEnumType()) { int enumMetaTypeId = QMetaType::type(qualifiedName(menum)); - if (enumMetaTypeId == 0) + if (enumMetaTypeId == QMetaType::UnknownType) return QVariant::Int; } #ifdef QT_COORD_TYPE @@ -2735,7 +2735,7 @@ QVariant::Type QMetaProperty::type() const \since 4.2 Returns this property's user type. The return value is one - of the values that are registered with QMetaType, or 0 if + of the values that are registered with QMetaType, or QMetaType::UnknownType if the type is not registered. \sa type(), QMetaType, typeName() @@ -2743,11 +2743,11 @@ QVariant::Type QMetaProperty::type() const int QMetaProperty::userType() const { if (!mobj) - return 0; + return QMetaType::UnknownType; if (priv(mobj->d.data)->revision >= 7) { int handle = priv(mobj->d.data)->propertyData + 3*idx; int type = typeFromTypeInfo(mobj, mobj->d.data[handle + 1]); - if (type) + if (type != QMetaType::UnknownType) return type; } else { QVariant::Type tp = type(); @@ -2756,7 +2756,7 @@ int QMetaProperty::userType() const } if (isEnumType()) { int enumMetaTypeId = QMetaType::type(qualifiedName(menum)); - if (enumMetaTypeId == 0) + if (enumMetaTypeId == QMetaType::UnknownType) return QVariant::Int; // Match behavior of QMetaType::type() return enumMetaTypeId; } @@ -2853,7 +2853,7 @@ QVariant QMetaProperty::read(const QObject *object) const with QMetaType) */ int enumMetaTypeId = QMetaType::type(qualifiedName(menum)); - if (enumMetaTypeId != 0) + if (enumMetaTypeId != QMetaType::UnknownType) t = enumMetaTypeId; } else { int handle = priv(mobj->d.data)->propertyData + 3*idx; @@ -2869,14 +2869,14 @@ QVariant QMetaProperty::read(const QObject *object) const } else { uint flags = mobj->d.data[handle + 2]; t = (flags >> 24); - if (t == QVariant::Invalid) { + if (t == QMetaType::UnknownType) { typeName = legacyString(mobj, mobj->d.data[handle + 1]); t = QMetaType::type(typeName); - if (t == QVariant::Invalid) + if (t == QMetaType::UnknownType) t = QVariant::nameToType(typeName); } } - if (t == QVariant::Invalid) { + if (t == QMetaType::UnknownType) { qWarning("QMetaProperty::read: Unable to handle unregistered datatype '%s' for property '%s::%s'", typeName, mobj->className(), name()); return QVariant(); } @@ -2931,7 +2931,7 @@ bool QMetaProperty::write(QObject *object, const QVariant &value) const return false; } else if (v.type() != QVariant::Int && v.type() != QVariant::UInt) { int enumMetaTypeId = QMetaType::type(qualifiedName(menum)); - if ((enumMetaTypeId == 0) || (v.userType() != enumMetaTypeId) || !v.constData()) + if ((enumMetaTypeId == QMetaType::UnknownType) || (v.userType() != enumMetaTypeId) || !v.constData()) return false; v = QVariant(*reinterpret_cast(v.constData())); } @@ -2952,7 +2952,7 @@ bool QMetaProperty::write(QObject *object, const QVariant &value) const t = flags >> 24; typeName = legacyString(mobj, mobj->d.data[handle + 1]); } - if (t == QVariant::Invalid) { + if (t == QMetaType::UnknownType) { const char *typeName = rawStringData(mobj, mobj->d.data[handle + 1]); const char *vtypeName = value.typeName(); if (vtypeName && strcmp(typeName, vtypeName) == 0) diff --git a/src/corelib/kernel/qmetatype.cpp b/src/corelib/kernel/qmetatype.cpp index 003ad1c..6d5973a 100644 --- a/src/corelib/kernel/qmetatype.cpp +++ b/src/corelib/kernel/qmetatype.cpp @@ -242,6 +242,7 @@ template<> struct TypeDefinition { static const bool IsAvailable = fals \value QEasingCurve QEasingCurve \value User Base value for user types + \value UnknownType This is an invalid type id. It is returned from QMetaType for types that are not registered \omitvalue FirstGuiType \omitvalue FirstWidgetsType @@ -311,7 +312,7 @@ static const struct { const char * typeName; int typeNameLength; int type; } typ QT_FOR_EACH_STATIC_TYPE(QT_ADD_STATIC_METATYPE) QT_FOR_EACH_STATIC_ALIAS_TYPE(QT_ADD_STATIC_METATYPE_ALIASES_ITER) QT_FOR_EACH_STATIC_HACKS_TYPE(QT_ADD_STATIC_METATYPE_HACKS_ITER) - {0, 0, QMetaType::Void} + {0, 0, QMetaType::UnknownType} }; Q_CORE_EXPORT const QMetaTypeInterface *qMetaTypeGuiHelper = 0; @@ -348,10 +349,7 @@ Q_GLOBAL_STATIC(QReadWriteLock, customTypesLock) void QMetaType::registerStreamOperators(const char *typeName, SaveOperator saveOp, LoadOperator loadOp) { - int idx = type(typeName); - if (!idx) - return; - registerStreamOperators(idx, saveOp, loadOp); + registerStreamOperators(type(typeName), saveOp, loadOp); } /*! \internal @@ -434,7 +432,7 @@ static int qMetaTypeCustomType_unlocked(const char *typeName, int length) { const QVector * const ct = customTypes(); if (!ct) - return 0; + return QMetaType::UnknownType; for (int v = 0; v < ct->count(); ++v) { const QCustomTypeInfo &customInfo = ct->at(v); @@ -445,7 +443,7 @@ static int qMetaTypeCustomType_unlocked(const char *typeName, int length) return v + QMetaType::User; } } - return 0; + return QMetaType::UnknownType; } /*! \internal @@ -488,11 +486,11 @@ int QMetaType::registerType(const char *typeName, Deleter deleter, int previousSize = 0; int previousFlags = 0; - if (!idx) { + if (idx == UnknownType) { QWriteLocker locker(customTypesLock()); idx = qMetaTypeCustomType_unlocked(normalizedTypeName.constData(), normalizedTypeName.size()); - if (!idx) { + if (idx == UnknownType) { QCustomTypeInfo inf; inf.typeName = normalizedTypeName; inf.creator = creator; @@ -558,12 +556,12 @@ int QMetaType::registerTypedef(const char* typeName, int aliasId) int idx = qMetaTypeStaticType(normalizedTypeName.constData(), normalizedTypeName.size()); - if (!idx) { + if (idx == UnknownType) { QWriteLocker locker(customTypesLock()); idx = qMetaTypeCustomType_unlocked(normalizedTypeName.constData(), normalizedTypeName.size()); - if (!idx) { + if (idx == UnknownType) { QCustomTypeInfo inf; inf.typeName = normalizedTypeName; inf.alias = aliasId; @@ -592,17 +590,20 @@ int QMetaType::registerTypedef(const char* typeName, int aliasId) */ bool QMetaType::isRegistered(int type) { - if (type >= 0 && type < User) { - // predefined type + // predefined type + if ((type >= FirstCoreType && type <= LastCoreType) + || (type >= FirstGuiType && type <= LastGuiType) + || (type >= FirstWidgetsType && type <= LastWidgetsType)) { return true; } + QReadLocker locker(customTypesLock()); const QVector * const ct = customTypes(); return ((type >= User) && (ct && ct->count() > type - User) && !ct->at(type - User).typeName.isEmpty()); } /*! - Returns a handle to the type called \a typeName, or 0 if there is + Returns a handle to the type called \a typeName, or QMetaType::UnknownType if there is no such type. \sa isRegistered(), typeName(), Type @@ -611,17 +612,17 @@ int QMetaType::type(const char *typeName) { int length = qstrlen(typeName); if (!length) - return 0; + return UnknownType; int type = qMetaTypeStaticType(typeName, length); - if (!type) { + if (type == UnknownType) { QReadLocker locker(customTypesLock()); type = qMetaTypeCustomType_unlocked(typeName, length); #ifndef QT_NO_QOBJECT - if (!type) { + if (type == UnknownType) { const NS(QByteArray) normalizedTypeName = QMetaObject::normalizedType(typeName); type = qMetaTypeStaticType(normalizedTypeName.constData(), normalizedTypeName.size()); - if (!type) { + if (type == UnknownType) { type = qMetaTypeCustomType_unlocked(normalizedTypeName.constData(), normalizedTypeName.size()); } @@ -652,6 +653,7 @@ bool QMetaType::save(QDataStream &stream, int type, const void *data) return false; switch(type) { + case QMetaType::UnknownType: case QMetaType::Void: case QMetaType::VoidStar: case QMetaType::QObjectStar: @@ -857,6 +859,7 @@ bool QMetaType::load(QDataStream &stream, int type, void *data) return false; switch(type) { + case QMetaType::UnknownType: case QMetaType::Void: case QMetaType::VoidStar: case QMetaType::QObjectStar: @@ -1154,6 +1157,7 @@ void *QMetaType::create(int type, const void *copy) case QMetaType::QModelIndex: return new NS(QModelIndex)(*static_cast(copy)); #endif + case QMetaType::UnknownType: case QMetaType::Void: return 0; default: @@ -1257,6 +1261,7 @@ void *QMetaType::create(int type, const void *copy) case QMetaType::QModelIndex: return new NS(QModelIndex); #endif + case QMetaType::UnknownType: case QMetaType::Void: return 0; default: @@ -1318,6 +1323,7 @@ public: template void delegate(const T *where) { DestroyerImpl::Destroy(m_type, const_cast(where)); } void delegate(const void *) {} + void delegate(const QMetaTypeSwitcher::UnknownType*) {} void delegate(const QMetaTypeSwitcher::NotBuiltinType *where) { customTypeDestroyer(m_type, (void*)where); } private: @@ -1380,6 +1386,7 @@ public: template void *delegate(const T *copy) { return ConstructorImpl::Construct(m_type, m_where, copy); } void *delegate(const void *) { return m_where; } + void *delegate(const QMetaTypeSwitcher::UnknownType*) { return m_where; } void *delegate(const QMetaTypeSwitcher::NotBuiltinType *copy) { return customTypeConstructor(m_type, m_where, copy); } private: @@ -1468,6 +1475,7 @@ public: template void delegate(const T *where) { DestructorImpl::Destruct(m_type, const_cast(where)); } void delegate(const void *) {} + void delegate(const QMetaTypeSwitcher::UnknownType*) {} void delegate(const QMetaTypeSwitcher::NotBuiltinType *where) { customTypeDestructor(m_type, (void*)where); } private: @@ -1536,6 +1544,7 @@ public: template int delegate(const T*) { return SizeOfImpl::Size(m_type); } + int delegate(const QMetaTypeSwitcher::UnknownType*) { return 0; } int delegate(const QMetaTypeSwitcher::NotBuiltinType*) { return customTypeSizeOf(m_type); } private: static int customTypeSizeOf(const int type) @@ -1606,13 +1615,14 @@ public: template quint32 delegate(const T*) { return FlagsImpl::Flags(m_type); } quint32 delegate(const void*) { return 0; } + quint32 delegate(const QMetaTypeSwitcher::UnknownType*) { return 0; } quint32 delegate(const QMetaTypeSwitcher::NotBuiltinType*) { return customTypeFlags(m_type); } private: const int m_type; static quint32 customTypeFlags(const int type) { const QVector * const ct = customTypes(); - if (Q_UNLIKELY(!ct)) + if (Q_UNLIKELY(!ct || type < QMetaType::User)) return 0; QReadLocker locker(customTypesLock()); if (Q_UNLIKELY(ct->count() <= type - QMetaType::User)) @@ -1793,6 +1803,7 @@ public: template void delegate(const T*) { TypeInfoImpl(m_type, info); } void delegate(const void*) {} + void delegate(const QMetaTypeSwitcher::UnknownType*) {} void delegate(const QMetaTypeSwitcher::NotBuiltinType*) { customTypeInfo(m_type); } private: void customTypeInfo(const uint type) @@ -1813,7 +1824,7 @@ QMetaType QMetaType::typeInfo(const int type) { TypeInfo typeInfo(type); QMetaTypeSwitcher::switcher(typeInfo, type, 0); - return typeInfo.info.creator || !type ? QMetaType(QMetaType::NoExtensionFlags + return typeInfo.info.creator || type == Void ? QMetaType(QMetaType::NoExtensionFlags , static_cast(0) // typeInfo::info is a temporary variable, we can't return address of it. , typeInfo.info.creator , typeInfo.info.deleter @@ -1824,26 +1835,23 @@ QMetaType QMetaType::typeInfo(const int type) , typeInfo.info.size , typeInfo.info.flags , type) - : QMetaType(-1); + : QMetaType(UnknownType); } QMetaType::QMetaType(const int typeId) : m_typeId(typeId) { - if (Q_UNLIKELY(typeId == -1)) { + if (Q_UNLIKELY(typeId == UnknownType)) { // Constructs invalid QMetaType instance. m_extensionFlags = 0xffffffff; Q_ASSERT(!isValid()); } else { // TODO it can be better. *this = QMetaType::typeInfo(typeId); - if (m_typeId > 0 && !m_creator) { + if (m_typeId == UnknownType) m_extensionFlags = 0xffffffff; - m_typeId = -1; - } - if (m_typeId == QMetaType::Void) { + else if (m_typeId == QMetaType::Void) m_extensionFlags = CreateEx | DestroyEx | ConstructEx | DestructEx; - } } } diff --git a/src/corelib/kernel/qmetatype.h b/src/corelib/kernel/qmetatype.h index beb7294..0f069dc 100644 --- a/src/corelib/kernel/qmetatype.h +++ b/src/corelib/kernel/qmetatype.h @@ -59,7 +59,7 @@ QT_BEGIN_NAMESPACE // F is a tuple: (QMetaType::TypeName, QMetaType::TypeNameID, RealType) #define QT_FOR_EACH_STATIC_PRIMITIVE_TYPE(F)\ - F(Void, 0, void) \ + F(Void, 43, void) \ F(Bool, 1, bool) \ F(Int, 2, int) \ F(UInt, 3, uint) \ @@ -192,8 +192,8 @@ public: // these are merged with QVariant QT_FOR_EACH_STATIC_TYPE(QT_DEFINE_METATYPE_ID) - FirstCoreType = Void, - LastCoreType = QModelIndex, + FirstCoreType = Bool, + LastCoreType = Void, FirstGuiType = QFont, LastGuiType = QPolygonF, FirstWidgetsType = QIcon, @@ -202,6 +202,7 @@ public: QReal = sizeof(qreal) == sizeof(double) ? Double : Float, + UnknownType = 0, User = 256 }; @@ -627,7 +628,7 @@ inline QMetaType::~QMetaType() inline bool QMetaType::isValid() const { - return m_typeId >= 0; + return m_typeId != UnknownType; } inline bool QMetaType::isRegistered() const diff --git a/src/corelib/kernel/qmetatypeswitcher_p.h b/src/corelib/kernel/qmetatypeswitcher_p.h index e9c15ea..ffd188c 100644 --- a/src/corelib/kernel/qmetatypeswitcher_p.h +++ b/src/corelib/kernel/qmetatypeswitcher_p.h @@ -59,7 +59,8 @@ QT_BEGIN_NAMESPACE class QMetaTypeSwitcher { public: - class NotBuiltinType; + class NotBuiltinType; // type is not a built-in type, but it may be a custom type or an unknown type + class UnknownType; // type not known to QMetaType system template static ReturnType switcher(DelegateObject &logic, int type, const void *data); }; @@ -74,7 +75,11 @@ ReturnType QMetaTypeSwitcher::switcher(DelegateObject &logic, int type, const vo switch (QMetaType::Type(type)) { QT_FOR_EACH_STATIC_TYPE(QT_METATYPE_SWICHER_CASE) + case QMetaType::UnknownType: + return logic.delegate(static_cast(data)); default: + if (type < QMetaType::User) + return logic.delegate(static_cast(data)); return logic.delegate(static_cast(data)); } } diff --git a/src/corelib/kernel/qvariant.cpp b/src/corelib/kernel/qvariant.cpp index 1c18883..ae51764 100644 --- a/src/corelib/kernel/qvariant.cpp +++ b/src/corelib/kernel/qvariant.cpp @@ -1697,7 +1697,7 @@ void QVariant::load(QDataStream &s) QByteArray name; s >> name; typeId = QMetaType::type(name); - if (!typeId) { + if (typeId == QMetaType::UnknownType) { s.setStatus(QDataStream::ReadCorruptData); return; } diff --git a/src/corelib/kernel/qvariant.h b/src/corelib/kernel/qvariant.h index 5da482d..4d4b2d5 100644 --- a/src/corelib/kernel/qvariant.h +++ b/src/corelib/kernel/qvariant.h @@ -126,7 +126,7 @@ class Q_CORE_EXPORT QVariant { public: enum Type { - Invalid = QMetaType::Void, + Invalid = QMetaType::UnknownType, Bool = QMetaType::Bool, Int = QMetaType::Int, UInt = QMetaType::UInt, diff --git a/src/corelib/kernel/qvariant_p.h b/src/corelib/kernel/qvariant_p.h index a754bc4..b28aaf3 100644 --- a/src/corelib/kernel/qvariant_p.h +++ b/src/corelib/kernel/qvariant_p.h @@ -187,7 +187,11 @@ public: return FilteredComparator::compare(m_a, m_b); } - bool delegate(const void*) { return true; } + bool delegate(const void*) { Q_ASSERT(false); return true; } + bool delegate(const QMetaTypeSwitcher::UnknownType*) + { + return true; // for historical reason invalid variant == invalid variant + } bool delegate(const QMetaTypeSwitcher::NotBuiltinType*) { return false; } protected: const QVariant::Private *m_a; @@ -281,7 +285,8 @@ public: return CallIsNull::isNull(m_d); } // we need that as sizof(void) is undefined and it is needed in HasIsNullMethod - bool delegate(const void *) { return m_d->is_null; } + bool delegate(const void *) { Q_ASSERT(false); return m_d->is_null; } + bool delegate(const QMetaTypeSwitcher::UnknownType *) { return m_d->is_null; } bool delegate(const QMetaTypeSwitcher::NotBuiltinType *) { return m_d->is_null; } protected: const QVariant::Private *m_d; @@ -354,8 +359,18 @@ public: void delegate(const void*) { - // QMetaType::Void == QVariant::Invalid, creating an invalid value creates invalid QVariant - // TODO it might go away, check is needed + qWarning("Trying to create a QVariant instance of QMetaType::Void type, an invalid QVariant will be constructed instead"); + m_x->type = QMetaType::UnknownType; + m_x->is_shared = false; + m_x->is_null = !m_copy; + } + + void delegate(const QMetaTypeSwitcher::UnknownType*) + { + if (m_x->type != QMetaType::UnknownType) { + qWarning("Trying to construct an instance of an invalid type, type id: %i", m_x->type); + m_x->type = QMetaType::UnknownType; + } m_x->is_shared = false; m_x->is_null = !m_copy; } @@ -401,7 +416,8 @@ public: qWarning("Trying to destruct an instance of an invalid type, type id: %i", m_d->type); } // Ignore nonconstructible type - void delegate(const void*) {} + void delegate(const QMetaTypeSwitcher::UnknownType*) {} + void delegate(const void*) { Q_ASSERT(false); } private: QVariant::Private *m_d; }; @@ -446,10 +462,11 @@ public: { qWarning("Trying to stream an instance of an invalid type, type id: %i", m_d->type); } - void delegate(const void*) + void delegate(const QMetaTypeSwitcher::UnknownType*) { m_debugStream.nospace() << "QVariant::Invalid"; } + void delegate(const void*) { Q_ASSERT(false); } private: QDebug m_debugStream; QVariant::Private *m_d; diff --git a/src/dbus/qdbusintegrator.cpp b/src/dbus/qdbusintegrator.cpp index f863650..8d46ee4 100644 --- a/src/dbus/qdbusintegrator.cpp +++ b/src/dbus/qdbusintegrator.cpp @@ -686,7 +686,7 @@ static int findSlot(const QMetaObject *mo, const QByteArray &name, int flags, ++i; // make sure that the output parameters have signatures too - if (returnType != 0 && QDBusMetaType::typeToSignature(returnType) == 0) + if (returnType != QMetaType::UnknownType && returnType != QMetaType::Void && QDBusMetaType::typeToSignature(returnType) == 0) continue; bool ok = true; @@ -919,7 +919,7 @@ void QDBusConnectionPrivate::deliverCall(QObject *object, int /*flags*/, const Q // output arguments QVariantList outputArgs; void *null = 0; - if (metaTypes[0] != QMetaType::Void) { + if (metaTypes[0] != QMetaType::Void && metaTypes[0] != QMetaType::UnknownType) { QVariant arg(metaTypes[0], null); outputArgs.append( arg ); params[0] = const_cast(outputArgs.at( outputArgs.count() - 1 ).constData()); diff --git a/src/dbus/qdbusmetaobject.cpp b/src/dbus/qdbusmetaobject.cpp index 7b8a67f..ce8146f 100644 --- a/src/dbus/qdbusmetaobject.cpp +++ b/src/dbus/qdbusmetaobject.cpp @@ -71,7 +71,6 @@ public: private: struct Method { QList parameterNames; - QByteArray typeName; QByteArray tag; QByteArray name; QVarLengthArray inputTypes; @@ -266,10 +265,7 @@ void QDBusMetaObjectGenerator::parseMethods() mm.outputTypes.append(type.id); - if (i == 0) { - // return value - mm.typeName = type.name; - } else { + if (i != 0) { // non-const ref parameter mm.parameterNames.append(arg.name.toLatin1()); @@ -477,7 +473,7 @@ void QDBusMetaObjectGenerator::write(QDBusMetaObject *obj) typeName = QMetaType::typeName(type); typeName.append('&'); } - Q_ASSERT(type || (i < 0)); + Q_ASSERT(type != QMetaType::UnknownType); int typeInfo; if (!typeName.isEmpty()) typeInfo = IsUnresolvedType | strings.enter(typeName); @@ -516,7 +512,7 @@ void QDBusMetaObjectGenerator::write(QDBusMetaObject *obj) // form is name, typeinfo, flags idata[offset++] = strings.enter(it.key()); // name - Q_ASSERT(mp.type != 0); + Q_ASSERT(mp.type != QMetaType::UnknownType); idata[offset++] = mp.type; idata[offset++] = mp.flags; diff --git a/src/dbus/qdbusmetatype.cpp b/src/dbus/qdbusmetatype.cpp index b0d6406..7c8d8cf 100644 --- a/src/dbus/qdbusmetatype.cpp +++ b/src/dbus/qdbusmetatype.cpp @@ -311,7 +311,7 @@ bool QDBusMetaType::demarshall(const QDBusArgument &arg, int id, void *data) int QDBusMetaType::signatureToType(const char *signature) { if (!signature) - return QVariant::Invalid; + return QMetaType::UnknownType; QDBusMetaTypeId::init(); switch (signature[0]) @@ -378,7 +378,7 @@ int QDBusMetaType::signatureToType(const char *signature) } // fall through default: - return QVariant::Invalid; + return QMetaType::UnknownType; } } diff --git a/src/dbus/qdbusmisc.cpp b/src/dbus/qdbusmisc.cpp index 0a5da60..88bab88 100644 --- a/src/dbus/qdbusmisc.cpp +++ b/src/dbus/qdbusmisc.cpp @@ -170,7 +170,7 @@ int qDBusParametersForMethod(const QMetaMethod &mm, QList& metaTypes) } int id = QMetaType::type(type); - if (id == 0) { + if (id == QMetaType::UnknownType) { //qWarning("Could not parse the method '%s'", mm.methodSignature().constData()); // invalid type in method parameter list return -1; diff --git a/src/testlib/qsignaldumper.cpp b/src/testlib/qsignaldumper.cpp index e15add0..c7b9f31 100644 --- a/src/testlib/qsignaldumper.cpp +++ b/src/testlib/qsignaldumper.cpp @@ -112,7 +112,8 @@ static void qSignalDumperCallback(QObject *caller, int method_index, void **argv quintptr addr = quintptr(*reinterpret_cast(argv[i + 1])); str.append(QByteArray::number(addr, 16)); - } else if (typeId != QMetaType::Void) { + } else if (typeId != QMetaType::UnknownType) { + Q_ASSERT(typeId != QMetaType::Void); // void parameter => metaobject is corrupt str.append(arg) .append('(') .append(QVariant(typeId, argv[i + 1]).toString().toLocal8Bit()) diff --git a/src/testlib/qsignalspy.h b/src/testlib/qsignalspy.h index eb52ebf..70944ba 100644 --- a/src/testlib/qsignalspy.h +++ b/src/testlib/qsignalspy.h @@ -122,9 +122,11 @@ private: QList params = member.parameterTypes(); for (int i = 0; i < params.count(); ++i) { int tp = QMetaType::type(params.at(i).constData()); - if (tp == QMetaType::Void) + if (tp == QMetaType::UnknownType) { + Q_ASSERT(tp != QMetaType::Void); // void parameter => metaobject is corrupt qWarning("Don't know how to handle '%s', use qRegisterMetaType to register it.", params.at(i).constData()); + } args << tp; } } diff --git a/src/tools/moc/generator.cpp b/src/tools/moc/generator.cpp index 73a0605..1284518 100644 --- a/src/tools/moc/generator.cpp +++ b/src/tools/moc/generator.cpp @@ -60,7 +60,7 @@ uint nameToBuiltinType(const QByteArray &name) return 0; uint tp = QMetaType::type(name.constData()); - return tp < QMetaType::User ? tp : 0; + return tp < uint(QMetaType::User) ? tp : QMetaType::UnknownType; } /* @@ -69,7 +69,7 @@ uint nameToBuiltinType(const QByteArray &name) bool isBuiltinType(const QByteArray &type) { int id = QMetaType::type(type.constData()); - if (!id && !type.isEmpty() && type != "void") + if (id == QMetaType::UnknownType) return false; return (id < QMetaType::User); } @@ -632,7 +632,7 @@ void Generator::generateFunctionParameters(const QList& list, const else fprintf(out, "%4d", type); } else { - Q_ASSERT(!typeName.isEmpty()); + Q_ASSERT(!typeName.isEmpty() || f.isConstructor); fprintf(out, "0x%.8x | %d", IsUnresolvedType, stridx(typeName)); } fputc(',', out); @@ -1097,8 +1097,9 @@ void Generator::generateStaticMetacall() fprintf(out, " switch (_id) {\n"); for (int methodindex = 0; methodindex < methodList.size(); ++methodindex) { const FunctionDef &f = methodList.at(methodindex); + Q_ASSERT(!f.normalizedType.isEmpty()); fprintf(out, " case %d: ", methodindex); - if (f.normalizedType.size()) + if (f.normalizedType != "void") fprintf(out, "{ %s _r = ", noRef(f.normalizedType).constData()); fprintf(out, "_t->"); if (f.inPrivateClass.size()) @@ -1113,7 +1114,7 @@ void Generator::generateStaticMetacall() isUsed_a = true; } fprintf(out, ");"); - if (f.normalizedType.size()) { + if (f.normalizedType != "void") { fprintf(out, "\n if (_a[0]) *reinterpret_cast< %s*>(_a[0]) = _r; } ", noRef(f.normalizedType).constData()); isUsed_a = true; @@ -1192,7 +1193,8 @@ void Generator::generateSignal(FunctionDef *def,int index) constQualifier = "const"; } - if (def->arguments.isEmpty() && def->normalizedType.isEmpty()) { + Q_ASSERT(!def->normalizedType.isEmpty()); + if (def->arguments.isEmpty() && def->normalizedType == "void") { fprintf(out, ")%s\n{\n" " QMetaObject::activate(%s, &staticMetaObject, %d, 0);\n" "}\n", constQualifier, thisPtr.constData(), index); @@ -1207,11 +1209,11 @@ void Generator::generateSignal(FunctionDef *def,int index) fprintf(out, "%s _t%d%s", a.type.name.constData(), offset++, a.rightType.constData()); } fprintf(out, ")%s\n{\n", constQualifier); - if (def->type.name.size() && def->normalizedType.size()) + if (def->type.name.size() && def->normalizedType != "void") fprintf(out, " %s _t0 = %s();\n", noRef(def->normalizedType).constData(), noRef(def->normalizedType).constData()); fprintf(out, " void *_a[] = { "); - if (def->normalizedType.isEmpty()) { + if (def->normalizedType == "void") { fprintf(out, "0"); } else { if (def->returnTypeIsVolatile) @@ -1227,7 +1229,7 @@ void Generator::generateSignal(FunctionDef *def,int index) fprintf(out, ", const_cast(reinterpret_cast(&_t%d))", i); fprintf(out, " };\n"); fprintf(out, " QMetaObject::activate(%s, &staticMetaObject, %d, _a);\n", thisPtr.constData(), index); - if (def->normalizedType.size()) + if (def->normalizedType != "void") fprintf(out, " return _t0;\n"); fprintf(out, "}\n"); } diff --git a/src/tools/moc/moc.cpp b/src/tools/moc/moc.cpp index 49fc295..467f85c 100644 --- a/src/tools/moc/moc.cpp +++ b/src/tools/moc/moc.cpp @@ -75,9 +75,7 @@ static QByteArray normalizeType(const QByteArray &ba, bool fixScope = false) } } *d = '\0'; - QByteArray result; - if (strncmp("void", buf, d - buf) != 0) - result = normalizeTypeInternal(buf, d, fixScope); + QByteArray result = normalizeTypeInternal(buf, d, fixScope); if (buf != stackbuf) delete [] buf; return result; diff --git a/tests/auto/corelib/kernel/qmetamethod/tst_qmetamethod.cpp b/tests/auto/corelib/kernel/qmetamethod/tst_qmetamethod.cpp index 60c8fdb..f44a671 100644 --- a/tests/auto/corelib/kernel/qmetamethod/tst_qmetamethod.cpp +++ b/tests/auto/corelib/kernel/qmetamethod/tst_qmetamethod.cpp @@ -223,7 +223,7 @@ void tst_QMetaMethod::method_data() QTest::newRow("MethodTestObject()") << QByteArray("MethodTestObject()") - << int(QMetaType::Void) << QByteArray("") + << int(QMetaType::UnknownType) << QByteArray("") << (QList()) << (QList()) << (QList()) @@ -259,7 +259,7 @@ void tst_QMetaMethod::method_data() QTest::newRow("MethodTestObject(int)") << QByteArray("MethodTestObject(int)") - << int(QMetaType::Void) << QByteArray("") + << int(QMetaType::UnknownType) << QByteArray("") << (QList() << int(QMetaType::Int)) << (QList() << QByteArray("int")) << (QList() << QByteArray("constructorIntArg")) @@ -295,7 +295,7 @@ void tst_QMetaMethod::method_data() QTest::newRow("MethodTestObject(qreal)") << QByteArray("MethodTestObject(qreal)") - << int(QMetaType::Void) << QByteArray("") + << int(QMetaType::UnknownType) << QByteArray("") << (QList() << qMetaTypeId()) << (QList() << QByteArray("qreal")) << (QList() << QByteArray("constructorQRealArg")) @@ -331,7 +331,7 @@ void tst_QMetaMethod::method_data() QTest::newRow("MethodTestObject(QString)") << QByteArray("MethodTestObject(QString)") - << int(QMetaType::Void) << QByteArray("") + << int(QMetaType::UnknownType) << QByteArray("") << (QList() << int(QMetaType::QString)) << (QList() << QByteArray("QString")) << (QList() << QByteArray("constructorQStringArg")) @@ -367,7 +367,7 @@ void tst_QMetaMethod::method_data() QTest::newRow("MethodTestObject(CustomType)") << QByteArray("MethodTestObject(CustomType)") - << int(QMetaType::Void) << QByteArray("") + << int(QMetaType::UnknownType) << QByteArray("") << (QList() << qMetaTypeId()) << (QList() << QByteArray("CustomType")) << (QList() << QByteArray("constructorCustomTypeArg")) @@ -403,7 +403,7 @@ void tst_QMetaMethod::method_data() QTest::newRow("MethodTestObject(CustomUnregisteredType)") << QByteArray("MethodTestObject(CustomUnregisteredType)") - << int(QMetaType::Void) << QByteArray("") + << int(QMetaType::UnknownType) << QByteArray("") << (QList() << 0) << (QList() << QByteArray("CustomUnregisteredType")) << (QList() << QByteArray("constructorCustomUnregisteredTypeArg")) @@ -536,7 +536,7 @@ void tst_QMetaMethod::method_data() QTest::newRow("MethodTestObject(bool,int,uint,qlonglong,qulonglong,double,long,short,char,ulong,ushort,uchar,float)") << QByteArray("MethodTestObject(bool,int,uint,qlonglong,qulonglong,double,long,short,char,ulong,ushort,uchar,float)") - << int(QMetaType::Void) << QByteArray("") + << int(QMetaType::UnknownType) << QByteArray("") << parameterTypes << parameterTypeNames << parameterNames << QMetaMethod::Public << QMetaMethod::Constructor; @@ -571,7 +571,7 @@ void tst_QMetaMethod::method_data() QTest::newRow("MethodTestObject(bool,int)") << QByteArray("MethodTestObject(bool,int)") - << int(QMetaType::Void) << QByteArray("") + << int(QMetaType::UnknownType) << QByteArray("") << (QList() << int(QMetaType::Bool) << int(QMetaType::Int)) << (QList() << QByteArray("bool") << QByteArray("int")) << (QList() << QByteArray("") << QByteArray("")) @@ -616,7 +616,6 @@ void tst_QMetaMethod::method() QCOMPARE(method.name(), computedName); QCOMPARE(method.tag(), ""); - QCOMPARE(method.returnType(), returnType); if (QByteArray(method.typeName()) != returnTypeName) { // QMetaMethod should always produce a semantically equivalent typename diff --git a/tests/auto/corelib/kernel/qmetatype/tst_qmetatype.cpp b/tests/auto/corelib/kernel/qmetatype/tst_qmetatype.cpp index 72913d1..4f283ce 100644 --- a/tests/auto/corelib/kernel/qmetatype/tst_qmetatype.cpp +++ b/tests/auto/corelib/kernel/qmetatype/tst_qmetatype.cpp @@ -315,6 +315,7 @@ void tst_QMetaType::typeName_data() QT_FOR_EACH_STATIC_TYPE(TYPENAME_DATA) QT_FOR_EACH_STATIC_ALIAS_TYPE(TYPENAME_DATA_ALIAS) + QTest::newRow("QMetaType::UnknownType") << QMetaType::UnknownType << static_cast(0); } void tst_QMetaType::typeName() @@ -625,6 +626,8 @@ void tst_QMetaType::sizeOf_data() { QTest::addColumn("type"); QTest::addColumn("size"); + + QTest::newRow("QMetaType::UnknownType") << QMetaType::UnknownType << 0; #define ADD_METATYPE_TEST_ROW(MetaTypeName, MetaTypeId, RealType) \ QTest::newRow(#RealType) << QMetaType::MetaTypeName << int(QTypeInfo::sizeOf); FOR_EACH_CORE_METATYPE(ADD_METATYPE_TEST_ROW) @@ -984,6 +987,7 @@ void tst_QMetaType::isRegistered_data() QTest::newRow("-1") << -1 << false; QTest::newRow("-42") << -42 << false; QTest::newRow("IsRegisteredDummyType + 1") << (dummyTypeId + 1) << false; + QTest::newRow("QMetaType::UnknownType") << int(QMetaType::UnknownType) << false; } void tst_QMetaType::isRegistered() diff --git a/tests/auto/corelib/kernel/qvariant/tst_qvariant.cpp b/tests/auto/corelib/kernel/qvariant/tst_qvariant.cpp index ccdab17..ffe1d2b 100644 --- a/tests/auto/corelib/kernel/qvariant/tst_qvariant.cpp +++ b/tests/auto/corelib/kernel/qvariant/tst_qvariant.cpp @@ -3542,6 +3542,10 @@ void tst_QVariant::loadQVariantFromDataStream(QDataStream::Version version) stream >> typeName >> loadedVariant; const int id = QMetaType::type(typeName.toLatin1()); + if (id == QMetaType::Void) { + // Void type is not supported by QVariant + return; + } QVariant constructedVariant(static_cast(id)); QCOMPARE(constructedVariant.userType(), id); @@ -3561,6 +3565,10 @@ void tst_QVariant::saveQVariantFromDataStream(QDataStream::Version version) dataFileStream >> typeName; QByteArray data = file.readAll(); const int id = QMetaType::type(typeName.toLatin1()); + if (id == QMetaType::Void) { + // Void type is not supported by QVariant + return; + } QBuffer buffer; buffer.open(QIODevice::ReadWrite); @@ -3621,7 +3629,9 @@ void tst_QVariant::debugStream_data() const char *tagName = QMetaType::typeName(id); if (!tagName) continue; - QTest::newRow(tagName) << QVariant(static_cast(id)) << id; + if (id != QMetaType::Void) { + QTest::newRow(tagName) << QVariant(static_cast(id)) << id; + } } QTest::newRow("QBitArray(111)") << QVariant(QBitArray(3, true)) << qMetaTypeId(); QTest::newRow("CustomStreamableClass") << QVariant(qMetaTypeId(), 0) << qMetaTypeId(); -- 2.7.4