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
[email protected]
http://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits