From 49bd825a9626eda77fd9e8313e1868bed4c77bff Mon Sep 17 00:00:00 2001 From: Olivier Goffart Date: Mon, 31 Oct 2011 15:22:31 +0100 Subject: moc: support mapping pointers to member functions to indexes This change adds QMetaObject::IndexOfMethod as a parameter to the qt_static_metacall function. It lets the moc generated code return the index of a signal or slot given its pointer to member function This is required to support the new connection syntax Change-Id: I39198c6699b5aa3599d3d282f7ac79b1e3684d33 Reviewed-by: Bradley T. Hughes Reviewed-by: Thiago Macieira --- src/tools/moc/generator.cpp | 29 +++++++++++++++++++++++++++++ src/tools/moc/moc.cpp | 6 +++++- src/tools/moc/moc.h | 6 +++++- 3 files changed, 39 insertions(+), 2 deletions(-) (limited to 'src/tools') 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(_a[0]);\n"); + fprintf(out, " void **func = reinterpret_cast(_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; -- cgit v1.2.3