Prevent invalid warnings about incomplete implementations for methods
which are inherited from base clases or protocols.


git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@55790 91177308-0d34-0410-b5e6-96231b3b80d8
diff --git a/lib/Sema/SemaDeclObjC.cpp b/lib/Sema/SemaDeclObjC.cpp
index 3562ba9..240d760 100644
--- a/lib/Sema/SemaDeclObjC.cpp
+++ b/lib/Sema/SemaDeclObjC.cpp
@@ -128,7 +128,7 @@
 }
 
 /// ActOnCompatiblityAlias - this action is called after complete parsing of
-/// @compaatibility_alias declaration. It sets up the alias relationships.
+/// @compatibility_alias declaration. It sets up the alias relationships.
 Sema::DeclTy *Sema::ActOnCompatiblityAlias(SourceLocation AtLoc,
                                            IdentifierInfo *AliasName, 
                                            SourceLocation AliasLocation,
@@ -203,8 +203,8 @@
 }
 
 /// FindProtocolDeclaration - This routine looks up protocols and
-/// issuer error if they are not declared. It returns list of protocol
-/// declarations in its 'Protocols' argument.
+/// issues an error if they are not declared. It returns list of
+/// protocol declarations in its 'Protocols' argument.
 void
 Sema::FindProtocolDeclaration(bool WarnOnDeclarations,
                               const IdentifierLocPair *ProtocolId,
@@ -582,27 +582,37 @@
                                    ObjCProtocolDecl *PDecl,
                                    bool& IncompleteImpl,
                                    const llvm::DenseSet<Selector> &InsMap,
-                                   const llvm::DenseSet<Selector> &ClsMap) {
+                                   const llvm::DenseSet<Selector> &ClsMap,
+                                   ObjCInterfaceDecl *IDecl) {
+  ObjCInterfaceDecl *Super = IDecl->getSuperClass();
+
+  // If a method lookup fails locally we still need to look and see if
+  // the method was implemented by a base class or an inherited
+  // protocol. This lookup is slow, but occurs rarely in correct code
+  // and otherwise would terminate in a warning.
+
   // check unimplemented instance methods.
   for (ObjCProtocolDecl::instmeth_iterator I = PDecl->instmeth_begin(), 
        E = PDecl->instmeth_end(); I != E; ++I) {
     ObjCMethodDecl *method = *I;
-    if (!InsMap.count(method->getSelector()) && 
-        method->getImplementationControl() != ObjCMethodDecl::Optional)
+    if (method->getImplementationControl() != ObjCMethodDecl::Optional && 
+        !InsMap.count(method->getSelector()) &&
+        (!Super || !Super->lookupInstanceMethod(method->getSelector())))
       WarnUndefinedMethod(ImpLoc, method, IncompleteImpl);
   }
   // check unimplemented class methods
   for (ObjCProtocolDecl::classmeth_iterator I = PDecl->classmeth_begin(), 
        E = PDecl->classmeth_end(); I != E; ++I) {
     ObjCMethodDecl *method = *I;
-    if (!ClsMap.count(method->getSelector()) &&
-        method->getImplementationControl() != ObjCMethodDecl::Optional)
+    if (method->getImplementationControl() != ObjCMethodDecl::Optional &&
+        !ClsMap.count(method->getSelector()) &&
+        (!Super || !Super->lookupClassMethod(method->getSelector())))
       WarnUndefinedMethod(ImpLoc, method, IncompleteImpl);
   }
   // Check on this protocols's referenced protocols, recursively.
   for (ObjCProtocolDecl::protocol_iterator PI = PDecl->protocol_begin(),
        E = PDecl->protocol_end(); PI != E; ++PI)
-    CheckProtocolMethodDefs(ImpLoc, *PI, IncompleteImpl, InsMap, ClsMap);
+    CheckProtocolMethodDefs(ImpLoc, *PI, IncompleteImpl, InsMap, ClsMap, IDecl);
 }
 
 void Sema::ImplMethodsVsClassMethods(ObjCImplementationDecl* IMPDecl, 
@@ -639,11 +649,11 @@
   for (ObjCList<ObjCProtocolDecl>::iterator I = Protocols.begin(),
        E = Protocols.end(); I != E; ++I)
     CheckProtocolMethodDefs(IMPDecl->getLocation(), *I, 
-                            IncompleteImpl, InsMap, ClsMap);
+                            IncompleteImpl, InsMap, ClsMap, IDecl);
 }
 
 /// ImplCategoryMethodsVsIntfMethods - Checks that methods declared in the
-/// category interface is implemented in the category @implementation.
+/// category interface are implemented in the category @implementation.
 void Sema::ImplCategoryMethodsVsIntfMethods(ObjCCategoryImplDecl *CatImplDecl,
                                             ObjCCategoryDecl *CatClassDecl) {
   llvm::DenseSet<Selector> InsMap;
@@ -677,7 +687,7 @@
   for (ObjCCategoryDecl::protocol_iterator PI = CatClassDecl->protocol_begin(),
        E = CatClassDecl->protocol_end(); PI != E; ++PI)
     CheckProtocolMethodDefs(CatImplDecl->getLocation(), *PI, IncompleteImpl, 
-                            InsMap, ClsMap);
+                            InsMap, ClsMap, CatClassDecl->getClassInterface());
 }
 
 /// ActOnForwardClassDeclaration -