From: Anders Carlsson Date: Fri, 28 Feb 2014 19:07:22 +0000 (+0000) Subject: When completing Objective-C instance method invocations, perform a contextual convers... X-Git-Url: https://granicus.if.org/sourcecode?a=commitdiff_plain;h=b7947f06d2e1303cb72a83aed6dc85e4691ce849;p=clang When completing Objective-C instance method invocations, perform a contextual conversion to an Objective-C pointer type of the target expression if needed. This fixes code completion of method invocations where the target is a smart pointer that has an explicit conversion operator to an Objective-C type. git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@202529 91177308-0d34-0410-b5e6-96231b3b80d8 --- diff --git a/lib/Sema/SemaCodeComplete.cpp b/lib/Sema/SemaCodeComplete.cpp index 00232f64b7..5369a4beb2 100644 --- a/lib/Sema/SemaCodeComplete.cpp +++ b/lib/Sema/SemaCodeComplete.cpp @@ -5529,7 +5529,7 @@ void Sema::CodeCompleteObjCInstanceMessage(Scope *S, Expr *Receiver, // 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 (ReceiverType->isObjCIdType() || ReceiverType->isObjCClassType()) { if (ObjCInterfaceDecl *IFace = GetAssumedMessageSendExprType(RecExpr)) { if (ReceiverType->isObjCClassType()) return CodeCompleteObjCClassMessage(S, @@ -5540,6 +5540,13 @@ void Sema::CodeCompleteObjCInstanceMessage(Scope *S, Expr *Receiver, ReceiverType = Context.getObjCObjectPointerType( Context.getObjCInterfaceType(IFace)); } + } else if (RecExpr && getLangOpts().CPlusPlus) { + ExprResult Conv = PerformContextuallyConvertToObjCPointer(RecExpr); + if (Conv.isUsable()) { + RecExpr = Conv.take(); + ReceiverType = RecExpr->getType(); + } + } // Build the set of methods we can see. ResultBuilder Results(*this, CodeCompleter->getAllocator(), diff --git a/test/CodeCompletion/objc-message.mm b/test/CodeCompletion/objc-message.mm new file mode 100644 index 0000000000..352a18e0da --- /dev/null +++ b/test/CodeCompletion/objc-message.mm @@ -0,0 +1,46 @@ +// Note: the run lines follow their respective tests, since line/column +// matter in this test. + +@protocol FooTestProtocol ++ protocolClassMethod; +- protocolInstanceMethod; +@end +@interface Foo { + void *isa; +} ++ (int)classMethod1:a withKeyword:b; ++ (void)classMethod2; ++ new; +- instanceMethod1; +@end + +@interface Foo (FooTestCategory) ++ categoryClassMethod; +- categoryInstanceMethod; +@end + +template struct RetainPtr { + template struct RemovePointer { typedef U Type; }; + template struct RemovePointer { typedef U Type; }; + + typedef typename RemovePointer::Type* PtrType; + + explicit operator PtrType() const; +}; + +void func(const RetainPtr& ptr) +{ + [ptr instanceMethod1]; +} + +void func(const RetainPtr>& ptr) +{ + [ptr instanceMethod1]; +} + +// RUN: %clang_cc1 -fsyntax-only -std=c++11 -code-completion-at=%s:33:7 %s -o - | FileCheck -check-prefix=CHECK-CC1 %s +// CHECK-CC1: categoryInstanceMethod : [#id#]categoryInstanceMethod +// CHECK-CC1: instanceMethod1 : [#id#]instanceMethod1 +// CHECK-CC1: protocolInstanceMethod : [#id#]protocolInstanceMethod +// RUN: %clang_cc1 -fsyntax-only -std=c++11 -code-completion-at=%s:38:7 %s -o - | FileCheck -check-prefix=CHECK-CC2 %s +// CHECK-CC2: protocolInstanceMethod : [#id#]protocolInstanceMethod