diff --git a/src/corelib/kernel/qmetaobject.cpp b/src/corelib/kernel/qmetaobject.cpp index 38beac2b4ac..c9848ece499 100644 --- a/src/corelib/kernel/qmetaobject.cpp +++ b/src/corelib/kernel/qmetaobject.cpp @@ -652,7 +652,7 @@ bool QMetaObjectPrivate::methodMatch(const QMetaObject *m, const QMetaMethod &me if (priv->parameterCount() != argc) return false; - if (stringData(m, data.name()) != name) + if (QMetaMethodPrivate::get(&method)->name() != name) return false; const QtPrivate::QMetaTypeInterface * const *ifaces = priv->parameterMetaTypeInterfaces(); @@ -2277,7 +2277,11 @@ QList QMetaMethod::parameterNames() const /*! - Returns the return type name of this method. + Returns the return type name of this method. If this method is a + constructor, this function returns an empty string (constructors have no + return types). + + \note In Qt 7, this function will return a null pointer for constructors. \sa returnType(), QMetaType::type() */ @@ -2285,6 +2289,10 @@ const char *QMetaMethod::typeName() const { if (!mobj) return nullptr; +#if QT_VERSION < QT_VERSION_CHECK(7, 0, 0) + if (methodType() == QMetaMethod::Constructor) + return ""; +#endif return QMetaMethodPrivate::get(this)->rawReturnTypeName(); } diff --git a/src/corelib/kernel/qtmochelpers.h b/src/corelib/kernel/qtmochelpers.h index d33b00bbbde..d93e62f459c 100644 --- a/src/corelib/kernel/qtmochelpers.h +++ b/src/corelib/kernel/qtmochelpers.h @@ -445,7 +445,13 @@ template struct SlotData : FunctionData struct ConstructorData : FunctionData { - using FunctionData::FunctionData; + using Base = FunctionData; + + // the name for a constructor is always the class name (string index zero) + // and it has no return type + constexpr ConstructorData(uint tagIndex, uint flags, typename Base::ParametersArray params = {}) + : Base(0, tagIndex, flags, QMetaType::UnknownType, params) + {} }; template struct RevisionedMethodData : @@ -469,7 +475,14 @@ template struct RevisionedSlotData : template struct RevisionedConstructorData : FunctionData { - using FunctionData::FunctionData; + using Base = FunctionData; + + // the name for a constructor is always the class name (string index zero) + // and it has no return type + constexpr RevisionedConstructorData(uint tagIndex, uint flags, uint revision, + typename Base::ParametersArray params = {}) + : Base(0, tagIndex, flags, revision, QMetaType::UnknownType, params) + {} }; diff --git a/src/tools/moc/generator.cpp b/src/tools/moc/generator.cpp index a6ce39c1ebd..5243ea64908 100644 --- a/src/tools/moc/generator.cpp +++ b/src/tools/moc/generator.cpp @@ -833,7 +833,11 @@ void Generator::addFunctions(const QList &list, const char *functyp comma = ", "; } - fprintf(out, ")%s>(%d, %d, ", f.isConst ? " const" : "", stridx(f.name), stridx(f.tag)); + if (f.isConstructor) + fprintf(out, ")>(%d, ", stridx(f.tag)); + else + fprintf(out, ")%s>(%d, %d, ", f.isConst ? " const" : "", stridx(f.name), stridx(f.tag)); + // flags // access right is always present if (f.access == FunctionDef::Private) @@ -854,9 +858,10 @@ void Generator::addFunctions(const QList &list, const char *functyp fprintf(out, ", %#x", f.revision); // return type (if not a constructor) - const bool allowEmptyName = f.isConstructor; - fprintf(out, ", "); - generateTypeInfo(f.normalizedType, allowEmptyName); + if (!f.isConstructor) { + fprintf(out, ", "); + generateTypeInfo(f.normalizedType); + } if (f.arguments.isEmpty()) { fprintf(out, "),\n"); diff --git a/tests/auto/corelib/kernel/qmetamethod/tst_qmetamethod.cpp b/tests/auto/corelib/kernel/qmetamethod/tst_qmetamethod.cpp index 1eb97e26cbb..190b8fabdaf 100644 --- a/tests/auto/corelib/kernel/qmetamethod/tst_qmetamethod.cpp +++ b/tests/auto/corelib/kernel/qmetamethod/tst_qmetamethod.cpp @@ -618,7 +618,10 @@ void tst_QMetaMethod::method() QCOMPARE(method.tag(), ""); QCOMPARE(method.returnType(), returnType); - QVERIFY(method.typeName() != 0); + if (QT7_ONLY(method.methodType() == QMetaMethod::Constructor) QT6_ONLY(false)) + QVERIFY(method.typeName()); + else + QVERIFY(method.typeName() != 0); if (QByteArray(method.typeName()) != returnTypeName) { // QMetaMethod should always produce a semantically equivalent typename QCOMPARE(QMetaType::fromName(method.typeName()), QMetaType::fromName(returnTypeName)); diff --git a/tests/auto/tools/moc/tst_moc.cpp b/tests/auto/tools/moc/tst_moc.cpp index 873acb6c77c..bd53f8e39ab 100644 --- a/tests/auto/tools/moc/tst_moc.cpp +++ b/tests/auto/tools/moc/tst_moc.cpp @@ -1879,7 +1879,7 @@ void tst_Moc::constructors() QCOMPARE(mm.access(), QMetaMethod::Public); QCOMPARE(mm.methodType(), QMetaMethod::Constructor); QCOMPARE(mm.methodSignature(), QByteArray("CtorTestClass(QObject*)")); - QCOMPARE(mm.typeName(), ""); + QCOMPARE(QByteArrayView(mm.typeName()), QByteArrayView()); QList paramNames = mm.parameterNames(); QCOMPARE(paramNames.size(), 1); QCOMPARE(paramNames.at(0), QByteArray("parent")); @@ -1892,7 +1892,7 @@ void tst_Moc::constructors() QCOMPARE(mm.access(), QMetaMethod::Public); QCOMPARE(mm.methodType(), QMetaMethod::Constructor); QCOMPARE(mm.methodSignature(), QByteArray("CtorTestClass()")); - QCOMPARE(mm.typeName(), ""); + QCOMPARE(QByteArrayView(mm.typeName()), QByteArrayView()); QCOMPARE(mm.parameterNames().size(), 0); QCOMPARE(mm.parameterTypes().size(), 0); } @@ -1901,7 +1901,7 @@ void tst_Moc::constructors() QCOMPARE(mm.access(), QMetaMethod::Public); QCOMPARE(mm.methodType(), QMetaMethod::Constructor); QCOMPARE(mm.methodSignature(), QByteArray("CtorTestClass(QString)")); - QCOMPARE(mm.typeName(), ""); + QCOMPARE(QByteArrayView(mm.typeName()), QByteArrayView()); QList paramNames = mm.parameterNames(); QCOMPARE(paramNames.size(), 1); QCOMPARE(paramNames.at(0), QByteArray("str")); diff --git a/tests/auto/tools/mochelpers/tst_mochelpers.cpp b/tests/auto/tools/mochelpers/tst_mochelpers.cpp index 41f6a9953cc..9513a5bd646 100644 --- a/tests/auto/tools/mochelpers/tst_mochelpers.cpp +++ b/tests/auto/tools/mochelpers/tst_mochelpers.cpp @@ -512,29 +512,28 @@ void tst_MocHelpers::methodUintGroup() void tst_MocHelpers::constructorUintData() { - constexpr uint NoType = 0x80000000 | 1; using namespace QtMocHelpers; using namespace QtMocConstants; { - auto result = ConstructorData(1, 2, AccessPublic, NoType, {}); - QCOMPARE(result.header[0], 1U); + auto result = ConstructorData(2, AccessPublic, {}); + QCOMPARE(result.header[0], 0U); QCOMPARE(result.header[1], 0U); QCOMPARE(result.header[3], 2U); QCOMPARE(result.header[4], AccessPublic | MethodConstructor); QCOMPARE(result.header[5], 0U); - QCOMPARE(result.payload[0], NoType); + QCOMPARE(result.payload[0], uint(QMetaType::UnknownType)); QCOMPARE(result.metaTypes().count(), 0); } { - auto result = ConstructorData(0, 1, AccessPublic, NoType, + auto result = ConstructorData(1, AccessPublic, {{ { QMetaType::QObjectStar, 2 } }}); QCOMPARE(result.header[0], 0U); QCOMPARE(result.header[1], 1U); QCOMPARE(result.header[3], 1U); QCOMPARE(result.header[4], AccessPublic | MethodConstructor); QCOMPARE(result.header[5], 0U); - QCOMPARE(result.payload[0], NoType); + QCOMPARE(result.payload[0], uint(QMetaType::UnknownType)); QCOMPARE(result.payload[1], uint(QMetaType::QObjectStar)); QCOMPARE(result.payload[2], 2U); @@ -561,7 +560,7 @@ checkConstructors(const std::array &data, const QtPrivate::QMetaTypeInt QCOMPARE(header[4], AccessPublic | MethodConstructor); QCOMPARE_GT(header[5], 0U); const uint *payload = data.data() + header[2]; - QCOMPARE(payload[0], 0x80000000U | 1); + QCOMPARE(payload[0], uint(QMetaType::UnknownType)); QCOMPARE(payload[1], uint(QMetaType::QObjectStar)); QCOMPARE(QMetaType(metaTypes[header[5]]), QMetaType::fromType()); @@ -574,7 +573,7 @@ checkConstructors(const std::array &data, const QtPrivate::QMetaTypeInt QCOMPARE(header[4], AccessPublic | MethodConstructor | MethodCloned); QCOMPARE_GT(header[5], 0U); payload = data.data() + header[2]; - QCOMPARE(payload[0], 0x80000000U | 1); + QCOMPARE(payload[0], uint(QMetaType::UnknownType)); // no metatype stored for this constructor // Constructor(const QString &) @@ -586,7 +585,7 @@ checkConstructors(const std::array &data, const QtPrivate::QMetaTypeInt QCOMPARE(header[4], AccessPublic | MethodConstructor); QCOMPARE_GT(header[5], 0U); payload = data.data() + header[2]; - QCOMPARE(payload[0], 0x80000000U | 1); + QCOMPARE(payload[0], uint(QMetaType::UnknownType)); QCOMPARE(payload[1], uint(QMetaType::QString)); QCOMPARE(QMetaType(metaTypes[header[5]]), QMetaType::fromType()); } @@ -596,14 +595,14 @@ void tst_MocHelpers::constructorUintGroup() using QtMocHelpers::NoType; QTest::setThrowOnFail(true); constexpr QtMocHelpers::UintData constructors = { - QtMocHelpers::ConstructorData(0, 1, QtMocConstants::AccessPublic, - 0x80000000 | 1, {{ { QMetaType::QObjectStar, 2 } }} + QtMocHelpers::ConstructorData(1, QtMocConstants::AccessPublic, + {{ { QMetaType::QObjectStar, 2 } }} ), - QtMocHelpers::ConstructorData(0, 1, QtMocConstants::AccessPublic | QtMocConstants::MethodCloned, - 0x80000000 | 1, {{ }} + QtMocHelpers::ConstructorData(1, QtMocConstants::AccessPublic | QtMocConstants::MethodCloned, + {{ }} ), - QtMocHelpers::ConstructorData(0, 1, QtMocConstants::AccessPublic, - 0x80000000 | 1, {{ { QMetaType::QString, 3 }, }} + QtMocHelpers::ConstructorData(1, QtMocConstants::AccessPublic, + {{ { QMetaType::QString, 3 }, }} ) }; testUintData(constructors); @@ -715,14 +714,14 @@ void tst_MocHelpers::uintArray() QtMocHelpers::EnumData>(11, 1, EnumIsFlag).add({ { 3, E1::AnEnumValue } }), }, QtMocHelpers::UintData{ - QtMocHelpers::ConstructorData(0, 1, QtMocConstants::AccessPublic, - 0x80000000 | 1, {{ { QMetaType::QObjectStar, 2 } }} + QtMocHelpers::ConstructorData(1, QtMocConstants::AccessPublic, + {{ { QMetaType::QObjectStar, 2 } }} ), - QtMocHelpers::ConstructorData(0, 1, QtMocConstants::AccessPublic | QtMocConstants::MethodCloned, - 0x80000000 | 1, {{ }} + QtMocHelpers::ConstructorData(1, QtMocConstants::AccessPublic | QtMocConstants::MethodCloned, + {{ }} ), - QtMocHelpers::ConstructorData(0, 1, QtMocConstants::AccessPublic, - 0x80000000 | 1, {{ { QMetaType::QString, 3 }, }} + QtMocHelpers::ConstructorData(1, QtMocConstants::AccessPublic, + {{ { QMetaType::QString, 3 }, }} ) }, QtMocHelpers::ClassInfos({{1, 2}, {3, 4}}));