[clang] 9e4774b - [clang-format] Add LT_RequiresExpression and LT_SimpleRequirement (#121681)
via cfe-commits
cfe-commits at lists.llvm.org
Mon Jan 6 01:46:20 PST 2025
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)");
More information about the cfe-commits
mailing list