aboutsummaryrefslogtreecommitdiff
path: root/lib/Format/UnwrappedLineParser.cpp
diff options
context:
space:
mode:
authorManuel Klimek <klimek@google.com>2013-01-22 16:31:55 +0000
committerManuel Klimek <klimek@google.com>2013-01-22 16:31:55 +0000
commit86721d2a4610ac0a4b162952ec409df1fe397d58 (patch)
treef642fb02d6bf9a870cf57c7adaac5f3a8321a9d0 /lib/Format/UnwrappedLineParser.cpp
parent3298327e0e6ecb31ca8f3d0996043292e7c860f2 (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.cpp94
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;
}
}