зеркало из 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;
|
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());
|
SourceLocation());
|
||||||
MsgExprs.push_back(Unop);
|
MsgExprs.push_back(Unop);
|
||||||
} else {
|
} 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());
|
recExpr = new CastExpr(Context->getObjcIdType(), recExpr, SourceLocation());
|
||||||
MsgExprs.push_back(recExpr);
|
MsgExprs.push_back(recExpr);
|
||||||
}
|
}
|
||||||
|
|
|
@ -2232,14 +2232,32 @@ Sema::ExprResult Sema::ActOnInstanceMessage(
|
||||||
static_cast<PointerType*>(receiverType.getTypePtr());
|
static_cast<PointerType*>(receiverType.getTypePtr());
|
||||||
receiverType = pointerType->getPointeeType();
|
receiverType = pointerType->getPointeeType();
|
||||||
}
|
}
|
||||||
assert(ObjcInterfaceType::classof(receiverType.getTypePtr()) &&
|
ObjcInterfaceDecl* ClassDecl;
|
||||||
"bad receiver type");
|
if (ObjcQualifiedInterfaceType *QIT =
|
||||||
ObjcInterfaceDecl* ClassDecl = static_cast<ObjcInterfaceType*>(
|
dyn_cast<ObjcQualifiedInterfaceType>(receiverType)) {
|
||||||
receiverType.getTypePtr())->getDecl();
|
ObjcInterfaceType * OITypePtr = QIT->getInterfaceType();
|
||||||
// FIXME: consider using InstanceMethodPool, since it will be faster
|
|
||||||
// than the following method (which can do *many* linear searches). The
|
ClassDecl = OITypePtr->getDecl();
|
||||||
// idea is to add class info to InstanceMethodPool...
|
Method = ClassDecl->lookupInstanceMethod(Sel);
|
||||||
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 (!Method) {
|
||||||
// If we have an implementation in scope, check "private" methods.
|
// If we have an implementation in scope, check "private" methods.
|
||||||
if (ObjcImplementationDecl *ImpDecl =
|
if (ObjcImplementationDecl *ImpDecl =
|
||||||
|
|
|
@ -283,6 +283,9 @@ public:
|
||||||
ObjcMethodDecl** getClassMethods() const { return ClassMethods; }
|
ObjcMethodDecl** getClassMethods() const { return ClassMethods; }
|
||||||
int getNumClassMethods() const { return NumClassMethods; }
|
int getNumClassMethods() const { return NumClassMethods; }
|
||||||
|
|
||||||
|
ObjcMethodDecl *lookupInstanceMethod(Selector &Sel);
|
||||||
|
ObjcMethodDecl *lookupClassMethod(Selector &Sel);
|
||||||
|
|
||||||
bool isForwardDecl() const { return isForwardProtoDecl; }
|
bool isForwardDecl() const { return isForwardProtoDecl; }
|
||||||
void setForwardDecl(bool val) { isForwardProtoDecl = val; }
|
void setForwardDecl(bool val) { isForwardProtoDecl = val; }
|
||||||
|
|
||||||
|
|
Загрузка…
Ссылка в новой задаче