diff --git a/tests/auto/cplusplus/preprocessor/tst_preprocessor.cpp b/tests/auto/cplusplus/preprocessor/tst_preprocessor.cpp index e9f05113017..91819d3175a 100644 --- a/tests/auto/cplusplus/preprocessor/tst_preprocessor.cpp +++ b/tests/auto/cplusplus/preprocessor/tst_preprocessor.cpp @@ -109,12 +109,15 @@ public: virtual void passedMacroDefinitionCheck(unsigned /*offset*/, const Macro &/*macro*/) {} virtual void failedMacroDefinitionCheck(unsigned /*offset*/, const QByteArray &/*name*/) {} - virtual void startExpandingMacro(unsigned /*offset*/, + virtual void startExpandingMacro(unsigned offset, const Macro &/*macro*/, const QByteArray &originalText, const QVector &/*actuals*/ = QVector()) - { m_expandedMacros.append(originalText); } + { + m_expandedMacros.append(originalText); + m_expandedMacrosOffset.append(offset); + } virtual void stopExpandingMacro(unsigned /*offset*/, const Macro &/*macro*/) {} @@ -210,6 +213,9 @@ public: QList expandedMacros() const { return m_expandedMacros; } + QList expandedMacrosOffset() const + { return m_expandedMacrosOffset; } + private: Environment *m_env; QByteArray *m_output; @@ -219,8 +225,34 @@ private: QList m_skippedBlocks; QList m_recordedIncludes; QList m_expandedMacros; + QList m_expandedMacrosOffset; }; +namespace QTest { + template<> char *toString(const QList &list) + { + QByteArray ba = "QList("; + foreach (const unsigned& item, list) { + ba += QTest::toString(item); + ba += ','; + } + if (!list.isEmpty()) + ba[ba.size() - 1] = ')'; + return qstrdup(ba.data()); + } + template<> char *toString(const QList &list) + { + QByteArray ba = "QList("; + foreach (const QByteArray& item, list) { + ba += QTest::toString(item); + ba += ','; + } + if (!list.isEmpty()) + ba[ba.size() - 1] = ')'; + return qstrdup(ba.data()); + } +} + QDebug &operator<<(QDebug& d, const MockClient::Block &b) { d << '[' << b.start << ',' << b.end << ']'; return d; } class tst_Preprocessor: public QObject @@ -236,9 +268,12 @@ protected: client.sourceNeeded("data/" + fileName, nolines); return output; } + static QString simplified(QByteArray buf); private /* not corrected yet */: void macro_definition_lineno(); + void param_expanding_as_multiple_params(); + void macro_argument_expansion(); private slots: void va_args(); @@ -246,6 +281,7 @@ private slots: void first_empty_macro_arg(); void invalid_param_count(); void objmacro_expanding_as_fnmacro_notification(); + void macro_uses(); void macro_arguments_notificatin(); void unfinished_function_like_macro_call(); void nasty_macro_expansion(); @@ -259,6 +295,30 @@ private slots: void comparisons(); }; +// Remove all #... lines, and 'simplify' string, to allow easily comparing the result +// Also, remove all unneeded spaces: keep only to ensure identifiers are separated. +// NOTE: may not correctly handle underscore in identifiers +QString tst_Preprocessor::simplified(QByteArray buf) +{ + QString out; + QList lines = buf.split('\n'); + foreach (QByteArray line, lines) + if (!line.startsWith('#')) { + out.append(' '); + out.append(line); + } + + out = out.simplified(); + for (int i=1; i"), + QByteArray("\n#define foo(a,b) int f(a,b);" + "\n#define ARGS(t) t a,t b" + "\nfoo(ARGS(int))")); + QCOMPARE(simplified(preprocessed), QString("int f(int a,int b);")); +} + +void tst_Preprocessor::macro_argument_expansion() //QTCREATORBUG-7225 +{ + Client *client = 0; // no client. + Environment env; + + Preprocessor preprocess(client, &env); + QByteArray preprocessed = preprocess(QLatin1String(""), + QByteArray("\n#define BAR1 2,3,4" + "\n#define FOO1(a,b,c) a+b+c" + "\nvoid test2(){" + "\nint x=FOO1(BAR1);" + "\n}")); + QCOMPARE(simplified(preprocessed), QString("void test2(){int x=2+3+4;}")); + +} + +void tst_Preprocessor::macro_uses() +{ + QByteArray buffer = QByteArray("\n#define FOO 8" + "\n#define BAR 9" + "\nvoid test(){" + "\n\tint x=FOO;" + "\n\tint y=BAR;" + "\n}"); + + QByteArray output; + Environment env; + MockClient client(&env, &output); + + Preprocessor preprocess(&client, &env); + QByteArray preprocessed = preprocess(QLatin1String(""), buffer); + QCOMPARE(simplified(preprocessed), QString("void test(){int x=8;int y=9;}")); + QCOMPARE(client.expandedMacros(), QList() << QByteArray("FOO") << QByteArray("BAR")); + QCOMPARE(client.expandedMacrosOffset(), QList() << buffer.indexOf("FOO;") << buffer.indexOf("BAR;")); +} + void tst_Preprocessor::macro_definition_lineno() { Client *client = 0; // no client. @@ -343,30 +446,30 @@ void tst_Preprocessor::macro_definition_lineno() QByteArray preprocessed = preprocess(QLatin1String(""), QByteArray("#define foo(ARGS) int f(ARGS)\n" "foo(int a);\n")); - QVERIFY(preprocessed.contains("#gen true\n# 2 ")); + QVERIFY(preprocessed.contains("#gen true\n# 2 \"\"\nint f")); preprocessed = preprocess(QLatin1String(""), QByteArray("#define foo(ARGS) int f(ARGS)\n" "foo(int a)\n" ";\n")); - QVERIFY(preprocessed.contains("#gen true\n# 2 ")); + QVERIFY(preprocessed.contains("#gen true\n# 2 \"\"\nint f")); preprocessed = preprocess(QLatin1String(""), QByteArray("#define foo(ARGS) int f(ARGS)\n" "foo(int \n" " a);\n")); - QVERIFY(preprocessed.contains("#gen true\n# 2 ")); + QVERIFY(preprocessed.contains("#gen true\n# 2 \"\"\nint f")); preprocessed = preprocess(QLatin1String(""), QByteArray("#define foo int f\n" "foo;\n")); - QVERIFY(preprocessed.contains("#gen true\n# 2 ")); + QVERIFY(preprocessed.contains("#gen true\n# 2 \"\"\nint f")); preprocessed = preprocess(QLatin1String(""), QByteArray("#define foo int f\n" "foo\n" ";\n")); - QVERIFY(preprocessed.contains("#gen true\n# 2 ")); + QVERIFY(preprocessed.contains("#gen true\n# 2 \"\"\nint f")); } void tst_Preprocessor::objmacro_expanding_as_fnmacro_notification() @@ -523,7 +626,6 @@ void tst_Preprocessor::test_file_builtin() void tst_Preprocessor::comparisons_data() { - /* QTest::addColumn("infile"); QTest::addColumn("outfile"); QTest::addColumn("errorfile"); @@ -541,7 +643,6 @@ void tst_Preprocessor::comparisons_data() QTest::newRow("macro-test") << "macro-test.cpp" << "macro-test.out.cpp" << ""; QTest::newRow("empty-macro") << "empty-macro.cpp" << "empty-macro.out.cpp" << ""; QTest::newRow("empty-macro 2") << "empty-macro.2.cpp" << "empty-macro.2.out.cpp" << ""; - */ } void tst_Preprocessor::comparisons()