OSDN Git Service

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