MetaObject: Store the QMetaType of the methods

This does the analog of 46f407126e 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;
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
{
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)
return QMetaType::UnknownType;
if (index >= QMetaMethodPrivate::get(this)->parameterCount())
return QMetaType::UnknownType;
int type = QMetaMethodPrivate::get(this)->parameterType(index);
if (type != QMetaType::UnknownType)
return type;
void *argv[] = { &type, &index };
mobj->static_metacall(QMetaObject::RegisterMethodArgumentMetaType, QMetaMethodPrivate::get(this)->ownMethodIndex(), argv);
if (type != -1)
return type;
return QMetaType::UnknownType;
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;

View File

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

View File

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

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

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

@ -48,6 +48,9 @@ private slots:
void fromSignal();
void gadget();
void returnMetaType();
void parameterMetaType();
};
struct CustomType { };
@ -378,10 +381,11 @@ void tst_QMetaMethod::method_data()
<< QMetaMethod::Public
<< QMetaMethod::Constructor;
// since Qt 6.0, parameter types get automatically registered
QTest::newRow("voidSignalCustomUnregisteredType")
<< QByteArray("voidSignalCustomUnregisteredType(CustomUnregisteredType)")
<< int(QMetaType::Void) << QByteArray("void")
<< (QList<int>() << 0)
<< (QList<int>() << QMetaType::fromType<CustomUnregisteredType>().id())
<< (QList<QByteArray>() << QByteArray("CustomUnregisteredType"))
<< (QList<QByteArray>() << QByteArray("voidSignalCustomUnregisteredTypeArg"))
<< QMetaMethod::Public
@ -390,7 +394,7 @@ void tst_QMetaMethod::method_data()
QTest::newRow("voidInvokableCustomUnregisteredType")
<< QByteArray("voidInvokableCustomUnregisteredType(CustomUnregisteredType)")
<< int(QMetaType::Void) << QByteArray("void")
<< (QList<int>() << 0)
<< (QList<int>() << QMetaType::fromType<CustomUnregisteredType>().id())
<< (QList<QByteArray>() << QByteArray("CustomUnregisteredType"))
<< (QList<QByteArray>() << QByteArray("voidInvokableCustomUnregisteredTypeArg"))
<< QMetaMethod::Public
@ -399,7 +403,7 @@ void tst_QMetaMethod::method_data()
QTest::newRow("voidSlotCustomUnregisteredType")
<< QByteArray("voidSlotCustomUnregisteredType(CustomUnregisteredType)")
<< int(QMetaType::Void) << QByteArray("void")
<< (QList<int>() << 0)
<< (QList<int>() << QMetaType::fromType<CustomUnregisteredType>().id())
<< (QList<QByteArray>() << QByteArray("CustomUnregisteredType"))
<< (QList<QByteArray>() << QByteArray("voidSlotCustomUnregisteredTypeArg"))
<< QMetaMethod::Public
@ -408,7 +412,7 @@ void tst_QMetaMethod::method_data()
QTest::newRow("MethodTestObject(CustomUnregisteredType)")
<< QByteArray("MethodTestObject(CustomUnregisteredType)")
<< int(QMetaType::UnknownType) << QByteArray("")
<< (QList<int>() << 0)
<< (QList<int>() << QMetaType::fromType<CustomUnregisteredType>().id())
<< (QList<QByteArray>() << QByteArray("CustomUnregisteredType"))
<< (QList<QByteArray>() << QByteArray("constructorCustomUnregisteredTypeArg"))
<< 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)
#include "tst_qmetamethod.moc"

View File

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

View File

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

View File

@ -30,6 +30,7 @@
#define FORWARD_DECLARED_PARAM_H
#include <qobject.h>
#include <qmetatype.h>
Q_MOC_INCLUDE("forwarddeclaredparam.h")
// 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
#include <qobject.h>
Q_MOC_INCLUDE(<QMap>)
// this is intentionally ugly to test moc's preprocessing capabilities
#define PD_NAMESPACE PD

View File

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

View File

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