diff options
Diffstat (limited to 'lib/Format')
-rw-r--r-- | lib/Format/Format.cpp | 22 | ||||
-rw-r--r-- | lib/Format/UnwrappedLineParser.cpp | 24 | ||||
-rw-r--r-- | lib/Format/UnwrappedLineParser.h | 12 |
3 files changed, 48 insertions, 10 deletions
diff --git a/lib/Format/Format.cpp b/lib/Format/Format.cpp index 60b2f56745..8ea95c4862 100644 --- a/lib/Format/Format.cpp +++ b/lib/Format/Format.cpp @@ -434,9 +434,21 @@ private: /// each \c FormatToken. void replaceWhitespace(const FormatToken &Tok, unsigned NewLines, unsigned Spaces) { + std::string NewLineText; + if (!Line.InPPDirective) { + NewLineText = std::string(NewLines, '\n'); + } else if (NewLines > 0) { + unsigned Offset = + SourceMgr.getSpellingColumnNumber(Tok.WhiteSpaceStart) - 1; + for (unsigned i = 0; i < NewLines; ++i) { + NewLineText += std::string(Style.ColumnLimit - Offset - 1, ' '); + NewLineText += "\\\n"; + Offset = 0; + } + } Replaces.insert(tooling::Replacement( SourceMgr, Tok.WhiteSpaceStart, Tok.WhiteSpaceLength, - std::string(NewLines, '\n') + std::string(Spaces, ' '))); + NewLineText + std::string(Spaces, ' '))); } /// \brief Add a new line and the required indent before the first Token @@ -634,6 +646,9 @@ public: next(); if (Index >= Tokens.size()) return; + // It is the responsibility of the UnwrappedLineParser to make sure + // this sequence is not produced inside an unwrapped line. + assert(Tokens[Index].Tok.getIdentifierInfo() != NULL); switch (Tokens[Index].Tok.getIdentifierInfo()->getPPKeywordID()) { case tok::pp_include: case tok::pp_import: @@ -969,7 +984,10 @@ public: // Consume and record whitespace until we find a significant token. while (FormatTok.Tok.is(tok::unknown)) { - FormatTok.NewlinesBefore += tokenText(FormatTok.Tok).count('\n'); + StringRef Text = tokenText(FormatTok.Tok); + FormatTok.NewlinesBefore += Text.count('\n'); + FormatTok.HasUnescapedNewline = + Text.count("\\\n") != FormatTok.NewlinesBefore; FormatTok.WhiteSpaceLength += FormatTok.Tok.getLength(); if (FormatTok.Tok.is(tok::eof)) diff --git a/lib/Format/UnwrappedLineParser.cpp b/lib/Format/UnwrappedLineParser.cpp index 78a1abdcf8..614125b943 100644 --- a/lib/Format/UnwrappedLineParser.cpp +++ b/lib/Format/UnwrappedLineParser.cpp @@ -80,13 +80,25 @@ bool UnwrappedLineParser::parseBlock(unsigned AddLevels) { } void UnwrappedLineParser::parsePPDirective() { - while (!eof()) { - nextToken(); - if (FormatTok.NewlinesBefore > 0) { - addUnwrappedLine(); - return; - } + assert(FormatTok.Tok.is(tok::hash) && "'#' expected"); + nextToken(); + + Line.InPPDirective = true; + if (FormatTok.Tok.getIdentifierInfo() == NULL) { + addUnwrappedLine(); + Line.InPPDirective = false; + return; } + + do { + if (FormatTok.NewlinesBefore > 0 && + FormatTok.HasUnescapedNewline) { + break; + } + nextToken(); + } while (!eof()); + addUnwrappedLine(); + Line.InPPDirective = false; } void UnwrappedLineParser::parseComments() { diff --git a/lib/Format/UnwrappedLineParser.h b/lib/Format/UnwrappedLineParser.h index ccf437f507..9ed796d45b 100644 --- a/lib/Format/UnwrappedLineParser.h +++ b/lib/Format/UnwrappedLineParser.h @@ -30,7 +30,8 @@ namespace format { /// \brief A wrapper around a \c Token storing information about the /// whitespace characters preceeding it. struct FormatToken { - FormatToken() : NewlinesBefore(0), WhiteSpaceLength(0) { + FormatToken() + : NewlinesBefore(0), HasUnescapedNewline(false), WhiteSpaceLength(0) { } /// \brief The \c Token. @@ -42,6 +43,10 @@ struct FormatToken { /// and thereby e.g. leave an empty line between two function definitions. unsigned NewlinesBefore; + /// \brief Whether there is at least one unescaped newline before the \c + /// Token. + bool HasUnescapedNewline; + /// \brief The location of the start of the whitespace immediately preceeding /// the \c Token. /// @@ -60,7 +65,7 @@ struct FormatToken { /// \c UnwrappedLineFormatter. The key property is that changing the formatting /// within an unwrapped line does not affect any other unwrapped lines. struct UnwrappedLine { - UnwrappedLine() : Level(0) { + UnwrappedLine() : Level(0), InPPDirective(false) { } /// \brief The \c Token comprising this \c UnwrappedLine. @@ -68,6 +73,9 @@ struct UnwrappedLine { /// \brief The indent level of the \c UnwrappedLine. unsigned Level; + + /// \brief Whether this \c UnwrappedLine is part of a preprocessor directive. + bool InPPDirective; }; class UnwrappedLineConsumer { |