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 #define obstack_chunk_alloc xmalloc
94 #define obstack_chunk_free free
96 /* This obstack is used to accumulate the encoding of a data type. */
97 static struct obstack util_obstack;
98 /* This points to the beginning of obstack contents,
99 so we can free the whole contents. */
102 /* for encode_method_def */
105 /* The version identifies which language generation and runtime
106 the module (file) was compiled for, and is recorded in the
107 module descriptor. */
109 #define OBJC_VERSION (flag_next_runtime ? 5 : 8)
110 #define PROTOCOL_VERSION 2
112 /* (Decide if these can ever be validly changed.) */
113 #define OBJC_ENCODE_INLINE_DEFS 0
114 #define OBJC_ENCODE_DONT_INLINE_DEFS 1
116 /*** Private Interface (procedures) ***/
118 /* Used by compile_file. */
120 static void init_objc PARAMS ((void));
121 static void finish_objc PARAMS ((void));
123 /* Code generation. */
125 static void synth_module_prologue PARAMS ((void));
126 static tree build_constructor PARAMS ((tree, tree));
127 static rtx build_module_descriptor PARAMS ((void));
128 static tree init_module_descriptor PARAMS ((tree));
129 static tree build_objc_method_call PARAMS ((int, tree, tree,
131 static void generate_strings PARAMS ((void));
132 static tree get_proto_encoding PARAMS ((tree));
133 static void build_selector_translation_table PARAMS ((void));
134 static tree build_ivar_chain PARAMS ((tree, int));
136 static tree objc_add_static_instance PARAMS ((tree, tree));
138 static tree build_ivar_template PARAMS ((void));
139 static tree build_method_template PARAMS ((void));
140 static tree build_private_template PARAMS ((tree));
141 static void build_class_template PARAMS ((void));
142 static void build_selector_template PARAMS ((void));
143 static void build_category_template PARAMS ((void));
144 static tree build_super_template PARAMS ((void));
145 static tree build_category_initializer PARAMS ((tree, tree, tree,
147 static tree build_protocol_initializer PARAMS ((tree, tree, tree,
150 static void synth_forward_declarations PARAMS ((void));
151 static void generate_ivar_lists PARAMS ((void));
152 static void generate_dispatch_tables PARAMS ((void));
153 static void generate_shared_structures PARAMS ((void));
154 static tree generate_protocol_list PARAMS ((tree));
155 static void generate_forward_declaration_to_string_table PARAMS ((void));
156 static void build_protocol_reference PARAMS ((tree));
158 static tree build_keyword_selector PARAMS ((tree));
159 static tree synth_id_with_class_suffix PARAMS ((const char *, tree));
161 static void generate_static_references PARAMS ((void));
162 static int check_methods_accessible PARAMS ((tree, tree,
164 static void encode_aggregate_within PARAMS ((tree, int, int,
166 static const char *objc_demangle PARAMS ((const char *));
167 static void objc_expand_function_end PARAMS ((void));
169 /* Hash tables to manage the global pool of method prototypes. */
171 hash *nst_method_hash_list = 0;
172 hash *cls_method_hash_list = 0;
174 static size_t hash_func PARAMS ((tree));
175 static void hash_init PARAMS ((void));
176 static void hash_enter PARAMS ((hash *, tree));
177 static hash hash_lookup PARAMS ((hash *, tree));
178 static void hash_add_attr PARAMS ((hash, tree));
179 static tree lookup_method PARAMS ((tree, tree));
180 static tree lookup_instance_method_static PARAMS ((tree, tree));
181 static tree lookup_class_method_static PARAMS ((tree, tree));
182 static tree add_class PARAMS ((tree));
183 static void add_category PARAMS ((tree, tree));
187 class_names, /* class, category, protocol, module names */
188 meth_var_names, /* method and variable names */
189 meth_var_types /* method and variable type descriptors */
192 static tree add_objc_string PARAMS ((tree,
193 enum string_section));
194 static tree get_objc_string_decl PARAMS ((tree,
195 enum string_section));
196 static tree build_objc_string_decl PARAMS ((enum string_section));
197 static tree build_selector_reference_decl PARAMS ((void));
199 /* Protocol additions. */
201 static tree add_protocol PARAMS ((tree));
202 static tree lookup_protocol PARAMS ((tree));
203 static void check_protocol_recursively PARAMS ((tree, tree));
204 static tree lookup_and_install_protocols PARAMS ((tree));
208 static void encode_type_qualifiers PARAMS ((tree));
209 static void encode_pointer PARAMS ((tree, int, int));
210 static void encode_array PARAMS ((tree, int, int));
211 static void encode_aggregate PARAMS ((tree, int, int));
212 static void encode_bitfield PARAMS ((int));
213 static void encode_type PARAMS ((tree, int, int));
214 static void encode_field_decl PARAMS ((tree, int, int));
216 static void really_start_method PARAMS ((tree, tree));
217 static int comp_method_with_proto PARAMS ((tree, tree));
218 static int comp_proto_with_proto PARAMS ((tree, tree));
219 static tree get_arg_type_list PARAMS ((tree, int, int));
220 static tree expr_last PARAMS ((tree));
222 /* Utilities for debugging and error diagnostics. */
224 static void warn_with_method PARAMS ((const char *, int, tree));
225 static void error_with_ivar PARAMS ((const char *, tree, tree));
226 static char *gen_method_decl PARAMS ((tree, char *));
227 static char *gen_declaration PARAMS ((tree, char *));
228 static void gen_declaration_1 PARAMS ((tree, char *));
229 static char *gen_declarator PARAMS ((tree, char *,
231 static int is_complex_decl PARAMS ((tree));
232 static void adorn_decl PARAMS ((tree, char *));
233 static void dump_interface PARAMS ((FILE *, tree));
235 /* Everything else. */
237 static tree define_decl PARAMS ((tree, tree));
238 static tree lookup_method_in_protocol_list PARAMS ((tree, tree, int));
239 static tree lookup_protocol_in_reflist PARAMS ((tree, tree));
240 static tree create_builtin_decl PARAMS ((enum tree_code,
241 tree, const char *));
242 static void setup_string_decl PARAMS ((void));
243 static void build_string_class_template PARAMS ((void));
244 static tree my_build_string PARAMS ((int, const char *));
245 static void build_objc_symtab_template PARAMS ((void));
246 static tree init_def_list PARAMS ((tree));
247 static tree init_objc_symtab PARAMS ((tree));
248 static void forward_declare_categories PARAMS ((void));
249 static void generate_objc_symtab_decl PARAMS ((void));
250 static tree build_selector PARAMS ((tree));
251 static tree build_typed_selector_reference PARAMS ((tree, tree));
252 static tree build_selector_reference PARAMS ((tree));
253 static tree build_class_reference_decl PARAMS ((void));
254 static void add_class_reference PARAMS ((tree));
255 static tree objc_copy_list PARAMS ((tree, tree *));
256 static tree build_protocol_template PARAMS ((void));
257 static tree build_descriptor_table_initializer PARAMS ((tree, tree));
258 static tree build_method_prototype_list_template PARAMS ((tree, int));
259 static tree build_method_prototype_template PARAMS ((void));
260 static int forwarding_offset PARAMS ((tree));
261 static tree encode_method_prototype PARAMS ((tree, tree));
262 static tree generate_descriptor_table PARAMS ((tree, const char *,
264 static void generate_method_descriptors PARAMS ((tree));
265 static tree build_tmp_function_decl PARAMS ((void));
266 static void hack_method_prototype PARAMS ((tree, tree));
267 static void generate_protocol_references PARAMS ((tree));
268 static void generate_protocols PARAMS ((void));
269 static void check_ivars PARAMS ((tree, tree));
270 static tree build_ivar_list_template PARAMS ((tree, int));
271 static tree build_method_list_template PARAMS ((tree, int));
272 static tree build_ivar_list_initializer PARAMS ((tree, tree));
273 static tree generate_ivars_list PARAMS ((tree, const char *,
275 static tree build_dispatch_table_initializer PARAMS ((tree, tree));
276 static tree generate_dispatch_table PARAMS ((tree, const char *,
278 static tree build_shared_structure_initializer PARAMS ((tree, tree, tree, tree,
279 tree, int, tree, tree,
281 static void generate_category PARAMS ((tree));
282 static int is_objc_type_qualifier PARAMS ((tree));
283 static tree adjust_type_for_id_default PARAMS ((tree));
284 static tree check_duplicates PARAMS ((hash));
285 static tree receiver_is_class_object PARAMS ((tree));
286 static int check_methods PARAMS ((tree, tree, int));
287 static int conforms_to_protocol PARAMS ((tree, tree));
288 static void check_protocol PARAMS ((tree, const char *,
290 static void check_protocols PARAMS ((tree, const char *,
292 static tree encode_method_def PARAMS ((tree));
293 static void gen_declspecs PARAMS ((tree, char *, int));
294 static void generate_classref_translation_entry PARAMS ((tree));
295 static void handle_class_ref PARAMS ((tree));
296 static void generate_struct_by_value_array PARAMS ((void))
299 /*** Private Interface (data) ***/
301 /* Reserved tag definitions. */
304 #define TAG_OBJECT "objc_object"
305 #define TAG_CLASS "objc_class"
306 #define TAG_SUPER "objc_super"
307 #define TAG_SELECTOR "objc_selector"
309 #define UTAG_CLASS "_objc_class"
310 #define UTAG_IVAR "_objc_ivar"
311 #define UTAG_IVAR_LIST "_objc_ivar_list"
312 #define UTAG_METHOD "_objc_method"
313 #define UTAG_METHOD_LIST "_objc_method_list"
314 #define UTAG_CATEGORY "_objc_category"
315 #define UTAG_MODULE "_objc_module"
316 #define UTAG_STATICS "_objc_statics"
317 #define UTAG_SYMTAB "_objc_symtab"
318 #define UTAG_SUPER "_objc_super"
319 #define UTAG_SELECTOR "_objc_selector"
321 #define UTAG_PROTOCOL "_objc_protocol"
322 #define UTAG_PROTOCOL_LIST "_objc_protocol_list"
323 #define UTAG_METHOD_PROTOTYPE "_objc_method_prototype"
324 #define UTAG_METHOD_PROTOTYPE_LIST "_objc__method_prototype_list"
326 /* Note that the string object global name is only needed for the
328 #define STRING_OBJECT_GLOBAL_NAME "_NSConstantStringClassReference"
330 #define PROTOCOL_OBJECT_CLASS_NAME "Protocol"
332 static const char *constant_string_class_name = NULL;
334 static const char *TAG_GETCLASS;
335 static const char *TAG_GETMETACLASS;
336 static const char *TAG_MSGSEND;
337 static const char *TAG_MSGSENDSUPER;
338 static const char *TAG_EXECCLASS;
339 static const char *default_constant_string_class_name;
341 /* The OCTI_... enumeration itself is in objc/objc-act.h. */
342 tree objc_global_trees[OCTI_MAX];
344 int objc_receiver_context;
346 static void handle_impent PARAMS ((struct imp_entry *));
348 struct imp_entry *imp_list = 0;
349 int imp_count = 0; /* `@implementation' */
350 int cat_count = 0; /* `@category' */
352 static int method_slot = 0; /* Used by start_method_def, */
356 static char *errbuf; /* Buffer for error diagnostics */
358 /* Data imported from tree.c. */
360 extern enum debug_info_type write_symbols;
362 /* Data imported from toplev.c. */
364 extern const char *dump_base_name;
366 /* Generate code for GNU or NeXT runtime environment. */
368 #ifdef NEXT_OBJC_RUNTIME
369 int flag_next_runtime = 1;
371 int flag_next_runtime = 0;
374 int flag_typed_selectors;
376 /* Open and close the file for outputting class declarations, if requested. */
378 int flag_gen_declaration = 0;
380 FILE *gen_declaration_file;
382 /* Warn if multiple methods are seen for the same selector, but with
383 different argument types. */
385 int warn_selector = 0;
387 /* Warn if methods required by a protocol are not implemented in the
388 class adopting it. When turned off, methods inherited to that
389 class are also considered implemented */
391 int flag_warn_protocol = 1;
393 /* Tells "encode_pointer/encode_aggregate" whether we are generating
394 type descriptors for instance variables (as opposed to methods).
395 Type descriptors for instance variables contain more information
396 than methods (for static typing and embedded structures). */
398 static int generating_instance_variables = 0;
400 /* Tells the compiler that this is a special run. Do not perform any
401 compiling, instead we are to test some platform dependent features
402 and output a C header file with appropriate definitions. */
404 static int print_struct_values = 0;
406 /* Some platforms pass small structures through registers versus
407 through an invisible pointer. Determine at what size structure is
408 the transition point between the two possibilities. */
411 generate_struct_by_value_array ()
414 tree field_decl, field_decl_chain;
416 int aggregate_in_mem[32];
419 /* Presumably no platform passes 32 byte structures in a register. */
420 for (i = 1; i < 32; i++)
424 /* Create an unnamed struct that has `i' character components */
425 type = start_struct (RECORD_TYPE, NULL_TREE);
427 strcpy (buffer, "c1");
428 field_decl = create_builtin_decl (FIELD_DECL,
431 field_decl_chain = field_decl;
433 for (j = 1; j < i; j++)
435 sprintf (buffer, "c%d", j + 1);
436 field_decl = create_builtin_decl (FIELD_DECL,
439 chainon (field_decl_chain, field_decl);
441 finish_struct (type, field_decl_chain, NULL_TREE);
443 aggregate_in_mem[i] = aggregate_value_p (type);
444 if (!aggregate_in_mem[i])
448 /* We found some structures that are returned in registers instead of memory
449 so output the necessary data. */
452 for (i = 31; i >= 0; i--)
453 if (!aggregate_in_mem[i])
455 printf ("#define OBJC_MAX_STRUCT_BY_VALUE %d\n\n", i);
457 /* The first member of the structure is always 0 because we don't handle
458 structures with 0 members */
459 printf ("static int struct_forward_array[] = {\n 0");
461 for (j = 1; j <= i; j++)
462 printf (", %d", aggregate_in_mem[j]);
471 const char *filename;
473 filename = c_objc_common_init (filename);
475 /* Force the line number back to 0; check_newline will have
476 raised it to 1, which will make the builtin functions appear
477 not to be built in. */
480 /* If gen_declaration desired, open the output file. */
481 if (flag_gen_declaration)
483 register char * const dumpname = concat (dump_base_name, ".decl", NULL);
484 gen_declaration_file = fopen (dumpname, "w");
485 if (gen_declaration_file == 0)
486 fatal_io_error ("can't open %s", dumpname);
490 if (flag_next_runtime)
492 TAG_GETCLASS = "objc_getClass";
493 TAG_GETMETACLASS = "objc_getMetaClass";
494 TAG_MSGSEND = "objc_msgSend";
495 TAG_MSGSENDSUPER = "objc_msgSendSuper";
496 TAG_EXECCLASS = "__objc_execClass";
497 default_constant_string_class_name = "NSConstantString";
501 TAG_GETCLASS = "objc_get_class";
502 TAG_GETMETACLASS = "objc_get_meta_class";
503 TAG_MSGSEND = "objc_msg_lookup";
504 TAG_MSGSENDSUPER = "objc_msg_lookup_super";
505 TAG_EXECCLASS = "__objc_exec_class";
506 default_constant_string_class_name = "NXConstantString";
507 flag_typed_selectors = 1;
510 objc_ellipsis_node = make_node (ERROR_MARK);
514 if (print_struct_values)
515 generate_struct_by_value_array ();
523 c_objc_common_finish_file ();
525 finish_objc (); /* Objective-C finalization */
527 if (gen_declaration_file)
528 fclose (gen_declaration_file);
532 objc_decode_option (argc, argv)
536 const char *p = argv[0];
538 if (!strcmp (p, "-gen-decls"))
539 flag_gen_declaration = 1;
540 else if (!strcmp (p, "-Wselector"))
542 else if (!strcmp (p, "-Wno-selector"))
544 else if (!strcmp (p, "-Wprotocol"))
545 flag_warn_protocol = 1;
546 else if (!strcmp (p, "-Wno-protocol"))
547 flag_warn_protocol = 0;
548 else if (!strcmp (p, "-fgnu-runtime"))
549 flag_next_runtime = 0;
550 else if (!strcmp (p, "-fno-next-runtime"))
551 flag_next_runtime = 0;
552 else if (!strcmp (p, "-fno-gnu-runtime"))
553 flag_next_runtime = 1;
554 else if (!strcmp (p, "-fnext-runtime"))
555 flag_next_runtime = 1;
556 else if (!strcmp (p, "-print-objc-runtime-info"))
557 print_struct_values = 1;
558 #define CSTSTRCLASS "-fconstant-string-class="
559 else if (!strncmp (p, CSTSTRCLASS, sizeof(CSTSTRCLASS) - 2)) {
560 if (strlen (argv[0]) <= strlen (CSTSTRCLASS))
561 error ("no class name specified as argument to -fconstant-string-class");
562 constant_string_class_name = xstrdup(argv[0] + sizeof(CSTSTRCLASS) - 1);
566 return c_decode_option (argc, argv);
573 define_decl (declarator, declspecs)
577 tree decl = start_decl (declarator, declspecs, 0, NULL_TREE);
578 finish_decl (decl, NULL_TREE, NULL_TREE);
582 /* Return 1 if LHS and RHS are compatible types for assignment or
583 various other operations. Return 0 if they are incompatible, and
584 return -1 if we choose to not decide. When the operation is
585 REFLEXIVE, check for compatibility in either direction.
587 For statically typed objects, an assignment of the form `a' = `b'
591 `a' and `b' are the same class type, or
592 `a' and `b' are of class types A and B such that B is a descendant of A. */
595 maybe_objc_comptypes (lhs, rhs, reflexive)
599 return objc_comptypes (lhs, rhs, reflexive);
603 lookup_method_in_protocol_list (rproto_list, sel_name, class_meth)
611 for (rproto = rproto_list; rproto; rproto = TREE_CHAIN (rproto))
613 p = TREE_VALUE (rproto);
615 if (TREE_CODE (p) == PROTOCOL_INTERFACE_TYPE)
617 if ((fnd = lookup_method (class_meth
618 ? PROTOCOL_CLS_METHODS (p)
619 : PROTOCOL_NST_METHODS (p), sel_name)))
621 else if (PROTOCOL_LIST (p))
622 fnd = lookup_method_in_protocol_list (PROTOCOL_LIST (p),
623 sel_name, class_meth);
627 ; /* An identifier...if we could not find a protocol. */
638 lookup_protocol_in_reflist (rproto_list, lproto)
644 /* Make sure the protocol is supported by the object on the rhs. */
645 if (TREE_CODE (lproto) == PROTOCOL_INTERFACE_TYPE)
648 for (rproto = rproto_list; rproto; rproto = TREE_CHAIN (rproto))
650 p = TREE_VALUE (rproto);
652 if (TREE_CODE (p) == PROTOCOL_INTERFACE_TYPE)
657 else if (PROTOCOL_LIST (p))
658 fnd = lookup_protocol_in_reflist (PROTOCOL_LIST (p), lproto);
667 ; /* An identifier...if we could not find a protocol. */
673 /* Return 1 if LHS and RHS are compatible types for assignment
674 or various other operations. Return 0 if they are incompatible,
675 and return -1 if we choose to not decide. When the operation
676 is REFLEXIVE, check for compatibility in either direction. */
679 objc_comptypes (lhs, rhs, reflexive)
684 /* New clause for protocols. */
686 if (TREE_CODE (lhs) == POINTER_TYPE
687 && TREE_CODE (TREE_TYPE (lhs)) == RECORD_TYPE
688 && TREE_CODE (rhs) == POINTER_TYPE
689 && TREE_CODE (TREE_TYPE (rhs)) == RECORD_TYPE)
691 int lhs_is_proto = IS_PROTOCOL_QUALIFIED_ID (lhs);
692 int rhs_is_proto = IS_PROTOCOL_QUALIFIED_ID (rhs);
696 tree lproto, lproto_list = TYPE_PROTOCOL_LIST (lhs);
697 tree rproto, rproto_list;
702 rproto_list = TYPE_PROTOCOL_LIST (rhs);
704 /* Make sure the protocol is supported by the object
706 for (lproto = lproto_list; lproto; lproto = TREE_CHAIN (lproto))
708 p = TREE_VALUE (lproto);
709 rproto = lookup_protocol_in_reflist (rproto_list, p);
712 warning ("object does not conform to the `%s' protocol",
713 IDENTIFIER_POINTER (PROTOCOL_NAME (p)));
716 else if (TYPED_OBJECT (TREE_TYPE (rhs)))
718 tree rname = TYPE_NAME (TREE_TYPE (rhs));
721 /* Make sure the protocol is supported by the object
723 for (lproto = lproto_list; lproto; lproto = TREE_CHAIN (lproto))
725 p = TREE_VALUE (lproto);
727 rinter = lookup_interface (rname);
729 while (rinter && !rproto)
733 rproto_list = CLASS_PROTOCOL_LIST (rinter);
734 /* If the underlying ObjC class does not have
735 protocols attached to it, perhaps there are
736 "one-off" protocols attached to the rhs?
737 E.g., 'id<MyProt> foo;'. */
739 rproto_list = TYPE_PROTOCOL_LIST (TREE_TYPE (rhs));
740 rproto = lookup_protocol_in_reflist (rproto_list, p);
742 /* Check for protocols adopted by categories. */
743 cat = CLASS_CATEGORY_LIST (rinter);
744 while (cat && !rproto)
746 rproto_list = CLASS_PROTOCOL_LIST (cat);
747 rproto = lookup_protocol_in_reflist (rproto_list, p);
749 cat = CLASS_CATEGORY_LIST (cat);
752 rinter = lookup_interface (CLASS_SUPER_NAME (rinter));
756 warning ("class `%s' does not implement the `%s' protocol",
757 IDENTIFIER_POINTER (TYPE_NAME (TREE_TYPE (rhs))),
758 IDENTIFIER_POINTER (PROTOCOL_NAME (p)));
762 /* May change...based on whether there was any mismatch */
765 else if (rhs_is_proto)
766 /* Lhs is not a protocol...warn if it is statically typed */
767 return (TYPED_OBJECT (TREE_TYPE (lhs)) != 0);
770 /* Defer to comptypes. */
774 else if (TREE_CODE (lhs) == RECORD_TYPE && TREE_CODE (rhs) == RECORD_TYPE)
775 ; /* Fall thru. This is the case we have been handling all along */
777 /* Defer to comptypes. */
780 /* `id' = `<class> *', `<class> *' = `id' */
782 if ((TYPE_NAME (lhs) == objc_object_id && TYPED_OBJECT (rhs))
783 || (TYPE_NAME (rhs) == objc_object_id && TYPED_OBJECT (lhs)))
786 /* `id' = `Class', `Class' = `id' */
788 else if ((TYPE_NAME (lhs) == objc_object_id
789 && TYPE_NAME (rhs) == objc_class_id)
790 || (TYPE_NAME (lhs) == objc_class_id
791 && TYPE_NAME (rhs) == objc_object_id))
794 /* `<class> *' = `<class> *' */
796 else if (TYPED_OBJECT (lhs) && TYPED_OBJECT (rhs))
798 tree lname = TYPE_NAME (lhs);
799 tree rname = TYPE_NAME (rhs);
805 /* If the left hand side is a super class of the right hand side,
807 for (inter = lookup_interface (rname); inter;
808 inter = lookup_interface (CLASS_SUPER_NAME (inter)))
809 if (lname == CLASS_SUPER_NAME (inter))
812 /* Allow the reverse when reflexive. */
814 for (inter = lookup_interface (lname); inter;
815 inter = lookup_interface (CLASS_SUPER_NAME (inter)))
816 if (rname == CLASS_SUPER_NAME (inter))
822 /* Defer to comptypes. */
826 /* Called from c-decl.c before all calls to rest_of_decl_compilation. */
829 objc_check_decl (decl)
832 tree type = TREE_TYPE (decl);
834 if (TREE_CODE (type) == RECORD_TYPE
835 && TREE_STATIC_TEMPLATE (type)
836 && type != constant_string_type)
837 error_with_decl (decl, "`%s' cannot be statically allocated");
841 maybe_objc_check_decl (decl)
844 objc_check_decl (decl);
847 /* Implement static typing. At this point, we know we have an interface. */
850 get_static_reference (interface, protocols)
854 tree type = xref_tag (RECORD_TYPE, interface);
858 tree t, m = TYPE_MAIN_VARIANT (type);
860 t = copy_node (type);
861 TYPE_BINFO (t) = make_tree_vec (2);
863 /* Add this type to the chain of variants of TYPE. */
864 TYPE_NEXT_VARIANT (t) = TYPE_NEXT_VARIANT (m);
865 TYPE_NEXT_VARIANT (m) = t;
867 /* Look up protocols and install in lang specific list. Note
868 that the protocol list can have a different lifetime than T! */
869 TYPE_PROTOCOL_LIST (t) = lookup_and_install_protocols (protocols);
871 /* This forces a new pointer type to be created later
872 (in build_pointer_type)...so that the new template
873 we just created will actually be used...what a hack! */
874 if (TYPE_POINTER_TO (t))
875 TYPE_POINTER_TO (t) = NULL_TREE;
884 get_object_reference (protocols)
887 tree type_decl = lookup_name (objc_id_id);
890 if (type_decl && TREE_CODE (type_decl) == TYPE_DECL)
892 type = TREE_TYPE (type_decl);
893 if (TYPE_MAIN_VARIANT (type) != id_type)
894 warning ("unexpected type for `id' (%s)",
895 gen_declaration (type, errbuf));
899 error ("undefined type `id', please import <objc/objc.h>");
900 return error_mark_node;
903 /* This clause creates a new pointer type that is qualified with
904 the protocol specification...this info is used later to do more
905 elaborate type checking. */
909 tree t, m = TYPE_MAIN_VARIANT (type);
911 t = copy_node (type);
912 TYPE_BINFO (t) = make_tree_vec (2);
914 /* Add this type to the chain of variants of TYPE. */
915 TYPE_NEXT_VARIANT (t) = TYPE_NEXT_VARIANT (m);
916 TYPE_NEXT_VARIANT (m) = t;
918 /* Look up protocols...and install in lang specific list */
919 TYPE_PROTOCOL_LIST (t) = lookup_and_install_protocols (protocols);
921 /* This forces a new pointer type to be created later
922 (in build_pointer_type)...so that the new template
923 we just created will actually be used...what a hack! */
924 if (TYPE_POINTER_TO (t))
925 TYPE_POINTER_TO (t) = NULL_TREE;
932 /* Check for circular dependencies in protocols. The arguments are
933 PROTO, the protocol to check, and LIST, a list of protocol it
937 check_protocol_recursively (proto, list)
943 for (p = list; p; p = TREE_CHAIN (p))
945 tree pp = TREE_VALUE (p);
947 if (TREE_CODE (pp) == IDENTIFIER_NODE)
948 pp = lookup_protocol (pp);
951 fatal_error ("protocol `%s' has circular dependency",
952 IDENTIFIER_POINTER (PROTOCOL_NAME (pp)));
954 check_protocol_recursively (proto, PROTOCOL_LIST (pp));
959 lookup_and_install_protocols (protocols)
964 tree return_value = protocols;
966 for (proto = protocols; proto; proto = TREE_CHAIN (proto))
968 tree ident = TREE_VALUE (proto);
969 tree p = lookup_protocol (ident);
973 error ("cannot find protocol declaration for `%s'",
974 IDENTIFIER_POINTER (ident));
976 TREE_CHAIN (prev) = TREE_CHAIN (proto);
978 return_value = TREE_CHAIN (proto);
982 /* Replace identifier with actual protocol node. */
983 TREE_VALUE (proto) = p;
991 /* Create and push a decl for a built-in external variable or field NAME.
993 TYPE is its data type. */
996 create_builtin_decl (code, type, name)
1001 tree decl = build_decl (code, get_identifier (name), type);
1003 if (code == VAR_DECL)
1005 TREE_STATIC (decl) = 1;
1006 make_decl_rtl (decl, 0);
1010 DECL_ARTIFICIAL (decl) = 1;
1014 /* Find the decl for the constant string class. */
1017 setup_string_decl ()
1019 if (!string_class_decl)
1021 if (!constant_string_global_id)
1022 constant_string_global_id = get_identifier (STRING_OBJECT_GLOBAL_NAME);
1023 string_class_decl = lookup_name (constant_string_global_id);
1027 /* Purpose: "play" parser, creating/installing representations
1028 of the declarations that are required by Objective-C.
1032 type_spec--------->sc_spec
1033 (tree_list) (tree_list)
1036 identifier_node identifier_node */
1039 synth_module_prologue ()
1044 /* Defined in `objc.h' */
1045 objc_object_id = get_identifier (TAG_OBJECT);
1047 objc_object_reference = xref_tag (RECORD_TYPE, objc_object_id);
1049 id_type = build_pointer_type (objc_object_reference);
1051 objc_id_id = get_identifier (TYPE_ID);
1052 objc_class_id = get_identifier (TAG_CLASS);
1054 objc_class_type = build_pointer_type (xref_tag (RECORD_TYPE, objc_class_id));
1055 protocol_type = build_pointer_type (xref_tag (RECORD_TYPE,
1056 get_identifier (PROTOCOL_OBJECT_CLASS_NAME)));
1058 /* Declare type of selector-objects that represent an operation name. */
1060 /* `struct objc_selector *' */
1062 = build_pointer_type (xref_tag (RECORD_TYPE,
1063 get_identifier (TAG_SELECTOR)));
1065 /* Forward declare type, or else the prototype for msgSendSuper will
1068 super_p = build_pointer_type (xref_tag (RECORD_TYPE,
1069 get_identifier (TAG_SUPER)));
1072 /* id objc_msgSend (id, SEL, ...); */
1075 = build_function_type (id_type,
1076 tree_cons (NULL_TREE, id_type,
1077 tree_cons (NULL_TREE, selector_type,
1080 if (! flag_next_runtime)
1082 umsg_decl = build_decl (FUNCTION_DECL,
1083 get_identifier (TAG_MSGSEND), temp_type);
1084 DECL_EXTERNAL (umsg_decl) = 1;
1085 TREE_PUBLIC (umsg_decl) = 1;
1086 DECL_INLINE (umsg_decl) = 1;
1087 DECL_ARTIFICIAL (umsg_decl) = 1;
1089 make_decl_rtl (umsg_decl, NULL);
1090 pushdecl (umsg_decl);
1093 umsg_decl = builtin_function (TAG_MSGSEND, temp_type, 0, NOT_BUILT_IN, 0);
1095 /* id objc_msgSendSuper (struct objc_super *, SEL, ...); */
1098 = build_function_type (id_type,
1099 tree_cons (NULL_TREE, super_p,
1100 tree_cons (NULL_TREE, selector_type,
1103 umsg_super_decl = builtin_function (TAG_MSGSENDSUPER,
1104 temp_type, 0, NOT_BUILT_IN, 0);
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, 0);
1117 /* id objc_getMetaClass (const char *); */
1119 objc_get_meta_class_decl
1120 = builtin_function (TAG_GETMETACLASS, temp_type, 0, NOT_BUILT_IN, 0);
1122 /* static SEL _OBJC_SELECTOR_TABLE[]; */
1124 if (! flag_next_runtime)
1126 if (flag_typed_selectors)
1128 /* Suppress outputting debug symbols, because
1129 dbxout_init hasn'r been called yet. */
1130 enum debug_info_type save_write_symbols = write_symbols;
1131 const struct gcc_debug_hooks *const save_hooks = debug_hooks;
1132 write_symbols = NO_DEBUG;
1133 debug_hooks = &do_nothing_debug_hooks;
1135 build_selector_template ();
1136 temp_type = build_array_type (objc_selector_template, NULL_TREE);
1138 write_symbols = save_write_symbols;
1139 debug_hooks = save_hooks;
1142 temp_type = build_array_type (selector_type, NULL_TREE);
1144 layout_type (temp_type);
1145 UOBJC_SELECTOR_TABLE_decl
1146 = create_builtin_decl (VAR_DECL, temp_type,
1147 "_OBJC_SELECTOR_TABLE");
1149 /* Avoid warning when not sending messages. */
1150 TREE_USED (UOBJC_SELECTOR_TABLE_decl) = 1;
1153 generate_forward_declaration_to_string_table ();
1155 /* Forward declare constant_string_id and constant_string_type. */
1156 if (!constant_string_class_name)
1157 constant_string_class_name = default_constant_string_class_name;
1159 constant_string_id = get_identifier (constant_string_class_name);
1160 constant_string_type = xref_tag (RECORD_TYPE, constant_string_id);
1163 /* Predefine the following data type:
1165 struct STRING_OBJECT_CLASS_NAME
1169 unsigned int length;
1173 build_string_class_template ()
1175 tree field_decl, field_decl_chain;
1177 field_decl = create_builtin_decl (FIELD_DECL, id_type, "isa");
1178 field_decl_chain = field_decl;
1180 field_decl = create_builtin_decl (FIELD_DECL,
1181 build_pointer_type (char_type_node),
1183 chainon (field_decl_chain, field_decl);
1185 field_decl = create_builtin_decl (FIELD_DECL, unsigned_type_node, "length");
1186 chainon (field_decl_chain, field_decl);
1188 finish_struct (constant_string_type, field_decl_chain, NULL_TREE);
1191 /* Custom build_string which sets TREE_TYPE! */
1194 my_build_string (len, str)
1198 return fix_string_type (build_string (len, str));
1201 /* Given a chain of STRING_CST's, build a static instance of
1202 NXConstantString which points at the concatenation of those strings.
1203 We place the string object in the __string_objects section of the
1204 __OBJC segment. The Objective-C runtime will initialize the isa
1205 pointers of the string objects to point at the NXConstantString
1209 build_objc_string_object (strings)
1212 tree string, initlist, constructor;
1215 if (lookup_interface (constant_string_id) == NULL_TREE)
1217 error ("cannot find interface declaration for `%s'",
1218 IDENTIFIER_POINTER (constant_string_id));
1219 return error_mark_node;
1222 add_class_reference (constant_string_id);
1224 if (TREE_CHAIN (strings))
1226 varray_type vstrings;
1227 VARRAY_TREE_INIT (vstrings, 32, "strings");
1229 for (; strings ; strings = TREE_CHAIN (strings))
1230 VARRAY_PUSH_TREE (vstrings, strings);
1232 string = combine_strings (vstrings);
1237 string = fix_string_type (string);
1239 TREE_SET_CODE (string, STRING_CST);
1240 length = TREE_STRING_LENGTH (string) - 1;
1242 /* We could not properly create NXConstantString in synth_module_prologue,
1243 because that's called before debugging is initialized. Do it now. */
1244 if (TYPE_FIELDS (constant_string_type) == NULL_TREE)
1245 build_string_class_template ();
1247 /* & ((NXConstantString) { NULL, string, length }) */
1249 if (flag_next_runtime)
1251 /* For the NeXT runtime, we can generate a literal reference
1252 to the string class, don't need to run a constructor. */
1253 setup_string_decl ();
1254 if (string_class_decl == NULL_TREE)
1256 error ("cannot find reference tag for class `%s'",
1257 IDENTIFIER_POINTER (constant_string_id));
1258 return error_mark_node;
1260 initlist = build_tree_list
1262 copy_node (build_unary_op (ADDR_EXPR, string_class_decl, 0)));
1266 initlist = build_tree_list (NULL_TREE, build_int_2 (0, 0));
1270 = tree_cons (NULL_TREE, copy_node (build_unary_op (ADDR_EXPR, string, 1)),
1272 initlist = tree_cons (NULL_TREE, build_int_2 (length, 0), initlist);
1273 constructor = build_constructor (constant_string_type, nreverse (initlist));
1275 if (!flag_next_runtime)
1278 = objc_add_static_instance (constructor, constant_string_type);
1281 return (build_unary_op (ADDR_EXPR, constructor, 1));
1284 /* Declare a static instance of CLASS_DECL initialized by CONSTRUCTOR. */
1287 objc_add_static_instance (constructor, class_decl)
1288 tree constructor, class_decl;
1290 static int num_static_inst;
1294 /* Find the list of static instances for the CLASS_DECL. Create one if
1296 for (chain = &objc_static_instances;
1297 *chain && TREE_VALUE (*chain) != class_decl;
1298 chain = &TREE_CHAIN (*chain));
1301 *chain = tree_cons (NULL_TREE, class_decl, NULL_TREE);
1302 add_objc_string (TYPE_NAME (class_decl), class_names);
1305 sprintf (buf, "_OBJC_INSTANCE_%d", num_static_inst++);
1306 decl = build_decl (VAR_DECL, get_identifier (buf), class_decl);
1307 DECL_COMMON (decl) = 1;
1308 TREE_STATIC (decl) = 1;
1309 DECL_ARTIFICIAL (decl) = 1;
1310 DECL_INITIAL (decl) = constructor;
1312 /* We may be writing something else just now.
1313 Postpone till end of input. */
1314 DECL_DEFER_OUTPUT (decl) = 1;
1315 pushdecl_top_level (decl);
1316 rest_of_decl_compilation (decl, 0, 1, 0);
1318 /* Add the DECL to the head of this CLASS' list. */
1319 TREE_PURPOSE (*chain) = tree_cons (NULL_TREE, decl, TREE_PURPOSE (*chain));
1324 /* Build a static constant CONSTRUCTOR
1325 with type TYPE and elements ELTS. */
1328 build_constructor (type, elts)
1331 tree constructor, f, e;
1333 /* ??? Most of the places that we build constructors, we don't fill in
1334 the type of integers properly. Convert them all en masse. */
1335 if (TREE_CODE (type) == ARRAY_TYPE)
1337 f = TREE_TYPE (type);
1338 if (TREE_CODE (f) == POINTER_TYPE || TREE_CODE (f) == INTEGER_TYPE)
1339 for (e = elts; e ; e = TREE_CHAIN (e))
1340 TREE_VALUE (e) = convert (f, TREE_VALUE (e));
1344 f = TYPE_FIELDS (type);
1345 for (e = elts; e ; e = TREE_CHAIN (e), f = TREE_CHAIN (f))
1346 if (TREE_CODE (TREE_TYPE (f)) == POINTER_TYPE
1347 || TREE_CODE (TREE_TYPE (f)) == INTEGER_TYPE)
1348 TREE_VALUE (e) = convert (TREE_TYPE (f), TREE_VALUE (e));
1351 constructor = build (CONSTRUCTOR, type, NULL_TREE, elts);
1352 TREE_CONSTANT (constructor) = 1;
1353 TREE_STATIC (constructor) = 1;
1354 TREE_READONLY (constructor) = 1;
1359 /* Take care of defining and initializing _OBJC_SYMBOLS. */
1361 /* Predefine the following data type:
1369 void *defs[cls_def_cnt + cat_def_cnt];
1373 build_objc_symtab_template ()
1375 tree field_decl, field_decl_chain, index;
1377 objc_symtab_template
1378 = start_struct (RECORD_TYPE, get_identifier (UTAG_SYMTAB));
1380 /* long sel_ref_cnt; */
1382 field_decl = create_builtin_decl (FIELD_DECL,
1383 long_integer_type_node,
1385 field_decl_chain = field_decl;
1389 field_decl = create_builtin_decl (FIELD_DECL,
1390 build_pointer_type (selector_type),
1392 chainon (field_decl_chain, field_decl);
1394 /* short cls_def_cnt; */
1396 field_decl = create_builtin_decl (FIELD_DECL,
1397 short_integer_type_node,
1399 chainon (field_decl_chain, field_decl);
1401 /* short cat_def_cnt; */
1403 field_decl = create_builtin_decl (FIELD_DECL,
1404 short_integer_type_node,
1406 chainon (field_decl_chain, field_decl);
1408 /* void *defs[cls_def_cnt + cat_def_cnt]; */
1410 if (!flag_next_runtime)
1411 index = build_index_type (build_int_2 (imp_count + cat_count, 0));
1413 index = build_index_type (build_int_2 (imp_count + cat_count - 1,
1414 imp_count == 0 && cat_count == 0
1416 field_decl = create_builtin_decl (FIELD_DECL,
1417 build_array_type (ptr_type_node, index),
1419 chainon (field_decl_chain, field_decl);
1421 finish_struct (objc_symtab_template, field_decl_chain, NULL_TREE);
1424 /* Create the initial value for the `defs' field of _objc_symtab.
1425 This is a CONSTRUCTOR. */
1428 init_def_list (type)
1431 tree expr, initlist = NULL_TREE;
1432 struct imp_entry *impent;
1435 for (impent = imp_list; impent; impent = impent->next)
1437 if (TREE_CODE (impent->imp_context) == CLASS_IMPLEMENTATION_TYPE)
1439 expr = build_unary_op (ADDR_EXPR, impent->class_decl, 0);
1440 initlist = tree_cons (NULL_TREE, expr, initlist);
1445 for (impent = imp_list; impent; impent = impent->next)
1447 if (TREE_CODE (impent->imp_context) == CATEGORY_IMPLEMENTATION_TYPE)
1449 expr = build_unary_op (ADDR_EXPR, impent->class_decl, 0);
1450 initlist = tree_cons (NULL_TREE, expr, initlist);
1454 if (!flag_next_runtime)
1456 /* statics = { ..., _OBJC_STATIC_INSTANCES, ... } */
1459 if (static_instances_decl)
1460 expr = build_unary_op (ADDR_EXPR, static_instances_decl, 0);
1462 expr = build_int_2 (0, 0);
1464 initlist = tree_cons (NULL_TREE, expr, initlist);
1467 return build_constructor (type, nreverse (initlist));
1470 /* Construct the initial value for all of _objc_symtab. */
1473 init_objc_symtab (type)
1478 /* sel_ref_cnt = { ..., 5, ... } */
1480 initlist = build_tree_list (NULL_TREE, build_int_2 (0, 0));
1482 /* refs = { ..., _OBJC_SELECTOR_TABLE, ... } */
1484 if (flag_next_runtime || ! sel_ref_chain)
1485 initlist = tree_cons (NULL_TREE, build_int_2 (0, 0), initlist);
1487 initlist = tree_cons (NULL_TREE,
1488 build_unary_op (ADDR_EXPR,
1489 UOBJC_SELECTOR_TABLE_decl, 1),
1492 /* cls_def_cnt = { ..., 5, ... } */
1494 initlist = tree_cons (NULL_TREE, build_int_2 (imp_count, 0), initlist);
1496 /* cat_def_cnt = { ..., 5, ... } */
1498 initlist = tree_cons (NULL_TREE, build_int_2 (cat_count, 0), initlist);
1500 /* cls_def = { ..., { &Foo, &Bar, ...}, ... } */
1502 if (imp_count || cat_count || static_instances_decl)
1505 tree field = TYPE_FIELDS (type);
1506 field = TREE_CHAIN (TREE_CHAIN (TREE_CHAIN (TREE_CHAIN (field))));
1508 initlist = tree_cons (NULL_TREE, init_def_list (TREE_TYPE (field)),
1512 return build_constructor (type, nreverse (initlist));
1515 /* Push forward-declarations of all the categories so that
1516 init_def_list can use them in a CONSTRUCTOR. */
1519 forward_declare_categories ()
1521 struct imp_entry *impent;
1522 tree sav = objc_implementation_context;
1524 for (impent = imp_list; impent; impent = impent->next)
1526 if (TREE_CODE (impent->imp_context) == CATEGORY_IMPLEMENTATION_TYPE)
1528 /* Set an invisible arg to synth_id_with_class_suffix. */
1529 objc_implementation_context = impent->imp_context;
1531 = create_builtin_decl (VAR_DECL, objc_category_template,
1532 IDENTIFIER_POINTER (synth_id_with_class_suffix ("_OBJC_CATEGORY", objc_implementation_context)));
1535 objc_implementation_context = sav;
1538 /* Create the declaration of _OBJC_SYMBOLS, with type `strict _objc_symtab'
1539 and initialized appropriately. */
1542 generate_objc_symtab_decl ()
1546 if (!objc_category_template)
1547 build_category_template ();
1549 /* forward declare categories */
1551 forward_declare_categories ();
1553 if (!objc_symtab_template)
1554 build_objc_symtab_template ();
1556 sc_spec = build_tree_list (NULL_TREE, ridpointers[(int) RID_STATIC]);
1558 UOBJC_SYMBOLS_decl = start_decl (get_identifier ("_OBJC_SYMBOLS"),
1559 tree_cons (NULL_TREE,
1560 objc_symtab_template, sc_spec),
1564 TREE_USED (UOBJC_SYMBOLS_decl) = 1;
1565 DECL_IGNORED_P (UOBJC_SYMBOLS_decl) = 1;
1566 DECL_ARTIFICIAL (UOBJC_SYMBOLS_decl) = 1;
1567 finish_decl (UOBJC_SYMBOLS_decl,
1568 init_objc_symtab (TREE_TYPE (UOBJC_SYMBOLS_decl)),
1573 init_module_descriptor (type)
1576 tree initlist, expr;
1578 /* version = { 1, ... } */
1580 expr = build_int_2 (OBJC_VERSION, 0);
1581 initlist = build_tree_list (NULL_TREE, expr);
1583 /* size = { ..., sizeof (struct objc_module), ... } */
1585 expr = size_in_bytes (objc_module_template);
1586 initlist = tree_cons (NULL_TREE, expr, initlist);
1588 /* name = { ..., "foo.m", ... } */
1590 expr = add_objc_string (get_identifier (input_filename), class_names);
1591 initlist = tree_cons (NULL_TREE, expr, initlist);
1593 /* symtab = { ..., _OBJC_SYMBOLS, ... } */
1595 if (UOBJC_SYMBOLS_decl)
1596 expr = build_unary_op (ADDR_EXPR, UOBJC_SYMBOLS_decl, 0);
1598 expr = build_int_2 (0, 0);
1599 initlist = tree_cons (NULL_TREE, expr, initlist);
1601 return build_constructor (type, nreverse (initlist));
1604 /* Write out the data structures to describe Objective C classes defined.
1605 If appropriate, compile and output a setup function to initialize them.
1606 Return a symbol_ref to the function to call to initialize the Objective C
1607 data structures for this file (and perhaps for other files also).
1609 struct objc_module { ... } _OBJC_MODULE = { ... }; */
1612 build_module_descriptor ()
1614 tree decl_specs, field_decl, field_decl_chain;
1616 objc_module_template
1617 = start_struct (RECORD_TYPE, get_identifier (UTAG_MODULE));
1621 decl_specs = build_tree_list (NULL_TREE, ridpointers[(int) RID_LONG]);
1622 field_decl = get_identifier ("version");
1624 = grokfield (input_filename, lineno, field_decl, decl_specs, NULL_TREE);
1625 field_decl_chain = field_decl;
1629 decl_specs = build_tree_list (NULL_TREE, ridpointers[(int) RID_LONG]);
1630 field_decl = get_identifier ("size");
1632 = grokfield (input_filename, lineno, field_decl, decl_specs, NULL_TREE);
1633 chainon (field_decl_chain, field_decl);
1637 decl_specs = build_tree_list (NULL_TREE, ridpointers[(int) RID_CHAR]);
1638 field_decl = build1 (INDIRECT_REF, NULL_TREE, get_identifier ("name"));
1640 = grokfield (input_filename, lineno, field_decl, decl_specs, NULL_TREE);
1641 chainon (field_decl_chain, field_decl);
1643 /* struct objc_symtab *symtab; */
1645 decl_specs = get_identifier (UTAG_SYMTAB);
1646 decl_specs = build_tree_list (NULL_TREE, xref_tag (RECORD_TYPE, decl_specs));
1647 field_decl = build1 (INDIRECT_REF, NULL_TREE, get_identifier ("symtab"));
1649 = grokfield (input_filename, lineno, field_decl, decl_specs, NULL_TREE);
1650 chainon (field_decl_chain, field_decl);
1652 finish_struct (objc_module_template, field_decl_chain, NULL_TREE);
1654 /* Create an instance of "objc_module". */
1656 decl_specs = tree_cons (NULL_TREE, objc_module_template,
1657 build_tree_list (NULL_TREE,
1658 ridpointers[(int) RID_STATIC]));
1660 UOBJC_MODULES_decl = start_decl (get_identifier ("_OBJC_MODULES"),
1661 decl_specs, 1, NULL_TREE);
1663 DECL_ARTIFICIAL (UOBJC_MODULES_decl) = 1;
1664 DECL_IGNORED_P (UOBJC_MODULES_decl) = 1;
1665 DECL_CONTEXT (UOBJC_MODULES_decl) = NULL_TREE;
1667 finish_decl (UOBJC_MODULES_decl,
1668 init_module_descriptor (TREE_TYPE (UOBJC_MODULES_decl)),
1671 /* Mark the decl to avoid "defined but not used" warning. */
1672 DECL_IN_SYSTEM_HEADER (UOBJC_MODULES_decl) = 1;
1674 /* Generate a constructor call for the module descriptor.
1675 This code was generated by reading the grammar rules
1676 of c-parse.in; Therefore, it may not be the most efficient
1677 way of generating the requisite code. */
1679 if (flag_next_runtime)
1683 tree parms, execclass_decl, decelerator, void_list_node_1;
1684 tree init_function_name, init_function_decl;
1686 /* Declare void __objc_execClass (void *); */
1688 void_list_node_1 = build_tree_list (NULL_TREE, void_type_node);
1689 execclass_decl = build_decl (FUNCTION_DECL,
1690 get_identifier (TAG_EXECCLASS),
1691 build_function_type (void_type_node,
1692 tree_cons (NULL_TREE, ptr_type_node,
1693 void_list_node_1)));
1694 DECL_EXTERNAL (execclass_decl) = 1;
1695 DECL_ARTIFICIAL (execclass_decl) = 1;
1696 TREE_PUBLIC (execclass_decl) = 1;
1697 pushdecl (execclass_decl);
1698 rest_of_decl_compilation (execclass_decl, 0, 0, 0);
1699 assemble_external (execclass_decl);
1701 /* void _GLOBAL_$I$<gnyf> () {objc_execClass (&L_OBJC_MODULES);} */
1703 init_function_name = get_file_function_name ('I');
1704 start_function (void_list_node_1,
1705 build_nt (CALL_EXPR, init_function_name,
1706 tree_cons (NULL_TREE, NULL_TREE,
1710 store_parm_decls ();
1712 init_function_decl = current_function_decl;
1713 TREE_PUBLIC (init_function_decl) = ! targetm.have_ctors_dtors;
1714 TREE_USED (init_function_decl) = 1;
1715 /* Don't let this one be deferred. */
1716 DECL_INLINE (init_function_decl) = 0;
1717 DECL_UNINLINABLE (init_function_decl) = 1;
1718 current_function_cannot_inline
1719 = "static constructors and destructors cannot be inlined";
1722 = build_tree_list (NULL_TREE,
1723 build_unary_op (ADDR_EXPR, UOBJC_MODULES_decl, 0));
1724 decelerator = build_function_call (execclass_decl, parms);
1726 c_expand_expr_stmt (decelerator);
1728 finish_function (0, 0);
1730 return XEXP (DECL_RTL (init_function_decl), 0);
1734 /* extern const char _OBJC_STRINGS[]; */
1737 generate_forward_declaration_to_string_table ()
1739 tree sc_spec, decl_specs, expr_decl;
1741 sc_spec = tree_cons (NULL_TREE, ridpointers[(int) RID_EXTERN], NULL_TREE);
1742 decl_specs = tree_cons (NULL_TREE, ridpointers[(int) RID_CHAR], sc_spec);
1745 = build_nt (ARRAY_REF, get_identifier ("_OBJC_STRINGS"), NULL_TREE);
1747 UOBJC_STRINGS_decl = define_decl (expr_decl, decl_specs);
1750 /* Return the DECL of the string IDENT in the SECTION. */
1753 get_objc_string_decl (ident, section)
1755 enum string_section section;
1759 if (section == class_names)
1760 chain = class_names_chain;
1761 else if (section == meth_var_names)
1762 chain = meth_var_names_chain;
1763 else if (section == meth_var_types)
1764 chain = meth_var_types_chain;
1768 for (; chain != 0; chain = TREE_VALUE (chain))
1769 if (TREE_VALUE (chain) == ident)
1770 return (TREE_PURPOSE (chain));
1776 /* Output references to all statically allocated objects. Return the DECL
1777 for the array built. */
1780 generate_static_references ()
1782 tree decls = NULL_TREE, ident, decl_spec, expr_decl, expr = NULL_TREE;
1783 tree class_name, class, decl, initlist;
1784 tree cl_chain, in_chain, type;
1785 int num_inst, num_class;
1788 if (flag_next_runtime)
1791 for (cl_chain = objc_static_instances, num_class = 0;
1792 cl_chain; cl_chain = TREE_CHAIN (cl_chain), num_class++)
1794 for (num_inst = 0, in_chain = TREE_PURPOSE (cl_chain);
1795 in_chain; num_inst++, in_chain = TREE_CHAIN (in_chain));
1797 sprintf (buf, "_OBJC_STATIC_INSTANCES_%d", num_class);
1798 ident = get_identifier (buf);
1800 expr_decl = build_nt (ARRAY_REF, ident, NULL_TREE);
1801 decl_spec = tree_cons (NULL_TREE, build_pointer_type (void_type_node),
1802 build_tree_list (NULL_TREE,
1803 ridpointers[(int) RID_STATIC]));
1804 decl = start_decl (expr_decl, decl_spec, 1, NULL_TREE);
1805 DECL_CONTEXT (decl) = 0;
1806 DECL_ARTIFICIAL (decl) = 1;
1808 /* Output {class_name, ...}. */
1809 class = TREE_VALUE (cl_chain);
1810 class_name = get_objc_string_decl (TYPE_NAME (class), class_names);
1811 initlist = build_tree_list (NULL_TREE,
1812 build_unary_op (ADDR_EXPR, class_name, 1));
1814 /* Output {..., instance, ...}. */
1815 for (in_chain = TREE_PURPOSE (cl_chain);
1816 in_chain; in_chain = TREE_CHAIN (in_chain))
1818 expr = build_unary_op (ADDR_EXPR, TREE_VALUE (in_chain), 1);
1819 initlist = tree_cons (NULL_TREE, expr, initlist);
1822 /* Output {..., NULL}. */
1823 initlist = tree_cons (NULL_TREE, build_int_2 (0, 0), initlist);
1825 expr = build_constructor (TREE_TYPE (decl), nreverse (initlist));
1826 finish_decl (decl, expr, NULL_TREE);
1827 TREE_USED (decl) = 1;
1829 type = build_array_type (build_pointer_type (void_type_node), 0);
1830 decl = build_decl (VAR_DECL, ident, type);
1831 TREE_USED (decl) = 1;
1832 TREE_STATIC (decl) = 1;
1834 = tree_cons (NULL_TREE, build_unary_op (ADDR_EXPR, decl, 1), decls);
1837 decls = tree_cons (NULL_TREE, build_int_2 (0, 0), decls);
1838 ident = get_identifier ("_OBJC_STATIC_INSTANCES");
1839 expr_decl = build_nt (ARRAY_REF, ident, NULL_TREE);
1840 decl_spec = tree_cons (NULL_TREE, build_pointer_type (void_type_node),
1841 build_tree_list (NULL_TREE,
1842 ridpointers[(int) RID_STATIC]));
1843 static_instances_decl
1844 = start_decl (expr_decl, decl_spec, 1, NULL_TREE);
1845 TREE_USED (static_instances_decl) = 1;
1846 DECL_CONTEXT (static_instances_decl) = 0;
1847 DECL_ARTIFICIAL (static_instances_decl) = 1;
1848 expr = build_constructor (TREE_TYPE (static_instances_decl),
1850 finish_decl (static_instances_decl, expr, NULL_TREE);
1853 /* Output all strings. */
1858 tree sc_spec, decl_specs, expr_decl;
1859 tree chain, string_expr;
1862 for (chain = class_names_chain; chain; chain = TREE_CHAIN (chain))
1864 string = TREE_VALUE (chain);
1865 decl = TREE_PURPOSE (chain);
1867 = tree_cons (NULL_TREE, ridpointers[(int) RID_STATIC], NULL_TREE);
1868 decl_specs = tree_cons (NULL_TREE, ridpointers[(int) RID_CHAR], sc_spec);
1869 expr_decl = build_nt (ARRAY_REF, DECL_NAME (decl), NULL_TREE);
1870 decl = start_decl (expr_decl, decl_specs, 1, NULL_TREE);
1871 DECL_CONTEXT (decl) = NULL_TREE;
1872 string_expr = my_build_string (IDENTIFIER_LENGTH (string) + 1,
1873 IDENTIFIER_POINTER (string));
1874 finish_decl (decl, string_expr, NULL_TREE);
1877 for (chain = meth_var_names_chain; chain; chain = TREE_CHAIN (chain))
1879 string = TREE_VALUE (chain);
1880 decl = TREE_PURPOSE (chain);
1882 = tree_cons (NULL_TREE, ridpointers[(int) RID_STATIC], NULL_TREE);
1883 decl_specs = tree_cons (NULL_TREE, ridpointers[(int) RID_CHAR], sc_spec);
1884 expr_decl = build_nt (ARRAY_REF, DECL_NAME (decl), NULL_TREE);
1885 decl = start_decl (expr_decl, decl_specs, 1, NULL_TREE);
1886 DECL_CONTEXT (decl) = NULL_TREE;
1887 string_expr = my_build_string (IDENTIFIER_LENGTH (string) + 1,
1888 IDENTIFIER_POINTER (string));
1889 finish_decl (decl, string_expr, NULL_TREE);
1892 for (chain = meth_var_types_chain; chain; chain = TREE_CHAIN (chain))
1894 string = TREE_VALUE (chain);
1895 decl = TREE_PURPOSE (chain);
1897 = tree_cons (NULL_TREE, ridpointers[(int) RID_STATIC], NULL_TREE);
1898 decl_specs = tree_cons (NULL_TREE, ridpointers[(int) RID_CHAR], sc_spec);
1899 expr_decl = build_nt (ARRAY_REF, DECL_NAME (decl), NULL_TREE);
1900 decl = start_decl (expr_decl, decl_specs, 1, NULL_TREE);
1901 DECL_CONTEXT (decl) = NULL_TREE;
1902 string_expr = my_build_string (IDENTIFIER_LENGTH (string) + 1,
1903 IDENTIFIER_POINTER (string));
1904 finish_decl (decl, string_expr, NULL_TREE);
1909 build_selector_reference_decl ()
1915 sprintf (buf, "_OBJC_SELECTOR_REFERENCES_%d", idx++);
1917 ident = get_identifier (buf);
1919 decl = build_decl (VAR_DECL, ident, selector_type);
1920 DECL_EXTERNAL (decl) = 1;
1921 TREE_PUBLIC (decl) = 1;
1922 TREE_USED (decl) = 1;
1923 TREE_READONLY (decl) = 1;
1924 DECL_ARTIFICIAL (decl) = 1;
1925 DECL_CONTEXT (decl) = 0;
1927 make_decl_rtl (decl, 0);
1928 pushdecl_top_level (decl);
1933 /* Just a handy wrapper for add_objc_string. */
1936 build_selector (ident)
1939 tree expr = add_objc_string (ident, meth_var_names);
1940 if (flag_typed_selectors)
1943 return build_c_cast (selector_type, expr); /* cast! */
1947 build_selector_translation_table ()
1949 tree sc_spec, decl_specs;
1950 tree chain, initlist = NULL_TREE;
1952 tree decl = NULL_TREE, var_decl, name;
1954 for (chain = sel_ref_chain; chain; chain = TREE_CHAIN (chain))
1958 expr = build_selector (TREE_VALUE (chain));
1960 if (flag_next_runtime)
1962 name = DECL_NAME (TREE_PURPOSE (chain));
1964 sc_spec = build_tree_list (NULL_TREE, ridpointers[(int) RID_STATIC]);
1966 /* static SEL _OBJC_SELECTOR_REFERENCES_n = ...; */
1967 decl_specs = tree_cons (NULL_TREE, selector_type, sc_spec);
1971 /* The `decl' that is returned from start_decl is the one that we
1972 forward declared in `build_selector_reference' */
1973 decl = start_decl (var_decl, decl_specs, 1, NULL_TREE );
1976 /* add one for the '\0' character */
1977 offset += IDENTIFIER_LENGTH (TREE_VALUE (chain)) + 1;
1979 if (flag_next_runtime)
1980 finish_decl (decl, expr, NULL_TREE);
1983 if (flag_typed_selectors)
1985 tree eltlist = NULL_TREE;
1986 tree encoding = get_proto_encoding (TREE_PURPOSE (chain));
1987 eltlist = tree_cons (NULL_TREE, expr, NULL_TREE);
1988 eltlist = tree_cons (NULL_TREE, encoding, eltlist);
1989 expr = build_constructor (objc_selector_template,
1990 nreverse (eltlist));
1992 initlist = tree_cons (NULL_TREE, expr, initlist);
1997 if (! flag_next_runtime)
1999 /* Cause the variable and its initial value to be actually output. */
2000 DECL_EXTERNAL (UOBJC_SELECTOR_TABLE_decl) = 0;
2001 TREE_STATIC (UOBJC_SELECTOR_TABLE_decl) = 1;
2002 /* NULL terminate the list and fix the decl for output. */
2003 initlist = tree_cons (NULL_TREE, build_int_2 (0, 0), initlist);
2004 DECL_INITIAL (UOBJC_SELECTOR_TABLE_decl) = objc_ellipsis_node;
2005 initlist = build_constructor (TREE_TYPE (UOBJC_SELECTOR_TABLE_decl),
2006 nreverse (initlist));
2007 finish_decl (UOBJC_SELECTOR_TABLE_decl, initlist, NULL_TREE);
2008 current_function_decl = NULL_TREE;
2013 get_proto_encoding (proto)
2021 if (! METHOD_ENCODING (proto))
2023 tmp_decl = build_tmp_function_decl ();
2024 hack_method_prototype (proto, tmp_decl);
2025 encoding = encode_method_prototype (proto, tmp_decl);
2026 METHOD_ENCODING (proto) = encoding;
2029 encoding = METHOD_ENCODING (proto);
2031 return add_objc_string (encoding, meth_var_types);
2034 return build_int_2 (0, 0);
2037 /* sel_ref_chain is a list whose "value" fields will be instances of
2038 identifier_node that represent the selector. */
2041 build_typed_selector_reference (ident, proto)
2044 tree *chain = &sel_ref_chain;
2050 if (TREE_PURPOSE (*chain) == ident && TREE_VALUE (*chain) == proto)
2051 goto return_at_index;
2054 chain = &TREE_CHAIN (*chain);
2057 *chain = tree_cons (proto, ident, NULL_TREE);
2060 expr = build_unary_op (ADDR_EXPR,
2061 build_array_ref (UOBJC_SELECTOR_TABLE_decl,
2062 build_int_2 (index, 0)),
2064 return build_c_cast (selector_type, expr);
2068 build_selector_reference (ident)
2071 tree *chain = &sel_ref_chain;
2077 if (TREE_VALUE (*chain) == ident)
2078 return (flag_next_runtime
2079 ? TREE_PURPOSE (*chain)
2080 : build_array_ref (UOBJC_SELECTOR_TABLE_decl,
2081 build_int_2 (index, 0)));
2084 chain = &TREE_CHAIN (*chain);
2087 expr = build_selector_reference_decl ();
2089 *chain = tree_cons (expr, ident, NULL_TREE);
2091 return (flag_next_runtime
2093 : build_array_ref (UOBJC_SELECTOR_TABLE_decl,
2094 build_int_2 (index, 0)));
2098 build_class_reference_decl ()
2104 sprintf (buf, "_OBJC_CLASS_REFERENCES_%d", idx++);
2106 ident = get_identifier (buf);
2108 decl = build_decl (VAR_DECL, ident, objc_class_type);
2109 DECL_EXTERNAL (decl) = 1;
2110 TREE_PUBLIC (decl) = 1;
2111 TREE_USED (decl) = 1;
2112 TREE_READONLY (decl) = 1;
2113 DECL_CONTEXT (decl) = 0;
2114 DECL_ARTIFICIAL (decl) = 1;
2116 make_decl_rtl (decl, 0);
2117 pushdecl_top_level (decl);
2122 /* Create a class reference, but don't create a variable to reference
2126 add_class_reference (ident)
2131 if ((chain = cls_ref_chain))
2136 if (ident == TREE_VALUE (chain))
2140 chain = TREE_CHAIN (chain);
2144 /* Append to the end of the list */
2145 TREE_CHAIN (tail) = tree_cons (NULL_TREE, ident, NULL_TREE);
2148 cls_ref_chain = tree_cons (NULL_TREE, ident, NULL_TREE);
2151 /* Get a class reference, creating it if necessary. Also create the
2152 reference variable. */
2155 get_class_reference (ident)
2158 if (flag_next_runtime)
2163 for (chain = &cls_ref_chain; *chain; chain = &TREE_CHAIN (*chain))
2164 if (TREE_VALUE (*chain) == ident)
2166 if (! TREE_PURPOSE (*chain))
2167 TREE_PURPOSE (*chain) = build_class_reference_decl ();
2169 return TREE_PURPOSE (*chain);
2172 decl = build_class_reference_decl ();
2173 *chain = tree_cons (decl, ident, NULL_TREE);
2180 add_class_reference (ident);
2182 params = build_tree_list (NULL_TREE,
2183 my_build_string (IDENTIFIER_LENGTH (ident) + 1,
2184 IDENTIFIER_POINTER (ident)));
2186 assemble_external (objc_get_class_decl);
2187 return build_function_call (objc_get_class_decl, params);
2191 /* For each string section we have a chain which maps identifier nodes
2192 to decls for the strings. */
2195 add_objc_string (ident, section)
2197 enum string_section section;
2201 if (section == class_names)
2202 chain = &class_names_chain;
2203 else if (section == meth_var_names)
2204 chain = &meth_var_names_chain;
2205 else if (section == meth_var_types)
2206 chain = &meth_var_types_chain;
2212 if (TREE_VALUE (*chain) == ident)
2213 return build_unary_op (ADDR_EXPR, TREE_PURPOSE (*chain), 1);
2215 chain = &TREE_CHAIN (*chain);
2218 decl = build_objc_string_decl (section);
2220 *chain = tree_cons (decl, ident, NULL_TREE);
2222 return build_unary_op (ADDR_EXPR, decl, 1);
2226 build_objc_string_decl (section)
2227 enum string_section section;
2231 static int class_names_idx = 0;
2232 static int meth_var_names_idx = 0;
2233 static int meth_var_types_idx = 0;
2235 if (section == class_names)
2236 sprintf (buf, "_OBJC_CLASS_NAME_%d", class_names_idx++);
2237 else if (section == meth_var_names)
2238 sprintf (buf, "_OBJC_METH_VAR_NAME_%d", meth_var_names_idx++);
2239 else if (section == meth_var_types)
2240 sprintf (buf, "_OBJC_METH_VAR_TYPE_%d", meth_var_types_idx++);
2242 ident = get_identifier (buf);
2244 decl = build_decl (VAR_DECL, ident, build_array_type (char_type_node, 0));
2245 DECL_EXTERNAL (decl) = 1;
2246 TREE_PUBLIC (decl) = 1;
2247 TREE_USED (decl) = 1;
2248 TREE_READONLY (decl) = 1;
2249 TREE_CONSTANT (decl) = 1;
2250 DECL_CONTEXT (decl) = 0;
2251 DECL_ARTIFICIAL (decl) = 1;
2253 make_decl_rtl (decl, 0);
2254 pushdecl_top_level (decl);
2261 objc_declare_alias (alias_ident, class_ident)
2265 if (is_class_name (class_ident) != class_ident)
2266 warning ("cannot find class `%s'", IDENTIFIER_POINTER (class_ident));
2267 else if (is_class_name (alias_ident))
2268 warning ("class `%s' already exists", IDENTIFIER_POINTER (alias_ident));
2270 alias_chain = tree_cons (class_ident, alias_ident, alias_chain);
2274 objc_declare_class (ident_list)
2279 for (list = ident_list; list; list = TREE_CHAIN (list))
2281 tree ident = TREE_VALUE (list);
2284 if ((decl = lookup_name (ident)))
2286 error ("`%s' redeclared as different kind of symbol",
2287 IDENTIFIER_POINTER (ident));
2288 error_with_decl (decl, "previous declaration of `%s'");
2291 if (! is_class_name (ident))
2293 tree record = xref_tag (RECORD_TYPE, ident);
2294 TREE_STATIC_TEMPLATE (record) = 1;
2295 class_chain = tree_cons (NULL_TREE, ident, class_chain);
2301 is_class_name (ident)
2306 if (lookup_interface (ident))
2309 for (chain = class_chain; chain; chain = TREE_CHAIN (chain))
2311 if (ident == TREE_VALUE (chain))
2315 for (chain = alias_chain; chain; chain = TREE_CHAIN (chain))
2317 if (ident == TREE_VALUE (chain))
2318 return TREE_PURPOSE (chain);
2325 lookup_interface (ident)
2330 for (chain = interface_chain; chain; chain = TREE_CHAIN (chain))
2332 if (ident == CLASS_NAME (chain))
2339 objc_copy_list (list, head)
2343 tree newlist = NULL_TREE, tail = NULL_TREE;
2347 tail = copy_node (list);
2349 /* The following statement fixes a bug when inheriting instance
2350 variables that are declared to be bitfields. finish_struct
2351 expects to find the width of the bitfield in DECL_INITIAL. */
2352 if (DECL_BIT_FIELD (tail) && DECL_INITIAL (tail) == 0)
2353 DECL_INITIAL (tail) = DECL_SIZE (tail);
2355 newlist = chainon (newlist, tail);
2356 list = TREE_CHAIN (list);
2363 /* Used by: build_private_template, get_class_ivars, and
2364 continue_class. COPY is 1 when called from @defs. In this case
2365 copy all fields. Otherwise don't copy leaf ivars since we rely on
2366 them being side-effected exactly once by finish_struct. */
2369 build_ivar_chain (interface, copy)
2373 tree my_name, super_name, ivar_chain;
2375 my_name = CLASS_NAME (interface);
2376 super_name = CLASS_SUPER_NAME (interface);
2378 /* Possibly copy leaf ivars. */
2380 objc_copy_list (CLASS_IVARS (interface), &ivar_chain);
2382 ivar_chain = CLASS_IVARS (interface);
2387 tree super_interface = lookup_interface (super_name);
2389 if (!super_interface)
2391 /* fatal did not work with 2 args...should fix */
2392 error ("cannot find interface declaration for `%s', superclass of `%s'",
2393 IDENTIFIER_POINTER (super_name),
2394 IDENTIFIER_POINTER (my_name));
2395 exit (FATAL_EXIT_CODE);
2398 if (super_interface == interface)
2399 fatal_error ("circular inheritance in interface declaration for `%s'",
2400 IDENTIFIER_POINTER (super_name));
2402 interface = super_interface;
2403 my_name = CLASS_NAME (interface);
2404 super_name = CLASS_SUPER_NAME (interface);
2406 op1 = CLASS_IVARS (interface);
2409 tree head, tail = objc_copy_list (op1, &head);
2411 /* Prepend super class ivars...make a copy of the list, we
2412 do not want to alter the original. */
2413 TREE_CHAIN (tail) = ivar_chain;
2420 /* struct <classname> {
2421 struct objc_class *isa;
2426 build_private_template (class)
2431 if (CLASS_STATIC_TEMPLATE (class))
2433 uprivate_record = CLASS_STATIC_TEMPLATE (class);
2434 ivar_context = TYPE_FIELDS (CLASS_STATIC_TEMPLATE (class));
2438 uprivate_record = start_struct (RECORD_TYPE, CLASS_NAME (class));
2440 ivar_context = build_ivar_chain (class, 0);
2442 finish_struct (uprivate_record, ivar_context, NULL_TREE);
2444 CLASS_STATIC_TEMPLATE (class) = uprivate_record;
2446 /* mark this record as class template - for class type checking */
2447 TREE_STATIC_TEMPLATE (uprivate_record) = 1;
2451 = groktypename (build_tree_list (build_tree_list (NULL_TREE,
2453 build1 (INDIRECT_REF, NULL_TREE,
2456 return ivar_context;
2459 /* Begin code generation for protocols... */
2461 /* struct objc_protocol {
2462 char *protocol_name;
2463 struct objc_protocol **protocol_list;
2464 struct objc_method_desc *instance_methods;
2465 struct objc_method_desc *class_methods;
2469 build_protocol_template ()
2471 tree decl_specs, field_decl, field_decl_chain;
2474 template = start_struct (RECORD_TYPE, get_identifier (UTAG_PROTOCOL));
2476 /* struct objc_class *isa; */
2478 decl_specs = build_tree_list (NULL_TREE, xref_tag (RECORD_TYPE,
2479 get_identifier (UTAG_CLASS)));
2480 field_decl = build1 (INDIRECT_REF, NULL_TREE, get_identifier ("isa"));
2482 = grokfield (input_filename, lineno, field_decl, decl_specs, NULL_TREE);
2483 field_decl_chain = field_decl;
2485 /* char *protocol_name; */
2487 decl_specs = build_tree_list (NULL_TREE, ridpointers[(int) RID_CHAR]);
2489 = build1 (INDIRECT_REF, NULL_TREE, get_identifier ("protocol_name"));
2491 = grokfield (input_filename, lineno, field_decl, decl_specs, NULL_TREE);
2492 chainon (field_decl_chain, field_decl);
2494 /* struct objc_protocol **protocol_list; */
2496 decl_specs = build_tree_list (NULL_TREE, template);
2498 = build1 (INDIRECT_REF, NULL_TREE, get_identifier ("protocol_list"));
2499 field_decl = build1 (INDIRECT_REF, NULL_TREE, field_decl);
2501 = grokfield (input_filename, lineno, field_decl, decl_specs, NULL_TREE);
2502 chainon (field_decl_chain, field_decl);
2504 /* struct objc_method_list *instance_methods; */
2507 = build_tree_list (NULL_TREE,
2508 xref_tag (RECORD_TYPE,
2509 get_identifier (UTAG_METHOD_PROTOTYPE_LIST)));
2511 = build1 (INDIRECT_REF, NULL_TREE, get_identifier ("instance_methods"));
2513 = grokfield (input_filename, lineno, field_decl, decl_specs, NULL_TREE);
2514 chainon (field_decl_chain, field_decl);
2516 /* struct objc_method_list *class_methods; */
2519 = build_tree_list (NULL_TREE,
2520 xref_tag (RECORD_TYPE,
2521 get_identifier (UTAG_METHOD_PROTOTYPE_LIST)));
2523 = build1 (INDIRECT_REF, NULL_TREE, get_identifier ("class_methods"));
2525 = grokfield (input_filename, lineno, field_decl, decl_specs, NULL_TREE);
2526 chainon (field_decl_chain, field_decl);
2528 return finish_struct (template, field_decl_chain, NULL_TREE);
2532 build_descriptor_table_initializer (type, entries)
2536 tree initlist = NULL_TREE;
2540 tree eltlist = NULL_TREE;
2543 = tree_cons (NULL_TREE,
2544 build_selector (METHOD_SEL_NAME (entries)), NULL_TREE);
2546 = tree_cons (NULL_TREE,
2547 add_objc_string (METHOD_ENCODING (entries),
2552 = tree_cons (NULL_TREE,
2553 build_constructor (type, nreverse (eltlist)), initlist);
2555 entries = TREE_CHAIN (entries);
2559 return build_constructor (build_array_type (type, 0), nreverse (initlist));
2562 /* struct objc_method_prototype_list {
2564 struct objc_method_prototype {
2571 build_method_prototype_list_template (list_type, size)
2575 tree objc_ivar_list_record;
2576 tree decl_specs, field_decl, field_decl_chain;
2578 /* Generate an unnamed struct definition. */
2580 objc_ivar_list_record = start_struct (RECORD_TYPE, NULL_TREE);
2582 /* int method_count; */
2584 decl_specs = build_tree_list (NULL_TREE, ridpointers[(int) RID_INT]);
2585 field_decl = get_identifier ("method_count");
2588 = grokfield (input_filename, lineno, field_decl, decl_specs, NULL_TREE);
2589 field_decl_chain = field_decl;
2591 /* struct objc_method method_list[]; */
2593 decl_specs = build_tree_list (NULL_TREE, list_type);
2594 field_decl = build_nt (ARRAY_REF, get_identifier ("method_list"),
2595 build_int_2 (size, 0));
2598 = grokfield (input_filename, lineno, field_decl, decl_specs, NULL_TREE);
2599 chainon (field_decl_chain, field_decl);
2601 finish_struct (objc_ivar_list_record, field_decl_chain, NULL_TREE);
2603 return objc_ivar_list_record;
2607 build_method_prototype_template ()
2610 tree decl_specs, field_decl, field_decl_chain;
2613 = start_struct (RECORD_TYPE, get_identifier (UTAG_METHOD_PROTOTYPE));
2615 /* struct objc_selector *_cmd; */
2616 decl_specs = tree_cons (NULL_TREE, xref_tag (RECORD_TYPE,
2617 get_identifier (TAG_SELECTOR)), NULL_TREE);
2618 field_decl = build1 (INDIRECT_REF, NULL_TREE, get_identifier ("_cmd"));
2621 = grokfield (input_filename, lineno, field_decl, decl_specs, NULL_TREE);
2622 field_decl_chain = field_decl;
2624 decl_specs = tree_cons (NULL_TREE, ridpointers[(int) RID_CHAR], NULL_TREE);
2626 = build1 (INDIRECT_REF, NULL_TREE, get_identifier ("method_types"));
2628 = grokfield (input_filename, lineno, field_decl, decl_specs, NULL_TREE);
2629 chainon (field_decl_chain, field_decl);
2631 finish_struct (proto_record, field_decl_chain, NULL_TREE);
2633 return proto_record;
2636 /* True if last call to forwarding_offset yielded a register offset. */
2637 static int offset_is_register;
2640 forwarding_offset (parm)
2643 int offset_in_bytes;
2645 if (GET_CODE (DECL_INCOMING_RTL (parm)) == MEM)
2647 rtx addr = XEXP (DECL_INCOMING_RTL (parm), 0);
2649 /* ??? Here we assume that the parm address is indexed
2650 off the frame pointer or arg pointer.
2651 If that is not true, we produce meaningless results,
2652 but do not crash. */
2653 if (GET_CODE (addr) == PLUS
2654 && GET_CODE (XEXP (addr, 1)) == CONST_INT)
2655 offset_in_bytes = INTVAL (XEXP (addr, 1));
2657 offset_in_bytes = 0;
2659 offset_in_bytes += OBJC_FORWARDING_STACK_OFFSET;
2660 offset_is_register = 0;
2662 else if (GET_CODE (DECL_INCOMING_RTL (parm)) == REG)
2664 int regno = REGNO (DECL_INCOMING_RTL (parm));
2665 offset_in_bytes = apply_args_register_offset (regno);
2666 offset_is_register = 1;
2671 /* This is the case where the parm is passed as an int or double
2672 and it is converted to a char, short or float and stored back
2673 in the parmlist. In this case, describe the parm
2674 with the variable's declared type, and adjust the address
2675 if the least significant bytes (which we are using) are not
2677 if (BYTES_BIG_ENDIAN && TREE_TYPE (parm) != DECL_ARG_TYPE (parm))
2678 offset_in_bytes += (GET_MODE_SIZE (TYPE_MODE (DECL_ARG_TYPE (parm)))
2679 - GET_MODE_SIZE (GET_MODE (DECL_RTL (parm))));
2681 return offset_in_bytes;
2685 encode_method_prototype (method_decl, func_decl)
2692 HOST_WIDE_INT max_parm_end = 0;
2696 /* ONEWAY and BYCOPY, for remote object are the only method qualifiers. */
2697 encode_type_qualifiers (TREE_PURPOSE (TREE_TYPE (method_decl)));
2700 encode_type (TREE_TYPE (TREE_TYPE (func_decl)),
2701 obstack_object_size (&util_obstack),
2702 OBJC_ENCODE_INLINE_DEFS);
2705 for (parms = DECL_ARGUMENTS (func_decl); parms;
2706 parms = TREE_CHAIN (parms))
2708 HOST_WIDE_INT parm_end = (forwarding_offset (parms)
2709 + int_size_in_bytes (TREE_TYPE (parms)));
2711 if (!offset_is_register && max_parm_end < parm_end)
2712 max_parm_end = parm_end;
2715 stack_size = max_parm_end - OBJC_FORWARDING_MIN_OFFSET;
2717 sprintf (buf, "%d", stack_size);
2718 obstack_grow (&util_obstack, buf, strlen (buf));
2720 user_args = METHOD_SEL_ARGS (method_decl);
2722 /* Argument types. */
2723 for (parms = DECL_ARGUMENTS (func_decl), i = 0; parms;
2724 parms = TREE_CHAIN (parms), i++)
2726 /* Process argument qualifiers for user supplied arguments. */
2729 encode_type_qualifiers (TREE_PURPOSE (TREE_TYPE (user_args)));
2730 user_args = TREE_CHAIN (user_args);
2734 encode_type (TREE_TYPE (parms),
2735 obstack_object_size (&util_obstack),
2736 OBJC_ENCODE_INLINE_DEFS);
2738 /* Compute offset. */
2739 sprintf (buf, "%d", forwarding_offset (parms));
2741 /* Indicate register. */
2742 if (offset_is_register)
2743 obstack_1grow (&util_obstack, '+');
2745 obstack_grow (&util_obstack, buf, strlen (buf));
2748 obstack_1grow (&util_obstack, '\0');
2749 result = get_identifier (obstack_finish (&util_obstack));
2750 obstack_free (&util_obstack, util_firstobj);
2755 generate_descriptor_table (type, name, size, list, proto)
2762 tree sc_spec, decl_specs, decl, initlist;
2764 sc_spec = tree_cons (NULL_TREE, ridpointers[(int) RID_STATIC], NULL_TREE);
2765 decl_specs = tree_cons (NULL_TREE, type, sc_spec);
2767 decl = start_decl (synth_id_with_class_suffix (name, proto),
2768 decl_specs, 1, NULL_TREE);
2769 DECL_CONTEXT (decl) = NULL_TREE;
2771 initlist = build_tree_list (NULL_TREE, build_int_2 (size, 0));
2772 initlist = tree_cons (NULL_TREE, list, initlist);
2774 finish_decl (decl, build_constructor (type, nreverse (initlist)),
2781 generate_method_descriptors (protocol)
2784 tree initlist, chain, method_list_template;
2785 tree cast, variable_length_type;
2788 if (!objc_method_prototype_template)
2789 objc_method_prototype_template = build_method_prototype_template ();
2791 cast = build_tree_list (build_tree_list (NULL_TREE, xref_tag (RECORD_TYPE,
2792 get_identifier (UTAG_METHOD_PROTOTYPE_LIST))),
2794 variable_length_type = groktypename (cast);
2796 chain = PROTOCOL_CLS_METHODS (protocol);
2799 size = list_length (chain);
2801 method_list_template
2802 = build_method_prototype_list_template (objc_method_prototype_template,
2806 = build_descriptor_table_initializer (objc_method_prototype_template,
2809 UOBJC_CLASS_METHODS_decl
2810 = generate_descriptor_table (method_list_template,
2811 "_OBJC_PROTOCOL_CLASS_METHODS",
2812 size, initlist, protocol);
2813 TREE_TYPE (UOBJC_CLASS_METHODS_decl) = variable_length_type;
2816 UOBJC_CLASS_METHODS_decl = 0;
2818 chain = PROTOCOL_NST_METHODS (protocol);
2821 size = list_length (chain);
2823 method_list_template
2824 = build_method_prototype_list_template (objc_method_prototype_template,
2827 = build_descriptor_table_initializer (objc_method_prototype_template,
2830 UOBJC_INSTANCE_METHODS_decl
2831 = generate_descriptor_table (method_list_template,
2832 "_OBJC_PROTOCOL_INSTANCE_METHODS",
2833 size, initlist, protocol);
2834 TREE_TYPE (UOBJC_INSTANCE_METHODS_decl) = variable_length_type;
2837 UOBJC_INSTANCE_METHODS_decl = 0;
2840 /* Generate a temporary FUNCTION_DECL node to be used in
2841 hack_method_prototype below. */
2844 build_tmp_function_decl ()
2846 tree decl_specs, expr_decl, parms;
2850 /* struct objc_object *objc_xxx (id, SEL, ...); */
2852 decl_specs = build_tree_list (NULL_TREE, objc_object_reference);
2853 push_parm_decl (build_tree_list
2854 (build_tree_list (decl_specs,
2855 build1 (INDIRECT_REF, NULL_TREE,
2859 decl_specs = build_tree_list (NULL_TREE, xref_tag (RECORD_TYPE,
2860 get_identifier (TAG_SELECTOR)));
2861 expr_decl = build1 (INDIRECT_REF, NULL_TREE, NULL_TREE);
2863 push_parm_decl (build_tree_list (build_tree_list (decl_specs, expr_decl),
2865 parms = get_parm_info (0);
2868 decl_specs = build_tree_list (NULL_TREE, objc_object_reference);
2869 sprintf (buffer, "__objc_tmp_%x", xxx++);
2870 expr_decl = build_nt (CALL_EXPR, get_identifier (buffer), parms, NULL_TREE);
2871 expr_decl = build1 (INDIRECT_REF, NULL_TREE, expr_decl);
2873 return define_decl (expr_decl, decl_specs);
2876 /* Generate the prototypes for protocol methods. This is used to
2877 generate method encodings for these.
2879 NST_METHODS is the method to generate a _DECL node for TMP_DECL is
2880 a decl node to be used. This is also where the return value is
2884 hack_method_prototype (nst_methods, tmp_decl)
2891 /* Hack to avoid problem with static typing of self arg. */
2892 TREE_SET_CODE (nst_methods, CLASS_METHOD_DECL);
2893 start_method_def (nst_methods);
2894 TREE_SET_CODE (nst_methods, INSTANCE_METHOD_DECL);
2896 if (METHOD_ADD_ARGS (nst_methods) == objc_ellipsis_node)
2897 parms = get_parm_info (0); /* we have a `, ...' */
2899 parms = get_parm_info (1); /* place a `void_at_end' */
2901 poplevel (0, 0, 0); /* Must be called BEFORE start_function. */
2903 /* Usually called from store_parm_decls -> init_function_start. */
2905 DECL_ARGUMENTS (tmp_decl) = TREE_PURPOSE (parms);
2907 if (current_function_decl)
2909 current_function_decl = tmp_decl;
2912 /* Code taken from start_function. */
2913 tree restype = TREE_TYPE (TREE_TYPE (tmp_decl));
2914 /* Promote the value to int before returning it. */
2915 if (TREE_CODE (restype) == INTEGER_TYPE
2916 && TYPE_PRECISION (restype) < TYPE_PRECISION (integer_type_node))
2917 restype = integer_type_node;
2918 DECL_RESULT (tmp_decl) = build_decl (RESULT_DECL, 0, restype);
2921 for (parm = DECL_ARGUMENTS (tmp_decl); parm; parm = TREE_CHAIN (parm))
2922 DECL_CONTEXT (parm) = tmp_decl;
2924 init_function_start (tmp_decl, "objc-act", 0);
2926 /* Typically called from expand_function_start for function definitions. */
2927 assign_parms (tmp_decl);
2929 /* install return type */
2930 TREE_TYPE (TREE_TYPE (tmp_decl)) = groktypename (TREE_TYPE (nst_methods));
2932 current_function_decl = NULL;
2936 generate_protocol_references (plist)
2941 /* Forward declare protocols referenced. */
2942 for (lproto = plist; lproto; lproto = TREE_CHAIN (lproto))
2944 tree proto = TREE_VALUE (lproto);
2946 if (TREE_CODE (proto) == PROTOCOL_INTERFACE_TYPE
2947 && PROTOCOL_NAME (proto))
2949 if (! PROTOCOL_FORWARD_DECL (proto))
2950 build_protocol_reference (proto);
2952 if (PROTOCOL_LIST (proto))
2953 generate_protocol_references (PROTOCOL_LIST (proto));
2959 generate_protocols ()
2961 tree p, tmp_decl, encoding;
2962 tree sc_spec, decl_specs, decl;
2963 tree initlist, protocol_name_expr, refs_decl, refs_expr;
2966 tmp_decl = build_tmp_function_decl ();
2968 if (! objc_protocol_template)
2969 objc_protocol_template = build_protocol_template ();
2971 /* If a protocol was directly referenced, pull in indirect references. */
2972 for (p = protocol_chain; p; p = TREE_CHAIN (p))
2973 if (PROTOCOL_FORWARD_DECL (p) && PROTOCOL_LIST (p))
2974 generate_protocol_references (PROTOCOL_LIST (p));
2976 for (p = protocol_chain; p; p = TREE_CHAIN (p))
2978 tree nst_methods = PROTOCOL_NST_METHODS (p);
2979 tree cls_methods = PROTOCOL_CLS_METHODS (p);
2981 /* If protocol wasn't referenced, don't generate any code. */
2982 if (! PROTOCOL_FORWARD_DECL (p))
2985 /* Make sure we link in the Protocol class. */
2986 add_class_reference (get_identifier (PROTOCOL_OBJECT_CLASS_NAME));
2990 if (! METHOD_ENCODING (nst_methods))
2992 hack_method_prototype (nst_methods, tmp_decl);
2993 encoding = encode_method_prototype (nst_methods, tmp_decl);
2994 METHOD_ENCODING (nst_methods) = encoding;
2996 nst_methods = TREE_CHAIN (nst_methods);
3001 if (! METHOD_ENCODING (cls_methods))
3003 hack_method_prototype (cls_methods, tmp_decl);
3004 encoding = encode_method_prototype (cls_methods, tmp_decl);
3005 METHOD_ENCODING (cls_methods) = encoding;
3008 cls_methods = TREE_CHAIN (cls_methods);
3010 generate_method_descriptors (p);
3012 if (PROTOCOL_LIST (p))
3013 refs_decl = generate_protocol_list (p);
3017 /* static struct objc_protocol _OBJC_PROTOCOL_<mumble>; */
3019 sc_spec = tree_cons (NULL_TREE, ridpointers[(int) RID_STATIC],
3021 decl_specs = tree_cons (NULL_TREE, objc_protocol_template, sc_spec);
3023 decl = start_decl (synth_id_with_class_suffix ("_OBJC_PROTOCOL", p),
3024 decl_specs, 1, NULL_TREE);
3026 DECL_CONTEXT (decl) = NULL_TREE;
3028 protocol_name_expr = add_objc_string (PROTOCOL_NAME (p), class_names);
3034 (build_tree_list (build_tree_list (NULL_TREE,
3035 objc_protocol_template),
3036 build1 (INDIRECT_REF, NULL_TREE,
3037 build1 (INDIRECT_REF, NULL_TREE,
3040 refs_expr = build_unary_op (ADDR_EXPR, refs_decl, 0);
3041 TREE_TYPE (refs_expr) = cast_type2;
3044 refs_expr = build_int_2 (0, 0);
3046 /* UOBJC_INSTANCE_METHODS_decl/UOBJC_CLASS_METHODS_decl are set
3047 by generate_method_descriptors, which is called above. */
3048 initlist = build_protocol_initializer (TREE_TYPE (decl),
3049 protocol_name_expr, refs_expr,
3050 UOBJC_INSTANCE_METHODS_decl,
3051 UOBJC_CLASS_METHODS_decl);
3052 finish_decl (decl, initlist, NULL_TREE);
3054 /* Mark the decl as used to avoid "defined but not used" warning. */
3055 TREE_USED (decl) = 1;
3060 build_protocol_initializer (type, protocol_name, protocol_list,
3061 instance_methods, class_methods)
3065 tree instance_methods;
3068 tree initlist = NULL_TREE, expr;
3071 cast_type = groktypename
3073 (build_tree_list (NULL_TREE,
3074 xref_tag (RECORD_TYPE,
3075 get_identifier (UTAG_CLASS))),
3076 build1 (INDIRECT_REF, NULL_TREE, NULL_TREE)));
3078 /* Filling the "isa" in with one allows the runtime system to
3079 detect that the version change...should remove before final release. */
3081 expr = build_int_2 (PROTOCOL_VERSION, 0);
3082 TREE_TYPE (expr) = cast_type;
3083 initlist = tree_cons (NULL_TREE, expr, initlist);
3084 initlist = tree_cons (NULL_TREE, protocol_name, initlist);
3085 initlist = tree_cons (NULL_TREE, protocol_list, initlist);
3087 if (!instance_methods)
3088 initlist = tree_cons (NULL_TREE, build_int_2 (0, 0), initlist);
3091 expr = build_unary_op (ADDR_EXPR, instance_methods, 0);
3092 initlist = tree_cons (NULL_TREE, expr, initlist);
3096 initlist = tree_cons (NULL_TREE, build_int_2 (0, 0), initlist);
3099 expr = build_unary_op (ADDR_EXPR, class_methods, 0);
3100 initlist = tree_cons (NULL_TREE, expr, initlist);
3103 return build_constructor (type, nreverse (initlist));
3106 /* struct objc_category {
3107 char *category_name;
3109 struct objc_method_list *instance_methods;
3110 struct objc_method_list *class_methods;
3111 struct objc_protocol_list *protocols;
3115 build_category_template ()
3117 tree decl_specs, field_decl, field_decl_chain;
3119 objc_category_template = start_struct (RECORD_TYPE,
3120 get_identifier (UTAG_CATEGORY));
3121 /* char *category_name; */
3123 decl_specs = build_tree_list (NULL_TREE, ridpointers[(int) RID_CHAR]);
3125 = build1 (INDIRECT_REF, NULL_TREE, get_identifier ("category_name"));
3127 = grokfield (input_filename, lineno, field_decl, decl_specs, NULL_TREE);
3128 field_decl_chain = field_decl;
3130 /* char *class_name; */
3132 decl_specs = build_tree_list (NULL_TREE, ridpointers[(int) RID_CHAR]);
3133 field_decl = build1 (INDIRECT_REF, NULL_TREE, get_identifier ("class_name"));
3135 = grokfield (input_filename, lineno, field_decl, decl_specs, NULL_TREE);
3136 chainon (field_decl_chain, field_decl);
3138 /* struct objc_method_list *instance_methods; */
3140 decl_specs = build_tree_list (NULL_TREE,
3141 xref_tag (RECORD_TYPE,
3142 get_identifier (UTAG_METHOD_LIST)));
3144 = build1 (INDIRECT_REF, NULL_TREE, get_identifier ("instance_methods"));
3146 = grokfield (input_filename, lineno, field_decl, decl_specs, NULL_TREE);
3147 chainon (field_decl_chain, field_decl);
3149 /* struct objc_method_list *class_methods; */
3151 decl_specs = build_tree_list (NULL_TREE,
3152 xref_tag (RECORD_TYPE,
3153 get_identifier (UTAG_METHOD_LIST)));
3155 = build1 (INDIRECT_REF, NULL_TREE, get_identifier ("class_methods"));
3157 = grokfield (input_filename, lineno, field_decl, decl_specs, NULL_TREE);
3158 chainon (field_decl_chain, field_decl);
3160 /* struct objc_protocol **protocol_list; */
3162 decl_specs = build_tree_list (NULL_TREE,
3163 xref_tag (RECORD_TYPE,
3164 get_identifier (UTAG_PROTOCOL)));
3166 = build1 (INDIRECT_REF, NULL_TREE, get_identifier ("protocol_list"));
3167 field_decl = build1 (INDIRECT_REF, NULL_TREE, field_decl);
3169 = grokfield (input_filename, lineno, field_decl, decl_specs, NULL_TREE);
3170 chainon (field_decl_chain, field_decl);
3172 finish_struct (objc_category_template, field_decl_chain, NULL_TREE);
3175 /* struct objc_selector {
3181 build_selector_template ()
3184 tree decl_specs, field_decl, field_decl_chain;
3186 objc_selector_template
3187 = start_struct (RECORD_TYPE, get_identifier (UTAG_SELECTOR));
3191 decl_specs = build_tree_list (NULL_TREE, ridpointers[(int) RID_VOID]);
3192 field_decl = build1 (INDIRECT_REF, NULL_TREE, get_identifier ("sel_id"));
3194 = grokfield (input_filename, lineno, field_decl, decl_specs, NULL_TREE);
3195 field_decl_chain = field_decl;
3197 /* char *sel_type; */
3199 decl_specs = build_tree_list (NULL_TREE, ridpointers[(int) RID_CHAR]);
3200 field_decl = build1 (INDIRECT_REF, NULL_TREE, get_identifier ("sel_type"));
3202 = grokfield (input_filename, lineno, field_decl, decl_specs, NULL_TREE);
3203 chainon (field_decl_chain, field_decl);
3205 finish_struct (objc_selector_template, field_decl_chain, NULL_TREE);
3208 /* struct objc_class {
3209 struct objc_class *isa;
3210 struct objc_class *super_class;
3215 struct objc_ivar_list *ivars;
3216 struct objc_method_list *methods;
3217 if (flag_next_runtime)
3218 struct objc_cache *cache;
3220 struct sarray *dtable;
3221 struct objc_class *subclass_list;
3222 struct objc_class *sibling_class;
3224 struct objc_protocol_list *protocols;
3225 void *gc_object_type;
3229 build_class_template ()
3231 tree decl_specs, field_decl, field_decl_chain;
3234 = start_struct (RECORD_TYPE, get_identifier (UTAG_CLASS));
3236 /* struct objc_class *isa; */
3238 decl_specs = build_tree_list (NULL_TREE, objc_class_template);
3239 field_decl = build1 (INDIRECT_REF, NULL_TREE, get_identifier ("isa"));
3241 = grokfield (input_filename, lineno, field_decl, decl_specs, NULL_TREE);
3242 field_decl_chain = field_decl;
3244 /* struct objc_class *super_class; */
3246 decl_specs = build_tree_list (NULL_TREE, objc_class_template);
3248 = build1 (INDIRECT_REF, NULL_TREE, get_identifier ("super_class"));
3250 = grokfield (input_filename, lineno, field_decl, decl_specs, NULL_TREE);
3251 chainon (field_decl_chain, field_decl);
3255 decl_specs = build_tree_list (NULL_TREE, ridpointers[(int) RID_CHAR]);
3256 field_decl = build1 (INDIRECT_REF, NULL_TREE, get_identifier ("name"));
3258 = grokfield (input_filename, lineno, field_decl, decl_specs, NULL_TREE);
3259 chainon (field_decl_chain, field_decl);
3263 decl_specs = build_tree_list (NULL_TREE, ridpointers[(int) RID_LONG]);
3264 field_decl = get_identifier ("version");
3266 = grokfield (input_filename, lineno, field_decl, decl_specs, NULL_TREE);
3267 chainon (field_decl_chain, field_decl);
3271 decl_specs = build_tree_list (NULL_TREE, ridpointers[(int) RID_LONG]);
3272 field_decl = get_identifier ("info");
3274 = grokfield (input_filename, lineno, field_decl, decl_specs, NULL_TREE);
3275 chainon (field_decl_chain, field_decl);
3277 /* long instance_size; */
3279 decl_specs = build_tree_list (NULL_TREE, ridpointers[(int) RID_LONG]);
3280 field_decl = get_identifier ("instance_size");
3282 = grokfield (input_filename, lineno, field_decl, decl_specs, NULL_TREE);
3283 chainon (field_decl_chain, field_decl);
3285 /* struct objc_ivar_list *ivars; */
3287 decl_specs = build_tree_list (NULL_TREE,
3288 xref_tag (RECORD_TYPE,
3289 get_identifier (UTAG_IVAR_LIST)));
3290 field_decl = build1 (INDIRECT_REF, NULL_TREE, get_identifier ("ivars"));
3292 = grokfield (input_filename, lineno, field_decl, decl_specs, NULL_TREE);
3293 chainon (field_decl_chain, field_decl);
3295 /* struct objc_method_list *methods; */
3297 decl_specs = build_tree_list (NULL_TREE,
3298 xref_tag (RECORD_TYPE,
3299 get_identifier (UTAG_METHOD_LIST)));
3300 field_decl = build1 (INDIRECT_REF, NULL_TREE, get_identifier ("methods"));
3302 = grokfield (input_filename, lineno, field_decl, decl_specs, NULL_TREE);
3303 chainon (field_decl_chain, field_decl);
3305 if (flag_next_runtime)
3307 /* struct objc_cache *cache; */
3309 decl_specs = build_tree_list (NULL_TREE,
3310 xref_tag (RECORD_TYPE,
3311 get_identifier ("objc_cache")));
3312 field_decl = build1 (INDIRECT_REF, NULL_TREE, get_identifier ("cache"));
3313 field_decl = grokfield (input_filename, lineno, field_decl,
3314 decl_specs, NULL_TREE);
3315 chainon (field_decl_chain, field_decl);
3319 /* struct sarray *dtable; */
3321 decl_specs = build_tree_list (NULL_TREE,
3322 xref_tag (RECORD_TYPE,
3323 get_identifier ("sarray")));
3324 field_decl = build1 (INDIRECT_REF, NULL_TREE, get_identifier ("dtable"));
3325 field_decl = grokfield (input_filename, lineno, field_decl,
3326 decl_specs, NULL_TREE);
3327 chainon (field_decl_chain, field_decl);
3329 /* struct objc_class *subclass_list; */
3331 decl_specs = build_tree_list (NULL_TREE, objc_class_template);
3333 = build1 (INDIRECT_REF, NULL_TREE, get_identifier ("subclass_list"));
3334 field_decl = grokfield (input_filename, lineno, field_decl,
3335 decl_specs, NULL_TREE);
3336 chainon (field_decl_chain, field_decl);
3338 /* struct objc_class *sibling_class; */
3340 decl_specs = build_tree_list (NULL_TREE, objc_class_template);
3342 = build1 (INDIRECT_REF, NULL_TREE, get_identifier ("sibling_class"));
3343 field_decl = grokfield (input_filename, lineno, field_decl,
3344 decl_specs, NULL_TREE);
3345 chainon (field_decl_chain, field_decl);
3348 /* struct objc_protocol **protocol_list; */
3350 decl_specs = build_tree_list (NULL_TREE,
3351 xref_tag (RECORD_TYPE,
3352 get_identifier (UTAG_PROTOCOL)));
3354 = build1 (INDIRECT_REF, NULL_TREE, get_identifier ("protocol_list"));
3356 = build1 (INDIRECT_REF, NULL_TREE, field_decl);
3357 field_decl = grokfield (input_filename, lineno, field_decl,
3358 decl_specs, NULL_TREE);
3359 chainon (field_decl_chain, field_decl);
3363 decl_specs = build_tree_list (NULL_TREE, ridpointers[(int) RID_VOID]);
3364 field_decl = build1 (INDIRECT_REF, NULL_TREE, get_identifier ("sel_id"));
3366 = grokfield (input_filename, lineno, field_decl, decl_specs, NULL_TREE);
3367 chainon (field_decl_chain, field_decl);
3369 /* void *gc_object_type; */
3371 decl_specs = build_tree_list (NULL_TREE, ridpointers[(int) RID_VOID]);
3372 field_decl = build1 (INDIRECT_REF, NULL_TREE, get_identifier ("gc_object_type"));
3374 = grokfield (input_filename, lineno, field_decl, decl_specs, NULL_TREE);
3375 chainon (field_decl_chain, field_decl);
3377 finish_struct (objc_class_template, field_decl_chain, NULL_TREE);
3380 /* Generate appropriate forward declarations for an implementation. */
3383 synth_forward_declarations ()
3385 tree sc_spec, decl_specs, an_id;
3387 /* extern struct objc_class _OBJC_CLASS_<my_name>; */
3389 an_id = synth_id_with_class_suffix ("_OBJC_CLASS", objc_implementation_context);
3391 sc_spec = build_tree_list (NULL_TREE, ridpointers[(int) RID_EXTERN]);
3392 decl_specs = tree_cons (NULL_TREE, objc_class_template, sc_spec);
3393 UOBJC_CLASS_decl = define_decl (an_id, decl_specs);
3394 TREE_USED (UOBJC_CLASS_decl) = 1;
3395 DECL_ARTIFICIAL (UOBJC_CLASS_decl) = 1;
3397 /* extern struct objc_class _OBJC_METACLASS_<my_name>; */
3399 an_id = synth_id_with_class_suffix ("_OBJC_METACLASS",
3400 objc_implementation_context);
3402 UOBJC_METACLASS_decl = define_decl (an_id, decl_specs);
3403 TREE_USED (UOBJC_METACLASS_decl) = 1;
3404 DECL_ARTIFICIAL(UOBJC_METACLASS_decl) = 1;
3406 /* Pre-build the following entities - for speed/convenience. */
3408 an_id = get_identifier ("super_class");
3409 ucls_super_ref = build_component_ref (UOBJC_CLASS_decl, an_id);
3410 uucls_super_ref = build_component_ref (UOBJC_METACLASS_decl, an_id);
3414 error_with_ivar (message, decl, rawdecl)
3415 const char *message;
3419 diagnostic_count_diagnostic (global_dc, DK_ERROR);
3421 diagnostic_report_current_function (global_dc);
3423 error_with_file_and_line (DECL_SOURCE_FILE (decl),
3424 DECL_SOURCE_LINE (decl),
3426 message, gen_declaration (rawdecl, errbuf));
3430 #define USERTYPE(t) \
3431 (TREE_CODE (t) == RECORD_TYPE || TREE_CODE (t) == UNION_TYPE \
3432 || TREE_CODE (t) == ENUMERAL_TYPE)
3435 check_ivars (inter, imp)
3439 tree intdecls = CLASS_IVARS (inter);
3440 tree impdecls = CLASS_IVARS (imp);
3441 tree rawintdecls = CLASS_RAW_IVARS (inter);
3442 tree rawimpdecls = CLASS_RAW_IVARS (imp);
3448 if (intdecls == 0 && impdecls == 0)
3450 if (intdecls == 0 || impdecls == 0)
3452 error ("inconsistent instance variable specification");
3456 t1 = TREE_TYPE (intdecls); t2 = TREE_TYPE (impdecls);
3458 if (!comptypes (t1, t2))
3460 if (DECL_NAME (intdecls) == DECL_NAME (impdecls))
3462 error_with_ivar ("conflicting instance variable type",
3463 impdecls, rawimpdecls);
3464 error_with_ivar ("previous declaration of",
3465 intdecls, rawintdecls);
3467 else /* both the type and the name don't match */
3469 error ("inconsistent instance variable specification");
3474 else if (DECL_NAME (intdecls) != DECL_NAME (impdecls))
3476 error_with_ivar ("conflicting instance variable name",
3477 impdecls, rawimpdecls);
3478 error_with_ivar ("previous declaration of",
3479 intdecls, rawintdecls);
3482 intdecls = TREE_CHAIN (intdecls);
3483 impdecls = TREE_CHAIN (impdecls);
3484 rawintdecls = TREE_CHAIN (rawintdecls);
3485 rawimpdecls = TREE_CHAIN (rawimpdecls);
3489 /* Set super_type to the data type node for struct objc_super *,
3490 first defining struct objc_super itself.
3491 This needs to be done just once per compilation. */
3494 build_super_template ()
3496 tree record, decl_specs, field_decl, field_decl_chain;
3498 record = start_struct (RECORD_TYPE, get_identifier (UTAG_SUPER));
3500 /* struct objc_object *self; */
3502 decl_specs = build_tree_list (NULL_TREE, objc_object_reference);
3503 field_decl = get_identifier ("self");
3504 field_decl = build1 (INDIRECT_REF, NULL_TREE, field_decl);
3505 field_decl = grokfield (input_filename, lineno,
3506 field_decl, decl_specs, NULL_TREE);
3507 field_decl_chain = field_decl;
3509 /* struct objc_class *class; */
3511 decl_specs = get_identifier (UTAG_CLASS);
3512 decl_specs = build_tree_list (NULL_TREE, xref_tag (RECORD_TYPE, decl_specs));
3513 field_decl = build1 (INDIRECT_REF, NULL_TREE, get_identifier ("class"));
3515 field_decl = grokfield (input_filename, lineno,
3516 field_decl, decl_specs, NULL_TREE);
3517 chainon (field_decl_chain, field_decl);
3519 finish_struct (record, field_decl_chain, NULL_TREE);
3521 /* `struct objc_super *' */
3522 super_type = groktypename (build_tree_list (build_tree_list (NULL_TREE,
3524 build1 (INDIRECT_REF,
3525 NULL_TREE, NULL_TREE)));
3529 /* struct objc_ivar {
3536 build_ivar_template ()
3538 tree objc_ivar_id, objc_ivar_record;
3539 tree decl_specs, field_decl, field_decl_chain;
3541 objc_ivar_id = get_identifier (UTAG_IVAR);
3542 objc_ivar_record = start_struct (RECORD_TYPE, objc_ivar_id);
3544 /* char *ivar_name; */
3546 decl_specs = build_tree_list (NULL_TREE, ridpointers[(int) RID_CHAR]);
3547 field_decl = build1 (INDIRECT_REF, NULL_TREE, get_identifier ("ivar_name"));
3549 field_decl = grokfield (input_filename, lineno, field_decl,
3550 decl_specs, NULL_TREE);
3551 field_decl_chain = field_decl;
3553 /* char *ivar_type; */
3555 decl_specs = build_tree_list (NULL_TREE, ridpointers[(int) RID_CHAR]);
3556 field_decl = build1 (INDIRECT_REF, NULL_TREE, get_identifier ("ivar_type"));
3558 field_decl = grokfield (input_filename, lineno, field_decl,
3559 decl_specs, NULL_TREE);
3560 chainon (field_decl_chain, field_decl);
3562 /* int ivar_offset; */
3564 decl_specs = build_tree_list (NULL_TREE, ridpointers[(int) RID_INT]);
3565 field_decl = get_identifier ("ivar_offset");
3567 field_decl = grokfield (input_filename, lineno, field_decl,
3568 decl_specs, NULL_TREE);
3569 chainon (field_decl_chain, field_decl);
3571 finish_struct (objc_ivar_record, field_decl_chain, NULL_TREE);
3573 return objc_ivar_record;
3578 struct objc_ivar ivar_list[ivar_count];
3582 build_ivar_list_template (list_type, size)
3586 tree objc_ivar_list_record;
3587 tree decl_specs, field_decl, field_decl_chain;
3589 objc_ivar_list_record = start_struct (RECORD_TYPE, NULL_TREE);
3591 /* int ivar_count; */
3593 decl_specs = build_tree_list (NULL_TREE, ridpointers[(int) RID_INT]);
3594 field_decl = get_identifier ("ivar_count");
3596 field_decl = grokfield (input_filename, lineno, field_decl,
3597 decl_specs, NULL_TREE);
3598 field_decl_chain = field_decl;
3600 /* struct objc_ivar ivar_list[]; */
3602 decl_specs = build_tree_list (NULL_TREE, list_type);
3603 field_decl = build_nt (ARRAY_REF, get_identifier ("ivar_list"),
3604 build_int_2 (size, 0));
3606 field_decl = grokfield (input_filename, lineno,
3607 field_decl, decl_specs, NULL_TREE);
3608 chainon (field_decl_chain, field_decl);
3610 finish_struct (objc_ivar_list_record, field_decl_chain, NULL_TREE);
3612 return objc_ivar_list_record;
3618 struct objc_method method_list[method_count];
3622 build_method_list_template (list_type, size)
3626 tree objc_ivar_list_record;
3627 tree decl_specs, field_decl, field_decl_chain;
3629 objc_ivar_list_record = start_struct (RECORD_TYPE, NULL_TREE);
3631 /* int method_next; */
3636 xref_tag (RECORD_TYPE,
3637 get_identifier (UTAG_METHOD_PROTOTYPE_LIST)));
3639 = build1 (INDIRECT_REF, NULL_TREE, get_identifier ("method_next"));
3640 field_decl = grokfield (input_filename, lineno, field_decl,
3641 decl_specs, NULL_TREE);
3642 field_decl_chain = field_decl;
3644 /* int method_count; */
3646 decl_specs = build_tree_list (NULL_TREE, ridpointers[(int) RID_INT]);
3647 field_decl = get_identifier ("method_count");
3649 field_decl = grokfield (input_filename, lineno,
3650 field_decl, decl_specs, NULL_TREE);
3651 chainon (field_decl_chain, field_decl);
3653 /* struct objc_method method_list[]; */
3655 decl_specs = build_tree_list (NULL_TREE, list_type);
3656 field_decl = build_nt (ARRAY_REF, get_identifier ("method_list"),
3657 build_int_2 (size, 0));
3659 field_decl = grokfield (input_filename, lineno,
3660 field_decl, decl_specs, NULL_TREE);
3661 chainon (field_decl_chain, field_decl);
3663 finish_struct (objc_ivar_list_record, field_decl_chain, NULL_TREE);
3665 return objc_ivar_list_record;
3669 build_ivar_list_initializer (type, field_decl)
3673 tree initlist = NULL_TREE;
3677 tree ivar = NULL_TREE;
3680 if (DECL_NAME (field_decl))
3681 ivar = tree_cons (NULL_TREE,
3682 add_objc_string (DECL_NAME (field_decl),
3686 /* Unnamed bit-field ivar (yuck). */
3687 ivar = tree_cons (NULL_TREE, build_int_2 (0, 0), ivar);
3690 encode_field_decl (field_decl,
3691 obstack_object_size (&util_obstack),
3692 OBJC_ENCODE_DONT_INLINE_DEFS);
3694 /* Null terminate string. */
3695 obstack_1grow (&util_obstack, 0);
3699 add_objc_string (get_identifier (obstack_finish (&util_obstack)),
3702 obstack_free (&util_obstack, util_firstobj);
3705 ivar = tree_cons (NULL_TREE, byte_position (field_decl), ivar);
3706 initlist = tree_cons (NULL_TREE,
3707 build_constructor (type, nreverse (ivar)),
3710 field_decl = TREE_CHAIN (field_decl);
3714 return build_constructor (build_array_type (type, 0), nreverse (initlist));
3718 generate_ivars_list (type, name, size, list)
3724 tree sc_spec, decl_specs, decl, initlist;
3726 sc_spec = tree_cons (NULL_TREE, ridpointers[(int) RID_STATIC], NULL_TREE);
3727 decl_specs = tree_cons (NULL_TREE, type, sc_spec);
3729 decl = start_decl (synth_id_with_class_suffix (name, objc_implementation_context),
3730 decl_specs, 1, NULL_TREE);
3732 initlist = build_tree_list (NULL_TREE, build_int_2 (size, 0));
3733 initlist = tree_cons (NULL_TREE, list, initlist);
3736 build_constructor (TREE_TYPE (decl), nreverse (initlist)),
3743 generate_ivar_lists ()
3745 tree initlist, ivar_list_template, chain;
3746 tree cast, variable_length_type;
3749 generating_instance_variables = 1;
3751 if (!objc_ivar_template)
3752 objc_ivar_template = build_ivar_template ();
3756 (build_tree_list (NULL_TREE, xref_tag (RECORD_TYPE,
3757 get_identifier (UTAG_IVAR_LIST))),
3759 variable_length_type = groktypename (cast);
3761 /* Only generate class variables for the root of the inheritance
3762 hierarchy since these will be the same for every class. */
3764 if (CLASS_SUPER_NAME (implementation_template) == NULL_TREE
3765 && (chain = TYPE_FIELDS (objc_class_template)))
3767 size = list_length (chain);
3769 ivar_list_template = build_ivar_list_template (objc_ivar_template, size);
3770 initlist = build_ivar_list_initializer (objc_ivar_template, chain);
3772 UOBJC_CLASS_VARIABLES_decl
3773 = generate_ivars_list (ivar_list_template, "_OBJC_CLASS_VARIABLES",
3775 TREE_TYPE (UOBJC_CLASS_VARIABLES_decl) = variable_length_type;
3778 UOBJC_CLASS_VARIABLES_decl = 0;
3780 chain = CLASS_IVARS (implementation_template);
3783 size = list_length (chain);
3784 ivar_list_template = build_ivar_list_template (objc_ivar_template, size);
3785 initlist = build_ivar_list_initializer (objc_ivar_template, chain);
3787 UOBJC_INSTANCE_VARIABLES_decl
3788 = generate_ivars_list (ivar_list_template, "_OBJC_INSTANCE_VARIABLES",
3790 TREE_TYPE (UOBJC_INSTANCE_VARIABLES_decl) = variable_length_type;
3793 UOBJC_INSTANCE_VARIABLES_decl = 0;
3795 generating_instance_variables = 0;
3799 build_dispatch_table_initializer (type, entries)
3803 tree initlist = NULL_TREE;
3807 tree elemlist = NULL_TREE;
3809 elemlist = tree_cons (NULL_TREE,
3810 build_selector (METHOD_SEL_NAME (entries)),
3813 /* Generate the method encoding if we don't have one already. */
3814 if (! METHOD_ENCODING (entries))
3815 METHOD_ENCODING (entries) =
3816 encode_method_def (METHOD_DEFINITION (entries));
3818 elemlist = tree_cons (NULL_TREE,
3819 add_objc_string (METHOD_ENCODING (entries),
3823 elemlist = tree_cons (NULL_TREE,
3824 build_unary_op (ADDR_EXPR,
3825 METHOD_DEFINITION (entries), 1),
3828 initlist = tree_cons (NULL_TREE,
3829 build_constructor (type, nreverse (elemlist)),
3832 entries = TREE_CHAIN (entries);
3836 return build_constructor (build_array_type (type, 0), nreverse (initlist));
3839 /* To accomplish method prototyping without generating all kinds of
3840 inane warnings, the definition of the dispatch table entries were
3843 struct objc_method { SEL _cmd; ...; id (*_imp)(); };
3845 struct objc_method { SEL _cmd; ...; void *_imp; }; */
3848 build_method_template ()
3851 tree decl_specs, field_decl, field_decl_chain;
3853 _SLT_record = start_struct (RECORD_TYPE, get_identifier (UTAG_METHOD));
3855 /* struct objc_selector *_cmd; */
3856 decl_specs = tree_cons (NULL_TREE,
3857 xref_tag (RECORD_TYPE,
3858 get_identifier (TAG_SELECTOR)),
3860 field_decl = build1 (INDIRECT_REF, NULL_TREE, get_identifier ("_cmd"));
3862 field_decl = grokfield (input_filename, lineno, field_decl,
3863 decl_specs, NULL_TREE);
3864 field_decl_chain = field_decl;
3866 decl_specs = tree_cons (NULL_TREE, ridpointers[(int) RID_CHAR], NULL_TREE);
3867 field_decl = build1 (INDIRECT_REF, NULL_TREE,
3868 get_identifier ("method_types"));
3869 field_decl = grokfield (input_filename, lineno, field_decl,
3870 decl_specs, NULL_TREE);
3871 chainon (field_decl_chain, field_decl);
3875 decl_specs = tree_cons (NULL_TREE, ridpointers[(int) RID_VOID], NULL_TREE);
3876 field_decl = build1 (INDIRECT_REF, NULL_TREE, get_identifier ("_imp"));
3877 field_decl = grokfield (input_filename, lineno, field_decl,
3878 decl_specs, NULL_TREE);
3879 chainon (field_decl_chain, field_decl);
3881 finish_struct (_SLT_record, field_decl_chain, NULL_TREE);
3888 generate_dispatch_table (type, name, size, list)
3894 tree sc_spec, decl_specs, decl, initlist;
3896 sc_spec = tree_cons (NULL_TREE, ridpointers[(int) RID_STATIC], NULL_TREE);
3897 decl_specs = tree_cons (NULL_TREE, type, sc_spec);
3899 decl = start_decl (synth_id_with_class_suffix (name, objc_implementation_context),
3900 decl_specs, 1, NULL_TREE);
3902 initlist = build_tree_list (NULL_TREE, build_int_2 (0, 0));
3903 initlist = tree_cons (NULL_TREE, build_int_2 (size, 0), initlist);
3904 initlist = tree_cons (NULL_TREE, list, initlist);
3907 build_constructor (TREE_TYPE (decl), nreverse (initlist)),
3914 generate_dispatch_tables ()
3916 tree initlist, chain, method_list_template;
3917 tree cast, variable_length_type;
3920 if (!objc_method_template)
3921 objc_method_template = build_method_template ();
3925 (build_tree_list (NULL_TREE,
3926 xref_tag (RECORD_TYPE,
3927 get_identifier (UTAG_METHOD_LIST))),
3930 variable_length_type = groktypename (cast);
3932 chain = CLASS_CLS_METHODS (objc_implementation_context);
3935 size = list_length (chain);
3937 method_list_template
3938 = build_method_list_template (objc_method_template, size);
3940 = build_dispatch_table_initializer (objc_method_template, chain);
3942 UOBJC_CLASS_METHODS_decl
3943 = generate_dispatch_table (method_list_template,
3944 ((TREE_CODE (objc_implementation_context)
3945 == CLASS_IMPLEMENTATION_TYPE)
3946 ? "_OBJC_CLASS_METHODS"
3947 : "_OBJC_CATEGORY_CLASS_METHODS"),
3949 TREE_TYPE (UOBJC_CLASS_METHODS_decl) = variable_length_type;
3952 UOBJC_CLASS_METHODS_decl = 0;
3954 chain = CLASS_NST_METHODS (objc_implementation_context);
3957 size = list_length (chain);
3959 method_list_template
3960 = build_method_list_template (objc_method_template, size);
3962 = build_dispatch_table_initializer (objc_method_template, chain);
3964 if (TREE_CODE (objc_implementation_context) == CLASS_IMPLEMENTATION_TYPE)
3965 UOBJC_INSTANCE_METHODS_decl
3966 = generate_dispatch_table (method_list_template,
3967 "_OBJC_INSTANCE_METHODS",
3970 /* We have a category. */
3971 UOBJC_INSTANCE_METHODS_decl
3972 = generate_dispatch_table (method_list_template,
3973 "_OBJC_CATEGORY_INSTANCE_METHODS",
3975 TREE_TYPE (UOBJC_INSTANCE_METHODS_decl) = variable_length_type;
3978 UOBJC_INSTANCE_METHODS_decl = 0;
3982 generate_protocol_list (i_or_p)
3985 tree initlist, decl_specs, sc_spec;
3986 tree refs_decl, expr_decl, lproto, e, plist;
3990 if (TREE_CODE (i_or_p) == CLASS_INTERFACE_TYPE
3991 || TREE_CODE (i_or_p) == CATEGORY_INTERFACE_TYPE)
3992 plist = CLASS_PROTOCOL_LIST (i_or_p);
3993 else if (TREE_CODE (i_or_p) == PROTOCOL_INTERFACE_TYPE)
3994 plist = PROTOCOL_LIST (i_or_p);
3998 cast_type = groktypename
4000 (build_tree_list (NULL_TREE,
4001 xref_tag (RECORD_TYPE,
4002 get_identifier (UTAG_PROTOCOL))),
4003 build1 (INDIRECT_REF, NULL_TREE, NULL_TREE)));
4006 for (lproto = plist; lproto; lproto = TREE_CHAIN (lproto))
4007 if (TREE_CODE (TREE_VALUE (lproto)) == PROTOCOL_INTERFACE_TYPE
4008 && PROTOCOL_FORWARD_DECL (TREE_VALUE (lproto)))
4011 /* Build initializer. */
4012 initlist = tree_cons (NULL_TREE, build_int_2 (0, 0), NULL_TREE);
4014 e = build_int_2 (size, 0);
4015 TREE_TYPE (e) = cast_type;
4016 initlist = tree_cons (NULL_TREE, e, initlist);
4018 for (lproto = plist; lproto; lproto = TREE_CHAIN (lproto))
4020 tree pval = TREE_VALUE (lproto);
4022 if (TREE_CODE (pval) == PROTOCOL_INTERFACE_TYPE
4023 && PROTOCOL_FORWARD_DECL (pval))
4025 e = build_unary_op (ADDR_EXPR, PROTOCOL_FORWARD_DECL (pval), 0);
4026 initlist = tree_cons (NULL_TREE, e, initlist);
4030 /* static struct objc_protocol *refs[n]; */
4032 sc_spec = tree_cons (NULL_TREE, ridpointers[(int) RID_STATIC], NULL_TREE);
4033 decl_specs = tree_cons (NULL_TREE, xref_tag (RECORD_TYPE,
4034 get_identifier (UTAG_PROTOCOL)),
4037 if (TREE_CODE (i_or_p) == PROTOCOL_INTERFACE_TYPE)
4038 expr_decl = build_nt (ARRAY_REF,
4039 synth_id_with_class_suffix ("_OBJC_PROTOCOL_REFS",
4041 build_int_2 (size + 2, 0));
4042 else if (TREE_CODE (i_or_p) == CLASS_INTERFACE_TYPE)
4043 expr_decl = build_nt (ARRAY_REF,
4044 synth_id_with_class_suffix ("_OBJC_CLASS_PROTOCOLS",
4046 build_int_2 (size + 2, 0));
4047 else if (TREE_CODE (i_or_p) == CATEGORY_INTERFACE_TYPE)
4049 = build_nt (ARRAY_REF,
4050 synth_id_with_class_suffix ("_OBJC_CATEGORY_PROTOCOLS",
4052 build_int_2 (size + 2, 0));
4056 expr_decl = build1 (INDIRECT_REF, NULL_TREE, expr_decl);
4058 refs_decl = start_decl (expr_decl, decl_specs, 1, NULL_TREE);
4059 DECL_CONTEXT (refs_decl) = NULL_TREE;
4061 finish_decl (refs_decl, build_constructor (TREE_TYPE (refs_decl),
4062 nreverse (initlist)),
4069 build_category_initializer (type, cat_name, class_name,
4070 instance_methods, class_methods, protocol_list)
4074 tree instance_methods;
4078 tree initlist = NULL_TREE, expr;
4080 initlist = tree_cons (NULL_TREE, cat_name, initlist);
4081 initlist = tree_cons (NULL_TREE, class_name, initlist);
4083 if (!instance_methods)
4084 initlist = tree_cons (NULL_TREE, build_int_2 (0, 0), initlist);
4087 expr = build_unary_op (ADDR_EXPR, instance_methods, 0);
4088 initlist = tree_cons (NULL_TREE, expr, initlist);
4091 initlist = tree_cons (NULL_TREE, build_int_2 (0, 0), initlist);
4094 expr = build_unary_op (ADDR_EXPR, class_methods, 0);
4095 initlist = tree_cons (NULL_TREE, expr, initlist);
4098 /* protocol_list = */
4100 initlist = tree_cons (NULL_TREE, build_int_2 (0, 0), initlist);
4103 tree cast_type2 = groktypename
4105 (build_tree_list (NULL_TREE,
4106 xref_tag (RECORD_TYPE,
4107 get_identifier (UTAG_PROTOCOL))),
4108 build1 (INDIRECT_REF, NULL_TREE,
4109 build1 (INDIRECT_REF, NULL_TREE, NULL_TREE))));
4111 expr = build_unary_op (ADDR_EXPR, protocol_list, 0);
4112 TREE_TYPE (expr) = cast_type2;
4113 initlist = tree_cons (NULL_TREE, expr, initlist);
4116 return build_constructor (type, nreverse (initlist));
4119 /* struct objc_class {
4120 struct objc_class *isa;
4121 struct objc_class *super_class;
4126 struct objc_ivar_list *ivars;
4127 struct objc_method_list *methods;
4128 if (flag_next_runtime)
4129 struct objc_cache *cache;
4131 struct sarray *dtable;
4132 struct objc_class *subclass_list;
4133 struct objc_class *sibling_class;
4135 struct objc_protocol_list *protocols;
4136 void *gc_object_type;
4140 build_shared_structure_initializer (type, isa, super, name, size, status,
4141 dispatch_table, ivar_list, protocol_list)
4148 tree dispatch_table;
4152 tree initlist = NULL_TREE, expr;
4155 initlist = tree_cons (NULL_TREE, isa, initlist);
4158 initlist = tree_cons (NULL_TREE, super, initlist);
4161 initlist = tree_cons (NULL_TREE, default_conversion (name), initlist);
4164 initlist = tree_cons (NULL_TREE, build_int_2 (0, 0), initlist);
4167 initlist = tree_cons (NULL_TREE, build_int_2 (status, 0), initlist);
4169 /* instance_size = */
4170 initlist = tree_cons (NULL_TREE, size, initlist);
4172 /* objc_ivar_list = */
4174 initlist = tree_cons (NULL_TREE, build_int_2 (0, 0), initlist);
4177 expr = build_unary_op (ADDR_EXPR, ivar_list, 0);
4178 initlist = tree_cons (NULL_TREE, expr, initlist);
4181 /* objc_method_list = */
4182 if (!dispatch_table)
4183 initlist = tree_cons (NULL_TREE, build_int_2 (0, 0), initlist);
4186 expr = build_unary_op (ADDR_EXPR, dispatch_table, 0);
4187 initlist = tree_cons (NULL_TREE, expr, initlist);
4190 if (flag_next_runtime)
4191 /* method_cache = */
4192 initlist = tree_cons (NULL_TREE, build_int_2 (0, 0), initlist);
4196 initlist = tree_cons (NULL_TREE, build_int_2 (0, 0), initlist);
4198 /* subclass_list = */
4199 initlist = tree_cons (NULL_TREE, build_int_2 (0, 0), initlist);
4201 /* sibling_class = */
4202 initlist = tree_cons (NULL_TREE, build_int_2 (0, 0), initlist);
4205 /* protocol_list = */
4206 if (! protocol_list)
4207 initlist = tree_cons (NULL_TREE, build_int_2 (0, 0), initlist);
4213 (build_tree_list (NULL_TREE,
4214 xref_tag (RECORD_TYPE,
4215 get_identifier (UTAG_PROTOCOL))),
4216 build1 (INDIRECT_REF, NULL_TREE,
4217 build1 (INDIRECT_REF, NULL_TREE, NULL_TREE))));
4219 expr = build_unary_op (ADDR_EXPR, protocol_list, 0);
4220 TREE_TYPE (expr) = cast_type2;
4221 initlist = tree_cons (NULL_TREE, expr, initlist);
4224 /* gc_object_type = NULL */
4225 initlist = tree_cons (NULL_TREE, build_int_2 (0, 0), initlist);
4227 return build_constructor (type, nreverse (initlist));
4230 /* static struct objc_category _OBJC_CATEGORY_<name> = { ... }; */
4233 generate_category (cat)
4236 tree sc_spec, decl_specs, decl;
4237 tree initlist, cat_name_expr, class_name_expr;
4238 tree protocol_decl, category;
4240 add_class_reference (CLASS_NAME (cat));
4241 cat_name_expr = add_objc_string (CLASS_SUPER_NAME (cat), class_names);
4243 class_name_expr = add_objc_string (CLASS_NAME (cat), class_names);
4245 category = CLASS_CATEGORY_LIST (implementation_template);
4247 /* find the category interface from the class it is associated with */
4250 if (CLASS_SUPER_NAME (cat) == CLASS_SUPER_NAME (category))
4252 category = CLASS_CATEGORY_LIST (category);
4255 if (category && CLASS_PROTOCOL_LIST (category))
4257 generate_protocol_references (CLASS_PROTOCOL_LIST (category));
4258 protocol_decl = generate_protocol_list (category);
4263 sc_spec = tree_cons (NULL_TREE, ridpointers[(int) RID_STATIC], NULL_TREE);
4264 decl_specs = tree_cons (NULL_TREE, objc_category_template, sc_spec);
4266 decl = start_decl (synth_id_with_class_suffix ("_OBJC_CATEGORY",
4267 objc_implementation_context),
4268 decl_specs, 1, NULL_TREE);
4270 initlist = build_category_initializer (TREE_TYPE (decl),
4271 cat_name_expr, class_name_expr,
4272 UOBJC_INSTANCE_METHODS_decl,
4273 UOBJC_CLASS_METHODS_decl,
4276 TREE_USED (decl) = 1;
4277 finish_decl (decl, initlist, NULL_TREE);
4280 /* static struct objc_class _OBJC_METACLASS_Foo={ ... };
4281 static struct objc_class _OBJC_CLASS_Foo={ ... }; */
4284 generate_shared_structures ()
4286 tree sc_spec, decl_specs, decl;
4287 tree name_expr, super_expr, root_expr;
4288 tree my_root_id = NULL_TREE, my_super_id = NULL_TREE;
4289 tree cast_type, initlist, protocol_decl;
4291 my_super_id = CLASS_SUPER_NAME (implementation_template);
4294 add_class_reference (my_super_id);
4296 /* Compute "my_root_id" - this is required for code generation.
4297 the "isa" for all meta class structures points to the root of
4298 the inheritance hierarchy (e.g. "__Object")... */
4299 my_root_id = my_super_id;
4302 tree my_root_int = lookup_interface (my_root_id);
4304 if (my_root_int && CLASS_SUPER_NAME (my_root_int))
4305 my_root_id = CLASS_SUPER_NAME (my_root_int);
4312 /* No super class. */
4313 my_root_id = CLASS_NAME (implementation_template);
4316 = groktypename (build_tree_list (build_tree_list (NULL_TREE,
4317 objc_class_template),
4318 build1 (INDIRECT_REF,
4319 NULL_TREE, NULL_TREE)));
4321 name_expr = add_objc_string (CLASS_NAME (implementation_template),
4324 /* Install class `isa' and `super' pointers at runtime. */
4327 super_expr = add_objc_string (my_super_id, class_names);
4328 super_expr = build_c_cast (cast_type, super_expr); /* cast! */
4331 super_expr = build_int_2 (0, 0);
4333 root_expr = add_objc_string (my_root_id, class_names);
4334 root_expr = build_c_cast (cast_type, root_expr); /* cast! */
4336 if (CLASS_PROTOCOL_LIST (implementation_template))
4338 generate_protocol_references
4339 (CLASS_PROTOCOL_LIST (implementation_template));
4340 protocol_decl = generate_protocol_list (implementation_template);
4345 /* static struct objc_class _OBJC_METACLASS_Foo = { ... }; */
4347 sc_spec = build_tree_list (NULL_TREE, ridpointers[(int) RID_STATIC]);
4348 decl_specs = tree_cons (NULL_TREE, objc_class_template, sc_spec);
4350 decl = start_decl (DECL_NAME (UOBJC_METACLASS_decl), decl_specs, 1,
4354 = build_shared_structure_initializer
4356 root_expr, super_expr, name_expr,
4357 convert (integer_type_node, TYPE_SIZE_UNIT (objc_class_template)),
4359 UOBJC_CLASS_METHODS_decl,
4360 UOBJC_CLASS_VARIABLES_decl,
4363 finish_decl (decl, initlist, NULL_TREE);
4365 /* static struct objc_class _OBJC_CLASS_Foo={ ... }; */
4367 decl = start_decl (DECL_NAME (UOBJC_CLASS_decl), decl_specs, 1,
4371 = build_shared_structure_initializer
4373 build_unary_op (ADDR_EXPR, UOBJC_METACLASS_decl, 0),
4374 super_expr, name_expr,
4375 convert (integer_type_node,
4376 TYPE_SIZE_UNIT (CLASS_STATIC_TEMPLATE
4377 (implementation_template))),
4379 UOBJC_INSTANCE_METHODS_decl,
4380 UOBJC_INSTANCE_VARIABLES_decl,
4383 finish_decl (decl, initlist, NULL_TREE);
4387 synth_id_with_class_suffix (preamble, ctxt)
4388 const char *preamble;
4392 if (TREE_CODE (ctxt) == CLASS_IMPLEMENTATION_TYPE
4393 || TREE_CODE (ctxt) == CLASS_INTERFACE_TYPE)
4395 const char *const class_name
4396 = IDENTIFIER_POINTER (CLASS_NAME (objc_implementation_context));
4397 string = (char *) alloca (strlen (preamble) + strlen (class_name) + 3);
4398 sprintf (string, "%s_%s", preamble,
4399 IDENTIFIER_POINTER (CLASS_NAME (ctxt)));
4401 else if (TREE_CODE (ctxt) == CATEGORY_IMPLEMENTATION_TYPE
4402 || TREE_CODE (ctxt) == CATEGORY_INTERFACE_TYPE)
4404 /* We have a category. */
4405 const char *const class_name
4406 = IDENTIFIER_POINTER (CLASS_NAME (objc_implementation_context));
4407 const char *const class_super_name
4408 = IDENTIFIER_POINTER (CLASS_SUPER_NAME (objc_implementation_context));
4409 string = (char *) alloca (strlen (preamble)
4410 + strlen (class_name)
4411 + strlen (class_super_name)
4413 sprintf (string, "%s_%s_%s", preamble, class_name, class_super_name);
4415 else if (TREE_CODE (ctxt) == PROTOCOL_INTERFACE_TYPE)
4417 const char *protocol_name = IDENTIFIER_POINTER (PROTOCOL_NAME (ctxt));
4419 = (char *) alloca (strlen (preamble) + strlen (protocol_name) + 3);
4420 sprintf (string, "%s_%s", preamble, protocol_name);
4425 return get_identifier (string);
4429 is_objc_type_qualifier (node)
4432 return (TREE_CODE (node) == IDENTIFIER_NODE
4433 && (node == ridpointers [(int) RID_CONST]
4434 || node == ridpointers [(int) RID_VOLATILE]
4435 || node == ridpointers [(int) RID_IN]
4436 || node == ridpointers [(int) RID_OUT]
4437 || node == ridpointers [(int) RID_INOUT]
4438 || node == ridpointers [(int) RID_BYCOPY]
4439 || node == ridpointers [(int) RID_BYREF]
4440 || node == ridpointers [(int) RID_ONEWAY]));
4443 /* If type is empty or only type qualifiers are present, add default
4444 type of id (otherwise grokdeclarator will default to int). */
4447 adjust_type_for_id_default (type)
4450 tree declspecs, chain;
4453 return build_tree_list (build_tree_list (NULL_TREE, objc_object_reference),
4454 build1 (INDIRECT_REF, NULL_TREE, NULL_TREE));
4456 declspecs = TREE_PURPOSE (type);
4458 /* Determine if a typespec is present. */
4459 for (chain = declspecs;
4461 chain = TREE_CHAIN (chain))
4463 if (!is_objc_type_qualifier (TREE_VALUE (chain)))
4467 return build_tree_list (tree_cons (NULL_TREE, objc_object_reference,
4469 build1 (INDIRECT_REF, NULL_TREE, NULL_TREE));
4474 selector ':' '(' typename ')' identifier
4477 Transform an Objective-C keyword argument into
4478 the C equivalent parameter declarator.
4480 In: key_name, an "identifier_node" (optional).
4481 arg_type, a "tree_list" (optional).
4482 arg_name, an "identifier_node".
4484 Note: It would be really nice to strongly type the preceding
4485 arguments in the function prototype; however, then I
4486 could not use the "accessor" macros defined in "tree.h".
4488 Out: an instance of "keyword_decl". */
4491 build_keyword_decl (key_name, arg_type, arg_name)
4498 /* If no type is specified, default to "id". */
4499 arg_type = adjust_type_for_id_default (arg_type);
4501 keyword_decl = make_node (KEYWORD_DECL);
4503 TREE_TYPE (keyword_decl) = arg_type;
4504 KEYWORD_ARG_NAME (keyword_decl) = arg_name;
4505 KEYWORD_KEY_NAME (keyword_decl) = key_name;
4507 return keyword_decl;
4510 /* Given a chain of keyword_decl's, synthesize the full keyword selector. */
4513 build_keyword_selector (selector)
4517 tree key_chain, key_name;
4520 /* Scan the selector to see how much space we'll need. */
4521 for (key_chain = selector; key_chain; key_chain = TREE_CHAIN (key_chain))
4523 if (TREE_CODE (selector) == KEYWORD_DECL)
4524 key_name = KEYWORD_KEY_NAME (key_chain);
4525 else if (TREE_CODE (selector) == TREE_LIST)
4526 key_name = TREE_PURPOSE (key_chain);
4531 len += IDENTIFIER_LENGTH (key_name) + 1;
4533 /* Just a ':' arg. */
4537 buf = (char *) alloca (len + 1);
4538 /* Start the buffer out as an empty string. */
4541 for (key_chain = selector; key_chain; key_chain = TREE_CHAIN (key_chain))
4543 if (TREE_CODE (selector) == KEYWORD_DECL)
4544 key_name = KEYWORD_KEY_NAME (key_chain);
4545 else if (TREE_CODE (selector) == TREE_LIST)
4546 key_name = TREE_PURPOSE (key_chain);
4551 strcat (buf, IDENTIFIER_POINTER (key_name));
4555 return get_identifier (buf);
4558 /* Used for declarations and definitions. */
4561 build_method_decl (code, ret_type, selector, add_args)
4562 enum tree_code code;
4569 /* If no type is specified, default to "id". */
4570 ret_type = adjust_type_for_id_default (ret_type);
4572 method_decl = make_node (code);
4573 TREE_TYPE (method_decl) = ret_type;
4575 /* If we have a keyword selector, create an identifier_node that
4576 represents the full selector name (`:' included)... */
4577 if (TREE_CODE (selector) == KEYWORD_DECL)
4579 METHOD_SEL_NAME (method_decl) = build_keyword_selector (selector);
4580 METHOD_SEL_ARGS (method_decl) = selector;
4581 METHOD_ADD_ARGS (method_decl) = add_args;
4585 METHOD_SEL_NAME (method_decl) = selector;
4586 METHOD_SEL_ARGS (method_decl) = NULL_TREE;
4587 METHOD_ADD_ARGS (method_decl) = NULL_TREE;
4593 #define METHOD_DEF 0
4594 #define METHOD_REF 1
4596 /* Used by `build_objc_method_call' and `comp_method_types'. Return
4597 an argument list for method METH. CONTEXT is either METHOD_DEF or
4598 METHOD_REF, saying whether we are trying to define a method or call
4599 one. SUPERFLAG says this is for a send to super; this makes a
4600 difference for the NeXT calling sequence in which the lookup and
4601 the method call are done together. */
4604 get_arg_type_list (meth, context, superflag)
4611 /* Receiver type. */
4612 if (flag_next_runtime && superflag)
4613 arglist = build_tree_list (NULL_TREE, super_type);
4614 else if (context == METHOD_DEF)
4615 arglist = build_tree_list (NULL_TREE, TREE_TYPE (self_decl));
4617 arglist = build_tree_list (NULL_TREE, id_type);
4619 /* Selector type - will eventually change to `int'. */
4620 chainon (arglist, build_tree_list (NULL_TREE, selector_type));
4622 /* Build a list of argument types. */
4623 for (akey = METHOD_SEL_ARGS (meth); akey; akey = TREE_CHAIN (akey))
4625 tree arg_decl = groktypename_in_parm_context (TREE_TYPE (akey));
4626 chainon (arglist, build_tree_list (NULL_TREE, TREE_TYPE (arg_decl)));
4629 if (METHOD_ADD_ARGS (meth) == objc_ellipsis_node)
4630 /* We have a `, ...' immediately following the selector,
4631 finalize the arglist...simulate get_parm_info (0). */
4633 else if (METHOD_ADD_ARGS (meth))
4635 /* we have a variable length selector */
4636 tree add_arg_list = TREE_CHAIN (METHOD_ADD_ARGS (meth));
4637 chainon (arglist, add_arg_list);
4640 /* finalize the arglist...simulate get_parm_info (1) */
4641 chainon (arglist, build_tree_list (NULL_TREE, void_type_node));
4647 check_duplicates (hsh)
4650 tree meth = NULL_TREE;
4658 /* We have two methods with the same name and different types. */
4660 char type = (TREE_CODE (meth) == INSTANCE_METHOD_DECL) ? '-' : '+';
4662 warning ("multiple declarations for method `%s'",
4663 IDENTIFIER_POINTER (METHOD_SEL_NAME (meth)));
4665 warn_with_method ("using", type, meth);
4666 for (loop = hsh->list; loop; loop = loop->next)
4667 warn_with_method ("also found", type, loop->value);
4673 /* If RECEIVER is a class reference, return the identifier node for
4674 the referenced class. RECEIVER is created by get_class_reference,
4675 so we check the exact form created depending on which runtimes are
4679 receiver_is_class_object (receiver)
4682 tree chain, exp, arg;
4684 /* The receiver is 'self' in the context of a class method. */
4685 if (objc_method_context
4686 && receiver == self_decl
4687 && TREE_CODE (objc_method_context) == CLASS_METHOD_DECL)
4689 return CLASS_NAME (objc_implementation_context);
4692 if (flag_next_runtime)
4694 /* The receiver is a variable created by
4695 build_class_reference_decl. */
4696 if (TREE_CODE (receiver) == VAR_DECL
4697 && TREE_TYPE (receiver) == objc_class_type)
4698 /* Look up the identifier. */
4699 for (chain = cls_ref_chain; chain; chain = TREE_CHAIN (chain))
4700 if (TREE_PURPOSE (chain) == receiver)
4701 return TREE_VALUE (chain);
4705 /* The receiver is a function call that returns an id. Check if
4706 it is a call to objc_getClass, if so, pick up the class name. */
4707 if (TREE_CODE (receiver) == CALL_EXPR
4708 && (exp = TREE_OPERAND (receiver, 0))
4709 && TREE_CODE (exp) == ADDR_EXPR
4710 && (exp = TREE_OPERAND (exp, 0))
4711 && TREE_CODE (exp) == FUNCTION_DECL
4712 && exp == objc_get_class_decl
4713 /* We have a call to objc_getClass! */
4714 && (arg = TREE_OPERAND (receiver, 1))
4715 && TREE_CODE (arg) == TREE_LIST
4716 && (arg = TREE_VALUE (arg)))
4719 if (TREE_CODE (arg) == ADDR_EXPR
4720 && (arg = TREE_OPERAND (arg, 0))
4721 && TREE_CODE (arg) == STRING_CST)
4722 /* Finally, we have the class name. */
4723 return get_identifier (TREE_STRING_POINTER (arg));
4729 /* If we are currently building a message expr, this holds
4730 the identifier of the selector of the message. This is
4731 used when printing warnings about argument mismatches. */
4733 static tree building_objc_message_expr = 0;
4736 maybe_building_objc_message_expr ()
4738 return building_objc_message_expr;
4741 /* Construct an expression for sending a message.
4742 MESS has the object to send to in TREE_PURPOSE
4743 and the argument list (including selector) in TREE_VALUE.
4745 (*(<abstract_decl>(*)())_msg)(receiver, selTransTbl[n], ...);
4746 (*(<abstract_decl>(*)())_msgSuper)(receiver, selTransTbl[n], ...); */
4749 build_message_expr (mess)
4752 tree receiver = TREE_PURPOSE (mess);
4754 tree args = TREE_VALUE (mess);
4755 tree method_params = NULL_TREE;
4757 if (TREE_CODE (receiver) == ERROR_MARK)
4758 return error_mark_node;
4760 /* Obtain the full selector name. */
4761 if (TREE_CODE (args) == IDENTIFIER_NODE)
4762 /* A unary selector. */
4764 else if (TREE_CODE (args) == TREE_LIST)
4765 sel_name = build_keyword_selector (args);
4769 /* Build the parameter list to give to the method. */
4770 if (TREE_CODE (args) == TREE_LIST)
4772 tree chain = args, prev = NULL_TREE;
4774 /* We have a keyword selector--check for comma expressions. */
4777 tree element = TREE_VALUE (chain);
4779 /* We have a comma expression, must collapse... */
4780 if (TREE_CODE (element) == TREE_LIST)
4783 TREE_CHAIN (prev) = element;
4788 chain = TREE_CHAIN (chain);
4790 method_params = args;
4793 return finish_message_expr (receiver, sel_name, method_params);
4796 /* The 'finish_message_expr' routine is called from within
4797 'build_message_expr' for non-template functions. In the case of
4798 C++ template functions, it is called from 'build_expr_from_tree'
4799 (in decl2.c) after RECEIVER and METHOD_PARAMS have been expanded. */
4802 finish_message_expr (receiver, sel_name, method_params)
4803 tree receiver, sel_name, method_params;
4805 tree method_prototype = NULL_TREE, class_ident = NULL_TREE;
4806 tree selector, self_object, retval;
4807 int statically_typed = 0, statically_allocated = 0;
4809 /* Determine receiver type. */
4810 tree rtype = TREE_TYPE (receiver);
4811 int super = IS_SUPER (rtype);
4815 if (TREE_STATIC_TEMPLATE (rtype))
4816 statically_allocated = 1;
4817 else if (TREE_CODE (rtype) == POINTER_TYPE
4818 && TREE_STATIC_TEMPLATE (TREE_TYPE (rtype)))
4819 statically_typed = 1;
4820 else if ((flag_next_runtime
4822 && (class_ident = receiver_is_class_object (receiver)))
4824 else if (! IS_ID (rtype)
4825 /* Allow any type that matches objc_class_type. */
4826 && ! comptypes (rtype, objc_class_type))
4828 warning ("invalid receiver type `%s'",
4829 gen_declaration (rtype, errbuf));
4831 if (statically_allocated)
4832 receiver = build_unary_op (ADDR_EXPR, receiver, 0);
4834 /* Don't evaluate the receiver twice. */
4835 receiver = save_expr (receiver);
4836 self_object = receiver;
4839 /* If sending to `super', use current self as the object. */
4840 self_object = self_decl;
4842 /* Determine operation return type. */
4848 if (CLASS_SUPER_NAME (implementation_template))
4851 = lookup_interface (CLASS_SUPER_NAME (implementation_template));
4853 if (TREE_CODE (objc_method_context) == INSTANCE_METHOD_DECL)
4854 method_prototype = lookup_instance_method_static (iface, sel_name);
4856 method_prototype = lookup_class_method_static (iface, sel_name);
4858 if (iface && !method_prototype)
4859 warning ("`%s' does not respond to `%s'",
4860 IDENTIFIER_POINTER (CLASS_SUPER_NAME (implementation_template)),
4861 IDENTIFIER_POINTER (sel_name));
4865 error ("no super class declared in interface for `%s'",
4866 IDENTIFIER_POINTER (CLASS_NAME (implementation_template)));
4867 return error_mark_node;
4871 else if (statically_allocated)
4873 tree ctype = TREE_TYPE (rtype);
4874 tree iface = lookup_interface (TYPE_NAME (rtype));
4877 method_prototype = lookup_instance_method_static (iface, sel_name);
4879 if (! method_prototype && TYPE_PROTOCOL_LIST (ctype))
4881 = lookup_method_in_protocol_list (TYPE_PROTOCOL_LIST (ctype),
4884 if (!method_prototype)
4885 warning ("`%s' does not respond to `%s'",
4886 IDENTIFIER_POINTER (TYPE_NAME (rtype)),
4887 IDENTIFIER_POINTER (sel_name));
4889 else if (statically_typed)
4891 tree ctype = TREE_TYPE (rtype);
4893 /* `self' is now statically_typed. All methods should be visible
4894 within the context of the implementation. */
4895 if (objc_implementation_context
4896 && CLASS_NAME (objc_implementation_context) == TYPE_NAME (ctype))
4899 = lookup_instance_method_static (implementation_template,
4902 if (! method_prototype && TYPE_PROTOCOL_LIST (ctype))
4904 = lookup_method_in_protocol_list (TYPE_PROTOCOL_LIST (ctype),
4907 if (! method_prototype
4908 && implementation_template != objc_implementation_context)
4909 /* The method is not published in the interface. Check
4912 = lookup_method (CLASS_NST_METHODS (objc_implementation_context),
4919 if ((iface = lookup_interface (TYPE_NAME (ctype))))
4920 method_prototype = lookup_instance_method_static (iface, sel_name);
4922 if (! method_prototype)
4924 tree protocol_list = TYPE_PROTOCOL_LIST (ctype);
4927 = lookup_method_in_protocol_list (protocol_list,
4932 if (!method_prototype)
4933 warning ("`%s' does not respond to `%s'",
4934 IDENTIFIER_POINTER (TYPE_NAME (ctype)),
4935 IDENTIFIER_POINTER (sel_name));
4937 else if (class_ident)
4939 if (objc_implementation_context
4940 && CLASS_NAME (objc_implementation_context) == class_ident)
4943 = lookup_class_method_static (implementation_template, sel_name);
4945 if (!method_prototype
4946 && implementation_template != objc_implementation_context)
4947 /* The method is not published in the interface. Check
4950 = lookup_method (CLASS_CLS_METHODS (objc_implementation_context),
4957 if ((iface = lookup_interface (class_ident)))
4958 method_prototype = lookup_class_method_static (iface, sel_name);
4961 if (!method_prototype)
4963 warning ("cannot find class (factory) method");
4964 warning ("return type for `%s' defaults to id",
4965 IDENTIFIER_POINTER (sel_name));
4968 else if (IS_PROTOCOL_QUALIFIED_ID (rtype))
4970 /* An anonymous object that has been qualified with a protocol. */
4972 tree protocol_list = TYPE_PROTOCOL_LIST (rtype);
4974 method_prototype = lookup_method_in_protocol_list (protocol_list,
4977 if (!method_prototype)
4981 warning ("method `%s' not implemented by protocol",
4982 IDENTIFIER_POINTER (sel_name));
4984 /* Try and find the method signature in the global pools. */
4986 if (!(hsh = hash_lookup (nst_method_hash_list, sel_name)))
4987 hsh = hash_lookup (cls_method_hash_list, sel_name);
4989 if (!(method_prototype = check_duplicates (hsh)))
4990 warning ("return type defaults to id");
4997 /* We think we have an instance...loophole: extern id Object; */
4998 hsh = hash_lookup (nst_method_hash_list, sel_name);
5001 /* For various loopholes */
5002 hsh = hash_lookup (cls_method_hash_list, sel_name);
5004 method_prototype = check_duplicates (hsh);
5005 if (!method_prototype)
5007 warning ("cannot find method");
5008 warning ("return type for `%s' defaults to id",
5009 IDENTIFIER_POINTER (sel_name));
5013 /* Save the selector name for printing error messages. */
5014 building_objc_message_expr = sel_name;
5016 /* Build the parameters list for looking up the method.
5017 These are the object itself and the selector. */
5019 if (flag_typed_selectors)
5020 selector = build_typed_selector_reference (sel_name, method_prototype);
5022 selector = build_selector_reference (sel_name);
5024 retval = build_objc_method_call (super, method_prototype,
5025 receiver, self_object,
5026 selector, method_params);
5028 building_objc_message_expr = 0;
5033 /* Build a tree expression to send OBJECT the operation SELECTOR,
5034 looking up the method on object LOOKUP_OBJECT (often same as OBJECT),
5035 assuming the method has prototype METHOD_PROTOTYPE.
5036 (That is an INSTANCE_METHOD_DECL or CLASS_METHOD_DECL.)
5037 Use METHOD_PARAMS as list of args to pass to the method.
5038 If SUPER_FLAG is nonzero, we look up the superclass's method. */
5041 build_objc_method_call (super_flag, method_prototype, lookup_object, object,
5042 selector, method_params)
5044 tree method_prototype, lookup_object, object, selector, method_params;
5046 tree sender = (super_flag ? umsg_super_decl : umsg_decl);
5047 tree rcv_p = (super_flag
5048 ? build_pointer_type (xref_tag (RECORD_TYPE,
5049 get_identifier (TAG_SUPER)))
5052 if (flag_next_runtime)
5054 if (! method_prototype)
5056 method_params = tree_cons (NULL_TREE, lookup_object,
5057 tree_cons (NULL_TREE, selector,
5059 assemble_external (sender);
5060 return build_function_call (sender, method_params);
5064 /* This is a real kludge, but it is used only for the Next.
5065 Clobber the data type of SENDER temporarily to accept
5066 all the arguments for this operation, and to return
5067 whatever this operation returns. */
5068 tree arglist = NULL_TREE, retval, savarg, savret;
5069 tree ret_type = groktypename (TREE_TYPE (method_prototype));
5071 /* Save the proper contents of SENDER's data type. */
5072 savarg = TYPE_ARG_TYPES (TREE_TYPE (sender));
5073 savret = TREE_TYPE (TREE_TYPE (sender));
5075 /* Install this method's argument types. */
5076 arglist = get_arg_type_list (method_prototype, METHOD_REF,
5078 TYPE_ARG_TYPES (TREE_TYPE (sender)) = arglist;
5080 /* Install this method's return type. */
5081 TREE_TYPE (TREE_TYPE (sender)) = ret_type;
5083 /* Call SENDER with all the parameters. This will do type
5084 checking using the arg types for this method. */
5085 method_params = tree_cons (NULL_TREE, lookup_object,
5086 tree_cons (NULL_TREE, selector,
5088 assemble_external (sender);
5089 retval = build_function_call (sender, method_params);
5091 /* Restore SENDER's return/argument types. */
5092 TYPE_ARG_TYPES (TREE_TYPE (sender)) = savarg;
5093 TREE_TYPE (TREE_TYPE (sender)) = savret;
5099 /* This is the portable way.
5100 First call the lookup function to get a pointer to the method,
5101 then cast the pointer, then call it with the method arguments. */
5104 /* Avoid trouble since we may evaluate each of these twice. */
5105 object = save_expr (object);
5106 selector = save_expr (selector);
5108 lookup_object = build_c_cast (rcv_p, lookup_object);
5110 assemble_external (sender);
5112 = build_function_call (sender,
5113 tree_cons (NULL_TREE, lookup_object,
5114 tree_cons (NULL_TREE, selector,
5117 /* If we have a method prototype, construct the data type this
5118 method needs, and cast what we got from SENDER into a pointer
5120 if (method_prototype)
5122 tree arglist = get_arg_type_list (method_prototype, METHOD_REF,
5124 tree valtype = groktypename (TREE_TYPE (method_prototype));
5125 tree fake_function_type = build_function_type (valtype, arglist);
5126 TREE_TYPE (method) = build_pointer_type (fake_function_type);
5130 = build_pointer_type (build_function_type (ptr_type_node, NULL_TREE));
5132 /* Pass the object to the method. */
5133 assemble_external (method);
5134 return build_function_call (method,
5135 tree_cons (NULL_TREE, object,
5136 tree_cons (NULL_TREE, selector,
5142 build_protocol_reference (p)
5145 tree decl, ident, ptype;
5147 /* extern struct objc_protocol _OBJC_PROTOCOL_<mumble>; */
5149 ident = synth_id_with_class_suffix ("_OBJC_PROTOCOL", p);
5151 = groktypename (build_tree_list (build_tree_list (NULL_TREE,
5152 objc_protocol_template),
5155 if (IDENTIFIER_GLOBAL_VALUE (ident))
5156 decl = IDENTIFIER_GLOBAL_VALUE (ident); /* Set by pushdecl. */
5159 decl = build_decl (VAR_DECL, ident, ptype);
5160 DECL_EXTERNAL (decl) = 1;
5161 TREE_PUBLIC (decl) = 1;
5162 TREE_USED (decl) = 1;
5163 DECL_ARTIFICIAL (decl) = 1;
5165 make_decl_rtl (decl, 0);
5166 pushdecl_top_level (decl);
5169 PROTOCOL_FORWARD_DECL (p) = decl;
5173 build_protocol_expr (protoname)
5177 tree p = lookup_protocol (protoname);
5181 error ("cannot find protocol declaration for `%s'",
5182 IDENTIFIER_POINTER (protoname));
5183 return error_mark_node;
5186 if (!PROTOCOL_FORWARD_DECL (p))
5187 build_protocol_reference (p);
5189 expr = build_unary_op (ADDR_EXPR, PROTOCOL_FORWARD_DECL (p), 0);
5191 TREE_TYPE (expr) = protocol_type;
5197 build_selector_expr (selnamelist)
5202 /* Obtain the full selector name. */
5203 if (TREE_CODE (selnamelist) == IDENTIFIER_NODE)
5204 /* A unary selector. */
5205 selname = selnamelist;
5206 else if (TREE_CODE (selnamelist) == TREE_LIST)
5207 selname = build_keyword_selector (selnamelist);
5211 if (flag_typed_selectors)
5212 return build_typed_selector_reference (selname, 0);
5214 return build_selector_reference (selname);
5218 build_encode_expr (type)
5224 encode_type (type, obstack_object_size (&util_obstack),
5225 OBJC_ENCODE_INLINE_DEFS);
5226 obstack_1grow (&util_obstack, 0); /* null terminate string */
5227 string = obstack_finish (&util_obstack);
5229 /* Synthesize a string that represents the encoded struct/union. */
5230 result = my_build_string (strlen (string) + 1, string);
5231 obstack_free (&util_obstack, util_firstobj);
5236 build_ivar_reference (id)
5239 if (TREE_CODE (objc_method_context) == CLASS_METHOD_DECL)
5241 /* Historically, a class method that produced objects (factory
5242 method) would assign `self' to the instance that it
5243 allocated. This would effectively turn the class method into
5244 an instance method. Following this assignment, the instance
5245 variables could be accessed. That practice, while safe,
5246 violates the simple rule that a class method should not refer
5247 to an instance variable. It's better to catch the cases
5248 where this is done unknowingly than to support the above
5250 warning ("instance variable `%s' accessed in class method",
5251 IDENTIFIER_POINTER (id));
5252 TREE_TYPE (self_decl) = instance_type; /* cast */
5255 return build_component_ref (build_indirect_ref (self_decl, "->"), id);
5258 /* Compute a hash value for a given method SEL_NAME. */
5261 hash_func (sel_name)
5264 const unsigned char *s
5265 = (const unsigned char *)IDENTIFIER_POINTER (sel_name);
5269 h = h * 67 + *s++ - 113;
5276 nst_method_hash_list = (hash *) ggc_calloc (SIZEHASHTABLE, sizeof (hash));
5277 cls_method_hash_list = (hash *) ggc_calloc (SIZEHASHTABLE, sizeof (hash));
5280 /* WARNING!!!! hash_enter is called with a method, and will peek
5281 inside to find its selector! But hash_lookup is given a selector
5282 directly, and looks for the selector that's inside the found
5283 entry's key (method) for comparison. */
5286 hash_enter (hashlist, method)
5291 int slot = hash_func (METHOD_SEL_NAME (method)) % SIZEHASHTABLE;
5293 obj = (hash) ggc_alloc (sizeof (struct hashed_entry));
5295 obj->next = hashlist[slot];
5298 hashlist[slot] = obj; /* append to front */
5302 hash_lookup (hashlist, sel_name)
5308 target = hashlist[hash_func (sel_name) % SIZEHASHTABLE];
5312 if (sel_name == METHOD_SEL_NAME (target->key))
5315 target = target->next;
5321 hash_add_attr (entry, value)
5327 obj = (attr) ggc_alloc (sizeof (struct hashed_attribute));
5328 obj->next = entry->list;
5331 entry->list = obj; /* append to front */
5335 lookup_method (mchain, method)
5341 if (TREE_CODE (method) == IDENTIFIER_NODE)
5344 key = METHOD_SEL_NAME (method);
5348 if (METHOD_SEL_NAME (mchain) == key)
5350 mchain = TREE_CHAIN (mchain);
5356 lookup_instance_method_static (interface, ident)
5360 tree inter = interface;
5361 tree chain = CLASS_NST_METHODS (inter);
5362 tree meth = NULL_TREE;
5366 if ((meth = lookup_method (chain, ident)))
5369 if (CLASS_CATEGORY_LIST (inter))
5371 tree category = CLASS_CATEGORY_LIST (inter);
5372 chain = CLASS_NST_METHODS (category);
5376 if ((meth = lookup_method (chain, ident)))
5379 /* Check for instance methods in protocols in categories. */
5380 if (CLASS_PROTOCOL_LIST (category))
5382 if ((meth = (lookup_method_in_protocol_list
5383 (CLASS_PROTOCOL_LIST (category), ident, 0))))
5387 if ((category = CLASS_CATEGORY_LIST (category)))
5388 chain = CLASS_NST_METHODS (category);
5393 if (CLASS_PROTOCOL_LIST (inter))
5395 if ((meth = (lookup_method_in_protocol_list
5396 (CLASS_PROTOCOL_LIST (inter), ident, 0))))
5400 if ((inter = lookup_interface (CLASS_SUPER_NAME (inter))))
5401 chain = CLASS_NST_METHODS (inter);
5409 lookup_class_method_static (interface, ident)
5413 tree inter = interface;
5414 tree chain = CLASS_CLS_METHODS (inter);
5415 tree meth = NULL_TREE;
5416 tree root_inter = NULL_TREE;
5420 if ((meth = lookup_method (chain, ident)))
5423 if (CLASS_CATEGORY_LIST (inter))
5425 tree category = CLASS_CATEGORY_LIST (inter);
5426 chain = CLASS_CLS_METHODS (category);
5430 if ((meth = lookup_method (chain, ident)))
5433 /* Check for class methods in protocols in categories. */
5434 if (CLASS_PROTOCOL_LIST (category))
5436 if ((meth = (lookup_method_in_protocol_list
5437 (CLASS_PROTOCOL_LIST (category), ident, 1))))
5441 if ((category = CLASS_CATEGORY_LIST (category)))
5442 chain = CLASS_CLS_METHODS (category);
5447 /* Check for class methods in protocols. */
5448 if (CLASS_PROTOCOL_LIST (inter))
5450 if ((meth = (lookup_method_in_protocol_list
5451 (CLASS_PROTOCOL_LIST (inter), ident, 1))))
5456 if ((inter = lookup_interface (CLASS_SUPER_NAME (inter))))
5457 chain = CLASS_CLS_METHODS (inter);
5461 /* If no class (factory) method was found, check if an _instance_
5462 method of the same name exists in the root class. This is what
5463 the Objective-C runtime will do. */
5464 return lookup_instance_method_static (root_inter, ident);
5468 add_class_method (class, method)
5475 if (!(mth = lookup_method (CLASS_CLS_METHODS (class), method)))
5477 /* put method on list in reverse order */
5478 TREE_CHAIN (method) = CLASS_CLS_METHODS (class);
5479 CLASS_CLS_METHODS (class) = method;
5483 if (TREE_CODE (class) == CLASS_IMPLEMENTATION_TYPE)
5484 error ("duplicate definition of class method `%s'",
5485 IDENTIFIER_POINTER (METHOD_SEL_NAME (mth)));
5488 /* Check types; if different, complain. */
5489 if (!comp_proto_with_proto (method, mth))
5490 error ("duplicate declaration of class method `%s'",
5491 IDENTIFIER_POINTER (METHOD_SEL_NAME (mth)));
5495 if (!(hsh = hash_lookup (cls_method_hash_list, METHOD_SEL_NAME (method))))
5497 /* Install on a global chain. */
5498 hash_enter (cls_method_hash_list, method);
5502 /* Check types; if different, add to a list. */
5503 if (!comp_proto_with_proto (method, hsh->key))
5504 hash_add_attr (hsh, method);
5510 add_instance_method (class, method)
5517 if (!(mth = lookup_method (CLASS_NST_METHODS (class), method)))
5519 /* Put method on list in reverse order. */
5520 TREE_CHAIN (method) = CLASS_NST_METHODS (class);
5521 CLASS_NST_METHODS (class) = method;
5525 if (TREE_CODE (class) == CLASS_IMPLEMENTATION_TYPE)
5526 error ("duplicate definition of instance method `%s'",
5527 IDENTIFIER_POINTER (METHOD_SEL_NAME (mth)));
5530 /* Check types; if different, complain. */
5531 if (!comp_proto_with_proto (method, mth))
5532 error ("duplicate declaration of instance method `%s'",
5533 IDENTIFIER_POINTER (METHOD_SEL_NAME (mth)));
5537 if (!(hsh = hash_lookup (nst_method_hash_list, METHOD_SEL_NAME (method))))
5539 /* Install on a global chain. */
5540 hash_enter (nst_method_hash_list, method);
5544 /* Check types; if different, add to a list. */
5545 if (!comp_proto_with_proto (method, hsh->key))
5546 hash_add_attr (hsh, method);
5555 /* Put interfaces on list in reverse order. */
5556 TREE_CHAIN (class) = interface_chain;
5557 interface_chain = class;
5558 return interface_chain;
5562 add_category (class, category)
5566 /* Put categories on list in reverse order. */
5567 tree cat = CLASS_CATEGORY_LIST (class);
5571 if (CLASS_SUPER_NAME (cat) == CLASS_SUPER_NAME (category))
5572 warning ("duplicate interface declaration for category `%s(%s)'",
5573 IDENTIFIER_POINTER (CLASS_NAME (class)),
5574 IDENTIFIER_POINTER (CLASS_SUPER_NAME (category)));
5575 cat = CLASS_CATEGORY_LIST (cat);
5578 CLASS_CATEGORY_LIST (category) = CLASS_CATEGORY_LIST (class);
5579 CLASS_CATEGORY_LIST (class) = category;
5582 /* Called after parsing each instance variable declaration. Necessary to
5583 preserve typedefs and implement public/private...
5585 PUBLIC is 1 for public, 0 for protected, and 2 for private. */
5588 add_instance_variable (class, public, declarator, declspecs, width)
5595 tree field_decl, raw_decl;
5597 raw_decl = build_tree_list (declspecs, declarator);
5599 if (CLASS_RAW_IVARS (class))
5600 chainon (CLASS_RAW_IVARS (class), raw_decl);
5602 CLASS_RAW_IVARS (class) = raw_decl;
5604 field_decl = grokfield (input_filename, lineno,
5605 declarator, declspecs, width);
5607 /* Overload the public attribute, it is not used for FIELD_DECLs. */
5611 TREE_PUBLIC (field_decl) = 0;
5612 TREE_PRIVATE (field_decl) = 0;
5613 TREE_PROTECTED (field_decl) = 1;
5617 TREE_PUBLIC (field_decl) = 1;
5618 TREE_PRIVATE (field_decl) = 0;
5619 TREE_PROTECTED (field_decl) = 0;
5623 TREE_PUBLIC (field_decl) = 0;
5624 TREE_PRIVATE (field_decl) = 1;
5625 TREE_PROTECTED (field_decl) = 0;
5630 if (CLASS_IVARS (class))
5631 chainon (CLASS_IVARS (class), field_decl);
5633 CLASS_IVARS (class) = field_decl;
5639 is_ivar (decl_chain, ident)
5643 for ( ; decl_chain; decl_chain = TREE_CHAIN (decl_chain))
5644 if (DECL_NAME (decl_chain) == ident)
5649 /* True if the ivar is private and we are not in its implementation. */
5655 if (TREE_PRIVATE (decl)
5656 && ! is_ivar (CLASS_IVARS (implementation_template), DECL_NAME (decl)))
5658 error ("instance variable `%s' is declared private",
5659 IDENTIFIER_POINTER (DECL_NAME (decl)));
5666 /* We have an instance variable reference;, check to see if it is public. */
5669 is_public (expr, identifier)
5673 tree basetype = TREE_TYPE (expr);
5674 enum tree_code code = TREE_CODE (basetype);
5677 if (code == RECORD_TYPE)
5679 if (TREE_STATIC_TEMPLATE (basetype))
5681 if (!lookup_interface (TYPE_NAME (basetype)))
5683 error ("cannot find interface declaration for `%s'",
5684 IDENTIFIER_POINTER (TYPE_NAME (basetype)));
5688 if ((decl = is_ivar (TYPE_FIELDS (basetype), identifier)))
5690 if (TREE_PUBLIC (decl))
5693 /* Important difference between the Stepstone translator:
5694 all instance variables should be public within the context
5695 of the implementation. */
5696 if (objc_implementation_context
5697 && (((TREE_CODE (objc_implementation_context)
5698 == CLASS_IMPLEMENTATION_TYPE)
5699 || (TREE_CODE (objc_implementation_context)
5700 == CATEGORY_IMPLEMENTATION_TYPE))
5701 && (CLASS_NAME (objc_implementation_context)
5702 == TYPE_NAME (basetype))))
5703 return ! is_private (decl);
5705 error ("instance variable `%s' is declared %s",
5706 IDENTIFIER_POINTER (identifier),
5707 TREE_PRIVATE (decl) ? "private" : "protected");
5712 else if (objc_implementation_context && (basetype == objc_object_reference))
5714 TREE_TYPE (expr) = uprivate_record;
5715 warning ("static access to object of type `id'");
5722 /* Implement @defs (<classname>) within struct bodies. */
5725 get_class_ivars (interface)
5728 /* Make sure we copy the leaf ivars in case @defs is used in a local
5729 context. Otherwise finish_struct will overwrite the layout info
5730 using temporary storage. */
5731 return build_ivar_chain (interface, 1);
5734 /* Make sure all entries in CHAIN are also in LIST. */
5737 check_methods (chain, list, mtype)
5746 if (!lookup_method (list, chain))
5750 if (TREE_CODE (objc_implementation_context)
5751 == CLASS_IMPLEMENTATION_TYPE)
5752 warning ("incomplete implementation of class `%s'",
5753 IDENTIFIER_POINTER (CLASS_NAME (objc_implementation_context)));
5754 else if (TREE_CODE (objc_implementation_context)
5755 == CATEGORY_IMPLEMENTATION_TYPE)
5756 warning ("incomplete implementation of category `%s'",
5757 IDENTIFIER_POINTER (CLASS_SUPER_NAME (objc_implementation_context)));
5761 warning ("method definition for `%c%s' not found",
5762 mtype, IDENTIFIER_POINTER (METHOD_SEL_NAME (chain)));
5765 chain = TREE_CHAIN (chain);
5771 /* Check if CLASS, or its superclasses, explicitly conforms to PROTOCOL. */
5774 conforms_to_protocol (class, protocol)
5778 if (TREE_CODE (protocol) == PROTOCOL_INTERFACE_TYPE)
5780 tree p = CLASS_PROTOCOL_LIST (class);
5781 while (p && TREE_VALUE (p) != protocol)
5786 tree super = (CLASS_SUPER_NAME (class)
5787 ? lookup_interface (CLASS_SUPER_NAME (class))
5789 int tmp = super ? conforms_to_protocol (super, protocol) : 0;
5798 /* Make sure all methods in CHAIN are accessible as MTYPE methods in
5799 CONTEXT. This is one of two mechanisms to check protocol integrity. */
5802 check_methods_accessible (chain, context, mtype)
5809 tree base_context = context;
5813 context = base_context;
5817 list = CLASS_CLS_METHODS (context);
5819 list = CLASS_NST_METHODS (context);
5821 if (lookup_method (list, chain))
5824 else if (TREE_CODE (context) == CLASS_IMPLEMENTATION_TYPE
5825 || TREE_CODE (context) == CLASS_INTERFACE_TYPE)
5826 context = (CLASS_SUPER_NAME (context)
5827 ? lookup_interface (CLASS_SUPER_NAME (context))
5830 else if (TREE_CODE (context) == CATEGORY_IMPLEMENTATION_TYPE
5831 || TREE_CODE (context) == CATEGORY_INTERFACE_TYPE)
5832 context = (CLASS_NAME (context)
5833 ? lookup_interface (CLASS_NAME (context))
5839 if (context == NULL_TREE)
5843 if (TREE_CODE (objc_implementation_context)
5844 == CLASS_IMPLEMENTATION_TYPE)
5845 warning ("incomplete implementation of class `%s'",
5847 (CLASS_NAME (objc_implementation_context)));
5848 else if (TREE_CODE (objc_implementation_context)
5849 == CATEGORY_IMPLEMENTATION_TYPE)
5850 warning ("incomplete implementation of category `%s'",
5852 (CLASS_SUPER_NAME (objc_implementation_context)));
5855 warning ("method definition for `%c%s' not found",
5856 mtype, IDENTIFIER_POINTER (METHOD_SEL_NAME (chain)));
5859 chain = TREE_CHAIN (chain); /* next method... */
5864 /* Check whether the current interface (accessible via
5865 'objc_implementation_context') actually implements protocol P, along
5866 with any protocols that P inherits. */
5869 check_protocol (p, type, name)
5874 if (TREE_CODE (p) == PROTOCOL_INTERFACE_TYPE)
5878 /* Ensure that all protocols have bodies! */
5879 if (flag_warn_protocol)
5881 f1 = check_methods (PROTOCOL_CLS_METHODS (p),
5882 CLASS_CLS_METHODS (objc_implementation_context),
5884 f2 = check_methods (PROTOCOL_NST_METHODS (p),
5885 CLASS_NST_METHODS (objc_implementation_context),
5890 f1 = check_methods_accessible (PROTOCOL_CLS_METHODS (p),
5891 objc_implementation_context,
5893 f2 = check_methods_accessible (PROTOCOL_NST_METHODS (p),
5894 objc_implementation_context,
5899 warning ("%s `%s' does not fully implement the `%s' protocol",
5900 type, name, IDENTIFIER_POINTER (PROTOCOL_NAME (p)));
5903 /* Check protocols recursively. */
5904 if (PROTOCOL_LIST (p))
5906 tree subs = PROTOCOL_LIST (p);
5908 lookup_interface (CLASS_SUPER_NAME (implementation_template));
5912 tree sub = TREE_VALUE (subs);
5914 /* If the superclass does not conform to the protocols
5915 inherited by P, then we must! */
5916 if (!super_class || !conforms_to_protocol (super_class, sub))
5917 check_protocol (sub, type, name);
5918 subs = TREE_CHAIN (subs);
5923 /* Check whether the current interface (accessible via
5924 'objc_implementation_context') actually implements the protocols listed
5928 check_protocols (proto_list, type, name)
5933 for ( ; proto_list; proto_list = TREE_CHAIN (proto_list))
5935 tree p = TREE_VALUE (proto_list);
5937 check_protocol (p, type, name);
5941 /* Make sure that the class CLASS_NAME is defined
5942 CODE says which kind of thing CLASS_NAME ought to be.
5943 It can be CLASS_INTERFACE_TYPE, CLASS_IMPLEMENTATION_TYPE,
5944 CATEGORY_INTERFACE_TYPE, or CATEGORY_IMPLEMENTATION_TYPE. */
5947 start_class (code, class_name, super_name, protocol_list)
5948 enum tree_code code;
5955 if (objc_implementation_context)
5957 warning ("`@end' missing in implementation context");
5958 finish_class (objc_implementation_context);
5959 objc_ivar_chain = NULL_TREE;
5960 objc_implementation_context = NULL_TREE;
5963 class = make_node (code);
5964 TYPE_BINFO (class) = make_tree_vec (5);
5966 CLASS_NAME (class) = class_name;
5967 CLASS_SUPER_NAME (class) = super_name;
5968 CLASS_CLS_METHODS (class) = NULL_TREE;
5970 if (! is_class_name (class_name) && (decl = lookup_name (class_name)))
5972 error ("`%s' redeclared as different kind of symbol",
5973 IDENTIFIER_POINTER (class_name));
5974 error_with_decl (decl, "previous declaration of `%s'");
5977 if (code == CLASS_IMPLEMENTATION_TYPE)
5982 for (chain = implemented_classes; chain; chain = TREE_CHAIN (chain))
5983 if (TREE_VALUE (chain) == class_name)
5985 error ("reimplementation of class `%s'",
5986 IDENTIFIER_POINTER (class_name));
5987 return error_mark_node;
5989 implemented_classes = tree_cons (NULL_TREE, class_name,
5990 implemented_classes);
5993 /* Pre-build the following entities - for speed/convenience. */
5995 self_id = get_identifier ("self");
5997 ucmd_id = get_identifier ("_cmd");
6000 = build_tree_list (get_identifier ("__unused__"), NULL_TREE);
6001 if (!objc_super_template)
6002 objc_super_template = build_super_template ();
6004 /* Reset for multiple classes per file. */
6007 objc_implementation_context = class;
6009 /* Lookup the interface for this implementation. */
6011 if (!(implementation_template = lookup_interface (class_name)))
6013 warning ("cannot find interface declaration for `%s'",
6014 IDENTIFIER_POINTER (class_name));
6015 add_class (implementation_template = objc_implementation_context);
6018 /* If a super class has been specified in the implementation,
6019 insure it conforms to the one specified in the interface. */
6022 && (super_name != CLASS_SUPER_NAME (implementation_template)))
6024 tree previous_name = CLASS_SUPER_NAME (implementation_template);
6025 const char *const name =
6026 previous_name ? IDENTIFIER_POINTER (previous_name) : "";
6027 error ("conflicting super class name `%s'",
6028 IDENTIFIER_POINTER (super_name));
6029 error ("previous declaration of `%s'", name);
6032 else if (! super_name)
6034 CLASS_SUPER_NAME (objc_implementation_context)
6035 = CLASS_SUPER_NAME (implementation_template);
6039 else if (code == CLASS_INTERFACE_TYPE)
6041 if (lookup_interface (class_name))
6042 warning ("duplicate interface declaration for class `%s'",
6043 IDENTIFIER_POINTER (class_name));
6048 CLASS_PROTOCOL_LIST (class)
6049 = lookup_and_install_protocols (protocol_list);
6052 else if (code == CATEGORY_INTERFACE_TYPE)
6054 tree class_category_is_assoc_with;
6056 /* For a category, class_name is really the name of the class that
6057 the following set of methods will be associated with. We must
6058 find the interface so that can derive the objects template. */
6060 if (!(class_category_is_assoc_with = lookup_interface (class_name)))
6062 error ("cannot find interface declaration for `%s'",
6063 IDENTIFIER_POINTER (class_name));
6064 exit (FATAL_EXIT_CODE);
6067 add_category (class_category_is_assoc_with, class);
6070 CLASS_PROTOCOL_LIST (class)
6071 = lookup_and_install_protocols (protocol_list);
6074 else if (code == CATEGORY_IMPLEMENTATION_TYPE)
6076 /* Pre-build the following entities for speed/convenience. */
6078 self_id = get_identifier ("self");
6080 ucmd_id = get_identifier ("_cmd");
6083 = build_tree_list (get_identifier ("__unused__"), NULL_TREE);
6084 if (!objc_super_template)
6085 objc_super_template = build_super_template ();
6087 /* Reset for multiple classes per file. */
6090 objc_implementation_context = class;
6092 /* For a category, class_name is really the name of the class that
6093 the following set of methods will be associated with. We must
6094 find the interface so that can derive the objects template. */
6096 if (!(implementation_template = lookup_interface (class_name)))
6098 error ("cannot find interface declaration for `%s'",
6099 IDENTIFIER_POINTER (class_name));
6100 exit (FATAL_EXIT_CODE);
6107 continue_class (class)
6110 if (TREE_CODE (class) == CLASS_IMPLEMENTATION_TYPE
6111 || TREE_CODE (class) == CATEGORY_IMPLEMENTATION_TYPE)
6113 struct imp_entry *imp_entry;
6116 /* Check consistency of the instance variables. */
6118 if (CLASS_IVARS (class))
6119 check_ivars (implementation_template, class);
6121 /* code generation */
6123 ivar_context = build_private_template (implementation_template);
6125 if (!objc_class_template)
6126 build_class_template ();
6128 imp_entry = (struct imp_entry *) ggc_alloc (sizeof (struct imp_entry));
6130 imp_entry->next = imp_list;
6131 imp_entry->imp_context = class;
6132 imp_entry->imp_template = implementation_template;
6134 synth_forward_declarations ();
6135 imp_entry->class_decl = UOBJC_CLASS_decl;
6136 imp_entry->meta_decl = UOBJC_METACLASS_decl;
6138 /* Append to front and increment count. */
6139 imp_list = imp_entry;
6140 if (TREE_CODE (class) == CLASS_IMPLEMENTATION_TYPE)
6145 return ivar_context;
6148 else if (TREE_CODE (class) == CLASS_INTERFACE_TYPE)
6150 tree record = xref_tag (RECORD_TYPE, CLASS_NAME (class));
6152 if (!TYPE_FIELDS (record))
6154 finish_struct (record, build_ivar_chain (class, 0), NULL_TREE);
6155 CLASS_STATIC_TEMPLATE (class) = record;
6157 /* Mark this record as a class template for static typing. */
6158 TREE_STATIC_TEMPLATE (record) = 1;
6165 return error_mark_node;
6168 /* This is called once we see the "@end" in an interface/implementation. */
6171 finish_class (class)
6174 if (TREE_CODE (class) == CLASS_IMPLEMENTATION_TYPE)
6176 /* All code generation is done in finish_objc. */
6178 if (implementation_template != objc_implementation_context)
6180 /* Ensure that all method listed in the interface contain bodies. */
6181 check_methods (CLASS_CLS_METHODS (implementation_template),
6182 CLASS_CLS_METHODS (objc_implementation_context), '+');
6183 check_methods (CLASS_NST_METHODS (implementation_template),
6184 CLASS_NST_METHODS (objc_implementation_context), '-');
6186 if (CLASS_PROTOCOL_LIST (implementation_template))
6187 check_protocols (CLASS_PROTOCOL_LIST (implementation_template),
6189 IDENTIFIER_POINTER (CLASS_NAME (objc_implementation_context)));
6193 else if (TREE_CODE (class) == CATEGORY_IMPLEMENTATION_TYPE)
6195 tree category = CLASS_CATEGORY_LIST (implementation_template);
6197 /* Find the category interface from the class it is associated with. */
6200 if (CLASS_SUPER_NAME (class) == CLASS_SUPER_NAME (category))
6202 category = CLASS_CATEGORY_LIST (category);
6207 /* Ensure all method listed in the interface contain bodies. */
6208 check_methods (CLASS_CLS_METHODS (category),
6209 CLASS_CLS_METHODS (objc_implementation_context), '+');
6210 check_methods (CLASS_NST_METHODS (category),
6211 CLASS_NST_METHODS (objc_implementation_context), '-');
6213 if (CLASS_PROTOCOL_LIST (category))
6214 check_protocols (CLASS_PROTOCOL_LIST (category),
6216 IDENTIFIER_POINTER (CLASS_SUPER_NAME (objc_implementation_context)));
6220 else if (TREE_CODE (class) == CLASS_INTERFACE_TYPE)
6223 const char *class_name = IDENTIFIER_POINTER (CLASS_NAME (class));
6224 char *string = (char *) alloca (strlen (class_name) + 3);
6226 /* extern struct objc_object *_<my_name>; */
6228 sprintf (string, "_%s", class_name);
6230 decl_specs = build_tree_list (NULL_TREE, ridpointers[(int) RID_EXTERN]);
6231 decl_specs = tree_cons (NULL_TREE, objc_object_reference, decl_specs);
6232 define_decl (build1 (INDIRECT_REF, NULL_TREE, get_identifier (string)),
6238 add_protocol (protocol)
6241 /* Put protocol on list in reverse order. */
6242 TREE_CHAIN (protocol) = protocol_chain;
6243 protocol_chain = protocol;
6244 return protocol_chain;
6248 lookup_protocol (ident)
6253 for (chain = protocol_chain; chain; chain = TREE_CHAIN (chain))
6254 if (ident == PROTOCOL_NAME (chain))
6260 /* This function forward declares the protocols named by NAMES. If
6261 they are already declared or defined, the function has no effect. */
6264 objc_declare_protocols (names)
6269 for (list = names; list; list = TREE_CHAIN (list))
6271 tree name = TREE_VALUE (list);
6273 if (lookup_protocol (name) == NULL_TREE)
6275 tree protocol = make_node (PROTOCOL_INTERFACE_TYPE);
6277 TYPE_BINFO (protocol) = make_tree_vec (2);
6278 PROTOCOL_NAME (protocol) = name;
6279 PROTOCOL_LIST (protocol) = NULL_TREE;
6280 add_protocol (protocol);
6281 PROTOCOL_DEFINED (protocol) = 0;
6282 PROTOCOL_FORWARD_DECL (protocol) = NULL_TREE;
6288 start_protocol (code, name, list)
6289 enum tree_code code;
6295 /* This is as good a place as any. Need to invoke
6296 push_tag_toplevel. */
6297 if (!objc_protocol_template)
6298 objc_protocol_template = build_protocol_template ();
6300 protocol = lookup_protocol (name);
6304 protocol = make_node (code);
6305 TYPE_BINFO (protocol) = make_tree_vec (2);
6307 PROTOCOL_NAME (protocol) = name;
6308 PROTOCOL_LIST (protocol) = lookup_and_install_protocols (list);
6309 add_protocol (protocol);
6310 PROTOCOL_DEFINED (protocol) = 1;
6311 PROTOCOL_FORWARD_DECL (protocol) = NULL_TREE;
6313 check_protocol_recursively (protocol, list);
6315 else if (! PROTOCOL_DEFINED (protocol))
6317 PROTOCOL_DEFINED (protocol) = 1;
6318 PROTOCOL_LIST (protocol) = lookup_and_install_protocols (list);
6320 check_protocol_recursively (protocol, list);
6324 warning ("duplicate declaration for protocol `%s'",
6325 IDENTIFIER_POINTER (name));
6331 finish_protocol (protocol)
6332 tree protocol ATTRIBUTE_UNUSED;
6337 /* "Encode" a data type into a string, which grows in util_obstack.
6338 ??? What is the FORMAT? Someone please document this! */
6341 encode_type_qualifiers (declspecs)
6346 for (spec = declspecs; spec; spec = TREE_CHAIN (spec))
6348 if (ridpointers[(int) RID_CONST] == TREE_VALUE (spec))
6349 obstack_1grow (&util_obstack, 'r');
6350 else if (ridpointers[(int) RID_IN] == TREE_VALUE (spec))
6351 obstack_1grow (&util_obstack, 'n');
6352 else if (ridpointers[(int) RID_INOUT] == TREE_VALUE (spec))
6353 obstack_1grow (&util_obstack, 'N');
6354 else if (ridpointers[(int) RID_OUT] == TREE_VALUE (spec))
6355 obstack_1grow (&util_obstack, 'o');
6356 else if (ridpointers[(int) RID_BYCOPY] == TREE_VALUE (spec))
6357 obstack_1grow (&util_obstack, 'O');
6358 else if (ridpointers[(int) RID_BYREF] == TREE_VALUE (spec))
6359 obstack_1grow (&util_obstack, 'R');
6360 else if (ridpointers[(int) RID_ONEWAY] == TREE_VALUE (spec))
6361 obstack_1grow (&util_obstack, 'V');
6365 /* Encode a pointer type. */
6368 encode_pointer (type, curtype, format)
6373 tree pointer_to = TREE_TYPE (type);
6375 if (TREE_CODE (pointer_to) == RECORD_TYPE)
6377 if (TYPE_NAME (pointer_to)
6378 && TREE_CODE (TYPE_NAME (pointer_to)) == IDENTIFIER_NODE)
6380 const char *name = IDENTIFIER_POINTER (TYPE_NAME (pointer_to));
6382 if (strcmp (name, TAG_OBJECT) == 0) /* '@' */
6384 obstack_1grow (&util_obstack, '@');
6387 else if (TREE_STATIC_TEMPLATE (pointer_to))
6389 if (generating_instance_variables)
6391 obstack_1grow (&util_obstack, '@');
6392 obstack_1grow (&util_obstack, '"');
6393 obstack_grow (&util_obstack, name, strlen (name));
6394 obstack_1grow (&util_obstack, '"');
6399 obstack_1grow (&util_obstack, '@');
6403 else if (strcmp (name, TAG_CLASS) == 0) /* '#' */
6405 obstack_1grow (&util_obstack, '#');
6408 else if (strcmp (name, TAG_SELECTOR) == 0) /* ':' */
6410 obstack_1grow (&util_obstack, ':');
6415 else if (TREE_CODE (pointer_to) == INTEGER_TYPE
6416 && TYPE_MODE (pointer_to) == QImode)
6418 obstack_1grow (&util_obstack, '*');
6422 /* We have a type that does not get special treatment. */
6424 /* NeXT extension */
6425 obstack_1grow (&util_obstack, '^');
6426 encode_type (pointer_to, curtype, format);
6430 encode_array (type, curtype, format)
6435 tree an_int_cst = TYPE_SIZE (type);
6436 tree array_of = TREE_TYPE (type);
6439 /* An incomplete array is treated like a pointer. */
6440 if (an_int_cst == NULL)
6442 encode_pointer (type, curtype, format);
6446 sprintf (buffer, "[%ld",
6447 (long) (TREE_INT_CST_LOW (an_int_cst)
6448 / TREE_INT_CST_LOW (TYPE_SIZE (array_of))));
6450 obstack_grow (&util_obstack, buffer, strlen (buffer));
6451 encode_type (array_of, curtype, format);
6452 obstack_1grow (&util_obstack, ']');
6457 encode_aggregate_within (type, curtype, format, left, right)
6464 /* The RECORD_TYPE may in fact be a typedef! For purposes
6465 of encoding, we need the real underlying enchilada. */
6466 if (TYPE_MAIN_VARIANT (type))
6467 type = TYPE_MAIN_VARIANT (type);
6469 if (obstack_object_size (&util_obstack) > 0
6470 && *(obstack_next_free (&util_obstack) - 1) == '^')
6472 tree name = TYPE_NAME (type);
6474 /* we have a reference; this is a NeXT extension. */
6476 if (obstack_object_size (&util_obstack) - curtype == 1
6477 && format == OBJC_ENCODE_INLINE_DEFS)
6479 /* Output format of struct for first level only. */
6480 tree fields = TYPE_FIELDS (type);
6482 if (name && TREE_CODE (name) == IDENTIFIER_NODE)
6484 obstack_1grow (&util_obstack, left);
6485 obstack_grow (&util_obstack,
6486 IDENTIFIER_POINTER (name),
6487 strlen (IDENTIFIER_POINTER (name)));
6488 obstack_1grow (&util_obstack, '=');
6492 obstack_1grow (&util_obstack, left);
6493 obstack_grow (&util_obstack, "?=", 2);
6496 for ( ; fields; fields = TREE_CHAIN (fields))
6497 encode_field_decl (fields, curtype, format);
6499 obstack_1grow (&util_obstack, right);
6502 else if (name && TREE_CODE (name) == IDENTIFIER_NODE)
6504 obstack_1grow (&util_obstack, left);
6505 obstack_grow (&util_obstack,
6506 IDENTIFIER_POINTER (name),
6507 strlen (IDENTIFIER_POINTER (name)));
6508 obstack_1grow (&util_obstack, right);
6513 /* We have an untagged structure or a typedef. */
6514 obstack_1grow (&util_obstack, left);
6515 obstack_1grow (&util_obstack, '?');
6516 obstack_1grow (&util_obstack, right);
6522 tree name = TYPE_NAME (type);
6523 tree fields = TYPE_FIELDS (type);
6525 if (format == OBJC_ENCODE_INLINE_DEFS
6526 || generating_instance_variables)
6528 obstack_1grow (&util_obstack, left);
6529 if (name && TREE_CODE (name) == IDENTIFIER_NODE)
6530 obstack_grow (&util_obstack,
6531 IDENTIFIER_POINTER (name),
6532 strlen (IDENTIFIER_POINTER (name)));
6534 obstack_1grow (&util_obstack, '?');
6536 obstack_1grow (&util_obstack, '=');
6538 for (; fields; fields = TREE_CHAIN (fields))
6540 if (generating_instance_variables)
6542 tree fname = DECL_NAME (fields);
6544 obstack_1grow (&util_obstack, '"');
6545 if (fname && TREE_CODE (fname) == IDENTIFIER_NODE)
6547 obstack_grow (&util_obstack,
6548 IDENTIFIER_POINTER (fname),
6549 strlen (IDENTIFIER_POINTER (fname)));
6552 obstack_1grow (&util_obstack, '"');
6555 encode_field_decl (fields, curtype, format);
6558 obstack_1grow (&util_obstack, right);
6563 obstack_1grow (&util_obstack, left);
6564 if (name && TREE_CODE (name) == IDENTIFIER_NODE)
6565 obstack_grow (&util_obstack,
6566 IDENTIFIER_POINTER (name),
6567 strlen (IDENTIFIER_POINTER (name)));
6569 /* We have an untagged structure or a typedef. */
6570 obstack_1grow (&util_obstack, '?');
6572 obstack_1grow (&util_obstack, right);
6578 encode_aggregate (type, curtype, format)
6583 enum tree_code code = TREE_CODE (type);
6589 encode_aggregate_within(type, curtype, format, '{', '}');
6594 encode_aggregate_within(type, curtype, format, '(', ')');
6599 obstack_1grow (&util_obstack, 'i');
6607 /* Support bitfields. The current version of Objective-C does not support
6608 them. The string will consist of one or more "b:n"'s where n is an
6609 integer describing the width of the bitfield. Currently, classes in
6610 the kit implement a method "-(char *)describeBitfieldStruct:" that
6611 simulates this. If they do not implement this method, the archiver
6612 assumes the bitfield is 16 bits wide (padded if necessary) and packed
6613 according to the GNU compiler. After looking at the "kit", it appears
6614 that all classes currently rely on this default behavior, rather than
6615 hand generating this string (which is tedious). */
6618 encode_bitfield (width)
6622 sprintf (buffer, "b%d", width);
6623 obstack_grow (&util_obstack, buffer, strlen (buffer));
6626 /* FORMAT will be OBJC_ENCODE_INLINE_DEFS or OBJC_ENCODE_DONT_INLINE_DEFS. */
6629 encode_type (type, curtype, format)
6634 enum tree_code code = TREE_CODE (type);
6636 if (code == INTEGER_TYPE)
6638 if (integer_zerop (TYPE_MIN_VALUE (type)))
6640 /* Unsigned integer types. */
6642 if (TYPE_MODE (type) == QImode)
6643 obstack_1grow (&util_obstack, 'C');
6644 else if (TYPE_MODE (type) == HImode)
6645 obstack_1grow (&util_obstack, 'S');
6646 else if (TYPE_MODE (type) == SImode)
6648 if (type == long_unsigned_type_node)
6649 obstack_1grow (&util_obstack, 'L');
6651 obstack_1grow (&util_obstack, 'I');
6653 else if (TYPE_MODE (type) == DImode)
6654 obstack_1grow (&util_obstack, 'Q');
6658 /* Signed integer types. */
6660 if (TYPE_MODE (type) == QImode)
6661 obstack_1grow (&util_obstack, 'c');
6662 else if (TYPE_MODE (type) == HImode)
6663 obstack_1grow (&util_obstack, 's');
6664 else if (TYPE_MODE (type) == SImode)
6666 if (type == long_integer_type_node)
6667 obstack_1grow (&util_obstack, 'l');
6669 obstack_1grow (&util_obstack, 'i');
6672 else if (TYPE_MODE (type) == DImode)
6673 obstack_1grow (&util_obstack, 'q');
6677 else if (code == REAL_TYPE)
6679 /* Floating point types. */
6681 if (TYPE_MODE (type) == SFmode)
6682 obstack_1grow (&util_obstack, 'f');
6683 else if (TYPE_MODE (type) == DFmode
6684 || TYPE_MODE (type) == TFmode)
6685 obstack_1grow (&util_obstack, 'd');
6688 else if (code == VOID_TYPE)
6689 obstack_1grow (&util_obstack, 'v');
6691 else if (code == ARRAY_TYPE)
6692 encode_array (type, curtype, format);
6694 else if (code == POINTER_TYPE)
6695 encode_pointer (type, curtype, format);
6697 else if (code == RECORD_TYPE || code == UNION_TYPE || code == ENUMERAL_TYPE)
6698 encode_aggregate (type, curtype, format);
6700 else if (code == FUNCTION_TYPE) /* '?' */
6701 obstack_1grow (&util_obstack, '?');
6705 encode_complete_bitfield (int position, tree type, int size)
6707 enum tree_code code = TREE_CODE (type);
6709 char charType = '?';
6711 if (code == INTEGER_TYPE)
6713 if (integer_zerop (TYPE_MIN_VALUE (type)))
6715 /* Unsigned integer types. */
6717 if (TYPE_MODE (type) == QImode)
6719 else if (TYPE_MODE (type) == HImode)
6721 else if (TYPE_MODE (type) == SImode)
6723 if (type == long_unsigned_type_node)
6728 else if (TYPE_MODE (type) == DImode)
6733 /* Signed integer types. */
6735 if (TYPE_MODE (type) == QImode)
6737 else if (TYPE_MODE (type) == HImode)
6739 else if (TYPE_MODE (type) == SImode)
6741 if (type == long_integer_type_node)
6747 else if (TYPE_MODE (type) == DImode)
6751 else if (code == ENUMERAL_TYPE)
6756 sprintf (buffer, "b%d%c%d", position, charType, size);
6757 obstack_grow (&util_obstack, buffer, strlen (buffer));
6761 encode_field_decl (field_decl, curtype, format)
6768 type = TREE_TYPE (field_decl);
6770 /* If this field is obviously a bitfield, or is a bitfield that has been
6771 clobbered to look like a ordinary integer mode, go ahead and generate
6772 the bitfield typing information. */
6773 if (flag_next_runtime)
6775 if (DECL_BIT_FIELD (field_decl))
6776 encode_bitfield (tree_low_cst (DECL_SIZE (field_decl), 1));
6778 encode_type (TREE_TYPE (field_decl), curtype, format);
6782 if (DECL_BIT_FIELD (field_decl))
6783 encode_complete_bitfield (int_bit_position (field_decl),
6784 DECL_BIT_FIELD_TYPE (field_decl),
6785 tree_low_cst (DECL_SIZE (field_decl), 1));
6787 encode_type (TREE_TYPE (field_decl), curtype, format);
6792 expr_last (complex_expr)
6798 while ((next = TREE_OPERAND (complex_expr, 0)))
6799 complex_expr = next;
6801 return complex_expr;
6804 /* Transform a method definition into a function definition as follows:
6805 - synthesize the first two arguments, "self" and "_cmd". */
6808 start_method_def (method)
6813 /* Required to implement _msgSuper. */
6814 objc_method_context = method;
6815 UOBJC_SUPER_decl = NULL_TREE;
6817 /* Must be called BEFORE start_function. */
6820 /* Generate prototype declarations for arguments..."new-style". */
6822 if (TREE_CODE (objc_method_context) == INSTANCE_METHOD_DECL)
6823 decl_specs = build_tree_list (NULL_TREE, uprivate_record);
6825 /* Really a `struct objc_class *'. However, we allow people to
6826 assign to self, which changes its type midstream. */
6827 decl_specs = build_tree_list (NULL_TREE, objc_object_reference);
6829 push_parm_decl (build_tree_list
6830 (build_tree_list (decl_specs,
6831 build1 (INDIRECT_REF, NULL_TREE, self_id)),
6834 decl_specs = build_tree_list (NULL_TREE,
6835 xref_tag (RECORD_TYPE,
6836 get_identifier (TAG_SELECTOR)));
6837 push_parm_decl (build_tree_list
6838 (build_tree_list (decl_specs,
6839 build1 (INDIRECT_REF, NULL_TREE, ucmd_id)),
6842 /* Generate argument declarations if a keyword_decl. */
6843 if (METHOD_SEL_ARGS (method))
6845 tree arglist = METHOD_SEL_ARGS (method);
6848 tree arg_spec = TREE_PURPOSE (TREE_TYPE (arglist));
6849 tree arg_decl = TREE_VALUE (TREE_TYPE (arglist));
6853 tree last_expr = expr_last (arg_decl);
6855 /* Unite the abstract decl with its name. */
6856 TREE_OPERAND (last_expr, 0) = KEYWORD_ARG_NAME (arglist);
6857 push_parm_decl (build_tree_list
6858 (build_tree_list (arg_spec, arg_decl),
6861 /* Unhook: restore the abstract declarator. */
6862 TREE_OPERAND (last_expr, 0) = NULL_TREE;
6866 push_parm_decl (build_tree_list
6867 (build_tree_list (arg_spec,
6868 KEYWORD_ARG_NAME (arglist)),
6871 arglist = TREE_CHAIN (arglist);
6876 if (METHOD_ADD_ARGS (method) != NULL_TREE
6877 && METHOD_ADD_ARGS (method) != objc_ellipsis_node)
6879 /* We have a variable length selector - in "prototype" format. */
6880 tree akey = TREE_PURPOSE (METHOD_ADD_ARGS (method));
6883 /* This must be done prior to calling pushdecl. pushdecl is
6884 going to change our chain on us. */
6885 tree nextkey = TREE_CHAIN (akey);
6893 warn_with_method (message, mtype, method)
6894 const char *message;
6898 if (!diagnostic_count_diagnostic (global_dc, DK_WARNING))
6901 diagnostic_report_current_function (global_dc);
6903 /* Add a readable method name to the warning. */
6904 warning_with_file_and_line (DECL_SOURCE_FILE (method),
6905 DECL_SOURCE_LINE (method),
6908 gen_method_decl (method, errbuf));
6911 /* Return 1 if METHOD is consistent with PROTO. */
6914 comp_method_with_proto (method, proto)
6917 /* Create a function template node at most once. */
6918 if (!function1_template)
6919 function1_template = make_node (FUNCTION_TYPE);
6921 /* Install argument types - normally set by build_function_type. */
6922 TYPE_ARG_TYPES (function1_template) = get_arg_type_list (proto, METHOD_DEF, 0);
6924 /* install return type */
6925 TREE_TYPE (function1_template) = groktypename (TREE_TYPE (proto));
6927 return comptypes (TREE_TYPE (METHOD_DEFINITION (method)), function1_template);
6930 /* Return 1 if PROTO1 is consistent with PROTO2. */
6933 comp_proto_with_proto (proto0, proto1)
6934 tree proto0, proto1;
6936 /* Create a couple of function_template nodes at most once. */
6937 if (!function1_template)
6938 function1_template = make_node (FUNCTION_TYPE);
6939 if (!function2_template)
6940 function2_template = make_node (FUNCTION_TYPE);
6942 /* Install argument types; normally set by build_function_type. */
6943 TYPE_ARG_TYPES (function1_template) = get_arg_type_list (proto0, METHOD_REF, 0);
6944 TYPE_ARG_TYPES (function2_template) = get_arg_type_list (proto1, METHOD_REF, 0);
6946 /* Install return type. */
6947 TREE_TYPE (function1_template) = groktypename (TREE_TYPE (proto0));
6948 TREE_TYPE (function2_template) = groktypename (TREE_TYPE (proto1));
6950 return comptypes (function1_template, function2_template);
6953 /* - Generate an identifier for the function. the format is "_n_cls",
6954 where 1 <= n <= nMethods, and cls is the name the implementation we
6956 - Install the return type from the method declaration.
6957 - If we have a prototype, check for type consistency. */
6960 really_start_method (method, parmlist)
6961 tree method, parmlist;
6963 tree sc_spec, ret_spec, ret_decl, decl_specs;
6964 tree method_decl, method_id;
6965 const char *sel_name, *class_name, *cat_name;
6968 /* Synth the storage class & assemble the return type. */
6969 sc_spec = tree_cons (NULL_TREE, ridpointers[(int) RID_STATIC], NULL_TREE);
6970 ret_spec = TREE_PURPOSE (TREE_TYPE (method));
6971 decl_specs = chainon (sc_spec, ret_spec);
6973 sel_name = IDENTIFIER_POINTER (METHOD_SEL_NAME (method));
6974 class_name = IDENTIFIER_POINTER (CLASS_NAME (objc_implementation_context));
6975 cat_name = ((TREE_CODE (objc_implementation_context)
6976 == CLASS_IMPLEMENTATION_TYPE)
6978 : IDENTIFIER_POINTER (CLASS_SUPER_NAME (objc_implementation_context)));
6981 /* Make sure this is big enough for any plausible method label. */
6982 buf = (char *) alloca (50 + strlen (sel_name) + strlen (class_name)
6983 + (cat_name ? strlen (cat_name) : 0));
6985 OBJC_GEN_METHOD_LABEL (buf, TREE_CODE (method) == INSTANCE_METHOD_DECL,
6986 class_name, cat_name, sel_name, method_slot);
6988 method_id = get_identifier (buf);
6990 method_decl = build_nt (CALL_EXPR, method_id, parmlist, NULL_TREE);
6992 /* Check the declarator portion of the return type for the method. */
6993 if ((ret_decl = TREE_VALUE (TREE_TYPE (method))))
6995 /* Unite the complex decl (specified in the abstract decl) with the
6996 function decl just synthesized..(int *), (int (*)()), (int (*)[]). */
6997 tree save_expr = expr_last (ret_decl);
6999 TREE_OPERAND (save_expr, 0) = method_decl;
7000 method_decl = ret_decl;
7002 /* Fool the parser into thinking it is starting a function. */
7003 start_function (decl_specs, method_decl, NULL_TREE);
7005 /* Unhook: this has the effect of restoring the abstract declarator. */
7006 TREE_OPERAND (save_expr, 0) = NULL_TREE;
7011 TREE_VALUE (TREE_TYPE (method)) = method_decl;
7013 /* Fool the parser into thinking it is starting a function. */
7014 start_function (decl_specs, method_decl, NULL_TREE);
7016 /* Unhook: this has the effect of restoring the abstract declarator. */
7017 TREE_VALUE (TREE_TYPE (method)) = NULL_TREE;
7020 METHOD_DEFINITION (method) = current_function_decl;
7022 /* Check consistency...start_function, pushdecl, duplicate_decls. */
7024 if (implementation_template != objc_implementation_context)
7028 if (TREE_CODE (method) == INSTANCE_METHOD_DECL)
7029 proto = lookup_instance_method_static (implementation_template,
7030 METHOD_SEL_NAME (method));
7032 proto = lookup_class_method_static (implementation_template,
7033 METHOD_SEL_NAME (method));
7035 if (proto && ! comp_method_with_proto (method, proto))
7037 char type = (TREE_CODE (method) == INSTANCE_METHOD_DECL ? '-' : '+');
7039 warn_with_method ("conflicting types for", type, method);
7040 warn_with_method ("previous declaration of", type, proto);
7045 /* The following routine is always called...this "architecture" is to
7046 accommodate "old-style" variable length selectors.
7048 - a:a b:b // prototype ; id c; id d; // old-style. */
7051 continue_method_def ()
7055 if (METHOD_ADD_ARGS (objc_method_context) == objc_ellipsis_node)
7056 /* We have a `, ...' immediately following the selector. */
7057 parmlist = get_parm_info (0);
7059 parmlist = get_parm_info (1); /* place a `void_at_end' */
7061 /* Set self_decl from the first argument...this global is used by
7062 build_ivar_reference calling build_indirect_ref. */
7063 self_decl = TREE_PURPOSE (parmlist);
7066 really_start_method (objc_method_context, parmlist);
7067 store_parm_decls ();
7070 /* Called by the parser, from the `pushlevel' production. */
7075 if (!UOBJC_SUPER_decl)
7077 UOBJC_SUPER_decl = start_decl (get_identifier (UTAG_SUPER),
7078 build_tree_list (NULL_TREE,
7079 objc_super_template),
7082 finish_decl (UOBJC_SUPER_decl, NULL_TREE, NULL_TREE);
7084 /* This prevents `unused variable' warnings when compiling with -Wall. */
7085 TREE_USED (UOBJC_SUPER_decl) = 1;
7086 DECL_ARTIFICIAL (UOBJC_SUPER_decl) = 1;
7090 /* _n_Method (id self, SEL sel, ...)
7092 struct objc_super _S;
7093 _msgSuper ((_S.self = self, _S.class = _cls, &_S), ...);
7097 get_super_receiver ()
7099 if (objc_method_context)
7101 tree super_expr, super_expr_list;
7103 /* Set receiver to self. */
7104 super_expr = build_component_ref (UOBJC_SUPER_decl, self_id);
7105 super_expr = build_modify_expr (super_expr, NOP_EXPR, self_decl);
7106 super_expr_list = build_tree_list (NULL_TREE, super_expr);
7108 /* Set class to begin searching. */
7109 super_expr = build_component_ref (UOBJC_SUPER_decl,
7110 get_identifier ("class"));
7112 if (TREE_CODE (objc_implementation_context) == CLASS_IMPLEMENTATION_TYPE)
7114 /* [_cls, __cls]Super are "pre-built" in
7115 synth_forward_declarations. */
7117 super_expr = build_modify_expr (super_expr, NOP_EXPR,
7118 ((TREE_CODE (objc_method_context)
7119 == INSTANCE_METHOD_DECL)
7121 : uucls_super_ref));
7125 /* We have a category. */
7127 tree super_name = CLASS_SUPER_NAME (implementation_template);
7130 /* Barf if super used in a category of Object. */
7133 error ("no super class declared in interface for `%s'",
7134 IDENTIFIER_POINTER (CLASS_NAME (implementation_template)));
7135 return error_mark_node;
7138 if (flag_next_runtime)
7140 super_class = get_class_reference (super_name);
7141 if (TREE_CODE (objc_method_context) == CLASS_METHOD_DECL)
7143 = build_component_ref (build_indirect_ref (super_class, "->"),
7144 get_identifier ("isa"));
7148 add_class_reference (super_name);
7149 super_class = (TREE_CODE (objc_method_context) == INSTANCE_METHOD_DECL
7150 ? objc_get_class_decl : objc_get_meta_class_decl);
7151 assemble_external (super_class);
7153 = build_function_call
7157 my_build_string (IDENTIFIER_LENGTH (super_name) + 1,
7158 IDENTIFIER_POINTER (super_name))));
7161 TREE_TYPE (super_class) = TREE_TYPE (ucls_super_ref);
7162 super_expr = build_modify_expr (super_expr, NOP_EXPR, super_class);
7165 chainon (super_expr_list, build_tree_list (NULL_TREE, super_expr));
7167 super_expr = build_unary_op (ADDR_EXPR, UOBJC_SUPER_decl, 0);
7168 chainon (super_expr_list, build_tree_list (NULL_TREE, super_expr));
7170 return build_compound_expr (super_expr_list);
7174 error ("[super ...] must appear in a method context");
7175 return error_mark_node;
7180 encode_method_def (func_decl)
7185 HOST_WIDE_INT max_parm_end = 0;
7190 encode_type (TREE_TYPE (TREE_TYPE (func_decl)),
7191 obstack_object_size (&util_obstack),
7192 OBJC_ENCODE_INLINE_DEFS);
7195 for (parms = DECL_ARGUMENTS (func_decl); parms;
7196 parms = TREE_CHAIN (parms))
7198 HOST_WIDE_INT parm_end = (forwarding_offset (parms)
7199 + int_size_in_bytes (TREE_TYPE (parms)));
7201 if (! offset_is_register && parm_end > max_parm_end)
7202 max_parm_end = parm_end;
7205 stack_size = max_parm_end - OBJC_FORWARDING_MIN_OFFSET;
7207 sprintf (buffer, "%d", stack_size);
7208 obstack_grow (&util_obstack, buffer, strlen (buffer));
7210 /* Argument types. */
7211 for (parms = DECL_ARGUMENTS (func_decl); parms;
7212 parms = TREE_CHAIN (parms))
7215 encode_type (TREE_TYPE (parms),
7216 obstack_object_size (&util_obstack),
7217 OBJC_ENCODE_INLINE_DEFS);
7219 /* Compute offset. */
7220 sprintf (buffer, "%d", forwarding_offset (parms));
7222 /* Indicate register. */
7223 if (offset_is_register)
7224 obstack_1grow (&util_obstack, '+');
7226 obstack_grow (&util_obstack, buffer, strlen (buffer));
7229 /* Null terminate string. */
7230 obstack_1grow (&util_obstack, 0);
7231 result = get_identifier (obstack_finish (&util_obstack));
7232 obstack_free (&util_obstack, util_firstobj);
7237 objc_expand_function_end ()
7239 METHOD_ENCODING (objc_method_context) = encode_method_def (current_function_decl);
7243 finish_method_def ()
7245 lang_expand_function_end = objc_expand_function_end;
7246 finish_function (0, 1);
7247 lang_expand_function_end = NULL;
7249 /* Required to implement _msgSuper. This must be done AFTER finish_function,
7250 since the optimizer may find "may be used before set" errors. */
7251 objc_method_context = NULL_TREE;
7256 lang_report_error_function (decl)
7259 if (objc_method_context)
7261 fprintf (stderr, "In method `%s'\n",
7262 IDENTIFIER_POINTER (METHOD_SEL_NAME (objc_method_context)));
7272 is_complex_decl (type)
7275 return (TREE_CODE (type) == ARRAY_TYPE
7276 || TREE_CODE (type) == FUNCTION_TYPE
7277 || (TREE_CODE (type) == POINTER_TYPE && ! IS_ID (type)));
7281 /* Code to convert a decl node into text for a declaration in C. */
7283 static char tmpbuf[256];
7286 adorn_decl (decl, str)
7290 enum tree_code code = TREE_CODE (decl);
7292 if (code == ARRAY_REF)
7294 tree an_int_cst = TREE_OPERAND (decl, 1);
7296 if (an_int_cst && TREE_CODE (an_int_cst) == INTEGER_CST)
7297 sprintf (str + strlen (str), "[%ld]",
7298 (long) TREE_INT_CST_LOW (an_int_cst));
7303 else if (code == ARRAY_TYPE)
7305 tree an_int_cst = TYPE_SIZE (decl);
7306 tree array_of = TREE_TYPE (decl);
7308 if (an_int_cst && TREE_CODE (an_int_cst) == INTEGER_TYPE)
7309 sprintf (str + strlen (str), "[%ld]",
7310 (long) (TREE_INT_CST_LOW (an_int_cst)
7311 / TREE_INT_CST_LOW (TYPE_SIZE (array_of))));
7316 else if (code == CALL_EXPR)
7318 tree chain = TREE_PURPOSE (TREE_OPERAND (decl, 1));
7323 gen_declaration_1 (chain, str);
7324 chain = TREE_CHAIN (chain);
7331 else if (code == FUNCTION_TYPE)
7333 tree chain = TYPE_ARG_TYPES (decl);
7336 while (chain && TREE_VALUE (chain) != void_type_node)
7338 gen_declaration_1 (TREE_VALUE (chain), str);
7339 chain = TREE_CHAIN (chain);
7340 if (chain && TREE_VALUE (chain) != void_type_node)
7346 else if (code == INDIRECT_REF)
7348 strcpy (tmpbuf, "*");
7349 if (TREE_TYPE (decl) && TREE_CODE (TREE_TYPE (decl)) == TREE_LIST)
7353 for (chain = nreverse (copy_list (TREE_TYPE (decl)));
7355 chain = TREE_CHAIN (chain))
7357 if (TREE_CODE (TREE_VALUE (chain)) == IDENTIFIER_NODE)
7359 strcat (tmpbuf, " ");
7360 strcat (tmpbuf, IDENTIFIER_POINTER (TREE_VALUE (chain)));
7364 strcat (tmpbuf, " ");
7366 strcat (tmpbuf, str);
7367 strcpy (str, tmpbuf);
7370 else if (code == POINTER_TYPE)
7372 strcpy (tmpbuf, "*");
7373 if (TREE_READONLY (decl) || TYPE_VOLATILE (decl))
7375 if (TREE_READONLY (decl))
7376 strcat (tmpbuf, " const");
7377 if (TYPE_VOLATILE (decl))
7378 strcat (tmpbuf, " volatile");
7380 strcat (tmpbuf, " ");
7382 strcat (tmpbuf, str);
7383 strcpy (str, tmpbuf);
7388 gen_declarator (decl, buf, name)
7395 enum tree_code code = TREE_CODE (decl);
7405 op = TREE_OPERAND (decl, 0);
7407 /* We have a pointer to a function or array...(*)(), (*)[] */
7408 if ((code == ARRAY_REF || code == CALL_EXPR)
7409 && op && TREE_CODE (op) == INDIRECT_REF)
7412 str = gen_declarator (op, buf, name);
7416 strcpy (tmpbuf, "(");
7417 strcat (tmpbuf, str);
7418 strcat (tmpbuf, ")");
7419 strcpy (str, tmpbuf);
7422 adorn_decl (decl, str);
7431 /* This clause is done iteratively rather than recursively. */
7434 op = (is_complex_decl (TREE_TYPE (decl))
7435 ? TREE_TYPE (decl) : NULL_TREE);
7437 adorn_decl (decl, str);
7439 /* We have a pointer to a function or array...(*)(), (*)[] */
7440 if (code == POINTER_TYPE
7441 && op && (TREE_CODE (op) == FUNCTION_TYPE
7442 || TREE_CODE (op) == ARRAY_TYPE))
7444 strcpy (tmpbuf, "(");
7445 strcat (tmpbuf, str);
7446 strcat (tmpbuf, ")");
7447 strcpy (str, tmpbuf);
7450 decl = (is_complex_decl (TREE_TYPE (decl))
7451 ? TREE_TYPE (decl) : NULL_TREE);
7454 while (decl && (code = TREE_CODE (decl)))
7459 case IDENTIFIER_NODE:
7460 /* Will only happen if we are processing a "raw" expr-decl. */
7461 strcpy (buf, IDENTIFIER_POINTER (decl));
7472 /* We have an abstract declarator or a _DECL node. */
7480 gen_declspecs (declspecs, buf, raw)
7489 for (chain = nreverse (copy_list (declspecs));
7490 chain; chain = TREE_CHAIN (chain))
7492 tree aspec = TREE_VALUE (chain);
7494 if (TREE_CODE (aspec) == IDENTIFIER_NODE)
7495 strcat (buf, IDENTIFIER_POINTER (aspec));
7496 else if (TREE_CODE (aspec) == RECORD_TYPE)
7498 if (TYPE_NAME (aspec))
7500 tree protocol_list = TYPE_PROTOCOL_LIST (aspec);
7502 if (! TREE_STATIC_TEMPLATE (aspec))
7503 strcat (buf, "struct ");
7504 strcat (buf, IDENTIFIER_POINTER (TYPE_NAME (aspec)));
7509 tree chain = protocol_list;
7516 (PROTOCOL_NAME (TREE_VALUE (chain))));
7517 chain = TREE_CHAIN (chain);
7526 strcat (buf, "untagged struct");
7529 else if (TREE_CODE (aspec) == UNION_TYPE)
7531 if (TYPE_NAME (aspec))
7533 if (! TREE_STATIC_TEMPLATE (aspec))
7534 strcat (buf, "union ");
7535 strcat (buf, IDENTIFIER_POINTER (TYPE_NAME (aspec)));
7538 strcat (buf, "untagged union");
7541 else if (TREE_CODE (aspec) == ENUMERAL_TYPE)
7543 if (TYPE_NAME (aspec))
7545 if (! TREE_STATIC_TEMPLATE (aspec))
7546 strcat (buf, "enum ");
7547 strcat (buf, IDENTIFIER_POINTER (TYPE_NAME (aspec)));
7550 strcat (buf, "untagged enum");
7553 else if (TREE_CODE (aspec) == TYPE_DECL && DECL_NAME (aspec))
7554 strcat (buf, IDENTIFIER_POINTER (DECL_NAME (aspec)));
7556 else if (IS_ID (aspec))
7558 tree protocol_list = TYPE_PROTOCOL_LIST (aspec);
7563 tree chain = protocol_list;
7570 (PROTOCOL_NAME (TREE_VALUE (chain))));
7571 chain = TREE_CHAIN (chain);
7578 if (TREE_CHAIN (chain))
7584 /* Type qualifiers. */
7585 if (TREE_READONLY (declspecs))
7586 strcat (buf, "const ");
7587 if (TYPE_VOLATILE (declspecs))
7588 strcat (buf, "volatile ");
7590 switch (TREE_CODE (declspecs))
7592 /* Type specifiers. */
7595 declspecs = TYPE_MAIN_VARIANT (declspecs);
7597 /* Signed integer types. */
7599 if (declspecs == short_integer_type_node)
7600 strcat (buf, "short int ");
7601 else if (declspecs == integer_type_node)
7602 strcat (buf, "int ");
7603 else if (declspecs == long_integer_type_node)
7604 strcat (buf, "long int ");
7605 else if (declspecs == long_long_integer_type_node)
7606 strcat (buf, "long long int ");
7607 else if (declspecs == signed_char_type_node
7608 || declspecs == char_type_node)
7609 strcat (buf, "char ");
7611 /* Unsigned integer types. */
7613 else if (declspecs == short_unsigned_type_node)
7614 strcat (buf, "unsigned short ");
7615 else if (declspecs == unsigned_type_node)
7616 strcat (buf, "unsigned int ");
7617 else if (declspecs == long_unsigned_type_node)
7618 strcat (buf, "unsigned long ");
7619 else if (declspecs == long_long_unsigned_type_node)
7620 strcat (buf, "unsigned long long ");
7621 else if (declspecs == unsigned_char_type_node)
7622 strcat (buf, "unsigned char ");
7626 declspecs = TYPE_MAIN_VARIANT (declspecs);
7628 if (declspecs == float_type_node)
7629 strcat (buf, "float ");
7630 else if (declspecs == double_type_node)
7631 strcat (buf, "double ");
7632 else if (declspecs == long_double_type_node)
7633 strcat (buf, "long double ");
7637 if (TYPE_NAME (declspecs)
7638 && TREE_CODE (TYPE_NAME (declspecs)) == IDENTIFIER_NODE)
7640 tree protocol_list = TYPE_PROTOCOL_LIST (declspecs);
7642 if (! TREE_STATIC_TEMPLATE (declspecs))
7643 strcat (buf, "struct ");
7644 strcat (buf, IDENTIFIER_POINTER (TYPE_NAME (declspecs)));
7648 tree chain = protocol_list;
7655 (PROTOCOL_NAME (TREE_VALUE (chain))));
7656 chain = TREE_CHAIN (chain);
7665 strcat (buf, "untagged struct");
7671 if (TYPE_NAME (declspecs)
7672 && TREE_CODE (TYPE_NAME (declspecs)) == IDENTIFIER_NODE)
7674 strcat (buf, "union ");
7675 strcat (buf, IDENTIFIER_POINTER (TYPE_NAME (declspecs)));
7680 strcat (buf, "untagged union ");
7684 if (TYPE_NAME (declspecs)
7685 && TREE_CODE (TYPE_NAME (declspecs)) == IDENTIFIER_NODE)
7687 strcat (buf, "enum ");
7688 strcat (buf, IDENTIFIER_POINTER (TYPE_NAME (declspecs)));
7693 strcat (buf, "untagged enum ");
7697 strcat (buf, "void ");
7702 tree protocol_list = TYPE_PROTOCOL_LIST (declspecs);
7707 tree chain = protocol_list;
7714 (PROTOCOL_NAME (TREE_VALUE (chain))));
7715 chain = TREE_CHAIN (chain);
7731 /* Given a tree node, produce a printable description of it in the given
7732 buffer, overwriting the buffer. */
7735 gen_declaration (atype_or_adecl, buf)
7736 tree atype_or_adecl;
7740 gen_declaration_1 (atype_or_adecl, buf);
7744 /* Given a tree node, append a printable description to the end of the
7748 gen_declaration_1 (atype_or_adecl, buf)
7749 tree atype_or_adecl;
7754 if (TREE_CODE (atype_or_adecl) == TREE_LIST)
7756 tree declspecs; /* "identifier_node", "record_type" */
7757 tree declarator; /* "array_ref", "indirect_ref", "call_expr"... */
7759 /* We have a "raw", abstract declarator (typename). */
7760 declarator = TREE_VALUE (atype_or_adecl);
7761 declspecs = TREE_PURPOSE (atype_or_adecl);
7763 gen_declspecs (declspecs, buf, 1);
7767 strcat (buf, gen_declarator (declarator, declbuf, ""));
7774 tree declspecs; /* "integer_type", "real_type", "record_type"... */
7775 tree declarator; /* "array_type", "function_type", "pointer_type". */
7777 if (TREE_CODE (atype_or_adecl) == FIELD_DECL
7778 || TREE_CODE (atype_or_adecl) == PARM_DECL
7779 || TREE_CODE (atype_or_adecl) == FUNCTION_DECL)
7780 atype = TREE_TYPE (atype_or_adecl);
7782 /* Assume we have a *_type node. */
7783 atype = atype_or_adecl;
7785 if (is_complex_decl (atype))
7789 /* Get the declaration specifier; it is at the end of the list. */
7790 declarator = chain = atype;
7792 chain = TREE_TYPE (chain); /* not TREE_CHAIN (chain); */
7793 while (is_complex_decl (chain));
7800 declarator = NULL_TREE;
7803 gen_declspecs (declspecs, buf, 0);
7805 if (TREE_CODE (atype_or_adecl) == FIELD_DECL
7806 || TREE_CODE (atype_or_adecl) == PARM_DECL
7807 || TREE_CODE (atype_or_adecl) == FUNCTION_DECL)
7809 const char *const decl_name =
7810 (DECL_NAME (atype_or_adecl)
7811 ? IDENTIFIER_POINTER (DECL_NAME (atype_or_adecl)) : "");
7816 strcat (buf, gen_declarator (declarator, declbuf, decl_name));
7819 else if (decl_name[0])
7822 strcat (buf, decl_name);
7825 else if (declarator)
7828 strcat (buf, gen_declarator (declarator, declbuf, ""));
7833 #define RAW_TYPESPEC(meth) (TREE_VALUE (TREE_PURPOSE (TREE_TYPE (meth))))
7835 /* Given a method tree, put a printable description into the given
7836 buffer (overwriting) and return a pointer to the buffer. */
7839 gen_method_decl (method, buf)
7846 if (RAW_TYPESPEC (method) != objc_object_reference)
7849 gen_declaration_1 (TREE_TYPE (method), buf);
7853 chain = METHOD_SEL_ARGS (method);
7856 /* We have a chain of keyword_decls. */
7859 if (KEYWORD_KEY_NAME (chain))
7860 strcat (buf, IDENTIFIER_POINTER (KEYWORD_KEY_NAME (chain)));
7863 if (RAW_TYPESPEC (chain) != objc_object_reference)
7866 gen_declaration_1 (TREE_TYPE (chain), buf);
7870 strcat (buf, IDENTIFIER_POINTER (KEYWORD_ARG_NAME (chain)));
7871 if ((chain = TREE_CHAIN (chain)))
7876 if (METHOD_ADD_ARGS (method) == objc_ellipsis_node)
7877 strcat (buf, ", ...");
7878 else if (METHOD_ADD_ARGS (method))
7880 /* We have a tree list node as generate by get_parm_info. */
7881 chain = TREE_PURPOSE (METHOD_ADD_ARGS (method));
7883 /* Know we have a chain of parm_decls. */
7887 gen_declaration_1 (chain, buf);
7888 chain = TREE_CHAIN (chain);
7894 /* We have a unary selector. */
7895 strcat (buf, IDENTIFIER_POINTER (METHOD_SEL_NAME (method)));
7903 dump_interface (fp, chain)
7907 char *buf = (char *) xmalloc (256);
7908 const char *my_name = IDENTIFIER_POINTER (CLASS_NAME (chain));
7909 tree ivar_decls = CLASS_RAW_IVARS (chain);
7910 tree nst_methods = CLASS_NST_METHODS (chain);
7911 tree cls_methods = CLASS_CLS_METHODS (chain);
7913 fprintf (fp, "\n@interface %s", my_name);
7915 if (CLASS_SUPER_NAME (chain))
7917 const char *super_name = IDENTIFIER_POINTER (CLASS_SUPER_NAME (chain));
7918 fprintf (fp, " : %s\n", super_name);
7925 fprintf (fp, "{\n");
7928 fprintf (fp, "\t%s;\n", gen_declaration (ivar_decls, buf));
7929 ivar_decls = TREE_CHAIN (ivar_decls);
7932 fprintf (fp, "}\n");
7937 fprintf (fp, "- %s;\n", gen_method_decl (nst_methods, buf));
7938 nst_methods = TREE_CHAIN (nst_methods);
7943 fprintf (fp, "+ %s;\n", gen_method_decl (cls_methods, buf));
7944 cls_methods = TREE_CHAIN (cls_methods);
7946 fprintf (fp, "\n@end");
7949 /* Demangle function for Objective-C */
7951 objc_demangle (mangled)
7952 const char *mangled;
7954 char *demangled, *cp;
7956 if (mangled[0] == '_' &&
7957 (mangled[1] == 'i' || mangled[1] == 'c') &&
7960 cp = demangled = xmalloc(strlen(mangled) + 2);
7961 if (mangled[1] == 'i')
7962 *cp++ = '-'; /* for instance method */
7964 *cp++ = '+'; /* for class method */
7965 *cp++ = '['; /* opening left brace */
7966 strcpy(cp, mangled+3); /* tack on the rest of the mangled name */
7967 while (*cp && *cp == '_')
7968 cp++; /* skip any initial underbars in class name */
7969 cp = strchr(cp, '_'); /* find first non-initial underbar */
7972 free(demangled); /* not mangled name */
7975 if (cp[1] == '_') /* easy case: no category name */
7977 *cp++ = ' '; /* replace two '_' with one ' ' */
7978 strcpy(cp, mangled + (cp - demangled) + 2);
7982 *cp++ = '('; /* less easy case: category name */
7983 cp = strchr(cp, '_');
7986 free(demangled); /* not mangled name */
7990 *cp++ = ' '; /* overwriting 1st char of method name... */
7991 strcpy(cp, mangled + (cp - demangled)); /* get it back */
7993 while (*cp && *cp == '_')
7994 cp++; /* skip any initial underbars in method name */
7997 *cp = ':'; /* replace remaining '_' with ':' */
7998 *cp++ = ']'; /* closing right brace */
7999 *cp++ = 0; /* string terminator */
8003 return mangled; /* not an objc mangled name */
8007 objc_printable_name (decl, kind)
8009 int kind ATTRIBUTE_UNUSED;
8011 return objc_demangle (IDENTIFIER_POINTER (DECL_NAME (decl)));
8017 gcc_obstack_init (&util_obstack);
8018 util_firstobj = (char *) obstack_finish (&util_obstack);
8020 errbuf = (char *) xmalloc (BUFSIZE);
8022 synth_module_prologue ();
8028 struct imp_entry *impent;
8030 /* The internally generated initializers appear to have missing braces.
8031 Don't warn about this. */
8032 int save_warn_missing_braces = warn_missing_braces;
8033 warn_missing_braces = 0;
8035 /* A missing @end may not be detected by the parser. */
8036 if (objc_implementation_context)
8038 warning ("`@end' missing in implementation context");
8039 finish_class (objc_implementation_context);
8040 objc_ivar_chain = NULL_TREE;
8041 objc_implementation_context = NULL_TREE;
8044 generate_forward_declaration_to_string_table ();
8046 #ifdef OBJC_PROLOGUE
8050 /* Process the static instances here because initialization of objc_symtab
8052 if (objc_static_instances)
8053 generate_static_references ();
8055 if (imp_list || class_names_chain
8056 || meth_var_names_chain || meth_var_types_chain || sel_ref_chain)
8057 generate_objc_symtab_decl ();
8059 for (impent = imp_list; impent; impent = impent->next)
8061 objc_implementation_context = impent->imp_context;
8062 implementation_template = impent->imp_template;
8064 UOBJC_CLASS_decl = impent->class_decl;
8065 UOBJC_METACLASS_decl = impent->meta_decl;
8067 if (TREE_CODE (objc_implementation_context) == CLASS_IMPLEMENTATION_TYPE)
8069 /* all of the following reference the string pool... */
8070 generate_ivar_lists ();
8071 generate_dispatch_tables ();
8072 generate_shared_structures ();
8076 generate_dispatch_tables ();
8077 generate_category (objc_implementation_context);
8081 /* If we are using an array of selectors, we must always
8082 finish up the array decl even if no selectors were used. */
8083 if (! flag_next_runtime || sel_ref_chain)
8084 build_selector_translation_table ();
8087 generate_protocols ();
8089 if (objc_implementation_context || class_names_chain || objc_static_instances
8090 || meth_var_names_chain || meth_var_types_chain || sel_ref_chain)
8092 /* Arrange for ObjC data structures to be initialized at run time. */
8093 rtx init_sym = build_module_descriptor ();
8094 if (init_sym && targetm.have_ctors_dtors)
8095 (* targetm.asm_out.constructor) (init_sym, DEFAULT_INIT_PRIORITY);
8098 /* Dump the class references. This forces the appropriate classes
8099 to be linked into the executable image, preserving unix archive
8100 semantics. This can be removed when we move to a more dynamically
8101 linked environment. */
8103 for (chain = cls_ref_chain; chain; chain = TREE_CHAIN (chain))
8105 handle_class_ref (chain);
8106 if (TREE_PURPOSE (chain))
8107 generate_classref_translation_entry (chain);
8110 for (impent = imp_list; impent; impent = impent->next)
8111 handle_impent (impent);
8113 /* Dump the string table last. */
8115 generate_strings ();
8117 if (flag_gen_declaration)
8119 add_class (objc_implementation_context);
8120 dump_interface (gen_declaration_file, objc_implementation_context);
8128 /* Run through the selector hash tables and print a warning for any
8129 selector which has multiple methods. */
8131 for (slot = 0; slot < SIZEHASHTABLE; slot++)
8132 for (hsh = cls_method_hash_list[slot]; hsh; hsh = hsh->next)
8135 tree meth = hsh->key;
8136 char type = (TREE_CODE (meth) == INSTANCE_METHOD_DECL
8140 warning ("potential selector conflict for method `%s'",
8141 IDENTIFIER_POINTER (METHOD_SEL_NAME (meth)));
8142 warn_with_method ("found", type, meth);
8143 for (loop = hsh->list; loop; loop = loop->next)
8144 warn_with_method ("found", type, loop->value);
8147 for (slot = 0; slot < SIZEHASHTABLE; slot++)
8148 for (hsh = nst_method_hash_list[slot]; hsh; hsh = hsh->next)
8151 tree meth = hsh->key;
8152 char type = (TREE_CODE (meth) == INSTANCE_METHOD_DECL
8156 warning ("potential selector conflict for method `%s'",
8157 IDENTIFIER_POINTER (METHOD_SEL_NAME (meth)));
8158 warn_with_method ("found", type, meth);
8159 for (loop = hsh->list; loop; loop = loop->next)
8160 warn_with_method ("found", type, loop->value);
8164 warn_missing_braces = save_warn_missing_braces;
8167 /* Subroutines of finish_objc. */
8170 generate_classref_translation_entry (chain)
8173 tree expr, name, decl_specs, decl, sc_spec;
8176 type = TREE_TYPE (TREE_PURPOSE (chain));
8178 expr = add_objc_string (TREE_VALUE (chain), class_names);
8179 expr = build_c_cast (type, expr); /* cast! */
8181 name = DECL_NAME (TREE_PURPOSE (chain));
8183 sc_spec = build_tree_list (NULL_TREE, ridpointers[(int) RID_STATIC]);
8185 /* static struct objc_class * _OBJC_CLASS_REFERENCES_n = ...; */
8186 decl_specs = tree_cons (NULL_TREE, type, sc_spec);
8188 /* The decl that is returned from start_decl is the one that we
8189 forward declared in build_class_reference. */
8190 decl = start_decl (name, decl_specs, 1, NULL_TREE);
8191 DECL_CONTEXT (decl) = NULL_TREE;
8192 finish_decl (decl, expr, NULL_TREE);
8197 handle_class_ref (chain)
8200 const char *name = IDENTIFIER_POINTER (TREE_VALUE (chain));
8201 char *string = (char *) alloca (strlen (name) + 30);
8205 sprintf (string, "%sobjc_class_name_%s",
8206 (flag_next_runtime ? "." : "__"), name);
8208 #ifdef ASM_DECLARE_UNRESOLVED_REFERENCE
8209 if (flag_next_runtime)
8211 ASM_DECLARE_UNRESOLVED_REFERENCE (asm_out_file, string);
8216 /* Make a decl for this name, so we can use its address in a tree. */
8217 decl = build_decl (VAR_DECL, get_identifier (string), char_type_node);
8218 DECL_EXTERNAL (decl) = 1;
8219 TREE_PUBLIC (decl) = 1;
8222 rest_of_decl_compilation (decl, 0, 0, 0);
8224 /* Make a decl for the address. */
8225 sprintf (string, "%sobjc_class_ref_%s",
8226 (flag_next_runtime ? "." : "__"), name);
8227 exp = build1 (ADDR_EXPR, string_type_node, decl);
8228 decl = build_decl (VAR_DECL, get_identifier (string), string_type_node);
8229 DECL_INITIAL (decl) = exp;
8230 TREE_STATIC (decl) = 1;
8231 TREE_USED (decl) = 1;
8234 rest_of_decl_compilation (decl, 0, 0, 0);
8238 handle_impent (impent)
8239 struct imp_entry *impent;
8243 objc_implementation_context = impent->imp_context;
8244 implementation_template = impent->imp_template;
8246 if (TREE_CODE (impent->imp_context) == CLASS_IMPLEMENTATION_TYPE)
8248 const char *const class_name =
8249 IDENTIFIER_POINTER (CLASS_NAME (impent->imp_context));
8251 string = (char *) alloca (strlen (class_name) + 30);
8253 sprintf (string, "%sobjc_class_name_%s",
8254 (flag_next_runtime ? "." : "__"), class_name);
8256 else if (TREE_CODE (impent->imp_context) == CATEGORY_IMPLEMENTATION_TYPE)
8258 const char *const class_name =
8259 IDENTIFIER_POINTER (CLASS_NAME (impent->imp_context));
8260 const char *const class_super_name =
8261 IDENTIFIER_POINTER (CLASS_SUPER_NAME (impent->imp_context));
8263 string = (char *) alloca (strlen (class_name)
8264 + strlen (class_super_name) + 30);
8266 /* Do the same for categories. Even though no references to
8267 these symbols are generated automatically by the compiler, it
8268 gives you a handle to pull them into an archive by hand. */
8269 sprintf (string, "*%sobjc_category_name_%s_%s",
8270 (flag_next_runtime ? "." : "__"), class_name, class_super_name);
8275 #ifdef ASM_DECLARE_CLASS_REFERENCE
8276 if (flag_next_runtime)
8278 ASM_DECLARE_CLASS_REFERENCE (asm_out_file, string);
8286 init = build_int_2 (0, 0);
8287 TREE_TYPE (init) = c_common_type_for_size (BITS_PER_WORD, 1);
8288 decl = build_decl (VAR_DECL, get_identifier (string), TREE_TYPE (init));
8289 TREE_PUBLIC (decl) = 1;
8290 TREE_READONLY (decl) = 1;
8291 TREE_USED (decl) = 1;
8292 TREE_CONSTANT (decl) = 1;
8293 DECL_CONTEXT (decl) = 0;
8294 DECL_ARTIFICIAL (decl) = 1;
8295 DECL_INITIAL (decl) = init;
8296 assemble_variable (decl, 1, 0, 0);
8300 /* Look up ID as an instance variable. */
8302 lookup_objc_ivar (id)
8307 if (objc_receiver_context && !strcmp (IDENTIFIER_POINTER (id), "super"))
8308 /* we have a message to super */
8309 return get_super_receiver ();
8310 else if (objc_method_context && (decl = is_ivar (objc_ivar_chain, id)))
8312 if (is_private (decl))
8313 return error_mark_node;
8315 return build_ivar_reference (id);
8321 #include "gtype-objc.h"