summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--src/corelib/kernel/qmetaobject.cpp35
-rw-r--r--src/corelib/kernel/qmetaobject_p.h6
-rw-r--r--src/corelib/kernel/qobject.cpp128
-rw-r--r--src/corelib/kernel/qobject_p.h10
-rw-r--r--src/corelib/kernel/qobjectdefs.h7
-rw-r--r--src/tools/moc/generator.cpp157
-rw-r--r--src/tools/moc/generator.h2
-rw-r--r--src/tools/moc/moc.cpp6
-rw-r--r--src/tools/moc/moc.h3
-rw-r--r--src/tools/moc/outputrevision.h2
10 files changed, 221 insertions, 135 deletions
diff --git a/src/corelib/kernel/qmetaobject.cpp b/src/corelib/kernel/qmetaobject.cpp
index c5775f6..4bf4290 100644
--- a/src/corelib/kernel/qmetaobject.cpp
+++ b/src/corelib/kernel/qmetaobject.cpp
@@ -218,12 +218,20 @@ QObject *QMetaObject::newInstance(QGenericArgument val0,
*/
int QMetaObject::static_metacall(Call cl, int idx, void **argv) const
{
- if (priv(d.data)->revision < 2)
- return 0;
- const QMetaObjectExtraData *extra = (const QMetaObjectExtraData*)(d.extradata);
- if (!extra || !extra->static_metacall)
- return 0;
- return extra->static_metacall(cl, idx, argv);
+ const QMetaObjectExtraData *extra = reinterpret_cast<const QMetaObjectExtraData *>(d.extradata);
+ if (priv(d.data)->revision >= 6) {
+ if (!extra || !extra->static_metacall)
+ return 0;
+ extra->static_metacall(0, cl, idx, argv);
+ return -1;
+ } else if (priv(d.data)->revision >= 2) {
+ if (!extra || !extra->static_metacall)
+ return 0;
+ typedef int (*OldMetacall)(QMetaObject::Call, int, void **);
+ OldMetacall o = reinterpret_cast<OldMetacall>(extra->static_metacall);
+ return o(cl, idx, argv);
+ }
+ return 0;
}
/*!
@@ -639,20 +647,21 @@ int QMetaObjectPrivate::indexOfSignalRelative(const QMetaObject **baseObject,
*/
int QMetaObject::indexOfSlot(const char *slot) const
{
- int i = QMetaObjectPrivate::indexOfSlot(this, slot, false);
+ const QMetaObject *m = this;
+ int i = QMetaObjectPrivate::indexOfSlotRelative(&m, slot, false);
if (i < 0)
- i = QMetaObjectPrivate::indexOfSlot(this, slot, true);
+ i = QMetaObjectPrivate::indexOfSlotRelative(&m, slot, true);
+ if (i >= 0)
+ i += methodOffset();
return i;
}
-int QMetaObjectPrivate::indexOfSlot(const QMetaObject *m,
+// same as indexOfSignalRelative but for slots.
+int QMetaObjectPrivate::indexOfSlotRelative(const QMetaObject **m,
const char *slot,
bool normalizeStringData)
{
- int i = indexOfMethodRelative<MethodSlot>(&m, slot, normalizeStringData);
- if (i >= 0)
- i += m->methodOffset();
- return i;
+ return indexOfMethodRelative<MethodSlot>(m, slot, normalizeStringData);
}
static const QMetaObject *QMetaObject_findMetaObject(const QMetaObject *self, const char *name)
diff --git a/src/corelib/kernel/qmetaobject_p.h b/src/corelib/kernel/qmetaobject_p.h
index 210b32c..fdadf4a 100644
--- a/src/corelib/kernel/qmetaobject_p.h
+++ b/src/corelib/kernel/qmetaobject_p.h
@@ -118,6 +118,7 @@ struct QMetaObjectPrivate
int flags; //since revision 3
int signalCount; //since revision 4
// revision 5 introduces changes in normalized signatures, no new members
+ // revision 6 added qt_static_metacall as a member of each Q_OBJECT and inside QMetaObject itself
static inline const QMetaObjectPrivate *get(const QMetaObject *metaobject)
{ return reinterpret_cast<const QMetaObjectPrivate*>(metaobject->d.data); }
@@ -125,7 +126,7 @@ struct QMetaObjectPrivate
static int indexOfSignalRelative(const QMetaObject **baseObject,
const char* name,
bool normalizeStringData);
- static int indexOfSlot(const QMetaObject *m,
+ static int indexOfSlotRelative(const QMetaObject **m,
const char *slot,
bool normalizeStringData);
static int originalClone(const QMetaObject *obj, int local_method_index);
@@ -136,7 +137,8 @@ struct QMetaObjectPrivate
static void memberIndexes(const QObject *obj, const QMetaMethod &member,
int *signalIndex, int *methodIndex);
static bool connect(const QObject *sender, int signal_index,
- const QObject *receiver, int method_index,
+ const QObject *receiver, int method_index_relative,
+ const QMetaObject *rmeta = 0,
int type = 0, int *types = 0);
static bool disconnect(const QObject *sender, int signal_index,
const QObject *receiver, int method_index,
diff --git a/src/corelib/kernel/qobject.cpp b/src/corelib/kernel/qobject.cpp
index c6f2456..4cbeee2 100644
--- a/src/corelib/kernel/qobject.cpp
+++ b/src/corelib/kernel/qobject.cpp
@@ -2607,18 +2607,17 @@ bool QObject::connect(const QObject *sender, const char *signal,
++method; // skip code
const QMetaObject *rmeta = receiver->metaObject();
- int method_index = -1;
+ int method_index_relative = -1;
switch (membcode) {
case QSLOT_CODE:
- method_index = QMetaObjectPrivate::indexOfSlot(rmeta, method, false);
+ method_index_relative = QMetaObjectPrivate::indexOfSlotRelative(&rmeta, method, false);
break;
case QSIGNAL_CODE:
- method_index = QMetaObjectPrivate::indexOfSignalRelative(&rmeta, method, false);
- if (method_index >= 0)
- method_index += rmeta->methodOffset();
+ method_index_relative = QMetaObjectPrivate::indexOfSignalRelative(&rmeta, method, false);
break;
}
- if (method_index < 0) {
+
+ if (method_index_relative < 0) {
// check for normalized methods
tmp_method_name = QMetaObject::normalizedSignature(method);
method = tmp_method_name.constData();
@@ -2627,19 +2626,24 @@ bool QObject::connect(const QObject *sender, const char *signal,
rmeta = receiver->metaObject();
switch (membcode) {
case QSLOT_CODE:
- method_index = rmeta->indexOfSlot(method);
+ method_index_relative = QMetaObjectPrivate::indexOfSlotRelative(&rmeta, method, false);
+ if (method_index_relative < 0)
+ method_index_relative = QMetaObjectPrivate::indexOfSlotRelative(&rmeta, method, true);
break;
case QSIGNAL_CODE:
- method_index = rmeta->indexOfSignal(method);
+ method_index_relative = QMetaObjectPrivate::indexOfSignalRelative(&rmeta, method, false);
+ if (method_index_relative < 0)
+ method_index_relative = QMetaObjectPrivate::indexOfSignalRelative(&rmeta, method, true);
break;
}
}
- if (method_index < 0) {
+ if (method_index_relative < 0) {
err_method_notfound(receiver, method_arg, "connect");
err_info_about_objects("connect", sender, receiver);
return false;
}
+
if (!QMetaObject::checkConnectArgs(signal, method)) {
qWarning("QObject::connect: Incompatible sender/receiver arguments"
"\n %s::%s --> %s::%s",
@@ -2654,14 +2658,13 @@ bool QObject::connect(const QObject *sender, const char *signal,
return false;
#ifndef QT_NO_DEBUG
- {
+ if (warnCompat) {
QMetaMethod smethod = smeta->method(signal_absolute_index);
- QMetaMethod rmethod = rmeta->method(method_index);
- if (warnCompat)
- check_and_warn_compat(smeta, smethod, rmeta, rmethod);
+ QMetaMethod rmethod = rmeta->method(method_index_relative + rmeta->methodOffset());
+ check_and_warn_compat(smeta, smethod, rmeta, rmethod);
}
#endif
- if (!QMetaObjectPrivate::connect(sender, signal_index, receiver, method_index, type, types))
+ if (!QMetaObjectPrivate::connect(sender, signal_index, receiver, method_index_relative, rmeta ,type, types))
return false;
const_cast<QObject*>(sender)->connectNotify(signal - 1);
return true;
@@ -2766,7 +2769,7 @@ bool QObject::connect(const QObject *sender, const QMetaMethod &signal,
if (warnCompat)
check_and_warn_compat(smeta, signal, rmeta, method);
#endif
- if (!QMetaObjectPrivate::connect(sender, signal_index, receiver, method_index, type, types))
+ if (!QMetaObjectPrivate::connect(sender, signal_index, receiver, method_index, 0, type, types))
return false;
const_cast<QObject*>(sender)->connectNotify(signalSignature.constData());
@@ -3157,18 +3160,28 @@ bool QMetaObject::connect(const QObject *sender, int signal_index,
{
signal_index = methodIndexToSignalIndex(sender->metaObject(), signal_index);
return QMetaObjectPrivate::connect(sender, signal_index,
- receiver, method_index, type, types);
+ receiver, method_index,
+ 0, //FIXME, we could speed this connection up by computing the relative index
+ type, types);
}
/*! \internal
Same as the QMetaObject::connect, but \a signal_index must be the result of QObjectPrivate::signalIndex
+
+ method_index is relative to the rmeta metaobject, if rmeta is null, then it is absolute index
*/
bool QMetaObjectPrivate::connect(const QObject *sender, int signal_index,
- const QObject *receiver, int method_index, int type, int *types)
+ const QObject *receiver, int method_index,
+ const QMetaObject *rmeta, int type, int *types)
{
QObject *s = const_cast<QObject *>(sender);
QObject *r = const_cast<QObject *>(receiver);
+ int method_offset = rmeta ? rmeta->methodOffset() : 0;
+ QObjectPrivate::StaticMetaCallFunction callFunction =
+ (rmeta && QMetaObjectPrivate::get(rmeta)->revision >= 6 && rmeta->d.extradata)
+ ? reinterpret_cast<const QMetaObjectExtraData *>(rmeta->d.extradata)->static_metacall : 0;
+
QOrderedMutexLocker locker(signalSlotLock(sender),
signalSlotLock(receiver));
@@ -3178,8 +3191,10 @@ bool QMetaObjectPrivate::connect(const QObject *sender, int signal_index,
const QObjectPrivate::Connection *c2 =
(*connectionLists)[signal_index].first;
+ int method_index_absolute = method_index + method_offset;
+
while (c2) {
- if (c2->receiver == receiver && c2->method == method_index)
+ if (c2->receiver == receiver && c2->method() == method_index_absolute)
return false;
c2 = c2->nextConnectionList;
}
@@ -3190,10 +3205,12 @@ bool QMetaObjectPrivate::connect(const QObject *sender, int signal_index,
QObjectPrivate::Connection *c = new QObjectPrivate::Connection;
c->sender = s;
c->receiver = r;
- c->method = method_index;
+ c->method_relative = method_index;
+ c->method_offset = method_offset;
c->connectionType = type;
c->argumentTypes = types;
c->nextConnectionList = 0;
+ c->callFunction = callFunction;
QT_TRY {
QObjectPrivate::get(s)->addConnection(signal_index, c);
@@ -3254,7 +3271,7 @@ bool QMetaObjectPrivate::disconnectHelper(QObjectPrivate::Connection *c,
while (c) {
if (c->receiver
&& (receiver == 0 || (c->receiver == receiver
- && (method_index < 0 || c->method == method_index)))) {
+ && (method_index < 0 || c->method() == method_index)))) {
bool needToUnlock = false;
QMutex *receiverMutex = 0;
if (!receiver) {
@@ -3428,7 +3445,7 @@ static void queued_activate(QObject *sender, int signal, QObjectPrivate::Connect
args[0] = 0; // return value
for (int n = 1; n < nargs; ++n)
args[n] = QMetaType::construct((types[n] = c->argumentTypes[n-1]), argv[n]);
- QCoreApplication::postEvent(c->receiver, new QMetaCallEvent(c->method,
+ QCoreApplication::postEvent(c->receiver, new QMetaCallEvent(c->method(),
sender,
signal,
nargs,
@@ -3503,7 +3520,6 @@ void QMetaObject::activate(QObject *sender, const QMetaObject *m, int local_sign
continue;
QObject * const receiver = c->receiver;
- const int method = c->method;
const bool receiverInSameThread = currentThreadId == receiver->d_func()->threadData->threadId;
// determine if this connection should be sent immediately or
@@ -3514,6 +3530,7 @@ void QMetaObject::activate(QObject *sender, const QMetaObject *m, int local_sign
continue;
#ifndef QT_NO_THREAD
} else if (c->connectionType == Qt::BlockingQueuedConnection) {
+ const int method = c->method();
locker.unlock();
if (receiverInSameThread) {
qWarning("Qt: Dead lock detected while activating a BlockingQueuedConnection: "
@@ -3532,6 +3549,7 @@ void QMetaObject::activate(QObject *sender, const QMetaObject *m, int local_sign
continue;
#endif
}
+
QObjectPrivate::Sender currentSender;
QObjectPrivate::Sender *previousSender = 0;
if (receiverInSameThread) {
@@ -3540,36 +3558,52 @@ void QMetaObject::activate(QObject *sender, const QMetaObject *m, int local_sign
currentSender.ref = 1;
previousSender = QObjectPrivate::setCurrentSender(receiver, &currentSender);
}
- locker.unlock();
+ const QObjectPrivate::StaticMetaCallFunction callFunction = c->callFunction;
+ const int method_relative = c->method_relative;
+ if (callFunction && c->method_offset <= receiver->metaObject()->methodOffset()) {
+ //we compare the vtable to make sure we are not in the destructor of the object.
+ locker.unlock();
+ if (qt_signal_spy_callback_set.slot_begin_callback != 0)
+ qt_signal_spy_callback_set.slot_begin_callback(receiver, c->method(), argv ? argv : empty_argv);
- if (qt_signal_spy_callback_set.slot_begin_callback != 0) {
- qt_signal_spy_callback_set.slot_begin_callback(receiver,
- method,
- argv ? argv : empty_argv);
- }
+ callFunction(receiver, QMetaObject::InvokeMetaMethod, method_relative, argv ? argv : empty_argv);
-#if defined(QT_NO_EXCEPTIONS)
- metacall(receiver, QMetaObject::InvokeMetaMethod, method, argv ? argv : empty_argv);
-#else
- QT_TRY {
- metacall(receiver, QMetaObject::InvokeMetaMethod, method, argv ? argv : empty_argv);
- } QT_CATCH(...) {
+ if (qt_signal_spy_callback_set.slot_end_callback != 0)
+ qt_signal_spy_callback_set.slot_end_callback(receiver, c->method());
locker.relock();
- if (receiverInSameThread)
- QObjectPrivate::resetCurrentSender(receiver, &currentSender, previousSender);
+ } else {
+ const int method = method_relative + c->method_offset;
+ locker.unlock();
- --connectionLists->inUse;
- Q_ASSERT(connectionLists->inUse >= 0);
- if (connectionLists->orphaned && !connectionLists->inUse)
- delete connectionLists;
- QT_RETHROW;
- }
+ if (qt_signal_spy_callback_set.slot_begin_callback != 0) {
+ qt_signal_spy_callback_set.slot_begin_callback(receiver,
+ method,
+ argv ? argv : empty_argv);
+ }
+
+#if defined(QT_NO_EXCEPTIONS)
+ metacall(receiver, QMetaObject::InvokeMetaMethod, method, argv ? argv : empty_argv);
+#else
+ QT_TRY {
+ metacall(receiver, QMetaObject::InvokeMetaMethod, method, argv ? argv : empty_argv);
+ } QT_CATCH(...) {
+ locker.relock();
+ if (receiverInSameThread)
+ QObjectPrivate::resetCurrentSender(receiver, &currentSender, previousSender);
+
+ --connectionLists->inUse;
+ Q_ASSERT(connectionLists->inUse >= 0);
+ if (connectionLists->orphaned && !connectionLists->inUse)
+ delete connectionLists;
+ QT_RETHROW;
+ }
#endif
- if (qt_signal_spy_callback_set.slot_end_callback != 0)
- qt_signal_spy_callback_set.slot_end_callback(receiver, method);
+ if (qt_signal_spy_callback_set.slot_end_callback != 0)
+ qt_signal_spy_callback_set.slot_end_callback(receiver, method);
- locker.relock();
+ locker.relock();
+ }
if (receiverInSameThread)
QObjectPrivate::resetCurrentSender(receiver, &currentSender, previousSender);
@@ -3870,7 +3904,7 @@ void QObject::dumpObjectInfo()
continue;
}
const QMetaObject *receiverMetaObject = c->receiver->metaObject();
- const QMetaMethod method = receiverMetaObject->method(c->method);
+ const QMetaMethod method = receiverMetaObject->method(c->method());
qDebug(" --> %s::%s %s",
receiverMetaObject->className(),
c->receiver->objectName().isEmpty() ? "unnamed" : qPrintable(c->receiver->objectName()),
@@ -3887,7 +3921,7 @@ void QObject::dumpObjectInfo()
if (d->senders) {
for (QObjectPrivate::Connection *s = d->senders; s; s = s->next) {
- const QMetaMethod slot = metaObject()->method(s->method);
+ const QMetaMethod slot = metaObject()->method(s->method());
qDebug(" <-- %s::%s %s",
s->sender->metaObject()->className(),
s->sender->objectName().isEmpty() ? "unnamed" : qPrintable(s->sender->objectName()),
diff --git a/src/corelib/kernel/qobject_p.h b/src/corelib/kernel/qobject_p.h
index c7555be..71b5bee 100644
--- a/src/corelib/kernel/qobject_p.h
+++ b/src/corelib/kernel/qobject_p.h
@@ -108,19 +108,23 @@ public:
QList<QVariant> propertyValues;
};
+ typedef void (*StaticMetaCallFunction)(QObject *, QMetaObject::Call, int, void **);
struct Connection
{
QObject *sender;
QObject *receiver;
- int method;
- uint connectionType : 3; // 0 == auto, 1 == direct, 2 == queued, 4 == blocking
- QBasicAtomicPointer<int> argumentTypes;
+ StaticMetaCallFunction callFunction;
// The next pointer for the singly-linked ConnectionList
Connection *nextConnectionList;
//senders linked list
Connection *next;
Connection **prev;
+ QBasicAtomicPointer<int> argumentTypes;
+ ushort method_offset;
+ ushort method_relative;
+ ushort connectionType : 3; // 0 == auto, 1 == direct, 2 == queued, 4 == blocking
~Connection();
+ int method() const { return method_offset + method_relative; }
};
// ConnectionList is a singly-linked list
struct ConnectionList {
diff --git a/src/corelib/kernel/qobjectdefs.h b/src/corelib/kernel/qobjectdefs.h
index 54b5ab2..6bf40f7 100644
--- a/src/corelib/kernel/qobjectdefs.h
+++ b/src/corelib/kernel/qobjectdefs.h
@@ -55,7 +55,7 @@ class QByteArray;
class QString;
#ifndef Q_MOC_OUTPUT_REVISION
-#define Q_MOC_OUTPUT_REVISION 62
+#define Q_MOC_OUTPUT_REVISION 63
#endif
// The following macros are our "extensions" to C++
@@ -163,6 +163,7 @@ public: \
virtual void *qt_metacast(const char *); \
QT_TR_FUNCTIONS \
virtual int qt_metacall(QMetaObject::Call, int, void **); \
+ static void qt_static_metacall(QObject *, QMetaObject::Call, int, void **); \
private:
/* tmake ignore Q_OBJECT */
#define Q_OBJECT_FAKE Q_OBJECT
@@ -468,7 +469,6 @@ struct Q_CORE_EXPORT QMetaObject
const uint *data;
const void *extradata;
} d;
-
};
typedef const QMetaObject& (*QMetaObjectAccessor)();
@@ -480,7 +480,8 @@ struct QMetaObjectExtraData
#else
const QMetaObject **objects;
#endif
- int (*static_metacall)(QMetaObject::Call, int, void **);
+ void (*static_metacall)(QObject *, QMetaObject::Call, int, void **); //from revision 6
+ //int (*static_metacall)(QMetaObject::Call, int, void **); //used from revison 2 until revison 5
};
inline const char *QMetaObject::className() const
diff --git a/src/tools/moc/generator.cpp b/src/tools/moc/generator.cpp
index 4df7ae5..ac769d7 100644
--- a/src/tools/moc/generator.cpp
+++ b/src/tools/moc/generator.cpp
@@ -173,7 +173,7 @@ void Generator::generateCode()
int index = 14;
fprintf(out, "static const uint qt_meta_data_%s[] = {\n", qualifiedClassNameIdentifier.constData());
fprintf(out, "\n // content:\n");
- fprintf(out, " %4d, // revision\n", 5);
+ fprintf(out, " %4d, // revision\n", 6);
fprintf(out, " %4d, // classname\n", strreg(cdef->qualified));
fprintf(out, " %4d, %4d, // classinfo\n", cdef->classInfoList.count(), cdef->classInfoList.count() ? index : 0);
index += cdef->classInfoList.count() * 2;
@@ -291,12 +291,11 @@ void Generator::generateCode()
}
fprintf(out, "\"\n};\n\n");
-
//
// Generate internal qt_static_metacall() function
//
- if (isConstructible)
- generateStaticMetacall(qualifiedClassNameIdentifier);
+ if (cdef->hasQObject && !isQt)
+ generateStaticMetacall();
//
// Build extra array
@@ -329,17 +328,19 @@ void Generator::generateCode()
fprintf(out, " 0\n};\n\n");
}
- if (isConstructible || !extraList.isEmpty()) {
+ bool hasExtraData = (cdef->hasQObject && !isQt) || !extraList.isEmpty();
+ if (hasExtraData) {
fprintf(out, "static const QMetaObjectExtraData qt_meta_extradata2_%s = {\n ",
qualifiedClassNameIdentifier.constData());
if (extraList.isEmpty())
fprintf(out, "0, ");
else
fprintf(out, "qt_meta_extradata_%s, ", qualifiedClassNameIdentifier.constData());
- if (!isConstructible)
- fprintf(out, "0");
+
+ if (cdef->hasQObject && !isQt)
+ fprintf(out, " %s::qt_static_metacall", cdef->qualified.constData());
else
- fprintf(out, "%s_qt_static_metacall", qualifiedClassNameIdentifier.constData());
+ fprintf(out, " 0");
fprintf(out, " \n};\n\n");
}
@@ -359,7 +360,7 @@ void Generator::generateCode()
fprintf(out, " { 0, ");
fprintf(out, "qt_meta_stringdata_%s,\n qt_meta_data_%s, ",
qualifiedClassNameIdentifier.constData(), qualifiedClassNameIdentifier.constData());
- if (!isConstructible && extraList.isEmpty())
+ if (!hasExtraData)
fprintf(out, "0 }\n");
else
fprintf(out, "&qt_meta_extradata2_%s }\n", qualifiedClassNameIdentifier.constData());
@@ -657,34 +658,11 @@ void Generator::generateMetacall()
if (methodList.size()) {
needElse = true;
- fprintf(out, "if (_c == QMetaObject::InvokeMetaMethod) {\n ");
- fprintf(out, "switch (_id) {\n");
- for (int methodindex = 0; methodindex < methodList.size(); ++methodindex) {
- const FunctionDef &f = methodList.at(methodindex);
- fprintf(out, " case %d: ", methodindex);
- if (f.normalizedType.size())
- fprintf(out, "{ %s _r = ", noRef(f.normalizedType).constData());
- if (f.inPrivateClass.size())
- fprintf(out, "%s->", f.inPrivateClass.constData());
- fprintf(out, "%s(", f.name.constData());
- int offset = 1;
- for (int j = 0; j < f.arguments.count(); ++j) {
- const ArgumentDef &a = f.arguments.at(j);
- if (j)
- fprintf(out, ",");
- fprintf(out, "(*reinterpret_cast< %s>(_a[%d]))",a.typeNameForCast.constData(), offset++);
- }
- fprintf(out, ");");
- if (f.normalizedType.size())
- fprintf(out, "\n if (_a[0]) *reinterpret_cast< %s*>(_a[0]) = _r; } ",
- noRef(f.normalizedType).constData());
- fprintf(out, " break;\n");
- }
- fprintf(out, " default: ;\n");
- fprintf(out, " }\n");
- }
- if (methodList.size())
+ fprintf(out, "if (_c == QMetaObject::InvokeMetaMethod) {\n");
+ fprintf(out, " if (_id < %d)\n", methodList.size());
+ fprintf(out, " qt_static_metacall(this, _c, _id, _a);\n");
fprintf(out, " _id -= %d;\n }", methodList.size());
+ }
if (cdef->propertyList.size()) {
bool needGet = false;
@@ -900,40 +878,95 @@ void Generator::generateMetacall()
fprintf(out,"return _id;\n}\n");
}
-void Generator::generateStaticMetacall(const QByteArray &prefix)
+void Generator::generateStaticMetacall()
{
- bool isQObject = (cdef->classname == "QObject");
+ fprintf(out, "void %s::qt_static_metacall(QObject *_o, QMetaObject::Call _c, int _id, void **_a)\n{\n",
+ cdef->qualified.constData());
- fprintf(out, "static int %s_qt_static_metacall(QMetaObject::Call _c, int _id, void **_a)\n{\n",
- prefix.constData());
+ bool needElse = false;
+ bool isUsed_a = false;
+
+ if (!cdef->constructorList.isEmpty()) {
+ fprintf(out, " if (_c == QMetaObject::CreateInstance) {\n");
+ fprintf(out, " switch (_id) {\n");
+ for (int ctorindex = 0; ctorindex < cdef->constructorList.count(); ++ctorindex) {
+ fprintf(out, " case %d: { %s *_r = new %s(", ctorindex,
+ cdef->classname.constData(), cdef->classname.constData());
+ const FunctionDef &f = cdef->constructorList.at(ctorindex);
+ int offset = 1;
+ for (int j = 0; j < f.arguments.count(); ++j) {
+ const ArgumentDef &a = f.arguments.at(j);
+ if (j)
+ fprintf(out, ",");
+ fprintf(out, "(*reinterpret_cast< %s>(_a[%d]))", a.typeNameForCast.constData(), offset++);
+ }
+ fprintf(out, ");\n");
+ fprintf(out, " if (_a[0]) *reinterpret_cast<QObject**>(_a[0]) = _r; } break;\n");
+ }
+ fprintf(out, " }\n");
+ fprintf(out, " }");
+ needElse = true;
+ isUsed_a = true;
+ }
- fprintf(out, " if (_c == QMetaObject::CreateInstance) {\n");
- fprintf(out, " switch (_id) {\n");
- for (int ctorindex = 0; ctorindex < cdef->constructorList.count(); ++ctorindex) {
- fprintf(out, " case %d: { %s *_r = new %s(", ctorindex,
- cdef->qualified.constData(), cdef->qualified.constData());
- const FunctionDef &f = cdef->constructorList.at(ctorindex);
- int offset = 1;
- for (int j = 0; j < f.arguments.count(); ++j) {
- const ArgumentDef &a = f.arguments.at(j);
- if (j)
- fprintf(out, ",");
- fprintf(out, "(*reinterpret_cast< %s>(_a[%d]))", a.typeNameForCast.constData(), offset++);
+ QList<FunctionDef> methodList;
+ methodList += cdef->signalList;
+ methodList += cdef->slotList;
+ methodList += cdef->methodList;
+
+ if (!methodList.isEmpty()) {
+ if (needElse)
+ fprintf(out, " else ");
+ else
+ fprintf(out, " ");
+ fprintf(out, "if (_c == QMetaObject::InvokeMetaMethod) {\n");
+ fprintf(out, " Q_ASSERT(qobject_cast<%s *>(_o));\n", cdef->classname.constData());
+ fprintf(out, " %s *_t = static_cast<%s *>(_o);\n", cdef->classname.constData(), cdef->classname.constData());
+ fprintf(out, " switch (_id) {\n");
+ for (int methodindex = 0; methodindex < methodList.size(); ++methodindex) {
+ const FunctionDef &f = methodList.at(methodindex);
+ fprintf(out, " case %d: ", methodindex);
+ if (f.normalizedType.size())
+ fprintf(out, "{ %s _r = ", noRef(f.normalizedType).constData());
+ fprintf(out, "_t->");
+ if (f.inPrivateClass.size())
+ fprintf(out, "%s->", f.inPrivateClass.constData());
+ fprintf(out, "%s(", f.name.constData());
+ int offset = 1;
+ for (int j = 0; j < f.arguments.count(); ++j) {
+ const ArgumentDef &a = f.arguments.at(j);
+ if (j)
+ fprintf(out, ",");
+ fprintf(out, "(*reinterpret_cast< %s>(_a[%d]))",a.typeNameForCast.constData(), offset++);
+ isUsed_a = true;
+ }
+ fprintf(out, ");");
+ if (f.normalizedType.size()) {
+ fprintf(out, "\n if (_a[0]) *reinterpret_cast< %s*>(_a[0]) = _r; } ",
+ noRef(f.normalizedType).constData());
+ isUsed_a = true;
+ }
+ fprintf(out, " break;\n");
}
- fprintf(out, ");\n");
- fprintf(out, " if (_a[0]) *reinterpret_cast<QObject**>(_a[0]) = _r; } break;\n");
+ fprintf(out, " default: ;\n");
+ fprintf(out, " }\n");
+ fprintf(out, " }");
+ needElse = true;
}
- fprintf(out, " }\n");
- fprintf(out, " _id -= %d;\n", cdef->constructorList.count());
- fprintf(out, " return _id;\n");
- fprintf(out, " }\n");
- if (!isQObject)
- fprintf(out, " _id = %s::staticMetaObject.superClass()->static_metacall(_c, _id, _a);\n", cdef->qualified.constData());
+ if (needElse)
+ fprintf(out, "\n");
- fprintf(out, " if (_id < 0)\n return _id;\n");
+ if (methodList.isEmpty()) {
+ fprintf(out, " Q_UNUSED(_o);\n");
+ if (cdef->constructorList.isEmpty()) {
+ fprintf(out, " Q_UNUSED(_id);\n");
+ fprintf(out, " Q_UNUSED(_c);\n");
+ }
+ }
+ if (!isUsed_a)
+ fprintf(out, " Q_UNUSED(_a);\n");
- fprintf(out, " return _id;\n");
fprintf(out, "}\n\n");
}
diff --git a/src/tools/moc/generator.h b/src/tools/moc/generator.h
index ed0980e..fa5885f 100644
--- a/src/tools/moc/generator.h
+++ b/src/tools/moc/generator.h
@@ -62,7 +62,7 @@ private:
void generateEnums(int index);
void generateProperties();
void generateMetacall();
- void generateStaticMetacall(const QByteArray &prefix);
+ void generateStaticMetacall();
void generateSignal(FunctionDef *def, int index);
// used by binary QMetaObject generator
diff --git a/src/tools/moc/moc.cpp b/src/tools/moc/moc.cpp
index 74b1ace..5078b28 100644
--- a/src/tools/moc/moc.cpp
+++ b/src/tools/moc/moc.cpp
@@ -356,8 +356,9 @@ bool Moc::testFunctionRevision(FunctionDef *def)
bool Moc::parseFunction(FunctionDef *def, bool inMacro)
{
def->isVirtual = false;
+ def->isStatic = false;
//skip modifiers and attributes
- while (test(INLINE) || test(STATIC) ||
+ while (test(INLINE) || (test(STATIC) && (def->isStatic = true)) ||
(test(VIRTUAL) && (def->isVirtual = true)) //mark as virtual
|| testFunctionAttribute(def) || testFunctionRevision(def)) {}
bool templateFunction = (lookup() == TEMPLATE);
@@ -447,8 +448,9 @@ bool Moc::parseFunction(FunctionDef *def, bool inMacro)
bool Moc::parseMaybeFunction(const ClassDef *cdef, FunctionDef *def)
{
def->isVirtual = false;
+ def->isStatic = false;
//skip modifiers and attributes
- while (test(EXPLICIT) || test(INLINE) || test(STATIC) ||
+ while (test(EXPLICIT) || test(INLINE) || (test(STATIC) && (def->isStatic = true)) ||
(test(VIRTUAL) && (def->isVirtual = true)) //mark as virtual
|| testFunctionAttribute(def) || testFunctionRevision(def)) {}
bool tilde = test(TILDE);
diff --git a/src/tools/moc/moc.h b/src/tools/moc/moc.h
index 38c3917..4049534 100644
--- a/src/tools/moc/moc.h
+++ b/src/tools/moc/moc.h
@@ -83,7 +83,7 @@ struct ArgumentDef
struct FunctionDef
{
- FunctionDef(): returnTypeIsVolatile(false), access(Private), isConst(false), isVirtual(false),
+ FunctionDef(): returnTypeIsVolatile(false), access(Private), isConst(false), isVirtual(false), isStatic(false),
inlineCode(false), wasCloned(false), isCompat(false), isInvokable(false),
isScriptable(false), isSlot(false), isSignal(false),
isConstructor(false), isDestructor(false), isAbstract(false), revision(0) {}
@@ -99,6 +99,7 @@ struct FunctionDef
Access access;
bool isConst;
bool isVirtual;
+ bool isStatic;
bool inlineCode;
bool wasCloned;
diff --git a/src/tools/moc/outputrevision.h b/src/tools/moc/outputrevision.h
index 7e2ca8b..104a373 100644
--- a/src/tools/moc/outputrevision.h
+++ b/src/tools/moc/outputrevision.h
@@ -43,6 +43,6 @@
#define OUTPUTREVISION_H
// if the output revision changes, you MUST change it in qobjectdefs.h too
-enum { mocOutputRevision = 62 }; // moc format output revision
+enum { mocOutputRevision = 63 }; // moc format output revision
#endif // OUTPUTREVISION_H