1 /* Implement classes and message passing for Objective C.
2 Copyright (C) 1992, 1993, 1994, 1995 Free Software Foundation, Inc.
3 Contributed by Steve Naroff.
5 This file is part of GNU CC.
7 GNU CC is free software; you can redistribute it and/or modify
8 it under the terms of the GNU General Public License as published by
9 the Free Software Foundation; either version 2, or (at your option)
12 GNU CC is distributed in the hope that it will be useful,
13 but WITHOUT ANY WARRANTY; without even the implied warranty of
14 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
15 GNU General Public License for more details.
17 You should have received a copy of the GNU General Public License
18 along with GNU CC; see the file COPYING. If not, write to
19 the Free Software Foundation, 59 Temple Place - Suite 330,
20 Boston, MA 02111-1307, USA. */
22 /* Purpose: This module implements the Objective-C 4.0 language.
24 compatibility issues (with the Stepstone translator):
26 - does not recognize the following 3.3 constructs.
27 @requires, @classes, @messages, = (...)
28 - methods with variable arguments must conform to ANSI standard.
29 - tagged structure definitions that appear in BOTH the interface
30 and implementation are not allowed.
31 - public/private: all instance variables are public within the
32 context of the implementation...I consider this to be a bug in
34 - statically allocated objects are not supported. the user will
35 receive an error if this service is requested.
37 code generation `options':
39 - OBJC_INT_SELECTORS */
52 /* This is the default way of generating a method name. */
53 /* I am not sure it is really correct.
54 Perhaps there's a danger that it will make name conflicts
55 if method names contain underscores. -- rms. */
56 #ifndef OBJC_GEN_METHOD_LABEL
57 #define OBJC_GEN_METHOD_LABEL(BUF, IS_INST, CLASS_NAME, CAT_NAME, SEL_NAME, NUM) \
60 sprintf ((BUF), "_%s_%s_%s_%s", \
61 ((IS_INST) ? "i" : "c"), \
63 ((CAT_NAME)? (CAT_NAME) : ""), \
65 for (temp = (BUF); *temp; temp++) \
66 if (*temp == ':') *temp = '_'; \
70 /* These need specifying. */
71 #ifndef OBJC_FORWARDING_STACK_OFFSET
72 #define OBJC_FORWARDING_STACK_OFFSET 0
75 #ifndef OBJC_FORWARDING_MIN_OFFSET
76 #define OBJC_FORWARDING_MIN_OFFSET 0
79 /* Define the special tree codes that we use. */
81 /* Table indexed by tree code giving a string containing a character
82 classifying the tree code. Possibilities are
83 t, d, s, c, r, <, 1 and 2. See objc-tree.def for details. */
85 #define DEFTREECODE(SYM, NAME, TYPE, LENGTH) TYPE,
87 char *objc_tree_code_type[] = {
89 #include "objc-tree.def"
93 /* Table indexed by tree code giving number of expression
94 operands beyond the fixed part of the node structure.
95 Not used for types or decls. */
97 #define DEFTREECODE(SYM, NAME, TYPE, LENGTH) LENGTH,
99 int objc_tree_code_length[] = {
101 #include "objc-tree.def"
105 /* Names of tree components.
106 Used for printing out the tree and error messages. */
107 #define DEFTREECODE(SYM, NAME, TYPE, LEN) NAME,
109 char *objc_tree_code_name[] = {
111 #include "objc-tree.def"
115 /* Set up for use of obstacks. */
119 #define obstack_chunk_alloc xmalloc
120 #define obstack_chunk_free free
122 /* This obstack is used to accumulate the encoding of a data type. */
123 static struct obstack util_obstack;
124 /* This points to the beginning of obstack contents,
125 so we can free the whole contents. */
128 /* List of classes with list of their static instances. */
129 static tree objc_static_instances;
131 /* The declaration of the array administrating the static instances. */
132 static tree static_instances_decl;
134 /* for encode_method_def */
138 #define OBJC_VERSION (flag_next_runtime ? 5 : 7)
139 #define PROTOCOL_VERSION 2
141 #define OBJC_ENCODE_INLINE_DEFS 0
142 #define OBJC_ENCODE_DONT_INLINE_DEFS 1
144 /*** Private Interface (procedures) ***/
146 /* Used by compile_file. */
148 static void init_objc PROTO((void));
149 static void finish_objc PROTO((void));
151 /* Code generation. */
153 static void synth_module_prologue PROTO((void));
154 static tree build_constructor PROTO((tree, tree));
155 static char *build_module_descriptor PROTO((void));
156 static tree init_module_descriptor PROTO((tree));
157 static tree build_objc_method_call PROTO((int, tree, tree,
159 static void generate_strings PROTO((void));
160 static tree get_proto_encoding PROTO((tree));
161 static void build_selector_translation_table PROTO((void));
162 static tree build_ivar_chain PROTO((tree, int));
164 static tree objc_add_static_instance PROTO((tree, tree));
166 static tree build_ivar_template PROTO((void));
167 static tree build_method_template PROTO((void));
168 static tree build_private_template PROTO((tree));
169 static void build_class_template PROTO((void));
170 static void build_selector_template PROTO((void));
171 static void build_category_template PROTO((void));
172 static tree build_super_template PROTO((void));
173 static tree build_category_initializer PROTO((tree, tree, tree,
175 static tree build_protocol_initializer PROTO((tree, tree, tree,
178 static void synth_forward_declarations PROTO((void));
179 static void generate_ivar_lists PROTO((void));
180 static void generate_dispatch_tables PROTO((void));
181 static void generate_shared_structures PROTO((void));
182 static tree generate_protocol_list PROTO((tree));
183 static void generate_forward_declaration_to_string_table PROTO((void));
184 static void build_protocol_reference PROTO((tree));
186 static tree init_selector PROTO((int));
187 static tree build_keyword_selector PROTO((tree));
188 static tree synth_id_with_class_suffix PROTO((char *, tree));
191 extern int apply_args_register_offset PROTO((int));
193 /* Misc. bookkeeping */
195 typedef struct hashed_entry *hash;
196 typedef struct hashed_attribute *attr;
198 struct hashed_attribute
210 static void hash_init PROTO((void));
211 static void hash_enter PROTO((hash *, tree));
212 static hash hash_lookup PROTO((hash *, tree));
213 static void hash_add_attr PROTO((hash, tree));
214 static tree lookup_method PROTO((tree, tree));
215 static tree lookup_instance_method_static PROTO((tree, tree));
216 static tree lookup_class_method_static PROTO((tree, tree));
217 static tree add_class PROTO((tree));
218 static void add_category PROTO((tree, tree));
222 class_names, /* class, category, protocol, module names */
223 meth_var_names, /* method and variable names */
224 meth_var_types /* method and variable type descriptors */
227 static tree add_objc_string PROTO((tree,
228 enum string_section));
229 static tree build_objc_string_decl PROTO((tree,
230 enum string_section));
231 static tree build_selector_reference_decl PROTO((tree));
233 /* Protocol additions. */
235 static tree add_protocol PROTO((tree));
236 static tree lookup_protocol PROTO((tree));
237 static tree lookup_and_install_protocols PROTO((tree));
241 static void encode_type_qualifiers PROTO((tree));
242 static void encode_pointer PROTO((tree, int, int));
243 static void encode_array PROTO((tree, int, int));
244 static void encode_aggregate PROTO((tree, int, int));
245 static void encode_bitfield PROTO((int, int));
246 static void encode_type PROTO((tree, int, int));
247 static void encode_field_decl PROTO((tree, int, int));
249 static void really_start_method PROTO((tree, tree));
250 static int comp_method_with_proto PROTO((tree, tree));
251 static int comp_proto_with_proto PROTO((tree, tree));
252 static tree get_arg_type_list PROTO((tree, int, int));
253 static tree expr_last PROTO((tree));
255 /* Utilities for debugging and error diagnostics. */
257 static void warn_with_method PROTO((char *, int, tree));
258 static void error_with_ivar PROTO((char *, tree, tree));
259 static char *gen_method_decl PROTO((tree, char *));
260 static char *gen_declaration PROTO((tree, char *));
261 static char *gen_declarator PROTO((tree, char *, char *));
262 static int is_complex_decl PROTO((tree));
263 static void adorn_decl PROTO((tree, char *));
264 static void dump_interface PROTO((FILE *, tree));
266 /* Everything else. */
268 static void objc_fatal PROTO((void));
269 static tree define_decl PROTO((tree, tree));
270 static tree lookup_method_in_protocol_list PROTO((tree, tree, int));
271 static tree lookup_protocol_in_reflist PROTO((tree, tree));
272 static tree create_builtin_decl PROTO((enum tree_code,
274 static tree my_build_string PROTO((int, char *));
275 static void build_objc_symtab_template PROTO((void));
276 static tree init_def_list PROTO((tree));
277 static tree init_objc_symtab PROTO((tree));
278 static void forward_declare_categories PROTO((void));
279 static void generate_objc_symtab_decl PROTO((void));
280 static tree build_selector PROTO((tree));
281 static tree build_msg_pool_reference PROTO((int));
282 static tree build_typed_selector_reference PROTO((tree, tree));
283 static tree build_selector_reference PROTO((tree));
284 static tree build_class_reference_decl PROTO((tree));
285 static void add_class_reference PROTO((tree));
286 static tree objc_copy_list PROTO((tree, tree *));
287 static tree build_protocol_template PROTO((void));
288 static tree build_descriptor_table_initializer PROTO((tree, tree));
289 static tree build_method_prototype_list_template PROTO((tree, int));
290 static tree build_method_prototype_template PROTO((void));
291 static int forwarding_offset PROTO((tree));
292 static tree encode_method_prototype PROTO((tree, tree));
293 static tree generate_descriptor_table PROTO((tree, char *, int, tree, tree));
294 static void generate_method_descriptors PROTO((tree));
295 static tree build_tmp_function_decl PROTO((void));
296 static void hack_method_prototype PROTO((tree, tree));
297 static void generate_protocol_references PROTO((tree));
298 static void generate_protocols PROTO((void));
299 static void check_ivars PROTO((tree, tree));
300 static tree build_ivar_list_template PROTO((tree, int));
301 static tree build_method_list_template PROTO((tree, int));
302 static tree build_ivar_list_initializer PROTO((tree, tree));
303 static tree generate_ivars_list PROTO((tree, char *,
305 static tree build_dispatch_table_initializer PROTO((tree, tree));
306 static tree generate_dispatch_table PROTO((tree, char *,
308 static tree build_shared_structure_initializer PROTO((tree, tree, tree, tree,
309 tree, int, tree, tree,
311 static void generate_category PROTO((tree));
312 static int is_objc_type_qualifier PROTO((tree));
313 static tree adjust_type_for_id_default PROTO((tree));
314 static tree check_duplicates PROTO((hash));
315 static tree receiver_is_class_object PROTO((tree));
316 static int check_methods PROTO((tree, tree, int));
317 static int conforms_to_protocol PROTO((tree, tree));
318 static void check_protocols PROTO((tree, char *, char *));
319 static tree encode_method_def PROTO((tree));
320 static void gen_declspecs PROTO((tree, char *, int));
321 static void generate_classref_translation_entry PROTO((tree));
322 static void handle_class_ref PROTO((tree));
324 /*** Private Interface (data) ***/
326 /* Reserved tag definitions. */
329 #define TAG_OBJECT "objc_object"
330 #define TAG_CLASS "objc_class"
331 #define TAG_SUPER "objc_super"
332 #define TAG_SELECTOR "objc_selector"
334 #define UTAG_CLASS "_objc_class"
335 #define UTAG_IVAR "_objc_ivar"
336 #define UTAG_IVAR_LIST "_objc_ivar_list"
337 #define UTAG_METHOD "_objc_method"
338 #define UTAG_METHOD_LIST "_objc_method_list"
339 #define UTAG_CATEGORY "_objc_category"
340 #define UTAG_MODULE "_objc_module"
341 #define UTAG_STATICS "_objc_statics"
342 #define UTAG_SYMTAB "_objc_symtab"
343 #define UTAG_SUPER "_objc_super"
344 #define UTAG_SELECTOR "_objc_selector"
346 #define UTAG_PROTOCOL "_objc_protocol"
347 #define UTAG_PROTOCOL_LIST "_objc_protocol_list"
348 #define UTAG_METHOD_PROTOTYPE "_objc_method_prototype"
349 #define UTAG_METHOD_PROTOTYPE_LIST "_objc__method_prototype_list"
351 #define STRING_OBJECT_CLASS_NAME "NXConstantString"
352 #define PROTOCOL_OBJECT_CLASS_NAME "Protocol"
354 static char *TAG_GETCLASS;
355 static char *TAG_GETMETACLASS;
356 static char *TAG_MSGSEND;
357 static char *TAG_MSGSENDSUPER;
358 static char *TAG_EXECCLASS;
360 /* Set by `continue_class' and checked by `is_public'. */
362 #define TREE_STATIC_TEMPLATE(record_type) (TREE_PUBLIC (record_type))
363 #define TYPED_OBJECT(type) \
364 (TREE_CODE (type) == RECORD_TYPE && TREE_STATIC_TEMPLATE (type))
366 /* Some commonly used instances of "identifier_node". */
368 static tree self_id, ucmd_id;
369 static tree unused_list;
371 static tree self_decl, umsg_decl, umsg_super_decl;
372 static tree objc_get_class_decl, objc_get_meta_class_decl;
374 static tree super_type, selector_type, id_type, objc_class_type;
375 static tree instance_type, protocol_type;
377 /* Type checking macros. */
379 #define IS_ID(TYPE) \
380 (TYPE_MAIN_VARIANT (TYPE) == TYPE_MAIN_VARIANT (id_type))
381 #define IS_PROTOCOL_QUALIFIED_ID(TYPE) \
382 (IS_ID (TYPE) && TYPE_PROTOCOL_LIST (TYPE))
383 #define IS_SUPER(TYPE) \
384 (super_type && TYPE_MAIN_VARIANT (TYPE) == TYPE_MAIN_VARIANT (super_type))
386 static tree class_chain = NULL_TREE;
387 static tree alias_chain = NULL_TREE;
388 static tree interface_chain = NULL_TREE;
389 static tree protocol_chain = NULL_TREE;
391 /* Chains to manage selectors that are referenced and defined in the module. */
393 static tree cls_ref_chain = NULL_TREE; /* Classes referenced. */
394 static tree sel_ref_chain = NULL_TREE; /* Selectors referenced. */
396 /* Chains to manage uniquing of strings. */
398 static tree class_names_chain = NULL_TREE;
399 static tree meth_var_names_chain = NULL_TREE;
400 static tree meth_var_types_chain = NULL_TREE;
402 /* Hash tables to manage the global pool of method prototypes. */
404 static hash *nst_method_hash_list = 0;
405 static hash *cls_method_hash_list = 0;
407 /* Backend data declarations. */
409 static tree UOBJC_SYMBOLS_decl;
410 static tree UOBJC_INSTANCE_VARIABLES_decl, UOBJC_CLASS_VARIABLES_decl;
411 static tree UOBJC_INSTANCE_METHODS_decl, UOBJC_CLASS_METHODS_decl;
412 static tree UOBJC_CLASS_decl, UOBJC_METACLASS_decl;
413 static tree UOBJC_SELECTOR_TABLE_decl;
414 static tree UOBJC_MODULES_decl;
415 static tree UOBJC_STRINGS_decl;
417 /* The following are used when compiling a class implementation.
418 implementation_template will normally be an interface, however if
419 none exists this will be equal to implementation_context...it is
420 set in start_class. */
422 static tree implementation_context = NULL_TREE;
423 static tree implementation_template = NULL_TREE;
427 struct imp_entry *next;
430 tree class_decl; /* _OBJC_CLASS_<my_name>; */
431 tree meta_decl; /* _OBJC_METACLASS_<my_name>; */
434 static void handle_impent PROTO((struct imp_entry *));
436 static struct imp_entry *imp_list = 0;
437 static int imp_count = 0; /* `@implementation' */
438 static int cat_count = 0; /* `@category' */
440 static tree objc_class_template, objc_category_template, uprivate_record;
441 static tree objc_protocol_template, objc_selector_template;
442 static tree ucls_super_ref, uucls_super_ref;
444 static tree objc_method_template, objc_ivar_template;
445 static tree objc_symtab_template, objc_module_template;
446 static tree objc_super_template, objc_object_reference;
448 static tree objc_object_id, objc_class_id, objc_id_id;
449 static tree constant_string_id;
450 static tree constant_string_type;
451 static tree UOBJC_SUPER_decl;
453 static tree method_context = NULL_TREE;
454 static int method_slot = 0; /* Used by start_method_def, */
458 static char *errbuf; /* Buffer for error diagnostics */
460 /* Data imported from tree.c. */
462 extern enum debug_info_type write_symbols;
464 /* Data imported from toplev.c. */
466 extern char *dump_base_name;
468 /* Generate code for GNU or NeXT runtime environment. */
470 #ifdef NEXT_OBJC_RUNTIME
471 int flag_next_runtime = 1;
473 int flag_next_runtime = 0;
476 int flag_typed_selectors;
478 /* Open and close the file for outputting class declarations, if requested. */
480 int flag_gen_declaration = 0;
482 FILE *gen_declaration_file;
484 /* Warn if multiple methods are seen for the same selector, but with
485 different argument types. */
487 int warn_selector = 0;
489 /* Warn if methods required by a protocol are not implemented in the
490 class adopting it. When turned off, methods inherited to that
491 class are also considered implemented */
493 int flag_warn_protocol = 1;
495 /* Tells "encode_pointer/encode_aggregate" whether we are generating
496 type descriptors for instance variables (as opposed to methods).
497 Type descriptors for instance variables contain more information
498 than methods (for static typing and embedded structures). This
499 was added to support features being planned for dbkit2. */
501 static int generating_instance_variables = 0;
506 /* The beginning of the file is a new line; check for #.
507 With luck, we discover the real source file's name from that
508 and put it in input_filename. */
509 ungetc (check_newline (), finput);
511 /* The line number can be -1 if we had -g3 and the input file
512 had a directive specifying line 0. But we want predefined
513 functions to have a line number of 0, not -1. */
517 /* If gen_declaration desired, open the output file. */
518 if (flag_gen_declaration)
520 int dump_base_name_length = strlen (dump_base_name);
521 register char *dumpname = (char *) xmalloc (dump_base_name_length + 7);
522 strcpy (dumpname, dump_base_name);
523 strcat (dumpname, ".decl");
524 gen_declaration_file = fopen (dumpname, "w");
525 if (gen_declaration_file == 0)
526 pfatal_with_name (dumpname);
529 if (flag_next_runtime)
531 TAG_GETCLASS = "objc_getClass";
532 TAG_GETMETACLASS = "objc_getMetaClass";
533 TAG_MSGSEND = "objc_msgSend";
534 TAG_MSGSENDSUPER = "objc_msgSendSuper";
535 TAG_EXECCLASS = "__objc_execClass";
539 TAG_GETCLASS = "objc_get_class";
540 TAG_GETMETACLASS = "objc_get_meta_class";
541 TAG_MSGSEND = "objc_msg_lookup";
542 TAG_MSGSENDSUPER = "objc_msg_lookup_super";
543 TAG_EXECCLASS = "__objc_exec_class";
544 flag_typed_selectors = 1;
547 if (doing_objc_thang)
554 fatal ("Objective-C text in C source file");
560 if (doing_objc_thang)
561 finish_objc (); /* Objective-C finalization */
563 if (gen_declaration_file)
564 fclose (gen_declaration_file);
579 lang_decode_option (p)
582 if (!strcmp (p, "-lang-objc"))
583 doing_objc_thang = 1;
584 else if (!strcmp (p, "-gen-decls"))
585 flag_gen_declaration = 1;
586 else if (!strcmp (p, "-Wselector"))
588 else if (!strcmp (p, "-Wno-selector"))
590 else if (!strcmp (p, "-Wprotocol"))
591 flag_warn_protocol = 1;
592 else if (!strcmp (p, "-Wno-protocol"))
593 flag_warn_protocol = 0;
594 else if (!strcmp (p, "-fgnu-runtime"))
595 flag_next_runtime = 0;
596 else if (!strcmp (p, "-fno-next-runtime"))
597 flag_next_runtime = 0;
598 else if (!strcmp (p, "-fno-gnu-runtime"))
599 flag_next_runtime = 1;
600 else if (!strcmp (p, "-fnext-runtime"))
601 flag_next_runtime = 1;
603 return c_decode_option (p);
609 define_decl (declarator, declspecs)
613 tree decl = start_decl (declarator, declspecs, 0, NULL_TREE, NULL_TREE);
614 finish_decl (decl, NULL_TREE, NULL_TREE);
618 /* Return 1 if LHS and RHS are compatible types for assignment or
619 various other operations. Return 0 if they are incompatible, and
620 return -1 if we choose to not decide. When the operation is
621 REFLEXIVE, check for compatibility in either direction.
623 For statically typed objects, an assignment of the form `a' = `b'
627 `a' and `b' are the same class type, or
628 `a' and `b' are of class types A and B such that B is a descendant of A. */
631 maybe_objc_comptypes (lhs, rhs, reflexive)
635 if (doing_objc_thang)
636 return objc_comptypes (lhs, rhs, reflexive);
641 lookup_method_in_protocol_list (rproto_list, sel_name, class_meth)
649 for (rproto = rproto_list; rproto; rproto = TREE_CHAIN (rproto))
651 p = TREE_VALUE (rproto);
653 if (TREE_CODE (p) == PROTOCOL_INTERFACE_TYPE)
655 if ((fnd = lookup_method (class_meth
656 ? PROTOCOL_CLS_METHODS (p)
657 : PROTOCOL_NST_METHODS (p), sel_name)))
659 else if (PROTOCOL_LIST (p))
660 fnd = lookup_method_in_protocol_list (PROTOCOL_LIST (p),
661 sel_name, class_meth);
664 ; /* An identifier...if we could not find a protocol. */
674 lookup_protocol_in_reflist (rproto_list, lproto)
680 /* Make sure the protocol is support by the object on the rhs. */
681 if (TREE_CODE (lproto) == PROTOCOL_INTERFACE_TYPE)
684 for (rproto = rproto_list; rproto; rproto = TREE_CHAIN (rproto))
686 p = TREE_VALUE (rproto);
688 if (TREE_CODE (p) == PROTOCOL_INTERFACE_TYPE)
693 else if (PROTOCOL_LIST (p))
694 fnd = lookup_protocol_in_reflist (PROTOCOL_LIST (p), lproto);
702 ; /* An identifier...if we could not find a protocol. */
707 /* Return 1 if LHS and RHS are compatible types for assignment
708 or various other operations. Return 0 if they are incompatible,
709 and return -1 if we choose to not decide. When the operation
710 is REFLEXIVE, check for compatibility in either direction. */
713 objc_comptypes (lhs, rhs, reflexive)
718 /* New clause for protocols. */
720 if (TREE_CODE (lhs) == POINTER_TYPE
721 && TREE_CODE (TREE_TYPE (lhs)) == RECORD_TYPE
722 && TREE_CODE (rhs) == POINTER_TYPE
723 && TREE_CODE (TREE_TYPE (rhs)) == RECORD_TYPE)
725 int lhs_is_proto = IS_PROTOCOL_QUALIFIED_ID (lhs);
726 int rhs_is_proto = IS_PROTOCOL_QUALIFIED_ID (rhs);
730 tree lproto, lproto_list = TYPE_PROTOCOL_LIST (lhs);
731 tree rproto, rproto_list;
736 rproto_list = TYPE_PROTOCOL_LIST (rhs);
738 /* Make sure the protocol is supported by the object
740 for (lproto = lproto_list; lproto; lproto = TREE_CHAIN (lproto))
742 p = TREE_VALUE (lproto);
743 rproto = lookup_protocol_in_reflist (rproto_list, p);
746 warning ("object does not conform to the `%s' protocol",
747 IDENTIFIER_POINTER (PROTOCOL_NAME (p)));
750 else if (TYPED_OBJECT (TREE_TYPE (rhs)))
752 tree rname = TYPE_NAME (TREE_TYPE (rhs));
755 /* Make sure the protocol is supported by the object
757 for (lproto = lproto_list; lproto; lproto = TREE_CHAIN (lproto))
759 p = TREE_VALUE (lproto);
761 rinter = lookup_interface (rname);
763 while (rinter && !rproto)
767 rproto_list = CLASS_PROTOCOL_LIST (rinter);
768 rproto = lookup_protocol_in_reflist (rproto_list, p);
770 /* Check for protocols adopted by categories. */
771 cat = CLASS_CATEGORY_LIST (rinter);
772 while (cat && !rproto)
774 rproto_list = CLASS_PROTOCOL_LIST (cat);
775 rproto = lookup_protocol_in_reflist (rproto_list, p);
777 cat = CLASS_CATEGORY_LIST (cat);
780 rinter = lookup_interface (CLASS_SUPER_NAME (rinter));
784 warning ("class `%s' does not implement the `%s' protocol",
785 IDENTIFIER_POINTER (TYPE_NAME (TREE_TYPE (rhs))),
786 IDENTIFIER_POINTER (PROTOCOL_NAME (p)));
790 /* May change...based on whether there was any mismatch */
793 else if (rhs_is_proto)
794 /* Lhs is not a protocol...warn if it is statically typed */
795 return (TYPED_OBJECT (TREE_TYPE (lhs)) != 0);
798 /* Defer to comptypes .*/
802 else if (TREE_CODE (lhs) == RECORD_TYPE && TREE_CODE (rhs) == RECORD_TYPE)
803 ; /* Fall thru. This is the case we have been handling all along */
805 /* Defer to comptypes. */
808 /* `id' = `<class> *', `<class> *' = `id' */
810 if ((TYPE_NAME (lhs) == objc_object_id && TYPED_OBJECT (rhs))
811 || (TYPE_NAME (rhs) == objc_object_id && TYPED_OBJECT (lhs)))
814 /* `id' = `Class', `Class' = `id' */
816 else if ((TYPE_NAME (lhs) == objc_object_id
817 && TYPE_NAME (rhs) == objc_class_id)
818 || (TYPE_NAME (lhs) == objc_class_id
819 && TYPE_NAME (rhs) == objc_object_id))
822 /* `<class> *' = `<class> *' */
824 else if (TYPED_OBJECT (lhs) && TYPED_OBJECT (rhs))
826 tree lname = TYPE_NAME (lhs);
827 tree rname = TYPE_NAME (rhs);
833 /* If the left hand side is a super class of the right hand side,
835 for (inter = lookup_interface (rname); inter;
836 inter = lookup_interface (CLASS_SUPER_NAME (inter)))
837 if (lname == CLASS_SUPER_NAME (inter))
840 /* Allow the reverse when reflexive. */
842 for (inter = lookup_interface (lname); inter;
843 inter = lookup_interface (CLASS_SUPER_NAME (inter)))
844 if (rname == CLASS_SUPER_NAME (inter))
850 /* Defer to comptypes. */
854 /* Called from c-decl.c before all calls to rest_of_decl_compilation. */
857 objc_check_decl (decl)
860 tree type = TREE_TYPE (decl);
862 if (TREE_CODE (type) == RECORD_TYPE
863 && TREE_STATIC_TEMPLATE (type)
864 && type != constant_string_type)
866 error_with_decl (decl, "`%s' cannot be statically allocated");
867 fatal ("statically allocated objects not supported");
872 maybe_objc_check_decl (decl)
875 if (doing_objc_thang)
876 objc_check_decl (decl);
879 /* Implement static typing. At this point, we know we have an interface. */
882 get_static_reference (interface, protocols)
886 tree type = xref_tag (RECORD_TYPE, interface);
890 tree t, m = TYPE_MAIN_VARIANT (type);
892 push_obstacks_nochange ();
893 end_temporary_allocation ();
894 t = copy_node (type);
895 TYPE_BINFO (t) = make_tree_vec (2);
898 /* Add this type to the chain of variants of TYPE. */
899 TYPE_NEXT_VARIANT (t) = TYPE_NEXT_VARIANT (m);
900 TYPE_NEXT_VARIANT (m) = t;
902 /* Look up protocols and install in lang specific list. */
903 TYPE_PROTOCOL_LIST (t) = lookup_and_install_protocols (protocols);
905 /* This forces a new pointer type to be created later
906 (in build_pointer_type)...so that the new template
907 we just created will actually be used...what a hack! */
908 if (TYPE_POINTER_TO (t))
909 TYPE_POINTER_TO (t) = 0;
918 get_object_reference (protocols)
921 tree type_decl = lookup_name (objc_id_id);
924 if (type_decl && TREE_CODE (type_decl) == TYPE_DECL)
926 type = TREE_TYPE (type_decl);
927 if (TYPE_MAIN_VARIANT (type) != id_type)
928 warning ("Unexpected type for `id' (%s)",
929 gen_declaration (type, errbuf));
932 fatal ("Undefined type `id', please import <objc/objc.h>");
934 /* This clause creates a new pointer type that is qualified with
935 the protocol specification...this info is used later to do more
936 elaborate type checking. */
940 tree t, m = TYPE_MAIN_VARIANT (type);
942 push_obstacks_nochange ();
943 end_temporary_allocation ();
944 t = copy_node (type);
945 TYPE_BINFO (t) = make_tree_vec (2);
948 /* Add this type to the chain of variants of TYPE. */
949 TYPE_NEXT_VARIANT (t) = TYPE_NEXT_VARIANT (m);
950 TYPE_NEXT_VARIANT (m) = t;
952 /* Look up protocols...and install in lang specific list */
953 TYPE_PROTOCOL_LIST (t) = lookup_and_install_protocols (protocols);
955 /* This forces a new pointer type to be created later
956 (in build_pointer_type)...so that the new template
957 we just created will actually be used...what a hack! */
958 if (TYPE_POINTER_TO (t))
959 TYPE_POINTER_TO (t) = NULL;
967 lookup_and_install_protocols (protocols)
972 tree return_value = protocols;
974 for (proto = protocols; proto; proto = TREE_CHAIN (proto))
976 tree ident = TREE_VALUE (proto);
977 tree p = lookup_protocol (ident);
981 error ("Cannot find protocol declaration for `%s'",
982 IDENTIFIER_POINTER (ident));
984 TREE_CHAIN (prev) = TREE_CHAIN (proto);
986 return_value = TREE_CHAIN (proto);
990 /* Replace identifier with actual protocol node. */
991 TREE_VALUE (proto) = p;
999 /* Create and push a decl for a built-in external variable or field NAME.
1001 TYPE is its data type. */
1004 create_builtin_decl (code, type, name)
1005 enum tree_code code;
1009 tree decl = build_decl (code, get_identifier (name), type);
1011 if (code == VAR_DECL)
1013 TREE_STATIC (decl) = 1;
1014 make_decl_rtl (decl, 0, 1);
1018 DECL_ARTIFICIAL (decl) = 1;
1022 /* Purpose: "play" parser, creating/installing representations
1023 of the declarations that are required by Objective-C.
1027 type_spec--------->sc_spec
1028 (tree_list) (tree_list)
1031 identifier_node identifier_node */
1034 synth_module_prologue ()
1039 /* Defined in `objc.h' */
1040 objc_object_id = get_identifier (TAG_OBJECT);
1042 objc_object_reference = xref_tag (RECORD_TYPE, objc_object_id);
1044 id_type = build_pointer_type (objc_object_reference);
1046 objc_id_id = get_identifier (TYPE_ID);
1047 objc_class_id = get_identifier (TAG_CLASS);
1049 objc_class_type = build_pointer_type (xref_tag (RECORD_TYPE, objc_class_id));
1050 protocol_type = build_pointer_type (xref_tag (RECORD_TYPE,
1051 get_identifier (PROTOCOL_OBJECT_CLASS_NAME)));
1053 /* Declare type of selector-objects that represent an operation name. */
1055 #ifdef OBJC_INT_SELECTORS
1056 /* `unsigned int' */
1057 selector_type = unsigned_type_node;
1059 /* `struct objc_selector *' */
1061 = build_pointer_type (xref_tag (RECORD_TYPE,
1062 get_identifier (TAG_SELECTOR)));
1063 #endif /* not OBJC_INT_SELECTORS */
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 if (flag_traditional && TAG_MSGSEND[0] != '_')
1090 DECL_BUILT_IN_NONANSI (umsg_decl) = 1;
1092 make_decl_rtl (umsg_decl, NULL_PTR, 1);
1093 pushdecl (umsg_decl);
1096 umsg_decl = builtin_function (TAG_MSGSEND, temp_type, NOT_BUILT_IN, 0);
1098 /* id objc_msgSendSuper (struct objc_super *, SEL, ...); */
1101 = build_function_type (id_type,
1102 tree_cons (NULL_TREE, super_p,
1103 tree_cons (NULL_TREE, selector_type,
1106 umsg_super_decl = builtin_function (TAG_MSGSENDSUPER,
1107 temp_type, NOT_BUILT_IN, 0);
1109 /* id objc_getClass (const char *); */
1111 temp_type = build_function_type (id_type,
1112 tree_cons (NULL_TREE,
1113 const_string_type_node,
1114 tree_cons (NULL_TREE, void_type_node,
1118 = builtin_function (TAG_GETCLASS, temp_type, NOT_BUILT_IN, 0);
1120 /* id objc_getMetaClass (const char *); */
1122 objc_get_meta_class_decl
1123 = builtin_function (TAG_GETMETACLASS, temp_type, NOT_BUILT_IN, 0);
1125 /* static SEL _OBJC_SELECTOR_TABLE[]; */
1127 if (! flag_next_runtime)
1129 if (flag_typed_selectors)
1131 /* Suppress outputting debug symbols, because
1132 dbxout_init hasn'r been called yet. */
1133 enum debug_info_type save_write_symbols = write_symbols;
1134 write_symbols = NO_DEBUG;
1136 build_selector_template ();
1137 temp_type = build_array_type (objc_selector_template, NULL_TREE);
1139 write_symbols = save_write_symbols;
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 constant_string_id = get_identifier (STRING_OBJECT_CLASS_NAME);
1157 constant_string_type = xref_tag (RECORD_TYPE, constant_string_id);
1160 /* Custom build_string which sets TREE_TYPE! */
1163 my_build_string (len, str)
1168 tree a_string = build_string (len, str);
1170 /* Some code from combine_strings, which is local to c-parse.y. */
1171 if (TREE_TYPE (a_string) == int_array_type_node)
1174 TREE_TYPE (a_string)
1175 = build_array_type (wide_flag ? integer_type_node : char_type_node,
1176 build_index_type (build_int_2 (len - 1, 0)));
1178 TREE_CONSTANT (a_string) = 1; /* Puts string in the readonly segment */
1179 TREE_STATIC (a_string) = 1;
1184 /* Return a newly constructed OBJC_STRING_CST node whose value is
1185 the LEN characters at STR.
1186 The TREE_TYPE is not initialized. */
1189 build_objc_string (len, str)
1193 tree s = build_string (len, str);
1195 TREE_SET_CODE (s, OBJC_STRING_CST);
1199 /* Given a chain of OBJC_STRING_CST's, build a static instance of
1200 NXConstanString which points at the concatenation of those strings.
1201 We place the string object in the __string_objects section of the
1202 __OBJC segment. The Objective-C runtime will initialize the isa
1203 pointers of the string objects to point at the NXConstandString class
1207 build_objc_string_object (strings)
1210 tree string, initlist, constructor;
1213 if (!doing_objc_thang)
1216 if (lookup_interface (constant_string_id) == NULL_TREE)
1218 error ("Cannot find interface declaration for `%s'",
1219 IDENTIFIER_POINTER (constant_string_id));
1220 return error_mark_node;
1223 add_class_reference (constant_string_id);
1225 /* Combine_strings will work for OBJC_STRING_CST's too. */
1226 string = combine_strings (strings);
1227 TREE_SET_CODE (string, STRING_CST);
1228 length = TREE_STRING_LENGTH (string) - 1;
1230 if (! flag_next_runtime)
1232 push_obstacks_nochange ();
1233 end_temporary_allocation ();
1234 if (! TREE_PERMANENT (strings))
1235 string = my_build_string (length + 1,
1236 TREE_STRING_POINTER (string));
1239 /* & ((NXConstantString) {0, string, length}) */
1241 initlist = build_tree_list (NULL_TREE, build_int_2 (0, 0));
1243 = tree_cons (NULL_TREE, copy_node (build_unary_op (ADDR_EXPR, string, 1)),
1245 initlist = tree_cons (NULL_TREE, build_int_2 (length, 0), initlist);
1246 constructor = build_constructor (constant_string_type, nreverse (initlist));
1248 if (!flag_next_runtime)
1251 = objc_add_static_instance (constructor, constant_string_type);
1255 return (build_unary_op (ADDR_EXPR, constructor, 1));
1258 /* Declare a static instance of CLASS_DECL initialized by CONSTRUCTOR. */
1261 objc_add_static_instance (constructor, class_decl)
1262 tree constructor, class_decl;
1264 static int num_static_inst;
1265 tree *chain, decl, decl_spec, decl_expr;
1268 push_obstacks_nochange ();
1269 end_temporary_allocation ();
1271 /* Find the list of static instances for the CLASS_DECL. Create one if
1273 for (chain = &objc_static_instances;
1274 *chain && TREE_VALUE (*chain) != class_decl;
1275 chain = &TREE_CHAIN (*chain));
1278 *chain = tree_cons (NULL_TREE, class_decl, NULL_TREE);
1279 add_objc_string (TYPE_NAME (class_decl), class_names);
1282 sprintf (buf, "_OBJC_INSTANCE_%d", num_static_inst++);
1283 decl = build_decl (VAR_DECL, get_identifier (buf), class_decl);
1284 DECL_COMMON (decl) = 1;
1285 TREE_STATIC (decl) = 1;
1286 DECL_ARTIFICIAL (decl) = 1;
1287 pushdecl_top_level (decl);
1288 rest_of_decl_compilation (decl, 0, 1, 0);
1290 /* Do this here so it gets output later instead of possibly
1291 inside something else we are writing. */
1292 DECL_INITIAL (decl) = constructor;
1294 /* Add the DECL to the head of this CLASS' list. */
1295 TREE_PURPOSE (*chain) = tree_cons (NULL_TREE, decl, TREE_PURPOSE (*chain));
1301 /* Build a static constant CONSTRUCTOR
1302 with type TYPE and elements ELTS. */
1305 build_constructor (type, elts)
1308 tree constructor = build (CONSTRUCTOR, type, NULL_TREE, elts);
1310 TREE_CONSTANT (constructor) = 1;
1311 TREE_STATIC (constructor) = 1;
1312 TREE_READONLY (constructor) = 1;
1317 /* Take care of defining and initializing _OBJC_SYMBOLS. */
1319 /* Predefine the following data type:
1327 void *defs[cls_def_cnt + cat_def_cnt];
1331 build_objc_symtab_template ()
1333 tree field_decl, field_decl_chain, index;
1335 objc_symtab_template
1336 = start_struct (RECORD_TYPE, get_identifier (UTAG_SYMTAB));
1338 /* long sel_ref_cnt; */
1340 field_decl = create_builtin_decl (FIELD_DECL,
1341 long_integer_type_node,
1343 field_decl_chain = field_decl;
1347 field_decl = create_builtin_decl (FIELD_DECL,
1348 build_pointer_type (selector_type),
1350 chainon (field_decl_chain, field_decl);
1352 /* short cls_def_cnt; */
1354 field_decl = create_builtin_decl (FIELD_DECL,
1355 short_integer_type_node,
1357 chainon (field_decl_chain, field_decl);
1359 /* short cat_def_cnt; */
1361 field_decl = create_builtin_decl (FIELD_DECL,
1362 short_integer_type_node,
1364 chainon (field_decl_chain, field_decl);
1366 /* void *defs[cls_def_cnt + cat_def_cnt]; */
1368 index = build_index_type (build_int_2 (imp_count + cat_count - 1,
1369 imp_count == 0 && cat_count == 0
1371 field_decl = create_builtin_decl (FIELD_DECL,
1372 build_array_type (ptr_type_node, index),
1374 chainon (field_decl_chain, field_decl);
1376 finish_struct (objc_symtab_template, field_decl_chain, NULL_TREE);
1379 /* Create the initial value for the `defs' field of _objc_symtab.
1380 This is a CONSTRUCTOR. */
1383 init_def_list (type)
1386 tree expr, initlist = NULL_TREE;
1387 struct imp_entry *impent;
1390 for (impent = imp_list; impent; impent = impent->next)
1392 if (TREE_CODE (impent->imp_context) == CLASS_IMPLEMENTATION_TYPE)
1394 expr = build_unary_op (ADDR_EXPR, impent->class_decl, 0);
1395 initlist = tree_cons (NULL_TREE, expr, initlist);
1400 for (impent = imp_list; impent; impent = impent->next)
1402 if (TREE_CODE (impent->imp_context) == CATEGORY_IMPLEMENTATION_TYPE)
1404 expr = build_unary_op (ADDR_EXPR, impent->class_decl, 0);
1405 initlist = tree_cons (NULL_TREE, expr, initlist);
1409 return build_constructor (type, nreverse (initlist));
1412 /* Construct the initial value for all of _objc_symtab. */
1415 init_objc_symtab (type)
1420 /* sel_ref_cnt = { ..., 5, ... } */
1422 initlist = build_tree_list (NULL_TREE, build_int_2 (0, 0));
1424 /* refs = { ..., _OBJC_SELECTOR_TABLE, ... } */
1426 if (flag_next_runtime || ! sel_ref_chain)
1427 initlist = tree_cons (NULL_TREE, build_int_2 (0, 0), initlist);
1429 initlist = tree_cons (NULL_TREE,
1430 build_unary_op (ADDR_EXPR,
1431 UOBJC_SELECTOR_TABLE_decl, 1),
1434 /* cls_def_cnt = { ..., 5, ... } */
1436 initlist = tree_cons (NULL_TREE, build_int_2 (imp_count, 0), initlist);
1438 /* cat_def_cnt = { ..., 5, ... } */
1440 initlist = tree_cons (NULL_TREE, build_int_2 (cat_count, 0), initlist);
1442 /* cls_def = { ..., { &Foo, &Bar, ...}, ... } */
1444 if (imp_count || cat_count)
1446 tree field = TYPE_FIELDS (type);
1447 field = TREE_CHAIN (TREE_CHAIN (TREE_CHAIN (TREE_CHAIN (field))));
1449 initlist = tree_cons (NULL_TREE, init_def_list (TREE_TYPE (field)),
1453 return build_constructor (type, nreverse (initlist));
1456 /* Push forward-declarations of all the categories
1457 so that init_def_list can use them in a CONSTRUCTOR. */
1460 forward_declare_categories ()
1462 struct imp_entry *impent;
1463 tree sav = implementation_context;
1465 for (impent = imp_list; impent; impent = impent->next)
1467 if (TREE_CODE (impent->imp_context) == CATEGORY_IMPLEMENTATION_TYPE)
1469 /* Set an invisible arg to synth_id_with_class_suffix. */
1470 implementation_context = impent->imp_context;
1472 = create_builtin_decl (VAR_DECL, objc_category_template,
1473 IDENTIFIER_POINTER (synth_id_with_class_suffix ("_OBJC_CATEGORY", implementation_context)));
1476 implementation_context = sav;
1479 /* Create the declaration of _OBJC_SYMBOLS, with type `strict _objc_symtab'
1480 and initialized appropriately. */
1483 generate_objc_symtab_decl ()
1487 if (!objc_category_template)
1488 build_category_template ();
1490 /* forward declare categories */
1492 forward_declare_categories ();
1494 if (!objc_symtab_template)
1495 build_objc_symtab_template ();
1497 sc_spec = build_tree_list (NULL_TREE, ridpointers[(int) RID_STATIC]);
1499 UOBJC_SYMBOLS_decl = start_decl (get_identifier ("_OBJC_SYMBOLS"),
1500 tree_cons (NULL_TREE,
1501 objc_symtab_template, sc_spec),
1503 NULL_TREE, NULL_TREE);
1505 TREE_USED (UOBJC_SYMBOLS_decl) = 1;
1506 DECL_IGNORED_P (UOBJC_SYMBOLS_decl) = 1;
1507 DECL_ARTIFICIAL (UOBJC_SYMBOLS_decl) = 1;
1508 finish_decl (UOBJC_SYMBOLS_decl,
1509 init_objc_symtab (TREE_TYPE (UOBJC_SYMBOLS_decl)),
1514 init_module_descriptor (type)
1517 tree initlist, expr;
1519 /* version = { 1, ... } */
1521 expr = build_int_2 (OBJC_VERSION, 0);
1522 initlist = build_tree_list (NULL_TREE, expr);
1524 /* size = { ..., sizeof (struct objc_module), ... } */
1526 expr = size_in_bytes (objc_module_template);
1527 initlist = tree_cons (NULL_TREE, expr, initlist);
1529 /* name = { ..., "foo.m", ... } */
1531 expr = add_objc_string (get_identifier (input_filename), class_names);
1532 initlist = tree_cons (NULL_TREE, expr, initlist);
1535 if (!flag_next_runtime)
1537 /* statics = { ..., _OBJC_STATIC_INSTANCES, ... } */
1538 if (static_instances_decl)
1539 expr = build_unary_op (ADDR_EXPR, static_instances_decl, 0);
1541 expr = build_int_2 (0, 0);
1542 initlist = tree_cons (NULL_TREE, expr, initlist);
1545 /* symtab = { ..., _OBJC_SYMBOLS, ... } */
1547 if (UOBJC_SYMBOLS_decl)
1548 expr = build_unary_op (ADDR_EXPR, UOBJC_SYMBOLS_decl, 0);
1550 expr = build_int_2 (0, 0);
1551 initlist = tree_cons (NULL_TREE, expr, initlist);
1553 return build_constructor (type, nreverse (initlist));
1556 /* Write out the data structures to describe Objective C classes defined.
1557 If appropriate, compile and output a setup function to initialize them.
1558 Return a string which is the name of a function to call to initialize
1559 the Objective C data structures for this file (and perhaps for other files
1562 struct objc_module { ... } _OBJC_MODULE = { ... }; */
1565 build_module_descriptor ()
1567 tree decl_specs, field_decl, field_decl_chain;
1569 objc_module_template
1570 = start_struct (RECORD_TYPE, get_identifier (UTAG_MODULE));
1574 decl_specs = build_tree_list (NULL_TREE, ridpointers[(int) RID_LONG]);
1575 field_decl = get_identifier ("version");
1577 = grokfield (input_filename, lineno, field_decl, decl_specs, NULL_TREE);
1578 field_decl_chain = field_decl;
1582 decl_specs = build_tree_list (NULL_TREE, ridpointers[(int) RID_LONG]);
1583 field_decl = get_identifier ("size");
1585 = grokfield (input_filename, lineno, field_decl, decl_specs, NULL_TREE);
1586 chainon (field_decl_chain, field_decl);
1590 decl_specs = build_tree_list (NULL_TREE, ridpointers[(int) RID_CHAR]);
1591 field_decl = build1 (INDIRECT_REF, NULL_TREE, get_identifier ("name"));
1593 = grokfield (input_filename, lineno, field_decl, decl_specs, NULL_TREE);
1594 chainon (field_decl_chain, field_decl);
1597 if (!flag_next_runtime)
1601 decl_specs = get_identifier (UTAG_STATICS);
1603 = build_tree_list (NULL_TREE, xref_tag (RECORD_TYPE, decl_specs));
1605 = build1 (INDIRECT_REF, NULL_TREE, get_identifier ("statics"));
1606 field_decl = grokfield (input_filename, lineno, field_decl,
1607 decl_specs, NULL_TREE);
1608 chainon (field_decl_chain, field_decl);
1612 /* struct objc_symtab *symtab; */
1614 decl_specs = get_identifier (UTAG_SYMTAB);
1615 decl_specs = build_tree_list (NULL_TREE, xref_tag (RECORD_TYPE, decl_specs));
1616 field_decl = build1 (INDIRECT_REF, NULL_TREE, get_identifier ("symtab"));
1618 = grokfield (input_filename, lineno, field_decl, decl_specs, NULL_TREE);
1619 chainon (field_decl_chain, field_decl);
1621 finish_struct (objc_module_template, field_decl_chain, NULL_TREE);
1623 /* Create an instance of "objc_module". */
1625 decl_specs = tree_cons (NULL_TREE, objc_module_template,
1626 build_tree_list (NULL_TREE,
1627 ridpointers[(int) RID_STATIC]));
1629 UOBJC_MODULES_decl = start_decl (get_identifier ("_OBJC_MODULES"),
1630 decl_specs, 1, NULL_TREE, NULL_TREE);
1632 DECL_ARTIFICIAL (UOBJC_MODULES_decl) = 1;
1633 DECL_IGNORED_P (UOBJC_MODULES_decl) = 1;
1634 finish_decl (UOBJC_MODULES_decl,
1635 init_module_descriptor (TREE_TYPE (UOBJC_MODULES_decl)),
1638 /* Mark the decl to avoid "defined but not used" warning. */
1639 DECL_IN_SYSTEM_HEADER (UOBJC_MODULES_decl) = 1;
1641 /* Generate a constructor call for the module descriptor.
1642 This code was generated by reading the grammar rules
1643 of c-parse.in; Therefore, it may not be the most efficient
1644 way of generating the requisite code. */
1646 if (flag_next_runtime)
1650 tree parms, function_decl, decelerator, void_list_node;
1652 extern tree get_file_function_name ();
1653 tree init_function_name = get_file_function_name ('I');
1655 /* Declare void __objc_execClass (void*); */
1657 void_list_node = build_tree_list (NULL_TREE, void_type_node);
1659 = build_function_type (void_type_node,
1660 tree_cons (NULL_TREE, ptr_type_node,
1662 function_decl = build_decl (FUNCTION_DECL,
1663 get_identifier (TAG_EXECCLASS),
1665 DECL_EXTERNAL (function_decl) = 1;
1666 DECL_ARTIFICIAL (function_decl) = 1;
1667 TREE_PUBLIC (function_decl) = 1;
1669 pushdecl (function_decl);
1670 rest_of_decl_compilation (function_decl, 0, 0, 0);
1673 = build_tree_list (NULL_TREE,
1674 build_unary_op (ADDR_EXPR, UOBJC_MODULES_decl, 0));
1675 decelerator = build_function_call (function_decl, parms);
1677 /* void _GLOBAL_$I$<gnyf> () {objc_execClass (&L_OBJC_MODULES);} */
1679 start_function (void_list_node,
1680 build_parse_node (CALL_EXPR, init_function_name,
1681 /* This has the format of the output
1682 of get_parm_info. */
1683 tree_cons (NULL_TREE, NULL_TREE,
1686 NULL_TREE, NULL_TREE, 0);
1687 #if 0 /* This should be turned back on later
1688 for the systems where collect is not needed. */
1689 /* Make these functions nonglobal
1690 so each file can use the same name. */
1691 TREE_PUBLIC (current_function_decl) = 0;
1693 TREE_USED (current_function_decl) = 1;
1694 store_parm_decls ();
1696 assemble_external (function_decl);
1697 c_expand_expr_stmt (decelerator);
1699 TREE_PUBLIC (current_function_decl) = 1;
1701 function_decl = current_function_decl;
1702 finish_function (0);
1704 /* Return the name of the constructor function. */
1705 return XSTR (XEXP (DECL_RTL (function_decl), 0), 0);
1709 /* extern const char _OBJC_STRINGS[]; */
1712 generate_forward_declaration_to_string_table ()
1714 tree sc_spec, decl_specs, expr_decl;
1716 sc_spec = tree_cons (NULL_TREE, ridpointers[(int) RID_EXTERN], NULL_TREE);
1717 decl_specs = tree_cons (NULL_TREE, ridpointers[(int) RID_CHAR], sc_spec);
1720 = build_nt (ARRAY_REF, get_identifier ("_OBJC_STRINGS"), NULL_TREE);
1722 UOBJC_STRINGS_decl = define_decl (expr_decl, decl_specs);
1725 /* Return the DECL of the string IDENT in the SECTION. */
1728 get_objc_string_decl (ident, section)
1730 enum string_section section;
1734 if (section == class_names)
1735 chain = class_names_chain;
1736 else if (section == meth_var_names)
1737 chain = meth_var_names_chain;
1738 else if (section == meth_var_types)
1739 chain = meth_var_types_chain;
1741 for (; chain != 0; chain = TREE_VALUE (chain))
1742 if (TREE_VALUE (chain) == ident)
1743 return (TREE_PURPOSE (chain));
1749 /* Output references to all statically allocated objects. Return the DECL
1750 for the array built. */
1753 generate_static_references ()
1755 tree decls = NULL_TREE, ident, decl_spec, expr_decl, expr = NULL_TREE;
1756 tree class_name, class, decl, instance, idecl, initlist;
1757 tree cl_chain, in_chain, type;
1758 int num_inst, num_class;
1761 if (flag_next_runtime)
1764 for (cl_chain = objc_static_instances, num_class = 0;
1765 cl_chain; cl_chain = TREE_CHAIN (cl_chain), num_class++)
1767 for (num_inst = 0, in_chain = TREE_PURPOSE (cl_chain);
1768 in_chain; num_inst++, in_chain = TREE_CHAIN (in_chain));
1770 sprintf (buf, "_OBJC_STATIC_INSTANCES_%d", num_class);
1771 ident = get_identifier (buf);
1773 expr_decl = build_nt (ARRAY_REF, ident, NULL_TREE);
1774 decl_spec = tree_cons (NULL_TREE, build_pointer_type (void_type_node),
1775 build_tree_list (NULL_TREE,
1776 ridpointers[(int) RID_STATIC]));
1777 decl = start_decl (expr_decl, decl_spec, 1, NULL_TREE, NULL_TREE);
1778 DECL_CONTEXT (decl) = 0;
1779 DECL_ARTIFICIAL (decl) = 1;
1781 /* Output {class_name, ...}. */
1782 class = TREE_VALUE (cl_chain);
1783 class_name = get_objc_string_decl (TYPE_NAME (class), class_names);
1784 initlist = build_tree_list (NULL_TREE,
1785 build_unary_op (ADDR_EXPR, class_name, 1));
1787 /* Output {..., instance, ...}. */
1788 for (in_chain = TREE_PURPOSE (cl_chain);
1789 in_chain; in_chain = TREE_CHAIN (in_chain))
1791 expr = build_unary_op (ADDR_EXPR, TREE_VALUE (in_chain), 1);
1792 initlist = tree_cons (NULL_TREE, expr, initlist);
1795 /* Output {..., NULL}. */
1796 initlist = tree_cons (NULL_TREE, build_int_2 (0, 0), initlist);
1798 expr = build_constructor (TREE_TYPE (decl), nreverse (initlist));
1799 finish_decl (decl, expr, NULL_TREE);
1800 TREE_USED (decl) = 1;
1802 type = build_array_type (build_pointer_type (void_type_node), 0);
1803 decl = build_decl (VAR_DECL, ident, type);
1804 make_decl_rtl (decl, 0, 1);
1805 TREE_USED (decl) = 1;
1807 = tree_cons (NULL_TREE, build_unary_op (ADDR_EXPR, decl, 1), decls);
1810 decls = tree_cons (NULL_TREE, build_int_2 (0, 0), decls);
1811 ident = get_identifier ("_OBJC_STATIC_INSTANCES");
1812 expr_decl = build_nt (ARRAY_REF, ident, NULL_TREE);
1813 decl_spec = tree_cons (NULL_TREE, build_pointer_type (void_type_node),
1814 build_tree_list (NULL_TREE,
1815 ridpointers[(int) RID_STATIC]));
1816 static_instances_decl
1817 = start_decl (expr_decl, decl_spec, 1, NULL_TREE, NULL_TREE);
1818 DECL_CONTEXT (static_instances_decl) = 0;
1819 DECL_ARTIFICIAL (static_instances_decl) = 1;
1820 end_temporary_allocation ();
1821 expr = build_constructor (TREE_TYPE (static_instances_decl),
1823 finish_decl (static_instances_decl, expr, NULL_TREE);
1826 /* Output all strings. */
1831 tree sc_spec, decl_specs, expr_decl;
1832 tree chain, string_expr;
1835 for (chain = class_names_chain; chain; chain = TREE_CHAIN (chain))
1837 string = TREE_VALUE (chain);
1838 decl = TREE_PURPOSE (chain);
1840 = tree_cons (NULL_TREE, ridpointers[(int) RID_STATIC], NULL_TREE);
1841 decl_specs = tree_cons (NULL_TREE, ridpointers[(int) RID_CHAR], sc_spec);
1842 expr_decl = build_nt (ARRAY_REF, DECL_NAME (decl), NULL_TREE);
1843 decl = start_decl (expr_decl, decl_specs, 1, NULL_TREE, NULL_TREE);
1844 end_temporary_allocation ();
1845 string_expr = my_build_string (IDENTIFIER_LENGTH (string) + 1,
1846 IDENTIFIER_POINTER (string));
1847 finish_decl (decl, string_expr, NULL_TREE);
1850 for (chain = meth_var_names_chain; chain; chain = TREE_CHAIN (chain))
1852 string = TREE_VALUE (chain);
1853 decl = TREE_PURPOSE (chain);
1855 = tree_cons (NULL_TREE, ridpointers[(int) RID_STATIC], NULL_TREE);
1856 decl_specs = tree_cons (NULL_TREE, ridpointers[(int) RID_CHAR], sc_spec);
1857 expr_decl = build_nt (ARRAY_REF, DECL_NAME (decl), NULL_TREE);
1858 decl = start_decl (expr_decl, decl_specs, 1, NULL_TREE, NULL_TREE);
1859 string_expr = my_build_string (IDENTIFIER_LENGTH (string) + 1,
1860 IDENTIFIER_POINTER (string));
1861 finish_decl (decl, string_expr, NULL_TREE);
1864 for (chain = meth_var_types_chain; chain; chain = TREE_CHAIN (chain))
1866 string = TREE_VALUE (chain);
1867 decl = TREE_PURPOSE (chain);
1869 = tree_cons (NULL_TREE, ridpointers[(int) RID_STATIC], NULL_TREE);
1870 decl_specs = tree_cons (NULL_TREE, ridpointers[(int) RID_CHAR], sc_spec);
1871 expr_decl = build_nt (ARRAY_REF, DECL_NAME (decl), NULL_TREE);
1872 decl = start_decl (expr_decl, decl_specs, 1, NULL_TREE, NULL_TREE);
1873 string_expr = my_build_string (IDENTIFIER_LENGTH (string) + 1,
1874 IDENTIFIER_POINTER (string));
1875 finish_decl (decl, string_expr, NULL_TREE);
1880 build_selector_reference_decl (name)
1887 sprintf (buf, "_OBJC_SELECTOR_REFERENCES_%d", idx++);
1889 push_obstacks_nochange ();
1890 end_temporary_allocation ();
1892 ident = get_identifier (buf);
1894 decl = build_decl (VAR_DECL, ident, selector_type);
1895 DECL_EXTERNAL (decl) = 1;
1896 TREE_PUBLIC (decl) = 1;
1897 TREE_USED (decl) = 1;
1898 TREE_READONLY (decl) = 1;
1899 DECL_ARTIFICIAL (decl) = 1;
1900 DECL_CONTEXT (decl) = 0;
1902 make_decl_rtl (decl, 0, 1);
1903 pushdecl_top_level (decl);
1910 /* Just a handy wrapper for add_objc_string. */
1913 build_selector (ident)
1916 tree expr = add_objc_string (ident, meth_var_names);
1917 if (flag_typed_selectors)
1920 return build_c_cast (selector_type, expr); /* cast! */
1923 /* Synthesize the following expr: (char *)&_OBJC_STRINGS[<offset>]
1924 The cast stops the compiler from issuing the following message:
1925 grok.m: warning: initialization of non-const * pointer from const *
1926 grok.m: warning: initialization between incompatible pointer types. */
1929 build_msg_pool_reference (offset)
1932 tree expr = build_int_2 (offset, 0);
1935 expr = build_array_ref (UOBJC_STRINGS_decl, expr);
1936 expr = build_unary_op (ADDR_EXPR, expr, 0);
1938 cast = build_tree_list (build_tree_list (NULL_TREE,
1939 ridpointers[(int) RID_CHAR]),
1940 build1 (INDIRECT_REF, NULL_TREE, NULL_TREE));
1941 TREE_TYPE (expr) = groktypename (cast);
1946 init_selector (offset)
1949 tree expr = build_msg_pool_reference (offset);
1950 TREE_TYPE (expr) = selector_type;
1955 build_selector_translation_table ()
1957 tree sc_spec, decl_specs;
1958 tree chain, initlist = NULL_TREE;
1960 tree decl, var_decl, name;
1962 /* The corresponding pop_obstacks is in finish_decl,
1963 called at the end of this function. */
1964 if (! flag_next_runtime)
1965 push_obstacks_nochange ();
1967 for (chain = sel_ref_chain; chain; chain = TREE_CHAIN (chain))
1971 expr = build_selector (TREE_VALUE (chain));
1973 if (flag_next_runtime)
1975 name = DECL_NAME (TREE_PURPOSE (chain));
1977 sc_spec = build_tree_list (NULL_TREE, ridpointers[(int) RID_STATIC]);
1979 /* static SEL _OBJC_SELECTOR_REFERENCES_n = ...; */
1980 decl_specs = tree_cons (NULL_TREE, selector_type, sc_spec);
1984 /* The `decl' that is returned from start_decl is the one that we
1985 forward declared in `build_selector_reference' */
1986 decl = start_decl (var_decl, decl_specs, 1, NULL_TREE, NULL_TREE);
1989 /* add one for the '\0' character */
1990 offset += IDENTIFIER_LENGTH (TREE_VALUE (chain)) + 1;
1992 if (flag_next_runtime)
1993 finish_decl (decl, expr, NULL_TREE);
1996 if (flag_typed_selectors)
1998 tree eltlist = NULL_TREE;
1999 tree encoding = get_proto_encoding (TREE_PURPOSE (chain));
2000 eltlist = tree_cons (NULL_TREE, expr, NULL_TREE);
2001 eltlist = tree_cons (NULL_TREE, encoding, eltlist);
2002 expr = build_constructor (objc_selector_template,
2003 nreverse (eltlist));
2005 initlist = tree_cons (NULL_TREE, expr, initlist);
2010 if (! flag_next_runtime)
2012 /* Cause the variable and its initial value to be actually output. */
2013 DECL_EXTERNAL (UOBJC_SELECTOR_TABLE_decl) = 0;
2014 TREE_STATIC (UOBJC_SELECTOR_TABLE_decl) = 1;
2015 /* NULL terminate the list and fix the decl for output. */
2016 initlist = tree_cons (NULL_TREE, build_int_2 (0, 0), initlist);
2017 DECL_INITIAL (UOBJC_SELECTOR_TABLE_decl) = (tree) 1;
2018 initlist = build_constructor (TREE_TYPE (UOBJC_SELECTOR_TABLE_decl),
2019 nreverse (initlist));
2020 finish_decl (UOBJC_SELECTOR_TABLE_decl, initlist, NULL_TREE);
2021 current_function_decl = NULL_TREE;
2026 get_proto_encoding (proto)
2034 if (! METHOD_ENCODING (proto))
2036 tmp_decl = build_tmp_function_decl ();
2037 hack_method_prototype (proto, tmp_decl);
2038 encoding = encode_method_prototype (proto, tmp_decl);
2039 METHOD_ENCODING (proto) = encoding;
2042 encoding = METHOD_ENCODING (proto);
2044 return add_objc_string (encoding, meth_var_types);
2047 return build_int_2 (0, 0);
2050 /* sel_ref_chain is a list whose "value" fields will be instances of
2051 identifier_node that represent the selector. */
2054 build_typed_selector_reference (ident, proto)
2057 tree *chain = &sel_ref_chain;
2063 if (TREE_PURPOSE (*chain) == ident && TREE_VALUE (*chain) == proto)
2064 goto return_at_index;
2067 chain = &TREE_CHAIN (*chain);
2070 *chain = perm_tree_cons (proto, ident, NULL_TREE);
2073 expr = build_unary_op (ADDR_EXPR,
2074 build_array_ref (UOBJC_SELECTOR_TABLE_decl,
2075 build_int_2 (index, 0)),
2077 return build_c_cast (selector_type, expr);
2081 build_selector_reference (ident)
2084 tree *chain = &sel_ref_chain;
2090 if (TREE_VALUE (*chain) == ident)
2091 return (flag_next_runtime
2092 ? TREE_PURPOSE (*chain)
2093 : build_array_ref (UOBJC_SELECTOR_TABLE_decl,
2094 build_int_2 (index, 0)));
2097 chain = &TREE_CHAIN (*chain);
2100 expr = build_selector_reference_decl (ident);
2102 *chain = perm_tree_cons (expr, ident, NULL_TREE);
2104 return (flag_next_runtime
2106 : build_array_ref (UOBJC_SELECTOR_TABLE_decl,
2107 build_int_2 (index, 0)));
2111 build_class_reference_decl (name)
2118 sprintf (buf, "_OBJC_CLASS_REFERENCES_%d", idx++);
2120 push_obstacks_nochange ();
2121 end_temporary_allocation ();
2123 ident = get_identifier (buf);
2125 decl = build_decl (VAR_DECL, ident, objc_class_type);
2126 DECL_EXTERNAL (decl) = 1;
2127 TREE_PUBLIC (decl) = 1;
2128 TREE_USED (decl) = 1;
2129 TREE_READONLY (decl) = 1;
2130 DECL_CONTEXT (decl) = 0;
2131 DECL_ARTIFICIAL (decl) = 1;
2133 make_decl_rtl (decl, 0, 1);
2134 pushdecl_top_level (decl);
2141 /* Create a class reference, but don't create a variable to reference
2145 add_class_reference (ident)
2150 if ((chain = cls_ref_chain))
2155 if (ident == TREE_VALUE (chain))
2159 chain = TREE_CHAIN (chain);
2163 /* Append to the end of the list */
2164 TREE_CHAIN (tail) = perm_tree_cons (NULL_TREE, ident, NULL_TREE);
2167 cls_ref_chain = perm_tree_cons (NULL_TREE, ident, NULL_TREE);
2170 /* Get a class reference, creating it if necessary. Also create the
2171 reference variable. */
2174 get_class_reference (ident)
2177 if (flag_next_runtime)
2182 for (chain = &cls_ref_chain; *chain; chain = &TREE_CHAIN (*chain))
2183 if (TREE_VALUE (*chain) == ident)
2185 if (! TREE_PURPOSE (*chain))
2186 TREE_PURPOSE (*chain) = build_class_reference_decl (ident);
2188 return TREE_PURPOSE (*chain);
2191 decl = build_class_reference_decl (ident);
2192 *chain = perm_tree_cons (decl, ident, NULL_TREE);
2199 add_class_reference (ident);
2201 params = build_tree_list (NULL_TREE,
2202 my_build_string (IDENTIFIER_LENGTH (ident) + 1,
2203 IDENTIFIER_POINTER (ident)));
2205 assemble_external (objc_get_class_decl);
2206 return build_function_call (objc_get_class_decl, params);
2210 /* SEL_REFDEF_CHAIN is a list whose "value" fields will be instances
2211 of identifier_node that represent the selector. It returns the
2212 offset of the selector from the beginning of the _OBJC_STRINGS
2213 pool. This offset is typically used by init_selector during code
2216 For each string section we have a chain which maps identifier nodes
2217 to decls for the strings. */
2220 add_objc_string (ident, section)
2222 enum string_section section;
2226 if (section == class_names)
2227 chain = &class_names_chain;
2228 else if (section == meth_var_names)
2229 chain = &meth_var_names_chain;
2230 else if (section == meth_var_types)
2231 chain = &meth_var_types_chain;
2235 if (TREE_VALUE (*chain) == ident)
2236 return build_unary_op (ADDR_EXPR, TREE_PURPOSE (*chain), 1);
2238 chain = &TREE_CHAIN (*chain);
2241 decl = build_objc_string_decl (ident, section);
2243 *chain = perm_tree_cons (decl, ident, NULL_TREE);
2245 return build_unary_op (ADDR_EXPR, decl, 1);
2249 build_objc_string_decl (name, section)
2251 enum string_section section;
2255 static int class_names_idx = 0;
2256 static int meth_var_names_idx = 0;
2257 static int meth_var_types_idx = 0;
2259 if (section == class_names)
2260 sprintf (buf, "_OBJC_CLASS_NAME_%d", class_names_idx++);
2261 else if (section == meth_var_names)
2262 sprintf (buf, "_OBJC_METH_VAR_NAME_%d", meth_var_names_idx++);
2263 else if (section == meth_var_types)
2264 sprintf (buf, "_OBJC_METH_VAR_TYPE_%d", meth_var_types_idx++);
2266 push_obstacks_nochange ();
2267 end_temporary_allocation ();
2268 ident = get_identifier (buf);
2270 decl = build_decl (VAR_DECL, ident, build_array_type (char_type_node, 0));
2271 DECL_EXTERNAL (decl) = 1;
2272 TREE_PUBLIC (decl) = 1;
2273 TREE_USED (decl) = 1;
2274 TREE_READONLY (decl) = 1;
2275 TREE_CONSTANT (decl) = 1;
2276 DECL_CONTEXT (decl) = 0;
2277 DECL_ARTIFICIAL (decl) = 1;
2279 make_decl_rtl (decl, 0, 1);
2280 pushdecl_top_level (decl);
2289 objc_declare_alias (alias_ident, class_ident)
2293 if (!doing_objc_thang)
2296 if (is_class_name (class_ident) != class_ident)
2297 warning ("Cannot find class `%s'", IDENTIFIER_POINTER (class_ident));
2298 else if (is_class_name (alias_ident))
2299 warning ("Class `%s' already exists", IDENTIFIER_POINTER (alias_ident));
2301 alias_chain = tree_cons (class_ident, alias_ident, alias_chain);
2305 objc_declare_class (ident_list)
2310 if (!doing_objc_thang)
2313 for (list = ident_list; list; list = TREE_CHAIN (list))
2315 tree ident = TREE_VALUE (list);
2318 if ((decl = lookup_name (ident)))
2320 error ("`%s' redeclared as different kind of symbol",
2321 IDENTIFIER_POINTER (ident));
2322 error_with_decl (decl, "previous declaration of `%s'");
2325 if (! is_class_name (ident))
2327 tree record = xref_tag (RECORD_TYPE, ident);
2328 TREE_STATIC_TEMPLATE (record) = 1;
2329 class_chain = tree_cons (NULL_TREE, ident, class_chain);
2335 is_class_name (ident)
2340 if (lookup_interface (ident))
2343 for (chain = class_chain; chain; chain = TREE_CHAIN (chain))
2345 if (ident == TREE_VALUE (chain))
2349 for (chain = alias_chain; chain; chain = TREE_CHAIN (chain))
2351 if (ident == TREE_VALUE (chain))
2352 return TREE_PURPOSE (chain);
2359 lookup_interface (ident)
2364 for (chain = interface_chain; chain; chain = TREE_CHAIN (chain))
2366 if (ident == CLASS_NAME (chain))
2373 objc_copy_list (list, head)
2377 tree newlist = NULL_TREE, tail = NULL_TREE;
2381 tail = copy_node (list);
2383 /* The following statement fixes a bug when inheriting instance
2384 variables that are declared to be bitfields. finish_struct
2385 expects to find the width of the bitfield in DECL_INITIAL,
2386 which it nulls out after processing the decl of the super
2387 class...rather than change the way finish_struct works (which
2388 is risky), I create the situation it expects...s.naroff
2391 if (DECL_BIT_FIELD (tail) && DECL_INITIAL (tail) == 0)
2392 DECL_INITIAL (tail) = build_int_2 (DECL_FIELD_SIZE (tail), 0);
2394 newlist = chainon (newlist, tail);
2395 list = TREE_CHAIN (list);
2402 /* Used by: build_private_template, get_class_ivars, and
2403 continue_class. COPY is 1 when called from @defs. In this case
2404 copy all fields. Otherwise don't copy leaf ivars since we rely on
2405 them being side-effected exactly once by finish_struct. */
2408 build_ivar_chain (interface, copy)
2412 tree my_name, super_name, ivar_chain;
2414 my_name = CLASS_NAME (interface);
2415 super_name = CLASS_SUPER_NAME (interface);
2417 /* Possibly copy leaf ivars. */
2419 objc_copy_list (CLASS_IVARS (interface), &ivar_chain);
2421 ivar_chain = CLASS_IVARS (interface);
2426 tree super_interface = lookup_interface (super_name);
2428 if (!super_interface)
2430 /* fatal did not work with 2 args...should fix */
2431 error ("Cannot find interface declaration for `%s', superclass of `%s'",
2432 IDENTIFIER_POINTER (super_name),
2433 IDENTIFIER_POINTER (my_name));
2434 exit (FATAL_EXIT_CODE);
2437 if (super_interface == interface)
2439 fatal ("Circular inheritance in interface declaration for `%s'",
2440 IDENTIFIER_POINTER (super_name));
2443 interface = super_interface;
2444 my_name = CLASS_NAME (interface);
2445 super_name = CLASS_SUPER_NAME (interface);
2447 op1 = CLASS_IVARS (interface);
2450 tree head, tail = objc_copy_list (op1, &head);
2452 /* Prepend super class ivars...make a copy of the list, we
2453 do not want to alter the original. */
2454 TREE_CHAIN (tail) = ivar_chain;
2461 /* struct <classname> {
2462 struct objc_class *isa;
2467 build_private_template (class)
2472 if (CLASS_STATIC_TEMPLATE (class))
2474 uprivate_record = CLASS_STATIC_TEMPLATE (class);
2475 ivar_context = TYPE_FIELDS (CLASS_STATIC_TEMPLATE (class));
2479 uprivate_record = start_struct (RECORD_TYPE, CLASS_NAME (class));
2481 ivar_context = build_ivar_chain (class, 0);
2483 finish_struct (uprivate_record, ivar_context, NULL_TREE);
2485 CLASS_STATIC_TEMPLATE (class) = uprivate_record;
2487 /* mark this record as class template - for class type checking */
2488 TREE_STATIC_TEMPLATE (uprivate_record) = 1;
2492 = groktypename (build_tree_list (build_tree_list (NULL_TREE,
2494 build1 (INDIRECT_REF, NULL_TREE,
2497 return ivar_context;
2500 /* Begin code generation for protocols... */
2502 /* struct objc_protocol {
2503 char *protocol_name;
2504 struct objc_protocol **protocol_list;
2505 struct objc_method_desc *instance_methods;
2506 struct objc_method_desc *class_methods;
2510 build_protocol_template ()
2512 tree decl_specs, field_decl, field_decl_chain;
2515 template = start_struct (RECORD_TYPE, get_identifier (UTAG_PROTOCOL));
2517 /* struct objc_class *isa; */
2519 decl_specs = build_tree_list (NULL_TREE, xref_tag (RECORD_TYPE,
2520 get_identifier (UTAG_CLASS)));
2521 field_decl = build1 (INDIRECT_REF, NULL_TREE, get_identifier ("isa"));
2523 = grokfield (input_filename, lineno, field_decl, decl_specs, NULL_TREE);
2524 field_decl_chain = field_decl;
2526 /* char *protocol_name; */
2528 decl_specs = build_tree_list (NULL_TREE, ridpointers[(int) RID_CHAR]);
2530 = build1 (INDIRECT_REF, NULL_TREE, get_identifier ("protocol_name"));
2532 = grokfield (input_filename, lineno, field_decl, decl_specs, NULL_TREE);
2533 chainon (field_decl_chain, field_decl);
2535 /* struct objc_protocol **protocol_list; */
2537 decl_specs = build_tree_list (NULL_TREE, template);
2539 = build1 (INDIRECT_REF, NULL_TREE, get_identifier ("protocol_list"));
2540 field_decl = build1 (INDIRECT_REF, NULL_TREE, field_decl);
2542 = grokfield (input_filename, lineno, field_decl, decl_specs, NULL_TREE);
2543 chainon (field_decl_chain, field_decl);
2545 /* struct objc_method_list *instance_methods; */
2548 = build_tree_list (NULL_TREE,
2549 xref_tag (RECORD_TYPE,
2550 get_identifier (UTAG_METHOD_PROTOTYPE_LIST)));
2552 = build1 (INDIRECT_REF, NULL_TREE, get_identifier ("instance_methods"));
2554 = grokfield (input_filename, lineno, field_decl, decl_specs, NULL_TREE);
2555 chainon (field_decl_chain, field_decl);
2557 /* struct objc_method_list *class_methods; */
2560 = build_tree_list (NULL_TREE,
2561 xref_tag (RECORD_TYPE,
2562 get_identifier (UTAG_METHOD_PROTOTYPE_LIST)));
2564 = build1 (INDIRECT_REF, NULL_TREE, get_identifier ("class_methods"));
2566 = grokfield (input_filename, lineno, field_decl, decl_specs, NULL_TREE);
2567 chainon (field_decl_chain, field_decl);
2569 return finish_struct (template, field_decl_chain, NULL_TREE);
2573 build_descriptor_table_initializer (type, entries)
2577 tree initlist = NULL_TREE;
2581 tree eltlist = NULL_TREE;
2584 = tree_cons (NULL_TREE,
2585 build_selector (METHOD_SEL_NAME (entries)), NULL_TREE);
2587 = tree_cons (NULL_TREE,
2588 add_objc_string (METHOD_ENCODING (entries),
2593 = tree_cons (NULL_TREE,
2594 build_constructor (type, nreverse (eltlist)), initlist);
2596 entries = TREE_CHAIN (entries);
2600 return build_constructor (build_array_type (type, 0), nreverse (initlist));
2603 /* struct objc_method_prototype_list {
2605 struct objc_method_prototype {
2612 build_method_prototype_list_template (list_type, size)
2616 tree objc_ivar_list_record;
2617 tree decl_specs, field_decl, field_decl_chain;
2619 /* Generate an unnamed struct definition. */
2621 objc_ivar_list_record = start_struct (RECORD_TYPE, NULL_TREE);
2623 /* int method_count; */
2625 decl_specs = build_tree_list (NULL_TREE, ridpointers[(int) RID_INT]);
2626 field_decl = get_identifier ("method_count");
2629 = grokfield (input_filename, lineno, field_decl, decl_specs, NULL_TREE);
2630 field_decl_chain = field_decl;
2632 /* struct objc_method method_list[]; */
2634 decl_specs = build_tree_list (NULL_TREE, list_type);
2635 field_decl = build_nt (ARRAY_REF, get_identifier ("method_list"),
2636 build_int_2 (size, 0));
2639 = grokfield (input_filename, lineno, field_decl, decl_specs, NULL_TREE);
2640 chainon (field_decl_chain, field_decl);
2642 finish_struct (objc_ivar_list_record, field_decl_chain, NULL_TREE);
2644 return objc_ivar_list_record;
2648 build_method_prototype_template ()
2651 tree decl_specs, field_decl, field_decl_chain;
2654 = start_struct (RECORD_TYPE, get_identifier (UTAG_METHOD_PROTOTYPE));
2656 #ifdef OBJC_INT_SELECTORS
2657 /* unsigned int _cmd; */
2659 = tree_cons (NULL_TREE, ridpointers[(int) RID_UNSIGNED], NULL_TREE);
2660 decl_specs = tree_cons (NULL_TREE, ridpointers[(int) RID_INT], decl_specs);
2661 field_decl = get_identifier ("_cmd");
2662 #else /* OBJC_INT_SELECTORS */
2663 /* struct objc_selector *_cmd; */
2664 decl_specs = tree_cons (NULL_TREE, xref_tag (RECORD_TYPE,
2665 get_identifier (TAG_SELECTOR)), NULL_TREE);
2666 field_decl = build1 (INDIRECT_REF, NULL_TREE, get_identifier ("_cmd"));
2667 #endif /* OBJC_INT_SELECTORS */
2670 = grokfield (input_filename, lineno, field_decl, decl_specs, NULL_TREE);
2671 field_decl_chain = field_decl;
2673 decl_specs = tree_cons (NULL_TREE, ridpointers[(int) RID_CHAR], NULL_TREE);
2675 = build1 (INDIRECT_REF, NULL_TREE, get_identifier ("method_types"));
2677 = grokfield (input_filename, lineno, field_decl, decl_specs, NULL_TREE);
2678 chainon (field_decl_chain, field_decl);
2680 finish_struct (proto_record, field_decl_chain, NULL_TREE);
2682 return proto_record;
2685 /* True if last call to forwarding_offset yielded a register offset. */
2686 static int offset_is_register;
2689 forwarding_offset (parm)
2692 int offset_in_bytes;
2694 if (GET_CODE (DECL_INCOMING_RTL (parm)) == MEM)
2696 rtx addr = XEXP (DECL_INCOMING_RTL (parm), 0);
2698 /* ??? Here we assume that the parm address is indexed
2699 off the frame pointer or arg pointer.
2700 If that is not true, we produce meaningless results,
2701 but do not crash. */
2702 if (GET_CODE (addr) == PLUS
2703 && GET_CODE (XEXP (addr, 1)) == CONST_INT)
2704 offset_in_bytes = INTVAL (XEXP (addr, 1));
2706 offset_in_bytes = 0;
2708 offset_in_bytes += OBJC_FORWARDING_STACK_OFFSET;
2709 offset_is_register = 0;
2711 else if (GET_CODE (DECL_INCOMING_RTL (parm)) == REG)
2713 int regno = REGNO (DECL_INCOMING_RTL (parm));
2714 offset_in_bytes = apply_args_register_offset (regno);
2715 offset_is_register = 1;
2720 /* This is the case where the parm is passed as an int or double
2721 and it is converted to a char, short or float and stored back
2722 in the parmlist. In this case, describe the parm
2723 with the variable's declared type, and adjust the address
2724 if the least significant bytes (which we are using) are not
2726 if (BYTES_BIG_ENDIAN && TREE_TYPE (parm) != DECL_ARG_TYPE (parm))
2727 offset_in_bytes += (GET_MODE_SIZE (TYPE_MODE (DECL_ARG_TYPE (parm)))
2728 - GET_MODE_SIZE (GET_MODE (DECL_RTL (parm))));
2730 return offset_in_bytes;
2734 encode_method_prototype (method_decl, func_decl)
2741 int max_parm_end = 0;
2745 /* ONEWAY and BYCOPY, for remote object are the only method qualifiers. */
2746 encode_type_qualifiers (TREE_PURPOSE (TREE_TYPE (method_decl)));
2749 encode_type (TREE_TYPE (TREE_TYPE (func_decl)),
2750 obstack_object_size (&util_obstack),
2751 OBJC_ENCODE_INLINE_DEFS);
2754 for (parms = DECL_ARGUMENTS (func_decl); parms;
2755 parms = TREE_CHAIN (parms))
2757 int parm_end = (forwarding_offset (parms)
2758 + (TREE_INT_CST_LOW (TYPE_SIZE (TREE_TYPE (parms)))
2761 if (!offset_is_register && max_parm_end < parm_end)
2762 max_parm_end = parm_end;
2765 stack_size = max_parm_end - OBJC_FORWARDING_MIN_OFFSET;
2767 sprintf (buf, "%d", stack_size);
2768 obstack_grow (&util_obstack, buf, strlen (buf));
2770 user_args = METHOD_SEL_ARGS (method_decl);
2772 /* Argument types. */
2773 for (parms = DECL_ARGUMENTS (func_decl), i = 0; parms;
2774 parms = TREE_CHAIN (parms), i++)
2776 /* Process argument qualifiers for user supplied arguments. */
2779 encode_type_qualifiers (TREE_PURPOSE (TREE_TYPE (user_args)));
2780 user_args = TREE_CHAIN (user_args);
2784 encode_type (TREE_TYPE (parms),
2785 obstack_object_size (&util_obstack),
2786 OBJC_ENCODE_INLINE_DEFS);
2788 /* Compute offset. */
2789 sprintf (buf, "%d", forwarding_offset (parms));
2791 /* Indicate register. */
2792 if (offset_is_register)
2793 obstack_1grow (&util_obstack, '+');
2795 obstack_grow (&util_obstack, buf, strlen (buf));
2798 obstack_1grow (&util_obstack, '\0');
2799 result = get_identifier (obstack_finish (&util_obstack));
2800 obstack_free (&util_obstack, util_firstobj);
2805 generate_descriptor_table (type, name, size, list, proto)
2812 tree sc_spec, decl_specs, decl, initlist;
2814 sc_spec = tree_cons (NULL_TREE, ridpointers[(int) RID_STATIC], NULL_TREE);
2815 decl_specs = tree_cons (NULL_TREE, type, sc_spec);
2817 decl = start_decl (synth_id_with_class_suffix (name, proto),
2818 decl_specs, 1, NULL_TREE, NULL_TREE);
2820 initlist = build_tree_list (NULL_TREE, build_int_2 (size, 0));
2821 initlist = tree_cons (NULL_TREE, list, initlist);
2823 finish_decl (decl, build_constructor (type, nreverse (initlist)),
2830 generate_method_descriptors (protocol) /* generate_dispatch_tables */
2833 static tree objc_method_prototype_template;
2834 tree initlist, chain, method_list_template;
2835 tree cast, variable_length_type;
2838 if (!objc_method_prototype_template)
2839 objc_method_prototype_template = build_method_prototype_template ();
2841 cast = build_tree_list (build_tree_list (NULL_TREE, xref_tag (RECORD_TYPE,
2842 get_identifier (UTAG_METHOD_PROTOTYPE_LIST))),
2844 variable_length_type = groktypename (cast);
2846 chain = PROTOCOL_CLS_METHODS (protocol);
2849 size = list_length (chain);
2851 method_list_template
2852 = build_method_prototype_list_template (objc_method_prototype_template,
2856 = build_descriptor_table_initializer (objc_method_prototype_template,
2859 UOBJC_CLASS_METHODS_decl
2860 = generate_descriptor_table (method_list_template,
2861 "_OBJC_PROTOCOL_CLASS_METHODS",
2862 size, initlist, protocol);
2863 TREE_TYPE (UOBJC_CLASS_METHODS_decl) = variable_length_type;
2866 UOBJC_CLASS_METHODS_decl = 0;
2868 chain = PROTOCOL_NST_METHODS (protocol);
2871 size = list_length (chain);
2873 method_list_template
2874 = build_method_prototype_list_template (objc_method_prototype_template,
2877 = build_descriptor_table_initializer (objc_method_prototype_template,
2880 UOBJC_INSTANCE_METHODS_decl
2881 = generate_descriptor_table (method_list_template,
2882 "_OBJC_PROTOCOL_INSTANCE_METHODS",
2883 size, initlist, protocol);
2884 TREE_TYPE (UOBJC_INSTANCE_METHODS_decl) = variable_length_type;
2887 UOBJC_INSTANCE_METHODS_decl = 0;
2891 build_tmp_function_decl ()
2893 tree decl_specs, expr_decl, parms;
2897 /* struct objc_object *objc_xxx (id, SEL, ...); */
2899 decl_specs = build_tree_list (NULL_TREE, objc_object_reference);
2900 push_parm_decl (build_tree_list
2901 (build_tree_list (decl_specs,
2902 build1 (INDIRECT_REF, NULL_TREE,
2904 build_tree_list (NULL_TREE, NULL_TREE)));
2906 decl_specs = build_tree_list (NULL_TREE, xref_tag (RECORD_TYPE,
2907 get_identifier (TAG_SELECTOR)));
2908 expr_decl = build1 (INDIRECT_REF, NULL_TREE, NULL_TREE);
2910 push_parm_decl (build_tree_list (build_tree_list (decl_specs, expr_decl),
2911 build_tree_list (NULL_TREE, NULL_TREE)));
2912 parms = get_parm_info (0);
2915 decl_specs = build_tree_list (NULL_TREE, objc_object_reference);
2916 sprintf (buffer, "__objc_tmp_%x", xxx++);
2917 expr_decl = build_nt (CALL_EXPR, get_identifier (buffer), parms, NULL_TREE);
2918 expr_decl = build1 (INDIRECT_REF, NULL_TREE, expr_decl);
2920 return define_decl (expr_decl, decl_specs);
2924 hack_method_prototype (nst_methods, tmp_decl)
2931 /* Hack to avoid problem with static typing of self arg. */
2932 TREE_SET_CODE (nst_methods, CLASS_METHOD_DECL);
2933 start_method_def (nst_methods);
2934 TREE_SET_CODE (nst_methods, INSTANCE_METHOD_DECL);
2936 if (METHOD_ADD_ARGS (nst_methods) == (tree) 1)
2937 parms = get_parm_info (0); /* we have a `, ...' */
2939 parms = get_parm_info (1); /* place a `void_at_end' */
2941 poplevel (0, 0, 0); /* Must be called BEFORE start_function. */
2943 /* Usually called from store_parm_decls -> init_function_start. */
2945 DECL_ARGUMENTS (tmp_decl) = TREE_PURPOSE (parms);
2946 current_function_decl = tmp_decl;
2949 /* Code taken from start_function. */
2950 tree restype = TREE_TYPE (TREE_TYPE (tmp_decl));
2951 /* Promote the value to int before returning it. */
2952 if (TREE_CODE (restype) == INTEGER_TYPE
2953 && TYPE_PRECISION (restype) < TYPE_PRECISION (integer_type_node))
2954 restype = integer_type_node;
2955 DECL_RESULT (tmp_decl) = build_decl (RESULT_DECL, 0, restype);
2958 for (parm = DECL_ARGUMENTS (tmp_decl); parm; parm = TREE_CHAIN (parm))
2959 DECL_CONTEXT (parm) = tmp_decl;
2961 init_function_start (tmp_decl, "objc-act", 0);
2963 /* Typically called from expand_function_start for function definitions. */
2964 assign_parms (tmp_decl, 0);
2966 /* install return type */
2967 TREE_TYPE (TREE_TYPE (tmp_decl)) = groktypename (TREE_TYPE (nst_methods));
2972 generate_protocol_references (plist)
2977 /* Forward declare protocols referenced. */
2978 for (lproto = plist; lproto; lproto = TREE_CHAIN (lproto))
2980 tree proto = TREE_VALUE (lproto);
2982 if (TREE_CODE (proto) == PROTOCOL_INTERFACE_TYPE
2983 && PROTOCOL_NAME (proto))
2985 if (! PROTOCOL_FORWARD_DECL (proto))
2986 build_protocol_reference (proto);
2988 if (PROTOCOL_LIST (proto))
2989 generate_protocol_references (PROTOCOL_LIST (proto));
2995 generate_protocols ()
2997 tree p, tmp_decl, encoding;
2998 tree sc_spec, decl_specs, decl;
2999 tree initlist, protocol_name_expr, refs_decl, refs_expr;
3000 tree cast_type2 = 0;
3002 tmp_decl = build_tmp_function_decl ();
3004 if (! objc_protocol_template)
3005 objc_protocol_template = build_protocol_template ();
3007 /* If a protocol was directly referenced, pull in indirect references. */
3008 for (p = protocol_chain; p; p = TREE_CHAIN (p))
3009 if (PROTOCOL_FORWARD_DECL (p) && PROTOCOL_LIST (p))
3010 generate_protocol_references (PROTOCOL_LIST (p));
3012 for (p = protocol_chain; p; p = TREE_CHAIN (p))
3014 tree nst_methods = PROTOCOL_NST_METHODS (p);
3015 tree cls_methods = PROTOCOL_CLS_METHODS (p);
3017 /* If protocol wasn't referenced, don't generate any code. */
3018 if (! PROTOCOL_FORWARD_DECL (p))
3021 /* Make sure we link in the Protocol class. */
3022 add_class_reference (get_identifier (PROTOCOL_OBJECT_CLASS_NAME));
3026 if (! METHOD_ENCODING (nst_methods))
3028 hack_method_prototype (nst_methods, tmp_decl);
3029 encoding = encode_method_prototype (nst_methods, tmp_decl);
3030 METHOD_ENCODING (nst_methods) = encoding;
3032 nst_methods = TREE_CHAIN (nst_methods);
3037 if (! METHOD_ENCODING (cls_methods))
3039 hack_method_prototype (cls_methods, tmp_decl);
3040 encoding = encode_method_prototype (cls_methods, tmp_decl);
3041 METHOD_ENCODING (cls_methods) = encoding;
3044 cls_methods = TREE_CHAIN (cls_methods);
3046 generate_method_descriptors (p);
3048 if (PROTOCOL_LIST (p))
3049 refs_decl = generate_protocol_list (p);
3053 /* static struct objc_protocol _OBJC_PROTOCOL_<mumble>; */
3055 sc_spec = tree_cons (NULL_TREE, ridpointers[(int) RID_STATIC],
3057 decl_specs = tree_cons (NULL_TREE, objc_protocol_template, sc_spec);
3059 decl = start_decl (synth_id_with_class_suffix ("_OBJC_PROTOCOL", p),
3060 decl_specs, 1, NULL_TREE, NULL_TREE);
3062 protocol_name_expr = add_objc_string (PROTOCOL_NAME (p), class_names);
3069 (build_tree_list (build_tree_list (NULL_TREE,
3070 objc_protocol_template),
3071 build1 (INDIRECT_REF, NULL_TREE,
3072 build1 (INDIRECT_REF, NULL_TREE,
3075 refs_expr = build_unary_op (ADDR_EXPR, refs_decl, 0);
3076 TREE_TYPE (refs_expr) = cast_type2;
3079 refs_expr = build_int_2 (0, 0);
3081 /* UOBJC_INSTANCE_METHODS_decl/UOBJC_CLASS_METHODS_decl are set
3082 by generate_method_descriptors, which is called above. */
3083 initlist = build_protocol_initializer (TREE_TYPE (decl),
3084 protocol_name_expr, refs_expr,
3085 UOBJC_INSTANCE_METHODS_decl,
3086 UOBJC_CLASS_METHODS_decl);
3087 finish_decl (decl, initlist, NULL_TREE);
3089 /* Mark the decl as used to avoid "defined but not used" warning. */
3090 TREE_USED (decl) = 1;
3095 build_protocol_initializer (type, protocol_name, protocol_list,
3096 instance_methods, class_methods)
3100 tree instance_methods;
3103 tree initlist = NULL_TREE, expr;
3104 static tree cast_type = 0;
3110 (build_tree_list (NULL_TREE,
3111 xref_tag (RECORD_TYPE,
3112 get_identifier (UTAG_CLASS))),
3113 build1 (INDIRECT_REF, NULL_TREE, NULL_TREE)));
3115 /* Filling the "isa" in with one allows the runtime system to
3116 detect that the version change...should remove before final release. */
3118 expr = build_int_2 (PROTOCOL_VERSION, 0);
3119 TREE_TYPE (expr) = cast_type;
3120 initlist = tree_cons (NULL_TREE, expr, initlist);
3121 initlist = tree_cons (NULL_TREE, protocol_name, initlist);
3122 initlist = tree_cons (NULL_TREE, protocol_list, initlist);
3124 if (!instance_methods)
3125 initlist = tree_cons (NULL_TREE, build_int_2 (0, 0), initlist);
3128 expr = build_unary_op (ADDR_EXPR, instance_methods, 0);
3129 initlist = tree_cons (NULL_TREE, expr, initlist);
3133 initlist = tree_cons (NULL_TREE, build_int_2 (0, 0), initlist);
3136 expr = build_unary_op (ADDR_EXPR, class_methods, 0);
3137 initlist = tree_cons (NULL_TREE, expr, initlist);
3140 return build_constructor (type, nreverse (initlist));
3143 /* struct objc_category {
3144 char *category_name;
3146 struct objc_method_list *instance_methods;
3147 struct objc_method_list *class_methods;
3148 struct objc_protocol_list *protocols;
3152 build_category_template ()
3154 tree decl_specs, field_decl, field_decl_chain;
3156 objc_category_template = start_struct (RECORD_TYPE,
3157 get_identifier (UTAG_CATEGORY));
3158 /* char *category_name; */
3160 decl_specs = build_tree_list (NULL_TREE, ridpointers[(int) RID_CHAR]);
3162 = build1 (INDIRECT_REF, NULL_TREE, get_identifier ("category_name"));
3164 = grokfield (input_filename, lineno, field_decl, decl_specs, NULL_TREE);
3165 field_decl_chain = field_decl;
3167 /* char *class_name; */
3169 decl_specs = build_tree_list (NULL_TREE, ridpointers[(int) RID_CHAR]);
3170 field_decl = build1 (INDIRECT_REF, NULL_TREE, get_identifier ("class_name"));
3172 = grokfield (input_filename, lineno, field_decl, decl_specs, NULL_TREE);
3173 chainon (field_decl_chain, field_decl);
3175 /* struct objc_method_list *instance_methods; */
3177 decl_specs = build_tree_list (NULL_TREE,
3178 xref_tag (RECORD_TYPE,
3179 get_identifier (UTAG_METHOD_LIST)));
3181 = build1 (INDIRECT_REF, NULL_TREE, get_identifier ("instance_methods"));
3183 = grokfield (input_filename, lineno, field_decl, decl_specs, NULL_TREE);
3184 chainon (field_decl_chain, field_decl);
3186 /* struct objc_method_list *class_methods; */
3188 decl_specs = build_tree_list (NULL_TREE,
3189 xref_tag (RECORD_TYPE,
3190 get_identifier (UTAG_METHOD_LIST)));
3192 = build1 (INDIRECT_REF, NULL_TREE, get_identifier ("class_methods"));
3194 = grokfield (input_filename, lineno, field_decl, decl_specs, NULL_TREE);
3195 chainon (field_decl_chain, field_decl);
3197 /* struct objc_protocol **protocol_list; */
3199 decl_specs = build_tree_list (NULL_TREE,
3200 xref_tag (RECORD_TYPE,
3201 get_identifier (UTAG_PROTOCOL)));
3203 = build1 (INDIRECT_REF, NULL_TREE, get_identifier ("protocol_list"));
3204 field_decl = build1 (INDIRECT_REF, NULL_TREE, field_decl);
3206 = grokfield (input_filename, lineno, field_decl, decl_specs, NULL_TREE);
3207 chainon (field_decl_chain, field_decl);
3209 finish_struct (objc_category_template, field_decl_chain, NULL_TREE);
3212 /* struct objc_selector {
3218 build_selector_template ()
3221 tree decl_specs, field_decl, field_decl_chain;
3223 objc_selector_template
3224 = start_struct (RECORD_TYPE, get_identifier (UTAG_SELECTOR));
3228 decl_specs = build_tree_list (NULL_TREE, ridpointers[(int) RID_VOID]);
3229 field_decl = build1 (INDIRECT_REF, NULL_TREE, get_identifier ("sel_id"));
3231 = grokfield (input_filename, lineno, field_decl, decl_specs, NULL_TREE);
3232 field_decl_chain = field_decl;
3234 /* char *sel_type; */
3236 decl_specs = build_tree_list (NULL_TREE, ridpointers[(int) RID_CHAR]);
3237 field_decl = build1 (INDIRECT_REF, NULL_TREE, get_identifier ("sel_type"));
3239 = grokfield (input_filename, lineno, field_decl, decl_specs, NULL_TREE);
3240 chainon (field_decl_chain, field_decl);
3242 finish_struct (objc_selector_template, field_decl_chain, NULL_TREE);
3245 /* struct objc_class {
3246 struct objc_class *isa;
3247 struct objc_class *super_class;
3252 struct objc_ivar_list *ivars;
3253 struct objc_method_list *methods;
3254 if (flag_next_runtime)
3255 struct objc_cache *cache;
3257 struct sarray *dtable;
3258 struct objc_class *subclass_list;
3259 struct objc_class *sibling_class;
3261 struct objc_protocol_list *protocols;
3265 build_class_template ()
3267 tree decl_specs, field_decl, field_decl_chain;
3270 = start_struct (RECORD_TYPE, get_identifier (UTAG_CLASS));
3272 /* struct objc_class *isa; */
3274 decl_specs = build_tree_list (NULL_TREE, objc_class_template);
3275 field_decl = build1 (INDIRECT_REF, NULL_TREE, get_identifier ("isa"));
3277 = grokfield (input_filename, lineno, field_decl, decl_specs, NULL_TREE);
3278 field_decl_chain = field_decl;
3280 /* struct objc_class *super_class; */
3282 decl_specs = build_tree_list (NULL_TREE, objc_class_template);
3284 = build1 (INDIRECT_REF, NULL_TREE, get_identifier ("super_class"));
3286 = grokfield (input_filename, lineno, field_decl, decl_specs, NULL_TREE);
3287 chainon (field_decl_chain, field_decl);
3291 decl_specs = build_tree_list (NULL_TREE, ridpointers[(int) RID_CHAR]);
3292 field_decl = build1 (INDIRECT_REF, NULL_TREE, get_identifier ("name"));
3294 = grokfield (input_filename, lineno, field_decl, decl_specs, NULL_TREE);
3295 chainon (field_decl_chain, field_decl);
3299 decl_specs = build_tree_list (NULL_TREE, ridpointers[(int) RID_LONG]);
3300 field_decl = get_identifier ("version");
3302 = grokfield (input_filename, lineno, field_decl, decl_specs, NULL_TREE);
3303 chainon (field_decl_chain, field_decl);
3307 decl_specs = build_tree_list (NULL_TREE, ridpointers[(int) RID_LONG]);
3308 field_decl = get_identifier ("info");
3310 = grokfield (input_filename, lineno, field_decl, decl_specs, NULL_TREE);
3311 chainon (field_decl_chain, field_decl);
3313 /* long instance_size; */
3315 decl_specs = build_tree_list (NULL_TREE, ridpointers[(int) RID_LONG]);
3316 field_decl = get_identifier ("instance_size");
3318 = grokfield (input_filename, lineno, field_decl, decl_specs, NULL_TREE);
3319 chainon (field_decl_chain, field_decl);
3321 /* struct objc_ivar_list *ivars; */
3323 decl_specs = build_tree_list (NULL_TREE,
3324 xref_tag (RECORD_TYPE,
3325 get_identifier (UTAG_IVAR_LIST)));
3326 field_decl = build1 (INDIRECT_REF, NULL_TREE, get_identifier ("ivars"));
3328 = grokfield (input_filename, lineno, field_decl, decl_specs, NULL_TREE);
3329 chainon (field_decl_chain, field_decl);
3331 /* struct objc_method_list *methods; */
3333 decl_specs = build_tree_list (NULL_TREE,
3334 xref_tag (RECORD_TYPE,
3335 get_identifier (UTAG_METHOD_LIST)));
3336 field_decl = build1 (INDIRECT_REF, NULL_TREE, get_identifier ("methods"));
3338 = grokfield (input_filename, lineno, field_decl, decl_specs, NULL_TREE);
3339 chainon (field_decl_chain, field_decl);
3341 if (flag_next_runtime)
3343 /* struct objc_cache *cache; */
3345 decl_specs = build_tree_list (NULL_TREE,
3346 xref_tag (RECORD_TYPE,
3347 get_identifier ("objc_cache")));
3348 field_decl = build1 (INDIRECT_REF, NULL_TREE, get_identifier ("cache"));
3349 field_decl = grokfield (input_filename, lineno, field_decl,
3350 decl_specs, NULL_TREE);
3351 chainon (field_decl_chain, field_decl);
3355 /* struct sarray *dtable; */
3357 decl_specs = build_tree_list (NULL_TREE,
3358 xref_tag (RECORD_TYPE,
3359 get_identifier ("sarray")));
3360 field_decl = build1 (INDIRECT_REF, NULL_TREE, get_identifier ("dtable"));
3361 field_decl = grokfield (input_filename, lineno, field_decl,
3362 decl_specs, NULL_TREE);
3363 chainon (field_decl_chain, field_decl);
3365 /* struct objc_class *subclass_list; */
3367 decl_specs = build_tree_list (NULL_TREE, objc_class_template);
3369 = build1 (INDIRECT_REF, NULL_TREE, get_identifier ("subclass_list"));
3370 field_decl = grokfield (input_filename, lineno, field_decl,
3371 decl_specs, NULL_TREE);
3372 chainon (field_decl_chain, field_decl);
3374 /* struct objc_class *sibling_class; */
3376 decl_specs = build_tree_list (NULL_TREE, objc_class_template);
3378 = build1 (INDIRECT_REF, NULL_TREE, get_identifier ("sibling_class"));
3379 field_decl = grokfield (input_filename, lineno, field_decl,
3380 decl_specs, NULL_TREE);
3381 chainon (field_decl_chain, field_decl);
3384 /* struct objc_protocol **protocol_list; */
3386 decl_specs = build_tree_list (NULL_TREE,
3387 xref_tag (RECORD_TYPE,
3388 get_identifier (UTAG_PROTOCOL)));
3390 = build1 (INDIRECT_REF, NULL_TREE, get_identifier ("protocol_list"));
3392 = build1 (INDIRECT_REF, NULL_TREE, field_decl);
3393 field_decl = grokfield (input_filename, lineno, field_decl,
3394 decl_specs, NULL_TREE);
3395 chainon (field_decl_chain, field_decl);
3398 finish_struct (objc_class_template, field_decl_chain, NULL_TREE);
3401 /* Generate appropriate forward declarations for an implementation. */
3404 synth_forward_declarations ()
3406 tree sc_spec, decl_specs, an_id;
3408 /* extern struct objc_class _OBJC_CLASS_<my_name>; */
3410 an_id = synth_id_with_class_suffix ("_OBJC_CLASS", implementation_context);
3412 sc_spec = build_tree_list (NULL_TREE, ridpointers[(int) RID_EXTERN]);
3413 decl_specs = tree_cons (NULL_TREE, objc_class_template, sc_spec);
3414 UOBJC_CLASS_decl = define_decl (an_id, decl_specs);
3415 TREE_USED (UOBJC_CLASS_decl) = 1;
3416 DECL_ARTIFICIAL (UOBJC_CLASS_decl) = 1;
3418 /* extern struct objc_class _OBJC_METACLASS_<my_name>; */
3420 an_id = synth_id_with_class_suffix ("_OBJC_METACLASS",
3421 implementation_context);
3423 UOBJC_METACLASS_decl = define_decl (an_id, decl_specs);
3424 TREE_USED (UOBJC_METACLASS_decl) = 1;
3425 DECL_ARTIFICIAL(UOBJC_METACLASS_decl) = 1;
3427 /* Pre-build the following entities - for speed/convenience. */
3429 an_id = get_identifier ("super_class");
3430 ucls_super_ref = build_component_ref (UOBJC_CLASS_decl, an_id);
3431 uucls_super_ref = build_component_ref (UOBJC_METACLASS_decl, an_id);
3435 error_with_ivar (message, decl, rawdecl)
3442 report_error_function (DECL_SOURCE_FILE (decl));
3444 fprintf (stderr, "%s:%d: ",
3445 DECL_SOURCE_FILE (decl), DECL_SOURCE_LINE (decl));
3446 bzero (errbuf, BUFSIZE);
3447 fprintf (stderr, "%s `%s'\n", message, gen_declaration (rawdecl, errbuf));
3450 #define USERTYPE(t) \
3451 (TREE_CODE (t) == RECORD_TYPE || TREE_CODE (t) == UNION_TYPE \
3452 || TREE_CODE (t) == ENUMERAL_TYPE)
3455 check_ivars (inter, imp)
3459 tree intdecls = CLASS_IVARS (inter);
3460 tree impdecls = CLASS_IVARS (imp);
3461 tree rawintdecls = CLASS_RAW_IVARS (inter);
3462 tree rawimpdecls = CLASS_RAW_IVARS (imp);
3468 if (intdecls == 0 && impdecls == 0)
3470 if (intdecls == 0 || impdecls == 0)
3472 error ("inconsistent instance variable specification");
3476 t1 = TREE_TYPE (intdecls); t2 = TREE_TYPE (impdecls);
3478 if (!comptypes (t1, t2))
3480 if (DECL_NAME (intdecls) == DECL_NAME (impdecls))
3482 error_with_ivar ("conflicting instance variable type",
3483 impdecls, rawimpdecls);
3484 error_with_ivar ("previous declaration of",
3485 intdecls, rawintdecls);
3487 else /* both the type and the name don't match */
3489 error ("inconsistent instance variable specification");
3494 else if (DECL_NAME (intdecls) != DECL_NAME (impdecls))
3496 error_with_ivar ("conflicting instance variable name",
3497 impdecls, rawimpdecls);
3498 error_with_ivar ("previous declaration of",
3499 intdecls, rawintdecls);
3502 intdecls = TREE_CHAIN (intdecls);
3503 impdecls = TREE_CHAIN (impdecls);
3504 rawintdecls = TREE_CHAIN (rawintdecls);
3505 rawimpdecls = TREE_CHAIN (rawimpdecls);
3509 /* Set super_type to the data type node for struct objc_super *,
3510 first defining struct objc_super itself.
3511 This needs to be done just once per compilation. */
3514 build_super_template ()
3516 tree record, decl_specs, field_decl, field_decl_chain;
3518 record = start_struct (RECORD_TYPE, get_identifier (UTAG_SUPER));
3520 /* struct objc_object *self; */
3522 decl_specs = build_tree_list (NULL_TREE, objc_object_reference);
3523 field_decl = get_identifier ("self");
3524 field_decl = build1 (INDIRECT_REF, NULL_TREE, field_decl);
3525 field_decl = grokfield (input_filename, lineno,
3526 field_decl, decl_specs, NULL_TREE);
3527 field_decl_chain = field_decl;
3529 /* struct objc_class *class; */
3531 decl_specs = get_identifier (UTAG_CLASS);
3532 decl_specs = build_tree_list (NULL_TREE, xref_tag (RECORD_TYPE, decl_specs));
3533 field_decl = build1 (INDIRECT_REF, NULL_TREE, get_identifier ("class"));
3535 field_decl = grokfield (input_filename, lineno,
3536 field_decl, decl_specs, NULL_TREE);
3537 chainon (field_decl_chain, field_decl);
3539 finish_struct (record, field_decl_chain, NULL_TREE);
3541 /* `struct objc_super *' */
3542 super_type = groktypename (build_tree_list (build_tree_list (NULL_TREE,
3544 build1 (INDIRECT_REF,
3545 NULL_TREE, NULL_TREE)));
3549 /* struct objc_ivar {
3556 build_ivar_template ()
3558 tree objc_ivar_id, objc_ivar_record;
3559 tree decl_specs, field_decl, field_decl_chain;
3561 objc_ivar_id = get_identifier (UTAG_IVAR);
3562 objc_ivar_record = start_struct (RECORD_TYPE, objc_ivar_id);
3564 /* char *ivar_name; */
3566 decl_specs = build_tree_list (NULL_TREE, ridpointers[(int) RID_CHAR]);
3567 field_decl = build1 (INDIRECT_REF, NULL_TREE, get_identifier ("ivar_name"));
3569 field_decl = grokfield (input_filename, lineno, field_decl,
3570 decl_specs, NULL_TREE);
3571 field_decl_chain = field_decl;
3573 /* char *ivar_type; */
3575 decl_specs = build_tree_list (NULL_TREE, ridpointers[(int) RID_CHAR]);
3576 field_decl = build1 (INDIRECT_REF, NULL_TREE, get_identifier ("ivar_type"));
3578 field_decl = grokfield (input_filename, lineno, field_decl,
3579 decl_specs, NULL_TREE);
3580 chainon (field_decl_chain, field_decl);
3582 /* int ivar_offset; */
3584 decl_specs = build_tree_list (NULL_TREE, ridpointers[(int) RID_INT]);
3585 field_decl = get_identifier ("ivar_offset");
3587 field_decl = grokfield (input_filename, lineno, field_decl,
3588 decl_specs, NULL_TREE);
3589 chainon (field_decl_chain, field_decl);
3591 finish_struct (objc_ivar_record, field_decl_chain, NULL_TREE);
3593 return objc_ivar_record;
3598 struct objc_ivar ivar_list[ivar_count];
3602 build_ivar_list_template (list_type, size)
3606 tree objc_ivar_list_record;
3607 tree decl_specs, field_decl, field_decl_chain;
3609 objc_ivar_list_record = start_struct (RECORD_TYPE, NULL_TREE);
3611 /* int ivar_count; */
3613 decl_specs = build_tree_list (NULL_TREE, ridpointers[(int) RID_INT]);
3614 field_decl = get_identifier ("ivar_count");
3616 field_decl = grokfield (input_filename, lineno, field_decl,
3617 decl_specs, NULL_TREE);
3618 field_decl_chain = field_decl;
3620 /* struct objc_ivar ivar_list[]; */
3622 decl_specs = build_tree_list (NULL_TREE, list_type);
3623 field_decl = build_nt (ARRAY_REF, get_identifier ("ivar_list"),
3624 build_int_2 (size, 0));
3626 field_decl = grokfield (input_filename, lineno,
3627 field_decl, decl_specs, NULL_TREE);
3628 chainon (field_decl_chain, field_decl);
3630 finish_struct (objc_ivar_list_record, field_decl_chain, NULL_TREE);
3632 return objc_ivar_list_record;
3638 struct objc_method method_list[method_count];
3642 build_method_list_template (list_type, size)
3646 tree objc_ivar_list_record;
3647 tree decl_specs, field_decl, field_decl_chain;
3649 objc_ivar_list_record = start_struct (RECORD_TYPE, NULL_TREE);
3651 /* int method_next; */
3656 xref_tag (RECORD_TYPE,
3657 get_identifier (UTAG_METHOD_PROTOTYPE_LIST)));
3659 = build1 (INDIRECT_REF, NULL_TREE, get_identifier ("method_next"));
3660 field_decl = grokfield (input_filename, lineno, field_decl,
3661 decl_specs, NULL_TREE);
3662 field_decl_chain = field_decl;
3664 /* int method_count; */
3666 decl_specs = build_tree_list (NULL_TREE, ridpointers[(int) RID_INT]);
3667 field_decl = get_identifier ("method_count");
3669 field_decl = grokfield (input_filename, lineno,
3670 field_decl, decl_specs, NULL_TREE);
3671 chainon (field_decl_chain, field_decl);
3673 /* struct objc_method method_list[]; */
3675 decl_specs = build_tree_list (NULL_TREE, list_type);
3676 field_decl = build_nt (ARRAY_REF, get_identifier ("method_list"),
3677 build_int_2 (size, 0));
3679 field_decl = grokfield (input_filename, lineno,
3680 field_decl, decl_specs, NULL_TREE);
3681 chainon (field_decl_chain, field_decl);
3683 finish_struct (objc_ivar_list_record, field_decl_chain, NULL_TREE);
3685 return objc_ivar_list_record;
3689 build_ivar_list_initializer (type, field_decl)
3693 tree initlist = NULL_TREE;
3697 tree ivar = NULL_TREE;
3700 if (DECL_NAME (field_decl))
3701 ivar = tree_cons (NULL_TREE,
3702 add_objc_string (DECL_NAME (field_decl),
3706 /* Unnamed bit-field ivar (yuck). */
3707 ivar = tree_cons (NULL_TREE, build_int_2 (0, 0), ivar);
3710 encode_field_decl (field_decl,
3711 obstack_object_size (&util_obstack),
3712 OBJC_ENCODE_DONT_INLINE_DEFS);
3714 /* Null terminate string. */
3715 obstack_1grow (&util_obstack, 0);
3719 add_objc_string (get_identifier (obstack_finish (&util_obstack)),
3722 obstack_free (&util_obstack, util_firstobj);
3728 build_int_2 ((TREE_INT_CST_LOW (DECL_FIELD_BITPOS (field_decl))
3733 initlist = tree_cons (NULL_TREE,
3734 build_constructor (type, nreverse (ivar)),
3737 field_decl = TREE_CHAIN (field_decl);
3741 return build_constructor (build_array_type (type, 0), nreverse (initlist));
3745 generate_ivars_list (type, name, size, list)
3751 tree sc_spec, decl_specs, decl, initlist;
3753 sc_spec = tree_cons (NULL_TREE, ridpointers[(int) RID_STATIC], NULL_TREE);
3754 decl_specs = tree_cons (NULL_TREE, type, sc_spec);
3756 decl = start_decl (synth_id_with_class_suffix (name, implementation_context),
3757 decl_specs, 1, NULL_TREE, NULL_TREE);
3759 initlist = build_tree_list (NULL_TREE, build_int_2 (size, 0));
3760 initlist = tree_cons (NULL_TREE, list, initlist);
3763 build_constructor (TREE_TYPE (decl), nreverse (initlist)),
3770 generate_ivar_lists ()
3772 tree initlist, ivar_list_template, chain;
3773 tree cast, variable_length_type;
3776 generating_instance_variables = 1;
3778 if (!objc_ivar_template)
3779 objc_ivar_template = build_ivar_template ();
3783 (build_tree_list (NULL_TREE, xref_tag (RECORD_TYPE,
3784 get_identifier (UTAG_IVAR_LIST))),
3786 variable_length_type = groktypename (cast);
3788 /* Only generate class variables for the root of the inheritance
3789 hierarchy since these will be the same for every class. */
3791 if (CLASS_SUPER_NAME (implementation_template) == NULL_TREE
3792 && (chain = TYPE_FIELDS (objc_class_template)))
3794 size = list_length (chain);
3796 ivar_list_template = build_ivar_list_template (objc_ivar_template, size);
3797 initlist = build_ivar_list_initializer (objc_ivar_template, chain);
3799 UOBJC_CLASS_VARIABLES_decl
3800 = generate_ivars_list (ivar_list_template, "_OBJC_CLASS_VARIABLES",
3802 TREE_TYPE (UOBJC_CLASS_VARIABLES_decl) = variable_length_type;
3805 UOBJC_CLASS_VARIABLES_decl = 0;
3807 chain = CLASS_IVARS (implementation_template);
3810 size = list_length (chain);
3811 ivar_list_template = build_ivar_list_template (objc_ivar_template, size);
3812 initlist = build_ivar_list_initializer (objc_ivar_template, chain);
3814 UOBJC_INSTANCE_VARIABLES_decl
3815 = generate_ivars_list (ivar_list_template, "_OBJC_INSTANCE_VARIABLES",
3817 TREE_TYPE (UOBJC_INSTANCE_VARIABLES_decl) = variable_length_type;
3820 UOBJC_INSTANCE_VARIABLES_decl = 0;
3822 generating_instance_variables = 0;
3826 build_dispatch_table_initializer (type, entries)
3830 tree initlist = NULL_TREE;
3834 tree elemlist = NULL_TREE;
3836 elemlist = tree_cons (NULL_TREE,
3837 build_selector (METHOD_SEL_NAME (entries)),
3840 elemlist = tree_cons (NULL_TREE,
3841 add_objc_string (METHOD_ENCODING (entries),
3845 elemlist = tree_cons (NULL_TREE,
3846 build_unary_op (ADDR_EXPR,
3847 METHOD_DEFINITION (entries), 1),
3850 initlist = tree_cons (NULL_TREE,
3851 build_constructor (type, nreverse (elemlist)),
3854 entries = TREE_CHAIN (entries);
3858 return build_constructor (build_array_type (type, 0), nreverse (initlist));
3861 /* To accomplish method prototyping without generating all kinds of
3862 inane warnings, the definition of the dispatch table entries were
3865 struct objc_method { SEL _cmd; ...; id (*_imp)(); };
3867 struct objc_method { SEL _cmd; ...; void *_imp; }; */
3870 build_method_template ()
3873 tree decl_specs, field_decl, field_decl_chain;
3875 _SLT_record = start_struct (RECORD_TYPE, get_identifier (UTAG_METHOD));
3877 #ifdef OBJC_INT_SELECTORS
3878 /* unsigned int _cmd; */
3879 decl_specs = tree_cons (NULL_TREE, ridpointers[(int) RID_UNSIGNED],
3881 decl_specs = tree_cons (NULL_TREE, ridpointers[(int) RID_INT], decl_specs);
3882 field_decl = get_identifier ("_cmd");
3883 #else /* not OBJC_INT_SELECTORS */
3884 /* struct objc_selector *_cmd; */
3885 decl_specs = tree_cons (NULL_TREE,
3886 xref_tag (RECORD_TYPE,
3887 get_identifier (TAG_SELECTOR)),
3889 field_decl = build1 (INDIRECT_REF, NULL_TREE, get_identifier ("_cmd"));
3890 #endif /* not OBJC_INT_SELECTORS */
3892 field_decl = grokfield (input_filename, lineno, field_decl,
3893 decl_specs, NULL_TREE);
3894 field_decl_chain = field_decl;
3896 decl_specs = tree_cons (NULL_TREE, ridpointers[(int) RID_CHAR], NULL_TREE);
3897 field_decl = build1 (INDIRECT_REF, NULL_TREE,
3898 get_identifier ("method_types"));
3899 field_decl = grokfield (input_filename, lineno, field_decl,
3900 decl_specs, NULL_TREE);
3901 chainon (field_decl_chain, field_decl);
3905 decl_specs = tree_cons (NULL_TREE, ridpointers[(int) RID_VOID], NULL_TREE);
3906 field_decl = build1 (INDIRECT_REF, NULL_TREE, get_identifier ("_imp"));
3907 field_decl = grokfield (input_filename, lineno, field_decl,
3908 decl_specs, NULL_TREE);
3909 chainon (field_decl_chain, field_decl);
3911 finish_struct (_SLT_record, field_decl_chain, NULL_TREE);
3918 generate_dispatch_table (type, name, size, list)
3924 tree sc_spec, decl_specs, decl, initlist;
3926 sc_spec = tree_cons (NULL_TREE, ridpointers[(int) RID_STATIC], NULL_TREE);
3927 decl_specs = tree_cons (NULL_TREE, type, sc_spec);
3929 decl = start_decl (synth_id_with_class_suffix (name, implementation_context),
3930 decl_specs, 1, NULL_TREE, NULL_TREE);
3932 initlist = build_tree_list (NULL_TREE, build_int_2 (0, 0));
3933 initlist = tree_cons (NULL_TREE, build_int_2 (size, 0), initlist);
3934 initlist = tree_cons (NULL_TREE, list, initlist);
3937 build_constructor (TREE_TYPE (decl), nreverse (initlist)),
3944 generate_dispatch_tables ()
3946 tree initlist, chain, method_list_template;
3947 tree cast, variable_length_type;
3950 if (!objc_method_template)
3951 objc_method_template = build_method_template ();
3955 (build_tree_list (NULL_TREE,
3956 xref_tag (RECORD_TYPE,
3957 get_identifier (UTAG_METHOD_LIST))),
3960 variable_length_type = groktypename (cast);
3962 chain = CLASS_CLS_METHODS (implementation_context);
3965 size = list_length (chain);
3967 method_list_template
3968 = build_method_list_template (objc_method_template, size);
3970 = build_dispatch_table_initializer (objc_method_template, chain);
3972 UOBJC_CLASS_METHODS_decl
3973 = generate_dispatch_table (method_list_template,
3974 ((TREE_CODE (implementation_context)
3975 == CLASS_IMPLEMENTATION_TYPE)
3976 ? "_OBJC_CLASS_METHODS"
3977 : "_OBJC_CATEGORY_CLASS_METHODS"),
3979 TREE_TYPE (UOBJC_CLASS_METHODS_decl) = variable_length_type;
3982 UOBJC_CLASS_METHODS_decl = 0;
3984 chain = CLASS_NST_METHODS (implementation_context);
3987 size = list_length (chain);
3989 method_list_template
3990 = build_method_list_template (objc_method_template, size);
3992 = build_dispatch_table_initializer (objc_method_template, chain);
3994 if (TREE_CODE (implementation_context) == CLASS_IMPLEMENTATION_TYPE)
3995 UOBJC_INSTANCE_METHODS_decl
3996 = generate_dispatch_table (method_list_template,
3997 "_OBJC_INSTANCE_METHODS",
4000 /* We have a category. */
4001 UOBJC_INSTANCE_METHODS_decl
4002 = generate_dispatch_table (method_list_template,
4003 "_OBJC_CATEGORY_INSTANCE_METHODS",
4005 TREE_TYPE (UOBJC_INSTANCE_METHODS_decl) = variable_length_type;
4008 UOBJC_INSTANCE_METHODS_decl = 0;
4012 generate_protocol_list (i_or_p)
4015 static tree cast_type = 0;
4016 tree initlist, decl_specs, sc_spec;
4017 tree refs_decl, expr_decl, lproto, e, plist;
4020 if (TREE_CODE (i_or_p) == CLASS_INTERFACE_TYPE
4021 || TREE_CODE (i_or_p) == CATEGORY_INTERFACE_TYPE)
4022 plist = CLASS_PROTOCOL_LIST (i_or_p);
4023 else if (TREE_CODE (i_or_p) == PROTOCOL_INTERFACE_TYPE)
4024 plist = PROTOCOL_LIST (i_or_p);
4032 (build_tree_list (NULL_TREE,
4033 xref_tag (RECORD_TYPE,
4034 get_identifier (UTAG_PROTOCOL))),
4035 build1 (INDIRECT_REF, NULL_TREE, NULL_TREE)));
4038 for (lproto = plist; lproto; lproto = TREE_CHAIN (lproto))
4039 if (TREE_CODE (TREE_VALUE (lproto)) == PROTOCOL_INTERFACE_TYPE
4040 && PROTOCOL_FORWARD_DECL (TREE_VALUE (lproto)))
4043 /* Build initializer. */
4044 initlist = tree_cons (NULL_TREE, build_int_2 (0, 0), NULL_TREE);
4046 e = build_int_2 (size, 0);
4047 TREE_TYPE (e) = cast_type;
4048 initlist = tree_cons (NULL_TREE, e, initlist);
4050 for (lproto = plist; lproto; lproto = TREE_CHAIN (lproto))
4052 tree pval = TREE_VALUE (lproto);
4054 if (TREE_CODE (pval) == PROTOCOL_INTERFACE_TYPE
4055 && PROTOCOL_FORWARD_DECL (pval))
4057 e = build_unary_op (ADDR_EXPR, PROTOCOL_FORWARD_DECL (pval), 0);
4058 initlist = tree_cons (NULL_TREE, e, initlist);
4062 /* static struct objc_protocol *refs[n]; */
4064 sc_spec = tree_cons (NULL_TREE, ridpointers[(int) RID_STATIC], NULL_TREE);
4065 decl_specs = tree_cons (NULL_TREE, xref_tag (RECORD_TYPE,
4066 get_identifier (UTAG_PROTOCOL)),
4069 if (TREE_CODE (i_or_p) == PROTOCOL_INTERFACE_TYPE)
4070 expr_decl = build_nt (ARRAY_REF,
4071 synth_id_with_class_suffix ("_OBJC_PROTOCOL_REFS",
4073 build_int_2 (size + 2, 0));
4074 else if (TREE_CODE (i_or_p) == CLASS_INTERFACE_TYPE)
4075 expr_decl = build_nt (ARRAY_REF,
4076 synth_id_with_class_suffix ("_OBJC_CLASS_PROTOCOLS",
4078 build_int_2 (size + 2, 0));
4079 else if (TREE_CODE (i_or_p) == CATEGORY_INTERFACE_TYPE)
4081 = build_nt (ARRAY_REF,
4082 synth_id_with_class_suffix ("_OBJC_CATEGORY_PROTOCOLS",
4084 build_int_2 (size + 2, 0));
4086 expr_decl = build1 (INDIRECT_REF, NULL_TREE, expr_decl);
4088 refs_decl = start_decl (expr_decl, decl_specs, 1, NULL_TREE, NULL_TREE);
4090 finish_decl (refs_decl, build_constructor (TREE_TYPE (refs_decl),
4091 nreverse (initlist)),
4098 build_category_initializer (type, cat_name, class_name,
4099 instance_methods, class_methods, protocol_list)
4103 tree instance_methods;
4107 tree initlist = NULL_TREE, expr;
4109 initlist = tree_cons (NULL_TREE, cat_name, initlist);
4110 initlist = tree_cons (NULL_TREE, class_name, initlist);
4112 if (!instance_methods)
4113 initlist = tree_cons (NULL_TREE, build_int_2 (0, 0), initlist);
4116 expr = build_unary_op (ADDR_EXPR, instance_methods, 0);
4117 initlist = tree_cons (NULL_TREE, expr, initlist);
4120 initlist = tree_cons (NULL_TREE, build_int_2 (0, 0), initlist);
4123 expr = build_unary_op (ADDR_EXPR, class_methods, 0);
4124 initlist = tree_cons (NULL_TREE, expr, initlist);
4127 /* protocol_list = */
4129 initlist = tree_cons (NULL_TREE, build_int_2 (0, 0), initlist);
4132 static tree cast_type2;
4138 (build_tree_list (NULL_TREE,
4139 xref_tag (RECORD_TYPE,
4140 get_identifier (UTAG_PROTOCOL))),
4141 build1 (INDIRECT_REF, NULL_TREE,
4142 build1 (INDIRECT_REF, NULL_TREE, NULL_TREE))));
4144 expr = build_unary_op (ADDR_EXPR, protocol_list, 0);
4145 TREE_TYPE (expr) = cast_type2;
4146 initlist = tree_cons (NULL_TREE, expr, initlist);
4149 return build_constructor (type, nreverse (initlist));
4152 /* struct objc_class {
4153 struct objc_class *isa;
4154 struct objc_class *super_class;
4159 struct objc_ivar_list *ivars;
4160 struct objc_method_list *methods;
4161 if (flag_next_runtime)
4162 struct objc_cache *cache;
4164 struct sarray *dtable;
4165 struct objc_class *subclass_list;
4166 struct objc_class *sibling_class;
4168 struct objc_protocol_list *protocols;
4172 build_shared_structure_initializer (type, isa, super, name, size, status,
4173 dispatch_table, ivar_list, protocol_list)
4180 tree dispatch_table;
4184 tree initlist = NULL_TREE, expr;
4187 initlist = tree_cons (NULL_TREE, isa, initlist);
4190 initlist = tree_cons (NULL_TREE, super, initlist);
4193 initlist = tree_cons (NULL_TREE, default_conversion (name), initlist);
4196 initlist = tree_cons (NULL_TREE, build_int_2 (0, 0), initlist);
4199 initlist = tree_cons (NULL_TREE, build_int_2 (status, 0), initlist);
4201 /* instance_size = */
4202 initlist = tree_cons (NULL_TREE, size, initlist);
4204 /* objc_ivar_list = */
4206 initlist = tree_cons (NULL_TREE, build_int_2 (0, 0), initlist);
4209 expr = build_unary_op (ADDR_EXPR, ivar_list, 0);
4210 initlist = tree_cons (NULL_TREE, expr, initlist);
4213 /* objc_method_list = */
4214 if (!dispatch_table)
4215 initlist = tree_cons (NULL_TREE, build_int_2 (0, 0), initlist);
4218 expr = build_unary_op (ADDR_EXPR, dispatch_table, 0);
4219 initlist = tree_cons (NULL_TREE, expr, initlist);
4222 if (flag_next_runtime)
4223 /* method_cache = */
4224 initlist = tree_cons (NULL_TREE, build_int_2 (0, 0), initlist);
4228 initlist = tree_cons (NULL_TREE, build_int_2 (0, 0), initlist);
4230 /* subclass_list = */
4231 initlist = tree_cons (NULL_TREE, build_int_2 (0, 0), initlist);
4233 /* sibling_class = */
4234 initlist = tree_cons (NULL_TREE, build_int_2 (0, 0), initlist);
4237 /* protocol_list = */
4238 if (! protocol_list)
4239 initlist = tree_cons (NULL_TREE, build_int_2 (0, 0), initlist);
4242 static tree cast_type2;
4248 (build_tree_list (NULL_TREE,
4249 xref_tag (RECORD_TYPE,
4250 get_identifier (UTAG_PROTOCOL))),
4251 build1 (INDIRECT_REF, NULL_TREE,
4252 build1 (INDIRECT_REF, NULL_TREE, NULL_TREE))));
4254 expr = build_unary_op (ADDR_EXPR, protocol_list, 0);
4255 TREE_TYPE (expr) = cast_type2;
4256 initlist = tree_cons (NULL_TREE, expr, initlist);
4259 return build_constructor (type, nreverse (initlist));
4262 /* static struct objc_category _OBJC_CATEGORY_<name> = { ... }; */
4264 generate_category (cat)
4267 tree sc_spec, decl_specs, decl;
4268 tree initlist, cat_name_expr, class_name_expr;
4269 tree protocol_decl, category;
4271 add_class_reference (CLASS_NAME (cat));
4272 cat_name_expr = add_objc_string (CLASS_SUPER_NAME (cat), class_names);
4274 class_name_expr = add_objc_string (CLASS_NAME (cat), class_names);
4276 category = CLASS_CATEGORY_LIST (implementation_template);
4278 /* find the category interface from the class it is associated with */
4281 if (CLASS_SUPER_NAME (cat) == CLASS_SUPER_NAME (category))
4283 category = CLASS_CATEGORY_LIST (category);
4286 if (category && CLASS_PROTOCOL_LIST (category))
4288 generate_protocol_references (CLASS_PROTOCOL_LIST (category));
4289 protocol_decl = generate_protocol_list (category);
4294 sc_spec = tree_cons (NULL_TREE, ridpointers[(int) RID_STATIC], NULL_TREE);
4295 decl_specs = tree_cons (NULL_TREE, objc_category_template, sc_spec);
4297 decl = start_decl (synth_id_with_class_suffix ("_OBJC_CATEGORY",
4298 implementation_context),
4299 decl_specs, 1, NULL_TREE, NULL_TREE);
4301 initlist = build_category_initializer (TREE_TYPE (decl),
4302 cat_name_expr, class_name_expr,
4303 UOBJC_INSTANCE_METHODS_decl,
4304 UOBJC_CLASS_METHODS_decl,
4307 TREE_USED (decl) = 1;
4308 finish_decl (decl, initlist, NULL_TREE);
4311 /* static struct objc_class _OBJC_METACLASS_Foo={ ... };
4312 static struct objc_class _OBJC_CLASS_Foo={ ... }; */
4315 generate_shared_structures ()
4317 tree sc_spec, decl_specs, decl;
4318 tree name_expr, super_expr, root_expr;
4319 tree my_root_id = NULL_TREE, my_super_id = NULL_TREE;
4320 tree cast_type, initlist, protocol_decl;
4322 my_super_id = CLASS_SUPER_NAME (implementation_template);
4325 add_class_reference (my_super_id);
4327 /* Compute "my_root_id" - this is required for code generation.
4328 the "isa" for all meta class structures points to the root of
4329 the inheritance hierarchy (e.g. "__Object")... */
4330 my_root_id = my_super_id;
4333 tree my_root_int = lookup_interface (my_root_id);
4335 if (my_root_int && CLASS_SUPER_NAME (my_root_int))
4336 my_root_id = CLASS_SUPER_NAME (my_root_int);
4343 /* No super class. */
4344 my_root_id = CLASS_NAME (implementation_template);
4347 = groktypename (build_tree_list (build_tree_list (NULL_TREE,
4348 objc_class_template),
4349 build1 (INDIRECT_REF,
4350 NULL_TREE, NULL_TREE)));
4352 name_expr = add_objc_string (CLASS_NAME (implementation_template),
4355 /* Install class `isa' and `super' pointers at runtime. */
4358 super_expr = add_objc_string (my_super_id, class_names);
4359 super_expr = build_c_cast (cast_type, super_expr); /* cast! */
4362 super_expr = build_int_2 (0, 0);
4364 root_expr = add_objc_string (my_root_id, class_names);
4365 root_expr = build_c_cast (cast_type, root_expr); /* cast! */
4367 if (CLASS_PROTOCOL_LIST (implementation_template))
4369 generate_protocol_references
4370 (CLASS_PROTOCOL_LIST (implementation_template));
4371 protocol_decl = generate_protocol_list (implementation_template);
4376 /* static struct objc_class _OBJC_METACLASS_Foo = { ... }; */
4378 sc_spec = build_tree_list (NULL_TREE, ridpointers[(int) RID_STATIC]);
4379 decl_specs = tree_cons (NULL_TREE, objc_class_template, sc_spec);
4381 decl = start_decl (DECL_NAME (UOBJC_METACLASS_decl), decl_specs, 1,
4382 NULL_TREE, NULL_TREE);
4385 = build_shared_structure_initializer
4387 root_expr, super_expr, name_expr,
4388 build_int_2 ((TREE_INT_CST_LOW (TYPE_SIZE (objc_class_template))
4392 UOBJC_CLASS_METHODS_decl,
4393 UOBJC_CLASS_VARIABLES_decl,
4396 finish_decl (decl, initlist, NULL_TREE);
4398 /* static struct objc_class _OBJC_CLASS_Foo={ ... }; */
4400 decl = start_decl (DECL_NAME (UOBJC_CLASS_decl), decl_specs, 1,
4401 NULL_TREE, NULL_TREE);
4404 = build_shared_structure_initializer
4406 build_unary_op (ADDR_EXPR, UOBJC_METACLASS_decl, 0),
4407 super_expr, name_expr,
4410 (TYPE_SIZE (CLASS_STATIC_TEMPLATE (implementation_template)))
4414 UOBJC_INSTANCE_METHODS_decl,
4415 UOBJC_INSTANCE_VARIABLES_decl,
4418 finish_decl (decl, initlist, NULL_TREE);
4422 synth_id_with_class_suffix (preamble, ctxt)
4427 if (TREE_CODE (ctxt) == CLASS_IMPLEMENTATION_TYPE
4428 || TREE_CODE (ctxt) == CLASS_INTERFACE_TYPE)
4431 = IDENTIFIER_POINTER (CLASS_NAME (implementation_context));
4432 string = (char *) alloca (strlen (preamble) + strlen (class_name) + 3);
4433 sprintf (string, "%s_%s", preamble,
4434 IDENTIFIER_POINTER (CLASS_NAME (ctxt)));
4436 else if (TREE_CODE (ctxt) == CATEGORY_IMPLEMENTATION_TYPE
4437 || TREE_CODE (ctxt) == CATEGORY_INTERFACE_TYPE)
4439 /* We have a category. */
4441 = IDENTIFIER_POINTER (CLASS_NAME (implementation_context));
4442 char *class_super_name
4443 = IDENTIFIER_POINTER (CLASS_SUPER_NAME (implementation_context));
4444 string = (char *) alloca (strlen (preamble)
4445 + strlen (class_name)
4446 + strlen (class_super_name)
4448 sprintf (string, "%s_%s_%s", preamble, class_name, class_super_name);
4450 else if (TREE_CODE (ctxt) == PROTOCOL_INTERFACE_TYPE)
4452 char *protocol_name = IDENTIFIER_POINTER (PROTOCOL_NAME (ctxt));
4454 = (char *) alloca (strlen (preamble) + strlen (protocol_name) + 3);
4455 sprintf (string, "%s_%s", preamble, protocol_name);
4457 return get_identifier (string);
4461 is_objc_type_qualifier (node)
4464 return (TREE_CODE (node) == IDENTIFIER_NODE
4465 && (node == ridpointers [(int) RID_CONST]
4466 || node == ridpointers [(int) RID_VOLATILE]
4467 || node == ridpointers [(int) RID_IN]
4468 || node == ridpointers [(int) RID_OUT]
4469 || node == ridpointers [(int) RID_INOUT]
4470 || node == ridpointers [(int) RID_BYCOPY]
4471 || node == ridpointers [(int) RID_ONEWAY]));
4474 /* If type is empty or only type qualifiers are present, add default
4475 type of id (otherwise grokdeclarator will default to int). */
4478 adjust_type_for_id_default (type)
4481 tree declspecs, chain;
4484 return build_tree_list (build_tree_list (NULL_TREE, objc_object_reference),
4485 build1 (INDIRECT_REF, NULL_TREE, NULL_TREE));
4487 declspecs = TREE_PURPOSE (type);
4489 /* Determine if a typespec is present. */
4490 for (chain = declspecs;
4492 chain = TREE_CHAIN (chain))
4494 if (!is_objc_type_qualifier (TREE_VALUE (chain)))
4498 return build_tree_list (tree_cons (NULL_TREE, objc_object_reference,
4500 build1 (INDIRECT_REF, NULL_TREE, NULL_TREE));
4505 selector ':' '(' typename ')' identifier
4508 Transform an Objective-C keyword argument into
4509 the C equivalent parameter declarator.
4511 In: key_name, an "identifier_node" (optional).
4512 arg_type, a "tree_list" (optional).
4513 arg_name, an "identifier_node".
4515 Note: It would be really nice to strongly type the preceding
4516 arguments in the function prototype; however, then I
4517 could not use the "accessor" macros defined in "tree.h".
4519 Out: an instance of "keyword_decl". */
4522 build_keyword_decl (key_name, arg_type, arg_name)
4529 /* If no type is specified, default to "id". */
4530 arg_type = adjust_type_for_id_default (arg_type);
4532 keyword_decl = make_node (KEYWORD_DECL);
4534 TREE_TYPE (keyword_decl) = arg_type;
4535 KEYWORD_ARG_NAME (keyword_decl) = arg_name;
4536 KEYWORD_KEY_NAME (keyword_decl) = key_name;
4538 return keyword_decl;
4541 /* Given a chain of keyword_decl's, synthesize the full keyword selector. */
4544 build_keyword_selector (selector)
4548 tree key_chain, key_name;
4551 for (key_chain = selector; key_chain; key_chain = TREE_CHAIN (key_chain))
4553 if (TREE_CODE (selector) == KEYWORD_DECL)
4554 key_name = KEYWORD_KEY_NAME (key_chain);
4555 else if (TREE_CODE (selector) == TREE_LIST)
4556 key_name = TREE_PURPOSE (key_chain);
4559 len += IDENTIFIER_LENGTH (key_name) + 1;
4561 /* Just a ':' arg. */
4565 buf = (char *)alloca (len + 1);
4566 bzero (buf, len + 1);
4568 for (key_chain = selector; key_chain; key_chain = TREE_CHAIN (key_chain))
4570 if (TREE_CODE (selector) == KEYWORD_DECL)
4571 key_name = KEYWORD_KEY_NAME (key_chain);
4572 else if (TREE_CODE (selector) == TREE_LIST)
4573 key_name = TREE_PURPOSE (key_chain);
4576 strcat (buf, IDENTIFIER_POINTER (key_name));
4580 return get_identifier (buf);
4583 /* Used for declarations and definitions. */
4586 build_method_decl (code, ret_type, selector, add_args)
4587 enum tree_code code;
4594 /* If no type is specified, default to "id". */
4595 ret_type = adjust_type_for_id_default (ret_type);
4597 method_decl = make_node (code);
4598 TREE_TYPE (method_decl) = ret_type;
4600 /* If we have a keyword selector, create an identifier_node that
4601 represents the full selector name (`:' included)... */
4602 if (TREE_CODE (selector) == KEYWORD_DECL)
4604 METHOD_SEL_NAME (method_decl) = build_keyword_selector (selector);
4605 METHOD_SEL_ARGS (method_decl) = selector;
4606 METHOD_ADD_ARGS (method_decl) = add_args;
4610 METHOD_SEL_NAME (method_decl) = selector;
4611 METHOD_SEL_ARGS (method_decl) = NULL_TREE;
4612 METHOD_ADD_ARGS (method_decl) = NULL_TREE;
4618 #define METHOD_DEF 0
4619 #define METHOD_REF 1
4621 /* Used by `build_message_expr' and `comp_method_types'. Return an
4622 argument list for method METH. CONTEXT is either METHOD_DEF or
4623 METHOD_REF, saying whether we are trying to define a method or call
4624 one. SUPERFLAG says this is for a send to super; this makes a
4625 difference for the NeXT calling sequence in which the lookup and
4626 the method call are done together. */
4629 get_arg_type_list (meth, context, superflag)
4636 /* Receiver type. */
4637 if (flag_next_runtime && superflag)
4638 arglist = build_tree_list (NULL_TREE, super_type);
4639 else if (context == METHOD_DEF)
4640 arglist = build_tree_list (NULL_TREE, TREE_TYPE (self_decl));
4642 arglist = build_tree_list (NULL_TREE, id_type);
4644 /* Selector type - will eventually change to `int'. */
4645 chainon (arglist, build_tree_list (NULL_TREE, selector_type));
4647 /* Build a list of argument types. */
4648 for (akey = METHOD_SEL_ARGS (meth); akey; akey = TREE_CHAIN (akey))
4650 tree arg_decl = groktypename_in_parm_context (TREE_TYPE (akey));
4651 chainon (arglist, build_tree_list (NULL_TREE, TREE_TYPE (arg_decl)));
4654 if (METHOD_ADD_ARGS (meth) == (tree)1)
4655 /* We have a `, ...' immediately following the selector,
4656 finalize the arglist...simulate get_parm_info (0). */
4658 else if (METHOD_ADD_ARGS (meth))
4660 /* we have a variable length selector */
4661 tree add_arg_list = TREE_CHAIN (METHOD_ADD_ARGS (meth));
4662 chainon (arglist, add_arg_list);
4665 /* finalize the arglist...simulate get_parm_info (1) */
4666 chainon (arglist, build_tree_list (NULL_TREE, void_type_node));
4672 check_duplicates (hsh)
4675 tree meth = NULL_TREE;
4683 /* We have two methods with the same name and different types. */
4685 char type = (TREE_CODE (meth) == INSTANCE_METHOD_DECL) ? '-' : '+';
4687 warning ("multiple declarations for method `%s'",
4688 IDENTIFIER_POINTER (METHOD_SEL_NAME (meth)));
4690 warn_with_method ("using", type, meth);
4691 for (loop = hsh->list; loop; loop = loop->next)
4692 warn_with_method ("also found", type, loop->value);
4698 /* If RECEIVER is a class reference, return the identifier node for the
4699 referenced class. RECEIVER is created by get_class_reference, so we
4700 check the exact form created depending on which runtimes are used. */
4703 receiver_is_class_object (receiver)
4706 tree chain, exp, arg;
4707 if (flag_next_runtime)
4709 /* The receiver is a variable created by build_class_reference_decl. */
4710 if (TREE_CODE (receiver) == VAR_DECL
4711 && TREE_TYPE (receiver) == objc_class_type)
4712 /* Look up the identifier. */
4713 for (chain = cls_ref_chain; chain; chain = TREE_CHAIN (chain))
4714 if (TREE_PURPOSE (chain) == receiver)
4715 return TREE_VALUE (chain);
4719 /* The receiver is a function call that returns an id. Check if
4720 it is a call to objc_getClass, if so, pick up the class name. */
4721 if ((exp = TREE_OPERAND (receiver, 0))
4722 && TREE_CODE (exp) == ADDR_EXPR
4723 && (exp = TREE_OPERAND (exp, 0))
4724 && TREE_CODE (exp) == FUNCTION_DECL
4725 && exp == objc_get_class_decl
4726 /* we have a call to objc_getClass! */
4727 && (arg = TREE_OPERAND (receiver, 1))
4728 && TREE_CODE (arg) == TREE_LIST
4729 && (arg = TREE_VALUE (arg)))
4732 if (TREE_CODE (arg) == ADDR_EXPR
4733 && (arg = TREE_OPERAND (arg, 0))
4734 && TREE_CODE (arg) == STRING_CST)
4735 /* Finally, we have the class name. */
4736 return get_identifier (TREE_STRING_POINTER (arg));
4742 /* If we are currently building a message expr, this holds
4743 the identifier of the selector of the message. This is
4744 used when printing warnings about argument mismatches. */
4746 static tree building_objc_message_expr = 0;
4749 maybe_building_objc_message_expr ()
4751 return building_objc_message_expr;
4754 /* Construct an expression for sending a message.
4755 MESS has the object to send to in TREE_PURPOSE
4756 and the argument list (including selector) in TREE_VALUE.
4758 (*(<abstract_decl>(*)())_msg)(receiver, selTransTbl[n], ...);
4759 (*(<abstract_decl>(*)())_msgSuper)(receiver, selTransTbl[n], ...); */
4762 build_message_expr (mess)
4765 tree receiver = TREE_PURPOSE (mess);
4766 tree selector, self_object;
4767 tree rtype, sel_name;
4768 tree args = TREE_VALUE (mess);
4769 tree method_params = NULL_TREE;
4770 tree method_prototype = NULL_TREE;
4772 int statically_typed = 0, statically_allocated = 0;
4773 tree class_ident = 0;
4775 /* 1 if this is sending to the superclass. */
4778 if (!doing_objc_thang)
4781 if (TREE_CODE (receiver) == ERROR_MARK)
4782 return error_mark_node;
4784 /* Determine receiver type. */
4785 rtype = TREE_TYPE (receiver);
4786 super = IS_SUPER (rtype);
4790 if (TREE_STATIC_TEMPLATE (rtype))
4791 statically_allocated = 1;
4792 else if (TREE_CODE (rtype) == POINTER_TYPE
4793 && TREE_STATIC_TEMPLATE (TREE_TYPE (rtype)))
4794 statically_typed = 1;
4795 else if ((flag_next_runtime
4796 || (TREE_CODE (receiver) == CALL_EXPR && IS_ID (rtype)))
4797 && (class_ident = receiver_is_class_object (receiver)))
4799 else if (! IS_ID (rtype)
4800 /* Allow any type that matches objc_class_type. */
4801 && ! comptypes (rtype, objc_class_type))
4803 bzero (errbuf, BUFSIZE);
4804 warning ("invalid receiver type `%s'",
4805 gen_declaration (rtype, errbuf));
4808 if (statically_allocated)
4809 receiver = build_unary_op (ADDR_EXPR, receiver, 0);
4811 /* Don't evaluate the receiver twice. */
4812 receiver = save_expr (receiver);
4813 self_object = receiver;
4816 /* If sending to `super', use current self as the object. */
4817 self_object = self_decl;
4819 /* Obtain the full selector name. */
4821 if (TREE_CODE (args) == IDENTIFIER_NODE)
4822 /* A unary selector. */
4824 else if (TREE_CODE (args) == TREE_LIST)
4825 sel_name = build_keyword_selector (args);
4827 /* Build the parameter list to give to the method. */
4829 method_params = NULL_TREE;
4830 if (TREE_CODE (args) == TREE_LIST)
4832 tree chain = args, prev = NULL_TREE;
4834 /* We have a keyword selector--check for comma expressions. */
4837 tree element = TREE_VALUE (chain);
4839 /* We have a comma expression, must collapse... */
4840 if (TREE_CODE (element) == TREE_LIST)
4843 TREE_CHAIN (prev) = element;
4848 chain = TREE_CHAIN (chain);
4850 method_params = args;
4853 /* Determine operation return type. */
4855 if (IS_SUPER (rtype))
4859 if (CLASS_SUPER_NAME (implementation_template))
4862 = lookup_interface (CLASS_SUPER_NAME (implementation_template));
4864 if (TREE_CODE (method_context) == INSTANCE_METHOD_DECL)
4865 method_prototype = lookup_instance_method_static (iface, sel_name);
4867 method_prototype = lookup_class_method_static (iface, sel_name);
4869 if (iface && !method_prototype)
4870 warning ("`%s' does not respond to `%s'",
4871 IDENTIFIER_POINTER (CLASS_SUPER_NAME (implementation_template)),
4872 IDENTIFIER_POINTER (sel_name));
4876 error ("no super class declared in interface for `%s'",
4877 IDENTIFIER_POINTER (CLASS_NAME (implementation_template)));
4878 return error_mark_node;
4882 else if (statically_allocated)
4884 tree ctype = TREE_TYPE (rtype);
4885 tree iface = lookup_interface (TYPE_NAME (rtype));
4888 method_prototype = lookup_instance_method_static (iface, sel_name);
4890 if (! method_prototype && TYPE_PROTOCOL_LIST (ctype))
4892 = lookup_method_in_protocol_list (TYPE_PROTOCOL_LIST (ctype),
4895 if (!method_prototype)
4896 warning ("`%s' does not respond to `%s'",
4897 IDENTIFIER_POINTER (TYPE_NAME (rtype)),
4898 IDENTIFIER_POINTER (sel_name));
4900 else if (statically_typed)
4902 tree ctype = TREE_TYPE (rtype);
4904 /* `self' is now statically_typed. All methods should be visible
4905 within the context of the implementation. */
4906 if (implementation_context
4907 && CLASS_NAME (implementation_context) == TYPE_NAME (ctype))
4910 = lookup_instance_method_static (implementation_template,
4913 if (! method_prototype && TYPE_PROTOCOL_LIST (ctype))
4915 = lookup_method_in_protocol_list (TYPE_PROTOCOL_LIST (ctype),
4918 if (! method_prototype
4919 && implementation_template != implementation_context)
4920 /* The method is not published in the interface. Check locally. */
4922 = lookup_method (CLASS_NST_METHODS (implementation_context),
4929 if ((iface = lookup_interface (TYPE_NAME (ctype))))
4930 method_prototype = lookup_instance_method_static (iface, sel_name);
4932 if (! method_prototype)
4934 tree protocol_list = TYPE_PROTOCOL_LIST (ctype);
4937 = lookup_method_in_protocol_list (protocol_list,
4942 if (!method_prototype)
4943 warning ("`%s' does not respond to `%s'",
4944 IDENTIFIER_POINTER (TYPE_NAME (ctype)),
4945 IDENTIFIER_POINTER (sel_name));
4947 else if (class_ident)
4949 if (implementation_context
4950 && CLASS_NAME (implementation_context) == class_ident)
4953 = lookup_class_method_static (implementation_template, sel_name);
4955 if (!method_prototype
4956 && implementation_template != implementation_context)
4957 /* The method is not published in the interface. Check locally. */
4959 = lookup_method (CLASS_CLS_METHODS (implementation_context),
4966 if ((iface = lookup_interface (class_ident)))
4967 method_prototype = lookup_class_method_static (iface, sel_name);
4970 if (!method_prototype)
4972 warning ("cannot find class (factory) method.");
4973 warning ("return type for `%s' defaults to id",
4974 IDENTIFIER_POINTER (sel_name));
4977 else if (IS_PROTOCOL_QUALIFIED_ID (rtype))
4979 /* An anonymous object that has been qualified with a protocol. */
4981 tree protocol_list = TYPE_PROTOCOL_LIST (rtype);
4983 method_prototype = lookup_method_in_protocol_list (protocol_list,
4986 if (!method_prototype)
4990 warning ("method `%s' not implemented by protocol.",
4991 IDENTIFIER_POINTER (sel_name));
4993 /* Try and find the method signature in the global pools. */
4995 if (!(hsh = hash_lookup (nst_method_hash_list, sel_name)))
4996 hsh = hash_lookup (cls_method_hash_list, sel_name);
4998 if (!(method_prototype = check_duplicates (hsh)))
4999 warning ("return type defaults to id");
5006 /* We think we have an instance...loophole: extern id Object; */
5007 hsh = hash_lookup (nst_method_hash_list, sel_name);
5009 /* For various loopholes, like sending messages to self in a
5011 hsh = hash_lookup (cls_method_hash_list, sel_name);
5013 method_prototype = check_duplicates (hsh);
5014 if (!method_prototype)
5016 warning ("cannot find method.");
5017 warning ("return type for `%s' defaults to id",
5018 IDENTIFIER_POINTER (sel_name));
5022 /* Save the selector name for printing error messages. */
5023 building_objc_message_expr = sel_name;
5025 /* Build the parameters list for looking up the method.
5026 These are the object itself and the selector. */
5028 if (flag_typed_selectors)
5029 selector = build_typed_selector_reference (sel_name, method_prototype);
5031 selector = build_selector_reference (sel_name);
5033 retval = build_objc_method_call (super, method_prototype,
5034 receiver, self_object,
5035 selector, method_params);
5037 building_objc_message_expr = 0;
5042 /* Build a tree expression to send OBJECT the operation SELECTOR,
5043 looking up the method on object LOOKUP_OBJECT (often same as OBJECT),
5044 assuming the method has prototype METHOD_PROTOTYPE.
5045 (That is an INSTANCE_METHOD_DECL or CLASS_METHOD_DECL.)
5046 Use METHOD_PARAMS as list of args to pass to the method.
5047 If SUPER_FLAG is nonzero, we look up the superclass's method. */
5050 build_objc_method_call (super_flag, method_prototype, lookup_object, object,
5051 selector, method_params)
5053 tree method_prototype, lookup_object, object, selector, method_params;
5055 tree sender = (super_flag ? umsg_super_decl : umsg_decl);
5056 tree rcv_p = (super_flag
5057 ? build_pointer_type (xref_tag (RECORD_TYPE,
5058 get_identifier (TAG_SUPER)))
5061 if (flag_next_runtime)
5063 if (! method_prototype)
5065 method_params = tree_cons (NULL_TREE, lookup_object,
5066 tree_cons (NULL_TREE, selector,
5068 assemble_external (sender);
5069 return build_function_call (sender, method_params);
5073 /* This is a real kludge, but it is used only for the Next.
5074 Clobber the data type of SENDER temporarily to accept
5075 all the arguments for this operation, and to return
5076 whatever this operation returns. */
5077 tree arglist = NULL_TREE;
5080 /* Save the proper contents of SENDER's data type. */
5081 tree savarg = TYPE_ARG_TYPES (TREE_TYPE (sender));
5082 tree savret = TREE_TYPE (TREE_TYPE (sender));
5084 /* Install this method's argument types. */
5085 arglist = get_arg_type_list (method_prototype, METHOD_REF,
5087 TYPE_ARG_TYPES (TREE_TYPE (sender)) = arglist;
5089 /* Install this method's return type. */
5090 TREE_TYPE (TREE_TYPE (sender))
5091 = groktypename (TREE_TYPE (method_prototype));
5093 /* Call SENDER with all the parameters. This will do type
5094 checking using the arg types for this method. */
5095 method_params = tree_cons (NULL_TREE, lookup_object,
5096 tree_cons (NULL_TREE, selector,
5098 assemble_external (sender);
5099 retval = build_function_call (sender, method_params);
5101 /* Restore SENDER's return/argument types. */
5102 TYPE_ARG_TYPES (TREE_TYPE (sender)) = savarg;
5103 TREE_TYPE (TREE_TYPE (sender)) = savret;
5109 /* This is the portable way.
5110 First call the lookup function to get a pointer to the method,
5111 then cast the pointer, then call it with the method arguments. */
5114 /* Avoid trouble since we may evaluate each of these twice. */
5115 object = save_expr (object);
5116 selector = save_expr (selector);
5118 lookup_object = build_c_cast (rcv_p, lookup_object);
5120 assemble_external (sender);
5122 = build_function_call (sender,
5123 tree_cons (NULL_TREE, lookup_object,
5124 tree_cons (NULL_TREE, selector,
5127 /* If we have a method prototype, construct the data type this
5128 method needs, and cast what we got from SENDER into a pointer
5130 if (method_prototype)
5132 tree arglist = get_arg_type_list (method_prototype, METHOD_REF,
5134 tree valtype = groktypename (TREE_TYPE (method_prototype));
5135 tree fake_function_type = build_function_type (valtype, arglist);
5136 TREE_TYPE (method) = build_pointer_type (fake_function_type);
5140 = build_pointer_type (build_function_type (ptr_type_node, NULL_TREE));
5142 /* Pass the object to the method. */
5143 assemble_external (method);
5144 return build_function_call (method,
5145 tree_cons (NULL_TREE, object,
5146 tree_cons (NULL_TREE, selector,
5152 build_protocol_reference (p)
5155 tree decl, ident, ptype;
5157 push_obstacks_nochange ();
5158 end_temporary_allocation ();
5160 /* extern struct objc_protocol _OBJC_PROTOCOL_<mumble>; */
5162 ident = synth_id_with_class_suffix ("_OBJC_PROTOCOL", p);
5164 = groktypename (build_tree_list (build_tree_list (NULL_TREE,
5165 objc_protocol_template),
5168 if (IDENTIFIER_GLOBAL_VALUE (ident))
5169 decl = IDENTIFIER_GLOBAL_VALUE (ident); /* Set by pushdecl. */
5172 decl = build_decl (VAR_DECL, ident, ptype);
5173 DECL_EXTERNAL (decl) = 1;
5174 TREE_PUBLIC (decl) = 1;
5175 TREE_USED (decl) = 1;
5176 DECL_ARTIFICIAL (decl) = 1;
5178 make_decl_rtl (decl, 0, 1);
5179 pushdecl_top_level (decl);
5182 PROTOCOL_FORWARD_DECL (p) = decl;
5187 build_protocol_expr (protoname)
5193 if (!doing_objc_thang)
5196 p = lookup_protocol (protoname);
5200 error ("Cannot find protocol declaration for `%s'",
5201 IDENTIFIER_POINTER (protoname));
5202 return error_mark_node;
5205 if (!PROTOCOL_FORWARD_DECL (p))
5206 build_protocol_reference (p);
5208 expr = build_unary_op (ADDR_EXPR, PROTOCOL_FORWARD_DECL (p), 0);
5210 TREE_TYPE (expr) = protocol_type;
5216 build_selector_expr (selnamelist)
5221 if (!doing_objc_thang)
5224 /* Obtain the full selector name. */
5225 if (TREE_CODE (selnamelist) == IDENTIFIER_NODE)
5226 /* A unary selector. */
5227 selname = selnamelist;
5228 else if (TREE_CODE (selnamelist) == TREE_LIST)
5229 selname = build_keyword_selector (selnamelist);
5231 if (flag_typed_selectors)
5232 return build_typed_selector_reference (selname, 0);
5234 return build_selector_reference (selname);
5238 build_encode_expr (type)
5244 if (!doing_objc_thang)
5247 encode_type (type, obstack_object_size (&util_obstack),
5248 OBJC_ENCODE_INLINE_DEFS);
5249 obstack_1grow (&util_obstack, 0); /* null terminate string */
5250 string = obstack_finish (&util_obstack);
5252 /* Synthesize a string that represents the encoded struct/union. */
5253 result = my_build_string (strlen (string) + 1, string);
5254 obstack_free (&util_obstack, util_firstobj);
5259 build_ivar_reference (id)
5262 if (TREE_CODE (method_context) == CLASS_METHOD_DECL)
5264 /* Historically, a class method that produced objects (factory
5265 method) would assign `self' to the instance that it
5266 allocated. This would effectively turn the class method into
5267 an instance method. Following this assignment, the instance
5268 variables could be accessed. That practice, while safe,
5269 violates the simple rule that a class method should not refer
5270 to an instance variable. It's better to catch the cases
5271 where this is done unknowingly than to support the above
5273 warning ("instance variable `%s' accessed in class method",
5274 IDENTIFIER_POINTER (id));
5275 TREE_TYPE (self_decl) = instance_type; /* cast */
5278 return build_component_ref (build_indirect_ref (self_decl, "->"), id);
5281 #define HASH_ALLOC_LIST_SIZE 170
5282 #define ATTR_ALLOC_LIST_SIZE 170
5283 #define SIZEHASHTABLE 257
5286 #define HASHFUNCTION(key) ((HOST_WIDE_INT) key & 0x7fffffff)
5291 nst_method_hash_list = (hash *)xmalloc (SIZEHASHTABLE * sizeof (hash));
5292 cls_method_hash_list = (hash *)xmalloc (SIZEHASHTABLE * sizeof (hash));
5294 if (!nst_method_hash_list || !cls_method_hash_list)
5295 perror ("unable to allocate space in objc-tree.c");
5300 for (i = 0; i < SIZEHASHTABLE; i++)
5302 nst_method_hash_list[i] = 0;
5303 cls_method_hash_list[i] = 0;
5309 hash_enter (hashlist, method)
5313 static hash hash_alloc_list = 0;
5314 static int hash_alloc_index = 0;
5316 int slot = HASHFUNCTION (METHOD_SEL_NAME (method)) % SIZEHASHTABLE;
5318 if (! hash_alloc_list || hash_alloc_index >= HASH_ALLOC_LIST_SIZE)
5320 hash_alloc_index = 0;
5321 hash_alloc_list = (hash) xmalloc (sizeof (struct hashed_entry)
5322 * HASH_ALLOC_LIST_SIZE);
5323 if (! hash_alloc_list)
5324 perror ("unable to allocate in objc-tree.c");
5326 obj = &hash_alloc_list[hash_alloc_index++];
5328 obj->next = hashlist[slot];
5331 hashlist[slot] = obj; /* append to front */
5335 hash_lookup (hashlist, sel_name)
5341 target = hashlist[HASHFUNCTION (sel_name) % SIZEHASHTABLE];
5345 if (sel_name == METHOD_SEL_NAME (target->key))
5348 target = target->next;
5354 hash_add_attr (entry, value)
5358 static attr attr_alloc_list = 0;
5359 static int attr_alloc_index = 0;
5362 if (! attr_alloc_list || attr_alloc_index >= ATTR_ALLOC_LIST_SIZE)
5364 attr_alloc_index = 0;
5365 attr_alloc_list = (attr) xmalloc (sizeof (struct hashed_attribute)
5366 * ATTR_ALLOC_LIST_SIZE);
5367 if (! attr_alloc_list)
5368 perror ("unable to allocate in objc-tree.c");
5370 obj = &attr_alloc_list[attr_alloc_index++];
5371 obj->next = entry->list;
5374 entry->list = obj; /* append to front */
5378 lookup_method (mchain, method)
5384 if (TREE_CODE (method) == IDENTIFIER_NODE)
5387 key = METHOD_SEL_NAME (method);
5391 if (METHOD_SEL_NAME (mchain) == key)
5393 mchain = TREE_CHAIN (mchain);
5399 lookup_instance_method_static (interface, ident)
5403 tree inter = interface;
5404 tree chain = CLASS_NST_METHODS (inter);
5405 tree meth = NULL_TREE;
5409 if ((meth = lookup_method (chain, ident)))
5412 if (CLASS_CATEGORY_LIST (inter))
5414 tree category = CLASS_CATEGORY_LIST (inter);
5415 chain = CLASS_NST_METHODS (category);
5419 if ((meth = lookup_method (chain, ident)))
5422 /* Check for instance methods in protocols in categories. */
5423 if (CLASS_PROTOCOL_LIST (category))
5425 if ((meth = (lookup_method_in_protocol_list
5426 (CLASS_PROTOCOL_LIST (category), ident, 0))))
5430 if ((category = CLASS_CATEGORY_LIST (category)))
5431 chain = CLASS_NST_METHODS (category);
5436 if (CLASS_PROTOCOL_LIST (inter))
5438 if ((meth = (lookup_method_in_protocol_list
5439 (CLASS_PROTOCOL_LIST (inter), ident, 0))))
5443 if ((inter = lookup_interface (CLASS_SUPER_NAME (inter))))
5444 chain = CLASS_NST_METHODS (inter);
5452 lookup_class_method_static (interface, ident)
5456 tree inter = interface;
5457 tree chain = CLASS_CLS_METHODS (inter);
5458 tree meth = NULL_TREE;
5459 tree root_inter = NULL_TREE;
5463 if ((meth = lookup_method (chain, ident)))
5466 if (CLASS_CATEGORY_LIST (inter))
5468 tree category = CLASS_CATEGORY_LIST (inter);
5469 chain = CLASS_CLS_METHODS (category);
5473 if ((meth = lookup_method (chain, ident)))
5476 /* Check for class methods in protocols in categories. */
5477 if (CLASS_PROTOCOL_LIST (category))
5479 if ((meth = (lookup_method_in_protocol_list
5480 (CLASS_PROTOCOL_LIST (category), ident, 1))))
5484 if ((category = CLASS_CATEGORY_LIST (category)))
5485 chain = CLASS_CLS_METHODS (category);
5490 /* Check for class methods in protocols. */
5491 if (CLASS_PROTOCOL_LIST (inter))
5493 if ((meth = (lookup_method_in_protocol_list
5494 (CLASS_PROTOCOL_LIST (inter), ident, 1))))
5499 if ((inter = lookup_interface (CLASS_SUPER_NAME (inter))))
5500 chain = CLASS_CLS_METHODS (inter);
5504 /* Simulate wrap around. */
5505 return lookup_instance_method_static (root_inter, ident);
5509 add_class_method (class, method)
5516 /* We will have allocated the method parameter declarations on the
5517 maybepermanent_obstack. Need to make sure they stick around! */
5520 if (!(mth = lookup_method (CLASS_CLS_METHODS (class), method)))
5522 /* put method on list in reverse order */
5523 TREE_CHAIN (method) = CLASS_CLS_METHODS (class);
5524 CLASS_CLS_METHODS (class) = method;
5528 if (TREE_CODE (class) == CLASS_IMPLEMENTATION_TYPE)
5529 error ("duplicate definition of class method `%s'.",
5530 IDENTIFIER_POINTER (METHOD_SEL_NAME (mth)));
5533 /* Check types; if different, complain. */
5534 if (!comp_proto_with_proto (method, mth))
5535 error ("duplicate declaration of class method `%s'.",
5536 IDENTIFIER_POINTER (METHOD_SEL_NAME (mth)));
5540 if (!(hsh = hash_lookup (cls_method_hash_list, METHOD_SEL_NAME (method))))
5542 /* Install on a global chain. */
5543 hash_enter (cls_method_hash_list, method);
5547 /* Check types; if different, add to a list. */
5548 if (!comp_proto_with_proto (method, hsh->key))
5549 hash_add_attr (hsh, method);
5555 add_instance_method (class, method)
5562 /* We will have allocated the method parameter declarations on the
5563 maybepermanent_obstack. Need to make sure they stick around! */
5566 if (!(mth = lookup_method (CLASS_NST_METHODS (class), method)))
5568 /* Put method on list in reverse order. */
5569 TREE_CHAIN (method) = CLASS_NST_METHODS (class);
5570 CLASS_NST_METHODS (class) = method;
5574 if (TREE_CODE (class) == CLASS_IMPLEMENTATION_TYPE)
5575 error ("duplicate definition of instance method `%s'.",
5576 IDENTIFIER_POINTER (METHOD_SEL_NAME (mth)));
5579 /* Check types; if different, complain. */
5580 if (!comp_proto_with_proto (method, mth))
5581 error ("duplicate declaration of instance method `%s'.",
5582 IDENTIFIER_POINTER (METHOD_SEL_NAME (mth)));
5586 if (!(hsh = hash_lookup (nst_method_hash_list, METHOD_SEL_NAME (method))))
5588 /* Install on a global chain. */
5589 hash_enter (nst_method_hash_list, method);
5593 /* Check types; if different, add to a list. */
5594 if (!comp_proto_with_proto (method, hsh->key))
5595 hash_add_attr (hsh, method);
5604 /* Put interfaces on list in reverse order. */
5605 TREE_CHAIN (class) = interface_chain;
5606 interface_chain = class;
5607 return interface_chain;
5611 add_category (class, category)
5615 /* Put categories on list in reverse order. */
5616 tree cat = CLASS_CATEGORY_LIST (class);
5620 if (CLASS_SUPER_NAME (cat) == CLASS_SUPER_NAME (category))
5621 warning ("duplicate interface declaration for category `%s(%s)'",
5622 IDENTIFIER_POINTER (CLASS_NAME (class)),
5623 IDENTIFIER_POINTER (CLASS_SUPER_NAME (category)));
5624 cat = CLASS_CATEGORY_LIST (cat);
5627 CLASS_CATEGORY_LIST (category) = CLASS_CATEGORY_LIST (class);
5628 CLASS_CATEGORY_LIST (class) = category;
5631 /* Called after parsing each instance variable declaration. Necessary to
5632 preserve typedefs and implement public/private...
5634 PUBLIC is 1 for public, 0 for protected, and 2 for private. */
5637 add_instance_variable (class, public, declarator, declspecs, width)
5644 tree field_decl, raw_decl;
5646 raw_decl = build_tree_list (declspecs, declarator);
5648 if (CLASS_RAW_IVARS (class))
5649 chainon (CLASS_RAW_IVARS (class), raw_decl);
5651 CLASS_RAW_IVARS (class) = raw_decl;
5653 field_decl = grokfield (input_filename, lineno,
5654 declarator, declspecs, width);
5656 /* Overload the public attribute, it is not used for FIELD_DECLs. */
5660 TREE_PUBLIC (field_decl) = 0;
5661 TREE_PRIVATE (field_decl) = 0;
5662 TREE_PROTECTED (field_decl) = 1;
5666 TREE_PUBLIC (field_decl) = 1;
5667 TREE_PRIVATE (field_decl) = 0;
5668 TREE_PROTECTED (field_decl) = 0;
5672 TREE_PUBLIC (field_decl) = 0;
5673 TREE_PRIVATE (field_decl) = 1;
5674 TREE_PROTECTED (field_decl) = 0;
5679 if (CLASS_IVARS (class))
5680 chainon (CLASS_IVARS (class), field_decl);
5682 CLASS_IVARS (class) = field_decl;
5688 is_ivar (decl_chain, ident)
5692 for ( ; decl_chain; decl_chain = TREE_CHAIN (decl_chain))
5693 if (DECL_NAME (decl_chain) == ident)
5698 /* True if the ivar is private and we are not in its implementation. */
5704 if (TREE_PRIVATE (decl)
5705 && ! is_ivar (CLASS_IVARS (implementation_template), DECL_NAME (decl)))
5707 error ("instance variable `%s' is declared private",
5708 IDENTIFIER_POINTER (DECL_NAME (decl)));
5715 /* We have an instance variable reference;, check to see if it is public. */
5718 is_public (expr, identifier)
5722 tree basetype = TREE_TYPE (expr);
5723 enum tree_code code = TREE_CODE (basetype);
5726 if (code == RECORD_TYPE)
5728 if (TREE_STATIC_TEMPLATE (basetype))
5730 if (!lookup_interface (TYPE_NAME (basetype)))
5732 error ("Cannot find interface declaration for `%s'",
5733 IDENTIFIER_POINTER (TYPE_NAME (basetype)));
5737 if ((decl = is_ivar (TYPE_FIELDS (basetype), identifier)))
5739 if (TREE_PUBLIC (decl))
5742 /* Important difference between the Stepstone translator:
5743 all instance variables should be public within the context
5744 of the implementation. */
5745 if (implementation_context
5746 && (((TREE_CODE (implementation_context)
5747 == CLASS_IMPLEMENTATION_TYPE)
5748 || (TREE_CODE (implementation_context)
5749 == CATEGORY_IMPLEMENTATION_TYPE))
5750 && (CLASS_NAME (implementation_context)
5751 == TYPE_NAME (basetype))))
5752 return ! is_private (decl);
5754 error ("instance variable `%s' is declared %s",
5755 IDENTIFIER_POINTER (identifier),
5756 TREE_PRIVATE (decl) ? "private" : "protected");
5761 else if (implementation_context && (basetype == objc_object_reference))
5763 TREE_TYPE (expr) = uprivate_record;
5764 warning ("static access to object of type `id'");
5771 /* Implement @defs (<classname>) within struct bodies. */
5774 get_class_ivars (interface)
5777 if (!doing_objc_thang)
5780 return build_ivar_chain (interface, 1);
5783 /* Make sure all entries in CHAIN are also in LIST. */
5786 check_methods (chain, list, mtype)
5795 if (!lookup_method (list, chain))
5799 if (TREE_CODE (implementation_context)
5800 == CLASS_IMPLEMENTATION_TYPE)
5801 warning ("incomplete implementation of class `%s'",
5802 IDENTIFIER_POINTER (CLASS_NAME (implementation_context)));
5803 else if (TREE_CODE (implementation_context)
5804 == CATEGORY_IMPLEMENTATION_TYPE)
5805 warning ("incomplete implementation of category `%s'",
5806 IDENTIFIER_POINTER (CLASS_SUPER_NAME (implementation_context)));
5810 warning ("method definition for `%c%s' not found",
5811 mtype, IDENTIFIER_POINTER (METHOD_SEL_NAME (chain)));
5814 chain = TREE_CHAIN (chain);
5821 conforms_to_protocol (class, protocol)
5827 tree p = CLASS_PROTOCOL_LIST (class);
5829 while (p && TREE_VALUE (p) != TREE_VALUE (protocol))
5834 tree super = (CLASS_SUPER_NAME (class)
5835 ? lookup_interface (CLASS_SUPER_NAME (class))
5837 int tmp = super ? conforms_to_protocol (super, protocol) : 0;
5842 protocol = TREE_CHAIN (protocol);
5848 /* Make sure all methods in CHAIN are accessible as MTYPE methods in
5849 CONTEXT. This is one of two mechanisms to check protocol integrity. */
5852 check_methods_accessible (chain, context, mtype)
5859 tree base_context = context;
5863 context = base_context;
5867 list = CLASS_CLS_METHODS (context);
5869 list = CLASS_NST_METHODS (context);
5871 if (lookup_method (list, chain))
5874 else if (TREE_CODE (context) == CLASS_IMPLEMENTATION_TYPE
5875 || TREE_CODE (context) == CLASS_INTERFACE_TYPE)
5876 context = (CLASS_SUPER_NAME (context)
5877 ? lookup_interface (CLASS_SUPER_NAME (context))
5880 else if (TREE_CODE (context) == CATEGORY_IMPLEMENTATION_TYPE
5881 || TREE_CODE (context) == CATEGORY_INTERFACE_TYPE)
5882 context = (CLASS_NAME (context)
5883 ? lookup_interface (CLASS_NAME (context))
5889 if (context == NULL_TREE)
5893 if (TREE_CODE (implementation_context)
5894 == CLASS_IMPLEMENTATION_TYPE)
5895 warning ("incomplete implementation of class `%s'",
5897 (CLASS_NAME (implementation_context)));
5898 else if (TREE_CODE (implementation_context)
5899 == CATEGORY_IMPLEMENTATION_TYPE)
5900 warning ("incomplete implementation of category `%s'",
5902 (CLASS_SUPER_NAME (implementation_context)));
5905 warning ("method definition for `%c%s' not found",
5906 mtype, IDENTIFIER_POINTER (METHOD_SEL_NAME (chain)));
5909 chain = TREE_CHAIN (chain); /* next method... */
5915 check_protocols (proto_list, type, name)
5920 for ( ; proto_list; proto_list = TREE_CHAIN (proto_list))
5922 tree p = TREE_VALUE (proto_list);
5924 if (TREE_CODE (p) == PROTOCOL_INTERFACE_TYPE)
5928 /* Ensure that all protocols have bodies. */
5929 if (flag_warn_protocol) {
5930 f1 = check_methods (PROTOCOL_CLS_METHODS (p),
5931 CLASS_CLS_METHODS (implementation_context),
5933 f2 = check_methods (PROTOCOL_NST_METHODS (p),
5934 CLASS_NST_METHODS (implementation_context),
5937 f1 = check_methods_accessible (PROTOCOL_CLS_METHODS (p),
5938 implementation_context,
5940 f2 = check_methods_accessible (PROTOCOL_NST_METHODS (p),
5941 implementation_context,
5946 warning ("%s `%s' does not fully implement the `%s' protocol",
5947 type, name, IDENTIFIER_POINTER (PROTOCOL_NAME (p)));
5951 ; /* An identifier if we could not find a protocol. */
5953 /* Check protocols recursively. */
5954 if (PROTOCOL_LIST (p))
5957 = lookup_interface (CLASS_SUPER_NAME (implementation_template));
5958 if (! conforms_to_protocol (super_class, PROTOCOL_LIST (p)))
5959 check_protocols (PROTOCOL_LIST (p), type, name);
5964 /* Make sure that the class CLASS_NAME is defined
5965 CODE says which kind of thing CLASS_NAME ought to be.
5966 It can be CLASS_INTERFACE_TYPE, CLASS_IMPLEMENTATION_TYPE,
5967 CATEGORY_INTERFACE_TYPE, or CATEGORY_IMPLEMENTATION_TYPE.
5969 If CODE is CLASS_INTERFACE_TYPE, we also do a push_obstacks_nochange
5970 whose matching pop is in continue_class. */
5973 start_class (code, class_name, super_name, protocol_list)
5974 enum tree_code code;
5981 if (code == CLASS_INTERFACE_TYPE)
5983 push_obstacks_nochange ();
5984 end_temporary_allocation ();
5987 if (!doing_objc_thang)
5990 class = make_node (code);
5991 TYPE_BINFO (class) = make_tree_vec (5);
5993 CLASS_NAME (class) = class_name;
5994 CLASS_SUPER_NAME (class) = super_name;
5995 CLASS_CLS_METHODS (class) = NULL_TREE;
5997 if (! is_class_name (class_name) && (decl = lookup_name (class_name)))
5999 error ("`%s' redeclared as different kind of symbol",
6000 IDENTIFIER_POINTER (class_name));
6001 error_with_decl (decl, "previous declaration of `%s'");
6004 if (code == CLASS_IMPLEMENTATION_TYPE)
6007 static tree implemented_classes = 0;
6008 tree chain = implemented_classes;
6009 for (chain = implemented_classes; chain; chain = TREE_CHAIN (chain))
6010 if (TREE_VALUE (chain) == class_name)
6012 error ("reimplementation of class `%s'",
6013 IDENTIFIER_POINTER (class_name));
6014 return error_mark_node;
6016 implemented_classes = perm_tree_cons (NULL_TREE, class_name,
6017 implemented_classes);
6020 /* Pre-build the following entities - for speed/convenience. */
6022 self_id = get_identifier ("self");
6024 ucmd_id = get_identifier ("_cmd");
6027 = build_tree_list (get_identifier ("__unused__"), NULL_TREE);
6028 if (!objc_super_template)
6029 objc_super_template = build_super_template ();
6031 /* Reset for multiple classes per file. */
6034 implementation_context = class;
6036 /* Lookup the interface for this implementation. */
6038 if (!(implementation_template = lookup_interface (class_name)))
6040 warning ("Cannot find interface declaration for `%s'",
6041 IDENTIFIER_POINTER (class_name));
6042 add_class (implementation_template = implementation_context);
6045 /* If a super class has been specified in the implementation,
6046 insure it conforms to the one specified in the interface. */
6049 && (super_name != CLASS_SUPER_NAME (implementation_template)))
6051 tree previous_name = CLASS_SUPER_NAME (implementation_template);
6052 char *name = previous_name ? IDENTIFIER_POINTER (previous_name) : "";
6053 error ("conflicting super class name `%s'",
6054 IDENTIFIER_POINTER (super_name));
6055 error ("previous declaration of `%s'", name);
6058 else if (! super_name)
6060 CLASS_SUPER_NAME (implementation_context)
6061 = CLASS_SUPER_NAME (implementation_template);
6065 else if (code == CLASS_INTERFACE_TYPE)
6067 if (lookup_interface (class_name))
6068 warning ("duplicate interface declaration for class `%s'",
6069 IDENTIFIER_POINTER (class_name));
6074 CLASS_PROTOCOL_LIST (class)
6075 = lookup_and_install_protocols (protocol_list);
6078 else if (code == CATEGORY_INTERFACE_TYPE)
6080 tree class_category_is_assoc_with;
6082 /* For a category, class_name is really the name of the class that
6083 the following set of methods will be associated with. We must
6084 find the interface so that can derive the objects template. */
6086 if (!(class_category_is_assoc_with = lookup_interface (class_name)))
6088 error ("Cannot find interface declaration for `%s'",
6089 IDENTIFIER_POINTER (class_name));
6090 exit (FATAL_EXIT_CODE);
6093 add_category (class_category_is_assoc_with, class);
6096 CLASS_PROTOCOL_LIST (class)
6097 = lookup_and_install_protocols (protocol_list);
6100 else if (code == CATEGORY_IMPLEMENTATION_TYPE)
6102 /* Pre-build the following entities for speed/convenience. */
6104 self_id = get_identifier ("self");
6106 ucmd_id = get_identifier ("_cmd");
6109 = build_tree_list (get_identifier ("__unused__"), NULL_TREE);
6110 if (!objc_super_template)
6111 objc_super_template = build_super_template ();
6113 /* Reset for multiple classes per file. */
6116 implementation_context = class;
6118 /* For a category, class_name is really the name of the class that
6119 the following set of methods will be associated with. We must
6120 find the interface so that can derive the objects template. */
6122 if (!(implementation_template = lookup_interface (class_name)))
6124 error ("Cannot find interface declaration for `%s'",
6125 IDENTIFIER_POINTER (class_name));
6126 exit (FATAL_EXIT_CODE);
6133 continue_class (class)
6136 if (TREE_CODE (class) == CLASS_IMPLEMENTATION_TYPE
6137 || TREE_CODE (class) == CATEGORY_IMPLEMENTATION_TYPE)
6139 struct imp_entry *imp_entry;
6142 /* Check consistency of the instance variables. */
6144 if (CLASS_IVARS (class))
6145 check_ivars (implementation_template, class);
6147 /* code generation */
6149 ivar_context = build_private_template (implementation_template);
6151 if (!objc_class_template)
6152 build_class_template ();
6155 = (struct imp_entry *) xmalloc (sizeof (struct imp_entry))))
6156 perror ("unable to allocate in objc-tree.c");
6158 imp_entry->next = imp_list;
6159 imp_entry->imp_context = class;
6160 imp_entry->imp_template = implementation_template;
6162 synth_forward_declarations ();
6163 imp_entry->class_decl = UOBJC_CLASS_decl;
6164 imp_entry->meta_decl = UOBJC_METACLASS_decl;
6166 /* Append to front and increment count. */
6167 imp_list = imp_entry;
6168 if (TREE_CODE (class) == CLASS_IMPLEMENTATION_TYPE)
6173 return ivar_context;
6176 else if (TREE_CODE (class) == CLASS_INTERFACE_TYPE)
6178 tree record = xref_tag (RECORD_TYPE, CLASS_NAME (class));
6180 if (!TYPE_FIELDS (record))
6182 finish_struct (record, build_ivar_chain (class, 0), NULL_TREE);
6183 CLASS_STATIC_TEMPLATE (class) = record;
6185 /* Mark this record as a class template for static typing. */
6186 TREE_STATIC_TEMPLATE (record) = 1;
6193 return error_mark_node;
6196 /* This is called once we see the "@end" in an interface/implementation. */
6199 finish_class (class)
6202 if (TREE_CODE (class) == CLASS_IMPLEMENTATION_TYPE)
6204 /* All code generation is done in finish_objc. */
6206 if (implementation_template != implementation_context)
6208 /* Ensure that all method listed in the interface contain bodies. */
6209 check_methods (CLASS_CLS_METHODS (implementation_template),
6210 CLASS_CLS_METHODS (implementation_context), '+');
6211 check_methods (CLASS_NST_METHODS (implementation_template),
6212 CLASS_NST_METHODS (implementation_context), '-');
6214 if (CLASS_PROTOCOL_LIST (implementation_template))
6215 check_protocols (CLASS_PROTOCOL_LIST (implementation_template),
6217 IDENTIFIER_POINTER (CLASS_NAME (implementation_context)));
6221 else if (TREE_CODE (class) == CATEGORY_IMPLEMENTATION_TYPE)
6223 tree category = CLASS_CATEGORY_LIST (implementation_template);
6225 /* Find the category interface from the class it is associated with. */
6228 if (CLASS_SUPER_NAME (class) == CLASS_SUPER_NAME (category))
6230 category = CLASS_CATEGORY_LIST (category);
6235 /* Ensure all method listed in the interface contain bodies. */
6236 check_methods (CLASS_CLS_METHODS (category),
6237 CLASS_CLS_METHODS (implementation_context), '+');
6238 check_methods (CLASS_NST_METHODS (category),
6239 CLASS_NST_METHODS (implementation_context), '-');
6241 if (CLASS_PROTOCOL_LIST (category))
6242 check_protocols (CLASS_PROTOCOL_LIST (category),
6244 IDENTIFIER_POINTER (CLASS_SUPER_NAME (implementation_context)));
6248 else if (TREE_CODE (class) == CLASS_INTERFACE_TYPE)
6251 char *class_name = IDENTIFIER_POINTER (CLASS_NAME (class));
6252 char *string = (char *) alloca (strlen (class_name) + 3);
6254 /* extern struct objc_object *_<my_name>; */
6256 sprintf (string, "_%s", class_name);
6258 decl_specs = build_tree_list (NULL_TREE, ridpointers[(int) RID_EXTERN]);
6259 decl_specs = tree_cons (NULL_TREE, objc_object_reference, decl_specs);
6260 define_decl (build1 (INDIRECT_REF, NULL_TREE, get_identifier (string)),
6266 add_protocol (protocol)
6269 /* Put protocol on list in reverse order. */
6270 TREE_CHAIN (protocol) = protocol_chain;
6271 protocol_chain = protocol;
6272 return protocol_chain;
6276 lookup_protocol (ident)
6281 for (chain = protocol_chain; chain; chain = TREE_CHAIN (chain))
6283 if (ident == PROTOCOL_NAME (chain))
6291 start_protocol (code, name, list)
6292 enum tree_code code;
6298 if (!doing_objc_thang)
6301 /* This is as good a place as any. Need to invoke push_tag_toplevel. */
6302 if (!objc_protocol_template)
6303 objc_protocol_template = build_protocol_template ();
6305 protocol = make_node (code);
6306 TYPE_BINFO (protocol) = make_tree_vec (2);
6308 PROTOCOL_NAME (protocol) = name;
6309 PROTOCOL_LIST (protocol) = list;
6311 lookup_and_install_protocols (list);
6313 if (lookup_protocol (name))
6314 warning ("duplicate declaration for protocol `%s'",
6315 IDENTIFIER_POINTER (name));
6317 add_protocol (protocol);
6319 PROTOCOL_FORWARD_DECL (protocol) = NULL_TREE;
6325 finish_protocol (protocol)
6331 /* "Encode" a data type into a string, which grows in util_obstack.
6332 ??? What is the FORMAT? Someone please document this! */
6335 encode_type_qualifiers (declspecs)
6340 for (spec = declspecs; spec; spec = TREE_CHAIN (spec))
6342 if (ridpointers[(int) RID_CONST] == TREE_VALUE (spec))
6343 obstack_1grow (&util_obstack, 'r');
6344 else if (ridpointers[(int) RID_IN] == TREE_VALUE (spec))
6345 obstack_1grow (&util_obstack, 'n');
6346 else if (ridpointers[(int) RID_INOUT] == TREE_VALUE (spec))
6347 obstack_1grow (&util_obstack, 'N');
6348 else if (ridpointers[(int) RID_OUT] == TREE_VALUE (spec))
6349 obstack_1grow (&util_obstack, 'o');
6350 else if (ridpointers[(int) RID_BYCOPY] == TREE_VALUE (spec))
6351 obstack_1grow (&util_obstack, 'O');
6352 else if (ridpointers[(int) RID_ONEWAY] == TREE_VALUE (spec))
6353 obstack_1grow (&util_obstack, 'V');
6357 /* Encode a pointer type. */
6360 encode_pointer (type, curtype, format)
6365 tree pointer_to = TREE_TYPE (type);
6367 if (TREE_CODE (pointer_to) == RECORD_TYPE)
6369 if (TYPE_NAME (pointer_to)
6370 && TREE_CODE (TYPE_NAME (pointer_to)) == IDENTIFIER_NODE)
6372 char *name = IDENTIFIER_POINTER (TYPE_NAME (pointer_to));
6374 if (strcmp (name, TAG_OBJECT) == 0) /* '@' */
6376 obstack_1grow (&util_obstack, '@');
6379 else if (TREE_STATIC_TEMPLATE (pointer_to))
6381 if (generating_instance_variables)
6383 obstack_1grow (&util_obstack, '@');
6384 obstack_1grow (&util_obstack, '"');
6385 obstack_grow (&util_obstack, name, strlen (name));
6386 obstack_1grow (&util_obstack, '"');
6391 obstack_1grow (&util_obstack, '@');
6395 else if (strcmp (name, TAG_CLASS) == 0) /* '#' */
6397 obstack_1grow (&util_obstack, '#');
6400 #ifndef OBJC_INT_SELECTORS
6401 else if (strcmp (name, TAG_SELECTOR) == 0) /* ':' */
6403 obstack_1grow (&util_obstack, ':');
6406 #endif /* OBJC_INT_SELECTORS */
6409 else if (TREE_CODE (pointer_to) == INTEGER_TYPE
6410 && TYPE_MODE (pointer_to) == QImode)
6412 obstack_1grow (&util_obstack, '*');
6416 /* We have a type that does not get special treatment. */
6418 /* NeXT extension */
6419 obstack_1grow (&util_obstack, '^');
6420 encode_type (pointer_to, curtype, format);
6424 encode_array (type, curtype, format)
6429 tree an_int_cst = TYPE_SIZE (type);
6430 tree array_of = TREE_TYPE (type);
6433 /* An incomplete array is treated like a pointer. */
6434 if (an_int_cst == NULL)
6436 encode_pointer (type, curtype, format);
6440 sprintf (buffer, "[%d",
6441 (TREE_INT_CST_LOW (an_int_cst)
6442 / TREE_INT_CST_LOW (TYPE_SIZE (array_of))));
6444 obstack_grow (&util_obstack, buffer, strlen (buffer));
6445 encode_type (array_of, curtype, format);
6446 obstack_1grow (&util_obstack, ']');
6451 encode_aggregate (type, curtype, format)
6456 enum tree_code code = TREE_CODE (type);
6462 if (obstack_object_size (&util_obstack) > 0
6463 && *(obstack_next_free (&util_obstack) - 1) == '^')
6465 tree name = TYPE_NAME (type);
6467 /* We have a reference; this is a NeXT extension. */
6469 if (obstack_object_size (&util_obstack) - curtype == 1
6470 && format == OBJC_ENCODE_INLINE_DEFS)
6472 /* Output format of struct for first level only. */
6473 tree fields = TYPE_FIELDS (type);
6475 if (name && TREE_CODE (name) == IDENTIFIER_NODE)
6477 obstack_1grow (&util_obstack, '{');
6478 obstack_grow (&util_obstack,
6479 IDENTIFIER_POINTER (name),
6480 strlen (IDENTIFIER_POINTER (name)));
6481 obstack_1grow (&util_obstack, '=');
6485 obstack_grow (&util_obstack, "{?=", 3);
6487 for ( ; fields; fields = TREE_CHAIN (fields))
6488 encode_field_decl (fields, curtype, format);
6490 obstack_1grow (&util_obstack, '}');
6493 else if (name && TREE_CODE (name) == IDENTIFIER_NODE)
6495 obstack_1grow (&util_obstack, '{');
6496 obstack_grow (&util_obstack,
6497 IDENTIFIER_POINTER (name),
6498 strlen (IDENTIFIER_POINTER (name)));
6499 obstack_1grow (&util_obstack, '}');
6503 /* We have an untagged structure or a typedef. */
6504 obstack_grow (&util_obstack, "{?}", 3);
6509 tree name = TYPE_NAME (type);
6510 tree fields = TYPE_FIELDS (type);
6512 if (format == OBJC_ENCODE_INLINE_DEFS
6513 || generating_instance_variables)
6515 obstack_1grow (&util_obstack, '{');
6516 if (name && TREE_CODE (name) == IDENTIFIER_NODE)
6517 obstack_grow (&util_obstack,
6518 IDENTIFIER_POINTER (name),
6519 strlen (IDENTIFIER_POINTER (name)));
6522 obstack_1grow (&util_obstack, '?');
6524 obstack_1grow (&util_obstack, '=');
6526 for (; fields; fields = TREE_CHAIN (fields))
6528 if (generating_instance_variables)
6530 tree fname = DECL_NAME (fields);
6532 obstack_1grow (&util_obstack, '"');
6533 if (fname && TREE_CODE (fname) == IDENTIFIER_NODE)
6535 obstack_grow (&util_obstack,
6536 IDENTIFIER_POINTER (fname),
6537 strlen (IDENTIFIER_POINTER (fname)));
6540 obstack_1grow (&util_obstack, '"');
6543 encode_field_decl (fields, curtype, format);
6546 obstack_1grow (&util_obstack, '}');
6551 obstack_1grow (&util_obstack, '{');
6552 if (name && TREE_CODE (name) == IDENTIFIER_NODE)
6553 obstack_grow (&util_obstack,
6554 IDENTIFIER_POINTER (name),
6555 strlen (IDENTIFIER_POINTER (name)));
6557 /* We have an untagged structure or a typedef. */
6558 obstack_1grow (&util_obstack, '?');
6560 obstack_1grow (&util_obstack, '}');
6568 if (*obstack_next_free (&util_obstack) == '^'
6569 || format != OBJC_ENCODE_INLINE_DEFS)
6571 /* We have a reference (this is a NeXT extension)
6572 or we don't want the details. */
6573 if (TYPE_NAME (type)
6574 && TREE_CODE (TYPE_NAME (type)) == IDENTIFIER_NODE)
6576 obstack_1grow (&util_obstack, '(');
6577 obstack_grow (&util_obstack,
6578 IDENTIFIER_POINTER (TYPE_NAME (type)),
6579 strlen (IDENTIFIER_POINTER (TYPE_NAME (type))));
6580 obstack_1grow (&util_obstack, ')');
6584 /* We have an untagged structure or a typedef. */
6585 obstack_grow (&util_obstack, "(?)", 3);
6589 tree fields = TYPE_FIELDS (type);
6590 obstack_1grow (&util_obstack, '(');
6591 for ( ; fields; fields = TREE_CHAIN (fields))
6592 encode_field_decl (fields, curtype, format);
6594 obstack_1grow (&util_obstack, ')');
6600 obstack_1grow (&util_obstack, 'i');
6605 /* Support bitfields. The current version of Objective-C does not support
6606 them. The string will consist of one or more "b:n"'s where n is an
6607 integer describing the width of the bitfield. Currently, classes in
6608 the kit implement a method "-(char *)describeBitfieldStruct:" that
6609 simulates this. If they do not implement this method, the archiver
6610 assumes the bitfield is 16 bits wide (padded if necessary) and packed
6611 according to the GNU compiler. After looking at the "kit", it appears
6612 that all classes currently rely on this default behavior, rather than
6613 hand generating this string (which is tedious). */
6616 encode_bitfield (width, format)
6621 sprintf (buffer, "b%d", width);
6622 obstack_grow (&util_obstack, buffer, strlen (buffer));
6625 /* FORMAT will be OBJC_ENCODE_INLINE_DEFS or OBJC_ENCODE_DONT_INLINE_DEFS. */
6628 encode_type (type, curtype, format)
6633 enum tree_code code = TREE_CODE (type);
6635 if (code == INTEGER_TYPE)
6637 if (TREE_INT_CST_LOW (TYPE_MIN_VALUE (type)) == 0
6638 && TREE_INT_CST_HIGH (TYPE_MIN_VALUE (type)) == 0)
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_field_decl (field_decl, curtype, format)
6712 /* If this field is obviously a bitfield, or is a bitfield that has been
6713 clobbered to look like a ordinary integer mode, go ahead and generate
6714 the bitfield typing information. */
6715 type = TREE_TYPE (field_decl);
6716 if (DECL_BIT_FIELD (field_decl))
6717 encode_bitfield (DECL_FIELD_SIZE (field_decl), format);
6718 else if (TREE_CODE (TYPE_SIZE (type)) == INTEGER_CST
6719 && DECL_FIELD_SIZE (field_decl)
6720 && TYPE_MODE (type) > DECL_MODE (field_decl))
6721 encode_bitfield (DECL_FIELD_SIZE (field_decl), format);
6723 encode_type (TREE_TYPE (field_decl), curtype, format);
6727 expr_last (complex_expr)
6733 while ((next = TREE_OPERAND (complex_expr, 0)))
6734 complex_expr = next;
6736 return complex_expr;
6739 /* The selector of the current method,
6740 or NULL if we aren't compiling a method. */
6743 maybe_objc_method_name (decl)
6747 return METHOD_SEL_NAME (method_context);
6752 /* Transform a method definition into a function definition as follows:
6753 - synthesize the first two arguments, "self" and "_cmd". */
6756 start_method_def (method)
6761 /* Required to implement _msgSuper. */
6762 method_context = method;
6763 UOBJC_SUPER_decl = NULL_TREE;
6765 /* Must be called BEFORE start_function. */
6768 /* Generate prototype declarations for arguments..."new-style". */
6770 if (TREE_CODE (method_context) == INSTANCE_METHOD_DECL)
6771 decl_specs = build_tree_list (NULL_TREE, uprivate_record);
6773 /* Really a `struct objc_class *'. However, we allow people to
6774 assign to self, which changes its type midstream. */
6775 decl_specs = build_tree_list (NULL_TREE, objc_object_reference);
6777 push_parm_decl (build_tree_list
6778 (build_tree_list (decl_specs,
6779 build1 (INDIRECT_REF, NULL_TREE, self_id)),
6780 build_tree_list (unused_list, NULL_TREE)));
6782 #ifdef OBJC_INT_SELECTORS
6783 decl_specs = build_tree_list (NULL_TREE, ridpointers[(int) RID_UNSIGNED]);
6784 decl_specs = tree_cons (NULL_TREE, ridpointers[(int) RID_INT], decl_specs);
6785 push_parm_decl (build_tree_list (build_tree_list (decl_specs, ucmd_id),
6786 build_tree_list (unused_list, NULL_TREE)));
6787 #else /* not OBJC_INT_SELECTORS */
6788 decl_specs = build_tree_list (NULL_TREE,
6789 xref_tag (RECORD_TYPE,
6790 get_identifier (TAG_SELECTOR)));
6791 push_parm_decl (build_tree_list
6792 (build_tree_list (decl_specs,
6793 build1 (INDIRECT_REF, NULL_TREE, ucmd_id)),
6794 build_tree_list (unused_list, NULL_TREE)));
6795 #endif /* not OBJC_INT_SELECTORS */
6797 /* Generate argument declarations if a keyword_decl. */
6798 if (METHOD_SEL_ARGS (method))
6800 tree arglist = METHOD_SEL_ARGS (method);
6803 tree arg_spec = TREE_PURPOSE (TREE_TYPE (arglist));
6804 tree arg_decl = TREE_VALUE (TREE_TYPE (arglist));
6808 tree last_expr = expr_last (arg_decl);
6810 /* Unite the abstract decl with its name. */
6811 TREE_OPERAND (last_expr, 0) = KEYWORD_ARG_NAME (arglist);
6812 push_parm_decl (build_tree_list
6813 (build_tree_list (arg_spec, arg_decl),
6814 build_tree_list (NULL_TREE, NULL_TREE)));
6816 /* Unhook: restore the abstract declarator. */
6817 TREE_OPERAND (last_expr, 0) = NULL_TREE;
6821 push_parm_decl (build_tree_list
6822 (build_tree_list (arg_spec,
6823 KEYWORD_ARG_NAME (arglist)),
6824 build_tree_list (NULL_TREE, NULL_TREE)));
6826 arglist = TREE_CHAIN (arglist);
6831 if (METHOD_ADD_ARGS (method) > (tree)1)
6833 /* We have a variable length selector - in "prototype" format. */
6834 tree akey = TREE_PURPOSE (METHOD_ADD_ARGS (method));
6837 /* This must be done prior to calling pushdecl. pushdecl is
6838 going to change our chain on us. */
6839 tree nextkey = TREE_CHAIN (akey);
6847 warn_with_method (message, mtype, method)
6852 if (count_error (1) == 0)
6855 report_error_function (DECL_SOURCE_FILE (method));
6857 fprintf (stderr, "%s:%d: warning: ",
6858 DECL_SOURCE_FILE (method), DECL_SOURCE_LINE (method));
6859 bzero (errbuf, BUFSIZE);
6860 fprintf (stderr, "%s `%c%s'\n",
6861 message, mtype, gen_method_decl (method, errbuf));
6864 /* Return 1 if METHOD is consistent with PROTO. */
6867 comp_method_with_proto (method, proto)
6870 static tree function_type = 0;
6872 /* Create a function_type node once. */
6875 push_obstacks_nochange ();
6876 end_temporary_allocation ();
6877 function_type = make_node (FUNCTION_TYPE);
6881 /* Install argument types - normally set by build_function_type. */
6882 TYPE_ARG_TYPES (function_type) = get_arg_type_list (proto, METHOD_DEF, 0);
6884 /* install return type */
6885 TREE_TYPE (function_type) = groktypename (TREE_TYPE (proto));
6887 return comptypes (TREE_TYPE (METHOD_DEFINITION (method)), function_type);
6890 /* Return 1 if PROTO1 is consistent with PROTO2. */
6893 comp_proto_with_proto (proto1, proto2)
6894 tree proto1, proto2;
6896 static tree function_type1 = 0, function_type2 = 0;
6898 /* Create a couple function_type node's once. */
6899 if (!function_type1)
6901 push_obstacks_nochange ();
6902 end_temporary_allocation ();
6903 function_type1 = make_node (FUNCTION_TYPE);
6904 function_type2 = make_node (FUNCTION_TYPE);
6908 /* Install argument types; normally set by build_function_type. */
6909 TYPE_ARG_TYPES (function_type1) = get_arg_type_list (proto1, METHOD_REF, 0);
6910 TYPE_ARG_TYPES (function_type2) = get_arg_type_list (proto2, METHOD_REF, 0);
6912 /* Install return type. */
6913 TREE_TYPE (function_type1) = groktypename (TREE_TYPE (proto1));
6914 TREE_TYPE (function_type2) = groktypename (TREE_TYPE (proto2));
6916 return comptypes (function_type1, function_type2);
6919 /* - Generate an identifier for the function. the format is "_n_cls",
6920 where 1 <= n <= nMethods, and cls is the name the implementation we
6922 - Install the return type from the method declaration.
6923 - If we have a prototype, check for type consistency. */
6926 really_start_method (method, parmlist)
6927 tree method, parmlist;
6929 tree sc_spec, ret_spec, ret_decl, decl_specs;
6930 tree method_decl, method_id;
6931 char *buf, *sel_name, *class_name, *cat_name;
6933 /* Synth the storage class & assemble the return type. */
6934 sc_spec = tree_cons (NULL_TREE, ridpointers[(int) RID_STATIC], NULL_TREE);
6935 ret_spec = TREE_PURPOSE (TREE_TYPE (method));
6936 decl_specs = chainon (sc_spec, ret_spec);
6938 sel_name = IDENTIFIER_POINTER (METHOD_SEL_NAME (method));
6939 class_name = IDENTIFIER_POINTER (CLASS_NAME (implementation_context));
6940 cat_name = ((TREE_CODE (implementation_context)
6941 == CLASS_IMPLEMENTATION_TYPE)
6943 : IDENTIFIER_POINTER (CLASS_SUPER_NAME (implementation_context)));
6946 /* Make sure this is big enough for any plausible method label. */
6947 buf = (char *) alloca (50 + strlen (sel_name) + strlen (class_name)
6948 + (cat_name ? strlen (cat_name) : 0));
6950 OBJC_GEN_METHOD_LABEL (buf, TREE_CODE (method) == INSTANCE_METHOD_DECL,
6951 class_name, cat_name, sel_name, method_slot);
6953 method_id = get_identifier (buf);
6955 method_decl = build_nt (CALL_EXPR, method_id, parmlist, NULL_TREE);
6957 /* Check the declarator portion of the return type for the method. */
6958 if ((ret_decl = TREE_VALUE (TREE_TYPE (method))))
6960 /* Unite the complex decl (specified in the abstract decl) with the
6961 function decl just synthesized..(int *), (int (*)()), (int (*)[]). */
6962 tree save_expr = expr_last (ret_decl);
6964 TREE_OPERAND (save_expr, 0) = method_decl;
6965 method_decl = ret_decl;
6967 /* Fool the parser into thinking it is starting a function. */
6968 start_function (decl_specs, method_decl, NULL_TREE, NULL_TREE, 0);
6970 /* Unhook: this has the effect of restoring the abstract declarator. */
6971 TREE_OPERAND (save_expr, 0) = NULL_TREE;
6976 TREE_VALUE (TREE_TYPE (method)) = method_decl;
6978 /* Fool the parser into thinking it is starting a function. */
6979 start_function (decl_specs, method_decl, NULL_TREE, NULL_TREE, 0);
6981 /* Unhook: this has the effect of restoring the abstract declarator. */
6982 TREE_VALUE (TREE_TYPE (method)) = NULL_TREE;
6985 METHOD_DEFINITION (method) = current_function_decl;
6987 if (implementation_template != implementation_context)
6991 if (TREE_CODE (method) == INSTANCE_METHOD_DECL)
6992 proto = lookup_instance_method_static (implementation_template,
6993 METHOD_SEL_NAME (method));
6995 proto = lookup_class_method_static (implementation_template,
6996 METHOD_SEL_NAME (method));
6998 if (proto && ! comp_method_with_proto (method, proto))
7000 char type = (TREE_CODE (method) == INSTANCE_METHOD_DECL ? '-' : '+');
7002 warn_with_method ("conflicting types for", type, method);
7003 warn_with_method ("previous declaration of", type, proto);
7008 /* The following routine is always called...this "architecture" is to
7009 accommodate "old-style" variable length selectors.
7011 - a:a b:b // prototype ; id c; id d; // old-style. */
7014 continue_method_def ()
7018 if (METHOD_ADD_ARGS (method_context) == (tree)1)
7019 /* We have a `, ...' immediately following the selector. */
7020 parmlist = get_parm_info (0);
7022 parmlist = get_parm_info (1); /* place a `void_at_end' */
7024 /* Set self_decl from the first argument...this global is used by
7025 build_ivar_reference calling build_indirect_ref. */
7026 self_decl = TREE_PURPOSE (parmlist);
7029 really_start_method (method_context, parmlist);
7030 store_parm_decls ();
7033 /* Called by the parser, from the `pushlevel' production. */
7038 if (!UOBJC_SUPER_decl)
7040 UOBJC_SUPER_decl = start_decl (get_identifier (UTAG_SUPER),
7041 build_tree_list (NULL_TREE,
7042 objc_super_template),
7043 0, NULL_TREE, NULL_TREE);
7045 finish_decl (UOBJC_SUPER_decl, NULL_TREE, NULL_TREE);
7047 /* This prevents `unused variable' warnings when compiling with -Wall. */
7048 TREE_USED (UOBJC_SUPER_decl) = 1;
7049 DECL_ARTIFICIAL (UOBJC_SUPER_decl) = 1;
7053 /* _n_Method (id self, SEL sel, ...)
7055 struct objc_super _S;
7056 _msgSuper ((_S.self = self, _S.class = _cls, &_S), ...);
7060 get_super_receiver ()
7064 tree super_expr, super_expr_list;
7066 /* Set receiver to self. */
7067 super_expr = build_component_ref (UOBJC_SUPER_decl, self_id);
7068 super_expr = build_modify_expr (super_expr, NOP_EXPR, self_decl);
7069 super_expr_list = build_tree_list (NULL_TREE, super_expr);
7071 /* Set class to begin searching. */
7072 super_expr = build_component_ref (UOBJC_SUPER_decl,
7073 get_identifier ("class"));
7075 if (TREE_CODE (implementation_context) == CLASS_IMPLEMENTATION_TYPE)
7077 /* [_cls, __cls]Super are "pre-built" in
7078 synth_forward_declarations. */
7080 super_expr = build_modify_expr (super_expr, NOP_EXPR,
7081 ((TREE_CODE (method_context)
7082 == INSTANCE_METHOD_DECL)
7084 : uucls_super_ref));
7088 /* We have a category. */
7090 tree super_name = CLASS_SUPER_NAME (implementation_template);
7095 error ("no super class declared in interface for `%s'",
7096 IDENTIFIER_POINTER (CLASS_NAME (implementation_template)));
7097 return error_mark_node;
7100 if (flag_next_runtime)
7102 super_class = get_class_reference (super_name);
7103 if (TREE_CODE (method_context) == CLASS_METHOD_DECL)
7105 = build_component_ref (build_indirect_ref (super_class, "->"),
7106 get_identifier ("isa"));
7110 add_class_reference (super_name);
7111 super_class = (TREE_CODE (method_context) == INSTANCE_METHOD_DECL
7112 ? objc_get_class_decl : objc_get_meta_class_decl);
7113 assemble_external (super_class);
7115 = build_function_call
7119 my_build_string (IDENTIFIER_LENGTH (super_name) + 1,
7120 IDENTIFIER_POINTER (super_name))));
7123 TREE_TYPE (super_class) = TREE_TYPE (ucls_super_ref);
7124 super_expr = build_modify_expr (super_expr, NOP_EXPR, super_class);
7127 chainon (super_expr_list, build_tree_list (NULL_TREE, super_expr));
7129 super_expr = build_unary_op (ADDR_EXPR, UOBJC_SUPER_decl, 0);
7130 chainon (super_expr_list, build_tree_list (NULL_TREE, super_expr));
7132 return build_compound_expr (super_expr_list);
7136 error ("[super ...] must appear in a method context");
7137 return error_mark_node;
7142 encode_method_def (func_decl)
7147 int max_parm_end = 0;
7152 encode_type (TREE_TYPE (TREE_TYPE (func_decl)),
7153 obstack_object_size (&util_obstack),
7154 OBJC_ENCODE_INLINE_DEFS);
7157 for (parms = DECL_ARGUMENTS (func_decl); parms;
7158 parms = TREE_CHAIN (parms))
7160 int parm_end = (forwarding_offset (parms)
7161 + (TREE_INT_CST_LOW (TYPE_SIZE (TREE_TYPE (parms)))
7164 if (!offset_is_register && parm_end > max_parm_end)
7165 max_parm_end = parm_end;
7168 stack_size = max_parm_end - OBJC_FORWARDING_MIN_OFFSET;
7170 sprintf (buffer, "%d", stack_size);
7171 obstack_grow (&util_obstack, buffer, strlen (buffer));
7173 /* Argument types. */
7174 for (parms = DECL_ARGUMENTS (func_decl); parms;
7175 parms = TREE_CHAIN (parms))
7178 encode_type (TREE_TYPE (parms),
7179 obstack_object_size (&util_obstack),
7180 OBJC_ENCODE_INLINE_DEFS);
7182 /* Compute offset. */
7183 sprintf (buffer, "%d", forwarding_offset (parms));
7185 /* Indicate register. */
7186 if (offset_is_register)
7187 obstack_1grow (&util_obstack, '+');
7189 obstack_grow (&util_obstack, buffer, strlen (buffer));
7192 obstack_1grow (&util_obstack, 0);
7193 result = get_identifier (obstack_finish (&util_obstack));
7194 obstack_free (&util_obstack, util_firstobj);
7199 finish_method_def ()
7201 METHOD_ENCODING (method_context) = encode_method_def (current_function_decl);
7203 finish_function (0);
7205 /* Required to implement _msgSuper. This must be done AFTER finish_function,
7206 since the optimizer may find "may be used before set" errors. */
7207 method_context = NULL_TREE;
7211 lang_report_error_function (decl)
7216 fprintf (stderr, "In method `%s'\n",
7217 IDENTIFIER_POINTER (METHOD_SEL_NAME (method_context)));
7226 is_complex_decl (type)
7229 return (TREE_CODE (type) == ARRAY_TYPE
7230 || TREE_CODE (type) == FUNCTION_TYPE
7231 || (TREE_CODE (type) == POINTER_TYPE && ! IS_ID (type)));
7235 /* Code to convert a decl node into text for a declaration in C. */
7237 static char tmpbuf[256];
7240 adorn_decl (decl, str)
7244 enum tree_code code = TREE_CODE (decl);
7246 if (code == ARRAY_REF)
7248 tree an_int_cst = TREE_OPERAND (decl, 1);
7250 if (an_int_cst && TREE_CODE (an_int_cst) == INTEGER_CST)
7251 sprintf (str + strlen (str), "[%d]", TREE_INT_CST_LOW (an_int_cst));
7256 else if (code == ARRAY_TYPE)
7258 tree an_int_cst = TYPE_SIZE (decl);
7259 tree array_of = TREE_TYPE (decl);
7261 if (an_int_cst && TREE_CODE (an_int_cst) == INTEGER_TYPE)
7262 sprintf (str + strlen (str), "[%d]",
7263 (TREE_INT_CST_LOW (an_int_cst)
7264 / TREE_INT_CST_LOW (TYPE_SIZE (array_of))));
7269 else if (code == CALL_EXPR)
7271 tree chain = TREE_PURPOSE (TREE_OPERAND (decl, 1));
7276 gen_declaration (chain, str);
7277 chain = TREE_CHAIN (chain);
7284 else if (code == FUNCTION_TYPE)
7286 tree chain = TYPE_ARG_TYPES (decl);
7289 while (chain && TREE_VALUE (chain) != void_type_node)
7291 gen_declaration (TREE_VALUE (chain), str);
7292 chain = TREE_CHAIN (chain);
7293 if (chain && TREE_VALUE (chain) != void_type_node)
7299 else if (code == INDIRECT_REF)
7301 strcpy (tmpbuf, "*");
7302 if (TREE_TYPE (decl) && TREE_CODE (TREE_TYPE (decl)) == TREE_LIST)
7306 for (chain = nreverse (copy_list (TREE_TYPE (decl)));
7308 chain = TREE_CHAIN (chain))
7310 if (TREE_CODE (TREE_VALUE (chain)) == IDENTIFIER_NODE)
7312 strcat (tmpbuf, " ");
7313 strcat (tmpbuf, IDENTIFIER_POINTER (TREE_VALUE (chain)));
7317 strcat (tmpbuf, " ");
7319 strcat (tmpbuf, str);
7320 strcpy (str, tmpbuf);
7323 else if (code == POINTER_TYPE)
7325 strcpy (tmpbuf, "*");
7326 if (TREE_READONLY (decl) || TYPE_VOLATILE (decl))
7328 if (TREE_READONLY (decl))
7329 strcat (tmpbuf, " const");
7330 if (TYPE_VOLATILE (decl))
7331 strcat (tmpbuf, " volatile");
7333 strcat (tmpbuf, " ");
7335 strcat (tmpbuf, str);
7336 strcpy (str, tmpbuf);
7341 gen_declarator (decl, buf, name)
7348 enum tree_code code = TREE_CODE (decl);
7358 op = TREE_OPERAND (decl, 0);
7360 /* We have a pointer to a function or array...(*)(), (*)[] */
7361 if ((code == ARRAY_REF || code == CALL_EXPR)
7362 && op && TREE_CODE (op) == INDIRECT_REF)
7365 str = gen_declarator (op, buf, name);
7369 strcpy (tmpbuf, "(");
7370 strcat (tmpbuf, str);
7371 strcat (tmpbuf, ")");
7372 strcpy (str, tmpbuf);
7375 adorn_decl (decl, str);
7384 /* This clause is done iteratively rather than recursively. */
7387 op = (is_complex_decl (TREE_TYPE (decl))
7388 ? TREE_TYPE (decl) : NULL_TREE);
7390 adorn_decl (decl, str);
7392 /* We have a pointer to a function or array...(*)(), (*)[] */
7393 if (code == POINTER_TYPE
7394 && op && (TREE_CODE (op) == FUNCTION_TYPE
7395 || TREE_CODE (op) == ARRAY_TYPE))
7397 strcpy (tmpbuf, "(");
7398 strcat (tmpbuf, str);
7399 strcat (tmpbuf, ")");
7400 strcpy (str, tmpbuf);
7403 decl = (is_complex_decl (TREE_TYPE (decl))
7404 ? TREE_TYPE (decl) : NULL_TREE);
7407 while (decl && (code = TREE_CODE (decl)))
7412 case IDENTIFIER_NODE:
7413 /* Will only happen if we are processing a "raw" expr-decl. */
7414 strcpy (buf, IDENTIFIER_POINTER (decl));
7422 /* We have an abstract declarator or a _DECL node. */
7430 gen_declspecs (declspecs, buf, raw)
7439 for (chain = nreverse (copy_list (declspecs));
7440 chain; chain = TREE_CHAIN (chain))
7442 tree aspec = TREE_VALUE (chain);
7444 if (TREE_CODE (aspec) == IDENTIFIER_NODE)
7445 strcat (buf, IDENTIFIER_POINTER (aspec));
7446 else if (TREE_CODE (aspec) == RECORD_TYPE)
7448 if (TYPE_NAME (aspec))
7450 tree protocol_list = TYPE_PROTOCOL_LIST (aspec);
7452 if (! TREE_STATIC_TEMPLATE (aspec))
7453 strcat (buf, "struct ");
7454 strcat (buf, IDENTIFIER_POINTER (TYPE_NAME (aspec)));
7459 tree chain = protocol_list;
7466 (PROTOCOL_NAME (TREE_VALUE (chain))));
7467 chain = TREE_CHAIN (chain);
7476 strcat (buf, "untagged struct");
7479 else if (TREE_CODE (aspec) == UNION_TYPE)
7481 if (TYPE_NAME (aspec))
7483 if (! TREE_STATIC_TEMPLATE (aspec))
7484 strcat (buf, "union ");
7485 strcat (buf, IDENTIFIER_POINTER (TYPE_NAME (aspec)));
7488 strcat (buf, "untagged union");
7491 else if (TREE_CODE (aspec) == ENUMERAL_TYPE)
7493 if (TYPE_NAME (aspec))
7495 if (! TREE_STATIC_TEMPLATE (aspec))
7496 strcat (buf, "enum ");
7497 strcat (buf, IDENTIFIER_POINTER (TYPE_NAME (aspec)));
7500 strcat (buf, "untagged enum");
7503 else if (TREE_CODE (aspec) == TYPE_DECL && DECL_NAME (aspec))
7504 strcat (buf, IDENTIFIER_POINTER (DECL_NAME (aspec)));
7506 else if (IS_ID (aspec))
7508 tree protocol_list = TYPE_PROTOCOL_LIST (aspec);
7513 tree chain = protocol_list;
7520 (PROTOCOL_NAME (TREE_VALUE (chain))));
7521 chain = TREE_CHAIN (chain);
7528 if (TREE_CHAIN (chain))
7534 /* Type qualifiers. */
7535 if (TREE_READONLY (declspecs))
7536 strcat (buf, "const ");
7537 if (TYPE_VOLATILE (declspecs))
7538 strcat (buf, "volatile ");
7540 switch (TREE_CODE (declspecs))
7542 /* Type specifiers. */
7545 declspecs = TYPE_MAIN_VARIANT (declspecs);
7547 /* Signed integer types. */
7549 if (declspecs == short_integer_type_node)
7550 strcat (buf, "short int ");
7551 else if (declspecs == integer_type_node)
7552 strcat (buf, "int ");
7553 else if (declspecs == long_integer_type_node)
7554 strcat (buf, "long int ");
7555 else if (declspecs == long_long_integer_type_node)
7556 strcat (buf, "long long int ");
7557 else if (declspecs == signed_char_type_node
7558 || declspecs == char_type_node)
7559 strcat (buf, "char ");
7561 /* Unsigned integer types. */
7563 else if (declspecs == short_unsigned_type_node)
7564 strcat (buf, "unsigned short ");
7565 else if (declspecs == unsigned_type_node)
7566 strcat (buf, "unsigned int ");
7567 else if (declspecs == long_unsigned_type_node)
7568 strcat (buf, "unsigned long ");
7569 else if (declspecs == long_long_unsigned_type_node)
7570 strcat (buf, "unsigned long long ");
7571 else if (declspecs == unsigned_char_type_node)
7572 strcat (buf, "unsigned char ");
7576 declspecs = TYPE_MAIN_VARIANT (declspecs);
7578 if (declspecs == float_type_node)
7579 strcat (buf, "float ");
7580 else if (declspecs == double_type_node)
7581 strcat (buf, "double ");
7582 else if (declspecs == long_double_type_node)
7583 strcat (buf, "long double ");
7587 if (TYPE_NAME (declspecs)
7588 && TREE_CODE (TYPE_NAME (declspecs)) == IDENTIFIER_NODE)
7590 tree protocol_list = TYPE_PROTOCOL_LIST (declspecs);
7592 if (! TREE_STATIC_TEMPLATE (declspecs))
7593 strcat (buf, "struct ");
7594 strcat (buf, IDENTIFIER_POINTER (TYPE_NAME (declspecs)));
7598 tree chain = protocol_list;
7605 (PROTOCOL_NAME (TREE_VALUE (chain))));
7606 chain = TREE_CHAIN (chain);
7615 strcat (buf, "untagged struct");
7621 if (TYPE_NAME (declspecs)
7622 && TREE_CODE (TYPE_NAME (declspecs)) == IDENTIFIER_NODE)
7624 strcat (buf, "union ");
7625 strcat (buf, IDENTIFIER_POINTER (TYPE_NAME (declspecs)));
7630 strcat (buf, "untagged union ");
7634 if (TYPE_NAME (declspecs)
7635 && TREE_CODE (TYPE_NAME (declspecs)) == IDENTIFIER_NODE)
7637 strcat (buf, "enum ");
7638 strcat (buf, IDENTIFIER_POINTER (TYPE_NAME (declspecs)));
7643 strcat (buf, "untagged enum ");
7647 strcat (buf, "void ");
7652 tree protocol_list = TYPE_PROTOCOL_LIST (declspecs);
7657 tree chain = protocol_list;
7664 (PROTOCOL_NAME (TREE_VALUE (chain))));
7665 chain = TREE_CHAIN (chain);
7678 gen_declaration (atype_or_adecl, buf)
7679 tree atype_or_adecl;
7684 if (TREE_CODE (atype_or_adecl) == TREE_LIST)
7686 tree declspecs; /* "identifier_node", "record_type" */
7687 tree declarator; /* "array_ref", "indirect_ref", "call_expr"... */
7689 /* We have a "raw", abstract declarator (typename). */
7690 declarator = TREE_VALUE (atype_or_adecl);
7691 declspecs = TREE_PURPOSE (atype_or_adecl);
7693 gen_declspecs (declspecs, buf, 1);
7697 strcat (buf, gen_declarator (declarator, declbuf, ""));
7704 tree declspecs; /* "integer_type", "real_type", "record_type"... */
7705 tree declarator; /* "array_type", "function_type", "pointer_type". */
7707 if (TREE_CODE (atype_or_adecl) == FIELD_DECL
7708 || TREE_CODE (atype_or_adecl) == PARM_DECL
7709 || TREE_CODE (atype_or_adecl) == FUNCTION_DECL)
7710 atype = TREE_TYPE (atype_or_adecl);
7712 /* Assume we have a *_type node. */
7713 atype = atype_or_adecl;
7715 if (is_complex_decl (atype))
7719 /* Get the declaration specifier; it is at the end of the list. */
7720 declarator = chain = atype;
7722 chain = TREE_TYPE (chain); /* not TREE_CHAIN (chain); */
7723 while (is_complex_decl (chain));
7730 declarator = NULL_TREE;
7733 gen_declspecs (declspecs, buf, 0);
7735 if (TREE_CODE (atype_or_adecl) == FIELD_DECL
7736 || TREE_CODE (atype_or_adecl) == PARM_DECL
7737 || TREE_CODE (atype_or_adecl) == FUNCTION_DECL)
7739 char *decl_name = (DECL_NAME (atype_or_adecl)
7740 ? IDENTIFIER_POINTER (DECL_NAME (atype_or_adecl))
7746 strcat (buf, gen_declarator (declarator, declbuf, decl_name));
7749 else if (decl_name[0])
7752 strcat (buf, decl_name);
7755 else if (declarator)
7758 strcat (buf, gen_declarator (declarator, declbuf, ""));
7765 #define RAW_TYPESPEC(meth) (TREE_VALUE (TREE_PURPOSE (TREE_TYPE (meth))))
7768 gen_method_decl (method, buf)
7774 if (RAW_TYPESPEC (method) != objc_object_reference)
7777 gen_declaration (TREE_TYPE (method), buf);
7781 chain = METHOD_SEL_ARGS (method);
7784 /* We have a chain of keyword_decls. */
7787 if (KEYWORD_KEY_NAME (chain))
7788 strcat (buf, IDENTIFIER_POINTER (KEYWORD_KEY_NAME (chain)));
7791 if (RAW_TYPESPEC (chain) != objc_object_reference)
7794 gen_declaration (TREE_TYPE (chain), buf);
7798 strcat (buf, IDENTIFIER_POINTER (KEYWORD_ARG_NAME (chain)));
7799 if ((chain = TREE_CHAIN (chain)))
7804 if (METHOD_ADD_ARGS (method) == (tree)1)
7805 strcat (buf, ", ...");
7806 else if (METHOD_ADD_ARGS (method))
7808 /* We have a tree list node as generate by get_parm_info. */
7809 chain = TREE_PURPOSE (METHOD_ADD_ARGS (method));
7811 /* Know we have a chain of parm_decls. */
7815 gen_declaration (chain, buf);
7816 chain = TREE_CHAIN (chain);
7822 /* We have a unary selector. */
7823 strcat (buf, IDENTIFIER_POINTER (METHOD_SEL_NAME (method)));
7831 dump_interface (fp, chain)
7835 char *buf = (char *)xmalloc (256);
7836 char *my_name = IDENTIFIER_POINTER (CLASS_NAME (chain));
7837 tree ivar_decls = CLASS_RAW_IVARS (chain);
7838 tree nst_methods = CLASS_NST_METHODS (chain);
7839 tree cls_methods = CLASS_CLS_METHODS (chain);
7841 fprintf (fp, "\n@interface %s", my_name);
7843 if (CLASS_SUPER_NAME (chain))
7845 char *super_name = IDENTIFIER_POINTER (CLASS_SUPER_NAME (chain));
7846 fprintf (fp, " : %s\n", super_name);
7853 fprintf (fp, "{\n");
7857 fprintf (fp, "\t%s;\n", gen_declaration (ivar_decls, buf));
7858 ivar_decls = TREE_CHAIN (ivar_decls);
7861 fprintf (fp, "}\n");
7867 fprintf (fp, "- %s;\n", gen_method_decl (nst_methods, buf));
7868 nst_methods = TREE_CHAIN (nst_methods);
7874 fprintf (fp, "+ %s;\n", gen_method_decl (cls_methods, buf));
7875 cls_methods = TREE_CHAIN (cls_methods);
7877 fprintf (fp, "\n@end");
7883 /* Add the special tree codes of Objective C to the tables. */
7885 #define LAST_CODE LAST_AND_UNUSED_TREE_CODE
7887 gcc_obstack_init (&util_obstack);
7888 util_firstobj = (char *) obstack_finish (&util_obstack);
7891 = (char **) xrealloc (tree_code_type,
7892 sizeof (char *) * LAST_OBJC_TREE_CODE);
7894 = (int *) xrealloc (tree_code_length,
7895 sizeof (int) * LAST_OBJC_TREE_CODE);
7897 = (char **) xrealloc (tree_code_name,
7898 sizeof (char *) * LAST_OBJC_TREE_CODE);
7899 bcopy ((char *) objc_tree_code_type,
7900 (char *) (tree_code_type + (int) LAST_CODE),
7901 (((int) LAST_OBJC_TREE_CODE - (int) LAST_CODE)
7902 * sizeof (char *)));
7903 bcopy ((char *) objc_tree_code_length,
7904 (char *) (tree_code_length + (int) LAST_CODE),
7905 (((int) LAST_OBJC_TREE_CODE - (int) LAST_CODE)
7907 bcopy ((char *) objc_tree_code_name,
7908 (char *) (tree_code_name + (int) LAST_CODE),
7909 (((int) LAST_OBJC_TREE_CODE - (int) LAST_CODE)
7910 * sizeof (char *)));
7912 errbuf = (char *)xmalloc (BUFSIZE);
7914 synth_module_prologue ();
7920 struct imp_entry *impent;
7922 /* The internally generated initializers appear to have missing braces.
7923 Don't warn about this. */
7924 int save_warn_missing_braces = warn_missing_braces;
7925 warn_missing_braces = 0;
7927 generate_forward_declaration_to_string_table ();
7929 #ifdef OBJC_PROLOGUE
7933 if (implementation_context || class_names_chain
7934 || meth_var_names_chain || meth_var_types_chain || sel_ref_chain)
7935 generate_objc_symtab_decl ();
7937 for (impent = imp_list; impent; impent = impent->next)
7939 implementation_context = impent->imp_context;
7940 implementation_template = impent->imp_template;
7942 UOBJC_CLASS_decl = impent->class_decl;
7943 UOBJC_METACLASS_decl = impent->meta_decl;
7945 if (TREE_CODE (implementation_context) == CLASS_IMPLEMENTATION_TYPE)
7947 /* all of the following reference the string pool... */
7948 generate_ivar_lists ();
7949 generate_dispatch_tables ();
7950 generate_shared_structures ();
7954 generate_dispatch_tables ();
7955 generate_category (implementation_context);
7959 /* If we are using an array of selectors, we must always
7960 finish up the array decl even if no selectors were used. */
7961 if (! flag_next_runtime || sel_ref_chain)
7962 build_selector_translation_table ();
7965 generate_protocols ();
7967 if (objc_static_instances)
7968 generate_static_references ();
7970 if (implementation_context || class_names_chain || objc_static_instances
7971 || meth_var_names_chain || meth_var_types_chain || sel_ref_chain)
7973 /* Arrange for Objc data structures to be initialized at run time. */
7974 char *init_name = build_module_descriptor ();
7976 assemble_constructor (init_name);
7979 /* Dump the class references. This forces the appropriate classes
7980 to be linked into the executable image, preserving unix archive
7981 semantics. This can be removed when we move to a more dynamically
7982 linked environment. */
7984 for (chain = cls_ref_chain; chain; chain = TREE_CHAIN (chain))
7986 handle_class_ref (chain);
7987 if (TREE_PURPOSE (chain))
7988 generate_classref_translation_entry (chain);
7991 for (impent = imp_list; impent; impent = impent->next)
7992 handle_impent (impent);
7994 /* Dump the string table last. */
7996 generate_strings ();
7998 if (flag_gen_declaration)
8000 add_class (implementation_context);
8001 dump_interface (gen_declaration_file, implementation_context);
8009 /* Run through the selector hash tables and print a warning for any
8010 selector which has multiple methods. */
8012 for (slot = 0; slot < SIZEHASHTABLE; slot++)
8013 for (hsh = cls_method_hash_list[slot]; hsh; hsh = hsh->next)
8016 tree meth = hsh->key;
8017 char type = (TREE_CODE (meth) == INSTANCE_METHOD_DECL
8021 warning ("potential selector conflict for method `%s'",
8022 IDENTIFIER_POINTER (METHOD_SEL_NAME (meth)));
8023 warn_with_method ("found", type, meth);
8024 for (loop = hsh->list; loop; loop = loop->next)
8025 warn_with_method ("found", type, loop->value);
8028 for (slot = 0; slot < SIZEHASHTABLE; slot++)
8029 for (hsh = nst_method_hash_list[slot]; hsh; hsh = hsh->next)
8032 tree meth = hsh->key;
8033 char type = (TREE_CODE (meth) == INSTANCE_METHOD_DECL
8037 warning ("potential selector conflict for method `%s'",
8038 IDENTIFIER_POINTER (METHOD_SEL_NAME (meth)));
8039 warn_with_method ("found", type, meth);
8040 for (loop = hsh->list; loop; loop = loop->next)
8041 warn_with_method ("found", type, loop->value);
8045 warn_missing_braces = save_warn_missing_braces;
8048 /* Subroutines of finish_objc. */
8051 generate_classref_translation_entry (chain)
8054 tree expr, name, decl_specs, decl, sc_spec;
8057 type = TREE_TYPE (TREE_PURPOSE (chain));
8059 expr = add_objc_string (TREE_VALUE (chain), class_names);
8060 expr = build_c_cast (type, expr); /* cast! */
8062 name = DECL_NAME (TREE_PURPOSE (chain));
8064 sc_spec = build_tree_list (NULL_TREE, ridpointers[(int) RID_STATIC]);
8066 /* static struct objc_class * _OBJC_CLASS_REFERENCES_n = ...; */
8067 decl_specs = tree_cons (NULL_TREE, type, sc_spec);
8069 /* The decl that is returned from start_decl is the one that we
8070 forward declared in build_class_reference. */
8071 decl = start_decl (name, decl_specs, 1, NULL_TREE, NULL_TREE);
8072 finish_decl (decl, expr, NULL_TREE);
8077 handle_class_ref (chain)
8080 char *name = IDENTIFIER_POINTER (TREE_VALUE (chain));
8081 if (! flag_next_runtime)
8084 char *string = (char *) alloca (strlen (name) + 30);
8087 sprintf (string, "%sobjc_class_name_%s",
8088 (flag_next_runtime ? "." : "__"), name);
8090 /* Make a decl for this name, so we can use its address in a tree. */
8091 decl = build_decl (VAR_DECL, get_identifier (string), char_type_node);
8092 DECL_EXTERNAL (decl) = 1;
8093 TREE_PUBLIC (decl) = 1;
8096 rest_of_decl_compilation (decl, 0, 0, 0);
8098 /* Make following constant read-only (why not)? */
8099 readonly_data_section ();
8101 exp = build1 (ADDR_EXPR, string_type_node, decl);
8103 /* Align the section properly. */
8104 assemble_constant_align (exp);
8106 /* Inform the assembler about this new external thing. */
8107 assemble_external (decl);
8109 /* Output a constant to reference this address. */
8110 output_constant (exp, int_size_in_bytes (string_type_node));
8114 /* This overreliance on our assembler (i.e. lack of portability)
8115 should be dealt with at some point. The GNU strategy (above)
8116 won't work either, but it is a start. */
8117 char *string = (char *) alloca (strlen (name) + 30);
8118 sprintf (string, ".reference .objc_class_name_%s", name);
8119 assemble_asm (my_build_string (strlen (string) + 1, string));
8124 handle_impent (impent)
8125 struct imp_entry *impent;
8127 implementation_context = impent->imp_context;
8128 implementation_template = impent->imp_template;
8130 if (TREE_CODE (impent->imp_context) == CLASS_IMPLEMENTATION_TYPE)
8132 char *class_name = IDENTIFIER_POINTER (CLASS_NAME (impent->imp_context));
8133 char *string = (char *) alloca (strlen (class_name) + 30);
8135 if (flag_next_runtime)
8137 /* Grossly unportable.
8138 People should know better than to assume
8139 such things about assembler syntax! */
8140 sprintf (string, ".objc_class_name_%s=0", class_name);
8141 assemble_asm (my_build_string (strlen (string) + 1, string));
8143 sprintf (string, ".globl .objc_class_name_%s", class_name);
8144 assemble_asm (my_build_string (strlen (string) + 1, string));
8149 sprintf (string, "%sobjc_class_name_%s",
8150 (flag_next_runtime ? "." : "__"), class_name);
8151 assemble_global (string);
8152 assemble_label (string);
8156 else if (TREE_CODE (impent->imp_context) == CATEGORY_IMPLEMENTATION_TYPE)
8158 char *class_name = IDENTIFIER_POINTER (CLASS_NAME (impent->imp_context));
8159 char *class_super_name
8160 = IDENTIFIER_POINTER (CLASS_SUPER_NAME (impent->imp_context));
8161 char *string = (char *) alloca (strlen (class_name)
8162 + strlen (class_super_name) + 30);
8164 /* Do the same for categories. Even though no references to these
8165 symbols are generated automatically by the compiler, it gives
8166 you a handle to pull them into an archive by hand. */
8167 if (flag_next_runtime)
8169 /* Grossly unportable. */
8170 sprintf (string, ".objc_category_name_%s_%s=0",
8171 class_name, class_super_name);
8172 assemble_asm (my_build_string (strlen (string) + 1, string));
8174 sprintf (string, ".globl .objc_category_name_%s_%s",
8175 class_name, class_super_name);
8176 assemble_asm (my_build_string (strlen (string) + 1, string));
8181 sprintf (string, "%sobjc_category_name_%s_%s",
8182 (flag_next_runtime ? "." : "__"),
8183 class_name, class_super_name);
8184 assemble_global (string);
8185 assemble_label (string);
8196 char *buf = (char *)xmalloc (256);
8198 { /* dump function prototypes */
8199 tree loop = UOBJC_MODULES_decl;
8201 fprintf (fp, "\n\nfunction prototypes:\n");
8204 if (TREE_CODE (loop) == FUNCTION_DECL && DECL_INITIAL (loop))
8206 /* We have a function definition: generate prototype. */
8207 bzero (errbuf, BUFSIZE);
8208 gen_declaration (loop, errbuf);
8209 fprintf (fp, "%s;\n", errbuf);
8211 loop = TREE_CHAIN (loop);
8215 /* Dump global chains. */
8217 int i, index = 0, offset = 0;
8220 for (i = 0; i < SIZEHASHTABLE; i++)
8222 if (hashlist = nst_method_hash_list[i])
8224 fprintf (fp, "\n\nnst_method_hash_list[%d]:\n", i);
8228 fprintf (fp, "-%s;\n", gen_method_decl (hashlist->key, buf));
8229 hashlist = hashlist->next;
8235 for (i = 0; i < SIZEHASHTABLE; i++)
8237 if (hashlist = cls_method_hash_list[i])
8239 fprintf (fp, "\n\ncls_method_hash_list[%d]:\n", i);
8243 fprintf (fp, "-%s;\n", gen_method_decl (hashlist->key, buf));
8244 hashlist = hashlist->next;
8250 fprintf (fp, "\nsel_refdef_chain:\n");
8251 for (loop = sel_refdef_chain; loop; loop = TREE_CHAIN (loop))
8253 fprintf (fp, "(index: %4d offset: %4d) %s\n", index, offset,
8254 IDENTIFIER_POINTER (TREE_VALUE (loop)));
8256 /* add one for the '\0' character */
8257 offset += IDENTIFIER_LENGTH (TREE_VALUE (loop)) + 1;
8260 fprintf (fp, "\n (max_selector_index: %4d.\n", max_selector_index);
8266 print_lang_statistics ()