sstwcw updated this revision to Diff 521667.
sstwcw added a comment.

- Remove the special case for operator[], it isn't necessary.


Repository:
  rG LLVM Github Monorepo

CHANGES SINCE LAST ACTION
  https://reviews.llvm.org/D150452/new/

https://reviews.llvm.org/D150452

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

Index: clang/unittests/Format/TokenAnnotatorTest.cpp
===================================================================
--- clang/unittests/Format/TokenAnnotatorTest.cpp
+++ clang/unittests/Format/TokenAnnotatorTest.cpp
@@ -40,6 +40,8 @@
   EXPECT_EQ((FormatTok)->getType(), Type) << *(FormatTok)
 #define EXPECT_TOKEN_PRECEDENCE(FormatTok, Prec)                               \
   EXPECT_EQ((FormatTok)->getPrecedence(), Prec) << *(FormatTok)
+#define EXPECT_BRACE_KIND(FormatTok, Kind)                                     \
+  EXPECT_EQ(FormatTok->getBlockKind(), Kind)
 #define EXPECT_TOKEN(FormatTok, Kind, Type)                                    \
   do {                                                                         \
     EXPECT_TOKEN_KIND(FormatTok, Kind);                                        \
@@ -1783,6 +1785,22 @@
   EXPECT_TOKEN(Tokens[3], tok::colon, TT_CaseLabelColon);
 }
 
+TEST_F(TokenAnnotatorTest, UnderstandsNestedBlocks) {
+  // The closing braces are not annotated.  It doesn't seem to cause a
+  // problem.  So we only test for the opening braces.
+  auto Tokens = annotate("{\n"
+                         "  {\n"
+                         "    { int a = 0; }\n"
+                         "  }\n"
+                         "  {}\n"
+                         "}");
+  ASSERT_EQ(Tokens.size(), 14u) << Tokens;
+  EXPECT_BRACE_KIND(Tokens[0], BK_Block);
+  EXPECT_BRACE_KIND(Tokens[1], BK_Block);
+  EXPECT_BRACE_KIND(Tokens[2], BK_Block);
+  EXPECT_BRACE_KIND(Tokens[10], BK_Block);
+}
+
 } // namespace
 } // namespace format
 } // namespace clang
