]> granicus.if.org Git - clang/commitdiff
This patch fixes a bug whereby, clang skipped
authorFariborz Jahanian <fjahanian@apple.com>
Tue, 29 Jun 2010 18:12:32 +0000 (18:12 +0000)
committerFariborz Jahanian <fjahanian@apple.com>
Tue, 29 Jun 2010 18:12:32 +0000 (18:12 +0000)
unimplemented property warning for properties
coming from class's conformin protocol. It also
simplifies the algorithm in the process.
Fixes radar 8035776.

git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@107174 91177308-0d34-0410-b5e6-96231b3b80d8

lib/Sema/Sema.h
lib/Sema/SemaObjCProperty.cpp
test/SemaObjC/super-class-protocol-conformance.m

index 325add767172ad813530af0ff09331383964ee69..f93a9492b2209d7b3df0bfbc3792dbc2594c0ce5 100644 (file)
@@ -1573,16 +1573,9 @@ public:
   /// CollectImmediateProperties - This routine collects all properties in
   /// the class and its conforming protocols; but not those it its super class.
   void CollectImmediateProperties(ObjCContainerDecl *CDecl,
-                  llvm::DenseMap<IdentifierInfo *, ObjCPropertyDecl*>& PropMap);
+            llvm::DenseMap<IdentifierInfo *, ObjCPropertyDecl*>& PropMap,
+            llvm::DenseMap<IdentifierInfo *, ObjCPropertyDecl*>& SuperPropMap);
   
-  /// ProtocolConformsToSuperClass - Returns true if class has a super class
-  /// and it, or its nested super class conforms to the protocol.
-  bool ProtocolConformsToSuperClass(const ObjCInterfaceDecl *IDecl, 
-                                    const ObjCProtocolDecl *PDecl);
-  /// ProtocolConformsToProtocol - Returns true if 2nd Protocol (PDecl) is
-  /// qualified by the 1st.
-  bool ProtocolConformsToProtocol(const ObjCProtocolDecl *NestedProtocol,
-                                  const ObjCProtocolDecl *PDecl);
 
   /// LookupPropertyDecl - Looks up a property in the current class and all
   /// its protocols.
