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