[ObjC] Change default property synthesis logic to not completely skip DiagnoseUnimplementedProperties.

We're going to extend DiagnoseUnimplementedProperties shortly to look for more cases
that aren't handled by default property synthesis.

llvm-svn: 201878
This commit is contained in:
Ted Kremenek 2014-02-21 19:41:34 +00:00
parent 7e81295153
commit 348e88c36a
4 changed files with 37 additions and 29 deletions

View File

@ -1228,10 +1228,11 @@ public:
/// including in all categories except for category passed
/// as argument.
ObjCMethodDecl *lookupPropertyAccessor(const Selector Sel,
const ObjCCategoryDecl *Cat) const {
const ObjCCategoryDecl *Cat,
bool followsSuper = true) const {
return lookupMethod(Sel, true/*isInstance*/,
false/*shallowCategoryLookup*/,
true /* followsSuper */,
followsSuper /* followsSuper */,
Cat);
}

View File

@ -2658,7 +2658,8 @@ public:
/// DiagnoseUnimplementedProperties - This routine warns on those properties
/// which must be implemented by this implementation.
void DiagnoseUnimplementedProperties(Scope *S, ObjCImplDecl* IMPDecl,
ObjCContainerDecl *CDecl);
ObjCContainerDecl *CDecl,
bool SynthesizeProperties);
/// DefaultSynthesizeProperties - This routine default synthesizes all
/// properties which must be synthesized in the class's \@implementation.

View File

@ -1927,12 +1927,13 @@ void Sema::ImplMethodsVsClassMethods(Scope *S, ObjCImplDecl* IMPDecl,
// Check and see if properties declared in the interface have either 1)
// an implementation or 2) there is a @synthesize/@dynamic implementation
// of the property in the @implementation.
if (const ObjCInterfaceDecl *IDecl = dyn_cast<ObjCInterfaceDecl>(CDecl))
if (!(LangOpts.ObjCDefaultSynthProperties &&
LangOpts.ObjCRuntime.isNonFragile()) ||
IDecl->isObjCRequiresPropertyDefs())
DiagnoseUnimplementedProperties(S, IMPDecl, CDecl);
if (const ObjCInterfaceDecl *IDecl = dyn_cast<ObjCInterfaceDecl>(CDecl)) {
bool SynthesizeProperties = LangOpts.ObjCDefaultSynthProperties &&
LangOpts.ObjCRuntime.isNonFragile() &&
!IDecl->isObjCRequiresPropertyDefs();
DiagnoseUnimplementedProperties(S, IMPDecl, CDecl, SynthesizeProperties);
}
SelectorSet ClsMap;
for (ObjCImplementationDecl::classmeth_iterator
I = IMPDecl->classmeth_begin(),
@ -1978,7 +1979,8 @@ void Sema::ImplMethodsVsClassMethods(Scope *S, ObjCImplDecl* IMPDecl,
E = C->protocol_end(); PI != E; ++PI)
CheckProtocolMethodDefs(*this, IMPDecl->getLocation(), *PI,
IncompleteImpl, InsMap, ClsMap, CDecl);
DiagnoseUnimplementedProperties(S, IMPDecl, CDecl);
DiagnoseUnimplementedProperties(S, IMPDecl, CDecl,
/* SynthesizeProperties */ false);
}
} else
llvm_unreachable("invalid ObjCContainerDecl type.");

View File

@ -1650,26 +1650,30 @@ static void DiagnoseUnimplementedAccessor(Sema &S,
}
void Sema::DiagnoseUnimplementedProperties(Scope *S, ObjCImplDecl* IMPDecl,
ObjCContainerDecl *CDecl) {
ObjCContainerDecl::PropertyMap NoNeedToImplPropMap;
ObjCInterfaceDecl *IDecl;
// Gather properties which need not be implemented in this class
// or category.
if (!(IDecl = dyn_cast<ObjCInterfaceDecl>(CDecl)))
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);
ObjCContainerDecl *CDecl,
bool SynthesizeProperties) {
ObjCContainerDecl::PropertyMap PropMap;
CollectImmediateProperties(CDecl, PropMap, NoNeedToImplPropMap);
if (!SynthesizeProperties) {
ObjCContainerDecl::PropertyMap NoNeedToImplPropMap;
ObjCInterfaceDecl *IDecl;
// Gather properties which need not be implemented in this class
// or category.
if (!(IDecl = dyn_cast<ObjCInterfaceDecl>(CDecl)))
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);
CollectImmediateProperties(CDecl, PropMap, NoNeedToImplPropMap);
}
if (PropMap.empty())
return;