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 #ifdef NEXT_OBJC_RUNTIME
367 #define STRING_OBJECT_CLASS_NAME "NSConstantString"
369 #define STRING_OBJECT_CLASS_NAME "NXConstantString"
371 /* Note that the string object global name is only needed for the
373 #define STRING_OBJECT_GLOBAL_NAME "_NSConstantStringClassReference"
375 #define PROTOCOL_OBJECT_CLASS_NAME "Protocol"
377 static const char *constant_string_class_name = NULL;
379 static const char *TAG_GETCLASS;
380 static const char *TAG_GETMETACLASS;
381 static const char *TAG_MSGSEND;
382 static const char *TAG_MSGSENDSUPER;
383 static const char *TAG_EXECCLASS;
385 /* The OCTI_... enumeration itself is in objc/objc-act.h. */
386 tree objc_global_trees[OCTI_MAX];
388 int objc_receiver_context;
390 static void handle_impent PARAMS ((struct imp_entry *));
392 struct imp_entry *imp_list = 0;
393 int imp_count = 0; /* `@implementation' */
394 int cat_count = 0; /* `@category' */
396 static int method_slot = 0; /* Used by start_method_def, */
400 static char *errbuf; /* Buffer for error diagnostics */
402 /* Data imported from tree.c. */
404 extern enum debug_info_type write_symbols;
406 /* Data imported from toplev.c. */
408 extern const char *dump_base_name;
410 /* Generate code for GNU or NeXT runtime environment. */
412 #ifdef NEXT_OBJC_RUNTIME
413 int flag_next_runtime = 1;
415 int flag_next_runtime = 0;
418 int flag_typed_selectors;
420 /* Open and close the file for outputting class declarations, if requested. */
422 int flag_gen_declaration = 0;
424 FILE *gen_declaration_file;
426 /* Warn if multiple methods are seen for the same selector, but with
427 different argument types. */
429 int warn_selector = 0;
431 /* Warn if methods required by a protocol are not implemented in the
432 class adopting it. When turned off, methods inherited to that
433 class are also considered implemented */
435 int flag_warn_protocol = 1;
437 /* Tells "encode_pointer/encode_aggregate" whether we are generating
438 type descriptors for instance variables (as opposed to methods).
439 Type descriptors for instance variables contain more information
440 than methods (for static typing and embedded structures). */
442 static int generating_instance_variables = 0;
444 /* Tells the compiler that this is a special run. Do not perform any
445 compiling, instead we are to test some platform dependent features
446 and output a C header file with appropriate definitions. */
448 static int print_struct_values = 0;
450 /* Some platforms pass small structures through registers versus
451 through an invisible pointer. Determine at what size structure is
452 the transition point between the two possibilities. */
455 generate_struct_by_value_array ()
458 tree field_decl, field_decl_chain;
460 int aggregate_in_mem[32];
463 /* Presumably no platform passes 32 byte structures in a register. */
464 for (i = 1; i < 32; i++)
468 /* Create an unnamed struct that has `i' character components */
469 type = start_struct (RECORD_TYPE, NULL_TREE);
471 strcpy (buffer, "c1");
472 field_decl = create_builtin_decl (FIELD_DECL,
475 field_decl_chain = field_decl;
477 for (j = 1; j < i; j++)
479 sprintf (buffer, "c%d", j + 1);
480 field_decl = create_builtin_decl (FIELD_DECL,
483 chainon (field_decl_chain, field_decl);
485 finish_struct (type, field_decl_chain, NULL_TREE);
487 aggregate_in_mem[i] = aggregate_value_p (type);
488 if (!aggregate_in_mem[i])
492 /* We found some structures that are returned in registers instead of memory
493 so output the necessary data. */
496 for (i = 31; i >= 0; i--)
497 if (!aggregate_in_mem[i])
499 printf ("#define OBJC_MAX_STRUCT_BY_VALUE %d\n\n", i);
501 /* The first member of the structure is always 0 because we don't handle
502 structures with 0 members */
503 printf ("static int struct_forward_array[] = {\n 0");
505 for (j = 1; j <= i; j++)
506 printf (", %d", aggregate_in_mem[j]);
515 const char *filename;
517 filename = c_objc_common_init (filename);
518 add_objc_tree_codes ();
520 decl_printable_name = objc_printable_name;
522 /* Force the line number back to 0; check_newline will have
523 raised it to 1, which will make the builtin functions appear
524 not to be built in. */
527 /* If gen_declaration desired, open the output file. */
528 if (flag_gen_declaration)
530 register char * const dumpname = concat (dump_base_name, ".decl", NULL);
531 gen_declaration_file = fopen (dumpname, "w");
532 if (gen_declaration_file == 0)
533 fatal_io_error ("can't open %s", dumpname);
537 if (flag_next_runtime)
539 TAG_GETCLASS = "objc_getClass";
540 TAG_GETMETACLASS = "objc_getMetaClass";
541 TAG_MSGSEND = "objc_msgSend";
542 TAG_MSGSENDSUPER = "objc_msgSendSuper";
543 TAG_EXECCLASS = "__objc_execClass";
547 TAG_GETCLASS = "objc_get_class";
548 TAG_GETMETACLASS = "objc_get_meta_class";
549 TAG_MSGSEND = "objc_msg_lookup";
550 TAG_MSGSENDSUPER = "objc_msg_lookup_super";
551 TAG_EXECCLASS = "__objc_exec_class";
552 flag_typed_selectors = 1;
555 objc_ellipsis_node = make_node (ERROR_MARK);
559 if (print_struct_values)
560 generate_struct_by_value_array ();
562 objc_act_parse_init ();
570 c_objc_common_finish_file ();
572 finish_objc (); /* Objective-C finalization */
574 if (gen_declaration_file)
575 fclose (gen_declaration_file);
579 objc_decode_option (argc, argv)
583 const char *p = argv[0];
585 if (!strcmp (p, "-gen-decls"))
586 flag_gen_declaration = 1;
587 else if (!strcmp (p, "-Wselector"))
589 else if (!strcmp (p, "-Wno-selector"))
591 else if (!strcmp (p, "-Wprotocol"))
592 flag_warn_protocol = 1;
593 else if (!strcmp (p, "-Wno-protocol"))
594 flag_warn_protocol = 0;
595 else if (!strcmp (p, "-fgnu-runtime"))
596 flag_next_runtime = 0;
597 else if (!strcmp (p, "-fno-next-runtime"))
598 flag_next_runtime = 0;
599 else if (!strcmp (p, "-fno-gnu-runtime"))
600 flag_next_runtime = 1;
601 else if (!strcmp (p, "-fnext-runtime"))
602 flag_next_runtime = 1;
603 else if (!strcmp (p, "-print-objc-runtime-info"))
604 print_struct_values = 1;
605 #define CSTSTRCLASS "-fconstant-string-class="
606 else if (!strncmp (p, CSTSTRCLASS, sizeof(CSTSTRCLASS) - 2)) {
607 if (strlen (argv[0]) <= strlen (CSTSTRCLASS))
608 error ("no class name specified as argument to -fconstant-string-class");
609 constant_string_class_name = xstrdup(argv[0] + sizeof(CSTSTRCLASS) - 1);
613 return c_decode_option (argc, argv);
620 define_decl (declarator, declspecs)
624 tree decl = start_decl (declarator, declspecs, 0, NULL_TREE);
625 finish_decl (decl, NULL_TREE, NULL_TREE);
629 /* Return 1 if LHS and RHS are compatible types for assignment or
630 various other operations. Return 0 if they are incompatible, and
631 return -1 if we choose to not decide. When the operation is
632 REFLEXIVE, check for compatibility in either direction.
634 For statically typed objects, an assignment of the form `a' = `b'
638 `a' and `b' are the same class type, or
639 `a' and `b' are of class types A and B such that B is a descendant of A. */
642 maybe_objc_comptypes (lhs, rhs, reflexive)
646 return objc_comptypes (lhs, rhs, reflexive);
650 lookup_method_in_protocol_list (rproto_list, sel_name, class_meth)
658 for (rproto = rproto_list; rproto; rproto = TREE_CHAIN (rproto))
660 p = TREE_VALUE (rproto);
662 if (TREE_CODE (p) == PROTOCOL_INTERFACE_TYPE)
664 if ((fnd = lookup_method (class_meth
665 ? PROTOCOL_CLS_METHODS (p)
666 : PROTOCOL_NST_METHODS (p), sel_name)))
668 else if (PROTOCOL_LIST (p))
669 fnd = lookup_method_in_protocol_list (PROTOCOL_LIST (p),
670 sel_name, class_meth);
674 ; /* An identifier...if we could not find a protocol. */
685 lookup_protocol_in_reflist (rproto_list, lproto)
691 /* Make sure the protocol is supported by the object on the rhs. */
692 if (TREE_CODE (lproto) == PROTOCOL_INTERFACE_TYPE)
695 for (rproto = rproto_list; rproto; rproto = TREE_CHAIN (rproto))
697 p = TREE_VALUE (rproto);
699 if (TREE_CODE (p) == PROTOCOL_INTERFACE_TYPE)
704 else if (PROTOCOL_LIST (p))
705 fnd = lookup_protocol_in_reflist (PROTOCOL_LIST (p), lproto);
714 ; /* An identifier...if we could not find a protocol. */
720 /* Return 1 if LHS and RHS are compatible types for assignment
721 or various other operations. Return 0 if they are incompatible,
722 and return -1 if we choose to not decide. When the operation
723 is REFLEXIVE, check for compatibility in either direction. */
726 objc_comptypes (lhs, rhs, reflexive)
731 /* New clause for protocols. */
733 if (TREE_CODE (lhs) == POINTER_TYPE
734 && TREE_CODE (TREE_TYPE (lhs)) == RECORD_TYPE
735 && TREE_CODE (rhs) == POINTER_TYPE
736 && TREE_CODE (TREE_TYPE (rhs)) == RECORD_TYPE)
738 int lhs_is_proto = IS_PROTOCOL_QUALIFIED_ID (lhs);
739 int rhs_is_proto = IS_PROTOCOL_QUALIFIED_ID (rhs);
743 tree lproto, lproto_list = TYPE_PROTOCOL_LIST (lhs);
744 tree rproto, rproto_list;
749 rproto_list = TYPE_PROTOCOL_LIST (rhs);
751 /* Make sure the protocol is supported by the object
753 for (lproto = lproto_list; lproto; lproto = TREE_CHAIN (lproto))
755 p = TREE_VALUE (lproto);
756 rproto = lookup_protocol_in_reflist (rproto_list, p);
759 warning ("object does not conform to the `%s' protocol",
760 IDENTIFIER_POINTER (PROTOCOL_NAME (p)));
763 else if (TYPED_OBJECT (TREE_TYPE (rhs)))
765 tree rname = TYPE_NAME (TREE_TYPE (rhs));
768 /* Make sure the protocol is supported by the object
770 for (lproto = lproto_list; lproto; lproto = TREE_CHAIN (lproto))
772 p = TREE_VALUE (lproto);
774 rinter = lookup_interface (rname);
776 while (rinter && !rproto)
780 rproto_list = CLASS_PROTOCOL_LIST (rinter);
781 /* If the underlying ObjC class does not have
782 protocols attached to it, perhaps there are
783 "one-off" protocols attached to the rhs?
784 E.g., 'id<MyProt> foo;'. */
786 rproto_list = TYPE_PROTOCOL_LIST (TREE_TYPE (rhs));
787 rproto = lookup_protocol_in_reflist (rproto_list, p);
789 /* Check for protocols adopted by categories. */
790 cat = CLASS_CATEGORY_LIST (rinter);
791 while (cat && !rproto)
793 rproto_list = CLASS_PROTOCOL_LIST (cat);
794 rproto = lookup_protocol_in_reflist (rproto_list, p);
796 cat = CLASS_CATEGORY_LIST (cat);
799 rinter = lookup_interface (CLASS_SUPER_NAME (rinter));
803 warning ("class `%s' does not implement the `%s' protocol",
804 IDENTIFIER_POINTER (TYPE_NAME (TREE_TYPE (rhs))),
805 IDENTIFIER_POINTER (PROTOCOL_NAME (p)));
809 /* May change...based on whether there was any mismatch */
812 else if (rhs_is_proto)
813 /* Lhs is not a protocol...warn if it is statically typed */
814 return (TYPED_OBJECT (TREE_TYPE (lhs)) != 0);
817 /* Defer to comptypes. */
821 else if (TREE_CODE (lhs) == RECORD_TYPE && TREE_CODE (rhs) == RECORD_TYPE)
822 ; /* Fall thru. This is the case we have been handling all along */
824 /* Defer to comptypes. */
827 /* `id' = `<class> *', `<class> *' = `id' */
829 if ((TYPE_NAME (lhs) == objc_object_id && TYPED_OBJECT (rhs))
830 || (TYPE_NAME (rhs) == objc_object_id && TYPED_OBJECT (lhs)))
833 /* `id' = `Class', `Class' = `id' */
835 else if ((TYPE_NAME (lhs) == objc_object_id
836 && TYPE_NAME (rhs) == objc_class_id)
837 || (TYPE_NAME (lhs) == objc_class_id
838 && TYPE_NAME (rhs) == objc_object_id))
841 /* `<class> *' = `<class> *' */
843 else if (TYPED_OBJECT (lhs) && TYPED_OBJECT (rhs))
845 tree lname = TYPE_NAME (lhs);
846 tree rname = TYPE_NAME (rhs);
852 /* If the left hand side is a super class of the right hand side,
854 for (inter = lookup_interface (rname); inter;
855 inter = lookup_interface (CLASS_SUPER_NAME (inter)))
856 if (lname == CLASS_SUPER_NAME (inter))
859 /* Allow the reverse when reflexive. */
861 for (inter = lookup_interface (lname); inter;
862 inter = lookup_interface (CLASS_SUPER_NAME (inter)))
863 if (rname == CLASS_SUPER_NAME (inter))
869 /* Defer to comptypes. */
873 /* Called from c-decl.c before all calls to rest_of_decl_compilation. */
876 objc_check_decl (decl)
879 tree type = TREE_TYPE (decl);
881 if (TREE_CODE (type) == RECORD_TYPE
882 && TREE_STATIC_TEMPLATE (type)
883 && type != constant_string_type)
884 error_with_decl (decl, "`%s' cannot be statically allocated");
888 maybe_objc_check_decl (decl)
891 objc_check_decl (decl);
894 /* Implement static typing. At this point, we know we have an interface. */
897 get_static_reference (interface, protocols)
901 tree type = xref_tag (RECORD_TYPE, interface);
905 tree t, m = TYPE_MAIN_VARIANT (type);
907 t = copy_node (type);
908 TYPE_BINFO (t) = make_tree_vec (2);
910 /* Add this type to the chain of variants of TYPE. */
911 TYPE_NEXT_VARIANT (t) = TYPE_NEXT_VARIANT (m);
912 TYPE_NEXT_VARIANT (m) = t;
914 /* Look up protocols and install in lang specific list. Note
915 that the protocol list can have a different lifetime than T! */
916 TYPE_PROTOCOL_LIST (t) = lookup_and_install_protocols (protocols);
918 /* This forces a new pointer type to be created later
919 (in build_pointer_type)...so that the new template
920 we just created will actually be used...what a hack! */
921 if (TYPE_POINTER_TO (t))
922 TYPE_POINTER_TO (t) = NULL_TREE;
931 get_object_reference (protocols)
934 tree type_decl = lookup_name (objc_id_id);
937 if (type_decl && TREE_CODE (type_decl) == TYPE_DECL)
939 type = TREE_TYPE (type_decl);
940 if (TYPE_MAIN_VARIANT (type) != id_type)
941 warning ("unexpected type for `id' (%s)",
942 gen_declaration (type, errbuf));
946 error ("undefined type `id', please import <objc/objc.h>");
947 return error_mark_node;
950 /* This clause creates a new pointer type that is qualified with
951 the protocol specification...this info is used later to do more
952 elaborate type checking. */
956 tree t, m = TYPE_MAIN_VARIANT (type);
958 t = copy_node (type);
959 TYPE_BINFO (t) = make_tree_vec (2);
961 /* Add this type to the chain of variants of TYPE. */
962 TYPE_NEXT_VARIANT (t) = TYPE_NEXT_VARIANT (m);
963 TYPE_NEXT_VARIANT (m) = t;
965 /* Look up protocols...and install in lang specific list */
966 TYPE_PROTOCOL_LIST (t) = lookup_and_install_protocols (protocols);
968 /* This forces a new pointer type to be created later
969 (in build_pointer_type)...so that the new template
970 we just created will actually be used...what a hack! */
971 if (TYPE_POINTER_TO (t))
972 TYPE_POINTER_TO (t) = NULL_TREE;
979 /* Check for circular dependencies in protocols. The arguments are
980 PROTO, the protocol to check, and LIST, a list of protocol it
984 check_protocol_recursively (proto, list)
990 for (p = list; p; p = TREE_CHAIN (p))
992 tree pp = TREE_VALUE (p);
994 if (TREE_CODE (pp) == IDENTIFIER_NODE)
995 pp = lookup_protocol (pp);
998 fatal_error ("protocol `%s' has circular dependency",
999 IDENTIFIER_POINTER (PROTOCOL_NAME (pp)));
1001 check_protocol_recursively (proto, PROTOCOL_LIST (pp));
1006 lookup_and_install_protocols (protocols)
1011 tree return_value = protocols;
1013 for (proto = protocols; proto; proto = TREE_CHAIN (proto))
1015 tree ident = TREE_VALUE (proto);
1016 tree p = lookup_protocol (ident);
1020 error ("cannot find protocol declaration for `%s'",
1021 IDENTIFIER_POINTER (ident));
1023 TREE_CHAIN (prev) = TREE_CHAIN (proto);
1025 return_value = TREE_CHAIN (proto);
1029 /* Replace identifier with actual protocol node. */
1030 TREE_VALUE (proto) = p;
1035 return return_value;
1038 /* Create and push a decl for a built-in external variable or field NAME.
1040 TYPE is its data type. */
1043 create_builtin_decl (code, type, name)
1044 enum tree_code code;
1048 tree decl = build_decl (code, get_identifier (name), type);
1050 if (code == VAR_DECL)
1052 TREE_STATIC (decl) = 1;
1053 make_decl_rtl (decl, 0);
1057 DECL_ARTIFICIAL (decl) = 1;
1061 /* Find the decl for the constant string class. */
1064 setup_string_decl ()
1066 if (!string_class_decl)
1068 if (!constant_string_global_id)
1069 constant_string_global_id = get_identifier (STRING_OBJECT_GLOBAL_NAME);
1070 string_class_decl = lookup_name (constant_string_global_id);
1074 /* Purpose: "play" parser, creating/installing representations
1075 of the declarations that are required by Objective-C.
1079 type_spec--------->sc_spec
1080 (tree_list) (tree_list)
1083 identifier_node identifier_node */
1086 synth_module_prologue ()
1091 /* Defined in `objc.h' */
1092 objc_object_id = get_identifier (TAG_OBJECT);
1094 objc_object_reference = xref_tag (RECORD_TYPE, objc_object_id);
1096 id_type = build_pointer_type (objc_object_reference);
1098 objc_id_id = get_identifier (TYPE_ID);
1099 objc_class_id = get_identifier (TAG_CLASS);
1101 objc_class_type = build_pointer_type (xref_tag (RECORD_TYPE, objc_class_id));
1102 protocol_type = build_pointer_type (xref_tag (RECORD_TYPE,
1103 get_identifier (PROTOCOL_OBJECT_CLASS_NAME)));
1105 /* Declare type of selector-objects that represent an operation name. */
1107 /* `struct objc_selector *' */
1109 = build_pointer_type (xref_tag (RECORD_TYPE,
1110 get_identifier (TAG_SELECTOR)));
1112 /* Forward declare type, or else the prototype for msgSendSuper will
1115 super_p = build_pointer_type (xref_tag (RECORD_TYPE,
1116 get_identifier (TAG_SUPER)));
1119 /* id objc_msgSend (id, SEL, ...); */
1122 = build_function_type (id_type,
1123 tree_cons (NULL_TREE, id_type,
1124 tree_cons (NULL_TREE, selector_type,
1127 if (! flag_next_runtime)
1129 umsg_decl = build_decl (FUNCTION_DECL,
1130 get_identifier (TAG_MSGSEND), temp_type);
1131 DECL_EXTERNAL (umsg_decl) = 1;
1132 TREE_PUBLIC (umsg_decl) = 1;
1133 DECL_INLINE (umsg_decl) = 1;
1134 DECL_ARTIFICIAL (umsg_decl) = 1;
1136 if (flag_traditional && TAG_MSGSEND[0] != '_')
1137 DECL_BUILT_IN_NONANSI (umsg_decl) = 1;
1139 make_decl_rtl (umsg_decl, NULL);
1140 pushdecl (umsg_decl);
1143 umsg_decl = builtin_function (TAG_MSGSEND, temp_type, 0, NOT_BUILT_IN, 0);
1145 /* id objc_msgSendSuper (struct objc_super *, SEL, ...); */
1148 = build_function_type (id_type,
1149 tree_cons (NULL_TREE, super_p,
1150 tree_cons (NULL_TREE, selector_type,
1153 umsg_super_decl = builtin_function (TAG_MSGSENDSUPER,
1154 temp_type, 0, NOT_BUILT_IN, 0);
1156 /* id objc_getClass (const char *); */
1158 temp_type = build_function_type (id_type,
1159 tree_cons (NULL_TREE,
1160 const_string_type_node,
1161 tree_cons (NULL_TREE, void_type_node,
1165 = builtin_function (TAG_GETCLASS, temp_type, 0, NOT_BUILT_IN, 0);
1167 /* id objc_getMetaClass (const char *); */
1169 objc_get_meta_class_decl
1170 = builtin_function (TAG_GETMETACLASS, temp_type, 0, NOT_BUILT_IN, 0);
1172 /* static SEL _OBJC_SELECTOR_TABLE[]; */
1174 if (! flag_next_runtime)
1176 if (flag_typed_selectors)
1178 /* Suppress outputting debug symbols, because
1179 dbxout_init hasn'r been called yet. */
1180 enum debug_info_type save_write_symbols = write_symbols;
1181 struct gcc_debug_hooks *save_hooks = debug_hooks;
1182 write_symbols = NO_DEBUG;
1183 debug_hooks = &do_nothing_debug_hooks;
1185 build_selector_template ();
1186 temp_type = build_array_type (objc_selector_template, NULL_TREE);
1188 write_symbols = save_write_symbols;
1189 debug_hooks = save_hooks;
1192 temp_type = build_array_type (selector_type, NULL_TREE);
1194 layout_type (temp_type);
1195 UOBJC_SELECTOR_TABLE_decl
1196 = create_builtin_decl (VAR_DECL, temp_type,
1197 "_OBJC_SELECTOR_TABLE");
1199 /* Avoid warning when not sending messages. */
1200 TREE_USED (UOBJC_SELECTOR_TABLE_decl) = 1;
1203 generate_forward_declaration_to_string_table ();
1205 /* Forward declare constant_string_id and constant_string_type. */
1206 if (!constant_string_class_name)
1207 constant_string_class_name = STRING_OBJECT_CLASS_NAME;
1209 constant_string_id = get_identifier (constant_string_class_name);
1210 constant_string_type = xref_tag (RECORD_TYPE, constant_string_id);
1213 /* Predefine the following data type:
1215 struct STRING_OBJECT_CLASS_NAME
1219 unsigned int length;
1223 build_string_class_template ()
1225 tree field_decl, field_decl_chain;
1227 field_decl = create_builtin_decl (FIELD_DECL, id_type, "isa");
1228 field_decl_chain = field_decl;
1230 field_decl = create_builtin_decl (FIELD_DECL,
1231 build_pointer_type (char_type_node),
1233 chainon (field_decl_chain, field_decl);
1235 field_decl = create_builtin_decl (FIELD_DECL, unsigned_type_node, "length");
1236 chainon (field_decl_chain, field_decl);
1238 finish_struct (constant_string_type, field_decl_chain, NULL_TREE);
1241 /* Custom build_string which sets TREE_TYPE! */
1244 my_build_string (len, str)
1249 tree a_string = build_string (len, str);
1251 /* Some code from combine_strings, which is local to c-parse.y. */
1252 if (TREE_TYPE (a_string) == int_array_type_node)
1255 TREE_TYPE (a_string)
1256 = build_array_type (wide_flag ? integer_type_node : char_type_node,
1257 build_index_type (build_int_2 (len - 1, 0)));
1259 TREE_CONSTANT (a_string) = 1; /* Puts string in the readonly segment */
1260 TREE_STATIC (a_string) = 1;
1265 /* Given a chain of STRING_CST's, build a static instance of
1266 NXConstantString which points at the concatenation of those strings.
1267 We place the string object in the __string_objects section of the
1268 __OBJC segment. The Objective-C runtime will initialize the isa
1269 pointers of the string objects to point at the NXConstantString
1273 build_objc_string_object (strings)
1276 tree string, initlist, constructor;
1279 if (lookup_interface (constant_string_id) == NULL_TREE)
1281 error ("cannot find interface declaration for `%s'",
1282 IDENTIFIER_POINTER (constant_string_id));
1283 return error_mark_node;
1286 add_class_reference (constant_string_id);
1288 string = combine_strings (strings);
1289 TREE_SET_CODE (string, STRING_CST);
1290 length = TREE_STRING_LENGTH (string) - 1;
1292 /* We could not properly create NXConstantString in synth_module_prologue,
1293 because that's called before debugging is initialized. Do it now. */
1294 if (TYPE_FIELDS (constant_string_type) == NULL_TREE)
1295 build_string_class_template ();
1297 /* & ((NXConstantString) { NULL, string, length }) */
1299 if (flag_next_runtime)
1301 /* For the NeXT runtime, we can generate a literal reference
1302 to the string class, don't need to run a constructor. */
1303 setup_string_decl ();
1304 if (string_class_decl == NULL_TREE)
1306 error ("cannot find reference tag for class `%s'",
1307 IDENTIFIER_POINTER (constant_string_id));
1308 return error_mark_node;
1310 initlist = build_tree_list
1312 copy_node (build_unary_op (ADDR_EXPR, string_class_decl, 0)));
1316 initlist = build_tree_list (NULL_TREE, build_int_2 (0, 0));
1320 = tree_cons (NULL_TREE, copy_node (build_unary_op (ADDR_EXPR, string, 1)),
1322 initlist = tree_cons (NULL_TREE, build_int_2 (length, 0), initlist);
1323 constructor = build_constructor (constant_string_type, nreverse (initlist));
1325 if (!flag_next_runtime)
1328 = objc_add_static_instance (constructor, constant_string_type);
1331 return (build_unary_op (ADDR_EXPR, constructor, 1));
1334 /* Declare a static instance of CLASS_DECL initialized by CONSTRUCTOR. */
1337 objc_add_static_instance (constructor, class_decl)
1338 tree constructor, class_decl;
1340 static int num_static_inst;
1344 /* Find the list of static instances for the CLASS_DECL. Create one if
1346 for (chain = &objc_static_instances;
1347 *chain && TREE_VALUE (*chain) != class_decl;
1348 chain = &TREE_CHAIN (*chain));
1351 *chain = tree_cons (NULL_TREE, class_decl, NULL_TREE);
1352 add_objc_string (TYPE_NAME (class_decl), class_names);
1355 sprintf (buf, "_OBJC_INSTANCE_%d", num_static_inst++);
1356 decl = build_decl (VAR_DECL, get_identifier (buf), class_decl);
1357 DECL_COMMON (decl) = 1;
1358 TREE_STATIC (decl) = 1;
1359 DECL_ARTIFICIAL (decl) = 1;
1360 DECL_INITIAL (decl) = constructor;
1362 /* We may be writing something else just now.
1363 Postpone till end of input. */
1364 DECL_DEFER_OUTPUT (decl) = 1;
1365 pushdecl_top_level (decl);
1366 rest_of_decl_compilation (decl, 0, 1, 0);
1368 /* Add the DECL to the head of this CLASS' list. */
1369 TREE_PURPOSE (*chain) = tree_cons (NULL_TREE, decl, TREE_PURPOSE (*chain));
1374 /* Build a static constant CONSTRUCTOR
1375 with type TYPE and elements ELTS. */
1378 build_constructor (type, elts)
1381 tree constructor, f, e;
1383 /* ??? Most of the places that we build constructors, we don't fill in
1384 the type of integers properly. Convert them all en masse. */
1385 if (TREE_CODE (type) == ARRAY_TYPE)
1387 f = TREE_TYPE (type);
1388 if (TREE_CODE (f) == POINTER_TYPE || TREE_CODE (f) == INTEGER_TYPE)
1389 for (e = elts; e ; e = TREE_CHAIN (e))
1390 TREE_VALUE (e) = convert (f, TREE_VALUE (e));
1394 f = TYPE_FIELDS (type);
1395 for (e = elts; e ; e = TREE_CHAIN (e), f = TREE_CHAIN (f))
1396 if (TREE_CODE (TREE_TYPE (f)) == POINTER_TYPE
1397 || TREE_CODE (TREE_TYPE (f)) == INTEGER_TYPE)
1398 TREE_VALUE (e) = convert (TREE_TYPE (f), TREE_VALUE (e));
1401 constructor = build (CONSTRUCTOR, type, NULL_TREE, elts);
1402 TREE_CONSTANT (constructor) = 1;
1403 TREE_STATIC (constructor) = 1;
1404 TREE_READONLY (constructor) = 1;
1409 /* Take care of defining and initializing _OBJC_SYMBOLS. */
1411 /* Predefine the following data type:
1419 void *defs[cls_def_cnt + cat_def_cnt];
1423 build_objc_symtab_template ()
1425 tree field_decl, field_decl_chain, index;
1427 objc_symtab_template
1428 = start_struct (RECORD_TYPE, get_identifier (UTAG_SYMTAB));
1430 /* long sel_ref_cnt; */
1432 field_decl = create_builtin_decl (FIELD_DECL,
1433 long_integer_type_node,
1435 field_decl_chain = field_decl;
1439 field_decl = create_builtin_decl (FIELD_DECL,
1440 build_pointer_type (selector_type),
1442 chainon (field_decl_chain, field_decl);
1444 /* short cls_def_cnt; */
1446 field_decl = create_builtin_decl (FIELD_DECL,
1447 short_integer_type_node,
1449 chainon (field_decl_chain, field_decl);
1451 /* short cat_def_cnt; */
1453 field_decl = create_builtin_decl (FIELD_DECL,
1454 short_integer_type_node,
1456 chainon (field_decl_chain, field_decl);
1458 /* void *defs[cls_def_cnt + cat_def_cnt]; */
1460 if (!flag_next_runtime)
1461 index = build_index_type (build_int_2 (imp_count + cat_count, 0));
1463 index = build_index_type (build_int_2 (imp_count + cat_count - 1,
1464 imp_count == 0 && cat_count == 0
1466 field_decl = create_builtin_decl (FIELD_DECL,
1467 build_array_type (ptr_type_node, index),
1469 chainon (field_decl_chain, field_decl);
1471 finish_struct (objc_symtab_template, field_decl_chain, NULL_TREE);
1474 /* Create the initial value for the `defs' field of _objc_symtab.
1475 This is a CONSTRUCTOR. */
1478 init_def_list (type)
1481 tree expr, initlist = NULL_TREE;
1482 struct imp_entry *impent;
1485 for (impent = imp_list; impent; impent = impent->next)
1487 if (TREE_CODE (impent->imp_context) == CLASS_IMPLEMENTATION_TYPE)
1489 expr = build_unary_op (ADDR_EXPR, impent->class_decl, 0);
1490 initlist = tree_cons (NULL_TREE, expr, initlist);
1495 for (impent = imp_list; impent; impent = impent->next)
1497 if (TREE_CODE (impent->imp_context) == CATEGORY_IMPLEMENTATION_TYPE)
1499 expr = build_unary_op (ADDR_EXPR, impent->class_decl, 0);
1500 initlist = tree_cons (NULL_TREE, expr, initlist);
1504 if (!flag_next_runtime)
1506 /* statics = { ..., _OBJC_STATIC_INSTANCES, ... } */
1509 if (static_instances_decl)
1510 expr = build_unary_op (ADDR_EXPR, static_instances_decl, 0);
1512 expr = build_int_2 (0, 0);
1514 initlist = tree_cons (NULL_TREE, expr, initlist);
1517 return build_constructor (type, nreverse (initlist));
1520 /* Construct the initial value for all of _objc_symtab. */
1523 init_objc_symtab (type)
1528 /* sel_ref_cnt = { ..., 5, ... } */
1530 initlist = build_tree_list (NULL_TREE, build_int_2 (0, 0));
1532 /* refs = { ..., _OBJC_SELECTOR_TABLE, ... } */
1534 if (flag_next_runtime || ! sel_ref_chain)
1535 initlist = tree_cons (NULL_TREE, build_int_2 (0, 0), initlist);
1537 initlist = tree_cons (NULL_TREE,
1538 build_unary_op (ADDR_EXPR,
1539 UOBJC_SELECTOR_TABLE_decl, 1),
1542 /* cls_def_cnt = { ..., 5, ... } */
1544 initlist = tree_cons (NULL_TREE, build_int_2 (imp_count, 0), initlist);
1546 /* cat_def_cnt = { ..., 5, ... } */
1548 initlist = tree_cons (NULL_TREE, build_int_2 (cat_count, 0), initlist);
1550 /* cls_def = { ..., { &Foo, &Bar, ...}, ... } */
1552 if (imp_count || cat_count || static_instances_decl)
1555 tree field = TYPE_FIELDS (type);
1556 field = TREE_CHAIN (TREE_CHAIN (TREE_CHAIN (TREE_CHAIN (field))));
1558 initlist = tree_cons (NULL_TREE, init_def_list (TREE_TYPE (field)),
1562 return build_constructor (type, nreverse (initlist));
1565 /* Push forward-declarations of all the categories so that
1566 init_def_list can use them in a CONSTRUCTOR. */
1569 forward_declare_categories ()
1571 struct imp_entry *impent;
1572 tree sav = objc_implementation_context;
1574 for (impent = imp_list; impent; impent = impent->next)
1576 if (TREE_CODE (impent->imp_context) == CATEGORY_IMPLEMENTATION_TYPE)
1578 /* Set an invisible arg to synth_id_with_class_suffix. */
1579 objc_implementation_context = impent->imp_context;
1581 = create_builtin_decl (VAR_DECL, objc_category_template,
1582 IDENTIFIER_POINTER (synth_id_with_class_suffix ("_OBJC_CATEGORY", objc_implementation_context)));
1585 objc_implementation_context = sav;
1588 /* Create the declaration of _OBJC_SYMBOLS, with type `strict _objc_symtab'
1589 and initialized appropriately. */
1592 generate_objc_symtab_decl ()
1596 if (!objc_category_template)
1597 build_category_template ();
1599 /* forward declare categories */
1601 forward_declare_categories ();
1603 if (!objc_symtab_template)
1604 build_objc_symtab_template ();
1606 sc_spec = build_tree_list (NULL_TREE, ridpointers[(int) RID_STATIC]);
1608 UOBJC_SYMBOLS_decl = start_decl (get_identifier ("_OBJC_SYMBOLS"),
1609 tree_cons (NULL_TREE,
1610 objc_symtab_template, sc_spec),
1614 TREE_USED (UOBJC_SYMBOLS_decl) = 1;
1615 DECL_IGNORED_P (UOBJC_SYMBOLS_decl) = 1;
1616 DECL_ARTIFICIAL (UOBJC_SYMBOLS_decl) = 1;
1617 finish_decl (UOBJC_SYMBOLS_decl,
1618 init_objc_symtab (TREE_TYPE (UOBJC_SYMBOLS_decl)),
1623 init_module_descriptor (type)
1626 tree initlist, expr;
1628 /* version = { 1, ... } */
1630 expr = build_int_2 (OBJC_VERSION, 0);
1631 initlist = build_tree_list (NULL_TREE, expr);
1633 /* size = { ..., sizeof (struct objc_module), ... } */
1635 expr = size_in_bytes (objc_module_template);
1636 initlist = tree_cons (NULL_TREE, expr, initlist);
1638 /* name = { ..., "foo.m", ... } */
1640 expr = add_objc_string (get_identifier (input_filename), class_names);
1641 initlist = tree_cons (NULL_TREE, expr, initlist);
1643 /* symtab = { ..., _OBJC_SYMBOLS, ... } */
1645 if (UOBJC_SYMBOLS_decl)
1646 expr = build_unary_op (ADDR_EXPR, UOBJC_SYMBOLS_decl, 0);
1648 expr = build_int_2 (0, 0);
1649 initlist = tree_cons (NULL_TREE, expr, initlist);
1651 return build_constructor (type, nreverse (initlist));
1654 /* Write out the data structures to describe Objective C classes defined.
1655 If appropriate, compile and output a setup function to initialize them.
1656 Return a symbol_ref to the function to call to initialize the Objective C
1657 data structures for this file (and perhaps for other files also).
1659 struct objc_module { ... } _OBJC_MODULE = { ... }; */
1662 build_module_descriptor ()
1664 tree decl_specs, field_decl, field_decl_chain;
1666 objc_module_template
1667 = start_struct (RECORD_TYPE, get_identifier (UTAG_MODULE));
1671 decl_specs = build_tree_list (NULL_TREE, ridpointers[(int) RID_LONG]);
1672 field_decl = get_identifier ("version");
1674 = grokfield (input_filename, lineno, field_decl, decl_specs, NULL_TREE);
1675 field_decl_chain = field_decl;
1679 decl_specs = build_tree_list (NULL_TREE, ridpointers[(int) RID_LONG]);
1680 field_decl = get_identifier ("size");
1682 = grokfield (input_filename, lineno, field_decl, decl_specs, NULL_TREE);
1683 chainon (field_decl_chain, field_decl);
1687 decl_specs = build_tree_list (NULL_TREE, ridpointers[(int) RID_CHAR]);
1688 field_decl = build1 (INDIRECT_REF, NULL_TREE, get_identifier ("name"));
1690 = grokfield (input_filename, lineno, field_decl, decl_specs, NULL_TREE);
1691 chainon (field_decl_chain, field_decl);
1693 /* struct objc_symtab *symtab; */
1695 decl_specs = get_identifier (UTAG_SYMTAB);
1696 decl_specs = build_tree_list (NULL_TREE, xref_tag (RECORD_TYPE, decl_specs));
1697 field_decl = build1 (INDIRECT_REF, NULL_TREE, get_identifier ("symtab"));
1699 = grokfield (input_filename, lineno, field_decl, decl_specs, NULL_TREE);
1700 chainon (field_decl_chain, field_decl);
1702 finish_struct (objc_module_template, field_decl_chain, NULL_TREE);
1704 /* Create an instance of "objc_module". */
1706 decl_specs = tree_cons (NULL_TREE, objc_module_template,
1707 build_tree_list (NULL_TREE,
1708 ridpointers[(int) RID_STATIC]));
1710 UOBJC_MODULES_decl = start_decl (get_identifier ("_OBJC_MODULES"),
1711 decl_specs, 1, NULL_TREE);
1713 DECL_ARTIFICIAL (UOBJC_MODULES_decl) = 1;
1714 DECL_IGNORED_P (UOBJC_MODULES_decl) = 1;
1715 DECL_CONTEXT (UOBJC_MODULES_decl) = NULL_TREE;
1717 finish_decl (UOBJC_MODULES_decl,
1718 init_module_descriptor (TREE_TYPE (UOBJC_MODULES_decl)),
1721 /* Mark the decl to avoid "defined but not used" warning. */
1722 DECL_IN_SYSTEM_HEADER (UOBJC_MODULES_decl) = 1;
1724 /* Generate a constructor call for the module descriptor.
1725 This code was generated by reading the grammar rules
1726 of c-parse.in; Therefore, it may not be the most efficient
1727 way of generating the requisite code. */
1729 if (flag_next_runtime)
1733 tree parms, execclass_decl, decelerator, void_list_node_1;
1734 tree init_function_name, init_function_decl;
1736 /* Declare void __objc_execClass (void *); */
1738 void_list_node_1 = build_tree_list (NULL_TREE, void_type_node);
1739 execclass_decl = build_decl (FUNCTION_DECL,
1740 get_identifier (TAG_EXECCLASS),
1741 build_function_type (void_type_node,
1742 tree_cons (NULL_TREE, ptr_type_node,
1743 void_list_node_1)));
1744 DECL_EXTERNAL (execclass_decl) = 1;
1745 DECL_ARTIFICIAL (execclass_decl) = 1;
1746 TREE_PUBLIC (execclass_decl) = 1;
1747 pushdecl (execclass_decl);
1748 rest_of_decl_compilation (execclass_decl, 0, 0, 0);
1749 assemble_external (execclass_decl);
1751 /* void _GLOBAL_$I$<gnyf> () {objc_execClass (&L_OBJC_MODULES);} */
1753 init_function_name = get_file_function_name ('I');
1754 start_function (void_list_node_1,
1755 build_nt (CALL_EXPR, init_function_name,
1756 tree_cons (NULL_TREE, NULL_TREE,
1760 store_parm_decls ();
1762 init_function_decl = current_function_decl;
1763 TREE_PUBLIC (init_function_decl) = ! targetm.have_ctors_dtors;
1764 TREE_USED (init_function_decl) = 1;
1765 /* Don't let this one be deferred. */
1766 DECL_INLINE (init_function_decl) = 0;
1767 DECL_UNINLINABLE (init_function_decl) = 1;
1768 current_function_cannot_inline
1769 = "static constructors and destructors cannot be inlined";
1772 = build_tree_list (NULL_TREE,
1773 build_unary_op (ADDR_EXPR, UOBJC_MODULES_decl, 0));
1774 decelerator = build_function_call (execclass_decl, parms);
1776 c_expand_expr_stmt (decelerator);
1778 finish_function (0);
1780 return XEXP (DECL_RTL (init_function_decl), 0);
1784 /* extern const char _OBJC_STRINGS[]; */
1787 generate_forward_declaration_to_string_table ()
1789 tree sc_spec, decl_specs, expr_decl;
1791 sc_spec = tree_cons (NULL_TREE, ridpointers[(int) RID_EXTERN], NULL_TREE);
1792 decl_specs = tree_cons (NULL_TREE, ridpointers[(int) RID_CHAR], sc_spec);
1795 = build_nt (ARRAY_REF, get_identifier ("_OBJC_STRINGS"), NULL_TREE);
1797 UOBJC_STRINGS_decl = define_decl (expr_decl, decl_specs);
1800 /* Return the DECL of the string IDENT in the SECTION. */
1803 get_objc_string_decl (ident, section)
1805 enum string_section section;
1809 if (section == class_names)
1810 chain = class_names_chain;
1811 else if (section == meth_var_names)
1812 chain = meth_var_names_chain;
1813 else if (section == meth_var_types)
1814 chain = meth_var_types_chain;
1818 for (; chain != 0; chain = TREE_VALUE (chain))
1819 if (TREE_VALUE (chain) == ident)
1820 return (TREE_PURPOSE (chain));
1826 /* Output references to all statically allocated objects. Return the DECL
1827 for the array built. */
1830 generate_static_references ()
1832 tree decls = NULL_TREE, ident, decl_spec, expr_decl, expr = NULL_TREE;
1833 tree class_name, class, decl, initlist;
1834 tree cl_chain, in_chain, type;
1835 int num_inst, num_class;
1838 if (flag_next_runtime)
1841 for (cl_chain = objc_static_instances, num_class = 0;
1842 cl_chain; cl_chain = TREE_CHAIN (cl_chain), num_class++)
1844 for (num_inst = 0, in_chain = TREE_PURPOSE (cl_chain);
1845 in_chain; num_inst++, in_chain = TREE_CHAIN (in_chain));
1847 sprintf (buf, "_OBJC_STATIC_INSTANCES_%d", num_class);
1848 ident = get_identifier (buf);
1850 expr_decl = build_nt (ARRAY_REF, ident, NULL_TREE);
1851 decl_spec = tree_cons (NULL_TREE, build_pointer_type (void_type_node),
1852 build_tree_list (NULL_TREE,
1853 ridpointers[(int) RID_STATIC]));
1854 decl = start_decl (expr_decl, decl_spec, 1, NULL_TREE);
1855 DECL_CONTEXT (decl) = 0;
1856 DECL_ARTIFICIAL (decl) = 1;
1858 /* Output {class_name, ...}. */
1859 class = TREE_VALUE (cl_chain);
1860 class_name = get_objc_string_decl (TYPE_NAME (class), class_names);
1861 initlist = build_tree_list (NULL_TREE,
1862 build_unary_op (ADDR_EXPR, class_name, 1));
1864 /* Output {..., instance, ...}. */
1865 for (in_chain = TREE_PURPOSE (cl_chain);
1866 in_chain; in_chain = TREE_CHAIN (in_chain))
1868 expr = build_unary_op (ADDR_EXPR, TREE_VALUE (in_chain), 1);
1869 initlist = tree_cons (NULL_TREE, expr, initlist);
1872 /* Output {..., NULL}. */
1873 initlist = tree_cons (NULL_TREE, build_int_2 (0, 0), initlist);
1875 expr = build_constructor (TREE_TYPE (decl), nreverse (initlist));
1876 finish_decl (decl, expr, NULL_TREE);
1877 TREE_USED (decl) = 1;
1879 type = build_array_type (build_pointer_type (void_type_node), 0);
1880 decl = build_decl (VAR_DECL, ident, type);
1881 TREE_USED (decl) = 1;
1882 TREE_STATIC (decl) = 1;
1884 = tree_cons (NULL_TREE, build_unary_op (ADDR_EXPR, decl, 1), decls);
1887 decls = tree_cons (NULL_TREE, build_int_2 (0, 0), decls);
1888 ident = get_identifier ("_OBJC_STATIC_INSTANCES");
1889 expr_decl = build_nt (ARRAY_REF, ident, NULL_TREE);
1890 decl_spec = tree_cons (NULL_TREE, build_pointer_type (void_type_node),
1891 build_tree_list (NULL_TREE,
1892 ridpointers[(int) RID_STATIC]));
1893 static_instances_decl
1894 = start_decl (expr_decl, decl_spec, 1, NULL_TREE);
1895 TREE_USED (static_instances_decl) = 1;
1896 DECL_CONTEXT (static_instances_decl) = 0;
1897 DECL_ARTIFICIAL (static_instances_decl) = 1;
1898 expr = build_constructor (TREE_TYPE (static_instances_decl),
1900 finish_decl (static_instances_decl, expr, NULL_TREE);
1903 /* Output all strings. */
1908 tree sc_spec, decl_specs, expr_decl;
1909 tree chain, string_expr;
1912 for (chain = class_names_chain; chain; chain = TREE_CHAIN (chain))
1914 string = TREE_VALUE (chain);
1915 decl = TREE_PURPOSE (chain);
1917 = tree_cons (NULL_TREE, ridpointers[(int) RID_STATIC], NULL_TREE);
1918 decl_specs = tree_cons (NULL_TREE, ridpointers[(int) RID_CHAR], sc_spec);
1919 expr_decl = build_nt (ARRAY_REF, DECL_NAME (decl), NULL_TREE);
1920 decl = start_decl (expr_decl, decl_specs, 1, NULL_TREE);
1921 DECL_CONTEXT (decl) = NULL_TREE;
1922 string_expr = my_build_string (IDENTIFIER_LENGTH (string) + 1,
1923 IDENTIFIER_POINTER (string));
1924 finish_decl (decl, string_expr, NULL_TREE);
1927 for (chain = meth_var_names_chain; chain; chain = TREE_CHAIN (chain))
1929 string = TREE_VALUE (chain);
1930 decl = TREE_PURPOSE (chain);
1932 = tree_cons (NULL_TREE, ridpointers[(int) RID_STATIC], NULL_TREE);
1933 decl_specs = tree_cons (NULL_TREE, ridpointers[(int) RID_CHAR], sc_spec);
1934 expr_decl = build_nt (ARRAY_REF, DECL_NAME (decl), NULL_TREE);
1935 decl = start_decl (expr_decl, decl_specs, 1, NULL_TREE);
1936 DECL_CONTEXT (decl) = NULL_TREE;
1937 string_expr = my_build_string (IDENTIFIER_LENGTH (string) + 1,
1938 IDENTIFIER_POINTER (string));
1939 finish_decl (decl, string_expr, NULL_TREE);
1942 for (chain = meth_var_types_chain; chain; chain = TREE_CHAIN (chain))
1944 string = TREE_VALUE (chain);
1945 decl = TREE_PURPOSE (chain);
1947 = tree_cons (NULL_TREE, ridpointers[(int) RID_STATIC], NULL_TREE);
1948 decl_specs = tree_cons (NULL_TREE, ridpointers[(int) RID_CHAR], sc_spec);
1949 expr_decl = build_nt (ARRAY_REF, DECL_NAME (decl), NULL_TREE);
1950 decl = start_decl (expr_decl, decl_specs, 1, NULL_TREE);
1951 DECL_CONTEXT (decl) = NULL_TREE;
1952 string_expr = my_build_string (IDENTIFIER_LENGTH (string) + 1,
1953 IDENTIFIER_POINTER (string));
1954 finish_decl (decl, string_expr, NULL_TREE);
1959 build_selector_reference_decl ()
1965 sprintf (buf, "_OBJC_SELECTOR_REFERENCES_%d", idx++);
1967 ident = get_identifier (buf);
1969 decl = build_decl (VAR_DECL, ident, selector_type);
1970 DECL_EXTERNAL (decl) = 1;
1971 TREE_PUBLIC (decl) = 1;
1972 TREE_USED (decl) = 1;
1973 TREE_READONLY (decl) = 1;
1974 DECL_ARTIFICIAL (decl) = 1;
1975 DECL_CONTEXT (decl) = 0;
1977 make_decl_rtl (decl, 0);
1978 pushdecl_top_level (decl);
1983 /* Just a handy wrapper for add_objc_string. */
1986 build_selector (ident)
1989 tree expr = add_objc_string (ident, meth_var_names);
1990 if (flag_typed_selectors)
1993 return build_c_cast (selector_type, expr); /* cast! */
1997 build_selector_translation_table ()
1999 tree sc_spec, decl_specs;
2000 tree chain, initlist = NULL_TREE;
2002 tree decl = NULL_TREE, var_decl, name;
2004 for (chain = sel_ref_chain; chain; chain = TREE_CHAIN (chain))
2008 expr = build_selector (TREE_VALUE (chain));
2010 if (flag_next_runtime)
2012 name = DECL_NAME (TREE_PURPOSE (chain));
2014 sc_spec = build_tree_list (NULL_TREE, ridpointers[(int) RID_STATIC]);
2016 /* static SEL _OBJC_SELECTOR_REFERENCES_n = ...; */
2017 decl_specs = tree_cons (NULL_TREE, selector_type, sc_spec);
2021 /* The `decl' that is returned from start_decl is the one that we
2022 forward declared in `build_selector_reference' */
2023 decl = start_decl (var_decl, decl_specs, 1, NULL_TREE );
2026 /* add one for the '\0' character */
2027 offset += IDENTIFIER_LENGTH (TREE_VALUE (chain)) + 1;
2029 if (flag_next_runtime)
2030 finish_decl (decl, expr, NULL_TREE);
2033 if (flag_typed_selectors)
2035 tree eltlist = NULL_TREE;
2036 tree encoding = get_proto_encoding (TREE_PURPOSE (chain));
2037 eltlist = tree_cons (NULL_TREE, expr, NULL_TREE);
2038 eltlist = tree_cons (NULL_TREE, encoding, eltlist);
2039 expr = build_constructor (objc_selector_template,
2040 nreverse (eltlist));
2042 initlist = tree_cons (NULL_TREE, expr, initlist);
2047 if (! flag_next_runtime)
2049 /* Cause the variable and its initial value to be actually output. */
2050 DECL_EXTERNAL (UOBJC_SELECTOR_TABLE_decl) = 0;
2051 TREE_STATIC (UOBJC_SELECTOR_TABLE_decl) = 1;
2052 /* NULL terminate the list and fix the decl for output. */
2053 initlist = tree_cons (NULL_TREE, build_int_2 (0, 0), initlist);
2054 DECL_INITIAL (UOBJC_SELECTOR_TABLE_decl) = objc_ellipsis_node;
2055 initlist = build_constructor (TREE_TYPE (UOBJC_SELECTOR_TABLE_decl),
2056 nreverse (initlist));
2057 finish_decl (UOBJC_SELECTOR_TABLE_decl, initlist, NULL_TREE);
2058 current_function_decl = NULL_TREE;
2063 get_proto_encoding (proto)
2071 if (! METHOD_ENCODING (proto))
2073 tmp_decl = build_tmp_function_decl ();
2074 hack_method_prototype (proto, tmp_decl);
2075 encoding = encode_method_prototype (proto, tmp_decl);
2076 METHOD_ENCODING (proto) = encoding;
2079 encoding = METHOD_ENCODING (proto);
2081 return add_objc_string (encoding, meth_var_types);
2084 return build_int_2 (0, 0);
2087 /* sel_ref_chain is a list whose "value" fields will be instances of
2088 identifier_node that represent the selector. */
2091 build_typed_selector_reference (ident, proto)
2094 tree *chain = &sel_ref_chain;
2100 if (TREE_PURPOSE (*chain) == ident && TREE_VALUE (*chain) == proto)
2101 goto return_at_index;
2104 chain = &TREE_CHAIN (*chain);
2107 *chain = tree_cons (proto, ident, NULL_TREE);
2110 expr = build_unary_op (ADDR_EXPR,
2111 build_array_ref (UOBJC_SELECTOR_TABLE_decl,
2112 build_int_2 (index, 0)),
2114 return build_c_cast (selector_type, expr);
2118 build_selector_reference (ident)
2121 tree *chain = &sel_ref_chain;
2127 if (TREE_VALUE (*chain) == ident)
2128 return (flag_next_runtime
2129 ? TREE_PURPOSE (*chain)
2130 : build_array_ref (UOBJC_SELECTOR_TABLE_decl,
2131 build_int_2 (index, 0)));
2134 chain = &TREE_CHAIN (*chain);
2137 expr = build_selector_reference_decl ();
2139 *chain = tree_cons (expr, ident, NULL_TREE);
2141 return (flag_next_runtime
2143 : build_array_ref (UOBJC_SELECTOR_TABLE_decl,
2144 build_int_2 (index, 0)));
2148 build_class_reference_decl ()
2154 sprintf (buf, "_OBJC_CLASS_REFERENCES_%d", idx++);
2156 ident = get_identifier (buf);
2158 decl = build_decl (VAR_DECL, ident, objc_class_type);
2159 DECL_EXTERNAL (decl) = 1;
2160 TREE_PUBLIC (decl) = 1;
2161 TREE_USED (decl) = 1;
2162 TREE_READONLY (decl) = 1;
2163 DECL_CONTEXT (decl) = 0;
2164 DECL_ARTIFICIAL (decl) = 1;
2166 make_decl_rtl (decl, 0);
2167 pushdecl_top_level (decl);
2172 /* Create a class reference, but don't create a variable to reference
2176 add_class_reference (ident)
2181 if ((chain = cls_ref_chain))
2186 if (ident == TREE_VALUE (chain))
2190 chain = TREE_CHAIN (chain);
2194 /* Append to the end of the list */
2195 TREE_CHAIN (tail) = tree_cons (NULL_TREE, ident, NULL_TREE);
2198 cls_ref_chain = tree_cons (NULL_TREE, ident, NULL_TREE);
2201 /* Get a class reference, creating it if necessary. Also create the
2202 reference variable. */
2205 get_class_reference (ident)
2208 if (flag_next_runtime)
2213 for (chain = &cls_ref_chain; *chain; chain = &TREE_CHAIN (*chain))
2214 if (TREE_VALUE (*chain) == ident)
2216 if (! TREE_PURPOSE (*chain))
2217 TREE_PURPOSE (*chain) = build_class_reference_decl ();
2219 return TREE_PURPOSE (*chain);
2222 decl = build_class_reference_decl ();
2223 *chain = tree_cons (decl, ident, NULL_TREE);
2230 add_class_reference (ident);
2232 params = build_tree_list (NULL_TREE,
2233 my_build_string (IDENTIFIER_LENGTH (ident) + 1,
2234 IDENTIFIER_POINTER (ident)));
2236 assemble_external (objc_get_class_decl);
2237 return build_function_call (objc_get_class_decl, params);
2241 /* For each string section we have a chain which maps identifier nodes
2242 to decls for the strings. */
2245 add_objc_string (ident, section)
2247 enum string_section section;
2251 if (section == class_names)
2252 chain = &class_names_chain;
2253 else if (section == meth_var_names)
2254 chain = &meth_var_names_chain;
2255 else if (section == meth_var_types)
2256 chain = &meth_var_types_chain;
2262 if (TREE_VALUE (*chain) == ident)
2263 return build_unary_op (ADDR_EXPR, TREE_PURPOSE (*chain), 1);
2265 chain = &TREE_CHAIN (*chain);
2268 decl = build_objc_string_decl (section);
2270 *chain = tree_cons (decl, ident, NULL_TREE);
2272 return build_unary_op (ADDR_EXPR, decl, 1);
2276 build_objc_string_decl (section)
2277 enum string_section section;
2281 static int class_names_idx = 0;
2282 static int meth_var_names_idx = 0;
2283 static int meth_var_types_idx = 0;
2285 if (section == class_names)
2286 sprintf (buf, "_OBJC_CLASS_NAME_%d", class_names_idx++);
2287 else if (section == meth_var_names)
2288 sprintf (buf, "_OBJC_METH_VAR_NAME_%d", meth_var_names_idx++);
2289 else if (section == meth_var_types)
2290 sprintf (buf, "_OBJC_METH_VAR_TYPE_%d", meth_var_types_idx++);
2292 ident = get_identifier (buf);
2294 decl = build_decl (VAR_DECL, ident, build_array_type (char_type_node, 0));
2295 DECL_EXTERNAL (decl) = 1;
2296 TREE_PUBLIC (decl) = 1;
2297 TREE_USED (decl) = 1;
2298 TREE_READONLY (decl) = 1;
2299 TREE_CONSTANT (decl) = 1;
2300 DECL_CONTEXT (decl) = 0;
2301 DECL_ARTIFICIAL (decl) = 1;
2303 make_decl_rtl (decl, 0);
2304 pushdecl_top_level (decl);
2311 objc_declare_alias (alias_ident, class_ident)
2315 if (is_class_name (class_ident) != class_ident)
2316 warning ("cannot find class `%s'", IDENTIFIER_POINTER (class_ident));
2317 else if (is_class_name (alias_ident))
2318 warning ("class `%s' already exists", IDENTIFIER_POINTER (alias_ident));
2320 alias_chain = tree_cons (class_ident, alias_ident, alias_chain);
2324 objc_declare_class (ident_list)
2329 for (list = ident_list; list; list = TREE_CHAIN (list))
2331 tree ident = TREE_VALUE (list);
2334 if ((decl = lookup_name (ident)))
2336 error ("`%s' redeclared as different kind of symbol",
2337 IDENTIFIER_POINTER (ident));
2338 error_with_decl (decl, "previous declaration of `%s'");
2341 if (! is_class_name (ident))
2343 tree record = xref_tag (RECORD_TYPE, ident);
2344 TREE_STATIC_TEMPLATE (record) = 1;
2345 class_chain = tree_cons (NULL_TREE, ident, class_chain);
2351 is_class_name (ident)
2356 if (lookup_interface (ident))
2359 for (chain = class_chain; chain; chain = TREE_CHAIN (chain))
2361 if (ident == TREE_VALUE (chain))
2365 for (chain = alias_chain; chain; chain = TREE_CHAIN (chain))
2367 if (ident == TREE_VALUE (chain))
2368 return TREE_PURPOSE (chain);
2375 lookup_interface (ident)
2380 for (chain = interface_chain; chain; chain = TREE_CHAIN (chain))
2382 if (ident == CLASS_NAME (chain))
2389 objc_copy_list (list, head)
2393 tree newlist = NULL_TREE, tail = NULL_TREE;
2397 tail = copy_node (list);
2399 /* The following statement fixes a bug when inheriting instance
2400 variables that are declared to be bitfields. finish_struct
2401 expects to find the width of the bitfield in DECL_INITIAL. */
2402 if (DECL_BIT_FIELD (tail) && DECL_INITIAL (tail) == 0)
2403 DECL_INITIAL (tail) = DECL_SIZE (tail);
2405 newlist = chainon (newlist, tail);
2406 list = TREE_CHAIN (list);
2413 /* Used by: build_private_template, get_class_ivars, and
2414 continue_class. COPY is 1 when called from @defs. In this case
2415 copy all fields. Otherwise don't copy leaf ivars since we rely on
2416 them being side-effected exactly once by finish_struct. */
2419 build_ivar_chain (interface, copy)
2423 tree my_name, super_name, ivar_chain;
2425 my_name = CLASS_NAME (interface);
2426 super_name = CLASS_SUPER_NAME (interface);
2428 /* Possibly copy leaf ivars. */
2430 objc_copy_list (CLASS_IVARS (interface), &ivar_chain);
2432 ivar_chain = CLASS_IVARS (interface);
2437 tree super_interface = lookup_interface (super_name);
2439 if (!super_interface)
2441 /* fatal did not work with 2 args...should fix */
2442 error ("cannot find interface declaration for `%s', superclass of `%s'",
2443 IDENTIFIER_POINTER (super_name),
2444 IDENTIFIER_POINTER (my_name));
2445 exit (FATAL_EXIT_CODE);
2448 if (super_interface == interface)
2449 fatal_error ("circular inheritance in interface declaration for `%s'",
2450 IDENTIFIER_POINTER (super_name));
2452 interface = super_interface;
2453 my_name = CLASS_NAME (interface);
2454 super_name = CLASS_SUPER_NAME (interface);
2456 op1 = CLASS_IVARS (interface);
2459 tree head, tail = objc_copy_list (op1, &head);
2461 /* Prepend super class ivars...make a copy of the list, we
2462 do not want to alter the original. */
2463 TREE_CHAIN (tail) = ivar_chain;
2470 /* struct <classname> {
2471 struct objc_class *isa;
2476 build_private_template (class)
2481 if (CLASS_STATIC_TEMPLATE (class))
2483 uprivate_record = CLASS_STATIC_TEMPLATE (class);
2484 ivar_context = TYPE_FIELDS (CLASS_STATIC_TEMPLATE (class));
2488 uprivate_record = start_struct (RECORD_TYPE, CLASS_NAME (class));
2490 ivar_context = build_ivar_chain (class, 0);
2492 finish_struct (uprivate_record, ivar_context, NULL_TREE);
2494 CLASS_STATIC_TEMPLATE (class) = uprivate_record;
2496 /* mark this record as class template - for class type checking */
2497 TREE_STATIC_TEMPLATE (uprivate_record) = 1;
2501 = groktypename (build_tree_list (build_tree_list (NULL_TREE,
2503 build1 (INDIRECT_REF, NULL_TREE,
2506 return ivar_context;
2509 /* Begin code generation for protocols... */
2511 /* struct objc_protocol {
2512 char *protocol_name;
2513 struct objc_protocol **protocol_list;
2514 struct objc_method_desc *instance_methods;
2515 struct objc_method_desc *class_methods;
2519 build_protocol_template ()
2521 tree decl_specs, field_decl, field_decl_chain;
2524 template = start_struct (RECORD_TYPE, get_identifier (UTAG_PROTOCOL));
2526 /* struct objc_class *isa; */
2528 decl_specs = build_tree_list (NULL_TREE, xref_tag (RECORD_TYPE,
2529 get_identifier (UTAG_CLASS)));
2530 field_decl = build1 (INDIRECT_REF, NULL_TREE, get_identifier ("isa"));
2532 = grokfield (input_filename, lineno, field_decl, decl_specs, NULL_TREE);
2533 field_decl_chain = field_decl;
2535 /* char *protocol_name; */
2537 decl_specs = build_tree_list (NULL_TREE, ridpointers[(int) RID_CHAR]);
2539 = build1 (INDIRECT_REF, NULL_TREE, get_identifier ("protocol_name"));
2541 = grokfield (input_filename, lineno, field_decl, decl_specs, NULL_TREE);
2542 chainon (field_decl_chain, field_decl);
2544 /* struct objc_protocol **protocol_list; */
2546 decl_specs = build_tree_list (NULL_TREE, template);
2548 = build1 (INDIRECT_REF, NULL_TREE, get_identifier ("protocol_list"));
2549 field_decl = build1 (INDIRECT_REF, NULL_TREE, field_decl);
2551 = grokfield (input_filename, lineno, field_decl, decl_specs, NULL_TREE);
2552 chainon (field_decl_chain, field_decl);
2554 /* struct objc_method_list *instance_methods; */
2557 = build_tree_list (NULL_TREE,
2558 xref_tag (RECORD_TYPE,
2559 get_identifier (UTAG_METHOD_PROTOTYPE_LIST)));
2561 = build1 (INDIRECT_REF, NULL_TREE, get_identifier ("instance_methods"));
2563 = grokfield (input_filename, lineno, field_decl, decl_specs, NULL_TREE);
2564 chainon (field_decl_chain, field_decl);
2566 /* struct objc_method_list *class_methods; */
2569 = build_tree_list (NULL_TREE,
2570 xref_tag (RECORD_TYPE,
2571 get_identifier (UTAG_METHOD_PROTOTYPE_LIST)));
2573 = build1 (INDIRECT_REF, NULL_TREE, get_identifier ("class_methods"));
2575 = grokfield (input_filename, lineno, field_decl, decl_specs, NULL_TREE);
2576 chainon (field_decl_chain, field_decl);
2578 return finish_struct (template, field_decl_chain, NULL_TREE);
2582 build_descriptor_table_initializer (type, entries)
2586 tree initlist = NULL_TREE;
2590 tree eltlist = NULL_TREE;
2593 = tree_cons (NULL_TREE,
2594 build_selector (METHOD_SEL_NAME (entries)), NULL_TREE);
2596 = tree_cons (NULL_TREE,
2597 add_objc_string (METHOD_ENCODING (entries),
2602 = tree_cons (NULL_TREE,
2603 build_constructor (type, nreverse (eltlist)), initlist);
2605 entries = TREE_CHAIN (entries);
2609 return build_constructor (build_array_type (type, 0), nreverse (initlist));
2612 /* struct objc_method_prototype_list {
2614 struct objc_method_prototype {
2621 build_method_prototype_list_template (list_type, size)
2625 tree objc_ivar_list_record;
2626 tree decl_specs, field_decl, field_decl_chain;
2628 /* Generate an unnamed struct definition. */
2630 objc_ivar_list_record = start_struct (RECORD_TYPE, NULL_TREE);
2632 /* int method_count; */
2634 decl_specs = build_tree_list (NULL_TREE, ridpointers[(int) RID_INT]);
2635 field_decl = get_identifier ("method_count");
2638 = grokfield (input_filename, lineno, field_decl, decl_specs, NULL_TREE);
2639 field_decl_chain = field_decl;
2641 /* struct objc_method method_list[]; */
2643 decl_specs = build_tree_list (NULL_TREE, list_type);
2644 field_decl = build_nt (ARRAY_REF, get_identifier ("method_list"),
2645 build_int_2 (size, 0));
2648 = grokfield (input_filename, lineno, field_decl, decl_specs, NULL_TREE);
2649 chainon (field_decl_chain, field_decl);
2651 finish_struct (objc_ivar_list_record, field_decl_chain, NULL_TREE);
2653 return objc_ivar_list_record;
2657 build_method_prototype_template ()
2660 tree decl_specs, field_decl, field_decl_chain;
2663 = start_struct (RECORD_TYPE, get_identifier (UTAG_METHOD_PROTOTYPE));
2665 /* struct objc_selector *_cmd; */
2666 decl_specs = tree_cons (NULL_TREE, xref_tag (RECORD_TYPE,
2667 get_identifier (TAG_SELECTOR)), NULL_TREE);
2668 field_decl = build1 (INDIRECT_REF, NULL_TREE, get_identifier ("_cmd"));
2671 = grokfield (input_filename, lineno, field_decl, decl_specs, NULL_TREE);
2672 field_decl_chain = field_decl;
2674 decl_specs = tree_cons (NULL_TREE, ridpointers[(int) RID_CHAR], NULL_TREE);
2676 = build1 (INDIRECT_REF, NULL_TREE, get_identifier ("method_types"));
2678 = grokfield (input_filename, lineno, field_decl, decl_specs, NULL_TREE);
2679 chainon (field_decl_chain, field_decl);
2681 finish_struct (proto_record, field_decl_chain, NULL_TREE);
2683 return proto_record;
2686 /* True if last call to forwarding_offset yielded a register offset. */
2687 static int offset_is_register;
2690 forwarding_offset (parm)
2693 int offset_in_bytes;
2695 if (GET_CODE (DECL_INCOMING_RTL (parm)) == MEM)
2697 rtx addr = XEXP (DECL_INCOMING_RTL (parm), 0);
2699 /* ??? Here we assume that the parm address is indexed
2700 off the frame pointer or arg pointer.
2701 If that is not true, we produce meaningless results,
2702 but do not crash. */
2703 if (GET_CODE (addr) == PLUS
2704 && GET_CODE (XEXP (addr, 1)) == CONST_INT)
2705 offset_in_bytes = INTVAL (XEXP (addr, 1));
2707 offset_in_bytes = 0;
2709 offset_in_bytes += OBJC_FORWARDING_STACK_OFFSET;
2710 offset_is_register = 0;
2712 else if (GET_CODE (DECL_INCOMING_RTL (parm)) == REG)
2714 int regno = REGNO (DECL_INCOMING_RTL (parm));
2715 offset_in_bytes = apply_args_register_offset (regno);
2716 offset_is_register = 1;
2721 /* This is the case where the parm is passed as an int or double
2722 and it is converted to a char, short or float and stored back
2723 in the parmlist. In this case, describe the parm
2724 with the variable's declared type, and adjust the address
2725 if the least significant bytes (which we are using) are not
2727 if (BYTES_BIG_ENDIAN && TREE_TYPE (parm) != DECL_ARG_TYPE (parm))
2728 offset_in_bytes += (GET_MODE_SIZE (TYPE_MODE (DECL_ARG_TYPE (parm)))
2729 - GET_MODE_SIZE (GET_MODE (DECL_RTL (parm))));
2731 return offset_in_bytes;
2735 encode_method_prototype (method_decl, func_decl)
2742 HOST_WIDE_INT max_parm_end = 0;
2746 /* ONEWAY and BYCOPY, for remote object are the only method qualifiers. */
2747 encode_type_qualifiers (TREE_PURPOSE (TREE_TYPE (method_decl)));
2750 encode_type (TREE_TYPE (TREE_TYPE (func_decl)),
2751 obstack_object_size (&util_obstack),
2752 OBJC_ENCODE_INLINE_DEFS);
2755 for (parms = DECL_ARGUMENTS (func_decl); parms;
2756 parms = TREE_CHAIN (parms))
2758 HOST_WIDE_INT parm_end = (forwarding_offset (parms)
2759 + int_size_in_bytes (TREE_TYPE (parms)));
2761 if (!offset_is_register && max_parm_end < parm_end)
2762 max_parm_end = parm_end;
2765 stack_size = max_parm_end - OBJC_FORWARDING_MIN_OFFSET;
2767 sprintf (buf, "%d", stack_size);
2768 obstack_grow (&util_obstack, buf, strlen (buf));
2770 user_args = METHOD_SEL_ARGS (method_decl);
2772 /* Argument types. */
2773 for (parms = DECL_ARGUMENTS (func_decl), i = 0; parms;
2774 parms = TREE_CHAIN (parms), i++)
2776 /* Process argument qualifiers for user supplied arguments. */
2779 encode_type_qualifiers (TREE_PURPOSE (TREE_TYPE (user_args)));
2780 user_args = TREE_CHAIN (user_args);
2784 encode_type (TREE_TYPE (parms),
2785 obstack_object_size (&util_obstack),
2786 OBJC_ENCODE_INLINE_DEFS);
2788 /* Compute offset. */
2789 sprintf (buf, "%d", forwarding_offset (parms));
2791 /* Indicate register. */
2792 if (offset_is_register)
2793 obstack_1grow (&util_obstack, '+');
2795 obstack_grow (&util_obstack, buf, strlen (buf));
2798 obstack_1grow (&util_obstack, '\0');
2799 result = get_identifier (obstack_finish (&util_obstack));
2800 obstack_free (&util_obstack, util_firstobj);
2805 generate_descriptor_table (type, name, size, list, proto)
2812 tree sc_spec, decl_specs, decl, initlist;
2814 sc_spec = tree_cons (NULL_TREE, ridpointers[(int) RID_STATIC], NULL_TREE);
2815 decl_specs = tree_cons (NULL_TREE, type, sc_spec);
2817 decl = start_decl (synth_id_with_class_suffix (name, proto),
2818 decl_specs, 1, NULL_TREE);
2819 DECL_CONTEXT (decl) = NULL_TREE;
2821 initlist = build_tree_list (NULL_TREE, build_int_2 (size, 0));
2822 initlist = tree_cons (NULL_TREE, list, initlist);
2824 finish_decl (decl, build_constructor (type, nreverse (initlist)),
2831 generate_method_descriptors (protocol)
2834 tree initlist, chain, method_list_template;
2835 tree cast, variable_length_type;
2838 if (!objc_method_prototype_template)
2839 objc_method_prototype_template = build_method_prototype_template ();
2841 cast = build_tree_list (build_tree_list (NULL_TREE, xref_tag (RECORD_TYPE,
2842 get_identifier (UTAG_METHOD_PROTOTYPE_LIST))),
2844 variable_length_type = groktypename (cast);
2846 chain = PROTOCOL_CLS_METHODS (protocol);
2849 size = list_length (chain);
2851 method_list_template
2852 = build_method_prototype_list_template (objc_method_prototype_template,
2856 = build_descriptor_table_initializer (objc_method_prototype_template,
2859 UOBJC_CLASS_METHODS_decl
2860 = generate_descriptor_table (method_list_template,
2861 "_OBJC_PROTOCOL_CLASS_METHODS",
2862 size, initlist, protocol);
2863 TREE_TYPE (UOBJC_CLASS_METHODS_decl) = variable_length_type;
2866 UOBJC_CLASS_METHODS_decl = 0;
2868 chain = PROTOCOL_NST_METHODS (protocol);
2871 size = list_length (chain);
2873 method_list_template
2874 = build_method_prototype_list_template (objc_method_prototype_template,
2877 = build_descriptor_table_initializer (objc_method_prototype_template,
2880 UOBJC_INSTANCE_METHODS_decl
2881 = generate_descriptor_table (method_list_template,
2882 "_OBJC_PROTOCOL_INSTANCE_METHODS",
2883 size, initlist, protocol);
2884 TREE_TYPE (UOBJC_INSTANCE_METHODS_decl) = variable_length_type;
2887 UOBJC_INSTANCE_METHODS_decl = 0;
2890 /* Generate a temporary FUNCTION_DECL node to be used in
2891 hack_method_prototype below. */
2894 build_tmp_function_decl ()
2896 tree decl_specs, expr_decl, parms;
2900 /* struct objc_object *objc_xxx (id, SEL, ...); */
2902 decl_specs = build_tree_list (NULL_TREE, objc_object_reference);
2903 push_parm_decl (build_tree_list
2904 (build_tree_list (decl_specs,
2905 build1 (INDIRECT_REF, NULL_TREE,
2909 decl_specs = build_tree_list (NULL_TREE, xref_tag (RECORD_TYPE,
2910 get_identifier (TAG_SELECTOR)));
2911 expr_decl = build1 (INDIRECT_REF, NULL_TREE, NULL_TREE);
2913 push_parm_decl (build_tree_list (build_tree_list (decl_specs, expr_decl),
2915 parms = get_parm_info (0);
2918 decl_specs = build_tree_list (NULL_TREE, objc_object_reference);
2919 sprintf (buffer, "__objc_tmp_%x", xxx++);
2920 expr_decl = build_nt (CALL_EXPR, get_identifier (buffer), parms, NULL_TREE);
2921 expr_decl = build1 (INDIRECT_REF, NULL_TREE, expr_decl);
2923 return define_decl (expr_decl, decl_specs);
2926 /* Generate the prototypes for protocol methods. This is used to
2927 generate method encodings for these.
2929 NST_METHODS is the method to generate a _DECL node for TMP_DECL is
2930 a decl node to be used. This is also where the return value is
2934 hack_method_prototype (nst_methods, tmp_decl)
2941 /* Hack to avoid problem with static typing of self arg. */
2942 TREE_SET_CODE (nst_methods, CLASS_METHOD_DECL);
2943 start_method_def (nst_methods);
2944 TREE_SET_CODE (nst_methods, INSTANCE_METHOD_DECL);
2946 if (METHOD_ADD_ARGS (nst_methods) == objc_ellipsis_node)
2947 parms = get_parm_info (0); /* we have a `, ...' */
2949 parms = get_parm_info (1); /* place a `void_at_end' */
2951 poplevel (0, 0, 0); /* Must be called BEFORE start_function. */
2953 /* Usually called from store_parm_decls -> init_function_start. */
2955 DECL_ARGUMENTS (tmp_decl) = TREE_PURPOSE (parms);
2956 current_function_decl = tmp_decl;
2959 /* Code taken from start_function. */
2960 tree restype = TREE_TYPE (TREE_TYPE (tmp_decl));
2961 /* Promote the value to int before returning it. */
2962 if (TREE_CODE (restype) == INTEGER_TYPE
2963 && TYPE_PRECISION (restype) < TYPE_PRECISION (integer_type_node))
2964 restype = integer_type_node;
2965 DECL_RESULT (tmp_decl) = build_decl (RESULT_DECL, 0, restype);
2968 for (parm = DECL_ARGUMENTS (tmp_decl); parm; parm = TREE_CHAIN (parm))
2969 DECL_CONTEXT (parm) = tmp_decl;
2971 init_function_start (tmp_decl, "objc-act", 0);
2973 /* Typically called from expand_function_start for function definitions. */
2974 assign_parms (tmp_decl);
2976 /* install return type */
2977 TREE_TYPE (TREE_TYPE (tmp_decl)) = groktypename (TREE_TYPE (nst_methods));
2982 generate_protocol_references (plist)
2987 /* Forward declare protocols referenced. */
2988 for (lproto = plist; lproto; lproto = TREE_CHAIN (lproto))
2990 tree proto = TREE_VALUE (lproto);
2992 if (TREE_CODE (proto) == PROTOCOL_INTERFACE_TYPE
2993 && PROTOCOL_NAME (proto))
2995 if (! PROTOCOL_FORWARD_DECL (proto))
2996 build_protocol_reference (proto);
2998 if (PROTOCOL_LIST (proto))
2999 generate_protocol_references (PROTOCOL_LIST (proto));
3005 generate_protocols ()
3007 tree p, tmp_decl, encoding;
3008 tree sc_spec, decl_specs, decl;
3009 tree initlist, protocol_name_expr, refs_decl, refs_expr;
3012 tmp_decl = build_tmp_function_decl ();
3014 if (! objc_protocol_template)
3015 objc_protocol_template = build_protocol_template ();
3017 /* If a protocol was directly referenced, pull in indirect references. */
3018 for (p = protocol_chain; p; p = TREE_CHAIN (p))
3019 if (PROTOCOL_FORWARD_DECL (p) && PROTOCOL_LIST (p))
3020 generate_protocol_references (PROTOCOL_LIST (p));
3022 for (p = protocol_chain; p; p = TREE_CHAIN (p))
3024 tree nst_methods = PROTOCOL_NST_METHODS (p);
3025 tree cls_methods = PROTOCOL_CLS_METHODS (p);
3027 /* If protocol wasn't referenced, don't generate any code. */
3028 if (! PROTOCOL_FORWARD_DECL (p))
3031 /* Make sure we link in the Protocol class. */
3032 add_class_reference (get_identifier (PROTOCOL_OBJECT_CLASS_NAME));
3036 if (! METHOD_ENCODING (nst_methods))
3038 hack_method_prototype (nst_methods, tmp_decl);
3039 encoding = encode_method_prototype (nst_methods, tmp_decl);
3040 METHOD_ENCODING (nst_methods) = encoding;
3042 nst_methods = TREE_CHAIN (nst_methods);
3047 if (! METHOD_ENCODING (cls_methods))
3049 hack_method_prototype (cls_methods, tmp_decl);
3050 encoding = encode_method_prototype (cls_methods, tmp_decl);
3051 METHOD_ENCODING (cls_methods) = encoding;
3054 cls_methods = TREE_CHAIN (cls_methods);
3056 generate_method_descriptors (p);
3058 if (PROTOCOL_LIST (p))
3059 refs_decl = generate_protocol_list (p);
3063 /* static struct objc_protocol _OBJC_PROTOCOL_<mumble>; */
3065 sc_spec = tree_cons (NULL_TREE, ridpointers[(int) RID_STATIC],
3067 decl_specs = tree_cons (NULL_TREE, objc_protocol_template, sc_spec);
3069 decl = start_decl (synth_id_with_class_suffix ("_OBJC_PROTOCOL", p),
3070 decl_specs, 1, NULL_TREE);
3072 DECL_CONTEXT (decl) = NULL_TREE;
3074 protocol_name_expr = add_objc_string (PROTOCOL_NAME (p), class_names);
3080 (build_tree_list (build_tree_list (NULL_TREE,
3081 objc_protocol_template),
3082 build1 (INDIRECT_REF, NULL_TREE,
3083 build1 (INDIRECT_REF, NULL_TREE,
3086 refs_expr = build_unary_op (ADDR_EXPR, refs_decl, 0);
3087 TREE_TYPE (refs_expr) = cast_type2;
3090 refs_expr = build_int_2 (0, 0);
3092 /* UOBJC_INSTANCE_METHODS_decl/UOBJC_CLASS_METHODS_decl are set
3093 by generate_method_descriptors, which is called above. */
3094 initlist = build_protocol_initializer (TREE_TYPE (decl),
3095 protocol_name_expr, refs_expr,
3096 UOBJC_INSTANCE_METHODS_decl,
3097 UOBJC_CLASS_METHODS_decl);
3098 finish_decl (decl, initlist, NULL_TREE);
3100 /* Mark the decl as used to avoid "defined but not used" warning. */
3101 TREE_USED (decl) = 1;
3106 build_protocol_initializer (type, protocol_name, protocol_list,
3107 instance_methods, class_methods)
3111 tree instance_methods;
3114 tree initlist = NULL_TREE, expr;
3117 cast_type = groktypename
3119 (build_tree_list (NULL_TREE,
3120 xref_tag (RECORD_TYPE,
3121 get_identifier (UTAG_CLASS))),
3122 build1 (INDIRECT_REF, NULL_TREE, NULL_TREE)));
3124 /* Filling the "isa" in with one allows the runtime system to
3125 detect that the version change...should remove before final release. */
3127 expr = build_int_2 (PROTOCOL_VERSION, 0);
3128 TREE_TYPE (expr) = cast_type;
3129 initlist = tree_cons (NULL_TREE, expr, initlist);
3130 initlist = tree_cons (NULL_TREE, protocol_name, initlist);
3131 initlist = tree_cons (NULL_TREE, protocol_list, initlist);
3133 if (!instance_methods)
3134 initlist = tree_cons (NULL_TREE, build_int_2 (0, 0), initlist);
3137 expr = build_unary_op (ADDR_EXPR, instance_methods, 0);
3138 initlist = tree_cons (NULL_TREE, expr, initlist);
3142 initlist = tree_cons (NULL_TREE, build_int_2 (0, 0), initlist);
3145 expr = build_unary_op (ADDR_EXPR, class_methods, 0);
3146 initlist = tree_cons (NULL_TREE, expr, initlist);
3149 return build_constructor (type, nreverse (initlist));
3152 /* struct objc_category {
3153 char *category_name;
3155 struct objc_method_list *instance_methods;
3156 struct objc_method_list *class_methods;
3157 struct objc_protocol_list *protocols;
3161 build_category_template ()
3163 tree decl_specs, field_decl, field_decl_chain;
3165 objc_category_template = start_struct (RECORD_TYPE,
3166 get_identifier (UTAG_CATEGORY));
3167 /* char *category_name; */
3169 decl_specs = build_tree_list (NULL_TREE, ridpointers[(int) RID_CHAR]);
3171 = build1 (INDIRECT_REF, NULL_TREE, get_identifier ("category_name"));
3173 = grokfield (input_filename, lineno, field_decl, decl_specs, NULL_TREE);
3174 field_decl_chain = field_decl;
3176 /* char *class_name; */
3178 decl_specs = build_tree_list (NULL_TREE, ridpointers[(int) RID_CHAR]);
3179 field_decl = build1 (INDIRECT_REF, NULL_TREE, get_identifier ("class_name"));
3181 = grokfield (input_filename, lineno, field_decl, decl_specs, NULL_TREE);
3182 chainon (field_decl_chain, field_decl);
3184 /* struct objc_method_list *instance_methods; */
3186 decl_specs = build_tree_list (NULL_TREE,
3187 xref_tag (RECORD_TYPE,
3188 get_identifier (UTAG_METHOD_LIST)));
3190 = build1 (INDIRECT_REF, NULL_TREE, get_identifier ("instance_methods"));
3192 = grokfield (input_filename, lineno, field_decl, decl_specs, NULL_TREE);
3193 chainon (field_decl_chain, field_decl);
3195 /* struct objc_method_list *class_methods; */
3197 decl_specs = build_tree_list (NULL_TREE,
3198 xref_tag (RECORD_TYPE,
3199 get_identifier (UTAG_METHOD_LIST)));
3201 = build1 (INDIRECT_REF, NULL_TREE, get_identifier ("class_methods"));
3203 = grokfield (input_filename, lineno, field_decl, decl_specs, NULL_TREE);
3204 chainon (field_decl_chain, field_decl);
3206 /* struct objc_protocol **protocol_list; */
3208 decl_specs = build_tree_list (NULL_TREE,
3209 xref_tag (RECORD_TYPE,
3210 get_identifier (UTAG_PROTOCOL)));
3212 = build1 (INDIRECT_REF, NULL_TREE, get_identifier ("protocol_list"));
3213 field_decl = build1 (INDIRECT_REF, NULL_TREE, field_decl);
3215 = grokfield (input_filename, lineno, field_decl, decl_specs, NULL_TREE);
3216 chainon (field_decl_chain, field_decl);
3218 finish_struct (objc_category_template, field_decl_chain, NULL_TREE);
3221 /* struct objc_selector {
3227 build_selector_template ()
3230 tree decl_specs, field_decl, field_decl_chain;
3232 objc_selector_template
3233 = start_struct (RECORD_TYPE, get_identifier (UTAG_SELECTOR));
3237 decl_specs = build_tree_list (NULL_TREE, ridpointers[(int) RID_VOID]);
3238 field_decl = build1 (INDIRECT_REF, NULL_TREE, get_identifier ("sel_id"));
3240 = grokfield (input_filename, lineno, field_decl, decl_specs, NULL_TREE);
3241 field_decl_chain = field_decl;
3243 /* char *sel_type; */
3245 decl_specs = build_tree_list (NULL_TREE, ridpointers[(int) RID_CHAR]);
3246 field_decl = build1 (INDIRECT_REF, NULL_TREE, get_identifier ("sel_type"));
3248 = grokfield (input_filename, lineno, field_decl, decl_specs, NULL_TREE);
3249 chainon (field_decl_chain, field_decl);
3251 finish_struct (objc_selector_template, field_decl_chain, NULL_TREE);
3254 /* struct objc_class {
3255 struct objc_class *isa;
3256 struct objc_class *super_class;
3261 struct objc_ivar_list *ivars;
3262 struct objc_method_list *methods;
3263 if (flag_next_runtime)
3264 struct objc_cache *cache;
3266 struct sarray *dtable;
3267 struct objc_class *subclass_list;
3268 struct objc_class *sibling_class;
3270 struct objc_protocol_list *protocols;
3271 void *gc_object_type;
3275 build_class_template ()
3277 tree decl_specs, field_decl, field_decl_chain;
3280 = start_struct (RECORD_TYPE, get_identifier (UTAG_CLASS));
3282 /* struct objc_class *isa; */
3284 decl_specs = build_tree_list (NULL_TREE, objc_class_template);
3285 field_decl = build1 (INDIRECT_REF, NULL_TREE, get_identifier ("isa"));
3287 = grokfield (input_filename, lineno, field_decl, decl_specs, NULL_TREE);
3288 field_decl_chain = field_decl;
3290 /* struct objc_class *super_class; */
3292 decl_specs = build_tree_list (NULL_TREE, objc_class_template);
3294 = build1 (INDIRECT_REF, NULL_TREE, get_identifier ("super_class"));
3296 = grokfield (input_filename, lineno, field_decl, decl_specs, NULL_TREE);
3297 chainon (field_decl_chain, field_decl);
3301 decl_specs = build_tree_list (NULL_TREE, ridpointers[(int) RID_CHAR]);
3302 field_decl = build1 (INDIRECT_REF, NULL_TREE, get_identifier ("name"));
3304 = grokfield (input_filename, lineno, field_decl, decl_specs, NULL_TREE);
3305 chainon (field_decl_chain, field_decl);
3309 decl_specs = build_tree_list (NULL_TREE, ridpointers[(int) RID_LONG]);
3310 field_decl = get_identifier ("version");
3312 = grokfield (input_filename, lineno, field_decl, decl_specs, NULL_TREE);
3313 chainon (field_decl_chain, field_decl);
3317 decl_specs = build_tree_list (NULL_TREE, ridpointers[(int) RID_LONG]);
3318 field_decl = get_identifier ("info");
3320 = grokfield (input_filename, lineno, field_decl, decl_specs, NULL_TREE);
3321 chainon (field_decl_chain, field_decl);
3323 /* long instance_size; */
3325 decl_specs = build_tree_list (NULL_TREE, ridpointers[(int) RID_LONG]);
3326 field_decl = get_identifier ("instance_size");
3328 = grokfield (input_filename, lineno, field_decl, decl_specs, NULL_TREE);
3329 chainon (field_decl_chain, field_decl);
3331 /* struct objc_ivar_list *ivars; */
3333 decl_specs = build_tree_list (NULL_TREE,
3334 xref_tag (RECORD_TYPE,
3335 get_identifier (UTAG_IVAR_LIST)));
3336 field_decl = build1 (INDIRECT_REF, NULL_TREE, get_identifier ("ivars"));
3338 = grokfield (input_filename, lineno, field_decl, decl_specs, NULL_TREE);
3339 chainon (field_decl_chain, field_decl);
3341 /* struct objc_method_list *methods; */
3343 decl_specs = build_tree_list (NULL_TREE,
3344 xref_tag (RECORD_TYPE,
3345 get_identifier (UTAG_METHOD_LIST)));
3346 field_decl = build1 (INDIRECT_REF, NULL_TREE, get_identifier ("methods"));
3348 = grokfield (input_filename, lineno, field_decl, decl_specs, NULL_TREE);
3349 chainon (field_decl_chain, field_decl);
3351 if (flag_next_runtime)
3353 /* struct objc_cache *cache; */
3355 decl_specs = build_tree_list (NULL_TREE,
3356 xref_tag (RECORD_TYPE,
3357 get_identifier ("objc_cache")));
3358 field_decl = build1 (INDIRECT_REF, NULL_TREE, get_identifier ("cache"));
3359 field_decl = grokfield (input_filename, lineno, field_decl,
3360 decl_specs, NULL_TREE);
3361 chainon (field_decl_chain, field_decl);
3365 /* struct sarray *dtable; */
3367 decl_specs = build_tree_list (NULL_TREE,
3368 xref_tag (RECORD_TYPE,
3369 get_identifier ("sarray")));
3370 field_decl = build1 (INDIRECT_REF, NULL_TREE, get_identifier ("dtable"));
3371 field_decl = grokfield (input_filename, lineno, field_decl,
3372 decl_specs, NULL_TREE);
3373 chainon (field_decl_chain, field_decl);
3375 /* struct objc_class *subclass_list; */
3377 decl_specs = build_tree_list (NULL_TREE, objc_class_template);
3379 = build1 (INDIRECT_REF, NULL_TREE, get_identifier ("subclass_list"));
3380 field_decl = grokfield (input_filename, lineno, field_decl,
3381 decl_specs, NULL_TREE);
3382 chainon (field_decl_chain, field_decl);
3384 /* struct objc_class *sibling_class; */
3386 decl_specs = build_tree_list (NULL_TREE, objc_class_template);
3388 = build1 (INDIRECT_REF, NULL_TREE, get_identifier ("sibling_class"));
3389 field_decl = grokfield (input_filename, lineno, field_decl,
3390 decl_specs, NULL_TREE);
3391 chainon (field_decl_chain, field_decl);
3394 /* struct objc_protocol **protocol_list; */
3396 decl_specs = build_tree_list (NULL_TREE,
3397 xref_tag (RECORD_TYPE,
3398 get_identifier (UTAG_PROTOCOL)));
3400 = build1 (INDIRECT_REF, NULL_TREE, get_identifier ("protocol_list"));
3402 = build1 (INDIRECT_REF, NULL_TREE, field_decl);
3403 field_decl = grokfield (input_filename, lineno, field_decl,
3404 decl_specs, NULL_TREE);
3405 chainon (field_decl_chain, field_decl);
3409 decl_specs = build_tree_list (NULL_TREE, ridpointers[(int) RID_VOID]);
3410 field_decl = build1 (INDIRECT_REF, NULL_TREE, get_identifier ("sel_id"));
3412 = grokfield (input_filename, lineno, field_decl, decl_specs, NULL_TREE);
3413 chainon (field_decl_chain, field_decl);
3415 /* void *gc_object_type; */
3417 decl_specs = build_tree_list (NULL_TREE, ridpointers[(int) RID_VOID]);
3418 field_decl = build1 (INDIRECT_REF, NULL_TREE, get_identifier ("gc_object_type"));
3420 = grokfield (input_filename, lineno, field_decl, decl_specs, NULL_TREE);
3421 chainon (field_decl_chain, field_decl);
3423 finish_struct (objc_class_template, field_decl_chain, NULL_TREE);
3426 /* Generate appropriate forward declarations for an implementation. */
3429 synth_forward_declarations ()
3431 tree sc_spec, decl_specs, an_id;
3433 /* extern struct objc_class _OBJC_CLASS_<my_name>; */
3435 an_id = synth_id_with_class_suffix ("_OBJC_CLASS", objc_implementation_context);
3437 sc_spec = build_tree_list (NULL_TREE, ridpointers[(int) RID_EXTERN]);
3438 decl_specs = tree_cons (NULL_TREE, objc_class_template, sc_spec);
3439 UOBJC_CLASS_decl = define_decl (an_id, decl_specs);
3440 TREE_USED (UOBJC_CLASS_decl) = 1;
3441 DECL_ARTIFICIAL (UOBJC_CLASS_decl) = 1;
3443 /* extern struct objc_class _OBJC_METACLASS_<my_name>; */
3445 an_id = synth_id_with_class_suffix ("_OBJC_METACLASS",
3446 objc_implementation_context);
3448 UOBJC_METACLASS_decl = define_decl (an_id, decl_specs);
3449 TREE_USED (UOBJC_METACLASS_decl) = 1;
3450 DECL_ARTIFICIAL(UOBJC_METACLASS_decl) = 1;
3452 /* Pre-build the following entities - for speed/convenience. */
3454 an_id = get_identifier ("super_class");
3455 ucls_super_ref = build_component_ref (UOBJC_CLASS_decl, an_id);
3456 uucls_super_ref = build_component_ref (UOBJC_METACLASS_decl, an_id);
3460 error_with_ivar (message, decl, rawdecl)
3461 const char *message;
3467 report_error_function (DECL_SOURCE_FILE (decl));
3469 error_with_file_and_line (DECL_SOURCE_FILE (decl),
3470 DECL_SOURCE_LINE (decl),
3472 message, gen_declaration (rawdecl, errbuf));
3476 #define USERTYPE(t) \
3477 (TREE_CODE (t) == RECORD_TYPE || TREE_CODE (t) == UNION_TYPE \
3478 || TREE_CODE (t) == ENUMERAL_TYPE)
3481 check_ivars (inter, imp)
3485 tree intdecls = CLASS_IVARS (inter);
3486 tree impdecls = CLASS_IVARS (imp);
3487 tree rawintdecls = CLASS_RAW_IVARS (inter);
3488 tree rawimpdecls = CLASS_RAW_IVARS (imp);
3494 if (intdecls == 0 && impdecls == 0)
3496 if (intdecls == 0 || impdecls == 0)
3498 error ("inconsistent instance variable specification");
3502 t1 = TREE_TYPE (intdecls); t2 = TREE_TYPE (impdecls);
3504 if (!comptypes (t1, t2))
3506 if (DECL_NAME (intdecls) == DECL_NAME (impdecls))
3508 error_with_ivar ("conflicting instance variable type",
3509 impdecls, rawimpdecls);
3510 error_with_ivar ("previous declaration of",
3511 intdecls, rawintdecls);
3513 else /* both the type and the name don't match */
3515 error ("inconsistent instance variable specification");
3520 else if (DECL_NAME (intdecls) != DECL_NAME (impdecls))
3522 error_with_ivar ("conflicting instance variable name",
3523 impdecls, rawimpdecls);
3524 error_with_ivar ("previous declaration of",
3525 intdecls, rawintdecls);
3528 intdecls = TREE_CHAIN (intdecls);
3529 impdecls = TREE_CHAIN (impdecls);
3530 rawintdecls = TREE_CHAIN (rawintdecls);
3531 rawimpdecls = TREE_CHAIN (rawimpdecls);
3535 /* Set super_type to the data type node for struct objc_super *,
3536 first defining struct objc_super itself.
3537 This needs to be done just once per compilation. */
3540 build_super_template ()
3542 tree record, decl_specs, field_decl, field_decl_chain;
3544 record = start_struct (RECORD_TYPE, get_identifier (UTAG_SUPER));
3546 /* struct objc_object *self; */
3548 decl_specs = build_tree_list (NULL_TREE, objc_object_reference);
3549 field_decl = get_identifier ("self");
3550 field_decl = build1 (INDIRECT_REF, NULL_TREE, field_decl);
3551 field_decl = grokfield (input_filename, lineno,
3552 field_decl, decl_specs, NULL_TREE);
3553 field_decl_chain = field_decl;
3555 /* struct objc_class *class; */
3557 decl_specs = get_identifier (UTAG_CLASS);
3558 decl_specs = build_tree_list (NULL_TREE, xref_tag (RECORD_TYPE, decl_specs));
3559 field_decl = build1 (INDIRECT_REF, NULL_TREE, get_identifier ("class"));
3561 field_decl = grokfield (input_filename, lineno,
3562 field_decl, decl_specs, NULL_TREE);
3563 chainon (field_decl_chain, field_decl);
3565 finish_struct (record, field_decl_chain, NULL_TREE);
3567 /* `struct objc_super *' */
3568 super_type = groktypename (build_tree_list (build_tree_list (NULL_TREE,
3570 build1 (INDIRECT_REF,
3571 NULL_TREE, NULL_TREE)));
3575 /* struct objc_ivar {
3582 build_ivar_template ()
3584 tree objc_ivar_id, objc_ivar_record;
3585 tree decl_specs, field_decl, field_decl_chain;
3587 objc_ivar_id = get_identifier (UTAG_IVAR);
3588 objc_ivar_record = start_struct (RECORD_TYPE, objc_ivar_id);
3590 /* char *ivar_name; */
3592 decl_specs = build_tree_list (NULL_TREE, ridpointers[(int) RID_CHAR]);
3593 field_decl = build1 (INDIRECT_REF, NULL_TREE, get_identifier ("ivar_name"));
3595 field_decl = grokfield (input_filename, lineno, field_decl,
3596 decl_specs, NULL_TREE);
3597 field_decl_chain = field_decl;
3599 /* char *ivar_type; */
3601 decl_specs = build_tree_list (NULL_TREE, ridpointers[(int) RID_CHAR]);
3602 field_decl = build1 (INDIRECT_REF, NULL_TREE, get_identifier ("ivar_type"));
3604 field_decl = grokfield (input_filename, lineno, field_decl,
3605 decl_specs, NULL_TREE);
3606 chainon (field_decl_chain, field_decl);
3608 /* int ivar_offset; */
3610 decl_specs = build_tree_list (NULL_TREE, ridpointers[(int) RID_INT]);
3611 field_decl = get_identifier ("ivar_offset");
3613 field_decl = grokfield (input_filename, lineno, field_decl,
3614 decl_specs, NULL_TREE);
3615 chainon (field_decl_chain, field_decl);
3617 finish_struct (objc_ivar_record, field_decl_chain, NULL_TREE);
3619 return objc_ivar_record;
3624 struct objc_ivar ivar_list[ivar_count];
3628 build_ivar_list_template (list_type, size)
3632 tree objc_ivar_list_record;
3633 tree decl_specs, field_decl, field_decl_chain;
3635 objc_ivar_list_record = start_struct (RECORD_TYPE, NULL_TREE);
3637 /* int ivar_count; */
3639 decl_specs = build_tree_list (NULL_TREE, ridpointers[(int) RID_INT]);
3640 field_decl = get_identifier ("ivar_count");
3642 field_decl = grokfield (input_filename, lineno, field_decl,
3643 decl_specs, NULL_TREE);
3644 field_decl_chain = field_decl;
3646 /* struct objc_ivar ivar_list[]; */
3648 decl_specs = build_tree_list (NULL_TREE, list_type);
3649 field_decl = build_nt (ARRAY_REF, get_identifier ("ivar_list"),
3650 build_int_2 (size, 0));
3652 field_decl = grokfield (input_filename, lineno,
3653 field_decl, decl_specs, NULL_TREE);
3654 chainon (field_decl_chain, field_decl);
3656 finish_struct (objc_ivar_list_record, field_decl_chain, NULL_TREE);
3658 return objc_ivar_list_record;
3664 struct objc_method method_list[method_count];
3668 build_method_list_template (list_type, size)
3672 tree objc_ivar_list_record;
3673 tree decl_specs, field_decl, field_decl_chain;
3675 objc_ivar_list_record = start_struct (RECORD_TYPE, NULL_TREE);
3677 /* int method_next; */
3682 xref_tag (RECORD_TYPE,
3683 get_identifier (UTAG_METHOD_PROTOTYPE_LIST)));
3685 = build1 (INDIRECT_REF, NULL_TREE, get_identifier ("method_next"));
3686 field_decl = grokfield (input_filename, lineno, field_decl,
3687 decl_specs, NULL_TREE);
3688 field_decl_chain = field_decl;
3690 /* int method_count; */
3692 decl_specs = build_tree_list (NULL_TREE, ridpointers[(int) RID_INT]);
3693 field_decl = get_identifier ("method_count");
3695 field_decl = grokfield (input_filename, lineno,
3696 field_decl, decl_specs, NULL_TREE);
3697 chainon (field_decl_chain, field_decl);
3699 /* struct objc_method method_list[]; */
3701 decl_specs = build_tree_list (NULL_TREE, list_type);
3702 field_decl = build_nt (ARRAY_REF, get_identifier ("method_list"),
3703 build_int_2 (size, 0));
3705 field_decl = grokfield (input_filename, lineno,
3706 field_decl, decl_specs, NULL_TREE);
3707 chainon (field_decl_chain, field_decl);
3709 finish_struct (objc_ivar_list_record, field_decl_chain, NULL_TREE);
3711 return objc_ivar_list_record;
3715 build_ivar_list_initializer (type, field_decl)
3719 tree initlist = NULL_TREE;
3723 tree ivar = NULL_TREE;
3726 if (DECL_NAME (field_decl))
3727 ivar = tree_cons (NULL_TREE,
3728 add_objc_string (DECL_NAME (field_decl),
3732 /* Unnamed bit-field ivar (yuck). */
3733 ivar = tree_cons (NULL_TREE, build_int_2 (0, 0), ivar);
3736 encode_field_decl (field_decl,
3737 obstack_object_size (&util_obstack),
3738 OBJC_ENCODE_DONT_INLINE_DEFS);
3740 /* Null terminate string. */
3741 obstack_1grow (&util_obstack, 0);
3745 add_objc_string (get_identifier (obstack_finish (&util_obstack)),
3748 obstack_free (&util_obstack, util_firstobj);
3751 ivar = tree_cons (NULL_TREE, byte_position (field_decl), ivar);
3752 initlist = tree_cons (NULL_TREE,
3753 build_constructor (type, nreverse (ivar)),
3756 field_decl = TREE_CHAIN (field_decl);
3760 return build_constructor (build_array_type (type, 0), nreverse (initlist));
3764 generate_ivars_list (type, name, size, list)
3770 tree sc_spec, decl_specs, decl, initlist;
3772 sc_spec = tree_cons (NULL_TREE, ridpointers[(int) RID_STATIC], NULL_TREE);
3773 decl_specs = tree_cons (NULL_TREE, type, sc_spec);
3775 decl = start_decl (synth_id_with_class_suffix (name, objc_implementation_context),
3776 decl_specs, 1, NULL_TREE);
3778 initlist = build_tree_list (NULL_TREE, build_int_2 (size, 0));
3779 initlist = tree_cons (NULL_TREE, list, initlist);
3782 build_constructor (TREE_TYPE (decl), nreverse (initlist)),
3789 generate_ivar_lists ()
3791 tree initlist, ivar_list_template, chain;
3792 tree cast, variable_length_type;
3795 generating_instance_variables = 1;
3797 if (!objc_ivar_template)
3798 objc_ivar_template = build_ivar_template ();
3802 (build_tree_list (NULL_TREE, xref_tag (RECORD_TYPE,
3803 get_identifier (UTAG_IVAR_LIST))),
3805 variable_length_type = groktypename (cast);
3807 /* Only generate class variables for the root of the inheritance
3808 hierarchy since these will be the same for every class. */
3810 if (CLASS_SUPER_NAME (implementation_template) == NULL_TREE
3811 && (chain = TYPE_FIELDS (objc_class_template)))
3813 size = list_length (chain);
3815 ivar_list_template = build_ivar_list_template (objc_ivar_template, size);
3816 initlist = build_ivar_list_initializer (objc_ivar_template, chain);
3818 UOBJC_CLASS_VARIABLES_decl
3819 = generate_ivars_list (ivar_list_template, "_OBJC_CLASS_VARIABLES",
3821 TREE_TYPE (UOBJC_CLASS_VARIABLES_decl) = variable_length_type;
3824 UOBJC_CLASS_VARIABLES_decl = 0;
3826 chain = CLASS_IVARS (implementation_template);
3829 size = list_length (chain);
3830 ivar_list_template = build_ivar_list_template (objc_ivar_template, size);
3831 initlist = build_ivar_list_initializer (objc_ivar_template, chain);
3833 UOBJC_INSTANCE_VARIABLES_decl
3834 = generate_ivars_list (ivar_list_template, "_OBJC_INSTANCE_VARIABLES",
3836 TREE_TYPE (UOBJC_INSTANCE_VARIABLES_decl) = variable_length_type;
3839 UOBJC_INSTANCE_VARIABLES_decl = 0;
3841 generating_instance_variables = 0;
3845 build_dispatch_table_initializer (type, entries)
3849 tree initlist = NULL_TREE;
3853 tree elemlist = NULL_TREE;
3855 elemlist = tree_cons (NULL_TREE,
3856 build_selector (METHOD_SEL_NAME (entries)),
3859 /* Generate the method encoding if we don't have one already. */
3860 if (! METHOD_ENCODING (entries))
3861 METHOD_ENCODING (entries) =
3862 encode_method_def (METHOD_DEFINITION (entries));
3864 elemlist = tree_cons (NULL_TREE,
3865 add_objc_string (METHOD_ENCODING (entries),
3869 elemlist = tree_cons (NULL_TREE,
3870 build_unary_op (ADDR_EXPR,
3871 METHOD_DEFINITION (entries), 1),
3874 initlist = tree_cons (NULL_TREE,
3875 build_constructor (type, nreverse (elemlist)),
3878 entries = TREE_CHAIN (entries);
3882 return build_constructor (build_array_type (type, 0), nreverse (initlist));
3885 /* To accomplish method prototyping without generating all kinds of
3886 inane warnings, the definition of the dispatch table entries were
3889 struct objc_method { SEL _cmd; ...; id (*_imp)(); };
3891 struct objc_method { SEL _cmd; ...; void *_imp; }; */
3894 build_method_template ()
3897 tree decl_specs, field_decl, field_decl_chain;
3899 _SLT_record = start_struct (RECORD_TYPE, get_identifier (UTAG_METHOD));
3901 /* struct objc_selector *_cmd; */
3902 decl_specs = tree_cons (NULL_TREE,
3903 xref_tag (RECORD_TYPE,
3904 get_identifier (TAG_SELECTOR)),
3906 field_decl = build1 (INDIRECT_REF, NULL_TREE, get_identifier ("_cmd"));
3908 field_decl = grokfield (input_filename, lineno, field_decl,
3909 decl_specs, NULL_TREE);
3910 field_decl_chain = field_decl;
3912 decl_specs = tree_cons (NULL_TREE, ridpointers[(int) RID_CHAR], NULL_TREE);
3913 field_decl = build1 (INDIRECT_REF, NULL_TREE,
3914 get_identifier ("method_types"));
3915 field_decl = grokfield (input_filename, lineno, field_decl,
3916 decl_specs, NULL_TREE);
3917 chainon (field_decl_chain, field_decl);
3921 decl_specs = tree_cons (NULL_TREE, ridpointers[(int) RID_VOID], NULL_TREE);
3922 field_decl = build1 (INDIRECT_REF, NULL_TREE, get_identifier ("_imp"));
3923 field_decl = grokfield (input_filename, lineno, field_decl,
3924 decl_specs, NULL_TREE);
3925 chainon (field_decl_chain, field_decl);
3927 finish_struct (_SLT_record, field_decl_chain, NULL_TREE);
3934 generate_dispatch_table (type, name, size, list)
3940 tree sc_spec, decl_specs, decl, initlist;
3942 sc_spec = tree_cons (NULL_TREE, ridpointers[(int) RID_STATIC], NULL_TREE);
3943 decl_specs = tree_cons (NULL_TREE, type, sc_spec);
3945 decl = start_decl (synth_id_with_class_suffix (name, objc_implementation_context),
3946 decl_specs, 1, NULL_TREE);
3948 initlist = build_tree_list (NULL_TREE, build_int_2 (0, 0));
3949 initlist = tree_cons (NULL_TREE, build_int_2 (size, 0), initlist);
3950 initlist = tree_cons (NULL_TREE, list, initlist);
3953 build_constructor (TREE_TYPE (decl), nreverse (initlist)),
3960 generate_dispatch_tables ()
3962 tree initlist, chain, method_list_template;
3963 tree cast, variable_length_type;
3966 if (!objc_method_template)
3967 objc_method_template = build_method_template ();
3971 (build_tree_list (NULL_TREE,
3972 xref_tag (RECORD_TYPE,
3973 get_identifier (UTAG_METHOD_LIST))),
3976 variable_length_type = groktypename (cast);
3978 chain = CLASS_CLS_METHODS (objc_implementation_context);
3981 size = list_length (chain);
3983 method_list_template
3984 = build_method_list_template (objc_method_template, size);
3986 = build_dispatch_table_initializer (objc_method_template, chain);
3988 UOBJC_CLASS_METHODS_decl
3989 = generate_dispatch_table (method_list_template,
3990 ((TREE_CODE (objc_implementation_context)
3991 == CLASS_IMPLEMENTATION_TYPE)
3992 ? "_OBJC_CLASS_METHODS"
3993 : "_OBJC_CATEGORY_CLASS_METHODS"),
3995 TREE_TYPE (UOBJC_CLASS_METHODS_decl) = variable_length_type;
3998 UOBJC_CLASS_METHODS_decl = 0;
4000 chain = CLASS_NST_METHODS (objc_implementation_context);
4003 size = list_length (chain);
4005 method_list_template
4006 = build_method_list_template (objc_method_template, size);
4008 = build_dispatch_table_initializer (objc_method_template, chain);
4010 if (TREE_CODE (objc_implementation_context) == CLASS_IMPLEMENTATION_TYPE)
4011 UOBJC_INSTANCE_METHODS_decl
4012 = generate_dispatch_table (method_list_template,
4013 "_OBJC_INSTANCE_METHODS",
4016 /* We have a category. */
4017 UOBJC_INSTANCE_METHODS_decl
4018 = generate_dispatch_table (method_list_template,
4019 "_OBJC_CATEGORY_INSTANCE_METHODS",
4021 TREE_TYPE (UOBJC_INSTANCE_METHODS_decl) = variable_length_type;
4024 UOBJC_INSTANCE_METHODS_decl = 0;
4028 generate_protocol_list (i_or_p)
4031 tree initlist, decl_specs, sc_spec;
4032 tree refs_decl, expr_decl, lproto, e, plist;
4036 if (TREE_CODE (i_or_p) == CLASS_INTERFACE_TYPE
4037 || TREE_CODE (i_or_p) == CATEGORY_INTERFACE_TYPE)
4038 plist = CLASS_PROTOCOL_LIST (i_or_p);
4039 else if (TREE_CODE (i_or_p) == PROTOCOL_INTERFACE_TYPE)
4040 plist = PROTOCOL_LIST (i_or_p);
4044 cast_type = groktypename
4046 (build_tree_list (NULL_TREE,
4047 xref_tag (RECORD_TYPE,
4048 get_identifier (UTAG_PROTOCOL))),
4049 build1 (INDIRECT_REF, NULL_TREE, NULL_TREE)));
4052 for (lproto = plist; lproto; lproto = TREE_CHAIN (lproto))
4053 if (TREE_CODE (TREE_VALUE (lproto)) == PROTOCOL_INTERFACE_TYPE
4054 && PROTOCOL_FORWARD_DECL (TREE_VALUE (lproto)))
4057 /* Build initializer. */
4058 initlist = tree_cons (NULL_TREE, build_int_2 (0, 0), NULL_TREE);
4060 e = build_int_2 (size, 0);
4061 TREE_TYPE (e) = cast_type;
4062 initlist = tree_cons (NULL_TREE, e, initlist);
4064 for (lproto = plist; lproto; lproto = TREE_CHAIN (lproto))
4066 tree pval = TREE_VALUE (lproto);
4068 if (TREE_CODE (pval) == PROTOCOL_INTERFACE_TYPE
4069 && PROTOCOL_FORWARD_DECL (pval))
4071 e = build_unary_op (ADDR_EXPR, PROTOCOL_FORWARD_DECL (pval), 0);
4072 initlist = tree_cons (NULL_TREE, e, initlist);
4076 /* static struct objc_protocol *refs[n]; */
4078 sc_spec = tree_cons (NULL_TREE, ridpointers[(int) RID_STATIC], NULL_TREE);
4079 decl_specs = tree_cons (NULL_TREE, xref_tag (RECORD_TYPE,
4080 get_identifier (UTAG_PROTOCOL)),
4083 if (TREE_CODE (i_or_p) == PROTOCOL_INTERFACE_TYPE)
4084 expr_decl = build_nt (ARRAY_REF,
4085 synth_id_with_class_suffix ("_OBJC_PROTOCOL_REFS",
4087 build_int_2 (size + 2, 0));
4088 else if (TREE_CODE (i_or_p) == CLASS_INTERFACE_TYPE)
4089 expr_decl = build_nt (ARRAY_REF,
4090 synth_id_with_class_suffix ("_OBJC_CLASS_PROTOCOLS",
4092 build_int_2 (size + 2, 0));
4093 else if (TREE_CODE (i_or_p) == CATEGORY_INTERFACE_TYPE)
4095 = build_nt (ARRAY_REF,
4096 synth_id_with_class_suffix ("_OBJC_CATEGORY_PROTOCOLS",
4098 build_int_2 (size + 2, 0));
4102 expr_decl = build1 (INDIRECT_REF, NULL_TREE, expr_decl);
4104 refs_decl = start_decl (expr_decl, decl_specs, 1, NULL_TREE);
4105 DECL_CONTEXT (refs_decl) = NULL_TREE;
4107 finish_decl (refs_decl, build_constructor (TREE_TYPE (refs_decl),
4108 nreverse (initlist)),
4115 build_category_initializer (type, cat_name, class_name,
4116 instance_methods, class_methods, protocol_list)
4120 tree instance_methods;
4124 tree initlist = NULL_TREE, expr;
4126 initlist = tree_cons (NULL_TREE, cat_name, initlist);
4127 initlist = tree_cons (NULL_TREE, class_name, initlist);
4129 if (!instance_methods)
4130 initlist = tree_cons (NULL_TREE, build_int_2 (0, 0), initlist);
4133 expr = build_unary_op (ADDR_EXPR, instance_methods, 0);
4134 initlist = tree_cons (NULL_TREE, expr, initlist);
4137 initlist = tree_cons (NULL_TREE, build_int_2 (0, 0), initlist);
4140 expr = build_unary_op (ADDR_EXPR, class_methods, 0);
4141 initlist = tree_cons (NULL_TREE, expr, initlist);
4144 /* protocol_list = */
4146 initlist = tree_cons (NULL_TREE, build_int_2 (0, 0), initlist);
4149 tree cast_type2 = groktypename
4151 (build_tree_list (NULL_TREE,
4152 xref_tag (RECORD_TYPE,
4153 get_identifier (UTAG_PROTOCOL))),
4154 build1 (INDIRECT_REF, NULL_TREE,
4155 build1 (INDIRECT_REF, NULL_TREE, NULL_TREE))));
4157 expr = build_unary_op (ADDR_EXPR, protocol_list, 0);
4158 TREE_TYPE (expr) = cast_type2;
4159 initlist = tree_cons (NULL_TREE, expr, initlist);
4162 return build_constructor (type, nreverse (initlist));
4165 /* struct objc_class {
4166 struct objc_class *isa;
4167 struct objc_class *super_class;
4172 struct objc_ivar_list *ivars;
4173 struct objc_method_list *methods;
4174 if (flag_next_runtime)
4175 struct objc_cache *cache;
4177 struct sarray *dtable;
4178 struct objc_class *subclass_list;
4179 struct objc_class *sibling_class;
4181 struct objc_protocol_list *protocols;
4182 void *gc_object_type;
4186 build_shared_structure_initializer (type, isa, super, name, size, status,
4187 dispatch_table, ivar_list, protocol_list)
4194 tree dispatch_table;
4198 tree initlist = NULL_TREE, expr;
4201 initlist = tree_cons (NULL_TREE, isa, initlist);
4204 initlist = tree_cons (NULL_TREE, super, initlist);
4207 initlist = tree_cons (NULL_TREE, default_conversion (name), initlist);
4210 initlist = tree_cons (NULL_TREE, build_int_2 (0, 0), initlist);
4213 initlist = tree_cons (NULL_TREE, build_int_2 (status, 0), initlist);
4215 /* instance_size = */
4216 initlist = tree_cons (NULL_TREE, size, initlist);
4218 /* objc_ivar_list = */
4220 initlist = tree_cons (NULL_TREE, build_int_2 (0, 0), initlist);
4223 expr = build_unary_op (ADDR_EXPR, ivar_list, 0);
4224 initlist = tree_cons (NULL_TREE, expr, initlist);
4227 /* objc_method_list = */
4228 if (!dispatch_table)
4229 initlist = tree_cons (NULL_TREE, build_int_2 (0, 0), initlist);
4232 expr = build_unary_op (ADDR_EXPR, dispatch_table, 0);
4233 initlist = tree_cons (NULL_TREE, expr, initlist);
4236 if (flag_next_runtime)
4237 /* method_cache = */
4238 initlist = tree_cons (NULL_TREE, build_int_2 (0, 0), initlist);
4242 initlist = tree_cons (NULL_TREE, build_int_2 (0, 0), initlist);
4244 /* subclass_list = */
4245 initlist = tree_cons (NULL_TREE, build_int_2 (0, 0), initlist);
4247 /* sibling_class = */
4248 initlist = tree_cons (NULL_TREE, build_int_2 (0, 0), initlist);
4251 /* protocol_list = */
4252 if (! protocol_list)
4253 initlist = tree_cons (NULL_TREE, build_int_2 (0, 0), initlist);
4259 (build_tree_list (NULL_TREE,
4260 xref_tag (RECORD_TYPE,
4261 get_identifier (UTAG_PROTOCOL))),
4262 build1 (INDIRECT_REF, NULL_TREE,
4263 build1 (INDIRECT_REF, NULL_TREE, NULL_TREE))));
4265 expr = build_unary_op (ADDR_EXPR, protocol_list, 0);
4266 TREE_TYPE (expr) = cast_type2;
4267 initlist = tree_cons (NULL_TREE, expr, initlist);
4270 /* gc_object_type = NULL */
4271 initlist = tree_cons (NULL_TREE, build_int_2 (0, 0), initlist);
4273 return build_constructor (type, nreverse (initlist));
4276 /* static struct objc_category _OBJC_CATEGORY_<name> = { ... }; */
4279 generate_category (cat)
4282 tree sc_spec, decl_specs, decl;
4283 tree initlist, cat_name_expr, class_name_expr;
4284 tree protocol_decl, category;
4286 add_class_reference (CLASS_NAME (cat));
4287 cat_name_expr = add_objc_string (CLASS_SUPER_NAME (cat), class_names);
4289 class_name_expr = add_objc_string (CLASS_NAME (cat), class_names);
4291 category = CLASS_CATEGORY_LIST (implementation_template);
4293 /* find the category interface from the class it is associated with */
4296 if (CLASS_SUPER_NAME (cat) == CLASS_SUPER_NAME (category))
4298 category = CLASS_CATEGORY_LIST (category);
4301 if (category && CLASS_PROTOCOL_LIST (category))
4303 generate_protocol_references (CLASS_PROTOCOL_LIST (category));
4304 protocol_decl = generate_protocol_list (category);
4309 sc_spec = tree_cons (NULL_TREE, ridpointers[(int) RID_STATIC], NULL_TREE);
4310 decl_specs = tree_cons (NULL_TREE, objc_category_template, sc_spec);
4312 decl = start_decl (synth_id_with_class_suffix ("_OBJC_CATEGORY",
4313 objc_implementation_context),
4314 decl_specs, 1, NULL_TREE);
4316 initlist = build_category_initializer (TREE_TYPE (decl),
4317 cat_name_expr, class_name_expr,
4318 UOBJC_INSTANCE_METHODS_decl,
4319 UOBJC_CLASS_METHODS_decl,
4322 TREE_USED (decl) = 1;
4323 finish_decl (decl, initlist, NULL_TREE);
4326 /* static struct objc_class _OBJC_METACLASS_Foo={ ... };
4327 static struct objc_class _OBJC_CLASS_Foo={ ... }; */
4330 generate_shared_structures ()
4332 tree sc_spec, decl_specs, decl;
4333 tree name_expr, super_expr, root_expr;
4334 tree my_root_id = NULL_TREE, my_super_id = NULL_TREE;
4335 tree cast_type, initlist, protocol_decl;
4337 my_super_id = CLASS_SUPER_NAME (implementation_template);
4340 add_class_reference (my_super_id);
4342 /* Compute "my_root_id" - this is required for code generation.
4343 the "isa" for all meta class structures points to the root of
4344 the inheritance hierarchy (e.g. "__Object")... */
4345 my_root_id = my_super_id;
4348 tree my_root_int = lookup_interface (my_root_id);
4350 if (my_root_int && CLASS_SUPER_NAME (my_root_int))
4351 my_root_id = CLASS_SUPER_NAME (my_root_int);
4358 /* No super class. */
4359 my_root_id = CLASS_NAME (implementation_template);
4362 = groktypename (build_tree_list (build_tree_list (NULL_TREE,
4363 objc_class_template),
4364 build1 (INDIRECT_REF,
4365 NULL_TREE, NULL_TREE)));
4367 name_expr = add_objc_string (CLASS_NAME (implementation_template),
4370 /* Install class `isa' and `super' pointers at runtime. */
4373 super_expr = add_objc_string (my_super_id, class_names);
4374 super_expr = build_c_cast (cast_type, super_expr); /* cast! */
4377 super_expr = build_int_2 (0, 0);
4379 root_expr = add_objc_string (my_root_id, class_names);
4380 root_expr = build_c_cast (cast_type, root_expr); /* cast! */
4382 if (CLASS_PROTOCOL_LIST (implementation_template))
4384 generate_protocol_references
4385 (CLASS_PROTOCOL_LIST (implementation_template));
4386 protocol_decl = generate_protocol_list (implementation_template);
4391 /* static struct objc_class _OBJC_METACLASS_Foo = { ... }; */
4393 sc_spec = build_tree_list (NULL_TREE, ridpointers[(int) RID_STATIC]);
4394 decl_specs = tree_cons (NULL_TREE, objc_class_template, sc_spec);
4396 decl = start_decl (DECL_NAME (UOBJC_METACLASS_decl), decl_specs, 1,
4400 = build_shared_structure_initializer
4402 root_expr, super_expr, name_expr,
4403 convert (integer_type_node, TYPE_SIZE_UNIT (objc_class_template)),
4405 UOBJC_CLASS_METHODS_decl,
4406 UOBJC_CLASS_VARIABLES_decl,
4409 finish_decl (decl, initlist, NULL_TREE);
4411 /* static struct objc_class _OBJC_CLASS_Foo={ ... }; */
4413 decl = start_decl (DECL_NAME (UOBJC_CLASS_decl), decl_specs, 1,
4417 = build_shared_structure_initializer
4419 build_unary_op (ADDR_EXPR, UOBJC_METACLASS_decl, 0),
4420 super_expr, name_expr,
4421 convert (integer_type_node,
4422 TYPE_SIZE_UNIT (CLASS_STATIC_TEMPLATE
4423 (implementation_template))),
4425 UOBJC_INSTANCE_METHODS_decl,
4426 UOBJC_INSTANCE_VARIABLES_decl,
4429 finish_decl (decl, initlist, NULL_TREE);
4433 synth_id_with_class_suffix (preamble, ctxt)
4434 const char *preamble;
4438 if (TREE_CODE (ctxt) == CLASS_IMPLEMENTATION_TYPE
4439 || TREE_CODE (ctxt) == CLASS_INTERFACE_TYPE)
4441 const char *const class_name
4442 = IDENTIFIER_POINTER (CLASS_NAME (objc_implementation_context));
4443 string = (char *) alloca (strlen (preamble) + strlen (class_name) + 3);
4444 sprintf (string, "%s_%s", preamble,
4445 IDENTIFIER_POINTER (CLASS_NAME (ctxt)));
4447 else if (TREE_CODE (ctxt) == CATEGORY_IMPLEMENTATION_TYPE
4448 || TREE_CODE (ctxt) == CATEGORY_INTERFACE_TYPE)
4450 /* We have a category. */
4451 const char *const class_name
4452 = IDENTIFIER_POINTER (CLASS_NAME (objc_implementation_context));
4453 const char *const class_super_name
4454 = IDENTIFIER_POINTER (CLASS_SUPER_NAME (objc_implementation_context));
4455 string = (char *) alloca (strlen (preamble)
4456 + strlen (class_name)
4457 + strlen (class_super_name)
4459 sprintf (string, "%s_%s_%s", preamble, class_name, class_super_name);
4461 else if (TREE_CODE (ctxt) == PROTOCOL_INTERFACE_TYPE)
4463 const char *protocol_name = IDENTIFIER_POINTER (PROTOCOL_NAME (ctxt));
4465 = (char *) alloca (strlen (preamble) + strlen (protocol_name) + 3);
4466 sprintf (string, "%s_%s", preamble, protocol_name);
4471 return get_identifier (string);
4475 is_objc_type_qualifier (node)
4478 return (TREE_CODE (node) == IDENTIFIER_NODE
4479 && (node == ridpointers [(int) RID_CONST]
4480 || node == ridpointers [(int) RID_VOLATILE]
4481 || node == ridpointers [(int) RID_IN]
4482 || node == ridpointers [(int) RID_OUT]
4483 || node == ridpointers [(int) RID_INOUT]
4484 || node == ridpointers [(int) RID_BYCOPY]
4485 || node == ridpointers [(int) RID_BYREF]
4486 || node == ridpointers [(int) RID_ONEWAY]));
4489 /* If type is empty or only type qualifiers are present, add default
4490 type of id (otherwise grokdeclarator will default to int). */
4493 adjust_type_for_id_default (type)
4496 tree declspecs, chain;
4499 return build_tree_list (build_tree_list (NULL_TREE, objc_object_reference),
4500 build1 (INDIRECT_REF, NULL_TREE, NULL_TREE));
4502 declspecs = TREE_PURPOSE (type);
4504 /* Determine if a typespec is present. */
4505 for (chain = declspecs;
4507 chain = TREE_CHAIN (chain))
4509 if (!is_objc_type_qualifier (TREE_VALUE (chain)))
4513 return build_tree_list (tree_cons (NULL_TREE, objc_object_reference,
4515 build1 (INDIRECT_REF, NULL_TREE, NULL_TREE));
4520 selector ':' '(' typename ')' identifier
4523 Transform an Objective-C keyword argument into
4524 the C equivalent parameter declarator.
4526 In: key_name, an "identifier_node" (optional).
4527 arg_type, a "tree_list" (optional).
4528 arg_name, an "identifier_node".
4530 Note: It would be really nice to strongly type the preceding
4531 arguments in the function prototype; however, then I
4532 could not use the "accessor" macros defined in "tree.h".
4534 Out: an instance of "keyword_decl". */
4537 build_keyword_decl (key_name, arg_type, arg_name)
4544 /* If no type is specified, default to "id". */
4545 arg_type = adjust_type_for_id_default (arg_type);
4547 keyword_decl = make_node (KEYWORD_DECL);
4549 TREE_TYPE (keyword_decl) = arg_type;
4550 KEYWORD_ARG_NAME (keyword_decl) = arg_name;
4551 KEYWORD_KEY_NAME (keyword_decl) = key_name;
4553 return keyword_decl;
4556 /* Given a chain of keyword_decl's, synthesize the full keyword selector. */
4559 build_keyword_selector (selector)
4563 tree key_chain, key_name;
4566 /* Scan the selector to see how much space we'll need. */
4567 for (key_chain = selector; key_chain; key_chain = TREE_CHAIN (key_chain))
4569 if (TREE_CODE (selector) == KEYWORD_DECL)
4570 key_name = KEYWORD_KEY_NAME (key_chain);
4571 else if (TREE_CODE (selector) == TREE_LIST)
4572 key_name = TREE_PURPOSE (key_chain);
4577 len += IDENTIFIER_LENGTH (key_name) + 1;
4579 /* Just a ':' arg. */
4583 buf = (char *) alloca (len + 1);
4584 /* Start the buffer out as an empty string. */
4587 for (key_chain = selector; key_chain; key_chain = TREE_CHAIN (key_chain))
4589 if (TREE_CODE (selector) == KEYWORD_DECL)
4590 key_name = KEYWORD_KEY_NAME (key_chain);
4591 else if (TREE_CODE (selector) == TREE_LIST)
4592 key_name = TREE_PURPOSE (key_chain);
4597 strcat (buf, IDENTIFIER_POINTER (key_name));
4601 return get_identifier (buf);
4604 /* Used for declarations and definitions. */
4607 build_method_decl (code, ret_type, selector, add_args)
4608 enum tree_code code;
4615 /* If no type is specified, default to "id". */
4616 ret_type = adjust_type_for_id_default (ret_type);
4618 method_decl = make_node (code);
4619 TREE_TYPE (method_decl) = ret_type;
4621 /* If we have a keyword selector, create an identifier_node that
4622 represents the full selector name (`:' included)... */
4623 if (TREE_CODE (selector) == KEYWORD_DECL)
4625 METHOD_SEL_NAME (method_decl) = build_keyword_selector (selector);
4626 METHOD_SEL_ARGS (method_decl) = selector;
4627 METHOD_ADD_ARGS (method_decl) = add_args;
4631 METHOD_SEL_NAME (method_decl) = selector;
4632 METHOD_SEL_ARGS (method_decl) = NULL_TREE;
4633 METHOD_ADD_ARGS (method_decl) = NULL_TREE;
4639 #define METHOD_DEF 0
4640 #define METHOD_REF 1
4642 /* Used by `build_objc_method_call' and `comp_method_types'. Return
4643 an argument list for method METH. CONTEXT is either METHOD_DEF or
4644 METHOD_REF, saying whether we are trying to define a method or call
4645 one. SUPERFLAG says this is for a send to super; this makes a
4646 difference for the NeXT calling sequence in which the lookup and
4647 the method call are done together. */
4650 get_arg_type_list (meth, context, superflag)
4657 /* Receiver type. */
4658 if (flag_next_runtime && superflag)
4659 arglist = build_tree_list (NULL_TREE, super_type);
4660 else if (context == METHOD_DEF)
4661 arglist = build_tree_list (NULL_TREE, TREE_TYPE (self_decl));
4663 arglist = build_tree_list (NULL_TREE, id_type);
4665 /* Selector type - will eventually change to `int'. */
4666 chainon (arglist, build_tree_list (NULL_TREE, selector_type));
4668 /* Build a list of argument types. */
4669 for (akey = METHOD_SEL_ARGS (meth); akey; akey = TREE_CHAIN (akey))
4671 tree arg_decl = groktypename_in_parm_context (TREE_TYPE (akey));
4672 chainon (arglist, build_tree_list (NULL_TREE, TREE_TYPE (arg_decl)));
4675 if (METHOD_ADD_ARGS (meth) == objc_ellipsis_node)
4676 /* We have a `, ...' immediately following the selector,
4677 finalize the arglist...simulate get_parm_info (0). */
4679 else if (METHOD_ADD_ARGS (meth))
4681 /* we have a variable length selector */
4682 tree add_arg_list = TREE_CHAIN (METHOD_ADD_ARGS (meth));
4683 chainon (arglist, add_arg_list);
4686 /* finalize the arglist...simulate get_parm_info (1) */
4687 chainon (arglist, build_tree_list (NULL_TREE, void_type_node));
4693 check_duplicates (hsh)
4696 tree meth = NULL_TREE;
4704 /* We have two methods with the same name and different types. */
4706 char type = (TREE_CODE (meth) == INSTANCE_METHOD_DECL) ? '-' : '+';
4708 warning ("multiple declarations for method `%s'",
4709 IDENTIFIER_POINTER (METHOD_SEL_NAME (meth)));
4711 warn_with_method ("using", type, meth);
4712 for (loop = hsh->list; loop; loop = loop->next)
4713 warn_with_method ("also found", type, loop->value);
4719 /* If RECEIVER is a class reference, return the identifier node for
4720 the referenced class. RECEIVER is created by get_class_reference,
4721 so we check the exact form created depending on which runtimes are
4725 receiver_is_class_object (receiver)
4728 tree chain, exp, arg;
4730 /* The receiver is 'self' in the context of a class method. */
4731 if (objc_method_context
4732 && receiver == self_decl
4733 && TREE_CODE (objc_method_context) == CLASS_METHOD_DECL)
4735 return CLASS_NAME (objc_implementation_context);
4738 if (flag_next_runtime)
4740 /* The receiver is a variable created by
4741 build_class_reference_decl. */
4742 if (TREE_CODE (receiver) == VAR_DECL
4743 && TREE_TYPE (receiver) == objc_class_type)
4744 /* Look up the identifier. */
4745 for (chain = cls_ref_chain; chain; chain = TREE_CHAIN (chain))
4746 if (TREE_PURPOSE (chain) == receiver)
4747 return TREE_VALUE (chain);
4751 /* The receiver is a function call that returns an id. Check if
4752 it is a call to objc_getClass, if so, pick up the class name. */
4753 if (TREE_CODE (receiver) == CALL_EXPR
4754 && (exp = TREE_OPERAND (receiver, 0))
4755 && TREE_CODE (exp) == ADDR_EXPR
4756 && (exp = TREE_OPERAND (exp, 0))
4757 && TREE_CODE (exp) == FUNCTION_DECL
4758 && exp == objc_get_class_decl
4759 /* We have a call to objc_getClass! */
4760 && (arg = TREE_OPERAND (receiver, 1))
4761 && TREE_CODE (arg) == TREE_LIST
4762 && (arg = TREE_VALUE (arg)))
4765 if (TREE_CODE (arg) == ADDR_EXPR
4766 && (arg = TREE_OPERAND (arg, 0))
4767 && TREE_CODE (arg) == STRING_CST)
4768 /* Finally, we have the class name. */
4769 return get_identifier (TREE_STRING_POINTER (arg));
4775 /* If we are currently building a message expr, this holds
4776 the identifier of the selector of the message. This is
4777 used when printing warnings about argument mismatches. */
4779 static tree building_objc_message_expr = 0;
4782 maybe_building_objc_message_expr ()
4784 return building_objc_message_expr;
4787 /* Construct an expression for sending a message.
4788 MESS has the object to send to in TREE_PURPOSE
4789 and the argument list (including selector) in TREE_VALUE.
4791 (*(<abstract_decl>(*)())_msg)(receiver, selTransTbl[n], ...);
4792 (*(<abstract_decl>(*)())_msgSuper)(receiver, selTransTbl[n], ...); */
4795 build_message_expr (mess)
4798 tree receiver = TREE_PURPOSE (mess);
4800 tree args = TREE_VALUE (mess);
4801 tree method_params = NULL_TREE;
4803 if (TREE_CODE (receiver) == ERROR_MARK)
4804 return error_mark_node;
4806 /* Obtain the full selector name. */
4807 if (TREE_CODE (args) == IDENTIFIER_NODE)
4808 /* A unary selector. */
4810 else if (TREE_CODE (args) == TREE_LIST)
4811 sel_name = build_keyword_selector (args);
4815 /* Build the parameter list to give to the method. */
4816 if (TREE_CODE (args) == TREE_LIST)
4818 tree chain = args, prev = NULL_TREE;
4820 /* We have a keyword selector--check for comma expressions. */
4823 tree element = TREE_VALUE (chain);
4825 /* We have a comma expression, must collapse... */
4826 if (TREE_CODE (element) == TREE_LIST)
4829 TREE_CHAIN (prev) = element;
4834 chain = TREE_CHAIN (chain);
4836 method_params = args;
4839 return finish_message_expr (receiver, sel_name, method_params);
4842 /* The 'finish_message_expr' routine is called from within
4843 'build_message_expr' for non-template functions. In the case of
4844 C++ template functions, it is called from 'build_expr_from_tree'
4845 (in decl2.c) after RECEIVER and METHOD_PARAMS have been expanded. */
4848 finish_message_expr (receiver, sel_name, method_params)
4849 tree receiver, sel_name, method_params;
4851 tree method_prototype = NULL_TREE, class_ident = NULL_TREE;
4852 tree selector, self_object, retval;
4853 int statically_typed = 0, statically_allocated = 0;
4855 /* Determine receiver type. */
4856 tree rtype = TREE_TYPE (receiver);
4857 int super = IS_SUPER (rtype);
4861 if (TREE_STATIC_TEMPLATE (rtype))
4862 statically_allocated = 1;
4863 else if (TREE_CODE (rtype) == POINTER_TYPE
4864 && TREE_STATIC_TEMPLATE (TREE_TYPE (rtype)))
4865 statically_typed = 1;
4866 else if ((flag_next_runtime
4868 && (class_ident = receiver_is_class_object (receiver)))
4870 else if (! IS_ID (rtype)
4871 /* Allow any type that matches objc_class_type. */
4872 && ! comptypes (rtype, objc_class_type))
4874 warning ("invalid receiver type `%s'",
4875 gen_declaration (rtype, errbuf));
4877 if (statically_allocated)
4878 receiver = build_unary_op (ADDR_EXPR, receiver, 0);
4880 /* Don't evaluate the receiver twice. */
4881 receiver = save_expr (receiver);
4882 self_object = receiver;
4885 /* If sending to `super', use current self as the object. */
4886 self_object = self_decl;
4888 /* Determine operation return type. */
4894 if (CLASS_SUPER_NAME (implementation_template))
4897 = lookup_interface (CLASS_SUPER_NAME (implementation_template));
4899 if (TREE_CODE (objc_method_context) == INSTANCE_METHOD_DECL)
4900 method_prototype = lookup_instance_method_static (iface, sel_name);
4902 method_prototype = lookup_class_method_static (iface, sel_name);
4904 if (iface && !method_prototype)
4905 warning ("`%s' does not respond to `%s'",
4906 IDENTIFIER_POINTER (CLASS_SUPER_NAME (implementation_template)),
4907 IDENTIFIER_POINTER (sel_name));
4911 error ("no super class declared in interface for `%s'",
4912 IDENTIFIER_POINTER (CLASS_NAME (implementation_template)));
4913 return error_mark_node;
4917 else if (statically_allocated)
4919 tree ctype = TREE_TYPE (rtype);
4920 tree iface = lookup_interface (TYPE_NAME (rtype));
4923 method_prototype = lookup_instance_method_static (iface, sel_name);
4925 if (! method_prototype && TYPE_PROTOCOL_LIST (ctype))
4927 = lookup_method_in_protocol_list (TYPE_PROTOCOL_LIST (ctype),
4930 if (!method_prototype)
4931 warning ("`%s' does not respond to `%s'",
4932 IDENTIFIER_POINTER (TYPE_NAME (rtype)),
4933 IDENTIFIER_POINTER (sel_name));
4935 else if (statically_typed)
4937 tree ctype = TREE_TYPE (rtype);
4939 /* `self' is now statically_typed. All methods should be visible
4940 within the context of the implementation. */
4941 if (objc_implementation_context
4942 && CLASS_NAME (objc_implementation_context) == TYPE_NAME (ctype))
4945 = lookup_instance_method_static (implementation_template,
4948 if (! method_prototype && TYPE_PROTOCOL_LIST (ctype))
4950 = lookup_method_in_protocol_list (TYPE_PROTOCOL_LIST (ctype),
4953 if (! method_prototype
4954 && implementation_template != objc_implementation_context)
4955 /* The method is not published in the interface. Check
4958 = lookup_method (CLASS_NST_METHODS (objc_implementation_context),
4965 if ((iface = lookup_interface (TYPE_NAME (ctype))))
4966 method_prototype = lookup_instance_method_static (iface, sel_name);
4968 if (! method_prototype)
4970 tree protocol_list = TYPE_PROTOCOL_LIST (ctype);
4973 = lookup_method_in_protocol_list (protocol_list,
4978 if (!method_prototype)
4979 warning ("`%s' does not respond to `%s'",
4980 IDENTIFIER_POINTER (TYPE_NAME (ctype)),
4981 IDENTIFIER_POINTER (sel_name));
4983 else if (class_ident)
4985 if (objc_implementation_context
4986 && CLASS_NAME (objc_implementation_context) == class_ident)
4989 = lookup_class_method_static (implementation_template, sel_name);
4991 if (!method_prototype
4992 && implementation_template != objc_implementation_context)
4993 /* The method is not published in the interface. Check
4996 = lookup_method (CLASS_CLS_METHODS (objc_implementation_context),
5003 if ((iface = lookup_interface (class_ident)))
5004 method_prototype = lookup_class_method_static (iface, sel_name);
5007 if (!method_prototype)
5009 warning ("cannot find class (factory) method");
5010 warning ("return type for `%s' defaults to id",
5011 IDENTIFIER_POINTER (sel_name));
5014 else if (IS_PROTOCOL_QUALIFIED_ID (rtype))
5016 /* An anonymous object that has been qualified with a protocol. */
5018 tree protocol_list = TYPE_PROTOCOL_LIST (rtype);
5020 method_prototype = lookup_method_in_protocol_list (protocol_list,
5023 if (!method_prototype)
5027 warning ("method `%s' not implemented by protocol",
5028 IDENTIFIER_POINTER (sel_name));
5030 /* Try and find the method signature in the global pools. */
5032 if (!(hsh = hash_lookup (nst_method_hash_list, sel_name)))
5033 hsh = hash_lookup (cls_method_hash_list, sel_name);
5035 if (!(method_prototype = check_duplicates (hsh)))
5036 warning ("return type defaults to id");
5043 /* We think we have an instance...loophole: extern id Object; */
5044 hsh = hash_lookup (nst_method_hash_list, sel_name);
5047 /* For various loopholes */
5048 hsh = hash_lookup (cls_method_hash_list, sel_name);
5050 method_prototype = check_duplicates (hsh);
5051 if (!method_prototype)
5053 warning ("cannot find method");
5054 warning ("return type for `%s' defaults to id",
5055 IDENTIFIER_POINTER (sel_name));
5059 /* Save the selector name for printing error messages. */
5060 building_objc_message_expr = sel_name;
5062 /* Build the parameters list for looking up the method.
5063 These are the object itself and the selector. */
5065 if (flag_typed_selectors)
5066 selector = build_typed_selector_reference (sel_name, method_prototype);
5068 selector = build_selector_reference (sel_name);
5070 retval = build_objc_method_call (super, method_prototype,
5071 receiver, self_object,
5072 selector, method_params);
5074 building_objc_message_expr = 0;
5079 /* Build a tree expression to send OBJECT the operation SELECTOR,
5080 looking up the method on object LOOKUP_OBJECT (often same as OBJECT),
5081 assuming the method has prototype METHOD_PROTOTYPE.
5082 (That is an INSTANCE_METHOD_DECL or CLASS_METHOD_DECL.)
5083 Use METHOD_PARAMS as list of args to pass to the method.
5084 If SUPER_FLAG is nonzero, we look up the superclass's method. */
5087 build_objc_method_call (super_flag, method_prototype, lookup_object, object,
5088 selector, method_params)
5090 tree method_prototype, lookup_object, object, selector, method_params;
5092 tree sender = (super_flag ? umsg_super_decl : umsg_decl);
5093 tree rcv_p = (super_flag
5094 ? build_pointer_type (xref_tag (RECORD_TYPE,
5095 get_identifier (TAG_SUPER)))
5098 if (flag_next_runtime)
5100 if (! method_prototype)
5102 method_params = tree_cons (NULL_TREE, lookup_object,
5103 tree_cons (NULL_TREE, selector,
5105 assemble_external (sender);
5106 return build_function_call (sender, method_params);
5110 /* This is a real kludge, but it is used only for the Next.
5111 Clobber the data type of SENDER temporarily to accept
5112 all the arguments for this operation, and to return
5113 whatever this operation returns. */
5114 tree arglist = NULL_TREE, retval, savarg, savret;
5115 tree ret_type = groktypename (TREE_TYPE (method_prototype));
5117 /* Save the proper contents of SENDER's data type. */
5118 savarg = TYPE_ARG_TYPES (TREE_TYPE (sender));
5119 savret = TREE_TYPE (TREE_TYPE (sender));
5121 /* Install this method's argument types. */
5122 arglist = get_arg_type_list (method_prototype, METHOD_REF,
5124 TYPE_ARG_TYPES (TREE_TYPE (sender)) = arglist;
5126 /* Install this method's return type. */
5127 TREE_TYPE (TREE_TYPE (sender)) = ret_type;
5129 /* Call SENDER with all the parameters. This will do type
5130 checking using the arg types for this method. */
5131 method_params = tree_cons (NULL_TREE, lookup_object,
5132 tree_cons (NULL_TREE, selector,
5134 assemble_external (sender);
5135 retval = build_function_call (sender, method_params);
5137 /* Restore SENDER's return/argument types. */
5138 TYPE_ARG_TYPES (TREE_TYPE (sender)) = savarg;
5139 TREE_TYPE (TREE_TYPE (sender)) = savret;
5145 /* This is the portable way.
5146 First call the lookup function to get a pointer to the method,
5147 then cast the pointer, then call it with the method arguments. */
5150 /* Avoid trouble since we may evaluate each of these twice. */
5151 object = save_expr (object);
5152 selector = save_expr (selector);
5154 lookup_object = build_c_cast (rcv_p, lookup_object);
5156 assemble_external (sender);
5158 = build_function_call (sender,
5159 tree_cons (NULL_TREE, lookup_object,
5160 tree_cons (NULL_TREE, selector,
5163 /* If we have a method prototype, construct the data type this
5164 method needs, and cast what we got from SENDER into a pointer
5166 if (method_prototype)
5168 tree arglist = get_arg_type_list (method_prototype, METHOD_REF,
5170 tree valtype = groktypename (TREE_TYPE (method_prototype));
5171 tree fake_function_type = build_function_type (valtype, arglist);
5172 TREE_TYPE (method) = build_pointer_type (fake_function_type);
5176 = build_pointer_type (build_function_type (ptr_type_node, NULL_TREE));
5178 /* Pass the object to the method. */
5179 assemble_external (method);
5180 return build_function_call (method,
5181 tree_cons (NULL_TREE, object,
5182 tree_cons (NULL_TREE, selector,
5188 build_protocol_reference (p)
5191 tree decl, ident, ptype;
5193 /* extern struct objc_protocol _OBJC_PROTOCOL_<mumble>; */
5195 ident = synth_id_with_class_suffix ("_OBJC_PROTOCOL", p);
5197 = groktypename (build_tree_list (build_tree_list (NULL_TREE,
5198 objc_protocol_template),
5201 if (IDENTIFIER_GLOBAL_VALUE (ident))
5202 decl = IDENTIFIER_GLOBAL_VALUE (ident); /* Set by pushdecl. */
5205 decl = build_decl (VAR_DECL, ident, ptype);
5206 DECL_EXTERNAL (decl) = 1;
5207 TREE_PUBLIC (decl) = 1;
5208 TREE_USED (decl) = 1;
5209 DECL_ARTIFICIAL (decl) = 1;
5211 make_decl_rtl (decl, 0);
5212 pushdecl_top_level (decl);
5215 PROTOCOL_FORWARD_DECL (p) = decl;
5219 build_protocol_expr (protoname)
5223 tree p = lookup_protocol (protoname);
5227 error ("cannot find protocol declaration for `%s'",
5228 IDENTIFIER_POINTER (protoname));
5229 return error_mark_node;
5232 if (!PROTOCOL_FORWARD_DECL (p))
5233 build_protocol_reference (p);
5235 expr = build_unary_op (ADDR_EXPR, PROTOCOL_FORWARD_DECL (p), 0);
5237 TREE_TYPE (expr) = protocol_type;
5243 build_selector_expr (selnamelist)
5248 /* Obtain the full selector name. */
5249 if (TREE_CODE (selnamelist) == IDENTIFIER_NODE)
5250 /* A unary selector. */
5251 selname = selnamelist;
5252 else if (TREE_CODE (selnamelist) == TREE_LIST)
5253 selname = build_keyword_selector (selnamelist);
5257 if (flag_typed_selectors)
5258 return build_typed_selector_reference (selname, 0);
5260 return build_selector_reference (selname);
5264 build_encode_expr (type)
5270 encode_type (type, obstack_object_size (&util_obstack),
5271 OBJC_ENCODE_INLINE_DEFS);
5272 obstack_1grow (&util_obstack, 0); /* null terminate string */
5273 string = obstack_finish (&util_obstack);
5275 /* Synthesize a string that represents the encoded struct/union. */
5276 result = my_build_string (strlen (string) + 1, string);
5277 obstack_free (&util_obstack, util_firstobj);
5282 build_ivar_reference (id)
5285 if (TREE_CODE (objc_method_context) == CLASS_METHOD_DECL)
5287 /* Historically, a class method that produced objects (factory
5288 method) would assign `self' to the instance that it
5289 allocated. This would effectively turn the class method into
5290 an instance method. Following this assignment, the instance
5291 variables could be accessed. That practice, while safe,
5292 violates the simple rule that a class method should not refer
5293 to an instance variable. It's better to catch the cases
5294 where this is done unknowingly than to support the above
5296 warning ("instance variable `%s' accessed in class method",
5297 IDENTIFIER_POINTER (id));
5298 TREE_TYPE (self_decl) = instance_type; /* cast */
5301 return build_component_ref (build_indirect_ref (self_decl, "->"), id);
5304 /* Compute a hash value for a given method SEL_NAME. */
5307 hash_func (sel_name)
5310 const unsigned char *s
5311 = (const unsigned char *)IDENTIFIER_POINTER (sel_name);
5315 h = h * 67 + *s++ - 113;
5322 nst_method_hash_list = (hash *) xcalloc (SIZEHASHTABLE, sizeof (hash));
5323 cls_method_hash_list = (hash *) xcalloc (SIZEHASHTABLE, sizeof (hash));
5326 /* WARNING!!!! hash_enter is called with a method, and will peek
5327 inside to find its selector! But hash_lookup is given a selector
5328 directly, and looks for the selector that's inside the found
5329 entry's key (method) for comparison. */
5332 hash_enter (hashlist, method)
5336 static hash hash_alloc_list = 0;
5337 static int hash_alloc_index = 0;
5339 int slot = hash_func (METHOD_SEL_NAME (method)) % SIZEHASHTABLE;
5341 if (! hash_alloc_list || hash_alloc_index >= HASH_ALLOC_LIST_SIZE)
5343 hash_alloc_index = 0;
5344 hash_alloc_list = (hash) xmalloc (sizeof (struct hashed_entry)
5345 * HASH_ALLOC_LIST_SIZE);
5347 obj = &hash_alloc_list[hash_alloc_index++];
5349 obj->next = hashlist[slot];
5352 hashlist[slot] = obj; /* append to front */
5356 hash_lookup (hashlist, sel_name)
5362 target = hashlist[hash_func (sel_name) % SIZEHASHTABLE];
5366 if (sel_name == METHOD_SEL_NAME (target->key))
5369 target = target->next;
5375 hash_add_attr (entry, value)
5379 static attr attr_alloc_list = 0;
5380 static int attr_alloc_index = 0;
5383 if (! attr_alloc_list || attr_alloc_index >= ATTR_ALLOC_LIST_SIZE)
5385 attr_alloc_index = 0;
5386 attr_alloc_list = (attr) xmalloc (sizeof (struct hashed_attribute)
5387 * ATTR_ALLOC_LIST_SIZE);
5389 obj = &attr_alloc_list[attr_alloc_index++];
5390 obj->next = entry->list;
5393 entry->list = obj; /* append to front */
5397 lookup_method (mchain, method)
5403 if (TREE_CODE (method) == IDENTIFIER_NODE)
5406 key = METHOD_SEL_NAME (method);
5410 if (METHOD_SEL_NAME (mchain) == key)
5412 mchain = TREE_CHAIN (mchain);
5418 lookup_instance_method_static (interface, ident)
5422 tree inter = interface;
5423 tree chain = CLASS_NST_METHODS (inter);
5424 tree meth = NULL_TREE;
5428 if ((meth = lookup_method (chain, ident)))
5431 if (CLASS_CATEGORY_LIST (inter))
5433 tree category = CLASS_CATEGORY_LIST (inter);
5434 chain = CLASS_NST_METHODS (category);
5438 if ((meth = lookup_method (chain, ident)))
5441 /* Check for instance methods in protocols in categories. */
5442 if (CLASS_PROTOCOL_LIST (category))
5444 if ((meth = (lookup_method_in_protocol_list
5445 (CLASS_PROTOCOL_LIST (category), ident, 0))))
5449 if ((category = CLASS_CATEGORY_LIST (category)))
5450 chain = CLASS_NST_METHODS (category);
5455 if (CLASS_PROTOCOL_LIST (inter))
5457 if ((meth = (lookup_method_in_protocol_list
5458 (CLASS_PROTOCOL_LIST (inter), ident, 0))))
5462 if ((inter = lookup_interface (CLASS_SUPER_NAME (inter))))
5463 chain = CLASS_NST_METHODS (inter);
5471 lookup_class_method_static (interface, ident)
5475 tree inter = interface;
5476 tree chain = CLASS_CLS_METHODS (inter);
5477 tree meth = NULL_TREE;
5478 tree root_inter = NULL_TREE;
5482 if ((meth = lookup_method (chain, ident)))
5485 if (CLASS_CATEGORY_LIST (inter))
5487 tree category = CLASS_CATEGORY_LIST (inter);
5488 chain = CLASS_CLS_METHODS (category);
5492 if ((meth = lookup_method (chain, ident)))
5495 /* Check for class methods in protocols in categories. */
5496 if (CLASS_PROTOCOL_LIST (category))
5498 if ((meth = (lookup_method_in_protocol_list
5499 (CLASS_PROTOCOL_LIST (category), ident, 1))))
5503 if ((category = CLASS_CATEGORY_LIST (category)))
5504 chain = CLASS_CLS_METHODS (category);
5509 /* Check for class methods in protocols. */
5510 if (CLASS_PROTOCOL_LIST (inter))
5512 if ((meth = (lookup_method_in_protocol_list
5513 (CLASS_PROTOCOL_LIST (inter), ident, 1))))
5518 if ((inter = lookup_interface (CLASS_SUPER_NAME (inter))))
5519 chain = CLASS_CLS_METHODS (inter);
5523 /* If no class (factory) method was found, check if an _instance_
5524 method of the same name exists in the root class. This is what
5525 the Objective-C runtime will do. */
5526 return lookup_instance_method_static (root_inter, ident);
5530 add_class_method (class, method)
5537 if (!(mth = lookup_method (CLASS_CLS_METHODS (class), method)))
5539 /* put method on list in reverse order */
5540 TREE_CHAIN (method) = CLASS_CLS_METHODS (class);
5541 CLASS_CLS_METHODS (class) = method;
5545 if (TREE_CODE (class) == CLASS_IMPLEMENTATION_TYPE)
5546 error ("duplicate definition of class method `%s'",
5547 IDENTIFIER_POINTER (METHOD_SEL_NAME (mth)));
5550 /* Check types; if different, complain. */
5551 if (!comp_proto_with_proto (method, mth))
5552 error ("duplicate declaration of class method `%s'",
5553 IDENTIFIER_POINTER (METHOD_SEL_NAME (mth)));
5557 if (!(hsh = hash_lookup (cls_method_hash_list, METHOD_SEL_NAME (method))))
5559 /* Install on a global chain. */
5560 hash_enter (cls_method_hash_list, method);
5564 /* Check types; if different, add to a list. */
5565 if (!comp_proto_with_proto (method, hsh->key))
5566 hash_add_attr (hsh, method);
5572 add_instance_method (class, method)
5579 if (!(mth = lookup_method (CLASS_NST_METHODS (class), method)))
5581 /* Put method on list in reverse order. */
5582 TREE_CHAIN (method) = CLASS_NST_METHODS (class);
5583 CLASS_NST_METHODS (class) = method;
5587 if (TREE_CODE (class) == CLASS_IMPLEMENTATION_TYPE)
5588 error ("duplicate definition of instance method `%s'",
5589 IDENTIFIER_POINTER (METHOD_SEL_NAME (mth)));
5592 /* Check types; if different, complain. */
5593 if (!comp_proto_with_proto (method, mth))
5594 error ("duplicate declaration of instance method `%s'",
5595 IDENTIFIER_POINTER (METHOD_SEL_NAME (mth)));
5599 if (!(hsh = hash_lookup (nst_method_hash_list, METHOD_SEL_NAME (method))))
5601 /* Install on a global chain. */
5602 hash_enter (nst_method_hash_list, method);
5606 /* Check types; if different, add to a list. */
5607 if (!comp_proto_with_proto (method, hsh->key))
5608 hash_add_attr (hsh, method);
5617 /* Put interfaces on list in reverse order. */
5618 TREE_CHAIN (class) = interface_chain;
5619 interface_chain = class;
5620 return interface_chain;
5624 add_category (class, category)
5628 /* Put categories on list in reverse order. */
5629 tree cat = CLASS_CATEGORY_LIST (class);
5633 if (CLASS_SUPER_NAME (cat) == CLASS_SUPER_NAME (category))
5634 warning ("duplicate interface declaration for category `%s(%s)'",
5635 IDENTIFIER_POINTER (CLASS_NAME (class)),
5636 IDENTIFIER_POINTER (CLASS_SUPER_NAME (category)));
5637 cat = CLASS_CATEGORY_LIST (cat);
5640 CLASS_CATEGORY_LIST (category) = CLASS_CATEGORY_LIST (class);
5641 CLASS_CATEGORY_LIST (class) = category;
5644 /* Called after parsing each instance variable declaration. Necessary to
5645 preserve typedefs and implement public/private...
5647 PUBLIC is 1 for public, 0 for protected, and 2 for private. */
5650 add_instance_variable (class, public, declarator, declspecs, width)
5657 tree field_decl, raw_decl;
5659 raw_decl = build_tree_list (declspecs, declarator);
5661 if (CLASS_RAW_IVARS (class))
5662 chainon (CLASS_RAW_IVARS (class), raw_decl);
5664 CLASS_RAW_IVARS (class) = raw_decl;
5666 field_decl = grokfield (input_filename, lineno,
5667 declarator, declspecs, width);
5669 /* Overload the public attribute, it is not used for FIELD_DECLs. */
5673 TREE_PUBLIC (field_decl) = 0;
5674 TREE_PRIVATE (field_decl) = 0;
5675 TREE_PROTECTED (field_decl) = 1;
5679 TREE_PUBLIC (field_decl) = 1;
5680 TREE_PRIVATE (field_decl) = 0;
5681 TREE_PROTECTED (field_decl) = 0;
5685 TREE_PUBLIC (field_decl) = 0;
5686 TREE_PRIVATE (field_decl) = 1;
5687 TREE_PROTECTED (field_decl) = 0;
5692 if (CLASS_IVARS (class))
5693 chainon (CLASS_IVARS (class), field_decl);
5695 CLASS_IVARS (class) = field_decl;
5701 is_ivar (decl_chain, ident)
5705 for ( ; decl_chain; decl_chain = TREE_CHAIN (decl_chain))
5706 if (DECL_NAME (decl_chain) == ident)
5711 /* True if the ivar is private and we are not in its implementation. */
5717 if (TREE_PRIVATE (decl)
5718 && ! is_ivar (CLASS_IVARS (implementation_template), DECL_NAME (decl)))
5720 error ("instance variable `%s' is declared private",
5721 IDENTIFIER_POINTER (DECL_NAME (decl)));
5728 /* We have an instance variable reference;, check to see if it is public. */
5731 is_public (expr, identifier)
5735 tree basetype = TREE_TYPE (expr);
5736 enum tree_code code = TREE_CODE (basetype);
5739 if (code == RECORD_TYPE)
5741 if (TREE_STATIC_TEMPLATE (basetype))
5743 if (!lookup_interface (TYPE_NAME (basetype)))
5745 error ("cannot find interface declaration for `%s'",
5746 IDENTIFIER_POINTER (TYPE_NAME (basetype)));
5750 if ((decl = is_ivar (TYPE_FIELDS (basetype), identifier)))
5752 if (TREE_PUBLIC (decl))
5755 /* Important difference between the Stepstone translator:
5756 all instance variables should be public within the context
5757 of the implementation. */
5758 if (objc_implementation_context
5759 && (((TREE_CODE (objc_implementation_context)
5760 == CLASS_IMPLEMENTATION_TYPE)
5761 || (TREE_CODE (objc_implementation_context)
5762 == CATEGORY_IMPLEMENTATION_TYPE))
5763 && (CLASS_NAME (objc_implementation_context)
5764 == TYPE_NAME (basetype))))
5765 return ! is_private (decl);
5767 error ("instance variable `%s' is declared %s",
5768 IDENTIFIER_POINTER (identifier),
5769 TREE_PRIVATE (decl) ? "private" : "protected");
5774 else if (objc_implementation_context && (basetype == objc_object_reference))
5776 TREE_TYPE (expr) = uprivate_record;
5777 warning ("static access to object of type `id'");
5784 /* Implement @defs (<classname>) within struct bodies. */
5787 get_class_ivars (interface)
5790 /* Make sure we copy the leaf ivars in case @defs is used in a local
5791 context. Otherwise finish_struct will overwrite the layout info
5792 using temporary storage. */
5793 return build_ivar_chain (interface, 1);
5796 /* Make sure all entries in CHAIN are also in LIST. */
5799 check_methods (chain, list, mtype)
5808 if (!lookup_method (list, chain))
5812 if (TREE_CODE (objc_implementation_context)
5813 == CLASS_IMPLEMENTATION_TYPE)
5814 warning ("incomplete implementation of class `%s'",
5815 IDENTIFIER_POINTER (CLASS_NAME (objc_implementation_context)));
5816 else if (TREE_CODE (objc_implementation_context)
5817 == CATEGORY_IMPLEMENTATION_TYPE)
5818 warning ("incomplete implementation of category `%s'",
5819 IDENTIFIER_POINTER (CLASS_SUPER_NAME (objc_implementation_context)));
5823 warning ("method definition for `%c%s' not found",
5824 mtype, IDENTIFIER_POINTER (METHOD_SEL_NAME (chain)));
5827 chain = TREE_CHAIN (chain);
5833 /* Check if CLASS, or its superclasses, explicitly conforms to PROTOCOL. */
5836 conforms_to_protocol (class, protocol)
5840 if (TREE_CODE (protocol) == PROTOCOL_INTERFACE_TYPE)
5842 tree p = CLASS_PROTOCOL_LIST (class);
5843 while (p && TREE_VALUE (p) != protocol)
5848 tree super = (CLASS_SUPER_NAME (class)
5849 ? lookup_interface (CLASS_SUPER_NAME (class))
5851 int tmp = super ? conforms_to_protocol (super, protocol) : 0;
5860 /* Make sure all methods in CHAIN are accessible as MTYPE methods in
5861 CONTEXT. This is one of two mechanisms to check protocol integrity. */
5864 check_methods_accessible (chain, context, mtype)
5871 tree base_context = context;
5875 context = base_context;
5879 list = CLASS_CLS_METHODS (context);
5881 list = CLASS_NST_METHODS (context);
5883 if (lookup_method (list, chain))
5886 else if (TREE_CODE (context) == CLASS_IMPLEMENTATION_TYPE
5887 || TREE_CODE (context) == CLASS_INTERFACE_TYPE)
5888 context = (CLASS_SUPER_NAME (context)
5889 ? lookup_interface (CLASS_SUPER_NAME (context))
5892 else if (TREE_CODE (context) == CATEGORY_IMPLEMENTATION_TYPE
5893 || TREE_CODE (context) == CATEGORY_INTERFACE_TYPE)
5894 context = (CLASS_NAME (context)
5895 ? lookup_interface (CLASS_NAME (context))
5901 if (context == NULL_TREE)
5905 if (TREE_CODE (objc_implementation_context)
5906 == CLASS_IMPLEMENTATION_TYPE)
5907 warning ("incomplete implementation of class `%s'",
5909 (CLASS_NAME (objc_implementation_context)));
5910 else if (TREE_CODE (objc_implementation_context)
5911 == CATEGORY_IMPLEMENTATION_TYPE)
5912 warning ("incomplete implementation of category `%s'",
5914 (CLASS_SUPER_NAME (objc_implementation_context)));
5917 warning ("method definition for `%c%s' not found",
5918 mtype, IDENTIFIER_POINTER (METHOD_SEL_NAME (chain)));
5921 chain = TREE_CHAIN (chain); /* next method... */
5926 /* Check whether the current interface (accessible via
5927 'objc_implementation_context') actually implements protocol P, along
5928 with any protocols that P inherits. */
5931 check_protocol (p, type, name)
5936 if (TREE_CODE (p) == PROTOCOL_INTERFACE_TYPE)
5940 /* Ensure that all protocols have bodies! */
5941 if (flag_warn_protocol)
5943 f1 = check_methods (PROTOCOL_CLS_METHODS (p),
5944 CLASS_CLS_METHODS (objc_implementation_context),
5946 f2 = check_methods (PROTOCOL_NST_METHODS (p),
5947 CLASS_NST_METHODS (objc_implementation_context),
5952 f1 = check_methods_accessible (PROTOCOL_CLS_METHODS (p),
5953 objc_implementation_context,
5955 f2 = check_methods_accessible (PROTOCOL_NST_METHODS (p),
5956 objc_implementation_context,
5961 warning ("%s `%s' does not fully implement the `%s' protocol",
5962 type, name, IDENTIFIER_POINTER (PROTOCOL_NAME (p)));
5965 /* Check protocols recursively. */
5966 if (PROTOCOL_LIST (p))
5968 tree subs = PROTOCOL_LIST (p);
5970 lookup_interface (CLASS_SUPER_NAME (implementation_template));
5974 tree sub = TREE_VALUE (subs);
5976 /* If the superclass does not conform to the protocols
5977 inherited by P, then we must! */
5978 if (!super_class || !conforms_to_protocol (super_class, sub))
5979 check_protocol (sub, type, name);
5980 subs = TREE_CHAIN (subs);
5985 /* Check whether the current interface (accessible via
5986 'objc_implementation_context') actually implements the protocols listed
5990 check_protocols (proto_list, type, name)
5995 for ( ; proto_list; proto_list = TREE_CHAIN (proto_list))
5997 tree p = TREE_VALUE (proto_list);
5999 check_protocol (p, type, name);
6003 /* Make sure that the class CLASS_NAME is defined
6004 CODE says which kind of thing CLASS_NAME ought to be.
6005 It can be CLASS_INTERFACE_TYPE, CLASS_IMPLEMENTATION_TYPE,
6006 CATEGORY_INTERFACE_TYPE, or CATEGORY_IMPLEMENTATION_TYPE. */
6009 start_class (code, class_name, super_name, protocol_list)
6010 enum tree_code code;
6017 if (objc_implementation_context)
6019 warning ("`@end' missing in implementation context");
6020 finish_class (objc_implementation_context);
6021 objc_ivar_chain = NULL_TREE;
6022 objc_implementation_context = NULL_TREE;
6025 class = make_node (code);
6026 TYPE_BINFO (class) = make_tree_vec (5);
6028 CLASS_NAME (class) = class_name;
6029 CLASS_SUPER_NAME (class) = super_name;
6030 CLASS_CLS_METHODS (class) = NULL_TREE;
6032 if (! is_class_name (class_name) && (decl = lookup_name (class_name)))
6034 error ("`%s' redeclared as different kind of symbol",
6035 IDENTIFIER_POINTER (class_name));
6036 error_with_decl (decl, "previous declaration of `%s'");
6039 if (code == CLASS_IMPLEMENTATION_TYPE)
6044 for (chain = implemented_classes; chain; chain = TREE_CHAIN (chain))
6045 if (TREE_VALUE (chain) == class_name)
6047 error ("reimplementation of class `%s'",
6048 IDENTIFIER_POINTER (class_name));
6049 return error_mark_node;
6051 implemented_classes = tree_cons (NULL_TREE, class_name,
6052 implemented_classes);
6055 /* Pre-build the following entities - for speed/convenience. */
6057 self_id = get_identifier ("self");
6059 ucmd_id = get_identifier ("_cmd");
6062 = build_tree_list (get_identifier ("__unused__"), NULL_TREE);
6063 if (!objc_super_template)
6064 objc_super_template = build_super_template ();
6066 /* Reset for multiple classes per file. */
6069 objc_implementation_context = class;
6071 /* Lookup the interface for this implementation. */
6073 if (!(implementation_template = lookup_interface (class_name)))
6075 warning ("cannot find interface declaration for `%s'",
6076 IDENTIFIER_POINTER (class_name));
6077 add_class (implementation_template = objc_implementation_context);
6080 /* If a super class has been specified in the implementation,
6081 insure it conforms to the one specified in the interface. */
6084 && (super_name != CLASS_SUPER_NAME (implementation_template)))
6086 tree previous_name = CLASS_SUPER_NAME (implementation_template);
6087 const char *const name =
6088 previous_name ? IDENTIFIER_POINTER (previous_name) : "";
6089 error ("conflicting super class name `%s'",
6090 IDENTIFIER_POINTER (super_name));
6091 error ("previous declaration of `%s'", name);
6094 else if (! super_name)
6096 CLASS_SUPER_NAME (objc_implementation_context)
6097 = CLASS_SUPER_NAME (implementation_template);
6101 else if (code == CLASS_INTERFACE_TYPE)
6103 if (lookup_interface (class_name))
6104 warning ("duplicate interface declaration for class `%s'",
6105 IDENTIFIER_POINTER (class_name));
6110 CLASS_PROTOCOL_LIST (class)
6111 = lookup_and_install_protocols (protocol_list);
6114 else if (code == CATEGORY_INTERFACE_TYPE)
6116 tree class_category_is_assoc_with;
6118 /* For a category, class_name is really the name of the class that
6119 the following set of methods will be associated with. We must
6120 find the interface so that can derive the objects template. */
6122 if (!(class_category_is_assoc_with = lookup_interface (class_name)))
6124 error ("cannot find interface declaration for `%s'",
6125 IDENTIFIER_POINTER (class_name));
6126 exit (FATAL_EXIT_CODE);
6129 add_category (class_category_is_assoc_with, class);
6132 CLASS_PROTOCOL_LIST (class)
6133 = lookup_and_install_protocols (protocol_list);
6136 else if (code == CATEGORY_IMPLEMENTATION_TYPE)
6138 /* Pre-build the following entities for speed/convenience. */
6140 self_id = get_identifier ("self");
6142 ucmd_id = get_identifier ("_cmd");
6145 = build_tree_list (get_identifier ("__unused__"), NULL_TREE);
6146 if (!objc_super_template)
6147 objc_super_template = build_super_template ();
6149 /* Reset for multiple classes per file. */
6152 objc_implementation_context = class;
6154 /* For a category, class_name is really the name of the class that
6155 the following set of methods will be associated with. We must
6156 find the interface so that can derive the objects template. */
6158 if (!(implementation_template = lookup_interface (class_name)))
6160 error ("cannot find interface declaration for `%s'",
6161 IDENTIFIER_POINTER (class_name));
6162 exit (FATAL_EXIT_CODE);
6169 continue_class (class)
6172 if (TREE_CODE (class) == CLASS_IMPLEMENTATION_TYPE
6173 || TREE_CODE (class) == CATEGORY_IMPLEMENTATION_TYPE)
6175 struct imp_entry *imp_entry;
6178 /* Check consistency of the instance variables. */
6180 if (CLASS_IVARS (class))
6181 check_ivars (implementation_template, class);
6183 /* code generation */
6185 ivar_context = build_private_template (implementation_template);
6187 if (!objc_class_template)
6188 build_class_template ();
6190 imp_entry = (struct imp_entry *) xmalloc (sizeof (struct imp_entry));
6192 imp_entry->next = imp_list;
6193 imp_entry->imp_context = class;
6194 imp_entry->imp_template = implementation_template;
6196 synth_forward_declarations ();
6197 imp_entry->class_decl = UOBJC_CLASS_decl;
6198 imp_entry->meta_decl = UOBJC_METACLASS_decl;
6200 /* Append to front and increment count. */
6201 imp_list = imp_entry;
6202 if (TREE_CODE (class) == CLASS_IMPLEMENTATION_TYPE)
6207 return ivar_context;
6210 else if (TREE_CODE (class) == CLASS_INTERFACE_TYPE)
6212 tree record = xref_tag (RECORD_TYPE, CLASS_NAME (class));
6214 if (!TYPE_FIELDS (record))
6216 finish_struct (record, build_ivar_chain (class, 0), NULL_TREE);
6217 CLASS_STATIC_TEMPLATE (class) = record;
6219 /* Mark this record as a class template for static typing. */
6220 TREE_STATIC_TEMPLATE (record) = 1;
6227 return error_mark_node;
6230 /* This is called once we see the "@end" in an interface/implementation. */
6233 finish_class (class)
6236 if (TREE_CODE (class) == CLASS_IMPLEMENTATION_TYPE)
6238 /* All code generation is done in finish_objc. */
6240 if (implementation_template != objc_implementation_context)
6242 /* Ensure that all method listed in the interface contain bodies. */
6243 check_methods (CLASS_CLS_METHODS (implementation_template),
6244 CLASS_CLS_METHODS (objc_implementation_context), '+');
6245 check_methods (CLASS_NST_METHODS (implementation_template),
6246 CLASS_NST_METHODS (objc_implementation_context), '-');
6248 if (CLASS_PROTOCOL_LIST (implementation_template))
6249 check_protocols (CLASS_PROTOCOL_LIST (implementation_template),
6251 IDENTIFIER_POINTER (CLASS_NAME (objc_implementation_context)));
6255 else if (TREE_CODE (class) == CATEGORY_IMPLEMENTATION_TYPE)
6257 tree category = CLASS_CATEGORY_LIST (implementation_template);
6259 /* Find the category interface from the class it is associated with. */
6262 if (CLASS_SUPER_NAME (class) == CLASS_SUPER_NAME (category))
6264 category = CLASS_CATEGORY_LIST (category);
6269 /* Ensure all method listed in the interface contain bodies. */
6270 check_methods (CLASS_CLS_METHODS (category),
6271 CLASS_CLS_METHODS (objc_implementation_context), '+');
6272 check_methods (CLASS_NST_METHODS (category),
6273 CLASS_NST_METHODS (objc_implementation_context), '-');
6275 if (CLASS_PROTOCOL_LIST (category))
6276 check_protocols (CLASS_PROTOCOL_LIST (category),
6278 IDENTIFIER_POINTER (CLASS_SUPER_NAME (objc_implementation_context)));
6282 else if (TREE_CODE (class) == CLASS_INTERFACE_TYPE)
6285 const char *class_name = IDENTIFIER_POINTER (CLASS_NAME (class));
6286 char *string = (char *) alloca (strlen (class_name) + 3);
6288 /* extern struct objc_object *_<my_name>; */
6290 sprintf (string, "_%s", class_name);
6292 decl_specs = build_tree_list (NULL_TREE, ridpointers[(int) RID_EXTERN]);
6293 decl_specs = tree_cons (NULL_TREE, objc_object_reference, decl_specs);
6294 define_decl (build1 (INDIRECT_REF, NULL_TREE, get_identifier (string)),
6300 add_protocol (protocol)
6303 /* Put protocol on list in reverse order. */
6304 TREE_CHAIN (protocol) = protocol_chain;
6305 protocol_chain = protocol;
6306 return protocol_chain;
6310 lookup_protocol (ident)
6315 for (chain = protocol_chain; chain; chain = TREE_CHAIN (chain))
6316 if (ident == PROTOCOL_NAME (chain))
6322 /* This function forward declares the protocols named by NAMES. If
6323 they are already declared or defined, the function has no effect. */
6326 objc_declare_protocols (names)
6331 for (list = names; list; list = TREE_CHAIN (list))
6333 tree name = TREE_VALUE (list);
6335 if (lookup_protocol (name) == NULL_TREE)
6337 tree protocol = make_node (PROTOCOL_INTERFACE_TYPE);
6339 TYPE_BINFO (protocol) = make_tree_vec (2);
6340 PROTOCOL_NAME (protocol) = name;
6341 PROTOCOL_LIST (protocol) = NULL_TREE;
6342 add_protocol (protocol);
6343 PROTOCOL_DEFINED (protocol) = 0;
6344 PROTOCOL_FORWARD_DECL (protocol) = NULL_TREE;
6350 start_protocol (code, name, list)
6351 enum tree_code code;
6357 /* This is as good a place as any. Need to invoke
6358 push_tag_toplevel. */
6359 if (!objc_protocol_template)
6360 objc_protocol_template = build_protocol_template ();
6362 protocol = lookup_protocol (name);
6366 protocol = make_node (code);
6367 TYPE_BINFO (protocol) = make_tree_vec (2);
6369 PROTOCOL_NAME (protocol) = name;
6370 PROTOCOL_LIST (protocol) = lookup_and_install_protocols (list);
6371 add_protocol (protocol);
6372 PROTOCOL_DEFINED (protocol) = 1;
6373 PROTOCOL_FORWARD_DECL (protocol) = NULL_TREE;
6375 check_protocol_recursively (protocol, list);
6377 else if (! PROTOCOL_DEFINED (protocol))
6379 PROTOCOL_DEFINED (protocol) = 1;
6380 PROTOCOL_LIST (protocol) = lookup_and_install_protocols (list);
6382 check_protocol_recursively (protocol, list);
6386 warning ("duplicate declaration for protocol `%s'",
6387 IDENTIFIER_POINTER (name));
6393 finish_protocol (protocol)
6394 tree protocol ATTRIBUTE_UNUSED;
6399 /* "Encode" a data type into a string, which grows in util_obstack.
6400 ??? What is the FORMAT? Someone please document this! */
6403 encode_type_qualifiers (declspecs)
6408 for (spec = declspecs; spec; spec = TREE_CHAIN (spec))
6410 if (ridpointers[(int) RID_CONST] == TREE_VALUE (spec))
6411 obstack_1grow (&util_obstack, 'r');
6412 else if (ridpointers[(int) RID_IN] == TREE_VALUE (spec))
6413 obstack_1grow (&util_obstack, 'n');
6414 else if (ridpointers[(int) RID_INOUT] == TREE_VALUE (spec))
6415 obstack_1grow (&util_obstack, 'N');
6416 else if (ridpointers[(int) RID_OUT] == TREE_VALUE (spec))
6417 obstack_1grow (&util_obstack, 'o');
6418 else if (ridpointers[(int) RID_BYCOPY] == TREE_VALUE (spec))
6419 obstack_1grow (&util_obstack, 'O');
6420 else if (ridpointers[(int) RID_BYREF] == TREE_VALUE (spec))
6421 obstack_1grow (&util_obstack, 'R');
6422 else if (ridpointers[(int) RID_ONEWAY] == TREE_VALUE (spec))
6423 obstack_1grow (&util_obstack, 'V');
6427 /* Encode a pointer type. */
6430 encode_pointer (type, curtype, format)
6435 tree pointer_to = TREE_TYPE (type);
6437 if (TREE_CODE (pointer_to) == RECORD_TYPE)
6439 if (TYPE_NAME (pointer_to)
6440 && TREE_CODE (TYPE_NAME (pointer_to)) == IDENTIFIER_NODE)
6442 const char *name = IDENTIFIER_POINTER (TYPE_NAME (pointer_to));
6444 if (strcmp (name, TAG_OBJECT) == 0) /* '@' */
6446 obstack_1grow (&util_obstack, '@');
6449 else if (TREE_STATIC_TEMPLATE (pointer_to))
6451 if (generating_instance_variables)
6453 obstack_1grow (&util_obstack, '@');
6454 obstack_1grow (&util_obstack, '"');
6455 obstack_grow (&util_obstack, name, strlen (name));
6456 obstack_1grow (&util_obstack, '"');
6461 obstack_1grow (&util_obstack, '@');
6465 else if (strcmp (name, TAG_CLASS) == 0) /* '#' */
6467 obstack_1grow (&util_obstack, '#');
6470 else if (strcmp (name, TAG_SELECTOR) == 0) /* ':' */
6472 obstack_1grow (&util_obstack, ':');
6477 else if (TREE_CODE (pointer_to) == INTEGER_TYPE
6478 && TYPE_MODE (pointer_to) == QImode)
6480 obstack_1grow (&util_obstack, '*');
6484 /* We have a type that does not get special treatment. */
6486 /* NeXT extension */
6487 obstack_1grow (&util_obstack, '^');
6488 encode_type (pointer_to, curtype, format);
6492 encode_array (type, curtype, format)
6497 tree an_int_cst = TYPE_SIZE (type);
6498 tree array_of = TREE_TYPE (type);
6501 /* An incomplete array is treated like a pointer. */
6502 if (an_int_cst == NULL)
6504 encode_pointer (type, curtype, format);
6508 sprintf (buffer, "[%ld",
6509 (long) (TREE_INT_CST_LOW (an_int_cst)
6510 / TREE_INT_CST_LOW (TYPE_SIZE (array_of))));
6512 obstack_grow (&util_obstack, buffer, strlen (buffer));
6513 encode_type (array_of, curtype, format);
6514 obstack_1grow (&util_obstack, ']');
6519 encode_aggregate_within (type, curtype, format, left, right)
6526 /* The RECORD_TYPE may in fact be a typedef! For purposes
6527 of encoding, we need the real underlying enchilada. */
6528 if (TYPE_MAIN_VARIANT (type))
6529 type = TYPE_MAIN_VARIANT (type);
6531 if (obstack_object_size (&util_obstack) > 0
6532 && *(obstack_next_free (&util_obstack) - 1) == '^')
6534 tree name = TYPE_NAME (type);
6536 /* we have a reference; this is a NeXT extension. */
6538 if (obstack_object_size (&util_obstack) - curtype == 1
6539 && format == OBJC_ENCODE_INLINE_DEFS)
6541 /* Output format of struct for first level only. */
6542 tree fields = TYPE_FIELDS (type);
6544 if (name && TREE_CODE (name) == IDENTIFIER_NODE)
6546 obstack_1grow (&util_obstack, left);
6547 obstack_grow (&util_obstack,
6548 IDENTIFIER_POINTER (name),
6549 strlen (IDENTIFIER_POINTER (name)));
6550 obstack_1grow (&util_obstack, '=');
6554 obstack_1grow (&util_obstack, left);
6555 obstack_grow (&util_obstack, "?=", 2);
6558 for ( ; fields; fields = TREE_CHAIN (fields))
6559 encode_field_decl (fields, curtype, format);
6561 obstack_1grow (&util_obstack, right);
6564 else if (name && TREE_CODE (name) == IDENTIFIER_NODE)
6566 obstack_1grow (&util_obstack, left);
6567 obstack_grow (&util_obstack,
6568 IDENTIFIER_POINTER (name),
6569 strlen (IDENTIFIER_POINTER (name)));
6570 obstack_1grow (&util_obstack, right);
6575 /* We have an untagged structure or a typedef. */
6576 obstack_1grow (&util_obstack, left);
6577 obstack_1grow (&util_obstack, '?');
6578 obstack_1grow (&util_obstack, right);
6584 tree name = TYPE_NAME (type);
6585 tree fields = TYPE_FIELDS (type);
6587 if (format == OBJC_ENCODE_INLINE_DEFS
6588 || generating_instance_variables)
6590 obstack_1grow (&util_obstack, left);
6591 if (name && TREE_CODE (name) == IDENTIFIER_NODE)
6592 obstack_grow (&util_obstack,
6593 IDENTIFIER_POINTER (name),
6594 strlen (IDENTIFIER_POINTER (name)));
6596 obstack_1grow (&util_obstack, '?');
6598 obstack_1grow (&util_obstack, '=');
6600 for (; fields; fields = TREE_CHAIN (fields))
6602 if (generating_instance_variables)
6604 tree fname = DECL_NAME (fields);
6606 obstack_1grow (&util_obstack, '"');
6607 if (fname && TREE_CODE (fname) == IDENTIFIER_NODE)
6609 obstack_grow (&util_obstack,
6610 IDENTIFIER_POINTER (fname),
6611 strlen (IDENTIFIER_POINTER (fname)));
6614 obstack_1grow (&util_obstack, '"');
6617 encode_field_decl (fields, curtype, format);
6620 obstack_1grow (&util_obstack, right);
6625 obstack_1grow (&util_obstack, left);
6626 if (name && TREE_CODE (name) == IDENTIFIER_NODE)
6627 obstack_grow (&util_obstack,
6628 IDENTIFIER_POINTER (name),
6629 strlen (IDENTIFIER_POINTER (name)));
6631 /* We have an untagged structure or a typedef. */
6632 obstack_1grow (&util_obstack, '?');
6634 obstack_1grow (&util_obstack, right);
6640 encode_aggregate (type, curtype, format)
6645 enum tree_code code = TREE_CODE (type);
6651 encode_aggregate_within(type, curtype, format, '{', '}');
6656 encode_aggregate_within(type, curtype, format, '(', ')');
6661 obstack_1grow (&util_obstack, 'i');
6669 /* Support bitfields. The current version of Objective-C does not support
6670 them. The string will consist of one or more "b:n"'s where n is an
6671 integer describing the width of the bitfield. Currently, classes in
6672 the kit implement a method "-(char *)describeBitfieldStruct:" that
6673 simulates this. If they do not implement this method, the archiver
6674 assumes the bitfield is 16 bits wide (padded if necessary) and packed
6675 according to the GNU compiler. After looking at the "kit", it appears
6676 that all classes currently rely on this default behavior, rather than
6677 hand generating this string (which is tedious). */
6680 encode_bitfield (width)
6684 sprintf (buffer, "b%d", width);
6685 obstack_grow (&util_obstack, buffer, strlen (buffer));
6688 /* FORMAT will be OBJC_ENCODE_INLINE_DEFS or OBJC_ENCODE_DONT_INLINE_DEFS. */
6691 encode_type (type, curtype, format)
6696 enum tree_code code = TREE_CODE (type);
6698 if (code == INTEGER_TYPE)
6700 if (integer_zerop (TYPE_MIN_VALUE (type)))
6702 /* Unsigned integer types. */
6704 if (TYPE_MODE (type) == QImode)
6705 obstack_1grow (&util_obstack, 'C');
6706 else if (TYPE_MODE (type) == HImode)
6707 obstack_1grow (&util_obstack, 'S');
6708 else if (TYPE_MODE (type) == SImode)
6710 if (type == long_unsigned_type_node)
6711 obstack_1grow (&util_obstack, 'L');
6713 obstack_1grow (&util_obstack, 'I');
6715 else if (TYPE_MODE (type) == DImode)
6716 obstack_1grow (&util_obstack, 'Q');
6720 /* Signed integer types. */
6722 if (TYPE_MODE (type) == QImode)
6723 obstack_1grow (&util_obstack, 'c');
6724 else if (TYPE_MODE (type) == HImode)
6725 obstack_1grow (&util_obstack, 's');
6726 else if (TYPE_MODE (type) == SImode)
6728 if (type == long_integer_type_node)
6729 obstack_1grow (&util_obstack, 'l');
6731 obstack_1grow (&util_obstack, 'i');
6734 else if (TYPE_MODE (type) == DImode)
6735 obstack_1grow (&util_obstack, 'q');
6739 else if (code == REAL_TYPE)
6741 /* Floating point types. */
6743 if (TYPE_MODE (type) == SFmode)
6744 obstack_1grow (&util_obstack, 'f');
6745 else if (TYPE_MODE (type) == DFmode
6746 || TYPE_MODE (type) == TFmode)
6747 obstack_1grow (&util_obstack, 'd');
6750 else if (code == VOID_TYPE)
6751 obstack_1grow (&util_obstack, 'v');
6753 else if (code == ARRAY_TYPE)
6754 encode_array (type, curtype, format);
6756 else if (code == POINTER_TYPE)
6757 encode_pointer (type, curtype, format);
6759 else if (code == RECORD_TYPE || code == UNION_TYPE || code == ENUMERAL_TYPE)
6760 encode_aggregate (type, curtype, format);
6762 else if (code == FUNCTION_TYPE) /* '?' */
6763 obstack_1grow (&util_obstack, '?');
6767 encode_complete_bitfield (int position, tree type, int size)
6769 enum tree_code code = TREE_CODE (type);
6771 char charType = '?';
6773 if (code == INTEGER_TYPE)
6775 if (integer_zerop (TYPE_MIN_VALUE (type)))
6777 /* Unsigned integer types. */
6779 if (TYPE_MODE (type) == QImode)
6781 else if (TYPE_MODE (type) == HImode)
6783 else if (TYPE_MODE (type) == SImode)
6785 if (type == long_unsigned_type_node)
6790 else if (TYPE_MODE (type) == DImode)
6795 /* Signed integer types. */
6797 if (TYPE_MODE (type) == QImode)
6799 else if (TYPE_MODE (type) == HImode)
6801 else if (TYPE_MODE (type) == SImode)
6803 if (type == long_integer_type_node)
6809 else if (TYPE_MODE (type) == DImode)
6813 else if (code == ENUMERAL_TYPE)
6818 sprintf (buffer, "b%d%c%d", position, charType, size);
6819 obstack_grow (&util_obstack, buffer, strlen (buffer));
6823 encode_field_decl (field_decl, curtype, format)
6830 type = TREE_TYPE (field_decl);
6832 /* If this field is obviously a bitfield, or is a bitfield that has been
6833 clobbered to look like a ordinary integer mode, go ahead and generate
6834 the bitfield typing information. */
6835 if (flag_next_runtime)
6837 if (DECL_BIT_FIELD (field_decl))
6838 encode_bitfield (tree_low_cst (DECL_SIZE (field_decl), 1));
6840 encode_type (TREE_TYPE (field_decl), curtype, format);
6844 if (DECL_BIT_FIELD (field_decl))
6845 encode_complete_bitfield (int_bit_position (field_decl),
6846 DECL_BIT_FIELD_TYPE (field_decl),
6847 tree_low_cst (DECL_SIZE (field_decl), 1));
6849 encode_type (TREE_TYPE (field_decl), curtype, format);
6854 expr_last (complex_expr)
6860 while ((next = TREE_OPERAND (complex_expr, 0)))
6861 complex_expr = next;
6863 return complex_expr;
6866 /* Transform a method definition into a function definition as follows:
6867 - synthesize the first two arguments, "self" and "_cmd". */
6870 start_method_def (method)
6875 /* Required to implement _msgSuper. */
6876 objc_method_context = method;
6877 UOBJC_SUPER_decl = NULL_TREE;
6879 /* Must be called BEFORE start_function. */
6882 /* Generate prototype declarations for arguments..."new-style". */
6884 if (TREE_CODE (objc_method_context) == INSTANCE_METHOD_DECL)
6885 decl_specs = build_tree_list (NULL_TREE, uprivate_record);
6887 /* Really a `struct objc_class *'. However, we allow people to
6888 assign to self, which changes its type midstream. */
6889 decl_specs = build_tree_list (NULL_TREE, objc_object_reference);
6891 push_parm_decl (build_tree_list
6892 (build_tree_list (decl_specs,
6893 build1 (INDIRECT_REF, NULL_TREE, self_id)),
6896 decl_specs = build_tree_list (NULL_TREE,
6897 xref_tag (RECORD_TYPE,
6898 get_identifier (TAG_SELECTOR)));
6899 push_parm_decl (build_tree_list
6900 (build_tree_list (decl_specs,
6901 build1 (INDIRECT_REF, NULL_TREE, ucmd_id)),
6904 /* Generate argument declarations if a keyword_decl. */
6905 if (METHOD_SEL_ARGS (method))
6907 tree arglist = METHOD_SEL_ARGS (method);
6910 tree arg_spec = TREE_PURPOSE (TREE_TYPE (arglist));
6911 tree arg_decl = TREE_VALUE (TREE_TYPE (arglist));
6915 tree last_expr = expr_last (arg_decl);
6917 /* Unite the abstract decl with its name. */
6918 TREE_OPERAND (last_expr, 0) = KEYWORD_ARG_NAME (arglist);
6919 push_parm_decl (build_tree_list
6920 (build_tree_list (arg_spec, arg_decl),
6923 /* Unhook: restore the abstract declarator. */
6924 TREE_OPERAND (last_expr, 0) = NULL_TREE;
6928 push_parm_decl (build_tree_list
6929 (build_tree_list (arg_spec,
6930 KEYWORD_ARG_NAME (arglist)),
6933 arglist = TREE_CHAIN (arglist);
6938 if (METHOD_ADD_ARGS (method) != NULL_TREE
6939 && METHOD_ADD_ARGS (method) != objc_ellipsis_node)
6941 /* We have a variable length selector - in "prototype" format. */
6942 tree akey = TREE_PURPOSE (METHOD_ADD_ARGS (method));
6945 /* This must be done prior to calling pushdecl. pushdecl is
6946 going to change our chain on us. */
6947 tree nextkey = TREE_CHAIN (akey);
6955 warn_with_method (message, mtype, method)
6956 const char *message;
6960 if (count_error (1) == 0)
6963 report_error_function (DECL_SOURCE_FILE (method));
6965 /* Add a readable method name to the warning. */
6966 warning_with_file_and_line (DECL_SOURCE_FILE (method),
6967 DECL_SOURCE_LINE (method),
6970 gen_method_decl (method, errbuf));
6973 /* Return 1 if METHOD is consistent with PROTO. */
6976 comp_method_with_proto (method, proto)
6979 /* Create a function template node at most once. */
6980 if (!function1_template)
6981 function1_template = make_node (FUNCTION_TYPE);
6983 /* Install argument types - normally set by build_function_type. */
6984 TYPE_ARG_TYPES (function1_template) = get_arg_type_list (proto, METHOD_DEF, 0);
6986 /* install return type */
6987 TREE_TYPE (function1_template) = groktypename (TREE_TYPE (proto));
6989 return comptypes (TREE_TYPE (METHOD_DEFINITION (method)), function1_template);
6992 /* Return 1 if PROTO1 is consistent with PROTO2. */
6995 comp_proto_with_proto (proto0, proto1)
6996 tree proto0, proto1;
6998 /* Create a couple of function_template nodes at most once. */
6999 if (!function1_template)
7000 function1_template = make_node (FUNCTION_TYPE);
7001 if (!function2_template)
7002 function2_template = make_node (FUNCTION_TYPE);
7004 /* Install argument types; normally set by build_function_type. */
7005 TYPE_ARG_TYPES (function1_template) = get_arg_type_list (proto0, METHOD_REF, 0);
7006 TYPE_ARG_TYPES (function2_template) = get_arg_type_list (proto1, METHOD_REF, 0);
7008 /* Install return type. */
7009 TREE_TYPE (function1_template) = groktypename (TREE_TYPE (proto0));
7010 TREE_TYPE (function2_template) = groktypename (TREE_TYPE (proto1));
7012 return comptypes (function1_template, function2_template);
7015 /* - Generate an identifier for the function. the format is "_n_cls",
7016 where 1 <= n <= nMethods, and cls is the name the implementation we
7018 - Install the return type from the method declaration.
7019 - If we have a prototype, check for type consistency. */
7022 really_start_method (method, parmlist)
7023 tree method, parmlist;
7025 tree sc_spec, ret_spec, ret_decl, decl_specs;
7026 tree method_decl, method_id;
7027 const char *sel_name, *class_name, *cat_name;
7030 /* Synth the storage class & assemble the return type. */
7031 sc_spec = tree_cons (NULL_TREE, ridpointers[(int) RID_STATIC], NULL_TREE);
7032 ret_spec = TREE_PURPOSE (TREE_TYPE (method));
7033 decl_specs = chainon (sc_spec, ret_spec);
7035 sel_name = IDENTIFIER_POINTER (METHOD_SEL_NAME (method));
7036 class_name = IDENTIFIER_POINTER (CLASS_NAME (objc_implementation_context));
7037 cat_name = ((TREE_CODE (objc_implementation_context)
7038 == CLASS_IMPLEMENTATION_TYPE)
7040 : IDENTIFIER_POINTER (CLASS_SUPER_NAME (objc_implementation_context)));
7043 /* Make sure this is big enough for any plausible method label. */
7044 buf = (char *) alloca (50 + strlen (sel_name) + strlen (class_name)
7045 + (cat_name ? strlen (cat_name) : 0));
7047 OBJC_GEN_METHOD_LABEL (buf, TREE_CODE (method) == INSTANCE_METHOD_DECL,
7048 class_name, cat_name, sel_name, method_slot);
7050 method_id = get_identifier (buf);
7052 method_decl = build_nt (CALL_EXPR, method_id, parmlist, NULL_TREE);
7054 /* Check the declarator portion of the return type for the method. */
7055 if ((ret_decl = TREE_VALUE (TREE_TYPE (method))))
7057 /* Unite the complex decl (specified in the abstract decl) with the
7058 function decl just synthesized..(int *), (int (*)()), (int (*)[]). */
7059 tree save_expr = expr_last (ret_decl);
7061 TREE_OPERAND (save_expr, 0) = method_decl;
7062 method_decl = ret_decl;
7064 /* Fool the parser into thinking it is starting a function. */
7065 start_function (decl_specs, method_decl, NULL_TREE);
7067 /* Unhook: this has the effect of restoring the abstract declarator. */
7068 TREE_OPERAND (save_expr, 0) = NULL_TREE;
7073 TREE_VALUE (TREE_TYPE (method)) = method_decl;
7075 /* Fool the parser into thinking it is starting a function. */
7076 start_function (decl_specs, method_decl, NULL_TREE);
7078 /* Unhook: this has the effect of restoring the abstract declarator. */
7079 TREE_VALUE (TREE_TYPE (method)) = NULL_TREE;
7082 METHOD_DEFINITION (method) = current_function_decl;
7084 /* Check consistency...start_function, pushdecl, duplicate_decls. */
7086 if (implementation_template != objc_implementation_context)
7090 if (TREE_CODE (method) == INSTANCE_METHOD_DECL)
7091 proto = lookup_instance_method_static (implementation_template,
7092 METHOD_SEL_NAME (method));
7094 proto = lookup_class_method_static (implementation_template,
7095 METHOD_SEL_NAME (method));
7097 if (proto && ! comp_method_with_proto (method, proto))
7099 char type = (TREE_CODE (method) == INSTANCE_METHOD_DECL ? '-' : '+');
7101 warn_with_method ("conflicting types for", type, method);
7102 warn_with_method ("previous declaration of", type, proto);
7107 /* The following routine is always called...this "architecture" is to
7108 accommodate "old-style" variable length selectors.
7110 - a:a b:b // prototype ; id c; id d; // old-style. */
7113 continue_method_def ()
7117 if (METHOD_ADD_ARGS (objc_method_context) == objc_ellipsis_node)
7118 /* We have a `, ...' immediately following the selector. */
7119 parmlist = get_parm_info (0);
7121 parmlist = get_parm_info (1); /* place a `void_at_end' */
7123 /* Set self_decl from the first argument...this global is used by
7124 build_ivar_reference calling build_indirect_ref. */
7125 self_decl = TREE_PURPOSE (parmlist);
7128 really_start_method (objc_method_context, parmlist);
7129 store_parm_decls ();
7132 /* Called by the parser, from the `pushlevel' production. */
7137 if (!UOBJC_SUPER_decl)
7139 UOBJC_SUPER_decl = start_decl (get_identifier (UTAG_SUPER),
7140 build_tree_list (NULL_TREE,
7141 objc_super_template),
7144 finish_decl (UOBJC_SUPER_decl, NULL_TREE, NULL_TREE);
7146 /* This prevents `unused variable' warnings when compiling with -Wall. */
7147 TREE_USED (UOBJC_SUPER_decl) = 1;
7148 DECL_ARTIFICIAL (UOBJC_SUPER_decl) = 1;
7152 /* _n_Method (id self, SEL sel, ...)
7154 struct objc_super _S;
7155 _msgSuper ((_S.self = self, _S.class = _cls, &_S), ...);
7159 get_super_receiver ()
7161 if (objc_method_context)
7163 tree super_expr, super_expr_list;
7165 /* Set receiver to self. */
7166 super_expr = build_component_ref (UOBJC_SUPER_decl, self_id);
7167 super_expr = build_modify_expr (super_expr, NOP_EXPR, self_decl);
7168 super_expr_list = build_tree_list (NULL_TREE, super_expr);
7170 /* Set class to begin searching. */
7171 super_expr = build_component_ref (UOBJC_SUPER_decl,
7172 get_identifier ("class"));
7174 if (TREE_CODE (objc_implementation_context) == CLASS_IMPLEMENTATION_TYPE)
7176 /* [_cls, __cls]Super are "pre-built" in
7177 synth_forward_declarations. */
7179 super_expr = build_modify_expr (super_expr, NOP_EXPR,
7180 ((TREE_CODE (objc_method_context)
7181 == INSTANCE_METHOD_DECL)
7183 : uucls_super_ref));
7187 /* We have a category. */
7189 tree super_name = CLASS_SUPER_NAME (implementation_template);
7192 /* Barf if super used in a category of Object. */
7195 error ("no super class declared in interface for `%s'",
7196 IDENTIFIER_POINTER (CLASS_NAME (implementation_template)));
7197 return error_mark_node;
7200 if (flag_next_runtime)
7202 super_class = get_class_reference (super_name);
7203 if (TREE_CODE (objc_method_context) == CLASS_METHOD_DECL)
7205 = build_component_ref (build_indirect_ref (super_class, "->"),
7206 get_identifier ("isa"));
7210 add_class_reference (super_name);
7211 super_class = (TREE_CODE (objc_method_context) == INSTANCE_METHOD_DECL
7212 ? objc_get_class_decl : objc_get_meta_class_decl);
7213 assemble_external (super_class);
7215 = build_function_call
7219 my_build_string (IDENTIFIER_LENGTH (super_name) + 1,
7220 IDENTIFIER_POINTER (super_name))));
7223 TREE_TYPE (super_class) = TREE_TYPE (ucls_super_ref);
7224 super_expr = build_modify_expr (super_expr, NOP_EXPR, super_class);
7227 chainon (super_expr_list, build_tree_list (NULL_TREE, super_expr));
7229 super_expr = build_unary_op (ADDR_EXPR, UOBJC_SUPER_decl, 0);
7230 chainon (super_expr_list, build_tree_list (NULL_TREE, super_expr));
7232 return build_compound_expr (super_expr_list);
7236 error ("[super ...] must appear in a method context");
7237 return error_mark_node;
7242 encode_method_def (func_decl)
7247 HOST_WIDE_INT max_parm_end = 0;
7252 encode_type (TREE_TYPE (TREE_TYPE (func_decl)),
7253 obstack_object_size (&util_obstack),
7254 OBJC_ENCODE_INLINE_DEFS);
7257 for (parms = DECL_ARGUMENTS (func_decl); parms;
7258 parms = TREE_CHAIN (parms))
7260 HOST_WIDE_INT parm_end = (forwarding_offset (parms)
7261 + int_size_in_bytes (TREE_TYPE (parms)));
7263 if (! offset_is_register && parm_end > max_parm_end)
7264 max_parm_end = parm_end;
7267 stack_size = max_parm_end - OBJC_FORWARDING_MIN_OFFSET;
7269 sprintf (buffer, "%d", stack_size);
7270 obstack_grow (&util_obstack, buffer, strlen (buffer));
7272 /* Argument types. */
7273 for (parms = DECL_ARGUMENTS (func_decl); parms;
7274 parms = TREE_CHAIN (parms))
7277 encode_type (TREE_TYPE (parms),
7278 obstack_object_size (&util_obstack),
7279 OBJC_ENCODE_INLINE_DEFS);
7281 /* Compute offset. */
7282 sprintf (buffer, "%d", forwarding_offset (parms));
7284 /* Indicate register. */
7285 if (offset_is_register)
7286 obstack_1grow (&util_obstack, '+');
7288 obstack_grow (&util_obstack, buffer, strlen (buffer));
7291 /* Null terminate string. */
7292 obstack_1grow (&util_obstack, 0);
7293 result = get_identifier (obstack_finish (&util_obstack));
7294 obstack_free (&util_obstack, util_firstobj);
7299 objc_expand_function_end ()
7301 METHOD_ENCODING (objc_method_context) = encode_method_def (current_function_decl);
7305 finish_method_def ()
7307 lang_expand_function_end = objc_expand_function_end;
7308 finish_function (0);
7309 lang_expand_function_end = NULL;
7311 /* Required to implement _msgSuper. This must be done AFTER finish_function,
7312 since the optimizer may find "may be used before set" errors. */
7313 objc_method_context = NULL_TREE;
7318 lang_report_error_function (decl)
7321 if (objc_method_context)
7323 fprintf (stderr, "In method `%s'\n",
7324 IDENTIFIER_POINTER (METHOD_SEL_NAME (objc_method_context)));
7334 is_complex_decl (type)
7337 return (TREE_CODE (type) == ARRAY_TYPE
7338 || TREE_CODE (type) == FUNCTION_TYPE
7339 || (TREE_CODE (type) == POINTER_TYPE && ! IS_ID (type)));
7343 /* Code to convert a decl node into text for a declaration in C. */
7345 static char tmpbuf[256];
7348 adorn_decl (decl, str)
7352 enum tree_code code = TREE_CODE (decl);
7354 if (code == ARRAY_REF)
7356 tree an_int_cst = TREE_OPERAND (decl, 1);
7358 if (an_int_cst && TREE_CODE (an_int_cst) == INTEGER_CST)
7359 sprintf (str + strlen (str), "[%ld]",
7360 (long) TREE_INT_CST_LOW (an_int_cst));
7365 else if (code == ARRAY_TYPE)
7367 tree an_int_cst = TYPE_SIZE (decl);
7368 tree array_of = TREE_TYPE (decl);
7370 if (an_int_cst && TREE_CODE (an_int_cst) == INTEGER_TYPE)
7371 sprintf (str + strlen (str), "[%ld]",
7372 (long) (TREE_INT_CST_LOW (an_int_cst)
7373 / TREE_INT_CST_LOW (TYPE_SIZE (array_of))));
7378 else if (code == CALL_EXPR)
7380 tree chain = TREE_PURPOSE (TREE_OPERAND (decl, 1));
7385 gen_declaration_1 (chain, str);
7386 chain = TREE_CHAIN (chain);
7393 else if (code == FUNCTION_TYPE)
7395 tree chain = TYPE_ARG_TYPES (decl);
7398 while (chain && TREE_VALUE (chain) != void_type_node)
7400 gen_declaration_1 (TREE_VALUE (chain), str);
7401 chain = TREE_CHAIN (chain);
7402 if (chain && TREE_VALUE (chain) != void_type_node)
7408 else if (code == INDIRECT_REF)
7410 strcpy (tmpbuf, "*");
7411 if (TREE_TYPE (decl) && TREE_CODE (TREE_TYPE (decl)) == TREE_LIST)
7415 for (chain = nreverse (copy_list (TREE_TYPE (decl)));
7417 chain = TREE_CHAIN (chain))
7419 if (TREE_CODE (TREE_VALUE (chain)) == IDENTIFIER_NODE)
7421 strcat (tmpbuf, " ");
7422 strcat (tmpbuf, IDENTIFIER_POINTER (TREE_VALUE (chain)));
7426 strcat (tmpbuf, " ");
7428 strcat (tmpbuf, str);
7429 strcpy (str, tmpbuf);
7432 else if (code == POINTER_TYPE)
7434 strcpy (tmpbuf, "*");
7435 if (TREE_READONLY (decl) || TYPE_VOLATILE (decl))
7437 if (TREE_READONLY (decl))
7438 strcat (tmpbuf, " const");
7439 if (TYPE_VOLATILE (decl))
7440 strcat (tmpbuf, " volatile");
7442 strcat (tmpbuf, " ");
7444 strcat (tmpbuf, str);
7445 strcpy (str, tmpbuf);
7450 gen_declarator (decl, buf, name)
7457 enum tree_code code = TREE_CODE (decl);
7467 op = TREE_OPERAND (decl, 0);
7469 /* We have a pointer to a function or array...(*)(), (*)[] */
7470 if ((code == ARRAY_REF || code == CALL_EXPR)
7471 && op && TREE_CODE (op) == INDIRECT_REF)
7474 str = gen_declarator (op, buf, name);
7478 strcpy (tmpbuf, "(");
7479 strcat (tmpbuf, str);
7480 strcat (tmpbuf, ")");
7481 strcpy (str, tmpbuf);
7484 adorn_decl (decl, str);
7493 /* This clause is done iteratively rather than recursively. */
7496 op = (is_complex_decl (TREE_TYPE (decl))
7497 ? TREE_TYPE (decl) : NULL_TREE);
7499 adorn_decl (decl, str);
7501 /* We have a pointer to a function or array...(*)(), (*)[] */
7502 if (code == POINTER_TYPE
7503 && op && (TREE_CODE (op) == FUNCTION_TYPE
7504 || TREE_CODE (op) == ARRAY_TYPE))
7506 strcpy (tmpbuf, "(");
7507 strcat (tmpbuf, str);
7508 strcat (tmpbuf, ")");
7509 strcpy (str, tmpbuf);
7512 decl = (is_complex_decl (TREE_TYPE (decl))
7513 ? TREE_TYPE (decl) : NULL_TREE);
7516 while (decl && (code = TREE_CODE (decl)))
7521 case IDENTIFIER_NODE:
7522 /* Will only happen if we are processing a "raw" expr-decl. */
7523 strcpy (buf, IDENTIFIER_POINTER (decl));
7534 /* We have an abstract declarator or a _DECL node. */
7542 gen_declspecs (declspecs, buf, raw)
7551 for (chain = nreverse (copy_list (declspecs));
7552 chain; chain = TREE_CHAIN (chain))
7554 tree aspec = TREE_VALUE (chain);
7556 if (TREE_CODE (aspec) == IDENTIFIER_NODE)
7557 strcat (buf, IDENTIFIER_POINTER (aspec));
7558 else if (TREE_CODE (aspec) == RECORD_TYPE)
7560 if (TYPE_NAME (aspec))
7562 tree protocol_list = TYPE_PROTOCOL_LIST (aspec);
7564 if (! TREE_STATIC_TEMPLATE (aspec))
7565 strcat (buf, "struct ");
7566 strcat (buf, IDENTIFIER_POINTER (TYPE_NAME (aspec)));
7571 tree chain = protocol_list;
7578 (PROTOCOL_NAME (TREE_VALUE (chain))));
7579 chain = TREE_CHAIN (chain);
7588 strcat (buf, "untagged struct");
7591 else if (TREE_CODE (aspec) == UNION_TYPE)
7593 if (TYPE_NAME (aspec))
7595 if (! TREE_STATIC_TEMPLATE (aspec))
7596 strcat (buf, "union ");
7597 strcat (buf, IDENTIFIER_POINTER (TYPE_NAME (aspec)));
7600 strcat (buf, "untagged union");
7603 else if (TREE_CODE (aspec) == ENUMERAL_TYPE)
7605 if (TYPE_NAME (aspec))
7607 if (! TREE_STATIC_TEMPLATE (aspec))
7608 strcat (buf, "enum ");
7609 strcat (buf, IDENTIFIER_POINTER (TYPE_NAME (aspec)));
7612 strcat (buf, "untagged enum");
7615 else if (TREE_CODE (aspec) == TYPE_DECL && DECL_NAME (aspec))
7616 strcat (buf, IDENTIFIER_POINTER (DECL_NAME (aspec)));
7618 else if (IS_ID (aspec))
7620 tree protocol_list = TYPE_PROTOCOL_LIST (aspec);
7625 tree chain = protocol_list;
7632 (PROTOCOL_NAME (TREE_VALUE (chain))));
7633 chain = TREE_CHAIN (chain);
7640 if (TREE_CHAIN (chain))
7646 /* Type qualifiers. */
7647 if (TREE_READONLY (declspecs))
7648 strcat (buf, "const ");
7649 if (TYPE_VOLATILE (declspecs))
7650 strcat (buf, "volatile ");
7652 switch (TREE_CODE (declspecs))
7654 /* Type specifiers. */
7657 declspecs = TYPE_MAIN_VARIANT (declspecs);
7659 /* Signed integer types. */
7661 if (declspecs == short_integer_type_node)
7662 strcat (buf, "short int ");
7663 else if (declspecs == integer_type_node)
7664 strcat (buf, "int ");
7665 else if (declspecs == long_integer_type_node)
7666 strcat (buf, "long int ");
7667 else if (declspecs == long_long_integer_type_node)
7668 strcat (buf, "long long int ");
7669 else if (declspecs == signed_char_type_node
7670 || declspecs == char_type_node)
7671 strcat (buf, "char ");
7673 /* Unsigned integer types. */
7675 else if (declspecs == short_unsigned_type_node)
7676 strcat (buf, "unsigned short ");
7677 else if (declspecs == unsigned_type_node)
7678 strcat (buf, "unsigned int ");
7679 else if (declspecs == long_unsigned_type_node)
7680 strcat (buf, "unsigned long ");
7681 else if (declspecs == long_long_unsigned_type_node)
7682 strcat (buf, "unsigned long long ");
7683 else if (declspecs == unsigned_char_type_node)
7684 strcat (buf, "unsigned char ");
7688 declspecs = TYPE_MAIN_VARIANT (declspecs);
7690 if (declspecs == float_type_node)
7691 strcat (buf, "float ");
7692 else if (declspecs == double_type_node)
7693 strcat (buf, "double ");
7694 else if (declspecs == long_double_type_node)
7695 strcat (buf, "long double ");
7699 if (TYPE_NAME (declspecs)
7700 && TREE_CODE (TYPE_NAME (declspecs)) == IDENTIFIER_NODE)
7702 tree protocol_list = TYPE_PROTOCOL_LIST (declspecs);
7704 if (! TREE_STATIC_TEMPLATE (declspecs))
7705 strcat (buf, "struct ");
7706 strcat (buf, IDENTIFIER_POINTER (TYPE_NAME (declspecs)));
7710 tree chain = protocol_list;
7717 (PROTOCOL_NAME (TREE_VALUE (chain))));
7718 chain = TREE_CHAIN (chain);
7727 strcat (buf, "untagged struct");
7733 if (TYPE_NAME (declspecs)
7734 && TREE_CODE (TYPE_NAME (declspecs)) == IDENTIFIER_NODE)
7736 strcat (buf, "union ");
7737 strcat (buf, IDENTIFIER_POINTER (TYPE_NAME (declspecs)));
7742 strcat (buf, "untagged union ");
7746 if (TYPE_NAME (declspecs)
7747 && TREE_CODE (TYPE_NAME (declspecs)) == IDENTIFIER_NODE)
7749 strcat (buf, "enum ");
7750 strcat (buf, IDENTIFIER_POINTER (TYPE_NAME (declspecs)));
7755 strcat (buf, "untagged enum ");
7759 strcat (buf, "void ");
7764 tree protocol_list = TYPE_PROTOCOL_LIST (declspecs);
7769 tree chain = protocol_list;
7776 (PROTOCOL_NAME (TREE_VALUE (chain))));
7777 chain = TREE_CHAIN (chain);
7793 /* Given a tree node, produce a printable description of it in the given
7794 buffer, overwriting the buffer. */
7797 gen_declaration (atype_or_adecl, buf)
7798 tree atype_or_adecl;
7802 gen_declaration_1 (atype_or_adecl, buf);
7806 /* Given a tree node, append a printable description to the end of the
7810 gen_declaration_1 (atype_or_adecl, buf)
7811 tree atype_or_adecl;
7816 if (TREE_CODE (atype_or_adecl) == TREE_LIST)
7818 tree declspecs; /* "identifier_node", "record_type" */
7819 tree declarator; /* "array_ref", "indirect_ref", "call_expr"... */
7821 /* We have a "raw", abstract declarator (typename). */
7822 declarator = TREE_VALUE (atype_or_adecl);
7823 declspecs = TREE_PURPOSE (atype_or_adecl);
7825 gen_declspecs (declspecs, buf, 1);
7829 strcat (buf, gen_declarator (declarator, declbuf, ""));
7836 tree declspecs; /* "integer_type", "real_type", "record_type"... */
7837 tree declarator; /* "array_type", "function_type", "pointer_type". */
7839 if (TREE_CODE (atype_or_adecl) == FIELD_DECL
7840 || TREE_CODE (atype_or_adecl) == PARM_DECL
7841 || TREE_CODE (atype_or_adecl) == FUNCTION_DECL)
7842 atype = TREE_TYPE (atype_or_adecl);
7844 /* Assume we have a *_type node. */
7845 atype = atype_or_adecl;
7847 if (is_complex_decl (atype))
7851 /* Get the declaration specifier; it is at the end of the list. */
7852 declarator = chain = atype;
7854 chain = TREE_TYPE (chain); /* not TREE_CHAIN (chain); */
7855 while (is_complex_decl (chain));
7862 declarator = NULL_TREE;
7865 gen_declspecs (declspecs, buf, 0);
7867 if (TREE_CODE (atype_or_adecl) == FIELD_DECL
7868 || TREE_CODE (atype_or_adecl) == PARM_DECL
7869 || TREE_CODE (atype_or_adecl) == FUNCTION_DECL)
7871 const char *const decl_name =
7872 (DECL_NAME (atype_or_adecl)
7873 ? IDENTIFIER_POINTER (DECL_NAME (atype_or_adecl)) : "");
7878 strcat (buf, gen_declarator (declarator, declbuf, decl_name));
7881 else if (decl_name[0])
7884 strcat (buf, decl_name);
7887 else if (declarator)
7890 strcat (buf, gen_declarator (declarator, declbuf, ""));
7895 #define RAW_TYPESPEC(meth) (TREE_VALUE (TREE_PURPOSE (TREE_TYPE (meth))))
7897 /* Given a method tree, put a printable description into the given
7898 buffer (overwriting) and return a pointer to the buffer. */
7901 gen_method_decl (method, buf)
7908 if (RAW_TYPESPEC (method) != objc_object_reference)
7911 gen_declaration_1 (TREE_TYPE (method), buf);
7915 chain = METHOD_SEL_ARGS (method);
7918 /* We have a chain of keyword_decls. */
7921 if (KEYWORD_KEY_NAME (chain))
7922 strcat (buf, IDENTIFIER_POINTER (KEYWORD_KEY_NAME (chain)));
7925 if (RAW_TYPESPEC (chain) != objc_object_reference)
7928 gen_declaration_1 (TREE_TYPE (chain), buf);
7932 strcat (buf, IDENTIFIER_POINTER (KEYWORD_ARG_NAME (chain)));
7933 if ((chain = TREE_CHAIN (chain)))
7938 if (METHOD_ADD_ARGS (method) == objc_ellipsis_node)
7939 strcat (buf, ", ...");
7940 else if (METHOD_ADD_ARGS (method))
7942 /* We have a tree list node as generate by get_parm_info. */
7943 chain = TREE_PURPOSE (METHOD_ADD_ARGS (method));
7945 /* Know we have a chain of parm_decls. */
7949 gen_declaration_1 (chain, buf);
7950 chain = TREE_CHAIN (chain);
7956 /* We have a unary selector. */
7957 strcat (buf, IDENTIFIER_POINTER (METHOD_SEL_NAME (method)));
7965 dump_interface (fp, chain)
7969 char *buf = (char *) xmalloc (256);
7970 const char *my_name = IDENTIFIER_POINTER (CLASS_NAME (chain));
7971 tree ivar_decls = CLASS_RAW_IVARS (chain);
7972 tree nst_methods = CLASS_NST_METHODS (chain);
7973 tree cls_methods = CLASS_CLS_METHODS (chain);
7975 fprintf (fp, "\n@interface %s", my_name);
7977 if (CLASS_SUPER_NAME (chain))
7979 const char *super_name = IDENTIFIER_POINTER (CLASS_SUPER_NAME (chain));
7980 fprintf (fp, " : %s\n", super_name);
7987 fprintf (fp, "{\n");
7990 fprintf (fp, "\t%s;\n", gen_declaration (ivar_decls, buf));
7991 ivar_decls = TREE_CHAIN (ivar_decls);
7994 fprintf (fp, "}\n");
7999 fprintf (fp, "- %s;\n", gen_method_decl (nst_methods, buf));
8000 nst_methods = TREE_CHAIN (nst_methods);
8005 fprintf (fp, "+ %s;\n", gen_method_decl (cls_methods, buf));
8006 cls_methods = TREE_CHAIN (cls_methods);
8008 fprintf (fp, "\n@end");
8011 /* Demangle function for Objective-C */
8013 objc_demangle (mangled)
8014 const char *mangled;
8016 char *demangled, *cp;
8018 if (mangled[0] == '_' &&
8019 (mangled[1] == 'i' || mangled[1] == 'c') &&
8022 cp = demangled = xmalloc(strlen(mangled) + 2);
8023 if (mangled[1] == 'i')
8024 *cp++ = '-'; /* for instance method */
8026 *cp++ = '+'; /* for class method */
8027 *cp++ = '['; /* opening left brace */
8028 strcpy(cp, mangled+3); /* tack on the rest of the mangled name */
8029 while (*cp && *cp == '_')
8030 cp++; /* skip any initial underbars in class name */
8031 cp = strchr(cp, '_'); /* find first non-initial underbar */
8034 free(demangled); /* not mangled name */
8037 if (cp[1] == '_') /* easy case: no category name */
8039 *cp++ = ' '; /* replace two '_' with one ' ' */
8040 strcpy(cp, mangled + (cp - demangled) + 2);
8044 *cp++ = '('; /* less easy case: category name */
8045 cp = strchr(cp, '_');
8048 free(demangled); /* not mangled name */
8052 *cp++ = ' '; /* overwriting 1st char of method name... */
8053 strcpy(cp, mangled + (cp - demangled)); /* get it back */
8055 while (*cp && *cp == '_')
8056 cp++; /* skip any initial underbars in method name */
8059 *cp = ':'; /* replace remaining '_' with ':' */
8060 *cp++ = ']'; /* closing right brace */
8061 *cp++ = 0; /* string terminator */
8065 return mangled; /* not an objc mangled name */
8069 objc_printable_name (decl, kind)
8071 int kind ATTRIBUTE_UNUSED;
8073 return objc_demangle (IDENTIFIER_POINTER (DECL_NAME (decl)));
8076 /* Adds the tree codes specific to the ObjC/ObjC++ front end to the
8077 list of all tree codes. */
8080 add_objc_tree_codes ()
8082 int add = (int) LAST_OBJC_TREE_CODE - (int) LAST_BASE_TREE_CODE;
8084 memcpy (tree_code_type + (int) LAST_BASE_TREE_CODE,
8085 objc_tree_code_type, add);
8086 memcpy (tree_code_length + (int) LAST_BASE_TREE_CODE,
8087 objc_tree_code_length, add * sizeof (int));
8088 memcpy (tree_code_name + (int) LAST_BASE_TREE_CODE,
8089 objc_tree_code_name, add * sizeof (char *));
8095 gcc_obstack_init (&util_obstack);
8096 util_firstobj = (char *) obstack_finish (&util_obstack);
8098 errbuf = (char *) xmalloc (BUFSIZE);
8100 synth_module_prologue ();
8106 struct imp_entry *impent;
8108 /* The internally generated initializers appear to have missing braces.
8109 Don't warn about this. */
8110 int save_warn_missing_braces = warn_missing_braces;
8111 warn_missing_braces = 0;
8113 /* A missing @end may not be detected by the parser. */
8114 if (objc_implementation_context)
8116 warning ("`@end' missing in implementation context");
8117 finish_class (objc_implementation_context);
8118 objc_ivar_chain = NULL_TREE;
8119 objc_implementation_context = NULL_TREE;
8122 generate_forward_declaration_to_string_table ();
8124 #ifdef OBJC_PROLOGUE
8128 /* Process the static instances here because initialization of objc_symtab
8130 if (objc_static_instances)
8131 generate_static_references ();
8133 if (imp_list || class_names_chain
8134 || meth_var_names_chain || meth_var_types_chain || sel_ref_chain)
8135 generate_objc_symtab_decl ();
8137 for (impent = imp_list; impent; impent = impent->next)
8139 objc_implementation_context = impent->imp_context;
8140 implementation_template = impent->imp_template;
8142 UOBJC_CLASS_decl = impent->class_decl;
8143 UOBJC_METACLASS_decl = impent->meta_decl;
8145 if (TREE_CODE (objc_implementation_context) == CLASS_IMPLEMENTATION_TYPE)
8147 /* all of the following reference the string pool... */
8148 generate_ivar_lists ();
8149 generate_dispatch_tables ();
8150 generate_shared_structures ();
8154 generate_dispatch_tables ();
8155 generate_category (objc_implementation_context);
8159 /* If we are using an array of selectors, we must always
8160 finish up the array decl even if no selectors were used. */
8161 if (! flag_next_runtime || sel_ref_chain)
8162 build_selector_translation_table ();
8165 generate_protocols ();
8167 if (objc_implementation_context || class_names_chain || objc_static_instances
8168 || meth_var_names_chain || meth_var_types_chain || sel_ref_chain)
8170 /* Arrange for ObjC data structures to be initialized at run time. */
8171 rtx init_sym = build_module_descriptor ();
8172 if (init_sym && targetm.have_ctors_dtors)
8173 (* targetm.asm_out.constructor) (init_sym, DEFAULT_INIT_PRIORITY);
8176 /* Dump the class references. This forces the appropriate classes
8177 to be linked into the executable image, preserving unix archive
8178 semantics. This can be removed when we move to a more dynamically
8179 linked environment. */
8181 for (chain = cls_ref_chain; chain; chain = TREE_CHAIN (chain))
8183 handle_class_ref (chain);
8184 if (TREE_PURPOSE (chain))
8185 generate_classref_translation_entry (chain);
8188 for (impent = imp_list; impent; impent = impent->next)
8189 handle_impent (impent);
8191 /* Dump the string table last. */
8193 generate_strings ();
8195 if (flag_gen_declaration)
8197 add_class (objc_implementation_context);
8198 dump_interface (gen_declaration_file, objc_implementation_context);
8206 /* Run through the selector hash tables and print a warning for any
8207 selector which has multiple methods. */
8209 for (slot = 0; slot < SIZEHASHTABLE; slot++)
8210 for (hsh = cls_method_hash_list[slot]; hsh; hsh = hsh->next)
8213 tree meth = hsh->key;
8214 char type = (TREE_CODE (meth) == INSTANCE_METHOD_DECL
8218 warning ("potential selector conflict for method `%s'",
8219 IDENTIFIER_POINTER (METHOD_SEL_NAME (meth)));
8220 warn_with_method ("found", type, meth);
8221 for (loop = hsh->list; loop; loop = loop->next)
8222 warn_with_method ("found", type, loop->value);
8225 for (slot = 0; slot < SIZEHASHTABLE; slot++)
8226 for (hsh = nst_method_hash_list[slot]; hsh; hsh = hsh->next)
8229 tree meth = hsh->key;
8230 char type = (TREE_CODE (meth) == INSTANCE_METHOD_DECL
8234 warning ("potential selector conflict for method `%s'",
8235 IDENTIFIER_POINTER (METHOD_SEL_NAME (meth)));
8236 warn_with_method ("found", type, meth);
8237 for (loop = hsh->list; loop; loop = loop->next)
8238 warn_with_method ("found", type, loop->value);
8242 warn_missing_braces = save_warn_missing_braces;
8245 /* Subroutines of finish_objc. */
8248 generate_classref_translation_entry (chain)
8251 tree expr, name, decl_specs, decl, sc_spec;
8254 type = TREE_TYPE (TREE_PURPOSE (chain));
8256 expr = add_objc_string (TREE_VALUE (chain), class_names);
8257 expr = build_c_cast (type, expr); /* cast! */
8259 name = DECL_NAME (TREE_PURPOSE (chain));
8261 sc_spec = build_tree_list (NULL_TREE, ridpointers[(int) RID_STATIC]);
8263 /* static struct objc_class * _OBJC_CLASS_REFERENCES_n = ...; */
8264 decl_specs = tree_cons (NULL_TREE, type, sc_spec);
8266 /* The decl that is returned from start_decl is the one that we
8267 forward declared in build_class_reference. */
8268 decl = start_decl (name, decl_specs, 1, NULL_TREE);
8269 DECL_CONTEXT (decl) = NULL_TREE;
8270 finish_decl (decl, expr, NULL_TREE);
8275 handle_class_ref (chain)
8278 const char *name = IDENTIFIER_POINTER (TREE_VALUE (chain));
8279 char *string = (char *) alloca (strlen (name) + 30);
8283 sprintf (string, "%sobjc_class_name_%s",
8284 (flag_next_runtime ? "." : "__"), name);
8286 #ifdef ASM_DECLARE_UNRESOLVED_REFERENCE
8287 if (flag_next_runtime)
8289 ASM_DECLARE_UNRESOLVED_REFERENCE (asm_out_file, string);
8294 /* Make a decl for this name, so we can use its address in a tree. */
8295 decl = build_decl (VAR_DECL, get_identifier (string), char_type_node);
8296 DECL_EXTERNAL (decl) = 1;
8297 TREE_PUBLIC (decl) = 1;
8300 rest_of_decl_compilation (decl, 0, 0, 0);
8302 /* Make a decl for the address. */
8303 sprintf (string, "%sobjc_class_ref_%s",
8304 (flag_next_runtime ? "." : "__"), name);
8305 exp = build1 (ADDR_EXPR, string_type_node, decl);
8306 decl = build_decl (VAR_DECL, get_identifier (string), string_type_node);
8307 DECL_INITIAL (decl) = exp;
8308 TREE_STATIC (decl) = 1;
8311 rest_of_decl_compilation (decl, 0, 0, 0);
8315 handle_impent (impent)
8316 struct imp_entry *impent;
8320 objc_implementation_context = impent->imp_context;
8321 implementation_template = impent->imp_template;
8323 if (TREE_CODE (impent->imp_context) == CLASS_IMPLEMENTATION_TYPE)
8325 const char *const class_name =
8326 IDENTIFIER_POINTER (CLASS_NAME (impent->imp_context));
8328 string = (char *) alloca (strlen (class_name) + 30);
8330 sprintf (string, "*%sobjc_class_name_%s",
8331 (flag_next_runtime ? "." : "__"), class_name);
8333 else if (TREE_CODE (impent->imp_context) == CATEGORY_IMPLEMENTATION_TYPE)
8335 const char *const class_name =
8336 IDENTIFIER_POINTER (CLASS_NAME (impent->imp_context));
8337 const char *const class_super_name =
8338 IDENTIFIER_POINTER (CLASS_SUPER_NAME (impent->imp_context));
8340 string = (char *) alloca (strlen (class_name)
8341 + strlen (class_super_name) + 30);
8343 /* Do the same for categories. Even though no references to
8344 these symbols are generated automatically by the compiler, it
8345 gives you a handle to pull them into an archive by hand. */
8346 sprintf (string, "*%sobjc_category_name_%s_%s",
8347 (flag_next_runtime ? "." : "__"), class_name, class_super_name);
8352 #ifdef ASM_DECLARE_CLASS_REFERENCE
8353 if (flag_next_runtime)
8355 ASM_DECLARE_CLASS_REFERENCE (asm_out_file, string);
8360 /* (Should this be a routine in varasm.c?) */
8361 readonly_data_section ();
8362 assemble_global (string);
8363 assemble_align (UNITS_PER_WORD);
8364 assemble_label (string);
8365 assemble_zeros (UNITS_PER_WORD);
8369 ggc_mark_imp_list (arg)
8372 struct imp_entry *impent;
8374 for (impent = *(struct imp_entry **)arg; impent; impent = impent->next)
8376 ggc_mark_tree (impent->imp_context);
8377 ggc_mark_tree (impent->imp_template);
8378 ggc_mark_tree (impent->class_decl);
8379 ggc_mark_tree (impent->meta_decl);
8384 ggc_mark_hash_table (arg)
8387 hash *hash_table = *(hash **)arg;
8392 if (hash_table == NULL)
8394 for (i = 0; i < SIZEHASHTABLE; i++)
8395 for (hst = hash_table [i]; hst; hst = hst->next)
8397 ggc_mark_tree (hst->key);
8398 for (list = hst->list; list; list = list->next)
8399 ggc_mark_tree (list->value);
8403 /* Add GC roots for variables local to this file. */
8405 objc_act_parse_init ()
8407 ggc_add_tree_root (objc_global_trees, OCTI_MAX);
8408 ggc_add_root (&imp_list, 1, sizeof imp_list, ggc_mark_imp_list);
8409 ggc_add_root (&nst_method_hash_list, 1, sizeof nst_method_hash_list, ggc_mark_hash_table);
8410 ggc_add_root (&cls_method_hash_list, 1, sizeof cls_method_hash_list, ggc_mark_hash_table);
8413 /* Look up ID as an instance variable. */
8415 lookup_objc_ivar (id)
8420 if (objc_receiver_context && !strcmp (IDENTIFIER_POINTER (id), "super"))
8421 /* we have a message to super */
8422 return get_super_receiver ();
8423 else if (objc_method_context && (decl = is_ivar (objc_ivar_chain, id)))
8425 if (is_private (decl))
8426 return error_mark_node;
8428 return build_ivar_reference (id);