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;
5109 build_selector_expr (selnamelist)
5114 /* Obtain the full selector name. */
5115 if (TREE_CODE (selnamelist) == IDENTIFIER_NODE)
5116 /* A unary selector. */
5117 selname = selnamelist;
5118 else if (TREE_CODE (selnamelist) == TREE_LIST)
5119 selname = build_keyword_selector (selnamelist);
5123 if (flag_typed_selectors)
5124 return build_typed_selector_reference (selname, 0);
5126 return build_selector_reference (selname);
5130 build_encode_expr (type)
5136 encode_type (type, obstack_object_size (&util_obstack),
5137 OBJC_ENCODE_INLINE_DEFS);
5138 obstack_1grow (&util_obstack, 0); /* null terminate string */
5139 string = obstack_finish (&util_obstack);
5141 /* Synthesize a string that represents the encoded struct/union. */
5142 result = my_build_string (strlen (string) + 1, string);
5143 obstack_free (&util_obstack, util_firstobj);
5148 build_ivar_reference (id)
5151 if (TREE_CODE (objc_method_context) == CLASS_METHOD_DECL)
5153 /* Historically, a class method that produced objects (factory
5154 method) would assign `self' to the instance that it
5155 allocated. This would effectively turn the class method into
5156 an instance method. Following this assignment, the instance
5157 variables could be accessed. That practice, while safe,
5158 violates the simple rule that a class method should not refer
5159 to an instance variable. It's better to catch the cases
5160 where this is done unknowingly than to support the above
5162 warning ("instance variable `%s' accessed in class method",
5163 IDENTIFIER_POINTER (id));
5164 TREE_TYPE (self_decl) = instance_type; /* cast */
5167 return build_component_ref (build_indirect_ref (self_decl, "->"), id);
5170 /* Compute a hash value for a given method SEL_NAME. */
5173 hash_func (sel_name)
5176 const unsigned char *s
5177 = (const unsigned char *)IDENTIFIER_POINTER (sel_name);
5181 h = h * 67 + *s++ - 113;
5188 nst_method_hash_list = (hash *) ggc_calloc (SIZEHASHTABLE, sizeof (hash));
5189 cls_method_hash_list = (hash *) ggc_calloc (SIZEHASHTABLE, sizeof (hash));
5192 /* WARNING!!!! hash_enter is called with a method, and will peek
5193 inside to find its selector! But hash_lookup is given a selector
5194 directly, and looks for the selector that's inside the found
5195 entry's key (method) for comparison. */
5198 hash_enter (hashlist, method)
5203 int slot = hash_func (METHOD_SEL_NAME (method)) % SIZEHASHTABLE;
5205 obj = (hash) ggc_alloc (sizeof (struct hashed_entry));
5207 obj->next = hashlist[slot];
5210 hashlist[slot] = obj; /* append to front */
5214 hash_lookup (hashlist, sel_name)
5220 target = hashlist[hash_func (sel_name) % SIZEHASHTABLE];
5224 if (sel_name == METHOD_SEL_NAME (target->key))
5227 target = target->next;
5233 hash_add_attr (entry, value)
5239 obj = (attr) ggc_alloc (sizeof (struct hashed_attribute));
5240 obj->next = entry->list;
5243 entry->list = obj; /* append to front */
5247 lookup_method (mchain, method)
5253 if (TREE_CODE (method) == IDENTIFIER_NODE)
5256 key = METHOD_SEL_NAME (method);
5260 if (METHOD_SEL_NAME (mchain) == key)
5262 mchain = TREE_CHAIN (mchain);
5268 lookup_instance_method_static (interface, ident)
5272 tree inter = interface;
5273 tree chain = CLASS_NST_METHODS (inter);
5274 tree meth = NULL_TREE;
5278 if ((meth = lookup_method (chain, ident)))
5281 if (CLASS_CATEGORY_LIST (inter))
5283 tree category = CLASS_CATEGORY_LIST (inter);
5284 chain = CLASS_NST_METHODS (category);
5288 if ((meth = lookup_method (chain, ident)))
5291 /* Check for instance methods in protocols in categories. */
5292 if (CLASS_PROTOCOL_LIST (category))
5294 if ((meth = (lookup_method_in_protocol_list
5295 (CLASS_PROTOCOL_LIST (category), ident, 0))))
5299 if ((category = CLASS_CATEGORY_LIST (category)))
5300 chain = CLASS_NST_METHODS (category);
5305 if (CLASS_PROTOCOL_LIST (inter))
5307 if ((meth = (lookup_method_in_protocol_list
5308 (CLASS_PROTOCOL_LIST (inter), ident, 0))))
5312 if ((inter = lookup_interface (CLASS_SUPER_NAME (inter))))
5313 chain = CLASS_NST_METHODS (inter);
5321 lookup_class_method_static (interface, ident)
5325 tree inter = interface;
5326 tree chain = CLASS_CLS_METHODS (inter);
5327 tree meth = NULL_TREE;
5328 tree root_inter = NULL_TREE;
5332 if ((meth = lookup_method (chain, ident)))
5335 if (CLASS_CATEGORY_LIST (inter))
5337 tree category = CLASS_CATEGORY_LIST (inter);
5338 chain = CLASS_CLS_METHODS (category);
5342 if ((meth = lookup_method (chain, ident)))
5345 /* Check for class methods in protocols in categories. */
5346 if (CLASS_PROTOCOL_LIST (category))
5348 if ((meth = (lookup_method_in_protocol_list
5349 (CLASS_PROTOCOL_LIST (category), ident, 1))))
5353 if ((category = CLASS_CATEGORY_LIST (category)))
5354 chain = CLASS_CLS_METHODS (category);
5359 /* Check for class methods in protocols. */
5360 if (CLASS_PROTOCOL_LIST (inter))
5362 if ((meth = (lookup_method_in_protocol_list
5363 (CLASS_PROTOCOL_LIST (inter), ident, 1))))
5368 if ((inter = lookup_interface (CLASS_SUPER_NAME (inter))))
5369 chain = CLASS_CLS_METHODS (inter);
5373 /* If no class (factory) method was found, check if an _instance_
5374 method of the same name exists in the root class. This is what
5375 the Objective-C runtime will do. */
5376 return lookup_instance_method_static (root_inter, ident);
5380 add_class_method (class, method)
5387 if (!(mth = lookup_method (CLASS_CLS_METHODS (class), method)))
5389 /* put method on list in reverse order */
5390 TREE_CHAIN (method) = CLASS_CLS_METHODS (class);
5391 CLASS_CLS_METHODS (class) = method;
5395 if (TREE_CODE (class) == CLASS_IMPLEMENTATION_TYPE)
5396 error ("duplicate definition of class method `%s'",
5397 IDENTIFIER_POINTER (METHOD_SEL_NAME (mth)));
5400 /* Check types; if different, complain. */
5401 if (!comp_proto_with_proto (method, mth))
5402 error ("duplicate declaration of class method `%s'",
5403 IDENTIFIER_POINTER (METHOD_SEL_NAME (mth)));
5407 if (!(hsh = hash_lookup (cls_method_hash_list, METHOD_SEL_NAME (method))))
5409 /* Install on a global chain. */
5410 hash_enter (cls_method_hash_list, method);
5414 /* Check types; if different, add to a list. */
5415 if (!comp_proto_with_proto (method, hsh->key))
5416 hash_add_attr (hsh, method);
5422 add_instance_method (class, method)
5429 if (!(mth = lookup_method (CLASS_NST_METHODS (class), method)))
5431 /* Put method on list in reverse order. */
5432 TREE_CHAIN (method) = CLASS_NST_METHODS (class);
5433 CLASS_NST_METHODS (class) = method;
5437 if (TREE_CODE (class) == CLASS_IMPLEMENTATION_TYPE)
5438 error ("duplicate definition of instance method `%s'",
5439 IDENTIFIER_POINTER (METHOD_SEL_NAME (mth)));
5442 /* Check types; if different, complain. */
5443 if (!comp_proto_with_proto (method, mth))
5444 error ("duplicate declaration of instance method `%s'",
5445 IDENTIFIER_POINTER (METHOD_SEL_NAME (mth)));
5449 if (!(hsh = hash_lookup (nst_method_hash_list, METHOD_SEL_NAME (method))))
5451 /* Install on a global chain. */
5452 hash_enter (nst_method_hash_list, method);
5456 /* Check types; if different, add to a list. */
5457 if (!comp_proto_with_proto (method, hsh->key))
5458 hash_add_attr (hsh, method);
5467 /* Put interfaces on list in reverse order. */
5468 TREE_CHAIN (class) = interface_chain;
5469 interface_chain = class;
5470 return interface_chain;
5474 add_category (class, category)
5478 /* Put categories on list in reverse order. */
5479 tree cat = CLASS_CATEGORY_LIST (class);
5483 if (CLASS_SUPER_NAME (cat) == CLASS_SUPER_NAME (category))
5484 warning ("duplicate interface declaration for category `%s(%s)'",
5485 IDENTIFIER_POINTER (CLASS_NAME (class)),
5486 IDENTIFIER_POINTER (CLASS_SUPER_NAME (category)));
5487 cat = CLASS_CATEGORY_LIST (cat);
5490 CLASS_CATEGORY_LIST (category) = CLASS_CATEGORY_LIST (class);
5491 CLASS_CATEGORY_LIST (class) = category;
5494 /* Called after parsing each instance variable declaration. Necessary to
5495 preserve typedefs and implement public/private...
5497 PUBLIC is 1 for public, 0 for protected, and 2 for private. */
5500 add_instance_variable (class, public, declarator, declspecs, width)
5507 tree field_decl, raw_decl;
5509 raw_decl = build_tree_list (declspecs, declarator);
5511 if (CLASS_RAW_IVARS (class))
5512 chainon (CLASS_RAW_IVARS (class), raw_decl);
5514 CLASS_RAW_IVARS (class) = raw_decl;
5516 field_decl = grokfield (input_filename, lineno,
5517 declarator, declspecs, width);
5519 /* Overload the public attribute, it is not used for FIELD_DECLs. */
5523 TREE_PUBLIC (field_decl) = 0;
5524 TREE_PRIVATE (field_decl) = 0;
5525 TREE_PROTECTED (field_decl) = 1;
5529 TREE_PUBLIC (field_decl) = 1;
5530 TREE_PRIVATE (field_decl) = 0;
5531 TREE_PROTECTED (field_decl) = 0;
5535 TREE_PUBLIC (field_decl) = 0;
5536 TREE_PRIVATE (field_decl) = 1;
5537 TREE_PROTECTED (field_decl) = 0;
5542 if (CLASS_IVARS (class))
5543 chainon (CLASS_IVARS (class), field_decl);
5545 CLASS_IVARS (class) = field_decl;
5551 is_ivar (decl_chain, ident)
5555 for ( ; decl_chain; decl_chain = TREE_CHAIN (decl_chain))
5556 if (DECL_NAME (decl_chain) == ident)
5561 /* True if the ivar is private and we are not in its implementation. */
5567 if (TREE_PRIVATE (decl)
5568 && ! is_ivar (CLASS_IVARS (implementation_template), DECL_NAME (decl)))
5570 error ("instance variable `%s' is declared private",
5571 IDENTIFIER_POINTER (DECL_NAME (decl)));
5578 /* We have an instance variable reference;, check to see if it is public. */
5581 is_public (expr, identifier)
5585 tree basetype = TREE_TYPE (expr);
5586 enum tree_code code = TREE_CODE (basetype);
5589 if (code == RECORD_TYPE)
5591 if (TREE_STATIC_TEMPLATE (basetype))
5593 if (!lookup_interface (TYPE_NAME (basetype)))
5595 error ("cannot find interface declaration for `%s'",
5596 IDENTIFIER_POINTER (TYPE_NAME (basetype)));
5600 if ((decl = is_ivar (TYPE_FIELDS (basetype), identifier)))
5602 if (TREE_PUBLIC (decl))
5605 /* Important difference between the Stepstone translator:
5606 all instance variables should be public within the context
5607 of the implementation. */
5608 if (objc_implementation_context
5609 && (((TREE_CODE (objc_implementation_context)
5610 == CLASS_IMPLEMENTATION_TYPE)
5611 || (TREE_CODE (objc_implementation_context)
5612 == CATEGORY_IMPLEMENTATION_TYPE))
5613 && (CLASS_NAME (objc_implementation_context)
5614 == TYPE_NAME (basetype))))
5615 return ! is_private (decl);
5617 error ("instance variable `%s' is declared %s",
5618 IDENTIFIER_POINTER (identifier),
5619 TREE_PRIVATE (decl) ? "private" : "protected");
5624 else if (objc_implementation_context && (basetype == objc_object_reference))
5626 TREE_TYPE (expr) = uprivate_record;
5627 warning ("static access to object of type `id'");
5634 /* Make sure all entries in CHAIN are also in LIST. */
5637 check_methods (chain, list, mtype)
5646 if (!lookup_method (list, chain))
5650 if (TREE_CODE (objc_implementation_context)
5651 == CLASS_IMPLEMENTATION_TYPE)
5652 warning ("incomplete implementation of class `%s'",
5653 IDENTIFIER_POINTER (CLASS_NAME (objc_implementation_context)));
5654 else if (TREE_CODE (objc_implementation_context)
5655 == CATEGORY_IMPLEMENTATION_TYPE)
5656 warning ("incomplete implementation of category `%s'",
5657 IDENTIFIER_POINTER (CLASS_SUPER_NAME (objc_implementation_context)));
5661 warning ("method definition for `%c%s' not found",
5662 mtype, IDENTIFIER_POINTER (METHOD_SEL_NAME (chain)));
5665 chain = TREE_CHAIN (chain);
5671 /* Check if CLASS, or its superclasses, explicitly conforms to PROTOCOL. */
5674 conforms_to_protocol (class, protocol)
5678 if (TREE_CODE (protocol) == PROTOCOL_INTERFACE_TYPE)
5680 tree p = CLASS_PROTOCOL_LIST (class);
5681 while (p && TREE_VALUE (p) != protocol)
5686 tree super = (CLASS_SUPER_NAME (class)
5687 ? lookup_interface (CLASS_SUPER_NAME (class))
5689 int tmp = super ? conforms_to_protocol (super, protocol) : 0;
5698 /* Make sure all methods in CHAIN are accessible as MTYPE methods in
5699 CONTEXT. This is one of two mechanisms to check protocol integrity. */
5702 check_methods_accessible (chain, context, mtype)
5709 tree base_context = context;
5713 context = base_context;
5717 list = CLASS_CLS_METHODS (context);
5719 list = CLASS_NST_METHODS (context);
5721 if (lookup_method (list, chain))
5724 else if (TREE_CODE (context) == CLASS_IMPLEMENTATION_TYPE
5725 || TREE_CODE (context) == CLASS_INTERFACE_TYPE)
5726 context = (CLASS_SUPER_NAME (context)
5727 ? lookup_interface (CLASS_SUPER_NAME (context))
5730 else if (TREE_CODE (context) == CATEGORY_IMPLEMENTATION_TYPE
5731 || TREE_CODE (context) == CATEGORY_INTERFACE_TYPE)
5732 context = (CLASS_NAME (context)
5733 ? lookup_interface (CLASS_NAME (context))
5739 if (context == NULL_TREE)
5743 if (TREE_CODE (objc_implementation_context)
5744 == CLASS_IMPLEMENTATION_TYPE)
5745 warning ("incomplete implementation of class `%s'",
5747 (CLASS_NAME (objc_implementation_context)));
5748 else if (TREE_CODE (objc_implementation_context)
5749 == CATEGORY_IMPLEMENTATION_TYPE)
5750 warning ("incomplete implementation of category `%s'",
5752 (CLASS_SUPER_NAME (objc_implementation_context)));
5755 warning ("method definition for `%c%s' not found",
5756 mtype, IDENTIFIER_POINTER (METHOD_SEL_NAME (chain)));
5759 chain = TREE_CHAIN (chain); /* next method... */
5764 /* Check whether the current interface (accessible via
5765 'objc_implementation_context') actually implements protocol P, along
5766 with any protocols that P inherits. */
5769 check_protocol (p, type, name)
5774 if (TREE_CODE (p) == PROTOCOL_INTERFACE_TYPE)
5778 /* Ensure that all protocols have bodies! */
5781 f1 = check_methods (PROTOCOL_CLS_METHODS (p),
5782 CLASS_CLS_METHODS (objc_implementation_context),
5784 f2 = check_methods (PROTOCOL_NST_METHODS (p),
5785 CLASS_NST_METHODS (objc_implementation_context),
5790 f1 = check_methods_accessible (PROTOCOL_CLS_METHODS (p),
5791 objc_implementation_context,
5793 f2 = check_methods_accessible (PROTOCOL_NST_METHODS (p),
5794 objc_implementation_context,
5799 warning ("%s `%s' does not fully implement the `%s' protocol",
5800 type, name, IDENTIFIER_POINTER (PROTOCOL_NAME (p)));
5803 /* Check protocols recursively. */
5804 if (PROTOCOL_LIST (p))
5806 tree subs = PROTOCOL_LIST (p);
5808 lookup_interface (CLASS_SUPER_NAME (implementation_template));
5812 tree sub = TREE_VALUE (subs);
5814 /* If the superclass does not conform to the protocols
5815 inherited by P, then we must! */
5816 if (!super_class || !conforms_to_protocol (super_class, sub))
5817 check_protocol (sub, type, name);
5818 subs = TREE_CHAIN (subs);
5823 /* Check whether the current interface (accessible via
5824 'objc_implementation_context') actually implements the protocols listed
5828 check_protocols (proto_list, type, name)
5833 for ( ; proto_list; proto_list = TREE_CHAIN (proto_list))
5835 tree p = TREE_VALUE (proto_list);
5837 check_protocol (p, type, name);
5841 /* Make sure that the class CLASS_NAME is defined
5842 CODE says which kind of thing CLASS_NAME ought to be.
5843 It can be CLASS_INTERFACE_TYPE, CLASS_IMPLEMENTATION_TYPE,
5844 CATEGORY_INTERFACE_TYPE, or CATEGORY_IMPLEMENTATION_TYPE. */
5847 start_class (code, class_name, super_name, protocol_list)
5848 enum tree_code code;
5855 if (objc_implementation_context)
5857 warning ("`@end' missing in implementation context");
5858 finish_class (objc_implementation_context);
5859 objc_ivar_chain = NULL_TREE;
5860 objc_implementation_context = NULL_TREE;
5863 class = make_node (code);
5864 TYPE_BINFO (class) = make_tree_vec (6);
5866 CLASS_NAME (class) = class_name;
5867 CLASS_SUPER_NAME (class) = super_name;
5868 CLASS_CLS_METHODS (class) = NULL_TREE;
5870 if (! is_class_name (class_name) && (decl = lookup_name (class_name)))
5872 error ("`%s' redeclared as different kind of symbol",
5873 IDENTIFIER_POINTER (class_name));
5874 error_with_decl (decl, "previous declaration of `%s'");
5877 if (code == CLASS_IMPLEMENTATION_TYPE)
5882 for (chain = implemented_classes; chain; chain = TREE_CHAIN (chain))
5883 if (TREE_VALUE (chain) == class_name)
5885 error ("reimplementation of class `%s'",
5886 IDENTIFIER_POINTER (class_name));
5887 return error_mark_node;
5889 implemented_classes = tree_cons (NULL_TREE, class_name,
5890 implemented_classes);
5893 /* Pre-build the following entities - for speed/convenience. */
5895 self_id = get_identifier ("self");
5897 ucmd_id = get_identifier ("_cmd");
5900 = build_tree_list (get_identifier ("__unused__"), NULL_TREE);
5901 if (!objc_super_template)
5902 objc_super_template = build_super_template ();
5904 /* Reset for multiple classes per file. */
5907 objc_implementation_context = class;
5909 /* Lookup the interface for this implementation. */
5911 if (!(implementation_template = lookup_interface (class_name)))
5913 warning ("cannot find interface declaration for `%s'",
5914 IDENTIFIER_POINTER (class_name));
5915 add_class (implementation_template = objc_implementation_context);
5918 /* If a super class has been specified in the implementation,
5919 insure it conforms to the one specified in the interface. */
5922 && (super_name != CLASS_SUPER_NAME (implementation_template)))
5924 tree previous_name = CLASS_SUPER_NAME (implementation_template);
5925 const char *const name =
5926 previous_name ? IDENTIFIER_POINTER (previous_name) : "";
5927 error ("conflicting super class name `%s'",
5928 IDENTIFIER_POINTER (super_name));
5929 error ("previous declaration of `%s'", name);
5932 else if (! super_name)
5934 CLASS_SUPER_NAME (objc_implementation_context)
5935 = CLASS_SUPER_NAME (implementation_template);
5939 else if (code == CLASS_INTERFACE_TYPE)
5941 if (lookup_interface (class_name))
5942 warning ("duplicate interface declaration for class `%s'",
5943 IDENTIFIER_POINTER (class_name));
5948 CLASS_PROTOCOL_LIST (class)
5949 = lookup_and_install_protocols (protocol_list);
5952 else if (code == CATEGORY_INTERFACE_TYPE)
5954 tree class_category_is_assoc_with;
5956 /* For a category, class_name is really the name of the class that
5957 the following set of methods will be associated with. We must
5958 find the interface so that can derive the objects template. */
5960 if (!(class_category_is_assoc_with = lookup_interface (class_name)))
5962 error ("cannot find interface declaration for `%s'",
5963 IDENTIFIER_POINTER (class_name));
5964 exit (FATAL_EXIT_CODE);
5967 add_category (class_category_is_assoc_with, class);
5970 CLASS_PROTOCOL_LIST (class)
5971 = lookup_and_install_protocols (protocol_list);
5974 else if (code == CATEGORY_IMPLEMENTATION_TYPE)
5976 /* Pre-build the following entities for speed/convenience. */
5978 self_id = get_identifier ("self");
5980 ucmd_id = get_identifier ("_cmd");
5983 = build_tree_list (get_identifier ("__unused__"), NULL_TREE);
5984 if (!objc_super_template)
5985 objc_super_template = build_super_template ();
5987 /* Reset for multiple classes per file. */
5990 objc_implementation_context = class;
5992 /* For a category, class_name is really the name of the class that
5993 the following set of methods will be associated with. We must
5994 find the interface so that can derive the objects template. */
5996 if (!(implementation_template = lookup_interface (class_name)))
5998 error ("cannot find interface declaration for `%s'",
5999 IDENTIFIER_POINTER (class_name));
6000 exit (FATAL_EXIT_CODE);
6007 continue_class (class)
6010 if (TREE_CODE (class) == CLASS_IMPLEMENTATION_TYPE
6011 || TREE_CODE (class) == CATEGORY_IMPLEMENTATION_TYPE)
6013 struct imp_entry *imp_entry;
6016 /* Check consistency of the instance variables. */
6018 if (CLASS_IVARS (class))
6019 check_ivars (implementation_template, class);
6021 /* code generation */
6023 ivar_context = build_private_template (implementation_template);
6025 if (!objc_class_template)
6026 build_class_template ();
6028 imp_entry = (struct imp_entry *) ggc_alloc (sizeof (struct imp_entry));
6030 imp_entry->next = imp_list;
6031 imp_entry->imp_context = class;
6032 imp_entry->imp_template = implementation_template;
6034 synth_forward_declarations ();
6035 imp_entry->class_decl = UOBJC_CLASS_decl;
6036 imp_entry->meta_decl = UOBJC_METACLASS_decl;
6038 /* Append to front and increment count. */
6039 imp_list = imp_entry;
6040 if (TREE_CODE (class) == CLASS_IMPLEMENTATION_TYPE)
6045 return ivar_context;
6048 else if (TREE_CODE (class) == CLASS_INTERFACE_TYPE)
6050 tree record = xref_tag (RECORD_TYPE, CLASS_NAME (class));
6052 if (!TYPE_FIELDS (record))
6054 finish_struct (record, get_class_ivars (class), NULL_TREE);
6055 CLASS_STATIC_TEMPLATE (class) = record;
6057 /* Mark this record as a class template for static typing. */
6058 TREE_STATIC_TEMPLATE (record) = 1;
6065 return error_mark_node;
6068 /* This is called once we see the "@end" in an interface/implementation. */
6071 finish_class (class)
6074 if (TREE_CODE (class) == CLASS_IMPLEMENTATION_TYPE)
6076 /* All code generation is done in finish_objc. */
6078 if (implementation_template != objc_implementation_context)
6080 /* Ensure that all method listed in the interface contain bodies. */
6081 check_methods (CLASS_CLS_METHODS (implementation_template),
6082 CLASS_CLS_METHODS (objc_implementation_context), '+');
6083 check_methods (CLASS_NST_METHODS (implementation_template),
6084 CLASS_NST_METHODS (objc_implementation_context), '-');
6086 if (CLASS_PROTOCOL_LIST (implementation_template))
6087 check_protocols (CLASS_PROTOCOL_LIST (implementation_template),
6089 IDENTIFIER_POINTER (CLASS_NAME (objc_implementation_context)));
6093 else if (TREE_CODE (class) == CATEGORY_IMPLEMENTATION_TYPE)
6095 tree category = CLASS_CATEGORY_LIST (implementation_template);
6097 /* Find the category interface from the class it is associated with. */
6100 if (CLASS_SUPER_NAME (class) == CLASS_SUPER_NAME (category))
6102 category = CLASS_CATEGORY_LIST (category);
6107 /* Ensure all method listed in the interface contain bodies. */
6108 check_methods (CLASS_CLS_METHODS (category),
6109 CLASS_CLS_METHODS (objc_implementation_context), '+');
6110 check_methods (CLASS_NST_METHODS (category),
6111 CLASS_NST_METHODS (objc_implementation_context), '-');
6113 if (CLASS_PROTOCOL_LIST (category))
6114 check_protocols (CLASS_PROTOCOL_LIST (category),
6116 IDENTIFIER_POINTER (CLASS_SUPER_NAME (objc_implementation_context)));
6120 else if (TREE_CODE (class) == CLASS_INTERFACE_TYPE)
6123 const char *class_name = IDENTIFIER_POINTER (CLASS_NAME (class));
6124 char *string = (char *) alloca (strlen (class_name) + 3);
6126 /* extern struct objc_object *_<my_name>; */
6128 sprintf (string, "_%s", class_name);
6130 decl_specs = build_tree_list (NULL_TREE, ridpointers[(int) RID_EXTERN]);
6131 decl_specs = tree_cons (NULL_TREE, objc_object_reference, decl_specs);
6132 define_decl (build1 (INDIRECT_REF, NULL_TREE, get_identifier (string)),
6138 add_protocol (protocol)
6141 /* Put protocol on list in reverse order. */
6142 TREE_CHAIN (protocol) = protocol_chain;
6143 protocol_chain = protocol;
6144 return protocol_chain;
6148 lookup_protocol (ident)
6153 for (chain = protocol_chain; chain; chain = TREE_CHAIN (chain))
6154 if (ident == PROTOCOL_NAME (chain))
6160 /* This function forward declares the protocols named by NAMES. If
6161 they are already declared or defined, the function has no effect. */
6164 objc_declare_protocols (names)
6169 for (list = names; list; list = TREE_CHAIN (list))
6171 tree name = TREE_VALUE (list);
6173 if (lookup_protocol (name) == NULL_TREE)
6175 tree protocol = make_node (PROTOCOL_INTERFACE_TYPE);
6177 TYPE_BINFO (protocol) = make_tree_vec (2);
6178 PROTOCOL_NAME (protocol) = name;
6179 PROTOCOL_LIST (protocol) = NULL_TREE;
6180 add_protocol (protocol);
6181 PROTOCOL_DEFINED (protocol) = 0;
6182 PROTOCOL_FORWARD_DECL (protocol) = NULL_TREE;
6188 start_protocol (code, name, list)
6189 enum tree_code code;
6195 /* This is as good a place as any. Need to invoke
6196 push_tag_toplevel. */
6197 if (!objc_protocol_template)
6198 objc_protocol_template = build_protocol_template ();
6200 protocol = lookup_protocol (name);
6204 protocol = make_node (code);
6205 TYPE_BINFO (protocol) = make_tree_vec (2);
6207 PROTOCOL_NAME (protocol) = name;
6208 PROTOCOL_LIST (protocol) = lookup_and_install_protocols (list);
6209 add_protocol (protocol);
6210 PROTOCOL_DEFINED (protocol) = 1;
6211 PROTOCOL_FORWARD_DECL (protocol) = NULL_TREE;
6213 check_protocol_recursively (protocol, list);
6215 else if (! PROTOCOL_DEFINED (protocol))
6217 PROTOCOL_DEFINED (protocol) = 1;
6218 PROTOCOL_LIST (protocol) = lookup_and_install_protocols (list);
6220 check_protocol_recursively (protocol, list);
6224 warning ("duplicate declaration for protocol `%s'",
6225 IDENTIFIER_POINTER (name));
6231 finish_protocol (protocol)
6232 tree protocol ATTRIBUTE_UNUSED;
6237 /* "Encode" a data type into a string, which grows in util_obstack.
6238 ??? What is the FORMAT? Someone please document this! */
6241 encode_type_qualifiers (declspecs)
6246 for (spec = declspecs; spec; spec = TREE_CHAIN (spec))
6248 if (ridpointers[(int) RID_CONST] == TREE_VALUE (spec))
6249 obstack_1grow (&util_obstack, 'r');
6250 else if (ridpointers[(int) RID_IN] == TREE_VALUE (spec))
6251 obstack_1grow (&util_obstack, 'n');
6252 else if (ridpointers[(int) RID_INOUT] == TREE_VALUE (spec))
6253 obstack_1grow (&util_obstack, 'N');
6254 else if (ridpointers[(int) RID_OUT] == TREE_VALUE (spec))
6255 obstack_1grow (&util_obstack, 'o');
6256 else if (ridpointers[(int) RID_BYCOPY] == TREE_VALUE (spec))
6257 obstack_1grow (&util_obstack, 'O');
6258 else if (ridpointers[(int) RID_BYREF] == TREE_VALUE (spec))
6259 obstack_1grow (&util_obstack, 'R');
6260 else if (ridpointers[(int) RID_ONEWAY] == TREE_VALUE (spec))
6261 obstack_1grow (&util_obstack, 'V');
6265 /* Encode a pointer type. */
6268 encode_pointer (type, curtype, format)
6273 tree pointer_to = TREE_TYPE (type);
6275 if (TREE_CODE (pointer_to) == RECORD_TYPE)
6277 if (TYPE_NAME (pointer_to)
6278 && TREE_CODE (TYPE_NAME (pointer_to)) == IDENTIFIER_NODE)
6280 const char *name = IDENTIFIER_POINTER (TYPE_NAME (pointer_to));
6282 if (strcmp (name, TAG_OBJECT) == 0) /* '@' */
6284 obstack_1grow (&util_obstack, '@');
6287 else if (TREE_STATIC_TEMPLATE (pointer_to))
6289 if (generating_instance_variables)
6291 obstack_1grow (&util_obstack, '@');
6292 obstack_1grow (&util_obstack, '"');
6293 obstack_grow (&util_obstack, name, strlen (name));
6294 obstack_1grow (&util_obstack, '"');
6299 obstack_1grow (&util_obstack, '@');
6303 else if (strcmp (name, TAG_CLASS) == 0) /* '#' */
6305 obstack_1grow (&util_obstack, '#');
6308 else if (strcmp (name, TAG_SELECTOR) == 0) /* ':' */
6310 obstack_1grow (&util_obstack, ':');
6315 else if (TREE_CODE (pointer_to) == INTEGER_TYPE
6316 && TYPE_MODE (pointer_to) == QImode)
6318 obstack_1grow (&util_obstack, '*');
6322 /* We have a type that does not get special treatment. */
6324 /* NeXT extension */
6325 obstack_1grow (&util_obstack, '^');
6326 encode_type (pointer_to, curtype, format);
6330 encode_array (type, curtype, format)
6335 tree an_int_cst = TYPE_SIZE (type);
6336 tree array_of = TREE_TYPE (type);
6339 /* An incomplete array is treated like a pointer. */
6340 if (an_int_cst == NULL)
6342 encode_pointer (type, curtype, format);
6346 sprintf (buffer, "[%ld",
6347 (long) (TREE_INT_CST_LOW (an_int_cst)
6348 / TREE_INT_CST_LOW (TYPE_SIZE (array_of))));
6350 obstack_grow (&util_obstack, buffer, strlen (buffer));
6351 encode_type (array_of, curtype, format);
6352 obstack_1grow (&util_obstack, ']');
6357 encode_aggregate_within (type, curtype, format, left, right)
6364 /* The RECORD_TYPE may in fact be a typedef! For purposes
6365 of encoding, we need the real underlying enchilada. */
6366 if (TYPE_MAIN_VARIANT (type))
6367 type = TYPE_MAIN_VARIANT (type);
6369 if (obstack_object_size (&util_obstack) > 0
6370 && *(obstack_next_free (&util_obstack) - 1) == '^')
6372 tree name = TYPE_NAME (type);
6374 /* we have a reference; this is a NeXT extension. */
6376 if (obstack_object_size (&util_obstack) - curtype == 1
6377 && format == OBJC_ENCODE_INLINE_DEFS)
6379 /* Output format of struct for first level only. */
6380 tree fields = TYPE_FIELDS (type);
6382 if (name && TREE_CODE (name) == IDENTIFIER_NODE)
6384 obstack_1grow (&util_obstack, left);
6385 obstack_grow (&util_obstack,
6386 IDENTIFIER_POINTER (name),
6387 strlen (IDENTIFIER_POINTER (name)));
6388 obstack_1grow (&util_obstack, '=');
6392 obstack_1grow (&util_obstack, left);
6393 obstack_grow (&util_obstack, "?=", 2);
6396 for ( ; fields; fields = TREE_CHAIN (fields))
6397 encode_field_decl (fields, curtype, format);
6399 obstack_1grow (&util_obstack, right);
6402 else if (name && TREE_CODE (name) == IDENTIFIER_NODE)
6404 obstack_1grow (&util_obstack, left);
6405 obstack_grow (&util_obstack,
6406 IDENTIFIER_POINTER (name),
6407 strlen (IDENTIFIER_POINTER (name)));
6408 obstack_1grow (&util_obstack, right);
6413 /* We have an untagged structure or a typedef. */
6414 obstack_1grow (&util_obstack, left);
6415 obstack_1grow (&util_obstack, '?');
6416 obstack_1grow (&util_obstack, right);
6422 tree name = TYPE_NAME (type);
6423 tree fields = TYPE_FIELDS (type);
6425 if (format == OBJC_ENCODE_INLINE_DEFS
6426 || generating_instance_variables)
6428 obstack_1grow (&util_obstack, left);
6429 if (name && TREE_CODE (name) == IDENTIFIER_NODE)
6430 obstack_grow (&util_obstack,
6431 IDENTIFIER_POINTER (name),
6432 strlen (IDENTIFIER_POINTER (name)));
6434 obstack_1grow (&util_obstack, '?');
6436 obstack_1grow (&util_obstack, '=');
6438 for (; fields; fields = TREE_CHAIN (fields))
6440 if (generating_instance_variables)
6442 tree fname = DECL_NAME (fields);
6444 obstack_1grow (&util_obstack, '"');
6445 if (fname && TREE_CODE (fname) == IDENTIFIER_NODE)
6447 obstack_grow (&util_obstack,
6448 IDENTIFIER_POINTER (fname),
6449 strlen (IDENTIFIER_POINTER (fname)));
6452 obstack_1grow (&util_obstack, '"');
6455 encode_field_decl (fields, curtype, format);
6458 obstack_1grow (&util_obstack, right);
6463 obstack_1grow (&util_obstack, left);
6464 if (name && TREE_CODE (name) == IDENTIFIER_NODE)
6465 obstack_grow (&util_obstack,
6466 IDENTIFIER_POINTER (name),
6467 strlen (IDENTIFIER_POINTER (name)));
6469 /* We have an untagged structure or a typedef. */
6470 obstack_1grow (&util_obstack, '?');
6472 obstack_1grow (&util_obstack, right);
6478 encode_aggregate (type, curtype, format)
6483 enum tree_code code = TREE_CODE (type);
6489 encode_aggregate_within(type, curtype, format, '{', '}');
6494 encode_aggregate_within(type, curtype, format, '(', ')');
6499 obstack_1grow (&util_obstack, 'i');
6507 /* Support bitfields. The current version of Objective-C does not support
6508 them. The string will consist of one or more "b:n"'s where n is an
6509 integer describing the width of the bitfield. Currently, classes in
6510 the kit implement a method "-(char *)describeBitfieldStruct:" that
6511 simulates this. If they do not implement this method, the archiver
6512 assumes the bitfield is 16 bits wide (padded if necessary) and packed
6513 according to the GNU compiler. After looking at the "kit", it appears
6514 that all classes currently rely on this default behavior, rather than
6515 hand generating this string (which is tedious). */
6518 encode_bitfield (width)
6522 sprintf (buffer, "b%d", width);
6523 obstack_grow (&util_obstack, buffer, strlen (buffer));
6526 /* FORMAT will be OBJC_ENCODE_INLINE_DEFS or OBJC_ENCODE_DONT_INLINE_DEFS. */
6529 encode_type (type, curtype, format)
6534 enum tree_code code = TREE_CODE (type);
6536 if (code == INTEGER_TYPE)
6538 if (integer_zerop (TYPE_MIN_VALUE (type)))
6540 /* Unsigned integer types. */
6542 if (TYPE_MODE (type) == QImode)
6543 obstack_1grow (&util_obstack, 'C');
6544 else if (TYPE_MODE (type) == HImode)
6545 obstack_1grow (&util_obstack, 'S');
6546 else if (TYPE_MODE (type) == SImode)
6548 if (type == long_unsigned_type_node)
6549 obstack_1grow (&util_obstack, 'L');
6551 obstack_1grow (&util_obstack, 'I');
6553 else if (TYPE_MODE (type) == DImode)
6554 obstack_1grow (&util_obstack, 'Q');
6558 /* Signed integer types. */
6560 if (TYPE_MODE (type) == QImode)
6561 obstack_1grow (&util_obstack, 'c');
6562 else if (TYPE_MODE (type) == HImode)
6563 obstack_1grow (&util_obstack, 's');
6564 else if (TYPE_MODE (type) == SImode)
6566 if (type == long_integer_type_node)
6567 obstack_1grow (&util_obstack, 'l');
6569 obstack_1grow (&util_obstack, 'i');
6572 else if (TYPE_MODE (type) == DImode)
6573 obstack_1grow (&util_obstack, 'q');
6577 else if (code == REAL_TYPE)
6579 /* Floating point types. */
6581 if (TYPE_MODE (type) == SFmode)
6582 obstack_1grow (&util_obstack, 'f');
6583 else if (TYPE_MODE (type) == DFmode
6584 || TYPE_MODE (type) == TFmode)
6585 obstack_1grow (&util_obstack, 'd');
6588 else if (code == VOID_TYPE)
6589 obstack_1grow (&util_obstack, 'v');
6591 else if (code == ARRAY_TYPE)
6592 encode_array (type, curtype, format);
6594 else if (code == POINTER_TYPE)
6595 encode_pointer (type, curtype, format);
6597 else if (code == RECORD_TYPE || code == UNION_TYPE || code == ENUMERAL_TYPE)
6598 encode_aggregate (type, curtype, format);
6600 else if (code == FUNCTION_TYPE) /* '?' */
6601 obstack_1grow (&util_obstack, '?');
6605 encode_complete_bitfield (position, type, size)
6610 enum tree_code code = TREE_CODE (type);
6612 char charType = '?';
6614 if (code == INTEGER_TYPE)
6616 if (integer_zerop (TYPE_MIN_VALUE (type)))
6618 /* Unsigned integer types. */
6620 if (TYPE_MODE (type) == QImode)
6622 else if (TYPE_MODE (type) == HImode)
6624 else if (TYPE_MODE (type) == SImode)
6626 if (type == long_unsigned_type_node)
6631 else if (TYPE_MODE (type) == DImode)
6636 /* Signed integer types. */
6638 if (TYPE_MODE (type) == QImode)
6640 else if (TYPE_MODE (type) == HImode)
6642 else if (TYPE_MODE (type) == SImode)
6644 if (type == long_integer_type_node)
6650 else if (TYPE_MODE (type) == DImode)
6654 else if (code == ENUMERAL_TYPE)
6659 sprintf (buffer, "b%d%c%d", position, charType, size);
6660 obstack_grow (&util_obstack, buffer, strlen (buffer));
6664 encode_field_decl (field_decl, curtype, format)
6671 type = TREE_TYPE (field_decl);
6673 /* If this field is obviously a bitfield, or is a bitfield that has been
6674 clobbered to look like a ordinary integer mode, go ahead and generate
6675 the bitfield typing information. */
6676 if (flag_next_runtime)
6678 if (DECL_BIT_FIELD_TYPE (field_decl))
6679 encode_bitfield (tree_low_cst (DECL_SIZE (field_decl), 1));
6681 encode_type (TREE_TYPE (field_decl), curtype, format);
6685 if (DECL_BIT_FIELD_TYPE (field_decl))
6686 encode_complete_bitfield (int_bit_position (field_decl),
6687 DECL_BIT_FIELD_TYPE (field_decl),
6688 tree_low_cst (DECL_SIZE (field_decl), 1));
6690 encode_type (TREE_TYPE (field_decl), curtype, format);
6695 expr_last (complex_expr)
6701 while ((next = TREE_OPERAND (complex_expr, 0)))
6702 complex_expr = next;
6704 return complex_expr;
6707 /* Transform a method definition into a function definition as follows:
6708 - synthesize the first two arguments, "self" and "_cmd". */
6711 start_method_def (method)
6716 /* Required to implement _msgSuper. */
6717 objc_method_context = method;
6718 UOBJC_SUPER_decl = NULL_TREE;
6720 /* Must be called BEFORE start_function. */
6723 /* Generate prototype declarations for arguments..."new-style". */
6725 if (TREE_CODE (objc_method_context) == INSTANCE_METHOD_DECL)
6726 decl_specs = build_tree_list (NULL_TREE, uprivate_record);
6728 /* Really a `struct objc_class *'. However, we allow people to
6729 assign to self, which changes its type midstream. */
6730 decl_specs = build_tree_list (NULL_TREE, objc_object_reference);
6732 push_parm_decl (build_tree_list
6733 (build_tree_list (decl_specs,
6734 build1 (INDIRECT_REF, NULL_TREE, self_id)),
6737 decl_specs = build_tree_list (NULL_TREE,
6738 xref_tag (RECORD_TYPE,
6739 get_identifier (TAG_SELECTOR)));
6740 push_parm_decl (build_tree_list
6741 (build_tree_list (decl_specs,
6742 build1 (INDIRECT_REF, NULL_TREE, ucmd_id)),
6745 /* Generate argument declarations if a keyword_decl. */
6746 if (METHOD_SEL_ARGS (method))
6748 tree arglist = METHOD_SEL_ARGS (method);
6751 tree arg_spec = TREE_PURPOSE (TREE_TYPE (arglist));
6752 tree arg_decl = TREE_VALUE (TREE_TYPE (arglist));
6756 tree last_expr = expr_last (arg_decl);
6758 /* Unite the abstract decl with its name. */
6759 TREE_OPERAND (last_expr, 0) = KEYWORD_ARG_NAME (arglist);
6760 push_parm_decl (build_tree_list
6761 (build_tree_list (arg_spec, arg_decl),
6764 /* Unhook: restore the abstract declarator. */
6765 TREE_OPERAND (last_expr, 0) = NULL_TREE;
6769 push_parm_decl (build_tree_list
6770 (build_tree_list (arg_spec,
6771 KEYWORD_ARG_NAME (arglist)),
6774 arglist = TREE_CHAIN (arglist);
6779 if (METHOD_ADD_ARGS (method) != NULL_TREE
6780 && METHOD_ADD_ARGS (method) != objc_ellipsis_node)
6782 /* We have a variable length selector - in "prototype" format. */
6783 tree akey = TREE_PURPOSE (METHOD_ADD_ARGS (method));
6786 /* This must be done prior to calling pushdecl. pushdecl is
6787 going to change our chain on us. */
6788 tree nextkey = TREE_CHAIN (akey);
6796 warn_with_method (message, mtype, method)
6797 const char *message;
6801 if (!diagnostic_count_diagnostic (global_dc, DK_WARNING))
6804 diagnostic_report_current_function (global_dc);
6806 /* Add a readable method name to the warning. */
6807 warning_with_file_and_line (DECL_SOURCE_FILE (method),
6808 DECL_SOURCE_LINE (method),
6811 gen_method_decl (method, errbuf));
6814 /* Return 1 if METHOD is consistent with PROTO. */
6817 comp_method_with_proto (method, proto)
6820 /* Create a function template node at most once. */
6821 if (!function1_template)
6822 function1_template = make_node (FUNCTION_TYPE);
6824 /* Install argument types - normally set by build_function_type. */
6825 TYPE_ARG_TYPES (function1_template) = get_arg_type_list (proto, METHOD_DEF, 0);
6827 /* install return type */
6828 TREE_TYPE (function1_template) = groktypename (TREE_TYPE (proto));
6830 return comptypes (TREE_TYPE (METHOD_DEFINITION (method)), function1_template);
6833 /* Return 1 if PROTO1 is consistent with PROTO2. */
6836 comp_proto_with_proto (proto0, proto1)
6837 tree proto0, proto1;
6839 /* Create a couple of function_template nodes at most once. */
6840 if (!function1_template)
6841 function1_template = make_node (FUNCTION_TYPE);
6842 if (!function2_template)
6843 function2_template = make_node (FUNCTION_TYPE);
6845 /* Install argument types; normally set by build_function_type. */
6846 TYPE_ARG_TYPES (function1_template) = get_arg_type_list (proto0, METHOD_REF, 0);
6847 TYPE_ARG_TYPES (function2_template) = get_arg_type_list (proto1, METHOD_REF, 0);
6849 /* Install return type. */
6850 TREE_TYPE (function1_template) = groktypename (TREE_TYPE (proto0));
6851 TREE_TYPE (function2_template) = groktypename (TREE_TYPE (proto1));
6853 return comptypes (function1_template, function2_template);
6856 /* - Generate an identifier for the function. the format is "_n_cls",
6857 where 1 <= n <= nMethods, and cls is the name the implementation we
6859 - Install the return type from the method declaration.
6860 - If we have a prototype, check for type consistency. */
6863 really_start_method (method, parmlist)
6864 tree method, parmlist;
6866 tree sc_spec, ret_spec, ret_decl, decl_specs;
6867 tree method_decl, method_id;
6868 const char *sel_name, *class_name, *cat_name;
6871 /* Synth the storage class & assemble the return type. */
6872 sc_spec = tree_cons (NULL_TREE, ridpointers[(int) RID_STATIC], NULL_TREE);
6873 ret_spec = TREE_PURPOSE (TREE_TYPE (method));
6874 decl_specs = chainon (sc_spec, ret_spec);
6876 sel_name = IDENTIFIER_POINTER (METHOD_SEL_NAME (method));
6877 class_name = IDENTIFIER_POINTER (CLASS_NAME (objc_implementation_context));
6878 cat_name = ((TREE_CODE (objc_implementation_context)
6879 == CLASS_IMPLEMENTATION_TYPE)
6881 : IDENTIFIER_POINTER (CLASS_SUPER_NAME (objc_implementation_context)));
6884 /* Make sure this is big enough for any plausible method label. */
6885 buf = (char *) alloca (50 + strlen (sel_name) + strlen (class_name)
6886 + (cat_name ? strlen (cat_name) : 0));
6888 OBJC_GEN_METHOD_LABEL (buf, TREE_CODE (method) == INSTANCE_METHOD_DECL,
6889 class_name, cat_name, sel_name, method_slot);
6891 method_id = get_identifier (buf);
6893 method_decl = build_nt (CALL_EXPR, method_id, parmlist, NULL_TREE);
6895 /* Check the declarator portion of the return type for the method. */
6896 if ((ret_decl = TREE_VALUE (TREE_TYPE (method))))
6898 /* Unite the complex decl (specified in the abstract decl) with the
6899 function decl just synthesized..(int *), (int (*)()), (int (*)[]). */
6900 tree save_expr = expr_last (ret_decl);
6902 TREE_OPERAND (save_expr, 0) = method_decl;
6903 method_decl = ret_decl;
6905 /* Fool the parser into thinking it is starting a function. */
6906 start_function (decl_specs, method_decl, NULL_TREE);
6908 /* Unhook: this has the effect of restoring the abstract declarator. */
6909 TREE_OPERAND (save_expr, 0) = NULL_TREE;
6914 TREE_VALUE (TREE_TYPE (method)) = method_decl;
6916 /* Fool the parser into thinking it is starting a function. */
6917 start_function (decl_specs, method_decl, NULL_TREE);
6919 /* Unhook: this has the effect of restoring the abstract declarator. */
6920 TREE_VALUE (TREE_TYPE (method)) = NULL_TREE;
6923 METHOD_DEFINITION (method) = current_function_decl;
6925 /* Check consistency...start_function, pushdecl, duplicate_decls. */
6927 if (implementation_template != objc_implementation_context)
6931 if (TREE_CODE (method) == INSTANCE_METHOD_DECL)
6932 proto = lookup_instance_method_static (implementation_template,
6933 METHOD_SEL_NAME (method));
6935 proto = lookup_class_method_static (implementation_template,
6936 METHOD_SEL_NAME (method));
6938 if (proto && ! comp_method_with_proto (method, proto))
6940 char type = (TREE_CODE (method) == INSTANCE_METHOD_DECL ? '-' : '+');
6942 warn_with_method ("conflicting types for", type, method);
6943 warn_with_method ("previous declaration of", type, proto);
6948 /* The following routine is always called...this "architecture" is to
6949 accommodate "old-style" variable length selectors.
6951 - a:a b:b // prototype ; id c; id d; // old-style. */
6954 continue_method_def ()
6958 if (METHOD_ADD_ARGS (objc_method_context) == objc_ellipsis_node)
6959 /* We have a `, ...' immediately following the selector. */
6960 parmlist = get_parm_info (0);
6962 parmlist = get_parm_info (1); /* place a `void_at_end' */
6964 /* Set self_decl from the first argument...this global is used by
6965 build_ivar_reference calling build_indirect_ref. */
6966 self_decl = TREE_PURPOSE (parmlist);
6969 really_start_method (objc_method_context, parmlist);
6970 store_parm_decls ();
6973 /* Called by the parser, from the `pushlevel' production. */
6978 if (!UOBJC_SUPER_decl)
6980 UOBJC_SUPER_decl = start_decl (get_identifier (UTAG_SUPER),
6981 build_tree_list (NULL_TREE,
6982 objc_super_template),
6985 finish_decl (UOBJC_SUPER_decl, NULL_TREE, NULL_TREE);
6987 /* This prevents `unused variable' warnings when compiling with -Wall. */
6988 TREE_USED (UOBJC_SUPER_decl) = 1;
6989 DECL_ARTIFICIAL (UOBJC_SUPER_decl) = 1;
6993 /* _n_Method (id self, SEL sel, ...)
6995 struct objc_super _S;
6996 _msgSuper ((_S.self = self, _S.class = _cls, &_S), ...);
7000 get_super_receiver ()
7002 if (objc_method_context)
7004 tree super_expr, super_expr_list;
7006 /* Set receiver to self. */
7007 super_expr = build_component_ref (UOBJC_SUPER_decl, self_id);
7008 super_expr = build_modify_expr (super_expr, NOP_EXPR, self_decl);
7009 super_expr_list = build_tree_list (NULL_TREE, super_expr);
7011 /* Set class to begin searching. */
7012 super_expr = build_component_ref (UOBJC_SUPER_decl,
7013 get_identifier ("class"));
7015 if (TREE_CODE (objc_implementation_context) == CLASS_IMPLEMENTATION_TYPE)
7017 /* [_cls, __cls]Super are "pre-built" in
7018 synth_forward_declarations. */
7020 super_expr = build_modify_expr (super_expr, NOP_EXPR,
7021 ((TREE_CODE (objc_method_context)
7022 == INSTANCE_METHOD_DECL)
7024 : uucls_super_ref));
7028 /* We have a category. */
7030 tree super_name = CLASS_SUPER_NAME (implementation_template);
7033 /* Barf if super used in a category of Object. */
7036 error ("no super class declared in interface for `%s'",
7037 IDENTIFIER_POINTER (CLASS_NAME (implementation_template)));
7038 return error_mark_node;
7041 if (flag_next_runtime)
7043 super_class = get_class_reference (super_name);
7044 if (TREE_CODE (objc_method_context) == CLASS_METHOD_DECL)
7046 = build_component_ref (build_indirect_ref (super_class, "->"),
7047 get_identifier ("isa"));
7051 add_class_reference (super_name);
7052 super_class = (TREE_CODE (objc_method_context) == INSTANCE_METHOD_DECL
7053 ? objc_get_class_decl : objc_get_meta_class_decl);
7054 assemble_external (super_class);
7056 = build_function_call
7060 my_build_string (IDENTIFIER_LENGTH (super_name) + 1,
7061 IDENTIFIER_POINTER (super_name))));
7064 TREE_TYPE (super_class) = TREE_TYPE (ucls_super_ref);
7065 super_expr = build_modify_expr (super_expr, NOP_EXPR, super_class);
7068 chainon (super_expr_list, build_tree_list (NULL_TREE, super_expr));
7070 super_expr = build_unary_op (ADDR_EXPR, UOBJC_SUPER_decl, 0);
7071 chainon (super_expr_list, build_tree_list (NULL_TREE, super_expr));
7073 return build_compound_expr (super_expr_list);
7077 error ("[super ...] must appear in a method context");
7078 return error_mark_node;
7083 encode_method_def (func_decl)
7088 HOST_WIDE_INT max_parm_end = 0;
7093 encode_type (TREE_TYPE (TREE_TYPE (func_decl)),
7094 obstack_object_size (&util_obstack),
7095 OBJC_ENCODE_INLINE_DEFS);
7098 for (parms = DECL_ARGUMENTS (func_decl); parms;
7099 parms = TREE_CHAIN (parms))
7101 HOST_WIDE_INT parm_end = (forwarding_offset (parms)
7102 + int_size_in_bytes (TREE_TYPE (parms)));
7104 if (! offset_is_register && parm_end > max_parm_end)
7105 max_parm_end = parm_end;
7108 stack_size = max_parm_end - OBJC_FORWARDING_MIN_OFFSET;
7110 sprintf (buffer, "%d", stack_size);
7111 obstack_grow (&util_obstack, buffer, strlen (buffer));
7113 /* Argument types. */
7114 for (parms = DECL_ARGUMENTS (func_decl); parms;
7115 parms = TREE_CHAIN (parms))
7118 encode_type (TREE_TYPE (parms),
7119 obstack_object_size (&util_obstack),
7120 OBJC_ENCODE_INLINE_DEFS);
7122 /* Compute offset. */
7123 sprintf (buffer, "%d", forwarding_offset (parms));
7125 /* Indicate register. */
7126 if (offset_is_register)
7127 obstack_1grow (&util_obstack, '+');
7129 obstack_grow (&util_obstack, buffer, strlen (buffer));
7132 /* Null terminate string. */
7133 obstack_1grow (&util_obstack, 0);
7134 result = get_identifier (obstack_finish (&util_obstack));
7135 obstack_free (&util_obstack, util_firstobj);
7140 objc_expand_function_end ()
7142 METHOD_ENCODING (objc_method_context) = encode_method_def (current_function_decl);
7146 finish_method_def ()
7148 lang_expand_function_end = objc_expand_function_end;
7149 finish_function (0, 1);
7150 lang_expand_function_end = NULL;
7152 /* Required to implement _msgSuper. This must be done AFTER finish_function,
7153 since the optimizer may find "may be used before set" errors. */
7154 objc_method_context = NULL_TREE;
7159 lang_report_error_function (decl)
7162 if (objc_method_context)
7164 fprintf (stderr, "In method `%s'\n",
7165 IDENTIFIER_POINTER (METHOD_SEL_NAME (objc_method_context)));
7175 is_complex_decl (type)
7178 return (TREE_CODE (type) == ARRAY_TYPE
7179 || TREE_CODE (type) == FUNCTION_TYPE
7180 || (TREE_CODE (type) == POINTER_TYPE && ! IS_ID (type)));
7184 /* Code to convert a decl node into text for a declaration in C. */
7186 static char tmpbuf[256];
7189 adorn_decl (decl, str)
7193 enum tree_code code = TREE_CODE (decl);
7195 if (code == ARRAY_REF)
7197 tree an_int_cst = TREE_OPERAND (decl, 1);
7199 if (an_int_cst && TREE_CODE (an_int_cst) == INTEGER_CST)
7200 sprintf (str + strlen (str), "[%ld]",
7201 (long) TREE_INT_CST_LOW (an_int_cst));
7206 else if (code == ARRAY_TYPE)
7208 tree an_int_cst = TYPE_SIZE (decl);
7209 tree array_of = TREE_TYPE (decl);
7211 if (an_int_cst && TREE_CODE (an_int_cst) == INTEGER_TYPE)
7212 sprintf (str + strlen (str), "[%ld]",
7213 (long) (TREE_INT_CST_LOW (an_int_cst)
7214 / TREE_INT_CST_LOW (TYPE_SIZE (array_of))));
7219 else if (code == CALL_EXPR)
7221 tree chain = TREE_PURPOSE (TREE_OPERAND (decl, 1));
7226 gen_declaration_1 (chain, str);
7227 chain = TREE_CHAIN (chain);
7234 else if (code == FUNCTION_TYPE)
7236 tree chain = TYPE_ARG_TYPES (decl);
7239 while (chain && TREE_VALUE (chain) != void_type_node)
7241 gen_declaration_1 (TREE_VALUE (chain), str);
7242 chain = TREE_CHAIN (chain);
7243 if (chain && TREE_VALUE (chain) != void_type_node)
7249 else if (code == INDIRECT_REF)
7251 strcpy (tmpbuf, "*");
7252 if (TREE_TYPE (decl) && TREE_CODE (TREE_TYPE (decl)) == TREE_LIST)
7256 for (chain = nreverse (copy_list (TREE_TYPE (decl)));
7258 chain = TREE_CHAIN (chain))
7260 if (TREE_CODE (TREE_VALUE (chain)) == IDENTIFIER_NODE)
7262 strcat (tmpbuf, " ");
7263 strcat (tmpbuf, IDENTIFIER_POINTER (TREE_VALUE (chain)));
7267 strcat (tmpbuf, " ");
7269 strcat (tmpbuf, str);
7270 strcpy (str, tmpbuf);
7273 else if (code == POINTER_TYPE)
7275 strcpy (tmpbuf, "*");
7276 if (TREE_READONLY (decl) || TYPE_VOLATILE (decl))
7278 if (TREE_READONLY (decl))
7279 strcat (tmpbuf, " const");
7280 if (TYPE_VOLATILE (decl))
7281 strcat (tmpbuf, " volatile");
7283 strcat (tmpbuf, " ");
7285 strcat (tmpbuf, str);
7286 strcpy (str, tmpbuf);
7291 gen_declarator (decl, buf, name)
7298 enum tree_code code = TREE_CODE (decl);
7308 op = TREE_OPERAND (decl, 0);
7310 /* We have a pointer to a function or array...(*)(), (*)[] */
7311 if ((code == ARRAY_REF || code == CALL_EXPR)
7312 && op && TREE_CODE (op) == INDIRECT_REF)
7315 str = gen_declarator (op, buf, name);
7319 strcpy (tmpbuf, "(");
7320 strcat (tmpbuf, str);
7321 strcat (tmpbuf, ")");
7322 strcpy (str, tmpbuf);
7325 adorn_decl (decl, str);
7334 /* This clause is done iteratively rather than recursively. */
7337 op = (is_complex_decl (TREE_TYPE (decl))
7338 ? TREE_TYPE (decl) : NULL_TREE);
7340 adorn_decl (decl, str);
7342 /* We have a pointer to a function or array...(*)(), (*)[] */
7343 if (code == POINTER_TYPE
7344 && op && (TREE_CODE (op) == FUNCTION_TYPE
7345 || TREE_CODE (op) == ARRAY_TYPE))
7347 strcpy (tmpbuf, "(");
7348 strcat (tmpbuf, str);
7349 strcat (tmpbuf, ")");
7350 strcpy (str, tmpbuf);
7353 decl = (is_complex_decl (TREE_TYPE (decl))
7354 ? TREE_TYPE (decl) : NULL_TREE);
7357 while (decl && (code = TREE_CODE (decl)))
7362 case IDENTIFIER_NODE:
7363 /* Will only happen if we are processing a "raw" expr-decl. */
7364 strcpy (buf, IDENTIFIER_POINTER (decl));
7375 /* We have an abstract declarator or a _DECL node. */
7383 gen_declspecs (declspecs, buf, raw)
7392 for (chain = nreverse (copy_list (declspecs));
7393 chain; chain = TREE_CHAIN (chain))
7395 tree aspec = TREE_VALUE (chain);
7397 if (TREE_CODE (aspec) == IDENTIFIER_NODE)
7398 strcat (buf, IDENTIFIER_POINTER (aspec));
7399 else if (TREE_CODE (aspec) == RECORD_TYPE)
7401 if (TYPE_NAME (aspec))
7403 tree protocol_list = TYPE_PROTOCOL_LIST (aspec);
7405 if (! TREE_STATIC_TEMPLATE (aspec))
7406 strcat (buf, "struct ");
7407 strcat (buf, IDENTIFIER_POINTER (TYPE_NAME (aspec)));
7412 tree chain = protocol_list;
7419 (PROTOCOL_NAME (TREE_VALUE (chain))));
7420 chain = TREE_CHAIN (chain);
7429 strcat (buf, "untagged struct");
7432 else if (TREE_CODE (aspec) == UNION_TYPE)
7434 if (TYPE_NAME (aspec))
7436 if (! TREE_STATIC_TEMPLATE (aspec))
7437 strcat (buf, "union ");
7438 strcat (buf, IDENTIFIER_POINTER (TYPE_NAME (aspec)));
7441 strcat (buf, "untagged union");
7444 else if (TREE_CODE (aspec) == ENUMERAL_TYPE)
7446 if (TYPE_NAME (aspec))
7448 if (! TREE_STATIC_TEMPLATE (aspec))
7449 strcat (buf, "enum ");
7450 strcat (buf, IDENTIFIER_POINTER (TYPE_NAME (aspec)));
7453 strcat (buf, "untagged enum");
7456 else if (TREE_CODE (aspec) == TYPE_DECL && DECL_NAME (aspec))
7457 strcat (buf, IDENTIFIER_POINTER (DECL_NAME (aspec)));
7459 else if (IS_ID (aspec))
7461 tree protocol_list = TYPE_PROTOCOL_LIST (aspec);
7466 tree chain = protocol_list;
7473 (PROTOCOL_NAME (TREE_VALUE (chain))));
7474 chain = TREE_CHAIN (chain);
7481 if (TREE_CHAIN (chain))
7487 /* Type qualifiers. */
7488 if (TREE_READONLY (declspecs))
7489 strcat (buf, "const ");
7490 if (TYPE_VOLATILE (declspecs))
7491 strcat (buf, "volatile ");
7493 switch (TREE_CODE (declspecs))
7495 /* Type specifiers. */
7498 declspecs = TYPE_MAIN_VARIANT (declspecs);
7500 /* Signed integer types. */
7502 if (declspecs == short_integer_type_node)
7503 strcat (buf, "short int ");
7504 else if (declspecs == integer_type_node)
7505 strcat (buf, "int ");
7506 else if (declspecs == long_integer_type_node)
7507 strcat (buf, "long int ");
7508 else if (declspecs == long_long_integer_type_node)
7509 strcat (buf, "long long int ");
7510 else if (declspecs == signed_char_type_node
7511 || declspecs == char_type_node)
7512 strcat (buf, "char ");
7514 /* Unsigned integer types. */
7516 else if (declspecs == short_unsigned_type_node)
7517 strcat (buf, "unsigned short ");
7518 else if (declspecs == unsigned_type_node)
7519 strcat (buf, "unsigned int ");
7520 else if (declspecs == long_unsigned_type_node)
7521 strcat (buf, "unsigned long ");
7522 else if (declspecs == long_long_unsigned_type_node)
7523 strcat (buf, "unsigned long long ");
7524 else if (declspecs == unsigned_char_type_node)
7525 strcat (buf, "unsigned char ");
7529 declspecs = TYPE_MAIN_VARIANT (declspecs);
7531 if (declspecs == float_type_node)
7532 strcat (buf, "float ");
7533 else if (declspecs == double_type_node)
7534 strcat (buf, "double ");
7535 else if (declspecs == long_double_type_node)
7536 strcat (buf, "long double ");
7540 if (TYPE_NAME (declspecs)
7541 && TREE_CODE (TYPE_NAME (declspecs)) == IDENTIFIER_NODE)
7543 tree protocol_list = TYPE_PROTOCOL_LIST (declspecs);
7545 if (! TREE_STATIC_TEMPLATE (declspecs))
7546 strcat (buf, "struct ");
7547 strcat (buf, IDENTIFIER_POINTER (TYPE_NAME (declspecs)));
7551 tree chain = protocol_list;
7558 (PROTOCOL_NAME (TREE_VALUE (chain))));
7559 chain = TREE_CHAIN (chain);
7568 strcat (buf, "untagged struct");
7574 if (TYPE_NAME (declspecs)
7575 && TREE_CODE (TYPE_NAME (declspecs)) == IDENTIFIER_NODE)
7577 strcat (buf, "union ");
7578 strcat (buf, IDENTIFIER_POINTER (TYPE_NAME (declspecs)));
7583 strcat (buf, "untagged union ");
7587 if (TYPE_NAME (declspecs)
7588 && TREE_CODE (TYPE_NAME (declspecs)) == IDENTIFIER_NODE)
7590 strcat (buf, "enum ");
7591 strcat (buf, IDENTIFIER_POINTER (TYPE_NAME (declspecs)));
7596 strcat (buf, "untagged enum ");
7600 strcat (buf, "void ");
7605 tree protocol_list = TYPE_PROTOCOL_LIST (declspecs);
7610 tree chain = protocol_list;
7617 (PROTOCOL_NAME (TREE_VALUE (chain))));
7618 chain = TREE_CHAIN (chain);
7634 /* Given a tree node, produce a printable description of it in the given
7635 buffer, overwriting the buffer. */
7638 gen_declaration (atype_or_adecl, buf)
7639 tree atype_or_adecl;
7643 gen_declaration_1 (atype_or_adecl, buf);
7647 /* Given a tree node, append a printable description to the end of the
7651 gen_declaration_1 (atype_or_adecl, buf)
7652 tree atype_or_adecl;
7657 if (TREE_CODE (atype_or_adecl) == TREE_LIST)
7659 tree declspecs; /* "identifier_node", "record_type" */
7660 tree declarator; /* "array_ref", "indirect_ref", "call_expr"... */
7662 /* We have a "raw", abstract declarator (typename). */
7663 declarator = TREE_VALUE (atype_or_adecl);
7664 declspecs = TREE_PURPOSE (atype_or_adecl);
7666 gen_declspecs (declspecs, buf, 1);
7670 strcat (buf, gen_declarator (declarator, declbuf, ""));
7677 tree declspecs; /* "integer_type", "real_type", "record_type"... */
7678 tree declarator; /* "array_type", "function_type", "pointer_type". */
7680 if (TREE_CODE (atype_or_adecl) == FIELD_DECL
7681 || TREE_CODE (atype_or_adecl) == PARM_DECL
7682 || TREE_CODE (atype_or_adecl) == FUNCTION_DECL)
7683 atype = TREE_TYPE (atype_or_adecl);
7685 /* Assume we have a *_type node. */
7686 atype = atype_or_adecl;
7688 if (is_complex_decl (atype))
7692 /* Get the declaration specifier; it is at the end of the list. */
7693 declarator = chain = atype;
7695 chain = TREE_TYPE (chain); /* not TREE_CHAIN (chain); */
7696 while (is_complex_decl (chain));
7703 declarator = NULL_TREE;
7706 gen_declspecs (declspecs, buf, 0);
7708 if (TREE_CODE (atype_or_adecl) == FIELD_DECL
7709 || TREE_CODE (atype_or_adecl) == PARM_DECL
7710 || TREE_CODE (atype_or_adecl) == FUNCTION_DECL)
7712 const char *const decl_name =
7713 (DECL_NAME (atype_or_adecl)
7714 ? IDENTIFIER_POINTER (DECL_NAME (atype_or_adecl)) : "");
7719 strcat (buf, gen_declarator (declarator, declbuf, decl_name));
7722 else if (decl_name[0])
7725 strcat (buf, decl_name);
7728 else if (declarator)
7731 strcat (buf, gen_declarator (declarator, declbuf, ""));
7736 #define RAW_TYPESPEC(meth) (TREE_VALUE (TREE_PURPOSE (TREE_TYPE (meth))))
7738 /* Given a method tree, put a printable description into the given
7739 buffer (overwriting) and return a pointer to the buffer. */
7742 gen_method_decl (method, buf)
7749 if (RAW_TYPESPEC (method) != objc_object_reference)
7752 gen_declaration_1 (TREE_TYPE (method), buf);
7756 chain = METHOD_SEL_ARGS (method);
7759 /* We have a chain of keyword_decls. */
7762 if (KEYWORD_KEY_NAME (chain))
7763 strcat (buf, IDENTIFIER_POINTER (KEYWORD_KEY_NAME (chain)));
7766 if (RAW_TYPESPEC (chain) != objc_object_reference)
7769 gen_declaration_1 (TREE_TYPE (chain), buf);
7773 strcat (buf, IDENTIFIER_POINTER (KEYWORD_ARG_NAME (chain)));
7774 if ((chain = TREE_CHAIN (chain)))
7779 if (METHOD_ADD_ARGS (method) == objc_ellipsis_node)
7780 strcat (buf, ", ...");
7781 else if (METHOD_ADD_ARGS (method))
7783 /* We have a tree list node as generate by get_parm_info. */
7784 chain = TREE_PURPOSE (METHOD_ADD_ARGS (method));
7786 /* Know we have a chain of parm_decls. */
7790 gen_declaration_1 (chain, buf);
7791 chain = TREE_CHAIN (chain);
7797 /* We have a unary selector. */
7798 strcat (buf, IDENTIFIER_POINTER (METHOD_SEL_NAME (method)));
7806 dump_interface (fp, chain)
7810 char *buf = (char *) xmalloc (256);
7811 const char *my_name = IDENTIFIER_POINTER (CLASS_NAME (chain));
7812 tree ivar_decls = CLASS_RAW_IVARS (chain);
7813 tree nst_methods = CLASS_NST_METHODS (chain);
7814 tree cls_methods = CLASS_CLS_METHODS (chain);
7816 fprintf (fp, "\n@interface %s", my_name);
7818 if (CLASS_SUPER_NAME (chain))
7820 const char *super_name = IDENTIFIER_POINTER (CLASS_SUPER_NAME (chain));
7821 fprintf (fp, " : %s\n", super_name);
7828 fprintf (fp, "{\n");
7831 fprintf (fp, "\t%s;\n", gen_declaration (ivar_decls, buf));
7832 ivar_decls = TREE_CHAIN (ivar_decls);
7835 fprintf (fp, "}\n");
7840 fprintf (fp, "- %s;\n", gen_method_decl (nst_methods, buf));
7841 nst_methods = TREE_CHAIN (nst_methods);
7846 fprintf (fp, "+ %s;\n", gen_method_decl (cls_methods, buf));
7847 cls_methods = TREE_CHAIN (cls_methods);
7849 fprintf (fp, "\n@end");
7852 /* Demangle function for Objective-C */
7854 objc_demangle (mangled)
7855 const char *mangled;
7857 char *demangled, *cp;
7859 if (mangled[0] == '_' &&
7860 (mangled[1] == 'i' || mangled[1] == 'c') &&
7863 cp = demangled = xmalloc(strlen(mangled) + 2);
7864 if (mangled[1] == 'i')
7865 *cp++ = '-'; /* for instance method */
7867 *cp++ = '+'; /* for class method */
7868 *cp++ = '['; /* opening left brace */
7869 strcpy(cp, mangled+3); /* tack on the rest of the mangled name */
7870 while (*cp && *cp == '_')
7871 cp++; /* skip any initial underbars in class name */
7872 cp = strchr(cp, '_'); /* find first non-initial underbar */
7875 free(demangled); /* not mangled name */
7878 if (cp[1] == '_') /* easy case: no category name */
7880 *cp++ = ' '; /* replace two '_' with one ' ' */
7881 strcpy(cp, mangled + (cp - demangled) + 2);
7885 *cp++ = '('; /* less easy case: category name */
7886 cp = strchr(cp, '_');
7889 free(demangled); /* not mangled name */
7893 *cp++ = ' '; /* overwriting 1st char of method name... */
7894 strcpy(cp, mangled + (cp - demangled)); /* get it back */
7896 while (*cp && *cp == '_')
7897 cp++; /* skip any initial underbars in method name */
7900 *cp = ':'; /* replace remaining '_' with ':' */
7901 *cp++ = ']'; /* closing right brace */
7902 *cp++ = 0; /* string terminator */
7906 return mangled; /* not an objc mangled name */
7910 objc_printable_name (decl, kind)
7912 int kind ATTRIBUTE_UNUSED;
7914 return objc_demangle (IDENTIFIER_POINTER (DECL_NAME (decl)));
7920 gcc_obstack_init (&util_obstack);
7921 util_firstobj = (char *) obstack_finish (&util_obstack);
7923 errbuf = (char *) xmalloc (BUFSIZE);
7925 synth_module_prologue ();
7931 struct imp_entry *impent;
7933 /* The internally generated initializers appear to have missing braces.
7934 Don't warn about this. */
7935 int save_warn_missing_braces = warn_missing_braces;
7936 warn_missing_braces = 0;
7938 /* A missing @end may not be detected by the parser. */
7939 if (objc_implementation_context)
7941 warning ("`@end' missing in implementation context");
7942 finish_class (objc_implementation_context);
7943 objc_ivar_chain = NULL_TREE;
7944 objc_implementation_context = NULL_TREE;
7947 generate_forward_declaration_to_string_table ();
7949 #ifdef OBJC_PROLOGUE
7953 /* Process the static instances here because initialization of objc_symtab
7955 if (objc_static_instances)
7956 generate_static_references ();
7958 if (imp_list || class_names_chain
7959 || meth_var_names_chain || meth_var_types_chain || sel_ref_chain)
7960 generate_objc_symtab_decl ();
7962 for (impent = imp_list; impent; impent = impent->next)
7964 objc_implementation_context = impent->imp_context;
7965 implementation_template = impent->imp_template;
7967 UOBJC_CLASS_decl = impent->class_decl;
7968 UOBJC_METACLASS_decl = impent->meta_decl;
7970 if (TREE_CODE (objc_implementation_context) == CLASS_IMPLEMENTATION_TYPE)
7972 /* all of the following reference the string pool... */
7973 generate_ivar_lists ();
7974 generate_dispatch_tables ();
7975 generate_shared_structures ();
7979 generate_dispatch_tables ();
7980 generate_category (objc_implementation_context);
7984 /* If we are using an array of selectors, we must always
7985 finish up the array decl even if no selectors were used. */
7986 if (! flag_next_runtime || sel_ref_chain)
7987 build_selector_translation_table ();
7990 generate_protocols ();
7992 if (objc_implementation_context || class_names_chain || objc_static_instances
7993 || meth_var_names_chain || meth_var_types_chain || sel_ref_chain)
7995 /* Arrange for ObjC data structures to be initialized at run time. */
7996 rtx init_sym = build_module_descriptor ();
7997 if (init_sym && targetm.have_ctors_dtors)
7998 (* targetm.asm_out.constructor) (init_sym, DEFAULT_INIT_PRIORITY);
8001 /* Dump the class references. This forces the appropriate classes
8002 to be linked into the executable image, preserving unix archive
8003 semantics. This can be removed when we move to a more dynamically
8004 linked environment. */
8006 for (chain = cls_ref_chain; chain; chain = TREE_CHAIN (chain))
8008 handle_class_ref (chain);
8009 if (TREE_PURPOSE (chain))
8010 generate_classref_translation_entry (chain);
8013 for (impent = imp_list; impent; impent = impent->next)
8014 handle_impent (impent);
8016 /* Dump the string table last. */
8018 generate_strings ();
8020 if (flag_gen_declaration)
8022 add_class (objc_implementation_context);
8023 dump_interface (gen_declaration_file, objc_implementation_context);
8031 /* Run through the selector hash tables and print a warning for any
8032 selector which has multiple methods. */
8034 for (slot = 0; slot < SIZEHASHTABLE; slot++)
8035 for (hsh = cls_method_hash_list[slot]; hsh; hsh = hsh->next)
8038 tree meth = hsh->key;
8039 char type = (TREE_CODE (meth) == INSTANCE_METHOD_DECL
8043 warning ("potential selector conflict for method `%s'",
8044 IDENTIFIER_POINTER (METHOD_SEL_NAME (meth)));
8045 warn_with_method ("found", type, meth);
8046 for (loop = hsh->list; loop; loop = loop->next)
8047 warn_with_method ("found", type, loop->value);
8050 for (slot = 0; slot < SIZEHASHTABLE; slot++)
8051 for (hsh = nst_method_hash_list[slot]; hsh; hsh = hsh->next)
8054 tree meth = hsh->key;
8055 char type = (TREE_CODE (meth) == INSTANCE_METHOD_DECL
8059 warning ("potential selector conflict for method `%s'",
8060 IDENTIFIER_POINTER (METHOD_SEL_NAME (meth)));
8061 warn_with_method ("found", type, meth);
8062 for (loop = hsh->list; loop; loop = loop->next)
8063 warn_with_method ("found", type, loop->value);
8067 warn_missing_braces = save_warn_missing_braces;
8070 /* Subroutines of finish_objc. */
8073 generate_classref_translation_entry (chain)
8076 tree expr, name, decl_specs, decl, sc_spec;
8079 type = TREE_TYPE (TREE_PURPOSE (chain));
8081 expr = add_objc_string (TREE_VALUE (chain), class_names);
8082 expr = build_c_cast (type, expr); /* cast! */
8084 name = DECL_NAME (TREE_PURPOSE (chain));
8086 sc_spec = build_tree_list (NULL_TREE, ridpointers[(int) RID_STATIC]);
8088 /* static struct objc_class * _OBJC_CLASS_REFERENCES_n = ...; */
8089 decl_specs = tree_cons (NULL_TREE, type, sc_spec);
8091 /* The decl that is returned from start_decl is the one that we
8092 forward declared in build_class_reference. */
8093 decl = start_decl (name, decl_specs, 1, NULL_TREE);
8094 DECL_CONTEXT (decl) = NULL_TREE;
8095 finish_decl (decl, expr, NULL_TREE);
8100 handle_class_ref (chain)
8103 const char *name = IDENTIFIER_POINTER (TREE_VALUE (chain));
8104 char *string = (char *) alloca (strlen (name) + 30);
8108 sprintf (string, "%sobjc_class_name_%s",
8109 (flag_next_runtime ? "." : "__"), name);
8111 #ifdef ASM_DECLARE_UNRESOLVED_REFERENCE
8112 if (flag_next_runtime)
8114 ASM_DECLARE_UNRESOLVED_REFERENCE (asm_out_file, string);
8119 /* Make a decl for this name, so we can use its address in a tree. */
8120 decl = build_decl (VAR_DECL, get_identifier (string), char_type_node);
8121 DECL_EXTERNAL (decl) = 1;
8122 TREE_PUBLIC (decl) = 1;
8125 rest_of_decl_compilation (decl, 0, 0, 0);
8127 /* Make a decl for the address. */
8128 sprintf (string, "%sobjc_class_ref_%s",
8129 (flag_next_runtime ? "." : "__"), name);
8130 exp = build1 (ADDR_EXPR, string_type_node, decl);
8131 decl = build_decl (VAR_DECL, get_identifier (string), string_type_node);
8132 DECL_INITIAL (decl) = exp;
8133 TREE_STATIC (decl) = 1;
8134 TREE_USED (decl) = 1;
8137 rest_of_decl_compilation (decl, 0, 0, 0);
8141 handle_impent (impent)
8142 struct imp_entry *impent;
8146 objc_implementation_context = impent->imp_context;
8147 implementation_template = impent->imp_template;
8149 if (TREE_CODE (impent->imp_context) == CLASS_IMPLEMENTATION_TYPE)
8151 const char *const class_name =
8152 IDENTIFIER_POINTER (CLASS_NAME (impent->imp_context));
8154 string = (char *) alloca (strlen (class_name) + 30);
8156 sprintf (string, "%sobjc_class_name_%s",
8157 (flag_next_runtime ? "." : "__"), class_name);
8159 else if (TREE_CODE (impent->imp_context) == CATEGORY_IMPLEMENTATION_TYPE)
8161 const char *const class_name =
8162 IDENTIFIER_POINTER (CLASS_NAME (impent->imp_context));
8163 const char *const class_super_name =
8164 IDENTIFIER_POINTER (CLASS_SUPER_NAME (impent->imp_context));
8166 string = (char *) alloca (strlen (class_name)
8167 + strlen (class_super_name) + 30);
8169 /* Do the same for categories. Even though no references to
8170 these symbols are generated automatically by the compiler, it
8171 gives you a handle to pull them into an archive by hand. */
8172 sprintf (string, "*%sobjc_category_name_%s_%s",
8173 (flag_next_runtime ? "." : "__"), class_name, class_super_name);
8178 #ifdef ASM_DECLARE_CLASS_REFERENCE
8179 if (flag_next_runtime)
8181 ASM_DECLARE_CLASS_REFERENCE (asm_out_file, string);
8189 init = build_int_2 (0, 0);
8190 TREE_TYPE (init) = c_common_type_for_size (BITS_PER_WORD, 1);
8191 decl = build_decl (VAR_DECL, get_identifier (string), TREE_TYPE (init));
8192 TREE_PUBLIC (decl) = 1;
8193 TREE_READONLY (decl) = 1;
8194 TREE_USED (decl) = 1;
8195 TREE_CONSTANT (decl) = 1;
8196 DECL_CONTEXT (decl) = 0;
8197 DECL_ARTIFICIAL (decl) = 1;
8198 DECL_INITIAL (decl) = init;
8199 assemble_variable (decl, 1, 0, 0);
8203 /* Look up ID as an instance variable. */
8205 lookup_objc_ivar (id)
8210 if (objc_method_context && !strcmp (IDENTIFIER_POINTER (id), "super"))
8211 /* We have a message to super. */
8212 return get_super_receiver ();
8213 else if (objc_method_context && (decl = is_ivar (objc_ivar_chain, id)))
8215 if (is_private (decl))
8216 return error_mark_node;
8218 return build_ivar_reference (id);
8224 #include "gtype-objc.h"