зеркало из https://github.com/microsoft/clang.git
Implemented when static typing is combined with protocols and use as receiver
type. git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@44685 91177308-0d34-0410-b5e6-96231b3b80d8
This commit is contained in:
Родитель
32c3904156
Коммит
7dd82836dc
42
AST/Decl.cpp
42
AST/Decl.cpp
|
@ -543,3 +543,45 @@ ObjcMethodDecl *ObjcCategoryImplDecl::lookupClassMethod(Selector &Sel) {
|
|||
}
|
||||
return NULL;
|
||||
}
|
||||
|
||||
// lookupInstanceMethod - Lookup a instance method in the protocol and protocols
|
||||
// it inherited.
|
||||
ObjcMethodDecl *ObjcProtocolDecl::lookupInstanceMethod(Selector &Sel) {
|
||||
ObjcMethodDecl *const*methods = getInstanceMethods();
|
||||
int methodCount = getNumInstanceMethods();
|
||||
for (int i = 0; i < methodCount; ++i) {
|
||||
if (methods[i]->getSelector() == Sel) {
|
||||
return methods[i];
|
||||
}
|
||||
}
|
||||
if (getNumReferencedProtocols() > 0) {
|
||||
ObjcProtocolDecl **RefPDecl = getReferencedProtocols();
|
||||
|
||||
for (int i = 0; i < getNumReferencedProtocols(); i++) {
|
||||
if (ObjcMethodDecl *Method = RefPDecl[i]->lookupInstanceMethod(Sel))
|
||||
return Method;
|
||||
}
|
||||
}
|
||||
return NULL;
|
||||
}
|
||||
|
||||
// lookupInstanceMethod - Lookup a class method in the protocol and protocols
|
||||
// it inherited.
|
||||
ObjcMethodDecl *ObjcProtocolDecl::lookupClassMethod(Selector &Sel) {
|
||||
ObjcMethodDecl *const*methods = getClassMethods();
|
||||
int methodCount = getNumClassMethods();
|
||||
for (int i = 0; i < methodCount; ++i) {
|
||||
if (methods[i]->getSelector() == Sel) {
|
||||
return methods[i];
|
||||
}
|
||||
}
|
||||
if (getNumReferencedProtocols() > 0) {
|
||||
ObjcProtocolDecl **RefPDecl = getReferencedProtocols();
|
||||
|
||||
for (int i = 0; i < getNumReferencedProtocols(); i++) {
|
||||
if (ObjcMethodDecl *Method = RefPDecl[i]->lookupClassMethod(Sel))
|
||||
return Method;
|
||||
}
|
||||
}
|
||||
return NULL;
|
||||
}
|
||||
|
|
|
@ -1446,6 +1446,10 @@ Stmt *RewriteTest::RewriteMessageExpr(ObjCMessageExpr *Exp) {
|
|||
SourceLocation());
|
||||
MsgExprs.push_back(Unop);
|
||||
} else {
|
||||
// Remove all type-casts because it may contain objc-style types; e.g.
|
||||
// Foo<Proto> *.
|
||||
while (CastExpr *CE = dyn_cast<CastExpr>(recExpr))
|
||||
recExpr = CE->getSubExpr();
|
||||
recExpr = new CastExpr(Context->getObjcIdType(), recExpr, SourceLocation());
|
||||
MsgExprs.push_back(recExpr);
|
||||
}
|
||||
|
|
|
@ -2232,14 +2232,32 @@ Sema::ExprResult Sema::ActOnInstanceMessage(
|
|||
static_cast<PointerType*>(receiverType.getTypePtr());
|
||||
receiverType = pointerType->getPointeeType();
|
||||
}
|
||||
assert(ObjcInterfaceType::classof(receiverType.getTypePtr()) &&
|
||||
"bad receiver type");
|
||||
ObjcInterfaceDecl* ClassDecl = static_cast<ObjcInterfaceType*>(
|
||||
receiverType.getTypePtr())->getDecl();
|
||||
// FIXME: consider using InstanceMethodPool, since it will be faster
|
||||
// than the following method (which can do *many* linear searches). The
|
||||
// idea is to add class info to InstanceMethodPool...
|
||||
Method = ClassDecl->lookupInstanceMethod(Sel);
|
||||
ObjcInterfaceDecl* ClassDecl;
|
||||
if (ObjcQualifiedInterfaceType *QIT =
|
||||
dyn_cast<ObjcQualifiedInterfaceType>(receiverType)) {
|
||||
ObjcInterfaceType * OITypePtr = QIT->getInterfaceType();
|
||||
|
||||
ClassDecl = OITypePtr->getDecl();
|
||||
Method = ClassDecl->lookupInstanceMethod(Sel);
|
||||
if (!Method) {
|
||||
// search protocols
|
||||
for (unsigned i = 0; i < QIT->getNumProtocols(); i++) {
|
||||
ObjcProtocolDecl *PDecl = QIT->getProtocols(i);
|
||||
if (PDecl && (Method = PDecl->lookupInstanceMethod(Sel)))
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
else {
|
||||
assert(ObjcInterfaceType::classof(receiverType.getTypePtr()) &&
|
||||
"bad receiver type");
|
||||
ClassDecl = static_cast<ObjcInterfaceType*>(
|
||||
receiverType.getTypePtr())->getDecl();
|
||||
// FIXME: consider using InstanceMethodPool, since it will be faster
|
||||
// than the following method (which can do *many* linear searches). The
|
||||
// idea is to add class info to InstanceMethodPool...
|
||||
Method = ClassDecl->lookupInstanceMethod(Sel);
|
||||
}
|
||||
if (!Method) {
|
||||
// If we have an implementation in scope, check "private" methods.
|
||||
if (ObjcImplementationDecl *ImpDecl =
|
||||
|
|
|
@ -283,6 +283,9 @@ public:
|
|||
ObjcMethodDecl** getClassMethods() const { return ClassMethods; }
|
||||
int getNumClassMethods() const { return NumClassMethods; }
|
||||
|
||||
ObjcMethodDecl *lookupInstanceMethod(Selector &Sel);
|
||||
ObjcMethodDecl *lookupClassMethod(Selector &Sel);
|
||||
|
||||
bool isForwardDecl() const { return isForwardProtoDecl; }
|
||||
void setForwardDecl(bool val) { isForwardProtoDecl = val; }
|
||||
|
||||
|
|
Загрузка…
Ссылка в новой задаче