[clang-format] Correctly recognize arrays in template parameter list.
authorMarek Kurdej <marek.kurdej+llvm.org@gmail.com>
Mon, 14 Mar 2022 11:00:19 +0000 (12:00 +0100)
committerMarek Kurdej <marek.kurdej+llvm.org@gmail.com>
Tue, 15 Mar 2022 10:33:13 +0000 (11:33 +0100)
Fixes https://github.com/llvm/llvm-project/issues/54245.

Reviewed By: MyDeveloperDay, HazardyKnusperkeks, owenpan

Differential Revision: https://reviews.llvm.org/D121584

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

index b03296c7e02d9bb352eaffecaa032832f649ce68..cadf1960dbf7a9551d3cdd862381f4e220380311 100644 (file)
@@ -1935,6 +1935,11 @@ bool UnwrappedLineParser::tryToParseLambda() {
   if (!tryToParseLambdaIntroducer())
     return false;
 
+  // `[something] >` is not a lambda, but an array type in a template parameter
+  // list.
+  if (FormatTok->is(tok::greater))
+    return false;
+
   bool SeenArrow = false;
   bool InTemplateParameterList = false;
 
@@ -3524,7 +3529,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;
index dff8c04662601268c815a843644523e775f89435..5f346fa5f8bfa5025793c5e78a2208bb22e585d1 100644 (file)
@@ -98,6 +98,20 @@ TEST_F(TokenAnnotatorTest, UnderstandsStructs) {
   auto Tokens = annotate("struct S {};");
   EXPECT_EQ(Tokens.size(), 6u) << Tokens;
   EXPECT_TOKEN(Tokens[2], 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);
 }
 
 TEST_F(TokenAnnotatorTest, UnderstandsUnions) {