Settled rule on warning on unimplemented property in
category implementation when some implementations
are missing in the primary class implementation.
(fixes radar 6505200).


git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@94014 91177308-0d34-0410-b5e6-96231b3b80d8
diff --git a/lib/Sema/SemaDeclObjC.cpp b/lib/Sema/SemaDeclObjC.cpp
index a0086ec..3738b9c 100644
--- a/lib/Sema/SemaDeclObjC.cpp
+++ b/lib/Sema/SemaDeclObjC.cpp
@@ -1101,6 +1101,17 @@
          E = IDecl->protocol_end(); PI != E; ++PI)
       CollectImmediateProperties((*PI), PropMap);
   }
+  if (ObjCCategoryDecl *CATDecl = dyn_cast<ObjCCategoryDecl>(CDecl)) {
+    for (ObjCContainerDecl::prop_iterator P = CATDecl->prop_begin(),
+         E = CATDecl->prop_end(); P != E; ++P) {
+      ObjCPropertyDecl *Prop = (*P);
+      PropMap[Prop->getIdentifier()] = Prop;
+    }
+    // scan through class's protocols.
+    for (ObjCInterfaceDecl::protocol_iterator PI = CATDecl->protocol_begin(),
+         E = CATDecl->protocol_end(); PI != E; ++PI)
+      CollectImmediateProperties((*PI), PropMap);
+  }  
   else if (ObjCProtocolDecl *PDecl = dyn_cast<ObjCProtocolDecl>(CDecl)) {
     for (ObjCProtocolDecl::prop_iterator P = PDecl->prop_begin(),
          E = PDecl->prop_end(); P != E; ++P) {
@@ -1141,7 +1152,9 @@
   
     if (!InsMap.count(Prop->getGetterName())) {
       Diag(Prop->getLocation(),
-           diag::warn_setter_getter_impl_required)
+           isa<ObjCCategoryDecl>(CDecl) ? 
+            diag::warn_setter_getter_impl_required_in_category : 
+            diag::warn_setter_getter_impl_required)
       << Prop->getDeclName() << Prop->getGetterName();
       Diag(IMPDecl->getLocation(),
            diag::note_property_impl_required);
@@ -1149,6 +1162,8 @@
     
     if (!Prop->isReadOnly() && !InsMap.count(Prop->getSetterName())) {
       Diag(Prop->getLocation(),
+           isa<ObjCCategoryDecl>(CDecl) ? 
+           diag::warn_setter_getter_impl_required_in_category :
            diag::warn_setter_getter_impl_required)
       << Prop->getDeclName() << Prop->getSetterName();
       Diag(IMPDecl->getLocation(),
@@ -1212,7 +1227,18 @@
            E = C->protocol_end(); PI != E; ++PI)
         CheckProtocolMethodDefs(IMPDecl->getLocation(), *PI, IncompleteImpl,
                                 InsMap, ClsMap, C->getClassInterface());
-    }
+      // Report unimplemented properties in the category as well.
+      // When reporting on missing setter/getters, do not report when
+      // setter/getter is implemented in category's primary class 
+      // implementation.
+      if (ObjCInterfaceDecl *ID = C->getClassInterface())
+        if (ObjCImplDecl *IMP = ID->getImplementation()) {
+          for (ObjCImplementationDecl::instmeth_iterator
+               I = IMP->instmeth_begin(), E = IMP->instmeth_end(); I!=E; ++I)
+            InsMap.insert((*I)->getSelector());
+        }
+      DiagnoseUnimplementedProperties(IMPDecl, CDecl, InsMap);      
+    } 
   } else
     assert(false && "invalid ObjCContainerDecl type.");
 }