diff options
author | Manuel Klimek <klimek@google.com> | 2013-01-18 14:04:34 +0000 |
---|---|---|
committer | Manuel Klimek <klimek@google.com> | 2013-01-18 14:04:34 +0000 |
commit | 525fe168c25a8273899281c5d2326c722fc3f2a5 (patch) | |
tree | 3118da57eae0699db38c0bcc26d974dd0d4fc1eb /lib/Format/UnwrappedLineParser.cpp | |
parent | b8238b6f20bf7b5a79f18dc84ab3e51db479faa7 (diff) |
Fixes problems with line merging in the face of preprocessor directives.
This patch prepares being able to test for and fix more problems (see
FIXME in the test for example).
Previously we would output unwrapped lines for preprocessor directives
at the point where we also parsed the hash token. Since often
projections only terminate (and thus output their own unwrapped line)
after peeking at the next token, this would lead to the formatter seeing
the preprocessor directives out-of-order (slightly earlier). To be able
to correctly identify lines to merge, the formatter needs a well-defined
order of unwrapped lines, which this patch introduces.
git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@172819 91177308-0d34-0410-b5e6-96231b3b80d8
Diffstat (limited to 'lib/Format/UnwrappedLineParser.cpp')
-rw-r--r-- | lib/Format/UnwrappedLineParser.cpp | 40 |
1 files changed, 33 insertions, 7 deletions
diff --git a/lib/Format/UnwrappedLineParser.cpp b/lib/Format/UnwrappedLineParser.cpp index 1f71b5b7da..a0a18ac1cf 100644 --- a/lib/Format/UnwrappedLineParser.cpp +++ b/lib/Format/UnwrappedLineParser.cpp @@ -79,7 +79,11 @@ private: class ScopedLineState { public: - ScopedLineState(UnwrappedLineParser &Parser) : Parser(Parser) { + ScopedLineState(UnwrappedLineParser &Parser, + bool SwitchToPreprocessorLines = false) + : Parser(Parser), SwitchToPreprocessorLines(SwitchToPreprocessorLines) { + if (SwitchToPreprocessorLines) + Parser.CurrentLines = &Parser.PreprocessorDirectives; PreBlockLine = Parser.Line.take(); Parser.Line.reset(new UnwrappedLine()); Parser.Line->Level = PreBlockLine->Level; @@ -93,10 +97,13 @@ public: assert(Parser.Line->Tokens.empty()); Parser.Line.reset(PreBlockLine); Parser.MustBreakBeforeNextToken = true; + if (SwitchToPreprocessorLines) + Parser.CurrentLines = &Parser.Lines; } private: UnwrappedLineParser &Parser; + const bool SwitchToPreprocessorLines; UnwrappedLine *PreBlockLine; }; @@ -104,14 +111,20 @@ private: UnwrappedLineParser::UnwrappedLineParser( clang::DiagnosticsEngine &Diag, const FormatStyle &Style, FormatTokenSource &Tokens, UnwrappedLineConsumer &Callback) - : Line(new UnwrappedLine), MustBreakBeforeNextToken(false), Diag(Diag), - Style(Style), Tokens(&Tokens), Callback(Callback) { -} + : Line(new UnwrappedLine), MustBreakBeforeNextToken(false), + CurrentLines(&Lines), Diag(Diag), Style(Style), Tokens(&Tokens), + Callback(Callback) {} bool UnwrappedLineParser::parse() { DEBUG(llvm::dbgs() << "----\n"); readToken(); - return parseFile(); + bool Error = parseFile(); + for (std::vector<UnwrappedLine>::iterator I = Lines.begin(), + E = Lines.end(); + I != E; ++I) { + Callback.consumeUnwrappedLine(*I); + } + return Error; } bool UnwrappedLineParser::parseFile() { @@ -668,8 +681,17 @@ void UnwrappedLineParser::addUnwrappedLine() { } llvm::dbgs() << "\n"; }); - Callback.consumeUnwrappedLine(*Line); + CurrentLines->push_back(*Line); Line->Tokens.clear(); + if (CurrentLines == &Lines && !PreprocessorDirectives.empty()) { + for (std::vector<UnwrappedLine>::iterator I = PreprocessorDirectives + .begin(), E = PreprocessorDirectives.end(); + I != E; ++I) { + CurrentLines->push_back(*I); + } + PreprocessorDirectives.clear(); + } + } bool UnwrappedLineParser::eof() const { @@ -692,7 +714,11 @@ void UnwrappedLineParser::readToken() { while (!Line->InPPDirective && FormatTok.Tok.is(tok::hash) && ((FormatTok.NewlinesBefore > 0 && FormatTok.HasUnescapedNewline) || FormatTok.IsFirst)) { - ScopedLineState BlockState(*this); + // If there is an unfinished unwrapped line, we flush the preprocessor + // directives only after that unwrapped line was finished later. + bool SwitchToPreprocessorLines = !Line->Tokens.empty() && + CurrentLines == &Lines; + ScopedLineState BlockState(*this, SwitchToPreprocessorLines); parsePPDirective(); } } |