alecto created this revision.
alecto added reviewers: Richard, smith.
Herald added a project: All.
alecto requested review of this revision.
Herald added a project: clang.
Herald added a subscriber: cfe-commits.

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

Given configuration:

  SeparateDefinitionBlocks: Always
  DefinitionBlockSpacing: 2

Two spaces will be inserted between definition blocks. Code before
formatting:

  /// f is a function
  void f() {
      // Some code
      // More code
      return;
  }
  /// g is another function
  void g() {
      // Some other code
  }

Versus code after formatting:

  /// f is a function
  void f() {
      // Some code
      // More code
      return;
  }
  ​
  ​
  /// g is another function
  void g() {
      // Some other code
  }

Note: two zero width spaces were inserted into the commit message in
order to prevent git from removing the additional lines inside the
commit. These will not appear in formatted code.


Repository:
  rG LLVM Github Monorepo

https://reviews.llvm.org/D132256

Files:
  clang/include/clang/Format/Format.h
  clang/lib/Format/DefinitionBlockSeparator.cpp
  clang/lib/Format/Format.cpp
  clang/unittests/Format/DefinitionBlockSeparatorTest.cpp

Index: clang/unittests/Format/DefinitionBlockSeparatorTest.cpp
===================================================================
--- clang/unittests/Format/DefinitionBlockSeparatorTest.cpp
+++ clang/unittests/Format/DefinitionBlockSeparatorTest.cpp
@@ -601,6 +601,90 @@
                "}",
                Style);
 }
+
+TEST_F(DefinitionBlockSeparatorTest, DefinitionBlockSpacing) {
+  FormatStyle Style = getLLVMStyle();
+  Style.SeparateDefinitionBlocks = FormatStyle::SDS_Always;
+  Style.DefinitionBlockSpacing = 2;
+  /// This has to be set, otherwise the extra lines will be removed
+  Style.MaxEmptyLinesToKeep = 2;
+  verifyFormat("int foo(int i, int j) {\n"
+               "  int r = i + j;\n"
+               "  return r;\n"
+               "}\n"
+               "\n"
+               "\n"
+               "int bar(int j, int k) {\n"
+               "  int r = j + k;\n"
+               "  return r;\n"
+               "}",
+               Style);
+
+  verifyFormat("struct foo {\n"
+               "  int i, j;\n"
+               "};\n"
+               "\n"
+               "\n"
+               "struct bar {\n"
+               "  int j, k;\n"
+               "};",
+               Style);
+
+  verifyFormat("union foo {\n"
+               "  int i, j;\n"
+               "};\n"
+               "\n"
+               "\n"
+               "union bar {\n"
+               "  int j, k;\n"
+               "};",
+               Style);
+
+  verifyFormat("class foo {\n"
+               "  int i, j;\n"
+               "};\n"
+               "\n"
+               "\n"
+               "class bar {\n"
+               "  int j, k;\n"
+               "};",
+               Style);
+
+  verifyFormat("namespace foo {\n"
+               "int i, j;\n"
+               "}\n"
+               "\n"
+               "\n"
+               "namespace bar {\n"
+               "int j, k;\n"
+               "}",
+               Style);
+
+  verifyFormat("enum Foo { FOO, BAR };\n"
+               "\n"
+               "\n"
+               "enum Bar { FOOBAR, BARFOO };\n",
+               Style);
+
+  FormatStyle BreakAfterReturnTypeStyle = Style;
+  BreakAfterReturnTypeStyle.AlwaysBreakAfterReturnType = FormatStyle::RTBS_All;
+  // Test uppercased long typename
+  verifyFormat("class Foo {\n"
+               "  void\n"
+               "  Bar(int t, int p) {\n"
+               "    int r = t + p;\n"
+               "    return r;\n"
+               "  }\n"
+               "\n"
+               "\n"
+               "  HRESULT\n"
+               "  Foobar(int t, int p) {\n"
+               "    int r = t * p;\n"
+               "    return r;\n"
+               "  }\n"
+               "}\n",
+               BreakAfterReturnTypeStyle);
+}
 } // namespace
 } // namespace format
 } // namespace clang
Index: clang/lib/Format/Format.cpp
===================================================================
--- clang/lib/Format/Format.cpp
+++ clang/lib/Format/Format.cpp
@@ -746,6 +746,7 @@
                    Style.ConstructorInitializerIndentWidth);
     IO.mapOptional("ContinuationIndentWidth", Style.ContinuationIndentWidth);
     IO.mapOptional("Cpp11BracedListStyle", Style.Cpp11BracedListStyle);
+    IO.mapOptional("DefinitionBlockSpacing", Style.DefinitionBlockSpacing);
     IO.mapOptional("DeriveLineEnding", Style.DeriveLineEnding);
     IO.mapOptional("DerivePointerAlignment", Style.DerivePointerAlignment);
     IO.mapOptional("DisableFormat", Style.DisableFormat);
@@ -1244,6 +1245,7 @@
   // Off by default Qualifier ordering
   LLVMStyle.QualifierAlignment = FormatStyle::QAS_Leave;
 
+  LLVMStyle.DefinitionBlockSpacing = 1;
   LLVMStyle.DeriveLineEnding = true;
   LLVMStyle.DerivePointerAlignment = false;
   LLVMStyle.EmptyLineAfterAccessModifier = FormatStyle::ELAAMS_Never;
Index: clang/lib/Format/DefinitionBlockSeparator.cpp
===================================================================
--- clang/lib/Format/DefinitionBlockSeparator.cpp
+++ clang/lib/Format/DefinitionBlockSeparator.cpp
@@ -66,7 +66,9 @@
     return false;
   };
   unsigned NewlineCount =
-      (Style.SeparateDefinitionBlocks == FormatStyle::SDS_Always ? 1 : 0) + 1;
+      1 + (Style.SeparateDefinitionBlocks == FormatStyle::SDS_Always
+               ? Style.DefinitionBlockSpacing
+               : 0);
   WhitespaceManager Whitespaces(
       Env.getSourceManager(), Style,
       Style.DeriveLineEnding
Index: clang/include/clang/Format/Format.h
===================================================================
--- clang/include/clang/Format/Format.h
+++ clang/include/clang/Format/Format.h
@@ -3177,6 +3177,18 @@
   /// \version 14
   SeparateDefinitionStyle SeparateDefinitionBlocks;
 
+  /// The number of empty lines to use when separating definition blocks.
+  /// Defaults to 1.
+  ///
+  /// This determines the number of empty lines to use when
+  /// SeparateDefinitionBlocks == SeparateDefinitionStyle::SDS_Always.
+  ///
+  /// Note: if MaxEmptyLinesToKeep < DefinitionBlockSpacing, then additional
+  /// lines will be removed. MaxEmptyLinesToKeep should be greater than or equal
+  /// to DefinitionBlockSpacing.
+  /// \version 15
+  unsigned DefinitionBlockSpacing;
+
   /// The maximal number of unwrapped lines that a short namespace spans.
   /// Defaults to 1.
   ///
@@ -3892,6 +3904,7 @@
                R.ConstructorInitializerIndentWidth &&
            ContinuationIndentWidth == R.ContinuationIndentWidth &&
            Cpp11BracedListStyle == R.Cpp11BracedListStyle &&
+           DefinitionBlockSpacing == R.DefinitionBlockSpacing &&
            DeriveLineEnding == R.DeriveLineEnding &&
            DerivePointerAlignment == R.DerivePointerAlignment &&
            DisableFormat == R.DisableFormat &&
_______________________________________________
cfe-commits mailing list
cfe-commits@lists.llvm.org
https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits

Reply via email to