int b = 23;
int ccc = 23;
+**AlignConsecutiveBitFields** (``bool``)
+ If ``true``, aligns consecutive bitfield members.
+
+ This will align the bitfield separators of consecutive lines. This
+ will result in formattings like
+
+ .. code-block:: c++
+
+ int aaaa : 1;
+ int b : 12;
+ int ccc : 8;
+
**AlignConsecutiveDeclarations** (``bool``)
If ``true``, aligns consecutive declarations.
bar();
});
+- Option ``AlignConsecutiveBitFields`` has been added to align bit field
+ declarations across multiple adjacent lines
+
+ .. code-block:: c++
+
+ true:
+ bool aaa : 1;
+ bool a : 1;
+ bool bb : 1;
+
+ false:
+ bool aaa : 1;
+ bool a : 1;
+ bool bb : 1;
+
libclang
--------
/// \endcode
bool AlignConsecutiveAssignments;
+ /// If ``true``, aligns consecutive bitfield members.
+ ///
+ /// This 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
/// \endcode
SBPO_ControlStatements,
/// Same as ``SBPO_ControlStatements`` except this option doesn't apply to
- /// ForEach macros. This is useful in projects where ForEach macros are
- /// treated as function calls instead of control statements.
+ /// ForEach macros. This is useful in projects where ForEach macros are
+ /// treated as function calls instead of control statements.
/// \code
/// void f() {
/// Q_FOREACH(...) {
return AccessModifierOffset == R.AccessModifierOffset &&
AlignAfterOpenBracket == R.AlignAfterOpenBracket &&
AlignConsecutiveAssignments == R.AlignConsecutiveAssignments &&
+ AlignConsecutiveBitFields == R.AlignConsecutiveBitFields &&
AlignConsecutiveDeclarations == R.AlignConsecutiveDeclarations &&
AlignEscapedNewlines == R.AlignEscapedNewlines &&
AlignOperands == R.AlignOperands &&
IO.mapOptional("AlignConsecutiveMacros", Style.AlignConsecutiveMacros);
IO.mapOptional("AlignConsecutiveAssignments",
Style.AlignConsecutiveAssignments);
+ IO.mapOptional("AlignConsecutiveBitFields",
+ Style.AlignConsecutiveBitFields);
IO.mapOptional("AlignConsecutiveDeclarations",
Style.AlignConsecutiveDeclarations);
IO.mapOptional("AlignEscapedNewlines", Style.AlignEscapedNewlines);
LLVMStyle.AlignOperands = FormatStyle::OAS_Align;
LLVMStyle.AlignTrailingComments = true;
LLVMStyle.AlignConsecutiveAssignments = false;
+ LLVMStyle.AlignConsecutiveBitFields = false;
LLVMStyle.AlignConsecutiveDeclarations = false;
LLVMStyle.AlignConsecutiveMacros = false;
LLVMStyle.AllowAllArgumentsOnNextLine = true;
calculateLineBreakInformation();
alignConsecutiveMacros();
alignConsecutiveDeclarations();
+ alignConsecutiveBitFields();
alignConsecutiveAssignments();
alignChainedConditionals();
alignTrailingComments();
Changes, /*StartAt=*/0);
}
+void WhitespaceManager::alignConsecutiveBitFields() {
+ if (!Style.AlignConsecutiveBitFields)
+ return;
+
+ AlignTokens(
+ Style,
+ [&](Change const &C) {
+ // Do not align on ':' that is first on a line.
+ if (C.NewlinesBefore > 0)
+ return false;
+
+ // Do not align on ':' that is last on a line.
+ if (&C != &Changes.back() && (&C + 1)->NewlinesBefore > 0)
+ return false;
+
+ return C.Tok->is(TT_BitFieldColon);
+ },
+ Changes, /*StartAt=*/0);
+}
+
void WhitespaceManager::alignConsecutiveDeclarations() {
if (!Style.AlignConsecutiveDeclarations)
return;
/// Align consecutive assignments over all \c Changes.
void alignConsecutiveAssignments();
+ /// Align consecutive bitfields over all \c Changes.
+ void alignConsecutiveBitFields();
+
/// Align consecutive declarations over all \c Changes.
void alignConsecutiveDeclarations();
Alignment));
}
+TEST_F(FormatTest, AlignConsecutiveBitFields) {
+ FormatStyle Alignment = getLLVMStyle();
+ Alignment.AlignConsecutiveBitFields = true;
+ verifyFormat("int const a : 5;\n"
+ "int oneTwoThree : 23;",
+ Alignment);
+
+ // Initializers are allowed starting with c++2a
+ verifyFormat("int const a : 5 = 1;\n"
+ "int oneTwoThree : 23 = 0;",
+ Alignment);
+
+ Alignment.AlignConsecutiveDeclarations = true;
+ verifyFormat("int const a : 5;\n"
+ "int oneTwoThree : 23;",
+ Alignment);
+
+ verifyFormat("int const a : 5; // comment\n"
+ "int oneTwoThree : 23; // comment",
+ Alignment);
+
+ verifyFormat("int const a : 5 = 1;\n"
+ "int oneTwoThree : 23 = 0;",
+ Alignment);
+
+ Alignment.AlignConsecutiveAssignments = true;
+ verifyFormat("int const a : 5 = 1;\n"
+ "int oneTwoThree : 23 = 0;",
+ Alignment);
+ verifyFormat("int const a : 5 = {1};\n"
+ "int oneTwoThree : 23 = 0;",
+ Alignment);
+
+ // Known limitations: ':' is only recognized as a bitfield colon when
+ // followed by a number.
+ /*
+ verifyFormat("int oneTwoThree : SOME_CONSTANT;\n"
+ "int a : 5;",
+ Alignment);
+ */
+}
+
TEST_F(FormatTest, AlignConsecutiveDeclarations) {
FormatStyle Alignment = getLLVMStyle();
Alignment.AlignConsecutiveMacros = true;
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);