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>
This commit is contained in:
Fabian Kosmale 2020-03-19 10:47:29 +01:00
parent 5306fdabc1
commit fa987d4441
49 changed files with 368 additions and 107 deletions

View File

@ -618,7 +618,7 @@ static inline int indexOfMethodRelative(const QMetaObject **baseObject,
? (priv(m->d.data)->signalCount) : 0; ? (priv(m->d.data)->signalCount) : 0;
for (; i >= end; --i) { 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)) { if (methodMatch(m, handle, name, argc, types)) {
*baseObject = m; *baseObject = m;
return i; return i;
@ -819,7 +819,7 @@ int QMetaObjectPrivate::indexOfConstructor(const QMetaObject *m, const QByteArra
int argc, const QArgumentType *types) int argc, const QArgumentType *types)
{ {
for (int i = priv(m->d.data)->constructorCount-1; i >= 0; --i) { 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)) if (methodMatch(m, handle, name, argc, types))
return i; return i;
} }
@ -895,7 +895,7 @@ QMetaMethod QMetaObjectPrivate::signal(const QMetaObject *m, int signal_index)
if (i >= 0 && i < priv(m->d.data)->signalCount) { if (i >= 0 && i < priv(m->d.data)->signalCount) {
result.mobj = m; result.mobj = m;
result.handle = priv(m->d.data)->methodData + 5*i; result.handle = priv(m->d.data)->methodData + QMetaObjectPrivate::IntsPerMethod*i;
} }
return result; return result;
} }
@ -1078,7 +1078,7 @@ QMetaMethod QMetaObject::constructor(int index) const
Q_ASSERT(priv(d.data)->revision >= 2); Q_ASSERT(priv(d.data)->revision >= 2);
if (i >= 0 && i < priv(d.data)->constructorCount) { if (i >= 0 && i < priv(d.data)->constructorCount) {
result.mobj = this; result.mobj = this;
result.handle = priv(d.data)->constructorData + 5*i; result.handle = priv(d.data)->constructorData + QMetaObjectPrivate::IntsPerMethod*i;
} }
return result; return result;
} }
@ -1098,7 +1098,7 @@ QMetaMethod QMetaObject::method(int index) const
QMetaMethod result; QMetaMethod result;
if (i >= 0 && i < priv(d.data)->methodCount) { if (i >= 0 && i < priv(d.data)->methodCount) {
result.mobj = this; result.mobj = this;
result.handle = priv(d.data)->methodData + 5*i; result.handle = priv(d.data)->methodData + QMetaObjectPrivate::IntsPerMethod*i;
} }
return result; return result;
} }
@ -1844,7 +1844,7 @@ QByteArray QMetaMethodPrivate::tag() const
int QMetaMethodPrivate::ownMethodIndex() const int QMetaMethodPrivate::ownMethodIndex() const
{ {
// recompute the methodIndex by reversing the arithmetic in QMetaObject::property() // 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 The return value is one of the types that are registered
with QMetaType, or QMetaType::UnknownType if the type is not 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 int QMetaMethod::returnType() const
{ {
if (!mobj) if (!mobj)
return QMetaType::UnknownType; 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 The return value is one of the types that are registered
with QMetaType, or QMetaType::UnknownType if the type is not 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 int QMetaMethod::parameterType(int index) const
{
return parameterMetaType(index).id();
}
/*!
\since 6.0
Returns the metatype of the parameter at the given \a index.
If the \a index is smaller than zero or larger than
parameterCount(), an invalid QMetaType is returned.
\sa parameterCount(), returnMetaType(), QMetaType
*/
QMetaType QMetaMethod::parameterMetaType(int index) const
{ {
if (!mobj || index < 0) if (!mobj || index < 0)
return QMetaType::UnknownType; return {};
if (index >= QMetaMethodPrivate::get(this)->parameterCount()) auto priv = QMetaMethodPrivate::get(this);
return QMetaType::UnknownType; if (index >= priv->parameterCount())
return {};
int type = QMetaMethodPrivate::get(this)->parameterType(index); // + 1 if there exists a return type
if (type != QMetaType::UnknownType) auto parameterOffset = index + (methodType() == QMetaMethod::Constructor ? 0 : 1);
return type; auto mt = QMetaType(mobj->d.metaTypes[mobj->d.data[handle + 5] + parameterOffset]);
if (mt.id() == QMetaType::UnknownType)
void *argv[] = { &type, &index }; return QMetaType(QMetaMethodPrivate::get(this)->parameterType(index));
mobj->static_metacall(QMetaObject::RegisterMethodArgumentMetaType, QMetaMethodPrivate::get(this)->ownMethodIndex(), argv); else
if (type != -1) return mt;
return type;
return QMetaType::UnknownType;
} }
/*! /*!
@ -2055,7 +2085,7 @@ int QMetaMethod::revision() const
return 0; return 0;
if ((QMetaMethod::Access)(mobj->d.data[handle + 4] & MethodRevisioned)) { if ((QMetaMethod::Access)(mobj->d.data[handle + 4] & MethodRevisioned)) {
int offset = priv(mobj->d.data)->methodData int offset = priv(mobj->d.data)->methodData
+ priv(mobj->d.data)->methodCount * 5 + priv(mobj->d.data)->methodCount * QMetaObjectPrivate::IntsPerMethod
+ QMetaMethodPrivate::get(this)->ownMethodIndex(); + QMetaMethodPrivate::get(this)->ownMethodIndex();
return mobj->d.data[offset]; return mobj->d.data[offset];
} }
@ -2120,7 +2150,7 @@ QMetaMethod QMetaMethod::fromSignalImpl(const QMetaObject *metaObject, void **si
m->static_metacall(QMetaObject::IndexOfMethod, 0, args); m->static_metacall(QMetaObject::IndexOfMethod, 0, args);
if (i >= 0) { if (i >= 0) {
result.mobj = m; result.mobj = m;
result.handle = priv(m->d.data)->methodData + 5*i; result.handle = priv(m->d.data)->methodData + QMetaObjectPrivate::IntsPerMethod*i;
break; break;
} }
} }
@ -3712,10 +3742,10 @@ const char* QMetaClassInfo::value() const
int QMetaObjectPrivate::originalClone(const QMetaObject *mobj, int local_method_index) int QMetaObjectPrivate::originalClone(const QMetaObject *mobj, int local_method_index)
{ {
Q_ASSERT(local_method_index < get(mobj)->methodCount); 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) { while (mobj->d.data[handle + 4] & MethodCloned) {
Q_ASSERT(local_method_index > 0); Q_ASSERT(local_method_index > 0);
handle -= 5; handle -= QMetaObjectPrivate::IntsPerMethod;
local_method_index--; local_method_index--;
} }
return local_method_index; return local_method_index;

View File

@ -57,8 +57,10 @@ public:
QByteArray name() const; QByteArray name() const;
const char *typeName() const; const char *typeName() const;
int returnType() const; int returnType() const;
QMetaType returnMetaType() const;
int parameterCount() const; int parameterCount() const;
int parameterType(int index) const; int parameterType(int index) const;
QMetaType parameterMetaType(int index) const;
void getParameterTypes(int *types) const; void getParameterTypes(int *types) const;
QList<QByteArray> parameterTypes() const; QList<QByteArray> parameterTypes() const;
QList<QByteArray> parameterNames() const; QList<QByteArray> parameterNames() const;

View File

@ -176,7 +176,9 @@ struct QMetaObjectPrivate
{ {
// revision 7 is Qt 5.0 everything lower is not supported // revision 7 is Qt 5.0 everything lower is not supported
// revision 8 is Qt 5.12: It adds the enum name to QMetaEnum // 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 revision;
int className; int className;

View File

@ -1216,7 +1216,7 @@ static int buildMetaObject(QMetaObjectBuilderPrivate *d, char *buf,
- int(d->methods.size()) // return "parameters" don't have names - int(d->methods.size()) // return "parameters" don't have names
- int(d->constructors.size()); // "this" parameters don't have names - int(d->constructors.size()); // "this" parameters don't have names
if (buf) { 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->revision = QMetaObjectPrivate::OutputRevision;
pmeta->flags = d->flags; pmeta->flags = d->flags;
pmeta->className = 0; // Class name is always the first string. 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->methodCount = int(d->methods.size());
pmeta->methodData = dataIndex; pmeta->methodData = dataIndex;
dataIndex += 5 * int(d->methods.size()); dataIndex += QMetaObjectPrivate::IntsPerMethod * int(d->methods.size());
if (hasRevisionedMethods) if (hasRevisionedMethods)
dataIndex += int(d->methods.size()); dataIndex += int(d->methods.size());
paramsIndex = dataIndex; paramsIndex = dataIndex;
@ -1248,10 +1248,10 @@ static int buildMetaObject(QMetaObjectBuilderPrivate *d, char *buf,
pmeta->constructorCount = int(d->constructors.size()); pmeta->constructorCount = int(d->constructors.size());
pmeta->constructorData = dataIndex; pmeta->constructorData = dataIndex;
dataIndex += 5 * int(d->constructors.size()); dataIndex += QMetaObjectPrivate::IntsPerMethod * int(d->constructors.size());
} else { } else {
dataIndex += 2 * int(d->classInfoNames.size()); dataIndex += 2 * int(d->classInfoNames.size());
dataIndex += 5 * int(d->methods.size()); dataIndex += QMetaObjectPrivate::IntsPerMethod * int(d->methods.size());
if (hasRevisionedMethods) if (hasRevisionedMethods)
dataIndex += int(d->methods.size()); dataIndex += int(d->methods.size());
paramsIndex = dataIndex; paramsIndex = dataIndex;
@ -1262,7 +1262,7 @@ static int buildMetaObject(QMetaObjectBuilderPrivate *d, char *buf,
if (hasRevisionedProperties) if (hasRevisionedProperties)
dataIndex += int(d->properties.size()); dataIndex += int(d->properties.size());
dataIndex += 5 * int(d->enumerators.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. // 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. // Output the methods in the class.
Q_ASSERT(!buf || dataIndex == pmeta->methodData); Q_ASSERT(!buf || dataIndex == pmeta->methodData);
int parameterMetaTypesIndex = d->properties.size();
for (const auto &method : d->methods) { for (const auto &method : d->methods) {
int name = strings.enter(method.name()); int name = strings.enter(method.name());
int argc = method.parameterCount(); int argc = method.parameterCount();
@ -1318,11 +1319,13 @@ static int buildMetaObject(QMetaObjectBuilderPrivate *d, char *buf,
data[dataIndex + 2] = paramsIndex; data[dataIndex + 2] = paramsIndex;
data[dataIndex + 3] = tag; data[dataIndex + 3] = tag;
data[dataIndex + 4] = attrs; data[dataIndex + 4] = attrs;
data[dataIndex + 5] = parameterMetaTypesIndex;
if (method.methodType() == QMetaMethod::Signal) if (method.methodType() == QMetaMethod::Signal)
pmeta->signalCount++; pmeta->signalCount++;
} }
dataIndex += 5; dataIndex += QMetaObjectPrivate::IntsPerMethod;
paramsIndex += 1 + argc * 2; paramsIndex += 1 + argc * 2;
parameterMetaTypesIndex += 1 + argc;
} }
if (hasRevisionedMethods) { if (hasRevisionedMethods) {
for (const auto &method : d->methods) { for (const auto &method : d->methods) {
@ -1333,7 +1336,7 @@ static int buildMetaObject(QMetaObjectBuilderPrivate *d, char *buf,
} }
// Output the method parameters in the class. // 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)); + (hasRevisionedMethods ? int(d->methods.size()) : 0));
for (int x = 0; x < 2; ++x) { for (int x = 0; x < 2; ++x) {
const std::vector<QMetaMethodBuilderPrivate> &methods = (x == 0) ? d->methods : d->constructors; 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 + 2] = paramsIndex;
data[dataIndex + 3] = tag; data[dataIndex + 3] = tag;
data[dataIndex + 4] = attrs; data[dataIndex + 4] = attrs;
data[dataIndex + 5] = parameterMetaTypesIndex;
} }
dataIndex += 5; dataIndex += QMetaObjectPrivate::IntsPerMethod;
paramsIndex += 1 + argc * 2; paramsIndex += 1 + argc * 2;
parameterMetaTypesIndex += argc;
} }
size += strings.blobSize(); size += strings.blobSize();
@ -1474,7 +1479,7 @@ static int buildMetaObject(QMetaObjectBuilderPrivate *d, char *buf,
size += sizeof(SuperData) * (d->relatedMetaObjects.size() + 1); 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 *); ALIGN(size, QtPrivate::QMetaTypeInterface *);
auto types = reinterpret_cast<QtPrivate::QMetaTypeInterface **>(buf + size); auto types = reinterpret_cast<QtPrivate::QMetaTypeInterface **>(buf + size);
if (buf) { if (buf) {
@ -1484,8 +1489,26 @@ static int buildMetaObject(QMetaObjectBuilderPrivate *d, char *buf,
*types = reinterpret_cast<QtPrivate::QMetaTypeInterface *&>(mt); *types = reinterpret_cast<QtPrivate::QMetaTypeInterface *&>(mt);
types++; 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. // Align the final size and return it.

View File

@ -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 } // namespace QtPrivate
template<typename T> template<typename T>
@ -2809,6 +2838,11 @@ QtPrivate::QMetaTypeInterface *const qt_metaTypeArray[] = {
QtPrivate::qMetaTypeInterfaceForType<T>()... QtPrivate::qMetaTypeInterfaceForType<T>()...
}; };
template<typename Unique,typename... T>
QtPrivate::QMetaTypeInterface *const qt_incomplete_metaTypeArray[] = {
QtPrivate::qTryMetaTypeInterfaceForType<Unique, T>()...
};
QT_END_NAMESPACE QT_END_NAMESPACE
#endif // QMETATYPE_H #endif // QMETATYPE_H

View File

@ -2562,7 +2562,7 @@ bool QObject::isSignalConnected(const QMetaMethod &signal) const
Q_ASSERT_X(signal.mobj->cast(this) && signal.methodType() == QMetaMethod::Signal, Q_ASSERT_X(signal.mobj->cast(this) && signal.methodType() == QMetaMethod::Signal,
"QObject::isSignalConnected" , "the parameter must be a signal member of the object"); "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) if (signal.mobj->d.data[signal.handle + 4] & MethodCloned)
signalIndex = QMetaObjectPrivate::originalClone(signal.mobj, signalIndex); signalIndex = QMetaObjectPrivate::originalClone(signal.mobj, signalIndex);
@ -2610,7 +2610,7 @@ void QMetaObjectPrivate::memberIndexes(const QObject *obj,
m = m->d.superdata; m = m->d.superdata;
if (!m) if (!m)
return; return;
*signalIndex = *methodIndex = (member.handle - get(member.mobj)->methodData)/5; *signalIndex = *methodIndex = (member.handle - get(member.mobj)->methodData)/QMetaObjectPrivate::IntsPerMethod;
int signalOffset; int signalOffset;
int methodOffset; int methodOffset;

View File

@ -76,25 +76,6 @@ static void preventDllUnload();
Q_GLOBAL_STATIC(QDBusConnectionManager, _q_manager) 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) QDBusConnectionPrivate *QDBusConnectionManager::busConnection(QDBusConnection::BusType type)
{ {
Q_STATIC_ASSERT(int(QDBusConnection::SessionBus) + int(QDBusConnection::SystemBus) == 1); Q_STATIC_ASSERT(int(QDBusConnection::SessionBus) + int(QDBusConnection::SystemBus) == 1);

View File

@ -77,6 +77,8 @@ class QDBusConnectionPrivate;
class Q_DBUS_EXPORT QDBusConnection class Q_DBUS_EXPORT QDBusConnection
{ {
Q_GADGET Q_GADGET
Q_MOC_INCLUDE(<QtDBus/qdbuspendingcall.h>)
public: public:
enum BusType { SessionBus, SystemBus, ActivationBus }; enum BusType { SessionBus, SystemBus, ActivationBus };
Q_ENUM(BusType) Q_ENUM(BusType)

View File

@ -70,6 +70,7 @@
#include <qdbusmessage.h> #include <qdbusmessage.h>
#include <qdbusservicewatcher.h> // for the WatchMode enum #include <qdbusservicewatcher.h> // for the WatchMode enum
Q_MOC_INCLUDE(<QtDBus/private/qdbuspendingcall_p.h>)
#ifndef QT_NO_DBUS #ifndef QT_NO_DBUS

View File

@ -100,6 +100,26 @@ private:
QString senderName; // internal; will probably change 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 QT_END_NAMESPACE
#endif // QT_NO_DBUS #endif // QT_NO_DBUS

View File

@ -141,6 +141,9 @@ Q_DBUS_EXPORT QDebug operator<<(QDebug, const QDBusError &);
QT_END_NAMESPACE QT_END_NAMESPACE
Q_DECLARE_METATYPE(QDBusError) 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 // QT_NO_DBUS
#endif #endif

View File

@ -139,6 +139,8 @@ QT_END_NAMESPACE
Q_DECLARE_METATYPE(QDBusMessage) Q_DECLARE_METATYPE(QDBusMessage)
#else
class Q_DBUS_EXPORT QDBusMessage {}; // dummy class for moc
#endif // QT_NO_DBUS #endif // QT_NO_DBUS
#endif #endif

View File

@ -416,7 +416,7 @@ void QDBusMetaObjectGenerator::write(QDBusMetaObject *obj)
- methods.count(); // ditto - methods.count(); // ditto
QDBusMetaObjectPrivate *header = reinterpret_cast<QDBusMetaObjectPrivate *>(idata.data()); 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->revision = QMetaObjectPrivate::OutputRevision;
header->className = 0; header->className = 0;
header->classInfoCount = 0; header->classInfoCount = 0;
@ -424,7 +424,7 @@ void QDBusMetaObjectGenerator::write(QDBusMetaObject *obj)
header->methodCount = signals_.count() + methods.count(); header->methodCount = signals_.count() + methods.count();
header->methodData = idata.size(); header->methodData = idata.size();
header->propertyCount = properties.count(); 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->enumeratorCount = 0;
header->enumeratorData = 0; header->enumeratorData = 0;
header->constructorCount = 0; header->constructorCount = 0;
@ -436,7 +436,7 @@ void QDBusMetaObjectGenerator::write(QDBusMetaObject *obj)
header->methodDBusData = header->propertyDBusData + header->propertyCount * intsPerProperty; header->methodDBusData = header->propertyDBusData + header->propertyCount * intsPerProperty;
int data_size = idata.size() + int data_size = idata.size() +
(header->methodCount * (5+intsPerMethod)) + methodParametersDataSize + (header->methodCount * (QMetaObjectPrivate::IntsPerMethod+intsPerMethod)) + methodParametersDataSize +
(header->propertyCount * (3+intsPerProperty)); (header->propertyCount * (3+intsPerProperty));
for (const Method &mm : qAsConst(signals_)) for (const Method &mm : qAsConst(signals_))
data_size += 2 + mm.inputTypes.count() + mm.outputTypes.count(); data_size += 2 + mm.inputTypes.count() + mm.outputTypes.count();
@ -447,12 +447,23 @@ void QDBusMetaObjectGenerator::write(QDBusMetaObject *obj)
QMetaStringTable strings(className.toLatin1()); QMetaStringTable strings(className.toLatin1());
int offset = header->methodData; int offset = header->methodData;
int parametersOffset = offset + header->methodCount * 5; int parametersOffset = offset + header->methodCount * QMetaObjectPrivate::IntsPerMethod;
int signatureOffset = header->methodDBusData; int signatureOffset = header->methodDBusData;
int typeidOffset = header->methodDBusData + header->methodCount * intsPerMethod; int typeidOffset = header->methodDBusData + header->methodCount * intsPerMethod;
idata[typeidOffset++] = 0; // eod 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: // add each method:
int currentMethodMetaTypeOffset = properties.count();
for (int x = 0; x < 2; ++x) { for (int x = 0; x < 2; ++x) {
// Signals must be added before other methods, to match moc. // Signals must be added before other methods, to match moc.
QMap<QByteArray, Method> &map = (x == 0) ? signals_ : methods; QMap<QByteArray, Method> &map = (x == 0) ? signals_ : methods;
@ -467,6 +478,7 @@ void QDBusMetaObjectGenerator::write(QDBusMetaObject *obj)
idata[offset++] = parametersOffset; idata[offset++] = parametersOffset;
idata[offset++] = strings.enter(mm.tag); idata[offset++] = strings.enter(mm.tag);
idata[offset++] = mm.flags; idata[offset++] = mm.flags;
idata[offset++] = currentMethodMetaTypeOffset;
// Parameter types // Parameter types
for (int i = -1; i < argc; ++i) { for (int i = -1; i < argc; ++i) {
@ -496,6 +508,7 @@ void QDBusMetaObjectGenerator::write(QDBusMetaObject *obj)
typeInfo = IsUnresolvedType | strings.enter(typeName); typeInfo = IsUnresolvedType | strings.enter(typeName);
else else
typeInfo = type; typeInfo = type;
metaTypes[currentMethodMetaTypeOffset++] = QMetaType (type);
idata[parametersOffset++] = typeInfo; idata[parametersOffset++] = typeInfo;
} }
// Parameter names // 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(parametersOffset == header->propertyData);
Q_ASSERT(signatureOffset == header->methodDBusData + header->methodCount * intsPerMethod); Q_ASSERT(signatureOffset == header->methodDBusData + header->methodCount * intsPerMethod);
Q_ASSERT(typeidOffset == idata.size()); Q_ASSERT(typeidOffset == idata.size());
offset += methodParametersDataSize; offset += methodParametersDataSize;
Q_ASSERT(offset == header->propertyData); Q_ASSERT(offset == header->propertyData);
QMetaType *metaTypes = new QMetaType[properties.count()];
int propertyId = 0;
// add each property // add each property
signatureOffset = header->propertyDBusData; signatureOffset = header->propertyDBusData;
for (QMap<QByteArray, Property>::ConstIterator it = properties.constBegin(); for (QMap<QByteArray, Property>::ConstIterator it = properties.constBegin();

View File

@ -43,6 +43,7 @@
#include <QtGui/qtguiglobal.h> #include <QtGui/qtguiglobal.h>
#include <QtCore/QObject> #include <QtCore/QObject>
#include <QtGui/qsurface.h> #include <QtGui/qsurface.h>
Q_MOC_INCLUDE(<QScreen>)
QT_BEGIN_NAMESPACE QT_BEGIN_NAMESPACE

View File

@ -58,6 +58,8 @@
#include <QtCore/QDir> #include <QtCore/QDir>
#include <QtCore/QUrl> #include <QtCore/QUrl>
#include <QtGui/QRgb> #include <QtGui/QRgb>
Q_MOC_INCLUDE(<QFont>)
Q_MOC_INCLUDE(<QColor>)
QT_BEGIN_NAMESPACE QT_BEGIN_NAMESPACE

View File

@ -66,6 +66,7 @@ class QBackingStore;
class Q_GUI_EXPORT QPlatformNativeInterface : public QObject class Q_GUI_EXPORT QPlatformNativeInterface : public QObject
{ {
Q_OBJECT Q_OBJECT
Q_MOC_INCLUDE(<qpa/qplatformwindow.h>)
public: public:
virtual void *nativeResourceForIntegration(const QByteArray &resource); virtual void *nativeResourceForIntegration(const QByteArray &resource);
virtual void *nativeResourceForContext(const QByteArray &resource, QOpenGLContext *context); virtual void *nativeResourceForContext(const QByteArray &resource, QOpenGLContext *context);

View File

@ -57,6 +57,7 @@ class QRect;
class Q_GUI_EXPORT QPlatformSystemTrayIcon : public QObject class Q_GUI_EXPORT QPlatformSystemTrayIcon : public QObject
{ {
Q_OBJECT Q_OBJECT
Q_MOC_INCLUDE(<qpa/qplatformscreen.h>)
public: public:
enum ActivationReason { enum ActivationReason {
Unknown, Unknown,

View File

@ -47,6 +47,7 @@
#include <QtCore/qvariant.h> #include <QtCore/qvariant.h>
#include <QtGui/qfont.h> #include <QtGui/qfont.h>
#include <QtCore/qurl.h> #include <QtCore/qurl.h>
Q_MOC_INCLUDE(<QtGui/qtextcursor.h>)
QT_BEGIN_NAMESPACE QT_BEGIN_NAMESPACE

View File

@ -75,6 +75,11 @@ struct z_stream_s;
#include <private/qringbuffer_p.h> #include <private/qringbuffer_p.h>
#include <private/qbytedata_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_REQUIRE_CONFIG(http);
QT_BEGIN_NAMESPACE QT_BEGIN_NAMESPACE

View File

@ -54,10 +54,11 @@
#include <QtNetwork/private/qtnetworkglobal_p.h> #include <QtNetwork/private/qtnetworkglobal_p.h>
#include "qnetworkreplyimpl_p.h" #include "qnetworkreplyimpl_p.h"
#include "QtCore/qobject.h" #include "QtCore/qobject.h"
Q_MOC_INCLUDE(<QAuthenticator>)
Q_MOC_INCLUDE(<QtNetwork/QSslError>)
QT_BEGIN_NAMESPACE QT_BEGIN_NAMESPACE
class QAuthenticator;
class QNetworkProxy; class QNetworkProxy;
class QNetworkProxyQuery; class QNetworkProxyQuery;
class QNetworkRequest; class QNetworkRequest;

View File

@ -1532,17 +1532,15 @@ void QNetworkAccessManagerPrivate::_q_replySslErrors(const QList<QSslError> &err
#endif #endif
} }
#ifndef QT_NO_SSL
void QNetworkAccessManagerPrivate::_q_replyPreSharedKeyAuthenticationRequired(QSslPreSharedKeyAuthenticator *authenticator) void QNetworkAccessManagerPrivate::_q_replyPreSharedKeyAuthenticationRequired(QSslPreSharedKeyAuthenticator *authenticator)
{ {
#ifndef QT_NO_SSL
Q_Q(QNetworkAccessManager); Q_Q(QNetworkAccessManager);
QNetworkReply *reply = qobject_cast<QNetworkReply *>(q->sender()); QNetworkReply *reply = qobject_cast<QNetworkReply *>(q->sender());
if (reply) if (reply)
emit q->preSharedKeyAuthenticationRequired(reply, authenticator); emit q->preSharedKeyAuthenticationRequired(reply, authenticator);
#else
Q_UNUSED(authenticator);
#endif
} }
#endif
QNetworkReply *QNetworkAccessManagerPrivate::postProcess(QNetworkReply *reply) QNetworkReply *QNetworkAccessManagerPrivate::postProcess(QNetworkReply *reply)
{ {

View File

@ -49,6 +49,7 @@
#include <QtNetwork/QSslConfiguration> #include <QtNetwork/QSslConfiguration>
#include <QtNetwork/QSslPreSharedKeyAuthenticator> #include <QtNetwork/QSslPreSharedKeyAuthenticator>
#endif #endif
Q_MOC_INCLUDE(<QtNetwork/QSslError>)
QT_BEGIN_NAMESPACE QT_BEGIN_NAMESPACE
@ -178,7 +179,9 @@ private:
#endif #endif
Q_DECLARE_PRIVATE(QNetworkAccessManager) Q_DECLARE_PRIVATE(QNetworkAccessManager)
Q_PRIVATE_SLOT(d_func(), void _q_replySslErrors(QList<QSslError>)) Q_PRIVATE_SLOT(d_func(), void _q_replySslErrors(QList<QSslError>))
#ifndef QT_NO_SSL
Q_PRIVATE_SLOT(d_func(), void _q_replyPreSharedKeyAuthenticationRequired(QSslPreSharedKeyAuthenticator*)) Q_PRIVATE_SLOT(d_func(), void _q_replyPreSharedKeyAuthenticationRequired(QSslPreSharedKeyAuthenticator*))
#endif
Q_PRIVATE_SLOT(d_func(), void _q_onlineStateChanged(bool)) Q_PRIVATE_SLOT(d_func(), void _q_onlineStateChanged(bool))
}; };

View File

@ -71,6 +71,8 @@
#include <QtNetwork/QSslConfiguration> #include <QtNetwork/QSslConfiguration>
#endif #endif
Q_MOC_INCLUDE(<QtNetwork/QAuthenticator>)
QT_REQUIRE_CONFIG(http); QT_REQUIRE_CONFIG(http);
QT_BEGIN_NAMESPACE QT_BEGIN_NAMESPACE

View File

@ -60,6 +60,8 @@ class QAuthenticator;
class Q_NETWORK_EXPORT QAbstractSocket : public QIODevice class Q_NETWORK_EXPORT QAbstractSocket : public QIODevice
{ {
Q_OBJECT Q_OBJECT
Q_MOC_INCLUDE(<QtNetwork/qauthenticator.h>)
public: public:
enum SocketType { enum SocketType {
TcpSocket, TcpSocket,

View File

@ -83,6 +83,7 @@ public:
class Q_AUTOTEST_EXPORT QAbstractSocketEngine : public QObject class Q_AUTOTEST_EXPORT QAbstractSocketEngine : public QObject
{ {
Q_OBJECT Q_OBJECT
Q_MOC_INCLUDE(<QtNetwork/qauthenticator.h>)
public: public:
static QAbstractSocketEngine *createSocketEngine(QAbstractSocket::SocketType socketType, const QNetworkProxy &, QObject *parent); static QAbstractSocketEngine *createSocketEngine(QAbstractSocket::SocketType socketType, const QNetworkProxy &, QObject *parent);

View File

@ -48,6 +48,8 @@
#include <QtCore/qcryptographichash.h> #include <QtCore/qcryptographichash.h>
#include <QtCore/qobject.h> #include <QtCore/qobject.h>
Q_MOC_INCLUDE(<QtNetwork/QSslPreSharedKeyAuthenticator>)
#ifndef Q_CLANG_QDOC #ifndef Q_CLANG_QDOC
QT_REQUIRE_CONFIG(dtls); QT_REQUIRE_CONFIG(dtls);
#endif #endif

View File

@ -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 &error);
Q_NETWORK_EXPORT QDebug operator<<(QDebug debug, const QSslError::SslError &error); Q_NETWORK_EXPORT QDebug operator<<(QDebug debug, const QSslError::SslError &error);
#endif #endif
#else
class Q_NETWORK_EXPORT QSslError {}; // dummy class so that moc has a complete type
#endif // QT_NO_SSL #endif // QT_NO_SSL
QT_END_NAMESPACE QT_END_NAMESPACE

View File

@ -109,6 +109,7 @@ class QSslSocketPrivate;
class Q_NETWORK_EXPORT QSslSocket : public QTcpSocket class Q_NETWORK_EXPORT QSslSocket : public QTcpSocket
{ {
Q_OBJECT Q_OBJECT
Q_MOC_INCLUDE(<QtNetwork/qsslpresharedkeyauthenticator.h>)
public: public:
enum SslMode { enum SslMode {
UnencryptedMode, UnencryptedMode,

View File

@ -56,6 +56,7 @@
#include <QtCore/QQueue> #include <QtCore/QQueue>
#include <QtDBus/QDBusConnection> #include <QtDBus/QDBusConnection>
#include <QtGui/QAccessibleInterface> #include <QtGui/QAccessibleInterface>
Q_MOC_INCLUDE(<QtDBus/QDBusMessage>)
QT_REQUIRE_CONFIG(accessibility); QT_REQUIRE_CONFIG(accessibility);

View File

@ -55,6 +55,7 @@
#include <QtCore/QString> #include <QtCore/QString>
#include <QtDBus/QDBusConnection> #include <QtDBus/QDBusConnection>
#include <QtDBus/QDBusVariant> #include <QtDBus/QDBusVariant>
Q_MOC_INCLUDE(<QtDBus/QDBusError>)
QT_BEGIN_NAMESPACE QT_BEGIN_NAMESPACE

View File

@ -56,6 +56,7 @@
#include <QtDBus/QDBusVariant> #include <QtDBus/QDBusVariant>
#include <QtGui/qtgui-config.h> #include <QtGui/qtgui-config.h>
Q_MOC_INCLUDE(<QtDBus/QDBusError>)
QT_BEGIN_NAMESPACE QT_BEGIN_NAMESPACE

View File

@ -59,6 +59,7 @@ class QTuioToken;
class QTuioHandler : public QObject class QTuioHandler : public QObject
{ {
Q_OBJECT Q_OBJECT
Q_MOC_INCLUDE("qoscmessage_p.h")
public: public:
explicit QTuioHandler(const QString &specification); explicit QTuioHandler(const QString &specification);

View File

@ -45,6 +45,7 @@
#include <xkbcommon/xkbcommon-compose.h> #include <xkbcommon/xkbcommon-compose.h>
Q_DECLARE_OPAQUE_POINTER(xkb_context *)
QT_BEGIN_NAMESPACE QT_BEGIN_NAMESPACE
Q_DECLARE_LOGGING_CATEGORY(lcXkbCompose) Q_DECLARE_LOGGING_CATEGORY(lcXkbCompose)

View File

@ -524,6 +524,6 @@ void QCocoaIntegration::focusWindowChanged(QWindow *focusWindow)
setApplicationIcon(focusWindow->icon()); setApplicationIcon(focusWindow->icon());
} }
#include "moc_qcocoaintegration.cpp"
QT_END_NAMESPACE QT_END_NAMESPACE
#include "moc_qcocoaintegration.cpp"

View File

@ -44,6 +44,9 @@
#include <qpa/qplatformnativeinterface.h> #include <qpa/qplatformnativeinterface.h>
#include <QtGui/qpixmap.h> #include <QtGui/qpixmap.h>
Q_MOC_INCLUDE(<QWindow>)
Q_MOC_INCLUDE(<qpa/qplatformprintersupport.h>)
Q_MOC_INCLUDE(<QPrintEngine>)
QT_BEGIN_NAMESPACE QT_BEGIN_NAMESPACE

View File

@ -58,6 +58,7 @@ class Q_SQL_EXPORT QSqlTableModel: public QSqlQueryModel
{ {
Q_OBJECT Q_OBJECT
Q_DECLARE_PRIVATE(QSqlTableModel) Q_DECLARE_PRIVATE(QSqlTableModel)
Q_MOC_INCLUDE(<QtSql/qsqlrecord.h>)
public: public:
enum EditStrategy {OnFieldChange, OnRowChange, OnManualSubmit}; enum EditStrategy {OnFieldChange, OnRowChange, OnManualSubmit};

View File

@ -80,9 +80,9 @@ QT_FOR_EACH_STATIC_TYPE(RETURN_METATYPENAME_STRING)
return nullptr; 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) : out(outfile), cdef(classDef), metaTypes(metaTypes), knownQObjectClasses(knownQObjectClasses)
, knownGadgets(knownGadgets) , knownGadgets(knownGadgets), requireCompleteTypes(requireCompleteTypes)
{ {
if (cdef->superclassList.size()) if (cdef->superclassList.size())
purestSuperClass = cdef->superclassList.constFirst().first; purestSuperClass = cdef->superclassList.constFirst().first;
@ -350,7 +350,7 @@ void Generator::generateCode()
int methodCount = cdef->signalList.count() + cdef->slotList.count() + cdef->methodList.count(); int methodCount = cdef->signalList.count() + cdef->slotList.count() + cdef->methodList.count();
fprintf(out, " %4d, %4d, // methods\n", methodCount, methodCount ? index : 0); fprintf(out, " %4d, %4d, // methods\n", methodCount, methodCount ? index : 0);
index += methodCount * 5; index += methodCount * QMetaObjectPrivate::IntsPerMethod;
if (cdef->revisionedMethods) if (cdef->revisionedMethods)
index += methodCount; index += methodCount;
int paramsIndex = index; int paramsIndex = index;
@ -391,20 +391,22 @@ void Generator::generateCode()
// //
generateClassInfos(); generateClassInfos();
int initialMetaTypeOffset = cdef->propertyList.count();
// //
// Build signals array first, otherwise the signal indices would be wrong // 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 // Build slots array
// //
generateFunctions(cdef->slotList, "slot", MethodSlot, paramsIndex); generateFunctions(cdef->slotList, "slot", MethodSlot, paramsIndex, initialMetaTypeOffset);
// //
// Build method array // Build method array
// //
generateFunctions(cdef->methodList, "method", MethodMethod, paramsIndex); generateFunctions(cdef->methodList, "method", MethodMethod, paramsIndex, initialMetaTypeOffset);
// //
// Build method version arrays // Build method version arrays
@ -438,7 +440,7 @@ void Generator::generateCode()
// Build constructors array // Build constructors array
// //
if (isConstructible) if (isConstructible)
generateFunctions(cdef->constructorList, "constructor", MethodConstructor, paramsIndex); generateFunctions(cdef->constructorList, "constructor", MethodConstructor, paramsIndex, initialMetaTypeOffset);
// //
// Terminate data array // Terminate data array
@ -553,14 +555,48 @@ void Generator::generateCode()
else else
fprintf(out, " qt_meta_extradata_%s,\n", qualifiedClassNameIdentifier.constData()); 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"); fprintf(out, " nullptr,\n");
} else { } 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) { for (int i = 0; i < cdef->propertyList.count(); ++i) {
const PropertyDef &p = cdef->propertyList.at(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"); 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", fprintf(out, "\nconst QMetaObject *%s::metaObject() const\n{\n return QObject::d_ptr->metaObject ? QObject::d_ptr->dynamicMetaObject() : &staticMetaObject;\n}\n",
cdef->qualified.constData()); cdef->qualified.constData());
// //
// Generate smart cast function // Generate smart cast function
// //
@ -688,11 +725,11 @@ void Generator::registerByteArrayVector(const QVector<QByteArray> &list)
strreg(ba); 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()) if (list.isEmpty())
return; 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) { for (int i = 0; i < list.count(); ++i) {
const FunctionDef &f = list.at(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(); int argc = f.arguments.count();
fprintf(out, " %4d, %4d, %4d, %4d, 0x%02x /* %s */,\n", fprintf(out, " %4d, %4d, %4d, %4d, 0x%02x, %4d /* %s */,\n",
stridx(f.name), argc, paramsIndex, stridx(f.tag), flags, comment.constData()); stridx(f.name), argc, paramsIndex, stridx(f.tag), flags, initialMetatypeOffset, comment.constData());
paramsIndex += 1 + argc * 2; paramsIndex += 1 + argc * 2;
// constructors don't have a return type
initialMetatypeOffset += (f.isConstructor ? 0 : 1) + argc;
} }
} }

