summaryrefslogtreecommitdiffstats
path: root/src/corelib/kernel/qmetatype.h
diff options
context:
space:
mode:
authorFabian Kosmale <fabian.kosmale@qt.io>2020-03-19 10:47:29 +0100
committerFabian Kosmale <fabian.kosmale@qt.io>2020-06-02 22:42:15 +0200
commitfa987d44417528856d5e80ed7b48ba99e19fa307 (patch)
tree50cd74c1a9dd3c2197f7de2ac0d431a5b16b0a42 /src/corelib/kernel/qmetatype.h
parent5306fdabc1ceb09875f791526553b3665017f7ce (diff)
MetaObject: Store the QMetaType of the methods
This does the analog of 46f407126ef3e94d59254012cdc34d6a4ad2faf2 for the methods we care about (signals, slots, Q_INVOKABLEs). In addition to the actual QMetaType, we store an array with offsets so that we later can do a mapping from methodIndex to metatype. The newly added QMetaMethod::{return,parameter}MetaType methods can then be used to retrieve the metatypes. This does however require that all involved types are complete. This is unfortunately not a feasible requirement. Thus, we only populate the metatype array on a best effort basis. For any incomplete type, we store QMetaType::Unknown. Then, when accessing the metatype, we fall back to the old string based code base if it's Unknown. Squashes "moc: support incomplete types" and "Fix compile failures after QMetaMethod change" Fixes: QTBUG-82932 Change-Id: I6b7a587cc364b7cad0c158d6de54e8a204289ad4 Reviewed-by: Lars Knoll <lars.knoll@qt.io>
Diffstat (limited to 'src/corelib/kernel/qmetatype.h')
-rw-r--r--src/corelib/kernel/qmetatype.h34
1 files changed, 34 insertions, 0 deletions
diff --git a/src/corelib/kernel/qmetatype.h b/src/corelib/kernel/qmetatype.h
index 05fe4450df..60192e4131 100644
--- a/src/corelib/kernel/qmetatype.h
+++ b/src/corelib/kernel/qmetatype.h
@@ -2796,6 +2796,35 @@ constexpr QMetaTypeInterface *qMetaTypeInterfaceForType()
}
}
+namespace detail {
+
+template <typename T, typename ODR_VIOLATION_PREVENTER>
+struct is_complete_helper {
+ template <typename U>
+ static auto check(U*) -> std::integral_constant<bool, sizeof(U) != 0>;
+ static auto check(...) -> std::false_type;
+ using type = decltype(check(static_cast<T*>(nullptr)));
+};
+
+}
+
+template <typename T, typename ODR_VIOLATION_PREVENTER>
+struct is_complete : detail::is_complete_helper<T, ODR_VIOLATION_PREVENTER>::type {};
+
+template<typename Unique, typename T>
+constexpr QMetaTypeInterface *qTryMetaTypeInterfaceForType()
+{
+ using Ty = std::remove_cv_t<std::remove_reference_t<T>>;
+ using Tz = std::remove_pointer_t<Ty>;
+ if constexpr (!is_complete<Tz, Unique>::value) {
+ return nullptr;
+ } else if constexpr (std::is_same_v<Ty, void>) {
+ return nullptr;
+ } else {
+ return &QMetaTypeForType<Ty>::metaType;
+ }
+}
+
} // namespace QtPrivate
template<typename T>
@@ -2809,6 +2838,11 @@ QtPrivate::QMetaTypeInterface *const qt_metaTypeArray[] = {
QtPrivate::qMetaTypeInterfaceForType<T>()...
};
+template<typename Unique,typename... T>
+QtPrivate::QMetaTypeInterface *const qt_incomplete_metaTypeArray[] = {
+ QtPrivate::qTryMetaTypeInterfaceForType<Unique, T>()...
+};
+
QT_END_NAMESPACE
#endif // QMETATYPE_H