[PATCH] D151954: [clang-format] Fix overlapping whitespace replacements before PPDirective

Owen Pan via Phabricator via cfe-commits cfe-commits at lists.llvm.org
Thu Jun 1 18:02:56 PDT 2023


owenpan created this revision.
Herald added projects: All, clang, clang-format.
Herald added a subscriber: cfe-commits.
Herald added reviewers: rymiel, HazardyKnusperkeks, MyDeveloperDay.
owenpan requested review of this revision.

If the first token of an annotated line is finalized, reuse its `NewlinesBefore` value to avoid potential overlapping whitespace replacements before preprocessor branching directives.

Fixes https://github.com/llvm/llvm-project/issues/62892.


Repository:
  rG LLVM Github Monorepo

https://reviews.llvm.org/D151954

Files:
  clang/lib/Format/UnwrappedLineFormatter.cpp
  clang/unittests/Format/FormatTest.cpp


Index: clang/unittests/Format/FormatTest.cpp
===================================================================
--- clang/unittests/Format/FormatTest.cpp
+++ clang/unittests/Format/FormatTest.cpp
@@ -12856,6 +12856,22 @@
                "  void f() {}\n"
                "};\n",
                Style);
+  verifyFormat("struct foo {\n"
+               "#ifdef FOO\n"
+               "#else\n"
+               "private:\n"
+               "\n"
+               "#endif\n"
+               "};",
+               "struct foo {\n"
+               "#ifdef FOO\n"
+               "#else\n"
+               "private:\n"
+               "\n"
+               "\n"
+               "#endif\n"
+               "};",
+               Style);
 
   Style.EmptyLineAfterAccessModifier = FormatStyle::ELAAMS_Always;
   verifyFormat("struct foo {\n"
Index: clang/lib/Format/UnwrappedLineFormatter.cpp
===================================================================
--- clang/lib/Format/UnwrappedLineFormatter.cpp
+++ clang/lib/Format/UnwrappedLineFormatter.cpp
@@ -1418,19 +1418,12 @@
   return Penalty;
 }
 
-void UnwrappedLineFormatter::formatFirstToken(
-    const AnnotatedLine &Line, const AnnotatedLine *PreviousLine,
-    const AnnotatedLine *PrevPrevLine,
-    const SmallVectorImpl<AnnotatedLine *> &Lines, unsigned Indent,
-    unsigned NewlineIndent) {
-  FormatToken &RootToken = *Line.First;
-  if (RootToken.is(tok::eof)) {
-    unsigned Newlines = std::min(RootToken.NewlinesBefore, 1u);
-    unsigned TokenIndent = Newlines ? NewlineIndent : 0;
-    Whitespaces->replaceWhitespace(RootToken, Newlines, TokenIndent,
-                                   TokenIndent);
-    return;
-  }
+static auto newlinesBeforeLine(const AnnotatedLine &Line,
+                               const AnnotatedLine *PreviousLine,
+                               const AnnotatedLine *PrevPrevLine,
+                               const SmallVectorImpl<AnnotatedLine *> &Lines,
+                               const FormatToken &RootToken,
+                               const FormatStyle &Style) {
   unsigned Newlines =
       std::min(RootToken.NewlinesBefore, Style.MaxEmptyLinesToKeep + 1);
   // Remove empty lines before "}" where applicable.
@@ -1510,6 +1503,27 @@
     }
   }
 
+  return Newlines;
+}
+
+void UnwrappedLineFormatter::formatFirstToken(
+    const AnnotatedLine &Line, const AnnotatedLine *PreviousLine,
+    const AnnotatedLine *PrevPrevLine,
+    const SmallVectorImpl<AnnotatedLine *> &Lines, unsigned Indent,
+    unsigned NewlineIndent) {
+  FormatToken &RootToken = *Line.First;
+  if (RootToken.is(tok::eof)) {
+    unsigned Newlines = std::min(RootToken.NewlinesBefore, 1u);
+    unsigned TokenIndent = Newlines ? NewlineIndent : 0;
+    Whitespaces->replaceWhitespace(RootToken, Newlines, TokenIndent,
+                                   TokenIndent);
+    return;
+  }
+
+  const auto Newlines =
+      RootToken.Finalized ? RootToken.NewlinesBefore
+                          : newlinesBeforeLine(Line, PreviousLine, PrevPrevLine,
+                                               Lines, RootToken, Style);
   if (Newlines)
     Indent = NewlineIndent;
 


-------------- next part --------------
A non-text attachment was scrubbed...
Name: D151954.527683.patch
Type: text/x-patch
Size: 3165 bytes
Desc: not available
URL: <http://lists.llvm.org/pipermail/cfe-commits/attachments/20230602/84851735/attachment.bin>


More information about the cfe-commits mailing list