[clang-format] Align preprocessor comments with #
Summary:
r312125, which introduced preprocessor indentation, shipped with a known
issue where "indentation of comments immediately before indented
preprocessor lines is toggled on each run". For example these two forms
toggle:
#ifndef HEADER_H
#define HEADER_H
#if 1
// comment
# define A 0
#endif
#endif
#ifndef HEADER_H
#define HEADER_H
#if 1
// comment
# define A 0
#endif
#endif
This happens because we check vertical alignment against the '#' yet
indent to the level of the 'define'. This patch resolves this issue by
aligning against the '#'.
Reviewers: krasimir, klimek, djasper
Reviewed By: krasimir
Subscribers: cfe-commits
Differential Revision: https://reviews.llvm.org/D42408
llvm-svn: 323904
diff --git a/clang/unittests/Format/FormatTest.cpp b/clang/unittests/Format/FormatTest.cpp
index dcb1089..cbabc45 100644
--- a/clang/unittests/Format/FormatTest.cpp
+++ b/clang/unittests/Format/FormatTest.cpp
@@ -2595,21 +2595,85 @@
"code();\n"
"#endif",
Style));
- // FIXME: The comment indent corrector in TokenAnnotator gets thrown off by
- // preprocessor indentation.
- EXPECT_EQ("#if 1\n"
- " // comment\n"
- "# define A 0\n"
- "// comment\n"
- "# define B 0\n"
- "#endif",
- format("#if 1\n"
- "// comment\n"
- "# define A 0\n"
- " // comment\n"
- "# define B 0\n"
- "#endif",
- Style));
+ // Keep comments aligned with #, otherwise indent comments normally. These
+ // tests cannot use verifyFormat because messUp manipulates leading
+ // whitespace.
+ {
+ const char *Expected = ""
+ "void f() {\n"
+ "#if 1\n"
+ "// Preprocessor aligned.\n"
+ "# define A 0\n"
+ " // Code. Separated by blank line.\n"
+ "\n"
+ "# define B 0\n"
+ " // Code. Not aligned with #\n"
+ "# define C 0\n"
+ "#endif";
+ const char *ToFormat = ""
+ "void f() {\n"
+ "#if 1\n"
+ "// Preprocessor aligned.\n"
+ "# define A 0\n"
+ "// Code. Separated by blank line.\n"
+ "\n"
+ "# define B 0\n"
+ " // Code. Not aligned with #\n"
+ "# define C 0\n"
+ "#endif";
+ EXPECT_EQ(Expected, format(ToFormat, Style));
+ EXPECT_EQ(Expected, format(Expected, Style));
+ }
+ // Keep block quotes aligned.
+ {
+ const char *Expected = ""
+ "void f() {\n"
+ "#if 1\n"
+ "/* Preprocessor aligned. */\n"
+ "# define A 0\n"
+ " /* Code. Separated by blank line. */\n"
+ "\n"
+ "# define B 0\n"
+ " /* Code. Not aligned with # */\n"
+ "# define C 0\n"
+ "#endif";
+ const char *ToFormat = ""
+ "void f() {\n"
+ "#if 1\n"
+ "/* Preprocessor aligned. */\n"
+ "# define A 0\n"
+ "/* Code. Separated by blank line. */\n"
+ "\n"
+ "# define B 0\n"
+ " /* Code. Not aligned with # */\n"
+ "# define C 0\n"
+ "#endif";
+ EXPECT_EQ(Expected, format(ToFormat, Style));
+ EXPECT_EQ(Expected, format(Expected, Style));
+ }
+ // Keep comments aligned with un-indented directives.
+ {
+ const char *Expected = ""
+ "void f() {\n"
+ "// Preprocessor aligned.\n"
+ "#define A 0\n"
+ " // Code. Separated by blank line.\n"
+ "\n"
+ "#define B 0\n"
+ " // Code. Not aligned with #\n"
+ "#define C 0\n";
+ const char *ToFormat = ""
+ "void f() {\n"
+ "// Preprocessor aligned.\n"
+ "#define A 0\n"
+ "// Code. Separated by blank line.\n"
+ "\n"
+ "#define B 0\n"
+ " // Code. Not aligned with #\n"
+ "#define C 0\n";
+ EXPECT_EQ(Expected, format(ToFormat, Style));
+ EXPECT_EQ(Expected, format(Expected, Style));
+ }
// Test with tabs.
Style.UseTab = FormatStyle::UT_Always;
Style.IndentWidth = 8;