[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"