[cfe-commits] r94014 - in /cfe/trunk: include/clang/Basic/DiagnosticSemaKinds.td lib/Sema/SemaDeclObjC.cpp test/SemaObjC/property-category-2.m test/SemaObjC/property-category-impl.m test/SemaObjC/property.m
Fariborz Jahanian
fjahanian at apple.com
Wed Jan 20 11:36:21 PST 2010
Author: fjahanian
Date: Wed Jan 20 13:36:21 2010
New Revision: 94014
URL: http://llvm.org/viewvc/llvm-project?rev=94014&view=rev
Log:
Settled rule on warning on unimplemented property in
category implementation when some implementations
are missing in the primary class implementation.
(fixes radar 6505200).
Added:
cfe/trunk/test/SemaObjC/property-category-impl.m
Modified:
cfe/trunk/include/clang/Basic/DiagnosticSemaKinds.td
cfe/trunk/lib/Sema/SemaDeclObjC.cpp
cfe/trunk/test/SemaObjC/property-category-2.m
cfe/trunk/test/SemaObjC/property.m
Modified: cfe/trunk/include/clang/Basic/DiagnosticSemaKinds.td
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/include/clang/Basic/DiagnosticSemaKinds.td?rev=94014&r1=94013&r2=94014&view=diff
==============================================================================
--- cfe/trunk/include/clang/Basic/DiagnosticSemaKinds.td (original)
+++ cfe/trunk/include/clang/Basic/DiagnosticSemaKinds.td Wed Jan 20 13:36:21 2010
@@ -1840,6 +1840,9 @@
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">;
Modified: cfe/trunk/lib/Sema/SemaDeclObjC.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/Sema/SemaDeclObjC.cpp?rev=94014&r1=94013&r2=94014&view=diff
==============================================================================
--- cfe/trunk/lib/Sema/SemaDeclObjC.cpp (original)
+++ cfe/trunk/lib/Sema/SemaDeclObjC.cpp Wed Jan 20 13:36:21 2010
@@ -1101,6 +1101,17 @@
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 @@
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 @@
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 @@
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.");
}
Modified: cfe/trunk/test/SemaObjC/property-category-2.m
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/test/SemaObjC/property-category-2.m?rev=94014&r1=94013&r2=94014&view=diff
==============================================================================
--- cfe/trunk/test/SemaObjC/property-category-2.m (original)
+++ cfe/trunk/test/SemaObjC/property-category-2.m Wed Jan 20 13:36:21 2010
@@ -4,7 +4,8 @@
@protocol MyProtocol
@property float myFloat;
- at property float anotherFloat;
+ at 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
- at implementation MyObject (CAT)
+ at 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
Added: cfe/trunk/test/SemaObjC/property-category-impl.m
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/test/SemaObjC/property-category-impl.m?rev=94014&view=auto
==============================================================================
--- cfe/trunk/test/SemaObjC/property-category-impl.m (added)
+++ cfe/trunk/test/SemaObjC/property-category-impl.m Wed Jan 20 13:36:21 2010
@@ -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.
+*/
+
+ at interface MyClass
+{
+ int _foo;
+}
+ at property(readonly) int foo;
+ at end
+
+ at implementation MyClass
+- (int) foo { return _foo; }
+ at end
+
+ at interface MyClass (private)
+ at property(readwrite) int foo;
+ at end
+
+ at implementation MyClass (private)
+- (void) setFoo:(int)foo { _foo = foo; }
+ at end
+
+ at interface MyClass (public)
+ at property(readwrite) int foo; // expected-warning {{property 'foo' requires method 'setFoo:' to be defined }}
+ at end
+
+ at implementation MyClass (public)// expected-note {{implementation is here}}
+ at end
Modified: cfe/trunk/test/SemaObjC/property.m
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/test/SemaObjC/property.m?rev=94014&r1=94013&r2=94014&view=diff
==============================================================================
--- cfe/trunk/test/SemaObjC/property.m (original)
+++ cfe/trunk/test/SemaObjC/property.m Wed Jan 20 13:36:21 2010
@@ -11,7 +11,8 @@
@end
@interface I(CAT)
- at property int d1;
+ at 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
- at implementation I(CAT)
+ at 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
More information about the cfe-commits
mailing list