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]

Re: [objc-improvements-branch]: FYI: Yet another round of ObjC++work committed -- ADDENDUM


Ziemowit Laski wrote:

> Oh, yeah, and I cleaned up <objc/...> headers to be usable with ObjC++.
> 

Did you simply merge in Andrew's changes to libobjc or were there other
changes necessary?

>>
>>David, if you want to whip-up an identifier cleanup patch for 
>>objc-improvements-branch, go for it. :-)
>>

Here is the cumulative patch adapted for the objc-improvements-branch for:

[RFA] c-parse.in unify ObjC tokens
http://gcc.gnu.org/ml/gcc-patches/2004-06/msg00782.html

[RFA][objc] Identifier cleanup
http://gcc.gnu.org/ml/gcc-patches/2004-06/msg01561.html

[RFC/RFA] [ObjC] Class <protocol> support I
http://gcc.gnu.org/ml/gcc-patches/2004-06/msg02496.html

I see that you have dealt with gcc/testsuite/objc.dg/id-1.m in a
different way already on the branch.  But I must admit that I find the
new diagnostics...
id-1.m:4: error: conflicting types for 'id'
id-1.m:0: error: previous declaration of 'id' was here
(note the missing location and line number 0 as this seems to be a built
in type now) a bit misleading.

Anyway, bootstrapped and testing passed (including obj-c++)

Cheers,
David

PS: Why did you choose 'obj-c++' over of 'objc++' in various places?  I
seems needlessly inconsistent.

2004-06-30  David Ayers  <d.ayers@inode.at>

        * objc.dg/class-protocol-1.m: New test.
gcc/
2004-06-30  David Ayers  <d.ayers@inode.at>

	* c-common.h: Remove RID_ID.

	* c-parse.in: Unify Objective-C token names.  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 (super_type): Rename to objc_super_type.
	(selector_type): Rename to objc_selector_type.
	(instance_type): Rename to objc_instance_type.
	(protocol_type): Rename to objc_protocol_type.
	(PROTOCOL_DECLARED_BY_ROOT): New macro.

	* objc/objc-act.c (lookup_method_in_protocol_list): Rename
	class_meth to is_class.  Add documentation.
	(objc_finish_message_expr): Rename is_class to class_tree.

	(synth_module_prologue, objc_build_protocol_expr): Update
	references to protocol_type.
	(synth_module_prologue, build_objc_symtab_template)
	(init_objc_symtab, build_selector_reference_decl)
	(build_selector_table_decl, build_selector)
	(build_selector_translation_table)
	(build_typed_selector_reference, build_method_prototype_template) 
	(build_selector_template, build_method_template)
	(get_arg_type_list, synth_self_and_ucmd_args): Update references
	to selector_type.
	(build_private_template, build_ivar_reference):Update references
	to instance_type.
	(synth_module_prologue, get_arg_type_list)
	(build_objc_method_call): Update references to super_type.
	
	(mark_protocols_declared_by_root_class)
	(instance_prototype_of_root_protocol): 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_get_protocol_qualified_type): Report error for unknown types
	with protocol qualifiers.  Update documentation.
	(objc_finish_message_expr): Extend prototype search for protocol
	qualified classes.
	(start_class): Call mark_protocols_declared_by_root_class if
	processing a root class with protocol references.

	(lookup_and_install_protocols): Update documentation.

	* objc/objc-tree.def: Add C mode identifier sequence.
	
gcc/cp
2004-06-30  David Ayers  <d.ayers@inode.at>

	* lex.c: Remove references to RID_ID.

Index: gcc/c-common.h
===================================================================
RCS file: /cvs/gcc/gcc/gcc/c-common.h,v
retrieving revision 1.189.2.18
diff -u -r1.189.2.18 c-common.h
--- gcc/c-common.h	26 Jun 2004 04:01:35 -0000	1.189.2.18
+++ gcc/c-common.h	30 Jun 2004 07:29:28 -0000
@@ -96,7 +96,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: /cvs/gcc/gcc/gcc/c-parse.in,v
retrieving revision 1.170.2.14
diff -u -r1.170.2.14 c-parse.in
--- gcc/c-parse.in	26 Jun 2004 04:01:36 -0000	1.170.2.14
+++ gcc/c-parse.in	30 Jun 2004 07:29:29 -0000
@@ -171,8 +171,9 @@
 
 /* The Objective-C keywords.  These are included in C and in
    Objective C, so that the token codes are the same in both.  */
