aboutsummaryrefslogtreecommitdiff
path: root/lib/Format
diff options
context:
space:
mode:
Diffstat (limited to 'lib/Format')
-rw-r--r--lib/Format/Format.cpp22
-rw-r--r--lib/Format/UnwrappedLineParser.cpp24
-rw-r--r--lib/Format/UnwrappedLineParser.h12
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 {