https://github.com/sstwcw created https://github.com/llvm/llvm-project/pull/201995
Previously, a blank got inserted before the `// clang-format off` comment with the `SeparateDefinitionBlocks` option set. Fixes #106983 and #146317. >From 91eae68f296772d06ca1ab418bd219366b58b20a Mon Sep 17 00:00:00 2001 From: sstwcw <[email protected]> Date: Sat, 6 Jun 2026 02:46:08 +0000 Subject: [PATCH] [clang-format] Stop inserting blank line in disabled region Previously, a blank got inserted before the `// clang-format off` comment with the `SeparateDefinitionBlocks` option set. Fixes #106983 and #146317. --- clang/lib/Format/DefinitionBlockSeparator.cpp | 2 ++ clang/lib/Format/FormatToken.h | 15 ++++++---- clang/lib/Format/FormatTokenLexer.cpp | 4 ++- .../Format/DefinitionBlockSeparatorTest.cpp | 30 +++++++++++++++++++ 4 files changed, 45 insertions(+), 6 deletions(-) diff --git a/clang/lib/Format/DefinitionBlockSeparator.cpp b/clang/lib/Format/DefinitionBlockSeparator.cpp index d16f8ddd5a2ec..96833a24d66ce 100644 --- a/clang/lib/Format/DefinitionBlockSeparator.cpp +++ b/clang/lib/Format/DefinitionBlockSeparator.cpp @@ -88,6 +88,8 @@ void DefinitionBlockSeparator::separateBlocks( assert(TargetLine); assert(TargetToken); + if (TargetToken->FinalizedNewLinesBefore) + return; // Do not handle EOF newlines. if (TargetToken->is(tok::eof)) return; diff --git a/clang/lib/Format/FormatToken.h b/clang/lib/Format/FormatToken.h index 556bb0f3dd0af..7fb1b6a1d6f46 100644 --- a/clang/lib/Format/FormatToken.h +++ b/clang/lib/Format/FormatToken.h @@ -328,11 +328,11 @@ struct FormatToken { IsUnterminatedLiteral(false), CanBreakBefore(false), ClosesTemplateDeclaration(false), StartsBinaryExpression(false), EndsBinaryExpression(false), PartOfMultiVariableDeclStmt(false), - ContinuesLineCommentSection(false), Finalized(false), - ClosesRequiresClause(false), EndsCppAttributeGroup(false), - BlockKind(BK_Unknown), Decision(FD_Unformatted), - PackingKind(PPK_Inconclusive), TypeIsFinalized(false), - Type(TT_Unknown) {} + ContinuesLineCommentSection(false), FinalizedNewLinesBefore(false), + Finalized(false), ClosesRequiresClause(false), + EndsCppAttributeGroup(false), BlockKind(BK_Unknown), + Decision(FD_Unformatted), PackingKind(PPK_Inconclusive), + TypeIsFinalized(false), Type(TT_Unknown) {} /// The \c Token. Token Tok; @@ -397,6 +397,11 @@ struct FormatToken { /// Only set to true if \c Type == \c TT_LineComment. unsigned ContinuesLineCommentSection : 1; + /// Empty lines should not be added before the token. But its indentation may + /// be changed. Set for the comment that ends a region where formatting is + /// disabled. + unsigned FinalizedNewLinesBefore : 1; + /// If \c true, this token has been fully formatted (indented and /// potentially re-formatted inside), and we do not allow further formatting /// changes. diff --git a/clang/lib/Format/FormatTokenLexer.cpp b/clang/lib/Format/FormatTokenLexer.cpp index 92571c012bdb2..5ac35b5a98680 100644 --- a/clang/lib/Format/FormatTokenLexer.cpp +++ b/clang/lib/Format/FormatTokenLexer.cpp @@ -1598,8 +1598,10 @@ void FormatTokenLexer::readRawToken(FormatToken &Tok) { if ((Style.isJavaScript() || Style.isProto()) && Tok.is(tok::char_constant)) Tok.Tok.setKind(tok::string_literal); - if (Tok.is(tok::comment) && isClangFormatOn(Tok.TokenText)) + if (Tok.is(tok::comment) && isClangFormatOn(Tok.TokenText)) { FormattingDisabled = false; + Tok.FinalizedNewLinesBefore = true; + } Tok.Finalized = FormattingDisabled; diff --git a/clang/unittests/Format/DefinitionBlockSeparatorTest.cpp b/clang/unittests/Format/DefinitionBlockSeparatorTest.cpp index d2b43ca2d70aa..5e4c574d68dbb 100644 --- a/clang/unittests/Format/DefinitionBlockSeparatorTest.cpp +++ b/clang/unittests/Format/DefinitionBlockSeparatorTest.cpp @@ -137,6 +137,36 @@ TEST_F(DefinitionBlockSeparatorTest, Basic) { "}", Style); + // There should not be an extra line when formatting is disabled. + verifyFormat("// clang-format off\n" + "void function()\n" + "{\n" + "\n" + "}\n" + "// clang-format on", + Style, + "// clang-format off\n" + "void function()\n" + "{\n" + "\n" + "}\n" + "// clang-format on", + /*Inverse=*/false); + verifyFormat("class X {\n" + " // clang-format off\n" + "#pragma warning(suppress : 4373)\n" + " void foo() {}\n" + " // clang-format on\n" + "};\n", + Style, + "class X {\n" + " // clang-format off\n" + "#pragma warning(suppress : 4373)\n" + " void foo() {}\n" + " // clang-format on\n" + "};\n", + /*Inverse=*/false); + verifyFormat("enum Foo { FOO, BAR };\n" "\n" "enum Bar { FOOBAR, BARFOO };", _______________________________________________ cfe-commits mailing list [email protected] https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits
