diff --git a/src/libs/cplusplus/pp-engine.cpp b/src/libs/cplusplus/pp-engine.cpp index 634f5789d78..1f74cbeab56 100644 --- a/src/libs/cplusplus/pp-engine.cpp +++ b/src/libs/cplusplus/pp-engine.cpp @@ -1113,16 +1113,16 @@ void Preprocessor::handleIncludeDirective(PPToken *tk) m_state.m_lexer->setScanAngleStringLiteralTokens(true); lex(tk); // consume "include" token m_state.m_lexer->setScanAngleStringLiteralTokens(false); + const unsigned line = tk->lineno; QByteArray included; if (tk->is(T_STRING_LITERAL) || tk->is(T_ANGLE_STRING_LITERAL)) { included = tk->asByteArrayRef().toByteArray(); + lex(tk); // consume string token } else { included = expand(tk); } included = included.trimmed(); - const unsigned line = tk->lineno; - lex(tk); // consume string token // qDebug("include [[%s]]", included.toUtf8().constData()); Client::IncludeType mode; @@ -1249,7 +1249,8 @@ QByteArray Preprocessor::expand(PPToken *tk, PPToken *lastConditionToken) const ByteArrayRef s = tk->asByteArrayRef(); condition.append(s.start(), s.length()); condition += ' '; - *lastConditionToken = *tk; + if (lastConditionToken) + *lastConditionToken = *tk; lex(tk); } // qDebug("*** Condition before: [%s]", condition.constData()); diff --git a/tests/auto/cplusplus/preprocessor/tst_preprocessor.cpp b/tests/auto/cplusplus/preprocessor/tst_preprocessor.cpp index edec90f7677..73e71d95cb5 100644 --- a/tests/auto/cplusplus/preprocessor/tst_preprocessor.cpp +++ b/tests/auto/cplusplus/preprocessor/tst_preprocessor.cpp @@ -65,6 +65,24 @@ void saveData(const QByteArray &data, const QString &fileName) inf.close(); } +struct Include +{ + Include(const QString &fileName, Client::IncludeType type, unsigned line) + : fileName(fileName), type(type), line(line) + {} + + QString fileName; + Client::IncludeType type; + unsigned line; +}; +QDebug &operator<<(QDebug& d, const Include &i) { + d << '[' << i.fileName + << ',' << (i.type == Client::IncludeGlobal ? "Global" : (i.type == Client::IncludeLocal ? "Local" : "Unknown")) + << ',' << i.line + << ']'; + return d; +} + class MockClient: public Client { public: @@ -107,8 +125,13 @@ public: { m_skippedBlocks.last().end = offset; } virtual void sourceNeeded(QString &includedFileName, IncludeType mode, - unsigned /*line*/) + unsigned line) { +#if 1 + m_recordedIncludes.append(Include(includedFileName, mode, line)); +#else + Q_UNUSED(line); + QString resolvedFileName; if (mode == IncludeLocal) resolvedFileName = resolveLocally(m_env->currentFile, includedFileName); @@ -128,6 +151,7 @@ public: // qDebug("%5d %s %s", m_includeDepth, QByteArray(m_includeDepth, '+').constData(), resolvedFileName.toUtf8().constData()); sourceNeeded(resolvedFileName); --m_includeDepth; +#endif } QString resolveLocally(const QString ¤tFileName, @@ -179,6 +203,9 @@ public: QList skippedBlocks() const { return m_skippedBlocks; } + QList recordedIncludes() const + { return m_recordedIncludes; } + private: Environment *m_env; QByteArray *m_output; @@ -186,6 +213,7 @@ private: QList m_includePaths; unsigned m_includeDepth; QList m_skippedBlocks; + QList m_recordedIncludes; }; QDebug &operator<<(QDebug& d, const MockClient::Block &b) { d << '[' << b.start << ',' << b.end << ']'; return d; } @@ -218,6 +246,7 @@ private slots: void test_file_builtin(); void blockSkipping(); + void includes_1(); void comparisons_data(); void comparisons(); @@ -523,5 +552,40 @@ void tst_Preprocessor::blockSkipping() QCOMPARE(b.end, 34U); } +void tst_Preprocessor::includes_1() +{ + QByteArray output; + Environment env; + MockClient client(&env, &output); + Preprocessor pp(&client, &env); + /*QByteArray preprocessed =*/ pp( + QLatin1String(""), + QByteArray("#define FOO \n" + "#define BAR \"bar.h\"\n" + "\n" + "#include FOO\n" + "#include BAR\n" + "\n" + "#include \n" + "#include \"mooze.h\"\n" + )); + + QList incs = client.recordedIncludes(); +// qDebug()<