Do not issue warning on unimplemented property in the class, if it
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). llvm-svn: 102919
This commit is contained in:
parent
f93cb3bacb
commit
58f11d6245
|
@ -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.
|
||||
|
|
|
@ -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,
|
||||
|
|
|
@ -85,14 +85,14 @@
|
|||
|
||||
@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
|
||||
|
|
|
@ -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}}
|
||||
|
Loading…
Reference in New Issue