forked from qt-creator/qt-creator
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: Erik Verbruggen <erik.verbruggen@nokia.com>
This commit is contained in:
committed by
Erik Verbruggen
parent
558b6e08ae
commit
2386d701b6
@@ -587,7 +587,7 @@ Preprocessor::State Preprocessor::createStateFromSource(const QByteArray &source
|
||||
return state;
|
||||
}
|
||||
|
||||
void Preprocessor::processNewline(bool force)
|
||||
void Preprocessor::processNewline(bool force, int extraLines)
|
||||
{
|
||||
if (_dot != _tokens.constBegin()) {
|
||||
TokenIterator prevTok = _dot - 1;
|
||||
@@ -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;
|
||||
|
||||
if (force || env->currentLine > _dot->lineno) {
|
||||
if (force || env->currentLine > lineno) {
|
||||
out("\n# ");
|
||||
out(QByteArray::number(_dot->lineno));
|
||||
out(QByteArray::number(lineno));
|
||||
out(' ');
|
||||
out('"');
|
||||
out(env->currentFile.toUtf8());
|
||||
out('"');
|
||||
out('\n');
|
||||
} else {
|
||||
for (unsigned i = env->currentLine; i < _dot->lineno; ++i)
|
||||
for (unsigned i = env->currentLine; i < lineno; ++i)
|
||||
out('\n');
|
||||
}
|
||||
|
||||
env->currentLine = _dot->lineno;
|
||||
env->currentLine = lineno;
|
||||
}
|
||||
|
||||
void Preprocessor::processSkippingBlocks(bool skippingBlocks,
|
||||
@@ -650,28 +652,33 @@ void Preprocessor::processSkippingBlocks(bool skippingBlocks,
|
||||
|
||||
bool Preprocessor::markGeneratedTokens(bool markGeneratedTokens,
|
||||
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;
|
||||
_markGeneratedTokens = markGeneratedTokens;
|
||||
|
||||
if (previous != _markGeneratedTokens) {
|
||||
if (! dot)
|
||||
dot = _dot;
|
||||
|
||||
if (_markGeneratedTokens)
|
||||
out("\n#gen true");
|
||||
else
|
||||
out("\n#gen false");
|
||||
|
||||
processNewline(/*force = */ true);
|
||||
processNewline(/*force = */ true, extraLines);
|
||||
|
||||
const char *begin = _source.constBegin();
|
||||
const char *end = begin;
|
||||
|
||||
if (markGeneratedTokens)
|
||||
end += dot->begin();
|
||||
else
|
||||
end += (dot - 1)->end();
|
||||
const char *end = begin + position;
|
||||
|
||||
const char *it = end - 1;
|
||||
for (; it != begin - 1; --it) {
|
||||
@@ -688,7 +695,7 @@ bool Preprocessor::markGeneratedTokens(bool markGeneratedTokens,
|
||||
out(*it);
|
||||
}
|
||||
|
||||
if (! markGeneratedTokens && dot->f.newline)
|
||||
if (!markGeneratedTokens && newline)
|
||||
processNewline(/*force = */ true);
|
||||
}
|
||||
|
||||
|
@@ -110,6 +110,7 @@ private:
|
||||
};
|
||||
|
||||
bool markGeneratedTokens(bool markGeneratedTokens, TokenIterator dot = 0);
|
||||
bool markGeneratedTokens(bool markGeneratedTokens, int position, int extraLines=0, bool newline=false);
|
||||
|
||||
QByteArray expand(const QByteArray &source);
|
||||
void expand(const QByteArray &source, QByteArray *result);
|
||||
@@ -143,7 +144,7 @@ private:
|
||||
void collectActualArguments(QVector<MacroArgumentReference> *actuals);
|
||||
MacroArgumentReference collectOneActualArgument();
|
||||
|
||||
void processNewline(bool force = false);
|
||||
void processNewline(bool force = false, int extraLines = 0);
|
||||
|
||||
void processSkippingBlocks(bool skippingBlocks,
|
||||
TokenIterator dot, TokenIterator lastToken);
|
||||
|
@@ -45,6 +45,7 @@ private Q_SLOTS:
|
||||
void named_va_args();
|
||||
void first_empty_macro_arg();
|
||||
void param_expanding_as_multiple_params();
|
||||
void macro_definition_lineno();
|
||||
void unfinished_function_like_macro_call();
|
||||
void nasty_macro_expansion();
|
||||
void tstst();
|
||||
@@ -114,6 +115,40 @@ void tst_Preprocessor::param_expanding_as_multiple_params()
|
||||
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()
|
||||
{
|
||||
Client *client = 0; // no client.
|
||||
|
Reference in New Issue
Block a user