Index: clang/docs/ClangFormatStyleOptions.rst =================================================================== --- clang/docs/ClangFormatStyleOptions.rst +++ clang/docs/ClangFormatStyleOptions.rst @@ -1084,6 +1084,23 @@ bar(); }); + * ``bool BeforeStructInitialization`` Wrap before struct initialization. + + .. code-block:: c++ + + true: + struct new_struct struct_name = + { + a = 1, + b = 2, + }; + + false: + struct new_struct struct_name = { + a = 1, + b = 2, + }; + * ``bool BeforeWhile`` Wrap before ``while``. .. code-block:: c++ Index: clang/include/clang/Format/Format.h =================================================================== --- clang/include/clang/Format/Format.h +++ clang/include/clang/Format/Format.h @@ -1094,6 +1094,22 @@ /// }); /// \endcode bool BeforeLambdaBody; + /// Wrap before struct initialization. + /// \code + /// true: + /// struct new_struct struct_name = + /// { + /// a = 1, + /// b = 2, + /// }; + /// + /// false: + /// struct new_struct struct_name = { + /// a = 1, + /// b = 2, + /// }; + /// \endcode + bool BeforeStructInitialization; /// Wrap before ``while``. /// \code /// true: Index: clang/lib/Format/ContinuationIndenter.cpp =================================================================== --- clang/lib/Format/ContinuationIndenter.cpp +++ clang/lib/Format/ContinuationIndenter.cpp @@ -972,8 +972,10 @@ const FormatToken &Previous = *Current.Previous; // If we are continuing an expression, we want to use the continuation indent. unsigned ContinuationIndent = - std::max(State.Stack.back().LastSpace, State.Stack.back().Indent) + - Style.ContinuationIndentWidth; + std::max(State.Stack.back().LastSpace, State.Stack.back().Indent); + if (!(Style.BraceWrapping.BeforeStructInitialization && + State.Line->First->is(tok::kw_struct) && Current.is(tok::l_brace))) + ContinuationIndent += Style.ContinuationIndentWidth; const FormatToken *PreviousNonComment = Current.getPreviousNonComment(); const FormatToken *NextNonComment = Previous.getNextNonComment(); if (!NextNonComment) Index: clang/lib/Format/Format.cpp =================================================================== --- clang/lib/Format/Format.cpp +++ clang/lib/Format/Format.cpp @@ -657,6 +657,8 @@ IO.mapOptional("BeforeCatch", Wrapping.BeforeCatch); IO.mapOptional("BeforeElse", Wrapping.BeforeElse); IO.mapOptional("BeforeLambdaBody", Wrapping.BeforeLambdaBody); + IO.mapOptional("BeforeStructInitialization", + Wrapping.BeforeStructInitialization); IO.mapOptional("BeforeWhile", Wrapping.BeforeWhile); IO.mapOptional("IndentBraces", Wrapping.IndentBraces); IO.mapOptional("SplitEmptyFunction", Wrapping.SplitEmptyFunction); @@ -754,6 +756,7 @@ /*BeforeCatch=*/false, /*BeforeElse=*/false, /*BeforeLambdaBody=*/false, + /*BeforeStructInitialization=*/false, /*BeforeWhile=*/false, /*IndentBraces=*/false, /*SplitEmptyFunction=*/true, @@ -826,6 +829,7 @@ /*BeforeCatch=*/true, /*BeforeElse=*/true, /*BeforeLambdaBody=*/false, + /*BeforeStructInitialization=*/false, /*BeforeWhile=*/true, /*IndentBraces=*/true, /*SplitEmptyFunction=*/true, @@ -887,6 +891,7 @@ /*BeforeCatch=*/false, /*BeforeElse=*/false, /*BeforeLambdaBody=*/false, + /*BeforeStructInitialization=*/false, /*BeforeWhile=*/false, /*IndentBraces=*/false, /*SplitEmptyFunction=*/true, Index: clang/lib/Format/TokenAnnotator.cpp =================================================================== --- clang/lib/Format/TokenAnnotator.cpp +++ clang/lib/Format/TokenAnnotator.cpp @@ -3489,6 +3489,10 @@ bool TokenAnnotator::mustBreakBefore(const AnnotatedLine &Line, const FormatToken &Right) { const FormatToken &Left = *Right.Previous; + if (Style.BraceWrapping.BeforeStructInitialization && + Line.First->is(tok::kw_struct) && Right.is(tok::l_brace) && + (Right.is(BK_BracedInit) || Left.is(tok::equal))) + return true; if (Right.NewlinesBefore > 1 && Style.MaxEmptyLinesToKeep > 0) return true; Index: clang/unittests/Format/FormatTest.cpp =================================================================== --- clang/unittests/Format/FormatTest.cpp +++ clang/unittests/Format/FormatTest.cpp @@ -5046,6 +5046,35 @@ format(Input, Style)); } +TEST_F(FormatTest, BreakBeforeStructInitialization) { + FormatStyle Style = getLLVMStyle(); + Style.ColumnLimit = 80; + Style.BreakBeforeBraces = FormatStyle::BS_Custom; + Style.BraceWrapping.BeforeStructInitialization = true; + verifyFormat("struct new_struct struct_name =\n" + "{a = 1};", + Style); + verifyFormat("struct new_struct struct_name =\n" + "{a = 1, b = 2};", + Style); + verifyFormat("struct new_struct struct_name =\n" + "{\n" + " a = 1,\n" + " b = 2,\n" + "};", + Style); + Style.BraceWrapping.BeforeStructInitialization = false; + verifyFormat("struct new_struct struct_name = {a = 1};", + Style); + verifyFormat("struct new_struct struct_name = {a = 1, b = 2};", + Style); + verifyFormat("struct new_struct struct_name = {\n" + " a = 1,\n" + " b = 2,\n" + "};", + Style); +} + TEST_F(FormatTest, BreakConstructorInitializersAfterColon) { FormatStyle Style = getLLVMStyle(); Style.BreakConstructorInitializers = FormatStyle::BCIS_AfterColon; @@ -14154,6 +14183,7 @@ CHECK_PARSE_NESTED_BOOL(BraceWrapping, BeforeCatch); CHECK_PARSE_NESTED_BOOL(BraceWrapping, BeforeElse); CHECK_PARSE_NESTED_BOOL(BraceWrapping, BeforeLambdaBody); + CHECK_PARSE_NESTED_BOOL(BraceWrapping, BeforeStructInitialization); CHECK_PARSE_NESTED_BOOL(BraceWrapping, BeforeWhile); CHECK_PARSE_NESTED_BOOL(BraceWrapping, IndentBraces); CHECK_PARSE_NESTED_BOOL(BraceWrapping, SplitEmptyFunction);