OSDN Git Service

* c-decl.c (c_decode_option): Don't handle -lang-objc.
[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,
3    1999, 2000 Free Software Foundation, Inc.
4    Contributed by Steve Naroff.
5
6 This file is part of GNU CC.
7
8 GNU CC is free software; you can redistribute it and/or modify
9 it under the terms of the GNU General Public License as published by
10 the Free Software Foundation; either version 2, or (at your option)
11 any later version.
12
13 GNU CC is distributed in the hope that it will be useful,
14 but WITHOUT ANY WARRANTY; without even the implied warranty of
15 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
16 GNU General Public License for more details.
17
18 You should have received a copy of the GNU General Public License
19 along with GNU CC; see the file COPYING.  If not, write to
20 the Free Software Foundation, 59 Temple Place - Suite 330,
21 Boston, MA 02111-1307, USA.  */
22
23 /* Purpose: This module implements the Objective-C 4.0 language.
24
25    compatibility issues (with the Stepstone translator):
26
27    - does not recognize the following 3.3 constructs.
28      @requires, @classes, @messages, = (...)
29    - methods with variable arguments must conform to ANSI standard.
30    - tagged structure definitions that appear in BOTH the interface
31      and implementation are not allowed.
32    - public/private: all instance variables are public within the
33      context of the implementation...I consider this to be a bug in
34      the translator.
35    - statically allocated objects are not supported. the user will
36      receive an error if this service is requested.
37
38    code generation `options':
39
40    - OBJC_INT_SELECTORS  */
41
42 #include "config.h"
43 #include "system.h"
44 #include "tree.h"
45 #include "rtl.h"
46 #include "expr.h"
47 #include "c-tree.h"
48 #include "c-lex.h"
49 #include "c-common.h"
50 #include "flags.h"
51 #include "objc-act.h"
52 #include "input.h"
53 #include "except.h"
54 #include "function.h"
55 #include "output.h"
56 #include "toplev.h"
57 #include "ggc.h"
58 #include "cpplib.h"
59
60 /* This is the default way of generating a method name.  */
61 /* I am not sure it is really correct.
62    Perhaps there's a danger that it will make name conflicts
63    if method names contain underscores. -- rms.  */
64 #ifndef OBJC_GEN_METHOD_LABEL
65 #define OBJC_GEN_METHOD_LABEL(BUF, IS_INST, CLASS_NAME, CAT_NAME, SEL_NAME, NUM) \
66   do {                                      \
67     char *temp;                             \
68     sprintf ((BUF), "_%s_%s_%s_%s",         \
69              ((IS_INST) ? "i" : "c"),       \
70              (CLASS_NAME),                  \
71              ((CAT_NAME)? (CAT_NAME) : ""), \
72              (SEL_NAME));                   \
73     for (temp = (BUF); *temp; temp++)       \
74       if (*temp == ':') *temp = '_';        \
75   } while (0)
76 #endif
77
78 /* These need specifying.  */
79 #ifndef OBJC_FORWARDING_STACK_OFFSET
80 #define OBJC_FORWARDING_STACK_OFFSET 0
81 #endif
82
83 #ifndef OBJC_FORWARDING_MIN_OFFSET
84 #define OBJC_FORWARDING_MIN_OFFSET 0
85 #endif
86 \f
87 /* Define the special tree codes that we use.  */
88
89 /* Table indexed by tree code giving a string containing a character
90    classifying the tree code.  Possibilities are
91    t, d, s, c, r, <, 1 and 2.  See objc-tree.def for details.  */
92
93 #define DEFTREECODE(SYM, NAME, TYPE, LENGTH) TYPE,
94
95 static const char objc_tree_code_type[] = {
96   'x',
97 #include "objc-tree.def"
98 };
99 #undef DEFTREECODE
100
101 /* Table indexed by tree code giving number of expression
102    operands beyond the fixed part of the node structure.
103    Not used for types or decls.  */
104
105 #define DEFTREECODE(SYM, NAME, TYPE, LENGTH) LENGTH,
106
107 static const int objc_tree_code_length[] = {
108   0,
109 #include "objc-tree.def"
110 };
111 #undef DEFTREECODE
112
113 /* Names of tree components.
114    Used for printing out the tree and error messages.  */
115 #define DEFTREECODE(SYM, NAME, TYPE, LEN) NAME,
116
117 static const char * const objc_tree_code_name[] = {
118   "@@dummy",
119 #include "objc-tree.def"
120 };
121 #undef DEFTREECODE
122 \f
123 /* Set up for use of obstacks.  */
124
125 #include "obstack.h"
126
127 #define obstack_chunk_alloc xmalloc
128 #define obstack_chunk_free free
129
130 /* This obstack is used to accumulate the encoding of a data type.  */
131 static struct obstack util_obstack;
132 /* This points to the beginning of obstack contents,
133    so we can free the whole contents.  */
134 char *util_firstobj;
135
136 /* for encode_method_def */
137 #include "rtl.h"
138
139 #define OBJC_VERSION    (flag_next_runtime ? 5 : 8)
140 #define PROTOCOL_VERSION 2
141
142 #define OBJC_ENCODE_INLINE_DEFS         0
143 #define OBJC_ENCODE_DONT_INLINE_DEFS    1
144
145 /*** Private Interface (procedures) ***/
146
147 /* Used by compile_file.  */
148
149 static void init_objc                           PARAMS ((void));
150 static void finish_objc                         PARAMS ((void));
151
152 /* Code generation.  */
153
154 static void synth_module_prologue               PARAMS ((void));
155 static tree build_constructor                   PARAMS ((tree, tree));
156 static const char *build_module_descriptor      PARAMS ((void));
157 static tree init_module_descriptor              PARAMS ((tree));
158 static tree build_objc_method_call              PARAMS ((int, tree, tree,
159                                                        tree, tree, tree));
160 static void generate_strings                    PARAMS ((void));
161 static tree get_proto_encoding                  PARAMS ((tree));
162 static void build_selector_translation_table    PARAMS ((void));
163 static tree build_ivar_chain                    PARAMS ((tree, int));
164
165 static tree objc_add_static_instance            PARAMS ((tree, tree));
166
167 static tree build_ivar_template                 PARAMS ((void));
168 static tree build_method_template               PARAMS ((void));
169 static tree build_private_template              PARAMS ((tree));
170 static void build_class_template                PARAMS ((void));
171 static void build_selector_template             PARAMS ((void));
172 static void build_category_template             PARAMS ((void));
173 static tree build_super_template                PARAMS ((void));
174 static tree build_category_initializer          PARAMS ((tree, tree, tree,
175                                                        tree, tree, tree));
176 static tree build_protocol_initializer          PARAMS ((tree, tree, tree,
177                                                        tree, tree));
178
179 static void synth_forward_declarations          PARAMS ((void));
180 static void generate_ivar_lists                 PARAMS ((void));
181 static void generate_dispatch_tables            PARAMS ((void));
182 static void generate_shared_structures          PARAMS ((void));
183 static tree generate_protocol_list              PARAMS ((tree));
184 static void generate_forward_declaration_to_string_table PARAMS ((void));
185 static void build_protocol_reference            PARAMS ((tree));
186
187 #if 0
188 static tree init_selector                       PARAMS ((int));
189 #endif
190 static tree build_keyword_selector              PARAMS ((tree));
191 static tree synth_id_with_class_suffix          PARAMS ((const char *, tree));
192
193 static void generate_static_references          PARAMS ((void));
194 static int check_methods_accessible             PARAMS ((tree, tree,
195                                                        int));
196 static void encode_aggregate_within             PARAMS ((tree, int, int,
197                                                        int, int));
198 static const char *objc_demangle                PARAMS ((const char *));
199 static const char *objc_printable_name          PARAMS ((tree, int));
200 static void objc_expand_function_end            PARAMS ((void));
201
202 /* Misc. bookkeeping */
203
204 typedef struct hashed_entry     *hash;
205 typedef struct hashed_attribute  *attr;
206
207 struct hashed_attribute
208 {
209   attr next;
210   tree value;
211 };
212 struct hashed_entry
213 {
214   attr list;
215   hash next;
216   tree key;
217 };
218
219 static void hash_init                           PARAMS ((void));
220 static void hash_enter                          PARAMS ((hash *, tree));
221 static hash hash_lookup                         PARAMS ((hash *, tree));
222 static void hash_add_attr                       PARAMS ((hash, tree));
223 static tree lookup_method                       PARAMS ((tree, tree));
224 static tree lookup_instance_method_static       PARAMS ((tree, tree));
225 static tree lookup_class_method_static          PARAMS ((tree, tree));
226 static tree add_class                           PARAMS ((tree));
227 static void add_category                        PARAMS ((tree, tree));
228
229 enum string_section
230 {
231   class_names,          /* class, category, protocol, module names */
232   meth_var_names,       /* method and variable names */
233   meth_var_types        /* method and variable type descriptors */
234 };
235
236 static tree add_objc_string                     PARAMS ((tree,
237                                                        enum string_section));
238 static tree get_objc_string_decl                PARAMS ((tree,
239                                                        enum string_section));
240 static tree build_objc_string_decl              PARAMS ((enum string_section));
241 static tree build_selector_reference_decl       PARAMS ((void));
242
243 /* Protocol additions.  */
244
245 static tree add_protocol                        PARAMS ((tree));
246 static tree lookup_protocol                     PARAMS ((tree));
247 static tree lookup_and_install_protocols        PARAMS ((tree));
248
249 /* Type encoding.  */
250
251 static void encode_type_qualifiers              PARAMS ((tree));
252 static void encode_pointer                      PARAMS ((tree, int, int));
253 static void encode_array                        PARAMS ((tree, int, int));
254 static void encode_aggregate                    PARAMS ((tree, int, int));
255 static void encode_bitfield                     PARAMS ((int));
256 static void encode_type                         PARAMS ((tree, int, int));
257 static void encode_field_decl                   PARAMS ((tree, int, int));
258
259 static void really_start_method                 PARAMS ((tree, tree));
260 static int comp_method_with_proto               PARAMS ((tree, tree));
261 static int comp_proto_with_proto                PARAMS ((tree, tree));
262 static tree get_arg_type_list                   PARAMS ((tree, int, int));
263 static tree expr_last                           PARAMS ((tree));
264
265 /* Utilities for debugging and error diagnostics.  */
266
267 static void warn_with_method                    PARAMS ((const char *, int, tree));
268 static void error_with_ivar                     PARAMS ((const char *, tree, tree));
269 static char *gen_method_decl                    PARAMS ((tree, char *));
270 static char *gen_declaration                    PARAMS ((tree, char *));
271 static char *gen_declarator                     PARAMS ((tree, char *,
272                                                        const char *));
273 static int is_complex_decl                      PARAMS ((tree));
274 static void adorn_decl                          PARAMS ((tree, char *));
275 static void dump_interface                      PARAMS ((FILE *, tree));
276
277 /* Everything else.  */
278
279 static void objc_fatal                          PARAMS ((void))
280   ATTRIBUTE_NORETURN;
281 static tree define_decl                         PARAMS ((tree, tree));
282 static tree lookup_method_in_protocol_list      PARAMS ((tree, tree, int));
283 static tree lookup_protocol_in_reflist          PARAMS ((tree, tree));
284 static tree create_builtin_decl                 PARAMS ((enum tree_code,
285                                                        tree, const char *));
286 static tree my_build_string                     PARAMS ((int, const char *));
287 static void build_objc_symtab_template          PARAMS ((void));
288 static tree init_def_list                       PARAMS ((tree));
289 static tree init_objc_symtab                    PARAMS ((tree));
290 static void forward_declare_categories          PARAMS ((void));
291 static void generate_objc_symtab_decl           PARAMS ((void));
292 static tree build_selector                      PARAMS ((tree));
293 #if 0
294 static tree build_msg_pool_reference            PARAMS ((int));
295 #endif
296 static tree build_typed_selector_reference      PARAMS ((tree, tree));
297 static tree build_selector_reference            PARAMS ((tree));
298 static tree build_class_reference_decl          PARAMS ((void));
299 static void add_class_reference                 PARAMS ((tree));
300 static tree objc_copy_list                      PARAMS ((tree, tree *));
301 static tree build_protocol_template             PARAMS ((void));
302 static tree build_descriptor_table_initializer  PARAMS ((tree, tree));
303 static tree build_method_prototype_list_template PARAMS ((tree, int));
304 static tree build_method_prototype_template     PARAMS ((void));
305 static int forwarding_offset                    PARAMS ((tree));
306 static tree encode_method_prototype             PARAMS ((tree, tree));
307 static tree generate_descriptor_table           PARAMS ((tree, const char *,
308                                                        int, tree, tree));
309 static void generate_method_descriptors         PARAMS ((tree));
310 static tree build_tmp_function_decl             PARAMS ((void));
311 static void hack_method_prototype               PARAMS ((tree, tree));
312 static void generate_protocol_references        PARAMS ((tree));
313 static void generate_protocols                  PARAMS ((void));
314 static void check_ivars                         PARAMS ((tree, tree));
315 static tree build_ivar_list_template            PARAMS ((tree, int));
316 static tree build_method_list_template          PARAMS ((tree, int));
317 static tree build_ivar_list_initializer         PARAMS ((tree, tree));
318 static tree generate_ivars_list                 PARAMS ((tree, const char *,
319                                                        int, tree));
320 static tree build_dispatch_table_initializer    PARAMS ((tree, tree));
321 static tree generate_dispatch_table             PARAMS ((tree, const char *,
322                                                        int, tree));
323 static tree build_shared_structure_initializer  PARAMS ((tree, tree, tree, tree,
324                                                        tree, int, tree, tree,
325                                                        tree));
326 static void generate_category                   PARAMS ((tree));
327 static int is_objc_type_qualifier               PARAMS ((tree));
328 static tree adjust_type_for_id_default          PARAMS ((tree));
329 static tree check_duplicates                    PARAMS ((hash));
330 static tree receiver_is_class_object            PARAMS ((tree));
331 static int check_methods                        PARAMS ((tree, tree, int));
332 static int conforms_to_protocol                 PARAMS ((tree, tree));
333 static void check_protocols                     PARAMS ((tree, const char *,
334                                                        const char *));
335 static tree encode_method_def                   PARAMS ((tree));
336 static void gen_declspecs                       PARAMS ((tree, char *, int));
337 static void generate_classref_translation_entry PARAMS ((tree));
338 static void handle_class_ref                    PARAMS ((tree));
339 static void generate_struct_by_value_array      PARAMS ((void))
340      ATTRIBUTE_NORETURN;
341 static void objc_act_parse_init                 PARAMS ((void));
342 static void ggc_mark_imp_list                   PARAMS ((void *));
343 static void ggc_mark_hash_table                 PARAMS ((void *));
344
345 /*** Private Interface (data) ***/
346
347 /* Reserved tag definitions.  */
348
349 #define TYPE_ID                 "id"
350 #define TAG_OBJECT              "objc_object"
351 #define TAG_CLASS               "objc_class"
352 #define TAG_SUPER               "objc_super"
353 #define TAG_SELECTOR            "objc_selector"
354
355 #define UTAG_CLASS              "_objc_class"
356 #define UTAG_IVAR               "_objc_ivar"
357 #define UTAG_IVAR_LIST          "_objc_ivar_list"
358 #define UTAG_METHOD             "_objc_method"
359 #define UTAG_METHOD_LIST        "_objc_method_list"
360 #define UTAG_CATEGORY           "_objc_category"
361 #define UTAG_MODULE             "_objc_module"
362 #define UTAG_STATICS            "_objc_statics"
363 #define UTAG_SYMTAB             "_objc_symtab"
364 #define UTAG_SUPER              "_objc_super"
365 #define UTAG_SELECTOR           "_objc_selector"
366
367 #define UTAG_PROTOCOL           "_objc_protocol"
368 #define UTAG_PROTOCOL_LIST      "_objc_protocol_list"
369 #define UTAG_METHOD_PROTOTYPE   "_objc_method_prototype"
370 #define UTAG_METHOD_PROTOTYPE_LIST "_objc__method_prototype_list"
371
372 #define STRING_OBJECT_CLASS_NAME "NXConstantString"
373 #define PROTOCOL_OBJECT_CLASS_NAME "Protocol"
374
375 static const char *constant_string_class_name = NULL;
376
377 static const char *TAG_GETCLASS;
378 static const char *TAG_GETMETACLASS;
379 static const char *TAG_MSGSEND;
380 static const char *TAG_MSGSENDSUPER;
381 static const char *TAG_EXECCLASS;
382
383 /* Set by `continue_class' and checked by `is_public'.  */
384
385 #define TREE_STATIC_TEMPLATE(record_type) (TREE_PUBLIC (record_type))
386 #define TYPED_OBJECT(type) \
387        (TREE_CODE (type) == RECORD_TYPE && TREE_STATIC_TEMPLATE (type))
388
389 tree objc_ellipsis_node;
390
391 enum objc_tree_index
392 {
393     OCTI_STATIC_NST,
394     OCTI_STATIC_NST_DECL,
395     OCTI_SELF_ID,
396     OCTI_UCMD_ID,
397     OCTI_UNUSED_LIST,
398     OCTI_SELF_DECL,
399     OCTI_UMSG_DECL,
400     OCTI_UMSG_SUPER_DECL,
401     OCTI_GET_CLASS_DECL,
402     OCTI_GET_MCLASS_DECL,
403     OCTI_SUPER_TYPE,
404     OCTI_SEL_TYPE,
405     OCTI_ID_TYPE,
406     OCTI_CLS_TYPE,
407     OCTI_NST_TYPE,
408     OCTI_PROTO_TYPE,
409
410     OCTI_CLS_CHAIN,
411     OCTI_ALIAS_CHAIN,
412     OCTI_INTF_CHAIN,
413     OCTI_PROTO_CHAIN,
414     OCTI_CLS_REF_CHAIN,
415     OCTI_SEL_REF_CHAIN,
416     OCTI_CLS_NAMES_CHAIN,
417     OCTI_METH_VAR_NAMES_CHAIN,
418     OCTI_METH_VAR_TYPES_CHAIN,
419
420     OCTI_SYMBOLS_DECL,
421     OCTI_NST_VAR_DECL,
422     OCTI_CLS_VAR_DECL,
423     OCTI_NST_METH_DECL,
424     OCTI_CLS_METH_DECL,
425     OCTI_CLS_DECL,
426     OCTI_MCLS_DECL,
427     OCTI_SEL_TABLE_DECL,
428     OCTI_MODULES_DECL,
429     OCTI_STRG_DECL,
430
431     OCTI_IMPL_CTX,
432     OCTI_IMPL_TEMPL,
433
434     OCTI_CLS_TEMPL,
435     OCTI_CAT_TEMPL,
436     OCTI_UPRIV_REC,
437     OCTI_PROTO_TEMPL,
438     OCTI_SEL_TEMPL,
439     OCTI_UCLS_SUPER_REF,
440     OCTI_UUCLS_SUPER_REF,
441     OCTI_METH_TEMPL,
442     OCTI_IVAR_TEMPL,
443     OCTI_SYMTAB_TEMPL,
444     OCTI_MODULE_TEMPL,
445     OCTI_SUPER_TEMPL,
446     OCTI_OBJ_REF,
447     OCTI_OBJ_ID,
448     OCTI_CLS_ID,
449     OCTI_ID_ID,
450     OCTI_CNST_STR_ID,
451     OCTI_CNST_STR_TYPE,
452     OCTI_SUPER_DECL,
453     OCTI_METH_CTX,
454
455     OCTI_MAX
456 };
457
458 static tree objc_global_trees[OCTI_MAX];
459
460 /* List of classes with list of their static instances.  */
461 #define objc_static_instances   objc_global_trees[OCTI_STATIC_NST]
462
463 /* The declaration of the array administrating the static instances.  */
464 #define static_instances_decl   objc_global_trees[OCTI_STATIC_NST_DECL]
465
466 /* Some commonly used instances of "identifier_node".  */
467
468 #define self_id                 objc_global_trees[OCTI_SELF_ID]
469 #define ucmd_id                 objc_global_trees[OCTI_UCMD_ID]
470 #define unused_list             objc_global_trees[OCTI_UNUSED_LIST]
471
472 #define self_decl               objc_global_trees[OCTI_SELF_DECL]
473 #define umsg_decl               objc_global_trees[OCTI_UMSG_DECL]
474 #define umsg_super_decl         objc_global_trees[OCTI_UMSG_SUPER_DECL]
475 #define objc_get_class_decl     objc_global_trees[OCTI_GET_CLASS_DECL]
476 #define objc_get_meta_class_decl                        \
477                                 objc_global_trees[OCTI_GET_MCLASS_DECL]
478
479 #define super_type              objc_global_trees[OCTI_SUPER_TYPE]
480 #define selector_type           objc_global_trees[OCTI_SEL_TYPE]
481 #define id_type                 objc_global_trees[OCTI_ID_TYPE]
482 #define objc_class_type         objc_global_trees[OCTI_CLS_TYPE]
483 #define instance_type           objc_global_trees[OCTI_NST_TYPE]
484 #define protocol_type           objc_global_trees[OCTI_PROTO_TYPE]
485
486 /* Type checking macros.  */
487
488 #define IS_ID(TYPE) \
489   (TYPE_MAIN_VARIANT (TYPE) == TYPE_MAIN_VARIANT (id_type))
490 #define IS_PROTOCOL_QUALIFIED_ID(TYPE) \
491   (IS_ID (TYPE) && TYPE_PROTOCOL_LIST (TYPE))
492 #define IS_SUPER(TYPE) \
493   (super_type && TYPE_MAIN_VARIANT (TYPE) == TYPE_MAIN_VARIANT (super_type))
494
495 #define class_chain             objc_global_trees[OCTI_CLS_CHAIN]
496 #define alias_chain             objc_global_trees[OCTI_ALIAS_CHAIN]
497 #define interface_chain         objc_global_trees[OCTI_INTF_CHAIN]
498 #define protocol_chain          objc_global_trees[OCTI_PROTO_CHAIN]
499
500 /* Chains to manage selectors that are referenced and defined in the
501    module.  */
502
503 #define cls_ref_chain           objc_global_trees[OCTI_CLS_REF_CHAIN]   /* Classes referenced.  */
504 #define sel_ref_chain           objc_global_trees[OCTI_SEL_REF_CHAIN]   /* Selectors referenced.  */
505
506 /* Chains to manage uniquing of strings.  */
507
508 #define class_names_chain       objc_global_trees[OCTI_CLS_NAMES_CHAIN]
509 #define meth_var_names_chain    objc_global_trees[OCTI_METH_VAR_NAMES_CHAIN]
510 #define meth_var_types_chain    objc_global_trees[OCTI_METH_VAR_TYPES_CHAIN]
511
512 /* Hash tables to manage the global pool of method prototypes.  */
513
514 static hash *nst_method_hash_list = 0;
515 static hash *cls_method_hash_list = 0;
516
517 /* Backend data declarations.  */
518
519 #define UOBJC_SYMBOLS_decl              objc_global_trees[OCTI_SYMBOLS_DECL]
520 #define UOBJC_INSTANCE_VARIABLES_decl   objc_global_trees[OCTI_NST_VAR_DECL]
521 #define UOBJC_CLASS_VARIABLES_decl      objc_global_trees[OCTI_CLS_VAR_DECL]
522 #define UOBJC_INSTANCE_METHODS_decl     objc_global_trees[OCTI_NST_METH_DECL]
523 #define UOBJC_CLASS_METHODS_decl        objc_global_trees[OCTI_CLS_METH_DECL]
524 #define UOBJC_CLASS_decl                objc_global_trees[OCTI_CLS_DECL]
525 #define UOBJC_METACLASS_decl            objc_global_trees[OCTI_MCLS_DECL]
526 #define UOBJC_SELECTOR_TABLE_decl       objc_global_trees[OCTI_SEL_TABLE_DECL]
527 #define UOBJC_MODULES_decl              objc_global_trees[OCTI_MODULES_DECL]
528 #define UOBJC_STRINGS_decl              objc_global_trees[OCTI_STRG_DECL]
529
530 /* The following are used when compiling a class implementation.
531    implementation_template will normally be an interface, however if
532    none exists this will be equal to implementation_context...it is
533    set in start_class.  */
534
535 #define implementation_context          objc_global_trees[OCTI_IMPL_CTX]
536 #define implementation_template         objc_global_trees[OCTI_IMPL_TEMPL]
537
538 struct imp_entry
539 {
540   struct imp_entry *next;
541   tree imp_context;
542   tree imp_template;
543   tree class_decl;              /* _OBJC_CLASS_<my_name>; */
544   tree meta_decl;               /* _OBJC_METACLASS_<my_name>; */
545 };
546
547 static void handle_impent                       PARAMS ((struct imp_entry *));
548
549 static struct imp_entry *imp_list = 0;
550 static int imp_count = 0;       /* `@implementation' */
551 static int cat_count = 0;       /* `@category' */
552
553 #define objc_class_template     objc_global_trees[OCTI_CLS_TEMPL]
554 #define objc_category_template  objc_global_trees[OCTI_CAT_TEMPL]
555 #define uprivate_record         objc_global_trees[OCTI_UPRIV_REC]
556 #define objc_protocol_template  objc_global_trees[OCTI_PROTO_TEMPL]
557 #define objc_selector_template  objc_global_trees[OCTI_SEL_TEMPL]
558 #define ucls_super_ref          objc_global_trees[OCTI_UCLS_SUPER_REF]
559 #define uucls_super_ref         objc_global_trees[OCTI_UUCLS_SUPER_REF]
560
561 #define objc_method_template    objc_global_trees[OCTI_METH_TEMPL]
562 #define objc_ivar_template      objc_global_trees[OCTI_IVAR_TEMPL]
563 #define objc_symtab_template    objc_global_trees[OCTI_SYMTAB_TEMPL]
564 #define objc_module_template    objc_global_trees[OCTI_MODULE_TEMPL]
565 #define objc_super_template     objc_global_trees[OCTI_SUPER_TEMPL]
566 #define objc_object_reference   objc_global_trees[OCTI_OBJ_REF]
567
568 #define objc_object_id          objc_global_trees[OCTI_OBJ_ID]
569 #define objc_class_id           objc_global_trees[OCTI_CLS_ID]
570 #define objc_id_id              objc_global_trees[OCTI_ID_ID]
571 #define constant_string_id      objc_global_trees[OCTI_CNST_STR_ID]
572 #define constant_string_type    objc_global_trees[OCTI_CNST_STR_TYPE]
573 #define UOBJC_SUPER_decl        objc_global_trees[OCTI_SUPER_DECL]
574
575 #define method_context          objc_global_trees[OCTI_METH_CTX]
576 static int  method_slot = 0;    /* Used by start_method_def, */
577
578 #define BUFSIZE         1024
579
580 static char *errbuf;    /* Buffer for error diagnostics */
581
582 /* Data imported from tree.c.  */
583
584 extern enum debug_info_type write_symbols;
585
586 /* Data imported from toplev.c.  */
587
588 extern const char *dump_base_name;
589 \f
590 /* Generate code for GNU or NeXT runtime environment.  */
591
592 #ifdef NEXT_OBJC_RUNTIME
593 int flag_next_runtime = 1;
594 #else
595 int flag_next_runtime = 0;
596 #endif
597
598 int flag_typed_selectors;
599
600 /* Open and close the file for outputting class declarations, if requested.  */
601
602 int flag_gen_declaration = 0;
603
604 FILE *gen_declaration_file;
605
606 /* Warn if multiple methods are seen for the same selector, but with
607    different argument types.  */
608
609 int warn_selector = 0;
610
611 /* Warn if methods required by a protocol are not implemented in the 
612    class adopting it.  When turned off, methods inherited to that
613    class are also considered implemented */
614
615 int flag_warn_protocol = 1;
616
617 /* Tells "encode_pointer/encode_aggregate" whether we are generating
618    type descriptors for instance variables (as opposed to methods).
619    Type descriptors for instance variables contain more information
620    than methods (for static typing and embedded structures). This
621    was added to support features being planned for dbkit2.  */
622
623 static int generating_instance_variables = 0;
624
625 /* Tells the compiler that this is a special run.  Do not perform
626    any compiling, instead we are to test some platform dependent
627    features and output a C header file with appropriate definitions. */
628
629 static int print_struct_values = 0;
630
631 /* Some platforms pass small structures through registers versus through
632    an invisible pointer.  Determine at what size structure is the 
633    transition point between the two possibilities. */
634
635 static void
636 generate_struct_by_value_array ()
637 {
638   tree type;
639   tree field_decl, field_decl_chain;
640   int i, j;
641   int aggregate_in_mem[32];
642   int found = 0;
643
644   /* Presumbaly no platform passes 32 byte structures in a register. */
645   for (i = 1; i < 32; i++)
646     {
647       char buffer[5];
648
649       /* Create an unnamed struct that has `i' character components */
650       type = start_struct (RECORD_TYPE, NULL_TREE);
651
652       strcpy (buffer, "c1");
653       field_decl = create_builtin_decl (FIELD_DECL,
654                                         char_type_node,
655                                         buffer);
656       field_decl_chain = field_decl;
657
658       for (j = 1; j < i; j++)
659         {
660           sprintf (buffer, "c%d", j + 1);
661           field_decl = create_builtin_decl (FIELD_DECL,
662                                             char_type_node,
663                                             buffer);
664           chainon (field_decl_chain, field_decl);
665         }
666       finish_struct (type, field_decl_chain, NULL_TREE);
667  
668       aggregate_in_mem[i] = aggregate_value_p (type);
669       if (!aggregate_in_mem[i])
670         found = 1;
671     }
672  
673   /* We found some structures that are returned in registers instead of memory
674      so output the necessary data. */
675   if (found)
676     {
677       for (i = 31; i >= 0;  i--)
678         if (!aggregate_in_mem[i])
679           break;
680       printf ("#define OBJC_MAX_STRUCT_BY_VALUE %d\n\n", i);
681  
682       /* The first member of the structure is always 0 because we don't handle
683          structures with 0 members */
684       printf ("static int struct_forward_array[] = {\n  0");
685  
686       for (j = 1; j <= i; j++)
687         printf (", %d", aggregate_in_mem[j]);
688       printf ("\n};\n");
689     }
690  
691   exit (0);
692 }
693
694 void
695 lang_init_options ()
696 {
697   parse_in = cpp_create_reader (CLK_OBJC);
698   c_language = clk_objective_c;
699 }
700
701 void
702 lang_init ()
703 {
704   /* Force the line number back to 0; check_newline will have
705      raised it to 1, which will make the builtin functions appear
706      not to be built in.  */
707   lineno = 0;
708
709   /* If gen_declaration desired, open the output file.  */
710   if (flag_gen_declaration)
711     {
712       register char * const dumpname = concat (dumpname, ".decl", NULL);
713       gen_declaration_file = fopen (dumpname, "w");
714       if (gen_declaration_file == 0)
715         pfatal_with_name (dumpname);
716       free (dumpname);
717     }
718
719   if (flag_next_runtime)
720     {
721       TAG_GETCLASS = "objc_getClass";
722       TAG_GETMETACLASS = "objc_getMetaClass";
723       TAG_MSGSEND = "objc_msgSend";
724       TAG_MSGSENDSUPER = "objc_msgSendSuper";
725       TAG_EXECCLASS = "__objc_execClass";
726     }
727   else
728     {
729       TAG_GETCLASS = "objc_get_class";
730       TAG_GETMETACLASS = "objc_get_meta_class";
731       TAG_MSGSEND = "objc_msg_lookup";
732       TAG_MSGSENDSUPER = "objc_msg_lookup_super";
733       TAG_EXECCLASS = "__objc_exec_class";
734       flag_typed_selectors = 1;
735     }
736
737   objc_ellipsis_node = make_node (ERROR_MARK);
738
739   if (doing_objc_thang)
740     init_objc ();
741
742   if (print_struct_values)
743     generate_struct_by_value_array ();
744
745   objc_act_parse_init ();
746   c_parse_init ();
747 }
748
749 static void
750 objc_fatal ()
751 {
752   fatal ("Objective-C text in C source file");
753 }
754
755 void
756 finish_file ()
757 {
758   if (doing_objc_thang)
759     finish_objc ();             /* Objective-C finalization */
760
761   if (gen_declaration_file)
762     fclose (gen_declaration_file);
763 }
764
765 void
766 lang_finish ()
767 {
768 }
769
770 const char *
771 lang_identify ()
772 {
773   return "objc";
774 }
775
776 int
777 lang_decode_option (argc, argv)
778      int argc;
779      char **argv;
780 {
781   const char *p = argv[0];
782
783   if (!strcmp (p, "-gen-decls"))
784     flag_gen_declaration = 1;
785   else if (!strcmp (p, "-Wselector"))
786     warn_selector = 1;
787   else if (!strcmp (p, "-Wno-selector"))
788     warn_selector = 0;
789   else if (!strcmp (p, "-Wprotocol"))
790     flag_warn_protocol = 1;
791   else if (!strcmp (p, "-Wno-protocol"))
792     flag_warn_protocol = 0;
793   else if (!strcmp (p, "-fgnu-runtime"))
794     flag_next_runtime = 0;
795   else if (!strcmp (p, "-fno-next-runtime"))
796     flag_next_runtime = 0;
797   else if (!strcmp (p, "-fno-gnu-runtime"))
798     flag_next_runtime = 1;
799   else if (!strcmp (p, "-fnext-runtime"))
800     flag_next_runtime = 1;
801   else if (!strcmp (p, "-print-objc-runtime-info"))
802     print_struct_values = 1;
803 #define CSTSTRCLASS "-fconstant-string-class="
804   else if (!strncmp (p, CSTSTRCLASS, sizeof(CSTSTRCLASS) - 2)) {
805     if (strlen (argv[0]) <= strlen (CSTSTRCLASS))
806       error ("no class name specified as argument to -fconstant-string-class");
807     constant_string_class_name = xstrdup(argv[0] + sizeof(CSTSTRCLASS) - 1);
808   }
809 #undef CSTSTRCLASS
810   else
811     return c_decode_option (argc, argv);
812
813   return 1;
814 }
815
816 /* used by print-tree.c */
817
818 void
819 lang_print_xnode (file, node, indent)
820      FILE *file ATTRIBUTE_UNUSED;
821      tree node ATTRIBUTE_UNUSED;
822      int indent ATTRIBUTE_UNUSED;
823 {
824 }
825
826 \f
827 static tree
828 define_decl (declarator, declspecs)
829      tree declarator;
830      tree declspecs;
831 {
832   tree decl = start_decl (declarator, declspecs, 0, NULL_TREE, NULL_TREE);
833   finish_decl (decl, NULL_TREE, NULL_TREE);
834   return decl;
835 }
836
837 /* Return 1 if LHS and RHS are compatible types for assignment or
838    various other operations.  Return 0 if they are incompatible, and
839    return -1 if we choose to not decide.  When the operation is
840    REFLEXIVE, check for compatibility in either direction.
841
842    For statically typed objects, an assignment of the form `a' = `b'
843    is permitted if:
844
845    `a' is of type "id",
846    `a' and `b' are the same class type, or
847    `a' and `b' are of class types A and B such that B is a descendant of A.  */
848
849 int
850 maybe_objc_comptypes (lhs, rhs, reflexive)
851      tree lhs, rhs;
852      int reflexive;
853 {
854   if (doing_objc_thang)
855     return objc_comptypes (lhs, rhs, reflexive);
856   return -1;
857 }
858
859 static tree
860 lookup_method_in_protocol_list (rproto_list, sel_name, class_meth)
861    tree rproto_list;
862    tree sel_name;
863    int class_meth;
864 {
865    tree rproto, p;
866    tree fnd = 0;
867
868    for (rproto = rproto_list; rproto; rproto = TREE_CHAIN (rproto))
869      {
870         p = TREE_VALUE (rproto);
871
872         if (TREE_CODE (p) == PROTOCOL_INTERFACE_TYPE)
873           {
874             if ((fnd = lookup_method (class_meth
875                                       ? PROTOCOL_CLS_METHODS (p)
876                                       : PROTOCOL_NST_METHODS (p), sel_name)))
877               ;
878             else if (PROTOCOL_LIST (p))
879               fnd = lookup_method_in_protocol_list (PROTOCOL_LIST (p),
880                                                     sel_name, class_meth);
881           }
882         else
883           {
884             ; /* An identifier...if we could not find a protocol.  */
885           }
886
887         if (fnd)
888           return fnd;
889      }
890
891    return 0;
892 }
893
894 static tree
895 lookup_protocol_in_reflist (rproto_list, lproto)
896    tree rproto_list;
897    tree lproto;
898 {
899    tree rproto, p;
900
901    /* Make sure the protocol is support by the object on the rhs.  */
902    if (TREE_CODE (lproto) == PROTOCOL_INTERFACE_TYPE)
903      {
904        tree fnd = 0;
905        for (rproto = rproto_list; rproto; rproto = TREE_CHAIN (rproto))
906          {
907            p = TREE_VALUE (rproto);
908
909            if (TREE_CODE (p) == PROTOCOL_INTERFACE_TYPE)
910              {
911                if (lproto == p)
912                  fnd = lproto;
913
914                else if (PROTOCOL_LIST (p))
915                  fnd = lookup_protocol_in_reflist (PROTOCOL_LIST (p), lproto);
916              }
917
918            if (fnd)
919              return fnd;
920          }
921      }
922    else
923      {
924        ; /* An identifier...if we could not find a protocol.  */
925      }
926
927    return 0;
928 }
929
930 /* Return 1 if LHS and RHS are compatible types for assignment
931    or various other operations.  Return 0 if they are incompatible,
932    and return -1 if we choose to not decide.  When the operation
933    is REFLEXIVE, check for compatibility in either direction.  */
934
935 int
936 objc_comptypes (lhs, rhs, reflexive)
937      tree lhs;
938      tree rhs;
939      int reflexive;
940 {
941   /* New clause for protocols.  */
942
943   if (TREE_CODE (lhs) == POINTER_TYPE
944       && TREE_CODE (TREE_TYPE (lhs)) == RECORD_TYPE
945       && TREE_CODE (rhs) == POINTER_TYPE
946       && TREE_CODE (TREE_TYPE (rhs)) == RECORD_TYPE)
947     {
948       int lhs_is_proto = IS_PROTOCOL_QUALIFIED_ID (lhs);
949       int rhs_is_proto = IS_PROTOCOL_QUALIFIED_ID (rhs);
950
951       if (lhs_is_proto)
952         {
953           tree lproto, lproto_list = TYPE_PROTOCOL_LIST (lhs);
954           tree rproto, rproto_list;
955           tree p;
956
957           if (rhs_is_proto)
958             {
959               rproto_list = TYPE_PROTOCOL_LIST (rhs);
960
961               /* Make sure the protocol is supported by the object
962                  on the rhs.  */
963               for (lproto = lproto_list; lproto; lproto = TREE_CHAIN (lproto))
964                 {
965                   p = TREE_VALUE (lproto);
966                   rproto = lookup_protocol_in_reflist (rproto_list, p);
967
968                   if (!rproto)
969                     warning ("object does not conform to the `%s' protocol",
970                              IDENTIFIER_POINTER (PROTOCOL_NAME (p)));
971                 }
972             }
973           else if (TYPED_OBJECT (TREE_TYPE (rhs)))
974             {
975               tree rname = TYPE_NAME (TREE_TYPE (rhs));
976               tree rinter;
977
978               /* Make sure the protocol is supported by the object
979                  on the rhs.  */
980               for (lproto = lproto_list; lproto; lproto = TREE_CHAIN (lproto))
981                 {
982                   p = TREE_VALUE (lproto);
983                   rproto = 0;
984                   rinter = lookup_interface (rname);
985
986                   while (rinter && !rproto)
987                     {
988                       tree cat;
989
990                       rproto_list = CLASS_PROTOCOL_LIST (rinter);
991                       rproto = lookup_protocol_in_reflist (rproto_list, p);
992
993                       /* Check for protocols adopted by categories.  */
994                       cat = CLASS_CATEGORY_LIST (rinter);
995                       while (cat && !rproto)
996                         {
997                           rproto_list = CLASS_PROTOCOL_LIST (cat);
998                           rproto = lookup_protocol_in_reflist (rproto_list, p);
999
1000                           cat = CLASS_CATEGORY_LIST (cat);
1001                         }
1002
1003                       rinter = lookup_interface (CLASS_SUPER_NAME (rinter));
1004                     }
1005
1006                   if (!rproto)
1007                     warning ("class `%s' does not implement the `%s' protocol",
1008                              IDENTIFIER_POINTER (TYPE_NAME (TREE_TYPE (rhs))),
1009                              IDENTIFIER_POINTER (PROTOCOL_NAME (p)));
1010                 }
1011             }
1012
1013           /* May change...based on whether there was any mismatch */
1014           return 1;
1015         }
1016       else if (rhs_is_proto)
1017         /* Lhs is not a protocol...warn if it is statically typed */
1018         return (TYPED_OBJECT (TREE_TYPE (lhs)) != 0);
1019
1020       else
1021         /* Defer to comptypes .*/
1022         return -1;
1023     }
1024
1025   else if (TREE_CODE (lhs) == RECORD_TYPE && TREE_CODE (rhs) == RECORD_TYPE)
1026     ; /* Fall thru.  This is the case we have been handling all along */
1027   else
1028     /* Defer to comptypes.  */
1029     return -1;
1030
1031   /* `id' = `<class> *', `<class> *' = `id' */
1032
1033   if ((TYPE_NAME (lhs) == objc_object_id && TYPED_OBJECT (rhs))
1034       || (TYPE_NAME (rhs) == objc_object_id && TYPED_OBJECT (lhs)))
1035     return 1;
1036
1037   /* `id' = `Class', `Class' = `id' */
1038
1039   else if ((TYPE_NAME (lhs) == objc_object_id
1040             && TYPE_NAME (rhs) == objc_class_id)
1041            || (TYPE_NAME (lhs) == objc_class_id
1042                && TYPE_NAME (rhs) == objc_object_id))
1043     return 1;
1044
1045   /* `<class> *' = `<class> *' */
1046
1047   else if (TYPED_OBJECT (lhs) && TYPED_OBJECT (rhs))
1048     {
1049       tree lname = TYPE_NAME (lhs);
1050       tree rname = TYPE_NAME (rhs);
1051       tree inter;
1052
1053       if (lname == rname)
1054         return 1;
1055
1056       /* If the left hand side is a super class of the right hand side,
1057          allow it.  */
1058       for (inter = lookup_interface (rname); inter;
1059            inter = lookup_interface (CLASS_SUPER_NAME (inter)))
1060         if (lname == CLASS_SUPER_NAME (inter))
1061           return 1;
1062
1063       /* Allow the reverse when reflexive.  */
1064       if (reflexive)
1065         for (inter = lookup_interface (lname); inter;
1066              inter = lookup_interface (CLASS_SUPER_NAME (inter)))
1067           if (rname == CLASS_SUPER_NAME (inter))
1068             return 1;
1069
1070       return 0;
1071     }
1072   else
1073     /* Defer to comptypes.  */
1074     return -1;
1075 }
1076
1077 /* Called from c-decl.c before all calls to rest_of_decl_compilation.  */
1078
1079 void
1080 objc_check_decl (decl)
1081      tree decl;
1082 {
1083   tree type = TREE_TYPE (decl);
1084
1085   if (TREE_CODE (type) == RECORD_TYPE
1086       && TREE_STATIC_TEMPLATE (type)
1087       && type != constant_string_type)
1088     {
1089       error_with_decl (decl, "`%s' cannot be statically allocated");
1090       fatal ("statically allocated objects not supported");
1091     }
1092 }
1093
1094 void
1095 maybe_objc_check_decl (decl)
1096      tree decl;
1097 {
1098   if (doing_objc_thang)
1099     objc_check_decl (decl);
1100 }
1101
1102 /* Implement static typing.  At this point, we know we have an interface.  */
1103
1104 tree
1105 get_static_reference (interface, protocols)
1106      tree interface;
1107      tree protocols;
1108 {
1109   tree type = xref_tag (RECORD_TYPE, interface);
1110
1111   if (protocols)
1112     {
1113       tree t, m = TYPE_MAIN_VARIANT (type);
1114
1115       t = copy_node (type);
1116       TYPE_BINFO (t) = make_tree_vec (2);
1117
1118       /* Add this type to the chain of variants of TYPE.  */
1119       TYPE_NEXT_VARIANT (t) = TYPE_NEXT_VARIANT (m);
1120       TYPE_NEXT_VARIANT (m) = t;
1121
1122       /* Look up protocols and install in lang specific list.  */
1123       TYPE_PROTOCOL_LIST (t) = lookup_and_install_protocols (protocols);
1124
1125       /* This forces a new pointer type to be created later
1126          (in build_pointer_type)...so that the new template
1127          we just created will actually be used...what a hack!  */
1128       if (TYPE_POINTER_TO (t))
1129         TYPE_POINTER_TO (t) = 0;
1130
1131       type = t;
1132     }
1133
1134   return type;
1135 }
1136
1137 tree
1138 get_object_reference (protocols)
1139      tree protocols;
1140 {
1141   tree type_decl = lookup_name (objc_id_id);
1142   tree type;
1143
1144   if (type_decl && TREE_CODE (type_decl) == TYPE_DECL)
1145     {
1146       type = TREE_TYPE (type_decl);
1147       if (TYPE_MAIN_VARIANT (type) != id_type)
1148         warning ("Unexpected type for `id' (%s)",
1149                 gen_declaration (type, errbuf));
1150     }
1151   else
1152     fatal ("Undefined type `id', please import <objc/objc.h>");
1153
1154   /* This clause creates a new pointer type that is qualified with
1155      the protocol specification...this info is used later to do more
1156      elaborate type checking.  */
1157
1158   if (protocols)
1159     {
1160       tree t, m = TYPE_MAIN_VARIANT (type);
1161
1162       t = copy_node (type);
1163       TYPE_BINFO (t) = make_tree_vec (2);
1164
1165       /* Add this type to the chain of variants of TYPE.  */
1166       TYPE_NEXT_VARIANT (t) = TYPE_NEXT_VARIANT (m);
1167       TYPE_NEXT_VARIANT (m) = t;
1168
1169       /* Look up protocols...and install in lang specific list */
1170       TYPE_PROTOCOL_LIST (t) = lookup_and_install_protocols (protocols);
1171
1172       /* This forces a new pointer type to be created later
1173          (in build_pointer_type)...so that the new template
1174          we just created will actually be used...what a hack!  */
1175       if (TYPE_POINTER_TO (t))
1176         TYPE_POINTER_TO (t) = NULL;
1177
1178       type = t;
1179     }
1180   return type;
1181 }
1182
1183 static tree
1184 lookup_and_install_protocols (protocols)
1185      tree protocols;
1186 {
1187   tree proto;
1188   tree prev = NULL;
1189   tree return_value = protocols;
1190
1191   for (proto = protocols; proto; proto = TREE_CHAIN (proto))
1192     {
1193       tree ident = TREE_VALUE (proto);
1194       tree p = lookup_protocol (ident);
1195
1196       if (!p)
1197         {
1198           error ("Cannot find protocol declaration for `%s'",
1199                  IDENTIFIER_POINTER (ident));
1200           if (prev)
1201             TREE_CHAIN (prev) = TREE_CHAIN (proto);
1202           else
1203             return_value = TREE_CHAIN (proto);
1204         }
1205       else
1206         {
1207           /* Replace identifier with actual protocol node.  */
1208           TREE_VALUE (proto) = p;
1209           prev = proto;
1210         }
1211     }
1212
1213   return return_value;
1214 }
1215
1216 /* Create and push a decl for a built-in external variable or field NAME.
1217    CODE says which.
1218    TYPE is its data type.  */
1219
1220 static tree
1221 create_builtin_decl (code, type, name)
1222      enum tree_code code;
1223      tree type;
1224      const char *name;
1225 {
1226   tree decl = build_decl (code, get_identifier (name), type);
1227
1228   if (code == VAR_DECL)
1229     {
1230       TREE_STATIC (decl) = 1;
1231       make_decl_rtl (decl, 0, 1);
1232       pushdecl (decl);
1233     }
1234
1235   DECL_ARTIFICIAL (decl) = 1;
1236   return decl;
1237 }
1238
1239 /* Purpose: "play" parser, creating/installing representations
1240    of the declarations that are required by Objective-C.
1241
1242    Model:
1243
1244         type_spec--------->sc_spec
1245         (tree_list)        (tree_list)
1246             |                  |
1247             |                  |
1248         identifier_node    identifier_node  */
1249
1250 static void
1251 synth_module_prologue ()
1252 {
1253   tree temp_type;
1254   tree super_p;
1255
1256   /* Defined in `objc.h' */
1257   objc_object_id = get_identifier (TAG_OBJECT);
1258
1259   objc_object_reference = xref_tag (RECORD_TYPE, objc_object_id);
1260
1261   id_type = build_pointer_type (objc_object_reference);
1262
1263   objc_id_id = get_identifier (TYPE_ID);
1264   objc_class_id = get_identifier (TAG_CLASS);
1265
1266   objc_class_type = build_pointer_type (xref_tag (RECORD_TYPE, objc_class_id));
1267   protocol_type = build_pointer_type (xref_tag (RECORD_TYPE,
1268                                 get_identifier (PROTOCOL_OBJECT_CLASS_NAME)));
1269
1270   /* Declare type of selector-objects that represent an operation name.  */
1271
1272 #ifdef OBJC_INT_SELECTORS
1273   /* `unsigned int' */
1274   selector_type = unsigned_type_node;
1275 #else
1276   /* `struct objc_selector *' */
1277   selector_type
1278     = build_pointer_type (xref_tag (RECORD_TYPE,
1279                                     get_identifier (TAG_SELECTOR)));
1280 #endif /* not OBJC_INT_SELECTORS */
1281
1282   /* Forward declare type, or else the prototype for msgSendSuper will
1283      complain.  */
1284
1285   super_p = build_pointer_type (xref_tag (RECORD_TYPE,
1286                                           get_identifier (TAG_SUPER)));
1287
1288
1289   /* id objc_msgSend (id, SEL, ...); */
1290
1291   temp_type
1292     = build_function_type (id_type,
1293                            tree_cons (NULL_TREE, id_type,
1294                                       tree_cons (NULL_TREE, selector_type,
1295                                                  NULL_TREE)));
1296
1297   if (! flag_next_runtime)
1298     {
1299       umsg_decl = build_decl (FUNCTION_DECL,
1300                               get_identifier (TAG_MSGSEND), temp_type);
1301       DECL_EXTERNAL (umsg_decl) = 1;
1302       TREE_PUBLIC (umsg_decl) = 1;
1303       DECL_INLINE (umsg_decl) = 1;
1304       DECL_ARTIFICIAL (umsg_decl) = 1;
1305
1306       if (flag_traditional && TAG_MSGSEND[0] != '_')
1307         DECL_BUILT_IN_NONANSI (umsg_decl) = 1;
1308
1309       make_decl_rtl (umsg_decl, NULL_PTR, 1);
1310       pushdecl (umsg_decl);
1311     }
1312   else
1313     umsg_decl = builtin_function (TAG_MSGSEND, temp_type, 0, NOT_BUILT_IN, 0);
1314
1315   /* id objc_msgSendSuper (struct objc_super *, SEL, ...); */
1316
1317   temp_type
1318     = build_function_type (id_type,
1319                            tree_cons (NULL_TREE, super_p,
1320                                       tree_cons (NULL_TREE, selector_type,
1321                                                  NULL_TREE)));
1322
1323   umsg_super_decl = builtin_function (TAG_MSGSENDSUPER,
1324                                      temp_type, 0, NOT_BUILT_IN, 0);
1325
1326   /* id objc_getClass (const char *); */
1327
1328   temp_type = build_function_type (id_type,
1329                         tree_cons (NULL_TREE,
1330                                    const_string_type_node,
1331                                    tree_cons (NULL_TREE, void_type_node,
1332                                               NULL_TREE)));
1333
1334   objc_get_class_decl
1335     = builtin_function (TAG_GETCLASS, temp_type, 0, NOT_BUILT_IN, 0);
1336
1337   /* id objc_getMetaClass (const char *); */
1338
1339   objc_get_meta_class_decl
1340     = builtin_function (TAG_GETMETACLASS, temp_type, 0, NOT_BUILT_IN, 0);
1341
1342   /* static SEL _OBJC_SELECTOR_TABLE[]; */
1343
1344   if (! flag_next_runtime)
1345     {
1346       if (flag_typed_selectors)
1347         {
1348           /* Suppress outputting debug symbols, because
1349              dbxout_init hasn'r been called yet.  */
1350           enum debug_info_type save_write_symbols = write_symbols;
1351           write_symbols = NO_DEBUG;
1352
1353           build_selector_template ();
1354           temp_type = build_array_type (objc_selector_template, NULL_TREE);
1355
1356           write_symbols = save_write_symbols;
1357         }
1358       else
1359         temp_type = build_array_type (selector_type, NULL_TREE);
1360
1361       layout_type (temp_type);
1362       UOBJC_SELECTOR_TABLE_decl
1363         = create_builtin_decl (VAR_DECL, temp_type,
1364                                "_OBJC_SELECTOR_TABLE");
1365
1366       /* Avoid warning when not sending messages.  */
1367       TREE_USED (UOBJC_SELECTOR_TABLE_decl) = 1;
1368     }
1369
1370   generate_forward_declaration_to_string_table ();
1371
1372   /* Forward declare constant_string_id and constant_string_type.  */
1373   if (!constant_string_class_name)
1374     constant_string_class_name = STRING_OBJECT_CLASS_NAME;
1375   
1376   constant_string_id = get_identifier (constant_string_class_name);
1377   constant_string_type = xref_tag (RECORD_TYPE, constant_string_id);
1378 }
1379
1380 /* Custom build_string which sets TREE_TYPE!  */
1381
1382 static tree
1383 my_build_string (len, str)
1384      int len;
1385      const char *str;
1386 {
1387   int wide_flag = 0;
1388   tree a_string = build_string (len, str);
1389
1390   /* Some code from combine_strings, which is local to c-parse.y.  */
1391   if (TREE_TYPE (a_string) == int_array_type_node)
1392     wide_flag = 1;
1393
1394   TREE_TYPE (a_string)
1395     = build_array_type (wide_flag ? integer_type_node : char_type_node,
1396                         build_index_type (build_int_2 (len - 1, 0)));
1397
1398   TREE_CONSTANT (a_string) = 1; /* Puts string in the readonly segment */
1399   TREE_STATIC (a_string) = 1;
1400
1401   return a_string;
1402 }
1403
1404 /* Given a chain of STRING_CST's, build a static instance of
1405    NXConstanString which points at the concatenation of those strings.
1406    We place the string object in the __string_objects section of the
1407    __OBJC segment.  The Objective-C runtime will initialize the isa
1408    pointers of the string objects to point at the NXConstandString class
1409    object.  */
1410
1411 tree
1412 build_objc_string_object (strings)
1413      tree strings;
1414 {
1415   tree string, initlist, constructor;
1416   int length;
1417
1418   if (!doing_objc_thang)
1419     objc_fatal ();
1420
1421   if (lookup_interface (constant_string_id) == NULL_TREE)
1422     {
1423       error ("Cannot find interface declaration for `%s'",
1424              IDENTIFIER_POINTER (constant_string_id));
1425       return error_mark_node;
1426     }
1427
1428   add_class_reference (constant_string_id);
1429
1430   string = combine_strings (strings);
1431   TREE_SET_CODE (string, STRING_CST);
1432   length = TREE_STRING_LENGTH (string) - 1;
1433
1434   /* & ((NXConstantString) {0, string, length})  */
1435
1436   initlist = build_tree_list (NULL_TREE, build_int_2 (0, 0));
1437   initlist
1438     = tree_cons (NULL_TREE, copy_node (build_unary_op (ADDR_EXPR, string, 1)),
1439                  initlist);
1440   initlist = tree_cons (NULL_TREE, build_int_2 (length, 0), initlist);
1441   constructor = build_constructor (constant_string_type, nreverse (initlist));
1442
1443   if (!flag_next_runtime)
1444     {
1445       constructor
1446         = objc_add_static_instance (constructor, constant_string_type);
1447     }
1448
1449   return (build_unary_op (ADDR_EXPR, constructor, 1));
1450 }
1451
1452 /* Declare a static instance of CLASS_DECL initialized by CONSTRUCTOR.  */
1453
1454 static tree
1455 objc_add_static_instance (constructor, class_decl)
1456      tree constructor, class_decl;
1457 {
1458   static int num_static_inst;
1459   tree *chain, decl;
1460   char buf[256];
1461
1462   /* Find the list of static instances for the CLASS_DECL.  Create one if
1463      not found.  */
1464   for (chain = &objc_static_instances;
1465        *chain && TREE_VALUE (*chain) != class_decl;
1466        chain = &TREE_CHAIN (*chain));
1467   if (!*chain)
1468     {
1469       *chain = tree_cons (NULL_TREE, class_decl, NULL_TREE);
1470       add_objc_string (TYPE_NAME (class_decl), class_names);
1471     }
1472
1473   sprintf (buf, "_OBJC_INSTANCE_%d", num_static_inst++);
1474   decl = build_decl (VAR_DECL, get_identifier (buf), class_decl);
1475   DECL_COMMON (decl) = 1;
1476   TREE_STATIC (decl) = 1;
1477   DECL_ARTIFICIAL (decl) = 1;
1478   pushdecl_top_level (decl);
1479   rest_of_decl_compilation (decl, 0, 1, 0);
1480
1481   /* Do this here so it gets output later instead of possibly
1482      inside something else we are writing.  */
1483   DECL_INITIAL (decl) = constructor;
1484
1485   /* Add the DECL to the head of this CLASS' list.  */
1486   TREE_PURPOSE (*chain) = tree_cons (NULL_TREE, decl, TREE_PURPOSE (*chain));
1487
1488   return decl;
1489 }
1490
1491 /* Build a static constant CONSTRUCTOR
1492    with type TYPE and elements ELTS.  */
1493
1494 static tree
1495 build_constructor (type, elts)
1496      tree type, elts;
1497 {
1498   tree constructor = build (CONSTRUCTOR, type, NULL_TREE, elts);
1499
1500   TREE_CONSTANT (constructor) = 1;
1501   TREE_STATIC (constructor) = 1;
1502   TREE_READONLY (constructor) = 1;
1503
1504   return constructor;
1505 }
1506 \f
1507 /* Take care of defining and initializing _OBJC_SYMBOLS.  */
1508
1509 /* Predefine the following data type:
1510
1511    struct _objc_symtab
1512    {
1513      long sel_ref_cnt;
1514      SEL *refs;
1515      short cls_def_cnt;
1516      short cat_def_cnt;
1517      void *defs[cls_def_cnt + cat_def_cnt];
1518    }; */
1519
1520 static void
1521 build_objc_symtab_template ()
1522 {
1523   tree field_decl, field_decl_chain, index;
1524
1525   objc_symtab_template
1526     = start_struct (RECORD_TYPE, get_identifier (UTAG_SYMTAB));
1527
1528   /* long sel_ref_cnt; */
1529
1530   field_decl = create_builtin_decl (FIELD_DECL,
1531                                     long_integer_type_node,
1532                                     "sel_ref_cnt");
1533   field_decl_chain = field_decl;
1534
1535   /* SEL *refs; */
1536
1537   field_decl = create_builtin_decl (FIELD_DECL,
1538                                     build_pointer_type (selector_type),
1539                                     "refs");
1540   chainon (field_decl_chain, field_decl);
1541
1542   /* short cls_def_cnt; */
1543
1544   field_decl = create_builtin_decl (FIELD_DECL,
1545                                     short_integer_type_node,
1546                                     "cls_def_cnt");
1547   chainon (field_decl_chain, field_decl);
1548
1549   /* short cat_def_cnt; */
1550
1551   field_decl = create_builtin_decl (FIELD_DECL,
1552                                     short_integer_type_node,
1553                                     "cat_def_cnt");
1554   chainon (field_decl_chain, field_decl);
1555
1556   /* void *defs[cls_def_cnt + cat_def_cnt]; */
1557
1558   if (!flag_next_runtime)
1559     index = build_index_type (build_int_2 (imp_count + cat_count, 0));
1560   else
1561     index = build_index_type (build_int_2 (imp_count + cat_count - 1,
1562                                            imp_count == 0 && cat_count == 0
1563                                            ? -1 : 0));
1564   field_decl = create_builtin_decl (FIELD_DECL,
1565                                     build_array_type (ptr_type_node, index),
1566                                     "defs");
1567   chainon (field_decl_chain, field_decl);
1568
1569   finish_struct (objc_symtab_template, field_decl_chain, NULL_TREE);
1570 }
1571
1572 /* Create the initial value for the `defs' field of _objc_symtab.
1573    This is a CONSTRUCTOR.  */
1574
1575 static tree
1576 init_def_list (type)
1577      tree type;
1578 {
1579   tree expr, initlist = NULL_TREE;
1580   struct imp_entry *impent;
1581
1582   if (imp_count)
1583     for (impent = imp_list; impent; impent = impent->next)
1584       {
1585         if (TREE_CODE (impent->imp_context) == CLASS_IMPLEMENTATION_TYPE)
1586           {
1587             expr = build_unary_op (ADDR_EXPR, impent->class_decl, 0);
1588             initlist = tree_cons (NULL_TREE, expr, initlist);
1589           }
1590       }
1591
1592   if (cat_count)
1593     for (impent = imp_list; impent; impent = impent->next)
1594       {
1595         if (TREE_CODE (impent->imp_context) == CATEGORY_IMPLEMENTATION_TYPE)
1596           {
1597             expr = build_unary_op (ADDR_EXPR, impent->class_decl, 0);
1598             initlist = tree_cons (NULL_TREE, expr, initlist);
1599           }
1600       }
1601
1602   if (!flag_next_runtime)
1603     {
1604       /* statics = { ..., _OBJC_STATIC_INSTANCES, ... }  */
1605       tree expr;
1606
1607       if (static_instances_decl)
1608         expr = build_unary_op (ADDR_EXPR, static_instances_decl, 0);
1609       else
1610         expr = build_int_2 (0, 0);
1611
1612       initlist = tree_cons (NULL_TREE, expr, initlist);
1613     }
1614
1615   return build_constructor (type, nreverse (initlist));
1616 }
1617
1618 /* Construct the initial value for all of _objc_symtab.  */
1619
1620 static tree
1621 init_objc_symtab (type)
1622      tree type;
1623 {
1624   tree initlist;
1625
1626   /* sel_ref_cnt = { ..., 5, ... } */
1627
1628   initlist = build_tree_list (NULL_TREE, build_int_2 (0, 0));
1629
1630   /* refs = { ..., _OBJC_SELECTOR_TABLE, ... } */
1631
1632   if (flag_next_runtime || ! sel_ref_chain)
1633     initlist = tree_cons (NULL_TREE, build_int_2 (0, 0), initlist);
1634   else
1635     initlist = tree_cons (NULL_TREE,
1636                           build_unary_op (ADDR_EXPR,
1637                                           UOBJC_SELECTOR_TABLE_decl, 1),
1638                           initlist);
1639
1640   /* cls_def_cnt = { ..., 5, ... } */
1641
1642   initlist = tree_cons (NULL_TREE, build_int_2 (imp_count, 0), initlist);
1643
1644   /* cat_def_cnt = { ..., 5, ... } */
1645
1646   initlist = tree_cons (NULL_TREE, build_int_2 (cat_count, 0), initlist);
1647
1648   /* cls_def = { ..., { &Foo, &Bar, ...}, ... } */
1649
1650   if (imp_count || cat_count || static_instances_decl)
1651     {
1652
1653       tree field = TYPE_FIELDS (type);
1654       field = TREE_CHAIN (TREE_CHAIN (TREE_CHAIN (TREE_CHAIN (field))));
1655
1656       initlist = tree_cons (NULL_TREE, init_def_list (TREE_TYPE (field)),
1657                             initlist);
1658     }
1659
1660   return build_constructor (type, nreverse (initlist));
1661 }
1662
1663 /* Push forward-declarations of all the categories
1664    so that init_def_list can use them in a CONSTRUCTOR.  */
1665
1666 static void
1667 forward_declare_categories ()
1668 {
1669   struct imp_entry *impent;
1670   tree sav = implementation_context;
1671
1672   for (impent = imp_list; impent; impent = impent->next)
1673     {
1674       if (TREE_CODE (impent->imp_context) == CATEGORY_IMPLEMENTATION_TYPE)
1675         {
1676           /* Set an invisible arg to synth_id_with_class_suffix.  */
1677           implementation_context = impent->imp_context;
1678           impent->class_decl
1679             = create_builtin_decl (VAR_DECL, objc_category_template,
1680                                    IDENTIFIER_POINTER (synth_id_with_class_suffix ("_OBJC_CATEGORY", implementation_context)));
1681         }
1682     }
1683   implementation_context = sav;
1684 }
1685
1686 /* Create the declaration of _OBJC_SYMBOLS, with type `strict _objc_symtab'
1687    and initialized appropriately.  */
1688
1689 static void
1690 generate_objc_symtab_decl ()
1691 {
1692   tree sc_spec;
1693
1694   if (!objc_category_template)
1695     build_category_template ();
1696
1697   /* forward declare categories */
1698   if (cat_count)
1699     forward_declare_categories ();
1700
1701   if (!objc_symtab_template)
1702     build_objc_symtab_template ();
1703
1704   sc_spec = build_tree_list (NULL_TREE, ridpointers[(int) RID_STATIC]);
1705
1706   UOBJC_SYMBOLS_decl = start_decl (get_identifier ("_OBJC_SYMBOLS"),
1707                                    tree_cons (NULL_TREE,
1708                                               objc_symtab_template, sc_spec),
1709                                    1,
1710                                    NULL_TREE, NULL_TREE);
1711
1712   TREE_USED (UOBJC_SYMBOLS_decl) = 1;
1713   DECL_IGNORED_P (UOBJC_SYMBOLS_decl) = 1;
1714   DECL_ARTIFICIAL (UOBJC_SYMBOLS_decl) = 1;
1715   finish_decl (UOBJC_SYMBOLS_decl,
1716                init_objc_symtab (TREE_TYPE (UOBJC_SYMBOLS_decl)),
1717                NULL_TREE);
1718 }
1719 \f
1720 static tree
1721 init_module_descriptor (type)
1722      tree type;
1723 {
1724   tree initlist, expr;
1725
1726   /* version = { 1, ... } */
1727
1728   expr = build_int_2 (OBJC_VERSION, 0);
1729   initlist = build_tree_list (NULL_TREE, expr);
1730
1731   /* size = { ..., sizeof (struct objc_module), ... } */
1732
1733   expr = size_in_bytes (objc_module_template);
1734   initlist = tree_cons (NULL_TREE, expr, initlist);
1735
1736   /* name = { ..., "foo.m", ... } */
1737
1738   expr = add_objc_string (get_identifier (input_filename), class_names);
1739   initlist = tree_cons (NULL_TREE, expr, initlist);
1740
1741   /* symtab = { ..., _OBJC_SYMBOLS, ... } */
1742
1743   if (UOBJC_SYMBOLS_decl)
1744     expr = build_unary_op (ADDR_EXPR, UOBJC_SYMBOLS_decl, 0);
1745   else
1746     expr = build_int_2 (0, 0);
1747   initlist = tree_cons (NULL_TREE, expr, initlist);
1748
1749   return build_constructor (type, nreverse (initlist));
1750 }
1751
1752 /* Write out the data structures to describe Objective C classes defined.
1753    If appropriate, compile and output a setup function to initialize them.
1754    Return a string which is the name of a function to call to initialize
1755    the Objective C data structures for this file (and perhaps for other files
1756    also).
1757
1758    struct objc_module { ... } _OBJC_MODULE = { ... };   */
1759
1760 static const char *
1761 build_module_descriptor ()
1762 {
1763   tree decl_specs, field_decl, field_decl_chain;
1764
1765   objc_module_template
1766     = start_struct (RECORD_TYPE, get_identifier (UTAG_MODULE));
1767
1768   /* Long version; */
1769
1770   decl_specs = build_tree_list (NULL_TREE, ridpointers[(int) RID_LONG]);
1771   field_decl = get_identifier ("version");
1772   field_decl
1773     = grokfield (input_filename, lineno, field_decl, decl_specs, NULL_TREE);
1774   field_decl_chain = field_decl;
1775
1776   /* long  size; */
1777
1778   decl_specs = build_tree_list (NULL_TREE, ridpointers[(int) RID_LONG]);
1779   field_decl = get_identifier ("size");
1780   field_decl
1781     = grokfield (input_filename, lineno, field_decl, decl_specs, NULL_TREE);
1782   chainon (field_decl_chain, field_decl);
1783
1784   /* char  *name; */
1785
1786   decl_specs = build_tree_list (NULL_TREE, ridpointers[(int) RID_CHAR]);
1787   field_decl = build1 (INDIRECT_REF, NULL_TREE, get_identifier ("name"));
1788   field_decl
1789     = grokfield (input_filename, lineno, field_decl, decl_specs, NULL_TREE);
1790   chainon (field_decl_chain, field_decl);
1791
1792   /* struct objc_symtab *symtab; */
1793
1794   decl_specs = get_identifier (UTAG_SYMTAB);
1795   decl_specs = build_tree_list (NULL_TREE, xref_tag (RECORD_TYPE, decl_specs));
1796   field_decl = build1 (INDIRECT_REF, NULL_TREE, get_identifier ("symtab"));
1797   field_decl
1798     = grokfield (input_filename, lineno, field_decl, decl_specs, NULL_TREE);
1799   chainon (field_decl_chain, field_decl);
1800
1801   finish_struct (objc_module_template, field_decl_chain, NULL_TREE);
1802
1803   /* Create an instance of "objc_module".  */
1804
1805   decl_specs = tree_cons (NULL_TREE, objc_module_template,
1806                           build_tree_list (NULL_TREE,
1807                                            ridpointers[(int) RID_STATIC]));
1808
1809   UOBJC_MODULES_decl = start_decl (get_identifier ("_OBJC_MODULES"),
1810                                    decl_specs, 1, NULL_TREE, NULL_TREE);
1811
1812   DECL_ARTIFICIAL (UOBJC_MODULES_decl) = 1;
1813   DECL_IGNORED_P (UOBJC_MODULES_decl) = 1;
1814   finish_decl (UOBJC_MODULES_decl,
1815                init_module_descriptor (TREE_TYPE (UOBJC_MODULES_decl)),
1816                NULL_TREE);
1817
1818   /* Mark the decl to avoid "defined but not used" warning.  */
1819   DECL_IN_SYSTEM_HEADER (UOBJC_MODULES_decl) = 1;
1820
1821   /* Generate a constructor call for the module descriptor.
1822      This code was generated by reading the grammar rules
1823      of c-parse.in;  Therefore, it may not be the most efficient
1824      way of generating the requisite code.  */
1825
1826   if (flag_next_runtime)
1827     return 0;
1828
1829   {
1830     tree parms, function_decl, decelerator, void_list_node_1;
1831     tree function_type;
1832     tree init_function_name = get_file_function_name ('I');
1833
1834     /* Declare void __objc_execClass (void *); */
1835
1836     void_list_node_1 = build_tree_list (NULL_TREE, void_type_node);
1837     function_type
1838       = build_function_type (void_type_node,
1839                              tree_cons (NULL_TREE, ptr_type_node,
1840                                         void_list_node_1));
1841     function_decl = build_decl (FUNCTION_DECL,
1842                                 get_identifier (TAG_EXECCLASS),
1843                                 function_type);
1844     DECL_EXTERNAL (function_decl) = 1;
1845     DECL_ARTIFICIAL (function_decl) = 1;
1846     TREE_PUBLIC (function_decl) = 1;
1847
1848     pushdecl (function_decl);
1849     rest_of_decl_compilation (function_decl, 0, 0, 0);
1850
1851     parms
1852       = build_tree_list (NULL_TREE,
1853                          build_unary_op (ADDR_EXPR, UOBJC_MODULES_decl, 0));
1854     decelerator = build_function_call (function_decl, parms);
1855
1856     /* void _GLOBAL_$I$<gnyf> () {objc_execClass (&L_OBJC_MODULES);}  */
1857
1858     start_function (void_list_node_1,
1859                     build_parse_node (CALL_EXPR, init_function_name,
1860                                       /* This has the format of the output
1861                                          of get_parm_info.  */
1862                                       tree_cons (NULL_TREE, NULL_TREE,
1863                                                  void_list_node_1),
1864                                       NULL_TREE),
1865                     NULL_TREE, NULL_TREE);
1866 #if 0 /* This should be turned back on later
1867          for the systems where collect is not needed.  */
1868     /* Make these functions nonglobal
1869        so each file can use the same name.  */
1870     TREE_PUBLIC (current_function_decl) = 0;
1871 #endif
1872     TREE_USED (current_function_decl) = 1;
1873     store_parm_decls ();
1874
1875     assemble_external (function_decl);
1876     c_expand_expr_stmt (decelerator);
1877
1878     TREE_PUBLIC (current_function_decl) = 1;
1879
1880     function_decl = current_function_decl;
1881     finish_function (0);
1882
1883     /* Return the name of the constructor function.  */
1884     return XSTR (XEXP (DECL_RTL (function_decl), 0), 0);
1885   }
1886 }
1887
1888 /* extern const char _OBJC_STRINGS[]; */
1889
1890 static void
1891 generate_forward_declaration_to_string_table ()
1892 {
1893   tree sc_spec, decl_specs, expr_decl;
1894
1895   sc_spec = tree_cons (NULL_TREE, ridpointers[(int) RID_EXTERN], NULL_TREE);
1896   decl_specs = tree_cons (NULL_TREE, ridpointers[(int) RID_CHAR], sc_spec);
1897
1898   expr_decl
1899     = build_nt (ARRAY_REF, get_identifier ("_OBJC_STRINGS"), NULL_TREE);
1900
1901   UOBJC_STRINGS_decl = define_decl (expr_decl, decl_specs);
1902 }
1903
1904 /* Return the DECL of the string IDENT in the SECTION.  */
1905
1906 static tree
1907 get_objc_string_decl (ident, section)
1908      tree ident;
1909      enum string_section section;
1910 {
1911   tree chain;
1912
1913   if (section == class_names)
1914     chain = class_names_chain;
1915   else if (section == meth_var_names)
1916     chain = meth_var_names_chain;
1917   else if (section == meth_var_types)
1918     chain = meth_var_types_chain;
1919   else
1920     abort ();
1921
1922   for (; chain != 0; chain = TREE_VALUE (chain))
1923     if (TREE_VALUE (chain) == ident)
1924       return (TREE_PURPOSE (chain));
1925
1926   abort ();
1927   return NULL_TREE;
1928 }
1929
1930 /* Output references to all statically allocated objects.  Return the DECL
1931    for the array built.  */
1932
1933 static void
1934 generate_static_references ()
1935 {
1936   tree decls = NULL_TREE, ident, decl_spec, expr_decl, expr = NULL_TREE;
1937   tree class_name, class, decl, initlist;
1938   tree cl_chain, in_chain, type;
1939   int num_inst, num_class;
1940   char buf[256];
1941
1942   if (flag_next_runtime)
1943     abort ();
1944
1945   for (cl_chain = objc_static_instances, num_class = 0;
1946        cl_chain; cl_chain = TREE_CHAIN (cl_chain), num_class++)
1947     {
1948       for (num_inst = 0, in_chain = TREE_PURPOSE (cl_chain);
1949            in_chain; num_inst++, in_chain = TREE_CHAIN (in_chain));
1950
1951       sprintf (buf, "_OBJC_STATIC_INSTANCES_%d", num_class);
1952       ident = get_identifier (buf);
1953
1954       expr_decl = build_nt (ARRAY_REF, ident, NULL_TREE);
1955       decl_spec = tree_cons (NULL_TREE, build_pointer_type (void_type_node),
1956                              build_tree_list (NULL_TREE,
1957                                               ridpointers[(int) RID_STATIC]));
1958       decl = start_decl (expr_decl, decl_spec, 1, NULL_TREE, NULL_TREE);
1959       DECL_CONTEXT (decl) = 0;
1960       DECL_ARTIFICIAL (decl) = 1;
1961
1962       /* Output {class_name, ...}.  */
1963       class = TREE_VALUE (cl_chain);
1964       class_name = get_objc_string_decl (TYPE_NAME (class), class_names);
1965       initlist = build_tree_list (NULL_TREE,
1966                                   build_unary_op (ADDR_EXPR, class_name, 1));
1967
1968       /* Output {..., instance, ...}.  */
1969       for (in_chain = TREE_PURPOSE (cl_chain);
1970            in_chain; in_chain = TREE_CHAIN (in_chain))
1971         {
1972           expr = build_unary_op (ADDR_EXPR, TREE_VALUE (in_chain), 1);
1973           initlist = tree_cons (NULL_TREE, expr, initlist);
1974         }
1975
1976       /* Output {..., NULL}.  */
1977       initlist = tree_cons (NULL_TREE, build_int_2 (0, 0), initlist);
1978
1979       expr = build_constructor (TREE_TYPE (decl), nreverse (initlist));
1980       finish_decl (decl, expr, NULL_TREE);
1981       TREE_USED (decl) = 1;
1982
1983       type = build_array_type (build_pointer_type (void_type_node), 0);
1984       decl = build_decl (VAR_DECL, ident, type);
1985       make_decl_rtl (decl, 0, 1);
1986       TREE_USED (decl) = 1;
1987       decls
1988         = tree_cons (NULL_TREE, build_unary_op (ADDR_EXPR, decl, 1), decls);
1989     }
1990
1991   decls = tree_cons (NULL_TREE, build_int_2 (0, 0), decls);
1992   ident = get_identifier ("_OBJC_STATIC_INSTANCES");
1993   expr_decl = build_nt (ARRAY_REF, ident, NULL_TREE);
1994   decl_spec = tree_cons (NULL_TREE, build_pointer_type (void_type_node),
1995                          build_tree_list (NULL_TREE,
1996                                           ridpointers[(int) RID_STATIC]));
1997   static_instances_decl
1998     = start_decl (expr_decl, decl_spec, 1, NULL_TREE, NULL_TREE);
1999   TREE_USED (static_instances_decl) = 1;
2000   DECL_CONTEXT (static_instances_decl) = 0;
2001   DECL_ARTIFICIAL (static_instances_decl) = 1;
2002   expr = build_constructor (TREE_TYPE (static_instances_decl),
2003                             nreverse (decls));
2004   finish_decl (static_instances_decl, expr, NULL_TREE);
2005 }
2006
2007 /* Output all strings.  */
2008
2009 static void
2010 generate_strings ()
2011 {
2012   tree sc_spec, decl_specs, expr_decl;
2013   tree chain, string_expr;
2014   tree string, decl;
2015
2016   for (chain = class_names_chain; chain; chain = TREE_CHAIN (chain))
2017     {
2018       string = TREE_VALUE (chain);
2019       decl = TREE_PURPOSE (chain);
2020       sc_spec
2021         = tree_cons (NULL_TREE, ridpointers[(int) RID_STATIC], NULL_TREE);
2022       decl_specs = tree_cons (NULL_TREE, ridpointers[(int) RID_CHAR], sc_spec);
2023       expr_decl = build_nt (ARRAY_REF, DECL_NAME (decl), NULL_TREE);
2024       decl = start_decl (expr_decl, decl_specs, 1, NULL_TREE, NULL_TREE);
2025       string_expr = my_build_string (IDENTIFIER_LENGTH (string) + 1,
2026                                      IDENTIFIER_POINTER (string));
2027       finish_decl (decl, string_expr, NULL_TREE);
2028     }
2029
2030   for (chain = meth_var_names_chain; chain; chain = TREE_CHAIN (chain))
2031     {
2032       string = TREE_VALUE (chain);
2033       decl = TREE_PURPOSE (chain);
2034       sc_spec
2035         = tree_cons (NULL_TREE, ridpointers[(int) RID_STATIC], NULL_TREE);
2036       decl_specs = tree_cons (NULL_TREE, ridpointers[(int) RID_CHAR], sc_spec);
2037       expr_decl = build_nt (ARRAY_REF, DECL_NAME (decl), NULL_TREE);
2038       decl = start_decl (expr_decl, decl_specs, 1, NULL_TREE, NULL_TREE);
2039       string_expr = my_build_string (IDENTIFIER_LENGTH (string) + 1,
2040                                      IDENTIFIER_POINTER (string));
2041       finish_decl (decl, string_expr, NULL_TREE);
2042     }
2043
2044   for (chain = meth_var_types_chain; chain; chain = TREE_CHAIN (chain))
2045     {
2046       string = TREE_VALUE (chain);
2047       decl = TREE_PURPOSE (chain);
2048       sc_spec
2049         = tree_cons (NULL_TREE, ridpointers[(int) RID_STATIC], NULL_TREE);
2050       decl_specs = tree_cons (NULL_TREE, ridpointers[(int) RID_CHAR], sc_spec);
2051       expr_decl = build_nt (ARRAY_REF, DECL_NAME (decl), NULL_TREE);
2052       decl = start_decl (expr_decl, decl_specs, 1, NULL_TREE, NULL_TREE);
2053       string_expr = my_build_string (IDENTIFIER_LENGTH (string) + 1,
2054                                 IDENTIFIER_POINTER (string));
2055       finish_decl (decl, string_expr, NULL_TREE);
2056     }
2057 }
2058
2059 static tree
2060 build_selector_reference_decl ()
2061 {
2062   tree decl, ident;
2063   char buf[256];
2064   static int idx = 0;
2065
2066   sprintf (buf, "_OBJC_SELECTOR_REFERENCES_%d", idx++);
2067
2068   ident = get_identifier (buf);
2069
2070   decl = build_decl (VAR_DECL, ident, selector_type);
2071   DECL_EXTERNAL (decl) = 1;
2072   TREE_PUBLIC (decl) = 1;
2073   TREE_USED (decl) = 1;
2074   TREE_READONLY (decl) = 1;
2075   DECL_ARTIFICIAL (decl) = 1;
2076   DECL_CONTEXT (decl) = 0;
2077
2078   make_decl_rtl (decl, 0, 1);
2079   pushdecl_top_level (decl);
2080
2081   return decl;
2082 }
2083
2084 /* Just a handy wrapper for add_objc_string.  */
2085
2086 static tree
2087 build_selector (ident)
2088      tree ident;
2089 {
2090   tree expr = add_objc_string (ident, meth_var_names);
2091   if (flag_typed_selectors)
2092     return expr;
2093   else
2094     return build_c_cast (selector_type, expr); /* cast! */
2095 }
2096
2097 /* Synthesize the following expr: (char *)&_OBJC_STRINGS[<offset>]
2098    The cast stops the compiler from issuing the following message:
2099    grok.m: warning: initialization of non-const * pointer from const *
2100    grok.m: warning: initialization between incompatible pointer types.  */
2101
2102 #if 0
2103 static tree
2104 build_msg_pool_reference (offset)
2105      int offset;
2106 {
2107   tree expr = build_int_2 (offset, 0);
2108   tree cast;
2109
2110   expr = build_array_ref (UOBJC_STRINGS_decl, expr);
2111   expr = build_unary_op (ADDR_EXPR, expr, 0);
2112
2113   cast = build_tree_list (build_tree_list (NULL_TREE,
2114                                            ridpointers[(int) RID_CHAR]),
2115                           build1 (INDIRECT_REF, NULL_TREE, NULL_TREE));
2116   TREE_TYPE (expr) = groktypename (cast);
2117   return expr;
2118 }
2119
2120 static tree
2121 init_selector (offset)
2122      int offset;
2123 {
2124   tree expr = build_msg_pool_reference (offset);
2125   TREE_TYPE (expr) = selector_type;
2126   return expr;
2127 }
2128 #endif
2129
2130 static void
2131 build_selector_translation_table ()
2132 {
2133   tree sc_spec, decl_specs;
2134   tree chain, initlist = NULL_TREE;
2135   int offset = 0;
2136   tree decl = NULL_TREE, var_decl, name;
2137
2138   for (chain = sel_ref_chain; chain; chain = TREE_CHAIN (chain))
2139     {
2140       tree expr;
2141
2142       expr = build_selector (TREE_VALUE (chain));
2143
2144       if (flag_next_runtime)
2145         {
2146           name = DECL_NAME (TREE_PURPOSE (chain));
2147
2148           sc_spec = build_tree_list (NULL_TREE, ridpointers[(int) RID_STATIC]);
2149
2150           /* static SEL _OBJC_SELECTOR_REFERENCES_n = ...; */
2151           decl_specs = tree_cons (NULL_TREE, selector_type, sc_spec);
2152
2153           var_decl = name;
2154
2155           /* The `decl' that is returned from start_decl is the one that we
2156              forward declared in `build_selector_reference'  */
2157           decl = start_decl (var_decl, decl_specs, 1, NULL_TREE, NULL_TREE);
2158         }
2159
2160       /* add one for the '\0' character */
2161       offset += IDENTIFIER_LENGTH (TREE_VALUE (chain)) + 1;
2162
2163       if (flag_next_runtime)
2164         finish_decl (decl, expr, NULL_TREE);
2165       else 
2166         {
2167           if (flag_typed_selectors)
2168             {
2169               tree eltlist = NULL_TREE;
2170               tree encoding = get_proto_encoding (TREE_PURPOSE (chain));
2171               eltlist = tree_cons (NULL_TREE, expr, NULL_TREE);
2172               eltlist = tree_cons (NULL_TREE, encoding, eltlist);
2173               expr = build_constructor (objc_selector_template,
2174                                         nreverse (eltlist));
2175             }
2176           initlist = tree_cons (NULL_TREE, expr, initlist);
2177           
2178         }
2179     }
2180
2181   if (! flag_next_runtime)
2182     {
2183       /* Cause the variable and its initial value to be actually output.  */
2184       DECL_EXTERNAL (UOBJC_SELECTOR_TABLE_decl) = 0;
2185       TREE_STATIC (UOBJC_SELECTOR_TABLE_decl) = 1;
2186       /* NULL terminate the list and fix the decl for output.  */
2187       initlist = tree_cons (NULL_TREE, build_int_2 (0, 0), initlist);
2188       DECL_INITIAL (UOBJC_SELECTOR_TABLE_decl) = objc_ellipsis_node;
2189       initlist = build_constructor (TREE_TYPE (UOBJC_SELECTOR_TABLE_decl),
2190                                     nreverse (initlist));
2191       finish_decl (UOBJC_SELECTOR_TABLE_decl, initlist, NULL_TREE);
2192       current_function_decl = NULL_TREE;
2193     }
2194 }
2195
2196 static tree
2197 get_proto_encoding (proto)
2198      tree proto;
2199 {
2200   tree encoding;
2201   if (proto)
2202     {
2203       tree tmp_decl;
2204
2205       if (! METHOD_ENCODING (proto))
2206         {
2207             tmp_decl = build_tmp_function_decl ();
2208             hack_method_prototype (proto, tmp_decl);
2209             encoding = encode_method_prototype (proto, tmp_decl);
2210             METHOD_ENCODING (proto) = encoding;
2211           }
2212       else
2213         encoding = METHOD_ENCODING (proto);
2214
2215       return add_objc_string (encoding, meth_var_types);
2216     }
2217   else
2218     return build_int_2 (0, 0);
2219 }
2220
2221 /* sel_ref_chain is a list whose "value" fields will be instances of
2222    identifier_node that represent the selector.  */
2223
2224 static tree
2225 build_typed_selector_reference (ident, proto)
2226      tree ident, proto;
2227 {
2228   tree *chain = &sel_ref_chain;
2229   tree expr;
2230   int index = 0;
2231
2232   while (*chain)
2233     {
2234       if (TREE_PURPOSE (*chain) == ident && TREE_VALUE (*chain) == proto)
2235         goto return_at_index;
2236
2237       index++;
2238       chain = &TREE_CHAIN (*chain);
2239     }
2240
2241   *chain = tree_cons (proto, ident, NULL_TREE);
2242
2243  return_at_index:
2244   expr = build_unary_op (ADDR_EXPR,
2245                          build_array_ref (UOBJC_SELECTOR_TABLE_decl,
2246                                           build_int_2 (index, 0)),
2247                          1);
2248   return build_c_cast (selector_type, expr);
2249 }
2250
2251 static tree
2252 build_selector_reference (ident)
2253      tree ident;
2254 {
2255   tree *chain = &sel_ref_chain;
2256   tree expr;
2257   int index = 0;
2258
2259   while (*chain)
2260     {
2261       if (TREE_VALUE (*chain) == ident)
2262         return (flag_next_runtime
2263                 ? TREE_PURPOSE (*chain)
2264                 : build_array_ref (UOBJC_SELECTOR_TABLE_decl,
2265                                    build_int_2 (index, 0)));
2266
2267       index++;
2268       chain = &TREE_CHAIN (*chain);
2269     }
2270
2271   expr = build_selector_reference_decl ();
2272
2273   *chain = tree_cons (expr, ident, NULL_TREE);
2274
2275   return (flag_next_runtime
2276           ? expr
2277           : build_array_ref (UOBJC_SELECTOR_TABLE_decl,
2278                              build_int_2 (index, 0)));
2279 }
2280
2281 static tree
2282 build_class_reference_decl ()
2283 {
2284   tree decl, ident;
2285   char buf[256];
2286   static int idx = 0;
2287
2288   sprintf (buf, "_OBJC_CLASS_REFERENCES_%d", idx++);
2289
2290   ident = get_identifier (buf);
2291
2292   decl = build_decl (VAR_DECL, ident, objc_class_type);
2293   DECL_EXTERNAL (decl) = 1;
2294   TREE_PUBLIC (decl) = 1;
2295   TREE_USED (decl) = 1;
2296   TREE_READONLY (decl) = 1;
2297   DECL_CONTEXT (decl) = 0;
2298   DECL_ARTIFICIAL (decl) = 1;
2299
2300   make_decl_rtl (decl, 0, 1);
2301   pushdecl_top_level (decl);
2302
2303   return decl;
2304 }
2305
2306 /* Create a class reference, but don't create a variable to reference
2307    it.  */
2308
2309 static void
2310 add_class_reference (ident)
2311      tree ident;
2312 {
2313   tree chain;
2314
2315   if ((chain = cls_ref_chain))
2316     {
2317       tree tail;
2318       do
2319         {
2320           if (ident == TREE_VALUE (chain))
2321             return;
2322
2323           tail = chain;
2324           chain = TREE_CHAIN (chain);
2325         }
2326       while (chain);
2327
2328       /* Append to the end of the list */
2329       TREE_CHAIN (tail) = tree_cons (NULL_TREE, ident, NULL_TREE);
2330     }
2331   else
2332     cls_ref_chain = tree_cons (NULL_TREE, ident, NULL_TREE);
2333 }
2334
2335 /* Get a class reference, creating it if necessary.  Also create the
2336    reference variable.  */
2337
2338 tree
2339 get_class_reference (ident)
2340     tree ident;
2341 {
2342   if (flag_next_runtime)
2343     {
2344       tree *chain;
2345       tree decl;
2346
2347       for (chain = &cls_ref_chain; *chain; chain = &TREE_CHAIN (*chain))
2348         if (TREE_VALUE (*chain) == ident)
2349           {
2350             if (! TREE_PURPOSE (*chain))
2351               TREE_PURPOSE (*chain) = build_class_reference_decl ();
2352
2353             return TREE_PURPOSE (*chain);
2354           }
2355
2356       decl = build_class_reference_decl ();
2357       *chain = tree_cons (decl, ident, NULL_TREE);
2358       return decl;
2359     }
2360   else
2361     {
2362       tree params;
2363
2364       add_class_reference (ident);
2365
2366       params = build_tree_list (NULL_TREE,
2367                                 my_build_string (IDENTIFIER_LENGTH (ident) + 1,
2368                                                  IDENTIFIER_POINTER (ident)));
2369
2370       assemble_external (objc_get_class_decl);
2371       return build_function_call (objc_get_class_decl, params);
2372     }
2373 }
2374
2375 /* SEL_REFDEF_CHAIN is a list whose "value" fields will be instances
2376    of identifier_node that represent the selector. It returns the
2377    offset of the selector from the beginning of the _OBJC_STRINGS
2378    pool. This offset is typically used by init_selector during code
2379    generation.
2380
2381    For each string section we have a chain which maps identifier nodes
2382    to decls for the strings.  */
2383
2384 static tree
2385 add_objc_string (ident, section)
2386      tree ident;
2387      enum string_section section;
2388 {
2389   tree *chain, decl;
2390
2391   if (section == class_names)
2392     chain = &class_names_chain;
2393   else if (section == meth_var_names)
2394     chain = &meth_var_names_chain;
2395   else if (section == meth_var_types)
2396     chain = &meth_var_types_chain;
2397   else
2398     abort ();
2399
2400   while (*chain)
2401     {
2402       if (TREE_VALUE (*chain) == ident)
2403         return build_unary_op (ADDR_EXPR, TREE_PURPOSE (*chain), 1);
2404
2405       chain = &TREE_CHAIN (*chain);
2406     }
2407
2408   decl = build_objc_string_decl (section);
2409
2410   *chain = tree_cons (decl, ident, NULL_TREE);
2411
2412   return build_unary_op (ADDR_EXPR, decl, 1);
2413 }
2414
2415 static tree
2416 build_objc_string_decl (section)
2417      enum string_section section;
2418 {
2419   tree decl, ident;
2420   char buf[256];
2421   static int class_names_idx = 0;
2422   static int meth_var_names_idx = 0;
2423   static int meth_var_types_idx = 0;
2424
2425   if (section == class_names)
2426     sprintf (buf, "_OBJC_CLASS_NAME_%d", class_names_idx++);
2427   else if (section == meth_var_names)
2428     sprintf (buf, "_OBJC_METH_VAR_NAME_%d", meth_var_names_idx++);
2429   else if (section == meth_var_types)
2430     sprintf (buf, "_OBJC_METH_VAR_TYPE_%d", meth_var_types_idx++);
2431
2432   ident = get_identifier (buf);
2433
2434   decl = build_decl (VAR_DECL, ident, build_array_type (char_type_node, 0));
2435   DECL_EXTERNAL (decl) = 1;
2436   TREE_PUBLIC (decl) = 1;
2437   TREE_USED (decl) = 1;
2438   TREE_READONLY (decl) = 1;
2439   TREE_CONSTANT (decl) = 1;
2440   DECL_CONTEXT (decl) = 0;
2441   DECL_ARTIFICIAL (decl) = 1;
2442  
2443   make_decl_rtl (decl, 0, 1);
2444   pushdecl_top_level (decl);
2445
2446   return decl;
2447 }
2448
2449
2450 void
2451 objc_declare_alias (alias_ident, class_ident)
2452      tree alias_ident;
2453      tree class_ident;
2454 {
2455   if (!doing_objc_thang)
2456     objc_fatal ();
2457
2458   if (is_class_name (class_ident) != class_ident)
2459     warning ("Cannot find class `%s'", IDENTIFIER_POINTER (class_ident));
2460   else if (is_class_name (alias_ident))
2461     warning ("Class `%s' already exists", IDENTIFIER_POINTER (alias_ident));
2462   else
2463     alias_chain = tree_cons (class_ident, alias_ident, alias_chain);
2464 }
2465
2466 void
2467 objc_declare_class (ident_list)
2468      tree ident_list;
2469 {
2470   tree list;
2471
2472   if (!doing_objc_thang)
2473     objc_fatal ();
2474
2475   for (list = ident_list; list; list = TREE_CHAIN (list))
2476     {
2477       tree ident = TREE_VALUE (list);
2478       tree decl;
2479
2480       if ((decl = lookup_name (ident)))
2481         {
2482           error ("`%s' redeclared as different kind of symbol",
2483                   IDENTIFIER_POINTER (ident));
2484           error_with_decl (decl, "previous declaration of `%s'");
2485         }
2486
2487       if (! is_class_name (ident))
2488         {
2489           tree record = xref_tag (RECORD_TYPE, ident);
2490           TREE_STATIC_TEMPLATE (record) = 1;
2491           class_chain = tree_cons (NULL_TREE, ident, class_chain);
2492         }
2493     }
2494 }
2495
2496 tree
2497 is_class_name (ident)
2498      tree ident;
2499 {
2500   tree chain;
2501
2502   if (lookup_interface (ident))
2503     return ident;
2504
2505   for (chain = class_chain; chain; chain = TREE_CHAIN (chain))
2506     {
2507       if (ident == TREE_VALUE (chain))
2508         return ident;
2509     }
2510
2511   for (chain = alias_chain; chain; chain = TREE_CHAIN (chain))
2512     {
2513       if (ident == TREE_VALUE (chain))
2514         return TREE_PURPOSE (chain);
2515     }
2516
2517   return 0;
2518 }
2519
2520 tree
2521 lookup_interface (ident)
2522      tree ident;
2523 {
2524   tree chain;
2525
2526   for (chain = interface_chain; chain; chain = TREE_CHAIN (chain))
2527     {
2528       if (ident == CLASS_NAME (chain))
2529         return chain;
2530     }
2531   return NULL_TREE;
2532 }
2533
2534 static tree
2535 objc_copy_list (list, head)
2536      tree list;
2537      tree *head;
2538 {
2539   tree newlist = NULL_TREE, tail = NULL_TREE;
2540
2541   while (list)
2542     {
2543       tail = copy_node (list);
2544
2545       /* The following statement fixes a bug when inheriting instance
2546          variables that are declared to be bitfields. finish_struct
2547          expects to find the width of the bitfield in DECL_INITIAL.  */
2548       if (DECL_BIT_FIELD (tail) && DECL_INITIAL (tail) == 0)
2549         DECL_INITIAL (tail) = DECL_SIZE (tail);
2550
2551       newlist = chainon (newlist, tail);
2552       list = TREE_CHAIN (list);
2553     }
2554
2555   *head = newlist;
2556   return tail;
2557 }
2558
2559 /* Used by: build_private_template, get_class_ivars, and
2560    continue_class.  COPY is 1 when called from @defs.  In this case
2561    copy all fields.  Otherwise don't copy leaf ivars since we rely on
2562    them being side-effected exactly once by finish_struct.  */
2563
2564 static tree
2565 build_ivar_chain (interface, copy)
2566      tree interface;
2567      int copy;
2568 {
2569   tree my_name, super_name, ivar_chain;
2570
2571   my_name = CLASS_NAME (interface);
2572   super_name = CLASS_SUPER_NAME (interface);
2573
2574   /* Possibly copy leaf ivars.  */
2575   if (copy)
2576     objc_copy_list (CLASS_IVARS (interface), &ivar_chain);
2577   else
2578     ivar_chain = CLASS_IVARS (interface);
2579
2580   while (super_name)
2581     {
2582       tree op1;
2583       tree super_interface = lookup_interface (super_name);
2584
2585       if (!super_interface)
2586         {
2587           /* fatal did not work with 2 args...should fix */
2588           error ("Cannot find interface declaration for `%s', superclass of `%s'",
2589                  IDENTIFIER_POINTER (super_name),
2590                  IDENTIFIER_POINTER (my_name));
2591           exit (FATAL_EXIT_CODE);
2592         }
2593
2594       if (super_interface == interface)
2595         {
2596           fatal ("Circular inheritance in interface declaration for `%s'",
2597                  IDENTIFIER_POINTER (super_name));
2598         }
2599
2600       interface = super_interface;
2601       my_name = CLASS_NAME (interface);
2602       super_name = CLASS_SUPER_NAME (interface);
2603
2604       op1 = CLASS_IVARS (interface);
2605       if (op1)
2606         {
2607           tree head, tail = objc_copy_list (op1, &head);
2608
2609           /* Prepend super class ivars...make a copy of the list, we
2610              do not want to alter the original.  */
2611           TREE_CHAIN (tail) = ivar_chain;
2612           ivar_chain = head;
2613         }
2614     }
2615   return ivar_chain;
2616 }
2617
2618 /* struct <classname> {
2619      struct objc_class *isa;
2620      ...
2621    };  */
2622
2623 static tree
2624 build_private_template (class)
2625      tree class;
2626 {
2627   tree ivar_context;
2628
2629   if (CLASS_STATIC_TEMPLATE (class))
2630     {
2631       uprivate_record = CLASS_STATIC_TEMPLATE (class);
2632       ivar_context = TYPE_FIELDS (CLASS_STATIC_TEMPLATE (class));
2633     }
2634   else
2635     {
2636       uprivate_record = start_struct (RECORD_TYPE, CLASS_NAME (class));
2637
2638       ivar_context = build_ivar_chain (class, 0);
2639
2640       finish_struct (uprivate_record, ivar_context, NULL_TREE);
2641
2642       CLASS_STATIC_TEMPLATE (class) = uprivate_record;
2643
2644       /* mark this record as class template - for class type checking */
2645       TREE_STATIC_TEMPLATE (uprivate_record) = 1;
2646     }
2647
2648   instance_type
2649     = groktypename (build_tree_list (build_tree_list (NULL_TREE,
2650                                                       uprivate_record),
2651                                      build1 (INDIRECT_REF, NULL_TREE,
2652                                              NULL_TREE)));
2653
2654   return ivar_context;
2655 }
2656 \f
2657 /* Begin code generation for protocols...  */
2658
2659 /* struct objc_protocol {
2660      char *protocol_name;
2661      struct objc_protocol **protocol_list;
2662      struct objc_method_desc *instance_methods;
2663      struct objc_method_desc *class_methods;
2664    };  */
2665
2666 static tree
2667 build_protocol_template ()
2668 {
2669   tree decl_specs, field_decl, field_decl_chain;
2670   tree template;
2671
2672   template = start_struct (RECORD_TYPE, get_identifier (UTAG_PROTOCOL));
2673
2674   /* struct objc_class *isa; */
2675
2676   decl_specs = build_tree_list (NULL_TREE, xref_tag (RECORD_TYPE,
2677                                         get_identifier (UTAG_CLASS)));
2678   field_decl = build1 (INDIRECT_REF, NULL_TREE, get_identifier ("isa"));
2679   field_decl
2680     = grokfield (input_filename, lineno, field_decl, decl_specs, NULL_TREE);
2681   field_decl_chain = field_decl;
2682
2683   /* char *protocol_name; */
2684
2685   decl_specs = build_tree_list (NULL_TREE, ridpointers[(int) RID_CHAR]);
2686   field_decl
2687     = build1 (INDIRECT_REF, NULL_TREE, get_identifier ("protocol_name"));
2688   field_decl
2689     = grokfield (input_filename, lineno, field_decl, decl_specs, NULL_TREE);
2690   chainon (field_decl_chain, field_decl);
2691
2692   /* struct objc_protocol **protocol_list; */
2693
2694   decl_specs = build_tree_list (NULL_TREE, template);
2695   field_decl
2696     = build1 (INDIRECT_REF, NULL_TREE, get_identifier ("protocol_list"));
2697   field_decl = build1 (INDIRECT_REF, NULL_TREE, field_decl);
2698   field_decl
2699     = grokfield (input_filename, lineno, field_decl, decl_specs, NULL_TREE);
2700   chainon (field_decl_chain, field_decl);
2701
2702   /* struct objc_method_list *instance_methods; */
2703
2704   decl_specs
2705     = build_tree_list (NULL_TREE,
2706                        xref_tag (RECORD_TYPE,
2707                                  get_identifier (UTAG_METHOD_PROTOTYPE_LIST)));
2708   field_decl
2709     = build1 (INDIRECT_REF, NULL_TREE, get_identifier ("instance_methods"));
2710   field_decl
2711     = grokfield (input_filename, lineno, field_decl, decl_specs, NULL_TREE);
2712   chainon (field_decl_chain, field_decl);
2713
2714   /* struct objc_method_list *class_methods; */
2715
2716   decl_specs
2717     = build_tree_list (NULL_TREE,
2718                        xref_tag (RECORD_TYPE,
2719                                  get_identifier (UTAG_METHOD_PROTOTYPE_LIST)));
2720   field_decl
2721     = build1 (INDIRECT_REF, NULL_TREE, get_identifier ("class_methods"));
2722   field_decl
2723     = grokfield (input_filename, lineno, field_decl, decl_specs, NULL_TREE);
2724   chainon (field_decl_chain, field_decl);
2725
2726   return finish_struct (template, field_decl_chain, NULL_TREE);
2727 }
2728
2729 static tree
2730 build_descriptor_table_initializer (type, entries)
2731      tree type;
2732      tree entries;
2733 {
2734   tree initlist = NULL_TREE;
2735
2736   do
2737     {
2738       tree eltlist = NULL_TREE;
2739
2740       eltlist
2741         = tree_cons (NULL_TREE,
2742                      build_selector (METHOD_SEL_NAME (entries)), NULL_TREE);
2743       eltlist
2744         = tree_cons (NULL_TREE,
2745                      add_objc_string (METHOD_ENCODING (entries),
2746                                       meth_var_types),
2747                      eltlist);
2748
2749       initlist
2750         = tree_cons (NULL_TREE,
2751                      build_constructor (type, nreverse (eltlist)), initlist);
2752
2753       entries = TREE_CHAIN (entries);
2754     }
2755   while (entries);
2756
2757   return build_constructor (build_array_type (type, 0), nreverse (initlist));
2758 }
2759
2760 /* struct objc_method_prototype_list {
2761      int count;
2762      struct objc_method_prototype {
2763         SEL name;
2764         char *types;
2765      } list[1];
2766    };  */
2767
2768 static tree
2769 build_method_prototype_list_template (list_type, size)
2770      tree list_type;
2771      int size;
2772 {
2773   tree objc_ivar_list_record;
2774   tree decl_specs, field_decl, field_decl_chain;
2775
2776   /* Generate an unnamed struct definition.  */
2777
2778   objc_ivar_list_record = start_struct (RECORD_TYPE, NULL_TREE);
2779
2780   /* int method_count; */
2781
2782   decl_specs = build_tree_list (NULL_TREE, ridpointers[(int) RID_INT]);
2783   field_decl = get_identifier ("method_count");
2784
2785   field_decl
2786     = grokfield (input_filename, lineno, field_decl, decl_specs, NULL_TREE);
2787   field_decl_chain = field_decl;
2788
2789   /* struct objc_method method_list[]; */
2790
2791   decl_specs = build_tree_list (NULL_TREE, list_type);
2792   field_decl = build_nt (ARRAY_REF, get_identifier ("method_list"),
2793                          build_int_2 (size, 0));
2794
2795   field_decl
2796     = grokfield (input_filename, lineno, field_decl, decl_specs, NULL_TREE);
2797   chainon (field_decl_chain, field_decl);
2798
2799   finish_struct (objc_ivar_list_record, field_decl_chain, NULL_TREE);
2800
2801   return objc_ivar_list_record;
2802 }
2803
2804 static tree
2805 build_method_prototype_template ()
2806 {
2807   tree proto_record;
2808   tree decl_specs, field_decl, field_decl_chain;
2809
2810   proto_record
2811     = start_struct (RECORD_TYPE, get_identifier (UTAG_METHOD_PROTOTYPE));
2812
2813 #ifdef OBJC_INT_SELECTORS
2814   /* unsigned int _cmd; */
2815   decl_specs
2816     = tree_cons (NULL_TREE, ridpointers[(int) RID_UNSIGNED], NULL_TREE);
2817   decl_specs = tree_cons (NULL_TREE, ridpointers[(int) RID_INT], decl_specs);
2818   field_decl = get_identifier ("_cmd");
2819 #else /* OBJC_INT_SELECTORS */
2820   /* struct objc_selector *_cmd; */
2821   decl_specs = tree_cons (NULL_TREE, xref_tag (RECORD_TYPE,
2822                           get_identifier (TAG_SELECTOR)), NULL_TREE);
2823   field_decl = build1 (INDIRECT_REF, NULL_TREE, get_identifier ("_cmd"));
2824 #endif /* OBJC_INT_SELECTORS */
2825
2826   field_decl
2827     = grokfield (input_filename, lineno, field_decl, decl_specs, NULL_TREE);
2828   field_decl_chain = field_decl;
2829
2830   decl_specs = tree_cons (NULL_TREE, ridpointers[(int) RID_CHAR], NULL_TREE);
2831   field_decl
2832     = build1 (INDIRECT_REF, NULL_TREE, get_identifier ("method_types"));
2833   field_decl
2834     = grokfield (input_filename, lineno, field_decl, decl_specs, NULL_TREE);
2835   chainon (field_decl_chain, field_decl);
2836
2837   finish_struct (proto_record, field_decl_chain, NULL_TREE);
2838
2839   return proto_record;
2840 }
2841
2842 /* True if last call to forwarding_offset yielded a register offset.  */
2843 static int offset_is_register;
2844
2845 static int
2846 forwarding_offset (parm)
2847       tree parm;
2848 {
2849   int offset_in_bytes;
2850
2851   if (GET_CODE (DECL_INCOMING_RTL (parm)) == MEM)
2852     {
2853       rtx addr = XEXP (DECL_INCOMING_RTL (parm), 0);
2854
2855       /* ??? Here we assume that the parm address is indexed
2856           off the frame pointer or arg pointer.
2857           If that is not true, we produce meaningless results,
2858           but do not crash.  */
2859       if (GET_CODE (addr) == PLUS
2860           && GET_CODE (XEXP (addr, 1)) == CONST_INT)
2861         offset_in_bytes = INTVAL (XEXP (addr, 1));
2862       else
2863         offset_in_bytes = 0;
2864
2865       offset_in_bytes += OBJC_FORWARDING_STACK_OFFSET;
2866       offset_is_register = 0;
2867     }
2868   else if (GET_CODE (DECL_INCOMING_RTL (parm)) == REG)
2869     {
2870       int regno = REGNO (DECL_INCOMING_RTL (parm));
2871       offset_in_bytes = apply_args_register_offset (regno);
2872       offset_is_register = 1;
2873     }
2874   else
2875     return 0;
2876
2877   /* This is the case where the parm is passed as an int or double
2878      and it is converted to a char, short or float and stored back
2879      in the parmlist.  In this case, describe the parm
2880      with the variable's declared type, and adjust the address
2881      if the least significant bytes (which we are using) are not
2882      the first ones.  */
2883   if (BYTES_BIG_ENDIAN && TREE_TYPE (parm) != DECL_ARG_TYPE (parm))
2884     offset_in_bytes += (GET_MODE_SIZE (TYPE_MODE (DECL_ARG_TYPE (parm)))
2885                         - GET_MODE_SIZE (GET_MODE (DECL_RTL (parm))));
2886
2887   return offset_in_bytes;
2888 }
2889
2890 static tree
2891 encode_method_prototype (method_decl, func_decl)
2892       tree method_decl;
2893       tree func_decl;
2894 {
2895   tree parms;
2896   int stack_size, i;
2897   tree user_args;
2898   HOST_WIDE_INT max_parm_end = 0;
2899   char buf[40];
2900   tree result;
2901
2902   /* ONEWAY and BYCOPY, for remote object are the only method qualifiers.  */
2903   encode_type_qualifiers (TREE_PURPOSE (TREE_TYPE (method_decl)));
2904
2905   /* C type.  */
2906   encode_type (TREE_TYPE (TREE_TYPE (func_decl)),
2907                obstack_object_size (&util_obstack),
2908                OBJC_ENCODE_INLINE_DEFS);
2909
2910   /* Stack size.  */
2911   for (parms = DECL_ARGUMENTS (func_decl); parms;
2912        parms = TREE_CHAIN (parms))
2913     {
2914       HOST_WIDE_INT parm_end = (forwarding_offset (parms)
2915                                 + int_size_in_bytes (TREE_TYPE (parms)));
2916
2917       if (!offset_is_register && max_parm_end < parm_end)
2918         max_parm_end = parm_end;
2919     }
2920
2921   stack_size = max_parm_end - OBJC_FORWARDING_MIN_OFFSET;
2922
2923   sprintf (buf, "%d", stack_size);
2924   obstack_grow (&util_obstack, buf, strlen (buf));
2925
2926   user_args = METHOD_SEL_ARGS (method_decl);
2927
2928   /* Argument types.  */
2929   for (parms = DECL_ARGUMENTS (func_decl), i = 0; parms;
2930        parms = TREE_CHAIN (parms), i++)
2931     {
2932       /* Process argument qualifiers for user supplied arguments.  */
2933       if (i > 1)
2934         {
2935           encode_type_qualifiers (TREE_PURPOSE (TREE_TYPE (user_args)));
2936           user_args = TREE_CHAIN (user_args);
2937         }
2938
2939       /* Type.  */
2940       encode_type (TREE_TYPE (parms),
2941                    obstack_object_size (&util_obstack),
2942                    OBJC_ENCODE_INLINE_DEFS);
2943
2944       /* Compute offset.  */
2945       sprintf (buf, "%d", forwarding_offset (parms));
2946
2947       /* Indicate register.  */
2948       if (offset_is_register)
2949         obstack_1grow (&util_obstack, '+');
2950       
2951       obstack_grow (&util_obstack, buf, strlen (buf));
2952     }
2953
2954   obstack_1grow (&util_obstack, '\0');
2955   result = get_identifier (obstack_finish (&util_obstack));
2956   obstack_free (&util_obstack, util_firstobj);
2957   return result;
2958 }
2959
2960 static tree
2961 generate_descriptor_table (type, name, size, list, proto)
2962      tree type;
2963      const char *name;
2964      int size;
2965      tree list;
2966      tree proto;
2967 {
2968   tree sc_spec, decl_specs, decl, initlist;
2969
2970   sc_spec = tree_cons (NULL_TREE, ridpointers[(int) RID_STATIC], NULL_TREE);
2971   decl_specs = tree_cons (NULL_TREE, type, sc_spec);
2972
2973   decl = start_decl (synth_id_with_class_suffix (name, proto),
2974                                 decl_specs, 1, NULL_TREE, NULL_TREE);
2975
2976   initlist = build_tree_list (NULL_TREE, build_int_2 (size, 0));
2977   initlist = tree_cons (NULL_TREE, list, initlist);
2978
2979   finish_decl (decl, build_constructor (type, nreverse (initlist)),
2980                NULL_TREE);
2981
2982   return decl;
2983 }
2984
2985 static void
2986 generate_method_descriptors (protocol)  /* generate_dispatch_tables */
2987   tree protocol;
2988 {
2989   static tree objc_method_prototype_template;
2990   tree initlist, chain, method_list_template;
2991   tree cast, variable_length_type;
2992   int size;
2993
2994   if (!objc_method_prototype_template)
2995     {
2996       objc_method_prototype_template = build_method_prototype_template ();
2997       ggc_add_tree_root (&objc_method_prototype_template, 1);
2998     }
2999
3000   cast = build_tree_list (build_tree_list (NULL_TREE, xref_tag (RECORD_TYPE,
3001                                 get_identifier (UTAG_METHOD_PROTOTYPE_LIST))),
3002                           NULL_TREE);
3003   variable_length_type = groktypename (cast);
3004
3005   chain = PROTOCOL_CLS_METHODS (protocol);
3006   if (chain)
3007     {
3008       size = list_length (chain);
3009
3010       method_list_template
3011         = build_method_prototype_list_template (objc_method_prototype_template,
3012                                                 size);
3013
3014       initlist 
3015         = build_descriptor_table_initializer (objc_method_prototype_template,
3016                                               chain);
3017
3018       UOBJC_CLASS_METHODS_decl
3019         = generate_descriptor_table (method_list_template,
3020                                      "_OBJC_PROTOCOL_CLASS_METHODS",
3021                                      size, initlist, protocol);
3022       TREE_TYPE (UOBJC_CLASS_METHODS_decl) = variable_length_type;
3023     }
3024   else
3025     UOBJC_CLASS_METHODS_decl = 0;
3026
3027   chain = PROTOCOL_NST_METHODS (protocol);
3028   if (chain)
3029     {
3030       size = list_length (chain);
3031
3032       method_list_template
3033         = build_method_prototype_list_template (objc_method_prototype_template,
3034                                                 size);
3035       initlist
3036         = build_descriptor_table_initializer (objc_method_prototype_template,
3037                                               chain);
3038
3039       UOBJC_INSTANCE_METHODS_decl
3040         = generate_descriptor_table (method_list_template,
3041                                      "_OBJC_PROTOCOL_INSTANCE_METHODS",
3042                                      size, initlist, protocol);
3043       TREE_TYPE (UOBJC_INSTANCE_METHODS_decl) = variable_length_type;
3044     }
3045   else
3046     UOBJC_INSTANCE_METHODS_decl = 0;
3047 }
3048
3049 static tree
3050 build_tmp_function_decl ()
3051 {
3052   tree decl_specs, expr_decl, parms;
3053   static int xxx = 0;
3054   char buffer[80];
3055
3056   /* struct objc_object *objc_xxx (id, SEL, ...); */
3057   pushlevel (0);
3058   decl_specs = build_tree_list (NULL_TREE, objc_object_reference);
3059   push_parm_decl (build_tree_list
3060                   (build_tree_list (decl_specs,
3061                                     build1 (INDIRECT_REF, NULL_TREE,
3062                                             NULL_TREE)),
3063                    build_tree_list (NULL_TREE, NULL_TREE)));
3064
3065   decl_specs = build_tree_list (NULL_TREE, xref_tag (RECORD_TYPE,
3066                                           get_identifier (TAG_SELECTOR)));
3067   expr_decl = build1 (INDIRECT_REF, NULL_TREE, NULL_TREE);
3068
3069   push_parm_decl (build_tree_list (build_tree_list (decl_specs, expr_decl),
3070                                    build_tree_list (NULL_TREE, NULL_TREE)));
3071   parms = get_parm_info (0);
3072   poplevel (0, 0, 0);
3073
3074   decl_specs = build_tree_list (NULL_TREE, objc_object_reference);
3075   sprintf (buffer, "__objc_tmp_%x", xxx++);
3076   expr_decl = build_nt (CALL_EXPR, get_identifier (buffer), parms, NULL_TREE);
3077   expr_decl = build1 (INDIRECT_REF, NULL_TREE, expr_decl);
3078
3079   return define_decl (expr_decl, decl_specs);
3080 }
3081
3082 static void
3083 hack_method_prototype (nst_methods, tmp_decl)
3084      tree nst_methods;
3085      tree tmp_decl;
3086 {
3087   tree parms;
3088   tree parm;
3089
3090   /* Hack to avoid problem with static typing of self arg.  */
3091   TREE_SET_CODE (nst_methods, CLASS_METHOD_DECL);
3092   start_method_def (nst_methods);
3093   TREE_SET_CODE (nst_methods, INSTANCE_METHOD_DECL);
3094
3095   if (METHOD_ADD_ARGS (nst_methods) == objc_ellipsis_node)
3096     parms = get_parm_info (0); /* we have a `, ...' */
3097   else
3098     parms = get_parm_info (1); /* place a `void_at_end' */
3099
3100   poplevel (0, 0, 0);   /* Must be called BEFORE start_function.  */
3101
3102   /* Usually called from store_parm_decls -> init_function_start.  */
3103
3104   DECL_ARGUMENTS (tmp_decl) = TREE_PURPOSE (parms);
3105   current_function_decl = tmp_decl;
3106
3107   {
3108     /* Code taken from start_function.  */
3109     tree restype = TREE_TYPE (TREE_TYPE (tmp_decl));
3110     /* Promote the value to int before returning it.  */
3111     if (TREE_CODE (restype) == INTEGER_TYPE
3112         && TYPE_PRECISION (restype) < TYPE_PRECISION (integer_type_node))
3113       restype = integer_type_node;
3114     DECL_RESULT (tmp_decl) = build_decl (RESULT_DECL, 0, restype);
3115   }
3116
3117   for (parm = DECL_ARGUMENTS (tmp_decl); parm; parm = TREE_CHAIN (parm))
3118     DECL_CONTEXT (parm) = tmp_decl;
3119
3120   init_function_start (tmp_decl, "objc-act", 0);
3121
3122   /* Typically called from expand_function_start for function definitions.  */
3123   assign_parms (tmp_decl);
3124
3125   /* install return type */
3126   TREE_TYPE (TREE_TYPE (tmp_decl)) = groktypename (TREE_TYPE (nst_methods));
3127
3128 }
3129
3130 static void
3131 generate_protocol_references (plist)
3132      tree plist;
3133 {
3134   tree lproto;
3135
3136   /* Forward declare protocols referenced.  */
3137   for (lproto = plist; lproto; lproto = TREE_CHAIN (lproto))
3138     {
3139       tree proto = TREE_VALUE (lproto);
3140
3141       if (TREE_CODE (proto) == PROTOCOL_INTERFACE_TYPE
3142           && PROTOCOL_NAME (proto))
3143         {
3144           if (! PROTOCOL_FORWARD_DECL (proto))
3145             build_protocol_reference (proto);
3146
3147           if (PROTOCOL_LIST (proto))
3148             generate_protocol_references (PROTOCOL_LIST (proto));
3149         }
3150     }
3151 }
3152
3153 static void
3154 generate_protocols ()
3155 {
3156   tree p, tmp_decl, encoding;
3157   tree sc_spec, decl_specs, decl;
3158   tree initlist, protocol_name_expr, refs_decl, refs_expr;
3159   tree cast_type2;
3160
3161   tmp_decl = build_tmp_function_decl ();
3162
3163   if (! objc_protocol_template)
3164     objc_protocol_template = build_protocol_template ();
3165
3166   /* If a protocol was directly referenced, pull in indirect references.  */
3167   for (p = protocol_chain; p; p = TREE_CHAIN (p))
3168     if (PROTOCOL_FORWARD_DECL (p) && PROTOCOL_LIST (p))
3169       generate_protocol_references (PROTOCOL_LIST (p));
3170
3171   for (p = protocol_chain; p; p = TREE_CHAIN (p))
3172     {
3173       tree nst_methods = PROTOCOL_NST_METHODS (p);
3174       tree cls_methods = PROTOCOL_CLS_METHODS (p);
3175
3176       /* If protocol wasn't referenced, don't generate any code.  */
3177       if (! PROTOCOL_FORWARD_DECL (p))
3178         continue;
3179
3180       /* Make sure we link in the Protocol class.  */
3181       add_class_reference (get_identifier (PROTOCOL_OBJECT_CLASS_NAME));
3182
3183       while (nst_methods)
3184         {
3185           if (! METHOD_ENCODING (nst_methods))
3186             {
3187               hack_method_prototype (nst_methods, tmp_decl);
3188               encoding = encode_method_prototype (nst_methods, tmp_decl);
3189               METHOD_ENCODING (nst_methods) = encoding;
3190             }
3191           nst_methods = TREE_CHAIN (nst_methods);
3192         }
3193
3194       while (cls_methods)
3195         {
3196           if (! METHOD_ENCODING (cls_methods))
3197             {
3198               hack_method_prototype (cls_methods, tmp_decl);
3199               encoding = encode_method_prototype (cls_methods, tmp_decl);
3200               METHOD_ENCODING (cls_methods) = encoding;
3201             }
3202
3203           cls_methods = TREE_CHAIN (cls_methods);
3204         }
3205       generate_method_descriptors (p);
3206
3207       if (PROTOCOL_LIST (p))
3208         refs_decl = generate_protocol_list (p);
3209       else
3210         refs_decl = 0;
3211
3212       /* static struct objc_protocol _OBJC_PROTOCOL_<mumble>; */
3213
3214       sc_spec = tree_cons (NULL_TREE, ridpointers[(int) RID_STATIC],
3215                            NULL_TREE);
3216       decl_specs = tree_cons (NULL_TREE, objc_protocol_template, sc_spec);
3217
3218       decl = start_decl (synth_id_with_class_suffix ("_OBJC_PROTOCOL", p),
3219                          decl_specs, 1, NULL_TREE, NULL_TREE);
3220
3221       protocol_name_expr = add_objc_string (PROTOCOL_NAME (p), class_names);
3222
3223       if (refs_decl)
3224         {
3225           cast_type2
3226             = groktypename
3227                 (build_tree_list (build_tree_list (NULL_TREE,
3228                                                    objc_protocol_template),
3229                                   build1 (INDIRECT_REF, NULL_TREE,
3230                                           build1 (INDIRECT_REF, NULL_TREE,
3231                                                   NULL_TREE))));
3232
3233           refs_expr = build_unary_op (ADDR_EXPR, refs_decl, 0);
3234           TREE_TYPE (refs_expr) = cast_type2;
3235         }
3236       else
3237         refs_expr = build_int_2 (0, 0);
3238
3239       /* UOBJC_INSTANCE_METHODS_decl/UOBJC_CLASS_METHODS_decl are set
3240          by generate_method_descriptors, which is called above.  */
3241       initlist = build_protocol_initializer (TREE_TYPE (decl),
3242                                              protocol_name_expr, refs_expr,
3243                                              UOBJC_INSTANCE_METHODS_decl,
3244                                              UOBJC_CLASS_METHODS_decl);
3245       finish_decl (decl, initlist, NULL_TREE);
3246
3247       /* Mark the decl as used to avoid "defined but not used" warning.  */
3248       TREE_USED (decl) = 1;
3249     }
3250 }
3251
3252 static tree
3253 build_protocol_initializer (type, protocol_name, protocol_list,
3254                             instance_methods, class_methods)
3255      tree type;
3256      tree protocol_name;
3257      tree protocol_list;
3258      tree instance_methods;
3259      tree class_methods;
3260 {
3261   tree initlist = NULL_TREE, expr;
3262   tree cast_type;
3263
3264   cast_type = groktypename
3265     (build_tree_list
3266      (build_tree_list (NULL_TREE,
3267                        xref_tag (RECORD_TYPE,
3268                                  get_identifier (UTAG_CLASS))),
3269       build1 (INDIRECT_REF, NULL_TREE, NULL_TREE)));
3270
3271   /* Filling the "isa" in with one allows the runtime system to
3272      detect that the version change...should remove before final release.  */
3273
3274   expr = build_int_2 (PROTOCOL_VERSION, 0);
3275   TREE_TYPE (expr) = cast_type;
3276   initlist = tree_cons (NULL_TREE, expr, initlist);
3277   initlist = tree_cons (NULL_TREE, protocol_name, initlist);
3278   initlist = tree_cons (NULL_TREE, protocol_list, initlist);
3279
3280   if (!instance_methods)
3281     initlist = tree_cons (NULL_TREE, build_int_2 (0, 0), initlist);
3282   else
3283     {
3284       expr = build_unary_op (ADDR_EXPR, instance_methods, 0);
3285       initlist = tree_cons (NULL_TREE, expr, initlist);
3286     }
3287
3288   if (!class_methods)
3289     initlist = tree_cons (NULL_TREE, build_int_2 (0, 0), initlist);
3290   else
3291     {
3292       expr = build_unary_op (ADDR_EXPR, class_methods, 0);
3293       initlist = tree_cons (NULL_TREE, expr, initlist);
3294     }
3295
3296   return build_constructor (type, nreverse (initlist));
3297 }
3298 \f
3299 /* struct objc_category {
3300      char *category_name;
3301      char *class_name;
3302      struct objc_method_list *instance_methods;
3303      struct objc_method_list *class_methods;
3304      struct objc_protocol_list *protocols;
3305    };   */
3306
3307 static void
3308 build_category_template ()
3309 {
3310   tree decl_specs, field_decl, field_decl_chain;
3311
3312   objc_category_template = start_struct (RECORD_TYPE,
3313                                          get_identifier (UTAG_CATEGORY));
3314   /* char *category_name; */
3315
3316   decl_specs = build_tree_list (NULL_TREE, ridpointers[(int) RID_CHAR]);
3317   field_decl
3318     = build1 (INDIRECT_REF, NULL_TREE, get_identifier ("category_name"));
3319   field_decl
3320     = grokfield (input_filename, lineno, field_decl, decl_specs, NULL_TREE);
3321   field_decl_chain = field_decl;
3322
3323   /* char *class_name; */
3324
3325   decl_specs = build_tree_list (NULL_TREE, ridpointers[(int) RID_CHAR]);
3326   field_decl = build1 (INDIRECT_REF, NULL_TREE, get_identifier ("class_name"));
3327   field_decl
3328     = grokfield (input_filename, lineno, field_decl, decl_specs, NULL_TREE);
3329   chainon (field_decl_chain, field_decl);
3330
3331   /* struct objc_method_list *instance_methods; */
3332
3333   decl_specs = build_tree_list (NULL_TREE,
3334                                 xref_tag (RECORD_TYPE,
3335                                           get_identifier (UTAG_METHOD_LIST)));
3336   field_decl
3337     = build1 (INDIRECT_REF, NULL_TREE, get_identifier ("instance_methods"));
3338   field_decl
3339     = grokfield (input_filename, lineno, field_decl, decl_specs, NULL_TREE);
3340   chainon (field_decl_chain, field_decl);
3341
3342   /* struct objc_method_list *class_methods; */
3343
3344   decl_specs = build_tree_list (NULL_TREE,
3345                                 xref_tag (RECORD_TYPE,
3346                                           get_identifier (UTAG_METHOD_LIST)));
3347   field_decl
3348     = build1 (INDIRECT_REF, NULL_TREE, get_identifier ("class_methods"));
3349   field_decl
3350     = grokfield (input_filename, lineno, field_decl, decl_specs, NULL_TREE);
3351   chainon (field_decl_chain, field_decl);
3352
3353   /* struct objc_protocol **protocol_list; */
3354
3355   decl_specs = build_tree_list (NULL_TREE,
3356                                 xref_tag (RECORD_TYPE,
3357                                           get_identifier (UTAG_PROTOCOL)));
3358   field_decl
3359     = build1 (INDIRECT_REF, NULL_TREE, get_identifier ("protocol_list"));
3360   field_decl = build1 (INDIRECT_REF, NULL_TREE, field_decl);
3361   field_decl
3362     = grokfield (input_filename, lineno, field_decl, decl_specs, NULL_TREE);
3363   chainon (field_decl_chain, field_decl);
3364
3365   finish_struct (objc_category_template, field_decl_chain, NULL_TREE);
3366 }
3367
3368 /* struct objc_selector {
3369      void *sel_id;
3370      char *sel_type;
3371    }; */
3372
3373 static void
3374 build_selector_template ()
3375 {
3376
3377   tree decl_specs, field_decl, field_decl_chain;
3378
3379   objc_selector_template 
3380     = start_struct (RECORD_TYPE, get_identifier (UTAG_SELECTOR));
3381
3382   /* void *sel_id; */
3383
3384   decl_specs = build_tree_list (NULL_TREE, ridpointers[(int) RID_VOID]);
3385   field_decl = build1 (INDIRECT_REF, NULL_TREE, get_identifier ("sel_id"));
3386   field_decl
3387     = grokfield (input_filename, lineno, field_decl, decl_specs, NULL_TREE);
3388   field_decl_chain = field_decl;
3389
3390   /* char *sel_type; */
3391
3392   decl_specs = build_tree_list (NULL_TREE, ridpointers[(int) RID_CHAR]);
3393   field_decl = build1 (INDIRECT_REF, NULL_TREE, get_identifier ("sel_type"));
3394   field_decl
3395     = grokfield (input_filename, lineno, field_decl, decl_specs, NULL_TREE);
3396   chainon (field_decl_chain, field_decl);
3397
3398   finish_struct (objc_selector_template, field_decl_chain, NULL_TREE);
3399 }
3400
3401 /* struct objc_class {
3402      struct objc_class *isa;
3403      struct objc_class *super_class;
3404      char *name;
3405      long version;
3406      long info;
3407      long instance_size;
3408      struct objc_ivar_list *ivars;
3409      struct objc_method_list *methods;
3410      if (flag_next_runtime)
3411        struct objc_cache *cache;
3412      else {
3413        struct sarray *dtable;
3414        struct objc_class *subclass_list;
3415        struct objc_class *sibling_class;
3416      }
3417      struct objc_protocol_list *protocols;
3418      void *gc_object_type;
3419    };  */
3420
3421 static void
3422 build_class_template ()
3423 {
3424   tree decl_specs, field_decl, field_decl_chain;
3425
3426   objc_class_template
3427     = start_struct (RECORD_TYPE, get_identifier (UTAG_CLASS));
3428
3429   /* struct objc_class *isa; */
3430
3431   decl_specs = build_tree_list (NULL_TREE, objc_class_template);
3432   field_decl = build1 (INDIRECT_REF, NULL_TREE, get_identifier ("isa"));
3433   field_decl
3434     = grokfield (input_filename, lineno, field_decl, decl_specs, NULL_TREE);
3435   field_decl_chain = field_decl;
3436
3437   /* struct objc_class *super_class; */
3438
3439   decl_specs = build_tree_list (NULL_TREE, objc_class_template);
3440   field_decl
3441     = build1 (INDIRECT_REF, NULL_TREE, get_identifier ("super_class"));
3442   field_decl
3443     = grokfield (input_filename, lineno, field_decl, decl_specs, NULL_TREE);
3444   chainon (field_decl_chain, field_decl);
3445
3446   /* char *name; */
3447
3448   decl_specs = build_tree_list (NULL_TREE, ridpointers[(int) RID_CHAR]);
3449   field_decl = build1 (INDIRECT_REF, NULL_TREE, get_identifier ("name"));
3450   field_decl
3451     = grokfield (input_filename, lineno, field_decl, decl_specs, NULL_TREE);
3452   chainon (field_decl_chain, field_decl);
3453
3454   /* long version; */
3455
3456   decl_specs = build_tree_list (NULL_TREE, ridpointers[(int) RID_LONG]);
3457   field_decl = get_identifier ("version");
3458   field_decl
3459     = grokfield (input_filename, lineno, field_decl, decl_specs, NULL_TREE);
3460   chainon (field_decl_chain, field_decl);
3461
3462   /* long info; */
3463
3464   decl_specs = build_tree_list (NULL_TREE, ridpointers[(int) RID_LONG]);
3465   field_decl = get_identifier ("info");
3466   field_decl
3467     = grokfield (input_filename, lineno, field_decl, decl_specs, NULL_TREE);
3468   chainon (field_decl_chain, field_decl);
3469
3470   /* long instance_size; */
3471
3472   decl_specs = build_tree_list (NULL_TREE, ridpointers[(int) RID_LONG]);
3473   field_decl = get_identifier ("instance_size");
3474   field_decl
3475     = grokfield (input_filename, lineno, field_decl, decl_specs, NULL_TREE);
3476   chainon (field_decl_chain, field_decl);
3477
3478   /* struct objc_ivar_list *ivars; */
3479
3480   decl_specs = build_tree_list (NULL_TREE,
3481                                 xref_tag (RECORD_TYPE,
3482                                           get_identifier (UTAG_IVAR_LIST)));
3483   field_decl = build1 (INDIRECT_REF, NULL_TREE, get_identifier ("ivars"));
3484   field_decl
3485     = grokfield (input_filename, lineno, field_decl, decl_specs, NULL_TREE);
3486   chainon (field_decl_chain, field_decl);
3487
3488   /* struct objc_method_list *methods; */
3489
3490   decl_specs = build_tree_list (NULL_TREE,
3491                                 xref_tag (RECORD_TYPE,
3492                                           get_identifier (UTAG_METHOD_LIST)));
3493   field_decl = build1 (INDIRECT_REF, NULL_TREE, get_identifier ("methods"));
3494   field_decl
3495     = grokfield (input_filename, lineno, field_decl, decl_specs, NULL_TREE);
3496   chainon (field_decl_chain, field_decl);
3497
3498   if (flag_next_runtime)
3499     {
3500       /* struct objc_cache *cache; */
3501
3502       decl_specs = build_tree_list (NULL_TREE,
3503                                     xref_tag (RECORD_TYPE,
3504                                               get_identifier ("objc_cache")));
3505       field_decl = build1 (INDIRECT_REF, NULL_TREE, get_identifier ("cache"));
3506       field_decl = grokfield (input_filename, lineno, field_decl,
3507                               decl_specs, NULL_TREE);
3508       chainon (field_decl_chain, field_decl);
3509     }
3510   else
3511     {
3512       /* struct sarray *dtable; */
3513
3514       decl_specs = build_tree_list (NULL_TREE,
3515                                     xref_tag (RECORD_TYPE,
3516                                               get_identifier ("sarray")));
3517       field_decl = build1 (INDIRECT_REF, NULL_TREE, get_identifier ("dtable"));
3518       field_decl = grokfield (input_filename, lineno, field_decl,
3519                               decl_specs, NULL_TREE);
3520       chainon (field_decl_chain, field_decl);
3521
3522       /* struct objc_class *subclass_list; */
3523
3524       decl_specs = build_tree_list (NULL_TREE, objc_class_template);
3525       field_decl
3526         = build1 (INDIRECT_REF, NULL_TREE, get_identifier ("subclass_list"));
3527       field_decl = grokfield (input_filename, lineno, field_decl,
3528                               decl_specs, NULL_TREE);
3529       chainon (field_decl_chain, field_decl);
3530
3531       /* struct objc_class *sibling_class; */
3532
3533       decl_specs = build_tree_list (NULL_TREE, objc_class_template);
3534       field_decl
3535         = build1 (INDIRECT_REF, NULL_TREE, get_identifier ("sibling_class"));
3536       field_decl = grokfield (input_filename, lineno, field_decl,
3537                               decl_specs, NULL_TREE);
3538       chainon (field_decl_chain, field_decl);
3539     }
3540
3541   /* struct objc_protocol **protocol_list; */
3542
3543   decl_specs = build_tree_list (NULL_TREE, 
3544                                 xref_tag (RECORD_TYPE,
3545                                           get_identifier (UTAG_PROTOCOL)));
3546   field_decl
3547     = build1 (INDIRECT_REF, NULL_TREE, get_identifier ("protocol_list"));
3548   field_decl
3549     = build1 (INDIRECT_REF, NULL_TREE, field_decl);
3550   field_decl = grokfield (input_filename, lineno, field_decl,
3551                           decl_specs, NULL_TREE);
3552   chainon (field_decl_chain, field_decl);