[PATCH] D79773: [clang-format] Improve clang-formats handling of concepts
MyDeveloperDay via Phabricator via cfe-commits
cfe-commits at lists.llvm.org
Tue May 12 03:11:30 PDT 2020
MyDeveloperDay created this revision.
MyDeveloperDay added reviewers: krasimir, sammccall, owenpan, jbcoe, mitchell-stellar.
MyDeveloperDay added projects: clang, clang-format.
This is a starting point to improve the handling of concepts in clang-format. There is currently no real formatting of concepts and this can lead to some odd formatting, e.g.
requires(R range) {
typename Iterator_type<R>;
{ begin(range) }
->Iterator_type<R>;
{ end(range) }
->Iterator_type<R>;
requires Input_iterator<Iterator_type<R>>();
};
The revision starts by resolving the additional newline added before the implicit conversion constraint and ensures that the concept keyword is always on the line below template<>
template <typename T>
concept bool EqualityComparable = requires(T a, T b) {
{ a == b } -> bool;
};
Repository:
rG LLVM Github Monorepo
https://reviews.llvm.org/D79773
Files:
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
@@ -15849,6 +15849,41 @@
verifyFormat("operator&&(int(&&)(), class Foo);", Style);
}
+TEST_F(FormatTest, ConceptsImplicitConversionConstraint) {
+ FormatStyle Style = getLLVMStyle();
+
+ verifyFormat("template <typename T>\n"
+ "concept Hashable = requires(T a) {\n"
+ " { std::hash<T>{}(a) } -> std::convertible_to<std::size_t>;\n"
+ "};",
+ Style);
+ verifyFormat("template <typename T>\n"
+ "concept bool EqualityComparable = requires(T a, T b) {\n"
+ " { a == b } -> bool;\n"
+ "};",
+ Style);
+ verifyFormat("template <typename T>\n"
+ "concept bool EqualityComparable = requires(T a, T b) {\n"
+ " { a == b } -> bool;\n"
+ " { a != b } -> bool;\n"
+ "};",
+ Style);
+ verifyFormat("template <typename T>\n"
+ "concept bool EqualityComparable = requires(T a, T b) {\n"
+ " { a == b } -> bool;\n"
+ " { a != b } -> bool;\n"
+ "};",
+ Style);
+
+ verifyFormat("requires(R range) {\n"
+ " typename Iterator_type<R>;\n"
+ " { begin(range) } -> Iterator_type<R>;\n"
+ " { end(range) } -> Iterator_type<R>;\n"
+ " requires Input_iterator<Iterator_type<R>>();\n"
+ "};\n",
+ Style);
+}
+
} // namespace
} // namespace format
} // namespace clang
Index: clang/lib/Format/UnwrappedLineParser.cpp
===================================================================
--- clang/lib/Format/UnwrappedLineParser.cpp
+++ clang/lib/Format/UnwrappedLineParser.cpp
@@ -628,6 +628,13 @@
if (MunchSemi && FormatTok->Tok.is(tok::semi))
nextToken();
+ else if (FormatTok->is(tok::arrow)) {
+ // Following the } we can find a trailing return type arrow
+ // as part of an implicit conversion constraint.
+ nextToken();
+ parseStructuralElement();
+ }
+
Line->Level = InitialLevel;
if (PPStartHash == PPEndHash) {
Index: clang/lib/Format/TokenAnnotator.cpp
===================================================================
--- clang/lib/Format/TokenAnnotator.cpp
+++ clang/lib/Format/TokenAnnotator.cpp
@@ -1563,7 +1563,11 @@
!Current.Previous->is(tok::kw_operator)) {
// not auto operator->() -> xxx;
Current.Type = TT_TrailingReturnArrow;
-
+ } else if (Current.is(tok::arrow) && Current.Previous &&
+ Current.Previous->is(tok::r_brace)) {
+ // Concept implicit conversion contrain needs to be treated like
+ // a trailing return type ... } -> <type>.
+ Current.Type = TT_TrailingReturnArrow;
} else if (isDeductionGuide(Current)) {
// Deduction guides trailing arrow " A(...) -> A<T>;".
Current.Type = TT_TrailingReturnArrow;
@@ -3466,6 +3470,12 @@
return true;
}
+ // Put concepts on the next line e.g.
+ // template<typename T>
+ // concept ...
+ if (Left.is(TT_TemplateCloser) && Right.is(tok::kw_concept))
+ return true;
+
if (Right.is(tok::comment))
return Left.BlockKind != BK_BracedInit &&
Left.isNot(TT_CtorInitializerColon) &&
-------------- next part --------------
A non-text attachment was scrubbed...
Name: D79773.263388.patch
Type: text/x-patch
Size: 3431 bytes
Desc: not available
URL: <http://lists.llvm.org/pipermail/cfe-commits/attachments/20200512/05c0da18/attachment.bin>
More information about the cfe-commits
mailing list