llvmbot wrote:

<!--LLVM PR SUMMARY COMMENT-->

@llvm/pr-subscribers-clang

Author: None (rmarker)

<details>
<summary>Changes</summary>

Adds options to customise how wrapped lambda braces are indented when using 
custom brace wrapping.

`IndentBraces` was recently updated to also indent wrapped lambda braces. This 
has been changed to be controlled separately to allow the old behaviour to be 
maintained. Ideally 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.

Resolves #<!-- -->143248

---
Full diff: https://github.com/llvm/llvm-project/pull/143249.diff


7 Files Affected:

- (modified) clang/docs/ClangFormatStyleOptions.rst (+34) 
- (modified) clang/docs/ReleaseNotes.rst (+2) 
- (modified) clang/include/clang/Format/Format.h (+32) 
- (modified) clang/lib/Format/ContinuationIndenter.cpp (+12-5) 
- (modified) clang/lib/Format/Format.cpp (+10) 
- (modified) clang/unittests/Format/ConfigParseTest.cpp (+2) 
- (modified) clang/unittests/Format/FormatTest.cpp (+78) 


``````````diff
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;

``````````

</details>


https://github.com/llvm/llvm-project/pull/143249
_______________________________________________
cfe-commits mailing list
cfe-commits@lists.llvm.org
https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits

Reply via email to