diff options
| author | Ben Hamilton <benhamilton@google.com> | 2018-03-06 17:21:42 +0000 |
|---|---|---|
| committer | Ben Hamilton <benhamilton@google.com> | 2018-03-06 17:21:42 +0000 |
| commit | 1d6c6ee1cf98d260b486242b288a9d8fa0e4e7e1 (patch) | |
| tree | ef113b17350d8baf20f8bcd8ac7cb22312786e5b /clang/lib/Format | |
| parent | 6cd91f1d4485b511017952592e3fab070942cb46 (diff) | |
| download | bcm5719-llvm-1d6c6ee1cf98d260b486242b288a9d8fa0e4e7e1.tar.gz bcm5719-llvm-1d6c6ee1cf98d260b486242b288a9d8fa0e4e7e1.zip | |
[clang-format] Improve detection of ObjC for-in statements
Summary:
Previously, clang-format would detect the following as an
Objective-C for-in statement:
for (int x = in.value(); ...) {}
because the logic only decided a for-loop was definitely *not*
an Objective-C for-in loop after it saw a semicolon or a colon.
To fix this, I delayed the decision of whether this was a for-in
statement until after we found the matching right-paren, at which
point we know if we've seen a semicolon or not.
Test Plan: New tests added. Ran tests with:
make -j12 FormatTests && ./tools/clang/unittests/Format/FormatTests
Reviewers: krasimir, jolesiak
Reviewed By: jolesiak
Subscribers: djasper, cfe-commits, klimek
Differential Revision: https://reviews.llvm.org/D43904
llvm-svn: 326815
Diffstat (limited to 'clang/lib/Format')
| -rw-r--r-- | clang/lib/Format/TokenAnnotator.cpp | 14 |
1 files changed, 11 insertions, 3 deletions
diff --git a/clang/lib/Format/TokenAnnotator.cpp b/clang/lib/Format/TokenAnnotator.cpp index d083cc7c33d..013a77b4c59 100644 --- a/clang/lib/Format/TokenAnnotator.cpp +++ b/clang/lib/Format/TokenAnnotator.cpp @@ -216,6 +216,7 @@ private: bool HasMultipleParametersOnALine = false; bool MightBeObjCForRangeLoop = Left->Previous && Left->Previous->is(tok::kw_for); + FormatToken *PossibleObjCForInToken = nullptr; while (CurrentToken) { // LookForDecls is set when "if (" has been seen. Check for // 'identifier' '*' 'identifier' followed by not '=' -- this @@ -301,10 +302,17 @@ private: CurrentToken->Previous->isSimpleTypeSpecifier()) && !CurrentToken->is(tok::l_brace)) Contexts.back().IsExpression = false; - if (CurrentToken->isOneOf(tok::semi, tok::colon)) + if (CurrentToken->isOneOf(tok::semi, tok::colon)) { MightBeObjCForRangeLoop = false; - if (MightBeObjCForRangeLoop && CurrentToken->is(Keywords.kw_in)) - CurrentToken->Type = TT_ObjCForIn; + if (PossibleObjCForInToken) { + PossibleObjCForInToken->Type = TT_Unknown; + PossibleObjCForInToken = nullptr; + } + } + if (MightBeObjCForRangeLoop && CurrentToken->is(Keywords.kw_in)) { + PossibleObjCForInToken = CurrentToken; + PossibleObjCForInToken->Type = TT_ObjCForIn; + } // When we discover a 'new', we set CanBeExpression to 'false' in order to // parse the type correctly. Reset that after a comma. if (CurrentToken->is(tok::comma)) |

