https://github.com/brandb97 updated https://github.com/llvm/llvm-project/pull/151428
>From 04cd330ab306e6718cf96ff3d29b446d35424a5e Mon Sep 17 00:00:00 2001 From: Lidong Yan <yldhome...@gmail.com> Date: Fri, 22 Aug 2025 23:31:28 +0800 Subject: [PATCH] [clang-format] allow short function bodies on a single line When set AllowShortBlocksOnASingleLine as Empty or Always and we can't put the whole function on a single line, clang-format doesn't tries to put the function body on a seperate line from function signature. Add tryMergeLines to put function bodies on a single line if possible. Signed-off-by: Lidong Yan <yldhome...@gmail.com> --- clang/lib/Format/UnwrappedLineFormatter.cpp | 51 ++++++++++++++++----- clang/lib/Format/UnwrappedLineParser.cpp | 6 ++- clang/unittests/Format/FormatTest.cpp | 32 +++++++++++++ 3 files changed, 76 insertions(+), 13 deletions(-) diff --git a/clang/lib/Format/UnwrappedLineFormatter.cpp b/clang/lib/Format/UnwrappedLineFormatter.cpp index c938ff3965f9e..37c04874c98f5 100644 --- a/clang/lib/Format/UnwrappedLineFormatter.cpp +++ b/clang/lib/Format/UnwrappedLineFormatter.cpp @@ -242,19 +242,24 @@ class LineJoiner { if (Style.ColumnLimit > 0 && Indent > Style.ColumnLimit) return 0; - unsigned Limit = + const unsigned LimitStripIndent = Style.ColumnLimit == 0 ? UINT_MAX : Style.ColumnLimit - Indent; // If we already exceed the column limit, we set 'Limit' to 0. The different // tryMerge..() functions can then decide whether to still do merging. - Limit = TheLine->Last->TotalLength > Limit - ? 0 - : Limit - TheLine->Last->TotalLength; + unsigned Limit = TheLine->Last->TotalLength > LimitStripIndent + ? 0 + : LimitStripIndent - TheLine->Last->TotalLength; if (TheLine->Last->is(TT_FunctionLBrace) && - TheLine->First == TheLine->Last && - !Style.BraceWrapping.SplitEmptyFunction && - NextLine.First->is(tok::r_brace)) { - return tryMergeSimpleBlock(I, E, Limit); + TheLine->First == TheLine->Last) { + if (!Style.BraceWrapping.SplitEmptyFunction && + NextLine.First->is(tok::r_brace)) { + return tryMergeSimpleBlock(I, E, Limit); + } + if (Style.AllowShortBlocksOnASingleLine == FormatStyle::SBS_Always && + I + 2 != E && I[2]->First->is(tok::r_brace)) { + return tryMergeSimpleBlock(I, E, Limit); + } } const auto *PreviousLine = I != AnnotatedLines.begin() ? I[-1] : nullptr; @@ -510,7 +515,8 @@ class LineJoiner { // Try to merge a function block with left brace wrapped. if (NextLine.First->is(TT_FunctionLBrace) && - Style.BraceWrapping.AfterFunction) { + (Style.BraceWrapping.AfterFunction || + Style.AllowShortBlocksOnASingleLine > FormatStyle::SBS_Never)) { if (NextLine.Last->is(TT_LineComment)) return 0; @@ -520,17 +526,38 @@ class LineJoiner { Limit -= 2; unsigned MergedLines = 0; + const bool NextShortBlock = NextLine.First == NextLine.Last && + I + 3 != E && I[3]->First->is(tok::r_brace); + const bool NextEmptyBlock = NextLine.First == NextLine.Last && + I + 2 != E && I[2]->First->is(tok::r_brace); if (MergeShortFunctions || (Style.AllowShortFunctionsOnASingleLine >= FormatStyle::SFS_Empty && - NextLine.First == NextLine.Last && I + 2 != E && - I[2]->First->is(tok::r_brace))) { + NextEmptyBlock) || + (Style.AllowShortFunctionsOnASingleLine == FormatStyle::SFS_All && + NextShortBlock)) { MergedLines = tryMergeSimpleBlock(I + 1, E, Limit); // If we managed to merge the block, count the function header, which is // on a separate line. if (MergedLines > 0) ++MergedLines; } - return MergedLines; + // Return early if we shouldn't merge left brace back to function header. + if (Style.BraceWrapping.AfterFunction || MergedLines) + return MergedLines; + + // If we can't put function body on a single line, we should merge left + // brace back to function header. + const unsigned NextLineLimit = + NextLine.Last->TotalLength > LimitStripIndent + ? 0 + : LimitStripIndent - NextLine.Last->TotalLength; + if ((NextShortBlock && + Style.AllowShortBlocksOnASingleLine == FormatStyle::SBS_Always) || + (NextEmptyBlock && + Style.AllowShortBlocksOnASingleLine > FormatStyle::SBS_Never)) { + MergedLines = tryMergeSimpleBlock(I + 1, E, NextLineLimit); + } + return MergedLines ? 0 : 1; } auto IsElseLine = [&TheLine]() -> bool { const FormatToken *First = TheLine->First; diff --git a/clang/lib/Format/UnwrappedLineParser.cpp b/clang/lib/Format/UnwrappedLineParser.cpp index 91b8fdc8a3c38..e3884c472a133 100644 --- a/clang/lib/Format/UnwrappedLineParser.cpp +++ b/clang/lib/Format/UnwrappedLineParser.cpp @@ -1919,7 +1919,11 @@ void UnwrappedLineParser::parseStructuralElement( FormatStyle::BWACS_Always) { addUnwrappedLine(); } - } else if (Style.BraceWrapping.AfterFunction) { + } else if (Style.BraceWrapping.AfterFunction || + // Wrap left brace here in case that we want + // to merge function body on a single line. + Style.AllowShortBlocksOnASingleLine > + FormatStyle::SBS_Never) { addUnwrappedLine(); } if (!Previous || Previous->isNot(TT_TypeDeclarationParen)) diff --git a/clang/unittests/Format/FormatTest.cpp b/clang/unittests/Format/FormatTest.cpp index 83c664c3b81f3..fef7607c30587 100644 --- a/clang/unittests/Format/FormatTest.cpp +++ b/clang/unittests/Format/FormatTest.cpp @@ -14953,11 +14953,25 @@ TEST_F(FormatTest, PullTrivialFunctionDefinitionsIntoSingleLine) { FormatStyle DoNotMerge = getLLVMStyle(); DoNotMerge.AllowShortFunctionsOnASingleLine = FormatStyle::SFS_None; + FormatStyle MergeBodyAlways = getLLVMStyle(); + MergeBodyAlways.AllowShortFunctionsOnASingleLine = FormatStyle::SFS_None; + MergeBodyAlways.AllowShortBlocksOnASingleLine = FormatStyle::SBS_Always; + + FormatStyle MergeBodyIfPossible = getLLVMStyleWithColumns(20); + MergeBodyIfPossible.AllowShortFunctionsOnASingleLine = FormatStyle::SFS_None; + MergeBodyIfPossible.AllowShortBlocksOnASingleLine = FormatStyle::SBS_Always; + verifyFormat("void f() { return 42; }"); verifyFormat("void f() {\n" " return 42;\n" "}", DoNotMerge); + verifyFormat("void f()\n" + "{ return 42; }", + MergeBodyAlways); + verifyFormat("void long_function_name()\n" + "{ return 42; }", + MergeBodyIfPossible); verifyFormat("void f() {\n" " // Comment\n" "}"); @@ -14982,6 +14996,24 @@ TEST_F(FormatTest, PullTrivialFunctionDefinitionsIntoSingleLine) { "} // comment", getLLVMStyleWithColumns(15)); + verifyFormat("void f()\n" + "{} // comment", + MergeBodyAlways); + verifyFormat("void f()\n" + "{ int a; } // comment", + MergeBodyAlways); + verifyFormat("void long_function_name()\n" + "{} // comment", + MergeBodyIfPossible); + verifyFormat("void f() {\n" + " int a;\n" + "} // comment", + MergeBodyIfPossible); + MergeBodyIfPossible.ColumnLimit = 21; + verifyFormat("void f()\n" + "{ int a; } // comment", + MergeBodyIfPossible); + verifyFormat("void f() { return 42; }", getLLVMStyleWithColumns(23)); verifyFormat("void f() {\n return 42;\n}", getLLVMStyleWithColumns(22)); _______________________________________________ cfe-commits mailing list cfe-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits