1 /* Implement classes and message passing for Objective C.
2 Copyright (C) 1992, 1993, 1994, 1995, 1997, 1998, 1999, 2000, 2001, 2002
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':
60 /* This is the default way of generating a method name. */
61 /* I am not sure it is really correct.
62 Perhaps there's a danger that it will make name conflicts
63 if method names contain underscores. -- rms. */
64 #ifndef OBJC_GEN_METHOD_LABEL
65 #define OBJC_GEN_METHOD_LABEL(BUF, IS_INST, CLASS_NAME, CAT_NAME, SEL_NAME, NUM) \
68 sprintf ((BUF), "_%s_%s_%s_%s", \
69 ((IS_INST) ? "i" : "c"), \
71 ((CAT_NAME)? (CAT_NAME) : ""), \
73 for (temp = (BUF); *temp; temp++) \
74 if (*temp == ':') *temp = '_'; \
78 /* These need specifying. */
79 #ifndef OBJC_FORWARDING_STACK_OFFSET
80 #define OBJC_FORWARDING_STACK_OFFSET 0
83 #ifndef OBJC_FORWARDING_MIN_OFFSET
84 #define OBJC_FORWARDING_MIN_OFFSET 0
88 /* Set up for use of obstacks. */
92 #define obstack_chunk_alloc xmalloc
93 #define obstack_chunk_free free
95 /* This obstack is used to accumulate the encoding of a data type. */
96 static struct obstack util_obstack;
97 /* This points to the beginning of obstack contents,
98 so we can free the whole contents. */
101 /* for encode_method_def */
104 /* The version identifies which language generation and runtime
105 the module (file) was compiled for, and is recorded in the
106 module descriptor. */
108 #define OBJC_VERSION (flag_next_runtime ? 5 : 8)
109 #define PROTOCOL_VERSION 2
111 /* (Decide if these can ever be validly changed.) */
112 #define OBJC_ENCODE_INLINE_DEFS 0
113 #define OBJC_ENCODE_DONT_INLINE_DEFS 1
115 /*** Private Interface (procedures) ***/
117 /* Used by compile_file. */
119 static void init_objc PARAMS ((void));
120 static void finish_objc PARAMS ((void));
122 /* Code generation. */
124 static void synth_module_prologue PARAMS ((void));
125 static tree build_constructor PARAMS ((tree, tree));
126 static rtx build_module_descriptor PARAMS ((void));
127 static tree init_module_descriptor PARAMS ((tree));
128 static tree build_objc_method_call PARAMS ((int, tree, tree,
130 static void generate_strings PARAMS ((void));
131 static tree get_proto_encoding PARAMS ((tree));
132 static void build_selector_translation_table PARAMS ((void));
133 static tree build_ivar_chain PARAMS ((tree, int));
135 static tree objc_add_static_instance PARAMS ((tree, tree));
137 static tree build_ivar_template PARAMS ((void));
138 static tree build_method_template PARAMS ((void));
139 static tree build_private_template PARAMS ((tree));
140 static void build_class_template PARAMS ((void));
141 static void build_selector_template PARAMS ((void));
142 static void build_category_template PARAMS ((void));
143 static tree build_super_template PARAMS ((void));
144 static tree build_category_initializer PARAMS ((tree, tree, tree,
146 static tree build_protocol_initializer PARAMS ((tree, tree, tree,
149 static void synth_forward_declarations PARAMS ((void));
150 static void generate_ivar_lists PARAMS ((void));
151 static void generate_dispatch_tables PARAMS ((void));
152 static void generate_shared_structures PARAMS ((void));
153 static tree generate_protocol_list PARAMS ((tree));
154 static void generate_forward_declaration_to_string_table PARAMS ((void));
155 static void build_protocol_reference PARAMS ((tree));
157 static tree build_keyword_selector PARAMS ((tree));
158 static tree synth_id_with_class_suffix PARAMS ((const char *, tree));
160 static void generate_static_references PARAMS ((void));
161 static int check_methods_accessible PARAMS ((tree, tree,
163 static void encode_aggregate_within PARAMS ((tree, int, int,
165 static const char *objc_demangle PARAMS ((const char *));
166 static void objc_expand_function_end PARAMS ((void));
168 /* Hash tables to manage the global pool of method prototypes. */
170 hash *nst_method_hash_list = 0;
171 hash *cls_method_hash_list = 0;
173 static size_t hash_func PARAMS ((tree));
174 static void hash_init PARAMS ((void));
175 static void hash_enter PARAMS ((hash *, tree));
176 static hash hash_lookup PARAMS ((hash *, tree));
177 static void hash_add_attr PARAMS ((hash, tree));
178 static tree lookup_method PARAMS ((tree, tree));
179 static tree lookup_instance_method_static PARAMS ((tree, tree));
180 static tree lookup_class_method_static PARAMS ((tree, tree));
181 static tree add_class PARAMS ((tree));
182 static void add_category PARAMS ((tree, tree));
186 class_names, /* class, category, protocol, module names */
187 meth_var_names, /* method and variable names */
188 meth_var_types /* method and variable type descriptors */
191 static tree add_objc_string PARAMS ((tree,
192 enum string_section));
193 static tree get_objc_string_decl PARAMS ((tree,
194 enum string_section));
195 static tree build_objc_string_decl PARAMS ((enum string_section));
196 static tree build_selector_reference_decl PARAMS ((void));
198 /* Protocol additions. */
200 static tree add_protocol PARAMS ((tree));
201 static tree lookup_protocol PARAMS ((tree));
202 static void check_protocol_recursively PARAMS ((tree, tree));
203 static tree lookup_and_install_protocols PARAMS ((tree));
207 static void encode_type_qualifiers PARAMS ((tree));
208 static void encode_pointer PARAMS ((tree, int, int));
209 static void encode_array PARAMS ((tree, int, int));
210 static void encode_aggregate PARAMS ((tree, int, int));
211 static void encode_bitfield PARAMS ((int));
212 static void encode_type PARAMS ((tree, int, int));
213 static void encode_field_decl PARAMS ((tree, int, int));
215 static void really_start_method PARAMS ((tree, tree));
216 static int comp_method_with_proto PARAMS ((tree, tree));
217 static int comp_proto_with_proto PARAMS ((tree, tree));
218 static tree get_arg_type_list PARAMS ((tree, int, int));
219 static tree expr_last PARAMS ((tree));
221 /* Utilities for debugging and error diagnostics. */
223 static void warn_with_method PARAMS ((const char *, int, tree));
224 static void error_with_ivar PARAMS ((const char *, tree, tree));
225 static char *gen_method_decl PARAMS ((tree, char *));
226 static char *gen_declaration PARAMS ((tree, char *));
227 static void gen_declaration_1 PARAMS ((tree, char *));
228 static char *gen_declarator PARAMS ((tree, char *,
230 static int is_complex_decl PARAMS ((tree));
231 static void adorn_decl PARAMS ((tree, char *));
232 static void dump_interface PARAMS ((FILE *, tree));
234 /* Everything else. */
236 static tree define_decl PARAMS ((tree, tree));
237 static tree lookup_method_in_protocol_list PARAMS ((tree, tree, int));
238 static tree lookup_protocol_in_reflist PARAMS ((tree, tree));
239 static tree create_builtin_decl PARAMS ((enum tree_code,
240 tree, const char *));
241 static void setup_string_decl PARAMS ((void));
242 static void build_string_class_template PARAMS ((void));
243 static tree my_build_string PARAMS ((int, const char *));
244 static void build_objc_symtab_template PARAMS ((void));
245 static tree init_def_list PARAMS ((tree));
246 static tree init_objc_symtab PARAMS ((tree));
247 static void forward_declare_categories PARAMS ((void));
248 static void generate_objc_symtab_decl PARAMS ((void));
249 static tree build_selector PARAMS ((tree));
250 static tree build_typed_selector_reference PARAMS ((tree, tree));
251 static tree build_selector_reference PARAMS ((tree));
252 static tree build_class_reference_decl PARAMS ((void));
253 static void add_class_reference PARAMS ((tree));
254 static tree objc_copy_list PARAMS ((tree, tree *));
255 static tree build_protocol_template PARAMS ((void));
256 static tree build_descriptor_table_initializer PARAMS ((tree, tree));
257 static tree build_method_prototype_list_template PARAMS ((tree, int));
258 static tree build_method_prototype_template PARAMS ((void));
259 static int forwarding_offset PARAMS ((tree));
260 static tree encode_method_prototype PARAMS ((tree, tree));
261 static tree generate_descriptor_table PARAMS ((tree, const char *,
263 static void generate_method_descriptors PARAMS ((tree));
264 static tree build_tmp_function_decl PARAMS ((void));
265 static void hack_method_prototype PARAMS ((tree, tree));
266 static void generate_protocol_references PARAMS ((tree));
267 static void generate_protocols PARAMS ((void));
268 static void check_ivars PARAMS ((tree, tree));
269 static tree build_ivar_list_template PARAMS ((tree, int));
270 static tree build_method_list_template PARAMS ((tree, int));
271 static tree build_ivar_list_initializer PARAMS ((tree, tree));
272 static tree generate_ivars_list PARAMS ((tree, const char *,
274 static tree build_dispatch_table_initializer PARAMS ((tree, tree));
275 static tree generate_dispatch_table PARAMS ((tree, const char *,
277 static tree build_shared_structure_initializer PARAMS ((tree, tree, tree, tree,
278 tree, int, tree, tree,
280 static void generate_category PARAMS ((tree));
281 static int is_objc_type_qualifier PARAMS ((tree));
282 static tree adjust_type_for_id_default PARAMS ((tree));
283 static tree check_duplicates PARAMS ((hash));
284 static tree receiver_is_class_object PARAMS ((tree));
285 static int check_methods PARAMS ((tree, tree, int));
286 static int conforms_to_protocol PARAMS ((tree, tree));
287 static void check_protocol PARAMS ((tree, const char *,
289 static void check_protocols PARAMS ((tree, const char *,
291 static tree encode_method_def PARAMS ((tree));
292 static void gen_declspecs PARAMS ((tree, char *, int));
293 static void generate_classref_translation_entry PARAMS ((tree));
294 static void handle_class_ref PARAMS ((tree));
295 static void generate_struct_by_value_array PARAMS ((void))
298 /*** Private Interface (data) ***/
300 /* Reserved tag definitions. */
303 #define TAG_OBJECT "objc_object"
304 #define TAG_CLASS "objc_class"
305 #define TAG_SUPER "objc_super"
306 #define TAG_SELECTOR "objc_selector"
308 #define UTAG_CLASS "_objc_class"
309 #define UTAG_IVAR "_objc_ivar"
310 #define UTAG_IVAR_LIST "_objc_ivar_list"
311 #define UTAG_METHOD "_objc_method"
312 #define UTAG_METHOD_LIST "_objc_method_list"
313 #define UTAG_CATEGORY "_objc_category"
314 #define UTAG_MODULE "_objc_module"
315 #define UTAG_STATICS "_objc_statics"
316 #define UTAG_SYMTAB "_objc_symtab"
317 #define UTAG_SUPER "_objc_super"
318 #define UTAG_SELECTOR "_objc_selector"
320 #define UTAG_PROTOCOL "_objc_protocol"
321 #define UTAG_PROTOCOL_LIST "_objc_protocol_list"
322 #define UTAG_METHOD_PROTOTYPE "_objc_method_prototype"
323 #define UTAG_METHOD_PROTOTYPE_LIST "_objc__method_prototype_list"
325 /* Note that the string object global name is only needed for the
327 #define STRING_OBJECT_GLOBAL_NAME "_NSConstantStringClassReference"
329 #define PROTOCOL_OBJECT_CLASS_NAME "Protocol"
331 static const char *constant_string_class_name = NULL;
333 static const char *TAG_GETCLASS;
334 static const char *TAG_GETMETACLASS;
335 static const char *TAG_MSGSEND;
336 static const char *TAG_MSGSENDSUPER;
337 static const char *TAG_EXECCLASS;
338 static const char *default_constant_string_class_name;
340 /* The OCTI_... enumeration itself is in objc/objc-act.h. */
341 tree objc_global_trees[OCTI_MAX];
343 int objc_receiver_context;
345 static void handle_impent PARAMS ((struct imp_entry *));
347 struct imp_entry *imp_list = 0;
348 int imp_count = 0; /* `@implementation' */
349 int cat_count = 0; /* `@category' */
351 static int method_slot = 0; /* Used by start_method_def, */
355 static char *errbuf; /* Buffer for error diagnostics */
357 /* Data imported from tree.c. */
359 extern enum debug_info_type write_symbols;
361 /* Data imported from toplev.c. */
363 extern const char *dump_base_name;
365 /* Generate code for GNU or NeXT runtime environment. */
367 #ifdef NEXT_OBJC_RUNTIME
368 int flag_next_runtime = 1;
370 int flag_next_runtime = 0;
373 int flag_typed_selectors;
375 /* Open and close the file for outputting class declarations, if requested. */
377 int flag_gen_declaration = 0;
379 FILE *gen_declaration_file;
381 /* Warn if multiple methods are seen for the same selector, but with
382 different argument types. */
384 int warn_selector = 0;
386 /* Warn if methods required by a protocol are not implemented in the
387 class adopting it. When turned off, methods inherited to that
388 class are also considered implemented */
390 int flag_warn_protocol = 1;
392 /* Tells "encode_pointer/encode_aggregate" whether we are generating
393 type descriptors for instance variables (as opposed to methods).
394 Type descriptors for instance variables contain more information
395 than methods (for static typing and embedded structures). */
397 static int generating_instance_variables = 0;
399 /* Tells the compiler that this is a special run. Do not perform any
400 compiling, instead we are to test some platform dependent features
401 and output a C header file with appropriate definitions. */
403 static int print_struct_values = 0;
405 /* Some platforms pass small structures through registers versus
406 through an invisible pointer. Determine at what size structure is
407 the transition point between the two possibilities. */
410 generate_struct_by_value_array ()
413 tree field_decl, field_decl_chain;
415 int aggregate_in_mem[32];
418 /* Presumably no platform passes 32 byte structures in a register. */
419 for (i = 1; i < 32; i++)
423 /* Create an unnamed struct that has `i' character components */
424 type = start_struct (RECORD_TYPE, NULL_TREE);
426 strcpy (buffer, "c1");
427 field_decl = create_builtin_decl (FIELD_DECL,
430 field_decl_chain = field_decl;
432 for (j = 1; j < i; j++)
434 sprintf (buffer, "c%d", j + 1);
435 field_decl = create_builtin_decl (FIELD_DECL,
438 chainon (field_decl_chain, field_decl);
440 finish_struct (type, field_decl_chain, NULL_TREE);
442 aggregate_in_mem[i] = aggregate_value_p (type);
443 if (!aggregate_in_mem[i])
447 /* We found some structures that are returned in registers instead of memory
448 so output the necessary data. */
451 for (i = 31; i >= 0; i--)
452 if (!aggregate_in_mem[i])
454 printf ("#define OBJC_MAX_STRUCT_BY_VALUE %d\n\n", i);
456 /* The first member of the structure is always 0 because we don't handle
457 structures with 0 members */
458 printf ("static int struct_forward_array[] = {\n 0");
460 for (j = 1; j <= i; j++)
461 printf (", %d", aggregate_in_mem[j]);
470 const char *filename;
472 filename = c_objc_common_init (filename);
474 /* Force the line number back to 0; check_newline will have
475 raised it to 1, which will make the builtin functions appear
476 not to be built in. */
479 /* If gen_declaration desired, open the output file. */
480 if (flag_gen_declaration)
482 register char * const dumpname = concat (dump_base_name, ".decl", NULL);
483 gen_declaration_file = fopen (dumpname, "w");
484 if (gen_declaration_file == 0)
485 fatal_io_error ("can't open %s", dumpname);
489 if (flag_next_runtime)
491 TAG_GETCLASS = "objc_getClass";
492 TAG_GETMETACLASS = "objc_getMetaClass";
493 TAG_MSGSEND = "objc_msgSend";
494 TAG_MSGSENDSUPER = "objc_msgSendSuper";
495 TAG_EXECCLASS = "__objc_execClass";
496 default_constant_string_class_name = "NSConstantString";
500 TAG_GETCLASS = "objc_get_class";
501 TAG_GETMETACLASS = "objc_get_meta_class";
502 TAG_MSGSEND = "objc_msg_lookup";
503 TAG_MSGSENDSUPER = "objc_msg_lookup_super";
504 TAG_EXECCLASS = "__objc_exec_class";
505 default_constant_string_class_name = "NXConstantString";
506 flag_typed_selectors = 1;
509 objc_ellipsis_node = make_node (ERROR_MARK);
513 if (print_struct_values)
514 generate_struct_by_value_array ();
522 c_objc_common_finish_file ();
524 finish_objc (); /* Objective-C finalization */
526 if (gen_declaration_file)
527 fclose (gen_declaration_file);
531 objc_decode_option (argc, argv)
535 const char *p = argv[0];
537 if (!strcmp (p, "-gen-decls"))
538 flag_gen_declaration = 1;
539 else if (!strcmp (p, "-Wselector"))
541 else if (!strcmp (p, "-Wno-selector"))
543 else if (!strcmp (p, "-Wprotocol"))
544 flag_warn_protocol = 1;
545 else if (!strcmp (p, "-Wno-protocol"))
546 flag_warn_protocol = 0;
547 else if (!strcmp (p, "-fgnu-runtime"))
548 flag_next_runtime = 0;
549 else if (!strcmp (p, "-fno-next-runtime"))
550 flag_next_runtime = 0;
551 else if (!strcmp (p, "-fno-gnu-runtime"))
552 flag_next_runtime = 1;
553 else if (!strcmp (p, "-fnext-runtime"))
554 flag_next_runtime = 1;
555 else if (!strcmp (p, "-print-objc-runtime-info"))
556 print_struct_values = 1;
557 #define CSTSTRCLASS "-fconstant-string-class="
558 else if (!strncmp (p, CSTSTRCLASS, sizeof(CSTSTRCLASS) - 2)) {
559 if (strlen (argv[0]) <= strlen (CSTSTRCLASS))
560 error ("no class name specified as argument to -fconstant-string-class");
561 constant_string_class_name = xstrdup(argv[0] + sizeof(CSTSTRCLASS) - 1);
565 return c_decode_option (argc, argv);
572 define_decl (declarator, declspecs)
576 tree decl = start_decl (declarator, declspecs, 0, NULL_TREE);
577 finish_decl (decl, NULL_TREE, NULL_TREE);
581 /* Return 1 if LHS and RHS are compatible types for assignment or
582 various other operations. Return 0 if they are incompatible, and
583 return -1 if we choose to not decide. When the operation is
584 REFLEXIVE, check for compatibility in either direction.
586 For statically typed objects, an assignment of the form `a' = `b'
590 `a' and `b' are the same class type, or
591 `a' and `b' are of class types A and B such that B is a descendant of A. */
594 maybe_objc_comptypes (lhs, rhs, reflexive)
598 return objc_comptypes (lhs, rhs, reflexive);
602 lookup_method_in_protocol_list (rproto_list, sel_name, class_meth)
610 for (rproto = rproto_list; rproto; rproto = TREE_CHAIN (rproto))
612 p = TREE_VALUE (rproto);
614 if (TREE_CODE (p) == PROTOCOL_INTERFACE_TYPE)
616 if ((fnd = lookup_method (class_meth
617 ? PROTOCOL_CLS_METHODS (p)
618 : PROTOCOL_NST_METHODS (p), sel_name)))
620 else if (PROTOCOL_LIST (p))
621 fnd = lookup_method_in_protocol_list (PROTOCOL_LIST (p),
622 sel_name, class_meth);
626 ; /* An identifier...if we could not find a protocol. */
637 lookup_protocol_in_reflist (rproto_list, lproto)
643 /* Make sure the protocol is supported by the object on the rhs. */
644 if (TREE_CODE (lproto) == PROTOCOL_INTERFACE_TYPE)
647 for (rproto = rproto_list; rproto; rproto = TREE_CHAIN (rproto))
649 p = TREE_VALUE (rproto);
651 if (TREE_CODE (p) == PROTOCOL_INTERFACE_TYPE)
656 else if (PROTOCOL_LIST (p))
657 fnd = lookup_protocol_in_reflist (PROTOCOL_LIST (p), lproto);
666 ; /* An identifier...if we could not find a protocol. */
672 /* Return 1 if LHS and RHS are compatible types for assignment
673 or various other operations. Return 0 if they are incompatible,
674 and return -1 if we choose to not decide. When the operation
675 is REFLEXIVE, check for compatibility in either direction. */
678 objc_comptypes (lhs, rhs, reflexive)
683 /* New clause for protocols. */
685 if (TREE_CODE (lhs) == POINTER_TYPE
686 && TREE_CODE (TREE_TYPE (lhs)) == RECORD_TYPE
687 && TREE_CODE (rhs) == POINTER_TYPE
688 && TREE_CODE (TREE_TYPE (rhs)) == RECORD_TYPE)
690 int lhs_is_proto = IS_PROTOCOL_QUALIFIED_ID (lhs);
691 int rhs_is_proto = IS_PROTOCOL_QUALIFIED_ID (rhs);
695 tree lproto, lproto_list = TYPE_PROTOCOL_LIST (lhs);
696 tree rproto, rproto_list;
701 rproto_list = TYPE_PROTOCOL_LIST (rhs);
703 /* Make sure the protocol is supported by the object
705 for (lproto = lproto_list; lproto; lproto = TREE_CHAIN (lproto))
707 p = TREE_VALUE (lproto);
708 rproto = lookup_protocol_in_reflist (rproto_list, p);
711 warning ("object does not conform to the `%s' protocol",
712 IDENTIFIER_POINTER (PROTOCOL_NAME (p)));
715 else if (TYPED_OBJECT (TREE_TYPE (rhs)))
717 tree rname = TYPE_NAME (TREE_TYPE (rhs));
720 /* Make sure the protocol is supported by the object
722 for (lproto = lproto_list; lproto; lproto = TREE_CHAIN (lproto))
724 p = TREE_VALUE (lproto);
726 rinter = lookup_interface (rname);
728 while (rinter && !rproto)
732 rproto_list = CLASS_PROTOCOL_LIST (rinter);
733 /* If the underlying ObjC class does not have
734 protocols attached to it, perhaps there are
735 "one-off" protocols attached to the rhs?
736 E.g., 'id<MyProt> foo;'. */
738 rproto_list = TYPE_PROTOCOL_LIST (TREE_TYPE (rhs));
739 rproto = lookup_protocol_in_reflist (rproto_list, p);
741 /* Check for protocols adopted by categories. */
742 cat = CLASS_CATEGORY_LIST (rinter);
743 while (cat && !rproto)
745 rproto_list = CLASS_PROTOCOL_LIST (cat);
746 rproto = lookup_protocol_in_reflist (rproto_list, p);
748 cat = CLASS_CATEGORY_LIST (cat);
751 rinter = lookup_interface (CLASS_SUPER_NAME (rinter));
755 warning ("class `%s' does not implement the `%s' protocol",
756 IDENTIFIER_POINTER (TYPE_NAME (TREE_TYPE (rhs))),
757 IDENTIFIER_POINTER (PROTOCOL_NAME (p)));
761 /* May change...based on whether there was any mismatch */
764 else if (rhs_is_proto)
765 /* Lhs is not a protocol...warn if it is statically typed */
766 return (TYPED_OBJECT (TREE_TYPE (lhs)) != 0);
769 /* Defer to comptypes. */
773 else if (TREE_CODE (lhs) == RECORD_TYPE && TREE_CODE (rhs) == RECORD_TYPE)
774 ; /* Fall thru. This is the case we have been handling all along */
776 /* Defer to comptypes. */
779 /* `id' = `<class> *', `<class> *' = `id' */
781 if ((TYPE_NAME (lhs) == objc_object_id && TYPED_OBJECT (rhs))
782 || (TYPE_NAME (rhs) == objc_object_id && TYPED_OBJECT (lhs)))
785 /* `id' = `Class', `Class' = `id' */
787 else if ((TYPE_NAME (lhs) == objc_object_id
788 && TYPE_NAME (rhs) == objc_class_id)
789 || (TYPE_NAME (lhs) == objc_class_id
790 && TYPE_NAME (rhs) == objc_object_id))
793 /* `<class> *' = `<class> *' */
795 else if (TYPED_OBJECT (lhs) && TYPED_OBJECT (rhs))
797 tree lname = TYPE_NAME (lhs);
798 tree rname = TYPE_NAME (rhs);
804 /* If the left hand side is a super class of the right hand side,
806 for (inter = lookup_interface (rname); inter;
807 inter = lookup_interface (CLASS_SUPER_NAME (inter)))
808 if (lname == CLASS_SUPER_NAME (inter))
811 /* Allow the reverse when reflexive. */
813 for (inter = lookup_interface (lname); inter;
814 inter = lookup_interface (CLASS_SUPER_NAME (inter)))
815 if (rname == CLASS_SUPER_NAME (inter))
821 /* Defer to comptypes. */
825 /* Called from c-decl.c before all calls to rest_of_decl_compilation. */
828 objc_check_decl (decl)
831 tree type = TREE_TYPE (decl);
833 if (TREE_CODE (type) == RECORD_TYPE
834 && TREE_STATIC_TEMPLATE (type)
835 && type != constant_string_type)
836 error_with_decl (decl, "`%s' cannot be statically allocated");
840 maybe_objc_check_decl (decl)
843 objc_check_decl (decl);
846 /* Implement static typing. At this point, we know we have an interface. */
849 get_static_reference (interface, protocols)
853 tree type = xref_tag (RECORD_TYPE, interface);
857 tree t, m = TYPE_MAIN_VARIANT (type);
859 t = copy_node (type);
860 TYPE_BINFO (t) = make_tree_vec (2);
862 /* Add this type to the chain of variants of TYPE. */
863 TYPE_NEXT_VARIANT (t) = TYPE_NEXT_VARIANT (m);
864 TYPE_NEXT_VARIANT (m) = t;
866 /* Look up protocols and install in lang specific list. Note
867 that the protocol list can have a different lifetime than T! */
868 TYPE_PROTOCOL_LIST (t) = lookup_and_install_protocols (protocols);
870 /* This forces a new pointer type to be created later
871 (in build_pointer_type)...so that the new template
872 we just created will actually be used...what a hack! */
873 if (TYPE_POINTER_TO (t))
874 TYPE_POINTER_TO (t) = NULL_TREE;
883 get_object_reference (protocols)
886 tree type_decl = lookup_name (objc_id_id);
889 if (type_decl && TREE_CODE (type_decl) == TYPE_DECL)
891 type = TREE_TYPE (type_decl);
892 if (TYPE_MAIN_VARIANT (type) != id_type)
893 warning ("unexpected type for `id' (%s)",
894 gen_declaration (type, errbuf));
898 error ("undefined type `id', please import <objc/objc.h>");
899 return error_mark_node;
902 /* This clause creates a new pointer type that is qualified with
903 the protocol specification...this info is used later to do more
904 elaborate type checking. */
908 tree t, m = TYPE_MAIN_VARIANT (type);
910 t = copy_node (type);
911 TYPE_BINFO (t) = make_tree_vec (2);
913 /* Add this type to the chain of variants of TYPE. */
914 TYPE_NEXT_VARIANT (t) = TYPE_NEXT_VARIANT (m);
915 TYPE_NEXT_VARIANT (m) = t;
917 /* Look up protocols...and install in lang specific list */
918 TYPE_PROTOCOL_LIST (t) = lookup_and_install_protocols (protocols);
920 /* This forces a new pointer type to be created later
921 (in build_pointer_type)...so that the new template
922 we just created will actually be used...what a hack! */
923 if (TYPE_POINTER_TO (t))
924 TYPE_POINTER_TO (t) = NULL_TREE;
931 /* Check for circular dependencies in protocols. The arguments are
932 PROTO, the protocol to check, and LIST, a list of protocol it
936 check_protocol_recursively (proto, list)
942 for (p = list; p; p = TREE_CHAIN (p))
944 tree pp = TREE_VALUE (p);
946 if (TREE_CODE (pp) == IDENTIFIER_NODE)
947 pp = lookup_protocol (pp);
950 fatal_error ("protocol `%s' has circular dependency",
951 IDENTIFIER_POINTER (PROTOCOL_NAME (pp)));
953 check_protocol_recursively (proto, PROTOCOL_LIST (pp));
958 lookup_and_install_protocols (protocols)
963 tree return_value = protocols;
965 for (proto = protocols; proto; proto = TREE_CHAIN (proto))
967 tree ident = TREE_VALUE (proto);
968 tree p = lookup_protocol (ident);
972 error ("cannot find protocol declaration for `%s'",
973 IDENTIFIER_POINTER (ident));
975 TREE_CHAIN (prev) = TREE_CHAIN (proto);
977 return_value = TREE_CHAIN (proto);
981 /* Replace identifier with actual protocol node. */
982 TREE_VALUE (proto) = p;
990 /* Create and push a decl for a built-in external variable or field NAME.
992 TYPE is its data type. */
995 create_builtin_decl (code, type, name)
1000 tree decl = build_decl (code, get_identifier (name), type);
1002 if (code == VAR_DECL)
1004 TREE_STATIC (decl) = 1;
1005 make_decl_rtl (decl, 0);
1009 DECL_ARTIFICIAL (decl) = 1;
1013 /* Find the decl for the constant string class. */
1016 setup_string_decl ()
1018 if (!string_class_decl)
1020 if (!constant_string_global_id)
1021 constant_string_global_id = get_identifier (STRING_OBJECT_GLOBAL_NAME);
1022 string_class_decl = lookup_name (constant_string_global_id);
1026 /* Purpose: "play" parser, creating/installing representations
1027 of the declarations that are required by Objective-C.
1031 type_spec--------->sc_spec
1032 (tree_list) (tree_list)
1035 identifier_node identifier_node */
1038 synth_module_prologue ()
1043 /* Defined in `objc.h' */
1044 objc_object_id = get_identifier (TAG_OBJECT);
1046 objc_object_reference = xref_tag (RECORD_TYPE, objc_object_id);
1048 id_type = build_pointer_type (objc_object_reference);
1050 objc_id_id = get_identifier (TYPE_ID);
1051 objc_class_id = get_identifier (TAG_CLASS);
1053 objc_class_type = build_pointer_type (xref_tag (RECORD_TYPE, objc_class_id));
1054 protocol_type = build_pointer_type (xref_tag (RECORD_TYPE,
1055 get_identifier (PROTOCOL_OBJECT_CLASS_NAME)));
1057 /* Declare type of selector-objects that represent an operation name. */
1059 /* `struct objc_selector *' */
1061 = build_pointer_type (xref_tag (RECORD_TYPE,
1062 get_identifier (TAG_SELECTOR)));
1064 /* Forward declare type, or else the prototype for msgSendSuper will
1067 super_p = build_pointer_type (xref_tag (RECORD_TYPE,
1068 get_identifier (TAG_SUPER)));
1071 /* id objc_msgSend (id, SEL, ...); */
1074 = build_function_type (id_type,
1075 tree_cons (NULL_TREE, id_type,
1076 tree_cons (NULL_TREE, selector_type,
1079 if (! flag_next_runtime)
1081 umsg_decl = build_decl (FUNCTION_DECL,
1082 get_identifier (TAG_MSGSEND), temp_type);
1083 DECL_EXTERNAL (umsg_decl) = 1;
1084 TREE_PUBLIC (umsg_decl) = 1;
1085 DECL_INLINE (umsg_decl) = 1;
1086 DECL_ARTIFICIAL (umsg_decl) = 1;
1088 make_decl_rtl (umsg_decl, NULL);
1089 pushdecl (umsg_decl);
1092 umsg_decl = builtin_function (TAG_MSGSEND, temp_type, 0, NOT_BUILT_IN, 0);
1094 /* id objc_msgSendSuper (struct objc_super *, SEL, ...); */
1097 = build_function_type (id_type,
1098 tree_cons (NULL_TREE, super_p,
1099 tree_cons (NULL_TREE, selector_type,
1102 umsg_super_decl = builtin_function (TAG_MSGSENDSUPER,
1103 temp_type, 0, NOT_BUILT_IN, 0);
1105 /* id objc_getClass (const char *); */
1107 temp_type = build_function_type (id_type,
1108 tree_cons (NULL_TREE,
1109 const_string_type_node,
1110 tree_cons (NULL_TREE, void_type_node,
1114 = builtin_function (TAG_GETCLASS, temp_type, 0, NOT_BUILT_IN, 0);
1116 /* id objc_getMetaClass (const char *); */
1118 objc_get_meta_class_decl
1119 = builtin_function (TAG_GETMETACLASS, temp_type, 0, NOT_BUILT_IN, 0);
1121 /* static SEL _OBJC_SELECTOR_TABLE[]; */
1123 if (! flag_next_runtime)
1125 if (flag_typed_selectors)
1127 /* Suppress outputting debug symbols, because
1128 dbxout_init hasn'r been called yet. */
1129 enum debug_info_type save_write_symbols = write_symbols;
1130 const struct gcc_debug_hooks *const save_hooks = debug_hooks;
1131 write_symbols = NO_DEBUG;
1132 debug_hooks = &do_nothing_debug_hooks;
1134 build_selector_template ();
1135 temp_type = build_array_type (objc_selector_template, NULL_TREE);
1137 write_symbols = save_write_symbols;
1138 debug_hooks = save_hooks;
1141 temp_type = build_array_type (selector_type, NULL_TREE);
1143 layout_type (temp_type);
1144 UOBJC_SELECTOR_TABLE_decl
1145 = create_builtin_decl (VAR_DECL, temp_type,
1146 "_OBJC_SELECTOR_TABLE");
1148 /* Avoid warning when not sending messages. */
1149 TREE_USED (UOBJC_SELECTOR_TABLE_decl) = 1;
1152 generate_forward_declaration_to_string_table ();
1154 /* Forward declare constant_string_id and constant_string_type. */
1155 if (!constant_string_class_name)
1156 constant_string_class_name = default_constant_string_class_name;
1158 constant_string_id = get_identifier (constant_string_class_name);
1159 constant_string_type = xref_tag (RECORD_TYPE, constant_string_id);
1162 /* Predefine the following data type:
1164 struct STRING_OBJECT_CLASS_NAME
1168 unsigned int length;
1172 build_string_class_template ()
1174 tree field_decl, field_decl_chain;
1176 field_decl = create_builtin_decl (FIELD_DECL, id_type, "isa");
1177 field_decl_chain = field_decl;
1179 field_decl = create_builtin_decl (FIELD_DECL,
1180 build_pointer_type (char_type_node),
1182 chainon (field_decl_chain, field_decl);
1184 field_decl = create_builtin_decl (FIELD_DECL, unsigned_type_node, "length");
1185 chainon (field_decl_chain, field_decl);
1187 finish_struct (constant_string_type, field_decl_chain, NULL_TREE);
1190 /* Custom build_string which sets TREE_TYPE! */
1193 my_build_string (len, str)
1197 return fix_string_type (build_string (len, str));
1200 /* Given a chain of STRING_CST's, build a static instance of
1201 NXConstantString which points at the concatenation of those strings.
1202 We place the string object in the __string_objects section of the
1203 __OBJC segment. The Objective-C runtime will initialize the isa
1204 pointers of the string objects to point at the NXConstantString
1208 build_objc_string_object (strings)
1211 tree string, initlist, constructor;
1214 if (lookup_interface (constant_string_id) == NULL_TREE)
1216 error ("cannot find interface declaration for `%s'",
1217 IDENTIFIER_POINTER (constant_string_id));
1218 return error_mark_node;
1221 add_class_reference (constant_string_id);
1223 if (TREE_CHAIN (strings))
1225 varray_type vstrings;
1226 VARRAY_TREE_INIT (vstrings, 32, "strings");
1228 for (; strings ; strings = TREE_CHAIN (strings))
1229 VARRAY_PUSH_TREE (vstrings, strings);
1231 string = combine_strings (vstrings);
1236 string = fix_string_type (string);
1238 TREE_SET_CODE (string, STRING_CST);
1239 length = TREE_STRING_LENGTH (string) - 1;
1241 /* We could not properly create NXConstantString in synth_module_prologue,
1242 because that's called before debugging is initialized. Do it now. */
1243 if (TYPE_FIELDS (constant_string_type) == NULL_TREE)
1244 build_string_class_template ();
1246 /* & ((NXConstantString) { NULL, string, length }) */
1248 if (flag_next_runtime)
1250 /* For the NeXT runtime, we can generate a literal reference
1251 to the string class, don't need to run a constructor. */
1252 setup_string_decl ();
1253 if (string_class_decl == NULL_TREE)
1255 error ("cannot find reference tag for class `%s'",
1256 IDENTIFIER_POINTER (constant_string_id));
1257 return error_mark_node;
1259 initlist = build_tree_list
1261 copy_node (build_unary_op (ADDR_EXPR, string_class_decl, 0)));
1265 initlist = build_tree_list (NULL_TREE, build_int_2 (0, 0));
1269 = tree_cons (NULL_TREE, copy_node (build_unary_op (ADDR_EXPR, string, 1)),
1271 initlist = tree_cons (NULL_TREE, build_int_2 (length, 0), initlist);
1272 constructor = build_constructor (constant_string_type, nreverse (initlist));
1274 if (!flag_next_runtime)
1277 = objc_add_static_instance (constructor, constant_string_type);
1280 return (build_unary_op (ADDR_EXPR, constructor, 1));
1283 /* Declare a static instance of CLASS_DECL initialized by CONSTRUCTOR. */
1286 objc_add_static_instance (constructor, class_decl)
1287 tree constructor, class_decl;
1289 static int num_static_inst;
1293 /* Find the list of static instances for the CLASS_DECL. Create one if
1295 for (chain = &objc_static_instances;
1296 *chain && TREE_VALUE (*chain) != class_decl;
1297 chain = &TREE_CHAIN (*chain));
1300 *chain = tree_cons (NULL_TREE, class_decl, NULL_TREE);
1301 add_objc_string (TYPE_NAME (class_decl), class_names);
1304 sprintf (buf, "_OBJC_INSTANCE_%d", num_static_inst++);
1305 decl = build_decl (VAR_DECL, get_identifier (buf), class_decl);
1306 DECL_COMMON (decl) = 1;
1307 TREE_STATIC (decl) = 1;
1308 DECL_ARTIFICIAL (decl) = 1;
1309 DECL_INITIAL (decl) = constructor;
1311 /* We may be writing something else just now.
1312 Postpone till end of input. */
1313 DECL_DEFER_OUTPUT (decl) = 1;
1314 pushdecl_top_level (decl);
1315 rest_of_decl_compilation (decl, 0, 1, 0);
1317 /* Add the DECL to the head of this CLASS' list. */
1318 TREE_PURPOSE (*chain) = tree_cons (NULL_TREE, decl, TREE_PURPOSE (*chain));
1323 /* Build a static constant CONSTRUCTOR
1324 with type TYPE and elements ELTS. */
1327 build_constructor (type, elts)
1330 tree constructor, f, e;
1332 /* ??? Most of the places that we build constructors, we don't fill in
1333 the type of integers properly. Convert them all en masse. */
1334 if (TREE_CODE (type) == ARRAY_TYPE)
1336 f = TREE_TYPE (type);
1337 if (TREE_CODE (f) == POINTER_TYPE || TREE_CODE (f) == INTEGER_TYPE)
1338 for (e = elts; e ; e = TREE_CHAIN (e))
1339 TREE_VALUE (e) = convert (f, TREE_VALUE (e));
1343 f = TYPE_FIELDS (type);
1344 for (e = elts; e ; e = TREE_CHAIN (e), f = TREE_CHAIN (f))
1345 if (TREE_CODE (TREE_TYPE (f)) == POINTER_TYPE
1346 || TREE_CODE (TREE_TYPE (f)) == INTEGER_TYPE)
1347 TREE_VALUE (e) = convert (TREE_TYPE (f), TREE_VALUE (e));
1350 constructor = build (CONSTRUCTOR, type, NULL_TREE, elts);
1351 TREE_CONSTANT (constructor) = 1;
1352 TREE_STATIC (constructor) = 1;
1353 TREE_READONLY (constructor) = 1;
1358 /* Take care of defining and initializing _OBJC_SYMBOLS. */
1360 /* Predefine the following data type:
1368 void *defs[cls_def_cnt + cat_def_cnt];
1372 build_objc_symtab_template ()
1374 tree field_decl, field_decl_chain, index;
1376 objc_symtab_template
1377 = start_struct (RECORD_TYPE, get_identifier (UTAG_SYMTAB));
1379 /* long sel_ref_cnt; */
1381 field_decl = create_builtin_decl (FIELD_DECL,
1382 long_integer_type_node,
1384 field_decl_chain = field_decl;
1388 field_decl = create_builtin_decl (FIELD_DECL,
1389 build_pointer_type (selector_type),
1391 chainon (field_decl_chain, field_decl);
1393 /* short cls_def_cnt; */
1395 field_decl = create_builtin_decl (FIELD_DECL,
1396 short_integer_type_node,
1398 chainon (field_decl_chain, field_decl);
1400 /* short cat_def_cnt; */
1402 field_decl = create_builtin_decl (FIELD_DECL,
1403 short_integer_type_node,
1405 chainon (field_decl_chain, field_decl);
1407 /* void *defs[cls_def_cnt + cat_def_cnt]; */
1409 if (!flag_next_runtime)
1410 index = build_index_type (build_int_2 (imp_count + cat_count, 0));
1412 index = build_index_type (build_int_2 (imp_count + cat_count - 1,
1413 imp_count == 0 && cat_count == 0
1415 field_decl = create_builtin_decl (FIELD_DECL,
1416 build_array_type (ptr_type_node, index),
1418 chainon (field_decl_chain, field_decl);
1420 finish_struct (objc_symtab_template, field_decl_chain, NULL_TREE);
1423 /* Create the initial value for the `defs' field of _objc_symtab.
1424 This is a CONSTRUCTOR. */
1427 init_def_list (type)
1430 tree expr, initlist = NULL_TREE;
1431 struct imp_entry *impent;
1434 for (impent = imp_list; impent; impent = impent->next)
1436 if (TREE_CODE (impent->imp_context) == CLASS_IMPLEMENTATION_TYPE)
1438 expr = build_unary_op (ADDR_EXPR, impent->class_decl, 0);
1439 initlist = tree_cons (NULL_TREE, expr, initlist);
1444 for (impent = imp_list; impent; impent = impent->next)
1446 if (TREE_CODE (impent->imp_context) == CATEGORY_IMPLEMENTATION_TYPE)
1448 expr = build_unary_op (ADDR_EXPR, impent->class_decl, 0);
1449 initlist = tree_cons (NULL_TREE, expr, initlist);
1453 if (!flag_next_runtime)
1455 /* statics = { ..., _OBJC_STATIC_INSTANCES, ... } */
1458 if (static_instances_decl)
1459 expr = build_unary_op (ADDR_EXPR, static_instances_decl, 0);
1461 expr = build_int_2 (0, 0);
1463 initlist = tree_cons (NULL_TREE, expr, initlist);
1466 return build_constructor (type, nreverse (initlist));
1469 /* Construct the initial value for all of _objc_symtab. */
1472 init_objc_symtab (type)
1477 /* sel_ref_cnt = { ..., 5, ... } */
1479 initlist = build_tree_list (NULL_TREE, build_int_2 (0, 0));
1481 /* refs = { ..., _OBJC_SELECTOR_TABLE, ... } */
1483 if (flag_next_runtime || ! sel_ref_chain)
1484 initlist = tree_cons (NULL_TREE, build_int_2 (0, 0), initlist);
1486 initlist = tree_cons (NULL_TREE,
1487 build_unary_op (ADDR_EXPR,
1488 UOBJC_SELECTOR_TABLE_decl, 1),
1491 /* cls_def_cnt = { ..., 5, ... } */
1493 initlist = tree_cons (NULL_TREE, build_int_2 (imp_count, 0), initlist);
1495 /* cat_def_cnt = { ..., 5, ... } */
1497 initlist = tree_cons (NULL_TREE, build_int_2 (cat_count, 0), initlist);
1499 /* cls_def = { ..., { &Foo, &Bar, ...}, ... } */
1501 if (imp_count || cat_count || static_instances_decl)
1504 tree field = TYPE_FIELDS (type);
1505 field = TREE_CHAIN (TREE_CHAIN (TREE_CHAIN (TREE_CHAIN (field))));
1507 initlist = tree_cons (NULL_TREE, init_def_list (TREE_TYPE (field)),
1511 return build_constructor (type, nreverse (initlist));
1514 /* Push forward-declarations of all the categories so that
1515 init_def_list can use them in a CONSTRUCTOR. */
1518 forward_declare_categories ()
1520 struct imp_entry *impent;
1521 tree sav = objc_implementation_context;
1523 for (impent = imp_list; impent; impent = impent->next)
1525 if (TREE_CODE (impent->imp_context) == CATEGORY_IMPLEMENTATION_TYPE)
1527 /* Set an invisible arg to synth_id_with_class_suffix. */
1528 objc_implementation_context = impent->imp_context;
1530 = create_builtin_decl (VAR_DECL, objc_category_template,
1531 IDENTIFIER_POINTER (synth_id_with_class_suffix ("_OBJC_CATEGORY", objc_implementation_context)));
1534 objc_implementation_context = sav;
1537 /* Create the declaration of _OBJC_SYMBOLS, with type `strict _objc_symtab'
1538 and initialized appropriately. */
1541 generate_objc_symtab_decl ()
1545 if (!objc_category_template)
1546 build_category_template ();
1548 /* forward declare categories */
1550 forward_declare_categories ();
1552 if (!objc_symtab_template)
1553 build_objc_symtab_template ();
1555 sc_spec = build_tree_list (NULL_TREE, ridpointers[(int) RID_STATIC]);
1557 UOBJC_SYMBOLS_decl = start_decl (get_identifier ("_OBJC_SYMBOLS"),
1558 tree_cons (NULL_TREE,
1559 objc_symtab_template, sc_spec),
1563 TREE_USED (UOBJC_SYMBOLS_decl) = 1;
1564 DECL_IGNORED_P (UOBJC_SYMBOLS_decl) = 1;
1565 DECL_ARTIFICIAL (UOBJC_SYMBOLS_decl) = 1;
1566 finish_decl (UOBJC_SYMBOLS_decl,
1567 init_objc_symtab (TREE_TYPE (UOBJC_SYMBOLS_decl)),
1572 init_module_descriptor (type)
1575 tree initlist, expr;
1577 /* version = { 1, ... } */
1579 expr = build_int_2 (OBJC_VERSION, 0);
1580 initlist = build_tree_list (NULL_TREE, expr);
1582 /* size = { ..., sizeof (struct objc_module), ... } */
1584 expr = size_in_bytes (objc_module_template);
1585 initlist = tree_cons (NULL_TREE, expr, initlist);
1587 /* name = { ..., "foo.m", ... } */
1589 expr = add_objc_string (get_identifier (input_filename), class_names);
1590 initlist = tree_cons (NULL_TREE, expr, initlist);
1592 /* symtab = { ..., _OBJC_SYMBOLS, ... } */
1594 if (UOBJC_SYMBOLS_decl)
1595 expr = build_unary_op (ADDR_EXPR, UOBJC_SYMBOLS_decl, 0);
1597 expr = build_int_2 (0, 0);
1598 initlist = tree_cons (NULL_TREE, expr, initlist);
1600 return build_constructor (type, nreverse (initlist));
1603 /* Write out the data structures to describe Objective C classes defined.
1604 If appropriate, compile and output a setup function to initialize them.
1605 Return a symbol_ref to the function to call to initialize the Objective C
1606 data structures for this file (and perhaps for other files also).
1608 struct objc_module { ... } _OBJC_MODULE = { ... }; */
1611 build_module_descriptor ()
1613 tree decl_specs, field_decl, field_decl_chain;
1615 objc_module_template
1616 = start_struct (RECORD_TYPE, get_identifier (UTAG_MODULE));
1620 decl_specs = build_tree_list (NULL_TREE, ridpointers[(int) RID_LONG]);
1621 field_decl = get_identifier ("version");
1623 = grokfield (input_filename, lineno, field_decl, decl_specs, NULL_TREE);
1624 field_decl_chain = field_decl;
1628 decl_specs = build_tree_list (NULL_TREE, ridpointers[(int) RID_LONG]);
1629 field_decl = get_identifier ("size");
1631 = grokfield (input_filename, lineno, field_decl, decl_specs, NULL_TREE);
1632 chainon (field_decl_chain, field_decl);
1636 decl_specs = build_tree_list (NULL_TREE, ridpointers[(int) RID_CHAR]);
1637 field_decl = build1 (INDIRECT_REF, NULL_TREE, get_identifier ("name"));
1639 = grokfield (input_filename, lineno, field_decl, decl_specs, NULL_TREE);
1640 chainon (field_decl_chain, field_decl);
1642 /* struct objc_symtab *symtab; */
1644 decl_specs = get_identifier (UTAG_SYMTAB);
1645 decl_specs = build_tree_list (NULL_TREE, xref_tag (RECORD_TYPE, decl_specs));
1646 field_decl = build1 (INDIRECT_REF, NULL_TREE, get_identifier ("symtab"));
1648 = grokfield (input_filename, lineno, field_decl, decl_specs, NULL_TREE);
1649 chainon (field_decl_chain, field_decl);
1651 finish_struct (objc_module_template, field_decl_chain, NULL_TREE);
1653 /* Create an instance of "objc_module". */
1655 decl_specs = tree_cons (NULL_TREE, objc_module_template,
1656 build_tree_list (NULL_TREE,
1657 ridpointers[(int) RID_STATIC]));
1659 UOBJC_MODULES_decl = start_decl (get_identifier ("_OBJC_MODULES"),
1660 decl_specs, 1, NULL_TREE);
1662 DECL_ARTIFICIAL (UOBJC_MODULES_decl) = 1;
1663 DECL_IGNORED_P (UOBJC_MODULES_decl) = 1;
1664 DECL_CONTEXT (UOBJC_MODULES_decl) = NULL_TREE;
1666 finish_decl (UOBJC_MODULES_decl,
1667 init_module_descriptor (TREE_TYPE (UOBJC_MODULES_decl)),
1670 /* Mark the decl to avoid "defined but not used" warning. */
1671 DECL_IN_SYSTEM_HEADER (UOBJC_MODULES_decl) = 1;
1673 /* Generate a constructor call for the module descriptor.
1674 This code was generated by reading the grammar rules
1675 of c-parse.in; Therefore, it may not be the most efficient
1676 way of generating the requisite code. */
1678 if (flag_next_runtime)
1682 tree parms, execclass_decl, decelerator, void_list_node_1;
1683 tree init_function_name, init_function_decl;
1685 /* Declare void __objc_execClass (void *); */
1687 void_list_node_1 = build_tree_list (NULL_TREE, void_type_node);
1688 execclass_decl = build_decl (FUNCTION_DECL,
1689 get_identifier (TAG_EXECCLASS),
1690 build_function_type (void_type_node,
1691 tree_cons (NULL_TREE, ptr_type_node,
1692 void_list_node_1)));
1693 DECL_EXTERNAL (execclass_decl) = 1;
1694 DECL_ARTIFICIAL (execclass_decl) = 1;
1695 TREE_PUBLIC (execclass_decl) = 1;
1696 pushdecl (execclass_decl);
1697 rest_of_decl_compilation (execclass_decl, 0, 0, 0);
1698 assemble_external (execclass_decl);
1700 /* void _GLOBAL_$I$<gnyf> () {objc_execClass (&L_OBJC_MODULES);} */
1702 init_function_name = get_file_function_name ('I');
1703 start_function (void_list_node_1,
1704 build_nt (CALL_EXPR, init_function_name,
1705 tree_cons (NULL_TREE, NULL_TREE,
1709 store_parm_decls ();
1711 init_function_decl = current_function_decl;
1712 TREE_PUBLIC (init_function_decl) = ! targetm.have_ctors_dtors;
1713 TREE_USED (init_function_decl) = 1;
1714 /* Don't let this one be deferred. */
1715 DECL_INLINE (init_function_decl) = 0;
1716 DECL_UNINLINABLE (init_function_decl) = 1;
1717 current_function_cannot_inline
1718 = "static constructors and destructors cannot be inlined";
1721 = build_tree_list (NULL_TREE,
1722 build_unary_op (ADDR_EXPR, UOBJC_MODULES_decl, 0));
1723 decelerator = build_function_call (execclass_decl, parms);
1725 c_expand_expr_stmt (decelerator);
1727 finish_function (0, 0);
1729 return XEXP (DECL_RTL (init_function_decl), 0);
1733 /* extern const char _OBJC_STRINGS[]; */
1736 generate_forward_declaration_to_string_table ()
1738 tree sc_spec, decl_specs, expr_decl;
1740 sc_spec = tree_cons (NULL_TREE, ridpointers[(int) RID_EXTERN], NULL_TREE);
1741 decl_specs = tree_cons (NULL_TREE, ridpointers[(int) RID_CHAR], sc_spec);
1744 = build_nt (ARRAY_REF, get_identifier ("_OBJC_STRINGS"), NULL_TREE);
1746 UOBJC_STRINGS_decl = define_decl (expr_decl, decl_specs);
1749 /* Return the DECL of the string IDENT in the SECTION. */
1752 get_objc_string_decl (ident, section)
1754 enum string_section section;
1758 if (section == class_names)
1759 chain = class_names_chain;
1760 else if (section == meth_var_names)
1761 chain = meth_var_names_chain;
1762 else if (section == meth_var_types)
1763 chain = meth_var_types_chain;
1767 for (; chain != 0; chain = TREE_VALUE (chain))
1768 if (TREE_VALUE (chain) == ident)
1769 return (TREE_PURPOSE (chain));
1775 /* Output references to all statically allocated objects. Return the DECL
1776 for the array built. */
1779 generate_static_references ()
1781 tree decls = NULL_TREE, ident, decl_spec, expr_decl, expr = NULL_TREE;
1782 tree class_name, class, decl, initlist;
1783 tree cl_chain, in_chain, type;
1784 int num_inst, num_class;
1787 if (flag_next_runtime)
1790 for (cl_chain = objc_static_instances, num_class = 0;
1791 cl_chain; cl_chain = TREE_CHAIN (cl_chain), num_class++)
1793 for (num_inst = 0, in_chain = TREE_PURPOSE (cl_chain);
1794 in_chain; num_inst++, in_chain = TREE_CHAIN (in_chain));
1796 sprintf (buf, "_OBJC_STATIC_INSTANCES_%d", num_class);
1797 ident = get_identifier (buf);
1799 expr_decl = build_nt (ARRAY_REF, ident, NULL_TREE);
1800 decl_spec = tree_cons (NULL_TREE, build_pointer_type (void_type_node),
1801 build_tree_list (NULL_TREE,
1802 ridpointers[(int) RID_STATIC]));
1803 decl = start_decl (expr_decl, decl_spec, 1, NULL_TREE);
1804 DECL_CONTEXT (decl) = 0;
1805 DECL_ARTIFICIAL (decl) = 1;
1807 /* Output {class_name, ...}. */
1808 class = TREE_VALUE (cl_chain);
1809 class_name = get_objc_string_decl (TYPE_NAME (class), class_names);
1810 initlist = build_tree_list (NULL_TREE,
1811 build_unary_op (ADDR_EXPR, class_name, 1));
1813 /* Output {..., instance, ...}. */
1814 for (in_chain = TREE_PURPOSE (cl_chain);
1815 in_chain; in_chain = TREE_CHAIN (in_chain))
1817 expr = build_unary_op (ADDR_EXPR, TREE_VALUE (in_chain), 1);
1818 initlist = tree_cons (NULL_TREE, expr, initlist);
1821 /* Output {..., NULL}. */
1822 initlist = tree_cons (NULL_TREE, build_int_2 (0, 0), initlist);
1824 expr = build_constructor (TREE_TYPE (decl), nreverse (initlist));
1825 finish_decl (decl, expr, NULL_TREE);
1826 TREE_USED (decl) = 1;
1828 type = build_array_type (build_pointer_type (void_type_node), 0);
1829 decl = build_decl (VAR_DECL, ident, type);
1830 TREE_USED (decl) = 1;
1831 TREE_STATIC (decl) = 1;
1833 = tree_cons (NULL_TREE, build_unary_op (ADDR_EXPR, decl, 1), decls);
1836 decls = tree_cons (NULL_TREE, build_int_2 (0, 0), decls);
1837 ident = get_identifier ("_OBJC_STATIC_INSTANCES");
1838 expr_decl = build_nt (ARRAY_REF, ident, NULL_TREE);
1839 decl_spec = tree_cons (NULL_TREE, build_pointer_type (void_type_node),
1840 build_tree_list (NULL_TREE,
1841 ridpointers[(int) RID_STATIC]));
1842 static_instances_decl
1843 = start_decl (expr_decl, decl_spec, 1, NULL_TREE);
1844 TREE_USED (static_instances_decl) = 1;
1845 DECL_CONTEXT (static_instances_decl) = 0;
1846 DECL_ARTIFICIAL (static_instances_decl) = 1;
1847 expr = build_constructor (TREE_TYPE (static_instances_decl),
1849 finish_decl (static_instances_decl, expr, NULL_TREE);
1852 /* Output all strings. */
1857 tree sc_spec, decl_specs, expr_decl;
1858 tree chain, string_expr;
1861 for (chain = class_names_chain; chain; chain = TREE_CHAIN (chain))
1863 string = TREE_VALUE (chain);
1864 decl = TREE_PURPOSE (chain);
1866 = tree_cons (NULL_TREE, ridpointers[(int) RID_STATIC], NULL_TREE);
1867 decl_specs = tree_cons (NULL_TREE, ridpointers[(int) RID_CHAR], sc_spec);
1868 expr_decl = build_nt (ARRAY_REF, DECL_NAME (decl), NULL_TREE);
1869 decl = start_decl (expr_decl, decl_specs, 1, NULL_TREE);
1870 DECL_CONTEXT (decl) = NULL_TREE;
1871 string_expr = my_build_string (IDENTIFIER_LENGTH (string) + 1,
1872 IDENTIFIER_POINTER (string));
1873 finish_decl (decl, string_expr, NULL_TREE);
1876 for (chain = meth_var_names_chain; chain; chain = TREE_CHAIN (chain))
1878 string = TREE_VALUE (chain);
1879 decl = TREE_PURPOSE (chain);
1881 = tree_cons (NULL_TREE, ridpointers[(int) RID_STATIC], NULL_TREE);
1882 decl_specs = tree_cons (NULL_TREE, ridpointers[(int) RID_CHAR], sc_spec);
1883 expr_decl = build_nt (ARRAY_REF, DECL_NAME (decl), NULL_TREE);
1884 decl = start_decl (expr_decl, decl_specs, 1, NULL_TREE);
1885 DECL_CONTEXT (decl) = NULL_TREE;
1886 string_expr = my_build_string (IDENTIFIER_LENGTH (string) + 1,
1887 IDENTIFIER_POINTER (string));
1888 finish_decl (decl, string_expr, NULL_TREE);
1891 for (chain = meth_var_types_chain; chain; chain = TREE_CHAIN (chain))
1893 string = TREE_VALUE (chain);
1894 decl = TREE_PURPOSE (chain);
1896 = tree_cons (NULL_TREE, ridpointers[(int) RID_STATIC], NULL_TREE);
1897 decl_specs = tree_cons (NULL_TREE, ridpointers[(int) RID_CHAR], sc_spec);
1898 expr_decl = build_nt (ARRAY_REF, DECL_NAME (decl), NULL_TREE);
1899 decl = start_decl (expr_decl, decl_specs, 1, NULL_TREE);
1900 DECL_CONTEXT (decl) = NULL_TREE;
1901 string_expr = my_build_string (IDENTIFIER_LENGTH (string) + 1,
1902 IDENTIFIER_POINTER (string));
1903 finish_decl (decl, string_expr, NULL_TREE);
1908 build_selector_reference_decl ()
1914 sprintf (buf, "_OBJC_SELECTOR_REFERENCES_%d", idx++);
1916 ident = get_identifier (buf);
1918 decl = build_decl (VAR_DECL, ident, selector_type);
1919 DECL_EXTERNAL (decl) = 1;
1920 TREE_PUBLIC (decl) = 1;
1921 TREE_USED (decl) = 1;
1922 TREE_READONLY (decl) = 1;
1923 DECL_ARTIFICIAL (decl) = 1;
1924 DECL_CONTEXT (decl) = 0;
1926 make_decl_rtl (decl, 0);
1927 pushdecl_top_level (decl);
1932 /* Just a handy wrapper for add_objc_string. */
1935 build_selector (ident)
1938 tree expr = add_objc_string (ident, meth_var_names);
1939 if (flag_typed_selectors)
1942 return build_c_cast (selector_type, expr); /* cast! */
1946 build_selector_translation_table ()
1948 tree sc_spec, decl_specs;
1949 tree chain, initlist = NULL_TREE;
1951 tree decl = NULL_TREE, var_decl, name;
1953 for (chain = sel_ref_chain; chain; chain = TREE_CHAIN (chain))
1957 expr = build_selector (TREE_VALUE (chain));
1959 if (flag_next_runtime)
1961 name = DECL_NAME (TREE_PURPOSE (chain));
1963 sc_spec = build_tree_list (NULL_TREE, ridpointers[(int) RID_STATIC]);
1965 /* static SEL _OBJC_SELECTOR_REFERENCES_n = ...; */
1966 decl_specs = tree_cons (NULL_TREE, selector_type, sc_spec);
1970 /* The `decl' that is returned from start_decl is the one that we
1971 forward declared in `build_selector_reference' */
1972 decl = start_decl (var_decl, decl_specs, 1, NULL_TREE );
1975 /* add one for the '\0' character */
1976 offset += IDENTIFIER_LENGTH (TREE_VALUE (chain)) + 1;
1978 if (flag_next_runtime)
1979 finish_decl (decl, expr, NULL_TREE);
1982 if (flag_typed_selectors)
1984 tree eltlist = NULL_TREE;
1985 tree encoding = get_proto_encoding (TREE_PURPOSE (chain));
1986 eltlist = tree_cons (NULL_TREE, expr, NULL_TREE);
1987 eltlist = tree_cons (NULL_TREE, encoding, eltlist);
1988 expr = build_constructor (objc_selector_template,
1989 nreverse (eltlist));
1991 initlist = tree_cons (NULL_TREE, expr, initlist);
1996 if (! flag_next_runtime)
1998 /* Cause the variable and its initial value to be actually output. */
1999 DECL_EXTERNAL (UOBJC_SELECTOR_TABLE_decl) = 0;
2000 TREE_STATIC (UOBJC_SELECTOR_TABLE_decl) = 1;
2001 /* NULL terminate the list and fix the decl for output. */
2002 initlist = tree_cons (NULL_TREE, build_int_2 (0, 0), initlist);
2003 DECL_INITIAL (UOBJC_SELECTOR_TABLE_decl) = objc_ellipsis_node;
2004 initlist = build_constructor (TREE_TYPE (UOBJC_SELECTOR_TABLE_decl),
2005 nreverse (initlist));
2006 finish_decl (UOBJC_SELECTOR_TABLE_decl, initlist, NULL_TREE);
2007 current_function_decl = NULL_TREE;
2012 get_proto_encoding (proto)
2020 if (! METHOD_ENCODING (proto))
2022 tmp_decl = build_tmp_function_decl ();
2023 hack_method_prototype (proto, tmp_decl);
2024 encoding = encode_method_prototype (proto, tmp_decl);
2025 METHOD_ENCODING (proto) = encoding;
2028 encoding = METHOD_ENCODING (proto);
2030 return add_objc_string (encoding, meth_var_types);
2033 return build_int_2 (0, 0);
2036 /* sel_ref_chain is a list whose "value" fields will be instances of
2037 identifier_node that represent the selector. */
2040 build_typed_selector_reference (ident, proto)
2043 tree *chain = &sel_ref_chain;
2049 if (TREE_PURPOSE (*chain) == ident && TREE_VALUE (*chain) == proto)
2050 goto return_at_index;
2053 chain = &TREE_CHAIN (*chain);
2056 *chain = tree_cons (proto, ident, NULL_TREE);
2059 expr = build_unary_op (ADDR_EXPR,
2060 build_array_ref (UOBJC_SELECTOR_TABLE_decl,
2061 build_int_2 (index, 0)),
2063 return build_c_cast (selector_type, expr);
2067 build_selector_reference (ident)
2070 tree *chain = &sel_ref_chain;
2076 if (TREE_VALUE (*chain) == ident)
2077 return (flag_next_runtime
2078 ? TREE_PURPOSE (*chain)
2079 : build_array_ref (UOBJC_SELECTOR_TABLE_decl,
2080 build_int_2 (index, 0)));
2083 chain = &TREE_CHAIN (*chain);
2086 expr = build_selector_reference_decl ();
2088 *chain = tree_cons (expr, ident, NULL_TREE);
2090 return (flag_next_runtime
2092 : build_array_ref (UOBJC_SELECTOR_TABLE_decl,
2093 build_int_2 (index, 0)));
2097 build_class_reference_decl ()
2103 sprintf (buf, "_OBJC_CLASS_REFERENCES_%d", idx++);
2105 ident = get_identifier (buf);
2107 decl = build_decl (VAR_DECL, ident, objc_class_type);
2108 DECL_EXTERNAL (decl) = 1;
2109 TREE_PUBLIC (decl) = 1;
2110 TREE_USED (decl) = 1;
2111 TREE_READONLY (decl) = 1;
2112 DECL_CONTEXT (decl) = 0;
2113 DECL_ARTIFICIAL (decl) = 1;
2115 make_decl_rtl (decl, 0);
2116 pushdecl_top_level (decl);
2121 /* Create a class reference, but don't create a variable to reference
2125 add_class_reference (ident)
2130 if ((chain = cls_ref_chain))
2135 if (ident == TREE_VALUE (chain))
2139 chain = TREE_CHAIN (chain);
2143 /* Append to the end of the list */
2144 TREE_CHAIN (tail) = tree_cons (NULL_TREE, ident, NULL_TREE);
2147 cls_ref_chain = tree_cons (NULL_TREE, ident, NULL_TREE);
2150 /* Get a class reference, creating it if necessary. Also create the
2151 reference variable. */
2154 get_class_reference (ident)
2157 if (flag_next_runtime)
2162 for (chain = &cls_ref_chain; *chain; chain = &TREE_CHAIN (*chain))
2163 if (TREE_VALUE (*chain) == ident)
2165 if (! TREE_PURPOSE (*chain))
2166 TREE_PURPOSE (*chain) = build_class_reference_decl ();
2168 return TREE_PURPOSE (*chain);
2171 decl = build_class_reference_decl ();
2172 *chain = tree_cons (decl, ident, NULL_TREE);
2179 add_class_reference (ident);
2181 params = build_tree_list (NULL_TREE,
2182 my_build_string (IDENTIFIER_LENGTH (ident) + 1,
2183 IDENTIFIER_POINTER (ident)));
2185 assemble_external (objc_get_class_decl);
2186 return build_function_call (objc_get_class_decl, params);
2190 /* For each string section we have a chain which maps identifier nodes
2191 to decls for the strings. */
2194 add_objc_string (ident, section)
2196 enum string_section section;
2200 if (section == class_names)
2201 chain = &class_names_chain;
2202 else if (section == meth_var_names)
2203 chain = &meth_var_names_chain;
2204 else if (section == meth_var_types)
2205 chain = &meth_var_types_chain;
2211 if (TREE_VALUE (*chain) == ident)
2212 return build_unary_op (ADDR_EXPR, TREE_PURPOSE (*chain), 1);
2214 chain = &TREE_CHAIN (*chain);
2217 decl = build_objc_string_decl (section);
2219 *chain = tree_cons (decl, ident, NULL_TREE);
2221 return build_unary_op (ADDR_EXPR, decl, 1);
2225 build_objc_string_decl (section)
2226 enum string_section section;
2230 static int class_names_idx = 0;
2231 static int meth_var_names_idx = 0;
2232 static int meth_var_types_idx = 0;
2234 if (section == class_names)
2235 sprintf (buf, "_OBJC_CLASS_NAME_%d", class_names_idx++);
2236 else if (section == meth_var_names)
2237 sprintf (buf, "_OBJC_METH_VAR_NAME_%d", meth_var_names_idx++);
2238 else if (section == meth_var_types)
2239 sprintf (buf, "_OBJC_METH_VAR_TYPE_%d", meth_var_types_idx++);
2241 ident = get_identifier (buf);
2243 decl = build_decl (VAR_DECL, ident, build_array_type (char_type_node, 0));
2244 DECL_EXTERNAL (decl) = 1;
2245 TREE_PUBLIC (decl) = 1;
2246 TREE_USED (decl) = 1;
2247 TREE_READONLY (decl) = 1;
2248 TREE_CONSTANT (decl) = 1;
2249 DECL_CONTEXT (decl) = 0;
2250 DECL_ARTIFICIAL (decl) = 1;
2252 make_decl_rtl (decl, 0);
2253 pushdecl_top_level (decl);
2260 objc_declare_alias (alias_ident, class_ident)
2264 if (is_class_name (class_ident) != class_ident)
2265 warning ("cannot find class `%s'", IDENTIFIER_POINTER (class_ident));
2266 else if (is_class_name (alias_ident))
2267 warning ("class `%s' already exists", IDENTIFIER_POINTER (alias_ident));
2269 alias_chain = tree_cons (class_ident, alias_ident, alias_chain);
2273 objc_declare_class (ident_list)
2278 for (list = ident_list; list; list = TREE_CHAIN (list))
2280 tree ident = TREE_VALUE (list);
2283 if ((decl = lookup_name (ident)))
2285 error ("`%s' redeclared as different kind of symbol",
2286 IDENTIFIER_POINTER (ident));
2287 error_with_decl (decl, "previous declaration of `%s'");
2290 if (! is_class_name (ident))
2292 tree record = xref_tag (RECORD_TYPE, ident);
2293 TREE_STATIC_TEMPLATE (record) = 1;
2294 class_chain = tree_cons (NULL_TREE, ident, class_chain);
2300 is_class_name (ident)
2305 if (lookup_interface (ident))
2308 for (chain = class_chain; chain; chain = TREE_CHAIN (chain))
2310 if (ident == TREE_VALUE (chain))
2314 for (chain = alias_chain; chain; chain = TREE_CHAIN (chain))
2316 if (ident == TREE_VALUE (chain))
2317 return TREE_PURPOSE (chain);
2324 lookup_interface (ident)
2329 for (chain = interface_chain; chain; chain = TREE_CHAIN (chain))
2331 if (ident == CLASS_NAME (chain))
2338 objc_copy_list (list, head)
2342 tree newlist = NULL_TREE, tail = NULL_TREE;
2346 tail = copy_node (list);
2348 /* The following statement fixes a bug when inheriting instance
2349 variables that are declared to be bitfields. finish_struct
2350 expects to find the width of the bitfield in DECL_INITIAL. */
2351 if (DECL_BIT_FIELD (tail) && DECL_INITIAL (tail) == 0)
2352 DECL_INITIAL (tail) = DECL_SIZE (tail);
2354 newlist = chainon (newlist, tail);
2355 list = TREE_CHAIN (list);
2362 /* Used by: build_private_template, get_class_ivars, and
2363 continue_class. COPY is 1 when called from @defs. In this case
2364 copy all fields. Otherwise don't copy leaf ivars since we rely on
2365 them being side-effected exactly once by finish_struct. */
2368 build_ivar_chain (interface, copy)
2372 tree my_name, super_name, ivar_chain;
2374 my_name = CLASS_NAME (interface);
2375 super_name = CLASS_SUPER_NAME (interface);
2377 /* Possibly copy leaf ivars. */
2379 objc_copy_list (CLASS_IVARS (interface), &ivar_chain);
2381 ivar_chain = CLASS_IVARS (interface);
2386 tree super_interface = lookup_interface (super_name);
2388 if (!super_interface)
2390 /* fatal did not work with 2 args...should fix */
2391 error ("cannot find interface declaration for `%s', superclass of `%s'",
2392 IDENTIFIER_POINTER (super_name),
2393 IDENTIFIER_POINTER (my_name));
2394 exit (FATAL_EXIT_CODE);
2397 if (super_interface == interface)
2398 fatal_error ("circular inheritance in interface declaration for `%s'",
2399 IDENTIFIER_POINTER (super_name));
2401 interface = super_interface;
2402 my_name = CLASS_NAME (interface);
2403 super_name = CLASS_SUPER_NAME (interface);
2405 op1 = CLASS_IVARS (interface);
2408 tree head, tail = objc_copy_list (op1, &head);
2410 /* Prepend super class ivars...make a copy of the list, we
2411 do not want to alter the original. */
2412 TREE_CHAIN (tail) = ivar_chain;
2419 /* struct <classname> {
2420 struct objc_class *isa;
2425 build_private_template (class)
2430 if (CLASS_STATIC_TEMPLATE (class))
2432 uprivate_record = CLASS_STATIC_TEMPLATE (class);
2433 ivar_context = TYPE_FIELDS (CLASS_STATIC_TEMPLATE (class));
2437 uprivate_record = start_struct (RECORD_TYPE, CLASS_NAME (class));
2439 ivar_context = build_ivar_chain (class, 0);
2441 finish_struct (uprivate_record, ivar_context, NULL_TREE);
2443 CLASS_STATIC_TEMPLATE (class) = uprivate_record;
2445 /* mark this record as class template - for class type checking */
2446 TREE_STATIC_TEMPLATE (uprivate_record) = 1;
2450 = groktypename (build_tree_list (build_tree_list (NULL_TREE,
2452 build1 (INDIRECT_REF, NULL_TREE,
2455 return ivar_context;
2458 /* Begin code generation for protocols... */
2460 /* struct objc_protocol {
2461 char *protocol_name;
2462 struct objc_protocol **protocol_list;
2463 struct objc_method_desc *instance_methods;
2464 struct objc_method_desc *class_methods;
2468 build_protocol_template ()
2470 tree decl_specs, field_decl, field_decl_chain;
2473 template = start_struct (RECORD_TYPE, get_identifier (UTAG_PROTOCOL));
2475 /* struct objc_class *isa; */
2477 decl_specs = build_tree_list (NULL_TREE, xref_tag (RECORD_TYPE,
2478 get_identifier (UTAG_CLASS)));
2479 field_decl = build1 (INDIRECT_REF, NULL_TREE, get_identifier ("isa"));
2481 = grokfield (input_filename, lineno, field_decl, decl_specs, NULL_TREE);
2482 field_decl_chain = field_decl;
2484 /* char *protocol_name; */
2486 decl_specs = build_tree_list (NULL_TREE, ridpointers[(int) RID_CHAR]);
2488 = build1 (INDIRECT_REF, NULL_TREE, get_identifier ("protocol_name"));
2490 = grokfield (input_filename, lineno, field_decl, decl_specs, NULL_TREE);
2491 chainon (field_decl_chain, field_decl);
2493 /* struct objc_protocol **protocol_list; */
2495 decl_specs = build_tree_list (NULL_TREE, template);
2497 = build1 (INDIRECT_REF, NULL_TREE, get_identifier ("protocol_list"));
2498 field_decl = build1 (INDIRECT_REF, NULL_TREE, field_decl);
2500 = grokfield (input_filename, lineno, field_decl, decl_specs, NULL_TREE);
2501 chainon (field_decl_chain, field_decl);
2503 /* struct objc_method_list *instance_methods; */
2506 = build_tree_list (NULL_TREE,
2507 xref_tag (RECORD_TYPE,
2508 get_identifier (UTAG_METHOD_PROTOTYPE_LIST)));
2510 = build1 (INDIRECT_REF, NULL_TREE, get_identifier ("instance_methods"));
2512 = grokfield (input_filename, lineno, field_decl, decl_specs, NULL_TREE);
2513 chainon (field_decl_chain, field_decl);
2515 /* struct objc_method_list *class_methods; */
2518 = build_tree_list (NULL_TREE,
2519 xref_tag (RECORD_TYPE,
2520 get_identifier (UTAG_METHOD_PROTOTYPE_LIST)));
2522 = build1 (INDIRECT_REF, NULL_TREE, get_identifier ("class_methods"));
2524 = grokfield (input_filename, lineno, field_decl, decl_specs, NULL_TREE);
2525 chainon (field_decl_chain, field_decl);
2527 return finish_struct (template, field_decl_chain, NULL_TREE);
2531 build_descriptor_table_initializer (type, entries)
2535 tree initlist = NULL_TREE;
2539 tree eltlist = NULL_TREE;
2542 = tree_cons (NULL_TREE,
2543 build_selector (METHOD_SEL_NAME (entries)), NULL_TREE);
2545 = tree_cons (NULL_TREE,
2546 add_objc_string (METHOD_ENCODING (entries),
2551 = tree_cons (NULL_TREE,
2552 build_constructor (type, nreverse (eltlist)), initlist);
2554 entries = TREE_CHAIN (entries);
2558 return build_constructor (build_array_type (type, 0), nreverse (initlist));
2561 /* struct objc_method_prototype_list {
2563 struct objc_method_prototype {
2570 build_method_prototype_list_template (list_type, size)
2574 tree objc_ivar_list_record;
2575 tree decl_specs, field_decl, field_decl_chain;
2577 /* Generate an unnamed struct definition. */
2579 objc_ivar_list_record = start_struct (RECORD_TYPE, NULL_TREE);
2581 /* int method_count; */
2583 decl_specs = build_tree_list (NULL_TREE, ridpointers[(int) RID_INT]);
2584 field_decl = get_identifier ("method_count");
2587 = grokfield (input_filename, lineno, field_decl, decl_specs, NULL_TREE);
2588 field_decl_chain = field_decl;
2590 /* struct objc_method method_list[]; */
2592 decl_specs = build_tree_list (NULL_TREE, list_type);
2593 field_decl = build_nt (ARRAY_REF, get_identifier ("method_list"),
2594 build_int_2 (size, 0));
2597 = grokfield (input_filename, lineno, field_decl, decl_specs, NULL_TREE);
2598 chainon (field_decl_chain, field_decl);
2600 finish_struct (objc_ivar_list_record, field_decl_chain, NULL_TREE);
2602 return objc_ivar_list_record;
2606 build_method_prototype_template ()
2609 tree decl_specs, field_decl, field_decl_chain;
2612 = start_struct (RECORD_TYPE, get_identifier (UTAG_METHOD_PROTOTYPE));
2614 /* struct objc_selector *_cmd; */
2615 decl_specs = tree_cons (NULL_TREE, xref_tag (RECORD_TYPE,
2616 get_identifier (TAG_SELECTOR)), NULL_TREE);
2617 field_decl = build1 (INDIRECT_REF, NULL_TREE, get_identifier ("_cmd"));
2620 = grokfield (input_filename, lineno, field_decl, decl_specs, NULL_TREE);
2621 field_decl_chain = field_decl;
2623 decl_specs = tree_cons (NULL_TREE, ridpointers[(int) RID_CHAR], NULL_TREE);
2625 = build1 (INDIRECT_REF, NULL_TREE, get_identifier ("method_types"));
2627 = grokfield (input_filename, lineno, field_decl, decl_specs, NULL_TREE);
2628 chainon (field_decl_chain, field_decl);
2630 finish_struct (proto_record, field_decl_chain, NULL_TREE);
2632 return proto_record;
2635 /* True if last call to forwarding_offset yielded a register offset. */
2636 static int offset_is_register;
2639 forwarding_offset (parm)
2642 int offset_in_bytes;
2644 if (GET_CODE (DECL_INCOMING_RTL (parm)) == MEM)
2646 rtx addr = XEXP (DECL_INCOMING_RTL (parm), 0);
2648 /* ??? Here we assume that the parm address is indexed
2649 off the frame pointer or arg pointer.
2650 If that is not true, we produce meaningless results,
2651 but do not crash. */
2652 if (GET_CODE (addr) == PLUS
2653 && GET_CODE (XEXP (addr, 1)) == CONST_INT)
2654 offset_in_bytes = INTVAL (XEXP (addr, 1));
2656 offset_in_bytes = 0;
2658 offset_in_bytes += OBJC_FORWARDING_STACK_OFFSET;
2659 offset_is_register = 0;
2661 else if (GET_CODE (DECL_INCOMING_RTL (parm)) == REG)
2663 int regno = REGNO (DECL_INCOMING_RTL (parm));
2664 offset_in_bytes = apply_args_register_offset (regno);
2665 offset_is_register = 1;
2670 /* This is the case where the parm is passed as an int or double
2671 and it is converted to a char, short or float and stored back
2672 in the parmlist. In this case, describe the parm
2673 with the variable's declared type, and adjust the address
2674 if the least significant bytes (which we are using) are not
2676 if (BYTES_BIG_ENDIAN && TREE_TYPE (parm) != DECL_ARG_TYPE (parm))
2677 offset_in_bytes += (GET_MODE_SIZE (TYPE_MODE (DECL_ARG_TYPE (parm)))
2678 - GET_MODE_SIZE (GET_MODE (DECL_RTL (parm))));
2680 return offset_in_bytes;
2684 encode_method_prototype (method_decl, func_decl)
2691 HOST_WIDE_INT max_parm_end = 0;
2695 /* ONEWAY and BYCOPY, for remote object are the only method qualifiers. */
2696 encode_type_qualifiers (TREE_PURPOSE (TREE_TYPE (method_decl)));
2699 encode_type (TREE_TYPE (TREE_TYPE (func_decl)),
2700 obstack_object_size (&util_obstack),
2701 OBJC_ENCODE_INLINE_DEFS);
2704 for (parms = DECL_ARGUMENTS (func_decl); parms;
2705 parms = TREE_CHAIN (parms))
2707 HOST_WIDE_INT parm_end = (forwarding_offset (parms)
2708 + int_size_in_bytes (TREE_TYPE (parms)));
2710 if (!offset_is_register && max_parm_end < parm_end)
2711 max_parm_end = parm_end;
2714 stack_size = max_parm_end - OBJC_FORWARDING_MIN_OFFSET;
2716 sprintf (buf, "%d", stack_size);
2717 obstack_grow (&util_obstack, buf, strlen (buf));
2719 user_args = METHOD_SEL_ARGS (method_decl);
2721 /* Argument types. */
2722 for (parms = DECL_ARGUMENTS (func_decl), i = 0; parms;
2723 parms = TREE_CHAIN (parms), i++)
2725 /* Process argument qualifiers for user supplied arguments. */
2728 encode_type_qualifiers (TREE_PURPOSE (TREE_TYPE (user_args)));
2729 user_args = TREE_CHAIN (user_args);
2733 encode_type (TREE_TYPE (parms),
2734 obstack_object_size (&util_obstack),
2735 OBJC_ENCODE_INLINE_DEFS);
2737 /* Compute offset. */
2738 sprintf (buf, "%d", forwarding_offset (parms));
2740 /* Indicate register. */
2741 if (offset_is_register)
2742 obstack_1grow (&util_obstack, '+');
2744 obstack_grow (&util_obstack, buf, strlen (buf));
2747 obstack_1grow (&util_obstack, '\0');
2748 result = get_identifier (obstack_finish (&util_obstack));
2749 obstack_free (&util_obstack, util_firstobj);
2754 generate_descriptor_table (type, name, size, list, proto)
2761 tree sc_spec, decl_specs, decl, initlist;
2763 sc_spec = tree_cons (NULL_TREE, ridpointers[(int) RID_STATIC], NULL_TREE);
2764 decl_specs = tree_cons (NULL_TREE, type, sc_spec);
2766 decl = start_decl (synth_id_with_class_suffix (name, proto),
2767 decl_specs, 1, NULL_TREE);
2768 DECL_CONTEXT (decl) = NULL_TREE;
2770 initlist = build_tree_list (NULL_TREE, build_int_2 (size, 0));
2771 initlist = tree_cons (NULL_TREE, list, initlist);
2773 finish_decl (decl, build_constructor (type, nreverse (initlist)),
2780 generate_method_descriptors (protocol)
2783 tree initlist, chain, method_list_template;
2784 tree cast, variable_length_type;
2787 if (!objc_method_prototype_template)
2788 objc_method_prototype_template = build_method_prototype_template ();
2790 cast = build_tree_list (build_tree_list (NULL_TREE, xref_tag (RECORD_TYPE,
2791 get_identifier (UTAG_METHOD_PROTOTYPE_LIST))),
2793 variable_length_type = groktypename (cast);
2795 chain = PROTOCOL_CLS_METHODS (protocol);
2798 size = list_length (chain);
2800 method_list_template
2801 = build_method_prototype_list_template (objc_method_prototype_template,
2805 = build_descriptor_table_initializer (objc_method_prototype_template,
2808 UOBJC_CLASS_METHODS_decl
2809 = generate_descriptor_table (method_list_template,
2810 "_OBJC_PROTOCOL_CLASS_METHODS",
2811 size, initlist, protocol);
2812 TREE_TYPE (UOBJC_CLASS_METHODS_decl) = variable_length_type;
2815 UOBJC_CLASS_METHODS_decl = 0;
2817 chain = PROTOCOL_NST_METHODS (protocol);
2820 size = list_length (chain);
2822 method_list_template
2823 = build_method_prototype_list_template (objc_method_prototype_template,
2826 = build_descriptor_table_initializer (objc_method_prototype_template,
2829 UOBJC_INSTANCE_METHODS_decl
2830 = generate_descriptor_table (method_list_template,
2831 "_OBJC_PROTOCOL_INSTANCE_METHODS",
2832 size, initlist, protocol);
2833 TREE_TYPE (UOBJC_INSTANCE_METHODS_decl) = variable_length_type;
2836 UOBJC_INSTANCE_METHODS_decl = 0;
2839 /* Generate a temporary FUNCTION_DECL node to be used in
2840 hack_method_prototype below. */
2843 build_tmp_function_decl ()
2845 tree decl_specs, expr_decl, parms;
2849 /* struct objc_object *objc_xxx (id, SEL, ...); */
2851 decl_specs = build_tree_list (NULL_TREE, objc_object_reference);
2852 push_parm_decl (build_tree_list
2853 (build_tree_list (decl_specs,
2854 build1 (INDIRECT_REF, NULL_TREE,
2858 decl_specs = build_tree_list (NULL_TREE, xref_tag (RECORD_TYPE,
2859 get_identifier (TAG_SELECTOR)));
2860 expr_decl = build1 (INDIRECT_REF, NULL_TREE, NULL_TREE);
2862 push_parm_decl (build_tree_list (build_tree_list (decl_specs, expr_decl),
2864 parms = get_parm_info (0);
2867 decl_specs = build_tree_list (NULL_TREE, objc_object_reference);
2868 sprintf (buffer, "__objc_tmp_%x", xxx++);
2869 expr_decl = build_nt (CALL_EXPR, get_identifier (buffer), parms, NULL_TREE);
2870 expr_decl = build1 (INDIRECT_REF, NULL_TREE, expr_decl);
2872 return define_decl (expr_decl, decl_specs);
2875 /* Generate the prototypes for protocol methods. This is used to
2876 generate method encodings for these.
2878 NST_METHODS is the method to generate a _DECL node for TMP_DECL is
2879 a decl node to be used. This is also where the return value is
2883 hack_method_prototype (nst_methods, tmp_decl)
2890 /* Hack to avoid problem with static typing of self arg. */
2891 TREE_SET_CODE (nst_methods, CLASS_METHOD_DECL);
2892 start_method_def (nst_methods);
2893 TREE_SET_CODE (nst_methods, INSTANCE_METHOD_DECL);
2895 if (METHOD_ADD_ARGS (nst_methods) == objc_ellipsis_node)
2896 parms = get_parm_info (0); /* we have a `, ...' */
2898 parms = get_parm_info (1); /* place a `void_at_end' */
2900 poplevel (0, 0, 0); /* Must be called BEFORE start_function. */
2902 /* Usually called from store_parm_decls -> init_function_start. */
2904 DECL_ARGUMENTS (tmp_decl) = TREE_PURPOSE (parms);
2906 if (current_function_decl)
2908 current_function_decl = tmp_decl;
2911 /* Code taken from start_function. */
2912 tree restype = TREE_TYPE (TREE_TYPE (tmp_decl));
2913 /* Promote the value to int before returning it. */
2914 if (TREE_CODE (restype) == INTEGER_TYPE
2915 && TYPE_PRECISION (restype) < TYPE_PRECISION (integer_type_node))
2916 restype = integer_type_node;
2917 DECL_RESULT (tmp_decl) = build_decl (RESULT_DECL, 0, restype);
2920 for (parm = DECL_ARGUMENTS (tmp_decl); parm; parm = TREE_CHAIN (parm))
2921 DECL_CONTEXT (parm) = tmp_decl;
2923 init_function_start (tmp_decl, "objc-act", 0);
2925 /* Typically called from expand_function_start for function definitions. */
2926 assign_parms (tmp_decl);
2928 /* install return type */
2929 TREE_TYPE (TREE_TYPE (tmp_decl)) = groktypename (TREE_TYPE (nst_methods));
2931 current_function_decl = NULL;
2935 generate_protocol_references (plist)
2940 /* Forward declare protocols referenced. */
2941 for (lproto = plist; lproto; lproto = TREE_CHAIN (lproto))
2943 tree proto = TREE_VALUE (lproto);
2945 if (TREE_CODE (proto) == PROTOCOL_INTERFACE_TYPE
2946 && PROTOCOL_NAME (proto))
2948 if (! PROTOCOL_FORWARD_DECL (proto))
2949 build_protocol_reference (proto);
2951 if (PROTOCOL_LIST (proto))
2952 generate_protocol_references (PROTOCOL_LIST (proto));
2958 generate_protocols ()
2960 tree p, tmp_decl, encoding;
2961 tree sc_spec, decl_specs, decl;
2962 tree initlist, protocol_name_expr, refs_decl, refs_expr;
2965 tmp_decl = build_tmp_function_decl ();
2967 if (! objc_protocol_template)
2968 objc_protocol_template = build_protocol_template ();
2970 /* If a protocol was directly referenced, pull in indirect references. */
2971 for (p = protocol_chain; p; p = TREE_CHAIN (p))
2972 if (PROTOCOL_FORWARD_DECL (p) && PROTOCOL_LIST (p))
2973 generate_protocol_references (PROTOCOL_LIST (p));
2975 for (p = protocol_chain; p; p = TREE_CHAIN (p))
2977 tree nst_methods = PROTOCOL_NST_METHODS (p);
2978 tree cls_methods = PROTOCOL_CLS_METHODS (p);
2980 /* If protocol wasn't referenced, don't generate any code. */
2981 if (! PROTOCOL_FORWARD_DECL (p))
2984 /* Make sure we link in the Protocol class. */
2985 add_class_reference (get_identifier (PROTOCOL_OBJECT_CLASS_NAME));
2989 if (! METHOD_ENCODING (nst_methods))
2991 hack_method_prototype (nst_methods, tmp_decl);
2992 encoding = encode_method_prototype (nst_methods, tmp_decl);
2993 METHOD_ENCODING (nst_methods) = encoding;
2995 nst_methods = TREE_CHAIN (nst_methods);
3000 if (! METHOD_ENCODING (cls_methods))
3002 hack_method_prototype (cls_methods, tmp_decl);
3003 encoding = encode_method_prototype (cls_methods, tmp_decl);
3004 METHOD_ENCODING (cls_methods) = encoding;
3007 cls_methods = TREE_CHAIN (cls_methods);
3009 generate_method_descriptors (p);
3011 if (PROTOCOL_LIST (p))
3012 refs_decl = generate_protocol_list (p);
3016 /* static struct objc_protocol _OBJC_PROTOCOL_<mumble>; */
3018 sc_spec = tree_cons (NULL_TREE, ridpointers[(int) RID_STATIC],
3020 decl_specs = tree_cons (NULL_TREE, objc_protocol_template, sc_spec);
3022 decl = start_decl (synth_id_with_class_suffix ("_OBJC_PROTOCOL", p),
3023 decl_specs, 1, NULL_TREE);
3025 DECL_CONTEXT (decl) = NULL_TREE;
3027 protocol_name_expr = add_objc_string (PROTOCOL_NAME (p), class_names);
3033 (build_tree_list (build_tree_list (NULL_TREE,
3034 objc_protocol_template),
3035 build1 (INDIRECT_REF, NULL_TREE,
3036 build1 (INDIRECT_REF, NULL_TREE,
3039 refs_expr = build_unary_op (ADDR_EXPR, refs_decl, 0);
3040 TREE_TYPE (refs_expr) = cast_type2;
3043 refs_expr = build_int_2 (0, 0);
3045 /* UOBJC_INSTANCE_METHODS_decl/UOBJC_CLASS_METHODS_decl are set
3046 by generate_method_descriptors, which is called above. */
3047 initlist = build_protocol_initializer (TREE_TYPE (decl),
3048 protocol_name_expr, refs_expr,
3049 UOBJC_INSTANCE_METHODS_decl,
3050 UOBJC_CLASS_METHODS_decl);
3051 finish_decl (decl, initlist, NULL_TREE);
3053 /* Mark the decl as used to avoid "defined but not used" warning. */
3054 TREE_USED (decl) = 1;
3059 build_protocol_initializer (type, protocol_name, protocol_list,
3060 instance_methods, class_methods)
3064 tree instance_methods;
3067 tree initlist = NULL_TREE, expr;
3070 cast_type = groktypename
3072 (build_tree_list (NULL_TREE,
3073 xref_tag (RECORD_TYPE,
3074 get_identifier (UTAG_CLASS))),
3075 build1 (INDIRECT_REF, NULL_TREE, NULL_TREE)));
3077 /* Filling the "isa" in with one allows the runtime system to
3078 detect that the version change...should remove before final release. */
3080 expr = build_int_2 (PROTOCOL_VERSION, 0);
3081 TREE_TYPE (expr) = cast_type;
3082 initlist = tree_cons (NULL_TREE, expr, initlist);
3083 initlist = tree_cons (NULL_TREE, protocol_name, initlist);
3084 initlist = tree_cons (NULL_TREE, protocol_list, initlist);
3086 if (!instance_methods)
3087 initlist = tree_cons (NULL_TREE, build_int_2 (0, 0), initlist);
3090 expr = build_unary_op (ADDR_EXPR, instance_methods, 0);
3091 initlist = tree_cons (NULL_TREE, expr, initlist);
3095 initlist = tree_cons (NULL_TREE, build_int_2 (0, 0), initlist);
3098 expr = build_unary_op (ADDR_EXPR, class_methods, 0);
3099 initlist = tree_cons (NULL_TREE, expr, initlist);
3102 return build_constructor (type, nreverse (initlist));
3105 /* struct objc_category {
3106 char *category_name;
3108 struct objc_method_list *instance_methods;
3109 struct objc_method_list *class_methods;
3110 struct objc_protocol_list *protocols;
3114 build_category_template ()
3116 tree decl_specs, field_decl, field_decl_chain;
3118 objc_category_template = start_struct (RECORD_TYPE,
3119 get_identifier (UTAG_CATEGORY));
3120 /* char *category_name; */
3122 decl_specs = build_tree_list (NULL_TREE, ridpointers[(int) RID_CHAR]);
3124 = build1 (INDIRECT_REF, NULL_TREE, get_identifier ("category_name"));
3126 = grokfield (input_filename, lineno, field_decl, decl_specs, NULL_TREE);
3127 field_decl_chain = field_decl;
3129 /* char *class_name; */
3131 decl_specs = build_tree_list (NULL_TREE, ridpointers[(int) RID_CHAR]);
3132 field_decl = build1 (INDIRECT_REF, NULL_TREE, get_identifier ("class_name"));
3134 = grokfield (input_filename, lineno, field_decl, decl_specs, NULL_TREE);
3135 chainon (field_decl_chain, field_decl);
3137 /* struct objc_method_list *instance_methods; */
3139 decl_specs = build_tree_list (NULL_TREE,
3140 xref_tag (RECORD_TYPE,
3141 get_identifier (UTAG_METHOD_LIST)));
3143 = build1 (INDIRECT_REF, NULL_TREE, get_identifier ("instance_methods"));
3145 = grokfield (input_filename, lineno, field_decl, decl_specs, NULL_TREE);
3146 chainon (field_decl_chain, field_decl);
3148 /* struct objc_method_list *class_methods; */
3150 decl_specs = build_tree_list (NULL_TREE,
3151 xref_tag (RECORD_TYPE,
3152 get_identifier (UTAG_METHOD_LIST)));
3154 = build1 (INDIRECT_REF, NULL_TREE, get_identifier ("class_methods"));
3156 = grokfield (input_filename, lineno, field_decl, decl_specs, NULL_TREE);
3157 chainon (field_decl_chain, field_decl);
3159 /* struct objc_protocol **protocol_list; */
3161 decl_specs = build_tree_list (NULL_TREE,
3162 xref_tag (RECORD_TYPE,
3163 get_identifier (UTAG_PROTOCOL)));
3165 = build1 (INDIRECT_REF, NULL_TREE, get_identifier ("protocol_list"));
3166 field_decl = build1 (INDIRECT_REF, NULL_TREE, field_decl);
3168 = grokfield (input_filename, lineno, field_decl, decl_specs, NULL_TREE);
3169 chainon (field_decl_chain, field_decl);
3171 finish_struct (objc_category_template, field_decl_chain, NULL_TREE);
3174 /* struct objc_selector {
3180 build_selector_template ()
3183 tree decl_specs, field_decl, field_decl_chain;
3185 objc_selector_template
3186 = start_struct (RECORD_TYPE, get_identifier (UTAG_SELECTOR));
3190 decl_specs = build_tree_list (NULL_TREE, ridpointers[(int) RID_VOID]);
3191 field_decl = build1 (INDIRECT_REF, NULL_TREE, get_identifier ("sel_id"));
3193 = grokfield (input_filename, lineno, field_decl, decl_specs, NULL_TREE);
3194 field_decl_chain = field_decl;
3196 /* char *sel_type; */
3198 decl_specs = build_tree_list (NULL_TREE, ridpointers[(int) RID_CHAR]);
3199 field_decl = build1 (INDIRECT_REF, NULL_TREE, get_identifier ("sel_type"));
3201 = grokfield (input_filename, lineno, field_decl, decl_specs, NULL_TREE);
3202 chainon (field_decl_chain, field_decl);
3204 finish_struct (objc_selector_template, field_decl_chain, NULL_TREE);
3207 /* struct objc_class {
3208 struct objc_class *isa;
3209 struct objc_class *super_class;
3214 struct objc_ivar_list *ivars;
3215 struct objc_method_list *methods;
3216 if (flag_next_runtime)
3217 struct objc_cache *cache;
3219 struct sarray *dtable;
3220 struct objc_class *subclass_list;
3221 struct objc_class *sibling_class;
3223 struct objc_protocol_list *protocols;
3224 void *gc_object_type;
3228 build_class_template ()
3230 tree decl_specs, field_decl, field_decl_chain;
3233 = start_struct (RECORD_TYPE, get_identifier (UTAG_CLASS));
3235 /* struct objc_class *isa; */
3237 decl_specs = build_tree_list (NULL_TREE, objc_class_template);
3238 field_decl = build1 (INDIRECT_REF, NULL_TREE, get_identifier ("isa"));
3240 = grokfield (input_filename, lineno, field_decl, decl_specs, NULL_TREE);
3241 field_decl_chain = field_decl;
3243 /* struct objc_class *super_class; */
3245 decl_specs = build_tree_list (NULL_TREE, objc_class_template);
3247 = build1 (INDIRECT_REF, NULL_TREE, get_identifier ("super_class"));
3249 = grokfield (input_filename, lineno, field_decl, decl_specs, NULL_TREE);
3250 chainon (field_decl_chain, field_decl);
3254 decl_specs = build_tree_list (NULL_TREE, ridpointers[(int) RID_CHAR]);
3255 field_decl = build1 (INDIRECT_REF, NULL_TREE, get_identifier ("name"));
3257 = grokfield (input_filename, lineno, field_decl, decl_specs, NULL_TREE);
3258 chainon (field_decl_chain, field_decl);
3262 decl_specs = build_tree_list (NULL_TREE, ridpointers[(int) RID_LONG]);
3263 field_decl = get_identifier ("version");
3265 = grokfield (input_filename, lineno, field_decl, decl_specs, NULL_TREE);
3266 chainon (field_decl_chain, field_decl);
3270 decl_specs = build_tree_list (NULL_TREE, ridpointers[(int) RID_LONG]);
3271 field_decl = get_identifier ("info");
3273 = grokfield (input_filename, lineno, field_decl, decl_specs, NULL_TREE);
3274 chainon (field_decl_chain, field_decl);
3276 /* long instance_size; */
3278 decl_specs = build_tree_list (NULL_TREE, ridpointers[(int) RID_LONG]);
3279 field_decl = get_identifier ("instance_size");
3281 = grokfield (input_filename, lineno, field_decl, decl_specs, NULL_TREE);
3282 chainon (field_decl_chain, field_decl);
3284 /* struct objc_ivar_list *ivars; */
3286 decl_specs = build_tree_list (NULL_TREE,
3287 xref_tag (RECORD_TYPE,
3288 get_identifier (UTAG_IVAR_LIST)));
3289 field_decl = build1 (INDIRECT_REF, NULL_TREE, get_identifier ("ivars"));
3291 = grokfield (input_filename, lineno, field_decl, decl_specs, NULL_TREE);
3292 chainon (field_decl_chain, field_decl);
3294 /* struct objc_method_list *methods; */
3296 decl_specs = build_tree_list (NULL_TREE,
3297 xref_tag (RECORD_TYPE,
3298 get_identifier (UTAG_METHOD_LIST)));
3299 field_decl = build1 (INDIRECT_REF, NULL_TREE, get_identifier ("methods"));
3301 = grokfield (input_filename, lineno, field_decl, decl_specs, NULL_TREE);
3302 chainon (field_decl_chain, field_decl);
3304 if (flag_next_runtime)
3306 /* struct objc_cache *cache; */
3308 decl_specs = build_tree_list (NULL_TREE,
3309 xref_tag (RECORD_TYPE,
3310 get_identifier ("objc_cache")));
3311 field_decl = build1 (INDIRECT_REF, NULL_TREE, get_identifier ("cache"));
3312 field_decl = grokfield (input_filename, lineno, field_decl,
3313 decl_specs, NULL_TREE);
3314 chainon (field_decl_chain, field_decl);
3318 /* struct sarray *dtable; */
3320 decl_specs = build_tree_list (NULL_TREE,
3321 xref_tag (RECORD_TYPE,
3322 get_identifier ("sarray")));
3323 field_decl = build1 (INDIRECT_REF, NULL_TREE, get_identifier ("dtable"));
3324 field_decl = grokfield (input_filename, lineno, field_decl,
3325 decl_specs, NULL_TREE);
3326 chainon (field_decl_chain, field_decl);
3328 /* struct objc_class *subclass_list; */
3330 decl_specs = build_tree_list (NULL_TREE, objc_class_template);
3332 = build1 (INDIRECT_REF, NULL_TREE, get_identifier ("subclass_list"));
3333 field_decl = grokfield (input_filename, lineno, field_decl,
3334 decl_specs, NULL_TREE);
3335 chainon (field_decl_chain, field_decl);
3337 /* struct objc_class *sibling_class; */
3339 decl_specs = build_tree_list (NULL_TREE, objc_class_template);
3341 = build1 (INDIRECT_REF, NULL_TREE, get_identifier ("sibling_class"));
3342 field_decl = grokfield (input_filename, lineno, field_decl,
3343 decl_specs, NULL_TREE);
3344 chainon (field_decl_chain, field_decl);
3347 /* struct objc_protocol **protocol_list; */
3349 decl_specs = build_tree_list (NULL_TREE,
3350 xref_tag (RECORD_TYPE,
3351 get_identifier (UTAG_PROTOCOL)));
3353 = build1 (INDIRECT_REF, NULL_TREE, get_identifier ("protocol_list"));
3355 = build1 (INDIRECT_REF, NULL_TREE, field_decl);
3356 field_decl = grokfield (input_filename, lineno, field_decl,
3357 decl_specs, NULL_TREE);
3358 chainon (field_decl_chain, field_decl);
3362 decl_specs = build_tree_list (NULL_TREE, ridpointers[(int) RID_VOID]);
3363 field_decl = build1 (INDIRECT_REF, NULL_TREE, get_identifier ("sel_id"));
3365 = grokfield (input_filename, lineno, field_decl, decl_specs, NULL_TREE);
3366 chainon (field_decl_chain, field_decl);
3368 /* void *gc_object_type; */
3370 decl_specs = build_tree_list (NULL_TREE, ridpointers[(int) RID_VOID]);
3371 field_decl = build1 (INDIRECT_REF, NULL_TREE, get_identifier ("gc_object_type"));
3373 = grokfield (input_filename, lineno, field_decl, decl_specs, NULL_TREE);
3374 chainon (field_decl_chain, field_decl);
3376 finish_struct (objc_class_template, field_decl_chain, NULL_TREE);
3379 /* Generate appropriate forward declarations for an implementation. */
3382 synth_forward_declarations ()
3384 tree sc_spec, decl_specs, an_id;
3386 /* extern struct objc_class _OBJC_CLASS_<my_name>; */
3388 an_id = synth_id_with_class_suffix ("_OBJC_CLASS", objc_implementation_context);
3390 sc_spec = build_tree_list (NULL_TREE, ridpointers[(int) RID_EXTERN]);
3391 decl_specs = tree_cons (NULL_TREE, objc_class_template, sc_spec);
3392 UOBJC_CLASS_decl = define_decl (an_id, decl_specs);
3393 TREE_USED (UOBJC_CLASS_decl) = 1;
3394 DECL_ARTIFICIAL (UOBJC_CLASS_decl) = 1;
3396 /* extern struct objc_class _OBJC_METACLASS_<my_name>; */
3398 an_id = synth_id_with_class_suffix ("_OBJC_METACLASS",
3399 objc_implementation_context);
3401 UOBJC_METACLASS_decl = define_decl (an_id, decl_specs);
3402 TREE_USED (UOBJC_METACLASS_decl) = 1;
3403 DECL_ARTIFICIAL(UOBJC_METACLASS_decl) = 1;
3405 /* Pre-build the following entities - for speed/convenience. */
3407 an_id = get_identifier ("super_class");
3408 ucls_super_ref = build_component_ref (UOBJC_CLASS_decl, an_id);
3409 uucls_super_ref = build_component_ref (UOBJC_METACLASS_decl, an_id);
3413 error_with_ivar (message, decl, rawdecl)
3414 const char *message;
3420 report_error_function (DECL_SOURCE_FILE (decl));
3422 error_with_file_and_line (DECL_SOURCE_FILE (decl),
3423 DECL_SOURCE_LINE (decl),
3425 message, gen_declaration (rawdecl, errbuf));
3429 #define USERTYPE(t) \
3430 (TREE_CODE (t) == RECORD_TYPE || TREE_CODE (t) == UNION_TYPE \
3431 || TREE_CODE (t) == ENUMERAL_TYPE)
3434 check_ivars (inter, imp)
3438 tree intdecls = CLASS_IVARS (inter);
3439 tree impdecls = CLASS_IVARS (imp);
3440 tree rawintdecls = CLASS_RAW_IVARS (inter);
3441 tree rawimpdecls = CLASS_RAW_IVARS (imp);
3447 if (intdecls == 0 && impdecls == 0)
3449 if (intdecls == 0 || impdecls == 0)
3451 error ("inconsistent instance variable specification");
3455 t1 = TREE_TYPE (intdecls); t2 = TREE_TYPE (impdecls);
3457 if (!comptypes (t1, t2))
3459 if (DECL_NAME (intdecls) == DECL_NAME (impdecls))
3461 error_with_ivar ("conflicting instance variable type",
3462 impdecls, rawimpdecls);
3463 error_with_ivar ("previous declaration of",
3464 intdecls, rawintdecls);
3466 else /* both the type and the name don't match */
3468 error ("inconsistent instance variable specification");
3473 else if (DECL_NAME (intdecls) != DECL_NAME (impdecls))
3475 error_with_ivar ("conflicting instance variable name",
3476 impdecls, rawimpdecls);
3477 error_with_ivar ("previous declaration of",
3478 intdecls, rawintdecls);
3481 intdecls = TREE_CHAIN (intdecls);
3482 impdecls = TREE_CHAIN (impdecls);
3483 rawintdecls = TREE_CHAIN (rawintdecls);
3484 rawimpdecls = TREE_CHAIN (rawimpdecls);
3488 /* Set super_type to the data type node for struct objc_super *,
3489 first defining struct objc_super itself.
3490 This needs to be done just once per compilation. */
3493 build_super_template ()
3495 tree record, decl_specs, field_decl, field_decl_chain;
3497 record = start_struct (RECORD_TYPE, get_identifier (UTAG_SUPER));
3499 /* struct objc_object *self; */
3501 decl_specs = build_tree_list (NULL_TREE, objc_object_reference);
3502 field_decl = get_identifier ("self");
3503 field_decl = build1 (INDIRECT_REF, NULL_TREE, field_decl);
3504 field_decl = grokfield (input_filename, lineno,
3505 field_decl, decl_specs, NULL_TREE);
3506 field_decl_chain = field_decl;
3508 /* struct objc_class *class; */
3510 decl_specs = get_identifier (UTAG_CLASS);
3511 decl_specs = build_tree_list (NULL_TREE, xref_tag (RECORD_TYPE, decl_specs));
3512 field_decl = build1 (INDIRECT_REF, NULL_TREE, get_identifier ("class"));
3514 field_decl = grokfield (input_filename, lineno,
3515 field_decl, decl_specs, NULL_TREE);
3516 chainon (field_decl_chain, field_decl);
3518 finish_struct (record, field_decl_chain, NULL_TREE);
3520 /* `struct objc_super *' */
3521 super_type = groktypename (build_tree_list (build_tree_list (NULL_TREE,
3523 build1 (INDIRECT_REF,
3524 NULL_TREE, NULL_TREE)));
3528 /* struct objc_ivar {
3535 build_ivar_template ()
3537 tree objc_ivar_id, objc_ivar_record;
3538 tree decl_specs, field_decl, field_decl_chain;
3540 objc_ivar_id = get_identifier (UTAG_IVAR);
3541 objc_ivar_record = start_struct (RECORD_TYPE, objc_ivar_id);
3543 /* char *ivar_name; */
3545 decl_specs = build_tree_list (NULL_TREE, ridpointers[(int) RID_CHAR]);
3546 field_decl = build1 (INDIRECT_REF, NULL_TREE, get_identifier ("ivar_name"));
3548 field_decl = grokfield (input_filename, lineno, field_decl,
3549 decl_specs, NULL_TREE);
3550 field_decl_chain = field_decl;
3552 /* char *ivar_type; */
3554 decl_specs = build_tree_list (NULL_TREE, ridpointers[(int) RID_CHAR]);
3555 field_decl = build1 (INDIRECT_REF, NULL_TREE, get_identifier ("ivar_type"));
3557 field_decl = grokfield (input_filename, lineno, field_decl,
3558 decl_specs, NULL_TREE);
3559 chainon (field_decl_chain, field_decl);
3561 /* int ivar_offset; */
3563 decl_specs = build_tree_list (NULL_TREE, ridpointers[(int) RID_INT]);
3564 field_decl = get_identifier ("ivar_offset");
3566 field_decl = grokfield (input_filename, lineno, field_decl,
3567 decl_specs, NULL_TREE);
3568 chainon (field_decl_chain, field_decl);
3570 finish_struct (objc_ivar_record, field_decl_chain, NULL_TREE);
3572 return objc_ivar_record;
3577 struct objc_ivar ivar_list[ivar_count];
3581 build_ivar_list_template (list_type, size)
3585 tree objc_ivar_list_record;
3586 tree decl_specs, field_decl, field_decl_chain;
3588 objc_ivar_list_record = start_struct (RECORD_TYPE, NULL_TREE);
3590 /* int ivar_count; */
3592 decl_specs = build_tree_list (NULL_TREE, ridpointers[(int) RID_INT]);
3593 field_decl = get_identifier ("ivar_count");
3595 field_decl = grokfield (input_filename, lineno, field_decl,
3596 decl_specs, NULL_TREE);
3597 field_decl_chain = field_decl;
3599 /* struct objc_ivar ivar_list[]; */
3601 decl_specs = build_tree_list (NULL_TREE, list_type);
3602 field_decl = build_nt (ARRAY_REF, get_identifier ("ivar_list"),
3603 build_int_2 (size, 0));
3605 field_decl = grokfield (input_filename, lineno,
3606 field_decl, decl_specs, NULL_TREE);
3607 chainon (field_decl_chain, field_decl);
3609 finish_struct (objc_ivar_list_record, field_decl_chain, NULL_TREE);
3611 return objc_ivar_list_record;
3617 struct objc_method method_list[method_count];
3621 build_method_list_template (list_type, size)
3625 tree objc_ivar_list_record;
3626 tree decl_specs, field_decl, field_decl_chain;
3628 objc_ivar_list_record = start_struct (RECORD_TYPE, NULL_TREE);
3630 /* int method_next; */
3635 xref_tag (RECORD_TYPE,
3636 get_identifier (UTAG_METHOD_PROTOTYPE_LIST)));
3638 = build1 (INDIRECT_REF, NULL_TREE, get_identifier ("method_next"));
3639 field_decl = grokfield (input_filename, lineno, field_decl,
3640 decl_specs, NULL_TREE);
3641 field_decl_chain = field_decl;
3643 /* int method_count; */
3645 decl_specs = build_tree_list (NULL_TREE, ridpointers[(int) RID_INT]);
3646 field_decl = get_identifier ("method_count");
3648 field_decl = grokfield (input_filename, lineno,
3649 field_decl, decl_specs, NULL_TREE);
3650 chainon (field_decl_chain, field_decl);
3652 /* struct objc_method method_list[]; */
3654 decl_specs = build_tree_list (NULL_TREE, list_type);
3655 field_decl = build_nt (ARRAY_REF, get_identifier ("method_list"),
3656 build_int_2 (size, 0));
3658 field_decl = grokfield (input_filename, lineno,
3659 field_decl, decl_specs, NULL_TREE);
3660 chainon (field_decl_chain, field_decl);
3662 finish_struct (objc_ivar_list_record, field_decl_chain, NULL_TREE);
3664 return objc_ivar_list_record;
3668 build_ivar_list_initializer (type, field_decl)
3672 tree initlist = NULL_TREE;
3676 tree ivar = NULL_TREE;
3679 if (DECL_NAME (field_decl))
3680 ivar = tree_cons (NULL_TREE,
3681 add_objc_string (DECL_NAME (field_decl),
3685 /* Unnamed bit-field ivar (yuck). */
3686 ivar = tree_cons (NULL_TREE, build_int_2 (0, 0), ivar);
3689 encode_field_decl (field_decl,
3690 obstack_object_size (&util_obstack),
3691 OBJC_ENCODE_DONT_INLINE_DEFS);
3693 /* Null terminate string. */
3694 obstack_1grow (&util_obstack, 0);
3698 add_objc_string (get_identifier (obstack_finish (&util_obstack)),
3701 obstack_free (&util_obstack, util_firstobj);
3704 ivar = tree_cons (NULL_TREE, byte_position (field_decl), ivar);
3705 initlist = tree_cons (NULL_TREE,
3706 build_constructor (type, nreverse (ivar)),
3709 field_decl = TREE_CHAIN (field_decl);
3713 return build_constructor (build_array_type (type, 0), nreverse (initlist));
3717 generate_ivars_list (type, name, size, list)
3723 tree sc_spec, decl_specs, decl, initlist;
3725 sc_spec = tree_cons (NULL_TREE, ridpointers[(int) RID_STATIC], NULL_TREE);
3726 decl_specs = tree_cons (NULL_TREE, type, sc_spec);
3728 decl = start_decl (synth_id_with_class_suffix (name, objc_implementation_context),
3729 decl_specs, 1, NULL_TREE);
3731 initlist = build_tree_list (NULL_TREE, build_int_2 (size, 0));
3732 initlist = tree_cons (NULL_TREE, list, initlist);
3735 build_constructor (TREE_TYPE (decl), nreverse (initlist)),
3742 generate_ivar_lists ()
3744 tree initlist, ivar_list_template, chain;
3745 tree cast, variable_length_type;
3748 generating_instance_variables = 1;
3750 if (!objc_ivar_template)
3751 objc_ivar_template = build_ivar_template ();
3755 (build_tree_list (NULL_TREE, xref_tag (RECORD_TYPE,
3756 get_identifier (UTAG_IVAR_LIST))),
3758 variable_length_type = groktypename (cast);
3760 /* Only generate class variables for the root of the inheritance
3761 hierarchy since these will be the same for every class. */
3763 if (CLASS_SUPER_NAME (implementation_template) == NULL_TREE
3764 && (chain = TYPE_FIELDS (objc_class_template)))
3766 size = list_length (chain);
3768 ivar_list_template = build_ivar_list_template (objc_ivar_template, size);
3769 initlist = build_ivar_list_initializer (objc_ivar_template, chain);
3771 UOBJC_CLASS_VARIABLES_decl
3772 = generate_ivars_list (ivar_list_template, "_OBJC_CLASS_VARIABLES",
3774 TREE_TYPE (UOBJC_CLASS_VARIABLES_decl) = variable_length_type;
3777 UOBJC_CLASS_VARIABLES_decl = 0;
3779 chain = CLASS_IVARS (implementation_template);
3782 size = list_length (chain);
3783 ivar_list_template = build_ivar_list_template (objc_ivar_template, size);
3784 initlist = build_ivar_list_initializer (objc_ivar_template, chain);
3786 UOBJC_INSTANCE_VARIABLES_decl
3787 = generate_ivars_list (ivar_list_template, "_OBJC_INSTANCE_VARIABLES",
3789 TREE_TYPE (UOBJC_INSTANCE_VARIABLES_decl) = variable_length_type;
3792 UOBJC_INSTANCE_VARIABLES_decl = 0;
3794 generating_instance_variables = 0;
3798 build_dispatch_table_initializer (type, entries)
3802 tree initlist = NULL_TREE;
3806 tree elemlist = NULL_TREE;
3808 elemlist = tree_cons (NULL_TREE,
3809 build_selector (METHOD_SEL_NAME (entries)),
3812 /* Generate the method encoding if we don't have one already. */
3813 if (! METHOD_ENCODING (entries))
3814 METHOD_ENCODING (entries) =
3815 encode_method_def (METHOD_DEFINITION (entries));
3817 elemlist = tree_cons (NULL_TREE,
3818 add_objc_string (METHOD_ENCODING (entries),
3822 elemlist = tree_cons (NULL_TREE,
3823 build_unary_op (ADDR_EXPR,
3824 METHOD_DEFINITION (entries), 1),
3827 initlist = tree_cons (NULL_TREE,
3828 build_constructor (type, nreverse (elemlist)),
3831 entries = TREE_CHAIN (entries);
3835 return build_constructor (build_array_type (type, 0), nreverse (initlist));
3838 /* To accomplish method prototyping without generating all kinds of
3839 inane warnings, the definition of the dispatch table entries were
3842 struct objc_method { SEL _cmd; ...; id (*_imp)(); };
3844 struct objc_method { SEL _cmd; ...; void *_imp; }; */
3847 build_method_template ()
3850 tree decl_specs, field_decl, field_decl_chain;
3852 _SLT_record = start_struct (RECORD_TYPE, get_identifier (UTAG_METHOD));
3854 /* struct objc_selector *_cmd; */
3855 decl_specs = tree_cons (NULL_TREE,
3856 xref_tag (RECORD_TYPE,
3857 get_identifier (TAG_SELECTOR)),
3859 field_decl = build1 (INDIRECT_REF, NULL_TREE, get_identifier ("_cmd"));
3861 field_decl = grokfield (input_filename, lineno, field_decl,
3862 decl_specs, NULL_TREE);
3863 field_decl_chain = field_decl;
3865 decl_specs = tree_cons (NULL_TREE, ridpointers[(int) RID_CHAR], NULL_TREE);
3866 field_decl = build1 (INDIRECT_REF, NULL_TREE,
3867 get_identifier ("method_types"));
3868 field_decl = grokfield (input_filename, lineno, field_decl,
3869 decl_specs, NULL_TREE);
3870 chainon (field_decl_chain, field_decl);
3874 decl_specs = tree_cons (NULL_TREE, ridpointers[(int) RID_VOID], NULL_TREE);
3875 field_decl = build1 (INDIRECT_REF, NULL_TREE, get_identifier ("_imp"));
3876 field_decl = grokfield (input_filename, lineno, field_decl,
3877 decl_specs, NULL_TREE);
3878 chainon (field_decl_chain, field_decl);
3880 finish_struct (_SLT_record, field_decl_chain, NULL_TREE);
3887 generate_dispatch_table (type, name, size, list)
3893 tree sc_spec, decl_specs, decl, initlist;
3895 sc_spec = tree_cons (NULL_TREE, ridpointers[(int) RID_STATIC], NULL_TREE);
3896 decl_specs = tree_cons (NULL_TREE, type, sc_spec);
3898 decl = start_decl (synth_id_with_class_suffix (name, objc_implementation_context),
3899 decl_specs, 1, NULL_TREE);
3901 initlist = build_tree_list (NULL_TREE, build_int_2 (0, 0));
3902 initlist = tree_cons (NULL_TREE, build_int_2 (size, 0), initlist);
3903 initlist = tree_cons (NULL_TREE, list, initlist);
3906 build_constructor (TREE_TYPE (decl), nreverse (initlist)),
3913 generate_dispatch_tables ()
3915 tree initlist, chain, method_list_template;
3916 tree cast, variable_length_type;
3919 if (!objc_method_template)
3920 objc_method_template = build_method_template ();
3924 (build_tree_list (NULL_TREE,
3925 xref_tag (RECORD_TYPE,
3926 get_identifier (UTAG_METHOD_LIST))),
3929 variable_length_type = groktypename (cast);
3931 chain = CLASS_CLS_METHODS (objc_implementation_context);
3934 size = list_length (chain);
3936 method_list_template
3937 = build_method_list_template (objc_method_template, size);
3939 = build_dispatch_table_initializer (objc_method_template, chain);
3941 UOBJC_CLASS_METHODS_decl
3942 = generate_dispatch_table (method_list_template,
3943 ((TREE_CODE (objc_implementation_context)
3944 == CLASS_IMPLEMENTATION_TYPE)
3945 ? "_OBJC_CLASS_METHODS"
3946 : "_OBJC_CATEGORY_CLASS_METHODS"),
3948 TREE_TYPE (UOBJC_CLASS_METHODS_decl) = variable_length_type;
3951 UOBJC_CLASS_METHODS_decl = 0;
3953 chain = CLASS_NST_METHODS (objc_implementation_context);
3956 size = list_length (chain);
3958 method_list_template
3959 = build_method_list_template (objc_method_template, size);
3961 = build_dispatch_table_initializer (objc_method_template, chain);
3963 if (TREE_CODE (objc_implementation_context) == CLASS_IMPLEMENTATION_TYPE)
3964 UOBJC_INSTANCE_METHODS_decl
3965 = generate_dispatch_table (method_list_template,
3966 "_OBJC_INSTANCE_METHODS",
3969 /* We have a category. */
3970 UOBJC_INSTANCE_METHODS_decl
3971 = generate_dispatch_table (method_list_template,
3972 "_OBJC_CATEGORY_INSTANCE_METHODS",
3974 TREE_TYPE (UOBJC_INSTANCE_METHODS_decl) = variable_length_type;
3977 UOBJC_INSTANCE_METHODS_decl = 0;
3981 generate_protocol_list (i_or_p)
3984 tree initlist, decl_specs, sc_spec;
3985 tree refs_decl, expr_decl, lproto, e, plist;
3989 if (TREE_CODE (i_or_p) == CLASS_INTERFACE_TYPE
3990 || TREE_CODE (i_or_p) == CATEGORY_INTERFACE_TYPE)
3991 plist = CLASS_PROTOCOL_LIST (i_or_p);
3992 else if (TREE_CODE (i_or_p) == PROTOCOL_INTERFACE_TYPE)
3993 plist = PROTOCOL_LIST (i_or_p);
3997 cast_type = groktypename
3999 (build_tree_list (NULL_TREE,
4000 xref_tag (RECORD_TYPE,
4001 get_identifier (UTAG_PROTOCOL))),
4002 build1 (INDIRECT_REF, NULL_TREE, NULL_TREE)));
4005 for (lproto = plist; lproto; lproto = TREE_CHAIN (lproto))
4006 if (TREE_CODE (TREE_VALUE (lproto)) == PROTOCOL_INTERFACE_TYPE
4007 && PROTOCOL_FORWARD_DECL (TREE_VALUE (lproto)))
4010 /* Build initializer. */
4011 initlist = tree_cons (NULL_TREE, build_int_2 (0, 0), NULL_TREE);
4013 e = build_int_2 (size, 0);
4014 TREE_TYPE (e) = cast_type;
4015 initlist = tree_cons (NULL_TREE, e, initlist);
4017 for (lproto = plist; lproto; lproto = TREE_CHAIN (lproto))
4019 tree pval = TREE_VALUE (lproto);
4021 if (TREE_CODE (pval) == PROTOCOL_INTERFACE_TYPE
4022 && PROTOCOL_FORWARD_DECL (pval))
4024 e = build_unary_op (ADDR_EXPR, PROTOCOL_FORWARD_DECL (pval), 0);
4025 initlist = tree_cons (NULL_TREE, e, initlist);
4029 /* static struct objc_protocol *refs[n]; */
4031 sc_spec = tree_cons (NULL_TREE, ridpointers[(int) RID_STATIC], NULL_TREE);
4032 decl_specs = tree_cons (NULL_TREE, xref_tag (RECORD_TYPE,
4033 get_identifier (UTAG_PROTOCOL)),
4036 if (TREE_CODE (i_or_p) == PROTOCOL_INTERFACE_TYPE)
4037 expr_decl = build_nt (ARRAY_REF,
4038 synth_id_with_class_suffix ("_OBJC_PROTOCOL_REFS",
4040 build_int_2 (size + 2, 0));
4041 else if (TREE_CODE (i_or_p) == CLASS_INTERFACE_TYPE)
4042 expr_decl = build_nt (ARRAY_REF,
4043 synth_id_with_class_suffix ("_OBJC_CLASS_PROTOCOLS",
4045 build_int_2 (size + 2, 0));
4046 else if (TREE_CODE (i_or_p) == CATEGORY_INTERFACE_TYPE)
4048 = build_nt (ARRAY_REF,
4049 synth_id_with_class_suffix ("_OBJC_CATEGORY_PROTOCOLS",
4051 build_int_2 (size + 2, 0));
4055 expr_decl = build1 (INDIRECT_REF, NULL_TREE, expr_decl);
4057 refs_decl = start_decl (expr_decl, decl_specs, 1, NULL_TREE);
4058 DECL_CONTEXT (refs_decl) = NULL_TREE;
4060 finish_decl (refs_decl, build_constructor (TREE_TYPE (refs_decl),
4061 nreverse (initlist)),
4068 build_category_initializer (type, cat_name, class_name,
4069 instance_methods, class_methods, protocol_list)
4073 tree instance_methods;
4077 tree initlist = NULL_TREE, expr;
4079 initlist = tree_cons (NULL_TREE, cat_name, initlist);
4080 initlist = tree_cons (NULL_TREE, class_name, initlist);
4082 if (!instance_methods)
4083 initlist = tree_cons (NULL_TREE, build_int_2 (0, 0), initlist);
4086 expr = build_unary_op (ADDR_EXPR, instance_methods, 0);
4087 initlist = tree_cons (NULL_TREE, expr, initlist);
4090 initlist = tree_cons (NULL_TREE, build_int_2 (0, 0), initlist);
4093 expr = build_unary_op (ADDR_EXPR, class_methods, 0);
4094 initlist = tree_cons (NULL_TREE, expr, initlist);
4097 /* protocol_list = */
4099 initlist = tree_cons (NULL_TREE, build_int_2 (0, 0), initlist);
4102 tree cast_type2 = groktypename
4104 (build_tree_list (NULL_TREE,
4105 xref_tag (RECORD_TYPE,
4106 get_identifier (UTAG_PROTOCOL))),
4107 build1 (INDIRECT_REF, NULL_TREE,
4108 build1 (INDIRECT_REF, NULL_TREE, NULL_TREE))));
4110 expr = build_unary_op (ADDR_EXPR, protocol_list, 0);
4111 TREE_TYPE (expr) = cast_type2;
4112 initlist = tree_cons (NULL_TREE, expr, initlist);
4115 return build_constructor (type, nreverse (initlist));
4118 /* struct objc_class {
4119 struct objc_class *isa;
4120 struct objc_class *super_class;
4125 struct objc_ivar_list *ivars;
4126 struct objc_method_list *methods;
4127 if (flag_next_runtime)
4128 struct objc_cache *cache;
4130 struct sarray *dtable;
4131 struct objc_class *subclass_list;
4132 struct objc_class *sibling_class;
4134 struct objc_protocol_list *protocols;
4135 void *gc_object_type;
4139 build_shared_structure_initializer (type, isa, super, name, size, status,
4140 dispatch_table, ivar_list, protocol_list)
4147 tree dispatch_table;
4151 tree initlist = NULL_TREE, expr;
4154 initlist = tree_cons (NULL_TREE, isa, initlist);
4157 initlist = tree_cons (NULL_TREE, super, initlist);
4160 initlist = tree_cons (NULL_TREE, default_conversion (name), initlist);
4163 initlist = tree_cons (NULL_TREE, build_int_2 (0, 0), initlist);
4166 initlist = tree_cons (NULL_TREE, build_int_2 (status, 0), initlist);
4168 /* instance_size = */
4169 initlist = tree_cons (NULL_TREE, size, initlist);
4171 /* objc_ivar_list = */
4173 initlist = tree_cons (NULL_TREE, build_int_2 (0, 0), initlist);
4176 expr = build_unary_op (ADDR_EXPR, ivar_list, 0);
4177 initlist = tree_cons (NULL_TREE, expr, initlist);
4180 /* objc_method_list = */
4181 if (!dispatch_table)
4182 initlist = tree_cons (NULL_TREE, build_int_2 (0, 0), initlist);
4185 expr = build_unary_op (ADDR_EXPR, dispatch_table, 0);
4186 initlist = tree_cons (NULL_TREE, expr, initlist);
4189 if (flag_next_runtime)
4190 /* method_cache = */
4191 initlist = tree_cons (NULL_TREE, build_int_2 (0, 0), initlist);
4195 initlist = tree_cons (NULL_TREE, build_int_2 (0, 0), initlist);
4197 /* subclass_list = */
4198 initlist = tree_cons (NULL_TREE, build_int_2 (0, 0), initlist);
4200 /* sibling_class = */
4201 initlist = tree_cons (NULL_TREE, build_int_2 (0, 0), initlist);
4204 /* protocol_list = */
4205 if (! protocol_list)
4206 initlist = tree_cons (NULL_TREE, build_int_2 (0, 0), initlist);
4212 (build_tree_list (NULL_TREE,
4213 xref_tag (RECORD_TYPE,
4214 get_identifier (UTAG_PROTOCOL))),
4215 build1 (INDIRECT_REF, NULL_TREE,
4216 build1 (INDIRECT_REF, NULL_TREE, NULL_TREE))));
4218 expr = build_unary_op (ADDR_EXPR, protocol_list, 0);
4219 TREE_TYPE (expr) = cast_type2;
4220 initlist = tree_cons (NULL_TREE, expr, initlist);
4223 /* gc_object_type = NULL */
4224 initlist = tree_cons (NULL_TREE, build_int_2 (0, 0), initlist);
4226 return build_constructor (type, nreverse (initlist));
4229 /* static struct objc_category _OBJC_CATEGORY_<name> = { ... }; */
4232 generate_category (cat)
4235 tree sc_spec, decl_specs, decl;
4236 tree initlist, cat_name_expr, class_name_expr;
4237 tree protocol_decl, category;
4239 add_class_reference (CLASS_NAME (cat));
4240 cat_name_expr = add_objc_string (CLASS_SUPER_NAME (cat), class_names);
4242 class_name_expr = add_objc_string (CLASS_NAME (cat), class_names);
4244 category = CLASS_CATEGORY_LIST (implementation_template);
4246 /* find the category interface from the class it is associated with */
4249 if (CLASS_SUPER_NAME (cat) == CLASS_SUPER_NAME (category))
4251 category = CLASS_CATEGORY_LIST (category);
4254 if (category && CLASS_PROTOCOL_LIST (category))
4256 generate_protocol_references (CLASS_PROTOCOL_LIST (category));
4257 protocol_decl = generate_protocol_list (category);
4262 sc_spec = tree_cons (NULL_TREE, ridpointers[(int) RID_STATIC], NULL_TREE);
4263 decl_specs = tree_cons (NULL_TREE, objc_category_template, sc_spec);
4265 decl = start_decl (synth_id_with_class_suffix ("_OBJC_CATEGORY",
4266 objc_implementation_context),
4267 decl_specs, 1, NULL_TREE);
4269 initlist = build_category_initializer (TREE_TYPE (decl),
4270 cat_name_expr, class_name_expr,
4271 UOBJC_INSTANCE_METHODS_decl,
4272 UOBJC_CLASS_METHODS_decl,
4275 TREE_USED (decl) = 1;
4276 finish_decl (decl, initlist, NULL_TREE);
4279 /* static struct objc_class _OBJC_METACLASS_Foo={ ... };
4280 static struct objc_class _OBJC_CLASS_Foo={ ... }; */
4283 generate_shared_structures ()
4285 tree sc_spec, decl_specs, decl;
4286 tree name_expr, super_expr, root_expr;
4287 tree my_root_id = NULL_TREE, my_super_id = NULL_TREE;
4288 tree cast_type, initlist, protocol_decl;
4290 my_super_id = CLASS_SUPER_NAME (implementation_template);
4293 add_class_reference (my_super_id);
4295 /* Compute "my_root_id" - this is required for code generation.
4296 the "isa" for all meta class structures points to the root of
4297 the inheritance hierarchy (e.g. "__Object")... */
4298 my_root_id = my_super_id;
4301 tree my_root_int = lookup_interface (my_root_id);
4303 if (my_root_int && CLASS_SUPER_NAME (my_root_int))
4304 my_root_id = CLASS_SUPER_NAME (my_root_int);
4311 /* No super class. */
4312 my_root_id = CLASS_NAME (implementation_template);
4315 = groktypename (build_tree_list (build_tree_list (NULL_TREE,
4316 objc_class_template),
4317 build1 (INDIRECT_REF,
4318 NULL_TREE, NULL_TREE)));
4320 name_expr = add_objc_string (CLASS_NAME (implementation_template),
4323 /* Install class `isa' and `super' pointers at runtime. */
4326 super_expr = add_objc_string (my_super_id, class_names);
4327 super_expr = build_c_cast (cast_type, super_expr); /* cast! */
4330 super_expr = build_int_2 (0, 0);
4332 root_expr = add_objc_string (my_root_id, class_names);
4333 root_expr = build_c_cast (cast_type, root_expr); /* cast! */
4335 if (CLASS_PROTOCOL_LIST (implementation_template))
4337 generate_protocol_references
4338 (CLASS_PROTOCOL_LIST (implementation_template));
4339 protocol_decl = generate_protocol_list (implementation_template);
4344 /* static struct objc_class _OBJC_METACLASS_Foo = { ... }; */
4346 sc_spec = build_tree_list (NULL_TREE, ridpointers[(int) RID_STATIC]);
4347 decl_specs = tree_cons (NULL_TREE, objc_class_template, sc_spec);
4349 decl = start_decl (DECL_NAME (UOBJC_METACLASS_decl), decl_specs, 1,
4353 = build_shared_structure_initializer
4355 root_expr, super_expr, name_expr,
4356 convert (integer_type_node, TYPE_SIZE_UNIT (objc_class_template)),
4358 UOBJC_CLASS_METHODS_decl,
4359 UOBJC_CLASS_VARIABLES_decl,
4362 finish_decl (decl, initlist, NULL_TREE);
4364 /* static struct objc_class _OBJC_CLASS_Foo={ ... }; */
4366 decl = start_decl (DECL_NAME (UOBJC_CLASS_decl), decl_specs, 1,
4370 = build_shared_structure_initializer
4372 build_unary_op (ADDR_EXPR, UOBJC_METACLASS_decl, 0),
4373 super_expr, name_expr,
4374 convert (integer_type_node,
4375 TYPE_SIZE_UNIT (CLASS_STATIC_TEMPLATE
4376 (implementation_template))),
4378 UOBJC_INSTANCE_METHODS_decl,
4379 UOBJC_INSTANCE_VARIABLES_decl,
4382 finish_decl (decl, initlist, NULL_TREE);
4386 synth_id_with_class_suffix (preamble, ctxt)
4387 const char *preamble;
4391 if (TREE_CODE (ctxt) == CLASS_IMPLEMENTATION_TYPE
4392 || TREE_CODE (ctxt) == CLASS_INTERFACE_TYPE)
4394 const char *const class_name
4395 = IDENTIFIER_POINTER (CLASS_NAME (objc_implementation_context));
4396 string = (char *) alloca (strlen (preamble) + strlen (class_name) + 3);
4397 sprintf (string, "%s_%s", preamble,
4398 IDENTIFIER_POINTER (CLASS_NAME (ctxt)));
4400 else if (TREE_CODE (ctxt) == CATEGORY_IMPLEMENTATION_TYPE
4401 || TREE_CODE (ctxt) == CATEGORY_INTERFACE_TYPE)
4403 /* We have a category. */
4404 const char *const class_name
4405 = IDENTIFIER_POINTER (CLASS_NAME (objc_implementation_context));
4406 const char *const class_super_name
4407 = IDENTIFIER_POINTER (CLASS_SUPER_NAME (objc_implementation_context));
4408 string = (char *) alloca (strlen (preamble)
4409 + strlen (class_name)
4410 + strlen (class_super_name)
4412 sprintf (string, "%s_%s_%s", preamble, class_name, class_super_name);
4414 else if (TREE_CODE (ctxt) == PROTOCOL_INTERFACE_TYPE)
4416 const char *protocol_name = IDENTIFIER_POINTER (PROTOCOL_NAME (ctxt));
4418 = (char *) alloca (strlen (preamble) + strlen (protocol_name) + 3);
4419 sprintf (string, "%s_%s", preamble, protocol_name);
4424 return get_identifier (string);
4428 is_objc_type_qualifier (node)
4431 return (TREE_CODE (node) == IDENTIFIER_NODE
4432 && (node == ridpointers [(int) RID_CONST]
4433 || node == ridpointers [(int) RID_VOLATILE]
4434 || node == ridpointers [(int) RID_IN]
4435 || node == ridpointers [(int) RID_OUT]
4436 || node == ridpointers [(int) RID_INOUT]
4437 || node == ridpointers [(int) RID_BYCOPY]
4438 || node == ridpointers [(int) RID_BYREF]
4439 || node == ridpointers [(int) RID_ONEWAY]));
4442 /* If type is empty or only type qualifiers are present, add default
4443 type of id (otherwise grokdeclarator will default to int). */
4446 adjust_type_for_id_default (type)
4449 tree declspecs, chain;
4452 return build_tree_list (build_tree_list (NULL_TREE, objc_object_reference),
4453 build1 (INDIRECT_REF, NULL_TREE, NULL_TREE));
4455 declspecs = TREE_PURPOSE (type);
4457 /* Determine if a typespec is present. */
4458 for (chain = declspecs;
4460 chain = TREE_CHAIN (chain))
4462 if (!is_objc_type_qualifier (TREE_VALUE (chain)))
4466 return build_tree_list (tree_cons (NULL_TREE, objc_object_reference,
4468 build1 (INDIRECT_REF, NULL_TREE, NULL_TREE));
4473 selector ':' '(' typename ')' identifier
4476 Transform an Objective-C keyword argument into
4477 the C equivalent parameter declarator.
4479 In: key_name, an "identifier_node" (optional).
4480 arg_type, a "tree_list" (optional).
4481 arg_name, an "identifier_node".
4483 Note: It would be really nice to strongly type the preceding
4484 arguments in the function prototype; however, then I
4485 could not use the "accessor" macros defined in "tree.h".
4487 Out: an instance of "keyword_decl". */
4490 build_keyword_decl (key_name, arg_type, arg_name)
4497 /* If no type is specified, default to "id". */
4498 arg_type = adjust_type_for_id_default (arg_type);
4500 keyword_decl = make_node (KEYWORD_DECL);
4502 TREE_TYPE (keyword_decl) = arg_type;
4503 KEYWORD_ARG_NAME (keyword_decl) = arg_name;
4504 KEYWORD_KEY_NAME (keyword_decl) = key_name;
4506 return keyword_decl;
4509 /* Given a chain of keyword_decl's, synthesize the full keyword selector. */
4512 build_keyword_selector (selector)
4516 tree key_chain, key_name;
4519 /* Scan the selector to see how much space we'll need. */
4520 for (key_chain = selector; key_chain; key_chain = TREE_CHAIN (key_chain))
4522 if (TREE_CODE (selector) == KEYWORD_DECL)
4523 key_name = KEYWORD_KEY_NAME (key_chain);
4524 else if (TREE_CODE (selector) == TREE_LIST)
4525 key_name = TREE_PURPOSE (key_chain);
4530 len += IDENTIFIER_LENGTH (key_name) + 1;
4532 /* Just a ':' arg. */
4536 buf = (char *) alloca (len + 1);
4537 /* Start the buffer out as an empty string. */
4540 for (key_chain = selector; key_chain; key_chain = TREE_CHAIN (key_chain))
4542 if (TREE_CODE (selector) == KEYWORD_DECL)
4543 key_name = KEYWORD_KEY_NAME (key_chain);
4544 else if (TREE_CODE (selector) == TREE_LIST)
4545 key_name = TREE_PURPOSE (key_chain);
4550 strcat (buf, IDENTIFIER_POINTER (key_name));
4554 return get_identifier (buf);
4557 /* Used for declarations and definitions. */
4560 build_method_decl (code, ret_type, selector, add_args)
4561 enum tree_code code;
4568 /* If no type is specified, default to "id". */
4569 ret_type = adjust_type_for_id_default (ret_type);
4571 method_decl = make_node (code);
4572 TREE_TYPE (method_decl) = ret_type;
4574 /* If we have a keyword selector, create an identifier_node that
4575 represents the full selector name (`:' included)... */
4576 if (TREE_CODE (selector) == KEYWORD_DECL)
4578 METHOD_SEL_NAME (method_decl) = build_keyword_selector (selector);
4579 METHOD_SEL_ARGS (method_decl) = selector;
4580 METHOD_ADD_ARGS (method_decl) = add_args;
4584 METHOD_SEL_NAME (method_decl) = selector;
4585 METHOD_SEL_ARGS (method_decl) = NULL_TREE;
4586 METHOD_ADD_ARGS (method_decl) = NULL_TREE;
4592 #define METHOD_DEF 0
4593 #define METHOD_REF 1
4595 /* Used by `build_objc_method_call' and `comp_method_types'. Return
4596 an argument list for method METH. CONTEXT is either METHOD_DEF or
4597 METHOD_REF, saying whether we are trying to define a method or call
4598 one. SUPERFLAG says this is for a send to super; this makes a
4599 difference for the NeXT calling sequence in which the lookup and
4600 the method call are done together. */
4603 get_arg_type_list (meth, context, superflag)
4610 /* Receiver type. */
4611 if (flag_next_runtime && superflag)
4612 arglist = build_tree_list (NULL_TREE, super_type);
4613 else if (context == METHOD_DEF)
4614 arglist = build_tree_list (NULL_TREE, TREE_TYPE (self_decl));
4616 arglist = build_tree_list (NULL_TREE, id_type);
4618 /* Selector type - will eventually change to `int'. */
4619 chainon (arglist, build_tree_list (NULL_TREE, selector_type));
4621 /* Build a list of argument types. */
4622 for (akey = METHOD_SEL_ARGS (meth); akey; akey = TREE_CHAIN (akey))
4624 tree arg_decl = groktypename_in_parm_context (TREE_TYPE (akey));
4625 chainon (arglist, build_tree_list (NULL_TREE, TREE_TYPE (arg_decl)));
4628 if (METHOD_ADD_ARGS (meth) == objc_ellipsis_node)
4629 /* We have a `, ...' immediately following the selector,
4630 finalize the arglist...simulate get_parm_info (0). */
4632 else if (METHOD_ADD_ARGS (meth))
4634 /* we have a variable length selector */
4635 tree add_arg_list = TREE_CHAIN (METHOD_ADD_ARGS (meth));
4636 chainon (arglist, add_arg_list);
4639 /* finalize the arglist...simulate get_parm_info (1) */
4640 chainon (arglist, build_tree_list (NULL_TREE, void_type_node));
4646 check_duplicates (hsh)
4649 tree meth = NULL_TREE;
4657 /* We have two methods with the same name and different types. */
4659 char type = (TREE_CODE (meth) == INSTANCE_METHOD_DECL) ? '-' : '+';
4661 warning ("multiple declarations for method `%s'",
4662 IDENTIFIER_POINTER (METHOD_SEL_NAME (meth)));
4664 warn_with_method ("using", type, meth);
4665 for (loop = hsh->list; loop; loop = loop->next)
4666 warn_with_method ("also found", type, loop->value);
4672 /* If RECEIVER is a class reference, return the identifier node for
4673 the referenced class. RECEIVER is created by get_class_reference,
4674 so we check the exact form created depending on which runtimes are
4678 receiver_is_class_object (receiver)
4681 tree chain, exp, arg;
4683 /* The receiver is 'self' in the context of a class method. */
4684 if (objc_method_context
4685 && receiver == self_decl
4686 && TREE_CODE (objc_method_context) == CLASS_METHOD_DECL)
4688 return CLASS_NAME (objc_implementation_context);
4691 if (flag_next_runtime)
4693 /* The receiver is a variable created by
4694 build_class_reference_decl. */
4695 if (TREE_CODE (receiver) == VAR_DECL
4696 && TREE_TYPE (receiver) == objc_class_type)
4697 /* Look up the identifier. */
4698 for (chain = cls_ref_chain; chain; chain = TREE_CHAIN (chain))
4699 if (TREE_PURPOSE (chain) == receiver)
4700 return TREE_VALUE (chain);
4704 /* The receiver is a function call that returns an id. Check if
4705 it is a call to objc_getClass, if so, pick up the class name. */
4706 if (TREE_CODE (receiver) == CALL_EXPR
4707 && (exp = TREE_OPERAND (receiver, 0))
4708 && TREE_CODE (exp) == ADDR_EXPR
4709 && (exp = TREE_OPERAND (exp, 0))
4710 && TREE_CODE (exp) == FUNCTION_DECL
4711 && exp == objc_get_class_decl
4712 /* We have a call to objc_getClass! */
4713 && (arg = TREE_OPERAND (receiver, 1))
4714 && TREE_CODE (arg) == TREE_LIST
4715 && (arg = TREE_VALUE (arg)))
4718 if (TREE_CODE (arg) == ADDR_EXPR
4719 && (arg = TREE_OPERAND (arg, 0))
4720 && TREE_CODE (arg) == STRING_CST)
4721 /* Finally, we have the class name. */
4722 return get_identifier (TREE_STRING_POINTER (arg));
4728 /* If we are currently building a message expr, this holds
4729 the identifier of the selector of the message. This is
4730 used when printing warnings about argument mismatches. */
4732 static tree building_objc_message_expr = 0;
4735 maybe_building_objc_message_expr ()
4737 return building_objc_message_expr;
4740 /* Construct an expression for sending a message.
4741 MESS has the object to send to in TREE_PURPOSE
4742 and the argument list (including selector) in TREE_VALUE.
4744 (*(<abstract_decl>(*)())_msg)(receiver, selTransTbl[n], ...);
4745 (*(<abstract_decl>(*)())_msgSuper)(receiver, selTransTbl[n], ...); */
4748 build_message_expr (mess)
4751 tree receiver = TREE_PURPOSE (mess);
4753 tree args = TREE_VALUE (mess);
4754 tree method_params = NULL_TREE;
4756 if (TREE_CODE (receiver) == ERROR_MARK)
4757 return error_mark_node;
4759 /* Obtain the full selector name. */
4760 if (TREE_CODE (args) == IDENTIFIER_NODE)
4761 /* A unary selector. */
4763 else if (TREE_CODE (args) == TREE_LIST)
4764 sel_name = build_keyword_selector (args);
4768 /* Build the parameter list to give to the method. */
4769 if (TREE_CODE (args) == TREE_LIST)
4771 tree chain = args, prev = NULL_TREE;
4773 /* We have a keyword selector--check for comma expressions. */
4776 tree element = TREE_VALUE (chain);
4778 /* We have a comma expression, must collapse... */
4779 if (TREE_CODE (element) == TREE_LIST)
4782 TREE_CHAIN (prev) = element;
4787 chain = TREE_CHAIN (chain);
4789 method_params = args;
4792 return finish_message_expr (receiver, sel_name, method_params);
4795 /* The 'finish_message_expr' routine is called from within
4796 'build_message_expr' for non-template functions. In the case of
4797 C++ template functions, it is called from 'build_expr_from_tree'
4798 (in decl2.c) after RECEIVER and METHOD_PARAMS have been expanded. */
4801 finish_message_expr (receiver, sel_name, method_params)
4802 tree receiver, sel_name, method_params;
4804 tree method_prototype = NULL_TREE, class_ident = NULL_TREE;
4805 tree selector, self_object, retval;
4806 int statically_typed = 0, statically_allocated = 0;
4808 /* Determine receiver type. */
4809 tree rtype = TREE_TYPE (receiver);
4810 int super = IS_SUPER (rtype);
4814 if (TREE_STATIC_TEMPLATE (rtype))
4815 statically_allocated = 1;
4816 else if (TREE_CODE (rtype) == POINTER_TYPE
4817 && TREE_STATIC_TEMPLATE (TREE_TYPE (rtype)))
4818 statically_typed = 1;
4819 else if ((flag_next_runtime
4821 && (class_ident = receiver_is_class_object (receiver)))
4823 else if (! IS_ID (rtype)
4824 /* Allow any type that matches objc_class_type. */
4825 && ! comptypes (rtype, objc_class_type))
4827 warning ("invalid receiver type `%s'",
4828 gen_declaration (rtype, errbuf));
4830 if (statically_allocated)
4831 receiver = build_unary_op (ADDR_EXPR, receiver, 0);
4833 /* Don't evaluate the receiver twice. */
4834 receiver = save_expr (receiver);
4835 self_object = receiver;
4838 /* If sending to `super', use current self as the object. */
4839 self_object = self_decl;
4841 /* Determine operation return type. */
4847 if (CLASS_SUPER_NAME (implementation_template))
4850 = lookup_interface (CLASS_SUPER_NAME (implementation_template));
4852 if (TREE_CODE (objc_method_context) == INSTANCE_METHOD_DECL)
4853 method_prototype = lookup_instance_method_static (iface, sel_name);
4855 method_prototype = lookup_class_method_static (iface, sel_name);
4857 if (iface && !method_prototype)
4858 warning ("`%s' does not respond to `%s'",
4859 IDENTIFIER_POINTER (CLASS_SUPER_NAME (implementation_template)),
4860 IDENTIFIER_POINTER (sel_name));
4864 error ("no super class declared in interface for `%s'",
4865 IDENTIFIER_POINTER (CLASS_NAME (implementation_template)));
4866 return error_mark_node;
4870 else if (statically_allocated)
4872 tree ctype = TREE_TYPE (rtype);
4873 tree iface = lookup_interface (TYPE_NAME (rtype));
4876 method_prototype = lookup_instance_method_static (iface, sel_name);
4878 if (! method_prototype && TYPE_PROTOCOL_LIST (ctype))
4880 = lookup_method_in_protocol_list (TYPE_PROTOCOL_LIST (ctype),
4883 if (!method_prototype)
4884 warning ("`%s' does not respond to `%s'",
4885 IDENTIFIER_POINTER (TYPE_NAME (rtype)),
4886 IDENTIFIER_POINTER (sel_name));
4888 else if (statically_typed)
4890 tree ctype = TREE_TYPE (rtype);
4892 /* `self' is now statically_typed. All methods should be visible
4893 within the context of the implementation. */
4894 if (objc_implementation_context
4895 && CLASS_NAME (objc_implementation_context) == TYPE_NAME (ctype))
4898 = lookup_instance_method_static (implementation_template,
4901 if (! method_prototype && TYPE_PROTOCOL_LIST (ctype))
4903 = lookup_method_in_protocol_list (TYPE_PROTOCOL_LIST (ctype),
4906 if (! method_prototype
4907 && implementation_template != objc_implementation_context)
4908 /* The method is not published in the interface. Check
4911 = lookup_method (CLASS_NST_METHODS (objc_implementation_context),
4918 if ((iface = lookup_interface (TYPE_NAME (ctype))))
4919 method_prototype = lookup_instance_method_static (iface, sel_name);
4921 if (! method_prototype)
4923 tree protocol_list = TYPE_PROTOCOL_LIST (ctype);
4926 = lookup_method_in_protocol_list (protocol_list,
4931 if (!method_prototype)
4932 warning ("`%s' does not respond to `%s'",
4933 IDENTIFIER_POINTER (TYPE_NAME (ctype)),
4934 IDENTIFIER_POINTER (sel_name));
4936 else if (class_ident)
4938 if (objc_implementation_context
4939 && CLASS_NAME (objc_implementation_context) == class_ident)
4942 = lookup_class_method_static (implementation_template, sel_name);
4944 if (!method_prototype
4945 && implementation_template != objc_implementation_context)
4946 /* The method is not published in the interface. Check
4949 = lookup_method (CLASS_CLS_METHODS (objc_implementation_context),
4956 if ((iface = lookup_interface (class_ident)))
4957 method_prototype = lookup_class_method_static (iface, sel_name);
4960 if (!method_prototype)
4962 warning ("cannot find class (factory) method");
4963 warning ("return type for `%s' defaults to id",
4964 IDENTIFIER_POINTER (sel_name));
4967 else if (IS_PROTOCOL_QUALIFIED_ID (rtype))
4969 /* An anonymous object that has been qualified with a protocol. */
4971 tree protocol_list = TYPE_PROTOCOL_LIST (rtype);
4973 method_prototype = lookup_method_in_protocol_list (protocol_list,
4976 if (!method_prototype)
4980 warning ("method `%s' not implemented by protocol",
4981 IDENTIFIER_POINTER (sel_name));
4983 /* Try and find the method signature in the global pools. */
4985 if (!(hsh = hash_lookup (nst_method_hash_list, sel_name)))
4986 hsh = hash_lookup (cls_method_hash_list, sel_name);
4988 if (!(method_prototype = check_duplicates (hsh)))
4989 warning ("return type defaults to id");
4996 /* We think we have an instance...loophole: extern id Object; */
4997 hsh = hash_lookup (nst_method_hash_list, sel_name);
5000 /* For various loopholes */
5001 hsh = hash_lookup (cls_method_hash_list, sel_name);
5003 method_prototype = check_duplicates (hsh);
5004 if (!method_prototype)
5006 warning ("cannot find method");
5007 warning ("return type for `%s' defaults to id",
5008 IDENTIFIER_POINTER (sel_name));
5012 /* Save the selector name for printing error messages. */
5013 building_objc_message_expr = sel_name;
5015 /* Build the parameters list for looking up the method.
5016 These are the object itself and the selector. */
5018 if (flag_typed_selectors)
5019 selector = build_typed_selector_reference (sel_name, method_prototype);
5021 selector = build_selector_reference (sel_name);
5023 retval = build_objc_method_call (super, method_prototype,
5024 receiver, self_object,
5025 selector, method_params);
5027 building_objc_message_expr = 0;
5032 /* Build a tree expression to send OBJECT the operation SELECTOR,
5033 looking up the method on object LOOKUP_OBJECT (often same as OBJECT),
5034 assuming the method has prototype METHOD_PROTOTYPE.
5035 (That is an INSTANCE_METHOD_DECL or CLASS_METHOD_DECL.)
5036 Use METHOD_PARAMS as list of args to pass to the method.
5037 If SUPER_FLAG is nonzero, we look up the superclass's method. */
5040 build_objc_method_call (super_flag, method_prototype, lookup_object, object,
5041 selector, method_params)
5043 tree method_prototype, lookup_object, object, selector, method_params;
5045 tree sender = (super_flag ? umsg_super_decl : umsg_decl);
5046 tree rcv_p = (super_flag
5047 ? build_pointer_type (xref_tag (RECORD_TYPE,
5048 get_identifier (TAG_SUPER)))
5051 if (flag_next_runtime)
5053 if (! method_prototype)
5055 method_params = tree_cons (NULL_TREE, lookup_object,
5056 tree_cons (NULL_TREE, selector,
5058 assemble_external (sender);
5059 return build_function_call (sender, method_params);
5063 /* This is a real kludge, but it is used only for the Next.
5064 Clobber the data type of SENDER temporarily to accept
5065 all the arguments for this operation, and to return
5066 whatever this operation returns. */
5067 tree arglist = NULL_TREE, retval, savarg, savret;
5068 tree ret_type = groktypename (TREE_TYPE (method_prototype));
5070 /* Save the proper contents of SENDER's data type. */
5071 savarg = TYPE_ARG_TYPES (TREE_TYPE (sender));
5072 savret = TREE_TYPE (TREE_TYPE (sender));
5074 /* Install this method's argument types. */
5075 arglist = get_arg_type_list (method_prototype, METHOD_REF,
5077 TYPE_ARG_TYPES (TREE_TYPE (sender)) = arglist;
5079 /* Install this method's return type. */
5080 TREE_TYPE (TREE_TYPE (sender)) = ret_type;
5082 /* Call SENDER with all the parameters. This will do type
5083 checking using the arg types for this method. */
5084 method_params = tree_cons (NULL_TREE, lookup_object,
5085 tree_cons (NULL_TREE, selector,
5087 assemble_external (sender);
5088 retval = build_function_call (sender, method_params);
5090 /* Restore SENDER's return/argument types. */
5091 TYPE_ARG_TYPES (TREE_TYPE (sender)) = savarg;
5092 TREE_TYPE (TREE_TYPE (sender)) = savret;
5098 /* This is the portable way.
5099 First call the lookup function to get a pointer to the method,
5100 then cast the pointer, then call it with the method arguments. */
5103 /* Avoid trouble since we may evaluate each of these twice. */
5104 object = save_expr (object);
5105 selector = save_expr (selector);
5107 lookup_object = build_c_cast (rcv_p, lookup_object);
5109 assemble_external (sender);
5111 = build_function_call (sender,
5112 tree_cons (NULL_TREE, lookup_object,
5113 tree_cons (NULL_TREE, selector,
5116 /* If we have a method prototype, construct the data type this
5117 method needs, and cast what we got from SENDER into a pointer
5119 if (method_prototype)
5121 tree arglist = get_arg_type_list (method_prototype, METHOD_REF,
5123 tree valtype = groktypename (TREE_TYPE (method_prototype));
5124 tree fake_function_type = build_function_type (valtype, arglist);
5125 TREE_TYPE (method) = build_pointer_type (fake_function_type);
5129 = build_pointer_type (build_function_type (ptr_type_node, NULL_TREE));
5131 /* Pass the object to the method. */
5132 assemble_external (method);
5133 return build_function_call (method,
5134 tree_cons (NULL_TREE, object,
5135 tree_cons (NULL_TREE, selector,
5141 build_protocol_reference (p)
5144 tree decl, ident, ptype;
5146 /* extern struct objc_protocol _OBJC_PROTOCOL_<mumble>; */
5148 ident = synth_id_with_class_suffix ("_OBJC_PROTOCOL", p);
5150 = groktypename (build_tree_list (build_tree_list (NULL_TREE,
5151 objc_protocol_template),
5154 if (IDENTIFIER_GLOBAL_VALUE (ident))
5155 decl = IDENTIFIER_GLOBAL_VALUE (ident); /* Set by pushdecl. */
5158 decl = build_decl (VAR_DECL, ident, ptype);
5159 DECL_EXTERNAL (decl) = 1;
5160 TREE_PUBLIC (decl) = 1;
5161 TREE_USED (decl) = 1;
5162 DECL_ARTIFICIAL (decl) = 1;
5164 make_decl_rtl (decl, 0);
5165 pushdecl_top_level (decl);
5168 PROTOCOL_FORWARD_DECL (p) = decl;
5172 build_protocol_expr (protoname)
5176 tree p = lookup_protocol (protoname);
5180 error ("cannot find protocol declaration for `%s'",
5181 IDENTIFIER_POINTER (protoname));
5182 return error_mark_node;
5185 if (!PROTOCOL_FORWARD_DECL (p))
5186 build_protocol_reference (p);
5188 expr = build_unary_op (ADDR_EXPR, PROTOCOL_FORWARD_DECL (p), 0);
5190 TREE_TYPE (expr) = protocol_type;
5196 build_selector_expr (selnamelist)
5201 /* Obtain the full selector name. */
5202 if (TREE_CODE (selnamelist) == IDENTIFIER_NODE)
5203 /* A unary selector. */
5204 selname = selnamelist;
5205 else if (TREE_CODE (selnamelist) == TREE_LIST)
5206 selname = build_keyword_selector (selnamelist);
5210 if (flag_typed_selectors)
5211 return build_typed_selector_reference (selname, 0);
5213 return build_selector_reference (selname);
5217 build_encode_expr (type)
5223 encode_type (type, obstack_object_size (&util_obstack),
5224 OBJC_ENCODE_INLINE_DEFS);
5225 obstack_1grow (&util_obstack, 0); /* null terminate string */
5226 string = obstack_finish (&util_obstack);
5228 /* Synthesize a string that represents the encoded struct/union. */
5229 result = my_build_string (strlen (string) + 1, string);
5230 obstack_free (&util_obstack, util_firstobj);
5235 build_ivar_reference (id)
5238 if (TREE_CODE (objc_method_context) == CLASS_METHOD_DECL)
5240 /* Historically, a class method that produced objects (factory
5241 method) would assign `self' to the instance that it
5242 allocated. This would effectively turn the class method into
5243 an instance method. Following this assignment, the instance
5244 variables could be accessed. That practice, while safe,
5245 violates the simple rule that a class method should not refer
5246 to an instance variable. It's better to catch the cases
5247 where this is done unknowingly than to support the above
5249 warning ("instance variable `%s' accessed in class method",
5250 IDENTIFIER_POINTER (id));
5251 TREE_TYPE (self_decl) = instance_type; /* cast */
5254 return build_component_ref (build_indirect_ref (self_decl, "->"), id);
5257 /* Compute a hash value for a given method SEL_NAME. */
5260 hash_func (sel_name)
5263 const unsigned char *s
5264 = (const unsigned char *)IDENTIFIER_POINTER (sel_name);
5268 h = h * 67 + *s++ - 113;
5275 nst_method_hash_list = (hash *) ggc_calloc (SIZEHASHTABLE, sizeof (hash));
5276 cls_method_hash_list = (hash *) ggc_calloc (SIZEHASHTABLE, sizeof (hash));
5279 /* WARNING!!!! hash_enter is called with a method, and will peek
5280 inside to find its selector! But hash_lookup is given a selector
5281 directly, and looks for the selector that's inside the found
5282 entry's key (method) for comparison. */
5285 hash_enter (hashlist, method)
5290 int slot = hash_func (METHOD_SEL_NAME (method)) % SIZEHASHTABLE;
5292 obj = (hash) ggc_alloc (sizeof (struct hashed_entry));
5294 obj->next = hashlist[slot];
5297 hashlist[slot] = obj; /* append to front */
5301 hash_lookup (hashlist, sel_name)
5307 target = hashlist[hash_func (sel_name) % SIZEHASHTABLE];
5311 if (sel_name == METHOD_SEL_NAME (target->key))
5314 target = target->next;
5320 hash_add_attr (entry, value)
5326 obj = (attr) ggc_alloc (sizeof (struct hashed_attribute));
5327 obj->next = entry->list;
5330 entry->list = obj; /* append to front */
5334 lookup_method (mchain, method)
5340 if (TREE_CODE (method) == IDENTIFIER_NODE)
5343 key = METHOD_SEL_NAME (method);
5347 if (METHOD_SEL_NAME (mchain) == key)
5349 mchain = TREE_CHAIN (mchain);
5355 lookup_instance_method_static (interface, ident)
5359 tree inter = interface;
5360 tree chain = CLASS_NST_METHODS (inter);
5361 tree meth = NULL_TREE;
5365 if ((meth = lookup_method (chain, ident)))
5368 if (CLASS_CATEGORY_LIST (inter))
5370 tree category = CLASS_CATEGORY_LIST (inter);
5371 chain = CLASS_NST_METHODS (category);
5375 if ((meth = lookup_method (chain, ident)))
5378 /* Check for instance methods in protocols in categories. */
5379 if (CLASS_PROTOCOL_LIST (category))
5381 if ((meth = (lookup_method_in_protocol_list
5382 (CLASS_PROTOCOL_LIST (category), ident, 0))))
5386 if ((category = CLASS_CATEGORY_LIST (category)))
5387 chain = CLASS_NST_METHODS (category);
5392 if (CLASS_PROTOCOL_LIST (inter))
5394 if ((meth = (lookup_method_in_protocol_list
5395 (CLASS_PROTOCOL_LIST (inter), ident, 0))))
5399 if ((inter = lookup_interface (CLASS_SUPER_NAME (inter))))
5400 chain = CLASS_NST_METHODS (inter);
5408 lookup_class_method_static (interface, ident)
5412 tree inter = interface;
5413 tree chain = CLASS_CLS_METHODS (inter);
5414 tree meth = NULL_TREE;
5415 tree root_inter = NULL_TREE;
5419 if ((meth = lookup_method (chain, ident)))
5422 if (CLASS_CATEGORY_LIST (inter))
5424 tree category = CLASS_CATEGORY_LIST (inter);
5425 chain = CLASS_CLS_METHODS (category);
5429 if ((meth = lookup_method (chain, ident)))
5432 /* Check for class methods in protocols in categories. */
5433 if (CLASS_PROTOCOL_LIST (category))
5435 if ((meth = (lookup_method_in_protocol_list
5436 (CLASS_PROTOCOL_LIST (category), ident, 1))))
5440 if ((category = CLASS_CATEGORY_LIST (category)))
5441 chain = CLASS_CLS_METHODS (category);
5446 /* Check for class methods in protocols. */
5447 if (CLASS_PROTOCOL_LIST (inter))
5449 if ((meth = (lookup_method_in_protocol_list
5450 (CLASS_PROTOCOL_LIST (inter), ident, 1))))
5455 if ((inter = lookup_interface (CLASS_SUPER_NAME (inter))))
5456 chain = CLASS_CLS_METHODS (inter);
5460 /* If no class (factory) method was found, check if an _instance_
5461 method of the same name exists in the root class. This is what
5462 the Objective-C runtime will do. */
5463 return lookup_instance_method_static (root_inter, ident);
5467 add_class_method (class, method)
5474 if (!(mth = lookup_method (CLASS_CLS_METHODS (class), method)))
5476 /* put method on list in reverse order */
5477 TREE_CHAIN (method) = CLASS_CLS_METHODS (class);
5478 CLASS_CLS_METHODS (class) = method;
5482 if (TREE_CODE (class) == CLASS_IMPLEMENTATION_TYPE)
5483 error ("duplicate definition of class method `%s'",
5484 IDENTIFIER_POINTER (METHOD_SEL_NAME (mth)));
5487 /* Check types; if different, complain. */
5488 if (!comp_proto_with_proto (method, mth))
5489 error ("duplicate declaration of class method `%s'",
5490 IDENTIFIER_POINTER (METHOD_SEL_NAME (mth)));
5494 if (!(hsh = hash_lookup (cls_method_hash_list, METHOD_SEL_NAME (method))))
5496 /* Install on a global chain. */
5497 hash_enter (cls_method_hash_list, method);
5501 /* Check types; if different, add to a list. */
5502 if (!comp_proto_with_proto (method, hsh->key))
5503 hash_add_attr (hsh, method);
5509 add_instance_method (class, method)
5516 if (!(mth = lookup_method (CLASS_NST_METHODS (class), method)))
5518 /* Put method on list in reverse order. */
5519 TREE_CHAIN (method) = CLASS_NST_METHODS (class);
5520 CLASS_NST_METHODS (class) = method;
5524 if (TREE_CODE (class) == CLASS_IMPLEMENTATION_TYPE)
5525 error ("duplicate definition of instance method `%s'",
5526 IDENTIFIER_POINTER (METHOD_SEL_NAME (mth)));
5529 /* Check types; if different, complain. */
5530 if (!comp_proto_with_proto (method, mth))
5531 error ("duplicate declaration of instance method `%s'",
5532 IDENTIFIER_POINTER (METHOD_SEL_NAME (mth)));
5536 if (!(hsh = hash_lookup (nst_method_hash_list, METHOD_SEL_NAME (method))))
5538 /* Install on a global chain. */
5539 hash_enter (nst_method_hash_list, method);
5543 /* Check types; if different, add to a list. */
5544 if (!comp_proto_with_proto (method, hsh->key))
5545 hash_add_attr (hsh, method);
5554 /* Put interfaces on list in reverse order. */
5555 TREE_CHAIN (class) = interface_chain;
5556 interface_chain = class;
5557 return interface_chain;
5561 add_category (class, category)
5565 /* Put categories on list in reverse order. */
5566 tree cat = CLASS_CATEGORY_LIST (class);
5570 if (CLASS_SUPER_NAME (cat) == CLASS_SUPER_NAME (category))
5571 warning ("duplicate interface declaration for category `%s(%s)'",
5572 IDENTIFIER_POINTER (CLASS_NAME (class)),
5573 IDENTIFIER_POINTER (CLASS_SUPER_NAME (category)));
5574 cat = CLASS_CATEGORY_LIST (cat);
5577 CLASS_CATEGORY_LIST (category) = CLASS_CATEGORY_LIST (class);
5578 CLASS_CATEGORY_LIST (class) = category;
5581 /* Called after parsing each instance variable declaration. Necessary to
5582 preserve typedefs and implement public/private...
5584 PUBLIC is 1 for public, 0 for protected, and 2 for private. */
5587 add_instance_variable (class, public, declarator, declspecs, width)
5594 tree field_decl, raw_decl;
5596 raw_decl = build_tree_list (declspecs, declarator);
5598 if (CLASS_RAW_IVARS (class))
5599 chainon (CLASS_RAW_IVARS (class), raw_decl);
5601 CLASS_RAW_IVARS (class) = raw_decl;
5603 field_decl = grokfield (input_filename, lineno,
5604 declarator, declspecs, width);
5606 /* Overload the public attribute, it is not used for FIELD_DECLs. */
5610 TREE_PUBLIC (field_decl) = 0;
5611 TREE_PRIVATE (field_decl) = 0;
5612 TREE_PROTECTED (field_decl) = 1;
5616 TREE_PUBLIC (field_decl) = 1;
5617 TREE_PRIVATE (field_decl) = 0;
5618 TREE_PROTECTED (field_decl) = 0;
5622 TREE_PUBLIC (field_decl) = 0;
5623 TREE_PRIVATE (field_decl) = 1;
5624 TREE_PROTECTED (field_decl) = 0;
5629 if (CLASS_IVARS (class))
5630 chainon (CLASS_IVARS (class), field_decl);
5632 CLASS_IVARS (class) = field_decl;
5638 is_ivar (decl_chain, ident)
5642 for ( ; decl_chain; decl_chain = TREE_CHAIN (decl_chain))
5643 if (DECL_NAME (decl_chain) == ident)
5648 /* True if the ivar is private and we are not in its implementation. */
5654 if (TREE_PRIVATE (decl)
5655 && ! is_ivar (CLASS_IVARS (implementation_template), DECL_NAME (decl)))
5657 error ("instance variable `%s' is declared private",
5658 IDENTIFIER_POINTER (DECL_NAME (decl)));
5665 /* We have an instance variable reference;, check to see if it is public. */
5668 is_public (expr, identifier)
5672 tree basetype = TREE_TYPE (expr);
5673 enum tree_code code = TREE_CODE (basetype);
5676 if (code == RECORD_TYPE)
5678 if (TREE_STATIC_TEMPLATE (basetype))
5680 if (!lookup_interface (TYPE_NAME (basetype)))
5682 error ("cannot find interface declaration for `%s'",
5683 IDENTIFIER_POINTER (TYPE_NAME (basetype)));
5687 if ((decl = is_ivar (TYPE_FIELDS (basetype), identifier)))
5689 if (TREE_PUBLIC (decl))
5692 /* Important difference between the Stepstone translator:
5693 all instance variables should be public within the context
5694 of the implementation. */
5695 if (objc_implementation_context
5696 && (((TREE_CODE (objc_implementation_context)
5697 == CLASS_IMPLEMENTATION_TYPE)
5698 || (TREE_CODE (objc_implementation_context)
5699 == CATEGORY_IMPLEMENTATION_TYPE))
5700 && (CLASS_NAME (objc_implementation_context)
5701 == TYPE_NAME (basetype))))
5702 return ! is_private (decl);
5704 error ("instance variable `%s' is declared %s",
5705 IDENTIFIER_POINTER (identifier),
5706 TREE_PRIVATE (decl) ? "private" : "protected");
5711 else if (objc_implementation_context && (basetype == objc_object_reference))
5713 TREE_TYPE (expr) = uprivate_record;
5714 warning ("static access to object of type `id'");
5721 /* Implement @defs (<classname>) within struct bodies. */
5724 get_class_ivars (interface)
5727 /* Make sure we copy the leaf ivars in case @defs is used in a local
5728 context. Otherwise finish_struct will overwrite the layout info
5729 using temporary storage. */
5730 return build_ivar_chain (interface, 1);
5733 /* Make sure all entries in CHAIN are also in LIST. */
5736 check_methods (chain, list, mtype)
5745 if (!lookup_method (list, chain))
5749 if (TREE_CODE (objc_implementation_context)
5750 == CLASS_IMPLEMENTATION_TYPE)
5751 warning ("incomplete implementation of class `%s'",
5752 IDENTIFIER_POINTER (CLASS_NAME (objc_implementation_context)));
5753 else if (TREE_CODE (objc_implementation_context)
5754 == CATEGORY_IMPLEMENTATION_TYPE)
5755 warning ("incomplete implementation of category `%s'",
5756 IDENTIFIER_POINTER (CLASS_SUPER_NAME (objc_implementation_context)));
5760 warning ("method definition for `%c%s' not found",
5761 mtype, IDENTIFIER_POINTER (METHOD_SEL_NAME (chain)));
5764 chain = TREE_CHAIN (chain);
5770 /* Check if CLASS, or its superclasses, explicitly conforms to PROTOCOL. */
5773 conforms_to_protocol (class, protocol)
5777 if (TREE_CODE (protocol) == PROTOCOL_INTERFACE_TYPE)
5779 tree p = CLASS_PROTOCOL_LIST (class);
5780 while (p && TREE_VALUE (p) != protocol)
5785 tree super = (CLASS_SUPER_NAME (class)
5786 ? lookup_interface (CLASS_SUPER_NAME (class))
5788 int tmp = super ? conforms_to_protocol (super, protocol) : 0;
5797 /* Make sure all methods in CHAIN are accessible as MTYPE methods in
5798 CONTEXT. This is one of two mechanisms to check protocol integrity. */
5801 check_methods_accessible (chain, context, mtype)
5808 tree base_context = context;
5812 context = base_context;
5816 list = CLASS_CLS_METHODS (context);
5818 list = CLASS_NST_METHODS (context);
5820 if (lookup_method (list, chain))
5823 else if (TREE_CODE (context) == CLASS_IMPLEMENTATION_TYPE
5824 || TREE_CODE (context) == CLASS_INTERFACE_TYPE)
5825 context = (CLASS_SUPER_NAME (context)
5826 ? lookup_interface (CLASS_SUPER_NAME (context))
5829 else if (TREE_CODE (context) == CATEGORY_IMPLEMENTATION_TYPE
5830 || TREE_CODE (context) == CATEGORY_INTERFACE_TYPE)
5831 context = (CLASS_NAME (context)
5832 ? lookup_interface (CLASS_NAME (context))
5838 if (context == NULL_TREE)
5842 if (TREE_CODE (objc_implementation_context)
5843 == CLASS_IMPLEMENTATION_TYPE)
5844 warning ("incomplete implementation of class `%s'",
5846 (CLASS_NAME (objc_implementation_context)));
5847 else if (TREE_CODE (objc_implementation_context)
5848 == CATEGORY_IMPLEMENTATION_TYPE)
5849 warning ("incomplete implementation of category `%s'",
5851 (CLASS_SUPER_NAME (objc_implementation_context)));
5854 warning ("method definition for `%c%s' not found",
5855 mtype, IDENTIFIER_POINTER (METHOD_SEL_NAME (chain)));
5858 chain = TREE_CHAIN (chain); /* next method... */
5863 /* Check whether the current interface (accessible via
5864 'objc_implementation_context') actually implements protocol P, along
5865 with any protocols that P inherits. */
5868 check_protocol (p, type, name)
5873 if (TREE_CODE (p) == PROTOCOL_INTERFACE_TYPE)
5877 /* Ensure that all protocols have bodies! */
5878 if (flag_warn_protocol)
5880 f1 = check_methods (PROTOCOL_CLS_METHODS (p),
5881 CLASS_CLS_METHODS (objc_implementation_context),
5883 f2 = check_methods (PROTOCOL_NST_METHODS (p),
5884 CLASS_NST_METHODS (objc_implementation_context),
5889 f1 = check_methods_accessible (PROTOCOL_CLS_METHODS (p),
5890 objc_implementation_context,
5892 f2 = check_methods_accessible (PROTOCOL_NST_METHODS (p),
5893 objc_implementation_context,
5898 warning ("%s `%s' does not fully implement the `%s' protocol",
5899 type, name, IDENTIFIER_POINTER (PROTOCOL_NAME (p)));
5902 /* Check protocols recursively. */
5903 if (PROTOCOL_LIST (p))
5905 tree subs = PROTOCOL_LIST (p);
5907 lookup_interface (CLASS_SUPER_NAME (implementation_template));
5911 tree sub = TREE_VALUE (subs);
5913 /* If the superclass does not conform to the protocols
5914 inherited by P, then we must! */
5915 if (!super_class || !conforms_to_protocol (super_class, sub))
5916 check_protocol (sub, type, name);
5917 subs = TREE_CHAIN (subs);
5922 /* Check whether the current interface (accessible via
5923 'objc_implementation_context') actually implements the protocols listed
5927 check_protocols (proto_list, type, name)
5932 for ( ; proto_list; proto_list = TREE_CHAIN (proto_list))
5934 tree p = TREE_VALUE (proto_list);
5936 check_protocol (p, type, name);
5940 /* Make sure that the class CLASS_NAME is defined
5941 CODE says which kind of thing CLASS_NAME ought to be.
5942 It can be CLASS_INTERFACE_TYPE, CLASS_IMPLEMENTATION_TYPE,
5943 CATEGORY_INTERFACE_TYPE, or CATEGORY_IMPLEMENTATION_TYPE. */
5946 start_class (code, class_name, super_name, protocol_list)
5947 enum tree_code code;
5954 if (objc_implementation_context)
5956 warning ("`@end' missing in implementation context");
5957 finish_class (objc_implementation_context);
5958 objc_ivar_chain = NULL_TREE;
5959 objc_implementation_context = NULL_TREE;
5962 class = make_node (code);
5963 TYPE_BINFO (class) = make_tree_vec (5);
5965 CLASS_NAME (class) = class_name;
5966 CLASS_SUPER_NAME (class) = super_name;
5967 CLASS_CLS_METHODS (class) = NULL_TREE;
5969 if (! is_class_name (class_name) && (decl = lookup_name (class_name)))
5971 error ("`%s' redeclared as different kind of symbol",
5972 IDENTIFIER_POINTER (class_name));
5973 error_with_decl (decl, "previous declaration of `%s'");
5976 if (code == CLASS_IMPLEMENTATION_TYPE)
5981 for (chain = implemented_classes; chain; chain = TREE_CHAIN (chain))
5982 if (TREE_VALUE (chain) == class_name)
5984 error ("reimplementation of class `%s'",
5985 IDENTIFIER_POINTER (class_name));
5986 return error_mark_node;
5988 implemented_classes = tree_cons (NULL_TREE, class_name,
5989 implemented_classes);
5992 /* Pre-build the following entities - for speed/convenience. */
5994 self_id = get_identifier ("self");
5996 ucmd_id = get_identifier ("_cmd");
5999 = build_tree_list (get_identifier ("__unused__"), NULL_TREE);
6000 if (!objc_super_template)
6001 objc_super_template = build_super_template ();
6003 /* Reset for multiple classes per file. */
6006 objc_implementation_context = class;
6008 /* Lookup the interface for this implementation. */
6010 if (!(implementation_template = lookup_interface (class_name)))
6012 warning ("cannot find interface declaration for `%s'",
6013 IDENTIFIER_POINTER (class_name));
6014 add_class (implementation_template = objc_implementation_context);
6017 /* If a super class has been specified in the implementation,
6018 insure it conforms to the one specified in the interface. */
6021 && (super_name != CLASS_SUPER_NAME (implementation_template)))
6023 tree previous_name = CLASS_SUPER_NAME (implementation_template);
6024 const char *const name =
6025 previous_name ? IDENTIFIER_POINTER (previous_name) : "";
6026 error ("conflicting super class name `%s'",
6027 IDENTIFIER_POINTER (super_name));
6028 error ("previous declaration of `%s'", name);
6031 else if (! super_name)
6033 CLASS_SUPER_NAME (objc_implementation_context)
6034 = CLASS_SUPER_NAME (implementation_template);
6038 else if (code == CLASS_INTERFACE_TYPE)
6040 if (lookup_interface (class_name))
6041 warning ("duplicate interface declaration for class `%s'",
6042 IDENTIFIER_POINTER (class_name));
6047 CLASS_PROTOCOL_LIST (class)
6048 = lookup_and_install_protocols (protocol_list);
6051 else if (code == CATEGORY_INTERFACE_TYPE)
6053 tree class_category_is_assoc_with;
6055 /* For a category, class_name is really the name of the class that
6056 the following set of methods will be associated with. We must
6057 find the interface so that can derive the objects template. */
6059 if (!(class_category_is_assoc_with = lookup_interface (class_name)))
6061 error ("cannot find interface declaration for `%s'",
6062 IDENTIFIER_POINTER (class_name));
6063 exit (FATAL_EXIT_CODE);
6066 add_category (class_category_is_assoc_with, class);
6069 CLASS_PROTOCOL_LIST (class)
6070 = lookup_and_install_protocols (protocol_list);
6073 else if (code == CATEGORY_IMPLEMENTATION_TYPE)
6075 /* Pre-build the following entities for speed/convenience. */
6077 self_id = get_identifier ("self");
6079 ucmd_id = get_identifier ("_cmd");
6082 = build_tree_list (get_identifier ("__unused__"), NULL_TREE);
6083 if (!objc_super_template)
6084 objc_super_template = build_super_template ();
6086 /* Reset for multiple classes per file. */
6089 objc_implementation_context = class;
6091 /* For a category, class_name is really the name of the class that
6092 the following set of methods will be associated with. We must
6093 find the interface so that can derive the objects template. */
6095 if (!(implementation_template = lookup_interface (class_name)))
6097 error ("cannot find interface declaration for `%s'",
6098 IDENTIFIER_POINTER (class_name));
6099 exit (FATAL_EXIT_CODE);
6106 continue_class (class)
6109 if (TREE_CODE (class) == CLASS_IMPLEMENTATION_TYPE
6110 || TREE_CODE (class) == CATEGORY_IMPLEMENTATION_TYPE)
6112 struct imp_entry *imp_entry;
6115 /* Check consistency of the instance variables. */
6117 if (CLASS_IVARS (class))
6118 check_ivars (implementation_template, class);
6120 /* code generation */
6122 ivar_context = build_private_template (implementation_template);
6124 if (!objc_class_template)
6125 build_class_template ();
6127 imp_entry = (struct imp_entry *) ggc_alloc (sizeof (struct imp_entry));
6129 imp_entry->next = imp_list;
6130 imp_entry->imp_context = class;
6131 imp_entry->imp_template = implementation_template;
6133 synth_forward_declarations ();
6134 imp_entry->class_decl = UOBJC_CLASS_decl;
6135 imp_entry->meta_decl = UOBJC_METACLASS_decl;
6137 /* Append to front and increment count. */
6138 imp_list = imp_entry;
6139 if (TREE_CODE (class) == CLASS_IMPLEMENTATION_TYPE)
6144 return ivar_context;
6147 else if (TREE_CODE (class) == CLASS_INTERFACE_TYPE)
6149 tree record = xref_tag (RECORD_TYPE, CLASS_NAME (class));
6151 if (!TYPE_FIELDS (record))
6153 finish_struct (record, build_ivar_chain (class, 0), NULL_TREE);
6154 CLASS_STATIC_TEMPLATE (class) = record;
6156 /* Mark this record as a class template for static typing. */
6157 TREE_STATIC_TEMPLATE (record) = 1;
6164 return error_mark_node;
6167 /* This is called once we see the "@end" in an interface/implementation. */
6170 finish_class (class)
6173 if (TREE_CODE (class) == CLASS_IMPLEMENTATION_TYPE)
6175 /* All code generation is done in finish_objc. */
6177 if (implementation_template != objc_implementation_context)
6179 /* Ensure that all method listed in the interface contain bodies. */
6180 check_methods (CLASS_CLS_METHODS (implementation_template),
6181 CLASS_CLS_METHODS (objc_implementation_context), '+');
6182 check_methods (CLASS_NST_METHODS (implementation_template),
6183 CLASS_NST_METHODS (objc_implementation_context), '-');
6185 if (CLASS_PROTOCOL_LIST (implementation_template))
6186 check_protocols (CLASS_PROTOCOL_LIST (implementation_template),
6188 IDENTIFIER_POINTER (CLASS_NAME (objc_implementation_context)));
6192 else if (TREE_CODE (class) == CATEGORY_IMPLEMENTATION_TYPE)
6194 tree category = CLASS_CATEGORY_LIST (implementation_template);
6196 /* Find the category interface from the class it is associated with. */
6199 if (CLASS_SUPER_NAME (class) == CLASS_SUPER_NAME (category))
6201 category = CLASS_CATEGORY_LIST (category);
6206 /* Ensure all method listed in the interface contain bodies. */
6207 check_methods (CLASS_CLS_METHODS (category),
6208 CLASS_CLS_METHODS (objc_implementation_context), '+');
6209 check_methods (CLASS_NST_METHODS (category),
6210 CLASS_NST_METHODS (objc_implementation_context), '-');
6212 if (CLASS_PROTOCOL_LIST (category))
6213 check_protocols (CLASS_PROTOCOL_LIST (category),
6215 IDENTIFIER_POINTER (CLASS_SUPER_NAME (objc_implementation_context)));
6219 else if (TREE_CODE (class) == CLASS_INTERFACE_TYPE)
6222 const char *class_name = IDENTIFIER_POINTER (CLASS_NAME (class));
6223 char *string = (char *) alloca (strlen (class_name) + 3);
6225 /* extern struct objc_object *_<my_name>; */
6227 sprintf (string, "_%s", class_name);
6229 decl_specs = build_tree_list (NULL_TREE, ridpointers[(int) RID_EXTERN]);
6230 decl_specs = tree_cons (NULL_TREE, objc_object_reference, decl_specs);
6231 define_decl (build1 (INDIRECT_REF, NULL_TREE, get_identifier (string)),
6237 add_protocol (protocol)
6240 /* Put protocol on list in reverse order. */
6241 TREE_CHAIN (protocol) = protocol_chain;
6242 protocol_chain = protocol;
6243 return protocol_chain;
6247 lookup_protocol (ident)
6252 for (chain = protocol_chain; chain; chain = TREE_CHAIN (chain))
6253 if (ident == PROTOCOL_NAME (chain))
6259 /* This function forward declares the protocols named by NAMES. If
6260 they are already declared or defined, the function has no effect. */
6263 objc_declare_protocols (names)
6268 for (list = names; list; list = TREE_CHAIN (list))
6270 tree name = TREE_VALUE (list);
6272 if (lookup_protocol (name) == NULL_TREE)
6274 tree protocol = make_node (PROTOCOL_INTERFACE_TYPE);
6276 TYPE_BINFO (protocol) = make_tree_vec (2);
6277 PROTOCOL_NAME (protocol) = name;
6278 PROTOCOL_LIST (protocol) = NULL_TREE;
6279 add_protocol (protocol);
6280 PROTOCOL_DEFINED (protocol) = 0;
6281 PROTOCOL_FORWARD_DECL (protocol) = NULL_TREE;
6287 start_protocol (code, name, list)
6288 enum tree_code code;
6294 /* This is as good a place as any. Need to invoke
6295 push_tag_toplevel. */
6296 if (!objc_protocol_template)
6297 objc_protocol_template = build_protocol_template ();
6299 protocol = lookup_protocol (name);
6303 protocol = make_node (code);
6304 TYPE_BINFO (protocol) = make_tree_vec (2);
6306 PROTOCOL_NAME (protocol) = name;
6307 PROTOCOL_LIST (protocol) = lookup_and_install_protocols (list);
6308 add_protocol (protocol);
6309 PROTOCOL_DEFINED (protocol) = 1;
6310 PROTOCOL_FORWARD_DECL (protocol) = NULL_TREE;
6312 check_protocol_recursively (protocol, list);
6314 else if (! PROTOCOL_DEFINED (protocol))
6316 PROTOCOL_DEFINED (protocol) = 1;
6317 PROTOCOL_LIST (protocol) = lookup_and_install_protocols (list);
6319 check_protocol_recursively (protocol, list);
6323 warning ("duplicate declaration for protocol `%s'",
6324 IDENTIFIER_POINTER (name));
6330 finish_protocol (protocol)
6331 tree protocol ATTRIBUTE_UNUSED;
6336 /* "Encode" a data type into a string, which grows in util_obstack.
6337 ??? What is the FORMAT? Someone please document this! */
6340 encode_type_qualifiers (declspecs)
6345 for (spec = declspecs; spec; spec = TREE_CHAIN (spec))
6347 if (ridpointers[(int) RID_CONST] == TREE_VALUE (spec))
6348 obstack_1grow (&util_obstack, 'r');
6349 else if (ridpointers[(int) RID_IN] == TREE_VALUE (spec))
6350 obstack_1grow (&util_obstack, 'n');
6351 else if (ridpointers[(int) RID_INOUT] == TREE_VALUE (spec))
6352 obstack_1grow (&util_obstack, 'N');
6353 else if (ridpointers[(int) RID_OUT] == TREE_VALUE (spec))
6354 obstack_1grow (&util_obstack, 'o');
6355 else if (ridpointers[(int) RID_BYCOPY] == TREE_VALUE (spec))
6356 obstack_1grow (&util_obstack, 'O');
6357 else if (ridpointers[(int) RID_BYREF] == TREE_VALUE (spec))
6358 obstack_1grow (&util_obstack, 'R');
6359 else if (ridpointers[(int) RID_ONEWAY] == TREE_VALUE (spec))
6360 obstack_1grow (&util_obstack, 'V');
6364 /* Encode a pointer type. */
6367 encode_pointer (type, curtype, format)
6372 tree pointer_to = TREE_TYPE (type);
6374 if (TREE_CODE (pointer_to) == RECORD_TYPE)
6376 if (TYPE_NAME (pointer_to)
6377 && TREE_CODE (TYPE_NAME (pointer_to)) == IDENTIFIER_NODE)
6379 const char *name = IDENTIFIER_POINTER (TYPE_NAME (pointer_to));
6381 if (strcmp (name, TAG_OBJECT) == 0) /* '@' */
6383 obstack_1grow (&util_obstack, '@');
6386 else if (TREE_STATIC_TEMPLATE (pointer_to))
6388 if (generating_instance_variables)
6390 obstack_1grow (&util_obstack, '@');
6391 obstack_1grow (&util_obstack, '"');
6392 obstack_grow (&util_obstack, name, strlen (name));
6393 obstack_1grow (&util_obstack, '"');
6398 obstack_1grow (&util_obstack, '@');
6402 else if (strcmp (name, TAG_CLASS) == 0) /* '#' */
6404 obstack_1grow (&util_obstack, '#');
6407 else if (strcmp (name, TAG_SELECTOR) == 0) /* ':' */
6409 obstack_1grow (&util_obstack, ':');
6414 else if (TREE_CODE (pointer_to) == INTEGER_TYPE
6415 && TYPE_MODE (pointer_to) == QImode)
6417 obstack_1grow (&util_obstack, '*');
6421 /* We have a type that does not get special treatment. */
6423 /* NeXT extension */
6424 obstack_1grow (&util_obstack, '^');
6425 encode_type (pointer_to, curtype, format);
6429 encode_array (type, curtype, format)
6434 tree an_int_cst = TYPE_SIZE (type);
6435 tree array_of = TREE_TYPE (type);
6438 /* An incomplete array is treated like a pointer. */
6439 if (an_int_cst == NULL)
6441 encode_pointer (type, curtype, format);
6445 sprintf (buffer, "[%ld",
6446 (long) (TREE_INT_CST_LOW (an_int_cst)
6447 / TREE_INT_CST_LOW (TYPE_SIZE (array_of))));
6449 obstack_grow (&util_obstack, buffer, strlen (buffer));
6450 encode_type (array_of, curtype, format);
6451 obstack_1grow (&util_obstack, ']');
6456 encode_aggregate_within (type, curtype, format, left, right)
6463 /* The RECORD_TYPE may in fact be a typedef! For purposes
6464 of encoding, we need the real underlying enchilada. */
6465 if (TYPE_MAIN_VARIANT (type))
6466 type = TYPE_MAIN_VARIANT (type);
6468 if (obstack_object_size (&util_obstack) > 0
6469 && *(obstack_next_free (&util_obstack) - 1) == '^')
6471 tree name = TYPE_NAME (type);
6473 /* we have a reference; this is a NeXT extension. */
6475 if (obstack_object_size (&util_obstack) - curtype == 1
6476 && format == OBJC_ENCODE_INLINE_DEFS)
6478 /* Output format of struct for first level only. */
6479 tree fields = TYPE_FIELDS (type);
6481 if (name && TREE_CODE (name) == IDENTIFIER_NODE)
6483 obstack_1grow (&util_obstack, left);
6484 obstack_grow (&util_obstack,
6485 IDENTIFIER_POINTER (name),
6486 strlen (IDENTIFIER_POINTER (name)));
6487 obstack_1grow (&util_obstack, '=');
6491 obstack_1grow (&util_obstack, left);
6492 obstack_grow (&util_obstack, "?=", 2);
6495 for ( ; fields; fields = TREE_CHAIN (fields))
6496 encode_field_decl (fields, curtype, format);
6498 obstack_1grow (&util_obstack, right);
6501 else if (name && TREE_CODE (name) == IDENTIFIER_NODE)
6503 obstack_1grow (&util_obstack, left);
6504 obstack_grow (&util_obstack,
6505 IDENTIFIER_POINTER (name),
6506 strlen (IDENTIFIER_POINTER (name)));
6507 obstack_1grow (&util_obstack, right);
6512 /* We have an untagged structure or a typedef. */
6513 obstack_1grow (&util_obstack, left);
6514 obstack_1grow (&util_obstack, '?');
6515 obstack_1grow (&util_obstack, right);
6521 tree name = TYPE_NAME (type);
6522 tree fields = TYPE_FIELDS (type);
6524 if (format == OBJC_ENCODE_INLINE_DEFS
6525 || generating_instance_variables)
6527 obstack_1grow (&util_obstack, left);
6528 if (name && TREE_CODE (name) == IDENTIFIER_NODE)
6529 obstack_grow (&util_obstack,
6530 IDENTIFIER_POINTER (name),
6531 strlen (IDENTIFIER_POINTER (name)));
6533 obstack_1grow (&util_obstack, '?');
6535 obstack_1grow (&util_obstack, '=');
6537 for (; fields; fields = TREE_CHAIN (fields))
6539 if (generating_instance_variables)
6541 tree fname = DECL_NAME (fields);
6543 obstack_1grow (&util_obstack, '"');
6544 if (fname && TREE_CODE (fname) == IDENTIFIER_NODE)
6546 obstack_grow (&util_obstack,
6547 IDENTIFIER_POINTER (fname),
6548 strlen (IDENTIFIER_POINTER (fname)));
6551 obstack_1grow (&util_obstack, '"');
6554 encode_field_decl (fields, curtype, format);
6557 obstack_1grow (&util_obstack, right);
6562 obstack_1grow (&util_obstack, left);
6563 if (name && TREE_CODE (name) == IDENTIFIER_NODE)
6564 obstack_grow (&util_obstack,
6565 IDENTIFIER_POINTER (name),
6566 strlen (IDENTIFIER_POINTER (name)));
6568 /* We have an untagged structure or a typedef. */
6569 obstack_1grow (&util_obstack, '?');
6571 obstack_1grow (&util_obstack, right);
6577 encode_aggregate (type, curtype, format)
6582 enum tree_code code = TREE_CODE (type);
6588 encode_aggregate_within(type, curtype, format, '{', '}');
6593 encode_aggregate_within(type, curtype, format, '(', ')');
6598 obstack_1grow (&util_obstack, 'i');
6606 /* Support bitfields. The current version of Objective-C does not support
6607 them. The string will consist of one or more "b:n"'s where n is an
6608 integer describing the width of the bitfield. Currently, classes in
6609 the kit implement a method "-(char *)describeBitfieldStruct:" that
6610 simulates this. If they do not implement this method, the archiver
6611 assumes the bitfield is 16 bits wide (padded if necessary) and packed
6612 according to the GNU compiler. After looking at the "kit", it appears
6613 that all classes currently rely on this default behavior, rather than
6614 hand generating this string (which is tedious). */
6617 encode_bitfield (width)
6621 sprintf (buffer, "b%d", width);
6622 obstack_grow (&util_obstack, buffer, strlen (buffer));
6625 /* FORMAT will be OBJC_ENCODE_INLINE_DEFS or OBJC_ENCODE_DONT_INLINE_DEFS. */
6628 encode_type (type, curtype, format)
6633 enum tree_code code = TREE_CODE (type);
6635 if (code == INTEGER_TYPE)
6637 if (integer_zerop (TYPE_MIN_VALUE (type)))
6639 /* Unsigned integer types. */
6641 if (TYPE_MODE (type) == QImode)
6642 obstack_1grow (&util_obstack, 'C');
6643 else if (TYPE_MODE (type) == HImode)
6644 obstack_1grow (&util_obstack, 'S');
6645 else if (TYPE_MODE (type) == SImode)
6647 if (type == long_unsigned_type_node)
6648 obstack_1grow (&util_obstack, 'L');
6650 obstack_1grow (&util_obstack, 'I');
6652 else if (TYPE_MODE (type) == DImode)
6653 obstack_1grow (&util_obstack, 'Q');
6657 /* Signed integer types. */
6659 if (TYPE_MODE (type) == QImode)
6660 obstack_1grow (&util_obstack, 'c');
6661 else if (TYPE_MODE (type) == HImode)
6662 obstack_1grow (&util_obstack, 's');
6663 else if (TYPE_MODE (type) == SImode)
6665 if (type == long_integer_type_node)
6666 obstack_1grow (&util_obstack, 'l');
6668 obstack_1grow (&util_obstack, 'i');
6671 else if (TYPE_MODE (type) == DImode)
6672 obstack_1grow (&util_obstack, 'q');
6676 else if (code == REAL_TYPE)
6678 /* Floating point types. */
6680 if (TYPE_MODE (type) == SFmode)
6681 obstack_1grow (&util_obstack, 'f');
6682 else if (TYPE_MODE (type) == DFmode
6683 || TYPE_MODE (type) == TFmode)
6684 obstack_1grow (&util_obstack, 'd');
6687 else if (code == VOID_TYPE)
6688 obstack_1grow (&util_obstack, 'v');
6690 else if (code == ARRAY_TYPE)
6691 encode_array (type, curtype, format);
6693 else if (code == POINTER_TYPE)
6694 encode_pointer (type, curtype, format);
6696 else if (code == RECORD_TYPE || code == UNION_TYPE || code == ENUMERAL_TYPE)
6697 encode_aggregate (type, curtype, format);
6699 else if (code == FUNCTION_TYPE) /* '?' */
6700 obstack_1grow (&util_obstack, '?');
6704 encode_complete_bitfield (int position, tree type, int size)
6706 enum tree_code code = TREE_CODE (type);
6708 char charType = '?';
6710 if (code == INTEGER_TYPE)
6712 if (integer_zerop (TYPE_MIN_VALUE (type)))
6714 /* Unsigned integer types. */
6716 if (TYPE_MODE (type) == QImode)
6718 else if (TYPE_MODE (type) == HImode)
6720 else if (TYPE_MODE (type) == SImode)
6722 if (type == long_unsigned_type_node)
6727 else if (TYPE_MODE (type) == DImode)
6732 /* Signed integer types. */
6734 if (TYPE_MODE (type) == QImode)
6736 else if (TYPE_MODE (type) == HImode)
6738 else if (TYPE_MODE (type) == SImode)
6740 if (type == long_integer_type_node)
6746 else if (TYPE_MODE (type) == DImode)
6750 else if (code == ENUMERAL_TYPE)
6755 sprintf (buffer, "b%d%c%d", position, charType, size);
6756 obstack_grow (&util_obstack, buffer, strlen (buffer));
6760 encode_field_decl (field_decl, curtype, format)
6767 type = TREE_TYPE (field_decl);
6769 /* If this field is obviously a bitfield, or is a bitfield that has been
6770 clobbered to look like a ordinary integer mode, go ahead and generate
6771 the bitfield typing information. */
6772 if (flag_next_runtime)
6774 if (DECL_BIT_FIELD (field_decl))
6775 encode_bitfield (tree_low_cst (DECL_SIZE (field_decl), 1));
6777 encode_type (TREE_TYPE (field_decl), curtype, format);
6781 if (DECL_BIT_FIELD (field_decl))
6782 encode_complete_bitfield (int_bit_position (field_decl),
6783 DECL_BIT_FIELD_TYPE (field_decl),
6784 tree_low_cst (DECL_SIZE (field_decl), 1));
6786 encode_type (TREE_TYPE (field_decl), curtype, format);
6791 expr_last (complex_expr)
6797 while ((next = TREE_OPERAND (complex_expr, 0)))
6798 complex_expr = next;
6800 return complex_expr;
6803 /* Transform a method definition into a function definition as follows:
6804 - synthesize the first two arguments, "self" and "_cmd". */
6807 start_method_def (method)
6812 /* Required to implement _msgSuper. */
6813 objc_method_context = method;
6814 UOBJC_SUPER_decl = NULL_TREE;
6816 /* Must be called BEFORE start_function. */
6819 /* Generate prototype declarations for arguments..."new-style". */
6821 if (TREE_CODE (objc_method_context) == INSTANCE_METHOD_DECL)
6822 decl_specs = build_tree_list (NULL_TREE, uprivate_record);
6824 /* Really a `struct objc_class *'. However, we allow people to
6825 assign to self, which changes its type midstream. */
6826 decl_specs = build_tree_list (NULL_TREE, objc_object_reference);
6828 push_parm_decl (build_tree_list
6829 (build_tree_list (decl_specs,
6830 build1 (INDIRECT_REF, NULL_TREE, self_id)),
6833 decl_specs = build_tree_list (NULL_TREE,
6834 xref_tag (RECORD_TYPE,
6835 get_identifier (TAG_SELECTOR)));
6836 push_parm_decl (build_tree_list
6837 (build_tree_list (decl_specs,
6838 build1 (INDIRECT_REF, NULL_TREE, ucmd_id)),
6841 /* Generate argument declarations if a keyword_decl. */
6842 if (METHOD_SEL_ARGS (method))
6844 tree arglist = METHOD_SEL_ARGS (method);
6847 tree arg_spec = TREE_PURPOSE (TREE_TYPE (arglist));
6848 tree arg_decl = TREE_VALUE (TREE_TYPE (arglist));
6852 tree last_expr = expr_last (arg_decl);
6854 /* Unite the abstract decl with its name. */
6855 TREE_OPERAND (last_expr, 0) = KEYWORD_ARG_NAME (arglist);
6856 push_parm_decl (build_tree_list
6857 (build_tree_list (arg_spec, arg_decl),
6860 /* Unhook: restore the abstract declarator. */
6861 TREE_OPERAND (last_expr, 0) = NULL_TREE;
6865 push_parm_decl (build_tree_list
6866 (build_tree_list (arg_spec,
6867 KEYWORD_ARG_NAME (arglist)),
6870 arglist = TREE_CHAIN (arglist);
6875 if (METHOD_ADD_ARGS (method) != NULL_TREE
6876 && METHOD_ADD_ARGS (method) != objc_ellipsis_node)
6878 /* We have a variable length selector - in "prototype" format. */
6879 tree akey = TREE_PURPOSE (METHOD_ADD_ARGS (method));
6882 /* This must be done prior to calling pushdecl. pushdecl is
6883 going to change our chain on us. */
6884 tree nextkey = TREE_CHAIN (akey);
6892 warn_with_method (message, mtype, method)
6893 const char *message;
6897 if (count_error (1) == 0)
6900 report_error_function (DECL_SOURCE_FILE (method));
6902 /* Add a readable method name to the warning. */
6903 warning_with_file_and_line (DECL_SOURCE_FILE (method),
6904 DECL_SOURCE_LINE (method),
6907 gen_method_decl (method, errbuf));
6910 /* Return 1 if METHOD is consistent with PROTO. */
6913 comp_method_with_proto (method, proto)
6916 /* Create a function template node at most once. */
6917 if (!function1_template)
6918 function1_template = make_node (FUNCTION_TYPE);
6920 /* Install argument types - normally set by build_function_type. */
6921 TYPE_ARG_TYPES (function1_template) = get_arg_type_list (proto, METHOD_DEF, 0);
6923 /* install return type */
6924 TREE_TYPE (function1_template) = groktypename (TREE_TYPE (proto));
6926 return comptypes (TREE_TYPE (METHOD_DEFINITION (method)), function1_template);
6929 /* Return 1 if PROTO1 is consistent with PROTO2. */
6932 comp_proto_with_proto (proto0, proto1)
6933 tree proto0, proto1;
6935 /* Create a couple of function_template nodes at most once. */
6936 if (!function1_template)
6937 function1_template = make_node (FUNCTION_TYPE);
6938 if (!function2_template)
6939 function2_template = make_node (FUNCTION_TYPE);
6941 /* Install argument types; normally set by build_function_type. */
6942 TYPE_ARG_TYPES (function1_template) = get_arg_type_list (proto0, METHOD_REF, 0);
6943 TYPE_ARG_TYPES (function2_template) = get_arg_type_list (proto1, METHOD_REF, 0);
6945 /* Install return type. */
6946 TREE_TYPE (function1_template) = groktypename (TREE_TYPE (proto0));
6947 TREE_TYPE (function2_template) = groktypename (TREE_TYPE (proto1));
6949 return comptypes (function1_template, function2_template);
6952 /* - Generate an identifier for the function. the format is "_n_cls",
6953 where 1 <= n <= nMethods, and cls is the name the implementation we
6955 - Install the return type from the method declaration.
6956 - If we have a prototype, check for type consistency. */
6959 really_start_method (method, parmlist)
6960 tree method, parmlist;
6962 tree sc_spec, ret_spec, ret_decl, decl_specs;
6963 tree method_decl, method_id;
6964 const char *sel_name, *class_name, *cat_name;
6967 /* Synth the storage class & assemble the return type. */
6968 sc_spec = tree_cons (NULL_TREE, ridpointers[(int) RID_STATIC], NULL_TREE);
6969 ret_spec = TREE_PURPOSE (TREE_TYPE (method));
6970 decl_specs = chainon (sc_spec, ret_spec);
6972 sel_name = IDENTIFIER_POINTER (METHOD_SEL_NAME (method));
6973 class_name = IDENTIFIER_POINTER (CLASS_NAME (objc_implementation_context));
6974 cat_name = ((TREE_CODE (objc_implementation_context)
6975 == CLASS_IMPLEMENTATION_TYPE)
6977 : IDENTIFIER_POINTER (CLASS_SUPER_NAME (objc_implementation_context)));
6980 /* Make sure this is big enough for any plausible method label. */
6981 buf = (char *) alloca (50 + strlen (sel_name) + strlen (class_name)
6982 + (cat_name ? strlen (cat_name) : 0));
6984 OBJC_GEN_METHOD_LABEL (buf, TREE_CODE (method) == INSTANCE_METHOD_DECL,
6985 class_name, cat_name, sel_name, method_slot);
6987 method_id = get_identifier (buf);
6989 method_decl = build_nt (CALL_EXPR, method_id, parmlist, NULL_TREE);
6991 /* Check the declarator portion of the return type for the method. */
6992 if ((ret_decl = TREE_VALUE (TREE_TYPE (method))))
6994 /* Unite the complex decl (specified in the abstract decl) with the
6995 function decl just synthesized..(int *), (int (*)()), (int (*)[]). */
6996 tree save_expr = expr_last (ret_decl);
6998 TREE_OPERAND (save_expr, 0) = method_decl;
6999 method_decl = ret_decl;
7001 /* Fool the parser into thinking it is starting a function. */
7002 start_function (decl_specs, method_decl, NULL_TREE);
7004 /* Unhook: this has the effect of restoring the abstract declarator. */
7005 TREE_OPERAND (save_expr, 0) = NULL_TREE;
7010 TREE_VALUE (TREE_TYPE (method)) = method_decl;
7012 /* Fool the parser into thinking it is starting a function. */
7013 start_function (decl_specs, method_decl, NULL_TREE);
7015 /* Unhook: this has the effect of restoring the abstract declarator. */
7016 TREE_VALUE (TREE_TYPE (method)) = NULL_TREE;
7019 METHOD_DEFINITION (method) = current_function_decl;
7021 /* Check consistency...start_function, pushdecl, duplicate_decls. */
7023 if (implementation_template != objc_implementation_context)
7027 if (TREE_CODE (method) == INSTANCE_METHOD_DECL)
7028 proto = lookup_instance_method_static (implementation_template,
7029 METHOD_SEL_NAME (method));
7031 proto = lookup_class_method_static (implementation_template,
7032 METHOD_SEL_NAME (method));
7034 if (proto && ! comp_method_with_proto (method, proto))
7036 char type = (TREE_CODE (method) == INSTANCE_METHOD_DECL ? '-' : '+');
7038 warn_with_method ("conflicting types for", type, method);
7039 warn_with_method ("previous declaration of", type, proto);
7044 /* The following routine is always called...this "architecture" is to
7045 accommodate "old-style" variable length selectors.
7047 - a:a b:b // prototype ; id c; id d; // old-style. */
7050 continue_method_def ()
7054 if (METHOD_ADD_ARGS (objc_method_context) == objc_ellipsis_node)
7055 /* We have a `, ...' immediately following the selector. */
7056 parmlist = get_parm_info (0);
7058 parmlist = get_parm_info (1); /* place a `void_at_end' */
7060 /* Set self_decl from the first argument...this global is used by
7061 build_ivar_reference calling build_indirect_ref. */
7062 self_decl = TREE_PURPOSE (parmlist);
7065 really_start_method (objc_method_context, parmlist);
7066 store_parm_decls ();
7069 /* Called by the parser, from the `pushlevel' production. */
7074 if (!UOBJC_SUPER_decl)
7076 UOBJC_SUPER_decl = start_decl (get_identifier (UTAG_SUPER),
7077 build_tree_list (NULL_TREE,
7078 objc_super_template),
7081 finish_decl (UOBJC_SUPER_decl, NULL_TREE, NULL_TREE);
7083 /* This prevents `unused variable' warnings when compiling with -Wall. */
7084 TREE_USED (UOBJC_SUPER_decl) = 1;
7085 DECL_ARTIFICIAL (UOBJC_SUPER_decl) = 1;
7089 /* _n_Method (id self, SEL sel, ...)
7091 struct objc_super _S;
7092 _msgSuper ((_S.self = self, _S.class = _cls, &_S), ...);
7096 get_super_receiver ()
7098 if (objc_method_context)
7100 tree super_expr, super_expr_list;
7102 /* Set receiver to self. */
7103 super_expr = build_component_ref (UOBJC_SUPER_decl, self_id);
7104 super_expr = build_modify_expr (super_expr, NOP_EXPR, self_decl);
7105 super_expr_list = build_tree_list (NULL_TREE, super_expr);
7107 /* Set class to begin searching. */
7108 super_expr = build_component_ref (UOBJC_SUPER_decl,
7109 get_identifier ("class"));
7111 if (TREE_CODE (objc_implementation_context) == CLASS_IMPLEMENTATION_TYPE)
7113 /* [_cls, __cls]Super are "pre-built" in
7114 synth_forward_declarations. */
7116 super_expr = build_modify_expr (super_expr, NOP_EXPR,
7117 ((TREE_CODE (objc_method_context)
7118 == INSTANCE_METHOD_DECL)
7120 : uucls_super_ref));
7124 /* We have a category. */
7126 tree super_name = CLASS_SUPER_NAME (implementation_template);
7129 /* Barf if super used in a category of Object. */
7132 error ("no super class declared in interface for `%s'",
7133 IDENTIFIER_POINTER (CLASS_NAME (implementation_template)));
7134 return error_mark_node;
7137 if (flag_next_runtime)
7139 super_class = get_class_reference (super_name);
7140 if (TREE_CODE (objc_method_context) == CLASS_METHOD_DECL)
7142 = build_component_ref (build_indirect_ref (super_class, "->"),
7143 get_identifier ("isa"));
7147 add_class_reference (super_name);
7148 super_class = (TREE_CODE (objc_method_context) == INSTANCE_METHOD_DECL
7149 ? objc_get_class_decl : objc_get_meta_class_decl);
7150 assemble_external (super_class);
7152 = build_function_call
7156 my_build_string (IDENTIFIER_LENGTH (super_name) + 1,
7157 IDENTIFIER_POINTER (super_name))));
7160 TREE_TYPE (super_class) = TREE_TYPE (ucls_super_ref);
7161 super_expr = build_modify_expr (super_expr, NOP_EXPR, super_class);
7164 chainon (super_expr_list, build_tree_list (NULL_TREE, super_expr));
7166 super_expr = build_unary_op (ADDR_EXPR, UOBJC_SUPER_decl, 0);
7167 chainon (super_expr_list, build_tree_list (NULL_TREE, super_expr));
7169 return build_compound_expr (super_expr_list);
7173 error ("[super ...] must appear in a method context");
7174 return error_mark_node;
7179 encode_method_def (func_decl)
7184 HOST_WIDE_INT max_parm_end = 0;
7189 encode_type (TREE_TYPE (TREE_TYPE (func_decl)),
7190 obstack_object_size (&util_obstack),
7191 OBJC_ENCODE_INLINE_DEFS);
7194 for (parms = DECL_ARGUMENTS (func_decl); parms;
7195 parms = TREE_CHAIN (parms))
7197 HOST_WIDE_INT parm_end = (forwarding_offset (parms)
7198 + int_size_in_bytes (TREE_TYPE (parms)));
7200 if (! offset_is_register && parm_end > max_parm_end)
7201 max_parm_end = parm_end;
7204 stack_size = max_parm_end - OBJC_FORWARDING_MIN_OFFSET;
7206 sprintf (buffer, "%d", stack_size);
7207 obstack_grow (&util_obstack, buffer, strlen (buffer));
7209 /* Argument types. */
7210 for (parms = DECL_ARGUMENTS (func_decl); parms;
7211 parms = TREE_CHAIN (parms))
7214 encode_type (TREE_TYPE (parms),
7215 obstack_object_size (&util_obstack),
7216 OBJC_ENCODE_INLINE_DEFS);
7218 /* Compute offset. */
7219 sprintf (buffer, "%d", forwarding_offset (parms));
7221 /* Indicate register. */
7222 if (offset_is_register)
7223 obstack_1grow (&util_obstack, '+');
7225 obstack_grow (&util_obstack, buffer, strlen (buffer));
7228 /* Null terminate string. */
7229 obstack_1grow (&util_obstack, 0);
7230 result = get_identifier (obstack_finish (&util_obstack));
7231 obstack_free (&util_obstack, util_firstobj);
7236 objc_expand_function_end ()
7238 METHOD_ENCODING (objc_method_context) = encode_method_def (current_function_decl);
7242 finish_method_def ()
7244 lang_expand_function_end = objc_expand_function_end;
7245 finish_function (0, 1);
7246 lang_expand_function_end = NULL;
7248 /* Required to implement _msgSuper. This must be done AFTER finish_function,
7249 since the optimizer may find "may be used before set" errors. */
7250 objc_method_context = NULL_TREE;
7255 lang_report_error_function (decl)
7258 if (objc_method_context)
7260 fprintf (stderr, "In method `%s'\n",
7261 IDENTIFIER_POINTER (METHOD_SEL_NAME (objc_method_context)));
7271 is_complex_decl (type)
7274 return (TREE_CODE (type) == ARRAY_TYPE
7275 || TREE_CODE (type) == FUNCTION_TYPE
7276 || (TREE_CODE (type) == POINTER_TYPE && ! IS_ID (type)));
7280 /* Code to convert a decl node into text for a declaration in C. */
7282 static char tmpbuf[256];
7285 adorn_decl (decl, str)
7289 enum tree_code code = TREE_CODE (decl);
7291 if (code == ARRAY_REF)
7293 tree an_int_cst = TREE_OPERAND (decl, 1);
7295 if (an_int_cst && TREE_CODE (an_int_cst) == INTEGER_CST)
7296 sprintf (str + strlen (str), "[%ld]",
7297 (long) TREE_INT_CST_LOW (an_int_cst));
7302 else if (code == ARRAY_TYPE)
7304 tree an_int_cst = TYPE_SIZE (decl);
7305 tree array_of = TREE_TYPE (decl);
7307 if (an_int_cst && TREE_CODE (an_int_cst) == INTEGER_TYPE)
7308 sprintf (str + strlen (str), "[%ld]",
7309 (long) (TREE_INT_CST_LOW (an_int_cst)
7310 / TREE_INT_CST_LOW (TYPE_SIZE (array_of))));
7315 else if (code == CALL_EXPR)
7317 tree chain = TREE_PURPOSE (TREE_OPERAND (decl, 1));
7322 gen_declaration_1 (chain, str);
7323 chain = TREE_CHAIN (chain);
7330 else if (code == FUNCTION_TYPE)
7332 tree chain = TYPE_ARG_TYPES (decl);
7335 while (chain && TREE_VALUE (chain) != void_type_node)
7337 gen_declaration_1 (TREE_VALUE (chain), str);
7338 chain = TREE_CHAIN (chain);
7339 if (chain && TREE_VALUE (chain) != void_type_node)
7345 else if (code == INDIRECT_REF)
7347 strcpy (tmpbuf, "*");
7348 if (TREE_TYPE (decl) && TREE_CODE (TREE_TYPE (decl)) == TREE_LIST)
7352 for (chain = nreverse (copy_list (TREE_TYPE (decl)));
7354 chain = TREE_CHAIN (chain))
7356 if (TREE_CODE (TREE_VALUE (chain)) == IDENTIFIER_NODE)
7358 strcat (tmpbuf, " ");
7359 strcat (tmpbuf, IDENTIFIER_POINTER (TREE_VALUE (chain)));
7363 strcat (tmpbuf, " ");
7365 strcat (tmpbuf, str);
7366 strcpy (str, tmpbuf);
7369 else if (code == POINTER_TYPE)
7371 strcpy (tmpbuf, "*");
7372 if (TREE_READONLY (decl) || TYPE_VOLATILE (decl))
7374 if (TREE_READONLY (decl))
7375 strcat (tmpbuf, " const");
7376 if (TYPE_VOLATILE (decl))
7377 strcat (tmpbuf, " volatile");
7379 strcat (tmpbuf, " ");
7381 strcat (tmpbuf, str);
7382 strcpy (str, tmpbuf);
7387 gen_declarator (decl, buf, name)
7394 enum tree_code code = TREE_CODE (decl);
7404 op = TREE_OPERAND (decl, 0);
7406 /* We have a pointer to a function or array...(*)(), (*)[] */
7407 if ((code == ARRAY_REF || code == CALL_EXPR)
7408 && op && TREE_CODE (op) == INDIRECT_REF)
7411 str = gen_declarator (op, buf, name);
7415 strcpy (tmpbuf, "(");
7416 strcat (tmpbuf, str);
7417 strcat (tmpbuf, ")");
7418 strcpy (str, tmpbuf);
7421 adorn_decl (decl, str);
7430 /* This clause is done iteratively rather than recursively. */
7433 op = (is_complex_decl (TREE_TYPE (decl))
7434 ? TREE_TYPE (decl) : NULL_TREE);
7436 adorn_decl (decl, str);
7438 /* We have a pointer to a function or array...(*)(), (*)[] */
7439 if (code == POINTER_TYPE
7440 && op && (TREE_CODE (op) == FUNCTION_TYPE
7441 || TREE_CODE (op) == ARRAY_TYPE))
7443 strcpy (tmpbuf, "(");
7444 strcat (tmpbuf, str);
7445 strcat (tmpbuf, ")");
7446 strcpy (str, tmpbuf);
7449 decl = (is_complex_decl (TREE_TYPE (decl))
7450 ? TREE_TYPE (decl) : NULL_TREE);
7453 while (decl && (code = TREE_CODE (decl)))
7458 case IDENTIFIER_NODE:
7459 /* Will only happen if we are processing a "raw" expr-decl. */
7460 strcpy (buf, IDENTIFIER_POINTER (decl));
7471 /* We have an abstract declarator or a _DECL node. */
7479 gen_declspecs (declspecs, buf, raw)
7488 for (chain = nreverse (copy_list (declspecs));
7489 chain; chain = TREE_CHAIN (chain))
7491 tree aspec = TREE_VALUE (chain);
7493 if (TREE_CODE (aspec) == IDENTIFIER_NODE)
7494 strcat (buf, IDENTIFIER_POINTER (aspec));
7495 else if (TREE_CODE (aspec) == RECORD_TYPE)
7497 if (TYPE_NAME (aspec))
7499 tree protocol_list = TYPE_PROTOCOL_LIST (aspec);
7501 if (! TREE_STATIC_TEMPLATE (aspec))
7502 strcat (buf, "struct ");
7503 strcat (buf, IDENTIFIER_POINTER (TYPE_NAME (aspec)));
7508 tree chain = protocol_list;
7515 (PROTOCOL_NAME (TREE_VALUE (chain))));
7516 chain = TREE_CHAIN (chain);
7525 strcat (buf, "untagged struct");
7528 else if (TREE_CODE (aspec) == UNION_TYPE)
7530 if (TYPE_NAME (aspec))
7532 if (! TREE_STATIC_TEMPLATE (aspec))
7533 strcat (buf, "union ");
7534 strcat (buf, IDENTIFIER_POINTER (TYPE_NAME (aspec)));
7537 strcat (buf, "untagged union");
7540 else if (TREE_CODE (aspec) == ENUMERAL_TYPE)
7542 if (TYPE_NAME (aspec))
7544 if (! TREE_STATIC_TEMPLATE (aspec))
7545 strcat (buf, "enum ");
7546 strcat (buf, IDENTIFIER_POINTER (TYPE_NAME (aspec)));
7549 strcat (buf, "untagged enum");
7552 else if (TREE_CODE (aspec) == TYPE_DECL && DECL_NAME (aspec))
7553 strcat (buf, IDENTIFIER_POINTER (DECL_NAME (aspec)));
7555 else if (IS_ID (aspec))
7557 tree protocol_list = TYPE_PROTOCOL_LIST (aspec);
7562 tree chain = protocol_list;
7569 (PROTOCOL_NAME (TREE_VALUE (chain))));
7570 chain = TREE_CHAIN (chain);
7577 if (TREE_CHAIN (chain))
7583 /* Type qualifiers. */
7584 if (TREE_READONLY (declspecs))
7585 strcat (buf, "const ");
7586 if (TYPE_VOLATILE (declspecs))
7587 strcat (buf, "volatile ");
7589 switch (TREE_CODE (declspecs))
7591 /* Type specifiers. */
7594 declspecs = TYPE_MAIN_VARIANT (declspecs);
7596 /* Signed integer types. */
7598 if (declspecs == short_integer_type_node)
7599 strcat (buf, "short int ");
7600 else if (declspecs == integer_type_node)
7601 strcat (buf, "int ");
7602 else if (declspecs == long_integer_type_node)
7603 strcat (buf, "long int ");
7604 else if (declspecs == long_long_integer_type_node)
7605 strcat (buf, "long long int ");
7606 else if (declspecs == signed_char_type_node
7607 || declspecs == char_type_node)
7608 strcat (buf, "char ");
7610 /* Unsigned integer types. */
7612 else if (declspecs == short_unsigned_type_node)
7613 strcat (buf, "unsigned short ");
7614 else if (declspecs == unsigned_type_node)
7615 strcat (buf, "unsigned int ");
7616 else if (declspecs == long_unsigned_type_node)
7617 strcat (buf, "unsigned long ");
7618 else if (declspecs == long_long_unsigned_type_node)
7619 strcat (buf, "unsigned long long ");
7620 else if (declspecs == unsigned_char_type_node)
7621 strcat (buf, "unsigned char ");
7625 declspecs = TYPE_MAIN_VARIANT (declspecs);
7627 if (declspecs == float_type_node)
7628 strcat (buf, "float ");
7629 else if (declspecs == double_type_node)
7630 strcat (buf, "double ");
7631 else if (declspecs == long_double_type_node)
7632 strcat (buf, "long double ");
7636 if (TYPE_NAME (declspecs)
7637 && TREE_CODE (TYPE_NAME (declspecs)) == IDENTIFIER_NODE)
7639 tree protocol_list = TYPE_PROTOCOL_LIST (declspecs);
7641 if (! TREE_STATIC_TEMPLATE (declspecs))
7642 strcat (buf, "struct ");
7643 strcat (buf, IDENTIFIER_POINTER (TYPE_NAME (declspecs)));
7647 tree chain = protocol_list;
7654 (PROTOCOL_NAME (TREE_VALUE (chain))));
7655 chain = TREE_CHAIN (chain);
7664 strcat (buf, "untagged struct");
7670 if (TYPE_NAME (declspecs)
7671 && TREE_CODE (TYPE_NAME (declspecs)) == IDENTIFIER_NODE)
7673 strcat (buf, "union ");
7674 strcat (buf, IDENTIFIER_POINTER (TYPE_NAME (declspecs)));
7679 strcat (buf, "untagged union ");
7683 if (TYPE_NAME (declspecs)
7684 && TREE_CODE (TYPE_NAME (declspecs)) == IDENTIFIER_NODE)
7686 strcat (buf, "enum ");
7687 strcat (buf, IDENTIFIER_POINTER (TYPE_NAME (declspecs)));
7692 strcat (buf, "untagged enum ");
7696 strcat (buf, "void ");
7701 tree protocol_list = TYPE_PROTOCOL_LIST (declspecs);
7706 tree chain = protocol_list;
7713 (PROTOCOL_NAME (TREE_VALUE (chain))));
7714 chain = TREE_CHAIN (chain);
7730 /* Given a tree node, produce a printable description of it in the given
7731 buffer, overwriting the buffer. */
7734 gen_declaration (atype_or_adecl, buf)
7735 tree atype_or_adecl;
7739 gen_declaration_1 (atype_or_adecl, buf);
7743 /* Given a tree node, append a printable description to the end of the
7747 gen_declaration_1 (atype_or_adecl, buf)
7748 tree atype_or_adecl;
7753 if (TREE_CODE (atype_or_adecl) == TREE_LIST)
7755 tree declspecs; /* "identifier_node", "record_type" */
7756 tree declarator; /* "array_ref", "indirect_ref", "call_expr"... */
7758 /* We have a "raw", abstract declarator (typename). */
7759 declarator = TREE_VALUE (atype_or_adecl);
7760 declspecs = TREE_PURPOSE (atype_or_adecl);
7762 gen_declspecs (declspecs, buf, 1);
7766 strcat (buf, gen_declarator (declarator, declbuf, ""));
7773 tree declspecs; /* "integer_type", "real_type", "record_type"... */
7774 tree declarator; /* "array_type", "function_type", "pointer_type". */
7776 if (TREE_CODE (atype_or_adecl) == FIELD_DECL
7777 || TREE_CODE (atype_or_adecl) == PARM_DECL
7778 || TREE_CODE (atype_or_adecl) == FUNCTION_DECL)
7779 atype = TREE_TYPE (atype_or_adecl);
7781 /* Assume we have a *_type node. */
7782 atype = atype_or_adecl;
7784 if (is_complex_decl (atype))
7788 /* Get the declaration specifier; it is at the end of the list. */
7789 declarator = chain = atype;
7791 chain = TREE_TYPE (chain); /* not TREE_CHAIN (chain); */
7792 while (is_complex_decl (chain));
7799 declarator = NULL_TREE;
7802 gen_declspecs (declspecs, buf, 0);
7804 if (TREE_CODE (atype_or_adecl) == FIELD_DECL
7805 || TREE_CODE (atype_or_adecl) == PARM_DECL
7806 || TREE_CODE (atype_or_adecl) == FUNCTION_DECL)
7808 const char *const decl_name =
7809 (DECL_NAME (atype_or_adecl)
7810 ? IDENTIFIER_POINTER (DECL_NAME (atype_or_adecl)) : "");
7815 strcat (buf, gen_declarator (declarator, declbuf, decl_name));
7818 else if (decl_name[0])
7821 strcat (buf, decl_name);
7824 else if (declarator)
7827 strcat (buf, gen_declarator (declarator, declbuf, ""));
7832 #define RAW_TYPESPEC(meth) (TREE_VALUE (TREE_PURPOSE (TREE_TYPE (meth))))
7834 /* Given a method tree, put a printable description into the given
7835 buffer (overwriting) and return a pointer to the buffer. */
7838 gen_method_decl (method, buf)
7845 if (RAW_TYPESPEC (method) != objc_object_reference)
7848 gen_declaration_1 (TREE_TYPE (method), buf);
7852 chain = METHOD_SEL_ARGS (method);
7855 /* We have a chain of keyword_decls. */
7858 if (KEYWORD_KEY_NAME (chain))
7859 strcat (buf, IDENTIFIER_POINTER (KEYWORD_KEY_NAME (chain)));
7862 if (RAW_TYPESPEC (chain) != objc_object_reference)
7865 gen_declaration_1 (TREE_TYPE (chain), buf);
7869 strcat (buf, IDENTIFIER_POINTER (KEYWORD_ARG_NAME (chain)));
7870 if ((chain = TREE_CHAIN (chain)))
7875 if (METHOD_ADD_ARGS (method) == objc_ellipsis_node)
7876 strcat (buf, ", ...");
7877 else if (METHOD_ADD_ARGS (method))
7879 /* We have a tree list node as generate by get_parm_info. */
7880 chain = TREE_PURPOSE (METHOD_ADD_ARGS (method));
7882 /* Know we have a chain of parm_decls. */
7886 gen_declaration_1 (chain, buf);
7887 chain = TREE_CHAIN (chain);
7893 /* We have a unary selector. */
7894 strcat (buf, IDENTIFIER_POINTER (METHOD_SEL_NAME (method)));
7902 dump_interface (fp, chain)
7906 char *buf = (char *) xmalloc (256);
7907 const char *my_name = IDENTIFIER_POINTER (CLASS_NAME (chain));
7908 tree ivar_decls = CLASS_RAW_IVARS (chain);
7909 tree nst_methods = CLASS_NST_METHODS (chain);
7910 tree cls_methods = CLASS_CLS_METHODS (chain);
7912 fprintf (fp, "\n@interface %s", my_name);
7914 if (CLASS_SUPER_NAME (chain))
7916 const char *super_name = IDENTIFIER_POINTER (CLASS_SUPER_NAME (chain));
7917 fprintf (fp, " : %s\n", super_name);
7924 fprintf (fp, "{\n");
7927 fprintf (fp, "\t%s;\n", gen_declaration (ivar_decls, buf));
7928 ivar_decls = TREE_CHAIN (ivar_decls);
7931 fprintf (fp, "}\n");
7936 fprintf (fp, "- %s;\n", gen_method_decl (nst_methods, buf));
7937 nst_methods = TREE_CHAIN (nst_methods);
7942 fprintf (fp, "+ %s;\n", gen_method_decl (cls_methods, buf));
7943 cls_methods = TREE_CHAIN (cls_methods);
7945 fprintf (fp, "\n@end");
7948 /* Demangle function for Objective-C */
7950 objc_demangle (mangled)
7951 const char *mangled;
7953 char *demangled, *cp;
7955 if (mangled[0] == '_' &&
7956 (mangled[1] == 'i' || mangled[1] == 'c') &&
7959 cp = demangled = xmalloc(strlen(mangled) + 2);
7960 if (mangled[1] == 'i')
7961 *cp++ = '-'; /* for instance method */
7963 *cp++ = '+'; /* for class method */
7964 *cp++ = '['; /* opening left brace */
7965 strcpy(cp, mangled+3); /* tack on the rest of the mangled name */
7966 while (*cp && *cp == '_')
7967 cp++; /* skip any initial underbars in class name */
7968 cp = strchr(cp, '_'); /* find first non-initial underbar */
7971 free(demangled); /* not mangled name */
7974 if (cp[1] == '_') /* easy case: no category name */
7976 *cp++ = ' '; /* replace two '_' with one ' ' */
7977 strcpy(cp, mangled + (cp - demangled) + 2);
7981 *cp++ = '('; /* less easy case: category name */
7982 cp = strchr(cp, '_');
7985 free(demangled); /* not mangled name */
7989 *cp++ = ' '; /* overwriting 1st char of method name... */
7990 strcpy(cp, mangled + (cp - demangled)); /* get it back */
7992 while (*cp && *cp == '_')
7993 cp++; /* skip any initial underbars in method name */
7996 *cp = ':'; /* replace remaining '_' with ':' */
7997 *cp++ = ']'; /* closing right brace */
7998 *cp++ = 0; /* string terminator */
8002 return mangled; /* not an objc mangled name */
8006 objc_printable_name (decl, kind)
8008 int kind ATTRIBUTE_UNUSED;
8010 return objc_demangle (IDENTIFIER_POINTER (DECL_NAME (decl)));
8016 gcc_obstack_init (&util_obstack);
8017 util_firstobj = (char *) obstack_finish (&util_obstack);
8019 errbuf = (char *) xmalloc (BUFSIZE);
8021 synth_module_prologue ();
8027 struct imp_entry *impent;
8029 /* The internally generated initializers appear to have missing braces.
8030 Don't warn about this. */
8031 int save_warn_missing_braces = warn_missing_braces;
8032 warn_missing_braces = 0;
8034 /* A missing @end may not be detected by the parser. */
8035 if (objc_implementation_context)
8037 warning ("`@end' missing in implementation context");
8038 finish_class (objc_implementation_context);
8039 objc_ivar_chain = NULL_TREE;
8040 objc_implementation_context = NULL_TREE;
8043 generate_forward_declaration_to_string_table ();
8045 #ifdef OBJC_PROLOGUE
8049 /* Process the static instances here because initialization of objc_symtab
8051 if (objc_static_instances)
8052 generate_static_references ();
8054 if (imp_list || class_names_chain
8055 || meth_var_names_chain || meth_var_types_chain || sel_ref_chain)
8056 generate_objc_symtab_decl ();
8058 for (impent = imp_list; impent; impent = impent->next)
8060 objc_implementation_context = impent->imp_context;
8061 implementation_template = impent->imp_template;
8063 UOBJC_CLASS_decl = impent->class_decl;
8064 UOBJC_METACLASS_decl = impent->meta_decl;
8066 if (TREE_CODE (objc_implementation_context) == CLASS_IMPLEMENTATION_TYPE)
8068 /* all of the following reference the string pool... */
8069 generate_ivar_lists ();
8070 generate_dispatch_tables ();
8071 generate_shared_structures ();
8075 generate_dispatch_tables ();
8076 generate_category (objc_implementation_context);
8080 /* If we are using an array of selectors, we must always
8081 finish up the array decl even if no selectors were used. */
8082 if (! flag_next_runtime || sel_ref_chain)
8083 build_selector_translation_table ();
8086 generate_protocols ();
8088 if (objc_implementation_context || class_names_chain || objc_static_instances
8089 || meth_var_names_chain || meth_var_types_chain || sel_ref_chain)
8091 /* Arrange for ObjC data structures to be initialized at run time. */
8092 rtx init_sym = build_module_descriptor ();
8093 if (init_sym && targetm.have_ctors_dtors)
8094 (* targetm.asm_out.constructor) (init_sym, DEFAULT_INIT_PRIORITY);
8097 /* Dump the class references. This forces the appropriate classes
8098 to be linked into the executable image, preserving unix archive
8099 semantics. This can be removed when we move to a more dynamically
8100 linked environment. */
8102 for (chain = cls_ref_chain; chain; chain = TREE_CHAIN (chain))
8104 handle_class_ref (chain);
8105 if (TREE_PURPOSE (chain))
8106 generate_classref_translation_entry (chain);
8109 for (impent = imp_list; impent; impent = impent->next)
8110 handle_impent (impent);
8112 /* Dump the string table last. */
8114 generate_strings ();
8116 if (flag_gen_declaration)
8118 add_class (objc_implementation_context);
8119 dump_interface (gen_declaration_file, objc_implementation_context);
8127 /* Run through the selector hash tables and print a warning for any
8128 selector which has multiple methods. */
8130 for (slot = 0; slot < SIZEHASHTABLE; slot++)
8131 for (hsh = cls_method_hash_list[slot]; hsh; hsh = hsh->next)
8134 tree meth = hsh->key;
8135 char type = (TREE_CODE (meth) == INSTANCE_METHOD_DECL
8139 warning ("potential selector conflict for method `%s'",
8140 IDENTIFIER_POINTER (METHOD_SEL_NAME (meth)));
8141 warn_with_method ("found", type, meth);
8142 for (loop = hsh->list; loop; loop = loop->next)
8143 warn_with_method ("found", type, loop->value);
8146 for (slot = 0; slot < SIZEHASHTABLE; slot++)
8147 for (hsh = nst_method_hash_list[slot]; hsh; hsh = hsh->next)
8150 tree meth = hsh->key;
8151 char type = (TREE_CODE (meth) == INSTANCE_METHOD_DECL
8155 warning ("potential selector conflict for method `%s'",
8156 IDENTIFIER_POINTER (METHOD_SEL_NAME (meth)));
8157 warn_with_method ("found", type, meth);
8158 for (loop = hsh->list; loop; loop = loop->next)
8159 warn_with_method ("found", type, loop->value);
8163 warn_missing_braces = save_warn_missing_braces;
8166 /* Subroutines of finish_objc. */
8169 generate_classref_translation_entry (chain)
8172 tree expr, name, decl_specs, decl, sc_spec;
8175 type = TREE_TYPE (TREE_PURPOSE (chain));
8177 expr = add_objc_string (TREE_VALUE (chain), class_names);
8178 expr = build_c_cast (type, expr); /* cast! */
8180 name = DECL_NAME (TREE_PURPOSE (chain));
8182 sc_spec = build_tree_list (NULL_TREE, ridpointers[(int) RID_STATIC]);
8184 /* static struct objc_class * _OBJC_CLASS_REFERENCES_n = ...; */
8185 decl_specs = tree_cons (NULL_TREE, type, sc_spec);
8187 /* The decl that is returned from start_decl is the one that we
8188 forward declared in build_class_reference. */
8189 decl = start_decl (name, decl_specs, 1, NULL_TREE);
8190 DECL_CONTEXT (decl) = NULL_TREE;
8191 finish_decl (decl, expr, NULL_TREE);
8196 handle_class_ref (chain)
8199 const char *name = IDENTIFIER_POINTER (TREE_VALUE (chain));
8200 char *string = (char *) alloca (strlen (name) + 30);
8204 sprintf (string, "%sobjc_class_name_%s",
8205 (flag_next_runtime ? "." : "__"), name);
8207 #ifdef ASM_DECLARE_UNRESOLVED_REFERENCE
8208 if (flag_next_runtime)
8210 ASM_DECLARE_UNRESOLVED_REFERENCE (asm_out_file, string);
8215 /* Make a decl for this name, so we can use its address in a tree. */
8216 decl = build_decl (VAR_DECL, get_identifier (string), char_type_node);
8217 DECL_EXTERNAL (decl) = 1;
8218 TREE_PUBLIC (decl) = 1;
8221 rest_of_decl_compilation (decl, 0, 0, 0);
8223 /* Make a decl for the address. */
8224 sprintf (string, "%sobjc_class_ref_%s",
8225 (flag_next_runtime ? "." : "__"), name);
8226 exp = build1 (ADDR_EXPR, string_type_node, decl);
8227 decl = build_decl (VAR_DECL, get_identifier (string), string_type_node);
8228 DECL_INITIAL (decl) = exp;
8229 TREE_STATIC (decl) = 1;
8230 TREE_USED (decl) = 1;
8233 rest_of_decl_compilation (decl, 0, 0, 0);
8237 handle_impent (impent)
8238 struct imp_entry *impent;
8242 objc_implementation_context = impent->imp_context;
8243 implementation_template = impent->imp_template;
8245 if (TREE_CODE (impent->imp_context) == CLASS_IMPLEMENTATION_TYPE)
8247 const char *const class_name =
8248 IDENTIFIER_POINTER (CLASS_NAME (impent->imp_context));
8250 string = (char *) alloca (strlen (class_name) + 30);
8252 sprintf (string, "%sobjc_class_name_%s",
8253 (flag_next_runtime ? "." : "__"), class_name);
8255 else if (TREE_CODE (impent->imp_context) == CATEGORY_IMPLEMENTATION_TYPE)
8257 const char *const class_name =
8258 IDENTIFIER_POINTER (CLASS_NAME (impent->imp_context));
8259 const char *const class_super_name =
8260 IDENTIFIER_POINTER (CLASS_SUPER_NAME (impent->imp_context));
8262 string = (char *) alloca (strlen (class_name)
8263 + strlen (class_super_name) + 30);
8265 /* Do the same for categories. Even though no references to
8266 these symbols are generated automatically by the compiler, it
8267 gives you a handle to pull them into an archive by hand. */
8268 sprintf (string, "*%sobjc_category_name_%s_%s",
8269 (flag_next_runtime ? "." : "__"), class_name, class_super_name);
8274 #ifdef ASM_DECLARE_CLASS_REFERENCE
8275 if (flag_next_runtime)
8277 ASM_DECLARE_CLASS_REFERENCE (asm_out_file, string);
8285 init = build_int_2 (0, 0);
8286 TREE_TYPE (init) = c_common_type_for_size (BITS_PER_WORD, 1);
8287 decl = build_decl (VAR_DECL, get_identifier (string), TREE_TYPE (init));
8288 TREE_PUBLIC (decl) = 1;
8289 TREE_READONLY (decl) = 1;
8290 TREE_USED (decl) = 1;
8291 TREE_CONSTANT (decl) = 1;
8292 DECL_CONTEXT (decl) = 0;
8293 DECL_ARTIFICIAL (decl) = 1;
8294 DECL_INITIAL (decl) = init;
8295 assemble_variable (decl, 1, 0, 0);
8299 /* Look up ID as an instance variable. */
8301 lookup_objc_ivar (id)
8306 if (objc_receiver_context && !strcmp (IDENTIFIER_POINTER (id), "super"))
8307 /* we have a message to super */
8308 return get_super_receiver ();
8309 else if (objc_method_context && (decl = is_ivar (objc_ivar_chain, id)))
8311 if (is_private (decl))
8312 return error_mark_node;
8314 return build_ivar_reference (id);
8320 #include "gtype-objc.h"