View File

@ -39,7 +39,7 @@ class Generator
ClassDef *cdef; ClassDef *cdef;
QVector<uint> meta_data; QVector<uint> meta_data;
public: 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(); void generateCode();
private: private:
bool registerableMetaType(const QByteArray &propertyType); bool registerableMetaType(const QByteArray &propertyType);
@ -47,7 +47,7 @@ private:
void generateClassInfos(); void generateClassInfos();
void registerFunctionStrings(const QVector<FunctionDef> &list); void registerFunctionStrings(const QVector<FunctionDef> &list);
void registerByteArrayVector(const QVector<QByteArray> &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 generateFunctionRevisions(const QVector<FunctionDef> &list, const char *functype);
void generateFunctionParameters(const QVector<FunctionDef> &list, const char *functype); void generateFunctionParameters(const QVector<FunctionDef> &list, const char *functype);
void generateTypeInfo(const QByteArray &typeName, bool allowEmptyName = false); void generateTypeInfo(const QByteArray &typeName, bool allowEmptyName = false);
@ -70,6 +70,7 @@ private:
QVector<QByteArray> metaTypes; QVector<QByteArray> metaTypes;
QHash<QByteArray, QByteArray> knownQObjectClasses; QHash<QByteArray, QByteArray> knownQObjectClasses;
QHash<QByteArray, QByteArray> knownGadgets; QHash<QByteArray, QByteArray> knownGadgets;
bool requireCompleteTypes;
}; };
QT_END_NAMESPACE QT_END_NAMESPACE

