/// CollectImmediateProperties - This routine collects all properties in
/// the class and its conforming protocols; but not those in its super class.
-static void CollectImmediateProperties(ObjCContainerDecl *CDecl,
- ObjCContainerDecl::PropertyMap &PropMap,
- ObjCContainerDecl::PropertyMap &SuperPropMap,
- bool IncludeProtocols = true) {
+static void
+CollectImmediateProperties(ObjCContainerDecl *CDecl,
+ ObjCContainerDecl::PropertyMap &PropMap,
+ ObjCContainerDecl::PropertyMap &SuperPropMap,
+ bool CollectClassPropsOnly = false,
+ bool IncludeProtocols = true) {
if (ObjCInterfaceDecl *IDecl = dyn_cast<ObjCInterfaceDecl>(CDecl)) {
- for (auto *Prop : IDecl->properties())
+ for (auto *Prop : IDecl->properties()) {
+ if (CollectClassPropsOnly && !Prop->isClassProperty())
+ continue;
PropMap[std::make_pair(Prop->getIdentifier(), Prop->isClassProperty())] =
Prop;
+ }
// Collect the properties from visible extensions.
for (auto *Ext : IDecl->visible_extensions())
- CollectImmediateProperties(Ext, PropMap, SuperPropMap, IncludeProtocols);
+ CollectImmediateProperties(Ext, PropMap, SuperPropMap,
+ CollectClassPropsOnly, IncludeProtocols);
if (IncludeProtocols) {
// Scan through class's protocols.
for (auto *PI : IDecl->all_referenced_protocols())
- CollectImmediateProperties(PI, PropMap, SuperPropMap);
+ CollectImmediateProperties(PI, PropMap, SuperPropMap,
+ CollectClassPropsOnly);
}
}
if (ObjCCategoryDecl *CATDecl = dyn_cast<ObjCCategoryDecl>(CDecl)) {
- for (auto *Prop : CATDecl->properties())
+ for (auto *Prop : CATDecl->properties()) {
+ if (CollectClassPropsOnly && !Prop->isClassProperty())
+ continue;
PropMap[std::make_pair(Prop->getIdentifier(), Prop->isClassProperty())] =
Prop;
+ }
if (IncludeProtocols) {
// Scan through class's protocols.
for (auto *PI : CATDecl->protocols())
- CollectImmediateProperties(PI, PropMap, SuperPropMap);
+ CollectImmediateProperties(PI, PropMap, SuperPropMap,
+ CollectClassPropsOnly);
}
}
else if (ObjCProtocolDecl *PDecl = dyn_cast<ObjCProtocolDecl>(CDecl)) {
for (auto *Prop : PDecl->properties()) {
+ if (CollectClassPropsOnly && !Prop->isClassProperty())
+ continue;
ObjCPropertyDecl *PropertyFromSuper =
SuperPropMap[std::make_pair(Prop->getIdentifier(),
Prop->isClassProperty())];
PropEntry = Prop;
}
}
- // scan through protocol's protocols.
+ // Scan through protocol's protocols.
for (auto *PI : PDecl->protocols())
- CollectImmediateProperties(PI, PropMap, SuperPropMap);
+ CollectImmediateProperties(PI, PropMap, SuperPropMap,
+ CollectClassPropsOnly);
}
}
(PrimaryClass == nullptr ||
!PrimaryClass->lookupPropertyAccessor(Method, C,
Prop->isClassProperty()))) {
- S.Diag(IMPDecl->getLocation(),
- isa<ObjCCategoryDecl>(CDecl) ?
- diag::warn_setter_getter_impl_required_in_category :
- diag::warn_setter_getter_impl_required)
- << Prop->getDeclName() << Method;
- S.Diag(Prop->getLocation(),
- diag::note_property_declare);
- if (S.LangOpts.ObjCDefaultSynthProperties &&
- S.LangOpts.ObjCRuntime.isNonFragile())
- if (ObjCInterfaceDecl *ID = dyn_cast<ObjCInterfaceDecl>(CDecl))
- if (const ObjCInterfaceDecl *RID = ID->isObjCRequiresPropertyDefs())
- S.Diag(RID->getLocation(), diag::note_suppressed_class_declare);
- }
+ unsigned diag =
+ isa<ObjCCategoryDecl>(CDecl)
+ ? (Prop->isClassProperty()
+ ? diag::warn_impl_required_in_category_for_class_property
+ : diag::warn_setter_getter_impl_required_in_category)
+ : (Prop->isClassProperty()
+ ? diag::warn_impl_required_for_class_property
+ : diag::warn_setter_getter_impl_required);
+ S.Diag(IMPDecl->getLocation(), diag) << Prop->getDeclName() << Method;
+ S.Diag(Prop->getLocation(), diag::note_property_declare);
+ if (S.LangOpts.ObjCDefaultSynthProperties &&
+ S.LangOpts.ObjCRuntime.isNonFragile())
+ if (ObjCInterfaceDecl *ID = dyn_cast<ObjCInterfaceDecl>(CDecl))
+ if (const ObjCInterfaceDecl *RID = ID->isObjCRequiresPropertyDefs())
+ S.Diag(RID->getLocation(), diag::note_suppressed_class_declare);
+ }
}
void Sema::DiagnoseUnimplementedProperties(Scope *S, ObjCImplDecl* IMPDecl,
ObjCContainerDecl::PropertyMap PropMap;
ObjCInterfaceDecl *IDecl = dyn_cast<ObjCInterfaceDecl>(CDecl);
- if (!SynthesizeProperties) {
- ObjCContainerDecl::PropertyMap NoNeedToImplPropMap;
- // Gather properties which need not be implemented in this class
- // or category.
- if (!IDecl)
- if (ObjCCategoryDecl *C = dyn_cast<ObjCCategoryDecl>(CDecl)) {
- // For categories, no need to implement properties declared in
- // its primary class (and its super classes) if property is
- // declared in one of those containers.
- if ((IDecl = C->getClassInterface())) {
- ObjCInterfaceDecl::PropertyDeclOrder PO;
- IDecl->collectPropertiesToImplement(NoNeedToImplPropMap, PO);
- }
+ // Since we don't synthesize class properties, we should emit diagnose even
+ // if SynthesizeProperties is true.
+ ObjCContainerDecl::PropertyMap NoNeedToImplPropMap;
+ // Gather properties which need not be implemented in this class
+ // or category.
+ if (!IDecl)
+ if (ObjCCategoryDecl *C = dyn_cast<ObjCCategoryDecl>(CDecl)) {
+ // For categories, no need to implement properties declared in
+ // its primary class (and its super classes) if property is
+ // declared in one of those containers.
+ if ((IDecl = C->getClassInterface())) {
+ ObjCInterfaceDecl::PropertyDeclOrder PO;
+ IDecl->collectPropertiesToImplement(NoNeedToImplPropMap, PO);
}
- if (IDecl)
- CollectSuperClassPropertyImplementations(IDecl, NoNeedToImplPropMap);
+ }
+ if (IDecl)
+ CollectSuperClassPropertyImplementations(IDecl, NoNeedToImplPropMap);
- CollectImmediateProperties(CDecl, PropMap, NoNeedToImplPropMap);
- }
+ // When SynthesizeProperties is true, we only check class properties.
+ CollectImmediateProperties(CDecl, PropMap, NoNeedToImplPropMap,
+ SynthesizeProperties/*CollectClassPropsOnly*/);
// Scan the @interface to see if any of the protocols it adopts
// require an explicit implementation, via attribute
ObjCContainerDecl::PropertyMap NoNeedToImplPropMap;
LazyMap.reset(new ObjCContainerDecl::PropertyMap());
CollectImmediateProperties(CDecl, *LazyMap, NoNeedToImplPropMap,
+ /* CollectClassPropsOnly */ false,
/* IncludeProtocols */ false);
}
// Add the properties of 'PDecl' to the list of properties that
for (ObjCContainerDecl::PropertyMap::iterator
P = PropMap.begin(), E = PropMap.end(); P != E; ++P) {
ObjCPropertyDecl *Prop = P->second;
- // Is there a matching propery synthesize/dynamic?
+ // Is there a matching property synthesize/dynamic?
if (Prop->isInvalidDecl() ||
Prop->getPropertyImplementation() == ObjCPropertyDecl::Optional ||
PropImplMap.count(Prop) ||