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));
131 static tree build_ivar_chain PARAMS ((tree, int));
133 static tree objc_add_static_instance PARAMS ((tree, tree));
135 static tree build_ivar_template PARAMS ((void));
136 static tree build_method_template PARAMS ((void));
137 static tree build_private_template PARAMS ((tree));
138 static void build_class_template PARAMS ((void));
139 static void build_selector_template PARAMS ((void));
140 static void build_category_template PARAMS ((void));
141 static tree build_super_template PARAMS ((void));
142 static tree build_category_initializer PARAMS ((tree, tree, tree,
144 static tree build_protocol_initializer PARAMS ((tree, tree, tree,
147 static void synth_forward_declarations PARAMS ((void));
148 static void generate_ivar_lists PARAMS ((void));
149 static void generate_dispatch_tables PARAMS ((void));
150 static void generate_shared_structures PARAMS ((void));
151 static tree generate_protocol_list PARAMS ((tree));
152 static void generate_forward_declaration_to_string_table PARAMS ((void));
153 static void build_protocol_reference PARAMS ((tree));
155 static tree build_keyword_selector PARAMS ((tree));
156 static tree synth_id_with_class_suffix PARAMS ((const char *, tree));
158 static void generate_static_references PARAMS ((void));
159 static int check_methods_accessible PARAMS ((tree, tree,
161 static void encode_aggregate_within PARAMS ((tree, int, int,
163 static const char *objc_demangle PARAMS ((const char *));
164 static void objc_expand_function_end PARAMS ((void));
166 /* Hash tables to manage the global pool of method prototypes. */
168 hash *nst_method_hash_list = 0;
169 hash *cls_method_hash_list = 0;
171 static size_t hash_func PARAMS ((tree));
172 static void hash_init PARAMS ((void));
173 static void hash_enter PARAMS ((hash *, tree));
174 static hash hash_lookup PARAMS ((hash *, tree));
175 static void hash_add_attr PARAMS ((hash, tree));
176 static tree lookup_method PARAMS ((tree, tree));
177 static tree lookup_instance_method_static PARAMS ((tree, tree));
178 static tree lookup_class_method_static PARAMS ((tree, tree));
179 static tree add_class PARAMS ((tree));
180 static void add_category PARAMS ((tree, tree));
184 class_names, /* class, category, protocol, module names */
185 meth_var_names, /* method and variable names */
186 meth_var_types /* method and variable type descriptors */
189 static tree add_objc_string PARAMS ((tree,
190 enum string_section));
191 static tree get_objc_string_decl PARAMS ((tree,
192 enum string_section));
193 static tree build_objc_string_decl PARAMS ((enum string_section));
194 static tree build_selector_reference_decl PARAMS ((void));
196 /* Protocol additions. */
198 static tree add_protocol PARAMS ((tree));
199 static tree lookup_protocol PARAMS ((tree));
200 static void check_protocol_recursively PARAMS ((tree, tree));
201 static tree lookup_and_install_protocols PARAMS ((tree));
205 static void encode_type_qualifiers PARAMS ((tree));
206 static void encode_pointer PARAMS ((tree, int, int));
207 static void encode_array PARAMS ((tree, int, int));
208 static void encode_aggregate PARAMS ((tree, int, int));
209 static void encode_bitfield PARAMS ((int));
210 static void encode_type PARAMS ((tree, int, int));
211 static void encode_field_decl PARAMS ((tree, int, int));
213 static void really_start_method PARAMS ((tree, tree));
214 static int comp_method_with_proto PARAMS ((tree, tree));
215 static int comp_proto_with_proto PARAMS ((tree, tree));
216 static tree get_arg_type_list PARAMS ((tree, int, int));
217 static tree expr_last PARAMS ((tree));
219 /* Utilities for debugging and error diagnostics. */
221 static void warn_with_method PARAMS ((const char *, int, tree));
222 static void error_with_ivar PARAMS ((const char *, tree, tree));
223 static char *gen_method_decl PARAMS ((tree, char *));
224 static char *gen_declaration PARAMS ((tree, char *));
225 static void gen_declaration_1 PARAMS ((tree, char *));
226 static char *gen_declarator PARAMS ((tree, char *,
228 static int is_complex_decl PARAMS ((tree));
229 static void adorn_decl PARAMS ((tree, char *));
230 static void dump_interface PARAMS ((FILE *, tree));
232 /* Everything else. */
234 static tree define_decl PARAMS ((tree, tree));
235 static tree lookup_method_in_protocol_list PARAMS ((tree, tree, int));
236 static tree lookup_protocol_in_reflist PARAMS ((tree, tree));
237 static tree create_builtin_decl PARAMS ((enum tree_code,
238 tree, const char *));
239 static void setup_string_decl PARAMS ((void));
240 static void build_string_class_template PARAMS ((void));
241 static tree my_build_string PARAMS ((int, const char *));
242 static void build_objc_symtab_template PARAMS ((void));
243 static tree init_def_list PARAMS ((tree));
244 static tree init_objc_symtab PARAMS ((tree));
245 static void forward_declare_categories PARAMS ((void));
246 static void generate_objc_symtab_decl PARAMS ((void));
247 static tree build_selector PARAMS ((tree));
248 static tree build_typed_selector_reference PARAMS ((tree, tree));
249 static tree build_selector_reference PARAMS ((tree));
250 static tree build_class_reference_decl PARAMS ((void));
251 static void add_class_reference PARAMS ((tree));
252 static tree objc_copy_list PARAMS ((tree, tree *));
253 static tree build_protocol_template PARAMS ((void));
254 static tree build_descriptor_table_initializer PARAMS ((tree, tree));
255 static tree build_method_prototype_list_template PARAMS ((tree, int));
256 static tree build_method_prototype_template PARAMS ((void));
257 static int forwarding_offset PARAMS ((tree));
258 static tree encode_method_prototype PARAMS ((tree, tree));
259 static tree generate_descriptor_table PARAMS ((tree, const char *,
261 static void generate_method_descriptors PARAMS ((tree));
262 static tree build_tmp_function_decl PARAMS ((void));
263 static void hack_method_prototype PARAMS ((tree, tree));
264 static void generate_protocol_references PARAMS ((tree));
265 static void generate_protocols PARAMS ((void));
266 static void check_ivars PARAMS ((tree, tree));
267 static tree build_ivar_list_template PARAMS ((tree, int));
268 static tree build_method_list_template PARAMS ((tree, int));
269 static tree build_ivar_list_initializer PARAMS ((tree, tree));
270 static tree generate_ivars_list PARAMS ((tree, const char *,
272 static tree build_dispatch_table_initializer PARAMS ((tree, tree));
273 static tree generate_dispatch_table PARAMS ((tree, const char *,
275 static tree build_shared_structure_initializer PARAMS ((tree, tree, tree, tree,
276 tree, int, tree, tree,
278 static void generate_category PARAMS ((tree));
279 static int is_objc_type_qualifier PARAMS ((tree));
280 static tree adjust_type_for_id_default PARAMS ((tree));
281 static tree check_duplicates PARAMS ((hash));
282 static tree receiver_is_class_object PARAMS ((tree));
283 static int check_methods PARAMS ((tree, tree, int));
284 static int conforms_to_protocol PARAMS ((tree, tree));
285 static void check_protocol PARAMS ((tree, const char *,
287 static void check_protocols PARAMS ((tree, const char *,
289 static tree encode_method_def PARAMS ((tree));
290 static void gen_declspecs PARAMS ((tree, char *, int));
291 static void generate_classref_translation_entry PARAMS ((tree));
292 static void handle_class_ref PARAMS ((tree));
293 static void generate_struct_by_value_array PARAMS ((void))
296 /*** Private Interface (data) ***/
298 /* Reserved tag definitions. */
301 #define TAG_OBJECT "objc_object"
302 #define TAG_CLASS "objc_class"
303 #define TAG_SUPER "objc_super"
304 #define TAG_SELECTOR "objc_selector"
306 #define UTAG_CLASS "_objc_class"
307 #define UTAG_IVAR "_objc_ivar"
308 #define UTAG_IVAR_LIST "_objc_ivar_list"
309 #define UTAG_METHOD "_objc_method"
310 #define UTAG_METHOD_LIST "_objc_method_list"
311 #define UTAG_CATEGORY "_objc_category"
312 #define UTAG_MODULE "_objc_module"
313 #define UTAG_SYMTAB "_objc_symtab"
314 #define UTAG_SUPER "_objc_super"
315 #define UTAG_SELECTOR "_objc_selector"
317 #define UTAG_PROTOCOL "_objc_protocol"
318 #define UTAG_METHOD_PROTOTYPE "_objc_method_prototype"
319 #define UTAG_METHOD_PROTOTYPE_LIST "_objc__method_prototype_list"
321 /* Note that the string object global name is only needed for the
323 #define STRING_OBJECT_GLOBAL_NAME "_NSConstantStringClassReference"
325 #define PROTOCOL_OBJECT_CLASS_NAME "Protocol"
327 static const char *constant_string_class_name = NULL;
329 static const char *TAG_GETCLASS;
330 static const char *TAG_GETMETACLASS;
331 static const char *TAG_MSGSEND;
332 static const char *TAG_MSGSENDSUPER;
333 static const char *TAG_EXECCLASS;
334 static const char *default_constant_string_class_name;
336 /* The OCTI_... enumeration itself is in objc/objc-act.h. */
337 tree objc_global_trees[OCTI_MAX];
339 static void handle_impent PARAMS ((struct imp_entry *));
341 struct imp_entry *imp_list = 0;
342 int imp_count = 0; /* `@implementation' */
343 int cat_count = 0; /* `@category' */
345 static int method_slot = 0; /* Used by start_method_def, */
349 static char *errbuf; /* Buffer for error diagnostics */
351 /* Data imported from tree.c. */
353 extern enum debug_info_type write_symbols;
355 /* Data imported from toplev.c. */
357 extern const char *dump_base_name;
359 /* Generate code for GNU or NeXT runtime environment. */
361 #ifdef NEXT_OBJC_RUNTIME
362 int flag_next_runtime = 1;
364 int flag_next_runtime = 0;
367 int flag_typed_selectors;
369 /* Open and close the file for outputting class declarations, if requested. */
371 int flag_gen_declaration = 0;
373 FILE *gen_declaration_file;
375 /* Warn if multiple methods are seen for the same selector, but with
376 different argument types. */
378 int warn_selector = 0;
380 /* Warn if methods required by a protocol are not implemented in the
381 class adopting it. When turned off, methods inherited to that
382 class are also considered implemented */
384 int flag_warn_protocol = 1;
386 /* Tells "encode_pointer/encode_aggregate" whether we are generating
387 type descriptors for instance variables (as opposed to methods).
388 Type descriptors for instance variables contain more information
389 than methods (for static typing and embedded structures). */
391 static int generating_instance_variables = 0;
393 /* Tells the compiler that this is a special run. Do not perform any
394 compiling, instead we are to test some platform dependent features
395 and output a C header file with appropriate definitions. */
397 static int print_struct_values = 0;
399 /* Some platforms pass small structures through registers versus
400 through an invisible pointer. Determine at what size structure is
401 the transition point between the two possibilities. */
404 generate_struct_by_value_array ()
407 tree field_decl, field_decl_chain;
409 int aggregate_in_mem[32];
412 /* Presumably no platform passes 32 byte structures in a register. */
413 for (i = 1; i < 32; i++)
417 /* Create an unnamed struct that has `i' character components */
418 type = start_struct (RECORD_TYPE, NULL_TREE);
420 strcpy (buffer, "c1");
421 field_decl = create_builtin_decl (FIELD_DECL,
424 field_decl_chain = field_decl;
426 for (j = 1; j < i; j++)
428 sprintf (buffer, "c%d", j + 1);
429 field_decl = create_builtin_decl (FIELD_DECL,
432 chainon (field_decl_chain, field_decl);
434 finish_struct (type, field_decl_chain, NULL_TREE);
436 aggregate_in_mem[i] = aggregate_value_p (type);
437 if (!aggregate_in_mem[i])
441 /* We found some structures that are returned in registers instead of memory
442 so output the necessary data. */
445 for (i = 31; i >= 0; i--)
446 if (!aggregate_in_mem[i])
448 printf ("#define OBJC_MAX_STRUCT_BY_VALUE %d\n\n", i);
450 /* The first member of the structure is always 0 because we don't handle
451 structures with 0 members */
452 printf ("static int struct_forward_array[] = {\n 0");
454 for (j = 1; j <= i; j++)
455 printf (", %d", aggregate_in_mem[j]);
464 const char *filename;
466 filename = c_objc_common_init (filename);
467 if (filename == NULL)
470 /* Force the line number back to 0; check_newline will have
471 raised it to 1, which will make the builtin functions appear
472 not to be built in. */
475 /* If gen_declaration desired, open the output file. */
476 if (flag_gen_declaration)
478 register char * const dumpname = concat (dump_base_name, ".decl", NULL);
479 gen_declaration_file = fopen (dumpname, "w");
480 if (gen_declaration_file == 0)
481 fatal_io_error ("can't open %s", dumpname);
485 if (flag_next_runtime)
487 TAG_GETCLASS = "objc_getClass";
488 TAG_GETMETACLASS = "objc_getMetaClass";
489 TAG_MSGSEND = "objc_msgSend";
490 TAG_MSGSENDSUPER = "objc_msgSendSuper";
491 TAG_EXECCLASS = "__objc_execClass";
492 default_constant_string_class_name = "NSConstantString";
496 TAG_GETCLASS = "objc_get_class";
497 TAG_GETMETACLASS = "objc_get_meta_class";
498 TAG_MSGSEND = "objc_msg_lookup";
499 TAG_MSGSENDSUPER = "objc_msg_lookup_super";
500 TAG_EXECCLASS = "__objc_exec_class";
501 default_constant_string_class_name = "NXConstantString";
502 flag_typed_selectors = 1;
505 objc_ellipsis_node = make_node (ERROR_MARK);
509 if (print_struct_values)
510 generate_struct_by_value_array ();
518 c_objc_common_finish_file ();
520 /* Finalize Objective-C runtime data. No need to generate tables
521 and code if only checking syntax. */
522 if (!flag_syntax_only)
525 if (gen_declaration_file)
526 fclose (gen_declaration_file);
530 objc_decode_option (argc, argv)
534 const char *p = argv[0];
536 if (!strcmp (p, "-gen-decls"))
537 flag_gen_declaration = 1;
538 else if (!strcmp (p, "-Wselector"))
540 else if (!strcmp (p, "-Wno-selector"))
542 else if (!strcmp (p, "-Wprotocol"))
543 flag_warn_protocol = 1;
544 else if (!strcmp (p, "-Wno-protocol"))
545 flag_warn_protocol = 0;
546 else if (!strcmp (p, "-fgnu-runtime"))
547 flag_next_runtime = 0;
548 else if (!strcmp (p, "-fno-next-runtime"))
549 flag_next_runtime = 0;
550 else if (!strcmp (p, "-fno-gnu-runtime"))
551 flag_next_runtime = 1;
552 else if (!strcmp (p, "-fnext-runtime"))
553 flag_next_runtime = 1;
554 else if (!strcmp (p, "-print-objc-runtime-info"))
555 print_struct_values = 1;
556 #define CSTSTRCLASS "-fconstant-string-class="
557 else if (!strncmp (p, CSTSTRCLASS, sizeof(CSTSTRCLASS) - 2)) {
558 if (strlen (argv[0]) <= strlen (CSTSTRCLASS))
559 error ("no class name specified as argument to -fconstant-string-class");
560 constant_string_class_name = xstrdup(argv[0] + sizeof(CSTSTRCLASS) - 1);
564 return c_decode_option (argc, argv);
571 define_decl (declarator, declspecs)
575 tree decl = start_decl (declarator, declspecs, 0, NULL_TREE);
576 finish_decl (decl, NULL_TREE, NULL_TREE);
580 /* Return 1 if LHS and RHS are compatible types for assignment or
581 various other operations. Return 0 if they are incompatible, and
582 return -1 if we choose to not decide. When the operation is
583 REFLEXIVE, check for compatibility in either direction.
585 For statically typed objects, an assignment of the form `a' = `b'
589 `a' and `b' are the same class type, or
590 `a' and `b' are of class types A and B such that B is a descendant of A. */
593 maybe_objc_comptypes (lhs, rhs, reflexive)
597 return objc_comptypes (lhs, rhs, reflexive);
601 lookup_method_in_protocol_list (rproto_list, sel_name, class_meth)
609 for (rproto = rproto_list; rproto; rproto = TREE_CHAIN (rproto))
611 p = TREE_VALUE (rproto);
613 if (TREE_CODE (p) == PROTOCOL_INTERFACE_TYPE)
615 if ((fnd = lookup_method (class_meth
616 ? PROTOCOL_CLS_METHODS (p)
617 : PROTOCOL_NST_METHODS (p), sel_name)))
619 else if (PROTOCOL_LIST (p))
620 fnd = lookup_method_in_protocol_list (PROTOCOL_LIST (p),
621 sel_name, class_meth);
625 ; /* An identifier...if we could not find a protocol. */
636 lookup_protocol_in_reflist (rproto_list, lproto)
642 /* Make sure the protocol is supported by the object on the rhs. */
643 if (TREE_CODE (lproto) == PROTOCOL_INTERFACE_TYPE)
646 for (rproto = rproto_list; rproto; rproto = TREE_CHAIN (rproto))
648 p = TREE_VALUE (rproto);
650 if (TREE_CODE (p) == PROTOCOL_INTERFACE_TYPE)
655 else if (PROTOCOL_LIST (p))
656 fnd = lookup_protocol_in_reflist (PROTOCOL_LIST (p), lproto);
665 ; /* An identifier...if we could not find a protocol. */
671 /* Return 1 if LHS and RHS are compatible types for assignment
672 or various other operations. Return 0 if they are incompatible,
673 and return -1 if we choose to not decide. When the operation
674 is REFLEXIVE, check for compatibility in either direction. */
677 objc_comptypes (lhs, rhs, reflexive)
682 /* New clause for protocols. */
684 if (TREE_CODE (lhs) == POINTER_TYPE
685 && TREE_CODE (TREE_TYPE (lhs)) == RECORD_TYPE
686 && TREE_CODE (rhs) == POINTER_TYPE
687 && TREE_CODE (TREE_TYPE (rhs)) == RECORD_TYPE)
689 int lhs_is_proto = IS_PROTOCOL_QUALIFIED_ID (lhs);
690 int rhs_is_proto = IS_PROTOCOL_QUALIFIED_ID (rhs);
694 tree lproto, lproto_list = TYPE_PROTOCOL_LIST (lhs);
695 tree rproto, rproto_list;
700 rproto_list = TYPE_PROTOCOL_LIST (rhs);
702 /* Make sure the protocol is supported by the object
704 for (lproto = lproto_list; lproto; lproto = TREE_CHAIN (lproto))
706 p = TREE_VALUE (lproto);
707 rproto = lookup_protocol_in_reflist (rproto_list, p);
710 warning ("object does not conform to the `%s' protocol",
711 IDENTIFIER_POINTER (PROTOCOL_NAME (p)));
714 else if (TYPED_OBJECT (TREE_TYPE (rhs)))
716 tree rname = TYPE_NAME (TREE_TYPE (rhs));
719 /* Make sure the protocol is supported by the object
721 for (lproto = lproto_list; lproto; lproto = TREE_CHAIN (lproto))
723 p = TREE_VALUE (lproto);
725 rinter = lookup_interface (rname);
727 while (rinter && !rproto)
731 rproto_list = CLASS_PROTOCOL_LIST (rinter);
732 /* If the underlying ObjC class does not have
733 protocols attached to it, perhaps there are
734 "one-off" protocols attached to the rhs?
735 E.g., 'id<MyProt> foo;'. */
737 rproto_list = TYPE_PROTOCOL_LIST (TREE_TYPE (rhs));
738 rproto = lookup_protocol_in_reflist (rproto_list, p);
740 /* Check for protocols adopted by categories. */
741 cat = CLASS_CATEGORY_LIST (rinter);
742 while (cat && !rproto)
744 rproto_list = CLASS_PROTOCOL_LIST (cat);
745 rproto = lookup_protocol_in_reflist (rproto_list, p);
747 cat = CLASS_CATEGORY_LIST (cat);
750 rinter = lookup_interface (CLASS_SUPER_NAME (rinter));
754 warning ("class `%s' does not implement the `%s' protocol",
755 IDENTIFIER_POINTER (TYPE_NAME (TREE_TYPE (rhs))),
756 IDENTIFIER_POINTER (PROTOCOL_NAME (p)));
760 /* May change...based on whether there was any mismatch */
763 else if (rhs_is_proto)
764 /* Lhs is not a protocol...warn if it is statically typed */
765 return (TYPED_OBJECT (TREE_TYPE (lhs)) != 0);
768 /* Defer to comptypes. */
772 else if (TREE_CODE (lhs) == RECORD_TYPE && TREE_CODE (rhs) == RECORD_TYPE)
773 ; /* Fall thru. This is the case we have been handling all along */
775 /* Defer to comptypes. */
778 /* `id' = `<class> *', `<class> *' = `id' */
780 if ((TYPE_NAME (lhs) == objc_object_id && TYPED_OBJECT (rhs))
781 || (TYPE_NAME (rhs) == objc_object_id && TYPED_OBJECT (lhs)))
784 /* `id' = `Class', `Class' = `id' */
786 else if ((TYPE_NAME (lhs) == objc_object_id
787 && TYPE_NAME (rhs) == objc_class_id)
788 || (TYPE_NAME (lhs) == objc_class_id
789 && TYPE_NAME (rhs) == objc_object_id))
792 /* `<class> *' = `<class> *' */
794 else if (TYPED_OBJECT (lhs) && TYPED_OBJECT (rhs))
796 tree lname = TYPE_NAME (lhs);
797 tree rname = TYPE_NAME (rhs);
803 /* If the left hand side is a super class of the right hand side,
805 for (inter = lookup_interface (rname); inter;
806 inter = lookup_interface (CLASS_SUPER_NAME (inter)))
807 if (lname == CLASS_SUPER_NAME (inter))
810 /* Allow the reverse when reflexive. */
812 for (inter = lookup_interface (lname); inter;
813 inter = lookup_interface (CLASS_SUPER_NAME (inter)))
814 if (rname == CLASS_SUPER_NAME (inter))
820 /* Defer to comptypes. */
824 /* Called from c-decl.c before all calls to rest_of_decl_compilation. */
827 objc_check_decl (decl)
830 tree type = TREE_TYPE (decl);
832 if (TREE_CODE (type) == RECORD_TYPE
833 && TREE_STATIC_TEMPLATE (type)
834 && type != constant_string_type)
835 error_with_decl (decl, "`%s' cannot be statically allocated");
839 maybe_objc_check_decl (decl)
842 objc_check_decl (decl);
845 /* Implement static typing. At this point, we know we have an interface. */
848 get_static_reference (interface, protocols)
852 tree type = xref_tag (RECORD_TYPE, interface);
856 tree t, m = TYPE_MAIN_VARIANT (type);
858 t = copy_node (type);
859 TYPE_BINFO (t) = make_tree_vec (2);
861 /* Add this type to the chain of variants of TYPE. */
862 TYPE_NEXT_VARIANT (t) = TYPE_NEXT_VARIANT (m);
863 TYPE_NEXT_VARIANT (m) = t;
865 /* Look up protocols and install in lang specific list. Note
866 that the protocol list can have a different lifetime than T! */
867 TYPE_PROTOCOL_LIST (t) = lookup_and_install_protocols (protocols);
869 /* This forces a new pointer type to be created later
870 (in build_pointer_type)...so that the new template
871 we just created will actually be used...what a hack! */
872 if (TYPE_POINTER_TO (t))
873 TYPE_POINTER_TO (t) = NULL_TREE;
882 get_object_reference (protocols)
885 tree type_decl = lookup_name (objc_id_id);
888 if (type_decl && TREE_CODE (type_decl) == TYPE_DECL)
890 type = TREE_TYPE (type_decl);
891 if (TYPE_MAIN_VARIANT (type) != id_type)
892 warning ("unexpected type for `id' (%s)",
893 gen_declaration (type, errbuf));
897 error ("undefined type `id', please import <objc/objc.h>");
898 return error_mark_node;
901 /* This clause creates a new pointer type that is qualified with
902 the protocol specification...this info is used later to do more
903 elaborate type checking. */
907 tree t, m = TYPE_MAIN_VARIANT (type);
909 t = copy_node (type);
910 TYPE_BINFO (t) = make_tree_vec (2);
912 /* Add this type to the chain of variants of TYPE. */
913 TYPE_NEXT_VARIANT (t) = TYPE_NEXT_VARIANT (m);
914 TYPE_NEXT_VARIANT (m) = t;
916 /* Look up protocols...and install in lang specific list */
917 TYPE_PROTOCOL_LIST (t) = lookup_and_install_protocols (protocols);
919 /* This forces a new pointer type to be created later
920 (in build_pointer_type)...so that the new template
921 we just created will actually be used...what a hack! */
922 if (TYPE_POINTER_TO (t))
923 TYPE_POINTER_TO (t) = NULL_TREE;
930 /* Check for circular dependencies in protocols. The arguments are
931 PROTO, the protocol to check, and LIST, a list of protocol it
935 check_protocol_recursively (proto, list)
941 for (p = list; p; p = TREE_CHAIN (p))
943 tree pp = TREE_VALUE (p);
945 if (TREE_CODE (pp) == IDENTIFIER_NODE)
946 pp = lookup_protocol (pp);
949 fatal_error ("protocol `%s' has circular dependency",
950 IDENTIFIER_POINTER (PROTOCOL_NAME (pp)));
952 check_protocol_recursively (proto, PROTOCOL_LIST (pp));
957 lookup_and_install_protocols (protocols)
962 tree return_value = protocols;
964 for (proto = protocols; proto; proto = TREE_CHAIN (proto))
966 tree ident = TREE_VALUE (proto);
967 tree p = lookup_protocol (ident);
971 error ("cannot find protocol declaration for `%s'",
972 IDENTIFIER_POINTER (ident));
974 TREE_CHAIN (prev) = TREE_CHAIN (proto);
976 return_value = TREE_CHAIN (proto);
980 /* Replace identifier with actual protocol node. */
981 TREE_VALUE (proto) = p;
989 /* Create and push a decl for a built-in external variable or field NAME.
991 TYPE is its data type. */
994 create_builtin_decl (code, type, name)
999 tree decl = build_decl (code, get_identifier (name), type);
1001 if (code == VAR_DECL)
1003 TREE_STATIC (decl) = 1;
1004 make_decl_rtl (decl, 0);
1008 DECL_ARTIFICIAL (decl) = 1;
1012 /* Find the decl for the constant string class. */
1015 setup_string_decl ()
1017 if (!string_class_decl)
1019 if (!constant_string_global_id)
1020 constant_string_global_id = get_identifier (STRING_OBJECT_GLOBAL_NAME);
1021 string_class_decl = lookup_name (constant_string_global_id);
1025 /* Purpose: "play" parser, creating/installing representations
1026 of the declarations that are required by Objective-C.
1030 type_spec--------->sc_spec
1031 (tree_list) (tree_list)
1034 identifier_node identifier_node */
1037 synth_module_prologue ()
1042 /* Defined in `objc.h' */
1043 objc_object_id = get_identifier (TAG_OBJECT);
1045 objc_object_reference = xref_tag (RECORD_TYPE, objc_object_id);
1047 id_type = build_pointer_type (objc_object_reference);
1049 objc_id_id = get_identifier (TYPE_ID);
1050 objc_class_id = get_identifier (TAG_CLASS);
1052 objc_class_type = build_pointer_type (xref_tag (RECORD_TYPE, objc_class_id));
1053 protocol_type = build_pointer_type (xref_tag (RECORD_TYPE,
1054 get_identifier (PROTOCOL_OBJECT_CLASS_NAME)));
1056 /* Declare type of selector-objects that represent an operation name. */
1058 /* `struct objc_selector *' */
1060 = build_pointer_type (xref_tag (RECORD_TYPE,
1061 get_identifier (TAG_SELECTOR)));
1063 /* Forward declare type, or else the prototype for msgSendSuper will
1066 super_p = build_pointer_type (xref_tag (RECORD_TYPE,
1067 get_identifier (TAG_SUPER)));
1070 /* id objc_msgSend (id, SEL, ...); */
1073 = build_function_type (id_type,
1074 tree_cons (NULL_TREE, id_type,
1075 tree_cons (NULL_TREE, selector_type,
1078 if (! flag_next_runtime)
1080 umsg_decl = build_decl (FUNCTION_DECL,
1081 get_identifier (TAG_MSGSEND), temp_type);
1082 DECL_EXTERNAL (umsg_decl) = 1;
1083 TREE_PUBLIC (umsg_decl) = 1;
1084 DECL_INLINE (umsg_decl) = 1;
1085 DECL_ARTIFICIAL (umsg_decl) = 1;
1087 make_decl_rtl (umsg_decl, NULL);
1088 pushdecl (umsg_decl);
1091 umsg_decl = builtin_function (TAG_MSGSEND, temp_type, 0, NOT_BUILT_IN,
1094 /* id objc_msgSendSuper (struct objc_super *, SEL, ...); */
1097 = build_function_type (id_type,
1098 tree_cons (NULL_TREE, super_p,
1099 tree_cons (NULL_TREE, selector_type,
1102 umsg_super_decl = builtin_function (TAG_MSGSENDSUPER,
1103 temp_type, 0, NOT_BUILT_IN,
1106 /* id objc_getClass (const char *); */
1108 temp_type = build_function_type (id_type,
1109 tree_cons (NULL_TREE,
1110 const_string_type_node,
1111 tree_cons (NULL_TREE, void_type_node,
1115 = builtin_function (TAG_GETCLASS, temp_type, 0, NOT_BUILT_IN,
1118 /* id objc_getMetaClass (const char *); */
1120 objc_get_meta_class_decl
1121 = builtin_function (TAG_GETMETACLASS, temp_type, 0, NOT_BUILT_IN,
1124 /* static SEL _OBJC_SELECTOR_TABLE[]; */
1126 if (! flag_next_runtime)
1128 if (flag_typed_selectors)
1130 /* Suppress outputting debug symbols, because
1131 dbxout_init hasn'r been called yet. */
1132 enum debug_info_type save_write_symbols = write_symbols;
1133 const struct gcc_debug_hooks *const save_hooks = debug_hooks;
1134 write_symbols = NO_DEBUG;
1135 debug_hooks = &do_nothing_debug_hooks;
1137 build_selector_template ();
1138 temp_type = build_array_type (objc_selector_template, NULL_TREE);
1140 write_symbols = save_write_symbols;
1141 debug_hooks = save_hooks;
1144 temp_type = build_array_type (selector_type, NULL_TREE);
1146 layout_type (temp_type);
1147 UOBJC_SELECTOR_TABLE_decl
1148 = create_builtin_decl (VAR_DECL, temp_type,
1149 "_OBJC_SELECTOR_TABLE");
1151 /* Avoid warning when not sending messages. */
1152 TREE_USED (UOBJC_SELECTOR_TABLE_decl) = 1;
1155 generate_forward_declaration_to_string_table ();
1157 /* Forward declare constant_string_id and constant_string_type. */
1158 if (!constant_string_class_name)
1159 constant_string_class_name = default_constant_string_class_name;
1161 constant_string_id = get_identifier (constant_string_class_name);
1162 constant_string_type = xref_tag (RECORD_TYPE, constant_string_id);
1165 /* Predefine the following data type:
1167 struct STRING_OBJECT_CLASS_NAME
1171 unsigned int length;
1175 build_string_class_template ()
1177 tree field_decl, field_decl_chain;
1179 field_decl = create_builtin_decl (FIELD_DECL, id_type, "isa");
1180 field_decl_chain = field_decl;
1182 field_decl = create_builtin_decl (FIELD_DECL,
1183 build_pointer_type (char_type_node),
1185 chainon (field_decl_chain, field_decl);
1187 field_decl = create_builtin_decl (FIELD_DECL, unsigned_type_node, "length");
1188 chainon (field_decl_chain, field_decl);
1190 finish_struct (constant_string_type, field_decl_chain, NULL_TREE);
1193 /* Custom build_string which sets TREE_TYPE! */
1196 my_build_string (len, str)
1200 return fix_string_type (build_string (len, str));
1203 /* Given a chain of STRING_CST's, build a static instance of
1204 NXConstantString which points at the concatenation of those strings.
1205 We place the string object in the __string_objects section of the
1206 __OBJC segment. The Objective-C runtime will initialize the isa
1207 pointers of the string objects to point at the NXConstantString
1211 build_objc_string_object (strings)
1214 tree string, initlist, constructor;
1217 if (lookup_interface (constant_string_id) == NULL_TREE)
1219 error ("cannot find interface declaration for `%s'",
1220 IDENTIFIER_POINTER (constant_string_id));
1221 return error_mark_node;
1224 add_class_reference (constant_string_id);
1226 if (TREE_CHAIN (strings))
1228 varray_type vstrings;
1229 VARRAY_TREE_INIT (vstrings, 32, "strings");
1231 for (; strings ; strings = TREE_CHAIN (strings))
1232 VARRAY_PUSH_TREE (vstrings, strings);
1234 string = combine_strings (vstrings);
1239 string = fix_string_type (string);
1241 TREE_SET_CODE (string, STRING_CST);
1242 length = TREE_STRING_LENGTH (string) - 1;
1244 /* We could not properly create NXConstantString in synth_module_prologue,
1245 because that's called before debugging is initialized. Do it now. */
1246 if (TYPE_FIELDS (constant_string_type) == NULL_TREE)
1247 build_string_class_template ();
1249 /* & ((NXConstantString) { NULL, string, length }) */
1251 if (flag_next_runtime)
1253 /* For the NeXT runtime, we can generate a literal reference
1254 to the string class, don't need to run a constructor. */
1255 setup_string_decl ();
1256 if (string_class_decl == NULL_TREE)
1258 error ("cannot find reference tag for class `%s'",
1259 IDENTIFIER_POINTER (constant_string_id));
1260 return error_mark_node;
1262 initlist = build_tree_list
1264 copy_node (build_unary_op (ADDR_EXPR, string_class_decl, 0)));
1268 initlist = build_tree_list (NULL_TREE, build_int_2 (0, 0));
1272 = tree_cons (NULL_TREE, copy_node (build_unary_op (ADDR_EXPR, string, 1)),
1274 initlist = tree_cons (NULL_TREE, build_int_2 (length, 0), initlist);
1275 constructor = build_constructor (constant_string_type, nreverse (initlist));
1277 if (!flag_next_runtime)
1280 = objc_add_static_instance (constructor, constant_string_type);
1283 return (build_unary_op (ADDR_EXPR, constructor, 1));
1286 /* Declare a static instance of CLASS_DECL initialized by CONSTRUCTOR. */
1289 objc_add_static_instance (constructor, class_decl)
1290 tree constructor, class_decl;
1292 static int num_static_inst;
1296 /* Find the list of static instances for the CLASS_DECL. Create one if
1298 for (chain = &objc_static_instances;
1299 *chain && TREE_VALUE (*chain) != class_decl;
1300 chain = &TREE_CHAIN (*chain));
1303 *chain = tree_cons (NULL_TREE, class_decl, NULL_TREE);
1304 add_objc_string (TYPE_NAME (class_decl), class_names);
1307 sprintf (buf, "_OBJC_INSTANCE_%d", num_static_inst++);
1308 decl = build_decl (VAR_DECL, get_identifier (buf), class_decl);
1309 DECL_COMMON (decl) = 1;
1310 TREE_STATIC (decl) = 1;
1311 DECL_ARTIFICIAL (decl) = 1;
1312 DECL_INITIAL (decl) = constructor;
1314 /* We may be writing something else just now.
1315 Postpone till end of input. */
1316 DECL_DEFER_OUTPUT (decl) = 1;
1317 pushdecl_top_level (decl);
1318 rest_of_decl_compilation (decl, 0, 1, 0);
1320 /* Add the DECL to the head of this CLASS' list. */
1321 TREE_PURPOSE (*chain) = tree_cons (NULL_TREE, decl, TREE_PURPOSE (*chain));
1326 /* Build a static constant CONSTRUCTOR
1327 with type TYPE and elements ELTS. */
1330 build_constructor (type, elts)
1333 tree constructor, f, e;
1335 /* ??? Most of the places that we build constructors, we don't fill in
1336 the type of integers properly. Convert them all en masse. */
1337 if (TREE_CODE (type) == ARRAY_TYPE)
1339 f = TREE_TYPE (type);
1340 if (TREE_CODE (f) == POINTER_TYPE || TREE_CODE (f) == INTEGER_TYPE)
1341 for (e = elts; e ; e = TREE_CHAIN (e))
1342 TREE_VALUE (e) = convert (f, TREE_VALUE (e));
1346 f = TYPE_FIELDS (type);
1347 for (e = elts; e ; e = TREE_CHAIN (e), f = TREE_CHAIN (f))
1348 if (TREE_CODE (TREE_TYPE (f)) == POINTER_TYPE
1349 || TREE_CODE (TREE_TYPE (f)) == INTEGER_TYPE)
1350 TREE_VALUE (e) = convert (TREE_TYPE (f), TREE_VALUE (e));
1353 constructor = build (CONSTRUCTOR, type, NULL_TREE, elts);
1354 TREE_CONSTANT (constructor) = 1;
1355 TREE_STATIC (constructor) = 1;
1356 TREE_READONLY (constructor) = 1;
1361 /* Take care of defining and initializing _OBJC_SYMBOLS. */
1363 /* Predefine the following data type:
1371 void *defs[cls_def_cnt + cat_def_cnt];
1375 build_objc_symtab_template ()
1377 tree field_decl, field_decl_chain, index;
1379 objc_symtab_template
1380 = start_struct (RECORD_TYPE, get_identifier (UTAG_SYMTAB));
1382 /* long sel_ref_cnt; */
1384 field_decl = create_builtin_decl (FIELD_DECL,
1385 long_integer_type_node,
1387 field_decl_chain = field_decl;
1391 field_decl = create_builtin_decl (FIELD_DECL,
1392 build_pointer_type (selector_type),
1394 chainon (field_decl_chain, field_decl);
1396 /* short cls_def_cnt; */
1398 field_decl = create_builtin_decl (FIELD_DECL,
1399 short_integer_type_node,
1401 chainon (field_decl_chain, field_decl);
1403 /* short cat_def_cnt; */
1405 field_decl = create_builtin_decl (FIELD_DECL,
1406 short_integer_type_node,
1408 chainon (field_decl_chain, field_decl);
1410 /* void *defs[cls_def_cnt + cat_def_cnt]; */
1412 if (!flag_next_runtime)
1413 index = build_index_type (build_int_2 (imp_count + cat_count, 0));
1415 index = build_index_type (build_int_2 (imp_count + cat_count - 1,
1416 imp_count == 0 && cat_count == 0
1418 field_decl = create_builtin_decl (FIELD_DECL,
1419 build_array_type (ptr_type_node, index),
1421 chainon (field_decl_chain, field_decl);
1423 finish_struct (objc_symtab_template, field_decl_chain, NULL_TREE);
1426 /* Create the initial value for the `defs' field of _objc_symtab.
1427 This is a CONSTRUCTOR. */
1430 init_def_list (type)
1433 tree expr, initlist = NULL_TREE;
1434 struct imp_entry *impent;
1437 for (impent = imp_list; impent; impent = impent->next)
1439 if (TREE_CODE (impent->imp_context) == CLASS_IMPLEMENTATION_TYPE)
1441 expr = build_unary_op (ADDR_EXPR, impent->class_decl, 0);
1442 initlist = tree_cons (NULL_TREE, expr, initlist);
1447 for (impent = imp_list; impent; impent = impent->next)
1449 if (TREE_CODE (impent->imp_context) == CATEGORY_IMPLEMENTATION_TYPE)
1451 expr = build_unary_op (ADDR_EXPR, impent->class_decl, 0);
1452 initlist = tree_cons (NULL_TREE, expr, initlist);
1456 if (!flag_next_runtime)
1458 /* statics = { ..., _OBJC_STATIC_INSTANCES, ... } */
1461 if (static_instances_decl)
1462 expr = build_unary_op (ADDR_EXPR, static_instances_decl, 0);
1464 expr = build_int_2 (0, 0);
1466 initlist = tree_cons (NULL_TREE, expr, initlist);
1469 return build_constructor (type, nreverse (initlist));
1472 /* Construct the initial value for all of _objc_symtab. */
1475 init_objc_symtab (type)
1480 /* sel_ref_cnt = { ..., 5, ... } */
1482 initlist = build_tree_list (NULL_TREE, build_int_2 (0, 0));
1484 /* refs = { ..., _OBJC_SELECTOR_TABLE, ... } */
1486 if (flag_next_runtime || ! sel_ref_chain)
1487 initlist = tree_cons (NULL_TREE, build_int_2 (0, 0), initlist);
1489 initlist = tree_cons (NULL_TREE,
1490 build_unary_op (ADDR_EXPR,
1491 UOBJC_SELECTOR_TABLE_decl, 1),
1494 /* cls_def_cnt = { ..., 5, ... } */
1496 initlist = tree_cons (NULL_TREE, build_int_2 (imp_count, 0), initlist);
1498 /* cat_def_cnt = { ..., 5, ... } */
1500 initlist = tree_cons (NULL_TREE, build_int_2 (cat_count, 0), initlist);
1502 /* cls_def = { ..., { &Foo, &Bar, ...}, ... } */
1504 if (imp_count || cat_count || static_instances_decl)
1507 tree field = TYPE_FIELDS (type);
1508 field = TREE_CHAIN (TREE_CHAIN (TREE_CHAIN (TREE_CHAIN (field))));
1510 initlist = tree_cons (NULL_TREE, init_def_list (TREE_TYPE (field)),
1514 return build_constructor (type, nreverse (initlist));
1517 /* Push forward-declarations of all the categories so that
1518 init_def_list can use them in a CONSTRUCTOR. */
1521 forward_declare_categories ()
1523 struct imp_entry *impent;
1524 tree sav = objc_implementation_context;
1526 for (impent = imp_list; impent; impent = impent->next)
1528 if (TREE_CODE (impent->imp_context) == CATEGORY_IMPLEMENTATION_TYPE)
1530 /* Set an invisible arg to synth_id_with_class_suffix. */
1531 objc_implementation_context = impent->imp_context;
1533 = create_builtin_decl (VAR_DECL, objc_category_template,
1534 IDENTIFIER_POINTER (synth_id_with_class_suffix ("_OBJC_CATEGORY", objc_implementation_context)));
1537 objc_implementation_context = sav;
1540 /* Create the declaration of _OBJC_SYMBOLS, with type `strict _objc_symtab'
1541 and initialized appropriately. */
1544 generate_objc_symtab_decl ()
1548 if (!objc_category_template)
1549 build_category_template ();
1551 /* forward declare categories */
1553 forward_declare_categories ();
1555 if (!objc_symtab_template)
1556 build_objc_symtab_template ();
1558 sc_spec = build_tree_list (NULL_TREE, ridpointers[(int) RID_STATIC]);
1560 UOBJC_SYMBOLS_decl = start_decl (get_identifier ("_OBJC_SYMBOLS"),
1561 tree_cons (NULL_TREE,
1562 objc_symtab_template, sc_spec),
1566 TREE_USED (UOBJC_SYMBOLS_decl) = 1;
1567 DECL_IGNORED_P (UOBJC_SYMBOLS_decl) = 1;
1568 DECL_ARTIFICIAL (UOBJC_SYMBOLS_decl) = 1;
1569 finish_decl (UOBJC_SYMBOLS_decl,
1570 init_objc_symtab (TREE_TYPE (UOBJC_SYMBOLS_decl)),
1575 init_module_descriptor (type)
1578 tree initlist, expr;
1580 /* version = { 1, ... } */
1582 expr = build_int_2 (OBJC_VERSION, 0);
1583 initlist = build_tree_list (NULL_TREE, expr);
1585 /* size = { ..., sizeof (struct objc_module), ... } */
1587 expr = size_in_bytes (objc_module_template);
1588 initlist = tree_cons (NULL_TREE, expr, initlist);
1590 /* name = { ..., "foo.m", ... } */
1592 expr = add_objc_string (get_identifier (input_filename), class_names);
1593 initlist = tree_cons (NULL_TREE, expr, initlist);
1595 /* symtab = { ..., _OBJC_SYMBOLS, ... } */
1597 if (UOBJC_SYMBOLS_decl)
1598 expr = build_unary_op (ADDR_EXPR, UOBJC_SYMBOLS_decl, 0);
1600 expr = build_int_2 (0, 0);
1601 initlist = tree_cons (NULL_TREE, expr, initlist);
1603 return build_constructor (type, nreverse (initlist));
1606 /* Write out the data structures to describe Objective C classes defined.
1607 If appropriate, compile and output a setup function to initialize them.
1608 Return a symbol_ref to the function to call to initialize the Objective C
1609 data structures for this file (and perhaps for other files also).
1611 struct objc_module { ... } _OBJC_MODULE = { ... }; */
1614 build_module_descriptor ()
1616 tree decl_specs, field_decl, field_decl_chain;
1618 objc_module_template
1619 = start_struct (RECORD_TYPE, get_identifier (UTAG_MODULE));
1623 decl_specs = build_tree_list (NULL_TREE, ridpointers[(int) RID_LONG]);
1624 field_decl = get_identifier ("version");
1626 = grokfield (input_filename, lineno, field_decl, decl_specs, NULL_TREE);
1627 field_decl_chain = field_decl;
1631 decl_specs = build_tree_list (NULL_TREE, ridpointers[(int) RID_LONG]);
1632 field_decl = get_identifier ("size");
1634 = grokfield (input_filename, lineno, field_decl, decl_specs, NULL_TREE);
1635 chainon (field_decl_chain, field_decl);
1639 decl_specs = build_tree_list (NULL_TREE, ridpointers[(int) RID_CHAR]);
1640 field_decl = build1 (INDIRECT_REF, NULL_TREE, get_identifier ("name"));
1642 = grokfield (input_filename, lineno, field_decl, decl_specs, NULL_TREE);
1643 chainon (field_decl_chain, field_decl);
1645 /* struct objc_symtab *symtab; */
1647 decl_specs = get_identifier (UTAG_SYMTAB);
1648 decl_specs = build_tree_list (NULL_TREE, xref_tag (RECORD_TYPE, decl_specs));
1649 field_decl = build1 (INDIRECT_REF, NULL_TREE, get_identifier ("symtab"));
1651 = grokfield (input_filename, lineno, field_decl, decl_specs, NULL_TREE);
1652 chainon (field_decl_chain, field_decl);
1654 finish_struct (objc_module_template, field_decl_chain, NULL_TREE);
1656 /* Create an instance of "objc_module". */
1658 decl_specs = tree_cons (NULL_TREE, objc_module_template,
1659 build_tree_list (NULL_TREE,
1660 ridpointers[(int) RID_STATIC]));
1662 UOBJC_MODULES_decl = start_decl (get_identifier ("_OBJC_MODULES"),
1663 decl_specs, 1, NULL_TREE);
1665 DECL_ARTIFICIAL (UOBJC_MODULES_decl) = 1;
1666 DECL_IGNORED_P (UOBJC_MODULES_decl) = 1;
1667 DECL_CONTEXT (UOBJC_MODULES_decl) = NULL_TREE;
1669 finish_decl (UOBJC_MODULES_decl,
1670 init_module_descriptor (TREE_TYPE (UOBJC_MODULES_decl)),
1673 /* Mark the decl to avoid "defined but not used" warning. */
1674 DECL_IN_SYSTEM_HEADER (UOBJC_MODULES_decl) = 1;
1676 /* Generate a constructor call for the module descriptor.
1677 This code was generated by reading the grammar rules
1678 of c-parse.in; Therefore, it may not be the most efficient
1679 way of generating the requisite code. */
1681 if (flag_next_runtime)
1685 tree parms, execclass_decl, decelerator, void_list_node_1;
1686 tree init_function_name, init_function_decl;
1688 /* Declare void __objc_execClass (void *); */
1690 void_list_node_1 = build_tree_list (NULL_TREE, void_type_node);
1691 execclass_decl = build_decl (FUNCTION_DECL,
1692 get_identifier (TAG_EXECCLASS),
1693 build_function_type (void_type_node,
1694 tree_cons (NULL_TREE, ptr_type_node,
1695 void_list_node_1)));
1696 DECL_EXTERNAL (execclass_decl) = 1;
1697 DECL_ARTIFICIAL (execclass_decl) = 1;
1698 TREE_PUBLIC (execclass_decl) = 1;
1699 pushdecl (execclass_decl);
1700 rest_of_decl_compilation (execclass_decl, 0, 0, 0);
1701 assemble_external (execclass_decl);
1703 /* void _GLOBAL_$I$<gnyf> () {objc_execClass (&L_OBJC_MODULES);} */
1705 init_function_name = get_file_function_name ('I');
1706 start_function (void_list_node_1,
1707 build_nt (CALL_EXPR, init_function_name,
1708 tree_cons (NULL_TREE, NULL_TREE,
1712 store_parm_decls ();
1714 init_function_decl = current_function_decl;
1715 TREE_PUBLIC (init_function_decl) = ! targetm.have_ctors_dtors;
1716 TREE_USED (init_function_decl) = 1;
1717 /* Don't let this one be deferred. */
1718 DECL_INLINE (init_function_decl) = 0;
1719 DECL_UNINLINABLE (init_function_decl) = 1;
1720 current_function_cannot_inline
1721 = "static constructors and destructors cannot be inlined";
1724 = build_tree_list (NULL_TREE,
1725 build_unary_op (ADDR_EXPR, UOBJC_MODULES_decl, 0));
1726 decelerator = build_function_call (execclass_decl, parms);
1728 c_expand_expr_stmt (decelerator);
1730 finish_function (0, 0);
1732 return XEXP (DECL_RTL (init_function_decl), 0);
1736 /* extern const char _OBJC_STRINGS[]; */
1739 generate_forward_declaration_to_string_table ()
1741 tree sc_spec, decl_specs, expr_decl;
1743 sc_spec = tree_cons (NULL_TREE, ridpointers[(int) RID_EXTERN], NULL_TREE);
1744 decl_specs = tree_cons (NULL_TREE, ridpointers[(int) RID_CHAR], sc_spec);
1747 = build_nt (ARRAY_REF, get_identifier ("_OBJC_STRINGS"), NULL_TREE);
1749 UOBJC_STRINGS_decl = define_decl (expr_decl, decl_specs);
1752 /* Return the DECL of the string IDENT in the SECTION. */
1755 get_objc_string_decl (ident, section)
1757 enum string_section section;
1761 if (section == class_names)
1762 chain = class_names_chain;
1763 else if (section == meth_var_names)
1764 chain = meth_var_names_chain;
1765 else if (section == meth_var_types)
1766 chain = meth_var_types_chain;
1770 for (; chain != 0; chain = TREE_VALUE (chain))
1771 if (TREE_VALUE (chain) == ident)
1772 return (TREE_PURPOSE (chain));
1778 /* Output references to all statically allocated objects. Return the DECL
1779 for the array built. */
1782 generate_static_references ()
1784 tree decls = NULL_TREE, ident, decl_spec, expr_decl, expr = NULL_TREE;
1785 tree class_name, class, decl, initlist;
1786 tree cl_chain, in_chain, type;
1787 int num_inst, num_class;
1790 if (flag_next_runtime)
1793 for (cl_chain = objc_static_instances, num_class = 0;
1794 cl_chain; cl_chain = TREE_CHAIN (cl_chain), num_class++)
1796 for (num_inst = 0, in_chain = TREE_PURPOSE (cl_chain);
1797 in_chain; num_inst++, in_chain = TREE_CHAIN (in_chain));
1799 sprintf (buf, "_OBJC_STATIC_INSTANCES_%d", num_class);
1800 ident = get_identifier (buf);
1802 expr_decl = build_nt (ARRAY_REF, ident, NULL_TREE);
1803 decl_spec = tree_cons (NULL_TREE, build_pointer_type (void_type_node),
1804 build_tree_list (NULL_TREE,
1805 ridpointers[(int) RID_STATIC]));
1806 decl = start_decl (expr_decl, decl_spec, 1, NULL_TREE);
1807 DECL_CONTEXT (decl) = 0;
1808 DECL_ARTIFICIAL (decl) = 1;
1810 /* Output {class_name, ...}. */
1811 class = TREE_VALUE (cl_chain);
1812 class_name = get_objc_string_decl (TYPE_NAME (class), class_names);
1813 initlist = build_tree_list (NULL_TREE,
1814 build_unary_op (ADDR_EXPR, class_name, 1));
1816 /* Output {..., instance, ...}. */
1817 for (in_chain = TREE_PURPOSE (cl_chain);
1818 in_chain; in_chain = TREE_CHAIN (in_chain))
1820 expr = build_unary_op (ADDR_EXPR, TREE_VALUE (in_chain), 1);
1821 initlist = tree_cons (NULL_TREE, expr, initlist);
1824 /* Output {..., NULL}. */
1825 initlist = tree_cons (NULL_TREE, build_int_2 (0, 0), initlist);
1827 expr = build_constructor (TREE_TYPE (decl), nreverse (initlist));
1828 finish_decl (decl, expr, NULL_TREE);
1829 TREE_USED (decl) = 1;
1831 type = build_array_type (build_pointer_type (void_type_node), 0);
1832 decl = build_decl (VAR_DECL, ident, type);
1833 TREE_USED (decl) = 1;
1834 TREE_STATIC (decl) = 1;
1836 = tree_cons (NULL_TREE, build_unary_op (ADDR_EXPR, decl, 1), decls);
1839 decls = tree_cons (NULL_TREE, build_int_2 (0, 0), decls);
1840 ident = get_identifier ("_OBJC_STATIC_INSTANCES");
1841 expr_decl = build_nt (ARRAY_REF, ident, NULL_TREE);
1842 decl_spec = tree_cons (NULL_TREE, build_pointer_type (void_type_node),
1843 build_tree_list (NULL_TREE,
1844 ridpointers[(int) RID_STATIC]));
1845 static_instances_decl
1846 = start_decl (expr_decl, decl_spec, 1, NULL_TREE);
1847 TREE_USED (static_instances_decl) = 1;
1848 DECL_CONTEXT (static_instances_decl) = 0;
1849 DECL_ARTIFICIAL (static_instances_decl) = 1;
1850 expr = build_constructor (TREE_TYPE (static_instances_decl),
1852 finish_decl (static_instances_decl, expr, NULL_TREE);
1855 /* Output all strings. */
1860 tree sc_spec, decl_specs, expr_decl;
1861 tree chain, string_expr;
1864 for (chain = class_names_chain; chain; chain = TREE_CHAIN (chain))
1866 string = TREE_VALUE (chain);
1867 decl = TREE_PURPOSE (chain);
1869 = tree_cons (NULL_TREE, ridpointers[(int) RID_STATIC], NULL_TREE);
1870 decl_specs = tree_cons (NULL_TREE, ridpointers[(int) RID_CHAR], sc_spec);
1871 expr_decl = build_nt (ARRAY_REF, DECL_NAME (decl), NULL_TREE);
1872 decl = start_decl (expr_decl, decl_specs, 1, NULL_TREE);
1873 DECL_CONTEXT (decl) = NULL_TREE;
1874 string_expr = my_build_string (IDENTIFIER_LENGTH (string) + 1,
1875 IDENTIFIER_POINTER (string));
1876 finish_decl (decl, string_expr, NULL_TREE);
1879 for (chain = meth_var_names_chain; chain; chain = TREE_CHAIN (chain))
1881 string = TREE_VALUE (chain);
1882 decl = TREE_PURPOSE (chain);
1884 = tree_cons (NULL_TREE, ridpointers[(int) RID_STATIC], NULL_TREE);
1885 decl_specs = tree_cons (NULL_TREE, ridpointers[(int) RID_CHAR], sc_spec);
1886 expr_decl = build_nt (ARRAY_REF, DECL_NAME (decl), NULL_TREE);
1887 decl = start_decl (expr_decl, decl_specs, 1, NULL_TREE);
1888 DECL_CONTEXT (decl) = NULL_TREE;
1889 string_expr = my_build_string (IDENTIFIER_LENGTH (string) + 1,
1890 IDENTIFIER_POINTER (string));
1891 finish_decl (decl, string_expr, NULL_TREE);
1894 for (chain = meth_var_types_chain; chain; chain = TREE_CHAIN (chain))
1896 string = TREE_VALUE (chain);
1897 decl = TREE_PURPOSE (chain);
1899 = tree_cons (NULL_TREE, ridpointers[(int) RID_STATIC], NULL_TREE);
1900 decl_specs = tree_cons (NULL_TREE, ridpointers[(int) RID_CHAR], sc_spec);
1901 expr_decl = build_nt (ARRAY_REF, DECL_NAME (decl), NULL_TREE);
1902 decl = start_decl (expr_decl, decl_specs, 1, NULL_TREE);
1903 DECL_CONTEXT (decl) = NULL_TREE;
1904 string_expr = my_build_string (IDENTIFIER_LENGTH (string) + 1,
1905 IDENTIFIER_POINTER (string));
1906 finish_decl (decl, string_expr, NULL_TREE);
1911 build_selector_reference_decl ()
1917 sprintf (buf, "_OBJC_SELECTOR_REFERENCES_%d", idx++);
1919 ident = get_identifier (buf);
1921 decl = build_decl (VAR_DECL, ident, selector_type);
1922 DECL_EXTERNAL (decl) = 1;
1923 TREE_PUBLIC (decl) = 1;
1924 TREE_USED (decl) = 1;
1925 TREE_READONLY (decl) = 1;
1926 DECL_ARTIFICIAL (decl) = 1;
1927 DECL_CONTEXT (decl) = 0;
1929 make_decl_rtl (decl, 0);
1930 pushdecl_top_level (decl);
1935 /* Just a handy wrapper for add_objc_string. */
1938 build_selector (ident)
1941 tree expr = add_objc_string (ident, meth_var_names);
1942 if (flag_typed_selectors)
1945 return build_c_cast (selector_type, expr); /* cast! */
1949 build_selector_translation_table ()
1951 tree sc_spec, decl_specs;
1952 tree chain, initlist = NULL_TREE;
1954 tree decl = NULL_TREE, var_decl, name;
1956 for (chain = sel_ref_chain; chain; chain = TREE_CHAIN (chain))
1960 expr = build_selector (TREE_VALUE (chain));
1962 if (flag_next_runtime)
1964 name = DECL_NAME (TREE_PURPOSE (chain));
1966 sc_spec = build_tree_list (NULL_TREE, ridpointers[(int) RID_STATIC]);
1968 /* static SEL _OBJC_SELECTOR_REFERENCES_n = ...; */
1969 decl_specs = tree_cons (NULL_TREE, selector_type, sc_spec);
1973 /* The `decl' that is returned from start_decl is the one that we
1974 forward declared in `build_selector_reference' */
1975 decl = start_decl (var_decl, decl_specs, 1, NULL_TREE );
1978 /* add one for the '\0' character */
1979 offset += IDENTIFIER_LENGTH (TREE_VALUE (chain)) + 1;
1981 if (flag_next_runtime)
1982 finish_decl (decl, expr, NULL_TREE);
1985 if (flag_typed_selectors)
1987 tree eltlist = NULL_TREE;
1988 tree encoding = get_proto_encoding (TREE_PURPOSE (chain));
1989 eltlist = tree_cons (NULL_TREE, expr, NULL_TREE);
1990 eltlist = tree_cons (NULL_TREE, encoding, eltlist);
1991 expr = build_constructor (objc_selector_template,
1992 nreverse (eltlist));
1994 initlist = tree_cons (NULL_TREE, expr, initlist);
1999 if (! flag_next_runtime)
2001 /* Cause the variable and its initial value to be actually output. */
2002 DECL_EXTERNAL (UOBJC_SELECTOR_TABLE_decl) = 0;
2003 TREE_STATIC (UOBJC_SELECTOR_TABLE_decl) = 1;
2004 /* NULL terminate the list and fix the decl for output. */
2005 initlist = tree_cons (NULL_TREE, build_int_2 (0, 0), initlist);
2006 DECL_INITIAL (UOBJC_SELECTOR_TABLE_decl) = objc_ellipsis_node;
2007 initlist = build_constructor (TREE_TYPE (UOBJC_SELECTOR_TABLE_decl),
2008 nreverse (initlist));
2009 finish_decl (UOBJC_SELECTOR_TABLE_decl, initlist, NULL_TREE);
2010 current_function_decl = NULL_TREE;
2015 get_proto_encoding (proto)
2023 if (! METHOD_ENCODING (proto))
2025 tmp_decl = build_tmp_function_decl ();
2026 hack_method_prototype (proto, tmp_decl);
2027 encoding = encode_method_prototype (proto, tmp_decl);
2028 METHOD_ENCODING (proto) = encoding;
2031 encoding = METHOD_ENCODING (proto);
2033 return add_objc_string (encoding, meth_var_types);
2036 return build_int_2 (0, 0);
2039 /* sel_ref_chain is a list whose "value" fields will be instances of
2040 identifier_node that represent the selector. */
2043 build_typed_selector_reference (ident, proto)
2046 tree *chain = &sel_ref_chain;
2052 if (TREE_PURPOSE (*chain) == ident && TREE_VALUE (*chain) == proto)
2053 goto return_at_index;
2056 chain = &TREE_CHAIN (*chain);
2059 *chain = tree_cons (proto, ident, NULL_TREE);
2062 expr = build_unary_op (ADDR_EXPR,
2063 build_array_ref (UOBJC_SELECTOR_TABLE_decl,
2064 build_int_2 (index, 0)),
2066 return build_c_cast (selector_type, expr);
2070 build_selector_reference (ident)
2073 tree *chain = &sel_ref_chain;
2079 if (TREE_VALUE (*chain) == ident)
2080 return (flag_next_runtime
2081 ? TREE_PURPOSE (*chain)
2082 : build_array_ref (UOBJC_SELECTOR_TABLE_decl,
2083 build_int_2 (index, 0)));
2086 chain = &TREE_CHAIN (*chain);
2089 expr = build_selector_reference_decl ();
2091 *chain = tree_cons (expr, ident, NULL_TREE);
2093 return (flag_next_runtime
2095 : build_array_ref (UOBJC_SELECTOR_TABLE_decl,
2096 build_int_2 (index, 0)));
2100 build_class_reference_decl ()
2106 sprintf (buf, "_OBJC_CLASS_REFERENCES_%d", idx++);
2108 ident = get_identifier (buf);
2110 decl = build_decl (VAR_DECL, ident, objc_class_type);
2111 DECL_EXTERNAL (decl) = 1;
2112 TREE_PUBLIC (decl) = 1;
2113 TREE_USED (decl) = 1;
2114 TREE_READONLY (decl) = 1;
2115 DECL_CONTEXT (decl) = 0;
2116 DECL_ARTIFICIAL (decl) = 1;
2118 make_decl_rtl (decl, 0);
2119 pushdecl_top_level (decl);
2124 /* Create a class reference, but don't create a variable to reference
2128 add_class_reference (ident)
2133 if ((chain = cls_ref_chain))
2138 if (ident == TREE_VALUE (chain))
2142 chain = TREE_CHAIN (chain);
2146 /* Append to the end of the list */
2147 TREE_CHAIN (tail) = tree_cons (NULL_TREE, ident, NULL_TREE);
2150 cls_ref_chain = tree_cons (NULL_TREE, ident, NULL_TREE);
2153 /* Get a class reference, creating it if necessary. Also create the
2154 reference variable. */
2157 get_class_reference (ident)
2160 if (flag_next_runtime)
2165 for (chain = &cls_ref_chain; *chain; chain = &TREE_CHAIN (*chain))
2166 if (TREE_VALUE (*chain) == ident)
2168 if (! TREE_PURPOSE (*chain))
2169 TREE_PURPOSE (*chain) = build_class_reference_decl ();
2171 return TREE_PURPOSE (*chain);
2174 decl = build_class_reference_decl ();
2175 *chain = tree_cons (decl, ident, NULL_TREE);
2182 add_class_reference (ident);
2184 params = build_tree_list (NULL_TREE,
2185 my_build_string (IDENTIFIER_LENGTH (ident) + 1,
2186 IDENTIFIER_POINTER (ident)));
2188 assemble_external (objc_get_class_decl);
2189 return build_function_call (objc_get_class_decl, params);
2193 /* For each string section we have a chain which maps identifier nodes
2194 to decls for the strings. */
2197 add_objc_string (ident, section)
2199 enum string_section section;
2203 if (section == class_names)
2204 chain = &class_names_chain;
2205 else if (section == meth_var_names)
2206 chain = &meth_var_names_chain;
2207 else if (section == meth_var_types)
2208 chain = &meth_var_types_chain;
2214 if (TREE_VALUE (*chain) == ident)
2215 return build_unary_op (ADDR_EXPR, TREE_PURPOSE (*chain), 1);
2217 chain = &TREE_CHAIN (*chain);
2220 decl = build_objc_string_decl (section);
2222 *chain = tree_cons (decl, ident, NULL_TREE);
2224 return build_unary_op (ADDR_EXPR, decl, 1);
2228 build_objc_string_decl (section)
2229 enum string_section section;
2233 static int class_names_idx = 0;
2234 static int meth_var_names_idx = 0;
2235 static int meth_var_types_idx = 0;
2237 if (section == class_names)
2238 sprintf (buf, "_OBJC_CLASS_NAME_%d", class_names_idx++);
2239 else if (section == meth_var_names)
2240 sprintf (buf, "_OBJC_METH_VAR_NAME_%d", meth_var_names_idx++);
2241 else if (section == meth_var_types)
2242 sprintf (buf, "_OBJC_METH_VAR_TYPE_%d", meth_var_types_idx++);
2244 ident = get_identifier (buf);
2246 decl = build_decl (VAR_DECL, ident, build_array_type (char_type_node, 0));
2247 DECL_EXTERNAL (decl) = 1;
2248 TREE_PUBLIC (decl) = 1;
2249 TREE_USED (decl) = 1;
2250 TREE_READONLY (decl) = 1;
2251 TREE_CONSTANT (decl) = 1;
2252 DECL_CONTEXT (decl) = 0;
2253 DECL_ARTIFICIAL (decl) = 1;
2255 make_decl_rtl (decl, 0);
2256 pushdecl_top_level (decl);
2263 objc_declare_alias (alias_ident, class_ident)
2267 if (is_class_name (class_ident) != class_ident)
2268 warning ("cannot find class `%s'", IDENTIFIER_POINTER (class_ident));
2269 else if (is_class_name (alias_ident))
2270 warning ("class `%s' already exists", IDENTIFIER_POINTER (alias_ident));
2272 alias_chain = tree_cons (class_ident, alias_ident, alias_chain);
2276 objc_declare_class (ident_list)
2281 for (list = ident_list; list; list = TREE_CHAIN (list))
2283 tree ident = TREE_VALUE (list);
2286 if ((decl = lookup_name (ident)))
2288 error ("`%s' redeclared as different kind of symbol",
2289 IDENTIFIER_POINTER (ident));
2290 error_with_decl (decl, "previous declaration of `%s'");
2293 if (! is_class_name (ident))
2295 tree record = xref_tag (RECORD_TYPE, ident);
2296 TREE_STATIC_TEMPLATE (record) = 1;
2297 class_chain = tree_cons (NULL_TREE, ident, class_chain);
2303 is_class_name (ident)
2308 if (lookup_interface (ident))
2311 for (chain = class_chain; chain; chain = TREE_CHAIN (chain))
2313 if (ident == TREE_VALUE (chain))
2317 for (chain = alias_chain; chain; chain = TREE_CHAIN (chain))
2319 if (ident == TREE_VALUE (chain))
2320 return TREE_PURPOSE (chain);
2327 lookup_interface (ident)
2332 for (chain = interface_chain; chain; chain = TREE_CHAIN (chain))
2334 if (ident == CLASS_NAME (chain))
2341 objc_copy_list (list, head)
2345 tree newlist = NULL_TREE, tail = NULL_TREE;
2349 tail = copy_node (list);
2351 /* The following statement fixes a bug when inheriting instance
2352 variables that are declared to be bitfields. finish_struct
2353 expects to find the width of the bitfield in DECL_INITIAL. */
2354 if (DECL_BIT_FIELD (tail) && DECL_INITIAL (tail) == 0)
2355 DECL_INITIAL (tail) = DECL_SIZE (tail);
2357 newlist = chainon (newlist, tail);
2358 list = TREE_CHAIN (list);
2365 /* Used by: build_private_template, get_class_ivars, and
2366 continue_class. COPY is 1 when called from @defs. In this case
2367 copy all fields. Otherwise don't copy leaf ivars since we rely on
2368 them being side-effected exactly once by finish_struct. */
2371 build_ivar_chain (interface, copy)
2375 tree my_name, super_name, ivar_chain;
2377 my_name = CLASS_NAME (interface);
2378 super_name = CLASS_SUPER_NAME (interface);
2380 /* Possibly copy leaf ivars. */
2382 objc_copy_list (CLASS_IVARS (interface), &ivar_chain);
2384 ivar_chain = CLASS_IVARS (interface);
2389 tree super_interface = lookup_interface (super_name);
2391 if (!super_interface)
2393 /* fatal did not work with 2 args...should fix */
2394 error ("cannot find interface declaration for `%s', superclass of `%s'",
2395 IDENTIFIER_POINTER (super_name),
2396 IDENTIFIER_POINTER (my_name));
2397 exit (FATAL_EXIT_CODE);
2400 if (super_interface == interface)
2401 fatal_error ("circular inheritance in interface declaration for `%s'",
2402 IDENTIFIER_POINTER (super_name));
2404 interface = super_interface;
2405 my_name = CLASS_NAME (interface);
2406 super_name = CLASS_SUPER_NAME (interface);
2408 op1 = CLASS_IVARS (interface);
2411 tree head, tail = objc_copy_list (op1, &head);
2413 /* Prepend super class ivars...make a copy of the list, we
2414 do not want to alter the original. */
2415 TREE_CHAIN (tail) = ivar_chain;
2422 /* struct <classname> {
2423 struct objc_class *isa;
2428 build_private_template (class)
2433 if (CLASS_STATIC_TEMPLATE (class))
2435 uprivate_record = CLASS_STATIC_TEMPLATE (class);
2436 ivar_context = TYPE_FIELDS (CLASS_STATIC_TEMPLATE (class));
2440 uprivate_record = start_struct (RECORD_TYPE, CLASS_NAME (class));
2442 ivar_context = build_ivar_chain (class, 0);
2444 finish_struct (uprivate_record, ivar_context, NULL_TREE);
2446 CLASS_STATIC_TEMPLATE (class) = uprivate_record;
2448 /* mark this record as class template - for class type checking */
2449 TREE_STATIC_TEMPLATE (uprivate_record) = 1;
2453 = groktypename (build_tree_list (build_tree_list (NULL_TREE,
2455 build1 (INDIRECT_REF, NULL_TREE,
2458 return ivar_context;
2461 /* Begin code generation for protocols... */
2463 /* struct objc_protocol {
2464 char *protocol_name;
2465 struct objc_protocol **protocol_list;
2466 struct objc_method_desc *instance_methods;
2467 struct objc_method_desc *class_methods;
2471 build_protocol_template ()
2473 tree decl_specs, field_decl, field_decl_chain;
2476 template = start_struct (RECORD_TYPE, get_identifier (UTAG_PROTOCOL));
2478 /* struct objc_class *isa; */
2480 decl_specs = build_tree_list (NULL_TREE, xref_tag (RECORD_TYPE,
2481 get_identifier (UTAG_CLASS)));
2482 field_decl = build1 (INDIRECT_REF, NULL_TREE, get_identifier ("isa"));
2484 = grokfield (input_filename, lineno, field_decl, decl_specs, NULL_TREE);
2485 field_decl_chain = field_decl;
2487 /* char *protocol_name; */
2489 decl_specs = build_tree_list (NULL_TREE, ridpointers[(int) RID_CHAR]);
2491 = build1 (INDIRECT_REF, NULL_TREE, get_identifier ("protocol_name"));
2493 = grokfield (input_filename, lineno, field_decl, decl_specs, NULL_TREE);
2494 chainon (field_decl_chain, field_decl);
2496 /* struct objc_protocol **protocol_list; */
2498 decl_specs = build_tree_list (NULL_TREE, template);
2500 = build1 (INDIRECT_REF, NULL_TREE, get_identifier ("protocol_list"));
2501 field_decl = build1 (INDIRECT_REF, NULL_TREE, field_decl);
2503 = grokfield (input_filename, lineno, field_decl, decl_specs, NULL_TREE);
2504 chainon (field_decl_chain, field_decl);
2506 /* struct objc_method_list *instance_methods; */
2509 = build_tree_list (NULL_TREE,
2510 xref_tag (RECORD_TYPE,
2511 get_identifier (UTAG_METHOD_PROTOTYPE_LIST)));
2513 = build1 (INDIRECT_REF, NULL_TREE, get_identifier ("instance_methods"));
2515 = grokfield (input_filename, lineno, field_decl, decl_specs, NULL_TREE);
2516 chainon (field_decl_chain, field_decl);
2518 /* struct objc_method_list *class_methods; */
2521 = build_tree_list (NULL_TREE,
2522 xref_tag (RECORD_TYPE,
2523 get_identifier (UTAG_METHOD_PROTOTYPE_LIST)));
2525 = build1 (INDIRECT_REF, NULL_TREE, get_identifier ("class_methods"));
2527 = grokfield (input_filename, lineno, field_decl, decl_specs, NULL_TREE);
2528 chainon (field_decl_chain, field_decl);
2530 return finish_struct (template, field_decl_chain, NULL_TREE);
2534 build_descriptor_table_initializer (type, entries)
2538 tree initlist = NULL_TREE;
2542 tree eltlist = NULL_TREE;
2545 = tree_cons (NULL_TREE,
2546 build_selector (METHOD_SEL_NAME (entries)), NULL_TREE);
2548 = tree_cons (NULL_TREE,
2549 add_objc_string (METHOD_ENCODING (entries),
2554 = tree_cons (NULL_TREE,
2555 build_constructor (type, nreverse (eltlist)), initlist);
2557 entries = TREE_CHAIN (entries);
2561 return build_constructor (build_array_type (type, 0), nreverse (initlist));
2564 /* struct objc_method_prototype_list {
2566 struct objc_method_prototype {
2573 build_method_prototype_list_template (list_type, size)
2577 tree objc_ivar_list_record;
2578 tree decl_specs, field_decl, field_decl_chain;
2580 /* Generate an unnamed struct definition. */
2582 objc_ivar_list_record = start_struct (RECORD_TYPE, NULL_TREE);
2584 /* int method_count; */
2586 decl_specs = build_tree_list (NULL_TREE, ridpointers[(int) RID_INT]);
2587 field_decl = get_identifier ("method_count");
2590 = grokfield (input_filename, lineno, field_decl, decl_specs, NULL_TREE);
2591 field_decl_chain = field_decl;
2593 /* struct objc_method method_list[]; */
2595 decl_specs = build_tree_list (NULL_TREE, list_type);
2596 field_decl = build_nt (ARRAY_REF, get_identifier ("method_list"),
2597 build_int_2 (size, 0));
2600 = grokfield (input_filename, lineno, field_decl, decl_specs, NULL_TREE);
2601 chainon (field_decl_chain, field_decl);
2603 finish_struct (objc_ivar_list_record, field_decl_chain, NULL_TREE);
2605 return objc_ivar_list_record;
2609 build_method_prototype_template ()
2612 tree decl_specs, field_decl, field_decl_chain;
2615 = start_struct (RECORD_TYPE, get_identifier (UTAG_METHOD_PROTOTYPE));
2617 /* struct objc_selector *_cmd; */
2618 decl_specs = tree_cons (NULL_TREE, xref_tag (RECORD_TYPE,
2619 get_identifier (TAG_SELECTOR)), NULL_TREE);
2620 field_decl = build1 (INDIRECT_REF, NULL_TREE, get_identifier ("_cmd"));
2623 = grokfield (input_filename, lineno, field_decl, decl_specs, NULL_TREE);
2624 field_decl_chain = field_decl;
2626 decl_specs = tree_cons (NULL_TREE, ridpointers[(int) RID_CHAR], NULL_TREE);
2628 = build1 (INDIRECT_REF, NULL_TREE, get_identifier ("method_types"));
2630 = grokfield (input_filename, lineno, field_decl, decl_specs, NULL_TREE);
2631 chainon (field_decl_chain, field_decl);
2633 finish_struct (proto_record, field_decl_chain, NULL_TREE);
2635 return proto_record;
2638 /* True if last call to forwarding_offset yielded a register offset. */
2639 static int offset_is_register;
2642 forwarding_offset (parm)
2645 int offset_in_bytes;
2647 if (GET_CODE (DECL_INCOMING_RTL (parm)) == MEM)
2649 rtx addr = XEXP (DECL_INCOMING_RTL (parm), 0);
2651 /* ??? Here we assume that the parm address is indexed
2652 off the frame pointer or arg pointer.
2653 If that is not true, we produce meaningless results,
2654 but do not crash. */
2655 if (GET_CODE (addr) == PLUS
2656 && GET_CODE (XEXP (addr, 1)) == CONST_INT)
2657 offset_in_bytes = INTVAL (XEXP (addr, 1));
2659 offset_in_bytes = 0;
2661 offset_in_bytes += OBJC_FORWARDING_STACK_OFFSET;
2662 offset_is_register = 0;
2664 else if (GET_CODE (DECL_INCOMING_RTL (parm)) == REG)
2666 int regno = REGNO (DECL_INCOMING_RTL (parm));
2667 offset_in_bytes = apply_args_register_offset (regno);
2668 offset_is_register = 1;
2673 /* This is the case where the parm is passed as an int or double
2674 and it is converted to a char, short or float and stored back
2675 in the parmlist. In this case, describe the parm
2676 with the variable's declared type, and adjust the address
2677 if the least significant bytes (which we are using) are not
2679 if (BYTES_BIG_ENDIAN && TREE_TYPE (parm) != DECL_ARG_TYPE (parm))
2680 offset_in_bytes += (GET_MODE_SIZE (TYPE_MODE (DECL_ARG_TYPE (parm)))
2681 - GET_MODE_SIZE (GET_MODE (DECL_RTL (parm))));
2683 return offset_in_bytes;
2687 encode_method_prototype (method_decl, func_decl)
2694 HOST_WIDE_INT max_parm_end = 0;
2698 /* ONEWAY and BYCOPY, for remote object are the only method qualifiers. */
2699 encode_type_qualifiers (TREE_PURPOSE (TREE_TYPE (method_decl)));
2702 encode_type (TREE_TYPE (TREE_TYPE (func_decl)),
2703 obstack_object_size (&util_obstack),
2704 OBJC_ENCODE_INLINE_DEFS);
2707 for (parms = DECL_ARGUMENTS (func_decl); parms;
2708 parms = TREE_CHAIN (parms))
2710 HOST_WIDE_INT parm_end = (forwarding_offset (parms)
2711 + int_size_in_bytes (TREE_TYPE (parms)));
2713 if (!offset_is_register && max_parm_end < parm_end)
2714 max_parm_end = parm_end;
2717 stack_size = max_parm_end - OBJC_FORWARDING_MIN_OFFSET;
2719 sprintf (buf, "%d", stack_size);
2720 obstack_grow (&util_obstack, buf, strlen (buf));
2722 user_args = METHOD_SEL_ARGS (method_decl);
2724 /* Argument types. */
2725 for (parms = DECL_ARGUMENTS (func_decl), i = 0; parms;
2726 parms = TREE_CHAIN (parms), i++)
2728 /* Process argument qualifiers for user supplied arguments. */
2731 encode_type_qualifiers (TREE_PURPOSE (TREE_TYPE (user_args)));
2732 user_args = TREE_CHAIN (user_args);
2736 encode_type (TREE_TYPE (parms),
2737 obstack_object_size (&util_obstack),
2738 OBJC_ENCODE_INLINE_DEFS);
2740 /* Compute offset. */
2741 sprintf (buf, "%d", forwarding_offset (parms));
2743 /* Indicate register. */
2744 if (offset_is_register)
2745 obstack_1grow (&util_obstack, '+');
2747 obstack_grow (&util_obstack, buf, strlen (buf));
2750 obstack_1grow (&util_obstack, '\0');
2751 result = get_identifier (obstack_finish (&util_obstack));
2752 obstack_free (&util_obstack, util_firstobj);
2757 generate_descriptor_table (type, name, size, list, proto)
2764 tree sc_spec, decl_specs, decl, initlist;
2766 sc_spec = tree_cons (NULL_TREE, ridpointers[(int) RID_STATIC], NULL_TREE);
2767 decl_specs = tree_cons (NULL_TREE, type, sc_spec);
2769 decl = start_decl (synth_id_with_class_suffix (name, proto),
2770 decl_specs, 1, NULL_TREE);
2771 DECL_CONTEXT (decl) = NULL_TREE;
2773 initlist = build_tree_list (NULL_TREE, build_int_2 (size, 0));
2774 initlist = tree_cons (NULL_TREE, list, initlist);
2776 finish_decl (decl, build_constructor (type, nreverse (initlist)),
2783 generate_method_descriptors (protocol)
2786 tree initlist, chain, method_list_template;
2787 tree cast, variable_length_type;
2790 if (!objc_method_prototype_template)
2791 objc_method_prototype_template = build_method_prototype_template ();
2793 cast = build_tree_list (build_tree_list (NULL_TREE, xref_tag (RECORD_TYPE,
2794 get_identifier (UTAG_METHOD_PROTOTYPE_LIST))),
2796 variable_length_type = groktypename (cast);
2798 chain = PROTOCOL_CLS_METHODS (protocol);
2801 size = list_length (chain);
2803 method_list_template
2804 = build_method_prototype_list_template (objc_method_prototype_template,
2808 = build_descriptor_table_initializer (objc_method_prototype_template,
2811 UOBJC_CLASS_METHODS_decl
2812 = generate_descriptor_table (method_list_template,
2813 "_OBJC_PROTOCOL_CLASS_METHODS",
2814 size, initlist, protocol);
2815 TREE_TYPE (UOBJC_CLASS_METHODS_decl) = variable_length_type;
2818 UOBJC_CLASS_METHODS_decl = 0;
2820 chain = PROTOCOL_NST_METHODS (protocol);
2823 size = list_length (chain);
2825 method_list_template
2826 = build_method_prototype_list_template (objc_method_prototype_template,
2829 = build_descriptor_table_initializer (objc_method_prototype_template,
2832 UOBJC_INSTANCE_METHODS_decl
2833 = generate_descriptor_table (method_list_template,
2834 "_OBJC_PROTOCOL_INSTANCE_METHODS",
2835 size, initlist, protocol);
2836 TREE_TYPE (UOBJC_INSTANCE_METHODS_decl) = variable_length_type;
2839 UOBJC_INSTANCE_METHODS_decl = 0;
2842 /* Generate a temporary FUNCTION_DECL node to be used in
2843 hack_method_prototype below. */
2846 build_tmp_function_decl ()
2848 tree decl_specs, expr_decl, parms;
2852 /* struct objc_object *objc_xxx (id, SEL, ...); */
2854 decl_specs = build_tree_list (NULL_TREE, objc_object_reference);
2855 push_parm_decl (build_tree_list
2856 (build_tree_list (decl_specs,
2857 build1 (INDIRECT_REF, NULL_TREE,
2861 decl_specs = build_tree_list (NULL_TREE, xref_tag (RECORD_TYPE,
2862 get_identifier (TAG_SELECTOR)));
2863 expr_decl = build1 (INDIRECT_REF, NULL_TREE, NULL_TREE);
2865 push_parm_decl (build_tree_list (build_tree_list (decl_specs, expr_decl),
2867 parms = get_parm_info (0);
2870 decl_specs = build_tree_list (NULL_TREE, objc_object_reference);
2871 sprintf (buffer, "__objc_tmp_%x", xxx++);
2872 expr_decl = build_nt (CALL_EXPR, get_identifier (buffer), parms, NULL_TREE);
2873 expr_decl = build1 (INDIRECT_REF, NULL_TREE, expr_decl);
2875 return define_decl (expr_decl, decl_specs);
2878 /* Generate the prototypes for protocol methods. This is used to
2879 generate method encodings for these.
2881 NST_METHODS is the method to generate a _DECL node for TMP_DECL is
2882 a decl node to be used. This is also where the return value is
2886 hack_method_prototype (nst_methods, tmp_decl)
2893 /* Hack to avoid problem with static typing of self arg. */
2894 TREE_SET_CODE (nst_methods, CLASS_METHOD_DECL);
2895 start_method_def (nst_methods);
2896 TREE_SET_CODE (nst_methods, INSTANCE_METHOD_DECL);
2898 if (METHOD_ADD_ARGS (nst_methods) == objc_ellipsis_node)
2899 parms = get_parm_info (0); /* we have a `, ...' */
2901 parms = get_parm_info (1); /* place a `void_at_end' */
2903 poplevel (0, 0, 0); /* Must be called BEFORE start_function. */
2905 /* Usually called from store_parm_decls -> init_function_start. */
2907 DECL_ARGUMENTS (tmp_decl) = TREE_PURPOSE (parms);
2909 if (current_function_decl)
2911 current_function_decl = tmp_decl;
2914 /* Code taken from start_function. */
2915 tree restype = TREE_TYPE (TREE_TYPE (tmp_decl));
2916 /* Promote the value to int before returning it. */
2917 if (TREE_CODE (restype) == INTEGER_TYPE
2918 && TYPE_PRECISION (restype) < TYPE_PRECISION (integer_type_node))
2919 restype = integer_type_node;
2920 DECL_RESULT (tmp_decl) = build_decl (RESULT_DECL, 0, restype);
2923 for (parm = DECL_ARGUMENTS (tmp_decl); parm; parm = TREE_CHAIN (parm))
2924 DECL_CONTEXT (parm) = tmp_decl;
2926 init_function_start (tmp_decl, "objc-act", 0);
2928 /* Typically called from expand_function_start for function definitions. */
2929 assign_parms (tmp_decl);
2931 /* install return type */
2932 TREE_TYPE (TREE_TYPE (tmp_decl)) = groktypename (TREE_TYPE (nst_methods));
2934 current_function_decl = NULL;
2938 generate_protocol_references (plist)
2943 /* Forward declare protocols referenced. */
2944 for (lproto = plist; lproto; lproto = TREE_CHAIN (lproto))
2946 tree proto = TREE_VALUE (lproto);
2948 if (TREE_CODE (proto) == PROTOCOL_INTERFACE_TYPE
2949 && PROTOCOL_NAME (proto))
2951 if (! PROTOCOL_FORWARD_DECL (proto))
2952 build_protocol_reference (proto);
2954 if (PROTOCOL_LIST (proto))
2955 generate_protocol_references (PROTOCOL_LIST (proto));
2961 generate_protocols ()
2963 tree p, tmp_decl, encoding;
2964 tree sc_spec, decl_specs, decl;
2965 tree initlist, protocol_name_expr, refs_decl, refs_expr;
2968 tmp_decl = build_tmp_function_decl ();
2970 if (! objc_protocol_template)
2971 objc_protocol_template = build_protocol_template ();
2973 /* If a protocol was directly referenced, pull in indirect references. */
2974 for (p = protocol_chain; p; p = TREE_CHAIN (p))
2975 if (PROTOCOL_FORWARD_DECL (p) && PROTOCOL_LIST (p))
2976 generate_protocol_references (PROTOCOL_LIST (p));
2978 for (p = protocol_chain; p; p = TREE_CHAIN (p))
2980 tree nst_methods = PROTOCOL_NST_METHODS (p);
2981 tree cls_methods = PROTOCOL_CLS_METHODS (p);
2983 /* If protocol wasn't referenced, don't generate any code. */
2984 if (! PROTOCOL_FORWARD_DECL (p))
2987 /* Make sure we link in the Protocol class. */
2988 add_class_reference (get_identifier (PROTOCOL_OBJECT_CLASS_NAME));
2992 if (! METHOD_ENCODING (nst_methods))
2994 hack_method_prototype (nst_methods, tmp_decl);
2995 encoding = encode_method_prototype (nst_methods, tmp_decl);
2996 METHOD_ENCODING (nst_methods) = encoding;
2998 nst_methods = TREE_CHAIN (nst_methods);
3003 if (! METHOD_ENCODING (cls_methods))
3005 hack_method_prototype (cls_methods, tmp_decl);
3006 encoding = encode_method_prototype (cls_methods, tmp_decl);
3007 METHOD_ENCODING (cls_methods) = encoding;
3010 cls_methods = TREE_CHAIN (cls_methods);
3012 generate_method_descriptors (p);
3014 if (PROTOCOL_LIST (p))
3015 refs_decl = generate_protocol_list (p);
3019 /* static struct objc_protocol _OBJC_PROTOCOL_<mumble>; */
3021 sc_spec = tree_cons (NULL_TREE, ridpointers[(int) RID_STATIC],
3023 decl_specs = tree_cons (NULL_TREE, objc_protocol_template, sc_spec);
3025 decl = start_decl (synth_id_with_class_suffix ("_OBJC_PROTOCOL", p),
3026 decl_specs, 1, NULL_TREE);
3028 DECL_CONTEXT (decl) = NULL_TREE;
3030 protocol_name_expr = add_objc_string (PROTOCOL_NAME (p), class_names);
3036 (build_tree_list (build_tree_list (NULL_TREE,
3037 objc_protocol_template),
3038 build1 (INDIRECT_REF, NULL_TREE,
3039 build1 (INDIRECT_REF, NULL_TREE,
3042 refs_expr = build_unary_op (ADDR_EXPR, refs_decl, 0);
3043 TREE_TYPE (refs_expr) = cast_type2;
3046 refs_expr = build_int_2 (0, 0);
3048 /* UOBJC_INSTANCE_METHODS_decl/UOBJC_CLASS_METHODS_decl are set
3049 by generate_method_descriptors, which is called above. */
3050 initlist = build_protocol_initializer (TREE_TYPE (decl),
3051 protocol_name_expr, refs_expr,
3052 UOBJC_INSTANCE_METHODS_decl,
3053 UOBJC_CLASS_METHODS_decl);
3054 finish_decl (decl, initlist, NULL_TREE);
3056 /* Mark the decl as used to avoid "defined but not used" warning. */
3057 TREE_USED (decl) = 1;
3062 build_protocol_initializer (type, protocol_name, protocol_list,
3063 instance_methods, class_methods)
3067 tree instance_methods;
3070 tree initlist = NULL_TREE, expr;
3073 cast_type = groktypename
3075 (build_tree_list (NULL_TREE,
3076 xref_tag (RECORD_TYPE,
3077 get_identifier (UTAG_CLASS))),
3078 build1 (INDIRECT_REF, NULL_TREE, NULL_TREE)));
3080 /* Filling the "isa" in with one allows the runtime system to
3081 detect that the version change...should remove before final release. */
3083 expr = build_int_2 (PROTOCOL_VERSION, 0);
3084 TREE_TYPE (expr) = cast_type;
3085 initlist = tree_cons (NULL_TREE, expr, initlist);
3086 initlist = tree_cons (NULL_TREE, protocol_name, initlist);
3087 initlist = tree_cons (NULL_TREE, protocol_list, initlist);
3089 if (!instance_methods)
3090 initlist = tree_cons (NULL_TREE, build_int_2 (0, 0), initlist);
3093 expr = build_unary_op (ADDR_EXPR, instance_methods, 0);
3094 initlist = tree_cons (NULL_TREE, expr, initlist);
3098 initlist = tree_cons (NULL_TREE, build_int_2 (0, 0), initlist);
3101 expr = build_unary_op (ADDR_EXPR, class_methods, 0);
3102 initlist = tree_cons (NULL_TREE, expr, initlist);
3105 return build_constructor (type, nreverse (initlist));
3108 /* struct objc_category {
3109 char *category_name;
3111 struct objc_method_list *instance_methods;
3112 struct objc_method_list *class_methods;
3113 struct objc_protocol_list *protocols;
3117 build_category_template ()
3119 tree decl_specs, field_decl, field_decl_chain;
3121 objc_category_template = start_struct (RECORD_TYPE,
3122 get_identifier (UTAG_CATEGORY));
3123 /* char *category_name; */
3125 decl_specs = build_tree_list (NULL_TREE, ridpointers[(int) RID_CHAR]);
3127 = build1 (INDIRECT_REF, NULL_TREE, get_identifier ("category_name"));
3129 = grokfield (input_filename, lineno, field_decl, decl_specs, NULL_TREE);
3130 field_decl_chain = field_decl;
3132 /* char *class_name; */
3134 decl_specs = build_tree_list (NULL_TREE, ridpointers[(int) RID_CHAR]);
3135 field_decl = build1 (INDIRECT_REF, NULL_TREE, get_identifier ("class_name"));
3137 = grokfield (input_filename, lineno, field_decl, decl_specs, NULL_TREE);
3138 chainon (field_decl_chain, field_decl);
3140 /* struct objc_method_list *instance_methods; */
3142 decl_specs = build_tree_list (NULL_TREE,
3143 xref_tag (RECORD_TYPE,
3144 get_identifier (UTAG_METHOD_LIST)));
3146 = build1 (INDIRECT_REF, NULL_TREE, get_identifier ("instance_methods"));
3148 = grokfield (input_filename, lineno, field_decl, decl_specs, NULL_TREE);
3149 chainon (field_decl_chain, field_decl);
3151 /* struct objc_method_list *class_methods; */
3153 decl_specs = build_tree_list (NULL_TREE,
3154 xref_tag (RECORD_TYPE,
3155 get_identifier (UTAG_METHOD_LIST)));
3157 = build1 (INDIRECT_REF, NULL_TREE, get_identifier ("class_methods"));
3159 = grokfield (input_filename, lineno, field_decl, decl_specs, NULL_TREE);
3160 chainon (field_decl_chain, field_decl);
3162 /* struct objc_protocol **protocol_list; */
3164 decl_specs = build_tree_list (NULL_TREE,
3165 xref_tag (RECORD_TYPE,
3166 get_identifier (UTAG_PROTOCOL)));
3168 = build1 (INDIRECT_REF, NULL_TREE, get_identifier ("protocol_list"));
3169 field_decl = build1 (INDIRECT_REF, NULL_TREE, field_decl);
3171 = grokfield (input_filename, lineno, field_decl, decl_specs, NULL_TREE);
3172 chainon (field_decl_chain, field_decl);
3174 finish_struct (objc_category_template, field_decl_chain, NULL_TREE);
3177 /* struct objc_selector {
3183 build_selector_template ()
3186 tree decl_specs, field_decl, field_decl_chain;
3188 objc_selector_template
3189 = start_struct (RECORD_TYPE, get_identifier (UTAG_SELECTOR));
3193 decl_specs = build_tree_list (NULL_TREE, ridpointers[(int) RID_VOID]);
3194 field_decl = build1 (INDIRECT_REF, NULL_TREE, get_identifier ("sel_id"));
3196 = grokfield (input_filename, lineno, field_decl, decl_specs, NULL_TREE);
3197 field_decl_chain = field_decl;
3199 /* char *sel_type; */
3201 decl_specs = build_tree_list (NULL_TREE, ridpointers[(int) RID_CHAR]);
3202 field_decl = build1 (INDIRECT_REF, NULL_TREE, get_identifier ("sel_type"));
3204 = grokfield (input_filename, lineno, field_decl, decl_specs, NULL_TREE);
3205 chainon (field_decl_chain, field_decl);
3207 finish_struct (objc_selector_template, field_decl_chain, NULL_TREE);
3210 /* struct objc_class {
3211 struct objc_class *isa;
3212 struct objc_class *super_class;
3217 struct objc_ivar_list *ivars;
3218 struct objc_method_list *methods;
3219 if (flag_next_runtime)
3220 struct objc_cache *cache;
3222 struct sarray *dtable;
3223 struct objc_class *subclass_list;
3224 struct objc_class *sibling_class;
3226 struct objc_protocol_list *protocols;
3227 void *gc_object_type;
3231 build_class_template ()
3233 tree decl_specs, field_decl, field_decl_chain;
3236 = start_struct (RECORD_TYPE, get_identifier (UTAG_CLASS));
3238 /* struct objc_class *isa; */
3240 decl_specs = build_tree_list (NULL_TREE, objc_class_template);
3241 field_decl = build1 (INDIRECT_REF, NULL_TREE, get_identifier ("isa"));
3243 = grokfield (input_filename, lineno, field_decl, decl_specs, NULL_TREE);
3244 field_decl_chain = field_decl;
3246 /* struct objc_class *super_class; */
3248 decl_specs = build_tree_list (NULL_TREE, objc_class_template);
3250 = build1 (INDIRECT_REF, NULL_TREE, get_identifier ("super_class"));
3252 = grokfield (input_filename, lineno, field_decl, decl_specs, NULL_TREE);
3253 chainon (field_decl_chain, field_decl);
3257 decl_specs = build_tree_list (NULL_TREE, ridpointers[(int) RID_CHAR]);
3258 field_decl = build1 (INDIRECT_REF, NULL_TREE, get_identifier ("name"));
3260 = grokfield (input_filename, lineno, field_decl, decl_specs, NULL_TREE);
3261 chainon (field_decl_chain, field_decl);
3265 decl_specs = build_tree_list (NULL_TREE, ridpointers[(int) RID_LONG]);
3266 field_decl = get_identifier ("version");
3268 = grokfield (input_filename, lineno, field_decl, decl_specs, NULL_TREE);
3269 chainon (field_decl_chain, field_decl);
3273 decl_specs = build_tree_list (NULL_TREE, ridpointers[(int) RID_LONG]);
3274 field_decl = get_identifier ("info");
3276 = grokfield (input_filename, lineno, field_decl, decl_specs, NULL_TREE);
3277 chainon (field_decl_chain, field_decl);
3279 /* long instance_size; */
3281 decl_specs = build_tree_list (NULL_TREE, ridpointers[(int) RID_LONG]);
3282 field_decl = get_identifier ("instance_size");
3284 = grokfield (input_filename, lineno, field_decl, decl_specs, NULL_TREE);
3285 chainon (field_decl_chain, field_decl);
3287 /* struct objc_ivar_list *ivars; */
3289 decl_specs = build_tree_list (NULL_TREE,
3290 xref_tag (RECORD_TYPE,
3291 get_identifier (UTAG_IVAR_LIST)));
3292 field_decl = build1 (INDIRECT_REF, NULL_TREE, get_identifier ("ivars"));
3294 = grokfield (input_filename, lineno, field_decl, decl_specs, NULL_TREE);
3295 chainon (field_decl_chain, field_decl);
3297 /* struct objc_method_list *methods; */
3299 decl_specs = build_tree_list (NULL_TREE,
3300 xref_tag (RECORD_TYPE,
3301 get_identifier (UTAG_METHOD_LIST)));
3302 field_decl = build1 (INDIRECT_REF, NULL_TREE, get_identifier ("methods"));
3304 = grokfield (input_filename, lineno, field_decl, decl_specs, NULL_TREE);
3305 chainon (field_decl_chain, field_decl);
3307 if (flag_next_runtime)
3309 /* struct objc_cache *cache; */
3311 decl_specs = build_tree_list (NULL_TREE,
3312 xref_tag (RECORD_TYPE,
3313 get_identifier ("objc_cache")));
3314 field_decl = build1 (INDIRECT_REF, NULL_TREE, get_identifier ("cache"));
3315 field_decl = grokfield (input_filename, lineno, field_decl,
3316 decl_specs, NULL_TREE);
3317 chainon (field_decl_chain, field_decl);
3321 /* struct sarray *dtable; */
3323 decl_specs = build_tree_list (NULL_TREE,
3324 xref_tag (RECORD_TYPE,
3325 get_identifier ("sarray")));
3326 field_decl = build1 (INDIRECT_REF, NULL_TREE, get_identifier ("dtable"));
3327 field_decl = grokfield (input_filename, lineno, field_decl,
3328 decl_specs, NULL_TREE);
3329 chainon (field_decl_chain, field_decl);
3331 /* struct objc_class *subclass_list; */
3333 decl_specs = build_tree_list (NULL_TREE, objc_class_template);
3335 = build1 (INDIRECT_REF, NULL_TREE, get_identifier ("subclass_list"));
3336 field_decl = grokfield (input_filename, lineno, field_decl,
3337 decl_specs, NULL_TREE);
3338 chainon (field_decl_chain, field_decl);
3340 /* struct objc_class *sibling_class; */
3342 decl_specs = build_tree_list (NULL_TREE, objc_class_template);
3344 = build1 (INDIRECT_REF, NULL_TREE, get_identifier ("sibling_class"));
3345 field_decl = grokfield (input_filename, lineno, field_decl,
3346 decl_specs, NULL_TREE);
3347 chainon (field_decl_chain, field_decl);
3350 /* struct objc_protocol **protocol_list; */
3352 decl_specs = build_tree_list (NULL_TREE,
3353 xref_tag (RECORD_TYPE,
3354 get_identifier (UTAG_PROTOCOL)));
3356 = build1 (INDIRECT_REF, NULL_TREE, get_identifier ("protocol_list"));
3358 = build1 (INDIRECT_REF, NULL_TREE, field_decl);
3359 field_decl = grokfield (input_filename, lineno, field_decl,
3360 decl_specs, NULL_TREE);
3361 chainon (field_decl_chain, field_decl);
3365 decl_specs = build_tree_list (NULL_TREE, ridpointers[(int) RID_VOID]);
3366 field_decl = build1 (INDIRECT_REF, NULL_TREE, get_identifier ("sel_id"));
3368 = grokfield (input_filename, lineno, field_decl, decl_specs, NULL_TREE);
3369 chainon (field_decl_chain, field_decl);
3371 /* void *gc_object_type; */
3373 decl_specs = build_tree_list (NULL_TREE, ridpointers[(int) RID_VOID]);
3374 field_decl = build1 (INDIRECT_REF, NULL_TREE, get_identifier ("gc_object_type"));
3376 = grokfield (input_filename, lineno, field_decl, decl_specs, NULL_TREE);
3377 chainon (field_decl_chain, field_decl);
3379 finish_struct (objc_class_template, field_decl_chain, NULL_TREE);
3382 /* Generate appropriate forward declarations for an implementation. */
3385 synth_forward_declarations ()
3387 tree sc_spec, decl_specs, an_id;
3389 /* extern struct objc_class _OBJC_CLASS_<my_name>; */
3391 an_id = synth_id_with_class_suffix ("_OBJC_CLASS", objc_implementation_context);
3393 sc_spec = build_tree_list (NULL_TREE, ridpointers[(int) RID_EXTERN]);
3394 decl_specs = tree_cons (NULL_TREE, objc_class_template, sc_spec);
3395 UOBJC_CLASS_decl = define_decl (an_id, decl_specs);
3396 TREE_USED (UOBJC_CLASS_decl) = 1;
3397 DECL_ARTIFICIAL (UOBJC_CLASS_decl) = 1;
3399 /* extern struct objc_class _OBJC_METACLASS_<my_name>; */
3401 an_id = synth_id_with_class_suffix ("_OBJC_METACLASS",
3402 objc_implementation_context);
3404 UOBJC_METACLASS_decl = define_decl (an_id, decl_specs);
3405 TREE_USED (UOBJC_METACLASS_decl) = 1;
3406 DECL_ARTIFICIAL(UOBJC_METACLASS_decl) = 1;
3408 /* Pre-build the following entities - for speed/convenience. */
3410 an_id = get_identifier ("super_class");
3411 ucls_super_ref = build_component_ref (UOBJC_CLASS_decl, an_id);
3412 uucls_super_ref = build_component_ref (UOBJC_METACLASS_decl, an_id);
3416 error_with_ivar (message, decl, rawdecl)
3417 const char *message;
3421 diagnostic_count_diagnostic (global_dc, DK_ERROR);
3423 diagnostic_report_current_function (global_dc);
3425 error_with_file_and_line (DECL_SOURCE_FILE (decl),
3426 DECL_SOURCE_LINE (decl),
3428 message, gen_declaration (rawdecl, errbuf));
3433 check_ivars (inter, imp)
3437 tree intdecls = CLASS_IVARS (inter);
3438 tree impdecls = CLASS_IVARS (imp);
3439 tree rawintdecls = CLASS_RAW_IVARS (inter);
3440 tree rawimpdecls = CLASS_RAW_IVARS (imp);
3446 if (intdecls == 0 && impdecls == 0)
3448 if (intdecls == 0 || impdecls == 0)
3450 error ("inconsistent instance variable specification");
3454 t1 = TREE_TYPE (intdecls); t2 = TREE_TYPE (impdecls);
3456 if (!comptypes (t1, t2))
3458 if (DECL_NAME (intdecls) == DECL_NAME (impdecls))
3460 error_with_ivar ("conflicting instance variable type",
3461 impdecls, rawimpdecls);
3462 error_with_ivar ("previous declaration of",
3463 intdecls, rawintdecls);
3465 else /* both the type and the name don't match */
3467 error ("inconsistent instance variable specification");
3472 else if (DECL_NAME (intdecls) != DECL_NAME (impdecls))
3474 error_with_ivar ("conflicting instance variable name",
3475 impdecls, rawimpdecls);
3476 error_with_ivar ("previous declaration of",
3477 intdecls, rawintdecls);
3480 intdecls = TREE_CHAIN (intdecls);
3481 impdecls = TREE_CHAIN (impdecls);
3482 rawintdecls = TREE_CHAIN (rawintdecls);
3483 rawimpdecls = TREE_CHAIN (rawimpdecls);
3487 /* Set super_type to the data type node for struct objc_super *,
3488 first defining struct objc_super itself.
3489 This needs to be done just once per compilation. */
3492 build_super_template ()
3494 tree record, decl_specs, field_decl, field_decl_chain;
3496 record = start_struct (RECORD_TYPE, get_identifier (UTAG_SUPER));
3498 /* struct objc_object *self; */
3500 decl_specs = build_tree_list (NULL_TREE, objc_object_reference);
3501 field_decl = get_identifier ("self");
3502 field_decl = build1 (INDIRECT_REF, NULL_TREE, field_decl);
3503 field_decl = grokfield (input_filename, lineno,
3504 field_decl, decl_specs, NULL_TREE);
3505 field_decl_chain = field_decl;
3507 /* struct objc_class *class; */
3509 decl_specs = get_identifier (UTAG_CLASS);
3510 decl_specs = build_tree_list (NULL_TREE, xref_tag (RECORD_TYPE, decl_specs));
3511 field_decl = build1 (INDIRECT_REF, NULL_TREE, get_identifier ("class"));
3513 field_decl = grokfield (input_filename, lineno,
3514 field_decl, decl_specs, NULL_TREE);
3515 chainon (field_decl_chain, field_decl);
3517 finish_struct (record, field_decl_chain, NULL_TREE);
3519 /* `struct objc_super *' */
3520 super_type = groktypename (build_tree_list (build_tree_list (NULL_TREE,
3522 build1 (INDIRECT_REF,
3523 NULL_TREE, NULL_TREE)));
3527 /* struct objc_ivar {
3534 build_ivar_template ()
3536 tree objc_ivar_id, objc_ivar_record;
3537 tree decl_specs, field_decl, field_decl_chain;
3539 objc_ivar_id = get_identifier (UTAG_IVAR);
3540 objc_ivar_record = start_struct (RECORD_TYPE, objc_ivar_id);
3542 /* char *ivar_name; */
3544 decl_specs = build_tree_list (NULL_TREE, ridpointers[(int) RID_CHAR]);
3545 field_decl = build1 (INDIRECT_REF, NULL_TREE, get_identifier ("ivar_name"));
3547 field_decl = grokfield (input_filename, lineno, field_decl,
3548 decl_specs, NULL_TREE);
3549 field_decl_chain = field_decl;
3551 /* char *ivar_type; */
3553 decl_specs = build_tree_list (NULL_TREE, ridpointers[(int) RID_CHAR]);
3554 field_decl = build1 (INDIRECT_REF, NULL_TREE, get_identifier ("ivar_type"));
3556 field_decl = grokfield (input_filename, lineno, field_decl,
3557 decl_specs, NULL_TREE);
3558 chainon (field_decl_chain, field_decl);
3560 /* int ivar_offset; */
3562 decl_specs = build_tree_list (NULL_TREE, ridpointers[(int) RID_INT]);
3563 field_decl = get_identifier ("ivar_offset");
3565 field_decl = grokfield (input_filename, lineno, field_decl,
3566 decl_specs, NULL_TREE);
3567 chainon (field_decl_chain, field_decl);
3569 finish_struct (objc_ivar_record, field_decl_chain, NULL_TREE);
3571 return objc_ivar_record;
3576 struct objc_ivar ivar_list[ivar_count];
3580 build_ivar_list_template (list_type, size)
3584 tree objc_ivar_list_record;
3585 tree decl_specs, field_decl, field_decl_chain;
3587 objc_ivar_list_record = start_struct (RECORD_TYPE, NULL_TREE);
3589 /* int ivar_count; */
3591 decl_specs = build_tree_list (NULL_TREE, ridpointers[(int) RID_INT]);
3592 field_decl = get_identifier ("ivar_count");
3594 field_decl = grokfield (input_filename, lineno, field_decl,
3595 decl_specs, NULL_TREE);
3596 field_decl_chain = field_decl;
3598 /* struct objc_ivar ivar_list[]; */
3600 decl_specs = build_tree_list (NULL_TREE, list_type);
3601 field_decl = build_nt (ARRAY_REF, get_identifier ("ivar_list"),
3602 build_int_2 (size, 0));
3604 field_decl = grokfield (input_filename, lineno,
3605 field_decl, decl_specs, NULL_TREE);
3606 chainon (field_decl_chain, field_decl);
3608 finish_struct (objc_ivar_list_record, field_decl_chain, NULL_TREE);
3610 return objc_ivar_list_record;
3616 struct objc_method method_list[method_count];
3620 build_method_list_template (list_type, size)
3624 tree objc_ivar_list_record;
3625 tree decl_specs, field_decl, field_decl_chain;
3627 objc_ivar_list_record = start_struct (RECORD_TYPE, NULL_TREE);
3629 /* int method_next; */
3634 xref_tag (RECORD_TYPE,
3635 get_identifier (UTAG_METHOD_PROTOTYPE_LIST)));
3637 = build1 (INDIRECT_REF, NULL_TREE, get_identifier ("method_next"));
3638 field_decl = grokfield (input_filename, lineno, field_decl,
3639 decl_specs, NULL_TREE);
3640 field_decl_chain = field_decl;
3642 /* int method_count; */
3644 decl_specs = build_tree_list (NULL_TREE, ridpointers[(int) RID_INT]);
3645 field_decl = get_identifier ("method_count");
3647 field_decl = grokfield (input_filename, lineno,
3648 field_decl, decl_specs, NULL_TREE);
3649 chainon (field_decl_chain, field_decl);
3651 /* struct objc_method method_list[]; */
3653 decl_specs = build_tree_list (NULL_TREE, list_type);
3654 field_decl = build_nt (ARRAY_REF, get_identifier ("method_list"),
3655 build_int_2 (size, 0));
3657 field_decl = grokfield (input_filename, lineno,
3658 field_decl, decl_specs, NULL_TREE);
3659 chainon (field_decl_chain, field_decl);
3661 finish_struct (objc_ivar_list_record, field_decl_chain, NULL_TREE);
3663 return objc_ivar_list_record;
3667 build_ivar_list_initializer (type, field_decl)
3671 tree initlist = NULL_TREE;
3675 tree ivar = NULL_TREE;
3678 if (DECL_NAME (field_decl))
3679 ivar = tree_cons (NULL_TREE,
3680 add_objc_string (DECL_NAME (field_decl),
3684 /* Unnamed bit-field ivar (yuck). */
3685 ivar = tree_cons (NULL_TREE, build_int_2 (0, 0), ivar);
3688 encode_field_decl (field_decl,
3689 obstack_object_size (&util_obstack),
3690 OBJC_ENCODE_DONT_INLINE_DEFS);
3692 /* Null terminate string. */
3693 obstack_1grow (&util_obstack, 0);
3697 add_objc_string (get_identifier (obstack_finish (&util_obstack)),
3700 obstack_free (&util_obstack, util_firstobj);
3703 ivar = tree_cons (NULL_TREE, byte_position (field_decl), ivar);
3704 initlist = tree_cons (NULL_TREE,
3705 build_constructor (type, nreverse (ivar)),
3708 field_decl = TREE_CHAIN (field_decl);
3712 return build_constructor (build_array_type (type, 0), nreverse (initlist));
3716 generate_ivars_list (type, name, size, list)
3722 tree sc_spec, decl_specs, decl, initlist;
3724 sc_spec = tree_cons (NULL_TREE, ridpointers[(int) RID_STATIC], NULL_TREE);
3725 decl_specs = tree_cons (NULL_TREE, type, sc_spec);
3727 decl = start_decl (synth_id_with_class_suffix (name, objc_implementation_context),
3728 decl_specs, 1, NULL_TREE);
3730 initlist = build_tree_list (NULL_TREE, build_int_2 (size, 0));
3731 initlist = tree_cons (NULL_TREE, list, initlist);
3734 build_constructor (TREE_TYPE (decl), nreverse (initlist)),
3741 generate_ivar_lists ()
3743 tree initlist, ivar_list_template, chain;
3744 tree cast, variable_length_type;
3747 generating_instance_variables = 1;
3749 if (!objc_ivar_template)
3750 objc_ivar_template = build_ivar_template ();
3754 (build_tree_list (NULL_TREE, xref_tag (RECORD_TYPE,
3755 get_identifier (UTAG_IVAR_LIST))),
3757 variable_length_type = groktypename (cast);
3759 /* Only generate class variables for the root of the inheritance
3760 hierarchy since these will be the same for every class. */
3762 if (CLASS_SUPER_NAME (implementation_template) == NULL_TREE
3763 && (chain = TYPE_FIELDS (objc_class_template)))
3765 size = list_length (chain);
3767 ivar_list_template = build_ivar_list_template (objc_ivar_template, size);
3768 initlist = build_ivar_list_initializer (objc_ivar_template, chain);
3770 UOBJC_CLASS_VARIABLES_decl
3771 = generate_ivars_list (ivar_list_template, "_OBJC_CLASS_VARIABLES",
3773 TREE_TYPE (UOBJC_CLASS_VARIABLES_decl) = variable_length_type;
3776 UOBJC_CLASS_VARIABLES_decl = 0;
3778 chain = CLASS_IVARS (implementation_template);
3781 size = list_length (chain);
3782 ivar_list_template = build_ivar_list_template (objc_ivar_template, size);
3783 initlist = build_ivar_list_initializer (objc_ivar_template, chain);
3785 UOBJC_INSTANCE_VARIABLES_decl
3786 = generate_ivars_list (ivar_list_template, "_OBJC_INSTANCE_VARIABLES",
3788 TREE_TYPE (UOBJC_INSTANCE_VARIABLES_decl) = variable_length_type;
3791 UOBJC_INSTANCE_VARIABLES_decl = 0;
3793 generating_instance_variables = 0;
3797 build_dispatch_table_initializer (type, entries)
3801 tree initlist = NULL_TREE;
3805 tree elemlist = NULL_TREE;
3807 elemlist = tree_cons (NULL_TREE,
3808 build_selector (METHOD_SEL_NAME (entries)),
3811 /* Generate the method encoding if we don't have one already. */
3812 if (! METHOD_ENCODING (entries))
3813 METHOD_ENCODING (entries) =
3814 encode_method_def (METHOD_DEFINITION (entries));
3816 elemlist = tree_cons (NULL_TREE,
3817 add_objc_string (METHOD_ENCODING (entries),
3821 elemlist = tree_cons (NULL_TREE,
3822 build_unary_op (ADDR_EXPR,
3823 METHOD_DEFINITION (entries), 1),
3826 initlist = tree_cons (NULL_TREE,
3827 build_constructor (type, nreverse (elemlist)),
3830 entries = TREE_CHAIN (entries);
3834 return build_constructor (build_array_type (type, 0), nreverse (initlist));
3837 /* To accomplish method prototyping without generating all kinds of
3838 inane warnings, the definition of the dispatch table entries were
3841 struct objc_method { SEL _cmd; ...; id (*_imp)(); };
3843 struct objc_method { SEL _cmd; ...; void *_imp; }; */
3846 build_method_template ()
3849 tree decl_specs, field_decl, field_decl_chain;
3851 _SLT_record = start_struct (RECORD_TYPE, get_identifier (UTAG_METHOD));
3853 /* struct objc_selector *_cmd; */
3854 decl_specs = tree_cons (NULL_TREE,
3855 xref_tag (RECORD_TYPE,
3856 get_identifier (TAG_SELECTOR)),
3858 field_decl = build1 (INDIRECT_REF, NULL_TREE, get_identifier ("_cmd"));
3860 field_decl = grokfield (input_filename, lineno, field_decl,
3861 decl_specs, NULL_TREE);
3862 field_decl_chain = field_decl;
3864 decl_specs = tree_cons (NULL_TREE, ridpointers[(int) RID_CHAR], NULL_TREE);
3865 field_decl = build1 (INDIRECT_REF, NULL_TREE,
3866 get_identifier ("method_types"));
3867 field_decl = grokfield (input_filename, lineno, field_decl,
3868 decl_specs, NULL_TREE);
3869 chainon (field_decl_chain, field_decl);
3873 decl_specs = tree_cons (NULL_TREE, ridpointers[(int) RID_VOID], NULL_TREE);
3874 field_decl = build1 (INDIRECT_REF, NULL_TREE, get_identifier ("_imp"));
3875 field_decl = grokfield (input_filename, lineno, field_decl,
3876 decl_specs, NULL_TREE);
3877 chainon (field_decl_chain, field_decl);
3879 finish_struct (_SLT_record, field_decl_chain, NULL_TREE);
3886 generate_dispatch_table (type, name, size, list)
3892 tree sc_spec, decl_specs, decl, initlist;
3894 sc_spec = tree_cons (NULL_TREE, ridpointers[(int) RID_STATIC], NULL_TREE);
3895 decl_specs = tree_cons (NULL_TREE, type, sc_spec);
3897 decl = start_decl (synth_id_with_class_suffix (name, objc_implementation_context),
3898 decl_specs, 1, NULL_TREE);
3900 initlist = build_tree_list (NULL_TREE, build_int_2 (0, 0));
3901 initlist = tree_cons (NULL_TREE, build_int_2 (size, 0), initlist);
3902 initlist = tree_cons (NULL_TREE, list, initlist);
3905 build_constructor (TREE_TYPE (decl), nreverse (initlist)),
3912 generate_dispatch_tables ()
3914 tree initlist, chain, method_list_template;
3915 tree cast, variable_length_type;
3918 if (!objc_method_template)
3919 objc_method_template = build_method_template ();
3923 (build_tree_list (NULL_TREE,
3924 xref_tag (RECORD_TYPE,
3925 get_identifier (UTAG_METHOD_LIST))),
3928 variable_length_type = groktypename (cast);
3930 chain = CLASS_CLS_METHODS (objc_implementation_context);
3933 size = list_length (chain);
3935 method_list_template
3936 = build_method_list_template (objc_method_template, size);
3938 = build_dispatch_table_initializer (objc_method_template, chain);
3940 UOBJC_CLASS_METHODS_decl
3941 = generate_dispatch_table (method_list_template,
3942 ((TREE_CODE (objc_implementation_context)
3943 == CLASS_IMPLEMENTATION_TYPE)
3944 ? "_OBJC_CLASS_METHODS"
3945 : "_OBJC_CATEGORY_CLASS_METHODS"),
3947 TREE_TYPE (UOBJC_CLASS_METHODS_decl) = variable_length_type;
3950 UOBJC_CLASS_METHODS_decl = 0;
3952 chain = CLASS_NST_METHODS (objc_implementation_context);
3955 size = list_length (chain);
3957 method_list_template
3958 = build_method_list_template (objc_method_template, size);
3960 = build_dispatch_table_initializer (objc_method_template, chain);
3962 if (TREE_CODE (objc_implementation_context) == CLASS_IMPLEMENTATION_TYPE)
3963 UOBJC_INSTANCE_METHODS_decl
3964 = generate_dispatch_table (method_list_template,
3965 "_OBJC_INSTANCE_METHODS",
3968 /* We have a category. */
3969 UOBJC_INSTANCE_METHODS_decl
3970 = generate_dispatch_table (method_list_template,
3971 "_OBJC_CATEGORY_INSTANCE_METHODS",
3973 TREE_TYPE (UOBJC_INSTANCE_METHODS_decl) = variable_length_type;
3976 UOBJC_INSTANCE_METHODS_decl = 0;
3980 generate_protocol_list (i_or_p)
3983 tree initlist, decl_specs, sc_spec;
3984 tree refs_decl, expr_decl, lproto, e, plist;
3988 if (TREE_CODE (i_or_p) == CLASS_INTERFACE_TYPE
3989 || TREE_CODE (i_or_p) == CATEGORY_INTERFACE_TYPE)
3990 plist = CLASS_PROTOCOL_LIST (i_or_p);
3991 else if (TREE_CODE (i_or_p) == PROTOCOL_INTERFACE_TYPE)
3992 plist = PROTOCOL_LIST (i_or_p);
3996 cast_type = groktypename
3998 (build_tree_list (NULL_TREE,
3999 xref_tag (RECORD_TYPE,
4000 get_identifier (UTAG_PROTOCOL))),
4001 build1 (INDIRECT_REF, NULL_TREE, NULL_TREE)));
4004 for (lproto = plist; lproto; lproto = TREE_CHAIN (lproto))
4005 if (TREE_CODE (TREE_VALUE (lproto)) == PROTOCOL_INTERFACE_TYPE
4006 && PROTOCOL_FORWARD_DECL (TREE_VALUE (lproto)))
4009 /* Build initializer. */
4010 initlist = tree_cons (NULL_TREE, build_int_2 (0, 0), NULL_TREE);
4012 e = build_int_2 (size, 0);
4013 TREE_TYPE (e) = cast_type;
4014 initlist = tree_cons (NULL_TREE, e, initlist);
4016 for (lproto = plist; lproto; lproto = TREE_CHAIN (lproto))
4018 tree pval = TREE_VALUE (lproto);
4020 if (TREE_CODE (pval) == PROTOCOL_INTERFACE_TYPE
4021 && PROTOCOL_FORWARD_DECL (pval))
4023 e = build_unary_op (ADDR_EXPR, PROTOCOL_FORWARD_DECL (pval), 0);
4024 initlist = tree_cons (NULL_TREE, e, initlist);
4028 /* static struct objc_protocol *refs[n]; */
4030 sc_spec = tree_cons (NULL_TREE, ridpointers[(int) RID_STATIC], NULL_TREE);
4031 decl_specs = tree_cons (NULL_TREE, xref_tag (RECORD_TYPE,
4032 get_identifier (UTAG_PROTOCOL)),
4035 if (TREE_CODE (i_or_p) == PROTOCOL_INTERFACE_TYPE)
4036 expr_decl = build_nt (ARRAY_REF,
4037 synth_id_with_class_suffix ("_OBJC_PROTOCOL_REFS",
4039 build_int_2 (size + 2, 0));
4040 else if (TREE_CODE (i_or_p) == CLASS_INTERFACE_TYPE)
4041 expr_decl = build_nt (ARRAY_REF,
4042 synth_id_with_class_suffix ("_OBJC_CLASS_PROTOCOLS",
4044 build_int_2 (size + 2, 0));
4045 else if (TREE_CODE (i_or_p) == CATEGORY_INTERFACE_TYPE)
4047 = build_nt (ARRAY_REF,
4048 synth_id_with_class_suffix ("_OBJC_CATEGORY_PROTOCOLS",
4050 build_int_2 (size + 2, 0));
4054 expr_decl = build1 (INDIRECT_REF, NULL_TREE, expr_decl);
4056 refs_decl = start_decl (expr_decl, decl_specs, 1, NULL_TREE);
4057 DECL_CONTEXT (refs_decl) = NULL_TREE;
4059 finish_decl (refs_decl, build_constructor (TREE_TYPE (refs_decl),
4060 nreverse (initlist)),
4067 build_category_initializer (type, cat_name, class_name,
4068 instance_methods, class_methods, protocol_list)
4072 tree instance_methods;
4076 tree initlist = NULL_TREE, expr;
4078 initlist = tree_cons (NULL_TREE, cat_name, initlist);
4079 initlist = tree_cons (NULL_TREE, class_name, initlist);
4081 if (!instance_methods)
4082 initlist = tree_cons (NULL_TREE, build_int_2 (0, 0), initlist);
4085 expr = build_unary_op (ADDR_EXPR, instance_methods, 0);
4086 initlist = tree_cons (NULL_TREE, expr, initlist);
4089 initlist = tree_cons (NULL_TREE, build_int_2 (0, 0), initlist);
4092 expr = build_unary_op (ADDR_EXPR, class_methods, 0);
4093 initlist = tree_cons (NULL_TREE, expr, initlist);
4096 /* protocol_list = */
4098 initlist = tree_cons (NULL_TREE, build_int_2 (0, 0), initlist);
4101 tree cast_type2 = groktypename
4103 (build_tree_list (NULL_TREE,
4104 xref_tag (RECORD_TYPE,
4105 get_identifier (UTAG_PROTOCOL))),
4106 build1 (INDIRECT_REF, NULL_TREE,
4107 build1 (INDIRECT_REF, NULL_TREE, NULL_TREE))));
4109 expr = build_unary_op (ADDR_EXPR, protocol_list, 0);
4110 TREE_TYPE (expr) = cast_type2;
4111 initlist = tree_cons (NULL_TREE, expr, initlist);
4114 return build_constructor (type, nreverse (initlist));
4117 /* struct objc_class {
4118 struct objc_class *isa;
4119 struct objc_class *super_class;
4124 struct objc_ivar_list *ivars;
4125 struct objc_method_list *methods;
4126 if (flag_next_runtime)
4127 struct objc_cache *cache;
4129 struct sarray *dtable;
4130 struct objc_class *subclass_list;
4131 struct objc_class *sibling_class;
4133 struct objc_protocol_list *protocols;
4134 void *gc_object_type;
4138 build_shared_structure_initializer (type, isa, super, name, size, status,
4139 dispatch_table, ivar_list, protocol_list)
4146 tree dispatch_table;
4150 tree initlist = NULL_TREE, expr;
4153 initlist = tree_cons (NULL_TREE, isa, initlist);
4156 initlist = tree_cons (NULL_TREE, super, initlist);
4159 initlist = tree_cons (NULL_TREE, default_conversion (name), initlist);
4162 initlist = tree_cons (NULL_TREE, build_int_2 (0, 0), initlist);
4165 initlist = tree_cons (NULL_TREE, build_int_2 (status, 0), initlist);
4167 /* instance_size = */
4168 initlist = tree_cons (NULL_TREE, size, initlist);
4170 /* objc_ivar_list = */
4172 initlist = tree_cons (NULL_TREE, build_int_2 (0, 0), initlist);
4175 expr = build_unary_op (ADDR_EXPR, ivar_list, 0);
4176 initlist = tree_cons (NULL_TREE, expr, initlist);
4179 /* objc_method_list = */
4180 if (!dispatch_table)
4181 initlist = tree_cons (NULL_TREE, build_int_2 (0, 0), initlist);
4184 expr = build_unary_op (ADDR_EXPR, dispatch_table, 0);
4185 initlist = tree_cons (NULL_TREE, expr, initlist);
4188 if (flag_next_runtime)
4189 /* method_cache = */
4190 initlist = tree_cons (NULL_TREE, build_int_2 (0, 0), initlist);
4194 initlist = tree_cons (NULL_TREE, build_int_2 (0, 0), initlist);
4196 /* subclass_list = */
4197 initlist = tree_cons (NULL_TREE, build_int_2 (0, 0), initlist);
4199 /* sibling_class = */
4200 initlist = tree_cons (NULL_TREE, build_int_2 (0, 0), initlist);
4203 /* protocol_list = */
4204 if (! protocol_list)
4205 initlist = tree_cons (NULL_TREE, build_int_2 (0, 0), initlist);
4211 (build_tree_list (NULL_TREE,
4212 xref_tag (RECORD_TYPE,
4213 get_identifier (UTAG_PROTOCOL))),
4214 build1 (INDIRECT_REF, NULL_TREE,
4215 build1 (INDIRECT_REF, NULL_TREE, NULL_TREE))));
4217 expr = build_unary_op (ADDR_EXPR, protocol_list, 0);
4218 TREE_TYPE (expr) = cast_type2;
4219 initlist = tree_cons (NULL_TREE, expr, initlist);
4222 /* gc_object_type = NULL */
4223 initlist = tree_cons (NULL_TREE, build_int_2 (0, 0), initlist);
4225 return build_constructor (type, nreverse (initlist));
4228 /* static struct objc_category _OBJC_CATEGORY_<name> = { ... }; */
4231 generate_category (cat)
4234 tree sc_spec, decl_specs, decl;
4235 tree initlist, cat_name_expr, class_name_expr;
4236 tree protocol_decl, category;
4238 add_class_reference (CLASS_NAME (cat));
4239 cat_name_expr = add_objc_string (CLASS_SUPER_NAME (cat), class_names);
4241 class_name_expr = add_objc_string (CLASS_NAME (cat), class_names);
4243 category = CLASS_CATEGORY_LIST (implementation_template);
4245 /* find the category interface from the class it is associated with */
4248 if (CLASS_SUPER_NAME (cat) == CLASS_SUPER_NAME (category))
4250 category = CLASS_CATEGORY_LIST (category);
4253 if (category && CLASS_PROTOCOL_LIST (category))
4255 generate_protocol_references (CLASS_PROTOCOL_LIST (category));
4256 protocol_decl = generate_protocol_list (category);
4261 sc_spec = tree_cons (NULL_TREE, ridpointers[(int) RID_STATIC], NULL_TREE);
4262 decl_specs = tree_cons (NULL_TREE, objc_category_template, sc_spec);
4264 decl = start_decl (synth_id_with_class_suffix ("_OBJC_CATEGORY",
4265 objc_implementation_context),
4266 decl_specs, 1, NULL_TREE);
4268 initlist = build_category_initializer (TREE_TYPE (decl),
4269 cat_name_expr, class_name_expr,
4270 UOBJC_INSTANCE_METHODS_decl,
4271 UOBJC_CLASS_METHODS_decl,
4274 TREE_USED (decl) = 1;
4275 finish_decl (decl, initlist, NULL_TREE);
4278 /* static struct objc_class _OBJC_METACLASS_Foo={ ... };
4279 static struct objc_class _OBJC_CLASS_Foo={ ... }; */
4282 generate_shared_structures ()
4284 tree sc_spec, decl_specs, decl;
4285 tree name_expr, super_expr, root_expr;
4286 tree my_root_id = NULL_TREE, my_super_id = NULL_TREE;
4287 tree cast_type, initlist, protocol_decl;
4289 my_super_id = CLASS_SUPER_NAME (implementation_template);
4292 add_class_reference (my_super_id);
4294 /* Compute "my_root_id" - this is required for code generation.
4295 the "isa" for all meta class structures points to the root of
4296 the inheritance hierarchy (e.g. "__Object")... */
4297 my_root_id = my_super_id;
4300 tree my_root_int = lookup_interface (my_root_id);
4302 if (my_root_int && CLASS_SUPER_NAME (my_root_int))
4303 my_root_id = CLASS_SUPER_NAME (my_root_int);
4310 /* No super class. */
4311 my_root_id = CLASS_NAME (implementation_template);
4314 = groktypename (build_tree_list (build_tree_list (NULL_TREE,
4315 objc_class_template),
4316 build1 (INDIRECT_REF,
4317 NULL_TREE, NULL_TREE)));
4319 name_expr = add_objc_string (CLASS_NAME (implementation_template),
4322 /* Install class `isa' and `super' pointers at runtime. */
4325 super_expr = add_objc_string (my_super_id, class_names);
4326 super_expr = build_c_cast (cast_type, super_expr); /* cast! */
4329 super_expr = build_int_2 (0, 0);
4331 root_expr = add_objc_string (my_root_id, class_names);
4332 root_expr = build_c_cast (cast_type, root_expr); /* cast! */
4334 if (CLASS_PROTOCOL_LIST (implementation_template))
4336 generate_protocol_references
4337 (CLASS_PROTOCOL_LIST (implementation_template));
4338 protocol_decl = generate_protocol_list (implementation_template);
4343 /* static struct objc_class _OBJC_METACLASS_Foo = { ... }; */
4345 sc_spec = build_tree_list (NULL_TREE, ridpointers[(int) RID_STATIC]);
4346 decl_specs = tree_cons (NULL_TREE, objc_class_template, sc_spec);
4348 decl = start_decl (DECL_NAME (UOBJC_METACLASS_decl), decl_specs, 1,
4352 = build_shared_structure_initializer
4354 root_expr, super_expr, name_expr,
4355 convert (integer_type_node, TYPE_SIZE_UNIT (objc_class_template)),
4357 UOBJC_CLASS_METHODS_decl,
4358 UOBJC_CLASS_VARIABLES_decl,
4361 finish_decl (decl, initlist, NULL_TREE);
4363 /* static struct objc_class _OBJC_CLASS_Foo={ ... }; */
4365 decl = start_decl (DECL_NAME (UOBJC_CLASS_decl), decl_specs, 1,
4369 = build_shared_structure_initializer
4371 build_unary_op (ADDR_EXPR, UOBJC_METACLASS_decl, 0),
4372 super_expr, name_expr,
4373 convert (integer_type_node,
4374 TYPE_SIZE_UNIT (CLASS_STATIC_TEMPLATE
4375 (implementation_template))),
4377 UOBJC_INSTANCE_METHODS_decl,
4378 UOBJC_INSTANCE_VARIABLES_decl,
4381 finish_decl (decl, initlist, NULL_TREE);
4385 synth_id_with_class_suffix (preamble, ctxt)
4386 const char *preamble;
4390 if (TREE_CODE (ctxt) == CLASS_IMPLEMENTATION_TYPE
4391 || TREE_CODE (ctxt) == CLASS_INTERFACE_TYPE)
4393 const char *const class_name
4394 = IDENTIFIER_POINTER (CLASS_NAME (objc_implementation_context));
4395 string = (char *) alloca (strlen (preamble) + strlen (class_name) + 3);
4396 sprintf (string, "%s_%s", preamble,
4397 IDENTIFIER_POINTER (CLASS_NAME (ctxt)));
4399 else if (TREE_CODE (ctxt) == CATEGORY_IMPLEMENTATION_TYPE
4400 || TREE_CODE (ctxt) == CATEGORY_INTERFACE_TYPE)
4402 /* We have a category. */
4403 const char *const class_name
4404 = IDENTIFIER_POINTER (CLASS_NAME (objc_implementation_context));
4405 const char *const class_super_name
4406 = IDENTIFIER_POINTER (CLASS_SUPER_NAME (objc_implementation_context));
4407 string = (char *) alloca (strlen (preamble)
4408 + strlen (class_name)
4409 + strlen (class_super_name)
4411 sprintf (string, "%s_%s_%s", preamble, class_name, class_super_name);
4413 else if (TREE_CODE (ctxt) == PROTOCOL_INTERFACE_TYPE)
4415 const char *protocol_name = IDENTIFIER_POINTER (PROTOCOL_NAME (ctxt));
4417 = (char *) alloca (strlen (preamble) + strlen (protocol_name) + 3);
4418 sprintf (string, "%s_%s", preamble, protocol_name);
4423 return get_identifier (string);
4427 is_objc_type_qualifier (node)
4430 return (TREE_CODE (node) == IDENTIFIER_NODE
4431 && (node == ridpointers [(int) RID_CONST]
4432 || node == ridpointers [(int) RID_VOLATILE]
4433 || node == ridpointers [(int) RID_IN]
4434 || node == ridpointers [(int) RID_OUT]
4435 || node == ridpointers [(int) RID_INOUT]
4436 || node == ridpointers [(int) RID_BYCOPY]
4437 || node == ridpointers [(int) RID_BYREF]
4438 || node == ridpointers [(int) RID_ONEWAY]));
4441 /* If type is empty or only type qualifiers are present, add default
4442 type of id (otherwise grokdeclarator will default to int). */
4445 adjust_type_for_id_default (type)
4448 tree declspecs, chain;
4451 return build_tree_list (build_tree_list (NULL_TREE, objc_object_reference),
4452 build1 (INDIRECT_REF, NULL_TREE, NULL_TREE));
4454 declspecs = TREE_PURPOSE (type);
4456 /* Determine if a typespec is present. */
4457 for (chain = declspecs;
4459 chain = TREE_CHAIN (chain))
4461 if (TYPED_OBJECT (TREE_VALUE (chain))
4462 && !(TREE_VALUE (type)
4463 && TREE_CODE (TREE_VALUE (type)) == INDIRECT_REF))
4464 error ("can not use an object as parameter to a method\n");
4465 if (!is_objc_type_qualifier (TREE_VALUE (chain)))
4469 return build_tree_list (tree_cons (NULL_TREE, objc_object_reference,
4471 build1 (INDIRECT_REF, NULL_TREE, NULL_TREE));
4476 selector ':' '(' typename ')' identifier
4479 Transform an Objective-C keyword argument into
4480 the C equivalent parameter declarator.
4482 In: key_name, an "identifier_node" (optional).
4483 arg_type, a "tree_list" (optional).
4484 arg_name, an "identifier_node".
4486 Note: It would be really nice to strongly type the preceding
4487 arguments in the function prototype; however, then I
4488 could not use the "accessor" macros defined in "tree.h".
4490 Out: an instance of "keyword_decl". */
4493 build_keyword_decl (key_name, arg_type, arg_name)
4500 /* If no type is specified, default to "id". */
4501 arg_type = adjust_type_for_id_default (arg_type);
4503 keyword_decl = make_node (KEYWORD_DECL);
4505 TREE_TYPE (keyword_decl) = arg_type;
4506 KEYWORD_ARG_NAME (keyword_decl) = arg_name;
4507 KEYWORD_KEY_NAME (keyword_decl) = key_name;
4509 return keyword_decl;
4512 /* Given a chain of keyword_decl's, synthesize the full keyword selector. */
4515 build_keyword_selector (selector)
4519 tree key_chain, key_name;
4522 /* Scan the selector to see how much space we'll need. */
4523 for (key_chain = selector; key_chain; key_chain = TREE_CHAIN (key_chain))
4525 if (TREE_CODE (selector) == KEYWORD_DECL)
4526 key_name = KEYWORD_KEY_NAME (key_chain);
4527 else if (TREE_CODE (selector) == TREE_LIST)
4528 key_name = TREE_PURPOSE (key_chain);
4533 len += IDENTIFIER_LENGTH (key_name) + 1;
4535 /* Just a ':' arg. */
4539 buf = (char *) alloca (len + 1);
4540 /* Start the buffer out as an empty string. */
4543 for (key_chain = selector; key_chain; key_chain = TREE_CHAIN (key_chain))
4545 if (TREE_CODE (selector) == KEYWORD_DECL)
4546 key_name = KEYWORD_KEY_NAME (key_chain);
4547 else if (TREE_CODE (selector) == TREE_LIST)
4548 key_name = TREE_PURPOSE (key_chain);
4553 strcat (buf, IDENTIFIER_POINTER (key_name));
4557 return get_identifier (buf);
4560 /* Used for declarations and definitions. */
4563 build_method_decl (code, ret_type, selector, add_args)
4564 enum tree_code code;
4571 /* If no type is specified, default to "id". */
4572 ret_type = adjust_type_for_id_default (ret_type);
4574 method_decl = make_node (code);
4575 TREE_TYPE (method_decl) = ret_type;
4577 /* If we have a keyword selector, create an identifier_node that
4578 represents the full selector name (`:' included)... */
4579 if (TREE_CODE (selector) == KEYWORD_DECL)
4581 METHOD_SEL_NAME (method_decl) = build_keyword_selector (selector);
4582 METHOD_SEL_ARGS (method_decl) = selector;
4583 METHOD_ADD_ARGS (method_decl) = add_args;
4587 METHOD_SEL_NAME (method_decl) = selector;
4588 METHOD_SEL_ARGS (method_decl) = NULL_TREE;
4589 METHOD_ADD_ARGS (method_decl) = NULL_TREE;
4595 #define METHOD_DEF 0
4596 #define METHOD_REF 1
4598 /* Used by `build_objc_method_call' and `comp_method_types'. Return
4599 an argument list for method METH. CONTEXT is either METHOD_DEF or
4600 METHOD_REF, saying whether we are trying to define a method or call
4601 one. SUPERFLAG says this is for a send to super; this makes a
4602 difference for the NeXT calling sequence in which the lookup and
4603 the method call are done together. */
4606 get_arg_type_list (meth, context, superflag)
4613 /* Receiver type. */
4614 if (flag_next_runtime && superflag)
4615 arglist = build_tree_list (NULL_TREE, super_type);
4616 else if (context == METHOD_DEF)
4617 arglist = build_tree_list (NULL_TREE, TREE_TYPE (self_decl));
4619 arglist = build_tree_list (NULL_TREE, id_type);
4621 /* Selector type - will eventually change to `int'. */
4622 chainon (arglist, build_tree_list (NULL_TREE, selector_type));
4624 /* Build a list of argument types. */
4625 for (akey = METHOD_SEL_ARGS (meth); akey; akey = TREE_CHAIN (akey))
4627 tree arg_decl = groktypename_in_parm_context (TREE_TYPE (akey));
4628 chainon (arglist, build_tree_list (NULL_TREE, TREE_TYPE (arg_decl)));
4631 if (METHOD_ADD_ARGS (meth) == objc_ellipsis_node)
4632 /* We have a `, ...' immediately following the selector,
4633 finalize the arglist...simulate get_parm_info (0). */
4635 else if (METHOD_ADD_ARGS (meth))
4637 /* we have a variable length selector */
4638 tree add_arg_list = TREE_CHAIN (METHOD_ADD_ARGS (meth));
4639 chainon (arglist, add_arg_list);
4642 /* finalize the arglist...simulate get_parm_info (1) */
4643 chainon (arglist, build_tree_list (NULL_TREE, void_type_node));
4649 check_duplicates (hsh)
4652 tree meth = NULL_TREE;
4660 /* We have two methods with the same name and different types. */
4662 char type = (TREE_CODE (meth) == INSTANCE_METHOD_DECL) ? '-' : '+';
4664 warning ("multiple declarations for method `%s'",
4665 IDENTIFIER_POINTER (METHOD_SEL_NAME (meth)));
4667 warn_with_method ("using", type, meth);
4668 for (loop = hsh->list; loop; loop = loop->next)
4669 warn_with_method ("also found", type, loop->value);
4675 /* If RECEIVER is a class reference, return the identifier node for
4676 the referenced class. RECEIVER is created by get_class_reference,
4677 so we check the exact form created depending on which runtimes are
4681 receiver_is_class_object (receiver)
4684 tree chain, exp, arg;
4686 /* The receiver is 'self' in the context of a class method. */
4687 if (objc_method_context
4688 && receiver == self_decl
4689 && TREE_CODE (objc_method_context) == CLASS_METHOD_DECL)
4691 return CLASS_NAME (objc_implementation_context);
4694 if (flag_next_runtime)
4696 /* The receiver is a variable created by
4697 build_class_reference_decl. */
4698 if (TREE_CODE (receiver) == VAR_DECL
4699 && TREE_TYPE (receiver) == objc_class_type)
4700 /* Look up the identifier. */
4701 for (chain = cls_ref_chain; chain; chain = TREE_CHAIN (chain))
4702 if (TREE_PURPOSE (chain) == receiver)
4703 return TREE_VALUE (chain);
4707 /* The receiver is a function call that returns an id. Check if
4708 it is a call to objc_getClass, if so, pick up the class name. */
4709 if (TREE_CODE (receiver) == CALL_EXPR
4710 && (exp = TREE_OPERAND (receiver, 0))
4711 && TREE_CODE (exp) == ADDR_EXPR
4712 && (exp = TREE_OPERAND (exp, 0))
4713 && TREE_CODE (exp) == FUNCTION_DECL
4714 && exp == objc_get_class_decl
4715 /* We have a call to objc_getClass! */
4716 && (arg = TREE_OPERAND (receiver, 1))
4717 && TREE_CODE (arg) == TREE_LIST
4718 && (arg = TREE_VALUE (arg)))
4721 if (TREE_CODE (arg) == ADDR_EXPR
4722 && (arg = TREE_OPERAND (arg, 0))
4723 && TREE_CODE (arg) == STRING_CST)
4724 /* Finally, we have the class name. */
4725 return get_identifier (TREE_STRING_POINTER (arg));
4731 /* If we are currently building a message expr, this holds
4732 the identifier of the selector of the message. This is
4733 used when printing warnings about argument mismatches. */
4735 static tree building_objc_message_expr = 0;
4738 maybe_building_objc_message_expr ()
4740 return building_objc_message_expr;
4743 /* Construct an expression for sending a message.
4744 MESS has the object to send to in TREE_PURPOSE
4745 and the argument list (including selector) in TREE_VALUE.
4747 (*(<abstract_decl>(*)())_msg)(receiver, selTransTbl[n], ...);
4748 (*(<abstract_decl>(*)())_msgSuper)(receiver, selTransTbl[n], ...); */
4751 build_message_expr (mess)
4754 tree receiver = TREE_PURPOSE (mess);
4756 tree args = TREE_VALUE (mess);
4757 tree method_params = NULL_TREE;
4759 if (TREE_CODE (receiver) == ERROR_MARK)
4760 return error_mark_node;
4762 /* Obtain the full selector name. */
4763 if (TREE_CODE (args) == IDENTIFIER_NODE)
4764 /* A unary selector. */
4766 else if (TREE_CODE (args) == TREE_LIST)
4767 sel_name = build_keyword_selector (args);
4771 /* Build the parameter list to give to the method. */
4772 if (TREE_CODE (args) == TREE_LIST)
4774 tree chain = args, prev = NULL_TREE;
4776 /* We have a keyword selector--check for comma expressions. */
4779 tree element = TREE_VALUE (chain);
4781 /* We have a comma expression, must collapse... */
4782 if (TREE_CODE (element) == TREE_LIST)
4785 TREE_CHAIN (prev) = element;
4790 chain = TREE_CHAIN (chain);
4792 method_params = args;
4795 return finish_message_expr (receiver, sel_name, method_params);
4798 /* The 'finish_message_expr' routine is called from within
4799 'build_message_expr' for non-template functions. In the case of
4800 C++ template functions, it is called from 'build_expr_from_tree'
4801 (in decl2.c) after RECEIVER and METHOD_PARAMS have been expanded. */
4804 finish_message_expr (receiver, sel_name, method_params)
4805 tree receiver, sel_name, method_params;
4807 tree method_prototype = NULL_TREE, class_ident = NULL_TREE;
4808 tree selector, self_object, retval;
4809 int statically_typed = 0, statically_allocated = 0;
4811 /* Determine receiver type. */
4812 tree rtype = TREE_TYPE (receiver);
4813 int super = IS_SUPER (rtype);
4817 if (TREE_STATIC_TEMPLATE (rtype))
4818 statically_allocated = 1;
4819 else if (TREE_CODE (rtype) == POINTER_TYPE
4820 && TREE_STATIC_TEMPLATE (TREE_TYPE (rtype)))
4821 statically_typed = 1;
4822 else if ((flag_next_runtime
4824 && (class_ident = receiver_is_class_object (receiver)))
4826 else if (! IS_ID (rtype)
4827 /* Allow any type that matches objc_class_type. */
4828 && ! comptypes (rtype, objc_class_type))
4830 warning ("invalid receiver type `%s'",
4831 gen_declaration (rtype, errbuf));
4833 if (statically_allocated)
4834 receiver = build_unary_op (ADDR_EXPR, receiver, 0);
4836 /* Don't evaluate the receiver twice. */
4837 receiver = save_expr (receiver);
4838 self_object = receiver;
4841 /* If sending to `super', use current self as the object. */
4842 self_object = self_decl;
4844 /* Determine operation return type. */
4850 if (CLASS_SUPER_NAME (implementation_template))
4853 = lookup_interface (CLASS_SUPER_NAME (implementation_template));
4855 if (TREE_CODE (objc_method_context) == INSTANCE_METHOD_DECL)
4856 method_prototype = lookup_instance_method_static (iface, sel_name);
4858 method_prototype = lookup_class_method_static (iface, sel_name);
4860 if (iface && !method_prototype)
4861 warning ("`%s' does not respond to `%s'",
4862 IDENTIFIER_POINTER (CLASS_SUPER_NAME (implementation_template)),
4863 IDENTIFIER_POINTER (sel_name));
4867 error ("no super class declared in interface for `%s'",
4868 IDENTIFIER_POINTER (CLASS_NAME (implementation_template)));
4869 return error_mark_node;
4873 else if (statically_allocated)
4875 tree ctype = TREE_TYPE (rtype);
4876 tree iface = lookup_interface (TYPE_NAME (rtype));
4879 method_prototype = lookup_instance_method_static (iface, sel_name);
4881 if (! method_prototype && TYPE_PROTOCOL_LIST (ctype))
4883 = lookup_method_in_protocol_list (TYPE_PROTOCOL_LIST (ctype),
4886 if (!method_prototype)
4887 warning ("`%s' does not respond to `%s'",
4888 IDENTIFIER_POINTER (TYPE_NAME (rtype)),
4889 IDENTIFIER_POINTER (sel_name));
4891 else if (statically_typed)
4893 tree ctype = TREE_TYPE (rtype);
4895 /* `self' is now statically_typed. All methods should be visible
4896 within the context of the implementation. */
4897 if (objc_implementation_context
4898 && CLASS_NAME (objc_implementation_context) == TYPE_NAME (ctype))
4901 = lookup_instance_method_static (implementation_template,
4904 if (! method_prototype && TYPE_PROTOCOL_LIST (ctype))
4906 = lookup_method_in_protocol_list (TYPE_PROTOCOL_LIST (ctype),
4909 if (! method_prototype
4910 && implementation_template != objc_implementation_context)
4911 /* The method is not published in the interface. Check
4914 = lookup_method (CLASS_NST_METHODS (objc_implementation_context),
4921 if ((iface = lookup_interface (TYPE_NAME (ctype))))
4922 method_prototype = lookup_instance_method_static (iface, sel_name);
4924 if (! method_prototype)
4926 tree protocol_list = TYPE_PROTOCOL_LIST (ctype);
4929 = lookup_method_in_protocol_list (protocol_list,
4934 if (!method_prototype)
4935 warning ("`%s' does not respond to `%s'",
4936 IDENTIFIER_POINTER (TYPE_NAME (ctype)),
4937 IDENTIFIER_POINTER (sel_name));
4939 else if (class_ident)
4941 if (objc_implementation_context
4942 && CLASS_NAME (objc_implementation_context) == class_ident)
4945 = lookup_class_method_static (implementation_template, sel_name);
4947 if (!method_prototype
4948 && implementation_template != objc_implementation_context)
4949 /* The method is not published in the interface. Check
4952 = lookup_method (CLASS_CLS_METHODS (objc_implementation_context),
4959 if ((iface = lookup_interface (class_ident)))
4960 method_prototype = lookup_class_method_static (iface, sel_name);
4963 if (!method_prototype)
4965 warning ("cannot find class (factory) method");
4966 warning ("return type for `%s' defaults to id",
4967 IDENTIFIER_POINTER (sel_name));
4970 else if (IS_PROTOCOL_QUALIFIED_ID (rtype))
4972 /* An anonymous object that has been qualified with a protocol. */
4974 tree protocol_list = TYPE_PROTOCOL_LIST (rtype);
4976 method_prototype = lookup_method_in_protocol_list (protocol_list,
4979 if (!method_prototype)
4983 warning ("method `%s' not implemented by protocol",
4984 IDENTIFIER_POINTER (sel_name));
4986 /* Try and find the method signature in the global pools. */
4988 if (!(hsh = hash_lookup (nst_method_hash_list, sel_name)))
4989 hsh = hash_lookup (cls_method_hash_list, sel_name);
4991 if (!(method_prototype = check_duplicates (hsh)))
4992 warning ("return type defaults to id");
4999 /* We think we have an instance...loophole: extern id Object; */
5000 hsh = hash_lookup (nst_method_hash_list, sel_name);
5003 /* For various loopholes */
5004 hsh = hash_lookup (cls_method_hash_list, sel_name);
5006 method_prototype = check_duplicates (hsh);
5007 if (!method_prototype)
5009 warning ("cannot find method");
5010 warning ("return type for `%s' defaults to id",
5011 IDENTIFIER_POINTER (sel_name));
5015 /* Save the selector name for printing error messages. */
5016 building_objc_message_expr = sel_name;
5018 /* Build the parameters list for looking up the method.
5019 These are the object itself and the selector. */
5021 if (flag_typed_selectors)
5022 selector = build_typed_selector_reference (sel_name, method_prototype);
5024 selector = build_selector_reference (sel_name);
5026 retval = build_objc_method_call (super, method_prototype,
5027 receiver, self_object,
5028 selector, method_params);
5030 building_objc_message_expr = 0;
5035 /* Build a tree expression to send OBJECT the operation SELECTOR,
5036 looking up the method on object LOOKUP_OBJECT (often same as OBJECT),
5037 assuming the method has prototype METHOD_PROTOTYPE.
5038 (That is an INSTANCE_METHOD_DECL or CLASS_METHOD_DECL.)
5039 Use METHOD_PARAMS as list of args to pass to the method.
5040 If SUPER_FLAG is nonzero, we look up the superclass's method. */
5043 build_objc_method_call (super_flag, method_prototype, lookup_object, object,
5044 selector, method_params)
5046 tree method_prototype, lookup_object, object, selector, method_params;
5048 tree sender = (super_flag ? umsg_super_decl : umsg_decl);
5049 tree rcv_p = (super_flag
5050 ? build_pointer_type (xref_tag (RECORD_TYPE,
5051 get_identifier (TAG_SUPER)))
5054 if (flag_next_runtime)
5056 if (! method_prototype)
5058 method_params = tree_cons (NULL_TREE, lookup_object,
5059 tree_cons (NULL_TREE, selector,
5061 assemble_external (sender);
5062 return build_function_call (sender, method_params);
5066 /* This is a real kludge, but it is used only for the Next.
5067 Clobber the data type of SENDER temporarily to accept
5068 all the arguments for this operation, and to return
5069 whatever this operation returns. */
5070 tree arglist = NULL_TREE, retval, savarg, savret;
5071 tree ret_type = groktypename (TREE_TYPE (method_prototype));
5073 /* Save the proper contents of SENDER's data type. */
5074 savarg = TYPE_ARG_TYPES (TREE_TYPE (sender));
5075 savret = TREE_TYPE (TREE_TYPE (sender));
5077 /* Install this method's argument types. */
5078 arglist = get_arg_type_list (method_prototype, METHOD_REF,
5080 TYPE_ARG_TYPES (TREE_TYPE (sender)) = arglist;
5082 /* Install this method's return type. */
5083 TREE_TYPE (TREE_TYPE (sender)) = ret_type;
5085 /* Call SENDER with all the parameters. This will do type
5086 checking using the arg types for this method. */
5087 method_params = tree_cons (NULL_TREE, lookup_object,
5088 tree_cons (NULL_TREE, selector,
5090 assemble_external (sender);
5091 retval = build_function_call (sender, method_params);
5093 /* Restore SENDER's return/argument types. */
5094 TYPE_ARG_TYPES (TREE_TYPE (sender)) = savarg;
5095 TREE_TYPE (TREE_TYPE (sender)) = savret;
5101 /* This is the portable way.
5102 First call the lookup function to get a pointer to the method,
5103 then cast the pointer, then call it with the method arguments. */
5106 /* Avoid trouble since we may evaluate each of these twice. */
5107 object = save_expr (object);
5108 selector = save_expr (selector);
5110 lookup_object = build_c_cast (rcv_p, lookup_object);
5112 assemble_external (sender);
5114 = build_function_call (sender,
5115 tree_cons (NULL_TREE, lookup_object,
5116 tree_cons (NULL_TREE, selector,
5119 /* If we have a method prototype, construct the data type this
5120 method needs, and cast what we got from SENDER into a pointer
5122 if (method_prototype)
5124 tree arglist = get_arg_type_list (method_prototype, METHOD_REF,
5126 tree valtype = groktypename (TREE_TYPE (method_prototype));
5127 tree fake_function_type = build_function_type (valtype, arglist);
5128 TREE_TYPE (method) = build_pointer_type (fake_function_type);
5132 = build_pointer_type (build_function_type (ptr_type_node, NULL_TREE));
5134 /* Pass the object to the method. */
5135 assemble_external (method);
5136 return build_function_call (method,
5137 tree_cons (NULL_TREE, object,
5138 tree_cons (NULL_TREE, selector,
5144 build_protocol_reference (p)
5147 tree decl, ident, ptype;
5149 /* extern struct objc_protocol _OBJC_PROTOCOL_<mumble>; */
5151 ident = synth_id_with_class_suffix ("_OBJC_PROTOCOL", p);
5153 = groktypename (build_tree_list (build_tree_list (NULL_TREE,
5154 objc_protocol_template),
5157 if (IDENTIFIER_GLOBAL_VALUE (ident))
5158 decl = IDENTIFIER_GLOBAL_VALUE (ident); /* Set by pushdecl. */
5161 decl = build_decl (VAR_DECL, ident, ptype);
5162 DECL_EXTERNAL (decl) = 1;
5163 TREE_PUBLIC (decl) = 1;
5164 TREE_USED (decl) = 1;
5165 DECL_ARTIFICIAL (decl) = 1;
5167 make_decl_rtl (decl, 0);
5168 pushdecl_top_level (decl);
5171 PROTOCOL_FORWARD_DECL (p) = decl;
5175 build_protocol_expr (protoname)
5179 tree p = lookup_protocol (protoname);
5183 error ("cannot find protocol declaration for `%s'",
5184 IDENTIFIER_POINTER (protoname));
5185 return error_mark_node;
5188 if (!PROTOCOL_FORWARD_DECL (p))
5189 build_protocol_reference (p);
5191 expr = build_unary_op (ADDR_EXPR, PROTOCOL_FORWARD_DECL (p), 0);
5193 TREE_TYPE (expr) = protocol_type;
5199 build_selector_expr (selnamelist)
5204 /* Obtain the full selector name. */
5205 if (TREE_CODE (selnamelist) == IDENTIFIER_NODE)
5206 /* A unary selector. */
5207 selname = selnamelist;
5208 else if (TREE_CODE (selnamelist) == TREE_LIST)
5209 selname = build_keyword_selector (selnamelist);
5213 if (flag_typed_selectors)
5214 return build_typed_selector_reference (selname, 0);
5216 return build_selector_reference (selname);
5220 build_encode_expr (type)
5226 encode_type (type, obstack_object_size (&util_obstack),
5227 OBJC_ENCODE_INLINE_DEFS);
5228 obstack_1grow (&util_obstack, 0); /* null terminate string */
5229 string = obstack_finish (&util_obstack);
5231 /* Synthesize a string that represents the encoded struct/union. */
5232 result = my_build_string (strlen (string) + 1, string);
5233 obstack_free (&util_obstack, util_firstobj);
5238 build_ivar_reference (id)
5241 if (TREE_CODE (objc_method_context) == CLASS_METHOD_DECL)
5243 /* Historically, a class method that produced objects (factory
5244 method) would assign `self' to the instance that it
5245 allocated. This would effectively turn the class method into
5246 an instance method. Following this assignment, the instance
5247 variables could be accessed. That practice, while safe,
5248 violates the simple rule that a class method should not refer
5249 to an instance variable. It's better to catch the cases
5250 where this is done unknowingly than to support the above
5252 warning ("instance variable `%s' accessed in class method",
5253 IDENTIFIER_POINTER (id));
5254 TREE_TYPE (self_decl) = instance_type; /* cast */
5257 return build_component_ref (build_indirect_ref (self_decl, "->"), id);
5260 /* Compute a hash value for a given method SEL_NAME. */
5263 hash_func (sel_name)
5266 const unsigned char *s
5267 = (const unsigned char *)IDENTIFIER_POINTER (sel_name);
5271 h = h * 67 + *s++ - 113;
5278 nst_method_hash_list = (hash *) ggc_calloc (SIZEHASHTABLE, sizeof (hash));
5279 cls_method_hash_list = (hash *) ggc_calloc (SIZEHASHTABLE, sizeof (hash));
5282 /* WARNING!!!! hash_enter is called with a method, and will peek
5283 inside to find its selector! But hash_lookup is given a selector
5284 directly, and looks for the selector that's inside the found
5285 entry's key (method) for comparison. */
5288 hash_enter (hashlist, method)
5293 int slot = hash_func (METHOD_SEL_NAME (method)) % SIZEHASHTABLE;
5295 obj = (hash) ggc_alloc (sizeof (struct hashed_entry));
5297 obj->next = hashlist[slot];
5300 hashlist[slot] = obj; /* append to front */
5304 hash_lookup (hashlist, sel_name)
5310 target = hashlist[hash_func (sel_name) % SIZEHASHTABLE];
5314 if (sel_name == METHOD_SEL_NAME (target->key))
5317 target = target->next;
5323 hash_add_attr (entry, value)
5329 obj = (attr) ggc_alloc (sizeof (struct hashed_attribute));
5330 obj->next = entry->list;
5333 entry->list = obj; /* append to front */
5337 lookup_method (mchain, method)
5343 if (TREE_CODE (method) == IDENTIFIER_NODE)
5346 key = METHOD_SEL_NAME (method);
5350 if (METHOD_SEL_NAME (mchain) == key)
5352 mchain = TREE_CHAIN (mchain);
5358 lookup_instance_method_static (interface, ident)
5362 tree inter = interface;
5363 tree chain = CLASS_NST_METHODS (inter);
5364 tree meth = NULL_TREE;
5368 if ((meth = lookup_method (chain, ident)))
5371 if (CLASS_CATEGORY_LIST (inter))
5373 tree category = CLASS_CATEGORY_LIST (inter);
5374 chain = CLASS_NST_METHODS (category);
5378 if ((meth = lookup_method (chain, ident)))
5381 /* Check for instance methods in protocols in categories. */
5382 if (CLASS_PROTOCOL_LIST (category))
5384 if ((meth = (lookup_method_in_protocol_list
5385 (CLASS_PROTOCOL_LIST (category), ident, 0))))
5389 if ((category = CLASS_CATEGORY_LIST (category)))
5390 chain = CLASS_NST_METHODS (category);
5395 if (CLASS_PROTOCOL_LIST (inter))
5397 if ((meth = (lookup_method_in_protocol_list
5398 (CLASS_PROTOCOL_LIST (inter), ident, 0))))
5402 if ((inter = lookup_interface (CLASS_SUPER_NAME (inter))))
5403 chain = CLASS_NST_METHODS (inter);
5411 lookup_class_method_static (interface, ident)
5415 tree inter = interface;
5416 tree chain = CLASS_CLS_METHODS (inter);
5417 tree meth = NULL_TREE;
5418 tree root_inter = NULL_TREE;
5422 if ((meth = lookup_method (chain, ident)))
5425 if (CLASS_CATEGORY_LIST (inter))
5427 tree category = CLASS_CATEGORY_LIST (inter);
5428 chain = CLASS_CLS_METHODS (category);
5432 if ((meth = lookup_method (chain, ident)))
5435 /* Check for class methods in protocols in categories. */
5436 if (CLASS_PROTOCOL_LIST (category))
5438 if ((meth = (lookup_method_in_protocol_list
5439 (CLASS_PROTOCOL_LIST (category), ident, 1))))
5443 if ((category = CLASS_CATEGORY_LIST (category)))
5444 chain = CLASS_CLS_METHODS (category);
5449 /* Check for class methods in protocols. */
5450 if (CLASS_PROTOCOL_LIST (inter))
5452 if ((meth = (lookup_method_in_protocol_list
5453 (CLASS_PROTOCOL_LIST (inter), ident, 1))))
5458 if ((inter = lookup_interface (CLASS_SUPER_NAME (inter))))
5459 chain = CLASS_CLS_METHODS (inter);
5463 /* If no class (factory) method was found, check if an _instance_
5464 method of the same name exists in the root class. This is what
5465 the Objective-C runtime will do. */
5466 return lookup_instance_method_static (root_inter, ident);
5470 add_class_method (class, method)
5477 if (!(mth = lookup_method (CLASS_CLS_METHODS (class), method)))
5479 /* put method on list in reverse order */
5480 TREE_CHAIN (method) = CLASS_CLS_METHODS (class);
5481 CLASS_CLS_METHODS (class) = method;
5485 if (TREE_CODE (class) == CLASS_IMPLEMENTATION_TYPE)
5486 error ("duplicate definition of class method `%s'",
5487 IDENTIFIER_POINTER (METHOD_SEL_NAME (mth)));
5490 /* Check types; if different, complain. */
5491 if (!comp_proto_with_proto (method, mth))
5492 error ("duplicate declaration of class method `%s'",
5493 IDENTIFIER_POINTER (METHOD_SEL_NAME (mth)));
5497 if (!(hsh = hash_lookup (cls_method_hash_list, METHOD_SEL_NAME (method))))
5499 /* Install on a global chain. */
5500 hash_enter (cls_method_hash_list, method);
5504 /* Check types; if different, add to a list. */
5505 if (!comp_proto_with_proto (method, hsh->key))
5506 hash_add_attr (hsh, method);
5512 add_instance_method (class, method)
5519 if (!(mth = lookup_method (CLASS_NST_METHODS (class), method)))
5521 /* Put method on list in reverse order. */
5522 TREE_CHAIN (method) = CLASS_NST_METHODS (class);
5523 CLASS_NST_METHODS (class) = method;
5527 if (TREE_CODE (class) == CLASS_IMPLEMENTATION_TYPE)
5528 error ("duplicate definition of instance method `%s'",
5529 IDENTIFIER_POINTER (METHOD_SEL_NAME (mth)));
5532 /* Check types; if different, complain. */
5533 if (!comp_proto_with_proto (method, mth))
5534 error ("duplicate declaration of instance method `%s'",
5535 IDENTIFIER_POINTER (METHOD_SEL_NAME (mth)));
5539 if (!(hsh = hash_lookup (nst_method_hash_list, METHOD_SEL_NAME (method))))
5541 /* Install on a global chain. */
5542 hash_enter (nst_method_hash_list, method);
5546 /* Check types; if different, add to a list. */
5547 if (!comp_proto_with_proto (method, hsh->key))
5548 hash_add_attr (hsh, method);
5557 /* Put interfaces on list in reverse order. */
5558 TREE_CHAIN (class) = interface_chain;
5559 interface_chain = class;
5560 return interface_chain;
5564 add_category (class, category)
5568 /* Put categories on list in reverse order. */
5569 tree cat = CLASS_CATEGORY_LIST (class);
5573 if (CLASS_SUPER_NAME (cat) == CLASS_SUPER_NAME (category))
5574 warning ("duplicate interface declaration for category `%s(%s)'",
5575 IDENTIFIER_POINTER (CLASS_NAME (class)),
5576 IDENTIFIER_POINTER (CLASS_SUPER_NAME (category)));
5577 cat = CLASS_CATEGORY_LIST (cat);
5580 CLASS_CATEGORY_LIST (category) = CLASS_CATEGORY_LIST (class);
5581 CLASS_CATEGORY_LIST (class) = category;
5584 /* Called after parsing each instance variable declaration. Necessary to
5585 preserve typedefs and implement public/private...
5587 PUBLIC is 1 for public, 0 for protected, and 2 for private. */
5590 add_instance_variable (class, public, declarator, declspecs, width)
5597 tree field_decl, raw_decl;
5599 raw_decl = build_tree_list (declspecs, declarator);
5601 if (CLASS_RAW_IVARS (class))
5602 chainon (CLASS_RAW_IVARS (class), raw_decl);
5604 CLASS_RAW_IVARS (class) = raw_decl;
5606 field_decl = grokfield (input_filename, lineno,
5607 declarator, declspecs, width);
5609 /* Overload the public attribute, it is not used for FIELD_DECLs. */
5613 TREE_PUBLIC (field_decl) = 0;
5614 TREE_PRIVATE (field_decl) = 0;
5615 TREE_PROTECTED (field_decl) = 1;
5619 TREE_PUBLIC (field_decl) = 1;
5620 TREE_PRIVATE (field_decl) = 0;
5621 TREE_PROTECTED (field_decl) = 0;
5625 TREE_PUBLIC (field_decl) = 0;
5626 TREE_PRIVATE (field_decl) = 1;
5627 TREE_PROTECTED (field_decl) = 0;
5632 if (CLASS_IVARS (class))
5633 chainon (CLASS_IVARS (class), field_decl);
5635 CLASS_IVARS (class) = field_decl;
5641 is_ivar (decl_chain, ident)
5645 for ( ; decl_chain; decl_chain = TREE_CHAIN (decl_chain))
5646 if (DECL_NAME (decl_chain) == ident)
5651 /* True if the ivar is private and we are not in its implementation. */
5657 if (TREE_PRIVATE (decl)
5658 && ! is_ivar (CLASS_IVARS (implementation_template), DECL_NAME (decl)))
5660 error ("instance variable `%s' is declared private",
5661 IDENTIFIER_POINTER (DECL_NAME (decl)));
5668 /* We have an instance variable reference;, check to see if it is public. */
5671 is_public (expr, identifier)
5675 tree basetype = TREE_TYPE (expr);
5676 enum tree_code code = TREE_CODE (basetype);
5679 if (code == RECORD_TYPE)
5681 if (TREE_STATIC_TEMPLATE (basetype))
5683 if (!lookup_interface (TYPE_NAME (basetype)))
5685 error ("cannot find interface declaration for `%s'",
5686 IDENTIFIER_POINTER (TYPE_NAME (basetype)));
5690 if ((decl = is_ivar (TYPE_FIELDS (basetype), identifier)))
5692 if (TREE_PUBLIC (decl))
5695 /* Important difference between the Stepstone translator:
5696 all instance variables should be public within the context
5697 of the implementation. */
5698 if (objc_implementation_context
5699 && (((TREE_CODE (objc_implementation_context)
5700 == CLASS_IMPLEMENTATION_TYPE)
5701 || (TREE_CODE (objc_implementation_context)
5702 == CATEGORY_IMPLEMENTATION_TYPE))
5703 && (CLASS_NAME (objc_implementation_context)
5704 == TYPE_NAME (basetype))))
5705 return ! is_private (decl);
5707 error ("instance variable `%s' is declared %s",
5708 IDENTIFIER_POINTER (identifier),
5709 TREE_PRIVATE (decl) ? "private" : "protected");
5714 else if (objc_implementation_context && (basetype == objc_object_reference))
5716 TREE_TYPE (expr) = uprivate_record;
5717 warning ("static access to object of type `id'");
5724 /* Implement @defs (<classname>) within struct bodies. */
5727 get_class_ivars (interface)
5730 /* Make sure we copy the leaf ivars in case @defs is used in a local
5731 context. Otherwise finish_struct will overwrite the layout info
5732 using temporary storage. */
5733 return build_ivar_chain (interface, 1);
5736 /* Make sure all entries in CHAIN are also in LIST. */
5739 check_methods (chain, list, mtype)
5748 if (!lookup_method (list, chain))
5752 if (TREE_CODE (objc_implementation_context)
5753 == CLASS_IMPLEMENTATION_TYPE)
5754 warning ("incomplete implementation of class `%s'",
5755 IDENTIFIER_POINTER (CLASS_NAME (objc_implementation_context)));
5756 else if (TREE_CODE (objc_implementation_context)
5757 == CATEGORY_IMPLEMENTATION_TYPE)
5758 warning ("incomplete implementation of category `%s'",
5759 IDENTIFIER_POINTER (CLASS_SUPER_NAME (objc_implementation_context)));
5763 warning ("method definition for `%c%s' not found",
5764 mtype, IDENTIFIER_POINTER (METHOD_SEL_NAME (chain)));
5767 chain = TREE_CHAIN (chain);
5773 /* Check if CLASS, or its superclasses, explicitly conforms to PROTOCOL. */
5776 conforms_to_protocol (class, protocol)
5780 if (TREE_CODE (protocol) == PROTOCOL_INTERFACE_TYPE)
5782 tree p = CLASS_PROTOCOL_LIST (class);
5783 while (p && TREE_VALUE (p) != protocol)
5788 tree super = (CLASS_SUPER_NAME (class)
5789 ? lookup_interface (CLASS_SUPER_NAME (class))
5791 int tmp = super ? conforms_to_protocol (super, protocol) : 0;
5800 /* Make sure all methods in CHAIN are accessible as MTYPE methods in
5801 CONTEXT. This is one of two mechanisms to check protocol integrity. */
5804 check_methods_accessible (chain, context, mtype)
5811 tree base_context = context;
5815 context = base_context;
5819 list = CLASS_CLS_METHODS (context);
5821 list = CLASS_NST_METHODS (context);
5823 if (lookup_method (list, chain))
5826 else if (TREE_CODE (context) == CLASS_IMPLEMENTATION_TYPE
5827 || TREE_CODE (context) == CLASS_INTERFACE_TYPE)
5828 context = (CLASS_SUPER_NAME (context)
5829 ? lookup_interface (CLASS_SUPER_NAME (context))
5832 else if (TREE_CODE (context) == CATEGORY_IMPLEMENTATION_TYPE
5833 || TREE_CODE (context) == CATEGORY_INTERFACE_TYPE)
5834 context = (CLASS_NAME (context)
5835 ? lookup_interface (CLASS_NAME (context))
5841 if (context == NULL_TREE)
5845 if (TREE_CODE (objc_implementation_context)
5846 == CLASS_IMPLEMENTATION_TYPE)
5847 warning ("incomplete implementation of class `%s'",
5849 (CLASS_NAME (objc_implementation_context)));
5850 else if (TREE_CODE (objc_implementation_context)
5851 == CATEGORY_IMPLEMENTATION_TYPE)
5852 warning ("incomplete implementation of category `%s'",
5854 (CLASS_SUPER_NAME (objc_implementation_context)));
5857 warning ("method definition for `%c%s' not found",
5858 mtype, IDENTIFIER_POINTER (METHOD_SEL_NAME (chain)));
5861 chain = TREE_CHAIN (chain); /* next method... */
5866 /* Check whether the current interface (accessible via
5867 'objc_implementation_context') actually implements protocol P, along
5868 with any protocols that P inherits. */
5871 check_protocol (p, type, name)
5876 if (TREE_CODE (p) == PROTOCOL_INTERFACE_TYPE)
5880 /* Ensure that all protocols have bodies! */
5881 if (flag_warn_protocol)
5883 f1 = check_methods (PROTOCOL_CLS_METHODS (p),
5884 CLASS_CLS_METHODS (objc_implementation_context),
5886 f2 = check_methods (PROTOCOL_NST_METHODS (p),
5887 CLASS_NST_METHODS (objc_implementation_context),
5892 f1 = check_methods_accessible (PROTOCOL_CLS_METHODS (p),
5893 objc_implementation_context,
5895 f2 = check_methods_accessible (PROTOCOL_NST_METHODS (p),
5896 objc_implementation_context,
5901 warning ("%s `%s' does not fully implement the `%s' protocol",
5902 type, name, IDENTIFIER_POINTER (PROTOCOL_NAME (p)));
5905 /* Check protocols recursively. */
5906 if (PROTOCOL_LIST (p))
5908 tree subs = PROTOCOL_LIST (p);
5910 lookup_interface (CLASS_SUPER_NAME (implementation_template));
5914 tree sub = TREE_VALUE (subs);
5916 /* If the superclass does not conform to the protocols
5917 inherited by P, then we must! */
5918 if (!super_class || !conforms_to_protocol (super_class, sub))
5919 check_protocol (sub, type, name);
5920 subs = TREE_CHAIN (subs);
5925 /* Check whether the current interface (accessible via
5926 'objc_implementation_context') actually implements the protocols listed
5930 check_protocols (proto_list, type, name)
5935 for ( ; proto_list; proto_list = TREE_CHAIN (proto_list))
5937 tree p = TREE_VALUE (proto_list);
5939 check_protocol (p, type, name);
5943 /* Make sure that the class CLASS_NAME is defined
5944 CODE says which kind of thing CLASS_NAME ought to be.
5945 It can be CLASS_INTERFACE_TYPE, CLASS_IMPLEMENTATION_TYPE,
5946 CATEGORY_INTERFACE_TYPE, or CATEGORY_IMPLEMENTATION_TYPE. */
5949 start_class (code, class_name, super_name, protocol_list)
5950 enum tree_code code;
5957 if (objc_implementation_context)
5959 warning ("`@end' missing in implementation context");
5960 finish_class (objc_implementation_context);
5961 objc_ivar_chain = NULL_TREE;
5962 objc_implementation_context = NULL_TREE;
5965 class = make_node (code);
5966 TYPE_BINFO (class) = make_tree_vec (5);
5968 CLASS_NAME (class) = class_name;
5969 CLASS_SUPER_NAME (class) = super_name;
5970 CLASS_CLS_METHODS (class) = NULL_TREE;
5972 if (! is_class_name (class_name) && (decl = lookup_name (class_name)))
5974 error ("`%s' redeclared as different kind of symbol",
5975 IDENTIFIER_POINTER (class_name));
5976 error_with_decl (decl, "previous declaration of `%s'");
5979 if (code == CLASS_IMPLEMENTATION_TYPE)
5984 for (chain = implemented_classes; chain; chain = TREE_CHAIN (chain))
5985 if (TREE_VALUE (chain) == class_name)
5987 error ("reimplementation of class `%s'",
5988 IDENTIFIER_POINTER (class_name));
5989 return error_mark_node;
5991 implemented_classes = tree_cons (NULL_TREE, class_name,
5992 implemented_classes);
5995 /* Pre-build the following entities - for speed/convenience. */
5997 self_id = get_identifier ("self");
5999 ucmd_id = get_identifier ("_cmd");
6002 = build_tree_list (get_identifier ("__unused__"), NULL_TREE);
6003 if (!objc_super_template)
6004 objc_super_template = build_super_template ();
6006 /* Reset for multiple classes per file. */
6009 objc_implementation_context = class;
6011 /* Lookup the interface for this implementation. */
6013 if (!(implementation_template = lookup_interface (class_name)))
6015 warning ("cannot find interface declaration for `%s'",
6016 IDENTIFIER_POINTER (class_name));
6017 add_class (implementation_template = objc_implementation_context);
6020 /* If a super class has been specified in the implementation,
6021 insure it conforms to the one specified in the interface. */
6024 && (super_name != CLASS_SUPER_NAME (implementation_template)))
6026 tree previous_name = CLASS_SUPER_NAME (implementation_template);
6027 const char *const name =
6028 previous_name ? IDENTIFIER_POINTER (previous_name) : "";
6029 error ("conflicting super class name `%s'",
6030 IDENTIFIER_POINTER (super_name));
6031 error ("previous declaration of `%s'", name);
6034 else if (! super_name)
6036 CLASS_SUPER_NAME (objc_implementation_context)
6037 = CLASS_SUPER_NAME (implementation_template);
6041 else if (code == CLASS_INTERFACE_TYPE)
6043 if (lookup_interface (class_name))
6044 warning ("duplicate interface declaration for class `%s'",
6045 IDENTIFIER_POINTER (class_name));
6050 CLASS_PROTOCOL_LIST (class)
6051 = lookup_and_install_protocols (protocol_list);
6054 else if (code == CATEGORY_INTERFACE_TYPE)
6056 tree class_category_is_assoc_with;
6058 /* For a category, class_name is really the name of the class that
6059 the following set of methods will be associated with. We must
6060 find the interface so that can derive the objects template. */
6062 if (!(class_category_is_assoc_with = lookup_interface (class_name)))
6064 error ("cannot find interface declaration for `%s'",
6065 IDENTIFIER_POINTER (class_name));
6066 exit (FATAL_EXIT_CODE);
6069 add_category (class_category_is_assoc_with, class);
6072 CLASS_PROTOCOL_LIST (class)
6073 = lookup_and_install_protocols (protocol_list);
6076 else if (code == CATEGORY_IMPLEMENTATION_TYPE)
6078 /* Pre-build the following entities for speed/convenience. */
6080 self_id = get_identifier ("self");
6082 ucmd_id = get_identifier ("_cmd");
6085 = build_tree_list (get_identifier ("__unused__"), NULL_TREE);
6086 if (!objc_super_template)
6087 objc_super_template = build_super_template ();
6089 /* Reset for multiple classes per file. */
6092 objc_implementation_context = class;
6094 /* For a category, class_name is really the name of the class that
6095 the following set of methods will be associated with. We must
6096 find the interface so that can derive the objects template. */
6098 if (!(implementation_template = lookup_interface (class_name)))
6100 error ("cannot find interface declaration for `%s'",
6101 IDENTIFIER_POINTER (class_name));
6102 exit (FATAL_EXIT_CODE);
6109 continue_class (class)
6112 if (TREE_CODE (class) == CLASS_IMPLEMENTATION_TYPE
6113 || TREE_CODE (class) == CATEGORY_IMPLEMENTATION_TYPE)
6115 struct imp_entry *imp_entry;
6118 /* Check consistency of the instance variables. */
6120 if (CLASS_IVARS (class))
6121 check_ivars (implementation_template, class);
6123 /* code generation */
6125 ivar_context = build_private_template (implementation_template);
6127 if (!objc_class_template)
6128 build_class_template ();
6130 imp_entry = (struct imp_entry *) ggc_alloc (sizeof (struct imp_entry));
6132 imp_entry->next = imp_list;
6133 imp_entry->imp_context = class;
6134 imp_entry->imp_template = implementation_template;
6136 synth_forward_declarations ();
6137 imp_entry->class_decl = UOBJC_CLASS_decl;
6138 imp_entry->meta_decl = UOBJC_METACLASS_decl;
6140 /* Append to front and increment count. */
6141 imp_list = imp_entry;
6142 if (TREE_CODE (class) == CLASS_IMPLEMENTATION_TYPE)
6147 return ivar_context;
6150 else if (TREE_CODE (class) == CLASS_INTERFACE_TYPE)
6152 tree record = xref_tag (RECORD_TYPE, CLASS_NAME (class));
6154 if (!TYPE_FIELDS (record))
6156 finish_struct (record, build_ivar_chain (class, 0), NULL_TREE);
6157 CLASS_STATIC_TEMPLATE (class) = record;
6159 /* Mark this record as a class template for static typing. */
6160 TREE_STATIC_TEMPLATE (record) = 1;
6167 return error_mark_node;
6170 /* This is called once we see the "@end" in an interface/implementation. */
6173 finish_class (class)
6176 if (TREE_CODE (class) == CLASS_IMPLEMENTATION_TYPE)
6178 /* All code generation is done in finish_objc. */
6180 if (implementation_template != objc_implementation_context)
6182 /* Ensure that all method listed in the interface contain bodies. */
6183 check_methods (CLASS_CLS_METHODS (implementation_template),
6184 CLASS_CLS_METHODS (objc_implementation_context), '+');
6185 check_methods (CLASS_NST_METHODS (implementation_template),
6186 CLASS_NST_METHODS (objc_implementation_context), '-');
6188 if (CLASS_PROTOCOL_LIST (implementation_template))
6189 check_protocols (CLASS_PROTOCOL_LIST (implementation_template),
6191 IDENTIFIER_POINTER (CLASS_NAME (objc_implementation_context)));
6195 else if (TREE_CODE (class) == CATEGORY_IMPLEMENTATION_TYPE)
6197 tree category = CLASS_CATEGORY_LIST (implementation_template);
6199 /* Find the category interface from the class it is associated with. */
6202 if (CLASS_SUPER_NAME (class) == CLASS_SUPER_NAME (category))
6204 category = CLASS_CATEGORY_LIST (category);
6209 /* Ensure all method listed in the interface contain bodies. */
6210 check_methods (CLASS_CLS_METHODS (category),
6211 CLASS_CLS_METHODS (objc_implementation_context), '+');
6212 check_methods (CLASS_NST_METHODS (category),
6213 CLASS_NST_METHODS (objc_implementation_context), '-');
6215 if (CLASS_PROTOCOL_LIST (category))
6216 check_protocols (CLASS_PROTOCOL_LIST (category),
6218 IDENTIFIER_POINTER (CLASS_SUPER_NAME (objc_implementation_context)));
6222 else if (TREE_CODE (class) == CLASS_INTERFACE_TYPE)
6225 const char *class_name = IDENTIFIER_POINTER (CLASS_NAME (class));
6226 char *string = (char *) alloca (strlen (class_name) + 3);
6228 /* extern struct objc_object *_<my_name>; */
6230 sprintf (string, "_%s", class_name);
6232 decl_specs = build_tree_list (NULL_TREE, ridpointers[(int) RID_EXTERN]);
6233 decl_specs = tree_cons (NULL_TREE, objc_object_reference, decl_specs);
6234 define_decl (build1 (INDIRECT_REF, NULL_TREE, get_identifier (string)),
6240 add_protocol (protocol)
6243 /* Put protocol on list in reverse order. */
6244 TREE_CHAIN (protocol) = protocol_chain;
6245 protocol_chain = protocol;
6246 return protocol_chain;
6250 lookup_protocol (ident)
6255 for (chain = protocol_chain; chain; chain = TREE_CHAIN (chain))
6256 if (ident == PROTOCOL_NAME (chain))
6262 /* This function forward declares the protocols named by NAMES. If
6263 they are already declared or defined, the function has no effect. */
6266 objc_declare_protocols (names)
6271 for (list = names; list; list = TREE_CHAIN (list))
6273 tree name = TREE_VALUE (list);
6275 if (lookup_protocol (name) == NULL_TREE)
6277 tree protocol = make_node (PROTOCOL_INTERFACE_TYPE);
6279 TYPE_BINFO (protocol) = make_tree_vec (2);
6280 PROTOCOL_NAME (protocol) = name;
6281 PROTOCOL_LIST (protocol) = NULL_TREE;
6282 add_protocol (protocol);
6283 PROTOCOL_DEFINED (protocol) = 0;
6284 PROTOCOL_FORWARD_DECL (protocol) = NULL_TREE;
6290 start_protocol (code, name, list)
6291 enum tree_code code;
6297 /* This is as good a place as any. Need to invoke
6298 push_tag_toplevel. */
6299 if (!objc_protocol_template)
6300 objc_protocol_template = build_protocol_template ();
6302 protocol = lookup_protocol (name);
6306 protocol = make_node (code);
6307 TYPE_BINFO (protocol) = make_tree_vec (2);
6309 PROTOCOL_NAME (protocol) = name;
6310 PROTOCOL_LIST (protocol) = lookup_and_install_protocols (list);
6311 add_protocol (protocol);
6312 PROTOCOL_DEFINED (protocol) = 1;
6313 PROTOCOL_FORWARD_DECL (protocol) = NULL_TREE;
6315 check_protocol_recursively (protocol, list);
6317 else if (! PROTOCOL_DEFINED (protocol))
6319 PROTOCOL_DEFINED (protocol) = 1;
6320 PROTOCOL_LIST (protocol) = lookup_and_install_protocols (list);
6322 check_protocol_recursively (protocol, list);
6326 warning ("duplicate declaration for protocol `%s'",
6327 IDENTIFIER_POINTER (name));
6333 finish_protocol (protocol)
6334 tree protocol ATTRIBUTE_UNUSED;
6339 /* "Encode" a data type into a string, which grows in util_obstack.
6340 ??? What is the FORMAT? Someone please document this! */
6343 encode_type_qualifiers (declspecs)
6348 for (spec = declspecs; spec; spec = TREE_CHAIN (spec))
6350 if (ridpointers[(int) RID_CONST] == TREE_VALUE (spec))
6351 obstack_1grow (&util_obstack, 'r');
6352 else if (ridpointers[(int) RID_IN] == TREE_VALUE (spec))
6353 obstack_1grow (&util_obstack, 'n');
6354 else if (ridpointers[(int) RID_INOUT] == TREE_VALUE (spec))
6355 obstack_1grow (&util_obstack, 'N');
6356 else if (ridpointers[(int) RID_OUT] == TREE_VALUE (spec))
6357 obstack_1grow (&util_obstack, 'o');
6358 else if (ridpointers[(int) RID_BYCOPY] == TREE_VALUE (spec))
6359 obstack_1grow (&util_obstack, 'O');
6360 else if (ridpointers[(int) RID_BYREF] == TREE_VALUE (spec))
6361 obstack_1grow (&util_obstack, 'R');
6362 else if (ridpointers[(int) RID_ONEWAY] == TREE_VALUE (spec))
6363 obstack_1grow (&util_obstack, 'V');
6367 /* Encode a pointer type. */
6370 encode_pointer (type, curtype, format)
6375 tree pointer_to = TREE_TYPE (type);
6377 if (TREE_CODE (pointer_to) == RECORD_TYPE)
6379 if (TYPE_NAME (pointer_to)
6380 && TREE_CODE (TYPE_NAME (pointer_to)) == IDENTIFIER_NODE)
6382 const char *name = IDENTIFIER_POINTER (TYPE_NAME (pointer_to));
6384 if (strcmp (name, TAG_OBJECT) == 0) /* '@' */
6386 obstack_1grow (&util_obstack, '@');
6389 else if (TREE_STATIC_TEMPLATE (pointer_to))
6391 if (generating_instance_variables)
6393 obstack_1grow (&util_obstack, '@');
6394 obstack_1grow (&util_obstack, '"');
6395 obstack_grow (&util_obstack, name, strlen (name));
6396 obstack_1grow (&util_obstack, '"');
6401 obstack_1grow (&util_obstack, '@');
6405 else if (strcmp (name, TAG_CLASS) == 0) /* '#' */
6407 obstack_1grow (&util_obstack, '#');
6410 else if (strcmp (name, TAG_SELECTOR) == 0) /* ':' */
6412 obstack_1grow (&util_obstack, ':');
6417 else if (TREE_CODE (pointer_to) == INTEGER_TYPE
6418 && TYPE_MODE (pointer_to) == QImode)
6420 obstack_1grow (&util_obstack, '*');
6424 /* We have a type that does not get special treatment. */
6426 /* NeXT extension */
6427 obstack_1grow (&util_obstack, '^');
6428 encode_type (pointer_to, curtype, format);
6432 encode_array (type, curtype, format)
6437 tree an_int_cst = TYPE_SIZE (type);
6438 tree array_of = TREE_TYPE (type);
6441 /* An incomplete array is treated like a pointer. */
6442 if (an_int_cst == NULL)
6444 encode_pointer (type, curtype, format);
6448 sprintf (buffer, "[%ld",
6449 (long) (TREE_INT_CST_LOW (an_int_cst)
6450 / TREE_INT_CST_LOW (TYPE_SIZE (array_of))));
6452 obstack_grow (&util_obstack, buffer, strlen (buffer));
6453 encode_type (array_of, curtype, format);
6454 obstack_1grow (&util_obstack, ']');
6459 encode_aggregate_within (type, curtype, format, left, right)
6466 /* The RECORD_TYPE may in fact be a typedef! For purposes
6467 of encoding, we need the real underlying enchilada. */
6468 if (TYPE_MAIN_VARIANT (type))
6469 type = TYPE_MAIN_VARIANT (type);
6471 if (obstack_object_size (&util_obstack) > 0
6472 && *(obstack_next_free (&util_obstack) - 1) == '^')
6474 tree name = TYPE_NAME (type);
6476 /* we have a reference; this is a NeXT extension. */
6478 if (obstack_object_size (&util_obstack) - curtype == 1
6479 && format == OBJC_ENCODE_INLINE_DEFS)
6481 /* Output format of struct for first level only. */
6482 tree fields = TYPE_FIELDS (type);
6484 if (name && TREE_CODE (name) == IDENTIFIER_NODE)
6486 obstack_1grow (&util_obstack, left);
6487 obstack_grow (&util_obstack,
6488 IDENTIFIER_POINTER (name),
6489 strlen (IDENTIFIER_POINTER (name)));
6490 obstack_1grow (&util_obstack, '=');
6494 obstack_1grow (&util_obstack, left);
6495 obstack_grow (&util_obstack, "?=", 2);
6498 for ( ; fields; fields = TREE_CHAIN (fields))
6499 encode_field_decl (fields, curtype, format);
6501 obstack_1grow (&util_obstack, right);
6504 else if (name && TREE_CODE (name) == IDENTIFIER_NODE)
6506 obstack_1grow (&util_obstack, left);
6507 obstack_grow (&util_obstack,
6508 IDENTIFIER_POINTER (name),
6509 strlen (IDENTIFIER_POINTER (name)));
6510 obstack_1grow (&util_obstack, right);
6515 /* We have an untagged structure or a typedef. */
6516 obstack_1grow (&util_obstack, left);
6517 obstack_1grow (&util_obstack, '?');
6518 obstack_1grow (&util_obstack, right);
6524 tree name = TYPE_NAME (type);
6525 tree fields = TYPE_FIELDS (type);
6527 if (format == OBJC_ENCODE_INLINE_DEFS
6528 || generating_instance_variables)
6530 obstack_1grow (&util_obstack, left);
6531 if (name && TREE_CODE (name) == IDENTIFIER_NODE)
6532 obstack_grow (&util_obstack,
6533 IDENTIFIER_POINTER (name),
6534 strlen (IDENTIFIER_POINTER (name)));
6536 obstack_1grow (&util_obstack, '?');
6538 obstack_1grow (&util_obstack, '=');
6540 for (; fields; fields = TREE_CHAIN (fields))
6542 if (generating_instance_variables)
6544 tree fname = DECL_NAME (fields);
6546 obstack_1grow (&util_obstack, '"');
6547 if (fname && TREE_CODE (fname) == IDENTIFIER_NODE)
6549 obstack_grow (&util_obstack,
6550 IDENTIFIER_POINTER (fname),
6551 strlen (IDENTIFIER_POINTER (fname)));
6554 obstack_1grow (&util_obstack, '"');
6557 encode_field_decl (fields, curtype, format);
6560 obstack_1grow (&util_obstack, right);
6565 obstack_1grow (&util_obstack, left);
6566 if (name && TREE_CODE (name) == IDENTIFIER_NODE)
6567 obstack_grow (&util_obstack,
6568 IDENTIFIER_POINTER (name),
6569 strlen (IDENTIFIER_POINTER (name)));
6571 /* We have an untagged structure or a typedef. */
6572 obstack_1grow (&util_obstack, '?');
6574 obstack_1grow (&util_obstack, right);
6580 encode_aggregate (type, curtype, format)
6585 enum tree_code code = TREE_CODE (type);
6591 encode_aggregate_within(type, curtype, format, '{', '}');
6596 encode_aggregate_within(type, curtype, format, '(', ')');
6601 obstack_1grow (&util_obstack, 'i');
6609 /* Support bitfields. The current version of Objective-C does not support
6610 them. The string will consist of one or more "b:n"'s where n is an
6611 integer describing the width of the bitfield. Currently, classes in
6612 the kit implement a method "-(char *)describeBitfieldStruct:" that
6613 simulates this. If they do not implement this method, the archiver
6614 assumes the bitfield is 16 bits wide (padded if necessary) and packed
6615 according to the GNU compiler. After looking at the "kit", it appears
6616 that all classes currently rely on this default behavior, rather than
6617 hand generating this string (which is tedious). */
6620 encode_bitfield (width)
6624 sprintf (buffer, "b%d", width);
6625 obstack_grow (&util_obstack, buffer, strlen (buffer));
6628 /* FORMAT will be OBJC_ENCODE_INLINE_DEFS or OBJC_ENCODE_DONT_INLINE_DEFS. */
6631 encode_type (type, curtype, format)
6636 enum tree_code code = TREE_CODE (type);
6638 if (code == INTEGER_TYPE)
6640 if (integer_zerop (TYPE_MIN_VALUE (type)))
6642 /* Unsigned integer types. */
6644 if (TYPE_MODE (type) == QImode)
6645 obstack_1grow (&util_obstack, 'C');
6646 else if (TYPE_MODE (type) == HImode)
6647 obstack_1grow (&util_obstack, 'S');
6648 else if (TYPE_MODE (type) == SImode)
6650 if (type == long_unsigned_type_node)
6651 obstack_1grow (&util_obstack, 'L');
6653 obstack_1grow (&util_obstack, 'I');
6655 else if (TYPE_MODE (type) == DImode)
6656 obstack_1grow (&util_obstack, 'Q');
6660 /* Signed integer types. */
6662 if (TYPE_MODE (type) == QImode)
6663 obstack_1grow (&util_obstack, 'c');
6664 else if (TYPE_MODE (type) == HImode)
6665 obstack_1grow (&util_obstack, 's');
6666 else if (TYPE_MODE (type) == SImode)
6668 if (type == long_integer_type_node)
6669 obstack_1grow (&util_obstack, 'l');
6671 obstack_1grow (&util_obstack, 'i');
6674 else if (TYPE_MODE (type) == DImode)
6675 obstack_1grow (&util_obstack, 'q');
6679 else if (code == REAL_TYPE)
6681 /* Floating point types. */
6683 if (TYPE_MODE (type) == SFmode)
6684 obstack_1grow (&util_obstack, 'f');
6685 else if (TYPE_MODE (type) == DFmode
6686 || TYPE_MODE (type) == TFmode)
6687 obstack_1grow (&util_obstack, 'd');
6690 else if (code == VOID_TYPE)
6691 obstack_1grow (&util_obstack, 'v');
6693 else if (code == ARRAY_TYPE)
6694 encode_array (type, curtype, format);
6696 else if (code == POINTER_TYPE)
6697 encode_pointer (type, curtype, format);
6699 else if (code == RECORD_TYPE || code == UNION_TYPE || code == ENUMERAL_TYPE)
6700 encode_aggregate (type, curtype, format);
6702 else if (code == FUNCTION_TYPE) /* '?' */
6703 obstack_1grow (&util_obstack, '?');
6707 encode_complete_bitfield (int position, tree type, int size)
6709 enum tree_code code = TREE_CODE (type);
6711 char charType = '?';
6713 if (code == INTEGER_TYPE)
6715 if (integer_zerop (TYPE_MIN_VALUE (type)))
6717 /* Unsigned integer types. */
6719 if (TYPE_MODE (type) == QImode)
6721 else if (TYPE_MODE (type) == HImode)
6723 else if (TYPE_MODE (type) == SImode)
6725 if (type == long_unsigned_type_node)
6730 else if (TYPE_MODE (type) == DImode)
6735 /* Signed integer types. */
6737 if (TYPE_MODE (type) == QImode)
6739 else if (TYPE_MODE (type) == HImode)
6741 else if (TYPE_MODE (type) == SImode)
6743 if (type == long_integer_type_node)
6749 else if (TYPE_MODE (type) == DImode)
6753 else if (code == ENUMERAL_TYPE)
6758 sprintf (buffer, "b%d%c%d", position, charType, size);
6759 obstack_grow (&util_obstack, buffer, strlen (buffer));
6763 encode_field_decl (field_decl, curtype, format)
6770 type = TREE_TYPE (field_decl);
6772 /* If this field is obviously a bitfield, or is a bitfield that has been
6773 clobbered to look like a ordinary integer mode, go ahead and generate
6774 the bitfield typing information. */
6775 if (flag_next_runtime)
6777 if (DECL_BIT_FIELD (field_decl))
6778 encode_bitfield (tree_low_cst (DECL_SIZE (field_decl), 1));
6780 encode_type (TREE_TYPE (field_decl), curtype, format);
6784 if (DECL_BIT_FIELD (field_decl))
6785 encode_complete_bitfield (int_bit_position (field_decl),
6786 DECL_BIT_FIELD_TYPE (field_decl),
6787 tree_low_cst (DECL_SIZE (field_decl), 1));
6789 encode_type (TREE_TYPE (field_decl), curtype, format);
6794 expr_last (complex_expr)
6800 while ((next = TREE_OPERAND (complex_expr, 0)))
6801 complex_expr = next;
6803 return complex_expr;
6806 /* Transform a method definition into a function definition as follows:
6807 - synthesize the first two arguments, "self" and "_cmd". */
6810 start_method_def (method)
6815 /* Required to implement _msgSuper. */
6816 objc_method_context = method;
6817 UOBJC_SUPER_decl = NULL_TREE;
6819 /* Must be called BEFORE start_function. */
6822 /* Generate prototype declarations for arguments..."new-style". */
6824 if (TREE_CODE (objc_method_context) == INSTANCE_METHOD_DECL)
6825 decl_specs = build_tree_list (NULL_TREE, uprivate_record);
6827 /* Really a `struct objc_class *'. However, we allow people to
6828 assign to self, which changes its type midstream. */
6829 decl_specs = build_tree_list (NULL_TREE, objc_object_reference);
6831 push_parm_decl (build_tree_list
6832 (build_tree_list (decl_specs,
6833 build1 (INDIRECT_REF, NULL_TREE, self_id)),
6836 decl_specs = build_tree_list (NULL_TREE,
6837 xref_tag (RECORD_TYPE,
6838 get_identifier (TAG_SELECTOR)));
6839 push_parm_decl (build_tree_list
6840 (build_tree_list (decl_specs,
6841 build1 (INDIRECT_REF, NULL_TREE, ucmd_id)),
6844 /* Generate argument declarations if a keyword_decl. */
6845 if (METHOD_SEL_ARGS (method))
6847 tree arglist = METHOD_SEL_ARGS (method);
6850 tree arg_spec = TREE_PURPOSE (TREE_TYPE (arglist));
6851 tree arg_decl = TREE_VALUE (TREE_TYPE (arglist));
6855 tree last_expr = expr_last (arg_decl);
6857 /* Unite the abstract decl with its name. */
6858 TREE_OPERAND (last_expr, 0) = KEYWORD_ARG_NAME (arglist);
6859 push_parm_decl (build_tree_list
6860 (build_tree_list (arg_spec, arg_decl),
6863 /* Unhook: restore the abstract declarator. */
6864 TREE_OPERAND (last_expr, 0) = NULL_TREE;
6868 push_parm_decl (build_tree_list
6869 (build_tree_list (arg_spec,
6870 KEYWORD_ARG_NAME (arglist)),
6873 arglist = TREE_CHAIN (arglist);
6878 if (METHOD_ADD_ARGS (method) != NULL_TREE
6879 && METHOD_ADD_ARGS (method) != objc_ellipsis_node)
6881 /* We have a variable length selector - in "prototype" format. */
6882 tree akey = TREE_PURPOSE (METHOD_ADD_ARGS (method));
6885 /* This must be done prior to calling pushdecl. pushdecl is
6886 going to change our chain on us. */
6887 tree nextkey = TREE_CHAIN (akey);
6895 warn_with_method (message, mtype, method)
6896 const char *message;
6900 if (!diagnostic_count_diagnostic (global_dc, DK_WARNING))
6903 diagnostic_report_current_function (global_dc);
6905 /* Add a readable method name to the warning. */
6906 warning_with_file_and_line (DECL_SOURCE_FILE (method),
6907 DECL_SOURCE_LINE (method),
6910 gen_method_decl (method, errbuf));
6913 /* Return 1 if METHOD is consistent with PROTO. */
6916 comp_method_with_proto (method, proto)
6919 /* Create a function template node at most once. */
6920 if (!function1_template)
6921 function1_template = make_node (FUNCTION_TYPE);
6923 /* Install argument types - normally set by build_function_type. */
6924 TYPE_ARG_TYPES (function1_template) = get_arg_type_list (proto, METHOD_DEF, 0);
6926 /* install return type */
6927 TREE_TYPE (function1_template) = groktypename (TREE_TYPE (proto));
6929 return comptypes (TREE_TYPE (METHOD_DEFINITION (method)), function1_template);
6932 /* Return 1 if PROTO1 is consistent with PROTO2. */
6935 comp_proto_with_proto (proto0, proto1)
6936 tree proto0, proto1;
6938 /* Create a couple of function_template nodes at most once. */
6939 if (!function1_template)
6940 function1_template = make_node (FUNCTION_TYPE);
6941 if (!function2_template)
6942 function2_template = make_node (FUNCTION_TYPE);
6944 /* Install argument types; normally set by build_function_type. */
6945 TYPE_ARG_TYPES (function1_template) = get_arg_type_list (proto0, METHOD_REF, 0);
6946 TYPE_ARG_TYPES (function2_template) = get_arg_type_list (proto1, METHOD_REF, 0);
6948 /* Install return type. */
6949 TREE_TYPE (function1_template) = groktypename (TREE_TYPE (proto0));
6950 TREE_TYPE (function2_template) = groktypename (TREE_TYPE (proto1));
6952 return comptypes (function1_template, function2_template);
6955 /* - Generate an identifier for the function. the format is "_n_cls",
6956 where 1 <= n <= nMethods, and cls is the name the implementation we
6958 - Install the return type from the method declaration.
6959 - If we have a prototype, check for type consistency. */
6962 really_start_method (method, parmlist)
6963 tree method, parmlist;
6965 tree sc_spec, ret_spec, ret_decl, decl_specs;
6966 tree method_decl, method_id;
6967 const char *sel_name, *class_name, *cat_name;
6970 /* Synth the storage class & assemble the return type. */
6971 sc_spec = tree_cons (NULL_TREE, ridpointers[(int) RID_STATIC], NULL_TREE);
6972 ret_spec = TREE_PURPOSE (TREE_TYPE (method));
6973 decl_specs = chainon (sc_spec, ret_spec);
6975 sel_name = IDENTIFIER_POINTER (METHOD_SEL_NAME (method));
6976 class_name = IDENTIFIER_POINTER (CLASS_NAME (objc_implementation_context));
6977 cat_name = ((TREE_CODE (objc_implementation_context)
6978 == CLASS_IMPLEMENTATION_TYPE)
6980 : IDENTIFIER_POINTER (CLASS_SUPER_NAME (objc_implementation_context)));
6983 /* Make sure this is big enough for any plausible method label. */
6984 buf = (char *) alloca (50 + strlen (sel_name) + strlen (class_name)
6985 + (cat_name ? strlen (cat_name) : 0));
6987 OBJC_GEN_METHOD_LABEL (buf, TREE_CODE (method) == INSTANCE_METHOD_DECL,
6988 class_name, cat_name, sel_name, method_slot);
6990 method_id = get_identifier (buf);
6992 method_decl = build_nt (CALL_EXPR, method_id, parmlist, NULL_TREE);
6994 /* Check the declarator portion of the return type for the method. */
6995 if ((ret_decl = TREE_VALUE (TREE_TYPE (method))))
6997 /* Unite the complex decl (specified in the abstract decl) with the
6998 function decl just synthesized..(int *), (int (*)()), (int (*)[]). */
6999 tree save_expr = expr_last (ret_decl);
7001 TREE_OPERAND (save_expr, 0) = method_decl;
7002 method_decl = ret_decl;
7004 /* Fool the parser into thinking it is starting a function. */
7005 start_function (decl_specs, method_decl, NULL_TREE);
7007 /* Unhook: this has the effect of restoring the abstract declarator. */
7008 TREE_OPERAND (save_expr, 0) = NULL_TREE;
7013 TREE_VALUE (TREE_TYPE (method)) = method_decl;
7015 /* Fool the parser into thinking it is starting a function. */
7016 start_function (decl_specs, method_decl, NULL_TREE);
7018 /* Unhook: this has the effect of restoring the abstract declarator. */
7019 TREE_VALUE (TREE_TYPE (method)) = NULL_TREE;
7022 METHOD_DEFINITION (method) = current_function_decl;
7024 /* Check consistency...start_function, pushdecl, duplicate_decls. */
7026 if (implementation_template != objc_implementation_context)
7030 if (TREE_CODE (method) == INSTANCE_METHOD_DECL)
7031 proto = lookup_instance_method_static (implementation_template,
7032 METHOD_SEL_NAME (method));
7034 proto = lookup_class_method_static (implementation_template,
7035 METHOD_SEL_NAME (method));
7037 if (proto && ! comp_method_with_proto (method, proto))
7039 char type = (TREE_CODE (method) == INSTANCE_METHOD_DECL ? '-' : '+');
7041 warn_with_method ("conflicting types for", type, method);
7042 warn_with_method ("previous declaration of", type, proto);
7047 /* The following routine is always called...this "architecture" is to
7048 accommodate "old-style" variable length selectors.
7050 - a:a b:b // prototype ; id c; id d; // old-style. */
7053 continue_method_def ()
7057 if (METHOD_ADD_ARGS (objc_method_context) == objc_ellipsis_node)
7058 /* We have a `, ...' immediately following the selector. */
7059 parmlist = get_parm_info (0);
7061 parmlist = get_parm_info (1); /* place a `void_at_end' */
7063 /* Set self_decl from the first argument...this global is used by
7064 build_ivar_reference calling build_indirect_ref. */
7065 self_decl = TREE_PURPOSE (parmlist);
7068 really_start_method (objc_method_context, parmlist);
7069 store_parm_decls ();
7072 /* Called by the parser, from the `pushlevel' production. */
7077 if (!UOBJC_SUPER_decl)
7079 UOBJC_SUPER_decl = start_decl (get_identifier (UTAG_SUPER),
7080 build_tree_list (NULL_TREE,
7081 objc_super_template),
7084 finish_decl (UOBJC_SUPER_decl, NULL_TREE, NULL_TREE);
7086 /* This prevents `unused variable' warnings when compiling with -Wall. */
7087 TREE_USED (UOBJC_SUPER_decl) = 1;
7088 DECL_ARTIFICIAL (UOBJC_SUPER_decl) = 1;
7092 /* _n_Method (id self, SEL sel, ...)
7094 struct objc_super _S;
7095 _msgSuper ((_S.self = self, _S.class = _cls, &_S), ...);
7099 get_super_receiver ()
7101 if (objc_method_context)
7103 tree super_expr, super_expr_list;
7105 /* Set receiver to self. */
7106 super_expr = build_component_ref (UOBJC_SUPER_decl, self_id);
7107 super_expr = build_modify_expr (super_expr, NOP_EXPR, self_decl);
7108 super_expr_list = build_tree_list (NULL_TREE, super_expr);
7110 /* Set class to begin searching. */
7111 super_expr = build_component_ref (UOBJC_SUPER_decl,
7112 get_identifier ("class"));
7114 if (TREE_CODE (objc_implementation_context) == CLASS_IMPLEMENTATION_TYPE)
7116 /* [_cls, __cls]Super are "pre-built" in
7117 synth_forward_declarations. */
7119 super_expr = build_modify_expr (super_expr, NOP_EXPR,
7120 ((TREE_CODE (objc_method_context)
7121 == INSTANCE_METHOD_DECL)
7123 : uucls_super_ref));
7127 /* We have a category. */
7129 tree super_name = CLASS_SUPER_NAME (implementation_template);
7132 /* Barf if super used in a category of Object. */
7135 error ("no super class declared in interface for `%s'",
7136 IDENTIFIER_POINTER (CLASS_NAME (implementation_template)));
7137 return error_mark_node;
7140 if (flag_next_runtime)
7142 super_class = get_class_reference (super_name);
7143 if (TREE_CODE (objc_method_context) == CLASS_METHOD_DECL)
7145 = build_component_ref (build_indirect_ref (super_class, "->"),
7146 get_identifier ("isa"));
7150 add_class_reference (super_name);
7151 super_class = (TREE_CODE (objc_method_context) == INSTANCE_METHOD_DECL
7152 ? objc_get_class_decl : objc_get_meta_class_decl);
7153 assemble_external (super_class);
7155 = build_function_call
7159 my_build_string (IDENTIFIER_LENGTH (super_name) + 1,
7160 IDENTIFIER_POINTER (super_name))));
7163 TREE_TYPE (super_class) = TREE_TYPE (ucls_super_ref);
7164 super_expr = build_modify_expr (super_expr, NOP_EXPR, super_class);
7167 chainon (super_expr_list, build_tree_list (NULL_TREE, super_expr));
7169 super_expr = build_unary_op (ADDR_EXPR, UOBJC_SUPER_decl, 0);
7170 chainon (super_expr_list, build_tree_list (NULL_TREE, super_expr));
7172 return build_compound_expr (super_expr_list);
7176 error ("[super ...] must appear in a method context");
7177 return error_mark_node;
7182 encode_method_def (func_decl)
7187 HOST_WIDE_INT max_parm_end = 0;
7192 encode_type (TREE_TYPE (TREE_TYPE (func_decl)),
7193 obstack_object_size (&util_obstack),
7194 OBJC_ENCODE_INLINE_DEFS);
7197 for (parms = DECL_ARGUMENTS (func_decl); parms;
7198 parms = TREE_CHAIN (parms))
7200 HOST_WIDE_INT parm_end = (forwarding_offset (parms)
7201 + int_size_in_bytes (TREE_TYPE (parms)));
7203 if (! offset_is_register && parm_end > max_parm_end)
7204 max_parm_end = parm_end;
7207 stack_size = max_parm_end - OBJC_FORWARDING_MIN_OFFSET;
7209 sprintf (buffer, "%d", stack_size);
7210 obstack_grow (&util_obstack, buffer, strlen (buffer));
7212 /* Argument types. */
7213 for (parms = DECL_ARGUMENTS (func_decl); parms;
7214 parms = TREE_CHAIN (parms))
7217 encode_type (TREE_TYPE (parms),
7218 obstack_object_size (&util_obstack),
7219 OBJC_ENCODE_INLINE_DEFS);
7221 /* Compute offset. */
7222 sprintf (buffer, "%d", forwarding_offset (parms));
7224 /* Indicate register. */
7225 if (offset_is_register)
7226 obstack_1grow (&util_obstack, '+');
7228 obstack_grow (&util_obstack, buffer, strlen (buffer));
7231 /* Null terminate string. */
7232 obstack_1grow (&util_obstack, 0);
7233 result = get_identifier (obstack_finish (&util_obstack));
7234 obstack_free (&util_obstack, util_firstobj);
7239 objc_expand_function_end ()
7241 METHOD_ENCODING (objc_method_context) = encode_method_def (current_function_decl);
7245 finish_method_def ()
7247 lang_expand_function_end = objc_expand_function_end;
7248 finish_function (0, 1);
7249 lang_expand_function_end = NULL;
7251 /* Required to implement _msgSuper. This must be done AFTER finish_function,
7252 since the optimizer may find "may be used before set" errors. */
7253 objc_method_context = NULL_TREE;
7258 lang_report_error_function (decl)
7261 if (objc_method_context)
7263 fprintf (stderr, "In method `%s'\n",
7264 IDENTIFIER_POINTER (METHOD_SEL_NAME (objc_method_context)));
7274 is_complex_decl (type)
7277 return (TREE_CODE (type) == ARRAY_TYPE
7278 || TREE_CODE (type) == FUNCTION_TYPE
7279 || (TREE_CODE (type) == POINTER_TYPE && ! IS_ID (type)));
7283 /* Code to convert a decl node into text for a declaration in C. */
7285 static char tmpbuf[256];
7288 adorn_decl (decl, str)
7292 enum tree_code code = TREE_CODE (decl);
7294 if (code == ARRAY_REF)
7296 tree an_int_cst = TREE_OPERAND (decl, 1);
7298 if (an_int_cst && TREE_CODE (an_int_cst) == INTEGER_CST)
7299 sprintf (str + strlen (str), "[%ld]",
7300 (long) TREE_INT_CST_LOW (an_int_cst));
7305 else if (code == ARRAY_TYPE)
7307 tree an_int_cst = TYPE_SIZE (decl);
7308 tree array_of = TREE_TYPE (decl);
7310 if (an_int_cst && TREE_CODE (an_int_cst) == INTEGER_TYPE)
7311 sprintf (str + strlen (str), "[%ld]",
7312 (long) (TREE_INT_CST_LOW (an_int_cst)
7313 / TREE_INT_CST_LOW (TYPE_SIZE (array_of))));
7318 else if (code == CALL_EXPR)
7320 tree chain = TREE_PURPOSE (TREE_OPERAND (decl, 1));
7325 gen_declaration_1 (chain, str);
7326 chain = TREE_CHAIN (chain);
7333 else if (code == FUNCTION_TYPE)
7335 tree chain = TYPE_ARG_TYPES (decl);
7338 while (chain && TREE_VALUE (chain) != void_type_node)
7340 gen_declaration_1 (TREE_VALUE (chain), str);
7341 chain = TREE_CHAIN (chain);
7342 if (chain && TREE_VALUE (chain) != void_type_node)
7348 else if (code == INDIRECT_REF)
7350 strcpy (tmpbuf, "*");
7351 if (TREE_TYPE (decl) && TREE_CODE (TREE_TYPE (decl)) == TREE_LIST)
7355 for (chain = nreverse (copy_list (TREE_TYPE (decl)));
7357 chain = TREE_CHAIN (chain))
7359 if (TREE_CODE (TREE_VALUE (chain)) == IDENTIFIER_NODE)
7361 strcat (tmpbuf, " ");
7362 strcat (tmpbuf, IDENTIFIER_POINTER (TREE_VALUE (chain)));
7366 strcat (tmpbuf, " ");
7368 strcat (tmpbuf, str);
7369 strcpy (str, tmpbuf);
7372 else if (code == POINTER_TYPE)
7374 strcpy (tmpbuf, "*");
7375 if (TREE_READONLY (decl) || TYPE_VOLATILE (decl))
7377 if (TREE_READONLY (decl))
7378 strcat (tmpbuf, " const");
7379 if (TYPE_VOLATILE (decl))
7380 strcat (tmpbuf, " volatile");
7382 strcat (tmpbuf, " ");
7384 strcat (tmpbuf, str);
7385 strcpy (str, tmpbuf);
7390 gen_declarator (decl, buf, name)
7397 enum tree_code code = TREE_CODE (decl);
7407 op = TREE_OPERAND (decl, 0);
7409 /* We have a pointer to a function or array...(*)(), (*)[] */
7410 if ((code == ARRAY_REF || code == CALL_EXPR)
7411 && op && TREE_CODE (op) == INDIRECT_REF)
7414 str = gen_declarator (op, buf, name);
7418 strcpy (tmpbuf, "(");
7419 strcat (tmpbuf, str);
7420 strcat (tmpbuf, ")");
7421 strcpy (str, tmpbuf);
7424 adorn_decl (decl, str);
7433 /* This clause is done iteratively rather than recursively. */
7436 op = (is_complex_decl (TREE_TYPE (decl))
7437 ? TREE_TYPE (decl) : NULL_TREE);
7439 adorn_decl (decl, str);
7441 /* We have a pointer to a function or array...(*)(), (*)[] */
7442 if (code == POINTER_TYPE
7443 && op && (TREE_CODE (op) == FUNCTION_TYPE
7444 || TREE_CODE (op) == ARRAY_TYPE))
7446 strcpy (tmpbuf, "(");
7447 strcat (tmpbuf, str);
7448 strcat (tmpbuf, ")");
7449 strcpy (str, tmpbuf);
7452 decl = (is_complex_decl (TREE_TYPE (decl))
7453 ? TREE_TYPE (decl) : NULL_TREE);
7456 while (decl && (code = TREE_CODE (decl)))
7461 case IDENTIFIER_NODE:
7462 /* Will only happen if we are processing a "raw" expr-decl. */
7463 strcpy (buf, IDENTIFIER_POINTER (decl));
7474 /* We have an abstract declarator or a _DECL node. */
7482 gen_declspecs (declspecs, buf, raw)
7491 for (chain = nreverse (copy_list (declspecs));
7492 chain; chain = TREE_CHAIN (chain))
7494 tree aspec = TREE_VALUE (chain);
7496 if (TREE_CODE (aspec) == IDENTIFIER_NODE)
7497 strcat (buf, IDENTIFIER_POINTER (aspec));
7498 else if (TREE_CODE (aspec) == RECORD_TYPE)
7500 if (TYPE_NAME (aspec))
7502 tree protocol_list = TYPE_PROTOCOL_LIST (aspec);
7504 if (! TREE_STATIC_TEMPLATE (aspec))
7505 strcat (buf, "struct ");
7506 strcat (buf, IDENTIFIER_POINTER (TYPE_NAME (aspec)));
7511 tree chain = protocol_list;
7518 (PROTOCOL_NAME (TREE_VALUE (chain))));
7519 chain = TREE_CHAIN (chain);
7528 strcat (buf, "untagged struct");
7531 else if (TREE_CODE (aspec) == UNION_TYPE)
7533 if (TYPE_NAME (aspec))
7535 if (! TREE_STATIC_TEMPLATE (aspec))
7536 strcat (buf, "union ");
7537 strcat (buf, IDENTIFIER_POINTER (TYPE_NAME (aspec)));
7540 strcat (buf, "untagged union");
7543 else if (TREE_CODE (aspec) == ENUMERAL_TYPE)
7545 if (TYPE_NAME (aspec))
7547 if (! TREE_STATIC_TEMPLATE (aspec))
7548 strcat (buf, "enum ");
7549 strcat (buf, IDENTIFIER_POINTER (TYPE_NAME (aspec)));
7552 strcat (buf, "untagged enum");
7555 else if (TREE_CODE (aspec) == TYPE_DECL && DECL_NAME (aspec))
7556 strcat (buf, IDENTIFIER_POINTER (DECL_NAME (aspec)));
7558 else if (IS_ID (aspec))
7560 tree protocol_list = TYPE_PROTOCOL_LIST (aspec);
7565 tree chain = protocol_list;
7572 (PROTOCOL_NAME (TREE_VALUE (chain))));
7573 chain = TREE_CHAIN (chain);
7580 if (TREE_CHAIN (chain))
7586 /* Type qualifiers. */
7587 if (TREE_READONLY (declspecs))
7588 strcat (buf, "const ");
7589 if (TYPE_VOLATILE (declspecs))
7590 strcat (buf, "volatile ");
7592 switch (TREE_CODE (declspecs))
7594 /* Type specifiers. */
7597 declspecs = TYPE_MAIN_VARIANT (declspecs);
7599 /* Signed integer types. */
7601 if (declspecs == short_integer_type_node)
7602 strcat (buf, "short int ");
7603 else if (declspecs == integer_type_node)
7604 strcat (buf, "int ");
7605 else if (declspecs == long_integer_type_node)
7606 strcat (buf, "long int ");
7607 else if (declspecs == long_long_integer_type_node)
7608 strcat (buf, "long long int ");
7609 else if (declspecs == signed_char_type_node
7610 || declspecs == char_type_node)
7611 strcat (buf, "char ");
7613 /* Unsigned integer types. */
7615 else if (declspecs == short_unsigned_type_node)
7616 strcat (buf, "unsigned short ");
7617 else if (declspecs == unsigned_type_node)
7618 strcat (buf, "unsigned int ");
7619 else if (declspecs == long_unsigned_type_node)
7620 strcat (buf, "unsigned long ");
7621 else if (declspecs == long_long_unsigned_type_node)
7622 strcat (buf, "unsigned long long ");
7623 else if (declspecs == unsigned_char_type_node)
7624 strcat (buf, "unsigned char ");
7628 declspecs = TYPE_MAIN_VARIANT (declspecs);
7630 if (declspecs == float_type_node)
7631 strcat (buf, "float ");
7632 else if (declspecs == double_type_node)
7633 strcat (buf, "double ");
7634 else if (declspecs == long_double_type_node)
7635 strcat (buf, "long double ");
7639 if (TYPE_NAME (declspecs)
7640 && TREE_CODE (TYPE_NAME (declspecs)) == IDENTIFIER_NODE)
7642 tree protocol_list = TYPE_PROTOCOL_LIST (declspecs);
7644 if (! TREE_STATIC_TEMPLATE (declspecs))
7645 strcat (buf, "struct ");
7646 strcat (buf, IDENTIFIER_POINTER (TYPE_NAME (declspecs)));
7650 tree chain = protocol_list;
7657 (PROTOCOL_NAME (TREE_VALUE (chain))));
7658 chain = TREE_CHAIN (chain);
7667 strcat (buf, "untagged struct");
7673 if (TYPE_NAME (declspecs)
7674 && TREE_CODE (TYPE_NAME (declspecs)) == IDENTIFIER_NODE)
7676 strcat (buf, "union ");
7677 strcat (buf, IDENTIFIER_POINTER (TYPE_NAME (declspecs)));
7682 strcat (buf, "untagged union ");
7686 if (TYPE_NAME (declspecs)
7687 && TREE_CODE (TYPE_NAME (declspecs)) == IDENTIFIER_NODE)
7689 strcat (buf, "enum ");
7690 strcat (buf, IDENTIFIER_POINTER (TYPE_NAME (declspecs)));
7695 strcat (buf, "untagged enum ");
7699 strcat (buf, "void ");
7704 tree protocol_list = TYPE_PROTOCOL_LIST (declspecs);
7709 tree chain = protocol_list;
7716 (PROTOCOL_NAME (TREE_VALUE (chain))));
7717 chain = TREE_CHAIN (chain);
7733 /* Given a tree node, produce a printable description of it in the given
7734 buffer, overwriting the buffer. */
7737 gen_declaration (atype_or_adecl, buf)
7738 tree atype_or_adecl;
7742 gen_declaration_1 (atype_or_adecl, buf);
7746 /* Given a tree node, append a printable description to the end of the
7750 gen_declaration_1 (atype_or_adecl, buf)
7751 tree atype_or_adecl;
7756 if (TREE_CODE (atype_or_adecl) == TREE_LIST)
7758 tree declspecs; /* "identifier_node", "record_type" */
7759 tree declarator; /* "array_ref", "indirect_ref", "call_expr"... */
7761 /* We have a "raw", abstract declarator (typename). */
7762 declarator = TREE_VALUE (atype_or_adecl);
7763 declspecs = TREE_PURPOSE (atype_or_adecl);
7765 gen_declspecs (declspecs, buf, 1);
7769 strcat (buf, gen_declarator (declarator, declbuf, ""));
7776 tree declspecs; /* "integer_type", "real_type", "record_type"... */
7777 tree declarator; /* "array_type", "function_type", "pointer_type". */
7779 if (TREE_CODE (atype_or_adecl) == FIELD_DECL
7780 || TREE_CODE (atype_or_adecl) == PARM_DECL
7781 || TREE_CODE (atype_or_adecl) == FUNCTION_DECL)
7782 atype = TREE_TYPE (atype_or_adecl);
7784 /* Assume we have a *_type node. */
7785 atype = atype_or_adecl;
7787 if (is_complex_decl (atype))
7791 /* Get the declaration specifier; it is at the end of the list. */
7792 declarator = chain = atype;
7794 chain = TREE_TYPE (chain); /* not TREE_CHAIN (chain); */
7795 while (is_complex_decl (chain));
7802 declarator = NULL_TREE;
7805 gen_declspecs (declspecs, buf, 0);
7807 if (TREE_CODE (atype_or_adecl) == FIELD_DECL
7808 || TREE_CODE (atype_or_adecl) == PARM_DECL
7809 || TREE_CODE (atype_or_adecl) == FUNCTION_DECL)
7811 const char *const decl_name =
7812 (DECL_NAME (atype_or_adecl)
7813 ? IDENTIFIER_POINTER (DECL_NAME (atype_or_adecl)) : "");
7818 strcat (buf, gen_declarator (declarator, declbuf, decl_name));
7821 else if (decl_name[0])
7824 strcat (buf, decl_name);
7827 else if (declarator)
7830 strcat (buf, gen_declarator (declarator, declbuf, ""));
7835 #define RAW_TYPESPEC(meth) (TREE_VALUE (TREE_PURPOSE (TREE_TYPE (meth))))
7837 /* Given a method tree, put a printable description into the given
7838 buffer (overwriting) and return a pointer to the buffer. */
7841 gen_method_decl (method, buf)
7848 if (RAW_TYPESPEC (method) != objc_object_reference)
7851 gen_declaration_1 (TREE_TYPE (method), buf);
7855 chain = METHOD_SEL_ARGS (method);
7858 /* We have a chain of keyword_decls. */
7861 if (KEYWORD_KEY_NAME (chain))
7862 strcat (buf, IDENTIFIER_POINTER (KEYWORD_KEY_NAME (chain)));
7865 if (RAW_TYPESPEC (chain) != objc_object_reference)
7868 gen_declaration_1 (TREE_TYPE (chain), buf);
7872 strcat (buf, IDENTIFIER_POINTER (KEYWORD_ARG_NAME (chain)));
7873 if ((chain = TREE_CHAIN (chain)))
7878 if (METHOD_ADD_ARGS (method) == objc_ellipsis_node)
7879 strcat (buf, ", ...");
7880 else if (METHOD_ADD_ARGS (method))
7882 /* We have a tree list node as generate by get_parm_info. */
7883 chain = TREE_PURPOSE (METHOD_ADD_ARGS (method));
7885 /* Know we have a chain of parm_decls. */
7889 gen_declaration_1 (chain, buf);
7890 chain = TREE_CHAIN (chain);
7896 /* We have a unary selector. */
7897 strcat (buf, IDENTIFIER_POINTER (METHOD_SEL_NAME (method)));
7905 dump_interface (fp, chain)
7909 char *buf = (char *) xmalloc (256);
7910 const char *my_name = IDENTIFIER_POINTER (CLASS_NAME (chain));
7911 tree ivar_decls = CLASS_RAW_IVARS (chain);
7912 tree nst_methods = CLASS_NST_METHODS (chain);
7913 tree cls_methods = CLASS_CLS_METHODS (chain);
7915 fprintf (fp, "\n@interface %s", my_name);
7917 if (CLASS_SUPER_NAME (chain))
7919 const char *super_name = IDENTIFIER_POINTER (CLASS_SUPER_NAME (chain));
7920 fprintf (fp, " : %s\n", super_name);
7927 fprintf (fp, "{\n");
7930 fprintf (fp, "\t%s;\n", gen_declaration (ivar_decls, buf));
7931 ivar_decls = TREE_CHAIN (ivar_decls);
7934 fprintf (fp, "}\n");
7939 fprintf (fp, "- %s;\n", gen_method_decl (nst_methods, buf));
7940 nst_methods = TREE_CHAIN (nst_methods);
7945 fprintf (fp, "+ %s;\n", gen_method_decl (cls_methods, buf));
7946 cls_methods = TREE_CHAIN (cls_methods);
7948 fprintf (fp, "\n@end");
7951 /* Demangle function for Objective-C */
7953 objc_demangle (mangled)
7954 const char *mangled;
7956 char *demangled, *cp;
7958 if (mangled[0] == '_' &&
7959 (mangled[1] == 'i' || mangled[1] == 'c') &&
7962 cp = demangled = xmalloc(strlen(mangled) + 2);
7963 if (mangled[1] == 'i')
7964 *cp++ = '-'; /* for instance method */
7966 *cp++ = '+'; /* for class method */
7967 *cp++ = '['; /* opening left brace */
7968 strcpy(cp, mangled+3); /* tack on the rest of the mangled name */
7969 while (*cp && *cp == '_')
7970 cp++; /* skip any initial underbars in class name */
7971 cp = strchr(cp, '_'); /* find first non-initial underbar */
7974 free(demangled); /* not mangled name */
7977 if (cp[1] == '_') /* easy case: no category name */
7979 *cp++ = ' '; /* replace two '_' with one ' ' */
7980 strcpy(cp, mangled + (cp - demangled) + 2);
7984 *cp++ = '('; /* less easy case: category name */
7985 cp = strchr(cp, '_');
7988 free(demangled); /* not mangled name */
7992 *cp++ = ' '; /* overwriting 1st char of method name... */
7993 strcpy(cp, mangled + (cp - demangled)); /* get it back */
7995 while (*cp && *cp == '_')
7996 cp++; /* skip any initial underbars in method name */
7999 *cp = ':'; /* replace remaining '_' with ':' */
8000 *cp++ = ']'; /* closing right brace */
8001 *cp++ = 0; /* string terminator */
8005 return mangled; /* not an objc mangled name */
8009 objc_printable_name (decl, kind)
8011 int kind ATTRIBUTE_UNUSED;
8013 return objc_demangle (IDENTIFIER_POINTER (DECL_NAME (decl)));
8019 gcc_obstack_init (&util_obstack);
8020 util_firstobj = (char *) obstack_finish (&util_obstack);
8022 errbuf = (char *) xmalloc (BUFSIZE);
8024 synth_module_prologue ();
8030 struct imp_entry *impent;
8032 /* The internally generated initializers appear to have missing braces.
8033 Don't warn about this. */
8034 int save_warn_missing_braces = warn_missing_braces;
8035 warn_missing_braces = 0;
8037 /* A missing @end may not be detected by the parser. */
8038 if (objc_implementation_context)
8040 warning ("`@end' missing in implementation context");
8041 finish_class (objc_implementation_context);
8042 objc_ivar_chain = NULL_TREE;
8043 objc_implementation_context = NULL_TREE;
8046 generate_forward_declaration_to_string_table ();
8048 #ifdef OBJC_PROLOGUE
8052 /* Process the static instances here because initialization of objc_symtab
8054 if (objc_static_instances)
8055 generate_static_references ();
8057 if (imp_list || class_names_chain
8058 || meth_var_names_chain || meth_var_types_chain || sel_ref_chain)
8059 generate_objc_symtab_decl ();
8061 for (impent = imp_list; impent; impent = impent->next)
8063 objc_implementation_context = impent->imp_context;
8064 implementation_template = impent->imp_template;
8066 UOBJC_CLASS_decl = impent->class_decl;
8067 UOBJC_METACLASS_decl = impent->meta_decl;
8069 if (TREE_CODE (objc_implementation_context) == CLASS_IMPLEMENTATION_TYPE)
8071 /* all of the following reference the string pool... */
8072 generate_ivar_lists ();
8073 generate_dispatch_tables ();
8074 generate_shared_structures ();
8078 generate_dispatch_tables ();
8079 generate_category (objc_implementation_context);
8083 /* If we are using an array of selectors, we must always
8084 finish up the array decl even if no selectors were used. */
8085 if (! flag_next_runtime || sel_ref_chain)
8086 build_selector_translation_table ();
8089 generate_protocols ();
8091 if (objc_implementation_context || class_names_chain || objc_static_instances
8092 || meth_var_names_chain || meth_var_types_chain || sel_ref_chain)
8094 /* Arrange for ObjC data structures to be initialized at run time. */
8095 rtx init_sym = build_module_descriptor ();
8096 if (init_sym && targetm.have_ctors_dtors)
8097 (* targetm.asm_out.constructor) (init_sym, DEFAULT_INIT_PRIORITY);
8100 /* Dump the class references. This forces the appropriate classes
8101 to be linked into the executable image, preserving unix archive
8102 semantics. This can be removed when we move to a more dynamically
8103 linked environment. */
8105 for (chain = cls_ref_chain; chain; chain = TREE_CHAIN (chain))
8107 handle_class_ref (chain);
8108 if (TREE_PURPOSE (chain))
8109 generate_classref_translation_entry (chain);
8112 for (impent = imp_list; impent; impent = impent->next)
8113 handle_impent (impent);
8115 /* Dump the string table last. */
8117 generate_strings ();
8119 if (flag_gen_declaration)
8121 add_class (objc_implementation_context);
8122 dump_interface (gen_declaration_file, objc_implementation_context);
8130 /* Run through the selector hash tables and print a warning for any
8131 selector which has multiple methods. */
8133 for (slot = 0; slot < SIZEHASHTABLE; slot++)
8134 for (hsh = cls_method_hash_list[slot]; hsh; hsh = hsh->next)
8137 tree meth = hsh->key;
8138 char type = (TREE_CODE (meth) == INSTANCE_METHOD_DECL
8142 warning ("potential selector conflict for method `%s'",
8143 IDENTIFIER_POINTER (METHOD_SEL_NAME (meth)));
8144 warn_with_method ("found", type, meth);
8145 for (loop = hsh->list; loop; loop = loop->next)
8146 warn_with_method ("found", type, loop->value);
8149 for (slot = 0; slot < SIZEHASHTABLE; slot++)
8150 for (hsh = nst_method_hash_list[slot]; hsh; hsh = hsh->next)
8153 tree meth = hsh->key;
8154 char type = (TREE_CODE (meth) == INSTANCE_METHOD_DECL
8158 warning ("potential selector conflict for method `%s'",
8159 IDENTIFIER_POINTER (METHOD_SEL_NAME (meth)));
8160 warn_with_method ("found", type, meth);
8161 for (loop = hsh->list; loop; loop = loop->next)
8162 warn_with_method ("found", type, loop->value);
8166 warn_missing_braces = save_warn_missing_braces;
8169 /* Subroutines of finish_objc. */
8172 generate_classref_translation_entry (chain)
8175 tree expr, name, decl_specs, decl, sc_spec;
8178 type = TREE_TYPE (TREE_PURPOSE (chain));
8180 expr = add_objc_string (TREE_VALUE (chain), class_names);
8181 expr = build_c_cast (type, expr); /* cast! */
8183 name = DECL_NAME (TREE_PURPOSE (chain));
8185 sc_spec = build_tree_list (NULL_TREE, ridpointers[(int) RID_STATIC]);
8187 /* static struct objc_class * _OBJC_CLASS_REFERENCES_n = ...; */
8188 decl_specs = tree_cons (NULL_TREE, type, sc_spec);
8190 /* The decl that is returned from start_decl is the one that we
8191 forward declared in build_class_reference. */
8192 decl = start_decl (name, decl_specs, 1, NULL_TREE);
8193 DECL_CONTEXT (decl) = NULL_TREE;
8194 finish_decl (decl, expr, NULL_TREE);
8199 handle_class_ref (chain)
8202 const char *name = IDENTIFIER_POINTER (TREE_VALUE (chain));
8203 char *string = (char *) alloca (strlen (name) + 30);
8207 sprintf (string, "%sobjc_class_name_%s",
8208 (flag_next_runtime ? "." : "__"), name);
8210 #ifdef ASM_DECLARE_UNRESOLVED_REFERENCE
8211 if (flag_next_runtime)
8213 ASM_DECLARE_UNRESOLVED_REFERENCE (asm_out_file, string);
8218 /* Make a decl for this name, so we can use its address in a tree. */
8219 decl = build_decl (VAR_DECL, get_identifier (string), char_type_node);
8220 DECL_EXTERNAL (decl) = 1;
8221 TREE_PUBLIC (decl) = 1;
8224 rest_of_decl_compilation (decl, 0, 0, 0);
8226 /* Make a decl for the address. */
8227 sprintf (string, "%sobjc_class_ref_%s",
8228 (flag_next_runtime ? "." : "__"), name);
8229 exp = build1 (ADDR_EXPR, string_type_node, decl);
8230 decl = build_decl (VAR_DECL, get_identifier (string), string_type_node);
8231 DECL_INITIAL (decl) = exp;
8232 TREE_STATIC (decl) = 1;
8233 TREE_USED (decl) = 1;
8236 rest_of_decl_compilation (decl, 0, 0, 0);
8240 handle_impent (impent)
8241 struct imp_entry *impent;
8245 objc_implementation_context = impent->imp_context;
8246 implementation_template = impent->imp_template;
8248 if (TREE_CODE (impent->imp_context) == CLASS_IMPLEMENTATION_TYPE)
8250 const char *const class_name =
8251 IDENTIFIER_POINTER (CLASS_NAME (impent->imp_context));
8253 string = (char *) alloca (strlen (class_name) + 30);
8255 sprintf (string, "%sobjc_class_name_%s",
8256 (flag_next_runtime ? "." : "__"), class_name);
8258 else if (TREE_CODE (impent->imp_context) == CATEGORY_IMPLEMENTATION_TYPE)
8260 const char *const class_name =
8261 IDENTIFIER_POINTER (CLASS_NAME (impent->imp_context));
8262 const char *const class_super_name =
8263 IDENTIFIER_POINTER (CLASS_SUPER_NAME (impent->imp_context));
8265 string = (char *) alloca (strlen (class_name)
8266 + strlen (class_super_name) + 30);
8268 /* Do the same for categories. Even though no references to
8269 these symbols are generated automatically by the compiler, it
8270 gives you a handle to pull them into an archive by hand. */
8271 sprintf (string, "*%sobjc_category_name_%s_%s",
8272 (flag_next_runtime ? "." : "__"), class_name, class_super_name);
8277 #ifdef ASM_DECLARE_CLASS_REFERENCE
8278 if (flag_next_runtime)
8280 ASM_DECLARE_CLASS_REFERENCE (asm_out_file, string);
8288 init = build_int_2 (0, 0);
8289 TREE_TYPE (init) = c_common_type_for_size (BITS_PER_WORD, 1);
8290 decl = build_decl (VAR_DECL, get_identifier (string), TREE_TYPE (init));
8291 TREE_PUBLIC (decl) = 1;
8292 TREE_READONLY (decl) = 1;
8293 TREE_USED (decl) = 1;
8294 TREE_CONSTANT (decl) = 1;
8295 DECL_CONTEXT (decl) = 0;
8296 DECL_ARTIFICIAL (decl) = 1;
8297 DECL_INITIAL (decl) = init;
8298 assemble_variable (decl, 1, 0, 0);
8302 /* Look up ID as an instance variable. */
8304 lookup_objc_ivar (id)
8309 if (objc_method_context && !strcmp (IDENTIFIER_POINTER (id), "super"))
8310 /* We have a message to super. */
8311 return get_super_receiver ();
8312 else if (objc_method_context && (decl = is_ivar (objc_ivar_chain, id)))
8314 if (is_private (decl))
8315 return error_mark_node;
8317 return build_ivar_reference (id);
8323 #include "gtype-objc.h"