OSDN Git Service

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