-%token INTERFACE IMPLEMENTATION END SELECTOR DEFS ENCODE
-%token CLASSNAME PUBLIC PRIVATE PROTECTED PROTOCOL OBJECTNAME CLASS ALIAS
+%token AT_INTERFACE AT_IMPLEMENTATION AT_END AT_SELECTOR AT_DEFS AT_ENCODE
+%token CLASSNAME AT_PUBLIC AT_PRIVATE AT_PROTECTED AT_PROTOCOL
+%token AT_CLASS AT_ALIAS
 %token AT_THROW AT_TRY AT_CATCH AT_FINALLY AT_SYNCHRONIZED
 %token OBJC_STRING
 
@@ -244,7 +245,7 @@
 %type <ttype> selectorarg keywordnamelist keywordname objcencodeexpr
 %type <ttype> non_empty_protocolrefs protocolrefs identifier_list objcprotocolexpr
 
-%type <ttype> CLASSNAME OBJECTNAME OBJC_STRING
+%type <ttype> CLASSNAME OBJC_STRING
 
 %type <ttype> superclass
 %type <itype> objc_try_catch_stmt objc_finally_block optellipsis
@@ -440,7 +441,6 @@
 	IDENTIFIER
 	| TYPENAME
 @@ifobjc
-	| OBJECTNAME
 	| CLASSNAME
 @@end_ifobjc
 	;
@@ -1326,7 +1326,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>"
@@ -1594,9 +1594,6 @@
 	| '*' maybe_type_quals_attrs after_type_declarator  %prec UNARY
 		{ $$ = make_pointer_declarator ($2, $3); }
 	| TYPENAME
-@@ifobjc
-	| OBJECTNAME
-@@end_ifobjc
 	;
 
 /* Kinds of declarator that can appear in a parameter list
@@ -1614,9 +1611,6 @@
 	| parm_declarator_starttypename array_declarator  %prec '.'
 		{ $$ = set_array_declarator_type ($2, $1, 0); }
 	| TYPENAME
-@@ifobjc
-	| OBJECTNAME
-@@end_ifobjc
 	;
 
 parm_declarator_nostarttypename:
@@ -1761,7 +1755,7 @@
 		    pedwarn ("extra semicolon in struct or union specified"); }
 @@ifobjc
 	/* foo(sizeof(struct{ @defs(ClassName)})); */
-	| DEFS '(' CLASSNAME ')'
+	| AT_DEFS '(' CLASSNAME ')'
 		{ $$ = nreverse (objc_get_class_ivars ($3)); }
 @@end_ifobjc
 	;
@@ -2710,7 +2704,7 @@
 	| aliasdecl
 	| protocoldef
 	| methoddef
-	| END
+	| AT_END
 		{
 		  objc_finish_implementation ();
 		}
@@ -2725,14 +2719,14 @@
 	;
 
 classdecl:
-	  CLASS identifier_list ';'
+	  AT_CLASS identifier_list ';'
 		{
 		  objc_declare_class ($2);
 		}
 	;
 
 aliasdecl:
-	  ALIAS identifier identifier ';'
+	  AT_ALIAS identifier identifier ';'
 		{
 		  objc_declare_alias ($2, $3);
 		}
@@ -2749,7 +2743,7 @@
 	;
 
 classdef:
-	  INTERFACE identifier superclass protocolrefs
+	  AT_INTERFACE identifier superclass protocolrefs
 		{
 		  objc_start_class_interface ($2, $3, $4);
 		}
@@ -2757,12 +2751,12 @@
 		{
 		  objc_continue_interface ();
 		}
-	  methodprotolist END
+	  methodprotolist AT_END
 		{
 		  objc_finish_interface ();
 		}
 
-	| IMPLEMENTATION identifier superclass
+	| AT_IMPLEMENTATION identifier superclass
 		{
 		  objc_start_class_implementation ($2, $3);
 		}
@@ -2771,28 +2765,28 @@
 		  objc_continue_implementation ();
 		}
 
