зеркало из https://github.com/microsoft/clang-1.git
Settled rule on warning on unimplemented property in
category implementation when some implementations are missing in the primary class implementation. (fixes radar 6505200). git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@94014 91177308-0d34-0410-b5e6-96231b3b80d8
This commit is contained in:
Родитель
3ea5cf8889
Коммит
3ad230eb62
|
@ -1840,6 +1840,9 @@ def err_illegal_super_cast : Error<
|
|||
def warn_setter_getter_impl_required : Warning<
|
||||
"property %0 requires method %1 to be defined - "
|
||||
"use @synthesize, @dynamic or provide a method implementation">;
|
||||
def warn_setter_getter_impl_required_in_category : Warning<
|
||||
"property %0 requires method %1 to be defined - "
|
||||
"use @dynamic or provide a method implementation in category">;
|
||||
def note_property_impl_required : Note<
|
||||
"implementation is here">;
|
||||
|
||||
|
|
|
@ -1101,6 +1101,17 @@ void Sema::CollectImmediateProperties(ObjCContainerDecl *CDecl,
|
|||
E = IDecl->protocol_end(); PI != E; ++PI)
|
||||
CollectImmediateProperties((*PI), PropMap);
|
||||
}
|
||||
if (ObjCCategoryDecl *CATDecl = dyn_cast<ObjCCategoryDecl>(CDecl)) {
|
||||
for (ObjCContainerDecl::prop_iterator P = CATDecl->prop_begin(),
|
||||
E = CATDecl->prop_end(); P != E; ++P) {
|
||||
ObjCPropertyDecl *Prop = (*P);
|
||||
PropMap[Prop->getIdentifier()] = Prop;
|
||||
}
|
||||
// scan through class's protocols.
|
||||
for (ObjCInterfaceDecl::protocol_iterator PI = CATDecl->protocol_begin(),
|
||||
E = CATDecl->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) {
|
||||
|
@ -1141,7 +1152,9 @@ void Sema::DiagnoseUnimplementedProperties(ObjCImplDecl* IMPDecl,
|
|||
|
||||
if (!InsMap.count(Prop->getGetterName())) {
|
||||
Diag(Prop->getLocation(),
|
||||
diag::warn_setter_getter_impl_required)
|
||||
isa<ObjCCategoryDecl>(CDecl) ?
|
||||
diag::warn_setter_getter_impl_required_in_category :
|
||||
diag::warn_setter_getter_impl_required)
|
||||
<< Prop->getDeclName() << Prop->getGetterName();
|
||||
Diag(IMPDecl->getLocation(),
|
||||
diag::note_property_impl_required);
|
||||
|
@ -1149,6 +1162,8 @@ void Sema::DiagnoseUnimplementedProperties(ObjCImplDecl* IMPDecl,
|
|||
|
||||
if (!Prop->isReadOnly() && !InsMap.count(Prop->getSetterName())) {
|
||||
Diag(Prop->getLocation(),
|
||||
isa<ObjCCategoryDecl>(CDecl) ?
|
||||
diag::warn_setter_getter_impl_required_in_category :
|
||||
diag::warn_setter_getter_impl_required)
|
||||
<< Prop->getDeclName() << Prop->getSetterName();
|
||||
Diag(IMPDecl->getLocation(),
|
||||
|
@ -1212,7 +1227,18 @@ void Sema::ImplMethodsVsClassMethods(ObjCImplDecl* IMPDecl,
|
|||
E = C->protocol_end(); PI != E; ++PI)
|
||||
CheckProtocolMethodDefs(IMPDecl->getLocation(), *PI, IncompleteImpl,
|
||||
InsMap, ClsMap, C->getClassInterface());
|
||||
}
|
||||
// Report unimplemented properties in the category as well.
|
||||
// When reporting on missing setter/getters, do not report when
|
||||
// setter/getter is implemented in category's primary class
|
||||
// implementation.
|
||||
if (ObjCInterfaceDecl *ID = C->getClassInterface())
|
||||
if (ObjCImplDecl *IMP = ID->getImplementation()) {
|
||||
for (ObjCImplementationDecl::instmeth_iterator
|
||||
I = IMP->instmeth_begin(), E = IMP->instmeth_end(); I!=E; ++I)
|
||||
InsMap.insert((*I)->getSelector());
|
||||
}
|
||||
DiagnoseUnimplementedProperties(IMPDecl, CDecl, InsMap);
|
||||
}
|
||||
} else
|
||||
assert(false && "invalid ObjCContainerDecl type.");
|
||||
}
|
||||
|
|
|
@ -4,7 +4,8 @@
|
|||
|
||||
@protocol MyProtocol
|
||||
@property float myFloat;
|
||||
@property float anotherFloat;
|
||||
@property float anotherFloat; // expected-warning {{property 'anotherFloat' requires method 'anotherFloat' to be defined - use @dynamic}} \
|
||||
// expected-warning {{property 'anotherFloat' requires method 'setAnotherFloat:' to be defined }}
|
||||
@end
|
||||
|
||||
@interface MyObject { float anotherFloat; }
|
||||
|
@ -13,7 +14,7 @@
|
|||
@interface MyObject (CAT) <MyProtocol>
|
||||
@end
|
||||
|
||||
@implementation MyObject (CAT)
|
||||
@implementation MyObject (CAT) // expected-note 2 {{implementation is here}}
|
||||
@dynamic myFloat; // OK
|
||||
@synthesize anotherFloat; // expected-error {{@synthesize not allowed in a category's implementation}}
|
||||
@end
|
||||
|
|
|
@ -0,0 +1,31 @@
|
|||
// RUN: %clang_cc1 -fsyntax-only -verify %s
|
||||
|
||||
/* This test is for categories which don't implement the accessors but some accessors are
|
||||
implemented in their base class implementation. In this case,no warning must be issued.
|
||||
*/
|
||||
|
||||
@interface MyClass
|
||||
{
|
||||
int _foo;
|
||||
}
|
||||
@property(readonly) int foo;
|
||||
@end
|
||||
|
||||
@implementation MyClass
|
||||
- (int) foo { return _foo; }
|
||||
@end
|
||||
|
||||
@interface MyClass (private)
|
||||
@property(readwrite) int foo;
|
||||
@end
|
||||
|
||||
@implementation MyClass (private)
|
||||
- (void) setFoo:(int)foo { _foo = foo; }
|
||||
@end
|
||||
|
||||
@interface MyClass (public)
|
||||
@property(readwrite) int foo; // expected-warning {{property 'foo' requires method 'setFoo:' to be defined }}
|
||||
@end
|
||||
|
||||
@implementation MyClass (public)// expected-note {{implementation is here}}
|
||||
@end
|
|
@ -11,7 +11,8 @@
|
|||
@end
|
||||
|
||||
@interface I(CAT)
|
||||
@property int d1;
|
||||
@property int d1; // expected-warning {{property 'd1' requires method 'd1' to be defined }} \
|
||||
// expected-warning {{property 'd1' requires method 'setD1:' to be defined }}
|
||||
@end
|
||||
|
||||
@implementation I
|
||||
|
@ -22,7 +23,7 @@
|
|||
@synthesize name; // OK! property with same name as an accessible ivar of same name
|
||||
@end
|
||||
|
||||
@implementation I(CAT)
|
||||
@implementation I(CAT) // expected-note 2 {{implementation is here}}
|
||||
@synthesize d1; // expected-error {{@synthesize not allowed in a category's implementation}}
|
||||
@dynamic bad; // expected-error {{property implementation must have its declaration in the category 'CAT'}}
|
||||
@end
|
||||
|
|
Загрузка…
Ссылка в новой задаче