View File

@ -367,6 +367,10 @@ int runMoc(int argc, char **argv)
depFileRuleNameOption.setValueName(QStringLiteral("rule name")); depFileRuleNameOption.setValueName(QStringLiteral("rule name"));
parser.addOption(depFileRuleNameOption); 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]"), parser.addPositionalArgument(QStringLiteral("[header-file]"),
QStringLiteral("Header file to read from, otherwise stdin.")); QStringLiteral("Header file to read from, otherwise stdin."));
parser.addPositionalArgument(QStringLiteral("[@option-file]"), parser.addPositionalArgument(QStringLiteral("[@option-file]"),
@ -398,6 +402,8 @@ int runMoc(int argc, char **argv)
moc.noInclude = true; moc.noInclude = true;
autoInclude = false; autoInclude = false;
} }
if (parser.isSet(requireCompleTypesOption))
moc.requireCompleteTypes = true;
if (!ignoreConflictingOptions) { if (!ignoreConflictingOptions) {
if (parser.isSet(forceIncludeOption)) { if (parser.isSet(forceIncludeOption)) {
moc.noInclude = false; moc.noInclude = false;

View File

@ -1125,7 +1125,7 @@ void Moc::generate(FILE *out, FILE *jsonOutput)
fputs("", out); fputs("", out);
for (i = 0; i < classList.size(); ++i) { 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(); generator.generateCode();
} }
fputs("", out); fputs("", out);

View File

@ -224,13 +224,14 @@ class Moc : public Parser
{ {
public: public:
Moc() Moc()
: noInclude(false), mustIncludeQPluginH(false) : noInclude(false), mustIncludeQPluginH(false), requireCompleteTypes(false)
{} {}
QByteArray filename; QByteArray filename;
bool noInclude; bool noInclude;
bool mustIncludeQPluginH; bool mustIncludeQPluginH;
bool requireCompleteTypes;
QByteArray includePath; QByteArray includePath;
QVector<QByteArray> includeFiles; QVector<QByteArray> includeFiles;
QVector<ClassDef> classList; QVector<ClassDef> classList;

View File

@ -48,6 +48,9 @@ private slots:
void fromSignal(); void fromSignal();
void gadget(); void gadget();
void returnMetaType();
void parameterMetaType();
}; };
struct CustomType { }; struct CustomType { };
@ -378,10 +381,11 @@ void tst_QMetaMethod::method_data()
<< QMetaMethod::Public << QMetaMethod::Public
<< QMetaMethod::Constructor; << QMetaMethod::Constructor;
// since Qt 6.0, parameter types get automatically registered
QTest::newRow("voidSignalCustomUnregisteredType") QTest::newRow("voidSignalCustomUnregisteredType")
<< QByteArray("voidSignalCustomUnregisteredType(CustomUnregisteredType)") << QByteArray("voidSignalCustomUnregisteredType(CustomUnregisteredType)")
<< int(QMetaType::Void) << QByteArray("void") << int(QMetaType::Void) << QByteArray("void")
<< (QList<int>() << 0) << (QList<int>() << QMetaType::fromType<CustomUnregisteredType>().id())
<< (QList<QByteArray>() << QByteArray("CustomUnregisteredType")) << (QList<QByteArray>() << QByteArray("CustomUnregisteredType"))
<< (QList<QByteArray>() << QByteArray("voidSignalCustomUnregisteredTypeArg")) << (QList<QByteArray>() << QByteArray("voidSignalCustomUnregisteredTypeArg"))
<< QMetaMethod::Public << QMetaMethod::Public
@ -390,7 +394,7 @@ void tst_QMetaMethod::method_data()
QTest::newRow("voidInvokableCustomUnregisteredType") QTest::newRow("voidInvokableCustomUnregisteredType")
<< QByteArray("voidInvokableCustomUnregisteredType(CustomUnregisteredType)") << QByteArray("voidInvokableCustomUnregisteredType(CustomUnregisteredType)")
<< int(QMetaType::Void) << QByteArray("void") << int(QMetaType::Void) << QByteArray("void")
<< (QList<int>() << 0) << (QList<int>() << QMetaType::fromType<CustomUnregisteredType>().id())
<< (QList<QByteArray>() << QByteArray("CustomUnregisteredType")) << (QList<QByteArray>() << QByteArray("CustomUnregisteredType"))
<< (QList<QByteArray>() << QByteArray("voidInvokableCustomUnregisteredTypeArg")) << (QList<QByteArray>() << QByteArray("voidInvokableCustomUnregisteredTypeArg"))
<< QMetaMethod::Public << QMetaMethod::Public
@ -399,7 +403,7 @@ void tst_QMetaMethod::method_data()
QTest::newRow("voidSlotCustomUnregisteredType") QTest::newRow("voidSlotCustomUnregisteredType")
<< QByteArray("voidSlotCustomUnregisteredType(CustomUnregisteredType)") << QByteArray("voidSlotCustomUnregisteredType(CustomUnregisteredType)")
<< int(QMetaType::Void) << QByteArray("void") << int(QMetaType::Void) << QByteArray("void")
<< (QList<int>() << 0) << (QList<int>() << QMetaType::fromType<CustomUnregisteredType>().id())
<< (QList<QByteArray>() << QByteArray("CustomUnregisteredType")) << (QList<QByteArray>() << QByteArray("CustomUnregisteredType"))
<< (QList<QByteArray>() << QByteArray("voidSlotCustomUnregisteredTypeArg")) << (QList<QByteArray>() << QByteArray("voidSlotCustomUnregisteredTypeArg"))
<< QMetaMethod::Public << QMetaMethod::Public
@ -408,7 +412,7 @@ void tst_QMetaMethod::method_data()
QTest::newRow("MethodTestObject(CustomUnregisteredType)") QTest::newRow("MethodTestObject(CustomUnregisteredType)")
<< QByteArray("MethodTestObject(CustomUnregisteredType)") << QByteArray("MethodTestObject(CustomUnregisteredType)")
<< int(QMetaType::UnknownType) << QByteArray("") << int(QMetaType::UnknownType) << QByteArray("")
<< (QList<int>() << 0) << (QList<int>() << QMetaType::fromType<CustomUnregisteredType>().id())
<< (QList<QByteArray>() << QByteArray("CustomUnregisteredType")) << (QList<QByteArray>() << QByteArray("CustomUnregisteredType"))
<< (QList<QByteArray>() << QByteArray("constructorCustomUnregisteredTypeArg")) << (QList<QByteArray>() << QByteArray("constructorCustomUnregisteredTypeArg"))
<< QMetaMethod::Public << QMetaMethod::Public
@ -770,6 +774,59 @@ void tst_QMetaMethod::gadget()
} }
} }
class MyTestClass : public QObject
{
Q_OBJECT
public:
MyTestClass() {};
public Q_SLOTS:
MyGadget doStuff(int, float, MyGadget) {return {};}
Q_SIGNALS:
QObject *mySignal();
};
void tst_QMetaMethod::returnMetaType()
{
{
QMetaMethod mm = QMetaMethod::fromSignal(&MyTestClass::mySignal);
QCOMPARE(mm.returnMetaType(), QMetaType::fromType<QObject*>());
}
auto mo = MyTestClass::staticMetaObject;
{
const auto normalized = QMetaObject::normalizedSignature("doStuff(int, float, MyGadget)");
const int idx = mo.indexOfSlot(normalized);
QMetaMethod mm = mo.method(idx);
QVERIFY(mm.isValid());
QCOMPARE(mm.returnMetaType(), QMetaType::fromType<MyGadget>());
}
{
// access of parent class meta methods works, too
const auto normalized = QMetaObject::normalizedSignature("deleteLater()");
const int idx = mo.indexOfSlot(normalized);
QMetaMethod mm = mo.method(idx);
QVERIFY(mm.isValid());
QCOMPARE(mm.returnMetaType(), QMetaType::fromType<void>());
}
}
void tst_QMetaMethod::parameterMetaType()
{
auto mo = MyTestClass::staticMetaObject;
const auto normalized = QMetaObject::normalizedSignature("doStuff(int, float, MyGadget)");
const int idx = mo.indexOfSlot(normalized);
QMetaMethod mm = mo.method(idx);
{
QVERIFY(!mm.parameterMetaType(-1).isValid());
QVERIFY(!mm.parameterMetaType(3).isValid());
}
{
QCOMPARE(mm.parameterMetaType(0), QMetaType::fromType<int>());
QCOMPARE(mm.parameterMetaType(1), QMetaType::fromType<float>());
QCOMPARE(mm.parameterMetaType(2), QMetaType::fromType<MyGadget>());
}
}
QTEST_MAIN(tst_QMetaMethod) QTEST_MAIN(tst_QMetaMethod)
#include "tst_qmetamethod.moc" #include "tst_qmetamethod.moc"

