Author: akirtzidis Date: Thu Apr 27 12:23:04 2017 New Revision: 301568 URL: http://llvm.org/viewvc/llvm-project?rev=301568&view=rev Log: [libclang] Enhance clang_Cursor_isDynamicCall and clang_Cursor_getReceiverType to handle ObjC property references
Also enhance clang_Cursor_getReceiverType to handle C++ method calls. Modified: cfe/trunk/include/clang-c/Index.h cfe/trunk/test/Index/cursor-dynamic-call.mm cfe/trunk/tools/c-index-test/c-index-test.c cfe/trunk/tools/libclang/CXCursor.cpp Modified: cfe/trunk/include/clang-c/Index.h URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/include/clang-c/Index.h?rev=301568&r1=301567&r2=301568&view=diff ============================================================================== --- cfe/trunk/include/clang-c/Index.h (original) +++ cfe/trunk/include/clang-c/Index.h Thu Apr 27 12:23:04 2017 @@ -3975,8 +3975,8 @@ CINDEX_LINKAGE int clang_Cursor_getObjCS CINDEX_LINKAGE int clang_Cursor_isDynamicCall(CXCursor C); /** - * \brief Given a cursor pointing to an Objective-C message, returns the CXType - * of the receiver. + * \brief Given a cursor pointing to an Objective-C message or property + * reference, or C++ method call, returns the CXType of the receiver. */ CINDEX_LINKAGE CXType clang_Cursor_getReceiverType(CXCursor C); Modified: cfe/trunk/test/Index/cursor-dynamic-call.mm URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/test/Index/cursor-dynamic-call.mm?rev=301568&r1=301567&r2=301568&view=diff ============================================================================== --- cfe/trunk/test/Index/cursor-dynamic-call.mm (original) +++ cfe/trunk/test/Index/cursor-dynamic-call.mm Thu Apr 27 12:23:04 2017 @@ -49,6 +49,14 @@ void test2() { id o = [[Test alloc] init]; } +@interface Test2 : NSObject +@property (assign) id someProp; +@end + +void test3(Test2 *o) { + id v = o.someProp; +} + // RUN: c-index-test -cursor-at=%s:8:11 \ // RUN: -cursor-at=%s:9:11 \ // RUN: -cursor-at=%s:25:11 \ @@ -59,6 +67,7 @@ void test2() { // RUN: -cursor-at=%s:36:9 \ // RUN: -cursor-at=%s:37:9 \ // RUN: -cursor-at=%s:49:26 \ +// RUN: -cursor-at=%s:57:12 \ // RUN: %s | FileCheck %s // CHECK: 8:11 MemberRefExpr=meth:3:16 {{.*}} Dynamic-call @@ -67,9 +76,10 @@ void test2() { // CHECK-NOT: 26:3 {{.*}} Dynamic-call // CHECK-NOT: 29:3 {{.*}} Dynamic-call // CHECK: 29:3 {{.*}} Receiver-type=ObjCInterface -// CHECK: 34:7 MemberRefExpr=meth:3:16 {{.*}} Dynamic-call +// CHECK: 34:7 MemberRefExpr=meth:3:16 {{.*}} Dynamic-call Receiver-type=Pointer // CHECK: 35:3 ObjCMessageExpr=meth:14:8 {{.*}} Dynamic-call Receiver-type=ObjCObjectPointer // 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 +// CHECK: 57:12 MemberRefExpr=someProp:53:23 {{.*}} Dynamic-call Receiver-type=ObjCObjectPointer Modified: cfe/trunk/tools/c-index-test/c-index-test.c URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/tools/c-index-test/c-index-test.c?rev=301568&r1=301567&r2=301568&view=diff ============================================================================== --- cfe/trunk/tools/c-index-test/c-index-test.c (original) +++ cfe/trunk/tools/c-index-test/c-index-test.c Thu Apr 27 12:23:04 2017 @@ -2437,11 +2437,14 @@ static void inspect_print_cursor(CXCurso clang_Cursor_getObjCSelectorIndex(Cursor)); if (clang_Cursor_isDynamicCall(Cursor)) printf(" Dynamic-call"); - if (Cursor.kind == CXCursor_ObjCMessageExpr) { + if (Cursor.kind == CXCursor_ObjCMessageExpr || + Cursor.kind == CXCursor_MemberRefExpr) { CXType T = clang_Cursor_getReceiverType(Cursor); - CXString S = clang_getTypeKindSpelling(T.kind); - printf(" Receiver-type=%s", clang_getCString(S)); - clang_disposeString(S); + if (T.kind != CXType_Invalid) { + CXString S = clang_getTypeKindSpelling(T.kind); + printf(" Receiver-type=%s", clang_getCString(S)); + clang_disposeString(S); + } } { Modified: cfe/trunk/tools/libclang/CXCursor.cpp URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/tools/libclang/CXCursor.cpp?rev=301568&r1=301567&r2=301568&view=diff ============================================================================== --- cfe/trunk/tools/libclang/CXCursor.cpp (original) +++ cfe/trunk/tools/libclang/CXCursor.cpp Thu Apr 27 12:23:04 2017 @@ -1523,6 +1523,10 @@ int clang_Cursor_isDynamicCall(CXCursor return true; } + if (auto *PropRefE = dyn_cast<ObjCPropertyRefExpr>(E)) { + return !PropRefE->isSuperReceiver(); + } + const MemberExpr *ME = nullptr; if (isa<MemberExpr>(E)) ME = cast<MemberExpr>(E); @@ -1532,7 +1536,9 @@ int clang_Cursor_isDynamicCall(CXCursor if (ME) { if (const CXXMethodDecl * MD = dyn_cast_or_null<CXXMethodDecl>(ME->getMemberDecl())) - return MD->isVirtual() && !ME->hasQualifier(); + return MD->isVirtual() && + ME->performsVirtualDispatch( + cxcursor::getCursorContext(C).getLangOpts()); } return 0; @@ -1547,5 +1553,24 @@ CXType clang_Cursor_getReceiverType(CXCu if (const ObjCMessageExpr *MsgE = dyn_cast_or_null<ObjCMessageExpr>(E)) return cxtype::MakeCXType(MsgE->getReceiverType(), TU); + if (auto *PropRefE = dyn_cast<ObjCPropertyRefExpr>(E)) { + return cxtype::MakeCXType( + PropRefE->getReceiverType(cxcursor::getCursorContext(C)), TU); + } + + const MemberExpr *ME = nullptr; + if (isa<MemberExpr>(E)) + ME = cast<MemberExpr>(E); + else if (const CallExpr *CE = dyn_cast<CallExpr>(E)) + ME = dyn_cast_or_null<MemberExpr>(CE->getCallee()); + + if (ME) { + if (const CXXMethodDecl * + MD = dyn_cast_or_null<CXXMethodDecl>(ME->getMemberDecl())) { + auto receiverTy = ME->getBase()->IgnoreImpCasts()->getType(); + return cxtype::MakeCXType(receiverTy, TU); + } + } + return cxtype::MakeCXType(QualType(), TU); } _______________________________________________ cfe-commits mailing list cfe-commits@lists.llvm.org http://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits