[clang] b786a4a - [clang-format] Extend SpaceBeforeParens for requires
Björn Schäpers via cfe-commits
cfe-commits at lists.llvm.org
Tue Feb 15 12:38:29 PST 2022
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) {
More information about the cfe-commits
mailing list