Index: docs/ClangFormatStyleOptions.rst =================================================================== --- docs/ClangFormatStyleOptions.rst +++ docs/ClangFormatStyleOptions.rst @@ -190,8 +190,6 @@ someLongFunction( argument1, argument2); - - **AlignConsecutiveAssignments** (``bool``) If ``true``, aligns consecutive assignments. @@ -1860,6 +1858,18 @@ Add a space in front of an Objective-C protocol list, i.e. use ``Foo `` instead of ``Foo``. +**OnePerLineBitFieldDecl** (``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; + **PenaltyBreakAssignment** (``unsigned``) The penalty for breaking around an assignment operator. 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 OnePerLineBitFieldDecl; + /// Different styles for aligning escaped newlines. enum EscapedNewlineAlignmentStyle { /// Don't align escaped newlines. @@ -1950,6 +1960,7 @@ JavaScriptWrapImports == R.JavaScriptWrapImports && KeepEmptyLinesAtTheStartOfBlocks == R.KeepEmptyLinesAtTheStartOfBlocks && + OnePerLineBitFieldDecl == R.OnePerLineBitFieldDecl && MacroBlockBegin == R.MacroBlockBegin && MacroBlockEnd == R.MacroBlockEnd && MaxEmptyLinesToKeep == R.MaxEmptyLinesToKeep && 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.OnePerLineBitFieldDecl) + 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("BitFieldDeclsOnSeparateLines", Style.BitFieldDeclsOnSeparateLines); 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,16 @@ 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(); + if (T->Tok.is(tok::comma) && Tok.is(tok::identifier) && + T->Next->Tok.is(tok::colon)) + return true; + return false; +} /// 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.OnePerLineBitFieldDecl && + 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.OnePerLineBitFieldDecl = true; + verifyFormat( + "unsigned int baz : 11, + aaa : 2, + foo : 3" + ); + Style.OnePerLineBitFieldDecl = false; + verifyFormat( + "unsigned int baz : 11, aaa : 2, foo : 3" + ); +} TEST_F(FormatTest, LineBreakingInBinaryExpressions) { verifyFormat(