diff options
| -rw-r--r-- | src/corelib/kernel/qmetaobject.cpp | 5 | ||||
| -rw-r--r-- | src/corelib/kernel/qtmochelpers.h | 147 | ||||
| -rw-r--r-- | src/tools/moc/generator.cpp | 96 | ||||
| -rw-r--r-- | src/tools/moc/generator.h | 6 | ||||
| -rw-r--r-- | tests/auto/tools/mochelpers/tst_mochelpers.cpp | 179 |
5 files changed, 311 insertions, 122 deletions
diff --git a/src/corelib/kernel/qmetaobject.cpp b/src/corelib/kernel/qmetaobject.cpp index 21f67c6d332..38beac2b4ac 100644 --- a/src/corelib/kernel/qmetaobject.cpp +++ b/src/corelib/kernel/qmetaobject.cpp @@ -1924,7 +1924,10 @@ QByteArray QMetaMethodPrivate::signature() const QByteArrayView QMetaMethodPrivate::name() const noexcept { Q_ASSERT(priv(mobj->d.data)->revision >= 7); - return stringDataView(mobj, data.name()); + QByteArrayView name = stringDataView(mobj, data.name()); + if (qsizetype colon = name.lastIndexOf(':'); colon > 0) + return name.sliced(colon + 1); + return name; } int QMetaMethodPrivate::typesDataIndex() const diff --git a/src/corelib/kernel/qtmochelpers.h b/src/corelib/kernel/qtmochelpers.h index e4eba1a1375..d33b00bbbde 100644 --- a/src/corelib/kernel/qtmochelpers.h +++ b/src/corelib/kernel/qtmochelpers.h @@ -81,6 +81,7 @@ template <uint... Nx> constexpr auto stringData(const char (&...strings)[Nx]) # define QT_MOC_HAS_STRINGDATA 1 struct NoType {}; +template <typename T> struct ForceCompleteMetaTypes {}; namespace detail { template<typename Enum> constexpr int payloadSizeForEnum() @@ -101,10 +102,53 @@ template <uint H, uint P> struct UintDataBlock uint payload[P ? P : 1] = {}; }; +// By default, we allow metatypes for incomplete types to be stored in the +// metatype array, but we provide a way to require them to be complete by using +// ForceCompleteMetaTypes in either the Unique type (used by moc if +// --require-complete-types is passed or some internal heuristic for QML +// matches) or in the type itself, used below for properties and enums. +template <typename T> struct TypeMustBeComplete : std::false_type {}; +template <typename T> struct TypeMustBeComplete<ForceCompleteMetaTypes<T>> : std::true_type {}; +// template <> struct TypeMustBeComplete<void> : std::true_type {}; + +template <typename Unique, typename T, typename RequireComplete = TypeMustBeComplete<Unique>> +struct TryMetaTypeInterfaceForType +{ + static constexpr const QtPrivate::QMetaTypeInterface *type() noexcept + { + using namespace QtPrivate; + using Query = TypeAndForceComplete<T, RequireComplete>; + return qTryMetaTypeInterfaceForType<Unique, Query>(); + } +}; + +template <typename Unique, typename T, typename RequireComplete> +struct TryMetaTypeInterfaceForType<Unique, ForceCompleteMetaTypes<T>, RequireComplete> : + TryMetaTypeInterfaceForType<void, T, std::true_type> +{}; + +template <typename... T> struct MetaTypeList +{ + static constexpr int count() { return sizeof...(T); } + template <typename Result> static constexpr void copyTo(Result &result, uint &metatypeoffset) + { + if constexpr (count()) { + using namespace QtPrivate; + using Unique = typename Result::UniqueType; + const QMetaTypeInterface *metaTypes[] = { + TryMetaTypeInterfaceForType<Unique, T>::type()... + }; + for (const QMetaTypeInterface *mt : metaTypes) + result.metaTypes[metatypeoffset++] = mt; + } + } +}; + template <int Idx, typename T> struct UintDataEntry { T entry; constexpr UintDataEntry(T &&entry_) : entry(std::move(entry_)) {} + static constexpr int metaTypeCount() { return decltype(T::metaTypes())::Count; } }; // This storage type is designed similar to libc++'s std::tuple, in that it @@ -131,6 +175,19 @@ template <int... Idx, typename... T> struct UintDataStorage<std::integer_sequenc }; (void) dummy; } + + static constexpr int metaTypeCount() + { + // same as: + // return (0 + ... + UintDataEntry<Idx, T>::metaTypeCount()); + // but not using the fold expression to avoid exceeding compiler limits + // (calculation done using int to get compile-time overflow checking) + int total = 0; + int counts[] = { 0, UintDataEntry<Idx, T>::metaTypeCount()... }; + for (int n : counts) + total += n; + return total; + } }; } // namespace detail @@ -163,9 +220,18 @@ template <typename... Block> struct UintData return total; } static constexpr uint dataSize() { return headerSize() + payloadSize(); } + static constexpr int metaTypeCount() + { + // ditto again + int total = 0; + int sizes[] = { 0, decltype(Block::metaTypes())::count()... }; + for (int n : sizes) + total += n; + return total; + } template <typename Result> - constexpr void copyTo(Result &result, size_t dataoffset) const + constexpr void copyTo(Result &result, size_t dataoffset, uint &metatypeoffset) const { uint *ptr = result.data.data(); size_t payloadoffset = dataoffset + headerSize(); @@ -173,7 +239,10 @@ template <typename... Block> struct UintData // copy the uint data q20::copy_n(input.header, input.headerSize(), ptr + dataoffset); q20::copy_n(input.payload, input.payloadSize(), ptr + payloadoffset); - input.adjustOffset(ptr, uint(dataoffset), uint(payloadoffset)); + input.adjustOffsets(ptr, uint(dataoffset), uint(payloadoffset), metatypeoffset); + + // copy the metatypes + decltype(input.metaTypes())::copyTo(result, metatypeoffset); dataoffset += input.headerSize(); payloadoffset += input.payloadSize(); @@ -202,7 +271,7 @@ template <int N> struct ClassInfos : detail::UintDataBlock<2 * N, 0> } }; -struct PropertyData : detail::UintDataBlock<5, 0> +template <typename PropertyType> struct PropertyData : detail::UintDataBlock<5, 0> { constexpr PropertyData(uint nameIndex, uint typeIndex, uint flags, uint notifyId = uint(-1), uint revision = 0) { @@ -213,7 +282,10 @@ struct PropertyData : detail::UintDataBlock<5, 0> this->header[4] = revision; } - static constexpr void adjustOffset(uint *, uint, uint) noexcept {} + static constexpr auto metaTypes() + { return detail::MetaTypeList<ForceCompleteMetaTypes<PropertyType>>{}; } + + static constexpr void adjustOffsets(uint *, uint, uint, uint) noexcept {} }; template <typename Enum, int N = 0> @@ -266,9 +338,14 @@ public: return result; } - static constexpr void adjustOffset(uint *ptr, uint dataoffset, uint payloadoffset) noexcept + static constexpr auto metaTypes() + { return detail::MetaTypeList<ForceCompleteMetaTypes<Enum>>{}; } + + static constexpr void + adjustOffsets(uint *ptr, uint dataoffset, uint payloadoffset, uint metatypeoffset) noexcept { ptr[dataoffset + 4] += uint(payloadoffset); + (void) metatypeoffset; } }; @@ -284,15 +361,34 @@ struct FunctionData<Ret (Args...), ExtraFlags> }; using ParametersArray = std::array<FunctionParameter, sizeof...(Args)>; - static constexpr void adjustOffset(uint *ptr, uint dataoffset, uint payloadoffset) noexcept + static auto metaTypes() + { + using namespace QtMocConstants; + if constexpr (std::is_same_v<Ret, NoType>) { + // constructors have no return type + static_assert((ExtraFlags & MethodConstructor) == MethodConstructor, + "NoType return type used on a non-constructor"); + static_assert((ExtraFlags & MethodIsConst) == 0, + "Constructors cannot be const"); + return detail::MetaTypeList<Args...>{}; + } else { + static_assert((ExtraFlags & MethodConstructor) != MethodConstructor, + "Constructors must use NoType as return type"); + return detail::MetaTypeList<Ret, Args...>{}; + } + } + + static constexpr void + adjustOffsets(uint *ptr, uint dataoffset, uint payloadoffset, uint metatypeoffset) noexcept { if constexpr (IsRevisioned) ++payloadoffset; ptr[dataoffset + 2] += uint(payloadoffset); + ptr[dataoffset + 5] = metatypeoffset; } constexpr - FunctionData(uint nameIndex, uint tagIndex, uint metaTypesIndex, uint flags, + FunctionData(uint nameIndex, uint tagIndex, uint flags, uint returnType, ParametersArray params = {}) { this->header[0] = nameIndex; @@ -300,7 +396,7 @@ struct FunctionData<Ret (Args...), ExtraFlags> this->header[2] = 0; // will be set in adjustOffsets() this->header[3] = tagIndex; this->header[4] = flags | ExtraFlags; - this->header[5] = metaTypesIndex; + this->header[5] = 0; // will be set in adjustOffsets() uint *p = this->payload; if constexpr (ExtraFlags & QtMocConstants::MethodRevisioned) @@ -313,17 +409,18 @@ struct FunctionData<Ret (Args...), ExtraFlags> } constexpr - FunctionData(uint nameIndex, uint tagIndex, uint metaTypesIndex, uint flags, uint revision, + FunctionData(uint nameIndex, uint tagIndex, uint flags, uint revision, uint returnType, ParametersArray params = {}) #ifdef __cpp_concepts requires(IsRevisioned) #endif - : FunctionData(nameIndex, tagIndex, metaTypesIndex, flags, returnType, params) + : FunctionData(nameIndex, tagIndex, flags, returnType, params) { // note: we place the revision differently from meta object revision 12 this->payload[0] = revision; } }; + template <typename Ret, typename... Args, uint ExtraFlags> struct FunctionData<Ret (Args...) const, ExtraFlags> : FunctionData<Ret (Args...), ExtraFlags | QtMocConstants::MethodIsConst> @@ -376,18 +473,26 @@ template <typename F> struct RevisionedConstructorData : }; - -template <uint N> struct UintDataResult +template <uint N, uint M, typename Unique = void> struct UintAndMetaTypeData { std::array<uint, N> data; + std::array<const QtPrivate::QMetaTypeInterface *, M> metaTypes; + using UniqueType = Unique; }; -template <typename Methods, typename Properties, typename Enums, +template <typename ObjectType, typename Unique, + typename Methods, typename Properties, typename Enums, typename Constructors = UintData<>, typename ClassInfo = detail::UintDataBlock<0, 0>> constexpr auto metaObjectData(uint flags, const Methods &methods, const Properties &properties, const Enums &enums, const Constructors &constructors = {}, const ClassInfo &classInfo = {}) { + constexpr uint MetaTypeCount = Properties::metaTypeCount() + + Enums::metaTypeCount() + + 1 // the gadget's or void + + Methods::metaTypeCount() + + Constructors::metaTypeCount(); + constexpr uint HeaderSize = 14; constexpr uint TotalSize = HeaderSize + Properties::dataSize() @@ -396,8 +501,9 @@ constexpr auto metaObjectData(uint flags, const Methods &methods, const Properti + Constructors::dataSize() + ClassInfo::headerSize() // + ClassInfo::payloadSize() + 1; // empty EOD - UintDataResult<TotalSize> result = {}; + UintAndMetaTypeData<TotalSize, MetaTypeCount, Unique> result = {}; uint dataoffset = HeaderSize; + uint metatypeoffset = 0; result.data[0] = QtMocConstants::OutputRevision; result.data[1] = 0; // class name index (it's always 0) @@ -409,22 +515,27 @@ constexpr auto metaObjectData(uint flags, const Methods &methods, const Properti result.data[6] = properties.count(); result.data[7] = properties.count() ? dataoffset : 0; - properties.copyTo(result, dataoffset); + properties.copyTo(result, dataoffset, metatypeoffset); dataoffset += properties.dataSize(); result.data[8] = enums.count(); result.data[9] = enums.count() ? dataoffset : 0; - enums.copyTo(result, dataoffset); + enums.copyTo(result, dataoffset, metatypeoffset); dataoffset += enums.dataSize(); + // the meta type referring to the object itself + result.metaTypes[metatypeoffset++] = + QtPrivate::qTryMetaTypeInterfaceForType<void, + QtPrivate::TypeAndForceComplete<ObjectType, std::true_type>>(); + result.data[4] = methods.count(); result.data[5] = methods.count() ? dataoffset : 0; - methods.copyTo(result, dataoffset); + methods.copyTo(result, dataoffset, metatypeoffset); dataoffset += methods.dataSize(); result.data[10] = constructors.count(); result.data[11] = constructors.count() ? dataoffset : 0; - constructors.copyTo(result, dataoffset); + constructors.copyTo(result, dataoffset, metatypeoffset); dataoffset += constructors.dataSize(); result.data[12] = flags; diff --git a/src/tools/moc/generator.cpp b/src/tools/moc/generator.cpp index efd8ced3bc1..a6ce39c1ebd 100644 --- a/src/tools/moc/generator.cpp +++ b/src/tools/moc/generator.cpp @@ -249,12 +249,16 @@ void Generator::generateCode() registerPropertyStrings(); registerEnumStrings(); + const bool requireCompleteness = requireCompleteTypes || cdef->requireCompleteMethodTypes; const bool hasStaticMetaCall = (cdef->hasQObject || !cdef->methodList.isEmpty() || !cdef->propertyList.isEmpty() || !cdef->constructorList.isEmpty()); const QByteArray qualifiedClassNameIdentifier = generateQualifiedClassNameIdentifier(cdef->qualified); + // type name for the Q_OJBECT/GADGET itself, void for namespaces + const char *ownType = !cdef->hasQNamespace ? cdef->classname.data() : "void"; + // ensure the qt_meta_tag_XXXX_t type is local fprintf(out, "namespace {\n" "struct qt_meta_tag_%s_t {};\n" @@ -286,8 +290,6 @@ void Generator::generateCode() // build the data array // - int initialMetaTypeOffset = 0; - // We define a method inside the context of the class or namespace we're // creating the meta object for, so we get access to everything it has // access to and with the same contexts (for example, member enums and @@ -296,23 +298,19 @@ void Generator::generateCode() "template <> constexpr inline auto %s::qt_create_metaobjectdata<qt_meta_tag_%s_t>()\n" "{\n" " namespace QMC = QtMocConstants;\n" - " QtMocHelpers::UintData qt_properties {\n", + " QtMocHelpers::UintData qt_methods {\n", cdef->qualified.constData(), qualifiedClassNameIdentifier.constData()); - addProperties(initialMetaTypeOffset); + // Build signals array first, otherwise the signal indices would be wrong + addFunctions(cdef->signalList, "Signal"); + addFunctions(cdef->slotList, "Slot"); + addFunctions(cdef->methodList, "Method"); fprintf(out, " };\n" - " QtMocHelpers::UintData qt_enums {\n"); - addEnums(initialMetaTypeOffset); + " QtMocHelpers::UintData qt_properties {\n"); + addProperties(); fprintf(out, " };\n" - " QtMocHelpers::UintData qt_methods {\n"); - - // we insert the metatype for the class itself here - ++initialMetaTypeOffset; - - // Build signals array first, otherwise the signal indices would be wrong - addFunctions(cdef->signalList, "Signal", initialMetaTypeOffset); - addFunctions(cdef->slotList, "Slot", initialMetaTypeOffset); - addFunctions(cdef->methodList, "Method", initialMetaTypeOffset); + " QtMocHelpers::UintData qt_enums {\n"); + addEnums(); fprintf(out, " };\n"); const char *uintDataParams = ""; @@ -320,7 +318,7 @@ void Generator::generateCode() if (isConstructible) { fprintf(out, " using Constructor = QtMocHelpers::NoType;\n" " QtMocHelpers::UintData qt_constructors {\n"); - addFunctions(cdef->constructorList, "Constructor", initialMetaTypeOffset); + addFunctions(cdef->constructorList, "Constructor"); fprintf(out, " };\n"); } else { fputs(" QtMocHelpers::UintData qt_constructors {};\n", out); @@ -342,13 +340,20 @@ void Generator::generateCode() // that we call qt_metacall for properties. metaObjectFlags = "QMC::PropertyAccessInStaticMetaCall"; } - fprintf(out, " return QtMocHelpers::metaObjectData(%s, qt_methods, qt_properties, qt_enums%s);\n" - "}\n", metaObjectFlags, uintDataParams); + { + QByteArray tagType = "qt_meta_tag_" + qualifiedClassNameIdentifier + "_t"; + if (requireCompleteness) + tagType = "QtMocHelpers::ForceCompleteMetaTypes<" + tagType + '>'; + fprintf(out, " return QtMocHelpers::metaObjectData<%s, %s>(%s,\n" + " qt_methods, qt_properties, qt_enums%s);\n" + "}\n", + ownType, tagType.constData(), metaObjectFlags, uintDataParams); + } if (cdef->hasQNamespace) { // We can always access the function above if it's at namespace scope. - fprintf(out, "static constexpr auto qt_meta_data_%s_array =\n" - " %s::qt_create_metaobjectdata<qt_meta_tag_%s_t>().data;\n", + fprintf(out, "static constexpr auto qt_meta_data_types_%s =\n" + " %s::qt_create_metaobjectdata<qt_meta_tag_%s_t>();\n", qualifiedClassNameIdentifier.constData(), cdef->qualified.constData(), qualifiedClassNameIdentifier.constData()); } else { @@ -358,16 +363,26 @@ void Generator::generateCode() "{\n" " return %s::qt_create_metaobjectdata<qt_meta_tag_%s_t>();\n" "}\n" - "static constexpr auto qt_meta_data_%s_array =\n" - " qt_call_create_metaobjectdata<qt_meta_tag_%s_t>().data;\n", + "static constexpr auto qt_meta_data_types_%s =\n" + " qt_call_create_metaobjectdata<qt_meta_tag_%s_t>();\n", qualifiedClassNameIdentifier.constData(), cdef->qualified.constData(), qualifiedClassNameIdentifier.constData(), qualifiedClassNameIdentifier.constData(), qualifiedClassNameIdentifier.constData()); } + + // create a copy of qt_meta_data_types' members so the uint array ends up + // in the pure .rodata section while the meta types is in .data.rel.ro + fprintf(out, "static constexpr auto qt_meta_data_%s_array =\n" + " qt_meta_data_types_%s.data;\n", + qualifiedClassNameIdentifier.constData(), qualifiedClassNameIdentifier.constData()); fprintf(out, "static constexpr const uint *qt_meta_data_%s =\n" - " qt_meta_data_%s_array.data();\n" - "#else // !QT_MOC_HAS_UINTDATA\n", + " qt_meta_data_%s_array.data();\n", qualifiedClassNameIdentifier.constData(), qualifiedClassNameIdentifier.constData()); + fprintf(out, "static constexpr auto qt_meta_types_%s =\n" + " qt_meta_data_types_%s.metaTypes;\n", + qualifiedClassNameIdentifier.constData(), qualifiedClassNameIdentifier.constData()); + + fprintf(out, "#else // !QT_MOC_HAS_UINTDATA\n"); int index = MetaObjectPrivateFieldCount; fprintf(out, "Q_CONSTINIT static const uint qt_meta_data_%s[] = {\n", qualifiedClassNameIdentifier.constData()); @@ -430,7 +445,7 @@ void Generator::generateCode() || propEnumCount >= std::numeric_limits<int>::max()) { parser->error("internal limit exceeded: number of property and enum metatypes is too big."); } - initialMetaTypeOffset = int(propEnumCount); + int initialMetaTypeOffset = int(propEnumCount); // // Build signals array first, otherwise the signal indices would be wrong @@ -587,8 +602,12 @@ void Generator::generateCode() else fprintf(out, " qt_meta_extradata_%s,\n", qualifiedClassNameIdentifier.constData()); + fprintf(out, "#ifdef QT_MOC_HAS_UINTDATA\n" + " qt_meta_types_%s.data(),\n" + "#else\n", + qualifiedClassNameIdentifier.constData()); + const char *comma = ""; - const bool requireCompleteness = requireCompleteTypes || cdef->requireCompleteMethodTypes; auto stringForType = [requireCompleteness](const QByteArray &type, bool forceComplete) -> QByteArray { const char *forceCompleteType = forceComplete ? ", std::true_type>" : ", std::false_type>"; if (requireCompleteness) @@ -615,8 +634,6 @@ void Generator::generateCode() comma = ","; } - // type name for the Q_OJBECT/GADGET itself, void for namespaces - auto ownType = !cdef->hasQNamespace ? cdef->classname.data() : "void"; fprintf(out, "%s\n // Q_OBJECT / Q_GADGET\n %s", comma, stringForType(ownType, true).constData()); comma = ","; @@ -647,6 +664,7 @@ void Generator::generateCode() } } fprintf(out, "\n >,\n"); + fprintf(out, "#endif // !QT_MOC_HAS_UINTDATA\n"); fprintf(out, " nullptr\n} };\n\n"); @@ -796,8 +814,7 @@ void Generator::registerByteArrayVector(const QList<QByteArray> &list) strreg(ba); } -void Generator::addFunctions(const QList<FunctionDef> &list, const char *functype, - int &initialMetatypeOffset) +void Generator::addFunctions(const QList<FunctionDef> &list, const char *functype) { for (const FunctionDef &f : list) { if (!f.isConstructor) @@ -816,8 +833,7 @@ void Generator::addFunctions(const QList<FunctionDef> &list, const char *functyp comma = ", "; } - fprintf(out, ")%s>(%d, %d, %d, ", f.isConst ? " const" : "", - stridx(f.name), stridx(f.tag), initialMetatypeOffset); + 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) @@ -858,11 +874,6 @@ void Generator::addFunctions(const QList<FunctionDef> &list, const char *functyp fprintf(out, "\n }}),\n"); } - - // constructors don't have a return type - if (!f.isConstructor) - ++initialMetatypeOffset; - initialMetatypeOffset += int(f.arguments.size()); } } @@ -986,12 +997,12 @@ void Generator::registerPropertyStrings() } } -void Generator::addProperties(int &initialMetaTypeOffset) +void Generator::addProperties() { for (const PropertyDef &p : std::as_const(cdef->propertyList)) { fprintf(out, " // property '%s'\n" - " QtMocHelpers::PropertyData(%d, ", - p.name.constData(), stridx(p.name)); + " QtMocHelpers::PropertyData<%s>(%d, ", + p.name.constData(), p.type.constData(), stridx(p.name)); generateTypeInfo(p.type); fputc(',', out); @@ -1056,7 +1067,6 @@ void Generator::addProperties(int &initialMetaTypeOffset) fprintf(out, "),\n"); } - initialMetaTypeOffset += int(cdef->propertyList.size()); } void Generator::generateProperties() @@ -1129,7 +1139,7 @@ void Generator::registerEnumStrings() } } -void Generator::addEnums(int &initialMetaTypeOffset) +void Generator::addEnums() { for (const EnumDef &e : std::as_const(cdef->enumList)) { const QByteArray &typeName = e.enumName.isNull() ? e.name : e.enumName; @@ -1167,8 +1177,6 @@ void Generator::addEnums(int &initialMetaTypeOffset) fprintf(out, " }),\n"); } - - initialMetaTypeOffset += int(cdef->enumList.size()); } void Generator::generateEnums(int index) diff --git a/src/tools/moc/generator.h b/src/tools/moc/generator.h index c8b1861cdf1..3bdff290f1e 100644 --- a/src/tools/moc/generator.h +++ b/src/tools/moc/generator.h @@ -29,9 +29,9 @@ private: void generateClassInfos(); void registerFunctionStrings(const QList<FunctionDef> &list); void registerByteArrayVector(const QList<QByteArray> &list); - void addProperties(int &initialMetaTypeOffset); - void addEnums(int &initialMetaTypeOffset); - void addFunctions(const QList<FunctionDef> &list, const char *functype, int &initialMetatypeOffset); + void addProperties(); + void addEnums(); + void addFunctions(const QList<FunctionDef> &list, const char *functype); void addClassInfos(); void generateFunctions(const QList<FunctionDef> &list, const char *functype, int type, int ¶msIndex, int &initialMetatypeOffset); diff --git a/tests/auto/tools/mochelpers/tst_mochelpers.cpp b/tests/auto/tools/mochelpers/tst_mochelpers.cpp index 035b78fa31c..41f6a9953cc 100644 --- a/tests/auto/tools/mochelpers/tst_mochelpers.cpp +++ b/tests/auto/tools/mochelpers/tst_mochelpers.cpp @@ -100,13 +100,26 @@ template <size_t N> static void checkClassInfos(const std::array<uint, N> &data) void tst_MocHelpers::classinfoDataGroup() { - constexpr auto data = QtMocHelpers::metaObjectData(0, + constexpr auto data = QtMocHelpers::metaObjectData<void, void>(0, QtMocHelpers::UintData{}, QtMocHelpers::UintData{}, QtMocHelpers::UintData{}, QtMocHelpers::UintData{}, QtMocHelpers::ClassInfos({{1, 2}, {3, 4}})); checkClassInfos(data.data); } +template <typename MetaTypeHolder> constexpr auto getMetaTypes(MetaTypeHolder) +{ + QtMocHelpers::UintAndMetaTypeData<0, MetaTypeHolder::count(), void> r = {}; + uint metatypeoffset = 0; + MetaTypeHolder::copyTo(r, metatypeoffset); + + std::array<QMetaType, MetaTypeHolder::count()> result; + for (uint i = 0; i < result.size(); ++i) + result[i] = QMetaType(r.metaTypes[i]); + + return result; +} + template <typename E, int N> void enumUintData_check(const E (&values)[N]) { using namespace QtMocHelpers; @@ -126,7 +139,7 @@ template <typename E, int N> void enumUintData_check(const E (&values)[N]) if constexpr (sizeof(E) > sizeof(uint)) { using U = std::underlying_type_t<E>; - for (uint i = 0; i < std::size(values); ++i) + for (uint i = 0; i < N; ++i) QCOMPARE(result.payload[2 * N + i], uint(U(values[i]) >> 32)); } } @@ -214,13 +227,15 @@ template <typename Data> void testUintData(const Data &data) QCOMPARE(data.payloadSize(), payloadSize); } -template <size_t N> static void checkEnums(const std::array<uint, N> &data) +template <size_t N> static void +checkEnums(const std::array<uint, N> &data, const QtPrivate::QMetaTypeInterface *const *metaTypes) { using namespace QtMocConstants; QCOMPARE(data[8], 4U); QCOMPARE_NE(data[9], 0U); const uint *header = data.data() + data[9]; + metaTypes += data[6]; // property count // E1: QCOMPARE(header[0 + 0], 1U); @@ -231,6 +246,7 @@ template <size_t N> static void checkEnums(const std::array<uint, N> &data) const uint *payload = data.data() + header[0 + 4]; QCOMPARE(payload[0], 3U); QCOMPARE(payload[1], uint(E1::AnEnumValue)); + QCOMPARE(QMetaType(metaTypes[0]), QMetaType::fromType<E1>()); // E3: QCOMPARE(header[5 + 0], 4U); @@ -245,6 +261,7 @@ template <size_t N> static void checkEnums(const std::array<uint, N> &data) QCOMPARE(payload[3], uint(E3::V2)); QCOMPARE(payload[4], uint(quint64(E3::V) >> 32)); QCOMPARE(payload[5], uint(quint64(E3::V2) >> 32)); + QCOMPARE(QMetaType(metaTypes[1]), QMetaType::fromType<E3>()); // E2: QCOMPARE(header[10 + 0], 7U); @@ -257,6 +274,7 @@ template <size_t N> static void checkEnums(const std::array<uint, N> &data) QCOMPARE(payload[1], uint(E2::V0)); QCOMPARE(payload[2], 10U); QCOMPARE(payload[3], uint(E2::V1)); + QCOMPARE(QMetaType(metaTypes[2]), QMetaType::fromType<E2>()); // QFlags<E1> QCOMPARE(header[15 + 0], 11U); @@ -267,6 +285,7 @@ template <size_t N> static void checkEnums(const std::array<uint, N> &data) payload = data.data() + header[15 + 4]; QCOMPARE(payload[0], 3U); QCOMPARE(payload[1], uint(E1::AnEnumValue)); + QCOMPARE(QMetaType(metaTypes[3]), QMetaType::fromType<QFlags<E1>>()); } void tst_MocHelpers::enumUintGroup() @@ -283,16 +302,16 @@ void tst_MocHelpers::enumUintGroup() }; testUintData(enums); - constexpr auto data = QtMocHelpers::metaObjectData(0, + constexpr auto data = QtMocHelpers::metaObjectData<void, void>(0, QtMocHelpers::UintData{}, QtMocHelpers::UintData{}, enums); - checkEnums(data.data); + checkEnums(data.data, data.metaTypes.data()); } void tst_MocHelpers::propertyUintData() { using namespace QtMocHelpers; { - auto result = PropertyData(3, QMetaType::Int, 0x3, 13, 0x101); + auto result = PropertyData<int>(3, QMetaType::Int, 0x3, 13, 0x101); QCOMPARE(result.payloadSize(), 0U); QCOMPARE(result.header[0], 3U); QCOMPARE(result.header[1], uint(QMetaType::Int)); @@ -302,18 +321,20 @@ void tst_MocHelpers::propertyUintData() } { // check that QMetaType doesn't override if it's an alias - auto result = PropertyData(3, 0x80000000 | 4, 0x03); + using Dummy = QString; + auto result = PropertyData<Dummy>(3, 0x80000000 | 4, 0x03); QCOMPARE(result.header[1], 0x80000000U | 4); } { // Or derived from struct Dummy : QString {}; - auto result = PropertyData(3, 0x80000000 | 4, 0x03); + auto result = PropertyData<Dummy>(3, 0x80000000 | 4, 0x03); QCOMPARE(result.header[1], 0x80000000U | 4); } } -template <size_t N> static void checkProperties(const std::array<uint, N> &data) +template <size_t N> static void +checkProperties(const std::array<uint, N> &data, const QtPrivate::QMetaTypeInterface *const *metaTypes) { QCOMPARE(data[6], 3U); QCOMPARE_NE(data[7], 0U); @@ -325,32 +346,35 @@ template <size_t N> static void checkProperties(const std::array<uint, N> &data) QCOMPARE(header[0 + 2], 0x3U); QCOMPARE(header[0 + 3], 13U); QCOMPARE(header[0 + 4], 0x0101U); + QCOMPARE(QMetaType(metaTypes[0]), QMetaType::fromType<int>()); QCOMPARE(header[5 + 0], 4U); QCOMPARE(header[5 + 1], 0x80000000U | 5); QCOMPARE(header[5 + 2], 0x3U); QCOMPARE(header[5 + 3], uint(-1)); QCOMPARE(header[5 + 4], 0U); + QCOMPARE(QMetaType(metaTypes[1]), QMetaType::fromType<QString>()); QCOMPARE(header[10 + 0], 6U); QCOMPARE(header[10 + 1], 0x80000000U | 7); QCOMPARE(header[10 + 2], 0x3U); QCOMPARE(header[10 + 3], uint(-1)); QCOMPARE(header[10 + 4], 0U); + QCOMPARE(QMetaType(metaTypes[2]), QMetaType::fromType<tst_MocHelpers *>()); } void tst_MocHelpers::propertyUintGroup() { QTest::setThrowOnFail(true); constexpr QtMocHelpers::UintData properties = { - QtMocHelpers::PropertyData(3, QMetaType::Int, 0x3, 13, 0x101), - QtMocHelpers::PropertyData(4, 0x80000000 | 5, 0x03), - QtMocHelpers::PropertyData(6, 0x80000000 | 7, 0x03) + QtMocHelpers::PropertyData<int>(3, QMetaType::Int, 0x3, 13, 0x101), + QtMocHelpers::PropertyData<QString>(4, 0x80000000 | 5, 0x03), + QtMocHelpers::PropertyData<tst_MocHelpers *>(6, 0x80000000 | 7, 0x03) }; testUintData(properties); - constexpr auto data = QtMocHelpers::metaObjectData(0, QtMocHelpers::UintData{}, properties, QtMocHelpers::UintData{}); - checkProperties(data.data); + constexpr auto data = QtMocHelpers::metaObjectData<void, void>(0, QtMocHelpers::UintData{}, properties, QtMocHelpers::UintData{}); + checkProperties(data.data, data.metaTypes.data()); } void tst_MocHelpers::methodUintData() @@ -358,16 +382,20 @@ void tst_MocHelpers::methodUintData() using namespace QtMocHelpers; using namespace QtMocConstants; { - auto result = SignalData<void()>(1, 2, 0, AccessPublic, QMetaType::Void, {}); + auto result = SignalData<void()>(1, 2, AccessPublic, QMetaType::Void, {}); QCOMPARE(result.header[0], 1U); QCOMPARE(result.header[1], 0U); QCOMPARE(result.header[3], 2U); QCOMPARE(result.header[4], AccessPublic | MethodSignal); QCOMPARE(result.header[5], 0U); QCOMPARE(result.payload[0], uint(QMetaType::Void)); + + QCOMPARE(result.metaTypes().count(), 1); + std::array mt = getMetaTypes(result.metaTypes()); + QCOMPARE(mt[0], QMetaType::fromType<void>()); } { - auto result = SlotData<void (const QString &) const>(1, 2, 0, AccessPublic, + auto result = SlotData<void (const QString &) const>(1, 2, AccessPublic, QMetaType::Void, { { { QMetaType::QString, 1000 } } }); QCOMPARE(result.header[0], 1U); QCOMPARE(result.header[1], 1U); @@ -377,9 +405,14 @@ void tst_MocHelpers::methodUintData() QCOMPARE(result.payload[0], uint(QMetaType::Void)); QCOMPARE(result.payload[1], uint(QMetaType::QString)); QCOMPARE(result.payload[2], 1000U); + + QCOMPARE(result.metaTypes().count(), 2); + std::array mt = getMetaTypes(result.metaTypes()); + QCOMPARE(mt[0], QMetaType::fromType<void>()); + QCOMPARE(mt[1], QMetaType::fromType<QString>()); } { - auto result = RevisionedSlotData<void (const QString &)>(1, 2, 0, AccessPublic, 0xff01, + auto result = RevisionedSlotData<void (const QString &)>(1, 2, AccessPublic, 0xff01, QMetaType::Void, { { { QMetaType::QString, 1000 } } }); QCOMPARE(result.header[0], 1U); QCOMPARE(result.header[1], 1U); @@ -390,16 +423,23 @@ void tst_MocHelpers::methodUintData() QCOMPARE(result.payload[1], uint(QMetaType::Void)); QCOMPARE(result.payload[2], uint(QMetaType::QString)); QCOMPARE(result.payload[3], 1000U); + + QCOMPARE(result.metaTypes().count(), 2); + std::array mt = getMetaTypes(result.metaTypes()); + QCOMPARE(mt[0], QMetaType::fromType<void>()); + QCOMPARE(mt[1], QMetaType::fromType<QString>()); } } -template <size_t N> static void checkMethods(const std::array<uint, N> &data) +template <size_t N> static void +checkMethods(const std::array<uint, N> &data, const QtPrivate::QMetaTypeInterface *const *metaTypes) { using namespace QtMocConstants; QCOMPARE(data[4], 3U); QCOMPARE_NE(data[5], 0U); const uint *header = data.data() + data[5]; + uint initialMetaTypeOffset = data[6] + data[8] + 1; // propcount + enumcount + object // signals: void signal() QCOMPARE(header[0], 1U); @@ -407,10 +447,11 @@ template <size_t N> static void checkMethods(const std::array<uint, N> &data) QCOMPARE_NE(header[2], 0U); QCOMPARE(header[3], 2U); QCOMPARE(header[4], AccessPublic | MethodSignal | MethodRevisioned); - QCOMPARE(header[5], 6U); // ### + QCOMPARE(header[5], initialMetaTypeOffset); const uint *payload = data.data() + header[2]; QCOMPARE(payload[-1], 0x0509U); QCOMPARE(payload[0], uint(QMetaType::Void)); + QCOMPARE(QMetaType(metaTypes[header[5]]), QMetaType::fromType<void>()); // signals: void signal(E1, Dummy) [Dummy = QString] header += 6; @@ -419,13 +460,16 @@ template <size_t N> static void checkMethods(const std::array<uint, N> &data) QCOMPARE_NE(header[2], 0U); QCOMPARE(header[3], 2U); QCOMPARE(header[4], AccessPublic | MethodSignal); - QCOMPARE(header[5], 7U); // ### + QCOMPARE(header[5], initialMetaTypeOffset + 1); payload = data.data() + header[2]; QCOMPARE(payload[0], uint(QMetaType::Void)); QCOMPARE(payload[1], 0x80000000U | 4); // not a builtin type QCOMPARE(payload[2], 0x80000000U | 5); QCOMPARE(payload[3], 6U); QCOMPARE(payload[4], 7U); + QCOMPARE(QMetaType(metaTypes[header[5] + 0]), QMetaType::fromType<void>()); + QCOMPARE(QMetaType(metaTypes[header[5] + 1]), QMetaType::fromType<E1>()); + QCOMPARE(QMetaType(metaTypes[header[5] + 2]), QMetaType::fromType<QString>()); // public slots: bool slot(QString &) const header += 6; @@ -434,11 +478,13 @@ template <size_t N> static void checkMethods(const std::array<uint, N> &data) QCOMPARE_NE(header[2], 0U); QCOMPARE(header[3], 2U); QCOMPARE(header[4], AccessPublic | MethodSlot | MethodIsConst); - QCOMPARE(header[5], 9U); // ### + QCOMPARE(header[5], initialMetaTypeOffset + 4); payload = data.data() + header[2]; QCOMPARE(payload[0], uint(QMetaType::Bool)); QCOMPARE(payload[1], 0x80000000U | 10); // not a builtin type QCOMPARE(payload[2], 11U); + QCOMPARE(QMetaType(metaTypes[header[5] + 0]), QMetaType::fromType<bool>()); + QCOMPARE(metaTypes[header[5] + 1], nullptr); // is a reference } void tst_MocHelpers::methodUintGroup() @@ -446,21 +492,22 @@ void tst_MocHelpers::methodUintGroup() QTest::setThrowOnFail(true); using Dummy = QString; constexpr QtMocHelpers::UintData methods = { - QtMocHelpers::RevisionedSignalData<void()>(1, 2, 6, QtMocConstants::AccessPublic, 0x509, + QtMocHelpers::RevisionedSignalData<void()>(1, 2, QtMocConstants::AccessPublic, 0x509, QMetaType::Void, {{ }} ), - QtMocHelpers::SignalData<void (E1, Dummy)>(3, 2, 7, QtMocConstants::AccessPublic, + QtMocHelpers::SignalData<void (E1, Dummy)>(3, 2, QtMocConstants::AccessPublic, QMetaType::Void, {{ { 0x80000000 | 4, 6 }, { 0x80000000 | 5, 7 }} } ), - QtMocHelpers::SlotData<bool (QString &) const>(8, 2, 9, QtMocConstants::AccessPublic, + QtMocHelpers::SlotData<bool (QString &) const>(8, 2, QtMocConstants::AccessPublic, QMetaType::Bool, {{ { 0x80000000 | 10, 11 } }} ) }; testUintData(methods); - constexpr auto data = QtMocHelpers::metaObjectData(0, methods, QtMocHelpers::UintData{}, - QtMocHelpers::UintData{}); - checkMethods(data.data); + constexpr auto data = + QtMocHelpers::metaObjectData<tst_MocHelpers, tst_MocHelpers>(0, methods, QtMocHelpers::UintData{}, + QtMocHelpers::UintData{}); + checkMethods(data.data, data.metaTypes.data()); } void tst_MocHelpers::constructorUintData() @@ -469,16 +516,18 @@ void tst_MocHelpers::constructorUintData() using namespace QtMocHelpers; using namespace QtMocConstants; { - auto result = ConstructorData<QtMocHelpers::NoType()>(1, 2, 0, AccessPublic, NoType, {}); + auto result = ConstructorData<QtMocHelpers::NoType()>(1, 2, AccessPublic, NoType, {}); QCOMPARE(result.header[0], 1U); 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.metaTypes().count(), 0); } { - auto result = ConstructorData<QtMocHelpers::NoType(QObject *)>(0, 1, 0, AccessPublic, NoType, + auto result = ConstructorData<QtMocHelpers::NoType(QObject *)>(0, 1, AccessPublic, NoType, {{ { QMetaType::QObjectStar, 2 } }}); QCOMPARE(result.header[0], 0U); QCOMPARE(result.header[1], 1U); @@ -488,10 +537,15 @@ void tst_MocHelpers::constructorUintData() QCOMPARE(result.payload[0], NoType); QCOMPARE(result.payload[1], uint(QMetaType::QObjectStar)); QCOMPARE(result.payload[2], 2U); + + QCOMPARE(result.metaTypes().count(), 1); + std::array mt = getMetaTypes(result.metaTypes()); + QCOMPARE(mt[0], QMetaType::fromType<QObject *>()); } } -template <size_t N> static void checkConstructors(const std::array<uint, N> &data) +template <size_t N> static void +checkConstructors(const std::array<uint, N> &data, const QtPrivate::QMetaTypeInterface *const *metaTypes) { using namespace QtMocConstants; QCOMPARE(data[10], 3U); @@ -509,6 +563,7 @@ template <size_t N> static void checkConstructors(const std::array<uint, N> &dat const uint *payload = data.data() + header[2]; QCOMPARE(payload[0], 0x80000000U | 1); QCOMPARE(payload[1], uint(QMetaType::QObjectStar)); + QCOMPARE(QMetaType(metaTypes[header[5]]), QMetaType::fromType<QObject *>()); // Constructor() [cloned from the previous with a default argument] header += 6; @@ -520,6 +575,7 @@ template <size_t N> static void checkConstructors(const std::array<uint, N> &dat QCOMPARE_GT(header[5], 0U); payload = data.data() + header[2]; QCOMPARE(payload[0], 0x80000000U | 1); + // no metatype stored for this constructor // Constructor(const QString &) header += 6; @@ -532,6 +588,7 @@ template <size_t N> static void checkConstructors(const std::array<uint, N> &dat payload = data.data() + header[2]; QCOMPARE(payload[0], 0x80000000U | 1); QCOMPARE(payload[1], uint(QMetaType::QString)); + QCOMPARE(QMetaType(metaTypes[header[5]]), QMetaType::fromType<QString>()); } void tst_MocHelpers::constructorUintGroup() @@ -539,24 +596,26 @@ void tst_MocHelpers::constructorUintGroup() using QtMocHelpers::NoType; QTest::setThrowOnFail(true); constexpr QtMocHelpers::UintData constructors = { - QtMocHelpers::ConstructorData<NoType(QObject *)>(0, 1, 1, QtMocConstants::AccessPublic, + QtMocHelpers::ConstructorData<NoType(QObject *)>(0, 1, QtMocConstants::AccessPublic, 0x80000000 | 1, {{ { QMetaType::QObjectStar, 2 } }} ), - QtMocHelpers::ConstructorData<NoType()>(0, 1, 2, QtMocConstants::AccessPublic | QtMocConstants::MethodCloned, + QtMocHelpers::ConstructorData<NoType()>(0, 1, QtMocConstants::AccessPublic | QtMocConstants::MethodCloned, 0x80000000 | 1, {{ }} ), - QtMocHelpers::ConstructorData<NoType(const QString &)>(0, 1, 2, QtMocConstants::AccessPublic, + QtMocHelpers::ConstructorData<NoType(const QString &)>(0, 1, QtMocConstants::AccessPublic, 0x80000000 | 1, {{ { QMetaType::QString, 3 }, }} ) }; testUintData(constructors); - constexpr auto data = QtMocHelpers::metaObjectData(0, + constexpr auto data = QtMocHelpers::metaObjectData<void, void>(0, QtMocHelpers::UintData{}, QtMocHelpers::UintData{}, QtMocHelpers::UintData{}, constructors); - checkConstructors(data.data); + checkConstructors(data.data, data.metaTypes.data()); } +struct Gadget {}; + template <size_t N> static void checkUintArrayGeneric(const std::array<uint, N> &data, uint flags = 0) { using namespace QtMocConstants; @@ -576,7 +635,7 @@ template <size_t N> static void checkUintArrayGeneric(const std::array<uint, N> void tst_MocHelpers::emptyUintArray() { using namespace QtMocConstants; - constexpr auto data = QtMocHelpers::metaObjectData(MetaObjectFlag{}, + constexpr auto data = QtMocHelpers::metaObjectData<Gadget, void>(MetaObjectFlag{}, QtMocHelpers::UintData{}, QtMocHelpers::UintData{}, QtMocHelpers::UintData{}); QTest::setThrowOnFail(true); checkUintArrayGeneric(data.data, MetaObjectFlag{}); @@ -589,17 +648,21 @@ void tst_MocHelpers::emptyUintArray() QCOMPARE(data.data[8], 0U); // enums QCOMPARE(data.data[10], 0U); // constructors QCOMPARE(data.data[13], 0U); // signals + + QCOMPARE(data.metaTypes.size(), 1U); + QMetaType self(data.metaTypes[data.data[6] + data.data[8]]); + QCOMPARE(self, QMetaType::fromType<Gadget>()); } void tst_MocHelpers::uintArrayNoMethods() { using namespace QtMocConstants; - constexpr auto data = QtMocHelpers::metaObjectData(PropertyAccessInStaticMetaCall, + constexpr auto data = QtMocHelpers::metaObjectData<Gadget, void>(PropertyAccessInStaticMetaCall, QtMocHelpers::UintData{}, QtMocHelpers::UintData{ - QtMocHelpers::PropertyData(3, QMetaType::Int, 0x3, 13, 0x101), - QtMocHelpers::PropertyData(4, 0x80000000 | 5, 0x03), - QtMocHelpers::PropertyData(6, 0x80000000 | 7, 0x03), + QtMocHelpers::PropertyData<int>(3, QMetaType::Int, 0x3, 13, 0x101), + QtMocHelpers::PropertyData<QString>(4, 0x80000000 | 5, 0x03), + QtMocHelpers::PropertyData<tst_MocHelpers *>(6, 0x80000000 | 7, 0x03) }, QtMocHelpers::UintData{ QtMocHelpers::EnumData<E1>(1, 1, 0x00).add({ { 3, E1::AnEnumValue } }), QtMocHelpers::EnumData<E3>(4, 5, EnumIsFlag | EnumIsScoped) @@ -612,12 +675,14 @@ void tst_MocHelpers::uintArrayNoMethods() QTest::setThrowOnFail(true); checkUintArrayGeneric(data.data, PropertyAccessInStaticMetaCall); checkClassInfos(data.data); - checkProperties(data.data); - checkEnums(data.data); + checkProperties(data.data, data.metaTypes.data()); + checkEnums(data.data, data.metaTypes.data()); QTest::setThrowOnFail(false); QCOMPARE(data.data[4], 0U); // methods QCOMPARE(data.data[10], 0U); // constructors QCOMPARE(data.data[13], 0U); // signals + QMetaType self(data.metaTypes[data.data[6] + data.data[8]]); + QCOMPARE(self, QMetaType::fromType<Gadget>()); } void tst_MocHelpers::uintArray() @@ -625,22 +690,22 @@ void tst_MocHelpers::uintArray() using Dummy = QString; using QtMocHelpers::NoType; using namespace QtMocConstants; - constexpr auto data = QtMocHelpers::metaObjectData(PropertyAccessInStaticMetaCall, + constexpr auto data = QtMocHelpers::metaObjectData<void, tst_MocHelpers>(PropertyAccessInStaticMetaCall, QtMocHelpers::UintData{ - QtMocHelpers::RevisionedSignalData<void()>(1, 2, 6, QtMocConstants::AccessPublic, 0x509, + QtMocHelpers::RevisionedSignalData<void()>(1, 2, QtMocConstants::AccessPublic, 0x509, QMetaType::Void, {{ }} ), - QtMocHelpers::SignalData<void (E1, Dummy)>(3, 2, 7, QtMocConstants::AccessPublic, + QtMocHelpers::SignalData<void (E1, Dummy)>(3, 2, QtMocConstants::AccessPublic, QMetaType::Void, {{ { 0x80000000 | 4, 6 }, { 0x80000000 | 5, 7 }} } ), - QtMocHelpers::SlotData<bool (QString &) const>(8, 2, 9, QtMocConstants::AccessPublic, + QtMocHelpers::SlotData<bool (QString &) const>(8, 2, QtMocConstants::AccessPublic, QMetaType::Bool, {{ { 0x80000000 | 10, 11 } }} ) }, QtMocHelpers::UintData{ - QtMocHelpers::PropertyData(3, QMetaType::Int, 0x3, 13, 0x101), - QtMocHelpers::PropertyData(4, 0x80000000 | 5, 0x03), - QtMocHelpers::PropertyData(6, 0x80000000 | 7, 0x03), + QtMocHelpers::PropertyData<int>(3, QMetaType::Int, 0x3, 13, 0x101), + QtMocHelpers::PropertyData<QString>(4, 0x80000000 | 5, 0x03), + QtMocHelpers::PropertyData<tst_MocHelpers *>(6, 0x80000000 | 7, 0x03) }, QtMocHelpers::UintData{ QtMocHelpers::EnumData<E1>(1, 1, 0x00).add({ { 3, E1::AnEnumValue } }), QtMocHelpers::EnumData<E3>(4, 5, EnumIsFlag | EnumIsScoped) @@ -650,13 +715,13 @@ void tst_MocHelpers::uintArray() QtMocHelpers::EnumData<QFlags<E1>>(11, 1, EnumIsFlag).add({ { 3, E1::AnEnumValue } }), }, QtMocHelpers::UintData{ - QtMocHelpers::ConstructorData<NoType(QObject *)>(0, 1, 1, QtMocConstants::AccessPublic, + QtMocHelpers::ConstructorData<NoType(QObject *)>(0, 1, QtMocConstants::AccessPublic, 0x80000000 | 1, {{ { QMetaType::QObjectStar, 2 } }} ), - QtMocHelpers::ConstructorData<NoType()>(0, 1, 2, QtMocConstants::AccessPublic | QtMocConstants::MethodCloned, + QtMocHelpers::ConstructorData<NoType()>(0, 1, QtMocConstants::AccessPublic | QtMocConstants::MethodCloned, 0x80000000 | 1, {{ }} ), - QtMocHelpers::ConstructorData<NoType(const QString &)>(0, 1, 3, QtMocConstants::AccessPublic, + QtMocHelpers::ConstructorData<NoType(const QString &)>(0, 1, QtMocConstants::AccessPublic, 0x80000000 | 1, {{ { QMetaType::QString, 3 }, }} ) }, QtMocHelpers::ClassInfos({{1, 2}, {3, 4}})); @@ -664,10 +729,12 @@ void tst_MocHelpers::uintArray() QTest::setThrowOnFail(true); checkUintArrayGeneric(data.data, PropertyAccessInStaticMetaCall); checkClassInfos(data.data); - checkProperties(data.data); - checkEnums(data.data); - checkMethods(data.data); - checkConstructors(data.data); + checkProperties(data.data, data.metaTypes.data()); + checkEnums(data.data, data.metaTypes.data()); + checkMethods(data.data, data.metaTypes.data()); + checkConstructors(data.data, data.metaTypes.data()); + QMetaType self(data.metaTypes[data.data[6] + data.data[8]]); + QCOMPARE(self, QMetaType::fromType<void>()); } QTEST_MAIN(tst_MocHelpers) |