-	| INTERFACE identifier '(' identifier ')' protocolrefs
+	| AT_INTERFACE identifier '(' identifier ')' protocolrefs
 		{
 		  objc_start_category_interface ($2, $4, $6);
 		}
-	  methodprotolist END
+	  methodprotolist AT_END
 		{
 		  objc_finish_interface ();
 		}
 
-	| IMPLEMENTATION identifier '(' identifier ')'
+	| AT_IMPLEMENTATION identifier '(' identifier ')'
 		{
 		  objc_start_category_implementation ($2, $4);
 		}
 	;
 
 protocoldef:
-	  PROTOCOL identifier protocolrefs
+	  AT_PROTOCOL identifier protocolrefs
 		{
 		  objc_pq_context = 1;
 		  objc_start_protocol ($2, $3);
 		}
-	  methodprotolist END
+	  methodprotolist AT_END
 		{
 		  objc_pq_context = 0;
 		  objc_finish_interface ();
@@ -2800,7 +2794,7 @@
 	/* The @protocol forward-declaration production introduces a
 	   reduce/reduce conflict on ';', which should be resolved in
 	   favor of the production 'identifier_list -> identifier'.  */
-	| PROTOCOL identifier_list ';'
+	| AT_PROTOCOL identifier_list ';'
 		{
 		  objc_declare_protocols ($2);
 		}
@@ -2830,9 +2824,9 @@
         ;
 
 visibility_spec:
-	  PRIVATE { objc_set_visibility (2); }
-	| PROTECTED { objc_set_visibility (0); }
-	| PUBLIC { objc_set_visibility (1); }
+	  AT_PRIVATE { objc_set_visibility (2); }
+	| AT_PROTECTED { objc_set_visibility (0); }
+	| AT_PUBLIC { objc_set_visibility (1); }
 	;
 
 ivar_decls:
@@ -3023,7 +3017,6 @@
 	  IDENTIFIER
 	| TYPENAME
 	| CLASSNAME
-	| OBJECTNAME
 	| reservedwords
 	;
 
@@ -3135,14 +3128,14 @@
 	;
 
 objcselectorexpr:
-	  SELECTOR '(' selectorarg ')'
+	  AT_SELECTOR '(' selectorarg ')'
 		{
 		  $$ = $3;
 		}
 	;
 
 objcprotocolexpr:
-	  PROTOCOL '(' identifier ')'
+	  AT_PROTOCOL '(' identifier ')'
 		{
 		  $$ = $3;
 		}
@@ -3151,7 +3144,7 @@
 /* extension to support C-structures in the archiver */
 
 objcencodeexpr:
-	  ENCODE '(' typename ')'
+	  AT_ENCODE '(' typename ')'
 		{
 		  $$ = groktypename ($3);
 		}
@@ -3260,8 +3253,6 @@
   { "volatile",		RID_VOLATILE,	0 },
   { "while",		RID_WHILE,	0 },
 @@ifobjc
-  { "id",		RID_ID,			D_OBJC },
-
   /* These objc keywords are recognized only immediately after
      an '@'.  */
   { "class",		RID_AT_CLASS,		D_OBJC },
@@ -3406,24 +3397,23 @@
   /* RID_STATCAST */	0,
 
   /* Objective C */
-  /* RID_ID */			OBJECTNAME,
-  /* RID_AT_ENCODE */		ENCODE,
-  /* RID_AT_END */		END,
-  /* RID_AT_CLASS */		CLASS,
-  /* RID_AT_ALIAS */		ALIAS,
-  /* RID_AT_DEFS */		DEFS,
-  /* RID_AT_PRIVATE */		PRIVATE,
-  /* RID_AT_PROTECTED */	PROTECTED,
-  /* RID_AT_PUBLIC */		PUBLIC,
-  /* RID_AT_PROTOCOL */		PROTOCOL,
-  /* RID_AT_SELECTOR */		SELECTOR,
+  /* RID_AT_ENCODE */		AT_ENCODE,
+  /* RID_AT_END */		AT_END,
+  /* RID_AT_CLASS */		AT_CLASS,
+  /* RID_AT_ALIAS */		AT_ALIAS,
+  /* RID_AT_DEFS */		AT_DEFS,
+  /* RID_AT_PRIVATE */		AT_PRIVATE,
+  /* RID_AT_PROTECTED */	AT_PROTECTED,
+  /* RID_AT_PUBLIC */		AT_PUBLIC,
+  /* RID_AT_PROTOCOL */		AT_PROTOCOL,
+  /* RID_AT_SELECTOR */		AT_SELECTOR,
   /* RID_AT_THROW */		AT_THROW,
   /* RID_AT_TRY */		AT_TRY,
   /* RID_AT_CATCH */		AT_CATCH,
   /* RID_AT_FINALLY */		AT_FINALLY,
   /* RID_AT_SYNCHRONIZED */	AT_SYNCHRONIZED,
-  /* RID_AT_INTERFACE */	INTERFACE,
-  /* RID_AT_IMPLEMENTATION */	IMPLEMENTATION
+  /* RID_AT_INTERFACE */	AT_INTERFACE,
+  /* RID_AT_IMPLEMENTATION */	AT_IMPLEMENTATION
 };
 
 static void
