In gcc/objc/: 2010-11-17 Nicola Pero <nicola.pero@meta-innovation.com>
authorNicola Pero <nicola.pero@meta-innovation.com>
Wed, 17 Nov 2010 01:01:49 +0000 (01:01 +0000)
committerNicola Pero <nicola@gcc.gnu.org>
Wed, 17 Nov 2010 01:01:49 +0000 (01:01 +0000)
In gcc/objc/:
2010-11-17  Nicola Pero  <nicola.pero@meta-innovation.com>

        * objc-act.c (lookup_method_in_protocol_list): Search methods in
        PROTOCOL_OPTIONAL_CLS_METHODS / PROTOCOL_OPTIONAL_NST_METHODS if
        they are not found in PROTOCOL_CLS_METHODS / PROTOCOL_NST_METHODS.

In gcc/testsuite/:
2010-11-17  Nicola Pero  <nicola.pero@meta-innovation.com>

        * objc.dg/protocol-optional-1.m: New.
        * obj-c++.dg/protocol-optional-1.mm: New.

From-SVN: r166847

gcc/objc/ChangeLog
gcc/objc/objc-act.c
gcc/testsuite/ChangeLog
gcc/testsuite/obj-c++.dg/protocol-optional-1.mm [new file with mode: 0644]
gcc/testsuite/objc.dg/protocol-optional-1.m [new file with mode: 0644]

index 54f08a250bffce09bb5bd43f0424e3970aa9ba5d..dd4814891a720473b158d9136a292e320f2bbad7 100644 (file)
@@ -1,3 +1,9 @@
+2010-11-17  Nicola Pero  <nicola.pero@meta-innovation.com>
+
+       * objc-act.c (lookup_method_in_protocol_list): Search methods in
+       PROTOCOL_OPTIONAL_CLS_METHODS / PROTOCOL_OPTIONAL_NST_METHODS if
+       they are not found in PROTOCOL_CLS_METHODS / PROTOCOL_NST_METHODS.
+
 2010-11-15  Nicola Pero  <nicola.pero@meta-innovation.com>
 
        * objc-act.c (objc_build_setter_call): New.
