HazardyKnusperkeks updated this revision to Diff 385588.
HazardyKnusperkeks marked 2 inline comments as done.
HazardyKnusperkeks added a comment.
Addressed comments.
Repository:
rG LLVM Github Monorepo
CHANGES SINCE LAST ACTION
https://reviews.llvm.org/D113369/new/
https://reviews.llvm.org/D113369
Files:
clang/docs/ClangFormatStyleOptions.rst
clang/include/clang/Format/Format.h
clang/lib/Format/Format.cpp
clang/lib/Format/TokenAnnotator.cpp
clang/lib/Format/UnwrappedLineParser.cpp
clang/unittests/Format/FormatTest.cpp
Index: clang/unittests/Format/FormatTest.cpp
===================================================================
--- clang/unittests/Format/FormatTest.cpp
+++ clang/unittests/Format/FormatTest.cpp
@@ -14300,6 +14300,36 @@
verifyFormat("X A::operator++ (T);", SomeSpace2);
verifyFormat("int x = int (y);", SomeSpace2);
verifyFormat("auto lambda = []() { return 0; };", SomeSpace2);
+
+ auto SpaceAfterRequires = getLLVMStyle();
+ SpaceAfterRequires.SpaceBeforeParens = FormatStyle::SBPO_Custom;
+ SpaceAfterRequires.SpaceBeforeParensOptions.AfterRequiresClause = true;
+ SpaceAfterRequires.SpaceBeforeParensOptions.AfterRequiresExpression = true;
+ verifyFormat(
+ "template <typename T> void func(T) requires(trait<T> && trait<T>) {\n"
+ " typename T::size_type;\n"
+ " { t.size() } -> std::same_as<typename T::size_type>;\n"
+ "}\n"
+ "{}");
+ verifyFormat("template <typename T> void func(T) requires requires(T &&t) {\n"
+ " typename T::size_type;\n"
+ " { t.size() } -> std::same_as<typename T::size_type>;\n"
+ "}\n"
+ "{}");
+ verifyFormat(
+ "template <typename T> void func(T) requires (trait<T> && trait<T>) {\n"
+ " typename T::size_type;\n"
+ " { t.size() } -> std::same_as<typename T::size_type>;\n"
+ "}\n"
+ "{}",
+ SpaceAfterRequires);
+ verifyFormat(
+ "template <typename T> void func(T) requires requires (T &&t) {\n"
+ " typename T::size_type;\n"
+ " { t.size() } -> std::same_as<typename T::size_type>;\n"
+ "}\n"
+ "{}",
+ SpaceAfterRequires);
}
TEST_F(FormatTest, SpaceAfterLogicalNot) {
@@ -22565,6 +22595,21 @@
"}\n"
"{}",
Style);
+
+ Style.SpaceBeforeParens = FormatStyle::SBPO_Custom;
+ Style.SpaceBeforeParensOptions.AfterRequiresClause = true;
+ Style.SpaceBeforeParensOptions.AfterRequiresExpression = true;
+ verifyFormat("template <typename T>\n"
+ " requires (std::is_integral_v<T> && std::is_signed_v<T>)\n"
+ "void func(T) {}",
+ Style);
+ verifyFormat(
+ "template <typename T> void func(T) requires requires (T &&t) {\n"
+ " typename T::size_type;\n"
+ " { t.size() } -> std::same_as<typename T::size_type>;\n"
+ "}\n"
+ "{}",
+ Style);
}
TEST_F(FormatTest, StatementAttributeLikeMacros) {
Index: clang/lib/Format/UnwrappedLineParser.cpp
===================================================================
--- clang/lib/Format/UnwrappedLineParser.cpp
+++ clang/lib/Format/UnwrappedLineParser.cpp
@@ -2477,6 +2477,13 @@
void UnwrappedLineParser::parseConstraintExpression(
unsigned int OriginalLevel) {
// requires Id<T> && Id<T> || Id<T>
+
+ if (FormatTok->Tok.is(tok::kw_requires)) {
+ assert(FormatTok->Previous);
+ assert(FormatTok->Previous->is(TT_RequiresClause));
+ FormatTok->setType(TT_RequiresExpression);
+ }
+
while (
FormatTok->isOneOf(tok::identifier, tok::kw_requires, tok::coloncolon)) {
nextToken();
Index: clang/lib/Format/TokenAnnotator.cpp
===================================================================
--- clang/lib/Format/TokenAnnotator.cpp
+++ clang/lib/Format/TokenAnnotator.cpp
@@ -3137,8 +3137,16 @@
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.is(tok::kw_requires)) {
+ if (spaceRequiredBeforeParens(Right))
+ return true;
+ if (Left.is(TT_RequiresClause))
+ return Style.SpaceBeforeParensOptions.AfterRequiresClause;
+ else {
+ assert(Left.is(TT_RequiresExpression));
+ return Style.SpaceBeforeParensOptions.AfterRequiresExpression;
+ }
+ }
if ((Left.is(tok::r_paren) && Left.is(TT_AttributeParen)) ||
(Left.is(tok::r_square) && Left.is(TT_AttributeSquare)))
return true;
Index: clang/lib/Format/Format.cpp
===================================================================
--- clang/lib/Format/Format.cpp
+++ clang/lib/Format/Format.cpp
@@ -855,6 +855,8 @@
IO.mapOptional("AfterFunctionDeclarationName",
Spacing.AfterFunctionDeclarationName);
IO.mapOptional("AfterIfMacros", Spacing.AfterIfMacros);
+ IO.mapOptional("AfterRequiresClause", Spacing.AfterRequiresClause);
+ IO.mapOptional("AfterRequiresExpression", Spacing.AfterRequiresExpression);
IO.mapOptional("BeforeNonEmptyParentheses",
Spacing.BeforeNonEmptyParentheses);
}
@@ -1214,6 +1216,7 @@
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;
Index: clang/include/clang/Format/Format.h
===================================================================
--- clang/include/clang/Format/Format.h
+++ clang/include/clang/Format/Format.h
@@ -3367,6 +3367,25 @@
/// <conditional-body> <conditional-body>
/// \endcode
bool AfterIfMacros;
+ /// If ``true``, put space between requires keyword in a requires clause and
+ /// opening parentheses, if is are one.
+ /// \code
+ /// true: false:
+ /// template<typename T> vs. template<typename T>
+ /// requires (A<T> && B<T>) requires(A<T> && B<T>)
+ /// ... ...
+ /// \endcode
+ bool AfterRequiresClause;
+ /// If ``true``, put space between requires keyword in a requires expression
+ /// and opening parentheses.
+ /// \code
+ /// true: false:
+ /// template<typename T> vs. template<typename T>
+ /// requires (T t) { requires(T t) {
+ /// ... ...
+ /// } }
+ /// \endcode
+ bool AfterRequiresExpression;
/// If ``true``, put a space before opening parentheses only if the
/// parentheses are not empty.
/// \code
@@ -3380,6 +3399,7 @@
: AfterControlStatements(false), AfterForeachMacros(false),
AfterFunctionDeclarationName(false),
AfterFunctionDefinitionName(false), AfterIfMacros(false),
+ AfterRequiresClause(false), AfterRequiresExpression(false),
BeforeNonEmptyParentheses(false) {}
bool operator==(const SpaceBeforeParensCustom &Other) const {
@@ -3389,6 +3409,8 @@
Other.AfterFunctionDeclarationName &&
AfterFunctionDefinitionName == Other.AfterFunctionDefinitionName &&
AfterIfMacros == Other.AfterIfMacros &&
+ AfterRequiresClause == Other.AfterRequiresClause &&
+ AfterRequiresExpression == Other.AfterRequiresExpression &&
BeforeNonEmptyParentheses == Other.BeforeNonEmptyParentheses;
}
};
Index: clang/docs/ClangFormatStyleOptions.rst
===================================================================
--- clang/docs/ClangFormatStyleOptions.rst
+++ clang/docs/ClangFormatStyleOptions.rst
@@ -3752,6 +3752,27 @@
IF (...) vs. IF(...)
<conditional-body> <conditional-body>
+ * ``bool AfterRequiresClause`` If ``true``, put space between requires keyword in a requires clause and
+ opening parentheses, if is are one.
+
+ .. code-block:: c++
+
+ true: false:
+ template<typename T> vs. template<typename T>
+ requires (A<T> && B<T>) requires(A<T> && B<T>)
+ ... ...
+
+ * ``bool AfterRequiresExpression`` 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>
+ requires (T t) { requires(T t) {
+ ... ...
+ } }
+
* ``bool BeforeNonEmptyParentheses`` If ``true``, put a space before opening parentheses only if the
parentheses are not empty.
_______________________________________________
cfe-commits mailing list
[email protected]
https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits