objective-c: Don't warn when a category does not implement a method

declared in its adopted protocol when another category declares it  
because that category will implement it. // rdar://11186449

llvm-svn: 154132
This commit is contained in:
Fariborz Jahanian 2012-04-05 22:14:12 +00:00
parent 64aa24e13f
commit c806b90717
4 changed files with 40 additions and 17 deletions

View File

@ -901,14 +901,14 @@ public:
// Lookup a method. First, we search locally. If a method isn't
// found, we search referenced protocols and class categories.
ObjCMethodDecl *lookupMethod(Selector Sel, bool isInstance,
bool noCategoryLookup= false) const;
bool shallowCategoryLookup= false) const;
ObjCMethodDecl *lookupInstanceMethod(Selector Sel,
bool noCategoryLookup = false) const {
return lookupMethod(Sel, true/*isInstance*/, noCategoryLookup);
bool shallowCategoryLookup = false) const {
return lookupMethod(Sel, true/*isInstance*/, shallowCategoryLookup);
}
ObjCMethodDecl *lookupClassMethod(Selector Sel,
bool noCategoryLookup = false) const {
return lookupMethod(Sel, false/*isInstance*/, noCategoryLookup);
bool shallowCategoryLookup = false) const {
return lookupMethod(Sel, false/*isInstance*/, shallowCategoryLookup);
}
ObjCInterfaceDecl *lookupInheritedClass(const IdentifierInfo *ICName);

View File

@ -316,9 +316,9 @@ ObjCInterfaceDecl *ObjCInterfaceDecl::lookupInheritedClass(
/// lookupMethod - This method returns an instance/class method by looking in
/// the class, its categories, and its super classes (using a linear search).
ObjCMethodDecl *ObjCInterfaceDecl::lookupMethod(Selector Sel,
bool isInstance,
bool noCategoryLookup) const {
ObjCMethodDecl *ObjCInterfaceDecl::lookupMethod(Selector Sel,
bool isInstance,
bool shallowCategoryLookup) const {
// FIXME: Should make sure no callers ever do this.
if (!hasDefinition())
return 0;
@ -339,13 +339,14 @@ ObjCMethodDecl *ObjCInterfaceDecl::lookupMethod(Selector Sel,
I != E; ++I)
if ((MethodDecl = (*I)->lookupMethod(Sel, isInstance)))
return MethodDecl;
if (!noCategoryLookup) {
// Didn't find one yet - now look through categories.
ObjCCategoryDecl *CatDecl = ClassDecl->getCategoryList();
while (CatDecl) {
if ((MethodDecl = CatDecl->getMethod(Sel, isInstance)))
return MethodDecl;
// Didn't find one yet - now look through categories.
ObjCCategoryDecl *CatDecl = ClassDecl->getCategoryList();
while (CatDecl) {
if ((MethodDecl = CatDecl->getMethod(Sel, isInstance)))
return MethodDecl;
if (!shallowCategoryLookup) {
// Didn't find one yet - look through protocols.
const ObjCList<ObjCProtocolDecl> &Protocols =
CatDecl->getReferencedProtocols();
@ -353,9 +354,10 @@ ObjCMethodDecl *ObjCInterfaceDecl::lookupMethod(Selector Sel,
E = Protocols.end(); I != E; ++I)
if ((MethodDecl = (*I)->lookupMethod(Sel, isInstance)))
return MethodDecl;
CatDecl = CatDecl->getNextClassCategory();
}
CatDecl = CatDecl->getNextClassCategory();
}
ClassDecl = ClassDecl->getSuperClass();
}
return NULL;

View File

@ -1537,7 +1537,7 @@ void Sema::CheckProtocolMethodDefs(SourceLocation ImpLoc,
// uses the protocol.
if (ObjCMethodDecl *MethodInClass =
IDecl->lookupInstanceMethod(method->getSelector(),
true /*noCategoryLookup*/))
true /*shallowCategoryLookup*/))
if (C || MethodInClass->isSynthesized())
continue;
unsigned DIAG = diag::warn_unimplemented_protocol_method;
@ -1561,7 +1561,7 @@ void Sema::CheckProtocolMethodDefs(SourceLocation ImpLoc,
(!Super || !Super->lookupClassMethod(method->getSelector()))) {
// See above comment for instance method lookups.
if (C && IDecl->lookupClassMethod(method->getSelector(),
true /*noCategoryLookup*/))
true /*shallowCategoryLookup*/))
continue;
unsigned DIAG = diag::warn_unimplemented_protocol_method;
if (Diags.getDiagnosticLevel(DIAG, ImpLoc) !=

View File

@ -51,3 +51,24 @@
@implementation NSObject (FooConformance)
@end
// rdar://11186449
// Don't warn when a category does not implemented a method imported
// by its protocol because another category has its declaration and
// that category will implement it.
@interface NSOrderedSet @end
@interface NSOrderedSet(CoolectionImplements)
- (unsigned char)containsObject:(id)object;
@end
@protocol Collection
- (unsigned char)containsObject:(id)object;
@end
@interface NSOrderedSet (CollectionConformance) <Collection>
@end
@implementation NSOrderedSet (CollectionConformance)
@end