diff options
-rw-r--r-- | lib/Format/Format.cpp | 12 | ||||
-rw-r--r-- | lib/Format/UnwrappedLineParser.cpp | 4 | ||||
-rw-r--r-- | lib/Format/UnwrappedLineParser.h | 6 | ||||
-rw-r--r-- | unittests/Format/FormatTest.cpp | 4 |
4 files changed, 19 insertions, 7 deletions
diff --git a/lib/Format/Format.cpp b/lib/Format/Format.cpp index effe0bc248..4d401a5be9 100644 --- a/lib/Format/Format.cpp +++ b/lib/Format/Format.cpp @@ -483,8 +483,7 @@ private: unsigned Newlines = std::min(Token.NewlinesBefore, Style.MaxEmptyLinesToKeep + 1); - unsigned Offset = SourceMgr.getFileOffset(Token.WhiteSpaceStart); - if (Newlines == 0 && Offset != 0) + if (Newlines == 0 && !Token.IsFirst) Newlines = 1; unsigned Indent = Line.Level * 2; if ((Token.Tok.is(tok::kw_public) || Token.Tok.is(tok::kw_protected) || @@ -685,9 +684,10 @@ 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); + // Hashes in the middle of a line can lead to any strange token + // sequence. + if (Tokens[Index].Tok.getIdentifierInfo() == NULL) + return; switch (Tokens[Index].Tok.getIdentifierInfo()->getPPKeywordID()) { case tok::pp_include: case tok::pp_import: @@ -1033,6 +1033,8 @@ public: Lex.LexFromRawLexer(FormatTok.Tok); StringRef Text = tokenText(FormatTok.Tok); FormatTok.WhiteSpaceStart = FormatTok.Tok.getLocation(); + if (SourceMgr.getFileOffset(FormatTok.WhiteSpaceStart) == 0) + FormatTok.IsFirst = true; // Consume and record whitespace until we find a significant token. while (FormatTok.Tok.is(tok::unknown)) { diff --git a/lib/Format/UnwrappedLineParser.cpp b/lib/Format/UnwrappedLineParser.cpp index 2f3a6034bc..72b47503ee 100644 --- a/lib/Format/UnwrappedLineParser.cpp +++ b/lib/Format/UnwrappedLineParser.cpp @@ -470,7 +470,9 @@ void UnwrappedLineParser::nextToken() { void UnwrappedLineParser::readToken() { FormatTok = Tokens->getNextToken(); - while (!Line.InPPDirective && FormatTok.Tok.is(tok::hash)) { + while (!Line.InPPDirective && FormatTok.Tok.is(tok::hash) && + ((FormatTok.NewlinesBefore > 0 && FormatTok.HasUnescapedNewline) || + FormatTok.IsFirst)) { // FIXME: This is incorrect - the correct way is to create a // data structure that will construct the parts around the preprocessor // directive as a structured \c UnwrappedLine. diff --git a/lib/Format/UnwrappedLineParser.h b/lib/Format/UnwrappedLineParser.h index a8e5b739bc..287143dae2 100644 --- a/lib/Format/UnwrappedLineParser.h +++ b/lib/Format/UnwrappedLineParser.h @@ -31,7 +31,8 @@ namespace format { /// whitespace characters preceeding it. struct FormatToken { FormatToken() - : NewlinesBefore(0), HasUnescapedNewline(false), WhiteSpaceLength(0) { + : NewlinesBefore(0), HasUnescapedNewline(false), WhiteSpaceLength(0), + IsFirst(false) { } /// \brief The \c Token. @@ -56,6 +57,9 @@ struct FormatToken { /// \brief The length in characters of the whitespace immediately preceeding /// the \c Token. unsigned WhiteSpaceLength; + + /// \brief Indicates that this is the first token. + bool IsFirst; }; /// \brief An unwrapped line is a sequence of \c Token, that we would like to diff --git a/unittests/Format/FormatTest.cpp b/unittests/Format/FormatTest.cpp index 2165056a7f..8d95538b16 100644 --- a/unittests/Format/FormatTest.cpp +++ b/unittests/Format/FormatTest.cpp @@ -470,6 +470,10 @@ TEST_F(FormatTest, IndentPreprocessorDirectivesAtZero) { EXPECT_EQ("{\n {\n#define A\n }\n}", format("{{\n#define A\n}}")); } +TEST_F(FormatTest, FormatHashIfNotAtStartOfLine) { + verifyFormat("{\n {\n a #c;\n }\n}"); +} + // FIXME: write test for unbalanced braces in macros... // FIXME: test # inside a normal statement (like {#define A b}) |