diff options
Diffstat (limited to 'lib/Sema/SemaObjCProperty.cpp')
-rw-r--r-- | lib/Sema/SemaObjCProperty.cpp | 79 |
1 files changed, 33 insertions, 46 deletions
diff --git a/lib/Sema/SemaObjCProperty.cpp b/lib/Sema/SemaObjCProperty.cpp index 4c89a11..44cd271 100644 --- a/lib/Sema/SemaObjCProperty.cpp +++ b/lib/Sema/SemaObjCProperty.cpp @@ -41,7 +41,8 @@ Sema::DeclPtrTy Sema::ActOnProperty(Scope *S, SourceLocation AtLoc, !(Attributes & ObjCDeclSpec::DQ_PR_retain) && !(Attributes & ObjCDeclSpec::DQ_PR_copy))); - QualType T = GetTypeForDeclarator(FD.D, S); + TypeSourceInfo *TSI = GetTypeForDeclarator(FD.D, S); + QualType T = TSI->getType(); if (T->isReferenceType()) { Diag(AtLoc, diag::error_reference_property); return DeclPtrTy(); @@ -56,13 +57,13 @@ Sema::DeclPtrTy Sema::ActOnProperty(Scope *S, SourceLocation AtLoc, FD, GetterSel, SetterSel, isAssign, isReadWrite, Attributes, - isOverridingProperty, T, + isOverridingProperty, TSI, MethodImplKind); DeclPtrTy Res = DeclPtrTy::make(CreatePropertyDecl(S, ClassDecl, AtLoc, FD, GetterSel, SetterSel, isAssign, isReadWrite, - Attributes, T, MethodImplKind)); + Attributes, TSI, MethodImplKind)); // Validate the attributes on the @property. CheckObjCPropertyAttributes(Res, AtLoc, Attributes); return Res; @@ -76,7 +77,7 @@ Sema::HandlePropertyInClassExtension(Scope *S, ObjCCategoryDecl *CDecl, const bool isReadWrite, const unsigned Attributes, bool *isOverridingProperty, - QualType T, + TypeSourceInfo *T, tok::ObjCKeywordKind MethodImplKind) { // Diagnose if this property is already in continuation class. @@ -122,6 +123,10 @@ Sema::HandlePropertyInClassExtension(Scope *S, ObjCCategoryDecl *CDecl, CreatePropertyDecl(S, CCPrimary, AtLoc, FD, GetterSel, SetterSel, isAssign, isReadWrite, Attributes, T, MethodImplKind, DC); + // Mark written attribute as having no attribute because + // this is not a user-written property declaration in primary + // class. + PDecl->setPropertyAttributesAsWritten(ObjCPropertyDecl::OBJC_PR_noattr); // A case of continuation class adding a new property in the class. This // is not what it was meant for. However, gcc supports it and so should we. @@ -133,7 +138,7 @@ Sema::HandlePropertyInClassExtension(Scope *S, ObjCCategoryDecl *CDecl, // The property 'PIDecl's readonly attribute will be over-ridden // with continuation class's readwrite property attribute! - unsigned PIkind = PIDecl->getPropertyAttributes(); + unsigned PIkind = PIDecl->getPropertyAttributesAsWritten(); if (isReadWrite && (PIkind & ObjCPropertyDecl::OBJC_PR_readonly)) { unsigned retainCopyNonatomic = (ObjCPropertyDecl::OBJC_PR_retain | @@ -190,11 +195,11 @@ ObjCPropertyDecl *Sema::CreatePropertyDecl(Scope *S, const bool isAssign, const bool isReadWrite, const unsigned Attributes, - QualType T, + TypeSourceInfo *TInfo, tok::ObjCKeywordKind MethodImplKind, DeclContext *lexicalDC){ - IdentifierInfo *PropertyId = FD.D.getIdentifier(); + QualType T = TInfo->getType(); // Issue a warning if property is 'assign' as default and its object, which is // gc'able conforms to NSCopying protocol @@ -215,7 +220,7 @@ ObjCPropertyDecl *Sema::CreatePropertyDecl(Scope *S, DeclContext *DC = cast<DeclContext>(CDecl); ObjCPropertyDecl *PDecl = ObjCPropertyDecl::Create(Context, DC, FD.D.getIdentifierLoc(), - PropertyId, AtLoc, T); + PropertyId, AtLoc, TInfo); if (ObjCPropertyDecl *prevDecl = ObjCPropertyDecl::findPropertyDecl(DC, PropertyId)) { @@ -265,6 +270,8 @@ ObjCPropertyDecl *Sema::CreatePropertyDecl(Scope *S, if (Attributes & ObjCDeclSpec::DQ_PR_nonatomic) PDecl->setPropertyAttributes(ObjCPropertyDecl::OBJC_PR_nonatomic); + PDecl->setPropertyAttributesAsWritten(PDecl->getPropertyAttributes()); + if (MethodImplKind == tok::objc_required) PDecl->setPropertyImplementation(ObjCPropertyDecl::Required); else if (MethodImplKind == tok::objc_optional) @@ -771,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) { @@ -781,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()) @@ -796,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); } } @@ -854,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, @@ -952,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; |