aboutsummaryrefslogtreecommitdiff
path: root/lib
diff options
context:
space:
mode:
Diffstat (limited to 'lib')
-rw-r--r--lib/Sema/Sema.h14
-rw-r--r--lib/Sema/SemaDeclObjC.cpp109
2 files changed, 82 insertions, 41 deletions
diff --git a/lib/Sema/Sema.h b/lib/Sema/Sema.h
index 948949b7dc..90a755aa0c 100644
--- a/lib/Sema/Sema.h
+++ b/lib/Sema/Sema.h
@@ -1278,9 +1278,6 @@ public:
const llvm::DenseSet<Selector> &InsMap,
const llvm::DenseSet<Selector> &ClsMap,
ObjCInterfaceDecl *IDecl);
-
- void CheckPropertyImplementation(ObjCImplDecl* IMPDecl,
- ObjCInterfaceDecl *CDecl);
/// CheckImplementationIvars - This routine checks if the instance variables
/// listed in the implelementation match those listed in the interface.
@@ -1294,6 +1291,17 @@ public:
ObjCContainerDecl* IDecl,
bool IncompleteImpl = false);
+ /// DiagnoseUnimplementedProperties - This routine warns on those properties
+ /// which must be implemented by this implementation.
+ void DiagnoseUnimplementedProperties(ObjCImplDecl* IMPDecl,
+ ObjCContainerDecl *CDecl,
+ const llvm::DenseSet<Selector>& InsMap);
+
+ /// CollectImmediateProperties - This routine collects all properties in
+ /// the class and its conforming protocols; but not those it its super class.
+ void CollectImmediateProperties(ObjCContainerDecl *CDecl,
+ llvm::DenseMap<IdentifierInfo *, ObjCPropertyDecl*>& PropMap);
+
/// AtomicPropertySetterGetterRules - This routine enforces the rule (via
/// warning) when atomic property has one but not the other user-declared
/// setter or getter.
diff --git a/lib/Sema/SemaDeclObjC.cpp b/lib/Sema/SemaDeclObjC.cpp
index c0cbc416d9..f970c314d5 100644
--- a/lib/Sema/SemaDeclObjC.cpp
+++ b/lib/Sema/SemaDeclObjC.cpp
@@ -1086,11 +1086,75 @@ void Sema::MatchAllMethodDeclarations(const llvm::DenseSet<Selector> &InsMap,
}
}
-/// CheckPropertyImplementation - Check that all required properties are
-/// synthesized in class's implementation. This includes properties
-/// declared in current class and in class's protocols (direct or indirect).
-void Sema::CheckPropertyImplementation(ObjCImplDecl* IMPDecl,
- ObjCInterfaceDecl *CDecl) {
+/// CollectImmediateProperties - This routine collects all properties in
+/// the class and its conforming protocols; but not those it its super class.
+void Sema::CollectImmediateProperties(ObjCContainerDecl *CDecl,
+ llvm::DenseMap<IdentifierInfo *, ObjCPropertyDecl*>& PropMap) {
+ if (ObjCInterfaceDecl *IDecl = dyn_cast<ObjCInterfaceDecl>(CDecl)) {
+ for (ObjCContainerDecl::prop_iterator P = IDecl->prop_begin(),
+ E = IDecl->prop_end(); P != E; ++P) {
+ ObjCPropertyDecl *Prop = (*P);
+ PropMap[Prop->getIdentifier()] = Prop;
+ }
+ // scan through class's protocols.
+ for (ObjCInterfaceDecl::protocol_iterator PI = IDecl->protocol_begin(),
+ E = IDecl->protocol_end(); PI != E; ++PI)
+ CollectImmediateProperties((*PI), PropMap);
+ }
+ else if (ObjCProtocolDecl *PDecl = dyn_cast<ObjCProtocolDecl>(CDecl)) {
+ for (ObjCProtocolDecl::prop_iterator P = PDecl->prop_begin(),
+ E = PDecl->prop_end(); P != E; ++P) {
+ ObjCPropertyDecl *Prop = (*P);
+ ObjCPropertyDecl *&PropEntry = PropMap[Prop->getIdentifier()];
+ if (!PropEntry)
+ PropEntry = Prop;
+ }
+ // scan through protocol's protocols.
+ for (ObjCProtocolDecl::protocol_iterator PI = PDecl->protocol_begin(),
+ E = PDecl->protocol_end(); PI != E; ++PI)
+ CollectImmediateProperties((*PI), PropMap);
+ }
+}
+
+void Sema::DiagnoseUnimplementedProperties(ObjCImplDecl* IMPDecl,
+ ObjCContainerDecl *CDecl,
+ const llvm::DenseSet<Selector>& InsMap) {
+ llvm::DenseMap<IdentifierInfo *, ObjCPropertyDecl*> PropMap;
+ CollectImmediateProperties(CDecl, PropMap);
+
+ for (llvm::DenseMap<IdentifierInfo *, ObjCPropertyDecl*>::iterator
+ P = PropMap.begin(), E = PropMap.end(); P != E; ++P) {
+ ObjCPropertyDecl *Prop = P->second;
+ if (Prop->isInvalidDecl() ||
+ Prop->getPropertyImplementation() == ObjCPropertyDecl::Optional)
+ continue;
+ ObjCPropertyImplDecl *PI = 0;
+ // Is there a matching propery synthesize/dynamic?
+ for (ObjCImplDecl::propimpl_iterator
+ I = IMPDecl->propimpl_begin(),
+ EI = IMPDecl->propimpl_end(); I != EI; ++I)
+ if ((*I)->getPropertyDecl() == Prop) {
+ PI = (*I);
+ break;
+ }
+ if (PI)
+ continue;
+ if (!InsMap.count(Prop->getGetterName())) {
+ Diag(Prop->getLocation(),
+ diag::warn_setter_getter_impl_required)
+ << Prop->getDeclName() << Prop->getGetterName();
+ Diag(IMPDecl->getLocation(),
+ diag::note_property_impl_required);
+ }
+
+ if (!Prop->isReadOnly() && !InsMap.count(Prop->getSetterName())) {
+ Diag(Prop->getLocation(),
+ diag::warn_setter_getter_impl_required)
+ << Prop->getDeclName() << Prop->getSetterName();
+ Diag(IMPDecl->getLocation(),
+ diag::note_property_impl_required);
+ }
+ }
}
void Sema::ImplMethodsVsClassMethods(ObjCImplDecl* IMPDecl,
@@ -1107,39 +1171,8 @@ void Sema::ImplMethodsVsClassMethods(ObjCImplDecl* IMPDecl,
// an implementation or 2) there is a @synthesize/@dynamic implementation
// of the property in the @implementation.
if (isa<ObjCInterfaceDecl>(CDecl))
- for (ObjCContainerDecl::prop_iterator P = CDecl->prop_begin(),
- E = CDecl->prop_end(); P != E; ++P) {
- ObjCPropertyDecl *Prop = (*P);
- if (Prop->isInvalidDecl())
- continue;
- ObjCPropertyImplDecl *PI = 0;
- // Is there a matching propery synthesize/dynamic?
- for (ObjCImplDecl::propimpl_iterator
- I = IMPDecl->propimpl_begin(),
- EI = IMPDecl->propimpl_end(); I != EI; ++I)
- if ((*I)->getPropertyDecl() == Prop) {
- PI = (*I);
- break;
- }
- if (PI)
- continue;
- if (!InsMap.count(Prop->getGetterName())) {
- Diag(Prop->getLocation(),
- diag::warn_setter_getter_impl_required)
- << Prop->getDeclName() << Prop->getGetterName();
- Diag(IMPDecl->getLocation(),
- diag::note_property_impl_required);
- }
-
- if (!Prop->isReadOnly() && !InsMap.count(Prop->getSetterName())) {
- Diag(Prop->getLocation(),
- diag::warn_setter_getter_impl_required)
- << Prop->getDeclName() << Prop->getSetterName();
- Diag(IMPDecl->getLocation(),
- diag::note_property_impl_required);
- }
- }
-
+ DiagnoseUnimplementedProperties(IMPDecl, CDecl, InsMap);
+
llvm::DenseSet<Selector> ClsMap;
for (ObjCImplementationDecl::classmeth_iterator
I = IMPDecl->classmeth_begin(),