1 /* Implement classes and message passing for Objective C.
2 Copyright (C) 1992, 1993, 1994, 1995, 1997, 1998, 1999, 2000, 2001
3 Free Software Foundation, Inc.
4 Contributed by Steve Naroff.
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)
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
35 - statically allocated objects are not supported. the user will
36 receive an error if this service is requested.
38 code generation `options':
61 #include "langhooks.h"
62 #include "langhooks-def.h"
64 /* This is the default way of generating a method name. */
65 /* I am not sure it is really correct.
66 Perhaps there's a danger that it will make name conflicts
67 if method names contain underscores. -- rms. */
68 #ifndef OBJC_GEN_METHOD_LABEL
69 #define OBJC_GEN_METHOD_LABEL(BUF, IS_INST, CLASS_NAME, CAT_NAME, SEL_NAME, NUM) \
72 sprintf ((BUF), "_%s_%s_%s_%s", \
73 ((IS_INST) ? "i" : "c"), \
75 ((CAT_NAME)? (CAT_NAME) : ""), \
77 for (temp = (BUF); *temp; temp++) \
78 if (*temp == ':') *temp = '_'; \
82 /* These need specifying. */
83 #ifndef OBJC_FORWARDING_STACK_OFFSET
84 #define OBJC_FORWARDING_STACK_OFFSET 0
87 #ifndef OBJC_FORWARDING_MIN_OFFSET
88 #define OBJC_FORWARDING_MIN_OFFSET 0
91 /* Define the special tree codes that we use. */
93 /* Table indexed by tree code giving a string containing a character
94 classifying the tree code. */
96 #define DEFTREECODE(SYM, NAME, TYPE, LENGTH) TYPE,
98 static const char objc_tree_code_type[] = {
100 #include "objc-tree.def"
104 /* Table indexed by tree code giving number of expression
105 operands beyond the fixed part of the node structure.
106 Not used for types or decls. */
108 #define DEFTREECODE(SYM, NAME, TYPE, LENGTH) LENGTH,
110 static const int objc_tree_code_length[] = {
112 #include "objc-tree.def"
116 /* Names of tree components.
117 Used for printing out the tree and error messages. */
118 #define DEFTREECODE(SYM, NAME, TYPE, LEN) NAME,
120 static const char * const objc_tree_code_name[] = {
122 #include "objc-tree.def"
126 /* Set up for use of obstacks. */
130 #define obstack_chunk_alloc xmalloc
131 #define obstack_chunk_free free
133 /* This obstack is used to accumulate the encoding of a data type. */
134 static struct obstack util_obstack;
135 /* This points to the beginning of obstack contents,
136 so we can free the whole contents. */
139 /* for encode_method_def */
142 /* The version identifies which language generation and runtime
143 the module (file) was compiled for, and is recorded in the
144 module descriptor. */
146 #define OBJC_VERSION (flag_next_runtime ? 5 : 8)
147 #define PROTOCOL_VERSION 2
149 /* (Decide if these can ever be validly changed.) */
150 #define OBJC_ENCODE_INLINE_DEFS 0
151 #define OBJC_ENCODE_DONT_INLINE_DEFS 1
153 /*** Private Interface (procedures) ***/
155 /* Used by compile_file. */
157 static void init_objc PARAMS ((void));
158 static void finish_objc PARAMS ((void));
159 static const char *objc_init PARAMS ((const char *));
160 static void objc_init_options PARAMS ((void));
161 static int objc_decode_option PARAMS ((int, char **));
162 static void objc_post_options PARAMS ((void));
164 /* Code generation. */
166 static void synth_module_prologue PARAMS ((void));
167 static tree build_constructor PARAMS ((tree, tree));
168 static rtx build_module_descriptor PARAMS ((void));
169 static tree init_module_descriptor PARAMS ((tree));
170 static tree build_objc_method_call PARAMS ((int, tree, tree,
172 static void generate_strings PARAMS ((void));
173 static tree get_proto_encoding PARAMS ((tree));
174 static void build_selector_translation_table PARAMS ((void));
175 static tree build_ivar_chain PARAMS ((tree, int));
177 static tree objc_add_static_instance PARAMS ((tree, tree));
179 static tree build_ivar_template PARAMS ((void));
180 static tree build_method_template PARAMS ((void));
181 static tree build_private_template PARAMS ((tree));
182 static void build_class_template PARAMS ((void));
183 static void build_selector_template PARAMS ((void));
184 static void build_category_template PARAMS ((void));
185 static tree build_super_template PARAMS ((void));
186 static tree build_category_initializer PARAMS ((tree, tree, tree,
188 static tree build_protocol_initializer PARAMS ((tree, tree, tree,
191 static void synth_forward_declarations PARAMS ((void));
192 static void generate_ivar_lists PARAMS ((void));
193 static void generate_dispatch_tables PARAMS ((void));
194 static void generate_shared_structures PARAMS ((void));
195 static tree generate_protocol_list PARAMS ((tree));
196 static void generate_forward_declaration_to_string_table PARAMS ((void));
197 static void build_protocol_reference PARAMS ((tree));
199 static tree build_keyword_selector PARAMS ((tree));
200 static tree synth_id_with_class_suffix PARAMS ((const char *, tree));
202 static void generate_static_references PARAMS ((void));
203 static int check_methods_accessible PARAMS ((tree, tree,
205 static void encode_aggregate_within PARAMS ((tree, int, int,
207 static const char *objc_demangle PARAMS ((const char *));
208 static const char *objc_printable_name PARAMS ((tree, int));
209 static void objc_expand_function_end PARAMS ((void));
211 /* Hash tables to manage the global pool of method prototypes. */
213 hash *nst_method_hash_list = 0;
214 hash *cls_method_hash_list = 0;
216 static void hash_init PARAMS ((void));
217 static void hash_enter PARAMS ((hash *, tree));
218 static hash hash_lookup PARAMS ((hash *, tree));
219 static void hash_add_attr PARAMS ((hash, tree));
220 static tree lookup_method PARAMS ((tree, tree));
221 static tree lookup_instance_method_static PARAMS ((tree, tree));
222 static tree lookup_class_method_static PARAMS ((tree, tree));
223 static tree add_class PARAMS ((tree));
224 static void add_category PARAMS ((tree, tree));
228 class_names, /* class, category, protocol, module names */
229 meth_var_names, /* method and variable names */
230 meth_var_types /* method and variable type descriptors */
233 static tree add_objc_string PARAMS ((tree,
234 enum string_section));
235 static tree get_objc_string_decl PARAMS ((tree,
236 enum string_section));
237 static tree build_objc_string_decl PARAMS ((enum string_section));
238 static tree build_selector_reference_decl PARAMS ((void));
240 /* Protocol additions. */
242 static tree add_protocol PARAMS ((tree));
243 static tree lookup_protocol PARAMS ((tree));
244 static void check_protocol_recursively PARAMS ((tree, tree));
245 static tree lookup_and_install_protocols PARAMS ((tree));
249 static void encode_type_qualifiers PARAMS ((tree));
250 static void encode_pointer PARAMS ((tree, int, int));
251 static void encode_array PARAMS ((tree, int, int));
252 static void encode_aggregate PARAMS ((tree, int, int));
253 static void encode_bitfield PARAMS ((int));
254 static void encode_type PARAMS ((tree, int, int));
255 static void encode_field_decl PARAMS ((tree, int, int));
257 static void really_start_method PARAMS ((tree, tree));
258 static int comp_method_with_proto PARAMS ((tree, tree));
259 static int comp_proto_with_proto PARAMS ((tree, tree));
260 static tree get_arg_type_list PARAMS ((tree, int, int));
261 static tree expr_last PARAMS ((tree));
263 /* Utilities for debugging and error diagnostics. */
265 static void warn_with_method PARAMS ((const char *, int, tree));
266 static void error_with_ivar PARAMS ((const char *, tree, tree));
267 static char *gen_method_decl PARAMS ((tree, char *));
268 static char *gen_declaration PARAMS ((tree, char *));
269 static void gen_declaration_1 PARAMS ((tree, char *));
270 static char *gen_declarator PARAMS ((tree, char *,
272 static int is_complex_decl PARAMS ((tree));
273 static void adorn_decl PARAMS ((tree, char *));
274 static void dump_interface PARAMS ((FILE *, tree));
276 /* Everything else. */
278 static tree define_decl PARAMS ((tree, tree));
279 static tree lookup_method_in_protocol_list PARAMS ((tree, tree, int));
280 static tree lookup_protocol_in_reflist PARAMS ((tree, tree));
281 static tree create_builtin_decl PARAMS ((enum tree_code,
282 tree, const char *));
283 static void setup_string_decl PARAMS ((void));
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 static tree build_typed_selector_reference PARAMS ((tree, tree));
292 static tree build_selector_reference PARAMS ((tree));
293 static tree build_class_reference_decl PARAMS ((void));
294 static void add_class_reference PARAMS ((tree));
295 static tree objc_copy_list PARAMS ((tree, tree *));
296 static tree build_protocol_template PARAMS ((void));
297 static tree build_descriptor_table_initializer PARAMS ((tree, tree));
298 static tree build_method_prototype_list_template PARAMS ((tree, int));
299 static tree build_method_prototype_template PARAMS ((void));
300 static int forwarding_offset PARAMS ((tree));
301 static tree encode_method_prototype PARAMS ((tree, tree));
302 static tree generate_descriptor_table PARAMS ((tree, const char *,
304 static void generate_method_descriptors PARAMS ((tree));
305 static tree build_tmp_function_decl PARAMS ((void));
306 static void hack_method_prototype PARAMS ((tree, tree));
307 static void generate_protocol_references PARAMS ((tree));
308 static void generate_protocols PARAMS ((void));
309 static void check_ivars PARAMS ((tree, tree));
310 static tree build_ivar_list_template PARAMS ((tree, int));
311 static tree build_method_list_template PARAMS ((tree, int));
312 static tree build_ivar_list_initializer PARAMS ((tree, tree));
313 static tree generate_ivars_list PARAMS ((tree, const char *,
315 static tree build_dispatch_table_initializer PARAMS ((tree, tree));
316 static tree generate_dispatch_table PARAMS ((tree, const char *,
318 static tree build_shared_structure_initializer PARAMS ((tree, tree, tree, tree,
319 tree, int, tree, tree,
321 static void generate_category PARAMS ((tree));
322 static int is_objc_type_qualifier PARAMS ((tree));
323 static tree adjust_type_for_id_default PARAMS ((tree));
324 static tree check_duplicates PARAMS ((hash));
325 static tree receiver_is_class_object PARAMS ((tree));
326 static int check_methods PARAMS ((tree, tree, int));
327 static int conforms_to_protocol PARAMS ((tree, tree));
328 static void check_protocol PARAMS ((tree, const char *,
330 static void check_protocols PARAMS ((tree, const char *,
332 static tree encode_method_def PARAMS ((tree));
333 static void gen_declspecs PARAMS ((tree, char *, int));
334 static void generate_classref_translation_entry PARAMS ((tree));
335 static void handle_class_ref PARAMS ((tree));
336 static void generate_struct_by_value_array PARAMS ((void))
338 static void objc_act_parse_init PARAMS ((void));
339 static void ggc_mark_imp_list PARAMS ((void *));
340 static void ggc_mark_hash_table PARAMS ((void *));
342 /*** Private Interface (data) ***/
344 /* Reserved tag definitions. */
347 #define TAG_OBJECT "objc_object"
348 #define TAG_CLASS "objc_class"
349 #define TAG_SUPER "objc_super"
350 #define TAG_SELECTOR "objc_selector"
352 #define UTAG_CLASS "_objc_class"
353 #define UTAG_IVAR "_objc_ivar"
354 #define UTAG_IVAR_LIST "_objc_ivar_list"
355 #define UTAG_METHOD "_objc_method"
356 #define UTAG_METHOD_LIST "_objc_method_list"
357 #define UTAG_CATEGORY "_objc_category"
358 #define UTAG_MODULE "_objc_module"
359 #define UTAG_STATICS "_objc_statics"
360 #define UTAG_SYMTAB "_objc_symtab"
361 #define UTAG_SUPER "_objc_super"
362 #define UTAG_SELECTOR "_objc_selector"
364 #define UTAG_PROTOCOL "_objc_protocol"
365 #define UTAG_PROTOCOL_LIST "_objc_protocol_list"
366 #define UTAG_METHOD_PROTOTYPE "_objc_method_prototype"
367 #define UTAG_METHOD_PROTOTYPE_LIST "_objc__method_prototype_list"
369 #ifdef NEXT_OBJC_RUNTIME
370 #define STRING_OBJECT_CLASS_NAME "NSConstantString"
372 #define STRING_OBJECT_CLASS_NAME "NXConstantString"
374 /* Note that the string object global name is only needed for the
376 #define STRING_OBJECT_GLOBAL_NAME "_NSConstantStringClassReference"
378 #define PROTOCOL_OBJECT_CLASS_NAME "Protocol"
380 static const char *constant_string_class_name = NULL;
382 static const char *TAG_GETCLASS;
383 static const char *TAG_GETMETACLASS;
384 static const char *TAG_MSGSEND;
385 static const char *TAG_MSGSENDSUPER;
386 static const char *TAG_EXECCLASS;
388 /* The OCTI_... enumeration itself in in objc/objc-act.h. */
389 tree objc_global_trees[OCTI_MAX];
391 int objc_receiver_context;
393 static void handle_impent PARAMS ((struct imp_entry *));
395 struct imp_entry *imp_list = 0;
396 int imp_count = 0; /* `@implementation' */
397 int cat_count = 0; /* `@category' */
399 static int method_slot = 0; /* Used by start_method_def, */
403 static char *errbuf; /* Buffer for error diagnostics */
405 /* Data imported from tree.c. */
407 extern enum debug_info_type write_symbols;
409 /* Data imported from toplev.c. */
411 extern const char *dump_base_name;
413 /* Generate code for GNU or NeXT runtime environment. */
415 #ifdef NEXT_OBJC_RUNTIME
416 int flag_next_runtime = 1;
418 int flag_next_runtime = 0;
421 int flag_typed_selectors;
423 /* Open and close the file for outputting class declarations, if requested. */
425 int flag_gen_declaration = 0;
427 FILE *gen_declaration_file;
429 /* Warn if multiple methods are seen for the same selector, but with
430 different argument types. */
432 int warn_selector = 0;
434 /* Warn if methods required by a protocol are not implemented in the
435 class adopting it. When turned off, methods inherited to that
436 class are also considered implemented */
438 int flag_warn_protocol = 1;
440 /* Tells "encode_pointer/encode_aggregate" whether we are generating
441 type descriptors for instance variables (as opposed to methods).
442 Type descriptors for instance variables contain more information
443 than methods (for static typing and embedded structures). This
444 was added to support features being planned for dbkit2. */
446 static int generating_instance_variables = 0;
448 /* Tells the compiler that this is a special run. Do not perform
449 any compiling, instead we are to test some platform dependent
450 features and output a C header file with appropriate definitions. */
452 static int print_struct_values = 0;
454 #undef LANG_HOOKS_NAME
455 #define LANG_HOOKS_NAME "GNU Objective-C"
456 #undef LANG_HOOKS_INIT
457 #define LANG_HOOKS_INIT objc_init
458 #undef LANG_HOOKS_FINISH
459 #define LANG_HOOKS_FINISH c_common_finish
460 #undef LANG_HOOKS_INIT_OPTIONS
461 #define LANG_HOOKS_INIT_OPTIONS objc_init_options
462 #undef LANG_HOOKS_DECODE_OPTION
463 #define LANG_HOOKS_DECODE_OPTION objc_decode_option
464 #undef LANG_HOOKS_POST_OPTIONS
465 #define LANG_HOOKS_POST_OPTIONS objc_post_options
466 #undef LANG_HOOKS_PRINT_IDENTIFIER
467 #define LANG_HOOKS_PRINT_IDENTIFIER c_print_identifier
468 #undef LANG_HOOKS_SET_YYDEBUG
469 #define LANG_HOOKS_SET_YYDEBUG c_set_yydebug
470 /* Inlining hooks same as the C front end. */
471 #undef LANG_HOOKS_TREE_INLINING_CANNOT_INLINE_TREE_FN
472 #define LANG_HOOKS_TREE_INLINING_CANNOT_INLINE_TREE_FN \
473 c_cannot_inline_tree_fn
474 #undef LANG_HOOKS_TREE_INLINING_DISREGARD_INLINE_LIMITS
475 #define LANG_HOOKS_TREE_INLINING_DISREGARD_INLINE_LIMITS \
476 c_disregard_inline_limits
477 #undef LANG_HOOKS_TREE_INLINING_ANON_AGGR_TYPE_P
478 #define LANG_HOOKS_TREE_INLINING_ANON_AGGR_TYPE_P \
481 /* Each front end provides its own. */
482 const struct lang_hooks lang_hooks = LANG_HOOKS_INITIALIZER;
484 /* Post-switch processing. */
488 c_common_post_options ();
491 /* Some platforms pass small structures through registers versus through
492 an invisible pointer. Determine at what size structure is the
493 transition point between the two possibilities. */
496 generate_struct_by_value_array ()
499 tree field_decl, field_decl_chain;
501 int aggregate_in_mem[32];
504 /* Presumably no platform passes 32 byte structures in a register. */
505 for (i = 1; i < 32; i++)
509 /* Create an unnamed struct that has `i' character components */
510 type = start_struct (RECORD_TYPE, NULL_TREE);
512 strcpy (buffer, "c1");
513 field_decl = create_builtin_decl (FIELD_DECL,
516 field_decl_chain = field_decl;
518 for (j = 1; j < i; j++)
520 sprintf (buffer, "c%d", j + 1);
521 field_decl = create_builtin_decl (FIELD_DECL,
524 chainon (field_decl_chain, field_decl);
526 finish_struct (type, field_decl_chain, NULL_TREE);
528 aggregate_in_mem[i] = aggregate_value_p (type);
529 if (!aggregate_in_mem[i])
533 /* We found some structures that are returned in registers instead of memory
534 so output the necessary data. */
537 for (i = 31; i >= 0; i--)
538 if (!aggregate_in_mem[i])
540 printf ("#define OBJC_MAX_STRUCT_BY_VALUE %d\n\n", i);
542 /* The first member of the structure is always 0 because we don't handle
543 structures with 0 members */
544 printf ("static int struct_forward_array[] = {\n 0");
546 for (j = 1; j <= i; j++)
547 printf (", %d", aggregate_in_mem[j]);
557 c_common_init_options (clk_objective_c);
562 const char *filename;
564 filename = c_objc_common_init (filename);
566 decl_printable_name = objc_printable_name;
568 /* Force the line number back to 0; check_newline will have
569 raised it to 1, which will make the builtin functions appear
570 not to be built in. */
573 /* If gen_declaration desired, open the output file. */
574 if (flag_gen_declaration)
576 register char * const dumpname = concat (dump_base_name, ".decl", NULL);
577 gen_declaration_file = fopen (dumpname, "w");
578 if (gen_declaration_file == 0)
579 fatal_io_error ("can't open %s", dumpname);
583 if (flag_next_runtime)
585 TAG_GETCLASS = "objc_getClass";
586 TAG_GETMETACLASS = "objc_getMetaClass";
587 TAG_MSGSEND = "objc_msgSend";
588 TAG_MSGSENDSUPER = "objc_msgSendSuper";
589 TAG_EXECCLASS = "__objc_execClass";
593 TAG_GETCLASS = "objc_get_class";
594 TAG_GETMETACLASS = "objc_get_meta_class";
595 TAG_MSGSEND = "objc_msg_lookup";
596 TAG_MSGSENDSUPER = "objc_msg_lookup_super";
597 TAG_EXECCLASS = "__objc_exec_class";
598 flag_typed_selectors = 1;
601 objc_ellipsis_node = make_node (ERROR_MARK);
605 if (print_struct_values)
606 generate_struct_by_value_array ();
608 objc_act_parse_init ();
616 c_objc_common_finish_file ();
618 finish_objc (); /* Objective-C finalization */
620 if (gen_declaration_file)
621 fclose (gen_declaration_file);
625 objc_decode_option (argc, argv)
629 const char *p = argv[0];
631 if (!strcmp (p, "-gen-decls"))
632 flag_gen_declaration = 1;
633 else if (!strcmp (p, "-Wselector"))
635 else if (!strcmp (p, "-Wno-selector"))
637 else if (!strcmp (p, "-Wprotocol"))
638 flag_warn_protocol = 1;
639 else if (!strcmp (p, "-Wno-protocol"))
640 flag_warn_protocol = 0;
641 else if (!strcmp (p, "-fgnu-runtime"))
642 flag_next_runtime = 0;
643 else if (!strcmp (p, "-fno-next-runtime"))
644 flag_next_runtime = 0;
645 else if (!strcmp (p, "-fno-gnu-runtime"))
646 flag_next_runtime = 1;
647 else if (!strcmp (p, "-fnext-runtime"))
648 flag_next_runtime = 1;
649 else if (!strcmp (p, "-print-objc-runtime-info"))
650 print_struct_values = 1;
651 #define CSTSTRCLASS "-fconstant-string-class="
652 else if (!strncmp (p, CSTSTRCLASS, sizeof(CSTSTRCLASS) - 2)) {
653 if (strlen (argv[0]) <= strlen (CSTSTRCLASS))
654 error ("no class name specified as argument to -fconstant-string-class");
655 constant_string_class_name = xstrdup(argv[0] + sizeof(CSTSTRCLASS) - 1);
659 return c_decode_option (argc, argv);
666 define_decl (declarator, declspecs)
670 tree decl = start_decl (declarator, declspecs, 0, NULL_TREE);
671 finish_decl (decl, NULL_TREE, NULL_TREE);
675 /* Return 1 if LHS and RHS are compatible types for assignment or
676 various other operations. Return 0 if they are incompatible, and
677 return -1 if we choose to not decide. When the operation is
678 REFLEXIVE, check for compatibility in either direction.
680 For statically typed objects, an assignment of the form `a' = `b'
684 `a' and `b' are the same class type, or
685 `a' and `b' are of class types A and B such that B is a descendant of A. */
688 maybe_objc_comptypes (lhs, rhs, reflexive)
692 return objc_comptypes (lhs, rhs, reflexive);
696 lookup_method_in_protocol_list (rproto_list, sel_name, class_meth)
704 for (rproto = rproto_list; rproto; rproto = TREE_CHAIN (rproto))
706 p = TREE_VALUE (rproto);
708 if (TREE_CODE (p) == PROTOCOL_INTERFACE_TYPE)
710 if ((fnd = lookup_method (class_meth
711 ? PROTOCOL_CLS_METHODS (p)
712 : PROTOCOL_NST_METHODS (p), sel_name)))
714 else if (PROTOCOL_LIST (p))
715 fnd = lookup_method_in_protocol_list (PROTOCOL_LIST (p),
716 sel_name, class_meth);
720 ; /* An identifier...if we could not find a protocol. */
731 lookup_protocol_in_reflist (rproto_list, lproto)
737 /* Make sure the protocol is supported by the object on the rhs. */
738 if (TREE_CODE (lproto) == PROTOCOL_INTERFACE_TYPE)
741 for (rproto = rproto_list; rproto; rproto = TREE_CHAIN (rproto))
743 p = TREE_VALUE (rproto);
745 if (TREE_CODE (p) == PROTOCOL_INTERFACE_TYPE)
750 else if (PROTOCOL_LIST (p))
751 fnd = lookup_protocol_in_reflist (PROTOCOL_LIST (p), lproto);
760 ; /* An identifier...if we could not find a protocol. */
766 /* Return 1 if LHS and RHS are compatible types for assignment
767 or various other operations. Return 0 if they are incompatible,
768 and return -1 if we choose to not decide. When the operation
769 is REFLEXIVE, check for compatibility in either direction. */
772 objc_comptypes (lhs, rhs, reflexive)
777 /* New clause for protocols. */
779 if (TREE_CODE (lhs) == POINTER_TYPE
780 && TREE_CODE (TREE_TYPE (lhs)) == RECORD_TYPE
781 && TREE_CODE (rhs) == POINTER_TYPE
782 && TREE_CODE (TREE_TYPE (rhs)) == RECORD_TYPE)
784 int lhs_is_proto = IS_PROTOCOL_QUALIFIED_ID (lhs);
785 int rhs_is_proto = IS_PROTOCOL_QUALIFIED_ID (rhs);
789 tree lproto, lproto_list = TYPE_PROTOCOL_LIST (lhs);
790 tree rproto, rproto_list;
795 rproto_list = TYPE_PROTOCOL_LIST (rhs);
797 /* Make sure the protocol is supported by the object
799 for (lproto = lproto_list; lproto; lproto = TREE_CHAIN (lproto))
801 p = TREE_VALUE (lproto);
802 rproto = lookup_protocol_in_reflist (rproto_list, p);
805 warning ("object does not conform to the `%s' protocol",
806 IDENTIFIER_POINTER (PROTOCOL_NAME (p)));
809 else if (TYPED_OBJECT (TREE_TYPE (rhs)))
811 tree rname = TYPE_NAME (TREE_TYPE (rhs));
814 /* Make sure the protocol is supported by the object
816 for (lproto = lproto_list; lproto; lproto = TREE_CHAIN (lproto))
818 p = TREE_VALUE (lproto);
820 rinter = lookup_interface (rname);
822 while (rinter && !rproto)
826 rproto_list = CLASS_PROTOCOL_LIST (rinter);
827 /* If the underlying ObjC class does not have
828 protocols attached to it, perhaps there are
829 "one-off" protocols attached to the rhs?
830 E.g., 'id<MyProt> foo;'. */
832 rproto_list = TYPE_PROTOCOL_LIST (TREE_TYPE (rhs));
833 rproto = lookup_protocol_in_reflist (rproto_list, p);
835 /* Check for protocols adopted by categories. */
836 cat = CLASS_CATEGORY_LIST (rinter);
837 while (cat && !rproto)
839 rproto_list = CLASS_PROTOCOL_LIST (cat);
840 rproto = lookup_protocol_in_reflist (rproto_list, p);
842 cat = CLASS_CATEGORY_LIST (cat);
845 rinter = lookup_interface (CLASS_SUPER_NAME (rinter));
849 warning ("class `%s' does not implement the `%s' protocol",
850 IDENTIFIER_POINTER (TYPE_NAME (TREE_TYPE (rhs))),
851 IDENTIFIER_POINTER (PROTOCOL_NAME (p)));
855 /* May change...based on whether there was any mismatch */
858 else if (rhs_is_proto)
859 /* Lhs is not a protocol...warn if it is statically typed */
860 return (TYPED_OBJECT (TREE_TYPE (lhs)) != 0);
863 /* Defer to comptypes. */
867 else if (TREE_CODE (lhs) == RECORD_TYPE && TREE_CODE (rhs) == RECORD_TYPE)
868 ; /* Fall thru. This is the case we have been handling all along */
870 /* Defer to comptypes. */
873 /* `id' = `<class> *', `<class> *' = `id' */
875 if ((TYPE_NAME (lhs) == objc_object_id && TYPED_OBJECT (rhs))
876 || (TYPE_NAME (rhs) == objc_object_id && TYPED_OBJECT (lhs)))
879 /* `id' = `Class', `Class' = `id' */
881 else if ((TYPE_NAME (lhs) == objc_object_id
882 && TYPE_NAME (rhs) == objc_class_id)
883 || (TYPE_NAME (lhs) == objc_class_id
884 && TYPE_NAME (rhs) == objc_object_id))
887 /* `<class> *' = `<class> *' */
889 else if (TYPED_OBJECT (lhs) && TYPED_OBJECT (rhs))
891 tree lname = TYPE_NAME (lhs);
892 tree rname = TYPE_NAME (rhs);
898 /* If the left hand side is a super class of the right hand side,
900 for (inter = lookup_interface (rname); inter;
901 inter = lookup_interface (CLASS_SUPER_NAME (inter)))
902 if (lname == CLASS_SUPER_NAME (inter))
905 /* Allow the reverse when reflexive. */
907 for (inter = lookup_interface (lname); inter;
908 inter = lookup_interface (CLASS_SUPER_NAME (inter)))
909 if (rname == CLASS_SUPER_NAME (inter))
915 /* Defer to comptypes. */
919 /* Called from c-decl.c before all calls to rest_of_decl_compilation. */
922 objc_check_decl (decl)
925 tree type = TREE_TYPE (decl);
927 if (TREE_CODE (type) == RECORD_TYPE
928 && TREE_STATIC_TEMPLATE (type)
929 && type != constant_string_type)
930 error_with_decl (decl, "`%s' cannot be statically allocated");
934 maybe_objc_check_decl (decl)
937 objc_check_decl (decl);
940 /* Implement static typing. At this point, we know we have an interface. */
943 get_static_reference (interface, protocols)
947 tree type = xref_tag (RECORD_TYPE, interface);
951 tree t, m = TYPE_MAIN_VARIANT (type);
953 t = copy_node (type);
954 TYPE_BINFO (t) = make_tree_vec (2);
956 /* Add this type to the chain of variants of TYPE. */
957 TYPE_NEXT_VARIANT (t) = TYPE_NEXT_VARIANT (m);
958 TYPE_NEXT_VARIANT (m) = t;
960 /* Look up protocols and install in lang specific list. Note
961 that the protocol list can have a different lifetime than T! */
962 TYPE_PROTOCOL_LIST (t) = lookup_and_install_protocols (protocols);
964 /* This forces a new pointer type to be created later
965 (in build_pointer_type)...so that the new template
966 we just created will actually be used...what a hack! */
967 if (TYPE_POINTER_TO (t))
968 TYPE_POINTER_TO (t) = NULL_TREE;
977 get_object_reference (protocols)
980 tree type_decl = lookup_name (objc_id_id);
983 if (type_decl && TREE_CODE (type_decl) == TYPE_DECL)
985 type = TREE_TYPE (type_decl);
986 if (TYPE_MAIN_VARIANT (type) != id_type)
987 warning ("unexpected type for `id' (%s)",
988 gen_declaration (type, errbuf));
992 error ("undefined type `id', please import <objc/objc.h>");
993 return error_mark_node;
996 /* This clause creates a new pointer type that is qualified with
997 the protocol specification...this info is used later to do more
998 elaborate type checking. */
1002 tree t, m = TYPE_MAIN_VARIANT (type);
1004 t = copy_node (type);
1005 TYPE_BINFO (t) = make_tree_vec (2);
1007 /* Add this type to the chain of variants of TYPE. */
1008 TYPE_NEXT_VARIANT (t) = TYPE_NEXT_VARIANT (m);
1009 TYPE_NEXT_VARIANT (m) = t;
1011 /* Look up protocols...and install in lang specific list */
1012 TYPE_PROTOCOL_LIST (t) = lookup_and_install_protocols (protocols);
1014 /* This forces a new pointer type to be created later
1015 (in build_pointer_type)...so that the new template
1016 we just created will actually be used...what a hack! */
1017 if (TYPE_POINTER_TO (t))
1018 TYPE_POINTER_TO (t) = NULL_TREE;
1025 /* Check for circular dependencies in protocols. The arguments are
1026 PROTO, the protocol to check, and LIST, a list of protocol it
1030 check_protocol_recursively (proto, list)
1036 for (p = list; p; p = TREE_CHAIN (p))
1038 tree pp = TREE_VALUE (p);
1040 if (TREE_CODE (pp) == IDENTIFIER_NODE)
1041 pp = lookup_protocol (pp);
1044 fatal_error ("protocol `%s' has circular dependency",
1045 IDENTIFIER_POINTER (PROTOCOL_NAME (pp)));
1047 check_protocol_recursively (proto, PROTOCOL_LIST (pp));
1052 lookup_and_install_protocols (protocols)
1057 tree return_value = protocols;
1059 for (proto = protocols; proto; proto = TREE_CHAIN (proto))
1061 tree ident = TREE_VALUE (proto);
1062 tree p = lookup_protocol (ident);
1066 error ("cannot find protocol declaration for `%s'",
1067 IDENTIFIER_POINTER (ident));
1069 TREE_CHAIN (prev) = TREE_CHAIN (proto);
1071 return_value = TREE_CHAIN (proto);
1075 /* Replace identifier with actual protocol node. */
1076 TREE_VALUE (proto) = p;
1081 return return_value;
1084 /* Create and push a decl for a built-in external variable or field NAME.
1086 TYPE is its data type. */
1089 create_builtin_decl (code, type, name)
1090 enum tree_code code;
1094 tree decl = build_decl (code, get_identifier (name), type);
1096 if (code == VAR_DECL)
1098 TREE_STATIC (decl) = 1;
1099 make_decl_rtl (decl, 0);
1103 DECL_ARTIFICIAL (decl) = 1;
1107 /* Find the decl for the constant string class. */
1110 setup_string_decl ()
1112 if (!string_class_decl)
1114 if (!constant_string_global_id)
1115 constant_string_global_id = get_identifier (STRING_OBJECT_GLOBAL_NAME);
1116 string_class_decl = lookup_name (constant_string_global_id);
1120 /* Purpose: "play" parser, creating/installing representations
1121 of the declarations that are required by Objective-C.
1125 type_spec--------->sc_spec
1126 (tree_list) (tree_list)
1129 identifier_node identifier_node */
1132 synth_module_prologue ()
1137 /* Defined in `objc.h' */
1138 objc_object_id = get_identifier (TAG_OBJECT);
1140 objc_object_reference = xref_tag (RECORD_TYPE, objc_object_id);
1142 id_type = build_pointer_type (objc_object_reference);
1144 objc_id_id = get_identifier (TYPE_ID);
1145 objc_class_id = get_identifier (TAG_CLASS);
1147 objc_class_type = build_pointer_type (xref_tag (RECORD_TYPE, objc_class_id));
1148 protocol_type = build_pointer_type (xref_tag (RECORD_TYPE,
1149 get_identifier (PROTOCOL_OBJECT_CLASS_NAME)));
1151 /* Declare type of selector-objects that represent an operation name. */
1153 /* `struct objc_selector *' */
1155 = build_pointer_type (xref_tag (RECORD_TYPE,
1156 get_identifier (TAG_SELECTOR)));
1158 /* Forward declare type, or else the prototype for msgSendSuper will
1161 super_p = build_pointer_type (xref_tag (RECORD_TYPE,
1162 get_identifier (TAG_SUPER)));
1165 /* id objc_msgSend (id, SEL, ...); */
1168 = build_function_type (id_type,
1169 tree_cons (NULL_TREE, id_type,
1170 tree_cons (NULL_TREE, selector_type,
1173 if (! flag_next_runtime)
1175 umsg_decl = build_decl (FUNCTION_DECL,
1176 get_identifier (TAG_MSGSEND), temp_type);
1177 DECL_EXTERNAL (umsg_decl) = 1;
1178 TREE_PUBLIC (umsg_decl) = 1;
1179 DECL_INLINE (umsg_decl) = 1;
1180 DECL_ARTIFICIAL (umsg_decl) = 1;
1182 if (flag_traditional && TAG_MSGSEND[0] != '_')
1183 DECL_BUILT_IN_NONANSI (umsg_decl) = 1;
1185 make_decl_rtl (umsg_decl, NULL);
1186 pushdecl (umsg_decl);
1189 umsg_decl = builtin_function (TAG_MSGSEND, temp_type, 0, NOT_BUILT_IN, 0);
1191 /* id objc_msgSendSuper (struct objc_super *, SEL, ...); */
1194 = build_function_type (id_type,
1195 tree_cons (NULL_TREE, super_p,
1196 tree_cons (NULL_TREE, selector_type,
1199 umsg_super_decl = builtin_function (TAG_MSGSENDSUPER,
1200 temp_type, 0, NOT_BUILT_IN, 0);
1202 /* id objc_getClass (const char *); */
1204 temp_type = build_function_type (id_type,
1205 tree_cons (NULL_TREE,
1206 const_string_type_node,
1207 tree_cons (NULL_TREE, void_type_node,
1211 = builtin_function (TAG_GETCLASS, temp_type, 0, NOT_BUILT_IN, 0);
1213 /* id objc_getMetaClass (const char *); */
1215 objc_get_meta_class_decl
1216 = builtin_function (TAG_GETMETACLASS, temp_type, 0, NOT_BUILT_IN, 0);
1218 /* static SEL _OBJC_SELECTOR_TABLE[]; */
1220 if (! flag_next_runtime)
1222 if (flag_typed_selectors)
1224 /* Suppress outputting debug symbols, because
1225 dbxout_init hasn'r been called yet. */
1226 enum debug_info_type save_write_symbols = write_symbols;
1227 struct gcc_debug_hooks *save_hooks = debug_hooks;
1228 write_symbols = NO_DEBUG;
1229 debug_hooks = &do_nothing_debug_hooks;
1231 build_selector_template ();
1232 temp_type = build_array_type (objc_selector_template, NULL_TREE);
1234 write_symbols = save_write_symbols;
1235 debug_hooks = save_hooks;
1238 temp_type = build_array_type (selector_type, NULL_TREE);
1240 layout_type (temp_type);
1241 UOBJC_SELECTOR_TABLE_decl
1242 = create_builtin_decl (VAR_DECL, temp_type,
1243 "_OBJC_SELECTOR_TABLE");
1245 /* Avoid warning when not sending messages. */
1246 TREE_USED (UOBJC_SELECTOR_TABLE_decl) = 1;
1249 generate_forward_declaration_to_string_table ();
1251 /* Forward declare constant_string_id and constant_string_type. */
1252 if (!constant_string_class_name)
1253 constant_string_class_name = STRING_OBJECT_CLASS_NAME;
1255 constant_string_id = get_identifier (constant_string_class_name);
1256 constant_string_type = xref_tag (RECORD_TYPE, constant_string_id);
1259 /* Custom build_string which sets TREE_TYPE! */
1262 my_build_string (len, str)
1267 tree a_string = build_string (len, str);
1269 /* Some code from combine_strings, which is local to c-parse.y. */
1270 if (TREE_TYPE (a_string) == int_array_type_node)
1273 TREE_TYPE (a_string)
1274 = build_array_type (wide_flag ? integer_type_node : char_type_node,
1275 build_index_type (build_int_2 (len - 1, 0)));
1277 TREE_CONSTANT (a_string) = 1; /* Puts string in the readonly segment */
1278 TREE_STATIC (a_string) = 1;
1283 /* Given a chain of STRING_CST's, build a static instance of
1284 NXConstantString which points at the concatenation of those strings.
1285 We place the string object in the __string_objects section of the
1286 __OBJC segment. The Objective-C runtime will initialize the isa
1287 pointers of the string objects to point at the NXConstantString
1291 build_objc_string_object (strings)
1294 tree string, initlist, constructor;
1297 if (lookup_interface (constant_string_id) == NULL_TREE)
1299 error ("cannot find interface declaration for `%s'",
1300 IDENTIFIER_POINTER (constant_string_id));
1301 return error_mark_node;
1304 add_class_reference (constant_string_id);
1306 string = combine_strings (strings);
1307 TREE_SET_CODE (string, STRING_CST);
1308 length = TREE_STRING_LENGTH (string) - 1;
1310 /* & ((NXConstantString) {0, string, length}) */
1312 if (flag_next_runtime)
1314 /* For the NeXT runtime, we can generate a literal reference
1315 to the string class, don't need to run a constructor. */
1316 setup_string_decl ();
1317 if (string_class_decl == NULL_TREE)
1319 error ("cannot find reference tag for class `%s'",
1320 IDENTIFIER_POINTER (constant_string_id));
1321 return error_mark_node;
1323 initlist = build_tree_list
1325 copy_node (build_unary_op (ADDR_EXPR, string_class_decl, 0)));
1329 initlist = build_tree_list (NULL_TREE, build_int_2 (0, 0));
1333 = tree_cons (NULL_TREE, copy_node (build_unary_op (ADDR_EXPR, string, 1)),
1335 initlist = tree_cons (NULL_TREE, build_int_2 (length, 0), initlist);
1336 constructor = build_constructor (constant_string_type, nreverse (initlist));
1338 if (!flag_next_runtime)
1341 = objc_add_static_instance (constructor, constant_string_type);
1344 return (build_unary_op (ADDR_EXPR, constructor, 1));
1347 /* Declare a static instance of CLASS_DECL initialized by CONSTRUCTOR. */
1350 objc_add_static_instance (constructor, class_decl)
1351 tree constructor, class_decl;
1353 static int num_static_inst;
1357 /* Find the list of static instances for the CLASS_DECL. Create one if
1359 for (chain = &objc_static_instances;
1360 *chain && TREE_VALUE (*chain) != class_decl;
1361 chain = &TREE_CHAIN (*chain));
1364 *chain = tree_cons (NULL_TREE, class_decl, NULL_TREE);
1365 add_objc_string (TYPE_NAME (class_decl), class_names);
1368 sprintf (buf, "_OBJC_INSTANCE_%d", num_static_inst++);
1369 decl = build_decl (VAR_DECL, get_identifier (buf), class_decl);
1370 DECL_COMMON (decl) = 1;
1371 TREE_STATIC (decl) = 1;
1372 DECL_ARTIFICIAL (decl) = 1;
1373 DECL_INITIAL (decl) = constructor;
1375 /* We may be writing something else just now.
1376 Postpone till end of input. */
1377 DECL_DEFER_OUTPUT (decl) = 1;
1378 pushdecl_top_level (decl);
1379 rest_of_decl_compilation (decl, 0, 1, 0);
1381 /* Add the DECL to the head of this CLASS' list. */
1382 TREE_PURPOSE (*chain) = tree_cons (NULL_TREE, decl, TREE_PURPOSE (*chain));
1387 /* Build a static constant CONSTRUCTOR
1388 with type TYPE and elements ELTS. */
1391 build_constructor (type, elts)
1394 tree constructor = build (CONSTRUCTOR, type, NULL_TREE, elts);
1396 TREE_CONSTANT (constructor) = 1;
1397 TREE_STATIC (constructor) = 1;
1398 TREE_READONLY (constructor) = 1;
1403 /* Take care of defining and initializing _OBJC_SYMBOLS. */
1405 /* Predefine the following data type:
1413 void *defs[cls_def_cnt + cat_def_cnt];
1417 build_objc_symtab_template ()
1419 tree field_decl, field_decl_chain, index;
1421 objc_symtab_template
1422 = start_struct (RECORD_TYPE, get_identifier (UTAG_SYMTAB));
1424 /* long sel_ref_cnt; */
1426 field_decl = create_builtin_decl (FIELD_DECL,
1427 long_integer_type_node,
1429 field_decl_chain = field_decl;
1433 field_decl = create_builtin_decl (FIELD_DECL,
1434 build_pointer_type (selector_type),
1436 chainon (field_decl_chain, field_decl);
1438 /* short cls_def_cnt; */
1440 field_decl = create_builtin_decl (FIELD_DECL,
1441 short_integer_type_node,
1443 chainon (field_decl_chain, field_decl);
1445 /* short cat_def_cnt; */
1447 field_decl = create_builtin_decl (FIELD_DECL,
1448 short_integer_type_node,
1450 chainon (field_decl_chain, field_decl);
1452 /* void *defs[cls_def_cnt + cat_def_cnt]; */
1454 if (!flag_next_runtime)
1455 index = build_index_type (build_int_2 (imp_count + cat_count, 0));
1457 index = build_index_type (build_int_2 (imp_count + cat_count - 1,
1458 imp_count == 0 && cat_count == 0
1460 field_decl = create_builtin_decl (FIELD_DECL,
1461 build_array_type (ptr_type_node, index),
1463 chainon (field_decl_chain, field_decl);
1465 finish_struct (objc_symtab_template, field_decl_chain, NULL_TREE);
1468 /* Create the initial value for the `defs' field of _objc_symtab.
1469 This is a CONSTRUCTOR. */
1472 init_def_list (type)
1475 tree expr, initlist = NULL_TREE;
1476 struct imp_entry *impent;
1479 for (impent = imp_list; impent; impent = impent->next)
1481 if (TREE_CODE (impent->imp_context) == CLASS_IMPLEMENTATION_TYPE)
1483 expr = build_unary_op (ADDR_EXPR, impent->class_decl, 0);
1484 initlist = tree_cons (NULL_TREE, expr, initlist);
1489 for (impent = imp_list; impent; impent = impent->next)
1491 if (TREE_CODE (impent->imp_context) == CATEGORY_IMPLEMENTATION_TYPE)
1493 expr = build_unary_op (ADDR_EXPR, impent->class_decl, 0);
1494 initlist = tree_cons (NULL_TREE, expr, initlist);
1498 if (!flag_next_runtime)
1500 /* statics = { ..., _OBJC_STATIC_INSTANCES, ... } */
1503 if (static_instances_decl)
1504 expr = build_unary_op (ADDR_EXPR, static_instances_decl, 0);
1506 expr = build_int_2 (0, 0);
1508 initlist = tree_cons (NULL_TREE, expr, initlist);
1511 return build_constructor (type, nreverse (initlist));
1514 /* Construct the initial value for all of _objc_symtab. */
1517 init_objc_symtab (type)
1522 /* sel_ref_cnt = { ..., 5, ... } */
1524 initlist = build_tree_list (NULL_TREE, build_int_2 (0, 0));
1526 /* refs = { ..., _OBJC_SELECTOR_TABLE, ... } */
1528 if (flag_next_runtime || ! sel_ref_chain)
1529 initlist = tree_cons (NULL_TREE, build_int_2 (0, 0), initlist);
1531 initlist = tree_cons (NULL_TREE,
1532 build_unary_op (ADDR_EXPR,
1533 UOBJC_SELECTOR_TABLE_decl, 1),
1536 /* cls_def_cnt = { ..., 5, ... } */
1538 initlist = tree_cons (NULL_TREE, build_int_2 (imp_count, 0), initlist);
1540 /* cat_def_cnt = { ..., 5, ... } */
1542 initlist = tree_cons (NULL_TREE, build_int_2 (cat_count, 0), initlist);
1544 /* cls_def = { ..., { &Foo, &Bar, ...}, ... } */
1546 if (imp_count || cat_count || static_instances_decl)
1549 tree field = TYPE_FIELDS (type);
1550 field = TREE_CHAIN (TREE_CHAIN (TREE_CHAIN (TREE_CHAIN (field))));
1552 initlist = tree_cons (NULL_TREE, init_def_list (TREE_TYPE (field)),
1556 return build_constructor (type, nreverse (initlist));
1559 /* Push forward-declarations of all the categories
1560 so that init_def_list can use them in a CONSTRUCTOR. */
1563 forward_declare_categories ()
1565 struct imp_entry *impent;
1566 tree sav = objc_implementation_context;
1568 for (impent = imp_list; impent; impent = impent->next)
1570 if (TREE_CODE (impent->imp_context) == CATEGORY_IMPLEMENTATION_TYPE)
1572 /* Set an invisible arg to synth_id_with_class_suffix. */
1573 objc_implementation_context = impent->imp_context;
1575 = create_builtin_decl (VAR_DECL, objc_category_template,
1576 IDENTIFIER_POINTER (synth_id_with_class_suffix ("_OBJC_CATEGORY", objc_implementation_context)));
1579 objc_implementation_context = sav;
1582 /* Create the declaration of _OBJC_SYMBOLS, with type `strict _objc_symtab'
1583 and initialized appropriately. */
1586 generate_objc_symtab_decl ()
1590 if (!objc_category_template)
1591 build_category_template ();
1593 /* forward declare categories */
1595 forward_declare_categories ();
1597 if (!objc_symtab_template)
1598 build_objc_symtab_template ();
1600 sc_spec = build_tree_list (NULL_TREE, ridpointers[(int) RID_STATIC]);
1602 UOBJC_SYMBOLS_decl = start_decl (get_identifier ("_OBJC_SYMBOLS"),
1603 tree_cons (NULL_TREE,
1604 objc_symtab_template, sc_spec),
1608 TREE_USED (UOBJC_SYMBOLS_decl) = 1;
1609 DECL_IGNORED_P (UOBJC_SYMBOLS_decl) = 1;
1610 DECL_ARTIFICIAL (UOBJC_SYMBOLS_decl) = 1;
1611 finish_decl (UOBJC_SYMBOLS_decl,
1612 init_objc_symtab (TREE_TYPE (UOBJC_SYMBOLS_decl)),
1617 init_module_descriptor (type)
1620 tree initlist, expr;
1622 /* version = { 1, ... } */
1624 expr = build_int_2 (OBJC_VERSION, 0);
1625 initlist = build_tree_list (NULL_TREE, expr);
1627 /* size = { ..., sizeof (struct objc_module), ... } */
1629 expr = size_in_bytes (objc_module_template);
1630 initlist = tree_cons (NULL_TREE, expr, initlist);
1632 /* name = { ..., "foo.m", ... } */
1634 expr = add_objc_string (get_identifier (input_filename), class_names);
1635 initlist = tree_cons (NULL_TREE, expr, initlist);
1637 /* symtab = { ..., _OBJC_SYMBOLS, ... } */
1639 if (UOBJC_SYMBOLS_decl)
1640 expr = build_unary_op (ADDR_EXPR, UOBJC_SYMBOLS_decl, 0);
1642 expr = build_int_2 (0, 0);
1643 initlist = tree_cons (NULL_TREE, expr, initlist);
1645 return build_constructor (type, nreverse (initlist));
1648 /* Write out the data structures to describe Objective C classes defined.
1649 If appropriate, compile and output a setup function to initialize them.
1650 Return a symbol_ref to the function to call to initialize the Objective C
1651 data structures for this file (and perhaps for other files also).
1653 struct objc_module { ... } _OBJC_MODULE = { ... }; */
1656 build_module_descriptor ()
1658 tree decl_specs, field_decl, field_decl_chain;
1660 objc_module_template
1661 = start_struct (RECORD_TYPE, get_identifier (UTAG_MODULE));
1665 decl_specs = build_tree_list (NULL_TREE, ridpointers[(int) RID_LONG]);
1666 field_decl = get_identifier ("version");
1668 = grokfield (input_filename, lineno, field_decl, decl_specs, NULL_TREE);
1669 field_decl_chain = field_decl;
1673 decl_specs = build_tree_list (NULL_TREE, ridpointers[(int) RID_LONG]);
1674 field_decl = get_identifier ("size");
1676 = grokfield (input_filename, lineno, field_decl, decl_specs, NULL_TREE);
1677 chainon (field_decl_chain, field_decl);
1681 decl_specs = build_tree_list (NULL_TREE, ridpointers[(int) RID_CHAR]);
1682 field_decl = build1 (INDIRECT_REF, NULL_TREE, get_identifier ("name"));
1684 = grokfield (input_filename, lineno, field_decl, decl_specs, NULL_TREE);
1685 chainon (field_decl_chain, field_decl);
1687 /* struct objc_symtab *symtab; */
1689 decl_specs = get_identifier (UTAG_SYMTAB);
1690 decl_specs = build_tree_list (NULL_TREE, xref_tag (RECORD_TYPE, decl_specs));
1691 field_decl = build1 (INDIRECT_REF, NULL_TREE, get_identifier ("symtab"));
1693 = grokfield (input_filename, lineno, field_decl, decl_specs, NULL_TREE);
1694 chainon (field_decl_chain, field_decl);
1696 finish_struct (objc_module_template, field_decl_chain, NULL_TREE);
1698 /* Create an instance of "objc_module". */
1700 decl_specs = tree_cons (NULL_TREE, objc_module_template,
1701 build_tree_list (NULL_TREE,
1702 ridpointers[(int) RID_STATIC]));
1704 UOBJC_MODULES_decl = start_decl (get_identifier ("_OBJC_MODULES"),
1705 decl_specs, 1, NULL_TREE);
1707 DECL_ARTIFICIAL (UOBJC_MODULES_decl) = 1;
1708 DECL_IGNORED_P (UOBJC_MODULES_decl) = 1;
1709 DECL_CONTEXT (UOBJC_MODULES_decl) = NULL_TREE;
1711 finish_decl (UOBJC_MODULES_decl,
1712 init_module_descriptor (TREE_TYPE (UOBJC_MODULES_decl)),
1715 /* Mark the decl to avoid "defined but not used" warning. */
1716 DECL_IN_SYSTEM_HEADER (UOBJC_MODULES_decl) = 1;
1718 /* Generate a constructor call for the module descriptor.
1719 This code was generated by reading the grammar rules
1720 of c-parse.in; Therefore, it may not be the most efficient
1721 way of generating the requisite code. */
1723 if (flag_next_runtime)
1727 tree parms, execclass_decl, decelerator, void_list_node_1;
1728 tree init_function_name, init_function_decl;
1730 /* Declare void __objc_execClass (void *); */
1732 void_list_node_1 = build_tree_list (NULL_TREE, void_type_node);
1733 execclass_decl = build_decl (FUNCTION_DECL,
1734 get_identifier (TAG_EXECCLASS),
1735 build_function_type (void_type_node,
1736 tree_cons (NULL_TREE, ptr_type_node,
1737 void_list_node_1)));
1738 DECL_EXTERNAL (execclass_decl) = 1;
1739 DECL_ARTIFICIAL (execclass_decl) = 1;
1740 TREE_PUBLIC (execclass_decl) = 1;
1741 pushdecl (execclass_decl);
1742 rest_of_decl_compilation (execclass_decl, 0, 0, 0);
1743 assemble_external (execclass_decl);
1745 /* void _GLOBAL_$I$<gnyf> () {objc_execClass (&L_OBJC_MODULES);} */
1747 init_function_name = get_file_function_name ('I');
1748 start_function (void_list_node_1,
1749 build_nt (CALL_EXPR, init_function_name,
1750 tree_cons (NULL_TREE, NULL_TREE,
1754 store_parm_decls ();
1756 init_function_decl = current_function_decl;
1757 TREE_PUBLIC (init_function_decl) = ! targetm.have_ctors_dtors;
1758 TREE_USED (init_function_decl) = 1;
1759 current_function_cannot_inline
1760 = "static constructors and destructors cannot be inlined";
1763 = build_tree_list (NULL_TREE,
1764 build_unary_op (ADDR_EXPR, UOBJC_MODULES_decl, 0));
1765 decelerator = build_function_call (execclass_decl, parms);
1767 c_expand_expr_stmt (decelerator);
1769 finish_function (0);
1771 return XEXP (DECL_RTL (init_function_decl), 0);
1775 /* extern const char _OBJC_STRINGS[]; */
1778 generate_forward_declaration_to_string_table ()
1780 tree sc_spec, decl_specs, expr_decl;
1782 sc_spec = tree_cons (NULL_TREE, ridpointers[(int) RID_EXTERN], NULL_TREE);
1783 decl_specs = tree_cons (NULL_TREE, ridpointers[(int) RID_CHAR], sc_spec);
1786 = build_nt (ARRAY_REF, get_identifier ("_OBJC_STRINGS"), NULL_TREE);
1788 UOBJC_STRINGS_decl = define_decl (expr_decl, decl_specs);
1791 /* Return the DECL of the string IDENT in the SECTION. */
1794 get_objc_string_decl (ident, section)
1796 enum string_section section;
1800 if (section == class_names)
1801 chain = class_names_chain;
1802 else if (section == meth_var_names)
1803 chain = meth_var_names_chain;
1804 else if (section == meth_var_types)
1805 chain = meth_var_types_chain;
1809 for (; chain != 0; chain = TREE_VALUE (chain))
1810 if (TREE_VALUE (chain) == ident)
1811 return (TREE_PURPOSE (chain));
1817 /* Output references to all statically allocated objects. Return the DECL
1818 for the array built. */
1821 generate_static_references ()
1823 tree decls = NULL_TREE, ident, decl_spec, expr_decl, expr = NULL_TREE;
1824 tree class_name, class, decl, initlist;
1825 tree cl_chain, in_chain, type;
1826 int num_inst, num_class;
1829 if (flag_next_runtime)
1832 for (cl_chain = objc_static_instances, num_class = 0;
1833 cl_chain; cl_chain = TREE_CHAIN (cl_chain), num_class++)
1835 for (num_inst = 0, in_chain = TREE_PURPOSE (cl_chain);
1836 in_chain; num_inst++, in_chain = TREE_CHAIN (in_chain));
1838 sprintf (buf, "_OBJC_STATIC_INSTANCES_%d", num_class);
1839 ident = get_identifier (buf);
1841 expr_decl = build_nt (ARRAY_REF, ident, NULL_TREE);
1842 decl_spec = tree_cons (NULL_TREE, build_pointer_type (void_type_node),
1843 build_tree_list (NULL_TREE,
1844 ridpointers[(int) RID_STATIC]));
1845 decl = start_decl (expr_decl, decl_spec, 1, NULL_TREE);
1846 DECL_CONTEXT (decl) = 0;
1847 DECL_ARTIFICIAL (decl) = 1;
1849 /* Output {class_name, ...}. */
1850 class = TREE_VALUE (cl_chain);
1851 class_name = get_objc_string_decl (TYPE_NAME (class), class_names);
1852 initlist = build_tree_list (NULL_TREE,
1853 build_unary_op (ADDR_EXPR, class_name, 1));
1855 /* Output {..., instance, ...}. */
1856 for (in_chain = TREE_PURPOSE (cl_chain);
1857 in_chain; in_chain = TREE_CHAIN (in_chain))
1859 expr = build_unary_op (ADDR_EXPR, TREE_VALUE (in_chain), 1);
1860 initlist = tree_cons (NULL_TREE, expr, initlist);
1863 /* Output {..., NULL}. */
1864 initlist = tree_cons (NULL_TREE, build_int_2 (0, 0), initlist);
1866 expr = build_constructor (TREE_TYPE (decl), nreverse (initlist));
1867 finish_decl (decl, expr, NULL_TREE);
1868 TREE_USED (decl) = 1;
1870 type = build_array_type (build_pointer_type (void_type_node), 0);
1871 decl = build_decl (VAR_DECL, ident, type);
1872 TREE_USED (decl) = 1;
1873 TREE_STATIC (decl) = 1;
1875 = tree_cons (NULL_TREE, build_unary_op (ADDR_EXPR, decl, 1), decls);
1878 decls = tree_cons (NULL_TREE, build_int_2 (0, 0), decls);
1879 ident = get_identifier ("_OBJC_STATIC_INSTANCES");
1880 expr_decl = build_nt (ARRAY_REF, ident, NULL_TREE);
1881 decl_spec = tree_cons (NULL_TREE, build_pointer_type (void_type_node),
1882 build_tree_list (NULL_TREE,
1883 ridpointers[(int) RID_STATIC]));
1884 static_instances_decl
1885 = start_decl (expr_decl, decl_spec, 1, NULL_TREE);
1886 TREE_USED (static_instances_decl) = 1;
1887 DECL_CONTEXT (static_instances_decl) = 0;
1888 DECL_ARTIFICIAL (static_instances_decl) = 1;
1889 expr = build_constructor (TREE_TYPE (static_instances_decl),
1891 finish_decl (static_instances_decl, expr, NULL_TREE);
1894 /* Output all strings. */
1899 tree sc_spec, decl_specs, expr_decl;
1900 tree chain, string_expr;
1903 for (chain = class_names_chain; chain; chain = TREE_CHAIN (chain))
1905 string = TREE_VALUE (chain);
1906 decl = TREE_PURPOSE (chain);
1908 = tree_cons (NULL_TREE, ridpointers[(int) RID_STATIC], NULL_TREE);
1909 decl_specs = tree_cons (NULL_TREE, ridpointers[(int) RID_CHAR], sc_spec);
1910 expr_decl = build_nt (ARRAY_REF, DECL_NAME (decl), NULL_TREE);
1911 decl = start_decl (expr_decl, decl_specs, 1, NULL_TREE);
1912 DECL_CONTEXT (decl) = NULL_TREE;
1913 string_expr = my_build_string (IDENTIFIER_LENGTH (string) + 1,
1914 IDENTIFIER_POINTER (string));
1915 finish_decl (decl, string_expr, NULL_TREE);
1918 for (chain = meth_var_names_chain; chain; chain = TREE_CHAIN (chain))
1920 string = TREE_VALUE (chain);
1921 decl = TREE_PURPOSE (chain);
1923 = tree_cons (NULL_TREE, ridpointers[(int) RID_STATIC], NULL_TREE);
1924 decl_specs = tree_cons (NULL_TREE, ridpointers[(int) RID_CHAR], sc_spec);
1925 expr_decl = build_nt (ARRAY_REF, DECL_NAME (decl), NULL_TREE);
1926 decl = start_decl (expr_decl, decl_specs, 1, NULL_TREE);
1927 DECL_CONTEXT (decl) = NULL_TREE;
1928 string_expr = my_build_string (IDENTIFIER_LENGTH (string) + 1,
1929 IDENTIFIER_POINTER (string));
1930 finish_decl (decl, string_expr, NULL_TREE);
1933 for (chain = meth_var_types_chain; chain; chain = TREE_CHAIN (chain))
1935 string = TREE_VALUE (chain);
1936 decl = TREE_PURPOSE (chain);
1938 = tree_cons (NULL_TREE, ridpointers[(int) RID_STATIC], NULL_TREE);
1939 decl_specs = tree_cons (NULL_TREE, ridpointers[(int) RID_CHAR], sc_spec);
1940 expr_decl = build_nt (ARRAY_REF, DECL_NAME (decl), NULL_TREE);
1941 decl = start_decl (expr_decl, decl_specs, 1, NULL_TREE);
1942 DECL_CONTEXT (decl) = NULL_TREE;
1943 string_expr = my_build_string (IDENTIFIER_LENGTH (string) + 1,
1944 IDENTIFIER_POINTER (string));
1945 finish_decl (decl, string_expr, NULL_TREE);
1950 build_selector_reference_decl ()
1956 sprintf (buf, "_OBJC_SELECTOR_REFERENCES_%d", idx++);
1958 ident = get_identifier (buf);
1960 decl = build_decl (VAR_DECL, ident, selector_type);
1961 DECL_EXTERNAL (decl) = 1;
1962 TREE_PUBLIC (decl) = 1;
1963 TREE_USED (decl) = 1;
1964 TREE_READONLY (decl) = 1;
1965 DECL_ARTIFICIAL (decl) = 1;
1966 DECL_CONTEXT (decl) = 0;
1968 make_decl_rtl (decl, 0);
1969 pushdecl_top_level (decl);
1974 /* Just a handy wrapper for add_objc_string. */
1977 build_selector (ident)
1980 tree expr = add_objc_string (ident, meth_var_names);
1981 if (flag_typed_selectors)
1984 return build_c_cast (selector_type, expr); /* cast! */
1988 build_selector_translation_table ()
1990 tree sc_spec, decl_specs;
1991 tree chain, initlist = NULL_TREE;
1993 tree decl = NULL_TREE, var_decl, name;
1995 for (chain = sel_ref_chain; chain; chain = TREE_CHAIN (chain))
1999 expr = build_selector (TREE_VALUE (chain));
2001 if (flag_next_runtime)
2003 name = DECL_NAME (TREE_PURPOSE (chain));
2005 sc_spec = build_tree_list (NULL_TREE, ridpointers[(int) RID_STATIC]);
2007 /* static SEL _OBJC_SELECTOR_REFERENCES_n = ...; */
2008 decl_specs = tree_cons (NULL_TREE, selector_type, sc_spec);
2012 /* The `decl' that is returned from start_decl is the one that we
2013 forward declared in `build_selector_reference' */
2014 decl = start_decl (var_decl, decl_specs, 1, NULL_TREE );
2017 /* add one for the '\0' character */
2018 offset += IDENTIFIER_LENGTH (TREE_VALUE (chain)) + 1;
2020 if (flag_next_runtime)
2021 finish_decl (decl, expr, NULL_TREE);
2024 if (flag_typed_selectors)
2026 tree eltlist = NULL_TREE;
2027 tree encoding = get_proto_encoding (TREE_PURPOSE (chain));
2028 eltlist = tree_cons (NULL_TREE, expr, NULL_TREE);
2029 eltlist = tree_cons (NULL_TREE, encoding, eltlist);
2030 expr = build_constructor (objc_selector_template,
2031 nreverse (eltlist));
2033 initlist = tree_cons (NULL_TREE, expr, initlist);
2038 if (! flag_next_runtime)
2040 /* Cause the variable and its initial value to be actually output. */
2041 DECL_EXTERNAL (UOBJC_SELECTOR_TABLE_decl) = 0;
2042 TREE_STATIC (UOBJC_SELECTOR_TABLE_decl) = 1;
2043 /* NULL terminate the list and fix the decl for output. */
2044 initlist = tree_cons (NULL_TREE, build_int_2 (0, 0), initlist);
2045 DECL_INITIAL (UOBJC_SELECTOR_TABLE_decl) = objc_ellipsis_node;
2046 initlist = build_constructor (TREE_TYPE (UOBJC_SELECTOR_TABLE_decl),
2047 nreverse (initlist));
2048 finish_decl (UOBJC_SELECTOR_TABLE_decl, initlist, NULL_TREE);
2049 current_function_decl = NULL_TREE;
2054 get_proto_encoding (proto)
2062 if (! METHOD_ENCODING (proto))
2064 tmp_decl = build_tmp_function_decl ();
2065 hack_method_prototype (proto, tmp_decl);
2066 encoding = encode_method_prototype (proto, tmp_decl);
2067 METHOD_ENCODING (proto) = encoding;
2070 encoding = METHOD_ENCODING (proto);
2072 return add_objc_string (encoding, meth_var_types);
2075 return build_int_2 (0, 0);
2078 /* sel_ref_chain is a list whose "value" fields will be instances of
2079 identifier_node that represent the selector. */
2082 build_typed_selector_reference (ident, proto)
2085 tree *chain = &sel_ref_chain;
2091 if (TREE_PURPOSE (*chain) == ident && TREE_VALUE (*chain) == proto)
2092 goto return_at_index;
2095 chain = &TREE_CHAIN (*chain);
2098 *chain = tree_cons (proto, ident, NULL_TREE);
2101 expr = build_unary_op (ADDR_EXPR,
2102 build_array_ref (UOBJC_SELECTOR_TABLE_decl,
2103 build_int_2 (index, 0)),
2105 return build_c_cast (selector_type, expr);
2109 build_selector_reference (ident)
2112 tree *chain = &sel_ref_chain;
2118 if (TREE_VALUE (*chain) == ident)
2119 return (flag_next_runtime
2120 ? TREE_PURPOSE (*chain)
2121 : build_array_ref (UOBJC_SELECTOR_TABLE_decl,
2122 build_int_2 (index, 0)));
2125 chain = &TREE_CHAIN (*chain);
2128 expr = build_selector_reference_decl ();
2130 *chain = tree_cons (expr, ident, NULL_TREE);
2132 return (flag_next_runtime
2134 : build_array_ref (UOBJC_SELECTOR_TABLE_decl,
2135 build_int_2 (index, 0)));
2139 build_class_reference_decl ()
2145 sprintf (buf, "_OBJC_CLASS_REFERENCES_%d", idx++);
2147 ident = get_identifier (buf);
2149 decl = build_decl (VAR_DECL, ident, objc_class_type);
2150 DECL_EXTERNAL (decl) = 1;
2151 TREE_PUBLIC (decl) = 1;
2152 TREE_USED (decl) = 1;
2153 TREE_READONLY (decl) = 1;
2154 DECL_CONTEXT (decl) = 0;
2155 DECL_ARTIFICIAL (decl) = 1;
2157 make_decl_rtl (decl, 0);
2158 pushdecl_top_level (decl);
2163 /* Create a class reference, but don't create a variable to reference
2167 add_class_reference (ident)
2172 if ((chain = cls_ref_chain))
2177 if (ident == TREE_VALUE (chain))
2181 chain = TREE_CHAIN (chain);
2185 /* Append to the end of the list */
2186 TREE_CHAIN (tail) = tree_cons (NULL_TREE, ident, NULL_TREE);
2189 cls_ref_chain = tree_cons (NULL_TREE, ident, NULL_TREE);
2192 /* Get a class reference, creating it if necessary. Also create the
2193 reference variable. */
2196 get_class_reference (ident)
2199 if (flag_next_runtime)
2204 for (chain = &cls_ref_chain; *chain; chain = &TREE_CHAIN (*chain))
2205 if (TREE_VALUE (*chain) == ident)
2207 if (! TREE_PURPOSE (*chain))
2208 TREE_PURPOSE (*chain) = build_class_reference_decl ();
2210 return TREE_PURPOSE (*chain);
2213 decl = build_class_reference_decl ();
2214 *chain = tree_cons (decl, ident, NULL_TREE);
2221 add_class_reference (ident);
2223 params = build_tree_list (NULL_TREE,
2224 my_build_string (IDENTIFIER_LENGTH (ident) + 1,
2225 IDENTIFIER_POINTER (ident)));
2227 assemble_external (objc_get_class_decl);
2228 return build_function_call (objc_get_class_decl, params);
2232 /* For each string section we have a chain which maps identifier nodes
2233 to decls for the strings. */
2236 add_objc_string (ident, section)
2238 enum string_section section;
2242 if (section == class_names)
2243 chain = &class_names_chain;
2244 else if (section == meth_var_names)
2245 chain = &meth_var_names_chain;
2246 else if (section == meth_var_types)
2247 chain = &meth_var_types_chain;
2253 if (TREE_VALUE (*chain) == ident)
2254 return build_unary_op (ADDR_EXPR, TREE_PURPOSE (*chain), 1);
2256 chain = &TREE_CHAIN (*chain);
2259 decl = build_objc_string_decl (section);
2261 *chain = tree_cons (decl, ident, NULL_TREE);
2263 return build_unary_op (ADDR_EXPR, decl, 1);
2267 build_objc_string_decl (section)
2268 enum string_section section;
2272 static int class_names_idx = 0;
2273 static int meth_var_names_idx = 0;
2274 static int meth_var_types_idx = 0;
2276 if (section == class_names)
2277 sprintf (buf, "_OBJC_CLASS_NAME_%d", class_names_idx++);
2278 else if (section == meth_var_names)
2279 sprintf (buf, "_OBJC_METH_VAR_NAME_%d", meth_var_names_idx++);
2280 else if (section == meth_var_types)
2281 sprintf (buf, "_OBJC_METH_VAR_TYPE_%d", meth_var_types_idx++);
2283 ident = get_identifier (buf);
2285 decl = build_decl (VAR_DECL, ident, build_array_type (char_type_node, 0));
2286 DECL_EXTERNAL (decl) = 1;
2287 TREE_PUBLIC (decl) = 1;
2288 TREE_USED (decl) = 1;
2289 TREE_READONLY (decl) = 1;
2290 TREE_CONSTANT (decl) = 1;
2291 DECL_CONTEXT (decl) = 0;
2292 DECL_ARTIFICIAL (decl) = 1;
2294 make_decl_rtl (decl, 0);
2295 pushdecl_top_level (decl);
2302 objc_declare_alias (alias_ident, class_ident)
2306 if (is_class_name (class_ident) != class_ident)
2307 warning ("cannot find class `%s'", IDENTIFIER_POINTER (class_ident));
2308 else if (is_class_name (alias_ident))
2309 warning ("class `%s' already exists", IDENTIFIER_POINTER (alias_ident));
2311 alias_chain = tree_cons (class_ident, alias_ident, alias_chain);
2315 objc_declare_class (ident_list)
2320 for (list = ident_list; list; list = TREE_CHAIN (list))
2322 tree ident = TREE_VALUE (list);
2325 if ((decl = lookup_name (ident)))
2327 error ("`%s' redeclared as different kind of symbol",
2328 IDENTIFIER_POINTER (ident));
2329 error_with_decl (decl, "previous declaration of `%s'");
2332 if (! is_class_name (ident))
2334 tree record = xref_tag (RECORD_TYPE, ident);
2335 TREE_STATIC_TEMPLATE (record) = 1;
2336 class_chain = tree_cons (NULL_TREE, ident, class_chain);
2342 is_class_name (ident)
2347 if (lookup_interface (ident))
2350 for (chain = class_chain; chain; chain = TREE_CHAIN (chain))
2352 if (ident == TREE_VALUE (chain))
2356 for (chain = alias_chain; chain; chain = TREE_CHAIN (chain))
2358 if (ident == TREE_VALUE (chain))
2359 return TREE_PURPOSE (chain);
2366 lookup_interface (ident)
2371 for (chain = interface_chain; chain; chain = TREE_CHAIN (chain))
2373 if (ident == CLASS_NAME (chain))
2380 objc_copy_list (list, head)
2384 tree newlist = NULL_TREE, tail = NULL_TREE;
2388 tail = copy_node (list);
2390 /* The following statement fixes a bug when inheriting instance
2391 variables that are declared to be bitfields. finish_struct
2392 expects to find the width of the bitfield in DECL_INITIAL. */
2393 if (DECL_BIT_FIELD (tail) && DECL_INITIAL (tail) == 0)
2394 DECL_INITIAL (tail) = DECL_SIZE (tail);
2396 newlist = chainon (newlist, tail);
2397 list = TREE_CHAIN (list);
2404 /* Used by: build_private_template, get_class_ivars, and
2405 continue_class. COPY is 1 when called from @defs. In this case
2406 copy all fields. Otherwise don't copy leaf ivars since we rely on
2407 them being side-effected exactly once by finish_struct. */
2410 build_ivar_chain (interface, copy)
2414 tree my_name, super_name, ivar_chain;
2416 my_name = CLASS_NAME (interface);
2417 super_name = CLASS_SUPER_NAME (interface);
2419 /* Possibly copy leaf ivars. */
2421 objc_copy_list (CLASS_IVARS (interface), &ivar_chain);
2423 ivar_chain = CLASS_IVARS (interface);
2428 tree super_interface = lookup_interface (super_name);
2430 if (!super_interface)
2432 /* fatal did not work with 2 args...should fix */
2433 error ("cannot find interface declaration for `%s', superclass of `%s'",
2434 IDENTIFIER_POINTER (super_name),
2435 IDENTIFIER_POINTER (my_name));
2436 exit (FATAL_EXIT_CODE);
2439 if (super_interface == interface)
2440 fatal_error ("circular inheritance in interface declaration for `%s'",
2441 IDENTIFIER_POINTER (super_name));
2443 interface = super_interface;
2444 my_name = CLASS_NAME (interface);
2445 super_name = CLASS_SUPER_NAME (interface);
2447 op1 = CLASS_IVARS (interface);
2450 tree head, tail = objc_copy_list (op1, &head);
2452 /* Prepend super class ivars...make a copy of the list, we
2453 do not want to alter the original. */
2454 TREE_CHAIN (tail) = ivar_chain;
2461 /* struct <classname> {
2462 struct objc_class *isa;
2467 build_private_template (class)
2472 if (CLASS_STATIC_TEMPLATE (class))
2474 uprivate_record = CLASS_STATIC_TEMPLATE (class);
2475 ivar_context = TYPE_FIELDS (CLASS_STATIC_TEMPLATE (class));
2479 uprivate_record = start_struct (RECORD_TYPE, CLASS_NAME (class));
2481 ivar_context = build_ivar_chain (class, 0);
2483 finish_struct (uprivate_record, ivar_context, NULL_TREE);
2485 CLASS_STATIC_TEMPLATE (class) = uprivate_record;
2487 /* mark this record as class template - for class type checking */
2488 TREE_STATIC_TEMPLATE (uprivate_record) = 1;
2492 = groktypename (build_tree_list (build_tree_list (NULL_TREE,
2494 build1 (INDIRECT_REF, NULL_TREE,
2497 return ivar_context;
2500 /* Begin code generation for protocols... */
2502 /* struct objc_protocol {
2503 char *protocol_name;
2504 struct objc_protocol **protocol_list;
2505 struct objc_method_desc *instance_methods;
2506 struct objc_method_desc *class_methods;
2510 build_protocol_template ()
2512 tree decl_specs, field_decl, field_decl_chain;
2515 template = start_struct (RECORD_TYPE, get_identifier (UTAG_PROTOCOL));
2517 /* struct objc_class *isa; */
2519 decl_specs = build_tree_list (NULL_TREE, xref_tag (RECORD_TYPE,
2520 get_identifier (UTAG_CLASS)));
2521 field_decl = build1 (INDIRECT_REF, NULL_TREE, get_identifier ("isa"));
2523 = grokfield (input_filename, lineno, field_decl, decl_specs, NULL_TREE);
2524 field_decl_chain = field_decl;
2526 /* char *protocol_name; */
2528 decl_specs = build_tree_list (NULL_TREE, ridpointers[(int) RID_CHAR]);
2530 = build1 (INDIRECT_REF, NULL_TREE, get_identifier ("protocol_name"));
2532 = grokfield (input_filename, lineno, field_decl, decl_specs, NULL_TREE);
2533 chainon (field_decl_chain, field_decl);
2535 /* struct objc_protocol **protocol_list; */
2537 decl_specs = build_tree_list (NULL_TREE, template);
2539 = build1 (INDIRECT_REF, NULL_TREE, get_identifier ("protocol_list"));
2540 field_decl = build1 (INDIRECT_REF, NULL_TREE, field_decl);
2542 = grokfield (input_filename, lineno, field_decl, decl_specs, NULL_TREE);
2543 chainon (field_decl_chain, field_decl);
2545 /* struct objc_method_list *instance_methods; */
2548 = build_tree_list (NULL_TREE,
2549 xref_tag (RECORD_TYPE,
2550 get_identifier (UTAG_METHOD_PROTOTYPE_LIST)));
2552 = build1 (INDIRECT_REF, NULL_TREE, get_identifier ("instance_methods"));
2554 = grokfield (input_filename, lineno, field_decl, decl_specs, NULL_TREE);
2555 chainon (field_decl_chain, field_decl);
2557 /* struct objc_method_list *class_methods; */
2560 = build_tree_list (NULL_TREE,
2561 xref_tag (RECORD_TYPE,
2562 get_identifier (UTAG_METHOD_PROTOTYPE_LIST)));
2564 = build1 (INDIRECT_REF, NULL_TREE, get_identifier ("class_methods"));
2566 = grokfield (input_filename, lineno, field_decl, decl_specs, NULL_TREE);
2567 chainon (field_decl_chain, field_decl);
2569 return finish_struct (template, field_decl_chain, NULL_TREE);
2573 build_descriptor_table_initializer (type, entries)
2577 tree initlist = NULL_TREE;
2581 tree eltlist = NULL_TREE;
2584 = tree_cons (NULL_TREE,
2585 build_selector (METHOD_SEL_NAME (entries)), NULL_TREE);
2587 = tree_cons (NULL_TREE,
2588 add_objc_string (METHOD_ENCODING (entries),
2593 = tree_cons (NULL_TREE,
2594 build_constructor (type, nreverse (eltlist)), initlist);
2596 entries = TREE_CHAIN (entries);
2600 return build_constructor (build_array_type (type, 0), nreverse (initlist));
2603 /* struct objc_method_prototype_list {
2605 struct objc_method_prototype {
2612 build_method_prototype_list_template (list_type, size)
2616 tree objc_ivar_list_record;
2617 tree decl_specs, field_decl, field_decl_chain;
2619 /* Generate an unnamed struct definition. */
2621 objc_ivar_list_record = start_struct (RECORD_TYPE, NULL_TREE);
2623 /* int method_count; */
2625 decl_specs = build_tree_list (NULL_TREE, ridpointers[(int) RID_INT]);
2626 field_decl = get_identifier ("method_count");
2629 = grokfield (input_filename, lineno, field_decl, decl_specs, NULL_TREE);
2630 field_decl_chain = field_decl;
2632 /* struct objc_method method_list[]; */
2634 decl_specs = build_tree_list (NULL_TREE, list_type);
2635 field_decl = build_nt (ARRAY_REF, get_identifier ("method_list"),
2636 build_int_2 (size, 0));
2639 = grokfield (input_filename, lineno, field_decl, decl_specs, NULL_TREE);
2640 chainon (field_decl_chain, field_decl);
2642 finish_struct (objc_ivar_list_record, field_decl_chain, NULL_TREE);
2644 return objc_ivar_list_record;
2648 build_method_prototype_template ()
2651 tree decl_specs, field_decl, field_decl_chain;
2654 = start_struct (RECORD_TYPE, get_identifier (UTAG_METHOD_PROTOTYPE));
2656 /* struct objc_selector *_cmd; */
2657 decl_specs = tree_cons (NULL_TREE, xref_tag (RECORD_TYPE,
2658 get_identifier (TAG_SELECTOR)), NULL_TREE);
2659 field_decl = build1 (INDIRECT_REF, NULL_TREE, get_identifier ("_cmd"));
2662 = grokfield (input_filename, lineno, field_decl, decl_specs, NULL_TREE);
2663 field_decl_chain = field_decl;
2665 decl_specs = tree_cons (NULL_TREE, ridpointers[(int) RID_CHAR], NULL_TREE);
2667 = build1 (INDIRECT_REF, NULL_TREE, get_identifier ("method_types"));
2669 = grokfield (input_filename, lineno, field_decl, decl_specs, NULL_TREE);
2670 chainon (field_decl_chain, field_decl);
2672 finish_struct (proto_record, field_decl_chain, NULL_TREE);
2674 return proto_record;
2677 /* True if last call to forwarding_offset yielded a register offset. */
2678 static int offset_is_register;
2681 forwarding_offset (parm)
2684 int offset_in_bytes;
2686 if (GET_CODE (DECL_INCOMING_RTL (parm)) == MEM)
2688 rtx addr = XEXP (DECL_INCOMING_RTL (parm), 0);
2690 /* ??? Here we assume that the parm address is indexed
2691 off the frame pointer or arg pointer.
2692 If that is not true, we produce meaningless results,
2693 but do not crash. */
2694 if (GET_CODE (addr) == PLUS
2695 && GET_CODE (XEXP (addr, 1)) == CONST_INT)
2696 offset_in_bytes = INTVAL (XEXP (addr, 1));
2698 offset_in_bytes = 0;
2700 offset_in_bytes += OBJC_FORWARDING_STACK_OFFSET;
2701 offset_is_register = 0;
2703 else if (GET_CODE (DECL_INCOMING_RTL (parm)) == REG)
2705 int regno = REGNO (DECL_INCOMING_RTL (parm));
2706 offset_in_bytes = apply_args_register_offset (regno);
2707 offset_is_register = 1;
2712 /* This is the case where the parm is passed as an int or double
2713 and it is converted to a char, short or float and stored back
2714 in the parmlist. In this case, describe the parm
2715 with the variable's declared type, and adjust the address
2716 if the least significant bytes (which we are using) are not
2718 if (BYTES_BIG_ENDIAN && TREE_TYPE (parm) != DECL_ARG_TYPE (parm))
2719 offset_in_bytes += (GET_MODE_SIZE (TYPE_MODE (DECL_ARG_TYPE (parm)))
2720 - GET_MODE_SIZE (GET_MODE (DECL_RTL (parm))));
2722 return offset_in_bytes;
2726 encode_method_prototype (method_decl, func_decl)
2733 HOST_WIDE_INT max_parm_end = 0;
2737 /* ONEWAY and BYCOPY, for remote object are the only method qualifiers. */
2738 encode_type_qualifiers (TREE_PURPOSE (TREE_TYPE (method_decl)));
2741 encode_type (TREE_TYPE (TREE_TYPE (func_decl)),
2742 obstack_object_size (&util_obstack),
2743 OBJC_ENCODE_INLINE_DEFS);
2746 for (parms = DECL_ARGUMENTS (func_decl); parms;
2747 parms = TREE_CHAIN (parms))
2749 HOST_WIDE_INT parm_end = (forwarding_offset (parms)
2750 + int_size_in_bytes (TREE_TYPE (parms)));
2752 if (!offset_is_register && max_parm_end < parm_end)
2753 max_parm_end = parm_end;
2756 stack_size = max_parm_end - OBJC_FORWARDING_MIN_OFFSET;
2758 sprintf (buf, "%d", stack_size);
2759 obstack_grow (&util_obstack, buf, strlen (buf));
2761 user_args = METHOD_SEL_ARGS (method_decl);
2763 /* Argument types. */
2764 for (parms = DECL_ARGUMENTS (func_decl), i = 0; parms;
2765 parms = TREE_CHAIN (parms), i++)
2767 /* Process argument qualifiers for user supplied arguments. */
2770 encode_type_qualifiers (TREE_PURPOSE (TREE_TYPE (user_args)));
2771 user_args = TREE_CHAIN (user_args);
2775 encode_type (TREE_TYPE (parms),
2776 obstack_object_size (&util_obstack),
2777 OBJC_ENCODE_INLINE_DEFS);
2779 /* Compute offset. */
2780 sprintf (buf, "%d", forwarding_offset (parms));
2782 /* Indicate register. */
2783 if (offset_is_register)
2784 obstack_1grow (&util_obstack, '+');
2786 obstack_grow (&util_obstack, buf, strlen (buf));
2789 obstack_1grow (&util_obstack, '\0');
2790 result = get_identifier (obstack_finish (&util_obstack));
2791 obstack_free (&util_obstack, util_firstobj);
2796 generate_descriptor_table (type, name, size, list, proto)
2803 tree sc_spec, decl_specs, decl, initlist;
2805 sc_spec = tree_cons (NULL_TREE, ridpointers[(int) RID_STATIC], NULL_TREE);
2806 decl_specs = tree_cons (NULL_TREE, type, sc_spec);
2808 decl = start_decl (synth_id_with_class_suffix (name, proto),
2809 decl_specs, 1, NULL_TREE);
2810 DECL_CONTEXT (decl) = NULL_TREE;
2812 initlist = build_tree_list (NULL_TREE, build_int_2 (size, 0));
2813 initlist = tree_cons (NULL_TREE, list, initlist);
2815 finish_decl (decl, build_constructor (type, nreverse (initlist)),
2822 generate_method_descriptors (protocol) /* generate_dispatch_tables */
2825 tree initlist, chain, method_list_template;
2826 tree cast, variable_length_type;
2829 if (!objc_method_prototype_template)
2831 objc_method_prototype_template = build_method_prototype_template ();
2834 cast = build_tree_list (build_tree_list (NULL_TREE, xref_tag (RECORD_TYPE,
2835 get_identifier (UTAG_METHOD_PROTOTYPE_LIST))),
2837 variable_length_type = groktypename (cast);
2839 chain = PROTOCOL_CLS_METHODS (protocol);
2842 size = list_length (chain);
2844 method_list_template
2845 = build_method_prototype_list_template (objc_method_prototype_template,
2849 = build_descriptor_table_initializer (objc_method_prototype_template,
2852 UOBJC_CLASS_METHODS_decl
2853 = generate_descriptor_table (method_list_template,
2854 "_OBJC_PROTOCOL_CLASS_METHODS",
2855 size, initlist, protocol);
2856 TREE_TYPE (UOBJC_CLASS_METHODS_decl) = variable_length_type;
2859 UOBJC_CLASS_METHODS_decl = 0;
2861 chain = PROTOCOL_NST_METHODS (protocol);
2864 size = list_length (chain);
2866 method_list_template
2867 = build_method_prototype_list_template (objc_method_prototype_template,
2870 = build_descriptor_table_initializer (objc_method_prototype_template,
2873 UOBJC_INSTANCE_METHODS_decl
2874 = generate_descriptor_table (method_list_template,
2875 "_OBJC_PROTOCOL_INSTANCE_METHODS",
2876 size, initlist, protocol);
2877 TREE_TYPE (UOBJC_INSTANCE_METHODS_decl) = variable_length_type;
2880 UOBJC_INSTANCE_METHODS_decl = 0;
2883 /* Generate a temporary FUNCTION_DECL node to be used in
2884 hack_method_prototype below. */
2887 build_tmp_function_decl ()
2889 tree decl_specs, expr_decl, parms;
2893 /* struct objc_object *objc_xxx (id, SEL, ...); */
2895 decl_specs = build_tree_list (NULL_TREE, objc_object_reference);
2896 push_parm_decl (build_tree_list
2897 (build_tree_list (decl_specs,
2898 build1 (INDIRECT_REF, NULL_TREE,
2902 decl_specs = build_tree_list (NULL_TREE, xref_tag (RECORD_TYPE,
2903 get_identifier (TAG_SELECTOR)));
2904 expr_decl = build1 (INDIRECT_REF, NULL_TREE, NULL_TREE);
2906 push_parm_decl (build_tree_list (build_tree_list (decl_specs, expr_decl),
2908 parms = get_parm_info (0);
2911 decl_specs = build_tree_list (NULL_TREE, objc_object_reference);
2912 sprintf (buffer, "__objc_tmp_%x", xxx++);
2913 expr_decl = build_nt (CALL_EXPR, get_identifier (buffer), parms, NULL_TREE);
2914 expr_decl = build1 (INDIRECT_REF, NULL_TREE, expr_decl);
2916 return define_decl (expr_decl, decl_specs);
2919 /* Generate the prototypes for protocol methods. This is used to
2920 generate method encodings for these.
2922 NST_METHODS is the method to generate a _DECL node for TMP_DECL is
2923 a decl node to be used. This is also where the return value is
2927 hack_method_prototype (nst_methods, tmp_decl)
2934 /* Hack to avoid problem with static typing of self arg. */
2935 TREE_SET_CODE (nst_methods, CLASS_METHOD_DECL);
2936 start_method_def (nst_methods);
2937 TREE_SET_CODE (nst_methods, INSTANCE_METHOD_DECL);
2939 if (METHOD_ADD_ARGS (nst_methods) == objc_ellipsis_node)
2940 parms = get_parm_info (0); /* we have a `, ...' */
2942 parms = get_parm_info (1); /* place a `void_at_end' */
2944 poplevel (0, 0, 0); /* Must be called BEFORE start_function. */
2946 /* Usually called from store_parm_decls -> init_function_start. */
2948 DECL_ARGUMENTS (tmp_decl) = TREE_PURPOSE (parms);
2949 current_function_decl = tmp_decl;
2952 /* Code taken from start_function. */
2953 tree restype = TREE_TYPE (TREE_TYPE (tmp_decl));
2954 /* Promote the value to int before returning it. */
2955 if (TREE_CODE (restype) == INTEGER_TYPE
2956 && TYPE_PRECISION (restype) < TYPE_PRECISION (integer_type_node))
2957 restype = integer_type_node;
2958 DECL_RESULT (tmp_decl) = build_decl (RESULT_DECL, 0, restype);
2961 for (parm = DECL_ARGUMENTS (tmp_decl); parm; parm = TREE_CHAIN (parm))
2962 DECL_CONTEXT (parm) = tmp_decl;
2964 init_function_start (tmp_decl, "objc-act", 0);
2966 /* Typically called from expand_function_start for function definitions. */
2967 assign_parms (tmp_decl);
2969 /* install return type */
2970 TREE_TYPE (TREE_TYPE (tmp_decl)) = groktypename (TREE_TYPE (nst_methods));
2975 generate_protocol_references (plist)
2980 /* Forward declare protocols referenced. */
2981 for (lproto = plist; lproto; lproto = TREE_CHAIN (lproto))
2983 tree proto = TREE_VALUE (lproto);
2985 if (TREE_CODE (proto) == PROTOCOL_INTERFACE_TYPE
2986 && PROTOCOL_NAME (proto))
2988 if (! PROTOCOL_FORWARD_DECL (proto))
2989 build_protocol_reference (proto);
2991 if (PROTOCOL_LIST (proto))
2992 generate_protocol_references (PROTOCOL_LIST (proto));
2998 generate_protocols ()
3000 tree p, tmp_decl, encoding;
3001 tree sc_spec, decl_specs, decl;
3002 tree initlist, protocol_name_expr, refs_decl, refs_expr;
3005 tmp_decl = build_tmp_function_decl ();
3007 if (! objc_protocol_template)
3008 objc_protocol_template = build_protocol_template ();
3010 /* If a protocol was directly referenced, pull in indirect references. */
3011 for (p = protocol_chain; p; p = TREE_CHAIN (p))
3012 if (PROTOCOL_FORWARD_DECL (p) && PROTOCOL_LIST (p))
3013 generate_protocol_references (PROTOCOL_LIST (p));
3015 for (p = protocol_chain; p; p = TREE_CHAIN (p))
3017 tree nst_methods = PROTOCOL_NST_METHODS (p);
3018 tree cls_methods = PROTOCOL_CLS_METHODS (p);
3020 /* If protocol wasn't referenced, don't generate any code. */
3021 if (! PROTOCOL_FORWARD_DECL (p))
3024 /* Make sure we link in the Protocol class. */
3025 add_class_reference (get_identifier (PROTOCOL_OBJECT_CLASS_NAME));
3029 if (! METHOD_ENCODING (nst_methods))
3031 hack_method_prototype (nst_methods, tmp_decl);
3032 encoding = encode_method_prototype (nst_methods, tmp_decl);
3033 METHOD_ENCODING (nst_methods) = encoding;
3035 nst_methods = TREE_CHAIN (nst_methods);
3040 if (! METHOD_ENCODING (cls_methods))
3042 hack_method_prototype (cls_methods, tmp_decl);
3043 encoding = encode_method_prototype (cls_methods, tmp_decl);
3044 METHOD_ENCODING (cls_methods) = encoding;
3047 cls_methods = TREE_CHAIN (cls_methods);
3049 generate_method_descriptors (p);
3051 if (PROTOCOL_LIST (p))
3052 refs_decl = generate_protocol_list (p);
3056 /* static struct objc_protocol _OBJC_PROTOCOL_<mumble>; */
3058 sc_spec = tree_cons (NULL_TREE, ridpointers[(int) RID_STATIC],
3060 decl_specs = tree_cons (NULL_TREE, objc_protocol_template, sc_spec);
3062 decl = start_decl (synth_id_with_class_suffix ("_OBJC_PROTOCOL", p),
3063 decl_specs, 1, NULL_TREE);
3065 DECL_CONTEXT (decl) = NULL_TREE;
3067 protocol_name_expr = add_objc_string (PROTOCOL_NAME (p), class_names);
3073 (build_tree_list (build_tree_list (NULL_TREE,
3074 objc_protocol_template),
3075 build1 (INDIRECT_REF, NULL_TREE,
3076 build1 (INDIRECT_REF, NULL_TREE,
3079 refs_expr = build_unary_op (ADDR_EXPR, refs_decl, 0);
3080 TREE_TYPE (refs_expr) = cast_type2;
3083 refs_expr = build_int_2 (0, 0);
3085 /* UOBJC_INSTANCE_METHODS_decl/UOBJC_CLASS_METHODS_decl are set
3086 by generate_method_descriptors, which is called above. */
3087 initlist = build_protocol_initializer (TREE_TYPE (decl),
3088 protocol_name_expr, refs_expr,
3089 UOBJC_INSTANCE_METHODS_decl,
3090 UOBJC_CLASS_METHODS_decl);
3091 finish_decl (decl, initlist, NULL_TREE);
3093 /* Mark the decl as used to avoid "defined but not used" warning. */
3094 TREE_USED (decl) = 1;
3099 build_protocol_initializer (type, protocol_name, protocol_list,
3100 instance_methods, class_methods)
3104 tree instance_methods;
3107 tree initlist = NULL_TREE, expr;
3110 cast_type = groktypename
3112 (build_tree_list (NULL_TREE,
3113 xref_tag (RECORD_TYPE,
3114 get_identifier (UTAG_CLASS))),
3115 build1 (INDIRECT_REF, NULL_TREE, NULL_TREE)));
3117 /* Filling the "isa" in with one allows the runtime system to
3118 detect that the version change...should remove before final release. */
3120 expr = build_int_2 (PROTOCOL_VERSION, 0);
3121 TREE_TYPE (expr) = cast_type;
3122 initlist = tree_cons (NULL_TREE, expr, initlist);
3123 initlist = tree_cons (NULL_TREE, protocol_name, initlist);
3124 initlist = tree_cons (NULL_TREE, protocol_list, initlist);
3126 if (!instance_methods)
3127 initlist = tree_cons (NULL_TREE, build_int_2 (0, 0), initlist);
3130 expr = build_unary_op (ADDR_EXPR, instance_methods, 0);
3131 initlist = tree_cons (NULL_TREE, expr, initlist);
3135 initlist = tree_cons (NULL_TREE, build_int_2 (0, 0), initlist);
3138 expr = build_unary_op (ADDR_EXPR, class_methods, 0);
3139 initlist = tree_cons (NULL_TREE, expr, initlist);
3142 return build_constructor (type, nreverse (initlist));
3145 /* struct objc_category {
3146 char *category_name;
3148 struct objc_method_list *instance_methods;
3149 struct objc_method_list *class_methods;
3150 struct objc_protocol_list *protocols;
3154 build_category_template ()
3156 tree decl_specs, field_decl, field_decl_chain;
3158 objc_category_template = start_struct (RECORD_TYPE,
3159 get_identifier (UTAG_CATEGORY));
3160 /* char *category_name; */
3162 decl_specs = build_tree_list (NULL_TREE, ridpointers[(int) RID_CHAR]);
3164 = build1 (INDIRECT_REF, NULL_TREE, get_identifier ("category_name"));
3166 = grokfield (input_filename, lineno, field_decl, decl_specs, NULL_TREE);
3167 field_decl_chain = field_decl;
3169 /* char *class_name; */
3171 decl_specs = build_tree_list (NULL_TREE, ridpointers[(int) RID_CHAR]);
3172 field_decl = build1 (INDIRECT_REF, NULL_TREE, get_identifier ("class_name"));
3174 = grokfield (input_filename, lineno, field_decl, decl_specs, NULL_TREE);
3175 chainon (field_decl_chain, field_decl);
3177 /* struct objc_method_list *instance_methods; */
3179 decl_specs = build_tree_list (NULL_TREE,
3180 xref_tag (RECORD_TYPE,
3181 get_identifier (UTAG_METHOD_LIST)));
3183 = build1 (INDIRECT_REF, NULL_TREE, get_identifier ("instance_methods"));
3185 = grokfield (input_filename, lineno, field_decl, decl_specs, NULL_TREE);
3186 chainon (field_decl_chain, field_decl);
3188 /* struct objc_method_list *class_methods; */
3190 decl_specs = build_tree_list (NULL_TREE,
3191 xref_tag (RECORD_TYPE,
3192 get_identifier (UTAG_METHOD_LIST)));
3194 = build1 (INDIRECT_REF, NULL_TREE, get_identifier ("class_methods"));
3196 = grokfield (input_filename, lineno, field_decl, decl_specs, NULL_TREE);
3197 chainon (field_decl_chain, field_decl);
3199 /* struct objc_protocol **protocol_list; */
3201 decl_specs = build_tree_list (NULL_TREE,
3202 xref_tag (RECORD_TYPE,
3203 get_identifier (UTAG_PROTOCOL)));
3205 = build1 (INDIRECT_REF, NULL_TREE, get_identifier ("protocol_list"));
3206 field_decl = build1 (INDIRECT_REF, NULL_TREE, field_decl);
3208 = grokfield (input_filename, lineno, field_decl, decl_specs, NULL_TREE);
3209 chainon (field_decl_chain, field_decl);
3211 finish_struct (objc_category_template, field_decl_chain, NULL_TREE);
3214 /* struct objc_selector {
3220 build_selector_template ()
3223 tree decl_specs, field_decl, field_decl_chain;
3225 objc_selector_template
3226 = start_struct (RECORD_TYPE, get_identifier (UTAG_SELECTOR));
3230 decl_specs = build_tree_list (NULL_TREE, ridpointers[(int) RID_VOID]);
3231 field_decl = build1 (INDIRECT_REF, NULL_TREE, get_identifier ("sel_id"));
3233 = grokfield (input_filename, lineno, field_decl, decl_specs, NULL_TREE);
3234 field_decl_chain = field_decl;
3236 /* char *sel_type; */
3238 decl_specs = build_tree_list (NULL_TREE, ridpointers[(int) RID_CHAR]);
3239 field_decl = build1 (INDIRECT_REF, NULL_TREE, get_identifier ("sel_type"));
3241 = grokfield (input_filename, lineno, field_decl, decl_specs, NULL_TREE);
3242 chainon (field_decl_chain, field_decl);
3244 finish_struct (objc_selector_template, field_decl_chain, NULL_TREE);
3247 /* struct objc_class {
3248 struct objc_class *isa;
3249 struct objc_class *super_class;
3254 struct objc_ivar_list *ivars;
3255 struct objc_method_list *methods;
3256 if (flag_next_runtime)
3257 struct objc_cache *cache;
3259 struct sarray *dtable;
3260 struct objc_class *subclass_list;
3261 struct objc_class *sibling_class;
3263 struct objc_protocol_list *protocols;
3264 void *gc_object_type;
3268 build_class_template ()
3270 tree decl_specs, field_decl, field_decl_chain;
3273 = start_struct (RECORD_TYPE, get_identifier (UTAG_CLASS));
3275 /* struct objc_class *isa; */
3277 decl_specs = build_tree_list (NULL_TREE, objc_class_template);
3278 field_decl = build1 (INDIRECT_REF, NULL_TREE, get_identifier ("isa"));
3280 = grokfield (input_filename, lineno, field_decl, decl_specs, NULL_TREE);
3281 field_decl_chain = field_decl;
3283 /* struct objc_class *super_class; */
3285 decl_specs = build_tree_list (NULL_TREE, objc_class_template);
3287 = build1 (INDIRECT_REF, NULL_TREE, get_identifier ("super_class"));
3289 = grokfield (input_filename, lineno, field_decl, decl_specs, NULL_TREE);
3290 chainon (field_decl_chain, field_decl);
3294 decl_specs = build_tree_list (NULL_TREE, ridpointers[(int) RID_CHAR]);
3295 field_decl = build1 (INDIRECT_REF, NULL_TREE, get_identifier ("name"));
3297 = grokfield (input_filename, lineno, field_decl, decl_specs, NULL_TREE);
3298 chainon (field_decl_chain, field_decl);
3302 decl_specs = build_tree_list (NULL_TREE, ridpointers[(int) RID_LONG]);
3303 field_decl = get_identifier ("version");
3305 = grokfield (input_filename, lineno, field_decl, decl_specs, NULL_TREE);
3306 chainon (field_decl_chain, field_decl);
3310 decl_specs = build_tree_list (NULL_TREE, ridpointers[(int) RID_LONG]);
3311 field_decl = get_identifier ("info");
3313 = grokfield (input_filename, lineno, field_decl, decl_specs, NULL_TREE);
3314 chainon (field_decl_chain, field_decl);
3316 /* long instance_size; */
3318 decl_specs = build_tree_list (NULL_TREE, ridpointers[(int) RID_LONG]);
3319 field_decl = get_identifier ("instance_size");
3321 = grokfield (input_filename, lineno, field_decl, decl_specs, NULL_TREE);
3322 chainon (field_decl_chain, field_decl);
3324 /* struct objc_ivar_list *ivars; */
3326 decl_specs = build_tree_list (NULL_TREE,
3327 xref_tag (RECORD_TYPE,
3328 get_identifier (UTAG_IVAR_LIST)));
3329 field_decl = build1 (INDIRECT_REF, NULL_TREE, get_identifier ("ivars"));
3331 = grokfield (input_filename, lineno, field_decl, decl_specs, NULL_TREE);
3332 chainon (field_decl_chain, field_decl);
3334 /* struct objc_method_list *methods; */
3336 decl_specs = build_tree_list (NULL_TREE,
3337 xref_tag (RECORD_TYPE,
3338 get_identifier (UTAG_METHOD_LIST)));
3339 field_decl = build1 (INDIRECT_REF, NULL_TREE, get_identifier ("methods"));
3341 = grokfield (input_filename, lineno, field_decl, decl_specs, NULL_TREE);
3342 chainon (field_decl_chain, field_decl);
3344 if (flag_next_runtime)
3346 /* struct objc_cache *cache; */
3348 decl_specs = build_tree_list (NULL_TREE,
3349 xref_tag (RECORD_TYPE,
3350 get_identifier ("objc_cache")));
3351 field_decl = build1 (INDIRECT_REF, NULL_TREE, get_identifier ("cache"));
3352 field_decl = grokfield (input_filename, lineno, field_decl,
3353 decl_specs, NULL_TREE);
3354 chainon (field_decl_chain, field_decl);
3358 /* struct sarray *dtable; */
3360 decl_specs = build_tree_list (NULL_TREE,
3361 xref_tag (RECORD_TYPE,
3362 get_identifier ("sarray")));
3363 field_decl = build1 (INDIRECT_REF, NULL_TREE, get_identifier ("dtable"));
3364 field_decl = grokfield (input_filename, lineno, field_decl,
3365 decl_specs, NULL_TREE);
3366 chainon (field_decl_chain, field_decl);
3368 /* struct objc_class *subclass_list; */
3370 decl_specs = build_tree_list (NULL_TREE, objc_class_template);
3372 = build1 (INDIRECT_REF, NULL_TREE, get_identifier ("subclass_list"));
3373 field_decl = grokfield (input_filename, lineno, field_decl,
3374 decl_specs, NULL_TREE);
3375 chainon (field_decl_chain, field_decl);
3377 /* struct objc_class *sibling_class; */
3379 decl_specs = build_tree_list (NULL_TREE, objc_class_template);
3381 = build1 (INDIRECT_REF, NULL_TREE, get_identifier ("sibling_class"));
3382 field_decl = grokfield (input_filename, lineno, field_decl,
3383 decl_specs, NULL_TREE);
3384 chainon (field_decl_chain, field_decl);
3387 /* struct objc_protocol **protocol_list; */
3389 decl_specs = build_tree_list (NULL_TREE,
3390 xref_tag (RECORD_TYPE,
3391 get_identifier (UTAG_PROTOCOL)));
3393 = build1 (INDIRECT_REF, NULL_TREE, get_identifier ("protocol_list"));
3395 = build1 (INDIRECT_REF, NULL_TREE, field_decl);
3396 field_decl = grokfield (input_filename, lineno, field_decl,
3397 decl_specs, NULL_TREE);
3398 chainon (field_decl_chain, field_decl);
3402 decl_specs = build_tree_list (NULL_TREE, ridpointers[(int) RID_VOID]);
3403 field_decl = build1 (INDIRECT_REF, NULL_TREE, get_identifier ("sel_id"));
3405 = grokfield (input_filename, lineno, field_decl, decl_specs, NULL_TREE);
3406 chainon (field_decl_chain, field_decl);
3408 /* void *gc_object_type; */
3410 decl_specs = build_tree_list (NULL_TREE, ridpointers[(int) RID_VOID]);
3411 field_decl = build1 (INDIRECT_REF, NULL_TREE, get_identifier ("gc_object_type"));
3413 = grokfield (input_filename, lineno, field_decl, decl_specs, NULL_TREE);
3414 chainon (field_decl_chain, field_decl);
3416 finish_struct (objc_class_template, field_decl_chain, NULL_TREE);
3419 /* Generate appropriate forward declarations for an implementation. */
3422 synth_forward_declarations ()
3424 tree sc_spec, decl_specs, an_id;
3426 /* extern struct objc_class _OBJC_CLASS_<my_name>; */
3428 an_id = synth_id_with_class_suffix ("_OBJC_CLASS", objc_implementation_context);
3430 sc_spec = build_tree_list (NULL_TREE, ridpointers[(int) RID_EXTERN]);
3431 decl_specs = tree_cons (NULL_TREE, objc_class_template, sc_spec);
3432 UOBJC_CLASS_decl = define_decl (an_id, decl_specs);
3433 TREE_USED (UOBJC_CLASS_decl) = 1;
3434 DECL_ARTIFICIAL (UOBJC_CLASS_decl) = 1;
3436 /* extern struct objc_class _OBJC_METACLASS_<my_name>; */
3438 an_id = synth_id_with_class_suffix ("_OBJC_METACLASS",
3439 objc_implementation_context);
3441 UOBJC_METACLASS_decl = define_decl (an_id, decl_specs);
3442 TREE_USED (UOBJC_METACLASS_decl) = 1;
3443 DECL_ARTIFICIAL(UOBJC_METACLASS_decl) = 1;
3445 /* Pre-build the following entities - for speed/convenience. */
3447 an_id = get_identifier ("super_class");
3448 ucls_super_ref = build_component_ref (UOBJC_CLASS_decl, an_id);
3449 uucls_super_ref = build_component_ref (UOBJC_METACLASS_decl, an_id);
3453 error_with_ivar (message, decl, rawdecl)
3454 const char *message;
3460 report_error_function (DECL_SOURCE_FILE (decl));
3462 error_with_file_and_line (DECL_SOURCE_FILE (decl),
3463 DECL_SOURCE_LINE (decl),
3465 message, gen_declaration (rawdecl, errbuf));
3469 #define USERTYPE(t) \
3470 (TREE_CODE (t) == RECORD_TYPE || TREE_CODE (t) == UNION_TYPE \
3471 || TREE_CODE (t) == ENUMERAL_TYPE)
3474 check_ivars (inter, imp)
3478 tree intdecls = CLASS_IVARS (inter);
3479 tree impdecls = CLASS_IVARS (imp);
3480 tree rawintdecls = CLASS_RAW_IVARS (inter);
3481 tree rawimpdecls = CLASS_RAW_IVARS (imp);
3487 if (intdecls == 0 && impdecls == 0)
3489 if (intdecls == 0 || impdecls == 0)
3491 error ("inconsistent instance variable specification");
3495 t1 = TREE_TYPE (intdecls); t2 = TREE_TYPE (impdecls);
3497 if (!comptypes (t1, t2))
3499 if (DECL_NAME (intdecls) == DECL_NAME (impdecls))
3501 error_with_ivar ("conflicting instance variable type",
3502 impdecls, rawimpdecls);
3503 error_with_ivar ("previous declaration of",
3504 intdecls, rawintdecls);
3506 else /* both the type and the name don't match */
3508 error ("inconsistent instance variable specification");
3513 else if (DECL_NAME (intdecls) != DECL_NAME (impdecls))
3515 error_with_ivar ("conflicting instance variable name",
3516 impdecls, rawimpdecls);
3517 error_with_ivar ("previous declaration of",
3518 intdecls, rawintdecls);
3521 intdecls = TREE_CHAIN (intdecls);
3522 impdecls = TREE_CHAIN (impdecls);
3523 rawintdecls = TREE_CHAIN (rawintdecls);
3524 rawimpdecls = TREE_CHAIN (rawimpdecls);
3528 /* Set super_type to the data type node for struct objc_super *,
3529 first defining struct objc_super itself.
3530 This needs to be done just once per compilation. */
3533 build_super_template ()
3535 tree record, decl_specs, field_decl, field_decl_chain;
3537 record = start_struct (RECORD_TYPE, get_identifier (UTAG_SUPER));
3539 /* struct objc_object *self; */
3541 decl_specs = build_tree_list (NULL_TREE, objc_object_reference);
3542 field_decl = get_identifier ("self");
3543 field_decl = build1 (INDIRECT_REF, NULL_TREE, field_decl);
3544 field_decl = grokfield (input_filename, lineno,
3545 field_decl, decl_specs, NULL_TREE);
3546 field_decl_chain = field_decl;
3548 /* struct objc_class *class; */
3550 decl_specs = get_identifier (UTAG_CLASS);
3551 decl_specs = build_tree_list (NULL_TREE, xref_tag (RECORD_TYPE, decl_specs));
3552 field_decl = build1 (INDIRECT_REF, NULL_TREE, get_identifier ("class"));
3554 field_decl = grokfield (input_filename, lineno,
3555 field_decl, decl_specs, NULL_TREE);
3556 chainon (field_decl_chain, field_decl);
3558 finish_struct (record, field_decl_chain, NULL_TREE);
3560 /* `struct objc_super *' */
3561 super_type = groktypename (build_tree_list (build_tree_list (NULL_TREE,
3563 build1 (INDIRECT_REF,
3564 NULL_TREE, NULL_TREE)));
3568 /* struct objc_ivar {
3575 build_ivar_template ()
3577 tree objc_ivar_id, objc_ivar_record;
3578 tree decl_specs, field_decl, field_decl_chain;
3580 objc_ivar_id = get_identifier (UTAG_IVAR);
3581 objc_ivar_record = start_struct (RECORD_TYPE, objc_ivar_id);
3583 /* char *ivar_name; */
3585 decl_specs = build_tree_list (NULL_TREE, ridpointers[(int) RID_CHAR]);
3586 field_decl = build1 (INDIRECT_REF, NULL_TREE, get_identifier ("ivar_name"));
3588 field_decl = grokfield (input_filename, lineno, field_decl,
3589 decl_specs, NULL_TREE);
3590 field_decl_chain = field_decl;
3592 /* char *ivar_type; */
3594 decl_specs = build_tree_list (NULL_TREE, ridpointers[(int) RID_CHAR]);
3595 field_decl = build1 (INDIRECT_REF, NULL_TREE, get_identifier ("ivar_type"));
3597 field_decl = grokfield (input_filename, lineno, field_decl,
3598 decl_specs, NULL_TREE);
3599 chainon (field_decl_chain, field_decl);
3601 /* int ivar_offset; */
3603 decl_specs = build_tree_list (NULL_TREE, ridpointers[(int) RID_INT]);
3604 field_decl = get_identifier ("ivar_offset");
3606 field_decl = grokfield (input_filename, lineno, field_decl,
3607 decl_specs, NULL_TREE);
3608 chainon (field_decl_chain, field_decl);
3610 finish_struct (objc_ivar_record, field_decl_chain, NULL_TREE);
3612 return objc_ivar_record;
3617 struct objc_ivar ivar_list[ivar_count];
3621 build_ivar_list_template (list_type, size)
3625 tree objc_ivar_list_record;
3626 tree decl_specs, field_decl, field_decl_chain;
3628 objc_ivar_list_record = start_struct (RECORD_TYPE, NULL_TREE);
3630 /* int ivar_count; */
3632 decl_specs = build_tree_list (NULL_TREE, ridpointers[(int) RID_INT]);
3633 field_decl = get_identifier ("ivar_count");
3635 field_decl = grokfield (input_filename, lineno, field_decl,
3636 decl_specs, NULL_TREE);
3637 field_decl_chain = field_decl;
3639 /* struct objc_ivar ivar_list[]; */
3641 decl_specs = build_tree_list (NULL_TREE, list_type);
3642 field_decl = build_nt (ARRAY_REF, get_identifier ("ivar_list"),
3643 build_int_2 (size, 0));
3645 field_decl = grokfield (input_filename, lineno,
3646 field_decl, decl_specs, NULL_TREE);
3647 chainon (field_decl_chain, field_decl);
3649 finish_struct (objc_ivar_list_record, field_decl_chain, NULL_TREE);
3651 return objc_ivar_list_record;
3657 struct objc_method method_list[method_count];
3661 build_method_list_template (list_type, size)
3665 tree objc_ivar_list_record;
3666 tree decl_specs, field_decl, field_decl_chain;
3668 objc_ivar_list_record = start_struct (RECORD_TYPE, NULL_TREE);
3670 /* int method_next; */
3675 xref_tag (RECORD_TYPE,
3676 get_identifier (UTAG_METHOD_PROTOTYPE_LIST)));
3678 = build1 (INDIRECT_REF, NULL_TREE, get_identifier ("method_next"));
3679 field_decl = grokfield (input_filename, lineno, field_decl,
3680 decl_specs, NULL_TREE);
3681 field_decl_chain = field_decl;
3683 /* int method_count; */
3685 decl_specs = build_tree_list (NULL_TREE, ridpointers[(int) RID_INT]);
3686 field_decl = get_identifier ("method_count");
3688 field_decl = grokfield (input_filename, lineno,
3689 field_decl, decl_specs, NULL_TREE);
3690 chainon (field_decl_chain, field_decl);
3692 /* struct objc_method method_list[]; */
3694 decl_specs = build_tree_list (NULL_TREE, list_type);
3695 field_decl = build_nt (ARRAY_REF, get_identifier ("method_list"),
3696 build_int_2 (size, 0));
3698 field_decl = grokfield (input_filename, lineno,
3699 field_decl, decl_specs, NULL_TREE);
3700 chainon (field_decl_chain, field_decl);
3702 finish_struct (objc_ivar_list_record, field_decl_chain, NULL_TREE);
3704 return objc_ivar_list_record;
3708 build_ivar_list_initializer (type, field_decl)
3712 tree initlist = NULL_TREE;
3716 tree ivar = NULL_TREE;
3719 if (DECL_NAME (field_decl))
3720 ivar = tree_cons (NULL_TREE,
3721 add_objc_string (DECL_NAME (field_decl),
3725 /* Unnamed bit-field ivar (yuck). */
3726 ivar = tree_cons (NULL_TREE, build_int_2 (0, 0), ivar);
3729 encode_field_decl (field_decl,
3730 obstack_object_size (&util_obstack),
3731 OBJC_ENCODE_DONT_INLINE_DEFS);
3733 /* Null terminate string. */
3734 obstack_1grow (&util_obstack, 0);
3738 add_objc_string (get_identifier (obstack_finish (&util_obstack)),
3741 obstack_free (&util_obstack, util_firstobj);
3744 ivar = tree_cons (NULL_TREE, byte_position (field_decl), ivar);
3745 initlist = tree_cons (NULL_TREE,
3746 build_constructor (type, nreverse (ivar)),
3749 field_decl = TREE_CHAIN (field_decl);
3753 return build_constructor (build_array_type (type, 0), nreverse (initlist));
3757 generate_ivars_list (type, name, size, list)
3763 tree sc_spec, decl_specs, decl, initlist;
3765 sc_spec = tree_cons (NULL_TREE, ridpointers[(int) RID_STATIC], NULL_TREE);
3766 decl_specs = tree_cons (NULL_TREE, type, sc_spec);
3768 decl = start_decl (synth_id_with_class_suffix (name, objc_implementation_context),
3769 decl_specs, 1, NULL_TREE);
3771 initlist = build_tree_list (NULL_TREE, build_int_2 (size, 0));
3772 initlist = tree_cons (NULL_TREE, list, initlist);
3775 build_constructor (TREE_TYPE (decl), nreverse (initlist)),
3782 generate_ivar_lists ()
3784 tree initlist, ivar_list_template, chain;
3785 tree cast, variable_length_type;
3788 generating_instance_variables = 1;
3790 if (!objc_ivar_template)
3791 objc_ivar_template = build_ivar_template ();
3795 (build_tree_list (NULL_TREE, xref_tag (RECORD_TYPE,
3796 get_identifier (UTAG_IVAR_LIST))),
3798 variable_length_type = groktypename (cast);
3800 /* Only generate class variables for the root of the inheritance
3801 hierarchy since these will be the same for every class. */
3803 if (CLASS_SUPER_NAME (implementation_template) == NULL_TREE
3804 && (chain = TYPE_FIELDS (objc_class_template)))
3806 size = list_length (chain);
3808 ivar_list_template = build_ivar_list_template (objc_ivar_template, size);
3809 initlist = build_ivar_list_initializer (objc_ivar_template, chain);
3811 UOBJC_CLASS_VARIABLES_decl
3812 = generate_ivars_list (ivar_list_template, "_OBJC_CLASS_VARIABLES",
3814 TREE_TYPE (UOBJC_CLASS_VARIABLES_decl) = variable_length_type;
3817 UOBJC_CLASS_VARIABLES_decl = 0;
3819 chain = CLASS_IVARS (implementation_template);
3822 size = list_length (chain);
3823 ivar_list_template = build_ivar_list_template (objc_ivar_template, size);
3824 initlist = build_ivar_list_initializer (objc_ivar_template, chain);
3826 UOBJC_INSTANCE_VARIABLES_decl
3827 = generate_ivars_list (ivar_list_template, "_OBJC_INSTANCE_VARIABLES",
3829 TREE_TYPE (UOBJC_INSTANCE_VARIABLES_decl) = variable_length_type;
3832 UOBJC_INSTANCE_VARIABLES_decl = 0;
3834 generating_instance_variables = 0;
3838 build_dispatch_table_initializer (type, entries)
3842 tree initlist = NULL_TREE;
3846 tree elemlist = NULL_TREE;
3848 elemlist = tree_cons (NULL_TREE,
3849 build_selector (METHOD_SEL_NAME (entries)),
3852 elemlist = tree_cons (NULL_TREE,
3853 add_objc_string (METHOD_ENCODING (entries),
3857 elemlist = tree_cons (NULL_TREE,
3858 build_unary_op (ADDR_EXPR,
3859 METHOD_DEFINITION (entries), 1),
3862 initlist = tree_cons (NULL_TREE,
3863 build_constructor (type, nreverse (elemlist)),
3866 entries = TREE_CHAIN (entries);
3870 return build_constructor (build_array_type (type, 0), nreverse (initlist));
3873 /* To accomplish method prototyping without generating all kinds of
3874 inane warnings, the definition of the dispatch table entries were
3877 struct objc_method { SEL _cmd; ...; id (*_imp)(); };
3879 struct objc_method { SEL _cmd; ...; void *_imp; }; */
3882 build_method_template ()
3885 tree decl_specs, field_decl, field_decl_chain;
3887 _SLT_record = start_struct (RECORD_TYPE, get_identifier (UTAG_METHOD));
3889 /* struct objc_selector *_cmd; */
3890 decl_specs = tree_cons (NULL_TREE,
3891 xref_tag (RECORD_TYPE,
3892 get_identifier (TAG_SELECTOR)),
3894 field_decl = build1 (INDIRECT_REF, NULL_TREE, get_identifier ("_cmd"));
3896 field_decl = grokfield (input_filename, lineno, field_decl,
3897 decl_specs, NULL_TREE);
3898 field_decl_chain = field_decl;
3900 decl_specs = tree_cons (NULL_TREE, ridpointers[(int) RID_CHAR], NULL_TREE);
3901 field_decl = build1 (INDIRECT_REF, NULL_TREE,
3902 get_identifier ("method_types"));
3903 field_decl = grokfield (input_filename, lineno, field_decl,
3904 decl_specs, NULL_TREE);
3905 chainon (field_decl_chain, field_decl);
3909 decl_specs = tree_cons (NULL_TREE, ridpointers[(int) RID_VOID], NULL_TREE);
3910 field_decl = build1 (INDIRECT_REF, NULL_TREE, get_identifier ("_imp"));
3911 field_decl = grokfield (input_filename, lineno, field_decl,
3912 decl_specs, NULL_TREE);
3913 chainon (field_decl_chain, field_decl);
3915 finish_struct (_SLT_record, field_decl_chain, NULL_TREE);
3922 generate_dispatch_table (type, name, size, list)
3928 tree sc_spec, decl_specs, decl, initlist;
3930 sc_spec = tree_cons (NULL_TREE, ridpointers[(int) RID_STATIC], NULL_TREE);
3931 decl_specs = tree_cons (NULL_TREE, type, sc_spec);
3933 decl = start_decl (synth_id_with_class_suffix (name, objc_implementation_context),
3934 decl_specs, 1, NULL_TREE);
3936 initlist = build_tree_list (NULL_TREE, build_int_2 (0, 0));
3937 initlist = tree_cons (NULL_TREE, build_int_2 (size, 0), initlist);
3938 initlist = tree_cons (NULL_TREE, list, initlist);
3941 build_constructor (TREE_TYPE (decl), nreverse (initlist)),
3948 generate_dispatch_tables ()
3950 tree initlist, chain, method_list_template;
3951 tree cast, variable_length_type;
3954 if (!objc_method_template)
3955 objc_method_template = build_method_template ();
3959 (build_tree_list (NULL_TREE,
3960 xref_tag (RECORD_TYPE,
3961 get_identifier (UTAG_METHOD_LIST))),
3964 variable_length_type = groktypename (cast);
3966 chain = CLASS_CLS_METHODS (objc_implementation_context);
3969 size = list_length (chain);
3971 method_list_template
3972 = build_method_list_template (objc_method_template, size);
3974 = build_dispatch_table_initializer (objc_method_template, chain);
3976 UOBJC_CLASS_METHODS_decl
3977 = generate_dispatch_table (method_list_template,
3978 ((TREE_CODE (objc_implementation_context)
3979 == CLASS_IMPLEMENTATION_TYPE)
3980 ? "_OBJC_CLASS_METHODS"
3981 : "_OBJC_CATEGORY_CLASS_METHODS"),
3983 TREE_TYPE (UOBJC_CLASS_METHODS_decl) = variable_length_type;
3986 UOBJC_CLASS_METHODS_decl = 0;
3988 chain = CLASS_NST_METHODS (objc_implementation_context);
3991 size = list_length (chain);
3993 method_list_template
3994 = build_method_list_template (objc_method_template, size);
3996 = build_dispatch_table_initializer (objc_method_template, chain);
3998 if (TREE_CODE (objc_implementation_context) == CLASS_IMPLEMENTATION_TYPE)
3999 UOBJC_INSTANCE_METHODS_decl
4000 = generate_dispatch_table (method_list_template,
4001 "_OBJC_INSTANCE_METHODS",
4004 /* We have a category. */
4005 UOBJC_INSTANCE_METHODS_decl
4006 = generate_dispatch_table (method_list_template,
4007 "_OBJC_CATEGORY_INSTANCE_METHODS",
4009 TREE_TYPE (UOBJC_INSTANCE_METHODS_decl) = variable_length_type;
4012 UOBJC_INSTANCE_METHODS_decl = 0;
4016 generate_protocol_list (i_or_p)
4019 tree initlist, decl_specs, sc_spec;
4020 tree refs_decl, expr_decl, lproto, e, plist;
4024 if (TREE_CODE (i_or_p) == CLASS_INTERFACE_TYPE
4025 || TREE_CODE (i_or_p) == CATEGORY_INTERFACE_TYPE)
4026 plist = CLASS_PROTOCOL_LIST (i_or_p);
4027 else if (TREE_CODE (i_or_p) == PROTOCOL_INTERFACE_TYPE)
4028 plist = PROTOCOL_LIST (i_or_p);
4032 cast_type = groktypename
4034 (build_tree_list (NULL_TREE,
4035 xref_tag (RECORD_TYPE,
4036 get_identifier (UTAG_PROTOCOL))),
4037 build1 (INDIRECT_REF, NULL_TREE, NULL_TREE)));
4040 for (lproto = plist; lproto; lproto = TREE_CHAIN (lproto))
4041 if (TREE_CODE (TREE_VALUE (lproto)) == PROTOCOL_INTERFACE_TYPE
4042 && PROTOCOL_FORWARD_DECL (TREE_VALUE (lproto)))
4045 /* Build initializer. */
4046 initlist = tree_cons (NULL_TREE, build_int_2 (0, 0), NULL_TREE);
4048 e = build_int_2 (size, 0);
4049 TREE_TYPE (e) = cast_type;
4050 initlist = tree_cons (NULL_TREE, e, initlist);
4052 for (lproto = plist; lproto; lproto = TREE_CHAIN (lproto))
4054 tree pval = TREE_VALUE (lproto);
4056 if (TREE_CODE (pval) == PROTOCOL_INTERFACE_TYPE
4057 && PROTOCOL_FORWARD_DECL (pval))
4059 e = build_unary_op (ADDR_EXPR, PROTOCOL_FORWARD_DECL (pval), 0);
4060 initlist = tree_cons (NULL_TREE, e, initlist);
4064 /* static struct objc_protocol *refs[n]; */
4066 sc_spec = tree_cons (NULL_TREE, ridpointers[(int) RID_STATIC], NULL_TREE);
4067 decl_specs = tree_cons (NULL_TREE, xref_tag (RECORD_TYPE,
4068 get_identifier (UTAG_PROTOCOL)),
4071 if (TREE_CODE (i_or_p) == PROTOCOL_INTERFACE_TYPE)
4072 expr_decl = build_nt (ARRAY_REF,
4073 synth_id_with_class_suffix ("_OBJC_PROTOCOL_REFS",
4075 build_int_2 (size + 2, 0));
4076 else if (TREE_CODE (i_or_p) == CLASS_INTERFACE_TYPE)
4077 expr_decl = build_nt (ARRAY_REF,
4078 synth_id_with_class_suffix ("_OBJC_CLASS_PROTOCOLS",
4080 build_int_2 (size + 2, 0));
4081 else if (TREE_CODE (i_or_p) == CATEGORY_INTERFACE_TYPE)
4083 = build_nt (ARRAY_REF,
4084 synth_id_with_class_suffix ("_OBJC_CATEGORY_PROTOCOLS",
4086 build_int_2 (size + 2, 0));
4090 expr_decl = build1 (INDIRECT_REF, NULL_TREE, expr_decl);
4092 refs_decl = start_decl (expr_decl, decl_specs, 1, NULL_TREE);
4093 DECL_CONTEXT (refs_decl) = NULL_TREE;
4095 finish_decl (refs_decl, build_constructor (TREE_TYPE (refs_decl),
4096 nreverse (initlist)),
4103 build_category_initializer (type, cat_name, class_name,
4104 instance_methods, class_methods, protocol_list)
4108 tree instance_methods;
4112 tree initlist = NULL_TREE, expr;
4114 initlist = tree_cons (NULL_TREE, cat_name, initlist);
4115 initlist = tree_cons (NULL_TREE, class_name, initlist);
4117 if (!instance_methods)
4118 initlist = tree_cons (NULL_TREE, build_int_2 (0, 0), initlist);
4121 expr = build_unary_op (ADDR_EXPR, instance_methods, 0);
4122 initlist = tree_cons (NULL_TREE, expr, initlist);
4125 initlist = tree_cons (NULL_TREE, build_int_2 (0, 0), initlist);
4128 expr = build_unary_op (ADDR_EXPR, class_methods, 0);
4129 initlist = tree_cons (NULL_TREE, expr, initlist);
4132 /* protocol_list = */
4134 initlist = tree_cons (NULL_TREE, build_int_2 (0, 0), initlist);
4137 tree cast_type2 = groktypename
4139 (build_tree_list (NULL_TREE,
4140 xref_tag (RECORD_TYPE,
4141 get_identifier (UTAG_PROTOCOL))),
4142 build1 (INDIRECT_REF, NULL_TREE,
4143 build1 (INDIRECT_REF, NULL_TREE, NULL_TREE))));
4145 expr = build_unary_op (ADDR_EXPR, protocol_list, 0);
4146 TREE_TYPE (expr) = cast_type2;
4147 initlist = tree_cons (NULL_TREE, expr, initlist);
4150 return build_constructor (type, nreverse (initlist));
4153 /* struct objc_class {
4154 struct objc_class *isa;
4155 struct objc_class *super_class;
4160 struct objc_ivar_list *ivars;
4161 struct objc_method_list *methods;
4162 if (flag_next_runtime)
4163 struct objc_cache *cache;
4165 struct sarray *dtable;
4166 struct objc_class *subclass_list;
4167 struct objc_class *sibling_class;
4169 struct objc_protocol_list *protocols;
4170 void *gc_object_type;
4174 build_shared_structure_initializer (type, isa, super, name, size, status,
4175 dispatch_table, ivar_list, protocol_list)
4182 tree dispatch_table;
4186 tree initlist = NULL_TREE, expr;
4189 initlist = tree_cons (NULL_TREE, isa, initlist);
4192 initlist = tree_cons (NULL_TREE, super, initlist);
4195 initlist = tree_cons (NULL_TREE, default_conversion (name), initlist);
4198 initlist = tree_cons (NULL_TREE, build_int_2 (0, 0), initlist);
4201 initlist = tree_cons (NULL_TREE, build_int_2 (status, 0), initlist);
4203 /* instance_size = */
4204 initlist = tree_cons (NULL_TREE, size, initlist);
4206 /* objc_ivar_list = */
4208 initlist = tree_cons (NULL_TREE, build_int_2 (0, 0), initlist);
4211 expr = build_unary_op (ADDR_EXPR, ivar_list, 0);
4212 initlist = tree_cons (NULL_TREE, expr, initlist);
4215 /* objc_method_list = */
4216 if (!dispatch_table)
4217 initlist = tree_cons (NULL_TREE, build_int_2 (0, 0), initlist);
4220 expr = build_unary_op (ADDR_EXPR, dispatch_table, 0);
4221 initlist = tree_cons (NULL_TREE, expr, initlist);
4224 if (flag_next_runtime)
4225 /* method_cache = */
4226 initlist = tree_cons (NULL_TREE, build_int_2 (0, 0), initlist);
4230 initlist = tree_cons (NULL_TREE, build_int_2 (0, 0), initlist);
4232 /* subclass_list = */
4233 initlist = tree_cons (NULL_TREE, build_int_2 (0, 0), initlist);
4235 /* sibling_class = */
4236 initlist = tree_cons (NULL_TREE, build_int_2 (0, 0), initlist);
4239 /* protocol_list = */
4240 if (! protocol_list)
4241 initlist = tree_cons (NULL_TREE, build_int_2 (0, 0), initlist);
4247 (build_tree_list (NULL_TREE,
4248 xref_tag (RECORD_TYPE,
4249 get_identifier (UTAG_PROTOCOL))),
4250 build1 (INDIRECT_REF, NULL_TREE,
4251 build1 (INDIRECT_REF, NULL_TREE, NULL_TREE))));
4253 expr = build_unary_op (ADDR_EXPR, protocol_list, 0);
4254 TREE_TYPE (expr) = cast_type2;
4255 initlist = tree_cons (NULL_TREE, expr, initlist);
4258 /* gc_object_type = NULL */
4259 initlist = tree_cons (NULL_TREE, build_int_2 (0, 0), initlist);
4261 return build_constructor (type, nreverse (initlist));
4264 /* static struct objc_category _OBJC_CATEGORY_<name> = { ... }; */
4267 generate_category (cat)
4270 tree sc_spec, decl_specs, decl;
4271 tree initlist, cat_name_expr, class_name_expr;
4272 tree protocol_decl, category;
4274 add_class_reference (CLASS_NAME (cat));
4275 cat_name_expr = add_objc_string (CLASS_SUPER_NAME (cat), class_names);
4277 class_name_expr = add_objc_string (CLASS_NAME (cat), class_names);
4279 category = CLASS_CATEGORY_LIST (implementation_template);
4281 /* find the category interface from the class it is associated with */
4284 if (CLASS_SUPER_NAME (cat) == CLASS_SUPER_NAME (category))
4286 category = CLASS_CATEGORY_LIST (category);
4289 if (category && CLASS_PROTOCOL_LIST (category))
4291 generate_protocol_references (CLASS_PROTOCOL_LIST (category));
4292 protocol_decl = generate_protocol_list (category);
4297 sc_spec = tree_cons (NULL_TREE, ridpointers[(int) RID_STATIC], NULL_TREE);
4298 decl_specs = tree_cons (NULL_TREE, objc_category_template, sc_spec);
4300 decl = start_decl (synth_id_with_class_suffix ("_OBJC_CATEGORY",
4301 objc_implementation_context),
4302 decl_specs, 1, NULL_TREE);
4304 initlist = build_category_initializer (TREE_TYPE (decl),
4305 cat_name_expr, class_name_expr,
4306 UOBJC_INSTANCE_METHODS_decl,
4307 UOBJC_CLASS_METHODS_decl,
4310 TREE_USED (decl) = 1;
4311 finish_decl (decl, initlist, NULL_TREE);
4314 /* static struct objc_class _OBJC_METACLASS_Foo={ ... };
4315 static struct objc_class _OBJC_CLASS_Foo={ ... }; */
4318 generate_shared_structures ()
4320 tree sc_spec, decl_specs, decl;
4321 tree name_expr, super_expr, root_expr;
4322 tree my_root_id = NULL_TREE, my_super_id = NULL_TREE;
4323 tree cast_type, initlist, protocol_decl;
4325 my_super_id = CLASS_SUPER_NAME (implementation_template);
4328 add_class_reference (my_super_id);
4330 /* Compute "my_root_id" - this is required for code generation.
4331 the "isa" for all meta class structures points to the root of
4332 the inheritance hierarchy (e.g. "__Object")... */
4333 my_root_id = my_super_id;
4336 tree my_root_int = lookup_interface (my_root_id);
4338 if (my_root_int && CLASS_SUPER_NAME (my_root_int))
4339 my_root_id = CLASS_SUPER_NAME (my_root_int);
4346 /* No super class. */
4347 my_root_id = CLASS_NAME (implementation_template);
4350 = groktypename (build_tree_list (build_tree_list (NULL_TREE,
4351 objc_class_template),
4352 build1 (INDIRECT_REF,
4353 NULL_TREE, NULL_TREE)));
4355 name_expr = add_objc_string (CLASS_NAME (implementation_template),
4358 /* Install class `isa' and `super' pointers at runtime. */
4361 super_expr = add_objc_string (my_super_id, class_names);
4362 super_expr = build_c_cast (cast_type, super_expr); /* cast! */
4365 super_expr = build_int_2 (0, 0);
4367 root_expr = add_objc_string (my_root_id, class_names);
4368 root_expr = build_c_cast (cast_type, root_expr); /* cast! */
4370 if (CLASS_PROTOCOL_LIST (implementation_template))
4372 generate_protocol_references
4373 (CLASS_PROTOCOL_LIST (implementation_template));
4374 protocol_decl = generate_protocol_list (implementation_template);
4379 /* static struct objc_class _OBJC_METACLASS_Foo = { ... }; */
4381 sc_spec = build_tree_list (NULL_TREE, ridpointers[(int) RID_STATIC]);
4382 decl_specs = tree_cons (NULL_TREE, objc_class_template, sc_spec);
4384 decl = start_decl (DECL_NAME (UOBJC_METACLASS_decl), decl_specs, 1,
4388 = build_shared_structure_initializer
4390 root_expr, super_expr, name_expr,
4391 convert (integer_type_node, TYPE_SIZE_UNIT (objc_class_template)),
4393 UOBJC_CLASS_METHODS_decl,
4394 UOBJC_CLASS_VARIABLES_decl,
4397 finish_decl (decl, initlist, NULL_TREE);
4399 /* static struct objc_class _OBJC_CLASS_Foo={ ... }; */
4401 decl = start_decl (DECL_NAME (UOBJC_CLASS_decl), decl_specs, 1,
4405 = build_shared_structure_initializer
4407 build_unary_op (ADDR_EXPR, UOBJC_METACLASS_decl, 0),
4408 super_expr, name_expr,
4409 convert (integer_type_node,
4410 TYPE_SIZE_UNIT (CLASS_STATIC_TEMPLATE
4411 (implementation_template))),
4413 UOBJC_INSTANCE_METHODS_decl,
4414 UOBJC_INSTANCE_VARIABLES_decl,
4417 finish_decl (decl, initlist, NULL_TREE);
4421 synth_id_with_class_suffix (preamble, ctxt)
4422 const char *preamble;
4426 if (TREE_CODE (ctxt) == CLASS_IMPLEMENTATION_TYPE
4427 || TREE_CODE (ctxt) == CLASS_INTERFACE_TYPE)
4429 const char *const class_name
4430 = IDENTIFIER_POINTER (CLASS_NAME (objc_implementation_context));
4431 string = (char *) alloca (strlen (preamble) + strlen (class_name) + 3);
4432 sprintf (string, "%s_%s", preamble,
4433 IDENTIFIER_POINTER (CLASS_NAME (ctxt)));
4435 else if (TREE_CODE (ctxt) == CATEGORY_IMPLEMENTATION_TYPE
4436 || TREE_CODE (ctxt) == CATEGORY_INTERFACE_TYPE)
4438 /* We have a category. */
4439 const char *const class_name
4440 = IDENTIFIER_POINTER (CLASS_NAME (objc_implementation_context));
4441 const char *const class_super_name
4442 = IDENTIFIER_POINTER (CLASS_SUPER_NAME (objc_implementation_context));
4443 string = (char *) alloca (strlen (preamble)
4444 + strlen (class_name)
4445 + strlen (class_super_name)
4447 sprintf (string, "%s_%s_%s", preamble, class_name, class_super_name);
4449 else if (TREE_CODE (ctxt) == PROTOCOL_INTERFACE_TYPE)
4451 const char *protocol_name = IDENTIFIER_POINTER (PROTOCOL_NAME (ctxt));
4453 = (char *) alloca (strlen (preamble) + strlen (protocol_name) + 3);
4454 sprintf (string, "%s_%s", preamble, protocol_name);
4459 return get_identifier (string);
4463 is_objc_type_qualifier (node)
4466 return (TREE_CODE (node) == IDENTIFIER_NODE
4467 && (node == ridpointers [(int) RID_CONST]
4468 || node == ridpointers [(int) RID_VOLATILE]
4469 || node == ridpointers [(int) RID_IN]
4470 || node == ridpointers [(int) RID_OUT]
4471 || node == ridpointers [(int) RID_INOUT]
4472 || node == ridpointers [(int) RID_BYCOPY]
4473 || node == ridpointers [(int) RID_BYREF]
4474 || node == ridpointers [(int) RID_ONEWAY]));
4477 /* If type is empty or only type qualifiers are present, add default
4478 type of id (otherwise grokdeclarator will default to int). */
4481 adjust_type_for_id_default (type)
4484 tree declspecs, chain;
4487 return build_tree_list (build_tree_list (NULL_TREE, objc_object_reference),
4488 build1 (INDIRECT_REF, NULL_TREE, NULL_TREE));
4490 declspecs = TREE_PURPOSE (type);
4492 /* Determine if a typespec is present. */
4493 for (chain = declspecs;
4495 chain = TREE_CHAIN (chain))
4497 if (!is_objc_type_qualifier (TREE_VALUE (chain)))
4501 return build_tree_list (tree_cons (NULL_TREE, objc_object_reference,
4503 build1 (INDIRECT_REF, NULL_TREE, NULL_TREE));
4508 selector ':' '(' typename ')' identifier
4511 Transform an Objective-C keyword argument into
4512 the C equivalent parameter declarator.
4514 In: key_name, an "identifier_node" (optional).
4515 arg_type, a "tree_list" (optional).
4516 arg_name, an "identifier_node".
4518 Note: It would be really nice to strongly type the preceding
4519 arguments in the function prototype; however, then I
4520 could not use the "accessor" macros defined in "tree.h".
4522 Out: an instance of "keyword_decl". */
4525 build_keyword_decl (key_name, arg_type, arg_name)
4532 /* If no type is specified, default to "id". */
4533 arg_type = adjust_type_for_id_default (arg_type);
4535 keyword_decl = make_node (KEYWORD_DECL);
4537 TREE_TYPE (keyword_decl) = arg_type;
4538 KEYWORD_ARG_NAME (keyword_decl) = arg_name;
4539 KEYWORD_KEY_NAME (keyword_decl) = key_name;
4541 return keyword_decl;
4544 /* Given a chain of keyword_decl's, synthesize the full keyword selector. */
4547 build_keyword_selector (selector)
4551 tree key_chain, key_name;
4554 /* Scan the selector to see how much space we'll need. */
4555 for (key_chain = selector; key_chain; key_chain = TREE_CHAIN (key_chain))
4557 if (TREE_CODE (selector) == KEYWORD_DECL)
4558 key_name = KEYWORD_KEY_NAME (key_chain);
4559 else if (TREE_CODE (selector) == TREE_LIST)
4560 key_name = TREE_PURPOSE (key_chain);
4565 len += IDENTIFIER_LENGTH (key_name) + 1;
4567 /* Just a ':' arg. */
4571 buf = (char *) alloca (len + 1);
4572 /* Start the buffer out as an empty string. */
4575 for (key_chain = selector; key_chain; key_chain = TREE_CHAIN (key_chain))
4577 if (TREE_CODE (selector) == KEYWORD_DECL)
4578 key_name = KEYWORD_KEY_NAME (key_chain);
4579 else if (TREE_CODE (selector) == TREE_LIST)
4580 key_name = TREE_PURPOSE (key_chain);
4585 strcat (buf, IDENTIFIER_POINTER (key_name));
4589 return get_identifier (buf);
4592 /* Used for declarations and definitions. */
4595 build_method_decl (code, ret_type, selector, add_args)
4596 enum tree_code code;
4603 /* If no type is specified, default to "id". */
4604 ret_type = adjust_type_for_id_default (ret_type);
4606 method_decl = make_node (code);
4607 TREE_TYPE (method_decl) = ret_type;
4609 /* If we have a keyword selector, create an identifier_node that
4610 represents the full selector name (`:' included)... */
4611 if (TREE_CODE (selector) == KEYWORD_DECL)
4613 METHOD_SEL_NAME (method_decl) = build_keyword_selector (selector);
4614 METHOD_SEL_ARGS (method_decl) = selector;
4615 METHOD_ADD_ARGS (method_decl) = add_args;
4619 METHOD_SEL_NAME (method_decl) = selector;
4620 METHOD_SEL_ARGS (method_decl) = NULL_TREE;
4621 METHOD_ADD_ARGS (method_decl) = NULL_TREE;
4627 #define METHOD_DEF 0
4628 #define METHOD_REF 1
4630 /* Used by `build_objc_method_call' and `comp_method_types'. Return
4631 an argument list for method METH. CONTEXT is either METHOD_DEF or
4632 METHOD_REF, saying whether we are trying to define a method or call
4633 one. SUPERFLAG says this is for a send to super; this makes a
4634 difference for the NeXT calling sequence in which the lookup and
4635 the method call are done together. */
4638 get_arg_type_list (meth, context, superflag)
4645 /* Receiver type. */
4646 if (flag_next_runtime && superflag)
4647 arglist = build_tree_list (NULL_TREE, super_type);
4648 else if (context == METHOD_DEF)
4649 arglist = build_tree_list (NULL_TREE, TREE_TYPE (self_decl));
4651 arglist = build_tree_list (NULL_TREE, id_type);
4653 /* Selector type - will eventually change to `int'. */
4654 chainon (arglist, build_tree_list (NULL_TREE, selector_type));
4656 /* Build a list of argument types. */
4657 for (akey = METHOD_SEL_ARGS (meth); akey; akey = TREE_CHAIN (akey))
4659 tree arg_decl = groktypename_in_parm_context (TREE_TYPE (akey));
4660 chainon (arglist, build_tree_list (NULL_TREE, TREE_TYPE (arg_decl)));
4663 if (METHOD_ADD_ARGS (meth) == objc_ellipsis_node)
4664 /* We have a `, ...' immediately following the selector,
4665 finalize the arglist...simulate get_parm_info (0). */
4667 else if (METHOD_ADD_ARGS (meth))
4669 /* we have a variable length selector */
4670 tree add_arg_list = TREE_CHAIN (METHOD_ADD_ARGS (meth));
4671 chainon (arglist, add_arg_list);
4674 /* finalize the arglist...simulate get_parm_info (1) */
4675 chainon (arglist, build_tree_list (NULL_TREE, void_type_node));
4681 check_duplicates (hsh)
4684 tree meth = NULL_TREE;
4692 /* We have two methods with the same name and different types. */
4694 char type = (TREE_CODE (meth) == INSTANCE_METHOD_DECL) ? '-' : '+';
4696 warning ("multiple declarations for method `%s'",
4697 IDENTIFIER_POINTER (METHOD_SEL_NAME (meth)));
4699 warn_with_method ("using", type, meth);
4700 for (loop = hsh->list; loop; loop = loop->next)
4701 warn_with_method ("also found", type, loop->value);
4707 /* If RECEIVER is a class reference, return the identifier node for
4708 the referenced class. RECEIVER is created by get_class_reference,
4709 so we check the exact form created depending on which runtimes are
4713 receiver_is_class_object (receiver)
4716 tree chain, exp, arg;
4718 /* The receiver is 'self' in the context of a class method. */
4719 if (objc_method_context
4720 && receiver == self_decl
4721 && TREE_CODE (objc_method_context) == CLASS_METHOD_DECL)
4723 return CLASS_NAME (objc_implementation_context);
4726 if (flag_next_runtime)
4728 /* The receiver is a variable created by
4729 build_class_reference_decl. */
4730 if (TREE_CODE (receiver) == VAR_DECL
4731 && TREE_TYPE (receiver) == objc_class_type)
4732 /* Look up the identifier. */
4733 for (chain = cls_ref_chain; chain; chain = TREE_CHAIN (chain))
4734 if (TREE_PURPOSE (chain) == receiver)
4735 return TREE_VALUE (chain);
4739 /* The receiver is a function call that returns an id. Check if
4740 it is a call to objc_getClass, if so, pick up the class name. */
4741 if (TREE_CODE (receiver) == CALL_EXPR
4742 && (exp = TREE_OPERAND (receiver, 0))
4743 && TREE_CODE (exp) == ADDR_EXPR
4744 && (exp = TREE_OPERAND (exp, 0))
4745 && TREE_CODE (exp) == FUNCTION_DECL
4746 && exp == objc_get_class_decl
4747 /* We have a call to objc_getClass! */
4748 && (arg = TREE_OPERAND (receiver, 1))
4749 && TREE_CODE (arg) == TREE_LIST
4750 && (arg = TREE_VALUE (arg)))
4753 if (TREE_CODE (arg) == ADDR_EXPR
4754 && (arg = TREE_OPERAND (arg, 0))
4755 && TREE_CODE (arg) == STRING_CST)
4756 /* Finally, we have the class name. */
4757 return get_identifier (TREE_STRING_POINTER (arg));
4763 /* If we are currently building a message expr, this holds
4764 the identifier of the selector of the message. This is
4765 used when printing warnings about argument mismatches. */
4767 static tree building_objc_message_expr = 0;
4770 maybe_building_objc_message_expr ()
4772 return building_objc_message_expr;
4775 /* Construct an expression for sending a message.
4776 MESS has the object to send to in TREE_PURPOSE
4777 and the argument list (including selector) in TREE_VALUE.
4779 (*(<abstract_decl>(*)())_msg)(receiver, selTransTbl[n], ...);
4780 (*(<abstract_decl>(*)())_msgSuper)(receiver, selTransTbl[n], ...); */
4783 build_message_expr (mess)
4786 tree receiver = TREE_PURPOSE (mess);
4788 tree args = TREE_VALUE (mess);
4789 tree method_params = NULL_TREE;
4791 if (TREE_CODE (receiver) == ERROR_MARK)
4792 return error_mark_node;
4794 /* Obtain the full selector name. */
4795 if (TREE_CODE (args) == IDENTIFIER_NODE)
4796 /* A unary selector. */
4798 else if (TREE_CODE (args) == TREE_LIST)
4799 sel_name = build_keyword_selector (args);
4803 /* Build the parameter list to give to the method. */
4804 if (TREE_CODE (args) == TREE_LIST)
4806 tree chain = args, prev = NULL_TREE;
4808 /* We have a keyword selector--check for comma expressions. */
4811 tree element = TREE_VALUE (chain);
4813 /* We have a comma expression, must collapse... */
4814 if (TREE_CODE (element) == TREE_LIST)
4817 TREE_CHAIN (prev) = element;
4822 chain = TREE_CHAIN (chain);
4824 method_params = args;
4827 return finish_message_expr (receiver, sel_name, method_params);
4830 /* The 'finish_message_expr' routine is called from within
4831 'build_message_expr' for non-template functions. In the case of
4832 C++ template functions, it is called from 'build_expr_from_tree'
4833 (in decl2.c) after RECEIVER and METHOD_PARAMS have been expanded. */
4836 finish_message_expr (receiver, sel_name, method_params)
4837 tree receiver, sel_name, method_params;
4839 tree method_prototype = NULL_TREE, class_ident = NULL_TREE;
4840 tree selector, self_object, retval;
4841 int statically_typed = 0, statically_allocated = 0;
4843 /* Determine receiver type. */
4844 tree rtype = TREE_TYPE (receiver);
4845 int super = IS_SUPER (rtype);
4849 if (TREE_STATIC_TEMPLATE (rtype))
4850 statically_allocated = 1;
4851 else if (TREE_CODE (rtype) == POINTER_TYPE
4852 && TREE_STATIC_TEMPLATE (TREE_TYPE (rtype)))
4853 statically_typed = 1;
4854 else if ((flag_next_runtime
4856 && (class_ident = receiver_is_class_object (receiver)))))
4858 else if (! IS_ID (rtype)
4859 /* Allow any type that matches objc_class_type. */
4860 && ! comptypes (rtype, objc_class_type))
4862 warning ("invalid receiver type `%s'",
4863 gen_declaration (rtype, errbuf));
4865 if (statically_allocated)
4866 receiver = build_unary_op (ADDR_EXPR, receiver, 0);
4868 /* Don't evaluate the receiver twice. */
4869 receiver = save_expr (receiver);
4870 self_object = receiver;
4873 /* If sending to `super', use current self as the object. */
4874 self_object = self_decl;
4876 /* Determine operation return type. */
4882 if (CLASS_SUPER_NAME (implementation_template))
4885 = lookup_interface (CLASS_SUPER_NAME (implementation_template));
4887 if (TREE_CODE (objc_method_context) == INSTANCE_METHOD_DECL)
4888 method_prototype = lookup_instance_method_static (iface, sel_name);
4890 method_prototype = lookup_class_method_static (iface, sel_name);
4892 if (iface && !method_prototype)
4893 warning ("`%s' does not respond to `%s'",
4894 IDENTIFIER_POINTER (CLASS_SUPER_NAME (implementation_template)),
4895 IDENTIFIER_POINTER (sel_name));
4899 error ("no super class declared in interface for `%s'",
4900 IDENTIFIER_POINTER (CLASS_NAME (implementation_template)));
4901 return error_mark_node;
4905 else if (statically_allocated)
4907 tree ctype = TREE_TYPE (rtype);
4908 tree iface = lookup_interface (TYPE_NAME (rtype));
4911 method_prototype = lookup_instance_method_static (iface, sel_name);
4913 if (! method_prototype && TYPE_PROTOCOL_LIST (ctype))
4915 = lookup_method_in_protocol_list (TYPE_PROTOCOL_LIST (ctype),
4918 if (!method_prototype)
4919 warning ("`%s' does not respond to `%s'",
4920 IDENTIFIER_POINTER (TYPE_NAME (rtype)),
4921 IDENTIFIER_POINTER (sel_name));
4923 else if (statically_typed)
4925 tree ctype = TREE_TYPE (rtype);
4927 /* `self' is now statically_typed. All methods should be visible
4928 within the context of the implementation. */
4929 if (objc_implementation_context
4930 && CLASS_NAME (objc_implementation_context) == TYPE_NAME (ctype))
4933 = lookup_instance_method_static (implementation_template,
4936 if (! method_prototype && TYPE_PROTOCOL_LIST (ctype))
4938 = lookup_method_in_protocol_list (TYPE_PROTOCOL_LIST (ctype),
4941 if (! method_prototype
4942 && implementation_template != objc_implementation_context)
4943 /* The method is not published in the interface. Check
4946 = lookup_method (CLASS_NST_METHODS (objc_implementation_context),
4953 if ((iface = lookup_interface (TYPE_NAME (ctype))))
4954 method_prototype = lookup_instance_method_static (iface, sel_name);
4956 if (! method_prototype)
4958 tree protocol_list = TYPE_PROTOCOL_LIST (ctype);
4961 = lookup_method_in_protocol_list (protocol_list,
4966 if (!method_prototype)
4967 warning ("`%s' does not respond to `%s'",
4968 IDENTIFIER_POINTER (TYPE_NAME (ctype)),
4969 IDENTIFIER_POINTER (sel_name));
4971 else if (class_ident)
4973 if (objc_implementation_context
4974 && CLASS_NAME (objc_implementation_context) == class_ident)
4977 = lookup_class_method_static (implementation_template, sel_name);
4979 if (!method_prototype
4980 && implementation_template != objc_implementation_context)
4981 /* The method is not published in the interface. Check
4984 = lookup_method (CLASS_CLS_METHODS (objc_implementation_context),
4991 if ((iface = lookup_interface (class_ident)))
4992 method_prototype = lookup_class_method_static (iface, sel_name);
4995 if (!method_prototype)
4997 warning ("cannot find class (factory) method");
4998 warning ("return type for `%s' defaults to id",
4999 IDENTIFIER_POINTER (sel_name));
5002 else if (IS_PROTOCOL_QUALIFIED_ID (rtype))
5004 /* An anonymous object that has been qualified with a protocol. */
5006 tree protocol_list = TYPE_PROTOCOL_LIST (rtype);
5008 method_prototype = lookup_method_in_protocol_list (protocol_list,
5011 if (!method_prototype)
5015 warning ("method `%s' not implemented by protocol",
5016 IDENTIFIER_POINTER (sel_name));
5018 /* Try and find the method signature in the global pools. */
5020 if (!(hsh = hash_lookup (nst_method_hash_list, sel_name)))
5021 hsh = hash_lookup (cls_method_hash_list, sel_name);
5023 if (!(method_prototype = check_duplicates (hsh)))
5024 warning ("return type defaults to id");
5031 /* We think we have an instance...loophole: extern id Object; */
5032 hsh = hash_lookup (nst_method_hash_list, sel_name);
5035 /* For various loopholes */
5036 hsh = hash_lookup (cls_method_hash_list, sel_name);
5038 method_prototype = check_duplicates (hsh);
5039 if (!method_prototype)
5041 warning ("cannot find method");
5042 warning ("return type for `%s' defaults to id",
5043 IDENTIFIER_POINTER (sel_name));
5047 /* Save the selector name for printing error messages. */
5048 building_objc_message_expr = sel_name;
5050 /* Build the parameters list for looking up the method.
5051 These are the object itself and the selector. */
5053 if (flag_typed_selectors)
5054 selector = build_typed_selector_reference (sel_name, method_prototype);
5056 selector = build_selector_reference (sel_name);
5058 retval = build_objc_method_call (super, method_prototype,
5059 receiver, self_object,
5060 selector, method_params);
5062 building_objc_message_expr = 0;
5067 /* Build a tree expression to send OBJECT the operation SELECTOR,
5068 looking up the method on object LOOKUP_OBJECT (often same as OBJECT),
5069 assuming the method has prototype METHOD_PROTOTYPE.
5070 (That is an INSTANCE_METHOD_DECL or CLASS_METHOD_DECL.)
5071 Use METHOD_PARAMS as list of args to pass to the method.
5072 If SUPER_FLAG is nonzero, we look up the superclass's method. */
5075 build_objc_method_call (super_flag, method_prototype, lookup_object, object,
5076 selector, method_params)
5078 tree method_prototype, lookup_object, object, selector, method_params;
5080 tree sender = (super_flag ? umsg_super_decl : umsg_decl);
5081 tree rcv_p = (super_flag
5082 ? build_pointer_type (xref_tag (RECORD_TYPE,
5083 get_identifier (TAG_SUPER)))
5086 if (flag_next_runtime)
5088 if (! method_prototype)
5090 method_params = tree_cons (NULL_TREE, lookup_object,
5091 tree_cons (NULL_TREE, selector,
5093 assemble_external (sender);
5094 return build_function_call (sender, method_params);
5098 /* This is a real kludge, but it is used only for the Next.
5099 Clobber the data type of SENDER temporarily to accept
5100 all the arguments for this operation, and to return
5101 whatever this operation returns. */
5102 tree arglist = NULL_TREE, retval, savarg, savret;
5103 tree ret_type = groktypename (TREE_TYPE (method_prototype));
5105 /* Save the proper contents of SENDER's data type. */
5106 savarg = TYPE_ARG_TYPES (TREE_TYPE (sender));
5107 savret = TREE_TYPE (TREE_TYPE (sender));
5109 /* Install this method's argument types. */
5110 arglist = get_arg_type_list (method_prototype, METHOD_REF,
5112 TYPE_ARG_TYPES (TREE_TYPE (sender)) = arglist;
5114 /* Install this method's return type. */
5115 TREE_TYPE (TREE_TYPE (sender)) = ret_type;
5117 /* Call SENDER with all the parameters. This will do type
5118 checking using the arg types for this method. */
5119 method_params = tree_cons (NULL_TREE, lookup_object,
5120 tree_cons (NULL_TREE, selector,
5122 assemble_external (sender);
5123 retval = build_function_call (sender, method_params);
5125 /* Restore SENDER's return/argument types. */
5126 TYPE_ARG_TYPES (TREE_TYPE (sender)) = savarg;
5127 TREE_TYPE (TREE_TYPE (sender)) = savret;
5133 /* This is the portable way.
5134 First call the lookup function to get a pointer to the method,
5135 then cast the pointer, then call it with the method arguments. */
5138 /* Avoid trouble since we may evaluate each of these twice. */
5139 object = save_expr (object);
5140 selector = save_expr (selector);
5142 lookup_object = build_c_cast (rcv_p, lookup_object);
5144 assemble_external (sender);
5146 = build_function_call (sender,
5147 tree_cons (NULL_TREE, lookup_object,
5148 tree_cons (NULL_TREE, selector,
5151 /* If we have a method prototype, construct the data type this
5152 method needs, and cast what we got from SENDER into a pointer
5154 if (method_prototype)
5156 tree arglist = get_arg_type_list (method_prototype, METHOD_REF,
5158 tree valtype = groktypename (TREE_TYPE (method_prototype));
5159 tree fake_function_type = build_function_type (valtype, arglist);
5160 TREE_TYPE (method) = build_pointer_type (fake_function_type);
5164 = build_pointer_type (build_function_type (ptr_type_node, NULL_TREE));
5166 /* Pass the object to the method. */
5167 assemble_external (method);
5168 return build_function_call (method,
5169 tree_cons (NULL_TREE, object,
5170 tree_cons (NULL_TREE, selector,
5176 build_protocol_reference (p)
5179 tree decl, ident, ptype;
5181 /* extern struct objc_protocol _OBJC_PROTOCOL_<mumble>; */
5183 ident = synth_id_with_class_suffix ("_OBJC_PROTOCOL", p);
5185 = groktypename (build_tree_list (build_tree_list (NULL_TREE,
5186 objc_protocol_template),
5189 if (IDENTIFIER_GLOBAL_VALUE (ident))
5190 decl = IDENTIFIER_GLOBAL_VALUE (ident); /* Set by pushdecl. */
5193 decl = build_decl (VAR_DECL, ident, ptype);
5194 DECL_EXTERNAL (decl) = 1;
5195 TREE_PUBLIC (decl) = 1;
5196 TREE_USED (decl) = 1;
5197 DECL_ARTIFICIAL (decl) = 1;
5199 make_decl_rtl (decl, 0);
5200 pushdecl_top_level (decl);
5203 PROTOCOL_FORWARD_DECL (p) = decl;
5207 build_protocol_expr (protoname)
5211 tree p = lookup_protocol (protoname);
5215 error ("cannot find protocol declaration for `%s'",
5216 IDENTIFIER_POINTER (protoname));
5217 return error_mark_node;
5220 if (!PROTOCOL_FORWARD_DECL (p))
5221 build_protocol_reference (p);
5223 expr = build_unary_op (ADDR_EXPR, PROTOCOL_FORWARD_DECL (p), 0);
5225 TREE_TYPE (expr) = protocol_type;
5231 build_selector_expr (selnamelist)
5236 /* Obtain the full selector name. */
5237 if (TREE_CODE (selnamelist) == IDENTIFIER_NODE)
5238 /* A unary selector. */
5239 selname = selnamelist;
5240 else if (TREE_CODE (selnamelist) == TREE_LIST)
5241 selname = build_keyword_selector (selnamelist);
5245 if (flag_typed_selectors)
5246 return build_typed_selector_reference (selname, 0);
5248 return build_selector_reference (selname);
5252 build_encode_expr (type)
5258 encode_type (type, obstack_object_size (&util_obstack),
5259 OBJC_ENCODE_INLINE_DEFS);
5260 obstack_1grow (&util_obstack, 0); /* null terminate string */
5261 string = obstack_finish (&util_obstack);
5263 /* Synthesize a string that represents the encoded struct/union. */
5264 result = my_build_string (strlen (string) + 1, string);
5265 obstack_free (&util_obstack, util_firstobj);
5270 build_ivar_reference (id)
5273 if (TREE_CODE (objc_method_context) == CLASS_METHOD_DECL)
5275 /* Historically, a class method that produced objects (factory
5276 method) would assign `self' to the instance that it
5277 allocated. This would effectively turn the class method into
5278 an instance method. Following this assignment, the instance
5279 variables could be accessed. That practice, while safe,
5280 violates the simple rule that a class method should not refer
5281 to an instance variable. It's better to catch the cases
5282 where this is done unknowingly than to support the above
5284 warning ("instance variable `%s' accessed in class method",
5285 IDENTIFIER_POINTER (id));
5286 TREE_TYPE (self_decl) = instance_type; /* cast */
5289 return build_component_ref (build_indirect_ref (self_decl, "->"), id);
5291 \f/* Make the hash value positive. */
5292 #define HASHFUNCTION(key) ((size_t) key & 0x7fffffff)
5297 nst_method_hash_list = (hash *) xcalloc (SIZEHASHTABLE, sizeof (hash));
5298 cls_method_hash_list = (hash *) xcalloc (SIZEHASHTABLE, sizeof (hash));
5301 /* WARNING!!!! hash_enter is called with a method, and will peek
5302 inside to find its selector! But hash_lookup is given a selector
5303 directly, and looks for the selector that's inside the found
5304 entry's key (method) for comparison. */
5307 hash_enter (hashlist, method)
5311 static hash hash_alloc_list = 0;
5312 static int hash_alloc_index = 0;
5314 int slot = HASHFUNCTION (METHOD_SEL_NAME (method)) % SIZEHASHTABLE;
5316 if (! hash_alloc_list || hash_alloc_index >= HASH_ALLOC_LIST_SIZE)
5318 hash_alloc_index = 0;
5319 hash_alloc_list = (hash) xmalloc (sizeof (struct hashed_entry)
5320 * HASH_ALLOC_LIST_SIZE);
5322 obj = &hash_alloc_list[hash_alloc_index++];
5324 obj->next = hashlist[slot];
5327 hashlist[slot] = obj; /* append to front */
5331 hash_lookup (hashlist, sel_name)
5337 target = hashlist[HASHFUNCTION (sel_name) % SIZEHASHTABLE];
5341 if (sel_name == METHOD_SEL_NAME (target->key))
5344 target = target->next;
5350 hash_add_attr (entry, value)
5354 static attr attr_alloc_list = 0;
5355 static int attr_alloc_index = 0;
5358 if (! attr_alloc_list || attr_alloc_index >= ATTR_ALLOC_LIST_SIZE)
5360 attr_alloc_index = 0;
5361 attr_alloc_list = (attr) xmalloc (sizeof (struct hashed_attribute)
5362 * ATTR_ALLOC_LIST_SIZE);
5364 obj = &attr_alloc_list[attr_alloc_index++];
5365 obj->next = entry->list;
5368 entry->list = obj; /* append to front */
5372 lookup_method (mchain, method)
5378 if (TREE_CODE (method) == IDENTIFIER_NODE)
5381 key = METHOD_SEL_NAME (method);
5385 if (METHOD_SEL_NAME (mchain) == key)
5387 mchain = TREE_CHAIN (mchain);
5393 lookup_instance_method_static (interface, ident)
5397 tree inter = interface;
5398 tree chain = CLASS_NST_METHODS (inter);
5399 tree meth = NULL_TREE;
5403 if ((meth = lookup_method (chain, ident)))
5406 if (CLASS_CATEGORY_LIST (inter))
5408 tree category = CLASS_CATEGORY_LIST (inter);
5409 chain = CLASS_NST_METHODS (category);
5413 if ((meth = lookup_method (chain, ident)))
5416 /* Check for instance methods in protocols in categories. */
5417 if (CLASS_PROTOCOL_LIST (category))
5419 if ((meth = (lookup_method_in_protocol_list
5420 (CLASS_PROTOCOL_LIST (category), ident, 0))))
5424 if ((category = CLASS_CATEGORY_LIST (category)))
5425 chain = CLASS_NST_METHODS (category);
5430 if (CLASS_PROTOCOL_LIST (inter))
5432 if ((meth = (lookup_method_in_protocol_list
5433 (CLASS_PROTOCOL_LIST (inter), ident, 0))))
5437 if ((inter = lookup_interface (CLASS_SUPER_NAME (inter))))
5438 chain = CLASS_NST_METHODS (inter);
5446 lookup_class_method_static (interface, ident)
5450 tree inter = interface;
5451 tree chain = CLASS_CLS_METHODS (inter);
5452 tree meth = NULL_TREE;
5453 tree root_inter = NULL_TREE;
5457 if ((meth = lookup_method (chain, ident)))
5460 if (CLASS_CATEGORY_LIST (inter))
5462 tree category = CLASS_CATEGORY_LIST (inter);
5463 chain = CLASS_CLS_METHODS (category);
5467 if ((meth = lookup_method (chain, ident)))
5470 /* Check for class methods in protocols in categories. */
5471 if (CLASS_PROTOCOL_LIST (category))
5473 if ((meth = (lookup_method_in_protocol_list
5474 (CLASS_PROTOCOL_LIST (category), ident, 1))))
5478 if ((category = CLASS_CATEGORY_LIST (category)))
5479 chain = CLASS_CLS_METHODS (category);
5484 /* Check for class methods in protocols. */
5485 if (CLASS_PROTOCOL_LIST (inter))
5487 if ((meth = (lookup_method_in_protocol_list
5488 (CLASS_PROTOCOL_LIST (inter), ident, 1))))
5493 if ((inter = lookup_interface (CLASS_SUPER_NAME (inter))))
5494 chain = CLASS_CLS_METHODS (inter);
5498 /* If no class (factory) method was found, check if an _instance_
5499 method of the same name exists in the root class. This is what
5500 the Objective-C runtime will do. */
5501 return lookup_instance_method_static (root_inter, ident);
5505 add_class_method (class, method)
5512 if (!(mth = lookup_method (CLASS_CLS_METHODS (class), method)))
5514 /* put method on list in reverse order */
5515 TREE_CHAIN (method) = CLASS_CLS_METHODS (class);
5516 CLASS_CLS_METHODS (class) = method;
5520 if (TREE_CODE (class) == CLASS_IMPLEMENTATION_TYPE)
5521 error ("duplicate definition of class method `%s'",
5522 IDENTIFIER_POINTER (METHOD_SEL_NAME (mth)));
5525 /* Check types; if different, complain. */
5526 if (!comp_proto_with_proto (method, mth))
5527 error ("duplicate declaration of class method `%s'",
5528 IDENTIFIER_POINTER (METHOD_SEL_NAME (mth)));
5532 if (!(hsh = hash_lookup (cls_method_hash_list, METHOD_SEL_NAME (method))))
5534 /* Install on a global chain. */
5535 hash_enter (cls_method_hash_list, method);
5539 /* Check types; if different, add to a list. */
5540 if (!comp_proto_with_proto (method, hsh->key))
5541 hash_add_attr (hsh, method);
5547 add_instance_method (class, method)
5554 if (!(mth = lookup_method (CLASS_NST_METHODS (class), method)))
5556 /* Put method on list in reverse order. */
5557 TREE_CHAIN (method) = CLASS_NST_METHODS (class);
5558 CLASS_NST_METHODS (class) = method;
5562 if (TREE_CODE (class) == CLASS_IMPLEMENTATION_TYPE)
5563 error ("duplicate definition of instance method `%s'",
5564 IDENTIFIER_POINTER (METHOD_SEL_NAME (mth)));
5567 /* Check types; if different, complain. */
5568 if (!comp_proto_with_proto (method, mth))
5569 error ("duplicate declaration of instance method `%s'",
5570 IDENTIFIER_POINTER (METHOD_SEL_NAME (mth)));
5574 if (!(hsh = hash_lookup (nst_method_hash_list, METHOD_SEL_NAME (method))))
5576 /* Install on a global chain. */
5577 hash_enter (nst_method_hash_list, method);
5581 /* Check types; if different, add to a list. */
5582 if (!comp_proto_with_proto (method, hsh->key))
5583 hash_add_attr (hsh, method);
5592 /* Put interfaces on list in reverse order. */
5593 TREE_CHAIN (class) = interface_chain;
5594 interface_chain = class;
5595 return interface_chain;
5599 add_category (class, category)
5603 /* Put categories on list in reverse order. */
5604 tree cat = CLASS_CATEGORY_LIST (class);
5608 if (CLASS_SUPER_NAME (cat) == CLASS_SUPER_NAME (category))
5609 warning ("duplicate interface declaration for category `%s(%s)'",
5610 IDENTIFIER_POINTER (CLASS_NAME (class)),
5611 IDENTIFIER_POINTER (CLASS_SUPER_NAME (category)));
5612 cat = CLASS_CATEGORY_LIST (cat);
5615 CLASS_CATEGORY_LIST (category) = CLASS_CATEGORY_LIST (class);
5616 CLASS_CATEGORY_LIST (class) = category;
5619 /* Called after parsing each instance variable declaration. Necessary to
5620 preserve typedefs and implement public/private...
5622 PUBLIC is 1 for public, 0 for protected, and 2 for private. */
5625 add_instance_variable (class, public, declarator, declspecs, width)
5632 tree field_decl, raw_decl;
5634 raw_decl = build_tree_list (declspecs, declarator);
5636 if (CLASS_RAW_IVARS (class))
5637 chainon (CLASS_RAW_IVARS (class), raw_decl);
5639 CLASS_RAW_IVARS (class) = raw_decl;
5641 field_decl = grokfield (input_filename, lineno,
5642 declarator, declspecs, width);
5644 /* Overload the public attribute, it is not used for FIELD_DECLs. */
5648 TREE_PUBLIC (field_decl) = 0;
5649 TREE_PRIVATE (field_decl) = 0;
5650 TREE_PROTECTED (field_decl) = 1;
5654 TREE_PUBLIC (field_decl) = 1;
5655 TREE_PRIVATE (field_decl) = 0;
5656 TREE_PROTECTED (field_decl) = 0;
5660 TREE_PUBLIC (field_decl) = 0;
5661 TREE_PRIVATE (field_decl) = 1;
5662 TREE_PROTECTED (field_decl) = 0;
5667 if (CLASS_IVARS (class))
5668 chainon (CLASS_IVARS (class), field_decl);
5670 CLASS_IVARS (class) = field_decl;
5676 is_ivar (decl_chain, ident)
5680 for ( ; decl_chain; decl_chain = TREE_CHAIN (decl_chain))
5681 if (DECL_NAME (decl_chain) == ident)
5686 /* True if the ivar is private and we are not in its implementation. */
5692 if (TREE_PRIVATE (decl)
5693 && ! is_ivar (CLASS_IVARS (implementation_template), DECL_NAME (decl)))
5695 error ("instance variable `%s' is declared private",
5696 IDENTIFIER_POINTER (DECL_NAME (decl)));
5703 /* We have an instance variable reference;, check to see if it is public. */
5706 is_public (expr, identifier)
5710 tree basetype = TREE_TYPE (expr);
5711 enum tree_code code = TREE_CODE (basetype);
5714 if (code == RECORD_TYPE)
5716 if (TREE_STATIC_TEMPLATE (basetype))
5718 if (!lookup_interface (TYPE_NAME (basetype)))
5720 error ("cannot find interface declaration for `%s'",
5721 IDENTIFIER_POINTER (TYPE_NAME (basetype)));
5725 if ((decl = is_ivar (TYPE_FIELDS (basetype), identifier)))
5727 if (TREE_PUBLIC (decl))
5730 /* Important difference between the Stepstone translator:
5731 all instance variables should be public within the context
5732 of the implementation. */
5733 if (objc_implementation_context
5734 && (((TREE_CODE (objc_implementation_context)
5735 == CLASS_IMPLEMENTATION_TYPE)
5736 || (TREE_CODE (objc_implementation_context)
5737 == CATEGORY_IMPLEMENTATION_TYPE))
5738 && (CLASS_NAME (objc_implementation_context)
5739 == TYPE_NAME (basetype))))
5740 return ! is_private (decl);
5742 error ("instance variable `%s' is declared %s",
5743 IDENTIFIER_POINTER (identifier),
5744 TREE_PRIVATE (decl) ? "private" : "protected");
5749 else if (objc_implementation_context && (basetype == objc_object_reference))
5751 TREE_TYPE (expr) = uprivate_record;
5752 warning ("static access to object of type `id'");
5759 /* Implement @defs (<classname>) within struct bodies. */
5762 get_class_ivars (interface)
5765 /* Make sure we copy the leaf ivars in case @defs is used in a local
5766 context. Otherwise finish_struct will overwrite the layout info
5767 using temporary storage. */
5768 return build_ivar_chain (interface, 1);
5771 /* Make sure all entries in CHAIN are also in LIST. */
5774 check_methods (chain, list, mtype)
5783 if (!lookup_method (list, chain))
5787 if (TREE_CODE (objc_implementation_context)
5788 == CLASS_IMPLEMENTATION_TYPE)
5789 warning ("incomplete implementation of class `%s'",
5790 IDENTIFIER_POINTER (CLASS_NAME (objc_implementation_context)));
5791 else if (TREE_CODE (objc_implementation_context)
5792 == CATEGORY_IMPLEMENTATION_TYPE)
5793 warning ("incomplete implementation of category `%s'",
5794 IDENTIFIER_POINTER (CLASS_SUPER_NAME (objc_implementation_context)));
5798 warning ("method definition for `%c%s' not found",
5799 mtype, IDENTIFIER_POINTER (METHOD_SEL_NAME (chain)));
5802 chain = TREE_CHAIN (chain);
5808 /* Check if CLASS, or its superclasses, explicitly conforms to PROTOCOL. */
5811 conforms_to_protocol (class, protocol)
5815 if (TREE_CODE (protocol) == PROTOCOL_INTERFACE_TYPE)
5817 tree p = CLASS_PROTOCOL_LIST (class);
5818 while (p && TREE_VALUE (p) != protocol)
5823 tree super = (CLASS_SUPER_NAME (class)
5824 ? lookup_interface (CLASS_SUPER_NAME (class))
5826 int tmp = super ? conforms_to_protocol (super, protocol) : 0;
5835 /* Make sure all methods in CHAIN are accessible as MTYPE methods in
5836 CONTEXT. This is one of two mechanisms to check protocol integrity. */
5839 check_methods_accessible (chain, context, mtype)
5846 tree base_context = context;
5850 context = base_context;
5854 list = CLASS_CLS_METHODS (context);
5856 list = CLASS_NST_METHODS (context);
5858 if (lookup_method (list, chain))
5861 else if (TREE_CODE (context) == CLASS_IMPLEMENTATION_TYPE
5862 || TREE_CODE (context) == CLASS_INTERFACE_TYPE)
5863 context = (CLASS_SUPER_NAME (context)
5864 ? lookup_interface (CLASS_SUPER_NAME (context))
5867 else if (TREE_CODE (context) == CATEGORY_IMPLEMENTATION_TYPE
5868 || TREE_CODE (context) == CATEGORY_INTERFACE_TYPE)
5869 context = (CLASS_NAME (context)
5870 ? lookup_interface (CLASS_NAME (context))
5876 if (context == NULL_TREE)
5880 if (TREE_CODE (objc_implementation_context)
5881 == CLASS_IMPLEMENTATION_TYPE)
5882 warning ("incomplete implementation of class `%s'",
5884 (CLASS_NAME (objc_implementation_context)));
5885 else if (TREE_CODE (objc_implementation_context)
5886 == CATEGORY_IMPLEMENTATION_TYPE)
5887 warning ("incomplete implementation of category `%s'",
5889 (CLASS_SUPER_NAME (objc_implementation_context)));
5892 warning ("method definition for `%c%s' not found",
5893 mtype, IDENTIFIER_POINTER (METHOD_SEL_NAME (chain)));
5896 chain = TREE_CHAIN (chain); /* next method... */
5901 /* Check whether the current interface (accessible via
5902 'objc_implementation_context') actually implements protocol P, along
5903 with any protocols that P inherits. */
5906 check_protocol (p, type, name)
5911 if (TREE_CODE (p) == PROTOCOL_INTERFACE_TYPE)
5915 /* Ensure that all protocols have bodies! */
5916 if (flag_warn_protocol)
5918 f1 = check_methods (PROTOCOL_CLS_METHODS (p),
5919 CLASS_CLS_METHODS (objc_implementation_context),
5921 f2 = check_methods (PROTOCOL_NST_METHODS (p),
5922 CLASS_NST_METHODS (objc_implementation_context),
5927 f1 = check_methods_accessible (PROTOCOL_CLS_METHODS (p),
5928 objc_implementation_context,
5930 f2 = check_methods_accessible (PROTOCOL_NST_METHODS (p),
5931 objc_implementation_context,
5936 warning ("%s `%s' does not fully implement the `%s' protocol",
5937 type, name, IDENTIFIER_POINTER (PROTOCOL_NAME (p)));
5940 /* Check protocols recursively. */
5941 if (PROTOCOL_LIST (p))
5943 tree subs = PROTOCOL_LIST (p);
5945 lookup_interface (CLASS_SUPER_NAME (implementation_template));
5948 tree sub = TREE_VALUE (subs);
5950 /* If the superclass does not conform to the protocols
5951 inherited by P, then we must! */
5952 if (!super_class || !conforms_to_protocol (super_class, sub))
5953 check_protocol (sub, type, name);
5954 subs = TREE_CHAIN (subs);
5959 /* Check whether the current interface (accessible via
5960 'objc_implementation_context') actually implements the protocols listed
5964 check_protocols (proto_list, type, name)
5969 for ( ; proto_list; proto_list = TREE_CHAIN (proto_list))
5971 tree p = TREE_VALUE (proto_list);
5973 check_protocol (p, type, name);
5977 /* Make sure that the class CLASS_NAME is defined
5978 CODE says which kind of thing CLASS_NAME ought to be.
5979 It can be CLASS_INTERFACE_TYPE, CLASS_IMPLEMENTATION_TYPE,
5980 CATEGORY_INTERFACE_TYPE, or CATEGORY_IMPLEMENTATION_TYPE. */
5983 start_class (code, class_name, super_name, protocol_list)
5984 enum tree_code code;
5991 if (objc_implementation_context)
5993 warning ("`@end' missing in implementation context");
5994 finish_class (objc_implementation_context);
5995 objc_ivar_chain = NULL_TREE;
5996 objc_implementation_context = NULL_TREE;
5999 class = make_node (code);
6000 TYPE_BINFO (class) = make_tree_vec (5);
6002 CLASS_NAME (class) = class_name;
6003 CLASS_SUPER_NAME (class) = super_name;
6004 CLASS_CLS_METHODS (class) = NULL_TREE;
6006 if (! is_class_name (class_name) && (decl = lookup_name (class_name)))
6008 error ("`%s' redeclared as different kind of symbol",
6009 IDENTIFIER_POINTER (class_name));
6010 error_with_decl (decl, "previous declaration of `%s'");
6013 if (code == CLASS_IMPLEMENTATION_TYPE)
6018 for (chain = implemented_classes; chain; chain = TREE_CHAIN (chain))
6019 if (TREE_VALUE (chain) == class_name)
6021 error ("reimplementation of class `%s'",
6022 IDENTIFIER_POINTER (class_name));
6023 return error_mark_node;
6025 implemented_classes = tree_cons (NULL_TREE, class_name,
6026 implemented_classes);
6029 /* Pre-build the following entities - for speed/convenience. */
6031 self_id = get_identifier ("self");
6033 ucmd_id = get_identifier ("_cmd");
6036 = build_tree_list (get_identifier ("__unused__"), NULL_TREE);
6037 if (!objc_super_template)
6038 objc_super_template = build_super_template ();
6040 /* Reset for multiple classes per file. */
6043 objc_implementation_context = class;
6045 /* Lookup the interface for this implementation. */
6047 if (!(implementation_template = lookup_interface (class_name)))
6049 warning ("cannot find interface declaration for `%s'",
6050 IDENTIFIER_POINTER (class_name));
6051 add_class (implementation_template = objc_implementation_context);
6054 /* If a super class has been specified in the implementation,
6055 insure it conforms to the one specified in the interface. */
6058 && (super_name != CLASS_SUPER_NAME (implementation_template)))
6060 tree previous_name = CLASS_SUPER_NAME (implementation_template);
6061 const char *const name =
6062 previous_name ? IDENTIFIER_POINTER (previous_name) : "";
6063 error ("conflicting super class name `%s'",
6064 IDENTIFIER_POINTER (super_name));
6065 error ("previous declaration of `%s'", name);
6068 else if (! super_name)
6070 CLASS_SUPER_NAME (objc_implementation_context)
6071 = CLASS_SUPER_NAME (implementation_template);
6075 else if (code == CLASS_INTERFACE_TYPE)
6077 if (lookup_interface (class_name))
6078 warning ("duplicate interface declaration for class `%s'",
6079 IDENTIFIER_POINTER (class_name));
6084 CLASS_PROTOCOL_LIST (class)
6085 = lookup_and_install_protocols (protocol_list);
6088 else if (code == CATEGORY_INTERFACE_TYPE)
6090 tree class_category_is_assoc_with;
6092 /* For a category, class_name is really the name of the class that
6093 the following set of methods will be associated with. We must
6094 find the interface so that can derive the objects template. */
6096 if (!(class_category_is_assoc_with = lookup_interface (class_name)))
6098 error ("cannot find interface declaration for `%s'",
6099 IDENTIFIER_POINTER (class_name));
6100 exit (FATAL_EXIT_CODE);
6103 add_category (class_category_is_assoc_with, class);
6106 CLASS_PROTOCOL_LIST (class)
6107 = lookup_and_install_protocols (protocol_list);
6110 else if (code == CATEGORY_IMPLEMENTATION_TYPE)
6112 /* Pre-build the following entities for speed/convenience. */
6114 self_id = get_identifier ("self");
6116 ucmd_id = get_identifier ("_cmd");
6119 = build_tree_list (get_identifier ("__unused__"), NULL_TREE);
6120 if (!objc_super_template)
6121 objc_super_template = build_super_template ();
6123 /* Reset for multiple classes per file. */
6126 objc_implementation_context = class;
6128 /* For a category, class_name is really the name of the class that
6129 the following set of methods will be associated with. We must
6130 find the interface so that can derive the objects template. */
6132 if (!(implementation_template = lookup_interface (class_name)))
6134 error ("cannot find interface declaration for `%s'",
6135 IDENTIFIER_POINTER (class_name));
6136 exit (FATAL_EXIT_CODE);
6143 continue_class (class)
6146 if (TREE_CODE (class) == CLASS_IMPLEMENTATION_TYPE
6147 || TREE_CODE (class) == CATEGORY_IMPLEMENTATION_TYPE)
6149 struct imp_entry *imp_entry;
6152 /* Check consistency of the instance variables. */
6154 if (CLASS_IVARS (class))
6155 check_ivars (implementation_template, class);
6157 /* code generation */
6159 ivar_context = build_private_template (implementation_template);
6161 if (!objc_class_template)
6162 build_class_template ();
6164 imp_entry = (struct imp_entry *) xmalloc (sizeof (struct imp_entry));
6166 imp_entry->next = imp_list;
6167 imp_entry->imp_context = class;
6168 imp_entry->imp_template = implementation_template;
6170 synth_forward_declarations ();
6171 imp_entry->class_decl = UOBJC_CLASS_decl;
6172 imp_entry->meta_decl = UOBJC_METACLASS_decl;
6174 /* Append to front and increment count. */
6175 imp_list = imp_entry;
6176 if (TREE_CODE (class) == CLASS_IMPLEMENTATION_TYPE)
6181 return ivar_context;
6184 else if (TREE_CODE (class) == CLASS_INTERFACE_TYPE)
6186 tree record = xref_tag (RECORD_TYPE, CLASS_NAME (class));
6188 if (!TYPE_FIELDS (record))
6190 finish_struct (record, build_ivar_chain (class, 0), NULL_TREE);
6191 CLASS_STATIC_TEMPLATE (class) = record;
6193 /* Mark this record as a class template for static typing. */
6194 TREE_STATIC_TEMPLATE (record) = 1;
6201 return error_mark_node;
6204 /* This is called once we see the "@end" in an interface/implementation. */
6207 finish_class (class)
6210 if (TREE_CODE (class) == CLASS_IMPLEMENTATION_TYPE)
6212 /* All code generation is done in finish_objc. */
6214 if (implementation_template != objc_implementation_context)
6216 /* Ensure that all method listed in the interface contain bodies. */
6217 check_methods (CLASS_CLS_METHODS (implementation_template),
6218 CLASS_CLS_METHODS (objc_implementation_context), '+');
6219 check_methods (CLASS_NST_METHODS (implementation_template),
6220 CLASS_NST_METHODS (objc_implementation_context), '-');
6222 if (CLASS_PROTOCOL_LIST (implementation_template))
6223 check_protocols (CLASS_PROTOCOL_LIST (implementation_template),
6225 IDENTIFIER_POINTER (CLASS_NAME (objc_implementation_context)));
6229 else if (TREE_CODE (class) == CATEGORY_IMPLEMENTATION_TYPE)
6231 tree category = CLASS_CATEGORY_LIST (implementation_template);
6233 /* Find the category interface from the class it is associated with. */
6236 if (CLASS_SUPER_NAME (class) == CLASS_SUPER_NAME (category))
6238 category = CLASS_CATEGORY_LIST (category);
6243 /* Ensure all method listed in the interface contain bodies. */
6244 check_methods (CLASS_CLS_METHODS (category),
6245 CLASS_CLS_METHODS (objc_implementation_context), '+');
6246 check_methods (CLASS_NST_METHODS (category),
6247 CLASS_NST_METHODS (objc_implementation_context), '-');
6249 if (CLASS_PROTOCOL_LIST (category))
6250 check_protocols (CLASS_PROTOCOL_LIST (category),
6252 IDENTIFIER_POINTER (CLASS_SUPER_NAME (objc_implementation_context)));
6256 else if (TREE_CODE (class) == CLASS_INTERFACE_TYPE)
6259 const char *class_name = IDENTIFIER_POINTER (CLASS_NAME (class));
6260 char *string = (char *) alloca (strlen (class_name) + 3);
6262 /* extern struct objc_object *_<my_name>; */
6264 sprintf (string, "_%s", class_name);
6266 decl_specs = build_tree_list (NULL_TREE, ridpointers[(int) RID_EXTERN]);
6267 decl_specs = tree_cons (NULL_TREE, objc_object_reference, decl_specs);
6268 define_decl (build1 (INDIRECT_REF, NULL_TREE, get_identifier (string)),
6274 add_protocol (protocol)
6277 /* Put protocol on list in reverse order. */
6278 TREE_CHAIN (protocol) = protocol_chain;
6279 protocol_chain = protocol;
6280 return protocol_chain;
6284 lookup_protocol (ident)
6289 for (chain = protocol_chain; chain; chain = TREE_CHAIN (chain))
6291 if (ident == PROTOCOL_NAME (chain))
6298 /* This function forward declares the protocols named by NAMES. If
6299 they are already declared or defined, the function has no effect. */
6302 objc_declare_protocols (names)
6307 for (list = names; list; list = TREE_CHAIN (list))
6309 tree name = TREE_VALUE (list);
6311 if (lookup_protocol (name) == NULL_TREE)
6313 tree protocol = make_node (PROTOCOL_INTERFACE_TYPE);
6315 TYPE_BINFO (protocol) = make_tree_vec (2);
6316 PROTOCOL_NAME (protocol) = name;
6317 PROTOCOL_LIST (protocol) = NULL_TREE;
6318 add_protocol (protocol);
6319 PROTOCOL_DEFINED (protocol) = 0;
6320 PROTOCOL_FORWARD_DECL (protocol) = NULL_TREE;
6326 start_protocol (code, name, list)
6327 enum tree_code code;
6333 /* This is as good a place as any. Need to invoke
6334 push_tag_toplevel. */
6335 if (!objc_protocol_template)
6336 objc_protocol_template = build_protocol_template ();
6338 protocol = lookup_protocol (name);
6342 protocol = make_node (code);
6343 TYPE_BINFO (protocol) = make_tree_vec (2);
6345 PROTOCOL_NAME (protocol) = name;
6346 PROTOCOL_LIST (protocol) = lookup_and_install_protocols (list);
6347 add_protocol (protocol);
6348 PROTOCOL_DEFINED (protocol) = 1;
6349 PROTOCOL_FORWARD_DECL (protocol) = NULL_TREE;
6351 check_protocol_recursively (protocol, list);
6353 else if (! PROTOCOL_DEFINED (protocol))
6355 PROTOCOL_DEFINED (protocol) = 1;
6356 PROTOCOL_LIST (protocol) = lookup_and_install_protocols (list);
6358 check_protocol_recursively (protocol, list);
6362 warning ("duplicate declaration for protocol `%s'",
6363 IDENTIFIER_POINTER (name));
6369 finish_protocol (protocol)
6370 tree protocol ATTRIBUTE_UNUSED;
6375 /* "Encode" a data type into a string, which grows in util_obstack.
6376 ??? What is the FORMAT? Someone please document this! */
6379 encode_type_qualifiers (declspecs)
6384 for (spec = declspecs; spec; spec = TREE_CHAIN (spec))
6386 if (ridpointers[(int) RID_CONST] == TREE_VALUE (spec))
6387 obstack_1grow (&util_obstack, 'r');
6388 else if (ridpointers[(int) RID_IN] == TREE_VALUE (spec))
6389 obstack_1grow (&util_obstack, 'n');
6390 else if (ridpointers[(int) RID_INOUT] == TREE_VALUE (spec))
6391 obstack_1grow (&util_obstack, 'N');
6392 else if (ridpointers[(int) RID_OUT] == TREE_VALUE (spec))
6393 obstack_1grow (&util_obstack, 'o');
6394 else if (ridpointers[(int) RID_BYCOPY] == TREE_VALUE (spec))
6395 obstack_1grow (&util_obstack, 'O');
6396 else if (ridpointers[(int) RID_BYREF] == TREE_VALUE (spec))
6397 obstack_1grow (&util_obstack, 'R');
6398 else if (ridpointers[(int) RID_ONEWAY] == TREE_VALUE (spec))
6399 obstack_1grow (&util_obstack, 'V');
6403 /* Encode a pointer type. */
6406 encode_pointer (type, curtype, format)
6411 tree pointer_to = TREE_TYPE (type);
6413 if (TREE_CODE (pointer_to) == RECORD_TYPE)
6415 if (TYPE_NAME (pointer_to)
6416 && TREE_CODE (TYPE_NAME (pointer_to)) == IDENTIFIER_NODE)
6418 const char *name = IDENTIFIER_POINTER (TYPE_NAME (pointer_to));
6420 if (strcmp (name, TAG_OBJECT) == 0) /* '@' */
6422 obstack_1grow (&util_obstack, '@');
6425 else if (TREE_STATIC_TEMPLATE (pointer_to))
6427 if (generating_instance_variables)
6429 obstack_1grow (&util_obstack, '@');
6430 obstack_1grow (&util_obstack, '"');
6431 obstack_grow (&util_obstack, name, strlen (name));
6432 obstack_1grow (&util_obstack, '"');
6437 obstack_1grow (&util_obstack, '@');
6441 else if (strcmp (name, TAG_CLASS) == 0) /* '#' */
6443 obstack_1grow (&util_obstack, '#');
6446 else if (strcmp (name, TAG_SELECTOR) == 0) /* ':' */
6448 obstack_1grow (&util_obstack, ':');
6453 else if (TREE_CODE (pointer_to) == INTEGER_TYPE
6454 && TYPE_MODE (pointer_to) == QImode)
6456 obstack_1grow (&util_obstack, '*');
6460 /* We have a type that does not get special treatment. */
6462 /* NeXT extension */
6463 obstack_1grow (&util_obstack, '^');
6464 encode_type (pointer_to, curtype, format);
6468 encode_array (type, curtype, format)
6473 tree an_int_cst = TYPE_SIZE (type);
6474 tree array_of = TREE_TYPE (type);
6477 /* An incomplete array is treated like a pointer. */
6478 if (an_int_cst == NULL)
6480 encode_pointer (type, curtype, format);
6484 sprintf (buffer, "[%ld",
6485 (long) (TREE_INT_CST_LOW (an_int_cst)
6486 / TREE_INT_CST_LOW (TYPE_SIZE (array_of))));
6488 obstack_grow (&util_obstack, buffer, strlen (buffer));
6489 encode_type (array_of, curtype, format);
6490 obstack_1grow (&util_obstack, ']');
6495 encode_aggregate_within (type, curtype, format, left, right)
6502 /* The RECORD_TYPE may in fact be a typedef! For purposes
6503 of encoding, we need the real underlying enchilada. */
6504 if (TYPE_MAIN_VARIANT (type))
6505 type = TYPE_MAIN_VARIANT (type);
6507 if (obstack_object_size (&util_obstack) > 0
6508 && *(obstack_next_free (&util_obstack) - 1) == '^')
6510 tree name = TYPE_NAME (type);
6512 /* we have a reference; this is a NeXT extension. */
6514 if (obstack_object_size (&util_obstack) - curtype == 1
6515 && format == OBJC_ENCODE_INLINE_DEFS)
6517 /* Output format of struct for first level only. */
6518 tree fields = TYPE_FIELDS (type);
6520 if (name && TREE_CODE (name) == IDENTIFIER_NODE)
6522 obstack_1grow (&util_obstack, left);
6523 obstack_grow (&util_obstack,
6524 IDENTIFIER_POINTER (name),
6525 strlen (IDENTIFIER_POINTER (name)));
6526 obstack_1grow (&util_obstack, '=');
6530 obstack_1grow (&util_obstack, left);
6531 obstack_grow (&util_obstack, "?=", 2);
6534 for ( ; fields; fields = TREE_CHAIN (fields))
6535 encode_field_decl (fields, curtype, format);
6537 obstack_1grow (&util_obstack, right);
6540 else if (name && TREE_CODE (name) == IDENTIFIER_NODE)
6542 obstack_1grow (&util_obstack, left);
6543 obstack_grow (&util_obstack,
6544 IDENTIFIER_POINTER (name),
6545 strlen (IDENTIFIER_POINTER (name)));
6546 obstack_1grow (&util_obstack, right);
6551 /* We have an untagged structure or a typedef. */
6552 obstack_1grow (&util_obstack, left);
6553 obstack_1grow (&util_obstack, '?');
6554 obstack_1grow (&util_obstack, right);
6560 tree name = TYPE_NAME (type);
6561 tree fields = TYPE_FIELDS (type);
6563 if (format == OBJC_ENCODE_INLINE_DEFS
6564 || generating_instance_variables)
6566 obstack_1grow (&util_obstack, left);
6567 if (name && TREE_CODE (name) == IDENTIFIER_NODE)
6568 obstack_grow (&util_obstack,
6569 IDENTIFIER_POINTER (name),
6570 strlen (IDENTIFIER_POINTER (name)));
6572 obstack_1grow (&util_obstack, '?');
6574 obstack_1grow (&util_obstack, '=');
6576 for (; fields; fields = TREE_CHAIN (fields))
6578 if (generating_instance_variables)
6580 tree fname = DECL_NAME (fields);
6582 obstack_1grow (&util_obstack, '"');
6583 if (fname && TREE_CODE (fname) == IDENTIFIER_NODE)
6585 obstack_grow (&util_obstack,
6586 IDENTIFIER_POINTER (fname),
6587 strlen (IDENTIFIER_POINTER (fname)));
6590 obstack_1grow (&util_obstack, '"');
6593 encode_field_decl (fields, curtype, format);
6596 obstack_1grow (&util_obstack, right);
6601 obstack_1grow (&util_obstack, left);
6602 if (name && TREE_CODE (name) == IDENTIFIER_NODE)
6603 obstack_grow (&util_obstack,
6604 IDENTIFIER_POINTER (name),
6605 strlen (IDENTIFIER_POINTER (name)));
6607 /* We have an untagged structure or a typedef. */
6608 obstack_1grow (&util_obstack, '?');
6610 obstack_1grow (&util_obstack, right);
6616 encode_aggregate (type, curtype, format)
6621 enum tree_code code = TREE_CODE (type);
6627 encode_aggregate_within(type, curtype, format, '{', '}');
6632 encode_aggregate_within(type, curtype, format, '(', ')');
6637 obstack_1grow (&util_obstack, 'i');
6645 /* Support bitfields. The current version of Objective-C does not support
6646 them. The string will consist of one or more "b:n"'s where n is an
6647 integer describing the width of the bitfield. Currently, classes in
6648 the kit implement a method "-(char *)describeBitfieldStruct:" that
6649 simulates this. If they do not implement this method, the archiver
6650 assumes the bitfield is 16 bits wide (padded if necessary) and packed
6651 according to the GNU compiler. After looking at the "kit", it appears
6652 that all classes currently rely on this default behavior, rather than
6653 hand generating this string (which is tedious). */
6656 encode_bitfield (width)
6660 sprintf (buffer, "b%d", width);
6661 obstack_grow (&util_obstack, buffer, strlen (buffer));
6664 /* FORMAT will be OBJC_ENCODE_INLINE_DEFS or OBJC_ENCODE_DONT_INLINE_DEFS. */
6667 encode_type (type, curtype, format)
6672 enum tree_code code = TREE_CODE (type);
6674 if (code == INTEGER_TYPE)
6676 if (integer_zerop (TYPE_MIN_VALUE (type)))
6678 /* Unsigned integer types. */
6680 if (TYPE_MODE (type) == QImode)
6681 obstack_1grow (&util_obstack, 'C');
6682 else if (TYPE_MODE (type) == HImode)
6683 obstack_1grow (&util_obstack, 'S');
6684 else if (TYPE_MODE (type) == SImode)
6686 if (type == long_unsigned_type_node)
6687 obstack_1grow (&util_obstack, 'L');
6689 obstack_1grow (&util_obstack, 'I');
6691 else if (TYPE_MODE (type) == DImode)
6692 obstack_1grow (&util_obstack, 'Q');
6696 /* Signed integer types. */
6698 if (TYPE_MODE (type) == QImode)
6699 obstack_1grow (&util_obstack, 'c');
6700 else if (TYPE_MODE (type) == HImode)
6701 obstack_1grow (&util_obstack, 's');
6702 else if (TYPE_MODE (type) == SImode)
6704 if (type == long_integer_type_node)
6705 obstack_1grow (&util_obstack, 'l');
6707 obstack_1grow (&util_obstack, 'i');
6710 else if (TYPE_MODE (type) == DImode)
6711 obstack_1grow (&util_obstack, 'q');
6715 else if (code == REAL_TYPE)
6717 /* Floating point types. */
6719 if (TYPE_MODE (type) == SFmode)
6720 obstack_1grow (&util_obstack, 'f');
6721 else if (TYPE_MODE (type) == DFmode
6722 || TYPE_MODE (type) == TFmode)
6723 obstack_1grow (&util_obstack, 'd');
6726 else if (code == VOID_TYPE)
6727 obstack_1grow (&util_obstack, 'v');
6729 else if (code == ARRAY_TYPE)
6730 encode_array (type, curtype, format);
6732 else if (code == POINTER_TYPE)
6733 encode_pointer (type, curtype, format);
6735 else if (code == RECORD_TYPE || code == UNION_TYPE || code == ENUMERAL_TYPE)
6736 encode_aggregate (type, curtype, format);
6738 else if (code == FUNCTION_TYPE) /* '?' */
6739 obstack_1grow (&util_obstack, '?');
6743 encode_complete_bitfield (int position, tree type, int size)
6745 enum tree_code code = TREE_CODE (type);
6747 char charType = '?';
6749 if (code == INTEGER_TYPE)
6751 if (integer_zerop (TYPE_MIN_VALUE (type)))
6753 /* Unsigned integer types. */
6755 if (TYPE_MODE (type) == QImode)
6757 else if (TYPE_MODE (type) == HImode)
6759 else if (TYPE_MODE (type) == SImode)
6761 if (type == long_unsigned_type_node)
6766 else if (TYPE_MODE (type) == DImode)
6771 /* Signed integer types. */
6773 if (TYPE_MODE (type) == QImode)
6775 else if (TYPE_MODE (type) == HImode)
6777 else if (TYPE_MODE (type) == SImode)
6779 if (type == long_integer_type_node)
6785 else if (TYPE_MODE (type) == DImode)
6793 sprintf (buffer, "b%d%c%d", position, charType, size);
6794 obstack_grow (&util_obstack, buffer, strlen (buffer));
6798 encode_field_decl (field_decl, curtype, format)
6805 type = TREE_TYPE (field_decl);
6807 /* If this field is obviously a bitfield, or is a bitfield that has been
6808 clobbered to look like a ordinary integer mode, go ahead and generate
6809 the bitfield typing information. */
6810 if (flag_next_runtime)
6812 if (DECL_BIT_FIELD (field_decl))
6813 encode_bitfield (tree_low_cst (DECL_SIZE (field_decl), 1));
6815 encode_type (TREE_TYPE (field_decl), curtype, format);
6819 if (DECL_BIT_FIELD (field_decl))
6820 encode_complete_bitfield (int_bit_position (field_decl),
6821 DECL_BIT_FIELD_TYPE (field_decl),
6822 tree_low_cst (DECL_SIZE (field_decl), 1));
6824 encode_type (TREE_TYPE (field_decl), curtype, format);
6829 expr_last (complex_expr)
6835 while ((next = TREE_OPERAND (complex_expr, 0)))
6836 complex_expr = next;
6838 return complex_expr;
6841 /* Transform a method definition into a function definition as follows:
6842 - synthesize the first two arguments, "self" and "_cmd". */
6845 start_method_def (method)
6850 /* Required to implement _msgSuper. */
6851 objc_method_context = method;
6852 UOBJC_SUPER_decl = NULL_TREE;
6854 /* Must be called BEFORE start_function. */
6857 /* Generate prototype declarations for arguments..."new-style". */
6859 if (TREE_CODE (objc_method_context) == INSTANCE_METHOD_DECL)
6860 decl_specs = build_tree_list (NULL_TREE, uprivate_record);
6862 /* Really a `struct objc_class *'. However, we allow people to
6863 assign to self, which changes its type midstream. */
6864 decl_specs = build_tree_list (NULL_TREE, objc_object_reference);
6866 push_parm_decl (build_tree_list
6867 (build_tree_list (decl_specs,
6868 build1 (INDIRECT_REF, NULL_TREE, self_id)),
6871 decl_specs = build_tree_list (NULL_TREE,
6872 xref_tag (RECORD_TYPE,
6873 get_identifier (TAG_SELECTOR)));
6874 push_parm_decl (build_tree_list
6875 (build_tree_list (decl_specs,
6876 build1 (INDIRECT_REF, NULL_TREE, ucmd_id)),
6879 /* Generate argument declarations if a keyword_decl. */
6880 if (METHOD_SEL_ARGS (method))
6882 tree arglist = METHOD_SEL_ARGS (method);
6885 tree arg_spec = TREE_PURPOSE (TREE_TYPE (arglist));
6886 tree arg_decl = TREE_VALUE (TREE_TYPE (arglist));
6890 tree last_expr = expr_last (arg_decl);
6892 /* Unite the abstract decl with its name. */
6893 TREE_OPERAND (last_expr, 0) = KEYWORD_ARG_NAME (arglist);
6894 push_parm_decl (build_tree_list
6895 (build_tree_list (arg_spec, arg_decl),
6898 /* Unhook: restore the abstract declarator. */
6899 TREE_OPERAND (last_expr, 0) = NULL_TREE;
6903 push_parm_decl (build_tree_list
6904 (build_tree_list (arg_spec,
6905 KEYWORD_ARG_NAME (arglist)),
6908 arglist = TREE_CHAIN (arglist);
6913 if (METHOD_ADD_ARGS (method) != NULL_TREE
6914 && METHOD_ADD_ARGS (method) != objc_ellipsis_node)
6916 /* We have a variable length selector - in "prototype" format. */
6917 tree akey = TREE_PURPOSE (METHOD_ADD_ARGS (method));
6920 /* This must be done prior to calling pushdecl. pushdecl is
6921 going to change our chain on us. */
6922 tree nextkey = TREE_CHAIN (akey);
6930 warn_with_method (message, mtype, method)
6931 const char *message;
6935 if (count_error (1) == 0)
6938 report_error_function (DECL_SOURCE_FILE (method));
6940 /* Add a readable method name to the warning. */
6941 warning_with_file_and_line (DECL_SOURCE_FILE (method),
6942 DECL_SOURCE_LINE (method),
6945 gen_method_decl (method, errbuf));
6948 /* Return 1 if METHOD is consistent with PROTO. */
6951 comp_method_with_proto (method, proto)
6954 /* Create a function template node at most once. */
6955 if (!function1_template)
6956 function1_template = make_node (FUNCTION_TYPE);
6958 /* Install argument types - normally set by build_function_type. */
6959 TYPE_ARG_TYPES (function1_template) = get_arg_type_list (proto, METHOD_DEF, 0);
6961 /* install return type */
6962 TREE_TYPE (function1_template) = groktypename (TREE_TYPE (proto));
6964 return comptypes (TREE_TYPE (METHOD_DEFINITION (method)), function1_template);
6967 /* Return 1 if PROTO1 is consistent with PROTO2. */
6970 comp_proto_with_proto (proto0, proto1)
6971 tree proto0, proto1;
6973 /* Create a couple of function_template nodes at most once. */
6974 if (!function1_template)
6975 function1_template = make_node (FUNCTION_TYPE);
6976 if (!function2_template)
6977 function2_template = make_node (FUNCTION_TYPE);
6979 /* Install argument types; normally set by build_function_type. */
6980 TYPE_ARG_TYPES (function1_template) = get_arg_type_list (proto0, METHOD_REF, 0);
6981 TYPE_ARG_TYPES (function2_template) = get_arg_type_list (proto1, METHOD_REF, 0);
6983 /* Install return type. */
6984 TREE_TYPE (function1_template) = groktypename (TREE_TYPE (proto0));
6985 TREE_TYPE (function2_template) = groktypename (TREE_TYPE (proto1));
6987 return comptypes (function1_template, function2_template);
6990 /* - Generate an identifier for the function. the format is "_n_cls",
6991 where 1 <= n <= nMethods, and cls is the name the implementation we
6993 - Install the return type from the method declaration.
6994 - If we have a prototype, check for type consistency. */
6997 really_start_method (method, parmlist)
6998 tree method, parmlist;
7000 tree sc_spec, ret_spec, ret_decl, decl_specs;
7001 tree method_decl, method_id;
7002 const char *sel_name, *class_name, *cat_name;
7005 /* Synth the storage class & assemble the return type. */
7006 sc_spec = tree_cons (NULL_TREE, ridpointers[(int) RID_STATIC], NULL_TREE);
7007 ret_spec = TREE_PURPOSE (TREE_TYPE (method));
7008 decl_specs = chainon (sc_spec, ret_spec);
7010 sel_name = IDENTIFIER_POINTER (METHOD_SEL_NAME (method));
7011 class_name = IDENTIFIER_POINTER (CLASS_NAME (objc_implementation_context));
7012 cat_name = ((TREE_CODE (objc_implementation_context)
7013 == CLASS_IMPLEMENTATION_TYPE)
7015 : IDENTIFIER_POINTER (CLASS_SUPER_NAME (objc_implementation_context)));
7018 /* Make sure this is big enough for any plausible method label. */
7019 buf = (char *) alloca (50 + strlen (sel_name) + strlen (class_name)
7020 + (cat_name ? strlen (cat_name) : 0));
7022 OBJC_GEN_METHOD_LABEL (buf, TREE_CODE (method) == INSTANCE_METHOD_DECL,
7023 class_name, cat_name, sel_name, method_slot);
7025 method_id = get_identifier (buf);
7027 method_decl = build_nt (CALL_EXPR, method_id, parmlist, NULL_TREE);
7029 /* Check the declarator portion of the return type for the method. */
7030 if ((ret_decl = TREE_VALUE (TREE_TYPE (method))))
7032 /* Unite the complex decl (specified in the abstract decl) with the
7033 function decl just synthesized..(int *), (int (*)()), (int (*)[]). */
7034 tree save_expr = expr_last (ret_decl);
7036 TREE_OPERAND (save_expr, 0) = method_decl;
7037 method_decl = ret_decl;
7039 /* Fool the parser into thinking it is starting a function. */
7040 start_function (decl_specs, method_decl, NULL_TREE);
7042 /* Unhook: this has the effect of restoring the abstract declarator. */
7043 TREE_OPERAND (save_expr, 0) = NULL_TREE;
7048 TREE_VALUE (TREE_TYPE (method)) = method_decl;
7050 /* Fool the parser into thinking it is starting a function. */
7051 start_function (decl_specs, method_decl, NULL_TREE);
7053 /* Unhook: this has the effect of restoring the abstract declarator. */
7054 TREE_VALUE (TREE_TYPE (method)) = NULL_TREE;
7057 METHOD_DEFINITION (method) = current_function_decl;
7059 /* Check consistency...start_function, pushdecl, duplicate_decls. */
7061 if (implementation_template != objc_implementation_context)
7065 if (TREE_CODE (method) == INSTANCE_METHOD_DECL)
7066 proto = lookup_instance_method_static (implementation_template,
7067 METHOD_SEL_NAME (method));
7069 proto = lookup_class_method_static (implementation_template,
7070 METHOD_SEL_NAME (method));
7072 if (proto && ! comp_method_with_proto (method, proto))
7074 char type = (TREE_CODE (method) == INSTANCE_METHOD_DECL ? '-' : '+');
7076 warn_with_method ("conflicting types for", type, method);
7077 warn_with_method ("previous declaration of", type, proto);
7082 /* The following routine is always called...this "architecture" is to
7083 accommodate "old-style" variable length selectors.
7085 - a:a b:b // prototype ; id c; id d; // old-style. */
7088 continue_method_def ()
7092 if (METHOD_ADD_ARGS (objc_method_context) == objc_ellipsis_node)
7093 /* We have a `, ...' immediately following the selector. */
7094 parmlist = get_parm_info (0);
7096 parmlist = get_parm_info (1); /* place a `void_at_end' */
7098 /* Set self_decl from the first argument...this global is used by
7099 build_ivar_reference calling build_indirect_ref. */
7100 self_decl = TREE_PURPOSE (parmlist);
7103 really_start_method (objc_method_context, parmlist);
7104 store_parm_decls ();
7107 /* Called by the parser, from the `pushlevel' production. */
7112 if (!UOBJC_SUPER_decl)
7114 UOBJC_SUPER_decl = start_decl (get_identifier (UTAG_SUPER),
7115 build_tree_list (NULL_TREE,
7116 objc_super_template),
7119 finish_decl (UOBJC_SUPER_decl, NULL_TREE, NULL_TREE);
7121 /* This prevents `unused variable' warnings when compiling with -Wall. */
7122 TREE_USED (UOBJC_SUPER_decl) = 1;
7123 DECL_ARTIFICIAL (UOBJC_SUPER_decl) = 1;
7127 /* _n_Method (id self, SEL sel, ...)
7129 struct objc_super _S;
7130 _msgSuper ((_S.self = self, _S.class = _cls, &_S), ...);
7134 get_super_receiver ()
7136 if (objc_method_context)
7138 tree super_expr, super_expr_list;
7140 /* Set receiver to self. */
7141 super_expr = build_component_ref (UOBJC_SUPER_decl, self_id);
7142 super_expr = build_modify_expr (super_expr, NOP_EXPR, self_decl);
7143 super_expr_list = build_tree_list (NULL_TREE, super_expr);
7145 /* Set class to begin searching. */
7146 super_expr = build_component_ref (UOBJC_SUPER_decl,
7147 get_identifier ("class"));
7149 if (TREE_CODE (objc_implementation_context) == CLASS_IMPLEMENTATION_TYPE)
7151 /* [_cls, __cls]Super are "pre-built" in
7152 synth_forward_declarations. */
7154 super_expr = build_modify_expr (super_expr, NOP_EXPR,
7155 ((TREE_CODE (objc_method_context)
7156 == INSTANCE_METHOD_DECL)
7158 : uucls_super_ref));
7162 /* We have a category. */
7164 tree super_name = CLASS_SUPER_NAME (implementation_template);
7167 /* Barf if super used in a category of Object. */
7170 error ("no super class declared in interface for `%s'",
7171 IDENTIFIER_POINTER (CLASS_NAME (implementation_template)));
7172 return error_mark_node;
7175 if (flag_next_runtime)
7177 super_class = get_class_reference (super_name);
7178 if (TREE_CODE (objc_method_context) == CLASS_METHOD_DECL)
7180 = build_component_ref (build_indirect_ref (super_class, "->"),
7181 get_identifier ("isa"));
7185 add_class_reference (super_name);
7186 super_class = (TREE_CODE (objc_method_context) == INSTANCE_METHOD_DECL
7187 ? objc_get_class_decl : objc_get_meta_class_decl);
7188 assemble_external (super_class);
7190 = build_function_call
7194 my_build_string (IDENTIFIER_LENGTH (super_name) + 1,
7195 IDENTIFIER_POINTER (super_name))));
7198 TREE_TYPE (super_class) = TREE_TYPE (ucls_super_ref);
7199 super_expr = build_modify_expr (super_expr, NOP_EXPR, super_class);
7202 chainon (super_expr_list, build_tree_list (NULL_TREE, super_expr));
7204 super_expr = build_unary_op (ADDR_EXPR, UOBJC_SUPER_decl, 0);
7205 chainon (super_expr_list, build_tree_list (NULL_TREE, super_expr));
7207 return build_compound_expr (super_expr_list);
7211 error ("[super ...] must appear in a method context");
7212 return error_mark_node;
7217 encode_method_def (func_decl)
7222 HOST_WIDE_INT max_parm_end = 0;
7227 encode_type (TREE_TYPE (TREE_TYPE (func_decl)),
7228 obstack_object_size (&util_obstack),
7229 OBJC_ENCODE_INLINE_DEFS);
7232 for (parms = DECL_ARGUMENTS (func_decl); parms;
7233 parms = TREE_CHAIN (parms))
7235 HOST_WIDE_INT parm_end = (forwarding_offset (parms)
7236 + int_size_in_bytes (TREE_TYPE (parms)));
7238 if (! offset_is_register && parm_end > max_parm_end)
7239 max_parm_end = parm_end;
7242 stack_size = max_parm_end - OBJC_FORWARDING_MIN_OFFSET;
7244 sprintf (buffer, "%d", stack_size);
7245 obstack_grow (&util_obstack, buffer, strlen (buffer));
7247 /* Argument types. */
7248 for (parms = DECL_ARGUMENTS (func_decl); parms;
7249 parms = TREE_CHAIN (parms))
7252 encode_type (TREE_TYPE (parms),
7253 obstack_object_size (&util_obstack),
7254 OBJC_ENCODE_INLINE_DEFS);
7256 /* Compute offset. */
7257 sprintf (buffer, "%d", forwarding_offset (parms));
7259 /* Indicate register. */
7260 if (offset_is_register)
7261 obstack_1grow (&util_obstack, '+');
7263 obstack_grow (&util_obstack, buffer, strlen (buffer));
7266 /* Null terminate string. */
7267 obstack_1grow (&util_obstack, 0);
7268 result = get_identifier (obstack_finish (&util_obstack));
7269 obstack_free (&util_obstack, util_firstobj);
7274 objc_expand_function_end ()
7276 METHOD_ENCODING (objc_method_context) = encode_method_def (current_function_decl);
7280 finish_method_def ()
7282 lang_expand_function_end = objc_expand_function_end;
7283 finish_function (0);
7284 lang_expand_function_end = NULL;
7286 /* Required to implement _msgSuper. This must be done AFTER finish_function,
7287 since the optimizer may find "may be used before set" errors. */
7288 objc_method_context = NULL_TREE;
7293 lang_report_error_function (decl)
7296 if (objc_method_context)
7298 fprintf (stderr, "In method `%s'\n",
7299 IDENTIFIER_POINTER (METHOD_SEL_NAME (objc_method_context)));
7309 is_complex_decl (type)
7312 return (TREE_CODE (type) == ARRAY_TYPE
7313 || TREE_CODE (type) == FUNCTION_TYPE
7314 || (TREE_CODE (type) == POINTER_TYPE && ! IS_ID (type)));
7318 /* Code to convert a decl node into text for a declaration in C. */
7320 static char tmpbuf[256];
7323 adorn_decl (decl, str)
7327 enum tree_code code = TREE_CODE (decl);
7329 if (code == ARRAY_REF)
7331 tree an_int_cst = TREE_OPERAND (decl, 1);
7333 if (an_int_cst && TREE_CODE (an_int_cst) == INTEGER_CST)
7334 sprintf (str + strlen (str), "[%ld]",
7335 (long) TREE_INT_CST_LOW (an_int_cst));
7340 else if (code == ARRAY_TYPE)
7342 tree an_int_cst = TYPE_SIZE (decl);
7343 tree array_of = TREE_TYPE (decl);
7345 if (an_int_cst && TREE_CODE (an_int_cst) == INTEGER_TYPE)
7346 sprintf (str + strlen (str), "[%ld]",
7347 (long) (TREE_INT_CST_LOW (an_int_cst)
7348 / TREE_INT_CST_LOW (TYPE_SIZE (array_of))));
7353 else if (code == CALL_EXPR)
7355 tree chain = TREE_PURPOSE (TREE_OPERAND (decl, 1));
7360 gen_declaration_1 (chain, str);
7361 chain = TREE_CHAIN (chain);
7368 else if (code == FUNCTION_TYPE)
7370 tree chain = TYPE_ARG_TYPES (decl);
7373 while (chain && TREE_VALUE (chain) != void_type_node)
7375 gen_declaration_1 (TREE_VALUE (chain), str);
7376 chain = TREE_CHAIN (chain);
7377 if (chain && TREE_VALUE (chain) != void_type_node)
7383 else if (code == INDIRECT_REF)
7385 strcpy (tmpbuf, "*");
7386 if (TREE_TYPE (decl) && TREE_CODE (TREE_TYPE (decl)) == TREE_LIST)
7390 for (chain = nreverse (copy_list (TREE_TYPE (decl)));
7392 chain = TREE_CHAIN (chain))
7394 if (TREE_CODE (TREE_VALUE (chain)) == IDENTIFIER_NODE)
7396 strcat (tmpbuf, " ");
7397 strcat (tmpbuf, IDENTIFIER_POINTER (TREE_VALUE (chain)));
7401 strcat (tmpbuf, " ");
7403 strcat (tmpbuf, str);
7404 strcpy (str, tmpbuf);
7407 else if (code == POINTER_TYPE)
7409 strcpy (tmpbuf, "*");
7410 if (TREE_READONLY (decl) || TYPE_VOLATILE (decl))
7412 if (TREE_READONLY (decl))
7413 strcat (tmpbuf, " const");
7414 if (TYPE_VOLATILE (decl))
7415 strcat (tmpbuf, " volatile");
7417 strcat (tmpbuf, " ");
7419 strcat (tmpbuf, str);
7420 strcpy (str, tmpbuf);
7425 gen_declarator (decl, buf, name)
7432 enum tree_code code = TREE_CODE (decl);
7442 op = TREE_OPERAND (decl, 0);
7444 /* We have a pointer to a function or array...(*)(), (*)[] */
7445 if ((code == ARRAY_REF || code == CALL_EXPR)
7446 && op && TREE_CODE (op) == INDIRECT_REF)
7449 str = gen_declarator (op, buf, name);
7453 strcpy (tmpbuf, "(");
7454 strcat (tmpbuf, str);
7455 strcat (tmpbuf, ")");
7456 strcpy (str, tmpbuf);
7459 adorn_decl (decl, str);
7468 /* This clause is done iteratively rather than recursively. */
7471 op = (is_complex_decl (TREE_TYPE (decl))
7472 ? TREE_TYPE (decl) : NULL_TREE);
7474 adorn_decl (decl, str);
7476 /* We have a pointer to a function or array...(*)(), (*)[] */
7477 if (code == POINTER_TYPE
7478 && op && (TREE_CODE (op) == FUNCTION_TYPE
7479 || TREE_CODE (op) == ARRAY_TYPE))
7481 strcpy (tmpbuf, "(");
7482 strcat (tmpbuf, str);
7483 strcat (tmpbuf, ")");
7484 strcpy (str, tmpbuf);
7487 decl = (is_complex_decl (TREE_TYPE (decl))
7488 ? TREE_TYPE (decl) : NULL_TREE);
7491 while (decl && (code = TREE_CODE (decl)))
7496 case IDENTIFIER_NODE:
7497 /* Will only happen if we are processing a "raw" expr-decl. */
7498 strcpy (buf, IDENTIFIER_POINTER (decl));
7509 /* We have an abstract declarator or a _DECL node. */
7517 gen_declspecs (declspecs, buf, raw)
7526 for (chain = nreverse (copy_list (declspecs));
7527 chain; chain = TREE_CHAIN (chain))
7529 tree aspec = TREE_VALUE (chain);
7531 if (TREE_CODE (aspec) == IDENTIFIER_NODE)
7532 strcat (buf, IDENTIFIER_POINTER (aspec));
7533 else if (TREE_CODE (aspec) == RECORD_TYPE)
7535 if (TYPE_NAME (aspec))
7537 tree protocol_list = TYPE_PROTOCOL_LIST (aspec);
7539 if (! TREE_STATIC_TEMPLATE (aspec))
7540 strcat (buf, "struct ");
7541 strcat (buf, IDENTIFIER_POINTER (TYPE_NAME (aspec)));
7546 tree chain = protocol_list;
7553 (PROTOCOL_NAME (TREE_VALUE (chain))));
7554 chain = TREE_CHAIN (chain);
7563 strcat (buf, "untagged struct");
7566 else if (TREE_CODE (aspec) == UNION_TYPE)
7568 if (TYPE_NAME (aspec))
7570 if (! TREE_STATIC_TEMPLATE (aspec))
7571 strcat (buf, "union ");
7572 strcat (buf, IDENTIFIER_POINTER (TYPE_NAME (aspec)));
7575 strcat (buf, "untagged union");
7578 else if (TREE_CODE (aspec) == ENUMERAL_TYPE)
7580 if (TYPE_NAME (aspec))
7582 if (! TREE_STATIC_TEMPLATE (aspec))
7583 strcat (buf, "enum ");
7584 strcat (buf, IDENTIFIER_POINTER (TYPE_NAME (aspec)));
7587 strcat (buf, "untagged enum");
7590 else if (TREE_CODE (aspec) == TYPE_DECL && DECL_NAME (aspec))
7591 strcat (buf, IDENTIFIER_POINTER (DECL_NAME (aspec)));
7593 else if (IS_ID (aspec))
7595 tree protocol_list = TYPE_PROTOCOL_LIST (aspec);
7600 tree chain = protocol_list;
7607 (PROTOCOL_NAME (TREE_VALUE (chain))));
7608 chain = TREE_CHAIN (chain);
7615 if (TREE_CHAIN (chain))
7621 /* Type qualifiers. */
7622 if (TREE_READONLY (declspecs))
7623 strcat (buf, "const ");
7624 if (TYPE_VOLATILE (declspecs))
7625 strcat (buf, "volatile ");
7627 switch (TREE_CODE (declspecs))
7629 /* Type specifiers. */
7632 declspecs = TYPE_MAIN_VARIANT (declspecs);
7634 /* Signed integer types. */
7636 if (declspecs == short_integer_type_node)
7637 strcat (buf, "short int ");
7638 else if (declspecs == integer_type_node)
7639 strcat (buf, "int ");
7640 else if (declspecs == long_integer_type_node)
7641 strcat (buf, "long int ");
7642 else if (declspecs == long_long_integer_type_node)
7643 strcat (buf, "long long int ");
7644 else if (declspecs == signed_char_type_node
7645 || declspecs == char_type_node)
7646 strcat (buf, "char ");
7648 /* Unsigned integer types. */
7650 else if (declspecs == short_unsigned_type_node)
7651 strcat (buf, "unsigned short ");
7652 else if (declspecs == unsigned_type_node)
7653 strcat (buf, "unsigned int ");
7654 else if (declspecs == long_unsigned_type_node)
7655 strcat (buf, "unsigned long ");
7656 else if (declspecs == long_long_unsigned_type_node)
7657 strcat (buf, "unsigned long long ");
7658 else if (declspecs == unsigned_char_type_node)
7659 strcat (buf, "unsigned char ");
7663 declspecs = TYPE_MAIN_VARIANT (declspecs);
7665 if (declspecs == float_type_node)
7666 strcat (buf, "float ");
7667 else if (declspecs == double_type_node)
7668 strcat (buf, "double ");
7669 else if (declspecs == long_double_type_node)
7670 strcat (buf, "long double ");
7674 if (TYPE_NAME (declspecs)
7675 && TREE_CODE (TYPE_NAME (declspecs)) == IDENTIFIER_NODE)
7677 tree protocol_list = TYPE_PROTOCOL_LIST (declspecs);
7679 if (! TREE_STATIC_TEMPLATE (declspecs))
7680 strcat (buf, "struct ");
7681 strcat (buf, IDENTIFIER_POINTER (TYPE_NAME (declspecs)));
7685 tree chain = protocol_list;
7692 (PROTOCOL_NAME (TREE_VALUE (chain))));
7693 chain = TREE_CHAIN (chain);
7702 strcat (buf, "untagged struct");
7708 if (TYPE_NAME (declspecs)
7709 && TREE_CODE (TYPE_NAME (declspecs)) == IDENTIFIER_NODE)
7711 strcat (buf, "union ");
7712 strcat (buf, IDENTIFIER_POINTER (TYPE_NAME (declspecs)));
7717 strcat (buf, "untagged union ");
7721 if (TYPE_NAME (declspecs)
7722 && TREE_CODE (TYPE_NAME (declspecs)) == IDENTIFIER_NODE)
7724 strcat (buf, "enum ");
7725 strcat (buf, IDENTIFIER_POINTER (TYPE_NAME (declspecs)));
7730 strcat (buf, "untagged enum ");
7734 strcat (buf, "void ");
7739 tree protocol_list = TYPE_PROTOCOL_LIST (declspecs);
7744 tree chain = protocol_list;
7751 (PROTOCOL_NAME (TREE_VALUE (chain))));
7752 chain = TREE_CHAIN (chain);
7768 /* Given a tree node, produce a printable description of it in the given
7769 buffer, overwriting the buffer. */
7772 gen_declaration (atype_or_adecl, buf)
7773 tree atype_or_adecl;
7777 gen_declaration_1 (atype_or_adecl, buf);
7781 /* Given a tree node, append a printable description to the end of the
7785 gen_declaration_1 (atype_or_adecl, buf)
7786 tree atype_or_adecl;
7791 if (TREE_CODE (atype_or_adecl) == TREE_LIST)
7793 tree declspecs; /* "identifier_node", "record_type" */
7794 tree declarator; /* "array_ref", "indirect_ref", "call_expr"... */
7796 /* We have a "raw", abstract declarator (typename). */
7797 declarator = TREE_VALUE (atype_or_adecl);
7798 declspecs = TREE_PURPOSE (atype_or_adecl);
7800 gen_declspecs (declspecs, buf, 1);
7804 strcat (buf, gen_declarator (declarator, declbuf, ""));
7811 tree declspecs; /* "integer_type", "real_type", "record_type"... */
7812 tree declarator; /* "array_type", "function_type", "pointer_type". */
7814 if (TREE_CODE (atype_or_adecl) == FIELD_DECL
7815 || TREE_CODE (atype_or_adecl) == PARM_DECL
7816 || TREE_CODE (atype_or_adecl) == FUNCTION_DECL)
7817 atype = TREE_TYPE (atype_or_adecl);
7819 /* Assume we have a *_type node. */
7820 atype = atype_or_adecl;
7822 if (is_complex_decl (atype))
7826 /* Get the declaration specifier; it is at the end of the list. */
7827 declarator = chain = atype;
7829 chain = TREE_TYPE (chain); /* not TREE_CHAIN (chain); */
7830 while (is_complex_decl (chain));
7837 declarator = NULL_TREE;
7840 gen_declspecs (declspecs, buf, 0);
7842 if (TREE_CODE (atype_or_adecl) == FIELD_DECL
7843 || TREE_CODE (atype_or_adecl) == PARM_DECL
7844 || TREE_CODE (atype_or_adecl) == FUNCTION_DECL)
7846 const char *const decl_name =
7847 (DECL_NAME (atype_or_adecl)
7848 ? IDENTIFIER_POINTER (DECL_NAME (atype_or_adecl)) : "");
7853 strcat (buf, gen_declarator (declarator, declbuf, decl_name));
7856 else if (decl_name[0])
7859 strcat (buf, decl_name);
7862 else if (declarator)
7865 strcat (buf, gen_declarator (declarator, declbuf, ""));
7870 #define RAW_TYPESPEC(meth) (TREE_VALUE (TREE_PURPOSE (TREE_TYPE (meth))))
7872 /* Given a method tree, put a printable description into the given
7873 buffer (overwriting) and return a pointer to the buffer. */
7876 gen_method_decl (method, buf)
7883 if (RAW_TYPESPEC (method) != objc_object_reference)
7886 gen_declaration_1 (TREE_TYPE (method), buf);
7890 chain = METHOD_SEL_ARGS (method);
7893 /* We have a chain of keyword_decls. */
7896 if (KEYWORD_KEY_NAME (chain))
7897 strcat (buf, IDENTIFIER_POINTER (KEYWORD_KEY_NAME (chain)));
7900 if (RAW_TYPESPEC (chain) != objc_object_reference)
7903 gen_declaration_1 (TREE_TYPE (chain), buf);
7907 strcat (buf, IDENTIFIER_POINTER (KEYWORD_ARG_NAME (chain)));
7908 if ((chain = TREE_CHAIN (chain)))
7913 if (METHOD_ADD_ARGS (method) == objc_ellipsis_node)
7914 strcat (buf, ", ...");
7915 else if (METHOD_ADD_ARGS (method))
7917 /* We have a tree list node as generate by get_parm_info. */
7918 chain = TREE_PURPOSE (METHOD_ADD_ARGS (method));
7920 /* Know we have a chain of parm_decls. */
7924 gen_declaration_1 (chain, buf);
7925 chain = TREE_CHAIN (chain);
7931 /* We have a unary selector. */
7932 strcat (buf, IDENTIFIER_POINTER (METHOD_SEL_NAME (method)));
7940 dump_interface (fp, chain)
7944 char *buf = (char *)xmalloc (256);
7945 const char *my_name = IDENTIFIER_POINTER (CLASS_NAME (chain));
7946 tree ivar_decls = CLASS_RAW_IVARS (chain);
7947 tree nst_methods = CLASS_NST_METHODS (chain);
7948 tree cls_methods = CLASS_CLS_METHODS (chain);
7950 fprintf (fp, "\n@interface %s", my_name);
7952 if (CLASS_SUPER_NAME (chain))
7954 const char *super_name = IDENTIFIER_POINTER (CLASS_SUPER_NAME (chain));
7955 fprintf (fp, " : %s\n", super_name);
7962 fprintf (fp, "{\n");
7965 fprintf (fp, "\t%s;\n", gen_declaration (ivar_decls, buf));
7966 ivar_decls = TREE_CHAIN (ivar_decls);
7969 fprintf (fp, "}\n");
7974 fprintf (fp, "- %s;\n", gen_method_decl (nst_methods, buf));
7975 nst_methods = TREE_CHAIN (nst_methods);
7980 fprintf (fp, "+ %s;\n", gen_method_decl (cls_methods, buf));
7981 cls_methods = TREE_CHAIN (cls_methods);
7983 fprintf (fp, "\n@end");
7986 /* Demangle function for Objective-C */
7988 objc_demangle (mangled)
7989 const char *mangled;
7991 char *demangled, *cp;
7993 if (mangled[0] == '_' &&
7994 (mangled[1] == 'i' || mangled[1] == 'c') &&
7997 cp = demangled = xmalloc(strlen(mangled) + 2);
7998 if (mangled[1] == 'i')
7999 *cp++ = '-'; /* for instance method */
8001 *cp++ = '+'; /* for class method */
8002 *cp++ = '['; /* opening left brace */
8003 strcpy(cp, mangled+3); /* tack on the rest of the mangled name */
8004 while (*cp && *cp == '_')
8005 cp++; /* skip any initial underbars in class name */
8006 cp = strchr(cp, '_'); /* find first non-initial underbar */
8009 free(demangled); /* not mangled name */
8012 if (cp[1] == '_') /* easy case: no category name */
8014 *cp++ = ' '; /* replace two '_' with one ' ' */
8015 strcpy(cp, mangled + (cp - demangled) + 2);
8019 *cp++ = '('; /* less easy case: category name */
8020 cp = strchr(cp, '_');
8023 free(demangled); /* not mangled name */
8027 *cp++ = ' '; /* overwriting 1st char of method name... */
8028 strcpy(cp, mangled + (cp - demangled)); /* get it back */
8030 while (*cp && *cp == '_')
8031 cp++; /* skip any initial underbars in method name */
8034 *cp = ':'; /* replace remaining '_' with ':' */
8035 *cp++ = ']'; /* closing right brace */
8036 *cp++ = 0; /* string terminator */
8040 return mangled; /* not an objc mangled name */
8044 objc_printable_name (decl, kind)
8046 int kind ATTRIBUTE_UNUSED;
8048 return objc_demangle (IDENTIFIER_POINTER (DECL_NAME (decl)));
8054 /* Add the special tree codes of Objective C to the tables. */
8056 gcc_obstack_init (&util_obstack);
8057 util_firstobj = (char *) obstack_finish (&util_obstack);
8059 memcpy (tree_code_type + (int) LAST_BASE_TREE_CODE,
8060 objc_tree_code_type,
8061 (int) LAST_OBJC_TREE_CODE - (int) LAST_BASE_TREE_CODE);
8062 memcpy (tree_code_length + (int) LAST_BASE_TREE_CODE,
8063 objc_tree_code_length,
8064 (((int) LAST_OBJC_TREE_CODE - (int) LAST_BASE_TREE_CODE) * sizeof (int)));
8065 memcpy (tree_code_name + (int) LAST_BASE_TREE_CODE,
8066 objc_tree_code_name,
8067 (((int) LAST_OBJC_TREE_CODE - (int) LAST_BASE_TREE_CODE) * sizeof (char *)));
8069 errbuf = (char *)xmalloc (BUFSIZE);
8071 synth_module_prologue ();
8077 struct imp_entry *impent;
8079 /* The internally generated initializers appear to have missing braces.
8080 Don't warn about this. */
8081 int save_warn_missing_braces = warn_missing_braces;
8082 warn_missing_braces = 0;
8084 /* A missing @end may not be detected by the parser. */
8085 if (objc_implementation_context)
8087 warning ("`@end' missing in implementation context");
8088 finish_class (objc_implementation_context);
8089 objc_ivar_chain = NULL_TREE;
8090 objc_implementation_context = NULL_TREE;
8093 generate_forward_declaration_to_string_table ();
8095 #ifdef OBJC_PROLOGUE
8099 /* Process the static instances here because initialization of objc_symtab
8101 if (objc_static_instances)
8102 generate_static_references ();
8104 if (imp_list || class_names_chain
8105 || meth_var_names_chain || meth_var_types_chain || sel_ref_chain)
8106 generate_objc_symtab_decl ();
8108 for (impent = imp_list; impent; impent = impent->next)
8110 objc_implementation_context = impent->imp_context;
8111 implementation_template = impent->imp_template;
8113 UOBJC_CLASS_decl = impent->class_decl;
8114 UOBJC_METACLASS_decl = impent->meta_decl;
8116 if (TREE_CODE (objc_implementation_context) == CLASS_IMPLEMENTATION_TYPE)
8118 /* all of the following reference the string pool... */
8119 generate_ivar_lists ();
8120 generate_dispatch_tables ();
8121 generate_shared_structures ();
8125 generate_dispatch_tables ();
8126 generate_category (objc_implementation_context);
8130 /* If we are using an array of selectors, we must always
8131 finish up the array decl even if no selectors were used. */
8132 if (! flag_next_runtime || sel_ref_chain)
8133 build_selector_translation_table ();
8136 generate_protocols ();
8138 if (objc_implementation_context || class_names_chain || objc_static_instances
8139 || meth_var_names_chain || meth_var_types_chain || sel_ref_chain)
8141 /* Arrange for Objc data structures to be initialized at run time. */
8142 rtx init_sym = build_module_descriptor ();
8143 if (init_sym && targetm.have_ctors_dtors)
8144 (* targetm.asm_out.constructor) (init_sym, DEFAULT_INIT_PRIORITY);
8147 /* Dump the class references. This forces the appropriate classes
8148 to be linked into the executable image, preserving unix archive
8149 semantics. This can be removed when we move to a more dynamically
8150 linked environment. */
8152 for (chain = cls_ref_chain; chain; chain = TREE_CHAIN (chain))
8154 handle_class_ref (chain);
8155 if (TREE_PURPOSE (chain))
8156 generate_classref_translation_entry (chain);
8159 for (impent = imp_list; impent; impent = impent->next)
8160 handle_impent (impent);
8162 /* Dump the string table last. */
8164 generate_strings ();
8166 if (flag_gen_declaration)
8168 add_class (objc_implementation_context);
8169 dump_interface (gen_declaration_file, objc_implementation_context);
8177 /* Run through the selector hash tables and print a warning for any
8178 selector which has multiple methods. */
8180 for (slot = 0; slot < SIZEHASHTABLE; slot++)
8181 for (hsh = cls_method_hash_list[slot]; hsh; hsh = hsh->next)
8184 tree meth = hsh->key;
8185 char type = (TREE_CODE (meth) == INSTANCE_METHOD_DECL
8189 warning ("potential selector conflict for method `%s'",
8190 IDENTIFIER_POINTER (METHOD_SEL_NAME (meth)));
8191 warn_with_method ("found", type, meth);
8192 for (loop = hsh->list; loop; loop = loop->next)
8193 warn_with_method ("found", type, loop->value);
8196 for (slot = 0; slot < SIZEHASHTABLE; slot++)
8197 for (hsh = nst_method_hash_list[slot]; hsh; hsh = hsh->next)
8200 tree meth = hsh->key;
8201 char type = (TREE_CODE (meth) == INSTANCE_METHOD_DECL
8205 warning ("potential selector conflict for method `%s'",
8206 IDENTIFIER_POINTER (METHOD_SEL_NAME (meth)));
8207 warn_with_method ("found", type, meth);
8208 for (loop = hsh->list; loop; loop = loop->next)
8209 warn_with_method ("found", type, loop->value);
8213 warn_missing_braces = save_warn_missing_braces;
8216 /* Subroutines of finish_objc. */
8219 generate_classref_translation_entry (chain)
8222 tree expr, name, decl_specs, decl, sc_spec;
8225 type = TREE_TYPE (TREE_PURPOSE (chain));
8227 expr = add_objc_string (TREE_VALUE (chain), class_names);
8228 expr = build_c_cast (type, expr); /* cast! */
8230 name = DECL_NAME (TREE_PURPOSE (chain));
8232 sc_spec = build_tree_list (NULL_TREE, ridpointers[(int) RID_STATIC]);
8234 /* static struct objc_class * _OBJC_CLASS_REFERENCES_n = ...; */
8235 decl_specs = tree_cons (NULL_TREE, type, sc_spec);
8237 /* The decl that is returned from start_decl is the one that we
8238 forward declared in build_class_reference. */
8239 decl = start_decl (name, decl_specs, 1, NULL_TREE);
8240 DECL_CONTEXT (decl) = NULL_TREE;
8241 finish_decl (decl, expr, NULL_TREE);
8246 handle_class_ref (chain)
8249 const char *name = IDENTIFIER_POINTER (TREE_VALUE (chain));
8250 char *string = (char *) alloca (strlen (name) + 30);
8254 sprintf (string, "%sobjc_class_name_%s",
8255 (flag_next_runtime ? "." : "__"), name);
8257 #ifdef ASM_DECLARE_UNRESOLVED_REFERENCE
8258 if (flag_next_runtime)
8260 ASM_DECLARE_UNRESOLVED_REFERENCE (asm_out_file, string);
8265 /* Make a decl for this name, so we can use its address in a tree. */
8266 decl = build_decl (VAR_DECL, get_identifier (string), char_type_node);
8267 DECL_EXTERNAL (decl) = 1;
8268 TREE_PUBLIC (decl) = 1;
8271 rest_of_decl_compilation (decl, 0, 0, 0);
8273 /* Make a decl for the address. */
8274 sprintf (string, "%sobjc_class_ref_%s",
8275 (flag_next_runtime ? "." : "__"), name);
8276 exp = build1 (ADDR_EXPR, string_type_node, decl);
8277 decl = build_decl (VAR_DECL, get_identifier (string), string_type_node);
8278 DECL_INITIAL (decl) = exp;
8279 TREE_STATIC (decl) = 1;
8282 rest_of_decl_compilation (decl, 0, 0, 0);
8286 handle_impent (impent)
8287 struct imp_entry *impent;
8291 objc_implementation_context = impent->imp_context;
8292 implementation_template = impent->imp_template;
8294 if (TREE_CODE (impent->imp_context) == CLASS_IMPLEMENTATION_TYPE)
8296 const char *const class_name =
8297 IDENTIFIER_POINTER (CLASS_NAME (impent->imp_context));
8299 string = (char *) alloca (strlen (class_name) + 30);
8301 sprintf (string, "*%sobjc_class_name_%s",
8302 (flag_next_runtime ? "." : "__"), class_name);
8304 else if (TREE_CODE (impent->imp_context) == CATEGORY_IMPLEMENTATION_TYPE)
8306 const char *const class_name =
8307 IDENTIFIER_POINTER (CLASS_NAME (impent->imp_context));
8308 const char *const class_super_name =
8309 IDENTIFIER_POINTER (CLASS_SUPER_NAME (impent->imp_context));
8311 string = (char *) alloca (strlen (class_name)
8312 + strlen (class_super_name) + 30);
8314 /* Do the same for categories. Even though no references to
8315 these symbols are generated automatically by the compiler, it
8316 gives you a handle to pull them into an archive by hand. */
8317 sprintf (string, "*%sobjc_category_name_%s_%s",
8318 (flag_next_runtime ? "." : "__"), class_name, class_super_name);
8323 #ifdef ASM_DECLARE_CLASS_REFERENCE
8324 if (flag_next_runtime)
8326 ASM_DECLARE_CLASS_REFERENCE (asm_out_file, string);
8331 /* (Should this be a routine in varasm.c?) */
8332 readonly_data_section ();
8333 assemble_global (string);
8334 assemble_align (UNITS_PER_WORD);
8335 assemble_label (string);
8336 assemble_zeros (UNITS_PER_WORD);
8340 ggc_mark_imp_list (arg)
8343 struct imp_entry *impent;
8345 for (impent = *(struct imp_entry **)arg; impent; impent = impent->next)
8347 ggc_mark_tree (impent->imp_context);
8348 ggc_mark_tree (impent->imp_template);
8349 ggc_mark_tree (impent->class_decl);
8350 ggc_mark_tree (impent->meta_decl);
8355 ggc_mark_hash_table (arg)
8358 hash *hash_table = *(hash **)arg;
8363 if (hash_table == NULL)
8365 for (i = 0; i < SIZEHASHTABLE; i++)
8366 for (hst = hash_table [i]; hst; hst = hst->next)
8368 ggc_mark_tree (hst->key);
8369 for (list = hst->list; list; list = list->next)
8370 ggc_mark_tree (list->value);
8374 /* Add GC roots for variables local to this file. */
8376 objc_act_parse_init ()
8378 ggc_add_tree_root (objc_global_trees, OCTI_MAX);
8379 ggc_add_root (&imp_list, 1, sizeof imp_list, ggc_mark_imp_list);
8380 ggc_add_root (&nst_method_hash_list, 1, sizeof nst_method_hash_list, ggc_mark_hash_table);
8381 ggc_add_root (&cls_method_hash_list, 1, sizeof cls_method_hash_list, ggc_mark_hash_table);
8384 /* Look up ID as an instance variable. */
8386 lookup_objc_ivar (id)
8391 if (objc_receiver_context && !strcmp (IDENTIFIER_POINTER (id), "super"))
8392 /* we have a message to super */
8393 return get_super_receiver ();
8394 else if (objc_method_context && (decl = is_ivar (objc_ivar_chain, id)))
8396 if (is_private (decl))
8397 return error_mark_node;
8399 return build_ivar_reference (id);