View File

@ -1391,7 +1391,7 @@ private:
}; };
QMetaObject TestObject::staticMetaObject = { QMetaObject TestObject::staticMetaObject = {
{ nullptr, nullptr, nullptr, nullptr, nullptr, nullptr } { nullptr, nullptr, nullptr, nullptr, nullptr, nullptr, nullptr}
}; };
TestObject::TestObject(QObject *parent) TestObject::TestObject(QObject *parent)

View File

@ -5278,6 +5278,8 @@ void tst_QObject::connectForwardDeclare()
QVERIFY(connect(&ob, &ForwardDeclareArguments::mySignal, &ob, &ForwardDeclareArguments::mySlot, Qt::QueuedConnection)); QVERIFY(connect(&ob, &ForwardDeclareArguments::mySignal, &ob, &ForwardDeclareArguments::mySlot, Qt::QueuedConnection));
} }
class ForwardDeclared {}; // complete definition for moc
class NoDefaultConstructor class NoDefaultConstructor
{ {
Q_GADGET Q_GADGET

View File

@ -30,6 +30,7 @@
#define FORWARD_DECLARED_PARAM_H #define FORWARD_DECLARED_PARAM_H
#include <qobject.h> #include <qobject.h>
#include <qmetatype.h> #include <qmetatype.h>
Q_MOC_INCLUDE("forwarddeclaredparam.h")
// test support for const refs to forward-declared structs in parameters // test support for const refs to forward-declared structs in parameters

View File

@ -0,0 +1,5 @@
#ifndef FORWARDDECLAREDPARAM_H
#define FORWARDDECLAREDPARAM_H
struct ForwardDeclaredParam {};
template <typename T> class ForwardDeclaredContainer {};
#endif

View File

@ -30,6 +30,7 @@
#define PARSE_DEFINES_H #define PARSE_DEFINES_H
#include <qobject.h> #include <qobject.h>
Q_MOC_INCLUDE(<QMap>)
// this is intentionally ugly to test moc's preprocessing capabilities // this is intentionally ugly to test moc's preprocessing capabilities
#define PD_NAMESPACE PD #define PD_NAMESPACE PD

View File

@ -1773,14 +1773,20 @@ public slots:
QString const returnConstString2( QString const s) { return s; } QString const returnConstString2( QString const s) { return s; }
}; };
struct science_constant {};
struct science_const {};
struct constconst {};
struct const_ {};
class QTBUG9354_constInName: public QObject class QTBUG9354_constInName: public QObject
{ Q_OBJECT { Q_OBJECT
public slots: public slots:
void slotChooseScientificConst0(struct science_constant const &) {}; void slotChooseScientificConst0(science_constant const &) {};
void foo(struct science_const const &) {}; void foo(science_const const &) {};
void foo(struct constconst const &) {}; void foo(constconst const &) {};
void foo(struct constconst *) {}; void foo(constconst *) {};
void foo(struct const_ *) {}; void foo(const_ *) {};
}; };

