]> granicus.if.org Git - clang/commitdiff
[libclang] When initializing an ObjC object via the "[[ClassName alloc] init*]" pattern,
authorArgyrios Kyrtzidis <akyrtzi@gmail.com>
Mon, 10 Nov 2014 23:21:35 +0000 (23:21 +0000)
committerArgyrios Kyrtzidis <akyrtzi@gmail.com>
Mon, 10 Nov 2014 23:21:35 +0000 (23:21 +0000)
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

test/Index/cursor-dynamic-call.mm
tools/libclang/CXCursor.cpp

index ac9e6d351a0a477e83ec21f17455341f7673d2be..a926c3d03d47255f71cd6db05d53a6ba30cb30ac 100644 (file)
@@ -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
index c069781739c28328f52eda092972e3d05dfb69ed..7834181d47810c03df9bf965cdca1e99f8333f20 100644 (file)
@@ -1417,8 +1417,16 @@ int clang_Cursor_isDynamicCall(CXCursor C) {
   if (!E)
     return 0;
 
-  if (const ObjCMessageExpr *MsgE = dyn_cast<ObjCMessageExpr>(E))
-    return MsgE->getReceiverKind() == ObjCMessageExpr::Instance;
+  if (const ObjCMessageExpr *MsgE = dyn_cast<ObjCMessageExpr>(E)) {
+    if (MsgE->getReceiverKind() != ObjCMessageExpr::Instance)
+      return false;
+    if (auto *RecE = dyn_cast<ObjCMessageExpr>(
+            MsgE->getInstanceReceiver()->IgnoreParenCasts())) {
+      if (RecE->getMethodFamily() == OMF_alloc)
+        return false;
+    }
+    return true;
+  }
 
   const MemberExpr *ME = nullptr;
   if (isa<MemberExpr>(E))