diff options
author | Manuel Klimek <klimek@google.com> | 2013-01-22 16:31:55 +0000 |
---|---|---|
committer | Manuel Klimek <klimek@google.com> | 2013-01-22 16:31:55 +0000 |
commit | 86721d2a4610ac0a4b162952ec409df1fe397d58 (patch) | |
tree | f642fb02d6bf9a870cf57c7adaac5f3a8321a9d0 /lib/Format/UnwrappedLineParser.cpp | |
parent | 3298327e0e6ecb31ca8f3d0996043292e7c860f2 (diff) |
Implements more principled comment parsing.
Changing nextToken() in the UnwrappedLineParser to get the next
non-comment token. This allows us to correctly layout a whole class of
snippets, like:
if /* */(/* */ a /* */) /* */
f() /* */; /* */
else /* */
g();
Fixes a bug in the formatter where we would assume there is a previous
non-comment token.
Also adds the indent level of an unwrapped line to the debug output in
the parser.
git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@173168 91177308-0d34-0410-b5e6-96231b3b80d8
Diffstat (limited to 'lib/Format/UnwrappedLineParser.cpp')
-rw-r--r-- | lib/Format/UnwrappedLineParser.cpp | 94 |
1 files changed, 56 insertions, 38 deletions
diff --git a/lib/Format/UnwrappedLineParser.cpp b/lib/Format/UnwrappedLineParser.cpp index 2d6c5cf070..53fa2a32df 100644 --- a/lib/Format/UnwrappedLineParser.cpp +++ b/lib/Format/UnwrappedLineParser.cpp @@ -130,6 +130,7 @@ bool UnwrappedLineParser::parse() { bool UnwrappedLineParser::parseFile() { bool Error = parseLevel(/*HasOpeningBrace=*/false); // Make sure to format the remaining tokens. + flushComments(true); addUnwrappedLine(); return Error; } @@ -174,12 +175,14 @@ bool UnwrappedLineParser::parseBlock(unsigned AddLevels) { Line->Level += AddLevels; parseLevel(/*HasOpeningBrace=*/true); - Line->Level -= AddLevels; - if (!FormatTok.Tok.is(tok::r_brace)) + if (!FormatTok.Tok.is(tok::r_brace)) { + Line->Level -= AddLevels; return true; + } nextToken(); // Munch the closing brace. + Line->Level -= AddLevels; return false; } @@ -232,18 +235,8 @@ void UnwrappedLineParser::parsePPUnknown() { addUnwrappedLine(); } -void UnwrappedLineParser::parseComments() { - // Consume leading line comments, e.g. for branches without compounds. - while (FormatTok.Tok.is(tok::comment)) { - nextToken(); - addUnwrappedLine(); - } -} - void UnwrappedLineParser::parseStructuralElement() { assert(!FormatTok.Tok.is(tok::l_brace)); - parseComments(); - int TokenNumber = 0; switch (FormatTok.Tok.getKind()) { case tok::at: @@ -598,11 +591,6 @@ void UnwrappedLineParser::parseEnum() { ++Line->Level; do { switch (FormatTok.Tok.getKind()) { - case tok::comment: - // FIXME: Handle comments centrally, instead of special casing - // them everywhere. - parseComments(); - break; case tok::l_paren: parseParens(); break; @@ -731,13 +719,8 @@ void UnwrappedLineParser::parseObjCProtocol() { void UnwrappedLineParser::addUnwrappedLine() { if (Line->Tokens.empty()) return; - // Consume trailing comments. - while (!eof() && FormatTok.NewlinesBefore == 0 && - FormatTok.Tok.is(tok::comment)) { - nextToken(); - } DEBUG({ - llvm::dbgs() << "Line: "; + llvm::dbgs() << "Line(" << Line->Level << "): "; for (std::list<FormatToken>::iterator I = Line->Tokens.begin(), E = Line->Tokens.end(); I != E; ++I) { @@ -763,28 +746,63 @@ bool UnwrappedLineParser::eof() const { return FormatTok.Tok.is(tok::eof); } +void UnwrappedLineParser::flushComments(bool NewlineBeforeNext) { + bool JustComments = Line->Tokens.empty(); + for (SmallVectorImpl<FormatToken>::const_iterator + I = CommentsBeforeNextToken.begin(), + E = CommentsBeforeNextToken.end(); + I != E; ++I) { + if (I->HasUnescapedNewline && JustComments) { + addUnwrappedLine(); + } + pushToken(*I); + } + if (NewlineBeforeNext && JustComments) { + addUnwrappedLine(); + } + CommentsBeforeNextToken.clear(); +} + void UnwrappedLineParser::nextToken() { if (eof()) return; - Line->Tokens.push_back(FormatTok); - if (MustBreakBeforeNextToken) { - Line->Tokens.back().MustBreakBefore = true; - MustBreakBeforeNextToken = false; - } + flushComments(FormatTok.HasUnescapedNewline); + pushToken(FormatTok); readToken(); } void UnwrappedLineParser::readToken() { - FormatTok = Tokens->getNextToken(); - while (!Line->InPPDirective && FormatTok.Tok.is(tok::hash) && - ((FormatTok.NewlinesBefore > 0 && FormatTok.HasUnescapedNewline) || - FormatTok.IsFirst)) { - // 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(); + bool CommentsInCurrentLine = true; + do { + FormatTok = Tokens->getNextToken(); + while (!Line->InPPDirective && FormatTok.Tok.is(tok::hash) && + ((FormatTok.NewlinesBefore > 0 && FormatTok.HasUnescapedNewline) || + FormatTok.IsFirst)) { + // 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(); + } + if (!FormatTok.Tok.is(tok::comment)) + return; + if (FormatTok.HasUnescapedNewline || FormatTok.IsFirst) { + CommentsInCurrentLine = false; + } + if (CommentsInCurrentLine) { + pushToken(FormatTok); + } else { + CommentsBeforeNextToken.push_back(FormatTok); + } + } while (!eof()); +} + +void UnwrappedLineParser::pushToken(const FormatToken &Tok) { + Line->Tokens.push_back(Tok); + if (MustBreakBeforeNextToken) { + Line->Tokens.back().MustBreakBefore = true; + MustBreakBeforeNextToken = false; } } |