https://github.com/sstwcw updated https://github.com/llvm/llvm-project/pull/201995
>From 91eae68f296772d06ca1ab418bd219366b58b20a Mon Sep 17 00:00:00 2001 From: sstwcw <[email protected]> Date: Sat, 6 Jun 2026 02:46:08 +0000 Subject: [PATCH 1/2] [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 };", >From 83aec246c61e53f9b70cd7d9e2ee21e12d5b8bcd Mon Sep 17 00:00:00 2001 From: sstwcw <[email protected]> Date: Mon, 8 Jun 2026 12:59:57 +0000 Subject: [PATCH 2/2] Remove the field --- clang/lib/Format/DefinitionBlockSeparator.cpp | 5 ++++- clang/lib/Format/FormatToken.h | 15 +++++---------- clang/lib/Format/FormatTokenLexer.cpp | 4 +--- 3 files changed, 10 insertions(+), 14 deletions(-) diff --git a/clang/lib/Format/DefinitionBlockSeparator.cpp b/clang/lib/Format/DefinitionBlockSeparator.cpp index 96833a24d66ce..6b52b1fc0deff 100644 --- a/clang/lib/Format/DefinitionBlockSeparator.cpp +++ b/clang/lib/Format/DefinitionBlockSeparator.cpp @@ -88,8 +88,11 @@ void DefinitionBlockSeparator::separateBlocks( assert(TargetLine); assert(TargetToken); - if (TargetToken->FinalizedNewLinesBefore) + // Lines should not be added in the disabled region. + if (TargetToken->is(tok::comment) && + isClangFormatOn(TargetToken->TokenText)) { 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 7fb1b6a1d6f46..556bb0f3dd0af 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), FinalizedNewLinesBefore(false), - Finalized(false), ClosesRequiresClause(false), - EndsCppAttributeGroup(false), BlockKind(BK_Unknown), - Decision(FD_Unformatted), PackingKind(PPK_Inconclusive), - TypeIsFinalized(false), Type(TT_Unknown) {} + ContinuesLineCommentSection(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,11 +397,6 @@ 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 5ac35b5a98680..92571c012bdb2 100644 --- a/clang/lib/Format/FormatTokenLexer.cpp +++ b/clang/lib/Format/FormatTokenLexer.cpp @@ -1598,10 +1598,8 @@ 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; _______________________________________________ cfe-commits mailing list [email protected] https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits
