From: Douglas Gregor Date: Mon, 8 Nov 2010 21:12:30 +0000 (+0000) Subject: If an instance method messages is sending to an expression of type Class, X-Git-Url: https://granicus.if.org/sourcecode?a=commitdiff_plain;h=da892649f9a0b6dd92eecb97c7959dc3f968241f;p=clang If an instance method messages is sending to an expression of type Class, and we statically can compute a bound on the actual type (e.g., because it's a send to the the magic "class" instance method), code complete as if we were performing a class message send to that class. git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@118443 91177308-0d34-0410-b5e6-96231b3b80d8 --- diff --git a/lib/Sema/SemaCodeComplete.cpp b/lib/Sema/SemaCodeComplete.cpp index c245e38bb4..90b005ddc3 100644 --- a/lib/Sema/SemaCodeComplete.cpp +++ b/lib/Sema/SemaCodeComplete.cpp @@ -4695,6 +4695,21 @@ void Sema::CodeCompleteObjCInstanceMessage(Scope *S, ExprTy *Receiver, Context.getObjCInterfaceType(Super)) : Context.getObjCIdType(); + // If we're messaging an expression with type "id" or "Class", check + // whether we know something special about the receiver that allows + // us to assume a more-specific receiver type. + if (ReceiverType->isObjCIdType() || ReceiverType->isObjCClassType()) + if (ObjCInterfaceDecl *IFace = GetAssumedMessageSendExprType(RecExpr)) { + if (ReceiverType->isObjCClassType()) + return CodeCompleteObjCClassMessage(S, + ParsedType::make(Context.getObjCInterfaceType(IFace)), + SelIdents, NumSelIdents, + AtArgumentExpression, Super); + + ReceiverType = Context.getObjCObjectPointerType( + Context.getObjCInterfaceType(IFace)); + } + // Build the set of methods we can see. ResultBuilder Results(*this, CodeCompletionContext::CCC_Other); Results.EnterNewScope(); @@ -4712,14 +4727,6 @@ void Sema::CodeCompleteObjCInstanceMessage(Scope *S, ExprTy *Receiver, // others. if (ObjCMethodDecl *CurMethod = getCurMethodDecl()) Results.setPreferredSelector(CurMethod->getSelector()); - - // If we're messaging an expression with type "id" or "Class", check - // whether we know something special about the receiver that allows - // us to assume a more-specific receiver type. - if (ReceiverType->isObjCIdType() || ReceiverType->isObjCClassType()) - if (ObjCInterfaceDecl *IFace = GetAssumedMessageSendExprType(RecExpr)) - ReceiverType = Context.getObjCObjectPointerType( - Context.getObjCInterfaceType(IFace)); // Keep track of the selectors we've already added. VisitedSelectorSet Selectors; diff --git a/test/Index/complete-objc-message.m b/test/Index/complete-objc-message.m index 161f544589..330e31fcd9 100644 --- a/test/Index/complete-objc-message.m +++ b/test/Index/complete-objc-message.m @@ -150,6 +150,27 @@ void test_redundancy(C *c) { [c method2]; }; +@protocol P +- (Class)class; +@end + +@interface A ()

+@end + +@interface A () ++ (void)class_method3; +@end + +@interface A (Cat) ++ (void)class_method4; +@end + +@implementation A +- (void)method5:(A*)a { + [[self class] class_method4]; +} +@end + // RUN: c-index-test -code-completion-at=%s:23:19 %s | FileCheck -check-prefix=CHECK-CC1 %s // CHECK-CC1: {TypedText categoryClassMethod} // CHECK-CC1: {TypedText classMethod1:}{Placeholder (id)}{HorizontalSpace }{TypedText withKeyword:}{Placeholder (int)} @@ -256,6 +277,10 @@ void test_redundancy(C *c) { // CHECK-REDUNDANT-NOT: ObjCInstanceMethodDecl:{ResultType void}{TypedText method2} // CHECK-REDUNDANT: ObjCInstanceMethodDecl:{ResultType void}{TypedText method3} (35) +// RUN: c-index-test -code-completion-at=%s:170:16 %s | FileCheck -check-prefix=CHECK-CLASS-RESULT %s +// CHECK-CLASS-RESULT: ObjCClassMethodDecl:{ResultType void}{TypedText class_method3} (35) +// CHECK-CLASS-RESULT: ObjCClassMethodDecl:{ResultType void}{TypedText class_method4} (35) + // Test code completion with a missing opening bracket: // RUN: c-index-test -code-completion-at=%s:135:5 %s | FileCheck -check-prefix=CHECK-CCI %s // RUN: c-index-test -code-completion-at=%s:139:7 %s | FileCheck -check-prefix=CHECK-CC7 %s @@ -268,3 +293,4 @@ void test_redundancy(C *c) { // RUN: c-index-test -code-completion-at=%s:141:14 %s | FileCheck -check-prefix=CHECK-CCC %s // RUN: c-index-test -code-completion-at=%s:141:23 %s | FileCheck -check-prefix=CHECK-CCD %s // RUN: c-index-test -code-completion-at=%s:141:30 %s | FileCheck -check-prefix=CHECK-CCE %s +