woboq/verdigris

Need to undefine READ when using QtQuck [Qt 5.8]

fmorgner opened this issue · 2 comments

Hi

I am not sure if I am using verdigris wrong, or if it is an issue purely related to verdigris in combination with QtQuick. I tried implementing a very simple example application an ran into the following issue:

In file included from main.cpp:4:
In file included from /usr/include/qt/QtQuick/QQuickView:1:
In file included from /usr/include/qt/QtQuick/qquickview.h:43:
/usr/include/qt/QtQuick/qquickwindow.h:71:79: error: too many arguments provided to function-like macro invocation
    Q_PRIVATE_PROPERTY(QQuickWindow::d_func(), QQmlListProperty<QObject> data READ data DESIGNABLE false)
                                                                              ^
/usr/include/wobjectdefs.h:757:16: note: expanded from macro 'READ'
#define READ , &W_ThisType::
               ^
/usr/include/qt/QtCore/qobjectdefs.h:75:10: note: macro 'QT_ANNOTATE_CLASS2' defined here
# define QT_ANNOTATE_CLASS2(type, a1, a2)
         ^
In file included from main.cpp:4:
In file included from /usr/include/qt/QtQuick/QQuickView:1:
In file included from /usr/include/qt/QtQuick/qquickview.h:43:
/usr/include/qt/QtQuick/qquickwindow.h:71:5: error: unknown type name 'QT_ANNOTATE_CLASS2'
    Q_PRIVATE_PROPERTY(QQuickWindow::d_func(), QQmlListProperty<QObject> data READ data DESIGNABLE false)
    ^
/usr/include/qt/QtCore/qobjectdefs.h:114:37: note: expanded from macro 'Q_PRIVATE_PROPERTY'
#define Q_PRIVATE_PROPERTY(d, text) QT_ANNOTATE_CLASS2(qt_private_property, d, text)
                                    ^
In file included from main.cpp:4:
In file included from /usr/include/qt/QtQuick/QQuickView:1:
In file included from /usr/include/qt/QtQuick/qquickview.h:43:
/usr/include/qt/QtQuick/qquickwindow.h:76:5: error: expected member name or ';' after declaration specifiers
    Q_DECLARE_PRIVATE(QQuickWindow)
    ^
/usr/include/qt/QtCore/qglobal.h:964:5: note: expanded from macro 'Q_DECLARE_PRIVATE'
    inline Class##Private* d_func() { return reinterpret_cast<Class##Private *>(qGetPtrHelper(d_ptr)); } \
    ^
3 errors generated.

Obviously, the definition of READ used by verdigris is picked up by QT. If i #undef READ at the end of my UI objects declaration, i have no issues whatsoever. I am not sure if my use of verdigris is wrong/flawed or if it would be generally beneficial to undef the macros also used by QT at the end of wobjectdefs.h.

Following is the code for my simple application (with the #undef READ in place):

ui.h:

#ifndef UI_h
#define UI_h

#include <wobjectdefs.h>
#include <QObject>

class UIObject : public QObject
  {
  W_OBJECT(UIObject)

  public:
    QString m_author;

    QString author() const;

    void setAuthor(QString const & author);

    void authorChanged()
    W_SIGNAL(authorChanged)

    W_PROPERTY(QString, author READ author WRITE setAuthor NOTIFY authorChanged)
  };

#undef READ
#endif

ui.cpp:

#include "ui.h"
#include <wobjectimpl.h>

W_OBJECT_IMPL(UIObject)

QString UIObject::author() const
  {
  return m_author;
  }

void UIObject::setAuthor(QString const & author)
  {
  m_author = author;
  emit authorChanged();
  }

ui.qml:

import QtQuick 2.0

Text {
  width: 100
  height: 100
  text: msg.author

  Component.onCompleted: {
    msg.author = "Jonah"
  }
}

ui.pro:

CONFIG += c++14
TEMPLATE += app
TARGET = ui
QT += quick

SOURCES += ui.cpp main.cpp
HEADERS += ui.h

main.cpp:

#include "ui.h"

#include <QGuiApplication>
#include <QQuickView>
#include <QQmlEngine>
#include <QQmlContext>
#include <QQmlComponent>

int main(int argc, char * argv[])
  {
  QGuiApplication app{argc, argv};
  QQuickView view{};
  UIObject object{};

  view.engine()->rootContext()->setContextProperty("msg", &object);
  view.setSource(QUrl::fromLocalFile("ui.qml"));
  view.show();

  return app.exec();
  }

Thanks for the bug report.

I think we might need to redefine Q_PRIVATE_PROPERTY to Q_PRIVATE_PROPERTY(...)

Should be fixed with commit 0ab909d