summaryrefslogtreecommitdiffstats
path: root/src/tools/moc
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 /src/tools/moc
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>
Diffstat (limited to 'src/tools/moc')
-rw-r--r--src/tools/moc/moc.cpp42
1 files changed, 42 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);