diff options
author | Douglas Gregor <dgregor@apple.com> | 2012-07-31 00:50:07 +0000 |
---|---|---|
committer | Douglas Gregor <dgregor@apple.com> | 2012-07-31 00:50:07 +0000 |
commit | 721b14d1b36ca1cfcd1c0208095c9161590b60f6 (patch) | |
tree | 2fe2c5322e9f8f2f7fca527505fdf236a0f51ce3 | |
parent | ff755cda9c624dd807360bf09717e808dff1665a (diff) | |
download | bcm5719-llvm-721b14d1b36ca1cfcd1c0208095c9161590b60f6.tar.gz bcm5719-llvm-721b14d1b36ca1cfcd1c0208095c9161590b60f6.zip |
When we encounter a code-completion token while parsing an ill-formed
lambda-introducer in Objective-C++11, fall back to treating the tokens
as an Objective-C message send to provide those (more likely)
completions. Fixes <rdar://problem/11980263>.
llvm-svn: 161015
-rw-r--r-- | clang/lib/Parse/ParseExprCXX.cpp | 6 | ||||
-rw-r--r-- | clang/test/Index/complete-lambdas.mm | 40 |
2 files changed, 45 insertions, 1 deletions
diff --git a/clang/lib/Parse/ParseExprCXX.cpp b/clang/lib/Parse/ParseExprCXX.cpp index b393d1ff67c..b1ce59f28c7 100644 --- a/clang/lib/Parse/ParseExprCXX.cpp +++ b/clang/lib/Parse/ParseExprCXX.cpp @@ -642,7 +642,11 @@ llvm::Optional<unsigned> Parser::ParseLambdaIntroducer(LambdaIntroducer &Intro){ while (Tok.isNot(tok::r_square)) { if (!first) { if (Tok.isNot(tok::comma)) { - if (Tok.is(tok::code_completion)) { + // Provide a completion for a lambda introducer here. Except + // in Objective-C, where this is Almost Surely meant to be a message + // send. In that case, fail here and let the ObjC message + // expression parser perform the completion. + if (Tok.is(tok::code_completion) && !getLangOpts().ObjC1) { Actions.CodeCompleteLambdaIntroducer(getCurScope(), Intro, /*AfterAmpersand=*/false); ConsumeCodeCompletionToken(); diff --git a/clang/test/Index/complete-lambdas.mm b/clang/test/Index/complete-lambdas.mm new file mode 100644 index 00000000000..5f33906471d --- /dev/null +++ b/clang/test/Index/complete-lambdas.mm @@ -0,0 +1,40 @@ +// This test is line- and column-sensitive. See below for run lines. + + +@interface A +- instanceMethod:(int)value withOther:(int)other; ++ classMethod; +@end + +@interface B : A +@end + +@implementation B +- someMethod:(A*)a { + [a classMethod]; + [A classMethod]; + [a instanceMethod:0 withOther:1]; + [self someMethod:a]; + [super instanceMethod]; +} + +@end + +// RUN: c-index-test -code-completion-at=%s:14:6 -std=c++11 %s | FileCheck -check-prefix=CHECK-CC1 %s +// CHECK-CC1: ObjCInstanceMethodDecl:{ResultType id}{TypedText instanceMethod:}{Placeholder (int)}{HorizontalSpace }{TypedText withOther:}{Placeholder (int)} (35) (parent: ObjCInterfaceDecl 'A') + +// RUN: c-index-test -code-completion-at=%s:15:6 -std=c++11 %s | FileCheck -check-prefix=CHECK-CC2 %s +// CHECK-CC2: ObjCClassMethodDecl:{ResultType id}{TypedText classMethod} (35) (parent: ObjCInterfaceDecl 'A') + +// RUN: c-index-test -code-completion-at=%s:16:4 -std=c++11 %s | FileCheck -check-prefix=CHECK-CC3 %s +// CHECK-CC3: ObjCInterfaceDecl:{TypedText A} (50) (parent: TranslationUnit '(null)') +// CHECK-CC3: ParmDecl:{ResultType A *}{TypedText a} (34) +// CHECK-CC3: ObjCInterfaceDecl:{TypedText B} (50) (parent: TranslationUnit '(null)') +// CHECK-CC3: TypedefDecl:{TypedText Class} (50) (parent: TranslationUnit '(null)') + + +// RUN: c-index-test -code-completion-at=%s:16:21 -x objective-c++ -std=c++11 %s | FileCheck -check-prefix=CHECK-CC4 %s +// CHECK-CC4: NotImplemented:{ResultType B *}{TypedText self} (34) +// CHECK-CC4: NotImplemented:{ResultType A *}{TypedText super} (40) + +// RUN: c-index-test -code-completion-at=%s:18:10 -x objective-c++ -std=c++11 %s | FileCheck -check-prefix=CHECK-CC1 %s |