From 6c54e10144e7af02f4c35e20e5f375a0cf280b8b Mon Sep 17 00:00:00 2001 From: Olivier Goffart Date: Tue, 8 Mar 2016 11:07:53 +0100 Subject: Qt Meta macros: Allow tools to define annotations MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit This might be useful for IDE or other tools to be made aware of Qt macros. This is inspired to what QtCreator[1] and moc-ng[2] does. But they are forced to redefine or inject code at precise location which might be difficult. This is going to make it easier to use libclang in qdoc. With this change, the tooling can just predefine the macro QT_ANNOTATE_FUNCTION and QT_ANNOTATE_CLASS to get what they need. Example with libclang: "-DQT_ANNOTATE_CLASS(type,...)=static_assert(sizeof(#__VA_ARGS__),#type);" "-DQT_ANNOTATE_CLASS2(type,a1,a2)=static_assert(sizeof(#a1,#a2),#type);" "-DQT_ANNOTATE_FUNCTION(a)=__attribute__((annotate(#a)))" "-DQT_ANNOTATE_ACCESS_SPECIFIER(a)=__attribute__((annotate(#a)))" "-DQ_CLASSINFO(name,value)=static_assert(sizeof(name,value),\"qt_classinfo\");" "-DQ_REVISION(v)=__attribute__((annotate(\"qt_revision:\" QT_STRINGIFY2(v))))" [1] qt-creator/cplusplus/wrappedQtHeaders/QtCore/qobjectdefs.h [2] https://code.woboq.org/mocng/src/qobjectdefs-injected.h.html Change-Id: I88fcb28f1dbb3d26ea82f10e9948e68a18c795e9 Reviewed-by: Nikolai Kosjar Reviewed-by: Kevin Funk Reviewed-by: Milian Wolff Reviewed-by: Thiago Macieira Reviewed-by: Jędrzej Nowacki --- src/corelib/kernel/qobjectdefs.h | 73 +++++++++++++++++++++++++++------------- 1 file changed, 50 insertions(+), 23 deletions(-) (limited to 'src/corelib/kernel/qobjectdefs.h') diff --git a/src/corelib/kernel/qobjectdefs.h b/src/corelib/kernel/qobjectdefs.h index 2e9ed4fb5f..8d32795af2 100644 --- a/src/corelib/kernel/qobjectdefs.h +++ b/src/corelib/kernel/qobjectdefs.h @@ -55,6 +55,25 @@ class QString; #define Q_MOC_OUTPUT_REVISION 67 #endif +// The following macros can be defined by tools that understand Qt +// to have the information from the macro. +#ifndef QT_ANNOTATE_CLASS +# ifndef Q_COMPILER_VARIADIC_MACROS +# define QT_ANNOTATE_CLASS(type, x) +# else +# define QT_ANNOTATE_CLASS(type, ...) +# endif +#endif +#ifndef QT_ANNOTATE_CLASS2 +# define QT_ANNOTATE_CLASS2(type, a1, a2) +#endif +#ifndef QT_ANNOTATE_FUNCTION +# define QT_ANNOTATE_FUNCTION(x) +#endif +#ifndef QT_ANNOTATE_ACCESS_SPECIFIER +# define QT_ANNOTATE_ACCESS_SPECIFIER(x) +#endif + // The following macros are our "extensions" to C++ // They are used, strictly speaking, only by the moc. @@ -64,38 +83,44 @@ class QString; # define QT_NO_EMIT # else # ifndef QT_NO_SIGNALS_SLOTS_KEYWORDS -# define slots -# define signals public +# define slots Q_SLOTS +# define signals Q_SIGNALS # endif # endif -# define Q_SLOTS -# define Q_SIGNALS public -# define Q_PRIVATE_SLOT(d, signature) +# define Q_SLOTS QT_ANNOTATE_ACCESS_SPECIFIER(qt_slot) +# define Q_SIGNALS public QT_ANNOTATE_ACCESS_SPECIFIER(qt_signal) +# define Q_PRIVATE_SLOT(d, signature) QT_ANNOTATE_CLASS2(qt_private_slot, d, signature) # define Q_EMIT #ifndef QT_NO_EMIT # define emit #endif -#define Q_CLASSINFO(name, value) -#define Q_PLUGIN_METADATA(x) -#define Q_INTERFACES(x) +#ifndef Q_CLASSINFO +# define Q_CLASSINFO(name, value) +#endif +#define Q_PLUGIN_METADATA(x) QT_ANNOTATE_CLASS(qt_plugin_metadata, x) +#define Q_INTERFACES(x) QT_ANNOTATE_CLASS(qt_interfaces, x) #ifdef Q_COMPILER_VARIADIC_MACROS -#define Q_PROPERTY(...) +# define Q_PROPERTY(...) QT_ANNOTATE_CLASS(qt_property, __VA_ARGS__) #else -#define Q_PROPERTY(text) +# define Q_PROPERTY(text) QT_ANNOTATE_CLASS(qt_property, text) +#endif +#define Q_PRIVATE_PROPERTY(d, text) QT_ANNOTATE_CLASS2(qt_private_property, d, text) +#ifndef Q_REVISION +# define Q_REVISION(v) #endif -#define Q_PRIVATE_PROPERTY(d, text) -#define Q_REVISION(v) -#define Q_OVERRIDE(text) -#define Q_ENUMS(x) -#define Q_FLAGS(x) -#define Q_ENUM(ENUM) \ +#define Q_OVERRIDE(text) QT_ANNOTATE_CLASS(qt_override, text) +#define QDOC_PROPERTY(text) QT_ANNOTATE_CLASS(qt_qdoc_property, text) +#define Q_ENUMS(x) QT_ANNOTATE_CLASS(qt_enums, x) +#define Q_FLAGS(x) QT_ANNOTATE_CLASS(qt_enums, x) +#define Q_ENUM_IMPL(ENUM) \ friend Q_DECL_CONSTEXPR const QMetaObject *qt_getEnumMetaObject(ENUM) Q_DECL_NOEXCEPT { return &staticMetaObject; } \ friend Q_DECL_CONSTEXPR const char *qt_getEnumName(ENUM) Q_DECL_NOEXCEPT { return #ENUM; } -#define Q_FLAG(ENUM) Q_ENUM(ENUM) -#define Q_SCRIPTABLE -#define Q_INVOKABLE -#define Q_SIGNAL -#define Q_SLOT +#define Q_ENUM(x) Q_ENUMS(x) Q_ENUM_IMPL(x) +#define Q_FLAG(x) Q_FLAGS(x) Q_ENUM_IMPL(x) +#define Q_SCRIPTABLE QT_ANNOTATE_FUNCTION(qt_scriptable) +#define Q_INVOKABLE QT_ANNOTATE_FUNCTION(qt_invokable) +#define Q_SIGNAL QT_ANNOTATE_FUNCTION(qt_signal) +#define Q_SLOT QT_ANNOTATE_FUNCTION(qt_slot) #endif // QT_NO_META_MACROS #ifndef QT_NO_TRANSLATION @@ -173,10 +198,11 @@ private: \ Q_OBJECT_NO_ATTRIBUTES_WARNING \ Q_DECL_HIDDEN_STATIC_METACALL static void qt_static_metacall(QObject *, QMetaObject::Call, int, void **); \ QT_WARNING_POP \ - struct QPrivateSignal {}; + struct QPrivateSignal {}; \ + QT_ANNOTATE_CLASS(qt_qobject, "") /* qmake ignore Q_OBJECT */ -#define Q_OBJECT_FAKE Q_OBJECT +#define Q_OBJECT_FAKE Q_OBJECT QT_ANNOTATE_CLASS(qt_fake, "") #ifndef QT_NO_META_MACROS /* qmake ignore Q_GADGET */ @@ -190,6 +216,7 @@ private: \ Q_OBJECT_NO_ATTRIBUTES_WARNING \ Q_DECL_HIDDEN_STATIC_METACALL static void qt_static_metacall(QObject *, QMetaObject::Call, int, void **); \ QT_WARNING_POP \ + QT_ANNOTATE_CLASS(qt_qgadget, "") \ /*end*/ #endif // QT_NO_META_MACROS -- cgit v1.2.3