https://github.com/owenca updated 
https://github.com/llvm/llvm-project/pull/106145

>From dde31f15552cb4f95a50e0835238062a0e6c69d8 Mon Sep 17 00:00:00 2001
From: dmasloff <dmaslo...@gmail.com>
Date: Mon, 26 Aug 2024 22:11:05 +0300
Subject: [PATCH 01/10] fix merge conflict

---
 clang/docs/ClangFormatStyleOptions.rst      |  42 ++++
 clang/include/clang/Format/Format.h         |  40 +++-
 clang/lib/Format/Format.cpp                 |  15 ++
 clang/lib/Format/UnwrappedLineFormatter.cpp |  42 ++++
 clang/unittests/Format/FormatTest.cpp       | 205 ++++++++++++++++++++
 5 files changed, 343 insertions(+), 1 deletion(-)

diff --git a/clang/docs/ClangFormatStyleOptions.rst 
b/clang/docs/ClangFormatStyleOptions.rst
index d9b3f666df03c0..df65d46f0275da 100644
--- a/clang/docs/ClangFormatStyleOptions.rst
+++ b/clang/docs/ClangFormatStyleOptions.rst
@@ -6843,6 +6843,48 @@ the configuration (without a prefix: ``Auto``).
 
   For example: BOOST_PP_STRINGIZE
 
+.. _WrapNamespaceBodyWithEmptyLines:
+
+**WrapNamespaceBodyWithEmptyLines** (``WrapNamespaceBodyWithEmptyLinesStyle``) 
:versionbadge:`clang-format 19` :ref:`¶ <WrapNamespaceBodyWithEmptyLines>`
+  Controls number of empty lines at the begging and at the end of
+  namespace definition.
+
+  Possible values:
+
+  * ``WNBWELS_Never`` (in configuration: ``Never``)
+    Removes all empty lines at the beginning and at the end of
+    namespace definition.
+
+    .. code-block:: c++
+
+      namespace N1 {
+      namespace N2
+        function();
+      }
+      }
+
+  * ``WNBWELS_Always`` (in configuration: ``Always``)
+    Always adds an empty line at the beginning and at the end of
+    namespace definition. MaxEmptyLinesToKeep is also applied, but
+    empty lines between consecutive namespace declarations are
+    always removed.
+
+    .. code-block:: c++
+
+      namespace N1 {
+      namespace N2 {
+
+        function();
+
+      }
+      }
+
+  * ``WNBWELS_Leave`` (in configuration: ``Leave``)
+    Keeps existing newlines at the beginning and at the end of
+    namespace definition using MaxEmptyLinesToKeep for formatting.
+
+
+
 .. END_FORMAT_STYLE_OPTIONS
 
 Adding additional style options
