|
@@ -1530,37 +1530,50 @@ bool Sema::DiagnosePropertyAccessorMismatch(ObjCPropertyDecl *property,
|
|
|
|
|
|
/// CollectImmediateProperties - This routine collects all properties in
|
|
/// CollectImmediateProperties - This routine collects all properties in
|
|
/// the class and its conforming protocols; but not those in its super class.
|
|
/// 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)) {
|
|
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())] =
|
|
PropMap[std::make_pair(Prop->getIdentifier(), Prop->isClassProperty())] =
|
|
Prop;
|
|
Prop;
|
|
|
|
+ }
|
|
|
|
|
|
// Collect the properties from visible extensions.
|
|
// Collect the properties from visible extensions.
|
|
for (auto *Ext : IDecl->visible_extensions())
|
|
for (auto *Ext : IDecl->visible_extensions())
|
|
- CollectImmediateProperties(Ext, PropMap, SuperPropMap, IncludeProtocols);
|
|
|
|
|
|
+ CollectImmediateProperties(Ext, PropMap, SuperPropMap,
|
|
|
|
+ CollectClassPropsOnly, IncludeProtocols);
|
|
|
|
|
|
if (IncludeProtocols) {
|
|
if (IncludeProtocols) {
|
|
// Scan through class's protocols.
|
|
// Scan through class's protocols.
|
|
for (auto *PI : IDecl->all_referenced_protocols())
|
|
for (auto *PI : IDecl->all_referenced_protocols())
|
|
- CollectImmediateProperties(PI, PropMap, SuperPropMap);
|
|
|
|
|
|
+ CollectImmediateProperties(PI, PropMap, SuperPropMap,
|
|
|
|
+ CollectClassPropsOnly);
|
|
}
|
|
}
|
|
}
|
|
}
|
|
if (ObjCCategoryDecl *CATDecl = dyn_cast<ObjCCategoryDecl>(CDecl)) {
|
|
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())] =
|
|
PropMap[std::make_pair(Prop->getIdentifier(), Prop->isClassProperty())] =
|
|
Prop;
|
|
Prop;
|
|
|
|
+ }
|
|
if (IncludeProtocols) {
|
|
if (IncludeProtocols) {
|
|
// Scan through class's protocols.
|
|
// Scan through class's protocols.
|
|
for (auto *PI : CATDecl->protocols())
|
|
for (auto *PI : CATDecl->protocols())
|
|
- CollectImmediateProperties(PI, PropMap, SuperPropMap);
|
|
|
|
|
|
+ CollectImmediateProperties(PI, PropMap, SuperPropMap,
|
|
|
|
+ CollectClassPropsOnly);
|
|
}
|
|
}
|
|
}
|
|
}
|
|
else if (ObjCProtocolDecl *PDecl = dyn_cast<ObjCProtocolDecl>(CDecl)) {
|
|
else if (ObjCProtocolDecl *PDecl = dyn_cast<ObjCProtocolDecl>(CDecl)) {
|
|
for (auto *Prop : PDecl->properties()) {
|
|
for (auto *Prop : PDecl->properties()) {
|
|
|
|
+ if (CollectClassPropsOnly && !Prop->isClassProperty())
|
|
|
|
+ continue;
|
|
ObjCPropertyDecl *PropertyFromSuper =
|
|
ObjCPropertyDecl *PropertyFromSuper =
|
|
SuperPropMap[std::make_pair(Prop->getIdentifier(),
|
|
SuperPropMap[std::make_pair(Prop->getIdentifier(),
|
|
Prop->isClassProperty())];
|
|
Prop->isClassProperty())];
|
|
@@ -1575,9 +1588,10 @@ static void CollectImmediateProperties(ObjCContainerDecl *CDecl,
|
|
PropEntry = Prop;
|
|
PropEntry = Prop;
|
|
}
|
|
}
|
|
}
|
|
}
|
|
- // scan through protocol's protocols.
|
|
|
|
|
|
+ // Scan through protocol's protocols.
|
|
for (auto *PI : PDecl->protocols())
|
|
for (auto *PI : PDecl->protocols())
|
|
- CollectImmediateProperties(PI, PropMap, SuperPropMap);
|
|
|
|
|
|
+ CollectImmediateProperties(PI, PropMap, SuperPropMap,
|
|
|
|
+ CollectClassPropsOnly);
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
|
|
@@ -1765,19 +1779,22 @@ static void DiagnoseUnimplementedAccessor(Sema &S,
|
|
(PrimaryClass == nullptr ||
|
|
(PrimaryClass == nullptr ||
|
|
!PrimaryClass->lookupPropertyAccessor(Method, C,
|
|
!PrimaryClass->lookupPropertyAccessor(Method, C,
|
|
Prop->isClassProperty()))) {
|
|
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,
|
|
void Sema::DiagnoseUnimplementedProperties(Scope *S, ObjCImplDecl* IMPDecl,
|
|
@@ -1786,25 +1803,27 @@ void Sema::DiagnoseUnimplementedProperties(Scope *S, ObjCImplDecl* IMPDecl,
|
|
ObjCContainerDecl::PropertyMap PropMap;
|
|
ObjCContainerDecl::PropertyMap PropMap;
|
|
ObjCInterfaceDecl *IDecl = dyn_cast<ObjCInterfaceDecl>(CDecl);
|
|
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
|
|
// Scan the @interface to see if any of the protocols it adopts
|
|
// require an explicit implementation, via attribute
|
|
// require an explicit implementation, via attribute
|
|
@@ -1826,6 +1845,7 @@ void Sema::DiagnoseUnimplementedProperties(Scope *S, ObjCImplDecl* IMPDecl,
|
|
ObjCContainerDecl::PropertyMap NoNeedToImplPropMap;
|
|
ObjCContainerDecl::PropertyMap NoNeedToImplPropMap;
|
|
LazyMap.reset(new ObjCContainerDecl::PropertyMap());
|
|
LazyMap.reset(new ObjCContainerDecl::PropertyMap());
|
|
CollectImmediateProperties(CDecl, *LazyMap, NoNeedToImplPropMap,
|
|
CollectImmediateProperties(CDecl, *LazyMap, NoNeedToImplPropMap,
|
|
|
|
+ /* CollectClassPropsOnly */ false,
|
|
/* IncludeProtocols */ false);
|
|
/* IncludeProtocols */ false);
|
|
}
|
|
}
|
|
// Add the properties of 'PDecl' to the list of properties that
|
|
// Add the properties of 'PDecl' to the list of properties that
|
|
@@ -1868,7 +1888,7 @@ void Sema::DiagnoseUnimplementedProperties(Scope *S, ObjCImplDecl* IMPDecl,
|
|
for (ObjCContainerDecl::PropertyMap::iterator
|
|
for (ObjCContainerDecl::PropertyMap::iterator
|
|
P = PropMap.begin(), E = PropMap.end(); P != E; ++P) {
|
|
P = PropMap.begin(), E = PropMap.end(); P != E; ++P) {
|
|
ObjCPropertyDecl *Prop = P->second;
|
|
ObjCPropertyDecl *Prop = P->second;
|
|
- // Is there a matching propery synthesize/dynamic?
|
|
|
|
|
|
+ // Is there a matching property synthesize/dynamic?
|
|
if (Prop->isInvalidDecl() ||
|
|
if (Prop->isInvalidDecl() ||
|
|
Prop->getPropertyImplementation() == ObjCPropertyDecl::Optional ||
|
|
Prop->getPropertyImplementation() == ObjCPropertyDecl::Optional ||
|
|
PropImplMap.count(Prop) ||
|
|
PropImplMap.count(Prop) ||
|