[PATCH] D79773: [clang-format] Improve clang-formats handling of concepts
Michael Schellenberger Costa via Phabricator via cfe-commits
cfe-commits at lists.llvm.org
Tue May 19 02:40:31 PDT 2020
miscco added a comment.
Awesome, Thank you very much, I dragged my feet on starting to implement something for real.
As a high level comment I think we need to handle requires expressions to get this correct, as `requires requires` would otherwise to bad things.
>From my early brainstorming i got the following options I thought useful. This is in no ways a request for you to implement them, but I would want to get them out here in case they are usefull
/// Different styles for merging short requires-clauses with the template
/// decalaration
enum ShortRequiresClauseStyle {
/// Never merge requires clauses into a single line.
/// \code
/// template <class T>
/// requires someConstraint<T>
/// T foo();
/// \endcode
SRCS_Never,
/// Only merge requires clauses with a single constraint.
/// \code
/// template <class T> requires someConstraint<T>
/// T foo();
///
/// template <class T>
/// requires someConstraint<T> && otherConstraint<T>
/// T bar();
/// \endcode
SRCS_Single,
/// Merge requires clauses if they are short
/// \code
/// template <class T> requires short<T> && shorter<T>
/// T foo();
///
/// template <class T>
/// requires someReallyLongElaborateConstraintThatIsReallyLong<T>
/// T bar();
///
/// template <class T>
/// requires someLongConstraint<T> && otherLongConstraint<T>
/// T baz();
/// \endcode
SRCS_Short,
/// Always try to merge the requires clause with the template declaration
/// \code
/// template <class T> requires someLongConstraint<T> &&
/// otherLongConstraint<T>
/// T foo();
/// \endcode
SRCS_Always,
};
/// Dependent on the value, requires-clauses can be put on the same line
/// as the template declaration.
ShortRequiresClauseStyle AllowShortRequiresClause;
/// Dependent on the value, requires-expressions can be a single line
/// Always try to merge the requires clause with the template declaration
/// \code
/// template <class T> requires someLongConstraint<T> &&
/// requires { T{}; }
/// T foo();
/// \endcode
bool AllowShortRequiresExpression;
/// Dependent on the value break before or after constraint expressions.
enum ConstraintExpressionBreakingStyle {
/// Break after constraint expressions but multiple may be on single line
/// \code
/// template <class T> requires someLongConstraint<T> &&
/// otherLongConstraint<T>
/// T foo();
///
/// template <class T> requires short<T> && shorter<T> &&
/// otherLongConstraint<T>
/// T bar();
/// \endcode
CEBS_After,
/// Break after constraint expressions.
/// \code
/// template <class T> requires short<T> &&
/// shorter<T> &&
/// otherLongConstraint<T>
/// T bar();
/// \endcode
CEBS_AfterSingleExpression,
/// Break before constraint expressions but multiple may be on single line
/// \code
/// template <class T> requires someLongConstraint<T> &&
/// otherLongConstraint<T>
/// T foo();
///
/// template <class T> requires short<T> && shorter<T>
/// && otherLongConstraint<T>
/// T bar();
/// \endcode
CEBS_Before,
/// Break before constraint expressions.
/// \code
/// template <class T> requires short<T>
/// && shorter<T>
/// && otherLongConstraint<T>
/// T foo();
/// \endcode
CEBS_BeforeSingleExpression,
};
/// The constraint expressions style to use.
ConstraintExpressionBreakingStyle BreakBeforeConstraintExpression;
/// Dependent on the value wrap before or after requires expressions.
enum BraceWrappingRequiresExpressionStyle {
/// Do not wrap braces of requires expressions
/// \code
/// template <class T> requires requires { T{};
/// T(int); }
/// T foo();
/// \endcode
BWARES_NoWrap,
/// Wrap after requires expressions.
/// \code
/// template <class T> requires requires { T{};
/// T(int);
/// }
/// T foo();
/// \endcode
BWARES_WrapAfter,
/// Wrap after requires expressions.
/// \code
/// template <class T> requires requires
/// { T{};
/// T(int); }
/// T foo();
/// \endcode
BWARES_WrapBefore,
/// Wrap after requires expressions with a new line.
/// \code
/// template <class T> requires requires
/// {
/// T{};
/// T(int); }
/// T foo();
/// \endcode
BWARES_WrapBeforeWithNewline,
/// Wrap before requires expressions.
/// \code
/// template <class T> requires requires
/// { T{};
/// T(int);
/// }
/// T foo();
/// \endcode
BWARES_WrapBoth,
/// Wrap before requires expressions.
/// \code
/// template <class T> requires requires
/// {
/// T{};
/// T(int);
/// }
/// T foo();
/// \endcode
BWARES_WrapBothWithNewline,
};
/// The requires expressions style to use.
BraceWrappingRequiresExpressionStyle BraceWrappingRequiresExpression;
My problem was that I had no idea how to properly tokenize the logical-or-constraint-expression. I have pushed my super clumsy WIP stuff here:
https://github.com/miscco/llvm-project/pull/new/clang_format_concepts
If I can help you in any way please tell me
================
Comment at: clang/lib/Format/TokenAnnotator.cpp:1566
Current.Type = TT_TrailingReturnArrow;
-
+ } else if (Current.is(tok::arrow) && Current.Previous &&
+ Current.Previous->is(tok::r_brace)) {
----------------
Should that really be `tok::arrow` and not `tok::kw_requires`?
================
Comment at: clang/lib/Format/TokenAnnotator.cpp:3484
+ // concept ...
+ if (Left.is(TT_TemplateCloser) && Right.is(tok::kw_concept))
+ return true;
----------------
I think we should have an option to allow short requires clauses on the same line similar to allow short functions
================
Comment at: clang/lib/Format/UnwrappedLineParser.cpp:2284
+
+void UnwrappedLineParser::parseRequires() {
+ assert(FormatTok->Tok.is(tok::kw_requires) && "'requires' expected");
----------------
I believe we should separate between constraint expressions aka: `tempalte< > requires Concept1 && Concept2` and requires expressions aka `requires { ... }`
The two are quite different. That said the handling of requires expressions should be "simple" as we only need to find the matching "}".
As an upside this would also handle the famous `requires requires`
CHANGES SINCE LAST ACTION
https://reviews.llvm.org/D79773/new/
https://reviews.llvm.org/D79773
More information about the cfe-commits
mailing list