diff options
author | Ben Hamilton <benhamilton@google.com> | 2018-04-05 15:26:23 +0000 |
---|---|---|
committer | Ben Hamilton <benhamilton@google.com> | 2018-04-05 15:26:23 +0000 |
commit | f90ad9cdac9edc7f3b4268681d5d7ff2532565cc (patch) | |
tree | ae7bae0604017e4ac56b3151ac09c795a45bb240 /clang/lib | |
parent | 441460dc9173bc10892ee9f53e5382f5768d4c8f (diff) | |
download | bcm5719-llvm-f90ad9cdac9edc7f3b4268681d5d7ff2532565cc.tar.gz bcm5719-llvm-f90ad9cdac9edc7f3b4268681d5d7ff2532565cc.zip |
[clang-format] Ensure ObjC selectors with 0 args are annotated correctly
Summary:
Previously, clang-format would incorrectly annotate 0-argument
Objective-C selector names as TT_TrailingAnnotation:
```
% echo "-(void)foo;" > /tmp/test.m
% ./bin/clang-format -debug /tmp/test.m
Language: Objective-C
----
Line(0, FSC=0): minus[T=68, OC=0] l_paren[T=68, OC=1] void[T=68, OC=2]
r_paren[T=68, OC=6] identifier[T=68, OC=7] semi[T=68, OC=10]
Line(0, FSC=0): eof[T=68, OC=0]
Run 0...
AnnotatedTokens(L=0):
M=0 C=0 T=ObjCMethodSpecifier S=1 B=0 BK=0 P=0 Name=minus L=1 PPK=2
FakeLParens= FakeRParens=0 Text='-'
M=0 C=1 T=Unknown S=1 B=0 BK=0 P=33 Name=l_paren L=3 PPK=2
FakeLParens= FakeRParens=0 Text='('
M=0 C=1 T=Unknown S=0 B=0 BK=0 P=140 Name=void L=7 PPK=2 FakeLParens=
FakeRParens=0 Text='void'
M=0 C=0 T=CastRParen S=0 B=0 BK=0 P=43 Name=r_paren L=8 PPK=2
FakeLParens= FakeRParens=0 Text=')'
M=0 C=1 T=TrailingAnnotation S=0 B=0 BK=0 P=120 Name=identifier L=11
PPK=2 FakeLParens= FakeRParens=0 Text='foo'
M=0 C=0 T=Unknown S=0 B=0 BK=0 P=23 Name=semi L=12 PPK=2 FakeLParens=
FakeRParens=0 Text=';'
```
This caused us to incorrectly indent 0-argument wrapped selectors
when Style.IndentWrappedFunctionNames was false, as we thought
the 0-argument ObjC selector name was actually a trailing
annotation (which is always indented).
This diff fixes the issue and adds tests.
Test Plan: New tests added. Confirmed tests failed before diff.
After diff, tests passed. Ran tests with:
% make -j12 FormatTests &&
./tools/clang/unittests/Format/FormatTests
Reviewers: djasper, jolesiak
Reviewed By: djasper, jolesiak
Subscribers: klimek, cfe-commits
Differential Revision: https://reviews.llvm.org/D44996
llvm-svn: 329297
Diffstat (limited to 'clang/lib')
-rw-r--r-- | clang/lib/Format/TokenAnnotator.cpp | 14 |
1 files changed, 14 insertions, 0 deletions
diff --git a/clang/lib/Format/TokenAnnotator.cpp b/clang/lib/Format/TokenAnnotator.cpp index c2d6875e0c3..60ebe56d072 100644 --- a/clang/lib/Format/TokenAnnotator.cpp +++ b/clang/lib/Format/TokenAnnotator.cpp @@ -391,6 +391,7 @@ private: Parent->isOneOf(tok::colon, tok::l_square, tok::l_paren, tok::kw_return, tok::kw_throw) || Parent->isUnaryOperator() || + // FIXME(bug 36976): ObjC return types shouldn't use TT_CastRParen. Parent->isOneOf(TT_ObjCForIn, TT_CastRParen) || getBinOpPrecedence(Parent->Tok.getKind(), true, true) > prec::Unknown); bool ColonFound = false; @@ -524,6 +525,7 @@ private: Left->ParameterCount = 0; Contexts.back().ColonIsObjCMethodExpr = true; if (Parent && Parent->is(tok::r_paren)) + // FIXME(bug 36976): ObjC return types shouldn't use TT_CastRParen. Parent->Type = TT_CastRParen; } ColonFound = true; @@ -676,6 +678,7 @@ private: Tok->Type = TT_ObjCMethodExpr; const FormatToken *BeforePrevious = Tok->Previous->Previous; if (!BeforePrevious || + // FIXME(bug 36976): ObjC return types shouldn't use TT_CastRParen. !(BeforePrevious->is(TT_CastRParen) || (BeforePrevious->is(TT_ObjCMethodExpr) && BeforePrevious->is(tok::colon))) || @@ -1343,6 +1346,17 @@ private: TT_LeadingJavaAnnotation)) { Current.Type = Current.Previous->Type; } + } else if (Current.isOneOf(tok::identifier, tok::kw_new) && + // FIXME(bug 36976): ObjC return types shouldn't use TT_CastRParen. + Current.Previous && Current.Previous->is(TT_CastRParen) && + Current.Previous->MatchingParen && + Current.Previous->MatchingParen->Previous && + Current.Previous->MatchingParen->Previous->is( + TT_ObjCMethodSpecifier)) { + // This is the first part of an Objective-C selector name. (If there's no + // colon after this, this is the only place which annotates the identifier + // as a selector.) + Current.Type = TT_SelectorName; } else if (Current.isOneOf(tok::identifier, tok::kw_const) && Current.Previous && !Current.Previous->isOneOf(tok::equal, tok::at) && |