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':
59 #include "diagnostic.h"
61 /* This is the default way of generating a method name. */
62 /* I am not sure it is really correct.
63 Perhaps there's a danger that it will make name conflicts
64 if method names contain underscores. -- rms. */
65 #ifndef OBJC_GEN_METHOD_LABEL
66 #define OBJC_GEN_METHOD_LABEL(BUF, IS_INST, CLASS_NAME, CAT_NAME, SEL_NAME, NUM) \
69 sprintf ((BUF), "_%s_%s_%s_%s", \
70 ((IS_INST) ? "i" : "c"), \
72 ((CAT_NAME)? (CAT_NAME) : ""), \
74 for (temp = (BUF); *temp; temp++) \
75 if (*temp == ':') *temp = '_'; \
79 /* These need specifying. */
80 #ifndef OBJC_FORWARDING_STACK_OFFSET
81 #define OBJC_FORWARDING_STACK_OFFSET 0
84 #ifndef OBJC_FORWARDING_MIN_OFFSET
85 #define OBJC_FORWARDING_MIN_OFFSET 0
89 /* Set up for use of obstacks. */
93 /* This obstack is used to accumulate the encoding of a data type. */
94 static struct obstack util_obstack;
95 /* This points to the beginning of obstack contents,
96 so we can free the whole contents. */
99 /* for encode_method_def */
102 /* The version identifies which language generation and runtime
103 the module (file) was compiled for, and is recorded in the
104 module descriptor. */
106 #define OBJC_VERSION (flag_next_runtime ? 5 : 8)
107 #define PROTOCOL_VERSION 2
109 /* (Decide if these can ever be validly changed.) */
110 #define OBJC_ENCODE_INLINE_DEFS 0
111 #define OBJC_ENCODE_DONT_INLINE_DEFS 1
113 /*** Private Interface (procedures) ***/
115 /* Used by compile_file. */
117 static void init_objc PARAMS ((void));
118 static void finish_objc PARAMS ((void));
120 /* Code generation. */
122 static void synth_module_prologue PARAMS ((void));
123 static tree build_constructor PARAMS ((tree, tree));
124 static rtx build_module_descriptor PARAMS ((void));
125 static tree init_module_descriptor PARAMS ((tree));
126 static tree build_objc_method_call PARAMS ((int, tree, tree,
128 static void generate_strings PARAMS ((void));
129 static tree get_proto_encoding PARAMS ((tree));
130 static void build_selector_translation_table PARAMS ((void));
132 static tree objc_add_static_instance PARAMS ((tree, tree));
134 static tree build_ivar_template PARAMS ((void));
135 static tree build_method_template PARAMS ((void));
136 static tree build_private_template PARAMS ((tree));
137 static void build_class_template PARAMS ((void));
138 static void build_selector_template PARAMS ((void));
139 static void build_category_template PARAMS ((void));
140 static tree build_super_template PARAMS ((void));
141 static tree build_category_initializer PARAMS ((tree, tree, tree,
143 static tree build_protocol_initializer PARAMS ((tree, tree, tree,
146 static void synth_forward_declarations PARAMS ((void));
147 static void generate_ivar_lists PARAMS ((void));
148 static void generate_dispatch_tables PARAMS ((void));
149 static void generate_shared_structures PARAMS ((void));
150 static tree generate_protocol_list PARAMS ((tree));
151 static void generate_forward_declaration_to_string_table PARAMS ((void));
152 static void build_protocol_reference PARAMS ((tree));
154 static tree build_keyword_selector PARAMS ((tree));
155 static tree synth_id_with_class_suffix PARAMS ((const char *, tree));
157 static void generate_static_references PARAMS ((void));
158 static int check_methods_accessible PARAMS ((tree, tree,
160 static void encode_aggregate_within PARAMS ((tree, int, int,
162 static const char *objc_demangle PARAMS ((const char *));
163 static void objc_expand_function_end PARAMS ((void));
165 /* Hash tables to manage the global pool of method prototypes. */
167 hash *nst_method_hash_list = 0;
168 hash *cls_method_hash_list = 0;
170 static size_t hash_func PARAMS ((tree));
171 static void hash_init PARAMS ((void));
172 static void hash_enter PARAMS ((hash *, tree));
173 static hash hash_lookup PARAMS ((hash *, tree));
174 static void hash_add_attr PARAMS ((hash, tree));
175 static tree lookup_method PARAMS ((tree, tree));
176 static tree lookup_instance_method_static PARAMS ((tree, tree));
177 static tree lookup_class_method_static PARAMS ((tree, tree));
178 static tree add_class PARAMS ((tree));
179 static void add_category PARAMS ((tree, tree));
183 class_names, /* class, category, protocol, module names */
184 meth_var_names, /* method and variable names */
185 meth_var_types /* method and variable type descriptors */
188 static tree add_objc_string PARAMS ((tree,
189 enum string_section));
190 static tree get_objc_string_decl PARAMS ((tree,
191 enum string_section));
192 static tree build_objc_string_decl PARAMS ((enum string_section));
193 static tree build_selector_reference_decl PARAMS ((void));
195 /* Protocol additions. */
197 static tree add_protocol PARAMS ((tree));
198 static tree lookup_protocol PARAMS ((tree));
199 static void check_protocol_recursively PARAMS ((tree, tree));
200 static tree lookup_and_install_protocols PARAMS ((tree));
204 static void encode_type_qualifiers PARAMS ((tree));
205 static void encode_pointer PARAMS ((tree, int, int));
206 static void encode_array PARAMS ((tree, int, int));
207 static void encode_aggregate PARAMS ((tree, int, int));
208 static void encode_bitfield PARAMS ((int));
209 static void encode_type PARAMS ((tree, int, int));
210 static void encode_field_decl PARAMS ((tree, int, int));
212 static void really_start_method PARAMS ((tree, tree));
213 static int comp_method_with_proto PARAMS ((tree, tree));
214 static int comp_proto_with_proto PARAMS ((tree, tree));
215 static tree get_arg_type_list PARAMS ((tree, int, int));
216 static tree expr_last PARAMS ((tree));
218 /* Utilities for debugging and error diagnostics. */
220 static void warn_with_method PARAMS ((const char *, int, tree));
221 static void error_with_ivar PARAMS ((const char *, tree, tree));
222 static char *gen_method_decl PARAMS ((tree, char *));
223 static char *gen_declaration PARAMS ((tree, char *));
224 static void gen_declaration_1 PARAMS ((tree, char *));
225 static char *gen_declarator PARAMS ((tree, char *,
227 static int is_complex_decl PARAMS ((tree));
228 static void adorn_decl PARAMS ((tree, char *));
229 static void dump_interface PARAMS ((FILE *, tree));
231 /* Everything else. */
233 static tree define_decl PARAMS ((tree, tree));
234 static tree lookup_method_in_protocol_list PARAMS ((tree, tree, int));
235 static tree lookup_protocol_in_reflist PARAMS ((tree, tree));
236 static tree create_builtin_decl PARAMS ((enum tree_code,
237 tree, const char *));
238 static void setup_string_decl PARAMS ((void));
239 static void build_string_class_template PARAMS ((void));
240 static tree my_build_string PARAMS ((int, const char *));
241 static void build_objc_symtab_template PARAMS ((void));
242 static tree init_def_list PARAMS ((tree));
243 static tree init_objc_symtab PARAMS ((tree));
244 static void forward_declare_categories PARAMS ((void));
245 static void generate_objc_symtab_decl PARAMS ((void));
246 static tree build_selector PARAMS ((tree));
247 static tree build_typed_selector_reference PARAMS ((tree, tree));
248 static tree build_selector_reference PARAMS ((tree));
249 static tree build_class_reference_decl PARAMS ((void));
250 static void add_class_reference PARAMS ((tree));
251 static tree build_protocol_template PARAMS ((void));
252 static tree build_descriptor_table_initializer PARAMS ((tree, tree));
253 static tree build_method_prototype_list_template PARAMS ((tree, int));
254 static tree build_method_prototype_template PARAMS ((void));
255 static int forwarding_offset PARAMS ((tree));
256 static tree encode_method_prototype PARAMS ((tree, tree));
257 static tree generate_descriptor_table PARAMS ((tree, const char *,
259 static void generate_method_descriptors PARAMS ((tree));
260 static tree build_tmp_function_decl PARAMS ((void));
261 static void hack_method_prototype PARAMS ((tree, tree));
262 static void generate_protocol_references PARAMS ((tree));
263 static void generate_protocols PARAMS ((void));
264 static void check_ivars PARAMS ((tree, tree));
265 static tree build_ivar_list_template PARAMS ((tree, int));
266 static tree build_method_list_template PARAMS ((tree, int));
267 static tree build_ivar_list_initializer PARAMS ((tree, tree));
268 static tree generate_ivars_list PARAMS ((tree, const char *,
270 static tree build_dispatch_table_initializer PARAMS ((tree, tree));
271 static tree generate_dispatch_table PARAMS ((tree, const char *,
273 static tree build_shared_structure_initializer PARAMS ((tree, tree, tree, tree,
274 tree, int, tree, tree,
276 static void generate_category PARAMS ((tree));
277 static int is_objc_type_qualifier PARAMS ((tree));
278 static tree adjust_type_for_id_default PARAMS ((tree));
279 static tree check_duplicates PARAMS ((hash));
280 static tree receiver_is_class_object PARAMS ((tree));
281 static int check_methods PARAMS ((tree, tree, int));
282 static int conforms_to_protocol PARAMS ((tree, tree));
283 static void check_protocol PARAMS ((tree, const char *,
285 static void check_protocols PARAMS ((tree, const char *,
287 static tree encode_method_def PARAMS ((tree));
288 static void gen_declspecs PARAMS ((tree, char *, int));
289 static void generate_classref_translation_entry PARAMS ((tree));
290 static void handle_class_ref PARAMS ((tree));
291 static void generate_struct_by_value_array PARAMS ((void))
293 static void encode_complete_bitfield PARAMS ((int, tree, int));
295 /*** Private Interface (data) ***/
297 /* Reserved tag definitions. */
300 #define TAG_OBJECT "objc_object"
301 #define TAG_CLASS "objc_class"
302 #define TAG_SUPER "objc_super"
303 #define TAG_SELECTOR "objc_selector"
305 #define UTAG_CLASS "_objc_class"
306 #define UTAG_IVAR "_objc_ivar"
307 #define UTAG_IVAR_LIST "_objc_ivar_list"
308 #define UTAG_METHOD "_objc_method"
309 #define UTAG_METHOD_LIST "_objc_method_list"
310 #define UTAG_CATEGORY "_objc_category"
311 #define UTAG_MODULE "_objc_module"
312 #define UTAG_SYMTAB "_objc_symtab"
313 #define UTAG_SUPER "_objc_super"
314 #define UTAG_SELECTOR "_objc_selector"
316 #define UTAG_PROTOCOL "_objc_protocol"
317 #define UTAG_METHOD_PROTOTYPE "_objc_method_prototype"
318 #define UTAG_METHOD_PROTOTYPE_LIST "_objc__method_prototype_list"
320 /* Note that the string object global name is only needed for the
322 #define STRING_OBJECT_GLOBAL_NAME "_NSConstantStringClassReference"
324 #define PROTOCOL_OBJECT_CLASS_NAME "Protocol"
326 static const char *TAG_GETCLASS;
327 static const char *TAG_GETMETACLASS;
328 static const char *TAG_MSGSEND;
329 static const char *TAG_MSGSENDSUPER;
330 static const char *TAG_EXECCLASS;
331 static const char *default_constant_string_class_name;
333 /* The OCTI_... enumeration itself is in objc/objc-act.h. */
334 tree objc_global_trees[OCTI_MAX];
336 static void handle_impent PARAMS ((struct imp_entry *));
338 struct imp_entry *imp_list = 0;
339 int imp_count = 0; /* `@implementation' */
340 int cat_count = 0; /* `@category' */
342 static int method_slot = 0; /* Used by start_method_def, */
346 static char *errbuf; /* Buffer for error diagnostics */
348 /* Data imported from tree.c. */
350 extern enum debug_info_type write_symbols;
352 /* Data imported from toplev.c. */
354 extern const char *dump_base_name;
356 static int flag_typed_selectors;
358 FILE *gen_declaration_file;
360 /* Tells "encode_pointer/encode_aggregate" whether we are generating
361 type descriptors for instance variables (as opposed to methods).
362 Type descriptors for instance variables contain more information
363 than methods (for static typing and embedded structures). */
365 static int generating_instance_variables = 0;
367 /* Some platforms pass small structures through registers versus
368 through an invisible pointer. Determine at what size structure is
369 the transition point between the two possibilities. */
372 generate_struct_by_value_array ()
375 tree field_decl, field_decl_chain;
377 int aggregate_in_mem[32];
380 /* Presumably no platform passes 32 byte structures in a register. */
381 for (i = 1; i < 32; i++)
385 /* Create an unnamed struct that has `i' character components */
386 type = start_struct (RECORD_TYPE, NULL_TREE);
388 strcpy (buffer, "c1");
389 field_decl = create_builtin_decl (FIELD_DECL,
392 field_decl_chain = field_decl;
394 for (j = 1; j < i; j++)
396 sprintf (buffer, "c%d", j + 1);
397 field_decl = create_builtin_decl (FIELD_DECL,
400 chainon (field_decl_chain, field_decl);
402 finish_struct (type, field_decl_chain, NULL_TREE);
404 aggregate_in_mem[i] = aggregate_value_p (type);
405 if (!aggregate_in_mem[i])
409 /* We found some structures that are returned in registers instead of memory
410 so output the necessary data. */
413 for (i = 31; i >= 0; i--)
414 if (!aggregate_in_mem[i])
416 printf ("#define OBJC_MAX_STRUCT_BY_VALUE %d\n\n", i);
418 /* The first member of the structure is always 0 because we don't handle
419 structures with 0 members */
420 printf ("static int struct_forward_array[] = {\n 0");
422 for (j = 1; j <= i; j++)
423 printf (", %d", aggregate_in_mem[j]);
432 const char *filename;
434 filename = c_objc_common_init (filename);
435 if (filename == NULL)
438 /* Force the line number back to 0; check_newline will have
439 raised it to 1, which will make the builtin functions appear
440 not to be built in. */
443 /* If gen_declaration desired, open the output file. */
444 if (flag_gen_declaration)
446 register char * const dumpname = concat (dump_base_name, ".decl", NULL);
447 gen_declaration_file = fopen (dumpname, "w");
448 if (gen_declaration_file == 0)
449 fatal_io_error ("can't open %s", dumpname);
453 if (flag_next_runtime)
455 TAG_GETCLASS = "objc_getClass";
456 TAG_GETMETACLASS = "objc_getMetaClass";
457 TAG_MSGSEND = "objc_msgSend";
458 TAG_MSGSENDSUPER = "objc_msgSendSuper";
459 TAG_EXECCLASS = "__objc_execClass";
460 default_constant_string_class_name = "NSConstantString";
464 TAG_GETCLASS = "objc_get_class";
465 TAG_GETMETACLASS = "objc_get_meta_class";
466 TAG_MSGSEND = "objc_msg_lookup";
467 TAG_MSGSENDSUPER = "objc_msg_lookup_super";
468 TAG_EXECCLASS = "__objc_exec_class";
469 default_constant_string_class_name = "NXConstantString";
470 flag_typed_selectors = 1;
473 objc_ellipsis_node = make_node (ERROR_MARK);
477 if (print_struct_values)
478 generate_struct_by_value_array ();
486 c_objc_common_finish_file ();
488 /* Finalize Objective-C runtime data. No need to generate tables
489 and code if only checking syntax. */
490 if (!flag_syntax_only)
493 if (gen_declaration_file)
494 fclose (gen_declaration_file);
498 define_decl (declarator, declspecs)
502 tree decl = start_decl (declarator, declspecs, 0, NULL_TREE);
503 finish_decl (decl, NULL_TREE, NULL_TREE);
507 /* Return 1 if LHS and RHS are compatible types for assignment or
508 various other operations. Return 0 if they are incompatible, and
509 return -1 if we choose to not decide. When the operation is
510 REFLEXIVE, check for compatibility in either direction.
512 For statically typed objects, an assignment of the form `a' = `b'
516 `a' and `b' are the same class type, or
517 `a' and `b' are of class types A and B such that B is a descendant of A. */
520 lookup_method_in_protocol_list (rproto_list, sel_name, class_meth)
528 for (rproto = rproto_list; rproto; rproto = TREE_CHAIN (rproto))
530 p = TREE_VALUE (rproto);
532 if (TREE_CODE (p) == PROTOCOL_INTERFACE_TYPE)
534 if ((fnd = lookup_method (class_meth
535 ? PROTOCOL_CLS_METHODS (p)
536 : PROTOCOL_NST_METHODS (p), sel_name)))
538 else if (PROTOCOL_LIST (p))
539 fnd = lookup_method_in_protocol_list (PROTOCOL_LIST (p),
540 sel_name, class_meth);
544 ; /* An identifier...if we could not find a protocol. */
555 lookup_protocol_in_reflist (rproto_list, lproto)
561 /* Make sure the protocol is supported by the object on the rhs. */
562 if (TREE_CODE (lproto) == PROTOCOL_INTERFACE_TYPE)
565 for (rproto = rproto_list; rproto; rproto = TREE_CHAIN (rproto))
567 p = TREE_VALUE (rproto);
569 if (TREE_CODE (p) == PROTOCOL_INTERFACE_TYPE)
574 else if (PROTOCOL_LIST (p))
575 fnd = lookup_protocol_in_reflist (PROTOCOL_LIST (p), lproto);
584 ; /* An identifier...if we could not find a protocol. */
590 /* Return 1 if LHS and RHS are compatible types for assignment
591 or various other operations. Return 0 if they are incompatible,
592 and return -1 if we choose to not decide. When the operation
593 is REFLEXIVE, check for compatibility in either direction. */
596 objc_comptypes (lhs, rhs, reflexive)
601 /* New clause for protocols. */
603 if (TREE_CODE (lhs) == POINTER_TYPE
604 && TREE_CODE (TREE_TYPE (lhs)) == RECORD_TYPE
605 && TREE_CODE (rhs) == POINTER_TYPE
606 && TREE_CODE (TREE_TYPE (rhs)) == RECORD_TYPE)
608 int lhs_is_proto = IS_PROTOCOL_QUALIFIED_ID (lhs);
609 int rhs_is_proto = IS_PROTOCOL_QUALIFIED_ID (rhs);
613 tree lproto, lproto_list = TYPE_PROTOCOL_LIST (lhs);
614 tree rproto, rproto_list;
619 rproto_list = TYPE_PROTOCOL_LIST (rhs);
621 /* Make sure the protocol is supported by the object
623 for (lproto = lproto_list; lproto; lproto = TREE_CHAIN (lproto))
625 p = TREE_VALUE (lproto);
626 rproto = lookup_protocol_in_reflist (rproto_list, p);
629 warning ("object does not conform to the `%s' protocol",
630 IDENTIFIER_POINTER (PROTOCOL_NAME (p)));
633 else if (TYPED_OBJECT (TREE_TYPE (rhs)))
635 tree rname = TYPE_NAME (TREE_TYPE (rhs));
638 /* Make sure the protocol is supported by the object
640 for (lproto = lproto_list; lproto; lproto = TREE_CHAIN (lproto))
642 p = TREE_VALUE (lproto);
644 rinter = lookup_interface (rname);
646 while (rinter && !rproto)
650 rproto_list = CLASS_PROTOCOL_LIST (rinter);
651 /* If the underlying ObjC class does not have
652 protocols attached to it, perhaps there are
653 "one-off" protocols attached to the rhs?
654 E.g., 'id<MyProt> foo;'. */
656 rproto_list = TYPE_PROTOCOL_LIST (TREE_TYPE (rhs));
657 rproto = lookup_protocol_in_reflist (rproto_list, p);
659 /* Check for protocols adopted by categories. */
660 cat = CLASS_CATEGORY_LIST (rinter);
661 while (cat && !rproto)
663 rproto_list = CLASS_PROTOCOL_LIST (cat);
664 rproto = lookup_protocol_in_reflist (rproto_list, p);
666 cat = CLASS_CATEGORY_LIST (cat);
669 rinter = lookup_interface (CLASS_SUPER_NAME (rinter));
673 warning ("class `%s' does not implement the `%s' protocol",
674 IDENTIFIER_POINTER (TYPE_NAME (TREE_TYPE (rhs))),
675 IDENTIFIER_POINTER (PROTOCOL_NAME (p)));
679 /* May change...based on whether there was any mismatch */
682 else if (rhs_is_proto)
683 /* Lhs is not a protocol...warn if it is statically typed */
684 return (TYPED_OBJECT (TREE_TYPE (lhs)) != 0);
687 /* Defer to comptypes. */
691 else if (TREE_CODE (lhs) == RECORD_TYPE && TREE_CODE (rhs) == RECORD_TYPE)
692 ; /* Fall thru. This is the case we have been handling all along */
694 /* Defer to comptypes. */
697 /* `id' = `<class> *', `<class> *' = `id' */
699 if ((TYPE_NAME (lhs) == objc_object_id && TYPED_OBJECT (rhs))
700 || (TYPE_NAME (rhs) == objc_object_id && TYPED_OBJECT (lhs)))
703 /* `id' = `Class', `Class' = `id' */
705 else if ((TYPE_NAME (lhs) == objc_object_id
706 && TYPE_NAME (rhs) == objc_class_id)
707 || (TYPE_NAME (lhs) == objc_class_id
708 && TYPE_NAME (rhs) == objc_object_id))
711 /* `<class> *' = `<class> *' */
713 else if (TYPED_OBJECT (lhs) && TYPED_OBJECT (rhs))
715 tree lname = TYPE_NAME (lhs);
716 tree rname = TYPE_NAME (rhs);
722 /* If the left hand side is a super class of the right hand side,
724 for (inter = lookup_interface (rname); inter;
725 inter = lookup_interface (CLASS_SUPER_NAME (inter)))
726 if (lname == CLASS_SUPER_NAME (inter))
729 /* Allow the reverse when reflexive. */
731 for (inter = lookup_interface (lname); inter;
732 inter = lookup_interface (CLASS_SUPER_NAME (inter)))
733 if (rname == CLASS_SUPER_NAME (inter))
739 /* Defer to comptypes. */
743 /* Called from c-decl.c before all calls to rest_of_decl_compilation. */
746 objc_check_decl (decl)
749 tree type = TREE_TYPE (decl);
751 if (TREE_CODE (type) == RECORD_TYPE
752 && TREE_STATIC_TEMPLATE (type)
753 && type != constant_string_type)
754 error_with_decl (decl, "`%s' cannot be statically allocated");
757 /* Implement static typing. At this point, we know we have an interface. */
760 get_static_reference (interface, protocols)
764 tree type = xref_tag (RECORD_TYPE, interface);
768 tree t, m = TYPE_MAIN_VARIANT (type);
770 t = copy_node (type);
771 TYPE_BINFO (t) = make_tree_vec (2);
773 /* Add this type to the chain of variants of TYPE. */
774 TYPE_NEXT_VARIANT (t) = TYPE_NEXT_VARIANT (m);
775 TYPE_NEXT_VARIANT (m) = t;
777 /* Look up protocols and install in lang specific list. Note
778 that the protocol list can have a different lifetime than T! */
779 TYPE_PROTOCOL_LIST (t) = lookup_and_install_protocols (protocols);
781 /* This forces a new pointer type to be created later
782 (in build_pointer_type)...so that the new template
783 we just created will actually be used...what a hack! */
784 if (TYPE_POINTER_TO (t))
785 TYPE_POINTER_TO (t) = NULL_TREE;
794 get_object_reference (protocols)
797 tree type_decl = lookup_name (objc_id_id);
800 if (type_decl && TREE_CODE (type_decl) == TYPE_DECL)
802 type = TREE_TYPE (type_decl);
803 if (TYPE_MAIN_VARIANT (type) != id_type)
804 warning ("unexpected type for `id' (%s)",
805 gen_declaration (type, errbuf));
809 error ("undefined type `id', please import <objc/objc.h>");
810 return error_mark_node;
813 /* This clause creates a new pointer type that is qualified with
814 the protocol specification...this info is used later to do more
815 elaborate type checking. */
819 tree t, m = TYPE_MAIN_VARIANT (type);
821 t = copy_node (type);
822 TYPE_BINFO (t) = make_tree_vec (2);
824 /* Add this type to the chain of variants of TYPE. */
825 TYPE_NEXT_VARIANT (t) = TYPE_NEXT_VARIANT (m);
826 TYPE_NEXT_VARIANT (m) = t;
828 /* Look up protocols...and install in lang specific list */
829 TYPE_PROTOCOL_LIST (t) = lookup_and_install_protocols (protocols);
831 /* This forces a new pointer type to be created later
832 (in build_pointer_type)...so that the new template
833 we just created will actually be used...what a hack! */
834 if (TYPE_POINTER_TO (t))
835 TYPE_POINTER_TO (t) = NULL_TREE;
842 /* Check for circular dependencies in protocols. The arguments are
843 PROTO, the protocol to check, and LIST, a list of protocol it
847 check_protocol_recursively (proto, list)
853 for (p = list; p; p = TREE_CHAIN (p))
855 tree pp = TREE_VALUE (p);
857 if (TREE_CODE (pp) == IDENTIFIER_NODE)
858 pp = lookup_protocol (pp);
861 fatal_error ("protocol `%s' has circular dependency",
862 IDENTIFIER_POINTER (PROTOCOL_NAME (pp)));
864 check_protocol_recursively (proto, PROTOCOL_LIST (pp));
869 lookup_and_install_protocols (protocols)
874 tree return_value = protocols;
876 for (proto = protocols; proto; proto = TREE_CHAIN (proto))
878 tree ident = TREE_VALUE (proto);
879 tree p = lookup_protocol (ident);
883 error ("cannot find protocol declaration for `%s'",
884 IDENTIFIER_POINTER (ident));
886 TREE_CHAIN (prev) = TREE_CHAIN (proto);
888 return_value = TREE_CHAIN (proto);
892 /* Replace identifier with actual protocol node. */
893 TREE_VALUE (proto) = p;
901 /* Create and push a decl for a built-in external variable or field NAME.
903 TYPE is its data type. */
906 create_builtin_decl (code, type, name)
911 tree decl = build_decl (code, get_identifier (name), type);
913 if (code == VAR_DECL)
915 TREE_STATIC (decl) = 1;
916 make_decl_rtl (decl, 0);
920 DECL_ARTIFICIAL (decl) = 1;
924 /* Find the decl for the constant string class. */
929 if (!string_class_decl)
931 if (!constant_string_global_id)
932 constant_string_global_id = get_identifier (STRING_OBJECT_GLOBAL_NAME);
933 string_class_decl = lookup_name (constant_string_global_id);
937 /* Purpose: "play" parser, creating/installing representations
938 of the declarations that are required by Objective-C.
942 type_spec--------->sc_spec
943 (tree_list) (tree_list)
946 identifier_node identifier_node */
949 synth_module_prologue ()
954 /* Defined in `objc.h' */
955 objc_object_id = get_identifier (TAG_OBJECT);
957 objc_object_reference = xref_tag (RECORD_TYPE, objc_object_id);
959 id_type = build_pointer_type (objc_object_reference);
961 objc_id_id = get_identifier (TYPE_ID);
962 objc_class_id = get_identifier (TAG_CLASS);
964 objc_class_type = build_pointer_type (xref_tag (RECORD_TYPE, objc_class_id));
965 protocol_type = build_pointer_type (xref_tag (RECORD_TYPE,
966 get_identifier (PROTOCOL_OBJECT_CLASS_NAME)));
968 /* Declare type of selector-objects that represent an operation name. */
970 /* `struct objc_selector *' */
972 = build_pointer_type (xref_tag (RECORD_TYPE,
973 get_identifier (TAG_SELECTOR)));
975 /* Forward declare type, or else the prototype for msgSendSuper will
978 super_p = build_pointer_type (xref_tag (RECORD_TYPE,
979 get_identifier (TAG_SUPER)));
982 /* id objc_msgSend (id, SEL, ...); */
985 = build_function_type (id_type,
986 tree_cons (NULL_TREE, id_type,
987 tree_cons (NULL_TREE, selector_type,
990 if (! flag_next_runtime)
992 umsg_decl = build_decl (FUNCTION_DECL,
993 get_identifier (TAG_MSGSEND), temp_type);
994 DECL_EXTERNAL (umsg_decl) = 1;
995 TREE_PUBLIC (umsg_decl) = 1;
996 DECL_INLINE (umsg_decl) = 1;
997 DECL_ARTIFICIAL (umsg_decl) = 1;
999 make_decl_rtl (umsg_decl, NULL);
1000 pushdecl (umsg_decl);
1003 umsg_decl = builtin_function (TAG_MSGSEND, temp_type, 0, NOT_BUILT_IN,
1006 /* id objc_msgSendSuper (struct objc_super *, SEL, ...); */
1009 = build_function_type (id_type,
1010 tree_cons (NULL_TREE, super_p,
1011 tree_cons (NULL_TREE, selector_type,
1014 umsg_super_decl = builtin_function (TAG_MSGSENDSUPER,
1015 temp_type, 0, NOT_BUILT_IN,
1018 /* id objc_getClass (const char *); */
1020 temp_type = build_function_type (id_type,
1021 tree_cons (NULL_TREE,
1022 const_string_type_node,
1023 tree_cons (NULL_TREE, void_type_node,
1027 = builtin_function (TAG_GETCLASS, temp_type, 0, NOT_BUILT_IN,
1030 /* id objc_getMetaClass (const char *); */
1032 objc_get_meta_class_decl
1033 = builtin_function (TAG_GETMETACLASS, temp_type, 0, NOT_BUILT_IN,
1036 /* static SEL _OBJC_SELECTOR_TABLE[]; */
1038 if (! flag_next_runtime)
1040 if (flag_typed_selectors)
1042 /* Suppress outputting debug symbols, because
1043 dbxout_init hasn'r been called yet. */
1044 enum debug_info_type save_write_symbols = write_symbols;
1045 const struct gcc_debug_hooks *const save_hooks = debug_hooks;
1046 write_symbols = NO_DEBUG;
1047 debug_hooks = &do_nothing_debug_hooks;
1049 build_selector_template ();
1050 temp_type = build_array_type (objc_selector_template, NULL_TREE);
1052 write_symbols = save_write_symbols;
1053 debug_hooks = save_hooks;
1056 temp_type = build_array_type (selector_type, NULL_TREE);
1058 layout_type (temp_type);
1059 UOBJC_SELECTOR_TABLE_decl
1060 = create_builtin_decl (VAR_DECL, temp_type,
1061 "_OBJC_SELECTOR_TABLE");
1063 /* Avoid warning when not sending messages. */
1064 TREE_USED (UOBJC_SELECTOR_TABLE_decl) = 1;
1067 generate_forward_declaration_to_string_table ();
1069 /* Forward declare constant_string_id and constant_string_type. */
1070 if (!constant_string_class_name)
1071 constant_string_class_name = default_constant_string_class_name;
1073 constant_string_id = get_identifier (constant_string_class_name);
1074 constant_string_type = xref_tag (RECORD_TYPE, constant_string_id);
1077 /* Predefine the following data type:
1079 struct STRING_OBJECT_CLASS_NAME
1083 unsigned int length;
1087 build_string_class_template ()
1089 tree field_decl, field_decl_chain;
1091 field_decl = create_builtin_decl (FIELD_DECL, id_type, "isa");
1092 field_decl_chain = field_decl;
1094 field_decl = create_builtin_decl (FIELD_DECL,
1095 build_pointer_type (char_type_node),
1097 chainon (field_decl_chain, field_decl);
1099 field_decl = create_builtin_decl (FIELD_DECL, unsigned_type_node, "length");
1100 chainon (field_decl_chain, field_decl);
1102 finish_struct (constant_string_type, field_decl_chain, NULL_TREE);
1105 /* Custom build_string which sets TREE_TYPE! */
1108 my_build_string (len, str)
1112 return fix_string_type (build_string (len, str));
1115 /* Given a chain of STRING_CST's, build a static instance of
1116 NXConstantString which points at the concatenation of those strings.
1117 We place the string object in the __string_objects section of the
1118 __OBJC segment. The Objective-C runtime will initialize the isa
1119 pointers of the string objects to point at the NXConstantString
1123 build_objc_string_object (strings)
1126 tree string, initlist, constructor;
1129 if (lookup_interface (constant_string_id) == NULL_TREE)
1131 error ("cannot find interface declaration for `%s'",
1132 IDENTIFIER_POINTER (constant_string_id));
1133 return error_mark_node;
1136 add_class_reference (constant_string_id);
1138 if (TREE_CHAIN (strings))
1140 varray_type vstrings;
1141 VARRAY_TREE_INIT (vstrings, 32, "strings");
1143 for (; strings ; strings = TREE_CHAIN (strings))
1144 VARRAY_PUSH_TREE (vstrings, strings);
1146 string = combine_strings (vstrings);
1151 string = fix_string_type (string);
1153 TREE_SET_CODE (string, STRING_CST);
1154 length = TREE_STRING_LENGTH (string) - 1;
1156 /* We could not properly create NXConstantString in synth_module_prologue,
1157 because that's called before debugging is initialized. Do it now. */
1158 if (TYPE_FIELDS (constant_string_type) == NULL_TREE)
1159 build_string_class_template ();
1161 /* & ((NXConstantString) { NULL, string, length }) */
1163 if (flag_next_runtime)
1165 /* For the NeXT runtime, we can generate a literal reference
1166 to the string class, don't need to run a constructor. */
1167 setup_string_decl ();
1168 if (string_class_decl == NULL_TREE)
1170 error ("cannot find reference tag for class `%s'",
1171 IDENTIFIER_POINTER (constant_string_id));
1172 return error_mark_node;
1174 initlist = build_tree_list
1176 copy_node (build_unary_op (ADDR_EXPR, string_class_decl, 0)));
1180 initlist = build_tree_list (NULL_TREE, build_int_2 (0, 0));
1184 = tree_cons (NULL_TREE, copy_node (build_unary_op (ADDR_EXPR, string, 1)),
1186 initlist = tree_cons (NULL_TREE, build_int_2 (length, 0), initlist);
1187 constructor = build_constructor (constant_string_type, nreverse (initlist));
1189 if (!flag_next_runtime)
1192 = objc_add_static_instance (constructor, constant_string_type);
1195 return (build_unary_op (ADDR_EXPR, constructor, 1));
1198 /* Declare a static instance of CLASS_DECL initialized by CONSTRUCTOR. */
1201 objc_add_static_instance (constructor, class_decl)
1202 tree constructor, class_decl;
1204 static int num_static_inst;
1208 /* Find the list of static instances for the CLASS_DECL. Create one if
1210 for (chain = &objc_static_instances;
1211 *chain && TREE_VALUE (*chain) != class_decl;
1212 chain = &TREE_CHAIN (*chain));
1215 *chain = tree_cons (NULL_TREE, class_decl, NULL_TREE);
1216 add_objc_string (TYPE_NAME (class_decl), class_names);
1219 sprintf (buf, "_OBJC_INSTANCE_%d", num_static_inst++);
1220 decl = build_decl (VAR_DECL, get_identifier (buf), class_decl);
1221 DECL_COMMON (decl) = 1;
1222 TREE_STATIC (decl) = 1;
1223 DECL_ARTIFICIAL (decl) = 1;
1224 DECL_INITIAL (decl) = constructor;
1226 /* We may be writing something else just now.
1227 Postpone till end of input. */
1228 DECL_DEFER_OUTPUT (decl) = 1;
1229 pushdecl_top_level (decl);
1230 rest_of_decl_compilation (decl, 0, 1, 0);
1232 /* Add the DECL to the head of this CLASS' list. */
1233 TREE_PURPOSE (*chain) = tree_cons (NULL_TREE, decl, TREE_PURPOSE (*chain));
1238 /* Build a static constant CONSTRUCTOR
1239 with type TYPE and elements ELTS. */
1242 build_constructor (type, elts)
1245 tree constructor, f, e;
1247 /* ??? Most of the places that we build constructors, we don't fill in
1248 the type of integers properly. Convert them all en masse. */
1249 if (TREE_CODE (type) == ARRAY_TYPE)
1251 f = TREE_TYPE (type);
1252 if (TREE_CODE (f) == POINTER_TYPE || TREE_CODE (f) == INTEGER_TYPE)
1253 for (e = elts; e ; e = TREE_CHAIN (e))
1254 TREE_VALUE (e) = convert (f, TREE_VALUE (e));
1258 f = TYPE_FIELDS (type);
1259 for (e = elts; e ; e = TREE_CHAIN (e), f = TREE_CHAIN (f))
1260 if (TREE_CODE (TREE_TYPE (f)) == POINTER_TYPE
1261 || TREE_CODE (TREE_TYPE (f)) == INTEGER_TYPE)
1262 TREE_VALUE (e) = convert (TREE_TYPE (f), TREE_VALUE (e));
1265 constructor = build (CONSTRUCTOR, type, NULL_TREE, elts);
1266 TREE_CONSTANT (constructor) = 1;
1267 TREE_STATIC (constructor) = 1;
1268 TREE_READONLY (constructor) = 1;
1273 /* Take care of defining and initializing _OBJC_SYMBOLS. */
1275 /* Predefine the following data type:
1283 void *defs[cls_def_cnt + cat_def_cnt];
1287 build_objc_symtab_template ()
1289 tree field_decl, field_decl_chain, index;
1291 objc_symtab_template
1292 = start_struct (RECORD_TYPE, get_identifier (UTAG_SYMTAB));
1294 /* long sel_ref_cnt; */
1296 field_decl = create_builtin_decl (FIELD_DECL,
1297 long_integer_type_node,
1299 field_decl_chain = field_decl;
1303 field_decl = create_builtin_decl (FIELD_DECL,
1304 build_pointer_type (selector_type),
1306 chainon (field_decl_chain, field_decl);
1308 /* short cls_def_cnt; */
1310 field_decl = create_builtin_decl (FIELD_DECL,
1311 short_integer_type_node,
1313 chainon (field_decl_chain, field_decl);
1315 /* short cat_def_cnt; */
1317 field_decl = create_builtin_decl (FIELD_DECL,
1318 short_integer_type_node,
1320 chainon (field_decl_chain, field_decl);
1322 /* void *defs[cls_def_cnt + cat_def_cnt]; */
1324 if (!flag_next_runtime)
1325 index = build_index_type (build_int_2 (imp_count + cat_count, 0));
1327 index = build_index_type (build_int_2 (imp_count + cat_count - 1,
1328 imp_count == 0 && cat_count == 0
1330 field_decl = create_builtin_decl (FIELD_DECL,
1331 build_array_type (ptr_type_node, index),
1333 chainon (field_decl_chain, field_decl);
1335 finish_struct (objc_symtab_template, field_decl_chain, NULL_TREE);
1338 /* Create the initial value for the `defs' field of _objc_symtab.
1339 This is a CONSTRUCTOR. */
1342 init_def_list (type)
1345 tree expr, initlist = NULL_TREE;
1346 struct imp_entry *impent;
1349 for (impent = imp_list; impent; impent = impent->next)
1351 if (TREE_CODE (impent->imp_context) == CLASS_IMPLEMENTATION_TYPE)
1353 expr = build_unary_op (ADDR_EXPR, impent->class_decl, 0);
1354 initlist = tree_cons (NULL_TREE, expr, initlist);
1359 for (impent = imp_list; impent; impent = impent->next)
1361 if (TREE_CODE (impent->imp_context) == CATEGORY_IMPLEMENTATION_TYPE)
1363 expr = build_unary_op (ADDR_EXPR, impent->class_decl, 0);
1364 initlist = tree_cons (NULL_TREE, expr, initlist);
1368 if (!flag_next_runtime)
1370 /* statics = { ..., _OBJC_STATIC_INSTANCES, ... } */
1373 if (static_instances_decl)
1374 expr = build_unary_op (ADDR_EXPR, static_instances_decl, 0);
1376 expr = build_int_2 (0, 0);
1378 initlist = tree_cons (NULL_TREE, expr, initlist);
1381 return build_constructor (type, nreverse (initlist));
1384 /* Construct the initial value for all of _objc_symtab. */
1387 init_objc_symtab (type)
1392 /* sel_ref_cnt = { ..., 5, ... } */
1394 initlist = build_tree_list (NULL_TREE, build_int_2 (0, 0));
1396 /* refs = { ..., _OBJC_SELECTOR_TABLE, ... } */
1398 if (flag_next_runtime || ! sel_ref_chain)
1399 initlist = tree_cons (NULL_TREE, build_int_2 (0, 0), initlist);
1401 initlist = tree_cons (NULL_TREE,
1402 build_unary_op (ADDR_EXPR,
1403 UOBJC_SELECTOR_TABLE_decl, 1),
1406 /* cls_def_cnt = { ..., 5, ... } */
1408 initlist = tree_cons (NULL_TREE, build_int_2 (imp_count, 0), initlist);
1410 /* cat_def_cnt = { ..., 5, ... } */
1412 initlist = tree_cons (NULL_TREE, build_int_2 (cat_count, 0), initlist);
1414 /* cls_def = { ..., { &Foo, &Bar, ...}, ... } */
1416 if (imp_count || cat_count || static_instances_decl)
1419 tree field = TYPE_FIELDS (type);
1420 field = TREE_CHAIN (TREE_CHAIN (TREE_CHAIN (TREE_CHAIN (field))));
1422 initlist = tree_cons (NULL_TREE, init_def_list (TREE_TYPE (field)),
1426 return build_constructor (type, nreverse (initlist));
1429 /* Push forward-declarations of all the categories so that
1430 init_def_list can use them in a CONSTRUCTOR. */
1433 forward_declare_categories ()
1435 struct imp_entry *impent;
1436 tree sav = objc_implementation_context;
1438 for (impent = imp_list; impent; impent = impent->next)
1440 if (TREE_CODE (impent->imp_context) == CATEGORY_IMPLEMENTATION_TYPE)
1442 /* Set an invisible arg to synth_id_with_class_suffix. */
1443 objc_implementation_context = impent->imp_context;
1445 = create_builtin_decl (VAR_DECL, objc_category_template,
1446 IDENTIFIER_POINTER (synth_id_with_class_suffix ("_OBJC_CATEGORY", objc_implementation_context)));
1449 objc_implementation_context = sav;
1452 /* Create the declaration of _OBJC_SYMBOLS, with type `strict _objc_symtab'
1453 and initialized appropriately. */
1456 generate_objc_symtab_decl ()
1460 if (!objc_category_template)
1461 build_category_template ();
1463 /* forward declare categories */
1465 forward_declare_categories ();
1467 if (!objc_symtab_template)
1468 build_objc_symtab_template ();
1470 sc_spec = build_tree_list (NULL_TREE, ridpointers[(int) RID_STATIC]);
1472 UOBJC_SYMBOLS_decl = start_decl (get_identifier ("_OBJC_SYMBOLS"),
1473 tree_cons (NULL_TREE,
1474 objc_symtab_template, sc_spec),
1478 TREE_USED (UOBJC_SYMBOLS_decl) = 1;
1479 DECL_IGNORED_P (UOBJC_SYMBOLS_decl) = 1;
1480 DECL_ARTIFICIAL (UOBJC_SYMBOLS_decl) = 1;
1481 finish_decl (UOBJC_SYMBOLS_decl,
1482 init_objc_symtab (TREE_TYPE (UOBJC_SYMBOLS_decl)),
1487 init_module_descriptor (type)
1490 tree initlist, expr;
1492 /* version = { 1, ... } */
1494 expr = build_int_2 (OBJC_VERSION, 0);
1495 initlist = build_tree_list (NULL_TREE, expr);
1497 /* size = { ..., sizeof (struct objc_module), ... } */
1499 expr = size_in_bytes (objc_module_template);
1500 initlist = tree_cons (NULL_TREE, expr, initlist);
1502 /* name = { ..., "foo.m", ... } */
1504 expr = add_objc_string (get_identifier (input_filename), class_names);
1505 initlist = tree_cons (NULL_TREE, expr, initlist);
1507 /* symtab = { ..., _OBJC_SYMBOLS, ... } */
1509 if (UOBJC_SYMBOLS_decl)
1510 expr = build_unary_op (ADDR_EXPR, UOBJC_SYMBOLS_decl, 0);
1512 expr = build_int_2 (0, 0);
1513 initlist = tree_cons (NULL_TREE, expr, initlist);
1515 return build_constructor (type, nreverse (initlist));
1518 /* Write out the data structures to describe Objective C classes defined.
1519 If appropriate, compile and output a setup function to initialize them.
1520 Return a symbol_ref to the function to call to initialize the Objective C
1521 data structures for this file (and perhaps for other files also).
1523 struct objc_module { ... } _OBJC_MODULE = { ... }; */
1526 build_module_descriptor ()
1528 tree decl_specs, field_decl, field_decl_chain;
1530 objc_module_template
1531 = start_struct (RECORD_TYPE, get_identifier (UTAG_MODULE));
1535 decl_specs = build_tree_list (NULL_TREE, ridpointers[(int) RID_LONG]);
1536 field_decl = get_identifier ("version");
1538 = grokfield (input_filename, lineno, field_decl, decl_specs, NULL_TREE);
1539 field_decl_chain = field_decl;
1543 decl_specs = build_tree_list (NULL_TREE, ridpointers[(int) RID_LONG]);
1544 field_decl = get_identifier ("size");
1546 = grokfield (input_filename, lineno, field_decl, decl_specs, NULL_TREE);
1547 chainon (field_decl_chain, field_decl);
1551 decl_specs = build_tree_list (NULL_TREE, ridpointers[(int) RID_CHAR]);
1552 field_decl = build1 (INDIRECT_REF, NULL_TREE, get_identifier ("name"));
1554 = grokfield (input_filename, lineno, field_decl, decl_specs, NULL_TREE);
1555 chainon (field_decl_chain, field_decl);
1557 /* struct objc_symtab *symtab; */
1559 decl_specs = get_identifier (UTAG_SYMTAB);
1560 decl_specs = build_tree_list (NULL_TREE, xref_tag (RECORD_TYPE, decl_specs));
1561 field_decl = build1 (INDIRECT_REF, NULL_TREE, get_identifier ("symtab"));
1563 = grokfield (input_filename, lineno, field_decl, decl_specs, NULL_TREE);
1564 chainon (field_decl_chain, field_decl);
1566 finish_struct (objc_module_template, field_decl_chain, NULL_TREE);
1568 /* Create an instance of "objc_module". */
1570 decl_specs = tree_cons (NULL_TREE, objc_module_template,
1571 build_tree_list (NULL_TREE,
1572 ridpointers[(int) RID_STATIC]));
1574 UOBJC_MODULES_decl = start_decl (get_identifier ("_OBJC_MODULES"),
1575 decl_specs, 1, NULL_TREE);
1577 DECL_ARTIFICIAL (UOBJC_MODULES_decl) = 1;
1578 DECL_IGNORED_P (UOBJC_MODULES_decl) = 1;
1579 DECL_CONTEXT (UOBJC_MODULES_decl) = NULL_TREE;
1581 finish_decl (UOBJC_MODULES_decl,
1582 init_module_descriptor (TREE_TYPE (UOBJC_MODULES_decl)),
1585 /* Mark the decl to avoid "defined but not used" warning. */
1586 DECL_IN_SYSTEM_HEADER (UOBJC_MODULES_decl) = 1;
1588 /* Generate a constructor call for the module descriptor.
1589 This code was generated by reading the grammar rules
1590 of c-parse.in; Therefore, it may not be the most efficient
1591 way of generating the requisite code. */
1593 if (flag_next_runtime)
1597 tree parms, execclass_decl, decelerator, void_list_node_1;
1598 tree init_function_name, init_function_decl;
1600 /* Declare void __objc_execClass (void *); */
1602 void_list_node_1 = build_tree_list (NULL_TREE, void_type_node);
1603 execclass_decl = build_decl (FUNCTION_DECL,
1604 get_identifier (TAG_EXECCLASS),
1605 build_function_type (void_type_node,
1606 tree_cons (NULL_TREE, ptr_type_node,
1607 void_list_node_1)));
1608 DECL_EXTERNAL (execclass_decl) = 1;
1609 DECL_ARTIFICIAL (execclass_decl) = 1;
1610 TREE_PUBLIC (execclass_decl) = 1;
1611 pushdecl (execclass_decl);
1612 rest_of_decl_compilation (execclass_decl, 0, 0, 0);
1613 assemble_external (execclass_decl);
1615 /* void _GLOBAL_$I$<gnyf> () {objc_execClass (&L_OBJC_MODULES);} */
1617 init_function_name = get_file_function_name ('I');
1618 start_function (void_list_node_1,
1619 build_nt (CALL_EXPR, init_function_name,
1620 tree_cons (NULL_TREE, NULL_TREE,
1624 store_parm_decls ();
1626 init_function_decl = current_function_decl;
1627 TREE_PUBLIC (init_function_decl) = ! targetm.have_ctors_dtors;
1628 TREE_USED (init_function_decl) = 1;
1629 /* Don't let this one be deferred. */
1630 DECL_INLINE (init_function_decl) = 0;
1631 DECL_UNINLINABLE (init_function_decl) = 1;
1632 current_function_cannot_inline
1633 = "static constructors and destructors cannot be inlined";
1636 = build_tree_list (NULL_TREE,
1637 build_unary_op (ADDR_EXPR, UOBJC_MODULES_decl, 0));
1638 decelerator = build_function_call (execclass_decl, parms);
1640 c_expand_expr_stmt (decelerator);
1642 finish_function (0, 0);
1644 return XEXP (DECL_RTL (init_function_decl), 0);
1648 /* extern const char _OBJC_STRINGS[]; */
1651 generate_forward_declaration_to_string_table ()
1653 tree sc_spec, decl_specs, expr_decl;
1655 sc_spec = tree_cons (NULL_TREE, ridpointers[(int) RID_EXTERN], NULL_TREE);
1656 decl_specs = tree_cons (NULL_TREE, ridpointers[(int) RID_CHAR], sc_spec);
1659 = build_nt (ARRAY_REF, get_identifier ("_OBJC_STRINGS"), NULL_TREE);
1661 UOBJC_STRINGS_decl = define_decl (expr_decl, decl_specs);
1664 /* Return the DECL of the string IDENT in the SECTION. */
1667 get_objc_string_decl (ident, section)
1669 enum string_section section;
1673 if (section == class_names)
1674 chain = class_names_chain;
1675 else if (section == meth_var_names)
1676 chain = meth_var_names_chain;
1677 else if (section == meth_var_types)
1678 chain = meth_var_types_chain;
1682 for (; chain != 0; chain = TREE_VALUE (chain))
1683 if (TREE_VALUE (chain) == ident)
1684 return (TREE_PURPOSE (chain));
1690 /* Output references to all statically allocated objects. Return the DECL
1691 for the array built. */
1694 generate_static_references ()
1696 tree decls = NULL_TREE, ident, decl_spec, expr_decl, expr = NULL_TREE;
1697 tree class_name, class, decl, initlist;
1698 tree cl_chain, in_chain, type;
1699 int num_inst, num_class;
1702 if (flag_next_runtime)
1705 for (cl_chain = objc_static_instances, num_class = 0;
1706 cl_chain; cl_chain = TREE_CHAIN (cl_chain), num_class++)
1708 for (num_inst = 0, in_chain = TREE_PURPOSE (cl_chain);
1709 in_chain; num_inst++, in_chain = TREE_CHAIN (in_chain));
1711 sprintf (buf, "_OBJC_STATIC_INSTANCES_%d", num_class);
1712 ident = get_identifier (buf);
1714 expr_decl = build_nt (ARRAY_REF, ident, NULL_TREE);
1715 decl_spec = tree_cons (NULL_TREE, build_pointer_type (void_type_node),
1716 build_tree_list (NULL_TREE,
1717 ridpointers[(int) RID_STATIC]));
1718 decl = start_decl (expr_decl, decl_spec, 1, NULL_TREE);
1719 DECL_CONTEXT (decl) = 0;
1720 DECL_ARTIFICIAL (decl) = 1;
1722 /* Output {class_name, ...}. */
1723 class = TREE_VALUE (cl_chain);
1724 class_name = get_objc_string_decl (TYPE_NAME (class), class_names);
1725 initlist = build_tree_list (NULL_TREE,
1726 build_unary_op (ADDR_EXPR, class_name, 1));
1728 /* Output {..., instance, ...}. */
1729 for (in_chain = TREE_PURPOSE (cl_chain);
1730 in_chain; in_chain = TREE_CHAIN (in_chain))
1732 expr = build_unary_op (ADDR_EXPR, TREE_VALUE (in_chain), 1);
1733 initlist = tree_cons (NULL_TREE, expr, initlist);
1736 /* Output {..., NULL}. */
1737 initlist = tree_cons (NULL_TREE, build_int_2 (0, 0), initlist);
1739 expr = build_constructor (TREE_TYPE (decl), nreverse (initlist));
1740 finish_decl (decl, expr, NULL_TREE);
1741 TREE_USED (decl) = 1;
1743 type = build_array_type (build_pointer_type (void_type_node), 0);
1744 decl = build_decl (VAR_DECL, ident, type);
1745 TREE_USED (decl) = 1;
1746 TREE_STATIC (decl) = 1;
1748 = tree_cons (NULL_TREE, build_unary_op (ADDR_EXPR, decl, 1), decls);
1751 decls = tree_cons (NULL_TREE, build_int_2 (0, 0), decls);
1752 ident = get_identifier ("_OBJC_STATIC_INSTANCES");
1753 expr_decl = build_nt (ARRAY_REF, ident, NULL_TREE);
1754 decl_spec = tree_cons (NULL_TREE, build_pointer_type (void_type_node),
1755 build_tree_list (NULL_TREE,
1756 ridpointers[(int) RID_STATIC]));
1757 static_instances_decl
1758 = start_decl (expr_decl, decl_spec, 1, NULL_TREE);
1759 TREE_USED (static_instances_decl) = 1;
1760 DECL_CONTEXT (static_instances_decl) = 0;
1761 DECL_ARTIFICIAL (static_instances_decl) = 1;
1762 expr = build_constructor (TREE_TYPE (static_instances_decl),
1764 finish_decl (static_instances_decl, expr, NULL_TREE);
1767 /* Output all strings. */
1772 tree sc_spec, decl_specs, expr_decl;
1773 tree chain, string_expr;
1776 for (chain = class_names_chain; chain; chain = TREE_CHAIN (chain))
1778 string = TREE_VALUE (chain);
1779 decl = TREE_PURPOSE (chain);
1781 = tree_cons (NULL_TREE, ridpointers[(int) RID_STATIC], NULL_TREE);
1782 decl_specs = tree_cons (NULL_TREE, ridpointers[(int) RID_CHAR], sc_spec);
1783 expr_decl = build_nt (ARRAY_REF, DECL_NAME (decl), NULL_TREE);
1784 decl = start_decl (expr_decl, decl_specs, 1, NULL_TREE);
1785 DECL_CONTEXT (decl) = NULL_TREE;
1786 string_expr = my_build_string (IDENTIFIER_LENGTH (string) + 1,
1787 IDENTIFIER_POINTER (string));
1788 finish_decl (decl, string_expr, NULL_TREE);
1791 for (chain = meth_var_names_chain; chain; chain = TREE_CHAIN (chain))
1793 string = TREE_VALUE (chain);
1794 decl = TREE_PURPOSE (chain);
1796 = tree_cons (NULL_TREE, ridpointers[(int) RID_STATIC], NULL_TREE);
1797 decl_specs = tree_cons (NULL_TREE, ridpointers[(int) RID_CHAR], sc_spec);
1798 expr_decl = build_nt (ARRAY_REF, DECL_NAME (decl), NULL_TREE);
1799 decl = start_decl (expr_decl, decl_specs, 1, NULL_TREE);
1800 DECL_CONTEXT (decl) = NULL_TREE;
1801 string_expr = my_build_string (IDENTIFIER_LENGTH (string) + 1,
1802 IDENTIFIER_POINTER (string));
1803 finish_decl (decl, string_expr, NULL_TREE);
1806 for (chain = meth_var_types_chain; chain; chain = TREE_CHAIN (chain))
1808 string = TREE_VALUE (chain);
1809 decl = TREE_PURPOSE (chain);
1811 = tree_cons (NULL_TREE, ridpointers[(int) RID_STATIC], NULL_TREE);
1812 decl_specs = tree_cons (NULL_TREE, ridpointers[(int) RID_CHAR], sc_spec);
1813 expr_decl = build_nt (ARRAY_REF, DECL_NAME (decl), NULL_TREE);
1814 decl = start_decl (expr_decl, decl_specs, 1, NULL_TREE);
1815 DECL_CONTEXT (decl) = NULL_TREE;
1816 string_expr = my_build_string (IDENTIFIER_LENGTH (string) + 1,
1817 IDENTIFIER_POINTER (string));
1818 finish_decl (decl, string_expr, NULL_TREE);
1823 build_selector_reference_decl ()
1829 sprintf (buf, "_OBJC_SELECTOR_REFERENCES_%d", idx++);
1831 ident = get_identifier (buf);
1833 decl = build_decl (VAR_DECL, ident, selector_type);
1834 DECL_EXTERNAL (decl) = 1;
1835 TREE_PUBLIC (decl) = 1;
1836 TREE_USED (decl) = 1;
1837 TREE_READONLY (decl) = 1;
1838 DECL_ARTIFICIAL (decl) = 1;
1839 DECL_CONTEXT (decl) = 0;
1841 make_decl_rtl (decl, 0);
1842 pushdecl_top_level (decl);
1847 /* Just a handy wrapper for add_objc_string. */
1850 build_selector (ident)
1853 tree expr = add_objc_string (ident, meth_var_names);
1854 if (flag_typed_selectors)
1857 return build_c_cast (selector_type, expr); /* cast! */
1861 build_selector_translation_table ()
1863 tree sc_spec, decl_specs;
1864 tree chain, initlist = NULL_TREE;
1866 tree decl = NULL_TREE, var_decl, name;
1868 for (chain = sel_ref_chain; chain; chain = TREE_CHAIN (chain))
1872 if (warn_selector && objc_implementation_context)
1876 for (method_chain = meth_var_names_chain;
1878 method_chain = TREE_CHAIN (method_chain))
1880 if (TREE_VALUE (method_chain) == TREE_VALUE (chain))
1888 /* Adjust line number for warning message. */
1889 int save_lineno = lineno;
1890 if (flag_next_runtime && TREE_PURPOSE (chain))
1891 lineno = DECL_SOURCE_LINE (TREE_PURPOSE (chain));
1892 warning ("creating selector for non existant method %s",
1893 IDENTIFIER_POINTER (TREE_VALUE (chain)));
1894 lineno = save_lineno;
1898 expr = build_selector (TREE_VALUE (chain));
1900 if (flag_next_runtime)
1902 name = DECL_NAME (TREE_PURPOSE (chain));
1904 sc_spec = build_tree_list (NULL_TREE, ridpointers[(int) RID_STATIC]);
1906 /* static SEL _OBJC_SELECTOR_REFERENCES_n = ...; */
1907 decl_specs = tree_cons (NULL_TREE, selector_type, sc_spec);
1911 /* The `decl' that is returned from start_decl is the one that we
1912 forward declared in `build_selector_reference' */
1913 decl = start_decl (var_decl, decl_specs, 1, NULL_TREE );
1916 /* add one for the '\0' character */
1917 offset += IDENTIFIER_LENGTH (TREE_VALUE (chain)) + 1;
1919 if (flag_next_runtime)
1920 finish_decl (decl, expr, NULL_TREE);
1923 if (flag_typed_selectors)
1925 tree eltlist = NULL_TREE;
1926 tree encoding = get_proto_encoding (TREE_PURPOSE (chain));
1927 eltlist = tree_cons (NULL_TREE, expr, NULL_TREE);
1928 eltlist = tree_cons (NULL_TREE, encoding, eltlist);
1929 expr = build_constructor (objc_selector_template,
1930 nreverse (eltlist));
1932 initlist = tree_cons (NULL_TREE, expr, initlist);
1937 if (! flag_next_runtime)
1939 /* Cause the variable and its initial value to be actually output. */
1940 DECL_EXTERNAL (UOBJC_SELECTOR_TABLE_decl) = 0;
1941 TREE_STATIC (UOBJC_SELECTOR_TABLE_decl) = 1;
1942 /* NULL terminate the list and fix the decl for output. */
1943 initlist = tree_cons (NULL_TREE, build_int_2 (0, 0), initlist);
1944 DECL_INITIAL (UOBJC_SELECTOR_TABLE_decl) = objc_ellipsis_node;
1945 initlist = build_constructor (TREE_TYPE (UOBJC_SELECTOR_TABLE_decl),
1946 nreverse (initlist));
1947 finish_decl (UOBJC_SELECTOR_TABLE_decl, initlist, NULL_TREE);
1948 current_function_decl = NULL_TREE;
1953 get_proto_encoding (proto)
1961 if (! METHOD_ENCODING (proto))
1963 tmp_decl = build_tmp_function_decl ();
1964 hack_method_prototype (proto, tmp_decl);
1965 encoding = encode_method_prototype (proto, tmp_decl);
1966 METHOD_ENCODING (proto) = encoding;
1969 encoding = METHOD_ENCODING (proto);
1971 return add_objc_string (encoding, meth_var_types);
1974 return build_int_2 (0, 0);
1977 /* sel_ref_chain is a list whose "value" fields will be instances of
1978 identifier_node that represent the selector. */
1981 build_typed_selector_reference (ident, proto)
1984 tree *chain = &sel_ref_chain;
1990 if (TREE_PURPOSE (*chain) == ident && TREE_VALUE (*chain) == proto)
1991 goto return_at_index;
1994 chain = &TREE_CHAIN (*chain);
1997 *chain = tree_cons (proto, ident, NULL_TREE);
2000 expr = build_unary_op (ADDR_EXPR,
2001 build_array_ref (UOBJC_SELECTOR_TABLE_decl,
2002 build_int_2 (index, 0)),
2004 return build_c_cast (selector_type, expr);
2008 build_selector_reference (ident)
2011 tree *chain = &sel_ref_chain;
2017 if (TREE_VALUE (*chain) == ident)
2018 return (flag_next_runtime
2019 ? TREE_PURPOSE (*chain)
2020 : build_array_ref (UOBJC_SELECTOR_TABLE_decl,
2021 build_int_2 (index, 0)));
2024 chain = &TREE_CHAIN (*chain);
2027 expr = build_selector_reference_decl ();
2029 *chain = tree_cons (expr, ident, NULL_TREE);
2031 return (flag_next_runtime
2033 : build_array_ref (UOBJC_SELECTOR_TABLE_decl,
2034 build_int_2 (index, 0)));
2038 build_class_reference_decl ()
2044 sprintf (buf, "_OBJC_CLASS_REFERENCES_%d", idx++);
2046 ident = get_identifier (buf);
2048 decl = build_decl (VAR_DECL, ident, objc_class_type);
2049 DECL_EXTERNAL (decl) = 1;
2050 TREE_PUBLIC (decl) = 1;
2051 TREE_USED (decl) = 1;
2052 TREE_READONLY (decl) = 1;
2053 DECL_CONTEXT (decl) = 0;
2054 DECL_ARTIFICIAL (decl) = 1;
2056 make_decl_rtl (decl, 0);
2057 pushdecl_top_level (decl);
2062 /* Create a class reference, but don't create a variable to reference
2066 add_class_reference (ident)
2071 if ((chain = cls_ref_chain))
2076 if (ident == TREE_VALUE (chain))
2080 chain = TREE_CHAIN (chain);
2084 /* Append to the end of the list */
2085 TREE_CHAIN (tail) = tree_cons (NULL_TREE, ident, NULL_TREE);
2088 cls_ref_chain = tree_cons (NULL_TREE, ident, NULL_TREE);
2091 /* Get a class reference, creating it if necessary. Also create the
2092 reference variable. */
2095 get_class_reference (ident)
2098 if (flag_next_runtime)
2103 for (chain = &cls_ref_chain; *chain; chain = &TREE_CHAIN (*chain))
2104 if (TREE_VALUE (*chain) == ident)
2106 if (! TREE_PURPOSE (*chain))
2107 TREE_PURPOSE (*chain) = build_class_reference_decl ();
2109 return TREE_PURPOSE (*chain);
2112 decl = build_class_reference_decl ();
2113 *chain = tree_cons (decl, ident, NULL_TREE);
2120 add_class_reference (ident);
2122 params = build_tree_list (NULL_TREE,
2123 my_build_string (IDENTIFIER_LENGTH (ident) + 1,
2124 IDENTIFIER_POINTER (ident)));
2126 assemble_external (objc_get_class_decl);
2127 return build_function_call (objc_get_class_decl, params);
2131 /* For each string section we have a chain which maps identifier nodes
2132 to decls for the strings. */
2135 add_objc_string (ident, section)
2137 enum string_section section;
2141 if (section == class_names)
2142 chain = &class_names_chain;
2143 else if (section == meth_var_names)
2144 chain = &meth_var_names_chain;
2145 else if (section == meth_var_types)
2146 chain = &meth_var_types_chain;
2152 if (TREE_VALUE (*chain) == ident)
2153 return build_unary_op (ADDR_EXPR, TREE_PURPOSE (*chain), 1);
2155 chain = &TREE_CHAIN (*chain);
2158 decl = build_objc_string_decl (section);
2160 *chain = tree_cons (decl, ident, NULL_TREE);
2162 return build_unary_op (ADDR_EXPR, decl, 1);
2166 build_objc_string_decl (section)
2167 enum string_section section;
2171 static int class_names_idx = 0;
2172 static int meth_var_names_idx = 0;
2173 static int meth_var_types_idx = 0;
2175 if (section == class_names)
2176 sprintf (buf, "_OBJC_CLASS_NAME_%d", class_names_idx++);
2177 else if (section == meth_var_names)
2178 sprintf (buf, "_OBJC_METH_VAR_NAME_%d", meth_var_names_idx++);
2179 else if (section == meth_var_types)
2180 sprintf (buf, "_OBJC_METH_VAR_TYPE_%d", meth_var_types_idx++);
2182 ident = get_identifier (buf);
2184 decl = build_decl (VAR_DECL, ident, build_array_type (char_type_node, 0));
2185 DECL_EXTERNAL (decl) = 1;
2186 TREE_PUBLIC (decl) = 1;
2187 TREE_USED (decl) = 1;
2188 TREE_READONLY (decl) = 1;
2189 TREE_CONSTANT (decl) = 1;
2190 DECL_CONTEXT (decl) = 0;
2191 DECL_ARTIFICIAL (decl) = 1;
2193 make_decl_rtl (decl, 0);
2194 pushdecl_top_level (decl);
2201 objc_declare_alias (alias_ident, class_ident)
2205 if (is_class_name (class_ident) != class_ident)
2206 warning ("cannot find class `%s'", IDENTIFIER_POINTER (class_ident));
2207 else if (is_class_name (alias_ident))
2208 warning ("class `%s' already exists", IDENTIFIER_POINTER (alias_ident));
2210 alias_chain = tree_cons (class_ident, alias_ident, alias_chain);
2214 objc_declare_class (ident_list)
2219 for (list = ident_list; list; list = TREE_CHAIN (list))
2221 tree ident = TREE_VALUE (list);
2224 if ((decl = lookup_name (ident)))
2226 error ("`%s' redeclared as different kind of symbol",
2227 IDENTIFIER_POINTER (ident));
2228 error_with_decl (decl, "previous declaration of `%s'");
2231 if (! is_class_name (ident))
2233 tree record = xref_tag (RECORD_TYPE, ident);
2234 TREE_STATIC_TEMPLATE (record) = 1;
2235 class_chain = tree_cons (NULL_TREE, ident, class_chain);
2241 is_class_name (ident)
2246 if (lookup_interface (ident))
2249 for (chain = class_chain; chain; chain = TREE_CHAIN (chain))
2251 if (ident == TREE_VALUE (chain))
2255 for (chain = alias_chain; chain; chain = TREE_CHAIN (chain))
2257 if (ident == TREE_VALUE (chain))
2258 return TREE_PURPOSE (chain);
2265 lookup_interface (ident)
2270 for (chain = interface_chain; chain; chain = TREE_CHAIN (chain))
2272 if (ident == CLASS_NAME (chain))
2278 /* Used by: build_private_template, continue_class,
2279 and for @defs constructs. */
2282 get_class_ivars (interface)
2285 tree my_name, super_name, ivar_chain;
2287 my_name = CLASS_NAME (interface);
2288 super_name = CLASS_SUPER_NAME (interface);
2289 ivar_chain = CLASS_IVARS (interface);
2291 /* Save off a pristine copy of the leaf ivars (i.e, those not
2292 inherited from a super class). */
2293 if (!CLASS_OWN_IVARS (interface))
2294 CLASS_OWN_IVARS (interface) = copy_list (ivar_chain);
2299 tree super_interface = lookup_interface (super_name);
2301 if (!super_interface)
2303 /* fatal did not work with 2 args...should fix */
2304 error ("cannot find interface declaration for `%s', superclass of `%s'",
2305 IDENTIFIER_POINTER (super_name),
2306 IDENTIFIER_POINTER (my_name));
2307 exit (FATAL_EXIT_CODE);
2310 if (super_interface == interface)
2311 fatal_error ("circular inheritance in interface declaration for `%s'",
2312 IDENTIFIER_POINTER (super_name));
2314 interface = super_interface;
2315 my_name = CLASS_NAME (interface);
2316 super_name = CLASS_SUPER_NAME (interface);
2318 op1 = CLASS_OWN_IVARS (interface);
2321 tree head = copy_list (op1);
2323 /* Prepend super class ivars...make a copy of the list, we
2324 do not want to alter the original. */
2325 chainon (head, ivar_chain);
2332 /* struct <classname> {
2333 struct objc_class *isa;
2338 build_private_template (class)
2343 if (CLASS_STATIC_TEMPLATE (class))
2345 uprivate_record = CLASS_STATIC_TEMPLATE (class);
2346 ivar_context = TYPE_FIELDS (CLASS_STATIC_TEMPLATE (class));
2350 uprivate_record = start_struct (RECORD_TYPE, CLASS_NAME (class));
2352 ivar_context = get_class_ivars (class);
2354 finish_struct (uprivate_record, ivar_context, NULL_TREE);
2356 CLASS_STATIC_TEMPLATE (class) = uprivate_record;
2358 /* mark this record as class template - for class type checking */
2359 TREE_STATIC_TEMPLATE (uprivate_record) = 1;
2363 = groktypename (build_tree_list (build_tree_list (NULL_TREE,
2365 build1 (INDIRECT_REF, NULL_TREE,
2368 return ivar_context;
2371 /* Begin code generation for protocols... */
2373 /* struct objc_protocol {
2374 char *protocol_name;
2375 struct objc_protocol **protocol_list;
2376 struct objc_method_desc *instance_methods;
2377 struct objc_method_desc *class_methods;
2381 build_protocol_template ()
2383 tree decl_specs, field_decl, field_decl_chain;
2386 template = start_struct (RECORD_TYPE, get_identifier (UTAG_PROTOCOL));
2388 /* struct objc_class *isa; */
2390 decl_specs = build_tree_list (NULL_TREE, xref_tag (RECORD_TYPE,
2391 get_identifier (UTAG_CLASS)));
2392 field_decl = build1 (INDIRECT_REF, NULL_TREE, get_identifier ("isa"));
2394 = grokfield (input_filename, lineno, field_decl, decl_specs, NULL_TREE);
2395 field_decl_chain = field_decl;
2397 /* char *protocol_name; */
2399 decl_specs = build_tree_list (NULL_TREE, ridpointers[(int) RID_CHAR]);
2401 = build1 (INDIRECT_REF, NULL_TREE, get_identifier ("protocol_name"));
2403 = grokfield (input_filename, lineno, field_decl, decl_specs, NULL_TREE);
2404 chainon (field_decl_chain, field_decl);
2406 /* struct objc_protocol **protocol_list; */
2408 decl_specs = build_tree_list (NULL_TREE, template);
2410 = build1 (INDIRECT_REF, NULL_TREE, get_identifier ("protocol_list"));
2411 field_decl = build1 (INDIRECT_REF, NULL_TREE, field_decl);
2413 = grokfield (input_filename, lineno, field_decl, decl_specs, NULL_TREE);
2414 chainon (field_decl_chain, field_decl);
2416 /* struct objc_method_list *instance_methods; */
2419 = build_tree_list (NULL_TREE,
2420 xref_tag (RECORD_TYPE,
2421 get_identifier (UTAG_METHOD_PROTOTYPE_LIST)));
2423 = build1 (INDIRECT_REF, NULL_TREE, get_identifier ("instance_methods"));
2425 = grokfield (input_filename, lineno, field_decl, decl_specs, NULL_TREE);
2426 chainon (field_decl_chain, field_decl);
2428 /* struct objc_method_list *class_methods; */
2431 = build_tree_list (NULL_TREE,
2432 xref_tag (RECORD_TYPE,
2433 get_identifier (UTAG_METHOD_PROTOTYPE_LIST)));
2435 = build1 (INDIRECT_REF, NULL_TREE, get_identifier ("class_methods"));
2437 = grokfield (input_filename, lineno, field_decl, decl_specs, NULL_TREE);
2438 chainon (field_decl_chain, field_decl);
2440 return finish_struct (template, field_decl_chain, NULL_TREE);
2444 build_descriptor_table_initializer (type, entries)
2448 tree initlist = NULL_TREE;
2452 tree eltlist = NULL_TREE;
2455 = tree_cons (NULL_TREE,
2456 build_selector (METHOD_SEL_NAME (entries)), NULL_TREE);
2458 = tree_cons (NULL_TREE,
2459 add_objc_string (METHOD_ENCODING (entries),
2464 = tree_cons (NULL_TREE,
2465 build_constructor (type, nreverse (eltlist)), initlist);
2467 entries = TREE_CHAIN (entries);
2471 return build_constructor (build_array_type (type, 0), nreverse (initlist));
2474 /* struct objc_method_prototype_list {
2476 struct objc_method_prototype {
2483 build_method_prototype_list_template (list_type, size)
2487 tree objc_ivar_list_record;
2488 tree decl_specs, field_decl, field_decl_chain;
2490 /* Generate an unnamed struct definition. */
2492 objc_ivar_list_record = start_struct (RECORD_TYPE, NULL_TREE);
2494 /* int method_count; */
2496 decl_specs = build_tree_list (NULL_TREE, ridpointers[(int) RID_INT]);
2497 field_decl = get_identifier ("method_count");
2500 = grokfield (input_filename, lineno, field_decl, decl_specs, NULL_TREE);
2501 field_decl_chain = field_decl;
2503 /* struct objc_method method_list[]; */
2505 decl_specs = build_tree_list (NULL_TREE, list_type);
2506 field_decl = build_nt (ARRAY_REF, get_identifier ("method_list"),
2507 build_int_2 (size, 0));
2510 = grokfield (input_filename, lineno, field_decl, decl_specs, NULL_TREE);
2511 chainon (field_decl_chain, field_decl);
2513 finish_struct (objc_ivar_list_record, field_decl_chain, NULL_TREE);
2515 return objc_ivar_list_record;
2519 build_method_prototype_template ()
2522 tree decl_specs, field_decl, field_decl_chain;
2525 = start_struct (RECORD_TYPE, get_identifier (UTAG_METHOD_PROTOTYPE));
2527 /* struct objc_selector *_cmd; */
2528 decl_specs = tree_cons (NULL_TREE, xref_tag (RECORD_TYPE,
2529 get_identifier (TAG_SELECTOR)), NULL_TREE);
2530 field_decl = build1 (INDIRECT_REF, NULL_TREE, get_identifier ("_cmd"));
2533 = grokfield (input_filename, lineno, field_decl, decl_specs, NULL_TREE);
2534 field_decl_chain = field_decl;
2536 decl_specs = tree_cons (NULL_TREE, ridpointers[(int) RID_CHAR], NULL_TREE);
2538 = build1 (INDIRECT_REF, NULL_TREE, get_identifier ("method_types"));
2540 = grokfield (input_filename, lineno, field_decl, decl_specs, NULL_TREE);
2541 chainon (field_decl_chain, field_decl);
2543 finish_struct (proto_record, field_decl_chain, NULL_TREE);
2545 return proto_record;
2548 /* True if last call to forwarding_offset yielded a register offset. */
2549 static int offset_is_register;
2552 forwarding_offset (parm)
2555 int offset_in_bytes;
2557 if (GET_CODE (DECL_INCOMING_RTL (parm)) == MEM)
2559 rtx addr = XEXP (DECL_INCOMING_RTL (parm), 0);
2561 /* ??? Here we assume that the parm address is indexed
2562 off the frame pointer or arg pointer.
2563 If that is not true, we produce meaningless results,
2564 but do not crash. */
2565 if (GET_CODE (addr) == PLUS
2566 && GET_CODE (XEXP (addr, 1)) == CONST_INT)
2567 offset_in_bytes = INTVAL (XEXP (addr, 1));
2569 offset_in_bytes = 0;
2571 offset_in_bytes += OBJC_FORWARDING_STACK_OFFSET;
2572 offset_is_register = 0;
2574 else if (GET_CODE (DECL_INCOMING_RTL (parm)) == REG)
2576 int regno = REGNO (DECL_INCOMING_RTL (parm));
2577 offset_in_bytes = apply_args_register_offset (regno);
2578 offset_is_register = 1;
2583 /* This is the case where the parm is passed as an int or double
2584 and it is converted to a char, short or float and stored back
2585 in the parmlist. In this case, describe the parm
2586 with the variable's declared type, and adjust the address
2587 if the least significant bytes (which we are using) are not
2589 if (BYTES_BIG_ENDIAN && TREE_TYPE (parm) != DECL_ARG_TYPE (parm))
2590 offset_in_bytes += (GET_MODE_SIZE (TYPE_MODE (DECL_ARG_TYPE (parm)))
2591 - GET_MODE_SIZE (GET_MODE (DECL_RTL (parm))));
2593 return offset_in_bytes;
2597 encode_method_prototype (method_decl, func_decl)
2604 HOST_WIDE_INT max_parm_end = 0;
2608 /* ONEWAY and BYCOPY, for remote object are the only method qualifiers. */
2609 encode_type_qualifiers (TREE_PURPOSE (TREE_TYPE (method_decl)));
2612 encode_type (TREE_TYPE (TREE_TYPE (func_decl)),
2613 obstack_object_size (&util_obstack),
2614 OBJC_ENCODE_INLINE_DEFS);
2617 for (parms = DECL_ARGUMENTS (func_decl); parms;
2618 parms = TREE_CHAIN (parms))
2620 HOST_WIDE_INT parm_end = (forwarding_offset (parms)
2621 + int_size_in_bytes (TREE_TYPE (parms)));
2623 if (!offset_is_register && max_parm_end < parm_end)
2624 max_parm_end = parm_end;
2627 stack_size = max_parm_end - OBJC_FORWARDING_MIN_OFFSET;
2629 sprintf (buf, "%d", stack_size);
2630 obstack_grow (&util_obstack, buf, strlen (buf));
2632 user_args = METHOD_SEL_ARGS (method_decl);
2634 /* Argument types. */
2635 for (parms = DECL_ARGUMENTS (func_decl), i = 0; parms;
2636 parms = TREE_CHAIN (parms), i++)
2638 /* Process argument qualifiers for user supplied arguments. */
2641 encode_type_qualifiers (TREE_PURPOSE (TREE_TYPE (user_args)));
2642 user_args = TREE_CHAIN (user_args);
2646 encode_type (TREE_TYPE (parms),
2647 obstack_object_size (&util_obstack),
2648 OBJC_ENCODE_INLINE_DEFS);
2650 /* Compute offset. */
2651 sprintf (buf, "%d", forwarding_offset (parms));
2653 /* Indicate register. */
2654 if (offset_is_register)
2655 obstack_1grow (&util_obstack, '+');
2657 obstack_grow (&util_obstack, buf, strlen (buf));
2660 obstack_1grow (&util_obstack, '\0');
2661 result = get_identifier (obstack_finish (&util_obstack));
2662 obstack_free (&util_obstack, util_firstobj);
2667 generate_descriptor_table (type, name, size, list, proto)
2674 tree sc_spec, decl_specs, decl, initlist;
2676 sc_spec = tree_cons (NULL_TREE, ridpointers[(int) RID_STATIC], NULL_TREE);
2677 decl_specs = tree_cons (NULL_TREE, type, sc_spec);
2679 decl = start_decl (synth_id_with_class_suffix (name, proto),
2680 decl_specs, 1, NULL_TREE);
2681 DECL_CONTEXT (decl) = NULL_TREE;
2683 initlist = build_tree_list (NULL_TREE, build_int_2 (size, 0));
2684 initlist = tree_cons (NULL_TREE, list, initlist);
2686 finish_decl (decl, build_constructor (type, nreverse (initlist)),
2693 generate_method_descriptors (protocol)
2696 tree initlist, chain, method_list_template;
2697 tree cast, variable_length_type;
2700 if (!objc_method_prototype_template)
2701 objc_method_prototype_template = build_method_prototype_template ();
2703 cast = build_tree_list (build_tree_list (NULL_TREE, xref_tag (RECORD_TYPE,
2704 get_identifier (UTAG_METHOD_PROTOTYPE_LIST))),
2706 variable_length_type = groktypename (cast);
2708 chain = PROTOCOL_CLS_METHODS (protocol);
2711 size = list_length (chain);
2713 method_list_template
2714 = build_method_prototype_list_template (objc_method_prototype_template,
2718 = build_descriptor_table_initializer (objc_method_prototype_template,
2721 UOBJC_CLASS_METHODS_decl
2722 = generate_descriptor_table (method_list_template,
2723 "_OBJC_PROTOCOL_CLASS_METHODS",
2724 size, initlist, protocol);
2725 TREE_TYPE (UOBJC_CLASS_METHODS_decl) = variable_length_type;
2728 UOBJC_CLASS_METHODS_decl = 0;
2730 chain = PROTOCOL_NST_METHODS (protocol);
2733 size = list_length (chain);
2735 method_list_template
2736 = build_method_prototype_list_template (objc_method_prototype_template,
2739 = build_descriptor_table_initializer (objc_method_prototype_template,
2742 UOBJC_INSTANCE_METHODS_decl
2743 = generate_descriptor_table (method_list_template,
2744 "_OBJC_PROTOCOL_INSTANCE_METHODS",
2745 size, initlist, protocol);
2746 TREE_TYPE (UOBJC_INSTANCE_METHODS_decl) = variable_length_type;
2749 UOBJC_INSTANCE_METHODS_decl = 0;
2752 /* Generate a temporary FUNCTION_DECL node to be used in
2753 hack_method_prototype below. */
2756 build_tmp_function_decl ()
2758 tree decl_specs, expr_decl, parms;
2762 /* struct objc_object *objc_xxx (id, SEL, ...); */
2764 decl_specs = build_tree_list (NULL_TREE, objc_object_reference);
2765 push_parm_decl (build_tree_list
2766 (build_tree_list (decl_specs,
2767 build1 (INDIRECT_REF, NULL_TREE,
2771 decl_specs = build_tree_list (NULL_TREE, xref_tag (RECORD_TYPE,
2772 get_identifier (TAG_SELECTOR)));
2773 expr_decl = build1 (INDIRECT_REF, NULL_TREE, NULL_TREE);
2775 push_parm_decl (build_tree_list (build_tree_list (decl_specs, expr_decl),
2777 parms = get_parm_info (0);
2780 decl_specs = build_tree_list (NULL_TREE, objc_object_reference);
2781 sprintf (buffer, "__objc_tmp_%x", xxx++);
2782 expr_decl = build_nt (CALL_EXPR, get_identifier (buffer), parms, NULL_TREE);
2783 expr_decl = build1 (INDIRECT_REF, NULL_TREE, expr_decl);
2785 return define_decl (expr_decl, decl_specs);
2788 /* Generate the prototypes for protocol methods. This is used to
2789 generate method encodings for these.
2791 NST_METHODS is the method to generate a _DECL node for TMP_DECL is
2792 a decl node to be used. This is also where the return value is
2796 hack_method_prototype (nst_methods, tmp_decl)
2803 /* Hack to avoid problem with static typing of self arg. */
2804 TREE_SET_CODE (nst_methods, CLASS_METHOD_DECL);
2805 start_method_def (nst_methods);
2806 TREE_SET_CODE (nst_methods, INSTANCE_METHOD_DECL);
2808 if (METHOD_ADD_ARGS (nst_methods) == objc_ellipsis_node)
2809 parms = get_parm_info (0); /* we have a `, ...' */
2811 parms = get_parm_info (1); /* place a `void_at_end' */
2813 poplevel (0, 0, 0); /* Must be called BEFORE start_function. */
2815 /* Usually called from store_parm_decls -> init_function_start. */
2817 DECL_ARGUMENTS (tmp_decl) = TREE_PURPOSE (parms);
2819 if (current_function_decl)
2821 current_function_decl = tmp_decl;
2824 /* Code taken from start_function. */
2825 tree restype = TREE_TYPE (TREE_TYPE (tmp_decl));
2826 /* Promote the value to int before returning it. */
2827 if (TREE_CODE (restype) == INTEGER_TYPE
2828 && TYPE_PRECISION (restype) < TYPE_PRECISION (integer_type_node))
2829 restype = integer_type_node;
2830 DECL_RESULT (tmp_decl) = build_decl (RESULT_DECL, 0, restype);
2833 for (parm = DECL_ARGUMENTS (tmp_decl); parm; parm = TREE_CHAIN (parm))
2834 DECL_CONTEXT (parm) = tmp_decl;
2836 init_function_start (tmp_decl, "objc-act", 0);
2838 /* Typically called from expand_function_start for function definitions. */
2839 assign_parms (tmp_decl);
2841 /* install return type */
2842 TREE_TYPE (TREE_TYPE (tmp_decl)) = groktypename (TREE_TYPE (nst_methods));
2844 current_function_decl = NULL;
2848 generate_protocol_references (plist)
2853 /* Forward declare protocols referenced. */
2854 for (lproto = plist; lproto; lproto = TREE_CHAIN (lproto))
2856 tree proto = TREE_VALUE (lproto);
2858 if (TREE_CODE (proto) == PROTOCOL_INTERFACE_TYPE
2859 && PROTOCOL_NAME (proto))
2861 if (! PROTOCOL_FORWARD_DECL (proto))
2862 build_protocol_reference (proto);
2864 if (PROTOCOL_LIST (proto))
2865 generate_protocol_references (PROTOCOL_LIST (proto));
2871 generate_protocols ()
2873 tree p, tmp_decl, encoding;
2874 tree sc_spec, decl_specs, decl;
2875 tree initlist, protocol_name_expr, refs_decl, refs_expr;
2878 tmp_decl = build_tmp_function_decl ();
2880 if (! objc_protocol_template)
2881 objc_protocol_template = build_protocol_template ();
2883 /* If a protocol was directly referenced, pull in indirect references. */
2884 for (p = protocol_chain; p; p = TREE_CHAIN (p))
2885 if (PROTOCOL_FORWARD_DECL (p) && PROTOCOL_LIST (p))
2886 generate_protocol_references (PROTOCOL_LIST (p));
2888 for (p = protocol_chain; p; p = TREE_CHAIN (p))
2890 tree nst_methods = PROTOCOL_NST_METHODS (p);
2891 tree cls_methods = PROTOCOL_CLS_METHODS (p);
2893 /* If protocol wasn't referenced, don't generate any code. */
2894 if (! PROTOCOL_FORWARD_DECL (p))
2897 /* Make sure we link in the Protocol class. */
2898 add_class_reference (get_identifier (PROTOCOL_OBJECT_CLASS_NAME));
2902 if (! METHOD_ENCODING (nst_methods))
2904 hack_method_prototype (nst_methods, tmp_decl);
2905 encoding = encode_method_prototype (nst_methods, tmp_decl);
2906 METHOD_ENCODING (nst_methods) = encoding;
2908 nst_methods = TREE_CHAIN (nst_methods);
2913 if (! METHOD_ENCODING (cls_methods))
2915 hack_method_prototype (cls_methods, tmp_decl);
2916 encoding = encode_method_prototype (cls_methods, tmp_decl);
2917 METHOD_ENCODING (cls_methods) = encoding;
2920 cls_methods = TREE_CHAIN (cls_methods);
2922 generate_method_descriptors (p);
2924 if (PROTOCOL_LIST (p))
2925 refs_decl = generate_protocol_list (p);
2929 /* static struct objc_protocol _OBJC_PROTOCOL_<mumble>; */
2931 sc_spec = tree_cons (NULL_TREE, ridpointers[(int) RID_STATIC],
2933 decl_specs = tree_cons (NULL_TREE, objc_protocol_template, sc_spec);
2935 decl = start_decl (synth_id_with_class_suffix ("_OBJC_PROTOCOL", p),
2936 decl_specs, 1, NULL_TREE);
2938 DECL_CONTEXT (decl) = NULL_TREE;
2940 protocol_name_expr = add_objc_string (PROTOCOL_NAME (p), class_names);
2946 (build_tree_list (build_tree_list (NULL_TREE,
2947 objc_protocol_template),
2948 build1 (INDIRECT_REF, NULL_TREE,
2949 build1 (INDIRECT_REF, NULL_TREE,
2952 refs_expr = build_unary_op (ADDR_EXPR, refs_decl, 0);
2953 TREE_TYPE (refs_expr) = cast_type2;
2956 refs_expr = build_int_2 (0, 0);
2958 /* UOBJC_INSTANCE_METHODS_decl/UOBJC_CLASS_METHODS_decl are set
2959 by generate_method_descriptors, which is called above. */
2960 initlist = build_protocol_initializer (TREE_TYPE (decl),
2961 protocol_name_expr, refs_expr,
2962 UOBJC_INSTANCE_METHODS_decl,
2963 UOBJC_CLASS_METHODS_decl);
2964 finish_decl (decl, initlist, NULL_TREE);
2966 /* Mark the decl as used to avoid "defined but not used" warning. */
2967 TREE_USED (decl) = 1;
2972 build_protocol_initializer (type, protocol_name, protocol_list,
2973 instance_methods, class_methods)
2977 tree instance_methods;
2980 tree initlist = NULL_TREE, expr;
2983 cast_type = groktypename
2985 (build_tree_list (NULL_TREE,
2986 xref_tag (RECORD_TYPE,
2987 get_identifier (UTAG_CLASS))),
2988 build1 (INDIRECT_REF, NULL_TREE, NULL_TREE)));
2990 /* Filling the "isa" in with one allows the runtime system to
2991 detect that the version change...should remove before final release. */
2993 expr = build_int_2 (PROTOCOL_VERSION, 0);
2994 TREE_TYPE (expr) = cast_type;
2995 initlist = tree_cons (NULL_TREE, expr, initlist);
2996 initlist = tree_cons (NULL_TREE, protocol_name, initlist);
2997 initlist = tree_cons (NULL_TREE, protocol_list, initlist);
2999 if (!instance_methods)
3000 initlist = tree_cons (NULL_TREE, build_int_2 (0, 0), initlist);
3003 expr = build_unary_op (ADDR_EXPR, instance_methods, 0);
3004 initlist = tree_cons (NULL_TREE, expr, initlist);
3008 initlist = tree_cons (NULL_TREE, build_int_2 (0, 0), initlist);
3011 expr = build_unary_op (ADDR_EXPR, class_methods, 0);
3012 initlist = tree_cons (NULL_TREE, expr, initlist);
3015 return build_constructor (type, nreverse (initlist));
3018 /* struct objc_category {
3019 char *category_name;
3021 struct objc_method_list *instance_methods;
3022 struct objc_method_list *class_methods;
3023 struct objc_protocol_list *protocols;
3027 build_category_template ()
3029 tree decl_specs, field_decl, field_decl_chain;
3031 objc_category_template = start_struct (RECORD_TYPE,
3032 get_identifier (UTAG_CATEGORY));
3033 /* char *category_name; */
3035 decl_specs = build_tree_list (NULL_TREE, ridpointers[(int) RID_CHAR]);
3037 = build1 (INDIRECT_REF, NULL_TREE, get_identifier ("category_name"));
3039 = grokfield (input_filename, lineno, field_decl, decl_specs, NULL_TREE);
3040 field_decl_chain = field_decl;
3042 /* char *class_name; */
3044 decl_specs = build_tree_list (NULL_TREE, ridpointers[(int) RID_CHAR]);
3045 field_decl = build1 (INDIRECT_REF, NULL_TREE, get_identifier ("class_name"));
3047 = grokfield (input_filename, lineno, field_decl, decl_specs, NULL_TREE);
3048 chainon (field_decl_chain, field_decl);
3050 /* struct objc_method_list *instance_methods; */
3052 decl_specs = build_tree_list (NULL_TREE,
3053 xref_tag (RECORD_TYPE,
3054 get_identifier (UTAG_METHOD_LIST)));
3056 = build1 (INDIRECT_REF, NULL_TREE, get_identifier ("instance_methods"));
3058 = grokfield (input_filename, lineno, field_decl, decl_specs, NULL_TREE);
3059 chainon (field_decl_chain, field_decl);
3061 /* struct objc_method_list *class_methods; */
3063 decl_specs = build_tree_list (NULL_TREE,
3064 xref_tag (RECORD_TYPE,
3065 get_identifier (UTAG_METHOD_LIST)));
3067 = build1 (INDIRECT_REF, NULL_TREE, get_identifier ("class_methods"));
3069 = grokfield (input_filename, lineno, field_decl, decl_specs, NULL_TREE);
3070 chainon (field_decl_chain, field_decl);
3072 /* struct objc_protocol **protocol_list; */
3074 decl_specs = build_tree_list (NULL_TREE,
3075 xref_tag (RECORD_TYPE,
3076 get_identifier (UTAG_PROTOCOL)));
3078 = build1 (INDIRECT_REF, NULL_TREE, get_identifier ("protocol_list"));
3079 field_decl = build1 (INDIRECT_REF, NULL_TREE, field_decl);
3081 = grokfield (input_filename, lineno, field_decl, decl_specs, NULL_TREE);
3082 chainon (field_decl_chain, field_decl);
3084 finish_struct (objc_category_template, field_decl_chain, NULL_TREE);
3087 /* struct objc_selector {
3093 build_selector_template ()
3096 tree decl_specs, field_decl, field_decl_chain;
3098 objc_selector_template
3099 = start_struct (RECORD_TYPE, get_identifier (UTAG_SELECTOR));
3103 decl_specs = build_tree_list (NULL_TREE, ridpointers[(int) RID_VOID]);
3104 field_decl = build1 (INDIRECT_REF, NULL_TREE, get_identifier ("sel_id"));
3106 = grokfield (input_filename, lineno, field_decl, decl_specs, NULL_TREE);
3107 field_decl_chain = field_decl;
3109 /* char *sel_type; */
3111 decl_specs = build_tree_list (NULL_TREE, ridpointers[(int) RID_CHAR]);
3112 field_decl = build1 (INDIRECT_REF, NULL_TREE, get_identifier ("sel_type"));
3114 = grokfield (input_filename, lineno, field_decl, decl_specs, NULL_TREE);
3115 chainon (field_decl_chain, field_decl);
3117 finish_struct (objc_selector_template, field_decl_chain, NULL_TREE);
3120 /* struct objc_class {
3121 struct objc_class *isa;
3122 struct objc_class *super_class;
3127 struct objc_ivar_list *ivars;
3128 struct objc_method_list *methods;
3129 if (flag_next_runtime)
3130 struct objc_cache *cache;
3132 struct sarray *dtable;
3133 struct objc_class *subclass_list;
3134 struct objc_class *sibling_class;
3136 struct objc_protocol_list *protocols;
3137 void *gc_object_type;
3141 build_class_template ()
3143 tree decl_specs, field_decl, field_decl_chain;
3146 = start_struct (RECORD_TYPE, get_identifier (UTAG_CLASS));
3148 /* struct objc_class *isa; */
3150 decl_specs = build_tree_list (NULL_TREE, objc_class_template);
3151 field_decl = build1 (INDIRECT_REF, NULL_TREE, get_identifier ("isa"));
3153 = grokfield (input_filename, lineno, field_decl, decl_specs, NULL_TREE);
3154 field_decl_chain = field_decl;
3156 /* struct objc_class *super_class; */
3158 decl_specs = build_tree_list (NULL_TREE, objc_class_template);
3160 = build1 (INDIRECT_REF, NULL_TREE, get_identifier ("super_class"));
3162 = grokfield (input_filename, lineno, field_decl, decl_specs, NULL_TREE);
3163 chainon (field_decl_chain, field_decl);
3167 decl_specs = build_tree_list (NULL_TREE, ridpointers[(int) RID_CHAR]);
3168 field_decl = build1 (INDIRECT_REF, NULL_TREE, get_identifier ("name"));
3170 = grokfield (input_filename, lineno, field_decl, decl_specs, NULL_TREE);
3171 chainon (field_decl_chain, field_decl);
3175 decl_specs = build_tree_list (NULL_TREE, ridpointers[(int) RID_LONG]);
3176 field_decl = get_identifier ("version");
3178 = grokfield (input_filename, lineno, field_decl, decl_specs, NULL_TREE);
3179 chainon (field_decl_chain, field_decl);
3183 decl_specs = build_tree_list (NULL_TREE, ridpointers[(int) RID_LONG]);
3184 field_decl = get_identifier ("info");
3186 = grokfield (input_filename, lineno, field_decl, decl_specs, NULL_TREE);
3187 chainon (field_decl_chain, field_decl);
3189 /* long instance_size; */
3191 decl_specs = build_tree_list (NULL_TREE, ridpointers[(int) RID_LONG]);
3192 field_decl = get_identifier ("instance_size");
3194 = grokfield (input_filename, lineno, field_decl, decl_specs, NULL_TREE);
3195 chainon (field_decl_chain, field_decl);
3197 /* struct objc_ivar_list *ivars; */
3199 decl_specs = build_tree_list (NULL_TREE,
3200 xref_tag (RECORD_TYPE,
3201 get_identifier (UTAG_IVAR_LIST)));
3202 field_decl = build1 (INDIRECT_REF, NULL_TREE, get_identifier ("ivars"));
3204 = grokfield (input_filename, lineno, field_decl, decl_specs, NULL_TREE);
3205 chainon (field_decl_chain, field_decl);
3207 /* struct objc_method_list *methods; */
3209 decl_specs = build_tree_list (NULL_TREE,
3210 xref_tag (RECORD_TYPE,
3211 get_identifier (UTAG_METHOD_LIST)));
3212 field_decl = build1 (INDIRECT_REF, NULL_TREE, get_identifier ("methods"));
3214 = grokfield (input_filename, lineno, field_decl, decl_specs, NULL_TREE);
3215 chainon (field_decl_chain, field_decl);
3217 if (flag_next_runtime)
3219 /* struct objc_cache *cache; */
3221 decl_specs = build_tree_list (NULL_TREE,
3222 xref_tag (RECORD_TYPE,
3223 get_identifier ("objc_cache")));
3224 field_decl = build1 (INDIRECT_REF, NULL_TREE, get_identifier ("cache"));
3225 field_decl = grokfield (input_filename, lineno, field_decl,
3226 decl_specs, NULL_TREE);
3227 chainon (field_decl_chain, field_decl);
3231 /* struct sarray *dtable; */
3233 decl_specs = build_tree_list (NULL_TREE,
3234 xref_tag (RECORD_TYPE,
3235 get_identifier ("sarray")));
3236 field_decl = build1 (INDIRECT_REF, NULL_TREE, get_identifier ("dtable"));
3237 field_decl = grokfield (input_filename, lineno, field_decl,
3238 decl_specs, NULL_TREE);
3239 chainon (field_decl_chain, field_decl);
3241 /* struct objc_class *subclass_list; */
3243 decl_specs = build_tree_list (NULL_TREE, objc_class_template);
3245 = build1 (INDIRECT_REF, NULL_TREE, get_identifier ("subclass_list"));
3246 field_decl = grokfield (input_filename, lineno, field_decl,
3247 decl_specs, NULL_TREE);
3248 chainon (field_decl_chain, field_decl);
3250 /* struct objc_class *sibling_class; */
3252 decl_specs = build_tree_list (NULL_TREE, objc_class_template);
3254 = build1 (INDIRECT_REF, NULL_TREE, get_identifier ("sibling_class"));
3255 field_decl = grokfield (input_filename, lineno, field_decl,
3256 decl_specs, NULL_TREE);
3257 chainon (field_decl_chain, field_decl);
3260 /* struct objc_protocol **protocol_list; */
3262 decl_specs = build_tree_list (NULL_TREE,
3263 xref_tag (RECORD_TYPE,
3264 get_identifier (UTAG_PROTOCOL)));
3266 = build1 (INDIRECT_REF, NULL_TREE, get_identifier ("protocol_list"));
3268 = build1 (INDIRECT_REF, NULL_TREE, field_decl);
3269 field_decl = grokfield (input_filename, lineno, field_decl,
3270 decl_specs, NULL_TREE);
3271 chainon (field_decl_chain, field_decl);
3275 decl_specs = build_tree_list (NULL_TREE, ridpointers[(int) RID_VOID]);
3276 field_decl = build1 (INDIRECT_REF, NULL_TREE, get_identifier ("sel_id"));
3278 = grokfield (input_filename, lineno, field_decl, decl_specs, NULL_TREE);
3279 chainon (field_decl_chain, field_decl);
3281 /* void *gc_object_type; */
3283 decl_specs = build_tree_list (NULL_TREE, ridpointers[(int) RID_VOID]);
3284 field_decl = build1 (INDIRECT_REF, NULL_TREE, get_identifier ("gc_object_type"));
3286 = grokfield (input_filename, lineno, field_decl, decl_specs, NULL_TREE);
3287 chainon (field_decl_chain, field_decl);
3289 finish_struct (objc_class_template, field_decl_chain, NULL_TREE);
3292 /* Generate appropriate forward declarations for an implementation. */
3295 synth_forward_declarations ()
3297 tree sc_spec, decl_specs, an_id;
3299 /* extern struct objc_class _OBJC_CLASS_<my_name>; */
3301 an_id = synth_id_with_class_suffix ("_OBJC_CLASS", objc_implementation_context);
3303 sc_spec = build_tree_list (NULL_TREE, ridpointers[(int) RID_EXTERN]);
3304 decl_specs = tree_cons (NULL_TREE, objc_class_template, sc_spec);
3305 UOBJC_CLASS_decl = define_decl (an_id, decl_specs);
3306 TREE_USED (UOBJC_CLASS_decl) = 1;
3307 DECL_ARTIFICIAL (UOBJC_CLASS_decl) = 1;
3309 /* extern struct objc_class _OBJC_METACLASS_<my_name>; */
3311 an_id = synth_id_with_class_suffix ("_OBJC_METACLASS",
3312 objc_implementation_context);
3314 UOBJC_METACLASS_decl = define_decl (an_id, decl_specs);
3315 TREE_USED (UOBJC_METACLASS_decl) = 1;
3316 DECL_ARTIFICIAL(UOBJC_METACLASS_decl) = 1;
3318 /* Pre-build the following entities - for speed/convenience. */
3320 an_id = get_identifier ("super_class");
3321 ucls_super_ref = build_component_ref (UOBJC_CLASS_decl, an_id);
3322 uucls_super_ref = build_component_ref (UOBJC_METACLASS_decl, an_id);
3326 error_with_ivar (message, decl, rawdecl)
3327 const char *message;
3331 diagnostic_count_diagnostic (global_dc, DK_ERROR);
3333 diagnostic_report_current_function (global_dc);
3335 error_with_file_and_line (DECL_SOURCE_FILE (decl),
3336 DECL_SOURCE_LINE (decl),
3338 message, gen_declaration (rawdecl, errbuf));
3343 check_ivars (inter, imp)
3347 tree intdecls = CLASS_IVARS (inter);
3348 tree impdecls = CLASS_IVARS (imp);
3349 tree rawintdecls = CLASS_RAW_IVARS (inter);
3350 tree rawimpdecls = CLASS_RAW_IVARS (imp);
3356 if (intdecls == 0 && impdecls == 0)
3358 if (intdecls == 0 || impdecls == 0)
3360 error ("inconsistent instance variable specification");
3364 t1 = TREE_TYPE (intdecls); t2 = TREE_TYPE (impdecls);
3366 if (!comptypes (t1, t2))
3368 if (DECL_NAME (intdecls) == DECL_NAME (impdecls))
3370 error_with_ivar ("conflicting instance variable type",
3371 impdecls, rawimpdecls);
3372 error_with_ivar ("previous declaration of",
3373 intdecls, rawintdecls);
3375 else /* both the type and the name don't match */
3377 error ("inconsistent instance variable specification");
3382 else if (DECL_NAME (intdecls) != DECL_NAME (impdecls))
3384 error_with_ivar ("conflicting instance variable name",
3385 impdecls, rawimpdecls);
3386 error_with_ivar ("previous declaration of",
3387 intdecls, rawintdecls);
3390 intdecls = TREE_CHAIN (intdecls);
3391 impdecls = TREE_CHAIN (impdecls);
3392 rawintdecls = TREE_CHAIN (rawintdecls);
3393 rawimpdecls = TREE_CHAIN (rawimpdecls);
3397 /* Set super_type to the data type node for struct objc_super *,
3398 first defining struct objc_super itself.
3399 This needs to be done just once per compilation. */
3402 build_super_template ()
3404 tree record, decl_specs, field_decl, field_decl_chain;
3406 record = start_struct (RECORD_TYPE, get_identifier (UTAG_SUPER));
3408 /* struct objc_object *self; */
3410 decl_specs = build_tree_list (NULL_TREE, objc_object_reference);
3411 field_decl = get_identifier ("self");
3412 field_decl = build1 (INDIRECT_REF, NULL_TREE, field_decl);
3413 field_decl = grokfield (input_filename, lineno,
3414 field_decl, decl_specs, NULL_TREE);
3415 field_decl_chain = field_decl;
3417 /* struct objc_class *class; */
3419 decl_specs = get_identifier (UTAG_CLASS);
3420 decl_specs = build_tree_list (NULL_TREE, xref_tag (RECORD_TYPE, decl_specs));
3421 field_decl = build1 (INDIRECT_REF, NULL_TREE, get_identifier ("class"));
3423 field_decl = grokfield (input_filename, lineno,
3424 field_decl, decl_specs, NULL_TREE);
3425 chainon (field_decl_chain, field_decl);
3427 finish_struct (record, field_decl_chain, NULL_TREE);
3429 /* `struct objc_super *' */
3430 super_type = groktypename (build_tree_list (build_tree_list (NULL_TREE,
3432 build1 (INDIRECT_REF,
3433 NULL_TREE, NULL_TREE)));
3437 /* struct objc_ivar {
3444 build_ivar_template ()
3446 tree objc_ivar_id, objc_ivar_record;
3447 tree decl_specs, field_decl, field_decl_chain;
3449 objc_ivar_id = get_identifier (UTAG_IVAR);
3450 objc_ivar_record = start_struct (RECORD_TYPE, objc_ivar_id);
3452 /* char *ivar_name; */
3454 decl_specs = build_tree_list (NULL_TREE, ridpointers[(int) RID_CHAR]);
3455 field_decl = build1 (INDIRECT_REF, NULL_TREE, get_identifier ("ivar_name"));
3457 field_decl = grokfield (input_filename, lineno, field_decl,
3458 decl_specs, NULL_TREE);
3459 field_decl_chain = field_decl;
3461 /* char *ivar_type; */
3463 decl_specs = build_tree_list (NULL_TREE, ridpointers[(int) RID_CHAR]);
3464 field_decl = build1 (INDIRECT_REF, NULL_TREE, get_identifier ("ivar_type"));
3466 field_decl = grokfield (input_filename, lineno, field_decl,
3467 decl_specs, NULL_TREE);
3468 chainon (field_decl_chain, field_decl);
3470 /* int ivar_offset; */
3472 decl_specs = build_tree_list (NULL_TREE, ridpointers[(int) RID_INT]);
3473 field_decl = get_identifier ("ivar_offset");
3475 field_decl = grokfield (input_filename, lineno, field_decl,
3476 decl_specs, NULL_TREE);
3477 chainon (field_decl_chain, field_decl);
3479 finish_struct (objc_ivar_record, field_decl_chain, NULL_TREE);
3481 return objc_ivar_record;
3486 struct objc_ivar ivar_list[ivar_count];
3490 build_ivar_list_template (list_type, size)
3494 tree objc_ivar_list_record;
3495 tree decl_specs, field_decl, field_decl_chain;
3497 objc_ivar_list_record = start_struct (RECORD_TYPE, NULL_TREE);
3499 /* int ivar_count; */
3501 decl_specs = build_tree_list (NULL_TREE, ridpointers[(int) RID_INT]);
3502 field_decl = get_identifier ("ivar_count");
3504 field_decl = grokfield (input_filename, lineno, field_decl,
3505 decl_specs, NULL_TREE);
3506 field_decl_chain = field_decl;
3508 /* struct objc_ivar ivar_list[]; */
3510 decl_specs = build_tree_list (NULL_TREE, list_type);
3511 field_decl = build_nt (ARRAY_REF, get_identifier ("ivar_list"),
3512 build_int_2 (size, 0));
3514 field_decl = grokfield (input_filename, lineno,
3515 field_decl, decl_specs, NULL_TREE);
3516 chainon (field_decl_chain, field_decl);
3518 finish_struct (objc_ivar_list_record, field_decl_chain, NULL_TREE);
3520 return objc_ivar_list_record;
3526 struct objc_method method_list[method_count];
3530 build_method_list_template (list_type, size)
3534 tree objc_ivar_list_record;
3535 tree decl_specs, field_decl, field_decl_chain;
3537 objc_ivar_list_record = start_struct (RECORD_TYPE, NULL_TREE);
3539 /* int method_next; */
3544 xref_tag (RECORD_TYPE,
3545 get_identifier (UTAG_METHOD_PROTOTYPE_LIST)));
3547 = build1 (INDIRECT_REF, NULL_TREE, get_identifier ("method_next"));
3548 field_decl = grokfield (input_filename, lineno, field_decl,
3549 decl_specs, NULL_TREE);
3550 field_decl_chain = field_decl;
3552 /* int method_count; */
3554 decl_specs = build_tree_list (NULL_TREE, ridpointers[(int) RID_INT]);
3555 field_decl = get_identifier ("method_count");
3557 field_decl = grokfield (input_filename, lineno,
3558 field_decl, decl_specs, NULL_TREE);
3559 chainon (field_decl_chain, field_decl);
3561 /* struct objc_method method_list[]; */
3563 decl_specs = build_tree_list (NULL_TREE, list_type);
3564 field_decl = build_nt (ARRAY_REF, get_identifier ("method_list"),
3565 build_int_2 (size, 0));
3567 field_decl = grokfield (input_filename, lineno,
3568 field_decl, decl_specs, NULL_TREE);
3569 chainon (field_decl_chain, field_decl);
3571 finish_struct (objc_ivar_list_record, field_decl_chain, NULL_TREE);
3573 return objc_ivar_list_record;
3577 build_ivar_list_initializer (type, field_decl)
3581 tree initlist = NULL_TREE;
3585 tree ivar = NULL_TREE;
3588 if (DECL_NAME (field_decl))
3589 ivar = tree_cons (NULL_TREE,
3590 add_objc_string (DECL_NAME (field_decl),
3594 /* Unnamed bit-field ivar (yuck). */
3595 ivar = tree_cons (NULL_TREE, build_int_2 (0, 0), ivar);
3598 encode_field_decl (field_decl,
3599 obstack_object_size (&util_obstack),
3600 OBJC_ENCODE_DONT_INLINE_DEFS);
3602 /* Null terminate string. */
3603 obstack_1grow (&util_obstack, 0);
3607 add_objc_string (get_identifier (obstack_finish (&util_obstack)),
3610 obstack_free (&util_obstack, util_firstobj);
3613 ivar = tree_cons (NULL_TREE, byte_position (field_decl), ivar);
3614 initlist = tree_cons (NULL_TREE,
3615 build_constructor (type, nreverse (ivar)),
3618 field_decl = TREE_CHAIN (field_decl);
3622 return build_constructor (build_array_type (type, 0), nreverse (initlist));
3626 generate_ivars_list (type, name, size, list)
3632 tree sc_spec, decl_specs, decl, initlist;
3634 sc_spec = tree_cons (NULL_TREE, ridpointers[(int) RID_STATIC], NULL_TREE);
3635 decl_specs = tree_cons (NULL_TREE, type, sc_spec);
3637 decl = start_decl (synth_id_with_class_suffix (name, objc_implementation_context),
3638 decl_specs, 1, NULL_TREE);
3640 initlist = build_tree_list (NULL_TREE, build_int_2 (size, 0));
3641 initlist = tree_cons (NULL_TREE, list, initlist);
3644 build_constructor (TREE_TYPE (decl), nreverse (initlist)),
3651 generate_ivar_lists ()
3653 tree initlist, ivar_list_template, chain;
3654 tree cast, variable_length_type;
3657 generating_instance_variables = 1;
3659 if (!objc_ivar_template)
3660 objc_ivar_template = build_ivar_template ();
3664 (build_tree_list (NULL_TREE, xref_tag (RECORD_TYPE,
3665 get_identifier (UTAG_IVAR_LIST))),
3667 variable_length_type = groktypename (cast);
3669 /* Only generate class variables for the root of the inheritance
3670 hierarchy since these will be the same for every class. */
3672 if (CLASS_SUPER_NAME (implementation_template) == NULL_TREE
3673 && (chain = TYPE_FIELDS (objc_class_template)))
3675 size = list_length (chain);
3677 ivar_list_template = build_ivar_list_template (objc_ivar_template, size);
3678 initlist = build_ivar_list_initializer (objc_ivar_template, chain);
3680 UOBJC_CLASS_VARIABLES_decl
3681 = generate_ivars_list (ivar_list_template, "_OBJC_CLASS_VARIABLES",
3683 TREE_TYPE (UOBJC_CLASS_VARIABLES_decl) = variable_length_type;
3686 UOBJC_CLASS_VARIABLES_decl = 0;
3688 chain = CLASS_IVARS (implementation_template);
3691 size = list_length (chain);
3692 ivar_list_template = build_ivar_list_template (objc_ivar_template, size);
3693 initlist = build_ivar_list_initializer (objc_ivar_template, chain);
3695 UOBJC_INSTANCE_VARIABLES_decl
3696 = generate_ivars_list (ivar_list_template, "_OBJC_INSTANCE_VARIABLES",
3698 TREE_TYPE (UOBJC_INSTANCE_VARIABLES_decl) = variable_length_type;
3701 UOBJC_INSTANCE_VARIABLES_decl = 0;
3703 generating_instance_variables = 0;
3707 build_dispatch_table_initializer (type, entries)
3711 tree initlist = NULL_TREE;
3715 tree elemlist = NULL_TREE;
3717 elemlist = tree_cons (NULL_TREE,
3718 build_selector (METHOD_SEL_NAME (entries)),
3721 /* Generate the method encoding if we don't have one already. */
3722 if (! METHOD_ENCODING (entries))
3723 METHOD_ENCODING (entries) =
3724 encode_method_def (METHOD_DEFINITION (entries));
3726 elemlist = tree_cons (NULL_TREE,
3727 add_objc_string (METHOD_ENCODING (entries),
3731 elemlist = tree_cons (NULL_TREE,
3732 build_unary_op (ADDR_EXPR,
3733 METHOD_DEFINITION (entries), 1),
3736 initlist = tree_cons (NULL_TREE,
3737 build_constructor (type, nreverse (elemlist)),
3740 entries = TREE_CHAIN (entries);
3744 return build_constructor (build_array_type (type, 0), nreverse (initlist));
3747 /* To accomplish method prototyping without generating all kinds of
3748 inane warnings, the definition of the dispatch table entries were
3751 struct objc_method { SEL _cmd; ...; id (*_imp)(); };
3753 struct objc_method { SEL _cmd; ...; void *_imp; }; */
3756 build_method_template ()
3759 tree decl_specs, field_decl, field_decl_chain;
3761 _SLT_record = start_struct (RECORD_TYPE, get_identifier (UTAG_METHOD));
3763 /* struct objc_selector *_cmd; */
3764 decl_specs = tree_cons (NULL_TREE,
3765 xref_tag (RECORD_TYPE,
3766 get_identifier (TAG_SELECTOR)),
3768 field_decl = build1 (INDIRECT_REF, NULL_TREE, get_identifier ("_cmd"));
3770 field_decl = grokfield (input_filename, lineno, field_decl,
3771 decl_specs, NULL_TREE);
3772 field_decl_chain = field_decl;
3774 decl_specs = tree_cons (NULL_TREE, ridpointers[(int) RID_CHAR], NULL_TREE);
3775 field_decl = build1 (INDIRECT_REF, NULL_TREE,
3776 get_identifier ("method_types"));
3777 field_decl = grokfield (input_filename, lineno, field_decl,
3778 decl_specs, NULL_TREE);
3779 chainon (field_decl_chain, field_decl);
3783 decl_specs = tree_cons (NULL_TREE, ridpointers[(int) RID_VOID], NULL_TREE);
3784 field_decl = build1 (INDIRECT_REF, NULL_TREE, get_identifier ("_imp"));
3785 field_decl = grokfield (input_filename, lineno, field_decl,
3786 decl_specs, NULL_TREE);
3787 chainon (field_decl_chain, field_decl);
3789 finish_struct (_SLT_record, field_decl_chain, NULL_TREE);
3796 generate_dispatch_table (type, name, size, list)
3802 tree sc_spec, decl_specs, decl, initlist;
3804 sc_spec = tree_cons (NULL_TREE, ridpointers[(int) RID_STATIC], NULL_TREE);
3805 decl_specs = tree_cons (NULL_TREE, type, sc_spec);
3807 decl = start_decl (synth_id_with_class_suffix (name, objc_implementation_context),
3808 decl_specs, 1, NULL_TREE);
3810 initlist = build_tree_list (NULL_TREE, build_int_2 (0, 0));
3811 initlist = tree_cons (NULL_TREE, build_int_2 (size, 0), initlist);
3812 initlist = tree_cons (NULL_TREE, list, initlist);
3815 build_constructor (TREE_TYPE (decl), nreverse (initlist)),
3822 generate_dispatch_tables ()
3824 tree initlist, chain, method_list_template;
3825 tree cast, variable_length_type;
3828 if (!objc_method_template)
3829 objc_method_template = build_method_template ();
3833 (build_tree_list (NULL_TREE,
3834 xref_tag (RECORD_TYPE,
3835 get_identifier (UTAG_METHOD_LIST))),
3838 variable_length_type = groktypename (cast);
3840 chain = CLASS_CLS_METHODS (objc_implementation_context);
3843 size = list_length (chain);
3845 method_list_template
3846 = build_method_list_template (objc_method_template, size);
3848 = build_dispatch_table_initializer (objc_method_template, chain);
3850 UOBJC_CLASS_METHODS_decl
3851 = generate_dispatch_table (method_list_template,
3852 ((TREE_CODE (objc_implementation_context)
3853 == CLASS_IMPLEMENTATION_TYPE)
3854 ? "_OBJC_CLASS_METHODS"
3855 : "_OBJC_CATEGORY_CLASS_METHODS"),
3857 TREE_TYPE (UOBJC_CLASS_METHODS_decl) = variable_length_type;
3860 UOBJC_CLASS_METHODS_decl = 0;
3862 chain = CLASS_NST_METHODS (objc_implementation_context);
3865 size = list_length (chain);
3867 method_list_template
3868 = build_method_list_template (objc_method_template, size);
3870 = build_dispatch_table_initializer (objc_method_template, chain);
3872 if (TREE_CODE (objc_implementation_context) == CLASS_IMPLEMENTATION_TYPE)
3873 UOBJC_INSTANCE_METHODS_decl
3874 = generate_dispatch_table (method_list_template,
3875 "_OBJC_INSTANCE_METHODS",
3878 /* We have a category. */
3879 UOBJC_INSTANCE_METHODS_decl
3880 = generate_dispatch_table (method_list_template,
3881 "_OBJC_CATEGORY_INSTANCE_METHODS",
3883 TREE_TYPE (UOBJC_INSTANCE_METHODS_decl) = variable_length_type;
3886 UOBJC_INSTANCE_METHODS_decl = 0;
3890 generate_protocol_list (i_or_p)
3893 tree initlist, decl_specs, sc_spec;
3894 tree refs_decl, expr_decl, lproto, e, plist;
3898 if (TREE_CODE (i_or_p) == CLASS_INTERFACE_TYPE
3899 || TREE_CODE (i_or_p) == CATEGORY_INTERFACE_TYPE)
3900 plist = CLASS_PROTOCOL_LIST (i_or_p);
3901 else if (TREE_CODE (i_or_p) == PROTOCOL_INTERFACE_TYPE)
3902 plist = PROTOCOL_LIST (i_or_p);
3906 cast_type = groktypename
3908 (build_tree_list (NULL_TREE,
3909 xref_tag (RECORD_TYPE,
3910 get_identifier (UTAG_PROTOCOL))),
3911 build1 (INDIRECT_REF, NULL_TREE, NULL_TREE)));
3914 for (lproto = plist; lproto; lproto = TREE_CHAIN (lproto))
3915 if (TREE_CODE (TREE_VALUE (lproto)) == PROTOCOL_INTERFACE_TYPE
3916 && PROTOCOL_FORWARD_DECL (TREE_VALUE (lproto)))
3919 /* Build initializer. */
3920 initlist = tree_cons (NULL_TREE, build_int_2 (0, 0), NULL_TREE);
3922 e = build_int_2 (size, 0);
3923 TREE_TYPE (e) = cast_type;
3924 initlist = tree_cons (NULL_TREE, e, initlist);
3926 for (lproto = plist; lproto; lproto = TREE_CHAIN (lproto))
3928 tree pval = TREE_VALUE (lproto);
3930 if (TREE_CODE (pval) == PROTOCOL_INTERFACE_TYPE
3931 && PROTOCOL_FORWARD_DECL (pval))
3933 e = build_unary_op (ADDR_EXPR, PROTOCOL_FORWARD_DECL (pval), 0);
3934 initlist = tree_cons (NULL_TREE, e, initlist);
3938 /* static struct objc_protocol *refs[n]; */
3940 sc_spec = tree_cons (NULL_TREE, ridpointers[(int) RID_STATIC], NULL_TREE);
3941 decl_specs = tree_cons (NULL_TREE, xref_tag (RECORD_TYPE,
3942 get_identifier (UTAG_PROTOCOL)),
3945 if (TREE_CODE (i_or_p) == PROTOCOL_INTERFACE_TYPE)
3946 expr_decl = build_nt (ARRAY_REF,
3947 synth_id_with_class_suffix ("_OBJC_PROTOCOL_REFS",
3949 build_int_2 (size + 2, 0));
3950 else if (TREE_CODE (i_or_p) == CLASS_INTERFACE_TYPE)
3951 expr_decl = build_nt (ARRAY_REF,
3952 synth_id_with_class_suffix ("_OBJC_CLASS_PROTOCOLS",
3954 build_int_2 (size + 2, 0));
3955 else if (TREE_CODE (i_or_p) == CATEGORY_INTERFACE_TYPE)
3957 = build_nt (ARRAY_REF,
3958 synth_id_with_class_suffix ("_OBJC_CATEGORY_PROTOCOLS",
3960 build_int_2 (size + 2, 0));
3964 expr_decl = build1 (INDIRECT_REF, NULL_TREE, expr_decl);
3966 refs_decl = start_decl (expr_decl, decl_specs, 1, NULL_TREE);
3967 DECL_CONTEXT (refs_decl) = NULL_TREE;
3969 finish_decl (refs_decl, build_constructor (TREE_TYPE (refs_decl),
3970 nreverse (initlist)),
3977 build_category_initializer (type, cat_name, class_name,
3978 instance_methods, class_methods, protocol_list)
3982 tree instance_methods;
3986 tree initlist = NULL_TREE, expr;
3988 initlist = tree_cons (NULL_TREE, cat_name, initlist);
3989 initlist = tree_cons (NULL_TREE, class_name, initlist);
3991 if (!instance_methods)
3992 initlist = tree_cons (NULL_TREE, build_int_2 (0, 0), initlist);
3995 expr = build_unary_op (ADDR_EXPR, instance_methods, 0);
3996 initlist = tree_cons (NULL_TREE, expr, initlist);
3999 initlist = tree_cons (NULL_TREE, build_int_2 (0, 0), initlist);
4002 expr = build_unary_op (ADDR_EXPR, class_methods, 0);
4003 initlist = tree_cons (NULL_TREE, expr, initlist);
4006 /* protocol_list = */
4008 initlist = tree_cons (NULL_TREE, build_int_2 (0, 0), initlist);
4011 tree cast_type2 = groktypename
4013 (build_tree_list (NULL_TREE,
4014 xref_tag (RECORD_TYPE,
4015 get_identifier (UTAG_PROTOCOL))),
4016 build1 (INDIRECT_REF, NULL_TREE,
4017 build1 (INDIRECT_REF, NULL_TREE, NULL_TREE))));
4019 expr = build_unary_op (ADDR_EXPR, protocol_list, 0);
4020 TREE_TYPE (expr) = cast_type2;
4021 initlist = tree_cons (NULL_TREE, expr, initlist);
4024 return build_constructor (type, nreverse (initlist));
4027 /* struct objc_class {
4028 struct objc_class *isa;
4029 struct objc_class *super_class;
4034 struct objc_ivar_list *ivars;
4035 struct objc_method_list *methods;
4036 if (flag_next_runtime)
4037 struct objc_cache *cache;
4039 struct sarray *dtable;
4040 struct objc_class *subclass_list;
4041 struct objc_class *sibling_class;
4043 struct objc_protocol_list *protocols;
4044 void *gc_object_type;
4048 build_shared_structure_initializer (type, isa, super, name, size, status,
4049 dispatch_table, ivar_list, protocol_list)
4056 tree dispatch_table;
4060 tree initlist = NULL_TREE, expr;
4063 initlist = tree_cons (NULL_TREE, isa, initlist);
4066 initlist = tree_cons (NULL_TREE, super, initlist);
4069 initlist = tree_cons (NULL_TREE, default_conversion (name), initlist);
4072 initlist = tree_cons (NULL_TREE, build_int_2 (0, 0), initlist);
4075 initlist = tree_cons (NULL_TREE, build_int_2 (status, 0), initlist);
4077 /* instance_size = */
4078 initlist = tree_cons (NULL_TREE, size, initlist);
4080 /* objc_ivar_list = */
4082 initlist = tree_cons (NULL_TREE, build_int_2 (0, 0), initlist);
4085 expr = build_unary_op (ADDR_EXPR, ivar_list, 0);
4086 initlist = tree_cons (NULL_TREE, expr, initlist);
4089 /* objc_method_list = */
4090 if (!dispatch_table)
4091 initlist = tree_cons (NULL_TREE, build_int_2 (0, 0), initlist);
4094 expr = build_unary_op (ADDR_EXPR, dispatch_table, 0);
4095 initlist = tree_cons (NULL_TREE, expr, initlist);
4098 if (flag_next_runtime)
4099 /* method_cache = */
4100 initlist = tree_cons (NULL_TREE, build_int_2 (0, 0), initlist);
4104 initlist = tree_cons (NULL_TREE, build_int_2 (0, 0), initlist);
4106 /* subclass_list = */
4107 initlist = tree_cons (NULL_TREE, build_int_2 (0, 0), initlist);
4109 /* sibling_class = */
4110 initlist = tree_cons (NULL_TREE, build_int_2 (0, 0), initlist);
4113 /* protocol_list = */
4114 if (! protocol_list)
4115 initlist = tree_cons (NULL_TREE, build_int_2 (0, 0), initlist);
4121 (build_tree_list (NULL_TREE,
4122 xref_tag (RECORD_TYPE,
4123 get_identifier (UTAG_PROTOCOL))),
4124 build1 (INDIRECT_REF, NULL_TREE,
4125 build1 (INDIRECT_REF, NULL_TREE, NULL_TREE))));
4127 expr = build_unary_op (ADDR_EXPR, protocol_list, 0);
4128 TREE_TYPE (expr) = cast_type2;
4129 initlist = tree_cons (NULL_TREE, expr, initlist);
4132 /* gc_object_type = NULL */
4133 initlist = tree_cons (NULL_TREE, build_int_2 (0, 0), initlist);
4135 return build_constructor (type, nreverse (initlist));
4138 /* static struct objc_category _OBJC_CATEGORY_<name> = { ... }; */
4141 generate_category (cat)
4144 tree sc_spec, decl_specs, decl;
4145 tree initlist, cat_name_expr, class_name_expr;
4146 tree protocol_decl, category;
4148 add_class_reference (CLASS_NAME (cat));
4149 cat_name_expr = add_objc_string (CLASS_SUPER_NAME (cat), class_names);
4151 class_name_expr = add_objc_string (CLASS_NAME (cat), class_names);
4153 category = CLASS_CATEGORY_LIST (implementation_template);
4155 /* find the category interface from the class it is associated with */
4158 if (CLASS_SUPER_NAME (cat) == CLASS_SUPER_NAME (category))
4160 category = CLASS_CATEGORY_LIST (category);
4163 if (category && CLASS_PROTOCOL_LIST (category))
4165 generate_protocol_references (CLASS_PROTOCOL_LIST (category));
4166 protocol_decl = generate_protocol_list (category);
4171 sc_spec = tree_cons (NULL_TREE, ridpointers[(int) RID_STATIC], NULL_TREE);
4172 decl_specs = tree_cons (NULL_TREE, objc_category_template, sc_spec);
4174 decl = start_decl (synth_id_with_class_suffix ("_OBJC_CATEGORY",
4175 objc_implementation_context),
4176 decl_specs, 1, NULL_TREE);
4178 initlist = build_category_initializer (TREE_TYPE (decl),
4179 cat_name_expr, class_name_expr,
4180 UOBJC_INSTANCE_METHODS_decl,
4181 UOBJC_CLASS_METHODS_decl,
4184 TREE_USED (decl) = 1;
4185 finish_decl (decl, initlist, NULL_TREE);
4188 /* static struct objc_class _OBJC_METACLASS_Foo={ ... };
4189 static struct objc_class _OBJC_CLASS_Foo={ ... }; */
4192 generate_shared_structures ()
4194 tree sc_spec, decl_specs, decl;
4195 tree name_expr, super_expr, root_expr;
4196 tree my_root_id = NULL_TREE, my_super_id = NULL_TREE;
4197 tree cast_type, initlist, protocol_decl;
4199 my_super_id = CLASS_SUPER_NAME (implementation_template);
4202 add_class_reference (my_super_id);
4204 /* Compute "my_root_id" - this is required for code generation.
4205 the "isa" for all meta class structures points to the root of
4206 the inheritance hierarchy (e.g. "__Object")... */
4207 my_root_id = my_super_id;
4210 tree my_root_int = lookup_interface (my_root_id);
4212 if (my_root_int && CLASS_SUPER_NAME (my_root_int))
4213 my_root_id = CLASS_SUPER_NAME (my_root_int);
4220 /* No super class. */
4221 my_root_id = CLASS_NAME (implementation_template);
4224 = groktypename (build_tree_list (build_tree_list (NULL_TREE,
4225 objc_class_template),
4226 build1 (INDIRECT_REF,
4227 NULL_TREE, NULL_TREE)));
4229 name_expr = add_objc_string (CLASS_NAME (implementation_template),
4232 /* Install class `isa' and `super' pointers at runtime. */
4235 super_expr = add_objc_string (my_super_id, class_names);
4236 super_expr = build_c_cast (cast_type, super_expr); /* cast! */
4239 super_expr = build_int_2 (0, 0);
4241 root_expr = add_objc_string (my_root_id, class_names);
4242 root_expr = build_c_cast (cast_type, root_expr); /* cast! */
4244 if (CLASS_PROTOCOL_LIST (implementation_template))
4246 generate_protocol_references
4247 (CLASS_PROTOCOL_LIST (implementation_template));
4248 protocol_decl = generate_protocol_list (implementation_template);
4253 /* static struct objc_class _OBJC_METACLASS_Foo = { ... }; */
4255 sc_spec = build_tree_list (NULL_TREE, ridpointers[(int) RID_STATIC]);
4256 decl_specs = tree_cons (NULL_TREE, objc_class_template, sc_spec);
4258 decl = start_decl (DECL_NAME (UOBJC_METACLASS_decl), decl_specs, 1,
4262 = build_shared_structure_initializer
4264 root_expr, super_expr, name_expr,
4265 convert (integer_type_node, TYPE_SIZE_UNIT (objc_class_template)),
4267 UOBJC_CLASS_METHODS_decl,
4268 UOBJC_CLASS_VARIABLES_decl,
4271 finish_decl (decl, initlist, NULL_TREE);
4273 /* static struct objc_class _OBJC_CLASS_Foo={ ... }; */
4275 decl = start_decl (DECL_NAME (UOBJC_CLASS_decl), decl_specs, 1,
4279 = build_shared_structure_initializer
4281 build_unary_op (ADDR_EXPR, UOBJC_METACLASS_decl, 0),
4282 super_expr, name_expr,
4283 convert (integer_type_node,
4284 TYPE_SIZE_UNIT (CLASS_STATIC_TEMPLATE
4285 (implementation_template))),
4287 UOBJC_INSTANCE_METHODS_decl,
4288 UOBJC_INSTANCE_VARIABLES_decl,
4291 finish_decl (decl, initlist, NULL_TREE);
4295 synth_id_with_class_suffix (preamble, ctxt)
4296 const char *preamble;
4300 if (TREE_CODE (ctxt) == CLASS_IMPLEMENTATION_TYPE
4301 || TREE_CODE (ctxt) == CLASS_INTERFACE_TYPE)
4303 const char *const class_name
4304 = IDENTIFIER_POINTER (CLASS_NAME (objc_implementation_context));
4305 string = (char *) alloca (strlen (preamble) + strlen (class_name) + 3);
4306 sprintf (string, "%s_%s", preamble,
4307 IDENTIFIER_POINTER (CLASS_NAME (ctxt)));
4309 else if (TREE_CODE (ctxt) == CATEGORY_IMPLEMENTATION_TYPE
4310 || TREE_CODE (ctxt) == CATEGORY_INTERFACE_TYPE)
4312 /* We have a category. */
4313 const char *const class_name
4314 = IDENTIFIER_POINTER (CLASS_NAME (objc_implementation_context));
4315 const char *const class_super_name
4316 = IDENTIFIER_POINTER (CLASS_SUPER_NAME (objc_implementation_context));
4317 string = (char *) alloca (strlen (preamble)
4318 + strlen (class_name)
4319 + strlen (class_super_name)
4321 sprintf (string, "%s_%s_%s", preamble, class_name, class_super_name);
4323 else if (TREE_CODE (ctxt) == PROTOCOL_INTERFACE_TYPE)
4325 const char *protocol_name = IDENTIFIER_POINTER (PROTOCOL_NAME (ctxt));
4327 = (char *) alloca (strlen (preamble) + strlen (protocol_name) + 3);
4328 sprintf (string, "%s_%s", preamble, protocol_name);
4333 return get_identifier (string);
4337 is_objc_type_qualifier (node)
4340 return (TREE_CODE (node) == IDENTIFIER_NODE
4341 && (node == ridpointers [(int) RID_CONST]
4342 || node == ridpointers [(int) RID_VOLATILE]
4343 || node == ridpointers [(int) RID_IN]
4344 || node == ridpointers [(int) RID_OUT]
4345 || node == ridpointers [(int) RID_INOUT]
4346 || node == ridpointers [(int) RID_BYCOPY]
4347 || node == ridpointers [(int) RID_BYREF]
4348 || node == ridpointers [(int) RID_ONEWAY]));
4351 /* If type is empty or only type qualifiers are present, add default
4352 type of id (otherwise grokdeclarator will default to int). */
4355 adjust_type_for_id_default (type)
4358 tree declspecs, chain;
4361 return build_tree_list (build_tree_list (NULL_TREE, objc_object_reference),
4362 build1 (INDIRECT_REF, NULL_TREE, NULL_TREE));
4364 declspecs = TREE_PURPOSE (type);
4366 /* Determine if a typespec is present. */
4367 for (chain = declspecs;
4369 chain = TREE_CHAIN (chain))
4371 if (TYPED_OBJECT (TREE_VALUE (chain))
4372 && !(TREE_VALUE (type)
4373 && TREE_CODE (TREE_VALUE (type)) == INDIRECT_REF))
4374 error ("can not use an object as parameter to a method\n");
4375 if (!is_objc_type_qualifier (TREE_VALUE (chain)))
4379 return build_tree_list (tree_cons (NULL_TREE, objc_object_reference,
4381 build1 (INDIRECT_REF, NULL_TREE, NULL_TREE));
4386 selector ':' '(' typename ')' identifier
4389 Transform an Objective-C keyword argument into
4390 the C equivalent parameter declarator.
4392 In: key_name, an "identifier_node" (optional).
4393 arg_type, a "tree_list" (optional).
4394 arg_name, an "identifier_node".
4396 Note: It would be really nice to strongly type the preceding
4397 arguments in the function prototype; however, then I
4398 could not use the "accessor" macros defined in "tree.h".
4400 Out: an instance of "keyword_decl". */
4403 build_keyword_decl (key_name, arg_type, arg_name)
4410 /* If no type is specified, default to "id". */
4411 arg_type = adjust_type_for_id_default (arg_type);
4413 keyword_decl = make_node (KEYWORD_DECL);
4415 TREE_TYPE (keyword_decl) = arg_type;
4416 KEYWORD_ARG_NAME (keyword_decl) = arg_name;
4417 KEYWORD_KEY_NAME (keyword_decl) = key_name;
4419 return keyword_decl;
4422 /* Given a chain of keyword_decl's, synthesize the full keyword selector. */
4425 build_keyword_selector (selector)
4429 tree key_chain, key_name;
4432 /* Scan the selector to see how much space we'll need. */
4433 for (key_chain = selector; key_chain; key_chain = TREE_CHAIN (key_chain))
4435 if (TREE_CODE (selector) == KEYWORD_DECL)
4436 key_name = KEYWORD_KEY_NAME (key_chain);
4437 else if (TREE_CODE (selector) == TREE_LIST)
4438 key_name = TREE_PURPOSE (key_chain);
4443 len += IDENTIFIER_LENGTH (key_name) + 1;
4445 /* Just a ':' arg. */
4449 buf = (char *) alloca (len + 1);
4450 /* Start the buffer out as an empty string. */
4453 for (key_chain = selector; key_chain; key_chain = TREE_CHAIN (key_chain))
4455 if (TREE_CODE (selector) == KEYWORD_DECL)
4456 key_name = KEYWORD_KEY_NAME (key_chain);
4457 else if (TREE_CODE (selector) == TREE_LIST)
4458 key_name = TREE_PURPOSE (key_chain);
4463 strcat (buf, IDENTIFIER_POINTER (key_name));
4467 return get_identifier (buf);
4470 /* Used for declarations and definitions. */
4473 build_method_decl (code, ret_type, selector, add_args)
4474 enum tree_code code;
4481 /* If no type is specified, default to "id". */
4482 ret_type = adjust_type_for_id_default (ret_type);
4484 method_decl = make_node (code);
4485 TREE_TYPE (method_decl) = ret_type;
4487 /* If we have a keyword selector, create an identifier_node that
4488 represents the full selector name (`:' included)... */
4489 if (TREE_CODE (selector) == KEYWORD_DECL)
4491 METHOD_SEL_NAME (method_decl) = build_keyword_selector (selector);
4492 METHOD_SEL_ARGS (method_decl) = selector;
4493 METHOD_ADD_ARGS (method_decl) = add_args;
4497 METHOD_SEL_NAME (method_decl) = selector;
4498 METHOD_SEL_ARGS (method_decl) = NULL_TREE;
4499 METHOD_ADD_ARGS (method_decl) = NULL_TREE;
4505 #define METHOD_DEF 0
4506 #define METHOD_REF 1
4508 /* Used by `build_objc_method_call' and `comp_method_types'. Return
4509 an argument list for method METH. CONTEXT is either METHOD_DEF or
4510 METHOD_REF, saying whether we are trying to define a method or call
4511 one. SUPERFLAG says this is for a send to super; this makes a
4512 difference for the NeXT calling sequence in which the lookup and
4513 the method call are done together. */
4516 get_arg_type_list (meth, context, superflag)
4523 /* Receiver type. */
4524 if (flag_next_runtime && superflag)
4525 arglist = build_tree_list (NULL_TREE, super_type);
4526 else if (context == METHOD_DEF)
4527 arglist = build_tree_list (NULL_TREE, TREE_TYPE (self_decl));
4529 arglist = build_tree_list (NULL_TREE, id_type);
4531 /* Selector type - will eventually change to `int'. */
4532 chainon (arglist, build_tree_list (NULL_TREE, selector_type));
4534 /* Build a list of argument types. */
4535 for (akey = METHOD_SEL_ARGS (meth); akey; akey = TREE_CHAIN (akey))
4537 tree arg_decl = groktypename_in_parm_context (TREE_TYPE (akey));
4538 chainon (arglist, build_tree_list (NULL_TREE, TREE_TYPE (arg_decl)));
4541 if (METHOD_ADD_ARGS (meth) == objc_ellipsis_node)
4542 /* We have a `, ...' immediately following the selector,
4543 finalize the arglist...simulate get_parm_info (0). */
4545 else if (METHOD_ADD_ARGS (meth))
4547 /* we have a variable length selector */
4548 tree add_arg_list = TREE_CHAIN (METHOD_ADD_ARGS (meth));
4549 chainon (arglist, add_arg_list);
4552 /* finalize the arglist...simulate get_parm_info (1) */
4553 chainon (arglist, build_tree_list (NULL_TREE, void_type_node));
4559 check_duplicates (hsh)
4562 tree meth = NULL_TREE;
4570 /* We have two methods with the same name and different types. */
4572 char type = (TREE_CODE (meth) == INSTANCE_METHOD_DECL) ? '-' : '+';
4574 warning ("multiple declarations for method `%s'",
4575 IDENTIFIER_POINTER (METHOD_SEL_NAME (meth)));
4577 warn_with_method ("using", type, meth);
4578 for (loop = hsh->list; loop; loop = loop->next)
4579 warn_with_method ("also found", type, loop->value);
4585 /* If RECEIVER is a class reference, return the identifier node for
4586 the referenced class. RECEIVER is created by get_class_reference,
4587 so we check the exact form created depending on which runtimes are
4591 receiver_is_class_object (receiver)
4594 tree chain, exp, arg;
4596 /* The receiver is 'self' in the context of a class method. */
4597 if (objc_method_context
4598 && receiver == self_decl
4599 && TREE_CODE (objc_method_context) == CLASS_METHOD_DECL)
4601 return CLASS_NAME (objc_implementation_context);
4604 if (flag_next_runtime)
4606 /* The receiver is a variable created by
4607 build_class_reference_decl. */
4608 if (TREE_CODE (receiver) == VAR_DECL
4609 && TREE_TYPE (receiver) == objc_class_type)
4610 /* Look up the identifier. */
4611 for (chain = cls_ref_chain; chain; chain = TREE_CHAIN (chain))
4612 if (TREE_PURPOSE (chain) == receiver)
4613 return TREE_VALUE (chain);
4617 /* The receiver is a function call that returns an id. Check if
4618 it is a call to objc_getClass, if so, pick up the class name. */
4619 if (TREE_CODE (receiver) == CALL_EXPR
4620 && (exp = TREE_OPERAND (receiver, 0))
4621 && TREE_CODE (exp) == ADDR_EXPR
4622 && (exp = TREE_OPERAND (exp, 0))
4623 && TREE_CODE (exp) == FUNCTION_DECL
4624 && exp == objc_get_class_decl
4625 /* We have a call to objc_getClass! */
4626 && (arg = TREE_OPERAND (receiver, 1))
4627 && TREE_CODE (arg) == TREE_LIST
4628 && (arg = TREE_VALUE (arg)))
4631 if (TREE_CODE (arg) == ADDR_EXPR
4632 && (arg = TREE_OPERAND (arg, 0))
4633 && TREE_CODE (arg) == STRING_CST)
4634 /* Finally, we have the class name. */
4635 return get_identifier (TREE_STRING_POINTER (arg));
4641 /* If we are currently building a message expr, this holds
4642 the identifier of the selector of the message. This is
4643 used when printing warnings about argument mismatches. */
4645 static tree current_objc_message_selector = 0;
4648 objc_message_selector ()
4650 return current_objc_message_selector;
4653 /* Construct an expression for sending a message.
4654 MESS has the object to send to in TREE_PURPOSE
4655 and the argument list (including selector) in TREE_VALUE.
4657 (*(<abstract_decl>(*)())_msg)(receiver, selTransTbl[n], ...);
4658 (*(<abstract_decl>(*)())_msgSuper)(receiver, selTransTbl[n], ...); */
4661 build_message_expr (mess)
4664 tree receiver = TREE_PURPOSE (mess);
4666 tree args = TREE_VALUE (mess);
4667 tree method_params = NULL_TREE;
4669 if (TREE_CODE (receiver) == ERROR_MARK)
4670 return error_mark_node;
4672 /* Obtain the full selector name. */
4673 if (TREE_CODE (args) == IDENTIFIER_NODE)
4674 /* A unary selector. */
4676 else if (TREE_CODE (args) == TREE_LIST)
4677 sel_name = build_keyword_selector (args);
4681 /* Build the parameter list to give to the method. */
4682 if (TREE_CODE (args) == TREE_LIST)
4684 tree chain = args, prev = NULL_TREE;
4686 /* We have a keyword selector--check for comma expressions. */
4689 tree element = TREE_VALUE (chain);
4691 /* We have a comma expression, must collapse... */
4692 if (TREE_CODE (element) == TREE_LIST)
4695 TREE_CHAIN (prev) = element;
4700 chain = TREE_CHAIN (chain);
4702 method_params = args;
4705 return finish_message_expr (receiver, sel_name, method_params);
4708 /* The 'finish_message_expr' routine is called from within
4709 'build_message_expr' for non-template functions. In the case of
4710 C++ template functions, it is called from 'build_expr_from_tree'
4711 (in decl2.c) after RECEIVER and METHOD_PARAMS have been expanded. */
4714 finish_message_expr (receiver, sel_name, method_params)
4715 tree receiver, sel_name, method_params;
4717 tree method_prototype = NULL_TREE, class_ident = NULL_TREE;
4718 tree selector, self_object, retval;
4719 int statically_typed = 0, statically_allocated = 0;
4721 /* Determine receiver type. */
4722 tree rtype = TREE_TYPE (receiver);
4723 int super = IS_SUPER (rtype);
4727 if (TREE_STATIC_TEMPLATE (rtype))
4728 statically_allocated = 1;
4729 else if (TREE_CODE (rtype) == POINTER_TYPE
4730 && TREE_STATIC_TEMPLATE (TREE_TYPE (rtype)))
4731 statically_typed = 1;
4732 else if ((flag_next_runtime
4734 && (class_ident = receiver_is_class_object (receiver)))
4736 else if (! IS_ID (rtype)
4737 /* Allow any type that matches objc_class_type. */
4738 && ! comptypes (rtype, objc_class_type))
4740 warning ("invalid receiver type `%s'",
4741 gen_declaration (rtype, errbuf));
4743 if (statically_allocated)
4744 receiver = build_unary_op (ADDR_EXPR, receiver, 0);
4746 /* Don't evaluate the receiver twice. */
4747 receiver = save_expr (receiver);
4748 self_object = receiver;
4751 /* If sending to `super', use current self as the object. */
4752 self_object = self_decl;
4754 /* Determine operation return type. */
4760 if (CLASS_SUPER_NAME (implementation_template))
4763 = lookup_interface (CLASS_SUPER_NAME (implementation_template));
4765 if (TREE_CODE (objc_method_context) == INSTANCE_METHOD_DECL)
4766 method_prototype = lookup_instance_method_static (iface, sel_name);
4768 method_prototype = lookup_class_method_static (iface, sel_name);
4770 if (iface && !method_prototype)
4771 warning ("`%s' does not respond to `%s'",
4772 IDENTIFIER_POINTER (CLASS_SUPER_NAME (implementation_template)),
4773 IDENTIFIER_POINTER (sel_name));
4777 error ("no super class declared in interface for `%s'",
4778 IDENTIFIER_POINTER (CLASS_NAME (implementation_template)));
4779 return error_mark_node;
4783 else if (statically_allocated)
4785 tree ctype = TREE_TYPE (rtype);
4786 tree iface = lookup_interface (TYPE_NAME (rtype));
4789 method_prototype = lookup_instance_method_static (iface, sel_name);
4791 if (! method_prototype && TYPE_PROTOCOL_LIST (ctype))
4793 = lookup_method_in_protocol_list (TYPE_PROTOCOL_LIST (ctype),
4796 if (!method_prototype)
4797 warning ("`%s' does not respond to `%s'",
4798 IDENTIFIER_POINTER (TYPE_NAME (rtype)),
4799 IDENTIFIER_POINTER (sel_name));
4801 else if (statically_typed)
4803 tree ctype = TREE_TYPE (rtype);
4805 /* `self' is now statically_typed. All methods should be visible
4806 within the context of the implementation. */
4807 if (objc_implementation_context
4808 && CLASS_NAME (objc_implementation_context) == TYPE_NAME (ctype))
4811 = lookup_instance_method_static (implementation_template,
4814 if (! method_prototype && TYPE_PROTOCOL_LIST (ctype))
4816 = lookup_method_in_protocol_list (TYPE_PROTOCOL_LIST (ctype),
4819 if (! method_prototype
4820 && implementation_template != objc_implementation_context)
4821 /* The method is not published in the interface. Check
4824 = lookup_method (CLASS_NST_METHODS (objc_implementation_context),
4831 if ((iface = lookup_interface (TYPE_NAME (ctype))))
4832 method_prototype = lookup_instance_method_static (iface, sel_name);
4834 if (! method_prototype)
4836 tree protocol_list = TYPE_PROTOCOL_LIST (ctype);
4839 = lookup_method_in_protocol_list (protocol_list,
4844 if (!method_prototype)
4845 warning ("`%s' does not respond to `%s'",
4846 IDENTIFIER_POINTER (TYPE_NAME (ctype)),
4847 IDENTIFIER_POINTER (sel_name));
4849 else if (class_ident)
4851 if (objc_implementation_context
4852 && CLASS_NAME (objc_implementation_context) == class_ident)
4855 = lookup_class_method_static (implementation_template, sel_name);
4857 if (!method_prototype
4858 && implementation_template != objc_implementation_context)
4859 /* The method is not published in the interface. Check
4862 = lookup_method (CLASS_CLS_METHODS (objc_implementation_context),
4869 if ((iface = lookup_interface (class_ident)))
4870 method_prototype = lookup_class_method_static (iface, sel_name);
4873 if (!method_prototype)
4875 warning ("cannot find class (factory) method");
4876 warning ("return type for `%s' defaults to id",
4877 IDENTIFIER_POINTER (sel_name));
4880 else if (IS_PROTOCOL_QUALIFIED_ID (rtype))
4882 /* An anonymous object that has been qualified with a protocol. */
4884 tree protocol_list = TYPE_PROTOCOL_LIST (rtype);
4886 method_prototype = lookup_method_in_protocol_list (protocol_list,
4889 if (!method_prototype)
4893 warning ("method `%s' not implemented by protocol",
4894 IDENTIFIER_POINTER (sel_name));
4896 /* Try and find the method signature in the global pools. */
4898 if (!(hsh = hash_lookup (nst_method_hash_list, sel_name)))
4899 hsh = hash_lookup (cls_method_hash_list, sel_name);
4901 if (!(method_prototype = check_duplicates (hsh)))
4902 warning ("return type defaults to id");
4909 /* We think we have an instance...loophole: extern id Object; */
4910 hsh = hash_lookup (nst_method_hash_list, sel_name);
4913 /* For various loopholes */
4914 hsh = hash_lookup (cls_method_hash_list, sel_name);
4916 method_prototype = check_duplicates (hsh);
4917 if (!method_prototype)
4919 warning ("cannot find method");
4920 warning ("return type for `%s' defaults to id",
4921 IDENTIFIER_POINTER (sel_name));
4925 /* Save the selector name for printing error messages. */
4926 current_objc_message_selector = sel_name;
4928 /* Build the parameters list for looking up the method.
4929 These are the object itself and the selector. */
4931 if (flag_typed_selectors)
4932 selector = build_typed_selector_reference (sel_name, method_prototype);
4934 selector = build_selector_reference (sel_name);
4936 retval = build_objc_method_call (super, method_prototype,
4937 receiver, self_object,
4938 selector, method_params);
4940 current_objc_message_selector = 0;
4945 /* Build a tree expression to send OBJECT the operation SELECTOR,
4946 looking up the method on object LOOKUP_OBJECT (often same as OBJECT),
4947 assuming the method has prototype METHOD_PROTOTYPE.
4948 (That is an INSTANCE_METHOD_DECL or CLASS_METHOD_DECL.)
4949 Use METHOD_PARAMS as list of args to pass to the method.
4950 If SUPER_FLAG is nonzero, we look up the superclass's method. */
4953 build_objc_method_call (super_flag, method_prototype, lookup_object, object,
4954 selector, method_params)
4956 tree method_prototype, lookup_object, object, selector, method_params;
4958 tree sender = (super_flag ? umsg_super_decl : umsg_decl);
4959 tree rcv_p = (super_flag
4960 ? build_pointer_type (xref_tag (RECORD_TYPE,
4961 get_identifier (TAG_SUPER)))
4964 if (flag_next_runtime)
4966 if (! method_prototype)
4968 method_params = tree_cons (NULL_TREE, lookup_object,
4969 tree_cons (NULL_TREE, selector,
4971 assemble_external (sender);
4972 return build_function_call (sender, method_params);
4976 /* This is a real kludge, but it is used only for the Next.
4977 Clobber the data type of SENDER temporarily to accept
4978 all the arguments for this operation, and to return
4979 whatever this operation returns. */
4980 tree arglist = NULL_TREE, retval, savarg, savret;
4981 tree ret_type = groktypename (TREE_TYPE (method_prototype));
4983 /* Save the proper contents of SENDER's data type. */
4984 savarg = TYPE_ARG_TYPES (TREE_TYPE (sender));
4985 savret = TREE_TYPE (TREE_TYPE (sender));
4987 /* Install this method's argument types. */
4988 arglist = get_arg_type_list (method_prototype, METHOD_REF,
4990 TYPE_ARG_TYPES (TREE_TYPE (sender)) = arglist;
4992 /* Install this method's return type. */
4993 TREE_TYPE (TREE_TYPE (sender)) = ret_type;
4995 /* Call SENDER with all the parameters. This will do type
4996 checking using the arg types for this method. */
4997 method_params = tree_cons (NULL_TREE, lookup_object,
4998 tree_cons (NULL_TREE, selector,
5000 assemble_external (sender);
5001 retval = build_function_call (sender, method_params);
5003 /* Restore SENDER's return/argument types. */
5004 TYPE_ARG_TYPES (TREE_TYPE (sender)) = savarg;
5005 TREE_TYPE (TREE_TYPE (sender)) = savret;
5011 /* This is the portable way.
5012 First call the lookup function to get a pointer to the method,
5013 then cast the pointer, then call it with the method arguments. */
5016 /* Avoid trouble since we may evaluate each of these twice. */
5017 object = save_expr (object);
5018 selector = save_expr (selector);
5020 lookup_object = build_c_cast (rcv_p, lookup_object);
5022 assemble_external (sender);
5024 = build_function_call (sender,
5025 tree_cons (NULL_TREE, lookup_object,
5026 tree_cons (NULL_TREE, selector,
5029 /* If we have a method prototype, construct the data type this
5030 method needs, and cast what we got from SENDER into a pointer
5032 if (method_prototype)
5034 tree arglist = get_arg_type_list (method_prototype, METHOD_REF,
5036 tree valtype = groktypename (TREE_TYPE (method_prototype));
5037 tree fake_function_type = build_function_type (valtype, arglist);
5038 TREE_TYPE (method) = build_pointer_type (fake_function_type);
5042 = build_pointer_type (build_function_type (ptr_type_node, NULL_TREE));
5044 /* Pass the object to the method. */
5045 assemble_external (method);
5046 return build_function_call (method,
5047 tree_cons (NULL_TREE, object,
5048 tree_cons (NULL_TREE, selector,
5054 build_protocol_reference (p)
5057 tree decl, ident, ptype;
5059 /* extern struct objc_protocol _OBJC_PROTOCOL_<mumble>; */
5061 ident = synth_id_with_class_suffix ("_OBJC_PROTOCOL", p);
5063 = groktypename (build_tree_list (build_tree_list (NULL_TREE,
5064 objc_protocol_template),
5067 if (IDENTIFIER_GLOBAL_VALUE (ident))
5068 decl = IDENTIFIER_GLOBAL_VALUE (ident); /* Set by pushdecl. */
5071 decl = build_decl (VAR_DECL, ident, ptype);
5072 DECL_EXTERNAL (decl) = 1;
5073 TREE_PUBLIC (decl) = 1;
5074 TREE_USED (decl) = 1;
5075 DECL_ARTIFICIAL (decl) = 1;
5077 make_decl_rtl (decl, 0);
5078 pushdecl_top_level (decl);
5081 PROTOCOL_FORWARD_DECL (p) = decl;
5085 build_protocol_expr (protoname)
5089 tree p = lookup_protocol (protoname);
5093 error ("cannot find protocol declaration for `%s'",
5094 IDENTIFIER_POINTER (protoname));
5095 return error_mark_node;
5098 if (!PROTOCOL_FORWARD_DECL (p))
5099 build_protocol_reference (p);
5101 expr = build_unary_op (ADDR_EXPR, PROTOCOL_FORWARD_DECL (p), 0);
5103 TREE_TYPE (expr) = protocol_type;
5108 /* This function is called by the parser when a @selector() expression
5109 is found, in order to compile it. It is only called by the parser
5110 and only to compile a @selector(). */
5112 build_selector_expr (selnamelist)
5117 /* Obtain the full selector name. */
5118 if (TREE_CODE (selnamelist) == IDENTIFIER_NODE)
5119 /* A unary selector. */
5120 selname = selnamelist;
5121 else if (TREE_CODE (selnamelist) == TREE_LIST)
5122 selname = build_keyword_selector (selnamelist);
5126 /* If we are required to check @selector() expressions as they
5127 are found, check that the selector has been declared. */
5128 if (warn_undeclared_selector)
5130 /* Look the selector up in the list of all known class and
5131 instance methods (up to this line) to check that the selector
5135 /* First try with instance methods. */
5136 hsh = hash_lookup (nst_method_hash_list, selname);
5138 /* If not found, try with class methods. */
5141 hsh = hash_lookup (cls_method_hash_list, selname);
5144 /* If still not found, print out a warning. */
5147 warning ("undeclared selector `%s'", IDENTIFIER_POINTER (selname));
5152 if (flag_typed_selectors)
5153 return build_typed_selector_reference (selname, 0);
5155 return build_selector_reference (selname);
5159 build_encode_expr (type)
5165 encode_type (type, obstack_object_size (&util_obstack),
5166 OBJC_ENCODE_INLINE_DEFS);
5167 obstack_1grow (&util_obstack, 0); /* null terminate string */
5168 string = obstack_finish (&util_obstack);
5170 /* Synthesize a string that represents the encoded struct/union. */
5171 result = my_build_string (strlen (string) + 1, string);
5172 obstack_free (&util_obstack, util_firstobj);
5177 build_ivar_reference (id)
5180 if (TREE_CODE (objc_method_context) == CLASS_METHOD_DECL)
5182 /* Historically, a class method that produced objects (factory
5183 method) would assign `self' to the instance that it
5184 allocated. This would effectively turn the class method into
5185 an instance method. Following this assignment, the instance
5186 variables could be accessed. That practice, while safe,
5187 violates the simple rule that a class method should not refer
5188 to an instance variable. It's better to catch the cases
5189 where this is done unknowingly than to support the above
5191 warning ("instance variable `%s' accessed in class method",
5192 IDENTIFIER_POINTER (id));
5193 TREE_TYPE (self_decl) = instance_type; /* cast */
5196 return build_component_ref (build_indirect_ref (self_decl, "->"), id);
5199 /* Compute a hash value for a given method SEL_NAME. */
5202 hash_func (sel_name)
5205 const unsigned char *s
5206 = (const unsigned char *)IDENTIFIER_POINTER (sel_name);
5210 h = h * 67 + *s++ - 113;
5217 nst_method_hash_list = (hash *) ggc_calloc (SIZEHASHTABLE, sizeof (hash));
5218 cls_method_hash_list = (hash *) ggc_calloc (SIZEHASHTABLE, sizeof (hash));
5221 /* WARNING!!!! hash_enter is called with a method, and will peek
5222 inside to find its selector! But hash_lookup is given a selector
5223 directly, and looks for the selector that's inside the found
5224 entry's key (method) for comparison. */
5227 hash_enter (hashlist, method)
5232 int slot = hash_func (METHOD_SEL_NAME (method)) % SIZEHASHTABLE;
5234 obj = (hash) ggc_alloc (sizeof (struct hashed_entry));
5236 obj->next = hashlist[slot];
5239 hashlist[slot] = obj; /* append to front */
5243 hash_lookup (hashlist, sel_name)
5249 target = hashlist[hash_func (sel_name) % SIZEHASHTABLE];
5253 if (sel_name == METHOD_SEL_NAME (target->key))
5256 target = target->next;
5262 hash_add_attr (entry, value)
5268 obj = (attr) ggc_alloc (sizeof (struct hashed_attribute));
5269 obj->next = entry->list;
5272 entry->list = obj; /* append to front */
5276 lookup_method (mchain, method)
5282 if (TREE_CODE (method) == IDENTIFIER_NODE)
5285 key = METHOD_SEL_NAME (method);
5289 if (METHOD_SEL_NAME (mchain) == key)
5292 mchain = TREE_CHAIN (mchain);
5298 lookup_instance_method_static (interface, ident)
5302 tree inter = interface;
5303 tree chain = CLASS_NST_METHODS (inter);
5304 tree meth = NULL_TREE;
5308 if ((meth = lookup_method (chain, ident)))
5311 if (CLASS_CATEGORY_LIST (inter))
5313 tree category = CLASS_CATEGORY_LIST (inter);
5314 chain = CLASS_NST_METHODS (category);
5318 if ((meth = lookup_method (chain, ident)))
5321 /* Check for instance methods in protocols in categories. */
5322 if (CLASS_PROTOCOL_LIST (category))
5324 if ((meth = (lookup_method_in_protocol_list
5325 (CLASS_PROTOCOL_LIST (category), ident, 0))))
5329 if ((category = CLASS_CATEGORY_LIST (category)))
5330 chain = CLASS_NST_METHODS (category);
5335 if (CLASS_PROTOCOL_LIST (inter))
5337 if ((meth = (lookup_method_in_protocol_list
5338 (CLASS_PROTOCOL_LIST (inter), ident, 0))))
5342 if ((inter = lookup_interface (CLASS_SUPER_NAME (inter))))
5343 chain = CLASS_NST_METHODS (inter);
5351 lookup_class_method_static (interface, ident)
5355 tree inter = interface;
5356 tree chain = CLASS_CLS_METHODS (inter);
5357 tree meth = NULL_TREE;
5358 tree root_inter = NULL_TREE;
5362 if ((meth = lookup_method (chain, ident)))
5365 if (CLASS_CATEGORY_LIST (inter))
5367 tree category = CLASS_CATEGORY_LIST (inter);
5368 chain = CLASS_CLS_METHODS (category);
5372 if ((meth = lookup_method (chain, ident)))
5375 /* Check for class methods in protocols in categories. */
5376 if (CLASS_PROTOCOL_LIST (category))
5378 if ((meth = (lookup_method_in_protocol_list
5379 (CLASS_PROTOCOL_LIST (category), ident, 1))))
5383 if ((category = CLASS_CATEGORY_LIST (category)))
5384 chain = CLASS_CLS_METHODS (category);
5389 /* Check for class methods in protocols. */
5390 if (CLASS_PROTOCOL_LIST (inter))
5392 if ((meth = (lookup_method_in_protocol_list
5393 (CLASS_PROTOCOL_LIST (inter), ident, 1))))
5398 if ((inter = lookup_interface (CLASS_SUPER_NAME (inter))))
5399 chain = CLASS_CLS_METHODS (inter);
5403 /* If no class (factory) method was found, check if an _instance_
5404 method of the same name exists in the root class. This is what
5405 the Objective-C runtime will do. */
5406 return lookup_instance_method_static (root_inter, ident);
5410 add_class_method (class, method)
5417 if (!(mth = lookup_method (CLASS_CLS_METHODS (class), method)))
5419 /* put method on list in reverse order */
5420 TREE_CHAIN (method) = CLASS_CLS_METHODS (class);
5421 CLASS_CLS_METHODS (class) = method;
5425 if (TREE_CODE (class) == CLASS_IMPLEMENTATION_TYPE)
5426 error ("duplicate definition of class method `%s'",
5427 IDENTIFIER_POINTER (METHOD_SEL_NAME (mth)));
5430 /* Check types; if different, complain. */
5431 if (!comp_proto_with_proto (method, mth))
5432 error ("duplicate declaration of class method `%s'",
5433 IDENTIFIER_POINTER (METHOD_SEL_NAME (mth)));
5437 if (!(hsh = hash_lookup (cls_method_hash_list, METHOD_SEL_NAME (method))))
5439 /* Install on a global chain. */
5440 hash_enter (cls_method_hash_list, method);
5444 /* Check types; if different, add to a list. */
5445 if (!comp_proto_with_proto (method, hsh->key))
5446 hash_add_attr (hsh, method);
5452 add_instance_method (class, method)
5459 if (!(mth = lookup_method (CLASS_NST_METHODS (class), method)))
5461 /* Put method on list in reverse order. */
5462 TREE_CHAIN (method) = CLASS_NST_METHODS (class);
5463 CLASS_NST_METHODS (class) = method;
5467 if (TREE_CODE (class) == CLASS_IMPLEMENTATION_TYPE)
5468 error ("duplicate definition of instance method `%s'",
5469 IDENTIFIER_POINTER (METHOD_SEL_NAME (mth)));
5472 /* Check types; if different, complain. */
5473 if (!comp_proto_with_proto (method, mth))
5474 error ("duplicate declaration of instance method `%s'",
5475 IDENTIFIER_POINTER (METHOD_SEL_NAME (mth)));
5479 if (!(hsh = hash_lookup (nst_method_hash_list, METHOD_SEL_NAME (method))))
5481 /* Install on a global chain. */
5482 hash_enter (nst_method_hash_list, method);
5486 /* Check types; if different, add to a list. */
5487 if (!comp_proto_with_proto (method, hsh->key))
5488 hash_add_attr (hsh, method);
5497 /* Put interfaces on list in reverse order. */
5498 TREE_CHAIN (class) = interface_chain;
5499 interface_chain = class;
5500 return interface_chain;
5504 add_category (class, category)
5508 /* Put categories on list in reverse order. */
5509 tree cat = CLASS_CATEGORY_LIST (class);
5513 if (CLASS_SUPER_NAME (cat) == CLASS_SUPER_NAME (category))
5514 warning ("duplicate interface declaration for category `%s(%s)'",
5515 IDENTIFIER_POINTER (CLASS_NAME (class)),
5516 IDENTIFIER_POINTER (CLASS_SUPER_NAME (category)));
5517 cat = CLASS_CATEGORY_LIST (cat);
5520 CLASS_CATEGORY_LIST (category) = CLASS_CATEGORY_LIST (class);
5521 CLASS_CATEGORY_LIST (class) = category;
5524 /* Called after parsing each instance variable declaration. Necessary to
5525 preserve typedefs and implement public/private...
5527 PUBLIC is 1 for public, 0 for protected, and 2 for private. */
5530 add_instance_variable (class, public, declarator, declspecs, width)
5537 tree field_decl, raw_decl;
5539 raw_decl = build_tree_list (declspecs, declarator);
5541 if (CLASS_RAW_IVARS (class))
5542 chainon (CLASS_RAW_IVARS (class), raw_decl);
5544 CLASS_RAW_IVARS (class) = raw_decl;
5546 field_decl = grokfield (input_filename, lineno,
5547 declarator, declspecs, width);
5549 /* Overload the public attribute, it is not used for FIELD_DECLs. */
5553 TREE_PUBLIC (field_decl) = 0;
5554 TREE_PRIVATE (field_decl) = 0;
5555 TREE_PROTECTED (field_decl) = 1;
5559 TREE_PUBLIC (field_decl) = 1;
5560 TREE_PRIVATE (field_decl) = 0;
5561 TREE_PROTECTED (field_decl) = 0;
5565 TREE_PUBLIC (field_decl) = 0;
5566 TREE_PRIVATE (field_decl) = 1;
5567 TREE_PROTECTED (field_decl) = 0;
5572 if (CLASS_IVARS (class))
5573 chainon (CLASS_IVARS (class), field_decl);
5575 CLASS_IVARS (class) = field_decl;
5581 is_ivar (decl_chain, ident)
5585 for ( ; decl_chain; decl_chain = TREE_CHAIN (decl_chain))
5586 if (DECL_NAME (decl_chain) == ident)
5591 /* True if the ivar is private and we are not in its implementation. */
5597 if (TREE_PRIVATE (decl)
5598 && ! is_ivar (CLASS_IVARS (implementation_template), DECL_NAME (decl)))
5600 error ("instance variable `%s' is declared private",
5601 IDENTIFIER_POINTER (DECL_NAME (decl)));
5608 /* We have an instance variable reference;, check to see if it is public. */
5611 is_public (expr, identifier)
5615 tree basetype = TREE_TYPE (expr);
5616 enum tree_code code = TREE_CODE (basetype);
5619 if (code == RECORD_TYPE)
5621 if (TREE_STATIC_TEMPLATE (basetype))
5623 if (!lookup_interface (TYPE_NAME (basetype)))
5625 error ("cannot find interface declaration for `%s'",
5626 IDENTIFIER_POINTER (TYPE_NAME (basetype)));
5630 if ((decl = is_ivar (TYPE_FIELDS (basetype), identifier)))
5632 if (TREE_PUBLIC (decl))
5635 /* Important difference between the Stepstone translator:
5636 all instance variables should be public within the context
5637 of the implementation. */
5638 if (objc_implementation_context
5639 && (((TREE_CODE (objc_implementation_context)
5640 == CLASS_IMPLEMENTATION_TYPE)
5641 || (TREE_CODE (objc_implementation_context)
5642 == CATEGORY_IMPLEMENTATION_TYPE))
5643 && (CLASS_NAME (objc_implementation_context)
5644 == TYPE_NAME (basetype))))
5645 return ! is_private (decl);
5647 error ("instance variable `%s' is declared %s",
5648 IDENTIFIER_POINTER (identifier),
5649 TREE_PRIVATE (decl) ? "private" : "protected");
5654 else if (objc_implementation_context && (basetype == objc_object_reference))
5656 TREE_TYPE (expr) = uprivate_record;
5657 warning ("static access to object of type `id'");
5664 /* Make sure all entries in CHAIN are also in LIST. */
5667 check_methods (chain, list, mtype)
5676 if (!lookup_method (list, chain))
5680 if (TREE_CODE (objc_implementation_context)
5681 == CLASS_IMPLEMENTATION_TYPE)
5682 warning ("incomplete implementation of class `%s'",
5683 IDENTIFIER_POINTER (CLASS_NAME (objc_implementation_context)));
5684 else if (TREE_CODE (objc_implementation_context)
5685 == CATEGORY_IMPLEMENTATION_TYPE)
5686 warning ("incomplete implementation of category `%s'",
5687 IDENTIFIER_POINTER (CLASS_SUPER_NAME (objc_implementation_context)));
5691 warning ("method definition for `%c%s' not found",
5692 mtype, IDENTIFIER_POINTER (METHOD_SEL_NAME (chain)));
5695 chain = TREE_CHAIN (chain);
5701 /* Check if CLASS, or its superclasses, explicitly conforms to PROTOCOL. */
5704 conforms_to_protocol (class, protocol)
5708 if (TREE_CODE (protocol) == PROTOCOL_INTERFACE_TYPE)
5710 tree p = CLASS_PROTOCOL_LIST (class);
5711 while (p && TREE_VALUE (p) != protocol)
5716 tree super = (CLASS_SUPER_NAME (class)
5717 ? lookup_interface (CLASS_SUPER_NAME (class))
5719 int tmp = super ? conforms_to_protocol (super, protocol) : 0;
5728 /* Make sure all methods in CHAIN are accessible as MTYPE methods in
5729 CONTEXT. This is one of two mechanisms to check protocol integrity. */
5732 check_methods_accessible (chain, context, mtype)
5739 tree base_context = context;
5743 context = base_context;
5747 list = CLASS_CLS_METHODS (context);
5749 list = CLASS_NST_METHODS (context);
5751 if (lookup_method (list, chain))
5754 else if (TREE_CODE (context) == CLASS_IMPLEMENTATION_TYPE
5755 || TREE_CODE (context) == CLASS_INTERFACE_TYPE)
5756 context = (CLASS_SUPER_NAME (context)
5757 ? lookup_interface (CLASS_SUPER_NAME (context))
5760 else if (TREE_CODE (context) == CATEGORY_IMPLEMENTATION_TYPE
5761 || TREE_CODE (context) == CATEGORY_INTERFACE_TYPE)
5762 context = (CLASS_NAME (context)
5763 ? lookup_interface (CLASS_NAME (context))
5769 if (context == NULL_TREE)
5773 if (TREE_CODE (objc_implementation_context)
5774 == CLASS_IMPLEMENTATION_TYPE)
5775 warning ("incomplete implementation of class `%s'",
5777 (CLASS_NAME (objc_implementation_context)));
5778 else if (TREE_CODE (objc_implementation_context)
5779 == CATEGORY_IMPLEMENTATION_TYPE)
5780 warning ("incomplete implementation of category `%s'",
5782 (CLASS_SUPER_NAME (objc_implementation_context)));
5785 warning ("method definition for `%c%s' not found",
5786 mtype, IDENTIFIER_POINTER (METHOD_SEL_NAME (chain)));
5789 chain = TREE_CHAIN (chain); /* next method... */
5794 /* Check whether the current interface (accessible via
5795 'objc_implementation_context') actually implements protocol P, along
5796 with any protocols that P inherits. */
5799 check_protocol (p, type, name)
5804 if (TREE_CODE (p) == PROTOCOL_INTERFACE_TYPE)
5808 /* Ensure that all protocols have bodies! */
5811 f1 = check_methods (PROTOCOL_CLS_METHODS (p),
5812 CLASS_CLS_METHODS (objc_implementation_context),
5814 f2 = check_methods (PROTOCOL_NST_METHODS (p),
5815 CLASS_NST_METHODS (objc_implementation_context),
5820 f1 = check_methods_accessible (PROTOCOL_CLS_METHODS (p),
5821 objc_implementation_context,
5823 f2 = check_methods_accessible (PROTOCOL_NST_METHODS (p),
5824 objc_implementation_context,
5829 warning ("%s `%s' does not fully implement the `%s' protocol",
5830 type, name, IDENTIFIER_POINTER (PROTOCOL_NAME (p)));
5833 /* Check protocols recursively. */
5834 if (PROTOCOL_LIST (p))
5836 tree subs = PROTOCOL_LIST (p);
5838 lookup_interface (CLASS_SUPER_NAME (implementation_template));
5842 tree sub = TREE_VALUE (subs);
5844 /* If the superclass does not conform to the protocols
5845 inherited by P, then we must! */
5846 if (!super_class || !conforms_to_protocol (super_class, sub))
5847 check_protocol (sub, type, name);
5848 subs = TREE_CHAIN (subs);
5853 /* Check whether the current interface (accessible via
5854 'objc_implementation_context') actually implements the protocols listed
5858 check_protocols (proto_list, type, name)
5863 for ( ; proto_list; proto_list = TREE_CHAIN (proto_list))
5865 tree p = TREE_VALUE (proto_list);
5867 check_protocol (p, type, name);
5871 /* Make sure that the class CLASS_NAME is defined
5872 CODE says which kind of thing CLASS_NAME ought to be.
5873 It can be CLASS_INTERFACE_TYPE, CLASS_IMPLEMENTATION_TYPE,
5874 CATEGORY_INTERFACE_TYPE, or CATEGORY_IMPLEMENTATION_TYPE. */
5877 start_class (code, class_name, super_name, protocol_list)
5878 enum tree_code code;
5885 if (objc_implementation_context)
5887 warning ("`@end' missing in implementation context");
5888 finish_class (objc_implementation_context);
5889 objc_ivar_chain = NULL_TREE;
5890 objc_implementation_context = NULL_TREE;
5893 class = make_node (code);
5894 TYPE_BINFO (class) = make_tree_vec (6);
5896 CLASS_NAME (class) = class_name;
5897 CLASS_SUPER_NAME (class) = super_name;
5898 CLASS_CLS_METHODS (class) = NULL_TREE;
5900 if (! is_class_name (class_name) && (decl = lookup_name (class_name)))
5902 error ("`%s' redeclared as different kind of symbol",
5903 IDENTIFIER_POINTER (class_name));
5904 error_with_decl (decl, "previous declaration of `%s'");
5907 if (code == CLASS_IMPLEMENTATION_TYPE)
5912 for (chain = implemented_classes; chain; chain = TREE_CHAIN (chain))
5913 if (TREE_VALUE (chain) == class_name)
5915 error ("reimplementation of class `%s'",
5916 IDENTIFIER_POINTER (class_name));
5917 return error_mark_node;
5919 implemented_classes = tree_cons (NULL_TREE, class_name,
5920 implemented_classes);
5923 /* Pre-build the following entities - for speed/convenience. */
5925 self_id = get_identifier ("self");
5927 ucmd_id = get_identifier ("_cmd");
5930 = build_tree_list (get_identifier ("__unused__"), NULL_TREE);
5931 if (!objc_super_template)
5932 objc_super_template = build_super_template ();
5934 /* Reset for multiple classes per file. */
5937 objc_implementation_context = class;
5939 /* Lookup the interface for this implementation. */
5941 if (!(implementation_template = lookup_interface (class_name)))
5943 warning ("cannot find interface declaration for `%s'",
5944 IDENTIFIER_POINTER (class_name));
5945 add_class (implementation_template = objc_implementation_context);
5948 /* If a super class has been specified in the implementation,
5949 insure it conforms to the one specified in the interface. */
5952 && (super_name != CLASS_SUPER_NAME (implementation_template)))
5954 tree previous_name = CLASS_SUPER_NAME (implementation_template);
5955 const char *const name =
5956 previous_name ? IDENTIFIER_POINTER (previous_name) : "";
5957 error ("conflicting super class name `%s'",
5958 IDENTIFIER_POINTER (super_name));
5959 error ("previous declaration of `%s'", name);
5962 else if (! super_name)
5964 CLASS_SUPER_NAME (objc_implementation_context)
5965 = CLASS_SUPER_NAME (implementation_template);
5969 else if (code == CLASS_INTERFACE_TYPE)
5971 if (lookup_interface (class_name))
5972 warning ("duplicate interface declaration for class `%s'",
5973 IDENTIFIER_POINTER (class_name));
5978 CLASS_PROTOCOL_LIST (class)
5979 = lookup_and_install_protocols (protocol_list);
5982 else if (code == CATEGORY_INTERFACE_TYPE)
5984 tree class_category_is_assoc_with;
5986 /* For a category, class_name is really the name of the class that
5987 the following set of methods will be associated with. We must
5988 find the interface so that can derive the objects template. */
5990 if (!(class_category_is_assoc_with = lookup_interface (class_name)))
5992 error ("cannot find interface declaration for `%s'",
5993 IDENTIFIER_POINTER (class_name));
5994 exit (FATAL_EXIT_CODE);
5997 add_category (class_category_is_assoc_with, class);
6000 CLASS_PROTOCOL_LIST (class)
6001 = lookup_and_install_protocols (protocol_list);
6004 else if (code == CATEGORY_IMPLEMENTATION_TYPE)
6006 /* Pre-build the following entities for speed/convenience. */
6008 self_id = get_identifier ("self");
6010 ucmd_id = get_identifier ("_cmd");
6013 = build_tree_list (get_identifier ("__unused__"), NULL_TREE);
6014 if (!objc_super_template)
6015 objc_super_template = build_super_template ();
6017 /* Reset for multiple classes per file. */
6020 objc_implementation_context = class;
6022 /* For a category, class_name is really the name of the class that
6023 the following set of methods will be associated with. We must
6024 find the interface so that can derive the objects template. */
6026 if (!(implementation_template = lookup_interface (class_name)))
6028 error ("cannot find interface declaration for `%s'",
6029 IDENTIFIER_POINTER (class_name));
6030 exit (FATAL_EXIT_CODE);
6037 continue_class (class)
6040 if (TREE_CODE (class) == CLASS_IMPLEMENTATION_TYPE
6041 || TREE_CODE (class) == CATEGORY_IMPLEMENTATION_TYPE)
6043 struct imp_entry *imp_entry;
6046 /* Check consistency of the instance variables. */
6048 if (CLASS_IVARS (class))
6049 check_ivars (implementation_template, class);
6051 /* code generation */
6053 ivar_context = build_private_template (implementation_template);
6055 if (!objc_class_template)
6056 build_class_template ();
6058 imp_entry = (struct imp_entry *) ggc_alloc (sizeof (struct imp_entry));
6060 imp_entry->next = imp_list;
6061 imp_entry->imp_context = class;
6062 imp_entry->imp_template = implementation_template;
6064 synth_forward_declarations ();
6065 imp_entry->class_decl = UOBJC_CLASS_decl;
6066 imp_entry->meta_decl = UOBJC_METACLASS_decl;
6068 /* Append to front and increment count. */
6069 imp_list = imp_entry;
6070 if (TREE_CODE (class) == CLASS_IMPLEMENTATION_TYPE)
6075 return ivar_context;
6078 else if (TREE_CODE (class) == CLASS_INTERFACE_TYPE)
6080 tree record = xref_tag (RECORD_TYPE, CLASS_NAME (class));
6082 if (!TYPE_FIELDS (record))
6084 finish_struct (record, get_class_ivars (class), NULL_TREE);
6085 CLASS_STATIC_TEMPLATE (class) = record;
6087 /* Mark this record as a class template for static typing. */
6088 TREE_STATIC_TEMPLATE (record) = 1;
6095 return error_mark_node;
6098 /* This is called once we see the "@end" in an interface/implementation. */
6101 finish_class (class)
6104 if (TREE_CODE (class) == CLASS_IMPLEMENTATION_TYPE)
6106 /* All code generation is done in finish_objc. */
6108 if (implementation_template != objc_implementation_context)
6110 /* Ensure that all method listed in the interface contain bodies. */
6111 check_methods (CLASS_CLS_METHODS (implementation_template),
6112 CLASS_CLS_METHODS (objc_implementation_context), '+');
6113 check_methods (CLASS_NST_METHODS (implementation_template),
6114 CLASS_NST_METHODS (objc_implementation_context), '-');
6116 if (CLASS_PROTOCOL_LIST (implementation_template))
6117 check_protocols (CLASS_PROTOCOL_LIST (implementation_template),
6119 IDENTIFIER_POINTER (CLASS_NAME (objc_implementation_context)));
6123 else if (TREE_CODE (class) == CATEGORY_IMPLEMENTATION_TYPE)
6125 tree category = CLASS_CATEGORY_LIST (implementation_template);
6127 /* Find the category interface from the class it is associated with. */
6130 if (CLASS_SUPER_NAME (class) == CLASS_SUPER_NAME (category))
6132 category = CLASS_CATEGORY_LIST (category);
6137 /* Ensure all method listed in the interface contain bodies. */
6138 check_methods (CLASS_CLS_METHODS (category),
6139 CLASS_CLS_METHODS (objc_implementation_context), '+');
6140 check_methods (CLASS_NST_METHODS (category),
6141 CLASS_NST_METHODS (objc_implementation_context), '-');
6143 if (CLASS_PROTOCOL_LIST (category))
6144 check_protocols (CLASS_PROTOCOL_LIST (category),
6146 IDENTIFIER_POINTER (CLASS_SUPER_NAME (objc_implementation_context)));
6150 else if (TREE_CODE (class) == CLASS_INTERFACE_TYPE)
6153 const char *class_name = IDENTIFIER_POINTER (CLASS_NAME (class));
6154 char *string = (char *) alloca (strlen (class_name) + 3);
6156 /* extern struct objc_object *_<my_name>; */
6158 sprintf (string, "_%s", class_name);
6160 decl_specs = build_tree_list (NULL_TREE, ridpointers[(int) RID_EXTERN]);
6161 decl_specs = tree_cons (NULL_TREE, objc_object_reference, decl_specs);
6162 define_decl (build1 (INDIRECT_REF, NULL_TREE, get_identifier (string)),
6168 add_protocol (protocol)
6171 /* Put protocol on list in reverse order. */
6172 TREE_CHAIN (protocol) = protocol_chain;
6173 protocol_chain = protocol;
6174 return protocol_chain;
6178 lookup_protocol (ident)
6183 for (chain = protocol_chain; chain; chain = TREE_CHAIN (chain))
6184 if (ident == PROTOCOL_NAME (chain))
6190 /* This function forward declares the protocols named by NAMES. If
6191 they are already declared or defined, the function has no effect. */
6194 objc_declare_protocols (names)
6199 for (list = names; list; list = TREE_CHAIN (list))
6201 tree name = TREE_VALUE (list);
6203 if (lookup_protocol (name) == NULL_TREE)
6205 tree protocol = make_node (PROTOCOL_INTERFACE_TYPE);
6207 TYPE_BINFO (protocol) = make_tree_vec (2);
6208 PROTOCOL_NAME (protocol) = name;
6209 PROTOCOL_LIST (protocol) = NULL_TREE;
6210 add_protocol (protocol);
6211 PROTOCOL_DEFINED (protocol) = 0;
6212 PROTOCOL_FORWARD_DECL (protocol) = NULL_TREE;
6218 start_protocol (code, name, list)
6219 enum tree_code code;
6225 /* This is as good a place as any. Need to invoke
6226 push_tag_toplevel. */
6227 if (!objc_protocol_template)
6228 objc_protocol_template = build_protocol_template ();
6230 protocol = lookup_protocol (name);
6234 protocol = make_node (code);
6235 TYPE_BINFO (protocol) = make_tree_vec (2);
6237 PROTOCOL_NAME (protocol) = name;
6238 PROTOCOL_LIST (protocol) = lookup_and_install_protocols (list);
6239 add_protocol (protocol);
6240 PROTOCOL_DEFINED (protocol) = 1;
6241 PROTOCOL_FORWARD_DECL (protocol) = NULL_TREE;
6243 check_protocol_recursively (protocol, list);
6245 else if (! PROTOCOL_DEFINED (protocol))
6247 PROTOCOL_DEFINED (protocol) = 1;
6248 PROTOCOL_LIST (protocol) = lookup_and_install_protocols (list);
6250 check_protocol_recursively (protocol, list);
6254 warning ("duplicate declaration for protocol `%s'",
6255 IDENTIFIER_POINTER (name));
6261 finish_protocol (protocol)
6262 tree protocol ATTRIBUTE_UNUSED;
6267 /* "Encode" a data type into a string, which grows in util_obstack.
6268 ??? What is the FORMAT? Someone please document this! */
6271 encode_type_qualifiers (declspecs)
6276 for (spec = declspecs; spec; spec = TREE_CHAIN (spec))
6278 if (ridpointers[(int) RID_CONST] == TREE_VALUE (spec))
6279 obstack_1grow (&util_obstack, 'r');
6280 else if (ridpointers[(int) RID_IN] == TREE_VALUE (spec))
6281 obstack_1grow (&util_obstack, 'n');
6282 else if (ridpointers[(int) RID_INOUT] == TREE_VALUE (spec))
6283 obstack_1grow (&util_obstack, 'N');
6284 else if (ridpointers[(int) RID_OUT] == TREE_VALUE (spec))
6285 obstack_1grow (&util_obstack, 'o');
6286 else if (ridpointers[(int) RID_BYCOPY] == TREE_VALUE (spec))
6287 obstack_1grow (&util_obstack, 'O');
6288 else if (ridpointers[(int) RID_BYREF] == TREE_VALUE (spec))
6289 obstack_1grow (&util_obstack, 'R');
6290 else if (ridpointers[(int) RID_ONEWAY] == TREE_VALUE (spec))
6291 obstack_1grow (&util_obstack, 'V');
6295 /* Encode a pointer type. */
6298 encode_pointer (type, curtype, format)
6303 tree pointer_to = TREE_TYPE (type);
6305 if (TREE_CODE (pointer_to) == RECORD_TYPE)
6307 if (TYPE_NAME (pointer_to)
6308 && TREE_CODE (TYPE_NAME (pointer_to)) == IDENTIFIER_NODE)
6310 const char *name = IDENTIFIER_POINTER (TYPE_NAME (pointer_to));
6312 if (strcmp (name, TAG_OBJECT) == 0) /* '@' */
6314 obstack_1grow (&util_obstack, '@');
6317 else if (TREE_STATIC_TEMPLATE (pointer_to))
6319 if (generating_instance_variables)
6321 obstack_1grow (&util_obstack, '@');
6322 obstack_1grow (&util_obstack, '"');
6323 obstack_grow (&util_obstack, name, strlen (name));
6324 obstack_1grow (&util_obstack, '"');
6329 obstack_1grow (&util_obstack, '@');
6333 else if (strcmp (name, TAG_CLASS) == 0) /* '#' */
6335 obstack_1grow (&util_obstack, '#');
6338 else if (strcmp (name, TAG_SELECTOR) == 0) /* ':' */
6340 obstack_1grow (&util_obstack, ':');
6345 else if (TREE_CODE (pointer_to) == INTEGER_TYPE
6346 && TYPE_MODE (pointer_to) == QImode)
6348 obstack_1grow (&util_obstack, '*');
6352 /* We have a type that does not get special treatment. */
6354 /* NeXT extension */
6355 obstack_1grow (&util_obstack, '^');
6356 encode_type (pointer_to, curtype, format);
6360 encode_array (type, curtype, format)
6365 tree an_int_cst = TYPE_SIZE (type);
6366 tree array_of = TREE_TYPE (type);
6369 /* An incomplete array is treated like a pointer. */
6370 if (an_int_cst == NULL)
6372 encode_pointer (type, curtype, format);
6376 sprintf (buffer, "[%ld",
6377 (long) (TREE_INT_CST_LOW (an_int_cst)
6378 / TREE_INT_CST_LOW (TYPE_SIZE (array_of))));
6380 obstack_grow (&util_obstack, buffer, strlen (buffer));
6381 encode_type (array_of, curtype, format);
6382 obstack_1grow (&util_obstack, ']');
6387 encode_aggregate_within (type, curtype, format, left, right)
6394 /* The RECORD_TYPE may in fact be a typedef! For purposes
6395 of encoding, we need the real underlying enchilada. */
6396 if (TYPE_MAIN_VARIANT (type))
6397 type = TYPE_MAIN_VARIANT (type);
6399 if (obstack_object_size (&util_obstack) > 0
6400 && *(obstack_next_free (&util_obstack) - 1) == '^')
6402 tree name = TYPE_NAME (type);
6404 /* we have a reference; this is a NeXT extension. */
6406 if (obstack_object_size (&util_obstack) - curtype == 1
6407 && format == OBJC_ENCODE_INLINE_DEFS)
6409 /* Output format of struct for first level only. */
6410 tree fields = TYPE_FIELDS (type);
6412 if (name && TREE_CODE (name) == IDENTIFIER_NODE)
6414 obstack_1grow (&util_obstack, left);
6415 obstack_grow (&util_obstack,
6416 IDENTIFIER_POINTER (name),
6417 strlen (IDENTIFIER_POINTER (name)));
6418 obstack_1grow (&util_obstack, '=');
6422 obstack_1grow (&util_obstack, left);
6423 obstack_grow (&util_obstack, "?=", 2);
6426 for ( ; fields; fields = TREE_CHAIN (fields))
6427 encode_field_decl (fields, curtype, format);
6429 obstack_1grow (&util_obstack, right);
6432 else if (name && TREE_CODE (name) == IDENTIFIER_NODE)
6434 obstack_1grow (&util_obstack, left);
6435 obstack_grow (&util_obstack,
6436 IDENTIFIER_POINTER (name),
6437 strlen (IDENTIFIER_POINTER (name)));
6438 obstack_1grow (&util_obstack, right);
6443 /* We have an untagged structure or a typedef. */
6444 obstack_1grow (&util_obstack, left);
6445 obstack_1grow (&util_obstack, '?');
6446 obstack_1grow (&util_obstack, right);
6452 tree name = TYPE_NAME (type);
6453 tree fields = TYPE_FIELDS (type);
6455 if (format == OBJC_ENCODE_INLINE_DEFS
6456 || generating_instance_variables)
6458 obstack_1grow (&util_obstack, left);
6459 if (name && TREE_CODE (name) == IDENTIFIER_NODE)
6460 obstack_grow (&util_obstack,
6461 IDENTIFIER_POINTER (name),
6462 strlen (IDENTIFIER_POINTER (name)));
6464 obstack_1grow (&util_obstack, '?');
6466 obstack_1grow (&util_obstack, '=');
6468 for (; fields; fields = TREE_CHAIN (fields))
6470 if (generating_instance_variables)
6472 tree fname = DECL_NAME (fields);
6474 obstack_1grow (&util_obstack, '"');
6475 if (fname && TREE_CODE (fname) == IDENTIFIER_NODE)
6477 obstack_grow (&util_obstack,
6478 IDENTIFIER_POINTER (fname),
6479 strlen (IDENTIFIER_POINTER (fname)));
6482 obstack_1grow (&util_obstack, '"');
6485 encode_field_decl (fields, curtype, format);
6488 obstack_1grow (&util_obstack, right);
6493 obstack_1grow (&util_obstack, left);
6494 if (name && TREE_CODE (name) == IDENTIFIER_NODE)
6495 obstack_grow (&util_obstack,
6496 IDENTIFIER_POINTER (name),
6497 strlen (IDENTIFIER_POINTER (name)));
6499 /* We have an untagged structure or a typedef. */
6500 obstack_1grow (&util_obstack, '?');
6502 obstack_1grow (&util_obstack, right);
6508 encode_aggregate (type, curtype, format)
6513 enum tree_code code = TREE_CODE (type);
6519 encode_aggregate_within(type, curtype, format, '{', '}');
6524 encode_aggregate_within(type, curtype, format, '(', ')');
6529 obstack_1grow (&util_obstack, 'i');
6537 /* Support bitfields. The current version of Objective-C does not support
6538 them. The string will consist of one or more "b:n"'s where n is an
6539 integer describing the width of the bitfield. Currently, classes in
6540 the kit implement a method "-(char *)describeBitfieldStruct:" that
6541 simulates this. If they do not implement this method, the archiver
6542 assumes the bitfield is 16 bits wide (padded if necessary) and packed
6543 according to the GNU compiler. After looking at the "kit", it appears
6544 that all classes currently rely on this default behavior, rather than
6545 hand generating this string (which is tedious). */
6548 encode_bitfield (width)
6552 sprintf (buffer, "b%d", width);
6553 obstack_grow (&util_obstack, buffer, strlen (buffer));
6556 /* FORMAT will be OBJC_ENCODE_INLINE_DEFS or OBJC_ENCODE_DONT_INLINE_DEFS. */
6559 encode_type (type, curtype, format)
6564 enum tree_code code = TREE_CODE (type);
6566 if (code == INTEGER_TYPE)
6568 if (integer_zerop (TYPE_MIN_VALUE (type)))
6570 /* Unsigned integer types. */
6572 if (TYPE_MODE (type) == QImode)
6573 obstack_1grow (&util_obstack, 'C');
6574 else if (TYPE_MODE (type) == HImode)
6575 obstack_1grow (&util_obstack, 'S');
6576 else if (TYPE_MODE (type) == SImode)
6578 if (type == long_unsigned_type_node)
6579 obstack_1grow (&util_obstack, 'L');
6581 obstack_1grow (&util_obstack, 'I');
6583 else if (TYPE_MODE (type) == DImode)
6584 obstack_1grow (&util_obstack, 'Q');
6588 /* Signed integer types. */
6590 if (TYPE_MODE (type) == QImode)
6591 obstack_1grow (&util_obstack, 'c');
6592 else if (TYPE_MODE (type) == HImode)
6593 obstack_1grow (&util_obstack, 's');
6594 else if (TYPE_MODE (type) == SImode)
6596 if (type == long_integer_type_node)
6597 obstack_1grow (&util_obstack, 'l');
6599 obstack_1grow (&util_obstack, 'i');
6602 else if (TYPE_MODE (type) == DImode)
6603 obstack_1grow (&util_obstack, 'q');
6607 else if (code == REAL_TYPE)
6609 /* Floating point types. */
6611 if (TYPE_MODE (type) == SFmode)
6612 obstack_1grow (&util_obstack, 'f');
6613 else if (TYPE_MODE (type) == DFmode
6614 || TYPE_MODE (type) == TFmode)
6615 obstack_1grow (&util_obstack, 'd');
6618 else if (code == VOID_TYPE)
6619 obstack_1grow (&util_obstack, 'v');
6621 else if (code == ARRAY_TYPE)
6622 encode_array (type, curtype, format);
6624 else if (code == POINTER_TYPE)
6625 encode_pointer (type, curtype, format);
6627 else if (code == RECORD_TYPE || code == UNION_TYPE || code == ENUMERAL_TYPE)
6628 encode_aggregate (type, curtype, format);
6630 else if (code == FUNCTION_TYPE) /* '?' */
6631 obstack_1grow (&util_obstack, '?');
6635 encode_complete_bitfield (position, type, size)
6640 enum tree_code code = TREE_CODE (type);
6642 char charType = '?';
6644 if (code == INTEGER_TYPE)
6646 if (integer_zerop (TYPE_MIN_VALUE (type)))
6648 /* Unsigned integer types. */
6650 if (TYPE_MODE (type) == QImode)
6652 else if (TYPE_MODE (type) == HImode)
6654 else if (TYPE_MODE (type) == SImode)
6656 if (type == long_unsigned_type_node)
6661 else if (TYPE_MODE (type) == DImode)
6666 /* Signed integer types. */
6668 if (TYPE_MODE (type) == QImode)
6670 else if (TYPE_MODE (type) == HImode)
6672 else if (TYPE_MODE (type) == SImode)
6674 if (type == long_integer_type_node)
6680 else if (TYPE_MODE (type) == DImode)
6684 else if (code == ENUMERAL_TYPE)
6689 sprintf (buffer, "b%d%c%d", position, charType, size);
6690 obstack_grow (&util_obstack, buffer, strlen (buffer));
6694 encode_field_decl (field_decl, curtype, format)
6701 type = TREE_TYPE (field_decl);
6703 /* If this field is obviously a bitfield, or is a bitfield that has been
6704 clobbered to look like a ordinary integer mode, go ahead and generate
6705 the bitfield typing information. */
6706 if (flag_next_runtime)
6708 if (DECL_BIT_FIELD_TYPE (field_decl))
6709 encode_bitfield (tree_low_cst (DECL_SIZE (field_decl), 1));
6711 encode_type (TREE_TYPE (field_decl), curtype, format);
6715 if (DECL_BIT_FIELD_TYPE (field_decl))
6716 encode_complete_bitfield (int_bit_position (field_decl),
6717 DECL_BIT_FIELD_TYPE (field_decl),
6718 tree_low_cst (DECL_SIZE (field_decl), 1));
6720 encode_type (TREE_TYPE (field_decl), curtype, format);
6725 expr_last (complex_expr)
6731 while ((next = TREE_OPERAND (complex_expr, 0)))
6732 complex_expr = next;
6734 return complex_expr;
6737 /* Transform a method definition into a function definition as follows:
6738 - synthesize the first two arguments, "self" and "_cmd". */
6741 start_method_def (method)
6746 /* Required to implement _msgSuper. */
6747 objc_method_context = method;
6748 UOBJC_SUPER_decl = NULL_TREE;
6750 /* Must be called BEFORE start_function. */
6753 /* Generate prototype declarations for arguments..."new-style". */
6755 if (TREE_CODE (objc_method_context) == INSTANCE_METHOD_DECL)
6756 decl_specs = build_tree_list (NULL_TREE, uprivate_record);
6758 /* Really a `struct objc_class *'. However, we allow people to
6759 assign to self, which changes its type midstream. */
6760 decl_specs = build_tree_list (NULL_TREE, objc_object_reference);
6762 push_parm_decl (build_tree_list
6763 (build_tree_list (decl_specs,
6764 build1 (INDIRECT_REF, NULL_TREE, self_id)),
6767 decl_specs = build_tree_list (NULL_TREE,
6768 xref_tag (RECORD_TYPE,
6769 get_identifier (TAG_SELECTOR)));
6770 push_parm_decl (build_tree_list
6771 (build_tree_list (decl_specs,
6772 build1 (INDIRECT_REF, NULL_TREE, ucmd_id)),
6775 /* Generate argument declarations if a keyword_decl. */
6776 if (METHOD_SEL_ARGS (method))
6778 tree arglist = METHOD_SEL_ARGS (method);
6781 tree arg_spec = TREE_PURPOSE (TREE_TYPE (arglist));
6782 tree arg_decl = TREE_VALUE (TREE_TYPE (arglist));
6786 tree last_expr = expr_last (arg_decl);
6788 /* Unite the abstract decl with its name. */
6789 TREE_OPERAND (last_expr, 0) = KEYWORD_ARG_NAME (arglist);
6790 push_parm_decl (build_tree_list
6791 (build_tree_list (arg_spec, arg_decl),
6794 /* Unhook: restore the abstract declarator. */
6795 TREE_OPERAND (last_expr, 0) = NULL_TREE;
6799 push_parm_decl (build_tree_list
6800 (build_tree_list (arg_spec,
6801 KEYWORD_ARG_NAME (arglist)),
6804 arglist = TREE_CHAIN (arglist);
6809 if (METHOD_ADD_ARGS (method) != NULL_TREE
6810 && METHOD_ADD_ARGS (method) != objc_ellipsis_node)
6812 /* We have a variable length selector - in "prototype" format. */
6813 tree akey = TREE_PURPOSE (METHOD_ADD_ARGS (method));
6816 /* This must be done prior to calling pushdecl. pushdecl is
6817 going to change our chain on us. */
6818 tree nextkey = TREE_CHAIN (akey);
6826 warn_with_method (message, mtype, method)
6827 const char *message;
6831 if (!diagnostic_count_diagnostic (global_dc, DK_WARNING))
6834 diagnostic_report_current_function (global_dc);
6836 /* Add a readable method name to the warning. */
6837 warning_with_file_and_line (DECL_SOURCE_FILE (method),
6838 DECL_SOURCE_LINE (method),
6841 gen_method_decl (method, errbuf));
6844 /* Return 1 if METHOD is consistent with PROTO. */
6847 comp_method_with_proto (method, proto)
6850 /* Create a function template node at most once. */
6851 if (!function1_template)
6852 function1_template = make_node (FUNCTION_TYPE);
6854 /* Install argument types - normally set by build_function_type. */
6855 TYPE_ARG_TYPES (function1_template) = get_arg_type_list (proto, METHOD_DEF, 0);
6857 /* install return type */
6858 TREE_TYPE (function1_template) = groktypename (TREE_TYPE (proto));
6860 return comptypes (TREE_TYPE (METHOD_DEFINITION (method)), function1_template);
6863 /* Return 1 if PROTO1 is consistent with PROTO2. */
6866 comp_proto_with_proto (proto0, proto1)
6867 tree proto0, proto1;
6869 /* Create a couple of function_template nodes at most once. */
6870 if (!function1_template)
6871 function1_template = make_node (FUNCTION_TYPE);
6872 if (!function2_template)
6873 function2_template = make_node (FUNCTION_TYPE);
6875 /* Install argument types; normally set by build_function_type. */
6876 TYPE_ARG_TYPES (function1_template) = get_arg_type_list (proto0, METHOD_REF, 0);
6877 TYPE_ARG_TYPES (function2_template) = get_arg_type_list (proto1, METHOD_REF, 0);
6879 /* Install return type. */
6880 TREE_TYPE (function1_template) = groktypename (TREE_TYPE (proto0));
6881 TREE_TYPE (function2_template) = groktypename (TREE_TYPE (proto1));
6883 return comptypes (function1_template, function2_template);
6886 /* - Generate an identifier for the function. the format is "_n_cls",
6887 where 1 <= n <= nMethods, and cls is the name the implementation we
6889 - Install the return type from the method declaration.
6890 - If we have a prototype, check for type consistency. */
6893 really_start_method (method, parmlist)
6894 tree method, parmlist;
6896 tree sc_spec, ret_spec, ret_decl, decl_specs;
6897 tree method_decl, method_id;
6898 const char *sel_name, *class_name, *cat_name;
6901 /* Synth the storage class & assemble the return type. */
6902 sc_spec = tree_cons (NULL_TREE, ridpointers[(int) RID_STATIC], NULL_TREE);
6903 ret_spec = TREE_PURPOSE (TREE_TYPE (method));
6904 decl_specs = chainon (sc_spec, ret_spec);
6906 sel_name = IDENTIFIER_POINTER (METHOD_SEL_NAME (method));
6907 class_name = IDENTIFIER_POINTER (CLASS_NAME (objc_implementation_context));
6908 cat_name = ((TREE_CODE (objc_implementation_context)
6909 == CLASS_IMPLEMENTATION_TYPE)
6911 : IDENTIFIER_POINTER (CLASS_SUPER_NAME (objc_implementation_context)));
6914 /* Make sure this is big enough for any plausible method label. */
6915 buf = (char *) alloca (50 + strlen (sel_name) + strlen (class_name)
6916 + (cat_name ? strlen (cat_name) : 0));
6918 OBJC_GEN_METHOD_LABEL (buf, TREE_CODE (method) == INSTANCE_METHOD_DECL,
6919 class_name, cat_name, sel_name, method_slot);
6921 method_id = get_identifier (buf);
6923 method_decl = build_nt (CALL_EXPR, method_id, parmlist, NULL_TREE);
6925 /* Check the declarator portion of the return type for the method. */
6926 if ((ret_decl = TREE_VALUE (TREE_TYPE (method))))
6928 /* Unite the complex decl (specified in the abstract decl) with the
6929 function decl just synthesized..(int *), (int (*)()), (int (*)[]). */
6930 tree save_expr = expr_last (ret_decl);
6932 TREE_OPERAND (save_expr, 0) = method_decl;
6933 method_decl = ret_decl;
6935 /* Fool the parser into thinking it is starting a function. */
6936 start_function (decl_specs, method_decl, NULL_TREE);
6938 /* Unhook: this has the effect of restoring the abstract declarator. */
6939 TREE_OPERAND (save_expr, 0) = NULL_TREE;
6944 TREE_VALUE (TREE_TYPE (method)) = method_decl;
6946 /* Fool the parser into thinking it is starting a function. */
6947 start_function (decl_specs, method_decl, NULL_TREE);
6949 /* Unhook: this has the effect of restoring the abstract declarator. */
6950 TREE_VALUE (TREE_TYPE (method)) = NULL_TREE;
6953 METHOD_DEFINITION (method) = current_function_decl;
6955 /* Check consistency...start_function, pushdecl, duplicate_decls. */
6957 if (implementation_template != objc_implementation_context)
6961 if (TREE_CODE (method) == INSTANCE_METHOD_DECL)
6962 proto = lookup_instance_method_static (implementation_template,
6963 METHOD_SEL_NAME (method));
6965 proto = lookup_class_method_static (implementation_template,
6966 METHOD_SEL_NAME (method));
6968 if (proto && ! comp_method_with_proto (method, proto))
6970 char type = (TREE_CODE (method) == INSTANCE_METHOD_DECL ? '-' : '+');
6972 warn_with_method ("conflicting types for", type, method);
6973 warn_with_method ("previous declaration of", type, proto);
6978 /* The following routine is always called...this "architecture" is to
6979 accommodate "old-style" variable length selectors.
6981 - a:a b:b // prototype ; id c; id d; // old-style. */
6984 continue_method_def ()
6988 if (METHOD_ADD_ARGS (objc_method_context) == objc_ellipsis_node)
6989 /* We have a `, ...' immediately following the selector. */
6990 parmlist = get_parm_info (0);
6992 parmlist = get_parm_info (1); /* place a `void_at_end' */
6994 /* Set self_decl from the first argument...this global is used by
6995 build_ivar_reference calling build_indirect_ref. */
6996 self_decl = TREE_PURPOSE (parmlist);
6999 really_start_method (objc_method_context, parmlist);
7000 store_parm_decls ();
7003 /* Called by the parser, from the `pushlevel' production. */
7008 if (!UOBJC_SUPER_decl)
7010 UOBJC_SUPER_decl = start_decl (get_identifier (UTAG_SUPER),
7011 build_tree_list (NULL_TREE,
7012 objc_super_template),
7015 finish_decl (UOBJC_SUPER_decl, NULL_TREE, NULL_TREE);
7017 /* This prevents `unused variable' warnings when compiling with -Wall. */
7018 TREE_USED (UOBJC_SUPER_decl) = 1;
7019 DECL_ARTIFICIAL (UOBJC_SUPER_decl) = 1;
7023 /* _n_Method (id self, SEL sel, ...)
7025 struct objc_super _S;
7026 _msgSuper ((_S.self = self, _S.class = _cls, &_S), ...);
7030 get_super_receiver ()
7032 if (objc_method_context)
7034 tree super_expr, super_expr_list;
7036 /* Set receiver to self. */
7037 super_expr = build_component_ref (UOBJC_SUPER_decl, self_id);
7038 super_expr = build_modify_expr (super_expr, NOP_EXPR, self_decl);
7039 super_expr_list = build_tree_list (NULL_TREE, super_expr);
7041 /* Set class to begin searching. */
7042 super_expr = build_component_ref (UOBJC_SUPER_decl,
7043 get_identifier ("class"));
7045 if (TREE_CODE (objc_implementation_context) == CLASS_IMPLEMENTATION_TYPE)
7047 /* [_cls, __cls]Super are "pre-built" in
7048 synth_forward_declarations. */
7050 super_expr = build_modify_expr (super_expr, NOP_EXPR,
7051 ((TREE_CODE (objc_method_context)
7052 == INSTANCE_METHOD_DECL)
7054 : uucls_super_ref));
7058 /* We have a category. */
7060 tree super_name = CLASS_SUPER_NAME (implementation_template);
7063 /* Barf if super used in a category of Object. */
7066 error ("no super class declared in interface for `%s'",
7067 IDENTIFIER_POINTER (CLASS_NAME (implementation_template)));
7068 return error_mark_node;
7071 if (flag_next_runtime)
7073 super_class = get_class_reference (super_name);
7074 if (TREE_CODE (objc_method_context) == CLASS_METHOD_DECL)
7075 /* Cast the super class to 'id', since the user may not have
7076 included <objc/objc-class.h>, leaving 'struct objc_class'
7077 an incomplete type. */
7079 = build_component_ref (build_indirect_ref
7080 (build_c_cast (id_type, super_class), "->"),
7081 get_identifier ("isa"));
7085 add_class_reference (super_name);
7086 super_class = (TREE_CODE (objc_method_context) == INSTANCE_METHOD_DECL
7087 ? objc_get_class_decl : objc_get_meta_class_decl);
7088 assemble_external (super_class);
7090 = build_function_call
7094 my_build_string (IDENTIFIER_LENGTH (super_name) + 1,
7095 IDENTIFIER_POINTER (super_name))));
7098 TREE_TYPE (super_class) = TREE_TYPE (ucls_super_ref);
7099 super_expr = build_modify_expr (super_expr, NOP_EXPR, super_class);
7102 chainon (super_expr_list, build_tree_list (NULL_TREE, super_expr));
7104 super_expr = build_unary_op (ADDR_EXPR, UOBJC_SUPER_decl, 0);
7105 chainon (super_expr_list, build_tree_list (NULL_TREE, super_expr));
7107 return build_compound_expr (super_expr_list);
7111 error ("[super ...] must appear in a method context");
7112 return error_mark_node;
7117 encode_method_def (func_decl)
7122 HOST_WIDE_INT max_parm_end = 0;
7127 encode_type (TREE_TYPE (TREE_TYPE (func_decl)),
7128 obstack_object_size (&util_obstack),
7129 OBJC_ENCODE_INLINE_DEFS);
7132 for (parms = DECL_ARGUMENTS (func_decl); parms;
7133 parms = TREE_CHAIN (parms))
7135 HOST_WIDE_INT parm_end = (forwarding_offset (parms)
7136 + int_size_in_bytes (TREE_TYPE (parms)));
7138 if (! offset_is_register && parm_end > max_parm_end)
7139 max_parm_end = parm_end;
7142 stack_size = max_parm_end - OBJC_FORWARDING_MIN_OFFSET;
7144 sprintf (buffer, "%d", stack_size);
7145 obstack_grow (&util_obstack, buffer, strlen (buffer));
7147 /* Argument types. */
7148 for (parms = DECL_ARGUMENTS (func_decl); parms;
7149 parms = TREE_CHAIN (parms))
7152 encode_type (TREE_TYPE (parms),
7153 obstack_object_size (&util_obstack),
7154 OBJC_ENCODE_INLINE_DEFS);
7156 /* Compute offset. */
7157 sprintf (buffer, "%d", forwarding_offset (parms));
7159 /* Indicate register. */
7160 if (offset_is_register)
7161 obstack_1grow (&util_obstack, '+');
7163 obstack_grow (&util_obstack, buffer, strlen (buffer));
7166 /* Null terminate string. */
7167 obstack_1grow (&util_obstack, 0);
7168 result = get_identifier (obstack_finish (&util_obstack));
7169 obstack_free (&util_obstack, util_firstobj);
7174 objc_expand_function_end ()
7176 METHOD_ENCODING (objc_method_context) = encode_method_def (current_function_decl);
7180 finish_method_def ()
7182 lang_expand_function_end = objc_expand_function_end;
7183 finish_function (0, 1);
7184 lang_expand_function_end = NULL;
7186 /* Required to implement _msgSuper. This must be done AFTER finish_function,
7187 since the optimizer may find "may be used before set" errors. */
7188 objc_method_context = NULL_TREE;
7193 lang_report_error_function (decl)
7196 if (objc_method_context)
7198 fprintf (stderr, "In method `%s'\n",
7199 IDENTIFIER_POINTER (METHOD_SEL_NAME (objc_method_context)));
7209 is_complex_decl (type)
7212 return (TREE_CODE (type) == ARRAY_TYPE
7213 || TREE_CODE (type) == FUNCTION_TYPE
7214 || (TREE_CODE (type) == POINTER_TYPE && ! IS_ID (type)));
7218 /* Code to convert a decl node into text for a declaration in C. */
7220 static char tmpbuf[256];
7223 adorn_decl (decl, str)
7227 enum tree_code code = TREE_CODE (decl);
7229 if (code == ARRAY_REF)
7231 tree an_int_cst = TREE_OPERAND (decl, 1);
7233 if (an_int_cst && TREE_CODE (an_int_cst) == INTEGER_CST)
7234 sprintf (str + strlen (str), "[%ld]",
7235 (long) TREE_INT_CST_LOW (an_int_cst));
7240 else if (code == ARRAY_TYPE)
7242 tree an_int_cst = TYPE_SIZE (decl);
7243 tree array_of = TREE_TYPE (decl);
7245 if (an_int_cst && TREE_CODE (an_int_cst) == INTEGER_TYPE)
7246 sprintf (str + strlen (str), "[%ld]",
7247 (long) (TREE_INT_CST_LOW (an_int_cst)
7248 / TREE_INT_CST_LOW (TYPE_SIZE (array_of))));
7253 else if (code == CALL_EXPR)
7255 tree chain = TREE_PURPOSE (TREE_OPERAND (decl, 1));
7260 gen_declaration_1 (chain, str);
7261 chain = TREE_CHAIN (chain);
7268 else if (code == FUNCTION_TYPE)
7270 tree chain = TYPE_ARG_TYPES (decl);
7273 while (chain && TREE_VALUE (chain) != void_type_node)
7275 gen_declaration_1 (TREE_VALUE (chain), str);
7276 chain = TREE_CHAIN (chain);
7277 if (chain && TREE_VALUE (chain) != void_type_node)
7283 else if (code == INDIRECT_REF)
7285 strcpy (tmpbuf, "*");
7286 if (TREE_TYPE (decl) && TREE_CODE (TREE_TYPE (decl)) == TREE_LIST)
7290 for (chain = nreverse (copy_list (TREE_TYPE (decl)));
7292 chain = TREE_CHAIN (chain))
7294 if (TREE_CODE (TREE_VALUE (chain)) == IDENTIFIER_NODE)
7296 strcat (tmpbuf, " ");
7297 strcat (tmpbuf, IDENTIFIER_POINTER (TREE_VALUE (chain)));
7301 strcat (tmpbuf, " ");
7303 strcat (tmpbuf, str);
7304 strcpy (str, tmpbuf);
7307 else if (code == POINTER_TYPE)
7309 strcpy (tmpbuf, "*");
7310 if (TREE_READONLY (decl) || TYPE_VOLATILE (decl))
7312 if (TREE_READONLY (decl))
7313 strcat (tmpbuf, " const");
7314 if (TYPE_VOLATILE (decl))
7315 strcat (tmpbuf, " volatile");
7317 strcat (tmpbuf, " ");
7319 strcat (tmpbuf, str);
7320 strcpy (str, tmpbuf);
7325 gen_declarator (decl, buf, name)
7332 enum tree_code code = TREE_CODE (decl);
7342 op = TREE_OPERAND (decl, 0);
7344 /* We have a pointer to a function or array...(*)(), (*)[] */
7345 if ((code == ARRAY_REF || code == CALL_EXPR)
7346 && op && TREE_CODE (op) == INDIRECT_REF)
7349 str = gen_declarator (op, buf, name);
7353 strcpy (tmpbuf, "(");
7354 strcat (tmpbuf, str);
7355 strcat (tmpbuf, ")");
7356 strcpy (str, tmpbuf);
7359 adorn_decl (decl, str);
7368 /* This clause is done iteratively rather than recursively. */
7371 op = (is_complex_decl (TREE_TYPE (decl))
7372 ? TREE_TYPE (decl) : NULL_TREE);
7374 adorn_decl (decl, str);
7376 /* We have a pointer to a function or array...(*)(), (*)[] */
7377 if (code == POINTER_TYPE
7378 && op && (TREE_CODE (op) == FUNCTION_TYPE
7379 || TREE_CODE (op) == ARRAY_TYPE))
7381 strcpy (tmpbuf, "(");
7382 strcat (tmpbuf, str);
7383 strcat (tmpbuf, ")");
7384 strcpy (str, tmpbuf);
7387 decl = (is_complex_decl (TREE_TYPE (decl))
7388 ? TREE_TYPE (decl) : NULL_TREE);
7391 while (decl && (code = TREE_CODE (decl)))
7396 case IDENTIFIER_NODE:
7397 /* Will only happen if we are processing a "raw" expr-decl. */
7398 strcpy (buf, IDENTIFIER_POINTER (decl));
7409 /* We have an abstract declarator or a _DECL node. */
7417 gen_declspecs (declspecs, buf, raw)
7426 for (chain = nreverse (copy_list (declspecs));
7427 chain; chain = TREE_CHAIN (chain))
7429 tree aspec = TREE_VALUE (chain);
7431 if (TREE_CODE (aspec) == IDENTIFIER_NODE)
7432 strcat (buf, IDENTIFIER_POINTER (aspec));
7433 else if (TREE_CODE (aspec) == RECORD_TYPE)
7435 if (TYPE_NAME (aspec))
7437 tree protocol_list = TYPE_PROTOCOL_LIST (aspec);
7439 if (! TREE_STATIC_TEMPLATE (aspec))
7440 strcat (buf, "struct ");
7441 strcat (buf, IDENTIFIER_POINTER (TYPE_NAME (aspec)));
7446 tree chain = protocol_list;
7453 (PROTOCOL_NAME (TREE_VALUE (chain))));
7454 chain = TREE_CHAIN (chain);
7463 strcat (buf, "untagged struct");
7466 else if (TREE_CODE (aspec) == UNION_TYPE)
7468 if (TYPE_NAME (aspec))
7470 if (! TREE_STATIC_TEMPLATE (aspec))
7471 strcat (buf, "union ");
7472 strcat (buf, IDENTIFIER_POINTER (TYPE_NAME (aspec)));
7475 strcat (buf, "untagged union");
7478 else if (TREE_CODE (aspec) == ENUMERAL_TYPE)
7480 if (TYPE_NAME (aspec))
7482 if (! TREE_STATIC_TEMPLATE (aspec))
7483 strcat (buf, "enum ");
7484 strcat (buf, IDENTIFIER_POINTER (TYPE_NAME (aspec)));
7487 strcat (buf, "untagged enum");
7490 else if (TREE_CODE (aspec) == TYPE_DECL && DECL_NAME (aspec))
7491 strcat (buf, IDENTIFIER_POINTER (DECL_NAME (aspec)));
7493 else if (IS_ID (aspec))
7495 tree protocol_list = TYPE_PROTOCOL_LIST (aspec);
7500 tree chain = protocol_list;
7507 (PROTOCOL_NAME (TREE_VALUE (chain))));
7508 chain = TREE_CHAIN (chain);
7515 if (TREE_CHAIN (chain))
7521 /* Type qualifiers. */
7522 if (TREE_READONLY (declspecs))
7523 strcat (buf, "const ");
7524 if (TYPE_VOLATILE (declspecs))
7525 strcat (buf, "volatile ");
7527 switch (TREE_CODE (declspecs))
7529 /* Type specifiers. */
7532 declspecs = TYPE_MAIN_VARIANT (declspecs);
7534 /* Signed integer types. */
7536 if (declspecs == short_integer_type_node)
7537 strcat (buf, "short int ");
7538 else if (declspecs == integer_type_node)
7539 strcat (buf, "int ");
7540 else if (declspecs == long_integer_type_node)
7541 strcat (buf, "long int ");
7542 else if (declspecs == long_long_integer_type_node)
7543 strcat (buf, "long long int ");
7544 else if (declspecs == signed_char_type_node
7545 || declspecs == char_type_node)
7546 strcat (buf, "char ");
7548 /* Unsigned integer types. */
7550 else if (declspecs == short_unsigned_type_node)
7551 strcat (buf, "unsigned short ");
7552 else if (declspecs == unsigned_type_node)
7553 strcat (buf, "unsigned int ");
7554 else if (declspecs == long_unsigned_type_node)
7555 strcat (buf, "unsigned long ");
7556 else if (declspecs == long_long_unsigned_type_node)
7557 strcat (buf, "unsigned long long ");
7558 else if (declspecs == unsigned_char_type_node)
7559 strcat (buf, "unsigned char ");
7563 declspecs = TYPE_MAIN_VARIANT (declspecs);
7565 if (declspecs == float_type_node)
7566 strcat (buf, "float ");
7567 else if (declspecs == double_type_node)
7568 strcat (buf, "double ");
7569 else if (declspecs == long_double_type_node)
7570 strcat (buf, "long double ");
7574 if (TYPE_NAME (declspecs)
7575 && TREE_CODE (TYPE_NAME (declspecs)) == IDENTIFIER_NODE)
7577 tree protocol_list = TYPE_PROTOCOL_LIST (declspecs);
7579 if (! TREE_STATIC_TEMPLATE (declspecs))
7580 strcat (buf, "struct ");
7581 strcat (buf, IDENTIFIER_POINTER (TYPE_NAME (declspecs)));
7585 tree chain = protocol_list;
7592 (PROTOCOL_NAME (TREE_VALUE (chain))));
7593 chain = TREE_CHAIN (chain);
7602 strcat (buf, "untagged struct");
7608 if (TYPE_NAME (declspecs)
7609 && TREE_CODE (TYPE_NAME (declspecs)) == IDENTIFIER_NODE)
7611 strcat (buf, "union ");
7612 strcat (buf, IDENTIFIER_POINTER (TYPE_NAME (declspecs)));
7617 strcat (buf, "untagged union ");
7621 if (TYPE_NAME (declspecs)
7622 && TREE_CODE (TYPE_NAME (declspecs)) == IDENTIFIER_NODE)
7624 strcat (buf, "enum ");
7625 strcat (buf, IDENTIFIER_POINTER (TYPE_NAME (declspecs)));
7630 strcat (buf, "untagged enum ");
7634 strcat (buf, "void ");
7639 tree protocol_list = TYPE_PROTOCOL_LIST (declspecs);
7644 tree chain = protocol_list;
7651 (PROTOCOL_NAME (TREE_VALUE (chain))));
7652 chain = TREE_CHAIN (chain);
7668 /* Given a tree node, produce a printable description of it in the given
7669 buffer, overwriting the buffer. */
7672 gen_declaration (atype_or_adecl, buf)
7673 tree atype_or_adecl;
7677 gen_declaration_1 (atype_or_adecl, buf);
7681 /* Given a tree node, append a printable description to the end of the
7685 gen_declaration_1 (atype_or_adecl, buf)
7686 tree atype_or_adecl;
7691 if (TREE_CODE (atype_or_adecl) == TREE_LIST)
7693 tree declspecs; /* "identifier_node", "record_type" */
7694 tree declarator; /* "array_ref", "indirect_ref", "call_expr"... */
7696 /* We have a "raw", abstract declarator (typename). */
7697 declarator = TREE_VALUE (atype_or_adecl);
7698 declspecs = TREE_PURPOSE (atype_or_adecl);
7700 gen_declspecs (declspecs, buf, 1);
7704 strcat (buf, gen_declarator (declarator, declbuf, ""));
7711 tree declspecs; /* "integer_type", "real_type", "record_type"... */
7712 tree declarator; /* "array_type", "function_type", "pointer_type". */
7714 if (TREE_CODE (atype_or_adecl) == FIELD_DECL
7715 || TREE_CODE (atype_or_adecl) == PARM_DECL
7716 || TREE_CODE (atype_or_adecl) == FUNCTION_DECL)
7717 atype = TREE_TYPE (atype_or_adecl);
7719 /* Assume we have a *_type node. */
7720 atype = atype_or_adecl;
7722 if (is_complex_decl (atype))
7726 /* Get the declaration specifier; it is at the end of the list. */
7727 declarator = chain = atype;
7729 chain = TREE_TYPE (chain); /* not TREE_CHAIN (chain); */
7730 while (is_complex_decl (chain));
7737 declarator = NULL_TREE;
7740 gen_declspecs (declspecs, buf, 0);
7742 if (TREE_CODE (atype_or_adecl) == FIELD_DECL
7743 || TREE_CODE (atype_or_adecl) == PARM_DECL
7744 || TREE_CODE (atype_or_adecl) == FUNCTION_DECL)
7746 const char *const decl_name =
7747 (DECL_NAME (atype_or_adecl)
7748 ? IDENTIFIER_POINTER (DECL_NAME (atype_or_adecl)) : "");
7753 strcat (buf, gen_declarator (declarator, declbuf, decl_name));
7756 else if (decl_name[0])
7759 strcat (buf, decl_name);
7762 else if (declarator)
7765 strcat (buf, gen_declarator (declarator, declbuf, ""));
7770 #define RAW_TYPESPEC(meth) (TREE_VALUE (TREE_PURPOSE (TREE_TYPE (meth))))
7772 /* Given a method tree, put a printable description into the given
7773 buffer (overwriting) and return a pointer to the buffer. */
7776 gen_method_decl (method, buf)
7783 if (RAW_TYPESPEC (method) != objc_object_reference)
7786 gen_declaration_1 (TREE_TYPE (method), buf);
7790 chain = METHOD_SEL_ARGS (method);
7793 /* We have a chain of keyword_decls. */
7796 if (KEYWORD_KEY_NAME (chain))
7797 strcat (buf, IDENTIFIER_POINTER (KEYWORD_KEY_NAME (chain)));
7800 if (RAW_TYPESPEC (chain) != objc_object_reference)
7803 gen_declaration_1 (TREE_TYPE (chain), buf);
7807 strcat (buf, IDENTIFIER_POINTER (KEYWORD_ARG_NAME (chain)));
7808 if ((chain = TREE_CHAIN (chain)))
7813 if (METHOD_ADD_ARGS (method) == objc_ellipsis_node)
7814 strcat (buf, ", ...");
7815 else if (METHOD_ADD_ARGS (method))
7817 /* We have a tree list node as generate by get_parm_info. */
7818 chain = TREE_PURPOSE (METHOD_ADD_ARGS (method));
7820 /* Know we have a chain of parm_decls. */
7824 gen_declaration_1 (chain, buf);
7825 chain = TREE_CHAIN (chain);
7831 /* We have a unary selector. */
7832 strcat (buf, IDENTIFIER_POINTER (METHOD_SEL_NAME (method)));
7840 dump_interface (fp, chain)
7844 char *buf = (char *) xmalloc (256);
7845 const char *my_name = IDENTIFIER_POINTER (CLASS_NAME (chain));
7846 tree ivar_decls = CLASS_RAW_IVARS (chain);
7847 tree nst_methods = CLASS_NST_METHODS (chain);
7848 tree cls_methods = CLASS_CLS_METHODS (chain);
7850 fprintf (fp, "\n@interface %s", my_name);
7852 if (CLASS_SUPER_NAME (chain))
7854 const char *super_name = IDENTIFIER_POINTER (CLASS_SUPER_NAME (chain));
7855 fprintf (fp, " : %s\n", super_name);
7862 fprintf (fp, "{\n");
7865 fprintf (fp, "\t%s;\n", gen_declaration (ivar_decls, buf));
7866 ivar_decls = TREE_CHAIN (ivar_decls);
7869 fprintf (fp, "}\n");
7874 fprintf (fp, "- %s;\n", gen_method_decl (nst_methods, buf));
7875 nst_methods = TREE_CHAIN (nst_methods);
7880 fprintf (fp, "+ %s;\n", gen_method_decl (cls_methods, buf));
7881 cls_methods = TREE_CHAIN (cls_methods);
7883 fprintf (fp, "\n@end");
7886 /* Demangle function for Objective-C */
7888 objc_demangle (mangled)
7889 const char *mangled;
7891 char *demangled, *cp;
7893 if (mangled[0] == '_' &&
7894 (mangled[1] == 'i' || mangled[1] == 'c') &&
7897 cp = demangled = xmalloc(strlen(mangled) + 2);
7898 if (mangled[1] == 'i')
7899 *cp++ = '-'; /* for instance method */
7901 *cp++ = '+'; /* for class method */
7902 *cp++ = '['; /* opening left brace */
7903 strcpy(cp, mangled+3); /* tack on the rest of the mangled name */
7904 while (*cp && *cp == '_')
7905 cp++; /* skip any initial underbars in class name */
7906 cp = strchr(cp, '_'); /* find first non-initial underbar */
7909 free(demangled); /* not mangled name */
7912 if (cp[1] == '_') /* easy case: no category name */
7914 *cp++ = ' '; /* replace two '_' with one ' ' */
7915 strcpy(cp, mangled + (cp - demangled) + 2);
7919 *cp++ = '('; /* less easy case: category name */
7920 cp = strchr(cp, '_');
7923 free(demangled); /* not mangled name */
7927 *cp++ = ' '; /* overwriting 1st char of method name... */
7928 strcpy(cp, mangled + (cp - demangled)); /* get it back */
7930 while (*cp && *cp == '_')
7931 cp++; /* skip any initial underbars in method name */
7934 *cp = ':'; /* replace remaining '_' with ':' */
7935 *cp++ = ']'; /* closing right brace */
7936 *cp++ = 0; /* string terminator */
7940 return mangled; /* not an objc mangled name */
7944 objc_printable_name (decl, kind)
7946 int kind ATTRIBUTE_UNUSED;
7948 return objc_demangle (IDENTIFIER_POINTER (DECL_NAME (decl)));
7954 gcc_obstack_init (&util_obstack);
7955 util_firstobj = (char *) obstack_finish (&util_obstack);
7957 errbuf = (char *) xmalloc (BUFSIZE);
7959 synth_module_prologue ();
7965 struct imp_entry *impent;
7967 /* The internally generated initializers appear to have missing braces.
7968 Don't warn about this. */
7969 int save_warn_missing_braces = warn_missing_braces;
7970 warn_missing_braces = 0;
7972 /* A missing @end may not be detected by the parser. */
7973 if (objc_implementation_context)
7975 warning ("`@end' missing in implementation context");
7976 finish_class (objc_implementation_context);
7977 objc_ivar_chain = NULL_TREE;
7978 objc_implementation_context = NULL_TREE;
7981 generate_forward_declaration_to_string_table ();
7983 #ifdef OBJC_PROLOGUE
7987 /* Process the static instances here because initialization of objc_symtab
7989 if (objc_static_instances)
7990 generate_static_references ();
7992 if (imp_list || class_names_chain
7993 || meth_var_names_chain || meth_var_types_chain || sel_ref_chain)
7994 generate_objc_symtab_decl ();
7996 for (impent = imp_list; impent; impent = impent->next)
7998 objc_implementation_context = impent->imp_context;
7999 implementation_template = impent->imp_template;
8001 UOBJC_CLASS_decl = impent->class_decl;
8002 UOBJC_METACLASS_decl = impent->meta_decl;
8004 if (TREE_CODE (objc_implementation_context) == CLASS_IMPLEMENTATION_TYPE)
8006 /* all of the following reference the string pool... */
8007 generate_ivar_lists ();
8008 generate_dispatch_tables ();
8009 generate_shared_structures ();
8013 generate_dispatch_tables ();
8014 generate_category (objc_implementation_context);
8018 /* If we are using an array of selectors, we must always
8019 finish up the array decl even if no selectors were used. */
8020 if (! flag_next_runtime || sel_ref_chain)
8021 build_selector_translation_table ();
8024 generate_protocols ();
8026 if (objc_implementation_context || class_names_chain || objc_static_instances
8027 || meth_var_names_chain || meth_var_types_chain || sel_ref_chain)
8029 /* Arrange for ObjC data structures to be initialized at run time. */
8030 rtx init_sym = build_module_descriptor ();
8031 if (init_sym && targetm.have_ctors_dtors)
8032 (* targetm.asm_out.constructor) (init_sym, DEFAULT_INIT_PRIORITY);
8035 /* Dump the class references. This forces the appropriate classes
8036 to be linked into the executable image, preserving unix archive
8037 semantics. This can be removed when we move to a more dynamically
8038 linked environment. */
8040 for (chain = cls_ref_chain; chain; chain = TREE_CHAIN (chain))
8042 handle_class_ref (chain);
8043 if (TREE_PURPOSE (chain))
8044 generate_classref_translation_entry (chain);
8047 for (impent = imp_list; impent; impent = impent->next)
8048 handle_impent (impent);
8050 /* Dump the string table last. */
8052 generate_strings ();
8054 if (flag_gen_declaration)
8056 add_class (objc_implementation_context);
8057 dump_interface (gen_declaration_file, objc_implementation_context);
8065 /* Run through the selector hash tables and print a warning for any
8066 selector which has multiple methods. */
8068 for (slot = 0; slot < SIZEHASHTABLE; slot++)
8069 for (hsh = cls_method_hash_list[slot]; hsh; hsh = hsh->next)
8072 tree meth = hsh->key;
8073 char type = (TREE_CODE (meth) == INSTANCE_METHOD_DECL
8077 warning ("potential selector conflict for method `%s'",
8078 IDENTIFIER_POINTER (METHOD_SEL_NAME (meth)));
8079 warn_with_method ("found", type, meth);
8080 for (loop = hsh->list; loop; loop = loop->next)
8081 warn_with_method ("found", type, loop->value);
8084 for (slot = 0; slot < SIZEHASHTABLE; slot++)
8085 for (hsh = nst_method_hash_list[slot]; hsh; hsh = hsh->next)
8088 tree meth = hsh->key;
8089 char type = (TREE_CODE (meth) == INSTANCE_METHOD_DECL
8093 warning ("potential selector conflict for method `%s'",
8094 IDENTIFIER_POINTER (METHOD_SEL_NAME (meth)));
8095 warn_with_method ("found", type, meth);
8096 for (loop = hsh->list; loop; loop = loop->next)
8097 warn_with_method ("found", type, loop->value);
8101 warn_missing_braces = save_warn_missing_braces;
8104 /* Subroutines of finish_objc. */
8107 generate_classref_translation_entry (chain)
8110 tree expr, name, decl_specs, decl, sc_spec;
8113 type = TREE_TYPE (TREE_PURPOSE (chain));
8115 expr = add_objc_string (TREE_VALUE (chain), class_names);
8116 expr = build_c_cast (type, expr); /* cast! */
8118 name = DECL_NAME (TREE_PURPOSE (chain));
8120 sc_spec = build_tree_list (NULL_TREE, ridpointers[(int) RID_STATIC]);
8122 /* static struct objc_class * _OBJC_CLASS_REFERENCES_n = ...; */
8123 decl_specs = tree_cons (NULL_TREE, type, sc_spec);
8125 /* The decl that is returned from start_decl is the one that we
8126 forward declared in build_class_reference. */
8127 decl = start_decl (name, decl_specs, 1, NULL_TREE);
8128 DECL_CONTEXT (decl) = NULL_TREE;
8129 finish_decl (decl, expr, NULL_TREE);
8134 handle_class_ref (chain)
8137 const char *name = IDENTIFIER_POINTER (TREE_VALUE (chain));
8138 char *string = (char *) alloca (strlen (name) + 30);
8142 sprintf (string, "%sobjc_class_name_%s",
8143 (flag_next_runtime ? "." : "__"), name);
8145 #ifdef ASM_DECLARE_UNRESOLVED_REFERENCE
8146 if (flag_next_runtime)
8148 ASM_DECLARE_UNRESOLVED_REFERENCE (asm_out_file, string);
8153 /* Make a decl for this name, so we can use its address in a tree. */
8154 decl = build_decl (VAR_DECL, get_identifier (string), char_type_node);
8155 DECL_EXTERNAL (decl) = 1;
8156 TREE_PUBLIC (decl) = 1;
8159 rest_of_decl_compilation (decl, 0, 0, 0);
8161 /* Make a decl for the address. */
8162 sprintf (string, "%sobjc_class_ref_%s",
8163 (flag_next_runtime ? "." : "__"), name);
8164 exp = build1 (ADDR_EXPR, string_type_node, decl);
8165 decl = build_decl (VAR_DECL, get_identifier (string), string_type_node);
8166 DECL_INITIAL (decl) = exp;
8167 TREE_STATIC (decl) = 1;
8168 TREE_USED (decl) = 1;
8171 rest_of_decl_compilation (decl, 0, 0, 0);
8175 handle_impent (impent)
8176 struct imp_entry *impent;
8180 objc_implementation_context = impent->imp_context;
8181 implementation_template = impent->imp_template;
8183 if (TREE_CODE (impent->imp_context) == CLASS_IMPLEMENTATION_TYPE)
8185 const char *const class_name =
8186 IDENTIFIER_POINTER (CLASS_NAME (impent->imp_context));
8188 string = (char *) alloca (strlen (class_name) + 30);
8190 sprintf (string, "%sobjc_class_name_%s",
8191 (flag_next_runtime ? "." : "__"), class_name);
8193 else if (TREE_CODE (impent->imp_context) == CATEGORY_IMPLEMENTATION_TYPE)
8195 const char *const class_name =
8196 IDENTIFIER_POINTER (CLASS_NAME (impent->imp_context));
8197 const char *const class_super_name =
8198 IDENTIFIER_POINTER (CLASS_SUPER_NAME (impent->imp_context));
8200 string = (char *) alloca (strlen (class_name)
8201 + strlen (class_super_name) + 30);
8203 /* Do the same for categories. Even though no references to
8204 these symbols are generated automatically by the compiler, it
8205 gives you a handle to pull them into an archive by hand. */
8206 sprintf (string, "*%sobjc_category_name_%s_%s",
8207 (flag_next_runtime ? "." : "__"), class_name, class_super_name);
8212 #ifdef ASM_DECLARE_CLASS_REFERENCE
8213 if (flag_next_runtime)
8215 ASM_DECLARE_CLASS_REFERENCE (asm_out_file, string);
8223 init = build_int_2 (0, 0);
8224 TREE_TYPE (init) = c_common_type_for_size (BITS_PER_WORD, 1);
8225 decl = build_decl (VAR_DECL, get_identifier (string), TREE_TYPE (init));
8226 TREE_PUBLIC (decl) = 1;
8227 TREE_READONLY (decl) = 1;
8228 TREE_USED (decl) = 1;
8229 TREE_CONSTANT (decl) = 1;
8230 DECL_CONTEXT (decl) = 0;
8231 DECL_ARTIFICIAL (decl) = 1;
8232 DECL_INITIAL (decl) = init;
8233 assemble_variable (decl, 1, 0, 0);
8237 /* Look up ID as an instance variable. */
8239 lookup_objc_ivar (id)
8244 if (objc_method_context && !strcmp (IDENTIFIER_POINTER (id), "super"))
8245 /* We have a message to super. */
8246 return get_super_receiver ();
8247 else if (objc_method_context && (decl = is_ivar (objc_ivar_chain, id)))
8249 if (is_private (decl))
8250 return error_mark_node;
8252 return build_ivar_reference (id);
8258 #include "gtype-objc.h"