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 <kent.hansen@nokia.com>
Reviewed-by: Olivier Goffart <ogoffart@woboq.com>
bb10
Jędrzej Nowacki 2012-02-13 16:26:35 +01:00 committed by Qt by Nokia
parent 2b70a7d25c
commit 362bde8e8e
20 changed files with 152 additions and 95 deletions

14
dist/changes-5.0.0 vendored
View File

@ -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

View File

@ -73,7 +73,7 @@ MyStruct s2 = var.value<MyStruct>();
//! [3]
int id = QMetaType::type("MyClass");
if (id != 0) {
if (id != QMetaType::UnknownType) {
void *myClassPtr = QMetaType::create(id);
...
QMetaType::destroy(id, myClassPtr);

View File

@ -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<const int *>(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)

View File

@ -242,6 +242,7 @@ template<> struct TypeDefinition<QRegExp> { 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<QCustomTypeInfo> * 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<QCustomTypeInfo> * 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<const NS(QModelIndex)*>(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<typename T>
void delegate(const T *where) { DestroyerImpl<T>::Destroy(m_type, const_cast<T*>(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<typename T>
void *delegate(const T *copy) { return ConstructorImpl<T>::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<typename T>
void delegate(const T *where) { DestructorImpl<T>::Destruct(m_type, const_cast<T*>(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<typename T>
int delegate(const T*) { return SizeOfImpl<T>::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<typename T>
quint32 delegate(const T*) { return FlagsImpl<T>::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<QCustomTypeInfo> * 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<typename T>
void delegate(const T*) { TypeInfoImpl<T>(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<void>(typeInfo, type, 0);
return typeInfo.info.creator || !type ? QMetaType(QMetaType::NoExtensionFlags
return typeInfo.info.creator || type == Void ? QMetaType(QMetaType::NoExtensionFlags
, static_cast<const QMetaTypeInterface *>(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;
}
}
}

View File

@ -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

View File

@ -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<class ReturnType, class DelegateObject>
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<UnknownType const *>(data));
default:
if (type < QMetaType::User)
return logic.delegate(static_cast<UnknownType const *>(data));
return logic.delegate(static_cast<NotBuiltinType const *>(data));
}
}

View File

@ -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;
}

View File

@ -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,

View File

@ -187,7 +187,11 @@ public:
return FilteredComparator<T>::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<T>::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;

View File

@ -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<void*>(outputArgs.at( outputArgs.count() - 1 ).constData());

View File

@ -71,7 +71,6 @@ public:
private:
struct Method {
QList<QByteArray> parameterNames;
QByteArray typeName;
QByteArray tag;
QByteArray name;
QVarLengthArray<int, 4> 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;

View File

@ -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;
}
}

View File

@ -170,7 +170,7 @@ int qDBusParametersForMethod(const QMetaMethod &mm, QList<int>& 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;

View File

@ -112,7 +112,8 @@ static void qSignalDumperCallback(QObject *caller, int method_index, void **argv
quintptr addr = quintptr(*reinterpret_cast<void **>(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())

View File

@ -122,9 +122,11 @@ private:
QList<QByteArray> 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;
}
}

View File

@ -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<FunctionDef>& 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<void*>(reinterpret_cast<const void*>(&_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");
}

View File

@ -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;

View File

@ -223,7 +223,7 @@ void tst_QMetaMethod::method_data()
QTest::newRow("MethodTestObject()")
<< QByteArray("MethodTestObject()")
<< int(QMetaType::Void) << QByteArray("")
<< int(QMetaType::UnknownType) << QByteArray("")
<< (QList<int>())
<< (QList<QByteArray>())
<< (QList<QByteArray>())
@ -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>() << int(QMetaType::Int))
<< (QList<QByteArray>() << QByteArray("int"))
<< (QList<QByteArray>() << 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<int>() << qMetaTypeId<qreal>())
<< (QList<QByteArray>() << QByteArray("qreal"))
<< (QList<QByteArray>() << 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>() << int(QMetaType::QString))
<< (QList<QByteArray>() << QByteArray("QString"))
<< (QList<QByteArray>() << 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<int>() << qMetaTypeId<CustomType>())
<< (QList<QByteArray>() << QByteArray("CustomType"))
<< (QList<QByteArray>() << 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<int>() << 0)
<< (QList<QByteArray>() << QByteArray("CustomUnregisteredType"))
<< (QList<QByteArray>() << 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>() << int(QMetaType::Bool) << int(QMetaType::Int))
<< (QList<QByteArray>() << QByteArray("bool") << QByteArray("int"))
<< (QList<QByteArray>() << 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

View File

@ -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<const char*>(0);
}
void tst_QMetaType::typeName()
@ -625,6 +626,8 @@ void tst_QMetaType::sizeOf_data()
{
QTest::addColumn<QMetaType::Type>("type");
QTest::addColumn<int>("size");
QTest::newRow("QMetaType::UnknownType") << QMetaType::UnknownType << 0;
#define ADD_METATYPE_TEST_ROW(MetaTypeName, MetaTypeId, RealType) \
QTest::newRow(#RealType) << QMetaType::MetaTypeName << int(QTypeInfo<RealType>::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()

View File

@ -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<QVariant::Type>(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<QVariant::Type>(id)) << id;
if (id != QMetaType::Void) {
QTest::newRow(tagName) << QVariant(static_cast<QVariant::Type>(id)) << id;
}
}
QTest::newRow("QBitArray(111)") << QVariant(QBitArray(3, true)) << qMetaTypeId<QBitArray>();
QTest::newRow("CustomStreamableClass") << QVariant(qMetaTypeId<CustomStreamableClass>(), 0) << qMetaTypeId<CustomStreamableClass>();