From 67caa75c56d303c9a4b72342959337144a97b1a7 Mon Sep 17 00:00:00 2001 From: Orgad Shaneh Date: Wed, 5 Feb 2014 08:37:33 +0200 Subject: [PATCH] C++: Fix preprocessing of uncontinued line-escaping The following snippet demonstrates the problem: --- snip --- // comment \ #include ... class Foo { ... }; --- snap --- If there are >=9 empty/preprocessor lines, the preprocessed source becomes // comment \ # 12 "file.cpp" ... The lexer considers the line marker as a continued C++ comment, and highlighting is broken Change-Id: I30a2fc7d19b279316e9273697179c90d81099573 Reviewed-by: Erik Verbruggen --- src/libs/cplusplus/pp-engine.cpp | 11 +++++++- .../preprocessor/tst_preprocessor.cpp | 25 +++++++++++++++++++ 2 files changed, 35 insertions(+), 1 deletion(-) diff --git a/src/libs/cplusplus/pp-engine.cpp b/src/libs/cplusplus/pp-engine.cpp index 9c86b7e35d..21440bc86c 100644 --- a/src/libs/cplusplus/pp-engine.cpp +++ b/src/libs/cplusplus/pp-engine.cpp @@ -2039,6 +2039,15 @@ bool Preprocessor::atStartOfOutputLine() const void Preprocessor::maybeStartOutputLine() { QByteArray &buffer = currentOutputBuffer(); - if (!buffer.isEmpty() && !buffer.endsWith('\n')) + if (buffer.isEmpty()) + return; + if (!buffer.endsWith('\n')) + buffer.append('\n'); + // If previous line ends with \ (possibly followed by whitespace), add another \n + const char *start = buffer.constData(); + const char *ch = start + buffer.length() - 2; + while (ch > start && (*ch != '\n') && std::isspace(*ch)) + --ch; + if (*ch == '\\') buffer.append('\n'); } diff --git a/tests/auto/cplusplus/preprocessor/tst_preprocessor.cpp b/tests/auto/cplusplus/preprocessor/tst_preprocessor.cpp index b262db3b40..ca3460335d 100644 --- a/tests/auto/cplusplus/preprocessor/tst_preprocessor.cpp +++ b/tests/auto/cplusplus/preprocessor/tst_preprocessor.cpp @@ -1453,6 +1453,31 @@ void tst_Preprocessor::comments_within_data() "\n" "int foo = 4;" ); + + QTest::newRow("joined_unterminated") << _( + "// comment \\\n" + "\n" + "\n" + "\n" + "\n" + "\n" + "\n" + "\n" + "\n" + "\n" + "\n" + "int foo = 4;" + ) << _( + "# 1 \"\"\n" + "# 12 \"\"\n" + "int foo = 4;" + ) << _( + "# 1 \"\"\n" + "// comment \\\n" + "\n" + "# 12 \"\"\n" + "int foo = 4;" + ); } void tst_Preprocessor::comments_before_args() -- GitLab