Commit 2386d701 authored by Francois Ferrand's avatar Francois Ferrand Committed by Erik Verbruggen

Preprocessor: fix line for generated code.

The macro used to be at the same line as the first token after the
closing parenthesis.

Change-Id: I4c2d7317632baf612900e84572017aeb247d0585
Reviewed-by: default avatarErik Verbruggen <erik.verbruggen@nokia.com>
parent 558b6e08
...@@ -587,7 +587,7 @@ Preprocessor::State Preprocessor::createStateFromSource(const QByteArray &source ...@@ -587,7 +587,7 @@ Preprocessor::State Preprocessor::createStateFromSource(const QByteArray &source
return state; return state;
} }
void Preprocessor::processNewline(bool force) void Preprocessor::processNewline(bool force, int extraLines)
{ {
if (_dot != _tokens.constBegin()) { if (_dot != _tokens.constBegin()) {
TokenIterator prevTok = _dot - 1; TokenIterator prevTok = _dot - 1;
...@@ -605,23 +605,25 @@ void Preprocessor::processNewline(bool force) ...@@ -605,23 +605,25 @@ void Preprocessor::processNewline(bool force)
} }
} }
if (! force && env->currentLine == _dot->lineno) unsigned lineno = _dot->lineno + extraLines;
if (! force && env->currentLine == lineno)
return; return;
if (force || env->currentLine > _dot->lineno) { if (force || env->currentLine > lineno) {
out("\n# "); out("\n# ");
out(QByteArray::number(_dot->lineno)); out(QByteArray::number(lineno));
out(' '); out(' ');
out('"'); out('"');
out(env->currentFile.toUtf8()); out(env->currentFile.toUtf8());
out('"'); out('"');
out('\n'); out('\n');
} else { } else {
for (unsigned i = env->currentLine; i < _dot->lineno; ++i) for (unsigned i = env->currentLine; i < lineno; ++i)
out('\n'); out('\n');
} }
env->currentLine = _dot->lineno; env->currentLine = lineno;
} }
void Preprocessor::processSkippingBlocks(bool skippingBlocks, void Preprocessor::processSkippingBlocks(bool skippingBlocks,
...@@ -650,28 +652,33 @@ void Preprocessor::processSkippingBlocks(bool skippingBlocks, ...@@ -650,28 +652,33 @@ void Preprocessor::processSkippingBlocks(bool skippingBlocks,
bool Preprocessor::markGeneratedTokens(bool markGeneratedTokens, bool Preprocessor::markGeneratedTokens(bool markGeneratedTokens,
TokenIterator dot) TokenIterator dot)
{
bool previous = _markGeneratedTokens;
if (previous != markGeneratedTokens) {
if (! dot)
dot = _dot;
const int pos = markGeneratedTokens ? dot->begin() : (dot - 1)->end();
this->markGeneratedTokens(markGeneratedTokens, pos, dot->lineno - _dot->lineno, dot->f.newline);
}
return previous;
}
bool Preprocessor::markGeneratedTokens(bool markGeneratedTokens, int position, int extraLines, bool newline)
{ {
bool previous = _markGeneratedTokens; bool previous = _markGeneratedTokens;
_markGeneratedTokens = markGeneratedTokens; _markGeneratedTokens = markGeneratedTokens;
if (previous != _markGeneratedTokens) { if (previous != _markGeneratedTokens) {
if (! dot)
dot = _dot;
if (_markGeneratedTokens) if (_markGeneratedTokens)
out("\n#gen true"); out("\n#gen true");
else else
out("\n#gen false"); out("\n#gen false");
processNewline(/*force = */ true); processNewline(/*force = */ true, extraLines);
const char *begin = _source.constBegin(); const char *begin = _source.constBegin();
const char *end = begin; const char *end = begin + position;
if (markGeneratedTokens)
end += dot->begin();
else
end += (dot - 1)->end();
const char *it = end - 1; const char *it = end - 1;
for (; it != begin - 1; --it) { for (; it != begin - 1; --it) {
...@@ -688,7 +695,7 @@ bool Preprocessor::markGeneratedTokens(bool markGeneratedTokens, ...@@ -688,7 +695,7 @@ bool Preprocessor::markGeneratedTokens(bool markGeneratedTokens,
out(*it); out(*it);
} }
if (! markGeneratedTokens && dot->f.newline) if (!markGeneratedTokens && newline)
processNewline(/*force = */ true); processNewline(/*force = */ true);
} }
......
...@@ -110,6 +110,7 @@ private: ...@@ -110,6 +110,7 @@ private:
}; };
bool markGeneratedTokens(bool markGeneratedTokens, TokenIterator dot = 0); bool markGeneratedTokens(bool markGeneratedTokens, TokenIterator dot = 0);
bool markGeneratedTokens(bool markGeneratedTokens, int position, int extraLines=0, bool newline=false);
QByteArray expand(const QByteArray &source); QByteArray expand(const QByteArray &source);
void expand(const QByteArray &source, QByteArray *result); void expand(const QByteArray &source, QByteArray *result);
...@@ -143,7 +144,7 @@ private: ...@@ -143,7 +144,7 @@ private:
void collectActualArguments(QVector<MacroArgumentReference> *actuals); void collectActualArguments(QVector<MacroArgumentReference> *actuals);
MacroArgumentReference collectOneActualArgument(); MacroArgumentReference collectOneActualArgument();
void processNewline(bool force = false); void processNewline(bool force = false, int extraLines = 0);
void processSkippingBlocks(bool skippingBlocks, void processSkippingBlocks(bool skippingBlocks,
TokenIterator dot, TokenIterator lastToken); TokenIterator dot, TokenIterator lastToken);
......
...@@ -45,6 +45,7 @@ private Q_SLOTS: ...@@ -45,6 +45,7 @@ private Q_SLOTS:
void named_va_args(); void named_va_args();
void first_empty_macro_arg(); void first_empty_macro_arg();
void param_expanding_as_multiple_params(); void param_expanding_as_multiple_params();
void macro_definition_lineno();
void unfinished_function_like_macro_call(); void unfinished_function_like_macro_call();
void nasty_macro_expansion(); void nasty_macro_expansion();
void tstst(); void tstst();
...@@ -114,6 +115,40 @@ void tst_Preprocessor::param_expanding_as_multiple_params() ...@@ -114,6 +115,40 @@ void tst_Preprocessor::param_expanding_as_multiple_params()
QVERIFY(preprocessed.contains("int f(int a,int b);")); QVERIFY(preprocessed.contains("int f(int a,int b);"));
} }
void tst_Preprocessor::macro_definition_lineno()
{
Client *client = 0; // no client.
Environment env;
Preprocessor preprocess(client, &env);
QByteArray preprocessed = preprocess(QLatin1String("<stdin>"),
QByteArray("#define foo(ARGS) int f(ARGS)\n"
"foo(int a);\n"));
QVERIFY(preprocessed.contains("#gen true\n# 2 "));
preprocessed = preprocess(QLatin1String("<stdin>"),
QByteArray("#define foo(ARGS) int f(ARGS)\n"
"foo(int a)\n"
";\n"));
QVERIFY(preprocessed.contains("#gen true\n# 2 "));
preprocessed = preprocess(QLatin1String("<stdin>"),
QByteArray("#define foo(ARGS) int f(ARGS)\n"
"foo(int \n"
" a);\n"));
QVERIFY(preprocessed.contains("#gen true\n# 2 "));
preprocessed = preprocess(QLatin1String("<stdin>"),
QByteArray("#define foo int f\n"
"foo;\n"));
QVERIFY(preprocessed.contains("#gen true\n# 2 "));
preprocessed = preprocess(QLatin1String("<stdin>"),
QByteArray("#define foo int f\n"
"foo\n"
";\n"));
QVERIFY(preprocessed.contains("#gen true\n# 2 "));
}
void tst_Preprocessor::unfinished_function_like_macro_call() void tst_Preprocessor::unfinished_function_like_macro_call()
{ {
Client *client = 0; // no client. Client *client = 0; // no client.
......
Markdown is supported
0% or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment