diff --git a/clang/lib/Format/Format.cpp b/clang/lib/Format/Format.cpp --- a/clang/lib/Format/Format.cpp +++ b/clang/lib/Format/Format.cpp @@ -1417,22 +1417,29 @@ checkEmptyNamespace(AnnotatedLines); - for (auto &Line : AnnotatedLines) { - if (Line->Affected) { - cleanupRight(Line->First, tok::comma, tok::comma); - cleanupRight(Line->First, TT_CtorInitializerColon, tok::comma); - cleanupRight(Line->First, tok::l_paren, tok::comma); - cleanupLeft(Line->First, tok::comma, tok::r_paren); - cleanupLeft(Line->First, TT_CtorInitializerComma, tok::l_brace); - cleanupLeft(Line->First, TT_CtorInitializerColon, tok::l_brace); - cleanupLeft(Line->First, TT_CtorInitializerColon, tok::equal); - } - } + for (auto *Line : AnnotatedLines) + cleanupLine(Line); return {generateFixes(), 0}; } private: + void cleanupLine(AnnotatedLine *Line) { + for (auto *Child : Line->Children) { + cleanupLine(Child); + } + + if (Line->Affected) { + cleanupRight(Line->First, tok::comma, tok::comma); + cleanupRight(Line->First, TT_CtorInitializerColon, tok::comma); + cleanupRight(Line->First, tok::l_paren, tok::comma); + cleanupLeft(Line->First, tok::comma, tok::r_paren); + cleanupLeft(Line->First, TT_CtorInitializerComma, tok::l_brace); + cleanupLeft(Line->First, TT_CtorInitializerColon, tok::l_brace); + cleanupLeft(Line->First, TT_CtorInitializerColon, tok::equal); + } + } + bool containsOnlyComments(const AnnotatedLine &Line) { for (FormatToken *Tok = Line.First; Tok != nullptr; Tok = Tok->Next) { if (Tok->isNot(tok::comment)) diff --git a/clang/unittests/Format/CleanupTest.cpp b/clang/unittests/Format/CleanupTest.cpp --- a/clang/unittests/Format/CleanupTest.cpp +++ b/clang/unittests/Format/CleanupTest.cpp @@ -183,10 +183,15 @@ std::string Code = "int main() { f(,1,,2,3,f(1,2,),4,,);}"; std::string Expected = "int main() { f(1,2,3,f(1,2),4);}"; EXPECT_EQ(Expected, cleanupAroundOffsets({15, 18, 29, 33}, Code)); + + // Lambda contents are also checked for trailing commas. + Code = "int main() { [](){f(,1,,2,3,f(1,2,),4,,);}();}"; + Expected = "int main() { [](){f(1,2,3,f(1,2),4);}();}"; + EXPECT_EQ(Expected, cleanupAroundOffsets({20, 23, 34, 38}, Code)); } TEST_F(CleanupTest, TrailingCommaInBraces) { - // Trainling comma is allowed in brace list. + // Trailing comma is allowed in brace list. // If there was trailing comma in the original code, then trailing comma is // preserved. In this example, element between the last two commas is deleted // causing the second-last comma to be redundant. @@ -194,7 +199,7 @@ std::string Expected = "void f() { std::vector v = {1,2,3,}; }"; EXPECT_EQ(Expected, cleanupAroundOffsets({39}, Code)); - // If there was no trailing comma in the original code, then trainling comma + // If there was no trailing comma in the original code, then trailing comma // introduced by replacements should be cleaned up. In this example, the // element after the last comma is deleted causing the last comma to be // redundant.