diff --git a/clang/lib/Format/UnwrappedLineParser.cpp b/clang/lib/Format/UnwrappedLineParser.cpp --- a/clang/lib/Format/UnwrappedLineParser.cpp +++ b/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; diff --git a/clang/unittests/Format/TokenAnnotatorTest.cpp b/clang/unittests/Format/TokenAnnotatorTest.cpp --- a/clang/unittests/Format/TokenAnnotatorTest.cpp +++ b/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 struct S {};"); + 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 struct S {};"); + 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 struct S {\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;