]> granicus.if.org Git - clang/commitdiff
Do not issue warning on unimplemented property in the class, if it
authorFariborz Jahanian <fjahanian@apple.com>
Mon, 3 May 2010 15:49:20 +0000 (15:49 +0000)
committerFariborz Jahanian <fjahanian@apple.com>
Mon, 3 May 2010 15:49:20 +0000 (15:49 +0000)
conforms to a protocol as one of its super classes does. This is because
conforming super class will implement the property. This implements
new warning rules for unimplemented properties (radar 7884086).

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

lib/Sema/Sema.h
lib/Sema/SemaObjCProperty.cpp
test/SemaObjC/default-synthesize.m
test/SemaObjC/super-class-protocol-conformance.m [new file with mode: 0644]

index 6c52ae5ceeae3d174c1440a5ad99fa8f69f225bd..ba20ed1e1a7f5b835cf5f78dde095db66fe4e68c 100644 (file)
@@ -1539,6 +1539,15 @@ public:
   /// the class and its conforming protocols; but not those it its super class.
   void CollectImmediateProperties(ObjCContainerDecl *CDecl,
                   llvm::DenseMap<IdentifierInfo *, ObjCPropertyDecl*>& PropMap);
+  
+  /// 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 13c75e4fe960776ef4a7b84ac7e828c31fcc6191..b73739fc55513c5c6860cfbdfa256be8ee0a48dc 100644 (file)
@@ -719,7 +719,10 @@ 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)
-      CollectImmediateProperties((*PI), PropMap);
+      // 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);
   }
   if (ObjCCategoryDecl *CATDecl = dyn_cast<ObjCCategoryDecl>(CDecl)) {
     if (!CATDecl->IsClassExtension())
@@ -748,6 +751,33 @@ void Sema::CollectImmediateProperties(ObjCContainerDecl *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,
index 21453d38414589b66f777a4c2061965fff568786..283ad260a94e50366dd28af59a12b3e188082b93 100644 (file)
 
 @interface TopClass <TopProtocol> 
 {
-  id myString; // expected-note {{previously declared 'myString' here}}
+  id myString; 
 }
 @end
 
 @interface SubClass : TopClass <TopProtocol> 
 @end
 
-@implementation SubClass @end // expected-error {{property 'myString' attempting to use ivar 'myString' declared in super class 'TopClass'}}
+@implementation SubClass @end 
 
 // rdar: // 7920807
 @interface C @end
diff --git a/test/SemaObjC/super-class-protocol-conformance.m b/test/SemaObjC/super-class-protocol-conformance.m
new file mode 100644 (file)
index 0000000..ac8bc70
--- /dev/null
@@ -0,0 +1,47 @@
+// RUN: %clang_cc1 -fsyntax-only -verify %s
+// rdar: // 7884086
+
+@interface NSObject @end
+
+@protocol TopProtocol
+  @property (readonly) id myString; // expected-warning {{property 'myString' requires method 'myString' to be defined}}
+@end
+
+@protocol SubProtocol <TopProtocol>
+@end
+
+@interface TopClass : NSObject <TopProtocol> {}
+@end
+
+@interface SubClass : TopClass <SubProtocol> {}
+@end
+
+@interface SubClass1 : TopClass {}     
+@end
+
+@implementation SubClass1 @end // Test1 - No Warning
+
+@implementation TopClass  // expected-note {{implementation is here}}
+@end
+
+@implementation SubClass // Test3 - No Warning 
+@end
+
+@interface SubClass2  : TopClass<TopProtocol> 
+@end
+
+@implementation SubClass2 @end // Test 4 - No Warning
+
+@interface SubClass3 : TopClass<SubProtocol> @end
+@implementation SubClass3 @end // Test 5 - No Warning 
+
+@interface SubClass4 : SubClass3 @end
+@implementation SubClass4 @end // Test 5 - No Warning
+
+@protocol NewProtocol
+  @property (readonly) id myNewString; // expected-warning {{property 'myNewString' requires method 'myNewString' to be defined}}
+@end
+
+@interface SubClass5 : SubClass4 <NewProtocol> @end
+@implementation SubClass5 @end   // expected-note {{implementation is here}}
+