aboutsummaryrefslogtreecommitdiff
path: root/lib/Format/UnwrappedLineParser.cpp
diff options
context:
space:
mode:
authorManuel Klimek <klimek@google.com>2013-01-10 11:52:21 +0000
committerManuel Klimek <klimek@google.com>2013-01-10 11:52:21 +0000
commitbb42bf1a8bfd18fa2beec7fcbcb73f738fb455ba (patch)
tree0764c85a4a442a13ef3caa2d3d3c818db37d0758 /lib/Format/UnwrappedLineParser.cpp
parent5cf7cf317f684dc61b8a0e4476440b5635b80db4 (diff)
Fix layout of blocks inside statements.
Previously, we would not indent: SOME_MACRO({ int i; }); correctly. This is fixed by adding the trailing }); to the unwrapped line starting with SOME_MACRO({, so the formatter can correctly match the braces and indent accordingly. Also fixes incorrect parsing of initializer lists, like: int a[] = { 1 }; git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@172058 91177308-0d34-0410-b5e6-96231b3b80d8
Diffstat (limited to 'lib/Format/UnwrappedLineParser.cpp')
-rw-r--r--lib/Format/UnwrappedLineParser.cpp88
1 files changed, 70 insertions, 18 deletions
diff --git a/lib/Format/UnwrappedLineParser.cpp b/lib/Format/UnwrappedLineParser.cpp
index c09ee311d3..736178e1eb 100644
--- a/lib/Format/UnwrappedLineParser.cpp
+++ b/lib/Format/UnwrappedLineParser.cpp
@@ -76,6 +76,40 @@ private:
FormatToken Token;
};
+class ScopedLineState {
+public:
+ ScopedLineState(UnwrappedLineParser &Parser) : Parser(Parser) {
+ PreBlockLine = Parser.Line.take();
+ Parser.Line.reset(new UnwrappedLine(*PreBlockLine));
+ assert(Parser.LastInCurrentLine == NULL ||
+ Parser.LastInCurrentLine->Children.empty());
+ PreBlockLastToken = Parser.LastInCurrentLine;
+ PreBlockRootTokenInitialized = Parser.RootTokenInitialized;
+ Parser.RootTokenInitialized = false;
+ Parser.LastInCurrentLine = NULL;
+ }
+
+ ~ScopedLineState() {
+ if (Parser.RootTokenInitialized) {
+ Parser.addUnwrappedLine();
+ }
+ assert(!Parser.RootTokenInitialized);
+ Parser.Line.reset(PreBlockLine);
+ Parser.RootTokenInitialized = PreBlockRootTokenInitialized;
+ Parser.LastInCurrentLine = PreBlockLastToken;
+ assert(Parser.LastInCurrentLine == NULL ||
+ Parser.LastInCurrentLine->Children.empty());
+ Parser.MustBreakBeforeNextToken = true;
+ }
+
+private:
+ UnwrappedLineParser &Parser;
+
+ UnwrappedLine *PreBlockLine;
+ FormatToken* PreBlockLastToken;
+ bool PreBlockRootTokenInitialized;
+};
+
UnwrappedLineParser::UnwrappedLineParser(const FormatStyle &Style,
FormatTokenSource &Tokens,
UnwrappedLineConsumer &Callback)
@@ -204,6 +238,7 @@ void UnwrappedLineParser::parseComments() {
}
void UnwrappedLineParser::parseStructuralElement() {
+ assert(!FormatTok.Tok.is(tok::l_brace));
parseComments();
int TokenNumber = 0;
@@ -289,6 +324,10 @@ void UnwrappedLineParser::parseStructuralElement() {
parseParens();
break;
case tok::l_brace:
+ // A block outside of parentheses must be the last part of a
+ // structural element.
+ // FIXME: Figure out cases where this is not true, and add projections for
+ // them (the one we know is missing are lambdas).
parseBlock();
addUnwrappedLine();
return;
@@ -301,10 +340,28 @@ void UnwrappedLineParser::parseStructuralElement() {
break;
case tok::equal:
nextToken();
- // Skip initializers as they will be formatted by a later step.
- if (FormatTok.Tok.is(tok::l_brace))
- nextToken();
+ if (FormatTok.Tok.is(tok::l_brace)) {
+ parseBracedList();
+ }
+ break;
+ default:
+ nextToken();
+ break;
+ }
+ } while (!eof());
+}
+
+void UnwrappedLineParser::parseBracedList() {
+ nextToken();
+
+ do {
+ switch (FormatTok.Tok.getKind()) {
+ case tok::l_brace:
+ parseBracedList();
break;
+ case tok::r_brace:
+ nextToken();
+ return;
default:
nextToken();
break;
@@ -323,6 +380,15 @@ void UnwrappedLineParser::parseParens() {
case tok::r_paren:
nextToken();
return;
+ case tok::l_brace:
+ {
+ nextToken();
+ ScopedLineState LineState(*this);
+ Line->Level += 1;
+ parseLevel(/*HasOpeningBrace=*/true);
+ Line->Level -= 1;
+ }
+ break;
default:
nextToken();
break;
@@ -626,22 +692,8 @@ void UnwrappedLineParser::readToken() {
while (!Line->InPPDirective && FormatTok.Tok.is(tok::hash) &&
((FormatTok.NewlinesBefore > 0 && FormatTok.HasUnescapedNewline) ||
FormatTok.IsFirst)) {
- UnwrappedLine* StoredLine = Line.take();
- Line.reset(new UnwrappedLine(*StoredLine));
- assert(LastInCurrentLine == NULL || LastInCurrentLine->Children.empty());
- FormatToken *StoredLastInCurrentLine = LastInCurrentLine;
- bool PreviousInitialized = RootTokenInitialized;
- RootTokenInitialized = false;
- LastInCurrentLine = NULL;
-
+ ScopedLineState BlockState(*this);
parsePPDirective();
-
- assert(!RootTokenInitialized);
- Line.reset(StoredLine);
- RootTokenInitialized = PreviousInitialized;
- LastInCurrentLine = StoredLastInCurrentLine;
- assert(LastInCurrentLine == NULL || LastInCurrentLine->Children.empty());
- MustBreakBeforeNextToken = true;
}
}