From a98a95cca735b95cca5c904fa5ca875d916effc1 Mon Sep 17 00:00:00 2001 From: Francois Ferrand Date: Fri, 28 Jul 2017 07:56:14 +0000 Subject: clang-format: fix block OpeningLineIndex around preprocessor Summary: The current code would return an incorrect value when a preprocessor directive is present immediately after the opening brace: this causes the nanespace end comment fixer to break in some places, for exemple it would not add the comment in this case: namespace a { #define FOO } Fixing the computation is simple enough, but it was breaking a feature, as it would cause comments to be added also when the namespace declaration was dependant on conditional compilation. To fix this, a hash of the current preprocessor stack/branches is computed at the beginning of parseBlock(), so that we explicitely do not store the OpeningLineIndex when the beginning and end of the block are not in the same preprocessor conditions. Tthe hash is computed based on the line, but this could propbably be improved by using the actual condition, so that clang-format would be able to match multiple identical #ifdef blocks. Reviewers: krasimir, djasper Reviewed By: krasimir Subscribers: klimek, cfe-commits Differential Revision: https://reviews.llvm.org/D35483 llvm-svn: 309369 --- .../Format/NamespaceEndCommentsFixerTest.cpp | 128 +++++++++++++++++++++ 1 file changed, 128 insertions(+) (limited to 'clang/unittests/Format/NamespaceEndCommentsFixerTest.cpp') diff --git a/clang/unittests/Format/NamespaceEndCommentsFixerTest.cpp b/clang/unittests/Format/NamespaceEndCommentsFixerTest.cpp index 92f34216293..fda8b4d69fe 100644 --- a/clang/unittests/Format/NamespaceEndCommentsFixerTest.cpp +++ b/clang/unittests/Format/NamespaceEndCommentsFixerTest.cpp @@ -509,6 +509,134 @@ TEST_F(NamespaceEndCommentsFixerTest, "}\n")); } +TEST_F(NamespaceEndCommentsFixerTest, AddEndCommentForNamespacesAroundMacros) { + // Conditional blocks around are fine + EXPECT_EQ("namespace A {\n" + "#if 1\n" + "int i;\n" + "#endif\n" + "}// namespace A", + fixNamespaceEndComments("namespace A {\n" + "#if 1\n" + "int i;\n" + "#endif\n" + "}")); + EXPECT_EQ("#if 1\n" + "#endif\n" + "namespace A {\n" + "int i;\n" + "int j;\n" + "}// namespace A", + fixNamespaceEndComments("#if 1\n" + "#endif\n" + "namespace A {\n" + "int i;\n" + "int j;\n" + "}")); + EXPECT_EQ("namespace A {\n" + "int i;\n" + "int j;\n" + "}// namespace A\n" + "#if 1\n" + "#endif", + fixNamespaceEndComments("namespace A {\n" + "int i;\n" + "int j;\n" + "}\n" + "#if 1\n" + "#endif")); + EXPECT_EQ("#if 1\n" + "namespace A {\n" + "int i;\n" + "int j;\n" + "}// namespace A\n" + "#endif", + fixNamespaceEndComments("#if 1\n" + "namespace A {\n" + "int i;\n" + "int j;\n" + "}\n" + "#endif")); + + // Macro definition has no impact + EXPECT_EQ("namespace A {\n" + "#define FOO\n" + "int i;\n" + "}// namespace A", + fixNamespaceEndComments("namespace A {\n" + "#define FOO\n" + "int i;\n" + "}")); + EXPECT_EQ("#define FOO\n" + "namespace A {\n" + "int i;\n" + "int j;\n" + "}// namespace A", + fixNamespaceEndComments("#define FOO\n" + "namespace A {\n" + "int i;\n" + "int j;\n" + "}")); + EXPECT_EQ("namespace A {\n" + "int i;\n" + "int j;\n" + "}// namespace A\n" + "#define FOO\n", + fixNamespaceEndComments("namespace A {\n" + "int i;\n" + "int j;\n" + "}\n" + "#define FOO\n")); + + // No replacement if open & close in different conditional blocks + EXPECT_EQ("#if 1\n" + "namespace A {\n" + "#endif\n" + "int i;\n" + "int j;\n" + "#if 1\n" + "}\n" + "#endif", + fixNamespaceEndComments("#if 1\n" + "namespace A {\n" + "#endif\n" + "int i;\n" + "int j;\n" + "#if 1\n" + "}\n" + "#endif")); + EXPECT_EQ("#ifdef A\n" + "namespace A {\n" + "#endif\n" + "int i;\n" + "int j;\n" + "#ifdef B\n" + "}\n" + "#endif", + fixNamespaceEndComments("#ifdef A\n" + "namespace A {\n" + "#endif\n" + "int i;\n" + "int j;\n" + "#ifdef B\n" + "}\n" + "#endif")); + + // No replacement inside unreachable conditional block + EXPECT_EQ("#if 0\n" + "namespace A {\n" + "int i;\n" + "int j;\n" + "}\n" + "#endif", + fixNamespaceEndComments("#if 0\n" + "namespace A {\n" + "int i;\n" + "int j;\n" + "}\n" + "#endif")); +} + TEST_F(NamespaceEndCommentsFixerTest, DoesNotAddEndCommentForNamespacesInMacroDeclarations) { EXPECT_EQ("#ifdef 1\n" -- cgit v1.2.3