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