Commit ff0a4654 authored by Erik Verbruggen's avatar Erik Verbruggen
Browse files

[C++] Always output a #line as first line of the pp output.



Change-Id: I60d25109ae8fe3628b1899078a21010263787c33
Reviewed-by: default avatarRoberto Raggi <roberto.raggi@nokia.com>
parent 5001982e
......@@ -56,6 +56,7 @@ QByteArray FastPreprocessor::run(QString fileName, const QString &source)
}
const QByteArray preprocessed = _preproc(fileName, source);
// qDebug("FastPreprocessor::run for %s produced [[%s]]", fileName.toUtf8().constData(), preprocessed.constData());
return preprocessed;
}
......
......@@ -624,6 +624,16 @@ Preprocessor::State Preprocessor::createStateFromSource(const QString &fileName,
return state;
}
void Preprocessor::genLine(unsigned lineno, const QByteArray &fileName) const
{
startNewOutputLine();
out("# ");
out(QByteArray::number(lineno));
out(" \"");
out(fileName);
out("\"\n");
}
void Preprocessor::handleDefined(PPToken *tk)
{
unsigned lineno = tk->lineno;
......@@ -678,8 +688,8 @@ _Lagain:
m_state.m_lexer->scan(tk);
}
if (tk->isValid() && !tk->generated() && !tk->is(T_EOF_SYMBOL))
m_env->currentLine = tk->lineno;
// if (tk->isValid() && !tk->generated() && !tk->is(T_EOF_SYMBOL))
// m_env->currentLine = tk->lineno;
_Lclassify:
if (! m_state.m_inPreprocessorDirective) {
......@@ -906,12 +916,13 @@ void Preprocessor::preprocess(const QString &fileName, const QByteArray &source,
m_env->currentFile = fileName;
const unsigned previousCurrentLine = m_env->currentLine;
m_env->currentLine = 0;
m_env->currentLine = 1;
const QByteArray fn = fileName.toUtf8();
if (!m_state.m_noLines)
genLine(1, fn);
PPToken tk(m_state.m_source), prevTk;
unsigned lineno = 1;
do {
_Lrestart:
bool forceLine = false;
......@@ -927,30 +938,25 @@ _Lrestart:
if (m_state.m_markGeneratedTokens && tk.generated() && !prevTk.generated()) {
startNewOutputLine();
out("#gen true\n");
++lineno;
++m_env->currentLine;
forceLine = true;
} else if (m_state.m_markGeneratedTokens && !tk.generated() && prevTk.generated()) {
startNewOutputLine();
out("#gen false\n");
++lineno;
++m_env->currentLine;
forceLine = true;
}
if (forceLine || lineno != tk.lineno) {
if (forceLine || lineno > tk.lineno || tk.lineno - lineno > 3) {
if (forceLine || m_env->currentLine != tk.lineno) {
if (forceLine || m_env->currentLine > tk.lineno || tk.lineno - m_env->currentLine > 3) {
if (m_state.m_noLines) {
if (!m_state.m_markGeneratedTokens)
out(' ');
} else {
startNewOutputLine();
out("# ");
out(QByteArray::number(tk.lineno));
out(" \"");
out(fn);
out("\"\n");
genLine(tk.lineno, fn);
}
} else {
for (unsigned i = lineno; i < tk.lineno; ++i)
for (unsigned i = m_env->currentLine; i < tk.lineno; ++i)
out('\n');
}
} else {
......@@ -961,7 +967,7 @@ _Lrestart:
if (tk.whitespace() || prevTk.generated() != tk.generated() || !prevTk.isValid()) {
if (prevTk.generated() && tk.generated()) {
out(' ');
} else if (tk.isValid() && !prevTk.isValid() && tk.lineno == lineno) {
} else if (tk.isValid() && !prevTk.isValid() && tk.lineno == m_env->currentLine) {
out(QByteArray(prevTk.length() + (tk.whitespace() ? 1 : 0), ' '));
} else if (prevTk.generated() != tk.generated() || !prevTk.isValid()) {
const char *begin = tk.source().constBegin();
......@@ -988,9 +994,9 @@ _Lrestart:
const ByteArrayRef tkBytes = tk.asByteArrayRef();
out(tkBytes);
lineno = tk.lineno;
m_env->currentLine = tk.lineno;
if (tk.is(T_COMMENT) || tk.is(T_DOXY_COMMENT))
lineno += tkBytes.count('\n');
m_env->currentLine += tkBytes.count('\n');
prevTk = tk;
} while (tk.isNot(T_EOF_SYMBOL));
......
......@@ -159,6 +159,8 @@ private:
out('\n');
}
void genLine(unsigned lineno, const QByteArray &fileName) const;
inline void out(const QByteArray &text) const
{ if (m_state.m_result) m_state.m_result->append(text); }
......
# 1 "data/empty-macro.2.cpp"
# 6 "data/empty-macro.2.cpp"
class Test {
private:
......
# 1 "data/identifier-expansion.1.cpp"
#gen true
# 1 "data/identifier-expansion.1.cpp"
test test
......
# 1 "data/identifier-expansion.2.cpp"
#gen true
# 1 "data/identifier-expansion.2.cpp"
test test
......
# 1 "data/identifier-expansion.3.cpp"
# 8 "data/identifier-expansion.3.cpp"
enum op_code {
#gen true
......
# 1 "data/identifier-expansion.5.cpp"
# 9 "data/identifier-expansion.5.cpp"
# 1 "data/macro-test.cpp"
# 7 "data/macro-test.cpp"
void thisFunctionIsEnabled();
# 21 "data/macro-test.cpp"
......
# 1 "data/recursive.1.cpp"
#gen true
# 1 "data/recursive.1.cpp"
b
......
# 1 "data/reserved.1.cpp"
# 5 "data/reserved.1.cpp"
int f() {
foreach (QString &s, QStringList()) {
......
......@@ -192,12 +192,12 @@ public:
}
}
void sourceNeeded(const QString &fileName)
void sourceNeeded(const QString &fileName, bool nolines)
{
QByteArray src = loadSource(fileName);
QVERIFY(!src.isEmpty());
m_pp.preprocess(fileName, src, m_output, false, true, false);
m_pp.preprocess(fileName, src, m_output, nolines, true, false);
}
QList<Block> skippedBlocks() const
......@@ -223,12 +223,12 @@ class tst_Preprocessor: public QObject
Q_OBJECT
protected:
QByteArray preprocess(const QString &fileName, QByteArray * /*errors*/) {
QByteArray preprocess(const QString &fileName, QByteArray * /*errors*/, bool nolines) {
//### TODO: hook up errors
QByteArray output;
Environment env;
MockClient client(&env, &output);
client.sourceNeeded("data/" + fileName);
client.sourceNeeded("data/" + fileName, nolines);
return output;
}
......@@ -371,7 +371,8 @@ void tst_Preprocessor::unfinished_function_like_macro_call()
QByteArray preprocessed = preprocess(QLatin1String("<stdin>"),
QByteArray("\n#define foo(a,b) a + b"
"\nfoo(1, 2\n"));
QByteArray expected__("\n\n 1\n#gen true\n# 2 \"<stdin>\"\n+\n#gen false\n# 3 \"<stdin>\"\n 2\n");
QByteArray expected__("# 1 \"<stdin>\"\n\n\n 1\n#gen true\n# 2 \"<stdin>\"\n+\n#gen false\n# 3 \"<stdin>\"\n 2\n");
// DUMP_OUTPUT(preprocessed);
QCOMPARE(preprocessed, expected__);
}
......@@ -441,7 +442,7 @@ void tst_Preprocessor::tstst()
"namespace std _GLIBCXX_VISIBILITY(default) {\n"
"}\n"
));
const QByteArray result____ ="\n\n"
const QByteArray result____ ="# 1 \"<stdin>\"\n\n\n"
"namespace std\n"
"#gen true\n"
"# 2 \"<stdin>\"\n"
......@@ -454,6 +455,7 @@ void tst_Preprocessor::tstst()
" {\n"
"}\n";
// DUMP_OUTPUT(preprocessed);
QCOMPARE(preprocessed, result____);
}
......@@ -468,6 +470,7 @@ void tst_Preprocessor::test_file_builtin()
QByteArray("const char *f = __FILE__\n"
));
const QByteArray result____ =
"# 1 \"some-file.c\"\n"
"const char *f =\n"
"#gen true\n"
"# 1 \"some-file.c\"\n"
......@@ -506,7 +509,7 @@ void tst_Preprocessor::comparisons()
QFETCH(QString, errorfile);
QByteArray errors;
QByteArray preprocessed = preprocess(infile, &errors);
QByteArray preprocessed = preprocess(infile, &errors, infile == outfile);
// DUMP_OUTPUT(preprocessed);
......
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