aboutsummaryrefslogtreecommitdiff
path: root/tools/libclang/CXCursor.cpp
diff options
context:
space:
mode:
authorArgyrios Kyrtzidis <akyrtzi@gmail.com>2012-07-02 23:54:36 +0000
committerArgyrios Kyrtzidis <akyrtzi@gmail.com>2012-07-02 23:54:36 +0000
commitf39a7aea7dd0bf0716a066e2db2f97ea8730e4fa (patch)
treefdcd2af9e8a3dc278eaecda2c16d22e2ef468185 /tools/libclang/CXCursor.cpp
parent6c89eafc90f5c51a0bf185a993961170aee530c2 (diff)
[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
Diffstat (limited to 'tools/libclang/CXCursor.cpp')
-rw-r--r--tools/libclang/CXCursor.cpp27
1 files changed, 26 insertions, 1 deletions
diff --git a/tools/libclang/CXCursor.cpp b/tools/libclang/CXCursor.cpp
index ae7d806c7f..2757af434c 100644
--- a/tools/libclang/CXCursor.cpp
+++ b/tools/libclang/CXCursor.cpp
@@ -1319,5 +1319,30 @@ void clang_disposeOverriddenCursors(CXCursor *overridden) {
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"