Index: clang/docs/ClangFormatStyleOptions.rst =================================================================== --- clang/docs/ClangFormatStyleOptions.rst +++ clang/docs/ClangFormatStyleOptions.rst @@ -204,6 +204,18 @@ int b = 23; int ccc = 23; +**AlignConsecutiveBitFields** (``bool``) + If ``true``, aligns consecutive bitfields. + + This will align the bitfield declaration of consecutive lines. This + will result in formattings like + + .. code-block:: c++ + + bool aaaa : 1; + bool b : 1; + bool ccc : 1; + **AlignConsecutiveDeclarations** (``bool``) If ``true``, aligns consecutive declarations. Index: clang/docs/ReleaseNotes.rst =================================================================== --- clang/docs/ReleaseNotes.rst +++ clang/docs/ReleaseNotes.rst @@ -297,6 +297,21 @@ 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 -------- Index: clang/include/clang/Format/Format.h =================================================================== --- clang/include/clang/Format/Format.h +++ clang/include/clang/Format/Format.h @@ -108,6 +108,17 @@ /// \endcode bool AlignConsecutiveAssignments; + /// If ``true``, aligns consecutive bitfields. + /// + /// This will align the bitfield declaration of consecutive lines. This + /// will result in formattings like + /// \code + /// bool aaaa : 1; + /// bool b : 1; + /// bool ccc : 1; + /// \endcode + bool AlignConsecutiveBitFields; + /// If ``true``, aligns consecutive declarations. /// /// This will align the declaration names of consecutive lines. This @@ -1984,8 +1995,8 @@ /// \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(...) { @@ -2191,6 +2202,7 @@ return AccessModifierOffset == R.AccessModifierOffset && AlignAfterOpenBracket == R.AlignAfterOpenBracket && AlignConsecutiveAssignments == R.AlignConsecutiveAssignments && + AlignConsecutiveBitFields == R.AlignConsecutiveBitFields && AlignConsecutiveDeclarations == R.AlignConsecutiveDeclarations && AlignEscapedNewlines == R.AlignEscapedNewlines && AlignOperands == R.AlignOperands && Index: clang/lib/Format/Format.cpp =================================================================== --- clang/lib/Format/Format.cpp +++ clang/lib/Format/Format.cpp @@ -387,14 +387,18 @@ IO.mapOptional("AccessModifierOffset", Style.AccessModifierOffset); IO.mapOptional("AlignAfterOpenBracket", Style.AlignAfterOpenBracket); - 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); + IO.mapOptional("AllowAllArgumentsOnNextLine", Style.AllowAllArgumentsOnNextLine); IO.mapOptional("AllowAllConstructorInitializersOnNextLine", @@ -753,6 +757,7 @@ LLVMStyle.AlignOperands = true; LLVMStyle.AlignTrailingComments = true; LLVMStyle.AlignConsecutiveAssignments = false; + LLVMStyle.AlignConsecutiveBitFields = false; LLVMStyle.AlignConsecutiveDeclarations = false; LLVMStyle.AlignConsecutiveMacros = false; LLVMStyle.AllowAllArgumentsOnNextLine = true; Index: clang/lib/Format/WhitespaceManager.h =================================================================== --- clang/lib/Format/WhitespaceManager.h +++ clang/lib/Format/WhitespaceManager.h @@ -178,6 +178,9 @@ /// 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(); Index: clang/lib/Format/WhitespaceManager.cpp =================================================================== --- clang/lib/Format/WhitespaceManager.cpp +++ clang/lib/Format/WhitespaceManager.cpp @@ -95,6 +95,7 @@ alignConsecutiveMacros(); alignConsecutiveDeclarations(); alignConsecutiveAssignments(); + alignConsecutiveBitFields(); alignTrailingComments(); alignEscapedNewlines(); generateChanges(); @@ -574,6 +575,22 @@ Changes, /*StartAt=*/0); } +void WhitespaceManager::alignConsecutiveBitFields() { + if (!Style.AlignConsecutiveBitFields) + return; + + AlignTokens( + Style, + [&](const Change &C) { + if (!C.Tok->Previous) + return false; + + return C.Tok->Previous->startsSequence(tok::identifier, tok::colon, + tok::numeric_constant); + }, + Changes, /*StartAt=*/0); +} + void WhitespaceManager::alignConsecutiveDeclarations() { if (!Style.AlignConsecutiveDeclarations) return; Index: clang/unittests/Format/FormatTest.cpp =================================================================== --- clang/unittests/Format/FormatTest.cpp +++ clang/unittests/Format/FormatTest.cpp @@ -13005,6 +13005,7 @@ CHECK_PARSE_BOOL(AlignOperands); CHECK_PARSE_BOOL(AlignTrailingComments); CHECK_PARSE_BOOL(AlignConsecutiveAssignments); + CHECK_PARSE_BOOL(AlignConsecutiveBitFields); CHECK_PARSE_BOOL(AlignConsecutiveDeclarations); CHECK_PARSE_BOOL(AlignConsecutiveMacros); CHECK_PARSE_BOOL(AllowAllArgumentsOnNextLine); @@ -15849,6 +15850,22 @@ verifyFormat("operator&&(int(&&)(), class Foo);", Style); } +TEST_F(FormatTest, AlignConsecutiveBitFields) { + FormatStyle Alignment = getLLVMStyle(); + Alignment.AlignConsecutiveMacros = false; + Alignment.AlignConsecutiveAssignments = false; + Alignment.AlignConsecutiveBitFields = false; + + verifyFormat("bool a : 1;\n" + "bool oneTwoThree : 1;", + Alignment); + + Alignment.AlignConsecutiveBitFields = true; + verifyFormat("bool a : 1;\n" + "bool oneTwoThree : 1;", + Alignment); +} + } // namespace } // namespace format } // namespace clang