Index: lib/Format/UnwrappedLineParser.cpp =================================================================== --- lib/Format/UnwrappedLineParser.cpp +++ lib/Format/UnwrappedLineParser.cpp @@ -2051,14 +2051,19 @@ const UnwrappedLine &Line) { if (Line.Tokens.empty()) return false; - const FormatToken &FirstLineTok = *Line.Tokens.front().Tok; + // If Line starts with a line comment, then FormatTok continues the comment - // section if its original column is greater or equal to the original start + // section if its original column is greater or equal to the original start // column of the line. // - // If Line starts with a a different token, then FormatTok continues the - // comment section if its original column greater than the original start - // column of the line. + // Define the min column token of a line as follows: if a line ends in '{' or + // contains a '{' followed by a line comment, then the min column token is + // that '{'. Otherwise, the min column token of the line is the first token of + // the line. + // + // If Line starts with a token other than a line comment, then FormatTok + // continues the comment section if its original column is greater than the + // original start column of the min column token of the line. // // For example, the second line comment continues the first in these cases: // // first line @@ -2069,6 +2074,11 @@ // and: // int i; // first line // // second line + // and: + // do { // first line + // // second line + // int i; + // } while (true); // // The second line comment doesn't continue the first in these cases: // // first line @@ -2076,9 +2086,31 @@ // and: // int i; // first line // // second line + // and: + // do { // first line + // // second line + // int i; + // } while (true); + const FormatToken *MinColumnToken = Line.Tokens.front().Tok; + + // Scan for '{//'. If found, use the column of '{' as a min column for line + // comment section continuation. + const FormatToken *PreviousToken = nullptr; + for (const UnwrappedLineNode Node : Line.Tokens) { + if (PreviousToken && PreviousToken->is(tok::l_brace) && + isLineComment(*Node.Tok)) { + MinColumnToken = PreviousToken; + break; + } + PreviousToken = Node.Tok; + } + if (PreviousToken && PreviousToken->is(tok::l_brace)) { + MinColumnToken = PreviousToken; + } + unsigned MinContinueColumn = - FirstLineTok.OriginalColumn + - ((isLineComment(FirstLineTok) && !FirstLineTok.Next) ? 0 : 1); + MinColumnToken->OriginalColumn + + (isLineComment(*MinColumnToken) ? 0 : 1); return isLineComment(FormatTok) && FormatTok.NewlinesBefore == 1 && isLineComment(*(Line.Tokens.back().Tok)) && FormatTok.OriginalColumn >= MinContinueColumn; Index: unittests/Format/FormatTest.cpp =================================================================== --- unittests/Format/FormatTest.cpp +++ unittests/Format/FormatTest.cpp @@ -1783,6 +1783,64 @@ " 0x00, 0x00, 0x00, 0x00}; // comment\n"); } +TEST_F(FormatTest, LineCommentsAfterRightBrace) { + EXPECT_EQ("if (true) { // comment about branch\n" + " // comment about f\n" + " f();\n" + "}", + format("if (true) { // comment about branch\n" + " // comment about f\n" + " f();\n" + "}", + getLLVMStyleWithColumns(80))); + EXPECT_EQ("if (1) { // if line 1\n" + " // if line 2\n" + " // if line 3\n" + " // f line 1\n" + " // f line 2\n" + " f();\n" + "} else { // else line 1\n" + " // else line 2\n" + " // else line 3\n" + " // g line 1\n" + " g();\n" + "}", + format("if (1) { // if line 1\n" + " // if line 2\n" + " // if line 3\n" + " // f line 1\n" + " // f line 2\n" + " f();\n" + "} else { // else line 1\n" + " // else line 2\n" + " // else line 3\n" + " // g line 1\n" + " g();\n" + "}")); + EXPECT_EQ("do { // line 1\n" + " // line 2\n" + " // line 3\n" + " f();\n" + "} while (true);", + format("do { // line 1\n" + " // line 2\n" + " // line 3\n" + " f();\n" + "} while (true);", + getLLVMStyleWithColumns(80))); + EXPECT_EQ("while (a < b) { // line 1\n" + " // line 2\n" + " // line 3\n" + " f();\n" + "}", + format("while (a < b) {// line 1\n" + " // line 2\n" + " // line 3\n" + " f();\n" + "}", + getLLVMStyleWithColumns(80))); +} + TEST_F(FormatTest, ReflowsComments) { // Break a long line and reflow with the full next line. EXPECT_EQ("// long long long\n"