https://github.com/rmarker updated 
https://github.com/llvm/llvm-project/pull/143249

>From 212f9142a084c4d7bb11423565fb1f0eae93c35f Mon Sep 17 00:00:00 2001
From: rmarker <rmar...@outlook.com>
Date: Sat, 7 Jun 2025 20:29:18 +0930
Subject: [PATCH 1/2] [clang-format] Add options to control wrapped lambda
 brace indent.

Adds options to customise how wrapped lambda braces are indented when
using custom brace wrapping.
IndentBraces was recently changed to also indent wrapped lambda braces.
This has been changed to be controlled separately to allow the old
behaviour to be maintained.
Especially before a release is made with the new behaviour.
In order to further increase flexibility, the indentation can be
controlled separately for both nested and unnested lambdas.
---
 clang/docs/ClangFormatStyleOptions.rst     | 34 ++++++++++
 clang/docs/ReleaseNotes.rst                |  2 +
 clang/include/clang/Format/Format.h        | 32 +++++++++
 clang/lib/Format/ContinuationIndenter.cpp  | 17 +++--
 clang/lib/Format/Format.cpp                | 10 +++
 clang/unittests/Format/ConfigParseTest.cpp |  2 +
 clang/unittests/Format/FormatTest.cpp      | 78 ++++++++++++++++++++++
 7 files changed, 170 insertions(+), 5 deletions(-)

diff --git a/clang/docs/ClangFormatStyleOptions.rst 
b/clang/docs/ClangFormatStyleOptions.rst
index 83716cc049ee3..5294c77020945 100644
--- a/clang/docs/ClangFormatStyleOptions.rst
+++ b/clang/docs/ClangFormatStyleOptions.rst
@@ -2541,6 +2541,40 @@ the configuration (without a prefix: ``Auto``).
 
   * ``bool IndentBraces`` Indent the wrapped braces themselves.
 
+  * ``bool IndentBracesLambdaNested`` Indent nested wrapped lambda braces.
+
+    .. code-block:: c++
+
+      false:
+      function(
+          []()
+          {
+            return true;
+          });
+
+      true:
+      function(
+          []()
+            {
+              return true;
+            });
+
+  * ``bool IndentBracesLambdaUnnested`` Indent unnested wrapped lambda braces.
+
+    .. code-block:: c++
+
+      false:
+      auto foo = []()
+      {
+        return true;
+      };
+
+      true:
+      auto foo = []()
+        {
+          return true;
+        };
+
   * ``bool SplitEmptyFunction`` If ``false``, empty function body can be put 
on a single line.
     This option is used only if the opening brace of the function has
     already been wrapped, i.e. the ``AfterFunction`` brace wrapping mode is
diff --git a/clang/docs/ReleaseNotes.rst b/clang/docs/ReleaseNotes.rst
index 9ab69320f0368..03e33c4fcdc49 100644
--- a/clang/docs/ReleaseNotes.rst
+++ b/clang/docs/ReleaseNotes.rst
@@ -988,6 +988,8 @@ clang-format
   ``enum`` enumerator lists.
 - Add ``OneLineFormatOffRegex`` option for turning formatting off for one line.
 - Add ``SpaceAfterOperatorKeyword`` option.
+- Add ``IndentBracesLambdaNested`` and ``IndentBracesLambdaUnnested`` to
+  ``BraceWrapping`` options for controlling wrapped lambda brace indentation.
 
 clang-refactor
 --------------
