Index: lib/Format/BreakableToken.cpp =================================================================== --- lib/Format/BreakableToken.cpp +++ lib/Format/BreakableToken.cpp @@ -695,7 +695,7 @@ Content[i] = Content[i].substr(0, EndOfLine); } LineTok = CurrentTok->Next; - if (CurrentTok->Next && CurrentTok->Next->NewlinesBefore > 1) { + if (CurrentTok->Next && !CurrentTok->Next->ContinuesLineCommentSection) { // A line comment section needs to broken by a line comment that is // preceded by at least two newlines. Note that we put this break here // instead of breaking at a previous stage during parsing, since that Index: lib/Format/FormatToken.h =================================================================== --- lib/Format/FormatToken.h +++ lib/Format/FormatToken.h @@ -261,6 +261,11 @@ /// Only set if \c Type == \c TT_StartOfName. bool PartOfMultiVariableDeclStmt = false; + /// \brief Does this line comment continue a line comment section? + /// + /// Only set to true if \c Type == \c TT_LineComment. + bool ContinuesLineCommentSection = false; + /// \brief If this is a bracket, this points to the matching one. FormatToken *MatchingParen = nullptr; Index: lib/Format/UnwrappedLineParser.cpp =================================================================== --- lib/Format/UnwrappedLineParser.cpp +++ lib/Format/UnwrappedLineParser.cpp @@ -2066,31 +2066,58 @@ // 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 // // second line + // // and: + // // // first line // // second line + // // and: + // // int i; // first line // // second line + // // and: + // // do { // first line // // second line // int i; // } while (true); // + // and: + // + // enum { + // a, // first line + // // second line + // b + // }; + // // The second line comment doesn't continue the first in these cases: + // // // first line // // second line + // // and: + // // int i; // first line // // second line + // // and: + // // do { // first line // // second line // int i; // } while (true); + // + // and: + // + // enum { + // a, // first line + // // second line + // }; const FormatToken *MinColumnToken = Line.Tokens.front().Tok; // Scan for '{//'. If found, use the column of '{' as a min column for line @@ -2103,6 +2130,11 @@ break; } PreviousToken = Node.Tok; + + // Grab the last newline preceding a token in this unwrapped line. + if (Node.Tok->NewlinesBefore > 0) { + MinColumnToken = Node.Tok; + } } if (PreviousToken && PreviousToken->is(tok::l_brace)) { MinColumnToken = PreviousToken; @@ -2130,7 +2162,8 @@ // // FIXME: Consider putting separate line comment sections as children to the // unwrapped line instead. - if (isOnNewLine(**I) && JustComments && !continuesLineComment(**I, *Line)) + (*I)->ContinuesLineCommentSection = continuesLineComment(**I, *Line); + if (isOnNewLine(**I) && JustComments && !(*I)->ContinuesLineCommentSection) addUnwrappedLine(); pushToken(*I); } @@ -2196,7 +2229,9 @@ if (!FormatTok->Tok.is(tok::comment)) return; - if (!continuesLineComment(*FormatTok, *Line) && + FormatTok->ContinuesLineCommentSection = + continuesLineComment(*FormatTok, *Line); + if (!FormatTok->ContinuesLineCommentSection && (isOnNewLine(*FormatTok) || FormatTok->IsFirst)) { CommentsInCurrentLine = false; } Index: unittests/Format/FormatTest.cpp =================================================================== --- unittests/Format/FormatTest.cpp +++ unittests/Format/FormatTest.cpp @@ -951,7 +951,28 @@ " c\n" "};", getLLVMStyleWithColumns(20))); - + EXPECT_EQ("enum A {\n" + " a, // line 1\n" + " // line 2\n" + " b\n" + "};", + format("enum A {\n" + " a, // line 1\n" + " // line 2\n" + " b\n" + "};", + getLLVMStyleWithColumns(20))); + EXPECT_EQ("enum A {\n" + " a, // line 1\n" + " // line 2\n" + " b\n" + "};", + format("enum A {\n" + " a, // line 1\n" + " // line 2\n" + " b\n" + "};", + getLLVMStyleWithColumns(20))); verifyFormat( "aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa =\n" " bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb; // Trailing comment");