OSDN Git Service

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