@@ -3475,15 +3465,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
@@ -3646,7 +3627,6 @@
     {
     case IDENTIFIER:
     case TYPENAME:
-    case OBJECTNAME:
     case TYPESPEC:
     case TYPE_QUAL:
     case SCSPEC:
Index: gcc/cp/lex.c
===================================================================
RCS file: /cvs/gcc/gcc/gcc/cp/lex.c,v
retrieving revision 1.309.2.8
diff -u -r1.309.2.8 lex.c
--- gcc/cp/lex.c	2 Apr 2004 00:11:46 -0000	1.309.2.8
+++ gcc/cp/lex.c	30 Jun 2004 07:29:33 -0000
@@ -349,7 +349,6 @@
      All of them will remain _disabled_, since they are context-
      sensitive.  */
 
-  { "id",		RID_ID,			D_OBJC },
   /* These ObjC keywords are recognized only immediately after
      an '@'.  NB: The following C++ keywords double as
      ObjC keywords in this context: RID_CLASS, RID_PRIVATE,
Index: gcc/objc/objc-act.c
===================================================================
RCS file: /cvs/gcc/gcc/gcc/objc/objc-act.c,v
retrieving revision 1.179.2.29
diff -u -r1.179.2.29 objc-act.c
--- gcc/objc/objc-act.c	26 Jun 2004 04:01:38 -0000	1.179.2.29
+++ gcc/objc/objc-act.c	30 Jun 2004 07:29:37 -0000
@@ -238,6 +238,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.  */
 
@@ -609,9 +611,14 @@
   return decl;
 }
 
+/* Return the first occurrence of a method declaration corresponding
+   to SEL_NAME in RPROTO_LIST.  Search RPROTO_LIST recursively.
+   If IS_CLASS is 0, search for instance methods, otherwise for class
+   methods.  */
+
 static tree
 lookup_method_in_protocol_list (tree rproto_list, tree sel_name,
-				int class_meth)
+				int is_class)
 {
    tree rproto, p;
    tree fnd = 0;
@@ -622,13 +629,13 @@
 
 	if (TREE_CODE (p) == PROTOCOL_INTERFACE_TYPE)
 	  {
-	    if ((fnd = lookup_method (class_meth
+	    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, class_meth);
+						    sel_name, is_class);
 	  }
 	else
           {
@@ -712,6 +719,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;
 }
 
@@ -1152,7 +1181,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)
@@ -1168,7 +1197,7 @@
       if (type)
 	type = xref_tag (RECORD_TYPE, type);
       else
-        return interface;
+	error ("protocol qualifiers specified for non-ObjC type");
     }
 
   if (protocols)
@@ -1221,8 +1250,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 a 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)
@@ -1246,6 +1277,95 @@
   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
@@ -1333,19 +1453,19 @@
 
   type = get_identifier (PROTOCOL_OBJECT_CLASS_NAME);
   objc_declare_class (tree_cons (NULL_TREE, type, NULL_TREE));
-  protocol_type = build_pointer_type (xref_tag (RECORD_TYPE,
-                                type));
+  objc_protocol_type = build_pointer_type (xref_tag (RECORD_TYPE,
+						     type));
 
   /* Declare type of selector-objects that represent an operation name.  */
 
   if (flag_next_runtime)
     /* `struct objc_selector *' */
