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:
Fariborz Jahanian 2007-12-07 21:21:21 +00:00
Родитель 32c3904156
Коммит 7dd82836dc
4 изменённых файлов: 75 добавлений и 8 удалений

Просмотреть файл

@ -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; }