Skip to content

Commit ef604d0

Browse files
committed
[clang-format] Make some binary operations imply requires clause
This patch adjusts the requires clause/expression lookahead heuristic to assume that some binary operation mean that the requires keyword refers to a clause. This partially reverts the removed case clauses from 9b68c09, with an additional check that we're not in a type parameter. This is quite a band-aid fix, it may be worth it to rewrite that whole heuristic to track more state in the future, instead of just blindly marching forward across multiple unrelated definitions, since right now, the definition following the one with the requires clause can influence whether the heuristic chooses clause or expression. Fixes #110485
1 parent 6c7a3f8 commit ef604d0

File tree

2 files changed

+26
-0
lines changed

2 files changed

+26
-0
lines changed

clang/lib/Format/UnwrappedLineParser.cpp

Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -3528,6 +3528,17 @@ bool UnwrappedLineParser::parseRequires() {
35283528
return false;
35293529
}
35303530
break;
3531+
case tok::equalequal:
3532+
case tok::greaterequal:
3533+
case tok::lessequal:
3534+
case tok::r_paren:
3535+
case tok::pipepipe:
3536+
if (OpenAngles == 0) {
3537+
FormatTok = Tokens->setPosition(StoredPosition);
3538+
parseRequiresClause(RequiresToken);
3539+
return true;
3540+
}
3541+
break;
35313542
case tok::eof:
35323543
// Break out of the loop.
35333544
Lookahead = 50;

clang/unittests/Format/TokenAnnotatorTest.cpp

Lines changed: 15 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1296,6 +1296,21 @@ TEST_F(TokenAnnotatorTest, UnderstandsRequiresClausesAndConcepts) {
12961296
Tokens = annotate("bool x = t && requires(Foo<C1 || C2> x) { x.foo(); };");
12971297
ASSERT_EQ(Tokens.size(), 25u) << Tokens;
12981298
EXPECT_TOKEN(Tokens[5], tok::kw_requires, TT_RequiresExpression);
1299+
1300+
// Second function definition is required due to lookahead
1301+
Tokens = annotate("void f() & requires(n == 1) {}\nvoid g();");
1302+
ASSERT_EQ(Tokens.size(), 19u) << Tokens;
1303+
EXPECT_TOKEN(Tokens[4], tok::amp, TT_PointerOrReference);
1304+
EXPECT_TOKEN(Tokens[5], tok::kw_requires, TT_RequiresClause);
1305+
1306+
Tokens = annotate("void f() & requires(n || h) {}\nvoid g();");
1307+
ASSERT_EQ(Tokens.size(), 19u) << Tokens;
1308+
EXPECT_TOKEN(Tokens[4], tok::amp, TT_PointerOrReference);
1309+
EXPECT_TOKEN(Tokens[5], tok::kw_requires, TT_RequiresClause);
1310+
1311+
Tokens = annotate("bool x = t && requires(F<n == 1> x) { x.foo(); };");
1312+
ASSERT_EQ(Tokens.size(), 25u) << Tokens;
1313+
EXPECT_TOKEN(Tokens[5], tok::kw_requires, TT_RequiresExpression);
12991314
}
13001315

13011316
TEST_F(TokenAnnotatorTest, UnderstandsRequiresExpressions) {

0 commit comments

Comments
 (0)