[libclang] Introduce clang_Cursor_isDynamicCall which,
given a cursor pointing to a C++ method call or an ObjC message,
returns non-zero if the method/message is "dynamic", meaning:
For a C++ method: the call is virtual.
For an ObjC message: the receiver is an object instance, not 'super' or a
specific class.
rdar://11779185
git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@159627 91177308-0d34-0410-b5e6-96231b3b80d8
diff --git a/tools/libclang/CXCursor.cpp b/tools/libclang/CXCursor.cpp
index ae7d806..2757af4 100644
--- a/tools/libclang/CXCursor.cpp
+++ b/tools/libclang/CXCursor.cpp
@@ -1319,5 +1319,30 @@
pool.AvailableCursors.push_back(Vec);
}
-
+
+int clang_Cursor_isDynamicCall(CXCursor C) {
+ const Expr *E = 0;
+ if (clang_isExpression(C.kind))
+ E = getCursorExpr(C);
+ if (!E)
+ return 0;
+
+ if (const ObjCMessageExpr *MsgE = dyn_cast<ObjCMessageExpr>(E))
+ return MsgE->getReceiverKind() == ObjCMessageExpr::Instance;
+
+ const MemberExpr *ME = 0;
+ 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()))
+ return MD->isVirtual() && !ME->hasQualifier();
+ }
+
+ return 0;
+}
+
} // end: extern "C"
diff --git a/tools/libclang/libclang.exports b/tools/libclang/libclang.exports
index 1272a02..3775ce1 100644
--- a/tools/libclang/libclang.exports
+++ b/tools/libclang/libclang.exports
@@ -12,6 +12,7 @@
clang_Cursor_getObjCSelectorIndex
clang_Cursor_getSpellingNameRange
clang_Cursor_getTranslationUnit
+clang_Cursor_isDynamicCall
clang_Cursor_isNull
clang_IndexAction_create
clang_IndexAction_dispose