diff options
author | Fariborz Jahanian <fjahanian@apple.com> | 2010-06-29 18:12:32 +0000 |
---|---|---|
committer | Fariborz Jahanian <fjahanian@apple.com> | 2010-06-29 18:12:32 +0000 |
commit | cfa6a27f3cc5add888c6ac84dbcc45854cfd8666 (patch) | |
tree | 675685a35a845982a7c28481db06225457a042dd /lib | |
parent | 376fe5e7800dface235c5382b39d77790d39dfa7 (diff) |
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
Diffstat (limited to 'lib')
-rw-r--r-- | lib/Sema/Sema.h | 11 | ||||
-rw-r--r-- | lib/Sema/SemaObjCProperty.cpp | 56 |
2 files changed, 20 insertions, 47 deletions
diff --git a/lib/Sema/Sema.h b/lib/Sema/Sema.h index 325add7671..f93a9492b2 100644 --- a/lib/Sema/Sema.h +++ b/lib/Sema/Sema.h @@ -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. diff --git a/lib/Sema/SemaObjCProperty.cpp b/lib/Sema/SemaObjCProperty.cpp index a27d2a8a2f..44cd271753 100644 --- a/lib/Sema/SemaObjCProperty.cpp +++ b/lib/Sema/SemaObjCProperty.cpp @@ -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; |