diff options
Diffstat (limited to 'clang/lib')
-rw-r--r-- | clang/lib/Sema/Sema.h | 5 | ||||
-rw-r--r-- | clang/lib/Sema/SemaDeclObjC.cpp | 4 | ||||
-rw-r--r-- | clang/lib/Sema/SemaObjCProperty.cpp | 77 |
3 files changed, 77 insertions, 9 deletions
diff --git a/clang/lib/Sema/Sema.h b/clang/lib/Sema/Sema.h index 4ef5ebe20a7..d97dc676823 100644 --- a/clang/lib/Sema/Sema.h +++ b/clang/lib/Sema/Sema.h @@ -1542,6 +1542,11 @@ public: ObjCContainerDecl *CDecl, const llvm::DenseSet<Selector>& InsMap); + /// DefaultSynthesizeProperties - This routine default synthesizes all + /// properties which must be synthesized in class's @implementation. + void DefaultSynthesizeProperties (Scope *S, ObjCImplDecl* IMPDecl, + ObjCInterfaceDecl *IDecl); + /// CollectImmediateProperties - This routine collects all properties in /// the class and its conforming protocols; but not those it its super class. void CollectImmediateProperties(ObjCContainerDecl *CDecl, diff --git a/clang/lib/Sema/SemaDeclObjC.cpp b/clang/lib/Sema/SemaDeclObjC.cpp index b7d737984c7..9ed96921141 100644 --- a/clang/lib/Sema/SemaDeclObjC.cpp +++ b/clang/lib/Sema/SemaDeclObjC.cpp @@ -938,7 +938,7 @@ void Sema::ImplMethodsVsClassMethods(Scope *S, ObjCImplDecl* IMPDecl, // Check and see if properties declared in the interface have either 1) // an implementation or 2) there is a @synthesize/@dynamic implementation // of the property in the @implementation. - if (isa<ObjCInterfaceDecl>(CDecl)) + if (isa<ObjCInterfaceDecl>(CDecl) && !LangOpts.ObjCNonFragileABI2) DiagnoseUnimplementedProperties(S, IMPDecl, CDecl, InsMap); llvm::DenseSet<Selector> ClsMap; @@ -1433,6 +1433,8 @@ void Sema::ActOnAtEnd(Scope *S, SourceRange AtEnd, if (ObjCImplementationDecl *IC=dyn_cast<ObjCImplementationDecl>(ClassDecl)) { IC->setAtEndRange(AtEnd); if (ObjCInterfaceDecl* IDecl = IC->getClassInterface()) { + if (LangOpts.ObjCNonFragileABI2) + DefaultSynthesizeProperties(S, IC, IDecl); ImplMethodsVsClassMethods(S, IC, IDecl); AtomicPropertySetterGetterRules(IC, IDecl); if (LangOpts.ObjCNonFragileABI2) diff --git a/clang/lib/Sema/SemaObjCProperty.cpp b/clang/lib/Sema/SemaObjCProperty.cpp index f64ee970a95..a2aef20f658 100644 --- a/clang/lib/Sema/SemaObjCProperty.cpp +++ b/clang/lib/Sema/SemaObjCProperty.cpp @@ -802,6 +802,47 @@ void Sema::CollectImmediateProperties(ObjCContainerDecl *CDecl, } } +/// CollectClassPropertyImplementations - This routine collects list of +/// properties to be implemented in the class. This includes, class's +/// and its conforming protocols' properties. +static void CollectClassPropertyImplementations(ObjCContainerDecl *CDecl, + llvm::DenseMap<IdentifierInfo *, ObjCPropertyDecl*>& PropMap) { + if (ObjCInterfaceDecl *IDecl = dyn_cast<ObjCInterfaceDecl>(CDecl)) { + for (ObjCContainerDecl::prop_iterator P = IDecl->prop_begin(), + E = IDecl->prop_end(); P != E; ++P) { + ObjCPropertyDecl *Prop = (*P); + PropMap[Prop->getIdentifier()] = Prop; + } + for (ObjCInterfaceDecl::protocol_iterator PI = IDecl->protocol_begin(), + E = IDecl->protocol_end(); PI != E; ++PI) + CollectClassPropertyImplementations((*PI), PropMap); + } + 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); + PropMap[Prop->getIdentifier()] = Prop; + } + // scan through protocol's protocols. + for (ObjCProtocolDecl::protocol_iterator PI = PDecl->protocol_begin(), + E = PDecl->protocol_end(); PI != E; ++PI) + CollectClassPropertyImplementations((*PI), PropMap); + } +} + +/// CollectSuperClassPropertyImplementations - This routine collects list of +/// properties to be implemented in super class(s) and also coming from their +/// conforming protocols. +static void CollectSuperClassPropertyImplementations(ObjCInterfaceDecl *CDecl, + llvm::DenseMap<IdentifierInfo *, ObjCPropertyDecl*>& PropMap) { + if (ObjCInterfaceDecl *SDecl = CDecl->getSuperClass()) { + while (SDecl) { + CollectClassPropertyImplementations(SDecl, PropMap); + SDecl = SDecl->getSuperClass(); + } + } +} + /// ProtocolConformsToSuperClass - Returns true if class's given protocol /// conforms to one of its super class's protocols. bool Sema::ProtocolConformsToSuperClass(const ObjCInterfaceDecl *IDecl, @@ -868,6 +909,34 @@ ObjCPropertyDecl *Sema::LookupPropertyDecl(const ObjCContainerDecl *CDecl, return 0; } +/// DefaultSynthesizeProperties - This routine default synthesizes all +/// properties which must be synthesized in class's @implementation. +void Sema::DefaultSynthesizeProperties (Scope *S, ObjCImplDecl* IMPDecl, + ObjCInterfaceDecl *IDecl) { + + llvm::DenseMap<IdentifierInfo *, ObjCPropertyDecl*> PropMap; + CollectClassPropertyImplementations(IDecl, PropMap); + if (PropMap.empty()) + return; + llvm::DenseMap<IdentifierInfo *, ObjCPropertyDecl*> SuperPropMap; + CollectSuperClassPropertyImplementations(IDecl, SuperPropMap); + + for (llvm::DenseMap<IdentifierInfo *, ObjCPropertyDecl*>::iterator + P = PropMap.begin(), E = PropMap.end(); P != E; ++P) { + ObjCPropertyDecl *Prop = P->second; + // If property to be implemented in the super class, ignore. + if (SuperPropMap[Prop->getIdentifier()]) + continue; + // Is there a matching propery synthesize/dynamic? + if (Prop->isInvalidDecl() || + Prop->getPropertyImplementation() == ObjCPropertyDecl::Optional || + IMPDecl->FindPropertyImplIvarDecl(Prop->getIdentifier())) + continue; + ActOnPropertyImplDecl(S, IMPDecl->getLocation(), IMPDecl->getLocation(), + true, DeclPtrTy::make(IMPDecl), + Prop->getIdentifier(), Prop->getIdentifier()); + } +} void Sema::DiagnoseUnimplementedProperties(Scope *S, ObjCImplDecl* IMPDecl, ObjCContainerDecl *CDecl, @@ -891,14 +960,6 @@ void Sema::DiagnoseUnimplementedProperties(Scope *S, ObjCImplDecl* IMPDecl, Prop->getPropertyImplementation() == ObjCPropertyDecl::Optional || PropImplMap.count(Prop)) continue; - if (LangOpts.ObjCNonFragileABI2 && !isa<ObjCCategoryImplDecl>(IMPDecl)) { - ActOnPropertyImplDecl(S, IMPDecl->getLocation(), - IMPDecl->getLocation(), - true, DeclPtrTy::make(IMPDecl), - Prop->getIdentifier(), - Prop->getIdentifier()); - continue; - } if (!InsMap.count(Prop->getGetterName())) { Diag(Prop->getLocation(), isa<ObjCCategoryDecl>(CDecl) ? |