diff --git a/clang/include/clang/Format/Format.h 
b/clang/include/clang/Format/Format.h
index 127b1d08919de..86291d6fa845c 100644
--- a/clang/include/clang/Format/Format.h
+++ b/clang/include/clang/Format/Format.h
@@ -1547,6 +1547,38 @@ struct FormatStyle {
     bool BeforeWhile;
     /// Indent the wrapped braces themselves.
     bool IndentBraces;
+    /// Indent nested wrapped lambda braces.
+    /// \code
+    ///   false:
+    ///   function(
+    ///       []()
+    ///       {
+    ///         return true;
+    ///       });
+    ///
+    ///   true:
+    ///   function(
+    ///       []()
+    ///         {
+    ///           return true;
+    ///         });
+    /// \endcode
+    bool IndentBracesLambdaNested;
+    /// Indent unnested wrapped lambda braces.
+    /// \code
+    ///   false:
+    ///   auto foo = []()
+    ///   {
+    ///     return true;
+    ///   };
+    ///
+    ///   true:
+    ///   auto foo = []()
+    ///     {
+    ///       return true;
+    ///     };
+    /// \endcode
+    bool IndentBracesLambdaUnnested;
     /// If ``false``, empty function body can be put on a single line.
     /// This option is used only if the opening brace of the function has
     /// already been wrapped, i.e. the ``AfterFunction`` brace wrapping mode is
diff --git a/clang/lib/Format/ContinuationIndenter.cpp 
b/clang/lib/Format/ContinuationIndenter.cpp
index 4e4e48f90a89f..d37b075da61ae 100644
--- a/clang/lib/Format/ContinuationIndenter.cpp
+++ b/clang/lib/Format/ContinuationIndenter.cpp
@@ -1334,12 +1334,15 @@ unsigned ContinuationIndenter::getNewLineColumn(const 
LineState &State) {
            Style.IndentWidth;
   }
 
-  if (Style.BraceWrapping.BeforeLambdaBody &&
-      Style.BraceWrapping.IndentBraces && Current.is(TT_LambdaLBrace)) {
+  if (Style.BraceWrapping.BeforeLambdaBody && Current.is(TT_LambdaLBrace)) {
+    const auto Nested = Current.NestingLevel != 0;
     const auto From = Style.LambdaBodyIndentation == FormatStyle::LBI_Signature
                           ? CurrentState.Indent
                           : State.FirstIndent;
-    return From + Style.IndentWidth;
+    const auto Indent =
+        (Style.BraceWrapping.IndentBracesLambdaNested && Nested) ||
+        (Style.BraceWrapping.IndentBracesLambdaUnnested && !Nested);
+    return From + (Indent * Style.IndentWidth);
   }
 
   if ((NextNonComment->is(tok::l_brace) && NextNonComment->is(BK_Block)) ||
@@ -2123,8 +2126,12 @@ void ContinuationIndenter::moveStateToNewBlock(LineState 
&State, bool NewLine) {
   if (Style.LambdaBodyIndentation == FormatStyle::LBI_OuterScope &&
       State.NextToken->is(TT_LambdaLBrace) &&
       !State.Line->MightBeFunctionDecl) {
-    const auto Indent = Style.IndentWidth * Style.BraceWrapping.IndentBraces;
-    State.Stack.back().NestedBlockIndent = State.FirstIndent + Indent;
+    const auto Nested = State.NextToken->NestingLevel != 0;
+    const auto Indent =
+        (Style.BraceWrapping.IndentBracesLambdaNested && Nested) ||
+        (Style.BraceWrapping.IndentBracesLambdaUnnested && !Nested);
+    State.Stack.back().NestedBlockIndent =
+        State.FirstIndent + (Indent * Style.IndentWidth);
   }
   unsigned NestedBlockIndent = State.Stack.back().NestedBlockIndent;
   // ObjC block sometimes follow special indentation rules.
diff --git a/clang/lib/Format/Format.cpp b/clang/lib/Format/Format.cpp
index bdaf264e9adce..db0f9f87eeb0a 100644
--- a/clang/lib/Format/Format.cpp
+++ b/clang/lib/Format/Format.cpp
@@ -196,6 +196,10 @@ template <> struct 
MappingTraits<FormatStyle::BraceWrappingFlags> {
     IO.mapOptional("BeforeLambdaBody", Wrapping.BeforeLambdaBody);
     IO.mapOptional("BeforeWhile", Wrapping.BeforeWhile);
     IO.mapOptional("IndentBraces", Wrapping.IndentBraces);
+    IO.mapOptional("IndentBracesLambdaNested",
+                   Wrapping.IndentBracesLambdaNested);
+    IO.mapOptional("IndentBracesLambdaUnnested",
+                   Wrapping.IndentBracesLambdaUnnested);
     IO.mapOptional("SplitEmptyFunction", Wrapping.SplitEmptyFunction);
     IO.mapOptional("SplitEmptyRecord", Wrapping.SplitEmptyRecord);
     IO.mapOptional("SplitEmptyNamespace", Wrapping.SplitEmptyNamespace);
@@ -1382,6 +1386,8 @@ static void expandPresetsBraceWrapping(FormatStyle 
&Expanded) {
                             /*BeforeLambdaBody=*/false,
                             /*BeforeWhile=*/false,
                             /*IndentBraces=*/false,
+                            /*IndentBracesLambdaNested=*/false,
+                            /*IndentBracesLambdaUnnested=*/false,
                             /*SplitEmptyFunction=*/true,
                             /*SplitEmptyRecord=*/true,
                             /*SplitEmptyNamespace=*/true};
@@ -1452,6 +1458,8 @@ static void expandPresetsBraceWrapping(FormatStyle 
&Expanded) {
         /*BeforeLambdaBody=*/true,
         /*BeforeWhile=*/true,
         /*IndentBraces=*/true,
+        /*IndentBracesLambdaNested=*/true,
+        /*IndentBracesLambdaUnnested=*/true,
         /*SplitEmptyFunction=*/true,
         /*SplitEmptyRecord=*/true,
         /*SplitEmptyNamespace=*/true};
@@ -1552,6 +1560,8 @@ FormatStyle getLLVMStyle(FormatStyle::LanguageKind 
Language) {
                              /*BeforeLambdaBody=*/false,
                              /*BeforeWhile=*/false,
                              /*IndentBraces=*/false,
+                             /*IndentBracesLambdaNested=*/false,
+                             /*IndentBracesLambdaUnnested=*/false,
                              /*SplitEmptyFunction=*/true,
                              /*SplitEmptyRecord=*/true,
                              /*SplitEmptyNamespace=*/true};
diff --git a/clang/unittests/Format/ConfigParseTest.cpp 
b/clang/unittests/Format/ConfigParseTest.cpp
index aedfdd151d6d3..4436e5ef4904f 100644
--- a/clang/unittests/Format/ConfigParseTest.cpp
+++ b/clang/unittests/Format/ConfigParseTest.cpp
@@ -236,6 +236,8 @@ TEST(ConfigParseTest, ParsesConfigurationBools) {
   CHECK_PARSE_NESTED_BOOL(BraceWrapping, BeforeLambdaBody);
   CHECK_PARSE_NESTED_BOOL(BraceWrapping, BeforeWhile);
   CHECK_PARSE_NESTED_BOOL(BraceWrapping, IndentBraces);
+  CHECK_PARSE_NESTED_BOOL(BraceWrapping, IndentBracesLambdaNested);
+  CHECK_PARSE_NESTED_BOOL(BraceWrapping, IndentBracesLambdaUnnested);
   CHECK_PARSE_NESTED_BOOL(BraceWrapping, SplitEmptyFunction);
   CHECK_PARSE_NESTED_BOOL(BraceWrapping, SplitEmptyRecord);
   CHECK_PARSE_NESTED_BOOL(BraceWrapping, SplitEmptyNamespace);
diff --git a/clang/unittests/Format/FormatTest.cpp 
b/clang/unittests/Format/FormatTest.cpp
index c0633ba3c29b3..fa06554ed584c 100644
--- a/clang/unittests/Format/FormatTest.cpp
+++ b/clang/unittests/Format/FormatTest.cpp
@@ -24358,6 +24358,84 @@ TEST_F(FormatTest, LambdaBracesInGNU) {
                Style);
 }
 
+TEST_F(FormatTest, LambdaBracesIndentationNested) {
+  auto Style = getLLVMStyle();
+  EXPECT_EQ(Style.LambdaBodyIndentation, FormatStyle::LBI_Signature);
+
+  Style.BreakBeforeBraces = FormatStyle::BS_Custom;
+  Style.BraceWrapping.BeforeLambdaBody = true;
+  verifyFormat("function(\n"
+               "    [&]()\n"
+               "    {\n"
+               "      for (int i = 0; i < y; ++i)\n"
+               "        return 97;\n"
+               "    });",
+               Style);
+
+  Style.BraceWrapping.IndentBracesLambdaNested = true;
+  verifyFormat("function(\n"
+               "    [&]()\n"
+               "      {\n"
+               "        for (int i = 0; i < y; ++i)\n"
+               "          return 97;\n"
+               "      });",
+               Style);
+
+  Style.LambdaBodyIndentation = FormatStyle::LBI_OuterScope;
+  verifyFormat("function([&]()\n"
+               "  {\n"
+               "    for (int i = 0; i < y; ++i)\n"
+               "      return 97;\n"
+               "  });",
+               Style);
+
+  Style.BraceWrapping.IndentBracesLambdaNested = false;
+  verifyFormat("function([&]()\n"
+               "{\n"
+               "  for (int i = 0; i < y; ++i)\n"
+               "    return 97;\n"
+               "});",
+               Style);
+}
+
+TEST_F(FormatTest, LambdaBracesIndentationUnnested) {
+  auto Style = getLLVMStyle();
+  EXPECT_EQ(Style.LambdaBodyIndentation, FormatStyle::LBI_Signature);
+
+  Style.BreakBeforeBraces = FormatStyle::BS_Custom;
+  Style.BraceWrapping.BeforeLambdaBody = true;
+  verifyFormat("auto x = [&]()\n"
+               "{\n"
+               "  for (int i = 0; i < y; ++i)\n"
+               "    return 97;\n"
+               "};",
+               Style);
+
+  Style.BraceWrapping.IndentBracesLambdaUnnested = true;
+  verifyFormat("auto x = [&]()\n"
+               "  {\n"
+               "    for (int i = 0; i < y; ++i)\n"
+               "      return 97;\n"
+               "  };",
+               Style);
+
+  Style.LambdaBodyIndentation = FormatStyle::LBI_OuterScope;
+  verifyFormat("auto x = [&]()\n"
+               "  {\n"
+               "    for (int i = 0; i < y; ++i)\n"
+               "      return 97;\n"
+               "  };",
+               Style);
+
+  Style.BraceWrapping.IndentBracesLambdaUnnested = false;
+  verifyFormat("auto x = [&]()\n"
+               "{\n"
+               "  for (int i = 0; i < y; ++i)\n"
+               "    return 97;\n"
+               "};",
+               Style);
+}
+
 TEST_F(FormatTest, FormatsBlocks) {
   FormatStyle ShortBlocks = getLLVMStyle();
   ShortBlocks.AllowShortBlocksOnASingleLine = FormatStyle::SBS_Always;

>From b8c94459def487429e8d8fcfb5d67d843de00d0b Mon Sep 17 00:00:00 2001
From: rmarker <rmar...@outlook.com>
Date: Sat, 7 Jun 2025 22:06:27 +0930
Subject: [PATCH 2/2] Improve handling of Nested to make it cleaner.

---
 clang/lib/Format/ContinuationIndenter.cpp | 14 ++++++--------
 1 file changed, 6 insertions(+), 8 deletions(-)

diff --git a/clang/lib/Format/ContinuationIndenter.cpp 
b/clang/lib/Format/ContinuationIndenter.cpp
index d37b075da61ae..81d7ad7dd1eeb 100644
--- a/clang/lib/Format/ContinuationIndenter.cpp
+++ b/clang/lib/Format/ContinuationIndenter.cpp
@@ -1335,13 +1335,12 @@ unsigned ContinuationIndenter::getNewLineColumn(const 
LineState &State) {
   }
 
   if (Style.BraceWrapping.BeforeLambdaBody && Current.is(TT_LambdaLBrace)) {
-    const auto Nested = Current.NestingLevel != 0;
+    const auto Nested = Current.NestingLevel > 0;
     const auto From = Style.LambdaBodyIndentation == FormatStyle::LBI_Signature
                           ? CurrentState.Indent
                           : State.FirstIndent;
-    const auto Indent =
-        (Style.BraceWrapping.IndentBracesLambdaNested && Nested) ||
-        (Style.BraceWrapping.IndentBracesLambdaUnnested && !Nested);
+    const auto Indent = Nested ? Style.BraceWrapping.IndentBracesLambdaNested
+                               : 
Style.BraceWrapping.IndentBracesLambdaUnnested;
     return From + (Indent * Style.IndentWidth);
   }
 
@@ -2126,10 +2125,9 @@ void ContinuationIndenter::moveStateToNewBlock(LineState 
&State, bool NewLine) {
   if (Style.LambdaBodyIndentation == FormatStyle::LBI_OuterScope &&
       State.NextToken->is(TT_LambdaLBrace) &&
       !State.Line->MightBeFunctionDecl) {
-    const auto Nested = State.NextToken->NestingLevel != 0;
-    const auto Indent =
-        (Style.BraceWrapping.IndentBracesLambdaNested && Nested) ||
-        (Style.BraceWrapping.IndentBracesLambdaUnnested && !Nested);
+    const auto Nested = State.NextToken->NestingLevel > 0;
+    const auto Indent = Nested ? Style.BraceWrapping.IndentBracesLambdaNested
+                               : 
Style.BraceWrapping.IndentBracesLambdaUnnested;
     State.Stack.back().NestedBlockIndent =
         State.FirstIndent + (Indent * Style.IndentWidth);
   }

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

Reply via email to