Author: Björn Schäpers Date: 2022-02-15T21:37:36+01:00 New Revision: b786a4aefedaf68eb7710d9c01a18ad1d0c820b7
URL: https://github.com/llvm/llvm-project/commit/b786a4aefedaf68eb7710d9c01a18ad1d0c820b7 DIFF: https://github.com/llvm/llvm-project/commit/b786a4aefedaf68eb7710d9c01a18ad1d0c820b7.diff LOG: [clang-format] Extend SpaceBeforeParens for requires We can now configure the space between requires and the following paren, seperate for clauses and expressions. Differential Revision: https://reviews.llvm.org/D113369 Added: Modified: clang/docs/ClangFormatStyleOptions.rst clang/include/clang/Format/Format.h clang/lib/Format/Format.cpp clang/lib/Format/TokenAnnotator.cpp clang/unittests/Format/FormatTest.cpp Removed: ################################################################################ diff --git a/clang/docs/ClangFormatStyleOptions.rst b/clang/docs/ClangFormatStyleOptions.rst index e89523d0e5676..8d6c80fb87e5a 100644 --- a/clang/docs/ClangFormatStyleOptions.rst +++ b/clang/docs/ClangFormatStyleOptions.rst @@ -4004,6 +4004,27 @@ the configuration (without a prefix: ``Auto``). void operator++ (int a); vs. void operator++(int a); object.operator++ (10); object.operator++(10); + * ``bool AfterRequiresInClause`` If ``true``, put space between requires keyword in a requires clause and + opening parentheses, if there is one. + + .. code-block:: c++ + + true: false: + template<typename T> vs. template<typename T> + requires (A<T> && B<T>) requires(A<T> && B<T>) + ... ... + + * ``bool AfterRequiresInExpression`` If ``true``, put space between requires keyword in a requires expression + and opening parentheses. + + .. code-block:: c++ + + true: false: + template<typename T> vs. template<typename T> + concept C = requires (T t) { concept C = requires(T t) { + ... ... + } } + * ``bool BeforeNonEmptyParentheses`` If ``true``, put a space before opening parentheses only if the parentheses are not empty. diff --git a/clang/include/clang/Format/Format.h b/clang/include/clang/Format/Format.h index 9d6df403230da..c86a700097160 100644 --- a/clang/include/clang/Format/Format.h +++ b/clang/include/clang/Format/Format.h @@ -3594,6 +3594,25 @@ struct FormatStyle { /// object.operator++ (10); object.operator++(10); /// \endcode bool AfterOverloadedOperator; + /// If ``true``, put space between requires keyword in a requires clause and + /// opening parentheses, if there is one. + /// \code + /// true: false: + /// template<typename T> vs. template<typename T> + /// requires (A<T> && B<T>) requires(A<T> && B<T>) + /// ... ... + /// \endcode + bool AfterRequiresInClause; + /// If ``true``, put space between requires keyword in a requires expression + /// and opening parentheses. + /// \code + /// true: false: + /// template<typename T> vs. template<typename T> + /// concept C = requires (T t) { concept C = requires(T t) { + /// ... ... + /// } } + /// \endcode + bool AfterRequiresInExpression; /// If ``true``, put a space before opening parentheses only if the /// parentheses are not empty. /// \code @@ -3607,7 +3626,8 @@ struct FormatStyle { : AfterControlStatements(false), AfterForeachMacros(false), AfterFunctionDeclarationName(false), AfterFunctionDefinitionName(false), AfterIfMacros(false), - AfterOverloadedOperator(false), BeforeNonEmptyParentheses(false) {} + AfterOverloadedOperator(false), AfterRequiresInClause(false), + AfterRequiresInExpression(false), BeforeNonEmptyParentheses(false) {} bool operator==(const SpaceBeforeParensCustom &Other) const { return AfterControlStatements == Other.AfterControlStatements && @@ -3617,6 +3637,8 @@ struct FormatStyle { AfterFunctionDefinitionName == Other.AfterFunctionDefinitionName && AfterIfMacros == Other.AfterIfMacros && AfterOverloadedOperator == Other.AfterOverloadedOperator && + AfterRequiresInClause == Other.AfterRequiresInClause && + AfterRequiresInExpression == Other.AfterRequiresInExpression && BeforeNonEmptyParentheses == Other.BeforeNonEmptyParentheses; } }; diff --git a/clang/lib/Format/Format.cpp b/clang/lib/Format/Format.cpp index 8aa12867c35f1..6acd850cac2cb 100644 --- a/clang/lib/Format/Format.cpp +++ b/clang/lib/Format/Format.cpp @@ -898,6 +898,9 @@ template <> struct MappingTraits<FormatStyle::SpaceBeforeParensCustom> { Spacing.AfterFunctionDeclarationName); IO.mapOptional("AfterIfMacros", Spacing.AfterIfMacros); IO.mapOptional("AfterOverloadedOperator", Spacing.AfterOverloadedOperator); + IO.mapOptional("AfterRequiresInClause", Spacing.AfterRequiresInClause); + IO.mapOptional("AfterRequiresInExpression", + Spacing.AfterRequiresInExpression); IO.mapOptional("BeforeNonEmptyParentheses", Spacing.BeforeNonEmptyParentheses); } @@ -1259,6 +1262,7 @@ FormatStyle getLLVMStyle(FormatStyle::LanguageKind Language) { LLVMStyle.SpaceBeforeCtorInitializerColon = true; LLVMStyle.SpaceBeforeInheritanceColon = true; LLVMStyle.SpaceBeforeParens = FormatStyle::SBPO_ControlStatements; + LLVMStyle.SpaceBeforeParensOptions = {}; LLVMStyle.SpaceBeforeParensOptions.AfterControlStatements = true; LLVMStyle.SpaceBeforeParensOptions.AfterForeachMacros = true; LLVMStyle.SpaceBeforeParensOptions.AfterIfMacros = true; diff --git a/clang/lib/Format/TokenAnnotator.cpp b/clang/lib/Format/TokenAnnotator.cpp index a2985eb75a195..cb5baae565321 100644 --- a/clang/lib/Format/TokenAnnotator.cpp +++ b/clang/lib/Format/TokenAnnotator.cpp @@ -3247,8 +3247,12 @@ bool TokenAnnotator::spaceRequiredBetween(const AnnotatedLine &Line, if (Right.is(tok::l_paren)) { if (Left.is(TT_TemplateCloser) && Right.isNot(TT_FunctionTypeLParen)) return spaceRequiredBeforeParens(Right); - if (Left.is(tok::kw_requires)) - return spaceRequiredBeforeParens(Right); + if (Left.isOneOf(TT_RequiresClause, TT_RequiresClauseInARequiresExpression)) + return Style.SpaceBeforeParensOptions.AfterRequiresInClause || + spaceRequiredBeforeParens(Right); + if (Left.is(TT_RequiresExpression)) + return Style.SpaceBeforeParensOptions.AfterRequiresInExpression || + spaceRequiredBeforeParens(Right); if ((Left.is(tok::r_paren) && Left.is(TT_AttributeParen)) || (Left.is(tok::r_square) && Left.is(TT_AttributeSquare))) return true; diff --git a/clang/unittests/Format/FormatTest.cpp b/clang/unittests/Format/FormatTest.cpp index 1b99b53bbee55..268fe16350b6b 100644 --- a/clang/unittests/Format/FormatTest.cpp +++ b/clang/unittests/Format/FormatTest.cpp @@ -15012,6 +15012,84 @@ TEST_F(FormatTest, ConfigurableSpaceBeforeParens) { verifyFormat("X A::operator++();", SpaceAfterOverloadedOperator); verifyFormat("some_object.operator++();", SpaceAfterOverloadedOperator); verifyFormat("auto func() -> int;", SpaceAfterOverloadedOperator); + + auto SpaceAfterRequires = getLLVMStyle(); + SpaceAfterRequires.SpaceBeforeParens = FormatStyle::SBPO_Custom; + EXPECT_FALSE( + SpaceAfterRequires.SpaceBeforeParensOptions.AfterRequiresInClause); + EXPECT_FALSE( + SpaceAfterRequires.SpaceBeforeParensOptions.AfterRequiresInExpression); + verifyFormat("void f(auto x)\n" + " requires requires(int i) { x + i; }\n" + "{}", + SpaceAfterRequires); + verifyFormat("void f(auto x)\n" + " requires(requires(int i) { x + i; })\n" + "{}", + SpaceAfterRequires); + verifyFormat("if (requires(int i) { x + i; })\n" + " return;", + SpaceAfterRequires); + verifyFormat("bool b = requires(int i) { x + i; };", SpaceAfterRequires); + verifyFormat("template <typename T>\n" + " requires(Foo<T>)\n" + "class Bar;", + SpaceAfterRequires); + + SpaceAfterRequires.SpaceBeforeParensOptions.AfterRequiresInClause = true; + verifyFormat("void f(auto x)\n" + " requires requires(int i) { x + i; }\n" + "{}", + SpaceAfterRequires); + verifyFormat("void f(auto x)\n" + " requires (requires(int i) { x + i; })\n" + "{}", + SpaceAfterRequires); + verifyFormat("if (requires(int i) { x + i; })\n" + " return;", + SpaceAfterRequires); + verifyFormat("bool b = requires(int i) { x + i; };", SpaceAfterRequires); + verifyFormat("template <typename T>\n" + " requires (Foo<T>)\n" + "class Bar;", + SpaceAfterRequires); + + SpaceAfterRequires.SpaceBeforeParensOptions.AfterRequiresInClause = false; + SpaceAfterRequires.SpaceBeforeParensOptions.AfterRequiresInExpression = true; + verifyFormat("void f(auto x)\n" + " requires requires (int i) { x + i; }\n" + "{}", + SpaceAfterRequires); + verifyFormat("void f(auto x)\n" + " requires(requires (int i) { x + i; })\n" + "{}", + SpaceAfterRequires); + verifyFormat("if (requires (int i) { x + i; })\n" + " return;", + SpaceAfterRequires); + verifyFormat("bool b = requires (int i) { x + i; };", SpaceAfterRequires); + verifyFormat("template <typename T>\n" + " requires(Foo<T>)\n" + "class Bar;", + SpaceAfterRequires); + + SpaceAfterRequires.SpaceBeforeParensOptions.AfterRequiresInClause = true; + verifyFormat("void f(auto x)\n" + " requires requires (int i) { x + i; }\n" + "{}", + SpaceAfterRequires); + verifyFormat("void f(auto x)\n" + " requires (requires (int i) { x + i; })\n" + "{}", + SpaceAfterRequires); + verifyFormat("if (requires (int i) { x + i; })\n" + " return;", + SpaceAfterRequires); + verifyFormat("bool b = requires (int i) { x + i; };", SpaceAfterRequires); + verifyFormat("template <typename T>\n" + " requires (Foo<T>)\n" + "class Bar;", + SpaceAfterRequires); } TEST_F(FormatTest, SpaceAfterLogicalNot) { _______________________________________________ cfe-commits mailing list cfe-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits