]> granicus.if.org Git - clang/commitdiff
Objective-C: This is a small modification to my
authorFariborz Jahanian <fjahanian@apple.com>
Thu, 25 Apr 2013 21:59:34 +0000 (21:59 +0000)
committerFariborz Jahanian <fjahanian@apple.com>
Thu, 25 Apr 2013 21:59:34 +0000 (21:59 +0000)
patch -n r180198.
When reporting on missing property accessor implementation in
categories, do not report when they are declared in primary class,
class's protocol, or one of it super classes or in of the other
categories. // rdar://13713098

git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@180580 91177308-0d34-0410-b5e6-96231b3b80d8

include/clang/AST/DeclObjC.h
lib/AST/DeclObjC.cpp
lib/Sema/SemaObjCProperty.cpp
test/SemaObjC/property-category-4.m
test/SemaObjC/property-category-impl.m

index 86cf7fc5aff95152e92a842384e0b5647c32febb..b9cb11d678357a353258120eb3c51f1bb20912f4 100644 (file)
@@ -1137,7 +1137,7 @@ public:
   // found, we search referenced protocols and class categories.
   ObjCMethodDecl *lookupMethod(Selector Sel, bool isInstance,
                                bool shallowCategoryLookup= false,
-                               bool CategoryLookup= true) const;
+                               const ObjCCategoryDecl *C= 0) const;
   ObjCMethodDecl *lookupInstanceMethod(Selector Sel,
                             bool shallowCategoryLookup = false) const {
     return lookupMethod(Sel, true/*isInstance*/, shallowCategoryLookup);
@@ -1156,15 +1156,15 @@ public:
     return lookupPrivateMethod(Sel, false);
   }
 
