Revert "Allow moc to handle symbols that have been redefined."
[profile/ivi/qtbase.git] / tests / auto / tools / moc / tst_moc.cpp
1 /****************************************************************************
2 **
3 ** Copyright (C) 2012 Nokia Corporation and/or its subsidiary(-ies).
4 ** Contact: http://www.qt-project.org/
5 **
6 ** This file is part of the test suite of the Qt Toolkit.
7 **
8 ** $QT_BEGIN_LICENSE:LGPL$
9 ** GNU Lesser General Public License Usage
10 ** This file may be used under the terms of the GNU Lesser General Public
11 ** License version 2.1 as published by the Free Software Foundation and
12 ** appearing in the file LICENSE.LGPL included in the packaging of this
13 ** file. Please review the following information to ensure the GNU Lesser
14 ** General Public License version 2.1 requirements will be met:
15 ** http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
16 **
17 ** In addition, as a special exception, Nokia gives you certain additional
18 ** rights. These rights are described in the Nokia Qt LGPL Exception
19 ** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
20 **
21 ** GNU General Public License Usage
22 ** Alternatively, this file may be used under the terms of the GNU General
23 ** Public License version 3.0 as published by the Free Software Foundation
24 ** and appearing in the file LICENSE.GPL included in the packaging of this
25 ** file. Please review the following information to ensure the GNU General
26 ** Public License version 3.0 requirements will be met:
27 ** http://www.gnu.org/copyleft/gpl.html.
28 **
29 ** Other Usage
30 ** Alternatively, this file may be used in accordance with the terms and
31 ** conditions contained in a signed written agreement between you and Nokia.
32 **
33 **
34 **
35 **
36 **
37 **
38 ** $QT_END_LICENSE$
39 **
40 ****************************************************************************/
41
42
43
44 #include <QtTest/QtTest>
45 #include <stdio.h>
46 #include <qobject.h>
47
48 #include "using-namespaces.h"
49 #include "assign-namespace.h"
50 #include "no-keywords.h"
51 #include "single_function_keyword.h"
52 #include "backslash-newlines.h"
53 #include "slots-with-void-template.h"
54 #include "pure-virtual-signals.h"
55 #include "qinvokable.h"
56 // msvc and friends crap out on it
57 #if !defined(Q_CC_GNU) || defined(Q_OS_IRIX) || defined(Q_OS_WIN)
58 #define SKIP_NEWLINE_TEST
59 #endif
60 #if !defined(SKIP_NEWLINE_TEST)
61 #include "os9-newlines.h"
62 // msvc and friends crap out on this file too,
63 // it seems to contain Mac 9 EOLs, and not windows EOLs.
64 #include "win-newlines.h"
65 #endif
66 #include "escapes-in-string-literals.h"
67 #include "cstyle-enums.h"
68
69 #if defined(PARSE_BOOST)
70 #include "parse-boost.h"
71 #endif
72 #include "cxx11-enums.h"
73
74 QT_USE_NAMESPACE
75
76 struct MyStruct {};
77 struct MyStruct2 {};
78
79 struct SuperClass {};
80
81 // Try to avoid inserting for instance a comment with a quote between the following line and the Q_OBJECT
82 // That will make the test give a false positive.
83 const char* test_multiple_number_of_escapes =   "\\\"";
84 namespace MyNamespace
85 {
86     class TestSuperClass : public QObject
87     {
88         Q_OBJECT
89         public:
90             inline TestSuperClass() {}
91     };
92 }
93
94 namespace String
95 {
96     typedef QString Type;
97 }
98
99 namespace Int
100 {
101     typedef int Type;
102 }
103
104 typedef struct {
105     int doNotConfuseMoc;
106 } OldStyleCStruct;
107
108 class Sender : public QObject
109 {
110     Q_OBJECT
111
112 public:
113     void sendValue(const String::Type& value)
114     {
115         emit send(value);
116     }
117     void sendValue(const Int::Type& value)
118     {
119         emit send(value);
120     }
121
122 signals:
123     void send(const String::Type&);
124     void send(const Int::Type&);
125 };
126
127 class Receiver : public QObject
128 {
129     Q_OBJECT
130 public:
131     Receiver() : stringCallCount(0), intCallCount(0) {}
132
133     int stringCallCount;
134     int intCallCount;
135
136 public slots:
137     void receive(const String::Type&) { stringCallCount++; }
138     void receive(const Int::Type&)    { intCallCount++; }
139 };
140
141 #define MACRO_WITH_POSSIBLE_COMPILER_SPECIFIC_ATTRIBUTES
142
143 #define DONT_CONFUSE_MOC(klass) klass
144 #define DONT_CONFUSE_MOC_EVEN_MORE(klass, dummy, dummy2) klass
145
146 Q_DECLARE_METATYPE(MyStruct)
147 Q_DECLARE_METATYPE(MyStruct*)
148
149 namespace myNS {
150     struct Points
151     {
152         Points() : p1(0xBEEF), p2(0xBABE) { }
153         int p1, p2;
154     };
155 }
156
157 Q_DECLARE_METATYPE(myNS::Points)
158
159 class TestClassinfoWithEscapes: public QObject
160 {
161     Q_OBJECT
162     Q_CLASSINFO("escaped", "\"bar\"")
163     Q_CLASSINFO("\"escaped\"", "foo")
164 public slots:
165     void slotWithAReallyLongName(int)
166     { }
167 };
168
169 struct ForwardDeclaredStruct;
170
171 struct StructQObject : public QObject
172 {
173     Q_OBJECT
174 public:
175     void foo(struct ForwardDeclaredStruct *);
176 };
177
178 void StructQObject::foo(struct ForwardDeclaredStruct *)
179 {
180     struct Inner {
181         bool field;
182     };
183
184     struct Inner unusedVariable;
185 }
186
187 class TestClass : public MyNamespace::TestSuperClass, public DONT_CONFUSE_MOC(MyStruct),
188                   public DONT_CONFUSE_MOC_EVEN_MORE(MyStruct2, dummy, ignored)
189 {
190     Q_OBJECT
191     Q_CLASSINFO("help", QT_TR_NOOP("Opening this will let you configure something"))
192     Q_PROPERTY(short int shortIntProperty READ shortIntProperty)
193     Q_PROPERTY(unsigned short int unsignedShortIntProperty READ unsignedShortIntProperty)
194     Q_PROPERTY(signed short int signedShortIntProperty READ signedShortIntProperty)
195     Q_PROPERTY(long int longIntProperty READ longIntProperty)
196     Q_PROPERTY(unsigned long int unsignedLongIntProperty READ unsignedLongIntProperty)
197     Q_PROPERTY(signed long int signedLongIntProperty READ signedLongIntProperty)
198     Q_PROPERTY(long double longDoubleProperty READ longDoubleProperty)
199     Q_PROPERTY(myNS::Points points READ points WRITE setPoints)
200
201     Q_CLASSINFO("Multi"
202                 "line",
203                 ""
204                 "This is a "
205                 "multiline Q_CLASSINFO"
206                 "")
207
208     // a really really long string that we have to cut into pieces in the generated stringdata
209     // table, otherwise msvc craps out
210     Q_CLASSINFO("D-Bus Introspection", ""
211 "  <interface name=\"org.kde.KCookieServer\" >\n"
212 "    <method name=\"findCookies\" >\n"
213 "      <arg direction=\"in\" type=\"s\" name=\"url\" />\n"
214 "      <arg direction=\"in\" type=\"x\" name=\"windowId\" />\n"
215 "      <arg direction=\"out\" type=\"s\" name=\"cookies\" />\n"
216 "    </method>\n"
217 "    <method name=\"findDomains\" >\n"
218 "      <arg direction=\"out\" type=\"as\" name=\"domains\" />\n"
219 "    </method>\n"
220 "    <method name=\"findCookies\" >\n"
221 "      <arg direction=\"in\" type=\"ai\" name=\"fields\" />\n"
222 "      <arg direction=\"in\" type=\"s\" name=\"domain\" />\n"
223 "      <arg direction=\"in\" type=\"s\" name=\"fqdn\" />\n"
224 "      <arg direction=\"in\" type=\"s\" name=\"path\" />\n"
225 "      <arg direction=\"in\" type=\"s\" name=\"name\" />\n"
226 "      <arg direction=\"out\" type=\"as\" name=\"cookies\" />\n"
227 "      <annotation value=\"QList&lt;int>\" name=\"com.trolltech.QtDBus.QtTypeName.In0\" />\n"
228 "    </method>\n"
229 "    <method name=\"findDOMCookies\" >\n"
230 "      <arg direction=\"in\" type=\"s\" name=\"url\" />\n"
231 "      <arg direction=\"in\" type=\"x\" name=\"windowId\" />\n"
232 "      <arg direction=\"out\" type=\"s\" name=\"cookies\" />\n"
233 "    </method>\n"
234 "    <method name=\"addCookies\" >\n"
235 "      <arg direction=\"in\" type=\"s\" name=\"url\" />\n"
236 "      <arg direction=\"in\" type=\"ay\" name=\"cookieHeader\" />\n"
237 "      <arg direction=\"in\" type=\"x\" name=\"windowId\"  />\n"
238 "    </method>\n"
239 "    <method name=\"deleteCookie\" >\n"
240 "      <arg direction=\"in\" type=\"s\" name=\"domain\" />\n"
241 "      <arg direction=\"in\" type=\"s\" name=\"fqdn\" />\n"
242 "      <arg direction=\"in\" type=\"s\" name=\"path\" />\n"
243 "      <arg direction=\"in\" type=\"s\" name=\"name\" />\n"
244 "    </method>\n"
245 "    <method name=\"deleteCookiesFromDomain\" >\n"
246 "      <arg direction=\"in\" type=\"s\" name=\"domain\" />\n"
247 "    </method>\n"
248 "    <method name=\"deleteSessionCookies\" >\n"
249 "      <arg direction=\"in\" type=\"x\" name=\"windowId\" />\n"
250 "    </method>\n"
251 "    <method name=\"deleteSessionCookiesFor\" >\n"
252 "      <arg direction=\"in\" type=\"s\" name=\"fqdn\" />\n"
253 "      <arg direction=\"in\" type=\"x\" name=\"windowId\" />\n"
254 "    </method>\n"
255 "    <method name=\"deleteAllCookies\" />\n"
256 "    <method name=\"addDOMCookies\" >\n"
257 "      <arg direction=\"in\" type=\"s\" name=\"url\" />\n"
258 "      <arg direction=\"in\" type=\"ay\" name=\"cookieHeader\" />\n"
259 "      <arg direction=\"in\" type=\"x\" name=\"windowId\" />\n"
260 "    </method>\n"
261 "    <method name=\"setDomainAdvice\" >\n"
262 "      <arg direction=\"in\" type=\"s\" name=\"url\" />\n"
263 "      <arg direction=\"in\" type=\"s\" name=\"advice\" />\n"
264 "    </method>\n"
265 "    <method name=\"getDomainAdvice\" >\n"
266 "      <arg direction=\"in\" type=\"s\" name=\"url\" />\n"
267 "      <arg direction=\"out\" type=\"s\" name=\"advice\" />\n"
268 "    </method>\n"
269 "    <method name=\"reloadPolicy\" />\n"
270 "    <method name=\"shutdown\" />\n"
271 "  </interface>\n"
272         "")
273
274 public:
275     inline TestClass() {}
276
277 private slots:
278     inline void dummy1() MACRO_WITH_POSSIBLE_COMPILER_SPECIFIC_ATTRIBUTES {}
279     inline void dummy2() MACRO_WITH_POSSIBLE_COMPILER_SPECIFIC_ATTRIBUTES const {}
280     inline void dummy3() const MACRO_WITH_POSSIBLE_COMPILER_SPECIFIC_ATTRIBUTES {}
281
282     void slotWithULongLong(unsigned long long) {}
283     void slotWithULongLongP(unsigned long long*) {}
284     void slotWithULong(unsigned long) {}
285     void slotWithLongLong(long long) {}
286     void slotWithLong(long) {}
287
288     void slotWithColonColonType(::Int::Type) {}
289
290     TestClass &slotWithReferenceReturnType() { return *this; }
291
292 #if (0 && 1) || 1
293     void expressionEvaluationShortcut1() {}
294 #endif
295 #if (1 || 0) && 0
296 #else
297     void expressionEvaluationShortcut2() {}
298 #endif
299
300 public slots:
301     void slotWithArray(const double[3]) {}
302     void slotWithNamedArray(const double namedArray[3]) { Q_UNUSED(namedArray); }
303     void slotWithMultiArray(const double[3][4]) {}
304
305     short int shortIntProperty() { return 0; }
306     unsigned short int unsignedShortIntProperty() { return 0; }
307     signed short int signedShortIntProperty() { return 0; }
308     long int longIntProperty() { return 0; }
309     unsigned long int unsignedLongIntProperty() { return 0; }
310     signed long int signedLongIntProperty() { return 0; }
311     long double longDoubleProperty() { return 0.0; }
312
313     myNS::Points points() { return m_points; }
314     void setPoints(myNS::Points points) { m_points = points; }
315
316 signals:
317     void signalWithArray(const double[3]);
318     void signalWithNamedArray(const double namedArray[3]);
319
320 private slots:
321     // for tst_Moc::preprocessorConditionals
322 #if 0
323     void invalidSlot() {}
324 #else
325     void slotInElse() {}
326 #endif
327
328 #if 1
329     void slotInIf() {}
330 #else
331     void invalidSlot() {}
332 #endif
333
334 #if 0
335     void invalidSlot() {}
336 #elif 0
337 #else
338     void slotInLastElse() {}
339 #endif
340
341 #if 0
342     void invalidSlot() {}
343 #elif 1
344     void slotInElif() {}
345 #else
346     void invalidSlot() {}
347 #endif
348
349     friend class Receiver; // task #85783
350 signals:
351     friend class Sender; // task #85783
352
353 #define MACRO_DEFINED
354
355 #if !(defined MACRO_UNDEF || defined MACRO_DEFINED) || 1
356     void signalInIf1();
357 #else
358     void doNotExist();
359 #endif
360 #if !(!defined MACRO_UNDEF || !defined MACRO_DEFINED) && 1
361     void doNotExist();
362 #else
363     void signalInIf2();
364 #endif
365 #if !(!defined (MACRO_DEFINED) || !defined (MACRO_UNDEF)) && 1
366     void doNotExist();
367 #else
368     void signalInIf3();
369 #endif
370
371 # //QTBUG-22717
372  # /*  */
373 #
374
375  # \
376
377 //
378 public slots:
379     void const slotWithSillyConst() {}
380
381 public:
382     Q_INVOKABLE void const slotWithSillyConst2() {}
383     Q_INVOKABLE QObject& myInvokableReturningRef()
384     { return *this; }
385     Q_INVOKABLE const QObject& myInvokableReturningConstRef() const
386     { return *this; }
387
388
389     // that one however should be fine
390 public slots:
391     void slotWithVoidStar(void *) {}
392
393 private:
394      myNS::Points m_points;
395
396 private slots:
397      inline virtual void blub1() {}
398      virtual inline void blub2() {}
399 };
400
401 class PropertyTestClass : public QObject
402 {
403     Q_OBJECT
404 public:
405
406     enum TestEnum { One, Two, Three };
407
408     Q_ENUMS(TestEnum)
409 };
410
411 class PropertyUseClass : public QObject
412 {
413     Q_OBJECT
414     Q_PROPERTY(PropertyTestClass::TestEnum foo READ foo)
415 public:
416
417     inline PropertyTestClass::TestEnum foo() const { return PropertyTestClass::One; }
418 };
419
420 class EnumSourceClass : public QObject
421 {
422     Q_OBJECT
423
424 public:
425     enum TestEnum { Value = 37 };
426
427     Q_ENUMS(TestEnum)
428 };
429
430 class EnumUserClass : public QObject
431 {
432     Q_OBJECT
433
434 public:
435     Q_ENUMS(EnumSourceClass::TestEnum)
436 };
437
438 #if defined(Q_MOC_RUN)
439 // Task #119503
440 #define _TASK_119503
441 #if !_TASK_119503
442 #endif
443 #endif
444
445 static QString srcify(const char *path)
446 {
447 #ifndef Q_OS_IRIX
448     return QString(SRCDIR) + QLatin1Char('/') + QLatin1String(path);
449 #else
450     return QString(QLatin1String(path));
451 #endif
452 }
453
454 class CtorTestClass : public QObject
455 {
456     Q_OBJECT
457 public:
458     Q_INVOKABLE CtorTestClass(QObject *parent = 0);
459
460     CtorTestClass(int foo);
461
462     inline Q_INVOKABLE CtorTestClass(const QString &str)
463         { m_str = str; }
464
465     QString m_str;
466
467 protected:
468     CtorTestClass(int foo, int bar, int baz);
469 private:
470     CtorTestClass(float, float) {}
471 };
472
473 CtorTestClass::CtorTestClass(QObject *parent)
474     : QObject(parent) {}
475
476 CtorTestClass::CtorTestClass(int, int, int) {}
477
478
479 class tst_Moc : public QObject
480 {
481     Q_OBJECT
482
483     Q_PROPERTY(bool user1 READ user1 USER true )
484     Q_PROPERTY(bool user2 READ user2 USER false)
485     Q_PROPERTY(bool user3 READ user3 USER userFunction())
486
487 public:
488     inline tst_Moc() {}
489
490 private slots:
491     void initTestCase();
492
493     void slotWithException() throw(MyStruct);
494     void dontStripNamespaces();
495     void oldStyleCasts();
496     void warnOnExtraSignalSlotQualifiaction();
497     void uLongLong();
498     void inputFileNameWithDotsButNoExtension();
499     void userProperties();
500     void supportConstSignals();
501     void task87883();
502     void multilineComments();
503     void classinfoWithEscapes();
504     void trNoopInClassInfo();
505     void ppExpressionEvaluation();
506     void arrayArguments();
507     void preprocessorConditionals();
508     void blackslashNewlines();
509     void slotWithSillyConst();
510     void testExtraData();
511     void testExtraDataForEnum();
512     void namespaceTypeProperty();
513     void slotsWithVoidTemplate();
514     void structQObject();
515     void namespacedFlags();
516     void warnOnMultipleInheritance();
517     void forgottenQInterface();
518     void os9Newline();
519     void winNewline();
520     void escapesInStringLiterals();
521     void frameworkSearchPath();
522     void cstyleEnums();
523     void defineMacroViaCmdline();
524     void invokable();
525     void singleFunctionKeywordSignalAndSlot();
526     void templateGtGt();
527     void qprivateslots();
528     void qprivateproperties();
529     void inlineSlotsWithThrowDeclaration();
530     void warnOnPropertyWithoutREAD();
531     void constructors();
532     void typenameWithUnsigned();
533     void warnOnVirtualSignal();
534     void QTBUG5590_dummyProperty();
535     void QTBUG12260_defaultTemplate();
536     void notifyError();
537     void QTBUG17635_invokableAndProperty();
538     void revisions();
539     void warnings_data();
540     void warnings();
541     void privateClass();
542     void cxx11Enums_data();
543     void cxx11Enums();
544     void returnRefs();
545
546 signals:
547     void sigWithUnsignedArg(unsigned foo);
548     void sigWithSignedArg(signed foo);
549     void sigWithConstSignedArg(const signed foo);
550     void sigWithVolatileConstSignedArg(volatile const signed foo);
551     void sigWithCustomType(const MyStruct);
552     void constSignal1() const;
553     void constSignal2(int arg) const;
554
555 private:
556     bool user1() { return true; };
557     bool user2() { return false; };
558     bool user3() { return false; };
559     bool userFunction(){ return false; };
560     template <class T> void revisions_T();
561
562 private:
563     QString qtIncludePath;
564     class PrivateClass;
565 };
566
567 void tst_Moc::initTestCase()
568 {
569 #if defined(Q_OS_UNIX) && !defined(QT_NO_PROCESS)
570     QProcess proc;
571     proc.start("qmake", QStringList() << "-query" << "QT_INSTALL_HEADERS");
572     QVERIFY(proc.waitForFinished());
573     QCOMPARE(proc.exitCode(), 0);
574     QByteArray output = proc.readAllStandardOutput();
575     QVERIFY(!output.isEmpty());
576     QCOMPARE(proc.readAllStandardError(), QByteArray());
577     qtIncludePath = QString::fromLocal8Bit(output).trimmed();
578     QFileInfo fi(qtIncludePath);
579     QVERIFY(fi.exists());
580     QVERIFY(fi.isDir());
581 #endif
582 }
583
584 void tst_Moc::slotWithException() throw(MyStruct)
585 {
586     // be happy
587     QVERIFY(true);
588 }
589
590 void tst_Moc::dontStripNamespaces()
591 {
592     Sender sender;
593     Receiver receiver;
594
595     connect(&sender, SIGNAL(send(const String::Type &)),
596             &receiver, SLOT(receive(const String::Type &)));
597     connect(&sender, SIGNAL(send(const Int::Type &)),
598             &receiver, SLOT(receive(const Int::Type &)));
599
600     sender.sendValue(String::Type("Hello"));
601     QCOMPARE(receiver.stringCallCount, 1);
602     QCOMPARE(receiver.intCallCount, 0);
603     sender.sendValue(Int::Type(42));
604     QCOMPARE(receiver.stringCallCount, 1);
605     QCOMPARE(receiver.intCallCount, 1);
606 }
607
608 void tst_Moc::oldStyleCasts()
609 {
610 #ifdef MOC_CROSS_COMPILED
611     QSKIP("Not tested when cross-compiled");
612 #endif
613 #if defined(Q_OS_LINUX) && defined(Q_CC_GNU) && !defined(QT_NO_PROCESS)
614     QProcess proc;
615     proc.start("moc", QStringList(srcify("/oldstyle-casts.h")));
616     QVERIFY(proc.waitForFinished());
617     QCOMPARE(proc.exitCode(), 0);
618     QByteArray mocOut = proc.readAllStandardOutput();
619     QVERIFY(!mocOut.isEmpty());
620     QCOMPARE(proc.readAllStandardError(), QByteArray());
621
622     QStringList args;
623     args << "-c" << "-x" << "c++" << "-Wold-style-cast" << "-I" << "."
624          << "-I" << qtIncludePath << "-o" << "/dev/null" << "-fPIE" << "-";
625     proc.start("gcc", args);
626     QVERIFY(proc.waitForStarted());
627     proc.write(mocOut);
628     proc.closeWriteChannel();
629
630     QVERIFY(proc.waitForFinished());
631     QCOMPARE(proc.exitCode(), 0);
632     QCOMPARE(QString::fromLocal8Bit(proc.readAllStandardError()), QString());
633 #else
634     QSKIP("Only tested on linux/gcc");
635 #endif
636 }
637
638 void tst_Moc::warnOnExtraSignalSlotQualifiaction()
639 {
640 #ifdef MOC_CROSS_COMPILED
641     QSKIP("Not tested when cross-compiled");
642 #endif
643 #if defined(Q_OS_LINUX) && defined(Q_CC_GNU) && !defined(QT_NO_PROCESS)
644     QProcess proc;
645     proc.start("moc", QStringList(srcify("extraqualification.h")));
646     QVERIFY(proc.waitForFinished());
647     QCOMPARE(proc.exitCode(), 0);
648     QByteArray mocOut = proc.readAllStandardOutput();
649     QVERIFY(!mocOut.isEmpty());
650     QString mocWarning = QString::fromLocal8Bit(proc.readAllStandardError());
651     QCOMPARE(mocWarning, QString(SRCDIR) +
652                 QString("/extraqualification.h:53: Warning: Function declaration Test::badFunctionDeclaration contains extra qualification. Ignoring as signal or slot.\n") +
653                 QString(SRCDIR) + QString("/extraqualification.h:56: Warning: parsemaybe: Function declaration Test::anotherOne contains extra qualification. Ignoring as signal or slot.\n"));
654 #else
655     QSKIP("Only tested on linux/gcc");
656 #endif
657 }
658
659 void tst_Moc::uLongLong()
660 {
661     TestClass tst;
662     const QMetaObject *mobj = tst.metaObject();
663     int idx = mobj->indexOfSlot("slotWithULong(ulong)");
664     QVERIFY(idx != -1);
665     idx = mobj->indexOfSlot("slotWithULongLong(unsigned long long)");
666     QVERIFY(idx != -1);
667     idx = mobj->indexOfSlot("slotWithULongLongP(unsigned long long*)");
668     QVERIFY(idx != -1);
669
670     idx = mobj->indexOfSlot("slotWithLong(long)");
671     QVERIFY(idx != -1);
672     idx = mobj->indexOfSlot("slotWithLongLong(long long)");
673     QVERIFY(idx != -1);
674 }
675
676 void tst_Moc::inputFileNameWithDotsButNoExtension()
677 {
678 #ifdef MOC_CROSS_COMPILED
679     QSKIP("Not tested when cross-compiled");
680 #endif
681 #if defined(Q_OS_LINUX) && defined(Q_CC_GNU) && !defined(QT_NO_PROCESS)
682     QProcess proc;
683     proc.setWorkingDirectory(QString(SRCDIR) + "/task71021");
684     proc.start("moc", QStringList("../Header"));
685     QVERIFY(proc.waitForFinished());
686     QCOMPARE(proc.exitCode(), 0);
687     QByteArray mocOut = proc.readAllStandardOutput();
688     QVERIFY(!mocOut.isEmpty());
689     QCOMPARE(proc.readAllStandardError(), QByteArray());
690
691     QStringList args;
692     args << "-c" << "-x" << "c++" << "-I" << ".."
693          << "-I" << qtIncludePath << "-o" << "/dev/null" << "-fPIE" <<  "-";
694     proc.start("gcc", args);
695     QVERIFY(proc.waitForStarted());
696     proc.write(mocOut);
697     proc.closeWriteChannel();
698
699     QVERIFY(proc.waitForFinished());
700     QCOMPARE(QString::fromLocal8Bit(proc.readAllStandardError()), QString());
701     QCOMPARE(proc.exitCode(), 0);
702 #else
703     QSKIP("Only tested on linux/gcc");
704 #endif
705 }
706
707 void tst_Moc::userProperties()
708 {
709     const QMetaObject *mobj = metaObject();
710     QMetaProperty property = mobj->property(mobj->indexOfProperty("user1"));
711     QVERIFY(property.isValid());
712     QVERIFY(property.isUser());
713
714     property = mobj->property(mobj->indexOfProperty("user2"));
715     QVERIFY(property.isValid());
716     QVERIFY(!property.isUser());
717
718     property = mobj->property(mobj->indexOfProperty("user3"));
719     QVERIFY(property.isValid());
720     QVERIFY(!property.isUser(this));
721 }
722
723 void tst_Moc::supportConstSignals()
724 {
725     QSignalSpy spy1(this, SIGNAL(constSignal1()));
726     QVERIFY(spy1.isEmpty());
727     emit constSignal1();
728     QCOMPARE(spy1.count(), 1);
729
730     QSignalSpy spy2(this, SIGNAL(constSignal2(int)));
731     QVERIFY(spy2.isEmpty());
732     emit constSignal2(42);
733     QCOMPARE(spy2.count(), 1);
734     QCOMPARE(spy2.at(0).at(0).toInt(), 42);
735 }
736
737 #include "task87883.h"
738
739 void tst_Moc::task87883()
740 {
741     QVERIFY(Task87883::staticMetaObject.className());
742 }
743
744 #include "c-comments.h"
745
746 void tst_Moc::multilineComments()
747 {
748     QVERIFY(IfdefedClass::staticMetaObject.className());
749 }
750
751 void tst_Moc::classinfoWithEscapes()
752 {
753     const QMetaObject *mobj = &TestClassinfoWithEscapes::staticMetaObject;
754     QCOMPARE(mobj->methodCount() - mobj->methodOffset(), 1);
755
756     QMetaMethod mm = mobj->method(mobj->methodOffset());
757     QCOMPARE(mm.methodSignature(), QByteArray("slotWithAReallyLongName(int)"));
758 }
759
760 void tst_Moc::trNoopInClassInfo()
761 {
762     TestClass t;
763     const QMetaObject *mobj = t.metaObject();
764     QVERIFY(mobj);
765     QCOMPARE(mobj->classInfoCount(), 3);
766     QCOMPARE(mobj->indexOfClassInfo("help"), 0);
767     QCOMPARE(QString(mobj->classInfo(0).value()), QString("Opening this will let you configure something"));
768 }
769
770 void tst_Moc::ppExpressionEvaluation()
771 {
772     TestClass tst;
773     const QMetaObject *mobj = tst.metaObject();
774     int idx = mobj->indexOfSlot("expressionEvaluationShortcut1()");
775     QVERIFY(idx != -1);
776
777     idx = mobj->indexOfSlot("expressionEvaluationShortcut2()");
778     QVERIFY(idx != -1);
779 }
780
781 void tst_Moc::arrayArguments()
782 {
783     TestClass tst;
784     const QMetaObject *mobj = tst.metaObject();
785     QVERIFY(mobj->indexOfSlot("slotWithArray(const double[3])") != -1);
786     QVERIFY(mobj->indexOfSlot("slotWithNamedArray(const double[3])") != -1);
787     QVERIFY(mobj->indexOfSlot("slotWithMultiArray(const double[3][4])") != -1);
788     QVERIFY(mobj->indexOfSignal("signalWithArray(const double[3])") != -1);
789     QVERIFY(mobj->indexOfSignal("signalWithNamedArray(const double[3])") != -1);
790 }
791
792 void tst_Moc::preprocessorConditionals()
793 {
794     TestClass tst;
795     const QMetaObject *mobj = tst.metaObject();
796     QVERIFY(mobj->indexOfSlot("slotInElse()") != -1);
797     QVERIFY(mobj->indexOfSlot("slotInIf()") != -1);
798     QVERIFY(mobj->indexOfSlot("slotInLastElse()") != -1);
799     QVERIFY(mobj->indexOfSlot("slotInElif()") != -1);
800     QVERIFY(mobj->indexOfSignal("signalInIf1()") != -1);
801     QVERIFY(mobj->indexOfSignal("signalInIf2()") != -1);
802     QVERIFY(mobj->indexOfSignal("signalInIf3()") != -1);
803     QVERIFY(mobj->indexOfSignal("doNotExist()") == -1);
804 }
805
806 void tst_Moc::blackslashNewlines()
807 {
808     BackslashNewlines tst;
809     const QMetaObject *mobj = tst.metaObject();
810     QVERIFY(mobj->indexOfSlot("works()") != -1);
811     QVERIFY(mobj->indexOfSlot("buggy()") == -1);
812 }
813
814 void tst_Moc::slotWithSillyConst()
815 {
816     TestClass tst;
817     const QMetaObject *mobj = tst.metaObject();
818     QVERIFY(mobj->indexOfSlot("slotWithSillyConst()") != -1);
819     QVERIFY(mobj->indexOfMethod("slotWithSillyConst2()") != -1);
820     QVERIFY(mobj->indexOfSlot("slotWithVoidStar(void*)") != -1);
821 }
822
823 void tst_Moc::testExtraData()
824 {
825     const QMetaObject *mobj = &PropertyTestClass::staticMetaObject;
826     QCOMPARE(mobj->enumeratorCount(), 1);
827     QCOMPARE(QByteArray(mobj->enumerator(0).name()), QByteArray("TestEnum"));
828
829     mobj = &PropertyUseClass::staticMetaObject;
830     const int idx = mobj->indexOfProperty("foo");
831     QVERIFY(idx != -1);
832     const QMetaProperty prop = mobj->property(idx);
833     QVERIFY(prop.isValid());
834     QVERIFY(prop.isEnumType());
835     const QMetaEnum en = prop.enumerator();
836     QCOMPARE(QByteArray(en.name()), QByteArray("TestEnum"));
837 }
838
839 // QTBUG-20639 - Accept non-local enums for QML signal/slot parameters.
840 void tst_Moc::testExtraDataForEnum()
841 {
842     const QMetaObject *mobjSource = &EnumSourceClass::staticMetaObject;
843     QCOMPARE(mobjSource->enumeratorCount(), 1);
844     QCOMPARE(QByteArray(mobjSource->enumerator(0).name()), QByteArray("TestEnum"));
845
846     const QMetaObject *mobjUser = &EnumUserClass::staticMetaObject;
847     QCOMPARE(mobjUser->enumeratorCount(), 0);
848
849     const QMetaObject **objects = mobjUser->d.relatedMetaObjects;
850     QVERIFY(objects);
851     QVERIFY(objects[0] == mobjSource);
852     QVERIFY(objects[1] == 0);
853 }
854
855 void tst_Moc::namespaceTypeProperty()
856 {
857     qRegisterMetaType<myNS::Points>("myNS::Points");
858     TestClass tst;
859     QByteArray ba = QByteArray("points");
860     QVariant v = tst.property(ba);
861     QVERIFY(v.isValid());
862     myNS::Points p = qvariant_cast<myNS::Points>(v);
863     QCOMPARE(p.p1, 0xBEEF);
864     QCOMPARE(p.p2, 0xBABE);
865     p.p1 = 0xCAFE;
866     p.p2 = 0x1EE7;
867     QVERIFY(tst.setProperty(ba, QVariant::fromValue(p)));
868     myNS::Points pp = qvariant_cast<myNS::Points>(tst.property(ba));
869     QCOMPARE(p.p1, pp.p1);
870     QCOMPARE(p.p2, pp.p2);
871 }
872
873 void tst_Moc::slotsWithVoidTemplate()
874 {
875     SlotsWithVoidTemplateTest test;
876     QVERIFY(QObject::connect(&test, SIGNAL(myVoidSignal(void)),
877                              &test, SLOT(dummySlot(void))));
878     QVERIFY(QObject::connect(&test, SIGNAL(mySignal(const TestTemplate<void> &)),
879                              &test, SLOT(anotherSlot(const TestTemplate<void> &))));
880     QVERIFY(QObject::connect(&test, SIGNAL(myVoidSignal2()),
881                              &test, SLOT(dummySlot2())));
882 }
883
884 void tst_Moc::structQObject()
885 {
886     StructQObject o;
887     QCOMPARE(QByteArray(o.metaObject()->className()), QByteArray("StructQObject"));
888 }
889
890 #include "namespaced-flags.h"
891
892 Q_DECLARE_METATYPE(QList<Foo::Bar::Flags>);
893
894 void tst_Moc::namespacedFlags()
895 {
896     Foo::Baz baz;
897     Foo::Bar bar;
898
899     bar.setFlags(Foo::Bar::Read | Foo::Bar::Write);
900     QVERIFY(baz.flags() != bar.flags());
901
902     const QVariant v = bar.property("flags");
903     QVERIFY(v.isValid());
904     QVERIFY(baz.setProperty("flags", v));
905     QVERIFY(baz.flags() == bar.flags());
906
907     QList<Foo::Bar::Flags> l;
908     l << baz.flags();
909     QVariant v2 = baz.setProperty("flagsList", QVariant::fromValue(l));
910     QCOMPARE(l, baz.flagsList());
911     QCOMPARE(l, qvariant_cast<QList<Foo::Bar::Flags> >(baz.property("flagsList")));
912 }
913
914 void tst_Moc::warnOnMultipleInheritance()
915 {
916 #ifdef MOC_CROSS_COMPILED
917     QSKIP("Not tested when cross-compiled");
918 #endif
919 #if defined(Q_OS_LINUX) && defined(Q_CC_GNU) && !defined(QT_NO_PROCESS)
920     QProcess proc;
921     QStringList args;
922     args << "-I" << qtIncludePath + "/QtGui"
923          << srcify("warn-on-multiple-qobject-subclasses.h");
924     proc.start("moc", args);
925     QVERIFY(proc.waitForFinished());
926     QCOMPARE(proc.exitCode(), 0);
927     QByteArray mocOut = proc.readAllStandardOutput();
928     QVERIFY(!mocOut.isEmpty());
929     QString mocWarning = QString::fromLocal8Bit(proc.readAllStandardError());
930     QCOMPARE(mocWarning, QString(SRCDIR) +
931                 QString("/warn-on-multiple-qobject-subclasses.h:53: Warning: Class Bar inherits from two QObject subclasses QWindow and Foo. This is not supported!\n"));
932 #else
933     QSKIP("Only tested on linux/gcc");
934 #endif
935 }
936
937 void tst_Moc::forgottenQInterface()
938 {
939 #ifdef MOC_CROSS_COMPILED
940     QSKIP("Not tested when cross-compiled");
941 #endif
942 #if defined(Q_OS_LINUX) && defined(Q_CC_GNU) && !defined(QT_NO_PROCESS)
943     QProcess proc;
944     QStringList args;
945     args << "-I" << qtIncludePath + "/QtCore"
946          << srcify("forgotten-qinterface.h");
947     proc.start("moc", args);
948     QVERIFY(proc.waitForFinished());
949     QCOMPARE(proc.exitCode(), 0);
950     QByteArray mocOut = proc.readAllStandardOutput();
951     QVERIFY(!mocOut.isEmpty());
952     QString mocWarning = QString::fromLocal8Bit(proc.readAllStandardError());
953     QCOMPARE(mocWarning, QString(SRCDIR) +
954                 QString("/forgotten-qinterface.h:55: Warning: Class Test implements the interface MyInterface but does not list it in Q_INTERFACES. qobject_cast to MyInterface will not work!\n"));
955 #else
956     QSKIP("Only tested on linux/gcc");
957 #endif
958 }
959
960 void tst_Moc::os9Newline()
961 {
962 #if !defined(SKIP_NEWLINE_TEST)
963     const QMetaObject &mo = Os9Newlines::staticMetaObject;
964     QVERIFY(mo.indexOfSlot("testSlot()") != -1);
965     QFile f(srcify("os9-newlines.h"));
966     QVERIFY(f.open(QIODevice::ReadOnly)); // no QIODevice::Text!
967     QByteArray data = f.readAll();
968     f.close();
969     QVERIFY(!data.contains('\n'));
970     QVERIFY(data.contains('\r'));
971 #endif
972 }
973
974 void tst_Moc::winNewline()
975 {
976 #if !defined(SKIP_NEWLINE_TEST)
977     const QMetaObject &mo = WinNewlines::staticMetaObject;
978     QVERIFY(mo.indexOfSlot("testSlot()") != -1);
979     QFile f(srcify("win-newlines.h"));
980     QVERIFY(f.open(QIODevice::ReadOnly)); // no QIODevice::Text!
981     QByteArray data = f.readAll();
982     f.close();
983     for (int i = 0; i < data.count(); ++i) {
984         if (data.at(i) == QLatin1Char('\r')) {
985             QVERIFY(i < data.count() - 1);
986             ++i;
987             QVERIFY(data.at(i) == '\n');
988         } else {
989             QVERIFY(data.at(i) != '\n');
990         }
991     }
992 #endif
993 }
994
995 void tst_Moc::escapesInStringLiterals()
996 {
997     const QMetaObject &mo = StringLiterals::staticMetaObject;
998     QCOMPARE(mo.classInfoCount(), 3);
999
1000     int idx = mo.indexOfClassInfo("Test");
1001     QVERIFY(idx != -1);
1002     QMetaClassInfo info = mo.classInfo(idx);
1003     QCOMPARE(QByteArray(info.value()),
1004              QByteArray("aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa\x53"));
1005
1006     QVERIFY(idx != -1);
1007     idx = mo.indexOfClassInfo("Test2");
1008     info = mo.classInfo(idx);
1009     QCOMPARE(QByteArray(info.value()),
1010              QByteArray("aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa\123"));
1011
1012     QVERIFY(idx != -1);
1013     idx = mo.indexOfClassInfo("Test3");
1014     info = mo.classInfo(idx);
1015     QCOMPARE(QByteArray(info.value()),
1016              QByteArray("aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa\nb"));
1017 }
1018
1019 void tst_Moc::frameworkSearchPath()
1020 {
1021 #ifdef MOC_CROSS_COMPILED
1022     QSKIP("Not tested when cross-compiled");
1023 #endif
1024 #if defined(Q_OS_UNIX) && !defined(QT_NO_PROCESS)
1025     QStringList args;
1026     args << "-F" << srcify(".")
1027          << srcify("interface-from-framework.h")
1028          ;
1029
1030     QProcess proc;
1031     proc.start("moc", args);
1032     bool finished = proc.waitForFinished();
1033     if (!finished)
1034         qWarning("waitForFinished failed. QProcess error: %d", (int)proc.error());
1035     QVERIFY(finished);
1036     if (proc.exitCode() != 0) {
1037         qDebug() << proc.readAllStandardError();
1038     }
1039     QCOMPARE(proc.exitCode(), 0);
1040     QCOMPARE(proc.readAllStandardError(), QByteArray());
1041 #else
1042     QSKIP("Only tested/relevant on unixy platforms");
1043 #endif
1044 }
1045
1046 void tst_Moc::cstyleEnums()
1047 {
1048     const QMetaObject &obj = CStyleEnums::staticMetaObject;
1049     QCOMPARE(obj.enumeratorCount(), 1);
1050     QMetaEnum metaEnum = obj.enumerator(0);
1051     QCOMPARE(metaEnum.name(), "Baz");
1052     QCOMPARE(metaEnum.keyCount(), 2);
1053     QCOMPARE(metaEnum.key(0), "Foo");
1054     QCOMPARE(metaEnum.key(1), "Bar");
1055 }
1056
1057 void tst_Moc::templateGtGt()
1058 {
1059 #ifdef MOC_CROSS_COMPILED
1060     QSKIP("Not tested when cross-compiled");
1061 #endif
1062 #if defined(Q_OS_LINUX) && defined(Q_CC_GNU) && !defined(QT_NO_PROCESS)
1063     QProcess proc;
1064     proc.start("moc", QStringList(srcify("template-gtgt.h")));
1065     QVERIFY(proc.waitForFinished());
1066     QCOMPARE(proc.exitCode(), 0);
1067     QByteArray mocOut = proc.readAllStandardOutput();
1068     QVERIFY(!mocOut.isEmpty());
1069     QString mocWarning = QString::fromLocal8Bit(proc.readAllStandardError());
1070     QVERIFY(mocWarning.isEmpty());
1071 #else
1072     QSKIP("Only tested on linux/gcc");
1073 #endif
1074 }
1075
1076 void tst_Moc::defineMacroViaCmdline()
1077 {
1078 #if defined(Q_OS_LINUX) && defined(Q_CC_GNU) && !defined(QT_NO_PROCESS)
1079     QProcess proc;
1080
1081     QStringList args;
1082     args << "-DFOO";
1083     args << srcify("macro-on-cmdline.h");
1084
1085     proc.start("moc", args);
1086     QVERIFY(proc.waitForFinished());
1087     QCOMPARE(proc.exitCode(), 0);
1088     QCOMPARE(proc.readAllStandardError(), QByteArray());
1089     QByteArray mocOut = proc.readAllStandardOutput();
1090     QVERIFY(!mocOut.isEmpty());
1091 #else
1092     QSKIP("Only tested on linux/gcc");
1093 #endif
1094 }
1095
1096 void tst_Moc::invokable()
1097 {
1098     {
1099         const QMetaObject &mobj = InvokableBeforeReturnType::staticMetaObject;
1100         QCOMPARE(mobj.methodCount(), 6);
1101         QVERIFY(mobj.method(5).methodSignature() == QByteArray("foo()"));
1102     }
1103
1104     {
1105         const QMetaObject &mobj = InvokableBeforeInline::staticMetaObject;
1106         QCOMPARE(mobj.methodCount(), 7);
1107         QVERIFY(mobj.method(5).methodSignature() == QByteArray("foo()"));
1108         QVERIFY(mobj.method(6).methodSignature() == QByteArray("bar()"));
1109     }
1110 }
1111
1112 void tst_Moc::singleFunctionKeywordSignalAndSlot()
1113 {
1114     {
1115         const QMetaObject &mobj = SingleFunctionKeywordBeforeReturnType::staticMetaObject;
1116         QCOMPARE(mobj.methodCount(), 7);
1117         QVERIFY(mobj.method(5).methodSignature() == QByteArray("mySignal()"));
1118         QVERIFY(mobj.method(6).methodSignature() == QByteArray("mySlot()"));
1119     }
1120
1121     {
1122         const QMetaObject &mobj = SingleFunctionKeywordBeforeInline::staticMetaObject;
1123         QCOMPARE(mobj.methodCount(), 7);
1124         QVERIFY(mobj.method(5).methodSignature() == QByteArray("mySignal()"));
1125         QVERIFY(mobj.method(6).methodSignature() == QByteArray("mySlot()"));
1126     }
1127
1128     {
1129         const QMetaObject &mobj = SingleFunctionKeywordAfterInline::staticMetaObject;
1130         QCOMPARE(mobj.methodCount(), 7);
1131         QVERIFY(mobj.method(5).methodSignature() == QByteArray("mySignal()"));
1132         QVERIFY(mobj.method(6).methodSignature() == QByteArray("mySlot()"));
1133     }
1134 }
1135
1136 #include "qprivateslots.h"
1137
1138 void tst_Moc::qprivateslots()
1139 {
1140     TestQPrivateSlots tst;
1141     const QMetaObject *mobj = tst.metaObject();
1142     QVERIFY(mobj->indexOfSlot("_q_privateslot()") != -1);
1143     QVERIFY(mobj->indexOfMethod("method1()") != -1); //tast204730
1144 }
1145
1146 class PrivatePropertyTest : public QObject
1147 {
1148     Q_OBJECT
1149     Q_PROPERTY(int foo READ foo WRITE setFoo)
1150     Q_PRIVATE_PROPERTY(d, int bar READ bar WRITE setBar)
1151     Q_PRIVATE_PROPERTY(PrivatePropertyTest::d, int plop READ plop WRITE setPlop)
1152     Q_PRIVATE_PROPERTY(PrivatePropertyTest::d_func(), int baz READ baz WRITE setBaz)
1153     class MyDPointer {
1154     public:
1155         MyDPointer() : mBar(0), mPlop(0) {}
1156         int bar() { return mBar ; }
1157         void setBar(int value) { mBar = value; }
1158         int plop() { return mPlop ; }
1159         void setPlop(int value) { mPlop = value; }
1160         int baz() { return mBaz ; }
1161         void setBaz(int value) { mBaz = value; }
1162     private:
1163         int mBar;
1164         int mPlop;
1165         int mBaz;
1166     };
1167 public:
1168     PrivatePropertyTest() : mFoo(0), d (new MyDPointer) {}
1169     int foo() { return mFoo ; }
1170     void setFoo(int value) { mFoo = value; }
1171     MyDPointer *d_func() {return d;}
1172 private:
1173     int mFoo;
1174     MyDPointer *d;
1175 };
1176
1177
1178 void tst_Moc::qprivateproperties()
1179 {
1180     PrivatePropertyTest test;
1181
1182     test.setProperty("foo", 1);
1183     QCOMPARE(test.property("foo"), QVariant::fromValue(1));
1184
1185     test.setProperty("bar", 2);
1186     QCOMPARE(test.property("bar"), QVariant::fromValue(2));
1187
1188     test.setProperty("plop", 3);
1189     QCOMPARE(test.property("plop"), QVariant::fromValue(3));
1190
1191     test.setProperty("baz", 4);
1192     QCOMPARE(test.property("baz"), QVariant::fromValue(4));
1193
1194 }
1195
1196 #include "task189996.h"
1197
1198 void InlineSlotsWithThrowDeclaration::c() throw() {}
1199
1200 void tst_Moc::inlineSlotsWithThrowDeclaration()
1201 {
1202     InlineSlotsWithThrowDeclaration tst;
1203     const QMetaObject *mobj = tst.metaObject();
1204     QVERIFY(mobj->indexOfSlot("a()") != -1);
1205     QVERIFY(mobj->indexOfSlot("b()") != -1);
1206     QVERIFY(mobj->indexOfSlot("c()") != -1);
1207     QVERIFY(mobj->indexOfSlot("d()") != -1);
1208     QVERIFY(mobj->indexOfSlot("e()") != -1);
1209 }
1210
1211 void tst_Moc::warnOnPropertyWithoutREAD()
1212 {
1213 #ifdef MOC_CROSS_COMPILED
1214     QSKIP("Not tested when cross-compiled");
1215 #endif
1216 #if defined(Q_OS_LINUX) && defined(Q_CC_GNU) && !defined(QT_NO_PROCESS)
1217     QProcess proc;
1218     proc.start("moc", QStringList(srcify("warn-on-property-without-read.h")));
1219     QVERIFY(proc.waitForFinished());
1220     QCOMPARE(proc.exitCode(), 0);
1221     QByteArray mocOut = proc.readAllStandardOutput();
1222     QVERIFY(!mocOut.isEmpty());
1223     QString mocWarning = QString::fromLocal8Bit(proc.readAllStandardError());
1224     QCOMPARE(mocWarning, QString(SRCDIR) +
1225                 QString("/warn-on-property-without-read.h:46: Warning: Property declaration foo has no READ accessor function. The property will be invalid.\n"));
1226 #else
1227     QSKIP("Only tested on linux/gcc");
1228 #endif
1229 }
1230
1231 void tst_Moc::constructors()
1232 {
1233     const QMetaObject *mo = &CtorTestClass::staticMetaObject;
1234     QCOMPARE(mo->constructorCount(), 3);
1235     {
1236         QMetaMethod mm = mo->constructor(0);
1237         QCOMPARE(mm.access(), QMetaMethod::Public);
1238         QCOMPARE(mm.methodType(), QMetaMethod::Constructor);
1239         QCOMPARE(mm.methodSignature(), QByteArray("CtorTestClass(QObject*)"));
1240         QCOMPARE(mm.typeName(), "");
1241         QList<QByteArray> paramNames = mm.parameterNames();
1242         QCOMPARE(paramNames.size(), 1);
1243         QCOMPARE(paramNames.at(0), QByteArray("parent"));
1244         QList<QByteArray> paramTypes = mm.parameterTypes();
1245         QCOMPARE(paramTypes.size(), 1);
1246         QCOMPARE(paramTypes.at(0), QByteArray("QObject*"));
1247     }
1248     {
1249         QMetaMethod mm = mo->constructor(1);
1250         QCOMPARE(mm.access(), QMetaMethod::Public);
1251         QCOMPARE(mm.methodType(), QMetaMethod::Constructor);
1252         QCOMPARE(mm.methodSignature(), QByteArray("CtorTestClass()"));
1253         QCOMPARE(mm.typeName(), "");
1254         QCOMPARE(mm.parameterNames().size(), 0);
1255         QCOMPARE(mm.parameterTypes().size(), 0);
1256     }
1257     {
1258         QMetaMethod mm = mo->constructor(2);
1259         QCOMPARE(mm.access(), QMetaMethod::Public);
1260         QCOMPARE(mm.methodType(), QMetaMethod::Constructor);
1261         QCOMPARE(mm.methodSignature(), QByteArray("CtorTestClass(QString)"));
1262         QCOMPARE(mm.typeName(), "");
1263         QList<QByteArray> paramNames = mm.parameterNames();
1264         QCOMPARE(paramNames.size(), 1);
1265         QCOMPARE(paramNames.at(0), QByteArray("str"));
1266         QList<QByteArray> paramTypes = mm.parameterTypes();
1267         QCOMPARE(paramTypes.size(), 1);
1268         QCOMPARE(paramTypes.at(0), QByteArray("QString"));
1269     }
1270
1271     QCOMPARE(mo->indexOfConstructor("CtorTestClass(QObject*)"), 0);
1272     QCOMPARE(mo->indexOfConstructor("CtorTestClass()"), 1);
1273     QCOMPARE(mo->indexOfConstructor("CtorTestClass(QString)"), 2);
1274     QCOMPARE(mo->indexOfConstructor("CtorTestClass2(QObject*)"), -1);
1275     QCOMPARE(mo->indexOfConstructor("CtorTestClass(float,float)"), -1);
1276
1277     QObject *o1 = mo->newInstance();
1278     QVERIFY(o1 != 0);
1279     QCOMPARE(o1->parent(), (QObject*)0);
1280     QVERIFY(qobject_cast<CtorTestClass*>(o1) != 0);
1281
1282     QObject *o2 = mo->newInstance(Q_ARG(QObject*, o1));
1283     QVERIFY(o2 != 0);
1284     QCOMPARE(o2->parent(), o1);
1285
1286     QString str = QString::fromLatin1("hello");
1287     QObject *o3 = mo->newInstance(Q_ARG(QString, str));
1288     QVERIFY(o3 != 0);
1289     QCOMPARE(qobject_cast<CtorTestClass*>(o3)->m_str, str);
1290
1291     {
1292         //explicit constructor
1293         QObject *o = QObject::staticMetaObject.newInstance();
1294         QVERIFY(o);
1295         delete o;
1296     }
1297 }
1298
1299 #include "task234909.h"
1300
1301 #include "task240368.h"
1302
1303 void tst_Moc::typenameWithUnsigned()
1304 {
1305     TypenameWithUnsigned tst;
1306     const QMetaObject *mobj = tst.metaObject();
1307     QVERIFY(mobj->indexOfSlot("a(uint)") != -1);
1308     QVERIFY(mobj->indexOfSlot("b(uint)") != -1);
1309     QVERIFY(mobj->indexOfSlot("c(uint*)") != -1);
1310     QVERIFY(mobj->indexOfSlot("d(uint*)") != -1);
1311     QVERIFY(mobj->indexOfSlot("e(uint&)") != -1);
1312     QVERIFY(mobj->indexOfSlot("f(uint&)") != -1);
1313     QVERIFY(mobj->indexOfSlot("g(unsigned1)") != -1);
1314     QVERIFY(mobj->indexOfSlot("h(unsigned1)") != -1);
1315     QVERIFY(mobj->indexOfSlot("i(uint,unsigned1)") != -1);
1316     QVERIFY(mobj->indexOfSlot("j(unsigned1,uint)") != -1);
1317     QVERIFY(mobj->indexOfSlot("k(unsignedQImage)") != -1);
1318     QVERIFY(mobj->indexOfSlot("l(unsignedQImage)") != -1);
1319 }
1320
1321 void tst_Moc::warnOnVirtualSignal()
1322 {
1323 #ifdef MOC_CROSS_COMPILED
1324     QSKIP("Not tested when cross-compiled");
1325 #endif
1326 #if defined(Q_OS_LINUX) && defined(Q_CC_GNU) && !defined(QT_NO_PROCESS)
1327     QProcess proc;
1328     proc.start("moc", QStringList(srcify("pure-virtual-signals.h")));
1329     QVERIFY(proc.waitForFinished());
1330     QCOMPARE(proc.exitCode(), 0);
1331     QByteArray mocOut = proc.readAllStandardOutput();
1332     QVERIFY(!mocOut.isEmpty());
1333     QString mocWarning = QString::fromLocal8Bit(proc.readAllStandardError());
1334     QCOMPARE(mocWarning, QString(SRCDIR) + QString("/pure-virtual-signals.h:48: Warning: Signals cannot be declared virtual\n") +
1335                          QString(SRCDIR) + QString("/pure-virtual-signals.h:50: Warning: Signals cannot be declared virtual\n"));
1336 #else
1337     QSKIP("Only tested on linux/gcc");
1338 #endif
1339 }
1340
1341 class QTBUG5590_DummyObject: public QObject
1342 {
1343     Q_OBJECT
1344     Q_PROPERTY(bool dummy)
1345 };
1346
1347 class QTBUG5590_PropertyObject: public QTBUG5590_DummyObject
1348 {
1349     Q_OBJECT
1350     Q_PROPERTY(int value READ value WRITE setValue)
1351     Q_PROPERTY(int value2 READ value2 WRITE setValue2)
1352
1353     public:
1354         QTBUG5590_PropertyObject() :  m_value(85), m_value2(40) { }
1355         int value() const { return m_value; }
1356         void setValue(int value) { m_value = value; }
1357         int value2() const { return m_value2; }
1358         void setValue2(int value) { m_value2 = value; }
1359     private:
1360         int m_value, m_value2;
1361 };
1362
1363 void tst_Moc::QTBUG5590_dummyProperty()
1364 {
1365     QTBUG5590_PropertyObject o;
1366     QCOMPARE(o.property("value").toInt(), 85);
1367     QCOMPARE(o.property("value2").toInt(), 40);
1368     o.setProperty("value", 32);
1369     QCOMPARE(o.value(), 32);
1370     o.setProperty("value2", 82);
1371     QCOMPARE(o.value2(), 82);
1372 }
1373
1374 class QTBUG7421_ReturnConstTemplate: public QObject
1375 { Q_OBJECT
1376 public slots:
1377         const QList<int> returnConstTemplate1() { return QList<int>(); }
1378         QList<int> const returnConstTemplate2() { return QList<int>(); }
1379         const int returnConstInt() { return 0; }
1380         const QString returnConstString(const QString s) { return s; }
1381         QString const returnConstString2( QString const s) { return s; }
1382 };
1383
1384 class QTBUG9354_constInName: public QObject
1385 { Q_OBJECT
1386 public slots:
1387     void slotChooseScientificConst0(struct science_constant const &) {};
1388     void foo(struct science_const const &) {};
1389     void foo(struct constconst const &) {};
1390     void foo(struct constconst *) {};
1391     void foo(struct const_ *) {};
1392 };
1393
1394
1395 template<typename T1, typename T2>
1396 class TestTemplate2
1397 {
1398 };
1399
1400 class QTBUG11647_constInTemplateParameter : public QObject
1401 { Q_OBJECT
1402 public slots:
1403     void testSlot(TestTemplate2<const int, const short*>) {}
1404     void testSlot2(TestTemplate2<int, short const * const >) {}
1405     void testSlot3(TestTemplate2<TestTemplate2 < const int, const short* > const *,
1406                                 TestTemplate2< TestTemplate2 < void, int > , unsigned char *> > ) {}
1407
1408 signals:
1409     void testSignal(TestTemplate2<const int, const short*>);
1410 };
1411
1412 class QTBUG12260_defaultTemplate_Object : public QObject
1413 { Q_OBJECT
1414 public slots:
1415 #if !(defined(Q_CC_GNU) && __GNUC__ == 4 && __GNUC_MINOR__ <= 3) || defined(Q_MOC_RUN)
1416     void doSomething(QHash<QString, QVariant> values = QHash<QString, QVariant>() ) { Q_UNUSED(values); }
1417 #else
1418     // we want to test the previous function, but gcc < 4.4 seemed to have a bug similar to the one moc has.
1419     typedef QHash<QString, QVariant> WorkaroundGCCBug;
1420     void doSomething(QHash<QString, QVariant> values = WorkaroundGCCBug() ) { Q_UNUSED(values); }
1421 #endif
1422
1423     void doAnotherThing(bool a = (1 < 3), bool b = (1 > 4)) { Q_UNUSED(a); Q_UNUSED(b); }
1424 };
1425
1426
1427 void tst_Moc::QTBUG12260_defaultTemplate()
1428 {
1429     QVERIFY(QTBUG12260_defaultTemplate_Object::staticMetaObject.indexOfSlot("doSomething(QHash<QString,QVariant>)") != -1);
1430     QVERIFY(QTBUG12260_defaultTemplate_Object::staticMetaObject.indexOfSlot("doAnotherThing(bool,bool)") != -1);
1431 }
1432
1433 void tst_Moc::notifyError()
1434 {
1435 #ifdef MOC_CROSS_COMPILED
1436     QSKIP("Not tested when cross-compiled");
1437 #endif
1438 #if defined(Q_OS_LINUX) && defined(Q_CC_GNU) && !defined(QT_NO_PROCESS)
1439     QProcess proc;
1440     proc.start("moc", QStringList(srcify("error-on-wrong-notify.h")));
1441     QVERIFY(proc.waitForFinished());
1442     QCOMPARE(proc.exitCode(), 1);
1443     QCOMPARE(proc.exitStatus(), QProcess::NormalExit);
1444     QByteArray mocOut = proc.readAllStandardOutput();
1445     QVERIFY(mocOut.isEmpty());
1446     QString mocError = QString::fromLocal8Bit(proc.readAllStandardError());
1447     QCOMPARE(mocError, QString(SRCDIR) +
1448         QString("/error-on-wrong-notify.h:52: Error: NOTIFY signal 'fooChanged' of property 'foo' does not exist in class ClassWithWrongNOTIFY.\n"));
1449 #else
1450     QSKIP("Only tested on linux/gcc");
1451 #endif
1452 }
1453
1454 class QTBUG_17635_InvokableAndProperty : public QObject
1455 {
1456     Q_OBJECT
1457 public:
1458     Q_PROPERTY(int numberOfEggs READ numberOfEggs)
1459     Q_PROPERTY(int numberOfChickens READ numberOfChickens)
1460     Q_INVOKABLE QString getEgg(int index) { Q_UNUSED(index); return QString::fromLatin1("Egg"); }
1461     Q_INVOKABLE QString getChicken(int index) { Q_UNUSED(index); return QString::fromLatin1("Chicken"); }
1462     int numberOfEggs() { return 2; }
1463     int numberOfChickens() { return 4; }
1464 };
1465
1466 void tst_Moc::QTBUG17635_invokableAndProperty()
1467 {
1468     //Moc used to fail parsing Q_INVOKABLE if they were dirrectly following a Q_PROPERTY;
1469     QTBUG_17635_InvokableAndProperty mc;
1470     QString val;
1471     QMetaObject::invokeMethod(&mc, "getEgg", Q_RETURN_ARG(QString, val), Q_ARG(int, 10));
1472     QCOMPARE(val, QString::fromLatin1("Egg"));
1473     QMetaObject::invokeMethod(&mc, "getChicken", Q_RETURN_ARG(QString, val), Q_ARG(int, 10));
1474     QCOMPARE(val, QString::fromLatin1("Chicken"));
1475     QVERIFY(mc.metaObject()->indexOfProperty("numberOfEggs") != -1);
1476     QVERIFY(mc.metaObject()->indexOfProperty("numberOfChickens") != -1);
1477 }
1478
1479 // If changed, update VersionTestNotify below
1480 class VersionTest : public QObject
1481 {
1482     Q_OBJECT
1483     Q_PROPERTY(int prop1 READ foo)
1484     Q_PROPERTY(int prop2 READ foo REVISION 2)
1485     Q_ENUMS(TestEnum);
1486
1487 public:
1488     int foo() const { return 0; }
1489
1490     Q_INVOKABLE void method1() {}
1491     Q_INVOKABLE Q_REVISION(4) void method2() {}
1492
1493     enum TestEnum { One, Two };
1494
1495 public slots:
1496     void slot1() {}
1497     Q_REVISION(3) void slot2() {}
1498
1499 signals:
1500     void signal1();
1501     Q_REVISION(5) void signal2();
1502
1503 public slots Q_REVISION(6):
1504     void slot3() {}
1505     void slot4() {}
1506
1507 signals Q_REVISION(7):
1508     void signal3();
1509     void signal4();
1510 };
1511
1512 // If changed, update VersionTest above
1513 class VersionTestNotify : public QObject
1514 {
1515     Q_OBJECT
1516     Q_PROPERTY(int prop1 READ foo NOTIFY fooChanged)
1517     Q_PROPERTY(int prop2 READ foo REVISION 2)
1518     Q_ENUMS(TestEnum);
1519
1520 public:
1521     int foo() const { return 0; }
1522
1523     Q_INVOKABLE void method1() {}
1524     Q_INVOKABLE Q_REVISION(4) void method2() {}
1525
1526     enum TestEnum { One, Two };
1527
1528 public slots:
1529     void slot1() {}
1530     Q_REVISION(3) void slot2() {}
1531
1532 signals:
1533     void fooChanged();
1534     void signal1();
1535     Q_REVISION(5) void signal2();
1536
1537 public slots Q_REVISION(6):
1538     void slot3() {}
1539     void slot4() {}
1540
1541 signals Q_REVISION(7):
1542     void signal3();
1543     void signal4();
1544 };
1545
1546 template <class T>
1547 void tst_Moc::revisions_T()
1548 {
1549     int idx = T::staticMetaObject.indexOfProperty("prop1");
1550     QVERIFY(T::staticMetaObject.property(idx).revision() == 0);
1551     idx = T::staticMetaObject.indexOfProperty("prop2");
1552     QVERIFY(T::staticMetaObject.property(idx).revision() == 2);
1553
1554     idx = T::staticMetaObject.indexOfMethod("method1()");
1555     QVERIFY(T::staticMetaObject.method(idx).revision() == 0);
1556     idx = T::staticMetaObject.indexOfMethod("method2()");
1557     QVERIFY(T::staticMetaObject.method(idx).revision() == 4);
1558
1559     idx = T::staticMetaObject.indexOfSlot("slot1()");
1560     QVERIFY(T::staticMetaObject.method(idx).revision() == 0);
1561     idx = T::staticMetaObject.indexOfSlot("slot2()");
1562     QVERIFY(T::staticMetaObject.method(idx).revision() == 3);
1563
1564     idx = T::staticMetaObject.indexOfSlot("slot3()");
1565     QVERIFY(T::staticMetaObject.method(idx).revision() == 6);
1566     idx = T::staticMetaObject.indexOfSlot("slot4()");
1567     QVERIFY(T::staticMetaObject.method(idx).revision() == 6);
1568
1569     idx = T::staticMetaObject.indexOfSignal("signal1()");
1570     QVERIFY(T::staticMetaObject.method(idx).revision() == 0);
1571     idx = T::staticMetaObject.indexOfSignal("signal2()");
1572     QVERIFY(T::staticMetaObject.method(idx).revision() == 5);
1573
1574     idx = T::staticMetaObject.indexOfSignal("signal3()");
1575     QVERIFY(T::staticMetaObject.method(idx).revision() == 7);
1576     idx = T::staticMetaObject.indexOfSignal("signal4()");
1577     QVERIFY(T::staticMetaObject.method(idx).revision() == 7);
1578
1579     idx = T::staticMetaObject.indexOfEnumerator("TestEnum");
1580     QCOMPARE(T::staticMetaObject.enumerator(idx).keyCount(), 2);
1581     QCOMPARE(T::staticMetaObject.enumerator(idx).key(0), "One");
1582 }
1583
1584 // test using both class that has properties with and without NOTIFY signals
1585 void tst_Moc::revisions()
1586 {
1587     revisions_T<VersionTest>();
1588     revisions_T<VersionTestNotify>();
1589 }
1590
1591 void tst_Moc::warnings_data()
1592 {
1593     QTest::addColumn<QByteArray>("input");
1594     QTest::addColumn<QStringList>("args");
1595     QTest::addColumn<int>("exitCode");
1596     QTest::addColumn<QString>("expectedStdOut");
1597     QTest::addColumn<QString>("expectedStdErr");
1598
1599     // empty input should result in "no relevant classes" note
1600     QTest::newRow("No relevant classes")
1601         << QByteArray(" ")
1602         << QStringList()
1603         << 0
1604         << QString()
1605         << QString("standard input:0: Note: No relevant classes found. No output generated.");
1606
1607     // passing "-nn" should suppress "no relevant classes" note
1608     QTest::newRow("-nn")
1609         << QByteArray(" ")
1610         << (QStringList() << "-nn")
1611         << 0
1612         << QString()
1613         << QString();
1614
1615     // passing "-nw" should also suppress "no relevant classes" note
1616     QTest::newRow("-nw")
1617         << QByteArray(" ")
1618         << (QStringList() << "-nw")
1619         << 0
1620         << QString()
1621         << QString();
1622
1623     // This should output a warning
1624     QTest::newRow("Invalid property warning")
1625         << QByteArray("class X : public QObject { Q_OBJECT Q_PROPERTY(int x) };")
1626         << QStringList()
1627         << 0
1628         << QString("IGNORE_ALL_STDOUT")
1629         << QString("standard input:1: Warning: Property declaration x has no READ accessor function. The property will be invalid.");
1630
1631     // Passing "-nn" should NOT suppress the warning
1632     QTest::newRow("Invalid property warning with -nn")
1633         << QByteArray("class X : public QObject { Q_OBJECT Q_PROPERTY(int x) };")
1634         << (QStringList() << "-nn")
1635         << 0
1636         << QString("IGNORE_ALL_STDOUT")
1637         << QString("standard input:1: Warning: Property declaration x has no READ accessor function. The property will be invalid.");
1638
1639     // Passing "-nw" should suppress the warning
1640     QTest::newRow("Invalid property warning with -nw")
1641         << QByteArray("class X : public QObject { Q_OBJECT Q_PROPERTY(int x) };")
1642         << (QStringList() << "-nw")
1643         << 0
1644         << QString("IGNORE_ALL_STDOUT")
1645         << QString();
1646
1647     // This should output an error
1648     QTest::newRow("Does not inherit QObject")
1649         << QByteArray("class X { Q_OBJECT };")
1650         << QStringList()
1651         << 1
1652         << QString()
1653         << QString("standard input:1: Error: Class contains Q_OBJECT macro but does not inherit from QObject");
1654
1655     // "-nn" should not suppress the error
1656     QTest::newRow("Does not inherit QObject with -nn")
1657         << QByteArray("class X { Q_OBJECT };")
1658         << (QStringList() << "-nn")
1659         << 1
1660         << QString()
1661         << QString("standard input:1: Error: Class contains Q_OBJECT macro but does not inherit from QObject");
1662
1663     // "-nw" should not suppress the error
1664     QTest::newRow("Does not inherit QObject with -nw")
1665         << QByteArray("class X { Q_OBJECT };")
1666         << (QStringList() << "-nw")
1667         << 1
1668         << QString()
1669         << QString("standard input:1: Error: Class contains Q_OBJECT macro but does not inherit from QObject");
1670 }
1671
1672 void tst_Moc::warnings()
1673 {
1674 #ifdef MOC_CROSS_COMPILED
1675     QSKIP("Not tested when cross-compiled");
1676 #endif
1677     QFETCH(QByteArray, input);
1678     QFETCH(QStringList, args);
1679     QFETCH(int, exitCode);
1680     QFETCH(QString, expectedStdOut);
1681     QFETCH(QString, expectedStdErr);
1682
1683 #ifdef Q_CC_MSVC
1684     // for some reasons, moc compiled with MSVC uses a different output format
1685     QRegExp lineNumberRe(":(\\d+):");
1686     lineNumberRe.setMinimal(true);
1687     expectedStdErr.replace(lineNumberRe, "(\\1):");
1688 #endif
1689
1690     QProcess proc;
1691     proc.start("moc", args);
1692     QVERIFY(proc.waitForStarted());
1693
1694     QCOMPARE(proc.write(input), qint64(input.size()));
1695
1696     proc.closeWriteChannel();
1697
1698     QVERIFY(proc.waitForFinished());
1699
1700     QCOMPARE(proc.exitCode(), exitCode);
1701     QCOMPARE(proc.exitStatus(), QProcess::NormalExit);
1702
1703     // magic value "IGNORE_ALL_STDOUT" ignores stdout
1704     if (expectedStdOut != "IGNORE_ALL_STDOUT")
1705         QCOMPARE(QString::fromLocal8Bit(proc.readAllStandardOutput()).trimmed(), expectedStdOut);
1706     QCOMPARE(QString::fromLocal8Bit(proc.readAllStandardError()).trimmed(), expectedStdErr);
1707 }
1708
1709 class tst_Moc::PrivateClass : public QObject {
1710     Q_PROPERTY(int someProperty READ someSlot WRITE someSlot2)
1711 Q_OBJECT
1712 Q_SIGNALS:
1713     void someSignal();
1714 public Q_SLOTS:
1715     int someSlot() { return 1; }
1716     void someSlot2(int) {}
1717 public:
1718     Q_INVOKABLE PrivateClass()  {}
1719 };
1720
1721 void tst_Moc::privateClass()
1722 {
1723     QVERIFY(PrivateClass::staticMetaObject.indexOfConstructor("PrivateClass()") == 0);
1724     QVERIFY(PrivateClass::staticMetaObject.indexOfSignal("someSignal()") > 0);
1725 }
1726
1727 void tst_Moc::cxx11Enums_data()
1728 {
1729     QTest::addColumn<QByteArray>("enumName");
1730     QTest::addColumn<char>("prefix");
1731
1732     QTest::newRow("EnumClass") << QByteArray("EnumClass") << 'A';
1733     QTest::newRow("TypedEnum") << QByteArray("TypedEnum") << 'B';
1734     QTest::newRow("TypedEnumClass") << QByteArray("TypedEnumClass") << 'C';
1735     QTest::newRow("NormalEnum") << QByteArray("NormalEnum") << 'D';
1736 }
1737
1738
1739 void tst_Moc::cxx11Enums()
1740 {
1741     const QMetaObject *meta = &CXX11Enums::staticMetaObject;
1742     QCOMPARE(meta->enumeratorOffset(), 0);
1743
1744     QFETCH(QByteArray, enumName);
1745     QFETCH(char, prefix);
1746
1747     int idx;
1748     idx = meta->indexOfEnumerator(enumName);
1749     QVERIFY(idx != -1);
1750     QCOMPARE(meta->enumerator(idx).enclosingMetaObject(), meta);
1751     QCOMPARE(meta->enumerator(idx).isValid(), true);
1752     QCOMPARE(meta->enumerator(idx).keyCount(), 4);
1753     QCOMPARE(meta->enumerator(idx).name(), enumName.constData());
1754     for (int i = 0; i < 4; i++) {
1755         QByteArray v = prefix + QByteArray::number(i);
1756         QCOMPARE(meta->enumerator(idx).keyToValue(v), i);
1757         QCOMPARE(meta->enumerator(idx).valueToKey(i), v.constData());
1758     }
1759 }
1760
1761 void tst_Moc::returnRefs()
1762 {
1763     TestClass tst;
1764     const QMetaObject *mobj = tst.metaObject();
1765     QVERIFY(mobj->indexOfMethod("myInvokableReturningRef()") != -1);
1766     QVERIFY(mobj->indexOfMethod("myInvokableReturningConstRef()") != -1);
1767     // Those two functions are copied from the qscriptextqobject test in qtscript
1768     // they used to cause miscompilation of the moc generated file.
1769 }
1770
1771 QTEST_MAIN(tst_Moc)
1772 #include "tst_moc.moc"
1773