From 5d2cc11a826aeae73ccaa9521ff2e277d01c8dd9 Mon Sep 17 00:00:00 2001 From: Yonggang Luo Date: Sat, 30 Jul 2022 04:59:55 +0800 Subject: [PATCH] QMetaMethod: Add QMetaMethod::from(&MyClass:myFunction) support MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Add QMetaMethod::from QMetaMethod::fromInvokable QMetaMethod::fromSlot Task-number: QTBUG-36861 Signed-off-by: Yonggang Luo --- src/corelib/kernel/qmetaobject.h | 44 ++++++++++++++++++++++++++++---- src/tools/moc/generator.cpp | 34 +++++++++++++----------- 2 files changed, 58 insertions(+), 20 deletions(-) diff --git a/src/corelib/kernel/qmetaobject.h b/src/corelib/kernel/qmetaobject.h index 0740acef60a..bfd30dd32b4 100644 --- a/src/corelib/kernel/qmetaobject.h +++ b/src/corelib/kernel/qmetaobject.h @@ -138,14 +138,48 @@ class Q_CORE_EXPORT QMetaMethod template static inline QMetaMethod fromSignal(PointerToMemberFunction signal) { - typedef QtPrivate::FunctionPointer SignalType; - static_assert(QtPrivate::HasQ_OBJECT_Macro::Value, - "No Q_OBJECT in the class with the signal"); - return fromSignalImpl(&SignalType::Object::staticMetaObject, - reinterpret_cast(&signal)); + QMetaMethod method = from(signal); + if (method.methodType() == Signal) + { + return method; + } + return QMetaMethod(); + } + + template + static inline QMetaMethod fromSlot(PointerToMemberFunction slot) + { + QMetaMethod method = from(slot); + if (method.methodType() == Slot) + { + return method; + } + return QMetaMethod(); + } + + template + static inline QMetaMethod fromInvokable(PointerToMemberFunction invokable) + { + QMetaMethod method = from(invokable); + if (method.methodType() == Method) + { + return method; + } + return QMetaMethod(); + } + + template + static inline QMetaMethod from(PointerToMemberFunction func) + { + typedef QtPrivate::FunctionPointer ClassType; + static_assert(QtPrivate::HasQ_OBJECT_Macro::Value, + "No Q_OBJECT in the class with the func"); + return fromSignalImpl(&ClassType::Object::staticMetaObject, + reinterpret_cast(&func)); } private: + // ### Qt 7: rename fromSignalImpl to fromImpl static QMetaMethod fromSignalImpl(const QMetaObject *, void **); static QMetaMethod fromRelativeMethodIndex(const QMetaObject *mobj, int index); static QMetaMethod fromRelativeConstructorIndex(const QMetaObject *mobj, int index); diff --git a/src/tools/moc/generator.cpp b/src/tools/moc/generator.cpp index 0e8ba0bb727..f913793b19e 100644 --- a/src/tools/moc/generator.cpp +++ b/src/tools/moc/generator.cpp @@ -1157,30 +1157,34 @@ void Generator::generateStaticMetacall() } } - if (!cdef->signalList.isEmpty()) { - Q_ASSERT(needElse); // if there is signal, there was method. + if (!methodList.isEmpty()) { + Q_ASSERT(needElse); // there was method. fprintf(out, " else if (_c == QMetaObject::IndexOfMethod) {\n"); fprintf(out, " int *result = reinterpret_cast(_a[0]);\n"); bool anythingUsed = false; - for (int methodindex = 0; methodindex < cdef->signalList.size(); ++methodindex) { - const FunctionDef &f = cdef->signalList.at(methodindex); + 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, " using _t = %s (%s::*)(",f.type.rawName.constData() , cdef->classname.constData()); - int argsCount = f.arguments.count(); - for (int j = 0; j < argsCount; ++j) { - const ArgumentDef &a = f.arguments.at(j); - if (j) - fprintf(out, ", "); - fprintf(out, "%s", QByteArray(a.type.name + ' ' + a.rightType).constData()); - } - if (f.isPrivateSignal) { - if (argsCount > 0) - fprintf(out, ", "); - fprintf(out, "%s", "QPrivateSignal"); + if (f.isRawSlot) { + fprintf(out, "QMethodRawArguments"); + } else { + int argsCount = f.arguments.count(); + for (int j = 0; j < argsCount; ++j) { + const ArgumentDef &a = f.arguments.at(j); + if (j) + fprintf(out, ", "); + fprintf(out, "%s", QByteArray(a.type.name + ' ' + a.rightType).constData()); + } + if (f.isPrivateSignal) { + if (argsCount > 0) + fprintf(out, ", "); + fprintf(out, "%s", "QPrivateSignal"); + } } if (f.isConst) fprintf(out, ") const;\n");