Index: lib/Format/TokenAnnotator.cpp =================================================================== --- lib/Format/TokenAnnotator.cpp +++ lib/Format/TokenAnnotator.cpp @@ -353,10 +353,10 @@ bool ColonFound = false; unsigned BindingIncrease = 1; - if (Left->is(TT_Unknown)) { - if (isCppStructuredBinding(Left)) { - Left->Type = TT_StructuredBindingLSquare; - } else if (StartsObjCMethodExpr) { + if (isCppStructuredBinding(Left)) { + Left->Type = TT_StructuredBindingLSquare; + } else if (Left->is(TT_Unknown)) { + if (StartsObjCMethodExpr) { Left->Type = TT_ObjCMethodExpr; } else if (Style.Language == FormatStyle::LK_JavaScript && Parent && Contexts.back().ContextKind == tok::l_brace && @@ -2193,6 +2193,10 @@ bool TokenAnnotator::spaceRequiredBetween(const AnnotatedLine &Line, const FormatToken &Left, const FormatToken &Right) { + if (Right.is(TT_StructuredBindingLSquare)) + return true; + if (Right.Next && Right.Next->is(TT_StructuredBindingLSquare)) + return false; if (Left.is(tok::kw_return) && Right.isNot(tok::semi)) return true; if (Style.ObjCSpaceAfterProperty && Line.Type == LT_ObjCProperty && @@ -2522,7 +2526,8 @@ tok::kw___super, TT_TemplateCloser, TT_TemplateOpener)); if ((Left.is(TT_TemplateOpener)) != (Right.is(TT_TemplateCloser))) return Style.SpacesInAngles; - if ((Right.is(TT_BinaryOperator) && !Left.is(tok::l_paren)) || + if ((Right.is(TT_BinaryOperator) && !Left.is(tok::l_paren) && + !(Right.Next && Right.Next->is(TT_StructuredBindingLSquare))) || (Left.isOneOf(TT_BinaryOperator, TT_ConditionalExpr) && !Right.is(tok::r_paren))) return true; Index: unittests/Format/FormatTest.cpp =================================================================== --- unittests/Format/FormatTest.cpp +++ unittests/Format/FormatTest.cpp @@ -11577,19 +11577,43 @@ EXPECT_EQ("auto const volatile [a, b] = f();", format("auto const volatile[a, b] = f();")); EXPECT_EQ("auto [a, b, c] = f();", format("auto [ a , b,c ] = f();")); - EXPECT_EQ("auto & [a, b, c] = f();", + EXPECT_EQ("auto& [a, b, c] = f();", format("auto &[ a , b,c ] = f();")); - EXPECT_EQ("auto && [a, b, c] = f();", + EXPECT_EQ("auto&& [a, b, c] = f();", format("auto &&[ a , b,c ] = f();")); - EXPECT_EQ("auto const & [a, b] = f();", format("auto const&[a, b] = f();")); - EXPECT_EQ("auto const volatile && [a, b] = f();", + EXPECT_EQ("auto const& [a, b] = f();", format("auto const&[a, b] = f();")); + EXPECT_EQ("auto const volatile&& [a, b] = f();", format("auto const volatile &&[a, b] = f();")); - EXPECT_EQ("auto && [a, b] = f();", format("auto &&[a, b] = f();")); + EXPECT_EQ("auto const&& [a, b] = f();", format("auto const && [a, b] = f();")); + EXPECT_EQ("const auto& [a, b] = f();", format("const auto & [a, b] = f();")); + EXPECT_EQ("const auto volatile&& [a, b] = f();", + format("const auto volatile &&[a, b] = f();")); + EXPECT_EQ("volatile const auto&& [a, b] = f();", + format("volatile const auto &&[a, b] = f();")); + EXPECT_EQ("const auto&& [a, b] = f();", format("const auto && [a, b] = f();")); + + 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 const& [x, y](expr);", format("auto const & [x,y] (expr);")); + EXPECT_EQ("auto const&& [x, y](expr);", format("auto const && [x,y] (expr);")); + EXPECT_EQ("auto [x, y] { expr };", format("auto[x,y] {expr};")); + EXPECT_EQ("auto const& [x, y] { expr };", format("auto const & [x,y] {expr};")); + EXPECT_EQ("auto const&& [x, y] { expr };", format("auto const && [x,y] {expr};")); format::FormatStyle Spaces = format::getLLVMStyle(); Spaces.SpacesInSquareBrackets = true; verifyFormat("auto [ a, b ] = f();", Spaces); - verifyFormat("auto && [ a, b ] = f();", Spaces); + verifyFormat("auto&& [ a, b ] = f();", Spaces); + verifyFormat("auto& [ a, b ] = f();", Spaces); + verifyFormat("auto const&& [ a, b ] = f();", Spaces); + verifyFormat("auto const& [ a, b ] = f();", Spaces); } } // end namespace