Index: docs/ClangFormatStyleOptions.rst =================================================================== --- docs/ClangFormatStyleOptions.rst +++ docs/ClangFormatStyleOptions.rst @@ -244,6 +244,12 @@ If ``true``, always break after the ``template<...>`` of a template declaration. +**AlwaysBreakBeforeElse** (``bool``) + If ``true``, always break before ``else``. + +**AlwaysBreakBeforeCatch** (``bool``) + If ``true``, always break before ``catch``. + **BinPackArguments** (``bool``) If ``false``, a function call's arguments will either be all on the same line or will have one line each. Index: include/clang/Format/Format.h =================================================================== --- include/clang/Format/Format.h +++ include/clang/Format/Format.h @@ -138,6 +138,12 @@ /// template declaration. bool AlwaysBreakTemplateDeclarations; + /// \brief If \c true, always break before 'else'. + bool AlwaysBreakBeforeElse; + + /// \brief If \c true, always break before 'catch'. + bool AlwaysBreakBeforeCatch; + /// \brief If \c false, a function call's arguments will either be all on the /// same line or will have one line each. bool BinPackArguments; @@ -465,6 +471,8 @@ R.AlwaysBreakBeforeMultilineStrings && AlwaysBreakTemplateDeclarations == R.AlwaysBreakTemplateDeclarations && + AlwaysBreakBeforeElse == R.AlwaysBreakBeforeElse && + AlwaysBreakBeforeCatch == R.AlwaysBreakBeforeCatch && BinPackArguments == R.BinPackArguments && BinPackParameters == R.BinPackParameters && BreakBeforeBinaryOperators == R.BreakBeforeBinaryOperators && @@ -472,8 +480,7 @@ BreakBeforeTernaryOperators == R.BreakBeforeTernaryOperators && BreakConstructorInitializersBeforeComma == R.BreakConstructorInitializersBeforeComma && - ColumnLimit == R.ColumnLimit && - CommentPragmas == R.CommentPragmas && + ColumnLimit == R.ColumnLimit && CommentPragmas == R.CommentPragmas && ConstructorInitializerAllOnOneLineOrOnePerLine == R.ConstructorInitializerAllOnOneLineOrOnePerLine && ConstructorInitializerIndentWidth == @@ -515,8 +522,7 @@ SpacesInCStyleCastParentheses == R.SpacesInCStyleCastParentheses && SpacesInParentheses == R.SpacesInParentheses && SpacesInSquareBrackets == R.SpacesInSquareBrackets && - Standard == R.Standard && - TabWidth == R.TabWidth && + Standard == R.Standard && TabWidth == R.TabWidth && UseTab == R.UseTab; } }; Index: lib/Format/Format.cpp =================================================================== --- lib/Format/Format.cpp +++ lib/Format/Format.cpp @@ -217,6 +217,8 @@ Style.AlwaysBreakAfterDefinitionReturnType); IO.mapOptional("AlwaysBreakBeforeMultilineStrings", Style.AlwaysBreakBeforeMultilineStrings); + IO.mapOptional("AlwaysBreakBeforeElse", Style.AlwaysBreakBeforeElse); + IO.mapOptional("AlwaysBreakBeforeCatch", Style.AlwaysBreakBeforeCatch); IO.mapOptional("AlwaysBreakTemplateDeclarations", Style.AlwaysBreakTemplateDeclarations); IO.mapOptional("BinPackArguments", Style.BinPackArguments); @@ -357,6 +359,8 @@ LLVMStyle.AllowShortLoopsOnASingleLine = false; LLVMStyle.AlwaysBreakAfterDefinitionReturnType = FormatStyle::DRTBS_None; LLVMStyle.AlwaysBreakBeforeMultilineStrings = false; + LLVMStyle.AlwaysBreakBeforeElse = false; + LLVMStyle.AlwaysBreakBeforeCatch = false; LLVMStyle.AlwaysBreakTemplateDeclarations = false; LLVMStyle.BinPackParameters = true; LLVMStyle.BinPackArguments = true; @@ -420,6 +424,8 @@ GoogleStyle.AllowShortIfStatementsOnASingleLine = true; GoogleStyle.AllowShortLoopsOnASingleLine = true; GoogleStyle.AlwaysBreakBeforeMultilineStrings = true; + GoogleStyle.AlwaysBreakBeforeElse = false; + GoogleStyle.AlwaysBreakBeforeCatch = false; GoogleStyle.AlwaysBreakTemplateDeclarations = true; GoogleStyle.ConstructorInitializerAllOnOneLineOrOnePerLine = true; GoogleStyle.DerivePointerAlignment = true; Index: lib/Format/UnwrappedLineParser.cpp =================================================================== --- lib/Format/UnwrappedLineParser.cpp +++ lib/Format/UnwrappedLineParser.cpp @@ -1272,8 +1272,11 @@ --Line->Level; } if (FormatTok->Tok.is(tok::kw_else)) { - if (Style.BreakBeforeBraces == FormatStyle::BS_Stroustrup) + if (Style.BreakBeforeBraces == FormatStyle::BS_Stroustrup || + Style.AlwaysBreakBeforeElse) { addUnwrappedLine(); + } + nextToken(); if (FormatTok->Tok.is(tok::l_brace)) { CompoundStatementIndenter Indenter(this, Style, Line->Level); @@ -1316,7 +1319,8 @@ parseBlock(/*MustBeDeclaration=*/false); if (Style.BreakBeforeBraces == FormatStyle::BS_Allman || Style.BreakBeforeBraces == FormatStyle::BS_GNU || - Style.BreakBeforeBraces == FormatStyle::BS_Stroustrup) { + Style.BreakBeforeBraces == FormatStyle::BS_Stroustrup || + Style.AlwaysBreakBeforeCatch) { addUnwrappedLine(); } else { NeedsUnwrappedLine = true; @@ -1356,7 +1360,8 @@ parseBlock(/*MustBeDeclaration=*/false); if (Style.BreakBeforeBraces == FormatStyle::BS_Allman || Style.BreakBeforeBraces == FormatStyle::BS_GNU || - Style.BreakBeforeBraces == FormatStyle::BS_Stroustrup) { + Style.BreakBeforeBraces == FormatStyle::BS_Stroustrup || + Style.AlwaysBreakBeforeCatch) { addUnwrappedLine(); } else { NeedsUnwrappedLine = true; Index: tools/CMakeLists.txt =================================================================== --- tools/CMakeLists.txt +++ tools/CMakeLists.txt @@ -21,4 +21,5 @@ # on top of the Clang tooling platform. We keep them in a separate repository # to keep the primary Clang repository small and focused. # It also may be included by LLVM_EXTERNAL_CLANG_TOOLS_EXTRA_SOURCE_DIR. -add_llvm_external_project(clang-tools-extra extra) +#add_llvm_external_project(clang-tools-extra extra) +add_subdirectory(extra) Index: unittests/Format/FormatTest.cpp =================================================================== --- unittests/Format/FormatTest.cpp +++ unittests/Format/FormatTest.cpp @@ -9131,6 +9131,50 @@ WebKitBraceStyle); } +TEST_F(FormatTest, AlwaysBreakBeforeElse) { + FormatStyle BeforeElse = getLLVMStyle(); + BeforeElse.AlwaysBreakBeforeElse = true; + verifyFormat("void foo() {\n" + " if (a) {\n" + " a();\n" + " }\n" + " else {\n" + " b();\n" + " }\n" + "}\n", + BeforeElse); + + verifyFormat("void foo() {\n" + " if (a) {\n" + " a();\n" + " }\n" + " else if (b) {\n" + " b();\n" + " }\n" + " else {\n" + " b();\n" + " }\n" + "}\n", + BeforeElse); +} + +TEST_F(FormatTest, AlwaysBreakBeforeCatch) { + FormatStyle BeforeCatch = getLLVMStyle(); + BeforeCatch.AlwaysBreakBeforeCatch = true; + verifyFormat("void foo() {\n" + " try {\n" + " a();\n" + " }\n" + " catch (exception &) {\n" + " b();\n" + " }\n" + " catch (exception &) {\n" + " b();\n" + " }\n" + "}\n", + BeforeCatch); +} + TEST_F(FormatTest, CatchExceptionReferenceBinding) { verifyFormat("void f() {\n" " try {\n"