https://github.com/urnathan updated https://github.com/llvm/llvm-project/pull/102078
>From 193e704ea21251ea639bfb733671b4047c93c4ea Mon Sep 17 00:00:00 2001 From: Nathan Sidwell <nat...@acm.org> Date: Sun, 4 Aug 2024 19:15:20 -0400 Subject: [PATCH 1/2] [clang-format] Adjust requires clause wrapping (#101550) Adjust line wrapping after a requires clause to permit a following '{' on the same line with OwnLine and WithPreceeding RequiresClausePositioning. Thus, instead of: ``` bool Foo () requires(true) { return true; } ``` we have: ``` bool Foo () requires(true) { return true; } ``` If the function body is empty, we'll get: ``` bool Foo () requires(true) {} ``` I attempted to get a line break between the open and close braces, but failed. Perhaps that's fine -- it's rare and only happens in the empty body case. --- clang/lib/Format/TokenAnnotator.cpp | 3 +- clang/unittests/Format/FormatTest.cpp | 53 +++++++++------------------ 2 files changed, 19 insertions(+), 37 deletions(-) diff --git a/clang/lib/Format/TokenAnnotator.cpp b/clang/lib/Format/TokenAnnotator.cpp index 4ed3e9d0e8e855..04ac0e2b90c609 100644 --- a/clang/lib/Format/TokenAnnotator.cpp +++ b/clang/lib/Format/TokenAnnotator.cpp @@ -5682,7 +5682,8 @@ bool TokenAnnotator::mustBreakBefore(const AnnotatedLine &Line, (Style.BreakTemplateDeclarations == FormatStyle::BTDS_Leave && Right.NewlinesBefore > 0); } - if (Left.ClosesRequiresClause && Right.isNot(tok::semi)) { + if (Left.ClosesRequiresClause && Right.isNot(tok::semi) && + Right.isNot(tok::l_brace)) { switch (Style.RequiresClausePosition) { case FormatStyle::RCPS_OwnLine: case FormatStyle::RCPS_WithPreceding: diff --git a/clang/unittests/Format/FormatTest.cpp b/clang/unittests/Format/FormatTest.cpp index 2a754a29e81e73..792c1971dae499 100644 --- a/clang/unittests/Format/FormatTest.cpp +++ b/clang/unittests/Format/FormatTest.cpp @@ -4325,8 +4325,7 @@ TEST_F(FormatTest, FormatsNamespaces) { Style); verifyFormat("template <int I>\n" "constexpr void foo()\n" - " requires(I == 42)\n" - "{}\n" + " requires(I == 42) {}\n" "namespace ns {\n" "void foo() {}\n" "} // namespace ns", @@ -17041,12 +17040,10 @@ TEST_F(FormatTest, ConfigurableSpaceBeforeParens) { EXPECT_FALSE( SpaceAfterRequires.SpaceBeforeParensOptions.AfterRequiresInExpression); verifyFormat("void f(auto x)\n" - " requires requires(int i) { x + i; }\n" - "{}", + " requires requires(int i) { x + i; } {}", SpaceAfterRequires); verifyFormat("void f(auto x)\n" - " requires(requires(int i) { x + i; })\n" - "{}", + " requires(requires(int i) { x + i; }) {}", SpaceAfterRequires); verifyFormat("if (requires(int i) { x + i; })\n" " return;", @@ -17059,12 +17056,10 @@ TEST_F(FormatTest, ConfigurableSpaceBeforeParens) { SpaceAfterRequires.SpaceBeforeParensOptions.AfterRequiresInClause = true; verifyFormat("void f(auto x)\n" - " requires requires(int i) { x + i; }\n" - "{}", + " requires requires(int i) { x + i; } {}", SpaceAfterRequires); verifyFormat("void f(auto x)\n" - " requires (requires(int i) { x + i; })\n" - "{}", + " requires (requires(int i) { x + i; }) {}", SpaceAfterRequires); verifyFormat("if (requires(int i) { x + i; })\n" " return;", @@ -17078,12 +17073,10 @@ TEST_F(FormatTest, ConfigurableSpaceBeforeParens) { SpaceAfterRequires.SpaceBeforeParensOptions.AfterRequiresInClause = false; SpaceAfterRequires.SpaceBeforeParensOptions.AfterRequiresInExpression = true; verifyFormat("void f(auto x)\n" - " requires requires (int i) { x + i; }\n" - "{}", + " requires requires (int i) { x + i; } {}", SpaceAfterRequires); verifyFormat("void f(auto x)\n" - " requires(requires (int i) { x + i; })\n" - "{}", + " requires(requires (int i) { x + i; }) {}", SpaceAfterRequires); verifyFormat("if (requires (int i) { x + i; })\n" " return;", @@ -17096,12 +17089,10 @@ TEST_F(FormatTest, ConfigurableSpaceBeforeParens) { SpaceAfterRequires.SpaceBeforeParensOptions.AfterRequiresInClause = true; verifyFormat("void f(auto x)\n" - " requires requires (int i) { x + i; }\n" - "{}", + " requires requires (int i) { x + i; } {}", SpaceAfterRequires); verifyFormat("void f(auto x)\n" - " requires (requires (int i) { x + i; })\n" - "{}", + " requires (requires (int i) { x + i; }) {}", SpaceAfterRequires); verifyFormat("if (requires (int i) { x + i; })\n" " return;", @@ -25799,8 +25790,7 @@ TEST_F(FormatTest, RequiresClausesPositions) { " requires Foo<T> && requires(T t) {\n" " { t.baz() } -> std::same_as<bool>;\n" " requires std::same_as<T::Factor, int>;\n" - " }\n" - "{\n" + " } {\n" " return t.baz() ? T::Factor : 5;\n" "}", Style); @@ -25814,16 +25804,14 @@ TEST_F(FormatTest, RequiresClausesPositions) { verifyFormat("template <typename T>\n" "int bar(T t)\n" - " requires F<T>\n" - "{\n" + " requires F<T> {\n" " return 5;\n" "}", Style); verifyFormat("template <typename T>\n" "int S::bar(T t) &&\n" - " requires F<T>\n" - "{\n" + " requires F<T> {\n" " return 5;\n" "}", Style); @@ -25843,16 +25831,14 @@ TEST_F(FormatTest, RequiresClausesPositions) { verifyFormat("template <typename T>\n" "int S::bar(T t) &&\n" - "requires F<T>\n" - "{\n" + "requires F<T> {\n" " return 5;\n" "}", Style); verifyFormat("template <typename T>\n" "int bar(T t)\n" - "requires F<T>\n" - "{\n" + "requires F<T> {\n" " return 5;\n" "}", Style); @@ -25982,13 +25968,9 @@ TEST_F(FormatTest, RequiresClausesPositions) { "struct Bar {};\n" "template <typename T> requires Foo<T>\n" "void bar() {}\n" - "template <typename T>\n" - "void bar() requires Foo<T>\n" - "{}\n" + "template <typename T> void bar() requires Foo<T> {}\n" "template <typename T> void bar() requires Foo<T>;\n" - "template <typename T>\n" - "void S::bar() && requires Foo<T>\n" - "{}\n" + "template <typename T> void S::bar() && requires Foo<T> {}\n" "template <typename T> requires Foo<T>\n" "Bar(T) -> Bar<T>;", Style); @@ -26001,8 +25983,7 @@ TEST_F(FormatTest, RequiresClausesPositions) { "void bar() {}\n" "template <typename AAAAAAA>\n" "void bar()\n" - " requires Foo<AAAAAAAAAAAAAAAA>\n" - "{}\n" + " requires Foo<AAAAAAAAAAAAAAAA> {}\n" "template <typename AAAAAAA>\n" "requires Foo<AAAAAAAA>\n" "Bar(T) -> Bar<T>;\n" >From 1fcb1f95d18803b980dda372c8da0b6b79b0fe1d Mon Sep 17 00:00:00 2001 From: Nathan Sidwell <nat...@acm.org> Date: Thu, 8 Aug 2024 17:04:47 -0400 Subject: [PATCH 2/2] [clang-format] Add OwnLineWithBrace requires clause style --- clang/docs/ClangFormatStyleOptions.rst | 33 ++++- clang/include/clang/Format/Format.h | 31 ++++- clang/lib/Format/ContinuationIndenter.cpp | 1 + clang/lib/Format/Format.cpp | 1 + clang/lib/Format/TokenAnnotator.cpp | 8 +- clang/unittests/Format/FormatTest.cpp | 140 +++++++++++++++++++--- 6 files changed, 187 insertions(+), 27 deletions(-) diff --git a/clang/docs/ClangFormatStyleOptions.rst b/clang/docs/ClangFormatStyleOptions.rst index 6c2e6da5948478..5e7a55f24a1e78 100644 --- a/clang/docs/ClangFormatStyleOptions.rst +++ b/clang/docs/ClangFormatStyleOptions.rst @@ -5379,23 +5379,48 @@ the configuration (without a prefix: ``Auto``). Possible values: * ``RCPS_OwnLine`` (in configuration: ``OwnLine``) - Always put the ``requires`` clause on its own line. + Always put the ``requires`` clause on its own line (possibly followed by + a semicolon). .. code-block:: c++ template <typename T> - requires C<T> + requires C<T> struct Foo {... template <typename T> - requires C<T> + void bar(T t) + requires C<T>; + + template <typename T> + requires C<T> void bar(T t) {... template <typename T> void baz(T t) - requires C<T> + requires C<T> {... + * ``RCPS_OwnLineWithBrace`` (in configuration: ``OwnLineWithBrace``) + As with ``OwnLine``, except, unless otherwise prohibited, place a + following open brace (of a function definition) to follow on the same + line. + + .. code-block:: c++ + + void bar(T t) + requires C<T> { + return; + } + + void bar(T t) + requires C<T> {} + + template <typename T> + requires C<T> + void baz(T t) { + ... + * ``RCPS_WithPreceding`` (in configuration: ``WithPreceding``) Try to put the clause together with the preceding part of a declaration. For class templates: stick to the template declaration. diff --git a/clang/include/clang/Format/Format.h b/clang/include/clang/Format/Format.h index c454ab2bc0ce29..1000cb5a8daeda 100644 --- a/clang/include/clang/Format/Format.h +++ b/clang/include/clang/Format/Format.h @@ -3909,22 +3909,45 @@ struct FormatStyle { /// ``IndentRequires`` option is only used if the ``requires`` is put on the /// start of a line. enum RequiresClausePositionStyle : int8_t { - /// Always put the ``requires`` clause on its own line. + /// Always put the ``requires`` clause on its own line (possibly followed by + /// a semicolon). /// \code /// template <typename T> - /// requires C<T> + /// requires C<T> /// struct Foo {... /// /// template <typename T> - /// requires C<T> + /// void bar(T t) + /// requires C<T>; + /// + /// template <typename T> + /// requires C<T> /// void bar(T t) {... /// /// template <typename T> /// void baz(T t) - /// requires C<T> + /// requires C<T> /// {... /// \endcode RCPS_OwnLine, + /// As with ``OwnLine``, except, unless otherwise prohibited, place a + /// following open brace (of a function definition) to follow on the same + /// line. + /// \code + /// void bar(T t) + /// requires C<T> { + /// return; + /// } + /// + /// void bar(T t) + /// requires C<T> {} + /// + /// template <typename T> + /// requires C<T> + /// void baz(T t) { + /// ... + /// \endcode + RCPS_OwnLineWithBrace, /// Try to put the clause together with the preceding part of a declaration. /// For class templates: stick to the template declaration. /// For function templates: stick to the template declaration. diff --git a/clang/lib/Format/ContinuationIndenter.cpp b/clang/lib/Format/ContinuationIndenter.cpp index df86a774ba0f4f..21adcc890d67f7 100644 --- a/clang/lib/Format/ContinuationIndenter.cpp +++ b/clang/lib/Format/ContinuationIndenter.cpp @@ -1395,6 +1395,7 @@ unsigned ContinuationIndenter::getNewLineColumn(const LineState &State) { switch (Style.RequiresClausePosition) { case FormatStyle::RCPS_OwnLine: case FormatStyle::RCPS_WithFollowing: + case FormatStyle::RCPS_OwnLineWithBrace: return CurrentState.Indent; default: break; diff --git a/clang/lib/Format/Format.cpp b/clang/lib/Format/Format.cpp index 7fd42e46e0ccb7..4c82a4f1109525 100644 --- a/clang/lib/Format/Format.cpp +++ b/clang/lib/Format/Format.cpp @@ -530,6 +530,7 @@ struct ScalarEnumerationTraits<FormatStyle::RequiresClausePositionStyle> { static void enumeration(IO &IO, FormatStyle::RequiresClausePositionStyle &Value) { IO.enumCase(Value, "OwnLine", FormatStyle::RCPS_OwnLine); + IO.enumCase(Value, "OwnLineWithBrace", FormatStyle::RCPS_OwnLineWithBrace); IO.enumCase(Value, "WithPreceding", FormatStyle::RCPS_WithPreceding); IO.enumCase(Value, "WithFollowing", FormatStyle::RCPS_WithFollowing); IO.enumCase(Value, "SingleLine", FormatStyle::RCPS_SingleLine); diff --git a/clang/lib/Format/TokenAnnotator.cpp b/clang/lib/Format/TokenAnnotator.cpp index 04ac0e2b90c609..fb8476401afea0 100644 --- a/clang/lib/Format/TokenAnnotator.cpp +++ b/clang/lib/Format/TokenAnnotator.cpp @@ -5664,6 +5664,7 @@ bool TokenAnnotator::mustBreakBefore(const AnnotatedLine &Line, if (Right.is(TT_RequiresClause)) { switch (Style.RequiresClausePosition) { case FormatStyle::RCPS_OwnLine: + case FormatStyle::RCPS_OwnLineWithBrace: case FormatStyle::RCPS_WithFollowing: return true; default: @@ -5682,12 +5683,15 @@ bool TokenAnnotator::mustBreakBefore(const AnnotatedLine &Line, (Style.BreakTemplateDeclarations == FormatStyle::BTDS_Leave && Right.NewlinesBefore > 0); } - if (Left.ClosesRequiresClause && Right.isNot(tok::semi) && - Right.isNot(tok::l_brace)) { + if (Left.ClosesRequiresClause && Right.isNot(tok::semi)) { switch (Style.RequiresClausePosition) { case FormatStyle::RCPS_OwnLine: case FormatStyle::RCPS_WithPreceding: return true; + case FormatStyle::RCPS_OwnLineWithBrace: + if (Right.isNot(tok::l_brace)) + return true; + break; default: break; } diff --git a/clang/unittests/Format/FormatTest.cpp b/clang/unittests/Format/FormatTest.cpp index 792c1971dae499..b80c419e6c0f8c 100644 --- a/clang/unittests/Format/FormatTest.cpp +++ b/clang/unittests/Format/FormatTest.cpp @@ -4325,7 +4325,8 @@ TEST_F(FormatTest, FormatsNamespaces) { Style); verifyFormat("template <int I>\n" "constexpr void foo()\n" - " requires(I == 42) {}\n" + " requires(I == 42)\n" + "{}\n" "namespace ns {\n" "void foo() {}\n" "} // namespace ns", @@ -17040,10 +17041,12 @@ TEST_F(FormatTest, ConfigurableSpaceBeforeParens) { EXPECT_FALSE( SpaceAfterRequires.SpaceBeforeParensOptions.AfterRequiresInExpression); verifyFormat("void f(auto x)\n" - " requires requires(int i) { x + i; } {}", + " requires requires(int i) { x + i; }\n" + "{}", SpaceAfterRequires); verifyFormat("void f(auto x)\n" - " requires(requires(int i) { x + i; }) {}", + " requires(requires(int i) { x + i; })\n" + "{}", SpaceAfterRequires); verifyFormat("if (requires(int i) { x + i; })\n" " return;", @@ -17056,10 +17059,12 @@ TEST_F(FormatTest, ConfigurableSpaceBeforeParens) { SpaceAfterRequires.SpaceBeforeParensOptions.AfterRequiresInClause = true; verifyFormat("void f(auto x)\n" - " requires requires(int i) { x + i; } {}", + " requires requires(int i) { x + i; }\n" + "{}", SpaceAfterRequires); verifyFormat("void f(auto x)\n" - " requires (requires(int i) { x + i; }) {}", + " requires (requires(int i) { x + i; })\n" + "{}", SpaceAfterRequires); verifyFormat("if (requires(int i) { x + i; })\n" " return;", @@ -17073,10 +17078,12 @@ TEST_F(FormatTest, ConfigurableSpaceBeforeParens) { SpaceAfterRequires.SpaceBeforeParensOptions.AfterRequiresInClause = false; SpaceAfterRequires.SpaceBeforeParensOptions.AfterRequiresInExpression = true; verifyFormat("void f(auto x)\n" - " requires requires (int i) { x + i; } {}", + " requires requires (int i) { x + i; }\n" + "{}", SpaceAfterRequires); verifyFormat("void f(auto x)\n" - " requires(requires (int i) { x + i; }) {}", + " requires(requires (int i) { x + i; })\n" + "{}", SpaceAfterRequires); verifyFormat("if (requires (int i) { x + i; })\n" " return;", @@ -17089,10 +17096,12 @@ TEST_F(FormatTest, ConfigurableSpaceBeforeParens) { SpaceAfterRequires.SpaceBeforeParensOptions.AfterRequiresInClause = true; verifyFormat("void f(auto x)\n" - " requires requires (int i) { x + i; } {}", + " requires requires (int i) { x + i; }\n" + "{}", SpaceAfterRequires); verifyFormat("void f(auto x)\n" - " requires (requires (int i) { x + i; }) {}", + " requires (requires (int i) { x + i; })\n" + "{}", SpaceAfterRequires); verifyFormat("if (requires (int i) { x + i; })\n" " return;", @@ -25790,7 +25799,8 @@ TEST_F(FormatTest, RequiresClausesPositions) { " requires Foo<T> && requires(T t) {\n" " { t.baz() } -> std::same_as<bool>;\n" " requires std::same_as<T::Factor, int>;\n" - " } {\n" + " }\n" + "{\n" " return t.baz() ? T::Factor : 5;\n" "}", Style); @@ -25804,14 +25814,16 @@ TEST_F(FormatTest, RequiresClausesPositions) { verifyFormat("template <typename T>\n" "int bar(T t)\n" - " requires F<T> {\n" + " requires F<T>\n" + "{\n" " return 5;\n" "}", Style); verifyFormat("template <typename T>\n" "int S::bar(T t) &&\n" - " requires F<T> {\n" + " requires F<T>\n" + "{\n" " return 5;\n" "}", Style); @@ -25831,19 +25843,108 @@ TEST_F(FormatTest, RequiresClausesPositions) { verifyFormat("template <typename T>\n" "int S::bar(T t) &&\n" - "requires F<T> {\n" + "requires F<T>\n" + "{\n" " return 5;\n" "}", Style); verifyFormat("template <typename T>\n" "int bar(T t)\n" - "requires F<T> {\n" + "requires F<T>\n" + "{\n" " return 5;\n" "}", Style); + Style.RequiresClausePosition = FormatStyle::RCPS_OwnLineWithBrace; + Style.IndentRequiresClause = true; + + // The default in LLVM style is REI_OuterScope, but these tests were written + // when the default was REI_Keyword. + Style.RequiresExpressionIndentation = FormatStyle::REI_Keyword; + + verifyFormat("template <typename T>\n" + " requires(Foo<T> && std::trait<T>)\n" + "struct Bar;", + Style); + + verifyFormat("template <typename T>\n" + " requires(Foo<T> && std::trait<T>)\n" + "class Bar {\n" + "public:\n" + " Bar(T t);\n" + " bool baz();\n" + "};", + Style); + + verifyFormat( + "template <typename T>\n" + " requires requires(T &&t) {\n" + " typename T::I;\n" + " requires(F<typename T::I> && std::trait<typename T::I>);\n" + " }\n" + "Bar(T) -> Bar<typename T::I>;", + Style); + + verifyFormat("template <typename T>\n" + " requires(Foo<T> && std::trait<T>)\n" + "constexpr T MyGlobal;", + Style); + + verifyFormat("template <typename T>\n" + " requires Foo<T> && requires(T t) {\n" + " { t.baz() } -> std::same_as<bool>;\n" + " requires std::same_as<T::Factor, int>;\n" + " }\n" + "inline int bar(T t) {\n" + " return t.baz() ? T::Factor : 5;\n" + "}", + Style); + + verifyFormat("template <typename T>\n" + "inline int bar(T t)\n" + " requires Foo<T> && requires(T t) {\n" + " { t.baz() } -> std::same_as<bool>;\n" + " requires std::same_as<T::Factor, int>;\n" + " } {\n" + " return t.baz() ? T::Factor : 5;\n" + "}", + Style); + + verifyFormat("template <typename T>\n" + " requires F<T>\n" + "int bar(T t) {\n" + " return 5;\n" + "}", + Style); + + verifyFormat("template <typename T>\n" + "int bar(T t)\n" + " requires F<T> {\n" + " return 5;\n" + "}", + Style); + + verifyFormat("template <typename T>\n" + "int S::bar(T t) &&\n" + " requires F<T> {\n" + " return 5;\n" + "}", + Style); + + verifyFormat("template <typename T>\n" + "int bar(T t)\n" + " requires F<T>;", + Style); + + verifyFormat("template <typename T>\n" + "int bar(T t)\n" + " requires F<T> {}", + Style); + Style.RequiresClausePosition = FormatStyle::RCPS_SingleLine; + Style.IndentRequiresClause = false; verifyFormat("template <typename T> requires Foo<T> struct Bar {};\n" "template <typename T> requires Foo<T> void bar() {}\n" "template <typename T> void bar() requires Foo<T> {}\n" @@ -25968,9 +26069,13 @@ TEST_F(FormatTest, RequiresClausesPositions) { "struct Bar {};\n" "template <typename T> requires Foo<T>\n" "void bar() {}\n" - "template <typename T> void bar() requires Foo<T> {}\n" + "template <typename T>\n" + "void bar() requires Foo<T>\n" + "{}\n" "template <typename T> void bar() requires Foo<T>;\n" - "template <typename T> void S::bar() && requires Foo<T> {}\n" + "template <typename T>\n" + "void S::bar() && requires Foo<T>\n" + "{}\n" "template <typename T> requires Foo<T>\n" "Bar(T) -> Bar<T>;", Style); @@ -25983,7 +26088,8 @@ TEST_F(FormatTest, RequiresClausesPositions) { "void bar() {}\n" "template <typename AAAAAAA>\n" "void bar()\n" - " requires Foo<AAAAAAAAAAAAAAAA> {}\n" + " requires Foo<AAAAAAAAAAAAAAAA>\n" + "{}\n" "template <typename AAAAAAA>\n" "requires Foo<AAAAAAAA>\n" "Bar(T) -> Bar<T>;\n" _______________________________________________ cfe-commits mailing list cfe-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits