rymiel updated this revision to Diff 463772. rymiel added a comment. Resolve nits:
- Re-sorted uses of the name RequiresExpressionIndentationKind - Updated version to be 16 - Add test for demonstrating indentation as subexpression - Reformatted Repository: rG LLVM Github Monorepo CHANGES SINCE LAST ACTION https://reviews.llvm.org/D129443/new/ https://reviews.llvm.org/D129443 Files: clang/docs/ClangFormatStyleOptions.rst clang/include/clang/Format/Format.h clang/lib/Format/ContinuationIndenter.cpp clang/lib/Format/Format.cpp clang/unittests/Format/FormatTest.cpp
Index: clang/unittests/Format/FormatTest.cpp =================================================================== --- clang/unittests/Format/FormatTest.cpp +++ clang/unittests/Format/FormatTest.cpp @@ -24984,6 +24984,123 @@ "bar(requires);"); } +TEST_F(FormatTest, RequiresExpressionIndentation) { + auto Style = getLLVMStyle(); + EXPECT_EQ(Style.RequiresExpressionIndentation, FormatStyle::REI_Keyword); + + verifyFormat("template <typename T>\n" + "concept C = requires(T t) {\n" + " typename T::value;\n" + " requires requires(typename T::value v) {\n" + " { t == v } -> std::same_as<bool>;\n" + " };\n" + " };", + Style); + + verifyFormat( + "template <typename T>\n" + "void bar(T)\n" + " requires Foo<T> && requires(T t) {\n" + " { t.foo() } -> std::same_as<int>;\n" + " } && requires(T t) {\n" + " { t.bar() } -> std::same_as<bool>;\n" + " --t;\n" + " };", + Style); + + verifyFormat("template <typename T>\n" + " requires Foo<T> &&\n" + " requires(T t) {\n" + " { t.foo() } -> std::same_as<int>;\n" + " } && requires(T t) {\n" + " { t.bar() } -> std::same_as<bool>;\n" + " --t;\n" + " }\n" + "void bar(T);", + Style); + + verifyFormat("template <typename T> void f() {\n" + " if constexpr (requires(T t) {\n" + " { t.bar() } -> std::same_as<bool>;\n" + " }) {\n" + " }\n" + "}", + Style); + + verifyFormat( + "template <typename T> void f() {\n" + " if constexpr (condition && requires(T t) {\n" + " { t.bar() } -> std::same_as<bool>;\n" + " }) {\n" + " }\n" + "}", + Style); + + verifyFormat("template <typename T> struct C {\n" + " void f()\n" + " requires requires(T t) {\n" + " { t.bar() } -> std::same_as<bool>;\n" + " };\n" + "};", + Style); + + Style.RequiresExpressionIndentation = FormatStyle::REI_OuterScope; + + verifyFormat("template <typename T>\n" + "concept C = requires(T t) {\n" + " typename T::value;\n" + " requires requires(typename T::value v) {\n" + " { t == v } -> std::same_as<bool>;\n" + " };\n" + "};", + Style); + + verifyFormat("template <typename T>\n" + "void bar(T)\n" + " requires Foo<T> && requires(T t) {\n" + " { t.foo() } -> std::same_as<int>;\n" + " } && requires(T t) {\n" + " { t.bar() } -> std::same_as<bool>;\n" + " --t;\n" + " };", + Style); + + verifyFormat("template <typename T>\n" + " requires Foo<T> &&\n" + " requires(T t) {\n" + " { t.foo() } -> std::same_as<int>;\n" + " } && requires(T t) {\n" + " { t.bar() } -> std::same_as<bool>;\n" + " --t;\n" + " }\n" + "void bar(T);", + Style); + + verifyFormat("template <typename T> void f() {\n" + " if constexpr (requires(T t) {\n" + " { t.bar() } -> std::same_as<bool>;\n" + " }) {\n" + " }\n" + "}", + Style); + + verifyFormat("template <typename T> void f() {\n" + " if constexpr (condition && requires(T t) {\n" + " { t.bar() } -> std::same_as<bool>;\n" + " }) {\n" + " }\n" + "}", + Style); + + verifyFormat("template <typename T> struct C {\n" + " void f()\n" + " requires requires(T t) {\n" + " { t.bar() } -> std::same_as<bool>;\n" + " };\n" + "};", + Style); +} + TEST_F(FormatTest, StatementAttributeLikeMacros) { FormatStyle Style = getLLVMStyle(); StringRef Source = "void Foo::slot() {\n" Index: clang/lib/Format/Format.cpp =================================================================== --- clang/lib/Format/Format.cpp +++ clang/lib/Format/Format.cpp @@ -99,6 +99,15 @@ } }; +template <> +struct ScalarEnumerationTraits<FormatStyle::RequiresExpressionIndentationKind> { + static void + enumeration(IO &IO, FormatStyle::RequiresExpressionIndentationKind &Value) { + IO.enumCase(Value, "Keyword", FormatStyle::REI_Keyword); + IO.enumCase(Value, "OuterScope", FormatStyle::REI_OuterScope); + } +}; + template <> struct ScalarEnumerationTraits<FormatStyle::UseTabStyle> { static void enumeration(IO &IO, FormatStyle::UseTabStyle &Value) { IO.enumCase(Value, "Never", FormatStyle::UT_Never); @@ -646,6 +655,8 @@ IO.mapOptional("AlignConsecutiveMacros", Style.AlignConsecutiveMacros); IO.mapOptional("AlignEscapedNewlines", Style.AlignEscapedNewlines); IO.mapOptional("AlignOperands", Style.AlignOperands); + IO.mapOptional("RequiresExpressionIndentation", + Style.RequiresExpressionIndentation); IO.mapOptional("AlignTrailingComments", Style.AlignTrailingComments); IO.mapOptional("AllowAllArgumentsOnNextLine", Style.AllowAllArgumentsOnNextLine); @@ -1289,6 +1300,7 @@ LLVMStyle.PointerAlignment = FormatStyle::PAS_Right; LLVMStyle.ReferenceAlignment = FormatStyle::RAS_Pointer; LLVMStyle.RequiresClausePosition = FormatStyle::RCPS_OwnLine; + LLVMStyle.RequiresExpressionIndentation = FormatStyle::REI_Keyword; LLVMStyle.SeparateDefinitionBlocks = FormatStyle::SDS_Leave; LLVMStyle.ShortNamespaceLines = 1; LLVMStyle.SpacesBeforeTrailingComments = 1; Index: clang/lib/Format/ContinuationIndenter.cpp =================================================================== --- clang/lib/Format/ContinuationIndenter.cpp +++ clang/lib/Format/ContinuationIndenter.cpp @@ -1403,8 +1403,10 @@ CurrentState.NestedBlockIndent = State.Column + Current.ColumnWidth + 1; if (Current.isOneOf(TT_LambdaLSquare, TT_LambdaArrow)) CurrentState.LastSpace = State.Column; - if (Current.is(TT_RequiresExpression)) + if (Current.is(TT_RequiresExpression) && + Style.RequiresExpressionIndentation == FormatStyle::REI_Keyword) { CurrentState.NestedBlockIndent = State.Column; + } // Insert scopes created by fake parenthesis. const FormatToken *Previous = Current.getPreviousNonComment(); Index: clang/include/clang/Format/Format.h =================================================================== --- clang/include/clang/Format/Format.h +++ clang/include/clang/Format/Format.h @@ -3136,6 +3136,32 @@ /// \version 15 RequiresClausePositionStyle RequiresClausePosition; + /// Indentation logic for requires expression bodies. + enum RequiresExpressionIndentationKind : int8_t { + /// Align requires expression body relative to the `requires` keyword. + /// This is the default. + /// \code + /// template <typename T> + /// concept C = requires(T t) { + /// ... + /// } + /// \endcode + REI_Keyword, + /// Align requires expression body relative to the indentation level of the + /// outer scope the requires expression resides in. + /// \code + /// template <typename T> + /// concept C = requires(T t) { + /// ... + /// } + /// \endcode + REI_OuterScope, + }; + + /// The indentation used for requires expression bodies. + /// \version 16 + RequiresExpressionIndentationKind RequiresExpressionIndentation; + /// \brief The style if definition blocks should be separated. enum SeparateDefinitionStyle : int8_t { /// Leave definition blocks as they are. @@ -3970,6 +3996,7 @@ ReferenceAlignment == R.ReferenceAlignment && RemoveBracesLLVM == R.RemoveBracesLLVM && RequiresClausePosition == R.RequiresClausePosition && + RequiresExpressionIndentation == R.RequiresExpressionIndentation && SeparateDefinitionBlocks == R.SeparateDefinitionBlocks && ShortNamespaceLines == R.ShortNamespaceLines && SortIncludes == R.SortIncludes && Index: clang/docs/ClangFormatStyleOptions.rst =================================================================== --- clang/docs/ClangFormatStyleOptions.rst +++ clang/docs/ClangFormatStyleOptions.rst @@ -3844,6 +3844,35 @@ +**RequiresExpressionIndentation** (``RequiresExpressionIndentationKind``) :versionbadge:`clang-format 16` + The indentation used for requires expression bodies. + + Possible values: + + * ``REI_Keyword`` (in configuration: ``Keyword``) + Align requires expression body relative to the `requires` keyword. + This is the default. + + .. code-block:: c++ + + template <typename T> + concept C = requires(T t) { + ... + } + + * ``REI_OuterScope`` (in configuration: ``OuterScope``) + Align requires expression body relative to the indentation level of the + outer scope the requires expression resides in. + + .. code-block:: c++ + + template <typename T> + concept C = requires(T t) { + ... + } + + + **SeparateDefinitionBlocks** (``SeparateDefinitionStyle``) :versionbadge:`clang-format 14` Specifies the use of empty lines to separate definition blocks, including classes, structs, enums, and functions.
_______________________________________________ cfe-commits mailing list cfe-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits