+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.
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;
{
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);
+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.
--- /dev/null
+/* 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;
+}
--- /dev/null
+/* 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;
+}