Index: docs/ClangFormatStyleOptions.rst =================================================================== --- docs/ClangFormatStyleOptions.rst +++ docs/ClangFormatStyleOptions.rst @@ -190,8 +190,6 @@ someLongFunction( argument1, argument2); - - **AlignConsecutiveAssignments** (``bool``) If ``true``, aligns consecutive assignments. @@ -686,6 +684,18 @@ int aaaaaaaaaaaaaaaaaaaa, int aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa) {} +**BitFieldDeclarationsOnePerLine** (``bool``) + If ``true``, Align Bitfield Declarations on separate lines. + + This will align Bitfield declarations on consecutive lines. This + will result in formatting like: + + .. code-block:: c++ + + unsigned int baz : 1, + fuz : 5, + zap : 2; + **BraceWrapping** (``BraceWrappingFlags``) Control of individual brace wrapping cases. Index: include/clang/Format/Format.h =================================================================== --- include/clang/Format/Format.h +++ include/clang/Format/Format.h @@ -101,6 +101,16 @@ /// \endcode bool AlignConsecutiveDeclarations; + /// If ``true``, Linesup Bitfield Declarations. + /// This will lineup Bitfield declarations on consecutive lines. This + /// will result in formatting like + /// \code + /// unsigned int baz : 1, /* Bitfield; line up entries if desire*/ + /// fuz : 5, + /// zap : 2; + /// \endcode + bool BitFieldDeclarationsOnePerLine; + /// Different styles for aligning escaped newlines. enum EscapedNewlineAlignmentStyle { /// Don't align escaped newlines. @@ -1918,6 +1928,7 @@ R.AlwaysBreakTemplateDeclarations && BinPackArguments == R.BinPackArguments && BinPackParameters == R.BinPackParameters && + BitFieldDeclarationsOnePerLine == R.BitFieldDeclarationsOnePerLine && BreakBeforeBinaryOperators == R.BreakBeforeBinaryOperators && BreakBeforeBraces == R.BreakBeforeBraces && BreakBeforeTernaryOperators == R.BreakBeforeTernaryOperators && Index: lib/Format/ContinuationIndenter.cpp =================================================================== --- lib/Format/ContinuationIndenter.cpp +++ lib/Format/ContinuationIndenter.cpp @@ -329,6 +329,8 @@ bool ContinuationIndenter::mustBreak(const LineState &State) { const FormatToken &Current = *State.NextToken; const FormatToken &Previous = *Current.Previous; + if (Style.isCpp() && Current.isBitField() && Style.BitFieldDeclarationsOnePerLine) + return true; if (Current.MustBreakBefore || Current.is(TT_InlineASMColon)) return true; if (State.Stack.back().BreakBeforeClosingBrace && @@ -541,7 +543,7 @@ unsigned ExtraSpaces) { FormatToken &Current = *State.NextToken; const FormatToken &Previous = *State.NextToken->Previous; - if (Current.is(tok::equal) && + if (Current.isOneOf(tok::equal, tok::colon) && (State.Line->First->is(tok::kw_for) || Current.NestingLevel == 0) && State.Stack.back().VariablePos == 0) { State.Stack.back().VariablePos = State.Column; Index: lib/Format/Format.cpp =================================================================== --- lib/Format/Format.cpp +++ lib/Format/Format.cpp @@ -451,6 +451,7 @@ IO.mapOptional("JavaScriptWrapImports", Style.JavaScriptWrapImports); IO.mapOptional("KeepEmptyLinesAtTheStartOfBlocks", Style.KeepEmptyLinesAtTheStartOfBlocks); + IO.mapOptional("BitFieldDeclarationsOnePerLine", Style.BitFieldDeclarationsOnePerLine); IO.mapOptional("MacroBlockBegin", Style.MacroBlockBegin); IO.mapOptional("MacroBlockEnd", Style.MacroBlockEnd); IO.mapOptional("MaxEmptyLinesToKeep", Style.MaxEmptyLinesToKeep); Index: lib/Format/FormatToken.h =================================================================== --- lib/Format/FormatToken.h +++ lib/Format/FormatToken.h @@ -516,6 +516,14 @@ return T && T->is(tok::kw_auto); } + /// Returns whether the token is a Bit field, and checks whether + /// the Style is C / C++. + bool isBitField() const { + const FormatToken *T = this; + T = T->getPreviousNonComment(); + return (T->Tok.is(tok::comma) && Tok.is(tok::identifier) && + T->Next->Tok.is(tok::colon)); + } /// Same as opensBlockOrBlockTypeList, but for the closing token. bool closesBlockOrBlockTypeList(const FormatStyle &Style) const { if (is(TT_TemplateString) && closesScope()) Index: lib/Format/TokenAnnotator.cpp =================================================================== --- lib/Format/TokenAnnotator.cpp +++ lib/Format/TokenAnnotator.cpp @@ -2916,6 +2916,9 @@ bool TokenAnnotator::mustBreakBefore(const AnnotatedLine &Line, const FormatToken &Right) { const FormatToken &Left = *Right.Previous; + if (Right.Previous->is(tok::comma) && Style.BitFieldDeclarationsOnePerLine && + Right.is(tok::identifier) && (Right.Next->is(tok::colon))) + return true; if (Right.NewlinesBefore > 1 && Style.MaxEmptyLinesToKeep > 0) return true; Index: unittests/Format/FormatTest.cpp =================================================================== --- unittests/Format/FormatTest.cpp +++ unittests/Format/FormatTest.cpp @@ -3656,6 +3656,19 @@ "#define A Just forcing a new line\n" " ddd);"); } +TEST_F(FormatTest, AlignBitFieldDeclarationsOnConsecutiveLines){ + FormatStyle Style = {}; + Style.BitFieldDeclarationsOnePerLine = true; + verifyFormat( + "unsigned int baz : 11, + aaa : 2, + foo : 3" + ); + Style.BitFieldDeclarationsOnePerLine = false; + verifyFormat( + "unsigned int baz : 11, aaa : 2, foo : 3" + ); +} TEST_F(FormatTest, LineBreakingInBinaryExpressions) { verifyFormat(