https://github.com/itzexpoexpo updated 
https://github.com/llvm/llvm-project/pull/151970

From 2c26e66e16bf2c42019e8a5bce421f106fcf978d Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?Tom=C3=A1=C5=A1=20Slanina?= <itzexpoe...@gmail.com>
Date: Mon, 4 Aug 2025 15:19:53 +0200
Subject: [PATCH 1/9] [clang-format] Add option to omit wrapping for empty
 records

Currently, clang-format does not allow empty records to be formatted
on a single line if the corresponding `BraceWrapping.After*` option
is set to true.

This results in unnecessarily wrapped code:

  struct foo
  {
      int i;
  };

  struct bar
  {
  };

This patch adds the `BraceWrapping.WrapEmptyRecord` option, which
allows `class`, `struct`, and `union` declarations with empty bodies
to be formatted as one-liners, even when `AfterRecord: true`.

As such, the following becomes possible:

  struct foo
  {
      int i;
  };

  struct bar {};
---
 clang/include/clang/Format/Format.h      | 28 ++++++++++++++++++++++
 clang/lib/Format/Format.cpp              | 13 +++++++++-
 clang/lib/Format/TokenAnnotator.cpp      |  9 +++----
 clang/lib/Format/UnwrappedLineParser.cpp | 20 ++++++++++------
 clang/unittests/Format/FormatTest.cpp    | 30 ++++++++++++++++++++++++
 5 files changed, 88 insertions(+), 12 deletions(-)

diff --git a/clang/include/clang/Format/Format.h 
b/clang/include/clang/Format/Format.h
index 31582a40de866..cc79dcb7b53ec 100644
--- a/clang/include/clang/Format/Format.h
+++ b/clang/include/clang/Format/Format.h
@@ -1355,6 +1355,32 @@ struct FormatStyle {
     BWACS_Always
   };
 
+  enum BraceWrapEmptyRecordStyle : int8_t {
+    /// Use default wrapping rules for records
+    /// (AfterClass,AfterStruct,AfterUnion)
+    /// \code
+    /// class foo
+    /// {
+    ///   int foo;
+    /// };
+    ///
+    /// class foo
+    /// {
+    /// };
+    /// \endcode
+    BWER_Default,
+    /// Override wrapping for empty records
+    /// \code
+    /// class foo
+    /// {
+    ///   int foo;
+    /// };
+    ///
+    /// class foo {};
+    /// \endcode
+    BWER_Never
+  };
+
   /// Precise control over the wrapping of braces.
   /// \code
   ///   # Should be declared this way:
@@ -1585,6 +1611,8 @@ struct FormatStyle {
     /// \endcode
     ///
     bool SplitEmptyNamespace;
+    /// Wrap empty record (``class``/``struct``/``union``).
+    BraceWrapEmptyRecordStyle WrapEmptyRecord;
   };
 
   /// Control of individual brace wrapping cases.
diff --git a/clang/lib/Format/Format.cpp b/clang/lib/Format/Format.cpp
index 063780721423f..0d72410f00c27 100644
--- a/clang/lib/Format/Format.cpp
+++ b/clang/lib/Format/Format.cpp
@@ -200,6 +200,7 @@ template <> struct 
MappingTraits<FormatStyle::BraceWrappingFlags> {
     IO.mapOptional("SplitEmptyFunction", Wrapping.SplitEmptyFunction);
     IO.mapOptional("SplitEmptyRecord", Wrapping.SplitEmptyRecord);
     IO.mapOptional("SplitEmptyNamespace", Wrapping.SplitEmptyNamespace);
+    IO.mapOptional("WrapEmptyRecord", Wrapping.WrapEmptyRecord);
   }
 };
 
@@ -232,6 +233,15 @@ struct ScalarEnumerationTraits<
   }
 };
 
