[cfe-commits] r50587 - in /cfe/trunk: include/clang/AST/DeclObjC.h include/clang/Basic/DiagnosticKinds.def lib/AST/DeclObjC.cpp lib/Sema/Sema.h lib/Sema/SemaDeclObjC.cpp test/Sema/objc-property-3.m test/Sema/objc-property-4.m
Fariborz Jahanian
fjahanian at apple.com
Fri May 2 12:17:31 PDT 2008
Author: fjahanian
Date: Fri May 2 14:17:30 2008
New Revision: 50587
URL: http://llvm.org/viewvc/llvm-project?rev=50587&view=rev
Log:
This patch is about merging ObjC2's properties declared in class
protocols into class's property list and performing semantics
on them for while doing so.
Added:
cfe/trunk/test/Sema/objc-property-4.m
Modified:
cfe/trunk/include/clang/AST/DeclObjC.h
cfe/trunk/include/clang/Basic/DiagnosticKinds.def
cfe/trunk/lib/AST/DeclObjC.cpp
cfe/trunk/lib/Sema/Sema.h
cfe/trunk/lib/Sema/SemaDeclObjC.cpp
cfe/trunk/test/Sema/objc-property-3.m
Modified: cfe/trunk/include/clang/AST/DeclObjC.h
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/include/clang/AST/DeclObjC.h?rev=50587&r1=50586&r2=50587&view=diff
==============================================================================
--- cfe/trunk/include/clang/AST/DeclObjC.h (original)
+++ cfe/trunk/include/clang/AST/DeclObjC.h Fri May 2 14:17:30 2008
@@ -285,6 +285,12 @@
ObjCCategoryDecl *FindCategoryDeclaration(IdentifierInfo *CategoryId) const;
ObjCIvarDecl *FindIvarDeclaration(IdentifierInfo *IvarId) const;
+ typedef ObjCProtocolDecl * const * protocol_iterator;
+ protocol_iterator protocol_begin() const { return ReferencedProtocols; }
+ protocol_iterator protocol_end() const {
+ return ReferencedProtocols+NumReferencedProtocols;
+ }
+
typedef ObjCIvarDecl * const *ivar_iterator;
ivar_iterator ivar_begin() const { return Ivars; }
ivar_iterator ivar_end() const { return Ivars + ivar_size();}
@@ -314,6 +320,8 @@
void addProperties(ObjCPropertyDecl **Properties, unsigned NumProperties);
+ void mergeProperties(ObjCPropertyDecl **Properties, unsigned NumProperties);
+
typedef ObjCPropertyDecl * const * classprop_iterator;
classprop_iterator classprop_begin() const { return PropertyDecl; }
classprop_iterator classprop_end() const {
@@ -517,6 +525,12 @@
return ReferencedProtocols;
}
unsigned getNumReferencedProtocols() const { return NumReferencedProtocols; }
+ typedef ObjCProtocolDecl * const * protocol_iterator;
+ protocol_iterator protocol_begin() const { return ReferencedProtocols; }
+ protocol_iterator protocol_end() const {
+ return ReferencedProtocols+NumReferencedProtocols;
+ }
+
unsigned getNumInstanceMethods() const { return NumInstanceMethods; }
unsigned getNumClassMethods() const { return NumClassMethods; }
Modified: cfe/trunk/include/clang/Basic/DiagnosticKinds.def
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/include/clang/Basic/DiagnosticKinds.def?rev=50587&r1=50586&r2=50587&view=diff
==============================================================================
--- cfe/trunk/include/clang/Basic/DiagnosticKinds.def (original)
+++ cfe/trunk/include/clang/Basic/DiagnosticKinds.def Fri May 2 14:17:30 2008
@@ -510,12 +510,11 @@
"type of property '%0' does not match type of ivar '%1'")
DIAG(warn_readonly_property, WARNING,
"attribute 'readonly' of property '%0' restricts attribute "
- "'readwrite' of '%1' property in super class")
+ "'readwrite' of property inherited from '%1'")
DIAG(warn_property_attribute, WARNING,
- "property '%0' '%1' attribute does not match super class '%2' "
- "property")
+ "property '%0' '%1' attribute does not match the property inherited from'%2' ")
DIAG(warn_property_type, WARNING,
- "property type '%0' does not match super class '%1' property type")
+ "property type '%0' does not match property type inherited from '%1'")
//===----------------------------------------------------------------------===//
// Semantic Analysis
Modified: cfe/trunk/lib/AST/DeclObjC.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/AST/DeclObjC.cpp?rev=50587&r1=50586&r2=50587&view=diff
==============================================================================
--- cfe/trunk/lib/AST/DeclObjC.cpp (original)
+++ cfe/trunk/lib/AST/DeclObjC.cpp Fri May 2 14:17:30 2008
@@ -242,6 +242,33 @@
memcpy(PropertyDecl, Properties, NumProperties*sizeof(ObjCPropertyDecl*));
}
+/// mergeProperties - Adds properties to the end of list of current properties
+/// for this class.
+
+void ObjCInterfaceDecl::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*));
+ free(PropertyDecl);
+ PropertyDecl = newPropertyDecl;
+ NumPropertyDecl += NumNewProperties;
+ }
+ else {
+ PropertyDecl = new ObjCPropertyDecl*[NumNewProperties];
+ memcpy(PropertyDecl, Properties, NumNewProperties*sizeof(ObjCPropertyDecl*));
+ NumPropertyDecl = NumNewProperties;
+ }
+}
+
/// addProperties - Insert property declaration AST nodes into
/// ObjCProtocolDecl's PropertyDecl field.
///
Modified: cfe/trunk/lib/Sema/Sema.h
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/Sema/Sema.h?rev=50587&r1=50586&r2=50587&view=diff
==============================================================================
--- cfe/trunk/lib/Sema/Sema.h (original)
+++ cfe/trunk/lib/Sema/Sema.h Fri May 2 14:17:30 2008
@@ -662,9 +662,15 @@
void DiagnosePropertyMismatch(ObjCPropertyDecl *Property,
ObjCPropertyDecl *SuperProperty,
- ObjCInterfaceDecl*SuperIDecl);
+ const char *Name);
void ComparePropertiesInBaseAndSuper(ObjCInterfaceDecl *IDecl);
+ void MergeProtocolPropertiesIntoClass(ObjCInterfaceDecl *IDecl,
+ DeclTy *MergeProtocols);
+
+ void MergeOneProtocolPropertiesIntoClass(ObjCInterfaceDecl *IDecl,
+ ObjCProtocolDecl *PDecl);
+
virtual void ActOnAtEnd(SourceLocation AtEndLoc, DeclTy *classDecl,
DeclTy **allMethods = 0, unsigned allNum = 0,
DeclTy **allProperties = 0, unsigned pNum = 0);
Modified: cfe/trunk/lib/Sema/SemaDeclObjC.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/Sema/SemaDeclObjC.cpp?rev=50587&r1=50586&r2=50587&view=diff
==============================================================================
--- cfe/trunk/lib/Sema/SemaDeclObjC.cpp (original)
+++ cfe/trunk/lib/Sema/SemaDeclObjC.cpp Fri May 2 14:17:30 2008
@@ -247,12 +247,10 @@
/// DiagnosePropertyMismatch - Compares two properties for their
/// attributes and types and warns on a variety of inconsistancies.
///
-// TODO: Incomplete.
-//
void
Sema::DiagnosePropertyMismatch(ObjCPropertyDecl *Property,
ObjCPropertyDecl *SuperProperty,
- ObjCInterfaceDecl *SuperIDecl) {
+ const char *inheritedName) {
ObjCPropertyDecl::PropertyAttributeKind CAttr =
Property->getPropertyAttributes();
ObjCPropertyDecl::PropertyAttributeKind SAttr =
@@ -260,36 +258,36 @@
if ((CAttr & ObjCPropertyDecl::OBJC_PR_readonly)
&& (SAttr & ObjCPropertyDecl::OBJC_PR_readwrite))
Diag(Property->getLocation(), diag::warn_readonly_property,
- Property->getName(), SuperIDecl->getName());
+ Property->getName(), inheritedName);
if ((CAttr & ObjCPropertyDecl::OBJC_PR_copy)
!= (SAttr & ObjCPropertyDecl::OBJC_PR_copy))
Diag(Property->getLocation(), diag::warn_property_attribute,
- Property->getName(), "copy", SuperIDecl->getName(),
+ Property->getName(), "copy", inheritedName,
SourceRange());
else if ((CAttr & ObjCPropertyDecl::OBJC_PR_retain)
!= (SAttr & ObjCPropertyDecl::OBJC_PR_retain))
Diag(Property->getLocation(), diag::warn_property_attribute,
- Property->getName(), "retain", SuperIDecl->getName(),
+ Property->getName(), "retain", inheritedName,
SourceRange());
if ((CAttr & ObjCPropertyDecl::OBJC_PR_nonatomic)
!= (SAttr & ObjCPropertyDecl::OBJC_PR_nonatomic))
Diag(Property->getLocation(), diag::warn_property_attribute,
- Property->getName(), "atomic", SuperIDecl->getName(),
+ Property->getName(), "atomic", inheritedName,
SourceRange());
if (Property->getSetterName() != SuperProperty->getSetterName())
Diag(Property->getLocation(), diag::warn_property_attribute,
- Property->getName(), "setter", SuperIDecl->getName(),
+ Property->getName(), "setter", inheritedName,
SourceRange());
if (Property->getGetterName() != SuperProperty->getGetterName())
Diag(Property->getLocation(), diag::warn_property_attribute,
- Property->getName(), "getter", SuperIDecl->getName(),
+ Property->getName(), "getter", inheritedName,
SourceRange());
if (Property->getCanonicalType() != SuperProperty->getCanonicalType())
Diag(Property->getLocation(), diag::warn_property_type,
Property->getType().getAsString(),
- SuperIDecl->getName());
+ inheritedName);
}
@@ -310,11 +308,69 @@
E = IDecl->classprop_end(); I != E; ++I) {
ObjCPropertyDecl *PDecl = (*I);
if (SuperPDecl->getIdentifier() == PDecl->getIdentifier())
- DiagnosePropertyMismatch(PDecl, SuperPDecl, SDecl);
+ DiagnosePropertyMismatch(PDecl, SuperPDecl, SDecl->getName());
}
}
}
+/// 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.
+void
+Sema::MergeOneProtocolPropertiesIntoClass(ObjCInterfaceDecl *IDecl,
+ ObjCProtocolDecl *PDecl)
+{
+ llvm::SmallVector<ObjCPropertyDecl*, 16> mergeProperties;
+ for (ObjCProtocolDecl::classprop_iterator P = PDecl->classprop_begin(),
+ E = PDecl->classprop_end(); P != E; ++P) {
+ ObjCPropertyDecl *Pr = (*P);
+ ObjCInterfaceDecl::classprop_iterator CP, CE;
+ // Is this property already in class's list of properties?
+ for (CP = IDecl->classprop_begin(), CE = IDecl->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->getName());
+ }
+ IDecl->mergeProperties(&mergeProperties[0], mergeProperties.size());
+}
+
+/// 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'
+///
+
+void
+Sema::MergeProtocolPropertiesIntoClass(ObjCInterfaceDecl *IDecl,
+ DeclTy *MergeItsProtocols) {
+ Decl *ClassDecl = static_cast<Decl *>(MergeItsProtocols);
+ if (ObjCInterfaceDecl *MDecl =
+ dyn_cast<ObjCInterfaceDecl>(ClassDecl)) {
+ for (ObjCInterfaceDecl::protocol_iterator P = MDecl->protocol_begin(),
+ E = MDecl->protocol_end(); P != E; ++P)
+ MergeOneProtocolPropertiesIntoClass(IDecl, (*P));
+ // Merge properties of class (*P) into IDECL's
+ ;
+ // Go thru the list of protocols for this class and recursively merge
+ // their properties into this class as well.
+ for (ObjCInterfaceDecl::protocol_iterator P = IDecl->protocol_begin(),
+ E = IDecl->protocol_end(); P != E; ++P)
+ MergeProtocolPropertiesIntoClass(IDecl, (*P));
+ }
+ else if (ObjCProtocolDecl *MDecl =
+ dyn_cast<ObjCProtocolDecl>(ClassDecl))
+ for (ObjCProtocolDecl::protocol_iterator P = MDecl->protocol_begin(),
+ E = MDecl->protocol_end(); P != E; ++P)
+ MergeOneProtocolPropertiesIntoClass(IDecl, (*P));
+ else
+ assert(false && "MergeProtocolPropertiesIntoClass - bad object kind");
+}
+
/// ActOnForwardProtocolDeclaration -
Action::DeclTy *
Sema::ActOnForwardProtocolDeclaration(SourceLocation AtProtocolLoc,
@@ -820,7 +876,8 @@
&clsMethods[0], clsMethods.size(), AtEndLoc);
// Compares properties declaraed in this class to those of its
// super class.
- ComparePropertiesInBaseAndSuper (I);
+ ComparePropertiesInBaseAndSuper(I);
+ MergeProtocolPropertiesIntoClass(I, I);
} else if (ObjCProtocolDecl *P = dyn_cast<ObjCProtocolDecl>(ClassDecl)) {
P->addMethods(&insMethods[0], insMethods.size(),
&clsMethods[0], clsMethods.size(), AtEndLoc);
Modified: cfe/trunk/test/Sema/objc-property-3.m
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/test/Sema/objc-property-3.m?rev=50587&r1=50586&r2=50587&view=diff
==============================================================================
--- cfe/trunk/test/Sema/objc-property-3.m (original)
+++ cfe/trunk/test/Sema/objc-property-3.m Fri May 2 14:17:30 2008
@@ -9,7 +9,7 @@
@end
@interface NOW : I
- at property (readonly, retain) id d1; // expected-warning {{attribute 'readonly' of property 'd1' restricts attribute 'readwrite' of 'I' property in super class}} expected-warning {{property 'd1' 'copy' attribute does not match super class 'I' property}}
- at property (readwrite, copy) I* d2; // expected-warning {{property type 'I *' does not match super class 'I' property type}}
+ at property (readonly, retain) id d1; // expected-warning {{attribute 'readonly' of property 'd1' restricts attribute 'readwrite' of property inherited from 'I'}} expected-warning {{property 'd1' 'copy' attribute does not match the property inherited from'I'}}
+ at property (readwrite, copy) I* d2; // expected-warning {{property type 'I *' does not match property type inherited from 'I'}}
@end
Added: cfe/trunk/test/Sema/objc-property-4.m
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/test/Sema/objc-property-4.m?rev=50587&view=auto
==============================================================================
--- cfe/trunk/test/Sema/objc-property-4.m (added)
+++ cfe/trunk/test/Sema/objc-property-4.m Fri May 2 14:17:30 2008
@@ -0,0 +1,30 @@
+// RUN: clang -verify %s
+
+ at interface Object
+ at end
+
+ at protocol ProtocolObject
+ at property int class;
+ at property (copy) id MayCauseError;
+ at end
+
+ at protocol ProtocolDerivedGCObject <ProtocolObject>
+ at property int Dclass;
+ at end
+
+ at interface GCObject : Object <ProtocolDerivedGCObject> {
+ int ifield;
+ int iOwnClass;
+ int iDclass;
+}
+ at property int OwnClass;
+ at end
+
+ at interface ReleaseObject : GCObject <ProtocolObject> {
+ int newO;
+ int oldO;
+}
+ at property (retain) id MayCauseError; // expected-warning {{property 'MayCauseError' 'copy' attribute does not match the property inherited from'GCObject'}} \
+ expected-warning {{property 'MayCauseError' 'copy' attribute does not match the property inherited from'ProtocolObject'}}
+ at end
+
More information about the cfe-commits
mailing list