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 fa987d4441
Change-Id: I5f66ff289631c056eecebe40926bf321d283eea7
Reviewed-by: Thiago Macieira <thiago.macieira@intel.com>
bb10
parent
af7a3430ed
commit
27fcf66319
|
|
@ -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;
|
||||
|
|
|
|||
|
|
@ -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;
|
||||
}
|
||||
}
|
||||
|
|
|
|||
Loading…
Reference in New Issue