This revision was automatically updated to reflect the committed changes.
Closed by commit rGf00a20e51c1d: [clang-format] Add the possibility to align
assignments spanning empty lines or… (authored by curdeius).
Repository:
rG LLVM Github Monorepo
CHANGES SINCE LAST ACTION
https://reviews.llvm.org/D93986/new/
https://reviews.llvm.org/D93986
Files:
clang/docs/ClangFormatStyleOptions.rst
clang/docs/ReleaseNotes.rst
clang/docs/tools/dump_format_style.py
clang/include/clang/Format/Format.h
clang/lib/Format/Format.cpp
clang/lib/Format/WhitespaceManager.cpp
clang/unittests/Format/FormatTest.cpp
Index: clang/unittests/Format/FormatTest.cpp
===================================================================
--- clang/unittests/Format/FormatTest.cpp
+++ clang/unittests/Format/FormatTest.cpp
@@ -11395,8 +11395,8 @@
"*/\n"
"}",
Tab));
- Tab.AlignConsecutiveAssignments = true;
- Tab.AlignConsecutiveDeclarations = true;
+ Tab.AlignConsecutiveAssignments = FormatStyle::ACS_Consecutive;
+ Tab.AlignConsecutiveDeclarations = FormatStyle::ACS_Consecutive;
Tab.TabWidth = 4;
Tab.IndentWidth = 4;
verifyFormat("class Assign {\n"
@@ -11634,8 +11634,8 @@
"*/\n"
"}",
Tab));
- Tab.AlignConsecutiveAssignments = true;
- Tab.AlignConsecutiveDeclarations = true;
+ Tab.AlignConsecutiveAssignments = FormatStyle::ACS_Consecutive;
+ Tab.AlignConsecutiveDeclarations = FormatStyle::ACS_Consecutive;
Tab.TabWidth = 4;
Tab.IndentWidth = 4;
verifyFormat("class Assign {\n"
@@ -12470,9 +12470,9 @@
TEST_F(FormatTest, AlignConsecutiveMacros) {
FormatStyle Style = getLLVMStyle();
- Style.AlignConsecutiveAssignments = true;
- Style.AlignConsecutiveDeclarations = true;
- Style.AlignConsecutiveMacros = false;
+ Style.AlignConsecutiveAssignments = FormatStyle::ACS_Consecutive;
+ Style.AlignConsecutiveDeclarations = FormatStyle::ACS_Consecutive;
+ Style.AlignConsecutiveMacros = FormatStyle::ACS_None;
verifyFormat("#define a 3\n"
"#define bbbb 4\n"
@@ -12496,7 +12496,7 @@
"#define ffff(x, y) (x - y)",
Style);
- Style.AlignConsecutiveMacros = true;
+ Style.AlignConsecutiveMacros = FormatStyle::ACS_Consecutive;
verifyFormat("#define a 3\n"
"#define bbbb 4\n"
"#define ccc (5)",
@@ -12536,7 +12536,7 @@
"};",
Style);
- Style.AlignConsecutiveMacros = false;
+ Style.AlignConsecutiveMacros = FormatStyle::ACS_None;
Style.ColumnLimit = 20;
verifyFormat("#define a \\\n"
@@ -12550,7 +12550,7 @@
" \"LLLLLLLL\"\n",
Style);
- Style.AlignConsecutiveMacros = true;
+ Style.AlignConsecutiveMacros = FormatStyle::ACS_Consecutive;
verifyFormat("#define a \\\n"
" \"aabbbbbbbbbbbb\"\n"
"#define D \\\n"
@@ -12561,12 +12561,766 @@
" \"FFFFFFFFFFFFF\" \\\n"
" \"LLLLLLLL\"\n",
Style);
+
+ // Test across comments
+ Style.MaxEmptyLinesToKeep = 10;
+ Style.ReflowComments = false;
+ Style.AlignConsecutiveMacros = FormatStyle::ACS_AcrossComments;
+ EXPECT_EQ("#define a 3\n"
+ "// line comment\n"
+ "#define bbbb 4\n"
+ "#define ccc (5)",
+ format("#define a 3\n"
+ "// line comment\n"
+ "#define bbbb 4\n"
+ "#define ccc (5)",
+ Style));
+
+ EXPECT_EQ("#define a 3\n"
+ "/* block comment */\n"
+ "#define bbbb 4\n"
+ "#define ccc (5)",
+ format("#define a 3\n"
+ "/* block comment */\n"
+ "#define bbbb 4\n"
+ "#define ccc (5)",
+ Style));
+
+ EXPECT_EQ("#define a 3\n"
+ "/* multi-line *\n"
+ " * block comment */\n"
+ "#define bbbb 4\n"
+ "#define ccc (5)",
+ format("#define a 3\n"
+ "/* multi-line *\n"
+ " * block comment */\n"
+ "#define bbbb 4\n"
+ "#define ccc (5)",
+ Style));
+
+ EXPECT_EQ("#define a 3\n"
+ "// multi-line line comment\n"
+ "//\n"
+ "#define bbbb 4\n"
+ "#define ccc (5)",
+ format("#define a 3\n"
+ "// multi-line line comment\n"
+ "//\n"
+ "#define bbbb 4\n"
+ "#define ccc (5)",
+ Style));
+
+ EXPECT_EQ("#define a 3\n"
+ "// empty lines still break.\n"
+ "\n"
+ "#define bbbb 4\n"
+ "#define ccc (5)",
+ format("#define a 3\n"
+ "// empty lines still break.\n"
+ "\n"
+ "#define bbbb 4\n"
+ "#define ccc (5)",
+ Style));
+
+ // Test across empty lines
+ Style.AlignConsecutiveMacros = FormatStyle::ACS_AcrossEmptyLines;
+ EXPECT_EQ("#define a 3\n"
+ "\n"
+ "#define bbbb 4\n"
+ "#define ccc (5)",
+ format("#define a 3\n"
+ "\n"
+ "#define bbbb 4\n"
+ "#define ccc (5)",
+ Style));
+
+ EXPECT_EQ("#define a 3\n"
+ "\n"
+ "\n"
+ "\n"
+ "#define bbbb 4\n"
+ "#define ccc (5)",
+ format("#define a 3\n"
+ "\n"
+ "\n"
+ "\n"
+ "#define bbbb 4\n"
+ "#define ccc (5)",
+ Style));
+
+ EXPECT_EQ("#define a 3\n"
+ "// comments should break alignment\n"
+ "//\n"
+ "#define bbbb 4\n"
+ "#define ccc (5)",
+ format("#define a 3\n"
+ "// comments should break alignment\n"
+ "//\n"
+ "#define bbbb 4\n"
+ "#define ccc (5)",
+ Style));
+
+ // Test across empty lines and comments
+ Style.AlignConsecutiveMacros = FormatStyle::ACS_AcrossEmptyLinesAndComments;
+ verifyFormat("#define a 3\n"
+ "\n"
+ "// line comment\n"
+ "#define bbbb 4\n"
+ "#define ccc (5)",
+ Style);
+
+ EXPECT_EQ("#define a 3\n"
+ "\n"
+ "\n"
+ "/* multi-line *\n"
+ " * block comment */\n"
+ "\n"
+ "\n"
+ "#define bbbb 4\n"
+ "#define ccc (5)",
+ format("#define a 3\n"
+ "\n"
+ "\n"
+ "/* multi-line *\n"
+ " * block comment */\n"
+ "\n"
+ "\n"
+ "#define bbbb 4\n"
+ "#define ccc (5)",
+ Style));
+
+ EXPECT_EQ("#define a 3\n"
+ "\n"
+ "\n"
+ "/* multi-line *\n"
+ " * block comment */\n"
+ "\n"
+ "\n"
+ "#define bbbb 4\n"
+ "#define ccc (5)",
+ format("#define a 3\n"
+ "\n"
+ "\n"
+ "/* multi-line *\n"
+ " * block comment */\n"
+ "\n"
+ "\n"
+ "#define bbbb 4\n"
+ "#define ccc (5)",
+ Style));
+}
+
+TEST_F(FormatTest, AlignConsecutiveAssignmentsAcrossEmptyLines) {
+ FormatStyle Alignment = getLLVMStyle();
+ Alignment.AlignConsecutiveMacros = FormatStyle::ACS_Consecutive;
+ Alignment.AlignConsecutiveAssignments = FormatStyle::ACS_AcrossEmptyLines;
+
+ Alignment.MaxEmptyLinesToKeep = 10;
+ /* Test alignment across empty lines */
+ EXPECT_EQ("int a = 5;\n"
+ "\n"
+ "int oneTwoThree = 123;",
+ format("int a = 5;\n"
+ "\n"
+ "int oneTwoThree= 123;",
+ Alignment));
+ EXPECT_EQ("int a = 5;\n"
+ "int one = 1;\n"
+ "\n"
+ "int oneTwoThree = 123;",
+ format("int a = 5;\n"
+ "int one = 1;\n"
+ "\n"
+ "int oneTwoThree = 123;",
+ Alignment));
+ EXPECT_EQ("int a = 5;\n"
+ "int one = 1;\n"
+ "\n"
+ "int oneTwoThree = 123;\n"
+ "int oneTwo = 12;",
+ format("int a = 5;\n"
+ "int one = 1;\n"
+ "\n"
+ "int oneTwoThree = 123;\n"
+ "int oneTwo = 12;",
+ Alignment));
+
+ /* Test across comments */
+ EXPECT_EQ("int a = 5;\n"
+ "/* block comment */\n"
+ "int oneTwoThree = 123;",
+ format("int a = 5;\n"
+ "/* block comment */\n"
+ "int oneTwoThree=123;",
+ Alignment));
+
+ EXPECT_EQ("int a = 5;\n"
+ "// line comment\n"
+ "int oneTwoThree = 123;",
+ format("int a = 5;\n"
+ "// line comment\n"
+ "int oneTwoThree=123;",
+ Alignment));
+
+ /* Test across comments and newlines */
+ EXPECT_EQ("int a = 5;\n"
+ "\n"
+ "/* block comment */\n"
+ "int oneTwoThree = 123;",
+ format("int a = 5;\n"
+ "\n"
+ "/* block comment */\n"
+ "int oneTwoThree=123;",
+ Alignment));
+
+ EXPECT_EQ("int a = 5;\n"
+ "\n"
+ "// line comment\n"
+ "int oneTwoThree = 123;",
+ format("int a = 5;\n"
+ "\n"
+ "// line comment\n"
+ "int oneTwoThree=123;",
+ Alignment));
+}
+
+TEST_F(FormatTest, AlignConsecutiveDeclarationsAcrossEmptyLinesAndComments) {
+ FormatStyle Alignment = getLLVMStyle();
+ Alignment.AlignConsecutiveDeclarations =
+ FormatStyle::ACS_AcrossEmptyLinesAndComments;
+ Alignment.AlignConsecutiveAssignments = FormatStyle::ACS_None;
+
+ Alignment.MaxEmptyLinesToKeep = 10;
+ /* Test alignment across empty lines */
+ EXPECT_EQ("int a = 5;\n"
+ "\n"
+ "float const oneTwoThree = 123;",
+ format("int a = 5;\n"
+ "\n"
+ "float const oneTwoThree = 123;",
+ Alignment));
+ EXPECT_EQ("int a = 5;\n"
+ "float const one = 1;\n"
+ "\n"
+ "int oneTwoThree = 123;",
+ format("int a = 5;\n"
+ "float const one = 1;\n"
+ "\n"
+ "int oneTwoThree = 123;",
+ Alignment));
+
+ /* Test across comments */
+ EXPECT_EQ("float const a = 5;\n"
+ "/* block comment */\n"
+ "int oneTwoThree = 123;",
+ format("float const a = 5;\n"
+ "/* block comment */\n"
+ "int oneTwoThree=123;",
+ Alignment));
+
+ EXPECT_EQ("float const a = 5;\n"
+ "// line comment\n"
+ "int oneTwoThree = 123;",
+ format("float const a = 5;\n"
+ "// line comment\n"
+ "int oneTwoThree=123;",
+ Alignment));
+
+ /* Test across comments and newlines */
+ EXPECT_EQ("float const a = 5;\n"
+ "\n"
+ "/* block comment */\n"
+ "int oneTwoThree = 123;",
+ format("float const a = 5;\n"
+ "\n"
+ "/* block comment */\n"
+ "int oneTwoThree=123;",
+ Alignment));
+
+ EXPECT_EQ("float const a = 5;\n"
+ "\n"
+ "// line comment\n"
+ "int oneTwoThree = 123;",
+ format("float const a = 5;\n"
+ "\n"
+ "// line comment\n"
+ "int oneTwoThree=123;",
+ Alignment));
+}
+
+TEST_F(FormatTest, AlignConsecutiveBitFieldsAcrossEmptyLinesAndComments) {
+ FormatStyle Alignment = getLLVMStyle();
+ Alignment.AlignConsecutiveBitFields =
+ FormatStyle::ACS_AcrossEmptyLinesAndComments;
+
+ Alignment.MaxEmptyLinesToKeep = 10;
+ /* Test alignment across empty lines */
+ EXPECT_EQ("int a : 5;\n"
+ "\n"
+ "int longbitfield : 6;",
+ format("int a : 5;\n"
+ "\n"
+ "int longbitfield : 6;",
+ Alignment));
+ EXPECT_EQ("int a : 5;\n"
+ "int one : 1;\n"
+ "\n"
+ "int longbitfield : 6;",
+ format("int a : 5;\n"
+ "int one : 1;\n"
+ "\n"
+ "int longbitfield : 6;",
+ Alignment));
+
+ /* Test across comments */
+ EXPECT_EQ("int a : 5;\n"
+ "/* block comment */\n"
+ "int longbitfield : 6;",
+ format("int a : 5;\n"
+ "/* block comment */\n"
+ "int longbitfield : 6;",
+ Alignment));
+ EXPECT_EQ("int a : 5;\n"
+ "int one : 1;\n"
+ "// line comment\n"
+ "int longbitfield : 6;",
+ format("int a : 5;\n"
+ "int one : 1;\n"
+ "// line comment\n"
+ "int longbitfield : 6;",
+ Alignment));
+
+ /* Test across comments and newlines */
+ EXPECT_EQ("int a : 5;\n"
+ "/* block comment */\n"
+ "\n"
+ "int longbitfield : 6;",
+ format("int a : 5;\n"
+ "/* block comment */\n"
+ "\n"
+ "int longbitfield : 6;",
+ Alignment));
+ EXPECT_EQ("int a : 5;\n"
+ "int one : 1;\n"
+ "\n"
+ "// line comment\n"
+ "\n"
+ "int longbitfield : 6;",
+ format("int a : 5;\n"
+ "int one : 1;\n"
+ "\n"
+ "// line comment \n"
+ "\n"
+ "int longbitfield : 6;",
+ Alignment));
+}
+
+TEST_F(FormatTest, AlignConsecutiveAssignmentsAcrossComments) {
+ FormatStyle Alignment = getLLVMStyle();
+ Alignment.AlignConsecutiveMacros = FormatStyle::ACS_Consecutive;
+ Alignment.AlignConsecutiveAssignments = FormatStyle::ACS_AcrossComments;
+
+ Alignment.MaxEmptyLinesToKeep = 10;
+ /* Test alignment across empty lines */
+ EXPECT_EQ("int a = 5;\n"
+ "\n"
+ "int oneTwoThree = 123;",
+ format("int a = 5;\n"
+ "\n"
+ "int oneTwoThree= 123;",
+ Alignment));
+ EXPECT_EQ("int a = 5;\n"
+ "int one = 1;\n"
+ "\n"
+ "int oneTwoThree = 123;",
+ format("int a = 5;\n"
+ "int one = 1;\n"
+ "\n"
+ "int oneTwoThree = 123;",
+ Alignment));
+
+ /* Test across comments */
+ EXPECT_EQ("int a = 5;\n"
+ "/* block comment */\n"
+ "int oneTwoThree = 123;",
+ format("int a = 5;\n"
+ "/* block comment */\n"
+ "int oneTwoThree=123;",
+ Alignment));
+
+ EXPECT_EQ("int a = 5;\n"
+ "// line comment\n"
+ "int oneTwoThree = 123;",
+ format("int a = 5;\n"
+ "// line comment\n"
+ "int oneTwoThree=123;",
+ Alignment));
+
+ EXPECT_EQ("int a = 5;\n"
+ "/*\n"
+ " * multi-line block comment\n"
+ " */\n"
+ "int oneTwoThree = 123;",
+ format("int a = 5;\n"
+ "/*\n"
+ " * multi-line block comment\n"
+ " */\n"
+ "int oneTwoThree=123;",
+ Alignment));
+
+ EXPECT_EQ("int a = 5;\n"
+ "//\n"
+ "// multi-line line comment\n"
+ "//\n"
+ "int oneTwoThree = 123;",
+ format("int a = 5;\n"
+ "//\n"
+ "// multi-line line comment\n"
+ "//\n"
+ "int oneTwoThree=123;",
+ Alignment));
+
+ /* Test across comments and newlines */
+ EXPECT_EQ("int a = 5;\n"
+ "\n"
+ "/* block comment */\n"
+ "int oneTwoThree = 123;",
+ format("int a = 5;\n"
+ "\n"
+ "/* block comment */\n"
+ "int oneTwoThree=123;",
+ Alignment));
+
+ EXPECT_EQ("int a = 5;\n"
+ "\n"
+ "// line comment\n"
+ "int oneTwoThree = 123;",
+ format("int a = 5;\n"
+ "\n"
+ "// line comment\n"
+ "int oneTwoThree=123;",
+ Alignment));
+}
+
+TEST_F(FormatTest, AlignConsecutiveAssignmentsAcrossEmptyLinesAndComments) {
+ FormatStyle Alignment = getLLVMStyle();
+ Alignment.AlignConsecutiveMacros = FormatStyle::ACS_Consecutive;
+ Alignment.AlignConsecutiveAssignments =
+ FormatStyle::ACS_AcrossEmptyLinesAndComments;
+ verifyFormat("int a = 5;\n"
+ "int oneTwoThree = 123;",
+ Alignment);
+ verifyFormat("int a = method();\n"
+ "int oneTwoThree = 133;",
+ Alignment);
+ verifyFormat("a &= 5;\n"
+ "bcd *= 5;\n"
+ "ghtyf += 5;\n"
+ "dvfvdb -= 5;\n"
+ "a /= 5;\n"
+ "vdsvsv %= 5;\n"
+ "sfdbddfbdfbb ^= 5;\n"
+ "dvsdsv |= 5;\n"
+ "int dsvvdvsdvvv = 123;",
+ Alignment);
+ verifyFormat("int i = 1, j = 10;\n"
+ "something = 2000;",
+ Alignment);
+ verifyFormat("something = 2000;\n"
+ "int i = 1, j = 10;\n",
+ Alignment);
+ verifyFormat("something = 2000;\n"
+ "another = 911;\n"
+ "int i = 1, j = 10;\n"
+ "oneMore = 1;\n"
+ "i = 2;",
+ Alignment);
+ verifyFormat("int a = 5;\n"
+ "int one = 1;\n"
+ "method();\n"
+ "int oneTwoThree = 123;\n"
+ "int oneTwo = 12;",
+ Alignment);
+ verifyFormat("int oneTwoThree = 123;\n"
+ "int oneTwo = 12;\n"
+ "method();\n",
+ Alignment);
+ verifyFormat("int oneTwoThree = 123; // comment\n"
+ "int oneTwo = 12; // comment",
+ Alignment);
+
+ // Bug 25167
+ /* Uncomment when fixed
+ verifyFormat("#if A\n"
+ "#else\n"
+ "int aaaaaaaa = 12;\n"
+ "#endif\n"
+ "#if B\n"
+ "#else\n"
+ "int a = 12;\n"
+ "#endif\n",
+ Alignment);
+ verifyFormat("enum foo {\n"
+ "#if A\n"
+ "#else\n"
+ " aaaaaaaa = 12;\n"
+ "#endif\n"
+ "#if B\n"
+ "#else\n"
+ " a = 12;\n"
+ "#endif\n"
+ "};\n",
+ Alignment);
+ */
+
+ Alignment.MaxEmptyLinesToKeep = 10;
+ /* Test alignment across empty lines */
+ EXPECT_EQ("int a = 5;\n"
+ "\n"
+ "int oneTwoThree = 123;",
+ format("int a = 5;\n"
+ "\n"
+ "int oneTwoThree= 123;",
+ Alignment));
+ EXPECT_EQ("int a = 5;\n"
+ "int one = 1;\n"
+ "\n"
+ "int oneTwoThree = 123;",
+ format("int a = 5;\n"
+ "int one = 1;\n"
+ "\n"
+ "int oneTwoThree = 123;",
+ Alignment));
+ EXPECT_EQ("int a = 5;\n"
+ "int one = 1;\n"
+ "\n"
+ "int oneTwoThree = 123;\n"
+ "int oneTwo = 12;",
+ format("int a = 5;\n"
+ "int one = 1;\n"
+ "\n"
+ "int oneTwoThree = 123;\n"
+ "int oneTwo = 12;",
+ Alignment));
+
+ /* Test across comments */
+ EXPECT_EQ("int a = 5;\n"
+ "/* block comment */\n"
+ "int oneTwoThree = 123;",
+ format("int a = 5;\n"
+ "/* block comment */\n"
+ "int oneTwoThree=123;",
+ Alignment));
+
+ EXPECT_EQ("int a = 5;\n"
+ "// line comment\n"
+ "int oneTwoThree = 123;",
+ format("int a = 5;\n"
+ "// line comment\n"
+ "int oneTwoThree=123;",
+ Alignment));
+
+ /* Test across comments and newlines */
+ EXPECT_EQ("int a = 5;\n"
+ "\n"
+ "/* block comment */\n"
+ "int oneTwoThree = 123;",
+ format("int a = 5;\n"
+ "\n"
+ "/* block comment */\n"
+ "int oneTwoThree=123;",
+ Alignment));
+
+ EXPECT_EQ("int a = 5;\n"
+ "\n"
+ "// line comment\n"
+ "int oneTwoThree = 123;",
+ format("int a = 5;\n"
+ "\n"
+ "// line comment\n"
+ "int oneTwoThree=123;",
+ Alignment));
+
+ EXPECT_EQ("int a = 5;\n"
+ "//\n"
+ "// multi-line line comment\n"
+ "//\n"
+ "int oneTwoThree = 123;",
+ format("int a = 5;\n"
+ "//\n"
+ "// multi-line line comment\n"
+ "//\n"
+ "int oneTwoThree=123;",
+ Alignment));
+
+ EXPECT_EQ("int a = 5;\n"
+ "/*\n"
+ " * multi-line block comment\n"
+ " */\n"
+ "int oneTwoThree = 123;",
+ format("int a = 5;\n"
+ "/*\n"
+ " * multi-line block comment\n"
+ " */\n"
+ "int oneTwoThree=123;",
+ Alignment));
+
+ EXPECT_EQ("int a = 5;\n"
+ "\n"
+ "/* block comment */\n"
+ "\n"
+ "\n"
+ "\n"
+ "int oneTwoThree = 123;",
+ format("int a = 5;\n"
+ "\n"
+ "/* block comment */\n"
+ "\n"
+ "\n"
+ "\n"
+ "int oneTwoThree=123;",
+ Alignment));
+
+ EXPECT_EQ("int a = 5;\n"
+ "\n"
+ "// line comment\n"
+ "\n"
+ "\n"
+ "\n"
+ "int oneTwoThree = 123;",
+ format("int a = 5;\n"
+ "\n"
+ "// line comment\n"
+ "\n"
+ "\n"
+ "\n"
+ "int oneTwoThree=123;",
+ Alignment));
+
+ Alignment.AlignEscapedNewlines = FormatStyle::ENAS_DontAlign;
+ verifyFormat("#define A \\\n"
+ " int aaaa = 12; \\\n"
+ " int b = 23; \\\n"
+ " int ccc = 234; \\\n"
+ " int dddddddddd = 2345;",
+ Alignment);
+ Alignment.AlignEscapedNewlines = FormatStyle::ENAS_Left;
+ verifyFormat("#define A \\\n"
+ " int aaaa = 12; \\\n"
+ " int b = 23; \\\n"
+ " int ccc = 234; \\\n"
+ " int dddddddddd = 2345;",
+ Alignment);
+ Alignment.AlignEscapedNewlines = FormatStyle::ENAS_Right;
+ verifyFormat("#define A "
+ " \\\n"
+ " int aaaa = 12; "
+ " \\\n"
+ " int b = 23; "
+ " \\\n"
+ " int ccc = 234; "
+ " \\\n"
+ " int dddddddddd = 2345;",
+ Alignment);
+ verifyFormat("void SomeFunction(int parameter = 1, int i = 2, int j = 3, int "
+ "k = 4, int l = 5,\n"
+ " int m = 6) {\n"
+ " int j = 10;\n"
+ " otherThing = 1;\n"
+ "}",
+ Alignment);
+ verifyFormat("void SomeFunction(int parameter = 0) {\n"
+ " int i = 1;\n"
+ " int j = 2;\n"
+ " int big = 10000;\n"
+ "}",
+ Alignment);
+ verifyFormat("class C {\n"
+ "public:\n"
+ " int i = 1;\n"
+ " virtual void f() = 0;\n"
+ "};",
+ Alignment);
+ verifyFormat("int i = 1;\n"
+ "if (SomeType t = getSomething()) {\n"
+ "}\n"
+ "int j = 2;\n"
+ "int big = 10000;",
+ Alignment);
+ verifyFormat("int j = 7;\n"
+ "for (int k = 0; k < N; ++k) {\n"
+ "}\n"
+ "int j = 2;\n"
+ "int big = 10000;\n"
+ "}",
+ Alignment);
+ Alignment.BreakBeforeBinaryOperators = FormatStyle::BOS_All;
+ verifyFormat("int i = 1;\n"
+ "LooooooooooongType loooooooooooooooooooooongVariable\n"
+ " = someLooooooooooooooooongFunction();\n"
+ "int j = 2;",
+ Alignment);
+ Alignment.BreakBeforeBinaryOperators = FormatStyle::BOS_None;
+ verifyFormat("int i = 1;\n"
+ "LooooooooooongType loooooooooooooooooooooongVariable =\n"
+ " someLooooooooooooooooongFunction();\n"
+ "int j = 2;",
+ Alignment);
+
+ verifyFormat("auto lambda = []() {\n"
+ " auto i = 0;\n"
+ " return 0;\n"
+ "};\n"
+ "int i = 0;\n"
+ "auto v = type{\n"
+ " i = 1, //\n"
+ " (i = 2), //\n"
+ " i = 3 //\n"
+ "};",
+ Alignment);
+
+ verifyFormat(
+ "int i = 1;\n"
+ "SomeType a = SomeFunction(looooooooooooooooooooooongParameterA,\n"
+ " loooooooooooooooooooooongParameterB);\n"
+ "int j = 2;",
+ Alignment);
+
+ verifyFormat("template <typename T, typename T_0 = very_long_type_name_0,\n"
+ " typename B = very_long_type_name_1,\n"
+ " typename T_2 = very_long_type_name_2>\n"
+ "auto foo() {}\n",
+ Alignment);
+ verifyFormat("int a, b = 1;\n"
+ "int c = 2;\n"
+ "int dd = 3;\n",
+ Alignment);
+ verifyFormat("int aa = ((1 > 2) ? 3 : 4);\n"
+ "float b[1][] = {{3.f}};\n",
+ Alignment);
+ verifyFormat("for (int i = 0; i < 1; i++)\n"
+ " int x = 1;\n",
+ Alignment);
+ verifyFormat("for (i = 0; i < 1; i++)\n"
+ " x = 1;\n"
+ "y = 1;\n",
+ Alignment);
+
+ Alignment.ReflowComments = true;
+ Alignment.ColumnLimit = 50;
+ EXPECT_EQ("int x = 0;\n"
+ "int yy = 1; /// specificlennospace\n"
+ "int zzz = 2;\n",
+ format("int x = 0;\n"
+ "int yy = 1; ///specificlennospace\n"
+ "int zzz = 2;\n",
+ Alignment));
}
TEST_F(FormatTest, AlignConsecutiveAssignments) {
FormatStyle Alignment = getLLVMStyle();
- Alignment.AlignConsecutiveMacros = true;
- Alignment.AlignConsecutiveAssignments = false;
+ Alignment.AlignConsecutiveMacros = FormatStyle::ACS_Consecutive;
+ Alignment.AlignConsecutiveAssignments = FormatStyle::ACS_None;
verifyFormat("int a = 5;\n"
"int oneTwoThree = 123;",
Alignment);
@@ -12574,7 +13328,7 @@
"int oneTwoThree = 123;",
Alignment);
- Alignment.AlignConsecutiveAssignments = true;
+ Alignment.AlignConsecutiveAssignments = FormatStyle::ACS_Consecutive;
verifyFormat("int a = 5;\n"
"int oneTwoThree = 123;",
Alignment);
@@ -12790,7 +13544,7 @@
TEST_F(FormatTest, AlignConsecutiveBitFields) {
FormatStyle Alignment = getLLVMStyle();
- Alignment.AlignConsecutiveBitFields = true;
+ Alignment.AlignConsecutiveBitFields = FormatStyle::ACS_Consecutive;
verifyFormat("int const a : 5;\n"
"int oneTwoThree : 23;",
Alignment);
@@ -12800,7 +13554,7 @@
"int oneTwoThree : 23 = 0;",
Alignment);
- Alignment.AlignConsecutiveDeclarations = true;
+ Alignment.AlignConsecutiveDeclarations = FormatStyle::ACS_Consecutive;
verifyFormat("int const a : 5;\n"
"int oneTwoThree : 23;",
Alignment);
@@ -12813,7 +13567,7 @@
"int oneTwoThree : 23 = 0;",
Alignment);
- Alignment.AlignConsecutiveAssignments = true;
+ Alignment.AlignConsecutiveAssignments = FormatStyle::ACS_Consecutive;
verifyFormat("int const a : 5 = 1;\n"
"int oneTwoThree : 23 = 0;",
Alignment);
@@ -12847,8 +13601,8 @@
TEST_F(FormatTest, AlignConsecutiveDeclarations) {
FormatStyle Alignment = getLLVMStyle();
- Alignment.AlignConsecutiveMacros = true;
- Alignment.AlignConsecutiveDeclarations = false;
+ Alignment.AlignConsecutiveMacros = FormatStyle::ACS_Consecutive;
+ Alignment.AlignConsecutiveDeclarations = FormatStyle::ACS_None;
verifyFormat("float const a = 5;\n"
"int oneTwoThree = 123;",
Alignment);
@@ -12856,7 +13610,7 @@
"float const oneTwoThree = 123;",
Alignment);
- Alignment.AlignConsecutiveDeclarations = true;
+ Alignment.AlignConsecutiveDeclarations = FormatStyle::ACS_Consecutive;
verifyFormat("float const a = 5;\n"
"int oneTwoThree = 123;",
Alignment);
@@ -12953,7 +13707,7 @@
verifyFormat("int a(int x, void (*fp)(int y));\n"
"double b();",
Alignment);
- Alignment.AlignConsecutiveAssignments = true;
+ Alignment.AlignConsecutiveAssignments = FormatStyle::ACS_Consecutive;
// Ensure recursive alignment is broken by function braces, so that the
// "a = 1" does not align with subsequent assignments inside the function
// body.
@@ -13016,7 +13770,7 @@
"int ll=10000;\n"
"}",
Alignment));
- Alignment.AlignConsecutiveAssignments = false;
+ Alignment.AlignConsecutiveAssignments = FormatStyle::ACS_None;
Alignment.AlignEscapedNewlines = FormatStyle::ENAS_DontAlign;
verifyFormat("#define A \\\n"
" int aaaa = 12; \\\n"
@@ -13085,7 +13839,7 @@
"int j = 2;",
Alignment);
- Alignment.AlignConsecutiveAssignments = true;
+ Alignment.AlignConsecutiveAssignments = FormatStyle::ACS_Consecutive;
verifyFormat("auto lambda = []() {\n"
" auto ii = 0;\n"
" float j = 0;\n"
@@ -13099,7 +13853,7 @@
" i = 3 //\n"
"};",
Alignment);
- Alignment.AlignConsecutiveAssignments = false;
+ Alignment.AlignConsecutiveAssignments = FormatStyle::ACS_None;
verifyFormat(
"int i = 1;\n"
@@ -13112,7 +13866,7 @@
// We expect declarations and assignments to align, as long as it doesn't
// exceed the column limit, starting a new alignment sequence whenever it
// happens.
- Alignment.AlignConsecutiveAssignments = true;
+ Alignment.AlignConsecutiveAssignments = FormatStyle::ACS_Consecutive;
Alignment.ColumnLimit = 30;
verifyFormat("float ii = 1;\n"
"unsigned j = 2;\n"
@@ -13122,7 +13876,7 @@
"int myvar = 1;",
Alignment);
Alignment.ColumnLimit = 80;
- Alignment.AlignConsecutiveAssignments = false;
+ Alignment.AlignConsecutiveAssignments = FormatStyle::ACS_None;
verifyFormat(
"template <typename LongTemplate, typename VeryLongTemplateTypeName,\n"
@@ -13136,7 +13890,7 @@
verifyFormat("int aa = ((1 > 2) ? 3 : 4);\n"
"float b[1][] = {{3.f}};\n",
Alignment);
- Alignment.AlignConsecutiveAssignments = true;
+ Alignment.AlignConsecutiveAssignments = FormatStyle::ACS_Consecutive;
verifyFormat("float a, b = 1;\n"
"int c = 2;\n"
"int dd = 3;\n",
@@ -13144,7 +13898,7 @@
verifyFormat("int aa = ((1 > 2) ? 3 : 4);\n"
"float b[1][] = {{3.f}};\n",
Alignment);
- Alignment.AlignConsecutiveAssignments = false;
+ Alignment.AlignConsecutiveAssignments = FormatStyle::ACS_None;
Alignment.ColumnLimit = 30;
Alignment.BinPackParameters = false;
@@ -13175,7 +13929,7 @@
Alignment.PointerAlignment = FormatStyle::PAS_Right;
// See llvm.org/PR35641
- Alignment.AlignConsecutiveDeclarations = true;
+ Alignment.AlignConsecutiveDeclarations = FormatStyle::ACS_Consecutive;
verifyFormat("int func() { //\n"
" int b;\n"
" unsigned c;\n"
@@ -13184,7 +13938,7 @@
// See PR37175
FormatStyle Style = getMozillaStyle();
- Style.AlignConsecutiveDeclarations = true;
+ Style.AlignConsecutiveDeclarations = FormatStyle::ACS_Consecutive;
EXPECT_EQ("DECOR1 /**/ int8_t /**/ DECOR2 /**/\n"
"foo(int a);",
format("DECOR1 /**/ int8_t /**/ DECOR2 /**/ foo (int a);", Style));
@@ -14374,10 +15128,6 @@
FormatStyle Style = {};
Style.Language = FormatStyle::LK_Cpp;
CHECK_PARSE_BOOL(AlignTrailingComments);
- CHECK_PARSE_BOOL(AlignConsecutiveAssignments);
- CHECK_PARSE_BOOL(AlignConsecutiveBitFields);
- CHECK_PARSE_BOOL(AlignConsecutiveDeclarations);
- CHECK_PARSE_BOOL(AlignConsecutiveMacros);
CHECK_PARSE_BOOL(AllowAllArgumentsOnNextLine);
CHECK_PARSE_BOOL(AllowAllConstructorInitializersOnNextLine);
CHECK_PARSE_BOOL(AllowAllParametersOfDeclarationOnNextLine);
@@ -14472,6 +15222,70 @@
CHECK_PARSE("ContinuationIndentWidth: 11", ContinuationIndentWidth, 11u);
CHECK_PARSE("CommentPragmas: '// abc$'", CommentPragmas, "// abc$");
+ Style.AlignConsecutiveAssignments = FormatStyle::ACS_Consecutive;
+ CHECK_PARSE("AlignConsecutiveAssignments: None", AlignConsecutiveAssignments,
+ FormatStyle::ACS_None);
+ CHECK_PARSE("AlignConsecutiveAssignments: Consecutive",
+ AlignConsecutiveAssignments, FormatStyle::ACS_Consecutive);
+ CHECK_PARSE("AlignConsecutiveAssignments: AcrossEmptyLines",
+ AlignConsecutiveAssignments, FormatStyle::ACS_AcrossEmptyLines);
+ CHECK_PARSE("AlignConsecutiveAssignments: AcrossEmptyLinesAndComments",
+ AlignConsecutiveAssignments,
+ FormatStyle::ACS_AcrossEmptyLinesAndComments);
+ // For backwards compability, false / true should still parse
+ CHECK_PARSE("AlignConsecutiveAssignments: false", AlignConsecutiveAssignments,
+ FormatStyle::ACS_None);
+ CHECK_PARSE("AlignConsecutiveAssignments: true", AlignConsecutiveAssignments,
+ FormatStyle::ACS_Consecutive);
+
+ Style.AlignConsecutiveBitFields = FormatStyle::ACS_Consecutive;
+ CHECK_PARSE("AlignConsecutiveBitFields: None", AlignConsecutiveBitFields,
+ FormatStyle::ACS_None);
+ CHECK_PARSE("AlignConsecutiveBitFields: Consecutive",
+ AlignConsecutiveBitFields, FormatStyle::ACS_Consecutive);
+ CHECK_PARSE("AlignConsecutiveBitFields: AcrossEmptyLines",
+ AlignConsecutiveBitFields, FormatStyle::ACS_AcrossEmptyLines);
+ CHECK_PARSE("AlignConsecutiveBitFields: AcrossEmptyLinesAndComments",
+ AlignConsecutiveBitFields,
+ FormatStyle::ACS_AcrossEmptyLinesAndComments);
+ // For backwards compability, false / true should still parse
+ CHECK_PARSE("AlignConsecutiveBitFields: false", AlignConsecutiveBitFields,
+ FormatStyle::ACS_None);
+ CHECK_PARSE("AlignConsecutiveBitFields: true", AlignConsecutiveBitFields,
+ FormatStyle::ACS_Consecutive);
+
+ Style.AlignConsecutiveMacros = FormatStyle::ACS_Consecutive;
+ CHECK_PARSE("AlignConsecutiveMacros: None", AlignConsecutiveMacros,
+ FormatStyle::ACS_None);
+ CHECK_PARSE("AlignConsecutiveMacros: Consecutive", AlignConsecutiveMacros,
+ FormatStyle::ACS_Consecutive);
+ CHECK_PARSE("AlignConsecutiveMacros: AcrossEmptyLines",
+ AlignConsecutiveMacros, FormatStyle::ACS_AcrossEmptyLines);
+ CHECK_PARSE("AlignConsecutiveMacros: AcrossEmptyLinesAndComments",
+ AlignConsecutiveMacros,
+ FormatStyle::ACS_AcrossEmptyLinesAndComments);
+ // For backwards compability, false / true should still parse
+ CHECK_PARSE("AlignConsecutiveMacros: false", AlignConsecutiveMacros,
+ FormatStyle::ACS_None);
+ CHECK_PARSE("AlignConsecutiveMacros: true", AlignConsecutiveMacros,
+ FormatStyle::ACS_Consecutive);
+
+ Style.AlignConsecutiveDeclarations = FormatStyle::ACS_Consecutive;
+ CHECK_PARSE("AlignConsecutiveDeclarations: None",
+ AlignConsecutiveDeclarations, FormatStyle::ACS_None);
+ CHECK_PARSE("AlignConsecutiveDeclarations: Consecutive",
+ AlignConsecutiveDeclarations, FormatStyle::ACS_Consecutive);
+ CHECK_PARSE("AlignConsecutiveDeclarations: AcrossEmptyLines",
+ AlignConsecutiveDeclarations, FormatStyle::ACS_AcrossEmptyLines);
+ CHECK_PARSE("AlignConsecutiveDeclarations: AcrossEmptyLinesAndComments",
+ AlignConsecutiveDeclarations,
+ FormatStyle::ACS_AcrossEmptyLinesAndComments);
+ // For backwards compability, false / true should still parse
+ CHECK_PARSE("AlignConsecutiveDeclarations: false",
+ AlignConsecutiveDeclarations, FormatStyle::ACS_None);
+ CHECK_PARSE("AlignConsecutiveDeclarations: true",
+ AlignConsecutiveDeclarations, FormatStyle::ACS_Consecutive);
+
Style.PointerAlignment = FormatStyle::PAS_Middle;
CHECK_PARSE("PointerAlignment: Left", PointerAlignment,
FormatStyle::PAS_Left);
@@ -17400,7 +18214,7 @@
format("FOO(String-ized&Messy+But,: :\n"
" Still=Intentional);",
Style));
- Style.AlignConsecutiveAssignments = true;
+ Style.AlignConsecutiveAssignments = FormatStyle::ACS_Consecutive;
EXPECT_EQ("FOO(String-ized=&Messy+But,: :\n"
" Still=Intentional);",
format("FOO(String-ized=&Messy+But,: :\n"
@@ -17871,7 +18685,7 @@
EXPECT_EQ(Source, format(Source, Style));
- Style.AlignConsecutiveDeclarations = true;
+ Style.AlignConsecutiveDeclarations = FormatStyle::ACS_Consecutive;
EXPECT_EQ("void Foo::slot() {\n"
" unsigned char MyChar = 'x';\n"
" emit signal(MyChar);\n"
Index: clang/lib/Format/WhitespaceManager.cpp
===================================================================
--- clang/lib/Format/WhitespaceManager.cpp
+++ clang/lib/Format/WhitespaceManager.cpp
@@ -361,9 +361,10 @@
// that are split across multiple lines. See the test case in FormatTest.cpp
// that mentions "split function parameter alignment" for an example of this.
template <typename F>
-static unsigned AlignTokens(const FormatStyle &Style, F &&Matches,
- SmallVector<WhitespaceManager::Change, 16> &Changes,
- unsigned StartAt) {
+static unsigned AlignTokens(
+ const FormatStyle &Style, F &&Matches,
+ SmallVector<WhitespaceManager::Change, 16> &Changes, unsigned StartAt,
+ const FormatStyle::AlignConsecutiveStyle &ACS = FormatStyle::ACS_None) {
unsigned MinColumn = 0;
unsigned MaxColumn = UINT_MAX;
@@ -386,6 +387,9 @@
// Whether a matching token has been found on the current line.
bool FoundMatchOnLine = false;
+ // Whether the current line consists purely of comments.
+ bool LineIsComment = true;
+
// Aligns a sequence of matching tokens, on the MinColumn column.
//
// Sequences start from the first matching token to align, and end at the
@@ -411,19 +415,38 @@
if (Changes[i].NewlinesBefore != 0) {
CommasBeforeMatch = 0;
EndOfSequence = i;
- // If there is a blank line, or if the last line didn't contain any
- // matching token, the sequence ends here.
- if (Changes[i].NewlinesBefore > 1 || !FoundMatchOnLine)
+
+ // Whether to break the alignment sequence because of an empty line.
+ bool EmptyLineBreak =
+ (Changes[i].NewlinesBefore > 1) &&
+ (ACS != FormatStyle::ACS_AcrossEmptyLines) &&
+ (ACS != FormatStyle::ACS_AcrossEmptyLinesAndComments);
+
+ // Whether to break the alignment sequence because of a line without a
+ // match.
+ bool NoMatchBreak =
+ !FoundMatchOnLine &&
+ !(LineIsComment &&
+ ((ACS == FormatStyle::ACS_AcrossComments) ||
+ (ACS == FormatStyle::ACS_AcrossEmptyLinesAndComments)));
+
+ if (EmptyLineBreak || NoMatchBreak)
AlignCurrentSequence();
+ // A new line starts, re-initialize line status tracking bools.
FoundMatchOnLine = false;
+ LineIsComment = true;
+ }
+
+ if (!Changes[i].Tok->is(tok::comment)) {
+ LineIsComment = false;
}
if (Changes[i].Tok->is(tok::comma)) {
++CommasBeforeMatch;
} else if (Changes[i].indentAndNestingLevel() > IndentAndNestingLevel) {
// Call AlignTokens recursively, skipping over this scope block.
- unsigned StoppedAt = AlignTokens(Style, Matches, Changes, i);
+ unsigned StoppedAt = AlignTokens(Style, Matches, Changes, i, ACS);
i = StoppedAt - 1;
continue;
}
@@ -518,7 +541,7 @@
}
void WhitespaceManager::alignConsecutiveMacros() {
- if (!Style.AlignConsecutiveMacros)
+ if (Style.AlignConsecutiveMacros == FormatStyle::ACS_None)
return;
auto AlignMacrosMatches = [](const Change &C) {
@@ -560,17 +583,41 @@
// Whether a matching token has been found on the current line.
bool FoundMatchOnLine = false;
+ // Whether the current line consists only of comments
+ bool LineIsComment = true;
+
unsigned I = 0;
for (unsigned E = Changes.size(); I != E; ++I) {
if (Changes[I].NewlinesBefore != 0) {
EndOfSequence = I;
- // If there is a blank line, or if the last line didn't contain any
- // matching token, the sequence ends here.
- if (Changes[I].NewlinesBefore > 1 || !FoundMatchOnLine)
+
+ // Whether to break the alignment sequence because of an empty line.
+ bool EmptyLineBreak =
+ (Changes[I].NewlinesBefore > 1) &&
+ (Style.AlignConsecutiveMacros != FormatStyle::ACS_AcrossEmptyLines) &&
+ (Style.AlignConsecutiveMacros !=
+ FormatStyle::ACS_AcrossEmptyLinesAndComments);
+
+ // Whether to break the alignment sequence because of a line without a
+ // match.
+ bool NoMatchBreak =
+ !FoundMatchOnLine &&
+ !(LineIsComment && ((Style.AlignConsecutiveMacros ==
+ FormatStyle::ACS_AcrossComments) ||
+ (Style.AlignConsecutiveMacros ==
+ FormatStyle::ACS_AcrossEmptyLinesAndComments)));
+
+ if (EmptyLineBreak || NoMatchBreak)
AlignMacroSequence(StartOfSequence, EndOfSequence, MinColumn, MaxColumn,
FoundMatchOnLine, AlignMacrosMatches, Changes);
+ // A new line starts, re-initialize line status tracking bools.
FoundMatchOnLine = false;
+ LineIsComment = true;
+ }
+
+ if (!Changes[I].Tok->is(tok::comment)) {
+ LineIsComment = false;
}
if (!AlignMacrosMatches(Changes[I]))
@@ -597,7 +644,7 @@
}
void WhitespaceManager::alignConsecutiveAssignments() {
- if (!Style.AlignConsecutiveAssignments)
+ if (Style.AlignConsecutiveAssignments == FormatStyle::ACS_None)
return;
AlignTokens(
@@ -613,11 +660,11 @@
return C.Tok->is(tok::equal);
},
- Changes, /*StartAt=*/0);
+ Changes, /*StartAt=*/0, Style.AlignConsecutiveAssignments);
}
void WhitespaceManager::alignConsecutiveBitFields() {
- if (!Style.AlignConsecutiveBitFields)
+ if (Style.AlignConsecutiveBitFields == FormatStyle::ACS_None)
return;
AlignTokens(
@@ -633,11 +680,11 @@
return C.Tok->is(TT_BitFieldColon);
},
- Changes, /*StartAt=*/0);
+ Changes, /*StartAt=*/0, Style.AlignConsecutiveBitFields);
}
void WhitespaceManager::alignConsecutiveDeclarations() {
- if (!Style.AlignConsecutiveDeclarations)
+ if (Style.AlignConsecutiveDeclarations == FormatStyle::ACS_None)
return;
// FIXME: Currently we don't handle properly the PointerAlignment: Right
@@ -670,7 +717,7 @@
}
return true;
},
- Changes, /*StartAt=*/0);
+ Changes, /*StartAt=*/0, Style.AlignConsecutiveDeclarations);
}
void WhitespaceManager::alignChainedConditionals() {
Index: clang/lib/Format/Format.cpp
===================================================================
--- clang/lib/Format/Format.cpp
+++ clang/lib/Format/Format.cpp
@@ -128,6 +128,21 @@
}
};
+template <> struct ScalarEnumerationTraits<FormatStyle::AlignConsecutiveStyle> {
+ static void enumeration(IO &IO, FormatStyle::AlignConsecutiveStyle &Value) {
+ IO.enumCase(Value, "None", FormatStyle::ACS_None);
+ IO.enumCase(Value, "Consecutive", FormatStyle::ACS_Consecutive);
+ IO.enumCase(Value, "AcrossEmptyLines", FormatStyle::ACS_AcrossEmptyLines);
+ IO.enumCase(Value, "AcrossComments", FormatStyle::ACS_AcrossComments);
+ IO.enumCase(Value, "AcrossEmptyLinesAndComments",
+ FormatStyle::ACS_AcrossEmptyLinesAndComments);
+
+ // For backward compability.
+ IO.enumCase(Value, "true", FormatStyle::ACS_Consecutive);
+ IO.enumCase(Value, "false", FormatStyle::ACS_None);
+ }
+};
+
template <> struct ScalarEnumerationTraits<FormatStyle::ShortIfStyle> {
static void enumeration(IO &IO, FormatStyle::ShortIfStyle &Value) {
IO.enumCase(Value, "Never", FormatStyle::SIS_Never);
@@ -857,10 +872,10 @@
LLVMStyle.AlignAfterOpenBracket = FormatStyle::BAS_Align;
LLVMStyle.AlignOperands = FormatStyle::OAS_Align;
LLVMStyle.AlignTrailingComments = true;
- LLVMStyle.AlignConsecutiveAssignments = false;
- LLVMStyle.AlignConsecutiveBitFields = false;
- LLVMStyle.AlignConsecutiveDeclarations = false;
- LLVMStyle.AlignConsecutiveMacros = false;
+ LLVMStyle.AlignConsecutiveAssignments = FormatStyle::ACS_None;
+ LLVMStyle.AlignConsecutiveBitFields = FormatStyle::ACS_None;
+ LLVMStyle.AlignConsecutiveDeclarations = FormatStyle::ACS_None;
+ LLVMStyle.AlignConsecutiveMacros = FormatStyle::ACS_None;
LLVMStyle.AllowAllArgumentsOnNextLine = true;
LLVMStyle.AllowAllConstructorInitializersOnNextLine = true;
LLVMStyle.AllowAllParametersOfDeclarationOnNextLine = true;
Index: clang/include/clang/Format/Format.h
===================================================================
--- clang/include/clang/Format/Format.h
+++ clang/include/clang/Format/Format.h
@@ -84,10 +84,23 @@
/// brackets.
BracketAlignmentStyle AlignAfterOpenBracket;
- /// \brief If ``true``, aligns consecutive C/C++ preprocessor macros.
+ /// Styles for alignment of consecutive tokens. Tokens can be assignment signs
+ /// (see
+ /// ``AlignConsecutiveAssignments``), bitfield member separators (see
+ /// ``AlignConsecutiveBitFields``), names in declarations (see
+ /// ``AlignConsecutiveDeclarations``) or macro definitions (see
+ /// ``AlignConsecutiveMacros``).
+ enum AlignConsecutiveStyle {
+ ACS_None,
+ ACS_Consecutive,
+ ACS_AcrossEmptyLines,
+ ACS_AcrossComments,
+ ACS_AcrossEmptyLinesAndComments
+ };
+
+ /// Style of aligning consecutive macro definitions.
///
- /// This will align C/C++ preprocessor macros of consecutive lines.
- /// Will result in formattings like
+ /// ``Consecutive`` will result in formattings like:
/// \code
/// #define SHORT_NAME 42
/// #define LONGER_NAME 0x007f
@@ -95,40 +108,271 @@
/// #define foo(x) (x * x)
/// #define bar(y, z) (y + z)
/// \endcode
- bool AlignConsecutiveMacros;
-
- /// If ``true``, aligns consecutive assignments.
///
- /// This will align the assignment operators of consecutive lines. This
- /// will result in formattings like
- /// \code
- /// int aaaa = 12;
- /// int b = 23;
- /// int ccc = 23;
- /// \endcode
- bool AlignConsecutiveAssignments;
-
- /// If ``true``, aligns consecutive bitfield members.
- ///
- /// This will align the bitfield separators of consecutive lines. This
- /// will result in formattings like
+ /// Possible values:
+ ///
+ /// * ``ACS_None`` (in configuration: ``None``)
+ /// Do not align macro definitions on consecutive lines.
+ ///
+ /// * ``ACS_Consecutive`` (in configuration: ``Consecutive``)
+ /// Align macro definitions on consecutive lines. This will result in
+ /// formattings like:
+ /// \code
+ /// #define SHORT_NAME 42
+ /// #define LONGER_NAME 0x007f
+ /// #define EVEN_LONGER_NAME (2)
+ ///
+ /// #define foo(x) (x * x)
+ /// /* some comment */
+ /// #define bar(y, z) (y + z)
+ /// \endcode
+ ///
+ /// * ``ACS_AcrossEmptyLines`` (in configuration: ``AcrossEmptyLines``)
+ /// Same as ACS_Consecutive, but also spans over empty lines, e.g.
+ /// \code
+ /// #define SHORT_NAME 42
+ /// #define LONGER_NAME 0x007f
+ /// #define EVEN_LONGER_NAME (2)
+ ///
+ /// #define foo(x) (x * x)
+ /// /* some comment */
+ /// #define bar(y, z) (y + z)
+ /// \endcode
+ ///
+ /// * ``ACS_AcrossComments`` (in configuration: ``AcrossComments``)
+ /// Same as ACS_Consecutive, but also spans over lines only containing
+ /// comments, e.g.
+ /// \code
+ /// #define SHORT_NAME 42
+ /// #define LONGER_NAME 0x007f
+ /// #define EVEN_LONGER_NAME (2)
+ ///
+ /// #define foo(x) (x * x)
+ /// /* some comment */
+ /// #define bar(y, z) (y + z)
+ /// \endcode
+ ///
+ /// * ``ACS_AcrossEmptyLinesAndComments``
+ /// (in configuration: ``AcrossEmptyLinesAndComments``)
+ ///
+ /// Same as ACS_Consecutive, but also spans over lines only containing
+ /// comments and empty lines, e.g.
+ /// \code
+ /// #define SHORT_NAME 42
+ /// #define LONGER_NAME 0x007f
+ /// #define EVEN_LONGER_NAME (2)
+ ///
+ /// #define foo(x) (x * x)
+ /// /* some comment */
+ /// #define bar(y, z) (y + z)
+ /// \endcode
+ AlignConsecutiveStyle AlignConsecutiveMacros;
+
+ /// Style of aligning consecutive assignments.
+ ///
+ /// ``Consecutive`` will result in formattings like:
+ /// \code
+ /// int a = 1;
+ /// int somelongname = 2;
+ /// double c = 3;
+ /// \endcode
+ ///
+ /// Possible values:
+ ///
+ /// * ``ACS_None`` (in configuration: ``None``)
+ /// Do not align assignments on consecutive lines.
+ ///
+ /// * ``ACS_Consecutive`` (in configuration: ``Consecutive``)
+ /// Align assignments on consecutive lines. This will result in
+ /// formattings like:
+ /// \code
+ /// int a = 1;
+ /// int somelongname = 2;
+ /// double c = 3;
+ ///
+ /// int d = 3;
+ /// /* A comment. */
+ /// double e = 4;
+ /// \endcode
+ ///
+ /// * ``ACS_AcrossEmptyLines`` (in configuration: ``AcrossEmptyLines``)
+ /// Same as ACS_Consecutive, but also spans over empty lines, e.g.
+ /// \code
+ /// int a = 1;
+ /// int somelongname = 2;
+ /// double c = 3;
+ ///
+ /// int d = 3;
+ /// /* A comment. */
+ /// double e = 4;
+ /// \endcode
+ ///
+ /// * ``ACS_AcrossComments`` (in configuration: ``AcrossComments``)
+ /// Same as ACS_Consecutive, but also spans over lines only containing
+ /// comments, e.g.
+ /// \code
+ /// int a = 1;
+ /// int somelongname = 2;
+ /// double c = 3;
+ ///
+ /// int d = 3;
+ /// /* A comment. */
+ /// double e = 4;
+ /// \endcode
+ ///
+ /// * ``ACS_AcrossEmptyLinesAndComments``
+ /// (in configuration: ``AcrossEmptyLinesAndComments``)
+ ///
+ /// Same as ACS_Consecutive, but also spans over lines only containing
+ /// comments and empty lines, e.g.
+ /// \code
+ /// int a = 1;
+ /// int somelongname = 2;
+ /// double c = 3;
+ ///
+ /// int d = 3;
+ /// /* A comment. */
+ /// double e = 4;
+ /// \endcode
+ AlignConsecutiveStyle AlignConsecutiveAssignments;
+
+ /// Style of aligning consecutive bit field.
+ ///
+ /// ``Consecutive`` will align the bitfield separators of consecutive lines.
+ /// This will result in formattings like:
/// \code
/// int aaaa : 1;
/// int b : 12;
/// int ccc : 8;
/// \endcode
- bool AlignConsecutiveBitFields;
-
- /// If ``true``, aligns consecutive declarations.
///
- /// This will align the declaration names of consecutive lines. This
- /// will result in formattings like
+ /// Possible values:
+ ///
+ /// * ``ACS_None`` (in configuration: ``None``)
+ /// Do not align bit fields on consecutive lines.
+ ///
+ /// * ``ACS_Consecutive`` (in configuration: ``Consecutive``)
+ /// Align bit fields on consecutive lines. This will result in
+ /// formattings like:
+ /// \code
+ /// int aaaa : 1;
+ /// int b : 12;
+ /// int ccc : 8;
+ ///
+ /// int d : 2;
+ /// /* A comment. */
+ /// int ee : 3;
+ /// \endcode
+ ///
+ /// * ``ACS_AcrossEmptyLines`` (in configuration: ``AcrossEmptyLines``)
+ /// Same as ACS_Consecutive, but also spans over empty lines, e.g.
+ /// \code
+ /// int aaaa : 1;
+ /// int b : 12;
+ /// int ccc : 8;
+ ///
+ /// int d : 2;
+ /// /* A comment. */
+ /// int ee : 3;
+ /// \endcode
+ ///
+ /// * ``ACS_AcrossComments`` (in configuration: ``AcrossComments``)
+ /// Same as ACS_Consecutive, but also spans over lines only containing
+ /// comments, e.g.
+ /// \code
+ /// int aaaa : 1;
+ /// int b : 12;
+ /// int ccc : 8;
+ ///
+ /// int d : 2;
+ /// /* A comment. */
+ /// int ee : 3;
+ /// \endcode
+ ///
+ /// * ``ACS_AcrossEmptyLinesAndComments``
+ /// (in configuration: ``AcrossEmptyLinesAndComments``)
+ ///
+ /// Same as ACS_Consecutive, but also spans over lines only containing
+ /// comments and empty lines, e.g.
+ /// \code
+ /// int aaaa : 1;
+ /// int b : 12;
+ /// int ccc : 8;
+ ///
+ /// int d : 2;
+ /// /* A comment. */
+ /// int ee : 3;
+ /// \endcode
+ AlignConsecutiveStyle AlignConsecutiveBitFields;
+
+ /// Style of aligning consecutive declarations.
+ ///
+ /// ``Consecutive`` will align the declaration names of consecutive lines.
+ /// This will result in formattings like:
/// \code
/// int aaaa = 12;
/// float b = 23;
- /// std::string ccc = 23;
- /// \endcode
- bool AlignConsecutiveDeclarations;
+ /// std::string ccc;
+ /// \endcode
+ ///
+ /// Possible values:
+ ///
+ /// * ``ACS_None`` (in configuration: ``None``)
+ /// Do not align bit declarations on consecutive lines.
+ ///
+ /// * ``ACS_Consecutive`` (in configuration: ``Consecutive``)
+ /// Align declarations on consecutive lines. This will result in
+ /// formattings like:
+ /// \code
+ /// int aaaa = 12;
+ /// float b = 23;
+ /// std::string ccc;
+ ///
+ /// int a = 42;
+ /// /* A comment. */
+ /// bool c = false;
+ /// \endcode
+ ///
+ /// * ``ACS_AcrossEmptyLines`` (in configuration: ``AcrossEmptyLines``)
+ /// Same as ACS_Consecutive, but also spans over empty lines, e.g.
+ /// \code
+ /// int aaaa = 12;
+ /// float b = 23;
+ /// std::string ccc;
+ ///
+ /// int a = 42;
+ /// /* A comment. */
+ /// bool c = false;
+ /// \endcode
+ ///
+ /// * ``ACS_AcrossComments`` (in configuration: ``AcrossComments``)
+ /// Same as ACS_Consecutive, but also spans over lines only containing
+ /// comments, e.g.
+ /// \code
+ /// int aaaa = 12;
+ /// float b = 23;
+ /// std::string ccc;
+ ///
+ /// int a = 42;
+ /// /* A comment. */
+ /// bool c = false;
+ /// \endcode
+ ///
+ /// * ``ACS_AcrossEmptyLinesAndComments``
+ /// (in configuration: ``AcrossEmptyLinesAndComments``)
+ ///
+ /// Same as ACS_Consecutive, but also spans over lines only containing
+ /// comments and empty lines, e.g.
+ /// \code
+ /// int aaaa = 12;
+ /// float b = 23;
+ /// std::string ccc;
+ ///
+ /// int a = 42;
+ /// /* A comment. */
+ /// bool c = false;
+ /// \endcode
+ AlignConsecutiveStyle AlignConsecutiveDeclarations;
/// Different styles for aligning escaped newlines.
enum EscapedNewlineAlignmentStyle : unsigned char {
@@ -2725,6 +2969,7 @@
AlignConsecutiveAssignments == R.AlignConsecutiveAssignments &&
AlignConsecutiveBitFields == R.AlignConsecutiveBitFields &&
AlignConsecutiveDeclarations == R.AlignConsecutiveDeclarations &&
+ AlignConsecutiveMacros == R.AlignConsecutiveMacros &&
AlignEscapedNewlines == R.AlignEscapedNewlines &&
AlignOperands == R.AlignOperands &&
AlignTrailingComments == R.AlignTrailingComments &&
Index: clang/docs/tools/dump_format_style.py
===================================================================
--- clang/docs/tools/dump_format_style.py
+++ clang/docs/tools/dump_format_style.py
@@ -42,7 +42,7 @@
def __str__(self):
s = '**%s** (``%s``)\n%s' % (self.name, self.type,
doxygen2rst(indent(self.comment, 2)))
- if self.enum:
+ if self.enum and self.enum.values:
s += indent('\n\nPossible values:\n\n%s\n' % self.enum, 2)
if self.nested_struct:
s += indent('\n\nNested configuration flags:\n\n%s\n' %self.nested_struct,
@@ -104,13 +104,18 @@
doxygen2rst(indent(self.comment, 2)))
def clean_comment_line(line):
- match = re.match(r'^/// \\code(\{.(\w+)\})?$', line)
+ match = re.match(r'^/// (?P<indent> +)?\\code(\{.(?P<lang>\w+)\})?$', line)
if match:
- lang = match.groups()[1]
+ indent = match.group('indent')
+ if not indent:
+ indent = ''
+ lang = match.group('lang')
if not lang:
lang = 'c++'
- return '\n.. code-block:: %s\n\n' % lang
- if line == '/// \\endcode':
+ return '\n%s.. code-block:: %s\n\n' % (indent, lang)
+
+ endcode_match = re.match(r'^/// +\\endcode$', line)
+ if endcode_match:
return ''
return line[4:] + '\n'
@@ -184,7 +189,9 @@
state = State.InStruct
enums[enum.name] = enum
else:
- raise Exception('Invalid format, expected enum field comment or };')
+ # Enum member without documentation. Must be documented where the enum
+ # is used.
+ pass
elif state == State.InEnumMemberComment:
if line.startswith('///'):
comment += clean_comment_line(line)
Index: clang/docs/ReleaseNotes.rst
===================================================================
--- clang/docs/ReleaseNotes.rst
+++ clang/docs/ReleaseNotes.rst
@@ -289,9 +289,11 @@
- Option ``IndentRequires`` has been added to indent the ``requires`` keyword
in templates.
+
- Option ``BreakBeforeConceptDeclarations`` has been added to aid the formatting of concepts.
-- Option ``IndentPragmas`` has been added to allow #pragma to indented with the current scope level. This is especially useful when using #pragma to mark OpenMP sections of code.
+- Option ``IndentPragmas`` has been added to allow #pragma to indented with the current scope
+ level. This is especially useful when using #pragma to mark OpenMP sections of code.
- Option ``SpaceBeforeCaseColon`` has been added to add a space before the
colon in a case or default statement.
@@ -300,6 +302,9 @@
macros which are not parsed as a type in front of a statement. See
the documentation for an example.
+- Options ``AlignConsecutiveAssignments``, ``AlignConsecutiveBitFields``,
+ ``AlignConsecutiveDeclarations`` and ``AlignConsecutiveMacros`` have been modified to allow
+ alignment across empty lines and/or comments.
libclang
--------
Index: clang/docs/ClangFormatStyleOptions.rst
===================================================================
--- clang/docs/ClangFormatStyleOptions.rst
+++ clang/docs/ClangFormatStyleOptions.rst
@@ -195,23 +195,84 @@
-**AlignConsecutiveAssignments** (``bool``)
- If ``true``, aligns consecutive assignments.
+**AlignConsecutiveAssignments** (``AlignConsecutiveStyle``)
+ Style of aligning consecutive assignments.
- This will align the assignment operators of consecutive lines. This
- will result in formattings like
+ ``Consecutive`` will result in formattings like:
.. code-block:: c++
- int aaaa = 12;
- int b = 23;
- int ccc = 23;
+ int a = 1;
+ int somelongname = 2;
+ double c = 3;
-**AlignConsecutiveBitFields** (``bool``)
- If ``true``, aligns consecutive bitfield members.
+ Possible values:
+
+ * ``ACS_None`` (in configuration: ``None``)
+ Do not align assignments on consecutive lines.
+
+ * ``ACS_Consecutive`` (in configuration: ``Consecutive``)
+ Align assignments on consecutive lines. This will result in
+ formattings like:
+
+ .. code-block:: c++
+
+ int a = 1;
+ int somelongname = 2;
+ double c = 3;
+
+ int d = 3;
+ /* A comment. */
+ double e = 4;
+
+ * ``ACS_AcrossEmptyLines`` (in configuration: ``AcrossEmptyLines``)
+ Same as ACS_Consecutive, but also spans over empty lines, e.g.
+
+ .. code-block:: c++
+
+ int a = 1;
+ int somelongname = 2;
+ double c = 3;
+
+ int d = 3;
+ /* A comment. */
+ double e = 4;
+
+ * ``ACS_AcrossComments`` (in configuration: ``AcrossComments``)
+ Same as ACS_Consecutive, but also spans over lines only containing
+ comments, e.g.
+
+ .. code-block:: c++
+
+ int a = 1;
+ int somelongname = 2;
+ double c = 3;
+
+ int d = 3;
+ /* A comment. */
+ double e = 4;
+
+ * ``ACS_AcrossEmptyLinesAndComments``
+ (in configuration: ``AcrossEmptyLinesAndComments``)
+
+ Same as ACS_Consecutive, but also spans over lines only containing
+ comments and empty lines, e.g.
+
+ .. code-block:: c++
+
+ int a = 1;
+ int somelongname = 2;
+ double c = 3;
+
+ int d = 3;
+ /* A comment. */
+ double e = 4;
+
+**AlignConsecutiveBitFields** (``AlignConsecutiveStyle``)
+ Style of aligning consecutive bit field.
- This will align the bitfield separators of consecutive lines. This
- will result in formattings like
+ ``Consecutive`` will align the bitfield separators of consecutive lines.
+ This will result in formattings like:
.. code-block:: c++
@@ -219,23 +280,146 @@
int b : 12;
int ccc : 8;
-**AlignConsecutiveDeclarations** (``bool``)
- If ``true``, aligns consecutive declarations.
+ Possible values:
+
+ * ``ACS_None`` (in configuration: ``None``)
+ Do not align bit fields on consecutive lines.
+
+ * ``ACS_Consecutive`` (in configuration: ``Consecutive``)
+ Align bit fields on consecutive lines. This will result in
+ formattings like:
+
+ .. code-block:: c++
+
+ int aaaa : 1;
+ int b : 12;
+ int ccc : 8;
+
+ int d : 2;
+ /* A comment. */
+ int ee : 3;
+
+ * ``ACS_AcrossEmptyLines`` (in configuration: ``AcrossEmptyLines``)
+ Same as ACS_Consecutive, but also spans over empty lines, e.g.
+
+ .. code-block:: c++
+
+ int aaaa : 1;
+ int b : 12;
+ int ccc : 8;
+
+ int d : 2;
+ /* A comment. */
+ int ee : 3;
+
+ * ``ACS_AcrossComments`` (in configuration: ``AcrossComments``)
+ Same as ACS_Consecutive, but also spans over lines only containing
+ comments, e.g.
+
+ .. code-block:: c++
+
+ int aaaa : 1;
+ int b : 12;
+ int ccc : 8;
+
+ int d : 2;
+ /* A comment. */
+ int ee : 3;
+
+ * ``ACS_AcrossEmptyLinesAndComments``
+ (in configuration: ``AcrossEmptyLinesAndComments``)
+
+ Same as ACS_Consecutive, but also spans over lines only containing
+ comments and empty lines, e.g.
+
+ .. code-block:: c++
+
+ int aaaa : 1;
+ int b : 12;
+ int ccc : 8;
+
+ int d : 2;
+ /* A comment. */
+ int ee : 3;
+
+**AlignConsecutiveDeclarations** (``AlignConsecutiveStyle``)
+ Style of aligning consecutive declarations.
- This will align the declaration names of consecutive lines. This
- will result in formattings like
+ ``Consecutive`` will align the declaration names of consecutive lines.
+ This will result in formattings like:
.. code-block:: c++
int aaaa = 12;
float b = 23;
- std::string ccc = 23;
+ std::string ccc;
-**AlignConsecutiveMacros** (``bool``)
- If ``true``, aligns consecutive C/C++ preprocessor macros.
+ Possible values:
+
+ * ``ACS_None`` (in configuration: ``None``)
+ Do not align bit declarations on consecutive lines.
+
+ * ``ACS_Consecutive`` (in configuration: ``Consecutive``)
+ Align declarations on consecutive lines. This will result in
+ formattings like:
+
+ .. code-block:: c++
+
+ int aaaa = 12;
+ float b = 23;
+ std::string ccc;
+
+ int a = 42;
+ /* A comment. */
+ bool c = false;
+
+ * ``ACS_AcrossEmptyLines`` (in configuration: ``AcrossEmptyLines``)
+ Same as ACS_Consecutive, but also spans over empty lines, e.g.
+
+ .. code-block:: c++
+
+ int aaaa = 12;
+ float b = 23;
+ std::string ccc;
+
+ int a = 42;
+ /* A comment. */
+ bool c = false;
+
+ * ``ACS_AcrossComments`` (in configuration: ``AcrossComments``)
+ Same as ACS_Consecutive, but also spans over lines only containing
+ comments, e.g.
+
+ .. code-block:: c++
+
+ int aaaa = 12;
+ float b = 23;
+ std::string ccc;
+
+ int a = 42;
+ /* A comment. */
+ bool c = false;
+
+ * ``ACS_AcrossEmptyLinesAndComments``
+ (in configuration: ``AcrossEmptyLinesAndComments``)
+
+ Same as ACS_Consecutive, but also spans over lines only containing
+ comments and empty lines, e.g.
+
+ .. code-block:: c++
+
+ int aaaa = 12;
+ float b = 23;
+ std::string ccc;
+
+ int a = 42;
+ /* A comment. */
+ bool c = false;
+
+**AlignConsecutiveMacros** (``AlignConsecutiveStyle``)
+ Style of aligning consecutive macro definitions.
- This will align C/C++ preprocessor macros of consecutive lines.
- Will result in formattings like
+ ``Consecutive`` will result in formattings like:
.. code-block:: c++
@@ -245,6 +429,68 @@
#define foo(x) (x * x)
#define bar(y, z) (y + z)
+ Possible values:
+
+ * ``ACS_None`` (in configuration: ``None``)
+ Do not align macro definitions on consecutive lines.
+
+ * ``ACS_Consecutive`` (in configuration: ``Consecutive``)
+ Align macro definitions on consecutive lines. This will result in
+ formattings like:
+
+ .. code-block:: c++
+
+ #define SHORT_NAME 42
+ #define LONGER_NAME 0x007f
+ #define EVEN_LONGER_NAME (2)
+
+ #define foo(x) (x * x)
+ /* some comment */
+ #define bar(y, z) (y + z)
+
+ * ``ACS_AcrossEmptyLines`` (in configuration: ``AcrossEmptyLines``)
+ Same as ACS_Consecutive, but also spans over empty lines, e.g.
+
+ .. code-block:: c++
+
+ #define SHORT_NAME 42
+ #define LONGER_NAME 0x007f
+ #define EVEN_LONGER_NAME (2)
+
+ #define foo(x) (x * x)
+ /* some comment */
+ #define bar(y, z) (y + z)
+
+ * ``ACS_AcrossComments`` (in configuration: ``AcrossComments``)
+ Same as ACS_Consecutive, but also spans over lines only containing
+ comments, e.g.
+
+ .. code-block:: c++
+
+ #define SHORT_NAME 42
+ #define LONGER_NAME 0x007f
+ #define EVEN_LONGER_NAME (2)
+
+ #define foo(x) (x * x)
+ /* some comment */
+ #define bar(y, z) (y + z)
+
+ * ``ACS_AcrossEmptyLinesAndComments``
+ (in configuration: ``AcrossEmptyLinesAndComments``)
+
+ Same as ACS_Consecutive, but also spans over lines only containing
+ comments and empty lines, e.g.
+
+ .. code-block:: c++
+
+ #define SHORT_NAME 42
+ #define LONGER_NAME 0x007f
+ #define EVEN_LONGER_NAME (2)
+
+ #define foo(x) (x * x)
+ /* some comment */
+ #define bar(y, z) (y + z)
+
**AlignEscapedNewlines** (``EscapedNewlineAlignmentStyle``)
Options for aligning backslashes in escaped newlines.
_______________________________________________
cfe-commits mailing list
[email protected]
https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits