зеркало из https://github.com/microsoft/clang-1.git
This patch fixes a bug whereby, clang skipped
unimplemented property warning for properties coming from class's conformin protocol. It also simplifies the algorithm in the process. Fixes radar 8035776. git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@107174 91177308-0d34-0410-b5e6-96231b3b80d8
This commit is contained in:
Родитель
376fe5e780
Коммит
cfa6a27f3c
|
@ -1573,16 +1573,9 @@ public:
|
|||
/// CollectImmediateProperties - This routine collects all properties in
|
||||
/// the class and its conforming protocols; but not those it its super class.
|
||||
void CollectImmediateProperties(ObjCContainerDecl *CDecl,
|
||||
llvm::DenseMap<IdentifierInfo *, ObjCPropertyDecl*>& PropMap);
|
||||
llvm::DenseMap<IdentifierInfo *, ObjCPropertyDecl*>& PropMap,
|
||||
llvm::DenseMap<IdentifierInfo *, ObjCPropertyDecl*>& SuperPropMap);
|
||||
|
||||
/// 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.
|
||||
|
|
|
@ -778,7 +778,8 @@ bool Sema::isPropertyReadonly(ObjCPropertyDecl *PDecl,
|
|||
/// CollectImmediateProperties - This routine collects all properties in
|
||||
/// the class and its conforming protocols; but not those it its super class.
|
||||
void Sema::CollectImmediateProperties(ObjCContainerDecl *CDecl,
|
||||
llvm::DenseMap<IdentifierInfo *, ObjCPropertyDecl*>& PropMap) {
|
||||
llvm::DenseMap<IdentifierInfo *, ObjCPropertyDecl*>& PropMap,
|
||||
llvm::DenseMap<IdentifierInfo *, ObjCPropertyDecl*>& SuperPropMap) {
|
||||
if (ObjCInterfaceDecl *IDecl = dyn_cast<ObjCInterfaceDecl>(CDecl)) {
|
||||
for (ObjCContainerDecl::prop_iterator P = IDecl->prop_begin(),
|
||||
E = IDecl->prop_end(); P != E; ++P) {
|
||||
|
@ -788,10 +789,7 @@ 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)
|
||||
// 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);
|
||||
CollectImmediateProperties((*PI), PropMap, SuperPropMap);
|
||||
}
|
||||
if (ObjCCategoryDecl *CATDecl = dyn_cast<ObjCCategoryDecl>(CDecl)) {
|
||||
if (!CATDecl->IsClassExtension())
|
||||
|
@ -803,20 +801,25 @@ void Sema::CollectImmediateProperties(ObjCContainerDecl *CDecl,
|
|||
// scan through class's protocols.
|
||||
for (ObjCInterfaceDecl::protocol_iterator PI = CATDecl->protocol_begin(),
|
||||
E = CATDecl->protocol_end(); PI != E; ++PI)
|
||||
CollectImmediateProperties((*PI), PropMap);
|
||||
CollectImmediateProperties((*PI), PropMap, SuperPropMap);
|
||||
}
|
||||
else if (ObjCProtocolDecl *PDecl = dyn_cast<ObjCProtocolDecl>(CDecl)) {
|
||||
for (ObjCProtocolDecl::prop_iterator P = PDecl->prop_begin(),
|
||||
E = PDecl->prop_end(); P != E; ++P) {
|
||||
ObjCPropertyDecl *Prop = (*P);
|
||||
ObjCPropertyDecl *&PropEntry = PropMap[Prop->getIdentifier()];
|
||||
if (!PropEntry)
|
||||
PropEntry = Prop;
|
||||
ObjCPropertyDecl *PropertyFromSuper = SuperPropMap[Prop->getIdentifier()];
|
||||
// Exclude property for protocols which conform to class's super-class,
|
||||
// as super-class has to implement the property.
|
||||
if (!PropertyFromSuper || PropertyFromSuper != Prop) {
|
||||
ObjCPropertyDecl *&PropEntry = PropMap[Prop->getIdentifier()];
|
||||
if (!PropEntry)
|
||||
PropEntry = Prop;
|
||||
}
|
||||
}
|
||||
// scan through protocol's protocols.
|
||||
for (ObjCProtocolDecl::protocol_iterator PI = PDecl->protocol_begin(),
|
||||
E = PDecl->protocol_end(); PI != E; ++PI)
|
||||
CollectImmediateProperties((*PI), PropMap);
|
||||
CollectImmediateProperties((*PI), PropMap, SuperPropMap);
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -861,33 +864,6 @@ static void CollectSuperClassPropertyImplementations(ObjCInterfaceDecl *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,
|
||||
|
@ -959,8 +935,12 @@ void Sema::DefaultSynthesizeProperties (Scope *S, ObjCImplDecl* IMPDecl,
|
|||
void Sema::DiagnoseUnimplementedProperties(Scope *S, ObjCImplDecl* IMPDecl,
|
||||
ObjCContainerDecl *CDecl,
|
||||
const llvm::DenseSet<Selector>& InsMap) {
|
||||
llvm::DenseMap<IdentifierInfo *, ObjCPropertyDecl*> SuperPropMap;
|
||||
if (ObjCInterfaceDecl *IDecl = dyn_cast<ObjCInterfaceDecl>(CDecl))
|
||||
CollectSuperClassPropertyImplementations(IDecl, SuperPropMap);
|
||||
|
||||
llvm::DenseMap<IdentifierInfo *, ObjCPropertyDecl*> PropMap;
|
||||
CollectImmediateProperties(CDecl, PropMap);
|
||||
CollectImmediateProperties(CDecl, PropMap, SuperPropMap);
|
||||
if (PropMap.empty())
|
||||
return;
|
||||
|
||||
|
|
|
@ -45,3 +45,19 @@
|
|||
@interface SubClass5 : SubClass4 <NewProtocol> @end
|
||||
@implementation SubClass5 @end // expected-note {{implementation is here}}
|
||||
|
||||
|
||||
// Radar 8035776
|
||||
@protocol SuperProtocol
|
||||
@end
|
||||
|
||||
@interface Super <SuperProtocol>
|
||||
@end
|
||||
|
||||
@protocol ProtocolWithProperty <SuperProtocol>
|
||||
@property (readonly, assign) id invalidationBacktrace; // expected-warning {{property 'invalidationBacktrace' requires method 'invalidationBacktrace' to be defined}}
|
||||
@end
|
||||
|
||||
@interface INTF : Super <ProtocolWithProperty>
|
||||
@end
|
||||
|
||||
@implementation INTF @end // expected-note {{implementation is here}}
|
||||
|
|
Загрузка…
Ссылка в новой задаче