diff options
author | Fabian Kosmale <fabian.kosmale@qt.io> | 2021-03-23 17:04:37 +0100 |
---|---|---|
committer | Fabian Kosmale <fabian.kosmale@qt.io> | 2021-03-25 17:33:07 +0100 |
commit | cb43aaca112c864a201b87037692cb8ae2e93b6d (patch) | |
tree | 4118aa054133f6c72a7185ac0adbfd8eaf2f190b /src/tools/moc | |
parent | 9145650302d3cfe7df0fbc2a11f5d8f5f867897d (diff) |
Introduce QMetaObject::metaType
This function returns the metatype corresponding to the metaobject, or
an invalid metatype for namespaces.
This works as follows: First we increment the metaobject revision for
new metaobjects. Metaobjects with older revisions are handled by doing a
lookup by name. That fallback is also used for dynamic metaobjects (from
QtDBUS and those created by QMetaObjectBuilder).
For new metaobjects, we store the metatype in its metatype array, behind
the property metatypes. This avoids any changes to the property and
method metatype extraction logic: For properties, the metatype access
does not change, as the new metatype is after their metatypes. For
method metatypes, we already have an indirection layer (using offsets),
so by adjusting those offsets by one, the same logic keeps working.
To distinguish between namespaces and dynamic metaobjects, namespaces
store the metatypeinterface pointer for void in the metatype array,
whereas dynamic metaobjects store a nullptr.
One nice additional benefit is that this simplifies the generator logic
in moc, as the metatype array is now never empty.
Task-number: QTBUG-92077
Change-Id: Id3f920f28553f12032a71a1a87dad29e5374dbe7
Reviewed-by: Ulf Hermann <ulf.hermann@qt.io>
Reviewed-by: Andrei Golubev <andrei.golubev@qt.io>
Diffstat (limited to 'src/tools/moc')
-rw-r--r-- | src/tools/moc/generator.cpp | 95 |
1 files changed, 46 insertions, 49 deletions
diff --git a/src/tools/moc/generator.cpp b/src/tools/moc/generator.cpp index 78829ce93c..ad3df36292 100644 --- a/src/tools/moc/generator.cpp +++ b/src/tools/moc/generator.cpp @@ -396,7 +396,8 @@ void Generator::generateCode() // generateClassInfos(); - int initialMetaTypeOffset = cdef->propertyList.count(); + // all property metatypes, + 1 for the type of the current class itself + int initialMetaTypeOffset = cdef->propertyList.count() + 1; // // Build signals array first, otherwise the signal indices would be wrong @@ -560,64 +561,60 @@ void Generator::generateCode() else fprintf(out, " qt_meta_extradata_%s,\n", qualifiedClassNameIdentifier.constData()); - bool constructorListContainsArgument = false; - for (int i = 0; i< cdef->constructorList.count(); ++i) { - const FunctionDef& fdef = cdef->constructorList.at(i); - if (fdef.arguments.count()) { - constructorListContainsArgument = true; - break; - } - } - if (cdef->propertyList.isEmpty() && cdef->signalList.isEmpty() && cdef->slotList.isEmpty() && cdef->methodList.isEmpty() && !constructorListContainsArgument) { - fprintf(out, " nullptr,\n"); + bool needsComma = false; + const bool requireCompleteness = requireCompleteTypes || cdef->requireCompleteMethodTypes; + if (!requireCompleteness) { + fprintf(out, "qt_incomplete_metaTypeArray<qt_meta_stringdata_%s_t\n", qualifiedClassNameIdentifier.constData()); + needsComma = true; } else { - bool needsComma = false; - const bool requireCompleteness = requireCompleteTypes || cdef->requireCompleteMethodTypes; - if (!requireCompleteness) { - fprintf(out, "qt_incomplete_metaTypeArray<qt_meta_stringdata_%s_t\n", qualifiedClassNameIdentifier.constData()); - needsComma = true; - } else { - fprintf(out, "qt_metaTypeArray<\n"); - } - for (int i = 0; i < cdef->propertyList.count(); ++i) { - const PropertyDef &p = cdef->propertyList.at(i); + fprintf(out, "qt_metaTypeArray<\n"); + } + // metatypes for properties + for (int i = 0; i < cdef->propertyList.count(); ++i) { + const PropertyDef &p = cdef->propertyList.at(i); + if (requireCompleteness) + fprintf(out, "%s%s", needsComma ? ", " : "", p.type.data()); + else + fprintf(out, "%sQtPrivate::TypeAndForceComplete<%s, std::true_type>", needsComma ? ", " : "", p.type.data()); + needsComma = true; + } + // type name for the Q_OJBECT/GADGET itself, void for namespaces + auto ownType = !cdef->hasQNamespace ? cdef->classname.data() : "void"; + if (requireCompleteness) + fprintf(out, "%s%s", needsComma ? ", " : "", ownType); + else + fprintf(out, "%sQtPrivate::TypeAndForceComplete<%s, std::true_type>", needsComma ? ", " : "", ownType); + + // metatypes for all exposed methods + // no need to check for needsComma any longer, as we always need one due to the classname being present + for (const QList<FunctionDef> &methodContainer : + { cdef->signalList, cdef->slotList, cdef->methodList }) { + for (int i = 0; i< methodContainer.count(); ++i) { + const FunctionDef& fdef = methodContainer.at(i); if (requireCompleteness) - fprintf(out, "%s%s", needsComma ? ", " : "", p.type.data()); + fprintf(out, ", %s", fdef.type.name.data()); else - fprintf(out, "%sQtPrivate::TypeAndForceComplete<%s, std::true_type>", needsComma ? ", " : "", p.type.data()); - needsComma = true; - } - for (const QList<FunctionDef> &methodContainer : - { cdef->signalList, cdef->slotList, cdef->methodList }) { - for (int i = 0; i< methodContainer.count(); ++i) { - const FunctionDef& fdef = methodContainer.at(i); - if (requireCompleteness) - fprintf(out, "%s%s", needsComma ? ", " : "", fdef.type.name.data()); - else - fprintf(out, "%sQtPrivate::TypeAndForceComplete<%s, std::false_type>", needsComma ? ", " : "", fdef.type.name.data()); - needsComma = true; - for (const auto &argument: fdef.arguments) { - if (requireCompleteness) - fprintf(out, ", %s", argument.type.name.data()); - else - fprintf(out, ", QtPrivate::TypeAndForceComplete<%s, std::false_type>", argument.type.name.data()); - } - } - fprintf(out, "\n"); - } - for (int i = 0; i< cdef->constructorList.count(); ++i) { - const FunctionDef& fdef = cdef->constructorList.at(i); + fprintf(out, ", QtPrivate::TypeAndForceComplete<%s, std::false_type>", fdef.type.name.data()); for (const auto &argument: fdef.arguments) { if (requireCompleteness) - fprintf(out, "%s%s", needsComma ? ", " : "", argument.type.name.data()); + fprintf(out, ", %s", argument.type.name.data()); else - fprintf(out, "%sQtPrivate::TypeAndForceComplete<%s, std::false_type>", needsComma ? ", " : "", argument.type.name.data()); - needsComma = true; + fprintf(out, ", QtPrivate::TypeAndForceComplete<%s, std::false_type>", argument.type.name.data()); } } fprintf(out, "\n"); - fprintf(out, ">,\n"); } + for (int i = 0; i< cdef->constructorList.count(); ++i) { + const FunctionDef& fdef = cdef->constructorList.at(i); + for (const auto &argument: fdef.arguments) { + if (requireCompleteness) + fprintf(out, ", %s", argument.type.name.data()); + else + fprintf(out, ", QtPrivate::TypeAndForceComplete<%s, std::false_type>", argument.type.name.data()); + } + } + fprintf(out, "\n"); + fprintf(out, ">,\n"); fprintf(out, " nullptr\n} };\n\n"); |