From 38882022af8038f008fdbe0f9e0307f8c711c248 Mon Sep 17 00:00:00 2001 From: Ted Kremenek Date: Fri, 21 Feb 2014 19:41:39 +0000 Subject: [PATCH] [ObjC] add support for properties in attribute 'objc_protocol_requires_explicit_implementation'. llvm-svn: 201880 --- clang/lib/Sema/SemaObjCProperty.cpp | 26 +++++++++++++++++-- .../SemaObjC/protocols-suppress-conformance.m | 12 +++++++-- 2 files changed, 34 insertions(+), 4 deletions(-) diff --git a/clang/lib/Sema/SemaObjCProperty.cpp b/clang/lib/Sema/SemaObjCProperty.cpp index 67be198f8de4..9b3643a2ed7b 100644 --- a/clang/lib/Sema/SemaObjCProperty.cpp +++ b/clang/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/clang/test/SemaObjC/protocols-suppress-conformance.m b/clang/test/SemaObjC/protocols-suppress-conformance.m index 53b5e3d76301..05c0486181f3 100644 --- a/clang/test/SemaObjC/protocols-suppress-conformance.m +++ b/clang/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.