This is the mail archive of the gcc-patches@gcc.gnu.org mailing list for the GCC project.
Index Nav: | [Date Index] [Subject Index] [Author Index] [Thread Index] | |
---|---|---|
Message Nav: | [Date Prev] [Date Next] | [Thread Prev] [Thread Next] |
Other format: | [Raw text] |
David Ayers wrote: > > OK, this has been bubble strapped and regtested for ObjC on > i686-pc-linux-gnu after bootstrap of cvs today. I'll run a full > bootstrap of c,objc,c++ tonight and regtest everything again tomorrow. > Hmm. seems the files got truncated somehow. Let's try again... Cheers, David
2004-09-28 David Ayers <d.ayers@inode.at> * c-common.h: Remove RID_ID. * c-parse.in: Remove OBJECTNAME and references to RID_ID. (typespec_reserved_attr): Add rule for TYPENAME non_empty_protocolrefs. (yylexname) Remove special handling of RID_ID. * objc/objc-act.h (PROTOCOL_DECLARED_BY_ROOT): New macro. (IS_PROTOCOL_QUALIFIED_CLASS): Likewise. * objc/objc-act.c (mark_protocols_declared_by_root_class) (instance_prototype_of_root_protocol) (objc_comptypes_proto_proto): Add new functions. (objc_finish_interface): Register instance prototypes as class prototypes if the interface context is a protocol which has previously been referenced by a root class. (objc_comptypes): Handle protocol qualified class types. (objc_get_protocol_qualified_type): Report error for unknown types with protocol qualifiers. Update documentation. (objc_finish_message_expr): Extend prototype search for protocol qualified class types. (start_class): Call mark_protocols_declared_by_root_class if processing a root class with protocol references. (lookup_and_install_protocols): Update documentation.
2004-09-28 David Ayers <d.ayers@inode.at> * objc.dg/class-protocol-1.m: New test.
Index: gcc/c-common.h =================================================================== RCS file: /cvsroot/gcc/gcc/gcc/c-common.h,v retrieving revision 1.264 diff -u -r1.264 c-common.h --- gcc/c-common.h 10 Sep 2004 23:56:18 -0000 1.264 +++ gcc/c-common.h 28 Sep 2004 18:23:00 -0000 @@ -92,7 +92,7 @@ RID_CONSTCAST, RID_DYNCAST, RID_REINTCAST, RID_STATCAST, /* Objective-C */ - RID_ID, RID_AT_ENCODE, RID_AT_END, + RID_AT_ENCODE, RID_AT_END, RID_AT_CLASS, RID_AT_ALIAS, RID_AT_DEFS, RID_AT_PRIVATE, RID_AT_PROTECTED, RID_AT_PUBLIC, RID_AT_PROTOCOL, RID_AT_SELECTOR, Index: gcc/c-parse.in =================================================================== RCS file: /cvsroot/gcc/gcc/gcc/c-parse.in,v retrieving revision 1.242 diff -u -r1.242 c-parse.in --- gcc/c-parse.in 17 Sep 2004 18:17:59 -0000 1.242 +++ gcc/c-parse.in 28 Sep 2004 18:23:01 -0000 @@ -180,7 +180,7 @@ Objective C, so that the token codes are the same in both. */ %token AT_INTERFACE AT_IMPLEMENTATION AT_END AT_SELECTOR AT_DEFS AT_ENCODE %token CLASSNAME AT_PUBLIC AT_PRIVATE AT_PROTECTED AT_PROTOCOL -%token OBJECTNAME AT_CLASS AT_ALIAS +%token AT_CLASS AT_ALIAS %token AT_THROW AT_TRY AT_CATCH AT_FINALLY AT_SYNCHRONIZED %token OBJC_STRING @@ -261,7 +261,7 @@ %type <ttype> selectorarg keywordnamelist keywordname objcencodeexpr %type <ttype> non_empty_protocolrefs protocolrefs identifier_list objcprotocolexpr -%type <ttype> CLASSNAME OBJECTNAME OBJC_STRING OBJC_TYPE_QUAL +%type <ttype> CLASSNAME OBJC_STRING OBJC_TYPE_QUAL %type <ttype> superclass objc_quals objc_qual objc_typename %type <itype> objc_try_catch_stmt optellipsis @@ -474,7 +474,6 @@ IDENTIFIER | TYPENAME @@ifobjc - | OBJECTNAME | CLASSNAME @@end_ifobjc ; @@ -1274,7 +1273,7 @@ @@ifobjc | CLASSNAME protocolrefs { $$ = objc_get_protocol_qualified_type ($1, $2); } - | OBJECTNAME protocolrefs + | TYPENAME non_empty_protocolrefs { $$ = objc_get_protocol_qualified_type ($1, $2); } /* Make "<SomeProtocol>" equivalent to "id <SomeProtocol>" @@ -1549,10 +1548,6 @@ { $$ = make_pointer_declarator ($2, $3); } | TYPENAME { $$ = build_id_declarator ($1); } -@@ifobjc - | OBJECTNAME - { $$ = build_id_declarator ($1); } -@@end_ifobjc ; /* Kinds of declarator that can appear in a parameter list @@ -1571,10 +1566,6 @@ { $$ = set_array_declarator_inner ($2, $1, false); } | TYPENAME { $$ = build_id_declarator ($1); } -@@ifobjc - | OBJECTNAME - { $$ = build_id_declarator ($1); } -@@end_ifobjc ; parm_declarator_nostarttypename: @@ -2861,7 +2852,6 @@ IDENTIFIER | TYPENAME | CLASSNAME - | OBJECTNAME | reservedwords ; @@ -3127,7 +3117,6 @@ { "while", RID_WHILE, 0 }, @@ifobjc - { "id", RID_ID, D_OBJC }, /* These objc keywords are recognized only immediately after an '@'. */ @@ -3273,7 +3262,6 @@ /* RID_STATCAST */ 0, /* Objective C */ - /* RID_ID */ OBJECTNAME, /* RID_AT_ENCODE */ AT_ENCODE, /* RID_AT_END */ AT_END, /* RID_AT_CLASS */ AT_CLASS, @@ -3342,15 +3330,6 @@ enum rid rid_code = C_RID_CODE (yylval.ttype); @@ifobjc - /* Turn non-typedefed refs to "id" into plain identifiers; this - allows constructs like "void foo(id id);" to work. */ - if (rid_code == RID_ID) - { - decl = lookup_name (yylval.ttype); - if (decl == NULL_TREE || TREE_CODE (decl) != TYPE_DECL) - return IDENTIFIER; - } - if (!OBJC_IS_AT_KEYWORD (rid_code) && (!OBJC_IS_PQ_KEYWORD (rid_code) || objc_pq_context)) @@end_ifobjc @@ -3513,7 +3492,6 @@ { case IDENTIFIER: case TYPENAME: - case OBJECTNAME: case TYPESPEC: case TYPE_QUAL: case SCSPEC: Index: gcc/objc/objc-act.c =================================================================== RCS file: /cvsroot/gcc/gcc/gcc/objc/objc-act.c,v retrieving revision 1.248 diff -u -r1.248 objc-act.c --- gcc/objc/objc-act.c 24 Sep 2004 23:15:33 -0000 1.248 +++ gcc/objc/objc-act.c 28 Sep 2004 18:23:05 -0000 @@ -236,6 +236,8 @@ static tree lookup_protocol (tree); static void check_protocol_recursively (tree, tree); static tree lookup_and_install_protocols (tree); +static void mark_protocols_declared_by_root_class (tree, int); +static tree instance_prototype_of_root_protocol (tree, tree, int); /* Type encoding. */ @@ -712,6 +714,28 @@ objc_finish_interface (void) { finish_class (objc_interface_context); + + if (TREE_CODE (objc_interface_context) == PROTOCOL_INTERFACE_TYPE + && PROTOCOL_DECLARED_BY_ROOT (objc_interface_context)) + { + tree protocol = objc_interface_context; + tree method_decl; + + /* Since we do not have a protocol list, + go ahead and register the method list directly. */ + for (method_decl = PROTOCOL_NST_METHODS (protocol); + method_decl; + method_decl = TREE_CHAIN (method_decl)) + { + add_method_to_hash_list(cls_method_hash_list, method_decl); + } + + /* This protocol is marked. Now insure that that all instance + prototypes of inherited protocols get registered as class + methods without marking them. */ + mark_protocols_declared_by_root_class (PROTOCOL_LIST (protocol), 1); + } + objc_interface_context = NULL_TREE; } @@ -836,6 +860,84 @@ } /* Return 1 if LHS and RHS are compatible types for assignment or + various other operations. Return 0 if they are incompatible. + When the operation is REFLEXIVE (typically comparisons), check + for compatibility in either direction; when it's not (typically + assignments), don't. + + This is ja helper function for objc_comptypes to be able to test + two protocol qualified types of the same basic type to insure + protocol conformance and to emit the necessary warnings. +*/ + +static inline +int objc_comptypes_proto_proto(tree lhs, tree rhs, int reflexive) +{ + tree lproto, lproto_list = TYPE_PROTOCOL_LIST (lhs); + tree rproto, rproto_list = TYPE_PROTOCOL_LIST (rhs); + tree p; + + gcc_assert((IS_ID (lhs) && IS_ID (rhs)) + || (IS_CLASS (lhs) && IS_CLASS (rhs))); + + if (!reflexive) + { + /* An assignment between two objects both either of type 'id <Protocol>' + or both 'Class <Protocol>; make sure the protocol on the lhs is + supported by the object on the rhs. */ + for (lproto = lproto_list; lproto; + lproto = TREE_CHAIN (lproto)) + { + p = TREE_VALUE (lproto); + rproto = lookup_protocol_in_reflist (rproto_list, p); + + if (!rproto) + warning + ("%s does not conform to the `%s' protocol", + IS_ID(lhs) ? "object" : "class", + IDENTIFIER_POINTER (PROTOCOL_NAME (p))); + } + return 1; + } + else + { + /* Obscure case - a comparison between two objects either both + of type 'id <Protocol>' or both 'Class <protocol>'. Check + that either the protocol on the lhs is supported by the object on + the rhs, or viceversa. */ + + /* Check if the protocol on the lhs is supported by the + object on the rhs. */ + for (lproto = lproto_list; lproto; + lproto = TREE_CHAIN (lproto)) + { + p = TREE_VALUE (lproto); + rproto = lookup_protocol_in_reflist (rproto_list, p); + + if (!rproto) + { + /* Check failed - check if the protocol on the rhs + is supported by the object on the lhs. */ + for (rproto = rproto_list; rproto; + rproto = TREE_CHAIN (rproto)) + { + p = TREE_VALUE (rproto); + lproto = lookup_protocol_in_reflist (lproto_list, p); + + if (!lproto) + { + /* This check failed too: incompatible */ + return 0; + } + } + return 1; + } + } + return 1; + } +} + +/* Return 1 if LHS and RHS are compatible types for assignment or various other operations. Return 0 if they are incompatible, and return -1 if we choose to not decide (because the types are really just C types, not ObjC specific ones). When the operation is @@ -866,76 +968,21 @@ && TREE_CODE (rhs) == POINTER_TYPE && TREE_CODE (TREE_TYPE (rhs)) == RECORD_TYPE) { - int lhs_is_proto = IS_PROTOCOL_QUALIFIED_ID (lhs); - int rhs_is_proto = IS_PROTOCOL_QUALIFIED_ID (rhs); + int lhs_is_proto_id = IS_PROTOCOL_QUALIFIED_ID (lhs); + int rhs_is_proto_id = IS_PROTOCOL_QUALIFIED_ID (rhs); + int lhs_is_proto_class = IS_PROTOCOL_QUALIFIED_CLASS (lhs); + int rhs_is_proto_class = IS_PROTOCOL_QUALIFIED_CLASS (rhs); - if (lhs_is_proto) + if (lhs_is_proto_id) { tree lproto, lproto_list = TYPE_PROTOCOL_LIST (lhs); tree rproto, rproto_list; tree p; /* <Protocol> = <Protocol> */ - if (rhs_is_proto) - { - rproto_list = TYPE_PROTOCOL_LIST (rhs); - - if (!reflexive) - { - /* An assignment between objects of type 'id - <Protocol>'; make sure the protocol on the lhs is - supported by the object on the rhs. */ - for (lproto = lproto_list; lproto; - lproto = TREE_CHAIN (lproto)) - { - p = TREE_VALUE (lproto); - rproto = lookup_protocol_in_reflist (rproto_list, p); - - if (!rproto) - warning - ("object does not conform to the `%s' protocol", - IDENTIFIER_POINTER (PROTOCOL_NAME (p))); - } - return 1; - } - else - { - /* Obscure case - a comparison between two objects - of type 'id <Protocol>'. Check that either the - protocol on the lhs is supported by the object on - the rhs, or viceversa. */ - - /* Check if the protocol on the lhs is supported by the - object on the rhs. */ - for (lproto = lproto_list; lproto; - lproto = TREE_CHAIN (lproto)) - { - p = TREE_VALUE (lproto); - rproto = lookup_protocol_in_reflist (rproto_list, p); + if (rhs_is_proto_id) + return objc_comptypes_proto_proto (lhs, rhs, reflexive); - if (!rproto) - { - /* Check failed - check if the protocol on the rhs - is supported by the object on the lhs. */ - for (rproto = rproto_list; rproto; - rproto = TREE_CHAIN (rproto)) - { - p = TREE_VALUE (rproto); - lproto = lookup_protocol_in_reflist (lproto_list, - p); - - if (!lproto) - { - /* This check failed too: incompatible */ - return 0; - } - } - return 1; - } - } - return 1; - } - } /* <Protocol> = <class> * */ else if (TYPED_OBJECT (TREE_TYPE (rhs))) { @@ -998,7 +1045,7 @@ /* <Protocol> = ?? : let comptypes decide. */ return -1; } - else if (rhs_is_proto) + else if (rhs_is_proto_id) { /* <class> * = <Protocol> */ if (TYPED_OBJECT (TREE_TYPE (lhs))) @@ -1078,6 +1125,46 @@ return -1; } } + else if (lhs_is_proto_class) + { + /* Class <Protocol> = Class <Protocol> */ + if (rhs_is_proto_class) + return objc_comptypes_proto_proto (lhs, rhs, reflexive); + + /* Class <Protocol> = <class> * */ + else if (TYPED_OBJECT (TREE_TYPE (rhs))) + return 0; + + /* Class <Protocol> = Class */ + else if (objc_is_class_id (TREE_TYPE (rhs))) + return 1; + + /* Class <Protocol> = id && Class <Protocol> = <Protocol> */ + else if (objc_is_object_id (TREE_TYPE (rhs))) + return (rhs_is_proto_id ? 0 : 1); + + /* <Protocol> = ?? : let comptypes decide. */ + else + return -1; + } + else if (rhs_is_proto_class) + { + /* <class> * = Class <Protocol> */ + if (TYPED_OBJECT (TREE_TYPE (lhs))) + return 0; + + /* id = Class <Protocol> && <Protocol> = Class <Protocol> */ + else if (objc_is_object_id (TREE_TYPE (lhs))) + return (lhs_is_proto_id ? 0 : 1); + + /* Class = Class <Protocol> */ + else if (objc_is_class_id (TREE_TYPE (lhs))) + return 1; + + /* ??? = Class <Protocol> : let comptypes decide */ + else + return -1; + } else { /* Attention: we shouldn't defer to comptypes here. One bad @@ -1164,7 +1251,7 @@ /* Construct a PROTOCOLS-qualified variant of INTERFACE, where INTERFACE may either name an Objective-C class, or refer to the special 'id' or 'Class' - types. If INTERFACE is not a valid ObjC type, just return it unchanged. */ + types. If INTERFACE is not a valid ObjC type, report error. */ tree objc_get_protocol_qualified_type (tree interface, tree protocols) @@ -1180,7 +1267,7 @@ if (type) type = xref_tag (RECORD_TYPE, type); else - return interface; + error ("protocol qualifiers specified for non-Objective-C type"); } if (protocols) @@ -1222,8 +1309,10 @@ } } -/* Look up PROTOCOLS, and return a list of those that are found. - If none are found, return NULL. */ +/* Look up PROTOCOLS, a list of identifiers, and return the list + of the protocol interface declarations that are found. Invokes error + for each identifier for which the lookup failed. + If PROTOCOLS is empty, return NULL. */ static tree lookup_and_install_protocols (tree protocols) @@ -1247,6 +1336,93 @@ return return_value; } +/* Iterates over the protocol interface list RPROTOS marking each as + PROTOCOL_DECLARED_BY_ROOT. Registers the instance methods prototypes + of each protocol and their inherited protocols recursively as + potential class methods. IGNORE should always be 0. It is used + for recursive calls to insure that inherited protocols will not be + marked unduly. */ + +static void +mark_protocols_declared_by_root_class (tree rprotos, int ignore) +{ + tree protocol_ch; + tree protocol; + + for (protocol_ch = rprotos; + protocol_ch; + protocol_ch = TREE_CHAIN (protocol_ch)) + { + protocol = TREE_CHECK(TREE_VALUE (protocol_ch), + PROTOCOL_INTERFACE_TYPE); + + /* Minor efficency check. Expect all protocols which have + been previously marked, to have had their methods registered. + A protocol which itself is not declared by a root class yet + is inherited by multiple root classes will have its instance + methods processed redundantly, but it does not seem worth while + to flag them just to avoid this. */ + if (!PROTOCOL_DECLARED_BY_ROOT (protocol)) + { + tree method_decl; + + for (method_decl = PROTOCOL_NST_METHODS (protocol); + method_decl; + method_decl = TREE_CHAIN (method_decl)) + { + add_method_to_hash_list(cls_method_hash_list, method_decl); + } + } + + if (!ignore) + PROTOCOL_DECLARED_BY_ROOT (protocol) = 1; + + mark_protocols_declared_by_root_class (PROTOCOL_LIST (protocol), 1); + } +} + +/* Searches for SELECTOR in the instance methods + of the protocol interface list RPROTOS. Returns + the prototype only if the corresponding protocol from RPROTOS + is declared by any root class. IGNORE should always be 0. + It is used for the recursive prototype search of inherited protocols. */ + +static tree +instance_prototype_of_root_protocol (tree rprotos, tree selector, int ignore) +{ + tree protocol_ch; + tree protocol; + tree prototype = NULL_TREE; + + /* Loop over protocol list and search for protocols + that declare the method as an instance method. */ + for (protocol_ch = rprotos; + protocol_ch; + protocol_ch = TREE_CHAIN (protocol_ch)) + { + protocol = TREE_CHECK(TREE_VALUE (protocol_ch), + PROTOCOL_INTERFACE_TYPE); + + if (ignore || PROTOCOL_DECLARED_BY_ROOT (protocol)) + { + /* Check the protocol itself. */ + prototype = lookup_method (PROTOCOL_NST_METHODS (protocol), + selector); + if (prototype) + return prototype; + + /* Search prototypes of inherited protocols independent of mark. */ + prototype + = instance_prototype_of_root_protocol (PROTOCOL_LIST (protocol), + selector, 1); + if (prototype) + return prototype; + } + } + return prototype; +} + + /* Create a declaration for field NAME of a given TYPE. */ static tree @@ -5569,14 +5745,24 @@ } else { + rprotos = TYPE_PROTOCOL_LIST (rtype); class_tree = objc_class_name; OBJC_SET_TYPE_NAME (rtype, class_tree); + + if (rprotos) + rtype = NULL_TREE; } if (rprotos) - method_prototype - = lookup_method_in_protocol_list (rprotos, sel_name, - class_tree != NULL_TREE); + { + method_prototype + = lookup_method_in_protocol_list (rprotos, sel_name, + class_tree != NULL_TREE); + if (!method_prototype && class_tree != NULL_TREE) + method_prototype + = instance_prototype_of_root_protocol(rprotos, sel_name, 0); + } + if (!method_prototype && !rprotos) method_prototype = lookup_method_in_hash_lists (sel_name, @@ -6680,8 +6866,14 @@ add_class (class); if (protocol_list) - CLASS_PROTOCOL_LIST (class) - = lookup_and_install_protocols (protocol_list); + { + CLASS_PROTOCOL_LIST (class) + = lookup_and_install_protocols (protocol_list); + + if (!CLASS_SUPER_NAME (class)) + mark_protocols_declared_by_root_class (CLASS_PROTOCOL_LIST (class), + 0); + } } else if (code == CATEGORY_INTERFACE_TYPE) @@ -6702,8 +6894,14 @@ add_category (class_category_is_assoc_with, class); if (protocol_list) - CLASS_PROTOCOL_LIST (class) - = lookup_and_install_protocols (protocol_list); + { + CLASS_PROTOCOL_LIST (class) + = lookup_and_install_protocols (protocol_list); + + if (!CLASS_SUPER_NAME (class_category_is_assoc_with)) + mark_protocols_declared_by_root_class (CLASS_PROTOCOL_LIST (class), + 0); + } } else if (code == CATEGORY_IMPLEMENTATION_TYPE) Index: gcc/objc/objc-act.h =================================================================== RCS file: /cvsroot/gcc/gcc/gcc/objc/objc-act.h,v retrieving revision 1.31 diff -u -r1.31 objc-act.h --- gcc/objc/objc-act.h 22 Sep 2004 01:13:07 -0000 1.31 +++ gcc/objc/objc-act.h 28 Sep 2004 18:23:08 -0000 @@ -37,6 +37,14 @@ #define CLASS_LANG_SLOT_ELTS 5 #define PROTOCOL_LANG_SLOT_ELTS 2 +/* + Objective-C usage for TREE_LANG_FLAG_?: + + 0: PROTOCOL_DECLARED_BY_ROOT - (valid for PROTOCOL_INTERFACE_TYPE) + Marks protocol declarations that are declared by root classes + so that instance methods are also checked for Class references. +*/ + /* KEYWORD_DECL */ #define KEYWORD_KEY_NAME(DECL) ((DECL)->decl.name) #define KEYWORD_ARG_NAME(DECL) ((DECL)->decl.arguments) @@ -66,6 +74,7 @@ #define PROTOCOL_CLS_METHODS(CLASS) ((CLASS)->type.maxval) #define PROTOCOL_FORWARD_DECL(CLASS) TREE_VEC_ELT (TYPE_LANG_SLOT_1 (CLASS), 1) #define PROTOCOL_DEFINED(CLASS) TREE_USED (CLASS) +#define PROTOCOL_DECLARED_BY_ROOT(CLASS) TREE_LANG_FLAG_0 (CLASS) /* We need to distinguish TYPE_PROTOCOL_LISTs from TYPE_CONTEXTs, both of which are stored in the same accessor slot. */ @@ -279,6 +288,8 @@ (POINTER_TYPE_P (TYPE) && TREE_TYPE (TYPE) == TREE_TYPE (objc_class_type)) #define IS_PROTOCOL_QUALIFIED_ID(TYPE) \ (IS_ID (TYPE) && TYPE_PROTOCOL_LIST (TYPE)) +#define IS_PROTOCOL_QUALIFIED_CLASS(TYPE) \ + (IS_CLASS (TYPE) && TYPE_PROTOCOL_LIST (TYPE)) #define IS_SUPER(TYPE) \ (POINTER_TYPE_P (TYPE) && TREE_TYPE (TYPE) == objc_super_template)
/* Check Class <protocol> types */ /* Author: David Ayers <d.ayers@inode.at> */ /* { dg-do compile } */ #include <objc/objc.h> #include <objc/objc-api.h> @protocol MyProto1 +(void)doItClass1; -(void)doItInstance1; @end @protocol MyProto2 +(void)doItClass2; -(void)doItInstance2; @end @interface MyClass1 <MyProto1> { Class isa; } @end @implementation MyClass1 +(void)doItClass1{} -(void)doItInstance1{} @end @interface MyClass2 : MyClass1 <MyProto2> @end @implementation MyClass2 +(void)doItClass2{} -(void)doItInstance2{} @end /*----------------------------------------*/ Class cls = 0; Class <MyProto1> clsP1 = 0; Class <MyProto2> clsP2 = 0; void testSimple(void) { [cls doItClass1]; [cls doItInstance1]; /* Do not warn as root Class declares this. */ [cls doItClass2]; [cls doItInstance2]; /* { dg-warning "may not respond" } */ [clsP1 doItClass1]; [clsP1 doItInstance1]; /* Do not warn as root Class declares this. */ [clsP1 doItClass2]; /* { dg-warning "not implemented by protocol" } */ [clsP1 doItInstance2]; /* { dg-warning "not implemented by protocol" } */ [clsP2 doItClass1]; /* { dg-warning "not implemented by protocol" } */ [clsP2 doItInstance1]; /* { dg-warning "not implemented by protocol" } */ [clsP2 doItClass2]; [clsP2 doItInstance2]; /* { dg-warning "not implemented by protocol" } */ [MyClass1 doItClass1]; [MyClass1 doItInstance1]; [MyClass1 doItClass2]; /* { dg-warning "may not respond to" } */ [MyClass1 doItInstance2]; /* { dg-warning "may not respond to" } */ [MyClass2 doItClass1]; [MyClass2 doItInstance1]; [MyClass2 doItClass2]; [MyClass2 doItInstance2]; /* { dg-warning "may not respond to" } */ } /*----------------------------------------*/ /* Protocols declared by categories */ @protocol MyProto3 +(void)doItClass3; -(void)doItInstance3; @end @protocol MyProto4 +(void)doItClass4; -(void)doItInstance4; @end @interface MyClass1 (Category1) <MyProto3> @end @interface MyClass2 (Category2) <MyProto4> @end void testCategory(void) { [cls doItClass3]; [cls doItInstance3]; /* Do not warn as root Class declares this. */ [cls doItClass4]; [cls doItInstance4]; /* { dg-warning "may not respond" } */ [MyClass1 doItClass3]; [MyClass1 doItInstance3]; [MyClass1 doItClass4]; /* { dg-warning "may not respond" } */ [MyClass1 doItInstance4]; /* { dg-warning "may not respond" } */ [MyClass2 doItClass3]; [MyClass2 doItInstance3]; [MyClass2 doItClass4]; [MyClass2 doItInstance4]; /* { dg-warning "may not respond" } */ } /*----------------------------------------*/ /* Inherited protocols declared by categories */ @protocol MyProto5 <MyProto1> +(void)doItClass5; -(void)doItInstance5; @end @protocol MyProto6 <MyProto2> +(void)doItClass6; -(void)doItInstance6; @end @interface MyClass1 (Category3) <MyProto5> @end @interface MyClass2 (Category4) <MyProto6> @end Class <MyProto5> clsP5 = 0; Class <MyProto6> clsP6 = 0; void testCategoryInherited(void) { [cls doItClass5]; [cls doItInstance5]; /* Do not warn as root Class declares this. */ [cls doItClass6]; [cls doItInstance6]; /* { dg-warning "may not respond" } */ [clsP5 doItClass1]; [clsP5 doItInstance1]; [clsP5 doItClass2]; /* { dg-warning "not implemented by protocol" } */ [clsP5 doItInstance2]; /* { dg-warning "not implemented by protocol" } */ [clsP6 doItClass1]; /* { dg-warning "not implemented by protocol" } */ [clsP6 doItInstance1]; /* { dg-warning "not implemented by protocol" } */ [clsP6 doItClass2]; [clsP6 doItInstance2]; /* { dg-warning "not implemented by protocol" } */ [MyClass1 doItClass5]; [MyClass1 doItInstance5]; /* Do not warn as root Class declares this. */ [MyClass1 doItClass6]; /* { dg-warning "may not respond" } */ [MyClass1 doItInstance6]; /* { dg-warning "may not respond" } */ [MyClass2 doItClass5]; [MyClass2 doItInstance5]; /* Do not warn as root Class declares this. */ [MyClass2 doItClass6]; [MyClass2 doItInstance6]; /* { dg-warning "may not respond" } */ } /*----------------------------------------*/ /* Forward declared root protocols */ @protocol FwProto; @interface MyClass1 (Forward) <FwProto> @end Class <FwProto> clsP7 = 0; void testForwardeDeclared1(void) { [cls doItClass7]; /* { dg-warning "may not respond" } */ [cls doItInstance7]; /* { dg-warning "may not respond" } */ [clsP7 doItClass7]; /* { dg-warning "not implemented by protocol" } */ [clsP7 doItInstance7]; /* { dg-warning "not implemented by protocol" } */ [MyClass1 doItClass7]; /* { dg-warning "may not respond" } */ [MyClass1 doItInstance7]; /* { dg-warning "may not respond" } */ [MyClass2 doItClass7]; /* { dg-warning "may not respond" } */ [MyClass2 doItInstance7]; /* { dg-warning "may not respond" } */ } @protocol FwProto +(void)doItClass7; -(void)doItInstance7; @end void testForwardeDeclared2(void) { [cls doItClass7]; [cls doItInstance7]; /* Do not warn as root Class declares this. */ [clsP7 doItClass7]; [clsP7 doItInstance7]; /* Do not warn as root Class declares this. */ [MyClass1 doItClass7]; [MyClass1 doItInstance7]; [MyClass2 doItClass7]; [MyClass2 doItInstance7]; } /*----------------------------------------*/ /* Inherited non root protocols */ @protocol MyProto8 +(void)doItClass8; -(void)doItInstance8; @end @protocol MyProto9 <MyProto8> +(void)doItClass9; -(void)doItInstance9; @end @interface MyClass1 (InheritedNonRoot) <MyProto9> @end Class <MyProto8> clsP8 = 0; Class <MyProto9> clsP9 = 0; void testInheritedNonRoot(void) { [cls doItClass8]; [cls doItInstance8]; /* Do not warn as root Class declares super. */ [cls doItClass9]; [cls doItInstance9]; /* Do not warn as root Class declares this. */ [clsP8 doItClass8]; [clsP8 doItInstance8]; /* { dg-warning "not implemented by protocol" } */ [clsP8 doItClass9]; /* { dg-warning "not implemented by protocol" } */ [clsP8 doItInstance9]; /* { dg-warning "not implemented by protocol" } */ [clsP9 doItClass8]; [clsP9 doItInstance8]; [clsP9 doItClass9]; [clsP9 doItInstance9]; [MyClass1 doItClass8]; [MyClass1 doItInstance8]; /* Do not warn as root Class declares this. */ [MyClass1 doItClass9]; [MyClass1 doItInstance9]; [MyClass2 doItClass8]; [MyClass2 doItInstance8]; /* Do not warn as root Class declares this. */ [MyClass2 doItClass9]; [MyClass2 doItInstance9]; } id obj = nil; id <MyProto1> objP1 = nil; id <MyProto2> objP2 = nil; MyClass1 *mc1 = nil; MyClass2 *mc2 = nil; void testComptypes(void) { cls == clsP1; clsP1 == cls; cls == objP1; /* { dg-warning "lacks a cast" } */ objP1 == cls; /* { dg-warning "lacks a cast" } */ clsP1 == clsP5; clsP5 == clsP1; mc1 == clsP1; /* { dg-warning "lacks a cast" } */ clsP1 == mc1; /* { dg-warning "lacks a cast" } */ cls = clsP1; clsP1 = cls; cls = objP1; /* { dg-warning "incompatible" } */ objP1 = cls; /* { dg-warning "incompatible" } */ clsP1 = clsP5; clsP5 = clsP1; /* { dg-warning "does not conform" } */ mc1 = clsP1; /* { dg-warning "incompatible" } */ clsP1 = mc1; /* { dg-warning "incompatible" } */ } int main () { testSimple(); testCategory(); testCategoryInherited(); return(0); } /* { dg-warning "Messages without a matching" "" { target *-*-* } 47 } */ /* { dg-warning "will be assumed to return" "" { target *-*-* } 47 } */ /* { dg-warning "as arguments" "" { target *-*-* } 47 } */
Attachment:
patch.tar.gz
Description: application/gunzip
Index Nav: | [Date Index] [Subject Index] [Author Index] [Thread Index] | |
---|---|---|
Message Nav: | [Date Prev] [Date Next] | [Thread Prev] [Thread Next] |