Avoid unnecessary dependencies on COND_EXEC insns.
[official-gcc.git] / gcc / objc / objc-act.c
blob5b6e33a85083f91e1244e5ce05509a8f51482ebb
1 /* Implement classes and message passing for Objective C.
2 Copyright (C) 1992, 1993, 1994, 1995, 1997, 1998,
3 1999, 2000 Free Software Foundation, Inc.
4 Contributed by Steve Naroff.
6 This file is part of GNU CC.
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.
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.
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. */
23 /* Purpose: This module implements the Objective-C 4.0 language.
25 compatibility issues (with the Stepstone translator):
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.
38 code generation `options':
40 - OBJC_INT_SELECTORS */
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"
60 /* This is the default way of generating a method name. */
61 /* I am not sure it is really correct.
62 Perhaps there's a danger that it will make name conflicts
63 if method names contain underscores. -- rms. */
64 #ifndef OBJC_GEN_METHOD_LABEL
65 #define OBJC_GEN_METHOD_LABEL(BUF, IS_INST, CLASS_NAME, CAT_NAME, SEL_NAME, NUM) \
66 do { \
67 char *temp; \
68 sprintf ((BUF), "_%s_%s_%s_%s", \
69 ((IS_INST) ? "i" : "c"), \
70 (CLASS_NAME), \
71 ((CAT_NAME)? (CAT_NAME) : ""), \
72 (SEL_NAME)); \
73 for (temp = (BUF); *temp; temp++) \
74 if (*temp == ':') *temp = '_'; \
75 } while (0)
76 #endif
78 /* These need specifying. */
79 #ifndef OBJC_FORWARDING_STACK_OFFSET
80 #define OBJC_FORWARDING_STACK_OFFSET 0
81 #endif
83 #ifndef OBJC_FORWARDING_MIN_OFFSET
84 #define OBJC_FORWARDING_MIN_OFFSET 0
85 #endif
87 /* Define the special tree codes that we use. */
89 /* Table indexed by tree code giving a string containing a character
90 classifying the tree code. Possibilities are
91 t, d, s, c, r, <, 1 and 2. See objc-tree.def for details. */
93 #define DEFTREECODE(SYM, NAME, TYPE, LENGTH) TYPE,
95 static const char objc_tree_code_type[] = {
96 'x',
97 #include "objc-tree.def"
99 #undef DEFTREECODE
101 /* Table indexed by tree code giving number of expression
102 operands beyond the fixed part of the node structure.
103 Not used for types or decls. */
105 #define DEFTREECODE(SYM, NAME, TYPE, LENGTH) LENGTH,
107 static const int objc_tree_code_length[] = {
109 #include "objc-tree.def"
111 #undef DEFTREECODE
113 /* Names of tree components.
114 Used for printing out the tree and error messages. */
115 #define DEFTREECODE(SYM, NAME, TYPE, LEN) NAME,
117 static const char * const objc_tree_code_name[] = {
118 "@@dummy",
119 #include "objc-tree.def"
121 #undef DEFTREECODE
123 /* Set up for use of obstacks. */
125 #include "obstack.h"
127 #define obstack_chunk_alloc xmalloc
128 #define obstack_chunk_free free
130 /* This obstack is used to accumulate the encoding of a data type. */
131 static struct obstack util_obstack;
132 /* This points to the beginning of obstack contents,
133 so we can free the whole contents. */
134 char *util_firstobj;
136 /* for encode_method_def */
137 #include "rtl.h"
139 #define OBJC_VERSION (flag_next_runtime ? 5 : 8)
140 #define PROTOCOL_VERSION 2
142 #define OBJC_ENCODE_INLINE_DEFS 0
143 #define OBJC_ENCODE_DONT_INLINE_DEFS 1
145 /*** Private Interface (procedures) ***/
147 /* Used by compile_file. */
149 static void init_objc PARAMS ((void));
150 static void finish_objc PARAMS ((void));
152 /* Code generation. */
154 static void synth_module_prologue PARAMS ((void));
155 static tree build_constructor PARAMS ((tree, tree));
156 static const char *build_module_descriptor PARAMS ((void));
157 static tree init_module_descriptor PARAMS ((tree));
158 static tree build_objc_method_call PARAMS ((int, tree, tree,
159 tree, tree, tree));
160 static void generate_strings PARAMS ((void));
161 static tree get_proto_encoding PARAMS ((tree));
162 static void build_selector_translation_table PARAMS ((void));
163 static tree build_ivar_chain PARAMS ((tree, int));
165 static tree objc_add_static_instance PARAMS ((tree, tree));
167 static tree build_ivar_template PARAMS ((void));
168 static tree build_method_template PARAMS ((void));
169 static tree build_private_template PARAMS ((tree));
170 static void build_class_template PARAMS ((void));
171 static void build_selector_template PARAMS ((void));
172 static void build_category_template PARAMS ((void));
173 static tree build_super_template PARAMS ((void));
174 static tree build_category_initializer PARAMS ((tree, tree, tree,
175 tree, tree, tree));
176 static tree build_protocol_initializer PARAMS ((tree, tree, tree,
177 tree, tree));
179 static void synth_forward_declarations PARAMS ((void));
180 static void generate_ivar_lists PARAMS ((void));
181 static void generate_dispatch_tables PARAMS ((void));
182 static void generate_shared_structures PARAMS ((void));
183 static tree generate_protocol_list PARAMS ((tree));
184 static void generate_forward_declaration_to_string_table PARAMS ((void));
185 static void build_protocol_reference PARAMS ((tree));
187 #if 0
188 static tree init_selector PARAMS ((int));
189 #endif
190 static tree build_keyword_selector PARAMS ((tree));
191 static tree synth_id_with_class_suffix PARAMS ((const char *, tree));
193 static void generate_static_references PARAMS ((void));
194 static int check_methods_accessible PARAMS ((tree, tree,
195 int));
196 static void encode_aggregate_within PARAMS ((tree, int, int,
197 int, int));
198 static const char *objc_demangle PARAMS ((const char *));
199 static const char *objc_printable_name PARAMS ((tree, int));
200 static void objc_expand_function_end PARAMS ((void));
202 /* Misc. bookkeeping */
204 typedef struct hashed_entry *hash;
205 typedef struct hashed_attribute *attr;
207 struct hashed_attribute
209 attr next;
210 tree value;
212 struct hashed_entry
214 attr list;
215 hash next;
216 tree key;
219 static void hash_init PARAMS ((void));
220 static void hash_enter PARAMS ((hash *, tree));
221 static hash hash_lookup PARAMS ((hash *, tree));
222 static void hash_add_attr PARAMS ((hash, tree));
223 static tree lookup_method PARAMS ((tree, tree));
224 static tree lookup_instance_method_static PARAMS ((tree, tree));
225 static tree lookup_class_method_static PARAMS ((tree, tree));
226 static tree add_class PARAMS ((tree));
227 static void add_category PARAMS ((tree, tree));
229 enum string_section
231 class_names, /* class, category, protocol, module names */
232 meth_var_names, /* method and variable names */
233 meth_var_types /* method and variable type descriptors */
236 static tree add_objc_string PARAMS ((tree,
237 enum string_section));
238 static tree get_objc_string_decl PARAMS ((tree,
239 enum string_section));
240 static tree build_objc_string_decl PARAMS ((enum string_section));
241 static tree build_selector_reference_decl PARAMS ((void));
243 /* Protocol additions. */
245 static tree add_protocol PARAMS ((tree));
246 static tree lookup_protocol PARAMS ((tree));
247 static tree lookup_and_install_protocols PARAMS ((tree));
249 /* Type encoding. */
251 static void encode_type_qualifiers PARAMS ((tree));
252 static void encode_pointer PARAMS ((tree, int, int));
253 static void encode_array PARAMS ((tree, int, int));
254 static void encode_aggregate PARAMS ((tree, int, int));
255 static void encode_bitfield PARAMS ((int));
256 static void encode_type PARAMS ((tree, int, int));
257 static void encode_field_decl PARAMS ((tree, int, int));
259 static void really_start_method PARAMS ((tree, tree));
260 static int comp_method_with_proto PARAMS ((tree, tree));
261 static int comp_proto_with_proto PARAMS ((tree, tree));
262 static tree get_arg_type_list PARAMS ((tree, int, int));
263 static tree expr_last PARAMS ((tree));
265 /* Utilities for debugging and error diagnostics. */
267 static void warn_with_method PARAMS ((const char *, int, tree));
268 static void error_with_ivar PARAMS ((const char *, tree, tree));
269 static char *gen_method_decl PARAMS ((tree, char *));
270 static char *gen_declaration PARAMS ((tree, char *));
271 static char *gen_declarator PARAMS ((tree, char *,
272 const char *));
273 static int is_complex_decl PARAMS ((tree));
274 static void adorn_decl PARAMS ((tree, char *));
275 static void dump_interface PARAMS ((FILE *, tree));
277 /* Everything else. */
279 static tree define_decl PARAMS ((tree, tree));
280 static tree lookup_method_in_protocol_list PARAMS ((tree, tree, int));
281 static tree lookup_protocol_in_reflist PARAMS ((tree, tree));
282 static tree create_builtin_decl PARAMS ((enum tree_code,
283 tree, const char *));
284 static tree my_build_string PARAMS ((int, const char *));
285 static void build_objc_symtab_template PARAMS ((void));
286 static tree init_def_list PARAMS ((tree));
287 static tree init_objc_symtab PARAMS ((tree));
288 static void forward_declare_categories PARAMS ((void));
289 static void generate_objc_symtab_decl PARAMS ((void));
290 static tree build_selector PARAMS ((tree));
291 #if 0
292 static tree build_msg_pool_reference PARAMS ((int));
293 #endif
294 static tree build_typed_selector_reference PARAMS ((tree, tree));
295 static tree build_selector_reference PARAMS ((tree));
296 static tree build_class_reference_decl PARAMS ((void));
297 static void add_class_reference PARAMS ((tree));
298 static tree objc_copy_list PARAMS ((tree, tree *));
299 static tree build_protocol_template PARAMS ((void));
300 static tree build_descriptor_table_initializer PARAMS ((tree, tree));
301 static tree build_method_prototype_list_template PARAMS ((tree, int));
302 static tree build_method_prototype_template PARAMS ((void));
303 static int forwarding_offset PARAMS ((tree));
304 static tree encode_method_prototype PARAMS ((tree, tree));
305 static tree generate_descriptor_table PARAMS ((tree, const char *,
306 int, tree, tree));
307 static void generate_method_descriptors PARAMS ((tree));
308 static tree build_tmp_function_decl PARAMS ((void));
309 static void hack_method_prototype PARAMS ((tree, tree));
310 static void generate_protocol_references PARAMS ((tree));
311 static void generate_protocols PARAMS ((void));
312 static void check_ivars PARAMS ((tree, tree));
313 static tree build_ivar_list_template PARAMS ((tree, int));
314 static tree build_method_list_template PARAMS ((tree, int));
315 static tree build_ivar_list_initializer PARAMS ((tree, tree));
316 static tree generate_ivars_list PARAMS ((tree, const char *,
317 int, tree));
318 static tree build_dispatch_table_initializer PARAMS ((tree, tree));
319 static tree generate_dispatch_table PARAMS ((tree, const char *,
320 int, tree));
321 static tree build_shared_structure_initializer PARAMS ((tree, tree, tree, tree,
322 tree, int, tree, tree,
323 tree));
324 static void generate_category PARAMS ((tree));
325 static int is_objc_type_qualifier PARAMS ((tree));
326 static tree adjust_type_for_id_default PARAMS ((tree));
327 static tree check_duplicates PARAMS ((hash));
328 static tree receiver_is_class_object PARAMS ((tree));
329 static int check_methods PARAMS ((tree, tree, int));
330 static int conforms_to_protocol PARAMS ((tree, tree));
331 static void check_protocols PARAMS ((tree, const char *,
332 const char *));
333 static tree encode_method_def PARAMS ((tree));
334 static void gen_declspecs PARAMS ((tree, char *, int));
335 static void generate_classref_translation_entry PARAMS ((tree));
336 static void handle_class_ref PARAMS ((tree));
337 static void generate_struct_by_value_array PARAMS ((void))
338 ATTRIBUTE_NORETURN;
339 static void objc_act_parse_init PARAMS ((void));
340 static void ggc_mark_imp_list PARAMS ((void *));
341 static void ggc_mark_hash_table PARAMS ((void *));
343 /*** Private Interface (data) ***/
345 /* Reserved tag definitions. */
347 #define TYPE_ID "id"
348 #define TAG_OBJECT "objc_object"
349 #define TAG_CLASS "objc_class"
350 #define TAG_SUPER "objc_super"
351 #define TAG_SELECTOR "objc_selector"
353 #define UTAG_CLASS "_objc_class"
354 #define UTAG_IVAR "_objc_ivar"
355 #define UTAG_IVAR_LIST "_objc_ivar_list"
356 #define UTAG_METHOD "_objc_method"
357 #define UTAG_METHOD_LIST "_objc_method_list"
358 #define UTAG_CATEGORY "_objc_category"
359 #define UTAG_MODULE "_objc_module"
360 #define UTAG_STATICS "_objc_statics"
361 #define UTAG_SYMTAB "_objc_symtab"
362 #define UTAG_SUPER "_objc_super"
363 #define UTAG_SELECTOR "_objc_selector"
365 #define UTAG_PROTOCOL "_objc_protocol"
366 #define UTAG_PROTOCOL_LIST "_objc_protocol_list"
367 #define UTAG_METHOD_PROTOTYPE "_objc_method_prototype"
368 #define UTAG_METHOD_PROTOTYPE_LIST "_objc__method_prototype_list"
370 #define STRING_OBJECT_CLASS_NAME "NXConstantString"
371 #define PROTOCOL_OBJECT_CLASS_NAME "Protocol"
373 static const char *constant_string_class_name = NULL;
375 static const char *TAG_GETCLASS;
376 static const char *TAG_GETMETACLASS;
377 static const char *TAG_MSGSEND;
378 static const char *TAG_MSGSENDSUPER;
379 static const char *TAG_EXECCLASS;
381 /* Set by `continue_class' and checked by `is_public'. */
383 #define TREE_STATIC_TEMPLATE(record_type) (TREE_PUBLIC (record_type))
384 #define TYPED_OBJECT(type) \
385 (TREE_CODE (type) == RECORD_TYPE && TREE_STATIC_TEMPLATE (type))
387 tree objc_ellipsis_node;
389 enum objc_tree_index
391 OCTI_STATIC_NST,
392 OCTI_STATIC_NST_DECL,
393 OCTI_SELF_ID,
394 OCTI_UCMD_ID,
395 OCTI_UNUSED_LIST,
396 OCTI_SELF_DECL,
397 OCTI_UMSG_DECL,
398 OCTI_UMSG_SUPER_DECL,
399 OCTI_GET_CLASS_DECL,
400 OCTI_GET_MCLASS_DECL,
401 OCTI_SUPER_TYPE,
402 OCTI_SEL_TYPE,
403 OCTI_ID_TYPE,
404 OCTI_CLS_TYPE,
405 OCTI_NST_TYPE,
406 OCTI_PROTO_TYPE,
408 OCTI_CLS_CHAIN,
409 OCTI_ALIAS_CHAIN,
410 OCTI_INTF_CHAIN,
411 OCTI_PROTO_CHAIN,
412 OCTI_CLS_REF_CHAIN,
413 OCTI_SEL_REF_CHAIN,
414 OCTI_CLS_NAMES_CHAIN,
415 OCTI_METH_VAR_NAMES_CHAIN,
416 OCTI_METH_VAR_TYPES_CHAIN,
418 OCTI_SYMBOLS_DECL,
419 OCTI_NST_VAR_DECL,
420 OCTI_CLS_VAR_DECL,
421 OCTI_NST_METH_DECL,
422 OCTI_CLS_METH_DECL,
423 OCTI_CLS_DECL,
424 OCTI_MCLS_DECL,
425 OCTI_SEL_TABLE_DECL,
426 OCTI_MODULES_DECL,
427 OCTI_STRG_DECL,
429 OCTI_IMPL_CTX,
430 OCTI_IMPL_TEMPL,
432 OCTI_CLS_TEMPL,
433 OCTI_CAT_TEMPL,
434 OCTI_UPRIV_REC,
435 OCTI_PROTO_TEMPL,
436 OCTI_SEL_TEMPL,
437 OCTI_UCLS_SUPER_REF,
438 OCTI_UUCLS_SUPER_REF,
439 OCTI_METH_TEMPL,
440 OCTI_IVAR_TEMPL,
441 OCTI_SYMTAB_TEMPL,
442 OCTI_MODULE_TEMPL,
443 OCTI_SUPER_TEMPL,
444 OCTI_OBJ_REF,
445 OCTI_OBJ_ID,
446 OCTI_CLS_ID,
447 OCTI_ID_ID,
448 OCTI_CNST_STR_ID,
449 OCTI_CNST_STR_TYPE,
450 OCTI_SUPER_DECL,
451 OCTI_METH_CTX,
453 OCTI_MAX
456 static tree objc_global_trees[OCTI_MAX];
458 /* List of classes with list of their static instances. */
459 #define objc_static_instances objc_global_trees[OCTI_STATIC_NST]
461 /* The declaration of the array administrating the static instances. */
462 #define static_instances_decl objc_global_trees[OCTI_STATIC_NST_DECL]
464 /* Some commonly used instances of "identifier_node". */
466 #define self_id objc_global_trees[OCTI_SELF_ID]
467 #define ucmd_id objc_global_trees[OCTI_UCMD_ID]
468 #define unused_list objc_global_trees[OCTI_UNUSED_LIST]
470 #define self_decl objc_global_trees[OCTI_SELF_DECL]
471 #define umsg_decl objc_global_trees[OCTI_UMSG_DECL]
472 #define umsg_super_decl objc_global_trees[OCTI_UMSG_SUPER_DECL]
473 #define objc_get_class_decl objc_global_trees[OCTI_GET_CLASS_DECL]
474 #define objc_get_meta_class_decl \
475 objc_global_trees[OCTI_GET_MCLASS_DECL]
477 #define super_type objc_global_trees[OCTI_SUPER_TYPE]
478 #define selector_type objc_global_trees[OCTI_SEL_TYPE]
479 #define id_type objc_global_trees[OCTI_ID_TYPE]
480 #define objc_class_type objc_global_trees[OCTI_CLS_TYPE]
481 #define instance_type objc_global_trees[OCTI_NST_TYPE]
482 #define protocol_type objc_global_trees[OCTI_PROTO_TYPE]
484 /* Type checking macros. */
486 #define IS_ID(TYPE) \
487 (TYPE_MAIN_VARIANT (TYPE) == TYPE_MAIN_VARIANT (id_type))
488 #define IS_PROTOCOL_QUALIFIED_ID(TYPE) \
489 (IS_ID (TYPE) && TYPE_PROTOCOL_LIST (TYPE))
490 #define IS_SUPER(TYPE) \
491 (super_type && TYPE_MAIN_VARIANT (TYPE) == TYPE_MAIN_VARIANT (super_type))
493 #define class_chain objc_global_trees[OCTI_CLS_CHAIN]
494 #define alias_chain objc_global_trees[OCTI_ALIAS_CHAIN]
495 #define interface_chain objc_global_trees[OCTI_INTF_CHAIN]
496 #define protocol_chain objc_global_trees[OCTI_PROTO_CHAIN]
498 /* Chains to manage selectors that are referenced and defined in the
499 module. */
501 #define cls_ref_chain objc_global_trees[OCTI_CLS_REF_CHAIN] /* Classes referenced. */
502 #define sel_ref_chain objc_global_trees[OCTI_SEL_REF_CHAIN] /* Selectors referenced. */
504 /* Chains to manage uniquing of strings. */
506 #define class_names_chain objc_global_trees[OCTI_CLS_NAMES_CHAIN]
507 #define meth_var_names_chain objc_global_trees[OCTI_METH_VAR_NAMES_CHAIN]
508 #define meth_var_types_chain objc_global_trees[OCTI_METH_VAR_TYPES_CHAIN]
510 /* Hash tables to manage the global pool of method prototypes. */
512 static hash *nst_method_hash_list = 0;
513 static hash *cls_method_hash_list = 0;
515 /* Backend data declarations. */
517 #define UOBJC_SYMBOLS_decl objc_global_trees[OCTI_SYMBOLS_DECL]
518 #define UOBJC_INSTANCE_VARIABLES_decl objc_global_trees[OCTI_NST_VAR_DECL]
519 #define UOBJC_CLASS_VARIABLES_decl objc_global_trees[OCTI_CLS_VAR_DECL]
520 #define UOBJC_INSTANCE_METHODS_decl objc_global_trees[OCTI_NST_METH_DECL]
521 #define UOBJC_CLASS_METHODS_decl objc_global_trees[OCTI_CLS_METH_DECL]
522 #define UOBJC_CLASS_decl objc_global_trees[OCTI_CLS_DECL]
523 #define UOBJC_METACLASS_decl objc_global_trees[OCTI_MCLS_DECL]
524 #define UOBJC_SELECTOR_TABLE_decl objc_global_trees[OCTI_SEL_TABLE_DECL]
525 #define UOBJC_MODULES_decl objc_global_trees[OCTI_MODULES_DECL]
526 #define UOBJC_STRINGS_decl objc_global_trees[OCTI_STRG_DECL]
528 /* The following are used when compiling a class implementation.
529 implementation_template will normally be an interface, however if
530 none exists this will be equal to implementation_context...it is
531 set in start_class. */
533 #define implementation_context objc_global_trees[OCTI_IMPL_CTX]
534 #define implementation_template objc_global_trees[OCTI_IMPL_TEMPL]
536 struct imp_entry
538 struct imp_entry *next;
539 tree imp_context;
540 tree imp_template;
541 tree class_decl; /* _OBJC_CLASS_<my_name>; */
542 tree meta_decl; /* _OBJC_METACLASS_<my_name>; */
545 static void handle_impent PARAMS ((struct imp_entry *));
547 static struct imp_entry *imp_list = 0;
548 static int imp_count = 0; /* `@implementation' */
549 static int cat_count = 0; /* `@category' */
551 #define objc_class_template objc_global_trees[OCTI_CLS_TEMPL]
552 #define objc_category_template objc_global_trees[OCTI_CAT_TEMPL]
553 #define uprivate_record objc_global_trees[OCTI_UPRIV_REC]
554 #define objc_protocol_template objc_global_trees[OCTI_PROTO_TEMPL]
555 #define objc_selector_template objc_global_trees[OCTI_SEL_TEMPL]
556 #define ucls_super_ref objc_global_trees[OCTI_UCLS_SUPER_REF]
557 #define uucls_super_ref objc_global_trees[OCTI_UUCLS_SUPER_REF]
559 #define objc_method_template objc_global_trees[OCTI_METH_TEMPL]
560 #define objc_ivar_template objc_global_trees[OCTI_IVAR_TEMPL]
561 #define objc_symtab_template objc_global_trees[OCTI_SYMTAB_TEMPL]
562 #define objc_module_template objc_global_trees[OCTI_MODULE_TEMPL]
563 #define objc_super_template objc_global_trees[OCTI_SUPER_TEMPL]
564 #define objc_object_reference objc_global_trees[OCTI_OBJ_REF]
566 #define objc_object_id objc_global_trees[OCTI_OBJ_ID]
567 #define objc_class_id objc_global_trees[OCTI_CLS_ID]
568 #define objc_id_id objc_global_trees[OCTI_ID_ID]
569 #define constant_string_id objc_global_trees[OCTI_CNST_STR_ID]
570 #define constant_string_type objc_global_trees[OCTI_CNST_STR_TYPE]
571 #define UOBJC_SUPER_decl objc_global_trees[OCTI_SUPER_DECL]
573 #define method_context objc_global_trees[OCTI_METH_CTX]
574 static int method_slot = 0; /* Used by start_method_def, */
576 #define BUFSIZE 1024
578 static char *errbuf; /* Buffer for error diagnostics */
580 /* Data imported from tree.c. */
582 extern enum debug_info_type write_symbols;
584 /* Data imported from toplev.c. */
586 extern const char *dump_base_name;
588 /* Generate code for GNU or NeXT runtime environment. */
590 #ifdef NEXT_OBJC_RUNTIME
591 int flag_next_runtime = 1;
592 #else
593 int flag_next_runtime = 0;
594 #endif
596 int flag_typed_selectors;
598 /* Open and close the file for outputting class declarations, if requested. */
600 int flag_gen_declaration = 0;
602 FILE *gen_declaration_file;
604 /* Warn if multiple methods are seen for the same selector, but with
605 different argument types. */
607 int warn_selector = 0;
609 /* Warn if methods required by a protocol are not implemented in the
610 class adopting it. When turned off, methods inherited to that
611 class are also considered implemented */
613 int flag_warn_protocol = 1;
615 /* Tells "encode_pointer/encode_aggregate" whether we are generating
616 type descriptors for instance variables (as opposed to methods).
617 Type descriptors for instance variables contain more information
618 than methods (for static typing and embedded structures). This
619 was added to support features being planned for dbkit2. */
621 static int generating_instance_variables = 0;
623 /* Tells the compiler that this is a special run. Do not perform
624 any compiling, instead we are to test some platform dependent
625 features and output a C header file with appropriate definitions. */
627 static int print_struct_values = 0;
629 /* Some platforms pass small structures through registers versus through
630 an invisible pointer. Determine at what size structure is the
631 transition point between the two possibilities. */
633 static void
634 generate_struct_by_value_array ()
636 tree type;
637 tree field_decl, field_decl_chain;
638 int i, j;
639 int aggregate_in_mem[32];
640 int found = 0;
642 /* Presumbaly no platform passes 32 byte structures in a register. */
643 for (i = 1; i < 32; i++)
645 char buffer[5];
647 /* Create an unnamed struct that has `i' character components */
648 type = start_struct (RECORD_TYPE, NULL_TREE);
650 strcpy (buffer, "c1");
651 field_decl = create_builtin_decl (FIELD_DECL,
652 char_type_node,
653 buffer);
654 field_decl_chain = field_decl;
656 for (j = 1; j < i; j++)
658 sprintf (buffer, "c%d", j + 1);
659 field_decl = create_builtin_decl (FIELD_DECL,
660 char_type_node,
661 buffer);
662 chainon (field_decl_chain, field_decl);
664 finish_struct (type, field_decl_chain, NULL_TREE);
666 aggregate_in_mem[i] = aggregate_value_p (type);
667 if (!aggregate_in_mem[i])
668 found = 1;
671 /* We found some structures that are returned in registers instead of memory
672 so output the necessary data. */
673 if (found)
675 for (i = 31; i >= 0; i--)
676 if (!aggregate_in_mem[i])
677 break;
678 printf ("#define OBJC_MAX_STRUCT_BY_VALUE %d\n\n", i);
680 /* The first member of the structure is always 0 because we don't handle
681 structures with 0 members */
682 printf ("static int struct_forward_array[] = {\n 0");
684 for (j = 1; j <= i; j++)
685 printf (", %d", aggregate_in_mem[j]);
686 printf ("\n};\n");
689 exit (0);
692 void
693 lang_init_options ()
695 parse_in = cpp_create_reader (CLK_OBJC);
696 c_language = clk_objective_c;
699 void
700 lang_init ()
702 /* Force the line number back to 0; check_newline will have
703 raised it to 1, which will make the builtin functions appear
704 not to be built in. */
705 lineno = 0;
707 /* If gen_declaration desired, open the output file. */
708 if (flag_gen_declaration)
710 register char * const dumpname = concat (dumpname, ".decl", NULL);
711 gen_declaration_file = fopen (dumpname, "w");
712 if (gen_declaration_file == 0)
713 pfatal_with_name (dumpname);
714 free (dumpname);
717 if (flag_next_runtime)
719 TAG_GETCLASS = "objc_getClass";
720 TAG_GETMETACLASS = "objc_getMetaClass";
721 TAG_MSGSEND = "objc_msgSend";
722 TAG_MSGSENDSUPER = "objc_msgSendSuper";
723 TAG_EXECCLASS = "__objc_execClass";
725 else
727 TAG_GETCLASS = "objc_get_class";
728 TAG_GETMETACLASS = "objc_get_meta_class";
729 TAG_MSGSEND = "objc_msg_lookup";
730 TAG_MSGSENDSUPER = "objc_msg_lookup_super";
731 TAG_EXECCLASS = "__objc_exec_class";
732 flag_typed_selectors = 1;
735 objc_ellipsis_node = make_node (ERROR_MARK);
737 init_objc ();
739 if (print_struct_values)
740 generate_struct_by_value_array ();
742 objc_act_parse_init ();
743 c_parse_init ();
746 void
747 finish_file ()
749 finish_objc (); /* Objective-C finalization */
751 if (gen_declaration_file)
752 fclose (gen_declaration_file);
755 void
756 lang_finish ()
760 const char *
761 lang_identify ()
763 return "objc";
767 lang_decode_option (argc, argv)
768 int argc;
769 char **argv;
771 const char *p = argv[0];
773 if (!strcmp (p, "-gen-decls"))
774 flag_gen_declaration = 1;
775 else if (!strcmp (p, "-Wselector"))
776 warn_selector = 1;
777 else if (!strcmp (p, "-Wno-selector"))
778 warn_selector = 0;
779 else if (!strcmp (p, "-Wprotocol"))
780 flag_warn_protocol = 1;
781 else if (!strcmp (p, "-Wno-protocol"))
782 flag_warn_protocol = 0;
783 else if (!strcmp (p, "-fgnu-runtime"))
784 flag_next_runtime = 0;
785 else if (!strcmp (p, "-fno-next-runtime"))
786 flag_next_runtime = 0;
787 else if (!strcmp (p, "-fno-gnu-runtime"))
788 flag_next_runtime = 1;
789 else if (!strcmp (p, "-fnext-runtime"))
790 flag_next_runtime = 1;
791 else if (!strcmp (p, "-print-objc-runtime-info"))
792 print_struct_values = 1;
793 #define CSTSTRCLASS "-fconstant-string-class="
794 else if (!strncmp (p, CSTSTRCLASS, sizeof(CSTSTRCLASS) - 2)) {
795 if (strlen (argv[0]) <= strlen (CSTSTRCLASS))
796 error ("no class name specified as argument to -fconstant-string-class");
797 constant_string_class_name = xstrdup(argv[0] + sizeof(CSTSTRCLASS) - 1);
799 #undef CSTSTRCLASS
800 else
801 return c_decode_option (argc, argv);
803 return 1;
806 /* used by print-tree.c */
808 void
809 lang_print_xnode (file, node, indent)
810 FILE *file ATTRIBUTE_UNUSED;
811 tree node ATTRIBUTE_UNUSED;
812 int indent ATTRIBUTE_UNUSED;
817 static tree
818 define_decl (declarator, declspecs)
819 tree declarator;
820 tree declspecs;
822 tree decl = start_decl (declarator, declspecs, 0, NULL_TREE, NULL_TREE);
823 finish_decl (decl, NULL_TREE, NULL_TREE);
824 return decl;
827 /* Return 1 if LHS and RHS are compatible types for assignment or
828 various other operations. Return 0 if they are incompatible, and
829 return -1 if we choose to not decide. When the operation is
830 REFLEXIVE, check for compatibility in either direction.
832 For statically typed objects, an assignment of the form `a' = `b'
833 is permitted if:
835 `a' is of type "id",
836 `a' and `b' are the same class type, or
837 `a' and `b' are of class types A and B such that B is a descendant of A. */
840 maybe_objc_comptypes (lhs, rhs, reflexive)
841 tree lhs, rhs;
842 int reflexive;
844 return objc_comptypes (lhs, rhs, reflexive);
847 static tree
848 lookup_method_in_protocol_list (rproto_list, sel_name, class_meth)
849 tree rproto_list;
850 tree sel_name;
851 int class_meth;
853 tree rproto, p;
854 tree fnd = 0;
856 for (rproto = rproto_list; rproto; rproto = TREE_CHAIN (rproto))
858 p = TREE_VALUE (rproto);
860 if (TREE_CODE (p) == PROTOCOL_INTERFACE_TYPE)
862 if ((fnd = lookup_method (class_meth
863 ? PROTOCOL_CLS_METHODS (p)
864 : PROTOCOL_NST_METHODS (p), sel_name)))
866 else if (PROTOCOL_LIST (p))
867 fnd = lookup_method_in_protocol_list (PROTOCOL_LIST (p),
868 sel_name, class_meth);
870 else
872 ; /* An identifier...if we could not find a protocol. */
875 if (fnd)
876 return fnd;
879 return 0;
882 static tree
883 lookup_protocol_in_reflist (rproto_list, lproto)
884 tree rproto_list;
885 tree lproto;
887 tree rproto, p;
889 /* Make sure the protocol is support by the object on the rhs. */
890 if (TREE_CODE (lproto) == PROTOCOL_INTERFACE_TYPE)
892 tree fnd = 0;
893 for (rproto = rproto_list; rproto; rproto = TREE_CHAIN (rproto))
895 p = TREE_VALUE (rproto);
897 if (TREE_CODE (p) == PROTOCOL_INTERFACE_TYPE)
899 if (lproto == p)
900 fnd = lproto;
902 else if (PROTOCOL_LIST (p))
903 fnd = lookup_protocol_in_reflist (PROTOCOL_LIST (p), lproto);
906 if (fnd)
907 return fnd;
910 else
912 ; /* An identifier...if we could not find a protocol. */
915 return 0;
918 /* Return 1 if LHS and RHS are compatible types for assignment
919 or various other operations. Return 0 if they are incompatible,
920 and return -1 if we choose to not decide. When the operation
921 is REFLEXIVE, check for compatibility in either direction. */
924 objc_comptypes (lhs, rhs, reflexive)
925 tree lhs;
926 tree rhs;
927 int reflexive;
929 /* New clause for protocols. */
931 if (TREE_CODE (lhs) == POINTER_TYPE
932 && TREE_CODE (TREE_TYPE (lhs)) == RECORD_TYPE
933 && TREE_CODE (rhs) == POINTER_TYPE
934 && TREE_CODE (TREE_TYPE (rhs)) == RECORD_TYPE)
936 int lhs_is_proto = IS_PROTOCOL_QUALIFIED_ID (lhs);
937 int rhs_is_proto = IS_PROTOCOL_QUALIFIED_ID (rhs);
939 if (lhs_is_proto)
941 tree lproto, lproto_list = TYPE_PROTOCOL_LIST (lhs);
942 tree rproto, rproto_list;
943 tree p;
945 if (rhs_is_proto)
947 rproto_list = TYPE_PROTOCOL_LIST (rhs);
949 /* Make sure the protocol is supported by the object
950 on the rhs. */
951 for (lproto = lproto_list; lproto; lproto = TREE_CHAIN (lproto))
953 p = TREE_VALUE (lproto);
954 rproto = lookup_protocol_in_reflist (rproto_list, p);
956 if (!rproto)
957 warning ("object does not conform to the `%s' protocol",
958 IDENTIFIER_POINTER (PROTOCOL_NAME (p)));
961 else if (TYPED_OBJECT (TREE_TYPE (rhs)))
963 tree rname = TYPE_NAME (TREE_TYPE (rhs));
964 tree rinter;
966 /* Make sure the protocol is supported by the object
967 on the rhs. */
968 for (lproto = lproto_list; lproto; lproto = TREE_CHAIN (lproto))
970 p = TREE_VALUE (lproto);
971 rproto = 0;
972 rinter = lookup_interface (rname);
974 while (rinter && !rproto)
976 tree cat;
978 rproto_list = CLASS_PROTOCOL_LIST (rinter);
979 rproto = lookup_protocol_in_reflist (rproto_list, p);
981 /* Check for protocols adopted by categories. */
982 cat = CLASS_CATEGORY_LIST (rinter);
983 while (cat && !rproto)
985 rproto_list = CLASS_PROTOCOL_LIST (cat);
986 rproto = lookup_protocol_in_reflist (rproto_list, p);
988 cat = CLASS_CATEGORY_LIST (cat);
991 rinter = lookup_interface (CLASS_SUPER_NAME (rinter));
994 if (!rproto)
995 warning ("class `%s' does not implement the `%s' protocol",
996 IDENTIFIER_POINTER (TYPE_NAME (TREE_TYPE (rhs))),
997 IDENTIFIER_POINTER (PROTOCOL_NAME (p)));
1001 /* May change...based on whether there was any mismatch */
1002 return 1;
1004 else if (rhs_is_proto)
1005 /* Lhs is not a protocol...warn if it is statically typed */
1006 return (TYPED_OBJECT (TREE_TYPE (lhs)) != 0);
1008 else
1009 /* Defer to comptypes .*/
1010 return -1;
1013 else if (TREE_CODE (lhs) == RECORD_TYPE && TREE_CODE (rhs) == RECORD_TYPE)
1014 ; /* Fall thru. This is the case we have been handling all along */
1015 else
1016 /* Defer to comptypes. */
1017 return -1;
1019 /* `id' = `<class> *', `<class> *' = `id' */
1021 if ((TYPE_NAME (lhs) == objc_object_id && TYPED_OBJECT (rhs))
1022 || (TYPE_NAME (rhs) == objc_object_id && TYPED_OBJECT (lhs)))
1023 return 1;
1025 /* `id' = `Class', `Class' = `id' */
1027 else if ((TYPE_NAME (lhs) == objc_object_id
1028 && TYPE_NAME (rhs) == objc_class_id)
1029 || (TYPE_NAME (lhs) == objc_class_id
1030 && TYPE_NAME (rhs) == objc_object_id))
1031 return 1;
1033 /* `<class> *' = `<class> *' */
1035 else if (TYPED_OBJECT (lhs) && TYPED_OBJECT (rhs))
1037 tree lname = TYPE_NAME (lhs);
1038 tree rname = TYPE_NAME (rhs);
1039 tree inter;
1041 if (lname == rname)
1042 return 1;
1044 /* If the left hand side is a super class of the right hand side,
1045 allow it. */
1046 for (inter = lookup_interface (rname); inter;
1047 inter = lookup_interface (CLASS_SUPER_NAME (inter)))
1048 if (lname == CLASS_SUPER_NAME (inter))
1049 return 1;
1051 /* Allow the reverse when reflexive. */
1052 if (reflexive)
1053 for (inter = lookup_interface (lname); inter;
1054 inter = lookup_interface (CLASS_SUPER_NAME (inter)))
1055 if (rname == CLASS_SUPER_NAME (inter))
1056 return 1;
1058 return 0;
1060 else
1061 /* Defer to comptypes. */
1062 return -1;
1065 /* Called from c-decl.c before all calls to rest_of_decl_compilation. */
1067 void
1068 objc_check_decl (decl)
1069 tree decl;
1071 tree type = TREE_TYPE (decl);
1073 if (TREE_CODE (type) == RECORD_TYPE
1074 && TREE_STATIC_TEMPLATE (type)
1075 && type != constant_string_type)
1077 error_with_decl (decl, "`%s' cannot be statically allocated");
1078 fatal ("statically allocated objects not supported");
1082 void
1083 maybe_objc_check_decl (decl)
1084 tree decl;
1086 objc_check_decl (decl);
1089 /* Implement static typing. At this point, we know we have an interface. */
1091 tree
1092 get_static_reference (interface, protocols)
1093 tree interface;
1094 tree protocols;
1096 tree type = xref_tag (RECORD_TYPE, interface);
1098 if (protocols)
1100 tree t, m = TYPE_MAIN_VARIANT (type);
1102 t = copy_node (type);
1103 TYPE_BINFO (t) = make_tree_vec (2);
1105 /* Add this type to the chain of variants of TYPE. */
1106 TYPE_NEXT_VARIANT (t) = TYPE_NEXT_VARIANT (m);
1107 TYPE_NEXT_VARIANT (m) = t;
1109 /* Look up protocols and install in lang specific list. */
1110 TYPE_PROTOCOL_LIST (t) = lookup_and_install_protocols (protocols);
1112 /* This forces a new pointer type to be created later
1113 (in build_pointer_type)...so that the new template
1114 we just created will actually be used...what a hack! */
1115 if (TYPE_POINTER_TO (t))
1116 TYPE_POINTER_TO (t) = 0;
1118 type = t;
1121 return type;
1124 tree
1125 get_object_reference (protocols)
1126 tree protocols;
1128 tree type_decl = lookup_name (objc_id_id);
1129 tree type;
1131 if (type_decl && TREE_CODE (type_decl) == TYPE_DECL)
1133 type = TREE_TYPE (type_decl);
1134 if (TYPE_MAIN_VARIANT (type) != id_type)
1135 warning ("Unexpected type for `id' (%s)",
1136 gen_declaration (type, errbuf));
1138 else
1139 fatal ("Undefined type `id', please import <objc/objc.h>");
1141 /* This clause creates a new pointer type that is qualified with
1142 the protocol specification...this info is used later to do more
1143 elaborate type checking. */
1145 if (protocols)
1147 tree t, m = TYPE_MAIN_VARIANT (type);
1149 t = copy_node (type);
1150 TYPE_BINFO (t) = make_tree_vec (2);
1152 /* Add this type to the chain of variants of TYPE. */
1153 TYPE_NEXT_VARIANT (t) = TYPE_NEXT_VARIANT (m);
1154 TYPE_NEXT_VARIANT (m) = t;
1156 /* Look up protocols...and install in lang specific list */
1157 TYPE_PROTOCOL_LIST (t) = lookup_and_install_protocols (protocols);
1159 /* This forces a new pointer type to be created later
1160 (in build_pointer_type)...so that the new template
1161 we just created will actually be used...what a hack! */
1162 if (TYPE_POINTER_TO (t))
1163 TYPE_POINTER_TO (t) = NULL;
1165 type = t;
1167 return type;
1170 static tree
1171 lookup_and_install_protocols (protocols)
1172 tree protocols;
1174 tree proto;
1175 tree prev = NULL;
1176 tree return_value = protocols;
1178 for (proto = protocols; proto; proto = TREE_CHAIN (proto))
1180 tree ident = TREE_VALUE (proto);
1181 tree p = lookup_protocol (ident);
1183 if (!p)
1185 error ("Cannot find protocol declaration for `%s'",
1186 IDENTIFIER_POINTER (ident));
1187 if (prev)
1188 TREE_CHAIN (prev) = TREE_CHAIN (proto);
1189 else
1190 return_value = TREE_CHAIN (proto);
1192 else
1194 /* Replace identifier with actual protocol node. */
1195 TREE_VALUE (proto) = p;
1196 prev = proto;
1200 return return_value;
1203 /* Create and push a decl for a built-in external variable or field NAME.
1204 CODE says which.
1205 TYPE is its data type. */
1207 static tree
1208 create_builtin_decl (code, type, name)
1209 enum tree_code code;
1210 tree type;
1211 const char *name;
1213 tree decl = build_decl (code, get_identifier (name), type);
1215 if (code == VAR_DECL)
1217 TREE_STATIC (decl) = 1;
1218 make_decl_rtl (decl, 0, 1);
1219 pushdecl (decl);
1222 DECL_ARTIFICIAL (decl) = 1;
1223 return decl;
1226 /* Purpose: "play" parser, creating/installing representations
1227 of the declarations that are required by Objective-C.
1229 Model:
1231 type_spec--------->sc_spec
1232 (tree_list) (tree_list)
1235 identifier_node identifier_node */
1237 static void
1238 synth_module_prologue ()
1240 tree temp_type;
1241 tree super_p;
1243 /* Defined in `objc.h' */
1244 objc_object_id = get_identifier (TAG_OBJECT);
1246 objc_object_reference = xref_tag (RECORD_TYPE, objc_object_id);
1248 id_type = build_pointer_type (objc_object_reference);
1250 objc_id_id = get_identifier (TYPE_ID);
1251 objc_class_id = get_identifier (TAG_CLASS);
1253 objc_class_type = build_pointer_type (xref_tag (RECORD_TYPE, objc_class_id));
1254 protocol_type = build_pointer_type (xref_tag (RECORD_TYPE,
1255 get_identifier (PROTOCOL_OBJECT_CLASS_NAME)));
1257 /* Declare type of selector-objects that represent an operation name. */
1259 #ifdef OBJC_INT_SELECTORS
1260 /* `unsigned int' */
1261 selector_type = unsigned_type_node;
1262 #else
1263 /* `struct objc_selector *' */
1264 selector_type
1265 = build_pointer_type (xref_tag (RECORD_TYPE,
1266 get_identifier (TAG_SELECTOR)));
1267 #endif /* not OBJC_INT_SELECTORS */
1269 /* Forward declare type, or else the prototype for msgSendSuper will
1270 complain. */
1272 super_p = build_pointer_type (xref_tag (RECORD_TYPE,
1273 get_identifier (TAG_SUPER)));
1276 /* id objc_msgSend (id, SEL, ...); */
1278 temp_type
1279 = build_function_type (id_type,
1280 tree_cons (NULL_TREE, id_type,
1281 tree_cons (NULL_TREE, selector_type,
1282 NULL_TREE)));
1284 if (! flag_next_runtime)
1286 umsg_decl = build_decl (FUNCTION_DECL,
1287 get_identifier (TAG_MSGSEND), temp_type);
1288 DECL_EXTERNAL (umsg_decl) = 1;
1289 TREE_PUBLIC (umsg_decl) = 1;
1290 DECL_INLINE (umsg_decl) = 1;
1291 DECL_ARTIFICIAL (umsg_decl) = 1;
1293 if (flag_traditional && TAG_MSGSEND[0] != '_')
1294 DECL_BUILT_IN_NONANSI (umsg_decl) = 1;
1296 make_decl_rtl (umsg_decl, NULL_PTR, 1);
1297 pushdecl (umsg_decl);
1299 else
1300 umsg_decl = builtin_function (TAG_MSGSEND, temp_type, 0, NOT_BUILT_IN, 0);
1302 /* id objc_msgSendSuper (struct objc_super *, SEL, ...); */
1304 temp_type
1305 = build_function_type (id_type,
1306 tree_cons (NULL_TREE, super_p,
1307 tree_cons (NULL_TREE, selector_type,
1308 NULL_TREE)));
1310 umsg_super_decl = builtin_function (TAG_MSGSENDSUPER,
1311 temp_type, 0, NOT_BUILT_IN, 0);
1313 /* id objc_getClass (const char *); */
1315 temp_type = build_function_type (id_type,
1316 tree_cons (NULL_TREE,
1317 const_string_type_node,
1318 tree_cons (NULL_TREE, void_type_node,
1319 NULL_TREE)));
1321 objc_get_class_decl
1322 = builtin_function (TAG_GETCLASS, temp_type, 0, NOT_BUILT_IN, 0);
1324 /* id objc_getMetaClass (const char *); */
1326 objc_get_meta_class_decl
1327 = builtin_function (TAG_GETMETACLASS, temp_type, 0, NOT_BUILT_IN, 0);
1329 /* static SEL _OBJC_SELECTOR_TABLE[]; */
1331 if (! flag_next_runtime)
1333 if (flag_typed_selectors)
1335 /* Suppress outputting debug symbols, because
1336 dbxout_init hasn'r been called yet. */
1337 enum debug_info_type save_write_symbols = write_symbols;
1338 write_symbols = NO_DEBUG;
1340 build_selector_template ();
1341 temp_type = build_array_type (objc_selector_template, NULL_TREE);
1343 write_symbols = save_write_symbols;
1345 else
1346 temp_type = build_array_type (selector_type, NULL_TREE);
1348 layout_type (temp_type);
1349 UOBJC_SELECTOR_TABLE_decl
1350 = create_builtin_decl (VAR_DECL, temp_type,
1351 "_OBJC_SELECTOR_TABLE");
1353 /* Avoid warning when not sending messages. */
1354 TREE_USED (UOBJC_SELECTOR_TABLE_decl) = 1;
1357 generate_forward_declaration_to_string_table ();
1359 /* Forward declare constant_string_id and constant_string_type. */
1360 if (!constant_string_class_name)
1361 constant_string_class_name = STRING_OBJECT_CLASS_NAME;
1363 constant_string_id = get_identifier (constant_string_class_name);
1364 constant_string_type = xref_tag (RECORD_TYPE, constant_string_id);
1367 /* Custom build_string which sets TREE_TYPE! */
1369 static tree
1370 my_build_string (len, str)
1371 int len;
1372 const char *str;
1374 int wide_flag = 0;
1375 tree a_string = build_string (len, str);
1377 /* Some code from combine_strings, which is local to c-parse.y. */
1378 if (TREE_TYPE (a_string) == int_array_type_node)
1379 wide_flag = 1;
1381 TREE_TYPE (a_string)
1382 = build_array_type (wide_flag ? integer_type_node : char_type_node,
1383 build_index_type (build_int_2 (len - 1, 0)));
1385 TREE_CONSTANT (a_string) = 1; /* Puts string in the readonly segment */
1386 TREE_STATIC (a_string) = 1;
1388 return a_string;
1391 /* Given a chain of STRING_CST's, build a static instance of
1392 NXConstanString which points at the concatenation of those strings.
1393 We place the string object in the __string_objects section of the
1394 __OBJC segment. The Objective-C runtime will initialize the isa
1395 pointers of the string objects to point at the NXConstandString class
1396 object. */
1398 tree
1399 build_objc_string_object (strings)
1400 tree strings;
1402 tree string, initlist, constructor;
1403 int length;
1405 if (lookup_interface (constant_string_id) == NULL_TREE)
1407 error ("Cannot find interface declaration for `%s'",
1408 IDENTIFIER_POINTER (constant_string_id));
1409 return error_mark_node;
1412 add_class_reference (constant_string_id);
1414 string = combine_strings (strings);
1415 TREE_SET_CODE (string, STRING_CST);
1416 length = TREE_STRING_LENGTH (string) - 1;
1418 /* & ((NXConstantString) {0, string, length}) */
1420 initlist = build_tree_list (NULL_TREE, build_int_2 (0, 0));
1421 initlist
1422 = tree_cons (NULL_TREE, copy_node (build_unary_op (ADDR_EXPR, string, 1)),
1423 initlist);
1424 initlist = tree_cons (NULL_TREE, build_int_2 (length, 0), initlist);
1425 constructor = build_constructor (constant_string_type, nreverse (initlist));
1427 if (!flag_next_runtime)
1429 constructor
1430 = objc_add_static_instance (constructor, constant_string_type);
1433 return (build_unary_op (ADDR_EXPR, constructor, 1));
1436 /* Declare a static instance of CLASS_DECL initialized by CONSTRUCTOR. */
1438 static tree
1439 objc_add_static_instance (constructor, class_decl)
1440 tree constructor, class_decl;
1442 static int num_static_inst;
1443 tree *chain, decl;
1444 char buf[256];
1446 /* Find the list of static instances for the CLASS_DECL. Create one if
1447 not found. */
1448 for (chain = &objc_static_instances;
1449 *chain && TREE_VALUE (*chain) != class_decl;
1450 chain = &TREE_CHAIN (*chain));
1451 if (!*chain)
1453 *chain = tree_cons (NULL_TREE, class_decl, NULL_TREE);
1454 add_objc_string (TYPE_NAME (class_decl), class_names);
1457 sprintf (buf, "_OBJC_INSTANCE_%d", num_static_inst++);
1458 decl = build_decl (VAR_DECL, get_identifier (buf), class_decl);
1459 DECL_COMMON (decl) = 1;
1460 TREE_STATIC (decl) = 1;
1461 DECL_ARTIFICIAL (decl) = 1;
1462 pushdecl_top_level (decl);
1463 rest_of_decl_compilation (decl, 0, 1, 0);
1465 /* Do this here so it gets output later instead of possibly
1466 inside something else we are writing. */
1467 DECL_INITIAL (decl) = constructor;
1469 /* Add the DECL to the head of this CLASS' list. */
1470 TREE_PURPOSE (*chain) = tree_cons (NULL_TREE, decl, TREE_PURPOSE (*chain));
1472 return decl;
1475 /* Build a static constant CONSTRUCTOR
1476 with type TYPE and elements ELTS. */
1478 static tree
1479 build_constructor (type, elts)
1480 tree type, elts;
1482 tree constructor = build (CONSTRUCTOR, type, NULL_TREE, elts);
1484 TREE_CONSTANT (constructor) = 1;
1485 TREE_STATIC (constructor) = 1;
1486 TREE_READONLY (constructor) = 1;
1488 return constructor;
1491 /* Take care of defining and initializing _OBJC_SYMBOLS. */
1493 /* Predefine the following data type:
1495 struct _objc_symtab
1497 long sel_ref_cnt;
1498 SEL *refs;
1499 short cls_def_cnt;
1500 short cat_def_cnt;
1501 void *defs[cls_def_cnt + cat_def_cnt];
1502 }; */
1504 static void
1505 build_objc_symtab_template ()
1507 tree field_decl, field_decl_chain, index;
1509 objc_symtab_template
1510 = start_struct (RECORD_TYPE, get_identifier (UTAG_SYMTAB));
1512 /* long sel_ref_cnt; */
1514 field_decl = create_builtin_decl (FIELD_DECL,
1515 long_integer_type_node,
1516 "sel_ref_cnt");
1517 field_decl_chain = field_decl;
1519 /* SEL *refs; */
1521 field_decl = create_builtin_decl (FIELD_DECL,
1522 build_pointer_type (selector_type),
1523 "refs");
1524 chainon (field_decl_chain, field_decl);
1526 /* short cls_def_cnt; */
1528 field_decl = create_builtin_decl (FIELD_DECL,
1529 short_integer_type_node,
1530 "cls_def_cnt");
1531 chainon (field_decl_chain, field_decl);
1533 /* short cat_def_cnt; */
1535 field_decl = create_builtin_decl (FIELD_DECL,
1536 short_integer_type_node,
1537 "cat_def_cnt");
1538 chainon (field_decl_chain, field_decl);
1540 /* void *defs[cls_def_cnt + cat_def_cnt]; */
1542 if (!flag_next_runtime)
1543 index = build_index_type (build_int_2 (imp_count + cat_count, 0));
1544 else
1545 index = build_index_type (build_int_2 (imp_count + cat_count - 1,
1546 imp_count == 0 && cat_count == 0
1547 ? -1 : 0));
1548 field_decl = create_builtin_decl (FIELD_DECL,
1549 build_array_type (ptr_type_node, index),
1550 "defs");
1551 chainon (field_decl_chain, field_decl);
1553 finish_struct (objc_symtab_template, field_decl_chain, NULL_TREE);
1556 /* Create the initial value for the `defs' field of _objc_symtab.
1557 This is a CONSTRUCTOR. */
1559 static tree
1560 init_def_list (type)
1561 tree type;
1563 tree expr, initlist = NULL_TREE;
1564 struct imp_entry *impent;
1566 if (imp_count)
1567 for (impent = imp_list; impent; impent = impent->next)
1569 if (TREE_CODE (impent->imp_context) == CLASS_IMPLEMENTATION_TYPE)
1571 expr = build_unary_op (ADDR_EXPR, impent->class_decl, 0);
1572 initlist = tree_cons (NULL_TREE, expr, initlist);
1576 if (cat_count)
1577 for (impent = imp_list; impent; impent = impent->next)
1579 if (TREE_CODE (impent->imp_context) == CATEGORY_IMPLEMENTATION_TYPE)
1581 expr = build_unary_op (ADDR_EXPR, impent->class_decl, 0);
1582 initlist = tree_cons (NULL_TREE, expr, initlist);
1586 if (!flag_next_runtime)
1588 /* statics = { ..., _OBJC_STATIC_INSTANCES, ... } */
1589 tree expr;
1591 if (static_instances_decl)
1592 expr = build_unary_op (ADDR_EXPR, static_instances_decl, 0);
1593 else
1594 expr = build_int_2 (0, 0);
1596 initlist = tree_cons (NULL_TREE, expr, initlist);
1599 return build_constructor (type, nreverse (initlist));
1602 /* Construct the initial value for all of _objc_symtab. */
1604 static tree
1605 init_objc_symtab (type)
1606 tree type;
1608 tree initlist;
1610 /* sel_ref_cnt = { ..., 5, ... } */
1612 initlist = build_tree_list (NULL_TREE, build_int_2 (0, 0));
1614 /* refs = { ..., _OBJC_SELECTOR_TABLE, ... } */
1616 if (flag_next_runtime || ! sel_ref_chain)
1617 initlist = tree_cons (NULL_TREE, build_int_2 (0, 0), initlist);
1618 else
1619 initlist = tree_cons (NULL_TREE,
1620 build_unary_op (ADDR_EXPR,
1621 UOBJC_SELECTOR_TABLE_decl, 1),
1622 initlist);
1624 /* cls_def_cnt = { ..., 5, ... } */
1626 initlist = tree_cons (NULL_TREE, build_int_2 (imp_count, 0), initlist);
1628 /* cat_def_cnt = { ..., 5, ... } */
1630 initlist = tree_cons (NULL_TREE, build_int_2 (cat_count, 0), initlist);
1632 /* cls_def = { ..., { &Foo, &Bar, ...}, ... } */
1634 if (imp_count || cat_count || static_instances_decl)
1637 tree field = TYPE_FIELDS (type);
1638 field = TREE_CHAIN (TREE_CHAIN (TREE_CHAIN (TREE_CHAIN (field))));
1640 initlist = tree_cons (NULL_TREE, init_def_list (TREE_TYPE (field)),
1641 initlist);
1644 return build_constructor (type, nreverse (initlist));
1647 /* Push forward-declarations of all the categories
1648 so that init_def_list can use them in a CONSTRUCTOR. */
1650 static void
1651 forward_declare_categories ()
1653 struct imp_entry *impent;
1654 tree sav = implementation_context;
1656 for (impent = imp_list; impent; impent = impent->next)
1658 if (TREE_CODE (impent->imp_context) == CATEGORY_IMPLEMENTATION_TYPE)
1660 /* Set an invisible arg to synth_id_with_class_suffix. */
1661 implementation_context = impent->imp_context;
1662 impent->class_decl
1663 = create_builtin_decl (VAR_DECL, objc_category_template,
1664 IDENTIFIER_POINTER (synth_id_with_class_suffix ("_OBJC_CATEGORY", implementation_context)));
1667 implementation_context = sav;
1670 /* Create the declaration of _OBJC_SYMBOLS, with type `strict _objc_symtab'
1671 and initialized appropriately. */
1673 static void
1674 generate_objc_symtab_decl ()
1676 tree sc_spec;
1678 if (!objc_category_template)
1679 build_category_template ();
1681 /* forward declare categories */
1682 if (cat_count)
1683 forward_declare_categories ();
1685 if (!objc_symtab_template)
1686 build_objc_symtab_template ();
1688 sc_spec = build_tree_list (NULL_TREE, ridpointers[(int) RID_STATIC]);
1690 UOBJC_SYMBOLS_decl = start_decl (get_identifier ("_OBJC_SYMBOLS"),
1691 tree_cons (NULL_TREE,
1692 objc_symtab_template, sc_spec),
1694 NULL_TREE, NULL_TREE);
1696 TREE_USED (UOBJC_SYMBOLS_decl) = 1;
1697 DECL_IGNORED_P (UOBJC_SYMBOLS_decl) = 1;
1698 DECL_ARTIFICIAL (UOBJC_SYMBOLS_decl) = 1;
1699 finish_decl (UOBJC_SYMBOLS_decl,
1700 init_objc_symtab (TREE_TYPE (UOBJC_SYMBOLS_decl)),
1701 NULL_TREE);
1704 static tree
1705 init_module_descriptor (type)
1706 tree type;
1708 tree initlist, expr;
1710 /* version = { 1, ... } */
1712 expr = build_int_2 (OBJC_VERSION, 0);
1713 initlist = build_tree_list (NULL_TREE, expr);
1715 /* size = { ..., sizeof (struct objc_module), ... } */
1717 expr = size_in_bytes (objc_module_template);
1718 initlist = tree_cons (NULL_TREE, expr, initlist);
1720 /* name = { ..., "foo.m", ... } */
1722 expr = add_objc_string (get_identifier (input_filename), class_names);
1723 initlist = tree_cons (NULL_TREE, expr, initlist);
1725 /* symtab = { ..., _OBJC_SYMBOLS, ... } */
1727 if (UOBJC_SYMBOLS_decl)
1728 expr = build_unary_op (ADDR_EXPR, UOBJC_SYMBOLS_decl, 0);
1729 else
1730 expr = build_int_2 (0, 0);
1731 initlist = tree_cons (NULL_TREE, expr, initlist);
1733 return build_constructor (type, nreverse (initlist));
1736 /* Write out the data structures to describe Objective C classes defined.
1737 If appropriate, compile and output a setup function to initialize them.
1738 Return a string which is the name of a function to call to initialize
1739 the Objective C data structures for this file (and perhaps for other files
1740 also).
1742 struct objc_module { ... } _OBJC_MODULE = { ... }; */
1744 static const char *
1745 build_module_descriptor ()
1747 tree decl_specs, field_decl, field_decl_chain;
1749 objc_module_template
1750 = start_struct (RECORD_TYPE, get_identifier (UTAG_MODULE));
1752 /* Long version; */
1754 decl_specs = build_tree_list (NULL_TREE, ridpointers[(int) RID_LONG]);
1755 field_decl = get_identifier ("version");
1756 field_decl
1757 = grokfield (input_filename, lineno, field_decl, decl_specs, NULL_TREE);
1758 field_decl_chain = field_decl;
1760 /* long size; */
1762 decl_specs = build_tree_list (NULL_TREE, ridpointers[(int) RID_LONG]);
1763 field_decl = get_identifier ("size");
1764 field_decl
1765 = grokfield (input_filename, lineno, field_decl, decl_specs, NULL_TREE);
1766 chainon (field_decl_chain, field_decl);
1768 /* char *name; */
1770 decl_specs = build_tree_list (NULL_TREE, ridpointers[(int) RID_CHAR]);
1771 field_decl = build1 (INDIRECT_REF, NULL_TREE, get_identifier ("name"));
1772 field_decl
1773 = grokfield (input_filename, lineno, field_decl, decl_specs, NULL_TREE);
1774 chainon (field_decl_chain, field_decl);
1776 /* struct objc_symtab *symtab; */
1778 decl_specs = get_identifier (UTAG_SYMTAB);
1779 decl_specs = build_tree_list (NULL_TREE, xref_tag (RECORD_TYPE, decl_specs));
1780 field_decl = build1 (INDIRECT_REF, NULL_TREE, get_identifier ("symtab"));
1781 field_decl
1782 = grokfield (input_filename, lineno, field_decl, decl_specs, NULL_TREE);
1783 chainon (field_decl_chain, field_decl);
1785 finish_struct (objc_module_template, field_decl_chain, NULL_TREE);
1787 /* Create an instance of "objc_module". */
1789 decl_specs = tree_cons (NULL_TREE, objc_module_template,
1790 build_tree_list (NULL_TREE,
1791 ridpointers[(int) RID_STATIC]));
1793 UOBJC_MODULES_decl = start_decl (get_identifier ("_OBJC_MODULES"),
1794 decl_specs, 1, NULL_TREE, NULL_TREE);
1796 DECL_ARTIFICIAL (UOBJC_MODULES_decl) = 1;
1797 DECL_IGNORED_P (UOBJC_MODULES_decl) = 1;
1798 finish_decl (UOBJC_MODULES_decl,
1799 init_module_descriptor (TREE_TYPE (UOBJC_MODULES_decl)),
1800 NULL_TREE);
1802 /* Mark the decl to avoid "defined but not used" warning. */
1803 DECL_IN_SYSTEM_HEADER (UOBJC_MODULES_decl) = 1;
1805 /* Generate a constructor call for the module descriptor.
1806 This code was generated by reading the grammar rules
1807 of c-parse.in; Therefore, it may not be the most efficient
1808 way of generating the requisite code. */
1810 if (flag_next_runtime)
1811 return 0;
1814 tree parms, function_decl, decelerator, void_list_node_1;
1815 tree function_type;
1816 tree init_function_name = get_file_function_name ('I');
1818 /* Declare void __objc_execClass (void *); */
1820 void_list_node_1 = build_tree_list (NULL_TREE, void_type_node);
1821 function_type
1822 = build_function_type (void_type_node,
1823 tree_cons (NULL_TREE, ptr_type_node,
1824 void_list_node_1));
1825 function_decl = build_decl (FUNCTION_DECL,
1826 get_identifier (TAG_EXECCLASS),
1827 function_type);
1828 DECL_EXTERNAL (function_decl) = 1;
1829 DECL_ARTIFICIAL (function_decl) = 1;
1830 TREE_PUBLIC (function_decl) = 1;
1832 pushdecl (function_decl);
1833 rest_of_decl_compilation (function_decl, 0, 0, 0);
1835 parms
1836 = build_tree_list (NULL_TREE,
1837 build_unary_op (ADDR_EXPR, UOBJC_MODULES_decl, 0));
1838 decelerator = build_function_call (function_decl, parms);
1840 /* void _GLOBAL_$I$<gnyf> () {objc_execClass (&L_OBJC_MODULES);} */
1842 start_function (void_list_node_1,
1843 build_parse_node (CALL_EXPR, init_function_name,
1844 /* This has the format of the output
1845 of get_parm_info. */
1846 tree_cons (NULL_TREE, NULL_TREE,
1847 void_list_node_1),
1848 NULL_TREE),
1849 NULL_TREE, NULL_TREE);
1850 #if 0 /* This should be turned back on later
1851 for the systems where collect is not needed. */
1852 /* Make these functions nonglobal
1853 so each file can use the same name. */
1854 TREE_PUBLIC (current_function_decl) = 0;
1855 #endif
1856 TREE_USED (current_function_decl) = 1;
1857 store_parm_decls ();
1859 assemble_external (function_decl);
1860 c_expand_expr_stmt (decelerator);
1862 TREE_PUBLIC (current_function_decl) = 1;
1864 function_decl = current_function_decl;
1865 finish_function (0);
1867 /* Return the name of the constructor function. */
1868 return XSTR (XEXP (DECL_RTL (function_decl), 0), 0);
1872 /* extern const char _OBJC_STRINGS[]; */
1874 static void
1875 generate_forward_declaration_to_string_table ()
1877 tree sc_spec, decl_specs, expr_decl;
1879 sc_spec = tree_cons (NULL_TREE, ridpointers[(int) RID_EXTERN], NULL_TREE);
1880 decl_specs = tree_cons (NULL_TREE, ridpointers[(int) RID_CHAR], sc_spec);
1882 expr_decl
1883 = build_nt (ARRAY_REF, get_identifier ("_OBJC_STRINGS"), NULL_TREE);
1885 UOBJC_STRINGS_decl = define_decl (expr_decl, decl_specs);
1888 /* Return the DECL of the string IDENT in the SECTION. */
1890 static tree
1891 get_objc_string_decl (ident, section)
1892 tree ident;
1893 enum string_section section;
1895 tree chain;
1897 if (section == class_names)
1898 chain = class_names_chain;
1899 else if (section == meth_var_names)
1900 chain = meth_var_names_chain;
1901 else if (section == meth_var_types)
1902 chain = meth_var_types_chain;
1903 else
1904 abort ();
1906 for (; chain != 0; chain = TREE_VALUE (chain))
1907 if (TREE_VALUE (chain) == ident)
1908 return (TREE_PURPOSE (chain));
1910 abort ();
1911 return NULL_TREE;
1914 /* Output references to all statically allocated objects. Return the DECL
1915 for the array built. */
1917 static void
1918 generate_static_references ()
1920 tree decls = NULL_TREE, ident, decl_spec, expr_decl, expr = NULL_TREE;
1921 tree class_name, class, decl, initlist;
1922 tree cl_chain, in_chain, type;
1923 int num_inst, num_class;
1924 char buf[256];
1926 if (flag_next_runtime)
1927 abort ();
1929 for (cl_chain = objc_static_instances, num_class = 0;
1930 cl_chain; cl_chain = TREE_CHAIN (cl_chain), num_class++)
1932 for (num_inst = 0, in_chain = TREE_PURPOSE (cl_chain);
1933 in_chain; num_inst++, in_chain = TREE_CHAIN (in_chain));
1935 sprintf (buf, "_OBJC_STATIC_INSTANCES_%d", num_class);
1936 ident = get_identifier (buf);
1938 expr_decl = build_nt (ARRAY_REF, ident, NULL_TREE);
1939 decl_spec = tree_cons (NULL_TREE, build_pointer_type (void_type_node),
1940 build_tree_list (NULL_TREE,
1941 ridpointers[(int) RID_STATIC]));
1942 decl = start_decl (expr_decl, decl_spec, 1, NULL_TREE, NULL_TREE);
1943 DECL_CONTEXT (decl) = 0;
1944 DECL_ARTIFICIAL (decl) = 1;
1946 /* Output {class_name, ...}. */
1947 class = TREE_VALUE (cl_chain);
1948 class_name = get_objc_string_decl (TYPE_NAME (class), class_names);
1949 initlist = build_tree_list (NULL_TREE,
1950 build_unary_op (ADDR_EXPR, class_name, 1));
1952 /* Output {..., instance, ...}. */
1953 for (in_chain = TREE_PURPOSE (cl_chain);
1954 in_chain; in_chain = TREE_CHAIN (in_chain))
1956 expr = build_unary_op (ADDR_EXPR, TREE_VALUE (in_chain), 1);
1957 initlist = tree_cons (NULL_TREE, expr, initlist);
1960 /* Output {..., NULL}. */
1961 initlist = tree_cons (NULL_TREE, build_int_2 (0, 0), initlist);
1963 expr = build_constructor (TREE_TYPE (decl), nreverse (initlist));
1964 finish_decl (decl, expr, NULL_TREE);
1965 TREE_USED (decl) = 1;
1967 type = build_array_type (build_pointer_type (void_type_node), 0);
1968 decl = build_decl (VAR_DECL, ident, type);
1969 make_decl_rtl (decl, 0, 1);
1970 TREE_USED (decl) = 1;
1971 decls
1972 = tree_cons (NULL_TREE, build_unary_op (ADDR_EXPR, decl, 1), decls);
1975 decls = tree_cons (NULL_TREE, build_int_2 (0, 0), decls);
1976 ident = get_identifier ("_OBJC_STATIC_INSTANCES");
1977 expr_decl = build_nt (ARRAY_REF, ident, NULL_TREE);
1978 decl_spec = tree_cons (NULL_TREE, build_pointer_type (void_type_node),
1979 build_tree_list (NULL_TREE,
1980 ridpointers[(int) RID_STATIC]));
1981 static_instances_decl
1982 = start_decl (expr_decl, decl_spec, 1, NULL_TREE, NULL_TREE);
1983 TREE_USED (static_instances_decl) = 1;
1984 DECL_CONTEXT (static_instances_decl) = 0;
1985 DECL_ARTIFICIAL (static_instances_decl) = 1;
1986 expr = build_constructor (TREE_TYPE (static_instances_decl),
1987 nreverse (decls));
1988 finish_decl (static_instances_decl, expr, NULL_TREE);
1991 /* Output all strings. */
1993 static void
1994 generate_strings ()
1996 tree sc_spec, decl_specs, expr_decl;
1997 tree chain, string_expr;
1998 tree string, decl;
2000 for (chain = class_names_chain; chain; chain = TREE_CHAIN (chain))
2002 string = TREE_VALUE (chain);
2003 decl = TREE_PURPOSE (chain);
2004 sc_spec
2005 = tree_cons (NULL_TREE, ridpointers[(int) RID_STATIC], NULL_TREE);
2006 decl_specs = tree_cons (NULL_TREE, ridpointers[(int) RID_CHAR], sc_spec);
2007 expr_decl = build_nt (ARRAY_REF, DECL_NAME (decl), NULL_TREE);
2008 decl = start_decl (expr_decl, decl_specs, 1, NULL_TREE, NULL_TREE);
2009 string_expr = my_build_string (IDENTIFIER_LENGTH (string) + 1,
2010 IDENTIFIER_POINTER (string));
2011 finish_decl (decl, string_expr, NULL_TREE);
2014 for (chain = meth_var_names_chain; chain; chain = TREE_CHAIN (chain))
2016 string = TREE_VALUE (chain);
2017 decl = TREE_PURPOSE (chain);
2018 sc_spec
2019 = tree_cons (NULL_TREE, ridpointers[(int) RID_STATIC], NULL_TREE);
2020 decl_specs = tree_cons (NULL_TREE, ridpointers[(int) RID_CHAR], sc_spec);
2021 expr_decl = build_nt (ARRAY_REF, DECL_NAME (decl), NULL_TREE);
2022 decl = start_decl (expr_decl, decl_specs, 1, NULL_TREE, NULL_TREE);
2023 string_expr = my_build_string (IDENTIFIER_LENGTH (string) + 1,
2024 IDENTIFIER_POINTER (string));
2025 finish_decl (decl, string_expr, NULL_TREE);
2028 for (chain = meth_var_types_chain; chain; chain = TREE_CHAIN (chain))
2030 string = TREE_VALUE (chain);
2031 decl = TREE_PURPOSE (chain);
2032 sc_spec
2033 = tree_cons (NULL_TREE, ridpointers[(int) RID_STATIC], NULL_TREE);
2034 decl_specs = tree_cons (NULL_TREE, ridpointers[(int) RID_CHAR], sc_spec);
2035 expr_decl = build_nt (ARRAY_REF, DECL_NAME (decl), NULL_TREE);
2036 decl = start_decl (expr_decl, decl_specs, 1, NULL_TREE, NULL_TREE);
2037 string_expr = my_build_string (IDENTIFIER_LENGTH (string) + 1,
2038 IDENTIFIER_POINTER (string));
2039 finish_decl (decl, string_expr, NULL_TREE);
2043 static tree
2044 build_selector_reference_decl ()
2046 tree decl, ident;
2047 char buf[256];
2048 static int idx = 0;
2050 sprintf (buf, "_OBJC_SELECTOR_REFERENCES_%d", idx++);
2052 ident = get_identifier (buf);
2054 decl = build_decl (VAR_DECL, ident, selector_type);
2055 DECL_EXTERNAL (decl) = 1;
2056 TREE_PUBLIC (decl) = 1;
2057 TREE_USED (decl) = 1;
2058 TREE_READONLY (decl) = 1;
2059 DECL_ARTIFICIAL (decl) = 1;
2060 DECL_CONTEXT (decl) = 0;
2062 make_decl_rtl (decl, 0, 1);
2063 pushdecl_top_level (decl);
2065 return decl;
2068 /* Just a handy wrapper for add_objc_string. */
2070 static tree
2071 build_selector (ident)
2072 tree ident;
2074 tree expr = add_objc_string (ident, meth_var_names);
2075 if (flag_typed_selectors)
2076 return expr;
2077 else
2078 return build_c_cast (selector_type, expr); /* cast! */
2081 /* Synthesize the following expr: (char *)&_OBJC_STRINGS[<offset>]
2082 The cast stops the compiler from issuing the following message:
2083 grok.m: warning: initialization of non-const * pointer from const *
2084 grok.m: warning: initialization between incompatible pointer types. */
2086 #if 0
2087 static tree
2088 build_msg_pool_reference (offset)
2089 int offset;
2091 tree expr = build_int_2 (offset, 0);
2092 tree cast;
2094 expr = build_array_ref (UOBJC_STRINGS_decl, expr);
2095 expr = build_unary_op (ADDR_EXPR, expr, 0);
2097 cast = build_tree_list (build_tree_list (NULL_TREE,
2098 ridpointers[(int) RID_CHAR]),
2099 build1 (INDIRECT_REF, NULL_TREE, NULL_TREE));
2100 TREE_TYPE (expr) = groktypename (cast);
2101 return expr;
2104 static tree
2105 init_selector (offset)
2106 int offset;
2108 tree expr = build_msg_pool_reference (offset);
2109 TREE_TYPE (expr) = selector_type;
2110 return expr;
2112 #endif
2114 static void
2115 build_selector_translation_table ()
2117 tree sc_spec, decl_specs;
2118 tree chain, initlist = NULL_TREE;
2119 int offset = 0;
2120 tree decl = NULL_TREE, var_decl, name;
2122 for (chain = sel_ref_chain; chain; chain = TREE_CHAIN (chain))
2124 tree expr;
2126 expr = build_selector (TREE_VALUE (chain));
2128 if (flag_next_runtime)
2130 name = DECL_NAME (TREE_PURPOSE (chain));
2132 sc_spec = build_tree_list (NULL_TREE, ridpointers[(int) RID_STATIC]);
2134 /* static SEL _OBJC_SELECTOR_REFERENCES_n = ...; */
2135 decl_specs = tree_cons (NULL_TREE, selector_type, sc_spec);
2137 var_decl = name;
2139 /* The `decl' that is returned from start_decl is the one that we
2140 forward declared in `build_selector_reference' */
2141 decl = start_decl (var_decl, decl_specs, 1, NULL_TREE, NULL_TREE);
2144 /* add one for the '\0' character */
2145 offset += IDENTIFIER_LENGTH (TREE_VALUE (chain)) + 1;
2147 if (flag_next_runtime)
2148 finish_decl (decl, expr, NULL_TREE);
2149 else
2151 if (flag_typed_selectors)
2153 tree eltlist = NULL_TREE;
2154 tree encoding = get_proto_encoding (TREE_PURPOSE (chain));
2155 eltlist = tree_cons (NULL_TREE, expr, NULL_TREE);
2156 eltlist = tree_cons (NULL_TREE, encoding, eltlist);
2157 expr = build_constructor (objc_selector_template,
2158 nreverse (eltlist));
2160 initlist = tree_cons (NULL_TREE, expr, initlist);
2165 if (! flag_next_runtime)
2167 /* Cause the variable and its initial value to be actually output. */
2168 DECL_EXTERNAL (UOBJC_SELECTOR_TABLE_decl) = 0;
2169 TREE_STATIC (UOBJC_SELECTOR_TABLE_decl) = 1;
2170 /* NULL terminate the list and fix the decl for output. */
2171 initlist = tree_cons (NULL_TREE, build_int_2 (0, 0), initlist);
2172 DECL_INITIAL (UOBJC_SELECTOR_TABLE_decl) = objc_ellipsis_node;
2173 initlist = build_constructor (TREE_TYPE (UOBJC_SELECTOR_TABLE_decl),
2174 nreverse (initlist));
2175 finish_decl (UOBJC_SELECTOR_TABLE_decl, initlist, NULL_TREE);
2176 current_function_decl = NULL_TREE;
2180 static tree
2181 get_proto_encoding (proto)
2182 tree proto;
2184 tree encoding;
2185 if (proto)
2187 tree tmp_decl;
2189 if (! METHOD_ENCODING (proto))
2191 tmp_decl = build_tmp_function_decl ();
2192 hack_method_prototype (proto, tmp_decl);
2193 encoding = encode_method_prototype (proto, tmp_decl);
2194 METHOD_ENCODING (proto) = encoding;
2196 else
2197 encoding = METHOD_ENCODING (proto);
2199 return add_objc_string (encoding, meth_var_types);
2201 else
2202 return build_int_2 (0, 0);
2205 /* sel_ref_chain is a list whose "value" fields will be instances of
2206 identifier_node that represent the selector. */
2208 static tree
2209 build_typed_selector_reference (ident, proto)
2210 tree ident, proto;
2212 tree *chain = &sel_ref_chain;
2213 tree expr;
2214 int index = 0;
2216 while (*chain)
2218 if (TREE_PURPOSE (*chain) == ident && TREE_VALUE (*chain) == proto)
2219 goto return_at_index;
2221 index++;
2222 chain = &TREE_CHAIN (*chain);
2225 *chain = tree_cons (proto, ident, NULL_TREE);
2227 return_at_index:
2228 expr = build_unary_op (ADDR_EXPR,
2229 build_array_ref (UOBJC_SELECTOR_TABLE_decl,
2230 build_int_2 (index, 0)),
2232 return build_c_cast (selector_type, expr);
2235 static tree
2236 build_selector_reference (ident)
2237 tree ident;
2239 tree *chain = &sel_ref_chain;
2240 tree expr;
2241 int index = 0;
2243 while (*chain)
2245 if (TREE_VALUE (*chain) == ident)
2246 return (flag_next_runtime
2247 ? TREE_PURPOSE (*chain)
2248 : build_array_ref (UOBJC_SELECTOR_TABLE_decl,
2249 build_int_2 (index, 0)));
2251 index++;
2252 chain = &TREE_CHAIN (*chain);
2255 expr = build_selector_reference_decl ();
2257 *chain = tree_cons (expr, ident, NULL_TREE);
2259 return (flag_next_runtime
2260 ? expr
2261 : build_array_ref (UOBJC_SELECTOR_TABLE_decl,
2262 build_int_2 (index, 0)));
2265 static tree
2266 build_class_reference_decl ()
2268 tree decl, ident;
2269 char buf[256];
2270 static int idx = 0;
2272 sprintf (buf, "_OBJC_CLASS_REFERENCES_%d", idx++);
2274 ident = get_identifier (buf);
2276 decl = build_decl (VAR_DECL, ident, objc_class_type);
2277 DECL_EXTERNAL (decl) = 1;
2278 TREE_PUBLIC (decl) = 1;
2279 TREE_USED (decl) = 1;
2280 TREE_READONLY (decl) = 1;
2281 DECL_CONTEXT (decl) = 0;
2282 DECL_ARTIFICIAL (decl) = 1;
2284 make_decl_rtl (decl, 0, 1);
2285 pushdecl_top_level (decl);
2287 return decl;
2290 /* Create a class reference, but don't create a variable to reference
2291 it. */
2293 static void
2294 add_class_reference (ident)
2295 tree ident;
2297 tree chain;
2299 if ((chain = cls_ref_chain))
2301 tree tail;
2304 if (ident == TREE_VALUE (chain))
2305 return;
2307 tail = chain;
2308 chain = TREE_CHAIN (chain);
2310 while (chain);
2312 /* Append to the end of the list */
2313 TREE_CHAIN (tail) = tree_cons (NULL_TREE, ident, NULL_TREE);
2315 else
2316 cls_ref_chain = tree_cons (NULL_TREE, ident, NULL_TREE);
2319 /* Get a class reference, creating it if necessary. Also create the
2320 reference variable. */
2322 tree
2323 get_class_reference (ident)
2324 tree ident;
2326 if (flag_next_runtime)
2328 tree *chain;
2329 tree decl;
2331 for (chain = &cls_ref_chain; *chain; chain = &TREE_CHAIN (*chain))
2332 if (TREE_VALUE (*chain) == ident)
2334 if (! TREE_PURPOSE (*chain))
2335 TREE_PURPOSE (*chain) = build_class_reference_decl ();
2337 return TREE_PURPOSE (*chain);
2340 decl = build_class_reference_decl ();
2341 *chain = tree_cons (decl, ident, NULL_TREE);
2342 return decl;
2344 else
2346 tree params;
2348 add_class_reference (ident);
2350 params = build_tree_list (NULL_TREE,
2351 my_build_string (IDENTIFIER_LENGTH (ident) + 1,
2352 IDENTIFIER_POINTER (ident)));
2354 assemble_external (objc_get_class_decl);
2355 return build_function_call (objc_get_class_decl, params);
2359 /* SEL_REFDEF_CHAIN is a list whose "value" fields will be instances
2360 of identifier_node that represent the selector. It returns the
2361 offset of the selector from the beginning of the _OBJC_STRINGS
2362 pool. This offset is typically used by init_selector during code
2363 generation.
2365 For each string section we have a chain which maps identifier nodes
2366 to decls for the strings. */
2368 static tree
2369 add_objc_string (ident, section)
2370 tree ident;
2371 enum string_section section;
2373 tree *chain, decl;
2375 if (section == class_names)
2376 chain = &class_names_chain;
2377 else if (section == meth_var_names)
2378 chain = &meth_var_names_chain;
2379 else if (section == meth_var_types)
2380 chain = &meth_var_types_chain;
2381 else
2382 abort ();
2384 while (*chain)
2386 if (TREE_VALUE (*chain) == ident)
2387 return build_unary_op (ADDR_EXPR, TREE_PURPOSE (*chain), 1);
2389 chain = &TREE_CHAIN (*chain);
2392 decl = build_objc_string_decl (section);
2394 *chain = tree_cons (decl, ident, NULL_TREE);
2396 return build_unary_op (ADDR_EXPR, decl, 1);
2399 static tree
2400 build_objc_string_decl (section)
2401 enum string_section section;
2403 tree decl, ident;
2404 char buf[256];
2405 static int class_names_idx = 0;
2406 static int meth_var_names_idx = 0;
2407 static int meth_var_types_idx = 0;
2409 if (section == class_names)
2410 sprintf (buf, "_OBJC_CLASS_NAME_%d", class_names_idx++);
2411 else if (section == meth_var_names)
2412 sprintf (buf, "_OBJC_METH_VAR_NAME_%d", meth_var_names_idx++);
2413 else if (section == meth_var_types)
2414 sprintf (buf, "_OBJC_METH_VAR_TYPE_%d", meth_var_types_idx++);
2416 ident = get_identifier (buf);
2418 decl = build_decl (VAR_DECL, ident, build_array_type (char_type_node, 0));
2419 DECL_EXTERNAL (decl) = 1;
2420 TREE_PUBLIC (decl) = 1;
2421 TREE_USED (decl) = 1;
2422 TREE_READONLY (decl) = 1;
2423 TREE_CONSTANT (decl) = 1;
2424 DECL_CONTEXT (decl) = 0;
2425 DECL_ARTIFICIAL (decl) = 1;
2427 make_decl_rtl (decl, 0, 1);
2428 pushdecl_top_level (decl);
2430 return decl;
2434 void
2435 objc_declare_alias (alias_ident, class_ident)
2436 tree alias_ident;
2437 tree class_ident;
2439 if (is_class_name (class_ident) != class_ident)
2440 warning ("Cannot find class `%s'", IDENTIFIER_POINTER (class_ident));
2441 else if (is_class_name (alias_ident))
2442 warning ("Class `%s' already exists", IDENTIFIER_POINTER (alias_ident));
2443 else
2444 alias_chain = tree_cons (class_ident, alias_ident, alias_chain);
2447 void
2448 objc_declare_class (ident_list)
2449 tree ident_list;
2451 tree list;
2453 for (list = ident_list; list; list = TREE_CHAIN (list))
2455 tree ident = TREE_VALUE (list);
2456 tree decl;
2458 if ((decl = lookup_name (ident)))
2460 error ("`%s' redeclared as different kind of symbol",
2461 IDENTIFIER_POINTER (ident));
2462 error_with_decl (decl, "previous declaration of `%s'");
2465 if (! is_class_name (ident))
2467 tree record = xref_tag (RECORD_TYPE, ident);
2468 TREE_STATIC_TEMPLATE (record) = 1;
2469 class_chain = tree_cons (NULL_TREE, ident, class_chain);
2474 tree
2475 is_class_name (ident)
2476 tree ident;
2478 tree chain;
2480 if (lookup_interface (ident))
2481 return ident;
2483 for (chain = class_chain; chain; chain = TREE_CHAIN (chain))
2485 if (ident == TREE_VALUE (chain))
2486 return ident;
2489 for (chain = alias_chain; chain; chain = TREE_CHAIN (chain))
2491 if (ident == TREE_VALUE (chain))
2492 return TREE_PURPOSE (chain);
2495 return 0;
2498 tree
2499 lookup_interface (ident)
2500 tree ident;
2502 tree chain;
2504 for (chain = interface_chain; chain; chain = TREE_CHAIN (chain))
2506 if (ident == CLASS_NAME (chain))
2507 return chain;
2509 return NULL_TREE;
2512 static tree
2513 objc_copy_list (list, head)
2514 tree list;
2515 tree *head;
2517 tree newlist = NULL_TREE, tail = NULL_TREE;
2519 while (list)
2521 tail = copy_node (list);
2523 /* The following statement fixes a bug when inheriting instance
2524 variables that are declared to be bitfields. finish_struct
2525 expects to find the width of the bitfield in DECL_INITIAL. */
2526 if (DECL_BIT_FIELD (tail) && DECL_INITIAL (tail) == 0)
2527 DECL_INITIAL (tail) = DECL_SIZE (tail);
2529 newlist = chainon (newlist, tail);
2530 list = TREE_CHAIN (list);
2533 *head = newlist;
2534 return tail;
2537 /* Used by: build_private_template, get_class_ivars, and
2538 continue_class. COPY is 1 when called from @defs. In this case
2539 copy all fields. Otherwise don't copy leaf ivars since we rely on
2540 them being side-effected exactly once by finish_struct. */
2542 static tree
2543 build_ivar_chain (interface, copy)
2544 tree interface;
2545 int copy;
2547 tree my_name, super_name, ivar_chain;
2549 my_name = CLASS_NAME (interface);
2550 super_name = CLASS_SUPER_NAME (interface);
2552 /* Possibly copy leaf ivars. */
2553 if (copy)
2554 objc_copy_list (CLASS_IVARS (interface), &ivar_chain);
2555 else
2556 ivar_chain = CLASS_IVARS (interface);
2558 while (super_name)
2560 tree op1;
2561 tree super_interface = lookup_interface (super_name);
2563 if (!super_interface)
2565 /* fatal did not work with 2 args...should fix */
2566 error ("Cannot find interface declaration for `%s', superclass of `%s'",
2567 IDENTIFIER_POINTER (super_name),
2568 IDENTIFIER_POINTER (my_name));
2569 exit (FATAL_EXIT_CODE);
2572 if (super_interface == interface)
2574 fatal ("Circular inheritance in interface declaration for `%s'",
2575 IDENTIFIER_POINTER (super_name));
2578 interface = super_interface;
2579 my_name = CLASS_NAME (interface);
2580 super_name = CLASS_SUPER_NAME (interface);
2582 op1 = CLASS_IVARS (interface);
2583 if (op1)
2585 tree head, tail = objc_copy_list (op1, &head);
2587 /* Prepend super class ivars...make a copy of the list, we
2588 do not want to alter the original. */
2589 TREE_CHAIN (tail) = ivar_chain;
2590 ivar_chain = head;
2593 return ivar_chain;
2596 /* struct <classname> {
2597 struct objc_class *isa;
2599 }; */
2601 static tree
2602 build_private_template (class)
2603 tree class;
2605 tree ivar_context;
2607 if (CLASS_STATIC_TEMPLATE (class))
2609 uprivate_record = CLASS_STATIC_TEMPLATE (class);
2610 ivar_context = TYPE_FIELDS (CLASS_STATIC_TEMPLATE (class));
2612 else
2614 uprivate_record = start_struct (RECORD_TYPE, CLASS_NAME (class));
2616 ivar_context = build_ivar_chain (class, 0);
2618 finish_struct (uprivate_record, ivar_context, NULL_TREE);
2620 CLASS_STATIC_TEMPLATE (class) = uprivate_record;
2622 /* mark this record as class template - for class type checking */
2623 TREE_STATIC_TEMPLATE (uprivate_record) = 1;
2626 instance_type
2627 = groktypename (build_tree_list (build_tree_list (NULL_TREE,
2628 uprivate_record),
2629 build1 (INDIRECT_REF, NULL_TREE,
2630 NULL_TREE)));
2632 return ivar_context;
2635 /* Begin code generation for protocols... */
2637 /* struct objc_protocol {
2638 char *protocol_name;
2639 struct objc_protocol **protocol_list;
2640 struct objc_method_desc *instance_methods;
2641 struct objc_method_desc *class_methods;
2642 }; */
2644 static tree
2645 build_protocol_template ()
2647 tree decl_specs, field_decl, field_decl_chain;
2648 tree template;
2650 template = start_struct (RECORD_TYPE, get_identifier (UTAG_PROTOCOL));
2652 /* struct objc_class *isa; */
2654 decl_specs = build_tree_list (NULL_TREE, xref_tag (RECORD_TYPE,
2655 get_identifier (UTAG_CLASS)));
2656 field_decl = build1 (INDIRECT_REF, NULL_TREE, get_identifier ("isa"));
2657 field_decl
2658 = grokfield (input_filename, lineno, field_decl, decl_specs, NULL_TREE);
2659 field_decl_chain = field_decl;
2661 /* char *protocol_name; */
2663 decl_specs = build_tree_list (NULL_TREE, ridpointers[(int) RID_CHAR]);
2664 field_decl
2665 = build1 (INDIRECT_REF, NULL_TREE, get_identifier ("protocol_name"));
2666 field_decl
2667 = grokfield (input_filename, lineno, field_decl, decl_specs, NULL_TREE);
2668 chainon (field_decl_chain, field_decl);
2670 /* struct objc_protocol **protocol_list; */
2672 decl_specs = build_tree_list (NULL_TREE, template);
2673 field_decl
2674 = build1 (INDIRECT_REF, NULL_TREE, get_identifier ("protocol_list"));
2675 field_decl = build1 (INDIRECT_REF, NULL_TREE, field_decl);
2676 field_decl
2677 = grokfield (input_filename, lineno, field_decl, decl_specs, NULL_TREE);
2678 chainon (field_decl_chain, field_decl);
2680 /* struct objc_method_list *instance_methods; */
2682 decl_specs
2683 = build_tree_list (NULL_TREE,
2684 xref_tag (RECORD_TYPE,
2685 get_identifier (UTAG_METHOD_PROTOTYPE_LIST)));
2686 field_decl
2687 = build1 (INDIRECT_REF, NULL_TREE, get_identifier ("instance_methods"));
2688 field_decl
2689 = grokfield (input_filename, lineno, field_decl, decl_specs, NULL_TREE);
2690 chainon (field_decl_chain, field_decl);
2692 /* struct objc_method_list *class_methods; */
2694 decl_specs
2695 = build_tree_list (NULL_TREE,
2696 xref_tag (RECORD_TYPE,
2697 get_identifier (UTAG_METHOD_PROTOTYPE_LIST)));
2698 field_decl
2699 = build1 (INDIRECT_REF, NULL_TREE, get_identifier ("class_methods"));
2700 field_decl
2701 = grokfield (input_filename, lineno, field_decl, decl_specs, NULL_TREE);
2702 chainon (field_decl_chain, field_decl);
2704 return finish_struct (template, field_decl_chain, NULL_TREE);
2707 static tree
2708 build_descriptor_table_initializer (type, entries)
2709 tree type;
2710 tree entries;
2712 tree initlist = NULL_TREE;
2716 tree eltlist = NULL_TREE;
2718 eltlist
2719 = tree_cons (NULL_TREE,
2720 build_selector (METHOD_SEL_NAME (entries)), NULL_TREE);
2721 eltlist
2722 = tree_cons (NULL_TREE,
2723 add_objc_string (METHOD_ENCODING (entries),
2724 meth_var_types),
2725 eltlist);
2727 initlist
2728 = tree_cons (NULL_TREE,
2729 build_constructor (type, nreverse (eltlist)), initlist);
2731 entries = TREE_CHAIN (entries);
2733 while (entries);
2735 return build_constructor (build_array_type (type, 0), nreverse (initlist));
2738 /* struct objc_method_prototype_list {
2739 int count;
2740 struct objc_method_prototype {
2741 SEL name;
2742 char *types;
2743 } list[1];
2744 }; */
2746 static tree
2747 build_method_prototype_list_template (list_type, size)
2748 tree list_type;
2749 int size;
2751 tree objc_ivar_list_record;
2752 tree decl_specs, field_decl, field_decl_chain;
2754 /* Generate an unnamed struct definition. */
2756 objc_ivar_list_record = start_struct (RECORD_TYPE, NULL_TREE);
2758 /* int method_count; */
2760 decl_specs = build_tree_list (NULL_TREE, ridpointers[(int) RID_INT]);
2761 field_decl = get_identifier ("method_count");
2763 field_decl
2764 = grokfield (input_filename, lineno, field_decl, decl_specs, NULL_TREE);
2765 field_decl_chain = field_decl;
2767 /* struct objc_method method_list[]; */
2769 decl_specs = build_tree_list (NULL_TREE, list_type);
2770 field_decl = build_nt (ARRAY_REF, get_identifier ("method_list"),
2771 build_int_2 (size, 0));
2773 field_decl
2774 = grokfield (input_filename, lineno, field_decl, decl_specs, NULL_TREE);
2775 chainon (field_decl_chain, field_decl);
2777 finish_struct (objc_ivar_list_record, field_decl_chain, NULL_TREE);
2779 return objc_ivar_list_record;
2782 static tree
2783 build_method_prototype_template ()
2785 tree proto_record;
2786 tree decl_specs, field_decl, field_decl_chain;
2788 proto_record
2789 = start_struct (RECORD_TYPE, get_identifier (UTAG_METHOD_PROTOTYPE));
2791 #ifdef OBJC_INT_SELECTORS
2792 /* unsigned int _cmd; */
2793 decl_specs
2794 = tree_cons (NULL_TREE, ridpointers[(int) RID_UNSIGNED], NULL_TREE);
2795 decl_specs = tree_cons (NULL_TREE, ridpointers[(int) RID_INT], decl_specs);
2796 field_decl = get_identifier ("_cmd");
2797 #else /* OBJC_INT_SELECTORS */
2798 /* struct objc_selector *_cmd; */
2799 decl_specs = tree_cons (NULL_TREE, xref_tag (RECORD_TYPE,
2800 get_identifier (TAG_SELECTOR)), NULL_TREE);
2801 field_decl = build1 (INDIRECT_REF, NULL_TREE, get_identifier ("_cmd"));
2802 #endif /* OBJC_INT_SELECTORS */
2804 field_decl
2805 = grokfield (input_filename, lineno, field_decl, decl_specs, NULL_TREE);
2806 field_decl_chain = field_decl;
2808 decl_specs = tree_cons (NULL_TREE, ridpointers[(int) RID_CHAR], NULL_TREE);
2809 field_decl
2810 = build1 (INDIRECT_REF, NULL_TREE, get_identifier ("method_types"));
2811 field_decl
2812 = grokfield (input_filename, lineno, field_decl, decl_specs, NULL_TREE);
2813 chainon (field_decl_chain, field_decl);
2815 finish_struct (proto_record, field_decl_chain, NULL_TREE);
2817 return proto_record;
2820 /* True if last call to forwarding_offset yielded a register offset. */
2821 static int offset_is_register;
2823 static int
2824 forwarding_offset (parm)
2825 tree parm;
2827 int offset_in_bytes;
2829 if (GET_CODE (DECL_INCOMING_RTL (parm)) == MEM)
2831 rtx addr = XEXP (DECL_INCOMING_RTL (parm), 0);
2833 /* ??? Here we assume that the parm address is indexed
2834 off the frame pointer or arg pointer.
2835 If that is not true, we produce meaningless results,
2836 but do not crash. */
2837 if (GET_CODE (addr) == PLUS
2838 && GET_CODE (XEXP (addr, 1)) == CONST_INT)
2839 offset_in_bytes = INTVAL (XEXP (addr, 1));
2840 else
2841 offset_in_bytes = 0;
2843 offset_in_bytes += OBJC_FORWARDING_STACK_OFFSET;
2844 offset_is_register = 0;
2846 else if (GET_CODE (DECL_INCOMING_RTL (parm)) == REG)
2848 int regno = REGNO (DECL_INCOMING_RTL (parm));
2849 offset_in_bytes = apply_args_register_offset (regno);
2850 offset_is_register = 1;
2852 else
2853 return 0;
2855 /* This is the case where the parm is passed as an int or double
2856 and it is converted to a char, short or float and stored back
2857 in the parmlist. In this case, describe the parm
2858 with the variable's declared type, and adjust the address
2859 if the least significant bytes (which we are using) are not
2860 the first ones. */
2861 if (BYTES_BIG_ENDIAN && TREE_TYPE (parm) != DECL_ARG_TYPE (parm))
2862 offset_in_bytes += (GET_MODE_SIZE (TYPE_MODE (DECL_ARG_TYPE (parm)))
2863 - GET_MODE_SIZE (GET_MODE (DECL_RTL (parm))));
2865 return offset_in_bytes;
2868 static tree
2869 encode_method_prototype (method_decl, func_decl)
2870 tree method_decl;
2871 tree func_decl;
2873 tree parms;
2874 int stack_size, i;
2875 tree user_args;
2876 HOST_WIDE_INT max_parm_end = 0;
2877 char buf[40];
2878 tree result;
2880 /* ONEWAY and BYCOPY, for remote object are the only method qualifiers. */
2881 encode_type_qualifiers (TREE_PURPOSE (TREE_TYPE (method_decl)));
2883 /* C type. */
2884 encode_type (TREE_TYPE (TREE_TYPE (func_decl)),
2885 obstack_object_size (&util_obstack),
2886 OBJC_ENCODE_INLINE_DEFS);
2888 /* Stack size. */
2889 for (parms = DECL_ARGUMENTS (func_decl); parms;
2890 parms = TREE_CHAIN (parms))
2892 HOST_WIDE_INT parm_end = (forwarding_offset (parms)
2893 + int_size_in_bytes (TREE_TYPE (parms)));
2895 if (!offset_is_register && max_parm_end < parm_end)
2896 max_parm_end = parm_end;
2899 stack_size = max_parm_end - OBJC_FORWARDING_MIN_OFFSET;
2901 sprintf (buf, "%d", stack_size);
2902 obstack_grow (&util_obstack, buf, strlen (buf));
2904 user_args = METHOD_SEL_ARGS (method_decl);
2906 /* Argument types. */
2907 for (parms = DECL_ARGUMENTS (func_decl), i = 0; parms;
2908 parms = TREE_CHAIN (parms), i++)
2910 /* Process argument qualifiers for user supplied arguments. */
2911 if (i > 1)
2913 encode_type_qualifiers (TREE_PURPOSE (TREE_TYPE (user_args)));
2914 user_args = TREE_CHAIN (user_args);
2917 /* Type. */
2918 encode_type (TREE_TYPE (parms),
2919 obstack_object_size (&util_obstack),
2920 OBJC_ENCODE_INLINE_DEFS);
2922 /* Compute offset. */
2923 sprintf (buf, "%d", forwarding_offset (parms));
2925 /* Indicate register. */
2926 if (offset_is_register)
2927 obstack_1grow (&util_obstack, '+');
2929 obstack_grow (&util_obstack, buf, strlen (buf));
2932 obstack_1grow (&util_obstack, '\0');
2933 result = get_identifier (obstack_finish (&util_obstack));
2934 obstack_free (&util_obstack, util_firstobj);
2935 return result;
2938 static tree
2939 generate_descriptor_table (type, name, size, list, proto)
2940 tree type;
2941 const char *name;
2942 int size;
2943 tree list;
2944 tree proto;
2946 tree sc_spec, decl_specs, decl, initlist;
2948 sc_spec = tree_cons (NULL_TREE, ridpointers[(int) RID_STATIC], NULL_TREE);
2949 decl_specs = tree_cons (NULL_TREE, type, sc_spec);
2951 decl = start_decl (synth_id_with_class_suffix (name, proto),
2952 decl_specs, 1, NULL_TREE, NULL_TREE);
2954 initlist = build_tree_list (NULL_TREE, build_int_2 (size, 0));
2955 initlist = tree_cons (NULL_TREE, list, initlist);
2957 finish_decl (decl, build_constructor (type, nreverse (initlist)),
2958 NULL_TREE);
2960 return decl;
2963 static void
2964 generate_method_descriptors (protocol) /* generate_dispatch_tables */
2965 tree protocol;
2967 static tree objc_method_prototype_template;
2968 tree initlist, chain, method_list_template;
2969 tree cast, variable_length_type;
2970 int size;
2972 if (!objc_method_prototype_template)
2974 objc_method_prototype_template = build_method_prototype_template ();
2975 ggc_add_tree_root (&objc_method_prototype_template, 1);
2978 cast = build_tree_list (build_tree_list (NULL_TREE, xref_tag (RECORD_TYPE,
2979 get_identifier (UTAG_METHOD_PROTOTYPE_LIST))),
2980 NULL_TREE);
2981 variable_length_type = groktypename (cast);
2983 chain = PROTOCOL_CLS_METHODS (protocol);
2984 if (chain)
2986 size = list_length (chain);
2988 method_list_template
2989 = build_method_prototype_list_template (objc_method_prototype_template,
2990 size);
2992 initlist
2993 = build_descriptor_table_initializer (objc_method_prototype_template,
2994 chain);
2996 UOBJC_CLASS_METHODS_decl
2997 = generate_descriptor_table (method_list_template,
2998 "_OBJC_PROTOCOL_CLASS_METHODS",
2999 size, initlist, protocol);
3000 TREE_TYPE (UOBJC_CLASS_METHODS_decl) = variable_length_type;
3002 else
3003 UOBJC_CLASS_METHODS_decl = 0;
3005 chain = PROTOCOL_NST_METHODS (protocol);
3006 if (chain)
3008 size = list_length (chain);
3010 method_list_template
3011 = build_method_prototype_list_template (objc_method_prototype_template,
3012 size);
3013 initlist
3014 = build_descriptor_table_initializer (objc_method_prototype_template,
3015 chain);
3017 UOBJC_INSTANCE_METHODS_decl
3018 = generate_descriptor_table (method_list_template,
3019 "_OBJC_PROTOCOL_INSTANCE_METHODS",
3020 size, initlist, protocol);
3021 TREE_TYPE (UOBJC_INSTANCE_METHODS_decl) = variable_length_type;
3023 else
3024 UOBJC_INSTANCE_METHODS_decl = 0;
3027 static tree
3028 build_tmp_function_decl ()
3030 tree decl_specs, expr_decl, parms;
3031 static int xxx = 0;
3032 char buffer[80];
3034 /* struct objc_object *objc_xxx (id, SEL, ...); */
3035 pushlevel (0);
3036 decl_specs = build_tree_list (NULL_TREE, objc_object_reference);
3037 push_parm_decl (build_tree_list
3038 (build_tree_list (decl_specs,
3039 build1 (INDIRECT_REF, NULL_TREE,
3040 NULL_TREE)),
3041 build_tree_list (NULL_TREE, NULL_TREE)));
3043 decl_specs = build_tree_list (NULL_TREE, xref_tag (RECORD_TYPE,
3044 get_identifier (TAG_SELECTOR)));
3045 expr_decl = build1 (INDIRECT_REF, NULL_TREE, NULL_TREE);
3047 push_parm_decl (build_tree_list (build_tree_list (decl_specs, expr_decl),
3048 build_tree_list (NULL_TREE, NULL_TREE)));
3049 parms = get_parm_info (0);
3050 poplevel (0, 0, 0);
3052 decl_specs = build_tree_list (NULL_TREE, objc_object_reference);
3053 sprintf (buffer, "__objc_tmp_%x", xxx++);
3054 expr_decl = build_nt (CALL_EXPR, get_identifier (buffer), parms, NULL_TREE);
3055 expr_decl = build1 (INDIRECT_REF, NULL_TREE, expr_decl);
3057 return define_decl (expr_decl, decl_specs);
3060 static void
3061 hack_method_prototype (nst_methods, tmp_decl)
3062 tree nst_methods;
3063 tree tmp_decl;
3065 tree parms;
3066 tree parm;
3068 /* Hack to avoid problem with static typing of self arg. */
3069 TREE_SET_CODE (nst_methods, CLASS_METHOD_DECL);
3070 start_method_def (nst_methods);
3071 TREE_SET_CODE (nst_methods, INSTANCE_METHOD_DECL);
3073 if (METHOD_ADD_ARGS (nst_methods) == objc_ellipsis_node)
3074 parms = get_parm_info (0); /* we have a `, ...' */
3075 else
3076 parms = get_parm_info (1); /* place a `void_at_end' */
3078 poplevel (0, 0, 0); /* Must be called BEFORE start_function. */
3080 /* Usually called from store_parm_decls -> init_function_start. */
3082 DECL_ARGUMENTS (tmp_decl) = TREE_PURPOSE (parms);
3083 current_function_decl = tmp_decl;
3086 /* Code taken from start_function. */
3087 tree restype = TREE_TYPE (TREE_TYPE (tmp_decl));
3088 /* Promote the value to int before returning it. */
3089 if (TREE_CODE (restype) == INTEGER_TYPE
3090 && TYPE_PRECISION (restype) < TYPE_PRECISION (integer_type_node))
3091 restype = integer_type_node;
3092 DECL_RESULT (tmp_decl) = build_decl (RESULT_DECL, 0, restype);
3095 for (parm = DECL_ARGUMENTS (tmp_decl); parm; parm = TREE_CHAIN (parm))
3096 DECL_CONTEXT (parm) = tmp_decl;
3098 init_function_start (tmp_decl, "objc-act", 0);
3100 /* Typically called from expand_function_start for function definitions. */
3101 assign_parms (tmp_decl);
3103 /* install return type */
3104 TREE_TYPE (TREE_TYPE (tmp_decl)) = groktypename (TREE_TYPE (nst_methods));
3108 static void
3109 generate_protocol_references (plist)
3110 tree plist;
3112 tree lproto;
3114 /* Forward declare protocols referenced. */
3115 for (lproto = plist; lproto; lproto = TREE_CHAIN (lproto))
3117 tree proto = TREE_VALUE (lproto);
3119 if (TREE_CODE (proto) == PROTOCOL_INTERFACE_TYPE
3120 && PROTOCOL_NAME (proto))
3122 if (! PROTOCOL_FORWARD_DECL (proto))
3123 build_protocol_reference (proto);
3125 if (PROTOCOL_LIST (proto))
3126 generate_protocol_references (PROTOCOL_LIST (proto));
3131 static void
3132 generate_protocols ()
3134 tree p, tmp_decl, encoding;
3135 tree sc_spec, decl_specs, decl;
3136 tree initlist, protocol_name_expr, refs_decl, refs_expr;
3137 tree cast_type2;
3139 tmp_decl = build_tmp_function_decl ();
3141 if (! objc_protocol_template)
3142 objc_protocol_template = build_protocol_template ();
3144 /* If a protocol was directly referenced, pull in indirect references. */
3145 for (p = protocol_chain; p; p = TREE_CHAIN (p))
3146 if (PROTOCOL_FORWARD_DECL (p) && PROTOCOL_LIST (p))
3147 generate_protocol_references (PROTOCOL_LIST (p));
3149 for (p = protocol_chain; p; p = TREE_CHAIN (p))
3151 tree nst_methods = PROTOCOL_NST_METHODS (p);
3152 tree cls_methods = PROTOCOL_CLS_METHODS (p);
3154 /* If protocol wasn't referenced, don't generate any code. */
3155 if (! PROTOCOL_FORWARD_DECL (p))
3156 continue;
3158 /* Make sure we link in the Protocol class. */
3159 add_class_reference (get_identifier (PROTOCOL_OBJECT_CLASS_NAME));
3161 while (nst_methods)
3163 if (! METHOD_ENCODING (nst_methods))
3165 hack_method_prototype (nst_methods, tmp_decl);
3166 encoding = encode_method_prototype (nst_methods, tmp_decl);
3167 METHOD_ENCODING (nst_methods) = encoding;
3169 nst_methods = TREE_CHAIN (nst_methods);
3172 while (cls_methods)
3174 if (! METHOD_ENCODING (cls_methods))
3176 hack_method_prototype (cls_methods, tmp_decl);
3177 encoding = encode_method_prototype (cls_methods, tmp_decl);
3178 METHOD_ENCODING (cls_methods) = encoding;
3181 cls_methods = TREE_CHAIN (cls_methods);
3183 generate_method_descriptors (p);
3185 if (PROTOCOL_LIST (p))
3186 refs_decl = generate_protocol_list (p);
3187 else
3188 refs_decl = 0;
3190 /* static struct objc_protocol _OBJC_PROTOCOL_<mumble>; */
3192 sc_spec = tree_cons (NULL_TREE, ridpointers[(int) RID_STATIC],
3193 NULL_TREE);
3194 decl_specs = tree_cons (NULL_TREE, objc_protocol_template, sc_spec);
3196 decl = start_decl (synth_id_with_class_suffix ("_OBJC_PROTOCOL", p),
3197 decl_specs, 1, NULL_TREE, NULL_TREE);
3199 protocol_name_expr = add_objc_string (PROTOCOL_NAME (p), class_names);
3201 if (refs_decl)
3203 cast_type2
3204 = groktypename
3205 (build_tree_list (build_tree_list (NULL_TREE,
3206 objc_protocol_template),
3207 build1 (INDIRECT_REF, NULL_TREE,
3208 build1 (INDIRECT_REF, NULL_TREE,
3209 NULL_TREE))));
3211 refs_expr = build_unary_op (ADDR_EXPR, refs_decl, 0);
3212 TREE_TYPE (refs_expr) = cast_type2;
3214 else
3215 refs_expr = build_int_2 (0, 0);
3217 /* UOBJC_INSTANCE_METHODS_decl/UOBJC_CLASS_METHODS_decl are set
3218 by generate_method_descriptors, which is called above. */
3219 initlist = build_protocol_initializer (TREE_TYPE (decl),
3220 protocol_name_expr, refs_expr,
3221 UOBJC_INSTANCE_METHODS_decl,
3222 UOBJC_CLASS_METHODS_decl);
3223 finish_decl (decl, initlist, NULL_TREE);
3225 /* Mark the decl as used to avoid "defined but not used" warning. */
3226 TREE_USED (decl) = 1;
3230 static tree
3231 build_protocol_initializer (type, protocol_name, protocol_list,
3232 instance_methods, class_methods)
3233 tree type;
3234 tree protocol_name;
3235 tree protocol_list;
3236 tree instance_methods;
3237 tree class_methods;
3239 tree initlist = NULL_TREE, expr;
3240 tree cast_type;
3242 cast_type = groktypename
3243 (build_tree_list
3244 (build_tree_list (NULL_TREE,
3245 xref_tag (RECORD_TYPE,
3246 get_identifier (UTAG_CLASS))),
3247 build1 (INDIRECT_REF, NULL_TREE, NULL_TREE)));
3249 /* Filling the "isa" in with one allows the runtime system to
3250 detect that the version change...should remove before final release. */
3252 expr = build_int_2 (PROTOCOL_VERSION, 0);
3253 TREE_TYPE (expr) = cast_type;
3254 initlist = tree_cons (NULL_TREE, expr, initlist);
3255 initlist = tree_cons (NULL_TREE, protocol_name, initlist);
3256 initlist = tree_cons (NULL_TREE, protocol_list, initlist);
3258 if (!instance_methods)
3259 initlist = tree_cons (NULL_TREE, build_int_2 (0, 0), initlist);
3260 else
3262 expr = build_unary_op (ADDR_EXPR, instance_methods, 0);
3263 initlist = tree_cons (NULL_TREE, expr, initlist);
3266 if (!class_methods)
3267 initlist = tree_cons (NULL_TREE, build_int_2 (0, 0), initlist);
3268 else
3270 expr = build_unary_op (ADDR_EXPR, class_methods, 0);
3271 initlist = tree_cons (NULL_TREE, expr, initlist);
3274 return build_constructor (type, nreverse (initlist));
3277 /* struct objc_category {
3278 char *category_name;
3279 char *class_name;
3280 struct objc_method_list *instance_methods;
3281 struct objc_method_list *class_methods;
3282 struct objc_protocol_list *protocols;
3283 }; */
3285 static void
3286 build_category_template ()
3288 tree decl_specs, field_decl, field_decl_chain;
3290 objc_category_template = start_struct (RECORD_TYPE,
3291 get_identifier (UTAG_CATEGORY));
3292 /* char *category_name; */
3294 decl_specs = build_tree_list (NULL_TREE, ridpointers[(int) RID_CHAR]);
3295 field_decl
3296 = build1 (INDIRECT_REF, NULL_TREE, get_identifier ("category_name"));
3297 field_decl
3298 = grokfield (input_filename, lineno, field_decl, decl_specs, NULL_TREE);
3299 field_decl_chain = field_decl;
3301 /* char *class_name; */
3303 decl_specs = build_tree_list (NULL_TREE, ridpointers[(int) RID_CHAR]);
3304 field_decl = build1 (INDIRECT_REF, NULL_TREE, get_identifier ("class_name"));
3305 field_decl
3306 = grokfield (input_filename, lineno, field_decl, decl_specs, NULL_TREE);
3307 chainon (field_decl_chain, field_decl);
3309 /* struct objc_method_list *instance_methods; */
3311 decl_specs = build_tree_list (NULL_TREE,
3312 xref_tag (RECORD_TYPE,
3313 get_identifier (UTAG_METHOD_LIST)));
3314 field_decl
3315 = build1 (INDIRECT_REF, NULL_TREE, get_identifier ("instance_methods"));
3316 field_decl
3317 = grokfield (input_filename, lineno, field_decl, decl_specs, NULL_TREE);
3318 chainon (field_decl_chain, field_decl);
3320 /* struct objc_method_list *class_methods; */
3322 decl_specs = build_tree_list (NULL_TREE,
3323 xref_tag (RECORD_TYPE,
3324 get_identifier (UTAG_METHOD_LIST)));
3325 field_decl
3326 = build1 (INDIRECT_REF, NULL_TREE, get_identifier ("class_methods"));
3327 field_decl
3328 = grokfield (input_filename, lineno, field_decl, decl_specs, NULL_TREE);
3329 chainon (field_decl_chain, field_decl);
3331 /* struct objc_protocol **protocol_list; */
3333 decl_specs = build_tree_list (NULL_TREE,
3334 xref_tag (RECORD_TYPE,
3335 get_identifier (UTAG_PROTOCOL)));
3336 field_decl
3337 = build1 (INDIRECT_REF, NULL_TREE, get_identifier ("protocol_list"));
3338 field_decl = build1 (INDIRECT_REF, NULL_TREE, field_decl);
3339 field_decl
3340 = grokfield (input_filename, lineno, field_decl, decl_specs, NULL_TREE);
3341 chainon (field_decl_chain, field_decl);
3343 finish_struct (objc_category_template, field_decl_chain, NULL_TREE);
3346 /* struct objc_selector {
3347 void *sel_id;
3348 char *sel_type;
3349 }; */
3351 static void
3352 build_selector_template ()
3355 tree decl_specs, field_decl, field_decl_chain;
3357 objc_selector_template
3358 = start_struct (RECORD_TYPE, get_identifier (UTAG_SELECTOR));
3360 /* void *sel_id; */
3362 decl_specs = build_tree_list (NULL_TREE, ridpointers[(int) RID_VOID]);
3363 field_decl = build1 (INDIRECT_REF, NULL_TREE, get_identifier ("sel_id"));
3364 field_decl
3365 = grokfield (input_filename, lineno, field_decl, decl_specs, NULL_TREE);
3366 field_decl_chain = field_decl;
3368 /* char *sel_type; */
3370 decl_specs = build_tree_list (NULL_TREE, ridpointers[(int) RID_CHAR]);
3371 field_decl = build1 (INDIRECT_REF, NULL_TREE, get_identifier ("sel_type"));
3372 field_decl
3373 = grokfield (input_filename, lineno, field_decl, decl_specs, NULL_TREE);
3374 chainon (field_decl_chain, field_decl);
3376 finish_struct (objc_selector_template, field_decl_chain, NULL_TREE);
3379 /* struct objc_class {
3380 struct objc_class *isa;
3381 struct objc_class *super_class;
3382 char *name;
3383 long version;
3384 long info;
3385 long instance_size;
3386 struct objc_ivar_list *ivars;
3387 struct objc_method_list *methods;
3388 if (flag_next_runtime)
3389 struct objc_cache *cache;
3390 else {
3391 struct sarray *dtable;
3392 struct objc_class *subclass_list;
3393 struct objc_class *sibling_class;
3395 struct objc_protocol_list *protocols;
3396 void *gc_object_type;
3397 }; */
3399 static void
3400 build_class_template ()
3402 tree decl_specs, field_decl, field_decl_chain;
3404 objc_class_template
3405 = start_struct (RECORD_TYPE, get_identifier (UTAG_CLASS));
3407 /* struct objc_class *isa; */
3409 decl_specs = build_tree_list (NULL_TREE, objc_class_template);
3410 field_decl = build1 (INDIRECT_REF, NULL_TREE, get_identifier ("isa"));
3411 field_decl
3412 = grokfield (input_filename, lineno, field_decl, decl_specs, NULL_TREE);
3413 field_decl_chain = field_decl;
3415 /* struct objc_class *super_class; */
3417 decl_specs = build_tree_list (NULL_TREE, objc_class_template);
3418 field_decl
3419 = build1 (INDIRECT_REF, NULL_TREE, get_identifier ("super_class"));
3420 field_decl
3421 = grokfield (input_filename, lineno, field_decl, decl_specs, NULL_TREE);
3422 chainon (field_decl_chain, field_decl);
3424 /* char *name; */
3426 decl_specs = build_tree_list (NULL_TREE, ridpointers[(int) RID_CHAR]);
3427 field_decl = build1 (INDIRECT_REF, NULL_TREE, get_identifier ("name"));
3428 field_decl
3429 = grokfield (input_filename, lineno, field_decl, decl_specs, NULL_TREE);
3430 chainon (field_decl_chain, field_decl);
3432 /* long version; */
3434 decl_specs = build_tree_list (NULL_TREE, ridpointers[(int) RID_LONG]);
3435 field_decl = get_identifier ("version");
3436 field_decl
3437 = grokfield (input_filename, lineno, field_decl, decl_specs, NULL_TREE);
3438 chainon (field_decl_chain, field_decl);
3440 /* long info; */
3442 decl_specs = build_tree_list (NULL_TREE, ridpointers[(int) RID_LONG]);
3443 field_decl = get_identifier ("info");
3444 field_decl
3445 = grokfield (input_filename, lineno, field_decl, decl_specs, NULL_TREE);
3446 chainon (field_decl_chain, field_decl);
3448 /* long instance_size; */
3450 decl_specs = build_tree_list (NULL_TREE, ridpointers[(int) RID_LONG]);
3451 field_decl = get_identifier ("instance_size");
3452 field_decl
3453 = grokfield (input_filename, lineno, field_decl, decl_specs, NULL_TREE);
3454 chainon (field_decl_chain, field_decl);
3456 /* struct objc_ivar_list *ivars; */
3458 decl_specs = build_tree_list (NULL_TREE,
3459 xref_tag (RECORD_TYPE,
3460 get_identifier (UTAG_IVAR_LIST)));
3461 field_decl = build1 (INDIRECT_REF, NULL_TREE, get_identifier ("ivars"));
3462 field_decl
3463 = grokfield (input_filename, lineno, field_decl, decl_specs, NULL_TREE);
3464 chainon (field_decl_chain, field_decl);
3466 /* struct objc_method_list *methods; */
3468 decl_specs = build_tree_list (NULL_TREE,
3469 xref_tag (RECORD_TYPE,
3470 get_identifier (UTAG_METHOD_LIST)));
3471 field_decl = build1 (INDIRECT_REF, NULL_TREE, get_identifier ("methods"));
3472 field_decl
3473 = grokfield (input_filename, lineno, field_decl, decl_specs, NULL_TREE);
3474 chainon (field_decl_chain, field_decl);
3476 if (flag_next_runtime)
3478 /* struct objc_cache *cache; */
3480 decl_specs = build_tree_list (NULL_TREE,
3481 xref_tag (RECORD_TYPE,
3482 get_identifier ("objc_cache")));
3483 field_decl = build1 (INDIRECT_REF, NULL_TREE, get_identifier ("cache"));
3484 field_decl = grokfield (input_filename, lineno, field_decl,
3485 decl_specs, NULL_TREE);
3486 chainon (field_decl_chain, field_decl);
3488 else
3490 /* struct sarray *dtable; */
3492 decl_specs = build_tree_list (NULL_TREE,
3493 xref_tag (RECORD_TYPE,
3494 get_identifier ("sarray")));
3495 field_decl = build1 (INDIRECT_REF, NULL_TREE, get_identifier ("dtable"));
3496 field_decl = grokfield (input_filename, lineno, field_decl,
3497 decl_specs, NULL_TREE);
3498 chainon (field_decl_chain, field_decl);
3500 /* struct objc_class *subclass_list; */
3502 decl_specs = build_tree_list (NULL_TREE, objc_class_template);
3503 field_decl
3504 = build1 (INDIRECT_REF, NULL_TREE, get_identifier ("subclass_list"));
3505 field_decl = grokfield (input_filename, lineno, field_decl,
3506 decl_specs, NULL_TREE);
3507 chainon (field_decl_chain, field_decl);
3509 /* struct objc_class *sibling_class; */
3511 decl_specs = build_tree_list (NULL_TREE, objc_class_template);
3512 field_decl
3513 = build1 (INDIRECT_REF, NULL_TREE, get_identifier ("sibling_class"));
3514 field_decl = grokfield (input_filename, lineno, field_decl,
3515 decl_specs, NULL_TREE);
3516 chainon (field_decl_chain, field_decl);
3519 /* struct objc_protocol **protocol_list; */
3521 decl_specs = build_tree_list (NULL_TREE,
3522 xref_tag (RECORD_TYPE,
3523 get_identifier (UTAG_PROTOCOL)));
3524 field_decl
3525 = build1 (INDIRECT_REF, NULL_TREE, get_identifier ("protocol_list"));
3526 field_decl
3527 = build1 (INDIRECT_REF, NULL_TREE, field_decl);
3528 field_decl = grokfield (input_filename, lineno, field_decl,
3529 decl_specs, NULL_TREE);
3530 chainon (field_decl_chain, field_decl);
3532 /* void *sel_id; */
3534 decl_specs = build_tree_list (NULL_TREE, ridpointers[(int) RID_VOID]);
3535 field_decl = build1 (INDIRECT_REF, NULL_TREE, get_identifier ("sel_id"));
3536 field_decl
3537 = grokfield (input_filename, lineno, field_decl, decl_specs, NULL_TREE);
3538 chainon (field_decl_chain, field_decl);
3540 /* void *gc_object_type; */
3542 decl_specs = build_tree_list (NULL_TREE, ridpointers[(int) RID_VOID]);
3543 field_decl = build1 (INDIRECT_REF, NULL_TREE, get_identifier ("gc_object_type"));
3544 field_decl
3545 = grokfield (input_filename, lineno, field_decl, decl_specs, NULL_TREE);
3546 chainon (field_decl_chain, field_decl);
3548 finish_struct (objc_class_template, field_decl_chain, NULL_TREE);
3551 /* Generate appropriate forward declarations for an implementation. */
3553 static void
3554 synth_forward_declarations ()
3556 tree sc_spec, decl_specs, an_id;
3558 /* extern struct objc_class _OBJC_CLASS_<my_name>; */
3560 an_id = synth_id_with_class_suffix ("_OBJC_CLASS", implementation_context);
3562 sc_spec = build_tree_list (NULL_TREE, ridpointers[(int) RID_EXTERN]);
3563 decl_specs = tree_cons (NULL_TREE, objc_class_template, sc_spec);
3564 UOBJC_CLASS_decl = define_decl (an_id, decl_specs);
3565 TREE_USED (UOBJC_CLASS_decl) = 1;
3566 DECL_ARTIFICIAL (UOBJC_CLASS_decl) = 1;
3568 /* extern struct objc_class _OBJC_METACLASS_<my_name>; */
3570 an_id = synth_id_with_class_suffix ("_OBJC_METACLASS",
3571 implementation_context);
3573 UOBJC_METACLASS_decl = define_decl (an_id, decl_specs);
3574 TREE_USED (UOBJC_METACLASS_decl) = 1;
3575 DECL_ARTIFICIAL(UOBJC_METACLASS_decl) = 1;
3577 /* Pre-build the following entities - for speed/convenience. */
3579 an_id = get_identifier ("super_class");
3580 ucls_super_ref = build_component_ref (UOBJC_CLASS_decl, an_id);
3581 uucls_super_ref = build_component_ref (UOBJC_METACLASS_decl, an_id);
3584 static void
3585 error_with_ivar (message, decl, rawdecl)
3586 const char *message;
3587 tree decl;
3588 tree rawdecl;
3590 count_error (0);
3592 report_error_function (DECL_SOURCE_FILE (decl));
3594 fprintf (stderr, "%s:%d: ",
3595 DECL_SOURCE_FILE (decl), DECL_SOURCE_LINE (decl));
3596 memset (errbuf, 0, BUFSIZE);
3597 fprintf (stderr, "%s `%s'\n", message, gen_declaration (rawdecl, errbuf));
3600 #define USERTYPE(t) \
3601 (TREE_CODE (t) == RECORD_TYPE || TREE_CODE (t) == UNION_TYPE \
3602 || TREE_CODE (t) == ENUMERAL_TYPE)
3604 static void
3605 check_ivars (inter, imp)
3606 tree inter;
3607 tree imp;
3609 tree intdecls = CLASS_IVARS (inter);
3610 tree impdecls = CLASS_IVARS (imp);
3611 tree rawintdecls = CLASS_RAW_IVARS (inter);
3612 tree rawimpdecls = CLASS_RAW_IVARS (imp);
3614 while (1)
3616 tree t1, t2;
3618 if (intdecls == 0 && impdecls == 0)
3619 break;
3620 if (intdecls == 0 || impdecls == 0)
3622 error ("inconsistent instance variable specification");
3623 break;
3626 t1 = TREE_TYPE (intdecls); t2 = TREE_TYPE (impdecls);
3628 if (!comptypes (t1, t2))
3630 if (DECL_NAME (intdecls) == DECL_NAME (impdecls))
3632 error_with_ivar ("conflicting instance variable type",
3633 impdecls, rawimpdecls);
3634 error_with_ivar ("previous declaration of",
3635 intdecls, rawintdecls);
3637 else /* both the type and the name don't match */
3639 error ("inconsistent instance variable specification");
3640 break;
3644 else if (DECL_NAME (intdecls) != DECL_NAME (impdecls))
3646 error_with_ivar ("conflicting instance variable name",
3647 impdecls, rawimpdecls);
3648 error_with_ivar ("previous declaration of",
3649 intdecls, rawintdecls);
3652 intdecls = TREE_CHAIN (intdecls);
3653 impdecls = TREE_CHAIN (impdecls);
3654 rawintdecls = TREE_CHAIN (rawintdecls);
3655 rawimpdecls = TREE_CHAIN (rawimpdecls);
3659 /* Set super_type to the data type node for struct objc_super *,
3660 first defining struct objc_super itself.
3661 This needs to be done just once per compilation. */
3663 static tree
3664 build_super_template ()
3666 tree record, decl_specs, field_decl, field_decl_chain;
3668 record = start_struct (RECORD_TYPE, get_identifier (UTAG_SUPER));
3670 /* struct objc_object *self; */
3672 decl_specs = build_tree_list (NULL_TREE, objc_object_reference);
3673 field_decl = get_identifier ("self");
3674 field_decl = build1 (INDIRECT_REF, NULL_TREE, field_decl);
3675 field_decl = grokfield (input_filename, lineno,
3676 field_decl, decl_specs, NULL_TREE);
3677 field_decl_chain = field_decl;
3679 /* struct objc_class *class; */
3681 decl_specs = get_identifier (UTAG_CLASS);
3682 decl_specs = build_tree_list (NULL_TREE, xref_tag (RECORD_TYPE, decl_specs));
3683 field_decl = build1 (INDIRECT_REF, NULL_TREE, get_identifier ("class"));
3685 field_decl = grokfield (input_filename, lineno,
3686 field_decl, decl_specs, NULL_TREE);
3687 chainon (field_decl_chain, field_decl);
3689 finish_struct (record, field_decl_chain, NULL_TREE);
3691 /* `struct objc_super *' */
3692 super_type = groktypename (build_tree_list (build_tree_list (NULL_TREE,
3693 record),
3694 build1 (INDIRECT_REF,
3695 NULL_TREE, NULL_TREE)));
3696 return record;
3699 /* struct objc_ivar {
3700 char *ivar_name;
3701 char *ivar_type;
3702 int ivar_offset;
3703 }; */
3705 static tree
3706 build_ivar_template ()
3708 tree objc_ivar_id, objc_ivar_record;
3709 tree decl_specs, field_decl, field_decl_chain;
3711 objc_ivar_id = get_identifier (UTAG_IVAR);
3712 objc_ivar_record = start_struct (RECORD_TYPE, objc_ivar_id);
3714 /* char *ivar_name; */
3716 decl_specs = build_tree_list (NULL_TREE, ridpointers[(int) RID_CHAR]);
3717 field_decl = build1 (INDIRECT_REF, NULL_TREE, get_identifier ("ivar_name"));
3719 field_decl = grokfield (input_filename, lineno, field_decl,
3720 decl_specs, NULL_TREE);
3721 field_decl_chain = field_decl;
3723 /* char *ivar_type; */
3725 decl_specs = build_tree_list (NULL_TREE, ridpointers[(int) RID_CHAR]);
3726 field_decl = build1 (INDIRECT_REF, NULL_TREE, get_identifier ("ivar_type"));
3728 field_decl = grokfield (input_filename, lineno, field_decl,
3729 decl_specs, NULL_TREE);
3730 chainon (field_decl_chain, field_decl);
3732 /* int ivar_offset; */
3734 decl_specs = build_tree_list (NULL_TREE, ridpointers[(int) RID_INT]);
3735 field_decl = get_identifier ("ivar_offset");
3737 field_decl = grokfield (input_filename, lineno, field_decl,
3738 decl_specs, NULL_TREE);
3739 chainon (field_decl_chain, field_decl);
3741 finish_struct (objc_ivar_record, field_decl_chain, NULL_TREE);
3743 return objc_ivar_record;
3746 /* struct {
3747 int ivar_count;
3748 struct objc_ivar ivar_list[ivar_count];
3749 }; */
3751 static tree
3752 build_ivar_list_template (list_type, size)
3753 tree list_type;
3754 int size;
3756 tree objc_ivar_list_record;
3757 tree decl_specs, field_decl, field_decl_chain;
3759 objc_ivar_list_record = start_struct (RECORD_TYPE, NULL_TREE);
3761 /* int ivar_count; */
3763 decl_specs = build_tree_list (NULL_TREE, ridpointers[(int) RID_INT]);
3764 field_decl = get_identifier ("ivar_count");
3766 field_decl = grokfield (input_filename, lineno, field_decl,
3767 decl_specs, NULL_TREE);
3768 field_decl_chain = field_decl;
3770 /* struct objc_ivar ivar_list[]; */
3772 decl_specs = build_tree_list (NULL_TREE, list_type);
3773 field_decl = build_nt (ARRAY_REF, get_identifier ("ivar_list"),
3774 build_int_2 (size, 0));
3776 field_decl = grokfield (input_filename, lineno,
3777 field_decl, decl_specs, NULL_TREE);
3778 chainon (field_decl_chain, field_decl);
3780 finish_struct (objc_ivar_list_record, field_decl_chain, NULL_TREE);
3782 return objc_ivar_list_record;
3785 /* struct {
3786 int method_next;
3787 int method_count;
3788 struct objc_method method_list[method_count];
3789 }; */
3791 static tree
3792 build_method_list_template (list_type, size)
3793 tree list_type;
3794 int size;
3796 tree objc_ivar_list_record;
3797 tree decl_specs, field_decl, field_decl_chain;
3799 objc_ivar_list_record = start_struct (RECORD_TYPE, NULL_TREE);
3801 /* int method_next; */
3803 decl_specs
3804 = build_tree_list
3805 (NULL_TREE,
3806 xref_tag (RECORD_TYPE,
3807 get_identifier (UTAG_METHOD_PROTOTYPE_LIST)));
3808 field_decl
3809 = build1 (INDIRECT_REF, NULL_TREE, get_identifier ("method_next"));
3810 field_decl = grokfield (input_filename, lineno, field_decl,
3811 decl_specs, NULL_TREE);
3812 field_decl_chain = field_decl;
3814 /* int method_count; */
3816 decl_specs = build_tree_list (NULL_TREE, ridpointers[(int) RID_INT]);
3817 field_decl = get_identifier ("method_count");
3819 field_decl = grokfield (input_filename, lineno,
3820 field_decl, decl_specs, NULL_TREE);
3821 chainon (field_decl_chain, field_decl);
3823 /* struct objc_method method_list[]; */
3825 decl_specs = build_tree_list (NULL_TREE, list_type);
3826 field_decl = build_nt (ARRAY_REF, get_identifier ("method_list"),
3827 build_int_2 (size, 0));
3829 field_decl = grokfield (input_filename, lineno,
3830 field_decl, decl_specs, NULL_TREE);
3831 chainon (field_decl_chain, field_decl);
3833 finish_struct (objc_ivar_list_record, field_decl_chain, NULL_TREE);
3835 return objc_ivar_list_record;
3838 static tree
3839 build_ivar_list_initializer (type, field_decl)
3840 tree type;
3841 tree field_decl;
3843 tree initlist = NULL_TREE;
3847 tree ivar = NULL_TREE;
3849 /* Set name. */
3850 if (DECL_NAME (field_decl))
3851 ivar = tree_cons (NULL_TREE,
3852 add_objc_string (DECL_NAME (field_decl),
3853 meth_var_names),
3854 ivar);
3855 else
3856 /* Unnamed bit-field ivar (yuck). */
3857 ivar = tree_cons (NULL_TREE, build_int_2 (0, 0), ivar);
3859 /* Set type. */
3860 encode_field_decl (field_decl,
3861 obstack_object_size (&util_obstack),
3862 OBJC_ENCODE_DONT_INLINE_DEFS);
3864 /* Null terminate string. */
3865 obstack_1grow (&util_obstack, 0);
3866 ivar
3867 = tree_cons
3868 (NULL_TREE,
3869 add_objc_string (get_identifier (obstack_finish (&util_obstack)),
3870 meth_var_types),
3871 ivar);
3872 obstack_free (&util_obstack, util_firstobj);
3874 /* Set offset. */
3875 ivar = tree_cons (NULL_TREE, byte_position (field_decl), ivar);
3876 initlist = tree_cons (NULL_TREE,
3877 build_constructor (type, nreverse (ivar)),
3878 initlist);
3880 field_decl = TREE_CHAIN (field_decl);
3882 while (field_decl);
3884 return build_constructor (build_array_type (type, 0), nreverse (initlist));
3887 static tree
3888 generate_ivars_list (type, name, size, list)
3889 tree type;
3890 const char *name;
3891 int size;
3892 tree list;
3894 tree sc_spec, decl_specs, decl, initlist;
3896 sc_spec = tree_cons (NULL_TREE, ridpointers[(int) RID_STATIC], NULL_TREE);
3897 decl_specs = tree_cons (NULL_TREE, type, sc_spec);
3899 decl = start_decl (synth_id_with_class_suffix (name, implementation_context),
3900 decl_specs, 1, NULL_TREE, NULL_TREE);
3902 initlist = build_tree_list (NULL_TREE, build_int_2 (size, 0));
3903 initlist = tree_cons (NULL_TREE, list, initlist);
3905 finish_decl (decl,
3906 build_constructor (TREE_TYPE (decl), nreverse (initlist)),
3907 NULL_TREE);
3909 return decl;
3912 static void
3913 generate_ivar_lists ()
3915 tree initlist, ivar_list_template, chain;
3916 tree cast, variable_length_type;
3917 int size;
3919 generating_instance_variables = 1;
3921 if (!objc_ivar_template)
3922 objc_ivar_template = build_ivar_template ();
3924 cast
3925 = build_tree_list
3926 (build_tree_list (NULL_TREE, xref_tag (RECORD_TYPE,
3927 get_identifier (UTAG_IVAR_LIST))),
3928 NULL_TREE);
3929 variable_length_type = groktypename (cast);
3931 /* Only generate class variables for the root of the inheritance
3932 hierarchy since these will be the same for every class. */
3934 if (CLASS_SUPER_NAME (implementation_template) == NULL_TREE
3935 && (chain = TYPE_FIELDS (objc_class_template)))
3937 size = list_length (chain);
3939 ivar_list_template = build_ivar_list_template (objc_ivar_template, size);
3940 initlist = build_ivar_list_initializer (objc_ivar_template, chain);
3942 UOBJC_CLASS_VARIABLES_decl
3943 = generate_ivars_list (ivar_list_template, "_OBJC_CLASS_VARIABLES",
3944 size, initlist);
3945 TREE_TYPE (UOBJC_CLASS_VARIABLES_decl) = variable_length_type;
3947 else
3948 UOBJC_CLASS_VARIABLES_decl = 0;
3950 chain = CLASS_IVARS (implementation_template);
3951 if (chain)
3953 size = list_length (chain);
3954 ivar_list_template = build_ivar_list_template (objc_ivar_template, size);
3955 initlist = build_ivar_list_initializer (objc_ivar_template, chain);
3957 UOBJC_INSTANCE_VARIABLES_decl
3958 = generate_ivars_list (ivar_list_template, "_OBJC_INSTANCE_VARIABLES",
3959 size, initlist);
3960 TREE_TYPE (UOBJC_INSTANCE_VARIABLES_decl) = variable_length_type;
3962 else
3963 UOBJC_INSTANCE_VARIABLES_decl = 0;
3965 generating_instance_variables = 0;
3968 static tree
3969 build_dispatch_table_initializer (type, entries)
3970 tree type;
3971 tree entries;
3973 tree initlist = NULL_TREE;
3977 tree elemlist = NULL_TREE;
3979 elemlist = tree_cons (NULL_TREE,
3980 build_selector (METHOD_SEL_NAME (entries)),
3981 NULL_TREE);
3983 elemlist = tree_cons (NULL_TREE,
3984 add_objc_string (METHOD_ENCODING (entries),
3985 meth_var_types),
3986 elemlist);
3988 elemlist = tree_cons (NULL_TREE,
3989 build_unary_op (ADDR_EXPR,
3990 METHOD_DEFINITION (entries), 1),
3991 elemlist);
3993 initlist = tree_cons (NULL_TREE,
3994 build_constructor (type, nreverse (elemlist)),
3995 initlist);
3997 entries = TREE_CHAIN (entries);
3999 while (entries);
4001 return build_constructor (build_array_type (type, 0), nreverse (initlist));
4004 /* To accomplish method prototyping without generating all kinds of
4005 inane warnings, the definition of the dispatch table entries were
4006 changed from:
4008 struct objc_method { SEL _cmd; ...; id (*_imp)(); };
4010 struct objc_method { SEL _cmd; ...; void *_imp; }; */
4012 static tree
4013 build_method_template ()
4015 tree _SLT_record;
4016 tree decl_specs, field_decl, field_decl_chain;
4018 _SLT_record = start_struct (RECORD_TYPE, get_identifier (UTAG_METHOD));
4020 #ifdef OBJC_INT_SELECTORS
4021 /* unsigned int _cmd; */
4022 decl_specs = tree_cons (NULL_TREE, ridpointers[(int) RID_UNSIGNED],
4023 NULL_TREE);
4024 decl_specs = tree_cons (NULL_TREE, ridpointers[(int) RID_INT], decl_specs);
4025 field_decl = get_identifier ("_cmd");
4026 #else /* not OBJC_INT_SELECTORS */
4027 /* struct objc_selector *_cmd; */
4028 decl_specs = tree_cons (NULL_TREE,
4029 xref_tag (RECORD_TYPE,
4030 get_identifier (TAG_SELECTOR)),
4031 NULL_TREE);
4032 field_decl = build1 (INDIRECT_REF, NULL_TREE, get_identifier ("_cmd"));
4033 #endif /* not OBJC_INT_SELECTORS */
4035 field_decl = grokfield (input_filename, lineno, field_decl,
4036 decl_specs, NULL_TREE);
4037 field_decl_chain = field_decl;
4039 decl_specs = tree_cons (NULL_TREE, ridpointers[(int) RID_CHAR], NULL_TREE);
4040 field_decl = build1 (INDIRECT_REF, NULL_TREE,
4041 get_identifier ("method_types"));
4042 field_decl = grokfield (input_filename, lineno, field_decl,
4043 decl_specs, NULL_TREE);
4044 chainon (field_decl_chain, field_decl);
4046 /* void *_imp; */
4048 decl_specs = tree_cons (NULL_TREE, ridpointers[(int) RID_VOID], NULL_TREE);
4049 field_decl = build1 (INDIRECT_REF, NULL_TREE, get_identifier ("_imp"));
4050 field_decl = grokfield (input_filename, lineno, field_decl,
4051 decl_specs, NULL_TREE);
4052 chainon (field_decl_chain, field_decl);
4054 finish_struct (_SLT_record, field_decl_chain, NULL_TREE);
4056 return _SLT_record;
4060 static tree
4061 generate_dispatch_table (type, name, size, list)
4062 tree type;
4063 const char *name;
4064 int size;
4065 tree list;
4067 tree sc_spec, decl_specs, decl, initlist;
4069 sc_spec = tree_cons (NULL_TREE, ridpointers[(int) RID_STATIC], NULL_TREE);
4070 decl_specs = tree_cons (NULL_TREE, type, sc_spec);
4072 decl = start_decl (synth_id_with_class_suffix (name, implementation_context),
4073 decl_specs, 1, NULL_TREE, NULL_TREE);
4075 initlist = build_tree_list (NULL_TREE, build_int_2 (0, 0));
4076 initlist = tree_cons (NULL_TREE, build_int_2 (size, 0), initlist);
4077 initlist = tree_cons (NULL_TREE, list, initlist);
4079 finish_decl (decl,
4080 build_constructor (TREE_TYPE (decl), nreverse (initlist)),
4081 NULL_TREE);
4083 return decl;
4086 static void
4087 generate_dispatch_tables ()
4089 tree initlist, chain, method_list_template;
4090 tree cast, variable_length_type;
4091 int size;
4093 if (!objc_method_template)
4094 objc_method_template = build_method_template ();
4096 cast
4097 = build_tree_list
4098 (build_tree_list (NULL_TREE,
4099 xref_tag (RECORD_TYPE,
4100 get_identifier (UTAG_METHOD_LIST))),
4101 NULL_TREE);
4103 variable_length_type = groktypename (cast);
4105 chain = CLASS_CLS_METHODS (implementation_context);
4106 if (chain)
4108 size = list_length (chain);
4110 method_list_template
4111 = build_method_list_template (objc_method_template, size);
4112 initlist
4113 = build_dispatch_table_initializer (objc_method_template, chain);
4115 UOBJC_CLASS_METHODS_decl
4116 = generate_dispatch_table (method_list_template,
4117 ((TREE_CODE (implementation_context)
4118 == CLASS_IMPLEMENTATION_TYPE)
4119 ? "_OBJC_CLASS_METHODS"
4120 : "_OBJC_CATEGORY_CLASS_METHODS"),
4121 size, initlist);
4122 TREE_TYPE (UOBJC_CLASS_METHODS_decl) = variable_length_type;
4124 else
4125 UOBJC_CLASS_METHODS_decl = 0;
4127 chain = CLASS_NST_METHODS (implementation_context);
4128 if (chain)
4130 size = list_length (chain);
4132 method_list_template
4133 = build_method_list_template (objc_method_template, size);
4134 initlist
4135 = build_dispatch_table_initializer (objc_method_template, chain);
4137 if (TREE_CODE (implementation_context) == CLASS_IMPLEMENTATION_TYPE)
4138 UOBJC_INSTANCE_METHODS_decl
4139 = generate_dispatch_table (method_list_template,
4140 "_OBJC_INSTANCE_METHODS",
4141 size, initlist);
4142 else
4143 /* We have a category. */
4144 UOBJC_INSTANCE_METHODS_decl
4145 = generate_dispatch_table (method_list_template,
4146 "_OBJC_CATEGORY_INSTANCE_METHODS",
4147 size, initlist);
4148 TREE_TYPE (UOBJC_INSTANCE_METHODS_decl) = variable_length_type;
4150 else
4151 UOBJC_INSTANCE_METHODS_decl = 0;
4154 static tree
4155 generate_protocol_list (i_or_p)
4156 tree i_or_p;
4158 tree initlist, decl_specs, sc_spec;
4159 tree refs_decl, expr_decl, lproto, e, plist;
4160 tree cast_type;
4161 int size = 0;
4163 if (TREE_CODE (i_or_p) == CLASS_INTERFACE_TYPE
4164 || TREE_CODE (i_or_p) == CATEGORY_INTERFACE_TYPE)
4165 plist = CLASS_PROTOCOL_LIST (i_or_p);
4166 else if (TREE_CODE (i_or_p) == PROTOCOL_INTERFACE_TYPE)
4167 plist = PROTOCOL_LIST (i_or_p);
4168 else
4169 abort ();
4171 cast_type = groktypename
4172 (build_tree_list
4173 (build_tree_list (NULL_TREE,
4174 xref_tag (RECORD_TYPE,
4175 get_identifier (UTAG_PROTOCOL))),
4176 build1 (INDIRECT_REF, NULL_TREE, NULL_TREE)));
4178 /* Compute size. */
4179 for (lproto = plist; lproto; lproto = TREE_CHAIN (lproto))
4180 if (TREE_CODE (TREE_VALUE (lproto)) == PROTOCOL_INTERFACE_TYPE
4181 && PROTOCOL_FORWARD_DECL (TREE_VALUE (lproto)))
4182 size++;
4184 /* Build initializer. */
4185 initlist = tree_cons (NULL_TREE, build_int_2 (0, 0), NULL_TREE);
4187 e = build_int_2 (size, 0);
4188 TREE_TYPE (e) = cast_type;
4189 initlist = tree_cons (NULL_TREE, e, initlist);
4191 for (lproto = plist; lproto; lproto = TREE_CHAIN (lproto))
4193 tree pval = TREE_VALUE (lproto);
4195 if (TREE_CODE (pval) == PROTOCOL_INTERFACE_TYPE
4196 && PROTOCOL_FORWARD_DECL (pval))
4198 e = build_unary_op (ADDR_EXPR, PROTOCOL_FORWARD_DECL (pval), 0);
4199 initlist = tree_cons (NULL_TREE, e, initlist);
4203 /* static struct objc_protocol *refs[n]; */
4205 sc_spec = tree_cons (NULL_TREE, ridpointers[(int) RID_STATIC], NULL_TREE);
4206 decl_specs = tree_cons (NULL_TREE, xref_tag (RECORD_TYPE,
4207 get_identifier (UTAG_PROTOCOL)),
4208 sc_spec);
4210 if (TREE_CODE (i_or_p) == PROTOCOL_INTERFACE_TYPE)
4211 expr_decl = build_nt (ARRAY_REF,
4212 synth_id_with_class_suffix ("_OBJC_PROTOCOL_REFS",
4213 i_or_p),
4214 build_int_2 (size + 2, 0));
4215 else if (TREE_CODE (i_or_p) == CLASS_INTERFACE_TYPE)
4216 expr_decl = build_nt (ARRAY_REF,
4217 synth_id_with_class_suffix ("_OBJC_CLASS_PROTOCOLS",
4218 i_or_p),
4219 build_int_2 (size + 2, 0));
4220 else if (TREE_CODE (i_or_p) == CATEGORY_INTERFACE_TYPE)
4221 expr_decl
4222 = build_nt (ARRAY_REF,
4223 synth_id_with_class_suffix ("_OBJC_CATEGORY_PROTOCOLS",
4224 i_or_p),
4225 build_int_2 (size + 2, 0));
4226 else
4227 abort ();
4229 expr_decl = build1 (INDIRECT_REF, NULL_TREE, expr_decl);
4231 refs_decl = start_decl (expr_decl, decl_specs, 1, NULL_TREE, NULL_TREE);
4233 finish_decl (refs_decl, build_constructor (TREE_TYPE (refs_decl),
4234 nreverse (initlist)),
4235 NULL_TREE);
4237 return refs_decl;
4240 static tree
4241 build_category_initializer (type, cat_name, class_name,
4242 instance_methods, class_methods, protocol_list)
4243 tree type;
4244 tree cat_name;
4245 tree class_name;
4246 tree instance_methods;
4247 tree class_methods;
4248 tree protocol_list;
4250 tree initlist = NULL_TREE, expr;
4252 initlist = tree_cons (NULL_TREE, cat_name, initlist);
4253 initlist = tree_cons (NULL_TREE, class_name, initlist);
4255 if (!instance_methods)
4256 initlist = tree_cons (NULL_TREE, build_int_2 (0, 0), initlist);
4257 else
4259 expr = build_unary_op (ADDR_EXPR, instance_methods, 0);
4260 initlist = tree_cons (NULL_TREE, expr, initlist);
4262 if (!class_methods)
4263 initlist = tree_cons (NULL_TREE, build_int_2 (0, 0), initlist);
4264 else
4266 expr = build_unary_op (ADDR_EXPR, class_methods, 0);
4267 initlist = tree_cons (NULL_TREE, expr, initlist);
4270 /* protocol_list = */
4271 if (!protocol_list)
4272 initlist = tree_cons (NULL_TREE, build_int_2 (0, 0), initlist);
4273 else
4275 tree cast_type2 = groktypename
4276 (build_tree_list
4277 (build_tree_list (NULL_TREE,
4278 xref_tag (RECORD_TYPE,
4279 get_identifier (UTAG_PROTOCOL))),
4280 build1 (INDIRECT_REF, NULL_TREE,
4281 build1 (INDIRECT_REF, NULL_TREE, NULL_TREE))));
4283 expr = build_unary_op (ADDR_EXPR, protocol_list, 0);
4284 TREE_TYPE (expr) = cast_type2;
4285 initlist = tree_cons (NULL_TREE, expr, initlist);
4288 return build_constructor (type, nreverse (initlist));
4291 /* struct objc_class {
4292 struct objc_class *isa;
4293 struct objc_class *super_class;
4294 char *name;
4295 long version;
4296 long info;
4297 long instance_size;
4298 struct objc_ivar_list *ivars;
4299 struct objc_method_list *methods;
4300 if (flag_next_runtime)
4301 struct objc_cache *cache;
4302 else {
4303 struct sarray *dtable;
4304 struct objc_class *subclass_list;
4305 struct objc_class *sibling_class;
4307 struct objc_protocol_list *protocols;
4308 void *gc_object_type;
4309 }; */
4311 static tree
4312 build_shared_structure_initializer (type, isa, super, name, size, status,
4313 dispatch_table, ivar_list, protocol_list)
4314 tree type;
4315 tree isa;
4316 tree super;
4317 tree name;
4318 tree size;
4319 int status;
4320 tree dispatch_table;
4321 tree ivar_list;
4322 tree protocol_list;
4324 tree initlist = NULL_TREE, expr;
4326 /* isa = */
4327 initlist = tree_cons (NULL_TREE, isa, initlist);
4329 /* super_class = */
4330 initlist = tree_cons (NULL_TREE, super, initlist);
4332 /* name = */
4333 initlist = tree_cons (NULL_TREE, default_conversion (name), initlist);
4335 /* version = */
4336 initlist = tree_cons (NULL_TREE, build_int_2 (0, 0), initlist);
4338 /* info = */
4339 initlist = tree_cons (NULL_TREE, build_int_2 (status, 0), initlist);
4341 /* instance_size = */
4342 initlist = tree_cons (NULL_TREE, size, initlist);
4344 /* objc_ivar_list = */
4345 if (!ivar_list)
4346 initlist = tree_cons (NULL_TREE, build_int_2 (0, 0), initlist);
4347 else
4349 expr = build_unary_op (ADDR_EXPR, ivar_list, 0);
4350 initlist = tree_cons (NULL_TREE, expr, initlist);
4353 /* objc_method_list = */
4354 if (!dispatch_table)
4355 initlist = tree_cons (NULL_TREE, build_int_2 (0, 0), initlist);
4356 else
4358 expr = build_unary_op (ADDR_EXPR, dispatch_table, 0);
4359 initlist = tree_cons (NULL_TREE, expr, initlist);
4362 if (flag_next_runtime)
4363 /* method_cache = */
4364 initlist = tree_cons (NULL_TREE, build_int_2 (0, 0), initlist);
4365 else
4367 /* dtable = */
4368 initlist = tree_cons (NULL_TREE, build_int_2 (0, 0), initlist);
4370 /* subclass_list = */
4371 initlist = tree_cons (NULL_TREE, build_int_2 (0, 0), initlist);
4373 /* sibling_class = */
4374 initlist = tree_cons (NULL_TREE, build_int_2 (0, 0), initlist);
4377 /* protocol_list = */
4378 if (! protocol_list)
4379 initlist = tree_cons (NULL_TREE, build_int_2 (0, 0), initlist);
4380 else
4382 tree cast_type2
4383 = groktypename
4384 (build_tree_list
4385 (build_tree_list (NULL_TREE,
4386 xref_tag (RECORD_TYPE,
4387 get_identifier (UTAG_PROTOCOL))),
4388 build1 (INDIRECT_REF, NULL_TREE,
4389 build1 (INDIRECT_REF, NULL_TREE, NULL_TREE))));
4391 expr = build_unary_op (ADDR_EXPR, protocol_list, 0);
4392 TREE_TYPE (expr) = cast_type2;
4393 initlist = tree_cons (NULL_TREE, expr, initlist);
4396 /* gc_object_type = NULL */
4397 initlist = tree_cons (NULL_TREE, build_int_2 (0, 0), initlist);
4399 return build_constructor (type, nreverse (initlist));
4402 /* static struct objc_category _OBJC_CATEGORY_<name> = { ... }; */
4404 static void
4405 generate_category (cat)
4406 tree cat;
4408 tree sc_spec, decl_specs, decl;
4409 tree initlist, cat_name_expr, class_name_expr;
4410 tree protocol_decl, category;
4412 add_class_reference (CLASS_NAME (cat));
4413 cat_name_expr = add_objc_string (CLASS_SUPER_NAME (cat), class_names);
4415 class_name_expr = add_objc_string (CLASS_NAME (cat), class_names);
4417 category = CLASS_CATEGORY_LIST (implementation_template);
4419 /* find the category interface from the class it is associated with */
4420 while (category)
4422 if (CLASS_SUPER_NAME (cat) == CLASS_SUPER_NAME (category))
4423 break;
4424 category = CLASS_CATEGORY_LIST (category);
4427 if (category && CLASS_PROTOCOL_LIST (category))
4429 generate_protocol_references (CLASS_PROTOCOL_LIST (category));
4430 protocol_decl = generate_protocol_list (category);
4432 else
4433 protocol_decl = 0;
4435 sc_spec = tree_cons (NULL_TREE, ridpointers[(int) RID_STATIC], NULL_TREE);
4436 decl_specs = tree_cons (NULL_TREE, objc_category_template, sc_spec);
4438 decl = start_decl (synth_id_with_class_suffix ("_OBJC_CATEGORY",
4439 implementation_context),
4440 decl_specs, 1, NULL_TREE, NULL_TREE);
4442 initlist = build_category_initializer (TREE_TYPE (decl),
4443 cat_name_expr, class_name_expr,
4444 UOBJC_INSTANCE_METHODS_decl,
4445 UOBJC_CLASS_METHODS_decl,
4446 protocol_decl);
4448 TREE_USED (decl) = 1;
4449 finish_decl (decl, initlist, NULL_TREE);
4452 /* static struct objc_class _OBJC_METACLASS_Foo={ ... };
4453 static struct objc_class _OBJC_CLASS_Foo={ ... }; */
4455 static void
4456 generate_shared_structures ()
4458 tree sc_spec, decl_specs, decl;
4459 tree name_expr, super_expr, root_expr;
4460 tree my_root_id = NULL_TREE, my_super_id = NULL_TREE;
4461 tree cast_type, initlist, protocol_decl;
4463 my_super_id = CLASS_SUPER_NAME (implementation_template);
4464 if (my_super_id)
4466 add_class_reference (my_super_id);
4468 /* Compute "my_root_id" - this is required for code generation.
4469 the "isa" for all meta class structures points to the root of
4470 the inheritance hierarchy (e.g. "__Object")... */
4471 my_root_id = my_super_id;
4474 tree my_root_int = lookup_interface (my_root_id);
4476 if (my_root_int && CLASS_SUPER_NAME (my_root_int))
4477 my_root_id = CLASS_SUPER_NAME (my_root_int);
4478 else
4479 break;
4481 while (1);
4483 else
4484 /* No super class. */
4485 my_root_id = CLASS_NAME (implementation_template);
4487 cast_type
4488 = groktypename (build_tree_list (build_tree_list (NULL_TREE,
4489 objc_class_template),
4490 build1 (INDIRECT_REF,
4491 NULL_TREE, NULL_TREE)));
4493 name_expr = add_objc_string (CLASS_NAME (implementation_template),
4494 class_names);
4496 /* Install class `isa' and `super' pointers at runtime. */
4497 if (my_super_id)
4499 super_expr = add_objc_string (my_super_id, class_names);
4500 super_expr = build_c_cast (cast_type, super_expr); /* cast! */
4502 else
4503 super_expr = build_int_2 (0, 0);
4505 root_expr = add_objc_string (my_root_id, class_names);
4506 root_expr = build_c_cast (cast_type, root_expr); /* cast! */
4508 if (CLASS_PROTOCOL_LIST (implementation_template))
4510 generate_protocol_references
4511 (CLASS_PROTOCOL_LIST (implementation_template));
4512 protocol_decl = generate_protocol_list (implementation_template);
4514 else
4515 protocol_decl = 0;
4517 /* static struct objc_class _OBJC_METACLASS_Foo = { ... }; */
4519 sc_spec = build_tree_list (NULL_TREE, ridpointers[(int) RID_STATIC]);
4520 decl_specs = tree_cons (NULL_TREE, objc_class_template, sc_spec);
4522 decl = start_decl (DECL_NAME (UOBJC_METACLASS_decl), decl_specs, 1,
4523 NULL_TREE, NULL_TREE);
4525 initlist
4526 = build_shared_structure_initializer
4527 (TREE_TYPE (decl),
4528 root_expr, super_expr, name_expr,
4529 convert (integer_type_node, TYPE_SIZE_UNIT (objc_class_template)),
4530 2 /*CLS_META*/,
4531 UOBJC_CLASS_METHODS_decl,
4532 UOBJC_CLASS_VARIABLES_decl,
4533 protocol_decl);
4535 finish_decl (decl, initlist, NULL_TREE);
4537 /* static struct objc_class _OBJC_CLASS_Foo={ ... }; */
4539 decl = start_decl (DECL_NAME (UOBJC_CLASS_decl), decl_specs, 1,
4540 NULL_TREE, NULL_TREE);
4542 initlist
4543 = build_shared_structure_initializer
4544 (TREE_TYPE (decl),
4545 build_unary_op (ADDR_EXPR, UOBJC_METACLASS_decl, 0),
4546 super_expr, name_expr,
4547 convert (integer_type_node,
4548 TYPE_SIZE_UNIT (CLASS_STATIC_TEMPLATE
4549 (implementation_template))),
4550 1 /*CLS_FACTORY*/,
4551 UOBJC_INSTANCE_METHODS_decl,
4552 UOBJC_INSTANCE_VARIABLES_decl,
4553 protocol_decl);
4555 finish_decl (decl, initlist, NULL_TREE);
4558 static tree
4559 synth_id_with_class_suffix (preamble, ctxt)
4560 const char *preamble;
4561 tree ctxt;
4563 char *string;
4564 if (TREE_CODE (ctxt) == CLASS_IMPLEMENTATION_TYPE
4565 || TREE_CODE (ctxt) == CLASS_INTERFACE_TYPE)
4567 const char *class_name
4568 = IDENTIFIER_POINTER (CLASS_NAME (implementation_context));
4569 string = (char *) alloca (strlen (preamble) + strlen (class_name) + 3);
4570 sprintf (string, "%s_%s", preamble,
4571 IDENTIFIER_POINTER (CLASS_NAME (ctxt)));
4573 else if (TREE_CODE (ctxt) == CATEGORY_IMPLEMENTATION_TYPE
4574 || TREE_CODE (ctxt) == CATEGORY_INTERFACE_TYPE)
4576 /* We have a category. */
4577 const char *class_name
4578 = IDENTIFIER_POINTER (CLASS_NAME (implementation_context));
4579 const char *class_super_name
4580 = IDENTIFIER_POINTER (CLASS_SUPER_NAME (implementation_context));
4581 string = (char *) alloca (strlen (preamble)
4582 + strlen (class_name)
4583 + strlen (class_super_name)
4584 + 3);
4585 sprintf (string, "%s_%s_%s", preamble, class_name, class_super_name);
4587 else if (TREE_CODE (ctxt) == PROTOCOL_INTERFACE_TYPE)
4589 const char *protocol_name = IDENTIFIER_POINTER (PROTOCOL_NAME (ctxt));
4590 string
4591 = (char *) alloca (strlen (preamble) + strlen (protocol_name) + 3);
4592 sprintf (string, "%s_%s", preamble, protocol_name);
4594 else
4595 abort ();
4597 return get_identifier (string);
4600 static int
4601 is_objc_type_qualifier (node)
4602 tree node;
4604 return (TREE_CODE (node) == IDENTIFIER_NODE
4605 && (node == ridpointers [(int) RID_CONST]
4606 || node == ridpointers [(int) RID_VOLATILE]
4607 || node == ridpointers [(int) RID_IN]
4608 || node == ridpointers [(int) RID_OUT]
4609 || node == ridpointers [(int) RID_INOUT]
4610 || node == ridpointers [(int) RID_BYCOPY]
4611 || node == ridpointers [(int) RID_BYREF]
4612 || node == ridpointers [(int) RID_ONEWAY]));
4615 /* If type is empty or only type qualifiers are present, add default
4616 type of id (otherwise grokdeclarator will default to int). */
4618 static tree
4619 adjust_type_for_id_default (type)
4620 tree type;
4622 tree declspecs, chain;
4624 if (!type)
4625 return build_tree_list (build_tree_list (NULL_TREE, objc_object_reference),
4626 build1 (INDIRECT_REF, NULL_TREE, NULL_TREE));
4628 declspecs = TREE_PURPOSE (type);
4630 /* Determine if a typespec is present. */
4631 for (chain = declspecs;
4632 chain;
4633 chain = TREE_CHAIN (chain))
4635 if (!is_objc_type_qualifier (TREE_VALUE (chain)))
4636 return type;
4639 return build_tree_list (tree_cons (NULL_TREE, objc_object_reference,
4640 declspecs),
4641 build1 (INDIRECT_REF, NULL_TREE, NULL_TREE));
4644 /* Usage:
4645 keyworddecl:
4646 selector ':' '(' typename ')' identifier
4648 Purpose:
4649 Transform an Objective-C keyword argument into
4650 the C equivalent parameter declarator.
4652 In: key_name, an "identifier_node" (optional).
4653 arg_type, a "tree_list" (optional).
4654 arg_name, an "identifier_node".
4656 Note: It would be really nice to strongly type the preceding
4657 arguments in the function prototype; however, then I
4658 could not use the "accessor" macros defined in "tree.h".
4660 Out: an instance of "keyword_decl". */
4662 tree
4663 build_keyword_decl (key_name, arg_type, arg_name)
4664 tree key_name;
4665 tree arg_type;
4666 tree arg_name;
4668 tree keyword_decl;
4670 /* If no type is specified, default to "id". */
4671 arg_type = adjust_type_for_id_default (arg_type);
4673 keyword_decl = make_node (KEYWORD_DECL);
4675 TREE_TYPE (keyword_decl) = arg_type;
4676 KEYWORD_ARG_NAME (keyword_decl) = arg_name;
4677 KEYWORD_KEY_NAME (keyword_decl) = key_name;
4679 return keyword_decl;
4682 /* Given a chain of keyword_decl's, synthesize the full keyword selector. */
4684 static tree
4685 build_keyword_selector (selector)
4686 tree selector;
4688 int len = 0;
4689 tree key_chain, key_name;
4690 char *buf;
4692 for (key_chain = selector; key_chain; key_chain = TREE_CHAIN (key_chain))
4694 if (TREE_CODE (selector) == KEYWORD_DECL)
4695 key_name = KEYWORD_KEY_NAME (key_chain);
4696 else if (TREE_CODE (selector) == TREE_LIST)
4697 key_name = TREE_PURPOSE (key_chain);
4698 else
4699 abort ();
4701 if (key_name)
4702 len += IDENTIFIER_LENGTH (key_name) + 1;
4703 else
4704 /* Just a ':' arg. */
4705 len++;
4708 buf = (char *)alloca (len + 1);
4709 memset (buf, 0, len + 1);
4711 for (key_chain = selector; key_chain; key_chain = TREE_CHAIN (key_chain))
4713 if (TREE_CODE (selector) == KEYWORD_DECL)
4714 key_name = KEYWORD_KEY_NAME (key_chain);
4715 else if (TREE_CODE (selector) == TREE_LIST)
4716 key_name = TREE_PURPOSE (key_chain);
4717 else
4718 abort ();
4720 if (key_name)
4721 strcat (buf, IDENTIFIER_POINTER (key_name));
4722 strcat (buf, ":");
4725 return get_identifier (buf);
4728 /* Used for declarations and definitions. */
4730 tree
4731 build_method_decl (code, ret_type, selector, add_args)
4732 enum tree_code code;
4733 tree ret_type;
4734 tree selector;
4735 tree add_args;
4737 tree method_decl;
4739 /* If no type is specified, default to "id". */
4740 ret_type = adjust_type_for_id_default (ret_type);
4742 method_decl = make_node (code);
4743 TREE_TYPE (method_decl) = ret_type;
4745 /* If we have a keyword selector, create an identifier_node that
4746 represents the full selector name (`:' included)... */
4747 if (TREE_CODE (selector) == KEYWORD_DECL)
4749 METHOD_SEL_NAME (method_decl) = build_keyword_selector (selector);
4750 METHOD_SEL_ARGS (method_decl) = selector;
4751 METHOD_ADD_ARGS (method_decl) = add_args;
4753 else
4755 METHOD_SEL_NAME (method_decl) = selector;
4756 METHOD_SEL_ARGS (method_decl) = NULL_TREE;
4757 METHOD_ADD_ARGS (method_decl) = NULL_TREE;
4760 return method_decl;
4763 #define METHOD_DEF 0
4764 #define METHOD_REF 1
4766 /* Used by `build_message_expr' and `comp_method_types'. Return an
4767 argument list for method METH. CONTEXT is either METHOD_DEF or
4768 METHOD_REF, saying whether we are trying to define a method or call
4769 one. SUPERFLAG says this is for a send to super; this makes a
4770 difference for the NeXT calling sequence in which the lookup and
4771 the method call are done together. */
4773 static tree
4774 get_arg_type_list (meth, context, superflag)
4775 tree meth;
4776 int context;
4777 int superflag;
4779 tree arglist, akey;
4781 /* Receiver type. */
4782 if (flag_next_runtime && superflag)
4783 arglist = build_tree_list (NULL_TREE, super_type);
4784 else if (context == METHOD_DEF)
4785 arglist = build_tree_list (NULL_TREE, TREE_TYPE (self_decl));
4786 else
4787 arglist = build_tree_list (NULL_TREE, id_type);
4789 /* Selector type - will eventually change to `int'. */
4790 chainon (arglist, build_tree_list (NULL_TREE, selector_type));
4792 /* Build a list of argument types. */
4793 for (akey = METHOD_SEL_ARGS (meth); akey; akey = TREE_CHAIN (akey))
4795 tree arg_decl = groktypename_in_parm_context (TREE_TYPE (akey));
4796 chainon (arglist, build_tree_list (NULL_TREE, TREE_TYPE (arg_decl)));
4799 if (METHOD_ADD_ARGS (meth) == objc_ellipsis_node)
4800 /* We have a `, ...' immediately following the selector,
4801 finalize the arglist...simulate get_parm_info (0). */
4803 else if (METHOD_ADD_ARGS (meth))
4805 /* we have a variable length selector */
4806 tree add_arg_list = TREE_CHAIN (METHOD_ADD_ARGS (meth));
4807 chainon (arglist, add_arg_list);
4809 else
4810 /* finalize the arglist...simulate get_parm_info (1) */
4811 chainon (arglist, build_tree_list (NULL_TREE, void_type_node));
4813 return arglist;
4816 static tree
4817 check_duplicates (hsh)
4818 hash hsh;
4820 tree meth = NULL_TREE;
4822 if (hsh)
4824 meth = hsh->key;
4826 if (hsh->list)
4828 /* We have two methods with the same name and different types. */
4829 attr loop;
4830 char type = (TREE_CODE (meth) == INSTANCE_METHOD_DECL) ? '-' : '+';
4832 warning ("multiple declarations for method `%s'",
4833 IDENTIFIER_POINTER (METHOD_SEL_NAME (meth)));
4835 warn_with_method ("using", type, meth);
4836 for (loop = hsh->list; loop; loop = loop->next)
4837 warn_with_method ("also found", type, loop->value);
4840 return meth;
4843 /* If RECEIVER is a class reference, return the identifier node for the
4844 referenced class. RECEIVER is created by get_class_reference, so we
4845 check the exact form created depending on which runtimes are used. */
4847 static tree
4848 receiver_is_class_object (receiver)
4849 tree receiver;
4851 tree chain, exp, arg;
4852 if (flag_next_runtime)
4854 /* The receiver is a variable created by build_class_reference_decl. */
4855 if (TREE_CODE (receiver) == VAR_DECL
4856 && TREE_TYPE (receiver) == objc_class_type)
4857 /* Look up the identifier. */
4858 for (chain = cls_ref_chain; chain; chain = TREE_CHAIN (chain))
4859 if (TREE_PURPOSE (chain) == receiver)
4860 return TREE_VALUE (chain);
4862 else
4864 /* The receiver is a function call that returns an id. Check if
4865 it is a call to objc_getClass, if so, pick up the class name. */
4866 if ((exp = TREE_OPERAND (receiver, 0))
4867 && TREE_CODE (exp) == ADDR_EXPR
4868 && (exp = TREE_OPERAND (exp, 0))
4869 && TREE_CODE (exp) == FUNCTION_DECL
4870 && exp == objc_get_class_decl
4871 /* we have a call to objc_getClass! */
4872 && (arg = TREE_OPERAND (receiver, 1))
4873 && TREE_CODE (arg) == TREE_LIST
4874 && (arg = TREE_VALUE (arg)))
4876 STRIP_NOPS (arg);
4877 if (TREE_CODE (arg) == ADDR_EXPR
4878 && (arg = TREE_OPERAND (arg, 0))
4879 && TREE_CODE (arg) == STRING_CST)
4880 /* Finally, we have the class name. */
4881 return get_identifier (TREE_STRING_POINTER (arg));
4884 return 0;
4887 /* If we are currently building a message expr, this holds
4888 the identifier of the selector of the message. This is
4889 used when printing warnings about argument mismatches. */
4891 static tree building_objc_message_expr = 0;
4893 tree
4894 maybe_building_objc_message_expr ()
4896 return building_objc_message_expr;
4899 /* Construct an expression for sending a message.
4900 MESS has the object to send to in TREE_PURPOSE
4901 and the argument list (including selector) in TREE_VALUE.
4903 (*(<abstract_decl>(*)())_msg)(receiver, selTransTbl[n], ...);
4904 (*(<abstract_decl>(*)())_msgSuper)(receiver, selTransTbl[n], ...); */
4906 tree
4907 build_message_expr (mess)
4908 tree mess;
4910 tree receiver = TREE_PURPOSE (mess);
4911 tree selector, self_object;
4912 tree rtype, sel_name;
4913 tree args = TREE_VALUE (mess);
4914 tree method_params = NULL_TREE;
4915 tree method_prototype = NULL_TREE;
4916 tree retval;
4917 int statically_typed = 0, statically_allocated = 0;
4918 tree class_ident = 0;
4920 /* 1 if this is sending to the superclass. */
4921 int super;
4923 if (TREE_CODE (receiver) == ERROR_MARK)
4924 return error_mark_node;
4926 /* Determine receiver type. */
4927 rtype = TREE_TYPE (receiver);
4928 super = IS_SUPER (rtype);
4930 if (! super)
4932 if (TREE_STATIC_TEMPLATE (rtype))
4933 statically_allocated = 1;
4934 else if (TREE_CODE (rtype) == POINTER_TYPE
4935 && TREE_STATIC_TEMPLATE (TREE_TYPE (rtype)))
4936 statically_typed = 1;
4937 else if ((flag_next_runtime
4938 || (TREE_CODE (receiver) == CALL_EXPR && IS_ID (rtype)))
4939 && (class_ident = receiver_is_class_object (receiver)))
4941 else if (! IS_ID (rtype)
4942 /* Allow any type that matches objc_class_type. */
4943 && ! comptypes (rtype, objc_class_type))
4945 memset (errbuf, 0, BUFSIZE);
4946 warning ("invalid receiver type `%s'",
4947 gen_declaration (rtype, errbuf));
4950 if (statically_allocated)
4951 receiver = build_unary_op (ADDR_EXPR, receiver, 0);
4953 /* Don't evaluate the receiver twice. */
4954 receiver = save_expr (receiver);
4955 self_object = receiver;
4957 else
4958 /* If sending to `super', use current self as the object. */
4959 self_object = self_decl;
4961 /* Obtain the full selector name. */
4963 if (TREE_CODE (args) == IDENTIFIER_NODE)
4964 /* A unary selector. */
4965 sel_name = args;
4966 else if (TREE_CODE (args) == TREE_LIST)
4967 sel_name = build_keyword_selector (args);
4968 else
4969 abort ();
4971 /* Build the parameter list to give to the method. */
4973 method_params = NULL_TREE;
4974 if (TREE_CODE (args) == TREE_LIST)
4976 tree chain = args, prev = NULL_TREE;
4978 /* We have a keyword selector--check for comma expressions. */
4979 while (chain)
4981 tree element = TREE_VALUE (chain);
4983 /* We have a comma expression, must collapse... */
4984 if (TREE_CODE (element) == TREE_LIST)
4986 if (prev)
4987 TREE_CHAIN (prev) = element;
4988 else
4989 args = element;
4991 prev = chain;
4992 chain = TREE_CHAIN (chain);
4994 method_params = args;
4997 /* Determine operation return type. */
4999 if (IS_SUPER (rtype))
5001 tree iface;
5003 if (CLASS_SUPER_NAME (implementation_template))
5005 iface
5006 = lookup_interface (CLASS_SUPER_NAME (implementation_template));
5008 if (TREE_CODE (method_context) == INSTANCE_METHOD_DECL)
5009 method_prototype = lookup_instance_method_static (iface, sel_name);
5010 else
5011 method_prototype = lookup_class_method_static (iface, sel_name);
5013 if (iface && !method_prototype)
5014 warning ("`%s' does not respond to `%s'",
5015 IDENTIFIER_POINTER (CLASS_SUPER_NAME (implementation_template)),
5016 IDENTIFIER_POINTER (sel_name));
5018 else
5020 error ("no super class declared in interface for `%s'",
5021 IDENTIFIER_POINTER (CLASS_NAME (implementation_template)));
5022 return error_mark_node;
5026 else if (statically_allocated)
5028 tree ctype = TREE_TYPE (rtype);
5029 tree iface = lookup_interface (TYPE_NAME (rtype));
5031 if (iface)
5032 method_prototype = lookup_instance_method_static (iface, sel_name);
5034 if (! method_prototype && TYPE_PROTOCOL_LIST (ctype))
5035 method_prototype
5036 = lookup_method_in_protocol_list (TYPE_PROTOCOL_LIST (ctype),
5037 sel_name, 0);
5039 if (!method_prototype)
5040 warning ("`%s' does not respond to `%s'",
5041 IDENTIFIER_POINTER (TYPE_NAME (rtype)),
5042 IDENTIFIER_POINTER (sel_name));
5044 else if (statically_typed)
5046 tree ctype = TREE_TYPE (rtype);
5048 /* `self' is now statically_typed. All methods should be visible
5049 within the context of the implementation. */
5050 if (implementation_context
5051 && CLASS_NAME (implementation_context) == TYPE_NAME (ctype))
5053 method_prototype
5054 = lookup_instance_method_static (implementation_template,
5055 sel_name);
5057 if (! method_prototype && TYPE_PROTOCOL_LIST (ctype))
5058 method_prototype
5059 = lookup_method_in_protocol_list (TYPE_PROTOCOL_LIST (ctype),
5060 sel_name, 0);
5062 if (! method_prototype
5063 && implementation_template != implementation_context)
5064 /* The method is not published in the interface. Check
5065 locally. */
5066 method_prototype
5067 = lookup_method (CLASS_NST_METHODS (implementation_context),
5068 sel_name);
5070 else
5072 tree iface;
5074 if ((iface = lookup_interface (TYPE_NAME (ctype))))
5075 method_prototype = lookup_instance_method_static (iface, sel_name);
5077 if (! method_prototype)
5079 tree protocol_list = TYPE_PROTOCOL_LIST (ctype);
5080 if (protocol_list)
5081 method_prototype
5082 = lookup_method_in_protocol_list (protocol_list,
5083 sel_name, 0);
5087 if (!method_prototype)
5088 warning ("`%s' does not respond to `%s'",
5089 IDENTIFIER_POINTER (TYPE_NAME (ctype)),
5090 IDENTIFIER_POINTER (sel_name));
5092 else if (class_ident)
5094 if (implementation_context
5095 && CLASS_NAME (implementation_context) == class_ident)
5097 method_prototype
5098 = lookup_class_method_static (implementation_template, sel_name);
5100 if (!method_prototype
5101 && implementation_template != implementation_context)
5102 /* The method is not published in the interface. Check
5103 locally. */
5104 method_prototype
5105 = lookup_method (CLASS_CLS_METHODS (implementation_context),
5106 sel_name);
5108 else
5110 tree iface;
5112 if ((iface = lookup_interface (class_ident)))
5113 method_prototype = lookup_class_method_static (iface, sel_name);
5116 if (!method_prototype)
5118 warning ("cannot find class (factory) method.");
5119 warning ("return type for `%s' defaults to id",
5120 IDENTIFIER_POINTER (sel_name));
5123 else if (IS_PROTOCOL_QUALIFIED_ID (rtype))
5125 /* An anonymous object that has been qualified with a protocol. */
5127 tree protocol_list = TYPE_PROTOCOL_LIST (rtype);
5129 method_prototype = lookup_method_in_protocol_list (protocol_list,
5130 sel_name, 0);
5132 if (!method_prototype)
5134 hash hsh;
5136 warning ("method `%s' not implemented by protocol.",
5137 IDENTIFIER_POINTER (sel_name));
5139 /* Try and find the method signature in the global pools. */
5141 if (!(hsh = hash_lookup (nst_method_hash_list, sel_name)))
5142 hsh = hash_lookup (cls_method_hash_list, sel_name);
5144 if (!(method_prototype = check_duplicates (hsh)))
5145 warning ("return type defaults to id");
5148 else
5150 hash hsh;
5152 /* We think we have an instance...loophole: extern id Object; */
5153 hsh = hash_lookup (nst_method_hash_list, sel_name);
5154 if (!hsh)
5155 /* For various loopholes, like sending messages to self in a
5156 factory context. */
5157 hsh = hash_lookup (cls_method_hash_list, sel_name);
5159 method_prototype = check_duplicates (hsh);
5160 if (!method_prototype)
5162 warning ("cannot find method.");
5163 warning ("return type for `%s' defaults to id",
5164 IDENTIFIER_POINTER (sel_name));
5168 /* Save the selector name for printing error messages. */
5169 building_objc_message_expr = sel_name;
5171 /* Build the parameters list for looking up the method.
5172 These are the object itself and the selector. */
5174 if (flag_typed_selectors)
5175 selector = build_typed_selector_reference (sel_name, method_prototype);
5176 else
5177 selector = build_selector_reference (sel_name);
5179 retval = build_objc_method_call (super, method_prototype,
5180 receiver, self_object,
5181 selector, method_params);
5183 building_objc_message_expr = 0;
5185 return retval;
5188 /* Build a tree expression to send OBJECT the operation SELECTOR,
5189 looking up the method on object LOOKUP_OBJECT (often same as OBJECT),
5190 assuming the method has prototype METHOD_PROTOTYPE.
5191 (That is an INSTANCE_METHOD_DECL or CLASS_METHOD_DECL.)
5192 Use METHOD_PARAMS as list of args to pass to the method.
5193 If SUPER_FLAG is nonzero, we look up the superclass's method. */
5195 static tree
5196 build_objc_method_call (super_flag, method_prototype, lookup_object, object,
5197 selector, method_params)
5198 int super_flag;
5199 tree method_prototype, lookup_object, object, selector, method_params;
5201 tree sender = (super_flag ? umsg_super_decl : umsg_decl);
5202 tree rcv_p = (super_flag
5203 ? build_pointer_type (xref_tag (RECORD_TYPE,
5204 get_identifier (TAG_SUPER)))
5205 : id_type);
5207 if (flag_next_runtime)
5209 if (! method_prototype)
5211 method_params = tree_cons (NULL_TREE, lookup_object,
5212 tree_cons (NULL_TREE, selector,
5213 method_params));
5214 assemble_external (sender);
5215 return build_function_call (sender, method_params);
5217 else
5219 /* This is a real kludge, but it is used only for the Next.
5220 Clobber the data type of SENDER temporarily to accept
5221 all the arguments for this operation, and to return
5222 whatever this operation returns. */
5223 tree arglist = NULL_TREE;
5224 tree retval;
5226 /* Save the proper contents of SENDER's data type. */
5227 tree savarg = TYPE_ARG_TYPES (TREE_TYPE (sender));
5228 tree savret = TREE_TYPE (TREE_TYPE (sender));
5230 /* Install this method's argument types. */
5231 arglist = get_arg_type_list (method_prototype, METHOD_REF,
5232 super_flag);
5233 TYPE_ARG_TYPES (TREE_TYPE (sender)) = arglist;
5235 /* Install this method's return type. */
5236 TREE_TYPE (TREE_TYPE (sender))
5237 = groktypename (TREE_TYPE (method_prototype));
5239 /* Call SENDER with all the parameters. This will do type
5240 checking using the arg types for this method. */
5241 method_params = tree_cons (NULL_TREE, lookup_object,
5242 tree_cons (NULL_TREE, selector,
5243 method_params));
5244 assemble_external (sender);
5245 retval = build_function_call (sender, method_params);
5247 /* Restore SENDER's return/argument types. */
5248 TYPE_ARG_TYPES (TREE_TYPE (sender)) = savarg;
5249 TREE_TYPE (TREE_TYPE (sender)) = savret;
5250 return retval;
5253 else
5255 /* This is the portable way.
5256 First call the lookup function to get a pointer to the method,
5257 then cast the pointer, then call it with the method arguments. */
5258 tree method;
5260 /* Avoid trouble since we may evaluate each of these twice. */
5261 object = save_expr (object);
5262 selector = save_expr (selector);
5264 lookup_object = build_c_cast (rcv_p, lookup_object);
5266 assemble_external (sender);
5267 method
5268 = build_function_call (sender,
5269 tree_cons (NULL_TREE, lookup_object,
5270 tree_cons (NULL_TREE, selector,
5271 NULL_TREE)));
5273 /* If we have a method prototype, construct the data type this
5274 method needs, and cast what we got from SENDER into a pointer
5275 to that type. */
5276 if (method_prototype)
5278 tree arglist = get_arg_type_list (method_prototype, METHOD_REF,
5279 super_flag);
5280 tree valtype = groktypename (TREE_TYPE (method_prototype));
5281 tree fake_function_type = build_function_type (valtype, arglist);
5282 TREE_TYPE (method) = build_pointer_type (fake_function_type);
5284 else
5285 TREE_TYPE (method)
5286 = build_pointer_type (build_function_type (ptr_type_node, NULL_TREE));
5288 /* Pass the object to the method. */
5289 assemble_external (method);
5290 return build_function_call (method,
5291 tree_cons (NULL_TREE, object,
5292 tree_cons (NULL_TREE, selector,
5293 method_params)));
5297 static void
5298 build_protocol_reference (p)
5299 tree p;
5301 tree decl, ident, ptype;
5303 /* extern struct objc_protocol _OBJC_PROTOCOL_<mumble>; */
5305 ident = synth_id_with_class_suffix ("_OBJC_PROTOCOL", p);
5306 ptype
5307 = groktypename (build_tree_list (build_tree_list (NULL_TREE,
5308 objc_protocol_template),
5309 NULL_TREE));
5311 if (IDENTIFIER_GLOBAL_VALUE (ident))
5312 decl = IDENTIFIER_GLOBAL_VALUE (ident); /* Set by pushdecl. */
5313 else
5315 decl = build_decl (VAR_DECL, ident, ptype);
5316 DECL_EXTERNAL (decl) = 1;
5317 TREE_PUBLIC (decl) = 1;
5318 TREE_USED (decl) = 1;
5319 DECL_ARTIFICIAL (decl) = 1;
5321 make_decl_rtl (decl, 0, 1);
5322 pushdecl_top_level (decl);
5325 PROTOCOL_FORWARD_DECL (p) = decl;
5328 tree
5329 build_protocol_expr (protoname)
5330 tree protoname;
5332 tree expr;
5333 tree p = lookup_protocol (protoname);
5335 if (!p)
5337 error ("Cannot find protocol declaration for `%s'",
5338 IDENTIFIER_POINTER (protoname));
5339 return error_mark_node;
5342 if (!PROTOCOL_FORWARD_DECL (p))
5343 build_protocol_reference (p);
5345 expr = build_unary_op (ADDR_EXPR, PROTOCOL_FORWARD_DECL (p), 0);
5347 TREE_TYPE (expr) = protocol_type;
5349 return expr;
5352 tree
5353 build_selector_expr (selnamelist)
5354 tree selnamelist;
5356 tree selname;
5358 /* Obtain the full selector name. */
5359 if (TREE_CODE (selnamelist) == IDENTIFIER_NODE)
5360 /* A unary selector. */
5361 selname = selnamelist;
5362 else if (TREE_CODE (selnamelist) == TREE_LIST)
5363 selname = build_keyword_selector (selnamelist);
5364 else
5365 abort ();
5367 if (flag_typed_selectors)
5368 return build_typed_selector_reference (selname, 0);
5369 else
5370 return build_selector_reference (selname);
5373 tree
5374 build_encode_expr (type)
5375 tree type;
5377 tree result;
5378 const char *string;
5380 encode_type (type, obstack_object_size (&util_obstack),
5381 OBJC_ENCODE_INLINE_DEFS);
5382 obstack_1grow (&util_obstack, 0); /* null terminate string */
5383 string = obstack_finish (&util_obstack);
5385 /* Synthesize a string that represents the encoded struct/union. */
5386 result = my_build_string (strlen (string) + 1, string);
5387 obstack_free (&util_obstack, util_firstobj);
5388 return result;
5391 tree
5392 build_ivar_reference (id)
5393 tree id;
5395 if (TREE_CODE (method_context) == CLASS_METHOD_DECL)
5397 /* Historically, a class method that produced objects (factory
5398 method) would assign `self' to the instance that it
5399 allocated. This would effectively turn the class method into
5400 an instance method. Following this assignment, the instance
5401 variables could be accessed. That practice, while safe,
5402 violates the simple rule that a class method should not refer
5403 to an instance variable. It's better to catch the cases
5404 where this is done unknowingly than to support the above
5405 paradigm. */
5406 warning ("instance variable `%s' accessed in class method",
5407 IDENTIFIER_POINTER (id));
5408 TREE_TYPE (self_decl) = instance_type; /* cast */
5411 return build_component_ref (build_indirect_ref (self_decl, "->"), id);
5414 #define HASH_ALLOC_LIST_SIZE 170
5415 #define ATTR_ALLOC_LIST_SIZE 170
5416 #define SIZEHASHTABLE 257
5418 /* make positive */
5419 #define HASHFUNCTION(key) ((HOST_WIDE_INT) key & 0x7fffffff)
5421 static void
5422 hash_init ()
5424 nst_method_hash_list = (hash *)xmalloc (SIZEHASHTABLE * sizeof (hash));
5425 cls_method_hash_list = (hash *)xmalloc (SIZEHASHTABLE * sizeof (hash));
5427 if (!nst_method_hash_list || !cls_method_hash_list)
5428 perror ("unable to allocate space in objc-tree.c");
5429 else
5431 int i;
5433 for (i = 0; i < SIZEHASHTABLE; i++)
5435 nst_method_hash_list[i] = 0;
5436 cls_method_hash_list[i] = 0;
5441 static void
5442 hash_enter (hashlist, method)
5443 hash *hashlist;
5444 tree method;
5446 static hash hash_alloc_list = 0;
5447 static int hash_alloc_index = 0;
5448 hash obj;
5449 int slot = HASHFUNCTION (METHOD_SEL_NAME (method)) % SIZEHASHTABLE;
5451 if (! hash_alloc_list || hash_alloc_index >= HASH_ALLOC_LIST_SIZE)
5453 hash_alloc_index = 0;
5454 hash_alloc_list = (hash) xmalloc (sizeof (struct hashed_entry)
5455 * HASH_ALLOC_LIST_SIZE);
5456 if (! hash_alloc_list)
5457 perror ("unable to allocate in objc-tree.c");
5459 obj = &hash_alloc_list[hash_alloc_index++];
5460 obj->list = 0;
5461 obj->next = hashlist[slot];
5462 obj->key = method;
5464 hashlist[slot] = obj; /* append to front */
5467 static hash
5468 hash_lookup (hashlist, sel_name)
5469 hash *hashlist;
5470 tree sel_name;
5472 hash target;
5474 target = hashlist[HASHFUNCTION (sel_name) % SIZEHASHTABLE];
5476 while (target)
5478 if (sel_name == METHOD_SEL_NAME (target->key))
5479 return target;
5481 target = target->next;
5483 return 0;
5486 static void
5487 hash_add_attr (entry, value)
5488 hash entry;
5489 tree value;
5491 static attr attr_alloc_list = 0;
5492 static int attr_alloc_index = 0;
5493 attr obj;
5495 if (! attr_alloc_list || attr_alloc_index >= ATTR_ALLOC_LIST_SIZE)
5497 attr_alloc_index = 0;
5498 attr_alloc_list = (attr) xmalloc (sizeof (struct hashed_attribute)
5499 * ATTR_ALLOC_LIST_SIZE);
5500 if (! attr_alloc_list)
5501 perror ("unable to allocate in objc-tree.c");
5503 obj = &attr_alloc_list[attr_alloc_index++];
5504 obj->next = entry->list;
5505 obj->value = value;
5507 entry->list = obj; /* append to front */
5510 static tree
5511 lookup_method (mchain, method)
5512 tree mchain;
5513 tree method;
5515 tree key;
5517 if (TREE_CODE (method) == IDENTIFIER_NODE)
5518 key = method;
5519 else
5520 key = METHOD_SEL_NAME (method);
5522 while (mchain)
5524 if (METHOD_SEL_NAME (mchain) == key)
5525 return mchain;
5526 mchain = TREE_CHAIN (mchain);
5528 return NULL_TREE;
5531 static tree
5532 lookup_instance_method_static (interface, ident)
5533 tree interface;
5534 tree ident;
5536 tree inter = interface;
5537 tree chain = CLASS_NST_METHODS (inter);
5538 tree meth = NULL_TREE;
5542 if ((meth = lookup_method (chain, ident)))
5543 return meth;
5545 if (CLASS_CATEGORY_LIST (inter))
5547 tree category = CLASS_CATEGORY_LIST (inter);
5548 chain = CLASS_NST_METHODS (category);
5552 if ((meth = lookup_method (chain, ident)))
5553 return meth;
5555 /* Check for instance methods in protocols in categories. */
5556 if (CLASS_PROTOCOL_LIST (category))
5558 if ((meth = (lookup_method_in_protocol_list
5559 (CLASS_PROTOCOL_LIST (category), ident, 0))))
5560 return meth;
5563 if ((category = CLASS_CATEGORY_LIST (category)))
5564 chain = CLASS_NST_METHODS (category);
5566 while (category);
5569 if (CLASS_PROTOCOL_LIST (inter))
5571 if ((meth = (lookup_method_in_protocol_list
5572 (CLASS_PROTOCOL_LIST (inter), ident, 0))))
5573 return meth;
5576 if ((inter = lookup_interface (CLASS_SUPER_NAME (inter))))
5577 chain = CLASS_NST_METHODS (inter);
5579 while (inter);
5581 return meth;
5584 static tree
5585 lookup_class_method_static (interface, ident)
5586 tree interface;
5587 tree ident;
5589 tree inter = interface;
5590 tree chain = CLASS_CLS_METHODS (inter);
5591 tree meth = NULL_TREE;
5592 tree root_inter = NULL_TREE;
5596 if ((meth = lookup_method (chain, ident)))
5597 return meth;
5599 if (CLASS_CATEGORY_LIST (inter))
5601 tree category = CLASS_CATEGORY_LIST (inter);
5602 chain = CLASS_CLS_METHODS (category);
5606 if ((meth = lookup_method (chain, ident)))
5607 return meth;
5609 /* Check for class methods in protocols in categories. */
5610 if (CLASS_PROTOCOL_LIST (category))
5612 if ((meth = (lookup_method_in_protocol_list
5613 (CLASS_PROTOCOL_LIST (category), ident, 1))))
5614 return meth;
5617 if ((category = CLASS_CATEGORY_LIST (category)))
5618 chain = CLASS_CLS_METHODS (category);
5620 while (category);
5623 /* Check for class methods in protocols. */
5624 if (CLASS_PROTOCOL_LIST (inter))
5626 if ((meth = (lookup_method_in_protocol_list
5627 (CLASS_PROTOCOL_LIST (inter), ident, 1))))
5628 return meth;
5631 root_inter = inter;
5632 if ((inter = lookup_interface (CLASS_SUPER_NAME (inter))))
5633 chain = CLASS_CLS_METHODS (inter);
5635 while (inter);
5637 /* Simulate wrap around. */
5638 return lookup_instance_method_static (root_inter, ident);
5641 tree
5642 add_class_method (class, method)
5643 tree class;
5644 tree method;
5646 tree mth;
5647 hash hsh;
5649 if (!(mth = lookup_method (CLASS_CLS_METHODS (class), method)))
5651 /* put method on list in reverse order */
5652 TREE_CHAIN (method) = CLASS_CLS_METHODS (class);
5653 CLASS_CLS_METHODS (class) = method;
5655 else
5657 if (TREE_CODE (class) == CLASS_IMPLEMENTATION_TYPE)
5658 error ("duplicate definition of class method `%s'.",
5659 IDENTIFIER_POINTER (METHOD_SEL_NAME (mth)));
5660 else
5662 /* Check types; if different, complain. */
5663 if (!comp_proto_with_proto (method, mth))
5664 error ("duplicate declaration of class method `%s'.",
5665 IDENTIFIER_POINTER (METHOD_SEL_NAME (mth)));
5669 if (!(hsh = hash_lookup (cls_method_hash_list, METHOD_SEL_NAME (method))))
5671 /* Install on a global chain. */
5672 hash_enter (cls_method_hash_list, method);
5674 else
5676 /* Check types; if different, add to a list. */
5677 if (!comp_proto_with_proto (method, hsh->key))
5678 hash_add_attr (hsh, method);
5680 return method;
5683 tree
5684 add_instance_method (class, method)
5685 tree class;
5686 tree method;
5688 tree mth;
5689 hash hsh;
5691 if (!(mth = lookup_method (CLASS_NST_METHODS (class), method)))
5693 /* Put method on list in reverse order. */
5694 TREE_CHAIN (method) = CLASS_NST_METHODS (class);
5695 CLASS_NST_METHODS (class) = method;
5697 else
5699 if (TREE_CODE (class) == CLASS_IMPLEMENTATION_TYPE)
5700 error ("duplicate definition of instance method `%s'.",
5701 IDENTIFIER_POINTER (METHOD_SEL_NAME (mth)));
5702 else
5704 /* Check types; if different, complain. */
5705 if (!comp_proto_with_proto (method, mth))
5706 error ("duplicate declaration of instance method `%s'.",
5707 IDENTIFIER_POINTER (METHOD_SEL_NAME (mth)));
5711 if (!(hsh = hash_lookup (nst_method_hash_list, METHOD_SEL_NAME (method))))
5713 /* Install on a global chain. */
5714 hash_enter (nst_method_hash_list, method);
5716 else
5718 /* Check types; if different, add to a list. */
5719 if (!comp_proto_with_proto (method, hsh->key))
5720 hash_add_attr (hsh, method);
5722 return method;
5725 static tree
5726 add_class (class)
5727 tree class;
5729 /* Put interfaces on list in reverse order. */
5730 TREE_CHAIN (class) = interface_chain;
5731 interface_chain = class;
5732 return interface_chain;
5735 static void
5736 add_category (class, category)
5737 tree class;
5738 tree category;
5740 /* Put categories on list in reverse order. */
5741 tree cat = CLASS_CATEGORY_LIST (class);
5743 while (cat)
5745 if (CLASS_SUPER_NAME (cat) == CLASS_SUPER_NAME (category))
5746 warning ("duplicate interface declaration for category `%s(%s)'",
5747 IDENTIFIER_POINTER (CLASS_NAME (class)),
5748 IDENTIFIER_POINTER (CLASS_SUPER_NAME (category)));
5749 cat = CLASS_CATEGORY_LIST (cat);
5752 CLASS_CATEGORY_LIST (category) = CLASS_CATEGORY_LIST (class);
5753 CLASS_CATEGORY_LIST (class) = category;
5756 /* Called after parsing each instance variable declaration. Necessary to
5757 preserve typedefs and implement public/private...
5759 PUBLIC is 1 for public, 0 for protected, and 2 for private. */
5761 tree
5762 add_instance_variable (class, public, declarator, declspecs, width)
5763 tree class;
5764 int public;
5765 tree declarator;
5766 tree declspecs;
5767 tree width;
5769 tree field_decl, raw_decl;
5771 raw_decl = build_tree_list (declspecs, declarator);
5773 if (CLASS_RAW_IVARS (class))
5774 chainon (CLASS_RAW_IVARS (class), raw_decl);
5775 else
5776 CLASS_RAW_IVARS (class) = raw_decl;
5778 field_decl = grokfield (input_filename, lineno,
5779 declarator, declspecs, width);
5781 /* Overload the public attribute, it is not used for FIELD_DECLs. */
5782 switch (public)
5784 case 0:
5785 TREE_PUBLIC (field_decl) = 0;
5786 TREE_PRIVATE (field_decl) = 0;
5787 TREE_PROTECTED (field_decl) = 1;
5788 break;
5790 case 1:
5791 TREE_PUBLIC (field_decl) = 1;
5792 TREE_PRIVATE (field_decl) = 0;
5793 TREE_PROTECTED (field_decl) = 0;
5794 break;
5796 case 2:
5797 TREE_PUBLIC (field_decl) = 0;
5798 TREE_PRIVATE (field_decl) = 1;
5799 TREE_PROTECTED (field_decl) = 0;
5800 break;
5804 if (CLASS_IVARS (class))
5805 chainon (CLASS_IVARS (class), field_decl);
5806 else
5807 CLASS_IVARS (class) = field_decl;
5809 return class;
5812 tree
5813 is_ivar (decl_chain, ident)
5814 tree decl_chain;
5815 tree ident;
5817 for ( ; decl_chain; decl_chain = TREE_CHAIN (decl_chain))
5818 if (DECL_NAME (decl_chain) == ident)
5819 return decl_chain;
5820 return NULL_TREE;
5823 /* True if the ivar is private and we are not in its implementation. */
5826 is_private (decl)
5827 tree decl;
5829 if (TREE_PRIVATE (decl)
5830 && ! is_ivar (CLASS_IVARS (implementation_template), DECL_NAME (decl)))
5832 error ("instance variable `%s' is declared private",
5833 IDENTIFIER_POINTER (DECL_NAME (decl)));
5834 return 1;
5836 else
5837 return 0;
5840 /* We have an instance variable reference;, check to see if it is public. */
5843 is_public (expr, identifier)
5844 tree expr;
5845 tree identifier;
5847 tree basetype = TREE_TYPE (expr);
5848 enum tree_code code = TREE_CODE (basetype);
5849 tree decl;
5851 if (code == RECORD_TYPE)
5853 if (TREE_STATIC_TEMPLATE (basetype))
5855 if (!lookup_interface (TYPE_NAME (basetype)))
5857 error ("Cannot find interface declaration for `%s'",
5858 IDENTIFIER_POINTER (TYPE_NAME (basetype)));
5859 return 0;
5862 if ((decl = is_ivar (TYPE_FIELDS (basetype), identifier)))
5864 if (TREE_PUBLIC (decl))
5865 return 1;
5867 /* Important difference between the Stepstone translator:
5868 all instance variables should be public within the context
5869 of the implementation. */
5870 if (implementation_context
5871 && (((TREE_CODE (implementation_context)
5872 == CLASS_IMPLEMENTATION_TYPE)
5873 || (TREE_CODE (implementation_context)
5874 == CATEGORY_IMPLEMENTATION_TYPE))
5875 && (CLASS_NAME (implementation_context)
5876 == TYPE_NAME (basetype))))
5877 return ! is_private (decl);
5879 error ("instance variable `%s' is declared %s",
5880 IDENTIFIER_POINTER (identifier),
5881 TREE_PRIVATE (decl) ? "private" : "protected");
5882 return 0;
5886 else if (implementation_context && (basetype == objc_object_reference))
5888 TREE_TYPE (expr) = uprivate_record;
5889 warning ("static access to object of type `id'");
5893 return 1;
5896 /* Implement @defs (<classname>) within struct bodies. */
5898 tree
5899 get_class_ivars (interface)
5900 tree interface;
5902 return build_ivar_chain (interface, 1);
5905 /* Make sure all entries in CHAIN are also in LIST. */
5907 static int
5908 check_methods (chain, list, mtype)
5909 tree chain;
5910 tree list;
5911 int mtype;
5913 int first = 1;
5915 while (chain)
5917 if (!lookup_method (list, chain))
5919 if (first)
5921 if (TREE_CODE (implementation_context)
5922 == CLASS_IMPLEMENTATION_TYPE)
5923 warning ("incomplete implementation of class `%s'",
5924 IDENTIFIER_POINTER (CLASS_NAME (implementation_context)));
5925 else if (TREE_CODE (implementation_context)
5926 == CATEGORY_IMPLEMENTATION_TYPE)
5927 warning ("incomplete implementation of category `%s'",
5928 IDENTIFIER_POINTER (CLASS_SUPER_NAME (implementation_context)));
5929 first = 0;
5932 warning ("method definition for `%c%s' not found",
5933 mtype, IDENTIFIER_POINTER (METHOD_SEL_NAME (chain)));
5936 chain = TREE_CHAIN (chain);
5939 return first;
5942 static int
5943 conforms_to_protocol (class, protocol)
5944 tree class;
5945 tree protocol;
5947 while (protocol)
5949 tree p = CLASS_PROTOCOL_LIST (class);
5951 while (p && TREE_VALUE (p) != TREE_VALUE (protocol))
5952 p = TREE_CHAIN (p);
5954 if (!p)
5956 tree super = (CLASS_SUPER_NAME (class)
5957 ? lookup_interface (CLASS_SUPER_NAME (class))
5958 : NULL_TREE);
5959 int tmp = super ? conforms_to_protocol (super, protocol) : 0;
5960 if (!tmp)
5961 return 0;
5964 protocol = TREE_CHAIN (protocol);
5967 return 1;
5970 /* Make sure all methods in CHAIN are accessible as MTYPE methods in
5971 CONTEXT. This is one of two mechanisms to check protocol integrity. */
5973 static int
5974 check_methods_accessible (chain, context, mtype)
5975 tree chain;
5976 tree context;
5977 int mtype;
5979 int first = 1;
5980 tree list;
5981 tree base_context = context;
5983 while (chain)
5985 context = base_context;
5986 while (context)
5988 if (mtype == '+')
5989 list = CLASS_CLS_METHODS (context);
5990 else
5991 list = CLASS_NST_METHODS (context);
5993 if (lookup_method (list, chain))
5994 break;
5996 else if (TREE_CODE (context) == CLASS_IMPLEMENTATION_TYPE
5997 || TREE_CODE (context) == CLASS_INTERFACE_TYPE)
5998 context = (CLASS_SUPER_NAME (context)
5999 ? lookup_interface (CLASS_SUPER_NAME (context))
6000 : NULL_TREE);
6002 else if (TREE_CODE (context) == CATEGORY_IMPLEMENTATION_TYPE
6003 || TREE_CODE (context) == CATEGORY_INTERFACE_TYPE)
6004 context = (CLASS_NAME (context)
6005 ? lookup_interface (CLASS_NAME (context))
6006 : NULL_TREE);
6007 else
6008 abort ();
6011 if (context == NULL_TREE)
6013 if (first)
6015 if (TREE_CODE (implementation_context)
6016 == CLASS_IMPLEMENTATION_TYPE)
6017 warning ("incomplete implementation of class `%s'",
6018 IDENTIFIER_POINTER
6019 (CLASS_NAME (implementation_context)));
6020 else if (TREE_CODE (implementation_context)
6021 == CATEGORY_IMPLEMENTATION_TYPE)
6022 warning ("incomplete implementation of category `%s'",
6023 IDENTIFIER_POINTER
6024 (CLASS_SUPER_NAME (implementation_context)));
6025 first = 0;
6027 warning ("method definition for `%c%s' not found",
6028 mtype, IDENTIFIER_POINTER (METHOD_SEL_NAME (chain)));
6031 chain = TREE_CHAIN (chain); /* next method... */
6033 return first;
6036 static void
6037 check_protocols (proto_list, type, name)
6038 tree proto_list;
6039 const char *type;
6040 const char *name;
6042 for ( ; proto_list; proto_list = TREE_CHAIN (proto_list))
6044 tree p = TREE_VALUE (proto_list);
6046 if (TREE_CODE (p) == PROTOCOL_INTERFACE_TYPE)
6048 int f1, f2;
6050 /* Ensure that all protocols have bodies. */
6051 if (flag_warn_protocol) {
6052 f1 = check_methods (PROTOCOL_CLS_METHODS (p),
6053 CLASS_CLS_METHODS (implementation_context),
6054 '+');
6055 f2 = check_methods (PROTOCOL_NST_METHODS (p),
6056 CLASS_NST_METHODS (implementation_context),
6057 '-');
6058 } else {
6059 f1 = check_methods_accessible (PROTOCOL_CLS_METHODS (p),
6060 implementation_context,
6061 '+');
6062 f2 = check_methods_accessible (PROTOCOL_NST_METHODS (p),
6063 implementation_context,
6064 '-');
6067 if (!f1 || !f2)
6068 warning ("%s `%s' does not fully implement the `%s' protocol",
6069 type, name, IDENTIFIER_POINTER (PROTOCOL_NAME (p)));
6072 else
6074 ; /* An identifier if we could not find a protocol. */
6077 /* Check protocols recursively. */
6078 if (PROTOCOL_LIST (p))
6080 tree super_class
6081 = lookup_interface (CLASS_SUPER_NAME (implementation_template));
6082 if (! conforms_to_protocol (super_class, PROTOCOL_LIST (p)))
6083 check_protocols (PROTOCOL_LIST (p), type, name);
6088 /* Make sure that the class CLASS_NAME is defined
6089 CODE says which kind of thing CLASS_NAME ought to be.
6090 It can be CLASS_INTERFACE_TYPE, CLASS_IMPLEMENTATION_TYPE,
6091 CATEGORY_INTERFACE_TYPE, or CATEGORY_IMPLEMENTATION_TYPE. */
6093 tree
6094 start_class (code, class_name, super_name, protocol_list)
6095 enum tree_code code;
6096 tree class_name;
6097 tree super_name;
6098 tree protocol_list;
6100 tree class, decl;
6102 class = make_node (code);
6103 TYPE_BINFO (class) = make_tree_vec (5);
6105 CLASS_NAME (class) = class_name;
6106 CLASS_SUPER_NAME (class) = super_name;
6107 CLASS_CLS_METHODS (class) = NULL_TREE;
6109 if (! is_class_name (class_name) && (decl = lookup_name (class_name)))
6111 error ("`%s' redeclared as different kind of symbol",
6112 IDENTIFIER_POINTER (class_name));
6113 error_with_decl (decl, "previous declaration of `%s'");
6116 if (code == CLASS_IMPLEMENTATION_TYPE)
6119 static tree implemented_classes = 0;
6120 tree chain = implemented_classes;
6121 for (chain = implemented_classes; chain; chain = TREE_CHAIN (chain))
6122 if (TREE_VALUE (chain) == class_name)
6124 error ("reimplementation of class `%s'",
6125 IDENTIFIER_POINTER (class_name));
6126 return error_mark_node;
6128 implemented_classes = tree_cons (NULL_TREE, class_name,
6129 implemented_classes);
6132 /* Pre-build the following entities - for speed/convenience. */
6133 if (!self_id)
6134 self_id = get_identifier ("self");
6135 if (!ucmd_id)
6136 ucmd_id = get_identifier ("_cmd");
6137 if (!unused_list)
6138 unused_list
6139 = build_tree_list (get_identifier ("__unused__"), NULL_TREE);
6140 if (!objc_super_template)
6141 objc_super_template = build_super_template ();
6143 /* Reset for multiple classes per file. */
6144 method_slot = 0;
6146 implementation_context = class;
6148 /* Lookup the interface for this implementation. */
6150 if (!(implementation_template = lookup_interface (class_name)))
6152 warning ("Cannot find interface declaration for `%s'",
6153 IDENTIFIER_POINTER (class_name));
6154 add_class (implementation_template = implementation_context);
6157 /* If a super class has been specified in the implementation,
6158 insure it conforms to the one specified in the interface. */
6160 if (super_name
6161 && (super_name != CLASS_SUPER_NAME (implementation_template)))
6163 tree previous_name = CLASS_SUPER_NAME (implementation_template);
6164 const char *name =
6165 previous_name ? IDENTIFIER_POINTER (previous_name) : "";
6166 error ("conflicting super class name `%s'",
6167 IDENTIFIER_POINTER (super_name));
6168 error ("previous declaration of `%s'", name);
6171 else if (! super_name)
6173 CLASS_SUPER_NAME (implementation_context)
6174 = CLASS_SUPER_NAME (implementation_template);
6178 else if (code == CLASS_INTERFACE_TYPE)
6180 if (lookup_interface (class_name))
6181 warning ("duplicate interface declaration for class `%s'",
6182 IDENTIFIER_POINTER (class_name));
6183 else
6184 add_class (class);
6186 if (protocol_list)
6187 CLASS_PROTOCOL_LIST (class)
6188 = lookup_and_install_protocols (protocol_list);
6191 else if (code == CATEGORY_INTERFACE_TYPE)
6193 tree class_category_is_assoc_with;
6195 /* For a category, class_name is really the name of the class that
6196 the following set of methods will be associated with. We must
6197 find the interface so that can derive the objects template. */
6199 if (!(class_category_is_assoc_with = lookup_interface (class_name)))
6201 error ("Cannot find interface declaration for `%s'",
6202 IDENTIFIER_POINTER (class_name));
6203 exit (FATAL_EXIT_CODE);
6205 else
6206 add_category (class_category_is_assoc_with, class);
6208 if (protocol_list)
6209 CLASS_PROTOCOL_LIST (class)
6210 = lookup_and_install_protocols (protocol_list);
6213 else if (code == CATEGORY_IMPLEMENTATION_TYPE)
6215 /* Pre-build the following entities for speed/convenience. */
6216 if (!self_id)
6217 self_id = get_identifier ("self");
6218 if (!ucmd_id)
6219 ucmd_id = get_identifier ("_cmd");
6220 if (!unused_list)
6221 unused_list
6222 = build_tree_list (get_identifier ("__unused__"), NULL_TREE);
6223 if (!objc_super_template)
6224 objc_super_template = build_super_template ();
6226 /* Reset for multiple classes per file. */
6227 method_slot = 0;
6229 implementation_context = class;
6231 /* For a category, class_name is really the name of the class that
6232 the following set of methods will be associated with. We must
6233 find the interface so that can derive the objects template. */
6235 if (!(implementation_template = lookup_interface (class_name)))
6237 error ("Cannot find interface declaration for `%s'",
6238 IDENTIFIER_POINTER (class_name));
6239 exit (FATAL_EXIT_CODE);
6242 return class;
6245 tree
6246 continue_class (class)
6247 tree class;
6249 if (TREE_CODE (class) == CLASS_IMPLEMENTATION_TYPE
6250 || TREE_CODE (class) == CATEGORY_IMPLEMENTATION_TYPE)
6252 struct imp_entry *imp_entry;
6253 tree ivar_context;
6255 /* Check consistency of the instance variables. */
6257 if (CLASS_IVARS (class))
6258 check_ivars (implementation_template, class);
6260 /* code generation */
6262 ivar_context = build_private_template (implementation_template);
6264 if (!objc_class_template)
6265 build_class_template ();
6267 if (!(imp_entry
6268 = (struct imp_entry *) xmalloc (sizeof (struct imp_entry))))
6269 perror ("unable to allocate in objc-tree.c");
6271 imp_entry->next = imp_list;
6272 imp_entry->imp_context = class;
6273 imp_entry->imp_template = implementation_template;
6275 synth_forward_declarations ();
6276 imp_entry->class_decl = UOBJC_CLASS_decl;
6277 imp_entry->meta_decl = UOBJC_METACLASS_decl;
6279 /* Append to front and increment count. */
6280 imp_list = imp_entry;
6281 if (TREE_CODE (class) == CLASS_IMPLEMENTATION_TYPE)
6282 imp_count++;
6283 else
6284 cat_count++;
6286 return ivar_context;
6289 else if (TREE_CODE (class) == CLASS_INTERFACE_TYPE)
6291 tree record = xref_tag (RECORD_TYPE, CLASS_NAME (class));
6293 if (!TYPE_FIELDS (record))
6295 finish_struct (record, build_ivar_chain (class, 0), NULL_TREE);
6296 CLASS_STATIC_TEMPLATE (class) = record;
6298 /* Mark this record as a class template for static typing. */
6299 TREE_STATIC_TEMPLATE (record) = 1;
6302 return NULL_TREE;
6305 else
6306 return error_mark_node;
6309 /* This is called once we see the "@end" in an interface/implementation. */
6311 void
6312 finish_class (class)
6313 tree class;
6315 if (TREE_CODE (class) == CLASS_IMPLEMENTATION_TYPE)
6317 /* All code generation is done in finish_objc. */
6319 if (implementation_template != implementation_context)
6321 /* Ensure that all method listed in the interface contain bodies. */
6322 check_methods (CLASS_CLS_METHODS (implementation_template),
6323 CLASS_CLS_METHODS (implementation_context), '+');
6324 check_methods (CLASS_NST_METHODS (implementation_template),
6325 CLASS_NST_METHODS (implementation_context), '-');
6327 if (CLASS_PROTOCOL_LIST (implementation_template))
6328 check_protocols (CLASS_PROTOCOL_LIST (implementation_template),
6329 "class",
6330 IDENTIFIER_POINTER (CLASS_NAME (implementation_context)));
6334 else if (TREE_CODE (class) == CATEGORY_IMPLEMENTATION_TYPE)
6336 tree category = CLASS_CATEGORY_LIST (implementation_template);
6338 /* Find the category interface from the class it is associated with. */
6339 while (category)
6341 if (CLASS_SUPER_NAME (class) == CLASS_SUPER_NAME (category))
6342 break;
6343 category = CLASS_CATEGORY_LIST (category);
6346 if (category)
6348 /* Ensure all method listed in the interface contain bodies. */
6349 check_methods (CLASS_CLS_METHODS (category),
6350 CLASS_CLS_METHODS (implementation_context), '+');
6351 check_methods (CLASS_NST_METHODS (category),
6352 CLASS_NST_METHODS (implementation_context), '-');
6354 if (CLASS_PROTOCOL_LIST (category))
6355 check_protocols (CLASS_PROTOCOL_LIST (category),
6356 "category",
6357 IDENTIFIER_POINTER (CLASS_SUPER_NAME (implementation_context)));
6361 else if (TREE_CODE (class) == CLASS_INTERFACE_TYPE)
6363 tree decl_specs;
6364 const char *class_name = IDENTIFIER_POINTER (CLASS_NAME (class));
6365 char *string = (char *) alloca (strlen (class_name) + 3);
6367 /* extern struct objc_object *_<my_name>; */
6369 sprintf (string, "_%s", class_name);
6371 decl_specs = build_tree_list (NULL_TREE, ridpointers[(int) RID_EXTERN]);
6372 decl_specs = tree_cons (NULL_TREE, objc_object_reference, decl_specs);
6373 define_decl (build1 (INDIRECT_REF, NULL_TREE, get_identifier (string)),
6374 decl_specs);
6378 static tree
6379 add_protocol (protocol)
6380 tree protocol;
6382 /* Put protocol on list in reverse order. */
6383 TREE_CHAIN (protocol) = protocol_chain;
6384 protocol_chain = protocol;
6385 return protocol_chain;
6388 static tree
6389 lookup_protocol (ident)
6390 tree ident;
6392 tree chain;
6394 for (chain = protocol_chain; chain; chain = TREE_CHAIN (chain))
6396 if (ident == PROTOCOL_NAME (chain))
6397 return chain;
6400 return NULL_TREE;
6403 tree
6404 start_protocol (code, name, list)
6405 enum tree_code code;
6406 tree name;
6407 tree list;
6409 tree protocol;
6411 /* This is as good a place as any. Need to invoke push_tag_toplevel. */
6412 if (!objc_protocol_template)
6413 objc_protocol_template = build_protocol_template ();
6415 protocol = make_node (code);
6416 TYPE_BINFO (protocol) = make_tree_vec (2);
6418 PROTOCOL_NAME (protocol) = name;
6419 PROTOCOL_LIST (protocol) = list;
6421 lookup_and_install_protocols (list);
6423 if (lookup_protocol (name))
6424 warning ("duplicate declaration for protocol `%s'",
6425 IDENTIFIER_POINTER (name));
6426 else
6427 add_protocol (protocol);
6429 PROTOCOL_FORWARD_DECL (protocol) = NULL_TREE;
6431 return protocol;
6434 void
6435 finish_protocol (protocol)
6436 tree protocol ATTRIBUTE_UNUSED;
6441 /* "Encode" a data type into a string, which grows in util_obstack.
6442 ??? What is the FORMAT? Someone please document this! */
6444 static void
6445 encode_type_qualifiers (declspecs)
6446 tree declspecs;
6448 tree spec;
6450 for (spec = declspecs; spec; spec = TREE_CHAIN (spec))
6452 if (ridpointers[(int) RID_CONST] == TREE_VALUE (spec))
6453 obstack_1grow (&util_obstack, 'r');
6454 else if (ridpointers[(int) RID_IN] == TREE_VALUE (spec))
6455 obstack_1grow (&util_obstack, 'n');
6456 else if (ridpointers[(int) RID_INOUT] == TREE_VALUE (spec))
6457 obstack_1grow (&util_obstack, 'N');
6458 else if (ridpointers[(int) RID_OUT] == TREE_VALUE (spec))
6459 obstack_1grow (&util_obstack, 'o');
6460 else if (ridpointers[(int) RID_BYCOPY] == TREE_VALUE (spec))
6461 obstack_1grow (&util_obstack, 'O');
6462 else if (ridpointers[(int) RID_BYREF] == TREE_VALUE (spec))
6463 obstack_1grow (&util_obstack, 'R');
6464 else if (ridpointers[(int) RID_ONEWAY] == TREE_VALUE (spec))
6465 obstack_1grow (&util_obstack, 'V');
6469 /* Encode a pointer type. */
6471 static void
6472 encode_pointer (type, curtype, format)
6473 tree type;
6474 int curtype;
6475 int format;
6477 tree pointer_to = TREE_TYPE (type);
6479 if (TREE_CODE (pointer_to) == RECORD_TYPE)
6481 if (TYPE_NAME (pointer_to)
6482 && TREE_CODE (TYPE_NAME (pointer_to)) == IDENTIFIER_NODE)
6484 const char *name = IDENTIFIER_POINTER (TYPE_NAME (pointer_to));
6486 if (strcmp (name, TAG_OBJECT) == 0) /* '@' */
6488 obstack_1grow (&util_obstack, '@');
6489 return;
6491 else if (TREE_STATIC_TEMPLATE (pointer_to))
6493 if (generating_instance_variables)
6495 obstack_1grow (&util_obstack, '@');
6496 obstack_1grow (&util_obstack, '"');
6497 obstack_grow (&util_obstack, name, strlen (name));
6498 obstack_1grow (&util_obstack, '"');
6499 return;
6501 else
6503 obstack_1grow (&util_obstack, '@');
6504 return;
6507 else if (strcmp (name, TAG_CLASS) == 0) /* '#' */
6509 obstack_1grow (&util_obstack, '#');
6510 return;
6512 #ifndef OBJC_INT_SELECTORS
6513 else if (strcmp (name, TAG_SELECTOR) == 0) /* ':' */
6515 obstack_1grow (&util_obstack, ':');
6516 return;
6518 #endif /* OBJC_INT_SELECTORS */
6521 else if (TREE_CODE (pointer_to) == INTEGER_TYPE
6522 && TYPE_MODE (pointer_to) == QImode)
6524 obstack_1grow (&util_obstack, '*');
6525 return;
6528 /* We have a type that does not get special treatment. */
6530 /* NeXT extension */
6531 obstack_1grow (&util_obstack, '^');
6532 encode_type (pointer_to, curtype, format);
6535 static void
6536 encode_array (type, curtype, format)
6537 tree type;
6538 int curtype;
6539 int format;
6541 tree an_int_cst = TYPE_SIZE (type);
6542 tree array_of = TREE_TYPE (type);
6543 char buffer[40];
6545 /* An incomplete array is treated like a pointer. */
6546 if (an_int_cst == NULL)
6548 encode_pointer (type, curtype, format);
6549 return;
6552 sprintf (buffer, "[%ld",
6553 (long) (TREE_INT_CST_LOW (an_int_cst)
6554 / TREE_INT_CST_LOW (TYPE_SIZE (array_of))));
6556 obstack_grow (&util_obstack, buffer, strlen (buffer));
6557 encode_type (array_of, curtype, format);
6558 obstack_1grow (&util_obstack, ']');
6559 return;
6562 static void
6563 encode_aggregate_within (type, curtype, format, left, right)
6564 tree type;
6565 int curtype;
6566 int format;
6567 int left;
6568 int right;
6570 if (obstack_object_size (&util_obstack) > 0
6571 && *(obstack_next_free (&util_obstack) - 1) == '^')
6573 tree name = TYPE_NAME (type);
6575 /* we have a reference; this is a NeXT extension. */
6577 if (obstack_object_size (&util_obstack) - curtype == 1
6578 && format == OBJC_ENCODE_INLINE_DEFS)
6580 /* Output format of struct for first level only. */
6581 tree fields = TYPE_FIELDS (type);
6583 if (name && TREE_CODE (name) == IDENTIFIER_NODE)
6585 obstack_1grow (&util_obstack, left);
6586 obstack_grow (&util_obstack,
6587 IDENTIFIER_POINTER (name),
6588 strlen (IDENTIFIER_POINTER (name)));
6589 obstack_1grow (&util_obstack, '=');
6591 else
6593 obstack_1grow (&util_obstack, left);
6594 obstack_grow (&util_obstack, "?=", 2);
6597 for ( ; fields; fields = TREE_CHAIN (fields))
6598 encode_field_decl (fields, curtype, format);
6600 obstack_1grow (&util_obstack, right);
6603 else if (name && TREE_CODE (name) == IDENTIFIER_NODE)
6605 obstack_1grow (&util_obstack, left);
6606 obstack_grow (&util_obstack,
6607 IDENTIFIER_POINTER (name),
6608 strlen (IDENTIFIER_POINTER (name)));
6609 obstack_1grow (&util_obstack, right);
6612 else
6614 /* We have an untagged structure or a typedef. */
6615 obstack_1grow (&util_obstack, left);
6616 obstack_1grow (&util_obstack, '?');
6617 obstack_1grow (&util_obstack, right);
6621 else
6623 tree name = TYPE_NAME (type);
6624 tree fields = TYPE_FIELDS (type);
6626 if (format == OBJC_ENCODE_INLINE_DEFS
6627 || generating_instance_variables)
6629 obstack_1grow (&util_obstack, left);
6630 if (name && TREE_CODE (name) == IDENTIFIER_NODE)
6631 obstack_grow (&util_obstack,
6632 IDENTIFIER_POINTER (name),
6633 strlen (IDENTIFIER_POINTER (name)));
6634 else
6635 obstack_1grow (&util_obstack, '?');
6637 obstack_1grow (&util_obstack, '=');
6639 for (; fields; fields = TREE_CHAIN (fields))
6641 if (generating_instance_variables)
6643 tree fname = DECL_NAME (fields);
6645 obstack_1grow (&util_obstack, '"');
6646 if (fname && TREE_CODE (fname) == IDENTIFIER_NODE)
6648 obstack_grow (&util_obstack,
6649 IDENTIFIER_POINTER (fname),
6650 strlen (IDENTIFIER_POINTER (fname)));
6653 obstack_1grow (&util_obstack, '"');
6656 encode_field_decl (fields, curtype, format);
6659 obstack_1grow (&util_obstack, right);
6662 else
6664 obstack_1grow (&util_obstack, left);
6665 if (name && TREE_CODE (name) == IDENTIFIER_NODE)
6666 obstack_grow (&util_obstack,
6667 IDENTIFIER_POINTER (name),
6668 strlen (IDENTIFIER_POINTER (name)));
6669 else
6670 /* We have an untagged structure or a typedef. */
6671 obstack_1grow (&util_obstack, '?');
6673 obstack_1grow (&util_obstack, right);
6678 static void
6679 encode_aggregate (type, curtype, format)
6680 tree type;
6681 int curtype;
6682 int format;
6684 enum tree_code code = TREE_CODE (type);
6686 switch (code)
6688 case RECORD_TYPE:
6690 encode_aggregate_within(type, curtype, format, '{', '}');
6691 break;
6693 case UNION_TYPE:
6695 encode_aggregate_within(type, curtype, format, '(', ')');
6696 break;
6699 case ENUMERAL_TYPE:
6700 obstack_1grow (&util_obstack, 'i');
6701 break;
6703 default:
6704 break;
6708 /* Support bitfields. The current version of Objective-C does not support
6709 them. The string will consist of one or more "b:n"'s where n is an
6710 integer describing the width of the bitfield. Currently, classes in
6711 the kit implement a method "-(char *)describeBitfieldStruct:" that
6712 simulates this. If they do not implement this method, the archiver
6713 assumes the bitfield is 16 bits wide (padded if necessary) and packed
6714 according to the GNU compiler. After looking at the "kit", it appears
6715 that all classes currently rely on this default behavior, rather than
6716 hand generating this string (which is tedious). */
6718 static void
6719 encode_bitfield (width)
6720 int width;
6722 char buffer[40];
6723 sprintf (buffer, "b%d", width);
6724 obstack_grow (&util_obstack, buffer, strlen (buffer));
6727 /* FORMAT will be OBJC_ENCODE_INLINE_DEFS or OBJC_ENCODE_DONT_INLINE_DEFS. */
6729 static void
6730 encode_type (type, curtype, format)
6731 tree type;
6732 int curtype;
6733 int format;
6735 enum tree_code code = TREE_CODE (type);
6737 if (code == INTEGER_TYPE)
6739 if (integer_zerop (TYPE_MIN_VALUE (type)))
6741 /* Unsigned integer types. */
6743 if (TYPE_MODE (type) == QImode)
6744 obstack_1grow (&util_obstack, 'C');
6745 else if (TYPE_MODE (type) == HImode)
6746 obstack_1grow (&util_obstack, 'S');
6747 else if (TYPE_MODE (type) == SImode)
6749 if (type == long_unsigned_type_node)
6750 obstack_1grow (&util_obstack, 'L');
6751 else
6752 obstack_1grow (&util_obstack, 'I');
6754 else if (TYPE_MODE (type) == DImode)
6755 obstack_1grow (&util_obstack, 'Q');
6758 else
6759 /* Signed integer types. */
6761 if (TYPE_MODE (type) == QImode)
6762 obstack_1grow (&util_obstack, 'c');
6763 else if (TYPE_MODE (type) == HImode)
6764 obstack_1grow (&util_obstack, 's');
6765 else if (TYPE_MODE (type) == SImode)
6767 if (type == long_integer_type_node)
6768 obstack_1grow (&util_obstack, 'l');
6769 else
6770 obstack_1grow (&util_obstack, 'i');
6773 else if (TYPE_MODE (type) == DImode)
6774 obstack_1grow (&util_obstack, 'q');
6778 else if (code == REAL_TYPE)
6780 /* Floating point types. */
6782 if (TYPE_MODE (type) == SFmode)
6783 obstack_1grow (&util_obstack, 'f');
6784 else if (TYPE_MODE (type) == DFmode
6785 || TYPE_MODE (type) == TFmode)
6786 obstack_1grow (&util_obstack, 'd');
6789 else if (code == VOID_TYPE)
6790 obstack_1grow (&util_obstack, 'v');
6792 else if (code == ARRAY_TYPE)
6793 encode_array (type, curtype, format);
6795 else if (code == POINTER_TYPE)
6796 encode_pointer (type, curtype, format);
6798 else if (code == RECORD_TYPE || code == UNION_TYPE || code == ENUMERAL_TYPE)
6799 encode_aggregate (type, curtype, format);
6801 else if (code == FUNCTION_TYPE) /* '?' */
6802 obstack_1grow (&util_obstack, '?');
6805 static void
6806 encode_complete_bitfield (int position, tree type, int size)
6808 enum tree_code code = TREE_CODE (type);
6809 char buffer[40];
6810 char charType = '?';
6812 if (code == INTEGER_TYPE)
6814 if (integer_zerop (TYPE_MIN_VALUE (type)))
6816 /* Unsigned integer types. */
6818 if (TYPE_MODE (type) == QImode)
6819 charType = 'C';
6820 else if (TYPE_MODE (type) == HImode)
6821 charType = 'S';
6822 else if (TYPE_MODE (type) == SImode)
6824 if (type == long_unsigned_type_node)
6825 charType = 'L';
6826 else
6827 charType = 'I';
6829 else if (TYPE_MODE (type) == DImode)
6830 charType = 'Q';
6833 else
6834 /* Signed integer types. */
6836 if (TYPE_MODE (type) == QImode)
6837 charType = 'c';
6838 else if (TYPE_MODE (type) == HImode)
6839 charType = 's';
6840 else if (TYPE_MODE (type) == SImode)
6842 if (type == long_integer_type_node)
6843 charType = 'l';
6844 else
6845 charType = 'i';
6848 else if (TYPE_MODE (type) == DImode)
6849 charType = 'q';
6853 else
6854 abort ();
6856 sprintf (buffer, "b%d%c%d", position, charType, size);
6857 obstack_grow (&util_obstack, buffer, strlen (buffer));
6860 static void
6861 encode_field_decl (field_decl, curtype, format)
6862 tree field_decl;
6863 int curtype;
6864 int format;
6866 tree type;
6868 type = TREE_TYPE (field_decl);
6870 /* If this field is obviously a bitfield, or is a bitfield that has been
6871 clobbered to look like a ordinary integer mode, go ahead and generate
6872 the bitfield typing information. */
6873 if (flag_next_runtime)
6875 if (DECL_BIT_FIELD (field_decl))
6876 encode_bitfield (tree_low_cst (DECL_SIZE (field_decl), 1));
6877 else
6878 encode_type (TREE_TYPE (field_decl), curtype, format);
6880 else
6882 if (DECL_BIT_FIELD (field_decl))
6883 encode_complete_bitfield (int_bit_position (field_decl),
6884 DECL_BIT_FIELD_TYPE (field_decl),
6885 tree_low_cst (DECL_SIZE (field_decl), 1));
6886 else
6887 encode_type (TREE_TYPE (field_decl), curtype, format);
6891 static tree
6892 expr_last (complex_expr)
6893 tree complex_expr;
6895 tree next;
6897 if (complex_expr)
6898 while ((next = TREE_OPERAND (complex_expr, 0)))
6899 complex_expr = next;
6901 return complex_expr;
6904 /* The selector of the current method,
6905 or NULL if we aren't compiling a method. */
6907 tree
6908 maybe_objc_method_name (decl)
6909 tree decl ATTRIBUTE_UNUSED;
6911 if (method_context)
6912 return METHOD_SEL_NAME (method_context);
6913 else
6914 return 0;
6917 /* Transform a method definition into a function definition as follows:
6918 - synthesize the first two arguments, "self" and "_cmd". */
6920 void
6921 start_method_def (method)
6922 tree method;
6924 tree decl_specs;
6926 /* Required to implement _msgSuper. */
6927 method_context = method;
6928 UOBJC_SUPER_decl = NULL_TREE;
6930 /* Must be called BEFORE start_function. */
6931 pushlevel (0);
6933 /* Generate prototype declarations for arguments..."new-style". */
6935 if (TREE_CODE (method_context) == INSTANCE_METHOD_DECL)
6936 decl_specs = build_tree_list (NULL_TREE, uprivate_record);
6937 else
6938 /* Really a `struct objc_class *'. However, we allow people to
6939 assign to self, which changes its type midstream. */
6940 decl_specs = build_tree_list (NULL_TREE, objc_object_reference);
6942 push_parm_decl (build_tree_list
6943 (build_tree_list (decl_specs,
6944 build1 (INDIRECT_REF, NULL_TREE, self_id)),
6945 build_tree_list (unused_list, NULL_TREE)));
6947 #ifdef OBJC_INT_SELECTORS
6948 decl_specs = build_tree_list (NULL_TREE, ridpointers[(int) RID_UNSIGNED]);
6949 decl_specs = tree_cons (NULL_TREE, ridpointers[(int) RID_INT], decl_specs);
6950 push_parm_decl (build_tree_list (build_tree_list (decl_specs, ucmd_id),
6951 build_tree_list (unused_list, NULL_TREE)));
6952 #else /* not OBJC_INT_SELECTORS */
6953 decl_specs = build_tree_list (NULL_TREE,
6954 xref_tag (RECORD_TYPE,
6955 get_identifier (TAG_SELECTOR)));
6956 push_parm_decl (build_tree_list
6957 (build_tree_list (decl_specs,
6958 build1 (INDIRECT_REF, NULL_TREE, ucmd_id)),
6959 build_tree_list (unused_list, NULL_TREE)));
6960 #endif /* not OBJC_INT_SELECTORS */
6962 /* Generate argument declarations if a keyword_decl. */
6963 if (METHOD_SEL_ARGS (method))
6965 tree arglist = METHOD_SEL_ARGS (method);
6968 tree arg_spec = TREE_PURPOSE (TREE_TYPE (arglist));
6969 tree arg_decl = TREE_VALUE (TREE_TYPE (arglist));
6971 if (arg_decl)
6973 tree last_expr = expr_last (arg_decl);
6975 /* Unite the abstract decl with its name. */
6976 TREE_OPERAND (last_expr, 0) = KEYWORD_ARG_NAME (arglist);
6977 push_parm_decl (build_tree_list
6978 (build_tree_list (arg_spec, arg_decl),
6979 build_tree_list (NULL_TREE, NULL_TREE)));
6981 /* Unhook: restore the abstract declarator. */
6982 TREE_OPERAND (last_expr, 0) = NULL_TREE;
6985 else
6986 push_parm_decl (build_tree_list
6987 (build_tree_list (arg_spec,
6988 KEYWORD_ARG_NAME (arglist)),
6989 build_tree_list (NULL_TREE, NULL_TREE)));
6991 arglist = TREE_CHAIN (arglist);
6993 while (arglist);
6996 if (METHOD_ADD_ARGS (method) != NULL_TREE
6997 && METHOD_ADD_ARGS (method) != objc_ellipsis_node)
6999 /* We have a variable length selector - in "prototype" format. */
7000 tree akey = TREE_PURPOSE (METHOD_ADD_ARGS (method));
7001 while (akey)
7003 /* This must be done prior to calling pushdecl. pushdecl is
7004 going to change our chain on us. */
7005 tree nextkey = TREE_CHAIN (akey);
7006 pushdecl (akey);
7007 akey = nextkey;
7012 static void
7013 warn_with_method (message, mtype, method)
7014 const char *message;
7015 int mtype;
7016 tree method;
7018 if (count_error (1) == 0)
7019 return;
7021 report_error_function (DECL_SOURCE_FILE (method));
7023 fprintf (stderr, "%s:%d: warning: ",
7024 DECL_SOURCE_FILE (method), DECL_SOURCE_LINE (method));
7025 memset (errbuf, 0, BUFSIZE);
7026 fprintf (stderr, "%s `%c%s'\n",
7027 message, mtype, gen_method_decl (method, errbuf));
7030 /* Return 1 if METHOD is consistent with PROTO. */
7032 static int
7033 comp_method_with_proto (method, proto)
7034 tree method, proto;
7036 static tree function_type = 0;
7038 /* Create a function_type node once. */
7039 if (!function_type)
7041 function_type = make_node (FUNCTION_TYPE);
7042 ggc_add_tree_root (&function_type, 1);
7045 /* Install argument types - normally set by build_function_type. */
7046 TYPE_ARG_TYPES (function_type) = get_arg_type_list (proto, METHOD_DEF, 0);
7048 /* install return type */
7049 TREE_TYPE (function_type) = groktypename (TREE_TYPE (proto));
7051 return comptypes (TREE_TYPE (METHOD_DEFINITION (method)), function_type);
7054 /* Return 1 if PROTO1 is consistent with PROTO2. */
7056 static int
7057 comp_proto_with_proto (proto0, proto1)
7058 tree proto0, proto1;
7060 static tree function_type[2];
7062 /* Create a couple function_type node's once. */
7063 if (!function_type[0])
7065 function_type[0] = make_node (FUNCTION_TYPE);
7066 function_type[1] = make_node (FUNCTION_TYPE);
7067 ggc_add_tree_root (function_type, 2);
7070 /* Install argument types; normally set by build_function_type. */
7071 TYPE_ARG_TYPES (function_type[0]) = get_arg_type_list (proto0, METHOD_REF, 0);
7072 TYPE_ARG_TYPES (function_type[1]) = get_arg_type_list (proto1, METHOD_REF, 0);
7074 /* Install return type. */
7075 TREE_TYPE (function_type[0]) = groktypename (TREE_TYPE (proto0));
7076 TREE_TYPE (function_type[1]) = groktypename (TREE_TYPE (proto1));
7078 return comptypes (function_type[0], function_type[1]);
7081 /* - Generate an identifier for the function. the format is "_n_cls",
7082 where 1 <= n <= nMethods, and cls is the name the implementation we
7083 are processing.
7084 - Install the return type from the method declaration.
7085 - If we have a prototype, check for type consistency. */
7087 static void
7088 really_start_method (method, parmlist)
7089 tree method, parmlist;
7091 tree sc_spec, ret_spec, ret_decl, decl_specs;
7092 tree method_decl, method_id;
7093 const char *sel_name, *class_name, *cat_name;
7094 char *buf;
7096 /* Synth the storage class & assemble the return type. */
7097 sc_spec = tree_cons (NULL_TREE, ridpointers[(int) RID_STATIC], NULL_TREE);
7098 ret_spec = TREE_PURPOSE (TREE_TYPE (method));
7099 decl_specs = chainon (sc_spec, ret_spec);
7101 sel_name = IDENTIFIER_POINTER (METHOD_SEL_NAME (method));
7102 class_name = IDENTIFIER_POINTER (CLASS_NAME (implementation_context));
7103 cat_name = ((TREE_CODE (implementation_context)
7104 == CLASS_IMPLEMENTATION_TYPE)
7105 ? NULL
7106 : IDENTIFIER_POINTER (CLASS_SUPER_NAME (implementation_context)));
7107 method_slot++;
7109 /* Make sure this is big enough for any plausible method label. */
7110 buf = (char *) alloca (50 + strlen (sel_name) + strlen (class_name)
7111 + (cat_name ? strlen (cat_name) : 0));
7113 OBJC_GEN_METHOD_LABEL (buf, TREE_CODE (method) == INSTANCE_METHOD_DECL,
7114 class_name, cat_name, sel_name, method_slot);
7116 method_id = get_identifier (buf);
7118 method_decl = build_nt (CALL_EXPR, method_id, parmlist, NULL_TREE);
7120 /* Check the declarator portion of the return type for the method. */
7121 if ((ret_decl = TREE_VALUE (TREE_TYPE (method))))
7123 /* Unite the complex decl (specified in the abstract decl) with the
7124 function decl just synthesized..(int *), (int (*)()), (int (*)[]). */
7125 tree save_expr = expr_last (ret_decl);
7127 TREE_OPERAND (save_expr, 0) = method_decl;
7128 method_decl = ret_decl;
7130 /* Fool the parser into thinking it is starting a function. */
7131 start_function (decl_specs, method_decl, NULL_TREE, NULL_TREE);
7133 /* Unhook: this has the effect of restoring the abstract declarator. */
7134 TREE_OPERAND (save_expr, 0) = NULL_TREE;
7137 else
7139 TREE_VALUE (TREE_TYPE (method)) = method_decl;
7141 /* Fool the parser into thinking it is starting a function. */
7142 start_function (decl_specs, method_decl, NULL_TREE, NULL_TREE);
7144 /* Unhook: this has the effect of restoring the abstract declarator. */
7145 TREE_VALUE (TREE_TYPE (method)) = NULL_TREE;
7148 METHOD_DEFINITION (method) = current_function_decl;
7150 if (implementation_template != implementation_context)
7152 tree proto;
7154 if (TREE_CODE (method) == INSTANCE_METHOD_DECL)
7155 proto = lookup_instance_method_static (implementation_template,
7156 METHOD_SEL_NAME (method));
7157 else
7158 proto = lookup_class_method_static (implementation_template,
7159 METHOD_SEL_NAME (method));
7161 if (proto && ! comp_method_with_proto (method, proto))
7163 char type = (TREE_CODE (method) == INSTANCE_METHOD_DECL ? '-' : '+');
7165 warn_with_method ("conflicting types for", type, method);
7166 warn_with_method ("previous declaration of", type, proto);
7171 /* The following routine is always called...this "architecture" is to
7172 accommodate "old-style" variable length selectors.
7174 - a:a b:b // prototype ; id c; id d; // old-style. */
7176 void
7177 continue_method_def ()
7179 tree parmlist;
7181 if (METHOD_ADD_ARGS (method_context) == objc_ellipsis_node)
7182 /* We have a `, ...' immediately following the selector. */
7183 parmlist = get_parm_info (0);
7184 else
7185 parmlist = get_parm_info (1); /* place a `void_at_end' */
7187 /* Set self_decl from the first argument...this global is used by
7188 build_ivar_reference calling build_indirect_ref. */
7189 self_decl = TREE_PURPOSE (parmlist);
7191 poplevel (0, 0, 0);
7192 really_start_method (method_context, parmlist);
7193 store_parm_decls ();
7196 /* Called by the parser, from the `pushlevel' production. */
7198 void
7199 add_objc_decls ()
7201 if (!UOBJC_SUPER_decl)
7203 UOBJC_SUPER_decl = start_decl (get_identifier (UTAG_SUPER),
7204 build_tree_list (NULL_TREE,
7205 objc_super_template),
7206 0, NULL_TREE, NULL_TREE);
7208 finish_decl (UOBJC_SUPER_decl, NULL_TREE, NULL_TREE);
7210 /* This prevents `unused variable' warnings when compiling with -Wall. */
7211 TREE_USED (UOBJC_SUPER_decl) = 1;
7212 DECL_ARTIFICIAL (UOBJC_SUPER_decl) = 1;
7216 /* _n_Method (id self, SEL sel, ...)
7218 struct objc_super _S;
7219 _msgSuper ((_S.self = self, _S.class = _cls, &_S), ...);
7220 } */
7222 tree
7223 get_super_receiver ()
7225 if (method_context)
7227 tree super_expr, super_expr_list;
7229 /* Set receiver to self. */
7230 super_expr = build_component_ref (UOBJC_SUPER_decl, self_id);
7231 super_expr = build_modify_expr (super_expr, NOP_EXPR, self_decl);
7232 super_expr_list = build_tree_list (NULL_TREE, super_expr);
7234 /* Set class to begin searching. */
7235 super_expr = build_component_ref (UOBJC_SUPER_decl,
7236 get_identifier ("class"));
7238 if (TREE_CODE (implementation_context) == CLASS_IMPLEMENTATION_TYPE)
7240 /* [_cls, __cls]Super are "pre-built" in
7241 synth_forward_declarations. */
7243 super_expr = build_modify_expr (super_expr, NOP_EXPR,
7244 ((TREE_CODE (method_context)
7245 == INSTANCE_METHOD_DECL)
7246 ? ucls_super_ref
7247 : uucls_super_ref));
7250 else
7251 /* We have a category. */
7253 tree super_name = CLASS_SUPER_NAME (implementation_template);
7254 tree super_class;
7256 if (!super_name)
7258 error ("no super class declared in interface for `%s'",
7259 IDENTIFIER_POINTER (CLASS_NAME (implementation_template)));
7260 return error_mark_node;
7263 if (flag_next_runtime)
7265 super_class = get_class_reference (super_name);
7266 if (TREE_CODE (method_context) == CLASS_METHOD_DECL)
7267 super_class
7268 = build_component_ref (build_indirect_ref (super_class, "->"),
7269 get_identifier ("isa"));
7271 else
7273 add_class_reference (super_name);
7274 super_class = (TREE_CODE (method_context) == INSTANCE_METHOD_DECL
7275 ? objc_get_class_decl : objc_get_meta_class_decl);
7276 assemble_external (super_class);
7277 super_class
7278 = build_function_call
7279 (super_class,
7280 build_tree_list
7281 (NULL_TREE,
7282 my_build_string (IDENTIFIER_LENGTH (super_name) + 1,
7283 IDENTIFIER_POINTER (super_name))));
7286 TREE_TYPE (super_class) = TREE_TYPE (ucls_super_ref);
7287 super_expr = build_modify_expr (super_expr, NOP_EXPR, super_class);
7290 chainon (super_expr_list, build_tree_list (NULL_TREE, super_expr));
7292 super_expr = build_unary_op (ADDR_EXPR, UOBJC_SUPER_decl, 0);
7293 chainon (super_expr_list, build_tree_list (NULL_TREE, super_expr));
7295 return build_compound_expr (super_expr_list);
7297 else
7299 error ("[super ...] must appear in a method context");
7300 return error_mark_node;
7304 static tree
7305 encode_method_def (func_decl)
7306 tree func_decl;
7308 tree parms;
7309 int stack_size;
7310 HOST_WIDE_INT max_parm_end = 0;
7311 char buffer[40];
7312 tree result;
7314 /* Return type. */
7315 encode_type (TREE_TYPE (TREE_TYPE (func_decl)),
7316 obstack_object_size (&util_obstack),
7317 OBJC_ENCODE_INLINE_DEFS);
7319 /* Stack size. */
7320 for (parms = DECL_ARGUMENTS (func_decl); parms;
7321 parms = TREE_CHAIN (parms))
7323 HOST_WIDE_INT parm_end = (forwarding_offset (parms)
7324 + int_size_in_bytes (TREE_TYPE (parms)));
7326 if (! offset_is_register && parm_end > max_parm_end)
7327 max_parm_end = parm_end;
7330 stack_size = max_parm_end - OBJC_FORWARDING_MIN_OFFSET;
7332 sprintf (buffer, "%d", stack_size);
7333 obstack_grow (&util_obstack, buffer, strlen (buffer));
7335 /* Argument types. */
7336 for (parms = DECL_ARGUMENTS (func_decl); parms;
7337 parms = TREE_CHAIN (parms))
7339 /* Type. */
7340 encode_type (TREE_TYPE (parms),
7341 obstack_object_size (&util_obstack),
7342 OBJC_ENCODE_INLINE_DEFS);
7344 /* Compute offset. */
7345 sprintf (buffer, "%d", forwarding_offset (parms));
7347 /* Indicate register. */
7348 if (offset_is_register)
7349 obstack_1grow (&util_obstack, '+');
7351 obstack_grow (&util_obstack, buffer, strlen (buffer));
7354 obstack_1grow (&util_obstack, 0);
7355 result = get_identifier (obstack_finish (&util_obstack));
7356 obstack_free (&util_obstack, util_firstobj);
7357 return result;
7360 static void
7361 objc_expand_function_end ()
7363 METHOD_ENCODING (method_context) = encode_method_def (current_function_decl);
7366 void
7367 finish_method_def ()
7369 lang_expand_function_end = objc_expand_function_end;
7370 finish_function (0);
7371 lang_expand_function_end = NULL;
7373 /* Required to implement _msgSuper. This must be done AFTER finish_function,
7374 since the optimizer may find "may be used before set" errors. */
7375 method_context = NULL_TREE;
7378 #if 0
7380 lang_report_error_function (decl)
7381 tree decl;
7383 if (method_context)
7385 fprintf (stderr, "In method `%s'\n",
7386 IDENTIFIER_POINTER (METHOD_SEL_NAME (method_context)));
7387 return 1;
7390 else
7391 return 0;
7393 #endif
7395 static int
7396 is_complex_decl (type)
7397 tree type;
7399 return (TREE_CODE (type) == ARRAY_TYPE
7400 || TREE_CODE (type) == FUNCTION_TYPE
7401 || (TREE_CODE (type) == POINTER_TYPE && ! IS_ID (type)));
7405 /* Code to convert a decl node into text for a declaration in C. */
7407 static char tmpbuf[256];
7409 static void
7410 adorn_decl (decl, str)
7411 tree decl;
7412 char *str;
7414 enum tree_code code = TREE_CODE (decl);
7416 if (code == ARRAY_REF)
7418 tree an_int_cst = TREE_OPERAND (decl, 1);
7420 if (an_int_cst && TREE_CODE (an_int_cst) == INTEGER_CST)
7421 sprintf (str + strlen (str), "[%ld]",
7422 (long) TREE_INT_CST_LOW (an_int_cst));
7423 else
7424 strcat (str, "[]");
7427 else if (code == ARRAY_TYPE)
7429 tree an_int_cst = TYPE_SIZE (decl);
7430 tree array_of = TREE_TYPE (decl);
7432 if (an_int_cst && TREE_CODE (an_int_cst) == INTEGER_TYPE)
7433 sprintf (str + strlen (str), "[%ld]",
7434 (long) (TREE_INT_CST_LOW (an_int_cst)
7435 / TREE_INT_CST_LOW (TYPE_SIZE (array_of))));
7436 else
7437 strcat (str, "[]");
7440 else if (code == CALL_EXPR)
7442 tree chain = TREE_PURPOSE (TREE_OPERAND (decl, 1));
7444 strcat (str, "(");
7445 while (chain)
7447 gen_declaration (chain, str);
7448 chain = TREE_CHAIN (chain);
7449 if (chain)
7450 strcat (str, ", ");
7452 strcat (str, ")");
7455 else if (code == FUNCTION_TYPE)
7457 tree chain = TYPE_ARG_TYPES (decl);
7459 strcat (str, "(");
7460 while (chain && TREE_VALUE (chain) != void_type_node)
7462 gen_declaration (TREE_VALUE (chain), str);
7463 chain = TREE_CHAIN (chain);
7464 if (chain && TREE_VALUE (chain) != void_type_node)
7465 strcat (str, ", ");
7467 strcat (str, ")");
7470 else if (code == INDIRECT_REF)
7472 strcpy (tmpbuf, "*");
7473 if (TREE_TYPE (decl) && TREE_CODE (TREE_TYPE (decl)) == TREE_LIST)
7475 tree chain;
7477 for (chain = nreverse (copy_list (TREE_TYPE (decl)));
7478 chain;
7479 chain = TREE_CHAIN (chain))
7481 if (TREE_CODE (TREE_VALUE (chain)) == IDENTIFIER_NODE)
7483 strcat (tmpbuf, " ");
7484 strcat (tmpbuf, IDENTIFIER_POINTER (TREE_VALUE (chain)));
7487 if (str[0])
7488 strcat (tmpbuf, " ");
7490 strcat (tmpbuf, str);
7491 strcpy (str, tmpbuf);
7494 else if (code == POINTER_TYPE)
7496 strcpy (tmpbuf, "*");
7497 if (TREE_READONLY (decl) || TYPE_VOLATILE (decl))
7499 if (TREE_READONLY (decl))
7500 strcat (tmpbuf, " const");
7501 if (TYPE_VOLATILE (decl))
7502 strcat (tmpbuf, " volatile");
7503 if (str[0])
7504 strcat (tmpbuf, " ");
7506 strcat (tmpbuf, str);
7507 strcpy (str, tmpbuf);
7511 static char *
7512 gen_declarator (decl, buf, name)
7513 tree decl;
7514 char *buf;
7515 const char *name;
7517 if (decl)
7519 enum tree_code code = TREE_CODE (decl);
7520 char *str;
7521 tree op;
7522 int wrap = 0;
7524 switch (code)
7526 case ARRAY_REF:
7527 case INDIRECT_REF:
7528 case CALL_EXPR:
7529 op = TREE_OPERAND (decl, 0);
7531 /* We have a pointer to a function or array...(*)(), (*)[] */
7532 if ((code == ARRAY_REF || code == CALL_EXPR)
7533 && op && TREE_CODE (op) == INDIRECT_REF)
7534 wrap = 1;
7536 str = gen_declarator (op, buf, name);
7538 if (wrap)
7540 strcpy (tmpbuf, "(");
7541 strcat (tmpbuf, str);
7542 strcat (tmpbuf, ")");
7543 strcpy (str, tmpbuf);
7546 adorn_decl (decl, str);
7547 break;
7549 case ARRAY_TYPE:
7550 case FUNCTION_TYPE:
7551 case POINTER_TYPE:
7552 strcpy (buf, name);
7553 str = buf;
7555 /* This clause is done iteratively rather than recursively. */
7558 op = (is_complex_decl (TREE_TYPE (decl))
7559 ? TREE_TYPE (decl) : NULL_TREE);
7561 adorn_decl (decl, str);
7563 /* We have a pointer to a function or array...(*)(), (*)[] */
7564 if (code == POINTER_TYPE
7565 && op && (TREE_CODE (op) == FUNCTION_TYPE
7566 || TREE_CODE (op) == ARRAY_TYPE))
7568 strcpy (tmpbuf, "(");
7569 strcat (tmpbuf, str);
7570 strcat (tmpbuf, ")");
7571 strcpy (str, tmpbuf);
7574 decl = (is_complex_decl (TREE_TYPE (decl))
7575 ? TREE_TYPE (decl) : NULL_TREE);
7578 while (decl && (code = TREE_CODE (decl)))
7581 break;
7583 case IDENTIFIER_NODE:
7584 /* Will only happen if we are processing a "raw" expr-decl. */
7585 strcpy (buf, IDENTIFIER_POINTER (decl));
7586 return buf;
7588 default:
7589 abort ();
7592 return str;
7595 else
7596 /* We have an abstract declarator or a _DECL node. */
7598 strcpy (buf, name);
7599 return buf;
7603 static void
7604 gen_declspecs (declspecs, buf, raw)
7605 tree declspecs;
7606 char *buf;
7607 int raw;
7609 if (raw)
7611 tree chain;
7613 for (chain = nreverse (copy_list (declspecs));
7614 chain; chain = TREE_CHAIN (chain))
7616 tree aspec = TREE_VALUE (chain);
7618 if (TREE_CODE (aspec) == IDENTIFIER_NODE)
7619 strcat (buf, IDENTIFIER_POINTER (aspec));
7620 else if (TREE_CODE (aspec) == RECORD_TYPE)
7622 if (TYPE_NAME (aspec))
7624 tree protocol_list = TYPE_PROTOCOL_LIST (aspec);
7626 if (! TREE_STATIC_TEMPLATE (aspec))
7627 strcat (buf, "struct ");
7628 strcat (buf, IDENTIFIER_POINTER (TYPE_NAME (aspec)));
7630 /* NEW!!! */
7631 if (protocol_list)
7633 tree chain = protocol_list;
7635 strcat (buf, " <");
7636 while (chain)
7638 strcat (buf,
7639 IDENTIFIER_POINTER
7640 (PROTOCOL_NAME (TREE_VALUE (chain))));
7641 chain = TREE_CHAIN (chain);
7642 if (chain)
7643 strcat (buf, ", ");
7645 strcat (buf, ">");
7649 else
7650 strcat (buf, "untagged struct");
7653 else if (TREE_CODE (aspec) == UNION_TYPE)
7655 if (TYPE_NAME (aspec))
7657 if (! TREE_STATIC_TEMPLATE (aspec))
7658 strcat (buf, "union ");
7659 strcat (buf, IDENTIFIER_POINTER (TYPE_NAME (aspec)));
7661 else
7662 strcat (buf, "untagged union");
7665 else if (TREE_CODE (aspec) == ENUMERAL_TYPE)
7667 if (TYPE_NAME (aspec))
7669 if (! TREE_STATIC_TEMPLATE (aspec))
7670 strcat (buf, "enum ");
7671 strcat (buf, IDENTIFIER_POINTER (TYPE_NAME (aspec)));
7673 else
7674 strcat (buf, "untagged enum");
7677 else if (TREE_CODE (aspec) == TYPE_DECL && DECL_NAME (aspec))
7678 strcat (buf, IDENTIFIER_POINTER (DECL_NAME (aspec)));
7680 else if (IS_ID (aspec))
7682 tree protocol_list = TYPE_PROTOCOL_LIST (aspec);
7684 strcat (buf, "id");
7685 if (protocol_list)
7687 tree chain = protocol_list;
7689 strcat (buf, " <");
7690 while (chain)
7692 strcat (buf,
7693 IDENTIFIER_POINTER
7694 (PROTOCOL_NAME (TREE_VALUE (chain))));
7695 chain = TREE_CHAIN (chain);
7696 if (chain)
7697 strcat (buf, ", ");
7699 strcat (buf, ">");
7702 if (TREE_CHAIN (chain))
7703 strcat (buf, " ");
7706 else
7708 /* Type qualifiers. */
7709 if (TREE_READONLY (declspecs))
7710 strcat (buf, "const ");
7711 if (TYPE_VOLATILE (declspecs))
7712 strcat (buf, "volatile ");
7714 switch (TREE_CODE (declspecs))
7716 /* Type specifiers. */
7718 case INTEGER_TYPE:
7719 declspecs = TYPE_MAIN_VARIANT (declspecs);
7721 /* Signed integer types. */
7723 if (declspecs == short_integer_type_node)
7724 strcat (buf, "short int ");
7725 else if (declspecs == integer_type_node)
7726 strcat (buf, "int ");
7727 else if (declspecs == long_integer_type_node)
7728 strcat (buf, "long int ");
7729 else if (declspecs == long_long_integer_type_node)
7730 strcat (buf, "long long int ");
7731 else if (declspecs == signed_char_type_node
7732 || declspecs == char_type_node)
7733 strcat (buf, "char ");
7735 /* Unsigned integer types. */
7737 else if (declspecs == short_unsigned_type_node)
7738 strcat (buf, "unsigned short ");
7739 else if (declspecs == unsigned_type_node)
7740 strcat (buf, "unsigned int ");
7741 else if (declspecs == long_unsigned_type_node)
7742 strcat (buf, "unsigned long ");
7743 else if (declspecs == long_long_unsigned_type_node)
7744 strcat (buf, "unsigned long long ");
7745 else if (declspecs == unsigned_char_type_node)
7746 strcat (buf, "unsigned char ");
7747 break;
7749 case REAL_TYPE:
7750 declspecs = TYPE_MAIN_VARIANT (declspecs);
7752 if (declspecs == float_type_node)
7753 strcat (buf, "float ");
7754 else if (declspecs == double_type_node)
7755 strcat (buf, "double ");
7756 else if (declspecs == long_double_type_node)
7757 strcat (buf, "long double ");
7758 break;
7760 case RECORD_TYPE:
7761 if (TYPE_NAME (declspecs)
7762 && TREE_CODE (TYPE_NAME (declspecs)) == IDENTIFIER_NODE)
7764 tree protocol_list = TYPE_PROTOCOL_LIST (declspecs);
7766 if (! TREE_STATIC_TEMPLATE (declspecs))
7767 strcat (buf, "struct ");
7768 strcat (buf, IDENTIFIER_POINTER (TYPE_NAME (declspecs)));
7770 if (protocol_list)
7772 tree chain = protocol_list;
7774 strcat (buf, " <");
7775 while (chain)
7777 strcat (buf,
7778 IDENTIFIER_POINTER
7779 (PROTOCOL_NAME (TREE_VALUE (chain))));
7780 chain = TREE_CHAIN (chain);
7781 if (chain)
7782 strcat (buf, ", ");
7784 strcat (buf, ">");
7788 else
7789 strcat (buf, "untagged struct");
7791 strcat (buf, " ");
7792 break;
7794 case UNION_TYPE:
7795 if (TYPE_NAME (declspecs)
7796 && TREE_CODE (TYPE_NAME (declspecs)) == IDENTIFIER_NODE)
7798 strcat (buf, "union ");
7799 strcat (buf, IDENTIFIER_POINTER (TYPE_NAME (declspecs)));
7800 strcat (buf, " ");
7803 else
7804 strcat (buf, "untagged union ");
7805 break;
7807 case ENUMERAL_TYPE:
7808 if (TYPE_NAME (declspecs)
7809 && TREE_CODE (TYPE_NAME (declspecs)) == IDENTIFIER_NODE)
7811 strcat (buf, "enum ");
7812 strcat (buf, IDENTIFIER_POINTER (TYPE_NAME (declspecs)));
7813 strcat (buf, " ");
7816 else
7817 strcat (buf, "untagged enum ");
7818 break;
7820 case VOID_TYPE:
7821 strcat (buf, "void ");
7822 break;
7824 case POINTER_TYPE:
7826 tree protocol_list = TYPE_PROTOCOL_LIST (declspecs);
7828 strcat (buf, "id");
7829 if (protocol_list)
7831 tree chain = protocol_list;
7833 strcat (buf, " <");
7834 while (chain)
7836 strcat (buf,
7837 IDENTIFIER_POINTER
7838 (PROTOCOL_NAME (TREE_VALUE (chain))));
7839 chain = TREE_CHAIN (chain);
7840 if (chain)
7841 strcat (buf, ", ");
7844 strcat (buf, ">");
7847 break;
7849 default:
7850 break;
7855 static char *
7856 gen_declaration (atype_or_adecl, buf)
7857 tree atype_or_adecl;
7858 char *buf;
7860 char declbuf[256];
7862 if (TREE_CODE (atype_or_adecl) == TREE_LIST)
7864 tree declspecs; /* "identifier_node", "record_type" */
7865 tree declarator; /* "array_ref", "indirect_ref", "call_expr"... */
7867 /* We have a "raw", abstract declarator (typename). */
7868 declarator = TREE_VALUE (atype_or_adecl);
7869 declspecs = TREE_PURPOSE (atype_or_adecl);
7871 gen_declspecs (declspecs, buf, 1);
7872 if (declarator)
7874 strcat (buf, " ");
7875 strcat (buf, gen_declarator (declarator, declbuf, ""));
7879 else
7881 tree atype;
7882 tree declspecs; /* "integer_type", "real_type", "record_type"... */
7883 tree declarator; /* "array_type", "function_type", "pointer_type". */
7885 if (TREE_CODE (atype_or_adecl) == FIELD_DECL
7886 || TREE_CODE (atype_or_adecl) == PARM_DECL
7887 || TREE_CODE (atype_or_adecl) == FUNCTION_DECL)
7888 atype = TREE_TYPE (atype_or_adecl);
7889 else
7890 /* Assume we have a *_type node. */
7891 atype = atype_or_adecl;
7893 if (is_complex_decl (atype))
7895 tree chain;
7897 /* Get the declaration specifier; it is at the end of the list. */
7898 declarator = chain = atype;
7900 chain = TREE_TYPE (chain); /* not TREE_CHAIN (chain); */
7901 while (is_complex_decl (chain));
7902 declspecs = chain;
7905 else
7907 declspecs = atype;
7908 declarator = NULL_TREE;
7911 gen_declspecs (declspecs, buf, 0);
7913 if (TREE_CODE (atype_or_adecl) == FIELD_DECL
7914 || TREE_CODE (atype_or_adecl) == PARM_DECL
7915 || TREE_CODE (atype_or_adecl) == FUNCTION_DECL)
7917 const char *decl_name =
7918 (DECL_NAME (atype_or_adecl)
7919 ? IDENTIFIER_POINTER (DECL_NAME (atype_or_adecl)) : "");
7921 if (declarator)
7923 strcat (buf, " ");
7924 strcat (buf, gen_declarator (declarator, declbuf, decl_name));
7927 else if (decl_name[0])
7929 strcat (buf, " ");
7930 strcat (buf, decl_name);
7933 else if (declarator)
7935 strcat (buf, " ");
7936 strcat (buf, gen_declarator (declarator, declbuf, ""));
7940 return buf;
7943 #define RAW_TYPESPEC(meth) (TREE_VALUE (TREE_PURPOSE (TREE_TYPE (meth))))
7945 static char *
7946 gen_method_decl (method, buf)
7947 tree method;
7948 char *buf;
7950 tree chain;
7952 if (RAW_TYPESPEC (method) != objc_object_reference)
7954 strcpy (buf, "(");
7955 gen_declaration (TREE_TYPE (method), buf);
7956 strcat (buf, ")");
7959 chain = METHOD_SEL_ARGS (method);
7960 if (chain)
7962 /* We have a chain of keyword_decls. */
7965 if (KEYWORD_KEY_NAME (chain))
7966 strcat (buf, IDENTIFIER_POINTER (KEYWORD_KEY_NAME (chain)));
7968 strcat (buf, ":");
7969 if (RAW_TYPESPEC (chain) != objc_object_reference)
7971 strcat (buf, "(");
7972 gen_declaration (TREE_TYPE (chain), buf);
7973 strcat (buf, ")");
7976 strcat (buf, IDENTIFIER_POINTER (KEYWORD_ARG_NAME (chain)));
7977 if ((chain = TREE_CHAIN (chain)))
7978 strcat (buf, " ");
7980 while (chain);
7982 if (METHOD_ADD_ARGS (method) == objc_ellipsis_node)
7983 strcat (buf, ", ...");
7984 else if (METHOD_ADD_ARGS (method))
7986 /* We have a tree list node as generate by get_parm_info. */
7987 chain = TREE_PURPOSE (METHOD_ADD_ARGS (method));
7989 /* Know we have a chain of parm_decls. */
7990 while (chain)
7992 strcat (buf, ", ");
7993 gen_declaration (chain, buf);
7994 chain = TREE_CHAIN (chain);
7999 else
8000 /* We have a unary selector. */
8001 strcat (buf, IDENTIFIER_POINTER (METHOD_SEL_NAME (method)));
8003 return buf;
8006 /* Debug info. */
8008 static void
8009 dump_interface (fp, chain)
8010 FILE *fp;
8011 tree chain;
8013 char *buf = (char *)xmalloc (256);
8014 const char *my_name = IDENTIFIER_POINTER (CLASS_NAME (chain));
8015 tree ivar_decls = CLASS_RAW_IVARS (chain);
8016 tree nst_methods = CLASS_NST_METHODS (chain);
8017 tree cls_methods = CLASS_CLS_METHODS (chain);
8019 fprintf (fp, "\n@interface %s", my_name);
8021 if (CLASS_SUPER_NAME (chain))
8023 const char *super_name = IDENTIFIER_POINTER (CLASS_SUPER_NAME (chain));
8024 fprintf (fp, " : %s\n", super_name);
8026 else
8027 fprintf (fp, "\n");
8029 if (ivar_decls)
8031 fprintf (fp, "{\n");
8034 memset (buf, 0, 256);
8035 fprintf (fp, "\t%s;\n", gen_declaration (ivar_decls, buf));
8036 ivar_decls = TREE_CHAIN (ivar_decls);
8038 while (ivar_decls);
8039 fprintf (fp, "}\n");
8042 while (nst_methods)
8044 memset (buf, 0, 256);
8045 fprintf (fp, "- %s;\n", gen_method_decl (nst_methods, buf));
8046 nst_methods = TREE_CHAIN (nst_methods);
8049 while (cls_methods)
8051 memset (buf, 0, 256);
8052 fprintf (fp, "+ %s;\n", gen_method_decl (cls_methods, buf));
8053 cls_methods = TREE_CHAIN (cls_methods);
8055 fprintf (fp, "\n@end");
8058 /* Demangle function for Objective-C */
8059 static const char *
8060 objc_demangle (mangled)
8061 const char *mangled;
8063 char *demangled, *cp;
8065 if (mangled[0] == '_' &&
8066 (mangled[1] == 'i' || mangled[1] == 'c') &&
8067 mangled[2] == '_')
8069 cp = demangled = xmalloc(strlen(mangled) + 2);
8070 if (mangled[1] == 'i')
8071 *cp++ = '-'; /* for instance method */
8072 else
8073 *cp++ = '+'; /* for class method */
8074 *cp++ = '['; /* opening left brace */
8075 strcpy(cp, mangled+3); /* tack on the rest of the mangled name */
8076 while (*cp && *cp == '_')
8077 cp++; /* skip any initial underbars in class name */
8078 cp = strchr(cp, '_'); /* find first non-initial underbar */
8079 if (cp == NULL)
8081 free(demangled); /* not mangled name */
8082 return mangled;
8084 if (cp[1] == '_') /* easy case: no category name */
8086 *cp++ = ' '; /* replace two '_' with one ' ' */
8087 strcpy(cp, mangled + (cp - demangled) + 2);
8089 else
8091 *cp++ = '('; /* less easy case: category name */
8092 cp = strchr(cp, '_');
8093 if (cp == 0)
8095 free(demangled); /* not mangled name */
8096 return mangled;
8098 *cp++ = ')';
8099 *cp++ = ' '; /* overwriting 1st char of method name... */
8100 strcpy(cp, mangled + (cp - demangled)); /* get it back */
8102 while (*cp && *cp == '_')
8103 cp++; /* skip any initial underbars in method name */
8104 for (; *cp; cp++)
8105 if (*cp == '_')
8106 *cp = ':'; /* replace remaining '_' with ':' */
8107 *cp++ = ']'; /* closing right brace */
8108 *cp++ = 0; /* string terminator */
8109 return demangled;
8111 else
8112 return mangled; /* not an objc mangled name */
8115 static const char *
8116 objc_printable_name (decl, kind)
8117 tree decl;
8118 int kind ATTRIBUTE_UNUSED;
8120 return objc_demangle (IDENTIFIER_POINTER (DECL_NAME (decl)));
8123 static void
8124 init_objc ()
8126 /* Add the special tree codes of Objective C to the tables. */
8128 #define LAST_CODE LAST_C_TREE_CODE
8130 gcc_obstack_init (&util_obstack);
8131 util_firstobj = (char *) obstack_finish (&util_obstack);
8133 memcpy (tree_code_type + (int) LAST_CODE,
8134 objc_tree_code_type,
8135 (int) LAST_OBJC_TREE_CODE - (int) LAST_CODE);
8136 memcpy (tree_code_length + (int) LAST_CODE,
8137 objc_tree_code_length,
8138 (((int) LAST_OBJC_TREE_CODE - (int) LAST_CODE) * sizeof (int)));
8139 memcpy (tree_code_name + (int) LAST_CODE,
8140 objc_tree_code_name,
8141 (((int) LAST_OBJC_TREE_CODE - (int) LAST_CODE) * sizeof (char *)));
8143 errbuf = (char *)xmalloc (BUFSIZE);
8144 hash_init ();
8145 synth_module_prologue ();
8147 /* Change the default error function */
8148 decl_printable_name = objc_printable_name;
8149 lang_expand_expr = c_expand_expr;
8150 lang_expand_decl_stmt = c_expand_decl_stmt;
8153 static void
8154 finish_objc ()
8156 struct imp_entry *impent;
8157 tree chain;
8158 /* The internally generated initializers appear to have missing braces.
8159 Don't warn about this. */
8160 int save_warn_missing_braces = warn_missing_braces;
8161 warn_missing_braces = 0;
8163 generate_forward_declaration_to_string_table ();
8165 #ifdef OBJC_PROLOGUE
8166 OBJC_PROLOGUE;
8167 #endif
8169 /* Process the static instances here because initialization of objc_symtab
8170 depends on them. */
8171 if (objc_static_instances)
8172 generate_static_references ();
8174 if (implementation_context || class_names_chain
8175 || meth_var_names_chain || meth_var_types_chain || sel_ref_chain)
8176 generate_objc_symtab_decl ();
8178 for (impent = imp_list; impent; impent = impent->next)
8180 implementation_context = impent->imp_context;
8181 implementation_template = impent->imp_template;
8183 UOBJC_CLASS_decl = impent->class_decl;
8184 UOBJC_METACLASS_decl = impent->meta_decl;
8186 if (TREE_CODE (implementation_context) == CLASS_IMPLEMENTATION_TYPE)
8188 /* all of the following reference the string pool... */
8189 generate_ivar_lists ();
8190 generate_dispatch_tables ();
8191 generate_shared_structures ();
8193 else
8195 generate_dispatch_tables ();
8196 generate_category (implementation_context);
8200 /* If we are using an array of selectors, we must always
8201 finish up the array decl even if no selectors were used. */
8202 if (! flag_next_runtime || sel_ref_chain)
8203 build_selector_translation_table ();
8205 if (protocol_chain)
8206 generate_protocols ();
8208 if (implementation_context || class_names_chain || objc_static_instances
8209 || meth_var_names_chain || meth_var_types_chain || sel_ref_chain)
8211 /* Arrange for Objc data structures to be initialized at run time. */
8212 const char *init_name = build_module_descriptor ();
8213 if (init_name)
8214 assemble_constructor (init_name);
8217 /* Dump the class references. This forces the appropriate classes
8218 to be linked into the executable image, preserving unix archive
8219 semantics. This can be removed when we move to a more dynamically
8220 linked environment. */
8222 for (chain = cls_ref_chain; chain; chain = TREE_CHAIN (chain))
8224 handle_class_ref (chain);
8225 if (TREE_PURPOSE (chain))
8226 generate_classref_translation_entry (chain);
8229 for (impent = imp_list; impent; impent = impent->next)
8230 handle_impent (impent);
8232 /* Dump the string table last. */
8234 generate_strings ();
8236 if (flag_gen_declaration)
8238 add_class (implementation_context);
8239 dump_interface (gen_declaration_file, implementation_context);
8242 if (warn_selector)
8244 int slot;
8245 hash hsh;
8247 /* Run through the selector hash tables and print a warning for any
8248 selector which has multiple methods. */
8250 for (slot = 0; slot < SIZEHASHTABLE; slot++)
8251 for (hsh = cls_method_hash_list[slot]; hsh; hsh = hsh->next)
8252 if (hsh->list)
8254 tree meth = hsh->key;
8255 char type = (TREE_CODE (meth) == INSTANCE_METHOD_DECL
8256 ? '-' : '+');
8257 attr loop;
8259 warning ("potential selector conflict for method `%s'",
8260 IDENTIFIER_POINTER (METHOD_SEL_NAME (meth)));
8261 warn_with_method ("found", type, meth);
8262 for (loop = hsh->list; loop; loop = loop->next)
8263 warn_with_method ("found", type, loop->value);
8266 for (slot = 0; slot < SIZEHASHTABLE; slot++)
8267 for (hsh = nst_method_hash_list[slot]; hsh; hsh = hsh->next)
8268 if (hsh->list)
8270 tree meth = hsh->key;
8271 char type = (TREE_CODE (meth) == INSTANCE_METHOD_DECL
8272 ? '-' : '+');
8273 attr loop;
8275 warning ("potential selector conflict for method `%s'",
8276 IDENTIFIER_POINTER (METHOD_SEL_NAME (meth)));
8277 warn_with_method ("found", type, meth);
8278 for (loop = hsh->list; loop; loop = loop->next)
8279 warn_with_method ("found", type, loop->value);
8283 warn_missing_braces = save_warn_missing_braces;
8286 /* Subroutines of finish_objc. */
8288 static void
8289 generate_classref_translation_entry (chain)
8290 tree chain;
8292 tree expr, name, decl_specs, decl, sc_spec;
8293 tree type;
8295 type = TREE_TYPE (TREE_PURPOSE (chain));
8297 expr = add_objc_string (TREE_VALUE (chain), class_names);
8298 expr = build_c_cast (type, expr); /* cast! */
8300 name = DECL_NAME (TREE_PURPOSE (chain));
8302 sc_spec = build_tree_list (NULL_TREE, ridpointers[(int) RID_STATIC]);
8304 /* static struct objc_class * _OBJC_CLASS_REFERENCES_n = ...; */
8305 decl_specs = tree_cons (NULL_TREE, type, sc_spec);
8307 /* The decl that is returned from start_decl is the one that we
8308 forward declared in build_class_reference. */
8309 decl = start_decl (name, decl_specs, 1, NULL_TREE, NULL_TREE);
8310 finish_decl (decl, expr, NULL_TREE);
8311 return;
8314 static void
8315 handle_class_ref (chain)
8316 tree chain;
8318 const char *name = IDENTIFIER_POINTER (TREE_VALUE (chain));
8319 if (! flag_next_runtime)
8321 tree decl;
8322 char *string = (char *) alloca (strlen (name) + 30);
8323 tree exp;
8325 sprintf (string, "%sobjc_class_name_%s",
8326 (flag_next_runtime ? "." : "__"), name);
8328 /* Make a decl for this name, so we can use its address in a tree. */
8329 decl = build_decl (VAR_DECL, get_identifier (string), char_type_node);
8330 DECL_EXTERNAL (decl) = 1;
8331 TREE_PUBLIC (decl) = 1;
8333 pushdecl (decl);
8334 rest_of_decl_compilation (decl, 0, 0, 0);
8336 /* Make following constant read-only (why not)? */
8337 readonly_data_section ();
8339 exp = build1 (ADDR_EXPR, string_type_node, decl);
8341 /* Align the section properly. */
8342 assemble_constant_align (exp);
8344 /* Inform the assembler about this new external thing. */
8345 assemble_external (decl);
8347 /* Output a constant to reference this address. */
8348 output_constant (exp, int_size_in_bytes (string_type_node));
8350 else
8352 /* This overreliance on our assembler (i.e. lack of portability)
8353 should be dealt with at some point. The GNU strategy (above)
8354 won't work either, but it is a start. */
8355 char *string = (char *) alloca (strlen (name) + 30);
8356 sprintf (string, ".reference .objc_class_name_%s", name);
8357 assemble_asm (my_build_string (strlen (string) + 1, string));
8361 static void
8362 handle_impent (impent)
8363 struct imp_entry *impent;
8365 implementation_context = impent->imp_context;
8366 implementation_template = impent->imp_template;
8368 if (TREE_CODE (impent->imp_context) == CLASS_IMPLEMENTATION_TYPE)
8370 const char *class_name =
8371 IDENTIFIER_POINTER (CLASS_NAME (impent->imp_context));
8372 char *string = (char *) alloca (strlen (class_name) + 30);
8374 if (flag_next_runtime)
8376 /* Grossly unportable.
8377 People should know better than to assume
8378 such things about assembler syntax! */
8379 sprintf (string, ".objc_class_name_%s=0", class_name);
8380 assemble_asm (my_build_string (strlen (string) + 1, string));
8382 sprintf (string, ".globl .objc_class_name_%s", class_name);
8383 assemble_asm (my_build_string (strlen (string) + 1, string));
8386 else
8388 sprintf (string, "%sobjc_class_name_%s",
8389 (flag_next_runtime ? "." : "__"), class_name);
8390 assemble_global (string);
8391 assemble_label (string);
8395 else if (TREE_CODE (impent->imp_context) == CATEGORY_IMPLEMENTATION_TYPE)
8397 const char *class_name =
8398 IDENTIFIER_POINTER (CLASS_NAME (impent->imp_context));
8399 const char *class_super_name =
8400 IDENTIFIER_POINTER (CLASS_SUPER_NAME (impent->imp_context));
8401 char *string = (char *) alloca (strlen (class_name)
8402 + strlen (class_super_name) + 30);
8404 /* Do the same for categories. Even though no references to these
8405 symbols are generated automatically by the compiler, it gives
8406 you a handle to pull them into an archive by hand. */
8407 if (flag_next_runtime)
8409 /* Grossly unportable. */
8410 sprintf (string, ".objc_category_name_%s_%s=0",
8411 class_name, class_super_name);
8412 assemble_asm (my_build_string (strlen (string) + 1, string));
8414 sprintf (string, ".globl .objc_category_name_%s_%s",
8415 class_name, class_super_name);
8416 assemble_asm (my_build_string (strlen (string) + 1, string));
8419 else
8421 sprintf (string, "%sobjc_category_name_%s_%s",
8422 (flag_next_runtime ? "." : "__"),
8423 class_name, class_super_name);
8424 assemble_global (string);
8425 assemble_label (string);
8430 #ifdef DEBUG
8432 static void
8433 objc_debug (fp)
8434 FILE *fp;
8436 char *buf = (char *)xmalloc (256);
8438 { /* dump function prototypes */
8439 tree loop = UOBJC_MODULES_decl;
8441 fprintf (fp, "\n\nfunction prototypes:\n");
8442 while (loop)
8444 if (TREE_CODE (loop) == FUNCTION_DECL && DECL_INITIAL (loop))
8446 /* We have a function definition: generate prototype. */
8447 memset (errbuf, 0, BUFSIZE);
8448 gen_declaration (loop, errbuf);
8449 fprintf (fp, "%s;\n", errbuf);
8451 loop = TREE_CHAIN (loop);
8455 /* Dump global chains. */
8456 tree loop;
8457 int i, index = 0, offset = 0;
8458 hash hashlist;
8460 for (i = 0; i < SIZEHASHTABLE; i++)
8462 if (hashlist = nst_method_hash_list[i])
8464 fprintf (fp, "\n\nnst_method_hash_list[%d]:\n", i);
8467 memset (buf, 0, 256);
8468 fprintf (fp, "-%s;\n", gen_method_decl (hashlist->key, buf));
8469 hashlist = hashlist->next;
8471 while (hashlist);
8475 for (i = 0; i < SIZEHASHTABLE; i++)
8477 if (hashlist = cls_method_hash_list[i])
8479 fprintf (fp, "\n\ncls_method_hash_list[%d]:\n", i);
8482 memset (buf, 0, 256);
8483 fprintf (fp, "-%s;\n", gen_method_decl (hashlist->key, buf));
8484 hashlist = hashlist->next;
8486 while (hashlist);
8490 fprintf (fp, "\nsel_refdef_chain:\n");
8491 for (loop = sel_refdef_chain; loop; loop = TREE_CHAIN (loop))
8493 fprintf (fp, "(index: %4d offset: %4d) %s\n", index, offset,
8494 IDENTIFIER_POINTER (TREE_VALUE (loop)));
8495 index++;
8496 /* add one for the '\0' character */
8497 offset += IDENTIFIER_LENGTH (TREE_VALUE (loop)) + 1;
8500 fprintf (fp, "\n (max_selector_index: %4d.\n", max_selector_index);
8503 #endif
8505 void
8506 print_lang_statistics ()
8510 static void
8511 ggc_mark_imp_list (arg)
8512 void *arg;
8514 struct imp_entry *impent;
8516 for (impent = *(struct imp_entry **)arg; impent; impent = impent->next)
8518 ggc_mark_tree (impent->imp_context);
8519 ggc_mark_tree (impent->imp_template);
8520 ggc_mark_tree (impent->class_decl);
8521 ggc_mark_tree (impent->meta_decl);
8525 static void
8526 ggc_mark_hash_table (arg)
8527 void *arg;
8529 hash *hash_table = *(hash **)arg;
8530 hash hst;
8531 attr list;
8532 int i;
8534 if (hash_table == NULL)
8535 return;
8536 for (i = 0; i < SIZEHASHTABLE; i++)
8537 for (hst = hash_table [i]; hst; hst = hst->next)
8539 ggc_mark_tree (hst->key);
8540 for (list = hst->list; list; list = list->next)
8541 ggc_mark_tree (list->value);
8545 /* Add GC roots for variables local to this file. */
8546 static void
8547 objc_act_parse_init ()
8549 ggc_add_tree_root (&objc_ellipsis_node, 1);
8550 ggc_add_tree_root (objc_global_trees, OCTI_MAX);
8551 ggc_add_root (&imp_list, 1, sizeof imp_list, ggc_mark_imp_list);
8552 ggc_add_root (&nst_method_hash_list, 1, sizeof nst_method_hash_list, ggc_mark_hash_table);
8553 ggc_add_root (&cls_method_hash_list, 1, sizeof cls_method_hash_list, ggc_mark_hash_table);
8556 /* Look up ID as an instance variable. */
8557 tree
8558 lookup_objc_ivar (id)
8559 tree id;
8561 tree decl;
8563 if (objc_receiver_context && !strcmp (IDENTIFIER_POINTER (id), "super"))
8564 /* we have a message to super */
8565 return get_super_receiver ();
8566 else if (objc_method_context && (decl = is_ivar (objc_ivar_chain, id)))
8568 if (is_private (decl))
8569 return error_mark_node;
8570 else
8571 return build_ivar_reference (id);
8573 else
8574 return 0;
8577 /* Parser callbacks. */
8578 void
8579 forget_protocol_qualifiers ()
8581 C_IS_RESERVED_WORD (ridpointers[(int) RID_IN]) = 0;
8582 C_IS_RESERVED_WORD (ridpointers[(int) RID_OUT]) = 0;
8583 C_IS_RESERVED_WORD (ridpointers[(int) RID_INOUT]) = 0;
8584 C_IS_RESERVED_WORD (ridpointers[(int) RID_BYCOPY]) = 0;
8585 C_IS_RESERVED_WORD (ridpointers[(int) RID_BYREF]) = 0;
8586 C_IS_RESERVED_WORD (ridpointers[(int) RID_ONEWAY]) = 0;
8589 void
8590 remember_protocol_qualifiers ()
8592 C_IS_RESERVED_WORD (ridpointers[(int) RID_IN]) = 1;
8593 C_IS_RESERVED_WORD (ridpointers[(int) RID_OUT]) = 1;
8594 C_IS_RESERVED_WORD (ridpointers[(int) RID_INOUT]) = 1;
8595 C_IS_RESERVED_WORD (ridpointers[(int) RID_BYCOPY]) = 1;
8596 C_IS_RESERVED_WORD (ridpointers[(int) RID_BYREF]) = 1;
8597 C_IS_RESERVED_WORD (ridpointers[(int) RID_ONEWAY]) = 1;