[clang] 2a42a7b - [clang-format] Don't misannotate left squares as lambda introducers
Owen Pan via cfe-commits
cfe-commits at lists.llvm.org
Fri Mar 31 16:13:11 PDT 2023
Author: Owen Pan
Date: 2023-03-31T16:13:03-07:00
New Revision: 2a42a7b4e87395ae2a4321292f0fd9dce401b4e1
URL: https://github.com/llvm/llvm-project/commit/2a42a7b4e87395ae2a4321292f0fd9dce401b4e1
DIFF: https://github.com/llvm/llvm-project/commit/2a42a7b4e87395ae2a4321292f0fd9dce401b4e1.diff
LOG: [clang-format] Don't misannotate left squares as lambda introducers
A left square can start a lambda only if it's not preceded by an
identifier other than return and co-wait/co-yield/co-return.
Fixes #54245.
Fixes #61786.
Differential Revision: https://reviews.llvm.org/D147295
Added:
Modified:
clang/lib/Format/UnwrappedLineParser.cpp
clang/unittests/Format/TokenAnnotatorTest.cpp
Removed:
################################################################################
diff --git a/clang/lib/Format/UnwrappedLineParser.cpp b/clang/lib/Format/UnwrappedLineParser.cpp
index 3a661292b2d72..fdf5d85d6b1d2 100644
--- a/clang/lib/Format/UnwrappedLineParser.cpp
+++ b/clang/lib/Format/UnwrappedLineParser.cpp
@@ -2231,11 +2231,11 @@ bool UnwrappedLineParser::tryToParseLambdaIntroducer() {
const FormatToken *Previous = FormatTok->Previous;
const FormatToken *LeftSquare = FormatTok;
nextToken();
- if (Previous &&
- (Previous->isOneOf(tok::identifier, tok::kw_operator, tok::kw_new,
- tok::kw_delete, tok::l_square) ||
- LeftSquare->isCppStructuredBinding(Style) || Previous->closesScope() ||
- Previous->isSimpleTypeSpecifier())) {
+ if ((Previous && ((Previous->Tok.getIdentifierInfo() &&
+ !Previous->isOneOf(tok::kw_return, tok::kw_co_await,
+ tok::kw_co_yield, tok::kw_co_return)) ||
+ Previous->closesScope())) ||
+ LeftSquare->isCppStructuredBinding(Style)) {
return false;
}
if (FormatTok->is(tok::l_square))
@@ -3784,7 +3784,7 @@ void UnwrappedLineParser::parseRecord(bool ParseAsExpr) {
// Don't try parsing a lambda if we had a closing parenthesis before,
// it was probably a pointer to an array: int (*)[].
if (!tryToParseLambda())
- break;
+ continue;
} else {
parseSquare();
continue;
diff --git a/clang/unittests/Format/TokenAnnotatorTest.cpp b/clang/unittests/Format/TokenAnnotatorTest.cpp
index b058e62654551..bea85e5bdba2f 100644
--- a/clang/unittests/Format/TokenAnnotatorTest.cpp
+++ b/clang/unittests/Format/TokenAnnotatorTest.cpp
@@ -382,6 +382,32 @@ TEST_F(TokenAnnotatorTest, UnderstandsStructs) {
Tokens = annotate("struct [[deprecated]] [[nodiscard]] C { int i; };");
EXPECT_EQ(Tokens.size(), 19u) << Tokens;
EXPECT_TOKEN(Tokens[12], tok::l_brace, TT_StructLBrace);
+
+ Tokens = annotate("template <typename T> struct S<const T[N]> {};");
+ EXPECT_EQ(Tokens.size(), 18u) << Tokens;
+ EXPECT_TOKEN(Tokens[7], tok::less, TT_TemplateOpener);
+ EXPECT_TOKEN(Tokens[10], tok::l_square, TT_ArraySubscriptLSquare);
+ EXPECT_TOKEN(Tokens[13], tok::greater, TT_TemplateCloser);
+ EXPECT_TOKEN(Tokens[14], tok::l_brace, TT_StructLBrace);
+
+ Tokens = annotate("template <typename T> struct S<T const[N]> {};");
+ EXPECT_EQ(Tokens.size(), 18u) << Tokens;
+ EXPECT_TOKEN(Tokens[7], tok::less, TT_TemplateOpener);
+ EXPECT_TOKEN(Tokens[10], tok::l_square, TT_ArraySubscriptLSquare);
+ EXPECT_TOKEN(Tokens[13], tok::greater, TT_TemplateCloser);
+ EXPECT_TOKEN(Tokens[14], tok::l_brace, TT_StructLBrace);
+
+ Tokens = annotate("template <typename T, unsigned n> struct S<T const[n]> {\n"
+ " void f(T const (&a)[n]);\n"
+ "};");
+ EXPECT_EQ(Tokens.size(), 35u) << Tokens;
+ EXPECT_TOKEN(Tokens[10], tok::less, TT_TemplateOpener);
+ EXPECT_TOKEN(Tokens[13], tok::l_square, TT_ArraySubscriptLSquare);
+ EXPECT_TOKEN(Tokens[16], tok::greater, TT_TemplateCloser);
+ EXPECT_TOKEN(Tokens[17], tok::l_brace, TT_StructLBrace);
+ EXPECT_TOKEN(Tokens[23], tok::l_paren, TT_FunctionTypeLParen);
+ EXPECT_TOKEN(Tokens[24], tok::amp, TT_UnaryOperator);
+ EXPECT_TOKEN(Tokens[27], tok::l_square, TT_ArraySubscriptLSquare);
}
TEST_F(TokenAnnotatorTest, UnderstandsUnions) {
@@ -1193,6 +1219,16 @@ TEST_F(TokenAnnotatorTest, UnderstandsObjCBlock) {
EXPECT_TOKEN(Tokens[9], tok::l_brace, TT_ObjCBlockLBrace);
}
+TEST_F(TokenAnnotatorTest, UnderstandsObjCMethodExpr) {
+ auto Tokens = annotate("void f() {\n"
+ " //\n"
+ " BOOL a = [b.c n] > 1;\n"
+ "}");
+ EXPECT_EQ(Tokens.size(), 20u) << Tokens;
+ EXPECT_TOKEN(Tokens[9], tok::l_square, TT_ObjCMethodExpr);
+ EXPECT_TOKEN(Tokens[15], tok::greater, TT_BinaryOperator);
+}
+
TEST_F(TokenAnnotatorTest, UnderstandsLambdas) {
auto Tokens = annotate("[]() constexpr {}");
ASSERT_EQ(Tokens.size(), 8u) << Tokens;
More information about the cfe-commits
mailing list