Index: include/clang/Format/Format.h =================================================================== --- include/clang/Format/Format.h +++ include/clang/Format/Format.h @@ -151,6 +151,39 @@ /// \endcode bool AlignTrailingComments; + /// \brief If a function call, initializer list, or template + /// argument list doesn't fit on a line, allow putting all + /// arguments onto the next line, even if ``BinPackArguments`` + /// is ``false``. + /// \code + /// true: + /// callFunction( + /// a, b, c, d); + /// + /// false: + /// callFunction(a, + /// b, + /// c, + /// d); + /// \endcode + bool AllowAllArgumentsOnNextLine; + + /// \brief If a constructor initializer list doesn't fit on a line, allow + /// putting all initializers onto the next line, if + /// ```ConstructorInitializerAllOnOneLineOrOnePerLine``` is true. + /// Note that this parameter has no effect if + /// ```ConstructorInitializerAllOnOneLineOrOnePerLine``` is false. + /// \code + /// true: + /// MyClass::MyClass() : + /// member0(0), member1(2) {} + /// + /// false: + /// MyClass::MyClass() : + /// member0(0), + /// member1(2) {} + bool AllowAllConstructorInitializersOnNextLine; + /// \brief If the function declaration doesn't fit on a line, /// allow putting all parameters of a function declaration onto /// the next line even if ``BinPackParameters`` is ``false``. @@ -1571,6 +1604,9 @@ AlignEscapedNewlines == R.AlignEscapedNewlines && AlignOperands == R.AlignOperands && AlignTrailingComments == R.AlignTrailingComments && + AllowAllArgumentsOnNextLine == R.AllowAllArgumentsOnNextLine && + AllowAllConstructorInitializersOnNextLine == + R.AllowAllConstructorInitializersOnNextLine && AllowAllParametersOfDeclarationOnNextLine == R.AllowAllParametersOfDeclarationOnNextLine && AllowShortBlocksOnASingleLine == R.AllowShortBlocksOnASingleLine && @@ -1625,8 +1661,7 @@ ObjCBlockIndentWidth == R.ObjCBlockIndentWidth && ObjCSpaceAfterProperty == R.ObjCSpaceAfterProperty && ObjCSpaceBeforeProtocolList == R.ObjCSpaceBeforeProtocolList && - PenaltyBreakAssignment == - R.PenaltyBreakAssignment && + PenaltyBreakAssignment == R.PenaltyBreakAssignment && PenaltyBreakBeforeFirstCallParameter == R.PenaltyBreakBeforeFirstCallParameter && PenaltyBreakComment == R.PenaltyBreakComment && Index: lib/Format/ContinuationIndenter.cpp =================================================================== --- lib/Format/ContinuationIndenter.cpp +++ lib/Format/ContinuationIndenter.cpp @@ -753,7 +753,8 @@ if (!Previous.isOneOf(tok::l_paren, tok::l_brace, TT_BinaryOperator) || (!Style.AllowAllParametersOfDeclarationOnNextLine && State.Line->MustBeDeclaration) || - Previous.is(TT_DictLiteral)) + Previous.is(TT_DictLiteral) || + (!Style.AllowAllArgumentsOnNextLine && !State.Line->MustBeDeclaration)) State.Stack.back().BreakBeforeParameter = true; } @@ -959,9 +960,13 @@ ? 0 : 2); State.Stack.back().NestedBlockIndent = State.Stack.back().Indent; - if (Style.ConstructorInitializerAllOnOneLineOrOnePerLine) + if (Style.ConstructorInitializerAllOnOneLineOrOnePerLine) { State.Stack.back().AvoidBinPacking = true; - State.Stack.back().BreakBeforeParameter = false; + State.Stack.back().BreakBeforeParameter = + !Style.AllowAllConstructorInitializersOnNextLine; + } else { + State.Stack.back().BreakBeforeParameter = false; + } } if (Current.is(TT_CtorInitializerColon) && Style.BreakConstructorInitializers == FormatStyle::BCIS_AfterColon) { Index: lib/Format/Format.cpp =================================================================== --- lib/Format/Format.cpp +++ lib/Format/Format.cpp @@ -287,6 +287,10 @@ IO.mapOptional("AlignEscapedNewlines", Style.AlignEscapedNewlines); IO.mapOptional("AlignOperands", Style.AlignOperands); IO.mapOptional("AlignTrailingComments", Style.AlignTrailingComments); + IO.mapOptional("AllowAllArgumentsOnNextLine", + Style.AllowAllArgumentsOnNextLine); + IO.mapOptional("AllowAllConstructorInitializersOnNextLine", + Style.AllowAllConstructorInitializersOnNextLine); IO.mapOptional("AllowAllParametersOfDeclarationOnNextLine", Style.AllowAllParametersOfDeclarationOnNextLine); IO.mapOptional("AllowShortBlocksOnASingleLine", @@ -303,6 +307,7 @@ Style.AlwaysBreakAfterDefinitionReturnType); IO.mapOptional("AlwaysBreakAfterReturnType", Style.AlwaysBreakAfterReturnType); + // If AlwaysBreakAfterDefinitionReturnType was specified but // AlwaysBreakAfterReturnType was not, initialize the latter from the // former for backwards compatibility. @@ -575,6 +580,8 @@ LLVMStyle.AlignTrailingComments = true; LLVMStyle.AlignConsecutiveAssignments = false; LLVMStyle.AlignConsecutiveDeclarations = false; + LLVMStyle.AllowAllArgumentsOnNextLine = true; + LLVMStyle.AllowAllConstructorInitializersOnNextLine = true; LLVMStyle.AllowAllParametersOfDeclarationOnNextLine = true; LLVMStyle.AllowShortFunctionsOnASingleLine = FormatStyle::SFS_All; LLVMStyle.AllowShortBlocksOnASingleLine = false; Index: unittests/Format/FormatTest.cpp =================================================================== --- unittests/Format/FormatTest.cpp +++ unittests/Format/FormatTest.cpp @@ -3433,6 +3433,56 @@ " aaaa(aaaa) {}")); } +TEST_F(FormatTest, AllowAllConstructorInitializersOnNextLine) { + FormatStyle Style = getLLVMStyle(); + Style.BreakConstructorInitializers = FormatStyle::BCIS_BeforeComma; + Style.ColumnLimit = 60; + Style.ConstructorInitializerAllOnOneLineOrOnePerLine = true; + Style.AllowAllConstructorInitializersOnNextLine = true; + verifyFormat("Constructor()\n" + " : aaaaaaaaaaaaaaaaaaaa(a), bbbbbbbbbbbbbbbbbbbbb(b) {}", + Style); + verifyFormat("Constructor() : a(a), b(b) {}", Style); + + Style.AllowAllConstructorInitializersOnNextLine = false; + verifyFormat("Constructor()\n" + " : aaaaaaaaaaaaaaaaaaaa(a)\n" + " , bbbbbbbbbbbbbbbbbbbbb(b) {}", + Style); + verifyFormat("Constructor() : a(a), b(b) {}", Style); +} + +TEST_F(FormatTest, AllowAllArgumentsOnNextLine) { + FormatStyle Style = getLLVMStyle(); + Style.ColumnLimit = 60; + Style.BinPackArguments = false; + Style.AllowAllArgumentsOnNextLine = true; + verifyFormat("void foo() {\n" + " FunctionCallWithReallyLongName(\n" + " aaaaaaaaaaaaaaaaaaaaaaaaaaa, bbbbbbbbbbbb);\n" + "}", + Style); + Style.AllowAllArgumentsOnNextLine = false; + verifyFormat("void foo() {\n" + " FunctionCallWithReallyLongName(\n" + " aaaaaaaaaaaaaaaaaaaaaaaaaaa,\n" + " bbbbbbbbbbbb);\n" + "}", + Style); + + // This parameter should not affect declarations. + Style.BinPackParameters = false; + Style.AllowAllParametersOfDeclarationOnNextLine = true; + verifyFormat("void FunctionCallWithReallyLongName(\n" + " int aaaaaaaaaaaaaaaaaaaaaaa, int bbbbbbbbbbbb);", + Style); + Style.AllowAllParametersOfDeclarationOnNextLine = false; + verifyFormat("void FunctionCallWithReallyLongName(\n" + " int aaaaaaaaaaaaaaaaaaaaaaa,\n" + " int bbbbbbbbbbbb);", + Style); +} + TEST_F(FormatTest, BreakConstructorInitializersAfterColon) { FormatStyle Style = getLLVMStyle(); Style.BreakConstructorInitializers = FormatStyle::BCIS_AfterColon; @@ -10020,6 +10070,8 @@ CHECK_PARSE_BOOL(AlignTrailingComments); CHECK_PARSE_BOOL(AlignConsecutiveAssignments); CHECK_PARSE_BOOL(AlignConsecutiveDeclarations); + CHECK_PARSE_BOOL(AllowAllArgumentsOnNextLine); + CHECK_PARSE_BOOL(AllowAllConstructorInitializersOnNextLine); CHECK_PARSE_BOOL(AllowAllParametersOfDeclarationOnNextLine); CHECK_PARSE_BOOL(AllowShortBlocksOnASingleLine); CHECK_PARSE_BOOL(AllowShortCaseLabelsOnASingleLine);