diff options
author | Argyrios Kyrtzidis <akyrtzi@gmail.com> | 2012-07-02 23:54:36 +0000 |
---|---|---|
committer | Argyrios Kyrtzidis <akyrtzi@gmail.com> | 2012-07-02 23:54:36 +0000 |
commit | f39a7aea7dd0bf0716a066e2db2f97ea8730e4fa (patch) | |
tree | fdcd2af9e8a3dc278eaecda2c16d22e2ef468185 /tools/libclang/CXCursor.cpp | |
parent | 6c89eafc90f5c51a0bf185a993961170aee530c2 (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.cpp | 27 |
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" |