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