From 4f7649633c7402af08e34f20628e6e827fc3d28e Mon Sep 17 00:00:00 2001 From: Nikolai Kosjar Date: Mon, 27 Jul 2015 10:47:08 +0200 Subject: [PATCH] Clang: Free us from specific Qt versions More precisely, free us from specific Q_MOC_RUN/QT_NO_META_MACROS code paths in QtCore/qobjectdefs.h. In order to track signals and slots we provided custom definitions of e.g. "Q_SIGNAL" by including qt5-qobjectdefs-injected.h with "-include". We also had to ensure that those macros were not overwritten by Qt's qobjectdefs.h, which we did by defining QT_NO_META_MACROS. However, this came with a cost: we needed to replicate all the other macro definitions in the Q_MOC_RUN/QT_NO_META_MACROS code path, e.g. Q_INTERFACES. This bound us to specific versions of qobjectdefs.h and occasionally we had to adapt (see change 4eafa2e02be4e659f8bb5f6ab020844174e82f47). The new approach wraps Qt's qobjectdefs.h with the help of "include_next". In the wrapper header, we only redefine what is necessary. The "include_next" directive is originally a GNU extension. Clang seems to support it unconditionally, as [1] implicitly states. [1] http://clang.llvm.org/docs/LanguageExtensions.html#include-file-checking-macros Change-Id: Ic1a263f94b178349cb32bfdbb074ad5e6e0761ee Reviewed-by: Christian Kandeler Reviewed-by: Erik Verbruggen --- .../QtCore/qobjectdefs.h} | 61 ++++++++----------- src/plugins/clangcodemodel/clangutils.cpp | 19 +++--- 2 files changed, 33 insertions(+), 47 deletions(-) rename share/qtcreator/cplusplus/{qt5-qobjectdefs-injected.h => wrappedQtHeaders/QtCore/qobjectdefs.h} (60%) diff --git a/share/qtcreator/cplusplus/qt5-qobjectdefs-injected.h b/share/qtcreator/cplusplus/wrappedQtHeaders/QtCore/qobjectdefs.h similarity index 60% rename from share/qtcreator/cplusplus/qt5-qobjectdefs-injected.h rename to share/qtcreator/cplusplus/wrappedQtHeaders/QtCore/qobjectdefs.h index cc7ca503bd7..2580ff1b424 100644 --- a/share/qtcreator/cplusplus/qt5-qobjectdefs-injected.h +++ b/share/qtcreator/cplusplus/wrappedQtHeaders/QtCore/qobjectdefs.h @@ -28,44 +28,35 @@ ** ****************************************************************************/ -#define QT_NO_META_MACROS +// Include qobjectdefs.h from Qt ... +#include_next -#if defined(QT_NO_KEYWORDS) -# define QT_NO_EMIT -#else -# ifndef QT_NO_SIGNALS_SLOTS_KEYWORDS -# define signals public __attribute__((annotate("qt_signal"))) -# define slots __attribute__((annotate("qt_slot"))) -# endif +#pragma clang diagnostic push +#pragma clang diagnostic ignored "-Wmacro-redefined" + +// ...and redefine macros for tagging signals/slots +#ifdef signals +# define signals public __attribute__((annotate("qt_signal"))) #endif -#define Q_SIGNALS public __attribute__((annotate("qt_signal"))) -#define Q_SLOTS slots __attribute__((annotate("qt_slot"))) -#define Q_SIGNAL __attribute__((annotate("qt_signal"))) -#define Q_SLOT __attribute__((annotate("qt_slot"))) -#define Q_PRIVATE_SLOT(d, signature) -#define Q_EMIT -#ifndef QT_NO_EMIT -# define emit +#ifdef slots +# define slots __attribute__((annotate("qt_slot"))) #endif -#define Q_CLASSINFO(name, value) -#define Q_PLUGIN_METADATA(x) -#define Q_INTERFACES(x) -#define Q_PROPERTY(text) -#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(x) -#define Q_FLAG(x) -#define Q_SCRIPTABLE -#define Q_INVOKABLE -#define Q_GADGET \ -public: \ - static const QMetaObject staticMetaObject; \ -private: +#ifdef Q_SIGNALS +# define Q_SIGNALS public __attribute__((annotate("qt_signal"))) +#endif -#define SIGNAL(a) #a -#define SLOT(a) #a +#ifdef Q_SLOTS +# define Q_SLOTS slots __attribute__((annotate("qt_slot"))) +#endif + +#ifdef Q_SIGNAL +# define Q_SIGNAL __attribute__((annotate("qt_signal"))) +#endif + +#ifdef Q_SLOT +# define Q_SLOT __attribute__((annotate("qt_slot"))) +#endif + +#pragma clang diagnostic pop diff --git a/src/plugins/clangcodemodel/clangutils.cpp b/src/plugins/clangcodemodel/clangutils.cpp index 22aad3235cd..02f448644fe 100644 --- a/src/plugins/clangcodemodel/clangutils.cpp +++ b/src/plugins/clangcodemodel/clangutils.cpp @@ -130,8 +130,8 @@ public: optionsBuilder.addToolchainAndProjectDefines(); optionsBuilder.addResourceDirOptions(); + optionsBuilder.addWrappedQtHeadersIncludePath(); optionsBuilder.addHeaderPathOptions(); - optionsBuilder.addInjectedHeaderWithCustomQtMacros(); optionsBuilder.addProjectConfigFileInclude(); optionsBuilder.addExtraOptions(); @@ -160,19 +160,14 @@ private: } } - void addInjectedHeaderWithCustomQtMacros() + void addWrappedQtHeadersIncludePath() { - static const QString injectedHeader = ICore::instance()->resourcePath() - + QLatin1String("/cplusplus/qt%1-qobjectdefs-injected.h"); + static const QString wrappedQtHeaders = ICore::instance()->resourcePath() + + QLatin1String("/cplusplus/wrappedQtHeaders"); -// if (pPart->qtVersion == ProjectPart::Qt4) { -// builder.addOption(QLatin1String("-include")); -// builder.addOption(injectedHeader.arg(QLatin1Char('4'))); -// } - - if (m_projectPart->qtVersion == ProjectPart::Qt5) { - add(QLatin1String("-include")); - add(injectedHeader.arg(QLatin1Char('5'))); + if (m_projectPart->qtVersion != ProjectPart::NoQt) { + add(QLatin1String("-I") + wrappedQtHeaders); + add(QLatin1String("-I") + wrappedQtHeaders + QLatin1String("/QtCore")); } }