From fa987d44417528856d5e80ed7b48ba99e19fa307 Mon Sep 17 00:00:00 2001 From: Fabian Kosmale Date: Thu, 19 Mar 2020 10:47:29 +0100 Subject: MetaObject: Store the QMetaType of the methods This does the analog of 46f407126ef3e94d59254012cdc34d6a4ad2faf2 for the methods we care about (signals, slots, Q_INVOKABLEs). In addition to the actual QMetaType, we store an array with offsets so that we later can do a mapping from methodIndex to metatype. The newly added QMetaMethod::{return,parameter}MetaType methods can then be used to retrieve the metatypes. This does however require that all involved types are complete. This is unfortunately not a feasible requirement. Thus, we only populate the metatype array on a best effort basis. For any incomplete type, we store QMetaType::Unknown. Then, when accessing the metatype, we fall back to the old string based code base if it's Unknown. Squashes "moc: support incomplete types" and "Fix compile failures after QMetaMethod change" Fixes: QTBUG-82932 Change-Id: I6b7a587cc364b7cad0c158d6de54e8a204289ad4 Reviewed-by: Lars Knoll --- src/dbus/qdbusconnection.cpp | 19 ------------------- src/dbus/qdbusconnection.h | 2 ++ src/dbus/qdbusconnection_p.h | 1 + src/dbus/qdbusconnectionmanager_p.h | 20 ++++++++++++++++++++ src/dbus/qdbuserror.h | 5 ++++- src/dbus/qdbusmessage.h | 2 ++ src/dbus/qdbusmetaobject.cpp | 26 ++++++++++++++++++-------- 7 files changed, 47 insertions(+), 28 deletions(-) (limited to 'src/dbus') diff --git a/src/dbus/qdbusconnection.cpp b/src/dbus/qdbusconnection.cpp index 412b428bdc..409be08ff0 100644 --- a/src/dbus/qdbusconnection.cpp +++ b/src/dbus/qdbusconnection.cpp @@ -76,25 +76,6 @@ static void preventDllUnload(); Q_GLOBAL_STATIC(QDBusConnectionManager, _q_manager) -struct QDBusConnectionManager::ConnectionRequestData -{ - enum RequestType { - ConnectToStandardBus, - ConnectToBusByAddress, - ConnectToPeerByAddress - } type; - - union { - QDBusConnection::BusType busType; - const QString *busAddress; - }; - const QString *name; - - QDBusConnectionPrivate *result; - - bool suspendedDelivery; -}; - QDBusConnectionPrivate *QDBusConnectionManager::busConnection(QDBusConnection::BusType type) { Q_STATIC_ASSERT(int(QDBusConnection::SessionBus) + int(QDBusConnection::SystemBus) == 1); diff --git a/src/dbus/qdbusconnection.h b/src/dbus/qdbusconnection.h index 1361fc5035..7304f2a8a2 100644 --- a/src/dbus/qdbusconnection.h +++ b/src/dbus/qdbusconnection.h @@ -77,6 +77,8 @@ class QDBusConnectionPrivate; class Q_DBUS_EXPORT QDBusConnection { Q_GADGET + Q_MOC_INCLUDE() + public: enum BusType { SessionBus, SystemBus, ActivationBus }; Q_ENUM(BusType) diff --git a/src/dbus/qdbusconnection_p.h b/src/dbus/qdbusconnection_p.h index 9bedbcc3a5..ce83270ac2 100644 --- a/src/dbus/qdbusconnection_p.h +++ b/src/dbus/qdbusconnection_p.h @@ -70,6 +70,7 @@ #include #include // for the WatchMode enum +Q_MOC_INCLUDE() #ifndef QT_NO_DBUS diff --git a/src/dbus/qdbusconnectionmanager_p.h b/src/dbus/qdbusconnectionmanager_p.h index ac49683cee..e080abca5e 100644 --- a/src/dbus/qdbusconnectionmanager_p.h +++ b/src/dbus/qdbusconnectionmanager_p.h @@ -100,6 +100,26 @@ private: QString senderName; // internal; will probably change }; +// TODO: move into own header and use Q_MOC_INCLUDE +struct QDBusConnectionManager::ConnectionRequestData +{ + enum RequestType { + ConnectToStandardBus, + ConnectToBusByAddress, + ConnectToPeerByAddress + } type; + + union { + QDBusConnection::BusType busType; + const QString *busAddress; + }; + const QString *name; + + QDBusConnectionPrivate *result; + + bool suspendedDelivery; +}; + QT_END_NAMESPACE #endif // QT_NO_DBUS diff --git a/src/dbus/qdbuserror.h b/src/dbus/qdbuserror.h index 50538b395b..8964f20415 100644 --- a/src/dbus/qdbuserror.h +++ b/src/dbus/qdbuserror.h @@ -141,6 +141,9 @@ Q_DBUS_EXPORT QDebug operator<<(QDebug, const QDBusError &); QT_END_NAMESPACE Q_DECLARE_METATYPE(QDBusError) - +#else +QT_BEGIN_NAMESPACE +class Q_DBUS_EXPORT QDBusError {}; // dummy class for moc +QT_END_NAMESPACE #endif // QT_NO_DBUS #endif diff --git a/src/dbus/qdbusmessage.h b/src/dbus/qdbusmessage.h index 33a706abd2..cd8f74d8bc 100644 --- a/src/dbus/qdbusmessage.h +++ b/src/dbus/qdbusmessage.h @@ -139,6 +139,8 @@ QT_END_NAMESPACE Q_DECLARE_METATYPE(QDBusMessage) +#else +class Q_DBUS_EXPORT QDBusMessage {}; // dummy class for moc #endif // QT_NO_DBUS #endif diff --git a/src/dbus/qdbusmetaobject.cpp b/src/dbus/qdbusmetaobject.cpp index 01eb1aee3f..265d0eacfa 100644 --- a/src/dbus/qdbusmetaobject.cpp +++ b/src/dbus/qdbusmetaobject.cpp @@ -416,7 +416,7 @@ void QDBusMetaObjectGenerator::write(QDBusMetaObject *obj) - methods.count(); // ditto QDBusMetaObjectPrivate *header = reinterpret_cast(idata.data()); - Q_STATIC_ASSERT_X(QMetaObjectPrivate::OutputRevision == 8, "QtDBus meta-object generator should generate the same version as moc"); + Q_STATIC_ASSERT_X(QMetaObjectPrivate::OutputRevision == 9, "QtDBus meta-object generator should generate the same version as moc"); header->revision = QMetaObjectPrivate::OutputRevision; header->className = 0; header->classInfoCount = 0; @@ -424,7 +424,7 @@ void QDBusMetaObjectGenerator::write(QDBusMetaObject *obj) header->methodCount = signals_.count() + methods.count(); header->methodData = idata.size(); header->propertyCount = properties.count(); - header->propertyData = header->methodData + header->methodCount * 5 + methodParametersDataSize; + header->propertyData = header->methodData + header->methodCount * QMetaObjectPrivate::IntsPerMethod + methodParametersDataSize; header->enumeratorCount = 0; header->enumeratorData = 0; header->constructorCount = 0; @@ -436,7 +436,7 @@ void QDBusMetaObjectGenerator::write(QDBusMetaObject *obj) header->methodDBusData = header->propertyDBusData + header->propertyCount * intsPerProperty; int data_size = idata.size() + - (header->methodCount * (5+intsPerMethod)) + methodParametersDataSize + + (header->methodCount * (QMetaObjectPrivate::IntsPerMethod+intsPerMethod)) + methodParametersDataSize + (header->propertyCount * (3+intsPerProperty)); for (const Method &mm : qAsConst(signals_)) data_size += 2 + mm.inputTypes.count() + mm.outputTypes.count(); @@ -447,12 +447,23 @@ void QDBusMetaObjectGenerator::write(QDBusMetaObject *obj) QMetaStringTable strings(className.toLatin1()); int offset = header->methodData; - int parametersOffset = offset + header->methodCount * 5; + int parametersOffset = offset + header->methodCount * QMetaObjectPrivate::IntsPerMethod; int signatureOffset = header->methodDBusData; int typeidOffset = header->methodDBusData + header->methodCount * intsPerMethod; idata[typeidOffset++] = 0; // eod + int totalMetaTypeCount = properties.count(); + for (const auto& methodContainer: {signals_, methods}) { + for (const auto& method: methodContainer) { + int argc = method.inputTypes.size() + qMax(qsizetype(0), method.outputTypes.size() - 1); + totalMetaTypeCount += argc + 1; + } + } + QMetaType *metaTypes = new QMetaType[totalMetaTypeCount]; + int propertyId = 0; + // add each method: + int currentMethodMetaTypeOffset = properties.count(); for (int x = 0; x < 2; ++x) { // Signals must be added before other methods, to match moc. QMap &map = (x == 0) ? signals_ : methods; @@ -467,6 +478,7 @@ void QDBusMetaObjectGenerator::write(QDBusMetaObject *obj) idata[offset++] = parametersOffset; idata[offset++] = strings.enter(mm.tag); idata[offset++] = mm.flags; + idata[offset++] = currentMethodMetaTypeOffset; // Parameter types for (int i = -1; i < argc; ++i) { @@ -496,6 +508,7 @@ void QDBusMetaObjectGenerator::write(QDBusMetaObject *obj) typeInfo = IsUnresolvedType | strings.enter(typeName); else typeInfo = type; + metaTypes[currentMethodMetaTypeOffset++] = QMetaType (type); idata[parametersOffset++] = typeInfo; } // Parameter names @@ -514,16 +527,13 @@ void QDBusMetaObjectGenerator::write(QDBusMetaObject *obj) } } - Q_ASSERT(offset == header->methodData + header->methodCount * 5); + Q_ASSERT(offset == header->methodData + header->methodCount * QMetaObjectPrivate::IntsPerMethod); Q_ASSERT(parametersOffset == header->propertyData); Q_ASSERT(signatureOffset == header->methodDBusData + header->methodCount * intsPerMethod); Q_ASSERT(typeidOffset == idata.size()); offset += methodParametersDataSize; Q_ASSERT(offset == header->propertyData); - QMetaType *metaTypes = new QMetaType[properties.count()]; - int propertyId = 0; - // add each property signatureOffset = header->propertyDBusData; for (QMap::ConstIterator it = properties.constBegin(); -- cgit v1.2.3