-    selector_type
+    objc_selector_type
       = build_pointer_type (xref_tag (RECORD_TYPE,
 				      get_identifier (TAG_SELECTOR)));
   else
     /* `const struct objc_selector *' */
-    selector_type
+    objc_selector_type
       = build_pointer_type
 	(build_qualified_type (xref_tag (RECORD_TYPE,
 					 get_identifier (TAG_SELECTOR)),
@@ -1354,8 +1474,8 @@
   /* Declare receiver type used for dispatching messages to 'super'.  */
 
   /* `struct objc_super *' */
-  super_type = build_pointer_type (xref_tag (RECORD_TYPE,
-					  get_identifier (TAG_SUPER)));
+  objc_super_type = build_pointer_type (xref_tag (RECORD_TYPE,
+						  get_identifier (TAG_SUPER)));
 
   if (flag_next_runtime)
     {
@@ -1371,7 +1491,8 @@
       type
 	= build_function_type (objc_object_type,
 			       tree_cons (NULL_TREE, objc_object_type,
-					  tree_cons (NULL_TREE, selector_type,
+					  tree_cons (NULL_TREE, 
+						     objc_selector_type,
 						     NULL_TREE)));
       umsg_decl = builtin_function (TAG_MSGSEND,
 				    type, 0, NOT_BUILT_IN,
@@ -1390,8 +1511,9 @@
       /* id objc_msgSendSuper_stret (struct objc_super *, SEL, ...); */
       type
 	= build_function_type (objc_object_type,
-			       tree_cons (NULL_TREE, super_type,
-					  tree_cons (NULL_TREE, selector_type,
+			       tree_cons (NULL_TREE, objc_super_type,
+					  tree_cons (NULL_TREE,
+						     objc_selector_type,
 						     NULL_TREE)));
       umsg_super_decl = builtin_function (TAG_MSGSENDSUPER,
 					  type, 0, NOT_BUILT_IN,
@@ -1409,14 +1531,16 @@
 	= build_pointer_type
 	  (build_function_type (objc_object_type,      
 				tree_cons (NULL_TREE, objc_object_type,      
-					   tree_cons (NULL_TREE, selector_type,      
+					   tree_cons (NULL_TREE,
+						      objc_selector_type,      
 						      NULL_TREE))));      
 
       /* IMP objc_msg_lookup (id, SEL); */
       type
         = build_function_type (IMP_type,
 			       tree_cons (NULL_TREE, objc_object_type,
-					  tree_cons (NULL_TREE, selector_type,
+					  tree_cons (NULL_TREE,
+						     objc_selector_type,
 						     OBJC_VOID_AT_END)));
       umsg_decl = builtin_function (TAG_MSGSEND,
 				    type, 0, NOT_BUILT_IN,
@@ -1425,8 +1549,9 @@
       /* IMP objc_msg_lookup_super (struct objc_super *, SEL); */
       type
         = build_function_type (IMP_type,
-			       tree_cons (NULL_TREE, super_type,
-					  tree_cons (NULL_TREE, selector_type,
+			       tree_cons (NULL_TREE, objc_super_type,
+					  tree_cons (NULL_TREE,
+						     objc_selector_type,
 						     OBJC_VOID_AT_END)));
       umsg_super_decl = builtin_function (TAG_MSGSENDSUPER,
 					  type, 0, NOT_BUILT_IN,
@@ -1718,7 +1843,7 @@
 
   /* SEL *refs; */
 
-  field_decl = create_field_decl (build_pointer_type (selector_type),
+  field_decl = create_field_decl (build_pointer_type (objc_selector_type),
 				  "refs");
   chainon (field_decl_chain, field_decl);
 
@@ -1814,7 +1939,7 @@
   else
     initlist
       = tree_cons (NULL_TREE,
-		   convert (build_pointer_type (selector_type),
+		   convert (build_pointer_type (objc_selector_type),
 			    build_unary_op (ADDR_EXPR,
 					    UOBJC_SELECTOR_TABLE_decl, 1)),
 		   initlist);
@@ -2277,7 +2402,7 @@
 
   ident = get_identifier (buf);
 
-  decl = build_decl (VAR_DECL, ident, selector_type);
+  decl = build_decl (VAR_DECL, ident, objc_selector_type);
   DECL_EXTERNAL (decl) = 1;
   TREE_PUBLIC (decl) = 0;
   TREE_USED (decl) = 1;
@@ -2304,7 +2429,7 @@
       temp = build_array_type (objc_selector_template, NULL_TREE);
     }
   else
-    temp = build_array_type (selector_type, NULL_TREE);
+    temp = build_array_type (objc_selector_type, NULL_TREE);
 
   UOBJC_SELECTOR_TABLE_decl
    = build_decl (VAR_DECL,
@@ -2327,7 +2452,7 @@
 static tree
 build_selector (tree ident)
 {
-  return convert (selector_type, add_objc_string (ident, meth_var_names));
+  return convert (objc_selector_type, add_objc_string (ident, meth_var_names));
 }
 
 static void
@@ -2377,7 +2502,7 @@
 	  sc_spec = build_tree_list (NULL_TREE, ridpointers[(int) RID_STATIC]);
 
 	  /* static SEL _OBJC_SELECTOR_REFERENCES_n = ...; */
-	  decl_specs = tree_cons (NULL_TREE, selector_type, sc_spec);
+	  decl_specs = tree_cons (NULL_TREE, objc_selector_type, sc_spec);
 
 	  var_decl = name;
 
@@ -2482,7 +2607,7 @@
 			 build_array_ref (UOBJC_SELECTOR_TABLE_decl,
 					  build_int_2 (index, 0)),
 			 1);
-  return convert (selector_type, expr);
+  return convert (objc_selector_type, expr);
 }
 
 static tree
@@ -3639,7 +3764,7 @@
       TREE_STATIC_TEMPLATE (uprivate_record) = 1;
     }
 
-  instance_type
+  objc_instance_type
     = groktypename (build_tree_list (build_tree_list (NULL_TREE,
 						      uprivate_record),
 				     build1 (INDIRECT_REF, NULL_TREE,
@@ -3794,7 +3919,7 @@
     = start_struct (RECORD_TYPE, get_identifier (UTAG_METHOD_PROTOTYPE));
 
   /* SEL _cmd; */
-  decl_specs = build_tree_list (NULL_TREE, selector_type);
+  decl_specs = build_tree_list (NULL_TREE, objc_selector_type);
   field_decl = get_identifier ("_cmd");
   field_decl = grokfield (field_decl, decl_specs, NULL_TREE);
   field_decl_chain = field_decl;
@@ -4269,7 +4394,7 @@
 
   /* SEL sel_id; */
 
-  decl_specs = build_tree_list (NULL_TREE, selector_type);
+  decl_specs = build_tree_list (NULL_TREE, objc_selector_type);
   field_decl = get_identifier ("sel_id");
   field_decl = grokfield (field_decl, decl_specs, NULL_TREE);
   field_decl_chain = field_decl;
@@ -4905,7 +5030,7 @@
   _SLT_record = start_struct (RECORD_TYPE, get_identifier (UTAG_METHOD));
 
   /* SEL _cmd; */
-  decl_specs = build_tree_list (NULL_TREE, selector_type);
+  decl_specs = build_tree_list (NULL_TREE, objc_selector_type);
   field_decl = get_identifier ("_cmd");
   field_decl = grokfield (field_decl, decl_specs, NULL_TREE);
   field_decl_chain = field_decl;
@@ -5668,14 +5793,14 @@
 
   /* Receiver type.  */
   if (flag_next_runtime && superflag)
-    arglist = build_tree_list (NULL_TREE, super_type);
+    arglist = build_tree_list (NULL_TREE, objc_super_type);
   else if (context == METHOD_DEF)
     arglist = build_tree_list (NULL_TREE, TREE_TYPE (self_decl));
   else
     arglist = build_tree_list (NULL_TREE, objc_object_type);
 
   /* Selector type - will eventually change to `int'.  */
-  chainon (arglist, build_tree_list (NULL_TREE, selector_type));
+  chainon (arglist, build_tree_list (NULL_TREE, objc_selector_type));
 
   /* No actual method prototype given -- assume that remaining arguments
      are `...'.  */
@@ -5921,7 +6046,7 @@
 objc_finish_message_expr (tree receiver, tree sel_name, tree method_params)
 {
   tree method_prototype = NULL_TREE, rprotos = NULL_TREE, rtype;
-  tree selector, retval, is_class;
+  tree selector, retval, class_tree;
   int self, super, have_cast;
 
   /* Extract the receiver of the message, as well as its type
@@ -5943,14 +6068,14 @@
 
   /* If the receiver is a class object, retrieve the corresponding
      @interface, if one exists. */
-  is_class = receiver_is_class_object (receiver, self, super);
+  class_tree = receiver_is_class_object (receiver, self, super);
 
   /* Now determine the receiver type (if an explicit cast has not been
      provided).  */
   if (!have_cast)
     {
-      if (is_class)
-	rtype = lookup_interface (is_class);
+      if (class_tree)
+	rtype = lookup_interface (class_tree);
       /* Handle `self' and `super'.  */
       else if (super)
 	{
@@ -5972,7 +6097,7 @@
   if (!rtype || objc_is_id (rtype))
     {
       if (!rtype)
-	rtype = xref_tag (RECORD_TYPE, is_class);
+	rtype = xref_tag (RECORD_TYPE, class_tree);
       else if (IS_ID (rtype))
 	{
 	  rprotos = TYPE_PROTOCOL_LIST (rtype);
@@ -5980,18 +6105,32 @@
 	}
       else
 	{
-	  is_class = objc_class_name;
-	  OBJC_SET_TYPE_NAME (rtype, is_class);
+	  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,
-					    is_class != 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,
-					 is_class != NULL_TREE);
+	{
+	  method_prototype
+	    = lookup_method_in_hash_lists (sel_name,
+					   class_tree != NULL_TREE);
+	}
     }
   else
     {
@@ -6023,7 +6162,7 @@
 	     in the published @interface for the class (and its
 	     superclasses). */
 	  method_prototype
-	    = lookup_method_static (rtype, sel_name, is_class != NULL_TREE);
+	    = lookup_method_static (rtype, sel_name, class_tree != NULL_TREE);
 
 	  /* If the method was not found in the @interface, it may still
 	     exist locally as part of the @implementation.  */
@@ -6032,7 +6171,7 @@
 		== OBJC_TYPE_NAME (rtype))			
 	    method_prototype
 	      = lookup_method
-		((is_class
+		((class_tree
 		  ? CLASS_CLS_METHODS (objc_implementation_context)
 		  : CLASS_NST_METHODS (objc_implementation_context)),
 		  sel_name);
@@ -6042,7 +6181,7 @@
 	  if (!method_prototype && rprotos)
 	    method_prototype
 	      = lookup_method_in_protocol_list (rprotos, sel_name,
-						is_class != NULL_TREE);
+						class_tree != NULL_TREE);
 	}
       else
 	{
@@ -6059,11 +6198,11 @@
       if (rtype)
 	warning ("`%s' may not respond to `%c%s'",
 		 IDENTIFIER_POINTER (OBJC_TYPE_NAME (rtype)),
-		 (is_class ? '+' : '-'),
+		 (class_tree ? '+' : '-'),
 		 IDENTIFIER_POINTER (sel_name));
       if (rprotos)
 	warning ("`%c%s' not implemented by protocol(s)",
-		 (is_class ? '+' : '-'),
+		 (class_tree ? '+' : '-'),
 		 IDENTIFIER_POINTER (sel_name));
       if (!warn_missing_methods)
 	{
@@ -6110,7 +6249,7 @@
 		 (!flag_next_runtime || flag_nil_receivers
 		  ? umsg_decl
 		  : umsg_nonnil_decl));
-  tree rcv_p = (super_flag ? super_type : objc_object_type);
+  tree rcv_p = (super_flag ? objc_super_type : objc_object_type);
 
   /* If a prototype for the method to be called exists, then cast
      the sender's return type and arguments to match that of the method.
@@ -6232,9 +6371,9 @@
 
   expr = build_unary_op (ADDR_EXPR, PROTOCOL_FORWARD_DECL (p), 0);
 
-  /* ??? Ideally we'd build the reference with protocol_type directly,
+  /* ??? Ideally we'd build the reference with objc_protocol_type directly,
      if we have it, rather than converting it here.  */
-  expr = convert (protocol_type, expr);
+  expr = convert (objc_protocol_type, expr);
 
   /* The @protocol() expression is being compiled into a pointer to a
      statically allocated instance of the Protocol class.  To become
@@ -6252,7 +6391,7 @@
   if (! flag_next_runtime)
     {
       /* This type is a struct containing the fields of a Protocol
-        object.  (Cfr. protocol_type instead is the type of a pointer
+        object.  (Cfr. objc_protocol_type instead is the type of a pointer
         to such a struct).  */
       tree protocol_struct_type = xref_tag
        (RECORD_TYPE, get_identifier (PROTOCOL_OBJECT_CLASS_NAME));
@@ -6365,7 +6504,7 @@
 	 paradigm.  */
       warning ("instance variable `%s' accessed in class method",
 	       IDENTIFIER_POINTER (id));
-      TREE_TYPE (self_decl) = instance_type; /* cast */
+      TREE_TYPE (self_decl) = objc_instance_type; /* cast */
     }
 
   return build_component_ref (build_indirect_ref (self_decl, "->"), id);
@@ -7103,8 +7242,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)
@@ -7125,8 +7270,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)
@@ -7785,7 +7936,7 @@
 				    build1 (INDIRECT_REF, NULL_TREE, self_id)),
 		   unused_list));
 
-  decl_specs = build_tree_list (NULL_TREE, TREE_TYPE (selector_type));
+  decl_specs = build_tree_list (NULL_TREE, TREE_TYPE (objc_selector_type));
   push_parm_decl (build_tree_list
 		  (build_tree_list (decl_specs,
 				    build1 (INDIRECT_REF, NULL_TREE, ucmd_id)),
Index: gcc/objc/objc-act.h
===================================================================
RCS file: /cvs/gcc/gcc/gcc/objc/objc-act.h,v
retrieving revision 1.16.4.11
diff -u -r1.16.4.11 objc-act.h
--- gcc/objc/objc-act.h	26 Jun 2004 04:01:39 -0000	1.16.4.11
+++ gcc/objc/objc-act.h	30 Jun 2004 07:29:37 -0000
@@ -36,6 +36,14 @@
 #define CLASS_BINFO_ELTS		6
 #define PROTOCOL_BINFO_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_BINFO (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.  */
@@ -265,12 +274,12 @@
 #define objc_get_meta_class_decl			\
 				objc_global_trees[OCTI_GET_MCLASS_DECL]
 
-#define super_type		objc_global_trees[OCTI_SUPER_TYPE]
-#define selector_type		objc_global_trees[OCTI_SEL_TYPE]
+#define objc_super_type		objc_global_trees[OCTI_SUPER_TYPE]
+#define objc_selector_type	objc_global_trees[OCTI_SEL_TYPE]
 #define objc_object_type	objc_global_trees[OCTI_ID_TYPE]
 #define objc_class_type		objc_global_trees[OCTI_CLS_TYPE]
-#define instance_type		objc_global_trees[OCTI_NST_TYPE]
-#define protocol_type		objc_global_trees[OCTI_PROTO_TYPE]
+#define objc_instance_type	objc_global_trees[OCTI_NST_TYPE]
+#define objc_protocol_type	objc_global_trees[OCTI_PROTO_TYPE]
 
 /* Type checking macros.  */
 
Index: gcc/objc/objc-tree.def
===================================================================
RCS file: /cvs/gcc/gcc/gcc/objc/objc-tree.def,v
retrieving revision 1.7.8.1
diff -u -r1.7.8.1 objc-tree.def
--- gcc/objc/objc-tree.def	23 Jul 2003 19:05:54 -0000	1.7.8.1
+++ gcc/objc/objc-tree.def	30 Jun 2004 07:29:37 -0000
@@ -37,3 +37,9 @@
 /* Objective-C expressions.  */
 DEFTREECODE (MESSAGE_SEND_EXPR, "message_send_expr", 'e', 3)
 DEFTREECODE (CLASS_REFERENCE_EXPR, "class_reference_expr", 'e', 1)
+
+/*
+Local variables:
+mode:c
+End:
+*/

Attachment: objc.patch.gz
Description: application/gunzip

/* 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];
  
}

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: class-protocol-1.m.gz
Description: application/gunzip


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]