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 <owenpi...@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) { _______________________________________________ cfe-commits mailing list cfe-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits