From 1fcbe675faf60f0ace39c879e423f17bae4e2947 Mon Sep 17 00:00:00 2001 From: Manuel Klimek Date: Fri, 11 Apr 2014 12:27:47 +0000 Subject: [PATCH] Correctly handle escaped newlines when the next token starts without a space. We will need this to correctly handle conflict markers inside macro definitions. llvm-svn: 206029 --- clang/lib/Format/Format.cpp | 4 +++- clang/lib/Format/TokenAnnotator.cpp | 2 +- clang/lib/Format/UnwrappedLineParser.cpp | 13 +++++++++---- clang/lib/Format/UnwrappedLineParser.h | 1 + 4 files changed, 14 insertions(+), 6 deletions(-) diff --git a/clang/lib/Format/Format.cpp b/clang/lib/Format/Format.cpp index 4075ccdc8cfd..95ae7b56dc41 100644 --- a/clang/lib/Format/Format.cpp +++ b/clang/lib/Format/Format.cpp @@ -913,6 +913,8 @@ private: 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 @@ private: // 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); diff --git a/clang/lib/Format/TokenAnnotator.cpp b/clang/lib/Format/TokenAnnotator.cpp index df5603b26825..174a7fa20228 100644 --- a/clang/lib/Format/TokenAnnotator.cpp +++ b/clang/lib/Format/TokenAnnotator.cpp @@ -1511,7 +1511,7 @@ bool TokenAnnotator::mustBreakBefore(const AnnotatedLine &Line, 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; diff --git a/clang/lib/Format/UnwrappedLineParser.cpp b/clang/lib/Format/UnwrappedLineParser.cpp index 8d951bb8c627..004c83648309 100644 --- a/clang/lib/Format/UnwrappedLineParser.cpp +++ b/clang/lib/Format/UnwrappedLineParser.cpp @@ -1358,13 +1358,18 @@ void UnwrappedLineParser::addUnwrappedLine() { 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::flushComments(bool NewlineBeforeNext) { void UnwrappedLineParser::nextToken() { if (eof()) return; - flushComments(FormatTok->NewlinesBefore > 0); + flushComments(isOnNewLine(*FormatTok)); pushToken(FormatTok); readToken(); } @@ -1398,7 +1403,7 @@ void UnwrappedLineParser::readToken() { // 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 @@ void UnwrappedLineParser::readToken() { if (!FormatTok->Tok.is(tok::comment)) return; - if (FormatTok->NewlinesBefore > 0 || FormatTok->IsFirst) { + if (isOnNewLine(*FormatTok) || FormatTok->IsFirst) { CommentsInCurrentLine = false; } if (CommentsInCurrentLine) { diff --git a/clang/lib/Format/UnwrappedLineParser.h b/clang/lib/Format/UnwrappedLineParser.h index 62e0b58ea13b..6eaa415b6b81 100644 --- a/clang/lib/Format/UnwrappedLineParser.h +++ b/clang/lib/Format/UnwrappedLineParser.h @@ -108,6 +108,7 @@ private: 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