index a27d2a8a2f5f223d8bbc441029c9bef9d764b17d..44cd271753f341b001587aa081945cce48556f95 100644 (file)
@@ -778,7 +778,8 @@ bool Sema::isPropertyReadonly(ObjCPropertyDecl *PDecl,
 /// CollectImmediateProperties - This routine collects all properties in
 /// the class and its conforming protocols; but not those it its super class.
 void Sema::CollectImmediateProperties(ObjCContainerDecl *CDecl,
-                llvm::DenseMap<IdentifierInfo *, ObjCPropertyDecl*>& PropMap) {
+            llvm::DenseMap<IdentifierInfo *, ObjCPropertyDecl*>& PropMap,
+            llvm::DenseMap<IdentifierInfo *, ObjCPropertyDecl*>& SuperPropMap) {
   if (ObjCInterfaceDecl *IDecl = dyn_cast<ObjCInterfaceDecl>(CDecl)) {
     for (ObjCContainerDecl::prop_iterator P = IDecl->prop_begin(),
          E = IDecl->prop_end(); P != E; ++P) {
@@ -788,10 +789,7 @@ void Sema::CollectImmediateProperties(ObjCContainerDecl *CDecl,
     // scan through class's protocols.
     for (ObjCInterfaceDecl::protocol_iterator PI = IDecl->protocol_begin(),
          E = IDecl->protocol_end(); PI != E; ++PI)
-      // Exclude property for protocols which conform to class's super-class, 
-      // as super-class has to implement the property.
-      if (!ProtocolConformsToSuperClass(IDecl, (*PI)))
-        CollectImmediateProperties((*PI), PropMap);
+        CollectImmediateProperties((*PI), PropMap, SuperPropMap);
   }
   if (ObjCCategoryDecl *CATDecl = dyn_cast<ObjCCategoryDecl>(CDecl)) {
     if (!CATDecl->IsClassExtension())
@@ -803,20 +801,25 @@ void Sema::CollectImmediateProperties(ObjCContainerDecl *CDecl,
     // scan through class's protocols.
     for (ObjCInterfaceDecl::protocol_iterator PI = CATDecl->protocol_begin(),
          E = CATDecl->protocol_end(); PI != E; ++PI)
-      CollectImmediateProperties((*PI), PropMap);
+      CollectImmediateProperties((*PI), PropMap, SuperPropMap);
   }
   else if (ObjCProtocolDecl *PDecl = dyn_cast<ObjCProtocolDecl>(CDecl)) {
     for (ObjCProtocolDecl::prop_iterator P = PDecl->prop_begin(),
          E = PDecl->prop_end(); P != E; ++P) {
       ObjCPropertyDecl *Prop = (*P);
-      ObjCPropertyDecl *&PropEntry = PropMap[Prop->getIdentifier()];
-      if (!PropEntry)
-        PropEntry = Prop;
+      ObjCPropertyDecl *PropertyFromSuper = SuperPropMap[Prop->getIdentifier()];
+      // Exclude property for protocols which conform to class's super-class, 
+      // as super-class has to implement the property.
+      if (!PropertyFromSuper || PropertyFromSuper != Prop) {
+        ObjCPropertyDecl *&PropEntry = PropMap[Prop->getIdentifier()];
+        if (!PropEntry)
+          PropEntry = Prop;
+      }
     }
     // scan through protocol's protocols.
     for (ObjCProtocolDecl::protocol_iterator PI = PDecl->protocol_begin(),
          E = PDecl->protocol_end(); PI != E; ++PI)
-      CollectImmediateProperties((*PI), PropMap);
+      CollectImmediateProperties((*PI), PropMap, SuperPropMap);
   }
 }
 
@@ -861,33 +864,6 @@ static void CollectSuperClassPropertyImplementations(ObjCInterfaceDecl *CDecl,
   }
 }
 
-/// ProtocolConformsToSuperClass - Returns true if class's given protocol
-/// conforms to one of its super class's protocols.
-bool Sema::ProtocolConformsToSuperClass(const ObjCInterfaceDecl *IDecl,
-                                        const ObjCProtocolDecl *PDecl) {
-  if (const ObjCInterfaceDecl *CDecl = IDecl->getSuperClass()) {
-    for (ObjCInterfaceDecl::protocol_iterator PI = CDecl->protocol_begin(),
-         E = CDecl->protocol_end(); PI != E; ++PI) {
-      if (ProtocolConformsToProtocol((*PI), PDecl))
-        return true;
-      return ProtocolConformsToSuperClass(CDecl, PDecl);
-    }
-  }
-  return false;
-}
-
-bool Sema::ProtocolConformsToProtocol(const ObjCProtocolDecl *NestedProtocol,
-                                      const ObjCProtocolDecl *PDecl) {
-  if (PDecl->getIdentifier() == NestedProtocol->getIdentifier())
-    return true;
-  // scan through protocol's protocols.
-  for (ObjCProtocolDecl::protocol_iterator PI = PDecl->protocol_begin(),
-       E = PDecl->protocol_end(); PI != E; ++PI)
-    if (ProtocolConformsToProtocol(NestedProtocol, (*PI)))
-      return true;
-  return false;
-}
-
 /// LookupPropertyDecl - Looks up a property in the current class and all
 /// its protocols.
 ObjCPropertyDecl *Sema::LookupPropertyDecl(const ObjCContainerDecl *CDecl,
@@ -959,8 +935,12 @@ void Sema::DefaultSynthesizeProperties (Scope *S, ObjCImplDecl* IMPDecl,
 void Sema::DiagnoseUnimplementedProperties(Scope *S, ObjCImplDecl* IMPDecl,
                                       ObjCContainerDecl *CDecl,
                                       const llvm::DenseSet<Selector>& InsMap) {
+  llvm::DenseMap<IdentifierInfo *, ObjCPropertyDecl*> SuperPropMap;
+  if (ObjCInterfaceDecl *IDecl = dyn_cast<ObjCInterfaceDecl>(CDecl))
+    CollectSuperClassPropertyImplementations(IDecl, SuperPropMap);
+  
   llvm::DenseMap<IdentifierInfo *, ObjCPropertyDecl*> PropMap;
-  CollectImmediateProperties(CDecl, PropMap);
+  CollectImmediateProperties(CDecl, PropMap, SuperPropMap);
   if (PropMap.empty())
     return;
 
index ac8bc70a99892369c69870a8465a2a1eccfaad38..f555c3203dcb9917b9ffa0ff1cf82afb47ade4a0 100644 (file)
 @interface SubClass5 : SubClass4 <NewProtocol> @end
 @implementation SubClass5 @end   // expected-note {{implementation is here}}
 
+
+// Radar 8035776
+@protocol SuperProtocol
+@end
+
+@interface Super <SuperProtocol> 
+@end
+
+@protocol ProtocolWithProperty <SuperProtocol>
+@property (readonly, assign) id invalidationBacktrace; // expected-warning {{property 'invalidationBacktrace' requires method 'invalidationBacktrace' to be defined}}
+@end
+
+@interface INTF : Super <ProtocolWithProperty> 
+@end
+
+@implementation INTF @end // expected-note {{implementation is here}}