yawanng created this revision.
yawanng added a project: clang-tools-extra.
Herald added a subscriber: klimek.

Add handling for Structured binding declaration in C++17 in clang-format. For 
example:
auto [x,y] = a; 
auto &[xr, yr] = a; 
auto &&[xrr, yrr] = a;


https://reviews.llvm.org/D35743

Files:
  lib/Format/TokenAnnotator.cpp
  lib/Format/UnwrappedLineParser.cpp
  test/Format/structured-binding-declaration.cpp

Index: test/Format/structured-binding-declaration.cpp
===================================================================
--- /dev/null
+++ test/Format/structured-binding-declaration.cpp
@@ -0,0 +1,54 @@
+// RUN: grep -Ev "// *[A-Z-]+:" %s | clang-format -style=LLVM \
+// RUN:   | FileCheck -strict-whitespace %s
+
+// CHECK: {{^auto\ \[x,\ y\]\ =\ a;}}
+auto[x, y] = a;
+// CHECK: {{^auto\ \&\[x,\ y\]\ =\ a;}}
+auto   &   [x, y] = a;
+// CHECK: {{^auto\ \&\&\[x,\ y\]\ =\ a;}}
+auto &&   [x, y] = a;
+
+// CHECK: {{^auto\ \[x\]\ =\ a;}}
+auto[x] = a;
+// CHECK: {{^auto\ \&\[x\]\ =\ a;}}
+auto   &   [x] = a;
+// CHECK: {{^auto\ \&\&\[x\]\ =\ a;}}
+auto &&   [x] = a;
+
+// CHECK: {{^const\ auto\ \[x,\ y\]\ =\ f\(\);}}
+const auto[x, y] = f();
+// CHECK: {{^const\ auto\ \&\[x,\ y\]\ =\ f\(\);}}
+const auto &   [x, y] = f();
+// CHECK: {{^const\ auto\ \&\&\[x,\ y\]\ =\ f\(\);}}
+const auto &&    [x, y] = f();
+
+// CHECK: {{^auto\ \[x,\ y\]\ =\ A\{\};}}
+auto[x,y] = A{};
+// CHECK: {{^auto\ \&\[x,\ y\]\ =\ A\{\};}}
+auto   &   [x,y] = A{};
+// CHECK: {{^auto\ \&\&\[x,\ y\]\ =\ A\{\};}}
+auto   &&   [x,y] = A{};
+
+// CHECK: {{^for\ \(const\ auto\ \&\&\[a,\ b\]\ :\ some_range\)\ \{}}
+for (const auto   &&   [a, b] : some_range) {
+}
+// CHECK: {{^for\ \(const\ auto\ \&\[a,\ b\]\ :\ some_range\)\ \{}}
+for (const auto   &    [a, b] : some_range) {
+}
+// CHECK: {{^for\ \(const\ auto\ \[a,\ b\]\ :\ some_range\)\ \{}}
+for (const auto[a, b] : some_range) {
+}
+
+// CHECK: {{^auto\ \[x,\ y\]\(expr\);}}
+auto[x,y]  (expr);
+// CHECK: {{^auto\ \&\[x,\ y\]\(expr\);}}
+auto   &   [x,y]    (expr);
+// CHECK: {{^auto\ \&\&\[x,\ y\]\(expr\);}}
+auto   &&   [x,y]    (expr);
+
+// CHECK: {{^auto\ \[x,\ y\]\{expr\};}}
+auto[x,y]     {expr};
+// CHECK: {{^auto\ \&\[x,\ y\]\{expr\};}}
+auto   &   [x,y]  {expr};
+// CHECK: {{^auto\ \&\&\[x,\ y\]\{expr\};}}
+auto   &&   [x,y]     {expr};
Index: lib/Format/UnwrappedLineParser.cpp
===================================================================
--- lib/Format/UnwrappedLineParser.cpp
+++ lib/Format/UnwrappedLineParser.cpp
@@ -1213,7 +1213,7 @@
   const FormatToken* Previous = getPreviousToken();
   if (Previous &&
       (Previous->isOneOf(tok::identifier, tok::kw_operator, tok::kw_new,
-                         tok::kw_delete) ||
+                         tok::kw_delete, tok::kw_auto, tok::ampamp, tok::amp) ||
        Previous->closesScope() || Previous->isSimpleTypeSpecifier())) {
     nextToken();
     return false;
Index: lib/Format/TokenAnnotator.cpp
===================================================================
--- lib/Format/TokenAnnotator.cpp
+++ lib/Format/TokenAnnotator.cpp
@@ -330,8 +330,12 @@
         (Contexts.back().CanBeExpression || Contexts.back().IsExpression ||
          Contexts.back().InTemplateArgument);
 
+    bool CppStructuredBindingDecl =
+        !CppArrayTemplates && Style.isCpp() && Parent &&
+        Parent->isOneOf(tok::kw_auto, tok::amp, tok::ampamp);
+
     bool StartsObjCMethodExpr =
-        !CppArrayTemplates && Style.isCpp() &&
+        !CppStructuredBindingDecl && !CppArrayTemplates && Style.isCpp() &&
         Contexts.back().CanBeExpression && Left->isNot(TT_LambdaLSquare) &&
         CurrentToken->isNot(tok::l_brace) &&
         (!Parent ||
@@ -344,7 +348,10 @@
 
     unsigned BindingIncrease = 1;
     if (Left->is(TT_Unknown)) {
-      if (StartsObjCMethodExpr) {
+      if (CppStructuredBindingDecl) {
+        Left->Type = Parent->is(tok::kw_auto) ? TT_DesignatedInitializerLSquare
+                                              : TT_ArraySubscriptLSquare;
+      } else if (StartsObjCMethodExpr) {
         Left->Type = TT_ObjCMethodExpr;
       } else if (Style.Language == FormatStyle::LK_JavaScript && Parent &&
                  Contexts.back().ContextKind == tok::l_brace &&
_______________________________________________
cfe-commits mailing list
cfe-commits@lists.llvm.org
http://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits

Reply via email to