summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorStephen Kelly <stephen.kelly@kdab.com>2012-09-03 12:55:38 +0200
committerQt by Nokia <qt-info@nokia.com>2012-09-03 20:05:04 +0200
commit5a1fa8860ca466bc109f1195e1e4b92c0c92018d (patch)
tree0a4c721a08ac849fe9b44575311642868b52b6a9
parent6efec23b100291dfea52a79626e2a577a49c10e5 (diff)
Generate includes for Qt containers used as auto-metatypes.
Otherwise the containers might be forward declared in the moc file, and when the moc file is compiled in a standalone translation unit, the full definition of it would not be available. This results in odd compile errors, so instead generate the includes if required. Change-Id: Ie01c5a5d45314daad0b00dec03b3e1e18cdbae64 Reviewed-by: Thiago Macieira <thiago.macieira@intel.com> Reviewed-by: Volker Krause <volker.krause@kdab.com> Reviewed-by: Olivier Goffart <ogoffart@woboq.com>
-rw-r--r--src/tools/moc/moc.cpp42
-rw-r--r--tests/auto/tools/moc/forward-declared-param.h76
-rw-r--r--tests/auto/tools/moc/moc.pro1
3 files changed, 119 insertions, 0 deletions
diff --git a/src/tools/moc/moc.cpp b/src/tools/moc/moc.cpp
index d7c08b4608..1693281c87 100644
--- a/src/tools/moc/moc.cpp
+++ b/src/tools/moc/moc.cpp
@@ -797,6 +797,38 @@ void Moc::parse()
}
}
+static void findRequiredContainers(ClassDef *cdef, QSet<QByteArray> *requiredQtContainers)
+{
+ static const QVector<QByteArray> candidates = QVector<QByteArray>()
+#define STREAM_SMART_POINTER(SMART_POINTER) << #SMART_POINTER
+ QT_FOR_EACH_AUTOMATIC_TEMPLATE_SMART_POINTER(STREAM_SMART_POINTER)
+#undef STREAM_SMART_POINTER
+#define STREAM_1ARG_TEMPLATE(TEMPLATENAME) << #TEMPLATENAME
+ QT_FOR_EACH_AUTOMATIC_TEMPLATE_1ARG(STREAM_1ARG_TEMPLATE)
+#undef STREAM_1ARG_TEMPLATE
+ ;
+
+ for (int i = 0; i < cdef->propertyList.count(); ++i) {
+ const PropertyDef &p = cdef->propertyList.at(i);
+ foreach (const QByteArray candidate, candidates) {
+ if (p.type.contains(candidate + "<"))
+ requiredQtContainers->insert(candidate);
+ }
+ }
+
+ QList<FunctionDef> allFunctions = cdef->slotList + cdef->signalList + cdef->methodList;
+
+ for (int i = 0; i < allFunctions.count(); ++i) {
+ const FunctionDef &f = allFunctions.at(i);
+ foreach (const ArgumentDef &arg, f.arguments) {
+ foreach (const QByteArray candidate, candidates) {
+ if (arg.normalizedType.contains(candidate + "<"))
+ requiredQtContainers->insert(candidate);
+ }
+ }
+ }
+}
+
void Moc::generate(FILE *out)
{
@@ -837,6 +869,16 @@ void Moc::generate(FILE *out)
if (mustIncludeQPluginH)
fprintf(out, "#include <QtCore/qplugin.h>\n");
+ QSet<QByteArray> requiredQtContainers;
+ for (i = 0; i < classList.size(); ++i) {
+ findRequiredContainers(&classList[i], &requiredQtContainers);
+ }
+
+ foreach (const QByteArray &qtContainer, requiredQtContainers) {
+ fprintf(out, "#include <QtCore/%s>\n", qtContainer.constData());
+ }
+
+
fprintf(out, "#if !defined(Q_MOC_OUTPUT_REVISION)\n"
"#error \"The header file '%s' doesn't include <QObject>.\"\n", fn.constData());
fprintf(out, "#elif Q_MOC_OUTPUT_REVISION != %d\n", mocOutputRevision);
diff --git a/tests/auto/tools/moc/forward-declared-param.h b/tests/auto/tools/moc/forward-declared-param.h
new file mode 100644
index 0000000000..9e0769f36c
--- /dev/null
+++ b/tests/auto/tools/moc/forward-declared-param.h
@@ -0,0 +1,76 @@
+/****************************************************************************
+**
+** Copyright (C) 2012 Intel Corporation
+** Contact: http://www.qt-project.org/
+**
+** This file is part of the test suite of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** GNU Lesser General Public License Usage
+** This file may be used under the terms of the GNU Lesser General Public
+** License version 2.1 as published by the Free Software Foundation and
+** appearing in the file LICENSE.LGPL included in the packaging of this
+** file. Please review the following information to ensure the GNU Lesser
+** General Public License version 2.1 requirements will be met:
+** http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
+**
+** In addition, as a special exception, Nokia gives you certain additional
+** rights. These rights are described in the Nokia Qt LGPL Exception
+** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
+**
+** GNU General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU General
+** Public License version 3.0 as published by the Free Software Foundation
+** and appearing in the file LICENSE.GPL included in the packaging of this
+** file. Please review the following information to ensure the GNU General
+** Public License version 3.0 requirements will be met:
+** http://www.gnu.org/copyleft/gpl.html.
+**
+** Other Usage
+** Alternatively, this file may be used in accordance with the terms and
+** conditions contained in a signed written agreement between you and Nokia.
+**
+**
+**
+**
+**
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+#include <qobject.h>
+#include <qmetatype.h>
+
+// test support for const refs to forward-declared structs in parameters
+
+struct ForwardDeclaredParam;
+template <typename T> class ForwardDeclaredContainer;
+
+struct FullyDefined {};
+Q_DECLARE_METATYPE(FullyDefined)
+
+class ForwardDeclaredParamClass : public QObject
+{
+ Q_OBJECT
+public slots:
+ void slotNaked(const ForwardDeclaredParam &) {}
+ void slotFDC(const ForwardDeclaredContainer<ForwardDeclaredParam> &) {}
+ void slotFDC(const ForwardDeclaredContainer<int> &) {}
+ void slotFDC(const ForwardDeclaredContainer<QString> &) {}
+ void slotFDC(const ForwardDeclaredContainer<FullyDefined> &) {}
+ void slotQSet(const QSet<ForwardDeclaredParam> &) {}
+ void slotQSet(const QSet<int> &) {}
+ void slotQSet(const QSet<QString> &) {}
+ void slotQSet(const QSet<FullyDefined> &) {}
+
+signals:
+ void signalNaked(const ForwardDeclaredParam &);
+ void signalFDC(const ForwardDeclaredContainer<ForwardDeclaredParam> &);
+ void signalFDC(const ForwardDeclaredContainer<int> &);
+ void signalFDC(const ForwardDeclaredContainer<QString> &);
+ void signalFDC(const ForwardDeclaredContainer<FullyDefined> &);
+ void signalQSet(const QSet<ForwardDeclaredParam> &);
+ void signalQSet(const QSet<int> &);
+ void signalQSet(const QSet<QString> &);
+ void signalQSet(const QSet<FullyDefined> &);
+}; \ No newline at end of file
diff --git a/tests/auto/tools/moc/moc.pro b/tests/auto/tools/moc/moc.pro
index b3ed5df469..0932f5a471 100644
--- a/tests/auto/tools/moc/moc.pro
+++ b/tests/auto/tools/moc/moc.pro
@@ -21,6 +21,7 @@ HEADERS += using-namespaces.h no-keywords.h task87883.h c-comments.h backslash-n
task234909.h task240368.h pure-virtual-signals.h cxx11-enums.h \
cxx11-final-classes.h \
cxx11-explicit-override-control.h \
+ forward-declared-param.h \
if(*-g++*|*-icc*|*-clang*|*-llvm):!irix-*:!win32-*: HEADERS += os9-newlines.h win-newlines.h