-  /// \brief Lookup a setter or getter in the class hierarchy.
-  /// In this lookup, only class hierarchy and not its categories
-  /// are looked up
-  ObjCMethodDecl *lookupPropertyAccessor(const Selector Sel) const {
-     return lookupMethod(Sel, true/*isInstance*/,
-                         false /*shallowCategoryLookup*/,
-                         false /*CategoryLookup*/);
+  /// \brief Lookup a setter or getter in the class hierarchy,
+  /// including in all categories except for category passed
+  /// as argument.
+  ObjCMethodDecl *lookupPropertyAccessor(const Selector Sel,
+                                         const ObjCCategoryDecl *Cat) const {
+    return lookupMethod(Sel, true/*isInstance*/,
+                        false/*shallowCategoryLookup*/, Cat);
   }
-
+                          
   SourceLocation getEndOfDefinitionLoc() const { 
     if (!hasDefinition())
       return getLocation();
index 43a128137be04fab0d2d258a6308774f6eb4dafa..ad09afe269401286174e94ad1f07c62a787f9226 100644 (file)
@@ -443,10 +443,12 @@ ObjCInterfaceDecl *ObjCInterfaceDecl::lookupInheritedClass(
 
 /// lookupMethod - This method returns an instance/class method by looking in
 /// the class, its categories, and its super classes (using a linear search).
+/// When argument category "C" is specified, any implicit method found
+/// in this category is ignored.
 ObjCMethodDecl *ObjCInterfaceDecl::lookupMethod(Selector Sel, 
                                      bool isInstance,
                                      bool shallowCategoryLookup,
-                                     bool CategoryLookup) const {
+                                     const ObjCCategoryDecl *C) const {
   // FIXME: Should make sure no callers ever do this.
   if (!hasDefinition())
     return 0;
@@ -469,24 +471,25 @@ ObjCMethodDecl *ObjCInterfaceDecl::lookupMethod(Selector Sel,
         return MethodDecl;
     
     // Didn't find one yet - now look through categories.
-    if (CategoryLookup)
-      for (ObjCInterfaceDecl::visible_categories_iterator
-           Cat = ClassDecl->visible_categories_begin(),
-           CatEnd = ClassDecl->visible_categories_end();
-           Cat != CatEnd; ++Cat) {
-        if ((MethodDecl = Cat->getMethod(Sel, isInstance)))
+    for (ObjCInterfaceDecl::visible_categories_iterator
+         Cat = ClassDecl->visible_categories_begin(),
+         CatEnd = ClassDecl->visible_categories_end();
+         Cat != CatEnd; ++Cat) {
+      if ((MethodDecl = Cat->getMethod(Sel, isInstance)))
+        if (C != (*Cat) || !MethodDecl->isImplicit())
           return MethodDecl;
 
-        if (!shallowCategoryLookup) {
-          // Didn't find one yet - look through protocols.
-          const ObjCList<ObjCProtocolDecl> &Protocols =
-            Cat->getReferencedProtocols();
-          for (ObjCList<ObjCProtocolDecl>::iterator I = Protocols.begin(),
-               E = Protocols.end(); I != E; ++I)
-            if ((MethodDecl = (*I)->lookupMethod(Sel, isInstance)))
+      if (!shallowCategoryLookup) {
+        // Didn't find one yet - look through protocols.
+        const ObjCList<ObjCProtocolDecl> &Protocols =
+        Cat->getReferencedProtocols();
+        for (ObjCList<ObjCProtocolDecl>::iterator I = Protocols.begin(),
+             E = Protocols.end(); I != E; ++I)
+          if ((MethodDecl = (*I)->lookupMethod(Sel, isInstance)))
+            if (C != (*Cat) || !MethodDecl->isImplicit())
               return MethodDecl;
-        }
       }
+    }
   
     ClassDecl = ClassDecl->getSuperClass();
   }
index 2162bf06e995ea76cb73996ada93cd6fcb3e42ef..19a369ff9df5ccdedadb3f5a8bccf84eecbadf74 100644 (file)
@@ -1726,7 +1726,7 @@ void Sema::DiagnoseUnimplementedProperties(Scope *S, ObjCImplDecl* IMPDecl,
     // the class is going to implement them.
     if (!InsMap.count(Prop->getGetterName()) &&
         (PrimaryClass == 0 ||
-         !PrimaryClass->lookupPropertyAccessor(Prop->getGetterName()))) {
+         !PrimaryClass->lookupPropertyAccessor(Prop->getGetterName(), C))) {
       Diag(IMPDecl->getLocation(),
            isa<ObjCCategoryDecl>(CDecl) ?
             diag::warn_setter_getter_impl_required_in_category :
@@ -1746,7 +1746,7 @@ void Sema::DiagnoseUnimplementedProperties(Scope *S, ObjCImplDecl* IMPDecl,
     // the class is going to implement them.
     if (!Prop->isReadOnly() && !InsMap.count(Prop->getSetterName()) &&
         (PrimaryClass == 0 ||
-         !PrimaryClass->lookupPropertyAccessor(Prop->getSetterName()))) {
+         !PrimaryClass->lookupPropertyAccessor(Prop->getSetterName(), C))) {
       Diag(IMPDecl->getLocation(),
            isa<ObjCCategoryDecl>(CDecl) ?
            diag::warn_setter_getter_impl_required_in_category :
index f99bd52998c2015fa874aca453b1a78904ea323a..ccf5e9b2a86fca139eeb39137217bb0bca9af9c2 100644 (file)
 
 @implementation I(CAT)
 @end
+
+// Test5 
+@interface C @end
+
+@interface C (CAT)
+- (int) p;
+@end
+
+
+@interface C (Category)
+@property (readonly) int p;  // no warning for this property - a getter is declared in another category
+@property (readonly) int p1; // expected-note {{property declared here}}
+@property (readonly) int p2;  // no warning for this property - a getter is declared in this category
+- (int) p2;
+@end
+
+@implementation C (Category)  // expected-warning {{property 'p1' requires method 'p1' to be defined - use @dynamic or provide a method implementation in this category}}
+@end
+
+// Test6
+@protocol MyProtocol
+@property (readonly) float  anotherFloat; // expected-note {{property declared here}}
+@property (readonly) float  Float; // no warning for this property - a getter is declared in this protocol
+- (float) Float;
+@end
+
+@interface MyObject 
+{ float anotherFloat; }
+@end
+
+@interface MyObject (CAT) <MyProtocol>
+@end
+
+@implementation MyObject (CAT) // expected-warning {{property 'anotherFloat' requires method 'anotherFloat' to be defined - use @dynamic or provide a method implementation in this category}}
+@end
+
index be42deaf909e22da3f45cd222a0c426ee2401bd0..135b0057618f5e87997b24bd9afbf393b063bf7c 100644 (file)
@@ -1,4 +1,5 @@
 // RUN: %clang_cc1 -fsyntax-only -verify -Wno-objc-root-class %s
+// expected-no-diagnostics
 
 /* 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.
 @end
 
 @interface MyClass (public)
-@property(readwrite)    int        foo;        // expected-note {{property declared here}}
+@property(readwrite)    int        foo;        
 @end
 
-@implementation MyClass (public)// expected-warning {{property 'foo' requires method 'setFoo:' to be defined }}
+@implementation MyClass (public)
 @end 
 
 // rdar://12568064