diff options
author | Nicola Pero <nicola.pero@meta-innovation.com> | 2010-11-17 01:01:49 +0000 |
---|---|---|
committer | Nicola Pero <nicola@gcc.gnu.org> | 2010-11-17 01:01:49 +0000 |
commit | 354d8ce1084fadee6f9761fb6b1d1dd897b69ef4 (patch) | |
tree | c5e43cfa2e004941e7921046bb7a9dcefad68617 | |
parent | 109a508a0af670a6b7e927d73661d9412c31c2ef (diff) | |
download | gcc-354d8ce1084fadee6f9761fb6b1d1dd897b69ef4.zip gcc-354d8ce1084fadee6f9761fb6b1d1dd897b69ef4.tar.gz gcc-354d8ce1084fadee6f9761fb6b1d1dd897b69ef4.tar.bz2 |
In gcc/objc/: 2010-11-17 Nicola Pero <nicola.pero@meta-innovation.com>
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
-rw-r--r-- | gcc/objc/ChangeLog | 6 | ||||
-rw-r--r-- | gcc/objc/objc-act.c | 45 | ||||
-rw-r--r-- | gcc/testsuite/ChangeLog | 5 | ||||
-rw-r--r-- | gcc/testsuite/obj-c++.dg/protocol-optional-1.mm | 48 | ||||
-rw-r--r-- | gcc/testsuite/objc.dg/protocol-optional-1.m | 48 |
5 files changed, 138 insertions, 14 deletions
diff --git a/gcc/objc/ChangeLog b/gcc/objc/ChangeLog index 54f08a2..dd48148 100644 --- a/gcc/objc/ChangeLog +++ b/gcc/objc/ChangeLog @@ -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. diff --git a/gcc/objc/objc-act.c b/gcc/objc/objc-act.c index bfff1d2..96a3998 100644 --- a/gcc/objc/objc-act.c +++ b/gcc/objc/objc-act.c @@ -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); diff --git a/gcc/testsuite/ChangeLog b/gcc/testsuite/ChangeLog index 599a5f2..01c6cb1 100644 --- a/gcc/testsuite/ChangeLog +++ b/gcc/testsuite/ChangeLog @@ -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 index 0000000..bc4a3d0 --- /dev/null +++ b/gcc/testsuite/obj-c++.dg/protocol-optional-1.mm @@ -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 index 0000000..bc4a3d0 --- /dev/null +++ b/gcc/testsuite/objc.dg/protocol-optional-1.m @@ -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; +} |