diff --git a/clang/include/clang/Format/Format.h 
b/clang/include/clang/Format/Format.h
index bb34f2d33ac15e..dc816d31264024 100644
--- a/clang/include/clang/Format/Format.h
+++ b/clang/include/clang/Format/Format.h
@@ -5143,6 +5143,43 @@ struct FormatStyle {
   /// \version 11
   std::vector<std::string> WhitespaceSensitiveMacros;
 
+  /// Different styles for modify number of empty lines in
+  /// the beginning and at the of end of namespaces.
+  enum WrapNamespaceBodyWithEmptyLinesStyle : int8_t {
+    /// Removes all empty lines at the beginning and at the end of
+    /// namespace definition.
+    /// \code
+    ///   namespace N1 {
+    ///   namespace N2
+    ///     function();
+    ///   }
+    ///   }
+    /// \endcode
+    WNBWELS_Never,
+    /// Always adds an empty line at the beginning and at the end of
+    /// namespace definition. MaxEmptyLinesToKeep is also applied, but
+    /// empty lines between consecutive namespace declarations are
+    /// always removed.
+    /// \code
+    ///   namespace N1 {
+    ///   namespace N2 {
+    ///
+    ///     function();
+    ///
+    ///   }
+    ///   }
+    /// \endcode
+    WNBWELS_Always,
+    /// Keeps existing newlines at the beginning and at the end of
+    /// namespace definition using MaxEmptyLinesToKeep for formatting.
+    WNBWELS_Leave
+  };
+
+  /// Controls number of empty lines at the begging and at the end of
+  /// namespace definition.
+  /// \version 19
+  WrapNamespaceBodyWithEmptyLinesStyle WrapNamespaceBodyWithEmptyLines;
+
   bool operator==(const FormatStyle &R) const {
     return AccessModifierOffset == R.AccessModifierOffset &&
            AlignAfterOpenBracket == R.AlignAfterOpenBracket &&
@@ -5326,7 +5363,8 @@ struct FormatStyle {
            UseTab == R.UseTab && VariableTemplates == R.VariableTemplates &&
            VerilogBreakBetweenInstancePorts ==
                R.VerilogBreakBetweenInstancePorts &&
-           WhitespaceSensitiveMacros == R.WhitespaceSensitiveMacros;
+           WhitespaceSensitiveMacros == R.WhitespaceSensitiveMacros &&
+           WrapNamespaceBodyWithEmptyLines == 
R.WrapNamespaceBodyWithEmptyLines;
   }
 
   std::optional<FormatStyle> GetLanguageStyle(LanguageKind Language) const;
diff --git a/clang/lib/Format/Format.cpp b/clang/lib/Format/Format.cpp
index a5657f2d910f68..e51d7ac2e5b6c4 100644
--- a/clang/lib/Format/Format.cpp
+++ b/clang/lib/Format/Format.cpp
@@ -839,6 +839,18 @@ template <> struct 
ScalarEnumerationTraits<FormatStyle::UseTabStyle> {
   }
 };
 
+template <>
+struct ScalarEnumerationTraits<
+    FormatStyle::WrapNamespaceBodyWithEmptyLinesStyle> {
+  static void
+  enumeration(IO &IO,
+              FormatStyle::WrapNamespaceBodyWithEmptyLinesStyle &Value) {
+    IO.enumCase(Value, "Never", FormatStyle::WNBWELS_Never);
+    IO.enumCase(Value, "Always", FormatStyle::WNBWELS_Always);
+    IO.enumCase(Value, "Leave", FormatStyle::WNBWELS_Leave);
+  }
+};
+
 template <> struct MappingTraits<FormatStyle> {
   static void mapping(IO &IO, FormatStyle &Style) {
     // When reading, read the language first, we need it for 
getPredefinedStyle.
@@ -1171,6 +1183,8 @@ template <> struct MappingTraits<FormatStyle> {
                    Style.VerilogBreakBetweenInstancePorts);
     IO.mapOptional("WhitespaceSensitiveMacros",
                    Style.WhitespaceSensitiveMacros);
+    IO.mapOptional("WrapNamespaceBodyWithEmptyLines",
+                   Style.WrapNamespaceBodyWithEmptyLines);
 
     // If AlwaysBreakAfterDefinitionReturnType was specified but
     // BreakAfterReturnType was not, initialize the latter from the former for
@@ -1639,6 +1653,7 @@ FormatStyle getLLVMStyle(FormatStyle::LanguageKind 
Language) {
   LLVMStyle.WhitespaceSensitiveMacros.push_back("NS_SWIFT_NAME");
   LLVMStyle.WhitespaceSensitiveMacros.push_back("PP_STRINGIZE");
   LLVMStyle.WhitespaceSensitiveMacros.push_back("STRINGIZE");
+  LLVMStyle.WrapNamespaceBodyWithEmptyLines = FormatStyle::WNBWELS_Leave;
 
   LLVMStyle.PenaltyBreakAssignment = prec::Assignment;
   LLVMStyle.PenaltyBreakBeforeFirstCallParameter = 19;
diff --git a/clang/lib/Format/UnwrappedLineFormatter.cpp 
b/clang/lib/Format/UnwrappedLineFormatter.cpp
index 803c600cec44db..d1b80e601ef737 100644
--- a/clang/lib/Format/UnwrappedLineFormatter.cpp
+++ b/clang/lib/Format/UnwrappedLineFormatter.cpp
@@ -32,6 +32,26 @@ bool isRecordLBrace(const FormatToken &Tok) {
                      TT_StructLBrace, TT_UnionLBrace);
 }
 
+bool LineStartsNamespaceScope(const AnnotatedLine *Line,
+                              const AnnotatedLine *PreviousLine,
+                              const AnnotatedLine *PrevPrevLine) {
+  return PreviousLine &&
+         ((PreviousLine->Last->is(tok::l_brace) &&
+           PreviousLine->startsWithNamespace()) ||
+          (PrevPrevLine && PrevPrevLine->startsWithNamespace() &&
+           PreviousLine->startsWith(tok::l_brace)));
+}
+
+bool LineEndsNamespaceScope(const AnnotatedLine *Line,
+                            const SmallVectorImpl<AnnotatedLine *> &Lines) {
+  if (!Line)
+    return false;
+  const FormatToken *tok = Line->First;
+  if (!tok || tok->isNot(tok::r_brace))
+    return false;
+  return getNamespaceToken(Line, Lines) != nullptr;
+}
+
 /// Tracks the indent level of \c AnnotatedLines across levels.
 ///
 /// \c nextLine must be called for each \c AnnotatedLine, after which \c
@@ -1584,6 +1604,28 @@ static auto computeNewlines(const AnnotatedLine &Line,
     Newlines = 1;
   }
 
+  // Modify empty lines after "{" that opens namespace scope.
+  if (Style.WrapNamespaceBodyWithEmptyLines != FormatStyle::WNBWELS_Leave &&
+      LineStartsNamespaceScope(&Line, PreviousLine, PrevPrevLine)) {
+    if (Style.WrapNamespaceBodyWithEmptyLines == FormatStyle::WNBWELS_Never)
+      Newlines = std::min(Newlines, 1u);
+    else if (!Line.startsWithNamespace())
+      Newlines = std::max(Newlines, 2u);
+    else
+      Newlines = std::min(Newlines, 1u);
+  }
+
+  // Modify empty lines before "}" that closes namespace scope.
+  if (Style.WrapNamespaceBodyWithEmptyLines != FormatStyle::WNBWELS_Leave &&
+      LineEndsNamespaceScope(&Line, Lines)) {
+    if (Style.WrapNamespaceBodyWithEmptyLines == FormatStyle::WNBWELS_Never)
+      Newlines = std::min(Newlines, 1u);
+    else if (!LineEndsNamespaceScope(PreviousLine, Lines))
+      Newlines = std::max(Newlines, 2u);
+    else
+      Newlines = std::min(Newlines, 1u);
+  }
+
   // Insert or remove empty line before access specifiers.
   if (PreviousLine && RootToken.isAccessSpecifier()) {
     switch (Style.EmptyLineBeforeAccessModifier) {
diff --git a/clang/unittests/Format/FormatTest.cpp 
b/clang/unittests/Format/FormatTest.cpp
index 22b6f7e1b62e2e..fd8dba436fdcf3 100644
--- a/clang/unittests/Format/FormatTest.cpp
+++ b/clang/unittests/Format/FormatTest.cpp
@@ -28427,6 +28427,211 @@ TEST_F(FormatTest, ShortNamespacesOption) {
       Style);
 }
 
+TEST_F(FormatTest, WrapNamespaceBodyWithEmptyLinesNever) {
+  FormatStyle Style = getLLVMStyle();
+  Style.FixNamespaceComments = false;
+  Style.ShortNamespaceLines = 0;
+  Style.MaxEmptyLinesToKeep = 2;
+  Style.WrapNamespaceBodyWithEmptyLines = FormatStyle::WNBWELS_Never;
+  Style.CompactNamespaces = false;
+
+  // Empty namespace
+  verifyNoChange("namespace N {};", Style);
+
+  // Single namespace
+  verifyNoChange("namespace N {\n"
+                 "int f1(int a) { return 2 * a; }\n"
+                 "};",
+                 Style);
+
+  // Nested namespace
+  verifyNoChange("namespace N1 {\n"
+                 "namespace N2 {\n"
+                 "namespace N3 {\n"
+                 "int f1() {\n"
+                 "  int a = 1;\n"
+                 "  return a;\n"
+                 "}\n"
+                 "}\n"
+                 "}\n"
+                 "}",
+                 Style);
+
+  Style.CompactNamespaces = true;
+
+  // Empty namespace
+  verifyNoChange("namespace N {\n};", Style);
+
+  // Single namespace
+  verifyNoChange("namespace N {\n"
+                 "int f1(int a) { return 2 * a; }\n"
+                 "};",
+                 Style);
+
+  // Nested namespace
+  verifyNoChange("namespace N1 { namespace N2 { namespace N3 {\n"
+                 "int f1() {\n"
+                 "  int a = 1;\n"
+                 "  return a;\n"
+                 "}\n"
+                 "}}}",
+                 Style);
+}
+
+TEST_F(FormatTest, WrapNamespaceBodyWithEmptyLinesAlways) {
+  FormatStyle Style = getLLVMStyle();
+  Style.FixNamespaceComments = false;
+  Style.ShortNamespaceLines = 0;
+  Style.MaxEmptyLinesToKeep = 0;
+  Style.WrapNamespaceBodyWithEmptyLines = FormatStyle::WNBWELS_Always;
+  Style.CompactNamespaces = false;
+
+  // Empty namespace
+  verifyNoChange("namespace N {};", Style);
+
+  // Single namespace
+  verifyNoChange("namespace N {\n\n"
+                 "int f1(int a) { return 2 * a; }\n\n"
+                 "};",
+                 Style);
+
+  // Nested namespace
+  verifyNoChange("namespace N1 {\n"
+                 "namespace N2 {\n"
+                 "namespace N3 {\n\n"
+                 "int f1() {\n"
+                 "  int a = 1;\n"
+                 "  return a;\n"
+                 "}\n\n"
+                 "}\n"
+                 "}\n"
+                 "}",
+                 Style);
+
+  Style.CompactNamespaces = true;
+
+  // Nested namespace
+  verifyNoChange("namespace N1 { namespace N2 { namespace N3 {\n\n"
+                 "int f1() {\n"
+                 "  int a = 1;\n"
+                 "  return a;\n"
+                 "}\n\n"
+                 "}}}",
+                 Style);
+
+  Style.MaxEmptyLinesToKeep = 2;
+  Style.CompactNamespaces = false;
+
+  // Empty namespace
+  verifyNoChange("namespace N {};", Style);
+
+  // Single namespace
+  verifyNoChange("namespace N {\n\n\n"
+                 "void function()\n\n\n"
+                 "};",
+                 Style);
+
+  // Nested namespace
+  verifyFormat("namespace N1 {\n"
+               "namespace N2 {\n"
+               "namespace N3 {\n\n\n"
+               "int f1() {\n"
+               "  int a = 1;\n"
+               "  return a;\n"
+               "}\n\n\n"
+               "}\n"
+               "}\n"
+               "}",
+               "namespace N1 {\n"
+               "namespace N2 {\n\n"
+               "namespace N3 {\n\n\n"
+               "int f1() {\n"
+               "  int a = 1;\n"
+               "  return a;\n"
+               "}\n\n\n"
+               "}\n\n"
+               "}\n"
+               "}",
+               Style);
+
+  Style.CompactNamespaces = true;
+
+  // Nested namespace
+  verifyNoChange("namespace N1 { namespace N2 { namespace N3 {\n\n\n"
+                 "int f1() {\n"
+                 "  int a = 1;\n"
+                 "  return a;\n"
+                 "}\n\n\n"
+                 "}}}",
+                 Style);
+}
+
+TEST_F(FormatTest, WrapNamespaceBodyWithEmptyLinesLeave) {
+  FormatStyle Style = getLLVMStyle();
+  Style.FixNamespaceComments = false;
+  Style.ShortNamespaceLines = 0;
+  Style.MaxEmptyLinesToKeep = 0;
+  Style.WrapNamespaceBodyWithEmptyLines = FormatStyle::WNBWELS_Leave;
+  Style.CompactNamespaces = false;
+
+  // Empty namespace
+  verifyNoChange("namespace N {};", Style);
+
+  // Single namespace
+  verifyNoChange("namespace N {\n"
+                 "int f1(int a) { return 2 * a; }\n"
+                 "};",
+                 Style);
+
+  // Nested namespace
+  verifyNoChange("namespace N1 {\n"
+                 "namespace N2 {\n"
+                 "namespace N3 {\n"
+                 "int f1() {\n"
+                 "  int a = 1;\n"
+                 "  return a;\n"
+                 "}\n"
+                 "}\n"
+                 "}\n"
+                 "}",
+                 Style);
+
+  Style.MaxEmptyLinesToKeep = 2;
+
+  // Single namespace
+  verifyNoChange("namespace N {\n\n\n"
+                 "int f1(int a) { return 2 * a; }\n\n\n"
+                 "};",
+                 Style);
+
+  // Nested namespace
+  verifyNoChange("namespace N1 {\n"
+                 "namespace N2 {\n\n"
+                 "namespace N3 {\n\n\n"
+                 "int f1() {\n"
+                 "  int a = 1;\n"
+                 "  return a;\n"
+                 "}\n\n\n"
+                 "}\n\n"
+                 "}\n"
+                 "}",
+                 Style);
+
+  Style.CompactNamespaces = true;
+
+  // Empty namespace
+  verifyNoChange("namespace N {\n};", Style);
+
+  // Nested namespace
+  verifyNoChange("namespace N1 { namespace N2 { namespace N3 {\n\n\n"
+                 "int f1() {\n"
+                 "  int a = 1;\n"
+                 "  return a;\n"
+                 "}\n\n\n"
+                 "}}}",
+                 Style);
+}
+
 } // namespace
 } // namespace test
 } // namespace format

>From fd58d2f485a75ee6565ff87175b43880ba53b82c Mon Sep 17 00:00:00 2001
From: dmasloff <dmaslo...@gmail.com>
Date: Mon, 2 Sep 2024 16:50:47 +0300
Subject: [PATCH 02/10] FormatTests update

---
 clang/unittests/Format/FormatTest.cpp | 90 +++++++++++++++++++--------
 1 file changed, 65 insertions(+), 25 deletions(-)

diff --git a/clang/unittests/Format/FormatTest.cpp 
b/clang/unittests/Format/FormatTest.cpp
index fd8dba436fdcf3..204eb1d3d8d7df 100644
--- a/clang/unittests/Format/FormatTest.cpp
+++ b/clang/unittests/Format/FormatTest.cpp
@@ -28460,7 +28460,9 @@ TEST_F(FormatTest, 
WrapNamespaceBodyWithEmptyLinesNever) {
   Style.CompactNamespaces = true;
 
   // Empty namespace
-  verifyNoChange("namespace N {\n};", Style);
+  verifyNoChange("namespace N {\n"
+                 "};",
+                 Style);
 
   // Single namespace
   verifyNoChange("namespace N {\n"
@@ -28490,19 +28492,23 @@ TEST_F(FormatTest, 
WrapNamespaceBodyWithEmptyLinesAlways) {
   verifyNoChange("namespace N {};", Style);
 
   // Single namespace
-  verifyNoChange("namespace N {\n\n"
-                 "int f1(int a) { return 2 * a; }\n\n"
+  verifyNoChange("namespace N {\n"
+                 "\n"
+                 "int f1(int a) { return 2 * a; }\n"
+                 "\n"
                  "};",
                  Style);
 
   // Nested namespace
   verifyNoChange("namespace N1 {\n"
                  "namespace N2 {\n"
-                 "namespace N3 {\n\n"
+                 "namespace N3 {\n"
+                 "\n"
                  "int f1() {\n"
                  "  int a = 1;\n"
                  "  return a;\n"
-                 "}\n\n"
+                 "}\n"
+                 "\n"
                  "}\n"
                  "}\n"
                  "}",
@@ -28511,11 +28517,13 @@ TEST_F(FormatTest, 
WrapNamespaceBodyWithEmptyLinesAlways) {
   Style.CompactNamespaces = true;
 
   // Nested namespace
-  verifyNoChange("namespace N1 { namespace N2 { namespace N3 {\n\n"
+  verifyNoChange("namespace N1 { namespace N2 { namespace N3 {\n"
+                 "\n"
                  "int f1() {\n"
                  "  int a = 1;\n"
                  "  return a;\n"
-                 "}\n\n"
+                 "}\n"
+                 "\n"
                  "}}}",
                  Style);
 
@@ -28526,30 +28534,44 @@ TEST_F(FormatTest, 
WrapNamespaceBodyWithEmptyLinesAlways) {
   verifyNoChange("namespace N {};", Style);
 
   // Single namespace
-  verifyNoChange("namespace N {\n\n\n"
-                 "void function()\n\n\n"
+  verifyNoChange("namespace N {\n"
+                 "\n"
+                 "\n"
+                 "void function()\n"
+                 "\n"
+                 "\n"
                  "};",
                  Style);
 
   // Nested namespace
   verifyFormat("namespace N1 {\n"
                "namespace N2 {\n"
-               "namespace N3 {\n\n\n"
+               "namespace N3 {\n"
+               "\n"
+               "\n"
                "int f1() {\n"
                "  int a = 1;\n"
                "  return a;\n"
-               "}\n\n\n"
+               "}\n"
+               "\n"
+               "\n"
                "}\n"
                "}\n"
                "}",
                "namespace N1 {\n"
-               "namespace N2 {\n\n"
-               "namespace N3 {\n\n\n"
+               "namespace N2 {\n"
+               "\n"
+               "namespace N3 {\n"
+               "\n"
+               "\n"
                "int f1() {\n"
                "  int a = 1;\n"
                "  return a;\n"
-               "}\n\n\n"
-               "}\n\n"
+               "}\n"
+               "\n"
+               "\n"
+               "}\n"
+               "\n"
                "}\n"
                "}",
                Style);
@@ -28557,11 +28579,15 @@ TEST_F(FormatTest, 
WrapNamespaceBodyWithEmptyLinesAlways) {
   Style.CompactNamespaces = true;
 
   // Nested namespace
-  verifyNoChange("namespace N1 { namespace N2 { namespace N3 {\n\n\n"
+  verifyNoChange("namespace N1 { namespace N2 { namespace N3 {\n"
+                 "\n"
+                 "\n"
                  "int f1() {\n"
                  "  int a = 1;\n"
                  "  return a;\n"
-                 "}\n\n\n"
+                 "}\n"
+                 "\n"
+                 "\n"
                  "}}}",
                  Style);
 }
@@ -28599,20 +28625,30 @@ TEST_F(FormatTest, 
WrapNamespaceBodyWithEmptyLinesLeave) {
   Style.MaxEmptyLinesToKeep = 2;
 
   // Single namespace
-  verifyNoChange("namespace N {\n\n\n"
-                 "int f1(int a) { return 2 * a; }\n\n\n"
+  verifyNoChange("namespace N {\n"
+                 "\n"
+                 "\n"
+                 "int f1(int a) { return 2 * a; }\n"
+                 "\n"
+                 "\n"
                  "};",
                  Style);
 
   // Nested namespace
   verifyNoChange("namespace N1 {\n"
-                 "namespace N2 {\n\n"
-                 "namespace N3 {\n\n\n"
+                 "namespace N2 {\n"
+                 "\n"
+                 "namespace N3 {\n"
+                 "\n"
+                 "\n"
                  "int f1() {\n"
                  "  int a = 1;\n"
                  "  return a;\n"
-                 "}\n\n\n"
-                 "}\n\n"
+                 "}\n"
+                 "\n"
+                 "\n"
+                 "}\n"
+                 "\n"
                  "}\n"
                  "}",
                  Style);
@@ -28623,11 +28659,15 @@ TEST_F(FormatTest, 
WrapNamespaceBodyWithEmptyLinesLeave) {
   verifyNoChange("namespace N {\n};", Style);
 
   // Nested namespace
-  verifyNoChange("namespace N1 { namespace N2 { namespace N3 {\n\n\n"
+  verifyNoChange("namespace N1 { namespace N2 { namespace N3 {\n"
+                 "\n"
+                 "\n"
                  "int f1() {\n"
                  "  int a = 1;\n"
                  "  return a;\n"
-                 "}\n\n\n"
+                 "}\n"
+                 "\n"
+                 "\n"
                  "}}}",
                  Style);
 }

>From 9134678cfdceb3a3c310c8cbdcc0d6854e1e3387 Mon Sep 17 00:00:00 2001
From: dmasloff <dmaslo...@gmail.com>
Date: Tue, 3 Sep 2024 23:54:25 +0300
Subject: [PATCH 03/10] ConfigParseTest added for new option + minor code-style
 fixes

---
 clang/docs/ClangFormatStyleOptions.rst      | 2 +-
 clang/include/clang/Format/Format.h         | 2 +-
 clang/lib/Format/UnwrappedLineFormatter.cpp | 4 ++--
 clang/unittests/Format/ConfigParseTest.cpp  | 8 ++++++++
 4 files changed, 12 insertions(+), 4 deletions(-)

diff --git a/clang/docs/ClangFormatStyleOptions.rst 
b/clang/docs/ClangFormatStyleOptions.rst
index df65d46f0275da..4a68e4ac4ce17d 100644
--- a/clang/docs/ClangFormatStyleOptions.rst
+++ b/clang/docs/ClangFormatStyleOptions.rst
@@ -6845,7 +6845,7 @@ the configuration (without a prefix: ``Auto``).
 
 .. _WrapNamespaceBodyWithEmptyLines:
 
-**WrapNamespaceBodyWithEmptyLines** (``WrapNamespaceBodyWithEmptyLinesStyle``) 
:versionbadge:`clang-format 19` :ref:`¶ <WrapNamespaceBodyWithEmptyLines>`
+**WrapNamespaceBodyWithEmptyLines** (``WrapNamespaceBodyWithEmptyLinesStyle``) 
:versionbadge:`clang-format 20` :ref:`¶ <WrapNamespaceBodyWithEmptyLines>`
   Controls number of empty lines at the begging and at the end of
   namespace definition.
 
diff --git a/clang/include/clang/Format/Format.h 
b/clang/include/clang/Format/Format.h
index dc816d31264024..24fc39410226b3 100644
--- a/clang/include/clang/Format/Format.h
+++ b/clang/include/clang/Format/Format.h
@@ -5177,7 +5177,7 @@ struct FormatStyle {
 
   /// Controls number of empty lines at the begging and at the end of
   /// namespace definition.
-  /// \version 19
+  /// \version 20
   WrapNamespaceBodyWithEmptyLinesStyle WrapNamespaceBodyWithEmptyLines;
 
   bool operator==(const FormatStyle &R) const {
diff --git a/clang/lib/Format/UnwrappedLineFormatter.cpp 
b/clang/lib/Format/UnwrappedLineFormatter.cpp
index d1b80e601ef737..8fb93d4eaa0347 100644
--- a/clang/lib/Format/UnwrappedLineFormatter.cpp
+++ b/clang/lib/Format/UnwrappedLineFormatter.cpp
@@ -46,8 +46,8 @@ bool LineEndsNamespaceScope(const AnnotatedLine *Line,
                             const SmallVectorImpl<AnnotatedLine *> &Lines) {
   if (!Line)
     return false;
-  const FormatToken *tok = Line->First;
-  if (!tok || tok->isNot(tok::r_brace))
+  const FormatToken *Tok = Line->First;
+  if (!Tok || Tok->isNot(tok::r_brace))
     return false;
   return getNamespaceToken(Line, Lines) != nullptr;
 }
diff --git a/clang/unittests/Format/ConfigParseTest.cpp 
b/clang/unittests/Format/ConfigParseTest.cpp
index b249bf073aa453..3e6a1d8fa0f486 100644
--- a/clang/unittests/Format/ConfigParseTest.cpp
+++ b/clang/unittests/Format/ConfigParseTest.cpp
@@ -865,6 +865,14 @@ TEST(ConfigParseTest, ParsesConfiguration) {
   CHECK_PARSE("SortUsingDeclarations: true", SortUsingDeclarations,
               FormatStyle::SUD_LexicographicNumeric);
 
+  Style.WrapNamespaceBodyWithEmptyLines = FormatStyle::WNBWELS_Leave;
+  CHECK_PARSE("WrapNamespaceBodyWithEmptyLines: Never",
+              WrapNamespaceBodyWithEmptyLines, FormatStyle::WNBWELS_Never);
+  CHECK_PARSE("WrapNamespaceBodyWithEmptyLines: Always",
+              WrapNamespaceBodyWithEmptyLines, FormatStyle::WNBWELS_Always);
+  CHECK_PARSE("WrapNamespaceBodyWithEmptyLines: Leave",
+              WrapNamespaceBodyWithEmptyLines, FormatStyle::WNBWELS_Leave);
+
   // FIXME: This is required because parsing a configuration simply overwrites
   // the first N elements of the list instead of resetting it.
   Style.ForEachMacros.clear();

>From 3574ea9c63e149b6f1a648bb666e51d05a40878f Mon Sep 17 00:00:00 2001
From: dmasloff <dmaslo...@gmail.com>
Date: Tue, 17 Sep 2024 18:43:40 +0300
Subject: [PATCH 04/10] Fix invalid tests with CompactNamespaces option

---
 clang/unittests/Format/FormatTest.cpp | 8 +++++---
 1 file changed, 5 insertions(+), 3 deletions(-)

diff --git a/clang/unittests/Format/FormatTest.cpp 
b/clang/unittests/Format/FormatTest.cpp
index 204eb1d3d8d7df..599a66f5f4269f 100644
--- a/clang/unittests/Format/FormatTest.cpp
+++ b/clang/unittests/Format/FormatTest.cpp
@@ -28460,8 +28460,8 @@ TEST_F(FormatTest, 
WrapNamespaceBodyWithEmptyLinesNever) {
   Style.CompactNamespaces = true;
 
   // Empty namespace
-  verifyNoChange("namespace N {\n"
-                 "};",
+  verifyNoChange("namespace N1 { namespace N2 {\n"
+                 "}};",
                  Style);
 
   // Single namespace
@@ -28656,7 +28656,9 @@ TEST_F(FormatTest, 
WrapNamespaceBodyWithEmptyLinesLeave) {
   Style.CompactNamespaces = true;
 
   // Empty namespace
-  verifyNoChange("namespace N {\n};", Style);
+  verifyNoChange("namespace N1 { namespace N2 {\n"
+                 "}};",
+                 Style);
 
   // Nested namespace
   verifyNoChange("namespace N1 { namespace N2 { namespace N3 {\n"

>From f3616649f0d614ca7aed5b37b22fc87594395700 Mon Sep 17 00:00:00 2001
From: dmasloff <dmaslo...@gmail.com>
Date: Thu, 26 Sep 2024 00:25:17 +0300
Subject: [PATCH 05/10] Reformat tests in FormatTest.cpp

---
 clang/unittests/Format/FormatTest.cpp | 317 +++++++++++++-------------
 1 file changed, 153 insertions(+), 164 deletions(-)

diff --git a/clang/unittests/Format/FormatTest.cpp 
b/clang/unittests/Format/FormatTest.cpp
index 599a66f5f4269f..7827fa4a037ed6 100644
--- a/clang/unittests/Format/FormatTest.cpp
+++ b/clang/unittests/Format/FormatTest.cpp
@@ -28428,226 +28428,223 @@ TEST_F(FormatTest, ShortNamespacesOption) {
 }
 
 TEST_F(FormatTest, WrapNamespaceBodyWithEmptyLinesNever) {
-  FormatStyle Style = getLLVMStyle();
+  auto Style = getLLVMStyle();
   Style.FixNamespaceComments = false;
-  Style.ShortNamespaceLines = 0;
-  Style.MaxEmptyLinesToKeep = 2;
-  Style.WrapNamespaceBodyWithEmptyLines = FormatStyle::WNBWELS_Never;
-  Style.CompactNamespaces = false;
 
-  // Empty namespace
-  verifyNoChange("namespace N {};", Style);
+  // Empty namespace.
+  verifyFormat("namespace N {}", Style);
 
-  // Single namespace
-  verifyNoChange("namespace N {\n"
-                 "int f1(int a) { return 2 * a; }\n"
-                 "};",
-                 Style);
+  // Single namespace.
+  verifyFormat("namespace N {\n"
+               "int f1(int a) { return 2 * a; }\n"
+               "}",
+               Style);
 
-  // Nested namespace
-  verifyNoChange("namespace N1 {\n"
-                 "namespace N2 {\n"
-                 "namespace N3 {\n"
-                 "int f1() {\n"
-                 "  int a = 1;\n"
-                 "  return a;\n"
-                 "}\n"
-                 "}\n"
-                 "}\n"
-                 "}",
-                 Style);
+  // Nested namespace.
+  verifyFormat("namespace N1 {\n"
+               "namespace N2 {\n"
+               "int a = 1;\n"
+               "}\n"
+               "}",
+               Style);
 
   Style.CompactNamespaces = true;
 
-  // Empty namespace
-  verifyNoChange("namespace N1 { namespace N2 {\n"
-                 "}};",
-                 Style);
+  verifyFormat("namespace N1 { namespace N2 {\n"
+               "int a = 1;\n"
+               "}}",
+               Style);
 
-  // Single namespace
-  verifyNoChange("namespace N {\n"
-                 "int f1(int a) { return 2 * a; }\n"
-                 "};",
-                 Style);
+  // Removing empty lines.
+  verifyFormat("namespace N {\n"
+               "\n"
+               "int a = 1;\n"
+               "\n"
+               "}",
+               "namespace N {\n"
+               "\n"
+               "\n"
+               "int a = 1;\n"
+               "\n"
+               "\n"
+               "}",
+               Style);
 
-  // Nested namespace
-  verifyNoChange("namespace N1 { namespace N2 { namespace N3 {\n"
-                 "int f1() {\n"
-                 "  int a = 1;\n"
-                 "  return a;\n"
-                 "}\n"
-                 "}}}",
-                 Style);
+  Style.MaxEmptyLinesToKeep = 0;
+
+  verifyFormat("namespace N {\n"
+               "int a = 1;\n"
+               "}",
+               "namespace N {\n"
+               "\n"
+               "\n"
+               "int a = 1;\n"
+               "\n"
+               "\n"
+               "}",
+               Style);
 }
 
 TEST_F(FormatTest, WrapNamespaceBodyWithEmptyLinesAlways) {
-  FormatStyle Style = getLLVMStyle();
+  auto Style = getLLVMStyle();
   Style.FixNamespaceComments = false;
-  Style.ShortNamespaceLines = 0;
-  Style.MaxEmptyLinesToKeep = 0;
   Style.WrapNamespaceBodyWithEmptyLines = FormatStyle::WNBWELS_Always;
-  Style.CompactNamespaces = false;
-
-  // Empty namespace
-  verifyNoChange("namespace N {};", Style);
-
-  // Single namespace
-  verifyNoChange("namespace N {\n"
-                 "\n"
-                 "int f1(int a) { return 2 * a; }\n"
-                 "\n"
-                 "};",
-                 Style);
-
-  // Nested namespace
-  verifyNoChange("namespace N1 {\n"
-                 "namespace N2 {\n"
-                 "namespace N3 {\n"
-                 "\n"
-                 "int f1() {\n"
-                 "  int a = 1;\n"
-                 "  return a;\n"
-                 "}\n"
-                 "\n"
-                 "}\n"
-                 "}\n"
-                 "}",
-                 Style);
 
-  Style.CompactNamespaces = true;
+  // Empty namespace.
+  verifyFormat("namespace N {}", Style);
 
-  // Nested namespace
-  verifyNoChange("namespace N1 { namespace N2 { namespace N3 {\n"
-                 "\n"
-                 "int f1() {\n"
-                 "  int a = 1;\n"
-                 "  return a;\n"
-                 "}\n"
-                 "\n"
-                 "}}}",
-                 Style);
-
-  Style.MaxEmptyLinesToKeep = 2;
-  Style.CompactNamespaces = false;
-
-  // Empty namespace
-  verifyNoChange("namespace N {};", Style);
-
-  // Single namespace
-  verifyNoChange("namespace N {\n"
-                 "\n"
-                 "\n"
-                 "void function()\n"
-                 "\n"
-                 "\n"
-                 "};",
-                 Style);
+  // Single namespace.
+  verifyFormat("namespace N {\n"
+               "\n"
+               "int f1(int a) { return 2 * a; }\n"
+               "\n"
+               "}",
+               Style);
 
-  // Nested namespace
+  // Nested namespace.
   verifyFormat("namespace N1 {\n"
                "namespace N2 {\n"
-               "namespace N3 {\n"
-               "\n"
-               "\n"
-               "int f1() {\n"
-               "  int a = 1;\n"
-               "  return a;\n"
-               "}\n"
                "\n"
+               "int a = 1;\n"
                "\n"
                "}\n"
-               "}\n"
                "}",
-               "namespace N1 {\n"
-               "namespace N2 {\n"
+               Style);
+
+  // Removing empty lines.
+  verifyFormat("namespace N {\n"
                "\n"
-               "namespace N3 {\n"
+               "int a = 1;\n"
                "\n"
+               "}",
+               "namespace N {"
                "\n"
-               "int f1() {\n"
-               "  int a = 1;\n"
-               "  return a;\n"
-               "}\n"
                "\n"
+               "int a = 1;\n"
                "\n"
-               "}\n"
                "\n"
-               "}\n"
                "}",
                Style);
 
   Style.CompactNamespaces = true;
 
-  // Nested namespace
-  verifyNoChange("namespace N1 { namespace N2 { namespace N3 {\n"
+  // Nested namespace.
+  verifyFormat("namespace N1 { namespace N2 {\n"
+               "\n"
+               "int a = 1;\n"
+               "\n"
+               "}}",
+               Style);
+
+  Style.MaxEmptyLinesToKeep = 2;
+
+  // Nested namespace.
+  verifyNoChange("namespace N1 { namespace N2 {\n"
                  "\n"
                  "\n"
-                 "int f1() {\n"
-                 "  int a = 1;\n"
-                 "  return a;\n"
-                 "}\n"
+                 "int a = 1;\n"
                  "\n"
                  "\n"
-                 "}}}",
+                 "}}",
                  Style);
-}
 
-TEST_F(FormatTest, WrapNamespaceBodyWithEmptyLinesLeave) {
-  FormatStyle Style = getLLVMStyle();
-  Style.FixNamespaceComments = false;
-  Style.ShortNamespaceLines = 0;
-  Style.MaxEmptyLinesToKeep = 0;
-  Style.WrapNamespaceBodyWithEmptyLines = FormatStyle::WNBWELS_Leave;
   Style.CompactNamespaces = false;
 
-  // Empty namespace
-  verifyNoChange("namespace N {};", Style);
+  // Empty namespace.
+  verifyFormat("namespace N {}", Style);
 
-  // Single namespace
+  // Single namespace.
   verifyNoChange("namespace N {\n"
-                 "int f1(int a) { return 2 * a; }\n"
-                 "};",
+                 "\n"
+                 "\n"
+                 "int a = 1;\n"
+                 "\n"
+                 "\n"
+                 "}",
                  Style);
 
-  // Nested namespace
+  // Nested namespace.
   verifyNoChange("namespace N1 {\n"
                  "namespace N2 {\n"
-                 "namespace N3 {\n"
-                 "int f1() {\n"
-                 "  int a = 1;\n"
-                 "  return a;\n"
-                 "}\n"
-                 "}\n"
+                 "\n"
+                 "\n"
+                 "int a = 1;\n"
+                 "\n"
+                 "\n"
                  "}\n"
                  "}",
                  Style);
+}
+
+TEST_F(FormatTest, WrapNamespaceBodyWithEmptyLinesLeave) {
+  auto Style = getLLVMStyle();
+  Style.FixNamespaceComments = false;
+
+  // Empty namespace.
+  verifyFormat("namespace N {}", Style);
+
+  // Single namespace.
+  verifyFormat("namespace N {\n"
+               "int f1(int a) { return 2 * a; }\n"
+               "}",
+               Style);
+
+  // Nested namespace.
+  verifyFormat("namespace N1 {\n"
+               "namespace N2 {\n"
+               "int a = 1;\n"
+               "}\n"
+               "}",
+               Style);
+
+  // Removing empty lines.
+  verifyFormat("namespace N {\n"
+               "\n"
+               "int a = 1;\n"
+               "\n"
+               "}",
+               "namespace N {\n"
+               "\n"
+               "\n"
+               "int a = 1;\n"
+               "\n"
+               "\n"
+               "}",
+               Style);
+
+  Style.MaxEmptyLinesToKeep = 0;
+
+  verifyFormat("namespace N {\n"
+               "int a = 1;\n"
+               "}",
+               "namespace N {\n"
+               "\n"
+               "\n"
+               "int a = 1;\n"
+               "\n"
+               "\n"
+               "}",
+               Style);
 
   Style.MaxEmptyLinesToKeep = 2;
 
-  // Single namespace
+  // Single namespace.
   verifyNoChange("namespace N {\n"
                  "\n"
                  "\n"
                  "int f1(int a) { return 2 * a; }\n"
                  "\n"
                  "\n"
-                 "};",
+                 "}",
                  Style);
 
-  // Nested namespace
+  // Nested namespace.
   verifyNoChange("namespace N1 {\n"
                  "namespace N2 {\n"
                  "\n"
-                 "namespace N3 {\n"
-                 "\n"
-                 "\n"
-                 "int f1() {\n"
-                 "  int a = 1;\n"
-                 "  return a;\n"
-                 "}\n"
                  "\n"
+                 "int a = 1;\n"
                  "\n"
-                 "}\n"
                  "\n"
                  "}\n"
                  "}",
@@ -28655,22 +28652,14 @@ TEST_F(FormatTest, 
WrapNamespaceBodyWithEmptyLinesLeave) {
 
   Style.CompactNamespaces = true;
 
-  // Empty namespace
+  // Nested namespace.
   verifyNoChange("namespace N1 { namespace N2 {\n"
-                 "}};",
-                 Style);
-
-  // Nested namespace
-  verifyNoChange("namespace N1 { namespace N2 { namespace N3 {\n"
                  "\n"
                  "\n"
-                 "int f1() {\n"
-                 "  int a = 1;\n"
-                 "  return a;\n"
-                 "}\n"
+                 "int a = 1;\n"
                  "\n"
                  "\n"
-                 "}}}",
+                 "}}",
                  Style);
 }
 

>From 061f40979c1fd25a44ce786f47f375dae817a7ce Mon Sep 17 00:00:00 2001
From: dmasloff <dmaslo...@gmail.com>
Date: Sun, 17 Nov 2024 02:07:39 +0300
Subject: [PATCH 06/10] Remove reduntant tests and simplify code

---
 clang/lib/Format/UnwrappedLineFormatter.cpp |  56 +++--------
 clang/unittests/Format/FormatTest.cpp       | 106 +-------------------
 2 files changed, 16 insertions(+), 146 deletions(-)

diff --git a/clang/lib/Format/UnwrappedLineFormatter.cpp 
b/clang/lib/Format/UnwrappedLineFormatter.cpp
index 8fb93d4eaa0347..b83f0459ab4e26 100644
--- a/clang/lib/Format/UnwrappedLineFormatter.cpp
+++ b/clang/lib/Format/UnwrappedLineFormatter.cpp
@@ -32,26 +32,6 @@ bool isRecordLBrace(const FormatToken &Tok) {
                      TT_StructLBrace, TT_UnionLBrace);
 }
 
-bool LineStartsNamespaceScope(const AnnotatedLine *Line,
-                              const AnnotatedLine *PreviousLine,
-                              const AnnotatedLine *PrevPrevLine) {
-  return PreviousLine &&
-         ((PreviousLine->Last->is(tok::l_brace) &&
-           PreviousLine->startsWithNamespace()) ||
-          (PrevPrevLine && PrevPrevLine->startsWithNamespace() &&
-           PreviousLine->startsWith(tok::l_brace)));
-}
-
-bool LineEndsNamespaceScope(const AnnotatedLine *Line,
-                            const SmallVectorImpl<AnnotatedLine *> &Lines) {
-  if (!Line)
-    return false;
-  const FormatToken *Tok = Line->First;
-  if (!Tok || Tok->isNot(tok::r_brace))
-    return false;
-  return getNamespaceToken(Line, Lines) != nullptr;
-}
-
 /// Tracks the indent level of \c AnnotatedLines across levels.
 ///
 /// \c nextLine must be called for each \c AnnotatedLine, after which \c
@@ -1604,27 +1584,21 @@ static auto computeNewlines(const AnnotatedLine &Line,
     Newlines = 1;
   }
 
-  // Modify empty lines after "{" that opens namespace scope.
-  if (Style.WrapNamespaceBodyWithEmptyLines != FormatStyle::WNBWELS_Leave &&
-      LineStartsNamespaceScope(&Line, PreviousLine, PrevPrevLine)) {
-    if (Style.WrapNamespaceBodyWithEmptyLines == FormatStyle::WNBWELS_Never)
-      Newlines = std::min(Newlines, 1u);
-    else if (!Line.startsWithNamespace())
-      Newlines = std::max(Newlines, 2u);
-    else
-      Newlines = std::min(Newlines, 1u);
-  }
-
-  // Modify empty lines before "}" that closes namespace scope.
-  if (Style.WrapNamespaceBodyWithEmptyLines != FormatStyle::WNBWELS_Leave &&
-      LineEndsNamespaceScope(&Line, Lines)) {
-    if (Style.WrapNamespaceBodyWithEmptyLines == FormatStyle::WNBWELS_Never)
-      Newlines = std::min(Newlines, 1u);
-    else if (!LineEndsNamespaceScope(PreviousLine, Lines))
-      Newlines = std::max(Newlines, 2u);
-    else
-      Newlines = std::min(Newlines, 1u);
-  }
+  if (Style.WrapNamespaceBodyWithEmptyLines != FormatStyle::WNBWELS_Leave) {
+    // Modify empty lines after TT_NamespaceLBrace.
+    if (PreviousLine && PreviousLine->endsWith(TT_NamespaceLBrace)) {
+      if (Style.WrapNamespaceBodyWithEmptyLines == FormatStyle::WNBWELS_Never)
+        Newlines = 1;
+      else if (!Line.startsWithNamespace())
+        Newlines = std::max(Newlines, 2u);
+    }
+    // Modify empty lines before TT_NamespaceRBrace.
+    if (Line.startsWith(TT_NamespaceRBrace)) {
+      if (Style.WrapNamespaceBodyWithEmptyLines == FormatStyle::WNBWELS_Never)
+        Newlines = 1;
+      else if (!PreviousLine->startsWith(TT_NamespaceRBrace))
+        Newlines = std::max(Newlines, 2u);
+    }
 
   // Insert or remove empty line before access specifiers.
   if (PreviousLine && RootToken.isAccessSpecifier()) {
diff --git a/clang/unittests/Format/FormatTest.cpp 
b/clang/unittests/Format/FormatTest.cpp
index 7827fa4a037ed6..71f6fd6be2f0c4 100644
--- a/clang/unittests/Format/FormatTest.cpp
+++ b/clang/unittests/Format/FormatTest.cpp
@@ -28430,6 +28430,7 @@ TEST_F(FormatTest, ShortNamespacesOption) {
 TEST_F(FormatTest, WrapNamespaceBodyWithEmptyLinesNever) {
   auto Style = getLLVMStyle();
   Style.FixNamespaceComments = false;
+  Style.WrapNamespaceBodyWithEmptyLines = FormatStyle::WNBWELS_Never;
 
   // Empty namespace.
   verifyFormat("namespace N {}", Style);
@@ -28511,21 +28512,6 @@ TEST_F(FormatTest, 
WrapNamespaceBodyWithEmptyLinesAlways) {
                "}",
                Style);
 
-  // Removing empty lines.
-  verifyFormat("namespace N {\n"
-               "\n"
-               "int a = 1;\n"
-               "\n"
-               "}",
-               "namespace N {"
-               "\n"
-               "\n"
-               "int a = 1;\n"
-               "\n"
-               "\n"
-               "}",
-               Style);
-
   Style.CompactNamespaces = true;
 
   // Nested namespace.
@@ -28550,9 +28536,6 @@ TEST_F(FormatTest, 
WrapNamespaceBodyWithEmptyLinesAlways) {
 
   Style.CompactNamespaces = false;
 
-  // Empty namespace.
-  verifyFormat("namespace N {}", Style);
-
   // Single namespace.
   verifyNoChange("namespace N {\n"
                  "\n"
@@ -28576,93 +28559,6 @@ TEST_F(FormatTest, 
WrapNamespaceBodyWithEmptyLinesAlways) {
                  Style);
 }
 
-TEST_F(FormatTest, WrapNamespaceBodyWithEmptyLinesLeave) {
-  auto Style = getLLVMStyle();
-  Style.FixNamespaceComments = false;
-
-  // Empty namespace.
-  verifyFormat("namespace N {}", Style);
-
-  // Single namespace.
-  verifyFormat("namespace N {\n"
-               "int f1(int a) { return 2 * a; }\n"
-               "}",
-               Style);
-
-  // Nested namespace.
-  verifyFormat("namespace N1 {\n"
-               "namespace N2 {\n"
-               "int a = 1;\n"
-               "}\n"
-               "}",
-               Style);
-
-  // Removing empty lines.
-  verifyFormat("namespace N {\n"
-               "\n"
-               "int a = 1;\n"
-               "\n"
-               "}",
-               "namespace N {\n"
-               "\n"
-               "\n"
-               "int a = 1;\n"
-               "\n"
-               "\n"
-               "}",
-               Style);
-
-  Style.MaxEmptyLinesToKeep = 0;
-
-  verifyFormat("namespace N {\n"
-               "int a = 1;\n"
-               "}",
-               "namespace N {\n"
-               "\n"
-               "\n"
-               "int a = 1;\n"
-               "\n"
-               "\n"
-               "}",
-               Style);
-
-  Style.MaxEmptyLinesToKeep = 2;
-
-  // Single namespace.
-  verifyNoChange("namespace N {\n"
-                 "\n"
-                 "\n"
-                 "int f1(int a) { return 2 * a; }\n"
-                 "\n"
-                 "\n"
-                 "}",
-                 Style);
-
-  // Nested namespace.
-  verifyNoChange("namespace N1 {\n"
-                 "namespace N2 {\n"
-                 "\n"
-                 "\n"
-                 "int a = 1;\n"
-                 "\n"
-                 "\n"
-                 "}\n"
-                 "}",
-                 Style);
-
-  Style.CompactNamespaces = true;
-
-  // Nested namespace.
-  verifyNoChange("namespace N1 { namespace N2 {\n"
-                 "\n"
-                 "\n"
-                 "int a = 1;\n"
-                 "\n"
-                 "\n"
-                 "}}",
-                 Style);
-}
-
 } // namespace
 } // namespace test
 } // namespace format

>From 78c1d983fed0ba9e50ac781d4f5979e1be198bb4 Mon Sep 17 00:00:00 2001
From: dmasloff <dmaslo...@gmail.com>
Date: Tue, 31 Dec 2024 23:18:38 +0300
Subject: [PATCH 07/10] minor fix

---
 clang/lib/Format/UnwrappedLineFormatter.cpp | 1 +
 clang/unittests/Format/FormatTest.cpp       | 2 --
 2 files changed, 1 insertion(+), 2 deletions(-)

diff --git a/clang/lib/Format/UnwrappedLineFormatter.cpp 
b/clang/lib/Format/UnwrappedLineFormatter.cpp
index b83f0459ab4e26..bc6766a47f5c70 100644
--- a/clang/lib/Format/UnwrappedLineFormatter.cpp
+++ b/clang/lib/Format/UnwrappedLineFormatter.cpp
@@ -1599,6 +1599,7 @@ static auto computeNewlines(const AnnotatedLine &Line,
       else if (!PreviousLine->startsWith(TT_NamespaceRBrace))
         Newlines = std::max(Newlines, 2u);
     }
+  }
 
   // Insert or remove empty line before access specifiers.
   if (PreviousLine && RootToken.isAccessSpecifier()) {
diff --git a/clang/unittests/Format/FormatTest.cpp 
b/clang/unittests/Format/FormatTest.cpp
index 71f6fd6be2f0c4..dd99f46a1a6d47 100644
--- a/clang/unittests/Format/FormatTest.cpp
+++ b/clang/unittests/Format/FormatTest.cpp
@@ -28458,9 +28458,7 @@ TEST_F(FormatTest, 
WrapNamespaceBodyWithEmptyLinesNever) {
 
   // Removing empty lines.
   verifyFormat("namespace N {\n"
-               "\n"
                "int a = 1;\n"
-               "\n"
                "}",
                "namespace N {\n"
                "\n"

>From 7f07b52b7dea7a348440fec37de5dfce30545df1 Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?Valentin=20Clement=20=28=E3=83=90=E3=83=AC=E3=83=B3?=
 =?UTF-8?q?=E3=82=BF=E3=82=A4=E3=83=B3=20=E3=82=AF=E3=83=AC=E3=83=A1?=
 =?UTF-8?q?=E3=83=B3=29?= <clement...@gmail.com>
Date: Tue, 27 Aug 2024 17:36:14 -0700
Subject: [PATCH 08/10] [flang][cuda] Add missing dependency (#106298)

Add missing dependency that sometimes makes a build fails with ninja.

>From 1edc8906841006ce2cab5eec2a015c646e00de79 Mon Sep 17 00:00:00 2001
From: dmasloff <dmaslo...@gmail.com>
Date: Thu, 2 Jan 2025 21:56:34 +0300
Subject: [PATCH 09/10] Adds review suggestions + adds option to
 clang/docs/ReleaseNotes.rst

---
 clang/docs/ReleaseNotes.rst           |   1 +
 clang/unittests/Format/FormatTest.cpp | 112 +++++++++++++-------------
 2 files changed, 57 insertions(+), 56 deletions(-)

diff --git a/clang/docs/ReleaseNotes.rst b/clang/docs/ReleaseNotes.rst
index aca07e2ba9cf2d..2789a24ebf273d 100644
--- a/clang/docs/ReleaseNotes.rst
+++ b/clang/docs/ReleaseNotes.rst
@@ -1127,6 +1127,7 @@ clang-format
 - Adds ``AllowShortNamespacesOnASingleLine`` option.
 - Adds ``VariableTemplates`` option.
 - Adds support for bash globstar in ``.clang-format-ignore``.
+- Adds ``WrapNamespaceBodyWithEmptyLines`` option.
 
 libclang
 --------
diff --git a/clang/unittests/Format/FormatTest.cpp 
b/clang/unittests/Format/FormatTest.cpp
index dd99f46a1a6d47..44b9dba2498900 100644
--- a/clang/unittests/Format/FormatTest.cpp
+++ b/clang/unittests/Format/FormatTest.cpp
@@ -28430,6 +28430,7 @@ TEST_F(FormatTest, ShortNamespacesOption) {
 TEST_F(FormatTest, WrapNamespaceBodyWithEmptyLinesNever) {
   auto Style = getLLVMStyle();
   Style.FixNamespaceComments = false;
+  Style.MaxEmptyLinesToKeep = 2;
   Style.WrapNamespaceBodyWithEmptyLines = FormatStyle::WNBWELS_Never;
 
   // Empty namespace.
@@ -28439,6 +28440,13 @@ TEST_F(FormatTest, 
WrapNamespaceBodyWithEmptyLinesNever) {
   verifyFormat("namespace N {\n"
                "int f1(int a) { return 2 * a; }\n"
                "}",
+               "namespace N {\n"
+               "\n"
+               "\n"
+               "int f1(int a) { return 2 * a; }\n"
+               "\n"
+               "\n"
+               "}",
                Style);
 
   // Nested namespace.
@@ -28447,46 +28455,38 @@ TEST_F(FormatTest, 
WrapNamespaceBodyWithEmptyLinesNever) {
                "int a = 1;\n"
                "}\n"
                "}",
-               Style);
-
-  Style.CompactNamespaces = true;
-
-  verifyFormat("namespace N1 { namespace N2 {\n"
-               "int a = 1;\n"
-               "}}",
-               Style);
-
-  // Removing empty lines.
-  verifyFormat("namespace N {\n"
-               "int a = 1;\n"
-               "}",
-               "namespace N {\n"
+               "namespace N1 {\n"
                "\n"
                "\n"
+               "namespace N2 {\n"
+               "\n"
                "int a = 1;\n"
                "\n"
+               "}\n"
+               "\n"
                "\n"
                "}",
                Style);
 
-  Style.MaxEmptyLinesToKeep = 0;
+  Style.CompactNamespaces = true;
 
-  verifyFormat("namespace N {\n"
+  verifyFormat("namespace N1 { namespace N2 {\n"
                "int a = 1;\n"
-               "}",
-               "namespace N {\n"
+               "}}",
+               "namespace N1 { namespace N2 {\n"
                "\n"
                "\n"
                "int a = 1;\n"
                "\n"
                "\n"
-               "}",
+               "}}",
                Style);
 }
 
 TEST_F(FormatTest, WrapNamespaceBodyWithEmptyLinesAlways) {
   auto Style = getLLVMStyle();
   Style.FixNamespaceComments = false;
+  Style.MaxEmptyLinesToKeep = 2;
   Style.WrapNamespaceBodyWithEmptyLines = FormatStyle::WNBWELS_Always;
 
   // Empty namespace.
@@ -28498,6 +28498,9 @@ TEST_F(FormatTest, 
WrapNamespaceBodyWithEmptyLinesAlways) {
                "int f1(int a) { return 2 * a; }\n"
                "\n"
                "}",
+               "namespace N {\n"
+               "int f1(int a) { return 2 * a; }\n"
+               "}",
                Style);
 
   // Nested namespace.
@@ -28508,53 +28511,50 @@ TEST_F(FormatTest, 
WrapNamespaceBodyWithEmptyLinesAlways) {
                "\n"
                "}\n"
                "}",
+               "namespace N1 {\n"
+               "namespace N2 {\n"
+               "int a = 1;\n"
+               "}\n"
+               "}",
+               Style);
+
+  verifyFormat("namespace N1 {\n"
+               "\n"
+               "namespace N2 {\n"
+               "\n"
+               "\n"
+               "int a = 1;\n"
+               "\n"
+               "\n"
+               "}\n"
+               "\n"
+               "}",
+               "namespace N1 {\n"
+               "\n"
+               "namespace N2 {\n"
+               "\n"
+               "\n"
+               "\n"
+               "int a = 1;\n"
+               "\n"
+               "\n"
+               "\n"
+               "}\n"
+               "\n"
+               "}",
                Style);
 
   Style.CompactNamespaces = true;
 
-  // Nested namespace.
   verifyFormat("namespace N1 { namespace N2 {\n"
                "\n"
                "int a = 1;\n"
                "\n"
                "}}",
+               "namespace N1 { namespace N2 {\n"
+               "int a = 1;\n"
+               "}}",
                Style);
-
-  Style.MaxEmptyLinesToKeep = 2;
-
-  // Nested namespace.
-  verifyNoChange("namespace N1 { namespace N2 {\n"
-                 "\n"
-                 "\n"
-                 "int a = 1;\n"
-                 "\n"
-                 "\n"
-                 "}}",
-                 Style);
-
-  Style.CompactNamespaces = false;
-
-  // Single namespace.
-  verifyNoChange("namespace N {\n"
-                 "\n"
-                 "\n"
-                 "int a = 1;\n"
-                 "\n"
-                 "\n"
-                 "}",
-                 Style);
-
-  // Nested namespace.
-  verifyNoChange("namespace N1 {\n"
-                 "namespace N2 {\n"
-                 "\n"
-                 "\n"
-                 "int a = 1;\n"
-                 "\n"
-                 "\n"
-                 "}\n"
-                 "}",
-                 Style);
 }
 
 } // namespace

>From 228747f38f69360ea531d762ea0565c2ad213307 Mon Sep 17 00:00:00 2001
From: Owen Pan <owenpi...@gmail.com>
Date: Thu, 2 Jan 2025 20:50:02 -0800
Subject: [PATCH 10/10] Clean up documentation

---
 clang/include/clang/Format/Format.h | 24 ++++++++++--------------
 1 file changed, 10 insertions(+), 14 deletions(-)

diff --git a/clang/include/clang/Format/Format.h 
b/clang/include/clang/Format/Format.h
index 24fc39410226b3..9b7a633e0a1461 100644
--- a/clang/include/clang/Format/Format.h
+++ b/clang/include/clang/Format/Format.h
@@ -5143,40 +5143,36 @@ struct FormatStyle {
   /// \version 11
   std::vector<std::string> WhitespaceSensitiveMacros;
 
-  /// Different styles for modify number of empty lines in
-  /// the beginning and at the of end of namespaces.
+  /// Different styles for wrapping namespace body with empty lines.
   enum WrapNamespaceBodyWithEmptyLinesStyle : int8_t {
-    /// Removes all empty lines at the beginning and at the end of
-    /// namespace definition.
+    /// Remove all empty lines at the beginning and the end of namespace body.
     /// \code
     ///   namespace N1 {
     ///   namespace N2
-    ///     function();
+    ///   function();
     ///   }
     ///   }
     /// \endcode
     WNBWELS_Never,
-    /// Always adds an empty line at the beginning and at the end of
-    /// namespace definition. MaxEmptyLinesToKeep is also applied, but
-    /// empty lines between consecutive namespace declarations are
-    /// always removed.
+    /// Always have at least one empty line at the beginning and the end of
+    /// namespace body except that the number of empty lines between 
consecutive
+    /// nested namespace definitions is not increased.
     /// \code
     ///   namespace N1 {
     ///   namespace N2 {
     ///
-    ///     function();
+    ///   function();
     ///
     ///   }
     ///   }
     /// \endcode
     WNBWELS_Always,
-    /// Keeps existing newlines at the beginning and at the end of
-    /// namespace definition using MaxEmptyLinesToKeep for formatting.
+    /// Keep existing newlines at the beginning and the end of namespace body.
+    /// ``MaxEmptyLinesToKeep`` still applies.
     WNBWELS_Leave
   };
 
-  /// Controls number of empty lines at the begging and at the end of
-  /// namespace definition.
+  /// Wrap namespace body with empty lines.
   /// \version 20
   WrapNamespaceBodyWithEmptyLinesStyle WrapNamespaceBodyWithEmptyLines;
 

_______________________________________________
cfe-commits mailing list
cfe-commits@lists.llvm.org
https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits

Reply via email to