From: Ted Kremenek Date: Fri, 21 Feb 2014 19:41:39 +0000 (+0000) Subject: [ObjC] add support for properties in attribute 'objc_protocol_requires_explicit_imple... X-Git-Url: https://granicus.if.org/sourcecode?a=commitdiff_plain;h=92856c23b572843ece0d6c23f68c0acfefad5de6;p=clang [ObjC] add support for properties in attribute 'objc_protocol_requires_explicit_implementation'. git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@201880 91177308-0d34-0410-b5e6-96231b3b80d8 --- diff --git a/lib/Sema/SemaObjCProperty.cpp b/lib/Sema/SemaObjCProperty.cpp index 67be198f8d..9b3643a2ed 100644 --- a/lib/Sema/SemaObjCProperty.cpp +++ b/lib/Sema/SemaObjCProperty.cpp @@ -1653,12 +1653,13 @@ void Sema::DiagnoseUnimplementedProperties(Scope *S, ObjCImplDecl* IMPDecl, ObjCContainerDecl *CDecl, bool SynthesizeProperties) { ObjCContainerDecl::PropertyMap PropMap; + ObjCInterfaceDecl *IDecl = dyn_cast(CDecl); + if (!SynthesizeProperties) { ObjCContainerDecl::PropertyMap NoNeedToImplPropMap; - ObjCInterfaceDecl *IDecl; // Gather properties which need not be implemented in this class // or category. - if (!(IDecl = dyn_cast(CDecl))) + if (!IDecl) if (ObjCCategoryDecl *C = dyn_cast(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()) + 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; diff --git a/test/SemaObjC/protocols-suppress-conformance.m b/test/SemaObjC/protocols-suppress-conformance.m index 53b5e3d763..05c0486181 100644 --- a/test/SemaObjC/protocols-suppress-conformance.m +++ b/test/SemaObjC/protocols-suppress-conformance.m @@ -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 @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 +@end + +@implementation ClassB_Good // no-warning +- (void) theBestOfTimes {} +@dynamic theWorstOfTimes; @end // Test that inherited protocols do not get the explicit conformance requirement.