index bfff1d2f110eb347f17e1338fe86cc6091656a48..96a3998221a72f0080ffeeb4b273a0cf38e2a400 100644 (file)
@@ -649,30 +649,44 @@ static tree
 lookup_method_in_protocol_list (tree rproto_list, tree sel_name,
                                int is_class)
 {
-   tree rproto, p;
-   tree fnd = 0;
+  tree rproto, p, m;
 
    for (rproto = rproto_list; rproto; rproto = TREE_CHAIN (rproto))
      {
-        p = TREE_VALUE (rproto);
+       p = TREE_VALUE (rproto);
+       m = NULL_TREE;
 
        if (TREE_CODE (p) == PROTOCOL_INTERFACE_TYPE)
          {
-           if ((fnd = lookup_method (is_class
-                                     ? PROTOCOL_CLS_METHODS (p)
-                                     : PROTOCOL_NST_METHODS (p), sel_name)))
-             ;
-           else if (PROTOCOL_LIST (p))
-             fnd = lookup_method_in_protocol_list (PROTOCOL_LIST (p),
-                                                   sel_name, is_class);
+           /* First, search the @required protocol methods.  */
+           if (is_class)
+             m = lookup_method (PROTOCOL_CLS_METHODS (p),  sel_name);
+           else
+             m = lookup_method (PROTOCOL_NST_METHODS (p), sel_name);
+
+           if (m)
+             return m;
+
+           /* If still not found, search the @optional protocol methods.  */
+           if (is_class)
+             m = lookup_method (PROTOCOL_OPTIONAL_CLS_METHODS (p), sel_name);
+           else
+             m = lookup_method (PROTOCOL_OPTIONAL_NST_METHODS (p), sel_name);
+
+           if (m)
+             return m;
+
+           /* If still not found, search the attached protocols.  */
+           if (PROTOCOL_LIST (p))
+             m = lookup_method_in_protocol_list (PROTOCOL_LIST (p),
+                                                 sel_name, is_class);
+           if (m)
+             return m;
          }
        else
           {
            ; /* An identifier...if we could not find a protocol.  */
           }
-
-       if (fnd)
-         return fnd;
      }
 
    return 0;
@@ -8642,7 +8656,10 @@ objc_add_method (tree klass, tree method, int is_class, bool is_optional)
 {
   tree mth;
 
-  /* @optional methods are added to protocol's OPTIONAL list */
+  /* @optional methods are added to protocol's OPTIONAL list.  Note
+     that this disables checking that the methods are implemented by
+     classes implementing the protocol, since these checks only use
+     the CLASS_CLS_METHODS and CLASS_NST_METHODS.  */
   if (is_optional)
     {
       gcc_assert (TREE_CODE (klass) == PROTOCOL_INTERFACE_TYPE);
index 599a5f2f16ab573dd822aa85d8afd9884f70735a..01c6cb189c2bfde5da6e42cb54b42d02e15822f3 100644 (file)
@@ -1,3 +1,8 @@
+2010-11-17  Nicola Pero  <nicola.pero@meta-innovation.com>
+
+       * objc.dg/protocol-optional-1.m: New.
+       * obj-c++.dg/protocol-optional-1.mm: New.
+
 2010-11-16  Richard Henderson  <rth@redhat.com>
 
        * gcc.target/powerpc/ppc-fma-2.c: Use -ffp-contract=off.
diff --git a/gcc/testsuite/obj-c++.dg/protocol-optional-1.mm b/gcc/testsuite/obj-c++.dg/protocol-optional-1.mm
new file mode 100644 (file)
index 0000000..bc4a3d0
--- /dev/null
@@ -0,0 +1,48 @@
+/* Contributed by Nicola Pero <nicola.pero@meta-innovation.com>, November 2010.  */
+/* { dg-do compile } */
+
+#include <objc/objc.h>
+
+/* Test that @optional for @protocol works.  */
+
+@protocol MyProtocol
++ (int)classMethod;
+- (int)method;
+@optional
++ (int)optionalClassMethod;
+- (int)optionalMethod;
+@end
+
+@interface MyRootClass <MyProtocol>
+@end
+
+/* The implementation implements both the @required methods, but none
+   of the @optional ones.  There should be no warnings as the
+   @optional methods are optional. ;-)  */
+@implementation MyRootClass
++ (int)classMethod
+{
+  return 20;
+}
+- (int)method
+{
+  return 11;
+}
+@end
+
+int function (id <MyProtocol> object1,
+             MyRootClass *object2)
+{
+  /* Test that there are no warnings if you try to use an @optional
+     method with an object of the class.  */
+  int i = 0;
+
+  i += [object1 method];
+  i += [object2 method];
+  i += [MyRootClass classMethod];
+  i += [object1 optionalMethod];
+  i += [object2 optionalMethod];
+  i += [MyRootClass optionalClassMethod];
+
+  return i;
+}
diff --git a/gcc/testsuite/objc.dg/protocol-optional-1.m b/gcc/testsuite/objc.dg/protocol-optional-1.m
new file mode 100644 (file)
index 0000000..bc4a3d0
--- /dev/null
@@ -0,0 +1,48 @@
+/* Contributed by Nicola Pero <nicola.pero@meta-innovation.com>, November 2010.  */
+/* { dg-do compile } */
+
+#include <objc/objc.h>
+
+/* Test that @optional for @protocol works.  */
+
+@protocol MyProtocol
++ (int)classMethod;
+- (int)method;
+@optional
++ (int)optionalClassMethod;
+- (int)optionalMethod;
+@end
+
+@interface MyRootClass <MyProtocol>
+@end
+
+/* The implementation implements both the @required methods, but none
+   of the @optional ones.  There should be no warnings as the
+   @optional methods are optional. ;-)  */
+@implementation MyRootClass
++ (int)classMethod
+{
+  return 20;
+}
+- (int)method
+{
+  return 11;
+}
+@end
+
+int function (id <MyProtocol> object1,
+             MyRootClass *object2)
+{
+  /* Test that there are no warnings if you try to use an @optional
+     method with an object of the class.  */
+  int i = 0;
+
+  i += [object1 method];
+  i += [object2 method];
+  i += [MyRootClass classMethod];
+  i += [object1 optionalMethod];
+  i += [object2 optionalMethod];
+  i += [MyRootClass optionalClassMethod];
+
+  return i;
+}