From: Fariborz Jahanian Date: Sat, 27 Aug 2011 21:55:47 +0000 (+0000) Subject: objective-c - Make warning on unimplemented protocols point X-Git-Url: https://granicus.if.org/sourcecode?a=commitdiff_plain;h=b8607398a5e1e552f82a86d1d8c3a4031ac4c946;p=clang objective-c - Make warning on unimplemented protocols point to class implementation where it is supposed to be implemented. // rdar://10009982. git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@138714 91177308-0d34-0410-b5e6-96231b3b80d8 --- diff --git a/include/clang/Basic/DiagnosticSemaKinds.td b/include/clang/Basic/DiagnosticSemaKinds.td index 8b39c782f2..d5b3ac3ac3 100644 --- a/include/clang/Basic/DiagnosticSemaKinds.td +++ b/include/clang/Basic/DiagnosticSemaKinds.td @@ -3372,10 +3372,11 @@ def err_incomplete_type_objc_at_encode : Error< def warn_setter_getter_impl_required : Warning< "property %0 requires method %1 to be defined - " - "use @synthesize, @dynamic or provide a method implementation">; + "use @synthesize, @dynamic or provide a method implementation " + "in this class 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">; + "use @dynamic or provide a method implementation in this category">; def note_property_impl_required : Note< "implementation is here">; def note_parameter_named_here : Note< diff --git a/lib/Sema/SemaObjCProperty.cpp b/lib/Sema/SemaObjCProperty.cpp index 4b9cd66f96..f4743acec5 100644 --- a/lib/Sema/SemaObjCProperty.cpp +++ b/lib/Sema/SemaObjCProperty.cpp @@ -1316,23 +1316,23 @@ void Sema::DiagnoseUnimplementedProperties(Scope *S, ObjCImplDecl* IMPDecl, PropImplMap.count(Prop) || Prop->hasAttr()) continue; if (!InsMap.count(Prop->getGetterName())) { - Diag(Prop->getLocation(), + Diag(IMPDecl->getLocation(), isa(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); + Diag(Prop->getLocation(), + diag::note_property_declare); } if (!Prop->isReadOnly() && !InsMap.count(Prop->getSetterName())) { - Diag(Prop->getLocation(), + Diag(IMPDecl->getLocation(), isa(CDecl) ? diag::warn_setter_getter_impl_required_in_category : diag::warn_setter_getter_impl_required) << Prop->getDeclName() << Prop->getSetterName(); - Diag(IMPDecl->getLocation(), - diag::note_property_impl_required); + Diag(Prop->getLocation(), + diag::note_property_declare); } } } diff --git a/test/SemaObjC/default-synthesize.m b/test/SemaObjC/default-synthesize.m index 33e3bd6f34..c9454d2699 100644 --- a/test/SemaObjC/default-synthesize.m +++ b/test/SemaObjC/default-synthesize.m @@ -97,10 +97,10 @@ // rdar://7920807 @interface C @end @interface C (Category) -@property int p; // expected-warning {{property 'p' requires method 'p' to be defined }} \ - // expected-warning {{property 'p' requires method 'setP:' to be defined}} +@property int p; // expected-note 2 {{property declared here}} @end -@implementation C (Category) // expected-note 2 {{implementation is here}} +@implementation C (Category) // expected-warning {{property 'p' requires method 'p' to be defined}} \ + // expected-warning {{property 'p' requires method 'setP:' to be defined}} @end // Don't complain if a property is already @synthesized by usr. diff --git a/test/SemaObjC/property-category-1.m b/test/SemaObjC/property-category-1.m index 26e73136d0..6382826080 100644 --- a/test/SemaObjC/property-category-1.m +++ b/test/SemaObjC/property-category-1.m @@ -37,7 +37,7 @@ int main(int argc, char **argv) { /// @interface I0 -@property(readonly) int p0; // expected-warning {{property 'p0' requires method 'p0' to be defined}} +@property(readonly) int p0; // expected-note {{property declared here}} @end @interface I0 (Cat0) @@ -46,7 +46,7 @@ int main(int argc, char **argv) { @interface I0 (Cat1) @end -@implementation I0 // expected-note {{implementation is here}} +@implementation I0 // expected-warning {{property 'p0' requires method 'p0' to be define}} - (void) foo { self.p0 = 0; // expected-error {{assigning to property with 'readonly' attribute not allowed}} } diff --git a/test/SemaObjC/property-category-2.m b/test/SemaObjC/property-category-2.m index e63672bb0a..ecc368162b 100644 --- a/test/SemaObjC/property-category-2.m +++ b/test/SemaObjC/property-category-2.m @@ -4,8 +4,7 @@ @protocol MyProtocol @property float myFloat; -@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 }} +@property float anotherFloat; // expected-note 2 {{property declared}} @end @interface MyObject { float anotherFloat; } @@ -14,7 +13,8 @@ @interface MyObject (CAT) @end -@implementation MyObject (CAT) // expected-note 2 {{implementation is here}} +@implementation MyObject (CAT) // expected-warning {{property 'anotherFloat' requires method}} \ + // expected-warning {{property 'anotherFloat' requires method 'setAnotherFloat:'}} @dynamic myFloat; // OK @synthesize anotherFloat; // expected-error {{@synthesize not allowed in a category's implementation}} @end diff --git a/test/SemaObjC/property-category-impl.m b/test/SemaObjC/property-category-impl.m index 997949778c..21fdf1b6d4 100644 --- a/test/SemaObjC/property-category-impl.m +++ b/test/SemaObjC/property-category-impl.m @@ -24,8 +24,8 @@ @end @interface MyClass (public) -@property(readwrite) int foo; // expected-warning {{property 'foo' requires method 'setFoo:' to be defined }} +@property(readwrite) int foo; // expected-note {{property declared here}} @end -@implementation MyClass (public)// expected-note {{implementation is here}} +@implementation MyClass (public)// expected-warning {{property 'foo' requires method 'setFoo:' to be defined }} @end diff --git a/test/SemaObjC/property.m b/test/SemaObjC/property.m index 4d00bd2b52..62291bb98c 100644 --- a/test/SemaObjC/property.m +++ b/test/SemaObjC/property.m @@ -11,8 +11,7 @@ @end @interface I(CAT) -@property int d1; // expected-warning {{property 'd1' requires method 'd1' to be defined }} \ - // expected-warning {{property 'd1' requires method 'setD1:' to be defined }} +@property int d1; // expected-note 2 {{property declared here}} @end @implementation I @@ -23,7 +22,8 @@ @synthesize name; // OK! property with same name as an accessible ivar of same name @end -@implementation I(CAT) // expected-note 2 {{implementation is here}} +@implementation I(CAT) // expected-warning {{property 'd1' requires method 'd1' to be defined }} \ + // expected-warning {{property 'd1' requires method 'setD1:' to be defined }} @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 diff --git a/test/SemaObjC/super-class-protocol-conformance.m b/test/SemaObjC/super-class-protocol-conformance.m index bf19c837f4..32d5392ad4 100644 --- a/test/SemaObjC/super-class-protocol-conformance.m +++ b/test/SemaObjC/super-class-protocol-conformance.m @@ -4,7 +4,7 @@ @interface NSObject @end @protocol TopProtocol - @property (readonly) id myString; // expected-warning {{property 'myString' requires method 'myString' to be defined}} + @property (readonly) id myString; // expected-note {{property}} @end @protocol SubProtocol @@ -21,7 +21,7 @@ @implementation SubClass1 @end // Test1 - No Warning -@implementation TopClass // expected-note {{implementation is here}} +@implementation TopClass // expected-warning {{property 'myString' requires method 'myString' to be defined}} @end @implementation SubClass // Test3 - No Warning @@ -39,11 +39,11 @@ @implementation SubClass4 @end // Test 5 - No Warning @protocol NewProtocol - @property (readonly) id myNewString; // expected-warning {{property 'myNewString' requires method 'myNewString' to be defined}} + @property (readonly) id myNewString; // expected-note {{property}} @end @interface SubClass5 : SubClass4 @end -@implementation SubClass5 @end // expected-note {{implementation is here}} +@implementation SubClass5 @end // expected-warning {{property 'myNewString' requires method 'myNewString' to be defined}} // Radar 8035776 @@ -54,10 +54,10 @@ @end @protocol ProtocolWithProperty -@property (readonly, assign) id invalidationBacktrace; // expected-warning {{property 'invalidationBacktrace' requires method 'invalidationBacktrace' to be defined}} +@property (readonly, assign) id invalidationBacktrace; // expected-note {{property}} @end @interface INTF : Super @end -@implementation INTF @end // expected-note {{implementation is here}} +@implementation INTF @end // expected-warning{{property 'invalidationBacktrace' requires method 'invalidationBacktrace' to be defined}} diff --git a/test/SemaObjC/unimplemented-protocol-prop.m b/test/SemaObjC/unimplemented-protocol-prop.m index d3de50efea..0805202c5e 100644 --- a/test/SemaObjC/unimplemented-protocol-prop.m +++ b/test/SemaObjC/unimplemented-protocol-prop.m @@ -2,14 +2,12 @@ @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}} +@property float MyProperty0; // expected-note 2 {{property declared}} @end @protocol PROTOCOL @required -@property float MyProperty; // expected-warning {{property 'MyProperty' requires method 'MyProperty' to be defined}} \ - // expected-warning {{property 'MyProperty' requires method 'setMyProperty:' to be defined}} +@property float MyProperty; // expected-note 2 {{property declared}} @optional @property float OptMyProperty; @end @@ -17,4 +15,7 @@ @interface I @end -@implementation I @end // expected-note 4 {{implementation is here}} +@implementation I @end // expected-warning {{property 'MyProperty0' requires method 'MyProperty0' to be defined}} \ + // expected-warning {{property 'MyProperty0' requires method 'setMyProperty0:' to be defined}}\ + // expected-warning {{property 'MyProperty' requires method 'MyProperty' to be defined}} \ + // expected-warning {{property 'MyProperty' requires method 'setMyProperty:' to be defined}}