summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--src/corelib/kernel/qobject.cpp17
-rw-r--r--src/corelib/kernel/qtmetamacros.h1
-rw-r--r--src/tools/moc/keywords.cpp25
-rw-r--r--src/tools/moc/moc.cpp21
-rw-r--r--src/tools/moc/moc.h1
-rw-r--r--src/tools/moc/token.h1
-rw-r--r--src/tools/moc/util/generate_keywords.cpp1
-rw-r--r--tests/auto/tools/moc/allmocs_baseline_in.json59
-rw-r--r--tests/auto/tools/moc/fwdclass1.h38
-rw-r--r--tests/auto/tools/moc/fwdclass2.h38
-rw-r--r--tests/auto/tools/moc/fwdclass3.h38
-rw-r--r--tests/auto/tools/moc/moc.pro3
-rw-r--r--tests/auto/tools/moc/moc_include.h74
-rw-r--r--tests/auto/tools/moc/tst_moc.cpp33
14 files changed, 339 insertions, 11 deletions
diff --git a/src/corelib/kernel/qobject.cpp b/src/corelib/kernel/qobject.cpp
index 133ccc88d9..c72383ff4a 100644
--- a/src/corelib/kernel/qobject.cpp
+++ b/src/corelib/kernel/qobject.cpp
@@ -4543,6 +4543,23 @@ QDebug operator<<(QDebug dbg, const QObject *o)
*/
/*!
+ \macro Q_MOC_INCLUDE
+ \relates QObject
+ \since 6.0
+
+ The Q_MOC_INCLUDE macro can be used within or outside a class, and tell the
+ \l{moc}{Meta Object Compiler} to add an include.
+
+ \code
+ // Put this in your code and the generated code will include this header.
+ Q_MOC_INCLUDE("myheader.h")
+ \endcode
+
+ This is useful if the types you use as properties or signal/slots arguments
+ are forward declared.
+*/
+
+/*!
\macro Q_SIGNALS
\relates QObject
diff --git a/src/corelib/kernel/qtmetamacros.h b/src/corelib/kernel/qtmetamacros.h
index 19b6bfa358..1d095c0d7c 100644
--- a/src/corelib/kernel/qtmetamacros.h
+++ b/src/corelib/kernel/qtmetamacros.h
@@ -112,6 +112,7 @@ QT_BEGIN_NAMESPACE
#define Q_INVOKABLE QT_ANNOTATE_FUNCTION(qt_invokable)
#define Q_SIGNAL QT_ANNOTATE_FUNCTION(qt_signal)
#define Q_SLOT QT_ANNOTATE_FUNCTION(qt_slot)
+#define Q_MOC_INCLUDE(...) QT_ANNOTATE_CLASS(qt_moc_include, __VA_ARGS__)
#endif // QT_NO_META_MACROS
#ifndef QT_NO_TRANSLATION
diff --git a/src/tools/moc/keywords.cpp b/src/tools/moc/keywords.cpp
index 7da8d94efc..cc7d747f5b 100644
--- a/src/tools/moc/keywords.cpp
+++ b/src/tools/moc/keywords.cpp
@@ -30,12 +30,12 @@
// DO NOT EDIT.
static const short keyword_trans[][128] = {
- {0,0,0,0,0,0,0,0,0,568,565,0,0,0,0,0,
+ {0,0,0,0,0,0,0,0,0,579,576,0,0,0,0,0,
0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
- 568,252,566,569,8,38,239,567,25,26,236,234,30,235,27,237,
+ 579,252,577,580,8,38,239,578,25,26,236,234,30,235,27,237,
22,22,22,22,22,22,22,22,22,22,34,41,23,39,24,43,
0,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,
- 8,21,8,8,8,8,8,8,8,8,8,31,571,32,238,8,
+ 8,21,8,8,8,8,8,8,8,8,8,31,582,32,238,8,
0,1,2,3,4,5,6,7,8,9,8,8,10,11,12,13,
14,8,15,16,17,18,19,20,8,8,8,36,245,37,248,0},
{0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
@@ -177,7 +177,7 @@ static const short keyword_trans[][128] = {
{0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
0,0,0,0,0,0,0,0,0,0,42,0,0,0,28,0,
- 574,574,574,574,574,574,574,574,574,574,0,0,0,0,0,0,
+ 585,585,585,585,585,585,585,585,585,585,0,0,0,0,0,0,
0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
@@ -336,7 +336,7 @@ static const short keyword_trans[][128] = {
0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0},
{0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
- 0,0,0,0,0,0,0,0,0,0,573,0,0,0,0,572,
+ 0,0,0,0,0,0,0,0,0,0,584,0,0,0,0,583,
0,0,0,0,0,0,0,0,0,0,0,0,0,258,0,0,
0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
@@ -378,7 +378,7 @@ static const short keyword_trans[][128] = {
0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
- 0,0,0,475,424,408,416,380,0,484,0,0,0,0,364,358,
+ 0,0,0,475,424,408,416,380,0,484,0,0,0,565,364,358,
386,0,557,472,0,0,0,0,0,0,0,0,0,0,0,0,
0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0},
@@ -1021,11 +1021,22 @@ static const struct
{CHARACTER, 0, 79, 563, CHARACTER},
{CHARACTER, 0, 78, 564, CHARACTER},
{Q_REVISION_TOKEN, 0, 0, 0, CHARACTER},
+ {CHARACTER, 0, 79, 566, CHARACTER},
+ {CHARACTER, 0, 67, 567, CHARACTER},
+ {CHARACTER, 0, 95, 568, CHARACTER},
+ {CHARACTER, 0, 73, 569, CHARACTER},
+ {CHARACTER, 0, 78, 570, CHARACTER},
+ {CHARACTER, 0, 67, 571, CHARACTER},
+ {CHARACTER, 0, 76, 572, CHARACTER},
+ {CHARACTER, 0, 85, 573, CHARACTER},
+ {CHARACTER, 0, 68, 574, CHARACTER},
+ {CHARACTER, 0, 69, 575, CHARACTER},
+ {Q_MOC_INCLUDE_TOKEN, 0, 0, 0, CHARACTER},
{NEWLINE, 0, 0, 0, NOTOKEN},
{QUOTE, 0, 0, 0, NOTOKEN},
{SINGLEQUOTE, 0, 0, 0, NOTOKEN},
{WHITESPACE, 0, 0, 0, NOTOKEN},
- {HASH, 0, 35, 570, HASH},
+ {HASH, 0, 35, 581, HASH},
{PP_HASHHASH, 0, 0, 0, NOTOKEN},
{BACKSLASH, 0, 0, 0, NOTOKEN},
{CPP_COMMENT, 0, 0, 0, NOTOKEN},
diff --git a/src/tools/moc/moc.cpp b/src/tools/moc/moc.cpp
index 7b132493f8..2fb8c8dee3 100644
--- a/src/tools/moc/moc.cpp
+++ b/src/tools/moc/moc.cpp
@@ -653,6 +653,11 @@ void Moc::parse()
case Q_CLASSINFO_TOKEN:
parseClassInfo(&def);
break;
+ case Q_MOC_INCLUDE_TOKEN:
+ // skip it, the namespace is parsed twice
+ next(LPAREN);
+ lexemUntil(RPAREN);
+ break;
case ENUM: {
EnumDef enumDef;
if (parseEnum(&enumDef))
@@ -696,6 +701,9 @@ void Moc::parse()
case Q_DECLARE_METATYPE_TOKEN:
parseDeclareMetatype();
break;
+ case Q_MOC_INCLUDE_TOKEN:
+ parseMocInclude();
+ break;
case USING:
if (test(NAMESPACE)) {
while (test(SCOPE) || test(IDENTIFIER))
@@ -828,6 +836,9 @@ void Moc::parse()
case Q_CLASSINFO_TOKEN:
parseClassInfo(&def);
break;
+ case Q_MOC_INCLUDE_TOKEN:
+ parseMocInclude();
+ break;
case Q_INTERFACES_TOKEN:
parseInterfaces(&def);
break;
@@ -1562,6 +1573,16 @@ void Moc::parseDeclareMetatype()
metaTypes.append(typeName);
}
+void Moc::parseMocInclude()
+{
+ next(LPAREN);
+ QByteArray include = lexemUntil(RPAREN);
+ // remove parentheses
+ include.remove(0, 1);
+ include.chop(1);
+ includeFiles.append(include);
+}
+
void Moc::parseSlotInPrivate(ClassDef *def, FunctionDef::Access access)
{
next(LPAREN);
diff --git a/src/tools/moc/moc.h b/src/tools/moc/moc.h
index 1d70fa154b..91a03a767f 100644
--- a/src/tools/moc/moc.h
+++ b/src/tools/moc/moc.h
@@ -256,6 +256,7 @@ public:
void parseInterfaces(ClassDef *def);
void parseDeclareInterface();
void parseDeclareMetatype();
+ void parseMocInclude();
void parseSlotInPrivate(ClassDef *def, FunctionDef::Access access);
void parsePrivateProperty(ClassDef *def);
diff --git a/src/tools/moc/token.h b/src/tools/moc/token.h
index 0cc163f9e4..c11ec6a38c 100644
--- a/src/tools/moc/token.h
+++ b/src/tools/moc/token.h
@@ -179,6 +179,7 @@ QT_BEGIN_NAMESPACE
F(Q_SCRIPTABLE_TOKEN) \
F(Q_PRIVATE_PROPERTY_TOKEN) \
F(Q_REVISION_TOKEN) \
+ F(Q_MOC_INCLUDE_TOKEN) \
F(SPECIAL_TREATMENT_MARK) \
F(MOC_INCLUDE_BEGIN) \
F(MOC_INCLUDE_END) \
diff --git a/src/tools/moc/util/generate_keywords.cpp b/src/tools/moc/util/generate_keywords.cpp
index 9248e9e2e7..c2cfe37fab 100644
--- a/src/tools/moc/util/generate_keywords.cpp
+++ b/src/tools/moc/util/generate_keywords.cpp
@@ -243,6 +243,7 @@ static const Keyword keywords[] = {
{ "Q_SCRIPTABLE", "Q_SCRIPTABLE_TOKEN" },
{ "Q_PRIVATE_PROPERTY", "Q_PRIVATE_PROPERTY_TOKEN" },
{ "Q_REVISION", "Q_REVISION_TOKEN" },
+ { "Q_MOC_INCLUDE", "Q_MOC_INCLUDE_TOKEN" },
{ "\n", "NEWLINE" },
{ "\"", "QUOTE" },
{ "\'", "SINGLEQUOTE" },
diff --git a/tests/auto/tools/moc/allmocs_baseline_in.json b/tests/auto/tools/moc/allmocs_baseline_in.json
index c8abba6a8f..2a70a52587 100644
--- a/tests/auto/tools/moc/allmocs_baseline_in.json
+++ b/tests/auto/tools/moc/allmocs_baseline_in.json
@@ -1015,6 +1015,65 @@
{
"classes": [
{
+ "className": "TestFwdProperties",
+ "properties": [
+ {
+ "constant": false,
+ "designable": true,
+ "final": false,
+ "name": "prop1",
+ "read": "getProp1",
+ "scriptable": true,
+ "stored": true,
+ "type": "FwdClass1",
+ "user": false,
+ "write": "setProp1"
+ },
+ {
+ "constant": false,
+ "designable": true,
+ "final": false,
+ "name": "prop2",
+ "read": "getProp2",
+ "scriptable": true,
+ "stored": true,
+ "type": "FwdClass2",
+ "user": false,
+ "write": "setProp2"
+ },
+ {
+ "constant": false,
+ "designable": true,
+ "final": false,
+ "name": "prop3",
+ "read": "getProp3",
+ "scriptable": true,
+ "stored": true,
+ "type": "FwdClass3",
+ "user": false,
+ "write": "setProp3"
+ }
+ ],
+ "qualifiedClassName": "TestFwdProperties",
+ "superClasses": [
+ {
+ "access": "public",
+ "name": "QObject"
+ }
+ ]
+ },
+ {
+ "className": "SomeRandomNamespace",
+ "gadget": true,
+ "qualifiedClassName": "SomeRandomNamespace"
+ }
+ ],
+ "inputFile": "moc_include.h",
+ "outputRevision": 67
+ },
+ {
+ "classes": [
+ {
"className": "FooNamespace",
"enums": [
{
diff --git a/tests/auto/tools/moc/fwdclass1.h b/tests/auto/tools/moc/fwdclass1.h
new file mode 100644
index 0000000000..a8457cca77
--- /dev/null
+++ b/tests/auto/tools/moc/fwdclass1.h
@@ -0,0 +1,38 @@
+/****************************************************************************
+**
+** Copyright (C) 2020 Olivier Goffart <ogoffart@woboq.com>
+** Contact: https://www.qt.io/licensing/
+**
+** This file is part of the test suite of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:GPL-EXCEPT$
+** Commercial License Usage
+** Licensees holding valid commercial Qt licenses may use this file in
+** accordance with the commercial license agreement provided with the
+** Software or, alternatively, in accordance with the terms contained in
+** a written agreement between you and The Qt Company. For licensing terms
+** and conditions see https://www.qt.io/terms-conditions. For further
+** information use the contact form at https://www.qt.io/contact-us.
+**
+** GNU General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU
+** General Public License version 3 as published by the Free Software
+** Foundation with exceptions as appearing in the file LICENSE.GPL3-EXCEPT
+** included in the packaging of this file. Please review the following
+** information to ensure the GNU General Public License requirements will
+** be met: https://www.gnu.org/licenses/gpl-3.0.html.
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#ifdef FWDCLASS1_H
+#error "This file can only be included once"
+#endif
+#define FWDCLASS1_H
+
+class FwdClass1
+{
+public:
+ int x;
+};
diff --git a/tests/auto/tools/moc/fwdclass2.h b/tests/auto/tools/moc/fwdclass2.h
new file mode 100644
index 0000000000..650da18116
--- /dev/null
+++ b/tests/auto/tools/moc/fwdclass2.h
@@ -0,0 +1,38 @@
+/****************************************************************************
+**
+** Copyright (C) 2020 Olivier Goffart <ogoffart@woboq.com>
+** Contact: https://www.qt.io/licensing/
+**
+** This file is part of the test suite of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:GPL-EXCEPT$
+** Commercial License Usage
+** Licensees holding valid commercial Qt licenses may use this file in
+** accordance with the commercial license agreement provided with the
+** Software or, alternatively, in accordance with the terms contained in
+** a written agreement between you and The Qt Company. For licensing terms
+** and conditions see https://www.qt.io/terms-conditions. For further
+** information use the contact form at https://www.qt.io/contact-us.
+**
+** GNU General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU
+** General Public License version 3 as published by the Free Software
+** Foundation with exceptions as appearing in the file LICENSE.GPL3-EXCEPT
+** included in the packaging of this file. Please review the following
+** information to ensure the GNU General Public License requirements will
+** be met: https://www.gnu.org/licenses/gpl-3.0.html.
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#ifdef FWDCLASS2_H
+#error "This file can only be included once"
+#endif
+#define FWDCLASS2_H
+
+class FwdClass2
+{
+public:
+ int x;
+};
diff --git a/tests/auto/tools/moc/fwdclass3.h b/tests/auto/tools/moc/fwdclass3.h
new file mode 100644
index 0000000000..080ac0340d
--- /dev/null
+++ b/tests/auto/tools/moc/fwdclass3.h
@@ -0,0 +1,38 @@
+/****************************************************************************
+**
+** Copyright (C) 2020 Olivier Goffart <ogoffart@woboq.com>
+** Contact: https://www.qt.io/licensing/
+**
+** This file is part of the test suite of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:GPL-EXCEPT$
+** Commercial License Usage
+** Licensees holding valid commercial Qt licenses may use this file in
+** accordance with the commercial license agreement provided with the
+** Software or, alternatively, in accordance with the terms contained in
+** a written agreement between you and The Qt Company. For licensing terms
+** and conditions see https://www.qt.io/terms-conditions. For further
+** information use the contact form at https://www.qt.io/contact-us.
+**
+** GNU General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU
+** General Public License version 3 as published by the Free Software
+** Foundation with exceptions as appearing in the file LICENSE.GPL3-EXCEPT
+** included in the packaging of this file. Please review the following
+** information to ensure the GNU General Public License requirements will
+** be met: https://www.gnu.org/licenses/gpl-3.0.html.
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#ifdef FWDCLASS3_H
+#error "This file can only be included once"
+#endif
+#define FWDCLASS3_H
+
+class FwdClass3
+{
+public:
+ int x;
+};
diff --git a/tests/auto/tools/moc/moc.pro b/tests/auto/tools/moc/moc.pro
index 93ca330126..094c76227b 100644
--- a/tests/auto/tools/moc/moc.pro
+++ b/tests/auto/tools/moc/moc.pro
@@ -30,7 +30,8 @@ HEADERS += using-namespaces.h no-keywords.h task87883.h c-comments.h backslash-n
related-metaobjects-in-gadget.h \
related-metaobjects-name-conflict.h \
namespace.h cxx17-namespaces.h \
- cxx-attributes.h
+ cxx-attributes.h \
+ moc_include.h
# No platform specifics in the JSON files, so that we can compare them
JSON_HEADERS = $$HEADERS
diff --git a/tests/auto/tools/moc/moc_include.h b/tests/auto/tools/moc/moc_include.h
new file mode 100644
index 0000000000..49b484a0c9
--- /dev/null
+++ b/tests/auto/tools/moc/moc_include.h
@@ -0,0 +1,74 @@
+/****************************************************************************
+**
+** Copyright (C) 2020 Olivier Goffart <ogoffart@woboq.com>
+** Contact: https://www.qt.io/licensing/
+**
+** This file is part of the test suite of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:GPL-EXCEPT$
+** Commercial License Usage
+** Licensees holding valid commercial Qt licenses may use this file in
+** accordance with the commercial license agreement provided with the
+** Software or, alternatively, in accordance with the terms contained in
+** a written agreement between you and The Qt Company. For licensing terms
+** and conditions see https://www.qt.io/terms-conditions. For further
+** information use the contact form at https://www.qt.io/contact-us.
+**
+** GNU General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU
+** General Public License version 3 as published by the Free Software
+** Foundation with exceptions as appearing in the file LICENSE.GPL3-EXCEPT
+** included in the packaging of this file. Please review the following
+** information to ensure the GNU General Public License requirements will
+** be met: https://www.gnu.org/licenses/gpl-3.0.html.
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#ifndef MOC_INCLUDE_H
+#define MOC_INCLUDE_H
+
+#include <QObject>
+
+class FwdClass1;
+class FwdClass2;
+class FwdClass3;
+
+Q_MOC_INCLUDE(fwdclass3.h)
+
+namespace SomeRandomNamespace {
+Q_MOC_INCLUDE("fwdclass1.h")
+Q_NAMESPACE
+}
+
+class TestFwdProperties : public QObject
+{
+ Q_OBJECT
+ Q_PROPERTY(FwdClass1 prop1 WRITE setProp1 READ getProp1)
+ Q_PROPERTY(FwdClass2 prop2 WRITE setProp2 READ getProp2)
+ Q_PROPERTY(FwdClass3 prop3 WRITE setProp3 READ getProp3)
+public:
+ ~TestFwdProperties();
+
+ void setProp1(const FwdClass1 &val);
+ void setProp2(const FwdClass2 &val);
+ void setProp3(const FwdClass3 &val);
+ const FwdClass1 &getProp1() { return *prop1; }
+ const FwdClass2 &getProp2() { return *prop2; }
+ const FwdClass3 &getProp3() { return *prop3; }
+
+ QScopedPointer<FwdClass1> prop1;
+ QScopedPointer<FwdClass2> prop2;
+ QScopedPointer<FwdClass3> prop3;
+
+ Q_MOC_INCLUDE(
+ \
+ "fwdclass2.h"
+ )
+
+};
+
+Q_MOC_INCLUDE(<QString>)
+
+#endif // MOC_INCLUDE_H
diff --git a/tests/auto/tools/moc/tst_moc.cpp b/tests/auto/tools/moc/tst_moc.cpp
index e5de647930..2bad8f2e63 100644
--- a/tests/auto/tools/moc/tst_moc.cpp
+++ b/tests/auto/tools/moc/tst_moc.cpp
@@ -1,7 +1,7 @@
/****************************************************************************
**
** Copyright (C) 2016 The Qt Company Ltd.
-** Copyright (C) 2013 Olivier Goffart <ogoffart@woboq.com>
+** Copyright (C) 2020 Olivier Goffart <ogoffart@woboq.com>
** Contact: https://www.qt.io/licensing/
**
** This file is part of the test suite of the Qt Toolkit.
@@ -27,8 +27,6 @@
**
****************************************************************************/
-
-
#include <QtTest/QtTest>
#include <stdio.h>
#include <qobject.h>
@@ -74,6 +72,11 @@
#include "cxx17-namespaces.h"
#include "cxx-attributes.h"
+#include "moc_include.h"
+#include "fwdclass1.h"
+#include "fwdclass2.h"
+#include "fwdclass3.h"
+
#ifdef Q_MOC_RUN
// check that moc can parse these constructs, they are being used in Windows winsock2.h header
#define STRING_HASH_HASH(x) ("foo" ## x ## "bar")
@@ -717,6 +720,7 @@ private slots:
void cxx17Namespaces();
void cxxAttributes();
void mocJsonOutput();
+ void mocInclude();
signals:
void sigWithUnsignedArg(unsigned foo);
@@ -4002,6 +4006,29 @@ void tst_Moc::mocJsonOutput()
QVERIFY2(actualOutput == expectedOutput, showPotentialDiff(actualOutput, expectedOutput).constData());
}
+void TestFwdProperties::setProp1(const FwdClass1 &v)
+{
+ prop1.reset(new FwdClass1(v));
+}
+void TestFwdProperties::setProp2(const FwdClass2 &v)
+{
+ prop2.reset(new FwdClass2(v));
+}
+void TestFwdProperties::setProp3(const FwdClass3 &v)
+{
+ prop3.reset(new FwdClass3(v));
+}
+TestFwdProperties::~TestFwdProperties() {}
+
+Q_DECLARE_METATYPE(FwdClass1);
+
+void tst_Moc::mocInclude()
+{
+ TestFwdProperties obj;
+ obj.setProperty("prop1", QVariant::fromValue(FwdClass1 { 45 }));
+ QCOMPARE(obj.prop1->x, 45);
+}
+
QTEST_MAIN(tst_Moc)
// the generated code must compile with QT_NO_KEYWORDS