sstwcw updated this revision to Diff 410271.
sstwcw retitled this revision from "Add option to align compound assignments
like `+=`" to "[clang-format] Add option to align compound assignments like
`+=`".
sstwcw added a comment.
Herald added subscribers: llvm-commits, dexonsmith.
Herald added a project: LLVM.
Use struct for the alignment options.
Repository:
rG LLVM Github Monorepo
CHANGES SINCE LAST ACTION
https://reviews.llvm.org/D119599/new/
https://reviews.llvm.org/D119599
Files:
clang/docs/ClangFormatStyleOptions.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
clang/unittests/Format/FormatTestJS.cpp
llvm/docs/YamlIO.rst
llvm/include/llvm/Support/YAMLTraits.h
Index: llvm/include/llvm/Support/YAMLTraits.h
===================================================================
--- llvm/include/llvm/Support/YAMLTraits.h
+++ llvm/include/llvm/Support/YAMLTraits.h
@@ -63,6 +63,7 @@
// static void mapping(IO &io, T &fields);
// Optionally may provide:
// static std::string validate(IO &io, T &fields);
+ // static void enumInput(IO &io, T &value);
//
// The optional flow flag will cause generated YAML to use a flow mapping
// (e.g. { a: 0, b: 1 }):
@@ -446,6 +447,31 @@
static bool const value = (sizeof(test<MappingTraits<T>>(nullptr)) == 1);
};
+// Test if MappingContextTraits<T>::enumInput() is defined on type T.
+template <class T, class Context> struct has_MappingEnumInputTraits {
+ using Signature_validate = void (*)(class IO &, T &);
+
+ template <typename U>
+ static char test(SameType<Signature_validate, &U::enumInput> *);
+
+ template <typename U> static double test(...);
+
+ static bool const value =
+ (sizeof(test<MappingContextTraits<T, Context>>(nullptr)) == 1);
+};
+
+// Test if MappingTraits<T>::enumInput() is defined on type T.
+template <class T> struct has_MappingEnumInputTraits<T, EmptyContext> {
+ using Signature_validate = void (*)(class IO &, T &);
+
+ template <typename U>
+ static char test(SameType<Signature_validate, &U::enumInput> *);
+
+ template <typename U> static double test(...);
+
+ static bool const value = (sizeof(test<MappingTraits<T>>(nullptr)) == 1);
+};
+
// Test if SequenceTraits<T> is defined on type T.
template <class T>
struct has_SequenceMethodTraits
@@ -1061,20 +1087,45 @@
io.endMapping();
}
+#define MAPPING_COMMON() \
+ do { \
+ if (has_FlowTraits<MappingTraits<T>>::value) { \
+ io.beginFlowMapping(); \
+ detail::doMapping(io, Val, Ctx); \
+ io.endFlowMapping(); \
+ } else { \
+ io.beginMapping(); \
+ detail::doMapping(io, Val, Ctx); \
+ io.endMapping(); \
+ } \
+ } while (false)
+
template <typename T, typename Context>
-std::enable_if_t<unvalidatedMappingTraits<T, Context>::value, void>
+std::enable_if_t<unvalidatedMappingTraits<T, Context>::value &&
+ has_MappingEnumInputTraits<T, Context>::value,
+ void>
yamlize(IO &io, T &Val, bool, Context &Ctx) {
- if (has_FlowTraits<MappingTraits<T>>::value) {
- io.beginFlowMapping();
- detail::doMapping(io, Val, Ctx);
- io.endFlowMapping();
- } else {
- io.beginMapping();
- detail::doMapping(io, Val, Ctx);
- io.endMapping();
+ if (!io.outputting()) {
+ io.beginEnumScalar();
+ MappingTraits<T>::enumInput(io, Val);
+ bool Matched = !io.matchEnumFallback();
+ io.endEnumScalar();
+ if (Matched)
+ return;
}
+ MAPPING_COMMON();
}
+template <typename T, typename Context>
+std::enable_if_t<unvalidatedMappingTraits<T, Context>::value &&
+ !has_MappingEnumInputTraits<T, Context>::value,
+ void>
+yamlize(IO &io, T &Val, bool, Context &Ctx) {
+ MAPPING_COMMON();
+}
+
+#undef MAPPING_COMMON
+
template <typename T>
std::enable_if_t<has_CustomMappingTraits<T>::value, void>
yamlize(IO &io, T &Val, bool, EmptyContext &Ctx) {
Index: llvm/docs/YamlIO.rst
===================================================================
--- llvm/docs/YamlIO.rst
+++ llvm/docs/YamlIO.rst
@@ -551,6 +551,43 @@
}
};
+There are circumstances where we want to allow the entire mapping to be
+read as an enumeration. For example, say some configuration option
+started as an enumeration. Then it got more complex so it is now a
+mapping. But it is necessary to support the old configuration files.
+In that case, add a function ``enumInput`` like for
+``ScalarEnumerationTraits::enumeration``. Examples:
+
+.. code-block:: c++
+
+ template <> struct MappingTraits<FormatStyle::AlignConsecutiveStyle> {
+ static void enumInput(IO &IO, FormatStyle::AlignConsecutiveStyle &Value) {
+ IO.enumCase(Value, "None", FormatStyle::AlignConsecutiveStyle({}));
+ IO.enumCase(Value, "Consecutive",
+ FormatStyle::AlignConsecutiveStyle({/*.Enabled=*/true}));
+ IO.enumCase(Value, "AcrossEmptyLines",
+ FormatStyle::AlignConsecutiveStyle(
+ {/*.Enabled=*/true, /*.AcrossEmptyLines=*/true}));
+ IO.enumCase(Value, "AcrossComments",
+ FormatStyle::AlignConsecutiveStyle({/*.Enabled=*/true,
+ /*.AcrossEmptyLines=*/false,
+ /*.AcrossComments=*/true}));
+ IO.enumCase(Value, "AcrossEmptyLinesAndComments",
+ FormatStyle::AlignConsecutiveStyle({/*.Enabled=*/true,
+ /*.AcrossEmptyLines=*/true,
+ /*.AcrossComments=*/true}));
+ IO.enumCase(Value, "true",
+ FormatStyle::AlignConsecutiveStyle({/*.Enabled=*/true}));
+ IO.enumCase(Value, "false", FormatStyle::AlignConsecutiveStyle({}));
+ }
+
+ static void mapping(IO &IO, FormatStyle::AlignConsecutiveStyle &Value) {
+ IO.mapOptional("Enabled", Value.Enabled);
+ IO.mapOptional("AcrossEmptyLines", Value.AcrossEmptyLines);
+ IO.mapOptional("AcrossComments", Value.AcrossComments);
+ }
+ };
+
No Normalization
----------------
Index: clang/unittests/Format/FormatTestJS.cpp
===================================================================
--- clang/unittests/Format/FormatTestJS.cpp
+++ clang/unittests/Format/FormatTestJS.cpp
@@ -2698,7 +2698,7 @@
TEST_F(FormatTestJS, AlignConsecutiveDeclarations) {
FormatStyle Style = getGoogleStyle(FormatStyle::LK_JavaScript);
- Style.AlignConsecutiveDeclarations = FormatStyle::ACS_Consecutive;
+ Style.AlignConsecutiveDeclarations.Enabled = true;
verifyFormat("let letVariable = 5;\n"
"double constVariable = 10;",
Style);
@@ -2735,7 +2735,7 @@
TEST_F(FormatTestJS, AlignConsecutiveAssignments) {
FormatStyle Style = getGoogleStyle(FormatStyle::LK_JavaScript);
- Style.AlignConsecutiveAssignments = FormatStyle::ACS_Consecutive;
+ Style.AlignConsecutiveAssignments.Enabled = true;
verifyFormat("let letVariable = 5;\n"
"double constVariable = 10;",
Style);
@@ -2771,8 +2771,8 @@
TEST_F(FormatTestJS, AlignConsecutiveAssignmentsAndDeclarations) {
FormatStyle Style = getGoogleStyle(FormatStyle::LK_JavaScript);
- Style.AlignConsecutiveDeclarations = FormatStyle::ACS_Consecutive;
- Style.AlignConsecutiveAssignments = FormatStyle::ACS_Consecutive;
+ Style.AlignConsecutiveDeclarations.Enabled = true;
+ Style.AlignConsecutiveAssignments.Enabled = true;
verifyFormat("let letVariable = 5;\n"
"double constVariable = 10;",
Style);
Index: clang/unittests/Format/FormatTest.cpp
===================================================================
--- clang/unittests/Format/FormatTest.cpp
+++ clang/unittests/Format/FormatTest.cpp
@@ -2046,7 +2046,7 @@
" res2 = [](int &a) { return 0000000000000; };",
Style);
- Style.AlignConsecutiveDeclarations = FormatStyle::ACS_Consecutive;
+ Style.AlignConsecutiveDeclarations.Enabled = true;
verifyFormat("Const unsigned int *c;\n"
"const unsigned int *d;\n"
"Const unsigned int &e;\n"
@@ -2087,7 +2087,7 @@
" res2 = [](int& a) { return 0000000000000; };",
Style);
- Style.AlignConsecutiveDeclarations = FormatStyle::ACS_Consecutive;
+ Style.AlignConsecutiveDeclarations.Enabled = true;
verifyFormat("Const unsigned int* c;\n"
"const unsigned int* d;\n"
"Const unsigned int& e;\n"
@@ -2108,7 +2108,7 @@
verifyFormat("for (int a = 0, b = 0; const Foo *c : {1, 2, 3})", Style);
verifyFormat("for (int a = 0, b++; const Foo *c : {1, 2, 3})", Style);
- Style.AlignConsecutiveDeclarations = FormatStyle::ACS_Consecutive;
+ Style.AlignConsecutiveDeclarations.Enabled = true;
verifyFormat("Const unsigned int *c;\n"
"const unsigned int *d;\n"
"Const unsigned int& e;\n"
@@ -2144,7 +2144,7 @@
" res2 = [](int & a) { return 0000000000000; };",
Style);
- Style.AlignConsecutiveDeclarations = FormatStyle::ACS_Consecutive;
+ Style.AlignConsecutiveDeclarations.Enabled = true;
verifyFormat("Const unsigned int* c;\n"
"const unsigned int* d;\n"
"Const unsigned int & e;\n"
@@ -14338,8 +14338,8 @@
"*/\n"
"}",
Tab));
- Tab.AlignConsecutiveAssignments = FormatStyle::ACS_Consecutive;
- Tab.AlignConsecutiveDeclarations = FormatStyle::ACS_Consecutive;
+ Tab.AlignConsecutiveAssignments.Enabled = true;
+ Tab.AlignConsecutiveDeclarations.Enabled = true;
Tab.TabWidth = 4;
Tab.IndentWidth = 4;
verifyFormat("class Assign {\n"
@@ -14577,8 +14577,8 @@
"*/\n"
"}",
Tab));
- Tab.AlignConsecutiveAssignments = FormatStyle::ACS_Consecutive;
- Tab.AlignConsecutiveDeclarations = FormatStyle::ACS_Consecutive;
+ Tab.AlignConsecutiveAssignments.Enabled = true;
+ Tab.AlignConsecutiveDeclarations.Enabled = true;
Tab.TabWidth = 4;
Tab.IndentWidth = 4;
verifyFormat("class Assign {\n"
@@ -15748,9 +15748,8 @@
TEST_F(FormatTest, AlignConsecutiveMacros) {
FormatStyle Style = getLLVMStyle();
- Style.AlignConsecutiveAssignments = FormatStyle::ACS_Consecutive;
- Style.AlignConsecutiveDeclarations = FormatStyle::ACS_Consecutive;
- Style.AlignConsecutiveMacros = FormatStyle::ACS_None;
+ Style.AlignConsecutiveAssignments.Enabled = true;
+ Style.AlignConsecutiveDeclarations.Enabled = true;
verifyFormat("#define a 3\n"
"#define bbbb 4\n"
@@ -15774,7 +15773,7 @@
"#define ffff(x, y) (x - y)",
Style);
- Style.AlignConsecutiveMacros = FormatStyle::ACS_Consecutive;
+ Style.AlignConsecutiveMacros.Enabled = true;
verifyFormat("#define a 3\n"
"#define bbbb 4\n"
"#define ccc (5)",
@@ -15814,7 +15813,7 @@
"};",
Style);
- Style.AlignConsecutiveMacros = FormatStyle::ACS_None;
+ Style.AlignConsecutiveMacros.Enabled = false;
Style.ColumnLimit = 20;
verifyFormat("#define a \\\n"
@@ -15828,7 +15827,7 @@
" \"LLLLLLLL\"\n",
Style);
- Style.AlignConsecutiveMacros = FormatStyle::ACS_Consecutive;
+ Style.AlignConsecutiveMacros.Enabled = true;
verifyFormat("#define a \\\n"
" \"aabbbbbbbbbbbb\"\n"
"#define D \\\n"
@@ -15843,7 +15842,7 @@
// Test across comments
Style.MaxEmptyLinesToKeep = 10;
Style.ReflowComments = false;
- Style.AlignConsecutiveMacros = FormatStyle::ACS_AcrossComments;
+ Style.AlignConsecutiveMacros.AcrossComments = true;
EXPECT_EQ("#define a 3\n"
"// line comment\n"
"#define bbbb 4\n"
@@ -15901,7 +15900,8 @@
Style));
// Test across empty lines
- Style.AlignConsecutiveMacros = FormatStyle::ACS_AcrossEmptyLines;
+ Style.AlignConsecutiveMacros.AcrossComments = false;
+ Style.AlignConsecutiveMacros.AcrossEmptyLines = true;
EXPECT_EQ("#define a 3\n"
"\n"
"#define bbbb 4\n"
@@ -15939,7 +15939,7 @@
Style));
// Test across empty lines and comments
- Style.AlignConsecutiveMacros = FormatStyle::ACS_AcrossEmptyLinesAndComments;
+ Style.AlignConsecutiveMacros.AcrossComments = true;
verifyFormat("#define a 3\n"
"\n"
"// line comment\n"
@@ -15990,8 +15990,9 @@
TEST_F(FormatTest, AlignConsecutiveAssignmentsAcrossEmptyLines) {
FormatStyle Alignment = getLLVMStyle();
- Alignment.AlignConsecutiveMacros = FormatStyle::ACS_Consecutive;
- Alignment.AlignConsecutiveAssignments = FormatStyle::ACS_AcrossEmptyLines;
+ Alignment.AlignConsecutiveMacros.Enabled = true;
+ Alignment.AlignConsecutiveAssignments.Enabled = true;
+ Alignment.AlignConsecutiveAssignments.AcrossEmptyLines = true;
Alignment.MaxEmptyLinesToKeep = 10;
/* Test alignment across empty lines */
@@ -16064,9 +16065,9 @@
TEST_F(FormatTest, AlignConsecutiveDeclarationsAcrossEmptyLinesAndComments) {
FormatStyle Alignment = getLLVMStyle();
- Alignment.AlignConsecutiveDeclarations =
- FormatStyle::ACS_AcrossEmptyLinesAndComments;
- Alignment.AlignConsecutiveAssignments = FormatStyle::ACS_None;
+ Alignment.AlignConsecutiveDeclarations.Enabled = true;
+ Alignment.AlignConsecutiveDeclarations.AcrossEmptyLines = true;
+ Alignment.AlignConsecutiveDeclarations.AcrossComments = true;
Alignment.MaxEmptyLinesToKeep = 10;
/* Test alignment across empty lines */
@@ -16128,8 +16129,9 @@
TEST_F(FormatTest, AlignConsecutiveBitFieldsAcrossEmptyLinesAndComments) {
FormatStyle Alignment = getLLVMStyle();
- Alignment.AlignConsecutiveBitFields =
- FormatStyle::ACS_AcrossEmptyLinesAndComments;
+ Alignment.AlignConsecutiveBitFields.Enabled = true;
+ Alignment.AlignConsecutiveBitFields.AcrossEmptyLines = true;
+ Alignment.AlignConsecutiveBitFields.AcrossComments = true;
Alignment.MaxEmptyLinesToKeep = 10;
/* Test alignment across empty lines */
@@ -16195,8 +16197,9 @@
TEST_F(FormatTest, AlignConsecutiveAssignmentsAcrossComments) {
FormatStyle Alignment = getLLVMStyle();
- Alignment.AlignConsecutiveMacros = FormatStyle::ACS_Consecutive;
- Alignment.AlignConsecutiveAssignments = FormatStyle::ACS_AcrossComments;
+ Alignment.AlignConsecutiveMacros.Enabled = true;
+ Alignment.AlignConsecutiveAssignments.Enabled = true;
+ Alignment.AlignConsecutiveAssignments.AcrossComments = true;
Alignment.MaxEmptyLinesToKeep = 10;
/* Test alignment across empty lines */
@@ -16282,9 +16285,10 @@
TEST_F(FormatTest, AlignConsecutiveAssignmentsAcrossEmptyLinesAndComments) {
FormatStyle Alignment = getLLVMStyle();
- Alignment.AlignConsecutiveMacros = FormatStyle::ACS_Consecutive;
- Alignment.AlignConsecutiveAssignments =
- FormatStyle::ACS_AcrossEmptyLinesAndComments;
+ Alignment.AlignConsecutiveMacros.Enabled = true;
+ Alignment.AlignConsecutiveAssignments.Enabled = true;
+ Alignment.AlignConsecutiveAssignments.AcrossEmptyLines = true;
+ Alignment.AlignConsecutiveAssignments.AcrossComments = true;
verifyFormat("int a = 5;\n"
"int oneTwoThree = 123;",
Alignment);
@@ -16595,10 +16599,122 @@
Alignment));
}
+TEST_F(FormatTest, AlignCompoundAssignments) {
+ FormatStyle Alignment = getLLVMStyle();
+ Alignment.AlignConsecutiveAssignments.Enabled = true;
+ Alignment.AlignConsecutiveAssignments.AlignCompound = true;
+ Alignment.AlignConsecutiveAssignments.PadOperators = false;
+ verifyFormat("sfdbddfbdfbb = 5;\n"
+ "dvsdsv = 5;\n"
+ "int dsvvdvsdvvv = 123;",
+ Alignment);
+ verifyFormat("sfdbddfbdfbb ^= 5;\n"
+ "dvsdsv |= 5;\n"
+ "int dsvvdvsdvvv = 123;",
+ Alignment);
+ verifyFormat("sfdbddfbdfbb ^= 5;\n"
+ "dvsdsv <<= 5;\n"
+ "int dsvvdvsdvvv = 123;",
+ Alignment);
+ // Test that `<=` is not treated as a compound assignment.
+ verifyFormat("aa &= 5;\n"
+ "b <= 10;\n"
+ "c = 15;",
+ Alignment);
+ Alignment.AlignConsecutiveAssignments.PadOperators = true;
+ verifyFormat("sfdbddfbdfbb = 5;\n"
+ "dvsdsv = 5;\n"
+ "int dsvvdvsdvvv = 123;",
+ Alignment);
+ verifyFormat("sfdbddfbdfbb ^= 5;\n"
+ "dvsdsv |= 5;\n"
+ "int dsvvdvsdvvv = 123;",
+ Alignment);
+ verifyFormat("sfdbddfbdfbb ^= 5;\n"
+ "dvsdsv <<= 5;\n"
+ "int dsvvdvsdvvv = 123;",
+ Alignment);
+ EXPECT_EQ("int a += 5;\n"
+ "int one = 1;\n"
+ "\n"
+ "int oneTwoThree = 123;\n",
+ format("int a += 5;\n"
+ "int one = 1;\n"
+ "\n"
+ "int oneTwoThree = 123;\n",
+ Alignment));
+ EXPECT_EQ("int a += 5;\n"
+ "int one = 1;\n"
+ "//\n"
+ "int oneTwoThree = 123;\n",
+ format("int a += 5;\n"
+ "int one = 1;\n"
+ "//\n"
+ "int oneTwoThree = 123;\n",
+ Alignment));
+ Alignment.AlignConsecutiveAssignments.AcrossEmptyLines = true;
+ EXPECT_EQ("int a += 5;\n"
+ "int one = 1;\n"
+ "\n"
+ "int oneTwoThree = 123;\n",
+ format("int a += 5;\n"
+ "int one = 1;\n"
+ "\n"
+ "int oneTwoThree = 123;\n",
+ Alignment));
+ EXPECT_EQ("int a += 5;\n"
+ "int one = 1;\n"
+ "//\n"
+ "int oneTwoThree = 123;\n",
+ format("int a += 5;\n"
+ "int one = 1;\n"
+ "//\n"
+ "int oneTwoThree = 123;\n",
+ Alignment));
+ Alignment.AlignConsecutiveAssignments.AcrossEmptyLines = false;
+ Alignment.AlignConsecutiveAssignments.AcrossComments = true;
+ EXPECT_EQ("int a += 5;\n"
+ "int one = 1;\n"
+ "\n"
+ "int oneTwoThree = 123;\n",
+ format("int a += 5;\n"
+ "int one = 1;\n"
+ "\n"
+ "int oneTwoThree = 123;\n",
+ Alignment));
+ EXPECT_EQ("int a += 5;\n"
+ "int one = 1;\n"
+ "//\n"
+ "int oneTwoThree = 123;\n",
+ format("int a += 5;\n"
+ "int one = 1;\n"
+ "//\n"
+ "int oneTwoThree = 123;\n",
+ Alignment));
+ Alignment.AlignConsecutiveAssignments.AcrossEmptyLines = true;
+ EXPECT_EQ("int a += 5;\n"
+ "int one >>= 1;\n"
+ "\n"
+ "int oneTwoThree = 123;\n",
+ format("int a += 5;\n"
+ "int one >>= 1;\n"
+ "\n"
+ "int oneTwoThree = 123;\n",
+ Alignment));
+ EXPECT_EQ("int a += 5;\n"
+ "int one = 1;\n"
+ "//\n"
+ "int oneTwoThree <<= 123;\n",
+ format("int a += 5;\n"
+ "int one = 1;\n"
+ "//\n"
+ "int oneTwoThree <<= 123;\n",
+ Alignment));
+}
+
TEST_F(FormatTest, AlignConsecutiveAssignments) {
FormatStyle Alignment = getLLVMStyle();
- Alignment.AlignConsecutiveMacros = FormatStyle::ACS_Consecutive;
- Alignment.AlignConsecutiveAssignments = FormatStyle::ACS_None;
+ Alignment.AlignConsecutiveMacros.Enabled = true;
verifyFormat("int a = 5;\n"
"int oneTwoThree = 123;",
Alignment);
@@ -16606,14 +16722,15 @@
"int oneTwoThree = 123;",
Alignment);
- Alignment.AlignConsecutiveAssignments = FormatStyle::ACS_Consecutive;
+ Alignment.AlignConsecutiveAssignments.Enabled = true;
verifyFormat("int a = 5;\n"
"int oneTwoThree = 123;",
Alignment);
verifyFormat("int a = method();\n"
"int oneTwoThree = 133;",
Alignment);
- verifyFormat("a &= 5;\n"
+ verifyFormat("aa <= 5;\n"
+ "a &= 5;\n"
"bcd *= 5;\n"
"ghtyf += 5;\n"
"dvfvdb -= 5;\n"
@@ -16686,8 +16803,7 @@
Alignment);
// https://llvm.org/PR33697
FormatStyle AlignmentWithPenalty = getLLVMStyle();
- AlignmentWithPenalty.AlignConsecutiveAssignments =
- FormatStyle::ACS_Consecutive;
+ AlignmentWithPenalty.AlignConsecutiveAssignments.Enabled = true;
AlignmentWithPenalty.PenaltyReturnTypeOnItsOwnLine = 5000;
verifyFormat("class SSSSSSSSSSSSSSSSSSSSSSSSSSSS {\n"
" void f() = delete;\n"
@@ -16906,7 +17022,7 @@
TEST_F(FormatTest, AlignConsecutiveBitFields) {
FormatStyle Alignment = getLLVMStyle();
- Alignment.AlignConsecutiveBitFields = FormatStyle::ACS_Consecutive;
+ Alignment.AlignConsecutiveBitFields.Enabled = true;
verifyFormat("int const a : 5;\n"
"int oneTwoThree : 23;",
Alignment);
@@ -16916,7 +17032,7 @@
"int oneTwoThree : 23 = 0;",
Alignment);
- Alignment.AlignConsecutiveDeclarations = FormatStyle::ACS_Consecutive;
+ Alignment.AlignConsecutiveDeclarations.Enabled = true;
verifyFormat("int const a : 5;\n"
"int oneTwoThree : 23;",
Alignment);
@@ -16929,7 +17045,7 @@
"int oneTwoThree : 23 = 0;",
Alignment);
- Alignment.AlignConsecutiveAssignments = FormatStyle::ACS_Consecutive;
+ Alignment.AlignConsecutiveAssignments.Enabled = true;
verifyFormat("int const a : 5 = 1;\n"
"int oneTwoThree : 23 = 0;",
Alignment);
@@ -16963,8 +17079,7 @@
TEST_F(FormatTest, AlignConsecutiveDeclarations) {
FormatStyle Alignment = getLLVMStyle();
- Alignment.AlignConsecutiveMacros = FormatStyle::ACS_Consecutive;
- Alignment.AlignConsecutiveDeclarations = FormatStyle::ACS_None;
+ Alignment.AlignConsecutiveMacros.Enabled = true;
Alignment.PointerAlignment = FormatStyle::PAS_Right;
verifyFormat("float const a = 5;\n"
"int oneTwoThree = 123;",
@@ -16973,7 +17088,7 @@
"float const oneTwoThree = 123;",
Alignment);
- Alignment.AlignConsecutiveDeclarations = FormatStyle::ACS_Consecutive;
+ Alignment.AlignConsecutiveDeclarations.Enabled = true;
verifyFormat("float const a = 5;\n"
"int oneTwoThree = 123;",
Alignment);
@@ -17084,7 +17199,7 @@
verifyFormat("int a(int x, void (*fp)(int y));\n"
"double b();",
Alignment);
- Alignment.AlignConsecutiveAssignments = FormatStyle::ACS_Consecutive;
+ Alignment.AlignConsecutiveAssignments.Enabled = true;
// Ensure recursive alignment is broken by function braces, so that the
// "a = 1" does not align with subsequent assignments inside the function
// body.
@@ -17309,7 +17424,7 @@
"int foobar;\n",
AlignmentMiddle);
- Alignment.AlignConsecutiveAssignments = FormatStyle::ACS_None;
+ Alignment.AlignConsecutiveAssignments.Enabled = false;
Alignment.AlignEscapedNewlines = FormatStyle::ENAS_DontAlign;
verifyFormat("#define A \\\n"
" int aaaa = 12; \\\n"
@@ -17378,7 +17493,7 @@
"int j = 2;",
Alignment);
- Alignment.AlignConsecutiveAssignments = FormatStyle::ACS_Consecutive;
+ Alignment.AlignConsecutiveAssignments.Enabled = true;
verifyFormat("auto lambda = []() {\n"
" auto ii = 0;\n"
" float j = 0;\n"
@@ -17392,7 +17507,7 @@
" i = 3 //\n"
"};",
Alignment);
- Alignment.AlignConsecutiveAssignments = FormatStyle::ACS_None;
+ Alignment.AlignConsecutiveAssignments.Enabled = false;
verifyFormat(
"int i = 1;\n"
@@ -17405,7 +17520,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 = FormatStyle::ACS_Consecutive;
+ Alignment.AlignConsecutiveAssignments.Enabled = true;
Alignment.ColumnLimit = 30;
verifyFormat("float ii = 1;\n"
"unsigned j = 2;\n"
@@ -17415,7 +17530,7 @@
"int myvar = 1;",
Alignment);
Alignment.ColumnLimit = 80;
- Alignment.AlignConsecutiveAssignments = FormatStyle::ACS_None;
+ Alignment.AlignConsecutiveAssignments.Enabled = false;
verifyFormat(
"template <typename LongTemplate, typename VeryLongTemplateTypeName,\n"
@@ -17429,7 +17544,7 @@
verifyFormat("int aa = ((1 > 2) ? 3 : 4);\n"
"float b[1][] = {{3.f}};\n",
Alignment);
- Alignment.AlignConsecutiveAssignments = FormatStyle::ACS_Consecutive;
+ Alignment.AlignConsecutiveAssignments.Enabled = true;
verifyFormat("float a, b = 1;\n"
"int c = 2;\n"
"int dd = 3;\n",
@@ -17437,7 +17552,7 @@
verifyFormat("int aa = ((1 > 2) ? 3 : 4);\n"
"float b[1][] = {{3.f}};\n",
Alignment);
- Alignment.AlignConsecutiveAssignments = FormatStyle::ACS_None;
+ Alignment.AlignConsecutiveAssignments.Enabled = false;
Alignment.ColumnLimit = 30;
Alignment.BinPackParameters = false;
@@ -17468,7 +17583,7 @@
Alignment.PointerAlignment = FormatStyle::PAS_Right;
// See llvm.org/PR35641
- Alignment.AlignConsecutiveDeclarations = FormatStyle::ACS_Consecutive;
+ Alignment.AlignConsecutiveDeclarations.Enabled = true;
verifyFormat("int func() { //\n"
" int b;\n"
" unsigned c;\n"
@@ -17477,7 +17592,7 @@
// See PR37175
FormatStyle Style = getMozillaStyle();
- Style.AlignConsecutiveDeclarations = FormatStyle::ACS_Consecutive;
+ Style.AlignConsecutiveDeclarations.Enabled = true;
EXPECT_EQ("DECOR1 /**/ int8_t /**/ DECOR2 /**/\n"
"foo(int a);",
format("DECOR1 /**/ int8_t /**/ DECOR2 /**/ foo (int a);", Style));
@@ -17516,7 +17631,7 @@
// See PR46529
FormatStyle BracedAlign = getLLVMStyle();
- BracedAlign.AlignConsecutiveDeclarations = FormatStyle::ACS_Consecutive;
+ BracedAlign.AlignConsecutiveDeclarations.Enabled = true;
verifyFormat("const auto result{[]() {\n"
" const auto something = 1;\n"
" return 2;\n"
@@ -17543,8 +17658,10 @@
TEST_F(FormatTest, AlignWithLineBreaks) {
auto Style = getLLVMStyleWithColumns(120);
- EXPECT_EQ(Style.AlignConsecutiveAssignments, FormatStyle::ACS_None);
- EXPECT_EQ(Style.AlignConsecutiveDeclarations, FormatStyle::ACS_None);
+ EXPECT_EQ(Style.AlignConsecutiveAssignments,
+ FormatStyle::AlignConsecutiveStyle({}));
+ EXPECT_EQ(Style.AlignConsecutiveDeclarations,
+ FormatStyle::AlignConsecutiveStyle({}));
verifyFormat("void foo() {\n"
" int myVar = 5;\n"
" double x = 3.14;\n"
@@ -17566,7 +17683,7 @@
Style);
// clang-format on
- Style.AlignConsecutiveAssignments = FormatStyle::ACS_Consecutive;
+ Style.AlignConsecutiveAssignments.Enabled = true;
verifyFormat("void foo() {\n"
" int myVar = 5;\n"
" double x = 3.14;\n"
@@ -17588,8 +17705,8 @@
Style);
// clang-format on
- Style.AlignConsecutiveAssignments = FormatStyle::ACS_None;
- Style.AlignConsecutiveDeclarations = FormatStyle::ACS_Consecutive;
+ Style.AlignConsecutiveAssignments.Enabled = false;
+ Style.AlignConsecutiveDeclarations.Enabled = true;
verifyFormat("void foo() {\n"
" int myVar = 5;\n"
" double x = 3.14;\n"
@@ -17611,8 +17728,8 @@
Style);
// clang-format on
- Style.AlignConsecutiveAssignments = FormatStyle::ACS_Consecutive;
- Style.AlignConsecutiveDeclarations = FormatStyle::ACS_Consecutive;
+ Style.AlignConsecutiveAssignments.Enabled = true;
+ Style.AlignConsecutiveDeclarations.Enabled = true;
verifyFormat("void foo() {\n"
" int myVar = 5;\n"
@@ -17636,7 +17753,7 @@
// clang-format on
Style = getLLVMStyleWithColumns(120);
- Style.AlignConsecutiveAssignments = FormatStyle::ACS_Consecutive;
+ Style.AlignConsecutiveAssignments.Enabled = true;
Style.ContinuationIndentWidth = 4;
Style.IndentWidth = 4;
@@ -17679,8 +17796,8 @@
"}",
Style);
- Style.AlignConsecutiveAssignments = FormatStyle::ACS_Consecutive;
- Style.AlignConsecutiveDeclarations = FormatStyle::ACS_None;
+ Style.AlignConsecutiveAssignments.Enabled = true;
+ Style.AlignConsecutiveDeclarations.Enabled = false;
verifyFormat("void foo2(void) {\n"
" BYTE p[1] = 1;\n"
" A B = {.one_foooooooooooooooo = 2,\n"
@@ -17690,8 +17807,8 @@
"}",
Style);
- Style.AlignConsecutiveAssignments = FormatStyle::ACS_None;
- Style.AlignConsecutiveDeclarations = FormatStyle::ACS_Consecutive;
+ Style.AlignConsecutiveAssignments.Enabled = false;
+ Style.AlignConsecutiveDeclarations.Enabled = true;
verifyFormat("void foo3(void) {\n"
" BYTE p[1] = 1;\n"
" A B = {.one_foooooooooooooooo = 2,\n"
@@ -17701,8 +17818,8 @@
"}",
Style);
- Style.AlignConsecutiveAssignments = FormatStyle::ACS_Consecutive;
- Style.AlignConsecutiveDeclarations = FormatStyle::ACS_Consecutive;
+ Style.AlignConsecutiveAssignments.Enabled = true;
+ Style.AlignConsecutiveDeclarations.Enabled = true;
verifyFormat("void foo4(void) {\n"
" BYTE p[1] = 1;\n"
" A B = {.one_foooooooooooooooo = 2,\n"
@@ -18718,10 +18835,8 @@
TEST_F(FormatTest, CatchAlignArrayOfStructuresRightAlignment) {
auto Style = getLLVMStyle();
Style.AlignArrayOfStructures = FormatStyle::AIAS_Right;
- Style.AlignConsecutiveAssignments =
- FormatStyle::AlignConsecutiveStyle::ACS_Consecutive;
- Style.AlignConsecutiveDeclarations =
- FormatStyle::AlignConsecutiveStyle::ACS_Consecutive;
+ Style.AlignConsecutiveAssignments.Enabled = true;
+ Style.AlignConsecutiveDeclarations.Enabled = true;
verifyFormat("struct test demo[] = {\n"
" {56, 23, \"hello\"},\n"
" {-1, 93463, \"world\"},\n"
@@ -18898,10 +19013,6 @@
Style = getLLVMStyleWithColumns(50);
Style.AlignArrayOfStructures = FormatStyle::AIAS_Right;
- Style.AlignConsecutiveAssignments =
- FormatStyle::AlignConsecutiveStyle::ACS_Consecutive;
- Style.AlignConsecutiveDeclarations =
- FormatStyle::AlignConsecutiveStyle::ACS_Consecutive;
verifyFormat("struct test demo[] = {\n"
" {56, 23, \"hello\"},\n"
" {-1, 93463, \"world\"},\n"
@@ -18913,10 +19024,8 @@
"};",
Style);
Style.ColumnLimit = 100;
- Style.AlignConsecutiveAssignments =
- FormatStyle::AlignConsecutiveStyle::ACS_AcrossComments;
- Style.AlignConsecutiveDeclarations =
- FormatStyle::AlignConsecutiveStyle::ACS_AcrossComments;
+ Style.AlignConsecutiveAssignments.AcrossComments = true;
+ Style.AlignConsecutiveDeclarations.AcrossComments = true;
verifyFormat("struct test demo[] = {\n"
" {56, 23, \"hello\"},\n"
" {-1, 93463, \"world\"},\n"
@@ -19575,69 +19684,37 @@
CHECK_PARSE("QualifierOrder: [volatile, type]", QualifierOrder,
std::vector<std::string>({"volatile", "type"}));
- 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);
+#define CHECK_ALIGN_CONSECUTIVE(FIELD) \
+ do { \
+ Style.FIELD.Enabled = true; \
+ CHECK_PARSE(#FIELD ": None", FIELD, \
+ FormatStyle::AlignConsecutiveStyle({})); \
+ CHECK_PARSE(#FIELD ": Consecutive", FIELD, \
+ FormatStyle::AlignConsecutiveStyle({/*.Enabled=*/true})); \
+ CHECK_PARSE(#FIELD ": AcrossEmptyLines", FIELD, \
+ FormatStyle::AlignConsecutiveStyle( \
+ {/*.Enabled=*/true, /*.AcrossEmptyLines=*/true})); \
+ CHECK_PARSE(#FIELD ": AcrossEmptyLinesAndComments", FIELD, \
+ FormatStyle::AlignConsecutiveStyle( \
+ {/*.Enabled=*/true, /*.AcrossEmptyLines=*/true, \
+ /*.AcrossComments=*/true})); \
+ /* For backwards compability, false / true should still parse */ \
+ CHECK_PARSE(#FIELD ": false", FIELD, \
+ FormatStyle::AlignConsecutiveStyle({})); \
+ CHECK_PARSE(#FIELD ": true", FIELD, \
+ FormatStyle::AlignConsecutiveStyle({/*.Enabled=*/true})); \
+ \
+ CHECK_PARSE_NESTED_BOOL(FIELD, Enabled); \
+ CHECK_PARSE_NESTED_BOOL(FIELD, AcrossEmptyLines); \
+ CHECK_PARSE_NESTED_BOOL(FIELD, AcrossComments); \
+ } while (false)
+
+ CHECK_ALIGN_CONSECUTIVE(AlignConsecutiveAssignments);
+ CHECK_ALIGN_CONSECUTIVE(AlignConsecutiveBitFields);
+ CHECK_ALIGN_CONSECUTIVE(AlignConsecutiveMacros);
+ CHECK_ALIGN_CONSECUTIVE(AlignConsecutiveDeclarations);
+
+#undef CHECK_ALIGN_CONSECUTIVE
Style.PointerAlignment = FormatStyle::PAS_Middle;
CHECK_PARSE("PointerAlignment: Left", PointerAlignment,
@@ -23202,7 +23279,7 @@
format("FOO(String-ized&Messy+But,: :\n"
" Still=Intentional);",
Style));
- Style.AlignConsecutiveAssignments = FormatStyle::ACS_Consecutive;
+ Style.AlignConsecutiveAssignments.Enabled = true;
EXPECT_EQ("FOO(String-ized=&Messy+But,: :\n"
" Still=Intentional);",
format("FOO(String-ized=&Messy+But,: :\n"
@@ -24027,7 +24104,7 @@
EXPECT_EQ(Source, format(Source, Style));
- Style.AlignConsecutiveDeclarations = FormatStyle::ACS_Consecutive;
+ Style.AlignConsecutiveDeclarations.Enabled = true;
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
@@ -267,10 +267,14 @@
}
// Align a single sequence of tokens, see AlignTokens below.
+// Column - The token for which Matches returns true is moved to this
+// column.
+// RightJustify - Whether it is the token's right end or left end that
+// gets moved to that column.
template <typename F>
static void
AlignTokenSequence(const FormatStyle &Style, unsigned Start, unsigned End,
- unsigned Column, F &&Matches,
+ unsigned Column, bool RightJustify, F &&Matches,
SmallVector<WhitespaceManager::Change, 16> &Changes) {
bool FoundMatchOnLine = false;
int Shift = 0;
@@ -329,7 +333,8 @@
// shifted by the same amount
if (!FoundMatchOnLine && !SkipMatchCheck && Matches(Changes[i])) {
FoundMatchOnLine = true;
- Shift = Column - Changes[i].StartOfTokenColumn;
+ Shift = Column - RightJustify * Changes[i].TokenLength -
+ Changes[i].StartOfTokenColumn;
Changes[i].Spaces += Shift;
// FIXME: This is a workaround that should be removed when we fix
// http://llvm.org/PR53699. An assertion later below verifies this.
@@ -456,13 +461,35 @@
// However, the special exception is that we do NOT skip function parameters
// that are split across multiple lines. See the test case in FormatTest.cpp
// that mentions "split function parameter alignment" for an example of this.
+// When the parameter RightJustify is true, the operator will be
+// right-justified. It is used to align compound assignments like `+=`
+// and `=`.
+// When RightJustify and PadAnchors are true, operators in each block to
+// be aligned will be padded on the left to the same length before
+// aligning.
template <typename F>
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;
+ const FormatStyle::AlignConsecutiveStyle &ACS = {},
+ bool RightJustify = false) {
+ // We arrange each line in 3 parts. The operator to be aligned (the
+ // anchor), and text to its left and right. In the aligned text the
+ // width of each part will be the maximum of that over the block that
+ // has been aligned.
+ // Maximum widths of each part so far.
+ // When RightJustify is true and ACS.PadOperators is false, the part
+ // from start of line to the right end of the anchor. Otherwise, only
+ // the part to the left of the anchor. Including the space that exists
+ // on its left from the start. Not including the padding added on the
+ // left to right-justify the anchor.
+ unsigned WidthLeft = 0;
+ // The operator to be aligned when RightJustify is true and
+ // ACS.PadOperators is false. 0 otherwise.
+ unsigned WidthAnchor = 0;
+ // Width to the right of the anchor. Plus width of the anchor when
+ // RightJustify is false.
+ unsigned WidthRight = 0;
// Line number of the start and the end of the current token sequence.
unsigned StartOfSequence = 0;
@@ -495,10 +522,12 @@
// containing any matching token to be aligned and located after such token.
auto AlignCurrentSequence = [&] {
if (StartOfSequence > 0 && StartOfSequence < EndOfSequence)
- AlignTokenSequence(Style, StartOfSequence, EndOfSequence, MinColumn,
- Matches, Changes);
- MinColumn = 0;
- MaxColumn = UINT_MAX;
+ AlignTokenSequence(Style, StartOfSequence, EndOfSequence,
+ WidthLeft + WidthAnchor, RightJustify, Matches,
+ Changes);
+ WidthLeft = 0;
+ WidthAnchor = 0;
+ WidthRight = 0;
StartOfSequence = 0;
EndOfSequence = 0;
};
@@ -514,17 +543,12 @@
// 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);
+ (Changes[i].NewlinesBefore > 1) && !ACS.AcrossEmptyLines;
// 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)));
+ !FoundMatchOnLine && !(LineIsComment && ACS.AcrossComments);
if (EmptyLineBreak || NoMatchBreak)
AlignCurrentSequence();
@@ -563,29 +587,44 @@
if (StartOfSequence == 0)
StartOfSequence = i;
- unsigned ChangeMinColumn = Changes[i].StartOfTokenColumn;
- int LineLengthAfter = Changes[i].TokenLength;
+ unsigned ChangeWidthLeft = Changes[i].StartOfTokenColumn;
+ unsigned ChangeWidthAnchor = 0;
+ unsigned ChangeWidthRight = 0;
+ if (RightJustify) {
+ if (ACS.PadOperators)
+ ChangeWidthAnchor = Changes[i].TokenLength;
+ else
+ ChangeWidthLeft += Changes[i].TokenLength;
+ } else
+ ChangeWidthRight = Changes[i].TokenLength;
for (unsigned j = i + 1; j != e && Changes[j].NewlinesBefore == 0; ++j) {
- LineLengthAfter += Changes[j].Spaces;
+ ChangeWidthRight += Changes[j].Spaces;
// Changes are generally 1:1 with the tokens, but a change could also be
// inside of a token, in which case it's counted more than once: once for
// the whitespace surrounding the token (!IsInsideToken) and once for
// each whitespace change within it (IsInsideToken).
// Therefore, changes inside of a token should only count the space.
if (!Changes[j].IsInsideToken)
- LineLengthAfter += Changes[j].TokenLength;
+ ChangeWidthRight += Changes[j].TokenLength;
}
- unsigned ChangeMaxColumn = Style.ColumnLimit - LineLengthAfter;
// If we are restricted by the maximum column width, end the sequence.
- if (ChangeMinColumn > MaxColumn || ChangeMaxColumn < MinColumn ||
- CommasBeforeLastMatch != CommasBeforeMatch) {
+ unsigned NewLeft = std::max(ChangeWidthLeft, WidthLeft);
+ unsigned NewAnchor = std::max(ChangeWidthAnchor, WidthAnchor);
+ unsigned NewRight = std::max(ChangeWidthRight, WidthRight);
+ // `ColumnLimit == 0` means there is no column limit.
+ if (Style.ColumnLimit != 0 &&
+ Style.ColumnLimit < NewLeft + NewAnchor + NewRight) {
AlignCurrentSequence();
StartOfSequence = i;
+ WidthLeft = ChangeWidthLeft;
+ WidthAnchor = ChangeWidthAnchor;
+ WidthRight = ChangeWidthRight;
+ } else {
+ WidthLeft = NewLeft;
+ WidthAnchor = NewAnchor;
+ WidthRight = NewRight;
}
-
- MinColumn = std::max(MinColumn, ChangeMinColumn);
- MaxColumn = std::min(MaxColumn, ChangeMaxColumn);
}
EndOfSequence = i;
@@ -639,7 +678,7 @@
}
void WhitespaceManager::alignConsecutiveMacros() {
- if (Style.AlignConsecutiveMacros == FormatStyle::ACS_None)
+ if (!Style.AlignConsecutiveMacros.Enabled)
return;
auto AlignMacrosMatches = [](const Change &C) {
@@ -690,20 +729,14 @@
EndOfSequence = I;
// 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);
+ bool EmptyLineBreak = (Changes[I].NewlinesBefore > 1) &&
+ !Style.AlignConsecutiveMacros.AcrossEmptyLines;
// 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)));
+ !(LineIsComment && Style.AlignConsecutiveMacros.AcrossComments);
if (EmptyLineBreak || NoMatchBreak)
AlignMacroSequence(StartOfSequence, EndOfSequence, MinColumn, MaxColumn,
@@ -741,7 +774,7 @@
}
void WhitespaceManager::alignConsecutiveAssignments() {
- if (Style.AlignConsecutiveAssignments == FormatStyle::ACS_None)
+ if (!Style.AlignConsecutiveAssignments.Enabled)
return;
AlignTokens(
@@ -760,13 +793,16 @@
if (Previous && Previous->is(tok::kw_operator))
return false;
- return C.Tok->is(tok::equal);
+ return Style.AlignConsecutiveAssignments.AlignCompound
+ ? C.Tok->getPrecedence() == prec::Assignment
+ : C.Tok->is(tok::equal);
},
- Changes, /*StartAt=*/0, Style.AlignConsecutiveAssignments);
+ Changes, /*StartAt=*/0, Style.AlignConsecutiveAssignments,
+ /*RightJustify=*/true);
}
void WhitespaceManager::alignConsecutiveBitFields() {
- if (Style.AlignConsecutiveBitFields == FormatStyle::ACS_None)
+ if (!Style.AlignConsecutiveBitFields.Enabled)
return;
AlignTokens(
@@ -786,7 +822,7 @@
}
void WhitespaceManager::alignConsecutiveDeclarations() {
- if (Style.AlignConsecutiveDeclarations == FormatStyle::ACS_None)
+ if (!Style.AlignConsecutiveDeclarations.Enabled)
return;
AlignTokens(
Index: clang/lib/Format/Format.cpp
===================================================================
--- clang/lib/Format/Format.cpp
+++ clang/lib/Format/Format.cpp
@@ -152,18 +152,35 @@
}
};
-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);
+template <> struct MappingTraits<FormatStyle::AlignConsecutiveStyle> {
+ static void enumInput(IO &IO, FormatStyle::AlignConsecutiveStyle &Value) {
+ IO.enumCase(Value, "None", FormatStyle::AlignConsecutiveStyle({}));
+ IO.enumCase(Value, "Consecutive",
+ FormatStyle::AlignConsecutiveStyle({/*.Enabled=*/true}));
+ IO.enumCase(Value, "AcrossEmptyLines",
+ FormatStyle::AlignConsecutiveStyle(
+ {/*.Enabled=*/true, /*.AcrossEmptyLines=*/true}));
+ IO.enumCase(Value, "AcrossComments",
+ FormatStyle::AlignConsecutiveStyle({/*.Enabled=*/true,
+ /*.AcrossEmptyLines=*/false,
+ /*.AcrossComments=*/true}));
IO.enumCase(Value, "AcrossEmptyLinesAndComments",
- FormatStyle::ACS_AcrossEmptyLinesAndComments);
+ FormatStyle::AlignConsecutiveStyle({/*.Enabled=*/true,
+ /*.AcrossEmptyLines=*/true,
+ /*.AcrossComments=*/true}));
// For backward compatibility.
- IO.enumCase(Value, "true", FormatStyle::ACS_Consecutive);
- IO.enumCase(Value, "false", FormatStyle::ACS_None);
+ IO.enumCase(Value, "true",
+ FormatStyle::AlignConsecutiveStyle({/*.Enabled=*/true}));
+ IO.enumCase(Value, "false", FormatStyle::AlignConsecutiveStyle({}));
+ }
+
+ static void mapping(IO &IO, FormatStyle::AlignConsecutiveStyle &Value) {
+ IO.mapOptional("Enabled", Value.Enabled);
+ IO.mapOptional("AcrossEmptyLines", Value.AcrossEmptyLines);
+ IO.mapOptional("AcrossComments", Value.AcrossComments);
+ IO.mapOptional("Aligncompound", Value.AlignCompound);
+ IO.mapOptional("PadOperators", Value.PadOperators);
}
};
@@ -600,13 +617,13 @@
IO.mapOptional("AccessModifierOffset", Style.AccessModifierOffset);
IO.mapOptional("AlignAfterOpenBracket", Style.AlignAfterOpenBracket);
IO.mapOptional("AlignArrayOfStructures", Style.AlignArrayOfStructures);
- IO.mapOptional("AlignConsecutiveMacros", Style.AlignConsecutiveMacros);
IO.mapOptional("AlignConsecutiveAssignments",
Style.AlignConsecutiveAssignments);
IO.mapOptional("AlignConsecutiveBitFields",
Style.AlignConsecutiveBitFields);
IO.mapOptional("AlignConsecutiveDeclarations",
Style.AlignConsecutiveDeclarations);
+ IO.mapOptional("AlignConsecutiveMacros", Style.AlignConsecutiveMacros);
IO.mapOptional("AlignEscapedNewlines", Style.AlignEscapedNewlines);
IO.mapOptional("AlignOperands", Style.AlignOperands);
IO.mapOptional("AlignTrailingComments", Style.AlignTrailingComments);
@@ -1140,10 +1157,13 @@
LLVMStyle.AlignArrayOfStructures = FormatStyle::AIAS_None;
LLVMStyle.AlignOperands = FormatStyle::OAS_Align;
LLVMStyle.AlignTrailingComments = true;
- LLVMStyle.AlignConsecutiveAssignments = FormatStyle::ACS_None;
- LLVMStyle.AlignConsecutiveBitFields = FormatStyle::ACS_None;
- LLVMStyle.AlignConsecutiveDeclarations = FormatStyle::ACS_None;
- LLVMStyle.AlignConsecutiveMacros = FormatStyle::ACS_None;
+ LLVMStyle.AlignConsecutiveAssignments = {
+ /*.Enabled=*/false, /*.AcrossEmptyLines=*/false,
+ /*.AcrossComments=*/false, /*.AlignCompound=*/false,
+ /*.PadOperators=*/true};
+ LLVMStyle.AlignConsecutiveBitFields = {};
+ LLVMStyle.AlignConsecutiveDeclarations = {};
+ LLVMStyle.AlignConsecutiveMacros = {};
LLVMStyle.AllowAllArgumentsOnNextLine = true;
LLVMStyle.AllowAllParametersOfDeclarationOnNextLine = true;
LLVMStyle.AllowShortEnumsOnASingleLine = true;
Index: clang/include/clang/Format/Format.h
===================================================================
--- clang/include/clang/Format/Format.h
+++ clang/include/clang/Format/Format.h
@@ -134,18 +134,115 @@
/// \version 13
ArrayInitializerAlignmentStyle AlignArrayOfStructures;
- /// 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
+ /// Options for aligning stuff.
+ ///
+ /// They can also be read as a whole for compatibility. The choices
+ /// are:
+ /// - None
+ /// - Consecutive
+ /// - AcrossEmptyLines
+ /// - AcrossComments
+ /// - AcrossEmptyLinesAndComments
+ ///
+ /// For example, to align across empty lines and not across comments,
+ /// either of these work.
+ /// \code
+ /// AlignConsecutiveMacros: AcrossEmptyLines
+ ///
+ /// AlignConsecutiveMacros:
+ /// Enabled: true
+ /// AcrossEmptyLines: true
+ /// AcrossComments: false
+ /// \endcode
+ struct AlignConsecutiveStyle {
+ /// Whether aligning is enabled.
+ /// \code
+ /// #define SHORT_NAME 42
+ /// #define LONGER_NAME 0x007f
+ /// #define EVEN_LONGER_NAME (2)
+ /// #define foo(x) (x * x)
+ /// #define bar(y, z) (y + z)
+ ///
+ /// int a = 1;
+ /// int somelongname = 2;
+ /// double c = 3;
+ ///
+ /// int aaaa : 1;
+ /// int b : 12;
+ /// int ccc : 8;
+ ///
+ /// int aaaa = 12;
+ /// float b = 23;
+ /// std::string ccc;
+ /// \endcode
+ bool Enabled;
+ /// Whether to align across empty lines.
+ /// \code
+ /// true:
+ /// int a = 1;
+ /// int somelongname = 2;
+ /// double c = 3;
+ ///
+ /// int d = 3;
+ ///
+ /// false:
+ /// int a = 1;
+ /// int somelongname = 2;
+ /// double c = 3;
+ ///
+ /// int d = 3;
+ /// \endcode
+ bool AcrossEmptyLines;
+ /// Whether to align across comments.
+ /// \code
+ /// true:
+ /// int d = 3;
+ /// /* A comment. */
+ /// double e = 4;
+ ///
+ /// false:
+ /// int d = 3;
+ /// /* A comment. */
+ /// double e = 4;
+ /// \endcode
+ bool AcrossComments;
+ /// Only for ``AlignConsecutiveAssignments``. Whether compound
+ /// assignments like ``+=``'s are aligned along with ``=``'s.
+ /// \code
+ /// true:
+ /// a &= 2;
+ /// bbb = 2;
+ ///
+ /// false:
+ /// a &= 2;
+ /// bbb = 2;
+ /// \endcode
+ bool AlignCompound;
+ /// Only for ``AlignConsecutiveAssignments``. Whether short
+ /// assignment operators are left-padded to the same length as long
+ /// ones in order to put all assignment operators to the right of
+ /// the left hand side.
+ /// \code
+ /// true:
+ /// a >>= 2;
+ /// bbb = 2;
+ ///
+ /// false:
+ /// a >>= 2;
+ /// bbb = 2;
+ ///
+ /// regardless of this option:
+ /// a = 2;
+ /// bbb >>= 2;
+ /// \endcode
+ bool PadOperators;
+ bool operator==(const AlignConsecutiveStyle &R) const {
+ return Enabled == R.Enabled && AcrossEmptyLines == R.AcrossEmptyLines &&
+ AcrossComments == R.AcrossComments;
+ }
+ bool operator!=(const AlignConsecutiveStyle &R) const {
+ return !(*this == R);
+ }
};
/// Style of aligning consecutive macro definitions.
@@ -158,67 +255,8 @@
/// #define foo(x) (x * x)
/// #define bar(y, z) (y + z)
/// \endcode
- ///
- /// 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
/// \version 9
AlignConsecutiveStyle AlignConsecutiveMacros;
-
/// Style of aligning consecutive assignments.
///
/// ``Consecutive`` will result in formattings like:
@@ -227,68 +265,9 @@
/// 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
/// \version 3.8
AlignConsecutiveStyle AlignConsecutiveAssignments;
-
- /// Style of aligning consecutive bit field.
+ /// Style of aligning consecutive bit fields.
///
/// ``Consecutive`` will align the bitfield separators of consecutive lines.
/// This will result in formattings like:
@@ -297,67 +276,8 @@
/// int b : 12;
/// int ccc : 8;
/// \endcode
- ///
- /// 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
/// \version 11
AlignConsecutiveStyle AlignConsecutiveBitFields;
-
/// Style of aligning consecutive declarations.
///
/// ``Consecutive`` will align the declaration names of consecutive lines.
@@ -367,64 +287,6 @@
/// float b = 23;
/// 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
/// \version 3.8
AlignConsecutiveStyle AlignConsecutiveDeclarations;
Index: clang/docs/tools/dump_format_style.py
===================================================================
--- clang/docs/tools/dump_format_style.py
+++ clang/docs/tools/dump_format_style.py
@@ -118,7 +118,7 @@
self.values = []
def __str__(self):
- return '\n'.join(map(str, self.values))
+ return self.comment + '\n' + '\n'.join(map(str, self.values))
class NestedField(object):
def __init__(self, name, comment):
Index: clang/docs/ClangFormatStyleOptions.rst
===================================================================
--- clang/docs/ClangFormatStyleOptions.rst
+++ clang/docs/ClangFormatStyleOptions.rst
@@ -278,70 +278,119 @@
int somelongname = 2;
double c = 3;
- Possible values:
+ Nested configuration flags:
- * ``ACS_None`` (in configuration: ``None``)
- Do not align assignments on consecutive lines.
+ Options for aligning stuff.
- * ``ACS_Consecutive`` (in configuration: ``Consecutive``)
- Align assignments on consecutive lines. This will result in
- formattings like:
+ They can also be read as a whole for compatibility. The choices
+ are:
+ - None
+ - Consecutive
+ - AcrossEmptyLines
+ - AcrossComments
+ - AcrossEmptyLinesAndComments
- .. code-block:: c++
+ For example, to align across empty lines and not across comments,
+ either of these work.
- int a = 1;
- int somelongname = 2;
- double c = 3;
+ .. code-block:: c++
- int d = 3;
- /* A comment. */
- double e = 4;
+ AlignConsecutiveMacros: AcrossEmptyLines
- * ``ACS_AcrossEmptyLines`` (in configuration: ``AcrossEmptyLines``)
- Same as ACS_Consecutive, but also spans over empty lines, e.g.
+ AlignConsecutiveMacros:
+ Enabled: true
+ AcrossEmptyLines: true
+ AcrossComments: false
- .. code-block:: c++
+ * ``bool Enabled`` Whether aligning is enabled.
- int a = 1;
- int somelongname = 2;
- double c = 3;
+ .. code-block:: c++
- int d = 3;
- /* A comment. */
- double e = 4;
+ #define SHORT_NAME 42
+ #define LONGER_NAME 0x007f
+ #define EVEN_LONGER_NAME (2)
+ #define foo(x) (x * x)
+ #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.
+ int a = 1;
+ int somelongname = 2;
+ double c = 3;
- .. code-block:: c++
+ int aaaa : 1;
+ int b : 12;
+ int ccc : 8;
- int a = 1;
- int somelongname = 2;
- double c = 3;
+ int aaaa = 12;
+ float b = 23;
+ std::string ccc;
- int d = 3;
- /* A comment. */
- double e = 4;
+ * ``bool AcrossEmptyLines`` Whether to align across empty lines.
- * ``ACS_AcrossEmptyLinesAndComments``
- (in configuration: ``AcrossEmptyLinesAndComments``)
+ .. code-block:: c++
- Same as ACS_Consecutive, but also spans over lines only containing
- comments and empty lines, e.g.
+ true:
+ int a = 1;
+ int somelongname = 2;
+ double c = 3;
+
+ int d = 3;
+
+ false:
+ int a = 1;
+ int somelongname = 2;
+ double c = 3;
- .. code-block:: c++
+ int d = 3;
- int a = 1;
- int somelongname = 2;
- double c = 3;
+ * ``bool AcrossComments`` Whether to align across comments.
+
+ .. code-block:: c++
+
+ true:
+ int d = 3;
+ /* A comment. */
+ double e = 4;
+
+ false:
+ int d = 3;
+ /* A comment. */
+ double e = 4;
+
+ * ``bool AlignCompound`` Only for ``AlignConsecutiveAssignments``. Whether compound
+ assignments like ``+=``'s are aligned along with ``=``'s.
+
+ .. code-block:: c++
+
+ true:
+ a &= 2;
+ bbb = 2;
+
+ false:
+ a &= 2;
+ bbb = 2;
+
+ * ``bool PadOperators`` Only for ``AlignConsecutiveAssignments``. Whether short
+ assignment operators are left-padded to the same length as long
+ ones in order to put all assignment operators to the right of
+ the left hand side.
+
+ .. code-block:: c++
+
+ true:
+ a >>= 2;
+ bbb = 2;
+
+ false:
+ a >>= 2;
+ bbb = 2;
+
+ regardless of this option:
+ a = 2;
+ bbb >>= 2;
- int d = 3;
- /* A comment. */
- double e = 4;
**AlignConsecutiveBitFields** (``AlignConsecutiveStyle``) :versionbadge:`clang-format 11`
- Style of aligning consecutive bit field.
+ Style of aligning consecutive bit fields.
``Consecutive`` will align the bitfield separators of consecutive lines.
This will result in formattings like:
@@ -352,67 +401,116 @@
int b : 12;
int ccc : 8;
- Possible values:
+ Nested configuration flags:
+
+ Options for aligning stuff.
- * ``ACS_None`` (in configuration: ``None``)
- Do not align bit fields on consecutive lines.
+ They can also be read as a whole for compatibility. The choices
+ are:
+ - None
+ - Consecutive
+ - AcrossEmptyLines
+ - AcrossComments
+ - AcrossEmptyLinesAndComments
- * ``ACS_Consecutive`` (in configuration: ``Consecutive``)
- Align bit fields on consecutive lines. This will result in
- formattings like:
+ For example, to align across empty lines and not across comments,
+ either of these work.
- .. code-block:: c++
+ .. code-block:: c++
- int aaaa : 1;
- int b : 12;
- int ccc : 8;
+ AlignConsecutiveMacros: AcrossEmptyLines
- int d : 2;
- /* A comment. */
- int ee : 3;
+ AlignConsecutiveMacros:
+ Enabled: true
+ AcrossEmptyLines: true
+ AcrossComments: false
- * ``ACS_AcrossEmptyLines`` (in configuration: ``AcrossEmptyLines``)
- Same as ACS_Consecutive, but also spans over empty lines, e.g.
+ * ``bool Enabled`` Whether aligning is enabled.
- .. code-block:: c++
+ .. code-block:: c++
- int aaaa : 1;
- int b : 12;
- int ccc : 8;
+ #define SHORT_NAME 42
+ #define LONGER_NAME 0x007f
+ #define EVEN_LONGER_NAME (2)
+ #define foo(x) (x * x)
+ #define bar(y, z) (y + z)
- int d : 2;
- /* A comment. */
- int ee : 3;
+ int a = 1;
+ int somelongname = 2;
+ double c = 3;
- * ``ACS_AcrossComments`` (in configuration: ``AcrossComments``)
- Same as ACS_Consecutive, but also spans over lines only containing
- comments, e.g.
+ int aaaa : 1;
+ int b : 12;
+ int ccc : 8;
- .. code-block:: c++
+ int aaaa = 12;
+ float b = 23;
+ std::string ccc;
- int aaaa : 1;
- int b : 12;
- int ccc : 8;
+ * ``bool AcrossEmptyLines`` Whether to align across empty lines.
- int d : 2;
- /* A comment. */
- int ee : 3;
+ .. code-block:: c++
- * ``ACS_AcrossEmptyLinesAndComments``
- (in configuration: ``AcrossEmptyLinesAndComments``)
+ true:
+ int a = 1;
+ int somelongname = 2;
+ double c = 3;
- Same as ACS_Consecutive, but also spans over lines only containing
- comments and empty lines, e.g.
+ int d = 3;
- .. code-block:: c++
+ false:
+ int a = 1;
+ int somelongname = 2;
+ double c = 3;
- int aaaa : 1;
- int b : 12;
- int ccc : 8;
+ int d = 3;
+
+ * ``bool AcrossComments`` Whether to align across comments.
+
+ .. code-block:: c++
+
+ true:
+ int d = 3;
+ /* A comment. */
+ double e = 4;
+
+ false:
+ int d = 3;
+ /* A comment. */
+ double e = 4;
+
+ * ``bool AlignCompound`` Only for ``AlignConsecutiveAssignments``. Whether compound
+ assignments like ``+=``'s are aligned along with ``=``'s.
+
+ .. code-block:: c++
+
+ true:
+ a &= 2;
+ bbb = 2;
+
+ false:
+ a &= 2;
+ bbb = 2;
+
+ * ``bool PadOperators`` Only for ``AlignConsecutiveAssignments``. Whether short
+ assignment operators are left-padded to the same length as long
+ ones in order to put all assignment operators to the right of
+ the left hand side.
+
+ .. code-block:: c++
+
+ true:
+ a >>= 2;
+ bbb = 2;
+
+ false:
+ a >>= 2;
+ bbb = 2;
+
+ regardless of this option:
+ a = 2;
+ bbb >>= 2;
- int d : 2;
- /* A comment. */
- int ee : 3;
**AlignConsecutiveDeclarations** (``AlignConsecutiveStyle``) :versionbadge:`clang-format 3.8`
Style of aligning consecutive declarations.
@@ -426,67 +524,116 @@
float b = 23;
std::string ccc;
- Possible values:
+ Nested configuration flags:
+
+ Options for aligning stuff.
+
+ They can also be read as a whole for compatibility. The choices
+ are:
+ - None
+ - Consecutive
+ - AcrossEmptyLines
+ - AcrossComments
+ - AcrossEmptyLinesAndComments
+
+ For example, to align across empty lines and not across comments,
+ either of these work.
+
+ .. code-block:: c++
- * ``ACS_None`` (in configuration: ``None``)
- Do not align bit declarations on consecutive lines.
+ AlignConsecutiveMacros: AcrossEmptyLines
- * ``ACS_Consecutive`` (in configuration: ``Consecutive``)
- Align declarations on consecutive lines. This will result in
- formattings like:
+ AlignConsecutiveMacros:
+ Enabled: true
+ AcrossEmptyLines: true
+ AcrossComments: false
- .. code-block:: c++
+ * ``bool Enabled`` Whether aligning is enabled.
- int aaaa = 12;
- float b = 23;
- std::string ccc;
+ .. code-block:: c++
- int a = 42;
- /* A comment. */
- bool c = false;
+ #define SHORT_NAME 42
+ #define LONGER_NAME 0x007f
+ #define EVEN_LONGER_NAME (2)
+ #define foo(x) (x * x)
+ #define bar(y, z) (y + z)
- * ``ACS_AcrossEmptyLines`` (in configuration: ``AcrossEmptyLines``)
- Same as ACS_Consecutive, but also spans over empty lines, e.g.
+ int a = 1;
+ int somelongname = 2;
+ double c = 3;
- .. code-block:: c++
+ int aaaa : 1;
+ int b : 12;
+ int ccc : 8;
- int aaaa = 12;
- float b = 23;
- std::string ccc;
+ int aaaa = 12;
+ float b = 23;
+ std::string ccc;
- int a = 42;
- /* A comment. */
- bool c = false;
+ * ``bool AcrossEmptyLines`` Whether to align across empty lines.
- * ``ACS_AcrossComments`` (in configuration: ``AcrossComments``)
- Same as ACS_Consecutive, but also spans over lines only containing
- comments, e.g.
+ .. code-block:: c++
- .. code-block:: c++
+ true:
+ int a = 1;
+ int somelongname = 2;
+ double c = 3;
- int aaaa = 12;
- float b = 23;
- std::string ccc;
+ int d = 3;
- int a = 42;
- /* A comment. */
- bool c = false;
+ false:
+ int a = 1;
+ int somelongname = 2;
+ double c = 3;
- * ``ACS_AcrossEmptyLinesAndComments``
- (in configuration: ``AcrossEmptyLinesAndComments``)
+ int d = 3;
- Same as ACS_Consecutive, but also spans over lines only containing
- comments and empty lines, e.g.
+ * ``bool AcrossComments`` Whether to align across comments.
- .. code-block:: c++
+ .. code-block:: c++
+
+ true:
+ int d = 3;
+ /* A comment. */
+ double e = 4;
- int aaaa = 12;
- float b = 23;
- std::string ccc;
+ false:
+ int d = 3;
+ /* A comment. */
+ double e = 4;
+
+ * ``bool AlignCompound`` Only for ``AlignConsecutiveAssignments``. Whether compound
+ assignments like ``+=``'s are aligned along with ``=``'s.
+
+ .. code-block:: c++
+
+ true:
+ a &= 2;
+ bbb = 2;
+
+ false:
+ a &= 2;
+ bbb = 2;
+
+ * ``bool PadOperators`` Only for ``AlignConsecutiveAssignments``. Whether short
+ assignment operators are left-padded to the same length as long
+ ones in order to put all assignment operators to the right of
+ the left hand side.
+
+ .. code-block:: c++
+
+ true:
+ a >>= 2;
+ bbb = 2;
+
+ false:
+ a >>= 2;
+ bbb = 2;
+
+ regardless of this option:
+ a = 2;
+ bbb >>= 2;
- int a = 42;
- /* A comment. */
- bool c = false;
**AlignConsecutiveMacros** (``AlignConsecutiveStyle``) :versionbadge:`clang-format 9`
Style of aligning consecutive macro definitions.
@@ -501,67 +648,116 @@
#define foo(x) (x * x)
#define bar(y, z) (y + z)
- Possible values:
+ Nested configuration flags:
+
+ Options for aligning stuff.
+
+ They can also be read as a whole for compatibility. The choices
+ are:
+ - None
+ - Consecutive
+ - AcrossEmptyLines
+ - AcrossComments
+ - AcrossEmptyLinesAndComments
+
+ For example, to align across empty lines and not across comments,
+ either of these work.
+
+ .. code-block:: c++
+
+ AlignConsecutiveMacros: AcrossEmptyLines
+
+ AlignConsecutiveMacros:
+ Enabled: true
+ AcrossEmptyLines: true
+ AcrossComments: false
- * ``ACS_None`` (in configuration: ``None``)
- Do not align macro definitions on consecutive lines.
+ * ``bool Enabled`` Whether aligning is enabled.
- * ``ACS_Consecutive`` (in configuration: ``Consecutive``)
- Align macro definitions on consecutive lines. This will result in
- formattings like:
+ .. code-block:: c++
- .. code-block:: c++
+ #define SHORT_NAME 42
+ #define LONGER_NAME 0x007f
+ #define EVEN_LONGER_NAME (2)
+ #define foo(x) (x * x)
+ #define bar(y, z) (y + z)
- #define SHORT_NAME 42
- #define LONGER_NAME 0x007f
- #define EVEN_LONGER_NAME (2)
+ int a = 1;
+ int somelongname = 2;
+ double c = 3;
- #define foo(x) (x * x)
- /* some comment */
- #define bar(y, z) (y + z)
+ int aaaa : 1;
+ int b : 12;
+ int ccc : 8;
- * ``ACS_AcrossEmptyLines`` (in configuration: ``AcrossEmptyLines``)
- Same as ACS_Consecutive, but also spans over empty lines, e.g.
+ int aaaa = 12;
+ float b = 23;
+ std::string ccc;
- .. code-block:: c++
+ * ``bool AcrossEmptyLines`` Whether to align across empty lines.
- #define SHORT_NAME 42
- #define LONGER_NAME 0x007f
- #define EVEN_LONGER_NAME (2)
+ .. code-block:: c++
- #define foo(x) (x * x)
- /* some comment */
- #define bar(y, z) (y + z)
+ true:
+ int a = 1;
+ int somelongname = 2;
+ double c = 3;
- * ``ACS_AcrossComments`` (in configuration: ``AcrossComments``)
- Same as ACS_Consecutive, but also spans over lines only containing
- comments, e.g.
+ int d = 3;
- .. code-block:: c++
+ false:
+ int a = 1;
+ int somelongname = 2;
+ double c = 3;
- #define SHORT_NAME 42
- #define LONGER_NAME 0x007f
- #define EVEN_LONGER_NAME (2)
+ int d = 3;
- #define foo(x) (x * x)
- /* some comment */
- #define bar(y, z) (y + z)
+ * ``bool AcrossComments`` Whether to align across comments.
- * ``ACS_AcrossEmptyLinesAndComments``
- (in configuration: ``AcrossEmptyLinesAndComments``)
+ .. code-block:: c++
- Same as ACS_Consecutive, but also spans over lines only containing
- comments and empty lines, e.g.
+ true:
+ int d = 3;
+ /* A comment. */
+ double e = 4;
+
+ false:
+ int d = 3;
+ /* A comment. */
+ double e = 4;
- .. code-block:: c++
+ * ``bool AlignCompound`` Only for ``AlignConsecutiveAssignments``. Whether compound
+ assignments like ``+=``'s are aligned along with ``=``'s.
- #define SHORT_NAME 42
- #define LONGER_NAME 0x007f
- #define EVEN_LONGER_NAME (2)
+ .. code-block:: c++
+
+ true:
+ a &= 2;
+ bbb = 2;
+
+ false:
+ a &= 2;
+ bbb = 2;
+
+ * ``bool PadOperators`` Only for ``AlignConsecutiveAssignments``. Whether short
+ assignment operators are left-padded to the same length as long
+ ones in order to put all assignment operators to the right of
+ the left hand side.
+
+ .. code-block:: c++
+
+ true:
+ a >>= 2;
+ bbb = 2;
+
+ false:
+ a >>= 2;
+ bbb = 2;
+
+ regardless of this option:
+ a = 2;
+ bbb >>= 2;
- #define foo(x) (x * x)
- /* some comment */
- #define bar(y, z) (y + z)
**AlignEscapedNewlines** (``EscapedNewlineAlignmentStyle``) :versionbadge:`clang-format 5`
Options for aligning backslashes in escaped newlines.
@@ -1209,6 +1405,14 @@
Nested configuration flags:
+ Precise control over the wrapping of braces.
+
+ .. code-block:: c++
+
+ # Should be declared this way:
+ BreakBeforeBraces: Custom
+ BraceWrapping:
+ AfterClass: true
* ``bool AfterCaseLabel`` Wrap case labels.
@@ -3956,6 +4160,15 @@
Nested configuration flags:
+ Precise control over the spacing before parentheses.
+
+ .. code-block:: c++
+
+ # Should be declared this way:
+ SpaceBeforeParens: Custom
+ SpaceBeforeParensOptions:
+ AfterControlStatements: true
+ AfterFunctionDefinitionName: true
* ``bool AfterControlStatements`` If ``true``, put space betwee control statement keywords
(for/if/while...) and opening parentheses.
@@ -4185,6 +4398,7 @@
Nested configuration flags:
+ Control of spaces within a single line comment
* ``unsigned Minimum`` The minimum number of spaces at the start of the comment.
_______________________________________________
cfe-commits mailing list
[email protected]
https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits