[cfe-commits] r60634 - in /cfe/trunk: include/clang/AST/DeclObjC.h lib/AST/DeclObjC.cpp lib/Sema/Sema.h lib/Sema/SemaDeclObjC.cpp test/SemaObjC/property-category-3.m
steve naroff
snaroff at apple.com
Thu Jan 8 13:01:28 PST 2009
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 @@
> + at protocol P
> + @property(readonly) int X;
> + at end
> +
> + at protocol P1<P>
> + @property (copy) id ID;
> + at end
> +
> + at interface I
> + at end
> +
> + at interface I (Cat) <P>
> + at property float X; // expected-warning {{property type 'float' does
> not match property type inherited from 'P'}}
> + at end
> +
> + at interface I (Cat2) <P1>
> + at property (retain) id ID; // expected-warning {{property 'ID'
> 'copy' attribute does not match the property inherited from 'P1'}}
> + at end
> +
> +
> +
>
>
> _______________________________________________
> cfe-commits mailing list
> cfe-commits at cs.uiuc.edu
> http://lists.cs.uiuc.edu/mailman/listinfo/cfe-commits
More information about the cfe-commits
mailing list