summaryrefslogtreecommitdiffstats
path: root/clang/lib
diff options
context:
space:
mode:
authorFariborz Jahanian <fjahanian@apple.com>2008-05-02 19:17:30 +0000
committerFariborz Jahanian <fjahanian@apple.com>2008-05-02 19:17:30 +0000
commit98a6c4fa77f21368a32a5a853a3899ac1016267e (patch)
treec5be492e7c28b86443f52ba2a3fdbb76a858f430 /clang/lib
parent5f0563ceb605b35a109dd96ce5f69860169fe5c0 (diff)
downloadbcm5719-llvm-98a6c4fa77f21368a32a5a853a3899ac1016267e.tar.gz
bcm5719-llvm-98a6c4fa77f21368a32a5a853a3899ac1016267e.zip
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. llvm-svn: 50587
Diffstat (limited to 'clang/lib')
-rw-r--r--clang/lib/AST/DeclObjC.cpp27
-rw-r--r--clang/lib/Sema/Sema.h8
-rw-r--r--clang/lib/Sema/SemaDeclObjC.cpp81
3 files changed, 103 insertions, 13 deletions
diff --git a/clang/lib/AST/DeclObjC.cpp b/clang/lib/AST/DeclObjC.cpp
index ef4a6e1c3d0..89f6d2c5019 100644
--- a/clang/lib/AST/DeclObjC.cpp
+++ b/clang/lib/AST/DeclObjC.cpp
@@ -242,6 +242,33 @@ void ObjCInterfaceDecl::addProperties(ObjCPropertyDecl **Properties,
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.
///
diff --git a/clang/lib/Sema/Sema.h b/clang/lib/Sema/Sema.h
index 1bed03c1fca..68a834c6b4c 100644
--- a/clang/lib/Sema/Sema.h
+++ b/clang/lib/Sema/Sema.h
@@ -662,9 +662,15 @@ public:
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);
diff --git a/clang/lib/Sema/SemaDeclObjC.cpp b/clang/lib/Sema/SemaDeclObjC.cpp
index e95ad6469ba..afac82ca76f 100644
--- a/clang/lib/Sema/SemaDeclObjC.cpp
+++ b/clang/lib/Sema/SemaDeclObjC.cpp
@@ -247,12 +247,10 @@ Sema::FindProtocolDeclaration(SourceLocation TypeLoc,
/// 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 @@ Sema::DiagnosePropertyMismatch(ObjCPropertyDecl *Property,
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 @@ Sema::ComparePropertiesInBaseAndSuper(ObjCInterfaceDecl *IDecl) {
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 @@ void Sema::ActOnAtEnd(SourceLocation AtEndLoc, DeclTy *classDecl,
&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);
OpenPOWER on IntegriCloud