summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--src/corelib/kernel/qmetaobject.cpp5
-rw-r--r--src/corelib/kernel/qtmochelpers.h147
-rw-r--r--src/tools/moc/generator.cpp96
-rw-r--r--src/tools/moc/generator.h6
-rw-r--r--tests/auto/tools/mochelpers/tst_mochelpers.cpp179
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 &paramsIndex, 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)