[clang] [clang-format] Correctly annotate requires clause in `&& requires(` (PR #132882)
Owen Pan via cfe-commits
cfe-commits at lists.llvm.org
Mon Mar 24 21:53:54 PDT 2025
https://github.com/owenca created https://github.com/llvm/llvm-project/pull/132882
Fix #132334
>From 07947452a460c7e4ac3715ccc8c703595670c90a Mon Sep 17 00:00:00 2001
From: Owen Pan <owenpiano at gmail.com>
Date: Mon, 24 Mar 2025 21:51:04 -0700
Subject: [PATCH] [clang-format] Correctly annotate requires clause in `&&
requires(`
Fix #132334
---
clang/lib/Format/UnwrappedLineParser.cpp | 8 +++++---
clang/lib/Format/UnwrappedLineParser.h | 2 +-
clang/unittests/Format/TokenAnnotatorTest.cpp | 9 +++++++++
3 files changed, 15 insertions(+), 4 deletions(-)
diff --git a/clang/lib/Format/UnwrappedLineParser.cpp b/clang/lib/Format/UnwrappedLineParser.cpp
index a6e0596add5d2..f7712bea01c2c 100644
--- a/clang/lib/Format/UnwrappedLineParser.cpp
+++ b/clang/lib/Format/UnwrappedLineParser.cpp
@@ -1708,6 +1708,7 @@ void UnwrappedLineParser::parseStructuralElement(
break;
}
+ bool SeenEqual = false;
for (const bool InRequiresExpression =
OpeningBrace && OpeningBrace->isOneOf(TT_RequiresExpressionLBrace,
TT_CompoundRequirementLBrace);
@@ -1782,7 +1783,7 @@ void UnwrappedLineParser::parseStructuralElement(
break;
case tok::kw_requires: {
if (IsCpp) {
- bool ParsedClause = parseRequires();
+ bool ParsedClause = parseRequires(SeenEqual);
if (ParsedClause)
return;
} else {
@@ -2062,6 +2063,7 @@ void UnwrappedLineParser::parseStructuralElement(
break;
}
+ SeenEqual = true;
nextToken();
if (FormatTok->is(tok::l_brace)) {
// Block kind should probably be set to BK_BracedInit for any language.
@@ -3416,7 +3418,7 @@ void UnwrappedLineParser::parseAccessSpecifier() {
/// \brief Parses a requires, decides if it is a clause or an expression.
/// \pre The current token has to be the requires keyword.
/// \returns true if it parsed a clause.
-bool UnwrappedLineParser::parseRequires() {
+bool UnwrappedLineParser::parseRequires(bool SeenEqual) {
assert(FormatTok->is(tok::kw_requires) && "'requires' expected");
auto RequiresToken = FormatTok;
@@ -3472,7 +3474,7 @@ bool UnwrappedLineParser::parseRequires() {
// We check the one token before that for a const:
// void member(...) const && requires (C<T> ...
auto PrevPrev = PreviousNonComment->getPreviousNonComment();
- if (PrevPrev && PrevPrev->is(tok::kw_const)) {
+ if ((PrevPrev && PrevPrev->is(tok::kw_const)) || !SeenEqual) {
parseRequiresClause(RequiresToken);
return true;
}
diff --git a/clang/lib/Format/UnwrappedLineParser.h b/clang/lib/Format/UnwrappedLineParser.h
index 87650c2756cd1..3c5d2c3e030e5 100644
--- a/clang/lib/Format/UnwrappedLineParser.h
+++ b/clang/lib/Format/UnwrappedLineParser.h
@@ -167,7 +167,7 @@ class UnwrappedLineParser {
void parseAccessSpecifier();
bool parseEnum();
bool parseStructLike();
- bool parseRequires();
+ bool parseRequires(bool SeenEqual);
void parseRequiresClause(FormatToken *RequiresToken);
void parseRequiresExpression(FormatToken *RequiresToken);
void parseConstraintExpression();
diff --git a/clang/unittests/Format/TokenAnnotatorTest.cpp b/clang/unittests/Format/TokenAnnotatorTest.cpp
index 1ff785110fc34..3480b55dcbae8 100644
--- a/clang/unittests/Format/TokenAnnotatorTest.cpp
+++ b/clang/unittests/Format/TokenAnnotatorTest.cpp
@@ -1399,6 +1399,15 @@ TEST_F(TokenAnnotatorTest, UnderstandsRequiresClausesAndConcepts) {
ASSERT_EQ(Tokens.size(), 19u) << Tokens;
EXPECT_TOKEN(Tokens[4], tok::amp, TT_PointerOrReference);
EXPECT_TOKEN(Tokens[5], tok::kw_requires, TT_RequiresClause);
+
+ Tokens = annotate("void foo() &&\n"
+ " requires(!bar)\n"
+ "{\n"
+ " baz();\n"
+ "}");
+ ASSERT_EQ(Tokens.size(), 17u) << Tokens;
+ EXPECT_TOKEN(Tokens[4], tok::ampamp, TT_PointerOrReference);
+ EXPECT_TOKEN(Tokens[5], tok::kw_requires, TT_RequiresClause);
}
TEST_F(TokenAnnotatorTest, UnderstandsRequiresExpressions) {
More information about the cfe-commits
mailing list