Author: Owen Pan Date: 2025-01-06T01:46:17-08:00 New Revision: 9e4774b934a26489e0e3ae60def3aefb5c73edd3
URL: https://github.com/llvm/llvm-project/commit/9e4774b934a26489e0e3ae60def3aefb5c73edd3 DIFF: https://github.com/llvm/llvm-project/commit/9e4774b934a26489e0e3ae60def3aefb5c73edd3.diff LOG: [clang-format] Add LT_RequiresExpression and LT_SimpleRequirement (#121681) The new line types help to annotate */&/&& in simple requirements as binary operators. Fixes #121675. Added: Modified: clang/lib/Format/TokenAnnotator.cpp clang/lib/Format/TokenAnnotator.h clang/unittests/Format/TokenAnnotatorTest.cpp Removed: ################################################################################ diff --git a/clang/lib/Format/TokenAnnotator.cpp b/clang/lib/Format/TokenAnnotator.cpp index 945174ca9c5861..e18e9a6fcd074b 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,11 @@ class AnnotatingParser { if (!consumeToken()) return LT_Invalid; } - if (Line.Type == LT_AccessModifier) - return LT_AccessModifier; + if (const auto Type = Line.Type; Type == LT_AccessModifier || + Type == LT_RequiresExpression || + Type == LT_SimpleRequirement) { + return Type; + } if (KeywordVirtualFound) return LT_VirtualFunctionDecl; if (ImportStatement) @@ -3102,8 +3108,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 +3701,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