View File

@ -30,14 +30,15 @@
#define QDBUSCPP2XML_TEST1_H #define QDBUSCPP2XML_TEST1_H
#include <QObject> #include <QObject>
#include <QtDBus/QDBusSignature>
class QDBusObjectPath; #include <QtDBus/QDBusObjectPath>
class QDBusUnixFileDescriptor; #include <QtDBus/QDBusUnixFileDescriptor>
class QDBusSignature;
class Test1 : public QObject class Test1 : public QObject
{ {
Q_OBJECT Q_OBJECT
Q_MOC_INCLUDE(<QtDBus/qdbusextratypes.h>)
Q_MOC_INCLUDE(<QtDBus/qdbusunixfiledescriptor.h>)
Q_CLASSINFO("D-Bus Interface", "org.qtProject.qdbuscpp2xmlTests.Test1") Q_CLASSINFO("D-Bus Interface", "org.qtProject.qdbuscpp2xmlTests.Test1")
Q_PROPERTY(int numProperty1 READ numProperty1 CONSTANT) Q_PROPERTY(int numProperty1 READ numProperty1 CONSTANT)
Q_PROPERTY(int numProperty2 READ numProperty2 WRITE setNumProperty2) Q_PROPERTY(int numProperty2 READ numProperty2 WRITE setNumProperty2)