Index: lib/Format/Format.cpp =================================================================== --- lib/Format/Format.cpp +++ lib/Format/Format.cpp @@ -913,6 +913,8 @@ Newlines = std::min(Newlines, 1u); if (Newlines == 0 && !RootToken.IsFirst) Newlines = 1; + if (RootToken.IsFirst && !RootToken.HasUnescapedNewline) + Newlines = 0; // Remove empty lines after "{". if (!Style.KeepEmptyLinesAtTheStartOfBlocks && PreviousLine && @@ -1329,7 +1331,7 @@ // FIXME: Add a more explicit test. while (FormatTok->TokenText.size() > 1 && FormatTok->TokenText[0] == '\\' && FormatTok->TokenText[1] == '\n') { - // FIXME: ++FormatTok->NewlinesBefore is missing... + ++FormatTok->NewlinesBefore; WhitespaceLength += 2; Column = 0; FormatTok->TokenText = FormatTok->TokenText.substr(2); Index: lib/Format/TokenAnnotator.cpp =================================================================== --- lib/Format/TokenAnnotator.cpp +++ lib/Format/TokenAnnotator.cpp @@ -1511,7 +1511,7 @@ if (Right.is(tok::comment)) { return Right.Previous->BlockKind != BK_BracedInit && Right.Previous->Type != TT_CtorInitializerColon && - Right.NewlinesBefore > 0; + (Right.NewlinesBefore > 0 && Right.HasUnescapedNewline); } else if (Right.Previous->isTrailingComment() || (Right.isStringLiteral() && Right.Previous->isStringLiteral())) { return true; Index: lib/Format/UnwrappedLineParser.h =================================================================== --- lib/Format/UnwrappedLineParser.h +++ lib/Format/UnwrappedLineParser.h @@ -108,6 +108,7 @@ void pushToken(FormatToken *Tok); void calculateBraceTypes(); void pushPPConditional(); + bool isOnNewLine(const FormatToken& FormatTok); // FIXME: We are constantly running into bugs where Line.Level is incorrectly // subtracted from beyond 0. Introduce a method to subtract from Line.Level Index: lib/Format/UnwrappedLineParser.cpp =================================================================== --- lib/Format/UnwrappedLineParser.cpp +++ lib/Format/UnwrappedLineParser.cpp @@ -1358,13 +1358,18 @@ bool UnwrappedLineParser::eof() const { return FormatTok->Tok.is(tok::eof); } +bool UnwrappedLineParser::isOnNewLine(const FormatToken& FormatTok) { + return (Line->InPPDirective || FormatTok.HasUnescapedNewline) && + FormatTok.NewlinesBefore > 0; +} + void UnwrappedLineParser::flushComments(bool NewlineBeforeNext) { bool JustComments = Line->Tokens.empty(); for (SmallVectorImpl::const_iterator I = CommentsBeforeNextToken.begin(), E = CommentsBeforeNextToken.end(); I != E; ++I) { - if ((*I)->NewlinesBefore && JustComments) { + if (isOnNewLine(**I) && JustComments) { addUnwrappedLine(); } pushToken(*I); @@ -1378,7 +1383,7 @@ void UnwrappedLineParser::nextToken() { if (eof()) return; - flushComments(FormatTok->NewlinesBefore > 0); + flushComments(isOnNewLine(*FormatTok)); pushToken(FormatTok); readToken(); } @@ -1398,7 +1403,7 @@ // Comments stored before the preprocessor directive need to be output // before the preprocessor directive, at the same level as the // preprocessor directive, as we consider them to apply to the directive. - flushComments(FormatTok->NewlinesBefore > 0); + flushComments(isOnNewLine(*FormatTok)); parsePPDirective(); } @@ -1409,7 +1414,7 @@ if (!FormatTok->Tok.is(tok::comment)) return; - if (FormatTok->NewlinesBefore > 0 || FormatTok->IsFirst) { + if (isOnNewLine(*FormatTok) || FormatTok->IsFirst) { CommentsInCurrentLine = false; } if (CommentsInCurrentLine) {