summaryrefslogtreecommitdiffstats
path: root/src/corelib/kernel/qmetaobject.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'src/corelib/kernel/qmetaobject.cpp')
-rw-r--r--src/corelib/kernel/qmetaobject.cpp236
1 files changed, 92 insertions, 144 deletions
diff --git a/src/corelib/kernel/qmetaobject.cpp b/src/corelib/kernel/qmetaobject.cpp
index 62e626b187..7429f5a323 100644
--- a/src/corelib/kernel/qmetaobject.cpp
+++ b/src/corelib/kernel/qmetaobject.cpp
@@ -154,20 +154,29 @@ QT_BEGIN_NAMESPACE
static inline const QMetaObjectPrivate *priv(const uint* data)
{ return reinterpret_cast<const QMetaObjectPrivate*>(data); }
+static inline const char *rawStringData(const QMetaObject *mo, int index)
+{
+ Q_ASSERT(priv(mo->d.data)->revision >= 7);
+ uint offset = mo->d.stringdata[2*index];
+ return reinterpret_cast<const char *>(mo->d.stringdata) + offset;
+}
+
static inline const QByteArray stringData(const QMetaObject *mo, int index)
{
Q_ASSERT(priv(mo->d.data)->revision >= 7);
- const QByteArrayDataPtr data = { const_cast<QByteArrayData*>(&mo->d.stringdata[index]) };
- Q_ASSERT(data.ptr->ref.isStatic());
- Q_ASSERT(data.ptr->alloc == 0);
- Q_ASSERT(data.ptr->capacityReserved == 0);
- Q_ASSERT(data.ptr->size >= 0);
- return data;
+ uint offset = mo->d.stringdata[2*index];
+ uint length = mo->d.stringdata[2*index + 1];
+ const char *string = reinterpret_cast<const char *>(mo->d.stringdata) + offset;
+ return QByteArray::fromRawData(string, length);
}
-static inline const char *rawStringData(const QMetaObject *mo, int index)
+static inline const char *rawTypeNameFromTypeInfo(const QMetaObject *mo, uint typeInfo)
{
- return stringData(mo, index).data();
+ if (typeInfo & IsUnresolvedType) {
+ return rawStringData(mo, typeInfo & TypeNameIndexMask);
+ } else {
+ return QMetaType::typeName(typeInfo);
+ }
}
static inline QByteArray typeNameFromTypeInfo(const QMetaObject *mo, uint typeInfo)
@@ -181,16 +190,11 @@ static inline QByteArray typeNameFromTypeInfo(const QMetaObject *mo, uint typeIn
}
}
-static inline const char *rawTypeNameFromTypeInfo(const QMetaObject *mo, uint typeInfo)
-{
- return typeNameFromTypeInfo(mo, typeInfo).constData();
-}
-
static inline int typeFromTypeInfo(const QMetaObject *mo, uint typeInfo)
{
if (!(typeInfo & IsUnresolvedType))
return typeInfo;
- return QMetaType::type(stringData(mo, typeInfo & TypeNameIndexMask));
+ return QMetaType::type(rawStringData(mo, typeInfo & TypeNameIndexMask));
}
class QMetaMethodPrivate : public QMetaMethod
@@ -577,7 +581,7 @@ static bool methodMatch(const QMetaObject *m, int handle,
if (int(m->d.data[handle + 1]) != argc)
return false;
- if (stringData(m, m->d.data[handle]) != name)
+ if (rawStringData(m, m->d.data[handle]) != name)
return false;
int paramsIndex = m->d.data[handle + 2] + 1;
@@ -682,7 +686,9 @@ static void argumentTypesFromString(const char *str, const char *end,
--level;
++str;
}
- types += QArgumentType(QByteArray(begin, str - begin));
+ QByteArray argType(begin, str - begin);
+ argType.replace("QList<", "QVector<");
+ types += QArgumentType(std::move(argType));
}
}
@@ -1161,7 +1167,7 @@ QMetaProperty QMetaObject::property(int index) const
const QMetaObject *scope = nullptr;
if (qstrcmp(scope_name, "Qt") == 0)
- scope = &QObject::staticQtMetaObject;
+ scope = &Qt::staticMetaObject;
else
scope = QMetaObject_findMetaObject(this, scope_name);
if (scope)
@@ -1309,17 +1315,7 @@ static char *qNormalizeType(char *d, int &templdepth, QByteArray &result)
*/
QByteArray QMetaObject::normalizedType(const char *type)
{
- QByteArray result;
-
- if (!type || !*type)
- return result;
-
- QVarLengthArray<char> stackbuf(qstrlen(type) + 1);
- qRemoveWhitespace(type, stackbuf.data());
- int templdepth = 0;
- qNormalizeType(stackbuf.data(), templdepth, result);
-
- return result;
+ return normalizeTypeInternal(type, type + qstrlen(type));
}
/*!
@@ -2837,10 +2833,6 @@ QByteArray QMetaEnum::valueToKeys(int value) const
The enum needs to be declared with Q_ENUM.
*/
-static QByteArray qualifiedName(const QMetaEnum &e)
-{
- return QByteArray(e.scope()) + "::" + e.name();
-}
/*!
\class QMetaProperty
@@ -2931,65 +2923,45 @@ const char *QMetaProperty::typeName() const
Returns this property's type. The return value is one
of the values of the QVariant::Type enumeration.
- \sa userType(), typeName(), name()
+ \sa userType(), typeName(), name(), metaType()
*/
QVariant::Type QMetaProperty::type() const
{
- if (!mobj)
- return QVariant::Invalid;
- int handle = priv(mobj->d.data)->propertyData + 3*idx;
-
- Q_ASSERT(priv(mobj->d.data)->revision >= 7);
- uint type = typeFromTypeInfo(mobj, mobj->d.data[handle + 1]);
+ uint type = userType();
if (type >= QMetaType::User)
return QVariant::UserType;
- if (type != QMetaType::UnknownType)
- return QVariant::Type(type);
- if (isEnumType()) {
- int enumMetaTypeId = QMetaType::type(qualifiedName(menum));
- if (enumMetaTypeId == QMetaType::UnknownType)
- return QVariant::Int;
- }
-#ifdef QT_COORD_TYPE
- // qreal metatype must be resolved at runtime.
- if (strcmp(typeName(), "qreal") == 0)
- return QVariant::Type(qMetaTypeId<qreal>());
-#endif
-
- return QVariant::UserType;
+ return QVariant::Type(type);
}
/*!
\since 4.2
Returns this property's user type. The return value is one
- of the values that are registered with QMetaType, or QMetaType::UnknownType if
- the type is not registered.
+ of the values that are registered with QMetaType.
+
+ This is equivalent to metaType().id()
- \sa type(), QMetaType, typeName()
+ \sa type(), QMetaType, typeName(), metaType()
*/
int QMetaProperty::userType() const
{
if (!mobj)
return QMetaType::UnknownType;
- Q_ASSERT(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 != QMetaType::UnknownType)
- return type;
- if (isEnumType()) {
- type = QMetaType::type(qualifiedName(menum));
- if (type == QMetaType::UnknownType) {
- type = registerPropertyType();
- if (type == QMetaType::UnknownType)
- return QMetaType::Int; // Match behavior of QMetaType::type()
- }
- return type;
- }
- type = QMetaType::type(typeName());
- if (type != QMetaType::UnknownType)
- return type;
- return registerPropertyType();
+ return QMetaType(mobj->d.metaTypes[idx]).id();
+}
+
+/*!
+ \since 6.0
+
+ Returns this property's QMetaType.
+
+ \sa QMetaType
+ */
+QMetaType QMetaProperty::metaType() const
+{
+ if (!mobj)
+ return {};
+ return QMetaType(mobj->d.metaTypes[idx]);
}
/*!
@@ -3100,37 +3072,6 @@ QVariant QMetaProperty::read(const QObject *object) const
if (!object || !mobj)
return QVariant();
- uint t = QMetaType::Int;
- if (isEnumType()) {
- /*
- try to create a QVariant that can be converted to this enum
- type (only works if the enum has already been registered
- with QMetaType)
- */
- int enumMetaTypeId = QMetaType::type(qualifiedName(menum));
- if (enumMetaTypeId != QMetaType::UnknownType)
- t = enumMetaTypeId;
- } else {
- int handle = priv(mobj->d.data)->propertyData + 3*idx;
- const char *typeName = nullptr;
- Q_ASSERT(priv(mobj->d.data)->revision >= 7);
- uint typeInfo = mobj->d.data[handle + 1];
- if (!(typeInfo & IsUnresolvedType))
- t = typeInfo;
- else {
- typeName = rawStringData(mobj, typeInfo & TypeNameIndexMask);
- t = QMetaType::type(typeName);
- }
- if (t == QMetaType::UnknownType) {
- // Try to register the type and try again before reporting an error.
- t = registerPropertyType();
- if (t == QMetaType::UnknownType) {
- qWarning("QMetaProperty::read: Unable to handle unregistered datatype '%s' for property '%s::%s'", typeName, mobj->className(), name());
- return QVariant();
- }
- }
- }
-
// the status variable is changed by qt_metacall to indicate what it did
// this feature is currently only used by Qt D-Bus and should not be depended
// upon. Don't change it without looking into QDBusAbstractInterface first
@@ -3139,10 +3080,11 @@ QVariant QMetaProperty::read(const QObject *object) const
int status = -1;
QVariant value;
void *argv[] = { nullptr, &value, &status };
- if (t == QMetaType::QVariant) {
+ QMetaType t(mobj->d.metaTypes[idx]);
+ if (t == QMetaType::fromType<QVariant>()) {
argv[0] = &value;
} else {
- value = QVariant(t, (void*)nullptr);
+ value = QVariant(t, nullptr);
argv[0] = value.data();
}
if (priv(mobj->d.data)->flags & PropertyAccessInStaticMetaCall && mobj->d.static_metacall) {
@@ -3154,9 +3096,9 @@ QVariant QMetaProperty::read(const QObject *object) const
if (status != -1)
return value;
- if (t != QMetaType::QVariant && argv[0] != value.data())
+ if (t != QMetaType::fromType<QVariant>() && argv[0] != value.data())
// pointer or reference
- return QVariant((QVariant::Type)t, argv[0]);
+ return QVariant(t, argv[0]);
return value;
}
@@ -3177,9 +3119,10 @@ bool QMetaProperty::write(QObject *object, const QVariant &value) const
return false;
QVariant v = value;
- uint t = QMetaType::UnknownType;
- if (isEnumType()) {
- if (v.userType() == QMetaType::QString) {
+ QMetaType t(mobj->d.metaTypes[idx]);
+ if (t != QMetaType::fromType<QVariant>() && t != v.metaType()) {
+ if (isEnumType() && !t.metaObject() && v.userType() == QMetaType::QString) {
+ // Assigning a string to a property of type Q_ENUMS (instead of Q_ENUM)
bool ok;
if (isFlagType())
v = QVariant(menum.keysToValue(value.toByteArray(), &ok));
@@ -3187,39 +3130,14 @@ bool QMetaProperty::write(QObject *object, const QVariant &value) const
v = QVariant(menum.keyToValue(value.toByteArray(), &ok));
if (!ok)
return false;
- } else if (v.userType() != QMetaType::Int && v.userType() != QMetaType::UInt) {
- int enumMetaTypeId = QMetaType::type(qualifiedName(menum));
- if ((enumMetaTypeId == QMetaType::UnknownType) || (v.userType() != enumMetaTypeId) || !v.constData())
- return false;
- v = QVariant(*reinterpret_cast<const int *>(v.constData()));
- }
- v.convert(QMetaType::Int);
- } else {
- int handle = priv(mobj->d.data)->propertyData + 3*idx;
- const char *typeName = nullptr;
- Q_ASSERT(priv(mobj->d.data)->revision >= 7);
- uint typeInfo = mobj->d.data[handle + 1];
- if (!(typeInfo & IsUnresolvedType))
- t = typeInfo;
- else {
- typeName = rawStringData(mobj, typeInfo & TypeNameIndexMask);
- t = QMetaType::type(typeName);
- if (t == QMetaType::UnknownType)
- t = registerPropertyType();
- if (t == QMetaType::UnknownType)
- return false;
- }
- if (t != QMetaType::QVariant && int(t) != value.userType()) {
- if (!value.isValid()) {
- if (isResettable())
- return reset(object);
- v = QVariant(t, nullptr);
- } else if (!v.convert(t)) {
- return false;
- }
+ } else if (!value.isValid()) {
+ if (isResettable())
+ return reset(object);
+ v = QVariant(t, nullptr);
+ } else if (!v.convert(t.id())) {
+ return false;
}
}
-
// the status variable is changed by qt_metacall to indicate what it did
// this feature is currently only used by Qt D-Bus and should not be depended
// upon. Don't change it without looking into QDBusAbstractInterface first
@@ -3230,7 +3148,7 @@ bool QMetaProperty::write(QObject *object, const QVariant &value) const
// interception of property writes.
int flags = 0;
void *argv[] = { nullptr, &v, &status, &flags };
- if (t == QMetaType::QVariant)
+ if (t == QMetaType::fromType<QVariant>())
argv[0] = &v;
else
argv[0] = v.data();
@@ -3588,6 +3506,21 @@ bool QMetaProperty::isRequired() const
}
/*!
+ \since 6.0
+ Returns \c true if the property is implemented using a QProperty member; otherwise returns \c false.
+
+ This can be used to detect the availability of QProperty related meta-call types ahead of
+ performing the call itself.
+*/
+bool QMetaProperty::isQProperty() const
+{
+ if (!mobj)
+ return false;
+ int flags = mobj->d.data[handle + 2];
+ return flags & IsQProperty;
+}
+
+/*!
\obsolete
Returns \c true if the property is editable for the given \a object;
@@ -3672,6 +3605,21 @@ const char* QMetaClassInfo::value() const
}
/*!
+ \class QMethodRawArguments
+ \internal
+
+ A wrapper class for the void ** arguments array used by the meta
+ object system. If a slot uses a single argument of this type,
+ the meta object system will pass the raw arguments array directly
+ to the slot and set the arguments count in the slot description to
+ zero, so that any signal can connect to it.
+
+ This is used internally to implement signal relay functionality in
+ our state machine and dbus.
+*/
+
+
+/*!
\macro QGenericArgument Q_ARG(Type, const Type &value)
\relates QMetaObject