Index: clang/unittests/Format/FormatTest.cpp
===================================================================
--- clang/unittests/Format/FormatTest.cpp
+++ clang/unittests/Format/FormatTest.cpp
@@ -55,6 +55,15 @@
 
 TEST_F(FormatTest, FormatsNestedBlockStatements) {
   EXPECT_EQ("{\n  {\n    {}\n  }\n}", format("{{{}}}"));
+  // The innermost block is on a single line because a block with only 1
+  // statement is hard-coded to be squeezed into one line in
+  // ContinuationIndenter, not because it is recognized as an initializer list.
+  verifyFormat("int main() {\n"
+               "  {\n"
+               "    { int a = 0; }\n"
+               "  }\n"
+               "  {}\n"
+               "}");
 }
 
 TEST_F(FormatTest, FormatsNestedCall) {
Index: clang/lib/Format/UnwrappedLineParser.cpp
===================================================================
--- clang/lib/Format/UnwrappedLineParser.cpp
+++ clang/lib/Format/UnwrappedLineParser.cpp
@@ -488,10 +488,17 @@
   unsigned StoredPosition = Tokens->getPosition();
   FormatToken *Tok = FormatTok;
   const FormatToken *PrevTok = Tok->Previous;
+  // A rough guess at whether a block is a lambda expression.
+  bool ProbablyLambda = false;
   // Keep a stack of positions of lbrace tokens. We will
   // update information about whether an lbrace starts a
   // braced init list or a different block during the loop.
-  SmallVector<FormatToken *, 8> LBraceStack;
+  struct StackEntry {
+    FormatToken *Tok;
+    const FormatToken *PrevTok, *NextTok;
+    bool ProbablyLambda;
+  };
+  SmallVector<StackEntry, 8> LBraceStack;
   assert(Tok->is(tok::l_brace));
   do {
     // Get next non-comment token.
@@ -521,12 +528,13 @@
       } else {
         Tok->setBlockKind(BK_Unknown);
       }
-      LBraceStack.push_back(Tok);
+      LBraceStack.push_back({Tok, PrevTok, NextTok, ProbablyLambda});
       break;
     case tok::r_brace:
       if (LBraceStack.empty())
         break;
-      if (LBraceStack.back()->is(BK_Unknown)) {
+      switch (LBraceStack.back().Tok->getBlockKind()) {
+      case BK_Unknown: {
         bool ProbablyBracedList = false;
         if (Style.Language == FormatStyle::LK_Proto) {
           ProbablyBracedList = NextTok->isOneOf(tok::comma, tok::r_square);
@@ -554,7 +562,7 @@
 
           // If we already marked the opening brace as braced list, the closing
           // must also be part of it.
-          ProbablyBracedList = LBraceStack.back()->is(TT_BracedListLBrace);
+          ProbablyBracedList = LBraceStack.back().Tok->is(TT_BracedListLBrace);
 
           ProbablyBracedList = ProbablyBracedList ||
                                (Style.isJavaScript() &&
@@ -595,15 +603,43 @@
         }
         if (ProbablyBracedList) {
           Tok->setBlockKind(BK_BracedInit);
-          LBraceStack.back()->setBlockKind(BK_BracedInit);
+          LBraceStack.back().Tok->setBlockKind(BK_BracedInit);
         } else {
           Tok->setBlockKind(BK_Block);
-          LBraceStack.back()->setBlockKind(BK_Block);
+          LBraceStack.back().Tok->setBlockKind(BK_Block);
         }
+        break;
+      }
+      case BK_Block:
+        // A block usually means the outer braces are also a block, except for
+        // the cases below where a block is inside an expression.
+        // A statement expression.
+        if ((NextTok && NextTok->is(tok::r_paren)) ||
+            (LBraceStack.back().PrevTok &&
+             LBraceStack.back().PrevTok->isOneOf(tok::l_paren, tok::caret,
+                                                 TT_FatArrow))) {
+          break;
+        }
+        // A lambda expression.  If the closing parenthesis is the condition
+        // part of a for loop, the block should already have been marked as a
+        // block when the `for` keyword is encountered.
+        if (LBraceStack.back().ProbablyLambda)
+          break;
+        if (LBraceStack.size() >= 2 &&
+            LBraceStack.end()[-2].Tok->is(BK_Unknown)) {
+          LBraceStack.end()[-2].Tok->setBlockKind(BK_Block);
+        }
+        break;
+      case BK_BracedInit:
+        break;
       }
       LBraceStack.pop_back();
       break;
     case tok::identifier:
+      if (Style.isJavaScript() && Tok->is(Keywords.kw_function)) {
+        ProbablyLambda = true;
+        break;
+      }
       if (!Tok->is(TT_StatementMacro))
         break;
       [[fallthrough]];
@@ -615,8 +651,12 @@
     case tok::kw_switch:
     case tok::kw_try:
     case tok::kw___try:
-      if (!LBraceStack.empty() && LBraceStack.back()->is(BK_Unknown))
-        LBraceStack.back()->setBlockKind(BK_Block);
+      ProbablyLambda = false;
+      if (!LBraceStack.empty() && LBraceStack.back().Tok->is(BK_Unknown))
+        LBraceStack.back().Tok->setBlockKind(BK_Block);
+      break;
+    case tok::l_square:
+      ProbablyLambda = true;
       break;
     default:
       break;
@@ -626,9 +666,9 @@
   } while (Tok->isNot(tok::eof) && !LBraceStack.empty());
 
   // Assume other blocks for all unclosed opening braces.
-  for (FormatToken *LBrace : LBraceStack)
-    if (LBrace->is(BK_Unknown))
-      LBrace->setBlockKind(BK_Block);
+  for (auto Entry : LBraceStack)
+    if (Entry.Tok->is(BK_Unknown))
+      Entry.Tok->setBlockKind(BK_Block);
 
   FormatTok = Tokens->setPosition(StoredPosition);
 }
_______________________________________________
cfe-commits mailing list
cfe-commits@lists.llvm.org
https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits

Reply via email to