From: Argyrios Kyrtzidis Date: Mon, 10 Nov 2014 23:21:35 +0000 (+0000) Subject: [libclang] When initializing an ObjC object via the "[[ClassName alloc] init*]" pattern, X-Git-Url: https://granicus.if.org/sourcecode?a=commitdiff_plain;h=5f43709b7487ce2b94870f2d73183a45c1d12d80;p=clang [libclang] When initializing an ObjC object via the "[[ClassName alloc] init*]" pattern, report the 'init*' invocation as non-dynamic via clang_Cursor_isDynamicCall. Of course it is dynamic at runtime, but for purposes of indexing we can treat as an invocation to ClassName's init*. Addresses rdar://18916871. git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@221641 91177308-0d34-0410-b5e6-96231b3b80d8 --- diff --git a/test/Index/cursor-dynamic-call.mm b/test/Index/cursor-dynamic-call.mm index ac9e6d351a..a926c3d03d 100644 --- a/test/Index/cursor-dynamic-call.mm +++ b/test/Index/cursor-dynamic-call.mm @@ -37,6 +37,18 @@ void foo(SS *ss, IS* is, Class cls) { [cls ClsMeth]; } +@interface NSObject ++(id)alloc; +-(id)init; +@end + +@interface Test : NSObject +@end + +void test2() { + id o = [[Test alloc] init]; +} + // RUN: c-index-test -cursor-at=%s:8:11 \ // RUN: -cursor-at=%s:9:11 \ // RUN: -cursor-at=%s:25:11 \ @@ -46,6 +58,7 @@ void foo(SS *ss, IS* is, Class cls) { // RUN: -cursor-at=%s:35:9 \ // RUN: -cursor-at=%s:36:9 \ // RUN: -cursor-at=%s:37:9 \ +// RUN: -cursor-at=%s:49:26 \ // RUN: %s | FileCheck %s // CHECK: 8:11 MemberRefExpr=meth:3:16 {{.*}} Dynamic-call @@ -59,3 +72,4 @@ void foo(SS *ss, IS* is, Class cls) { // CHECK-NOT: 36:3 {{.*}} Dynamic-call // CHECK: 36:3 {{.*}} Receiver-type=ObjCInterface // CHECK: 37:3 ObjCMessageExpr=ClsMeth:15:8 {{.*}} Dynamic-call Receiver-type=ObjCClass +// CHECK-NOT: 49:10 {{.*}} Dynamic-call diff --git a/tools/libclang/CXCursor.cpp b/tools/libclang/CXCursor.cpp index c069781739..7834181d47 100644 --- a/tools/libclang/CXCursor.cpp +++ b/tools/libclang/CXCursor.cpp @@ -1417,8 +1417,16 @@ int clang_Cursor_isDynamicCall(CXCursor C) { if (!E) return 0; - if (const ObjCMessageExpr *MsgE = dyn_cast(E)) - return MsgE->getReceiverKind() == ObjCMessageExpr::Instance; + if (const ObjCMessageExpr *MsgE = dyn_cast(E)) { + if (MsgE->getReceiverKind() != ObjCMessageExpr::Instance) + return false; + if (auto *RecE = dyn_cast( + MsgE->getInstanceReceiver()->IgnoreParenCasts())) { + if (RecE->getMethodFamily() == OMF_alloc) + return false; + } + return true; + } const MemberExpr *ME = nullptr; if (isa(E))