summaryrefslogtreecommitdiffstats
path: root/src
diff options
context:
space:
mode:
authorFabian Kosmale <fabian.kosmale@qt.io>2020-07-22 11:21:42 +0200
committerFabian Kosmale <fabian.kosmale@qt.io>2020-07-24 07:46:29 +0200
commit27fcf66319605ed29d35de4034a41f05e8ba0a3b (patch)
treed2c6f9255e9f9137cd6b9578f83313e55304f235 /src
parentaf7a3430edfc4deff494c9ec88b803f468b5cf2a (diff)
QMetaType: force properties to have a complete type again
When the compile time metatype support for methods was introduced, we needed to allow incomplete types to avoid breaking a large amount of code. However, this mistakenly enabled using incomplete types for properties, too. In contrast to methods, properties lack the fallback code to retrieve the metatype at runtime. Thus, this commit restores the completeness requirement for properties again. This is done by always calling QMetaTypeForType for properties in qTryMetaTypeForType. Amends fa987d44417528856d5e80ed7b48ba99e19fa307 Change-Id: I5f66ff289631c056eecebe40926bf321d283eea7 Reviewed-by: Thiago Macieira <thiago.macieira@intel.com>
Diffstat (limited to 'src')
-rw-r--r--src/corelib/kernel/qmetatype.h13
-rw-r--r--src/tools/moc/generator.cpp20
2 files changed, 27 insertions, 6 deletions
diff --git a/src/corelib/kernel/qmetatype.h b/src/corelib/kernel/qmetatype.h
index e5a71dd5a8..f89ece7d23 100644
--- a/src/corelib/kernel/qmetatype.h
+++ b/src/corelib/kernel/qmetatype.h
@@ -2828,12 +2828,21 @@ template<typename T>
using qRemovePointerLike_t = typename qRemovePointerLike<T>::type;
#undef Q_REMOVE_POINTER_LIKE_IMPL
-template<typename Unique, typename T>
+template<typename T, typename ForceComplete_>
+struct TypeAndForceComplete
+{
+ using type = T;
+ using ForceComplete = ForceComplete_;
+};
+
+template<typename Unique, typename TypeCompletePair>
constexpr QMetaTypeInterface *qTryMetaTypeInterfaceForType()
{
+ using T = typename TypeCompletePair::type;
+ using ForceComplete = typename TypeCompletePair::ForceComplete;
using Ty = std::remove_cv_t<std::remove_reference_t<T>>;
using Tz = qRemovePointerLike_t<Ty>;
- if constexpr (!is_complete<Tz, Unique>::value) {
+ if constexpr (!is_complete<Tz, Unique>::value && !ForceComplete::value) {
return nullptr;
} else {
return &QMetaTypeForType<Ty>::metaType;
diff --git a/src/tools/moc/generator.cpp b/src/tools/moc/generator.cpp
index 9fd61a34c3..da3f22aa96 100644
--- a/src/tools/moc/generator.cpp
+++ b/src/tools/moc/generator.cpp
@@ -580,17 +580,26 @@ void Generator::generateCode()
}
for (int i = 0; i < cdef->propertyList.count(); ++i) {
const PropertyDef &p = cdef->propertyList.at(i);
- fprintf(out, "%s%s", needsComma ? ", " : "", p.type.data());
+ if (requireCompleteTypes)
+ fprintf(out, "%s%s", needsComma ? ", " : "", p.type.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);
- fprintf(out, "%s%s", needsComma ? ", " : "", fdef.type.name.data());
+ if (requireCompleteTypes)
+ 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) {
- fprintf(out, ", %s", argument.type.name.data());
+ if (requireCompleteTypes)
+ fprintf(out, ", %s", argument.type.name.data());
+ else
+ fprintf(out, ", QtPrivate::TypeAndForceComplete<%s, std::false_type>", argument.type.name.data());
}
}
fprintf(out, "\n");
@@ -598,7 +607,10 @@ void Generator::generateCode()
for (int i = 0; i< cdef->constructorList.count(); ++i) {
const FunctionDef& fdef = cdef->constructorList.at(i);
for (const auto &argument: fdef.arguments) {
- fprintf(out, "%s%s", needsComma ? ", " : "", argument.type.name.data());
+ if (requireCompleteTypes)
+ fprintf(out, "%s%s", needsComma ? ", " : "", argument.type.name.data());
+ else
+ fprintf(out, "%sQtPrivate::TypeAndForceComplete<%s, std::false_type>", needsComma ? ", " : "", argument.type.name.data());
needsComma = true;
}
}