diff options
author | Manuel Klimek <klimek@google.com> | 2013-01-23 09:32:48 +0000 |
---|---|---|
committer | Manuel Klimek <klimek@google.com> | 2013-01-23 09:32:48 +0000 |
commit | 70b03f4edaefcc5b9aa2e084d1c12e9d91b32a77 (patch) | |
tree | e43b61232306a4d0ea1fee82dc51eab210a1710e /lib/Format/UnwrappedLineParser.cpp | |
parent | 69652660e765ec2bbcf1877ac05c66e91b8fa745 (diff) |
Allow us to better guess the context of an unwrapped line.
This gives us the ability to guess better defaults for whether a *
between identifiers is a pointer dereference or binary operator.
Now correctly formats:
void f(a *b);
void f() { f(a * b); }
git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@173243 91177308-0d34-0410-b5e6-96231b3b80d8
Diffstat (limited to 'lib/Format/UnwrappedLineParser.cpp')
-rw-r--r-- | lib/Format/UnwrappedLineParser.cpp | 53 |
1 files changed, 39 insertions, 14 deletions
diff --git a/lib/Format/UnwrappedLineParser.cpp b/lib/Format/UnwrappedLineParser.cpp index 53fa2a32df..047074135c 100644 --- a/lib/Format/UnwrappedLineParser.cpp +++ b/lib/Format/UnwrappedLineParser.cpp @@ -28,6 +28,23 @@ namespace clang { namespace format { +class ScopedDeclarationState { +public: + ScopedDeclarationState(UnwrappedLine &Line, std::vector<bool> &Stack, + bool MustBeDeclaration) + : Line(Line), Stack(Stack) { + Stack.push_back(MustBeDeclaration); + Line.MustBeDeclaration = MustBeDeclaration; + } + ~ScopedDeclarationState() { + Line.MustBeDeclaration = Stack.back(); + Stack.pop_back(); + } +private: + UnwrappedLine &Line; + std::vector<bool> &Stack; +}; + class ScopedMacroState : public FormatTokenSource { public: ScopedMacroState(UnwrappedLine &Line, FormatTokenSource *&TokenSource, @@ -128,6 +145,8 @@ bool UnwrappedLineParser::parse() { } bool UnwrappedLineParser::parseFile() { + ScopedDeclarationState DeclarationState(*Line, DeclarationScopeStack, + /*MustBeDeclaration=*/ true); bool Error = parseLevel(/*HasOpeningBrace=*/false); // Make sure to format the remaining tokens. flushComments(true); @@ -144,7 +163,9 @@ bool UnwrappedLineParser::parseLevel(bool HasOpeningBrace) { addUnwrappedLine(); break; case tok::l_brace: - Error |= parseBlock(); + // FIXME: Add parameter whether this can happen - if this happens, we must + // be in a non-declaration context. + Error |= parseBlock(/*MustBeDeclaration=*/ false); addUnwrappedLine(); break; case tok::r_brace: @@ -167,12 +188,14 @@ bool UnwrappedLineParser::parseLevel(bool HasOpeningBrace) { return Error; } -bool UnwrappedLineParser::parseBlock(unsigned AddLevels) { +bool UnwrappedLineParser::parseBlock(bool MustBeDeclaration, unsigned AddLevels) { assert(FormatTok.Tok.is(tok::l_brace) && "'{' expected"); nextToken(); addUnwrappedLine(); + ScopedDeclarationState DeclarationState(*Line, DeclarationScopeStack, + MustBeDeclaration); Line->Level += AddLevels; parseLevel(/*HasOpeningBrace=*/true); @@ -307,7 +330,7 @@ void UnwrappedLineParser::parseStructuralElement() { if (FormatTok.Tok.is(tok::string_literal)) { nextToken(); if (FormatTok.Tok.is(tok::l_brace)) { - parseBlock(0); + parseBlock(/*MustBeDeclaration=*/ true, 0); addUnwrappedLine(); return; } @@ -345,7 +368,7 @@ void UnwrappedLineParser::parseStructuralElement() { // 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(); + parseBlock(/*MustBeDeclaration=*/ false); addUnwrappedLine(); return; case tok::identifier: @@ -427,8 +450,10 @@ void UnwrappedLineParser::parseParens() { { nextToken(); ScopedLineState LineState(*this); + ScopedDeclarationState DeclarationState(*Line, DeclarationScopeStack, + /*MustBeDeclaration=*/ false); Line->Level += 1; - parseLevel(/*HasOpeningBrace=*/true); + parseLevel(/*HasOpeningBrace=*/ true); Line->Level -= 1; } break; @@ -446,7 +471,7 @@ void UnwrappedLineParser::parseIfThenElse() { parseParens(); bool NeedsUnwrappedLine = false; if (FormatTok.Tok.is(tok::l_brace)) { - parseBlock(); + parseBlock(/*MustBeDeclaration=*/ false); NeedsUnwrappedLine = true; } else { addUnwrappedLine(); @@ -457,7 +482,7 @@ void UnwrappedLineParser::parseIfThenElse() { if (FormatTok.Tok.is(tok::kw_else)) { nextToken(); if (FormatTok.Tok.is(tok::l_brace)) { - parseBlock(); + parseBlock(/*MustBeDeclaration=*/ false); addUnwrappedLine(); } else if (FormatTok.Tok.is(tok::kw_if)) { parseIfThenElse(); @@ -478,7 +503,7 @@ void UnwrappedLineParser::parseNamespace() { if (FormatTok.Tok.is(tok::identifier)) nextToken(); if (FormatTok.Tok.is(tok::l_brace)) { - parseBlock(0); + parseBlock(/*MustBeDeclaration=*/ true, 0); addUnwrappedLine(); } // FIXME: Add error handling. @@ -491,7 +516,7 @@ void UnwrappedLineParser::parseForOrWhileLoop() { if (FormatTok.Tok.is(tok::l_paren)) parseParens(); if (FormatTok.Tok.is(tok::l_brace)) { - parseBlock(); + parseBlock(/*MustBeDeclaration=*/ false); addUnwrappedLine(); } else { addUnwrappedLine(); @@ -505,7 +530,7 @@ void UnwrappedLineParser::parseDoWhile() { assert(FormatTok.Tok.is(tok::kw_do) && "'do' expected"); nextToken(); if (FormatTok.Tok.is(tok::l_brace)) { - parseBlock(); + parseBlock(/*MustBeDeclaration=*/ false); } else { addUnwrappedLine(); ++Line->Level; @@ -531,7 +556,7 @@ void UnwrappedLineParser::parseLabel() { if (Line->Level > 0) --Line->Level; if (FormatTok.Tok.is(tok::l_brace)) { - parseBlock(); + parseBlock(/*MustBeDeclaration=*/ false); if (FormatTok.Tok.is(tok::kw_break)) parseStructuralElement(); // "break;" after "}" goes on the same line. } @@ -554,7 +579,7 @@ void UnwrappedLineParser::parseSwitch() { if (FormatTok.Tok.is(tok::l_paren)) parseParens(); if (FormatTok.Tok.is(tok::l_brace)) { - parseBlock(Style.IndentCaseLabels ? 2 : 1); + parseBlock(/*MustBeDeclaration=*/ false, Style.IndentCaseLabels ? 2 : 1); addUnwrappedLine(); } else { addUnwrappedLine(); @@ -648,7 +673,7 @@ void UnwrappedLineParser::parseRecord() { } } if (FormatTok.Tok.is(tok::l_brace)) - parseBlock(); + parseBlock(/*MustBeDeclaration=*/ true); // We fall through to parsing a structural element afterwards, so // class A {} n, m; // will end up in one unwrapped line. @@ -690,7 +715,7 @@ void UnwrappedLineParser::parseObjCInterfaceOrImplementation() { // If instance variables are present, keep the '{' on the first line too. if (FormatTok.Tok.is(tok::l_brace)) - parseBlock(); + parseBlock(/*MustBeDeclaration=*/ true); // With instance variables, this puts '}' on its own line. Without instance // variables, this ends the @interface line. |