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

>From a25f8f96d82d3eaff6fec031bc7ba6f9917156b8 Mon Sep 17 00:00:00 2001
From: rmarker <rmar...@outlook.com>
Date: Tue, 27 May 2025 19:54:00 +0930
Subject: [PATCH] [clang-format] Stop moving lambda to new line only to indent
 it more.

Hanging indents are minimised for lambdas by pushing them onto a new
line. However, it could still do this even if it would cause even more
hanging indents than it otherwise would.

The handling has been expanded to check for this case and avoid moving
the lambda to a new line.
---
 clang/lib/Format/ContinuationIndenter.cpp | 30 ++++++++++++++++++++---
 clang/unittests/Format/FormatTest.cpp     | 11 +++++++++
 2 files changed, 37 insertions(+), 4 deletions(-)

diff --git a/clang/lib/Format/ContinuationIndenter.cpp 
b/clang/lib/Format/ContinuationIndenter.cpp
index b4745477b96ef..86544928016dd 100644
--- a/clang/lib/Format/ContinuationIndenter.cpp
+++ b/clang/lib/Format/ContinuationIndenter.cpp
@@ -325,13 +325,35 @@ bool ContinuationIndenter::canBreak(const LineState 
&State) {
   if (Current.isMemberAccess() && CurrentState.ContainsUnwrappedBuilder)
     return false;
 
-  // Don't create a 'hanging' indent if there are multiple blocks in a single
-  // statement and we are aligning lambda blocks to their signatures.
+  // Force a lambda onto a new line so that we don't create a 'hanging' indent
+  // if there are multiple blocks in a single statement and we are aligning
+  // lambda blocks to their signatures.
   if (Previous.is(tok::l_brace) && State.Stack.size() > 1 &&
       State.Stack[State.Stack.size() - 2].NestedBlockInlined &&
       State.Stack[State.Stack.size() - 2].HasMultipleNestedBlocks) {
-    return Style.isCpp() &&
-           Style.LambdaBodyIndentation == FormatStyle::LBI_OuterScope;
+    if (!Style.isCpp())
+      return false;
+
+    if (Style.LambdaBodyIndentation == FormatStyle::LBI_OuterScope)
+      return true;
+
+    // Make sure to push lambdas to a new line when they are an argument with
+    // other arguments preceding them.
+    if (State.Stack[State.Stack.size() - 2].StartOfFunctionCall > 0)
+      return false;
+
+    // Only force a new line if it is not just going to create a worse hanging
+    // indent. Otherwise, based on the ContinuationIndentWidth, we could end up
+    // more indented than we would've been. To avoid odd looking breaks, make
+    // sure we save at least IndentWidth.
+    if (State.Stack.size() > 2 &&
+        State.Stack[State.Stack.size() - 3].Indent +
+                Style.ContinuationIndentWidth + Style.IndentWidth <
+            State.Stack[State.Stack.size() - 2].Indent) {
+      return false;
+    }
+
+    return true;
   }
 
   // Don't break after very short return types (e.g. "void") as that is often
diff --git a/clang/unittests/Format/FormatTest.cpp 
b/clang/unittests/Format/FormatTest.cpp
index c0633ba3c29b3..7f7ae55a92d31 100644
--- a/clang/unittests/Format/FormatTest.cpp
+++ b/clang/unittests/Format/FormatTest.cpp
@@ -23813,6 +23813,17 @@ TEST_F(FormatTest, FormatsLambdas) {
                "          }};\n"
                "}",
                LLVMWithBeforeLambdaBody);
+  verifyFormat("if ([]()\n"
+               "    {\n"
+               "      return true;\n"
+               "    }()) {\n"
+               "}",
+               LLVMWithBeforeLambdaBody);
+  verifyFormat("fun([]()\n"
+               "    {\n"
+               "      return 17;\n"
+               "    });",
+               LLVMWithBeforeLambdaBody);
 
   LLVMWithBeforeLambdaBody.AllowShortLambdasOnASingleLine =
       FormatStyle::ShortLambdaStyle::SLS_Empty;

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

Reply via email to