]> granicus.if.org Git - clang/commitdiff
[ObjC] add support for properties in attribute 'objc_protocol_requires_explicit_imple...
authorTed Kremenek <kremenek@apple.com>
Fri, 21 Feb 2014 19:41:39 +0000 (19:41 +0000)
committerTed Kremenek <kremenek@apple.com>
Fri, 21 Feb 2014 19:41:39 +0000 (19:41 +0000)
git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@201880 91177308-0d34-0410-b5e6-96231b3b80d8

lib/Sema/SemaObjCProperty.cpp
test/SemaObjC/protocols-suppress-conformance.m

index 67be198f8de478595d028f05cefeba0330994273..9b3643a2ed7bdbf8af536334e2e4af4bb8e8f39c 100644 (file)
@@ -1653,12 +1653,13 @@ void Sema::DiagnoseUnimplementedProperties(Scope *S, ObjCImplDecl* IMPDecl,
                                            ObjCContainerDecl *CDecl,
                                            bool SynthesizeProperties) {
   ObjCContainerDecl::PropertyMap PropMap;
+  ObjCInterfaceDecl *IDecl = dyn_cast<ObjCInterfaceDecl>(CDecl);
+
   if (!SynthesizeProperties) {
     ObjCContainerDecl::PropertyMap NoNeedToImplPropMap;
-    ObjCInterfaceDecl *IDecl;
     // Gather properties which need not be implemented in this class
     // or category.
-    if (!(IDecl = dyn_cast<ObjCInterfaceDecl>(CDecl)))
+    if (!IDecl)
       if (ObjCCategoryDecl *C = dyn_cast<ObjCCategoryDecl>(CDecl)) {
         // For categories, no need to implement properties declared in
         // its primary class (and its super classes) if property is
@@ -1674,6 +1675,27 @@ void Sema::DiagnoseUnimplementedProperties(Scope *S, ObjCImplDecl* IMPDecl,
     CollectImmediateProperties(CDecl, PropMap, NoNeedToImplPropMap);
   }
 
+  // Scan the @interface to see if any of the protocols it adopts
+  // require an explicit implementation, via attribute
+  // 'objc_protocol_requires_explicit_implementation'.
+  if (IDecl)
+    for (ObjCInterfaceDecl::all_protocol_iterator
+          PI = IDecl->all_referenced_protocol_begin(),
+          PE = IDecl->all_referenced_protocol_end();
+          PI != PE; ++PI) {
+      ObjCProtocolDecl *PDecl = *PI;
+      if (!PDecl->hasAttr<ObjCExplicitProtocolImplAttr>())
+        continue;
+      // Add the properties of 'PDecl' to the list of properties that
+      // need to be implemented.
+      for (ObjCProtocolDecl::prop_iterator
+           PRI = PDecl->prop_begin(), PRE = PDecl->prop_end();
+           PRI != PRE; ++PRI) {
+        ObjCPropertyDecl *PropDecl = *PRI;
+        PropMap[PRI->getIdentifier()] = PropDecl;
+      }
+    }
+
   if (PropMap.empty())
     return;
 
index 53b5e3d76301eb622094738151c8c99902259d58..05c0486181f3f9f48b7c1877ae65c9883b29c9ed 100644 (file)
@@ -5,7 +5,7 @@
 __attribute__((objc_protocol_requires_explicit_implementation))
 @protocol Protocol
 - (void) theBestOfTimes; // expected-note {{method 'theBestOfTimes' declared here}}
-@property (readonly) id theWorstOfTimes;
+@property (readonly) id theWorstOfTimes; // expected-note {{property declared here}}
 @end
 
 // In this example, ClassA adopts the protocol.  We won't
@@ -21,7 +21,15 @@ __attribute__((objc_protocol_requires_explicit_implementation))
 @interface ClassB : ClassA <Protocol>
 @end
 
-@implementation ClassB // expected-warning {{method 'theBestOfTimes' in protocol 'Protocol' not implemented}}
+@implementation ClassB // expected-warning {{method 'theBestOfTimes' in protocol 'Protocol' not implemented}} expected-warning {{property 'theWorstOfTimes' requires method 'theWorstOfTimes' to be defined - use @synthesize, @dynamic or provide a method implementation in this class implementation}}
+@end
+
+@interface ClassB_Good : ClassA <Protocol>
+@end
+
+@implementation ClassB_Good // no-warning
+- (void) theBestOfTimes {}
+@dynamic theWorstOfTimes;
 @end
 
 // Test that inherited protocols do not get the explicit conformance requirement.