diff --git a/clang/lib/Format/TokenAnnotator.cpp b/clang/lib/Format/TokenAnnotator.cpp index a6c6ddcad117b..72f49478d5b4b 100644 --- a/clang/lib/Format/TokenAnnotator.cpp +++ b/clang/lib/Format/TokenAnnotator.cpp @@ -3134,7 +3134,15 @@ bool TokenAnnotator::spaceRequiredBetween(const AnnotatedLine &Line, return false; if (getTokenPointerOrReferenceAlignment(Left) == FormatStyle::PAS_Right) return false; - if (Line.IsMultiVariableDeclStmt) + // FIXME: Setting IsMultiVariableDeclStmt for the whole line is error-prone, + // because it does not take into account nested scopes like lambdas. + // In multi-variable declaration statements, attach */& to the variable + // independently of the style. However, avoid doing it if we are in a nested + // scope, e.g. lambda. We still need to special-case statements with + // initializers. + if (Line.IsMultiVariableDeclStmt && + (Left.NestingLevel == Line.First->NestingLevel || + startsWithInitStatement(Line))) return false; return Left.Previous && !Left.Previous->isOneOf( tok::l_paren, tok::coloncolon, tok::l_square); diff --git a/clang/unittests/Format/FormatTest.cpp b/clang/unittests/Format/FormatTest.cpp index fc2b121faee02..689600c591b26 100644 --- a/clang/unittests/Format/FormatTest.cpp +++ b/clang/unittests/Format/FormatTest.cpp @@ -2031,6 +2031,10 @@ TEST_F(FormatTest, SeparatePointerReferenceAlignment) { verifyFormat("for (int x = 0; int &c : {1, 2, 3})", Style); verifyFormat("for (f(); auto &c : {1, 2, 3})", Style); verifyFormat("for (f(); int &c : {1, 2, 3})", Style); + verifyFormat( + "function res1 = [](int &a) { return 0000000000000; },\n" + " res2 = [](int &a) { return 0000000000000; };", + Style); Style.AlignConsecutiveDeclarations = FormatStyle::ACS_Consecutive; verifyFormat("Const unsigned int *c;\n" @@ -2068,6 +2072,10 @@ TEST_F(FormatTest, SeparatePointerReferenceAlignment) { verifyFormat("for (int x = 0; int& c : {1, 2, 3})", Style); verifyFormat("for (f(); auto& c : {1, 2, 3})", Style); verifyFormat("for (f(); int& c : {1, 2, 3})", Style); + verifyFormat( + "function res1 = [](int& a) { return 0000000000000; },\n" + " res2 = [](int& a) { return 0000000000000; };", + Style); Style.AlignConsecutiveDeclarations = FormatStyle::ACS_Consecutive; verifyFormat("Const unsigned int* c;\n" @@ -2121,6 +2129,10 @@ TEST_F(FormatTest, SeparatePointerReferenceAlignment) { verifyFormat("for (int x = 0; int & c : {1, 2, 3})", Style); verifyFormat("for (f(); auto & c : {1, 2, 3})", Style); verifyFormat("for (f(); int & c : {1, 2, 3})", Style); + verifyFormat( + "function res1 = [](int & a) { return 0000000000000; },\n" + " res2 = [](int & a) { return 0000000000000; };", + Style); Style.AlignConsecutiveDeclarations = FormatStyle::ACS_Consecutive; verifyFormat("Const unsigned int* c;\n"