From 009d6b1e2ffd9fc617c2bfe135daf2eb107fc5b6 Mon Sep 17 00:00:00 2001 From: Leandro Melo Date: Wed, 15 Aug 2012 16:06:22 +0200 Subject: [PATCH] C++: Handle C++ style comments in macro expansion Notice that a similar problem still exists for which we need to fix the lexer when there's a C style commend which ends with a backslash-newline. Task-number: QTCREATORBUG-7713 Change-Id: I0f6d561703984f917fa5ed29de020ad0bdc5aaf0 Reviewed-by: David Schulz Reviewed-by: hjk --- src/libs/cplusplus/pp-engine.cpp | 16 +++- .../preprocessor/tst_preprocessor.cpp | 73 +++++++++++++++++++ 2 files changed, 88 insertions(+), 1 deletion(-) diff --git a/src/libs/cplusplus/pp-engine.cpp b/src/libs/cplusplus/pp-engine.cpp index 45cf36f5882..f71ba47c142 100644 --- a/src/libs/cplusplus/pp-engine.cpp +++ b/src/libs/cplusplus/pp-engine.cpp @@ -1349,7 +1349,21 @@ void Preprocessor::scanActualArgument(PPToken *tk, QVector *tokens) break; } - tokens->append(*tk); + if (m_keepComments + && (tk->is(T_CPP_COMMENT) || tk->is(T_CPP_DOXY_COMMENT))) { + // Even in keep comments mode, we cannot preserve C++ style comments inside the + // expansion. We stick with GCC's approach which is to replace them by C style + // comments (currently clang just gets rid of them) and transform internals */ + // into *|. + QByteArray text = m_state.m_source.mid(tk->begin() + 2, tk->end() - tk->begin() - 2); + const QByteArray &comment = "/*" + text.replace("*/", "*|") + "*/"; + tokens->append(generateToken(T_COMMENT, + comment.constData(), comment.size(), + tk->lineno, false)); + } else { + tokens->append(*tk); + } + lex(tk); } } diff --git a/tests/auto/cplusplus/preprocessor/tst_preprocessor.cpp b/tests/auto/cplusplus/preprocessor/tst_preprocessor.cpp index b1659bdad8e..015fffc153a 100644 --- a/tests/auto/cplusplus/preprocessor/tst_preprocessor.cpp +++ b/tests/auto/cplusplus/preprocessor/tst_preprocessor.cpp @@ -1181,6 +1181,42 @@ void tst_Preprocessor::comments_within_data() "# 10 \"\"\n" "x = 10\n"; QTest::newRow("case 4") << original << expected; + + original = "#define FOO(x, y) { (void)x; (void)y; }\n" + "\n" + "void foo() {\n" + " FOO(10,\n" + " //comment\n" + " 12\n" + "}\n"; + expected = + "# 1 \"\"\n" + "\n" + "\n" + "void foo() {\n" + "# expansion begin 57,3 ~4 4:7 ~4 6:7 7:0 ~2\n" + "{ (void)10; (void)12}; }\n" + "# expansion end\n" + "# 8 \"\"\n"; + QTest::newRow("case 5") << original << expected; + + original = "#define FOO(x, y) { (void)x; (void)y; }\n" + "\n" + "void foo() {\n" + " FOO(10,\n" + " //tricky*/comment\n" + " 12\n" + "}\n"; + expected = + "# 1 \"\"\n" + "\n" + "\n" + "void foo() {\n" + "# expansion begin 57,3 ~4 4:7 ~4 6:7 7:0 ~2\n" + "{ (void)10; (void)12}; }\n" + "# expansion end\n" + "# 8 \"\"\n"; + QTest::newRow("case 6") << original << expected; } void tst_Preprocessor::comments_within2() @@ -1298,6 +1334,43 @@ void tst_Preprocessor::comments_within2_data() "*/\n" "x = 10\n"; QTest::newRow("case 4") << original << expected; + + + original = "#define FOO(x, y) { (void)x; (void)y; }\n" + "\n" + "void foo() {\n" + " FOO(10,\n" + " //comment\n" + " 12\n" + "}\n"; + expected = + "# 1 \"\"\n" + "\n" + "\n" + "void foo() {\n" + "# expansion begin 57,3 ~4 4:7 ~5 6:7 7:0 ~2\n" + "{ (void)10; (void)/*comment*/ 12}; }\n" + "# expansion end\n" + "# 8 \"\"\n"; + QTest::newRow("case 5") << original << expected; + + original = "#define FOO(x, y) { (void)x; (void)y; }\n" + "\n" + "void foo() {\n" + " FOO(10,\n" + " //tricky*/comment\n" + " 12\n" + "}\n"; + expected = + "# 1 \"\"\n" + "\n" + "\n" + "void foo() {\n" + "# expansion begin 57,3 ~4 4:7 ~5 6:7 7:0 ~2\n" + "{ (void)10; (void)/*tricky*|comment*/ 12}; }\n" + "# expansion end\n" + "# 8 \"\"\n"; + QTest::newRow("case 6") << original << expected; } void tst_Preprocessor::multiline_strings()