-
Notifications
You must be signed in to change notification settings - Fork 14.7k
[clang-format] allow short function body on a single line #151428
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
base: main
Are you sure you want to change the base?
Conversation
@llvm/pr-subscribers-clang @llvm/pr-subscribers-clang-format Author: Lidong Yan (brandb97) ChangesFix issue #145161 Full diff: https://github.com/llvm/llvm-project/pull/151428.diff 4 Files Affected:
diff --git a/clang/include/clang/Format/Format.h b/clang/include/clang/Format/Format.h
index 31582a40de866..e13df9df83e18 100644
--- a/clang/include/clang/Format/Format.h
+++ b/clang/include/clang/Format/Format.h
@@ -878,6 +878,12 @@ struct FormatStyle {
/// \version 3.5
ShortFunctionStyle AllowShortFunctionsOnASingleLine;
+ /// Dependent on the value, function body like ``{ return 0; }`` can be
+ /// put on a single line. Only when AllowShortFunctionsOnASingleLine = None
+ /// and AllowShortBlocksOnASingleLine != Never, the value of this option
+ /// is true.
+ bool AllowShortFunctionBodiesOnASingleLine;
+
/// Different styles for handling short if statements.
enum ShortIfStyle : int8_t {
/// Never put short ifs on the same line.
diff --git a/clang/lib/Format/Format.cpp b/clang/lib/Format/Format.cpp
index 063780721423f..61c0d399ca796 100644
--- a/clang/lib/Format/Format.cpp
+++ b/clang/lib/Format/Format.cpp
@@ -3828,6 +3828,9 @@ reformat(const FormatStyle &Style, StringRef Code,
default:
break;
}
+ Expanded.AllowShortFunctionBodiesOnASingleLine =
+ Expanded.AllowShortFunctionsOnASingleLine == FormatStyle::SFS_None &&
+ Expanded.AllowShortBlocksOnASingleLine != FormatStyle::SBS_Never;
if (Expanded.DisableFormat)
return {tooling::Replacements(), 0};
diff --git a/clang/lib/Format/UnwrappedLineFormatter.cpp b/clang/lib/Format/UnwrappedLineFormatter.cpp
index 0adf7ee9ed543..44c767a0db9b8 100644
--- a/clang/lib/Format/UnwrappedLineFormatter.cpp
+++ b/clang/lib/Format/UnwrappedLineFormatter.cpp
@@ -257,6 +257,12 @@ class LineJoiner {
return tryMergeSimpleBlock(I, E, Limit);
}
+ if (TheLine->Last->is(TT_FunctionLBrace) &&
+ TheLine->First == TheLine->Last &&
+ Style.AllowShortFunctionBodiesOnASingleLine) {
+ return tryMergeSimpleBlock(I, E, Limit);
+ }
+
const auto *PreviousLine = I != AnnotatedLines.begin() ? I[-1] : nullptr;
// Handle empty record blocks where the brace has already been wrapped.
if (PreviousLine && TheLine->Last->is(tok::l_brace) &&
@@ -532,6 +538,20 @@ class LineJoiner {
}
return MergedLines;
}
+
+ // Previously, UnwrappedLineParser would move the left brace to a new line
+ // when AllowShortFunctionBodiesOnASingleLine is enabled. However, if the
+ // function body cannot fit on a single line, and Style.BraceWrapping.AfterFunction
+ // is false, we should merge the function name and the left brace back onto
+ // the same line
+ if (NextLine.First->is(TT_FunctionLBrace) &&
+ Style.AllowShortFunctionBodiesOnASingleLine &&
+ !Style.BraceWrapping.AfterFunction) {
+ unsigned MergedLines = 0;
+ MergedLines = tryMergeSimpleBlock(I + 1, E, Limit);
+ return MergedLines > 0 ? 0 : 1;
+ }
+
auto IsElseLine = [&TheLine]() -> bool {
const FormatToken *First = TheLine->First;
if (First->is(tok::kw_else))
diff --git a/clang/lib/Format/UnwrappedLineParser.cpp b/clang/lib/Format/UnwrappedLineParser.cpp
index 91b8fdc8a3c38..7dd59c1cbd678 100644
--- a/clang/lib/Format/UnwrappedLineParser.cpp
+++ b/clang/lib/Format/UnwrappedLineParser.cpp
@@ -1921,6 +1921,10 @@ void UnwrappedLineParser::parseStructuralElement(
}
} else if (Style.BraceWrapping.AfterFunction) {
addUnwrappedLine();
+ } else if (Style.AllowShortFunctionBodiesOnASingleLine) {
+ // Wrap the left brace here; we'll try to merge it back
+ // later if needed.
+ addUnwrappedLine();
}
if (!Previous || Previous->isNot(TT_TypeDeclarationParen))
FormatTok->setFinalizedType(TT_FunctionLBrace);
|
✅ With the latest revision this PR passed the C/C++ code formatter. |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
You are missing unit tests. clang/unittests/Format/FromatTest.cpp
.
@@ -1921,6 +1921,10 @@ void UnwrappedLineParser::parseStructuralElement( | |||
} | |||
} else if (Style.BraceWrapping.AfterFunction) { | |||
addUnwrappedLine(); | |||
} else if (Style.AllowShortFunctionBodiesOnASingleLine) { | |||
// Wrap the left brace here; we'll try to merge it back |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Why is this needed? It seems wrong to me.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
If Style.AllowShortFunctionBodiesOnSingleLine = true
, I modified UnwrappedLineParser to parse
int main() {
//...
}
into unwrapped lines ["int main()", "{", ..., "}"], not ["int main() {", ..., "}"] as usual. If clang-format can't put function body on a single line, I want to merge "int main()" and "{" back if possible.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
The reason I parse the { in void foo() { as an unwrapped line is to allow merging the { and the function body into one line when the function body is very short.
clang-format doesn't put short function body on a single line even if user asks to put short blocks on a single line and do not put a whole function on a single line. Add tryMergeSimpleBlocks() if we find user want to put short function body on a single line. Signed-off-by: Lidong Yan <[email protected]>
7a074db
to
25d45a4
Compare
Fix issue #145161