xref: /openbsd-src/gnu/usr.bin/gcc/gcc/objc/objc-act.c (revision 4e43c760ad4cd5f644ec700462679d05749498d8)
1 /* Implement classes and message passing for Objective C.
2    Copyright (C) 1992, 1993, 1994, 1995, 1997, 1998, 1999, 2000, 2001, 2002
3    Free Software Foundation, Inc.
4    Contributed by Steve Naroff.
5 
6 This file is part of GNU CC.
7 
8 GNU CC is free software; you can redistribute it and/or modify
9 it under the terms of the GNU General Public License as published by
10 the Free Software Foundation; either version 2, or (at your option)
11 any later version.
12 
13 GNU CC is distributed in the hope that it will be useful,
14 but WITHOUT ANY WARRANTY; without even the implied warranty of
15 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
16 GNU General Public License for more details.
17 
18 You should have received a copy of the GNU General Public License
19 along with GNU CC; see the file COPYING.  If not, write to
20 the Free Software Foundation, 59 Temple Place - Suite 330,
21 Boston, MA 02111-1307, USA.  */
22 
23 /* Purpose: This module implements the Objective-C 4.0 language.
24 
25    compatibility issues (with the Stepstone translator):
26 
27    - does not recognize the following 3.3 constructs.
28      @requires, @classes, @messages, = (...)
29    - methods with variable arguments must conform to ANSI standard.
30    - tagged structure definitions that appear in BOTH the interface
31      and implementation are not allowed.
32    - public/private: all instance variables are public within the
33      context of the implementation...I consider this to be a bug in
34      the translator.
35    - statically allocated objects are not supported. the user will
36      receive an error if this service is requested.
37 
38    code generation `options':
39 
40    */
41 
42 #include "config.h"
43 #include "system.h"
44 #include "tree.h"
45 #include "rtl.h"
46 #include "expr.h"
47 #include "c-tree.h"
48 #include "c-common.h"
49 #include "flags.h"
50 #include "objc-act.h"
51 #include "input.h"
52 #include "except.h"
53 #include "function.h"
54 #include "output.h"
55 #include "toplev.h"
56 #include "ggc.h"
57 #include "debug.h"
58 #include "target.h"
59 #include "diagnostic.h"
60 
61 /* This is the default way of generating a method name.  */
62 /* I am not sure it is really correct.
63    Perhaps there's a danger that it will make name conflicts
64    if method names contain underscores. -- rms.  */
65 #ifndef OBJC_GEN_METHOD_LABEL
66 #define OBJC_GEN_METHOD_LABEL(BUF, IS_INST, CLASS_NAME, CAT_NAME, SEL_NAME, NUM) \
67   do {					    \
68     char *temp;				    \
69     sprintf ((BUF), "_%s_%s_%s_%s",	    \
70 	     ((IS_INST) ? "i" : "c"),	    \
71 	     (CLASS_NAME),		    \
72 	     ((CAT_NAME)? (CAT_NAME) : ""), \
73 	     (SEL_NAME));		    \
74     for (temp = (BUF); *temp; temp++)	    \
75       if (*temp == ':') *temp = '_';	    \
76   } while (0)
77 #endif
78 
79 /* These need specifying.  */
80 #ifndef OBJC_FORWARDING_STACK_OFFSET
81 #define OBJC_FORWARDING_STACK_OFFSET 0
82 #endif
83 
84 #ifndef OBJC_FORWARDING_MIN_OFFSET
85 #define OBJC_FORWARDING_MIN_OFFSET 0
86 #endif
87 
88 
89 /* Set up for use of obstacks.  */
90 
91 #include "obstack.h"
92 
93 /* This obstack is used to accumulate the encoding of a data type.  */
94 static struct obstack util_obstack;
95 /* This points to the beginning of obstack contents,
96    so we can free the whole contents.  */
97 char *util_firstobj;
98 
99 /* for encode_method_def */
100 #include "rtl.h"
101 
102 /* The version identifies which language generation and runtime
103    the module (file) was compiled for, and is recorded in the
104    module descriptor.  */
105 
106 #define OBJC_VERSION	(flag_next_runtime ? 5 : 8)
107 #define PROTOCOL_VERSION 2
108 
109 /* (Decide if these can ever be validly changed.) */
110 #define OBJC_ENCODE_INLINE_DEFS 	0
111 #define OBJC_ENCODE_DONT_INLINE_DEFS	1
112 
113 /*** Private Interface (procedures) ***/
114 
115 /* Used by compile_file.  */
116 
117 static void init_objc				PARAMS ((void));
118 static void finish_objc				PARAMS ((void));
119 
120 /* Code generation.  */
121 
122 static void synth_module_prologue		PARAMS ((void));
123 static tree build_constructor			PARAMS ((tree, tree));
124 static rtx build_module_descriptor		PARAMS ((void));
125 static tree init_module_descriptor		PARAMS ((tree));
126 static tree build_objc_method_call		PARAMS ((int, tree, tree,
127 						       tree, tree, tree));
128 static void generate_strings			PARAMS ((void));
129 static tree get_proto_encoding 			PARAMS ((tree));
130 static void build_selector_translation_table	PARAMS ((void));
131 
132 static tree objc_add_static_instance		PARAMS ((tree, tree));
133 
134 static tree build_ivar_template			PARAMS ((void));
135 static tree build_method_template		PARAMS ((void));
136 static tree build_private_template		PARAMS ((tree));
137 static void build_class_template		PARAMS ((void));
138 static void build_selector_template		PARAMS ((void));
139 static void build_category_template		PARAMS ((void));
140 static tree build_super_template		PARAMS ((void));
141 static tree build_category_initializer		PARAMS ((tree, tree, tree,
142 						       tree, tree, tree));
143 static tree build_protocol_initializer		PARAMS ((tree, tree, tree,
144 						       tree, tree));
145 
146 static void synth_forward_declarations		PARAMS ((void));
147 static void generate_ivar_lists			PARAMS ((void));
148 static void generate_dispatch_tables		PARAMS ((void));
149 static void generate_shared_structures		PARAMS ((void));
150 static tree generate_protocol_list		PARAMS ((tree));
151 static void generate_forward_declaration_to_string_table PARAMS ((void));
152 static void build_protocol_reference		PARAMS ((tree));
153 
154 static tree build_keyword_selector		PARAMS ((tree));
155 static tree synth_id_with_class_suffix		PARAMS ((const char *, tree));
156 
157 static void generate_static_references		PARAMS ((void));
158 static int check_methods_accessible		PARAMS ((tree, tree,
159 						       int));
160 static void encode_aggregate_within		PARAMS ((tree, int, int,
161 					               int, int));
162 static const char *objc_demangle		PARAMS ((const char *));
163 static void objc_expand_function_end            PARAMS ((void));
164 
165 /* Hash tables to manage the global pool of method prototypes.  */
166 
167 hash *nst_method_hash_list = 0;
168 hash *cls_method_hash_list = 0;
169 
170 static size_t hash_func				PARAMS ((tree));
171 static void hash_init				PARAMS ((void));
172 static void hash_enter				PARAMS ((hash *, tree));
173 static hash hash_lookup				PARAMS ((hash *, tree));
174 static void hash_add_attr			PARAMS ((hash, tree));
175 static tree lookup_method			PARAMS ((tree, tree));
176 static tree lookup_instance_method_static	PARAMS ((tree, tree));
177 static tree lookup_class_method_static		PARAMS ((tree, tree));
178 static tree add_class				PARAMS ((tree));
179 static void add_category			PARAMS ((tree, tree));
180 
181 enum string_section
182 {
183   class_names,		/* class, category, protocol, module names */
184   meth_var_names,	/* method and variable names */
185   meth_var_types	/* method and variable type descriptors */
186 };
187 
188 static tree add_objc_string			PARAMS ((tree,
189 						       enum string_section));
190 static tree get_objc_string_decl		PARAMS ((tree,
191 						       enum string_section));
192 static tree build_objc_string_decl		PARAMS ((enum string_section));
193 static tree build_selector_reference_decl	PARAMS ((void));
194 
195 /* Protocol additions.  */
196 
197 static tree add_protocol			PARAMS ((tree));
198 static tree lookup_protocol			PARAMS ((tree));
199 static void check_protocol_recursively		PARAMS ((tree, tree));
200 static tree lookup_and_install_protocols	PARAMS ((tree));
201 
202 /* Type encoding.  */
203 
204 static void encode_type_qualifiers		PARAMS ((tree));
205 static void encode_pointer			PARAMS ((tree, int, int));
206 static void encode_array			PARAMS ((tree, int, int));
207 static void encode_aggregate			PARAMS ((tree, int, int));
208 static void encode_bitfield			PARAMS ((int));
209 static void encode_type				PARAMS ((tree, int, int));
210 static void encode_field_decl			PARAMS ((tree, int, int));
211 
212 static void really_start_method			PARAMS ((tree, tree));
213 static int comp_method_with_proto		PARAMS ((tree, tree));
214 static int comp_proto_with_proto		PARAMS ((tree, tree));
215 static tree get_arg_type_list			PARAMS ((tree, int, int));
216 static tree expr_last				PARAMS ((tree));
217 
218 /* Utilities for debugging and error diagnostics.  */
219 
220 static void warn_with_method			PARAMS ((const char *, int, tree));
221 static void error_with_ivar			PARAMS ((const char *, tree, tree));
222 static char *gen_method_decl			PARAMS ((tree, char *));
223 static char *gen_declaration			PARAMS ((tree, char *));
224 static void gen_declaration_1			PARAMS ((tree, char *));
225 static char *gen_declarator			PARAMS ((tree, char *,
226 						       const char *));
227 static int is_complex_decl			PARAMS ((tree));
228 static void adorn_decl				PARAMS ((tree, char *));
229 static void dump_interface			PARAMS ((FILE *, tree));
230 
231 /* Everything else.  */
232 
233 static tree define_decl				PARAMS ((tree, tree));
234 static tree lookup_method_in_protocol_list	PARAMS ((tree, tree, int));
235 static tree lookup_protocol_in_reflist		PARAMS ((tree, tree));
236 static tree create_builtin_decl			PARAMS ((enum tree_code,
237 						       tree, const char *));
238 static void setup_string_decl			PARAMS ((void));
239 static void build_string_class_template		PARAMS ((void));
240 static tree my_build_string			PARAMS ((int, const char *));
241 static void build_objc_symtab_template		PARAMS ((void));
242 static tree init_def_list			PARAMS ((tree));
243 static tree init_objc_symtab			PARAMS ((tree));
244 static void forward_declare_categories		PARAMS ((void));
245 static void generate_objc_symtab_decl		PARAMS ((void));
246 static tree build_selector			PARAMS ((tree));
247 static tree build_typed_selector_reference     	PARAMS ((tree, tree));
248 static tree build_selector_reference		PARAMS ((tree));
249 static tree build_class_reference_decl		PARAMS ((void));
250 static void add_class_reference			PARAMS ((tree));
251 static tree build_protocol_template		PARAMS ((void));
252 static tree build_descriptor_table_initializer	PARAMS ((tree, tree));
253 static tree build_method_prototype_list_template PARAMS ((tree, int));
254 static tree build_method_prototype_template	PARAMS ((void));
255 static int forwarding_offset			PARAMS ((tree));
256 static tree encode_method_prototype		PARAMS ((tree, tree));
257 static tree generate_descriptor_table		PARAMS ((tree, const char *,
258 						       int, tree, tree));
259 static void generate_method_descriptors		PARAMS ((tree));
260 static tree build_tmp_function_decl		PARAMS ((void));
261 static void hack_method_prototype		PARAMS ((tree, tree));
262 static void generate_protocol_references	PARAMS ((tree));
263 static void generate_protocols			PARAMS ((void));
264 static void check_ivars				PARAMS ((tree, tree));
265 static tree build_ivar_list_template		PARAMS ((tree, int));
266 static tree build_method_list_template		PARAMS ((tree, int));
267 static tree build_ivar_list_initializer		PARAMS ((tree, tree));
268 static tree generate_ivars_list			PARAMS ((tree, const char *,
269 						       int, tree));
270 static tree build_dispatch_table_initializer	PARAMS ((tree, tree));
271 static tree generate_dispatch_table		PARAMS ((tree, const char *,
272 						       int, tree));
273 static tree build_shared_structure_initializer	PARAMS ((tree, tree, tree, tree,
274 						       tree, int, tree, tree,
275 						       tree));
276 static void generate_category			PARAMS ((tree));
277 static int is_objc_type_qualifier		PARAMS ((tree));
278 static tree adjust_type_for_id_default		PARAMS ((tree));
279 static tree check_duplicates			PARAMS ((hash));
280 static tree receiver_is_class_object		PARAMS ((tree));
281 static int check_methods			PARAMS ((tree, tree, int));
282 static int conforms_to_protocol			PARAMS ((tree, tree));
283 static void check_protocol			PARAMS ((tree, const char *,
284 						       const char *));
285 static void check_protocols			PARAMS ((tree, const char *,
286 						       const char *));
287 static tree encode_method_def			PARAMS ((tree));
288 static void gen_declspecs			PARAMS ((tree, char *, int));
289 static void generate_classref_translation_entry	PARAMS ((tree));
290 static void handle_class_ref			PARAMS ((tree));
291 static void generate_struct_by_value_array	PARAMS ((void))
292      ATTRIBUTE_NORETURN;
293 static void encode_complete_bitfield		PARAMS ((int, tree, int));
294 
295 /*** Private Interface (data) ***/
296 
297 /* Reserved tag definitions.  */
298 
299 #define TYPE_ID			"id"
300 #define TAG_OBJECT		"objc_object"
301 #define TAG_CLASS		"objc_class"
302 #define TAG_SUPER		"objc_super"
303 #define TAG_SELECTOR		"objc_selector"
304 
305 #define UTAG_CLASS		"_objc_class"
306 #define UTAG_IVAR		"_objc_ivar"
307 #define UTAG_IVAR_LIST		"_objc_ivar_list"
308 #define UTAG_METHOD		"_objc_method"
309 #define UTAG_METHOD_LIST	"_objc_method_list"
310 #define UTAG_CATEGORY		"_objc_category"
311 #define UTAG_MODULE		"_objc_module"
312 #define UTAG_SYMTAB		"_objc_symtab"
313 #define UTAG_SUPER		"_objc_super"
314 #define UTAG_SELECTOR		"_objc_selector"
315 
316 #define UTAG_PROTOCOL		"_objc_protocol"
317 #define UTAG_METHOD_PROTOTYPE	"_objc_method_prototype"
318 #define UTAG_METHOD_PROTOTYPE_LIST "_objc__method_prototype_list"
319 
320 /* Note that the string object global name is only needed for the
321    NeXT runtime.  */
322 #define STRING_OBJECT_GLOBAL_NAME "_NSConstantStringClassReference"
323 
324 #define PROTOCOL_OBJECT_CLASS_NAME "Protocol"
325 
326 static const char *TAG_GETCLASS;
327 static const char *TAG_GETMETACLASS;
328 static const char *TAG_MSGSEND;
329 static const char *TAG_MSGSENDSUPER;
330 static const char *TAG_EXECCLASS;
331 static const char *default_constant_string_class_name;
332 
333 /* The OCTI_... enumeration itself is in objc/objc-act.h.  */
334 tree objc_global_trees[OCTI_MAX];
335 
336 static void handle_impent			PARAMS ((struct imp_entry *));
337 
338 struct imp_entry *imp_list = 0;
339 int imp_count = 0;	/* `@implementation' */
340 int cat_count = 0;	/* `@category' */
341 
342 static int  method_slot = 0;	/* Used by start_method_def, */
343 
344 #define BUFSIZE		1024
345 
346 static char *errbuf;	/* Buffer for error diagnostics */
347 
348 /* Data imported from tree.c.  */
349 
350 extern enum debug_info_type write_symbols;
351 
352 /* Data imported from toplev.c.  */
353 
354 extern const char *dump_base_name;
355 
356 static int flag_typed_selectors;
357 
358 FILE *gen_declaration_file;
359 
360 /* Tells "encode_pointer/encode_aggregate" whether we are generating
361    type descriptors for instance variables (as opposed to methods).
362    Type descriptors for instance variables contain more information
363    than methods (for static typing and embedded structures).  */
364 
365 static int generating_instance_variables = 0;
366 
367 /* Some platforms pass small structures through registers versus
368    through an invisible pointer.  Determine at what size structure is
369    the transition point between the two possibilities.  */
370 
371 static void
generate_struct_by_value_array()372 generate_struct_by_value_array ()
373 {
374   tree type;
375   tree field_decl, field_decl_chain;
376   int i, j;
377   int aggregate_in_mem[32];
378   int found = 0;
379 
380   /* Presumably no platform passes 32 byte structures in a register.  */
381   for (i = 1; i < 32; i++)
382     {
383       char buffer[5];
384 
385       /* Create an unnamed struct that has `i' character components */
386       type = start_struct (RECORD_TYPE, NULL_TREE);
387 
388       strcpy (buffer, "c1");
389       field_decl = create_builtin_decl (FIELD_DECL,
390 					char_type_node,
391 					buffer);
392       field_decl_chain = field_decl;
393 
394       for (j = 1; j < i; j++)
395 	{
396 	  sprintf (buffer, "c%d", j + 1);
397 	  field_decl = create_builtin_decl (FIELD_DECL,
398 					    char_type_node,
399 					    buffer);
400 	  chainon (field_decl_chain, field_decl);
401 	}
402       finish_struct (type, field_decl_chain, NULL_TREE);
403 
404       aggregate_in_mem[i] = aggregate_value_p (type);
405       if (!aggregate_in_mem[i])
406 	found = 1;
407     }
408 
409   /* We found some structures that are returned in registers instead of memory
410      so output the necessary data.  */
411   if (found)
412     {
413       for (i = 31; i >= 0;  i--)
414 	if (!aggregate_in_mem[i])
415 	  break;
416       printf ("#define OBJC_MAX_STRUCT_BY_VALUE %d\n\n", i);
417 
418       /* The first member of the structure is always 0 because we don't handle
419 	 structures with 0 members */
420       printf ("static int struct_forward_array[] = {\n  0");
421 
422       for (j = 1; j <= i; j++)
423 	printf (", %d", aggregate_in_mem[j]);
424       printf ("\n};\n");
425     }
426 
427   exit (0);
428 }
429 
430 const char *
objc_init(filename)431 objc_init (filename)
432      const char *filename;
433 {
434   filename = c_objc_common_init (filename);
435   if (filename == NULL)
436     return filename;
437 
438   /* Force the line number back to 0; check_newline will have
439      raised it to 1, which will make the builtin functions appear
440      not to be built in.  */
441   lineno = 0;
442 
443   /* If gen_declaration desired, open the output file.  */
444   if (flag_gen_declaration)
445     {
446       register char * const dumpname = concat (dump_base_name, ".decl", NULL);
447       gen_declaration_file = fopen (dumpname, "w");
448       if (gen_declaration_file == 0)
449 	fatal_io_error ("can't open %s", dumpname);
450       free (dumpname);
451     }
452 
453   if (flag_next_runtime)
454     {
455       TAG_GETCLASS = "objc_getClass";
456       TAG_GETMETACLASS = "objc_getMetaClass";
457       TAG_MSGSEND = "objc_msgSend";
458       TAG_MSGSENDSUPER = "objc_msgSendSuper";
459       TAG_EXECCLASS = "__objc_execClass";
460       default_constant_string_class_name = "NSConstantString";
461     }
462   else
463     {
464       TAG_GETCLASS = "objc_get_class";
465       TAG_GETMETACLASS = "objc_get_meta_class";
466       TAG_MSGSEND = "objc_msg_lookup";
467       TAG_MSGSENDSUPER = "objc_msg_lookup_super";
468       TAG_EXECCLASS = "__objc_exec_class";
469       default_constant_string_class_name = "NXConstantString";
470       flag_typed_selectors = 1;
471     }
472 
473   objc_ellipsis_node = make_node (ERROR_MARK);
474 
475   init_objc ();
476 
477   if (print_struct_values)
478     generate_struct_by_value_array ();
479 
480   return filename;
481 }
482 
483 void
finish_file()484 finish_file ()
485 {
486   c_objc_common_finish_file ();
487 
488   /* Finalize Objective-C runtime data.  No need to generate tables
489      and code if only checking syntax.  */
490   if (!flag_syntax_only)
491     finish_objc ();
492 
493   if (gen_declaration_file)
494     fclose (gen_declaration_file);
495 }
496 
497 static tree
define_decl(declarator,declspecs)498 define_decl (declarator, declspecs)
499      tree declarator;
500      tree declspecs;
501 {
502   tree decl = start_decl (declarator, declspecs, 0, NULL_TREE);
503   finish_decl (decl, NULL_TREE, NULL_TREE);
504   return decl;
505 }
506 
507 /* Return 1 if LHS and RHS are compatible types for assignment or
508    various other operations.  Return 0 if they are incompatible, and
509    return -1 if we choose to not decide.  When the operation is
510    REFLEXIVE, check for compatibility in either direction.
511 
512    For statically typed objects, an assignment of the form `a' = `b'
513    is permitted if:
514 
515    `a' is of type "id",
516    `a' and `b' are the same class type, or
517    `a' and `b' are of class types A and B such that B is a descendant of A.  */
518 
519 static tree
lookup_method_in_protocol_list(rproto_list,sel_name,class_meth)520 lookup_method_in_protocol_list (rproto_list, sel_name, class_meth)
521    tree rproto_list;
522    tree sel_name;
523    int class_meth;
524 {
525    tree rproto, p;
526    tree fnd = 0;
527 
528    for (rproto = rproto_list; rproto; rproto = TREE_CHAIN (rproto))
529      {
530         p = TREE_VALUE (rproto);
531 
532 	if (TREE_CODE (p) == PROTOCOL_INTERFACE_TYPE)
533 	  {
534 	    if ((fnd = lookup_method (class_meth
535 				      ? PROTOCOL_CLS_METHODS (p)
536 				      : PROTOCOL_NST_METHODS (p), sel_name)))
537 	      ;
538 	    else if (PROTOCOL_LIST (p))
539 	      fnd = lookup_method_in_protocol_list (PROTOCOL_LIST (p),
540 						    sel_name, class_meth);
541 	  }
542 	else
543           {
544 	    ; /* An identifier...if we could not find a protocol.  */
545           }
546 
547 	if (fnd)
548 	  return fnd;
549      }
550 
551    return 0;
552 }
553 
554 static tree
lookup_protocol_in_reflist(rproto_list,lproto)555 lookup_protocol_in_reflist (rproto_list, lproto)
556      tree rproto_list;
557      tree lproto;
558 {
559   tree rproto, p;
560 
561   /* Make sure the protocol is supported by the object on the rhs.  */
562   if (TREE_CODE (lproto) == PROTOCOL_INTERFACE_TYPE)
563     {
564       tree fnd = 0;
565       for (rproto = rproto_list; rproto; rproto = TREE_CHAIN (rproto))
566 	{
567 	  p = TREE_VALUE (rproto);
568 
569 	  if (TREE_CODE (p) == PROTOCOL_INTERFACE_TYPE)
570 	    {
571 	      if (lproto == p)
572 		fnd = lproto;
573 
574 	      else if (PROTOCOL_LIST (p))
575 		fnd = lookup_protocol_in_reflist (PROTOCOL_LIST (p), lproto);
576 	    }
577 
578 	  if (fnd)
579 	    return fnd;
580 	}
581     }
582   else
583     {
584       ; /* An identifier...if we could not find a protocol.  */
585     }
586 
587   return 0;
588 }
589 
590 /* Return 1 if LHS and RHS are compatible types for assignment or
591    various other operations.  Return 0 if they are incompatible, and
592    return -1 if we choose to not decide (because the types are really
593    just C types, not ObjC specific ones).  When the operation is
594    REFLEXIVE (typically comparisons), check for compatibility in
595    either direction; when it's not (typically assignments), don't.
596 
597    This function is called in two cases: when both lhs and rhs are
598    pointers to records (in which case we check protocols too), and
599    when both lhs and rhs are records (in which case we check class
600    inheritance only).
601 
602    Warnings about classes/protocols not implementing a protocol are
603    emitted here (multiple of those warnings might be emitted for a
604    single line!); generic warnings about incompatible assignments and
605    lacks of casts in comparisons are/must be emitted by the caller if
606    we return 0.
607 */
608 
609 int
objc_comptypes(lhs,rhs,reflexive)610 objc_comptypes (lhs, rhs, reflexive)
611      tree lhs;
612      tree rhs;
613      int reflexive;
614 {
615   /* New clause for protocols.  */
616 
617   /* Here we manage the case of a POINTER_TYPE = POINTER_TYPE.  We only
618      manage the ObjC ones, and leave the rest to the C code.  */
619   if (TREE_CODE (lhs) == POINTER_TYPE
620       && TREE_CODE (TREE_TYPE (lhs)) == RECORD_TYPE
621       && TREE_CODE (rhs) == POINTER_TYPE
622       && TREE_CODE (TREE_TYPE (rhs)) == RECORD_TYPE)
623     {
624       int lhs_is_proto = IS_PROTOCOL_QUALIFIED_ID (lhs);
625       int rhs_is_proto = IS_PROTOCOL_QUALIFIED_ID (rhs);
626 
627       if (lhs_is_proto)
628         {
629 	  tree lproto, lproto_list = TYPE_PROTOCOL_LIST (lhs);
630 	  tree rproto, rproto_list;
631 	  tree p;
632 
633 	  /* <Protocol> = <Protocol>  */
634 	  if (rhs_is_proto)
635 	    {
636 	      rproto_list = TYPE_PROTOCOL_LIST (rhs);
637 
638 	      if (!reflexive)
639 		{
640 		  /* An assignment between objects of type 'id
641 		     <Protocol>'; make sure the protocol on the lhs is
642 		     supported by the object on the rhs.  */
643 		  for (lproto = lproto_list; lproto;
644 		       lproto = TREE_CHAIN (lproto))
645 		    {
646 		      p = TREE_VALUE (lproto);
647 		      rproto = lookup_protocol_in_reflist (rproto_list, p);
648 
649 		      if (!rproto)
650 			warning
651 			  ("object does not conform to the `%s' protocol",
652 			   IDENTIFIER_POINTER (PROTOCOL_NAME (p)));
653 		    }
654 		  return 1;
655 		}
656 	      else
657 		{
658 		  /* Obscure case - a comparison between two objects
659 		     of type 'id <Protocol>'.  Check that either the
660 		     protocol on the lhs is supported by the object on
661 		     the rhs, or viceversa.  */
662 
663 		  /* Check if the protocol on the lhs is supported by the
664 		     object on the rhs.  */
665 		  for (lproto = lproto_list; lproto;
666 		       lproto = TREE_CHAIN (lproto))
667 		    {
668 		      p = TREE_VALUE (lproto);
669 		      rproto = lookup_protocol_in_reflist (rproto_list, p);
670 
671 		      if (!rproto)
672 			{
673 			  /* Check failed - check if the protocol on the rhs
674 			     is supported by the object on the lhs.  */
675 			  for (rproto = rproto_list; rproto;
676 			       rproto = TREE_CHAIN (rproto))
677 			    {
678 			      p = TREE_VALUE (rproto);
679 			      lproto = lookup_protocol_in_reflist (lproto_list,
680 								   p);
681 
682 			      if (!lproto)
683 				{
684 				  /* This check failed too: incompatible  */
685 				  return 0;
686 				}
687 			    }
688 			  return 1;
689 			}
690 		    }
691 		  return 1;
692 		}
693 	    }
694 	  /* <Protocol> = <class> *  */
695 	  else if (TYPED_OBJECT (TREE_TYPE (rhs)))
696 	    {
697 	      tree rname = TYPE_NAME (TREE_TYPE (rhs));
698 	      tree rinter;
699 
700 	      /* Make sure the protocol is supported by the object on
701 		 the rhs.  */
702 	      for (lproto = lproto_list; lproto; lproto = TREE_CHAIN (lproto))
703 		{
704 		  p = TREE_VALUE (lproto);
705 		  rproto = 0;
706 		  rinter = lookup_interface (rname);
707 
708 		  while (rinter && !rproto)
709 		    {
710 		      tree cat;
711 
712 		      rproto_list = CLASS_PROTOCOL_LIST (rinter);
713 		      rproto = lookup_protocol_in_reflist (rproto_list, p);
714 		      /* If the underlying ObjC class does not have
715 			 the protocol we're looking for, check for "one-off"
716 			 protocols (e.g., `NSObject<MyProt> *foo;') attached
717 			 to the rhs.  */
718 		      if (!rproto)
719 			{
720 			  rproto_list = TYPE_PROTOCOL_LIST (TREE_TYPE (rhs));
721 			  rproto = lookup_protocol_in_reflist (rproto_list, p);
722 			}
723 
724 		      /* Check for protocols adopted by categories.  */
725 		      cat = CLASS_CATEGORY_LIST (rinter);
726 		      while (cat && !rproto)
727 			{
728 			  rproto_list = CLASS_PROTOCOL_LIST (cat);
729 			  rproto = lookup_protocol_in_reflist (rproto_list, p);
730 			  cat = CLASS_CATEGORY_LIST (cat);
731 			}
732 
733 		      rinter = lookup_interface (CLASS_SUPER_NAME (rinter));
734 		    }
735 
736 		  if (!rproto)
737 		    warning ("class `%s' does not implement the `%s' protocol",
738 			     IDENTIFIER_POINTER (TYPE_NAME (TREE_TYPE (rhs))),
739 			     IDENTIFIER_POINTER (PROTOCOL_NAME (p)));
740 		}
741 	      return 1;
742 	    }
743 	  /* <Protocol> = id */
744 	  else if (TYPE_NAME (TREE_TYPE (rhs)) == objc_object_id)
745 	    {
746 	      return 1;
747 	    }
748 	  /* <Protocol> = Class */
749 	  else if (TYPE_NAME (TREE_TYPE (rhs)) == objc_class_id)
750 	    {
751 	      return 0;
752 	    }
753 	  /* <Protocol> = ?? : let comptypes decide.  */
754           return -1;
755         }
756       else if (rhs_is_proto)
757 	{
758 	  /* <class> * = <Protocol> */
759 	  if (TYPED_OBJECT (TREE_TYPE (lhs)))
760 	    {
761 	      if (reflexive)
762 		{
763 		  tree rname = TYPE_NAME (TREE_TYPE (lhs));
764 		  tree rinter;
765 		  tree rproto, rproto_list = TYPE_PROTOCOL_LIST (rhs);
766 
767 		  /* Make sure the protocol is supported by the object on
768 		     the lhs.  */
769 		  for (rproto = rproto_list; rproto;
770 		       rproto = TREE_CHAIN (rproto))
771 		    {
772 		      tree p = TREE_VALUE (rproto);
773 		      tree lproto = 0;
774 		      rinter = lookup_interface (rname);
775 
776 		      while (rinter && !lproto)
777 			{
778 			  tree cat;
779 
780 			  tree lproto_list = CLASS_PROTOCOL_LIST (rinter);
781 			  lproto = lookup_protocol_in_reflist (lproto_list, p);
782 			  /* If the underlying ObjC class does not
783 			     have the protocol we're looking for,
784 			     check for "one-off" protocols (e.g.,
785 			     `NSObject<MyProt> *foo;') attached to the
786 			     lhs.  */
787 			  if (!lproto)
788 			    {
789 			      lproto_list = TYPE_PROTOCOL_LIST
790 				(TREE_TYPE (lhs));
791 			      lproto = lookup_protocol_in_reflist
792 				(lproto_list, p);
793 			    }
794 
795 			  /* Check for protocols adopted by categories.  */
796 			  cat = CLASS_CATEGORY_LIST (rinter);
797 			  while (cat && !lproto)
798 			    {
799 			      lproto_list = CLASS_PROTOCOL_LIST (cat);
800 			      lproto = lookup_protocol_in_reflist (lproto_list,
801 								   p);
802 			      cat = CLASS_CATEGORY_LIST (cat);
803 			    }
804 
805 			  rinter = lookup_interface (CLASS_SUPER_NAME
806 						     (rinter));
807 			}
808 
809 		      if (!lproto)
810 			warning ("class `%s' does not implement the `%s' protocol",
811 				 IDENTIFIER_POINTER (TYPE_NAME
812 						     (TREE_TYPE (lhs))),
813 				 IDENTIFIER_POINTER (PROTOCOL_NAME (p)));
814 		    }
815 		  return 1;
816 		}
817 	      else
818 		return 0;
819 	    }
820 	  /* id = <Protocol> */
821 	  else if (TYPE_NAME (TREE_TYPE (lhs)) == objc_object_id)
822 	    {
823 	      return 1;
824 	    }
825 	  /* Class = <Protocol> */
826 	  else if (TYPE_NAME (TREE_TYPE (lhs)) == objc_class_id)
827 	    {
828 	      return 0;
829 	    }
830 	  /* ??? = <Protocol> : let comptypes decide */
831 	  else
832 	    {
833 	      return -1;
834 	    }
835 	}
836       else
837 	{
838 	  /* Attention: we shouldn't defer to comptypes here.  One bad
839 	     side effect would be that we might loose the REFLEXIVE
840 	     information.
841 	  */
842 	  lhs = TREE_TYPE (lhs);
843 	  rhs = TREE_TYPE (rhs);
844 	}
845     }
846 
847   if (TREE_CODE (lhs) != RECORD_TYPE || TREE_CODE (rhs) != RECORD_TYPE)
848     {
849       /* Nothing to do with ObjC - let immediately comptypes take
850 	 responsibility for checking.  */
851       return -1;
852     }
853 
854   /* `id' = `<class> *' `<class> *' = `id': always allow it.
855      Please note that
856      'Object *o = [[Object alloc] init]; falls
857      in the case <class> * = `id'.
858   */
859   if ((TYPE_NAME (lhs) == objc_object_id && TYPED_OBJECT (rhs))
860       || (TYPE_NAME (rhs) == objc_object_id && TYPED_OBJECT (lhs)))
861     return 1;
862 
863   /* `id' = `Class', `Class' = `id' */
864 
865   else if ((TYPE_NAME (lhs) == objc_object_id
866 	    && TYPE_NAME (rhs) == objc_class_id)
867 	   || (TYPE_NAME (lhs) == objc_class_id
868 	       && TYPE_NAME (rhs) == objc_object_id))
869     return 1;
870 
871   /* `<class> *' = `<class> *' */
872 
873   else if (TYPED_OBJECT (lhs) && TYPED_OBJECT (rhs))
874     {
875       tree lname = TYPE_NAME (lhs);
876       tree rname = TYPE_NAME (rhs);
877       tree inter;
878 
879       if (lname == rname)
880 	return 1;
881 
882       /* If the left hand side is a super class of the right hand side,
883 	 allow it.  */
884       for (inter = lookup_interface (rname); inter;
885 	   inter = lookup_interface (CLASS_SUPER_NAME (inter)))
886 	if (lname == CLASS_SUPER_NAME (inter))
887 	  return 1;
888 
889       /* Allow the reverse when reflexive.  */
890       if (reflexive)
891 	for (inter = lookup_interface (lname); inter;
892 	     inter = lookup_interface (CLASS_SUPER_NAME (inter)))
893 	  if (rname == CLASS_SUPER_NAME (inter))
894 	    return 1;
895 
896       return 0;
897     }
898   else
899     /* Not an ObjC type - let comptypes do the check.  */
900     return -1;
901 }
902 
903 /* Called from c-decl.c before all calls to rest_of_decl_compilation.  */
904 
905 void
objc_check_decl(decl)906 objc_check_decl (decl)
907      tree decl;
908 {
909   tree type = TREE_TYPE (decl);
910 
911   if (TREE_CODE (type) == RECORD_TYPE
912       && TREE_STATIC_TEMPLATE (type)
913       && type != constant_string_type)
914     error_with_decl (decl, "`%s' cannot be statically allocated");
915 }
916 
917 /* Implement static typing.  At this point, we know we have an interface.  */
918 
919 tree
get_static_reference(interface,protocols)920 get_static_reference (interface, protocols)
921      tree interface;
922      tree protocols;
923 {
924   tree type = xref_tag (RECORD_TYPE, interface);
925 
926   if (protocols)
927     {
928       tree t, m = TYPE_MAIN_VARIANT (type);
929 
930       t = copy_node (type);
931 
932       /* Add this type to the chain of variants of TYPE.  */
933       TYPE_NEXT_VARIANT (t) = TYPE_NEXT_VARIANT (m);
934       TYPE_NEXT_VARIANT (m) = t;
935 
936       /* Look up protocols and install in lang specific list.  Note
937 	 that the protocol list can have a different lifetime than T!  */
938       TYPE_PROTOCOL_LIST (t) = lookup_and_install_protocols (protocols);
939 
940       /* This forces a new pointer type to be created later
941 	 (in build_pointer_type)...so that the new template
942 	 we just created will actually be used...what a hack!  */
943       if (TYPE_POINTER_TO (t))
944 	TYPE_POINTER_TO (t) = NULL_TREE;
945 
946       type = t;
947     }
948 
949   return type;
950 }
951 
952 tree
get_object_reference(protocols)953 get_object_reference (protocols)
954      tree protocols;
955 {
956   tree type_decl = lookup_name (objc_id_id);
957   tree type;
958 
959   if (type_decl && TREE_CODE (type_decl) == TYPE_DECL)
960     {
961       type = TREE_TYPE (type_decl);
962       if (TYPE_MAIN_VARIANT (type) != id_type)
963 	warning ("unexpected type for `id' (%s)",
964 		 gen_declaration (type, errbuf));
965     }
966   else
967     {
968       error ("undefined type `id', please import <objc/objc.h>");
969       return error_mark_node;
970     }
971 
972   /* This clause creates a new pointer type that is qualified with
973      the protocol specification...this info is used later to do more
974      elaborate type checking.  */
975 
976   if (protocols)
977     {
978       tree t, m = TYPE_MAIN_VARIANT (type);
979 
980       t = copy_node (type);
981 
982       /* Add this type to the chain of variants of TYPE.  */
983       TYPE_NEXT_VARIANT (t) = TYPE_NEXT_VARIANT (m);
984       TYPE_NEXT_VARIANT (m) = t;
985 
986       /* Look up protocols...and install in lang specific list */
987       TYPE_PROTOCOL_LIST (t) = lookup_and_install_protocols (protocols);
988 
989       /* This forces a new pointer type to be created later
990 	 (in build_pointer_type)...so that the new template
991 	 we just created will actually be used...what a hack!  */
992       if (TYPE_POINTER_TO (t))
993 	TYPE_POINTER_TO (t) = NULL_TREE;
994 
995       type = t;
996     }
997   return type;
998 }
999 
1000 /* Check for circular dependencies in protocols.  The arguments are
1001    PROTO, the protocol to check, and LIST, a list of protocol it
1002    conforms to.  */
1003 
1004 static void
check_protocol_recursively(proto,list)1005 check_protocol_recursively (proto, list)
1006      tree proto;
1007      tree list;
1008 {
1009   tree p;
1010 
1011   for (p = list; p; p = TREE_CHAIN (p))
1012     {
1013       tree pp = TREE_VALUE (p);
1014 
1015       if (TREE_CODE (pp) == IDENTIFIER_NODE)
1016 	pp = lookup_protocol (pp);
1017 
1018       if (pp == proto)
1019 	fatal_error ("protocol `%s' has circular dependency",
1020 		     IDENTIFIER_POINTER (PROTOCOL_NAME (pp)));
1021       if (pp)
1022 	check_protocol_recursively (proto, PROTOCOL_LIST (pp));
1023     }
1024 }
1025 
1026 static tree
lookup_and_install_protocols(protocols)1027 lookup_and_install_protocols (protocols)
1028      tree protocols;
1029 {
1030   tree proto;
1031   tree prev = NULL;
1032   tree return_value = protocols;
1033 
1034   for (proto = protocols; proto; proto = TREE_CHAIN (proto))
1035     {
1036       tree ident = TREE_VALUE (proto);
1037       tree p = lookup_protocol (ident);
1038 
1039       if (!p)
1040 	{
1041 	  error ("cannot find protocol declaration for `%s'",
1042 		 IDENTIFIER_POINTER (ident));
1043 	  if (prev)
1044 	    TREE_CHAIN (prev) = TREE_CHAIN (proto);
1045 	  else
1046 	    return_value = TREE_CHAIN (proto);
1047 	}
1048       else
1049 	{
1050 	  /* Replace identifier with actual protocol node.  */
1051 	  TREE_VALUE (proto) = p;
1052 	  prev = proto;
1053 	}
1054     }
1055 
1056   return return_value;
1057 }
1058 
1059 /* Create and push a decl for a built-in external variable or field NAME.
1060    CODE says which.
1061    TYPE is its data type.  */
1062 
1063 static tree
create_builtin_decl(code,type,name)1064 create_builtin_decl (code, type, name)
1065      enum tree_code code;
1066      tree type;
1067      const char *name;
1068 {
1069   tree decl = build_decl (code, get_identifier (name), type);
1070 
1071   if (code == VAR_DECL)
1072     {
1073       TREE_STATIC (decl) = 1;
1074       make_decl_rtl (decl, 0);
1075       pushdecl (decl);
1076     }
1077 
1078   DECL_ARTIFICIAL (decl) = 1;
1079   return decl;
1080 }
1081 
1082 /* Find the decl for the constant string class.  */
1083 
1084 static void
setup_string_decl()1085 setup_string_decl ()
1086 {
1087   if (!string_class_decl)
1088     {
1089       if (!constant_string_global_id)
1090 	constant_string_global_id = get_identifier (STRING_OBJECT_GLOBAL_NAME);
1091       string_class_decl = lookup_name (constant_string_global_id);
1092     }
1093 }
1094 
1095 /* Purpose: "play" parser, creating/installing representations
1096    of the declarations that are required by Objective-C.
1097 
1098    Model:
1099 
1100  	type_spec--------->sc_spec
1101  	(tree_list)        (tree_list)
1102  	    |                  |
1103  	    |                  |
1104  	identifier_node    identifier_node  */
1105 
1106 static void
synth_module_prologue()1107 synth_module_prologue ()
1108 {
1109   tree temp_type;
1110   tree super_p;
1111 
1112   /* Defined in `objc.h' */
1113   objc_object_id = get_identifier (TAG_OBJECT);
1114 
1115   objc_object_reference = xref_tag (RECORD_TYPE, objc_object_id);
1116 
1117   id_type = build_pointer_type (objc_object_reference);
1118 
1119   objc_id_id = get_identifier (TYPE_ID);
1120   objc_class_id = get_identifier (TAG_CLASS);
1121 
1122   objc_class_type = build_pointer_type (xref_tag (RECORD_TYPE, objc_class_id));
1123   protocol_type = build_pointer_type (xref_tag (RECORD_TYPE,
1124 				get_identifier (PROTOCOL_OBJECT_CLASS_NAME)));
1125 
1126   /* Declare type of selector-objects that represent an operation name.  */
1127 
1128   /* `struct objc_selector *' */
1129   selector_type
1130     = build_pointer_type (xref_tag (RECORD_TYPE,
1131 				    get_identifier (TAG_SELECTOR)));
1132 
1133   /* Forward declare type, or else the prototype for msgSendSuper will
1134      complain.  */
1135 
1136   super_p = build_pointer_type (xref_tag (RECORD_TYPE,
1137 					  get_identifier (TAG_SUPER)));
1138 
1139 
1140   /* id objc_msgSend (id, SEL, ...); */
1141 
1142   temp_type
1143     = build_function_type (id_type,
1144 			   tree_cons (NULL_TREE, id_type,
1145 				      tree_cons (NULL_TREE, selector_type,
1146 						 NULL_TREE)));
1147 
1148   if (! flag_next_runtime)
1149     {
1150       umsg_decl = build_decl (FUNCTION_DECL,
1151 			      get_identifier (TAG_MSGSEND), temp_type);
1152       DECL_EXTERNAL (umsg_decl) = 1;
1153       TREE_PUBLIC (umsg_decl) = 1;
1154       DECL_INLINE (umsg_decl) = 1;
1155       DECL_ARTIFICIAL (umsg_decl) = 1;
1156 
1157       make_decl_rtl (umsg_decl, NULL);
1158       pushdecl (umsg_decl);
1159     }
1160   else
1161     umsg_decl = builtin_function (TAG_MSGSEND, temp_type, 0, NOT_BUILT_IN,
1162 				  NULL, NULL_TREE);
1163 
1164   /* id objc_msgSendSuper (struct objc_super *, SEL, ...); */
1165 
1166   temp_type
1167     = build_function_type (id_type,
1168 			   tree_cons (NULL_TREE, super_p,
1169 				      tree_cons (NULL_TREE, selector_type,
1170 						 NULL_TREE)));
1171 
1172   umsg_super_decl = builtin_function (TAG_MSGSENDSUPER,
1173 				      temp_type, 0, NOT_BUILT_IN,
1174 				      NULL, NULL_TREE);
1175 
1176   /* id objc_getClass (const char *); */
1177 
1178   temp_type = build_function_type (id_type,
1179 			tree_cons (NULL_TREE,
1180 				   const_string_type_node,
1181 				   tree_cons (NULL_TREE, void_type_node,
1182 					      NULL_TREE)));
1183 
1184   objc_get_class_decl
1185     = builtin_function (TAG_GETCLASS, temp_type, 0, NOT_BUILT_IN,
1186 			NULL, NULL_TREE);
1187 
1188   /* id objc_getMetaClass (const char *); */
1189 
1190   objc_get_meta_class_decl
1191     = builtin_function (TAG_GETMETACLASS, temp_type, 0, NOT_BUILT_IN,
1192 			NULL, NULL_TREE);
1193 
1194   /* static SEL _OBJC_SELECTOR_TABLE[]; */
1195 
1196   if (! flag_next_runtime)
1197     {
1198       if (flag_typed_selectors)
1199 	{
1200 	  /* Suppress outputting debug symbols, because
1201 	     dbxout_init hasn'r been called yet.  */
1202 	  enum debug_info_type save_write_symbols = write_symbols;
1203 	  const struct gcc_debug_hooks *const save_hooks = debug_hooks;
1204 	  write_symbols = NO_DEBUG;
1205 	  debug_hooks = &do_nothing_debug_hooks;
1206 
1207 	  build_selector_template ();
1208 	  temp_type = build_array_type (objc_selector_template, NULL_TREE);
1209 
1210 	  write_symbols = save_write_symbols;
1211 	  debug_hooks = save_hooks;
1212 	}
1213       else
1214 	temp_type = build_array_type (selector_type, NULL_TREE);
1215 
1216       layout_type (temp_type);
1217       UOBJC_SELECTOR_TABLE_decl
1218 	= create_builtin_decl (VAR_DECL, temp_type,
1219 			       "_OBJC_SELECTOR_TABLE");
1220 
1221       /* Avoid warning when not sending messages.  */
1222       TREE_USED (UOBJC_SELECTOR_TABLE_decl) = 1;
1223     }
1224 
1225   generate_forward_declaration_to_string_table ();
1226 
1227   /* Forward declare constant_string_id and constant_string_type.  */
1228   if (!constant_string_class_name)
1229     constant_string_class_name = default_constant_string_class_name;
1230 
1231   constant_string_id = get_identifier (constant_string_class_name);
1232   constant_string_type = xref_tag (RECORD_TYPE, constant_string_id);
1233 }
1234 
1235 /* Predefine the following data type:
1236 
1237    struct STRING_OBJECT_CLASS_NAME
1238    {
1239      Object isa;
1240      char *cString;
1241      unsigned int length;
1242    }; */
1243 
1244 static void
build_string_class_template()1245 build_string_class_template ()
1246 {
1247   tree field_decl, field_decl_chain;
1248 
1249   field_decl = create_builtin_decl (FIELD_DECL, id_type, "isa");
1250   field_decl_chain = field_decl;
1251 
1252   field_decl = create_builtin_decl (FIELD_DECL,
1253 				    build_pointer_type (char_type_node),
1254 				    "cString");
1255   chainon (field_decl_chain, field_decl);
1256 
1257   field_decl = create_builtin_decl (FIELD_DECL, unsigned_type_node, "length");
1258   chainon (field_decl_chain, field_decl);
1259 
1260   finish_struct (constant_string_type, field_decl_chain, NULL_TREE);
1261 }
1262 
1263 /* Custom build_string which sets TREE_TYPE!  */
1264 
1265 static tree
my_build_string(len,str)1266 my_build_string (len, str)
1267      int len;
1268      const char *str;
1269 {
1270   return fix_string_type (build_string (len, str));
1271 }
1272 
1273 /* Given a chain of STRING_CST's, build a static instance of
1274    NXConstantString which points at the concatenation of those strings.
1275    We place the string object in the __string_objects section of the
1276    __OBJC segment.  The Objective-C runtime will initialize the isa
1277    pointers of the string objects to point at the NXConstantString
1278    class object.  */
1279 
1280 tree
build_objc_string_object(strings)1281 build_objc_string_object (strings)
1282      tree strings;
1283 {
1284   tree string, initlist, constructor;
1285   int length;
1286 
1287   if (lookup_interface (constant_string_id) == NULL_TREE)
1288     {
1289       error ("cannot find interface declaration for `%s'",
1290 	     IDENTIFIER_POINTER (constant_string_id));
1291       return error_mark_node;
1292     }
1293 
1294   add_class_reference (constant_string_id);
1295 
1296   if (TREE_CHAIN (strings))
1297     {
1298       varray_type vstrings;
1299       VARRAY_TREE_INIT (vstrings, 32, "strings");
1300 
1301       for (; strings ; strings = TREE_CHAIN (strings))
1302 	VARRAY_PUSH_TREE (vstrings, strings);
1303 
1304       string = combine_strings (vstrings);
1305     }
1306   else
1307     string = strings;
1308 
1309   string = fix_string_type (string);
1310 
1311   TREE_SET_CODE (string, STRING_CST);
1312   length = TREE_STRING_LENGTH (string) - 1;
1313 
1314   /* We could not properly create NXConstantString in synth_module_prologue,
1315      because that's called before debugging is initialized.  Do it now.  */
1316   if (TYPE_FIELDS (constant_string_type) == NULL_TREE)
1317     build_string_class_template ();
1318 
1319   /* & ((NXConstantString) { NULL, string, length })  */
1320 
1321   if (flag_next_runtime)
1322     {
1323       /* For the NeXT runtime, we can generate a literal reference
1324 	 to the string class, don't need to run a constructor.  */
1325       setup_string_decl ();
1326       if (string_class_decl == NULL_TREE)
1327 	{
1328 	  error ("cannot find reference tag for class `%s'",
1329 		 IDENTIFIER_POINTER (constant_string_id));
1330 	  return error_mark_node;
1331 	}
1332       initlist = build_tree_list
1333 	(NULL_TREE,
1334 	 copy_node (build_unary_op (ADDR_EXPR, string_class_decl, 0)));
1335     }
1336   else
1337     {
1338       initlist = build_tree_list (NULL_TREE, build_int_2 (0, 0));
1339     }
1340 
1341   initlist
1342     = tree_cons (NULL_TREE, copy_node (build_unary_op (ADDR_EXPR, string, 1)),
1343 		 initlist);
1344   initlist = tree_cons (NULL_TREE, build_int_2 (length, 0), initlist);
1345   constructor = build_constructor (constant_string_type, nreverse (initlist));
1346 
1347   if (!flag_next_runtime)
1348     {
1349       constructor
1350 	= objc_add_static_instance (constructor, constant_string_type);
1351     }
1352 
1353   return (build_unary_op (ADDR_EXPR, constructor, 1));
1354 }
1355 
1356 /* Declare a static instance of CLASS_DECL initialized by CONSTRUCTOR.  */
1357 
1358 static tree
objc_add_static_instance(constructor,class_decl)1359 objc_add_static_instance (constructor, class_decl)
1360      tree constructor, class_decl;
1361 {
1362   static int num_static_inst;
1363   tree *chain, decl;
1364   char buf[256];
1365 
1366   /* Find the list of static instances for the CLASS_DECL.  Create one if
1367      not found.  */
1368   for (chain = &objc_static_instances;
1369        *chain && TREE_VALUE (*chain) != class_decl;
1370        chain = &TREE_CHAIN (*chain));
1371   if (!*chain)
1372     {
1373       *chain = tree_cons (NULL_TREE, class_decl, NULL_TREE);
1374       add_objc_string (TYPE_NAME (class_decl), class_names);
1375     }
1376 
1377   sprintf (buf, "_OBJC_INSTANCE_%d", num_static_inst++);
1378   decl = build_decl (VAR_DECL, get_identifier (buf), class_decl);
1379   DECL_COMMON (decl) = 1;
1380   TREE_STATIC (decl) = 1;
1381   DECL_ARTIFICIAL (decl) = 1;
1382   DECL_INITIAL (decl) = constructor;
1383 
1384   /* We may be writing something else just now.
1385      Postpone till end of input.  */
1386   DECL_DEFER_OUTPUT (decl) = 1;
1387   pushdecl_top_level (decl);
1388   rest_of_decl_compilation (decl, 0, 1, 0);
1389 
1390   /* Add the DECL to the head of this CLASS' list.  */
1391   TREE_PURPOSE (*chain) = tree_cons (NULL_TREE, decl, TREE_PURPOSE (*chain));
1392 
1393   return decl;
1394 }
1395 
1396 /* Build a static constant CONSTRUCTOR
1397    with type TYPE and elements ELTS.  */
1398 
1399 static tree
build_constructor(type,elts)1400 build_constructor (type, elts)
1401      tree type, elts;
1402 {
1403   tree constructor, f, e;
1404 
1405   /* ??? Most of the places that we build constructors, we don't fill in
1406      the type of integers properly.  Convert them all en masse.  */
1407   if (TREE_CODE (type) == ARRAY_TYPE)
1408     {
1409       f = TREE_TYPE (type);
1410       if (TREE_CODE (f) == POINTER_TYPE || TREE_CODE (f) == INTEGER_TYPE)
1411 	for (e = elts; e ; e = TREE_CHAIN (e))
1412 	  TREE_VALUE (e) = convert (f, TREE_VALUE (e));
1413     }
1414   else
1415     {
1416       f = TYPE_FIELDS (type);
1417       for (e = elts; e && f; e = TREE_CHAIN (e), f = TREE_CHAIN (f))
1418 	if (TREE_CODE (TREE_TYPE (f)) == POINTER_TYPE
1419 	    || TREE_CODE (TREE_TYPE (f)) == INTEGER_TYPE)
1420 	  TREE_VALUE (e) = convert (TREE_TYPE (f), TREE_VALUE (e));
1421     }
1422 
1423   constructor = build (CONSTRUCTOR, type, NULL_TREE, elts);
1424   TREE_CONSTANT (constructor) = 1;
1425   TREE_STATIC (constructor) = 1;
1426   TREE_READONLY (constructor) = 1;
1427 
1428   return constructor;
1429 }
1430 
1431 /* Take care of defining and initializing _OBJC_SYMBOLS.  */
1432 
1433 /* Predefine the following data type:
1434 
1435    struct _objc_symtab
1436    {
1437      long sel_ref_cnt;
1438      SEL *refs;
1439      short cls_def_cnt;
1440      short cat_def_cnt;
1441      void *defs[cls_def_cnt + cat_def_cnt];
1442    }; */
1443 
1444 static void
build_objc_symtab_template()1445 build_objc_symtab_template ()
1446 {
1447   tree field_decl, field_decl_chain, index;
1448 
1449   objc_symtab_template
1450     = start_struct (RECORD_TYPE, get_identifier (UTAG_SYMTAB));
1451 
1452   /* long sel_ref_cnt; */
1453 
1454   field_decl = create_builtin_decl (FIELD_DECL,
1455 				    long_integer_type_node,
1456 				    "sel_ref_cnt");
1457   field_decl_chain = field_decl;
1458 
1459   /* SEL *refs; */
1460 
1461   field_decl = create_builtin_decl (FIELD_DECL,
1462 				    build_pointer_type (selector_type),
1463 				    "refs");
1464   chainon (field_decl_chain, field_decl);
1465 
1466   /* short cls_def_cnt; */
1467 
1468   field_decl = create_builtin_decl (FIELD_DECL,
1469 				    short_integer_type_node,
1470 				    "cls_def_cnt");
1471   chainon (field_decl_chain, field_decl);
1472 
1473   /* short cat_def_cnt; */
1474 
1475   field_decl = create_builtin_decl (FIELD_DECL,
1476 				    short_integer_type_node,
1477 				    "cat_def_cnt");
1478   chainon (field_decl_chain, field_decl);
1479 
1480   /* void *defs[cls_def_cnt + cat_def_cnt]; */
1481 
1482   if (!flag_next_runtime)
1483     index = build_index_type (build_int_2 (imp_count + cat_count, 0));
1484   else
1485     index = build_index_type (build_int_2 (imp_count + cat_count - 1,
1486 					   imp_count == 0 && cat_count == 0
1487 					   ? -1 : 0));
1488   field_decl = create_builtin_decl (FIELD_DECL,
1489 				    build_array_type (ptr_type_node, index),
1490 				    "defs");
1491   chainon (field_decl_chain, field_decl);
1492 
1493   finish_struct (objc_symtab_template, field_decl_chain, NULL_TREE);
1494 }
1495 
1496 /* Create the initial value for the `defs' field of _objc_symtab.
1497    This is a CONSTRUCTOR.  */
1498 
1499 static tree
init_def_list(type)1500 init_def_list (type)
1501      tree type;
1502 {
1503   tree expr, initlist = NULL_TREE;
1504   struct imp_entry *impent;
1505 
1506   if (imp_count)
1507     for (impent = imp_list; impent; impent = impent->next)
1508       {
1509 	if (TREE_CODE (impent->imp_context) == CLASS_IMPLEMENTATION_TYPE)
1510 	  {
1511 	    expr = build_unary_op (ADDR_EXPR, impent->class_decl, 0);
1512 	    initlist = tree_cons (NULL_TREE, expr, initlist);
1513 	  }
1514       }
1515 
1516   if (cat_count)
1517     for (impent = imp_list; impent; impent = impent->next)
1518       {
1519 	if (TREE_CODE (impent->imp_context) == CATEGORY_IMPLEMENTATION_TYPE)
1520 	  {
1521 	    expr = build_unary_op (ADDR_EXPR, impent->class_decl, 0);
1522 	    initlist = tree_cons (NULL_TREE, expr, initlist);
1523 	  }
1524       }
1525 
1526   if (!flag_next_runtime)
1527     {
1528       /* statics = { ..., _OBJC_STATIC_INSTANCES, ... }  */
1529       tree expr;
1530 
1531       if (static_instances_decl)
1532 	expr = build_unary_op (ADDR_EXPR, static_instances_decl, 0);
1533       else
1534 	expr = build_int_2 (0, 0);
1535 
1536       initlist = tree_cons (NULL_TREE, expr, initlist);
1537     }
1538 
1539   return build_constructor (type, nreverse (initlist));
1540 }
1541 
1542 /* Construct the initial value for all of _objc_symtab.  */
1543 
1544 static tree
init_objc_symtab(type)1545 init_objc_symtab (type)
1546      tree type;
1547 {
1548   tree initlist;
1549 
1550   /* sel_ref_cnt = { ..., 5, ... } */
1551 
1552   initlist = build_tree_list (NULL_TREE, build_int_2 (0, 0));
1553 
1554   /* refs = { ..., _OBJC_SELECTOR_TABLE, ... } */
1555 
1556   if (flag_next_runtime || ! sel_ref_chain)
1557     initlist = tree_cons (NULL_TREE, build_int_2 (0, 0), initlist);
1558   else
1559     initlist = tree_cons (NULL_TREE,
1560 			  build_unary_op (ADDR_EXPR,
1561 					  UOBJC_SELECTOR_TABLE_decl, 1),
1562 			  initlist);
1563 
1564   /* cls_def_cnt = { ..., 5, ... } */
1565 
1566   initlist = tree_cons (NULL_TREE, build_int_2 (imp_count, 0), initlist);
1567 
1568   /* cat_def_cnt = { ..., 5, ... } */
1569 
1570   initlist = tree_cons (NULL_TREE, build_int_2 (cat_count, 0), initlist);
1571 
1572   /* cls_def = { ..., { &Foo, &Bar, ...}, ... } */
1573 
1574   if (imp_count || cat_count || static_instances_decl)
1575     {
1576 
1577       tree field = TYPE_FIELDS (type);
1578       field = TREE_CHAIN (TREE_CHAIN (TREE_CHAIN (TREE_CHAIN (field))));
1579 
1580       initlist = tree_cons (NULL_TREE, init_def_list (TREE_TYPE (field)),
1581 			    initlist);
1582     }
1583 
1584   return build_constructor (type, nreverse (initlist));
1585 }
1586 
1587 /* Push forward-declarations of all the categories so that
1588    init_def_list can use them in a CONSTRUCTOR.  */
1589 
1590 static void
forward_declare_categories()1591 forward_declare_categories ()
1592 {
1593   struct imp_entry *impent;
1594   tree sav = objc_implementation_context;
1595 
1596   for (impent = imp_list; impent; impent = impent->next)
1597     {
1598       if (TREE_CODE (impent->imp_context) == CATEGORY_IMPLEMENTATION_TYPE)
1599 	{
1600 	  /* Set an invisible arg to synth_id_with_class_suffix.  */
1601 	  objc_implementation_context = impent->imp_context;
1602 	  impent->class_decl
1603 	    = create_builtin_decl (VAR_DECL, objc_category_template,
1604 				   IDENTIFIER_POINTER (synth_id_with_class_suffix ("_OBJC_CATEGORY", objc_implementation_context)));
1605 	}
1606     }
1607   objc_implementation_context = sav;
1608 }
1609 
1610 /* Create the declaration of _OBJC_SYMBOLS, with type `strict _objc_symtab'
1611    and initialized appropriately.  */
1612 
1613 static void
generate_objc_symtab_decl()1614 generate_objc_symtab_decl ()
1615 {
1616   tree sc_spec;
1617 
1618   if (!objc_category_template)
1619     build_category_template ();
1620 
1621   /* forward declare categories */
1622   if (cat_count)
1623     forward_declare_categories ();
1624 
1625   if (!objc_symtab_template)
1626     build_objc_symtab_template ();
1627 
1628   sc_spec = build_tree_list (NULL_TREE, ridpointers[(int) RID_STATIC]);
1629 
1630   UOBJC_SYMBOLS_decl = start_decl (get_identifier ("_OBJC_SYMBOLS"),
1631 				   tree_cons (NULL_TREE,
1632 					      objc_symtab_template, sc_spec),
1633 				   1,
1634 				   NULL_TREE);
1635 
1636   TREE_USED (UOBJC_SYMBOLS_decl) = 1;
1637   DECL_IGNORED_P (UOBJC_SYMBOLS_decl) = 1;
1638   DECL_ARTIFICIAL (UOBJC_SYMBOLS_decl) = 1;
1639   finish_decl (UOBJC_SYMBOLS_decl,
1640 	       init_objc_symtab (TREE_TYPE (UOBJC_SYMBOLS_decl)),
1641 	       NULL_TREE);
1642 }
1643 
1644 static tree
init_module_descriptor(type)1645 init_module_descriptor (type)
1646      tree type;
1647 {
1648   tree initlist, expr;
1649 
1650   /* version = { 1, ... } */
1651 
1652   expr = build_int_2 (OBJC_VERSION, 0);
1653   initlist = build_tree_list (NULL_TREE, expr);
1654 
1655   /* size = { ..., sizeof (struct objc_module), ... } */
1656 
1657   expr = size_in_bytes (objc_module_template);
1658   initlist = tree_cons (NULL_TREE, expr, initlist);
1659 
1660   /* name = { ..., "foo.m", ... } */
1661 
1662   expr = add_objc_string (get_identifier (input_filename), class_names);
1663   initlist = tree_cons (NULL_TREE, expr, initlist);
1664 
1665   /* symtab = { ..., _OBJC_SYMBOLS, ... } */
1666 
1667   if (UOBJC_SYMBOLS_decl)
1668     expr = build_unary_op (ADDR_EXPR, UOBJC_SYMBOLS_decl, 0);
1669   else
1670     expr = build_int_2 (0, 0);
1671   initlist = tree_cons (NULL_TREE, expr, initlist);
1672 
1673   return build_constructor (type, nreverse (initlist));
1674 }
1675 
1676 /* Write out the data structures to describe Objective C classes defined.
1677    If appropriate, compile and output a setup function to initialize them.
1678    Return a symbol_ref to the function to call to initialize the Objective C
1679    data structures for this file (and perhaps for other files also).
1680 
1681    struct objc_module { ... } _OBJC_MODULE = { ... };   */
1682 
1683 static rtx
build_module_descriptor()1684 build_module_descriptor ()
1685 {
1686   tree decl_specs, field_decl, field_decl_chain;
1687 
1688   objc_module_template
1689     = start_struct (RECORD_TYPE, get_identifier (UTAG_MODULE));
1690 
1691   /* Long version; */
1692 
1693   decl_specs = build_tree_list (NULL_TREE, ridpointers[(int) RID_LONG]);
1694   field_decl = get_identifier ("version");
1695   field_decl
1696     = grokfield (input_filename, lineno, field_decl, decl_specs, NULL_TREE);
1697   field_decl_chain = field_decl;
1698 
1699   /* long  size; */
1700 
1701   decl_specs = build_tree_list (NULL_TREE, ridpointers[(int) RID_LONG]);
1702   field_decl = get_identifier ("size");
1703   field_decl
1704     = grokfield (input_filename, lineno, field_decl, decl_specs, NULL_TREE);
1705   chainon (field_decl_chain, field_decl);
1706 
1707   /* char  *name; */
1708 
1709   decl_specs = build_tree_list (NULL_TREE, ridpointers[(int) RID_CHAR]);
1710   field_decl = build1 (INDIRECT_REF, NULL_TREE, get_identifier ("name"));
1711   field_decl
1712     = grokfield (input_filename, lineno, field_decl, decl_specs, NULL_TREE);
1713   chainon (field_decl_chain, field_decl);
1714 
1715   /* struct objc_symtab *symtab; */
1716 
1717   decl_specs = get_identifier (UTAG_SYMTAB);
1718   decl_specs = build_tree_list (NULL_TREE, xref_tag (RECORD_TYPE, decl_specs));
1719   field_decl = build1 (INDIRECT_REF, NULL_TREE, get_identifier ("symtab"));
1720   field_decl
1721     = grokfield (input_filename, lineno, field_decl, decl_specs, NULL_TREE);
1722   chainon (field_decl_chain, field_decl);
1723 
1724   finish_struct (objc_module_template, field_decl_chain, NULL_TREE);
1725 
1726   /* Create an instance of "objc_module".  */
1727 
1728   decl_specs = tree_cons (NULL_TREE, objc_module_template,
1729 			  build_tree_list (NULL_TREE,
1730 					   ridpointers[(int) RID_STATIC]));
1731 
1732   UOBJC_MODULES_decl = start_decl (get_identifier ("_OBJC_MODULES"),
1733 				   decl_specs, 1, NULL_TREE);
1734 
1735   DECL_ARTIFICIAL (UOBJC_MODULES_decl) = 1;
1736   DECL_IGNORED_P (UOBJC_MODULES_decl) = 1;
1737   DECL_CONTEXT (UOBJC_MODULES_decl) = NULL_TREE;
1738 
1739   finish_decl (UOBJC_MODULES_decl,
1740 	       init_module_descriptor (TREE_TYPE (UOBJC_MODULES_decl)),
1741 	       NULL_TREE);
1742 
1743   /* Mark the decl to avoid "defined but not used" warning.  */
1744   DECL_IN_SYSTEM_HEADER (UOBJC_MODULES_decl) = 1;
1745 
1746   /* Generate a constructor call for the module descriptor.
1747      This code was generated by reading the grammar rules
1748      of c-parse.in;  Therefore, it may not be the most efficient
1749      way of generating the requisite code.  */
1750 
1751   if (flag_next_runtime)
1752     return NULL_RTX;
1753 
1754   {
1755     tree parms, execclass_decl, decelerator, void_list_node_1;
1756     tree init_function_name, init_function_decl;
1757 
1758     /* Declare void __objc_execClass (void *); */
1759 
1760     void_list_node_1 = build_tree_list (NULL_TREE, void_type_node);
1761     execclass_decl = build_decl (FUNCTION_DECL,
1762 				 get_identifier (TAG_EXECCLASS),
1763 				 build_function_type (void_type_node,
1764 					tree_cons (NULL_TREE, ptr_type_node,
1765 						   void_list_node_1)));
1766     DECL_EXTERNAL (execclass_decl) = 1;
1767     DECL_ARTIFICIAL (execclass_decl) = 1;
1768     TREE_PUBLIC (execclass_decl) = 1;
1769     pushdecl (execclass_decl);
1770     rest_of_decl_compilation (execclass_decl, 0, 0, 0);
1771     assemble_external (execclass_decl);
1772 
1773     /* void _GLOBAL_$I$<gnyf> () {objc_execClass (&L_OBJC_MODULES);}  */
1774 
1775     init_function_name = get_file_function_name ('I');
1776     start_function (void_list_node_1,
1777 		    build_nt (CALL_EXPR, init_function_name,
1778 			      tree_cons (NULL_TREE, NULL_TREE,
1779 					 void_list_node_1),
1780 			      NULL_TREE),
1781 		    NULL_TREE);
1782     store_parm_decls ();
1783 
1784     init_function_decl = current_function_decl;
1785     TREE_PUBLIC (init_function_decl) = ! targetm.have_ctors_dtors;
1786     TREE_USED (init_function_decl) = 1;
1787     /* Don't let this one be deferred.  */
1788     DECL_INLINE (init_function_decl) = 0;
1789     DECL_UNINLINABLE (init_function_decl) = 1;
1790     current_function_cannot_inline
1791       = "static constructors and destructors cannot be inlined";
1792 
1793     parms
1794       = build_tree_list (NULL_TREE,
1795 			 build_unary_op (ADDR_EXPR, UOBJC_MODULES_decl, 0));
1796     decelerator = build_function_call (execclass_decl, parms);
1797 
1798     c_expand_expr_stmt (decelerator);
1799 
1800     finish_function (0, 0);
1801 
1802     return XEXP (DECL_RTL (init_function_decl), 0);
1803   }
1804 }
1805 
1806 /* extern const char _OBJC_STRINGS[]; */
1807 
1808 static void
generate_forward_declaration_to_string_table()1809 generate_forward_declaration_to_string_table ()
1810 {
1811   tree sc_spec, decl_specs, expr_decl;
1812 
1813   sc_spec = tree_cons (NULL_TREE, ridpointers[(int) RID_EXTERN], NULL_TREE);
1814   decl_specs = tree_cons (NULL_TREE, ridpointers[(int) RID_CHAR], sc_spec);
1815 
1816   expr_decl
1817     = build_nt (ARRAY_REF, get_identifier ("_OBJC_STRINGS"), NULL_TREE);
1818 
1819   UOBJC_STRINGS_decl = define_decl (expr_decl, decl_specs);
1820 }
1821 
1822 /* Return the DECL of the string IDENT in the SECTION.  */
1823 
1824 static tree
get_objc_string_decl(ident,section)1825 get_objc_string_decl (ident, section)
1826      tree ident;
1827      enum string_section section;
1828 {
1829   tree chain;
1830 
1831   if (section == class_names)
1832     chain = class_names_chain;
1833   else if (section == meth_var_names)
1834     chain = meth_var_names_chain;
1835   else if (section == meth_var_types)
1836     chain = meth_var_types_chain;
1837   else
1838     abort ();
1839 
1840   for (; chain != 0; chain = TREE_CHAIN (chain))
1841     if (TREE_VALUE (chain) == ident)
1842       return (TREE_PURPOSE (chain));
1843 
1844   abort ();
1845   return NULL_TREE;
1846 }
1847 
1848 /* Output references to all statically allocated objects.  Return the DECL
1849    for the array built.  */
1850 
1851 static void
generate_static_references()1852 generate_static_references ()
1853 {
1854   tree decls = NULL_TREE, ident, decl_spec, expr_decl, expr = NULL_TREE;
1855   tree class_name, class, decl, initlist;
1856   tree cl_chain, in_chain, type;
1857   int num_inst, num_class;
1858   char buf[256];
1859 
1860   if (flag_next_runtime)
1861     abort ();
1862 
1863   for (cl_chain = objc_static_instances, num_class = 0;
1864        cl_chain; cl_chain = TREE_CHAIN (cl_chain), num_class++)
1865     {
1866       for (num_inst = 0, in_chain = TREE_PURPOSE (cl_chain);
1867 	   in_chain; num_inst++, in_chain = TREE_CHAIN (in_chain));
1868 
1869       sprintf (buf, "_OBJC_STATIC_INSTANCES_%d", num_class);
1870       ident = get_identifier (buf);
1871 
1872       expr_decl = build_nt (ARRAY_REF, ident, NULL_TREE);
1873       decl_spec = tree_cons (NULL_TREE, build_pointer_type (void_type_node),
1874 			     build_tree_list (NULL_TREE,
1875 					      ridpointers[(int) RID_STATIC]));
1876       decl = start_decl (expr_decl, decl_spec, 1, NULL_TREE);
1877       DECL_CONTEXT (decl) = 0;
1878       DECL_ARTIFICIAL (decl) = 1;
1879 
1880       /* Output {class_name, ...}.  */
1881       class = TREE_VALUE (cl_chain);
1882       class_name = get_objc_string_decl (TYPE_NAME (class), class_names);
1883       initlist = build_tree_list (NULL_TREE,
1884 				  build_unary_op (ADDR_EXPR, class_name, 1));
1885 
1886       /* Output {..., instance, ...}.  */
1887       for (in_chain = TREE_PURPOSE (cl_chain);
1888 	   in_chain; in_chain = TREE_CHAIN (in_chain))
1889 	{
1890 	  expr = build_unary_op (ADDR_EXPR, TREE_VALUE (in_chain), 1);
1891 	  initlist = tree_cons (NULL_TREE, expr, initlist);
1892 	}
1893 
1894       /* Output {..., NULL}.  */
1895       initlist = tree_cons (NULL_TREE, build_int_2 (0, 0), initlist);
1896 
1897       expr = build_constructor (TREE_TYPE (decl), nreverse (initlist));
1898       finish_decl (decl, expr, NULL_TREE);
1899       TREE_USED (decl) = 1;
1900 
1901       type = build_array_type (build_pointer_type (void_type_node), 0);
1902       decl = build_decl (VAR_DECL, ident, type);
1903       TREE_USED (decl) = 1;
1904       TREE_STATIC (decl) = 1;
1905       decls
1906 	= tree_cons (NULL_TREE, build_unary_op (ADDR_EXPR, decl, 1), decls);
1907     }
1908 
1909   decls = tree_cons (NULL_TREE, build_int_2 (0, 0), decls);
1910   ident = get_identifier ("_OBJC_STATIC_INSTANCES");
1911   expr_decl = build_nt (ARRAY_REF, ident, NULL_TREE);
1912   decl_spec = tree_cons (NULL_TREE, build_pointer_type (void_type_node),
1913 			 build_tree_list (NULL_TREE,
1914 					  ridpointers[(int) RID_STATIC]));
1915   static_instances_decl
1916     = start_decl (expr_decl, decl_spec, 1, NULL_TREE);
1917   TREE_USED (static_instances_decl) = 1;
1918   DECL_CONTEXT (static_instances_decl) = 0;
1919   DECL_ARTIFICIAL (static_instances_decl) = 1;
1920   expr = build_constructor (TREE_TYPE (static_instances_decl),
1921 			    nreverse (decls));
1922   finish_decl (static_instances_decl, expr, NULL_TREE);
1923 }
1924 
1925 /* Output all strings.  */
1926 
1927 static void
generate_strings()1928 generate_strings ()
1929 {
1930   tree sc_spec, decl_specs, expr_decl;
1931   tree chain, string_expr;
1932   tree string, decl;
1933 
1934   for (chain = class_names_chain; chain; chain = TREE_CHAIN (chain))
1935     {
1936       string = TREE_VALUE (chain);
1937       decl = TREE_PURPOSE (chain);
1938       sc_spec
1939 	= tree_cons (NULL_TREE, ridpointers[(int) RID_STATIC], NULL_TREE);
1940       decl_specs = tree_cons (NULL_TREE, ridpointers[(int) RID_CHAR], sc_spec);
1941       expr_decl = build_nt (ARRAY_REF, DECL_NAME (decl), NULL_TREE);
1942       decl = start_decl (expr_decl, decl_specs, 1, NULL_TREE);
1943       DECL_CONTEXT (decl) = NULL_TREE;
1944       string_expr = my_build_string (IDENTIFIER_LENGTH (string) + 1,
1945 				     IDENTIFIER_POINTER (string));
1946       finish_decl (decl, string_expr, NULL_TREE);
1947     }
1948 
1949   for (chain = meth_var_names_chain; chain; chain = TREE_CHAIN (chain))
1950     {
1951       string = TREE_VALUE (chain);
1952       decl = TREE_PURPOSE (chain);
1953       sc_spec
1954 	= tree_cons (NULL_TREE, ridpointers[(int) RID_STATIC], NULL_TREE);
1955       decl_specs = tree_cons (NULL_TREE, ridpointers[(int) RID_CHAR], sc_spec);
1956       expr_decl = build_nt (ARRAY_REF, DECL_NAME (decl), NULL_TREE);
1957       decl = start_decl (expr_decl, decl_specs, 1, NULL_TREE);
1958       DECL_CONTEXT (decl) = NULL_TREE;
1959       string_expr = my_build_string (IDENTIFIER_LENGTH (string) + 1,
1960 				     IDENTIFIER_POINTER (string));
1961       finish_decl (decl, string_expr, NULL_TREE);
1962     }
1963 
1964   for (chain = meth_var_types_chain; chain; chain = TREE_CHAIN (chain))
1965     {
1966       string = TREE_VALUE (chain);
1967       decl = TREE_PURPOSE (chain);
1968       sc_spec
1969 	= tree_cons (NULL_TREE, ridpointers[(int) RID_STATIC], NULL_TREE);
1970       decl_specs = tree_cons (NULL_TREE, ridpointers[(int) RID_CHAR], sc_spec);
1971       expr_decl = build_nt (ARRAY_REF, DECL_NAME (decl), NULL_TREE);
1972       decl = start_decl (expr_decl, decl_specs, 1, NULL_TREE);
1973       DECL_CONTEXT (decl) = NULL_TREE;
1974       string_expr = my_build_string (IDENTIFIER_LENGTH (string) + 1,
1975 				IDENTIFIER_POINTER (string));
1976       finish_decl (decl, string_expr, NULL_TREE);
1977     }
1978 }
1979 
1980 static tree
build_selector_reference_decl()1981 build_selector_reference_decl ()
1982 {
1983   tree decl, ident;
1984   char buf[256];
1985   static int idx = 0;
1986 
1987   sprintf (buf, "_OBJC_SELECTOR_REFERENCES_%d", idx++);
1988 
1989   ident = get_identifier (buf);
1990 
1991   decl = build_decl (VAR_DECL, ident, selector_type);
1992   DECL_EXTERNAL (decl) = 1;
1993   TREE_PUBLIC (decl) = 1;
1994   TREE_USED (decl) = 1;
1995   TREE_READONLY (decl) = 1;
1996   DECL_ARTIFICIAL (decl) = 1;
1997   DECL_CONTEXT (decl) = 0;
1998 
1999   make_decl_rtl (decl, 0);
2000   pushdecl_top_level (decl);
2001 
2002   return decl;
2003 }
2004 
2005 /* Just a handy wrapper for add_objc_string.  */
2006 
2007 static tree
build_selector(ident)2008 build_selector (ident)
2009      tree ident;
2010 {
2011   tree expr = add_objc_string (ident, meth_var_names);
2012   if (flag_typed_selectors)
2013     return expr;
2014   else
2015     return build_c_cast (selector_type, expr); /* cast! */
2016 }
2017 
2018 static void
build_selector_translation_table()2019 build_selector_translation_table ()
2020 {
2021   tree sc_spec, decl_specs;
2022   tree chain, initlist = NULL_TREE;
2023   int offset = 0;
2024   tree decl = NULL_TREE, var_decl, name;
2025 
2026   for (chain = sel_ref_chain; chain; chain = TREE_CHAIN (chain))
2027     {
2028       tree expr;
2029 
2030       if (warn_selector && objc_implementation_context)
2031       {
2032         tree method_chain;
2033         bool found = false;
2034         for (method_chain = meth_var_names_chain;
2035              method_chain;
2036              method_chain = TREE_CHAIN (method_chain))
2037           {
2038             if (TREE_VALUE (method_chain) == TREE_VALUE (chain))
2039               {
2040                 found = true;
2041                 break;
2042               }
2043           }
2044         if (!found)
2045           {
2046             /* Adjust line number for warning message.  */
2047             int save_lineno = lineno;
2048             if (flag_next_runtime && TREE_PURPOSE (chain))
2049               lineno = DECL_SOURCE_LINE (TREE_PURPOSE (chain));
2050             warning ("creating selector for non existant method %s",
2051                      IDENTIFIER_POINTER (TREE_VALUE (chain)));
2052             lineno = save_lineno;
2053           }
2054       }
2055 
2056       expr = build_selector (TREE_VALUE (chain));
2057 
2058       if (flag_next_runtime)
2059 	{
2060 	  name = DECL_NAME (TREE_PURPOSE (chain));
2061 
2062 	  sc_spec = build_tree_list (NULL_TREE, ridpointers[(int) RID_STATIC]);
2063 
2064 	  /* static SEL _OBJC_SELECTOR_REFERENCES_n = ...; */
2065 	  decl_specs = tree_cons (NULL_TREE, selector_type, sc_spec);
2066 
2067 	  var_decl = name;
2068 
2069 	  /* The `decl' that is returned from start_decl is the one that we
2070 	     forward declared in `build_selector_reference'  */
2071 	  decl = start_decl (var_decl, decl_specs, 1, NULL_TREE );
2072 	}
2073 
2074       /* add one for the '\0' character */
2075       offset += IDENTIFIER_LENGTH (TREE_VALUE (chain)) + 1;
2076 
2077       if (flag_next_runtime)
2078 	finish_decl (decl, expr, NULL_TREE);
2079       else
2080 	{
2081 	  if (flag_typed_selectors)
2082 	    {
2083 	      tree eltlist = NULL_TREE;
2084 	      tree encoding = get_proto_encoding (TREE_PURPOSE (chain));
2085 	      eltlist = tree_cons (NULL_TREE, expr, NULL_TREE);
2086 	      eltlist = tree_cons (NULL_TREE, encoding, eltlist);
2087 	      expr = build_constructor (objc_selector_template,
2088 					nreverse (eltlist));
2089 	    }
2090 	  initlist = tree_cons (NULL_TREE, expr, initlist);
2091 
2092 	}
2093     }
2094 
2095   if (! flag_next_runtime)
2096     {
2097       /* Cause the variable and its initial value to be actually output.  */
2098       DECL_EXTERNAL (UOBJC_SELECTOR_TABLE_decl) = 0;
2099       TREE_STATIC (UOBJC_SELECTOR_TABLE_decl) = 1;
2100       /* NULL terminate the list and fix the decl for output.  */
2101       initlist = tree_cons (NULL_TREE, build_int_2 (0, 0), initlist);
2102       DECL_INITIAL (UOBJC_SELECTOR_TABLE_decl) = objc_ellipsis_node;
2103       initlist = build_constructor (TREE_TYPE (UOBJC_SELECTOR_TABLE_decl),
2104 				    nreverse (initlist));
2105       finish_decl (UOBJC_SELECTOR_TABLE_decl, initlist, NULL_TREE);
2106       current_function_decl = NULL_TREE;
2107     }
2108 }
2109 
2110 static tree
get_proto_encoding(proto)2111 get_proto_encoding (proto)
2112      tree proto;
2113 {
2114   tree encoding;
2115   if (proto)
2116     {
2117       tree tmp_decl;
2118 
2119       if (! METHOD_ENCODING (proto))
2120 	{
2121 	    tmp_decl = build_tmp_function_decl ();
2122 	    hack_method_prototype (proto, tmp_decl);
2123 	    encoding = encode_method_prototype (proto, tmp_decl);
2124 	    METHOD_ENCODING (proto) = encoding;
2125 	  }
2126       else
2127 	encoding = METHOD_ENCODING (proto);
2128 
2129       return add_objc_string (encoding, meth_var_types);
2130     }
2131   else
2132     return build_int_2 (0, 0);
2133 }
2134 
2135 /* sel_ref_chain is a list whose "value" fields will be instances of
2136    identifier_node that represent the selector.  */
2137 
2138 static tree
build_typed_selector_reference(ident,prototype)2139 build_typed_selector_reference (ident, prototype)
2140      tree ident, prototype;
2141 {
2142   tree *chain = &sel_ref_chain;
2143   tree expr;
2144   int index = 0;
2145 
2146   while (*chain)
2147     {
2148       if (TREE_PURPOSE (*chain) == prototype && TREE_VALUE (*chain) == ident)
2149 	goto return_at_index;
2150 
2151       index++;
2152       chain = &TREE_CHAIN (*chain);
2153     }
2154 
2155   *chain = tree_cons (prototype, ident, NULL_TREE);
2156 
2157  return_at_index:
2158   expr = build_unary_op (ADDR_EXPR,
2159 			 build_array_ref (UOBJC_SELECTOR_TABLE_decl,
2160 					  build_int_2 (index, 0)),
2161 			 1);
2162   return build_c_cast (selector_type, expr);
2163 }
2164 
2165 static tree
build_selector_reference(ident)2166 build_selector_reference (ident)
2167      tree ident;
2168 {
2169   tree *chain = &sel_ref_chain;
2170   tree expr;
2171   int index = 0;
2172 
2173   while (*chain)
2174     {
2175       if (TREE_VALUE (*chain) == ident)
2176 	return (flag_next_runtime
2177 		? TREE_PURPOSE (*chain)
2178 		: build_array_ref (UOBJC_SELECTOR_TABLE_decl,
2179 				   build_int_2 (index, 0)));
2180 
2181       index++;
2182       chain = &TREE_CHAIN (*chain);
2183     }
2184 
2185   expr = build_selector_reference_decl ();
2186 
2187   *chain = tree_cons (expr, ident, NULL_TREE);
2188 
2189   return (flag_next_runtime
2190 	  ? expr
2191 	  : build_array_ref (UOBJC_SELECTOR_TABLE_decl,
2192 			     build_int_2 (index, 0)));
2193 }
2194 
2195 static tree
build_class_reference_decl()2196 build_class_reference_decl ()
2197 {
2198   tree decl, ident;
2199   char buf[256];
2200   static int idx = 0;
2201 
2202   sprintf (buf, "_OBJC_CLASS_REFERENCES_%d", idx++);
2203 
2204   ident = get_identifier (buf);
2205 
2206   decl = build_decl (VAR_DECL, ident, objc_class_type);
2207   DECL_EXTERNAL (decl) = 1;
2208   TREE_PUBLIC (decl) = 1;
2209   TREE_USED (decl) = 1;
2210   TREE_READONLY (decl) = 1;
2211   DECL_CONTEXT (decl) = 0;
2212   DECL_ARTIFICIAL (decl) = 1;
2213 
2214   make_decl_rtl (decl, 0);
2215   pushdecl_top_level (decl);
2216 
2217   return decl;
2218 }
2219 
2220 /* Create a class reference, but don't create a variable to reference
2221    it.  */
2222 
2223 static void
add_class_reference(ident)2224 add_class_reference (ident)
2225      tree ident;
2226 {
2227   tree chain;
2228 
2229   if ((chain = cls_ref_chain))
2230     {
2231       tree tail;
2232       do
2233         {
2234 	  if (ident == TREE_VALUE (chain))
2235 	    return;
2236 
2237 	  tail = chain;
2238 	  chain = TREE_CHAIN (chain);
2239         }
2240       while (chain);
2241 
2242       /* Append to the end of the list */
2243       TREE_CHAIN (tail) = tree_cons (NULL_TREE, ident, NULL_TREE);
2244     }
2245   else
2246     cls_ref_chain = tree_cons (NULL_TREE, ident, NULL_TREE);
2247 }
2248 
2249 /* Get a class reference, creating it if necessary.  Also create the
2250    reference variable.  */
2251 
2252 tree
get_class_reference(ident)2253 get_class_reference (ident)
2254      tree ident;
2255 {
2256   if (flag_next_runtime)
2257     {
2258       tree *chain;
2259       tree decl;
2260 
2261       for (chain = &cls_ref_chain; *chain; chain = &TREE_CHAIN (*chain))
2262 	if (TREE_VALUE (*chain) == ident)
2263 	  {
2264 	    if (! TREE_PURPOSE (*chain))
2265 	      TREE_PURPOSE (*chain) = build_class_reference_decl ();
2266 
2267 	    return TREE_PURPOSE (*chain);
2268 	  }
2269 
2270       decl = build_class_reference_decl ();
2271       *chain = tree_cons (decl, ident, NULL_TREE);
2272       return decl;
2273     }
2274   else
2275     {
2276       tree params;
2277 
2278       add_class_reference (ident);
2279 
2280       params = build_tree_list (NULL_TREE,
2281 				my_build_string (IDENTIFIER_LENGTH (ident) + 1,
2282 						 IDENTIFIER_POINTER (ident)));
2283 
2284       assemble_external (objc_get_class_decl);
2285       return build_function_call (objc_get_class_decl, params);
2286     }
2287 }
2288 
2289 /* For each string section we have a chain which maps identifier nodes
2290    to decls for the strings.  */
2291 
2292 static tree
add_objc_string(ident,section)2293 add_objc_string (ident, section)
2294      tree ident;
2295      enum string_section section;
2296 {
2297   tree *chain, decl;
2298 
2299   if (section == class_names)
2300     chain = &class_names_chain;
2301   else if (section == meth_var_names)
2302     chain = &meth_var_names_chain;
2303   else if (section == meth_var_types)
2304     chain = &meth_var_types_chain;
2305   else
2306     abort ();
2307 
2308   while (*chain)
2309     {
2310       if (TREE_VALUE (*chain) == ident)
2311 	return build_unary_op (ADDR_EXPR, TREE_PURPOSE (*chain), 1);
2312 
2313       chain = &TREE_CHAIN (*chain);
2314     }
2315 
2316   decl = build_objc_string_decl (section);
2317 
2318   *chain = tree_cons (decl, ident, NULL_TREE);
2319 
2320   return build_unary_op (ADDR_EXPR, decl, 1);
2321 }
2322 
2323 static tree
build_objc_string_decl(section)2324 build_objc_string_decl (section)
2325      enum string_section section;
2326 {
2327   tree decl, ident;
2328   char buf[256];
2329   static int class_names_idx = 0;
2330   static int meth_var_names_idx = 0;
2331   static int meth_var_types_idx = 0;
2332 
2333   if (section == class_names)
2334     sprintf (buf, "_OBJC_CLASS_NAME_%d", class_names_idx++);
2335   else if (section == meth_var_names)
2336     sprintf (buf, "_OBJC_METH_VAR_NAME_%d", meth_var_names_idx++);
2337   else if (section == meth_var_types)
2338     sprintf (buf, "_OBJC_METH_VAR_TYPE_%d", meth_var_types_idx++);
2339 
2340   ident = get_identifier (buf);
2341 
2342   decl = build_decl (VAR_DECL, ident, build_array_type (char_type_node, 0));
2343   DECL_EXTERNAL (decl) = 1;
2344   TREE_PUBLIC (decl) = 1;
2345   TREE_USED (decl) = 1;
2346   TREE_READONLY (decl) = 1;
2347   TREE_CONSTANT (decl) = 1;
2348   DECL_CONTEXT (decl) = 0;
2349   DECL_ARTIFICIAL (decl) = 1;
2350 
2351   make_decl_rtl (decl, 0);
2352   pushdecl_top_level (decl);
2353 
2354   return decl;
2355 }
2356 
2357 
2358 void
objc_declare_alias(alias_ident,class_ident)2359 objc_declare_alias (alias_ident, class_ident)
2360      tree alias_ident;
2361      tree class_ident;
2362 {
2363   if (is_class_name (class_ident) != class_ident)
2364     warning ("cannot find class `%s'", IDENTIFIER_POINTER (class_ident));
2365   else if (is_class_name (alias_ident))
2366     warning ("class `%s' already exists", IDENTIFIER_POINTER (alias_ident));
2367   else
2368     alias_chain = tree_cons (class_ident, alias_ident, alias_chain);
2369 }
2370 
2371 void
objc_declare_class(ident_list)2372 objc_declare_class (ident_list)
2373      tree ident_list;
2374 {
2375   tree list;
2376 
2377   for (list = ident_list; list; list = TREE_CHAIN (list))
2378     {
2379       tree ident = TREE_VALUE (list);
2380       tree decl;
2381 
2382       if ((decl = lookup_name (ident)))
2383 	{
2384 	  error ("`%s' redeclared as different kind of symbol",
2385 		  IDENTIFIER_POINTER (ident));
2386 	  error_with_decl (decl, "previous declaration of `%s'");
2387 	}
2388 
2389       if (! is_class_name (ident))
2390         {
2391 	  tree record = xref_tag (RECORD_TYPE, ident);
2392 	  TREE_STATIC_TEMPLATE (record) = 1;
2393 	  class_chain = tree_cons (NULL_TREE, ident, class_chain);
2394 	}
2395     }
2396 }
2397 
2398 tree
is_class_name(ident)2399 is_class_name (ident)
2400      tree ident;
2401 {
2402   tree chain;
2403 
2404   if (lookup_interface (ident))
2405     return ident;
2406 
2407   for (chain = class_chain; chain; chain = TREE_CHAIN (chain))
2408     {
2409       if (ident == TREE_VALUE (chain))
2410 	return ident;
2411     }
2412 
2413   for (chain = alias_chain; chain; chain = TREE_CHAIN (chain))
2414     {
2415       if (ident == TREE_VALUE (chain))
2416 	return TREE_PURPOSE (chain);
2417     }
2418 
2419   return 0;
2420 }
2421 
2422 tree
objc_is_id(ident)2423 objc_is_id (ident)
2424      tree ident;
2425 {
2426   /* NB: This function may be called before the ObjC front-end
2427      has been initialized, in which case ID_TYPE will be NULL. */
2428   return (id_type && ident && TYPE_P (ident) && IS_ID (ident))
2429 	  ? id_type
2430 	  : NULL_TREE;
2431 }
2432 
2433 tree
lookup_interface(ident)2434 lookup_interface (ident)
2435      tree ident;
2436 {
2437   tree chain;
2438 
2439   for (chain = interface_chain; chain; chain = TREE_CHAIN (chain))
2440     {
2441       if (ident == CLASS_NAME (chain))
2442 	return chain;
2443     }
2444   return NULL_TREE;
2445 }
2446 
2447 /* Used by: build_private_template, continue_class,
2448    and for @defs constructs.  */
2449 
2450 tree
get_class_ivars(interface)2451 get_class_ivars (interface)
2452      tree interface;
2453 {
2454   tree my_name, super_name, ivar_chain;
2455 
2456   my_name = CLASS_NAME (interface);
2457   super_name = CLASS_SUPER_NAME (interface);
2458   ivar_chain = CLASS_IVARS (interface);
2459 
2460   /* Save off a pristine copy of the leaf ivars (i.e, those not
2461      inherited from a super class).  */
2462   if (!CLASS_OWN_IVARS (interface))
2463     CLASS_OWN_IVARS (interface) = copy_list (ivar_chain);
2464 
2465   while (super_name)
2466     {
2467       tree op1;
2468       tree super_interface = lookup_interface (super_name);
2469 
2470       if (!super_interface)
2471         {
2472 	  /* fatal did not work with 2 args...should fix */
2473 	  error ("cannot find interface declaration for `%s', superclass of `%s'",
2474 		 IDENTIFIER_POINTER (super_name),
2475 		 IDENTIFIER_POINTER (my_name));
2476 	  exit (FATAL_EXIT_CODE);
2477         }
2478 
2479       if (super_interface == interface)
2480 	fatal_error ("circular inheritance in interface declaration for `%s'",
2481 		     IDENTIFIER_POINTER (super_name));
2482 
2483       interface = super_interface;
2484       my_name = CLASS_NAME (interface);
2485       super_name = CLASS_SUPER_NAME (interface);
2486 
2487       op1 = CLASS_OWN_IVARS (interface);
2488       if (op1)
2489         {
2490 	  tree head = copy_list (op1);
2491 
2492 	  /* Prepend super class ivars...make a copy of the list, we
2493 	     do not want to alter the original.  */
2494 	  chainon (head, ivar_chain);
2495 	  ivar_chain = head;
2496         }
2497     }
2498   return ivar_chain;
2499 }
2500 
2501 /* struct <classname> {
2502      struct objc_class *isa;
2503      ...
2504    };  */
2505 
2506 static tree
build_private_template(class)2507 build_private_template (class)
2508      tree class;
2509 {
2510   tree ivar_context;
2511 
2512   if (CLASS_STATIC_TEMPLATE (class))
2513     {
2514       uprivate_record = CLASS_STATIC_TEMPLATE (class);
2515       ivar_context = TYPE_FIELDS (CLASS_STATIC_TEMPLATE (class));
2516     }
2517   else
2518     {
2519       uprivate_record = start_struct (RECORD_TYPE, CLASS_NAME (class));
2520 
2521       ivar_context = get_class_ivars (class);
2522 
2523       finish_struct (uprivate_record, ivar_context, NULL_TREE);
2524 
2525       CLASS_STATIC_TEMPLATE (class) = uprivate_record;
2526 
2527       /* mark this record as class template - for class type checking */
2528       TREE_STATIC_TEMPLATE (uprivate_record) = 1;
2529     }
2530 
2531   instance_type
2532     = groktypename (build_tree_list (build_tree_list (NULL_TREE,
2533 						      uprivate_record),
2534 				     build1 (INDIRECT_REF, NULL_TREE,
2535 					     NULL_TREE)));
2536 
2537   return ivar_context;
2538 }
2539 
2540 /* Begin code generation for protocols...  */
2541 
2542 /* struct objc_protocol {
2543      char *protocol_name;
2544      struct objc_protocol **protocol_list;
2545      struct objc_method_desc *instance_methods;
2546      struct objc_method_desc *class_methods;
2547    };  */
2548 
2549 static tree
build_protocol_template()2550 build_protocol_template ()
2551 {
2552   tree decl_specs, field_decl, field_decl_chain;
2553   tree template;
2554 
2555   template = start_struct (RECORD_TYPE, get_identifier (UTAG_PROTOCOL));
2556 
2557   /* struct objc_class *isa; */
2558 
2559   decl_specs = build_tree_list (NULL_TREE, xref_tag (RECORD_TYPE,
2560 					get_identifier (UTAG_CLASS)));
2561   field_decl = build1 (INDIRECT_REF, NULL_TREE, get_identifier ("isa"));
2562   field_decl
2563     = grokfield (input_filename, lineno, field_decl, decl_specs, NULL_TREE);
2564   field_decl_chain = field_decl;
2565 
2566   /* char *protocol_name; */
2567 
2568   decl_specs = build_tree_list (NULL_TREE, ridpointers[(int) RID_CHAR]);
2569   field_decl
2570     = build1 (INDIRECT_REF, NULL_TREE, get_identifier ("protocol_name"));
2571   field_decl
2572     = grokfield (input_filename, lineno, field_decl, decl_specs, NULL_TREE);
2573   chainon (field_decl_chain, field_decl);
2574 
2575   /* struct objc_protocol **protocol_list; */
2576 
2577   decl_specs = build_tree_list (NULL_TREE, template);
2578   field_decl
2579     = build1 (INDIRECT_REF, NULL_TREE, get_identifier ("protocol_list"));
2580   field_decl = build1 (INDIRECT_REF, NULL_TREE, field_decl);
2581   field_decl
2582     = grokfield (input_filename, lineno, field_decl, decl_specs, NULL_TREE);
2583   chainon (field_decl_chain, field_decl);
2584 
2585   /* struct objc_method_list *instance_methods; */
2586 
2587   decl_specs
2588     = build_tree_list (NULL_TREE,
2589 		       xref_tag (RECORD_TYPE,
2590 				 get_identifier (UTAG_METHOD_PROTOTYPE_LIST)));
2591   field_decl
2592     = build1 (INDIRECT_REF, NULL_TREE, get_identifier ("instance_methods"));
2593   field_decl
2594     = grokfield (input_filename, lineno, field_decl, decl_specs, NULL_TREE);
2595   chainon (field_decl_chain, field_decl);
2596 
2597   /* struct objc_method_list *class_methods; */
2598 
2599   decl_specs
2600     = build_tree_list (NULL_TREE,
2601 		       xref_tag (RECORD_TYPE,
2602 				 get_identifier (UTAG_METHOD_PROTOTYPE_LIST)));
2603   field_decl
2604     = build1 (INDIRECT_REF, NULL_TREE, get_identifier ("class_methods"));
2605   field_decl
2606     = grokfield (input_filename, lineno, field_decl, decl_specs, NULL_TREE);
2607   chainon (field_decl_chain, field_decl);
2608 
2609   return finish_struct (template, field_decl_chain, NULL_TREE);
2610 }
2611 
2612 static tree
build_descriptor_table_initializer(type,entries)2613 build_descriptor_table_initializer (type, entries)
2614      tree type;
2615      tree entries;
2616 {
2617   tree initlist = NULL_TREE;
2618 
2619   do
2620     {
2621       tree eltlist = NULL_TREE;
2622 
2623       eltlist
2624 	= tree_cons (NULL_TREE,
2625 		     build_selector (METHOD_SEL_NAME (entries)), NULL_TREE);
2626       eltlist
2627 	= tree_cons (NULL_TREE,
2628 		     add_objc_string (METHOD_ENCODING (entries),
2629 				      meth_var_types),
2630 		     eltlist);
2631 
2632       initlist
2633 	= tree_cons (NULL_TREE,
2634 		     build_constructor (type, nreverse (eltlist)), initlist);
2635 
2636       entries = TREE_CHAIN (entries);
2637     }
2638   while (entries);
2639 
2640   return build_constructor (build_array_type (type, 0), nreverse (initlist));
2641 }
2642 
2643 /* struct objc_method_prototype_list {
2644      int count;
2645      struct objc_method_prototype {
2646  	SEL name;
2647  	char *types;
2648      } list[1];
2649    };  */
2650 
2651 static tree
build_method_prototype_list_template(list_type,size)2652 build_method_prototype_list_template (list_type, size)
2653      tree list_type;
2654      int size;
2655 {
2656   tree objc_ivar_list_record;
2657   tree decl_specs, field_decl, field_decl_chain;
2658 
2659   /* Generate an unnamed struct definition.  */
2660 
2661   objc_ivar_list_record = start_struct (RECORD_TYPE, NULL_TREE);
2662 
2663   /* int method_count; */
2664 
2665   decl_specs = build_tree_list (NULL_TREE, ridpointers[(int) RID_INT]);
2666   field_decl = get_identifier ("method_count");
2667 
2668   field_decl
2669     = grokfield (input_filename, lineno, field_decl, decl_specs, NULL_TREE);
2670   field_decl_chain = field_decl;
2671 
2672   /* struct objc_method method_list[]; */
2673 
2674   decl_specs = build_tree_list (NULL_TREE, list_type);
2675   field_decl = build_nt (ARRAY_REF, get_identifier ("method_list"),
2676 			 build_int_2 (size, 0));
2677 
2678   field_decl
2679     = grokfield (input_filename, lineno, field_decl, decl_specs, NULL_TREE);
2680   chainon (field_decl_chain, field_decl);
2681 
2682   finish_struct (objc_ivar_list_record, field_decl_chain, NULL_TREE);
2683 
2684   return objc_ivar_list_record;
2685 }
2686 
2687 static tree
build_method_prototype_template()2688 build_method_prototype_template ()
2689 {
2690   tree proto_record;
2691   tree decl_specs, field_decl, field_decl_chain;
2692 
2693   proto_record
2694     = start_struct (RECORD_TYPE, get_identifier (UTAG_METHOD_PROTOTYPE));
2695 
2696   /* struct objc_selector *_cmd; */
2697   decl_specs = tree_cons (NULL_TREE, xref_tag (RECORD_TYPE,
2698 		          get_identifier (TAG_SELECTOR)), NULL_TREE);
2699   field_decl = build1 (INDIRECT_REF, NULL_TREE, get_identifier ("_cmd"));
2700 
2701   field_decl
2702     = grokfield (input_filename, lineno, field_decl, decl_specs, NULL_TREE);
2703   field_decl_chain = field_decl;
2704 
2705   decl_specs = tree_cons (NULL_TREE, ridpointers[(int) RID_CHAR], NULL_TREE);
2706   field_decl
2707     = build1 (INDIRECT_REF, NULL_TREE, get_identifier ("method_types"));
2708   field_decl
2709     = grokfield (input_filename, lineno, field_decl, decl_specs, NULL_TREE);
2710   chainon (field_decl_chain, field_decl);
2711 
2712   finish_struct (proto_record, field_decl_chain, NULL_TREE);
2713 
2714   return proto_record;
2715 }
2716 
2717 /* True if last call to forwarding_offset yielded a register offset.  */
2718 static int offset_is_register;
2719 
2720 static int
forwarding_offset(parm)2721 forwarding_offset (parm)
2722       tree parm;
2723 {
2724   int offset_in_bytes;
2725 
2726   if (GET_CODE (DECL_INCOMING_RTL (parm)) == MEM)
2727     {
2728       rtx addr = XEXP (DECL_INCOMING_RTL (parm), 0);
2729 
2730       /* ??? Here we assume that the parm address is indexed
2731 	  off the frame pointer or arg pointer.
2732 	  If that is not true, we produce meaningless results,
2733 	  but do not crash.  */
2734       if (GET_CODE (addr) == PLUS
2735 	  && GET_CODE (XEXP (addr, 1)) == CONST_INT)
2736 	offset_in_bytes = INTVAL (XEXP (addr, 1));
2737       else
2738 	offset_in_bytes = 0;
2739 
2740       offset_in_bytes += OBJC_FORWARDING_STACK_OFFSET;
2741       offset_is_register = 0;
2742     }
2743   else if (GET_CODE (DECL_INCOMING_RTL (parm)) == REG)
2744     {
2745       int regno = REGNO (DECL_INCOMING_RTL (parm));
2746       offset_in_bytes = apply_args_register_offset (regno);
2747       offset_is_register = 1;
2748     }
2749   else
2750     return 0;
2751 
2752   /* This is the case where the parm is passed as an int or double
2753      and it is converted to a char, short or float and stored back
2754      in the parmlist.  In this case, describe the parm
2755      with the variable's declared type, and adjust the address
2756      if the least significant bytes (which we are using) are not
2757      the first ones.  */
2758   if (BYTES_BIG_ENDIAN && TREE_TYPE (parm) != DECL_ARG_TYPE (parm))
2759     offset_in_bytes += (GET_MODE_SIZE (TYPE_MODE (DECL_ARG_TYPE (parm)))
2760 			- GET_MODE_SIZE (GET_MODE (DECL_RTL (parm))));
2761 
2762   return offset_in_bytes;
2763 }
2764 
2765 static tree
encode_method_prototype(method_decl,func_decl)2766 encode_method_prototype (method_decl, func_decl)
2767       tree method_decl;
2768       tree func_decl;
2769 {
2770   tree parms;
2771   int stack_size, i;
2772   tree user_args;
2773   HOST_WIDE_INT max_parm_end = 0;
2774   char buf[40];
2775   tree result;
2776 
2777   /* ONEWAY and BYCOPY, for remote object are the only method qualifiers.  */
2778   encode_type_qualifiers (TREE_PURPOSE (TREE_TYPE (method_decl)));
2779 
2780   /* C type.  */
2781   encode_type (TREE_TYPE (TREE_TYPE (func_decl)),
2782 	       obstack_object_size (&util_obstack),
2783 	       OBJC_ENCODE_INLINE_DEFS);
2784 
2785   /* Stack size.  */
2786   for (parms = DECL_ARGUMENTS (func_decl); parms;
2787        parms = TREE_CHAIN (parms))
2788     {
2789       HOST_WIDE_INT parm_end = (forwarding_offset (parms)
2790 				+ int_size_in_bytes (TREE_TYPE (parms)));
2791 
2792       if (!offset_is_register && max_parm_end < parm_end)
2793 	max_parm_end = parm_end;
2794     }
2795 
2796   stack_size = max_parm_end - OBJC_FORWARDING_MIN_OFFSET;
2797 
2798   sprintf (buf, "%d", stack_size);
2799   obstack_grow (&util_obstack, buf, strlen (buf));
2800 
2801   user_args = METHOD_SEL_ARGS (method_decl);
2802 
2803   /* Argument types.  */
2804   for (parms = DECL_ARGUMENTS (func_decl), i = 0; parms;
2805        parms = TREE_CHAIN (parms), i++)
2806     {
2807       /* Process argument qualifiers for user supplied arguments.  */
2808       if (i > 1)
2809         {
2810 	  encode_type_qualifiers (TREE_PURPOSE (TREE_TYPE (user_args)));
2811 	  user_args = TREE_CHAIN (user_args);
2812  	}
2813 
2814       /* Type.  */
2815       encode_type (TREE_TYPE (parms),
2816 		   obstack_object_size (&util_obstack),
2817 		   OBJC_ENCODE_INLINE_DEFS);
2818 
2819       /* Compute offset.  */
2820       sprintf (buf, "%d", forwarding_offset (parms));
2821 
2822       /* Indicate register.  */
2823       if (offset_is_register)
2824 	obstack_1grow (&util_obstack, '+');
2825 
2826       obstack_grow (&util_obstack, buf, strlen (buf));
2827     }
2828 
2829   obstack_1grow (&util_obstack, '\0');
2830   result = get_identifier (obstack_finish (&util_obstack));
2831   obstack_free (&util_obstack, util_firstobj);
2832   return result;
2833 }
2834 
2835 static tree
generate_descriptor_table(type,name,size,list,proto)2836 generate_descriptor_table (type, name, size, list, proto)
2837      tree type;
2838      const char *name;
2839      int size;
2840      tree list;
2841      tree proto;
2842 {
2843   tree sc_spec, decl_specs, decl, initlist;
2844 
2845   sc_spec = tree_cons (NULL_TREE, ridpointers[(int) RID_STATIC], NULL_TREE);
2846   decl_specs = tree_cons (NULL_TREE, type, sc_spec);
2847 
2848   decl = start_decl (synth_id_with_class_suffix (name, proto),
2849 		     decl_specs, 1, NULL_TREE);
2850   DECL_CONTEXT (decl) = NULL_TREE;
2851 
2852   initlist = build_tree_list (NULL_TREE, build_int_2 (size, 0));
2853   initlist = tree_cons (NULL_TREE, list, initlist);
2854 
2855   finish_decl (decl, build_constructor (type, nreverse (initlist)),
2856 	       NULL_TREE);
2857 
2858   return decl;
2859 }
2860 
2861 static void
generate_method_descriptors(protocol)2862 generate_method_descriptors (protocol)
2863      tree protocol;
2864 {
2865   tree initlist, chain, method_list_template;
2866   tree cast, variable_length_type;
2867   int size;
2868 
2869   if (!objc_method_prototype_template)
2870     objc_method_prototype_template = build_method_prototype_template ();
2871 
2872   cast = build_tree_list (build_tree_list (NULL_TREE, xref_tag (RECORD_TYPE,
2873 				get_identifier (UTAG_METHOD_PROTOTYPE_LIST))),
2874 			  NULL_TREE);
2875   variable_length_type = groktypename (cast);
2876 
2877   chain = PROTOCOL_CLS_METHODS (protocol);
2878   if (chain)
2879     {
2880       size = list_length (chain);
2881 
2882       method_list_template
2883 	= build_method_prototype_list_template (objc_method_prototype_template,
2884 						size);
2885 
2886       initlist
2887 	= build_descriptor_table_initializer (objc_method_prototype_template,
2888 					      chain);
2889 
2890       UOBJC_CLASS_METHODS_decl
2891 	= generate_descriptor_table (method_list_template,
2892 				     "_OBJC_PROTOCOL_CLASS_METHODS",
2893 				     size, initlist, protocol);
2894       TREE_TYPE (UOBJC_CLASS_METHODS_decl) = variable_length_type;
2895     }
2896   else
2897     UOBJC_CLASS_METHODS_decl = 0;
2898 
2899   chain = PROTOCOL_NST_METHODS (protocol);
2900   if (chain)
2901     {
2902       size = list_length (chain);
2903 
2904       method_list_template
2905 	= build_method_prototype_list_template (objc_method_prototype_template,
2906 						size);
2907       initlist
2908 	= build_descriptor_table_initializer (objc_method_prototype_template,
2909 					      chain);
2910 
2911       UOBJC_INSTANCE_METHODS_decl
2912 	= generate_descriptor_table (method_list_template,
2913 				     "_OBJC_PROTOCOL_INSTANCE_METHODS",
2914 				     size, initlist, protocol);
2915       TREE_TYPE (UOBJC_INSTANCE_METHODS_decl) = variable_length_type;
2916     }
2917   else
2918     UOBJC_INSTANCE_METHODS_decl = 0;
2919 }
2920 
2921 /* Generate a temporary FUNCTION_DECL node to be used in
2922    hack_method_prototype below.  */
2923 
2924 static tree
build_tmp_function_decl()2925 build_tmp_function_decl ()
2926 {
2927   tree decl_specs, expr_decl, parms;
2928   static int xxx = 0;
2929   char buffer[80];
2930 
2931   /* struct objc_object *objc_xxx (id, SEL, ...); */
2932   pushlevel (0);
2933   decl_specs = build_tree_list (NULL_TREE, objc_object_reference);
2934   push_parm_decl (build_tree_list
2935 		  (build_tree_list (decl_specs,
2936 				    build1 (INDIRECT_REF, NULL_TREE,
2937 					    NULL_TREE)),
2938 		   NULL_TREE));
2939 
2940   decl_specs = build_tree_list (NULL_TREE, xref_tag (RECORD_TYPE,
2941 					  get_identifier (TAG_SELECTOR)));
2942   expr_decl = build1 (INDIRECT_REF, NULL_TREE, NULL_TREE);
2943 
2944   push_parm_decl (build_tree_list (build_tree_list (decl_specs, expr_decl),
2945 				   NULL_TREE));
2946   parms = get_parm_info (0);
2947   poplevel (0, 0, 0);
2948 
2949   decl_specs = build_tree_list (NULL_TREE, objc_object_reference);
2950   sprintf (buffer, "__objc_tmp_%x", xxx++);
2951   expr_decl = build_nt (CALL_EXPR, get_identifier (buffer), parms, NULL_TREE);
2952   expr_decl = build1 (INDIRECT_REF, NULL_TREE, expr_decl);
2953 
2954   return define_decl (expr_decl, decl_specs);
2955 }
2956 
2957 /* Generate the prototypes for protocol methods.  This is used to
2958    generate method encodings for these.
2959 
2960    NST_METHODS is the method to generate a _DECL node for TMP_DECL is
2961    a decl node to be used.  This is also where the return value is
2962    given.  */
2963 
2964 static void
hack_method_prototype(nst_methods,tmp_decl)2965 hack_method_prototype (nst_methods, tmp_decl)
2966      tree nst_methods;
2967      tree tmp_decl;
2968 {
2969   tree parms;
2970   tree parm;
2971 
2972   /* Hack to avoid problem with static typing of self arg.  */
2973   TREE_SET_CODE (nst_methods, CLASS_METHOD_DECL);
2974   start_method_def (nst_methods);
2975   TREE_SET_CODE (nst_methods, INSTANCE_METHOD_DECL);
2976 
2977   if (METHOD_ADD_ARGS (nst_methods) == objc_ellipsis_node)
2978     parms = get_parm_info (0); /* we have a `, ...' */
2979   else
2980     parms = get_parm_info (1); /* place a `void_at_end' */
2981 
2982   poplevel (0, 0, 0);	/* Must be called BEFORE start_function.  */
2983 
2984   /* Usually called from store_parm_decls -> init_function_start.  */
2985 
2986   DECL_ARGUMENTS (tmp_decl) = TREE_PURPOSE (parms);
2987 
2988   if (current_function_decl)
2989     abort ();
2990   current_function_decl = tmp_decl;
2991 
2992   {
2993     /* Code taken from start_function.  */
2994     tree restype = TREE_TYPE (TREE_TYPE (tmp_decl));
2995     /* Promote the value to int before returning it.  */
2996     if (TREE_CODE (restype) == INTEGER_TYPE
2997 	&& TYPE_PRECISION (restype) < TYPE_PRECISION (integer_type_node))
2998       restype = integer_type_node;
2999     DECL_RESULT (tmp_decl) = build_decl (RESULT_DECL, 0, restype);
3000   }
3001 
3002   for (parm = DECL_ARGUMENTS (tmp_decl); parm; parm = TREE_CHAIN (parm))
3003     DECL_CONTEXT (parm) = tmp_decl;
3004 
3005   init_function_start (tmp_decl, "objc-act", 0);
3006 
3007   /* Typically called from expand_function_start for function definitions.  */
3008   assign_parms (tmp_decl);
3009 
3010   /* install return type */
3011   TREE_TYPE (TREE_TYPE (tmp_decl)) = groktypename (TREE_TYPE (nst_methods));
3012 
3013   current_function_decl = NULL;
3014 }
3015 
3016 static void
generate_protocol_references(plist)3017 generate_protocol_references (plist)
3018      tree plist;
3019 {
3020   tree lproto;
3021 
3022   /* Forward declare protocols referenced.  */
3023   for (lproto = plist; lproto; lproto = TREE_CHAIN (lproto))
3024     {
3025       tree proto = TREE_VALUE (lproto);
3026 
3027       if (TREE_CODE (proto) == PROTOCOL_INTERFACE_TYPE
3028 	  && PROTOCOL_NAME (proto))
3029 	{
3030           if (! PROTOCOL_FORWARD_DECL (proto))
3031             build_protocol_reference (proto);
3032 
3033           if (PROTOCOL_LIST (proto))
3034             generate_protocol_references (PROTOCOL_LIST (proto));
3035         }
3036     }
3037 }
3038 
3039 /* For each protocol which was referenced either from a @protocol()
3040    expression, or because a class/category implements it (then a
3041    pointer to the protocol is stored in the struct describing the
3042    class/category), we create a statically allocated instance of the
3043    Protocol class.  The code is written in such a way as to generate
3044    as few Protocol objects as possible; we generate a unique Protocol
3045    instance for each protocol, and we don't generate a Protocol
3046    instance if the protocol is never referenced (either from a
3047    @protocol() or from a class/category implementation).  These
3048    statically allocated objects can be referred to via the static
3049    (that is, private to this module) symbols _OBJC_PROTOCOL_n.
3050 
3051    The statically allocated Protocol objects that we generate here
3052    need to be fixed up at runtime in order to be used: the 'isa'
3053   pointer of the objects need to be set up to point to the 'Protocol'
3054    class, as known at runtime.
3055 
3056    The NeXT runtime fixes up all protocols at program startup time,
3057    before main() is entered.  It uses a low-level trick to look up all
3058    those symbols, then loops on them and fixes them up.
3059 
3060    The GNU runtime as well fixes up all protocols before user code
3061    from the module is executed; it requires pointers to those symbols
3062    to be put in the objc_symtab (which is then passed as argument to
3063    the function __objc_exec_class() which the compiler sets up to be
3064    executed automatically when the module is loaded); setup of those
3065    Protocol objects happen in two ways in the GNU runtime: all
3066    Protocol objects referred to by a class or category implementation
3067    are fixed up when the class/category is loaded; all Protocol
3068    objects referred to by a @protocol() expression are added by the
3069    compiler to the list of statically allocated instances to fixup
3070    (the same list holding the statically allocated constant string
3071    objects).  Because, as explained above, the compiler generates as
3072    few Protocol objects as possible, some Protocol object might end up
3073    being referenced multiple times when compiled with the GNU runtime,
3074    and end up being fixed up multiple times at runtime inizialization.
3075    But that doesn't hurt, it's just a little inefficient.  */
3076 static void
generate_protocols()3077 generate_protocols ()
3078 {
3079   tree p, tmp_decl, encoding;
3080   tree sc_spec, decl_specs, decl;
3081   tree initlist, protocol_name_expr, refs_decl, refs_expr;
3082   tree cast_type2;
3083 
3084   tmp_decl = build_tmp_function_decl ();
3085 
3086   if (! objc_protocol_template)
3087     objc_protocol_template = build_protocol_template ();
3088 
3089   /* If a protocol was directly referenced, pull in indirect references.  */
3090   for (p = protocol_chain; p; p = TREE_CHAIN (p))
3091     if (PROTOCOL_FORWARD_DECL (p) && PROTOCOL_LIST (p))
3092       generate_protocol_references (PROTOCOL_LIST (p));
3093 
3094   for (p = protocol_chain; p; p = TREE_CHAIN (p))
3095     {
3096       tree nst_methods = PROTOCOL_NST_METHODS (p);
3097       tree cls_methods = PROTOCOL_CLS_METHODS (p);
3098 
3099       /* If protocol wasn't referenced, don't generate any code.  */
3100       if (! PROTOCOL_FORWARD_DECL (p))
3101 	continue;
3102 
3103       /* Make sure we link in the Protocol class.  */
3104       add_class_reference (get_identifier (PROTOCOL_OBJECT_CLASS_NAME));
3105 
3106       while (nst_methods)
3107 	{
3108 	  if (! METHOD_ENCODING (nst_methods))
3109 	    {
3110 	      hack_method_prototype (nst_methods, tmp_decl);
3111 	      encoding = encode_method_prototype (nst_methods, tmp_decl);
3112 	      METHOD_ENCODING (nst_methods) = encoding;
3113 	    }
3114 	  nst_methods = TREE_CHAIN (nst_methods);
3115 	}
3116 
3117       while (cls_methods)
3118 	{
3119 	  if (! METHOD_ENCODING (cls_methods))
3120 	    {
3121 	      hack_method_prototype (cls_methods, tmp_decl);
3122 	      encoding = encode_method_prototype (cls_methods, tmp_decl);
3123 	      METHOD_ENCODING (cls_methods) = encoding;
3124 	    }
3125 
3126 	  cls_methods = TREE_CHAIN (cls_methods);
3127 	}
3128       generate_method_descriptors (p);
3129 
3130       if (PROTOCOL_LIST (p))
3131 	refs_decl = generate_protocol_list (p);
3132       else
3133 	refs_decl = 0;
3134 
3135       /* static struct objc_protocol _OBJC_PROTOCOL_<mumble>; */
3136 
3137       sc_spec = tree_cons (NULL_TREE, ridpointers[(int) RID_STATIC],
3138 			   NULL_TREE);
3139       decl_specs = tree_cons (NULL_TREE, objc_protocol_template, sc_spec);
3140 
3141       decl = start_decl (synth_id_with_class_suffix ("_OBJC_PROTOCOL", p),
3142 			 decl_specs, 1, NULL_TREE);
3143 
3144       DECL_CONTEXT (decl) = NULL_TREE;
3145 
3146       protocol_name_expr = add_objc_string (PROTOCOL_NAME (p), class_names);
3147 
3148       if (refs_decl)
3149 	{
3150 	  cast_type2
3151 	    = groktypename
3152 		(build_tree_list (build_tree_list (NULL_TREE,
3153 						   objc_protocol_template),
3154 				  build1 (INDIRECT_REF, NULL_TREE,
3155 					  build1 (INDIRECT_REF, NULL_TREE,
3156 						  NULL_TREE))));
3157 
3158 	  refs_expr = build_unary_op (ADDR_EXPR, refs_decl, 0);
3159 	  TREE_TYPE (refs_expr) = cast_type2;
3160 	}
3161       else
3162 	refs_expr = build_int_2 (0, 0);
3163 
3164       /* UOBJC_INSTANCE_METHODS_decl/UOBJC_CLASS_METHODS_decl are set
3165 	 by generate_method_descriptors, which is called above.  */
3166       initlist = build_protocol_initializer (TREE_TYPE (decl),
3167 					     protocol_name_expr, refs_expr,
3168 					     UOBJC_INSTANCE_METHODS_decl,
3169 					     UOBJC_CLASS_METHODS_decl);
3170       finish_decl (decl, initlist, NULL_TREE);
3171 
3172       /* Mark the decl as used to avoid "defined but not used" warning.  */
3173       TREE_USED (decl) = 1;
3174     }
3175 }
3176 
3177 static tree
build_protocol_initializer(type,protocol_name,protocol_list,instance_methods,class_methods)3178 build_protocol_initializer (type, protocol_name, protocol_list,
3179 			    instance_methods, class_methods)
3180      tree type;
3181      tree protocol_name;
3182      tree protocol_list;
3183      tree instance_methods;
3184      tree class_methods;
3185 {
3186   tree initlist = NULL_TREE, expr;
3187   tree cast_type;
3188 
3189   cast_type = groktypename
3190     (build_tree_list
3191      (build_tree_list (NULL_TREE,
3192 		       xref_tag (RECORD_TYPE,
3193 				 get_identifier (UTAG_CLASS))),
3194       build1 (INDIRECT_REF, NULL_TREE, NULL_TREE)));
3195 
3196   /* Filling the "isa" in with one allows the runtime system to
3197      detect that the version change...should remove before final release.  */
3198 
3199   expr = build_int_2 (PROTOCOL_VERSION, 0);
3200   TREE_TYPE (expr) = cast_type;
3201   initlist = tree_cons (NULL_TREE, expr, initlist);
3202   initlist = tree_cons (NULL_TREE, protocol_name, initlist);
3203   initlist = tree_cons (NULL_TREE, protocol_list, initlist);
3204 
3205   if (!instance_methods)
3206     initlist = tree_cons (NULL_TREE, build_int_2 (0, 0), initlist);
3207   else
3208     {
3209       expr = build_unary_op (ADDR_EXPR, instance_methods, 0);
3210       initlist = tree_cons (NULL_TREE, expr, initlist);
3211     }
3212 
3213   if (!class_methods)
3214     initlist = tree_cons (NULL_TREE, build_int_2 (0, 0), initlist);
3215   else
3216     {
3217       expr = build_unary_op (ADDR_EXPR, class_methods, 0);
3218       initlist = tree_cons (NULL_TREE, expr, initlist);
3219     }
3220 
3221   return build_constructor (type, nreverse (initlist));
3222 }
3223 
3224 /* struct objc_category {
3225      char *category_name;
3226      char *class_name;
3227      struct objc_method_list *instance_methods;
3228      struct objc_method_list *class_methods;
3229      struct objc_protocol_list *protocols;
3230    };   */
3231 
3232 static void
build_category_template()3233 build_category_template ()
3234 {
3235   tree decl_specs, field_decl, field_decl_chain;
3236 
3237   objc_category_template = start_struct (RECORD_TYPE,
3238 					 get_identifier (UTAG_CATEGORY));
3239   /* char *category_name; */
3240 
3241   decl_specs = build_tree_list (NULL_TREE, ridpointers[(int) RID_CHAR]);
3242   field_decl
3243     = build1 (INDIRECT_REF, NULL_TREE, get_identifier ("category_name"));
3244   field_decl
3245     = grokfield (input_filename, lineno, field_decl, decl_specs, NULL_TREE);
3246   field_decl_chain = field_decl;
3247 
3248   /* char *class_name; */
3249 
3250   decl_specs = build_tree_list (NULL_TREE, ridpointers[(int) RID_CHAR]);
3251   field_decl = build1 (INDIRECT_REF, NULL_TREE, get_identifier ("class_name"));
3252   field_decl
3253     = grokfield (input_filename, lineno, field_decl, decl_specs, NULL_TREE);
3254   chainon (field_decl_chain, field_decl);
3255 
3256   /* struct objc_method_list *instance_methods; */
3257 
3258   decl_specs = build_tree_list (NULL_TREE,
3259 				xref_tag (RECORD_TYPE,
3260 					  get_identifier (UTAG_METHOD_LIST)));
3261   field_decl
3262     = build1 (INDIRECT_REF, NULL_TREE, get_identifier ("instance_methods"));
3263   field_decl
3264     = grokfield (input_filename, lineno, field_decl, decl_specs, NULL_TREE);
3265   chainon (field_decl_chain, field_decl);
3266 
3267   /* struct objc_method_list *class_methods; */
3268 
3269   decl_specs = build_tree_list (NULL_TREE,
3270 				xref_tag (RECORD_TYPE,
3271 					  get_identifier (UTAG_METHOD_LIST)));
3272   field_decl
3273     = build1 (INDIRECT_REF, NULL_TREE, get_identifier ("class_methods"));
3274   field_decl
3275     = grokfield (input_filename, lineno, field_decl, decl_specs, NULL_TREE);
3276   chainon (field_decl_chain, field_decl);
3277 
3278   /* struct objc_protocol **protocol_list; */
3279 
3280   decl_specs = build_tree_list (NULL_TREE,
3281 				xref_tag (RECORD_TYPE,
3282 					  get_identifier (UTAG_PROTOCOL)));
3283   field_decl
3284     = build1 (INDIRECT_REF, NULL_TREE, get_identifier ("protocol_list"));
3285   field_decl = build1 (INDIRECT_REF, NULL_TREE, field_decl);
3286   field_decl
3287     = grokfield (input_filename, lineno, field_decl, decl_specs, NULL_TREE);
3288   chainon (field_decl_chain, field_decl);
3289 
3290   finish_struct (objc_category_template, field_decl_chain, NULL_TREE);
3291 }
3292 
3293 /* struct objc_selector {
3294      void *sel_id;
3295      char *sel_type;
3296    }; */
3297 
3298 static void
build_selector_template()3299 build_selector_template ()
3300 {
3301 
3302   tree decl_specs, field_decl, field_decl_chain;
3303 
3304   objc_selector_template
3305     = start_struct (RECORD_TYPE, get_identifier (UTAG_SELECTOR));
3306 
3307   /* void *sel_id; */
3308 
3309   decl_specs = build_tree_list (NULL_TREE, ridpointers[(int) RID_VOID]);
3310   field_decl = build1 (INDIRECT_REF, NULL_TREE, get_identifier ("sel_id"));
3311   field_decl
3312     = grokfield (input_filename, lineno, field_decl, decl_specs, NULL_TREE);
3313   field_decl_chain = field_decl;
3314 
3315   /* char *sel_type; */
3316 
3317   decl_specs = build_tree_list (NULL_TREE, ridpointers[(int) RID_CHAR]);
3318   field_decl = build1 (INDIRECT_REF, NULL_TREE, get_identifier ("sel_type"));
3319   field_decl
3320     = grokfield (input_filename, lineno, field_decl, decl_specs, NULL_TREE);
3321   chainon (field_decl_chain, field_decl);
3322 
3323   finish_struct (objc_selector_template, field_decl_chain, NULL_TREE);
3324 }
3325 
3326 /* struct objc_class {
3327      struct objc_class *isa;
3328      struct objc_class *super_class;
3329      char *name;
3330      long version;
3331      long info;
3332      long instance_size;
3333      struct objc_ivar_list *ivars;
3334      struct objc_method_list *methods;
3335      if (flag_next_runtime)
3336        struct objc_cache *cache;
3337      else {
3338        struct sarray *dtable;
3339        struct objc_class *subclass_list;
3340        struct objc_class *sibling_class;
3341      }
3342      struct objc_protocol_list *protocols;
3343      void *gc_object_type;
3344    };  */
3345 
3346 static void
build_class_template()3347 build_class_template ()
3348 {
3349   tree decl_specs, field_decl, field_decl_chain;
3350 
3351   objc_class_template
3352     = start_struct (RECORD_TYPE, get_identifier (UTAG_CLASS));
3353 
3354   /* struct objc_class *isa; */
3355 
3356   decl_specs = build_tree_list (NULL_TREE, objc_class_template);
3357   field_decl = build1 (INDIRECT_REF, NULL_TREE, get_identifier ("isa"));
3358   field_decl
3359     = grokfield (input_filename, lineno, field_decl, decl_specs, NULL_TREE);
3360   field_decl_chain = field_decl;
3361 
3362   /* struct objc_class *super_class; */
3363 
3364   decl_specs = build_tree_list (NULL_TREE, objc_class_template);
3365   field_decl
3366     = build1 (INDIRECT_REF, NULL_TREE, get_identifier ("super_class"));
3367   field_decl
3368     = grokfield (input_filename, lineno, field_decl, decl_specs, NULL_TREE);
3369   chainon (field_decl_chain, field_decl);
3370 
3371   /* char *name; */
3372 
3373   decl_specs = build_tree_list (NULL_TREE, ridpointers[(int) RID_CHAR]);
3374   field_decl = build1 (INDIRECT_REF, NULL_TREE, get_identifier ("name"));
3375   field_decl
3376     = grokfield (input_filename, lineno, field_decl, decl_specs, NULL_TREE);
3377   chainon (field_decl_chain, field_decl);
3378 
3379   /* long version; */
3380 
3381   decl_specs = build_tree_list (NULL_TREE, ridpointers[(int) RID_LONG]);
3382   field_decl = get_identifier ("version");
3383   field_decl
3384     = grokfield (input_filename, lineno, field_decl, decl_specs, NULL_TREE);
3385   chainon (field_decl_chain, field_decl);
3386 
3387   /* long info; */
3388 
3389   decl_specs = build_tree_list (NULL_TREE, ridpointers[(int) RID_LONG]);
3390   field_decl = get_identifier ("info");
3391   field_decl
3392     = grokfield (input_filename, lineno, field_decl, decl_specs, NULL_TREE);
3393   chainon (field_decl_chain, field_decl);
3394 
3395   /* long instance_size; */
3396 
3397   decl_specs = build_tree_list (NULL_TREE, ridpointers[(int) RID_LONG]);
3398   field_decl = get_identifier ("instance_size");
3399   field_decl
3400     = grokfield (input_filename, lineno, field_decl, decl_specs, NULL_TREE);
3401   chainon (field_decl_chain, field_decl);
3402 
3403   /* struct objc_ivar_list *ivars; */
3404 
3405   decl_specs = build_tree_list (NULL_TREE,
3406 				xref_tag (RECORD_TYPE,
3407 					  get_identifier (UTAG_IVAR_LIST)));
3408   field_decl = build1 (INDIRECT_REF, NULL_TREE, get_identifier ("ivars"));
3409   field_decl
3410     = grokfield (input_filename, lineno, field_decl, decl_specs, NULL_TREE);
3411   chainon (field_decl_chain, field_decl);
3412 
3413   /* struct objc_method_list *methods; */
3414 
3415   decl_specs = build_tree_list (NULL_TREE,
3416 				xref_tag (RECORD_TYPE,
3417 					  get_identifier (UTAG_METHOD_LIST)));
3418   field_decl = build1 (INDIRECT_REF, NULL_TREE, get_identifier ("methods"));
3419   field_decl
3420     = grokfield (input_filename, lineno, field_decl, decl_specs, NULL_TREE);
3421   chainon (field_decl_chain, field_decl);
3422 
3423   if (flag_next_runtime)
3424     {
3425       /* struct objc_cache *cache; */
3426 
3427       decl_specs = build_tree_list (NULL_TREE,
3428 				    xref_tag (RECORD_TYPE,
3429 					      get_identifier ("objc_cache")));
3430       field_decl = build1 (INDIRECT_REF, NULL_TREE, get_identifier ("cache"));
3431       field_decl = grokfield (input_filename, lineno, field_decl,
3432 			      decl_specs, NULL_TREE);
3433       chainon (field_decl_chain, field_decl);
3434     }
3435   else
3436     {
3437       /* struct sarray *dtable; */
3438 
3439       decl_specs = build_tree_list (NULL_TREE,
3440 				    xref_tag (RECORD_TYPE,
3441 					      get_identifier ("sarray")));
3442       field_decl = build1 (INDIRECT_REF, NULL_TREE, get_identifier ("dtable"));
3443       field_decl = grokfield (input_filename, lineno, field_decl,
3444 			      decl_specs, NULL_TREE);
3445       chainon (field_decl_chain, field_decl);
3446 
3447       /* struct objc_class *subclass_list; */
3448 
3449       decl_specs = build_tree_list (NULL_TREE, objc_class_template);
3450       field_decl
3451 	= build1 (INDIRECT_REF, NULL_TREE, get_identifier ("subclass_list"));
3452       field_decl = grokfield (input_filename, lineno, field_decl,
3453 			      decl_specs, NULL_TREE);
3454       chainon (field_decl_chain, field_decl);
3455 
3456       /* struct objc_class *sibling_class; */
3457 
3458       decl_specs = build_tree_list (NULL_TREE, objc_class_template);
3459       field_decl
3460 	= build1 (INDIRECT_REF, NULL_TREE, get_identifier ("sibling_class"));
3461       field_decl = grokfield (input_filename, lineno, field_decl,
3462 			      decl_specs, NULL_TREE);
3463       chainon (field_decl_chain, field_decl);
3464     }
3465 
3466   /* struct objc_protocol **protocol_list; */
3467 
3468   decl_specs = build_tree_list (NULL_TREE,
3469 				xref_tag (RECORD_TYPE,
3470 					  get_identifier (UTAG_PROTOCOL)));
3471   field_decl
3472     = build1 (INDIRECT_REF, NULL_TREE, get_identifier ("protocol_list"));
3473   field_decl
3474     = build1 (INDIRECT_REF, NULL_TREE, field_decl);
3475   field_decl = grokfield (input_filename, lineno, field_decl,
3476 			  decl_specs, NULL_TREE);
3477   chainon (field_decl_chain, field_decl);
3478 
3479   /* void *sel_id; */
3480 
3481   decl_specs = build_tree_list (NULL_TREE, ridpointers[(int) RID_VOID]);
3482   field_decl = build1 (INDIRECT_REF, NULL_TREE, get_identifier ("sel_id"));
3483   field_decl
3484     = grokfield (input_filename, lineno, field_decl, decl_specs, NULL_TREE);
3485   chainon (field_decl_chain, field_decl);
3486 
3487   /* void *gc_object_type; */
3488 
3489   decl_specs = build_tree_list (NULL_TREE, ridpointers[(int) RID_VOID]);
3490   field_decl = build1 (INDIRECT_REF, NULL_TREE, get_identifier ("gc_object_type"));
3491   field_decl
3492     = grokfield (input_filename, lineno, field_decl, decl_specs, NULL_TREE);
3493   chainon (field_decl_chain, field_decl);
3494 
3495   finish_struct (objc_class_template, field_decl_chain, NULL_TREE);
3496 }
3497 
3498 /* Generate appropriate forward declarations for an implementation.  */
3499 
3500 static void
synth_forward_declarations()3501 synth_forward_declarations ()
3502 {
3503   tree sc_spec, decl_specs, an_id;
3504 
3505   /* extern struct objc_class _OBJC_CLASS_<my_name>; */
3506 
3507   an_id = synth_id_with_class_suffix ("_OBJC_CLASS", objc_implementation_context);
3508 
3509   sc_spec = build_tree_list (NULL_TREE, ridpointers[(int) RID_EXTERN]);
3510   decl_specs = tree_cons (NULL_TREE, objc_class_template, sc_spec);
3511   UOBJC_CLASS_decl = define_decl (an_id, decl_specs);
3512   TREE_USED (UOBJC_CLASS_decl) = 1;
3513   DECL_ARTIFICIAL (UOBJC_CLASS_decl) = 1;
3514 
3515   /* extern struct objc_class _OBJC_METACLASS_<my_name>; */
3516 
3517   an_id = synth_id_with_class_suffix ("_OBJC_METACLASS",
3518 				      objc_implementation_context);
3519 
3520   UOBJC_METACLASS_decl = define_decl (an_id, decl_specs);
3521   TREE_USED (UOBJC_METACLASS_decl) = 1;
3522   DECL_ARTIFICIAL(UOBJC_METACLASS_decl) = 1;
3523 
3524   /* Pre-build the following entities - for speed/convenience.  */
3525 
3526   an_id = get_identifier ("super_class");
3527   ucls_super_ref = build_component_ref (UOBJC_CLASS_decl, an_id);
3528   uucls_super_ref = build_component_ref (UOBJC_METACLASS_decl, an_id);
3529 }
3530 
3531 static void
error_with_ivar(message,decl,rawdecl)3532 error_with_ivar (message, decl, rawdecl)
3533      const char *message;
3534      tree decl;
3535      tree rawdecl;
3536 {
3537   diagnostic_count_diagnostic (global_dc, DK_ERROR);
3538 
3539   diagnostic_report_current_function (global_dc);
3540 
3541   error_with_file_and_line (DECL_SOURCE_FILE (decl),
3542 			    DECL_SOURCE_LINE (decl),
3543 			    "%s `%s'",
3544 			    message, gen_declaration (rawdecl, errbuf));
3545 
3546 }
3547 
3548 static void
check_ivars(inter,imp)3549 check_ivars (inter, imp)
3550      tree inter;
3551      tree imp;
3552 {
3553   tree intdecls = CLASS_IVARS (inter);
3554   tree impdecls = CLASS_IVARS (imp);
3555   tree rawintdecls = CLASS_RAW_IVARS (inter);
3556   tree rawimpdecls = CLASS_RAW_IVARS (imp);
3557 
3558   while (1)
3559     {
3560       tree t1, t2;
3561 
3562       if (intdecls == 0 && impdecls == 0)
3563 	break;
3564       if (intdecls == 0 || impdecls == 0)
3565 	{
3566 	  error ("inconsistent instance variable specification");
3567 	  break;
3568 	}
3569 
3570       t1 = TREE_TYPE (intdecls); t2 = TREE_TYPE (impdecls);
3571 
3572       if (!comptypes (t1, t2))
3573 	{
3574 	  if (DECL_NAME (intdecls) == DECL_NAME (impdecls))
3575 	    {
3576 	      error_with_ivar ("conflicting instance variable type",
3577 			       impdecls, rawimpdecls);
3578 	      error_with_ivar ("previous declaration of",
3579 			       intdecls, rawintdecls);
3580 	    }
3581 	  else			/* both the type and the name don't match */
3582 	    {
3583 	      error ("inconsistent instance variable specification");
3584 	      break;
3585 	    }
3586 	}
3587 
3588       else if (DECL_NAME (intdecls) != DECL_NAME (impdecls))
3589 	{
3590 	  error_with_ivar ("conflicting instance variable name",
3591 			   impdecls, rawimpdecls);
3592 	  error_with_ivar ("previous declaration of",
3593 			   intdecls, rawintdecls);
3594 	}
3595 
3596       intdecls = TREE_CHAIN (intdecls);
3597       impdecls = TREE_CHAIN (impdecls);
3598       rawintdecls = TREE_CHAIN (rawintdecls);
3599       rawimpdecls = TREE_CHAIN (rawimpdecls);
3600     }
3601 }
3602 
3603 /* Set super_type to the data type node for struct objc_super *,
3604    first defining struct objc_super itself.
3605    This needs to be done just once per compilation.  */
3606 
3607 static tree
build_super_template()3608 build_super_template ()
3609 {
3610   tree record, decl_specs, field_decl, field_decl_chain;
3611 
3612   record = start_struct (RECORD_TYPE, get_identifier (UTAG_SUPER));
3613 
3614   /* struct objc_object *self; */
3615 
3616   decl_specs = build_tree_list (NULL_TREE, objc_object_reference);
3617   field_decl = get_identifier ("self");
3618   field_decl = build1 (INDIRECT_REF, NULL_TREE, field_decl);
3619   field_decl = grokfield (input_filename, lineno,
3620 			  field_decl, decl_specs, NULL_TREE);
3621   field_decl_chain = field_decl;
3622 
3623   /* struct objc_class *class; */
3624 
3625   decl_specs = get_identifier (UTAG_CLASS);
3626   decl_specs = build_tree_list (NULL_TREE, xref_tag (RECORD_TYPE, decl_specs));
3627   field_decl = build1 (INDIRECT_REF, NULL_TREE, get_identifier ("class"));
3628 
3629   field_decl = grokfield (input_filename, lineno,
3630 			  field_decl, decl_specs, NULL_TREE);
3631   chainon (field_decl_chain, field_decl);
3632 
3633   finish_struct (record, field_decl_chain, NULL_TREE);
3634 
3635   /* `struct objc_super *' */
3636   super_type = groktypename (build_tree_list (build_tree_list (NULL_TREE,
3637 							       record),
3638 					      build1 (INDIRECT_REF,
3639 						      NULL_TREE, NULL_TREE)));
3640   return record;
3641 }
3642 
3643 /* struct objc_ivar {
3644      char *ivar_name;
3645      char *ivar_type;
3646      int ivar_offset;
3647    };  */
3648 
3649 static tree
build_ivar_template()3650 build_ivar_template ()
3651 {
3652   tree objc_ivar_id, objc_ivar_record;
3653   tree decl_specs, field_decl, field_decl_chain;
3654 
3655   objc_ivar_id = get_identifier (UTAG_IVAR);
3656   objc_ivar_record = start_struct (RECORD_TYPE, objc_ivar_id);
3657 
3658   /* char *ivar_name; */
3659 
3660   decl_specs = build_tree_list (NULL_TREE, ridpointers[(int) RID_CHAR]);
3661   field_decl = build1 (INDIRECT_REF, NULL_TREE, get_identifier ("ivar_name"));
3662 
3663   field_decl = grokfield (input_filename, lineno, field_decl,
3664 			  decl_specs, NULL_TREE);
3665   field_decl_chain = field_decl;
3666 
3667   /* char *ivar_type; */
3668 
3669   decl_specs = build_tree_list (NULL_TREE, ridpointers[(int) RID_CHAR]);
3670   field_decl = build1 (INDIRECT_REF, NULL_TREE, get_identifier ("ivar_type"));
3671 
3672   field_decl = grokfield (input_filename, lineno, field_decl,
3673 			  decl_specs, NULL_TREE);
3674   chainon (field_decl_chain, field_decl);
3675 
3676   /* int ivar_offset; */
3677 
3678   decl_specs = build_tree_list (NULL_TREE, ridpointers[(int) RID_INT]);
3679   field_decl = get_identifier ("ivar_offset");
3680 
3681   field_decl = grokfield (input_filename, lineno, field_decl,
3682 			  decl_specs, NULL_TREE);
3683   chainon (field_decl_chain, field_decl);
3684 
3685   finish_struct (objc_ivar_record, field_decl_chain, NULL_TREE);
3686 
3687   return objc_ivar_record;
3688 }
3689 
3690 /* struct {
3691      int ivar_count;
3692      struct objc_ivar ivar_list[ivar_count];
3693    };  */
3694 
3695 static tree
build_ivar_list_template(list_type,size)3696 build_ivar_list_template (list_type, size)
3697      tree list_type;
3698      int size;
3699 {
3700   tree objc_ivar_list_record;
3701   tree decl_specs, field_decl, field_decl_chain;
3702 
3703   objc_ivar_list_record = start_struct (RECORD_TYPE, NULL_TREE);
3704 
3705   /* int ivar_count; */
3706 
3707   decl_specs = build_tree_list (NULL_TREE, ridpointers[(int) RID_INT]);
3708   field_decl = get_identifier ("ivar_count");
3709 
3710   field_decl = grokfield (input_filename, lineno, field_decl,
3711 			  decl_specs, NULL_TREE);
3712   field_decl_chain = field_decl;
3713 
3714   /* struct objc_ivar ivar_list[]; */
3715 
3716   decl_specs = build_tree_list (NULL_TREE, list_type);
3717   field_decl = build_nt (ARRAY_REF, get_identifier ("ivar_list"),
3718 			 build_int_2 (size, 0));
3719 
3720   field_decl = grokfield (input_filename, lineno,
3721 			  field_decl, decl_specs, NULL_TREE);
3722   chainon (field_decl_chain, field_decl);
3723 
3724   finish_struct (objc_ivar_list_record, field_decl_chain, NULL_TREE);
3725 
3726   return objc_ivar_list_record;
3727 }
3728 
3729 /* struct {
3730      int method_next;
3731      int method_count;
3732      struct objc_method method_list[method_count];
3733    };  */
3734 
3735 static tree
build_method_list_template(list_type,size)3736 build_method_list_template (list_type, size)
3737      tree list_type;
3738      int size;
3739 {
3740   tree objc_ivar_list_record;
3741   tree decl_specs, field_decl, field_decl_chain;
3742 
3743   objc_ivar_list_record = start_struct (RECORD_TYPE, NULL_TREE);
3744 
3745   /* int method_next; */
3746 
3747   decl_specs
3748     = build_tree_list
3749       (NULL_TREE,
3750        xref_tag (RECORD_TYPE,
3751 		 get_identifier (UTAG_METHOD_PROTOTYPE_LIST)));
3752   field_decl
3753     = build1 (INDIRECT_REF, NULL_TREE, get_identifier ("method_next"));
3754   field_decl = grokfield (input_filename, lineno, field_decl,
3755 			  decl_specs, NULL_TREE);
3756   field_decl_chain = field_decl;
3757 
3758   /* int method_count; */
3759 
3760   decl_specs = build_tree_list (NULL_TREE, ridpointers[(int) RID_INT]);
3761   field_decl = get_identifier ("method_count");
3762 
3763   field_decl = grokfield (input_filename, lineno,
3764 			  field_decl, decl_specs, NULL_TREE);
3765   chainon (field_decl_chain, field_decl);
3766 
3767   /* struct objc_method method_list[]; */
3768 
3769   decl_specs = build_tree_list (NULL_TREE, list_type);
3770   field_decl = build_nt (ARRAY_REF, get_identifier ("method_list"),
3771 			 build_int_2 (size, 0));
3772 
3773   field_decl = grokfield (input_filename, lineno,
3774 			  field_decl, decl_specs, NULL_TREE);
3775   chainon (field_decl_chain, field_decl);
3776 
3777   finish_struct (objc_ivar_list_record, field_decl_chain, NULL_TREE);
3778 
3779   return objc_ivar_list_record;
3780 }
3781 
3782 static tree
build_ivar_list_initializer(type,field_decl)3783 build_ivar_list_initializer (type, field_decl)
3784      tree type;
3785      tree field_decl;
3786 {
3787   tree initlist = NULL_TREE;
3788 
3789   do
3790     {
3791       tree ivar = NULL_TREE;
3792 
3793       /* Set name.  */
3794       if (DECL_NAME (field_decl))
3795 	ivar = tree_cons (NULL_TREE,
3796 			  add_objc_string (DECL_NAME (field_decl),
3797 					   meth_var_names),
3798 			  ivar);
3799       else
3800 	/* Unnamed bit-field ivar (yuck).  */
3801 	ivar = tree_cons (NULL_TREE, build_int_2 (0, 0), ivar);
3802 
3803       /* Set type.  */
3804       encode_field_decl (field_decl,
3805 			 obstack_object_size (&util_obstack),
3806 			 OBJC_ENCODE_DONT_INLINE_DEFS);
3807 
3808       /* Null terminate string.  */
3809       obstack_1grow (&util_obstack, 0);
3810       ivar
3811 	= tree_cons
3812 	  (NULL_TREE,
3813 	   add_objc_string (get_identifier (obstack_finish (&util_obstack)),
3814 			    meth_var_types),
3815 	   ivar);
3816       obstack_free (&util_obstack, util_firstobj);
3817 
3818       /* Set offset.  */
3819       ivar = tree_cons (NULL_TREE, byte_position (field_decl), ivar);
3820       initlist = tree_cons (NULL_TREE,
3821 			    build_constructor (type, nreverse (ivar)),
3822 			    initlist);
3823 
3824       field_decl = TREE_CHAIN (field_decl);
3825     }
3826   while (field_decl);
3827 
3828   return build_constructor (build_array_type (type, 0), nreverse (initlist));
3829 }
3830 
3831 static tree
generate_ivars_list(type,name,size,list)3832 generate_ivars_list (type, name, size, list)
3833      tree type;
3834      const char *name;
3835      int size;
3836      tree list;
3837 {
3838   tree sc_spec, decl_specs, decl, initlist;
3839 
3840   sc_spec = tree_cons (NULL_TREE, ridpointers[(int) RID_STATIC], NULL_TREE);
3841   decl_specs = tree_cons (NULL_TREE, type, sc_spec);
3842 
3843   decl = start_decl (synth_id_with_class_suffix (name, objc_implementation_context),
3844 		     decl_specs, 1, NULL_TREE);
3845 
3846   initlist = build_tree_list (NULL_TREE, build_int_2 (size, 0));
3847   initlist = tree_cons (NULL_TREE, list, initlist);
3848 
3849   finish_decl (decl,
3850 	       build_constructor (TREE_TYPE (decl), nreverse (initlist)),
3851 	       NULL_TREE);
3852 
3853   return decl;
3854 }
3855 
3856 static void
generate_ivar_lists()3857 generate_ivar_lists ()
3858 {
3859   tree initlist, ivar_list_template, chain;
3860   tree cast, variable_length_type;
3861   int size;
3862 
3863   generating_instance_variables = 1;
3864 
3865   if (!objc_ivar_template)
3866     objc_ivar_template = build_ivar_template ();
3867 
3868   cast
3869     = build_tree_list
3870       (build_tree_list (NULL_TREE, xref_tag (RECORD_TYPE,
3871 					 get_identifier (UTAG_IVAR_LIST))),
3872        NULL_TREE);
3873   variable_length_type = groktypename (cast);
3874 
3875   /* Only generate class variables for the root of the inheritance
3876      hierarchy since these will be the same for every class.  */
3877 
3878   if (CLASS_SUPER_NAME (implementation_template) == NULL_TREE
3879       && (chain = TYPE_FIELDS (objc_class_template)))
3880     {
3881       size = list_length (chain);
3882 
3883       ivar_list_template = build_ivar_list_template (objc_ivar_template, size);
3884       initlist = build_ivar_list_initializer (objc_ivar_template, chain);
3885 
3886       UOBJC_CLASS_VARIABLES_decl
3887 	= generate_ivars_list (ivar_list_template, "_OBJC_CLASS_VARIABLES",
3888 			       size, initlist);
3889       TREE_TYPE (UOBJC_CLASS_VARIABLES_decl) = variable_length_type;
3890     }
3891   else
3892     UOBJC_CLASS_VARIABLES_decl = 0;
3893 
3894   chain = CLASS_IVARS (implementation_template);
3895   if (chain)
3896     {
3897       size = list_length (chain);
3898       ivar_list_template = build_ivar_list_template (objc_ivar_template, size);
3899       initlist = build_ivar_list_initializer (objc_ivar_template, chain);
3900 
3901       UOBJC_INSTANCE_VARIABLES_decl
3902 	= generate_ivars_list (ivar_list_template, "_OBJC_INSTANCE_VARIABLES",
3903 			       size, initlist);
3904       TREE_TYPE (UOBJC_INSTANCE_VARIABLES_decl) = variable_length_type;
3905     }
3906   else
3907     UOBJC_INSTANCE_VARIABLES_decl = 0;
3908 
3909   generating_instance_variables = 0;
3910 }
3911 
3912 static tree
build_dispatch_table_initializer(type,entries)3913 build_dispatch_table_initializer (type, entries)
3914      tree type;
3915      tree entries;
3916 {
3917   tree initlist = NULL_TREE;
3918 
3919   do
3920     {
3921       tree elemlist = NULL_TREE;
3922 
3923       elemlist = tree_cons (NULL_TREE,
3924 			    build_selector (METHOD_SEL_NAME (entries)),
3925 			    NULL_TREE);
3926 
3927       /* Generate the method encoding if we don't have one already.  */
3928       if (! METHOD_ENCODING (entries))
3929 	METHOD_ENCODING (entries) =
3930 	  encode_method_def (METHOD_DEFINITION (entries));
3931 
3932       elemlist = tree_cons (NULL_TREE,
3933 			    add_objc_string (METHOD_ENCODING (entries),
3934 					     meth_var_types),
3935 			    elemlist);
3936 
3937       elemlist = tree_cons (NULL_TREE,
3938 			    build_unary_op (ADDR_EXPR,
3939 					    METHOD_DEFINITION (entries), 1),
3940 			    elemlist);
3941 
3942       initlist = tree_cons (NULL_TREE,
3943 			    build_constructor (type, nreverse (elemlist)),
3944 			    initlist);
3945 
3946       entries = TREE_CHAIN (entries);
3947     }
3948   while (entries);
3949 
3950   return build_constructor (build_array_type (type, 0), nreverse (initlist));
3951 }
3952 
3953 /* To accomplish method prototyping without generating all kinds of
3954    inane warnings, the definition of the dispatch table entries were
3955    changed from:
3956 
3957    	struct objc_method { SEL _cmd; ...; id (*_imp)(); };
3958    to:
3959    	struct objc_method { SEL _cmd; ...; void *_imp; };  */
3960 
3961 static tree
build_method_template()3962 build_method_template ()
3963 {
3964   tree _SLT_record;
3965   tree decl_specs, field_decl, field_decl_chain;
3966 
3967   _SLT_record = start_struct (RECORD_TYPE, get_identifier (UTAG_METHOD));
3968 
3969   /* struct objc_selector *_cmd; */
3970   decl_specs = tree_cons (NULL_TREE,
3971 			  xref_tag (RECORD_TYPE,
3972 				    get_identifier (TAG_SELECTOR)),
3973 			  NULL_TREE);
3974   field_decl = build1 (INDIRECT_REF, NULL_TREE, get_identifier ("_cmd"));
3975 
3976   field_decl = grokfield (input_filename, lineno, field_decl,
3977 			  decl_specs, NULL_TREE);
3978   field_decl_chain = field_decl;
3979 
3980   decl_specs = tree_cons (NULL_TREE, ridpointers[(int) RID_CHAR], NULL_TREE);
3981   field_decl = build1 (INDIRECT_REF, NULL_TREE,
3982 		       get_identifier ("method_types"));
3983   field_decl = grokfield (input_filename, lineno, field_decl,
3984 			  decl_specs, NULL_TREE);
3985   chainon (field_decl_chain, field_decl);
3986 
3987   /* void *_imp; */
3988 
3989   decl_specs = tree_cons (NULL_TREE, ridpointers[(int) RID_VOID], NULL_TREE);
3990   field_decl = build1 (INDIRECT_REF, NULL_TREE, get_identifier ("_imp"));
3991   field_decl = grokfield (input_filename, lineno, field_decl,
3992 			  decl_specs, NULL_TREE);
3993   chainon (field_decl_chain, field_decl);
3994 
3995   finish_struct (_SLT_record, field_decl_chain, NULL_TREE);
3996 
3997   return _SLT_record;
3998 }
3999 
4000 
4001 static tree
generate_dispatch_table(type,name,size,list)4002 generate_dispatch_table (type, name, size, list)
4003      tree type;
4004      const char *name;
4005      int size;
4006      tree list;
4007 {
4008   tree sc_spec, decl_specs, decl, initlist;
4009 
4010   sc_spec = tree_cons (NULL_TREE, ridpointers[(int) RID_STATIC], NULL_TREE);
4011   decl_specs = tree_cons (NULL_TREE, type, sc_spec);
4012 
4013   decl = start_decl (synth_id_with_class_suffix (name, objc_implementation_context),
4014 		     decl_specs, 1, NULL_TREE);
4015 
4016   initlist = build_tree_list (NULL_TREE, build_int_2 (0, 0));
4017   initlist = tree_cons (NULL_TREE, build_int_2 (size, 0), initlist);
4018   initlist = tree_cons (NULL_TREE, list, initlist);
4019 
4020   finish_decl (decl,
4021 	       build_constructor (TREE_TYPE (decl), nreverse (initlist)),
4022 	       NULL_TREE);
4023 
4024   return decl;
4025 }
4026 
4027 static void
generate_dispatch_tables()4028 generate_dispatch_tables ()
4029 {
4030   tree initlist, chain, method_list_template;
4031   tree cast, variable_length_type;
4032   int size;
4033 
4034   if (!objc_method_template)
4035     objc_method_template = build_method_template ();
4036 
4037   cast
4038     = build_tree_list
4039       (build_tree_list (NULL_TREE,
4040 			xref_tag (RECORD_TYPE,
4041 				  get_identifier (UTAG_METHOD_LIST))),
4042        NULL_TREE);
4043 
4044   variable_length_type = groktypename (cast);
4045 
4046   chain = CLASS_CLS_METHODS (objc_implementation_context);
4047   if (chain)
4048     {
4049       size = list_length (chain);
4050 
4051       method_list_template
4052 	= build_method_list_template (objc_method_template, size);
4053       initlist
4054 	= build_dispatch_table_initializer (objc_method_template, chain);
4055 
4056       UOBJC_CLASS_METHODS_decl
4057 	= generate_dispatch_table (method_list_template,
4058 				   ((TREE_CODE (objc_implementation_context)
4059 				     == CLASS_IMPLEMENTATION_TYPE)
4060 				    ? "_OBJC_CLASS_METHODS"
4061 				    : "_OBJC_CATEGORY_CLASS_METHODS"),
4062 				   size, initlist);
4063       TREE_TYPE (UOBJC_CLASS_METHODS_decl) = variable_length_type;
4064     }
4065   else
4066     UOBJC_CLASS_METHODS_decl = 0;
4067 
4068   chain = CLASS_NST_METHODS (objc_implementation_context);
4069   if (chain)
4070     {
4071       size = list_length (chain);
4072 
4073       method_list_template
4074 	= build_method_list_template (objc_method_template, size);
4075       initlist
4076 	= build_dispatch_table_initializer (objc_method_template, chain);
4077 
4078       if (TREE_CODE (objc_implementation_context) == CLASS_IMPLEMENTATION_TYPE)
4079 	UOBJC_INSTANCE_METHODS_decl
4080 	  = generate_dispatch_table (method_list_template,
4081 				     "_OBJC_INSTANCE_METHODS",
4082 				     size, initlist);
4083       else
4084 	/* We have a category.  */
4085 	UOBJC_INSTANCE_METHODS_decl
4086 	  = generate_dispatch_table (method_list_template,
4087 				     "_OBJC_CATEGORY_INSTANCE_METHODS",
4088 				     size, initlist);
4089       TREE_TYPE (UOBJC_INSTANCE_METHODS_decl) = variable_length_type;
4090     }
4091   else
4092     UOBJC_INSTANCE_METHODS_decl = 0;
4093 }
4094 
4095 static tree
generate_protocol_list(i_or_p)4096 generate_protocol_list (i_or_p)
4097      tree i_or_p;
4098 {
4099   tree initlist, decl_specs, sc_spec;
4100   tree refs_decl, expr_decl, lproto, e, plist;
4101   tree cast_type;
4102   int size = 0;
4103 
4104   if (TREE_CODE (i_or_p) == CLASS_INTERFACE_TYPE
4105       || TREE_CODE (i_or_p) == CATEGORY_INTERFACE_TYPE)
4106     plist = CLASS_PROTOCOL_LIST (i_or_p);
4107   else if (TREE_CODE (i_or_p) == PROTOCOL_INTERFACE_TYPE)
4108     plist = PROTOCOL_LIST (i_or_p);
4109   else
4110     abort ();
4111 
4112   cast_type = groktypename
4113     (build_tree_list
4114      (build_tree_list (NULL_TREE,
4115 		       xref_tag (RECORD_TYPE,
4116 				 get_identifier (UTAG_PROTOCOL))),
4117       build1 (INDIRECT_REF, NULL_TREE, NULL_TREE)));
4118 
4119   /* Compute size.  */
4120   for (lproto = plist; lproto; lproto = TREE_CHAIN (lproto))
4121     if (TREE_CODE (TREE_VALUE (lproto)) == PROTOCOL_INTERFACE_TYPE
4122 	&& PROTOCOL_FORWARD_DECL (TREE_VALUE (lproto)))
4123       size++;
4124 
4125   /* Build initializer.  */
4126   initlist = tree_cons (NULL_TREE, build_int_2 (0, 0), NULL_TREE);
4127 
4128   e = build_int_2 (size, 0);
4129   TREE_TYPE (e) = cast_type;
4130   initlist = tree_cons (NULL_TREE, e, initlist);
4131 
4132   for (lproto = plist; lproto; lproto = TREE_CHAIN (lproto))
4133     {
4134       tree pval = TREE_VALUE (lproto);
4135 
4136       if (TREE_CODE (pval) == PROTOCOL_INTERFACE_TYPE
4137 	  && PROTOCOL_FORWARD_DECL (pval))
4138 	{
4139 	  e = build_unary_op (ADDR_EXPR, PROTOCOL_FORWARD_DECL (pval), 0);
4140 	  initlist = tree_cons (NULL_TREE, e, initlist);
4141 	}
4142     }
4143 
4144   /* static struct objc_protocol *refs[n]; */
4145 
4146   sc_spec = tree_cons (NULL_TREE, ridpointers[(int) RID_STATIC], NULL_TREE);
4147   decl_specs = tree_cons (NULL_TREE, xref_tag (RECORD_TYPE,
4148 					   get_identifier (UTAG_PROTOCOL)),
4149 			  sc_spec);
4150 
4151   if (TREE_CODE (i_or_p) == PROTOCOL_INTERFACE_TYPE)
4152     expr_decl = build_nt (ARRAY_REF,
4153 			  synth_id_with_class_suffix ("_OBJC_PROTOCOL_REFS",
4154 						      i_or_p),
4155 			  build_int_2 (size + 2, 0));
4156   else if (TREE_CODE (i_or_p) == CLASS_INTERFACE_TYPE)
4157     expr_decl = build_nt (ARRAY_REF,
4158 			  synth_id_with_class_suffix ("_OBJC_CLASS_PROTOCOLS",
4159 						      i_or_p),
4160 			  build_int_2 (size + 2, 0));
4161   else if (TREE_CODE (i_or_p) == CATEGORY_INTERFACE_TYPE)
4162     expr_decl
4163       = build_nt (ARRAY_REF,
4164 		  synth_id_with_class_suffix ("_OBJC_CATEGORY_PROTOCOLS",
4165 					      i_or_p),
4166 		  build_int_2 (size + 2, 0));
4167   else
4168     abort ();
4169 
4170   expr_decl = build1 (INDIRECT_REF, NULL_TREE, expr_decl);
4171 
4172   refs_decl = start_decl (expr_decl, decl_specs, 1, NULL_TREE);
4173   DECL_CONTEXT (refs_decl) = NULL_TREE;
4174 
4175   finish_decl (refs_decl, build_constructor (TREE_TYPE (refs_decl),
4176 					     nreverse (initlist)),
4177 	       NULL_TREE);
4178 
4179   return refs_decl;
4180 }
4181 
4182 static tree
build_category_initializer(type,cat_name,class_name,instance_methods,class_methods,protocol_list)4183 build_category_initializer (type, cat_name, class_name,
4184 			    instance_methods, class_methods, protocol_list)
4185      tree type;
4186      tree cat_name;
4187      tree class_name;
4188      tree instance_methods;
4189      tree class_methods;
4190      tree protocol_list;
4191 {
4192   tree initlist = NULL_TREE, expr;
4193 
4194   initlist = tree_cons (NULL_TREE, cat_name, initlist);
4195   initlist = tree_cons (NULL_TREE, class_name, initlist);
4196 
4197   if (!instance_methods)
4198     initlist = tree_cons (NULL_TREE, build_int_2 (0, 0), initlist);
4199   else
4200     {
4201       expr = build_unary_op (ADDR_EXPR, instance_methods, 0);
4202       initlist = tree_cons (NULL_TREE, expr, initlist);
4203     }
4204   if (!class_methods)
4205     initlist = tree_cons (NULL_TREE, build_int_2 (0, 0), initlist);
4206   else
4207     {
4208       expr = build_unary_op (ADDR_EXPR, class_methods, 0);
4209       initlist = tree_cons (NULL_TREE, expr, initlist);
4210     }
4211 
4212   /* protocol_list = */
4213   if (!protocol_list)
4214      initlist = tree_cons (NULL_TREE, build_int_2 (0, 0), initlist);
4215   else
4216      {
4217        tree cast_type2 = groktypename
4218 	 (build_tree_list
4219 	  (build_tree_list (NULL_TREE,
4220 			    xref_tag (RECORD_TYPE,
4221 				      get_identifier (UTAG_PROTOCOL))),
4222 	   build1 (INDIRECT_REF, NULL_TREE,
4223 		   build1 (INDIRECT_REF, NULL_TREE, NULL_TREE))));
4224 
4225 	expr = build_unary_op (ADDR_EXPR, protocol_list, 0);
4226 	TREE_TYPE (expr) = cast_type2;
4227 	initlist = tree_cons (NULL_TREE, expr, initlist);
4228      }
4229 
4230   return build_constructor (type, nreverse (initlist));
4231 }
4232 
4233 /* struct objc_class {
4234      struct objc_class *isa;
4235      struct objc_class *super_class;
4236      char *name;
4237      long version;
4238      long info;
4239      long instance_size;
4240      struct objc_ivar_list *ivars;
4241      struct objc_method_list *methods;
4242      if (flag_next_runtime)
4243        struct objc_cache *cache;
4244      else {
4245        struct sarray *dtable;
4246        struct objc_class *subclass_list;
4247        struct objc_class *sibling_class;
4248      }
4249      struct objc_protocol_list *protocols;
4250      void *gc_object_type;
4251    };  */
4252 
4253 static tree
build_shared_structure_initializer(type,isa,super,name,size,status,dispatch_table,ivar_list,protocol_list)4254 build_shared_structure_initializer (type, isa, super, name, size, status,
4255 				    dispatch_table, ivar_list, protocol_list)
4256      tree type;
4257      tree isa;
4258      tree super;
4259      tree name;
4260      tree size;
4261      int status;
4262      tree dispatch_table;
4263      tree ivar_list;
4264      tree protocol_list;
4265 {
4266   tree initlist = NULL_TREE, expr;
4267 
4268   /* isa = */
4269   initlist = tree_cons (NULL_TREE, isa, initlist);
4270 
4271   /* super_class = */
4272   initlist = tree_cons (NULL_TREE, super, initlist);
4273 
4274   /* name = */
4275   initlist = tree_cons (NULL_TREE, default_conversion (name), initlist);
4276 
4277   /* version = */
4278   initlist = tree_cons (NULL_TREE, build_int_2 (0, 0), initlist);
4279 
4280   /* info = */
4281   initlist = tree_cons (NULL_TREE, build_int_2 (status, 0), initlist);
4282 
4283   /* instance_size = */
4284   initlist = tree_cons (NULL_TREE, size, initlist);
4285 
4286   /* objc_ivar_list = */
4287   if (!ivar_list)
4288     initlist = tree_cons (NULL_TREE, build_int_2 (0, 0), initlist);
4289   else
4290     {
4291       expr = build_unary_op (ADDR_EXPR, ivar_list, 0);
4292       initlist = tree_cons (NULL_TREE, expr, initlist);
4293     }
4294 
4295   /* objc_method_list = */
4296   if (!dispatch_table)
4297     initlist = tree_cons (NULL_TREE, build_int_2 (0, 0), initlist);
4298   else
4299     {
4300       expr = build_unary_op (ADDR_EXPR, dispatch_table, 0);
4301       initlist = tree_cons (NULL_TREE, expr, initlist);
4302     }
4303 
4304   if (flag_next_runtime)
4305     /* method_cache = */
4306     initlist = tree_cons (NULL_TREE, build_int_2 (0, 0), initlist);
4307   else
4308     {
4309       /* dtable = */
4310       initlist = tree_cons (NULL_TREE, build_int_2 (0, 0), initlist);
4311 
4312       /* subclass_list = */
4313       initlist = tree_cons (NULL_TREE, build_int_2 (0, 0), initlist);
4314 
4315       /* sibling_class = */
4316       initlist = tree_cons (NULL_TREE, build_int_2 (0, 0), initlist);
4317     }
4318 
4319   /* protocol_list = */
4320   if (! protocol_list)
4321     initlist = tree_cons (NULL_TREE, build_int_2 (0, 0), initlist);
4322   else
4323      {
4324        tree cast_type2
4325 	 = groktypename
4326 	 (build_tree_list
4327 	  (build_tree_list (NULL_TREE,
4328 			    xref_tag (RECORD_TYPE,
4329 				      get_identifier (UTAG_PROTOCOL))),
4330 	   build1 (INDIRECT_REF, NULL_TREE,
4331 		   build1 (INDIRECT_REF, NULL_TREE, NULL_TREE))));
4332 
4333      expr = build_unary_op (ADDR_EXPR, protocol_list, 0);
4334      TREE_TYPE (expr) = cast_type2;
4335      initlist = tree_cons (NULL_TREE, expr, initlist);
4336      }
4337 
4338   /* gc_object_type = NULL */
4339   initlist = tree_cons (NULL_TREE, build_int_2 (0, 0), initlist);
4340 
4341   return build_constructor (type, nreverse (initlist));
4342 }
4343 
4344 /* static struct objc_category _OBJC_CATEGORY_<name> = { ... };  */
4345 
4346 static void
generate_category(cat)4347 generate_category (cat)
4348      tree cat;
4349 {
4350   tree sc_spec, decl_specs, decl;
4351   tree initlist, cat_name_expr, class_name_expr;
4352   tree protocol_decl, category;
4353 
4354   add_class_reference (CLASS_NAME (cat));
4355   cat_name_expr = add_objc_string (CLASS_SUPER_NAME (cat), class_names);
4356 
4357   class_name_expr = add_objc_string (CLASS_NAME (cat), class_names);
4358 
4359   category = CLASS_CATEGORY_LIST (implementation_template);
4360 
4361   /* find the category interface from the class it is associated with */
4362   while (category)
4363     {
4364       if (CLASS_SUPER_NAME (cat) == CLASS_SUPER_NAME (category))
4365 	break;
4366       category = CLASS_CATEGORY_LIST (category);
4367     }
4368 
4369   if (category && CLASS_PROTOCOL_LIST (category))
4370     {
4371       generate_protocol_references (CLASS_PROTOCOL_LIST (category));
4372       protocol_decl = generate_protocol_list (category);
4373     }
4374   else
4375     protocol_decl = 0;
4376 
4377   sc_spec = tree_cons (NULL_TREE, ridpointers[(int) RID_STATIC], NULL_TREE);
4378   decl_specs = tree_cons (NULL_TREE, objc_category_template, sc_spec);
4379 
4380   decl = start_decl (synth_id_with_class_suffix ("_OBJC_CATEGORY",
4381 						 objc_implementation_context),
4382 		     decl_specs, 1, NULL_TREE);
4383 
4384   initlist = build_category_initializer (TREE_TYPE (decl),
4385 					 cat_name_expr, class_name_expr,
4386 					 UOBJC_INSTANCE_METHODS_decl,
4387 					 UOBJC_CLASS_METHODS_decl,
4388 					 protocol_decl);
4389 
4390   TREE_USED (decl) = 1;
4391   finish_decl (decl, initlist, NULL_TREE);
4392 }
4393 
4394 /* static struct objc_class _OBJC_METACLASS_Foo={ ... };
4395    static struct objc_class _OBJC_CLASS_Foo={ ... };  */
4396 
4397 static void
generate_shared_structures()4398 generate_shared_structures ()
4399 {
4400   tree sc_spec, decl_specs, decl;
4401   tree name_expr, super_expr, root_expr;
4402   tree my_root_id = NULL_TREE, my_super_id = NULL_TREE;
4403   tree cast_type, initlist, protocol_decl;
4404 
4405   my_super_id = CLASS_SUPER_NAME (implementation_template);
4406   if (my_super_id)
4407     {
4408       add_class_reference (my_super_id);
4409 
4410       /* Compute "my_root_id" - this is required for code generation.
4411          the "isa" for all meta class structures points to the root of
4412          the inheritance hierarchy (e.g. "__Object")...  */
4413       my_root_id = my_super_id;
4414       do
4415 	{
4416 	  tree my_root_int = lookup_interface (my_root_id);
4417 
4418 	  if (my_root_int && CLASS_SUPER_NAME (my_root_int))
4419 	    my_root_id = CLASS_SUPER_NAME (my_root_int);
4420 	  else
4421 	    break;
4422 	}
4423       while (1);
4424     }
4425   else
4426     /* No super class.  */
4427     my_root_id = CLASS_NAME (implementation_template);
4428 
4429   cast_type
4430     = groktypename (build_tree_list (build_tree_list (NULL_TREE,
4431 						      objc_class_template),
4432 				     build1 (INDIRECT_REF,
4433 					     NULL_TREE, NULL_TREE)));
4434 
4435   name_expr = add_objc_string (CLASS_NAME (implementation_template),
4436 			       class_names);
4437 
4438   /* Install class `isa' and `super' pointers at runtime.  */
4439   if (my_super_id)
4440     {
4441       super_expr = add_objc_string (my_super_id, class_names);
4442       super_expr = build_c_cast (cast_type, super_expr); /* cast! */
4443     }
4444   else
4445     super_expr = build_int_2 (0, 0);
4446 
4447   root_expr = add_objc_string (my_root_id, class_names);
4448   root_expr = build_c_cast (cast_type, root_expr); /* cast! */
4449 
4450   if (CLASS_PROTOCOL_LIST (implementation_template))
4451     {
4452       generate_protocol_references
4453 	(CLASS_PROTOCOL_LIST (implementation_template));
4454       protocol_decl = generate_protocol_list (implementation_template);
4455     }
4456   else
4457     protocol_decl = 0;
4458 
4459   /* static struct objc_class _OBJC_METACLASS_Foo = { ... }; */
4460 
4461   sc_spec = build_tree_list (NULL_TREE, ridpointers[(int) RID_STATIC]);
4462   decl_specs = tree_cons (NULL_TREE, objc_class_template, sc_spec);
4463 
4464   decl = start_decl (DECL_NAME (UOBJC_METACLASS_decl), decl_specs, 1,
4465 		     NULL_TREE);
4466 
4467   initlist
4468     = build_shared_structure_initializer
4469       (TREE_TYPE (decl),
4470        root_expr, super_expr, name_expr,
4471        convert (integer_type_node, TYPE_SIZE_UNIT (objc_class_template)),
4472        2 /*CLS_META*/,
4473        UOBJC_CLASS_METHODS_decl,
4474        UOBJC_CLASS_VARIABLES_decl,
4475        protocol_decl);
4476 
4477   finish_decl (decl, initlist, NULL_TREE);
4478 
4479   /* static struct objc_class _OBJC_CLASS_Foo={ ... }; */
4480 
4481   decl = start_decl (DECL_NAME (UOBJC_CLASS_decl), decl_specs, 1,
4482 		     NULL_TREE);
4483 
4484   initlist
4485     = build_shared_structure_initializer
4486       (TREE_TYPE (decl),
4487        build_unary_op (ADDR_EXPR, UOBJC_METACLASS_decl, 0),
4488        super_expr, name_expr,
4489        convert (integer_type_node,
4490 		TYPE_SIZE_UNIT (CLASS_STATIC_TEMPLATE
4491 				(implementation_template))),
4492        1 /*CLS_FACTORY*/,
4493        UOBJC_INSTANCE_METHODS_decl,
4494        UOBJC_INSTANCE_VARIABLES_decl,
4495        protocol_decl);
4496 
4497   finish_decl (decl, initlist, NULL_TREE);
4498 }
4499 
4500 static tree
synth_id_with_class_suffix(preamble,ctxt)4501 synth_id_with_class_suffix (preamble, ctxt)
4502      const char *preamble;
4503      tree ctxt;
4504 {
4505   char *string;
4506   if (TREE_CODE (ctxt) == CLASS_IMPLEMENTATION_TYPE
4507       || TREE_CODE (ctxt) == CLASS_INTERFACE_TYPE)
4508     {
4509       const char *const class_name
4510 	= IDENTIFIER_POINTER (CLASS_NAME (objc_implementation_context));
4511       string = (char *) alloca (strlen (preamble) + strlen (class_name) + 3);
4512       sprintf (string, "%s_%s", preamble,
4513 	       IDENTIFIER_POINTER (CLASS_NAME (ctxt)));
4514     }
4515   else if (TREE_CODE (ctxt) == CATEGORY_IMPLEMENTATION_TYPE
4516 	   || TREE_CODE (ctxt) == CATEGORY_INTERFACE_TYPE)
4517     {
4518       /* We have a category.  */
4519       const char *const class_name
4520 	= IDENTIFIER_POINTER (CLASS_NAME (objc_implementation_context));
4521       const char *const class_super_name
4522 	= IDENTIFIER_POINTER (CLASS_SUPER_NAME (objc_implementation_context));
4523       string = (char *) alloca (strlen (preamble)
4524 				+ strlen (class_name)
4525 				+ strlen (class_super_name)
4526 				+ 3);
4527       sprintf (string, "%s_%s_%s", preamble, class_name, class_super_name);
4528     }
4529   else if (TREE_CODE (ctxt) == PROTOCOL_INTERFACE_TYPE)
4530     {
4531       const char *protocol_name = IDENTIFIER_POINTER (PROTOCOL_NAME (ctxt));
4532       string
4533 	= (char *) alloca (strlen (preamble) + strlen (protocol_name) + 3);
4534       sprintf (string, "%s_%s", preamble, protocol_name);
4535     }
4536   else
4537     abort ();
4538 
4539   return get_identifier (string);
4540 }
4541 
4542 static int
is_objc_type_qualifier(node)4543 is_objc_type_qualifier (node)
4544      tree node;
4545 {
4546   return (TREE_CODE (node) == IDENTIFIER_NODE
4547 	  && (node == ridpointers [(int) RID_CONST]
4548 	      || node == ridpointers [(int) RID_VOLATILE]
4549 	      || node == ridpointers [(int) RID_IN]
4550 	      || node == ridpointers [(int) RID_OUT]
4551 	      || node == ridpointers [(int) RID_INOUT]
4552 	      || node == ridpointers [(int) RID_BYCOPY]
4553               || node == ridpointers [(int) RID_BYREF]
4554 	      || node == ridpointers [(int) RID_ONEWAY]));
4555 }
4556 
4557 /* If type is empty or only type qualifiers are present, add default
4558    type of id (otherwise grokdeclarator will default to int).  */
4559 
4560 static tree
adjust_type_for_id_default(type)4561 adjust_type_for_id_default (type)
4562      tree type;
4563 {
4564   tree declspecs, chain;
4565 
4566   if (!type)
4567     return build_tree_list (build_tree_list (NULL_TREE, objc_object_reference),
4568 			    build1 (INDIRECT_REF, NULL_TREE, NULL_TREE));
4569 
4570   declspecs = TREE_PURPOSE (type);
4571 
4572   /* Determine if a typespec is present.  */
4573   for (chain = declspecs;
4574        chain;
4575        chain = TREE_CHAIN (chain))
4576     {
4577       if (TYPED_OBJECT (TREE_VALUE (chain))
4578           && !(TREE_VALUE (type)
4579                && TREE_CODE (TREE_VALUE (type)) == INDIRECT_REF))
4580         error ("can not use an object as parameter to a method\n");
4581       if (!is_objc_type_qualifier (TREE_VALUE (chain)))
4582 	return type;
4583     }
4584 
4585   return build_tree_list (tree_cons (NULL_TREE, objc_object_reference,
4586 				     declspecs),
4587 			  build1 (INDIRECT_REF, NULL_TREE, NULL_TREE));
4588 }
4589 
4590 /*   Usage:
4591   		keyworddecl:
4592   			selector ':' '(' typename ')' identifier
4593 
4594      Purpose:
4595   		Transform an Objective-C keyword argument into
4596   		the C equivalent parameter declarator.
4597 
4598      In:	key_name, an "identifier_node" (optional).
4599   		arg_type, a  "tree_list" (optional).
4600   		arg_name, an "identifier_node".
4601 
4602      Note:	It would be really nice to strongly type the preceding
4603   		arguments in the function prototype; however, then I
4604   		could not use the "accessor" macros defined in "tree.h".
4605 
4606      Out:	an instance of "keyword_decl".  */
4607 
4608 tree
build_keyword_decl(key_name,arg_type,arg_name)4609 build_keyword_decl (key_name, arg_type, arg_name)
4610      tree key_name;
4611      tree arg_type;
4612      tree arg_name;
4613 {
4614   tree keyword_decl;
4615 
4616   /* If no type is specified, default to "id".  */
4617   arg_type = adjust_type_for_id_default (arg_type);
4618 
4619   keyword_decl = make_node (KEYWORD_DECL);
4620 
4621   TREE_TYPE (keyword_decl) = arg_type;
4622   KEYWORD_ARG_NAME (keyword_decl) = arg_name;
4623   KEYWORD_KEY_NAME (keyword_decl) = key_name;
4624 
4625   return keyword_decl;
4626 }
4627 
4628 /* Given a chain of keyword_decl's, synthesize the full keyword selector.  */
4629 
4630 static tree
build_keyword_selector(selector)4631 build_keyword_selector (selector)
4632      tree selector;
4633 {
4634   int len = 0;
4635   tree key_chain, key_name;
4636   char *buf;
4637 
4638   /* Scan the selector to see how much space we'll need.  */
4639   for (key_chain = selector; key_chain; key_chain = TREE_CHAIN (key_chain))
4640     {
4641       if (TREE_CODE (selector) == KEYWORD_DECL)
4642 	key_name = KEYWORD_KEY_NAME (key_chain);
4643       else if (TREE_CODE (selector) == TREE_LIST)
4644 	key_name = TREE_PURPOSE (key_chain);
4645       else
4646 	abort ();
4647 
4648       if (key_name)
4649 	len += IDENTIFIER_LENGTH (key_name) + 1;
4650       else
4651 	/* Just a ':' arg.  */
4652 	len++;
4653     }
4654 
4655   buf = (char *) alloca (len + 1);
4656   /* Start the buffer out as an empty string.  */
4657   buf[0] = '\0';
4658 
4659   for (key_chain = selector; key_chain; key_chain = TREE_CHAIN (key_chain))
4660     {
4661       if (TREE_CODE (selector) == KEYWORD_DECL)
4662 	key_name = KEYWORD_KEY_NAME (key_chain);
4663       else if (TREE_CODE (selector) == TREE_LIST)
4664 	key_name = TREE_PURPOSE (key_chain);
4665       else
4666 	abort ();
4667 
4668       if (key_name)
4669 	strcat (buf, IDENTIFIER_POINTER (key_name));
4670       strcat (buf, ":");
4671     }
4672 
4673   return get_identifier (buf);
4674 }
4675 
4676 /* Used for declarations and definitions.  */
4677 
4678 tree
build_method_decl(code,ret_type,selector,add_args)4679 build_method_decl (code, ret_type, selector, add_args)
4680      enum tree_code code;
4681      tree ret_type;
4682      tree selector;
4683      tree add_args;
4684 {
4685   tree method_decl;
4686 
4687   /* If no type is specified, default to "id".  */
4688   ret_type = adjust_type_for_id_default (ret_type);
4689 
4690   method_decl = make_node (code);
4691   TREE_TYPE (method_decl) = ret_type;
4692 
4693   /* If we have a keyword selector, create an identifier_node that
4694      represents the full selector name (`:' included)...  */
4695   if (TREE_CODE (selector) == KEYWORD_DECL)
4696     {
4697       METHOD_SEL_NAME (method_decl) = build_keyword_selector (selector);
4698       METHOD_SEL_ARGS (method_decl) = selector;
4699       METHOD_ADD_ARGS (method_decl) = add_args;
4700     }
4701   else
4702     {
4703       METHOD_SEL_NAME (method_decl) = selector;
4704       METHOD_SEL_ARGS (method_decl) = NULL_TREE;
4705       METHOD_ADD_ARGS (method_decl) = NULL_TREE;
4706     }
4707 
4708   return method_decl;
4709 }
4710 
4711 #define METHOD_DEF 0
4712 #define METHOD_REF 1
4713 
4714 /* Used by `build_objc_method_call' and `comp_method_types'.  Return
4715    an argument list for method METH.  CONTEXT is either METHOD_DEF or
4716    METHOD_REF, saying whether we are trying to define a method or call
4717    one.  SUPERFLAG says this is for a send to super; this makes a
4718    difference for the NeXT calling sequence in which the lookup and
4719    the method call are done together.  */
4720 
4721 static tree
get_arg_type_list(meth,context,superflag)4722 get_arg_type_list (meth, context, superflag)
4723      tree meth;
4724      int context;
4725      int superflag;
4726 {
4727   tree arglist, akey;
4728 
4729   /* Receiver type.  */
4730   if (flag_next_runtime && superflag)
4731     arglist = build_tree_list (NULL_TREE, super_type);
4732   else if (context == METHOD_DEF)
4733     arglist = build_tree_list (NULL_TREE, TREE_TYPE (self_decl));
4734   else
4735     arglist = build_tree_list (NULL_TREE, id_type);
4736 
4737   /* Selector type - will eventually change to `int'.  */
4738   chainon (arglist, build_tree_list (NULL_TREE, selector_type));
4739 
4740   /* Build a list of argument types.  */
4741   for (akey = METHOD_SEL_ARGS (meth); akey; akey = TREE_CHAIN (akey))
4742     {
4743       tree arg_decl = groktypename_in_parm_context (TREE_TYPE (akey));
4744       chainon (arglist, build_tree_list (NULL_TREE, TREE_TYPE (arg_decl)));
4745     }
4746 
4747   if (METHOD_ADD_ARGS (meth) == objc_ellipsis_node)
4748     /* We have a `, ...' immediately following the selector,
4749        finalize the arglist...simulate get_parm_info (0).  */
4750     ;
4751   else if (METHOD_ADD_ARGS (meth))
4752     {
4753       /* we have a variable length selector */
4754       tree add_arg_list = TREE_CHAIN (METHOD_ADD_ARGS (meth));
4755       chainon (arglist, add_arg_list);
4756     }
4757   else
4758     /* finalize the arglist...simulate get_parm_info (1) */
4759     chainon (arglist, build_tree_list (NULL_TREE, void_type_node));
4760 
4761   return arglist;
4762 }
4763 
4764 static tree
check_duplicates(hsh)4765 check_duplicates (hsh)
4766      hash hsh;
4767 {
4768   tree meth = NULL_TREE;
4769 
4770   if (hsh)
4771     {
4772       meth = hsh->key;
4773 
4774       if (hsh->list)
4775         {
4776 	  /* We have two methods with the same name and different types.  */
4777 	  attr loop;
4778 	  char type = (TREE_CODE (meth) == INSTANCE_METHOD_DECL) ? '-' : '+';
4779 
4780 	  warning ("multiple declarations for method `%s'",
4781 		   IDENTIFIER_POINTER (METHOD_SEL_NAME (meth)));
4782 
4783 	  warn_with_method ("using", type, meth);
4784 	  for (loop = hsh->list; loop; loop = loop->next)
4785 	    warn_with_method ("also found", type, loop->value);
4786         }
4787     }
4788   return meth;
4789 }
4790 
4791 /* If RECEIVER is a class reference, return the identifier node for
4792    the referenced class.  RECEIVER is created by get_class_reference,
4793    so we check the exact form created depending on which runtimes are
4794    used.  */
4795 
4796 static tree
receiver_is_class_object(receiver)4797 receiver_is_class_object (receiver)
4798       tree receiver;
4799 {
4800   tree chain, exp, arg;
4801 
4802   /* The receiver is 'self' in the context of a class method.  */
4803   if (objc_method_context
4804       && receiver == self_decl
4805       && TREE_CODE (objc_method_context) == CLASS_METHOD_DECL)
4806     {
4807       return CLASS_NAME (objc_implementation_context);
4808     }
4809 
4810   if (flag_next_runtime)
4811     {
4812       /* The receiver is a variable created by
4813          build_class_reference_decl.  */
4814       if (TREE_CODE (receiver) == VAR_DECL
4815 	  && TREE_TYPE (receiver) == objc_class_type)
4816 	/* Look up the identifier.  */
4817 	for (chain = cls_ref_chain; chain; chain = TREE_CHAIN (chain))
4818 	  if (TREE_PURPOSE (chain) == receiver)
4819 	    return TREE_VALUE (chain);
4820     }
4821   else
4822     {
4823       /* The receiver is a function call that returns an id.  Check if
4824 	 it is a call to objc_getClass, if so, pick up the class name.  */
4825       if (TREE_CODE (receiver) == CALL_EXPR
4826 	  && (exp = TREE_OPERAND (receiver, 0))
4827 	  && TREE_CODE (exp) == ADDR_EXPR
4828 	  && (exp = TREE_OPERAND (exp, 0))
4829 	  && TREE_CODE (exp) == FUNCTION_DECL
4830 	  && exp == objc_get_class_decl
4831 	  /* We have a call to objc_getClass!  */
4832 	  && (arg = TREE_OPERAND (receiver, 1))
4833 	  && TREE_CODE (arg) == TREE_LIST
4834 	  && (arg = TREE_VALUE (arg)))
4835 	{
4836 	  STRIP_NOPS (arg);
4837 	  if (TREE_CODE (arg) == ADDR_EXPR
4838 	      && (arg = TREE_OPERAND (arg, 0))
4839 	      && TREE_CODE (arg) == STRING_CST)
4840 	    /* Finally, we have the class name.  */
4841 	    return get_identifier (TREE_STRING_POINTER (arg));
4842 	}
4843     }
4844   return 0;
4845 }
4846 
4847 /* If we are currently building a message expr, this holds
4848    the identifier of the selector of the message.  This is
4849    used when printing warnings about argument mismatches.  */
4850 
4851 static tree current_objc_message_selector = 0;
4852 
4853 tree
objc_message_selector()4854 objc_message_selector ()
4855 {
4856   return current_objc_message_selector;
4857 }
4858 
4859 /* Construct an expression for sending a message.
4860    MESS has the object to send to in TREE_PURPOSE
4861    and the argument list (including selector) in TREE_VALUE.
4862 
4863    (*(<abstract_decl>(*)())_msg)(receiver, selTransTbl[n], ...);
4864    (*(<abstract_decl>(*)())_msgSuper)(receiver, selTransTbl[n], ...);  */
4865 
4866 tree
build_message_expr(mess)4867 build_message_expr (mess)
4868      tree mess;
4869 {
4870   tree receiver = TREE_PURPOSE (mess);
4871   tree sel_name;
4872   tree args = TREE_VALUE (mess);
4873   tree method_params = NULL_TREE;
4874 
4875   if (TREE_CODE (receiver) == ERROR_MARK)
4876     return error_mark_node;
4877 
4878   /* Obtain the full selector name.  */
4879   if (TREE_CODE (args) == IDENTIFIER_NODE)
4880     /* A unary selector.  */
4881     sel_name = args;
4882   else if (TREE_CODE (args) == TREE_LIST)
4883     sel_name = build_keyword_selector (args);
4884   else
4885     abort ();
4886 
4887   /* Build the parameter list to give to the method.  */
4888   if (TREE_CODE (args) == TREE_LIST)
4889     {
4890       tree chain = args, prev = NULL_TREE;
4891 
4892       /* We have a keyword selector--check for comma expressions.  */
4893       while (chain)
4894 	{
4895 	  tree element = TREE_VALUE (chain);
4896 
4897 	  /* We have a comma expression, must collapse...  */
4898 	  if (TREE_CODE (element) == TREE_LIST)
4899 	    {
4900 	      if (prev)
4901 		TREE_CHAIN (prev) = element;
4902 	      else
4903 		args = element;
4904 	    }
4905 	  prev = chain;
4906 	  chain = TREE_CHAIN (chain);
4907         }
4908       method_params = args;
4909     }
4910 
4911   return finish_message_expr (receiver, sel_name, method_params);
4912 }
4913 
4914 /* The 'finish_message_expr' routine is called from within
4915    'build_message_expr' for non-template functions.  In the case of
4916    C++ template functions, it is called from 'build_expr_from_tree'
4917    (in decl2.c) after RECEIVER and METHOD_PARAMS have been expanded.  */
4918 
4919 tree
finish_message_expr(receiver,sel_name,method_params)4920 finish_message_expr (receiver, sel_name, method_params)
4921      tree receiver, sel_name, method_params;
4922 {
4923   tree method_prototype = NULL_TREE, class_ident = NULL_TREE;
4924   tree selector, self_object, retval;
4925   int statically_typed = 0, statically_allocated = 0;
4926 
4927   /* Determine receiver type.  */
4928   tree rtype = TREE_TYPE (receiver);
4929   int super = IS_SUPER (rtype);
4930 
4931   if (! super)
4932     {
4933       if (TREE_STATIC_TEMPLATE (rtype))
4934 	statically_allocated = 1;
4935       else if (TREE_CODE (rtype) == POINTER_TYPE
4936 	       && TREE_STATIC_TEMPLATE (TREE_TYPE (rtype)))
4937 	statically_typed = 1;
4938       else if ((flag_next_runtime
4939 		|| (IS_ID (rtype)))
4940 	       && (class_ident = receiver_is_class_object (receiver)))
4941 	;
4942       else if (! IS_ID (rtype)
4943 	       /* Allow any type that matches objc_class_type.  */
4944 	       && ! comptypes (rtype, objc_class_type))
4945 	{
4946 	  warning ("invalid receiver type `%s'",
4947 		   gen_declaration (rtype, errbuf));
4948 	}
4949       if (statically_allocated)
4950 	receiver = build_unary_op (ADDR_EXPR, receiver, 0);
4951 
4952       /* Don't evaluate the receiver twice.  */
4953       receiver = save_expr (receiver);
4954       self_object = receiver;
4955     }
4956   else
4957     /* If sending to `super', use current self as the object.  */
4958     self_object = self_decl;
4959 
4960   /* Determine operation return type.  */
4961 
4962   if (super)
4963     {
4964       tree iface;
4965 
4966       if (CLASS_SUPER_NAME (implementation_template))
4967 	{
4968 	  iface
4969 	    = lookup_interface (CLASS_SUPER_NAME (implementation_template));
4970 
4971 	  if (TREE_CODE (objc_method_context) == INSTANCE_METHOD_DECL)
4972 	    method_prototype = lookup_instance_method_static (iface, sel_name);
4973 	  else
4974 	    method_prototype = lookup_class_method_static (iface, sel_name);
4975 
4976 	  if (iface && !method_prototype)
4977 	    warning ("`%s' does not respond to `%s'",
4978 		     IDENTIFIER_POINTER (CLASS_SUPER_NAME (implementation_template)),
4979 		     IDENTIFIER_POINTER (sel_name));
4980 	}
4981       else
4982 	{
4983 	  error ("no super class declared in interface for `%s'",
4984 		 IDENTIFIER_POINTER (CLASS_NAME (implementation_template)));
4985 	  return error_mark_node;
4986 	}
4987 
4988     }
4989   else if (statically_allocated)
4990     {
4991       tree ctype = TREE_TYPE (rtype);
4992       tree iface = lookup_interface (TYPE_NAME (rtype));
4993 
4994       if (iface)
4995 	method_prototype = lookup_instance_method_static (iface, sel_name);
4996 
4997       if (! method_prototype && ctype && TYPE_PROTOCOL_LIST (ctype))
4998 	method_prototype
4999 	  = lookup_method_in_protocol_list (TYPE_PROTOCOL_LIST (ctype),
5000 					    sel_name, 0);
5001 
5002       if (!method_prototype)
5003 	warning ("`%s' does not respond to `%s'",
5004 		 IDENTIFIER_POINTER (TYPE_NAME (rtype)),
5005 		 IDENTIFIER_POINTER (sel_name));
5006     }
5007   else if (statically_typed)
5008     {
5009       tree ctype = TREE_TYPE (rtype);
5010 
5011       /* `self' is now statically_typed.  All methods should be visible
5012          within the context of the implementation.  */
5013       if (objc_implementation_context
5014 	  && CLASS_NAME (objc_implementation_context) == TYPE_NAME (ctype))
5015 	{
5016 	  method_prototype
5017 	    = lookup_instance_method_static (implementation_template,
5018 					     sel_name);
5019 
5020 	  if (! method_prototype && TYPE_PROTOCOL_LIST (ctype))
5021 	    method_prototype
5022 	      = lookup_method_in_protocol_list (TYPE_PROTOCOL_LIST (ctype),
5023 						sel_name, 0);
5024 
5025 	  if (! method_prototype
5026 	      && implementation_template != objc_implementation_context)
5027 	    /* The method is not published in the interface.  Check
5028                locally.  */
5029 	    method_prototype
5030 	      = lookup_method (CLASS_NST_METHODS (objc_implementation_context),
5031 			       sel_name);
5032 	}
5033       else
5034 	{
5035 	  tree iface;
5036 
5037 	  if ((iface = lookup_interface (TYPE_NAME (ctype))))
5038 	    method_prototype = lookup_instance_method_static (iface, sel_name);
5039 
5040           if (! method_prototype)
5041 	    {
5042 	      tree protocol_list = TYPE_PROTOCOL_LIST (ctype);
5043 	      if (protocol_list)
5044 		method_prototype
5045 		  = lookup_method_in_protocol_list (protocol_list,
5046 						    sel_name, 0);
5047 	    }
5048 	}
5049 
5050       if (!method_prototype)
5051         warning ("`%s' does not respond to `%s'",
5052 		 IDENTIFIER_POINTER (TYPE_NAME (ctype)),
5053 		 IDENTIFIER_POINTER (sel_name));
5054     }
5055   else if (class_ident)
5056     {
5057       if (objc_implementation_context
5058 	  && CLASS_NAME (objc_implementation_context) == class_ident)
5059 	{
5060 	  method_prototype
5061 	    = lookup_class_method_static (implementation_template, sel_name);
5062 
5063 	  if (!method_prototype
5064 	      && implementation_template != objc_implementation_context)
5065 	    /* The method is not published in the interface. Check
5066                locally.  */
5067 	    method_prototype
5068 	      = lookup_method (CLASS_CLS_METHODS (objc_implementation_context),
5069 			       sel_name);
5070 	}
5071       else
5072 	{
5073 	  tree iface;
5074 
5075 	  if ((iface = lookup_interface (class_ident)))
5076 	    method_prototype = lookup_class_method_static (iface, sel_name);
5077 	}
5078 
5079       if (!method_prototype)
5080 	{
5081 	  warning ("cannot find class (factory) method");
5082 	  warning ("return type for `%s' defaults to id",
5083 		   IDENTIFIER_POINTER (sel_name));
5084 	}
5085     }
5086   else if (IS_PROTOCOL_QUALIFIED_ID (rtype))
5087     {
5088       /* An anonymous object that has been qualified with a protocol.  */
5089 
5090       tree protocol_list = TYPE_PROTOCOL_LIST (rtype);
5091 
5092       method_prototype = lookup_method_in_protocol_list (protocol_list,
5093 							 sel_name, 0);
5094 
5095       if (!method_prototype)
5096 	{
5097           hash hsh;
5098 
5099 	  warning ("method `%s' not implemented by protocol",
5100 		   IDENTIFIER_POINTER (sel_name));
5101 
5102           /* Try and find the method signature in the global pools.  */
5103 
5104           if (!(hsh = hash_lookup (nst_method_hash_list, sel_name)))
5105 	    hsh = hash_lookup (cls_method_hash_list, sel_name);
5106 
5107           if (!(method_prototype = check_duplicates (hsh)))
5108 	    warning ("return type defaults to id");
5109 	}
5110     }
5111   else
5112     {
5113       hash hsh;
5114 
5115       /* We think we have an instance...loophole: extern id Object; */
5116       hsh = hash_lookup (nst_method_hash_list, sel_name);
5117 
5118       if (!hsh)
5119 	/* For various loopholes */
5120 	hsh = hash_lookup (cls_method_hash_list, sel_name);
5121 
5122       method_prototype = check_duplicates (hsh);
5123       if (!method_prototype)
5124 	{
5125 	  warning ("cannot find method");
5126 	  warning ("return type for `%s' defaults to id",
5127 		   IDENTIFIER_POINTER (sel_name));
5128 	}
5129     }
5130 
5131   /* Save the selector name for printing error messages.  */
5132   current_objc_message_selector = sel_name;
5133 
5134   /* Build the parameters list for looking up the method.
5135      These are the object itself and the selector.  */
5136 
5137   if (flag_typed_selectors)
5138     selector = build_typed_selector_reference (sel_name, method_prototype);
5139   else
5140     selector = build_selector_reference (sel_name);
5141 
5142   retval = build_objc_method_call (super, method_prototype,
5143 				   receiver, self_object,
5144 				   selector, method_params);
5145 
5146   current_objc_message_selector = 0;
5147 
5148   return retval;
5149 }
5150 
5151 /* Build a tree expression to send OBJECT the operation SELECTOR,
5152    looking up the method on object LOOKUP_OBJECT (often same as OBJECT),
5153    assuming the method has prototype METHOD_PROTOTYPE.
5154    (That is an INSTANCE_METHOD_DECL or CLASS_METHOD_DECL.)
5155    Use METHOD_PARAMS as list of args to pass to the method.
5156    If SUPER_FLAG is nonzero, we look up the superclass's method.  */
5157 
5158 static tree
build_objc_method_call(super_flag,method_prototype,lookup_object,object,selector,method_params)5159 build_objc_method_call (super_flag, method_prototype, lookup_object, object,
5160 			selector, method_params)
5161      int super_flag;
5162      tree method_prototype, lookup_object, object, selector, method_params;
5163 {
5164   tree sender = (super_flag ? umsg_super_decl : umsg_decl);
5165   tree rcv_p = (super_flag
5166 		? build_pointer_type (xref_tag (RECORD_TYPE,
5167 						get_identifier (TAG_SUPER)))
5168 		: id_type);
5169 
5170   if (flag_next_runtime)
5171     {
5172       if (! method_prototype)
5173 	{
5174 	  method_params = tree_cons (NULL_TREE, lookup_object,
5175 				     tree_cons (NULL_TREE, selector,
5176 						method_params));
5177 	  assemble_external (sender);
5178 	  return build_function_call (sender, method_params);
5179 	}
5180       else
5181 	{
5182 	  /* This is a real kludge, but it is used only for the Next.
5183 	     Clobber the data type of SENDER temporarily to accept
5184 	     all the arguments for this operation, and to return
5185 	     whatever this operation returns.  */
5186 	  tree arglist = NULL_TREE, retval, savarg, savret;
5187 	  tree ret_type = groktypename (TREE_TYPE (method_prototype));
5188 
5189 	  /* Save the proper contents of SENDER's data type.  */
5190 	  savarg = TYPE_ARG_TYPES (TREE_TYPE (sender));
5191 	  savret = TREE_TYPE (TREE_TYPE (sender));
5192 
5193 	  /* Install this method's argument types.  */
5194 	  arglist = get_arg_type_list (method_prototype, METHOD_REF,
5195 				       super_flag);
5196 	  TYPE_ARG_TYPES (TREE_TYPE (sender)) = arglist;
5197 
5198 	  /* Install this method's return type.  */
5199 	  TREE_TYPE (TREE_TYPE (sender)) = ret_type;
5200 
5201 	  /* Call SENDER with all the parameters.  This will do type
5202 	     checking using the arg types for this method.  */
5203 	  method_params = tree_cons (NULL_TREE, lookup_object,
5204 				     tree_cons (NULL_TREE, selector,
5205 						method_params));
5206 	  assemble_external (sender);
5207 	  retval = build_function_call (sender, method_params);
5208 
5209 	  /* Restore SENDER's return/argument types.  */
5210 	  TYPE_ARG_TYPES (TREE_TYPE (sender)) = savarg;
5211 	  TREE_TYPE (TREE_TYPE (sender)) = savret;
5212 	  return retval;
5213 	}
5214     }
5215   else
5216     {
5217       /* This is the portable way.
5218 	 First call the lookup function to get a pointer to the method,
5219 	 then cast the pointer, then call it with the method arguments.  */
5220       tree method;
5221 
5222       /* Avoid trouble since we may evaluate each of these twice.  */
5223       object = save_expr (object);
5224       selector = save_expr (selector);
5225 
5226       lookup_object = build_c_cast (rcv_p, lookup_object);
5227 
5228       assemble_external (sender);
5229       method
5230 	= build_function_call (sender,
5231 			       tree_cons (NULL_TREE, lookup_object,
5232 					  tree_cons (NULL_TREE, selector,
5233 						     NULL_TREE)));
5234 
5235       /* If we have a method prototype, construct the data type this
5236 	 method needs, and cast what we got from SENDER into a pointer
5237 	 to that type.  */
5238       if (method_prototype)
5239 	{
5240 	  tree arglist = get_arg_type_list (method_prototype, METHOD_REF,
5241 					    super_flag);
5242 	  tree valtype = groktypename (TREE_TYPE (method_prototype));
5243 	  tree fake_function_type = build_function_type (valtype, arglist);
5244 	  TREE_TYPE (method) = build_pointer_type (fake_function_type);
5245 	}
5246       else
5247 	TREE_TYPE (method)
5248 	  = build_pointer_type (build_function_type (ptr_type_node, NULL_TREE));
5249 
5250       /* Pass the object to the method.  */
5251       assemble_external (method);
5252       return build_function_call (method,
5253 				  tree_cons (NULL_TREE, object,
5254 					     tree_cons (NULL_TREE, selector,
5255 							method_params)));
5256     }
5257 }
5258 
5259 static void
build_protocol_reference(p)5260 build_protocol_reference (p)
5261      tree p;
5262 {
5263   tree decl, ident, ptype;
5264 
5265   /* extern struct objc_protocol _OBJC_PROTOCOL_<mumble>; */
5266 
5267   ident = synth_id_with_class_suffix ("_OBJC_PROTOCOL", p);
5268   ptype
5269     = groktypename (build_tree_list (build_tree_list (NULL_TREE,
5270 						      objc_protocol_template),
5271 				     NULL_TREE));
5272 
5273   if (IDENTIFIER_GLOBAL_VALUE (ident))
5274     decl = IDENTIFIER_GLOBAL_VALUE (ident); /* Set by pushdecl.  */
5275   else
5276     {
5277       decl = build_decl (VAR_DECL, ident, ptype);
5278       DECL_EXTERNAL (decl) = 1;
5279       TREE_PUBLIC (decl) = 1;
5280       TREE_USED (decl) = 1;
5281       DECL_ARTIFICIAL (decl) = 1;
5282 
5283       make_decl_rtl (decl, 0);
5284       pushdecl_top_level (decl);
5285    }
5286 
5287   PROTOCOL_FORWARD_DECL (p) = decl;
5288 }
5289 
5290 /* This function is called by the parser when (and only when) a
5291    @protocol() expression is found, in order to compile it.  */
5292 tree
build_protocol_expr(protoname)5293 build_protocol_expr (protoname)
5294      tree protoname;
5295 {
5296   tree expr;
5297   tree p = lookup_protocol (protoname);
5298 
5299   if (!p)
5300     {
5301       error ("cannot find protocol declaration for `%s'",
5302 	     IDENTIFIER_POINTER (protoname));
5303       return error_mark_node;
5304     }
5305 
5306   if (!PROTOCOL_FORWARD_DECL (p))
5307     build_protocol_reference (p);
5308 
5309   expr = build_unary_op (ADDR_EXPR, PROTOCOL_FORWARD_DECL (p), 0);
5310 
5311   TREE_TYPE (expr) = protocol_type;
5312 
5313   /* The @protocol() expression is being compiled into a pointer to a
5314      statically allocated instance of the Protocol class.  To become
5315      usable at runtime, the 'isa' pointer of the instance need to be
5316      fixed up at runtime by the runtime library, to point to the
5317      actual 'Protocol' class.  */
5318 
5319   /* For the GNU runtime, put the static Protocol instance in the list
5320      of statically allocated instances, so that we make sure that its
5321      'isa' pointer is fixed up at runtime by the GNU runtime library
5322      to point to the Protocol class (at runtime, when loading the
5323      module, the GNU runtime library loops on the statically allocated
5324      instances (as found in the defs field in objc_symtab) and fixups
5325      all the 'isa' pointers of those objects).  */
5326   if (! flag_next_runtime)
5327     {
5328       /* This type is a struct containing the fields of a Protocol
5329         object.  (Cfr. protocol_type instead is the type of a pointer
5330         to such a struct).  */
5331       tree protocol_struct_type = xref_tag
5332        (RECORD_TYPE, get_identifier (PROTOCOL_OBJECT_CLASS_NAME));
5333       tree *chain;
5334 
5335       /* Look for the list of Protocol statically allocated instances
5336         to fixup at runtime.  Create a new list to hold Protocol
5337         statically allocated instances, if the list is not found.  At
5338         present there is only another list, holding NSConstantString
5339         static instances to be fixed up at runtime.  */
5340       for (chain = &objc_static_instances;
5341 	   *chain && TREE_VALUE (*chain) != protocol_struct_type;
5342 	   chain = &TREE_CHAIN (*chain));
5343       if (!*chain)
5344 	{
5345          *chain = tree_cons (NULL_TREE, protocol_struct_type, NULL_TREE);
5346          add_objc_string (TYPE_NAME (protocol_struct_type),
5347                           class_names);
5348        }
5349 
5350       /* Add this statically allocated instance to the Protocol list.  */
5351       TREE_PURPOSE (*chain) = tree_cons (NULL_TREE,
5352 					 PROTOCOL_FORWARD_DECL (p),
5353 					 TREE_PURPOSE (*chain));
5354     }
5355 
5356 
5357   return expr;
5358 }
5359 
5360 /* This function is called by the parser when a @selector() expression
5361    is found, in order to compile it.  It is only called by the parser
5362    and only to compile a @selector().  */
5363 tree
build_selector_expr(selnamelist)5364 build_selector_expr (selnamelist)
5365      tree selnamelist;
5366 {
5367   tree selname;
5368 
5369   /* Obtain the full selector name.  */
5370   if (TREE_CODE (selnamelist) == IDENTIFIER_NODE)
5371     /* A unary selector.  */
5372     selname = selnamelist;
5373   else if (TREE_CODE (selnamelist) == TREE_LIST)
5374     selname = build_keyword_selector (selnamelist);
5375   else
5376     abort ();
5377 
5378   /* If we are required to check @selector() expressions as they
5379      are found, check that the selector has been declared.  */
5380   if (warn_undeclared_selector)
5381     {
5382       /* Look the selector up in the list of all known class and
5383          instance methods (up to this line) to check that the selector
5384          exists.  */
5385       hash hsh;
5386 
5387       /* First try with instance methods.  */
5388       hsh = hash_lookup (nst_method_hash_list, selname);
5389 
5390       /* If not found, try with class methods.  */
5391       if (!hsh)
5392 	{
5393 	  hsh = hash_lookup (cls_method_hash_list, selname);
5394 	}
5395 
5396       /* If still not found, print out a warning.  */
5397       if (!hsh)
5398 	{
5399 	  warning ("undeclared selector `%s'", IDENTIFIER_POINTER (selname));
5400 	}
5401     }
5402 
5403 
5404   if (flag_typed_selectors)
5405     return build_typed_selector_reference (selname, 0);
5406   else
5407     return build_selector_reference (selname);
5408 }
5409 
5410 tree
build_encode_expr(type)5411 build_encode_expr (type)
5412      tree type;
5413 {
5414   tree result;
5415   const char *string;
5416 
5417   encode_type (type, obstack_object_size (&util_obstack),
5418 	       OBJC_ENCODE_INLINE_DEFS);
5419   obstack_1grow (&util_obstack, 0);    /* null terminate string */
5420   string = obstack_finish (&util_obstack);
5421 
5422   /* Synthesize a string that represents the encoded struct/union.  */
5423   result = my_build_string (strlen (string) + 1, string);
5424   obstack_free (&util_obstack, util_firstobj);
5425   return result;
5426 }
5427 
5428 tree
build_ivar_reference(id)5429 build_ivar_reference (id)
5430      tree id;
5431 {
5432   if (TREE_CODE (objc_method_context) == CLASS_METHOD_DECL)
5433     {
5434       /* Historically, a class method that produced objects (factory
5435 	 method) would assign `self' to the instance that it
5436 	 allocated.  This would effectively turn the class method into
5437 	 an instance method.  Following this assignment, the instance
5438 	 variables could be accessed.  That practice, while safe,
5439 	 violates the simple rule that a class method should not refer
5440 	 to an instance variable.  It's better to catch the cases
5441 	 where this is done unknowingly than to support the above
5442 	 paradigm.  */
5443       warning ("instance variable `%s' accessed in class method",
5444 	       IDENTIFIER_POINTER (id));
5445       TREE_TYPE (self_decl) = instance_type; /* cast */
5446     }
5447 
5448   return build_component_ref (build_indirect_ref (self_decl, "->"), id);
5449 }
5450 
5451 /* Compute a hash value for a given method SEL_NAME.  */
5452 
5453 static size_t
hash_func(sel_name)5454 hash_func (sel_name)
5455      tree sel_name;
5456 {
5457   const unsigned char *s
5458     = (const unsigned char *)IDENTIFIER_POINTER (sel_name);
5459   size_t h = 0;
5460 
5461   while (*s)
5462     h = h * 67 + *s++ - 113;
5463   return h;
5464 }
5465 
5466 static void
hash_init()5467 hash_init ()
5468 {
5469   nst_method_hash_list = (hash *) ggc_calloc (SIZEHASHTABLE, sizeof (hash));
5470   cls_method_hash_list = (hash *) ggc_calloc (SIZEHASHTABLE, sizeof (hash));
5471 }
5472 
5473 /* WARNING!!!!  hash_enter is called with a method, and will peek
5474    inside to find its selector!  But hash_lookup is given a selector
5475    directly, and looks for the selector that's inside the found
5476    entry's key (method) for comparison.  */
5477 
5478 static void
hash_enter(hashlist,method)5479 hash_enter (hashlist, method)
5480      hash *hashlist;
5481      tree method;
5482 {
5483   hash obj;
5484   int slot = hash_func (METHOD_SEL_NAME (method)) % SIZEHASHTABLE;
5485 
5486   obj = (hash) ggc_alloc (sizeof (struct hashed_entry));
5487   obj->list = 0;
5488   obj->next = hashlist[slot];
5489   obj->key = method;
5490 
5491   hashlist[slot] = obj;		/* append to front */
5492 }
5493 
5494 static hash
hash_lookup(hashlist,sel_name)5495 hash_lookup (hashlist, sel_name)
5496      hash *hashlist;
5497      tree sel_name;
5498 {
5499   hash target;
5500 
5501   target = hashlist[hash_func (sel_name) % SIZEHASHTABLE];
5502 
5503   while (target)
5504     {
5505       if (sel_name == METHOD_SEL_NAME (target->key))
5506 	return target;
5507 
5508       target = target->next;
5509     }
5510   return 0;
5511 }
5512 
5513 static void
hash_add_attr(entry,value)5514 hash_add_attr (entry, value)
5515      hash entry;
5516      tree value;
5517 {
5518   attr obj;
5519 
5520   obj = (attr) ggc_alloc (sizeof (struct hashed_attribute));
5521   obj->next = entry->list;
5522   obj->value = value;
5523 
5524   entry->list = obj;		/* append to front */
5525 }
5526 
5527 static tree
lookup_method(mchain,method)5528 lookup_method (mchain, method)
5529      tree mchain;
5530      tree method;
5531 {
5532   tree key;
5533 
5534   if (TREE_CODE (method) == IDENTIFIER_NODE)
5535     key = method;
5536   else
5537     key = METHOD_SEL_NAME (method);
5538 
5539   while (mchain)
5540     {
5541       if (METHOD_SEL_NAME (mchain) == key)
5542 	return mchain;
5543 
5544       mchain = TREE_CHAIN (mchain);
5545     }
5546   return NULL_TREE;
5547 }
5548 
5549 static tree
lookup_instance_method_static(interface,ident)5550 lookup_instance_method_static (interface, ident)
5551      tree interface;
5552      tree ident;
5553 {
5554   tree inter = interface;
5555   tree chain = CLASS_NST_METHODS (inter);
5556   tree meth = NULL_TREE;
5557 
5558   do
5559     {
5560       if ((meth = lookup_method (chain, ident)))
5561 	return meth;
5562 
5563       if (CLASS_CATEGORY_LIST (inter))
5564 	{
5565 	  tree category = CLASS_CATEGORY_LIST (inter);
5566 	  chain = CLASS_NST_METHODS (category);
5567 
5568 	  do
5569 	    {
5570 	      if ((meth = lookup_method (chain, ident)))
5571 		return meth;
5572 
5573 	      /* Check for instance methods in protocols in categories.  */
5574 	      if (CLASS_PROTOCOL_LIST (category))
5575 		{
5576 		  if ((meth = (lookup_method_in_protocol_list
5577 			       (CLASS_PROTOCOL_LIST (category), ident, 0))))
5578 		    return meth;
5579 		}
5580 
5581 	      if ((category = CLASS_CATEGORY_LIST (category)))
5582 		chain = CLASS_NST_METHODS (category);
5583 	    }
5584 	  while (category);
5585 	}
5586 
5587       if (CLASS_PROTOCOL_LIST (inter))
5588 	{
5589 	  if ((meth = (lookup_method_in_protocol_list
5590 		       (CLASS_PROTOCOL_LIST (inter), ident, 0))))
5591 	    return meth;
5592 	}
5593 
5594       if ((inter = lookup_interface (CLASS_SUPER_NAME (inter))))
5595 	chain = CLASS_NST_METHODS (inter);
5596     }
5597   while (inter);
5598 
5599   return meth;
5600 }
5601 
5602 static tree
lookup_class_method_static(interface,ident)5603 lookup_class_method_static (interface, ident)
5604      tree interface;
5605      tree ident;
5606 {
5607   tree inter = interface;
5608   tree chain = CLASS_CLS_METHODS (inter);
5609   tree meth = NULL_TREE;
5610   tree root_inter = NULL_TREE;
5611 
5612   do
5613     {
5614       if ((meth = lookup_method (chain, ident)))
5615 	return meth;
5616 
5617       if (CLASS_CATEGORY_LIST (inter))
5618 	{
5619 	  tree category = CLASS_CATEGORY_LIST (inter);
5620 	  chain = CLASS_CLS_METHODS (category);
5621 
5622 	  do
5623 	    {
5624 	      if ((meth = lookup_method (chain, ident)))
5625 		return meth;
5626 
5627 	      /* Check for class methods in protocols in categories.  */
5628 	      if (CLASS_PROTOCOL_LIST (category))
5629 		{
5630 		  if ((meth = (lookup_method_in_protocol_list
5631 			       (CLASS_PROTOCOL_LIST (category), ident, 1))))
5632 		    return meth;
5633 		}
5634 
5635 	      if ((category = CLASS_CATEGORY_LIST (category)))
5636 		chain = CLASS_CLS_METHODS (category);
5637 	    }
5638 	  while (category);
5639 	}
5640 
5641       /* Check for class methods in protocols.  */
5642       if (CLASS_PROTOCOL_LIST (inter))
5643 	{
5644 	  if ((meth = (lookup_method_in_protocol_list
5645 		       (CLASS_PROTOCOL_LIST (inter), ident, 1))))
5646 	    return meth;
5647 	}
5648 
5649       root_inter = inter;
5650       if ((inter = lookup_interface (CLASS_SUPER_NAME (inter))))
5651 	chain = CLASS_CLS_METHODS (inter);
5652     }
5653   while (inter);
5654 
5655   /* If no class (factory) method was found, check if an _instance_
5656      method of the same name exists in the root class.  This is what
5657      the Objective-C runtime will do.  */
5658   return lookup_instance_method_static (root_inter, ident);
5659 }
5660 
5661 tree
add_class_method(class,method)5662 add_class_method (class, method)
5663      tree class;
5664      tree method;
5665 {
5666   tree mth;
5667   hash hsh;
5668 
5669   if (!(mth = lookup_method (CLASS_CLS_METHODS (class), method)))
5670     {
5671       /* put method on list in reverse order */
5672       TREE_CHAIN (method) = CLASS_CLS_METHODS (class);
5673       CLASS_CLS_METHODS (class) = method;
5674     }
5675   else
5676     {
5677       if (TREE_CODE (class) == CLASS_IMPLEMENTATION_TYPE)
5678 	error ("duplicate definition of class method `%s'",
5679 	       IDENTIFIER_POINTER (METHOD_SEL_NAME (mth)));
5680       else
5681         {
5682 	  /* Check types; if different, complain.  */
5683 	  if (!comp_proto_with_proto (method, mth))
5684 	    error ("duplicate declaration of class method `%s'",
5685 		   IDENTIFIER_POINTER (METHOD_SEL_NAME (mth)));
5686         }
5687     }
5688 
5689   if (!(hsh = hash_lookup (cls_method_hash_list, METHOD_SEL_NAME (method))))
5690     {
5691       /* Install on a global chain.  */
5692       hash_enter (cls_method_hash_list, method);
5693     }
5694   else
5695     {
5696       /* Check types; if different, add to a list.  */
5697       if (!comp_proto_with_proto (method, hsh->key))
5698         hash_add_attr (hsh, method);
5699     }
5700   return method;
5701 }
5702 
5703 tree
add_instance_method(class,method)5704 add_instance_method (class, method)
5705      tree class;
5706      tree method;
5707 {
5708   tree mth;
5709   hash hsh;
5710 
5711   if (!(mth = lookup_method (CLASS_NST_METHODS (class), method)))
5712     {
5713       /* Put method on list in reverse order.  */
5714       TREE_CHAIN (method) = CLASS_NST_METHODS (class);
5715       CLASS_NST_METHODS (class) = method;
5716     }
5717   else
5718     {
5719       if (TREE_CODE (class) == CLASS_IMPLEMENTATION_TYPE)
5720 	error ("duplicate definition of instance method `%s'",
5721 	       IDENTIFIER_POINTER (METHOD_SEL_NAME (mth)));
5722       else
5723         {
5724 	  /* Check types; if different, complain.  */
5725 	  if (!comp_proto_with_proto (method, mth))
5726 	    error ("duplicate declaration of instance method `%s'",
5727 		   IDENTIFIER_POINTER (METHOD_SEL_NAME (mth)));
5728         }
5729     }
5730 
5731   if (!(hsh = hash_lookup (nst_method_hash_list, METHOD_SEL_NAME (method))))
5732     {
5733       /* Install on a global chain.  */
5734       hash_enter (nst_method_hash_list, method);
5735     }
5736   else
5737     {
5738       /* Check types; if different, add to a list.  */
5739       if (!comp_proto_with_proto (method, hsh->key))
5740         hash_add_attr (hsh, method);
5741     }
5742   return method;
5743 }
5744 
5745 static tree
add_class(class)5746 add_class (class)
5747      tree class;
5748 {
5749   /* Put interfaces on list in reverse order.  */
5750   TREE_CHAIN (class) = interface_chain;
5751   interface_chain = class;
5752   return interface_chain;
5753 }
5754 
5755 static void
add_category(class,category)5756 add_category (class, category)
5757       tree class;
5758       tree category;
5759 {
5760   /* Put categories on list in reverse order.  */
5761   tree cat = CLASS_CATEGORY_LIST (class);
5762 
5763   while (cat)
5764     {
5765       if (CLASS_SUPER_NAME (cat) == CLASS_SUPER_NAME (category))
5766 	warning ("duplicate interface declaration for category `%s(%s)'",
5767 		 IDENTIFIER_POINTER (CLASS_NAME (class)),
5768 		 IDENTIFIER_POINTER (CLASS_SUPER_NAME (category)));
5769       cat = CLASS_CATEGORY_LIST (cat);
5770     }
5771 
5772   CLASS_CATEGORY_LIST (category) = CLASS_CATEGORY_LIST (class);
5773   CLASS_CATEGORY_LIST (class) = category;
5774 }
5775 
5776 /* Called after parsing each instance variable declaration. Necessary to
5777    preserve typedefs and implement public/private...
5778 
5779    PUBLIC is 1 for public, 0 for protected, and 2 for private.  */
5780 
5781 tree
add_instance_variable(class,public,declarator,declspecs,width)5782 add_instance_variable (class, public, declarator, declspecs, width)
5783      tree class;
5784      int public;
5785      tree declarator;
5786      tree declspecs;
5787      tree width;
5788 {
5789   tree field_decl, raw_decl;
5790 
5791   raw_decl = build_tree_list (declspecs, declarator);
5792 
5793   if (CLASS_RAW_IVARS (class))
5794     chainon (CLASS_RAW_IVARS (class), raw_decl);
5795   else
5796     CLASS_RAW_IVARS (class) = raw_decl;
5797 
5798   field_decl = grokfield (input_filename, lineno,
5799 			  declarator, declspecs, width);
5800 
5801   /* Overload the public attribute, it is not used for FIELD_DECLs.  */
5802   switch (public)
5803     {
5804     case 0:
5805       TREE_PUBLIC (field_decl) = 0;
5806       TREE_PRIVATE (field_decl) = 0;
5807       TREE_PROTECTED (field_decl) = 1;
5808       break;
5809 
5810     case 1:
5811       TREE_PUBLIC (field_decl) = 1;
5812       TREE_PRIVATE (field_decl) = 0;
5813       TREE_PROTECTED (field_decl) = 0;
5814       break;
5815 
5816     case 2:
5817       TREE_PUBLIC (field_decl) = 0;
5818       TREE_PRIVATE (field_decl) = 1;
5819       TREE_PROTECTED (field_decl) = 0;
5820       break;
5821 
5822     }
5823 
5824   if (CLASS_IVARS (class))
5825     chainon (CLASS_IVARS (class), field_decl);
5826   else
5827     CLASS_IVARS (class) = field_decl;
5828 
5829   return class;
5830 }
5831 
5832 tree
is_ivar(decl_chain,ident)5833 is_ivar (decl_chain, ident)
5834      tree decl_chain;
5835      tree ident;
5836 {
5837   for ( ; decl_chain; decl_chain = TREE_CHAIN (decl_chain))
5838     if (DECL_NAME (decl_chain) == ident)
5839       return decl_chain;
5840   return NULL_TREE;
5841 }
5842 
5843 /* True if the ivar is private and we are not in its implementation.  */
5844 
5845 int
is_private(decl)5846 is_private (decl)
5847      tree decl;
5848 {
5849   if (TREE_PRIVATE (decl)
5850       && ! is_ivar (CLASS_IVARS (implementation_template), DECL_NAME (decl)))
5851     return 1;
5852   else
5853     return 0;
5854 }
5855 
5856 /* We have an instance variable reference;, check to see if it is public.  */
5857 
5858 int
is_public(expr,identifier)5859 is_public (expr, identifier)
5860      tree expr;
5861      tree identifier;
5862 {
5863   tree basetype = TREE_TYPE (expr);
5864   enum tree_code code = TREE_CODE (basetype);
5865   tree decl;
5866 
5867   if (code == RECORD_TYPE)
5868     {
5869       if (TREE_STATIC_TEMPLATE (basetype))
5870 	{
5871 	  if (!lookup_interface (TYPE_NAME (basetype)))
5872 	    {
5873 	      error ("cannot find interface declaration for `%s'",
5874 		     IDENTIFIER_POINTER (TYPE_NAME (basetype)));
5875 	      return 0;
5876 	    }
5877 
5878 	  if ((decl = is_ivar (TYPE_FIELDS (basetype), identifier)))
5879 	    {
5880 	      if (TREE_PUBLIC (decl))
5881 		return 1;
5882 
5883 	      /* Important difference between the Stepstone translator:
5884 		 all instance variables should be public within the context
5885 		 of the implementation.  */
5886 	      if (objc_implementation_context
5887 		  && (((TREE_CODE (objc_implementation_context)
5888 			== CLASS_IMPLEMENTATION_TYPE)
5889 		       || (TREE_CODE (objc_implementation_context)
5890 			   == CATEGORY_IMPLEMENTATION_TYPE))
5891 		      && (CLASS_NAME (objc_implementation_context)
5892 			  == TYPE_NAME (basetype))))
5893                 {
5894                   int private = is_private (decl);
5895                   if (private)
5896                     error ("instance variable '%s' is declared private",
5897                            IDENTIFIER_POINTER (DECL_NAME (decl)));
5898 
5899                   return !private;
5900                 }
5901 
5902 	      error ("instance variable `%s' is declared %s",
5903 		     IDENTIFIER_POINTER (identifier),
5904 		     TREE_PRIVATE (decl) ? "private" : "protected");
5905 	      return 0;
5906 	    }
5907 	}
5908 
5909       else if (objc_implementation_context && (basetype == objc_object_reference))
5910 	{
5911 	  TREE_TYPE (expr) = uprivate_record;
5912 	  warning ("static access to object of type `id'");
5913 	}
5914     }
5915 
5916   return 1;
5917 }
5918 
5919 /* Make sure all entries in CHAIN are also in LIST.  */
5920 
5921 static int
check_methods(chain,list,mtype)5922 check_methods (chain, list, mtype)
5923      tree chain;
5924      tree list;
5925      int mtype;
5926 {
5927   int first = 1;
5928 
5929   while (chain)
5930     {
5931       if (!lookup_method (list, chain))
5932 	{
5933 	  if (first)
5934 	    {
5935 	      if (TREE_CODE (objc_implementation_context)
5936 		  == CLASS_IMPLEMENTATION_TYPE)
5937 		warning ("incomplete implementation of class `%s'",
5938 			 IDENTIFIER_POINTER (CLASS_NAME (objc_implementation_context)));
5939 	      else if (TREE_CODE (objc_implementation_context)
5940 		       == CATEGORY_IMPLEMENTATION_TYPE)
5941 		warning ("incomplete implementation of category `%s'",
5942 			 IDENTIFIER_POINTER (CLASS_SUPER_NAME (objc_implementation_context)));
5943 	      first = 0;
5944 	    }
5945 
5946 	  warning ("method definition for `%c%s' not found",
5947 		   mtype, IDENTIFIER_POINTER (METHOD_SEL_NAME (chain)));
5948 	}
5949 
5950       chain = TREE_CHAIN (chain);
5951     }
5952 
5953     return first;
5954 }
5955 
5956 /* Check if CLASS, or its superclasses, explicitly conforms to PROTOCOL.  */
5957 
5958 static int
conforms_to_protocol(class,protocol)5959 conforms_to_protocol (class, protocol)
5960      tree class;
5961      tree protocol;
5962 {
5963    if (TREE_CODE (protocol) == PROTOCOL_INTERFACE_TYPE)
5964      {
5965        tree p = CLASS_PROTOCOL_LIST (class);
5966        while (p && TREE_VALUE (p) != protocol)
5967 	 p = TREE_CHAIN (p);
5968 
5969        if (!p)
5970 	 {
5971 	   tree super = (CLASS_SUPER_NAME (class)
5972 			 ? lookup_interface (CLASS_SUPER_NAME (class))
5973 			 : NULL_TREE);
5974 	   int tmp = super ? conforms_to_protocol (super, protocol) : 0;
5975 	   if (!tmp)
5976 	     return 0;
5977 	 }
5978      }
5979 
5980    return 1;
5981 }
5982 
5983 /* Make sure all methods in CHAIN are accessible as MTYPE methods in
5984    CONTEXT.  This is one of two mechanisms to check protocol integrity.  */
5985 
5986 static int
check_methods_accessible(chain,context,mtype)5987 check_methods_accessible (chain, context, mtype)
5988      tree chain;
5989      tree context;
5990      int mtype;
5991 {
5992   int first = 1;
5993   tree list;
5994   tree base_context = context;
5995 
5996   while (chain)
5997     {
5998       context = base_context;
5999       while (context)
6000 	{
6001 	  if (mtype == '+')
6002 	    list = CLASS_CLS_METHODS (context);
6003 	  else
6004 	    list = CLASS_NST_METHODS (context);
6005 
6006 	  if (lookup_method (list, chain))
6007 	      break;
6008 
6009 	  else if (TREE_CODE (context) == CLASS_IMPLEMENTATION_TYPE
6010 		   || TREE_CODE (context) == CLASS_INTERFACE_TYPE)
6011 	    context = (CLASS_SUPER_NAME (context)
6012 		       ? lookup_interface (CLASS_SUPER_NAME (context))
6013 		       : NULL_TREE);
6014 
6015 	  else if (TREE_CODE (context) == CATEGORY_IMPLEMENTATION_TYPE
6016 		   || TREE_CODE (context) == CATEGORY_INTERFACE_TYPE)
6017 	    context = (CLASS_NAME (context)
6018 		       ? lookup_interface (CLASS_NAME (context))
6019 		       : NULL_TREE);
6020 	  else
6021 	    abort ();
6022 	}
6023 
6024       if (context == NULL_TREE)
6025 	{
6026 	  if (first)
6027 	    {
6028 	      if (TREE_CODE (objc_implementation_context)
6029 		  == CLASS_IMPLEMENTATION_TYPE)
6030 		warning ("incomplete implementation of class `%s'",
6031 			 IDENTIFIER_POINTER
6032 			   (CLASS_NAME (objc_implementation_context)));
6033 	      else if (TREE_CODE (objc_implementation_context)
6034 		       == CATEGORY_IMPLEMENTATION_TYPE)
6035 		warning ("incomplete implementation of category `%s'",
6036 			 IDENTIFIER_POINTER
6037 			   (CLASS_SUPER_NAME (objc_implementation_context)));
6038 	      first = 0;
6039 	    }
6040 	  warning ("method definition for `%c%s' not found",
6041 		   mtype, IDENTIFIER_POINTER (METHOD_SEL_NAME (chain)));
6042 	}
6043 
6044       chain = TREE_CHAIN (chain); /* next method...  */
6045     }
6046   return first;
6047 }
6048 
6049 /* Check whether the current interface (accessible via
6050    'objc_implementation_context') actually implements protocol P, along
6051    with any protocols that P inherits.  */
6052 
6053 static void
check_protocol(p,type,name)6054 check_protocol (p, type, name)
6055      tree p;
6056      const char *type;
6057      const char *name;
6058 {
6059   if (TREE_CODE (p) == PROTOCOL_INTERFACE_TYPE)
6060     {
6061       int f1, f2;
6062 
6063       /* Ensure that all protocols have bodies!  */
6064       if (warn_protocol)
6065 	{
6066 	  f1 = check_methods (PROTOCOL_CLS_METHODS (p),
6067 			      CLASS_CLS_METHODS (objc_implementation_context),
6068 			      '+');
6069 	  f2 = check_methods (PROTOCOL_NST_METHODS (p),
6070 			      CLASS_NST_METHODS (objc_implementation_context),
6071 			      '-');
6072 	}
6073       else
6074 	{
6075 	  f1 = check_methods_accessible (PROTOCOL_CLS_METHODS (p),
6076 					 objc_implementation_context,
6077 					 '+');
6078 	  f2 = check_methods_accessible (PROTOCOL_NST_METHODS (p),
6079 					 objc_implementation_context,
6080 					 '-');
6081 	}
6082 
6083       if (!f1 || !f2)
6084 	warning ("%s `%s' does not fully implement the `%s' protocol",
6085 		 type, name, IDENTIFIER_POINTER (PROTOCOL_NAME (p)));
6086     }
6087 
6088   /* Check protocols recursively.  */
6089   if (PROTOCOL_LIST (p))
6090     {
6091       tree subs = PROTOCOL_LIST (p);
6092       tree super_class =
6093 	lookup_interface (CLASS_SUPER_NAME (implementation_template));
6094 
6095       while (subs)
6096 	{
6097 	  tree sub = TREE_VALUE (subs);
6098 
6099 	  /* If the superclass does not conform to the protocols
6100 	     inherited by P, then we must!  */
6101 	  if (!super_class || !conforms_to_protocol (super_class, sub))
6102 	    check_protocol (sub, type, name);
6103 	  subs = TREE_CHAIN (subs);
6104 	}
6105     }
6106 }
6107 
6108 /* Check whether the current interface (accessible via
6109    'objc_implementation_context') actually implements the protocols listed
6110    in PROTO_LIST.  */
6111 
6112 static void
check_protocols(proto_list,type,name)6113 check_protocols (proto_list, type, name)
6114      tree proto_list;
6115      const char *type;
6116      const char *name;
6117 {
6118   for ( ; proto_list; proto_list = TREE_CHAIN (proto_list))
6119     {
6120       tree p = TREE_VALUE (proto_list);
6121 
6122       check_protocol (p, type, name);
6123     }
6124 }
6125 
6126 /* Make sure that the class CLASS_NAME is defined
6127    CODE says which kind of thing CLASS_NAME ought to be.
6128    It can be CLASS_INTERFACE_TYPE, CLASS_IMPLEMENTATION_TYPE,
6129    CATEGORY_INTERFACE_TYPE, or CATEGORY_IMPLEMENTATION_TYPE.  */
6130 
6131 tree
start_class(code,class_name,super_name,protocol_list)6132 start_class (code, class_name, super_name, protocol_list)
6133      enum tree_code code;
6134      tree class_name;
6135      tree super_name;
6136      tree protocol_list;
6137 {
6138   tree class, decl;
6139 
6140   if (objc_implementation_context)
6141     {
6142       warning ("`@end' missing in implementation context");
6143       finish_class (objc_implementation_context);
6144       objc_ivar_chain = NULL_TREE;
6145       objc_implementation_context = NULL_TREE;
6146     }
6147 
6148   class = make_node (code);
6149   TYPE_BINFO (class) = make_tree_vec (6);
6150 
6151   CLASS_NAME (class) = class_name;
6152   CLASS_SUPER_NAME (class) = super_name;
6153   CLASS_CLS_METHODS (class) = NULL_TREE;
6154 
6155   if (! is_class_name (class_name) && (decl = lookup_name (class_name)))
6156     {
6157       error ("`%s' redeclared as different kind of symbol",
6158 	     IDENTIFIER_POINTER (class_name));
6159       error_with_decl (decl, "previous declaration of `%s'");
6160     }
6161 
6162   if (code == CLASS_IMPLEMENTATION_TYPE)
6163     {
6164       {
6165         tree chain;
6166 
6167         for (chain = implemented_classes; chain; chain = TREE_CHAIN (chain))
6168            if (TREE_VALUE (chain) == class_name)
6169 	     {
6170 	       error ("reimplementation of class `%s'",
6171 		      IDENTIFIER_POINTER (class_name));
6172 	       return error_mark_node;
6173 	     }
6174         implemented_classes = tree_cons (NULL_TREE, class_name,
6175 					 implemented_classes);
6176       }
6177 
6178       /* Pre-build the following entities - for speed/convenience.  */
6179       if (!self_id)
6180 	  self_id = get_identifier ("self");
6181       if (!ucmd_id)
6182         ucmd_id = get_identifier ("_cmd");
6183       if (!unused_list)
6184 	unused_list
6185 	  = build_tree_list (get_identifier ("__unused__"), NULL_TREE);
6186       if (!objc_super_template)
6187 	objc_super_template = build_super_template ();
6188 
6189       /* Reset for multiple classes per file.  */
6190       method_slot = 0;
6191 
6192       objc_implementation_context = class;
6193 
6194       /* Lookup the interface for this implementation.  */
6195 
6196       if (!(implementation_template = lookup_interface (class_name)))
6197         {
6198 	  warning ("cannot find interface declaration for `%s'",
6199 		   IDENTIFIER_POINTER (class_name));
6200 	  add_class (implementation_template = objc_implementation_context);
6201         }
6202 
6203       /* If a super class has been specified in the implementation,
6204 	 insure it conforms to the one specified in the interface.  */
6205 
6206       if (super_name
6207 	  && (super_name != CLASS_SUPER_NAME (implementation_template)))
6208         {
6209 	  tree previous_name = CLASS_SUPER_NAME (implementation_template);
6210           const char *const name =
6211 	    previous_name ? IDENTIFIER_POINTER (previous_name) : "";
6212 	  error ("conflicting super class name `%s'",
6213 		 IDENTIFIER_POINTER (super_name));
6214 	  error ("previous declaration of `%s'", name);
6215         }
6216 
6217       else if (! super_name)
6218 	{
6219 	  CLASS_SUPER_NAME (objc_implementation_context)
6220 	    = CLASS_SUPER_NAME (implementation_template);
6221 	}
6222     }
6223 
6224   else if (code == CLASS_INTERFACE_TYPE)
6225     {
6226       if (lookup_interface (class_name))
6227         warning ("duplicate interface declaration for class `%s'",
6228                  IDENTIFIER_POINTER (class_name));
6229       else
6230         add_class (class);
6231 
6232       if (protocol_list)
6233 	CLASS_PROTOCOL_LIST (class)
6234 	  = lookup_and_install_protocols (protocol_list);
6235     }
6236 
6237   else if (code == CATEGORY_INTERFACE_TYPE)
6238     {
6239       tree class_category_is_assoc_with;
6240 
6241       /* For a category, class_name is really the name of the class that
6242 	 the following set of methods will be associated with. We must
6243 	 find the interface so that can derive the objects template.  */
6244 
6245       if (!(class_category_is_assoc_with = lookup_interface (class_name)))
6246 	{
6247 	  error ("cannot find interface declaration for `%s'",
6248 		 IDENTIFIER_POINTER (class_name));
6249 	  exit (FATAL_EXIT_CODE);
6250 	}
6251       else
6252         add_category (class_category_is_assoc_with, class);
6253 
6254       if (protocol_list)
6255 	CLASS_PROTOCOL_LIST (class)
6256 	  = lookup_and_install_protocols (protocol_list);
6257     }
6258 
6259   else if (code == CATEGORY_IMPLEMENTATION_TYPE)
6260     {
6261       /* Pre-build the following entities for speed/convenience.  */
6262       if (!self_id)
6263         self_id = get_identifier ("self");
6264       if (!ucmd_id)
6265         ucmd_id = get_identifier ("_cmd");
6266       if (!unused_list)
6267 	unused_list
6268 	  = build_tree_list (get_identifier ("__unused__"), NULL_TREE);
6269       if (!objc_super_template)
6270 	objc_super_template = build_super_template ();
6271 
6272       /* Reset for multiple classes per file.  */
6273       method_slot = 0;
6274 
6275       objc_implementation_context = class;
6276 
6277       /* For a category, class_name is really the name of the class that
6278 	 the following set of methods will be associated with.  We must
6279 	 find the interface so that can derive the objects template.  */
6280 
6281       if (!(implementation_template = lookup_interface (class_name)))
6282         {
6283 	  error ("cannot find interface declaration for `%s'",
6284 		 IDENTIFIER_POINTER (class_name));
6285 	  exit (FATAL_EXIT_CODE);
6286         }
6287     }
6288   return class;
6289 }
6290 
6291 tree
continue_class(class)6292 continue_class (class)
6293      tree class;
6294 {
6295   if (TREE_CODE (class) == CLASS_IMPLEMENTATION_TYPE
6296       || TREE_CODE (class) == CATEGORY_IMPLEMENTATION_TYPE)
6297     {
6298       struct imp_entry *imp_entry;
6299       tree ivar_context;
6300 
6301       /* Check consistency of the instance variables.  */
6302 
6303       if (CLASS_IVARS (class))
6304 	check_ivars (implementation_template, class);
6305 
6306       /* code generation */
6307 
6308       ivar_context = build_private_template (implementation_template);
6309 
6310       if (!objc_class_template)
6311 	build_class_template ();
6312 
6313       imp_entry = (struct imp_entry *) ggc_alloc (sizeof (struct imp_entry));
6314 
6315       imp_entry->next = imp_list;
6316       imp_entry->imp_context = class;
6317       imp_entry->imp_template = implementation_template;
6318 
6319       synth_forward_declarations ();
6320       imp_entry->class_decl = UOBJC_CLASS_decl;
6321       imp_entry->meta_decl = UOBJC_METACLASS_decl;
6322 
6323       /* Append to front and increment count.  */
6324       imp_list = imp_entry;
6325       if (TREE_CODE (class) == CLASS_IMPLEMENTATION_TYPE)
6326 	imp_count++;
6327       else
6328 	cat_count++;
6329 
6330       return ivar_context;
6331     }
6332 
6333   else if (TREE_CODE (class) == CLASS_INTERFACE_TYPE)
6334     {
6335       tree record = xref_tag (RECORD_TYPE, CLASS_NAME (class));
6336 
6337       if (!TYPE_FIELDS (record))
6338 	{
6339 	  finish_struct (record, get_class_ivars (class), NULL_TREE);
6340 	  CLASS_STATIC_TEMPLATE (class) = record;
6341 
6342 	  /* Mark this record as a class template for static typing.  */
6343 	  TREE_STATIC_TEMPLATE (record) = 1;
6344 	}
6345 
6346       return NULL_TREE;
6347     }
6348 
6349   else
6350     return error_mark_node;
6351 }
6352 
6353 /* This is called once we see the "@end" in an interface/implementation.  */
6354 
6355 void
finish_class(class)6356 finish_class (class)
6357      tree class;
6358 {
6359   if (TREE_CODE (class) == CLASS_IMPLEMENTATION_TYPE)
6360     {
6361       /* All code generation is done in finish_objc.  */
6362 
6363       if (implementation_template != objc_implementation_context)
6364 	{
6365 	  /* Ensure that all method listed in the interface contain bodies.  */
6366 	  check_methods (CLASS_CLS_METHODS (implementation_template),
6367 			 CLASS_CLS_METHODS (objc_implementation_context), '+');
6368 	  check_methods (CLASS_NST_METHODS (implementation_template),
6369 			 CLASS_NST_METHODS (objc_implementation_context), '-');
6370 
6371 	  if (CLASS_PROTOCOL_LIST (implementation_template))
6372 	    check_protocols (CLASS_PROTOCOL_LIST (implementation_template),
6373 			     "class",
6374 			     IDENTIFIER_POINTER (CLASS_NAME (objc_implementation_context)));
6375 	}
6376     }
6377 
6378   else if (TREE_CODE (class) == CATEGORY_IMPLEMENTATION_TYPE)
6379     {
6380       tree category = CLASS_CATEGORY_LIST (implementation_template);
6381 
6382       /* Find the category interface from the class it is associated with.  */
6383       while (category)
6384 	{
6385 	  if (CLASS_SUPER_NAME (class) == CLASS_SUPER_NAME (category))
6386 	    break;
6387 	  category = CLASS_CATEGORY_LIST (category);
6388 	}
6389 
6390       if (category)
6391 	{
6392 	  /* Ensure all method listed in the interface contain bodies.  */
6393 	  check_methods (CLASS_CLS_METHODS (category),
6394 			 CLASS_CLS_METHODS (objc_implementation_context), '+');
6395 	  check_methods (CLASS_NST_METHODS (category),
6396 			 CLASS_NST_METHODS (objc_implementation_context), '-');
6397 
6398 	  if (CLASS_PROTOCOL_LIST (category))
6399 	    check_protocols (CLASS_PROTOCOL_LIST (category),
6400 			     "category",
6401 			     IDENTIFIER_POINTER (CLASS_SUPER_NAME (objc_implementation_context)));
6402 	}
6403     }
6404 
6405   else if (TREE_CODE (class) == CLASS_INTERFACE_TYPE)
6406     {
6407       tree decl_specs;
6408       const char *class_name = IDENTIFIER_POINTER (CLASS_NAME (class));
6409       char *string = (char *) alloca (strlen (class_name) + 3);
6410 
6411       /* extern struct objc_object *_<my_name>; */
6412 
6413       sprintf (string, "_%s", class_name);
6414 
6415       decl_specs = build_tree_list (NULL_TREE, ridpointers[(int) RID_EXTERN]);
6416       decl_specs = tree_cons (NULL_TREE, objc_object_reference, decl_specs);
6417       define_decl (build1 (INDIRECT_REF, NULL_TREE, get_identifier (string)),
6418 		   decl_specs);
6419     }
6420 }
6421 
6422 static tree
add_protocol(protocol)6423 add_protocol (protocol)
6424      tree protocol;
6425 {
6426   /* Put protocol on list in reverse order.  */
6427   TREE_CHAIN (protocol) = protocol_chain;
6428   protocol_chain = protocol;
6429   return protocol_chain;
6430 }
6431 
6432 static tree
lookup_protocol(ident)6433 lookup_protocol (ident)
6434      tree ident;
6435 {
6436   tree chain;
6437 
6438   for (chain = protocol_chain; chain; chain = TREE_CHAIN (chain))
6439     if (ident == PROTOCOL_NAME (chain))
6440       return chain;
6441 
6442   return NULL_TREE;
6443 }
6444 
6445 /* This function forward declares the protocols named by NAMES.  If
6446    they are already declared or defined, the function has no effect.  */
6447 
6448 void
objc_declare_protocols(names)6449 objc_declare_protocols (names)
6450      tree names;
6451 {
6452   tree list;
6453 
6454   for (list = names; list; list = TREE_CHAIN (list))
6455     {
6456       tree name = TREE_VALUE (list);
6457 
6458       if (lookup_protocol (name) == NULL_TREE)
6459 	{
6460 	  tree protocol = make_node (PROTOCOL_INTERFACE_TYPE);
6461 
6462 	  TYPE_BINFO (protocol) = make_tree_vec (2);
6463 	  PROTOCOL_NAME (protocol) = name;
6464 	  PROTOCOL_LIST (protocol) = NULL_TREE;
6465 	  add_protocol (protocol);
6466 	  PROTOCOL_DEFINED (protocol) = 0;
6467 	  PROTOCOL_FORWARD_DECL (protocol) = NULL_TREE;
6468 	}
6469     }
6470 }
6471 
6472 tree
start_protocol(code,name,list)6473 start_protocol (code, name, list)
6474      enum tree_code code;
6475      tree name;
6476      tree list;
6477 {
6478   tree protocol;
6479 
6480   /* This is as good a place as any.  Need to invoke
6481      push_tag_toplevel.  */
6482   if (!objc_protocol_template)
6483     objc_protocol_template = build_protocol_template ();
6484 
6485   protocol = lookup_protocol (name);
6486 
6487   if (!protocol)
6488     {
6489       protocol = make_node (code);
6490       TYPE_BINFO (protocol) = make_tree_vec (2);
6491 
6492       PROTOCOL_NAME (protocol) = name;
6493       PROTOCOL_LIST (protocol) = lookup_and_install_protocols (list);
6494       add_protocol (protocol);
6495       PROTOCOL_DEFINED (protocol) = 1;
6496       PROTOCOL_FORWARD_DECL (protocol) = NULL_TREE;
6497 
6498       check_protocol_recursively (protocol, list);
6499     }
6500   else if (! PROTOCOL_DEFINED (protocol))
6501     {
6502       PROTOCOL_DEFINED (protocol) = 1;
6503       PROTOCOL_LIST (protocol) = lookup_and_install_protocols (list);
6504 
6505       check_protocol_recursively (protocol, list);
6506     }
6507   else
6508     {
6509       warning ("duplicate declaration for protocol `%s'",
6510 	       IDENTIFIER_POINTER (name));
6511     }
6512   return protocol;
6513 }
6514 
6515 void
finish_protocol(protocol)6516 finish_protocol (protocol)
6517      tree protocol ATTRIBUTE_UNUSED;
6518 {
6519 }
6520 
6521 
6522 /* "Encode" a data type into a string, which grows in util_obstack.
6523    ??? What is the FORMAT?  Someone please document this!  */
6524 
6525 static void
encode_type_qualifiers(declspecs)6526 encode_type_qualifiers (declspecs)
6527      tree declspecs;
6528 {
6529   tree spec;
6530 
6531   for (spec = declspecs; spec; spec = TREE_CHAIN (spec))
6532     {
6533       if (ridpointers[(int) RID_CONST] == TREE_VALUE (spec))
6534 	obstack_1grow (&util_obstack, 'r');
6535       else if (ridpointers[(int) RID_IN] == TREE_VALUE (spec))
6536 	obstack_1grow (&util_obstack, 'n');
6537       else if (ridpointers[(int) RID_INOUT] == TREE_VALUE (spec))
6538 	obstack_1grow (&util_obstack, 'N');
6539       else if (ridpointers[(int) RID_OUT] == TREE_VALUE (spec))
6540 	obstack_1grow (&util_obstack, 'o');
6541       else if (ridpointers[(int) RID_BYCOPY] == TREE_VALUE (spec))
6542 	obstack_1grow (&util_obstack, 'O');
6543       else if (ridpointers[(int) RID_BYREF] == TREE_VALUE (spec))
6544         obstack_1grow (&util_obstack, 'R');
6545       else if (ridpointers[(int) RID_ONEWAY] == TREE_VALUE (spec))
6546 	obstack_1grow (&util_obstack, 'V');
6547     }
6548 }
6549 
6550 /* Encode a pointer type.  */
6551 
6552 static void
encode_pointer(type,curtype,format)6553 encode_pointer (type, curtype, format)
6554      tree type;
6555      int curtype;
6556      int format;
6557 {
6558   tree pointer_to = TREE_TYPE (type);
6559 
6560   if (TREE_CODE (pointer_to) == RECORD_TYPE)
6561     {
6562       if (TYPE_NAME (pointer_to)
6563 	  && TREE_CODE (TYPE_NAME (pointer_to)) == IDENTIFIER_NODE)
6564 	{
6565 	  const char *name = IDENTIFIER_POINTER (TYPE_NAME (pointer_to));
6566 
6567 	  if (strcmp (name, TAG_OBJECT) == 0) /* '@' */
6568 	    {
6569 	      obstack_1grow (&util_obstack, '@');
6570 	      return;
6571 	    }
6572 	  else if (TREE_STATIC_TEMPLATE (pointer_to))
6573 	    {
6574               if (generating_instance_variables)
6575 	        {
6576 	          obstack_1grow (&util_obstack, '@');
6577 	          obstack_1grow (&util_obstack, '"');
6578 	          obstack_grow (&util_obstack, name, strlen (name));
6579 	          obstack_1grow (&util_obstack, '"');
6580 	          return;
6581 		}
6582               else
6583 	        {
6584 	          obstack_1grow (&util_obstack, '@');
6585 	          return;
6586 		}
6587 	    }
6588 	  else if (strcmp (name, TAG_CLASS) == 0) /* '#' */
6589 	    {
6590 	      obstack_1grow (&util_obstack, '#');
6591 	      return;
6592 	    }
6593 	  else if (strcmp (name, TAG_SELECTOR) == 0) /* ':' */
6594 	    {
6595 	      obstack_1grow (&util_obstack, ':');
6596 	      return;
6597 	    }
6598 	}
6599     }
6600   else if (TREE_CODE (pointer_to) == INTEGER_TYPE
6601 	   && TYPE_MODE (pointer_to) == QImode)
6602     {
6603       obstack_1grow (&util_obstack, '*');
6604       return;
6605     }
6606 
6607   /* We have a type that does not get special treatment.  */
6608 
6609   /* NeXT extension */
6610   obstack_1grow (&util_obstack, '^');
6611   encode_type (pointer_to, curtype, format);
6612 }
6613 
6614 static void
encode_array(type,curtype,format)6615 encode_array (type, curtype, format)
6616      tree type;
6617      int curtype;
6618      int format;
6619 {
6620   tree an_int_cst = TYPE_SIZE (type);
6621   tree array_of = TREE_TYPE (type);
6622   char buffer[40];
6623 
6624   /* An incomplete array is treated like a pointer.  */
6625   if (an_int_cst == NULL)
6626     {
6627       encode_pointer (type, curtype, format);
6628       return;
6629     }
6630 
6631   sprintf (buffer, "[%ld",
6632 	   (long) (TREE_INT_CST_LOW (an_int_cst)
6633 		   / TREE_INT_CST_LOW (TYPE_SIZE (array_of))));
6634 
6635   obstack_grow (&util_obstack, buffer, strlen (buffer));
6636   encode_type (array_of, curtype, format);
6637   obstack_1grow (&util_obstack, ']');
6638   return;
6639 }
6640 
6641 static void
encode_aggregate_within(type,curtype,format,left,right)6642 encode_aggregate_within (type, curtype, format, left, right)
6643      tree type;
6644      int curtype;
6645      int format;
6646      int left;
6647      int right;
6648 {
6649   /* The RECORD_TYPE may in fact be a typedef!  For purposes
6650      of encoding, we need the real underlying enchilada.  */
6651   if (TYPE_MAIN_VARIANT (type))
6652     type = TYPE_MAIN_VARIANT (type);
6653 
6654   if (obstack_object_size (&util_obstack) > 0
6655       && *(obstack_next_free (&util_obstack) - 1) == '^')
6656     {
6657       tree name = TYPE_NAME (type);
6658 
6659       /* we have a reference; this is a NeXT extension.  */
6660 
6661       if (obstack_object_size (&util_obstack) - curtype == 1
6662 	  && format == OBJC_ENCODE_INLINE_DEFS)
6663 	{
6664 	  /* Output format of struct for first level only.  */
6665 	  tree fields = TYPE_FIELDS (type);
6666 
6667 	  if (name && TREE_CODE (name) == IDENTIFIER_NODE)
6668 	    {
6669 	      obstack_1grow (&util_obstack, left);
6670 	      obstack_grow (&util_obstack,
6671 			    IDENTIFIER_POINTER (name),
6672 			    strlen (IDENTIFIER_POINTER (name)));
6673 	      obstack_1grow (&util_obstack, '=');
6674 	    }
6675 	  else
6676 	    {
6677 	      obstack_1grow (&util_obstack, left);
6678 	      obstack_grow (&util_obstack, "?=", 2);
6679 	    }
6680 
6681 	  for ( ; fields; fields = TREE_CHAIN (fields))
6682 	      encode_field_decl (fields, curtype, format);
6683 
6684 	  obstack_1grow (&util_obstack, right);
6685 	}
6686 
6687       else if (name && TREE_CODE (name) == IDENTIFIER_NODE)
6688 	{
6689 	  obstack_1grow (&util_obstack, left);
6690 	  obstack_grow (&util_obstack,
6691 			IDENTIFIER_POINTER (name),
6692 			strlen (IDENTIFIER_POINTER (name)));
6693 	  obstack_1grow (&util_obstack, right);
6694 	}
6695 
6696       else
6697 	{
6698 	  /* We have an untagged structure or a typedef.  */
6699 	  obstack_1grow (&util_obstack, left);
6700 	  obstack_1grow (&util_obstack, '?');
6701 	  obstack_1grow (&util_obstack, right);
6702 	}
6703     }
6704 
6705   else
6706     {
6707       tree name = TYPE_NAME (type);
6708       tree fields = TYPE_FIELDS (type);
6709 
6710       if (format == OBJC_ENCODE_INLINE_DEFS
6711 	  || generating_instance_variables)
6712 	{
6713 	  obstack_1grow (&util_obstack, left);
6714 	  if (name && TREE_CODE (name) == IDENTIFIER_NODE)
6715 	      obstack_grow (&util_obstack,
6716 			  IDENTIFIER_POINTER (name),
6717 			  strlen (IDENTIFIER_POINTER (name)));
6718 	  else
6719 	      obstack_1grow (&util_obstack, '?');
6720 
6721 	  obstack_1grow (&util_obstack, '=');
6722 
6723 	  for (; fields; fields = TREE_CHAIN (fields))
6724 	    {
6725 	      if (generating_instance_variables)
6726 		{
6727 		  tree fname = DECL_NAME (fields);
6728 
6729 		  obstack_1grow (&util_obstack, '"');
6730 		  if (fname && TREE_CODE (fname) == IDENTIFIER_NODE)
6731 		    {
6732 		      obstack_grow (&util_obstack,
6733 				    IDENTIFIER_POINTER (fname),
6734 				    strlen (IDENTIFIER_POINTER (fname)));
6735 		    }
6736 
6737 		  obstack_1grow (&util_obstack, '"');
6738 		}
6739 
6740 	      encode_field_decl (fields, curtype, format);
6741 	    }
6742 
6743 	  obstack_1grow (&util_obstack, right);
6744 	}
6745 
6746       else
6747 	{
6748 	  obstack_1grow (&util_obstack, left);
6749 	  if (name && TREE_CODE (name) == IDENTIFIER_NODE)
6750 	      obstack_grow (&util_obstack,
6751 			    IDENTIFIER_POINTER (name),
6752 			    strlen (IDENTIFIER_POINTER (name)));
6753 	  else
6754 	      /* We have an untagged structure or a typedef.  */
6755 	      obstack_1grow (&util_obstack, '?');
6756 
6757 	  obstack_1grow (&util_obstack, right);
6758 	}
6759     }
6760 }
6761 
6762 static void
encode_aggregate(type,curtype,format)6763 encode_aggregate (type, curtype, format)
6764      tree type;
6765      int curtype;
6766      int format;
6767 {
6768   enum tree_code code = TREE_CODE (type);
6769 
6770   switch (code)
6771     {
6772     case RECORD_TYPE:
6773       {
6774 	encode_aggregate_within(type, curtype, format, '{', '}');
6775 	break;
6776       }
6777     case UNION_TYPE:
6778       {
6779 	encode_aggregate_within(type, curtype, format, '(', ')');
6780 	break;
6781       }
6782 
6783     case ENUMERAL_TYPE:
6784       obstack_1grow (&util_obstack, 'i');
6785       break;
6786 
6787     default:
6788       break;
6789     }
6790 }
6791 
6792 /* Support bitfields.  The current version of Objective-C does not support
6793    them.  The string will consist of one or more "b:n"'s where n is an
6794    integer describing the width of the bitfield. Currently, classes in
6795    the kit implement a method "-(char *)describeBitfieldStruct:" that
6796    simulates this. If they do not implement this method, the archiver
6797    assumes the bitfield is 16 bits wide (padded if necessary) and packed
6798    according to the GNU compiler. After looking at the "kit", it appears
6799    that all classes currently rely on this default behavior, rather than
6800    hand generating this string (which is tedious).  */
6801 
6802 static void
encode_bitfield(width)6803 encode_bitfield (width)
6804      int width;
6805 {
6806   char buffer[40];
6807   sprintf (buffer, "b%d", width);
6808   obstack_grow (&util_obstack, buffer, strlen (buffer));
6809 }
6810 
6811 /* FORMAT will be OBJC_ENCODE_INLINE_DEFS or OBJC_ENCODE_DONT_INLINE_DEFS.  */
6812 
6813 static void
encode_type(type,curtype,format)6814 encode_type (type, curtype, format)
6815      tree type;
6816      int curtype;
6817      int format;
6818 {
6819   enum tree_code code = TREE_CODE (type);
6820 
6821   if (code == INTEGER_TYPE)
6822     {
6823       if (integer_zerop (TYPE_MIN_VALUE (type)))
6824 	{
6825 	  /* Unsigned integer types.  */
6826 
6827 	  if (TYPE_MODE (type) == QImode)
6828 	    obstack_1grow (&util_obstack, 'C');
6829 	  else if (TYPE_MODE (type) == HImode)
6830 	    obstack_1grow (&util_obstack, 'S');
6831 	  else if (TYPE_MODE (type) == SImode)
6832 	    {
6833 	      if (type == long_unsigned_type_node)
6834 		obstack_1grow (&util_obstack, 'L');
6835 	      else
6836 		obstack_1grow (&util_obstack, 'I');
6837 	    }
6838 	  else if (TYPE_MODE (type) == DImode)
6839 	    obstack_1grow (&util_obstack, 'Q');
6840 	}
6841 
6842       else
6843 	/* Signed integer types.  */
6844 	{
6845 	  if (TYPE_MODE (type) == QImode)
6846 	    obstack_1grow (&util_obstack, 'c');
6847 	  else if (TYPE_MODE (type) == HImode)
6848 	    obstack_1grow (&util_obstack, 's');
6849 	  else if (TYPE_MODE (type) == SImode)
6850 	    {
6851 	      if (type == long_integer_type_node)
6852 		obstack_1grow (&util_obstack, 'l');
6853 	      else
6854 		obstack_1grow (&util_obstack, 'i');
6855 	    }
6856 
6857 	  else if (TYPE_MODE (type) == DImode)
6858 	    obstack_1grow (&util_obstack, 'q');
6859 	}
6860     }
6861 
6862   else if (code == REAL_TYPE)
6863     {
6864       /* Floating point types.  */
6865 
6866       if (TYPE_MODE (type) == SFmode)
6867 	obstack_1grow (&util_obstack, 'f');
6868       else if (TYPE_MODE (type) == DFmode
6869 	       || TYPE_MODE (type) == TFmode)
6870 	obstack_1grow (&util_obstack, 'd');
6871     }
6872 
6873   else if (code == VOID_TYPE)
6874     obstack_1grow (&util_obstack, 'v');
6875 
6876   else if (code == ARRAY_TYPE)
6877     encode_array (type, curtype, format);
6878 
6879   else if (code == POINTER_TYPE)
6880     encode_pointer (type, curtype, format);
6881 
6882   else if (code == RECORD_TYPE || code == UNION_TYPE || code == ENUMERAL_TYPE)
6883     encode_aggregate (type, curtype, format);
6884 
6885   else if (code == FUNCTION_TYPE) /* '?' */
6886     obstack_1grow (&util_obstack, '?');
6887 }
6888 
6889 static void
encode_complete_bitfield(position,type,size)6890 encode_complete_bitfield (position, type, size)
6891      int position;
6892      tree type;
6893      int size;
6894 {
6895   enum tree_code code = TREE_CODE (type);
6896   char buffer[40];
6897   char charType = '?';
6898 
6899   if (code == INTEGER_TYPE)
6900     {
6901       if (integer_zerop (TYPE_MIN_VALUE (type)))
6902 	{
6903 	  /* Unsigned integer types.  */
6904 
6905 	  if (TYPE_MODE (type) == QImode)
6906 	    charType = 'C';
6907 	  else if (TYPE_MODE (type) == HImode)
6908 	    charType = 'S';
6909 	  else if (TYPE_MODE (type) == SImode)
6910 	    {
6911 	      if (type == long_unsigned_type_node)
6912 		charType = 'L';
6913 	      else
6914 		charType = 'I';
6915 	    }
6916 	  else if (TYPE_MODE (type) == DImode)
6917 	    charType = 'Q';
6918 	}
6919 
6920       else
6921 	/* Signed integer types.  */
6922 	{
6923 	  if (TYPE_MODE (type) == QImode)
6924 	    charType = 'c';
6925 	  else if (TYPE_MODE (type) == HImode)
6926 	    charType = 's';
6927 	  else if (TYPE_MODE (type) == SImode)
6928 	    {
6929 	      if (type == long_integer_type_node)
6930 		charType = 'l';
6931 	      else
6932 		charType = 'i';
6933 	    }
6934 
6935 	  else if (TYPE_MODE (type) == DImode)
6936 	    charType = 'q';
6937 	}
6938     }
6939   else if (code == ENUMERAL_TYPE)
6940     charType = 'i';
6941   else
6942     abort ();
6943 
6944   sprintf (buffer, "b%d%c%d", position, charType, size);
6945   obstack_grow (&util_obstack, buffer, strlen (buffer));
6946 }
6947 
6948 static void
encode_field_decl(field_decl,curtype,format)6949 encode_field_decl (field_decl, curtype, format)
6950      tree field_decl;
6951      int curtype;
6952      int format;
6953 {
6954   tree type;
6955 
6956   type = TREE_TYPE (field_decl);
6957 
6958   /* If this field is obviously a bitfield, or is a bitfield that has been
6959      clobbered to look like a ordinary integer mode, go ahead and generate
6960      the bitfield typing information.  */
6961   if (flag_next_runtime)
6962     {
6963       if (DECL_BIT_FIELD_TYPE (field_decl))
6964 	encode_bitfield (tree_low_cst (DECL_SIZE (field_decl), 1));
6965       else
6966 	encode_type (TREE_TYPE (field_decl), curtype, format);
6967     }
6968   else
6969     {
6970       if (DECL_BIT_FIELD_TYPE (field_decl))
6971 	encode_complete_bitfield (int_bit_position (field_decl),
6972 				  DECL_BIT_FIELD_TYPE (field_decl),
6973 				  tree_low_cst (DECL_SIZE (field_decl), 1));
6974       else
6975 	encode_type (TREE_TYPE (field_decl), curtype, format);
6976     }
6977 }
6978 
6979 static tree
expr_last(complex_expr)6980 expr_last (complex_expr)
6981      tree complex_expr;
6982 {
6983   tree next;
6984 
6985   if (complex_expr)
6986     while ((next = TREE_OPERAND (complex_expr, 0)))
6987       complex_expr = next;
6988 
6989   return complex_expr;
6990 }
6991 
6992 /* Transform a method definition into a function definition as follows:
6993    - synthesize the first two arguments, "self" and "_cmd".  */
6994 
6995 void
start_method_def(method)6996 start_method_def (method)
6997      tree method;
6998 {
6999   tree decl_specs;
7000 
7001   /* Required to implement _msgSuper.  */
7002   objc_method_context = method;
7003   UOBJC_SUPER_decl = NULL_TREE;
7004 
7005   /* Must be called BEFORE start_function.  */
7006   pushlevel (0);
7007 
7008   /* Generate prototype declarations for arguments..."new-style".  */
7009 
7010   if (TREE_CODE (objc_method_context) == INSTANCE_METHOD_DECL)
7011     decl_specs = build_tree_list (NULL_TREE, uprivate_record);
7012   else
7013     /* Really a `struct objc_class *'. However, we allow people to
7014        assign to self, which changes its type midstream.  */
7015     decl_specs = build_tree_list (NULL_TREE, objc_object_reference);
7016 
7017   push_parm_decl (build_tree_list
7018 		  (build_tree_list (decl_specs,
7019 				    build1 (INDIRECT_REF, NULL_TREE, self_id)),
7020 		   unused_list));
7021 
7022   decl_specs = build_tree_list (NULL_TREE,
7023 				xref_tag (RECORD_TYPE,
7024 					  get_identifier (TAG_SELECTOR)));
7025   push_parm_decl (build_tree_list
7026 		  (build_tree_list (decl_specs,
7027 				    build1 (INDIRECT_REF, NULL_TREE, ucmd_id)),
7028 		   unused_list));
7029 
7030   /* Generate argument declarations if a keyword_decl.  */
7031   if (METHOD_SEL_ARGS (method))
7032     {
7033       tree arglist = METHOD_SEL_ARGS (method);
7034       do
7035 	{
7036 	  tree arg_spec = TREE_PURPOSE (TREE_TYPE (arglist));
7037 	  tree arg_decl = TREE_VALUE (TREE_TYPE (arglist));
7038 
7039 	  if (arg_decl)
7040 	    {
7041 	      tree last_expr = expr_last (arg_decl);
7042 
7043 	      /* Unite the abstract decl with its name.  */
7044 	      TREE_OPERAND (last_expr, 0) = KEYWORD_ARG_NAME (arglist);
7045 	      push_parm_decl (build_tree_list
7046 			      (build_tree_list (arg_spec, arg_decl),
7047 			       NULL_TREE));
7048 
7049 	      /* Unhook: restore the abstract declarator.  */
7050 	      TREE_OPERAND (last_expr, 0) = NULL_TREE;
7051 	    }
7052 
7053 	  else
7054 	    push_parm_decl (build_tree_list
7055 			    (build_tree_list (arg_spec,
7056 					      KEYWORD_ARG_NAME (arglist)),
7057 			     NULL_TREE));
7058 
7059 	  arglist = TREE_CHAIN (arglist);
7060 	}
7061       while (arglist);
7062     }
7063 
7064   if (METHOD_ADD_ARGS (method) != NULL_TREE
7065       && METHOD_ADD_ARGS (method) != objc_ellipsis_node)
7066     {
7067       /* We have a variable length selector - in "prototype" format.  */
7068       tree akey = TREE_PURPOSE (METHOD_ADD_ARGS (method));
7069       while (akey)
7070 	{
7071 	  /* This must be done prior to calling pushdecl.  pushdecl is
7072 	     going to change our chain on us.  */
7073 	  tree nextkey = TREE_CHAIN (akey);
7074 	  pushdecl (akey);
7075 	  akey = nextkey;
7076 	}
7077     }
7078 }
7079 
7080 static void
warn_with_method(message,mtype,method)7081 warn_with_method (message, mtype, method)
7082      const char *message;
7083      int mtype;
7084      tree method;
7085 {
7086   if (!diagnostic_count_diagnostic (global_dc, DK_WARNING))
7087     return;
7088 
7089   diagnostic_report_current_function (global_dc);
7090 
7091   /* Add a readable method name to the warning.  */
7092   warning_with_file_and_line (DECL_SOURCE_FILE (method),
7093 			      DECL_SOURCE_LINE (method),
7094 			      "%s `%c%s'",
7095 			      message, mtype,
7096 			      gen_method_decl (method, errbuf));
7097 }
7098 
7099 /* Return 1 if METHOD is consistent with PROTO.  */
7100 
7101 static int
comp_method_with_proto(method,proto)7102 comp_method_with_proto (method, proto)
7103      tree method, proto;
7104 {
7105   /* Create a function template node at most once.  */
7106   if (!function1_template)
7107     function1_template = make_node (FUNCTION_TYPE);
7108 
7109   /* Install argument types - normally set by build_function_type.  */
7110   TYPE_ARG_TYPES (function1_template) = get_arg_type_list (proto, METHOD_DEF, 0);
7111 
7112   /* install return type */
7113   TREE_TYPE (function1_template) = groktypename (TREE_TYPE (proto));
7114 
7115   return comptypes (TREE_TYPE (METHOD_DEFINITION (method)), function1_template);
7116 }
7117 
7118 /* Return 1 if PROTO1 is consistent with PROTO2.  */
7119 
7120 static int
comp_proto_with_proto(proto0,proto1)7121 comp_proto_with_proto (proto0, proto1)
7122      tree proto0, proto1;
7123 {
7124   /* Create a couple of function_template nodes at most once.  */
7125   if (!function1_template)
7126     function1_template = make_node (FUNCTION_TYPE);
7127   if (!function2_template)
7128     function2_template = make_node (FUNCTION_TYPE);
7129 
7130   /* Install argument types; normally set by build_function_type.  */
7131   TYPE_ARG_TYPES (function1_template) = get_arg_type_list (proto0, METHOD_REF, 0);
7132   TYPE_ARG_TYPES (function2_template) = get_arg_type_list (proto1, METHOD_REF, 0);
7133 
7134   /* Install return type.  */
7135   TREE_TYPE (function1_template) = groktypename (TREE_TYPE (proto0));
7136   TREE_TYPE (function2_template) = groktypename (TREE_TYPE (proto1));
7137 
7138   return comptypes (function1_template, function2_template);
7139 }
7140 
7141 /* - Generate an identifier for the function. the format is "_n_cls",
7142      where 1 <= n <= nMethods, and cls is the name the implementation we
7143      are processing.
7144    - Install the return type from the method declaration.
7145    - If we have a prototype, check for type consistency.  */
7146 
7147 static void
really_start_method(method,parmlist)7148 really_start_method (method, parmlist)
7149      tree method, parmlist;
7150 {
7151   tree sc_spec, ret_spec, ret_decl, decl_specs;
7152   tree method_decl, method_id;
7153   const char *sel_name, *class_name, *cat_name;
7154   char *buf;
7155 
7156   /* Synth the storage class & assemble the return type.  */
7157   sc_spec = tree_cons (NULL_TREE, ridpointers[(int) RID_STATIC], NULL_TREE);
7158   ret_spec = TREE_PURPOSE (TREE_TYPE (method));
7159   decl_specs = chainon (sc_spec, ret_spec);
7160 
7161   sel_name = IDENTIFIER_POINTER (METHOD_SEL_NAME (method));
7162   class_name = IDENTIFIER_POINTER (CLASS_NAME (objc_implementation_context));
7163   cat_name = ((TREE_CODE (objc_implementation_context)
7164 	       == CLASS_IMPLEMENTATION_TYPE)
7165 	      ? NULL
7166 	      : IDENTIFIER_POINTER (CLASS_SUPER_NAME (objc_implementation_context)));
7167   method_slot++;
7168 
7169   /* Make sure this is big enough for any plausible method label.  */
7170   buf = (char *) alloca (50 + strlen (sel_name) + strlen (class_name)
7171 			 + (cat_name ? strlen (cat_name) : 0));
7172 
7173   OBJC_GEN_METHOD_LABEL (buf, TREE_CODE (method) == INSTANCE_METHOD_DECL,
7174 			 class_name, cat_name, sel_name, method_slot);
7175 
7176   method_id = get_identifier (buf);
7177 
7178   method_decl = build_nt (CALL_EXPR, method_id, parmlist, NULL_TREE);
7179 
7180   /* Check the declarator portion of the return type for the method.  */
7181   if ((ret_decl = TREE_VALUE (TREE_TYPE (method))))
7182     {
7183       /* Unite the complex decl (specified in the abstract decl) with the
7184 	 function decl just synthesized..(int *), (int (*)()), (int (*)[]).  */
7185       tree save_expr = expr_last (ret_decl);
7186 
7187       TREE_OPERAND (save_expr, 0) = method_decl;
7188       method_decl = ret_decl;
7189 
7190       /* Fool the parser into thinking it is starting a function.  */
7191       start_function (decl_specs, method_decl, NULL_TREE);
7192 
7193       /* Unhook: this has the effect of restoring the abstract declarator.  */
7194       TREE_OPERAND (save_expr, 0) = NULL_TREE;
7195     }
7196 
7197   else
7198     {
7199       TREE_VALUE (TREE_TYPE (method)) = method_decl;
7200 
7201       /* Fool the parser into thinking it is starting a function.  */
7202       start_function (decl_specs, method_decl, NULL_TREE);
7203 
7204       /* Unhook: this has the effect of restoring the abstract declarator.  */
7205       TREE_VALUE (TREE_TYPE (method)) = NULL_TREE;
7206     }
7207 
7208   METHOD_DEFINITION (method) = current_function_decl;
7209 
7210   /* Check consistency...start_function, pushdecl, duplicate_decls.  */
7211 
7212   if (implementation_template != objc_implementation_context)
7213     {
7214       tree proto;
7215 
7216       if (TREE_CODE (method) == INSTANCE_METHOD_DECL)
7217 	proto = lookup_instance_method_static (implementation_template,
7218 					       METHOD_SEL_NAME (method));
7219       else
7220 	proto = lookup_class_method_static (implementation_template,
7221 					    METHOD_SEL_NAME (method));
7222 
7223       if (proto && ! comp_method_with_proto (method, proto))
7224 	{
7225 	  char type = (TREE_CODE (method) == INSTANCE_METHOD_DECL ? '-' : '+');
7226 
7227 	  warn_with_method ("conflicting types for", type, method);
7228 	  warn_with_method ("previous declaration of", type, proto);
7229 	}
7230     }
7231 }
7232 
7233 /* The following routine is always called...this "architecture" is to
7234    accommodate "old-style" variable length selectors.
7235 
7236    - a:a b:b // prototype  ; id c; id d; // old-style.  */
7237 
7238 void
continue_method_def()7239 continue_method_def ()
7240 {
7241   tree parmlist;
7242 
7243   if (METHOD_ADD_ARGS (objc_method_context) == objc_ellipsis_node)
7244     /* We have a `, ...' immediately following the selector.  */
7245     parmlist = get_parm_info (0);
7246   else
7247     parmlist = get_parm_info (1); /* place a `void_at_end' */
7248 
7249   /* Set self_decl from the first argument...this global is used by
7250      build_ivar_reference calling build_indirect_ref.  */
7251   self_decl = TREE_PURPOSE (parmlist);
7252 
7253   poplevel (0, 0, 0);
7254   really_start_method (objc_method_context, parmlist);
7255   store_parm_decls ();
7256 }
7257 
7258 /* Called by the parser, from the `pushlevel' production.  */
7259 
7260 void
add_objc_decls()7261 add_objc_decls ()
7262 {
7263   if (!UOBJC_SUPER_decl)
7264     {
7265       UOBJC_SUPER_decl = start_decl (get_identifier (UTAG_SUPER),
7266 				     build_tree_list (NULL_TREE,
7267 						      objc_super_template),
7268 				     0, NULL_TREE);
7269 
7270       finish_decl (UOBJC_SUPER_decl, NULL_TREE, NULL_TREE);
7271 
7272       /* This prevents `unused variable' warnings when compiling with -Wall.  */
7273       TREE_USED (UOBJC_SUPER_decl) = 1;
7274       DECL_ARTIFICIAL (UOBJC_SUPER_decl) = 1;
7275     }
7276 }
7277 
7278 /* _n_Method (id self, SEL sel, ...)
7279      {
7280        struct objc_super _S;
7281        _msgSuper ((_S.self = self, _S.class = _cls, &_S), ...);
7282      }  */
7283 
7284 tree
get_super_receiver()7285 get_super_receiver ()
7286 {
7287   if (objc_method_context)
7288     {
7289       tree super_expr, super_expr_list;
7290 
7291       /* Set receiver to self.  */
7292       super_expr = build_component_ref (UOBJC_SUPER_decl, self_id);
7293       super_expr = build_modify_expr (super_expr, NOP_EXPR, self_decl);
7294       super_expr_list = build_tree_list (NULL_TREE, super_expr);
7295 
7296       /* Set class to begin searching.  */
7297       super_expr = build_component_ref (UOBJC_SUPER_decl,
7298 					get_identifier ("class"));
7299 
7300       if (TREE_CODE (objc_implementation_context) == CLASS_IMPLEMENTATION_TYPE)
7301 	{
7302 	  /* [_cls, __cls]Super are "pre-built" in
7303 	     synth_forward_declarations.  */
7304 
7305 	  super_expr = build_modify_expr (super_expr, NOP_EXPR,
7306 					  ((TREE_CODE (objc_method_context)
7307 					    == INSTANCE_METHOD_DECL)
7308 					   ? ucls_super_ref
7309 					   : uucls_super_ref));
7310 	}
7311 
7312       else
7313 	/* We have a category.  */
7314 	{
7315 	  tree super_name = CLASS_SUPER_NAME (implementation_template);
7316 	  tree super_class;
7317 
7318 	  /* Barf if super used in a category of Object.  */
7319 	  if (!super_name)
7320 	    {
7321 	      error ("no super class declared in interface for `%s'",
7322 		    IDENTIFIER_POINTER (CLASS_NAME (implementation_template)));
7323 	      return error_mark_node;
7324 	    }
7325 
7326 	  if (flag_next_runtime)
7327 	    {
7328 	      super_class = get_class_reference (super_name);
7329 	      if (TREE_CODE (objc_method_context) == CLASS_METHOD_DECL)
7330 		/* Cast the super class to 'id', since the user may not have
7331 		   included <objc/objc-class.h>, leaving 'struct objc_class'
7332 		   an incomplete type.  */
7333 		super_class
7334 		  = build_component_ref (build_indirect_ref
7335 					 (build_c_cast (id_type, super_class), "->"),
7336 					  get_identifier ("isa"));
7337 	    }
7338 	  else
7339 	    {
7340 	      add_class_reference (super_name);
7341 	      super_class = (TREE_CODE (objc_method_context) == INSTANCE_METHOD_DECL
7342 			     ? objc_get_class_decl : objc_get_meta_class_decl);
7343 	      assemble_external (super_class);
7344 	      super_class
7345 		= build_function_call
7346 		  (super_class,
7347 		   build_tree_list
7348 		   (NULL_TREE,
7349 		    my_build_string (IDENTIFIER_LENGTH (super_name) + 1,
7350 				     IDENTIFIER_POINTER (super_name))));
7351 	    }
7352 
7353 	  TREE_TYPE (super_class) = TREE_TYPE (ucls_super_ref);
7354 	  super_expr = build_modify_expr (super_expr, NOP_EXPR, super_class);
7355 	}
7356 
7357       chainon (super_expr_list, build_tree_list (NULL_TREE, super_expr));
7358 
7359       super_expr = build_unary_op (ADDR_EXPR, UOBJC_SUPER_decl, 0);
7360       chainon (super_expr_list, build_tree_list (NULL_TREE, super_expr));
7361 
7362       return build_compound_expr (super_expr_list);
7363     }
7364   else
7365     {
7366       error ("[super ...] must appear in a method context");
7367       return error_mark_node;
7368     }
7369 }
7370 
7371 static tree
encode_method_def(func_decl)7372 encode_method_def (func_decl)
7373       tree func_decl;
7374 {
7375   tree parms;
7376   int stack_size;
7377   HOST_WIDE_INT max_parm_end = 0;
7378   char buffer[40];
7379   tree result;
7380 
7381   /* Return type.  */
7382   encode_type (TREE_TYPE (TREE_TYPE (func_decl)),
7383 	       obstack_object_size (&util_obstack),
7384 	       OBJC_ENCODE_INLINE_DEFS);
7385 
7386   /* Stack size.  */
7387   for (parms = DECL_ARGUMENTS (func_decl); parms;
7388        parms = TREE_CHAIN (parms))
7389     {
7390       HOST_WIDE_INT parm_end = (forwarding_offset (parms)
7391 				+ int_size_in_bytes (TREE_TYPE (parms)));
7392 
7393       if (! offset_is_register && parm_end > max_parm_end)
7394 	max_parm_end = parm_end;
7395     }
7396 
7397   stack_size = max_parm_end - OBJC_FORWARDING_MIN_OFFSET;
7398 
7399   sprintf (buffer, "%d", stack_size);
7400   obstack_grow (&util_obstack, buffer, strlen (buffer));
7401 
7402   /* Argument types.  */
7403   for (parms = DECL_ARGUMENTS (func_decl); parms;
7404        parms = TREE_CHAIN (parms))
7405     {
7406       /* Type.  */
7407       encode_type (TREE_TYPE (parms),
7408 		   obstack_object_size (&util_obstack),
7409 		   OBJC_ENCODE_INLINE_DEFS);
7410 
7411       /* Compute offset.  */
7412       sprintf (buffer, "%d", forwarding_offset (parms));
7413 
7414       /* Indicate register.  */
7415       if (offset_is_register)
7416 	obstack_1grow (&util_obstack, '+');
7417 
7418       obstack_grow (&util_obstack, buffer, strlen (buffer));
7419     }
7420 
7421   /* Null terminate string.  */
7422   obstack_1grow (&util_obstack, 0);
7423   result = get_identifier (obstack_finish (&util_obstack));
7424   obstack_free (&util_obstack, util_firstobj);
7425   return result;
7426 }
7427 
7428 static void
objc_expand_function_end()7429 objc_expand_function_end ()
7430 {
7431   METHOD_ENCODING (objc_method_context) = encode_method_def (current_function_decl);
7432 }
7433 
7434 void
finish_method_def()7435 finish_method_def ()
7436 {
7437   lang_expand_function_end = objc_expand_function_end;
7438   finish_function (0, 1);
7439   lang_expand_function_end = NULL;
7440 
7441   /* Required to implement _msgSuper. This must be done AFTER finish_function,
7442      since the optimizer may find "may be used before set" errors.  */
7443   objc_method_context = NULL_TREE;
7444 }
7445 
7446 #if 0
7447 int
7448 lang_report_error_function (decl)
7449       tree decl;
7450 {
7451   if (objc_method_context)
7452     {
7453       fprintf (stderr, "In method `%s'\n",
7454 	       IDENTIFIER_POINTER (METHOD_SEL_NAME (objc_method_context)));
7455       return 1;
7456     }
7457 
7458   else
7459     return 0;
7460 }
7461 #endif
7462 
7463 static int
is_complex_decl(type)7464 is_complex_decl (type)
7465      tree type;
7466 {
7467   return (TREE_CODE (type) == ARRAY_TYPE
7468 	  || TREE_CODE (type) == FUNCTION_TYPE
7469 	  || (TREE_CODE (type) == POINTER_TYPE && ! IS_ID (type)));
7470 }
7471 
7472 
7473 /* Code to convert a decl node into text for a declaration in C.  */
7474 
7475 static char tmpbuf[256];
7476 
7477 static void
adorn_decl(decl,str)7478 adorn_decl (decl, str)
7479      tree decl;
7480      char *str;
7481 {
7482   enum tree_code code = TREE_CODE (decl);
7483 
7484   if (code == ARRAY_REF)
7485     {
7486       tree an_int_cst = TREE_OPERAND (decl, 1);
7487 
7488       if (an_int_cst && TREE_CODE (an_int_cst) == INTEGER_CST)
7489 	sprintf (str + strlen (str), "[%ld]",
7490 		 (long) TREE_INT_CST_LOW (an_int_cst));
7491       else
7492 	strcat (str, "[]");
7493     }
7494 
7495   else if (code == ARRAY_TYPE)
7496     {
7497       tree an_int_cst = TYPE_SIZE (decl);
7498       tree array_of = TREE_TYPE (decl);
7499 
7500       if (an_int_cst && TREE_CODE (an_int_cst) == INTEGER_TYPE)
7501 	sprintf (str + strlen (str), "[%ld]",
7502 		 (long) (TREE_INT_CST_LOW (an_int_cst)
7503 			 / TREE_INT_CST_LOW (TYPE_SIZE (array_of))));
7504       else
7505 	strcat (str, "[]");
7506     }
7507 
7508   else if (code == CALL_EXPR)
7509     {
7510       tree chain = TREE_PURPOSE (TREE_OPERAND (decl, 1));
7511 
7512       strcat (str, "(");
7513       while (chain)
7514 	{
7515 	  gen_declaration_1 (chain, str);
7516 	  chain = TREE_CHAIN (chain);
7517 	  if (chain)
7518 	    strcat (str, ", ");
7519 	}
7520       strcat (str, ")");
7521     }
7522 
7523   else if (code == FUNCTION_TYPE)
7524     {
7525       tree chain  = TYPE_ARG_TYPES (decl);
7526 
7527       strcat (str, "(");
7528       while (chain && TREE_VALUE (chain) != void_type_node)
7529 	{
7530 	  gen_declaration_1 (TREE_VALUE (chain), str);
7531 	  chain = TREE_CHAIN (chain);
7532 	  if (chain && TREE_VALUE (chain) != void_type_node)
7533 	    strcat (str, ", ");
7534 	}
7535       strcat (str, ")");
7536     }
7537 
7538   else if (code == INDIRECT_REF)
7539     {
7540       strcpy (tmpbuf, "*");
7541       if (TREE_TYPE (decl) && TREE_CODE (TREE_TYPE (decl)) == TREE_LIST)
7542 	{
7543 	  tree chain;
7544 
7545 	  for (chain = nreverse (copy_list (TREE_TYPE (decl)));
7546 	       chain;
7547 	       chain = TREE_CHAIN (chain))
7548 	    {
7549 	      if (TREE_CODE (TREE_VALUE (chain)) == IDENTIFIER_NODE)
7550 		{
7551 		  strcat (tmpbuf, " ");
7552 		  strcat (tmpbuf, IDENTIFIER_POINTER (TREE_VALUE (chain)));
7553 		}
7554 	    }
7555 	  if (str[0])
7556 	    strcat (tmpbuf, " ");
7557 	}
7558       strcat (tmpbuf, str);
7559       strcpy (str, tmpbuf);
7560     }
7561 
7562   else if (code == POINTER_TYPE)
7563     {
7564       strcpy (tmpbuf, "*");
7565       if (TREE_READONLY (decl) || TYPE_VOLATILE (decl))
7566 	{
7567 	  if (TREE_READONLY (decl))
7568 	    strcat (tmpbuf, " const");
7569 	  if (TYPE_VOLATILE (decl))
7570 	    strcat (tmpbuf, " volatile");
7571 	  if (str[0])
7572 	    strcat (tmpbuf, " ");
7573 	}
7574       strcat (tmpbuf, str);
7575       strcpy (str, tmpbuf);
7576     }
7577 }
7578 
7579 static char *
gen_declarator(decl,buf,name)7580 gen_declarator (decl, buf, name)
7581      tree decl;
7582      char *buf;
7583      const char *name;
7584 {
7585   if (decl)
7586     {
7587       enum tree_code code = TREE_CODE (decl);
7588       char *str;
7589       tree op;
7590       int wrap = 0;
7591 
7592       switch (code)
7593 	{
7594 	case ARRAY_REF:
7595 	case INDIRECT_REF:
7596 	case CALL_EXPR:
7597 	  op = TREE_OPERAND (decl, 0);
7598 
7599 	  /* We have a pointer to a function or array...(*)(), (*)[] */
7600 	  if ((code == ARRAY_REF || code == CALL_EXPR)
7601 	      && op && TREE_CODE (op) == INDIRECT_REF)
7602 	    wrap = 1;
7603 
7604 	  str = gen_declarator (op, buf, name);
7605 
7606 	  if (wrap)
7607 	    {
7608 	      strcpy (tmpbuf, "(");
7609 	      strcat (tmpbuf, str);
7610 	      strcat (tmpbuf, ")");
7611 	      strcpy (str, tmpbuf);
7612 	    }
7613 
7614 	  adorn_decl (decl, str);
7615 	  break;
7616 
7617 	case ARRAY_TYPE:
7618 	case FUNCTION_TYPE:
7619 	case POINTER_TYPE:
7620 	  strcpy (buf, name);
7621 	  str = buf;
7622 
7623 	  /* This clause is done iteratively rather than recursively.  */
7624 	  do
7625 	    {
7626 	      op = (is_complex_decl (TREE_TYPE (decl))
7627 		    ? TREE_TYPE (decl) : NULL_TREE);
7628 
7629 	      adorn_decl (decl, str);
7630 
7631 	      /* We have a pointer to a function or array...(*)(), (*)[] */
7632 	      if (code == POINTER_TYPE
7633 		  && op && (TREE_CODE (op) == FUNCTION_TYPE
7634 			    || TREE_CODE (op) == ARRAY_TYPE))
7635 		{
7636 		  strcpy (tmpbuf, "(");
7637 		  strcat (tmpbuf, str);
7638 		  strcat (tmpbuf, ")");
7639 		  strcpy (str, tmpbuf);
7640 		}
7641 
7642 	      decl = (is_complex_decl (TREE_TYPE (decl))
7643 		      ? TREE_TYPE (decl) : NULL_TREE);
7644 	    }
7645 
7646 	  while (decl && (code = TREE_CODE (decl)))
7647 	    ;
7648 
7649 	  break;
7650 
7651 	case IDENTIFIER_NODE:
7652 	  /* Will only happen if we are processing a "raw" expr-decl.  */
7653 	  strcpy (buf, IDENTIFIER_POINTER (decl));
7654 	  return buf;
7655 
7656 	default:
7657 	  abort ();
7658 	}
7659 
7660       return str;
7661     }
7662 
7663   else
7664     /* We have an abstract declarator or a _DECL node.  */
7665     {
7666       strcpy (buf, name);
7667       return buf;
7668     }
7669 }
7670 
7671 static void
gen_declspecs(declspecs,buf,raw)7672 gen_declspecs (declspecs, buf, raw)
7673      tree declspecs;
7674      char *buf;
7675      int raw;
7676 {
7677   if (raw)
7678     {
7679       tree chain;
7680 
7681       for (chain = nreverse (copy_list (declspecs));
7682 	   chain; chain = TREE_CHAIN (chain))
7683 	{
7684 	  tree aspec = TREE_VALUE (chain);
7685 
7686 	  if (TREE_CODE (aspec) == IDENTIFIER_NODE)
7687 	    strcat (buf, IDENTIFIER_POINTER (aspec));
7688 	  else if (TREE_CODE (aspec) == RECORD_TYPE)
7689 	    {
7690 	      if (TYPE_NAME (aspec))
7691 		{
7692 		  tree protocol_list = TYPE_PROTOCOL_LIST (aspec);
7693 
7694 		  if (! TREE_STATIC_TEMPLATE (aspec))
7695 		    strcat (buf, "struct ");
7696 		  strcat (buf, IDENTIFIER_POINTER (TYPE_NAME (aspec)));
7697 
7698 		  /* NEW!!! */
7699 		  if (protocol_list)
7700 		    {
7701 		      tree chain = protocol_list;
7702 
7703 		      strcat (buf, " <");
7704 		      while (chain)
7705 			{
7706 			  strcat (buf,
7707 				  IDENTIFIER_POINTER
7708 				  (PROTOCOL_NAME (TREE_VALUE (chain))));
7709 			  chain = TREE_CHAIN (chain);
7710 			  if (chain)
7711 			    strcat (buf, ", ");
7712 			}
7713 		      strcat (buf, ">");
7714 		    }
7715 		}
7716 
7717 	      else
7718 		strcat (buf, "untagged struct");
7719 	    }
7720 
7721 	  else if (TREE_CODE (aspec) == UNION_TYPE)
7722 	    {
7723 	      if (TYPE_NAME (aspec))
7724 		{
7725 		  if (! TREE_STATIC_TEMPLATE (aspec))
7726 		    strcat (buf, "union ");
7727 		  strcat (buf, IDENTIFIER_POINTER (TYPE_NAME (aspec)));
7728 		}
7729 	      else
7730 		strcat (buf, "untagged union");
7731 	    }
7732 
7733 	  else if (TREE_CODE (aspec) == ENUMERAL_TYPE)
7734 	    {
7735 	      if (TYPE_NAME (aspec))
7736 		{
7737 		  if (! TREE_STATIC_TEMPLATE (aspec))
7738 		    strcat (buf, "enum ");
7739 		  strcat (buf, IDENTIFIER_POINTER (TYPE_NAME (aspec)));
7740 		}
7741 	      else
7742 		strcat (buf, "untagged enum");
7743 	    }
7744 
7745 	  else if (TREE_CODE (aspec) == TYPE_DECL && DECL_NAME (aspec))
7746 	    strcat (buf, IDENTIFIER_POINTER (DECL_NAME (aspec)));
7747 
7748 	  else if (IS_ID (aspec))
7749 	    {
7750 	      tree protocol_list = TYPE_PROTOCOL_LIST (aspec);
7751 
7752 	      strcat (buf, "id");
7753 	      if (protocol_list)
7754 		{
7755 		  tree chain = protocol_list;
7756 
7757 		  strcat (buf, " <");
7758 		  while (chain)
7759 		    {
7760 		      strcat (buf,
7761 			      IDENTIFIER_POINTER
7762 			      (PROTOCOL_NAME (TREE_VALUE (chain))));
7763 		      chain = TREE_CHAIN (chain);
7764 		      if (chain)
7765 			strcat (buf, ", ");
7766 		    }
7767 		  strcat (buf, ">");
7768 		}
7769 	    }
7770 	  if (TREE_CHAIN (chain))
7771 	    strcat (buf, " ");
7772 	}
7773     }
7774   else
7775     {
7776       /* Type qualifiers.  */
7777       if (TREE_READONLY (declspecs))
7778 	strcat (buf, "const ");
7779       if (TYPE_VOLATILE (declspecs))
7780 	strcat (buf, "volatile ");
7781 
7782       switch (TREE_CODE (declspecs))
7783 	{
7784 	  /* Type specifiers.  */
7785 
7786 	case INTEGER_TYPE:
7787 	  declspecs = TYPE_MAIN_VARIANT (declspecs);
7788 
7789 	  /* Signed integer types.  */
7790 
7791 	  if (declspecs == short_integer_type_node)
7792 	    strcat (buf, "short int ");
7793 	  else if (declspecs == integer_type_node)
7794 	    strcat (buf, "int ");
7795 	  else if (declspecs == long_integer_type_node)
7796 	    strcat (buf, "long int ");
7797 	  else if (declspecs == long_long_integer_type_node)
7798 	    strcat (buf, "long long int ");
7799 	  else if (declspecs == signed_char_type_node
7800 		   || declspecs == char_type_node)
7801 	    strcat (buf, "char ");
7802 
7803 	  /* Unsigned integer types.  */
7804 
7805 	  else if (declspecs == short_unsigned_type_node)
7806 	    strcat (buf, "unsigned short ");
7807 	  else if (declspecs == unsigned_type_node)
7808 	    strcat (buf, "unsigned int ");
7809 	  else if (declspecs == long_unsigned_type_node)
7810 	    strcat (buf, "unsigned long ");
7811 	  else if (declspecs == long_long_unsigned_type_node)
7812 	    strcat (buf, "unsigned long long ");
7813 	  else if (declspecs == unsigned_char_type_node)
7814 	    strcat (buf, "unsigned char ");
7815 	  break;
7816 
7817 	case REAL_TYPE:
7818 	  declspecs = TYPE_MAIN_VARIANT (declspecs);
7819 
7820 	  if (declspecs == float_type_node)
7821 	    strcat (buf, "float ");
7822 	  else if (declspecs == double_type_node)
7823 	    strcat (buf, "double ");
7824 	  else if (declspecs == long_double_type_node)
7825 	    strcat (buf, "long double ");
7826 	  break;
7827 
7828 	case RECORD_TYPE:
7829 	  if (TYPE_NAME (declspecs)
7830 	      && TREE_CODE (TYPE_NAME (declspecs)) == IDENTIFIER_NODE)
7831 	    {
7832 	      tree protocol_list = TYPE_PROTOCOL_LIST (declspecs);
7833 
7834 	      if (! TREE_STATIC_TEMPLATE (declspecs))
7835 		strcat (buf, "struct ");
7836 	      strcat (buf, IDENTIFIER_POINTER (TYPE_NAME (declspecs)));
7837 
7838 	      if (protocol_list)
7839 		{
7840 		  tree chain = protocol_list;
7841 
7842 		  strcat (buf, " <");
7843 		  while (chain)
7844 		    {
7845 		      strcat (buf,
7846 			      IDENTIFIER_POINTER
7847 			      (PROTOCOL_NAME (TREE_VALUE (chain))));
7848 		      chain = TREE_CHAIN (chain);
7849 		      if (chain)
7850 			strcat (buf, ", ");
7851 		    }
7852 		  strcat (buf, ">");
7853 		}
7854 	    }
7855 
7856 	  else
7857 	    strcat (buf, "untagged struct");
7858 
7859 	  strcat (buf, " ");
7860 	  break;
7861 
7862 	case UNION_TYPE:
7863 	  if (TYPE_NAME (declspecs)
7864 	      && TREE_CODE (TYPE_NAME (declspecs)) == IDENTIFIER_NODE)
7865 	    {
7866 	      strcat (buf, "union ");
7867 	      strcat (buf, IDENTIFIER_POINTER (TYPE_NAME (declspecs)));
7868 	      strcat (buf, " ");
7869 	    }
7870 
7871 	  else
7872 	    strcat (buf, "untagged union ");
7873 	  break;
7874 
7875 	case ENUMERAL_TYPE:
7876 	  if (TYPE_NAME (declspecs)
7877 	      && TREE_CODE (TYPE_NAME (declspecs)) == IDENTIFIER_NODE)
7878 	    {
7879 	      strcat (buf, "enum ");
7880 	      strcat (buf, IDENTIFIER_POINTER (TYPE_NAME (declspecs)));
7881 	      strcat (buf, " ");
7882 	    }
7883 
7884 	  else
7885 	    strcat (buf, "untagged enum ");
7886 	  break;
7887 
7888 	case VOID_TYPE:
7889 	  strcat (buf, "void ");
7890 	  break;
7891 
7892 	case POINTER_TYPE:
7893 	  {
7894 	    tree protocol_list = TYPE_PROTOCOL_LIST (declspecs);
7895 
7896 	    strcat (buf, "id");
7897 	    if (protocol_list)
7898 	      {
7899 		tree chain = protocol_list;
7900 
7901 		strcat (buf, " <");
7902 		while (chain)
7903 		  {
7904 		    strcat (buf,
7905 			    IDENTIFIER_POINTER
7906 			    (PROTOCOL_NAME (TREE_VALUE (chain))));
7907 		    chain = TREE_CHAIN (chain);
7908 		    if (chain)
7909 		      strcat (buf, ", ");
7910 		  }
7911 
7912 		strcat (buf, ">");
7913 	      }
7914 	  }
7915 	  break;
7916 
7917 	default:
7918 	  break;
7919 	}
7920     }
7921 }
7922 
7923 /* Given a tree node, produce a printable description of it in the given
7924    buffer, overwriting the buffer.  */
7925 
7926 static char *
gen_declaration(atype_or_adecl,buf)7927 gen_declaration (atype_or_adecl, buf)
7928      tree atype_or_adecl;
7929      char *buf;
7930 {
7931   buf[0] = '\0';
7932   gen_declaration_1 (atype_or_adecl, buf);
7933   return buf;
7934 }
7935 
7936 /* Given a tree node, append a printable description to the end of the
7937    given buffer.  */
7938 
7939 static void
gen_declaration_1(atype_or_adecl,buf)7940 gen_declaration_1 (atype_or_adecl, buf)
7941      tree atype_or_adecl;
7942      char *buf;
7943 {
7944   char declbuf[256];
7945 
7946   if (TREE_CODE (atype_or_adecl) == TREE_LIST)
7947     {
7948       tree declspecs;	/* "identifier_node", "record_type" */
7949       tree declarator;	/* "array_ref", "indirect_ref", "call_expr"...  */
7950 
7951       /* We have a "raw", abstract declarator (typename).  */
7952       declarator = TREE_VALUE (atype_or_adecl);
7953       declspecs  = TREE_PURPOSE (atype_or_adecl);
7954 
7955       gen_declspecs (declspecs, buf, 1);
7956       if (declarator)
7957 	{
7958 	  strcat (buf, " ");
7959 	  strcat (buf, gen_declarator (declarator, declbuf, ""));
7960 	}
7961     }
7962 
7963   else
7964     {
7965       tree atype;
7966       tree declspecs;	/* "integer_type", "real_type", "record_type"...  */
7967       tree declarator;	/* "array_type", "function_type", "pointer_type".  */
7968 
7969       if (TREE_CODE (atype_or_adecl) == FIELD_DECL
7970 	  || TREE_CODE (atype_or_adecl) == PARM_DECL
7971 	  || TREE_CODE (atype_or_adecl) == FUNCTION_DECL)
7972 	atype = TREE_TYPE (atype_or_adecl);
7973       else
7974 	/* Assume we have a *_type node.  */
7975 	atype = atype_or_adecl;
7976 
7977       if (is_complex_decl (atype))
7978 	{
7979 	  tree chain;
7980 
7981 	  /* Get the declaration specifier; it is at the end of the list.  */
7982 	  declarator = chain = atype;
7983 	  do
7984 	    chain = TREE_TYPE (chain); /* not TREE_CHAIN (chain); */
7985 	  while (is_complex_decl (chain));
7986 	  declspecs = chain;
7987 	}
7988 
7989       else
7990 	{
7991 	  declspecs = atype;
7992 	  declarator = NULL_TREE;
7993 	}
7994 
7995       gen_declspecs (declspecs, buf, 0);
7996 
7997       if (TREE_CODE (atype_or_adecl) == FIELD_DECL
7998 	  || TREE_CODE (atype_or_adecl) == PARM_DECL
7999 	  || TREE_CODE (atype_or_adecl) == FUNCTION_DECL)
8000 	{
8001 	  const char *const decl_name =
8002 	    (DECL_NAME (atype_or_adecl)
8003 	     ? IDENTIFIER_POINTER (DECL_NAME (atype_or_adecl)) : "");
8004 
8005 	  if (declarator)
8006 	    {
8007 	      strcat (buf, " ");
8008 	      strcat (buf, gen_declarator (declarator, declbuf, decl_name));
8009 	    }
8010 
8011 	  else if (decl_name[0])
8012 	    {
8013 	      strcat (buf, " ");
8014 	      strcat (buf, decl_name);
8015 	    }
8016 	}
8017       else if (declarator)
8018 	{
8019 	  strcat (buf, " ");
8020 	  strcat (buf, gen_declarator (declarator, declbuf, ""));
8021 	}
8022     }
8023 }
8024 
8025 #define RAW_TYPESPEC(meth) (TREE_VALUE (TREE_PURPOSE (TREE_TYPE (meth))))
8026 
8027 /* Given a method tree, put a printable description into the given
8028    buffer (overwriting) and return a pointer to the buffer.  */
8029 
8030 static char *
gen_method_decl(method,buf)8031 gen_method_decl (method, buf)
8032      tree method;
8033      char *buf;
8034 {
8035   tree chain;
8036 
8037   buf[0] = '\0';
8038   if (RAW_TYPESPEC (method) != objc_object_reference)
8039     {
8040       strcat (buf, "(");
8041       gen_declaration_1 (TREE_TYPE (method), buf);
8042       strcat (buf, ")");
8043     }
8044 
8045   chain = METHOD_SEL_ARGS (method);
8046   if (chain)
8047     {
8048       /* We have a chain of keyword_decls.  */
8049       do
8050         {
8051 	  if (KEYWORD_KEY_NAME (chain))
8052 	    strcat (buf, IDENTIFIER_POINTER (KEYWORD_KEY_NAME (chain)));
8053 
8054 	  strcat (buf, ":");
8055 	  if (RAW_TYPESPEC (chain) != objc_object_reference)
8056 	    {
8057 	      strcat (buf, "(");
8058 	      gen_declaration_1 (TREE_TYPE (chain), buf);
8059 	      strcat (buf, ")");
8060 	    }
8061 
8062 	  strcat (buf, IDENTIFIER_POINTER (KEYWORD_ARG_NAME (chain)));
8063 	  if ((chain = TREE_CHAIN (chain)))
8064 	    strcat (buf, " ");
8065         }
8066       while (chain);
8067 
8068       if (METHOD_ADD_ARGS (method) == objc_ellipsis_node)
8069         strcat (buf, ", ...");
8070       else if (METHOD_ADD_ARGS (method))
8071         {
8072 	  /* We have a tree list node as generate by get_parm_info.  */
8073 	  chain  = TREE_PURPOSE (METHOD_ADD_ARGS (method));
8074 
8075           /* Know we have a chain of parm_decls.  */
8076           while (chain)
8077             {
8078 	      strcat (buf, ", ");
8079 	      gen_declaration_1 (chain, buf);
8080 	      chain = TREE_CHAIN (chain);
8081             }
8082 	}
8083     }
8084 
8085   else
8086     /* We have a unary selector.  */
8087     strcat (buf, IDENTIFIER_POINTER (METHOD_SEL_NAME (method)));
8088 
8089   return buf;
8090 }
8091 
8092 /* Debug info.  */
8093 
8094 
8095 /* Dump an @interface declaration of the supplied class CHAIN to the
8096    supplied file FP.  Used to implement the -gen-decls option (which
8097    prints out an @interface declaration of all classes compiled in
8098    this run); potentially useful for debugging the compiler too.  */
8099 static void
dump_interface(fp,chain)8100 dump_interface (fp, chain)
8101      FILE *fp;
8102      tree chain;
8103 {
8104   /* FIXME: A heap overflow here whenever a method (or ivar)
8105      declaration is so long that it doesn't fit in the buffer.  The
8106      code and all the related functions should be rewritten to avoid
8107      using fixed size buffers.  */
8108   char *buf = (char *) xmalloc (1024 * 10);
8109   const char *my_name = IDENTIFIER_POINTER (CLASS_NAME (chain));
8110   tree ivar_decls = CLASS_RAW_IVARS (chain);
8111   tree nst_methods = CLASS_NST_METHODS (chain);
8112   tree cls_methods = CLASS_CLS_METHODS (chain);
8113 
8114   fprintf (fp, "\n@interface %s", my_name);
8115 
8116   /* CLASS_SUPER_NAME is used to store the superclass name for
8117      classes, and the category name for categories.  */
8118   if (CLASS_SUPER_NAME (chain))
8119     {
8120       const char *name = IDENTIFIER_POINTER (CLASS_SUPER_NAME (chain));
8121 
8122       if (TREE_CODE (chain) == CATEGORY_IMPLEMENTATION_TYPE
8123 	  || TREE_CODE (chain) == CATEGORY_INTERFACE_TYPE)
8124 	{
8125 	  fprintf (fp, " (%s)\n", name);
8126 	}
8127       else
8128 	{
8129 	  fprintf (fp, " : %s\n", name);
8130 	}
8131     }
8132   else
8133     fprintf (fp, "\n");
8134 
8135   /* FIXME - the following doesn't seem to work at the moment.  */
8136   if (ivar_decls)
8137     {
8138       fprintf (fp, "{\n");
8139       do
8140 	{
8141 	  fprintf (fp, "\t%s;\n", gen_declaration (ivar_decls, buf));
8142 	  ivar_decls = TREE_CHAIN (ivar_decls);
8143 	}
8144       while (ivar_decls);
8145       fprintf (fp, "}\n");
8146     }
8147 
8148   while (nst_methods)
8149     {
8150       fprintf (fp, "- %s;\n", gen_method_decl (nst_methods, buf));
8151       nst_methods = TREE_CHAIN (nst_methods);
8152     }
8153 
8154   while (cls_methods)
8155     {
8156       fprintf (fp, "+ %s;\n", gen_method_decl (cls_methods, buf));
8157       cls_methods = TREE_CHAIN (cls_methods);
8158     }
8159 
8160   fprintf (fp, "@end\n");
8161 }
8162 
8163 /* Demangle function for Objective-C */
8164 static const char *
objc_demangle(mangled)8165 objc_demangle (mangled)
8166      const char *mangled;
8167 {
8168   char *demangled, *cp;
8169 
8170   if (mangled[0] == '_' &&
8171       (mangled[1] == 'i' || mangled[1] == 'c') &&
8172       mangled[2] == '_')
8173     {
8174       cp = demangled = xmalloc(strlen(mangled) + 2);
8175       if (mangled[1] == 'i')
8176 	*cp++ = '-';            /* for instance method */
8177       else
8178 	*cp++ = '+';            /* for class method */
8179       *cp++ = '[';              /* opening left brace */
8180       strcpy(cp, mangled+3);    /* tack on the rest of the mangled name */
8181       while (*cp && *cp == '_')
8182 	cp++;                   /* skip any initial underbars in class name */
8183       cp = strchr(cp, '_');     /* find first non-initial underbar */
8184       if (cp == NULL)
8185 	{
8186 	  free(demangled);      /* not mangled name */
8187 	  return mangled;
8188 	}
8189       if (cp[1] == '_')  /* easy case: no category name */
8190 	{
8191 	  *cp++ = ' ';            /* replace two '_' with one ' ' */
8192 	  strcpy(cp, mangled + (cp - demangled) + 2);
8193 	}
8194       else
8195 	{
8196 	  *cp++ = '(';            /* less easy case: category name */
8197 	  cp = strchr(cp, '_');
8198 	  if (cp == 0)
8199 	    {
8200 	      free(demangled);    /* not mangled name */
8201 	      return mangled;
8202 	    }
8203 	  *cp++ = ')';
8204 	  *cp++ = ' ';            /* overwriting 1st char of method name... */
8205 	  strcpy(cp, mangled + (cp - demangled)); /* get it back */
8206 	}
8207       while (*cp && *cp == '_')
8208 	cp++;                   /* skip any initial underbars in method name */
8209       for (; *cp; cp++)
8210 	if (*cp == '_')
8211 	  *cp = ':';            /* replace remaining '_' with ':' */
8212       *cp++ = ']';              /* closing right brace */
8213       *cp++ = 0;                /* string terminator */
8214       return demangled;
8215     }
8216   else
8217     return mangled;             /* not an objc mangled name */
8218 }
8219 
8220 const char *
objc_printable_name(decl,kind)8221 objc_printable_name (decl, kind)
8222      tree decl;
8223      int kind ATTRIBUTE_UNUSED;
8224 {
8225   return objc_demangle (IDENTIFIER_POINTER (DECL_NAME (decl)));
8226 }
8227 
8228 static void
init_objc()8229 init_objc ()
8230 {
8231   gcc_obstack_init (&util_obstack);
8232   util_firstobj = (char *) obstack_finish (&util_obstack);
8233 
8234   errbuf = (char *) xmalloc (BUFSIZE);
8235   hash_init ();
8236   synth_module_prologue ();
8237 }
8238 
8239 static void
finish_objc()8240 finish_objc ()
8241 {
8242   struct imp_entry *impent;
8243   tree chain;
8244   /* The internally generated initializers appear to have missing braces.
8245      Don't warn about this.  */
8246   int save_warn_missing_braces = warn_missing_braces;
8247   warn_missing_braces = 0;
8248 
8249   /* A missing @end may not be detected by the parser.  */
8250   if (objc_implementation_context)
8251     {
8252       warning ("`@end' missing in implementation context");
8253       finish_class (objc_implementation_context);
8254       objc_ivar_chain = NULL_TREE;
8255       objc_implementation_context = NULL_TREE;
8256     }
8257 
8258   generate_forward_declaration_to_string_table ();
8259 
8260 #ifdef OBJC_PROLOGUE
8261   OBJC_PROLOGUE;
8262 #endif
8263 
8264   /* Process the static instances here because initialization of objc_symtab
8265      depends on them.  */
8266   if (objc_static_instances)
8267     generate_static_references ();
8268 
8269   if (imp_list || class_names_chain
8270       || meth_var_names_chain || meth_var_types_chain || sel_ref_chain)
8271     generate_objc_symtab_decl ();
8272 
8273   for (impent = imp_list; impent; impent = impent->next)
8274     {
8275       objc_implementation_context = impent->imp_context;
8276       implementation_template = impent->imp_template;
8277 
8278       UOBJC_CLASS_decl = impent->class_decl;
8279       UOBJC_METACLASS_decl = impent->meta_decl;
8280 
8281       /* Dump the @interface of each class as we compile it, if the
8282 	 -gen-decls option is in use.  TODO: Dump the classes in the
8283          order they were found, rather than in reverse order as we
8284          are doing now.  */
8285       if (flag_gen_declaration)
8286 	{
8287 	  dump_interface (gen_declaration_file, objc_implementation_context);
8288 	}
8289 
8290       if (TREE_CODE (objc_implementation_context) == CLASS_IMPLEMENTATION_TYPE)
8291 	{
8292 	  /* all of the following reference the string pool...  */
8293 	  generate_ivar_lists ();
8294 	  generate_dispatch_tables ();
8295 	  generate_shared_structures ();
8296 	}
8297       else
8298 	{
8299 	  generate_dispatch_tables ();
8300 	  generate_category (objc_implementation_context);
8301 	}
8302     }
8303 
8304   /* If we are using an array of selectors, we must always
8305      finish up the array decl even if no selectors were used.  */
8306   if (! flag_next_runtime || sel_ref_chain)
8307     build_selector_translation_table ();
8308 
8309   if (protocol_chain)
8310     generate_protocols ();
8311 
8312   if (objc_implementation_context || class_names_chain || objc_static_instances
8313       || meth_var_names_chain || meth_var_types_chain || sel_ref_chain)
8314     {
8315       /* Arrange for ObjC data structures to be initialized at run time.  */
8316       rtx init_sym = build_module_descriptor ();
8317       if (init_sym && targetm.have_ctors_dtors)
8318 	(* targetm.asm_out.constructor) (init_sym, DEFAULT_INIT_PRIORITY);
8319     }
8320 
8321   /* Dump the class references.  This forces the appropriate classes
8322      to be linked into the executable image, preserving unix archive
8323      semantics.  This can be removed when we move to a more dynamically
8324      linked environment.  */
8325 
8326   for (chain = cls_ref_chain; chain; chain = TREE_CHAIN (chain))
8327     {
8328       handle_class_ref (chain);
8329       if (TREE_PURPOSE (chain))
8330 	generate_classref_translation_entry (chain);
8331     }
8332 
8333   for (impent = imp_list; impent; impent = impent->next)
8334     handle_impent (impent);
8335 
8336   /* Dump the string table last.  */
8337 
8338   generate_strings ();
8339 
8340   if (warn_selector)
8341     {
8342       int slot;
8343       hash hsh;
8344 
8345       /* Run through the selector hash tables and print a warning for any
8346          selector which has multiple methods.  */
8347 
8348       for (slot = 0; slot < SIZEHASHTABLE; slot++)
8349 	for (hsh = cls_method_hash_list[slot]; hsh; hsh = hsh->next)
8350 	  if (hsh->list)
8351 	    {
8352 	      tree meth = hsh->key;
8353 	      char type = (TREE_CODE (meth) == INSTANCE_METHOD_DECL
8354 			   ? '-' : '+');
8355 	      attr loop;
8356 
8357 	      warning ("potential selector conflict for method `%s'",
8358 		       IDENTIFIER_POINTER (METHOD_SEL_NAME (meth)));
8359 	      warn_with_method ("found", type, meth);
8360 	      for (loop = hsh->list; loop; loop = loop->next)
8361 		warn_with_method ("found", type, loop->value);
8362 	    }
8363 
8364       for (slot = 0; slot < SIZEHASHTABLE; slot++)
8365 	for (hsh = nst_method_hash_list[slot]; hsh; hsh = hsh->next)
8366 	  if (hsh->list)
8367 	    {
8368 	      tree meth = hsh->key;
8369 	      char type = (TREE_CODE (meth) == INSTANCE_METHOD_DECL
8370 			   ? '-' : '+');
8371 	      attr loop;
8372 
8373 	      warning ("potential selector conflict for method `%s'",
8374 		       IDENTIFIER_POINTER (METHOD_SEL_NAME (meth)));
8375 	      warn_with_method ("found", type, meth);
8376 	      for (loop = hsh->list; loop; loop = loop->next)
8377 		warn_with_method ("found", type, loop->value);
8378 	    }
8379     }
8380 
8381   warn_missing_braces = save_warn_missing_braces;
8382 }
8383 
8384 /* Subroutines of finish_objc.  */
8385 
8386 static void
generate_classref_translation_entry(chain)8387 generate_classref_translation_entry (chain)
8388      tree chain;
8389 {
8390   tree expr, name, decl_specs, decl, sc_spec;
8391   tree type;
8392 
8393   type = TREE_TYPE (TREE_PURPOSE (chain));
8394 
8395   expr = add_objc_string (TREE_VALUE (chain), class_names);
8396   expr = build_c_cast (type, expr); /* cast! */
8397 
8398   name = DECL_NAME (TREE_PURPOSE (chain));
8399 
8400   sc_spec = build_tree_list (NULL_TREE, ridpointers[(int) RID_STATIC]);
8401 
8402   /* static struct objc_class * _OBJC_CLASS_REFERENCES_n = ...; */
8403   decl_specs = tree_cons (NULL_TREE, type, sc_spec);
8404 
8405   /* The decl that is returned from start_decl is the one that we
8406      forward declared in build_class_reference.  */
8407   decl = start_decl (name, decl_specs, 1, NULL_TREE);
8408   DECL_CONTEXT (decl) = NULL_TREE;
8409   finish_decl (decl, expr, NULL_TREE);
8410   return;
8411 }
8412 
8413 static void
handle_class_ref(chain)8414 handle_class_ref (chain)
8415      tree chain;
8416 {
8417   const char *name = IDENTIFIER_POINTER (TREE_VALUE (chain));
8418   char *string = (char *) alloca (strlen (name) + 30);
8419   tree decl;
8420   tree exp;
8421 
8422   sprintf (string, "%sobjc_class_name_%s",
8423 	   (flag_next_runtime ? "." : "__"), name);
8424 
8425 #ifdef ASM_DECLARE_UNRESOLVED_REFERENCE
8426   if (flag_next_runtime)
8427     {
8428       ASM_DECLARE_UNRESOLVED_REFERENCE (asm_out_file, string);
8429       return;
8430     }
8431 #endif
8432 
8433   /* Make a decl for this name, so we can use its address in a tree.  */
8434   decl = build_decl (VAR_DECL, get_identifier (string), char_type_node);
8435   DECL_EXTERNAL (decl) = 1;
8436   TREE_PUBLIC (decl) = 1;
8437 
8438   pushdecl (decl);
8439   rest_of_decl_compilation (decl, 0, 0, 0);
8440 
8441   /* Make a decl for the address.  */
8442   sprintf (string, "%sobjc_class_ref_%s",
8443 	   (flag_next_runtime ? "." : "__"), name);
8444   exp = build1 (ADDR_EXPR, string_type_node, decl);
8445   decl = build_decl (VAR_DECL, get_identifier (string), string_type_node);
8446   DECL_INITIAL (decl) = exp;
8447   TREE_STATIC (decl) = 1;
8448   TREE_USED (decl) = 1;
8449 
8450   pushdecl (decl);
8451   rest_of_decl_compilation (decl, 0, 0, 0);
8452 }
8453 
8454 static void
handle_impent(impent)8455 handle_impent (impent)
8456      struct imp_entry *impent;
8457 {
8458   char *string;
8459 
8460   objc_implementation_context = impent->imp_context;
8461   implementation_template = impent->imp_template;
8462 
8463   if (TREE_CODE (impent->imp_context) == CLASS_IMPLEMENTATION_TYPE)
8464     {
8465       const char *const class_name =
8466 	IDENTIFIER_POINTER (CLASS_NAME (impent->imp_context));
8467 
8468       string = (char *) alloca (strlen (class_name) + 30);
8469 
8470       sprintf (string, "%sobjc_class_name_%s",
8471                (flag_next_runtime ? "." : "__"), class_name);
8472     }
8473   else if (TREE_CODE (impent->imp_context) == CATEGORY_IMPLEMENTATION_TYPE)
8474     {
8475       const char *const class_name =
8476 	IDENTIFIER_POINTER (CLASS_NAME (impent->imp_context));
8477       const char *const class_super_name =
8478         IDENTIFIER_POINTER (CLASS_SUPER_NAME (impent->imp_context));
8479 
8480       string = (char *) alloca (strlen (class_name)
8481 				+ strlen (class_super_name) + 30);
8482 
8483       /* Do the same for categories.  Even though no references to
8484          these symbols are generated automatically by the compiler, it
8485          gives you a handle to pull them into an archive by hand.  */
8486       sprintf (string, "*%sobjc_category_name_%s_%s",
8487                (flag_next_runtime ? "." : "__"), class_name, class_super_name);
8488     }
8489   else
8490     return;
8491 
8492 #ifdef ASM_DECLARE_CLASS_REFERENCE
8493   if (flag_next_runtime)
8494     {
8495       ASM_DECLARE_CLASS_REFERENCE (asm_out_file, string);
8496       return;
8497     }
8498   else
8499 #endif
8500     {
8501       tree decl, init;
8502 
8503       init = build_int_2 (0, 0);
8504       TREE_TYPE (init) = c_common_type_for_size (BITS_PER_WORD, 1);
8505       decl = build_decl (VAR_DECL, get_identifier (string), TREE_TYPE (init));
8506       TREE_PUBLIC (decl) = 1;
8507       TREE_READONLY (decl) = 1;
8508       TREE_USED (decl) = 1;
8509       TREE_CONSTANT (decl) = 1;
8510       DECL_CONTEXT (decl) = 0;
8511       DECL_ARTIFICIAL (decl) = 1;
8512       DECL_INITIAL (decl) = init;
8513       assemble_variable (decl, 1, 0, 0);
8514     }
8515 }
8516 
8517 /* Look up ID as an instance variable.  */
8518 tree
lookup_objc_ivar(id)8519 lookup_objc_ivar (id)
8520      tree id;
8521 {
8522   tree decl;
8523 
8524   if (objc_method_context && !strcmp (IDENTIFIER_POINTER (id), "super"))
8525     /* We have a message to super.  */
8526     return get_super_receiver ();
8527   else if (objc_method_context && (decl = is_ivar (objc_ivar_chain, id)))
8528     {
8529       if (is_private (decl))
8530 	return 0;
8531       else
8532         return build_ivar_reference (id);
8533     }
8534   else
8535     return 0;
8536 }
8537 
8538 #include "gtype-objc.h"
8539