[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
Fariborz Jahanian
fjahanian at apple.com
Sat Dec 6 15:03:39 PST 2008
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
+
+
+
More information about the cfe-commits
mailing list