OSDN Git Service

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