mirror of
https://github.com/llvm/llvm-project.git
synced 2025-04-27 14:26:09 +00:00
[libclang] Introduce clang_Cursor_getReceiverType which returns the CXType for
the receiver of an ObjC message expression. rdar://12578643 llvm-svn: 167201
This commit is contained in:
parent
b351c8d692
commit
b26a24cca2
@ -24,7 +24,7 @@
|
||||
#include "clang-c/CXString.h"
|
||||
|
||||
#define CINDEX_VERSION_MAJOR 0
|
||||
#define CINDEX_VERSION_MINOR 5
|
||||
#define CINDEX_VERSION_MINOR 6
|
||||
|
||||
#define CINDEX_VERSION_ENCODE(major, minor) ( \
|
||||
((major) * 10000) \
|
||||
@ -3196,6 +3196,12 @@ CINDEX_LINKAGE int clang_Cursor_getObjCSelectorIndex(CXCursor);
|
||||
*/
|
||||
CINDEX_LINKAGE int clang_Cursor_isDynamicCall(CXCursor C);
|
||||
|
||||
/**
|
||||
* \brief Given a cursor pointing to an ObjC message, returns the CXType of the
|
||||
* receiver.
|
||||
*/
|
||||
CINDEX_LINKAGE CXType clang_Cursor_getReceiverType(CXCursor C);
|
||||
|
||||
/**
|
||||
* \brief Given a cursor that represents a declaration, return the associated
|
||||
* comment's source range. The range may include multiple consecutive comments
|
||||
|
@ -1195,6 +1195,17 @@ public:
|
||||
return SourceLocation();
|
||||
}
|
||||
|
||||
/// \brief Retrieve the receiver type to which this message is being directed.
|
||||
///
|
||||
/// This routine cross-cuts all of the different kinds of message
|
||||
/// sends to determine what the underlying (statically known) type
|
||||
/// of the receiver will be; use \c getReceiverKind() to determine
|
||||
/// whether the message is a class or an instance method, whether it
|
||||
/// is a send to super or not, etc.
|
||||
///
|
||||
/// \returns The type of the receiver.
|
||||
QualType getReceiverType() const;
|
||||
|
||||
/// \brief Retrieve the Objective-C interface to which this message
|
||||
/// is being directed, if known.
|
||||
///
|
||||
|
@ -3442,33 +3442,29 @@ Selector ObjCMessageExpr::getSelector() const {
|
||||
return Selector(SelectorOrMethod);
|
||||
}
|
||||
|
||||
ObjCInterfaceDecl *ObjCMessageExpr::getReceiverInterface() const {
|
||||
QualType ObjCMessageExpr::getReceiverType() const {
|
||||
switch (getReceiverKind()) {
|
||||
case Instance:
|
||||
if (const ObjCObjectPointerType *Ptr
|
||||
= getInstanceReceiver()->getType()->getAs<ObjCObjectPointerType>())
|
||||
return Ptr->getInterfaceDecl();
|
||||
break;
|
||||
|
||||
return getInstanceReceiver()->getType();
|
||||
case Class:
|
||||
if (const ObjCObjectType *Ty
|
||||
= getClassReceiver()->getAs<ObjCObjectType>())
|
||||
return Ty->getInterface();
|
||||
break;
|
||||
|
||||
return getClassReceiver();
|
||||
case SuperInstance:
|
||||
if (const ObjCObjectPointerType *Ptr
|
||||
= getSuperType()->getAs<ObjCObjectPointerType>())
|
||||
return Ptr->getInterfaceDecl();
|
||||
break;
|
||||
|
||||
case SuperClass:
|
||||
if (const ObjCObjectType *Iface
|
||||
= getSuperType()->getAs<ObjCObjectType>())
|
||||
return Iface->getInterface();
|
||||
break;
|
||||
return getSuperType();
|
||||
}
|
||||
|
||||
llvm_unreachable("unexpected receiver kind");
|
||||
}
|
||||
|
||||
ObjCInterfaceDecl *ObjCMessageExpr::getReceiverInterface() const {
|
||||
QualType T = getReceiverType();
|
||||
|
||||
if (const ObjCObjectPointerType *Ptr = T->getAs<ObjCObjectPointerType>())
|
||||
return Ptr->getInterfaceDecl();
|
||||
|
||||
if (const ObjCObjectType *Ty = T->getAs<ObjCObjectType>())
|
||||
return Ty->getInterface();
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
@ -50,10 +50,12 @@ void foo(SS *ss, IS* is, Class cls) {
|
||||
|
||||
// CHECK: 8:11 MemberRefExpr=meth:3:16 {{.*}} Dynamic-call
|
||||
// CHECK-NOT: 9:9 {{.*}} Dynamic-call
|
||||
// CHECK: 25:3 ObjCMessageExpr=meth:14:8 {{.*}} Dynamic-call
|
||||
// CHECK: 25:3 ObjCMessageExpr=meth:14:8 {{.*}} Dynamic-call Receiver-type=ObjCObjectPointer
|
||||
// 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: 35:3 ObjCMessageExpr=meth:14:8 {{.*}} Dynamic-call
|
||||
// CHECK: 35:3 ObjCMessageExpr=meth:14:8 {{.*}} Dynamic-call Receiver-type=ObjCObjectPointer
|
||||
// CHECK-NOT: 36:3 {{.*}} Dynamic-call
|
||||
// CHECK: 37:3 ObjCMessageExpr=ClsMeth:15:8 {{.*}} Dynamic-call
|
||||
// CHECK: 36:3 {{.*}} Receiver-type=ObjCInterface
|
||||
// CHECK: 37:3 ObjCMessageExpr=ClsMeth:15:8 {{.*}} Dynamic-call Receiver-type=ObjCClass
|
||||
|
@ -1955,6 +1955,12 @@ static int inspect_cursor_at(int argc, const char **argv) {
|
||||
printf(" Selector index=%d",clang_Cursor_getObjCSelectorIndex(Cursor));
|
||||
if (clang_Cursor_isDynamicCall(Cursor))
|
||||
printf(" Dynamic-call");
|
||||
if (Cursor.kind == CXCursor_ObjCMessageExpr) {
|
||||
CXType T = clang_Cursor_getReceiverType(Cursor);
|
||||
CXString S = clang_getTypeKindSpelling(T.kind);
|
||||
printf(" Receiver-type=%s", clang_getCString(S));
|
||||
clang_disposeString(S);
|
||||
}
|
||||
|
||||
{
|
||||
CXModule mod = clang_Cursor_getModule(Cursor);
|
||||
|
@ -15,6 +15,7 @@
|
||||
|
||||
#include "CXTranslationUnit.h"
|
||||
#include "CXCursor.h"
|
||||
#include "CXType.h"
|
||||
#include "CXString.h"
|
||||
#include "clang/Frontend/ASTUnit.h"
|
||||
#include "clang/AST/Decl.h"
|
||||
@ -1172,4 +1173,16 @@ int clang_Cursor_isDynamicCall(CXCursor C) {
|
||||
return 0;
|
||||
}
|
||||
|
||||
CXType clang_Cursor_getReceiverType(CXCursor C) {
|
||||
CXTranslationUnit TU = cxcursor::getCursorTU(C);
|
||||
const Expr *E = 0;
|
||||
if (clang_isExpression(C.kind))
|
||||
E = getCursorExpr(C);
|
||||
|
||||
if (const ObjCMessageExpr *MsgE = dyn_cast_or_null<ObjCMessageExpr>(E))
|
||||
return cxtype::MakeCXType(MsgE->getReceiverType(), TU);
|
||||
|
||||
return cxtype::MakeCXType(QualType(), TU);
|
||||
}
|
||||
|
||||
} // end: extern "C"
|
||||
|
@ -13,6 +13,7 @@ clang_Cursor_getNumArguments
|
||||
clang_Cursor_getObjCSelectorIndex
|
||||
clang_Cursor_getSpellingNameRange
|
||||
clang_Cursor_getTranslationUnit
|
||||
clang_Cursor_getReceiverType
|
||||
clang_Cursor_isDynamicCall
|
||||
clang_Cursor_isNull
|
||||
clang_Cursor_getModule
|
||||
|
Loading…
x
Reference in New Issue
Block a user