+template <>
+struct ScalarEnumerationTraits<FormatStyle::BraceWrapEmptyRecordStyle> {
+  static void enumeration(IO &IO,
+                          FormatStyle::BraceWrapEmptyRecordStyle &Value) {
+    IO.enumCase(Value, "Default", FormatStyle::BWER_Default);
+    IO.enumCase(Value, "Never", FormatStyle::BWER_Never);
+  }
+};
+
 template <>
 struct ScalarEnumerationTraits<
     FormatStyle::BreakBeforeConceptDeclarationsStyle> {
@@ -1392,7 +1402,8 @@ static void expandPresetsBraceWrapping(FormatStyle 
&Expanded) {
                             /*IndentBraces=*/false,
                             /*SplitEmptyFunction=*/true,
                             /*SplitEmptyRecord=*/true,
-                            /*SplitEmptyNamespace=*/true};
+                            /*SplitEmptyNamespace=*/true,
+                            /*WrapEmptyRecord=*/FormatStyle::BWER_Default};
   switch (Expanded.BreakBeforeBraces) {
   case FormatStyle::BS_Linux:
     Expanded.BraceWrapping.AfterClass = true;
diff --git a/clang/lib/Format/TokenAnnotator.cpp 
b/clang/lib/Format/TokenAnnotator.cpp
index 4801d27b1395a..22132f6d2fd3b 100644
--- a/clang/lib/Format/TokenAnnotator.cpp
+++ b/clang/lib/Format/TokenAnnotator.cpp
@@ -5935,10 +5935,11 @@ bool TokenAnnotator::mustBreakBefore(const 
AnnotatedLine &Line,
 
     // Don't attempt to interpret struct return types as structs.
     if (Right.isNot(TT_FunctionLBrace)) {
-      return (Line.startsWith(tok::kw_class) &&
-              Style.BraceWrapping.AfterClass) ||
-             (Line.startsWith(tok::kw_struct) &&
-              Style.BraceWrapping.AfterStruct);
+      return ((Line.startsWith(tok::kw_class) &&
+               Style.BraceWrapping.AfterClass) ||
+              (Line.startsWith(tok::kw_struct) &&
+               Style.BraceWrapping.AfterStruct)) &&
+             Style.BraceWrapping.WrapEmptyRecord == FormatStyle::BWER_Default;
     }
   }
 
diff --git a/clang/lib/Format/UnwrappedLineParser.cpp 
b/clang/lib/Format/UnwrappedLineParser.cpp
index 91b8fdc8a3c38..e3efb0804d988 100644
--- a/clang/lib/Format/UnwrappedLineParser.cpp
+++ b/clang/lib/Format/UnwrappedLineParser.cpp
@@ -952,20 +952,26 @@ static bool isIIFE(const UnwrappedLine &Line,
 }
 
 static bool ShouldBreakBeforeBrace(const FormatStyle &Style,
-                                   const FormatToken &InitialToken) {
+                                   const FormatToken &InitialToken,
+                                   const FormatToken &NextToken) {
   tok::TokenKind Kind = InitialToken.Tok.getKind();
   if (InitialToken.is(TT_NamespaceMacro))
     Kind = tok::kw_namespace;
 
+  bool IsEmptyBlock = NextToken.is(tok::r_brace);
+  bool WrapRecordAllowed =
+      !(IsEmptyBlock &&
+        Style.BraceWrapping.WrapEmptyRecord == FormatStyle::BWER_Never);
+
   switch (Kind) {
   case tok::kw_namespace:
     return Style.BraceWrapping.AfterNamespace;
   case tok::kw_class:
-    return Style.BraceWrapping.AfterClass;
+    return Style.BraceWrapping.AfterClass && WrapRecordAllowed;
   case tok::kw_union:
-    return Style.BraceWrapping.AfterUnion;
+    return Style.BraceWrapping.AfterUnion && WrapRecordAllowed;
   case tok::kw_struct:
-    return Style.BraceWrapping.AfterStruct;
+    return Style.BraceWrapping.AfterStruct && WrapRecordAllowed;
   case tok::kw_enum:
     return Style.BraceWrapping.AfterEnum;
   default:
@@ -3191,7 +3197,7 @@ void UnwrappedLineParser::parseNamespace() {
   if (FormatTok->is(tok::l_brace)) {
     FormatTok->setFinalizedType(TT_NamespaceLBrace);
 
-    if (ShouldBreakBeforeBrace(Style, InitialToken))
+    if (ShouldBreakBeforeBrace(Style, InitialToken, *Tokens->peekNextToken()))
       addUnwrappedLine();
 
     unsigned AddLevels =
@@ -3856,7 +3862,7 @@ bool UnwrappedLineParser::parseEnum() {
   }
 
   if (!Style.AllowShortEnumsOnASingleLine &&
-      ShouldBreakBeforeBrace(Style, InitialToken)) {
+      ShouldBreakBeforeBrace(Style, InitialToken, *Tokens->peekNextToken())) {
     addUnwrappedLine();
   }
   // Parse enum body.
@@ -4151,7 +4157,7 @@ void UnwrappedLineParser::parseRecord(bool ParseAsExpr, 
bool IsJavaRecord) {
     if (ParseAsExpr) {
       parseChildBlock();
     } else {
-      if (ShouldBreakBeforeBrace(Style, InitialToken))
+      if (ShouldBreakBeforeBrace(Style, InitialToken, 
*Tokens->peekNextToken()))
         addUnwrappedLine();
 
       unsigned AddLevels = Style.IndentAccessModifiers ? 2u : 1u;
diff --git a/clang/unittests/Format/FormatTest.cpp 
b/clang/unittests/Format/FormatTest.cpp
index 96cc650f52a5d..3a5233674bd0f 100644
--- a/clang/unittests/Format/FormatTest.cpp
+++ b/clang/unittests/Format/FormatTest.cpp
@@ -15615,6 +15615,36 @@ TEST_F(FormatTest, NeverMergeShortRecords) {
                Style);
 }
 
+TEST_F(FormatTest, WrapEmptyRecords) {
+  FormatStyle Style = getLLVMStyle();
+
+  Style.BreakBeforeBraces = FormatStyle::BS_Custom;
+  Style.BraceWrapping.AfterStruct = true;
+  Style.BraceWrapping.AfterClass = true;
+  Style.BraceWrapping.AfterUnion = true;
+  Style.BraceWrapping.SplitEmptyRecord = false;
+
+  verifyFormat("class foo\n{\n  void bar();\n};", Style);
+  verifyFormat("class foo\n{};", Style);
+
+  verifyFormat("struct foo\n{\n  int bar;\n};", Style);
+  verifyFormat("struct foo\n{};", Style);
+
+  verifyFormat("union foo\n{\n  int bar;\n};", Style);
+  verifyFormat("union foo\n{};", Style);
+
+  Style.BraceWrapping.WrapEmptyRecord = FormatStyle::BWER_Never;
+
+  verifyFormat("class foo\n{\n  void bar();\n};", Style);
+  verifyFormat("class foo {};", Style);
+
+  verifyFormat("struct foo\n{\n  int bar;\n};", Style);
+  verifyFormat("struct foo {};", Style);
+
+  verifyFormat("union foo\n{\n  int bar;\n};", Style);
+  verifyFormat("union foo {};", Style);
+}
+
 TEST_F(FormatTest, UnderstandContextOfRecordTypeKeywords) {
   // Elaborate type variable declarations.
   verifyFormat("struct foo a = {bar};\nint n;");

From ce10b36f779b54b07cd90dd4023c949166380327 Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?Tom=C3=A1=C5=A1=20Slanina?= <itzexpoe...@gmail.com>
Date: Mon, 4 Aug 2025 16:11:48 +0200
Subject: [PATCH 2/9] Fix missing style option docs

---
 clang/docs/ClangFormatStyleOptions.rst | 30 ++++++++++++++++++++++++++
 1 file changed, 30 insertions(+)

diff --git a/clang/docs/ClangFormatStyleOptions.rst 
b/clang/docs/ClangFormatStyleOptions.rst
index 02986a94a656c..f3ee029b6c2bf 100644
--- a/clang/docs/ClangFormatStyleOptions.rst
+++ b/clang/docs/ClangFormatStyleOptions.rst
@@ -2579,6 +2579,36 @@ the configuration (without a prefix: ``Auto``).
       {}                   {
                            }
 
+  * ``BraceWrapEmptyRecordStyle WrapEmptyRecord``
+    Wrap empty record (``class``/``struct``/``union``).
+
+    Possible values:
+
+    * ``BWËR_Never`` (in configuration: ``Never``)
+      Never wrap braces of empty records.
+
+      .. code-block:: c++
+
+        class foo
+        {
+          int foo;
+        };
+        
+        class foo{};
+
+    * ``BWER_Default`` (in configuration: ``MultiLine``)
+      Use default wrapping rules for records. (``AfterClass``, 
``AfterStruct``, ``AfterUnion``)
+
+      .. code-block:: c++
+
+        class foo
+        {
+          int foo;
+        };
+        
+        class foo
+        {
+        };
 
 .. _BracedInitializerIndentWidth:
 

From 38318671aafe724c2c1208468585b884e614edfb Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?Tom=C3=A1=C5=A1=20Slanina?= <itzexpoe...@gmail.com>
Date: Mon, 11 Aug 2025 16:23:17 +0200
Subject: [PATCH 3/9] !fixup [clang-format] Add option to omit wrapping for
 empty records

---
 clang/docs/ClangFormatStyleOptions.rst   | 22 ++++++++++---------
 clang/include/clang/Format/Format.h      | 28 ++++++++++++------------
 clang/lib/Format/UnwrappedLineParser.cpp |  4 ++--
 clang/unittests/Format/FormatTest.cpp    | 24 +++++++++++++++-----
 4 files changed, 46 insertions(+), 32 deletions(-)

diff --git a/clang/docs/ClangFormatStyleOptions.rst 
b/clang/docs/ClangFormatStyleOptions.rst
index f3ee029b6c2bf..8c3b0ad707851 100644
--- a/clang/docs/ClangFormatStyleOptions.rst
+++ b/clang/docs/ClangFormatStyleOptions.rst
@@ -2584,8 +2584,9 @@ the configuration (without a prefix: ``Auto``).
 
     Possible values:
 
-    * ``BWËR_Never`` (in configuration: ``Never``)
-      Never wrap braces of empty records.
+    * ``BWER_Default`` (in configuration: ``Default``)
+      Use default wrapping rules for records
+      (``AfterClass``,``AfterStruct``,``AfterUnion``).
 
       .. code-block:: c++
 
@@ -2593,11 +2594,12 @@ the configuration (without a prefix: ``Auto``).
         {
           int foo;
         };
-        
-        class foo{};
 
-    * ``BWER_Default`` (in configuration: ``MultiLine``)
-      Use default wrapping rules for records. (``AfterClass``, 
``AfterStruct``, ``AfterUnion``)
+        class foo
+        {};
+
+    * ``BWER_Never`` (in configuration: ``Never``)
+      Override wrapping for empty records.
 
       .. code-block:: c++
 
@@ -2605,10 +2607,10 @@ the configuration (without a prefix: ``Auto``).
         {
           int foo;
         };
-        
-        class foo
-        {
-        };
+
+        class foo {};
+
+
 
 .. _BracedInitializerIndentWidth:
 
diff --git a/clang/include/clang/Format/Format.h 
b/clang/include/clang/Format/Format.h
index cc79dcb7b53ec..5d7d0fd9a48d6 100644
--- a/clang/include/clang/Format/Format.h
+++ b/clang/include/clang/Format/Format.h
@@ -1355,28 +1355,28 @@ struct FormatStyle {
     BWACS_Always
   };
 
+  /// Override wrapping of empty records.
   enum BraceWrapEmptyRecordStyle : int8_t {
     /// Use default wrapping rules for records
-    /// (AfterClass,AfterStruct,AfterUnion)
+    /// (``AfterClass``,``AfterStruct``,``AfterUnion``).
     /// \code
-    /// class foo
-    /// {
-    ///   int foo;
-    /// };
+    ///   class foo
+    ///   {
+    ///     int foo;
+    ///   };
     ///
-    /// class foo
-    /// {
-    /// };
+    ///   class foo
+    ///   {};
     /// \endcode
     BWER_Default,
-    /// Override wrapping for empty records
+    /// Override wrapping for empty records.
     /// \code
-    /// class foo
-    /// {
-    ///   int foo;
-    /// };
+    ///   class foo
+    ///   {
+    ///     int foo;
+    ///   };
     ///
-    /// class foo {};
+    ///   class foo {};
     /// \endcode
     BWER_Never
   };
diff --git a/clang/lib/Format/UnwrappedLineParser.cpp 
b/clang/lib/Format/UnwrappedLineParser.cpp
index e3efb0804d988..c6bb0103b2081 100644
--- a/clang/lib/Format/UnwrappedLineParser.cpp
+++ b/clang/lib/Format/UnwrappedLineParser.cpp
@@ -960,8 +960,8 @@ static bool ShouldBreakBeforeBrace(const FormatStyle &Style,
 
   bool IsEmptyBlock = NextToken.is(tok::r_brace);
   bool WrapRecordAllowed =
-      !(IsEmptyBlock &&
-        Style.BraceWrapping.WrapEmptyRecord == FormatStyle::BWER_Never);
+      !IsEmptyBlock ||
+        Style.BraceWrapping.WrapEmptyRecord != FormatStyle::BWER_Never;
 
   switch (Kind) {
   case tok::kw_namespace:
diff --git a/clang/unittests/Format/FormatTest.cpp 
b/clang/unittests/Format/FormatTest.cpp
index 3a5233674bd0f..c8dff7f2710da 100644
--- a/clang/unittests/Format/FormatTest.cpp
+++ b/clang/unittests/Format/FormatTest.cpp
@@ -15624,24 +15624,36 @@ TEST_F(FormatTest, WrapEmptyRecords) {
   Style.BraceWrapping.AfterUnion = true;
   Style.BraceWrapping.SplitEmptyRecord = false;
 
-  verifyFormat("class foo\n{\n  void bar();\n};", Style);
+  verifyFormat("class foo\n{\n"
+    "  void bar();\n"
+    "};", Style);
   verifyFormat("class foo\n{};", Style);
 
-  verifyFormat("struct foo\n{\n  int bar;\n};", Style);
+  verifyFormat("struct foo\n{\n"
+    "  int bar;\n"
+    "};", Style);
   verifyFormat("struct foo\n{};", Style);
 
-  verifyFormat("union foo\n{\n  int bar;\n};", Style);
+  verifyFormat("union foo\n{\n"
+    "  int bar;\n"
+    "};", Style);
   verifyFormat("union foo\n{};", Style);
 
   Style.BraceWrapping.WrapEmptyRecord = FormatStyle::BWER_Never;
 
-  verifyFormat("class foo\n{\n  void bar();\n};", Style);
+  verifyFormat("class foo\n{\n"
+    "  void bar();\n"
+    "};", Style);
   verifyFormat("class foo {};", Style);
 
-  verifyFormat("struct foo\n{\n  int bar;\n};", Style);
+  verifyFormat("struct foo\n{\n"
+    "  int bar;\n"
+    "};", Style);
   verifyFormat("struct foo {};", Style);
 
-  verifyFormat("union foo\n{\n  int bar;\n};", Style);
+  verifyFormat("union foo\n{\n"
+    "  int bar;\n"
+    "};", Style);
   verifyFormat("union foo {};", Style);
 }
 

From 1678747f9915164a56c3076172b8c8f9cf86948e Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?Tom=C3=A1=C5=A1=20Slanina?= <itzexpoe...@gmail.com>
Date: Mon, 11 Aug 2025 18:06:50 +0200
Subject: [PATCH 4/9] Fix formatting

---
 clang/lib/Format/UnwrappedLineParser.cpp |  2 +-
 clang/unittests/Format/FormatTest.cpp    | 30 ++++++++++++++----------
 2 files changed, 19 insertions(+), 13 deletions(-)

diff --git a/clang/lib/Format/UnwrappedLineParser.cpp 
b/clang/lib/Format/UnwrappedLineParser.cpp
index c6bb0103b2081..5d17bef78e9d2 100644
--- a/clang/lib/Format/UnwrappedLineParser.cpp
+++ b/clang/lib/Format/UnwrappedLineParser.cpp
@@ -961,7 +961,7 @@ static bool ShouldBreakBeforeBrace(const FormatStyle &Style,
   bool IsEmptyBlock = NextToken.is(tok::r_brace);
   bool WrapRecordAllowed =
       !IsEmptyBlock ||
-        Style.BraceWrapping.WrapEmptyRecord != FormatStyle::BWER_Never;
+      Style.BraceWrapping.WrapEmptyRecord != FormatStyle::BWER_Never;
 
   switch (Kind) {
   case tok::kw_namespace:
diff --git a/clang/unittests/Format/FormatTest.cpp 
b/clang/unittests/Format/FormatTest.cpp
index c8dff7f2710da..5ac92a45927ce 100644
--- a/clang/unittests/Format/FormatTest.cpp
+++ b/clang/unittests/Format/FormatTest.cpp
@@ -15625,35 +15625,41 @@ TEST_F(FormatTest, WrapEmptyRecords) {
   Style.BraceWrapping.SplitEmptyRecord = false;
 
   verifyFormat("class foo\n{\n"
-    "  void bar();\n"
-    "};", Style);
+               "  void bar();\n"
+               "};",
+               Style);
   verifyFormat("class foo\n{};", Style);
 
   verifyFormat("struct foo\n{\n"
-    "  int bar;\n"
-    "};", Style);
+               "  int bar;\n"
+               "};",
+               Style);
   verifyFormat("struct foo\n{};", Style);
 
   verifyFormat("union foo\n{\n"
-    "  int bar;\n"
-    "};", Style);
+               "  int bar;\n"
+               "};",
+               Style);
   verifyFormat("union foo\n{};", Style);
 
   Style.BraceWrapping.WrapEmptyRecord = FormatStyle::BWER_Never;
 
   verifyFormat("class foo\n{\n"
-    "  void bar();\n"
-    "};", Style);
+               "  void bar();\n"
+               "};",
+               Style);
   verifyFormat("class foo {};", Style);
 
   verifyFormat("struct foo\n{\n"
-    "  int bar;\n"
-    "};", Style);
+               "  int bar;\n"
+               "};",
+               Style);
   verifyFormat("struct foo {};", Style);
 
   verifyFormat("union foo\n{\n"
-    "  int bar;\n"
-    "};", Style);
+               "  int bar;\n"
+               "};",
+               Style);
   verifyFormat("union foo {};", Style);
 }
 

From 19afee66ea5e0b00964641d5b75d6283b98eb413 Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?Tom=C3=A1=C5=A1=20Slanina?= <itzexpoe...@gmail.com>
Date: Tue, 12 Aug 2025 21:09:08 +0200
Subject: [PATCH 5/9] Deprecate SplitEmptyRecord and replace it with
 WrapEmptyRecord

---
 clang/docs/ClangFormatStyleOptions.rst      | 18 ++++++++---------
 clang/docs/tools/dump_format_style.py       |  2 +-
 clang/include/clang/Format/Format.h         | 22 ++++++++++-----------
 clang/lib/Format/Format.cpp                 | 17 +++++++++-------
 clang/lib/Format/UnwrappedLineFormatter.cpp | 12 +++++------
 clang/unittests/Format/ConfigParseTest.cpp  |  1 -
 clang/unittests/Format/FormatTest.cpp       | 16 +++++++--------
 clang/unittests/Format/FormatTestCSharp.cpp |  2 +-
 8 files changed, 45 insertions(+), 45 deletions(-)

diff --git a/clang/docs/ClangFormatStyleOptions.rst 
b/clang/docs/ClangFormatStyleOptions.rst
index 8c3b0ad707851..375393e12691e 100644
--- a/clang/docs/ClangFormatStyleOptions.rst
+++ b/clang/docs/ClangFormatStyleOptions.rst
@@ -2555,7 +2555,8 @@ the configuration (without a prefix: ``Auto``).
       {}              {
                       }
 
-  * ``bool SplitEmptyRecord`` If ``false``, empty record (e.g. class, struct 
or union) body
+  * ``bool SplitEmptyRecord`` This option is **deprecated**. See 
`WrapEmptyRecord`.
+    If ``false``, empty record (e.g. class, struct or union) body
     can be put on a single line. This option is used only if the opening
     brace of the record has already been wrapped, i.e. the ``AfterClass``
     (for classes) brace wrapping mode is set.
@@ -2585,29 +2586,28 @@ the configuration (without a prefix: ``Auto``).
     Possible values:
 
     * ``BWER_Default`` (in configuration: ``Default``)
-      Use default wrapping rules for records
+      Use default wrapping rules for empty records
       (``AfterClass``,``AfterStruct``,``AfterUnion``).
 
       .. code-block:: c++
 
         class foo
         {
-          int foo;
         };
 
+    * ``BWER_BeforeBrace`` (in configuration: ``BeforeBrace``)
+      Only wrap before brace (equivalent to ``SplitEmptyRecord=false``).
+
+      .. code-block:: c++
+
         class foo
         {};
 
     * ``BWER_Never`` (in configuration: ``Never``)
-      Override wrapping for empty records.
+      Wrap neither before or after the brace.
 
       .. code-block:: c++
 
-        class foo
-        {
-          int foo;
-        };
-
         class foo {};
 
 
diff --git a/clang/docs/tools/dump_format_style.py 
b/clang/docs/tools/dump_format_style.py
index f035143f6b3d1..227bf36c58024 100755
--- a/clang/docs/tools/dump_format_style.py
+++ b/clang/docs/tools/dump_format_style.py
@@ -384,7 +384,7 @@ class State:
                 else:
                     state = State.InNestedStruct
                     field_type, field_name = re.match(
-                        r"([<>:\w(,\s)]+)\s+(\w+);", line
+                        r"(?:// )?([<>:\w(,\s)]+)\s+(\w+);", line
                     ).groups()
                     # if not version:
                     #    self.__warning(f"missing version for {field_name}", 
line)
diff --git a/clang/include/clang/Format/Format.h 
b/clang/include/clang/Format/Format.h
index 5d7d0fd9a48d6..22b43a68ed583 100644
--- a/clang/include/clang/Format/Format.h
+++ b/clang/include/clang/Format/Format.h
@@ -1357,25 +1357,22 @@ struct FormatStyle {
 
   /// Override wrapping of empty records.
   enum BraceWrapEmptyRecordStyle : int8_t {
-    /// Use default wrapping rules for records
+    /// Use default wrapping rules for empty records
     /// (``AfterClass``,``AfterStruct``,``AfterUnion``).
     /// \code
     ///   class foo
     ///   {
-    ///     int foo;
     ///   };
-    ///
-    ///   class foo
-    ///   {};
     /// \endcode
     BWER_Default,
-    /// Override wrapping for empty records.
+    /// Only wrap before brace (equivalent to ``SplitEmptyRecord=false``).
     /// \code
     ///   class foo
-    ///   {
-    ///     int foo;
-    ///   };
-    ///
+    ///   {};
+    /// \endcode
+    BWER_BeforeBrace,
+    /// Wrap neither before or after the brace.
+    /// \code
     ///   class foo {};
     /// \endcode
     BWER_Never
@@ -1587,6 +1584,7 @@ struct FormatStyle {
     /// \endcode
     ///
     bool SplitEmptyFunction;
+    /// This option is **deprecated**. See `WrapEmptyRecord`.
     /// If ``false``, empty record (e.g. class, struct or union) body
     /// can be put on a single line. This option is used only if the opening
     /// brace of the record has already been wrapped, i.e. the ``AfterClass``
@@ -1597,8 +1595,8 @@ struct FormatStyle {
     ///   {}               {
     ///                    }
     /// \endcode
-    ///
-    bool SplitEmptyRecord;
+    // bool SplitEmptyRecord;
+    
     /// If ``false``, empty namespace body can be put on a single line.
     /// This option is used only if the opening brace of the namespace has
     /// already been wrapped, i.e. the ``AfterNamespace`` brace wrapping mode 
is
diff --git a/clang/lib/Format/Format.cpp b/clang/lib/Format/Format.cpp
index 0d72410f00c27..6f865b66e3aed 100644
--- a/clang/lib/Format/Format.cpp
+++ b/clang/lib/Format/Format.cpp
@@ -198,7 +198,7 @@ template <> struct 
MappingTraits<FormatStyle::BraceWrappingFlags> {
     IO.mapOptional("BeforeWhile", Wrapping.BeforeWhile);
     IO.mapOptional("IndentBraces", Wrapping.IndentBraces);
     IO.mapOptional("SplitEmptyFunction", Wrapping.SplitEmptyFunction);
-    IO.mapOptional("SplitEmptyRecord", Wrapping.SplitEmptyRecord);
+    IO.mapOptional("SplitEmptyRecord", Wrapping.WrapEmptyRecord); // For 
backward compatibility.
     IO.mapOptional("SplitEmptyNamespace", Wrapping.SplitEmptyNamespace);
     IO.mapOptional("WrapEmptyRecord", Wrapping.WrapEmptyRecord);
   }
@@ -239,6 +239,10 @@ struct 
ScalarEnumerationTraits<FormatStyle::BraceWrapEmptyRecordStyle> {
                           FormatStyle::BraceWrapEmptyRecordStyle &Value) {
     IO.enumCase(Value, "Default", FormatStyle::BWER_Default);
     IO.enumCase(Value, "Never", FormatStyle::BWER_Never);
+
+    // For backward compatibility.
+    IO.enumCase(Value, "false", FormatStyle::BWER_BeforeBrace);
+    IO.enumCase(Value, "true", FormatStyle::BWER_Default);
   }
 };
 
@@ -1401,7 +1405,6 @@ static void expandPresetsBraceWrapping(FormatStyle 
&Expanded) {
                             /*BeforeWhile=*/false,
                             /*IndentBraces=*/false,
                             /*SplitEmptyFunction=*/true,
-                            /*SplitEmptyRecord=*/true,
                             /*SplitEmptyNamespace=*/true,
                             /*WrapEmptyRecord=*/FormatStyle::BWER_Default};
   switch (Expanded.BreakBeforeBraces) {
@@ -1418,7 +1421,7 @@ static void expandPresetsBraceWrapping(FormatStyle 
&Expanded) {
     Expanded.BraceWrapping.AfterUnion = true;
     Expanded.BraceWrapping.AfterExternBlock = true;
     Expanded.BraceWrapping.SplitEmptyFunction = true;
-    Expanded.BraceWrapping.SplitEmptyRecord = false;
+    Expanded.BraceWrapping.WrapEmptyRecord = FormatStyle::BWER_BeforeBrace;
     break;
   case FormatStyle::BS_Stroustrup:
     Expanded.BraceWrapping.AfterFunction = true;
@@ -1472,8 +1475,8 @@ static void expandPresetsBraceWrapping(FormatStyle 
&Expanded) {
         /*BeforeWhile=*/true,
         /*IndentBraces=*/true,
         /*SplitEmptyFunction=*/true,
-        /*SplitEmptyRecord=*/true,
-        /*SplitEmptyNamespace=*/true};
+        /*SplitEmptyNamespace=*/true,
+        /*WrapEmptyRecord=*/FormatStyle::BWER_Default};
     break;
   case FormatStyle::BS_WebKit:
     Expanded.BraceWrapping.AfterFunction = true;
@@ -1572,8 +1575,8 @@ FormatStyle getLLVMStyle(FormatStyle::LanguageKind 
Language) {
                              /*BeforeWhile=*/false,
                              /*IndentBraces=*/false,
                              /*SplitEmptyFunction=*/true,
-                             /*SplitEmptyRecord=*/true,
-                             /*SplitEmptyNamespace=*/true};
+                             /*SplitEmptyNamespace=*/true,
+                             /*WrapEmptyRecord=*/FormatStyle::BWER_Default};
   LLVMStyle.BreakAdjacentStringLiterals = true;
   LLVMStyle.BreakAfterAttributes = FormatStyle::ABS_Leave;
   LLVMStyle.BreakAfterJavaFieldAnnotations = false;
diff --git a/clang/lib/Format/UnwrappedLineFormatter.cpp 
b/clang/lib/Format/UnwrappedLineFormatter.cpp
index 0adf7ee9ed543..5adea2d8f1032 100644
--- a/clang/lib/Format/UnwrappedLineFormatter.cpp
+++ b/clang/lib/Format/UnwrappedLineFormatter.cpp
@@ -277,13 +277,13 @@ class LineJoiner {
         Tok = Tok->getNextNonComment();
       if (Tok && Tok->isOneOf(tok::kw_class, tok::kw_struct, tok::kw_union,
                               tok::kw_extern, Keywords.kw_interface)) {
-        return !Style.BraceWrapping.SplitEmptyRecord && EmptyBlock
+        return Style.BraceWrapping.WrapEmptyRecord != 
FormatStyle::BWER_Default && EmptyBlock
                    ? tryMergeSimpleBlock(I, E, Limit)
                    : 0;
       }
 
       if (Tok && Tok->is(tok::kw_template) &&
-          Style.BraceWrapping.SplitEmptyRecord && EmptyBlock) {
+          Style.BraceWrapping.WrapEmptyRecord == FormatStyle::BWER_Default && 
EmptyBlock) {
         return 0;
       }
     }
@@ -453,9 +453,9 @@ class LineJoiner {
       }
     }
 
-    // Don't merge an empty template class or struct if SplitEmptyRecords
-    // is defined.
-    if (PreviousLine && Style.BraceWrapping.SplitEmptyRecord &&
+    // Merge an empty class or struct only if WrapEmptyRecord
+    // is not set to Default
+    if (PreviousLine && Style.BraceWrapping.WrapEmptyRecord == 
FormatStyle::BWER_Default &&
         TheLine->Last->is(tok::l_brace) && PreviousLine->Last) {
       const FormatToken *Previous = PreviousLine->Last;
       if (Previous) {
@@ -495,7 +495,7 @@ class LineJoiner {
         // elsewhere.
         ShouldMerge = !Style.BraceWrapping.AfterClass ||
                       (NextLine.First->is(tok::r_brace) &&
-                       !Style.BraceWrapping.SplitEmptyRecord);
+                       Style.BraceWrapping.WrapEmptyRecord != 
FormatStyle::BWER_Default);
       } else if (TheLine->InPPDirective ||
                  !TheLine->First->isOneOf(tok::kw_class, tok::kw_enum,
                                           tok::kw_struct)) {
diff --git a/clang/unittests/Format/ConfigParseTest.cpp 
b/clang/unittests/Format/ConfigParseTest.cpp
index 9de3cca71630d..4479128e00397 100644
--- a/clang/unittests/Format/ConfigParseTest.cpp
+++ b/clang/unittests/Format/ConfigParseTest.cpp
@@ -237,7 +237,6 @@ TEST(ConfigParseTest, ParsesConfigurationBools) {
   CHECK_PARSE_NESTED_BOOL(BraceWrapping, BeforeWhile);
   CHECK_PARSE_NESTED_BOOL(BraceWrapping, IndentBraces);
   CHECK_PARSE_NESTED_BOOL(BraceWrapping, SplitEmptyFunction);
-  CHECK_PARSE_NESTED_BOOL(BraceWrapping, SplitEmptyRecord);
   CHECK_PARSE_NESTED_BOOL(BraceWrapping, SplitEmptyNamespace);
   CHECK_PARSE_NESTED_BOOL(KeepEmptyLines, AtEndOfFile);
   CHECK_PARSE_NESTED_BOOL(KeepEmptyLines, AtStartOfBlock);
diff --git a/clang/unittests/Format/FormatTest.cpp 
b/clang/unittests/Format/FormatTest.cpp
index 5ac92a45927ce..a4f85b8c6d131 100644
--- a/clang/unittests/Format/FormatTest.cpp
+++ b/clang/unittests/Format/FormatTest.cpp
@@ -1491,7 +1491,7 @@ TEST_F(FormatTest, FormatShortBracedStatements) {
   AllowSimpleBracedStatements.AllowShortLoopsOnASingleLine = true;
   AllowSimpleBracedStatements.BreakBeforeBraces = FormatStyle::BS_Custom;
   AllowSimpleBracedStatements.BraceWrapping.AfterFunction = true;
-  AllowSimpleBracedStatements.BraceWrapping.SplitEmptyRecord = false;
+  AllowSimpleBracedStatements.BraceWrapping.WrapEmptyRecord = 
FormatStyle::BWER_BeforeBrace;
 
   verifyFormat("if (true) {}", AllowSimpleBracedStatements);
   verifyFormat("if constexpr (true) {}", AllowSimpleBracedStatements);
@@ -4678,7 +4678,7 @@ TEST_F(FormatTest, FormatsExternC) {
                Style);
 
   Style.BraceWrapping.AfterExternBlock = true;
-  Style.BraceWrapping.SplitEmptyRecord = false;
+  Style.BraceWrapping.WrapEmptyRecord = FormatStyle::BWER_BeforeBrace;
   verifyFormat("extern \"C\"\n"
                "{}",
                Style);
@@ -15322,7 +15322,7 @@ TEST_F(FormatTest, SplitEmptyFunctionButNotRecord) {
   Style.BreakBeforeBraces = FormatStyle::BS_Custom;
   Style.BraceWrapping.AfterFunction = true;
   Style.BraceWrapping.SplitEmptyFunction = true;
-  Style.BraceWrapping.SplitEmptyRecord = false;
+  Style.BraceWrapping.WrapEmptyRecord = FormatStyle::BWER_BeforeBrace;
 
   verifyFormat("class C {};", Style);
   verifyFormat("struct C {};", Style);
@@ -15361,7 +15361,7 @@ TEST_F(FormatTest, SplitEmptyClass) {
   FormatStyle Style = getLLVMStyle();
   Style.BreakBeforeBraces = FormatStyle::BS_Custom;
   Style.BraceWrapping.AfterClass = true;
-  Style.BraceWrapping.SplitEmptyRecord = false;
+  Style.BraceWrapping.WrapEmptyRecord = FormatStyle::BWER_BeforeBrace;
 
   verifyFormat("class Foo\n"
                "{};",
@@ -15382,7 +15382,7 @@ TEST_F(FormatTest, SplitEmptyClass) {
                "} Foo_t;",
                Style);
 
-  Style.BraceWrapping.SplitEmptyRecord = true;
+  Style.BraceWrapping.WrapEmptyRecord = FormatStyle::BWER_Default;
   Style.BraceWrapping.AfterStruct = true;
   verifyFormat("class rep\n"
                "{\n"
@@ -15467,7 +15467,7 @@ TEST_F(FormatTest, SplitEmptyStruct) {
   FormatStyle Style = getLLVMStyle();
   Style.BreakBeforeBraces = FormatStyle::BS_Custom;
   Style.BraceWrapping.AfterStruct = true;
-  Style.BraceWrapping.SplitEmptyRecord = false;
+  Style.BraceWrapping.WrapEmptyRecord = FormatStyle::BWER_BeforeBrace;
 
   verifyFormat("struct Foo\n"
                "{};",
@@ -15494,7 +15494,7 @@ TEST_F(FormatTest, SplitEmptyUnion) {
   FormatStyle Style = getLLVMStyle();
   Style.BreakBeforeBraces = FormatStyle::BS_Custom;
   Style.BraceWrapping.AfterUnion = true;
-  Style.BraceWrapping.SplitEmptyRecord = false;
+  Style.BraceWrapping.WrapEmptyRecord = FormatStyle::BWER_BeforeBrace;
 
   verifyFormat("union Foo\n"
                "{};",
@@ -15622,7 +15622,7 @@ TEST_F(FormatTest, WrapEmptyRecords) {
   Style.BraceWrapping.AfterStruct = true;
   Style.BraceWrapping.AfterClass = true;
   Style.BraceWrapping.AfterUnion = true;
-  Style.BraceWrapping.SplitEmptyRecord = false;
+  Style.BraceWrapping.WrapEmptyRecord = FormatStyle::BWER_BeforeBrace;
 
   verifyFormat("class foo\n{\n"
                "  void bar();\n"
diff --git a/clang/unittests/Format/FormatTestCSharp.cpp 
b/clang/unittests/Format/FormatTestCSharp.cpp
index ea85ed6140dd0..303e6f42898e3 100644
--- a/clang/unittests/Format/FormatTestCSharp.cpp
+++ b/clang/unittests/Format/FormatTestCSharp.cpp
@@ -1315,7 +1315,7 @@ if (someThings[i][j][k].Contains(myThing)) {
 TEST_F(FormatTestCSharp, CSharpGenericTypeConstraints) {
   FormatStyle Style = getGoogleStyle(FormatStyle::LK_CSharp);
 
-  EXPECT_TRUE(Style.BraceWrapping.SplitEmptyRecord);
+  EXPECT_EQ(Style.BraceWrapping.WrapEmptyRecord, FormatStyle::BWER_Default);
 
   verifyFormat("class ItemFactory<T>\n"
                "    where T : new() {\n"

From 84852590930ca927818113b3cbebe52c15847058 Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?Tom=C3=A1=C5=A1=20Slanina?= <itzexpoe...@gmail.com>
Date: Wed, 13 Aug 2025 14:39:05 +0200
Subject: [PATCH 6/9] Fix formatting

---
 clang/lib/Format/Format.cpp                 |  4 +++-
 clang/lib/Format/UnwrappedLineFormatter.cpp | 17 +++++++++++------
 clang/unittests/Format/FormatTest.cpp       |  3 ++-
 3 files changed, 16 insertions(+), 8 deletions(-)

diff --git a/clang/lib/Format/Format.cpp b/clang/lib/Format/Format.cpp
index 6f865b66e3aed..3c4b8ba3f54b6 100644
--- a/clang/lib/Format/Format.cpp
+++ b/clang/lib/Format/Format.cpp
@@ -198,9 +198,11 @@ template <> struct 
MappingTraits<FormatStyle::BraceWrappingFlags> {
     IO.mapOptional("BeforeWhile", Wrapping.BeforeWhile);
     IO.mapOptional("IndentBraces", Wrapping.IndentBraces);
     IO.mapOptional("SplitEmptyFunction", Wrapping.SplitEmptyFunction);
-    IO.mapOptional("SplitEmptyRecord", Wrapping.WrapEmptyRecord); // For 
backward compatibility.
     IO.mapOptional("SplitEmptyNamespace", Wrapping.SplitEmptyNamespace);
     IO.mapOptional("WrapEmptyRecord", Wrapping.WrapEmptyRecord);
+
+    // For backward compatibility.
+    IO.mapOptional("SplitEmptyRecord", Wrapping.WrapEmptyRecord);
   }
 };
 
diff --git a/clang/lib/Format/UnwrappedLineFormatter.cpp 
b/clang/lib/Format/UnwrappedLineFormatter.cpp
index 5adea2d8f1032..74df699111fb9 100644
--- a/clang/lib/Format/UnwrappedLineFormatter.cpp
+++ b/clang/lib/Format/UnwrappedLineFormatter.cpp
@@ -277,13 +277,16 @@ class LineJoiner {
         Tok = Tok->getNextNonComment();
       if (Tok && Tok->isOneOf(tok::kw_class, tok::kw_struct, tok::kw_union,
                               tok::kw_extern, Keywords.kw_interface)) {
-        return Style.BraceWrapping.WrapEmptyRecord != 
FormatStyle::BWER_Default && EmptyBlock
+        return Style.BraceWrapping.WrapEmptyRecord !=
+                           FormatStyle::BWER_Default &&
+                       EmptyBlock
                    ? tryMergeSimpleBlock(I, E, Limit)
                    : 0;
       }
 
       if (Tok && Tok->is(tok::kw_template) &&
-          Style.BraceWrapping.WrapEmptyRecord == FormatStyle::BWER_Default && 
EmptyBlock) {
+          Style.BraceWrapping.WrapEmptyRecord == FormatStyle::BWER_Default &&
+          EmptyBlock) {
         return 0;
       }
     }
@@ -455,7 +458,8 @@ class LineJoiner {
 
     // Merge an empty class or struct only if WrapEmptyRecord
     // is not set to Default
-    if (PreviousLine && Style.BraceWrapping.WrapEmptyRecord == 
FormatStyle::BWER_Default &&
+    if (PreviousLine &&
+        Style.BraceWrapping.WrapEmptyRecord == FormatStyle::BWER_Default &&
         TheLine->Last->is(tok::l_brace) && PreviousLine->Last) {
       const FormatToken *Previous = PreviousLine->Last;
       if (Previous) {
@@ -493,9 +497,10 @@ class LineJoiner {
         // NOTE: We use AfterClass (whereas AfterStruct exists) for both 
classes
         // and structs, but it seems that wrapping is still handled correctly
         // elsewhere.
-        ShouldMerge = !Style.BraceWrapping.AfterClass ||
-                      (NextLine.First->is(tok::r_brace) &&
-                       Style.BraceWrapping.WrapEmptyRecord != 
FormatStyle::BWER_Default);
+        ShouldMerge =
+            !Style.BraceWrapping.AfterClass ||
+            (NextLine.First->is(tok::r_brace) &&
+             Style.BraceWrapping.WrapEmptyRecord != FormatStyle::BWER_Default);
       } else if (TheLine->InPPDirective ||
                  !TheLine->First->isOneOf(tok::kw_class, tok::kw_enum,
                                           tok::kw_struct)) {
diff --git a/clang/unittests/Format/FormatTest.cpp 
b/clang/unittests/Format/FormatTest.cpp
index a4f85b8c6d131..ab5b48f50c86e 100644
--- a/clang/unittests/Format/FormatTest.cpp
+++ b/clang/unittests/Format/FormatTest.cpp
@@ -1491,7 +1491,8 @@ TEST_F(FormatTest, FormatShortBracedStatements) {
   AllowSimpleBracedStatements.AllowShortLoopsOnASingleLine = true;
   AllowSimpleBracedStatements.BreakBeforeBraces = FormatStyle::BS_Custom;
   AllowSimpleBracedStatements.BraceWrapping.AfterFunction = true;
-  AllowSimpleBracedStatements.BraceWrapping.WrapEmptyRecord = 
FormatStyle::BWER_BeforeBrace;
+  AllowSimpleBracedStatements.BraceWrapping.WrapEmptyRecord =
+      FormatStyle::BWER_BeforeBrace;
 
   verifyFormat("if (true) {}", AllowSimpleBracedStatements);
   verifyFormat("if constexpr (true) {}", AllowSimpleBracedStatements);

From 3c440e8e690017f3667af7f907db1c1de914aaf0 Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?Tom=C3=A1=C5=A1=20Slanina?= <itzexpoe...@gmail.com>
Date: Wed, 13 Aug 2025 17:11:18 +0200
Subject: [PATCH 7/9] Fixup docs, config parse, test

---
 clang/include/clang/Format/Format.h         |  4 ++--
 clang/lib/Format/Format.cpp                 |  8 +++++---
 clang/lib/Format/TokenAnnotator.cpp         |  6 ++++--
 clang/lib/Format/UnwrappedLineFormatter.cpp |  2 +-
 clang/unittests/Format/ConfigParseTest.cpp  | 18 ++++++++++++++++++
 clang/unittests/Format/FormatTest.cpp       | 13 +++++++++++++
 6 files changed, 43 insertions(+), 8 deletions(-)

diff --git a/clang/include/clang/Format/Format.h 
b/clang/include/clang/Format/Format.h
index 22b43a68ed583..74055580570d7 100644
--- a/clang/include/clang/Format/Format.h
+++ b/clang/include/clang/Format/Format.h
@@ -1365,13 +1365,13 @@ struct FormatStyle {
     ///   };
     /// \endcode
     BWER_Default,
-    /// Only wrap before brace (equivalent to ``SplitEmptyRecord=false``).
+    /// Only wrap before brace.
     /// \code
     ///   class foo
     ///   {};
     /// \endcode
     BWER_BeforeBrace,
-    /// Wrap neither before or after the brace.
+    /// Wrap neither before nor after the brace.
     /// \code
     ///   class foo {};
     /// \endcode
diff --git a/clang/lib/Format/Format.cpp b/clang/lib/Format/Format.cpp
index 3c4b8ba3f54b6..8687b487b2d15 100644
--- a/clang/lib/Format/Format.cpp
+++ b/clang/lib/Format/Format.cpp
@@ -182,6 +182,10 @@ template <> struct 
ScalarEnumerationTraits<FormatStyle::BraceBreakingStyle> {
 
 template <> struct MappingTraits<FormatStyle::BraceWrappingFlags> {
   static void mapping(IO &IO, FormatStyle::BraceWrappingFlags &Wrapping) {
+    // For backward compatibility.
+    if (!IO.outputting())
+      IO.mapOptional("SplitEmptyRecord", Wrapping.WrapEmptyRecord);
+
     IO.mapOptional("AfterCaseLabel", Wrapping.AfterCaseLabel);
     IO.mapOptional("AfterClass", Wrapping.AfterClass);
     IO.mapOptional("AfterControlStatement", Wrapping.AfterControlStatement);
@@ -200,9 +204,6 @@ template <> struct 
MappingTraits<FormatStyle::BraceWrappingFlags> {
     IO.mapOptional("SplitEmptyFunction", Wrapping.SplitEmptyFunction);
     IO.mapOptional("SplitEmptyNamespace", Wrapping.SplitEmptyNamespace);
     IO.mapOptional("WrapEmptyRecord", Wrapping.WrapEmptyRecord);
-
-    // For backward compatibility.
-    IO.mapOptional("SplitEmptyRecord", Wrapping.WrapEmptyRecord);
   }
 };
 
@@ -240,6 +241,7 @@ struct 
ScalarEnumerationTraits<FormatStyle::BraceWrapEmptyRecordStyle> {
   static void enumeration(IO &IO,
                           FormatStyle::BraceWrapEmptyRecordStyle &Value) {
     IO.enumCase(Value, "Default", FormatStyle::BWER_Default);
+    IO.enumCase(Value, "BeforeBrace", FormatStyle::BWER_BeforeBrace);
     IO.enumCase(Value, "Never", FormatStyle::BWER_Never);
 
     // For backward compatibility.
diff --git a/clang/lib/Format/TokenAnnotator.cpp 
b/clang/lib/Format/TokenAnnotator.cpp
index 22132f6d2fd3b..804a6fb0418c6 100644
--- a/clang/lib/Format/TokenAnnotator.cpp
+++ b/clang/lib/Format/TokenAnnotator.cpp
@@ -5933,12 +5933,14 @@ bool TokenAnnotator::mustBreakBefore(const 
AnnotatedLine &Line,
       return true;
     }
 
-    // Don't attempt to interpret struct return types as structs.
+    // Don't attempt to interpret record return types as records.
     if (Right.isNot(TT_FunctionLBrace)) {
       return ((Line.startsWith(tok::kw_class) &&
                Style.BraceWrapping.AfterClass) ||
               (Line.startsWith(tok::kw_struct) &&
-               Style.BraceWrapping.AfterStruct)) &&
+               Style.BraceWrapping.AfterStruct) ||
+              (Line.startsWith(tok::kw_union) &&
+               Style.BraceWrapping.AfterUnion)) &&
              Style.BraceWrapping.WrapEmptyRecord == FormatStyle::BWER_Default;
     }
   }
diff --git a/clang/lib/Format/UnwrappedLineFormatter.cpp 
b/clang/lib/Format/UnwrappedLineFormatter.cpp
index 74df699111fb9..01bc06a754c53 100644
--- a/clang/lib/Format/UnwrappedLineFormatter.cpp
+++ b/clang/lib/Format/UnwrappedLineFormatter.cpp
@@ -457,7 +457,7 @@ class LineJoiner {
     }
 
     // Merge an empty class or struct only if WrapEmptyRecord
-    // is not set to Default
+    // is not set to Default.
     if (PreviousLine &&
         Style.BraceWrapping.WrapEmptyRecord == FormatStyle::BWER_Default &&
         TheLine->Last->is(tok::l_brace) && PreviousLine->Last) {
diff --git a/clang/unittests/Format/ConfigParseTest.cpp 
b/clang/unittests/Format/ConfigParseTest.cpp
index 4479128e00397..809244bf86eb2 100644
--- a/clang/unittests/Format/ConfigParseTest.cpp
+++ b/clang/unittests/Format/ConfigParseTest.cpp
@@ -758,6 +758,24 @@ TEST(ConfigParseTest, ParsesConfiguration) {
               "  AfterControlStatement: false",
               BraceWrapping.AfterControlStatement, FormatStyle::BWACS_Never);
 
+  Style.BraceWrapping.WrapEmptyRecord = FormatStyle::BWER_Default;
+  CHECK_PARSE("BraceWrapping:\n"
+              "  WrapEmptyRecord: BeforeBrace",
+              BraceWrapping.WrapEmptyRecord, FormatStyle::BWER_BeforeBrace);
+  CHECK_PARSE("BraceWrapping:\n"
+              "  WrapEmptyRecord: Default",
+              BraceWrapping.WrapEmptyRecord, FormatStyle::BWER_Default);
+  CHECK_PARSE("BraceWrapping:\n"
+              "  WrapEmptyRecord: Never",
+              BraceWrapping.WrapEmptyRecord, FormatStyle::BWER_Never);
+  // For backward compatibility:
+  CHECK_PARSE("BraceWrapping:\n"
+              "  WrapEmptyRecord: true",
+              BraceWrapping.WrapEmptyRecord, FormatStyle::BWER_Default);
+  CHECK_PARSE("BraceWrapping:\n"
+              "  WrapEmptyRecord: false",
+              BraceWrapping.WrapEmptyRecord, FormatStyle::BWER_BeforeBrace);
+
   Style.BreakAfterReturnType = FormatStyle::RTBS_All;
   CHECK_PARSE("BreakAfterReturnType: None", BreakAfterReturnType,
               FormatStyle::RTBS_None);
diff --git a/clang/unittests/Format/FormatTest.cpp 
b/clang/unittests/Format/FormatTest.cpp
index ab5b48f50c86e..fa03bea45a533 100644
--- a/clang/unittests/Format/FormatTest.cpp
+++ b/clang/unittests/Format/FormatTest.cpp
@@ -8625,6 +8625,19 @@ TEST_F(FormatTest, BreaksFunctionDeclarations) {
                Style);
 }
 
+TEST_F(FormatTest, BreakFunctionsReturningRecords) {
+  FormatStyle Style = getLLVMStyle();
+  Style.BreakBeforeBraces = FormatStyle::BS_Custom;
+  Style.BraceWrapping.AfterFunction = true;
+  Style.BraceWrapping.AfterClass = false;
+  Style.BraceWrapping.AfterStruct = false;
+  Style.BraceWrapping.AfterUnion = false;
+
+  verifyFormat("class Bar foo() {}", Style);
+  verifyFormat("struct Bar foo() {}", Style);
+  verifyFormat("union Bar foo() {}", Style);
+}
+
 TEST_F(FormatTest, DontBreakBeforeQualifiedOperator) {
   // Regression test for https://bugs.llvm.org/show_bug.cgi?id=40516:
   // Prefer keeping `::` followed by `operator` together.

From 0a50d975af9e253f6e4ddfab37cb42288d93cfde Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?Tom=C3=A1=C5=A1=20Slanina?= <itzexpoe...@gmail.com>
Date: Wed, 13 Aug 2025 17:24:05 +0200
Subject: [PATCH 8/9] Regenerate format option docs

---
 clang/docs/ClangFormatStyleOptions.rst | 4 ++--
 1 file changed, 2 insertions(+), 2 deletions(-)

diff --git a/clang/docs/ClangFormatStyleOptions.rst 
b/clang/docs/ClangFormatStyleOptions.rst
index 375393e12691e..1197ede357dd4 100644
--- a/clang/docs/ClangFormatStyleOptions.rst
+++ b/clang/docs/ClangFormatStyleOptions.rst
@@ -2596,7 +2596,7 @@ the configuration (without a prefix: ``Auto``).
         };
 
     * ``BWER_BeforeBrace`` (in configuration: ``BeforeBrace``)
-      Only wrap before brace (equivalent to ``SplitEmptyRecord=false``).
+      Only wrap before brace.
 
       .. code-block:: c++
 
@@ -2604,7 +2604,7 @@ the configuration (without a prefix: ``Auto``).
         {};
 
     * ``BWER_Never`` (in configuration: ``Never``)
-      Wrap neither before or after the brace.
+      Wrap neither before nor after the brace.
 
       .. code-block:: c++
 

From c11352ed314c356e67902aaf602a54226c143473 Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?Tom=C3=A1=C5=A1=20Slanina?= <itzexpoe...@gmail.com>
Date: Thu, 14 Aug 2025 13:10:40 +0200
Subject: [PATCH 9/9] Fix formatting

---
 clang/include/clang/Format/Format.h | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/clang/include/clang/Format/Format.h 
b/clang/include/clang/Format/Format.h
index 74055580570d7..4f3784e33cb45 100644
--- a/clang/include/clang/Format/Format.h
+++ b/clang/include/clang/Format/Format.h
@@ -1596,7 +1596,7 @@ struct FormatStyle {
     ///                    }
     /// \endcode
     // bool SplitEmptyRecord;
-    
+
     /// If ``false``, empty namespace body can be put on a single line.
     /// This option is used only if the opening brace of the namespace has
     /// already been wrapped, i.e. the ``AfterNamespace`` brace wrapping mode 
is

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

Reply via email to