ObjectiveC: Don't warn when method implemented in
category is declared in category's primary
class's super class. Because the super class is
expected to implemented the method. // rdar://15580969
llvm-svn: 196531
diff --git a/clang/lib/Sema/SemaDeclObjC.cpp b/clang/lib/Sema/SemaDeclObjC.cpp
index 6020473..421b797 100644
--- a/clang/lib/Sema/SemaDeclObjC.cpp
+++ b/clang/lib/Sema/SemaDeclObjC.cpp
@@ -1867,20 +1867,6 @@
/// warns each time an exact match is found.
void Sema::CheckCategoryVsClassMethodMatches(
ObjCCategoryImplDecl *CatIMPDecl) {
- SelectorSet InsMap, ClsMap;
-
- for (ObjCImplementationDecl::instmeth_iterator
- I = CatIMPDecl->instmeth_begin(),
- E = CatIMPDecl->instmeth_end(); I!=E; ++I)
- InsMap.insert((*I)->getSelector());
-
- for (ObjCImplementationDecl::classmeth_iterator
- I = CatIMPDecl->classmeth_begin(),
- E = CatIMPDecl->classmeth_end(); I != E; ++I)
- ClsMap.insert((*I)->getSelector());
- if (InsMap.empty() && ClsMap.empty())
- return;
-
// Get category's primary class.
ObjCCategoryDecl *CatDecl = CatIMPDecl->getCategoryDecl();
if (!CatDecl)
@@ -1888,6 +1874,32 @@
ObjCInterfaceDecl *IDecl = CatDecl->getClassInterface();
if (!IDecl)
return;
+ ObjCInterfaceDecl *SuperIDecl = IDecl->getSuperClass();
+ SelectorSet InsMap, ClsMap;
+
+ for (ObjCImplementationDecl::instmeth_iterator
+ I = CatIMPDecl->instmeth_begin(),
+ E = CatIMPDecl->instmeth_end(); I!=E; ++I) {
+ Selector Sel = (*I)->getSelector();
+ // When checking for methods implemented in the category, skip over
+ // those declared in category class's super class. This is because
+ // the super class must implement the method.
+ if (SuperIDecl && SuperIDecl->lookupMethod(Sel, true))
+ continue;
+ InsMap.insert(Sel);
+ }
+
+ for (ObjCImplementationDecl::classmeth_iterator
+ I = CatIMPDecl->classmeth_begin(),
+ E = CatIMPDecl->classmeth_end(); I != E; ++I) {
+ Selector Sel = (*I)->getSelector();
+ if (SuperIDecl && SuperIDecl->lookupMethod(Sel, false))
+ continue;
+ ClsMap.insert(Sel);
+ }
+ if (InsMap.empty() && ClsMap.empty())
+ return;
+
SelectorSet InsMapSeen, ClsMapSeen;
bool IncompleteImpl = false;
MatchAllMethodDeclarations(InsMap, ClsMap, InsMapSeen, ClsMapSeen,
diff --git a/clang/test/SemaObjC/incomplete-implementation.m b/clang/test/SemaObjC/incomplete-implementation.m
index 4b8d600..74dea2a 100644
--- a/clang/test/SemaObjC/incomplete-implementation.m
+++ b/clang/test/SemaObjC/incomplete-implementation.m
@@ -39,3 +39,29 @@
@end
+// rdar://15580969
+typedef char BOOL;
+
+@protocol NSObject
+- (BOOL)isEqual:(id)object;
+@end
+
+@interface NSObject <NSObject>
+@end
+
+@protocol NSApplicationDelegate <NSObject>
+- (void)ImpleThisMethod; // expected-note {{method 'ImpleThisMethod' declared here}}
+@end
+
+@interface AppDelegate : NSObject <NSApplicationDelegate>
+@end
+
+@implementation AppDelegate (MRRCategory)
+
+- (BOOL)isEqual:(id)object
+{
+ return __objc_no;
+}
+
+- (void)ImpleThisMethod {} // expected-warning {{category is implementing a method which will also be implemented by its primary class}}
+@end