Fariborz, Now that we have ObjCContainerDecl, I'd really like to move the property related API's "up" to it (from ObjCInterface/Category/ Protocol).
One of the recently added methods (mergeProperties) is implemented on ObjCInterface/Category (but on ObjCProtocolDecl). More importantly, the "realloc()" won't fly with ObjCContainerDecl/ DeclContext. Wouldn't it have been easier to change (or add) a lookup routine that does a "deep" lookup? I'm confused why we you needed to "flatten" the property list to fix this particular bug. Please advise...I think it's important to clean this up. Since it was recently added, I can't imagine it is too difficult to fix. Thanks, snaroff On Dec 6, 2008, at 6:03 PM, Fariborz Jahanian wrote: > Author: fjahanian > Date: Sat Dec 6 17:03:39 2008 > New Revision: 60634 > > URL: http://llvm.org/viewvc/llvm-project?rev=60634&view=rev > Log: > Use of properties declared in protocols in the category > via the category's protocol list1s, with appropriate > diagnsostics and a test case. > > Added: > cfe/trunk/test/SemaObjC/property-category-3.m > Modified: > cfe/trunk/include/clang/AST/DeclObjC.h > cfe/trunk/lib/AST/DeclObjC.cpp > cfe/trunk/lib/Sema/Sema.h > cfe/trunk/lib/Sema/SemaDeclObjC.cpp > > Modified: cfe/trunk/include/clang/AST/DeclObjC.h > URL: > http://llvm.org/viewvc/llvm-project/cfe/trunk/include/clang/AST/DeclObjC.h?rev=60634&r1=60633&r2=60634&view=diff > > = > = > = > = > = > = > = > = > ====================================================================== > --- cfe/trunk/include/clang/AST/DeclObjC.h (original) > +++ cfe/trunk/include/clang/AST/DeclObjC.h Sat Dec 6 17:03:39 2008 > @@ -883,6 +883,8 @@ > > void addProperties(ObjCPropertyDecl **Properties, unsigned > NumProperties); > > + void mergeProperties(ObjCPropertyDecl **Properties, unsigned > NumProperties); > + > void addPropertyMethods(ASTContext &Context, > ObjCPropertyDecl* Property, > llvm::SmallVector<ObjCMethodDecl*, 32> > &insMethods, > > Modified: cfe/trunk/lib/AST/DeclObjC.cpp > URL: > http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/AST/DeclObjC.cpp?rev=60634&r1=60633&r2=60634&view=diff > > = > = > = > = > = > = > = > = > ====================================================================== > --- cfe/trunk/lib/AST/DeclObjC.cpp (original) > +++ cfe/trunk/lib/AST/DeclObjC.cpp Sat Dec 6 17:03:39 2008 > @@ -513,6 +513,31 @@ > ::addPropertyMethods(this, Context, property, insMethods, InsMap); > } > > +/// mergeProperties - Adds properties to the end of list of current > properties > +/// for this category. > + > +void ObjCCategoryDecl::mergeProperties(ObjCPropertyDecl **Properties, > + unsigned NumNewProperties) { > + if (NumNewProperties == 0) return; > + > + if (PropertyDecl) { > + ObjCPropertyDecl **newPropertyDecl = > + new ObjCPropertyDecl*[NumNewProperties + NumPropertyDecl]; > + ObjCPropertyDecl **buf = newPropertyDecl; > + // put back original properties in buffer. > + memcpy(buf, PropertyDecl, > NumPropertyDecl*sizeof(ObjCPropertyDecl*)); > + // Add new properties to this buffer. > + memcpy(buf+NumPropertyDecl, Properties, > + NumNewProperties*sizeof(ObjCPropertyDecl*)); > + delete[] PropertyDecl; > + PropertyDecl = newPropertyDecl; > + NumPropertyDecl += NumNewProperties; > + } > + else { > + addProperties(Properties, NumNewProperties); > + } > +} > + > /// addPropertyMethods - Goes through list of properties declared in > this class > /// and builds setter/getter method declartions depending on the > setter/getter > /// attributes of the property. > > Modified: cfe/trunk/lib/Sema/Sema.h > URL: > http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/Sema/Sema.h?rev=60634&r1=60633&r2=60634&view=diff > > = > = > = > = > = > = > = > = > ====================================================================== > --- cfe/trunk/lib/Sema/Sema.h (original) > +++ cfe/trunk/lib/Sema/Sema.h Sat Dec 6 17:03:39 2008 > @@ -1075,10 +1075,10 @@ > const IdentifierInfo *Name); > void ComparePropertiesInBaseAndSuper(ObjCInterfaceDecl *IDecl); > > - void MergeProtocolPropertiesIntoClass(ObjCInterfaceDecl *IDecl, > + void MergeProtocolPropertiesIntoClass(Decl *CDecl, > DeclTy *MergeProtocols); > > - void MergeOneProtocolPropertiesIntoClass(ObjCInterfaceDecl *IDecl, > + void MergeOneProtocolPropertiesIntoClass(Decl *CDecl, > ObjCProtocolDecl *PDecl); > > virtual void ActOnAtEnd(SourceLocation AtEndLoc, DeclTy *classDecl, > > Modified: cfe/trunk/lib/Sema/SemaDeclObjC.cpp > URL: > http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/Sema/SemaDeclObjC.cpp?rev=60634&r1=60633&r2=60634&view=diff > > = > = > = > = > = > = > = > = > ====================================================================== > --- cfe/trunk/lib/Sema/SemaDeclObjC.cpp (original) > +++ cfe/trunk/lib/Sema/SemaDeclObjC.cpp Sat Dec 6 17:03:39 2008 > @@ -311,11 +311,35 @@ > > /// MergeOneProtocolPropertiesIntoClass - This routine goes thru the > list > /// of properties declared in a protocol and adds them to the list > -/// of properties for current class if it is not there already. > +/// of properties for current class/category if it is not there > already. > void > -Sema::MergeOneProtocolPropertiesIntoClass(ObjCInterfaceDecl *IDecl, > +Sema::MergeOneProtocolPropertiesIntoClass(Decl *CDecl, > ObjCProtocolDecl *PDecl) { > llvm::SmallVector<ObjCPropertyDecl*, 16> mergeProperties; > + ObjCInterfaceDecl *IDecl = > dyn_cast_or_null<ObjCInterfaceDecl>(CDecl); > + if (!IDecl) { > + // Category > + ObjCCategoryDecl *CatDecl = > static_cast<ObjCCategoryDecl*>(CDecl); > + assert (CatDecl && "MergeOneProtocolPropertiesIntoClass"); > + for (ObjCProtocolDecl::classprop_iterator P = PDecl- > >classprop_begin(), > + E = PDecl->classprop_end(); P != E; ++P) { > + ObjCPropertyDecl *Pr = (*P); > + ObjCCategoryDecl::classprop_iterator CP, CE; > + // Is this property already in category's list of properties? > + for (CP = CatDecl->classprop_begin(), CE = CatDecl- > >classprop_end(); > + CP != CE; ++CP) > + if ((*CP)->getIdentifier() == Pr->getIdentifier()) > + break; > + if (CP == CE) > + // Add this property to list of properties for thie class. > + mergeProperties.push_back(Pr); > + else > + // Property protocol already exist in class. Diagnose any > mismatch. > + DiagnosePropertyMismatch((*CP), Pr, PDecl->getIdentifier()); > + } > + CatDecl->mergeProperties(&mergeProperties[0], > mergeProperties.size()); > + return; > + } > for (ObjCProtocolDecl::classprop_iterator P = PDecl- > >classprop_begin(), > E = PDecl->classprop_end(); P != E; ++P) { > ObjCPropertyDecl *Pr = (*P); > @@ -337,13 +361,39 @@ > > /// MergeProtocolPropertiesIntoClass - This routine merges properties > /// declared in 'MergeItsProtocols' objects (which can be a class or > an > -/// inherited protocol into the list of properties for class 'IDecl' > +/// inherited protocol into the list of properties for class/ > category 'CDecl' > /// > > void > -Sema::MergeProtocolPropertiesIntoClass(ObjCInterfaceDecl *IDecl, > +Sema::MergeProtocolPropertiesIntoClass(Decl *CDecl, > DeclTy *MergeItsProtocols) { > Decl *ClassDecl = static_cast<Decl *>(MergeItsProtocols); > + ObjCInterfaceDecl *IDecl = > dyn_cast_or_null<ObjCInterfaceDecl>(CDecl); > + > + if (!IDecl) { > + // Category > + ObjCCategoryDecl *CatDecl = > static_cast<ObjCCategoryDecl*>(CDecl); > + assert (CatDecl && "MergeProtocolPropertiesIntoClass"); > + if (ObjCCategoryDecl *MDecl = > dyn_cast<ObjCCategoryDecl>(ClassDecl)) { > + for (ObjCCategoryDecl::protocol_iterator P = MDecl- > >protocol_begin(), > + E = MDecl->protocol_end(); P != E; ++P) > + // Merge properties of category (*P) into IDECL's > + MergeOneProtocolPropertiesIntoClass(CatDecl, *P); > + > + // Go thru the list of protocols for this category and > recursively merge > + // their properties into this class as well. > + for (ObjCCategoryDecl::protocol_iterator P = CatDecl- > >protocol_begin(), > + E = CatDecl->protocol_end(); P != E; ++P) > + MergeProtocolPropertiesIntoClass(CatDecl, *P); > + } else { > + ObjCProtocolDecl *MD = cast<ObjCProtocolDecl>(ClassDecl); > + for (ObjCProtocolDecl::protocol_iterator P = MD- > >protocol_begin(), > + E = MD->protocol_end(); P != E; ++P) > + MergeOneProtocolPropertiesIntoClass(CatDecl, (*P)); > + } > + return; > + } > + > if (ObjCInterfaceDecl *MDecl = > dyn_cast<ObjCInterfaceDecl>(ClassDecl)) { > for (ObjCInterfaceDecl::protocol_iterator P = MDecl- > >protocol_begin(), > E = MDecl->protocol_end(); P != E; ++P) > @@ -1063,8 +1113,8 @@ > // By the same token, they are also used to add new properties. No > // need to compare the added property to those in the class. > > - // FIXME: If we merge properties into class we should probably > - // merge them into category as well? > + // Merge protocol properties into category > + MergeProtocolPropertiesIntoClass(C, C); > for (ObjCCategoryDecl::classprop_iterator i = C- > >classprop_begin(), > e = C->classprop_end(); i != e; ++i) { > diagnosePropertySetterGetterMismatch((*i), InsMap[(*i)- > >getGetterName()], > > Added: cfe/trunk/test/SemaObjC/property-category-3.m > URL: > http://llvm.org/viewvc/llvm-project/cfe/trunk/test/SemaObjC/property-category-3.m?rev=60634&view=auto > > = > = > = > = > = > = > = > = > ====================================================================== > --- cfe/trunk/test/SemaObjC/property-category-3.m (added) > +++ cfe/trunk/test/SemaObjC/property-category-3.m Sat Dec 6 > 17:03:39 2008 > @@ -0,0 +1,21 @@ > +...@protocol P > + @property(readonly) int X; > +...@end > + > +...@protocol P1<P> > + @property (copy) id ID; > +...@end > + > +...@interface I > +...@end > + > +...@interface I (Cat) <P> > +...@property float X; // expected-warning {{property type 'float' does > not match property type inherited from 'P'}} > +...@end > + > +...@interface I (Cat2) <P1> > +...@property (retain) id ID; // expected-warning {{property 'ID' > 'copy' attribute does not match the property inherited from 'P1'}} > +...@end > + > + > + > > > _______________________________________________ > cfe-commits mailing list > [email protected] > http://lists.cs.uiuc.edu/mailman/listinfo/cfe-commits _______________________________________________ cfe-commits mailing list [email protected] http://lists.cs.uiuc.edu/mailman/listinfo/cfe-commits
