https://github.com/owenca updated https://github.com/llvm/llvm-project/pull/121681
>From 14e26d9bb27724705e51fc134a4f3df2a09807e6 Mon Sep 17 00:00:00 2001 From: Owen Pan <owenpi...@gmail.com> Date: Sat, 4 Jan 2025 23:42:38 -0800 Subject: [PATCH] [clang-format] Add LT_RequiresExpression and LT_SimpleRequirement The new line types help to annotate */&/&& in simple requirements as binary operators. Fixes #121675. --- clang/lib/Format/TokenAnnotator.cpp | 24 +++++++++++++---- clang/lib/Format/TokenAnnotator.h | 2 ++ clang/unittests/Format/TokenAnnotatorTest.cpp | 27 ++++++++++--------- 3 files changed, 36 insertions(+), 17 deletions(-) diff --git a/clang/lib/Format/TokenAnnotator.cpp b/clang/lib/Format/TokenAnnotator.cpp index 945174ca9c5861..fa864f4c5e943d 100644 --- a/clang/lib/Format/TokenAnnotator.cpp +++ b/clang/lib/Format/TokenAnnotator.cpp @@ -1582,7 +1582,10 @@ class AnnotatingParser { return false; break; case tok::l_brace: - if (Style.Language == FormatStyle::LK_TextProto) { + if (IsCpp) { + if (Tok->is(TT_RequiresExpressionLBrace)) + Line.Type = LT_RequiresExpression; + } else if (Style.Language == FormatStyle::LK_TextProto) { FormatToken *Previous = Tok->getPreviousNonComment(); if (Previous && Previous->isNot(TT_DictLiteral)) Previous->setType(TT_SelectorName); @@ -2024,8 +2027,10 @@ class AnnotatingParser { if (!consumeToken()) return LT_Invalid; } - if (Line.Type == LT_AccessModifier) - return LT_AccessModifier; + if (Line.Type == LT_AccessModifier || Line.Type == LT_RequiresExpression || + Line.Type == LT_SimpleRequirement) { + return Line.Type; + } if (KeywordVirtualFound) return LT_VirtualFunctionDecl; if (ImportStatement) @@ -3102,8 +3107,10 @@ class AnnotatingParser { } } - if (!Scopes.empty() && Scopes.back() == ST_CompoundRequirement) + if (Line.Type == LT_SimpleRequirement || + (!Scopes.empty() && Scopes.back() == ST_CompoundRequirement)) { return TT_BinaryOperator; + } return TT_PointerOrReference; } @@ -3693,8 +3700,15 @@ void TokenAnnotator::annotate(AnnotatedLine &Line) { if (!Line.Children.empty()) { ScopeStack.push_back(ST_ChildBlock); - for (auto &Child : Line.Children) + const bool InRequiresExpression = Line.Type == LT_RequiresExpression; + for (auto &Child : Line.Children) { + if (InRequiresExpression && + !Child->First->isOneOf(tok::kw_typename, tok::kw_requires, + TT_CompoundRequirementLBrace)) { + Child->Type = LT_SimpleRequirement; + } annotate(*Child); + } // ScopeStack can become empty if Child has an unmatched `}`. if (!ScopeStack.empty()) ScopeStack.pop_back(); diff --git a/clang/lib/Format/TokenAnnotator.h b/clang/lib/Format/TokenAnnotator.h index 1a250e94d97c50..fa15517042f250 100644 --- a/clang/lib/Format/TokenAnnotator.h +++ b/clang/lib/Format/TokenAnnotator.h @@ -33,6 +33,8 @@ enum LineType { LT_VirtualFunctionDecl, LT_ArrayOfStructInitializer, LT_CommentAbovePPDirective, + LT_RequiresExpression, + LT_SimpleRequirement, }; enum ScopeType { diff --git a/clang/unittests/Format/TokenAnnotatorTest.cpp b/clang/unittests/Format/TokenAnnotatorTest.cpp index a5b2d09a9f704d..0383780c2d84a2 100644 --- a/clang/unittests/Format/TokenAnnotatorTest.cpp +++ b/clang/unittests/Format/TokenAnnotatorTest.cpp @@ -370,6 +370,21 @@ TEST_F(TokenAnnotatorTest, UnderstandsUsesOfStarAndAmp) { ASSERT_EQ(Tokens.size(), 18u) << Tokens; EXPECT_TOKEN(Tokens[8], tok::r_paren, TT_CastRParen); EXPECT_TOKEN(Tokens[11], tok::star, TT_BinaryOperator); + + Tokens = annotate("template <typename T>\n" + "concept C = requires(T a, T b) { a && b; };"); + ASSERT_EQ(Tokens.size(), 24u) << Tokens; + EXPECT_TOKEN(Tokens[16], tok::l_brace, TT_RequiresExpressionLBrace); + EXPECT_TOKEN(Tokens[18], tok::ampamp, TT_BinaryOperator); + + Tokens = annotate("template <typename T, typename V>\n" + "concept CheckMultiplicableBy = requires(T a, V b) {\n" + " { a * b } -> std::same_as<T>;\n" + "};"); + ASSERT_EQ(Tokens.size(), 36u) << Tokens; + EXPECT_TOKEN(Tokens[19], tok::l_brace, TT_RequiresExpressionLBrace); + EXPECT_TOKEN(Tokens[20], tok::l_brace, TT_CompoundRequirementLBrace); + EXPECT_TOKEN(Tokens[22], tok::star, TT_BinaryOperator); } TEST_F(TokenAnnotatorTest, UnderstandsUsesOfPlusAndMinus) { @@ -1456,18 +1471,6 @@ TEST_F(TokenAnnotatorTest, UnderstandsRequiresExpressions) { EXPECT_TOKEN(Tokens[13], tok::l_brace, TT_RequiresExpressionLBrace); } -TEST_F(TokenAnnotatorTest, CompoundRequirement) { - auto Tokens = annotate("template <typename T, typename V>\n" - "concept CheckMultiplicableBy = requires(T a, V b) {\n" - " { a * b } -> std::same_as<T>;\n" - "};"); - ASSERT_EQ(Tokens.size(), 36u) << Tokens; - - EXPECT_TOKEN(Tokens[19], tok::l_brace, TT_RequiresExpressionLBrace); - EXPECT_TOKEN(Tokens[20], tok::l_brace, TT_CompoundRequirementLBrace); - EXPECT_TOKEN(Tokens[22], tok::star, TT_BinaryOperator); -} - TEST_F(TokenAnnotatorTest, UnderstandsPragmaRegion) { // Everything after #pragma region should be ImplicitStringLiteral auto Tokens = annotate("#pragma region Foo(Bar: Hello)"); _______________________________________________ cfe-commits mailing list cfe-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits