forked from OSchip/llvm-project
Patch to implement required warnings for unimplemented
properties imported frfom protocol. Fixes radar 7544809. llvm-svn: 93965
This commit is contained in:
parent
1bcb2631e6
commit
98609b3a07
|
@ -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.
|
||||
|
|
|
@ -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(),
|
||||
|
|
|
@ -12,6 +12,7 @@ void test() {
|
|||
}
|
||||
|
||||
@protocol P1
|
||||
@optional
|
||||
@property int *sprop; // expected-note{{'sprop' declared here}}
|
||||
@end
|
||||
|
||||
|
|
|
@ -0,0 +1,20 @@
|
|||
// RUN: %clang_cc1 -fsyntax-only -verify %s
|
||||
|
||||
@protocol PROTOCOL0
|
||||
@required
|
||||
@property float MyProperty0; // expected-warning {{property 'MyProperty0' requires method 'MyProperty0' to be defined }} \
|
||||
// expected-warning {{property 'MyProperty0' requires method 'setMyProperty0:' to be defined}}
|
||||
@end
|
||||
|
||||
@protocol PROTOCOL<PROTOCOL0>
|
||||
@required
|
||||
@property float MyProperty; // expected-warning {{property 'MyProperty' requires method 'MyProperty' to be defined}} \
|
||||
// expected-warning {{property 'MyProperty' requires method 'setMyProperty:' to be defined}}
|
||||
@optional
|
||||
@property float OptMyProperty;
|
||||
@end
|
||||
|
||||
@interface I <PROTOCOL>
|
||||
@end
|
||||
|
||||
@implementation I @end // expected-note 4 {{implementation is here}}
|
Loading…
Reference in New Issue