summaryrefslogtreecommitdiffstats
path: root/src/corelib
diff options
context:
space:
mode:
authorOlivier Goffart <ogoffart@woboq.com>2013-09-14 13:18:15 +0200
committerThe Qt Project <gerrit-noreply@qt-project.org>2013-09-14 20:33:29 +0200
commit7d7e8ae3fa79b06c916de1a7a10eed63611c5d25 (patch)
treebd663644f5f3d46e8760e0de908e2faaf5fff12e /src/corelib
parent6b9d1256214839dd18b2ba5c6fc6f007cf21869f (diff)
Use Q_STATIC_ASSERT to report error about missing Q_OBJECT
Q_STATIC_ASSERT gives better error with C++11 enabled. Aslo the qt_check_for_QOBJECT_macro had warning on some compiler since it used null reference Change-Id: Ic6115da800064b00c50a5762f0b79f5f656bf750 Reviewed-by: Thiago Macieira <thiago.macieira@intel.com>
Diffstat (limited to 'src/corelib')
-rw-r--r--src/corelib/kernel/qmetaobject.h4
-rw-r--r--src/corelib/kernel/qobject.h26
-rw-r--r--src/corelib/kernel/qobject_impl.h1
-rw-r--r--src/corelib/kernel/qobject_p.h6
-rw-r--r--src/corelib/kernel/qobjectdefs.h10
5 files changed, 34 insertions, 13 deletions
diff --git a/src/corelib/kernel/qmetaobject.h b/src/corelib/kernel/qmetaobject.h
index 0c8ad8591f..818613195d 100644
--- a/src/corelib/kernel/qmetaobject.h
+++ b/src/corelib/kernel/qmetaobject.h
@@ -148,8 +148,8 @@ public:
static inline QMetaMethod fromSignal(Func signal)
{
typedef QtPrivate::FunctionPointer<Func> SignalType;
- reinterpret_cast<typename SignalType::Object *>(0)->qt_check_for_QOBJECT_macro(
- *reinterpret_cast<typename SignalType::Object *>(0));
+ Q_STATIC_ASSERT_X(QtPrivate::HasQ_OBJECT_Macro<typename SignalType::Object>::Value,
+ "No Q_OBJECT in the class with the signal");
return fromSignalImpl(&SignalType::Object::staticMetaObject,
reinterpret_cast<void **>(&signal));
}
diff --git a/src/corelib/kernel/qobject.h b/src/corelib/kernel/qobject.h
index aaa09fac50..9d49bf26d2 100644
--- a/src/corelib/kernel/qobject.h
+++ b/src/corelib/kernel/qobject.h
@@ -217,7 +217,9 @@ public:
{
typedef QtPrivate::FunctionPointer<Func1> SignalType;
typedef QtPrivate::FunctionPointer<Func2> SlotType;
- reinterpret_cast<typename SignalType::Object *>(0)->qt_check_for_QOBJECT_macro(*reinterpret_cast<typename SignalType::Object *>(0));
+
+ Q_STATIC_ASSERT_X(QtPrivate::HasQ_OBJECT_Macro<typename SignalType::Object>::Value,
+ "No Q_OBJECT in the class with the signal");
//compilation error if the arguments does not match.
Q_STATIC_ASSERT_X(int(SignalType::ArgumentCount) >= int(SlotType::ArgumentCount),
@@ -246,6 +248,9 @@ public:
typedef QtPrivate::FunctionPointer<Func1> SignalType;
typedef QtPrivate::FunctionPointer<Func2> SlotType;
+ Q_STATIC_ASSERT_X(QtPrivate::HasQ_OBJECT_Macro<typename SignalType::Object>::Value,
+ "No Q_OBJECT in the class with the signal");
+
//compilation error if the arguments does not match.
Q_STATIC_ASSERT_X(int(SignalType::ArgumentCount) >= int(SlotType::ArgumentCount),
"The slot requires more arguments than the signal provides.");
@@ -307,6 +312,9 @@ public:
Q_STATIC_ASSERT_X((QtPrivate::AreArgumentsCompatible<SlotReturnType, typename SignalType::ReturnType>::value),
"Return type of the slot is not compatible with the return type of the signal.");
+ Q_STATIC_ASSERT_X(QtPrivate::HasQ_OBJECT_Macro<typename SignalType::Object>::Value,
+ "No Q_OBJECT in the class with the signal");
+
return connectImpl(sender, reinterpret_cast<void **>(&signal), sender, 0,
new QtPrivate::QFunctorSlotObject<Func2, SlotArgumentCount,
typename QtPrivate::List_Left<typename SignalType::Arguments, SlotArgumentCount>::Value,
@@ -335,7 +343,9 @@ public:
{
typedef QtPrivate::FunctionPointer<Func1> SignalType;
typedef QtPrivate::FunctionPointer<Func2> SlotType;
- reinterpret_cast<typename SignalType::Object *>(0)->qt_check_for_QOBJECT_macro(*reinterpret_cast<typename SignalType::Object *>(0));
+
+ Q_STATIC_ASSERT_X(QtPrivate::HasQ_OBJECT_Macro<typename SignalType::Object>::Value,
+ "No Q_OBJECT in the class with the signal");
//compilation error if the arguments does not match.
Q_STATIC_ASSERT_X((QtPrivate::CheckCompatibleArguments<typename SignalType::Arguments, typename SlotType::Arguments>::value),
@@ -477,18 +487,18 @@ inline QT_DEPRECATED QList<T> qFindChildren(const QObject *o, const QRegExp &re)
template <class T>
inline T qobject_cast(QObject *object)
{
-#if !defined(QT_NO_QOBJECT_CHECK)
- reinterpret_cast<T>(object)->qt_check_for_QOBJECT_macro(*reinterpret_cast<T>(object));
-#endif
+ typedef typename QtPrivate::remove_cv<typename QtPrivate::remove_pointer<T>::type>::type ObjType;
+ Q_STATIC_ASSERT_X(QtPrivate::HasQ_OBJECT_Macro<ObjType>::Value,
+ "qobject_cast require the type to have a Q_OBJECT macro");
return static_cast<T>(reinterpret_cast<T>(object)->staticMetaObject.cast(object));
}
template <class T>
inline T qobject_cast(const QObject *object)
{
-#if !defined(QT_NO_QOBJECT_CHECK)
- reinterpret_cast<T>(object)->qt_check_for_QOBJECT_macro(*reinterpret_cast<T>(const_cast<QObject *>(object)));
-#endif
+ typedef typename QtPrivate::remove_cv<typename QtPrivate::remove_pointer<T>::type>::type ObjType;
+ Q_STATIC_ASSERT_X(QtPrivate::HasQ_OBJECT_Macro<ObjType>::Value,
+ "qobject_cast require the type to have a Q_OBJECT macro");
return static_cast<T>(reinterpret_cast<T>(object)->staticMetaObject.cast(object));
}
diff --git a/src/corelib/kernel/qobject_impl.h b/src/corelib/kernel/qobject_impl.h
index 0b5631f2a6..1bbd548be6 100644
--- a/src/corelib/kernel/qobject_impl.h
+++ b/src/corelib/kernel/qobject_impl.h
@@ -204,7 +204,6 @@ namespace QtPrivate {
public:
explicit QFunctorSlotObject(const Func &f) : QSlotObjectBase(&impl), function(f) {}
};
-
}
diff --git a/src/corelib/kernel/qobject_p.h b/src/corelib/kernel/qobject_p.h
index 3c43972ac9..562b0d24c7 100644
--- a/src/corelib/kernel/qobject_p.h
+++ b/src/corelib/kernel/qobject_p.h
@@ -316,7 +316,8 @@ inline QMetaObject::Connection QObjectPrivate::connect(const typename QtPrivate:
{
typedef QtPrivate::FunctionPointer<Func1> SignalType;
typedef QtPrivate::FunctionPointer<Func2> SlotType;
- reinterpret_cast<typename SignalType::Object *>(0)->qt_check_for_QOBJECT_macro(*reinterpret_cast<typename SignalType::Object *>(0));
+ Q_STATIC_ASSERT_X(QtPrivate::HasQ_OBJECT_Macro<typename SignalType::Object>::Value,
+ "No Q_OBJECT in the class with the signal");
//compilation error if the arguments does not match.
Q_STATIC_ASSERT_X(int(SignalType::ArgumentCount) >= int(SlotType::ArgumentCount),
@@ -343,7 +344,8 @@ bool QObjectPrivate::disconnect(const typename QtPrivate::FunctionPointer< Func1
{
typedef QtPrivate::FunctionPointer<Func1> SignalType;
typedef QtPrivate::FunctionPointer<Func2> SlotType;
- reinterpret_cast<typename SignalType::Object *>(0)->qt_check_for_QOBJECT_macro(*reinterpret_cast<typename SignalType::Object *>(0));
+ Q_STATIC_ASSERT_X(QtPrivate::HasQ_OBJECT_Macro<typename SignalType::Object>::Value,
+ "No Q_OBJECT in the class with the signal");
//compilation error if the arguments does not match.
Q_STATIC_ASSERT_X((QtPrivate::CheckCompatibleArguments<typename SignalType::Arguments, typename SlotType::Arguments>::value),
"Signal and slot arguments are not compatible.");
diff --git a/src/corelib/kernel/qobjectdefs.h b/src/corelib/kernel/qobjectdefs.h
index dd10e70609..7354c3f0d0 100644
--- a/src/corelib/kernel/qobjectdefs.h
+++ b/src/corelib/kernel/qobjectdefs.h
@@ -480,6 +480,16 @@ public:
inline const QMetaObject *QMetaObject::superClass() const
{ return d.superdata; }
+namespace QtPrivate {
+ /* Trait that tells is a the Object has a Q_OBJECT macro */
+ template <typename Object> struct HasQ_OBJECT_Macro {
+ template <typename T>
+ static char test(int (T::*)(QMetaObject::Call, int, void **));
+ static int test(int (Object::*)(QMetaObject::Call, int, void **));
+ enum { Value = sizeof(test(&Object::qt_metacall)) == sizeof(int) };
+ };
+}
+
QT_END_NAMESPACE
#endif // QOBJECTDEFS_H