[clang] [clang-format] Respect definition separators when MaxEmptyLinesToKeep: 0 (PR #206406)
via cfe-commits
cfe-commits at lists.llvm.org
Tue Jul 14 06:11:13 PDT 2026
https://github.com/gautamnsankar updated https://github.com/llvm/llvm-project/pull/206406
>From fe22ab60bdf87e46f504e850d9b5417983c571b0 Mon Sep 17 00:00:00 2001
From: Gautam Neelakantan Sankar <gautam.neelakantan.sankar at gmail.com>
Date: Mon, 29 Jun 2026 15:08:44 +0900
Subject: [PATCH] [clang-format] Respect definition separators when
MaxEmptyLinesToKeep: 0
---
clang/lib/Format/UnwrappedLineFormatter.cpp | 12 +++++--
.../Format/DefinitionBlockSeparatorTest.cpp | 31 +++++++++++++++++++
2 files changed, 41 insertions(+), 2 deletions(-)
diff --git a/clang/lib/Format/UnwrappedLineFormatter.cpp b/clang/lib/Format/UnwrappedLineFormatter.cpp
index 7ea424349d923..e7ce95b1d5628 100644
--- a/clang/lib/Format/UnwrappedLineFormatter.cpp
+++ b/clang/lib/Format/UnwrappedLineFormatter.cpp
@@ -1633,8 +1633,16 @@ static auto computeNewlines(const AnnotatedLine &Line,
const SmallVectorImpl<AnnotatedLine *> &Lines,
const FormatStyle &Style) {
const auto &RootToken = *Line.First;
- auto Newlines =
- std::min(RootToken.NewlinesBefore, Style.MaxEmptyLinesToKeep + 1);
+
+ unsigned MaxNewlines = Style.MaxEmptyLinesToKeep + 1;
+ if (Style.SeparateDefinitionBlocks == FormatStyle::SDS_Always &&
+ RootToken.NewlinesBefore > 1 && PreviousLine &&
+ !RootToken.is(tok::l_brace) && Line.MightBeFunctionDecl &&
+ Line.mightBeFunctionDefinition()) {
+ MaxNewlines = std::max(MaxNewlines, 2u);
+ }
+
+ auto Newlines = std::min(RootToken.NewlinesBefore, MaxNewlines);
// Remove empty lines before "}" where applicable.
if (RootToken.is(tok::r_brace) &&
(!RootToken.Next ||
diff --git a/clang/unittests/Format/DefinitionBlockSeparatorTest.cpp b/clang/unittests/Format/DefinitionBlockSeparatorTest.cpp
index 5e4c574d68dbb..960ed5be335f9 100644
--- a/clang/unittests/Format/DefinitionBlockSeparatorTest.cpp
+++ b/clang/unittests/Format/DefinitionBlockSeparatorTest.cpp
@@ -391,6 +391,37 @@ TEST_F(DefinitionBlockSeparatorTest, Always) {
Style, Prefix + Infix + Postfix);
}
+TEST_F(DefinitionBlockSeparatorTest, AlwaysMaxEmptyLinesZeroAllman) {
+ FormatStyle Style = getLLVMStyle();
+ Style.BreakBeforeBraces = FormatStyle::BS_Allman;
+ Style.MaxEmptyLinesToKeep = 0;
+ Style.SeparateDefinitionBlocks = FormatStyle::SDS_Always;
+ Style.AllowShortFunctionsOnASingleLine = FormatStyle::ShortFunctionStyle();
+
+ constexpr StringRef Input = "int my_function(int a)\n"
+ "\n"
+ "{\n"
+ " return a;\n"
+ "}\n"
+ "int other_function(int a)\n"
+ "\n"
+ "{\n"
+ " return a;\n"
+ "}\n";
+
+ constexpr StringRef Expected = "int my_function(int a)\n"
+ "{\n"
+ " return a;\n"
+ "}\n"
+ "\n"
+ "int other_function(int a)\n"
+ "{\n"
+ " return a;\n"
+ "}\n";
+
+ verifyFormat(Input, Style, Expected);
+}
+
TEST_F(DefinitionBlockSeparatorTest, Never) {
FormatStyle Style = getLLVMStyle();
Style.SeparateDefinitionBlocks = FormatStyle::SDS_Never;
More information about the cfe-commits
mailing list