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':
62 /* This is the default way of generating a method name. */
63 /* I am not sure it is really correct.
64 Perhaps there's a danger that it will make name conflicts
65 if method names contain underscores. -- rms. */
66 #ifndef OBJC_GEN_METHOD_LABEL
67 #define OBJC_GEN_METHOD_LABEL(BUF, IS_INST, CLASS_NAME, CAT_NAME, SEL_NAME, NUM) \
70 sprintf ((BUF), "_%s_%s_%s_%s", \
71 ((IS_INST) ? "i" : "c"), \
73 ((CAT_NAME)? (CAT_NAME) : ""), \
75 for (temp = (BUF); *temp; temp++) \
76 if (*temp == ':') *temp = '_'; \
80 /* These need specifying. */
81 #ifndef OBJC_FORWARDING_STACK_OFFSET
82 #define OBJC_FORWARDING_STACK_OFFSET 0
85 #ifndef OBJC_FORWARDING_MIN_OFFSET
86 #define OBJC_FORWARDING_MIN_OFFSET 0
89 /* Define the special tree codes that we use. */
91 /* Table indexed by tree code giving a string containing a character
92 classifying the tree code. */
94 #define DEFTREECODE(SYM, NAME, TYPE, LENGTH) TYPE,
96 static const char objc_tree_code_type[] = {
98 #include "objc-tree.def"
102 /* Table indexed by tree code giving number of expression
103 operands beyond the fixed part of the node structure.
104 Not used for types or decls. */
106 #define DEFTREECODE(SYM, NAME, TYPE, LENGTH) LENGTH,
108 static const int objc_tree_code_length[] = {
110 #include "objc-tree.def"
114 /* Names of tree components.
115 Used for printing out the tree and error messages. */
116 #define DEFTREECODE(SYM, NAME, TYPE, LEN) NAME,
118 static const char * const objc_tree_code_name[] = {
120 #include "objc-tree.def"
124 /* Set up for use of obstacks. */
128 #define obstack_chunk_alloc xmalloc
129 #define obstack_chunk_free free
131 /* This obstack is used to accumulate the encoding of a data type. */
132 static struct obstack util_obstack;
133 /* This points to the beginning of obstack contents,
134 so we can free the whole contents. */
137 /* for encode_method_def */
140 /* The version identifies which language generation and runtime
141 the module (file) was compiled for, and is recorded in the
142 module descriptor. */
144 #define OBJC_VERSION (flag_next_runtime ? 5 : 8)
145 #define PROTOCOL_VERSION 2
147 /* (Decide if these can ever be validly changed.) */
148 #define OBJC_ENCODE_INLINE_DEFS 0
149 #define OBJC_ENCODE_DONT_INLINE_DEFS 1
151 /*** Private Interface (procedures) ***/
153 /* Used by compile_file. */
155 static void init_objc PARAMS ((void));
156 static void finish_objc PARAMS ((void));
158 /* Code generation. */
160 static void synth_module_prologue PARAMS ((void));
161 static tree build_constructor PARAMS ((tree, tree));
162 static rtx build_module_descriptor PARAMS ((void));
163 static tree init_module_descriptor PARAMS ((tree));
164 static tree build_objc_method_call PARAMS ((int, tree, tree,
166 static void generate_strings PARAMS ((void));
167 static tree get_proto_encoding PARAMS ((tree));
168 static void build_selector_translation_table PARAMS ((void));
169 static tree build_ivar_chain PARAMS ((tree, int));
171 static tree objc_add_static_instance PARAMS ((tree, tree));
173 static tree build_ivar_template PARAMS ((void));
174 static tree build_method_template PARAMS ((void));
175 static tree build_private_template PARAMS ((tree));
176 static void build_class_template PARAMS ((void));
177 static void build_selector_template PARAMS ((void));
178 static void build_category_template PARAMS ((void));
179 static tree build_super_template PARAMS ((void));
180 static tree build_category_initializer PARAMS ((tree, tree, tree,
182 static tree build_protocol_initializer PARAMS ((tree, tree, tree,
185 static void synth_forward_declarations PARAMS ((void));
186 static void generate_ivar_lists PARAMS ((void));
187 static void generate_dispatch_tables PARAMS ((void));
188 static void generate_shared_structures PARAMS ((void));
189 static tree generate_protocol_list PARAMS ((tree));
190 static void generate_forward_declaration_to_string_table PARAMS ((void));
191 static void build_protocol_reference PARAMS ((tree));
193 static tree build_keyword_selector PARAMS ((tree));
194 static tree synth_id_with_class_suffix PARAMS ((const char *, tree));
196 static void generate_static_references PARAMS ((void));
197 static int check_methods_accessible PARAMS ((tree, tree,
199 static void encode_aggregate_within PARAMS ((tree, int, int,
201 static const char *objc_demangle PARAMS ((const char *));
202 static const char *objc_printable_name PARAMS ((tree, int));
203 static void objc_expand_function_end PARAMS ((void));
205 /* Hash tables to manage the global pool of method prototypes. */
207 hash *nst_method_hash_list = 0;
208 hash *cls_method_hash_list = 0;
210 static size_t hash_func PARAMS ((tree));
211 static void hash_init PARAMS ((void));
212 static void hash_enter PARAMS ((hash *, tree));
213 static hash hash_lookup PARAMS ((hash *, tree));
214 static void hash_add_attr PARAMS ((hash, tree));
215 static tree lookup_method PARAMS ((tree, tree));
216 static tree lookup_instance_method_static PARAMS ((tree, tree));
217 static tree lookup_class_method_static PARAMS ((tree, tree));
218 static tree add_class PARAMS ((tree));
219 static void add_category PARAMS ((tree, tree));
223 class_names, /* class, category, protocol, module names */
224 meth_var_names, /* method and variable names */
225 meth_var_types /* method and variable type descriptors */
228 static tree add_objc_string PARAMS ((tree,
229 enum string_section));
230 static tree get_objc_string_decl PARAMS ((tree,
231 enum string_section));
232 static tree build_objc_string_decl PARAMS ((enum string_section));
233 static tree build_selector_reference_decl PARAMS ((void));
235 /* Protocol additions. */
237 static tree add_protocol PARAMS ((tree));
238 static tree lookup_protocol PARAMS ((tree));
239 static void check_protocol_recursively PARAMS ((tree, tree));
240 static tree lookup_and_install_protocols PARAMS ((tree));
244 static void encode_type_qualifiers PARAMS ((tree));
245 static void encode_pointer PARAMS ((tree, int, int));
246 static void encode_array PARAMS ((tree, int, int));
247 static void encode_aggregate PARAMS ((tree, int, int));
248 static void encode_bitfield PARAMS ((int));
249 static void encode_type PARAMS ((tree, int, int));
250 static void encode_field_decl PARAMS ((tree, int, int));
252 static void really_start_method PARAMS ((tree, tree));
253 static int comp_method_with_proto PARAMS ((tree, tree));
254 static int comp_proto_with_proto PARAMS ((tree, tree));
255 static tree get_arg_type_list PARAMS ((tree, int, int));
256 static tree expr_last PARAMS ((tree));
258 /* Utilities for debugging and error diagnostics. */
260 static void warn_with_method PARAMS ((const char *, int, tree));
261 static void error_with_ivar PARAMS ((const char *, tree, tree));
262 static char *gen_method_decl PARAMS ((tree, char *));
263 static char *gen_declaration PARAMS ((tree, char *));
264 static void gen_declaration_1 PARAMS ((tree, char *));
265 static char *gen_declarator PARAMS ((tree, char *,
267 static int is_complex_decl PARAMS ((tree));
268 static void adorn_decl PARAMS ((tree, char *));
269 static void dump_interface PARAMS ((FILE *, tree));
271 /* Everything else. */
273 static void add_objc_tree_codes PARAMS ((void));
274 static tree define_decl PARAMS ((tree, tree));
275 static tree lookup_method_in_protocol_list PARAMS ((tree, tree, int));
276 static tree lookup_protocol_in_reflist PARAMS ((tree, tree));
277 static tree create_builtin_decl PARAMS ((enum tree_code,
278 tree, const char *));
279 static void setup_string_decl PARAMS ((void));
280 static void build_string_class_template PARAMS ((void));
281 static tree my_build_string PARAMS ((int, const char *));
282 static void build_objc_symtab_template PARAMS ((void));
283 static tree init_def_list PARAMS ((tree));
284 static tree init_objc_symtab PARAMS ((tree));
285 static void forward_declare_categories PARAMS ((void));
286 static void generate_objc_symtab_decl PARAMS ((void));
287 static tree build_selector PARAMS ((tree));
288 static tree build_typed_selector_reference PARAMS ((tree, tree));
289 static tree build_selector_reference PARAMS ((tree));
290 static tree build_class_reference_decl PARAMS ((void));
291 static void add_class_reference PARAMS ((tree));
292 static tree objc_copy_list PARAMS ((tree, tree *));
293 static tree build_protocol_template PARAMS ((void));
294 static tree build_descriptor_table_initializer PARAMS ((tree, tree));
295 static tree build_method_prototype_list_template PARAMS ((tree, int));
296 static tree build_method_prototype_template PARAMS ((void));
297 static int forwarding_offset PARAMS ((tree));
298 static tree encode_method_prototype PARAMS ((tree, tree));
299 static tree generate_descriptor_table PARAMS ((tree, const char *,
301 static void generate_method_descriptors PARAMS ((tree));
302 static tree build_tmp_function_decl PARAMS ((void));
303 static void hack_method_prototype PARAMS ((tree, tree));
304 static void generate_protocol_references PARAMS ((tree));
305 static void generate_protocols PARAMS ((void));
306 static void check_ivars PARAMS ((tree, tree));
307 static tree build_ivar_list_template PARAMS ((tree, int));
308 static tree build_method_list_template PARAMS ((tree, int));
309 static tree build_ivar_list_initializer PARAMS ((tree, tree));
310 static tree generate_ivars_list PARAMS ((tree, const char *,
312 static tree build_dispatch_table_initializer PARAMS ((tree, tree));
313 static tree generate_dispatch_table PARAMS ((tree, const char *,
315 static tree build_shared_structure_initializer PARAMS ((tree, tree, tree, tree,
316 tree, int, tree, tree,
318 static void generate_category PARAMS ((tree));
319 static int is_objc_type_qualifier PARAMS ((tree));
320 static tree adjust_type_for_id_default PARAMS ((tree));
321 static tree check_duplicates PARAMS ((hash));
322 static tree receiver_is_class_object PARAMS ((tree));
323 static int check_methods PARAMS ((tree, tree, int));
324 static int conforms_to_protocol PARAMS ((tree, tree));
325 static void check_protocol PARAMS ((tree, const char *,
327 static void check_protocols PARAMS ((tree, const char *,
329 static tree encode_method_def PARAMS ((tree));
330 static void gen_declspecs PARAMS ((tree, char *, int));
331 static void generate_classref_translation_entry PARAMS ((tree));
332 static void handle_class_ref PARAMS ((tree));
333 static void generate_struct_by_value_array PARAMS ((void))
335 static void objc_act_parse_init PARAMS ((void));
336 static void ggc_mark_imp_list PARAMS ((void *));
337 static void ggc_mark_hash_table PARAMS ((void *));
339 /*** Private Interface (data) ***/
341 /* Reserved tag definitions. */
344 #define TAG_OBJECT "objc_object"
345 #define TAG_CLASS "objc_class"
346 #define TAG_SUPER "objc_super"
347 #define TAG_SELECTOR "objc_selector"
349 #define UTAG_CLASS "_objc_class"
350 #define UTAG_IVAR "_objc_ivar"
351 #define UTAG_IVAR_LIST "_objc_ivar_list"
352 #define UTAG_METHOD "_objc_method"
353 #define UTAG_METHOD_LIST "_objc_method_list"
354 #define UTAG_CATEGORY "_objc_category"
355 #define UTAG_MODULE "_objc_module"
356 #define UTAG_STATICS "_objc_statics"
357 #define UTAG_SYMTAB "_objc_symtab"
358 #define UTAG_SUPER "_objc_super"
359 #define UTAG_SELECTOR "_objc_selector"
361 #define UTAG_PROTOCOL "_objc_protocol"
362 #define UTAG_PROTOCOL_LIST "_objc_protocol_list"
363 #define UTAG_METHOD_PROTOTYPE "_objc_method_prototype"
364 #define UTAG_METHOD_PROTOTYPE_LIST "_objc__method_prototype_list"
366 /* Note that the string object global name is only needed for the
368 #define STRING_OBJECT_GLOBAL_NAME "_NSConstantStringClassReference"
370 #define PROTOCOL_OBJECT_CLASS_NAME "Protocol"
372 static const char *constant_string_class_name = NULL;
374 static const char *TAG_GETCLASS;
375 static const char *TAG_GETMETACLASS;
376 static const char *TAG_MSGSEND;
377 static const char *TAG_MSGSENDSUPER;
378 static const char *TAG_EXECCLASS;
379 static const char *default_constant_string_class_name;
381 /* The OCTI_... enumeration itself is in objc/objc-act.h. */
382 tree objc_global_trees[OCTI_MAX];
384 int objc_receiver_context;
386 static void handle_impent PARAMS ((struct imp_entry *));
388 struct imp_entry *imp_list = 0;
389 int imp_count = 0; /* `@implementation' */
390 int cat_count = 0; /* `@category' */
392 static int method_slot = 0; /* Used by start_method_def, */
396 static char *errbuf; /* Buffer for error diagnostics */
398 /* Data imported from tree.c. */
400 extern enum debug_info_type write_symbols;
402 /* Data imported from toplev.c. */
404 extern const char *dump_base_name;
406 /* Generate code for GNU or NeXT runtime environment. */
408 #ifdef NEXT_OBJC_RUNTIME
409 int flag_next_runtime = 1;
411 int flag_next_runtime = 0;
414 int flag_typed_selectors;
416 /* Open and close the file for outputting class declarations, if requested. */
418 int flag_gen_declaration = 0;
420 FILE *gen_declaration_file;
422 /* Warn if multiple methods are seen for the same selector, but with
423 different argument types. */
425 int warn_selector = 0;
427 /* Warn if methods required by a protocol are not implemented in the
428 class adopting it. When turned off, methods inherited to that
429 class are also considered implemented */
431 int flag_warn_protocol = 1;
433 /* Tells "encode_pointer/encode_aggregate" whether we are generating
434 type descriptors for instance variables (as opposed to methods).
435 Type descriptors for instance variables contain more information
436 than methods (for static typing and embedded structures). */
438 static int generating_instance_variables = 0;
440 /* Tells the compiler that this is a special run. Do not perform any
441 compiling, instead we are to test some platform dependent features
442 and output a C header file with appropriate definitions. */
444 static int print_struct_values = 0;
446 /* Some platforms pass small structures through registers versus
447 through an invisible pointer. Determine at what size structure is
448 the transition point between the two possibilities. */
451 generate_struct_by_value_array ()
454 tree field_decl, field_decl_chain;
456 int aggregate_in_mem[32];
459 /* Presumably no platform passes 32 byte structures in a register. */
460 for (i = 1; i < 32; i++)
464 /* Create an unnamed struct that has `i' character components */
465 type = start_struct (RECORD_TYPE, NULL_TREE);
467 strcpy (buffer, "c1");
468 field_decl = create_builtin_decl (FIELD_DECL,
471 field_decl_chain = field_decl;
473 for (j = 1; j < i; j++)
475 sprintf (buffer, "c%d", j + 1);
476 field_decl = create_builtin_decl (FIELD_DECL,
479 chainon (field_decl_chain, field_decl);
481 finish_struct (type, field_decl_chain, NULL_TREE);
483 aggregate_in_mem[i] = aggregate_value_p (type);
484 if (!aggregate_in_mem[i])
488 /* We found some structures that are returned in registers instead of memory
489 so output the necessary data. */
492 for (i = 31; i >= 0; i--)
493 if (!aggregate_in_mem[i])
495 printf ("#define OBJC_MAX_STRUCT_BY_VALUE %d\n\n", i);
497 /* The first member of the structure is always 0 because we don't handle
498 structures with 0 members */
499 printf ("static int struct_forward_array[] = {\n 0");
501 for (j = 1; j <= i; j++)
502 printf (", %d", aggregate_in_mem[j]);
511 const char *filename;
513 filename = c_objc_common_init (filename);
514 add_objc_tree_codes ();
516 decl_printable_name = objc_printable_name;
518 /* Force the line number back to 0; check_newline will have
519 raised it to 1, which will make the builtin functions appear
520 not to be built in. */
523 /* If gen_declaration desired, open the output file. */
524 if (flag_gen_declaration)
526 register char * const dumpname = concat (dump_base_name, ".decl", NULL);
527 gen_declaration_file = fopen (dumpname, "w");
528 if (gen_declaration_file == 0)
529 fatal_io_error ("can't open %s", dumpname);
533 if (flag_next_runtime)
535 TAG_GETCLASS = "objc_getClass";
536 TAG_GETMETACLASS = "objc_getMetaClass";
537 TAG_MSGSEND = "objc_msgSend";
538 TAG_MSGSENDSUPER = "objc_msgSendSuper";
539 TAG_EXECCLASS = "__objc_execClass";
540 default_constant_string_class_name = "NSConstantString";
544 TAG_GETCLASS = "objc_get_class";
545 TAG_GETMETACLASS = "objc_get_meta_class";
546 TAG_MSGSEND = "objc_msg_lookup";
547 TAG_MSGSENDSUPER = "objc_msg_lookup_super";
548 TAG_EXECCLASS = "__objc_exec_class";
549 default_constant_string_class_name = "NXConstantString";
550 flag_typed_selectors = 1;
553 objc_ellipsis_node = make_node (ERROR_MARK);
557 if (print_struct_values)
558 generate_struct_by_value_array ();
560 objc_act_parse_init ();
568 c_objc_common_finish_file ();
570 finish_objc (); /* Objective-C finalization */
572 if (gen_declaration_file)
573 fclose (gen_declaration_file);
577 objc_decode_option (argc, argv)
581 const char *p = argv[0];
583 if (!strcmp (p, "-gen-decls"))
584 flag_gen_declaration = 1;
585 else if (!strcmp (p, "-Wselector"))
587 else if (!strcmp (p, "-Wno-selector"))
589 else if (!strcmp (p, "-Wprotocol"))
590 flag_warn_protocol = 1;
591 else if (!strcmp (p, "-Wno-protocol"))
592 flag_warn_protocol = 0;
593 else if (!strcmp (p, "-fgnu-runtime"))
594 flag_next_runtime = 0;
595 else if (!strcmp (p, "-fno-next-runtime"))
596 flag_next_runtime = 0;
597 else if (!strcmp (p, "-fno-gnu-runtime"))
598 flag_next_runtime = 1;
599 else if (!strcmp (p, "-fnext-runtime"))
600 flag_next_runtime = 1;
601 else if (!strcmp (p, "-print-objc-runtime-info"))
602 print_struct_values = 1;
603 #define CSTSTRCLASS "-fconstant-string-class="
604 else if (!strncmp (p, CSTSTRCLASS, sizeof(CSTSTRCLASS) - 2)) {
605 if (strlen (argv[0]) <= strlen (CSTSTRCLASS))
606 error ("no class name specified as argument to -fconstant-string-class");
607 constant_string_class_name = xstrdup(argv[0] + sizeof(CSTSTRCLASS) - 1);
611 return c_decode_option (argc, argv);
618 define_decl (declarator, declspecs)
622 tree decl = start_decl (declarator, declspecs, 0, NULL_TREE);
623 finish_decl (decl, NULL_TREE, NULL_TREE);
627 /* Return 1 if LHS and RHS are compatible types for assignment or
628 various other operations. Return 0 if they are incompatible, and
629 return -1 if we choose to not decide. When the operation is
630 REFLEXIVE, check for compatibility in either direction.
632 For statically typed objects, an assignment of the form `a' = `b'
636 `a' and `b' are the same class type, or
637 `a' and `b' are of class types A and B such that B is a descendant of A. */
640 maybe_objc_comptypes (lhs, rhs, reflexive)
644 return objc_comptypes (lhs, rhs, reflexive);
648 lookup_method_in_protocol_list (rproto_list, sel_name, class_meth)
656 for (rproto = rproto_list; rproto; rproto = TREE_CHAIN (rproto))
658 p = TREE_VALUE (rproto);
660 if (TREE_CODE (p) == PROTOCOL_INTERFACE_TYPE)
662 if ((fnd = lookup_method (class_meth
663 ? PROTOCOL_CLS_METHODS (p)
664 : PROTOCOL_NST_METHODS (p), sel_name)))
666 else if (PROTOCOL_LIST (p))
667 fnd = lookup_method_in_protocol_list (PROTOCOL_LIST (p),
668 sel_name, class_meth);
672 ; /* An identifier...if we could not find a protocol. */
683 lookup_protocol_in_reflist (rproto_list, lproto)
689 /* Make sure the protocol is supported by the object on the rhs. */
690 if (TREE_CODE (lproto) == PROTOCOL_INTERFACE_TYPE)
693 for (rproto = rproto_list; rproto; rproto = TREE_CHAIN (rproto))
695 p = TREE_VALUE (rproto);
697 if (TREE_CODE (p) == PROTOCOL_INTERFACE_TYPE)
702 else if (PROTOCOL_LIST (p))
703 fnd = lookup_protocol_in_reflist (PROTOCOL_LIST (p), lproto);
712 ; /* An identifier...if we could not find a protocol. */
718 /* Return 1 if LHS and RHS are compatible types for assignment
719 or various other operations. Return 0 if they are incompatible,
720 and return -1 if we choose to not decide. When the operation
721 is REFLEXIVE, check for compatibility in either direction. */
724 objc_comptypes (lhs, rhs, reflexive)
729 /* New clause for protocols. */
731 if (TREE_CODE (lhs) == POINTER_TYPE
732 && TREE_CODE (TREE_TYPE (lhs)) == RECORD_TYPE
733 && TREE_CODE (rhs) == POINTER_TYPE
734 && TREE_CODE (TREE_TYPE (rhs)) == RECORD_TYPE)
736 int lhs_is_proto = IS_PROTOCOL_QUALIFIED_ID (lhs);
737 int rhs_is_proto = IS_PROTOCOL_QUALIFIED_ID (rhs);
741 tree lproto, lproto_list = TYPE_PROTOCOL_LIST (lhs);
742 tree rproto, rproto_list;
747 rproto_list = TYPE_PROTOCOL_LIST (rhs);
749 /* Make sure the protocol is supported by the object
751 for (lproto = lproto_list; lproto; lproto = TREE_CHAIN (lproto))
753 p = TREE_VALUE (lproto);
754 rproto = lookup_protocol_in_reflist (rproto_list, p);
757 warning ("object does not conform to the `%s' protocol",
758 IDENTIFIER_POINTER (PROTOCOL_NAME (p)));
761 else if (TYPED_OBJECT (TREE_TYPE (rhs)))
763 tree rname = TYPE_NAME (TREE_TYPE (rhs));
766 /* Make sure the protocol is supported by the object
768 for (lproto = lproto_list; lproto; lproto = TREE_CHAIN (lproto))
770 p = TREE_VALUE (lproto);
772 rinter = lookup_interface (rname);
774 while (rinter && !rproto)
778 rproto_list = CLASS_PROTOCOL_LIST (rinter);
779 /* If the underlying ObjC class does not have
780 protocols attached to it, perhaps there are
781 "one-off" protocols attached to the rhs?
782 E.g., 'id<MyProt> foo;'. */
784 rproto_list = TYPE_PROTOCOL_LIST (TREE_TYPE (rhs));
785 rproto = lookup_protocol_in_reflist (rproto_list, p);
787 /* Check for protocols adopted by categories. */
788 cat = CLASS_CATEGORY_LIST (rinter);
789 while (cat && !rproto)
791 rproto_list = CLASS_PROTOCOL_LIST (cat);
792 rproto = lookup_protocol_in_reflist (rproto_list, p);
794 cat = CLASS_CATEGORY_LIST (cat);
797 rinter = lookup_interface (CLASS_SUPER_NAME (rinter));
801 warning ("class `%s' does not implement the `%s' protocol",
802 IDENTIFIER_POINTER (TYPE_NAME (TREE_TYPE (rhs))),
803 IDENTIFIER_POINTER (PROTOCOL_NAME (p)));
807 /* May change...based on whether there was any mismatch */
810 else if (rhs_is_proto)
811 /* Lhs is not a protocol...warn if it is statically typed */
812 return (TYPED_OBJECT (TREE_TYPE (lhs)) != 0);
815 /* Defer to comptypes. */
819 else if (TREE_CODE (lhs) == RECORD_TYPE && TREE_CODE (rhs) == RECORD_TYPE)
820 ; /* Fall thru. This is the case we have been handling all along */
822 /* Defer to comptypes. */
825 /* `id' = `<class> *', `<class> *' = `id' */
827 if ((TYPE_NAME (lhs) == objc_object_id && TYPED_OBJECT (rhs))
828 || (TYPE_NAME (rhs) == objc_object_id && TYPED_OBJECT (lhs)))
831 /* `id' = `Class', `Class' = `id' */
833 else if ((TYPE_NAME (lhs) == objc_object_id
834 && TYPE_NAME (rhs) == objc_class_id)
835 || (TYPE_NAME (lhs) == objc_class_id
836 && TYPE_NAME (rhs) == objc_object_id))
839 /* `<class> *' = `<class> *' */
841 else if (TYPED_OBJECT (lhs) && TYPED_OBJECT (rhs))
843 tree lname = TYPE_NAME (lhs);
844 tree rname = TYPE_NAME (rhs);
850 /* If the left hand side is a super class of the right hand side,
852 for (inter = lookup_interface (rname); inter;
853 inter = lookup_interface (CLASS_SUPER_NAME (inter)))
854 if (lname == CLASS_SUPER_NAME (inter))
857 /* Allow the reverse when reflexive. */
859 for (inter = lookup_interface (lname); inter;
860 inter = lookup_interface (CLASS_SUPER_NAME (inter)))
861 if (rname == CLASS_SUPER_NAME (inter))
867 /* Defer to comptypes. */
871 /* Called from c-decl.c before all calls to rest_of_decl_compilation. */
874 objc_check_decl (decl)
877 tree type = TREE_TYPE (decl);
879 if (TREE_CODE (type) == RECORD_TYPE
880 && TREE_STATIC_TEMPLATE (type)
881 && type != constant_string_type)
882 error_with_decl (decl, "`%s' cannot be statically allocated");
886 maybe_objc_check_decl (decl)
889 objc_check_decl (decl);
892 /* Implement static typing. At this point, we know we have an interface. */
895 get_static_reference (interface, protocols)
899 tree type = xref_tag (RECORD_TYPE, interface);
903 tree t, m = TYPE_MAIN_VARIANT (type);
905 t = copy_node (type);
906 TYPE_BINFO (t) = make_tree_vec (2);
908 /* Add this type to the chain of variants of TYPE. */
909 TYPE_NEXT_VARIANT (t) = TYPE_NEXT_VARIANT (m);
910 TYPE_NEXT_VARIANT (m) = t;
912 /* Look up protocols and install in lang specific list. Note
913 that the protocol list can have a different lifetime than T! */
914 TYPE_PROTOCOL_LIST (t) = lookup_and_install_protocols (protocols);
916 /* This forces a new pointer type to be created later
917 (in build_pointer_type)...so that the new template
918 we just created will actually be used...what a hack! */
919 if (TYPE_POINTER_TO (t))
920 TYPE_POINTER_TO (t) = NULL_TREE;
929 get_object_reference (protocols)
932 tree type_decl = lookup_name (objc_id_id);
935 if (type_decl && TREE_CODE (type_decl) == TYPE_DECL)
937 type = TREE_TYPE (type_decl);
938 if (TYPE_MAIN_VARIANT (type) != id_type)
939 warning ("unexpected type for `id' (%s)",
940 gen_declaration (type, errbuf));
944 error ("undefined type `id', please import <objc/objc.h>");
945 return error_mark_node;
948 /* This clause creates a new pointer type that is qualified with
949 the protocol specification...this info is used later to do more
950 elaborate type checking. */
954 tree t, m = TYPE_MAIN_VARIANT (type);
956 t = copy_node (type);
957 TYPE_BINFO (t) = make_tree_vec (2);
959 /* Add this type to the chain of variants of TYPE. */
960 TYPE_NEXT_VARIANT (t) = TYPE_NEXT_VARIANT (m);
961 TYPE_NEXT_VARIANT (m) = t;
963 /* Look up protocols...and install in lang specific list */
964 TYPE_PROTOCOL_LIST (t) = lookup_and_install_protocols (protocols);
966 /* This forces a new pointer type to be created later
967 (in build_pointer_type)...so that the new template
968 we just created will actually be used...what a hack! */
969 if (TYPE_POINTER_TO (t))
970 TYPE_POINTER_TO (t) = NULL_TREE;
977 /* Check for circular dependencies in protocols. The arguments are
978 PROTO, the protocol to check, and LIST, a list of protocol it
982 check_protocol_recursively (proto, list)
988 for (p = list; p; p = TREE_CHAIN (p))
990 tree pp = TREE_VALUE (p);
992 if (TREE_CODE (pp) == IDENTIFIER_NODE)
993 pp = lookup_protocol (pp);
996 fatal_error ("protocol `%s' has circular dependency",
997 IDENTIFIER_POINTER (PROTOCOL_NAME (pp)));
999 check_protocol_recursively (proto, PROTOCOL_LIST (pp));
1004 lookup_and_install_protocols (protocols)
1009 tree return_value = protocols;
1011 for (proto = protocols; proto; proto = TREE_CHAIN (proto))
1013 tree ident = TREE_VALUE (proto);
1014 tree p = lookup_protocol (ident);
1018 error ("cannot find protocol declaration for `%s'",
1019 IDENTIFIER_POINTER (ident));
1021 TREE_CHAIN (prev) = TREE_CHAIN (proto);
1023 return_value = TREE_CHAIN (proto);
1027 /* Replace identifier with actual protocol node. */
1028 TREE_VALUE (proto) = p;
1033 return return_value;
1036 /* Create and push a decl for a built-in external variable or field NAME.
1038 TYPE is its data type. */
1041 create_builtin_decl (code, type, name)
1042 enum tree_code code;
1046 tree decl = build_decl (code, get_identifier (name), type);
1048 if (code == VAR_DECL)
1050 TREE_STATIC (decl) = 1;
1051 make_decl_rtl (decl, 0);
1055 DECL_ARTIFICIAL (decl) = 1;
1059 /* Find the decl for the constant string class. */
1062 setup_string_decl ()
1064 if (!string_class_decl)
1066 if (!constant_string_global_id)
1067 constant_string_global_id = get_identifier (STRING_OBJECT_GLOBAL_NAME);
1068 string_class_decl = lookup_name (constant_string_global_id);
1072 /* Purpose: "play" parser, creating/installing representations
1073 of the declarations that are required by Objective-C.
1077 type_spec--------->sc_spec
1078 (tree_list) (tree_list)
1081 identifier_node identifier_node */
1084 synth_module_prologue ()
1089 /* Defined in `objc.h' */
1090 objc_object_id = get_identifier (TAG_OBJECT);
1092 objc_object_reference = xref_tag (RECORD_TYPE, objc_object_id);
1094 id_type = build_pointer_type (objc_object_reference);
1096 objc_id_id = get_identifier (TYPE_ID);
1097 objc_class_id = get_identifier (TAG_CLASS);
1099 objc_class_type = build_pointer_type (xref_tag (RECORD_TYPE, objc_class_id));
1100 protocol_type = build_pointer_type (xref_tag (RECORD_TYPE,
1101 get_identifier (PROTOCOL_OBJECT_CLASS_NAME)));
1103 /* Declare type of selector-objects that represent an operation name. */
1105 /* `struct objc_selector *' */
1107 = build_pointer_type (xref_tag (RECORD_TYPE,
1108 get_identifier (TAG_SELECTOR)));
1110 /* Forward declare type, or else the prototype for msgSendSuper will
1113 super_p = build_pointer_type (xref_tag (RECORD_TYPE,
1114 get_identifier (TAG_SUPER)));
1117 /* id objc_msgSend (id, SEL, ...); */
1120 = build_function_type (id_type,
1121 tree_cons (NULL_TREE, id_type,
1122 tree_cons (NULL_TREE, selector_type,
1125 if (! flag_next_runtime)
1127 umsg_decl = build_decl (FUNCTION_DECL,
1128 get_identifier (TAG_MSGSEND), temp_type);
1129 DECL_EXTERNAL (umsg_decl) = 1;
1130 TREE_PUBLIC (umsg_decl) = 1;
1131 DECL_INLINE (umsg_decl) = 1;
1132 DECL_ARTIFICIAL (umsg_decl) = 1;
1134 if (flag_traditional && TAG_MSGSEND[0] != '_')
1135 DECL_BUILT_IN_NONANSI (umsg_decl) = 1;
1137 make_decl_rtl (umsg_decl, NULL);
1138 pushdecl (umsg_decl);
1141 umsg_decl = builtin_function (TAG_MSGSEND, temp_type, 0, NOT_BUILT_IN, 0);
1143 /* id objc_msgSendSuper (struct objc_super *, SEL, ...); */
1146 = build_function_type (id_type,
1147 tree_cons (NULL_TREE, super_p,
1148 tree_cons (NULL_TREE, selector_type,
1151 umsg_super_decl = builtin_function (TAG_MSGSENDSUPER,
1152 temp_type, 0, NOT_BUILT_IN, 0);
1154 /* id objc_getClass (const char *); */
1156 temp_type = build_function_type (id_type,
1157 tree_cons (NULL_TREE,
1158 const_string_type_node,
1159 tree_cons (NULL_TREE, void_type_node,
1163 = builtin_function (TAG_GETCLASS, temp_type, 0, NOT_BUILT_IN, 0);
1165 /* id objc_getMetaClass (const char *); */
1167 objc_get_meta_class_decl
1168 = builtin_function (TAG_GETMETACLASS, temp_type, 0, NOT_BUILT_IN, 0);
1170 /* static SEL _OBJC_SELECTOR_TABLE[]; */
1172 if (! flag_next_runtime)
1174 if (flag_typed_selectors)
1176 /* Suppress outputting debug symbols, because
1177 dbxout_init hasn'r been called yet. */
1178 enum debug_info_type save_write_symbols = write_symbols;
1179 struct gcc_debug_hooks *save_hooks = debug_hooks;
1180 write_symbols = NO_DEBUG;
1181 debug_hooks = &do_nothing_debug_hooks;
1183 build_selector_template ();
1184 temp_type = build_array_type (objc_selector_template, NULL_TREE);
1186 write_symbols = save_write_symbols;
1187 debug_hooks = save_hooks;
1190 temp_type = build_array_type (selector_type, NULL_TREE);
1192 layout_type (temp_type);
1193 UOBJC_SELECTOR_TABLE_decl
1194 = create_builtin_decl (VAR_DECL, temp_type,
1195 "_OBJC_SELECTOR_TABLE");
1197 /* Avoid warning when not sending messages. */
1198 TREE_USED (UOBJC_SELECTOR_TABLE_decl) = 1;
1201 generate_forward_declaration_to_string_table ();
1203 /* Forward declare constant_string_id and constant_string_type. */
1204 if (!constant_string_class_name)
1205 constant_string_class_name = default_constant_string_class_name;
1207 constant_string_id = get_identifier (constant_string_class_name);
1208 constant_string_type = xref_tag (RECORD_TYPE, constant_string_id);
1211 /* Predefine the following data type:
1213 struct STRING_OBJECT_CLASS_NAME
1217 unsigned int length;
1221 build_string_class_template ()
1223 tree field_decl, field_decl_chain;
1225 field_decl = create_builtin_decl (FIELD_DECL, id_type, "isa");
1226 field_decl_chain = field_decl;
1228 field_decl = create_builtin_decl (FIELD_DECL,
1229 build_pointer_type (char_type_node),
1231 chainon (field_decl_chain, field_decl);
1233 field_decl = create_builtin_decl (FIELD_DECL, unsigned_type_node, "length");
1234 chainon (field_decl_chain, field_decl);
1236 finish_struct (constant_string_type, field_decl_chain, NULL_TREE);
1239 /* Custom build_string which sets TREE_TYPE! */
1242 my_build_string (len, str)
1247 tree a_string = build_string (len, str);
1249 /* Some code from combine_strings, which is local to c-parse.y. */
1250 if (TREE_TYPE (a_string) == int_array_type_node)
1253 TREE_TYPE (a_string)
1254 = build_array_type (wide_flag ? integer_type_node : char_type_node,
1255 build_index_type (build_int_2 (len - 1, 0)));
1257 TREE_CONSTANT (a_string) = 1; /* Puts string in the readonly segment */
1258 TREE_STATIC (a_string) = 1;
1263 /* Given a chain of STRING_CST's, build a static instance of
1264 NXConstantString which points at the concatenation of those strings.
1265 We place the string object in the __string_objects section of the
1266 __OBJC segment. The Objective-C runtime will initialize the isa
1267 pointers of the string objects to point at the NXConstantString
1271 build_objc_string_object (strings)
1274 tree string, initlist, constructor;
1277 if (lookup_interface (constant_string_id) == NULL_TREE)
1279 error ("cannot find interface declaration for `%s'",
1280 IDENTIFIER_POINTER (constant_string_id));
1281 return error_mark_node;
1284 add_class_reference (constant_string_id);
1286 string = combine_strings (strings);
1287 TREE_SET_CODE (string, STRING_CST);
1288 length = TREE_STRING_LENGTH (string) - 1;
1290 /* We could not properly create NXConstantString in synth_module_prologue,
1291 because that's called before debugging is initialized. Do it now. */
1292 if (TYPE_FIELDS (constant_string_type) == NULL_TREE)
1293 build_string_class_template ();
1295 /* & ((NXConstantString) { NULL, string, length }) */
1297 if (flag_next_runtime)
1299 /* For the NeXT runtime, we can generate a literal reference
1300 to the string class, don't need to run a constructor. */
1301 setup_string_decl ();
1302 if (string_class_decl == NULL_TREE)
1304 error ("cannot find reference tag for class `%s'",
1305 IDENTIFIER_POINTER (constant_string_id));
1306 return error_mark_node;
1308 initlist = build_tree_list
1310 copy_node (build_unary_op (ADDR_EXPR, string_class_decl, 0)));
1314 initlist = build_tree_list (NULL_TREE, build_int_2 (0, 0));
1318 = tree_cons (NULL_TREE, copy_node (build_unary_op (ADDR_EXPR, string, 1)),
1320 initlist = tree_cons (NULL_TREE, build_int_2 (length, 0), initlist);
1321 constructor = build_constructor (constant_string_type, nreverse (initlist));
1323 if (!flag_next_runtime)
1326 = objc_add_static_instance (constructor, constant_string_type);
1329 return (build_unary_op (ADDR_EXPR, constructor, 1));
1332 /* Declare a static instance of CLASS_DECL initialized by CONSTRUCTOR. */
1335 objc_add_static_instance (constructor, class_decl)
1336 tree constructor, class_decl;
1338 static int num_static_inst;
1342 /* Find the list of static instances for the CLASS_DECL. Create one if
1344 for (chain = &objc_static_instances;
1345 *chain && TREE_VALUE (*chain) != class_decl;
1346 chain = &TREE_CHAIN (*chain));
1349 *chain = tree_cons (NULL_TREE, class_decl, NULL_TREE);
1350 add_objc_string (TYPE_NAME (class_decl), class_names);
1353 sprintf (buf, "_OBJC_INSTANCE_%d", num_static_inst++);
1354 decl = build_decl (VAR_DECL, get_identifier (buf), class_decl);
1355 DECL_COMMON (decl) = 1;
1356 TREE_STATIC (decl) = 1;
1357 DECL_ARTIFICIAL (decl) = 1;
1358 DECL_INITIAL (decl) = constructor;
1360 /* We may be writing something else just now.
1361 Postpone till end of input. */
1362 DECL_DEFER_OUTPUT (decl) = 1;
1363 pushdecl_top_level (decl);
1364 rest_of_decl_compilation (decl, 0, 1, 0);
1366 /* Add the DECL to the head of this CLASS' list. */
1367 TREE_PURPOSE (*chain) = tree_cons (NULL_TREE, decl, TREE_PURPOSE (*chain));
1372 /* Build a static constant CONSTRUCTOR
1373 with type TYPE and elements ELTS. */
1376 build_constructor (type, elts)
1379 tree constructor, f, e;
1381 /* ??? Most of the places that we build constructors, we don't fill in
1382 the type of integers properly. Convert them all en masse. */
1383 if (TREE_CODE (type) == ARRAY_TYPE)
1385 f = TREE_TYPE (type);
1386 if (TREE_CODE (f) == POINTER_TYPE || TREE_CODE (f) == INTEGER_TYPE)
1387 for (e = elts; e ; e = TREE_CHAIN (e))
1388 TREE_VALUE (e) = convert (f, TREE_VALUE (e));
1392 f = TYPE_FIELDS (type);
1393 for (e = elts; e ; e = TREE_CHAIN (e), f = TREE_CHAIN (f))
1394 if (TREE_CODE (TREE_TYPE (f)) == POINTER_TYPE
1395 || TREE_CODE (TREE_TYPE (f)) == INTEGER_TYPE)
1396 TREE_VALUE (e) = convert (TREE_TYPE (f), TREE_VALUE (e));
1399 constructor = build (CONSTRUCTOR, type, NULL_TREE, elts);
1400 TREE_CONSTANT (constructor) = 1;
1401 TREE_STATIC (constructor) = 1;
1402 TREE_READONLY (constructor) = 1;
1407 /* Take care of defining and initializing _OBJC_SYMBOLS. */
1409 /* Predefine the following data type:
1417 void *defs[cls_def_cnt + cat_def_cnt];
1421 build_objc_symtab_template ()
1423 tree field_decl, field_decl_chain, index;
1425 objc_symtab_template
1426 = start_struct (RECORD_TYPE, get_identifier (UTAG_SYMTAB));
1428 /* long sel_ref_cnt; */
1430 field_decl = create_builtin_decl (FIELD_DECL,
1431 long_integer_type_node,
1433 field_decl_chain = field_decl;
1437 field_decl = create_builtin_decl (FIELD_DECL,
1438 build_pointer_type (selector_type),
1440 chainon (field_decl_chain, field_decl);
1442 /* short cls_def_cnt; */
1444 field_decl = create_builtin_decl (FIELD_DECL,
1445 short_integer_type_node,
1447 chainon (field_decl_chain, field_decl);
1449 /* short cat_def_cnt; */
1451 field_decl = create_builtin_decl (FIELD_DECL,
1452 short_integer_type_node,
1454 chainon (field_decl_chain, field_decl);
1456 /* void *defs[cls_def_cnt + cat_def_cnt]; */
1458 if (!flag_next_runtime)
1459 index = build_index_type (build_int_2 (imp_count + cat_count, 0));
1461 index = build_index_type (build_int_2 (imp_count + cat_count - 1,
1462 imp_count == 0 && cat_count == 0
1464 field_decl = create_builtin_decl (FIELD_DECL,
1465 build_array_type (ptr_type_node, index),
1467 chainon (field_decl_chain, field_decl);
1469 finish_struct (objc_symtab_template, field_decl_chain, NULL_TREE);
1472 /* Create the initial value for the `defs' field of _objc_symtab.
1473 This is a CONSTRUCTOR. */
1476 init_def_list (type)
1479 tree expr, initlist = NULL_TREE;
1480 struct imp_entry *impent;
1483 for (impent = imp_list; impent; impent = impent->next)
1485 if (TREE_CODE (impent->imp_context) == CLASS_IMPLEMENTATION_TYPE)
1487 expr = build_unary_op (ADDR_EXPR, impent->class_decl, 0);
1488 initlist = tree_cons (NULL_TREE, expr, initlist);
1493 for (impent = imp_list; impent; impent = impent->next)
1495 if (TREE_CODE (impent->imp_context) == CATEGORY_IMPLEMENTATION_TYPE)
1497 expr = build_unary_op (ADDR_EXPR, impent->class_decl, 0);
1498 initlist = tree_cons (NULL_TREE, expr, initlist);
1502 if (!flag_next_runtime)
1504 /* statics = { ..., _OBJC_STATIC_INSTANCES, ... } */
1507 if (static_instances_decl)
1508 expr = build_unary_op (ADDR_EXPR, static_instances_decl, 0);
1510 expr = build_int_2 (0, 0);
1512 initlist = tree_cons (NULL_TREE, expr, initlist);
1515 return build_constructor (type, nreverse (initlist));
1518 /* Construct the initial value for all of _objc_symtab. */
1521 init_objc_symtab (type)
1526 /* sel_ref_cnt = { ..., 5, ... } */
1528 initlist = build_tree_list (NULL_TREE, build_int_2 (0, 0));
1530 /* refs = { ..., _OBJC_SELECTOR_TABLE, ... } */
1532 if (flag_next_runtime || ! sel_ref_chain)
1533 initlist = tree_cons (NULL_TREE, build_int_2 (0, 0), initlist);
1535 initlist = tree_cons (NULL_TREE,
1536 build_unary_op (ADDR_EXPR,
1537 UOBJC_SELECTOR_TABLE_decl, 1),
1540 /* cls_def_cnt = { ..., 5, ... } */
1542 initlist = tree_cons (NULL_TREE, build_int_2 (imp_count, 0), initlist);
1544 /* cat_def_cnt = { ..., 5, ... } */
1546 initlist = tree_cons (NULL_TREE, build_int_2 (cat_count, 0), initlist);
1548 /* cls_def = { ..., { &Foo, &Bar, ...}, ... } */
1550 if (imp_count || cat_count || static_instances_decl)
1553 tree field = TYPE_FIELDS (type);
1554 field = TREE_CHAIN (TREE_CHAIN (TREE_CHAIN (TREE_CHAIN (field))));
1556 initlist = tree_cons (NULL_TREE, init_def_list (TREE_TYPE (field)),
1560 return build_constructor (type, nreverse (initlist));
1563 /* Push forward-declarations of all the categories so that
1564 init_def_list can use them in a CONSTRUCTOR. */
1567 forward_declare_categories ()
1569 struct imp_entry *impent;
1570 tree sav = objc_implementation_context;
1572 for (impent = imp_list; impent; impent = impent->next)
1574 if (TREE_CODE (impent->imp_context) == CATEGORY_IMPLEMENTATION_TYPE)
1576 /* Set an invisible arg to synth_id_with_class_suffix. */
1577 objc_implementation_context = impent->imp_context;
1579 = create_builtin_decl (VAR_DECL, objc_category_template,
1580 IDENTIFIER_POINTER (synth_id_with_class_suffix ("_OBJC_CATEGORY", objc_implementation_context)));
1583 objc_implementation_context = sav;
1586 /* Create the declaration of _OBJC_SYMBOLS, with type `strict _objc_symtab'
1587 and initialized appropriately. */
1590 generate_objc_symtab_decl ()
1594 if (!objc_category_template)
1595 build_category_template ();
1597 /* forward declare categories */
1599 forward_declare_categories ();
1601 if (!objc_symtab_template)
1602 build_objc_symtab_template ();
1604 sc_spec = build_tree_list (NULL_TREE, ridpointers[(int) RID_STATIC]);
1606 UOBJC_SYMBOLS_decl = start_decl (get_identifier ("_OBJC_SYMBOLS"),
1607 tree_cons (NULL_TREE,
1608 objc_symtab_template, sc_spec),
1612 TREE_USED (UOBJC_SYMBOLS_decl) = 1;
1613 DECL_IGNORED_P (UOBJC_SYMBOLS_decl) = 1;
1614 DECL_ARTIFICIAL (UOBJC_SYMBOLS_decl) = 1;
1615 finish_decl (UOBJC_SYMBOLS_decl,
1616 init_objc_symtab (TREE_TYPE (UOBJC_SYMBOLS_decl)),
1621 init_module_descriptor (type)
1624 tree initlist, expr;
1626 /* version = { 1, ... } */
1628 expr = build_int_2 (OBJC_VERSION, 0);
1629 initlist = build_tree_list (NULL_TREE, expr);
1631 /* size = { ..., sizeof (struct objc_module), ... } */
1633 expr = size_in_bytes (objc_module_template);
1634 initlist = tree_cons (NULL_TREE, expr, initlist);
1636 /* name = { ..., "foo.m", ... } */
1638 expr = add_objc_string (get_identifier (input_filename), class_names);
1639 initlist = tree_cons (NULL_TREE, expr, initlist);
1641 /* symtab = { ..., _OBJC_SYMBOLS, ... } */
1643 if (UOBJC_SYMBOLS_decl)
1644 expr = build_unary_op (ADDR_EXPR, UOBJC_SYMBOLS_decl, 0);
1646 expr = build_int_2 (0, 0);
1647 initlist = tree_cons (NULL_TREE, expr, initlist);
1649 return build_constructor (type, nreverse (initlist));
1652 /* Write out the data structures to describe Objective C classes defined.
1653 If appropriate, compile and output a setup function to initialize them.
1654 Return a symbol_ref to the function to call to initialize the Objective C
1655 data structures for this file (and perhaps for other files also).
1657 struct objc_module { ... } _OBJC_MODULE = { ... }; */
1660 build_module_descriptor ()
1662 tree decl_specs, field_decl, field_decl_chain;
1664 objc_module_template
1665 = start_struct (RECORD_TYPE, get_identifier (UTAG_MODULE));
1669 decl_specs = build_tree_list (NULL_TREE, ridpointers[(int) RID_LONG]);
1670 field_decl = get_identifier ("version");
1672 = grokfield (input_filename, lineno, field_decl, decl_specs, NULL_TREE);
1673 field_decl_chain = field_decl;
1677 decl_specs = build_tree_list (NULL_TREE, ridpointers[(int) RID_LONG]);
1678 field_decl = get_identifier ("size");
1680 = grokfield (input_filename, lineno, field_decl, decl_specs, NULL_TREE);
1681 chainon (field_decl_chain, field_decl);
1685 decl_specs = build_tree_list (NULL_TREE, ridpointers[(int) RID_CHAR]);
1686 field_decl = build1 (INDIRECT_REF, NULL_TREE, get_identifier ("name"));
1688 = grokfield (input_filename, lineno, field_decl, decl_specs, NULL_TREE);
1689 chainon (field_decl_chain, field_decl);
1691 /* struct objc_symtab *symtab; */
1693 decl_specs = get_identifier (UTAG_SYMTAB);
1694 decl_specs = build_tree_list (NULL_TREE, xref_tag (RECORD_TYPE, decl_specs));
1695 field_decl = build1 (INDIRECT_REF, NULL_TREE, get_identifier ("symtab"));
1697 = grokfield (input_filename, lineno, field_decl, decl_specs, NULL_TREE);
1698 chainon (field_decl_chain, field_decl);
1700 finish_struct (objc_module_template, field_decl_chain, NULL_TREE);
1702 /* Create an instance of "objc_module". */
1704 decl_specs = tree_cons (NULL_TREE, objc_module_template,
1705 build_tree_list (NULL_TREE,
1706 ridpointers[(int) RID_STATIC]));
1708 UOBJC_MODULES_decl = start_decl (get_identifier ("_OBJC_MODULES"),
1709 decl_specs, 1, NULL_TREE);
1711 DECL_ARTIFICIAL (UOBJC_MODULES_decl) = 1;
1712 DECL_IGNORED_P (UOBJC_MODULES_decl) = 1;
1713 DECL_CONTEXT (UOBJC_MODULES_decl) = NULL_TREE;
1715 finish_decl (UOBJC_MODULES_decl,
1716 init_module_descriptor (TREE_TYPE (UOBJC_MODULES_decl)),
1719 /* Mark the decl to avoid "defined but not used" warning. */
1720 DECL_IN_SYSTEM_HEADER (UOBJC_MODULES_decl) = 1;
1722 /* Generate a constructor call for the module descriptor.
1723 This code was generated by reading the grammar rules
1724 of c-parse.in; Therefore, it may not be the most efficient
1725 way of generating the requisite code. */
1727 if (flag_next_runtime)
1731 tree parms, execclass_decl, decelerator, void_list_node_1;
1732 tree init_function_name, init_function_decl;
1734 /* Declare void __objc_execClass (void *); */
1736 void_list_node_1 = build_tree_list (NULL_TREE, void_type_node);
1737 execclass_decl = build_decl (FUNCTION_DECL,
1738 get_identifier (TAG_EXECCLASS),
1739 build_function_type (void_type_node,
1740 tree_cons (NULL_TREE, ptr_type_node,
1741 void_list_node_1)));
1742 DECL_EXTERNAL (execclass_decl) = 1;
1743 DECL_ARTIFICIAL (execclass_decl) = 1;
1744 TREE_PUBLIC (execclass_decl) = 1;
1745 pushdecl (execclass_decl);
1746 rest_of_decl_compilation (execclass_decl, 0, 0, 0);
1747 assemble_external (execclass_decl);
1749 /* void _GLOBAL_$I$<gnyf> () {objc_execClass (&L_OBJC_MODULES);} */
1751 init_function_name = get_file_function_name ('I');
1752 start_function (void_list_node_1,
1753 build_nt (CALL_EXPR, init_function_name,
1754 tree_cons (NULL_TREE, NULL_TREE,
1758 store_parm_decls ();
1760 init_function_decl = current_function_decl;
1761 TREE_PUBLIC (init_function_decl) = ! targetm.have_ctors_dtors;
1762 TREE_USED (init_function_decl) = 1;
1763 /* Don't let this one be deferred. */
1764 DECL_INLINE (init_function_decl) = 0;
1765 DECL_UNINLINABLE (init_function_decl) = 1;
1766 current_function_cannot_inline
1767 = "static constructors and destructors cannot be inlined";
1770 = build_tree_list (NULL_TREE,
1771 build_unary_op (ADDR_EXPR, UOBJC_MODULES_decl, 0));
1772 decelerator = build_function_call (execclass_decl, parms);
1774 c_expand_expr_stmt (decelerator);
1776 finish_function (0);
1778 return XEXP (DECL_RTL (init_function_decl), 0);
1782 /* extern const char _OBJC_STRINGS[]; */
1785 generate_forward_declaration_to_string_table ()
1787 tree sc_spec, decl_specs, expr_decl;
1789 sc_spec = tree_cons (NULL_TREE, ridpointers[(int) RID_EXTERN], NULL_TREE);
1790 decl_specs = tree_cons (NULL_TREE, ridpointers[(int) RID_CHAR], sc_spec);
1793 = build_nt (ARRAY_REF, get_identifier ("_OBJC_STRINGS"), NULL_TREE);
1795 UOBJC_STRINGS_decl = define_decl (expr_decl, decl_specs);
1798 /* Return the DECL of the string IDENT in the SECTION. */
1801 get_objc_string_decl (ident, section)
1803 enum string_section section;
1807 if (section == class_names)
1808 chain = class_names_chain;
1809 else if (section == meth_var_names)
1810 chain = meth_var_names_chain;
1811 else if (section == meth_var_types)
1812 chain = meth_var_types_chain;
1816 for (; chain != 0; chain = TREE_VALUE (chain))
1817 if (TREE_VALUE (chain) == ident)
1818 return (TREE_PURPOSE (chain));
1824 /* Output references to all statically allocated objects. Return the DECL
1825 for the array built. */
1828 generate_static_references ()
1830 tree decls = NULL_TREE, ident, decl_spec, expr_decl, expr = NULL_TREE;
1831 tree class_name, class, decl, initlist;
1832 tree cl_chain, in_chain, type;
1833 int num_inst, num_class;
1836 if (flag_next_runtime)
1839 for (cl_chain = objc_static_instances, num_class = 0;
1840 cl_chain; cl_chain = TREE_CHAIN (cl_chain), num_class++)
1842 for (num_inst = 0, in_chain = TREE_PURPOSE (cl_chain);
1843 in_chain; num_inst++, in_chain = TREE_CHAIN (in_chain));
1845 sprintf (buf, "_OBJC_STATIC_INSTANCES_%d", num_class);
1846 ident = get_identifier (buf);
1848 expr_decl = build_nt (ARRAY_REF, ident, NULL_TREE);
1849 decl_spec = tree_cons (NULL_TREE, build_pointer_type (void_type_node),
1850 build_tree_list (NULL_TREE,
1851 ridpointers[(int) RID_STATIC]));
1852 decl = start_decl (expr_decl, decl_spec, 1, NULL_TREE);
1853 DECL_CONTEXT (decl) = 0;
1854 DECL_ARTIFICIAL (decl) = 1;
1856 /* Output {class_name, ...}. */
1857 class = TREE_VALUE (cl_chain);
1858 class_name = get_objc_string_decl (TYPE_NAME (class), class_names);
1859 initlist = build_tree_list (NULL_TREE,
1860 build_unary_op (ADDR_EXPR, class_name, 1));
1862 /* Output {..., instance, ...}. */
1863 for (in_chain = TREE_PURPOSE (cl_chain);
1864 in_chain; in_chain = TREE_CHAIN (in_chain))
1866 expr = build_unary_op (ADDR_EXPR, TREE_VALUE (in_chain), 1);
1867 initlist = tree_cons (NULL_TREE, expr, initlist);
1870 /* Output {..., NULL}. */
1871 initlist = tree_cons (NULL_TREE, build_int_2 (0, 0), initlist);
1873 expr = build_constructor (TREE_TYPE (decl), nreverse (initlist));
1874 finish_decl (decl, expr, NULL_TREE);
1875 TREE_USED (decl) = 1;
1877 type = build_array_type (build_pointer_type (void_type_node), 0);
1878 decl = build_decl (VAR_DECL, ident, type);
1879 TREE_USED (decl) = 1;
1880 TREE_STATIC (decl) = 1;
1882 = tree_cons (NULL_TREE, build_unary_op (ADDR_EXPR, decl, 1), decls);
1885 decls = tree_cons (NULL_TREE, build_int_2 (0, 0), decls);
1886 ident = get_identifier ("_OBJC_STATIC_INSTANCES");
1887 expr_decl = build_nt (ARRAY_REF, ident, NULL_TREE);
1888 decl_spec = tree_cons (NULL_TREE, build_pointer_type (void_type_node),
1889 build_tree_list (NULL_TREE,
1890 ridpointers[(int) RID_STATIC]));
1891 static_instances_decl
1892 = start_decl (expr_decl, decl_spec, 1, NULL_TREE);
1893 TREE_USED (static_instances_decl) = 1;
1894 DECL_CONTEXT (static_instances_decl) = 0;
1895 DECL_ARTIFICIAL (static_instances_decl) = 1;
1896 expr = build_constructor (TREE_TYPE (static_instances_decl),
1898 finish_decl (static_instances_decl, expr, NULL_TREE);
1901 /* Output all strings. */
1906 tree sc_spec, decl_specs, expr_decl;
1907 tree chain, string_expr;
1910 for (chain = class_names_chain; chain; chain = TREE_CHAIN (chain))
1912 string = TREE_VALUE (chain);
1913 decl = TREE_PURPOSE (chain);
1915 = tree_cons (NULL_TREE, ridpointers[(int) RID_STATIC], NULL_TREE);
1916 decl_specs = tree_cons (NULL_TREE, ridpointers[(int) RID_CHAR], sc_spec);
1917 expr_decl = build_nt (ARRAY_REF, DECL_NAME (decl), NULL_TREE);
1918 decl = start_decl (expr_decl, decl_specs, 1, NULL_TREE);
1919 DECL_CONTEXT (decl) = NULL_TREE;
1920 string_expr = my_build_string (IDENTIFIER_LENGTH (string) + 1,
1921 IDENTIFIER_POINTER (string));
1922 finish_decl (decl, string_expr, NULL_TREE);
1925 for (chain = meth_var_names_chain; chain; chain = TREE_CHAIN (chain))
1927 string = TREE_VALUE (chain);
1928 decl = TREE_PURPOSE (chain);
1930 = tree_cons (NULL_TREE, ridpointers[(int) RID_STATIC], NULL_TREE);
1931 decl_specs = tree_cons (NULL_TREE, ridpointers[(int) RID_CHAR], sc_spec);
1932 expr_decl = build_nt (ARRAY_REF, DECL_NAME (decl), NULL_TREE);
1933 decl = start_decl (expr_decl, decl_specs, 1, NULL_TREE);
1934 DECL_CONTEXT (decl) = NULL_TREE;
1935 string_expr = my_build_string (IDENTIFIER_LENGTH (string) + 1,
1936 IDENTIFIER_POINTER (string));
1937 finish_decl (decl, string_expr, NULL_TREE);
1940 for (chain = meth_var_types_chain; chain; chain = TREE_CHAIN (chain))
1942 string = TREE_VALUE (chain);
1943 decl = TREE_PURPOSE (chain);
1945 = tree_cons (NULL_TREE, ridpointers[(int) RID_STATIC], NULL_TREE);
1946 decl_specs = tree_cons (NULL_TREE, ridpointers[(int) RID_CHAR], sc_spec);
1947 expr_decl = build_nt (ARRAY_REF, DECL_NAME (decl), NULL_TREE);
1948 decl = start_decl (expr_decl, decl_specs, 1, NULL_TREE);
1949 DECL_CONTEXT (decl) = NULL_TREE;
1950 string_expr = my_build_string (IDENTIFIER_LENGTH (string) + 1,
1951 IDENTIFIER_POINTER (string));
1952 finish_decl (decl, string_expr, NULL_TREE);
1957 build_selector_reference_decl ()
1963 sprintf (buf, "_OBJC_SELECTOR_REFERENCES_%d", idx++);
1965 ident = get_identifier (buf);
1967 decl = build_decl (VAR_DECL, ident, selector_type);
1968 DECL_EXTERNAL (decl) = 1;
1969 TREE_PUBLIC (decl) = 1;
1970 TREE_USED (decl) = 1;
1971 TREE_READONLY (decl) = 1;
1972 DECL_ARTIFICIAL (decl) = 1;
1973 DECL_CONTEXT (decl) = 0;
1975 make_decl_rtl (decl, 0);
1976 pushdecl_top_level (decl);
1981 /* Just a handy wrapper for add_objc_string. */
1984 build_selector (ident)
1987 tree expr = add_objc_string (ident, meth_var_names);
1988 if (flag_typed_selectors)
1991 return build_c_cast (selector_type, expr); /* cast! */
1995 build_selector_translation_table ()
1997 tree sc_spec, decl_specs;
1998 tree chain, initlist = NULL_TREE;
2000 tree decl = NULL_TREE, var_decl, name;
2002 for (chain = sel_ref_chain; chain; chain = TREE_CHAIN (chain))
2006 expr = build_selector (TREE_VALUE (chain));
2008 if (flag_next_runtime)
2010 name = DECL_NAME (TREE_PURPOSE (chain));
2012 sc_spec = build_tree_list (NULL_TREE, ridpointers[(int) RID_STATIC]);
2014 /* static SEL _OBJC_SELECTOR_REFERENCES_n = ...; */
2015 decl_specs = tree_cons (NULL_TREE, selector_type, sc_spec);
2019 /* The `decl' that is returned from start_decl is the one that we
2020 forward declared in `build_selector_reference' */
2021 decl = start_decl (var_decl, decl_specs, 1, NULL_TREE );
2024 /* add one for the '\0' character */
2025 offset += IDENTIFIER_LENGTH (TREE_VALUE (chain)) + 1;
2027 if (flag_next_runtime)
2028 finish_decl (decl, expr, NULL_TREE);
2031 if (flag_typed_selectors)
2033 tree eltlist = NULL_TREE;
2034 tree encoding = get_proto_encoding (TREE_PURPOSE (chain));
2035 eltlist = tree_cons (NULL_TREE, expr, NULL_TREE);
2036 eltlist = tree_cons (NULL_TREE, encoding, eltlist);
2037 expr = build_constructor (objc_selector_template,
2038 nreverse (eltlist));
2040 initlist = tree_cons (NULL_TREE, expr, initlist);
2045 if (! flag_next_runtime)
2047 /* Cause the variable and its initial value to be actually output. */
2048 DECL_EXTERNAL (UOBJC_SELECTOR_TABLE_decl) = 0;
2049 TREE_STATIC (UOBJC_SELECTOR_TABLE_decl) = 1;
2050 /* NULL terminate the list and fix the decl for output. */
2051 initlist = tree_cons (NULL_TREE, build_int_2 (0, 0), initlist);
2052 DECL_INITIAL (UOBJC_SELECTOR_TABLE_decl) = objc_ellipsis_node;
2053 initlist = build_constructor (TREE_TYPE (UOBJC_SELECTOR_TABLE_decl),
2054 nreverse (initlist));
2055 finish_decl (UOBJC_SELECTOR_TABLE_decl, initlist, NULL_TREE);
2056 current_function_decl = NULL_TREE;
2061 get_proto_encoding (proto)
2069 if (! METHOD_ENCODING (proto))
2071 tmp_decl = build_tmp_function_decl ();
2072 hack_method_prototype (proto, tmp_decl);
2073 encoding = encode_method_prototype (proto, tmp_decl);
2074 METHOD_ENCODING (proto) = encoding;
2077 encoding = METHOD_ENCODING (proto);
2079 return add_objc_string (encoding, meth_var_types);
2082 return build_int_2 (0, 0);
2085 /* sel_ref_chain is a list whose "value" fields will be instances of
2086 identifier_node that represent the selector. */
2089 build_typed_selector_reference (ident, proto)
2092 tree *chain = &sel_ref_chain;
2098 if (TREE_PURPOSE (*chain) == ident && TREE_VALUE (*chain) == proto)
2099 goto return_at_index;
2102 chain = &TREE_CHAIN (*chain);
2105 *chain = tree_cons (proto, ident, NULL_TREE);
2108 expr = build_unary_op (ADDR_EXPR,
2109 build_array_ref (UOBJC_SELECTOR_TABLE_decl,
2110 build_int_2 (index, 0)),
2112 return build_c_cast (selector_type, expr);
2116 build_selector_reference (ident)
2119 tree *chain = &sel_ref_chain;
2125 if (TREE_VALUE (*chain) == ident)
2126 return (flag_next_runtime
2127 ? TREE_PURPOSE (*chain)
2128 : build_array_ref (UOBJC_SELECTOR_TABLE_decl,
2129 build_int_2 (index, 0)));
2132 chain = &TREE_CHAIN (*chain);
2135 expr = build_selector_reference_decl ();
2137 *chain = tree_cons (expr, ident, NULL_TREE);
2139 return (flag_next_runtime
2141 : build_array_ref (UOBJC_SELECTOR_TABLE_decl,
2142 build_int_2 (index, 0)));
2146 build_class_reference_decl ()
2152 sprintf (buf, "_OBJC_CLASS_REFERENCES_%d", idx++);
2154 ident = get_identifier (buf);
2156 decl = build_decl (VAR_DECL, ident, objc_class_type);
2157 DECL_EXTERNAL (decl) = 1;
2158 TREE_PUBLIC (decl) = 1;
2159 TREE_USED (decl) = 1;
2160 TREE_READONLY (decl) = 1;
2161 DECL_CONTEXT (decl) = 0;
2162 DECL_ARTIFICIAL (decl) = 1;
2164 make_decl_rtl (decl, 0);
2165 pushdecl_top_level (decl);
2170 /* Create a class reference, but don't create a variable to reference
2174 add_class_reference (ident)
2179 if ((chain = cls_ref_chain))
2184 if (ident == TREE_VALUE (chain))
2188 chain = TREE_CHAIN (chain);
2192 /* Append to the end of the list */
2193 TREE_CHAIN (tail) = tree_cons (NULL_TREE, ident, NULL_TREE);
2196 cls_ref_chain = tree_cons (NULL_TREE, ident, NULL_TREE);
2199 /* Get a class reference, creating it if necessary. Also create the
2200 reference variable. */
2203 get_class_reference (ident)
2206 if (flag_next_runtime)
2211 for (chain = &cls_ref_chain; *chain; chain = &TREE_CHAIN (*chain))
2212 if (TREE_VALUE (*chain) == ident)
2214 if (! TREE_PURPOSE (*chain))
2215 TREE_PURPOSE (*chain) = build_class_reference_decl ();
2217 return TREE_PURPOSE (*chain);
2220 decl = build_class_reference_decl ();
2221 *chain = tree_cons (decl, ident, NULL_TREE);
2228 add_class_reference (ident);
2230 params = build_tree_list (NULL_TREE,
2231 my_build_string (IDENTIFIER_LENGTH (ident) + 1,
2232 IDENTIFIER_POINTER (ident)));
2234 assemble_external (objc_get_class_decl);
2235 return build_function_call (objc_get_class_decl, params);
2239 /* For each string section we have a chain which maps identifier nodes
2240 to decls for the strings. */
2243 add_objc_string (ident, section)
2245 enum string_section section;
2249 if (section == class_names)
2250 chain = &class_names_chain;
2251 else if (section == meth_var_names)
2252 chain = &meth_var_names_chain;
2253 else if (section == meth_var_types)
2254 chain = &meth_var_types_chain;
2260 if (TREE_VALUE (*chain) == ident)
2261 return build_unary_op (ADDR_EXPR, TREE_PURPOSE (*chain), 1);
2263 chain = &TREE_CHAIN (*chain);
2266 decl = build_objc_string_decl (section);
2268 *chain = tree_cons (decl, ident, NULL_TREE);
2270 return build_unary_op (ADDR_EXPR, decl, 1);
2274 build_objc_string_decl (section)
2275 enum string_section section;
2279 static int class_names_idx = 0;
2280 static int meth_var_names_idx = 0;
2281 static int meth_var_types_idx = 0;
2283 if (section == class_names)
2284 sprintf (buf, "_OBJC_CLASS_NAME_%d", class_names_idx++);
2285 else if (section == meth_var_names)
2286 sprintf (buf, "_OBJC_METH_VAR_NAME_%d", meth_var_names_idx++);
2287 else if (section == meth_var_types)
2288 sprintf (buf, "_OBJC_METH_VAR_TYPE_%d", meth_var_types_idx++);
2290 ident = get_identifier (buf);
2292 decl = build_decl (VAR_DECL, ident, build_array_type (char_type_node, 0));
2293 DECL_EXTERNAL (decl) = 1;
2294 TREE_PUBLIC (decl) = 1;
2295 TREE_USED (decl) = 1;
2296 TREE_READONLY (decl) = 1;
2297 TREE_CONSTANT (decl) = 1;
2298 DECL_CONTEXT (decl) = 0;
2299 DECL_ARTIFICIAL (decl) = 1;
2301 make_decl_rtl (decl, 0);
2302 pushdecl_top_level (decl);
2309 objc_declare_alias (alias_ident, class_ident)
2313 if (is_class_name (class_ident) != class_ident)
2314 warning ("cannot find class `%s'", IDENTIFIER_POINTER (class_ident));
2315 else if (is_class_name (alias_ident))
2316 warning ("class `%s' already exists", IDENTIFIER_POINTER (alias_ident));
2318 alias_chain = tree_cons (class_ident, alias_ident, alias_chain);
2322 objc_declare_class (ident_list)
2327 for (list = ident_list; list; list = TREE_CHAIN (list))
2329 tree ident = TREE_VALUE (list);
2332 if ((decl = lookup_name (ident)))
2334 error ("`%s' redeclared as different kind of symbol",
2335 IDENTIFIER_POINTER (ident));
2336 error_with_decl (decl, "previous declaration of `%s'");
2339 if (! is_class_name (ident))
2341 tree record = xref_tag (RECORD_TYPE, ident);
2342 TREE_STATIC_TEMPLATE (record) = 1;
2343 class_chain = tree_cons (NULL_TREE, ident, class_chain);
2349 is_class_name (ident)
2354 if (lookup_interface (ident))
2357 for (chain = class_chain; chain; chain = TREE_CHAIN (chain))
2359 if (ident == TREE_VALUE (chain))
2363 for (chain = alias_chain; chain; chain = TREE_CHAIN (chain))
2365 if (ident == TREE_VALUE (chain))
2366 return TREE_PURPOSE (chain);
2373 lookup_interface (ident)
2378 for (chain = interface_chain; chain; chain = TREE_CHAIN (chain))
2380 if (ident == CLASS_NAME (chain))
2387 objc_copy_list (list, head)
2391 tree newlist = NULL_TREE, tail = NULL_TREE;
2395 tail = copy_node (list);
2397 /* The following statement fixes a bug when inheriting instance
2398 variables that are declared to be bitfields. finish_struct
2399 expects to find the width of the bitfield in DECL_INITIAL. */
2400 if (DECL_BIT_FIELD (tail) && DECL_INITIAL (tail) == 0)
2401 DECL_INITIAL (tail) = DECL_SIZE (tail);
2403 newlist = chainon (newlist, tail);
2404 list = TREE_CHAIN (list);
2411 /* Used by: build_private_template, get_class_ivars, and
2412 continue_class. COPY is 1 when called from @defs. In this case
2413 copy all fields. Otherwise don't copy leaf ivars since we rely on
2414 them being side-effected exactly once by finish_struct. */
2417 build_ivar_chain (interface, copy)
2421 tree my_name, super_name, ivar_chain;
2423 my_name = CLASS_NAME (interface);
2424 super_name = CLASS_SUPER_NAME (interface);
2426 /* Possibly copy leaf ivars. */
2428 objc_copy_list (CLASS_IVARS (interface), &ivar_chain);
2430 ivar_chain = CLASS_IVARS (interface);
2435 tree super_interface = lookup_interface (super_name);
2437 if (!super_interface)
2439 /* fatal did not work with 2 args...should fix */
2440 error ("cannot find interface declaration for `%s', superclass of `%s'",
2441 IDENTIFIER_POINTER (super_name),
2442 IDENTIFIER_POINTER (my_name));
2443 exit (FATAL_EXIT_CODE);
2446 if (super_interface == interface)
2447 fatal_error ("circular inheritance in interface declaration for `%s'",
2448 IDENTIFIER_POINTER (super_name));
2450 interface = super_interface;
2451 my_name = CLASS_NAME (interface);
2452 super_name = CLASS_SUPER_NAME (interface);
2454 op1 = CLASS_IVARS (interface);
2457 tree head, tail = objc_copy_list (op1, &head);
2459 /* Prepend super class ivars...make a copy of the list, we
2460 do not want to alter the original. */
2461 TREE_CHAIN (tail) = ivar_chain;
2468 /* struct <classname> {
2469 struct objc_class *isa;
2474 build_private_template (class)
2479 if (CLASS_STATIC_TEMPLATE (class))
2481 uprivate_record = CLASS_STATIC_TEMPLATE (class);
2482 ivar_context = TYPE_FIELDS (CLASS_STATIC_TEMPLATE (class));
2486 uprivate_record = start_struct (RECORD_TYPE, CLASS_NAME (class));
2488 ivar_context = build_ivar_chain (class, 0);
2490 finish_struct (uprivate_record, ivar_context, NULL_TREE);
2492 CLASS_STATIC_TEMPLATE (class) = uprivate_record;
2494 /* mark this record as class template - for class type checking */
2495 TREE_STATIC_TEMPLATE (uprivate_record) = 1;
2499 = groktypename (build_tree_list (build_tree_list (NULL_TREE,
2501 build1 (INDIRECT_REF, NULL_TREE,
2504 return ivar_context;
2507 /* Begin code generation for protocols... */
2509 /* struct objc_protocol {
2510 char *protocol_name;
2511 struct objc_protocol **protocol_list;
2512 struct objc_method_desc *instance_methods;
2513 struct objc_method_desc *class_methods;
2517 build_protocol_template ()
2519 tree decl_specs, field_decl, field_decl_chain;
2522 template = start_struct (RECORD_TYPE, get_identifier (UTAG_PROTOCOL));
2524 /* struct objc_class *isa; */
2526 decl_specs = build_tree_list (NULL_TREE, xref_tag (RECORD_TYPE,
2527 get_identifier (UTAG_CLASS)));
2528 field_decl = build1 (INDIRECT_REF, NULL_TREE, get_identifier ("isa"));
2530 = grokfield (input_filename, lineno, field_decl, decl_specs, NULL_TREE);
2531 field_decl_chain = field_decl;
2533 /* char *protocol_name; */
2535 decl_specs = build_tree_list (NULL_TREE, ridpointers[(int) RID_CHAR]);
2537 = build1 (INDIRECT_REF, NULL_TREE, get_identifier ("protocol_name"));
2539 = grokfield (input_filename, lineno, field_decl, decl_specs, NULL_TREE);
2540 chainon (field_decl_chain, field_decl);
2542 /* struct objc_protocol **protocol_list; */
2544 decl_specs = build_tree_list (NULL_TREE, template);
2546 = build1 (INDIRECT_REF, NULL_TREE, get_identifier ("protocol_list"));
2547 field_decl = build1 (INDIRECT_REF, NULL_TREE, field_decl);
2549 = grokfield (input_filename, lineno, field_decl, decl_specs, NULL_TREE);
2550 chainon (field_decl_chain, field_decl);
2552 /* struct objc_method_list *instance_methods; */
2555 = build_tree_list (NULL_TREE,
2556 xref_tag (RECORD_TYPE,
2557 get_identifier (UTAG_METHOD_PROTOTYPE_LIST)));
2559 = build1 (INDIRECT_REF, NULL_TREE, get_identifier ("instance_methods"));
2561 = grokfield (input_filename, lineno, field_decl, decl_specs, NULL_TREE);
2562 chainon (field_decl_chain, field_decl);
2564 /* struct objc_method_list *class_methods; */
2567 = build_tree_list (NULL_TREE,
2568 xref_tag (RECORD_TYPE,
2569 get_identifier (UTAG_METHOD_PROTOTYPE_LIST)));
2571 = build1 (INDIRECT_REF, NULL_TREE, get_identifier ("class_methods"));
2573 = grokfield (input_filename, lineno, field_decl, decl_specs, NULL_TREE);
2574 chainon (field_decl_chain, field_decl);
2576 return finish_struct (template, field_decl_chain, NULL_TREE);
2580 build_descriptor_table_initializer (type, entries)
2584 tree initlist = NULL_TREE;
2588 tree eltlist = NULL_TREE;
2591 = tree_cons (NULL_TREE,
2592 build_selector (METHOD_SEL_NAME (entries)), NULL_TREE);
2594 = tree_cons (NULL_TREE,
2595 add_objc_string (METHOD_ENCODING (entries),
2600 = tree_cons (NULL_TREE,
2601 build_constructor (type, nreverse (eltlist)), initlist);
2603 entries = TREE_CHAIN (entries);
2607 return build_constructor (build_array_type (type, 0), nreverse (initlist));
2610 /* struct objc_method_prototype_list {
2612 struct objc_method_prototype {
2619 build_method_prototype_list_template (list_type, size)
2623 tree objc_ivar_list_record;
2624 tree decl_specs, field_decl, field_decl_chain;
2626 /* Generate an unnamed struct definition. */
2628 objc_ivar_list_record = start_struct (RECORD_TYPE, NULL_TREE);
2630 /* int method_count; */
2632 decl_specs = build_tree_list (NULL_TREE, ridpointers[(int) RID_INT]);
2633 field_decl = get_identifier ("method_count");
2636 = grokfield (input_filename, lineno, field_decl, decl_specs, NULL_TREE);
2637 field_decl_chain = field_decl;
2639 /* struct objc_method method_list[]; */
2641 decl_specs = build_tree_list (NULL_TREE, list_type);
2642 field_decl = build_nt (ARRAY_REF, get_identifier ("method_list"),
2643 build_int_2 (size, 0));
2646 = grokfield (input_filename, lineno, field_decl, decl_specs, NULL_TREE);
2647 chainon (field_decl_chain, field_decl);
2649 finish_struct (objc_ivar_list_record, field_decl_chain, NULL_TREE);
2651 return objc_ivar_list_record;
2655 build_method_prototype_template ()
2658 tree decl_specs, field_decl, field_decl_chain;
2661 = start_struct (RECORD_TYPE, get_identifier (UTAG_METHOD_PROTOTYPE));
2663 /* struct objc_selector *_cmd; */
2664 decl_specs = tree_cons (NULL_TREE, xref_tag (RECORD_TYPE,
2665 get_identifier (TAG_SELECTOR)), NULL_TREE);
2666 field_decl = build1 (INDIRECT_REF, NULL_TREE, get_identifier ("_cmd"));
2669 = grokfield (input_filename, lineno, field_decl, decl_specs, NULL_TREE);
2670 field_decl_chain = field_decl;
2672 decl_specs = tree_cons (NULL_TREE, ridpointers[(int) RID_CHAR], NULL_TREE);
2674 = build1 (INDIRECT_REF, NULL_TREE, get_identifier ("method_types"));
2676 = grokfield (input_filename, lineno, field_decl, decl_specs, NULL_TREE);
2677 chainon (field_decl_chain, field_decl);
2679 finish_struct (proto_record, field_decl_chain, NULL_TREE);
2681 return proto_record;
2684 /* True if last call to forwarding_offset yielded a register offset. */
2685 static int offset_is_register;
2688 forwarding_offset (parm)
2691 int offset_in_bytes;
2693 if (GET_CODE (DECL_INCOMING_RTL (parm)) == MEM)
2695 rtx addr = XEXP (DECL_INCOMING_RTL (parm), 0);
2697 /* ??? Here we assume that the parm address is indexed
2698 off the frame pointer or arg pointer.
2699 If that is not true, we produce meaningless results,
2700 but do not crash. */
2701 if (GET_CODE (addr) == PLUS
2702 && GET_CODE (XEXP (addr, 1)) == CONST_INT)
2703 offset_in_bytes = INTVAL (XEXP (addr, 1));
2705 offset_in_bytes = 0;
2707 offset_in_bytes += OBJC_FORWARDING_STACK_OFFSET;
2708 offset_is_register = 0;
2710 else if (GET_CODE (DECL_INCOMING_RTL (parm)) == REG)
2712 int regno = REGNO (DECL_INCOMING_RTL (parm));
2713 offset_in_bytes = apply_args_register_offset (regno);
2714 offset_is_register = 1;
2719 /* This is the case where the parm is passed as an int or double
2720 and it is converted to a char, short or float and stored back
2721 in the parmlist. In this case, describe the parm
2722 with the variable's declared type, and adjust the address
2723 if the least significant bytes (which we are using) are not
2725 if (BYTES_BIG_ENDIAN && TREE_TYPE (parm) != DECL_ARG_TYPE (parm))
2726 offset_in_bytes += (GET_MODE_SIZE (TYPE_MODE (DECL_ARG_TYPE (parm)))
2727 - GET_MODE_SIZE (GET_MODE (DECL_RTL (parm))));
2729 return offset_in_bytes;
2733 encode_method_prototype (method_decl, func_decl)
2740 HOST_WIDE_INT max_parm_end = 0;
2744 /* ONEWAY and BYCOPY, for remote object are the only method qualifiers. */
2745 encode_type_qualifiers (TREE_PURPOSE (TREE_TYPE (method_decl)));
2748 encode_type (TREE_TYPE (TREE_TYPE (func_decl)),
2749 obstack_object_size (&util_obstack),
2750 OBJC_ENCODE_INLINE_DEFS);
2753 for (parms = DECL_ARGUMENTS (func_decl); parms;
2754 parms = TREE_CHAIN (parms))
2756 HOST_WIDE_INT parm_end = (forwarding_offset (parms)
2757 + int_size_in_bytes (TREE_TYPE (parms)));
2759 if (!offset_is_register && max_parm_end < parm_end)
2760 max_parm_end = parm_end;
2763 stack_size = max_parm_end - OBJC_FORWARDING_MIN_OFFSET;
2765 sprintf (buf, "%d", stack_size);
2766 obstack_grow (&util_obstack, buf, strlen (buf));
2768 user_args = METHOD_SEL_ARGS (method_decl);
2770 /* Argument types. */
2771 for (parms = DECL_ARGUMENTS (func_decl), i = 0; parms;
2772 parms = TREE_CHAIN (parms), i++)
2774 /* Process argument qualifiers for user supplied arguments. */
2777 encode_type_qualifiers (TREE_PURPOSE (TREE_TYPE (user_args)));
2778 user_args = TREE_CHAIN (user_args);
2782 encode_type (TREE_TYPE (parms),
2783 obstack_object_size (&util_obstack),
2784 OBJC_ENCODE_INLINE_DEFS);
2786 /* Compute offset. */
2787 sprintf (buf, "%d", forwarding_offset (parms));
2789 /* Indicate register. */
2790 if (offset_is_register)
2791 obstack_1grow (&util_obstack, '+');
2793 obstack_grow (&util_obstack, buf, strlen (buf));
2796 obstack_1grow (&util_obstack, '\0');
2797 result = get_identifier (obstack_finish (&util_obstack));
2798 obstack_free (&util_obstack, util_firstobj);
2803 generate_descriptor_table (type, name, size, list, proto)
2810 tree sc_spec, decl_specs, decl, initlist;
2812 sc_spec = tree_cons (NULL_TREE, ridpointers[(int) RID_STATIC], NULL_TREE);
2813 decl_specs = tree_cons (NULL_TREE, type, sc_spec);
2815 decl = start_decl (synth_id_with_class_suffix (name, proto),
2816 decl_specs, 1, NULL_TREE);
2817 DECL_CONTEXT (decl) = NULL_TREE;
2819 initlist = build_tree_list (NULL_TREE, build_int_2 (size, 0));
2820 initlist = tree_cons (NULL_TREE, list, initlist);
2822 finish_decl (decl, build_constructor (type, nreverse (initlist)),
2829 generate_method_descriptors (protocol)
2832 tree initlist, chain, method_list_template;
2833 tree cast, variable_length_type;
2836 if (!objc_method_prototype_template)
2837 objc_method_prototype_template = build_method_prototype_template ();
2839 cast = build_tree_list (build_tree_list (NULL_TREE, xref_tag (RECORD_TYPE,
2840 get_identifier (UTAG_METHOD_PROTOTYPE_LIST))),
2842 variable_length_type = groktypename (cast);
2844 chain = PROTOCOL_CLS_METHODS (protocol);
2847 size = list_length (chain);
2849 method_list_template
2850 = build_method_prototype_list_template (objc_method_prototype_template,
2854 = build_descriptor_table_initializer (objc_method_prototype_template,
2857 UOBJC_CLASS_METHODS_decl
2858 = generate_descriptor_table (method_list_template,
2859 "_OBJC_PROTOCOL_CLASS_METHODS",
2860 size, initlist, protocol);
2861 TREE_TYPE (UOBJC_CLASS_METHODS_decl) = variable_length_type;
2864 UOBJC_CLASS_METHODS_decl = 0;
2866 chain = PROTOCOL_NST_METHODS (protocol);
2869 size = list_length (chain);
2871 method_list_template
2872 = build_method_prototype_list_template (objc_method_prototype_template,
2875 = build_descriptor_table_initializer (objc_method_prototype_template,
2878 UOBJC_INSTANCE_METHODS_decl
2879 = generate_descriptor_table (method_list_template,
2880 "_OBJC_PROTOCOL_INSTANCE_METHODS",
2881 size, initlist, protocol);
2882 TREE_TYPE (UOBJC_INSTANCE_METHODS_decl) = variable_length_type;
2885 UOBJC_INSTANCE_METHODS_decl = 0;
2888 /* Generate a temporary FUNCTION_DECL node to be used in
2889 hack_method_prototype below. */
2892 build_tmp_function_decl ()
2894 tree decl_specs, expr_decl, parms;
2898 /* struct objc_object *objc_xxx (id, SEL, ...); */
2900 decl_specs = build_tree_list (NULL_TREE, objc_object_reference);
2901 push_parm_decl (build_tree_list
2902 (build_tree_list (decl_specs,
2903 build1 (INDIRECT_REF, NULL_TREE,
2907 decl_specs = build_tree_list (NULL_TREE, xref_tag (RECORD_TYPE,
2908 get_identifier (TAG_SELECTOR)));
2909 expr_decl = build1 (INDIRECT_REF, NULL_TREE, NULL_TREE);
2911 push_parm_decl (build_tree_list (build_tree_list (decl_specs, expr_decl),
2913 parms = get_parm_info (0);
2916 decl_specs = build_tree_list (NULL_TREE, objc_object_reference);
2917 sprintf (buffer, "__objc_tmp_%x", xxx++);
2918 expr_decl = build_nt (CALL_EXPR, get_identifier (buffer), parms, NULL_TREE);
2919 expr_decl = build1 (INDIRECT_REF, NULL_TREE, expr_decl);
2921 return define_decl (expr_decl, decl_specs);
2924 /* Generate the prototypes for protocol methods. This is used to
2925 generate method encodings for these.
2927 NST_METHODS is the method to generate a _DECL node for TMP_DECL is
2928 a decl node to be used. This is also where the return value is
2932 hack_method_prototype (nst_methods, tmp_decl)
2939 /* Hack to avoid problem with static typing of self arg. */
2940 TREE_SET_CODE (nst_methods, CLASS_METHOD_DECL);
2941 start_method_def (nst_methods);
2942 TREE_SET_CODE (nst_methods, INSTANCE_METHOD_DECL);
2944 if (METHOD_ADD_ARGS (nst_methods) == objc_ellipsis_node)
2945 parms = get_parm_info (0); /* we have a `, ...' */
2947 parms = get_parm_info (1); /* place a `void_at_end' */
2949 poplevel (0, 0, 0); /* Must be called BEFORE start_function. */
2951 /* Usually called from store_parm_decls -> init_function_start. */
2953 DECL_ARGUMENTS (tmp_decl) = TREE_PURPOSE (parms);
2954 current_function_decl = tmp_decl;
2957 /* Code taken from start_function. */
2958 tree restype = TREE_TYPE (TREE_TYPE (tmp_decl));
2959 /* Promote the value to int before returning it. */
2960 if (TREE_CODE (restype) == INTEGER_TYPE
2961 && TYPE_PRECISION (restype) < TYPE_PRECISION (integer_type_node))
2962 restype = integer_type_node;
2963 DECL_RESULT (tmp_decl) = build_decl (RESULT_DECL, 0, restype);
2966 for (parm = DECL_ARGUMENTS (tmp_decl); parm; parm = TREE_CHAIN (parm))
2967 DECL_CONTEXT (parm) = tmp_decl;
2969 init_function_start (tmp_decl, "objc-act", 0);
2971 /* Typically called from expand_function_start for function definitions. */
2972 assign_parms (tmp_decl);
2974 /* install return type */
2975 TREE_TYPE (TREE_TYPE (tmp_decl)) = groktypename (TREE_TYPE (nst_methods));
2980 generate_protocol_references (plist)
2985 /* Forward declare protocols referenced. */
2986 for (lproto = plist; lproto; lproto = TREE_CHAIN (lproto))
2988 tree proto = TREE_VALUE (lproto);
2990 if (TREE_CODE (proto) == PROTOCOL_INTERFACE_TYPE
2991 && PROTOCOL_NAME (proto))
2993 if (! PROTOCOL_FORWARD_DECL (proto))
2994 build_protocol_reference (proto);
2996 if (PROTOCOL_LIST (proto))
2997 generate_protocol_references (PROTOCOL_LIST (proto));
3003 generate_protocols ()
3005 tree p, tmp_decl, encoding;
3006 tree sc_spec, decl_specs, decl;
3007 tree initlist, protocol_name_expr, refs_decl, refs_expr;
3010 tmp_decl = build_tmp_function_decl ();
3012 if (! objc_protocol_template)
3013 objc_protocol_template = build_protocol_template ();
3015 /* If a protocol was directly referenced, pull in indirect references. */
3016 for (p = protocol_chain; p; p = TREE_CHAIN (p))
3017 if (PROTOCOL_FORWARD_DECL (p) && PROTOCOL_LIST (p))
3018 generate_protocol_references (PROTOCOL_LIST (p));
3020 for (p = protocol_chain; p; p = TREE_CHAIN (p))
3022 tree nst_methods = PROTOCOL_NST_METHODS (p);
3023 tree cls_methods = PROTOCOL_CLS_METHODS (p);
3025 /* If protocol wasn't referenced, don't generate any code. */
3026 if (! PROTOCOL_FORWARD_DECL (p))
3029 /* Make sure we link in the Protocol class. */
3030 add_class_reference (get_identifier (PROTOCOL_OBJECT_CLASS_NAME));
3034 if (! METHOD_ENCODING (nst_methods))
3036 hack_method_prototype (nst_methods, tmp_decl);
3037 encoding = encode_method_prototype (nst_methods, tmp_decl);
3038 METHOD_ENCODING (nst_methods) = encoding;
3040 nst_methods = TREE_CHAIN (nst_methods);
3045 if (! METHOD_ENCODING (cls_methods))
3047 hack_method_prototype (cls_methods, tmp_decl);
3048 encoding = encode_method_prototype (cls_methods, tmp_decl);
3049 METHOD_ENCODING (cls_methods) = encoding;
3052 cls_methods = TREE_CHAIN (cls_methods);
3054 generate_method_descriptors (p);
3056 if (PROTOCOL_LIST (p))
3057 refs_decl = generate_protocol_list (p);
3061 /* static struct objc_protocol _OBJC_PROTOCOL_<mumble>; */
3063 sc_spec = tree_cons (NULL_TREE, ridpointers[(int) RID_STATIC],
3065 decl_specs = tree_cons (NULL_TREE, objc_protocol_template, sc_spec);
3067 decl = start_decl (synth_id_with_class_suffix ("_OBJC_PROTOCOL", p),
3068 decl_specs, 1, NULL_TREE);
3070 DECL_CONTEXT (decl) = NULL_TREE;
3072 protocol_name_expr = add_objc_string (PROTOCOL_NAME (p), class_names);
3078 (build_tree_list (build_tree_list (NULL_TREE,
3079 objc_protocol_template),
3080 build1 (INDIRECT_REF, NULL_TREE,
3081 build1 (INDIRECT_REF, NULL_TREE,
3084 refs_expr = build_unary_op (ADDR_EXPR, refs_decl, 0);
3085 TREE_TYPE (refs_expr) = cast_type2;
3088 refs_expr = build_int_2 (0, 0);
3090 /* UOBJC_INSTANCE_METHODS_decl/UOBJC_CLASS_METHODS_decl are set
3091 by generate_method_descriptors, which is called above. */
3092 initlist = build_protocol_initializer (TREE_TYPE (decl),
3093 protocol_name_expr, refs_expr,
3094 UOBJC_INSTANCE_METHODS_decl,
3095 UOBJC_CLASS_METHODS_decl);
3096 finish_decl (decl, initlist, NULL_TREE);
3098 /* Mark the decl as used to avoid "defined but not used" warning. */
3099 TREE_USED (decl) = 1;
3104 build_protocol_initializer (type, protocol_name, protocol_list,
3105 instance_methods, class_methods)
3109 tree instance_methods;
3112 tree initlist = NULL_TREE, expr;
3115 cast_type = groktypename
3117 (build_tree_list (NULL_TREE,
3118 xref_tag (RECORD_TYPE,
3119 get_identifier (UTAG_CLASS))),
3120 build1 (INDIRECT_REF, NULL_TREE, NULL_TREE)));
3122 /* Filling the "isa" in with one allows the runtime system to
3123 detect that the version change...should remove before final release. */
3125 expr = build_int_2 (PROTOCOL_VERSION, 0);
3126 TREE_TYPE (expr) = cast_type;
3127 initlist = tree_cons (NULL_TREE, expr, initlist);
3128 initlist = tree_cons (NULL_TREE, protocol_name, initlist);
3129 initlist = tree_cons (NULL_TREE, protocol_list, initlist);
3131 if (!instance_methods)
3132 initlist = tree_cons (NULL_TREE, build_int_2 (0, 0), initlist);
3135 expr = build_unary_op (ADDR_EXPR, instance_methods, 0);
3136 initlist = tree_cons (NULL_TREE, expr, initlist);
3140 initlist = tree_cons (NULL_TREE, build_int_2 (0, 0), initlist);
3143 expr = build_unary_op (ADDR_EXPR, class_methods, 0);
3144 initlist = tree_cons (NULL_TREE, expr, initlist);
3147 return build_constructor (type, nreverse (initlist));
3150 /* struct objc_category {
3151 char *category_name;
3153 struct objc_method_list *instance_methods;
3154 struct objc_method_list *class_methods;
3155 struct objc_protocol_list *protocols;
3159 build_category_template ()
3161 tree decl_specs, field_decl, field_decl_chain;
3163 objc_category_template = start_struct (RECORD_TYPE,
3164 get_identifier (UTAG_CATEGORY));
3165 /* char *category_name; */
3167 decl_specs = build_tree_list (NULL_TREE, ridpointers[(int) RID_CHAR]);
3169 = build1 (INDIRECT_REF, NULL_TREE, get_identifier ("category_name"));
3171 = grokfield (input_filename, lineno, field_decl, decl_specs, NULL_TREE);
3172 field_decl_chain = field_decl;
3174 /* char *class_name; */
3176 decl_specs = build_tree_list (NULL_TREE, ridpointers[(int) RID_CHAR]);
3177 field_decl = build1 (INDIRECT_REF, NULL_TREE, get_identifier ("class_name"));
3179 = grokfield (input_filename, lineno, field_decl, decl_specs, NULL_TREE);
3180 chainon (field_decl_chain, field_decl);
3182 /* struct objc_method_list *instance_methods; */
3184 decl_specs = build_tree_list (NULL_TREE,
3185 xref_tag (RECORD_TYPE,
3186 get_identifier (UTAG_METHOD_LIST)));
3188 = build1 (INDIRECT_REF, NULL_TREE, get_identifier ("instance_methods"));
3190 = grokfield (input_filename, lineno, field_decl, decl_specs, NULL_TREE);
3191 chainon (field_decl_chain, field_decl);
3193 /* struct objc_method_list *class_methods; */
3195 decl_specs = build_tree_list (NULL_TREE,
3196 xref_tag (RECORD_TYPE,
3197 get_identifier (UTAG_METHOD_LIST)));
3199 = build1 (INDIRECT_REF, NULL_TREE, get_identifier ("class_methods"));
3201 = grokfield (input_filename, lineno, field_decl, decl_specs, NULL_TREE);
3202 chainon (field_decl_chain, field_decl);
3204 /* struct objc_protocol **protocol_list; */
3206 decl_specs = build_tree_list (NULL_TREE,
3207 xref_tag (RECORD_TYPE,
3208 get_identifier (UTAG_PROTOCOL)));
3210 = build1 (INDIRECT_REF, NULL_TREE, get_identifier ("protocol_list"));
3211 field_decl = build1 (INDIRECT_REF, NULL_TREE, field_decl);
3213 = grokfield (input_filename, lineno, field_decl, decl_specs, NULL_TREE);
3214 chainon (field_decl_chain, field_decl);
3216 finish_struct (objc_category_template, field_decl_chain, NULL_TREE);
3219 /* struct objc_selector {
3225 build_selector_template ()
3228 tree decl_specs, field_decl, field_decl_chain;
3230 objc_selector_template
3231 = start_struct (RECORD_TYPE, get_identifier (UTAG_SELECTOR));
3235 decl_specs = build_tree_list (NULL_TREE, ridpointers[(int) RID_VOID]);
3236 field_decl = build1 (INDIRECT_REF, NULL_TREE, get_identifier ("sel_id"));
3238 = grokfield (input_filename, lineno, field_decl, decl_specs, NULL_TREE);
3239 field_decl_chain = field_decl;
3241 /* char *sel_type; */
3243 decl_specs = build_tree_list (NULL_TREE, ridpointers[(int) RID_CHAR]);
3244 field_decl = build1 (INDIRECT_REF, NULL_TREE, get_identifier ("sel_type"));
3246 = grokfield (input_filename, lineno, field_decl, decl_specs, NULL_TREE);
3247 chainon (field_decl_chain, field_decl);
3249 finish_struct (objc_selector_template, field_decl_chain, NULL_TREE);
3252 /* struct objc_class {
3253 struct objc_class *isa;
3254 struct objc_class *super_class;
3259 struct objc_ivar_list *ivars;
3260 struct objc_method_list *methods;
3261 if (flag_next_runtime)
3262 struct objc_cache *cache;
3264 struct sarray *dtable;
3265 struct objc_class *subclass_list;
3266 struct objc_class *sibling_class;
3268 struct objc_protocol_list *protocols;
3269 void *gc_object_type;
3273 build_class_template ()
3275 tree decl_specs, field_decl, field_decl_chain;
3278 = start_struct (RECORD_TYPE, get_identifier (UTAG_CLASS));
3280 /* struct objc_class *isa; */
3282 decl_specs = build_tree_list (NULL_TREE, objc_class_template);
3283 field_decl = build1 (INDIRECT_REF, NULL_TREE, get_identifier ("isa"));
3285 = grokfield (input_filename, lineno, field_decl, decl_specs, NULL_TREE);
3286 field_decl_chain = field_decl;
3288 /* struct objc_class *super_class; */
3290 decl_specs = build_tree_list (NULL_TREE, objc_class_template);
3292 = build1 (INDIRECT_REF, NULL_TREE, get_identifier ("super_class"));
3294 = grokfield (input_filename, lineno, field_decl, decl_specs, NULL_TREE);
3295 chainon (field_decl_chain, field_decl);
3299 decl_specs = build_tree_list (NULL_TREE, ridpointers[(int) RID_CHAR]);
3300 field_decl = build1 (INDIRECT_REF, NULL_TREE, get_identifier ("name"));
3302 = grokfield (input_filename, lineno, field_decl, decl_specs, NULL_TREE);
3303 chainon (field_decl_chain, field_decl);
3307 decl_specs = build_tree_list (NULL_TREE, ridpointers[(int) RID_LONG]);
3308 field_decl = get_identifier ("version");
3310 = grokfield (input_filename, lineno, field_decl, decl_specs, NULL_TREE);
3311 chainon (field_decl_chain, field_decl);
3315 decl_specs = build_tree_list (NULL_TREE, ridpointers[(int) RID_LONG]);
3316 field_decl = get_identifier ("info");
3318 = grokfield (input_filename, lineno, field_decl, decl_specs, NULL_TREE);
3319 chainon (field_decl_chain, field_decl);
3321 /* long instance_size; */
3323 decl_specs = build_tree_list (NULL_TREE, ridpointers[(int) RID_LONG]);
3324 field_decl = get_identifier ("instance_size");
3326 = grokfield (input_filename, lineno, field_decl, decl_specs, NULL_TREE);
3327 chainon (field_decl_chain, field_decl);
3329 /* struct objc_ivar_list *ivars; */
3331 decl_specs = build_tree_list (NULL_TREE,
3332 xref_tag (RECORD_TYPE,
3333 get_identifier (UTAG_IVAR_LIST)));
3334 field_decl = build1 (INDIRECT_REF, NULL_TREE, get_identifier ("ivars"));
3336 = grokfield (input_filename, lineno, field_decl, decl_specs, NULL_TREE);
3337 chainon (field_decl_chain, field_decl);
3339 /* struct objc_method_list *methods; */
3341 decl_specs = build_tree_list (NULL_TREE,
3342 xref_tag (RECORD_TYPE,
3343 get_identifier (UTAG_METHOD_LIST)));
3344 field_decl = build1 (INDIRECT_REF, NULL_TREE, get_identifier ("methods"));
3346 = grokfield (input_filename, lineno, field_decl, decl_specs, NULL_TREE);
3347 chainon (field_decl_chain, field_decl);
3349 if (flag_next_runtime)
3351 /* struct objc_cache *cache; */
3353 decl_specs = build_tree_list (NULL_TREE,
3354 xref_tag (RECORD_TYPE,
3355 get_identifier ("objc_cache")));
3356 field_decl = build1 (INDIRECT_REF, NULL_TREE, get_identifier ("cache"));
3357 field_decl = grokfield (input_filename, lineno, field_decl,
3358 decl_specs, NULL_TREE);
3359 chainon (field_decl_chain, field_decl);
3363 /* struct sarray *dtable; */
3365 decl_specs = build_tree_list (NULL_TREE,
3366 xref_tag (RECORD_TYPE,
3367 get_identifier ("sarray")));
3368 field_decl = build1 (INDIRECT_REF, NULL_TREE, get_identifier ("dtable"));
3369 field_decl = grokfield (input_filename, lineno, field_decl,
3370 decl_specs, NULL_TREE);
3371 chainon (field_decl_chain, field_decl);
3373 /* struct objc_class *subclass_list; */
3375 decl_specs = build_tree_list (NULL_TREE, objc_class_template);
3377 = build1 (INDIRECT_REF, NULL_TREE, get_identifier ("subclass_list"));
3378 field_decl = grokfield (input_filename, lineno, field_decl,
3379 decl_specs, NULL_TREE);
3380 chainon (field_decl_chain, field_decl);
3382 /* struct objc_class *sibling_class; */
3384 decl_specs = build_tree_list (NULL_TREE, objc_class_template);
3386 = build1 (INDIRECT_REF, NULL_TREE, get_identifier ("sibling_class"));
3387 field_decl = grokfield (input_filename, lineno, field_decl,
3388 decl_specs, NULL_TREE);
3389 chainon (field_decl_chain, field_decl);
3392 /* struct objc_protocol **protocol_list; */
3394 decl_specs = build_tree_list (NULL_TREE,
3395 xref_tag (RECORD_TYPE,
3396 get_identifier (UTAG_PROTOCOL)));
3398 = build1 (INDIRECT_REF, NULL_TREE, get_identifier ("protocol_list"));
3400 = build1 (INDIRECT_REF, NULL_TREE, field_decl);
3401 field_decl = grokfield (input_filename, lineno, field_decl,
3402 decl_specs, NULL_TREE);
3403 chainon (field_decl_chain, field_decl);
3407 decl_specs = build_tree_list (NULL_TREE, ridpointers[(int) RID_VOID]);
3408 field_decl = build1 (INDIRECT_REF, NULL_TREE, get_identifier ("sel_id"));
3410 = grokfield (input_filename, lineno, field_decl, decl_specs, NULL_TREE);
3411 chainon (field_decl_chain, field_decl);
3413 /* void *gc_object_type; */
3415 decl_specs = build_tree_list (NULL_TREE, ridpointers[(int) RID_VOID]);
3416 field_decl = build1 (INDIRECT_REF, NULL_TREE, get_identifier ("gc_object_type"));
3418 = grokfield (input_filename, lineno, field_decl, decl_specs, NULL_TREE);
3419 chainon (field_decl_chain, field_decl);
3421 finish_struct (objc_class_template, field_decl_chain, NULL_TREE);
3424 /* Generate appropriate forward declarations for an implementation. */
3427 synth_forward_declarations ()
3429 tree sc_spec, decl_specs, an_id;
3431 /* extern struct objc_class _OBJC_CLASS_<my_name>; */
3433 an_id = synth_id_with_class_suffix ("_OBJC_CLASS", objc_implementation_context);
3435 sc_spec = build_tree_list (NULL_TREE, ridpointers[(int) RID_EXTERN]);
3436 decl_specs = tree_cons (NULL_TREE, objc_class_template, sc_spec);
3437 UOBJC_CLASS_decl = define_decl (an_id, decl_specs);
3438 TREE_USED (UOBJC_CLASS_decl) = 1;
3439 DECL_ARTIFICIAL (UOBJC_CLASS_decl) = 1;
3441 /* extern struct objc_class _OBJC_METACLASS_<my_name>; */
3443 an_id = synth_id_with_class_suffix ("_OBJC_METACLASS",
3444 objc_implementation_context);
3446 UOBJC_METACLASS_decl = define_decl (an_id, decl_specs);
3447 TREE_USED (UOBJC_METACLASS_decl) = 1;
3448 DECL_ARTIFICIAL(UOBJC_METACLASS_decl) = 1;
3450 /* Pre-build the following entities - for speed/convenience. */
3452 an_id = get_identifier ("super_class");
3453 ucls_super_ref = build_component_ref (UOBJC_CLASS_decl, an_id);
3454 uucls_super_ref = build_component_ref (UOBJC_METACLASS_decl, an_id);
3458 error_with_ivar (message, decl, rawdecl)
3459 const char *message;
3465 report_error_function (DECL_SOURCE_FILE (decl));
3467 error_with_file_and_line (DECL_SOURCE_FILE (decl),
3468 DECL_SOURCE_LINE (decl),
3470 message, gen_declaration (rawdecl, errbuf));
3474 #define USERTYPE(t) \
3475 (TREE_CODE (t) == RECORD_TYPE || TREE_CODE (t) == UNION_TYPE \
3476 || TREE_CODE (t) == ENUMERAL_TYPE)
3479 check_ivars (inter, imp)
3483 tree intdecls = CLASS_IVARS (inter);
3484 tree impdecls = CLASS_IVARS (imp);
3485 tree rawintdecls = CLASS_RAW_IVARS (inter);
3486 tree rawimpdecls = CLASS_RAW_IVARS (imp);
3492 if (intdecls == 0 && impdecls == 0)
3494 if (intdecls == 0 || impdecls == 0)
3496 error ("inconsistent instance variable specification");
3500 t1 = TREE_TYPE (intdecls); t2 = TREE_TYPE (impdecls);
3502 if (!comptypes (t1, t2))
3504 if (DECL_NAME (intdecls) == DECL_NAME (impdecls))
3506 error_with_ivar ("conflicting instance variable type",
3507 impdecls, rawimpdecls);
3508 error_with_ivar ("previous declaration of",
3509 intdecls, rawintdecls);
3511 else /* both the type and the name don't match */
3513 error ("inconsistent instance variable specification");
3518 else if (DECL_NAME (intdecls) != DECL_NAME (impdecls))
3520 error_with_ivar ("conflicting instance variable name",
3521 impdecls, rawimpdecls);
3522 error_with_ivar ("previous declaration of",
3523 intdecls, rawintdecls);
3526 intdecls = TREE_CHAIN (intdecls);
3527 impdecls = TREE_CHAIN (impdecls);
3528 rawintdecls = TREE_CHAIN (rawintdecls);
3529 rawimpdecls = TREE_CHAIN (rawimpdecls);
3533 /* Set super_type to the data type node for struct objc_super *,
3534 first defining struct objc_super itself.
3535 This needs to be done just once per compilation. */
3538 build_super_template ()
3540 tree record, decl_specs, field_decl, field_decl_chain;
3542 record = start_struct (RECORD_TYPE, get_identifier (UTAG_SUPER));
3544 /* struct objc_object *self; */
3546 decl_specs = build_tree_list (NULL_TREE, objc_object_reference);
3547 field_decl = get_identifier ("self");
3548 field_decl = build1 (INDIRECT_REF, NULL_TREE, field_decl);
3549 field_decl = grokfield (input_filename, lineno,
3550 field_decl, decl_specs, NULL_TREE);
3551 field_decl_chain = field_decl;
3553 /* struct objc_class *class; */
3555 decl_specs = get_identifier (UTAG_CLASS);
3556 decl_specs = build_tree_list (NULL_TREE, xref_tag (RECORD_TYPE, decl_specs));
3557 field_decl = build1 (INDIRECT_REF, NULL_TREE, get_identifier ("class"));
3559 field_decl = grokfield (input_filename, lineno,
3560 field_decl, decl_specs, NULL_TREE);
3561 chainon (field_decl_chain, field_decl);
3563 finish_struct (record, field_decl_chain, NULL_TREE);
3565 /* `struct objc_super *' */
3566 super_type = groktypename (build_tree_list (build_tree_list (NULL_TREE,
3568 build1 (INDIRECT_REF,
3569 NULL_TREE, NULL_TREE)));
3573 /* struct objc_ivar {
3580 build_ivar_template ()
3582 tree objc_ivar_id, objc_ivar_record;
3583 tree decl_specs, field_decl, field_decl_chain;
3585 objc_ivar_id = get_identifier (UTAG_IVAR);
3586 objc_ivar_record = start_struct (RECORD_TYPE, objc_ivar_id);
3588 /* char *ivar_name; */
3590 decl_specs = build_tree_list (NULL_TREE, ridpointers[(int) RID_CHAR]);
3591 field_decl = build1 (INDIRECT_REF, NULL_TREE, get_identifier ("ivar_name"));
3593 field_decl = grokfield (input_filename, lineno, field_decl,
3594 decl_specs, NULL_TREE);
3595 field_decl_chain = field_decl;
3597 /* char *ivar_type; */
3599 decl_specs = build_tree_list (NULL_TREE, ridpointers[(int) RID_CHAR]);
3600 field_decl = build1 (INDIRECT_REF, NULL_TREE, get_identifier ("ivar_type"));
3602 field_decl = grokfield (input_filename, lineno, field_decl,
3603 decl_specs, NULL_TREE);
3604 chainon (field_decl_chain, field_decl);
3606 /* int ivar_offset; */
3608 decl_specs = build_tree_list (NULL_TREE, ridpointers[(int) RID_INT]);
3609 field_decl = get_identifier ("ivar_offset");
3611 field_decl = grokfield (input_filename, lineno, field_decl,
3612 decl_specs, NULL_TREE);
3613 chainon (field_decl_chain, field_decl);
3615 finish_struct (objc_ivar_record, field_decl_chain, NULL_TREE);
3617 return objc_ivar_record;
3622 struct objc_ivar ivar_list[ivar_count];
3626 build_ivar_list_template (list_type, size)
3630 tree objc_ivar_list_record;
3631 tree decl_specs, field_decl, field_decl_chain;
3633 objc_ivar_list_record = start_struct (RECORD_TYPE, NULL_TREE);
3635 /* int ivar_count; */
3637 decl_specs = build_tree_list (NULL_TREE, ridpointers[(int) RID_INT]);
3638 field_decl = get_identifier ("ivar_count");
3640 field_decl = grokfield (input_filename, lineno, field_decl,
3641 decl_specs, NULL_TREE);
3642 field_decl_chain = field_decl;
3644 /* struct objc_ivar ivar_list[]; */
3646 decl_specs = build_tree_list (NULL_TREE, list_type);
3647 field_decl = build_nt (ARRAY_REF, get_identifier ("ivar_list"),
3648 build_int_2 (size, 0));
3650 field_decl = grokfield (input_filename, lineno,
3651 field_decl, decl_specs, NULL_TREE);
3652 chainon (field_decl_chain, field_decl);
3654 finish_struct (objc_ivar_list_record, field_decl_chain, NULL_TREE);
3656 return objc_ivar_list_record;
3662 struct objc_method method_list[method_count];
3666 build_method_list_template (list_type, size)
3670 tree objc_ivar_list_record;
3671 tree decl_specs, field_decl, field_decl_chain;
3673 objc_ivar_list_record = start_struct (RECORD_TYPE, NULL_TREE);
3675 /* int method_next; */
3680 xref_tag (RECORD_TYPE,
3681 get_identifier (UTAG_METHOD_PROTOTYPE_LIST)));
3683 = build1 (INDIRECT_REF, NULL_TREE, get_identifier ("method_next"));
3684 field_decl = grokfield (input_filename, lineno, field_decl,
3685 decl_specs, NULL_TREE);
3686 field_decl_chain = field_decl;
3688 /* int method_count; */
3690 decl_specs = build_tree_list (NULL_TREE, ridpointers[(int) RID_INT]);
3691 field_decl = get_identifier ("method_count");
3693 field_decl = grokfield (input_filename, lineno,
3694 field_decl, decl_specs, NULL_TREE);
3695 chainon (field_decl_chain, field_decl);
3697 /* struct objc_method method_list[]; */
3699 decl_specs = build_tree_list (NULL_TREE, list_type);
3700 field_decl = build_nt (ARRAY_REF, get_identifier ("method_list"),
3701 build_int_2 (size, 0));
3703 field_decl = grokfield (input_filename, lineno,
3704 field_decl, decl_specs, NULL_TREE);
3705 chainon (field_decl_chain, field_decl);
3707 finish_struct (objc_ivar_list_record, field_decl_chain, NULL_TREE);
3709 return objc_ivar_list_record;
3713 build_ivar_list_initializer (type, field_decl)
3717 tree initlist = NULL_TREE;
3721 tree ivar = NULL_TREE;
3724 if (DECL_NAME (field_decl))
3725 ivar = tree_cons (NULL_TREE,
3726 add_objc_string (DECL_NAME (field_decl),
3730 /* Unnamed bit-field ivar (yuck). */
3731 ivar = tree_cons (NULL_TREE, build_int_2 (0, 0), ivar);
3734 encode_field_decl (field_decl,
3735 obstack_object_size (&util_obstack),
3736 OBJC_ENCODE_DONT_INLINE_DEFS);
3738 /* Null terminate string. */
3739 obstack_1grow (&util_obstack, 0);
3743 add_objc_string (get_identifier (obstack_finish (&util_obstack)),
3746 obstack_free (&util_obstack, util_firstobj);
3749 ivar = tree_cons (NULL_TREE, byte_position (field_decl), ivar);
3750 initlist = tree_cons (NULL_TREE,
3751 build_constructor (type, nreverse (ivar)),
3754 field_decl = TREE_CHAIN (field_decl);
3758 return build_constructor (build_array_type (type, 0), nreverse (initlist));
3762 generate_ivars_list (type, name, size, list)
3768 tree sc_spec, decl_specs, decl, initlist;
3770 sc_spec = tree_cons (NULL_TREE, ridpointers[(int) RID_STATIC], NULL_TREE);
3771 decl_specs = tree_cons (NULL_TREE, type, sc_spec);
3773 decl = start_decl (synth_id_with_class_suffix (name, objc_implementation_context),
3774 decl_specs, 1, NULL_TREE);
3776 initlist = build_tree_list (NULL_TREE, build_int_2 (size, 0));
3777 initlist = tree_cons (NULL_TREE, list, initlist);
3780 build_constructor (TREE_TYPE (decl), nreverse (initlist)),
3787 generate_ivar_lists ()
3789 tree initlist, ivar_list_template, chain;
3790 tree cast, variable_length_type;
3793 generating_instance_variables = 1;
3795 if (!objc_ivar_template)
3796 objc_ivar_template = build_ivar_template ();
3800 (build_tree_list (NULL_TREE, xref_tag (RECORD_TYPE,
3801 get_identifier (UTAG_IVAR_LIST))),
3803 variable_length_type = groktypename (cast);
3805 /* Only generate class variables for the root of the inheritance
3806 hierarchy since these will be the same for every class. */
3808 if (CLASS_SUPER_NAME (implementation_template) == NULL_TREE
3809 && (chain = TYPE_FIELDS (objc_class_template)))
3811 size = list_length (chain);
3813 ivar_list_template = build_ivar_list_template (objc_ivar_template, size);
3814 initlist = build_ivar_list_initializer (objc_ivar_template, chain);
3816 UOBJC_CLASS_VARIABLES_decl
3817 = generate_ivars_list (ivar_list_template, "_OBJC_CLASS_VARIABLES",
3819 TREE_TYPE (UOBJC_CLASS_VARIABLES_decl) = variable_length_type;
3822 UOBJC_CLASS_VARIABLES_decl = 0;
3824 chain = CLASS_IVARS (implementation_template);
3827 size = list_length (chain);
3828 ivar_list_template = build_ivar_list_template (objc_ivar_template, size);
3829 initlist = build_ivar_list_initializer (objc_ivar_template, chain);
3831 UOBJC_INSTANCE_VARIABLES_decl
3832 = generate_ivars_list (ivar_list_template, "_OBJC_INSTANCE_VARIABLES",
3834 TREE_TYPE (UOBJC_INSTANCE_VARIABLES_decl) = variable_length_type;
3837 UOBJC_INSTANCE_VARIABLES_decl = 0;
3839 generating_instance_variables = 0;
3843 build_dispatch_table_initializer (type, entries)
3847 tree initlist = NULL_TREE;
3851 tree elemlist = NULL_TREE;
3853 elemlist = tree_cons (NULL_TREE,
3854 build_selector (METHOD_SEL_NAME (entries)),
3857 /* Generate the method encoding if we don't have one already. */
3858 if (! METHOD_ENCODING (entries))
3859 METHOD_ENCODING (entries) =
3860 encode_method_def (METHOD_DEFINITION (entries));
3862 elemlist = tree_cons (NULL_TREE,
3863 add_objc_string (METHOD_ENCODING (entries),
3867 elemlist = tree_cons (NULL_TREE,
3868 build_unary_op (ADDR_EXPR,
3869 METHOD_DEFINITION (entries), 1),
3872 initlist = tree_cons (NULL_TREE,
3873 build_constructor (type, nreverse (elemlist)),
3876 entries = TREE_CHAIN (entries);
3880 return build_constructor (build_array_type (type, 0), nreverse (initlist));
3883 /* To accomplish method prototyping without generating all kinds of
3884 inane warnings, the definition of the dispatch table entries were
3887 struct objc_method { SEL _cmd; ...; id (*_imp)(); };
3889 struct objc_method { SEL _cmd; ...; void *_imp; }; */
3892 build_method_template ()
3895 tree decl_specs, field_decl, field_decl_chain;
3897 _SLT_record = start_struct (RECORD_TYPE, get_identifier (UTAG_METHOD));
3899 /* struct objc_selector *_cmd; */
3900 decl_specs = tree_cons (NULL_TREE,
3901 xref_tag (RECORD_TYPE,
3902 get_identifier (TAG_SELECTOR)),
3904 field_decl = build1 (INDIRECT_REF, NULL_TREE, get_identifier ("_cmd"));
3906 field_decl = grokfield (input_filename, lineno, field_decl,
3907 decl_specs, NULL_TREE);
3908 field_decl_chain = field_decl;
3910 decl_specs = tree_cons (NULL_TREE, ridpointers[(int) RID_CHAR], NULL_TREE);
3911 field_decl = build1 (INDIRECT_REF, NULL_TREE,
3912 get_identifier ("method_types"));
3913 field_decl = grokfield (input_filename, lineno, field_decl,
3914 decl_specs, NULL_TREE);
3915 chainon (field_decl_chain, field_decl);
3919 decl_specs = tree_cons (NULL_TREE, ridpointers[(int) RID_VOID], NULL_TREE);
3920 field_decl = build1 (INDIRECT_REF, NULL_TREE, get_identifier ("_imp"));
3921 field_decl = grokfield (input_filename, lineno, field_decl,
3922 decl_specs, NULL_TREE);
3923 chainon (field_decl_chain, field_decl);
3925 finish_struct (_SLT_record, field_decl_chain, NULL_TREE);
3932 generate_dispatch_table (type, name, size, list)
3938 tree sc_spec, decl_specs, decl, initlist;
3940 sc_spec = tree_cons (NULL_TREE, ridpointers[(int) RID_STATIC], NULL_TREE);
3941 decl_specs = tree_cons (NULL_TREE, type, sc_spec);
3943 decl = start_decl (synth_id_with_class_suffix (name, objc_implementation_context),
3944 decl_specs, 1, NULL_TREE);
3946 initlist = build_tree_list (NULL_TREE, build_int_2 (0, 0));
3947 initlist = tree_cons (NULL_TREE, build_int_2 (size, 0), initlist);
3948 initlist = tree_cons (NULL_TREE, list, initlist);
3951 build_constructor (TREE_TYPE (decl), nreverse (initlist)),
3958 generate_dispatch_tables ()
3960 tree initlist, chain, method_list_template;
3961 tree cast, variable_length_type;
3964 if (!objc_method_template)
3965 objc_method_template = build_method_template ();
3969 (build_tree_list (NULL_TREE,
3970 xref_tag (RECORD_TYPE,
3971 get_identifier (UTAG_METHOD_LIST))),
3974 variable_length_type = groktypename (cast);
3976 chain = CLASS_CLS_METHODS (objc_implementation_context);
3979 size = list_length (chain);
3981 method_list_template
3982 = build_method_list_template (objc_method_template, size);
3984 = build_dispatch_table_initializer (objc_method_template, chain);
3986 UOBJC_CLASS_METHODS_decl
3987 = generate_dispatch_table (method_list_template,
3988 ((TREE_CODE (objc_implementation_context)
3989 == CLASS_IMPLEMENTATION_TYPE)
3990 ? "_OBJC_CLASS_METHODS"
3991 : "_OBJC_CATEGORY_CLASS_METHODS"),
3993 TREE_TYPE (UOBJC_CLASS_METHODS_decl) = variable_length_type;
3996 UOBJC_CLASS_METHODS_decl = 0;
3998 chain = CLASS_NST_METHODS (objc_implementation_context);
4001 size = list_length (chain);
4003 method_list_template
4004 = build_method_list_template (objc_method_template, size);
4006 = build_dispatch_table_initializer (objc_method_template, chain);
4008 if (TREE_CODE (objc_implementation_context) == CLASS_IMPLEMENTATION_TYPE)
4009 UOBJC_INSTANCE_METHODS_decl
4010 = generate_dispatch_table (method_list_template,
4011 "_OBJC_INSTANCE_METHODS",
4014 /* We have a category. */
4015 UOBJC_INSTANCE_METHODS_decl
4016 = generate_dispatch_table (method_list_template,
4017 "_OBJC_CATEGORY_INSTANCE_METHODS",
4019 TREE_TYPE (UOBJC_INSTANCE_METHODS_decl) = variable_length_type;
4022 UOBJC_INSTANCE_METHODS_decl = 0;
4026 generate_protocol_list (i_or_p)
4029 tree initlist, decl_specs, sc_spec;
4030 tree refs_decl, expr_decl, lproto, e, plist;
4034 if (TREE_CODE (i_or_p) == CLASS_INTERFACE_TYPE
4035 || TREE_CODE (i_or_p) == CATEGORY_INTERFACE_TYPE)
4036 plist = CLASS_PROTOCOL_LIST (i_or_p);
4037 else if (TREE_CODE (i_or_p) == PROTOCOL_INTERFACE_TYPE)
4038 plist = PROTOCOL_LIST (i_or_p);
4042 cast_type = groktypename
4044 (build_tree_list (NULL_TREE,
4045 xref_tag (RECORD_TYPE,
4046 get_identifier (UTAG_PROTOCOL))),
4047 build1 (INDIRECT_REF, NULL_TREE, NULL_TREE)));
4050 for (lproto = plist; lproto; lproto = TREE_CHAIN (lproto))
4051 if (TREE_CODE (TREE_VALUE (lproto)) == PROTOCOL_INTERFACE_TYPE
4052 && PROTOCOL_FORWARD_DECL (TREE_VALUE (lproto)))
4055 /* Build initializer. */
4056 initlist = tree_cons (NULL_TREE, build_int_2 (0, 0), NULL_TREE);
4058 e = build_int_2 (size, 0);
4059 TREE_TYPE (e) = cast_type;
4060 initlist = tree_cons (NULL_TREE, e, initlist);
4062 for (lproto = plist; lproto; lproto = TREE_CHAIN (lproto))
4064 tree pval = TREE_VALUE (lproto);
4066 if (TREE_CODE (pval) == PROTOCOL_INTERFACE_TYPE
4067 && PROTOCOL_FORWARD_DECL (pval))
4069 e = build_unary_op (ADDR_EXPR, PROTOCOL_FORWARD_DECL (pval), 0);
4070 initlist = tree_cons (NULL_TREE, e, initlist);
4074 /* static struct objc_protocol *refs[n]; */
4076 sc_spec = tree_cons (NULL_TREE, ridpointers[(int) RID_STATIC], NULL_TREE);
4077 decl_specs = tree_cons (NULL_TREE, xref_tag (RECORD_TYPE,
4078 get_identifier (UTAG_PROTOCOL)),
4081 if (TREE_CODE (i_or_p) == PROTOCOL_INTERFACE_TYPE)
4082 expr_decl = build_nt (ARRAY_REF,
4083 synth_id_with_class_suffix ("_OBJC_PROTOCOL_REFS",
4085 build_int_2 (size + 2, 0));
4086 else if (TREE_CODE (i_or_p) == CLASS_INTERFACE_TYPE)
4087 expr_decl = build_nt (ARRAY_REF,
4088 synth_id_with_class_suffix ("_OBJC_CLASS_PROTOCOLS",
4090 build_int_2 (size + 2, 0));
4091 else if (TREE_CODE (i_or_p) == CATEGORY_INTERFACE_TYPE)
4093 = build_nt (ARRAY_REF,
4094 synth_id_with_class_suffix ("_OBJC_CATEGORY_PROTOCOLS",
4096 build_int_2 (size + 2, 0));
4100 expr_decl = build1 (INDIRECT_REF, NULL_TREE, expr_decl);
4102 refs_decl = start_decl (expr_decl, decl_specs, 1, NULL_TREE);
4103 DECL_CONTEXT (refs_decl) = NULL_TREE;
4105 finish_decl (refs_decl, build_constructor (TREE_TYPE (refs_decl),
4106 nreverse (initlist)),
4113 build_category_initializer (type, cat_name, class_name,
4114 instance_methods, class_methods, protocol_list)
4118 tree instance_methods;
4122 tree initlist = NULL_TREE, expr;
4124 initlist = tree_cons (NULL_TREE, cat_name, initlist);
4125 initlist = tree_cons (NULL_TREE, class_name, initlist);
4127 if (!instance_methods)
4128 initlist = tree_cons (NULL_TREE, build_int_2 (0, 0), initlist);
4131 expr = build_unary_op (ADDR_EXPR, instance_methods, 0);
4132 initlist = tree_cons (NULL_TREE, expr, initlist);
4135 initlist = tree_cons (NULL_TREE, build_int_2 (0, 0), initlist);
4138 expr = build_unary_op (ADDR_EXPR, class_methods, 0);
4139 initlist = tree_cons (NULL_TREE, expr, initlist);
4142 /* protocol_list = */
4144 initlist = tree_cons (NULL_TREE, build_int_2 (0, 0), initlist);
4147 tree cast_type2 = groktypename
4149 (build_tree_list (NULL_TREE,
4150 xref_tag (RECORD_TYPE,
4151 get_identifier (UTAG_PROTOCOL))),
4152 build1 (INDIRECT_REF, NULL_TREE,
4153 build1 (INDIRECT_REF, NULL_TREE, NULL_TREE))));
4155 expr = build_unary_op (ADDR_EXPR, protocol_list, 0);
4156 TREE_TYPE (expr) = cast_type2;
4157 initlist = tree_cons (NULL_TREE, expr, initlist);
4160 return build_constructor (type, nreverse (initlist));
4163 /* struct objc_class {
4164 struct objc_class *isa;
4165 struct objc_class *super_class;
4170 struct objc_ivar_list *ivars;
4171 struct objc_method_list *methods;
4172 if (flag_next_runtime)
4173 struct objc_cache *cache;
4175 struct sarray *dtable;
4176 struct objc_class *subclass_list;
4177 struct objc_class *sibling_class;
4179 struct objc_protocol_list *protocols;
4180 void *gc_object_type;
4184 build_shared_structure_initializer (type, isa, super, name, size, status,
4185 dispatch_table, ivar_list, protocol_list)
4192 tree dispatch_table;
4196 tree initlist = NULL_TREE, expr;
4199 initlist = tree_cons (NULL_TREE, isa, initlist);
4202 initlist = tree_cons (NULL_TREE, super, initlist);
4205 initlist = tree_cons (NULL_TREE, default_conversion (name), initlist);
4208 initlist = tree_cons (NULL_TREE, build_int_2 (0, 0), initlist);
4211 initlist = tree_cons (NULL_TREE, build_int_2 (status, 0), initlist);
4213 /* instance_size = */
4214 initlist = tree_cons (NULL_TREE, size, initlist);
4216 /* objc_ivar_list = */
4218 initlist = tree_cons (NULL_TREE, build_int_2 (0, 0), initlist);
4221 expr = build_unary_op (ADDR_EXPR, ivar_list, 0);
4222 initlist = tree_cons (NULL_TREE, expr, initlist);
4225 /* objc_method_list = */
4226 if (!dispatch_table)
4227 initlist = tree_cons (NULL_TREE, build_int_2 (0, 0), initlist);
4230 expr = build_unary_op (ADDR_EXPR, dispatch_table, 0);
4231 initlist = tree_cons (NULL_TREE, expr, initlist);
4234 if (flag_next_runtime)
4235 /* method_cache = */
4236 initlist = tree_cons (NULL_TREE, build_int_2 (0, 0), initlist);
4240 initlist = tree_cons (NULL_TREE, build_int_2 (0, 0), initlist);
4242 /* subclass_list = */
4243 initlist = tree_cons (NULL_TREE, build_int_2 (0, 0), initlist);
4245 /* sibling_class = */
4246 initlist = tree_cons (NULL_TREE, build_int_2 (0, 0), initlist);
4249 /* protocol_list = */
4250 if (! protocol_list)
4251 initlist = tree_cons (NULL_TREE, build_int_2 (0, 0), initlist);
4257 (build_tree_list (NULL_TREE,
4258 xref_tag (RECORD_TYPE,
4259 get_identifier (UTAG_PROTOCOL))),
4260 build1 (INDIRECT_REF, NULL_TREE,
4261 build1 (INDIRECT_REF, NULL_TREE, NULL_TREE))));
4263 expr = build_unary_op (ADDR_EXPR, protocol_list, 0);
4264 TREE_TYPE (expr) = cast_type2;
4265 initlist = tree_cons (NULL_TREE, expr, initlist);
4268 /* gc_object_type = NULL */
4269 initlist = tree_cons (NULL_TREE, build_int_2 (0, 0), initlist);
4271 return build_constructor (type, nreverse (initlist));
4274 /* static struct objc_category _OBJC_CATEGORY_<name> = { ... }; */
4277 generate_category (cat)
4280 tree sc_spec, decl_specs, decl;
4281 tree initlist, cat_name_expr, class_name_expr;
4282 tree protocol_decl, category;
4284 add_class_reference (CLASS_NAME (cat));
4285 cat_name_expr = add_objc_string (CLASS_SUPER_NAME (cat), class_names);
4287 class_name_expr = add_objc_string (CLASS_NAME (cat), class_names);
4289 category = CLASS_CATEGORY_LIST (implementation_template);
4291 /* find the category interface from the class it is associated with */
4294 if (CLASS_SUPER_NAME (cat) == CLASS_SUPER_NAME (category))
4296 category = CLASS_CATEGORY_LIST (category);
4299 if (category && CLASS_PROTOCOL_LIST (category))
4301 generate_protocol_references (CLASS_PROTOCOL_LIST (category));
4302 protocol_decl = generate_protocol_list (category);
4307 sc_spec = tree_cons (NULL_TREE, ridpointers[(int) RID_STATIC], NULL_TREE);
4308 decl_specs = tree_cons (NULL_TREE, objc_category_template, sc_spec);
4310 decl = start_decl (synth_id_with_class_suffix ("_OBJC_CATEGORY",
4311 objc_implementation_context),
4312 decl_specs, 1, NULL_TREE);
4314 initlist = build_category_initializer (TREE_TYPE (decl),
4315 cat_name_expr, class_name_expr,
4316 UOBJC_INSTANCE_METHODS_decl,
4317 UOBJC_CLASS_METHODS_decl,
4320 TREE_USED (decl) = 1;
4321 finish_decl (decl, initlist, NULL_TREE);
4324 /* static struct objc_class _OBJC_METACLASS_Foo={ ... };
4325 static struct objc_class _OBJC_CLASS_Foo={ ... }; */
4328 generate_shared_structures ()
4330 tree sc_spec, decl_specs, decl;
4331 tree name_expr, super_expr, root_expr;
4332 tree my_root_id = NULL_TREE, my_super_id = NULL_TREE;
4333 tree cast_type, initlist, protocol_decl;
4335 my_super_id = CLASS_SUPER_NAME (implementation_template);
4338 add_class_reference (my_super_id);
4340 /* Compute "my_root_id" - this is required for code generation.
4341 the "isa" for all meta class structures points to the root of
4342 the inheritance hierarchy (e.g. "__Object")... */
4343 my_root_id = my_super_id;
4346 tree my_root_int = lookup_interface (my_root_id);
4348 if (my_root_int && CLASS_SUPER_NAME (my_root_int))
4349 my_root_id = CLASS_SUPER_NAME (my_root_int);
4356 /* No super class. */
4357 my_root_id = CLASS_NAME (implementation_template);
4360 = groktypename (build_tree_list (build_tree_list (NULL_TREE,
4361 objc_class_template),
4362 build1 (INDIRECT_REF,
4363 NULL_TREE, NULL_TREE)));
4365 name_expr = add_objc_string (CLASS_NAME (implementation_template),
4368 /* Install class `isa' and `super' pointers at runtime. */
4371 super_expr = add_objc_string (my_super_id, class_names);
4372 super_expr = build_c_cast (cast_type, super_expr); /* cast! */
4375 super_expr = build_int_2 (0, 0);
4377 root_expr = add_objc_string (my_root_id, class_names);
4378 root_expr = build_c_cast (cast_type, root_expr); /* cast! */
4380 if (CLASS_PROTOCOL_LIST (implementation_template))
4382 generate_protocol_references
4383 (CLASS_PROTOCOL_LIST (implementation_template));
4384 protocol_decl = generate_protocol_list (implementation_template);
4389 /* static struct objc_class _OBJC_METACLASS_Foo = { ... }; */
4391 sc_spec = build_tree_list (NULL_TREE, ridpointers[(int) RID_STATIC]);
4392 decl_specs = tree_cons (NULL_TREE, objc_class_template, sc_spec);
4394 decl = start_decl (DECL_NAME (UOBJC_METACLASS_decl), decl_specs, 1,
4398 = build_shared_structure_initializer
4400 root_expr, super_expr, name_expr,
4401 convert (integer_type_node, TYPE_SIZE_UNIT (objc_class_template)),
4403 UOBJC_CLASS_METHODS_decl,
4404 UOBJC_CLASS_VARIABLES_decl,
4407 finish_decl (decl, initlist, NULL_TREE);
4409 /* static struct objc_class _OBJC_CLASS_Foo={ ... }; */
4411 decl = start_decl (DECL_NAME (UOBJC_CLASS_decl), decl_specs, 1,
4415 = build_shared_structure_initializer
4417 build_unary_op (ADDR_EXPR, UOBJC_METACLASS_decl, 0),
4418 super_expr, name_expr,
4419 convert (integer_type_node,
4420 TYPE_SIZE_UNIT (CLASS_STATIC_TEMPLATE
4421 (implementation_template))),
4423 UOBJC_INSTANCE_METHODS_decl,
4424 UOBJC_INSTANCE_VARIABLES_decl,
4427 finish_decl (decl, initlist, NULL_TREE);
4431 synth_id_with_class_suffix (preamble, ctxt)
4432 const char *preamble;
4436 if (TREE_CODE (ctxt) == CLASS_IMPLEMENTATION_TYPE
4437 || TREE_CODE (ctxt) == CLASS_INTERFACE_TYPE)
4439 const char *const class_name
4440 = IDENTIFIER_POINTER (CLASS_NAME (objc_implementation_context));
4441 string = (char *) alloca (strlen (preamble) + strlen (class_name) + 3);
4442 sprintf (string, "%s_%s", preamble,
4443 IDENTIFIER_POINTER (CLASS_NAME (ctxt)));
4445 else if (TREE_CODE (ctxt) == CATEGORY_IMPLEMENTATION_TYPE
4446 || TREE_CODE (ctxt) == CATEGORY_INTERFACE_TYPE)
4448 /* We have a category. */
4449 const char *const class_name
4450 = IDENTIFIER_POINTER (CLASS_NAME (objc_implementation_context));
4451 const char *const class_super_name
4452 = IDENTIFIER_POINTER (CLASS_SUPER_NAME (objc_implementation_context));
4453 string = (char *) alloca (strlen (preamble)
4454 + strlen (class_name)
4455 + strlen (class_super_name)
4457 sprintf (string, "%s_%s_%s", preamble, class_name, class_super_name);
4459 else if (TREE_CODE (ctxt) == PROTOCOL_INTERFACE_TYPE)
4461 const char *protocol_name = IDENTIFIER_POINTER (PROTOCOL_NAME (ctxt));
4463 = (char *) alloca (strlen (preamble) + strlen (protocol_name) + 3);
4464 sprintf (string, "%s_%s", preamble, protocol_name);
4469 return get_identifier (string);
4473 is_objc_type_qualifier (node)
4476 return (TREE_CODE (node) == IDENTIFIER_NODE
4477 && (node == ridpointers [(int) RID_CONST]
4478 || node == ridpointers [(int) RID_VOLATILE]
4479 || node == ridpointers [(int) RID_IN]
4480 || node == ridpointers [(int) RID_OUT]
4481 || node == ridpointers [(int) RID_INOUT]
4482 || node == ridpointers [(int) RID_BYCOPY]
4483 || node == ridpointers [(int) RID_BYREF]
4484 || node == ridpointers [(int) RID_ONEWAY]));
4487 /* If type is empty or only type qualifiers are present, add default
4488 type of id (otherwise grokdeclarator will default to int). */
4491 adjust_type_for_id_default (type)
4494 tree declspecs, chain;
4497 return build_tree_list (build_tree_list (NULL_TREE, objc_object_reference),
4498 build1 (INDIRECT_REF, NULL_TREE, NULL_TREE));
4500 declspecs = TREE_PURPOSE (type);
4502 /* Determine if a typespec is present. */
4503 for (chain = declspecs;
4505 chain = TREE_CHAIN (chain))
4507 if (!is_objc_type_qualifier (TREE_VALUE (chain)))
4511 return build_tree_list (tree_cons (NULL_TREE, objc_object_reference,
4513 build1 (INDIRECT_REF, NULL_TREE, NULL_TREE));
4518 selector ':' '(' typename ')' identifier
4521 Transform an Objective-C keyword argument into
4522 the C equivalent parameter declarator.
4524 In: key_name, an "identifier_node" (optional).
4525 arg_type, a "tree_list" (optional).
4526 arg_name, an "identifier_node".
4528 Note: It would be really nice to strongly type the preceding
4529 arguments in the function prototype; however, then I
4530 could not use the "accessor" macros defined in "tree.h".
4532 Out: an instance of "keyword_decl". */
4535 build_keyword_decl (key_name, arg_type, arg_name)
4542 /* If no type is specified, default to "id". */
4543 arg_type = adjust_type_for_id_default (arg_type);
4545 keyword_decl = make_node (KEYWORD_DECL);
4547 TREE_TYPE (keyword_decl) = arg_type;
4548 KEYWORD_ARG_NAME (keyword_decl) = arg_name;
4549 KEYWORD_KEY_NAME (keyword_decl) = key_name;
4551 return keyword_decl;
4554 /* Given a chain of keyword_decl's, synthesize the full keyword selector. */
4557 build_keyword_selector (selector)
4561 tree key_chain, key_name;
4564 /* Scan the selector to see how much space we'll need. */
4565 for (key_chain = selector; key_chain; key_chain = TREE_CHAIN (key_chain))
4567 if (TREE_CODE (selector) == KEYWORD_DECL)
4568 key_name = KEYWORD_KEY_NAME (key_chain);
4569 else if (TREE_CODE (selector) == TREE_LIST)
4570 key_name = TREE_PURPOSE (key_chain);
4575 len += IDENTIFIER_LENGTH (key_name) + 1;
4577 /* Just a ':' arg. */
4581 buf = (char *) alloca (len + 1);
4582 /* Start the buffer out as an empty string. */
4585 for (key_chain = selector; key_chain; key_chain = TREE_CHAIN (key_chain))
4587 if (TREE_CODE (selector) == KEYWORD_DECL)
4588 key_name = KEYWORD_KEY_NAME (key_chain);
4589 else if (TREE_CODE (selector) == TREE_LIST)
4590 key_name = TREE_PURPOSE (key_chain);
4595 strcat (buf, IDENTIFIER_POINTER (key_name));
4599 return get_identifier (buf);
4602 /* Used for declarations and definitions. */
4605 build_method_decl (code, ret_type, selector, add_args)
4606 enum tree_code code;
4613 /* If no type is specified, default to "id". */
4614 ret_type = adjust_type_for_id_default (ret_type);
4616 method_decl = make_node (code);
4617 TREE_TYPE (method_decl) = ret_type;
4619 /* If we have a keyword selector, create an identifier_node that
4620 represents the full selector name (`:' included)... */
4621 if (TREE_CODE (selector) == KEYWORD_DECL)
4623 METHOD_SEL_NAME (method_decl) = build_keyword_selector (selector);
4624 METHOD_SEL_ARGS (method_decl) = selector;
4625 METHOD_ADD_ARGS (method_decl) = add_args;
4629 METHOD_SEL_NAME (method_decl) = selector;
4630 METHOD_SEL_ARGS (method_decl) = NULL_TREE;
4631 METHOD_ADD_ARGS (method_decl) = NULL_TREE;
4637 #define METHOD_DEF 0
4638 #define METHOD_REF 1
4640 /* Used by `build_objc_method_call' and `comp_method_types'. Return
4641 an argument list for method METH. CONTEXT is either METHOD_DEF or
4642 METHOD_REF, saying whether we are trying to define a method or call
4643 one. SUPERFLAG says this is for a send to super; this makes a
4644 difference for the NeXT calling sequence in which the lookup and
4645 the method call are done together. */
4648 get_arg_type_list (meth, context, superflag)
4655 /* Receiver type. */
4656 if (flag_next_runtime && superflag)
4657 arglist = build_tree_list (NULL_TREE, super_type);
4658 else if (context == METHOD_DEF)
4659 arglist = build_tree_list (NULL_TREE, TREE_TYPE (self_decl));
4661 arglist = build_tree_list (NULL_TREE, id_type);
4663 /* Selector type - will eventually change to `int'. */
4664 chainon (arglist, build_tree_list (NULL_TREE, selector_type));
4666 /* Build a list of argument types. */
4667 for (akey = METHOD_SEL_ARGS (meth); akey; akey = TREE_CHAIN (akey))
4669 tree arg_decl = groktypename_in_parm_context (TREE_TYPE (akey));
4670 chainon (arglist, build_tree_list (NULL_TREE, TREE_TYPE (arg_decl)));
4673 if (METHOD_ADD_ARGS (meth) == objc_ellipsis_node)
4674 /* We have a `, ...' immediately following the selector,
4675 finalize the arglist...simulate get_parm_info (0). */
4677 else if (METHOD_ADD_ARGS (meth))
4679 /* we have a variable length selector */
4680 tree add_arg_list = TREE_CHAIN (METHOD_ADD_ARGS (meth));
4681 chainon (arglist, add_arg_list);
4684 /* finalize the arglist...simulate get_parm_info (1) */
4685 chainon (arglist, build_tree_list (NULL_TREE, void_type_node));
4691 check_duplicates (hsh)
4694 tree meth = NULL_TREE;
4702 /* We have two methods with the same name and different types. */
4704 char type = (TREE_CODE (meth) == INSTANCE_METHOD_DECL) ? '-' : '+';
4706 warning ("multiple declarations for method `%s'",
4707 IDENTIFIER_POINTER (METHOD_SEL_NAME (meth)));
4709 warn_with_method ("using", type, meth);
4710 for (loop = hsh->list; loop; loop = loop->next)
4711 warn_with_method ("also found", type, loop->value);
4717 /* If RECEIVER is a class reference, return the identifier node for
4718 the referenced class. RECEIVER is created by get_class_reference,
4719 so we check the exact form created depending on which runtimes are
4723 receiver_is_class_object (receiver)
4726 tree chain, exp, arg;
4728 /* The receiver is 'self' in the context of a class method. */
4729 if (objc_method_context
4730 && receiver == self_decl
4731 && TREE_CODE (objc_method_context) == CLASS_METHOD_DECL)
4733 return CLASS_NAME (objc_implementation_context);
4736 if (flag_next_runtime)
4738 /* The receiver is a variable created by
4739 build_class_reference_decl. */
4740 if (TREE_CODE (receiver) == VAR_DECL
4741 && TREE_TYPE (receiver) == objc_class_type)
4742 /* Look up the identifier. */
4743 for (chain = cls_ref_chain; chain; chain = TREE_CHAIN (chain))
4744 if (TREE_PURPOSE (chain) == receiver)
4745 return TREE_VALUE (chain);
4749 /* The receiver is a function call that returns an id. Check if
4750 it is a call to objc_getClass, if so, pick up the class name. */
4751 if (TREE_CODE (receiver) == CALL_EXPR
4752 && (exp = TREE_OPERAND (receiver, 0))
4753 && TREE_CODE (exp) == ADDR_EXPR
4754 && (exp = TREE_OPERAND (exp, 0))
4755 && TREE_CODE (exp) == FUNCTION_DECL
4756 && exp == objc_get_class_decl
4757 /* We have a call to objc_getClass! */
4758 && (arg = TREE_OPERAND (receiver, 1))
4759 && TREE_CODE (arg) == TREE_LIST
4760 && (arg = TREE_VALUE (arg)))
4763 if (TREE_CODE (arg) == ADDR_EXPR
4764 && (arg = TREE_OPERAND (arg, 0))
4765 && TREE_CODE (arg) == STRING_CST)
4766 /* Finally, we have the class name. */
4767 return get_identifier (TREE_STRING_POINTER (arg));
4773 /* If we are currently building a message expr, this holds
4774 the identifier of the selector of the message. This is
4775 used when printing warnings about argument mismatches. */
4777 static tree building_objc_message_expr = 0;
4780 maybe_building_objc_message_expr ()
4782 return building_objc_message_expr;
4785 /* Construct an expression for sending a message.
4786 MESS has the object to send to in TREE_PURPOSE
4787 and the argument list (including selector) in TREE_VALUE.
4789 (*(<abstract_decl>(*)())_msg)(receiver, selTransTbl[n], ...);
4790 (*(<abstract_decl>(*)())_msgSuper)(receiver, selTransTbl[n], ...); */
4793 build_message_expr (mess)
4796 tree receiver = TREE_PURPOSE (mess);
4798 tree args = TREE_VALUE (mess);
4799 tree method_params = NULL_TREE;
4801 if (TREE_CODE (receiver) == ERROR_MARK)
4802 return error_mark_node;
4804 /* Obtain the full selector name. */
4805 if (TREE_CODE (args) == IDENTIFIER_NODE)
4806 /* A unary selector. */
4808 else if (TREE_CODE (args) == TREE_LIST)
4809 sel_name = build_keyword_selector (args);
4813 /* Build the parameter list to give to the method. */
4814 if (TREE_CODE (args) == TREE_LIST)
4816 tree chain = args, prev = NULL_TREE;
4818 /* We have a keyword selector--check for comma expressions. */
4821 tree element = TREE_VALUE (chain);
4823 /* We have a comma expression, must collapse... */
4824 if (TREE_CODE (element) == TREE_LIST)
4827 TREE_CHAIN (prev) = element;
4832 chain = TREE_CHAIN (chain);
4834 method_params = args;
4837 return finish_message_expr (receiver, sel_name, method_params);
4840 /* The 'finish_message_expr' routine is called from within
4841 'build_message_expr' for non-template functions. In the case of
4842 C++ template functions, it is called from 'build_expr_from_tree'
4843 (in decl2.c) after RECEIVER and METHOD_PARAMS have been expanded. */
4846 finish_message_expr (receiver, sel_name, method_params)
4847 tree receiver, sel_name, method_params;
4849 tree method_prototype = NULL_TREE, class_ident = NULL_TREE;
4850 tree selector, self_object, retval;
4851 int statically_typed = 0, statically_allocated = 0;
4853 /* Determine receiver type. */
4854 tree rtype = TREE_TYPE (receiver);
4855 int super = IS_SUPER (rtype);
4859 if (TREE_STATIC_TEMPLATE (rtype))
4860 statically_allocated = 1;
4861 else if (TREE_CODE (rtype) == POINTER_TYPE
4862 && TREE_STATIC_TEMPLATE (TREE_TYPE (rtype)))
4863 statically_typed = 1;
4864 else if ((flag_next_runtime
4866 && (class_ident = receiver_is_class_object (receiver)))
4868 else if (! IS_ID (rtype)
4869 /* Allow any type that matches objc_class_type. */
4870 && ! comptypes (rtype, objc_class_type))
4872 warning ("invalid receiver type `%s'",
4873 gen_declaration (rtype, errbuf));
4875 if (statically_allocated)
4876 receiver = build_unary_op (ADDR_EXPR, receiver, 0);
4878 /* Don't evaluate the receiver twice. */
4879 receiver = save_expr (receiver);
4880 self_object = receiver;
4883 /* If sending to `super', use current self as the object. */
4884 self_object = self_decl;
4886 /* Determine operation return type. */
4892 if (CLASS_SUPER_NAME (implementation_template))
4895 = lookup_interface (CLASS_SUPER_NAME (implementation_template));
4897 if (TREE_CODE (objc_method_context) == INSTANCE_METHOD_DECL)
4898 method_prototype = lookup_instance_method_static (iface, sel_name);
4900 method_prototype = lookup_class_method_static (iface, sel_name);
4902 if (iface && !method_prototype)
4903 warning ("`%s' does not respond to `%s'",
4904 IDENTIFIER_POINTER (CLASS_SUPER_NAME (implementation_template)),
4905 IDENTIFIER_POINTER (sel_name));
4909 error ("no super class declared in interface for `%s'",
4910 IDENTIFIER_POINTER (CLASS_NAME (implementation_template)));
4911 return error_mark_node;
4915 else if (statically_allocated)
4917 tree ctype = TREE_TYPE (rtype);
4918 tree iface = lookup_interface (TYPE_NAME (rtype));
4921 method_prototype = lookup_instance_method_static (iface, sel_name);
4923 if (! method_prototype && TYPE_PROTOCOL_LIST (ctype))
4925 = lookup_method_in_protocol_list (TYPE_PROTOCOL_LIST (ctype),
4928 if (!method_prototype)
4929 warning ("`%s' does not respond to `%s'",
4930 IDENTIFIER_POINTER (TYPE_NAME (rtype)),
4931 IDENTIFIER_POINTER (sel_name));
4933 else if (statically_typed)
4935 tree ctype = TREE_TYPE (rtype);
4937 /* `self' is now statically_typed. All methods should be visible
4938 within the context of the implementation. */
4939 if (objc_implementation_context
4940 && CLASS_NAME (objc_implementation_context) == TYPE_NAME (ctype))
4943 = lookup_instance_method_static (implementation_template,
4946 if (! method_prototype && TYPE_PROTOCOL_LIST (ctype))
4948 = lookup_method_in_protocol_list (TYPE_PROTOCOL_LIST (ctype),
4951 if (! method_prototype
4952 && implementation_template != objc_implementation_context)
4953 /* The method is not published in the interface. Check
4956 = lookup_method (CLASS_NST_METHODS (objc_implementation_context),
4963 if ((iface = lookup_interface (TYPE_NAME (ctype))))
4964 method_prototype = lookup_instance_method_static (iface, sel_name);
4966 if (! method_prototype)
4968 tree protocol_list = TYPE_PROTOCOL_LIST (ctype);
4971 = lookup_method_in_protocol_list (protocol_list,
4976 if (!method_prototype)
4977 warning ("`%s' does not respond to `%s'",
4978 IDENTIFIER_POINTER (TYPE_NAME (ctype)),
4979 IDENTIFIER_POINTER (sel_name));
4981 else if (class_ident)
4983 if (objc_implementation_context
4984 && CLASS_NAME (objc_implementation_context) == class_ident)
4987 = lookup_class_method_static (implementation_template, sel_name);
4989 if (!method_prototype
4990 && implementation_template != objc_implementation_context)
4991 /* The method is not published in the interface. Check
4994 = lookup_method (CLASS_CLS_METHODS (objc_implementation_context),
5001 if ((iface = lookup_interface (class_ident)))
5002 method_prototype = lookup_class_method_static (iface, sel_name);
5005 if (!method_prototype)
5007 warning ("cannot find class (factory) method");
5008 warning ("return type for `%s' defaults to id",
5009 IDENTIFIER_POINTER (sel_name));
5012 else if (IS_PROTOCOL_QUALIFIED_ID (rtype))
5014 /* An anonymous object that has been qualified with a protocol. */
5016 tree protocol_list = TYPE_PROTOCOL_LIST (rtype);
5018 method_prototype = lookup_method_in_protocol_list (protocol_list,
5021 if (!method_prototype)
5025 warning ("method `%s' not implemented by protocol",
5026 IDENTIFIER_POINTER (sel_name));
5028 /* Try and find the method signature in the global pools. */
5030 if (!(hsh = hash_lookup (nst_method_hash_list, sel_name)))
5031 hsh = hash_lookup (cls_method_hash_list, sel_name);
5033 if (!(method_prototype = check_duplicates (hsh)))
5034 warning ("return type defaults to id");
5041 /* We think we have an instance...loophole: extern id Object; */
5042 hsh = hash_lookup (nst_method_hash_list, sel_name);
5045 /* For various loopholes */
5046 hsh = hash_lookup (cls_method_hash_list, sel_name);
5048 method_prototype = check_duplicates (hsh);
5049 if (!method_prototype)
5051 warning ("cannot find method");
5052 warning ("return type for `%s' defaults to id",
5053 IDENTIFIER_POINTER (sel_name));
5057 /* Save the selector name for printing error messages. */
5058 building_objc_message_expr = sel_name;
5060 /* Build the parameters list for looking up the method.
5061 These are the object itself and the selector. */
5063 if (flag_typed_selectors)
5064 selector = build_typed_selector_reference (sel_name, method_prototype);
5066 selector = build_selector_reference (sel_name);
5068 retval = build_objc_method_call (super, method_prototype,
5069 receiver, self_object,
5070 selector, method_params);
5072 building_objc_message_expr = 0;
5077 /* Build a tree expression to send OBJECT the operation SELECTOR,
5078 looking up the method on object LOOKUP_OBJECT (often same as OBJECT),
5079 assuming the method has prototype METHOD_PROTOTYPE.
5080 (That is an INSTANCE_METHOD_DECL or CLASS_METHOD_DECL.)
5081 Use METHOD_PARAMS as list of args to pass to the method.
5082 If SUPER_FLAG is nonzero, we look up the superclass's method. */
5085 build_objc_method_call (super_flag, method_prototype, lookup_object, object,
5086 selector, method_params)
5088 tree method_prototype, lookup_object, object, selector, method_params;
5090 tree sender = (super_flag ? umsg_super_decl : umsg_decl);
5091 tree rcv_p = (super_flag
5092 ? build_pointer_type (xref_tag (RECORD_TYPE,
5093 get_identifier (TAG_SUPER)))
5096 if (flag_next_runtime)
5098 if (! method_prototype)
5100 method_params = tree_cons (NULL_TREE, lookup_object,
5101 tree_cons (NULL_TREE, selector,
5103 assemble_external (sender);
5104 return build_function_call (sender, method_params);
5108 /* This is a real kludge, but it is used only for the Next.
5109 Clobber the data type of SENDER temporarily to accept
5110 all the arguments for this operation, and to return
5111 whatever this operation returns. */
5112 tree arglist = NULL_TREE, retval, savarg, savret;
5113 tree ret_type = groktypename (TREE_TYPE (method_prototype));
5115 /* Save the proper contents of SENDER's data type. */
5116 savarg = TYPE_ARG_TYPES (TREE_TYPE (sender));
5117 savret = TREE_TYPE (TREE_TYPE (sender));
5119 /* Install this method's argument types. */
5120 arglist = get_arg_type_list (method_prototype, METHOD_REF,
5122 TYPE_ARG_TYPES (TREE_TYPE (sender)) = arglist;
5124 /* Install this method's return type. */
5125 TREE_TYPE (TREE_TYPE (sender)) = ret_type;
5127 /* Call SENDER with all the parameters. This will do type
5128 checking using the arg types for this method. */
5129 method_params = tree_cons (NULL_TREE, lookup_object,
5130 tree_cons (NULL_TREE, selector,
5132 assemble_external (sender);
5133 retval = build_function_call (sender, method_params);
5135 /* Restore SENDER's return/argument types. */
5136 TYPE_ARG_TYPES (TREE_TYPE (sender)) = savarg;
5137 TREE_TYPE (TREE_TYPE (sender)) = savret;
5143 /* This is the portable way.
5144 First call the lookup function to get a pointer to the method,
5145 then cast the pointer, then call it with the method arguments. */
5148 /* Avoid trouble since we may evaluate each of these twice. */
5149 object = save_expr (object);
5150 selector = save_expr (selector);
5152 lookup_object = build_c_cast (rcv_p, lookup_object);
5154 assemble_external (sender);
5156 = build_function_call (sender,
5157 tree_cons (NULL_TREE, lookup_object,
5158 tree_cons (NULL_TREE, selector,
5161 /* If we have a method prototype, construct the data type this
5162 method needs, and cast what we got from SENDER into a pointer
5164 if (method_prototype)
5166 tree arglist = get_arg_type_list (method_prototype, METHOD_REF,
5168 tree valtype = groktypename (TREE_TYPE (method_prototype));
5169 tree fake_function_type = build_function_type (valtype, arglist);
5170 TREE_TYPE (method) = build_pointer_type (fake_function_type);
5174 = build_pointer_type (build_function_type (ptr_type_node, NULL_TREE));
5176 /* Pass the object to the method. */
5177 assemble_external (method);
5178 return build_function_call (method,
5179 tree_cons (NULL_TREE, object,
5180 tree_cons (NULL_TREE, selector,
5186 build_protocol_reference (p)
5189 tree decl, ident, ptype;
5191 /* extern struct objc_protocol _OBJC_PROTOCOL_<mumble>; */
5193 ident = synth_id_with_class_suffix ("_OBJC_PROTOCOL", p);
5195 = groktypename (build_tree_list (build_tree_list (NULL_TREE,
5196 objc_protocol_template),
5199 if (IDENTIFIER_GLOBAL_VALUE (ident))
5200 decl = IDENTIFIER_GLOBAL_VALUE (ident); /* Set by pushdecl. */
5203 decl = build_decl (VAR_DECL, ident, ptype);
5204 DECL_EXTERNAL (decl) = 1;
5205 TREE_PUBLIC (decl) = 1;
5206 TREE_USED (decl) = 1;
5207 DECL_ARTIFICIAL (decl) = 1;
5209 make_decl_rtl (decl, 0);
5210 pushdecl_top_level (decl);
5213 PROTOCOL_FORWARD_DECL (p) = decl;
5217 build_protocol_expr (protoname)
5221 tree p = lookup_protocol (protoname);
5225 error ("cannot find protocol declaration for `%s'",
5226 IDENTIFIER_POINTER (protoname));
5227 return error_mark_node;
5230 if (!PROTOCOL_FORWARD_DECL (p))
5231 build_protocol_reference (p);
5233 expr = build_unary_op (ADDR_EXPR, PROTOCOL_FORWARD_DECL (p), 0);
5235 TREE_TYPE (expr) = protocol_type;
5241 build_selector_expr (selnamelist)
5246 /* Obtain the full selector name. */
5247 if (TREE_CODE (selnamelist) == IDENTIFIER_NODE)
5248 /* A unary selector. */
5249 selname = selnamelist;
5250 else if (TREE_CODE (selnamelist) == TREE_LIST)
5251 selname = build_keyword_selector (selnamelist);
5255 if (flag_typed_selectors)
5256 return build_typed_selector_reference (selname, 0);
5258 return build_selector_reference (selname);
5262 build_encode_expr (type)
5268 encode_type (type, obstack_object_size (&util_obstack),
5269 OBJC_ENCODE_INLINE_DEFS);
5270 obstack_1grow (&util_obstack, 0); /* null terminate string */
5271 string = obstack_finish (&util_obstack);
5273 /* Synthesize a string that represents the encoded struct/union. */
5274 result = my_build_string (strlen (string) + 1, string);
5275 obstack_free (&util_obstack, util_firstobj);
5280 build_ivar_reference (id)
5283 if (TREE_CODE (objc_method_context) == CLASS_METHOD_DECL)
5285 /* Historically, a class method that produced objects (factory
5286 method) would assign `self' to the instance that it
5287 allocated. This would effectively turn the class method into
5288 an instance method. Following this assignment, the instance
5289 variables could be accessed. That practice, while safe,
5290 violates the simple rule that a class method should not refer
5291 to an instance variable. It's better to catch the cases
5292 where this is done unknowingly than to support the above
5294 warning ("instance variable `%s' accessed in class method",
5295 IDENTIFIER_POINTER (id));
5296 TREE_TYPE (self_decl) = instance_type; /* cast */
5299 return build_component_ref (build_indirect_ref (self_decl, "->"), id);
5302 /* Compute a hash value for a given method SEL_NAME. */
5305 hash_func (sel_name)
5308 const unsigned char *s
5309 = (const unsigned char *)IDENTIFIER_POINTER (sel_name);
5313 h = h * 67 + *s++ - 113;
5320 nst_method_hash_list = (hash *) xcalloc (SIZEHASHTABLE, sizeof (hash));
5321 cls_method_hash_list = (hash *) xcalloc (SIZEHASHTABLE, sizeof (hash));
5324 /* WARNING!!!! hash_enter is called with a method, and will peek
5325 inside to find its selector! But hash_lookup is given a selector
5326 directly, and looks for the selector that's inside the found
5327 entry's key (method) for comparison. */
5330 hash_enter (hashlist, method)
5334 static hash hash_alloc_list = 0;
5335 static int hash_alloc_index = 0;
5337 int slot = hash_func (METHOD_SEL_NAME (method)) % SIZEHASHTABLE;
5339 if (! hash_alloc_list || hash_alloc_index >= HASH_ALLOC_LIST_SIZE)
5341 hash_alloc_index = 0;
5342 hash_alloc_list = (hash) xmalloc (sizeof (struct hashed_entry)
5343 * HASH_ALLOC_LIST_SIZE);
5345 obj = &hash_alloc_list[hash_alloc_index++];
5347 obj->next = hashlist[slot];
5350 hashlist[slot] = obj; /* append to front */
5354 hash_lookup (hashlist, sel_name)
5360 target = hashlist[hash_func (sel_name) % SIZEHASHTABLE];
5364 if (sel_name == METHOD_SEL_NAME (target->key))
5367 target = target->next;
5373 hash_add_attr (entry, value)
5377 static attr attr_alloc_list = 0;
5378 static int attr_alloc_index = 0;
5381 if (! attr_alloc_list || attr_alloc_index >= ATTR_ALLOC_LIST_SIZE)
5383 attr_alloc_index = 0;
5384 attr_alloc_list = (attr) xmalloc (sizeof (struct hashed_attribute)
5385 * ATTR_ALLOC_LIST_SIZE);
5387 obj = &attr_alloc_list[attr_alloc_index++];
5388 obj->next = entry->list;
5391 entry->list = obj; /* append to front */
5395 lookup_method (mchain, method)
5401 if (TREE_CODE (method) == IDENTIFIER_NODE)
5404 key = METHOD_SEL_NAME (method);
5408 if (METHOD_SEL_NAME (mchain) == key)
5410 mchain = TREE_CHAIN (mchain);
5416 lookup_instance_method_static (interface, ident)
5420 tree inter = interface;
5421 tree chain = CLASS_NST_METHODS (inter);
5422 tree meth = NULL_TREE;
5426 if ((meth = lookup_method (chain, ident)))
5429 if (CLASS_CATEGORY_LIST (inter))
5431 tree category = CLASS_CATEGORY_LIST (inter);
5432 chain = CLASS_NST_METHODS (category);
5436 if ((meth = lookup_method (chain, ident)))
5439 /* Check for instance methods in protocols in categories. */
5440 if (CLASS_PROTOCOL_LIST (category))
5442 if ((meth = (lookup_method_in_protocol_list
5443 (CLASS_PROTOCOL_LIST (category), ident, 0))))
5447 if ((category = CLASS_CATEGORY_LIST (category)))
5448 chain = CLASS_NST_METHODS (category);
5453 if (CLASS_PROTOCOL_LIST (inter))
5455 if ((meth = (lookup_method_in_protocol_list
5456 (CLASS_PROTOCOL_LIST (inter), ident, 0))))
5460 if ((inter = lookup_interface (CLASS_SUPER_NAME (inter))))
5461 chain = CLASS_NST_METHODS (inter);
5469 lookup_class_method_static (interface, ident)
5473 tree inter = interface;
5474 tree chain = CLASS_CLS_METHODS (inter);
5475 tree meth = NULL_TREE;
5476 tree root_inter = NULL_TREE;
5480 if ((meth = lookup_method (chain, ident)))
5483 if (CLASS_CATEGORY_LIST (inter))
5485 tree category = CLASS_CATEGORY_LIST (inter);
5486 chain = CLASS_CLS_METHODS (category);
5490 if ((meth = lookup_method (chain, ident)))
5493 /* Check for class methods in protocols in categories. */
5494 if (CLASS_PROTOCOL_LIST (category))
5496 if ((meth = (lookup_method_in_protocol_list
5497 (CLASS_PROTOCOL_LIST (category), ident, 1))))
5501 if ((category = CLASS_CATEGORY_LIST (category)))
5502 chain = CLASS_CLS_METHODS (category);
5507 /* Check for class methods in protocols. */
5508 if (CLASS_PROTOCOL_LIST (inter))
5510 if ((meth = (lookup_method_in_protocol_list
5511 (CLASS_PROTOCOL_LIST (inter), ident, 1))))
5516 if ((inter = lookup_interface (CLASS_SUPER_NAME (inter))))
5517 chain = CLASS_CLS_METHODS (inter);
5521 /* If no class (factory) method was found, check if an _instance_
5522 method of the same name exists in the root class. This is what
5523 the Objective-C runtime will do. */
5524 return lookup_instance_method_static (root_inter, ident);
5528 add_class_method (class, method)
5535 if (!(mth = lookup_method (CLASS_CLS_METHODS (class), method)))
5537 /* put method on list in reverse order */
5538 TREE_CHAIN (method) = CLASS_CLS_METHODS (class);
5539 CLASS_CLS_METHODS (class) = method;
5543 if (TREE_CODE (class) == CLASS_IMPLEMENTATION_TYPE)
5544 error ("duplicate definition of class method `%s'",
5545 IDENTIFIER_POINTER (METHOD_SEL_NAME (mth)));
5548 /* Check types; if different, complain. */
5549 if (!comp_proto_with_proto (method, mth))
5550 error ("duplicate declaration of class method `%s'",
5551 IDENTIFIER_POINTER (METHOD_SEL_NAME (mth)));
5555 if (!(hsh = hash_lookup (cls_method_hash_list, METHOD_SEL_NAME (method))))
5557 /* Install on a global chain. */
5558 hash_enter (cls_method_hash_list, method);
5562 /* Check types; if different, add to a list. */
5563 if (!comp_proto_with_proto (method, hsh->key))
5564 hash_add_attr (hsh, method);
5570 add_instance_method (class, method)
5577 if (!(mth = lookup_method (CLASS_NST_METHODS (class), method)))
5579 /* Put method on list in reverse order. */
5580 TREE_CHAIN (method) = CLASS_NST_METHODS (class);
5581 CLASS_NST_METHODS (class) = method;
5585 if (TREE_CODE (class) == CLASS_IMPLEMENTATION_TYPE)
5586 error ("duplicate definition of instance method `%s'",
5587 IDENTIFIER_POINTER (METHOD_SEL_NAME (mth)));
5590 /* Check types; if different, complain. */
5591 if (!comp_proto_with_proto (method, mth))
5592 error ("duplicate declaration of instance method `%s'",
5593 IDENTIFIER_POINTER (METHOD_SEL_NAME (mth)));
5597 if (!(hsh = hash_lookup (nst_method_hash_list, METHOD_SEL_NAME (method))))
5599 /* Install on a global chain. */
5600 hash_enter (nst_method_hash_list, method);
5604 /* Check types; if different, add to a list. */
5605 if (!comp_proto_with_proto (method, hsh->key))
5606 hash_add_attr (hsh, method);
5615 /* Put interfaces on list in reverse order. */
5616 TREE_CHAIN (class) = interface_chain;
5617 interface_chain = class;
5618 return interface_chain;
5622 add_category (class, category)
5626 /* Put categories on list in reverse order. */
5627 tree cat = CLASS_CATEGORY_LIST (class);
5631 if (CLASS_SUPER_NAME (cat) == CLASS_SUPER_NAME (category))
5632 warning ("duplicate interface declaration for category `%s(%s)'",
5633 IDENTIFIER_POINTER (CLASS_NAME (class)),
5634 IDENTIFIER_POINTER (CLASS_SUPER_NAME (category)));
5635 cat = CLASS_CATEGORY_LIST (cat);
5638 CLASS_CATEGORY_LIST (category) = CLASS_CATEGORY_LIST (class);
5639 CLASS_CATEGORY_LIST (class) = category;
5642 /* Called after parsing each instance variable declaration. Necessary to
5643 preserve typedefs and implement public/private...
5645 PUBLIC is 1 for public, 0 for protected, and 2 for private. */
5648 add_instance_variable (class, public, declarator, declspecs, width)
5655 tree field_decl, raw_decl;
5657 raw_decl = build_tree_list (declspecs, declarator);
5659 if (CLASS_RAW_IVARS (class))
5660 chainon (CLASS_RAW_IVARS (class), raw_decl);
5662 CLASS_RAW_IVARS (class) = raw_decl;
5664 field_decl = grokfield (input_filename, lineno,
5665 declarator, declspecs, width);
5667 /* Overload the public attribute, it is not used for FIELD_DECLs. */
5671 TREE_PUBLIC (field_decl) = 0;
5672 TREE_PRIVATE (field_decl) = 0;
5673 TREE_PROTECTED (field_decl) = 1;
5677 TREE_PUBLIC (field_decl) = 1;
5678 TREE_PRIVATE (field_decl) = 0;
5679 TREE_PROTECTED (field_decl) = 0;
5683 TREE_PUBLIC (field_decl) = 0;
5684 TREE_PRIVATE (field_decl) = 1;
5685 TREE_PROTECTED (field_decl) = 0;
5690 if (CLASS_IVARS (class))
5691 chainon (CLASS_IVARS (class), field_decl);
5693 CLASS_IVARS (class) = field_decl;
5699 is_ivar (decl_chain, ident)
5703 for ( ; decl_chain; decl_chain = TREE_CHAIN (decl_chain))
5704 if (DECL_NAME (decl_chain) == ident)
5709 /* True if the ivar is private and we are not in its implementation. */
5715 if (TREE_PRIVATE (decl)
5716 && ! is_ivar (CLASS_IVARS (implementation_template), DECL_NAME (decl)))
5718 error ("instance variable `%s' is declared private",
5719 IDENTIFIER_POINTER (DECL_NAME (decl)));
5726 /* We have an instance variable reference;, check to see if it is public. */
5729 is_public (expr, identifier)
5733 tree basetype = TREE_TYPE (expr);
5734 enum tree_code code = TREE_CODE (basetype);
5737 if (code == RECORD_TYPE)
5739 if (TREE_STATIC_TEMPLATE (basetype))
5741 if (!lookup_interface (TYPE_NAME (basetype)))
5743 error ("cannot find interface declaration for `%s'",
5744 IDENTIFIER_POINTER (TYPE_NAME (basetype)));
5748 if ((decl = is_ivar (TYPE_FIELDS (basetype), identifier)))
5750 if (TREE_PUBLIC (decl))
5753 /* Important difference between the Stepstone translator:
5754 all instance variables should be public within the context
5755 of the implementation. */
5756 if (objc_implementation_context
5757 && (((TREE_CODE (objc_implementation_context)
5758 == CLASS_IMPLEMENTATION_TYPE)
5759 || (TREE_CODE (objc_implementation_context)
5760 == CATEGORY_IMPLEMENTATION_TYPE))
5761 && (CLASS_NAME (objc_implementation_context)
5762 == TYPE_NAME (basetype))))
5763 return ! is_private (decl);
5765 error ("instance variable `%s' is declared %s",
5766 IDENTIFIER_POINTER (identifier),
5767 TREE_PRIVATE (decl) ? "private" : "protected");
5772 else if (objc_implementation_context && (basetype == objc_object_reference))
5774 TREE_TYPE (expr) = uprivate_record;
5775 warning ("static access to object of type `id'");
5782 /* Implement @defs (<classname>) within struct bodies. */
5785 get_class_ivars (interface)
5788 /* Make sure we copy the leaf ivars in case @defs is used in a local
5789 context. Otherwise finish_struct will overwrite the layout info
5790 using temporary storage. */
5791 return build_ivar_chain (interface, 1);
5794 /* Make sure all entries in CHAIN are also in LIST. */
5797 check_methods (chain, list, mtype)
5806 if (!lookup_method (list, chain))
5810 if (TREE_CODE (objc_implementation_context)
5811 == CLASS_IMPLEMENTATION_TYPE)
5812 warning ("incomplete implementation of class `%s'",
5813 IDENTIFIER_POINTER (CLASS_NAME (objc_implementation_context)));
5814 else if (TREE_CODE (objc_implementation_context)
5815 == CATEGORY_IMPLEMENTATION_TYPE)
5816 warning ("incomplete implementation of category `%s'",
5817 IDENTIFIER_POINTER (CLASS_SUPER_NAME (objc_implementation_context)));
5821 warning ("method definition for `%c%s' not found",
5822 mtype, IDENTIFIER_POINTER (METHOD_SEL_NAME (chain)));
5825 chain = TREE_CHAIN (chain);
5831 /* Check if CLASS, or its superclasses, explicitly conforms to PROTOCOL. */
5834 conforms_to_protocol (class, protocol)
5838 if (TREE_CODE (protocol) == PROTOCOL_INTERFACE_TYPE)
5840 tree p = CLASS_PROTOCOL_LIST (class);
5841 while (p && TREE_VALUE (p) != protocol)
5846 tree super = (CLASS_SUPER_NAME (class)
5847 ? lookup_interface (CLASS_SUPER_NAME (class))
5849 int tmp = super ? conforms_to_protocol (super, protocol) : 0;
5858 /* Make sure all methods in CHAIN are accessible as MTYPE methods in
5859 CONTEXT. This is one of two mechanisms to check protocol integrity. */
5862 check_methods_accessible (chain, context, mtype)
5869 tree base_context = context;
5873 context = base_context;
5877 list = CLASS_CLS_METHODS (context);
5879 list = CLASS_NST_METHODS (context);
5881 if (lookup_method (list, chain))
5884 else if (TREE_CODE (context) == CLASS_IMPLEMENTATION_TYPE
5885 || TREE_CODE (context) == CLASS_INTERFACE_TYPE)
5886 context = (CLASS_SUPER_NAME (context)
5887 ? lookup_interface (CLASS_SUPER_NAME (context))
5890 else if (TREE_CODE (context) == CATEGORY_IMPLEMENTATION_TYPE
5891 || TREE_CODE (context) == CATEGORY_INTERFACE_TYPE)
5892 context = (CLASS_NAME (context)
5893 ? lookup_interface (CLASS_NAME (context))
5899 if (context == NULL_TREE)
5903 if (TREE_CODE (objc_implementation_context)
5904 == CLASS_IMPLEMENTATION_TYPE)
5905 warning ("incomplete implementation of class `%s'",
5907 (CLASS_NAME (objc_implementation_context)));
5908 else if (TREE_CODE (objc_implementation_context)
5909 == CATEGORY_IMPLEMENTATION_TYPE)
5910 warning ("incomplete implementation of category `%s'",
5912 (CLASS_SUPER_NAME (objc_implementation_context)));
5915 warning ("method definition for `%c%s' not found",
5916 mtype, IDENTIFIER_POINTER (METHOD_SEL_NAME (chain)));
5919 chain = TREE_CHAIN (chain); /* next method... */
5924 /* Check whether the current interface (accessible via
5925 'objc_implementation_context') actually implements protocol P, along
5926 with any protocols that P inherits. */
5929 check_protocol (p, type, name)
5934 if (TREE_CODE (p) == PROTOCOL_INTERFACE_TYPE)
5938 /* Ensure that all protocols have bodies! */
5939 if (flag_warn_protocol)
5941 f1 = check_methods (PROTOCOL_CLS_METHODS (p),
5942 CLASS_CLS_METHODS (objc_implementation_context),
5944 f2 = check_methods (PROTOCOL_NST_METHODS (p),
5945 CLASS_NST_METHODS (objc_implementation_context),
5950 f1 = check_methods_accessible (PROTOCOL_CLS_METHODS (p),
5951 objc_implementation_context,
5953 f2 = check_methods_accessible (PROTOCOL_NST_METHODS (p),
5954 objc_implementation_context,
5959 warning ("%s `%s' does not fully implement the `%s' protocol",
5960 type, name, IDENTIFIER_POINTER (PROTOCOL_NAME (p)));
5963 /* Check protocols recursively. */
5964 if (PROTOCOL_LIST (p))
5966 tree subs = PROTOCOL_LIST (p);
5968 lookup_interface (CLASS_SUPER_NAME (implementation_template));
5972 tree sub = TREE_VALUE (subs);
5974 /* If the superclass does not conform to the protocols
5975 inherited by P, then we must! */
5976 if (!super_class || !conforms_to_protocol (super_class, sub))
5977 check_protocol (sub, type, name);
5978 subs = TREE_CHAIN (subs);
5983 /* Check whether the current interface (accessible via
5984 'objc_implementation_context') actually implements the protocols listed
5988 check_protocols (proto_list, type, name)
5993 for ( ; proto_list; proto_list = TREE_CHAIN (proto_list))
5995 tree p = TREE_VALUE (proto_list);
5997 check_protocol (p, type, name);
6001 /* Make sure that the class CLASS_NAME is defined
6002 CODE says which kind of thing CLASS_NAME ought to be.
6003 It can be CLASS_INTERFACE_TYPE, CLASS_IMPLEMENTATION_TYPE,
6004 CATEGORY_INTERFACE_TYPE, or CATEGORY_IMPLEMENTATION_TYPE. */
6007 start_class (code, class_name, super_name, protocol_list)
6008 enum tree_code code;
6015 if (objc_implementation_context)
6017 warning ("`@end' missing in implementation context");
6018 finish_class (objc_implementation_context);
6019 objc_ivar_chain = NULL_TREE;
6020 objc_implementation_context = NULL_TREE;
6023 class = make_node (code);
6024 TYPE_BINFO (class) = make_tree_vec (5);
6026 CLASS_NAME (class) = class_name;
6027 CLASS_SUPER_NAME (class) = super_name;
6028 CLASS_CLS_METHODS (class) = NULL_TREE;
6030 if (! is_class_name (class_name) && (decl = lookup_name (class_name)))
6032 error ("`%s' redeclared as different kind of symbol",
6033 IDENTIFIER_POINTER (class_name));
6034 error_with_decl (decl, "previous declaration of `%s'");
6037 if (code == CLASS_IMPLEMENTATION_TYPE)
6042 for (chain = implemented_classes; chain; chain = TREE_CHAIN (chain))
6043 if (TREE_VALUE (chain) == class_name)
6045 error ("reimplementation of class `%s'",
6046 IDENTIFIER_POINTER (class_name));
6047 return error_mark_node;
6049 implemented_classes = tree_cons (NULL_TREE, class_name,
6050 implemented_classes);
6053 /* Pre-build the following entities - for speed/convenience. */
6055 self_id = get_identifier ("self");
6057 ucmd_id = get_identifier ("_cmd");
6060 = build_tree_list (get_identifier ("__unused__"), NULL_TREE);
6061 if (!objc_super_template)
6062 objc_super_template = build_super_template ();
6064 /* Reset for multiple classes per file. */
6067 objc_implementation_context = class;
6069 /* Lookup the interface for this implementation. */
6071 if (!(implementation_template = lookup_interface (class_name)))
6073 warning ("cannot find interface declaration for `%s'",
6074 IDENTIFIER_POINTER (class_name));
6075 add_class (implementation_template = objc_implementation_context);
6078 /* If a super class has been specified in the implementation,
6079 insure it conforms to the one specified in the interface. */
6082 && (super_name != CLASS_SUPER_NAME (implementation_template)))
6084 tree previous_name = CLASS_SUPER_NAME (implementation_template);
6085 const char *const name =
6086 previous_name ? IDENTIFIER_POINTER (previous_name) : "";
6087 error ("conflicting super class name `%s'",
6088 IDENTIFIER_POINTER (super_name));
6089 error ("previous declaration of `%s'", name);
6092 else if (! super_name)
6094 CLASS_SUPER_NAME (objc_implementation_context)
6095 = CLASS_SUPER_NAME (implementation_template);
6099 else if (code == CLASS_INTERFACE_TYPE)
6101 if (lookup_interface (class_name))
6102 warning ("duplicate interface declaration for class `%s'",
6103 IDENTIFIER_POINTER (class_name));
6108 CLASS_PROTOCOL_LIST (class)
6109 = lookup_and_install_protocols (protocol_list);
6112 else if (code == CATEGORY_INTERFACE_TYPE)
6114 tree class_category_is_assoc_with;
6116 /* For a category, class_name is really the name of the class that
6117 the following set of methods will be associated with. We must
6118 find the interface so that can derive the objects template. */
6120 if (!(class_category_is_assoc_with = lookup_interface (class_name)))
6122 error ("cannot find interface declaration for `%s'",
6123 IDENTIFIER_POINTER (class_name));
6124 exit (FATAL_EXIT_CODE);
6127 add_category (class_category_is_assoc_with, class);
6130 CLASS_PROTOCOL_LIST (class)
6131 = lookup_and_install_protocols (protocol_list);
6134 else if (code == CATEGORY_IMPLEMENTATION_TYPE)
6136 /* Pre-build the following entities for speed/convenience. */
6138 self_id = get_identifier ("self");
6140 ucmd_id = get_identifier ("_cmd");
6143 = build_tree_list (get_identifier ("__unused__"), NULL_TREE);
6144 if (!objc_super_template)
6145 objc_super_template = build_super_template ();
6147 /* Reset for multiple classes per file. */
6150 objc_implementation_context = class;
6152 /* For a category, class_name is really the name of the class that
6153 the following set of methods will be associated with. We must
6154 find the interface so that can derive the objects template. */
6156 if (!(implementation_template = lookup_interface (class_name)))
6158 error ("cannot find interface declaration for `%s'",
6159 IDENTIFIER_POINTER (class_name));
6160 exit (FATAL_EXIT_CODE);
6167 continue_class (class)
6170 if (TREE_CODE (class) == CLASS_IMPLEMENTATION_TYPE
6171 || TREE_CODE (class) == CATEGORY_IMPLEMENTATION_TYPE)
6173 struct imp_entry *imp_entry;
6176 /* Check consistency of the instance variables. */
6178 if (CLASS_IVARS (class))
6179 check_ivars (implementation_template, class);
6181 /* code generation */
6183 ivar_context = build_private_template (implementation_template);
6185 if (!objc_class_template)
6186 build_class_template ();
6188 imp_entry = (struct imp_entry *) xmalloc (sizeof (struct imp_entry));
6190 imp_entry->next = imp_list;
6191 imp_entry->imp_context = class;
6192 imp_entry->imp_template = implementation_template;
6194 synth_forward_declarations ();
6195 imp_entry->class_decl = UOBJC_CLASS_decl;
6196 imp_entry->meta_decl = UOBJC_METACLASS_decl;
6198 /* Append to front and increment count. */
6199 imp_list = imp_entry;
6200 if (TREE_CODE (class) == CLASS_IMPLEMENTATION_TYPE)
6205 return ivar_context;
6208 else if (TREE_CODE (class) == CLASS_INTERFACE_TYPE)
6210 tree record = xref_tag (RECORD_TYPE, CLASS_NAME (class));
6212 if (!TYPE_FIELDS (record))
6214 finish_struct (record, build_ivar_chain (class, 0), NULL_TREE);
6215 CLASS_STATIC_TEMPLATE (class) = record;
6217 /* Mark this record as a class template for static typing. */
6218 TREE_STATIC_TEMPLATE (record) = 1;
6225 return error_mark_node;
6228 /* This is called once we see the "@end" in an interface/implementation. */
6231 finish_class (class)
6234 if (TREE_CODE (class) == CLASS_IMPLEMENTATION_TYPE)
6236 /* All code generation is done in finish_objc. */
6238 if (implementation_template != objc_implementation_context)
6240 /* Ensure that all method listed in the interface contain bodies. */
6241 check_methods (CLASS_CLS_METHODS (implementation_template),
6242 CLASS_CLS_METHODS (objc_implementation_context), '+');
6243 check_methods (CLASS_NST_METHODS (implementation_template),
6244 CLASS_NST_METHODS (objc_implementation_context), '-');
6246 if (CLASS_PROTOCOL_LIST (implementation_template))
6247 check_protocols (CLASS_PROTOCOL_LIST (implementation_template),
6249 IDENTIFIER_POINTER (CLASS_NAME (objc_implementation_context)));
6253 else if (TREE_CODE (class) == CATEGORY_IMPLEMENTATION_TYPE)
6255 tree category = CLASS_CATEGORY_LIST (implementation_template);
6257 /* Find the category interface from the class it is associated with. */
6260 if (CLASS_SUPER_NAME (class) == CLASS_SUPER_NAME (category))
6262 category = CLASS_CATEGORY_LIST (category);
6267 /* Ensure all method listed in the interface contain bodies. */
6268 check_methods (CLASS_CLS_METHODS (category),
6269 CLASS_CLS_METHODS (objc_implementation_context), '+');
6270 check_methods (CLASS_NST_METHODS (category),
6271 CLASS_NST_METHODS (objc_implementation_context), '-');
6273 if (CLASS_PROTOCOL_LIST (category))
6274 check_protocols (CLASS_PROTOCOL_LIST (category),
6276 IDENTIFIER_POINTER (CLASS_SUPER_NAME (objc_implementation_context)));
6280 else if (TREE_CODE (class) == CLASS_INTERFACE_TYPE)
6283 const char *class_name = IDENTIFIER_POINTER (CLASS_NAME (class));
6284 char *string = (char *) alloca (strlen (class_name) + 3);
6286 /* extern struct objc_object *_<my_name>; */
6288 sprintf (string, "_%s", class_name);
6290 decl_specs = build_tree_list (NULL_TREE, ridpointers[(int) RID_EXTERN]);
6291 decl_specs = tree_cons (NULL_TREE, objc_object_reference, decl_specs);
6292 define_decl (build1 (INDIRECT_REF, NULL_TREE, get_identifier (string)),
6298 add_protocol (protocol)
6301 /* Put protocol on list in reverse order. */
6302 TREE_CHAIN (protocol) = protocol_chain;
6303 protocol_chain = protocol;
6304 return protocol_chain;
6308 lookup_protocol (ident)
6313 for (chain = protocol_chain; chain; chain = TREE_CHAIN (chain))
6314 if (ident == PROTOCOL_NAME (chain))
6320 /* This function forward declares the protocols named by NAMES. If
6321 they are already declared or defined, the function has no effect. */
6324 objc_declare_protocols (names)
6329 for (list = names; list; list = TREE_CHAIN (list))
6331 tree name = TREE_VALUE (list);
6333 if (lookup_protocol (name) == NULL_TREE)
6335 tree protocol = make_node (PROTOCOL_INTERFACE_TYPE);
6337 TYPE_BINFO (protocol) = make_tree_vec (2);
6338 PROTOCOL_NAME (protocol) = name;
6339 PROTOCOL_LIST (protocol) = NULL_TREE;
6340 add_protocol (protocol);
6341 PROTOCOL_DEFINED (protocol) = 0;
6342 PROTOCOL_FORWARD_DECL (protocol) = NULL_TREE;
6348 start_protocol (code, name, list)
6349 enum tree_code code;
6355 /* This is as good a place as any. Need to invoke
6356 push_tag_toplevel. */
6357 if (!objc_protocol_template)
6358 objc_protocol_template = build_protocol_template ();
6360 protocol = lookup_protocol (name);
6364 protocol = make_node (code);
6365 TYPE_BINFO (protocol) = make_tree_vec (2);
6367 PROTOCOL_NAME (protocol) = name;
6368 PROTOCOL_LIST (protocol) = lookup_and_install_protocols (list);
6369 add_protocol (protocol);
6370 PROTOCOL_DEFINED (protocol) = 1;
6371 PROTOCOL_FORWARD_DECL (protocol) = NULL_TREE;
6373 check_protocol_recursively (protocol, list);
6375 else if (! PROTOCOL_DEFINED (protocol))
6377 PROTOCOL_DEFINED (protocol) = 1;
6378 PROTOCOL_LIST (protocol) = lookup_and_install_protocols (list);
6380 check_protocol_recursively (protocol, list);
6384 warning ("duplicate declaration for protocol `%s'",
6385 IDENTIFIER_POINTER (name));
6391 finish_protocol (protocol)
6392 tree protocol ATTRIBUTE_UNUSED;
6397 /* "Encode" a data type into a string, which grows in util_obstack.
6398 ??? What is the FORMAT? Someone please document this! */
6401 encode_type_qualifiers (declspecs)
6406 for (spec = declspecs; spec; spec = TREE_CHAIN (spec))
6408 if (ridpointers[(int) RID_CONST] == TREE_VALUE (spec))
6409 obstack_1grow (&util_obstack, 'r');
6410 else if (ridpointers[(int) RID_IN] == TREE_VALUE (spec))
6411 obstack_1grow (&util_obstack, 'n');
6412 else if (ridpointers[(int) RID_INOUT] == TREE_VALUE (spec))
6413 obstack_1grow (&util_obstack, 'N');
6414 else if (ridpointers[(int) RID_OUT] == TREE_VALUE (spec))
6415 obstack_1grow (&util_obstack, 'o');
6416 else if (ridpointers[(int) RID_BYCOPY] == TREE_VALUE (spec))
6417 obstack_1grow (&util_obstack, 'O');
6418 else if (ridpointers[(int) RID_BYREF] == TREE_VALUE (spec))
6419 obstack_1grow (&util_obstack, 'R');
6420 else if (ridpointers[(int) RID_ONEWAY] == TREE_VALUE (spec))
6421 obstack_1grow (&util_obstack, 'V');
6425 /* Encode a pointer type. */
6428 encode_pointer (type, curtype, format)
6433 tree pointer_to = TREE_TYPE (type);
6435 if (TREE_CODE (pointer_to) == RECORD_TYPE)
6437 if (TYPE_NAME (pointer_to)
6438 && TREE_CODE (TYPE_NAME (pointer_to)) == IDENTIFIER_NODE)
6440 const char *name = IDENTIFIER_POINTER (TYPE_NAME (pointer_to));
6442 if (strcmp (name, TAG_OBJECT) == 0) /* '@' */
6444 obstack_1grow (&util_obstack, '@');
6447 else if (TREE_STATIC_TEMPLATE (pointer_to))
6449 if (generating_instance_variables)
6451 obstack_1grow (&util_obstack, '@');
6452 obstack_1grow (&util_obstack, '"');
6453 obstack_grow (&util_obstack, name, strlen (name));
6454 obstack_1grow (&util_obstack, '"');
6459 obstack_1grow (&util_obstack, '@');
6463 else if (strcmp (name, TAG_CLASS) == 0) /* '#' */
6465 obstack_1grow (&util_obstack, '#');
6468 else if (strcmp (name, TAG_SELECTOR) == 0) /* ':' */
6470 obstack_1grow (&util_obstack, ':');
6475 else if (TREE_CODE (pointer_to) == INTEGER_TYPE
6476 && TYPE_MODE (pointer_to) == QImode)
6478 obstack_1grow (&util_obstack, '*');
6482 /* We have a type that does not get special treatment. */
6484 /* NeXT extension */
6485 obstack_1grow (&util_obstack, '^');
6486 encode_type (pointer_to, curtype, format);
6490 encode_array (type, curtype, format)
6495 tree an_int_cst = TYPE_SIZE (type);
6496 tree array_of = TREE_TYPE (type);
6499 /* An incomplete array is treated like a pointer. */
6500 if (an_int_cst == NULL)
6502 encode_pointer (type, curtype, format);
6506 sprintf (buffer, "[%ld",
6507 (long) (TREE_INT_CST_LOW (an_int_cst)
6508 / TREE_INT_CST_LOW (TYPE_SIZE (array_of))));
6510 obstack_grow (&util_obstack, buffer, strlen (buffer));
6511 encode_type (array_of, curtype, format);
6512 obstack_1grow (&util_obstack, ']');
6517 encode_aggregate_within (type, curtype, format, left, right)
6524 /* The RECORD_TYPE may in fact be a typedef! For purposes
6525 of encoding, we need the real underlying enchilada. */
6526 if (TYPE_MAIN_VARIANT (type))
6527 type = TYPE_MAIN_VARIANT (type);
6529 if (obstack_object_size (&util_obstack) > 0
6530 && *(obstack_next_free (&util_obstack) - 1) == '^')
6532 tree name = TYPE_NAME (type);
6534 /* we have a reference; this is a NeXT extension. */
6536 if (obstack_object_size (&util_obstack) - curtype == 1
6537 && format == OBJC_ENCODE_INLINE_DEFS)
6539 /* Output format of struct for first level only. */
6540 tree fields = TYPE_FIELDS (type);
6542 if (name && TREE_CODE (name) == IDENTIFIER_NODE)
6544 obstack_1grow (&util_obstack, left);
6545 obstack_grow (&util_obstack,
6546 IDENTIFIER_POINTER (name),
6547 strlen (IDENTIFIER_POINTER (name)));
6548 obstack_1grow (&util_obstack, '=');
6552 obstack_1grow (&util_obstack, left);
6553 obstack_grow (&util_obstack, "?=", 2);
6556 for ( ; fields; fields = TREE_CHAIN (fields))
6557 encode_field_decl (fields, curtype, format);
6559 obstack_1grow (&util_obstack, right);
6562 else if (name && TREE_CODE (name) == IDENTIFIER_NODE)
6564 obstack_1grow (&util_obstack, left);
6565 obstack_grow (&util_obstack,
6566 IDENTIFIER_POINTER (name),
6567 strlen (IDENTIFIER_POINTER (name)));
6568 obstack_1grow (&util_obstack, right);
6573 /* We have an untagged structure or a typedef. */
6574 obstack_1grow (&util_obstack, left);
6575 obstack_1grow (&util_obstack, '?');
6576 obstack_1grow (&util_obstack, right);
6582 tree name = TYPE_NAME (type);
6583 tree fields = TYPE_FIELDS (type);
6585 if (format == OBJC_ENCODE_INLINE_DEFS
6586 || generating_instance_variables)
6588 obstack_1grow (&util_obstack, left);
6589 if (name && TREE_CODE (name) == IDENTIFIER_NODE)
6590 obstack_grow (&util_obstack,
6591 IDENTIFIER_POINTER (name),
6592 strlen (IDENTIFIER_POINTER (name)));
6594 obstack_1grow (&util_obstack, '?');
6596 obstack_1grow (&util_obstack, '=');
6598 for (; fields; fields = TREE_CHAIN (fields))
6600 if (generating_instance_variables)
6602 tree fname = DECL_NAME (fields);
6604 obstack_1grow (&util_obstack, '"');
6605 if (fname && TREE_CODE (fname) == IDENTIFIER_NODE)
6607 obstack_grow (&util_obstack,
6608 IDENTIFIER_POINTER (fname),
6609 strlen (IDENTIFIER_POINTER (fname)));
6612 obstack_1grow (&util_obstack, '"');
6615 encode_field_decl (fields, curtype, format);
6618 obstack_1grow (&util_obstack, right);
6623 obstack_1grow (&util_obstack, left);
6624 if (name && TREE_CODE (name) == IDENTIFIER_NODE)
6625 obstack_grow (&util_obstack,
6626 IDENTIFIER_POINTER (name),
6627 strlen (IDENTIFIER_POINTER (name)));
6629 /* We have an untagged structure or a typedef. */
6630 obstack_1grow (&util_obstack, '?');
6632 obstack_1grow (&util_obstack, right);
6638 encode_aggregate (type, curtype, format)
6643 enum tree_code code = TREE_CODE (type);
6649 encode_aggregate_within(type, curtype, format, '{', '}');
6654 encode_aggregate_within(type, curtype, format, '(', ')');
6659 obstack_1grow (&util_obstack, 'i');
6667 /* Support bitfields. The current version of Objective-C does not support
6668 them. The string will consist of one or more "b:n"'s where n is an
6669 integer describing the width of the bitfield. Currently, classes in
6670 the kit implement a method "-(char *)describeBitfieldStruct:" that
6671 simulates this. If they do not implement this method, the archiver
6672 assumes the bitfield is 16 bits wide (padded if necessary) and packed
6673 according to the GNU compiler. After looking at the "kit", it appears
6674 that all classes currently rely on this default behavior, rather than
6675 hand generating this string (which is tedious). */
6678 encode_bitfield (width)
6682 sprintf (buffer, "b%d", width);
6683 obstack_grow (&util_obstack, buffer, strlen (buffer));
6686 /* FORMAT will be OBJC_ENCODE_INLINE_DEFS or OBJC_ENCODE_DONT_INLINE_DEFS. */
6689 encode_type (type, curtype, format)
6694 enum tree_code code = TREE_CODE (type);
6696 if (code == INTEGER_TYPE)
6698 if (integer_zerop (TYPE_MIN_VALUE (type)))
6700 /* Unsigned integer types. */
6702 if (TYPE_MODE (type) == QImode)
6703 obstack_1grow (&util_obstack, 'C');
6704 else if (TYPE_MODE (type) == HImode)
6705 obstack_1grow (&util_obstack, 'S');
6706 else if (TYPE_MODE (type) == SImode)
6708 if (type == long_unsigned_type_node)
6709 obstack_1grow (&util_obstack, 'L');
6711 obstack_1grow (&util_obstack, 'I');
6713 else if (TYPE_MODE (type) == DImode)
6714 obstack_1grow (&util_obstack, 'Q');
6718 /* Signed integer types. */
6720 if (TYPE_MODE (type) == QImode)
6721 obstack_1grow (&util_obstack, 'c');
6722 else if (TYPE_MODE (type) == HImode)
6723 obstack_1grow (&util_obstack, 's');
6724 else if (TYPE_MODE (type) == SImode)
6726 if (type == long_integer_type_node)
6727 obstack_1grow (&util_obstack, 'l');
6729 obstack_1grow (&util_obstack, 'i');
6732 else if (TYPE_MODE (type) == DImode)
6733 obstack_1grow (&util_obstack, 'q');
6737 else if (code == REAL_TYPE)
6739 /* Floating point types. */
6741 if (TYPE_MODE (type) == SFmode)
6742 obstack_1grow (&util_obstack, 'f');
6743 else if (TYPE_MODE (type) == DFmode
6744 || TYPE_MODE (type) == TFmode)
6745 obstack_1grow (&util_obstack, 'd');
6748 else if (code == VOID_TYPE)
6749 obstack_1grow (&util_obstack, 'v');
6751 else if (code == ARRAY_TYPE)
6752 encode_array (type, curtype, format);
6754 else if (code == POINTER_TYPE)
6755 encode_pointer (type, curtype, format);
6757 else if (code == RECORD_TYPE || code == UNION_TYPE || code == ENUMERAL_TYPE)
6758 encode_aggregate (type, curtype, format);
6760 else if (code == FUNCTION_TYPE) /* '?' */
6761 obstack_1grow (&util_obstack, '?');
6765 encode_complete_bitfield (int position, tree type, int size)
6767 enum tree_code code = TREE_CODE (type);
6769 char charType = '?';
6771 if (code == INTEGER_TYPE)
6773 if (integer_zerop (TYPE_MIN_VALUE (type)))
6775 /* Unsigned integer types. */
6777 if (TYPE_MODE (type) == QImode)
6779 else if (TYPE_MODE (type) == HImode)
6781 else if (TYPE_MODE (type) == SImode)
6783 if (type == long_unsigned_type_node)
6788 else if (TYPE_MODE (type) == DImode)
6793 /* Signed integer types. */
6795 if (TYPE_MODE (type) == QImode)
6797 else if (TYPE_MODE (type) == HImode)
6799 else if (TYPE_MODE (type) == SImode)
6801 if (type == long_integer_type_node)
6807 else if (TYPE_MODE (type) == DImode)
6811 else if (code == ENUMERAL_TYPE)
6816 sprintf (buffer, "b%d%c%d", position, charType, size);
6817 obstack_grow (&util_obstack, buffer, strlen (buffer));
6821 encode_field_decl (field_decl, curtype, format)
6828 type = TREE_TYPE (field_decl);
6830 /* If this field is obviously a bitfield, or is a bitfield that has been
6831 clobbered to look like a ordinary integer mode, go ahead and generate
6832 the bitfield typing information. */
6833 if (flag_next_runtime)
6835 if (DECL_BIT_FIELD (field_decl))
6836 encode_bitfield (tree_low_cst (DECL_SIZE (field_decl), 1));
6838 encode_type (TREE_TYPE (field_decl), curtype, format);
6842 if (DECL_BIT_FIELD (field_decl))
6843 encode_complete_bitfield (int_bit_position (field_decl),
6844 DECL_BIT_FIELD_TYPE (field_decl),
6845 tree_low_cst (DECL_SIZE (field_decl), 1));
6847 encode_type (TREE_TYPE (field_decl), curtype, format);
6852 expr_last (complex_expr)
6858 while ((next = TREE_OPERAND (complex_expr, 0)))
6859 complex_expr = next;
6861 return complex_expr;
6864 /* Transform a method definition into a function definition as follows:
6865 - synthesize the first two arguments, "self" and "_cmd". */
6868 start_method_def (method)
6873 /* Required to implement _msgSuper. */
6874 objc_method_context = method;
6875 UOBJC_SUPER_decl = NULL_TREE;
6877 /* Must be called BEFORE start_function. */
6880 /* Generate prototype declarations for arguments..."new-style". */
6882 if (TREE_CODE (objc_method_context) == INSTANCE_METHOD_DECL)
6883 decl_specs = build_tree_list (NULL_TREE, uprivate_record);
6885 /* Really a `struct objc_class *'. However, we allow people to
6886 assign to self, which changes its type midstream. */
6887 decl_specs = build_tree_list (NULL_TREE, objc_object_reference);
6889 push_parm_decl (build_tree_list
6890 (build_tree_list (decl_specs,
6891 build1 (INDIRECT_REF, NULL_TREE, self_id)),
6894 decl_specs = build_tree_list (NULL_TREE,
6895 xref_tag (RECORD_TYPE,
6896 get_identifier (TAG_SELECTOR)));
6897 push_parm_decl (build_tree_list
6898 (build_tree_list (decl_specs,
6899 build1 (INDIRECT_REF, NULL_TREE, ucmd_id)),
6902 /* Generate argument declarations if a keyword_decl. */
6903 if (METHOD_SEL_ARGS (method))
6905 tree arglist = METHOD_SEL_ARGS (method);
6908 tree arg_spec = TREE_PURPOSE (TREE_TYPE (arglist));
6909 tree arg_decl = TREE_VALUE (TREE_TYPE (arglist));
6913 tree last_expr = expr_last (arg_decl);
6915 /* Unite the abstract decl with its name. */
6916 TREE_OPERAND (last_expr, 0) = KEYWORD_ARG_NAME (arglist);
6917 push_parm_decl (build_tree_list
6918 (build_tree_list (arg_spec, arg_decl),
6921 /* Unhook: restore the abstract declarator. */
6922 TREE_OPERAND (last_expr, 0) = NULL_TREE;
6926 push_parm_decl (build_tree_list
6927 (build_tree_list (arg_spec,
6928 KEYWORD_ARG_NAME (arglist)),
6931 arglist = TREE_CHAIN (arglist);
6936 if (METHOD_ADD_ARGS (method) != NULL_TREE
6937 && METHOD_ADD_ARGS (method) != objc_ellipsis_node)
6939 /* We have a variable length selector - in "prototype" format. */
6940 tree akey = TREE_PURPOSE (METHOD_ADD_ARGS (method));
6943 /* This must be done prior to calling pushdecl. pushdecl is
6944 going to change our chain on us. */
6945 tree nextkey = TREE_CHAIN (akey);
6953 warn_with_method (message, mtype, method)
6954 const char *message;
6958 if (count_error (1) == 0)
6961 report_error_function (DECL_SOURCE_FILE (method));
6963 /* Add a readable method name to the warning. */
6964 warning_with_file_and_line (DECL_SOURCE_FILE (method),
6965 DECL_SOURCE_LINE (method),
6968 gen_method_decl (method, errbuf));
6971 /* Return 1 if METHOD is consistent with PROTO. */
6974 comp_method_with_proto (method, proto)
6977 /* Create a function template node at most once. */
6978 if (!function1_template)
6979 function1_template = make_node (FUNCTION_TYPE);
6981 /* Install argument types - normally set by build_function_type. */
6982 TYPE_ARG_TYPES (function1_template) = get_arg_type_list (proto, METHOD_DEF, 0);
6984 /* install return type */
6985 TREE_TYPE (function1_template) = groktypename (TREE_TYPE (proto));
6987 return comptypes (TREE_TYPE (METHOD_DEFINITION (method)), function1_template);
6990 /* Return 1 if PROTO1 is consistent with PROTO2. */
6993 comp_proto_with_proto (proto0, proto1)
6994 tree proto0, proto1;
6996 /* Create a couple of function_template nodes at most once. */
6997 if (!function1_template)
6998 function1_template = make_node (FUNCTION_TYPE);
6999 if (!function2_template)
7000 function2_template = make_node (FUNCTION_TYPE);
7002 /* Install argument types; normally set by build_function_type. */
7003 TYPE_ARG_TYPES (function1_template) = get_arg_type_list (proto0, METHOD_REF, 0);
7004 TYPE_ARG_TYPES (function2_template) = get_arg_type_list (proto1, METHOD_REF, 0);
7006 /* Install return type. */
7007 TREE_TYPE (function1_template) = groktypename (TREE_TYPE (proto0));
7008 TREE_TYPE (function2_template) = groktypename (TREE_TYPE (proto1));
7010 return comptypes (function1_template, function2_template);
7013 /* - Generate an identifier for the function. the format is "_n_cls",
7014 where 1 <= n <= nMethods, and cls is the name the implementation we
7016 - Install the return type from the method declaration.
7017 - If we have a prototype, check for type consistency. */
7020 really_start_method (method, parmlist)
7021 tree method, parmlist;
7023 tree sc_spec, ret_spec, ret_decl, decl_specs;
7024 tree method_decl, method_id;
7025 const char *sel_name, *class_name, *cat_name;
7028 /* Synth the storage class & assemble the return type. */
7029 sc_spec = tree_cons (NULL_TREE, ridpointers[(int) RID_STATIC], NULL_TREE);
7030 ret_spec = TREE_PURPOSE (TREE_TYPE (method));
7031 decl_specs = chainon (sc_spec, ret_spec);
7033 sel_name = IDENTIFIER_POINTER (METHOD_SEL_NAME (method));
7034 class_name = IDENTIFIER_POINTER (CLASS_NAME (objc_implementation_context));
7035 cat_name = ((TREE_CODE (objc_implementation_context)
7036 == CLASS_IMPLEMENTATION_TYPE)
7038 : IDENTIFIER_POINTER (CLASS_SUPER_NAME (objc_implementation_context)));
7041 /* Make sure this is big enough for any plausible method label. */
7042 buf = (char *) alloca (50 + strlen (sel_name) + strlen (class_name)
7043 + (cat_name ? strlen (cat_name) : 0));
7045 OBJC_GEN_METHOD_LABEL (buf, TREE_CODE (method) == INSTANCE_METHOD_DECL,
7046 class_name, cat_name, sel_name, method_slot);
7048 method_id = get_identifier (buf);
7050 method_decl = build_nt (CALL_EXPR, method_id, parmlist, NULL_TREE);
7052 /* Check the declarator portion of the return type for the method. */
7053 if ((ret_decl = TREE_VALUE (TREE_TYPE (method))))
7055 /* Unite the complex decl (specified in the abstract decl) with the
7056 function decl just synthesized..(int *), (int (*)()), (int (*)[]). */
7057 tree save_expr = expr_last (ret_decl);
7059 TREE_OPERAND (save_expr, 0) = method_decl;
7060 method_decl = ret_decl;
7062 /* Fool the parser into thinking it is starting a function. */
7063 start_function (decl_specs, method_decl, NULL_TREE);
7065 /* Unhook: this has the effect of restoring the abstract declarator. */
7066 TREE_OPERAND (save_expr, 0) = NULL_TREE;
7071 TREE_VALUE (TREE_TYPE (method)) = method_decl;
7073 /* Fool the parser into thinking it is starting a function. */
7074 start_function (decl_specs, method_decl, NULL_TREE);
7076 /* Unhook: this has the effect of restoring the abstract declarator. */
7077 TREE_VALUE (TREE_TYPE (method)) = NULL_TREE;
7080 METHOD_DEFINITION (method) = current_function_decl;
7082 /* Check consistency...start_function, pushdecl, duplicate_decls. */
7084 if (implementation_template != objc_implementation_context)
7088 if (TREE_CODE (method) == INSTANCE_METHOD_DECL)
7089 proto = lookup_instance_method_static (implementation_template,
7090 METHOD_SEL_NAME (method));
7092 proto = lookup_class_method_static (implementation_template,
7093 METHOD_SEL_NAME (method));
7095 if (proto && ! comp_method_with_proto (method, proto))
7097 char type = (TREE_CODE (method) == INSTANCE_METHOD_DECL ? '-' : '+');
7099 warn_with_method ("conflicting types for", type, method);
7100 warn_with_method ("previous declaration of", type, proto);
7105 /* The following routine is always called...this "architecture" is to
7106 accommodate "old-style" variable length selectors.
7108 - a:a b:b // prototype ; id c; id d; // old-style. */
7111 continue_method_def ()
7115 if (METHOD_ADD_ARGS (objc_method_context) == objc_ellipsis_node)
7116 /* We have a `, ...' immediately following the selector. */
7117 parmlist = get_parm_info (0);
7119 parmlist = get_parm_info (1); /* place a `void_at_end' */
7121 /* Set self_decl from the first argument...this global is used by
7122 build_ivar_reference calling build_indirect_ref. */
7123 self_decl = TREE_PURPOSE (parmlist);
7126 really_start_method (objc_method_context, parmlist);
7127 store_parm_decls ();
7130 /* Called by the parser, from the `pushlevel' production. */
7135 if (!UOBJC_SUPER_decl)
7137 UOBJC_SUPER_decl = start_decl (get_identifier (UTAG_SUPER),
7138 build_tree_list (NULL_TREE,
7139 objc_super_template),
7142 finish_decl (UOBJC_SUPER_decl, NULL_TREE, NULL_TREE);
7144 /* This prevents `unused variable' warnings when compiling with -Wall. */
7145 TREE_USED (UOBJC_SUPER_decl) = 1;
7146 DECL_ARTIFICIAL (UOBJC_SUPER_decl) = 1;
7150 /* _n_Method (id self, SEL sel, ...)
7152 struct objc_super _S;
7153 _msgSuper ((_S.self = self, _S.class = _cls, &_S), ...);
7157 get_super_receiver ()
7159 if (objc_method_context)
7161 tree super_expr, super_expr_list;
7163 /* Set receiver to self. */
7164 super_expr = build_component_ref (UOBJC_SUPER_decl, self_id);
7165 super_expr = build_modify_expr (super_expr, NOP_EXPR, self_decl);
7166 super_expr_list = build_tree_list (NULL_TREE, super_expr);
7168 /* Set class to begin searching. */
7169 super_expr = build_component_ref (UOBJC_SUPER_decl,
7170 get_identifier ("class"));
7172 if (TREE_CODE (objc_implementation_context) == CLASS_IMPLEMENTATION_TYPE)
7174 /* [_cls, __cls]Super are "pre-built" in
7175 synth_forward_declarations. */
7177 super_expr = build_modify_expr (super_expr, NOP_EXPR,
7178 ((TREE_CODE (objc_method_context)
7179 == INSTANCE_METHOD_DECL)
7181 : uucls_super_ref));
7185 /* We have a category. */
7187 tree super_name = CLASS_SUPER_NAME (implementation_template);
7190 /* Barf if super used in a category of Object. */
7193 error ("no super class declared in interface for `%s'",
7194 IDENTIFIER_POINTER (CLASS_NAME (implementation_template)));
7195 return error_mark_node;
7198 if (flag_next_runtime)
7200 super_class = get_class_reference (super_name);
7201 if (TREE_CODE (objc_method_context) == CLASS_METHOD_DECL)
7203 = build_component_ref (build_indirect_ref (super_class, "->"),
7204 get_identifier ("isa"));
7208 add_class_reference (super_name);
7209 super_class = (TREE_CODE (objc_method_context) == INSTANCE_METHOD_DECL
7210 ? objc_get_class_decl : objc_get_meta_class_decl);
7211 assemble_external (super_class);
7213 = build_function_call
7217 my_build_string (IDENTIFIER_LENGTH (super_name) + 1,
7218 IDENTIFIER_POINTER (super_name))));
7221 TREE_TYPE (super_class) = TREE_TYPE (ucls_super_ref);
7222 super_expr = build_modify_expr (super_expr, NOP_EXPR, super_class);
7225 chainon (super_expr_list, build_tree_list (NULL_TREE, super_expr));
7227 super_expr = build_unary_op (ADDR_EXPR, UOBJC_SUPER_decl, 0);
7228 chainon (super_expr_list, build_tree_list (NULL_TREE, super_expr));
7230 return build_compound_expr (super_expr_list);
7234 error ("[super ...] must appear in a method context");
7235 return error_mark_node;
7240 encode_method_def (func_decl)
7245 HOST_WIDE_INT max_parm_end = 0;
7250 encode_type (TREE_TYPE (TREE_TYPE (func_decl)),
7251 obstack_object_size (&util_obstack),
7252 OBJC_ENCODE_INLINE_DEFS);
7255 for (parms = DECL_ARGUMENTS (func_decl); parms;
7256 parms = TREE_CHAIN (parms))
7258 HOST_WIDE_INT parm_end = (forwarding_offset (parms)
7259 + int_size_in_bytes (TREE_TYPE (parms)));
7261 if (! offset_is_register && parm_end > max_parm_end)
7262 max_parm_end = parm_end;
7265 stack_size = max_parm_end - OBJC_FORWARDING_MIN_OFFSET;
7267 sprintf (buffer, "%d", stack_size);
7268 obstack_grow (&util_obstack, buffer, strlen (buffer));
7270 /* Argument types. */
7271 for (parms = DECL_ARGUMENTS (func_decl); parms;
7272 parms = TREE_CHAIN (parms))
7275 encode_type (TREE_TYPE (parms),
7276 obstack_object_size (&util_obstack),
7277 OBJC_ENCODE_INLINE_DEFS);
7279 /* Compute offset. */
7280 sprintf (buffer, "%d", forwarding_offset (parms));
7282 /* Indicate register. */
7283 if (offset_is_register)
7284 obstack_1grow (&util_obstack, '+');
7286 obstack_grow (&util_obstack, buffer, strlen (buffer));
7289 /* Null terminate string. */
7290 obstack_1grow (&util_obstack, 0);
7291 result = get_identifier (obstack_finish (&util_obstack));
7292 obstack_free (&util_obstack, util_firstobj);
7297 objc_expand_function_end ()
7299 METHOD_ENCODING (objc_method_context) = encode_method_def (current_function_decl);
7303 finish_method_def ()
7305 lang_expand_function_end = objc_expand_function_end;
7306 finish_function (0);
7307 lang_expand_function_end = NULL;
7309 /* Required to implement _msgSuper. This must be done AFTER finish_function,
7310 since the optimizer may find "may be used before set" errors. */
7311 objc_method_context = NULL_TREE;
7316 lang_report_error_function (decl)
7319 if (objc_method_context)
7321 fprintf (stderr, "In method `%s'\n",
7322 IDENTIFIER_POINTER (METHOD_SEL_NAME (objc_method_context)));
7332 is_complex_decl (type)
7335 return (TREE_CODE (type) == ARRAY_TYPE
7336 || TREE_CODE (type) == FUNCTION_TYPE
7337 || (TREE_CODE (type) == POINTER_TYPE && ! IS_ID (type)));
7341 /* Code to convert a decl node into text for a declaration in C. */
7343 static char tmpbuf[256];
7346 adorn_decl (decl, str)
7350 enum tree_code code = TREE_CODE (decl);
7352 if (code == ARRAY_REF)
7354 tree an_int_cst = TREE_OPERAND (decl, 1);
7356 if (an_int_cst && TREE_CODE (an_int_cst) == INTEGER_CST)
7357 sprintf (str + strlen (str), "[%ld]",
7358 (long) TREE_INT_CST_LOW (an_int_cst));
7363 else if (code == ARRAY_TYPE)
7365 tree an_int_cst = TYPE_SIZE (decl);
7366 tree array_of = TREE_TYPE (decl);
7368 if (an_int_cst && TREE_CODE (an_int_cst) == INTEGER_TYPE)
7369 sprintf (str + strlen (str), "[%ld]",
7370 (long) (TREE_INT_CST_LOW (an_int_cst)
7371 / TREE_INT_CST_LOW (TYPE_SIZE (array_of))));
7376 else if (code == CALL_EXPR)
7378 tree chain = TREE_PURPOSE (TREE_OPERAND (decl, 1));
7383 gen_declaration_1 (chain, str);
7384 chain = TREE_CHAIN (chain);
7391 else if (code == FUNCTION_TYPE)
7393 tree chain = TYPE_ARG_TYPES (decl);
7396 while (chain && TREE_VALUE (chain) != void_type_node)
7398 gen_declaration_1 (TREE_VALUE (chain), str);
7399 chain = TREE_CHAIN (chain);
7400 if (chain && TREE_VALUE (chain) != void_type_node)
7406 else if (code == INDIRECT_REF)
7408 strcpy (tmpbuf, "*");
7409 if (TREE_TYPE (decl) && TREE_CODE (TREE_TYPE (decl)) == TREE_LIST)
7413 for (chain = nreverse (copy_list (TREE_TYPE (decl)));
7415 chain = TREE_CHAIN (chain))
7417 if (TREE_CODE (TREE_VALUE (chain)) == IDENTIFIER_NODE)
7419 strcat (tmpbuf, " ");
7420 strcat (tmpbuf, IDENTIFIER_POINTER (TREE_VALUE (chain)));
7424 strcat (tmpbuf, " ");
7426 strcat (tmpbuf, str);
7427 strcpy (str, tmpbuf);
7430 else if (code == POINTER_TYPE)
7432 strcpy (tmpbuf, "*");
7433 if (TREE_READONLY (decl) || TYPE_VOLATILE (decl))
7435 if (TREE_READONLY (decl))
7436 strcat (tmpbuf, " const");
7437 if (TYPE_VOLATILE (decl))
7438 strcat (tmpbuf, " volatile");
7440 strcat (tmpbuf, " ");
7442 strcat (tmpbuf, str);
7443 strcpy (str, tmpbuf);
7448 gen_declarator (decl, buf, name)
7455 enum tree_code code = TREE_CODE (decl);
7465 op = TREE_OPERAND (decl, 0);
7467 /* We have a pointer to a function or array...(*)(), (*)[] */
7468 if ((code == ARRAY_REF || code == CALL_EXPR)
7469 && op && TREE_CODE (op) == INDIRECT_REF)
7472 str = gen_declarator (op, buf, name);
7476 strcpy (tmpbuf, "(");
7477 strcat (tmpbuf, str);
7478 strcat (tmpbuf, ")");
7479 strcpy (str, tmpbuf);
7482 adorn_decl (decl, str);
7491 /* This clause is done iteratively rather than recursively. */
7494 op = (is_complex_decl (TREE_TYPE (decl))
7495 ? TREE_TYPE (decl) : NULL_TREE);
7497 adorn_decl (decl, str);
7499 /* We have a pointer to a function or array...(*)(), (*)[] */
7500 if (code == POINTER_TYPE
7501 && op && (TREE_CODE (op) == FUNCTION_TYPE
7502 || TREE_CODE (op) == ARRAY_TYPE))
7504 strcpy (tmpbuf, "(");
7505 strcat (tmpbuf, str);
7506 strcat (tmpbuf, ")");
7507 strcpy (str, tmpbuf);
7510 decl = (is_complex_decl (TREE_TYPE (decl))
7511 ? TREE_TYPE (decl) : NULL_TREE);
7514 while (decl && (code = TREE_CODE (decl)))
7519 case IDENTIFIER_NODE:
7520 /* Will only happen if we are processing a "raw" expr-decl. */
7521 strcpy (buf, IDENTIFIER_POINTER (decl));
7532 /* We have an abstract declarator or a _DECL node. */
7540 gen_declspecs (declspecs, buf, raw)
7549 for (chain = nreverse (copy_list (declspecs));
7550 chain; chain = TREE_CHAIN (chain))
7552 tree aspec = TREE_VALUE (chain);
7554 if (TREE_CODE (aspec) == IDENTIFIER_NODE)
7555 strcat (buf, IDENTIFIER_POINTER (aspec));
7556 else if (TREE_CODE (aspec) == RECORD_TYPE)
7558 if (TYPE_NAME (aspec))
7560 tree protocol_list = TYPE_PROTOCOL_LIST (aspec);
7562 if (! TREE_STATIC_TEMPLATE (aspec))
7563 strcat (buf, "struct ");
7564 strcat (buf, IDENTIFIER_POINTER (TYPE_NAME (aspec)));
7569 tree chain = protocol_list;
7576 (PROTOCOL_NAME (TREE_VALUE (chain))));
7577 chain = TREE_CHAIN (chain);
7586 strcat (buf, "untagged struct");
7589 else if (TREE_CODE (aspec) == UNION_TYPE)
7591 if (TYPE_NAME (aspec))
7593 if (! TREE_STATIC_TEMPLATE (aspec))
7594 strcat (buf, "union ");
7595 strcat (buf, IDENTIFIER_POINTER (TYPE_NAME (aspec)));
7598 strcat (buf, "untagged union");
7601 else if (TREE_CODE (aspec) == ENUMERAL_TYPE)
7603 if (TYPE_NAME (aspec))
7605 if (! TREE_STATIC_TEMPLATE (aspec))
7606 strcat (buf, "enum ");
7607 strcat (buf, IDENTIFIER_POINTER (TYPE_NAME (aspec)));
7610 strcat (buf, "untagged enum");
7613 else if (TREE_CODE (aspec) == TYPE_DECL && DECL_NAME (aspec))
7614 strcat (buf, IDENTIFIER_POINTER (DECL_NAME (aspec)));
7616 else if (IS_ID (aspec))
7618 tree protocol_list = TYPE_PROTOCOL_LIST (aspec);
7623 tree chain = protocol_list;
7630 (PROTOCOL_NAME (TREE_VALUE (chain))));
7631 chain = TREE_CHAIN (chain);
7638 if (TREE_CHAIN (chain))
7644 /* Type qualifiers. */
7645 if (TREE_READONLY (declspecs))
7646 strcat (buf, "const ");
7647 if (TYPE_VOLATILE (declspecs))
7648 strcat (buf, "volatile ");
7650 switch (TREE_CODE (declspecs))
7652 /* Type specifiers. */
7655 declspecs = TYPE_MAIN_VARIANT (declspecs);
7657 /* Signed integer types. */
7659 if (declspecs == short_integer_type_node)
7660 strcat (buf, "short int ");
7661 else if (declspecs == integer_type_node)
7662 strcat (buf, "int ");
7663 else if (declspecs == long_integer_type_node)
7664 strcat (buf, "long int ");
7665 else if (declspecs == long_long_integer_type_node)
7666 strcat (buf, "long long int ");
7667 else if (declspecs == signed_char_type_node
7668 || declspecs == char_type_node)
7669 strcat (buf, "char ");
7671 /* Unsigned integer types. */
7673 else if (declspecs == short_unsigned_type_node)
7674 strcat (buf, "unsigned short ");
7675 else if (declspecs == unsigned_type_node)
7676 strcat (buf, "unsigned int ");
7677 else if (declspecs == long_unsigned_type_node)
7678 strcat (buf, "unsigned long ");
7679 else if (declspecs == long_long_unsigned_type_node)
7680 strcat (buf, "unsigned long long ");
7681 else if (declspecs == unsigned_char_type_node)
7682 strcat (buf, "unsigned char ");
7686 declspecs = TYPE_MAIN_VARIANT (declspecs);
7688 if (declspecs == float_type_node)
7689 strcat (buf, "float ");
7690 else if (declspecs == double_type_node)
7691 strcat (buf, "double ");
7692 else if (declspecs == long_double_type_node)
7693 strcat (buf, "long double ");
7697 if (TYPE_NAME (declspecs)
7698 && TREE_CODE (TYPE_NAME (declspecs)) == IDENTIFIER_NODE)
7700 tree protocol_list = TYPE_PROTOCOL_LIST (declspecs);
7702 if (! TREE_STATIC_TEMPLATE (declspecs))
7703 strcat (buf, "struct ");
7704 strcat (buf, IDENTIFIER_POINTER (TYPE_NAME (declspecs)));
7708 tree chain = protocol_list;
7715 (PROTOCOL_NAME (TREE_VALUE (chain))));
7716 chain = TREE_CHAIN (chain);
7725 strcat (buf, "untagged struct");
7731 if (TYPE_NAME (declspecs)
7732 && TREE_CODE (TYPE_NAME (declspecs)) == IDENTIFIER_NODE)
7734 strcat (buf, "union ");
7735 strcat (buf, IDENTIFIER_POINTER (TYPE_NAME (declspecs)));
7740 strcat (buf, "untagged union ");
7744 if (TYPE_NAME (declspecs)
7745 && TREE_CODE (TYPE_NAME (declspecs)) == IDENTIFIER_NODE)
7747 strcat (buf, "enum ");
7748 strcat (buf, IDENTIFIER_POINTER (TYPE_NAME (declspecs)));
7753 strcat (buf, "untagged enum ");
7757 strcat (buf, "void ");
7762 tree protocol_list = TYPE_PROTOCOL_LIST (declspecs);
7767 tree chain = protocol_list;
7774 (PROTOCOL_NAME (TREE_VALUE (chain))));
7775 chain = TREE_CHAIN (chain);
7791 /* Given a tree node, produce a printable description of it in the given
7792 buffer, overwriting the buffer. */
7795 gen_declaration (atype_or_adecl, buf)
7796 tree atype_or_adecl;
7800 gen_declaration_1 (atype_or_adecl, buf);
7804 /* Given a tree node, append a printable description to the end of the
7808 gen_declaration_1 (atype_or_adecl, buf)
7809 tree atype_or_adecl;
7814 if (TREE_CODE (atype_or_adecl) == TREE_LIST)
7816 tree declspecs; /* "identifier_node", "record_type" */
7817 tree declarator; /* "array_ref", "indirect_ref", "call_expr"... */
7819 /* We have a "raw", abstract declarator (typename). */
7820 declarator = TREE_VALUE (atype_or_adecl);
7821 declspecs = TREE_PURPOSE (atype_or_adecl);
7823 gen_declspecs (declspecs, buf, 1);
7827 strcat (buf, gen_declarator (declarator, declbuf, ""));
7834 tree declspecs; /* "integer_type", "real_type", "record_type"... */
7835 tree declarator; /* "array_type", "function_type", "pointer_type". */
7837 if (TREE_CODE (atype_or_adecl) == FIELD_DECL
7838 || TREE_CODE (atype_or_adecl) == PARM_DECL
7839 || TREE_CODE (atype_or_adecl) == FUNCTION_DECL)
7840 atype = TREE_TYPE (atype_or_adecl);
7842 /* Assume we have a *_type node. */
7843 atype = atype_or_adecl;
7845 if (is_complex_decl (atype))
7849 /* Get the declaration specifier; it is at the end of the list. */
7850 declarator = chain = atype;
7852 chain = TREE_TYPE (chain); /* not TREE_CHAIN (chain); */
7853 while (is_complex_decl (chain));
7860 declarator = NULL_TREE;
7863 gen_declspecs (declspecs, buf, 0);
7865 if (TREE_CODE (atype_or_adecl) == FIELD_DECL
7866 || TREE_CODE (atype_or_adecl) == PARM_DECL
7867 || TREE_CODE (atype_or_adecl) == FUNCTION_DECL)
7869 const char *const decl_name =
7870 (DECL_NAME (atype_or_adecl)
7871 ? IDENTIFIER_POINTER (DECL_NAME (atype_or_adecl)) : "");
7876 strcat (buf, gen_declarator (declarator, declbuf, decl_name));
7879 else if (decl_name[0])
7882 strcat (buf, decl_name);
7885 else if (declarator)
7888 strcat (buf, gen_declarator (declarator, declbuf, ""));
7893 #define RAW_TYPESPEC(meth) (TREE_VALUE (TREE_PURPOSE (TREE_TYPE (meth))))
7895 /* Given a method tree, put a printable description into the given
7896 buffer (overwriting) and return a pointer to the buffer. */
7899 gen_method_decl (method, buf)
7906 if (RAW_TYPESPEC (method) != objc_object_reference)
7909 gen_declaration_1 (TREE_TYPE (method), buf);
7913 chain = METHOD_SEL_ARGS (method);
7916 /* We have a chain of keyword_decls. */
7919 if (KEYWORD_KEY_NAME (chain))
7920 strcat (buf, IDENTIFIER_POINTER (KEYWORD_KEY_NAME (chain)));
7923 if (RAW_TYPESPEC (chain) != objc_object_reference)
7926 gen_declaration_1 (TREE_TYPE (chain), buf);
7930 strcat (buf, IDENTIFIER_POINTER (KEYWORD_ARG_NAME (chain)));
7931 if ((chain = TREE_CHAIN (chain)))
7936 if (METHOD_ADD_ARGS (method) == objc_ellipsis_node)
7937 strcat (buf, ", ...");
7938 else if (METHOD_ADD_ARGS (method))
7940 /* We have a tree list node as generate by get_parm_info. */
7941 chain = TREE_PURPOSE (METHOD_ADD_ARGS (method));
7943 /* Know we have a chain of parm_decls. */
7947 gen_declaration_1 (chain, buf);
7948 chain = TREE_CHAIN (chain);
7954 /* We have a unary selector. */
7955 strcat (buf, IDENTIFIER_POINTER (METHOD_SEL_NAME (method)));
7963 dump_interface (fp, chain)
7967 char *buf = (char *) xmalloc (256);
7968 const char *my_name = IDENTIFIER_POINTER (CLASS_NAME (chain));
7969 tree ivar_decls = CLASS_RAW_IVARS (chain);
7970 tree nst_methods = CLASS_NST_METHODS (chain);
7971 tree cls_methods = CLASS_CLS_METHODS (chain);
7973 fprintf (fp, "\n@interface %s", my_name);
7975 if (CLASS_SUPER_NAME (chain))
7977 const char *super_name = IDENTIFIER_POINTER (CLASS_SUPER_NAME (chain));
7978 fprintf (fp, " : %s\n", super_name);
7985 fprintf (fp, "{\n");
7988 fprintf (fp, "\t%s;\n", gen_declaration (ivar_decls, buf));
7989 ivar_decls = TREE_CHAIN (ivar_decls);
7992 fprintf (fp, "}\n");
7997 fprintf (fp, "- %s;\n", gen_method_decl (nst_methods, buf));
7998 nst_methods = TREE_CHAIN (nst_methods);
8003 fprintf (fp, "+ %s;\n", gen_method_decl (cls_methods, buf));
8004 cls_methods = TREE_CHAIN (cls_methods);
8006 fprintf (fp, "\n@end");
8009 /* Demangle function for Objective-C */
8011 objc_demangle (mangled)
8012 const char *mangled;
8014 char *demangled, *cp;
8016 if (mangled[0] == '_' &&
8017 (mangled[1] == 'i' || mangled[1] == 'c') &&
8020 cp = demangled = xmalloc(strlen(mangled) + 2);
8021 if (mangled[1] == 'i')
8022 *cp++ = '-'; /* for instance method */
8024 *cp++ = '+'; /* for class method */
8025 *cp++ = '['; /* opening left brace */
8026 strcpy(cp, mangled+3); /* tack on the rest of the mangled name */
8027 while (*cp && *cp == '_')
8028 cp++; /* skip any initial underbars in class name */
8029 cp = strchr(cp, '_'); /* find first non-initial underbar */
8032 free(demangled); /* not mangled name */
8035 if (cp[1] == '_') /* easy case: no category name */
8037 *cp++ = ' '; /* replace two '_' with one ' ' */
8038 strcpy(cp, mangled + (cp - demangled) + 2);
8042 *cp++ = '('; /* less easy case: category name */
8043 cp = strchr(cp, '_');
8046 free(demangled); /* not mangled name */
8050 *cp++ = ' '; /* overwriting 1st char of method name... */
8051 strcpy(cp, mangled + (cp - demangled)); /* get it back */
8053 while (*cp && *cp == '_')
8054 cp++; /* skip any initial underbars in method name */
8057 *cp = ':'; /* replace remaining '_' with ':' */
8058 *cp++ = ']'; /* closing right brace */
8059 *cp++ = 0; /* string terminator */
8063 return mangled; /* not an objc mangled name */
8067 objc_printable_name (decl, kind)
8069 int kind ATTRIBUTE_UNUSED;
8071 return objc_demangle (IDENTIFIER_POINTER (DECL_NAME (decl)));
8074 /* Adds the tree codes specific to the ObjC/ObjC++ front end to the
8075 list of all tree codes. */
8078 add_objc_tree_codes ()
8080 int add = (int) LAST_OBJC_TREE_CODE - (int) LAST_BASE_TREE_CODE;
8082 memcpy (tree_code_type + (int) LAST_BASE_TREE_CODE,
8083 objc_tree_code_type, add);
8084 memcpy (tree_code_length + (int) LAST_BASE_TREE_CODE,
8085 objc_tree_code_length, add * sizeof (int));
8086 memcpy (tree_code_name + (int) LAST_BASE_TREE_CODE,
8087 objc_tree_code_name, add * sizeof (char *));
8093 gcc_obstack_init (&util_obstack);
8094 util_firstobj = (char *) obstack_finish (&util_obstack);
8096 errbuf = (char *) xmalloc (BUFSIZE);
8098 synth_module_prologue ();
8104 struct imp_entry *impent;
8106 /* The internally generated initializers appear to have missing braces.
8107 Don't warn about this. */
8108 int save_warn_missing_braces = warn_missing_braces;
8109 warn_missing_braces = 0;
8111 /* A missing @end may not be detected by the parser. */
8112 if (objc_implementation_context)
8114 warning ("`@end' missing in implementation context");
8115 finish_class (objc_implementation_context);
8116 objc_ivar_chain = NULL_TREE;
8117 objc_implementation_context = NULL_TREE;
8120 generate_forward_declaration_to_string_table ();
8122 #ifdef OBJC_PROLOGUE
8126 /* Process the static instances here because initialization of objc_symtab
8128 if (objc_static_instances)
8129 generate_static_references ();
8131 if (imp_list || class_names_chain
8132 || meth_var_names_chain || meth_var_types_chain || sel_ref_chain)
8133 generate_objc_symtab_decl ();
8135 for (impent = imp_list; impent; impent = impent->next)
8137 objc_implementation_context = impent->imp_context;
8138 implementation_template = impent->imp_template;
8140 UOBJC_CLASS_decl = impent->class_decl;
8141 UOBJC_METACLASS_decl = impent->meta_decl;
8143 if (TREE_CODE (objc_implementation_context) == CLASS_IMPLEMENTATION_TYPE)
8145 /* all of the following reference the string pool... */
8146 generate_ivar_lists ();
8147 generate_dispatch_tables ();
8148 generate_shared_structures ();
8152 generate_dispatch_tables ();
8153 generate_category (objc_implementation_context);
8157 /* If we are using an array of selectors, we must always
8158 finish up the array decl even if no selectors were used. */
8159 if (! flag_next_runtime || sel_ref_chain)
8160 build_selector_translation_table ();
8163 generate_protocols ();
8165 if (objc_implementation_context || class_names_chain || objc_static_instances
8166 || meth_var_names_chain || meth_var_types_chain || sel_ref_chain)
8168 /* Arrange for ObjC data structures to be initialized at run time. */
8169 rtx init_sym = build_module_descriptor ();
8170 if (init_sym && targetm.have_ctors_dtors)
8171 (* targetm.asm_out.constructor) (init_sym, DEFAULT_INIT_PRIORITY);
8174 /* Dump the class references. This forces the appropriate classes
8175 to be linked into the executable image, preserving unix archive
8176 semantics. This can be removed when we move to a more dynamically
8177 linked environment. */
8179 for (chain = cls_ref_chain; chain; chain = TREE_CHAIN (chain))
8181 handle_class_ref (chain);
8182 if (TREE_PURPOSE (chain))
8183 generate_classref_translation_entry (chain);
8186 for (impent = imp_list; impent; impent = impent->next)
8187 handle_impent (impent);
8189 /* Dump the string table last. */
8191 generate_strings ();
8193 if (flag_gen_declaration)
8195 add_class (objc_implementation_context);
8196 dump_interface (gen_declaration_file, objc_implementation_context);
8204 /* Run through the selector hash tables and print a warning for any
8205 selector which has multiple methods. */
8207 for (slot = 0; slot < SIZEHASHTABLE; slot++)
8208 for (hsh = cls_method_hash_list[slot]; hsh; hsh = hsh->next)
8211 tree meth = hsh->key;
8212 char type = (TREE_CODE (meth) == INSTANCE_METHOD_DECL
8216 warning ("potential selector conflict for method `%s'",
8217 IDENTIFIER_POINTER (METHOD_SEL_NAME (meth)));
8218 warn_with_method ("found", type, meth);
8219 for (loop = hsh->list; loop; loop = loop->next)
8220 warn_with_method ("found", type, loop->value);
8223 for (slot = 0; slot < SIZEHASHTABLE; slot++)
8224 for (hsh = nst_method_hash_list[slot]; hsh; hsh = hsh->next)
8227 tree meth = hsh->key;
8228 char type = (TREE_CODE (meth) == INSTANCE_METHOD_DECL
8232 warning ("potential selector conflict for method `%s'",
8233 IDENTIFIER_POINTER (METHOD_SEL_NAME (meth)));
8234 warn_with_method ("found", type, meth);
8235 for (loop = hsh->list; loop; loop = loop->next)
8236 warn_with_method ("found", type, loop->value);
8240 warn_missing_braces = save_warn_missing_braces;
8243 /* Subroutines of finish_objc. */
8246 generate_classref_translation_entry (chain)
8249 tree expr, name, decl_specs, decl, sc_spec;
8252 type = TREE_TYPE (TREE_PURPOSE (chain));
8254 expr = add_objc_string (TREE_VALUE (chain), class_names);
8255 expr = build_c_cast (type, expr); /* cast! */
8257 name = DECL_NAME (TREE_PURPOSE (chain));
8259 sc_spec = build_tree_list (NULL_TREE, ridpointers[(int) RID_STATIC]);
8261 /* static struct objc_class * _OBJC_CLASS_REFERENCES_n = ...; */
8262 decl_specs = tree_cons (NULL_TREE, type, sc_spec);
8264 /* The decl that is returned from start_decl is the one that we
8265 forward declared in build_class_reference. */
8266 decl = start_decl (name, decl_specs, 1, NULL_TREE);
8267 DECL_CONTEXT (decl) = NULL_TREE;
8268 finish_decl (decl, expr, NULL_TREE);
8273 handle_class_ref (chain)
8276 const char *name = IDENTIFIER_POINTER (TREE_VALUE (chain));
8277 char *string = (char *) alloca (strlen (name) + 30);
8281 sprintf (string, "%sobjc_class_name_%s",
8282 (flag_next_runtime ? "." : "__"), name);
8284 #ifdef ASM_DECLARE_UNRESOLVED_REFERENCE
8285 if (flag_next_runtime)
8287 ASM_DECLARE_UNRESOLVED_REFERENCE (asm_out_file, string);
8292 /* Make a decl for this name, so we can use its address in a tree. */
8293 decl = build_decl (VAR_DECL, get_identifier (string), char_type_node);
8294 DECL_EXTERNAL (decl) = 1;
8295 TREE_PUBLIC (decl) = 1;
8298 rest_of_decl_compilation (decl, 0, 0, 0);
8300 /* Make a decl for the address. */
8301 sprintf (string, "%sobjc_class_ref_%s",
8302 (flag_next_runtime ? "." : "__"), name);
8303 exp = build1 (ADDR_EXPR, string_type_node, decl);
8304 decl = build_decl (VAR_DECL, get_identifier (string), string_type_node);
8305 DECL_INITIAL (decl) = exp;
8306 TREE_STATIC (decl) = 1;
8309 rest_of_decl_compilation (decl, 0, 0, 0);
8313 handle_impent (impent)
8314 struct imp_entry *impent;
8318 objc_implementation_context = impent->imp_context;
8319 implementation_template = impent->imp_template;
8321 if (TREE_CODE (impent->imp_context) == CLASS_IMPLEMENTATION_TYPE)
8323 const char *const class_name =
8324 IDENTIFIER_POINTER (CLASS_NAME (impent->imp_context));
8326 string = (char *) alloca (strlen (class_name) + 30);
8328 sprintf (string, "*%sobjc_class_name_%s",
8329 (flag_next_runtime ? "." : "__"), class_name);
8331 else if (TREE_CODE (impent->imp_context) == CATEGORY_IMPLEMENTATION_TYPE)
8333 const char *const class_name =
8334 IDENTIFIER_POINTER (CLASS_NAME (impent->imp_context));
8335 const char *const class_super_name =
8336 IDENTIFIER_POINTER (CLASS_SUPER_NAME (impent->imp_context));
8338 string = (char *) alloca (strlen (class_name)
8339 + strlen (class_super_name) + 30);
8341 /* Do the same for categories. Even though no references to
8342 these symbols are generated automatically by the compiler, it
8343 gives you a handle to pull them into an archive by hand. */
8344 sprintf (string, "*%sobjc_category_name_%s_%s",
8345 (flag_next_runtime ? "." : "__"), class_name, class_super_name);
8350 #ifdef ASM_DECLARE_CLASS_REFERENCE
8351 if (flag_next_runtime)
8353 ASM_DECLARE_CLASS_REFERENCE (asm_out_file, string);
8358 /* (Should this be a routine in varasm.c?) */
8359 readonly_data_section ();
8360 assemble_global (string);
8361 assemble_align (UNITS_PER_WORD);
8362 assemble_label (string);
8363 assemble_zeros (UNITS_PER_WORD);
8367 ggc_mark_imp_list (arg)
8370 struct imp_entry *impent;
8372 for (impent = *(struct imp_entry **)arg; impent; impent = impent->next)
8374 ggc_mark_tree (impent->imp_context);
8375 ggc_mark_tree (impent->imp_template);
8376 ggc_mark_tree (impent->class_decl);
8377 ggc_mark_tree (impent->meta_decl);
8382 ggc_mark_hash_table (arg)
8385 hash *hash_table = *(hash **)arg;
8390 if (hash_table == NULL)
8392 for (i = 0; i < SIZEHASHTABLE; i++)
8393 for (hst = hash_table [i]; hst; hst = hst->next)
8395 ggc_mark_tree (hst->key);
8396 for (list = hst->list; list; list = list->next)
8397 ggc_mark_tree (list->value);
8401 /* Add GC roots for variables local to this file. */
8403 objc_act_parse_init ()
8405 ggc_add_tree_root (objc_global_trees, OCTI_MAX);
8406 ggc_add_root (&imp_list, 1, sizeof imp_list, ggc_mark_imp_list);
8407 ggc_add_root (&nst_method_hash_list, 1, sizeof nst_method_hash_list, ggc_mark_hash_table);
8408 ggc_add_root (&cls_method_hash_list, 1, sizeof cls_method_hash_list, ggc_mark_hash_table);
8411 /* Look up ID as an instance variable. */
8413 lookup_objc_ivar (id)
8418 if (objc_receiver_context && !strcmp (IDENTIFIER_POINTER (id), "super"))
8419 /* we have a message to super */
8420 return get_super_receiver ();
8421 else if (objc_method_context && (decl = is_ivar (objc_ivar_chain, id)))
8423 if (is_private (decl))
8424 return error_mark_node;
8426 return build_ivar_reference (id);