summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--src/corelib/kernel/qobjectdefs.h3
-rw-r--r--src/tools/moc/generator.cpp29
-rw-r--r--src/tools/moc/moc.cpp6
-rw-r--r--src/tools/moc/moc.h6
-rw-r--r--tests/auto/corelib/kernel/qmetaobject/tst_qmetaobject.cpp22
5 files changed, 63 insertions, 3 deletions
diff --git a/src/corelib/kernel/qobjectdefs.h b/src/corelib/kernel/qobjectdefs.h
index 48d05cec46..c04b66480d 100644
--- a/src/corelib/kernel/qobjectdefs.h
+++ b/src/corelib/kernel/qobjectdefs.h
@@ -443,7 +443,8 @@ struct Q_CORE_EXPORT QMetaObject
QueryPropertyStored,
QueryPropertyEditable,
QueryPropertyUser,
- CreateInstance
+ CreateInstance,
+ IndexOfMethod
};
int static_metacall(Call, int, void **) const;
diff --git a/src/tools/moc/generator.cpp b/src/tools/moc/generator.cpp
index 1ed7de228a..9ad4d1bb68 100644
--- a/src/tools/moc/generator.cpp
+++ b/src/tools/moc/generator.cpp
@@ -954,6 +954,35 @@ void Generator::generateStaticMetacall()
}
fprintf(out, " default: ;\n");
fprintf(out, " }\n");
+
+ fprintf(out, " } else if (_c == QMetaObject::IndexOfMethod) {\n");
+ fprintf(out, " int *result = reinterpret_cast<int *>(_a[0]);\n");
+ fprintf(out, " void **func = reinterpret_cast<void **>(_a[1]);\n");
+ bool anythingUsed = false;
+ for (int methodindex = 0; methodindex < methodList.size(); ++methodindex) {
+ const FunctionDef &f = methodList.at(methodindex);
+ if (f.wasCloned || !f.inPrivateClass.isEmpty() || f.isStatic)
+ continue;
+ anythingUsed = true;
+ fprintf(out, " {\n");
+ fprintf(out, " typedef %s (%s::*_t)(",f.type.rawName.constData() , cdef->classname.constData());
+ for (int j = 0; j < f.arguments.count(); ++j) {
+ const ArgumentDef &a = f.arguments.at(j);
+ if (j)
+ fprintf(out, ", ");
+ fprintf(out, "%s", QByteArray(a.type.name + ' ' + a.rightType).constData());
+ }
+ if (f.isConst)
+ fprintf(out, ") const;\n");
+ else
+ fprintf(out, ");\n");
+ fprintf(out, " if (*reinterpret_cast<_t *>(func) == static_cast<_t>(&%s::%s)) {\n",
+ cdef->classname.constData(), f.name.constData());
+ fprintf(out, " *result = %d;\n", methodindex);
+ fprintf(out, " }\n }\n");
+ }
+ if (!anythingUsed)
+ fprintf(out, " Q_UNUSED(result);\n Q_UNUSED(func);\n");
fprintf(out, " }");
needElse = true;
}
diff --git a/src/tools/moc/moc.cpp b/src/tools/moc/moc.cpp
index 8999148108..6086eb0ddb 100644
--- a/src/tools/moc/moc.cpp
+++ b/src/tools/moc/moc.cpp
@@ -240,6 +240,7 @@ Type Moc::parseType()
else if (lookup(0) == STAR)
type.referenceType = Type::Pointer;
}
+ type.rawName = type.name;
// transform stupid things like 'const void' or 'void const' into 'void'
if (isVoid && type.referenceType == Type::NoReference) {
type.name = "void";
@@ -404,8 +405,11 @@ bool Moc::parseFunction(FunctionDef *def, bool inMacro)
}
// we don't support references as return types, it's too dangerous
- if (def->type.referenceType == Type::Reference)
+ if (def->type.referenceType == Type::Reference) {
+ QByteArray rawName = def->type.rawName;
def->type = Type("void");
+ def->type.rawName = rawName;
+ }
def->normalizedType = normalizeType(def->type.name);
diff --git a/src/tools/moc/moc.h b/src/tools/moc/moc.h
index 917cf69a51..5772a5a6ba 100644
--- a/src/tools/moc/moc.h
+++ b/src/tools/moc/moc.h
@@ -58,8 +58,12 @@ struct Type
enum ReferenceType { NoReference, Reference, RValueReference, Pointer };
inline Type() : isVolatile(false), isScoped(false), firstToken(NOTOKEN), referenceType(NoReference) {}
- inline explicit Type(const QByteArray &_name) : name(_name), isVolatile(false), isScoped(false), firstToken(NOTOKEN), referenceType(NoReference) {}
+ inline explicit Type(const QByteArray &_name)
+ : name(_name), rawName(name), isVolatile(false), isScoped(false), firstToken(NOTOKEN), referenceType(NoReference) {}
QByteArray name;
+ //When used as a return type, the type name may be modified to remove the references.
+ // rawName is the type as found in the function signature
+ QByteArray rawName;
uint isVolatile : 1;
uint isScoped : 1;
Token firstToken;
diff --git a/tests/auto/corelib/kernel/qmetaobject/tst_qmetaobject.cpp b/tests/auto/corelib/kernel/qmetaobject/tst_qmetaobject.cpp
index 2831d9fc34..e68f7e5ed1 100644
--- a/tests/auto/corelib/kernel/qmetaobject/tst_qmetaobject.cpp
+++ b/tests/auto/corelib/kernel/qmetaobject/tst_qmetaobject.cpp
@@ -174,6 +174,8 @@ private slots:
void indexOfMethod_data();
void indexOfMethod();
+ void indexOfMethodPMF();
+
signals:
void value6Changed();
void value7Changed(const QString &);
@@ -290,6 +292,7 @@ void tst_QMetaObject::connectSlotsByName()
class QtTestObject: public QObject
{
+ friend class tst_QMetaObject;
Q_OBJECT
public:
@@ -1115,6 +1118,25 @@ void tst_QMetaObject::indexOfMethod()
QCOMPARE(object->metaObject()->indexOfSignal(name), !isSignal ? -1 : idx);
}
+void tst_QMetaObject::indexOfMethodPMF()
+{
+#define INDEXOFMETHODPMF_HELPER(ObjectType, Name, Arguments) { \
+ int idx = -1; \
+ void (ObjectType::*signal)Arguments = &ObjectType::Name; \
+ void *signal_p = &signal; \
+ void *args[] = { &idx, signal_p, 0}; \
+ ObjectType::qt_static_metacall(0, QMetaObject::IndexOfMethod, 0, args); \
+ QCOMPARE(ObjectType::staticMetaObject.indexOfMethod(QMetaObject::normalizedSignature(#Name #Arguments)), \
+ ObjectType::staticMetaObject.methodOffset() + idx); \
+ }
+
+ INDEXOFMETHODPMF_HELPER(tst_QMetaObject, value7Changed, (const QString&))
+ INDEXOFMETHODPMF_HELPER(tst_QMetaObject, stdSet, ())
+ INDEXOFMETHODPMF_HELPER(QtTestObject, sl10, (QString,QString,QString,QString,QString,QString,QString,QString,QString,QString))
+ INDEXOFMETHODPMF_HELPER(QtTestObject, sig0, ())
+ INDEXOFMETHODPMF_HELPER(QtTestObject, testLongLong, (qint64, quint64))
+ INDEXOFMETHODPMF_HELPER(QtTestObject, testReference, (QString&))
+}
QTEST_MAIN(tst_QMetaObject)
#include "tst_qmetaobject.moc"