[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