summaryrefslogtreecommitdiffstats
path: root/src
diff options
context:
space:
mode:
authorFabian Kosmale <fabian.kosmale@qt.io>2020-03-19 10:47:29 +0100
committerFabian Kosmale <fabian.kosmale@qt.io>2020-06-02 22:42:15 +0200
commitfa987d44417528856d5e80ed7b48ba99e19fa307 (patch)
tree50cd74c1a9dd3c2197f7de2ac0d431a5b16b0a42 /src
parent5306fdabc1ceb09875f791526553b3665017f7ce (diff)
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 <lars.knoll@qt.io>
Diffstat (limited to 'src')
-rw-r--r--src/corelib/kernel/qmetaobject.cpp80
-rw-r--r--src/corelib/kernel/qmetaobject.h2
-rw-r--r--src/corelib/kernel/qmetaobject_p.h4
-rw-r--r--src/corelib/kernel/qmetaobjectbuilder.cpp43
-rw-r--r--src/corelib/kernel/qmetatype.h34
-rw-r--r--src/corelib/kernel/qobject.cpp4
-rw-r--r--src/dbus/qdbusconnection.cpp19
-rw-r--r--src/dbus/qdbusconnection.h2
-rw-r--r--src/dbus/qdbusconnection_p.h1
-rw-r--r--src/dbus/qdbusconnectionmanager_p.h20
-rw-r--r--src/dbus/qdbuserror.h5
-rw-r--r--src/dbus/qdbusmessage.h2
-rw-r--r--src/dbus/qdbusmetaobject.cpp26
-rw-r--r--src/gui/kernel/qoffscreensurface.h1
-rw-r--r--src/gui/kernel/qplatformdialoghelper.h2
-rw-r--r--src/gui/kernel/qplatformnativeinterface.h1
-rw-r--r--src/gui/kernel/qplatformsystemtrayicon.h1
-rw-r--r--src/gui/text/qtextdocument.h1
-rw-r--r--src/network/access/qhttpnetworkreply_p.h5
-rw-r--r--src/network/access/qnetworkaccessbackend_p.h3
-rw-r--r--src/network/access/qnetworkaccessmanager.cpp6
-rw-r--r--src/network/access/qnetworkaccessmanager.h3
-rw-r--r--src/network/access/qnetworkreplyhttpimpl_p.h2
-rw-r--r--src/network/socket/qabstractsocket.h2
-rw-r--r--src/network/socket/qabstractsocketengine_p.h1
-rw-r--r--src/network/ssl/qdtls.h2
-rw-r--r--src/network/ssl/qsslerror.h3
-rw-r--r--src/network/ssl/qsslsocket.h1
-rw-r--r--src/platformsupport/linuxaccessibility/application_p.h1
-rw-r--r--src/platformsupport/linuxaccessibility/dbusconnection_p.h1
-rw-r--r--src/platformsupport/themes/genericunix/dbusmenu/qdbusmenuconnection_p.h1
-rw-r--r--src/plugins/generic/tuiotouch/qtuiohandler_p.h1
-rw-r--r--src/plugins/platforminputcontexts/compose/qcomposeplatforminputcontext.h1
-rw-r--r--src/plugins/platforms/cocoa/qcocoaintegration.mm4
-rw-r--r--src/plugins/platforms/cocoa/qcocoanativeinterface.h3
-rw-r--r--src/sql/models/qsqltablemodel.h1
-rw-r--r--src/tools/moc/generator.cpp67
-rw-r--r--src/tools/moc/generator.h5
-rw-r--r--src/tools/moc/main.cpp6
-rw-r--r--src/tools/moc/moc.cpp2
-rw-r--r--src/tools/moc/moc.h3
41 files changed, 280 insertions, 92 deletions
diff --git a/src/corelib/kernel/qmetaobject.cpp b/src/corelib/kernel/qmetaobject.cpp
index f68a042db0..a234b46d70 100644
--- a/src/corelib/kernel/qmetaobject.cpp
+++ b/src/corelib/kernel/qmetaobject.cpp
@@ -618,7 +618,7 @@ static inline int indexOfMethodRelative(const QMetaObject **baseObject,
? (priv(m->d.data)->signalCount) : 0;
for (; i >= end; --i) {
- int handle = priv(m->d.data)->methodData + 5*i;
+ int handle = priv(m->d.data)->methodData + QMetaObjectPrivate::IntsPerMethod*i;
if (methodMatch(m, handle, name, argc, types)) {
*baseObject = m;
return i;
@@ -819,7 +819,7 @@ int QMetaObjectPrivate::indexOfConstructor(const QMetaObject *m, const QByteArra
int argc, const QArgumentType *types)
{
for (int i = priv(m->d.data)->constructorCount-1; i >= 0; --i) {
- int handle = priv(m->d.data)->constructorData + 5*i;
+ int handle = priv(m->d.data)->constructorData + QMetaObjectPrivate::IntsPerMethod*i;
if (methodMatch(m, handle, name, argc, types))
return i;
}
@@ -895,7 +895,7 @@ QMetaMethod QMetaObjectPrivate::signal(const QMetaObject *m, int signal_index)
if (i >= 0 && i < priv(m->d.data)->signalCount) {
result.mobj = m;
- result.handle = priv(m->d.data)->methodData + 5*i;
+ result.handle = priv(m->d.data)->methodData + QMetaObjectPrivate::IntsPerMethod*i;
}
return result;
}
@@ -1078,7 +1078,7 @@ QMetaMethod QMetaObject::constructor(int index) const
Q_ASSERT(priv(d.data)->revision >= 2);
if (i >= 0 && i < priv(d.data)->constructorCount) {
result.mobj = this;
- result.handle = priv(d.data)->constructorData + 5*i;
+ result.handle = priv(d.data)->constructorData + QMetaObjectPrivate::IntsPerMethod*i;
}
return result;
}
@@ -1098,7 +1098,7 @@ QMetaMethod QMetaObject::method(int index) const
QMetaMethod result;
if (i >= 0 && i < priv(d.data)->methodCount) {
result.mobj = this;
- result.handle = priv(d.data)->methodData + 5*i;
+ result.handle = priv(d.data)->methodData + QMetaObjectPrivate::IntsPerMethod*i;
}
return result;
}
@@ -1844,7 +1844,7 @@ QByteArray QMetaMethodPrivate::tag() const
int QMetaMethodPrivate::ownMethodIndex() const
{
// recompute the methodIndex by reversing the arithmetic in QMetaObject::property()
- return (handle - priv(mobj->d.data)->methodData) / 5;
+ return (handle - priv(mobj->d.data)->methodData) / QMetaObjectPrivate::IntsPerMethod;
}
/*!
@@ -1884,13 +1884,30 @@ QByteArray QMetaMethod::name() const
The return value is one of the types that are registered
with QMetaType, or QMetaType::UnknownType if the type is not registered.
- \sa parameterType(), QMetaType, typeName()
+ \sa parameterType(), QMetaType, typeName(), returnMetaType()
*/
int QMetaMethod::returnType() const
{
if (!mobj)
return QMetaType::UnknownType;
- return QMetaMethodPrivate::get(this)->returnType();
+ return QMetaMethodPrivate::get(this)->returnType();
+}
+
+/*!
+ \since 6.0
+
+ Returns the return type of this method.
+ \sa parameterMetaType(), QMetaType, typeName()
+*/
+QMetaType QMetaMethod::returnMetaType() const
+{
+ if (!mobj || methodType() == QMetaMethod::Constructor)
+ return QMetaType{};
+ auto mt = QMetaType(mobj->d.metaTypes[mobj->d.data[handle + 5]]);
+ if (mt.id() == QMetaType::UnknownType)
+ return QMetaType(QMetaMethodPrivate::get(this)->returnType());
+ else
+ return mt;
}
/*!
@@ -1915,24 +1932,37 @@ int QMetaMethod::parameterCount() const
The return value is one of the types that are registered
with QMetaType, or QMetaType::UnknownType if the type is not registered.
- \sa parameterCount(), returnType(), QMetaType
+ \sa parameterCount(), parameterMetaType(), returnType(), QMetaType
*/
int QMetaMethod::parameterType(int index) const
{
- if (!mobj || index < 0)
- return QMetaType::UnknownType;
- if (index >= QMetaMethodPrivate::get(this)->parameterCount())
- return QMetaType::UnknownType;
+ return parameterMetaType(index).id();
+}
+
+/*!
+ \since 6.0
+
+ Returns the metatype of the parameter at the given \a index.
- int type = QMetaMethodPrivate::get(this)->parameterType(index);
- if (type != QMetaType::UnknownType)
- return type;
+ If the \a index is smaller than zero or larger than
+ parameterCount(), an invalid QMetaType is returned.
- void *argv[] = { &type, &index };
- mobj->static_metacall(QMetaObject::RegisterMethodArgumentMetaType, QMetaMethodPrivate::get(this)->ownMethodIndex(), argv);
- if (type != -1)
- return type;
- return QMetaType::UnknownType;
+ \sa parameterCount(), returnMetaType(), QMetaType
+*/
+QMetaType QMetaMethod::parameterMetaType(int index) const
+{
+ if (!mobj || index < 0)
+ return {};
+ auto priv = QMetaMethodPrivate::get(this);
+ if (index >= priv->parameterCount())
+ return {};
+ // + 1 if there exists a return type
+ auto parameterOffset = index + (methodType() == QMetaMethod::Constructor ? 0 : 1);
+ auto mt = QMetaType(mobj->d.metaTypes[mobj->d.data[handle + 5] + parameterOffset]);
+ if (mt.id() == QMetaType::UnknownType)
+ return QMetaType(QMetaMethodPrivate::get(this)->parameterType(index));
+ else
+ return mt;
}
/*!
@@ -2055,7 +2085,7 @@ int QMetaMethod::revision() const
return 0;
if ((QMetaMethod::Access)(mobj->d.data[handle + 4] & MethodRevisioned)) {
int offset = priv(mobj->d.data)->methodData
- + priv(mobj->d.data)->methodCount * 5
+ + priv(mobj->d.data)->methodCount * QMetaObjectPrivate::IntsPerMethod
+ QMetaMethodPrivate::get(this)->ownMethodIndex();
return mobj->d.data[offset];
}
@@ -2120,7 +2150,7 @@ QMetaMethod QMetaMethod::fromSignalImpl(const QMetaObject *metaObject, void **si
m->static_metacall(QMetaObject::IndexOfMethod, 0, args);
if (i >= 0) {
result.mobj = m;
- result.handle = priv(m->d.data)->methodData + 5*i;
+ result.handle = priv(m->d.data)->methodData + QMetaObjectPrivate::IntsPerMethod*i;
break;
}
}
@@ -3712,10 +3742,10 @@ const char* QMetaClassInfo::value() const
int QMetaObjectPrivate::originalClone(const QMetaObject *mobj, int local_method_index)
{
Q_ASSERT(local_method_index < get(mobj)->methodCount);
- int handle = get(mobj)->methodData + 5 * local_method_index;
+ int handle = get(mobj)->methodData + QMetaObjectPrivate::IntsPerMethod * local_method_index;
while (mobj->d.data[handle + 4] & MethodCloned) {
Q_ASSERT(local_method_index > 0);
- handle -= 5;
+ handle -= QMetaObjectPrivate::IntsPerMethod;
local_method_index--;
}
return local_method_index;
diff --git a/src/corelib/kernel/qmetaobject.h b/src/corelib/kernel/qmetaobject.h
index b0d6cb7446..67f5efe6f6 100644
--- a/src/corelib/kernel/qmetaobject.h
+++ b/src/corelib/kernel/qmetaobject.h
@@ -57,8 +57,10 @@ public:
QByteArray name() const;
const char *typeName() const;
int returnType() const;
+ QMetaType returnMetaType() const;
int parameterCount() const;
int parameterType(int index) const;
+ QMetaType parameterMetaType(int index) const;
void getParameterTypes(int *types) const;
QList<QByteArray> parameterTypes() const;
QList<QByteArray> parameterNames() const;
diff --git a/src/corelib/kernel/qmetaobject_p.h b/src/corelib/kernel/qmetaobject_p.h
index 49c43e3d79..b825c983f9 100644
--- a/src/corelib/kernel/qmetaobject_p.h
+++ b/src/corelib/kernel/qmetaobject_p.h
@@ -176,7 +176,9 @@ struct QMetaObjectPrivate
{
// revision 7 is Qt 5.0 everything lower is not supported
// revision 8 is Qt 5.12: It adds the enum name to QMetaEnum
- enum { OutputRevision = 8 }; // Used by moc, qmetaobjectbuilder and qdbus
+ // revision 9 is Qt 6.0: It adds the metatype of properties and methods
+ enum { OutputRevision = 9 }; // Used by moc, qmetaobjectbuilder and qdbus
+ enum { IntsPerMethod = 6};
int revision;
int className;
diff --git a/src/corelib/kernel/qmetaobjectbuilder.cpp b/src/corelib/kernel/qmetaobjectbuilder.cpp
index a2dedda0ad..7b9b06ed3e 100644
--- a/src/corelib/kernel/qmetaobjectbuilder.cpp
+++ b/src/corelib/kernel/qmetaobjectbuilder.cpp
@@ -1216,7 +1216,7 @@ static int buildMetaObject(QMetaObjectBuilderPrivate *d, char *buf,
- int(d->methods.size()) // return "parameters" don't have names
- int(d->constructors.size()); // "this" parameters don't have names
if (buf) {
- Q_STATIC_ASSERT_X(QMetaObjectPrivate::OutputRevision == 8, "QMetaObjectBuilder should generate the same version as moc");
+ Q_STATIC_ASSERT_X(QMetaObjectPrivate::OutputRevision == 9, "QMetaObjectBuilder should generate the same version as moc");
pmeta->revision = QMetaObjectPrivate::OutputRevision;
pmeta->flags = d->flags;
pmeta->className = 0; // Class name is always the first string.
@@ -1228,7 +1228,7 @@ static int buildMetaObject(QMetaObjectBuilderPrivate *d, char *buf,
pmeta->methodCount = int(d->methods.size());
pmeta->methodData = dataIndex;
- dataIndex += 5 * int(d->methods.size());
+ dataIndex += QMetaObjectPrivate::IntsPerMethod * int(d->methods.size());
if (hasRevisionedMethods)
dataIndex += int(d->methods.size());
paramsIndex = dataIndex;
@@ -1248,10 +1248,10 @@ static int buildMetaObject(QMetaObjectBuilderPrivate *d, char *buf,
pmeta->constructorCount = int(d->constructors.size());
pmeta->constructorData = dataIndex;
- dataIndex += 5 * int(d->constructors.size());
+ dataIndex += QMetaObjectPrivate::IntsPerMethod * int(d->constructors.size());
} else {
dataIndex += 2 * int(d->classInfoNames.size());
- dataIndex += 5 * int(d->methods.size());
+ dataIndex += QMetaObjectPrivate::IntsPerMethod * int(d->methods.size());
if (hasRevisionedMethods)
dataIndex += int(d->methods.size());
paramsIndex = dataIndex;
@@ -1262,7 +1262,7 @@ static int buildMetaObject(QMetaObjectBuilderPrivate *d, char *buf,
if (hasRevisionedProperties)
dataIndex += int(d->properties.size());
dataIndex += 5 * int(d->enumerators.size());
- dataIndex += 5 * int(d->constructors.size());
+ dataIndex += QMetaObjectPrivate::IntsPerMethod * int(d->constructors.size());
}
// Allocate space for the enumerator key names and values.
@@ -1307,6 +1307,7 @@ static int buildMetaObject(QMetaObjectBuilderPrivate *d, char *buf,
// Output the methods in the class.
Q_ASSERT(!buf || dataIndex == pmeta->methodData);
+ int parameterMetaTypesIndex = d->properties.size();
for (const auto &method : d->methods) {
int name = strings.enter(method.name());
int argc = method.parameterCount();
@@ -1318,11 +1319,13 @@ static int buildMetaObject(QMetaObjectBuilderPrivate *d, char *buf,
data[dataIndex + 2] = paramsIndex;
data[dataIndex + 3] = tag;
data[dataIndex + 4] = attrs;
+ data[dataIndex + 5] = parameterMetaTypesIndex;
if (method.methodType() == QMetaMethod::Signal)
pmeta->signalCount++;
}
- dataIndex += 5;
+ dataIndex += QMetaObjectPrivate::IntsPerMethod;
paramsIndex += 1 + argc * 2;
+ parameterMetaTypesIndex += 1 + argc;
}
if (hasRevisionedMethods) {
for (const auto &method : d->methods) {
@@ -1333,7 +1336,7 @@ static int buildMetaObject(QMetaObjectBuilderPrivate *d, char *buf,
}
// Output the method parameters in the class.
- Q_ASSERT(!buf || dataIndex == pmeta->methodData + int(d->methods.size()) * 5
+ Q_ASSERT(!buf || dataIndex == pmeta->methodData + int(d->methods.size()) * QMetaObjectPrivate::IntsPerMethod
+ (hasRevisionedMethods ? int(d->methods.size()) : 0));
for (int x = 0; x < 2; ++x) {
const std::vector<QMetaMethodBuilderPrivate> &methods = (x == 0) ? d->methods : d->constructors;
@@ -1446,9 +1449,11 @@ static int buildMetaObject(QMetaObjectBuilderPrivate *d, char *buf,
data[dataIndex + 2] = paramsIndex;
data[dataIndex + 3] = tag;
data[dataIndex + 4] = attrs;
+ data[dataIndex + 5] = parameterMetaTypesIndex;
}
- dataIndex += 5;
+ dataIndex += QMetaObjectPrivate::IntsPerMethod;
paramsIndex += 1 + argc * 2;
+ parameterMetaTypesIndex += argc;
}
size += strings.blobSize();
@@ -1474,7 +1479,7 @@ static int buildMetaObject(QMetaObjectBuilderPrivate *d, char *buf,
size += sizeof(SuperData) * (d->relatedMetaObjects.size() + 1);
}
- if (d->properties.size() > 0) {
+ if (d->properties.size() > 0 || d->methods.size() > 0 || d->constructors.size() > 0) {
ALIGN(size, QtPrivate::QMetaTypeInterface *);
auto types = reinterpret_cast<QtPrivate::QMetaTypeInterface **>(buf + size);
if (buf) {
@@ -1484,8 +1489,26 @@ static int buildMetaObject(QMetaObjectBuilderPrivate *d, char *buf,
*types = reinterpret_cast<QtPrivate::QMetaTypeInterface *&>(mt);
types++;
}
+ for (const auto &method: d->methods) {
+ QMetaType mt(QMetaType::type(method.returnType));
+ *types = reinterpret_cast<QtPrivate::QMetaTypeInterface *&>(mt);
+ types++;
+ for (const auto &parameterType: method.parameterTypes()) {
+ QMetaType mt(QMetaType::type(parameterType));
+ *types = reinterpret_cast<QtPrivate::QMetaTypeInterface *&>(mt);
+ types++;
+ }
+ }
+ for (const auto &constructor: d->constructors) {
+ for (const auto &parameterType: constructor.parameterTypes()) {
+ QMetaType mt(QMetaType::type(parameterType));
+ *types = reinterpret_cast<QtPrivate::QMetaTypeInterface *&>(mt);
+ types++;
+ }
+ }
}
- size += static_cast<int>(sizeof(QMetaType) * d->properties.size());
+ // parameterMetaTypesIndex is equal to the total number of metatypes
+ size += static_cast<int>(sizeof(QMetaType) * parameterMetaTypesIndex);
}
// Align the final size and return it.
diff --git a/src/corelib/kernel/qmetatype.h b/src/corelib/kernel/qmetatype.h
index 05fe4450df..60192e4131 100644
--- a/src/corelib/kernel/qmetatype.h
+++ b/src/corelib/kernel/qmetatype.h
@@ -2796,6 +2796,35 @@ constexpr QMetaTypeInterface *qMetaTypeInterfaceForType()
}
}
+namespace detail {
+
+template <typename T, typename ODR_VIOLATION_PREVENTER>
+struct is_complete_helper {
+ template <typename U>
+ static auto check(U*) -> std::integral_constant<bool, sizeof(U) != 0>;
+ static auto check(...) -> std::false_type;
+ using type = decltype(check(static_cast<T*>(nullptr)));
+};
+
+}
+
+template <typename T, typename ODR_VIOLATION_PREVENTER>
+struct is_complete : detail::is_complete_helper<T, ODR_VIOLATION_PREVENTER>::type {};
+
+template<typename Unique, typename T>
+constexpr QMetaTypeInterface *qTryMetaTypeInterfaceForType()
+{
+ using Ty = std::remove_cv_t<std::remove_reference_t<T>>;
+ using Tz = std::remove_pointer_t<Ty>;
+ if constexpr (!is_complete<Tz, Unique>::value) {
+ return nullptr;
+ } else if constexpr (std::is_same_v<Ty, void>) {
+ return nullptr;
+ } else {
+ return &QMetaTypeForType<Ty>::metaType;
+ }
+}
+
} // namespace QtPrivate
template<typename T>
@@ -2809,6 +2838,11 @@ QtPrivate::QMetaTypeInterface *const qt_metaTypeArray[] = {
QtPrivate::qMetaTypeInterfaceForType<T>()...
};
+template<typename Unique,typename... T>
+QtPrivate::QMetaTypeInterface *const qt_incomplete_metaTypeArray[] = {
+ QtPrivate::qTryMetaTypeInterfaceForType<Unique, T>()...
+};
+
QT_END_NAMESPACE
#endif // QMETATYPE_H
diff --git a/src/corelib/kernel/qobject.cpp b/src/corelib/kernel/qobject.cpp
index ad810c8b26..11ec534434 100644
--- a/src/corelib/kernel/qobject.cpp
+++ b/src/corelib/kernel/qobject.cpp
@@ -2562,7 +2562,7 @@ bool QObject::isSignalConnected(const QMetaMethod &signal) const
Q_ASSERT_X(signal.mobj->cast(this) && signal.methodType() == QMetaMethod::Signal,
"QObject::isSignalConnected" , "the parameter must be a signal member of the object");
- uint signalIndex = (signal.handle - QMetaObjectPrivate::get(signal.mobj)->methodData)/5;
+ uint signalIndex = (signal.handle - QMetaObjectPrivate::get(signal.mobj)->methodData)/QMetaObjectPrivate::IntsPerMethod;
if (signal.mobj->d.data[signal.handle + 4] & MethodCloned)
signalIndex = QMetaObjectPrivate::originalClone(signal.mobj, signalIndex);
@@ -2610,7 +2610,7 @@ void QMetaObjectPrivate::memberIndexes(const QObject *obj,
m = m->d.superdata;
if (!m)
return;
- *signalIndex = *methodIndex = (member.handle - get(member.mobj)->methodData)/5;
+ *signalIndex = *methodIndex = (member.handle - get(member.mobj)->methodData)/QMetaObjectPrivate::IntsPerMethod;
int signalOffset;
int methodOffset;
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(<QtDBus/qdbuspendingcall.h>)
+
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 <qdbusmessage.h>
#include <qdbusservicewatcher.h> // for the WatchMode enum
+Q_MOC_INCLUDE(<QtDBus/private/qdbuspendingcall_p.h>)
#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<QDBusMetaObjectPrivate *>(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<QByteArray, Method> &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<QByteArray, Property>::ConstIterator it = properties.constBegin();
diff --git a/src/gui/kernel/qoffscreensurface.h b/src/gui/kernel/qoffscreensurface.h
index 1b9e7c00ca..cfdcd758ec 100644
--- a/src/gui/kernel/qoffscreensurface.h
+++ b/src/gui/kernel/qoffscreensurface.h
@@ -43,6 +43,7 @@
#include <QtGui/qtguiglobal.h>
#include <QtCore/QObject>
#include <QtGui/qsurface.h>
+Q_MOC_INCLUDE(<QScreen>)
QT_BEGIN_NAMESPACE
diff --git a/src/gui/kernel/qplatformdialoghelper.h b/src/gui/kernel/qplatformdialoghelper.h
index ba800a696f..fa58177a2d 100644
--- a/src/gui/kernel/qplatformdialoghelper.h
+++ b/src/gui/kernel/qplatformdialoghelper.h
@@ -58,6 +58,8 @@
#include <QtCore/QDir>
#include <QtCore/QUrl>
#include <QtGui/QRgb>
+Q_MOC_INCLUDE(<QFont>)
+Q_MOC_INCLUDE(<QColor>)
QT_BEGIN_NAMESPACE
diff --git a/src/gui/kernel/qplatformnativeinterface.h b/src/gui/kernel/qplatformnativeinterface.h
index 95d6a03dbb..58c8f6b414 100644
--- a/src/gui/kernel/qplatformnativeinterface.h
+++ b/src/gui/kernel/qplatformnativeinterface.h
@@ -66,6 +66,7 @@ class QBackingStore;
class Q_GUI_EXPORT QPlatformNativeInterface : public QObject
{
Q_OBJECT
+ Q_MOC_INCLUDE(<qpa/qplatformwindow.h>)
public:
virtual void *nativeResourceForIntegration(const QByteArray &resource);
virtual void *nativeResourceForContext(const QByteArray &resource, QOpenGLContext *context);
diff --git a/src/gui/kernel/qplatformsystemtrayicon.h b/src/gui/kernel/qplatformsystemtrayicon.h
index 948a6c099d..bd74a2cc0a 100644
--- a/src/gui/kernel/qplatformsystemtrayicon.h
+++ b/src/gui/kernel/qplatformsystemtrayicon.h
@@ -57,6 +57,7 @@ class QRect;
class Q_GUI_EXPORT QPlatformSystemTrayIcon : public QObject
{
Q_OBJECT
+ Q_MOC_INCLUDE(<qpa/qplatformscreen.h>)
public:
enum ActivationReason {
Unknown,
diff --git a/src/gui/text/qtextdocument.h b/src/gui/text/qtextdocument.h
index b34175994d..175a34313c 100644
--- a/src/gui/text/qtextdocument.h
+++ b/src/gui/text/qtextdocument.h
@@ -47,6 +47,7 @@
#include <QtCore/qvariant.h>
#include <QtGui/qfont.h>
#include <QtCore/qurl.h>
+Q_MOC_INCLUDE(<QtGui/qtextcursor.h>)
QT_BEGIN_NAMESPACE
diff --git a/src/network/access/qhttpnetworkreply_p.h b/src/network/access/qhttpnetworkreply_p.h
index 59010606b9..f8b45a8adc 100644
--- a/src/network/access/qhttpnetworkreply_p.h
+++ b/src/network/access/qhttpnetworkreply_p.h
@@ -75,6 +75,11 @@ struct z_stream_s;
#include <private/qringbuffer_p.h>
#include <private/qbytedata_p.h>
+#ifndef QT_NO_NETWORKPROXY
+Q_MOC_INCLUDE(<QtNetwork/QNetworkProxy>)
+#endif
+Q_MOC_INCLUDE(<QtNetwork/QAuthenticator>)
+
QT_REQUIRE_CONFIG(http);
QT_BEGIN_NAMESPACE
diff --git a/src/network/access/qnetworkaccessbackend_p.h b/src/network/access/qnetworkaccessbackend_p.h
index 4b5422ce29..b18f30c287 100644
--- a/src/network/access/qnetworkaccessbackend_p.h
+++ b/src/network/access/qnetworkaccessbackend_p.h
@@ -54,10 +54,11 @@
#include <QtNetwork/private/qtnetworkglobal_p.h>
#include "qnetworkreplyimpl_p.h"
#include "QtCore/qobject.h"
+Q_MOC_INCLUDE(<QAuthenticator>)
+Q_MOC_INCLUDE(<QtNetwork/QSslError>)
QT_BEGIN_NAMESPACE
-class QAuthenticator;
class QNetworkProxy;
class QNetworkProxyQuery;
class QNetworkRequest;
diff --git a/src/network/access/qnetworkaccessmanager.cpp b/src/network/access/qnetworkaccessmanager.cpp
index 1c5e29f8ac..351eca43df 100644
--- a/src/network/access/qnetworkaccessmanager.cpp
+++ b/src/network/access/qnetworkaccessmanager.cpp
@@ -1532,17 +1532,15 @@ void QNetworkAccessManagerPrivate::_q_replySslErrors(const QList<QSslError> &err
#endif
}
+#ifndef QT_NO_SSL
void QNetworkAccessManagerPrivate::_q_replyPreSharedKeyAuthenticationRequired(QSslPreSharedKeyAuthenticator *authenticator)
{
-#ifndef QT_NO_SSL
Q_Q(QNetworkAccessManager);
QNetworkReply *reply = qobject_cast<QNetworkReply *>(q->sender());
if (reply)
emit q->preSharedKeyAuthenticationRequired(reply, authenticator);
-#else
- Q_UNUSED(authenticator);
-#endif
}
+#endif
QNetworkReply *QNetworkAccessManagerPrivate::postProcess(QNetworkReply *reply)
{
diff --git a/src/network/access/qnetworkaccessmanager.h b/src/network/access/qnetworkaccessmanager.h
index 3a08c30a21..cbc9a0b660 100644
--- a/src/network/access/qnetworkaccessmanager.h
+++ b/src/network/access/qnetworkaccessmanager.h
@@ -49,6 +49,7 @@
#include <QtNetwork/QSslConfiguration>
#include <QtNetwork/QSslPreSharedKeyAuthenticator>
#endif
+Q_MOC_INCLUDE(<QtNetwork/QSslError>)
QT_BEGIN_NAMESPACE
@@ -178,7 +179,9 @@ private:
#endif
Q_DECLARE_PRIVATE(QNetworkAccessManager)
Q_PRIVATE_SLOT(d_func(), void _q_replySslErrors(QList<QSslError>))
+#ifndef QT_NO_SSL
Q_PRIVATE_SLOT(d_func(), void _q_replyPreSharedKeyAuthenticationRequired(QSslPreSharedKeyAuthenticator*))
+#endif
Q_PRIVATE_SLOT(d_func(), void _q_onlineStateChanged(bool))
};
diff --git a/src/network/access/qnetworkreplyhttpimpl_p.h b/src/network/access/qnetworkreplyhttpimpl_p.h
index a25adb668c..1dded7096d 100644
--- a/src/network/access/qnetworkreplyhttpimpl_p.h
+++ b/src/network/access/qnetworkreplyhttpimpl_p.h
@@ -71,6 +71,8 @@
#include <QtNetwork/QSslConfiguration>
#endif
+Q_MOC_INCLUDE(<QtNetwork/QAuthenticator>)
+
QT_REQUIRE_CONFIG(http);
QT_BEGIN_NAMESPACE
diff --git a/src/network/socket/qabstractsocket.h b/src/network/socket/qabstractsocket.h
index 46d25d5677..f76467b2a6 100644
--- a/src/network/socket/qabstractsocket.h
+++ b/src/network/socket/qabstractsocket.h
@@ -60,6 +60,8 @@ class QAuthenticator;
class Q_NETWORK_EXPORT QAbstractSocket : public QIODevice
{
Q_OBJECT
+ Q_MOC_INCLUDE(<QtNetwork/qauthenticator.h>)
+
public:
enum SocketType {
TcpSocket,
diff --git a/src/network/socket/qabstractsocketengine_p.h b/src/network/socket/qabstractsocketengine_p.h
index 112e7032d6..3d9ce96cb3 100644
--- a/src/network/socket/qabstractsocketengine_p.h
+++ b/src/network/socket/qabstractsocketengine_p.h
@@ -83,6 +83,7 @@ public:
class Q_AUTOTEST_EXPORT QAbstractSocketEngine : public QObject
{
Q_OBJECT
+ Q_MOC_INCLUDE(<QtNetwork/qauthenticator.h>)
public:
static QAbstractSocketEngine *createSocketEngine(QAbstractSocket::SocketType socketType, const QNetworkProxy &, QObject *parent);
diff --git a/src/network/ssl/qdtls.h b/src/network/ssl/qdtls.h
index d057eadf19..fe1da23409 100644
--- a/src/network/ssl/qdtls.h
+++ b/src/network/ssl/qdtls.h
@@ -48,6 +48,8 @@
#include <QtCore/qcryptographichash.h>
#include <QtCore/qobject.h>
+Q_MOC_INCLUDE(<QtNetwork/QSslPreSharedKeyAuthenticator>)
+
#ifndef Q_CLANG_QDOC
QT_REQUIRE_CONFIG(dtls);
#endif
diff --git a/src/network/ssl/qsslerror.h b/src/network/ssl/qsslerror.h
index 834684cd9d..6c4dabde96 100644
--- a/src/network/ssl/qsslerror.h
+++ b/src/network/ssl/qsslerror.h
@@ -131,7 +131,8 @@ class QDebug;
Q_NETWORK_EXPORT QDebug operator<<(QDebug debug, const QSslError &error);
Q_NETWORK_EXPORT QDebug operator<<(QDebug debug, const QSslError::SslError &error);
#endif
-
+#else
+class Q_NETWORK_EXPORT QSslError {}; // dummy class so that moc has a complete type
#endif // QT_NO_SSL
QT_END_NAMESPACE
diff --git a/src/network/ssl/qsslsocket.h b/src/network/ssl/qsslsocket.h
index 7fd2b1cb08..238928e108 100644
--- a/src/network/ssl/qsslsocket.h
+++ b/src/network/ssl/qsslsocket.h
@@ -109,6 +109,7 @@ class QSslSocketPrivate;
class Q_NETWORK_EXPORT QSslSocket : public QTcpSocket
{
Q_OBJECT
+ Q_MOC_INCLUDE(<QtNetwork/qsslpresharedkeyauthenticator.h>)
public:
enum SslMode {
UnencryptedMode,
diff --git a/src/platformsupport/linuxaccessibility/application_p.h b/src/platformsupport/linuxaccessibility/application_p.h
index e980232bbf..6a8786dc07 100644
--- a/src/platformsupport/linuxaccessibility/application_p.h
+++ b/src/platformsupport/linuxaccessibility/application_p.h
@@ -56,6 +56,7 @@
#include <QtCore/QQueue>
#include <QtDBus/QDBusConnection>
#include <QtGui/QAccessibleInterface>
+Q_MOC_INCLUDE(<QtDBus/QDBusMessage>)
QT_REQUIRE_CONFIG(accessibility);
diff --git a/src/platformsupport/linuxaccessibility/dbusconnection_p.h b/src/platformsupport/linuxaccessibility/dbusconnection_p.h
index 860c18ca05..dde3bbb98f 100644
--- a/src/platformsupport/linuxaccessibility/dbusconnection_p.h
+++ b/src/platformsupport/linuxaccessibility/dbusconnection_p.h
@@ -55,6 +55,7 @@
#include <QtCore/QString>
#include <QtDBus/QDBusConnection>
#include <QtDBus/QDBusVariant>
+Q_MOC_INCLUDE(<QtDBus/QDBusError>)
QT_BEGIN_NAMESPACE
diff --git a/src/platformsupport/themes/genericunix/dbusmenu/qdbusmenuconnection_p.h b/src/platformsupport/themes/genericunix/dbusmenu/qdbusmenuconnection_p.h
index f484795fbb..bbdaad1e89 100644
--- a/src/platformsupport/themes/genericunix/dbusmenu/qdbusmenuconnection_p.h
+++ b/src/platformsupport/themes/genericunix/dbusmenu/qdbusmenuconnection_p.h
@@ -56,6 +56,7 @@
#include <QtDBus/QDBusVariant>
#include <QtGui/qtgui-config.h>
+Q_MOC_INCLUDE(<QtDBus/QDBusError>)
QT_BEGIN_NAMESPACE
diff --git a/src/plugins/generic/tuiotouch/qtuiohandler_p.h b/src/plugins/generic/tuiotouch/qtuiohandler_p.h
index 2e444f2a0d..eb68baa915 100644
--- a/src/plugins/generic/tuiotouch/qtuiohandler_p.h
+++ b/src/plugins/generic/tuiotouch/qtuiohandler_p.h
@@ -59,6 +59,7 @@ class QTuioToken;
class QTuioHandler : public QObject
{
Q_OBJECT
+ Q_MOC_INCLUDE("qoscmessage_p.h")
public:
explicit QTuioHandler(const QString &specification);
diff --git a/src/plugins/platforminputcontexts/compose/qcomposeplatforminputcontext.h b/src/plugins/platforminputcontexts/compose/qcomposeplatforminputcontext.h
index b1de1b1094..29e862ecc1 100644
--- a/src/plugins/platforminputcontexts/compose/qcomposeplatforminputcontext.h
+++ b/src/plugins/platforminputcontexts/compose/qcomposeplatforminputcontext.h
@@ -45,6 +45,7 @@
#include <xkbcommon/xkbcommon-compose.h>
+Q_DECLARE_OPAQUE_POINTER(xkb_context *)
QT_BEGIN_NAMESPACE
Q_DECLARE_LOGGING_CATEGORY(lcXkbCompose)
diff --git a/src/plugins/platforms/cocoa/qcocoaintegration.mm b/src/plugins/platforms/cocoa/qcocoaintegration.mm
index 6b97eb710b..13a4b0301b 100644
--- a/src/plugins/platforms/cocoa/qcocoaintegration.mm
+++ b/src/plugins/platforms/cocoa/qcocoaintegration.mm
@@ -524,6 +524,6 @@ void QCocoaIntegration::focusWindowChanged(QWindow *focusWindow)
setApplicationIcon(focusWindow->icon());
}
-#include "moc_qcocoaintegration.cpp"
-
QT_END_NAMESPACE
+
+#include "moc_qcocoaintegration.cpp"
diff --git a/src/plugins/platforms/cocoa/qcocoanativeinterface.h b/src/plugins/platforms/cocoa/qcocoanativeinterface.h
index 70d25e345a..c30297c8ca 100644
--- a/src/plugins/platforms/cocoa/qcocoanativeinterface.h
+++ b/src/plugins/platforms/cocoa/qcocoanativeinterface.h
@@ -44,6 +44,9 @@
#include <qpa/qplatformnativeinterface.h>
#include <QtGui/qpixmap.h>
+Q_MOC_INCLUDE(<QWindow>)
+Q_MOC_INCLUDE(<qpa/qplatformprintersupport.h>)
+Q_MOC_INCLUDE(<QPrintEngine>)
QT_BEGIN_NAMESPACE
diff --git a/src/sql/models/qsqltablemodel.h b/src/sql/models/qsqltablemodel.h
index 97692c573e..90cddd7b61 100644
--- a/src/sql/models/qsqltablemodel.h
+++ b/src/sql/models/qsqltablemodel.h
@@ -58,6 +58,7 @@ class Q_SQL_EXPORT QSqlTableModel: public QSqlQueryModel
{
Q_OBJECT
Q_DECLARE_PRIVATE(QSqlTableModel)
+ Q_MOC_INCLUDE(<QtSql/qsqlrecord.h>)
public:
enum EditStrategy {OnFieldChange, OnRowChange, OnManualSubmit};
diff --git a/src/tools/moc/generator.cpp b/src/tools/moc/generator.cpp
index 976d49ad20..849e25b76d 100644
--- a/src/tools/moc/generator.cpp
+++ b/src/tools/moc/generator.cpp
@@ -80,9 +80,9 @@ QT_FOR_EACH_STATIC_TYPE(RETURN_METATYPENAME_STRING)
return nullptr;
}
-Generator::Generator(ClassDef *classDef, const QVector<QByteArray> &metaTypes, const QHash<QByteArray, QByteArray> &knownQObjectClasses, const QHash<QByteArray, QByteArray> &knownGadgets, FILE *outfile)
+Generator::Generator(ClassDef *classDef, const QVector<QByteArray> &metaTypes, const QHash<QByteArray, QByteArray> &knownQObjectClasses, const QHash<QByteArray, QByteArray> &knownGadgets, FILE *outfile, bool requireCompleteTypes)
: out(outfile), cdef(classDef), metaTypes(metaTypes), knownQObjectClasses(knownQObjectClasses)
- , knownGadgets(knownGadgets)
+ , knownGadgets(knownGadgets), requireCompleteTypes(requireCompleteTypes)
{
if (cdef->superclassList.size())
purestSuperClass = cdef->superclassList.constFirst().first;
@@ -350,7 +350,7 @@ void Generator::generateCode()
int methodCount = cdef->signalList.count() + cdef->slotList.count() + cdef->methodList.count();
fprintf(out, " %4d, %4d, // methods\n", methodCount, methodCount ? index : 0);
- index += methodCount * 5;
+ index += methodCount * QMetaObjectPrivate::IntsPerMethod;
if (cdef->revisionedMethods)
index += methodCount;
int paramsIndex = index;
@@ -391,20 +391,22 @@ void Generator::generateCode()
//
generateClassInfos();
+ int initialMetaTypeOffset = cdef->propertyList.count();
+
//
// Build signals array first, otherwise the signal indices would be wrong
//
- generateFunctions(cdef->signalList, "signal", MethodSignal, paramsIndex);
+ generateFunctions(cdef->signalList, "signal", MethodSignal, paramsIndex, initialMetaTypeOffset);
//
// Build slots array
//
- generateFunctions(cdef->slotList, "slot", MethodSlot, paramsIndex);
+ generateFunctions(cdef->slotList, "slot", MethodSlot, paramsIndex, initialMetaTypeOffset);
//
// Build method array
//
- generateFunctions(cdef->methodList, "method", MethodMethod, paramsIndex);
+ generateFunctions(cdef->methodList, "method", MethodMethod, paramsIndex, initialMetaTypeOffset);
//
// Build method version arrays
@@ -438,7 +440,7 @@ void Generator::generateCode()
// Build constructors array
//
if (isConstructible)
- generateFunctions(cdef->constructorList, "constructor", MethodConstructor, paramsIndex);
+ generateFunctions(cdef->constructorList, "constructor", MethodConstructor, paramsIndex, initialMetaTypeOffset);
//
// Terminate data array
@@ -553,14 +555,48 @@ void Generator::generateCode()
else
fprintf(out, " qt_meta_extradata_%s,\n", qualifiedClassNameIdentifier.constData());
- if (cdef->propertyList.isEmpty()) {
+ bool constructorListContainsArgument = false;
+ for (int i = 0; i< cdef->constructorList.count(); ++i) {
+ const FunctionDef& fdef = cdef->constructorList.at(i);
+ if (fdef.arguments.count()) {
+ constructorListContainsArgument = true;
+ break;
+ }
+ }
+ if (cdef->propertyList.isEmpty() && cdef->signalList.isEmpty() && cdef->slotList.isEmpty() && cdef->methodList.isEmpty() && !constructorListContainsArgument) {
fprintf(out, " nullptr,\n");
} else {
- fprintf(out, "qt_metaTypeArray<\n");
+ bool needsComma = false;
+ if (!requireCompleteTypes) {
+ fprintf(out, "qt_incomplete_metaTypeArray<qt_meta_stringdata_%s_t\n", qualifiedClassNameIdentifier.constData());
+ needsComma = true;
+ } else {
+ fprintf(out, "qt_metaTypeArray<\n");
+ }
for (int i = 0; i < cdef->propertyList.count(); ++i) {
const PropertyDef &p = cdef->propertyList.at(i);
- fprintf(out, "%s%s", i == 0 ? "" : ", ", p.type.data());
+ fprintf(out, "%s%s", needsComma ? ", " : "", p.type.data());
+ needsComma = true;
+ }
+ for (const QVector<FunctionDef> &methodContainer: {cdef->signalList, cdef->slotList, cdef->methodList} ) {
+ for (int i = 0; i< methodContainer.count(); ++i) {
+ const FunctionDef& fdef = methodContainer.at(i);
+ fprintf(out, "%s%s", needsComma ? ", " : "", fdef.type.name.data());
+ needsComma = true;
+ for (const auto &argument: fdef.arguments) {
+ fprintf(out, ", %s", argument.type.name.data());
+ }
+ }
+ fprintf(out, "\n");
+ }
+ for (int i = 0; i< cdef->constructorList.count(); ++i) {
+ const FunctionDef& fdef = cdef->constructorList.at(i);
+ for (const auto &argument: fdef.arguments) {
+ fprintf(out, "%s%s", needsComma ? ", " : "", argument.type.name.data());
+ needsComma = true;
+ }
}
+ fprintf(out, "\n");
fprintf(out, ">,\n");
}
@@ -572,6 +608,7 @@ void Generator::generateCode()
fprintf(out, "\nconst QMetaObject *%s::metaObject() const\n{\n return QObject::d_ptr->metaObject ? QObject::d_ptr->dynamicMetaObject() : &staticMetaObject;\n}\n",
cdef->qualified.constData());
+
//
// Generate smart cast function
//
@@ -688,11 +725,11 @@ void Generator::registerByteArrayVector(const QVector<QByteArray> &list)
strreg(ba);
}
-void Generator::generateFunctions(const QVector<FunctionDef>& list, const char *functype, int type, int &paramsIndex)
+void Generator::generateFunctions(const QVector<FunctionDef>& list, const char *functype, int type, int &paramsIndex, int &initialMetatypeOffset)
{
if (list.isEmpty())
return;
- fprintf(out, "\n // %ss: name, argc, parameters, tag, flags\n", functype);
+ fprintf(out, "\n // %ss: name, argc, parameters, tag, flags, initial metatype offsets\n", functype);
for (int i = 0; i < list.count(); ++i) {
const FunctionDef &f = list.at(i);
@@ -727,10 +764,12 @@ void Generator::generateFunctions(const QVector<FunctionDef>& list, const char *
}
int argc = f.arguments.count();
- fprintf(out, " %4d, %4d, %4d, %4d, 0x%02x /* %s */,\n",
- stridx(f.name), argc, paramsIndex, stridx(f.tag), flags, comment.constData());
+ fprintf(out, " %4d, %4d, %4d, %4d, 0x%02x, %4d /* %s */,\n",
+ stridx(f.name), argc, paramsIndex, stridx(f.tag), flags, initialMetatypeOffset, comment.constData());
paramsIndex += 1 + argc * 2;
+ // constructors don't have a return type
+ initialMetatypeOffset += (f.isConstructor ? 0 : 1) + argc;
}
}
diff --git a/src/tools/moc/generator.h b/src/tools/moc/generator.h
index e92b9d1208..f3d3b40349 100644
--- a/src/tools/moc/generator.h
+++ b/src/tools/moc/generator.h
@@ -39,7 +39,7 @@ class Generator
ClassDef *cdef;
QVector<uint> meta_data;
public:
- Generator(ClassDef *classDef, const QVector<QByteArray> &metaTypes, const QHash<QByteArray, QByteArray> &knownQObjectClasses, const QHash<QByteArray, QByteArray> &knownGadgets, FILE *outfile = nullptr);
+ Generator(ClassDef *classDef, const QVector<QByteArray> &metaTypes, const QHash<QByteArray, QByteArray> &knownQObjectClasses, const QHash<QByteArray, QByteArray> &knownGadgets, FILE *outfile = nullptr, bool requireCompleteTypes = false);
void generateCode();
private:
bool registerableMetaType(const QByteArray &propertyType);
@@ -47,7 +47,7 @@ private:
void generateClassInfos();
void registerFunctionStrings(const QVector<FunctionDef> &list);
void registerByteArrayVector(const QVector<QByteArray> &list);
- void generateFunctions(const QVector<FunctionDef> &list, const char *functype, int type, int &paramsIndex);
+ void generateFunctions(const QVector<FunctionDef> &list, const char *functype, int type, int &paramsIndex, int &initialMetatypeOffset);
void generateFunctionRevisions(const QVector<FunctionDef> &list, const char *functype);
void generateFunctionParameters(const QVector<FunctionDef> &list, const char *functype);
void generateTypeInfo(const QByteArray &typeName, bool allowEmptyName = false);
@@ -70,6 +70,7 @@ private:
QVector<QByteArray> metaTypes;
QHash<QByteArray, QByteArray> knownQObjectClasses;
QHash<QByteArray, QByteArray> knownGadgets;
+ bool requireCompleteTypes;
};
QT_END_NAMESPACE
diff --git a/src/tools/moc/main.cpp b/src/tools/moc/main.cpp
index b8c2d7f594..61f3666b16 100644
--- a/src/tools/moc/main.cpp
+++ b/src/tools/moc/main.cpp
@@ -367,6 +367,10 @@ int runMoc(int argc, char **argv)
depFileRuleNameOption.setValueName(QStringLiteral("rule name"));
parser.addOption(depFileRuleNameOption);
+ QCommandLineOption requireCompleTypesOption(QStringLiteral("require-complete-types"));
+ requireCompleTypesOption.setDescription(QStringLiteral("Require complete types for better performance"));
+ parser.addOption(requireCompleTypesOption);
+
parser.addPositionalArgument(QStringLiteral("[header-file]"),
QStringLiteral("Header file to read from, otherwise stdin."));
parser.addPositionalArgument(QStringLiteral("[@option-file]"),
@@ -398,6 +402,8 @@ int runMoc(int argc, char **argv)
moc.noInclude = true;
autoInclude = false;
}
+ if (parser.isSet(requireCompleTypesOption))
+ moc.requireCompleteTypes = true;
if (!ignoreConflictingOptions) {
if (parser.isSet(forceIncludeOption)) {
moc.noInclude = false;
diff --git a/src/tools/moc/moc.cpp b/src/tools/moc/moc.cpp
index f04f4c5d0d..0ffbe7bb13 100644
--- a/src/tools/moc/moc.cpp
+++ b/src/tools/moc/moc.cpp
@@ -1125,7 +1125,7 @@ void Moc::generate(FILE *out, FILE *jsonOutput)
fputs("", out);
for (i = 0; i < classList.size(); ++i) {
- Generator generator(&classList[i], metaTypes, knownQObjectClasses, knownGadgets, out);
+ Generator generator(&classList[i], metaTypes, knownQObjectClasses, knownGadgets, out, requireCompleteTypes);
generator.generateCode();
}
fputs("", out);
diff --git a/src/tools/moc/moc.h b/src/tools/moc/moc.h
index 486d033049..84ddf47a89 100644
--- a/src/tools/moc/moc.h
+++ b/src/tools/moc/moc.h
@@ -224,13 +224,14 @@ class Moc : public Parser
{
public:
Moc()
- : noInclude(false), mustIncludeQPluginH(false)
+ : noInclude(false), mustIncludeQPluginH(false), requireCompleteTypes(false)
{}
QByteArray filename;
bool noInclude;
bool mustIncludeQPluginH;
+ bool requireCompleteTypes;
QByteArray includePath;
QVector<QByteArray> includeFiles;
QVector<ClassDef> classList;