[PATCH] D147295: [clang-format] Don't misannotate left squares as lambda introducers

Owen Pan via Phabricator via cfe-commits cfe-commits at lists.llvm.org
Thu Mar 30 20:33:47 PDT 2023


owenpan created this revision.
owenpan added reviewers: MyDeveloperDay, HazardyKnusperkeks, rymiel.
Herald added projects: All, clang, clang-format.
Herald added a subscriber: cfe-commits.
owenpan requested review of this revision.

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 https://github.com/llvm/llvm-project/issues/54245.
Fixes https://github.com/llvm/llvm-project/issues/61786.


Repository:
  rG LLVM Github Monorepo

https://reviews.llvm.org/D147295

Files:
  clang/lib/Format/UnwrappedLineParser.cpp
  clang/unittests/Format/TokenAnnotatorTest.cpp


Index: clang/unittests/Format/TokenAnnotatorTest.cpp
===================================================================
--- clang/unittests/Format/TokenAnnotatorTest.cpp
+++ clang/unittests/Format/TokenAnnotatorTest.cpp
@@ -382,6 +382,32 @@
   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 @@
   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;
Index: clang/lib/Format/UnwrappedLineParser.cpp
===================================================================
--- clang/lib/Format/UnwrappedLineParser.cpp
+++ clang/lib/Format/UnwrappedLineParser.cpp
@@ -2231,11 +2231,11 @@
   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 @@
           // 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;


-------------- next part --------------
A non-text attachment was scrubbed...
Name: D147295.509890.patch
Type: text/x-patch
Size: 3801 bytes
Desc: not available
URL: <http://lists.llvm.org/pipermail/cfe-commits/attachments/20230331/eb7886d0/attachment.bin>


More information about the cfe-commits mailing list