From f06121a3c16e68cb6fee9b77c24c400e7ff8b111 Mon Sep 17 00:00:00 2001 From: Ruoyu Zhong Date: Tue, 21 Oct 2025 02:44:16 +0800 Subject: [PATCH] [clang-format] Fix repeated backslash insertion in macro line comments MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Line comments in preprocessor directives were incorrectly marked as continuing the directive, causing clang-format to add backslashes after them on repeated runs. Backslashes appended after line comments in this way do not continue the PP directive because the following line would also become part of the comment. Fix by unsetting InPPDirective in WhitespaceManager::replaceWhitespace for line comments in two places: when breaking lines and when formatting tokens on the same line. This stops the spurious backslash insertion for both standalone line comments after PP directives and trailing line comments after macro bodies. Fixes https://github.com/llvm/llvm-project/issues/164282. Co-authored-by: Björn Schäpers Signed-off-by: Ruoyu Zhong --- clang/lib/Format/ContinuationIndenter.cpp | 11 +++++++---- clang/unittests/Format/FormatTestComments.cpp | 19 +++++++++++++++++++ 2 files changed, 26 insertions(+), 4 deletions(-) diff --git a/clang/lib/Format/ContinuationIndenter.cpp b/clang/lib/Format/ContinuationIndenter.cpp index 26a95421775f3..02ee170d9503f 100644 --- a/clang/lib/Format/ContinuationIndenter.cpp +++ b/clang/lib/Format/ContinuationIndenter.cpp @@ -798,9 +798,11 @@ void ContinuationIndenter::addTokenOnCurrentLine(LineState &State, bool DryRun, } if (!DryRun) { + const bool ContinuePPDirective = + State.Line->InMacroBody && Current.isNot(TT_LineComment); Whitespaces.replaceWhitespace(Current, /*Newlines=*/0, Spaces, State.Column + Spaces + PPColumnCorrection, - /*IsAligned=*/false, State.Line->InMacroBody); + /*IsAligned=*/false, ContinuePPDirective); } // If "BreakBeforeInheritanceComma" mode, don't break within the inheritance @@ -1176,10 +1178,11 @@ unsigned ContinuationIndenter::addTokenOnNewLine(LineState &State, // about removing empty lines on closing blocks. Special case them here. MaxEmptyLinesToKeep = 1; } - unsigned Newlines = + const unsigned Newlines = std::max(1u, std::min(Current.NewlinesBefore, MaxEmptyLinesToKeep)); - bool ContinuePPDirective = - State.Line->InPPDirective && State.Line->Type != LT_ImportStatement; + const bool ContinuePPDirective = State.Line->InPPDirective && + State.Line->Type != LT_ImportStatement && + Current.isNot(TT_LineComment); Whitespaces.replaceWhitespace(Current, Newlines, State.Column, State.Column, CurrentState.IsAligned, ContinuePPDirective); } diff --git a/clang/unittests/Format/FormatTestComments.cpp b/clang/unittests/Format/FormatTestComments.cpp index fc80bf4024fd9..6b433bb384864 100644 --- a/clang/unittests/Format/FormatTestComments.cpp +++ b/clang/unittests/Format/FormatTestComments.cpp @@ -839,6 +839,25 @@ TEST_F(FormatTestComments, MultiLineCommentsInDefines) { getLLVMStyleWithColumns(17))); } +TEST_F(FormatTestComments, LineCommentsInMacrosDoNotGetEscapedNewlines) { + FormatStyle Style = getLLVMStyleWithColumns(0); + Style.ReflowComments = FormatStyle::RCS_Never; + verifyFormat("#define FOO (1U) // comment\n" + " // comment", + Style); + + Style.ColumnLimit = 32; + verifyFormat("#define SOME_MACRO(x) x\n" + "#define FOO \\\n" + " SOME_MACRO(1) + \\\n" + " SOME_MACRO(2) // comment\n" + " // comment", + "#define SOME_MACRO(x) x\n" + "#define FOO SOME_MACRO(1) + SOME_MACRO(2) // comment\n" + " // comment", + Style); +} + TEST_F(FormatTestComments, ParsesCommentsAdjacentToPPDirectives) { EXPECT_EQ("namespace {}\n// Test\n#define A", format("namespace {}\n // Test\n#define A"));