yawanng updated this revision to Diff 110640.
yawanng added a comment.

Show full context.


https://reviews.llvm.org/D35743

Files:
  lib/Format/TokenAnnotator.cpp
  lib/Format/UnwrappedLineParser.cpp
  lib/Format/UnwrappedLineParser.h
  unittests/Format/FormatTest.cpp

Index: unittests/Format/FormatTest.cpp
===================================================================
--- unittests/Format/FormatTest.cpp
+++ unittests/Format/FormatTest.cpp
@@ -11085,6 +11085,41 @@
   EXPECT_EQ("auto c = u8'a';", format("auto c = u8'a';"));
 }
 
+TEST_F(FormatTest, StructuredBindingDeclaration) {
+  // structured-binding-declaration is a C++17 feature.
+  EXPECT_EQ("auto [x, y] = a;", format("auto[x, y] = a;"));
+  EXPECT_EQ("auto &[x, y] = a;", format("auto   &   [x, y] = a;"));
+  EXPECT_EQ("auto &&[x, y] = a;", format("auto &&   [x, y] = a;"));
+  EXPECT_EQ("auto &&[x, y] = a;", format("auto &&   [x, y] = a;"));
+  EXPECT_EQ("auto [x] = a;", format("auto[x] = a;"));
+  EXPECT_EQ("auto &[x] = a;", format("auto   &   [x] = a;"));
+  EXPECT_EQ("auto &&[x] = a;", format("auto &&   [x] = a;"));
+  EXPECT_EQ("const auto [x, y] = f();", format("const auto[x, y] = f();"));
+  EXPECT_EQ("const auto &[x, y] = f();", format("const auto  &   [x, y] = f();"));
+  EXPECT_EQ("const auto &&[x, y] = f();", format("const auto  &&   [x, y] = f();"));
+  EXPECT_EQ("auto [x, y] = A{};", format("auto[x,y] = A{};"));
+  EXPECT_EQ("auto &[x, y] = A{};", format("auto   &   [x,y] = A{};"));
+  EXPECT_EQ("auto &&[x, y] = A{};", format("auto   &&   [x,y] = A{};"));
+  EXPECT_EQ("for (const auto &&[a, b] : some_range) {\n"
+            "}",
+            format("for (const auto   &&   [a, b] : some_range) {\n"
+                        "}"));
+  EXPECT_EQ("for (const auto &[a, b] : some_range) {\n"
+            "}",
+            format("for (const auto   &   [a, b] : some_range) {\n"
+                        "}"));
+  EXPECT_EQ("for (const auto [a, b] : some_range) {\n"
+            "}",
+            format("for (const auto[a, b] : some_range) {\n"
+                        "}"));
+  EXPECT_EQ("auto [x, y](expr);", format("auto[x,y]  (expr);"));
+  EXPECT_EQ("auto &[x, y](expr);", format("auto   &   [x,y]    (expr);"));
+  EXPECT_EQ("auto &&[x, y](expr);", format("auto   &&   [x,y]    (expr);"));
+  EXPECT_EQ("auto [x, y]{expr};", format("auto[x,y]     {expr};"));
+  EXPECT_EQ("auto &[x, y]{expr};", format("auto   &   [x,y]  {expr};"));
+  EXPECT_EQ("auto &&[x, y]{expr};", format("auto   &&   [x,y]  {expr};"));
+}
+
 } // end namespace
 } // end namespace format
 } // end namespace clang
Index: lib/Format/UnwrappedLineParser.h
===================================================================
--- lib/Format/UnwrappedLineParser.h
+++ lib/Format/UnwrappedLineParser.h
@@ -125,6 +125,7 @@
   bool eof() const;
   void nextToken();
   const FormatToken *getPreviousToken();
+  const FormatToken *getPrePreviousToken();
   void readToken();
 
   // Decides which comment tokens should be added to the current line and which
Index: lib/Format/UnwrappedLineParser.cpp
===================================================================
--- lib/Format/UnwrappedLineParser.cpp
+++ lib/Format/UnwrappedLineParser.cpp
@@ -1211,9 +1211,12 @@
     return false;
   }
   const FormatToken* Previous = getPreviousToken();
+  const FormatToken* PrePrevious = getPrePreviousToken();
   if (Previous &&
       (Previous->isOneOf(tok::identifier, tok::kw_operator, tok::kw_new,
-                         tok::kw_delete) ||
+                         tok::kw_delete, tok::kw_auto) ||
+       (PrePrevious && Previous->isOneOf(tok::amp, tok::ampamp) &&
+        PrePrevious->is(tok::kw_auto)) ||
        Previous->closesScope() || Previous->isSimpleTypeSpecifier())) {
     nextToken();
     return false;
@@ -2306,6 +2309,12 @@
   return Line->Tokens.back().Tok;
 }
 
+const FormatToken *UnwrappedLineParser::getPrePreviousToken() {
+  if (!Line || Line->Tokens.size() < 2)
+    return nullptr;
+  return std::prev(Line->Tokens.end(), 2)->Tok;
+}
+
 void UnwrappedLineParser::distributeComments(
     const SmallVectorImpl<FormatToken *> &Comments,
     const FormatToken *NextTok) {
Index: lib/Format/TokenAnnotator.cpp
===================================================================
--- lib/Format/TokenAnnotator.cpp
+++ lib/Format/TokenAnnotator.cpp
@@ -330,8 +330,15 @@
         (Contexts.back().CanBeExpression || Contexts.back().IsExpression ||
          Contexts.back().InTemplateArgument);
 
+    bool CppStructuredBindingDecl =
+        !CppArrayTemplates && Style.isCpp() && Parent &&
+        (Parent->is(tok::kw_auto) ||
+         (Parent->isOneOf(tok::amp, tok::ampamp) &&
+          Parent->getPreviousNonComment() &&
+          Parent->getPreviousNonComment()->is(tok::kw_auto)));
+
     bool StartsObjCMethodExpr =
-        !CppArrayTemplates && Style.isCpp() &&
+        !CppStructuredBindingDecl && !CppArrayTemplates && Style.isCpp() &&
         Contexts.back().CanBeExpression && Left->isNot(TT_LambdaLSquare) &&
         CurrentToken->isNot(tok::l_brace) &&
         (!Parent ||
@@ -344,7 +351,9 @@
 
     unsigned BindingIncrease = 1;
     if (Left->is(TT_Unknown)) {
-      if (StartsObjCMethodExpr) {
+      if (CppStructuredBindingDecl) {
+        Left->Type = TT_ArraySubscriptLSquare;
+      } else if (StartsObjCMethodExpr) {
         Left->Type = TT_ObjCMethodExpr;
       } else if (Style.Language == FormatStyle::LK_JavaScript && Parent &&
                  Contexts.back().ContextKind == tok::l_brace &&
@@ -2150,6 +2159,8 @@
 bool TokenAnnotator::spaceRequiredBetween(const AnnotatedLine &Line,
                                           const FormatToken &Left,
                                           const FormatToken &Right) {
+  if (Left.is(tok::kw_auto) && Right.is(TT_ArraySubscriptLSquare))
+    return true;
   if (Left.is(tok::kw_return) && Right.isNot(tok::semi))
     return true;
   if (Style.ObjCSpaceAfterProperty && Line.Type == LT_ObjCProperty &&
_______________________________________________
cfe-commits mailing list
cfe-commits@lists.llvm.org
http://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits

Reply via email to