Index: cfe/trunk/docs/ClangFormatStyleOptions.rst =================================================================== --- cfe/trunk/docs/ClangFormatStyleOptions.rst +++ cfe/trunk/docs/ClangFormatStyleOptions.rst @@ -344,10 +344,42 @@ int d, int e); -**AllowShortBlocksOnASingleLine** (``bool``) - Allows contracting simple braced statements to a single line. +**AllowShortBlocksOnASingleLine** (``ShortBlockStyle``) + Dependent on the value, ``while (true) { continue; }`` can be put on a + single line. + + Possible values: + + * ``SBS_Never`` (in configuration: ``Never``) + Never merge blocks into a single line. + + .. code-block:: c++ + + while (true) { + } + while (true) { + continue; + } + + * ``SBS_Empty`` (in configuration: ``Empty``) + Only merge empty blocks. + + .. code-block:: c++ + + while (true) {} + while (true) { + continue; + } + + * ``SBS_Always`` (in configuration: ``Always``) + Always merge short blocks into a single line. + + .. code-block:: c++ + + while (true) {} + while (true) { continue; } + - E.g., this allows ``if (a) { return; }`` to be put on a single line. **AllowShortCaseLabelsOnASingleLine** (``bool``) If ``true``, short case labels will be contracted to a single line. Index: cfe/trunk/include/clang/Format/Format.h =================================================================== --- cfe/trunk/include/clang/Format/Format.h +++ cfe/trunk/include/clang/Format/Format.h @@ -216,10 +216,37 @@ /// \endcode bool AllowAllParametersOfDeclarationOnNextLine; - /// Allows contracting simple braced statements to a single line. - /// - /// E.g., this allows ``if (a) { return; }`` to be put on a single line. - bool AllowShortBlocksOnASingleLine; + /// Different styles for merging short blocks containing at most one + /// statement. + enum ShortBlockStyle { + /// Never merge blocks into a single line. + /// \code + /// while (true) { + /// } + /// while (true) { + /// continue; + /// } + /// \endcode + SBS_Never, + /// Only merge empty blocks. + /// \code + /// while (true) {} + /// while (true) { + /// continue; + /// } + /// \endcode + SBS_Empty, + /// Always merge short blocks into a single line. + /// \code + /// while (true) {} + /// while (true) { continue; } + /// \endcode + SBS_Always, + }; + + /// Dependent on the value, ``while (true) { continue; }`` can be put on a + /// single line. + ShortBlockStyle AllowShortBlocksOnASingleLine; /// If ``true``, short case labels will be contracted to a single line. /// \code Index: cfe/trunk/lib/Format/Format.cpp =================================================================== --- cfe/trunk/lib/Format/Format.cpp +++ cfe/trunk/lib/Format/Format.cpp @@ -95,6 +95,16 @@ } }; +template <> struct ScalarEnumerationTraits { + static void enumeration(IO &IO, FormatStyle::ShortBlockStyle &Value) { + IO.enumCase(Value, "Never", FormatStyle::SBS_Never); + IO.enumCase(Value, "false", FormatStyle::SBS_Never); + IO.enumCase(Value, "Always", FormatStyle::SBS_Always); + IO.enumCase(Value, "true", FormatStyle::SBS_Always); + IO.enumCase(Value, "Empty", FormatStyle::SBS_Empty); + } +}; + template <> struct ScalarEnumerationTraits { static void enumeration(IO &IO, FormatStyle::ShortFunctionStyle &Value) { IO.enumCase(Value, "None", FormatStyle::SFS_None); @@ -674,7 +684,7 @@ LLVMStyle.AllowAllConstructorInitializersOnNextLine = true; LLVMStyle.AllowAllParametersOfDeclarationOnNextLine = true; LLVMStyle.AllowShortFunctionsOnASingleLine = FormatStyle::SFS_All; - LLVMStyle.AllowShortBlocksOnASingleLine = false; + LLVMStyle.AllowShortBlocksOnASingleLine = FormatStyle::SBS_Never; LLVMStyle.AllowShortCaseLabelsOnASingleLine = false; LLVMStyle.AllowShortIfStatementsOnASingleLine = FormatStyle::SIS_Never; LLVMStyle.AllowShortLambdasOnASingleLine = FormatStyle::SLS_All; @@ -969,6 +979,7 @@ Style.AlignAfterOpenBracket = FormatStyle::BAS_DontAlign; Style.AlignOperands = false; Style.AlignTrailingComments = false; + Style.AllowShortBlocksOnASingleLine = FormatStyle::SBS_Empty; Style.BreakBeforeBinaryOperators = FormatStyle::BOS_All; Style.BreakBeforeBraces = FormatStyle::BS_WebKit; Style.BreakConstructorInitializers = FormatStyle::BCIS_BeforeComma; @@ -1019,7 +1030,6 @@ Style.BraceWrapping.BeforeElse = true; Style.PenaltyReturnTypeOnItsOwnLine = 1000; Style.AllowShortFunctionsOnASingleLine = FormatStyle::SFS_None; - Style.AllowShortBlocksOnASingleLine = false; Style.AllowShortCaseLabelsOnASingleLine = false; Style.AllowShortIfStatementsOnASingleLine = FormatStyle::SIS_Never; Style.AllowShortLoopsOnASingleLine = false; Index: cfe/trunk/lib/Format/TokenAnnotator.cpp =================================================================== --- cfe/trunk/lib/Format/TokenAnnotator.cpp +++ cfe/trunk/lib/Format/TokenAnnotator.cpp @@ -3044,7 +3044,8 @@ Style.BraceWrapping.AfterEnum) || (Line.startsWith(tok::kw_class) && Style.BraceWrapping.AfterClass) || (Line.startsWith(tok::kw_struct) && Style.BraceWrapping.AfterStruct); - if (Left.is(TT_ObjCBlockLBrace) && !Style.AllowShortBlocksOnASingleLine) + if (Left.is(TT_ObjCBlockLBrace) && + Style.AllowShortBlocksOnASingleLine == FormatStyle::SBS_Never) return true; if (Left.is(TT_LambdaLBrace)) { Index: cfe/trunk/lib/Format/UnwrappedLineFormatter.cpp =================================================================== --- cfe/trunk/lib/Format/UnwrappedLineFormatter.cpp +++ cfe/trunk/lib/Format/UnwrappedLineFormatter.cpp @@ -300,7 +300,7 @@ // Try to merge a control statement block with left brace unwrapped if (TheLine->Last->is(tok::l_brace) && TheLine->First != TheLine->Last && TheLine->First->isOneOf(tok::kw_if, tok::kw_while, tok::kw_for)) { - return Style.AllowShortBlocksOnASingleLine + return Style.AllowShortBlocksOnASingleLine != FormatStyle::SBS_Never ? tryMergeSimpleBlock(I, E, Limit) : 0; } @@ -317,7 +317,7 @@ I != AnnotatedLines.begin() && I[-1]->First->isOneOf(tok::kw_if, tok::kw_while, tok::kw_for)) { unsigned MergedLines = 0; - if (Style.AllowShortBlocksOnASingleLine) { + if (Style.AllowShortBlocksOnASingleLine != FormatStyle::SBS_Never) { MergedLines = tryMergeSimpleBlock(I - 1, E, Limit); // If we managed to merge the block, discard the first merged line // since we are merging starting from I. @@ -411,7 +411,8 @@ if (Limit == 0) return 0; if (Style.BraceWrapping.AfterControlStatement && - (I[1]->First->is(tok::l_brace) && !Style.AllowShortBlocksOnASingleLine)) + I[1]->First->is(tok::l_brace) && + Style.AllowShortBlocksOnASingleLine == FormatStyle::SBS_Never) return 0; if (I[1]->InPPDirective != (*I)->InPPDirective || (I[1]->InPPDirective && I[1]->First->HasUnescapedNewline)) @@ -511,7 +512,7 @@ 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 (!Style.AllowShortBlocksOnASingleLine) + if (Style.AllowShortBlocksOnASingleLine == FormatStyle::SBS_Never) return 0; // Don't merge when we can't except the case when // the control statement block is empty @@ -607,7 +608,7 @@ return 0; Limit -= 2; unsigned MergedLines = 0; - if (Style.AllowShortBlocksOnASingleLine || + if (Style.AllowShortBlocksOnASingleLine != FormatStyle::SBS_Never || (I[1]->First == I[1]->Last && I + 2 != E && I[2]->First->is(tok::r_brace))) { MergedLines = tryMergeSimpleBlock(I + 1, E, Limit); Index: cfe/trunk/unittests/Format/FormatTest.cpp =================================================================== --- cfe/trunk/unittests/Format/FormatTest.cpp +++ cfe/trunk/unittests/Format/FormatTest.cpp @@ -561,7 +561,8 @@ TEST_F(FormatTest, FormatShortBracedStatements) { FormatStyle AllowSimpleBracedStatements = getLLVMStyle(); AllowSimpleBracedStatements.ColumnLimit = 40; - AllowSimpleBracedStatements.AllowShortBlocksOnASingleLine = true; + AllowSimpleBracedStatements.AllowShortBlocksOnASingleLine = + FormatStyle::SBS_Always; AllowSimpleBracedStatements.AllowShortIfStatementsOnASingleLine = FormatStyle::SIS_WithoutElse; @@ -714,7 +715,7 @@ TEST_F(FormatTest, ShortBlocksInMacrosDontMergeWithCodeAfterMacro) { FormatStyle Style = getLLVMStyleWithColumns(60); - Style.AllowShortBlocksOnASingleLine = true; + Style.AllowShortBlocksOnASingleLine = FormatStyle::SBS_Always; Style.AllowShortIfStatementsOnASingleLine = FormatStyle::SIS_WithoutElse; Style.BreakBeforeBraces = FormatStyle::BS_Allman; EXPECT_EQ("#define A \\\n" @@ -1163,7 +1164,7 @@ FormatStyle Style = getLLVMStyle(); Style.IndentCaseLabels = true; - Style.AllowShortBlocksOnASingleLine = false; + Style.AllowShortBlocksOnASingleLine = FormatStyle::SBS_Never; Style.BreakBeforeBraces = FormatStyle::BS_Custom; Style.BraceWrapping.AfterCaseLabel = true; Style.BraceWrapping.AfterControlStatement = true; @@ -3692,10 +3693,10 @@ EXPECT_EQ("{}", format("{}")); verifyFormat("enum E {};"); verifyFormat("enum E {}"); - EXPECT_EQ("void f() { }", format("void f() {}", getWebKitStyle())); FormatStyle Style = getLLVMStyle(); - Style.AllowShortBlocksOnASingleLine = true; Style.SpaceInEmptyBlock = true; + EXPECT_EQ("void f() { }", format("void f() {}", Style)); + Style.AllowShortBlocksOnASingleLine = FormatStyle::SBS_Empty; EXPECT_EQ("while (true) { }", format("while (true) {}", Style)); } @@ -11745,7 +11746,6 @@ CHECK_PARSE_BOOL(AllowAllArgumentsOnNextLine); CHECK_PARSE_BOOL(AllowAllConstructorInitializersOnNextLine); CHECK_PARSE_BOOL(AllowAllParametersOfDeclarationOnNextLine); - CHECK_PARSE_BOOL(AllowShortBlocksOnASingleLine); CHECK_PARSE_BOOL(AllowShortCaseLabelsOnASingleLine); CHECK_PARSE_BOOL(AllowShortLoopsOnASingleLine); CHECK_PARSE_BOOL(BinPackArguments); @@ -11920,6 +11920,19 @@ CHECK_PARSE("UseTab: false", UseTab, FormatStyle::UT_Never); CHECK_PARSE("UseTab: true", UseTab, FormatStyle::UT_Always); + Style.AllowShortBlocksOnASingleLine = FormatStyle::SBS_Empty; + CHECK_PARSE("AllowShortBlocksOnASingleLine: Never", + AllowShortBlocksOnASingleLine, FormatStyle::SBS_Never); + CHECK_PARSE("AllowShortBlocksOnASingleLine: Empty", + AllowShortBlocksOnASingleLine, FormatStyle::SBS_Empty); + CHECK_PARSE("AllowShortBlocksOnASingleLine: Always", + AllowShortBlocksOnASingleLine, FormatStyle::SBS_Always); + // For backward compatibility: + CHECK_PARSE("AllowShortBlocksOnASingleLine: false", + AllowShortBlocksOnASingleLine, FormatStyle::SBS_Never); + CHECK_PARSE("AllowShortBlocksOnASingleLine: true", + AllowShortBlocksOnASingleLine, FormatStyle::SBS_Always); + Style.AllowShortFunctionsOnASingleLine = FormatStyle::SFS_Inline; CHECK_PARSE("AllowShortFunctionsOnASingleLine: None", AllowShortFunctionsOnASingleLine, FormatStyle::SFS_None); @@ -12527,6 +12540,14 @@ // Allow functions on a single line. verifyFormat("void f() { return; }", Style); + // Allow empty blocks on a single line and insert a space in empty blocks. + EXPECT_EQ("void f() { }", format("void f() {}", Style)); + EXPECT_EQ("while (true) { }", format("while (true) {}", Style)); + // However, don't merge non-empty short loops. + EXPECT_EQ("while (true) {\n" + " continue;\n" + "}", format("while (true) { continue; }", Style)); + // Constructor initializers are formatted one per line with the "," on the // new line. verifyFormat("Constructor()\n" @@ -13033,7 +13054,7 @@ TEST_F(FormatTest, FormatsBlocks) { FormatStyle ShortBlocks = getLLVMStyle(); - ShortBlocks.AllowShortBlocksOnASingleLine = true; + ShortBlocks.AllowShortBlocksOnASingleLine = FormatStyle::SBS_Always; verifyFormat("int (^Block)(int, int);", ShortBlocks); verifyFormat("int (^Block1)(int, int) = ^(int i, int j)", ShortBlocks); verifyFormat("void (^block)(int) = ^(id test) { int i; };", ShortBlocks); @@ -13191,10 +13212,10 @@ "};", ZeroColumn); - ZeroColumn.AllowShortBlocksOnASingleLine = true; + ZeroColumn.AllowShortBlocksOnASingleLine = FormatStyle::SBS_Always; EXPECT_EQ("void (^largeBlock)(void) = ^{ int i; };", format("void (^largeBlock)(void) = ^{ int i; };", ZeroColumn)); - ZeroColumn.AllowShortBlocksOnASingleLine = false; + ZeroColumn.AllowShortBlocksOnASingleLine = FormatStyle::SBS_Never; EXPECT_EQ("void (^largeBlock)(void) = ^{\n" " int i;\n" "};",