Index: clang/docs/ClangFormatStyleOptions.rst =================================================================== --- clang/docs/ClangFormatStyleOptions.rst +++ clang/docs/ClangFormatStyleOptions.rst @@ -397,16 +397,43 @@ return; } + * ``SIS_AlwaysNoElse`` (in configuration: ``AlwaysNoElse``) + Allow short if/else if statements even if the else is a compound statement. + + .. code-block:: c++ + + if (a) return; + else { + return; + } + * ``SIS_Always`` (in configuration: ``Always``) - Allow short if statements even if the else is a compound statement. + Allow short if/else if/else statements when they are not compound statements. .. code-block:: c++ + if (a) return; + else return; + + if (a) return; + else if (b) return; + else return; + if (a) return; else { return; } + if (a) return; + else if (b) return; + else { + return; + } + + if (a) return; + else if (b) return; + else return; + **AllowShortLoopsOnASingleLine** (``bool``) If ``true``, ``while (true) continue;`` can be put on a single line. Index: clang/include/clang/Format/Format.h =================================================================== --- clang/include/clang/Format/Format.h +++ clang/include/clang/Format/Format.h @@ -260,13 +260,33 @@ /// return; /// \endcode SIS_WithoutElse, - /// Always put short ifs on the same line if - /// the else is not a compound statement or not. + /// If Else statements have no braces don't put them + /// on the same line. + /// \code + /// if (a) return; + /// else + /// return; + /// \endcode + SIS_AlwaysNoElse, + /// Always put short if/else/else if on the same line if + /// the not compound statement. /// \code /// if (a) return; /// else { /// return; /// } + /// if (a) return; + /// else if (b) return; + /// else { + /// return; + /// } + /// + /// if (a) return; + /// else if (b) return; + /// else return; + /// + /// if (a) return; + /// else return; /// \endcode SIS_Always, }; Index: clang/lib/Format/Format.cpp =================================================================== --- clang/lib/Format/Format.cpp +++ clang/lib/Format/Format.cpp @@ -110,6 +110,7 @@ static void enumeration(IO &IO, FormatStyle::ShortIfStyle &Value) { IO.enumCase(Value, "Never", FormatStyle::SIS_Never); IO.enumCase(Value, "Always", FormatStyle::SIS_Always); + IO.enumCase(Value, "AlwaysNoElse", FormatStyle::SIS_AlwaysNoElse); IO.enumCase(Value, "WithoutElse", FormatStyle::SIS_WithoutElse); // For backward compatibility. Index: clang/lib/Format/UnwrappedLineFormatter.cpp =================================================================== --- clang/lib/Format/UnwrappedLineFormatter.cpp +++ clang/lib/Format/UnwrappedLineFormatter.cpp @@ -363,6 +363,18 @@ ? tryMergeSimpleControlStatement(I, E, Limit) : 0; } + if (TheLine->First->startsSequence(tok::kw_else, tok::kw_if)) { + return (Style.AllowShortIfStatementsOnASingleLine >= + FormatStyle::SIS_AlwaysNoElse) + ? tryMergeSimpleControlStatement(I, E, Limit) + : 0; + } + if (TheLine->First->is(tok::kw_else)) { + return Style.AllowShortIfStatementsOnASingleLine == + FormatStyle::SIS_Always + ? tryMergeSimpleControlStatement(I, E, Limit) + : 0; + } if (TheLine->First->isOneOf(tok::kw_for, tok::kw_while)) { return Style.AllowShortLoopsOnASingleLine ? tryMergeSimpleControlStatement(I, E, Limit) @@ -406,7 +418,8 @@ return 0; Limit = limitConsideringMacros(I + 1, E, Limit); AnnotatedLine &Line = **I; - if (Line.Last->isNot(tok::r_paren)) + if (Line.Last->isNot(tok::r_paren) && + Style.AllowShortIfStatementsOnASingleLine < FormatStyle::SIS_Always) return 0; if (1 + I[1]->Last->TotalLength > Limit) return 0; @@ -414,7 +427,8 @@ TT_LineComment)) return 0; // Only inline simple if's (no nested if or else), unless specified - if (Style.AllowShortIfStatementsOnASingleLine != FormatStyle::SIS_Always) { + if (Style.AllowShortIfStatementsOnASingleLine < + FormatStyle::SIS_AlwaysNoElse) { if (I + 2 != E && Line.startsWith(tok::kw_if) && I[2]->First->is(tok::kw_else)) return 0; @@ -487,7 +501,7 @@ // Check that the current line allows merging. This depends on whether we // are in a control flow statements as well as several style flags. - if (Line.First->isOneOf(tok::kw_else, tok::kw_case) || + if (Line.First->is(tok::kw_case) || (Line.First->Next && Line.First->Next->is(tok::kw_else))) return 0; // default: in switch statement @@ -496,9 +510,10 @@ if (Tok && Tok->is(tok::colon)) return 0; } - if (Line.First->isOneOf(tok::kw_if, tok::kw_while, tok::kw_do, tok::kw_try, - tok::kw___try, tok::kw_catch, tok::kw___finally, - tok::kw_for, tok::r_brace, Keywords.kw___except)) { + if (Line.First->isOneOf(tok::kw_if, tok::kw_else, tok::kw_while, tok::kw_do, + tok::kw_try, tok::kw___try, tok::kw_catch, + tok::kw___finally, tok::kw_for, tok::r_brace, + Keywords.kw___except)) { if (!Style.AllowShortBlocksOnASingleLine) return 0; // Don't merge when we can't except the case when @@ -508,6 +523,11 @@ !Style.BraceWrapping.AfterControlStatement && !I[1]->First->is(tok::r_brace)) return 0; + if (!Style.AllowShortIfStatementsOnASingleLine && + Line.startsWith(tok::kw_else) && + !Style.BraceWrapping.AfterControlStatement && + !I[1]->First->is(tok::r_brace)) + return 0; if (!Style.AllowShortIfStatementsOnASingleLine && Line.startsWith(tok::kw_if) && Style.BraceWrapping.AfterControlStatement && I + 2 != E && Index: clang/unittests/Format/FormatTest.cpp =================================================================== --- clang/unittests/Format/FormatTest.cpp +++ clang/unittests/Format/FormatTest.cpp @@ -505,6 +505,35 @@ " g();\n", AllowsMergedIf); + AllowsMergedIf.AllowShortIfStatementsOnASingleLine = FormatStyle::SIS_AlwaysNoElse; + + verifyFormat("if (a) f();\n" + "else {\n" + " g();\n" + "}", + AllowsMergedIf); + verifyFormat("if (a) f();\n" + "else\n" + " g();\n", + AllowsMergedIf); + verifyFormat("if (a) f();\n" + "else if (b) g();\n", + AllowsMergedIf); + verifyFormat("if (a) f();\n" + "else if (b) g();\n" + "else\n" + " h();\n", + AllowsMergedIf); + verifyFormat("if (a) f();\n" + "else {\n" + " if (a) f();\n" + " else {\n" + " g();\n" + " }\n" + " g();\n" + "}", + AllowsMergedIf); + AllowsMergedIf.AllowShortIfStatementsOnASingleLine = FormatStyle::SIS_Always; verifyFormat("if (a) f();\n" @@ -521,6 +550,16 @@ " g();\n" "}", AllowsMergedIf); + verifyFormat("if (a) f();\n" + "else g();\n", + AllowsMergedIf); + verifyFormat("if (a) f();\n" + "else if (b) g();\n", + AllowsMergedIf); + verifyFormat("if (a) f();\n" + "else if (b) g();\n" + "else h();\n", + AllowsMergedIf); } TEST_F(FormatTest, FormatLoopsWithoutCompoundStatement) {