1 /* Implement classes and message passing for Objective C.
2 Copyright (C) 1992, 1993, 1994, 1995, 1997 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 */
53 /* This is the default way of generating a method name. */
54 /* I am not sure it is really correct.
55 Perhaps there's a danger that it will make name conflicts
56 if method names contain underscores. -- rms. */
57 #ifndef OBJC_GEN_METHOD_LABEL
58 #define OBJC_GEN_METHOD_LABEL(BUF, IS_INST, CLASS_NAME, CAT_NAME, SEL_NAME, NUM) \
61 sprintf ((BUF), "_%s_%s_%s_%s", \
62 ((IS_INST) ? "i" : "c"), \
64 ((CAT_NAME)? (CAT_NAME) : ""), \
66 for (temp = (BUF); *temp; temp++) \
67 if (*temp == ':') *temp = '_'; \
71 /* These need specifying. */
72 #ifndef OBJC_FORWARDING_STACK_OFFSET
73 #define OBJC_FORWARDING_STACK_OFFSET 0
76 #ifndef OBJC_FORWARDING_MIN_OFFSET
77 #define OBJC_FORWARDING_MIN_OFFSET 0
80 /* Define the special tree codes that we use. */
82 /* Table indexed by tree code giving a string containing a character
83 classifying the tree code. Possibilities are
84 t, d, s, c, r, <, 1 and 2. See objc-tree.def for details. */
86 #define DEFTREECODE(SYM, NAME, TYPE, LENGTH) TYPE,
88 char *objc_tree_code_type[] = {
90 #include "objc-tree.def"
94 /* Table indexed by tree code giving number of expression
95 operands beyond the fixed part of the node structure.
96 Not used for types or decls. */
98 #define DEFTREECODE(SYM, NAME, TYPE, LENGTH) LENGTH,
100 int objc_tree_code_length[] = {
102 #include "objc-tree.def"
106 /* Names of tree components.
107 Used for printing out the tree and error messages. */
108 #define DEFTREECODE(SYM, NAME, TYPE, LEN) NAME,
110 char *objc_tree_code_name[] = {
112 #include "objc-tree.def"
116 /* Set up for use of obstacks. */
120 #define obstack_chunk_alloc xmalloc
121 #define obstack_chunk_free free
123 /* This obstack is used to accumulate the encoding of a data type. */
124 static struct obstack util_obstack;
125 /* This points to the beginning of obstack contents,
126 so we can free the whole contents. */
129 /* List of classes with list of their static instances. */
130 static tree objc_static_instances = NULL_TREE;
132 /* The declaration of the array administrating the static instances. */
133 static tree static_instances_decl = NULL_TREE;
135 /* for encode_method_def */
139 #define OBJC_VERSION (flag_next_runtime ? 5 : 8)
140 #define PROTOCOL_VERSION 2
142 #define OBJC_ENCODE_INLINE_DEFS 0
143 #define OBJC_ENCODE_DONT_INLINE_DEFS 1
145 /*** Private Interface (procedures) ***/
147 /* Used by compile_file. */
149 static void init_objc PROTO((void));
150 static void finish_objc PROTO((void));
152 /* Code generation. */
154 static void synth_module_prologue PROTO((void));
155 static tree build_constructor PROTO((tree, tree));
156 static char *build_module_descriptor PROTO((void));
157 static tree init_module_descriptor PROTO((tree));
158 static tree build_objc_method_call PROTO((int, tree, tree,
160 static void generate_strings PROTO((void));
161 static tree get_proto_encoding PROTO((tree));
162 static void build_selector_translation_table PROTO((void));
163 static tree build_ivar_chain PROTO((tree, int));
165 static tree objc_add_static_instance PROTO((tree, tree));
167 static tree build_ivar_template PROTO((void));
168 static tree build_method_template PROTO((void));
169 static tree build_private_template PROTO((tree));
170 static void build_class_template PROTO((void));
171 static void build_selector_template PROTO((void));
172 static void build_category_template PROTO((void));
173 static tree build_super_template PROTO((void));
174 static tree build_category_initializer PROTO((tree, tree, tree,
176 static tree build_protocol_initializer PROTO((tree, tree, tree,
179 static void synth_forward_declarations PROTO((void));
180 static void generate_ivar_lists PROTO((void));
181 static void generate_dispatch_tables PROTO((void));
182 static void generate_shared_structures PROTO((void));
183 static tree generate_protocol_list PROTO((tree));
184 static void generate_forward_declaration_to_string_table PROTO((void));
185 static void build_protocol_reference PROTO((tree));
187 static tree init_selector PROTO((int));
188 static tree build_keyword_selector PROTO((tree));
189 static tree synth_id_with_class_suffix PROTO((char *, tree));
192 extern int apply_args_register_offset PROTO((int));
194 /* Misc. bookkeeping */
196 typedef struct hashed_entry *hash;
197 typedef struct hashed_attribute *attr;
199 struct hashed_attribute
211 static void hash_init PROTO((void));
212 static void hash_enter PROTO((hash *, tree));
213 static hash hash_lookup PROTO((hash *, tree));
214 static void hash_add_attr PROTO((hash, tree));
215 static tree lookup_method PROTO((tree, tree));
216 static tree lookup_instance_method_static PROTO((tree, tree));
217 static tree lookup_class_method_static PROTO((tree, tree));
218 static tree add_class PROTO((tree));
219 static void add_category PROTO((tree, tree));
223 class_names, /* class, category, protocol, module names */
224 meth_var_names, /* method and variable names */
225 meth_var_types /* method and variable type descriptors */
228 static tree add_objc_string PROTO((tree,
229 enum string_section));
230 static tree build_objc_string_decl PROTO((tree,
231 enum string_section));
232 static tree build_selector_reference_decl PROTO((tree));
234 /* Protocol additions. */
236 static tree add_protocol PROTO((tree));
237 static tree lookup_protocol PROTO((tree));
238 static tree lookup_and_install_protocols PROTO((tree));
242 static void encode_type_qualifiers PROTO((tree));
243 static void encode_pointer PROTO((tree, int, int));
244 static void encode_array PROTO((tree, int, int));
245 static void encode_aggregate PROTO((tree, int, int));
246 static void encode_bitfield PROTO((int, int));
247 static void encode_type PROTO((tree, int, int));
248 static void encode_field_decl PROTO((tree, int, int));
250 static void really_start_method PROTO((tree, tree));
251 static int comp_method_with_proto PROTO((tree, tree));
252 static int comp_proto_with_proto PROTO((tree, tree));
253 static tree get_arg_type_list PROTO((tree, int, int));
254 static tree expr_last PROTO((tree));
256 /* Utilities for debugging and error diagnostics. */
258 static void warn_with_method PROTO((char *, int, tree));
259 static void error_with_ivar PROTO((char *, tree, tree));
260 static char *gen_method_decl PROTO((tree, char *));
261 static char *gen_declaration PROTO((tree, char *));
262 static char *gen_declarator PROTO((tree, char *, char *));
263 static int is_complex_decl PROTO((tree));
264 static void adorn_decl PROTO((tree, char *));
265 static void dump_interface PROTO((FILE *, tree));
267 /* Everything else. */
269 static void objc_fatal PROTO((void));
270 static tree define_decl PROTO((tree, tree));
271 static tree lookup_method_in_protocol_list PROTO((tree, tree, int));
272 static tree lookup_protocol_in_reflist PROTO((tree, tree));
273 static tree create_builtin_decl PROTO((enum tree_code,
275 static tree my_build_string PROTO((int, char *));
276 static void build_objc_symtab_template PROTO((void));
277 static tree init_def_list PROTO((tree));
278 static tree init_objc_symtab PROTO((tree));
279 static void forward_declare_categories PROTO((void));
280 static void generate_objc_symtab_decl PROTO((void));
281 static tree build_selector PROTO((tree));
282 static tree build_msg_pool_reference PROTO((int));
283 static tree build_typed_selector_reference PROTO((tree, tree));
284 static tree build_selector_reference PROTO((tree));
285 static tree build_class_reference_decl PROTO((tree));
286 static void add_class_reference PROTO((tree));
287 static tree objc_copy_list PROTO((tree, tree *));
288 static tree build_protocol_template PROTO((void));
289 static tree build_descriptor_table_initializer PROTO((tree, tree));
290 static tree build_method_prototype_list_template PROTO((tree, int));
291 static tree build_method_prototype_template PROTO((void));
292 static int forwarding_offset PROTO((tree));
293 static tree encode_method_prototype PROTO((tree, tree));
294 static tree generate_descriptor_table PROTO((tree, char *, int, tree, tree));
295 static void generate_method_descriptors PROTO((tree));
296 static tree build_tmp_function_decl PROTO((void));
297 static void hack_method_prototype PROTO((tree, tree));
298 static void generate_protocol_references PROTO((tree));
299 static void generate_protocols PROTO((void));
300 static void check_ivars PROTO((tree, tree));
301 static tree build_ivar_list_template PROTO((tree, int));
302 static tree build_method_list_template PROTO((tree, int));
303 static tree build_ivar_list_initializer PROTO((tree, tree));
304 static tree generate_ivars_list PROTO((tree, char *,
306 static tree build_dispatch_table_initializer PROTO((tree, tree));
307 static tree generate_dispatch_table PROTO((tree, char *,
309 static tree build_shared_structure_initializer PROTO((tree, tree, tree, tree,
310 tree, int, tree, tree,
312 static void generate_category PROTO((tree));
313 static int is_objc_type_qualifier PROTO((tree));
314 static tree adjust_type_for_id_default PROTO((tree));
315 static tree check_duplicates PROTO((hash));
316 static tree receiver_is_class_object PROTO((tree));
317 static int check_methods PROTO((tree, tree, int));
318 static int conforms_to_protocol PROTO((tree, tree));
319 static void check_protocols PROTO((tree, char *, char *));
320 static tree encode_method_def PROTO((tree));
321 static void gen_declspecs PROTO((tree, char *, int));
322 static void generate_classref_translation_entry PROTO((tree));
323 static void handle_class_ref PROTO((tree));
325 /*** Private Interface (data) ***/
327 /* Reserved tag definitions. */
330 #define TAG_OBJECT "objc_object"
331 #define TAG_CLASS "objc_class"
332 #define TAG_SUPER "objc_super"
333 #define TAG_SELECTOR "objc_selector"
335 #define UTAG_CLASS "_objc_class"
336 #define UTAG_IVAR "_objc_ivar"
337 #define UTAG_IVAR_LIST "_objc_ivar_list"
338 #define UTAG_METHOD "_objc_method"
339 #define UTAG_METHOD_LIST "_objc_method_list"
340 #define UTAG_CATEGORY "_objc_category"
341 #define UTAG_MODULE "_objc_module"
342 #define UTAG_STATICS "_objc_statics"
343 #define UTAG_SYMTAB "_objc_symtab"
344 #define UTAG_SUPER "_objc_super"
345 #define UTAG_SELECTOR "_objc_selector"
347 #define UTAG_PROTOCOL "_objc_protocol"
348 #define UTAG_PROTOCOL_LIST "_objc_protocol_list"
349 #define UTAG_METHOD_PROTOTYPE "_objc_method_prototype"
350 #define UTAG_METHOD_PROTOTYPE_LIST "_objc__method_prototype_list"
352 #define STRING_OBJECT_CLASS_NAME "NXConstantString"
353 #define PROTOCOL_OBJECT_CLASS_NAME "Protocol"
355 static char *TAG_GETCLASS;
356 static char *TAG_GETMETACLASS;
357 static char *TAG_MSGSEND;
358 static char *TAG_MSGSENDSUPER;
359 static char *TAG_EXECCLASS;
361 /* Set by `continue_class' and checked by `is_public'. */
363 #define TREE_STATIC_TEMPLATE(record_type) (TREE_PUBLIC (record_type))
364 #define TYPED_OBJECT(type) \
365 (TREE_CODE (type) == RECORD_TYPE && TREE_STATIC_TEMPLATE (type))
367 /* Some commonly used instances of "identifier_node". */
369 static tree self_id, ucmd_id;
370 static tree unused_list;
372 static tree self_decl, umsg_decl, umsg_super_decl;
373 static tree objc_get_class_decl, objc_get_meta_class_decl;
375 static tree super_type, selector_type, id_type, objc_class_type;
376 static tree instance_type, protocol_type;
378 /* Type checking macros. */
380 #define IS_ID(TYPE) \
381 (TYPE_MAIN_VARIANT (TYPE) == TYPE_MAIN_VARIANT (id_type))
382 #define IS_PROTOCOL_QUALIFIED_ID(TYPE) \
383 (IS_ID (TYPE) && TYPE_PROTOCOL_LIST (TYPE))
384 #define IS_SUPER(TYPE) \
385 (super_type && TYPE_MAIN_VARIANT (TYPE) == TYPE_MAIN_VARIANT (super_type))
387 static tree class_chain = NULL_TREE;
388 static tree alias_chain = NULL_TREE;
389 static tree interface_chain = NULL_TREE;
390 static tree protocol_chain = NULL_TREE;
392 /* Chains to manage selectors that are referenced and defined in the
395 static tree cls_ref_chain = NULL_TREE; /* Classes referenced. */
396 static tree sel_ref_chain = NULL_TREE; /* Selectors referenced. */
398 /* Chains to manage uniquing of strings. */
400 static tree class_names_chain = NULL_TREE;
401 static tree meth_var_names_chain = NULL_TREE;
402 static tree meth_var_types_chain = NULL_TREE;
404 /* Hash tables to manage the global pool of method prototypes. */
406 static hash *nst_method_hash_list = 0;
407 static hash *cls_method_hash_list = 0;
409 /* Backend data declarations. */
411 static tree UOBJC_SYMBOLS_decl;
412 static tree UOBJC_INSTANCE_VARIABLES_decl, UOBJC_CLASS_VARIABLES_decl;
413 static tree UOBJC_INSTANCE_METHODS_decl, UOBJC_CLASS_METHODS_decl;
414 static tree UOBJC_CLASS_decl, UOBJC_METACLASS_decl;
415 static tree UOBJC_SELECTOR_TABLE_decl;
416 static tree UOBJC_MODULES_decl;
417 static tree UOBJC_STRINGS_decl;
419 /* The following are used when compiling a class implementation.
420 implementation_template will normally be an interface, however if
421 none exists this will be equal to implementation_context...it is
422 set in start_class. */
424 static tree implementation_context = NULL_TREE;
425 static tree implementation_template = NULL_TREE;
429 struct imp_entry *next;
432 tree class_decl; /* _OBJC_CLASS_<my_name>; */
433 tree meta_decl; /* _OBJC_METACLASS_<my_name>; */
436 static void handle_impent PROTO((struct imp_entry *));
438 static struct imp_entry *imp_list = 0;
439 static int imp_count = 0; /* `@implementation' */
440 static int cat_count = 0; /* `@category' */
442 static tree objc_class_template, objc_category_template, uprivate_record;
443 static tree objc_protocol_template, objc_selector_template;
444 static tree ucls_super_ref, uucls_super_ref;
446 static tree objc_method_template, objc_ivar_template;
447 static tree objc_symtab_template, objc_module_template;
448 static tree objc_super_template, objc_object_reference;
450 static tree objc_object_id, objc_class_id, objc_id_id;
451 static tree constant_string_id;
452 static tree constant_string_type;
453 static tree UOBJC_SUPER_decl;
455 static tree method_context = NULL_TREE;
456 static int method_slot = 0; /* Used by start_method_def, */
460 static char *errbuf; /* Buffer for error diagnostics */
462 /* Data imported from tree.c. */
464 extern enum debug_info_type write_symbols;
466 /* Data imported from toplev.c. */
468 extern char *dump_base_name;
470 /* Generate code for GNU or NeXT runtime environment. */
472 #ifdef NEXT_OBJC_RUNTIME
473 int flag_next_runtime = 1;
475 int flag_next_runtime = 0;
478 int flag_typed_selectors;
480 /* Open and close the file for outputting class declarations, if requested. */
482 int flag_gen_declaration = 0;
484 FILE *gen_declaration_file;
486 /* Warn if multiple methods are seen for the same selector, but with
487 different argument types. */
489 int warn_selector = 0;
491 /* Warn if methods required by a protocol are not implemented in the
492 class adopting it. When turned off, methods inherited to that
493 class are also considered implemented */
495 int flag_warn_protocol = 1;
497 /* Tells "encode_pointer/encode_aggregate" whether we are generating
498 type descriptors for instance variables (as opposed to methods).
499 Type descriptors for instance variables contain more information
500 than methods (for static typing and embedded structures). This
501 was added to support features being planned for dbkit2. */
503 static int generating_instance_variables = 0;
508 /* The beginning of the file is a new line; check for #.
509 With luck, we discover the real source file's name from that
510 and put it in input_filename. */
511 ungetc (check_newline (), finput);
513 /* The line number can be -1 if we had -g3 and the input file
514 had a directive specifying line 0. But we want predefined
515 functions to have a line number of 0, not -1. */
519 /* If gen_declaration desired, open the output file. */
520 if (flag_gen_declaration)
522 int dump_base_name_length = strlen (dump_base_name);
523 register char *dumpname = (char *) xmalloc (dump_base_name_length + 7);
524 strcpy (dumpname, dump_base_name);
525 strcat (dumpname, ".decl");
526 gen_declaration_file = fopen (dumpname, "w");
527 if (gen_declaration_file == 0)
528 pfatal_with_name (dumpname);
531 if (flag_next_runtime)
533 TAG_GETCLASS = "objc_getClass";
534 TAG_GETMETACLASS = "objc_getMetaClass";
535 TAG_MSGSEND = "objc_msgSend";
536 TAG_MSGSENDSUPER = "objc_msgSendSuper";
537 TAG_EXECCLASS = "__objc_execClass";
541 TAG_GETCLASS = "objc_get_class";
542 TAG_GETMETACLASS = "objc_get_meta_class";
543 TAG_MSGSEND = "objc_msg_lookup";
544 TAG_MSGSENDSUPER = "objc_msg_lookup_super";
545 TAG_EXECCLASS = "__objc_exec_class";
546 flag_typed_selectors = 1;
549 if (doing_objc_thang)
556 fatal ("Objective-C text in C source file");
562 if (doing_objc_thang)
563 finish_objc (); /* Objective-C finalization */
565 if (gen_declaration_file)
566 fclose (gen_declaration_file);
581 lang_decode_option (p)
584 if (!strcmp (p, "-lang-objc"))
585 doing_objc_thang = 1;
586 else if (!strcmp (p, "-gen-decls"))
587 flag_gen_declaration = 1;
588 else if (!strcmp (p, "-Wselector"))
590 else if (!strcmp (p, "-Wno-selector"))
592 else if (!strcmp (p, "-Wprotocol"))
593 flag_warn_protocol = 1;
594 else if (!strcmp (p, "-Wno-protocol"))
595 flag_warn_protocol = 0;
596 else if (!strcmp (p, "-fgnu-runtime"))
597 flag_next_runtime = 0;
598 else if (!strcmp (p, "-fno-next-runtime"))
599 flag_next_runtime = 0;
600 else if (!strcmp (p, "-fno-gnu-runtime"))
601 flag_next_runtime = 1;
602 else if (!strcmp (p, "-fnext-runtime"))
603 flag_next_runtime = 1;
605 return c_decode_option (p);
611 define_decl (declarator, declspecs)
615 tree decl = start_decl (declarator, declspecs, 0, NULL_TREE, NULL_TREE);
616 finish_decl (decl, NULL_TREE, NULL_TREE);
620 /* Return 1 if LHS and RHS are compatible types for assignment or
621 various other operations. Return 0 if they are incompatible, and
622 return -1 if we choose to not decide. When the operation is
623 REFLEXIVE, check for compatibility in either direction.
625 For statically typed objects, an assignment of the form `a' = `b'
629 `a' and `b' are the same class type, or
630 `a' and `b' are of class types A and B such that B is a descendant of A. */
633 maybe_objc_comptypes (lhs, rhs, reflexive)
637 if (doing_objc_thang)
638 return objc_comptypes (lhs, rhs, reflexive);
643 lookup_method_in_protocol_list (rproto_list, sel_name, class_meth)
651 for (rproto = rproto_list; rproto; rproto = TREE_CHAIN (rproto))
653 p = TREE_VALUE (rproto);
655 if (TREE_CODE (p) == PROTOCOL_INTERFACE_TYPE)
657 if ((fnd = lookup_method (class_meth
658 ? PROTOCOL_CLS_METHODS (p)
659 : PROTOCOL_NST_METHODS (p), sel_name)))
661 else if (PROTOCOL_LIST (p))
662 fnd = lookup_method_in_protocol_list (PROTOCOL_LIST (p),
663 sel_name, class_meth);
666 ; /* An identifier...if we could not find a protocol. */
676 lookup_protocol_in_reflist (rproto_list, lproto)
682 /* Make sure the protocol is support by the object on the rhs. */
683 if (TREE_CODE (lproto) == PROTOCOL_INTERFACE_TYPE)
686 for (rproto = rproto_list; rproto; rproto = TREE_CHAIN (rproto))
688 p = TREE_VALUE (rproto);
690 if (TREE_CODE (p) == PROTOCOL_INTERFACE_TYPE)
695 else if (PROTOCOL_LIST (p))
696 fnd = lookup_protocol_in_reflist (PROTOCOL_LIST (p), lproto);
704 ; /* An identifier...if we could not find a protocol. */
709 /* Return 1 if LHS and RHS are compatible types for assignment
710 or various other operations. Return 0 if they are incompatible,
711 and return -1 if we choose to not decide. When the operation
712 is REFLEXIVE, check for compatibility in either direction. */
715 objc_comptypes (lhs, rhs, reflexive)
720 /* New clause for protocols. */
722 if (TREE_CODE (lhs) == POINTER_TYPE
723 && TREE_CODE (TREE_TYPE (lhs)) == RECORD_TYPE
724 && TREE_CODE (rhs) == POINTER_TYPE
725 && TREE_CODE (TREE_TYPE (rhs)) == RECORD_TYPE)
727 int lhs_is_proto = IS_PROTOCOL_QUALIFIED_ID (lhs);
728 int rhs_is_proto = IS_PROTOCOL_QUALIFIED_ID (rhs);
732 tree lproto, lproto_list = TYPE_PROTOCOL_LIST (lhs);
733 tree rproto, rproto_list;
738 rproto_list = TYPE_PROTOCOL_LIST (rhs);
740 /* Make sure the protocol is supported by the object
742 for (lproto = lproto_list; lproto; lproto = TREE_CHAIN (lproto))
744 p = TREE_VALUE (lproto);
745 rproto = lookup_protocol_in_reflist (rproto_list, p);
748 warning ("object does not conform to the `%s' protocol",
749 IDENTIFIER_POINTER (PROTOCOL_NAME (p)));
752 else if (TYPED_OBJECT (TREE_TYPE (rhs)))
754 tree rname = TYPE_NAME (TREE_TYPE (rhs));
757 /* Make sure the protocol is supported by the object
759 for (lproto = lproto_list; lproto; lproto = TREE_CHAIN (lproto))
761 p = TREE_VALUE (lproto);
763 rinter = lookup_interface (rname);
765 while (rinter && !rproto)
769 rproto_list = CLASS_PROTOCOL_LIST (rinter);
770 rproto = lookup_protocol_in_reflist (rproto_list, p);
772 /* Check for protocols adopted by categories. */
773 cat = CLASS_CATEGORY_LIST (rinter);
774 while (cat && !rproto)
776 rproto_list = CLASS_PROTOCOL_LIST (cat);
777 rproto = lookup_protocol_in_reflist (rproto_list, p);
779 cat = CLASS_CATEGORY_LIST (cat);
782 rinter = lookup_interface (CLASS_SUPER_NAME (rinter));
786 warning ("class `%s' does not implement the `%s' protocol",
787 IDENTIFIER_POINTER (TYPE_NAME (TREE_TYPE (rhs))),
788 IDENTIFIER_POINTER (PROTOCOL_NAME (p)));
792 /* May change...based on whether there was any mismatch */
795 else if (rhs_is_proto)
796 /* Lhs is not a protocol...warn if it is statically typed */
797 return (TYPED_OBJECT (TREE_TYPE (lhs)) != 0);
800 /* Defer to comptypes .*/
804 else if (TREE_CODE (lhs) == RECORD_TYPE && TREE_CODE (rhs) == RECORD_TYPE)
805 ; /* Fall thru. This is the case we have been handling all along */
807 /* Defer to comptypes. */
810 /* `id' = `<class> *', `<class> *' = `id' */
812 if ((TYPE_NAME (lhs) == objc_object_id && TYPED_OBJECT (rhs))
813 || (TYPE_NAME (rhs) == objc_object_id && TYPED_OBJECT (lhs)))
816 /* `id' = `Class', `Class' = `id' */
818 else if ((TYPE_NAME (lhs) == objc_object_id
819 && TYPE_NAME (rhs) == objc_class_id)
820 || (TYPE_NAME (lhs) == objc_class_id
821 && TYPE_NAME (rhs) == objc_object_id))
824 /* `<class> *' = `<class> *' */
826 else if (TYPED_OBJECT (lhs) && TYPED_OBJECT (rhs))
828 tree lname = TYPE_NAME (lhs);
829 tree rname = TYPE_NAME (rhs);
835 /* If the left hand side is a super class of the right hand side,
837 for (inter = lookup_interface (rname); inter;
838 inter = lookup_interface (CLASS_SUPER_NAME (inter)))
839 if (lname == CLASS_SUPER_NAME (inter))
842 /* Allow the reverse when reflexive. */
844 for (inter = lookup_interface (lname); inter;
845 inter = lookup_interface (CLASS_SUPER_NAME (inter)))
846 if (rname == CLASS_SUPER_NAME (inter))
852 /* Defer to comptypes. */
856 /* Called from c-decl.c before all calls to rest_of_decl_compilation. */
859 objc_check_decl (decl)
862 tree type = TREE_TYPE (decl);
864 if (TREE_CODE (type) == RECORD_TYPE
865 && TREE_STATIC_TEMPLATE (type)
866 && type != constant_string_type)
868 error_with_decl (decl, "`%s' cannot be statically allocated");
869 fatal ("statically allocated objects not supported");
874 maybe_objc_check_decl (decl)
877 if (doing_objc_thang)
878 objc_check_decl (decl);
881 /* Implement static typing. At this point, we know we have an interface. */
884 get_static_reference (interface, protocols)
888 tree type = xref_tag (RECORD_TYPE, interface);
892 tree t, m = TYPE_MAIN_VARIANT (type);
894 push_obstacks_nochange ();
895 end_temporary_allocation ();
896 t = copy_node (type);
897 TYPE_BINFO (t) = make_tree_vec (2);
900 /* Add this type to the chain of variants of TYPE. */
901 TYPE_NEXT_VARIANT (t) = TYPE_NEXT_VARIANT (m);
902 TYPE_NEXT_VARIANT (m) = t;
904 /* Look up protocols and install in lang specific list. */
905 TYPE_PROTOCOL_LIST (t) = lookup_and_install_protocols (protocols);
907 /* This forces a new pointer type to be created later
908 (in build_pointer_type)...so that the new template
909 we just created will actually be used...what a hack! */
910 if (TYPE_POINTER_TO (t))
911 TYPE_POINTER_TO (t) = 0;
920 get_object_reference (protocols)
923 tree type_decl = lookup_name (objc_id_id);
926 if (type_decl && TREE_CODE (type_decl) == TYPE_DECL)
928 type = TREE_TYPE (type_decl);
929 if (TYPE_MAIN_VARIANT (type) != id_type)
930 warning ("Unexpected type for `id' (%s)",
931 gen_declaration (type, errbuf));
934 fatal ("Undefined type `id', please import <objc/objc.h>");
936 /* This clause creates a new pointer type that is qualified with
937 the protocol specification...this info is used later to do more
938 elaborate type checking. */
942 tree t, m = TYPE_MAIN_VARIANT (type);
944 push_obstacks_nochange ();
945 end_temporary_allocation ();
946 t = copy_node (type);
947 TYPE_BINFO (t) = make_tree_vec (2);
950 /* Add this type to the chain of variants of TYPE. */
951 TYPE_NEXT_VARIANT (t) = TYPE_NEXT_VARIANT (m);
952 TYPE_NEXT_VARIANT (m) = t;
954 /* Look up protocols...and install in lang specific list */
955 TYPE_PROTOCOL_LIST (t) = lookup_and_install_protocols (protocols);
957 /* This forces a new pointer type to be created later
958 (in build_pointer_type)...so that the new template
959 we just created will actually be used...what a hack! */
960 if (TYPE_POINTER_TO (t))
961 TYPE_POINTER_TO (t) = NULL;
969 lookup_and_install_protocols (protocols)
974 tree return_value = protocols;
976 for (proto = protocols; proto; proto = TREE_CHAIN (proto))
978 tree ident = TREE_VALUE (proto);
979 tree p = lookup_protocol (ident);
983 error ("Cannot find protocol declaration for `%s'",
984 IDENTIFIER_POINTER (ident));
986 TREE_CHAIN (prev) = TREE_CHAIN (proto);
988 return_value = TREE_CHAIN (proto);
992 /* Replace identifier with actual protocol node. */
993 TREE_VALUE (proto) = p;
1001 /* Create and push a decl for a built-in external variable or field NAME.
1003 TYPE is its data type. */
1006 create_builtin_decl (code, type, name)
1007 enum tree_code code;
1011 tree decl = build_decl (code, get_identifier (name), type);
1013 if (code == VAR_DECL)
1015 TREE_STATIC (decl) = 1;
1016 make_decl_rtl (decl, 0, 1);
1020 DECL_ARTIFICIAL (decl) = 1;
1024 /* Purpose: "play" parser, creating/installing representations
1025 of the declarations that are required by Objective-C.
1029 type_spec--------->sc_spec
1030 (tree_list) (tree_list)
1033 identifier_node identifier_node */
1036 synth_module_prologue ()
1041 /* Defined in `objc.h' */
1042 objc_object_id = get_identifier (TAG_OBJECT);
1044 objc_object_reference = xref_tag (RECORD_TYPE, objc_object_id);
1046 id_type = build_pointer_type (objc_object_reference);
1048 objc_id_id = get_identifier (TYPE_ID);
1049 objc_class_id = get_identifier (TAG_CLASS);
1051 objc_class_type = build_pointer_type (xref_tag (RECORD_TYPE, objc_class_id));
1052 protocol_type = build_pointer_type (xref_tag (RECORD_TYPE,
1053 get_identifier (PROTOCOL_OBJECT_CLASS_NAME)));
1055 /* Declare type of selector-objects that represent an operation name. */
1057 #ifdef OBJC_INT_SELECTORS
1058 /* `unsigned int' */
1059 selector_type = unsigned_type_node;
1061 /* `struct objc_selector *' */
1063 = build_pointer_type (xref_tag (RECORD_TYPE,
1064 get_identifier (TAG_SELECTOR)));
1065 #endif /* not OBJC_INT_SELECTORS */
1067 /* Forward declare type, or else the prototype for msgSendSuper will
1070 super_p = build_pointer_type (xref_tag (RECORD_TYPE,
1071 get_identifier (TAG_SUPER)));
1074 /* id objc_msgSend (id, SEL, ...); */
1077 = build_function_type (id_type,
1078 tree_cons (NULL_TREE, id_type,
1079 tree_cons (NULL_TREE, selector_type,
1082 if (! flag_next_runtime)
1084 umsg_decl = build_decl (FUNCTION_DECL,
1085 get_identifier (TAG_MSGSEND), temp_type);
1086 DECL_EXTERNAL (umsg_decl) = 1;
1087 TREE_PUBLIC (umsg_decl) = 1;
1088 DECL_INLINE (umsg_decl) = 1;
1089 DECL_ARTIFICIAL (umsg_decl) = 1;
1091 if (flag_traditional && TAG_MSGSEND[0] != '_')
1092 DECL_BUILT_IN_NONANSI (umsg_decl) = 1;
1094 make_decl_rtl (umsg_decl, NULL_PTR, 1);
1095 pushdecl (umsg_decl);
1098 umsg_decl = builtin_function (TAG_MSGSEND, temp_type, NOT_BUILT_IN, 0);
1100 /* id objc_msgSendSuper (struct objc_super *, SEL, ...); */
1103 = build_function_type (id_type,
1104 tree_cons (NULL_TREE, super_p,
1105 tree_cons (NULL_TREE, selector_type,
1108 umsg_super_decl = builtin_function (TAG_MSGSENDSUPER,
1109 temp_type, NOT_BUILT_IN, 0);
1111 /* id objc_getClass (const char *); */
1113 temp_type = build_function_type (id_type,
1114 tree_cons (NULL_TREE,
1115 const_string_type_node,
1116 tree_cons (NULL_TREE, void_type_node,
1120 = builtin_function (TAG_GETCLASS, temp_type, NOT_BUILT_IN, 0);
1122 /* id objc_getMetaClass (const char *); */
1124 objc_get_meta_class_decl
1125 = builtin_function (TAG_GETMETACLASS, temp_type, NOT_BUILT_IN, 0);
1127 /* static SEL _OBJC_SELECTOR_TABLE[]; */
1129 if (! flag_next_runtime)
1131 if (flag_typed_selectors)
1133 /* Suppress outputting debug symbols, because
1134 dbxout_init hasn'r been called yet. */
1135 enum debug_info_type save_write_symbols = write_symbols;
1136 write_symbols = NO_DEBUG;
1138 build_selector_template ();
1139 temp_type = build_array_type (objc_selector_template, NULL_TREE);
1141 write_symbols = save_write_symbols;
1144 temp_type = build_array_type (selector_type, NULL_TREE);
1146 layout_type (temp_type);
1147 UOBJC_SELECTOR_TABLE_decl
1148 = create_builtin_decl (VAR_DECL, temp_type,
1149 "_OBJC_SELECTOR_TABLE");
1151 /* Avoid warning when not sending messages. */
1152 TREE_USED (UOBJC_SELECTOR_TABLE_decl) = 1;
1155 generate_forward_declaration_to_string_table ();
1157 /* Forward declare constant_string_id and constant_string_type. */
1158 constant_string_id = get_identifier (STRING_OBJECT_CLASS_NAME);
1159 constant_string_type = xref_tag (RECORD_TYPE, constant_string_id);
1162 /* Custom build_string which sets TREE_TYPE! */
1165 my_build_string (len, str)
1170 tree a_string = build_string (len, str);
1172 /* Some code from combine_strings, which is local to c-parse.y. */
1173 if (TREE_TYPE (a_string) == int_array_type_node)
1176 TREE_TYPE (a_string)
1177 = build_array_type (wide_flag ? integer_type_node : char_type_node,
1178 build_index_type (build_int_2 (len - 1, 0)));
1180 TREE_CONSTANT (a_string) = 1; /* Puts string in the readonly segment */
1181 TREE_STATIC (a_string) = 1;
1186 /* Return a newly constructed OBJC_STRING_CST node whose value is
1187 the LEN characters at STR.
1188 The TREE_TYPE is not initialized. */
1191 build_objc_string (len, str)
1195 tree s = build_string (len, str);
1197 TREE_SET_CODE (s, OBJC_STRING_CST);
1201 /* Given a chain of OBJC_STRING_CST's, build a static instance of
1202 NXConstanString which points at the concatenation of those strings.
1203 We place the string object in the __string_objects section of the
1204 __OBJC segment. The Objective-C runtime will initialize the isa
1205 pointers of the string objects to point at the NXConstandString class
1209 build_objc_string_object (strings)
1212 tree string, initlist, constructor;
1215 if (!doing_objc_thang)
1218 if (lookup_interface (constant_string_id) == NULL_TREE)
1220 error ("Cannot find interface declaration for `%s'",
1221 IDENTIFIER_POINTER (constant_string_id));
1222 return error_mark_node;
1225 add_class_reference (constant_string_id);
1227 /* Combine_strings will work for OBJC_STRING_CST's too. */
1228 string = combine_strings (strings);
1229 TREE_SET_CODE (string, STRING_CST);
1230 length = TREE_STRING_LENGTH (string) - 1;
1232 if (! flag_next_runtime)
1234 push_obstacks_nochange ();
1235 end_temporary_allocation ();
1236 if (! TREE_PERMANENT (strings))
1237 string = my_build_string (length + 1,
1238 TREE_STRING_POINTER (string));
1241 /* & ((NXConstantString) {0, string, length}) */
1243 initlist = build_tree_list (NULL_TREE, build_int_2 (0, 0));
1245 = tree_cons (NULL_TREE, copy_node (build_unary_op (ADDR_EXPR, string, 1)),
1247 initlist = tree_cons (NULL_TREE, build_int_2 (length, 0), initlist);
1248 constructor = build_constructor (constant_string_type, nreverse (initlist));
1250 if (!flag_next_runtime)
1253 = objc_add_static_instance (constructor, constant_string_type);
1257 return (build_unary_op (ADDR_EXPR, constructor, 1));
1260 /* Declare a static instance of CLASS_DECL initialized by CONSTRUCTOR. */
1263 objc_add_static_instance (constructor, class_decl)
1264 tree constructor, class_decl;
1266 static int num_static_inst;
1267 tree *chain, decl, decl_spec, decl_expr;
1270 push_obstacks_nochange ();
1271 end_temporary_allocation ();
1273 /* Find the list of static instances for the CLASS_DECL. Create one if
1275 for (chain = &objc_static_instances;
1276 *chain && TREE_VALUE (*chain) != class_decl;
1277 chain = &TREE_CHAIN (*chain));
1280 *chain = tree_cons (NULL_TREE, class_decl, NULL_TREE);
1281 add_objc_string (TYPE_NAME (class_decl), class_names);
1284 sprintf (buf, "_OBJC_INSTANCE_%d", num_static_inst++);
1285 decl = build_decl (VAR_DECL, get_identifier (buf), class_decl);
1286 DECL_COMMON (decl) = 1;
1287 TREE_STATIC (decl) = 1;
1288 DECL_ARTIFICIAL (decl) = 1;
1289 pushdecl_top_level (decl);
1290 rest_of_decl_compilation (decl, 0, 1, 0);
1292 /* Do this here so it gets output later instead of possibly
1293 inside something else we are writing. */
1294 DECL_INITIAL (decl) = constructor;
1296 /* Add the DECL to the head of this CLASS' list. */
1297 TREE_PURPOSE (*chain) = tree_cons (NULL_TREE, decl, TREE_PURPOSE (*chain));
1303 /* Build a static constant CONSTRUCTOR
1304 with type TYPE and elements ELTS. */
1307 build_constructor (type, elts)
1310 tree constructor = build (CONSTRUCTOR, type, NULL_TREE, elts);
1312 TREE_CONSTANT (constructor) = 1;
1313 TREE_STATIC (constructor) = 1;
1314 TREE_READONLY (constructor) = 1;
1319 /* Take care of defining and initializing _OBJC_SYMBOLS. */
1321 /* Predefine the following data type:
1329 void *defs[cls_def_cnt + cat_def_cnt];
1333 build_objc_symtab_template ()
1335 tree field_decl, field_decl_chain, index;
1337 objc_symtab_template
1338 = start_struct (RECORD_TYPE, get_identifier (UTAG_SYMTAB));
1340 /* long sel_ref_cnt; */
1342 field_decl = create_builtin_decl (FIELD_DECL,
1343 long_integer_type_node,
1345 field_decl_chain = field_decl;
1349 field_decl = create_builtin_decl (FIELD_DECL,
1350 build_pointer_type (selector_type),
1352 chainon (field_decl_chain, field_decl);
1354 /* short cls_def_cnt; */
1356 field_decl = create_builtin_decl (FIELD_DECL,
1357 short_integer_type_node,
1359 chainon (field_decl_chain, field_decl);
1361 /* short cat_def_cnt; */
1363 field_decl = create_builtin_decl (FIELD_DECL,
1364 short_integer_type_node,
1366 chainon (field_decl_chain, field_decl);
1368 /* void *defs[cls_def_cnt + cat_def_cnt]; */
1370 if (!flag_next_runtime)
1371 index = build_index_type (build_int_2 (imp_count + cat_count, 0));
1373 index = build_index_type (build_int_2 (imp_count + cat_count - 1,
1374 imp_count == 0 && cat_count == 0
1376 field_decl = create_builtin_decl (FIELD_DECL,
1377 build_array_type (ptr_type_node, index),
1379 chainon (field_decl_chain, field_decl);
1381 finish_struct (objc_symtab_template, field_decl_chain, NULL_TREE);
1384 /* Create the initial value for the `defs' field of _objc_symtab.
1385 This is a CONSTRUCTOR. */
1388 init_def_list (type)
1391 tree expr, initlist = NULL_TREE;
1392 struct imp_entry *impent;
1395 for (impent = imp_list; impent; impent = impent->next)
1397 if (TREE_CODE (impent->imp_context) == CLASS_IMPLEMENTATION_TYPE)
1399 expr = build_unary_op (ADDR_EXPR, impent->class_decl, 0);
1400 initlist = tree_cons (NULL_TREE, expr, initlist);
1405 for (impent = imp_list; impent; impent = impent->next)
1407 if (TREE_CODE (impent->imp_context) == CATEGORY_IMPLEMENTATION_TYPE)
1409 expr = build_unary_op (ADDR_EXPR, impent->class_decl, 0);
1410 initlist = tree_cons (NULL_TREE, expr, initlist);
1414 if (!flag_next_runtime)
1416 /* statics = { ..., _OBJC_STATIC_INSTANCES, ... } */
1419 if (static_instances_decl)
1420 expr = build_unary_op (ADDR_EXPR, static_instances_decl, 0);
1422 expr = build_int_2 (0, 0);
1424 initlist = tree_cons (NULL_TREE, expr, initlist);
1427 return build_constructor (type, nreverse (initlist));
1430 /* Construct the initial value for all of _objc_symtab. */
1433 init_objc_symtab (type)
1438 /* sel_ref_cnt = { ..., 5, ... } */
1440 initlist = build_tree_list (NULL_TREE, build_int_2 (0, 0));
1442 /* refs = { ..., _OBJC_SELECTOR_TABLE, ... } */
1444 if (flag_next_runtime || ! sel_ref_chain)
1445 initlist = tree_cons (NULL_TREE, build_int_2 (0, 0), initlist);
1447 initlist = tree_cons (NULL_TREE,
1448 build_unary_op (ADDR_EXPR,
1449 UOBJC_SELECTOR_TABLE_decl, 1),
1452 /* cls_def_cnt = { ..., 5, ... } */
1454 initlist = tree_cons (NULL_TREE, build_int_2 (imp_count, 0), initlist);
1456 /* cat_def_cnt = { ..., 5, ... } */
1458 initlist = tree_cons (NULL_TREE, build_int_2 (cat_count, 0), initlist);
1460 /* cls_def = { ..., { &Foo, &Bar, ...}, ... } */
1462 if (imp_count || cat_count || static_instances_decl)
1465 tree field = TYPE_FIELDS (type);
1466 field = TREE_CHAIN (TREE_CHAIN (TREE_CHAIN (TREE_CHAIN (field))));
1468 initlist = tree_cons (NULL_TREE, init_def_list (TREE_TYPE (field)),
1472 return build_constructor (type, nreverse (initlist));
1475 /* Push forward-declarations of all the categories
1476 so that init_def_list can use them in a CONSTRUCTOR. */
1479 forward_declare_categories ()
1481 struct imp_entry *impent;
1482 tree sav = implementation_context;
1484 for (impent = imp_list; impent; impent = impent->next)
1486 if (TREE_CODE (impent->imp_context) == CATEGORY_IMPLEMENTATION_TYPE)
1488 /* Set an invisible arg to synth_id_with_class_suffix. */
1489 implementation_context = impent->imp_context;
1491 = create_builtin_decl (VAR_DECL, objc_category_template,
1492 IDENTIFIER_POINTER (synth_id_with_class_suffix ("_OBJC_CATEGORY", implementation_context)));
1495 implementation_context = sav;
1498 /* Create the declaration of _OBJC_SYMBOLS, with type `strict _objc_symtab'
1499 and initialized appropriately. */
1502 generate_objc_symtab_decl ()
1506 if (!objc_category_template)
1507 build_category_template ();
1509 /* forward declare categories */
1511 forward_declare_categories ();
1513 if (!objc_symtab_template)
1514 build_objc_symtab_template ();
1516 sc_spec = build_tree_list (NULL_TREE, ridpointers[(int) RID_STATIC]);
1518 UOBJC_SYMBOLS_decl = start_decl (get_identifier ("_OBJC_SYMBOLS"),
1519 tree_cons (NULL_TREE,
1520 objc_symtab_template, sc_spec),
1522 NULL_TREE, NULL_TREE);
1524 TREE_USED (UOBJC_SYMBOLS_decl) = 1;
1525 DECL_IGNORED_P (UOBJC_SYMBOLS_decl) = 1;
1526 DECL_ARTIFICIAL (UOBJC_SYMBOLS_decl) = 1;
1527 finish_decl (UOBJC_SYMBOLS_decl,
1528 init_objc_symtab (TREE_TYPE (UOBJC_SYMBOLS_decl)),
1533 init_module_descriptor (type)
1536 tree initlist, expr;
1538 /* version = { 1, ... } */
1540 expr = build_int_2 (OBJC_VERSION, 0);
1541 initlist = build_tree_list (NULL_TREE, expr);
1543 /* size = { ..., sizeof (struct objc_module), ... } */
1545 expr = size_in_bytes (objc_module_template);
1546 initlist = tree_cons (NULL_TREE, expr, initlist);
1548 /* name = { ..., "foo.m", ... } */
1550 expr = add_objc_string (get_identifier (input_filename), class_names);
1551 initlist = tree_cons (NULL_TREE, expr, initlist);
1553 /* symtab = { ..., _OBJC_SYMBOLS, ... } */
1555 if (UOBJC_SYMBOLS_decl)
1556 expr = build_unary_op (ADDR_EXPR, UOBJC_SYMBOLS_decl, 0);
1558 expr = build_int_2 (0, 0);
1559 initlist = tree_cons (NULL_TREE, expr, initlist);
1561 return build_constructor (type, nreverse (initlist));
1564 /* Write out the data structures to describe Objective C classes defined.
1565 If appropriate, compile and output a setup function to initialize them.
1566 Return a string which is the name of a function to call to initialize
1567 the Objective C data structures for this file (and perhaps for other files
1570 struct objc_module { ... } _OBJC_MODULE = { ... }; */
1573 build_module_descriptor ()
1575 tree decl_specs, field_decl, field_decl_chain;
1577 objc_module_template
1578 = start_struct (RECORD_TYPE, get_identifier (UTAG_MODULE));
1582 decl_specs = build_tree_list (NULL_TREE, ridpointers[(int) RID_LONG]);
1583 field_decl = get_identifier ("version");
1585 = grokfield (input_filename, lineno, field_decl, decl_specs, NULL_TREE);
1586 field_decl_chain = field_decl;
1590 decl_specs = build_tree_list (NULL_TREE, ridpointers[(int) RID_LONG]);
1591 field_decl = get_identifier ("size");
1593 = grokfield (input_filename, lineno, field_decl, decl_specs, NULL_TREE);
1594 chainon (field_decl_chain, field_decl);
1598 decl_specs = build_tree_list (NULL_TREE, ridpointers[(int) RID_CHAR]);
1599 field_decl = build1 (INDIRECT_REF, NULL_TREE, get_identifier ("name"));
1601 = grokfield (input_filename, lineno, field_decl, decl_specs, NULL_TREE);
1602 chainon (field_decl_chain, field_decl);
1604 /* struct objc_symtab *symtab; */
1606 decl_specs = get_identifier (UTAG_SYMTAB);
1607 decl_specs = build_tree_list (NULL_TREE, xref_tag (RECORD_TYPE, decl_specs));
1608 field_decl = build1 (INDIRECT_REF, NULL_TREE, get_identifier ("symtab"));
1610 = grokfield (input_filename, lineno, field_decl, decl_specs, NULL_TREE);
1611 chainon (field_decl_chain, field_decl);
1613 finish_struct (objc_module_template, field_decl_chain, NULL_TREE);
1615 /* Create an instance of "objc_module". */
1617 decl_specs = tree_cons (NULL_TREE, objc_module_template,
1618 build_tree_list (NULL_TREE,
1619 ridpointers[(int) RID_STATIC]));
1621 UOBJC_MODULES_decl = start_decl (get_identifier ("_OBJC_MODULES"),
1622 decl_specs, 1, NULL_TREE, NULL_TREE);
1624 DECL_ARTIFICIAL (UOBJC_MODULES_decl) = 1;
1625 DECL_IGNORED_P (UOBJC_MODULES_decl) = 1;
1626 finish_decl (UOBJC_MODULES_decl,
1627 init_module_descriptor (TREE_TYPE (UOBJC_MODULES_decl)),
1630 /* Mark the decl to avoid "defined but not used" warning. */
1631 DECL_IN_SYSTEM_HEADER (UOBJC_MODULES_decl) = 1;
1633 /* Generate a constructor call for the module descriptor.
1634 This code was generated by reading the grammar rules
1635 of c-parse.in; Therefore, it may not be the most efficient
1636 way of generating the requisite code. */
1638 if (flag_next_runtime)
1642 tree parms, function_decl, decelerator, void_list_node;
1644 extern tree get_file_function_name ();
1645 tree init_function_name = get_file_function_name ('I');
1647 /* Declare void __objc_execClass (void *); */
1649 void_list_node = build_tree_list (NULL_TREE, void_type_node);
1651 = build_function_type (void_type_node,
1652 tree_cons (NULL_TREE, ptr_type_node,
1654 function_decl = build_decl (FUNCTION_DECL,
1655 get_identifier (TAG_EXECCLASS),
1657 DECL_EXTERNAL (function_decl) = 1;
1658 DECL_ARTIFICIAL (function_decl) = 1;
1659 TREE_PUBLIC (function_decl) = 1;
1661 pushdecl (function_decl);
1662 rest_of_decl_compilation (function_decl, 0, 0, 0);
1665 = build_tree_list (NULL_TREE,
1666 build_unary_op (ADDR_EXPR, UOBJC_MODULES_decl, 0));
1667 decelerator = build_function_call (function_decl, parms);
1669 /* void _GLOBAL_$I$<gnyf> () {objc_execClass (&L_OBJC_MODULES);} */
1671 start_function (void_list_node,
1672 build_parse_node (CALL_EXPR, init_function_name,
1673 /* This has the format of the output
1674 of get_parm_info. */
1675 tree_cons (NULL_TREE, NULL_TREE,
1678 NULL_TREE, NULL_TREE, 0);
1679 #if 0 /* This should be turned back on later
1680 for the systems where collect is not needed. */
1681 /* Make these functions nonglobal
1682 so each file can use the same name. */
1683 TREE_PUBLIC (current_function_decl) = 0;
1685 TREE_USED (current_function_decl) = 1;
1686 store_parm_decls ();
1688 assemble_external (function_decl);
1689 c_expand_expr_stmt (decelerator);
1691 TREE_PUBLIC (current_function_decl) = 1;
1693 function_decl = current_function_decl;
1694 finish_function (0);
1696 /* Return the name of the constructor function. */
1697 return XSTR (XEXP (DECL_RTL (function_decl), 0), 0);
1701 /* extern const char _OBJC_STRINGS[]; */
1704 generate_forward_declaration_to_string_table ()
1706 tree sc_spec, decl_specs, expr_decl;
1708 sc_spec = tree_cons (NULL_TREE, ridpointers[(int) RID_EXTERN], NULL_TREE);
1709 decl_specs = tree_cons (NULL_TREE, ridpointers[(int) RID_CHAR], sc_spec);
1712 = build_nt (ARRAY_REF, get_identifier ("_OBJC_STRINGS"), NULL_TREE);
1714 UOBJC_STRINGS_decl = define_decl (expr_decl, decl_specs);
1717 /* Return the DECL of the string IDENT in the SECTION. */
1720 get_objc_string_decl (ident, section)
1722 enum string_section section;
1726 if (section == class_names)
1727 chain = class_names_chain;
1728 else if (section == meth_var_names)
1729 chain = meth_var_names_chain;
1730 else if (section == meth_var_types)
1731 chain = meth_var_types_chain;
1733 for (; chain != 0; chain = TREE_VALUE (chain))
1734 if (TREE_VALUE (chain) == ident)
1735 return (TREE_PURPOSE (chain));
1741 /* Output references to all statically allocated objects. Return the DECL
1742 for the array built. */
1745 generate_static_references ()
1747 tree decls = NULL_TREE, ident, decl_spec, expr_decl, expr = NULL_TREE;
1748 tree class_name, class, decl, instance, idecl, initlist;
1749 tree cl_chain, in_chain, type;
1750 int num_inst, num_class;
1753 if (flag_next_runtime)
1756 for (cl_chain = objc_static_instances, num_class = 0;
1757 cl_chain; cl_chain = TREE_CHAIN (cl_chain), num_class++)
1759 for (num_inst = 0, in_chain = TREE_PURPOSE (cl_chain);
1760 in_chain; num_inst++, in_chain = TREE_CHAIN (in_chain));
1762 sprintf (buf, "_OBJC_STATIC_INSTANCES_%d", num_class);
1763 ident = get_identifier (buf);
1765 expr_decl = build_nt (ARRAY_REF, ident, NULL_TREE);
1766 decl_spec = tree_cons (NULL_TREE, build_pointer_type (void_type_node),
1767 build_tree_list (NULL_TREE,
1768 ridpointers[(int) RID_STATIC]));
1769 decl = start_decl (expr_decl, decl_spec, 1, NULL_TREE, NULL_TREE);
1770 DECL_CONTEXT (decl) = 0;
1771 DECL_ARTIFICIAL (decl) = 1;
1773 /* Output {class_name, ...}. */
1774 class = TREE_VALUE (cl_chain);
1775 class_name = get_objc_string_decl (TYPE_NAME (class), class_names);
1776 initlist = build_tree_list (NULL_TREE,
1777 build_unary_op (ADDR_EXPR, class_name, 1));
1779 /* Output {..., instance, ...}. */
1780 for (in_chain = TREE_PURPOSE (cl_chain);
1781 in_chain; in_chain = TREE_CHAIN (in_chain))
1783 expr = build_unary_op (ADDR_EXPR, TREE_VALUE (in_chain), 1);
1784 initlist = tree_cons (NULL_TREE, expr, initlist);
1787 /* Output {..., NULL}. */
1788 initlist = tree_cons (NULL_TREE, build_int_2 (0, 0), initlist);
1790 expr = build_constructor (TREE_TYPE (decl), nreverse (initlist));
1791 finish_decl (decl, expr, NULL_TREE);
1792 TREE_USED (decl) = 1;
1794 type = build_array_type (build_pointer_type (void_type_node), 0);
1795 decl = build_decl (VAR_DECL, ident, type);
1796 make_decl_rtl (decl, 0, 1);
1797 TREE_USED (decl) = 1;
1799 = tree_cons (NULL_TREE, build_unary_op (ADDR_EXPR, decl, 1), decls);
1802 decls = tree_cons (NULL_TREE, build_int_2 (0, 0), decls);
1803 ident = get_identifier ("_OBJC_STATIC_INSTANCES");
1804 expr_decl = build_nt (ARRAY_REF, ident, NULL_TREE);
1805 decl_spec = tree_cons (NULL_TREE, build_pointer_type (void_type_node),
1806 build_tree_list (NULL_TREE,
1807 ridpointers[(int) RID_STATIC]));
1808 static_instances_decl
1809 = start_decl (expr_decl, decl_spec, 1, NULL_TREE, NULL_TREE);
1810 TREE_USED (static_instances_decl) = 1;
1811 DECL_CONTEXT (static_instances_decl) = 0;
1812 DECL_ARTIFICIAL (static_instances_decl) = 1;
1813 end_temporary_allocation ();
1814 expr = build_constructor (TREE_TYPE (static_instances_decl),
1816 finish_decl (static_instances_decl, expr, NULL_TREE);
1819 /* Output all strings. */
1824 tree sc_spec, decl_specs, expr_decl;
1825 tree chain, string_expr;
1828 for (chain = class_names_chain; chain; chain = TREE_CHAIN (chain))
1830 string = TREE_VALUE (chain);
1831 decl = TREE_PURPOSE (chain);
1833 = tree_cons (NULL_TREE, ridpointers[(int) RID_STATIC], NULL_TREE);
1834 decl_specs = tree_cons (NULL_TREE, ridpointers[(int) RID_CHAR], sc_spec);
1835 expr_decl = build_nt (ARRAY_REF, DECL_NAME (decl), NULL_TREE);
1836 decl = start_decl (expr_decl, decl_specs, 1, NULL_TREE, NULL_TREE);
1837 end_temporary_allocation ();
1838 string_expr = my_build_string (IDENTIFIER_LENGTH (string) + 1,
1839 IDENTIFIER_POINTER (string));
1840 finish_decl (decl, string_expr, NULL_TREE);
1843 for (chain = meth_var_names_chain; chain; chain = TREE_CHAIN (chain))
1845 string = TREE_VALUE (chain);
1846 decl = TREE_PURPOSE (chain);
1848 = tree_cons (NULL_TREE, ridpointers[(int) RID_STATIC], NULL_TREE);
1849 decl_specs = tree_cons (NULL_TREE, ridpointers[(int) RID_CHAR], sc_spec);
1850 expr_decl = build_nt (ARRAY_REF, DECL_NAME (decl), NULL_TREE);
1851 decl = start_decl (expr_decl, decl_specs, 1, NULL_TREE, NULL_TREE);
1852 string_expr = my_build_string (IDENTIFIER_LENGTH (string) + 1,
1853 IDENTIFIER_POINTER (string));
1854 finish_decl (decl, string_expr, NULL_TREE);
1857 for (chain = meth_var_types_chain; chain; chain = TREE_CHAIN (chain))
1859 string = TREE_VALUE (chain);
1860 decl = TREE_PURPOSE (chain);
1862 = tree_cons (NULL_TREE, ridpointers[(int) RID_STATIC], NULL_TREE);
1863 decl_specs = tree_cons (NULL_TREE, ridpointers[(int) RID_CHAR], sc_spec);
1864 expr_decl = build_nt (ARRAY_REF, DECL_NAME (decl), NULL_TREE);
1865 decl = start_decl (expr_decl, decl_specs, 1, NULL_TREE, NULL_TREE);
1866 string_expr = my_build_string (IDENTIFIER_LENGTH (string) + 1,
1867 IDENTIFIER_POINTER (string));
1868 finish_decl (decl, string_expr, NULL_TREE);
1873 build_selector_reference_decl (name)
1880 sprintf (buf, "_OBJC_SELECTOR_REFERENCES_%d", idx++);
1882 push_obstacks_nochange ();
1883 end_temporary_allocation ();
1885 ident = get_identifier (buf);
1887 decl = build_decl (VAR_DECL, ident, selector_type);
1888 DECL_EXTERNAL (decl) = 1;
1889 TREE_PUBLIC (decl) = 1;
1890 TREE_USED (decl) = 1;
1891 TREE_READONLY (decl) = 1;
1892 DECL_ARTIFICIAL (decl) = 1;
1893 DECL_CONTEXT (decl) = 0;
1895 make_decl_rtl (decl, 0, 1);
1896 pushdecl_top_level (decl);
1903 /* Just a handy wrapper for add_objc_string. */
1906 build_selector (ident)
1909 tree expr = add_objc_string (ident, meth_var_names);
1910 if (flag_typed_selectors)
1913 return build_c_cast (selector_type, expr); /* cast! */
1916 /* Synthesize the following expr: (char *)&_OBJC_STRINGS[<offset>]
1917 The cast stops the compiler from issuing the following message:
1918 grok.m: warning: initialization of non-const * pointer from const *
1919 grok.m: warning: initialization between incompatible pointer types. */
1922 build_msg_pool_reference (offset)
1925 tree expr = build_int_2 (offset, 0);
1928 expr = build_array_ref (UOBJC_STRINGS_decl, expr);
1929 expr = build_unary_op (ADDR_EXPR, expr, 0);
1931 cast = build_tree_list (build_tree_list (NULL_TREE,
1932 ridpointers[(int) RID_CHAR]),
1933 build1 (INDIRECT_REF, NULL_TREE, NULL_TREE));
1934 TREE_TYPE (expr) = groktypename (cast);
1939 init_selector (offset)
1942 tree expr = build_msg_pool_reference (offset);
1943 TREE_TYPE (expr) = selector_type;
1948 build_selector_translation_table ()
1950 tree sc_spec, decl_specs;
1951 tree chain, initlist = NULL_TREE;
1953 tree decl, var_decl, name;
1955 /* The corresponding pop_obstacks is in finish_decl,
1956 called at the end of this function. */
1957 if (! flag_next_runtime)
1958 push_obstacks_nochange ();
1960 for (chain = sel_ref_chain; chain; chain = TREE_CHAIN (chain))
1964 expr = build_selector (TREE_VALUE (chain));
1966 if (flag_next_runtime)
1968 name = DECL_NAME (TREE_PURPOSE (chain));
1970 sc_spec = build_tree_list (NULL_TREE, ridpointers[(int) RID_STATIC]);
1972 /* static SEL _OBJC_SELECTOR_REFERENCES_n = ...; */
1973 decl_specs = tree_cons (NULL_TREE, selector_type, sc_spec);
1977 /* The `decl' that is returned from start_decl is the one that we
1978 forward declared in `build_selector_reference' */
1979 decl = start_decl (var_decl, decl_specs, 1, NULL_TREE, NULL_TREE);
1982 /* add one for the '\0' character */
1983 offset += IDENTIFIER_LENGTH (TREE_VALUE (chain)) + 1;
1985 if (flag_next_runtime)
1986 finish_decl (decl, expr, NULL_TREE);
1989 if (flag_typed_selectors)
1991 tree eltlist = NULL_TREE;
1992 tree encoding = get_proto_encoding (TREE_PURPOSE (chain));
1993 eltlist = tree_cons (NULL_TREE, expr, NULL_TREE);
1994 eltlist = tree_cons (NULL_TREE, encoding, eltlist);
1995 expr = build_constructor (objc_selector_template,
1996 nreverse (eltlist));
1998 initlist = tree_cons (NULL_TREE, expr, initlist);
2003 if (! flag_next_runtime)
2005 /* Cause the variable and its initial value to be actually output. */
2006 DECL_EXTERNAL (UOBJC_SELECTOR_TABLE_decl) = 0;
2007 TREE_STATIC (UOBJC_SELECTOR_TABLE_decl) = 1;
2008 /* NULL terminate the list and fix the decl for output. */
2009 initlist = tree_cons (NULL_TREE, build_int_2 (0, 0), initlist);
2010 DECL_INITIAL (UOBJC_SELECTOR_TABLE_decl) = (tree) 1;
2011 initlist = build_constructor (TREE_TYPE (UOBJC_SELECTOR_TABLE_decl),
2012 nreverse (initlist));
2013 finish_decl (UOBJC_SELECTOR_TABLE_decl, initlist, NULL_TREE);
2014 current_function_decl = NULL_TREE;
2019 get_proto_encoding (proto)
2027 if (! METHOD_ENCODING (proto))
2029 tmp_decl = build_tmp_function_decl ();
2030 hack_method_prototype (proto, tmp_decl);
2031 encoding = encode_method_prototype (proto, tmp_decl);
2032 METHOD_ENCODING (proto) = encoding;
2035 encoding = METHOD_ENCODING (proto);
2037 return add_objc_string (encoding, meth_var_types);
2040 return build_int_2 (0, 0);
2043 /* sel_ref_chain is a list whose "value" fields will be instances of
2044 identifier_node that represent the selector. */
2047 build_typed_selector_reference (ident, proto)
2050 tree *chain = &sel_ref_chain;
2056 if (TREE_PURPOSE (*chain) == ident && TREE_VALUE (*chain) == proto)
2057 goto return_at_index;
2060 chain = &TREE_CHAIN (*chain);
2063 *chain = perm_tree_cons (proto, ident, NULL_TREE);
2066 expr = build_unary_op (ADDR_EXPR,
2067 build_array_ref (UOBJC_SELECTOR_TABLE_decl,
2068 build_int_2 (index, 0)),
2070 return build_c_cast (selector_type, expr);
2074 build_selector_reference (ident)
2077 tree *chain = &sel_ref_chain;
2083 if (TREE_VALUE (*chain) == ident)
2084 return (flag_next_runtime
2085 ? TREE_PURPOSE (*chain)
2086 : build_array_ref (UOBJC_SELECTOR_TABLE_decl,
2087 build_int_2 (index, 0)));
2090 chain = &TREE_CHAIN (*chain);
2093 expr = build_selector_reference_decl (ident);
2095 *chain = perm_tree_cons (expr, ident, NULL_TREE);
2097 return (flag_next_runtime
2099 : build_array_ref (UOBJC_SELECTOR_TABLE_decl,
2100 build_int_2 (index, 0)));
2104 build_class_reference_decl (name)
2111 sprintf (buf, "_OBJC_CLASS_REFERENCES_%d", idx++);
2113 push_obstacks_nochange ();
2114 end_temporary_allocation ();
2116 ident = get_identifier (buf);
2118 decl = build_decl (VAR_DECL, ident, objc_class_type);
2119 DECL_EXTERNAL (decl) = 1;
2120 TREE_PUBLIC (decl) = 1;
2121 TREE_USED (decl) = 1;
2122 TREE_READONLY (decl) = 1;
2123 DECL_CONTEXT (decl) = 0;
2124 DECL_ARTIFICIAL (decl) = 1;
2126 make_decl_rtl (decl, 0, 1);
2127 pushdecl_top_level (decl);
2134 /* Create a class reference, but don't create a variable to reference
2138 add_class_reference (ident)
2143 if ((chain = cls_ref_chain))
2148 if (ident == TREE_VALUE (chain))
2152 chain = TREE_CHAIN (chain);
2156 /* Append to the end of the list */
2157 TREE_CHAIN (tail) = perm_tree_cons (NULL_TREE, ident, NULL_TREE);
2160 cls_ref_chain = perm_tree_cons (NULL_TREE, ident, NULL_TREE);
2163 /* Get a class reference, creating it if necessary. Also create the
2164 reference variable. */
2167 get_class_reference (ident)
2170 if (flag_next_runtime)
2175 for (chain = &cls_ref_chain; *chain; chain = &TREE_CHAIN (*chain))
2176 if (TREE_VALUE (*chain) == ident)
2178 if (! TREE_PURPOSE (*chain))
2179 TREE_PURPOSE (*chain) = build_class_reference_decl (ident);
2181 return TREE_PURPOSE (*chain);
2184 decl = build_class_reference_decl (ident);
2185 *chain = perm_tree_cons (decl, ident, NULL_TREE);
2192 add_class_reference (ident);
2194 params = build_tree_list (NULL_TREE,
2195 my_build_string (IDENTIFIER_LENGTH (ident) + 1,
2196 IDENTIFIER_POINTER (ident)));
2198 assemble_external (objc_get_class_decl);
2199 return build_function_call (objc_get_class_decl, params);
2203 /* SEL_REFDEF_CHAIN is a list whose "value" fields will be instances
2204 of identifier_node that represent the selector. It returns the
2205 offset of the selector from the beginning of the _OBJC_STRINGS
2206 pool. This offset is typically used by init_selector during code
2209 For each string section we have a chain which maps identifier nodes
2210 to decls for the strings. */
2213 add_objc_string (ident, section)
2215 enum string_section section;
2219 if (section == class_names)
2220 chain = &class_names_chain;
2221 else if (section == meth_var_names)
2222 chain = &meth_var_names_chain;
2223 else if (section == meth_var_types)
2224 chain = &meth_var_types_chain;
2228 if (TREE_VALUE (*chain) == ident)
2229 return build_unary_op (ADDR_EXPR, TREE_PURPOSE (*chain), 1);
2231 chain = &TREE_CHAIN (*chain);
2234 decl = build_objc_string_decl (ident, section);
2236 *chain = perm_tree_cons (decl, ident, NULL_TREE);
2238 return build_unary_op (ADDR_EXPR, decl, 1);
2242 build_objc_string_decl (name, section)
2244 enum string_section section;
2248 static int class_names_idx = 0;
2249 static int meth_var_names_idx = 0;
2250 static int meth_var_types_idx = 0;
2252 if (section == class_names)
2253 sprintf (buf, "_OBJC_CLASS_NAME_%d", class_names_idx++);
2254 else if (section == meth_var_names)
2255 sprintf (buf, "_OBJC_METH_VAR_NAME_%d", meth_var_names_idx++);
2256 else if (section == meth_var_types)
2257 sprintf (buf, "_OBJC_METH_VAR_TYPE_%d", meth_var_types_idx++);
2259 push_obstacks_nochange ();
2260 end_temporary_allocation ();
2261 ident = get_identifier (buf);
2263 decl = build_decl (VAR_DECL, ident, build_array_type (char_type_node, 0));
2264 DECL_EXTERNAL (decl) = 1;
2265 TREE_PUBLIC (decl) = 1;
2266 TREE_USED (decl) = 1;
2267 TREE_READONLY (decl) = 1;
2268 TREE_CONSTANT (decl) = 1;
2269 DECL_CONTEXT (decl) = 0;
2270 DECL_ARTIFICIAL (decl) = 1;
2272 make_decl_rtl (decl, 0, 1);
2273 pushdecl_top_level (decl);
2282 objc_declare_alias (alias_ident, class_ident)
2286 if (!doing_objc_thang)
2289 if (is_class_name (class_ident) != class_ident)
2290 warning ("Cannot find class `%s'", IDENTIFIER_POINTER (class_ident));
2291 else if (is_class_name (alias_ident))
2292 warning ("Class `%s' already exists", IDENTIFIER_POINTER (alias_ident));
2294 alias_chain = tree_cons (class_ident, alias_ident, alias_chain);
2298 objc_declare_class (ident_list)
2303 if (!doing_objc_thang)
2306 for (list = ident_list; list; list = TREE_CHAIN (list))
2308 tree ident = TREE_VALUE (list);
2311 if ((decl = lookup_name (ident)))
2313 error ("`%s' redeclared as different kind of symbol",
2314 IDENTIFIER_POINTER (ident));
2315 error_with_decl (decl, "previous declaration of `%s'");
2318 if (! is_class_name (ident))
2320 tree record = xref_tag (RECORD_TYPE, ident);
2321 TREE_STATIC_TEMPLATE (record) = 1;
2322 class_chain = tree_cons (NULL_TREE, ident, class_chain);
2328 is_class_name (ident)
2333 if (lookup_interface (ident))
2336 for (chain = class_chain; chain; chain = TREE_CHAIN (chain))
2338 if (ident == TREE_VALUE (chain))
2342 for (chain = alias_chain; chain; chain = TREE_CHAIN (chain))
2344 if (ident == TREE_VALUE (chain))
2345 return TREE_PURPOSE (chain);
2352 lookup_interface (ident)
2357 for (chain = interface_chain; chain; chain = TREE_CHAIN (chain))
2359 if (ident == CLASS_NAME (chain))
2366 objc_copy_list (list, head)
2370 tree newlist = NULL_TREE, tail = NULL_TREE;
2374 tail = copy_node (list);
2376 /* The following statement fixes a bug when inheriting instance
2377 variables that are declared to be bitfields. finish_struct
2378 expects to find the width of the bitfield in DECL_INITIAL,
2379 which it nulls out after processing the decl of the super
2380 class...rather than change the way finish_struct works (which
2381 is risky), I create the situation it expects...s.naroff
2384 if (DECL_BIT_FIELD (tail) && DECL_INITIAL (tail) == 0)
2385 DECL_INITIAL (tail) = build_int_2 (DECL_FIELD_SIZE (tail), 0);
2387 newlist = chainon (newlist, tail);
2388 list = TREE_CHAIN (list);
2395 /* Used by: build_private_template, get_class_ivars, and
2396 continue_class. COPY is 1 when called from @defs. In this case
2397 copy all fields. Otherwise don't copy leaf ivars since we rely on
2398 them being side-effected exactly once by finish_struct. */
2401 build_ivar_chain (interface, copy)
2405 tree my_name, super_name, ivar_chain;
2407 my_name = CLASS_NAME (interface);
2408 super_name = CLASS_SUPER_NAME (interface);
2410 /* Possibly copy leaf ivars. */
2412 objc_copy_list (CLASS_IVARS (interface), &ivar_chain);
2414 ivar_chain = CLASS_IVARS (interface);
2419 tree super_interface = lookup_interface (super_name);
2421 if (!super_interface)
2423 /* fatal did not work with 2 args...should fix */
2424 error ("Cannot find interface declaration for `%s', superclass of `%s'",
2425 IDENTIFIER_POINTER (super_name),
2426 IDENTIFIER_POINTER (my_name));
2427 exit (FATAL_EXIT_CODE);
2430 if (super_interface == interface)
2432 fatal ("Circular inheritance in interface declaration for `%s'",
2433 IDENTIFIER_POINTER (super_name));
2436 interface = super_interface;
2437 my_name = CLASS_NAME (interface);
2438 super_name = CLASS_SUPER_NAME (interface);
2440 op1 = CLASS_IVARS (interface);
2443 tree head, tail = objc_copy_list (op1, &head);
2445 /* Prepend super class ivars...make a copy of the list, we
2446 do not want to alter the original. */
2447 TREE_CHAIN (tail) = ivar_chain;
2454 /* struct <classname> {
2455 struct objc_class *isa;
2460 build_private_template (class)
2465 if (CLASS_STATIC_TEMPLATE (class))
2467 uprivate_record = CLASS_STATIC_TEMPLATE (class);
2468 ivar_context = TYPE_FIELDS (CLASS_STATIC_TEMPLATE (class));
2472 uprivate_record = start_struct (RECORD_TYPE, CLASS_NAME (class));
2474 ivar_context = build_ivar_chain (class, 0);
2476 finish_struct (uprivate_record, ivar_context, NULL_TREE);
2478 CLASS_STATIC_TEMPLATE (class) = uprivate_record;
2480 /* mark this record as class template - for class type checking */
2481 TREE_STATIC_TEMPLATE (uprivate_record) = 1;
2485 = groktypename (build_tree_list (build_tree_list (NULL_TREE,
2487 build1 (INDIRECT_REF, NULL_TREE,
2490 return ivar_context;
2493 /* Begin code generation for protocols... */
2495 /* struct objc_protocol {
2496 char *protocol_name;
2497 struct objc_protocol **protocol_list;
2498 struct objc_method_desc *instance_methods;
2499 struct objc_method_desc *class_methods;
2503 build_protocol_template ()
2505 tree decl_specs, field_decl, field_decl_chain;
2508 template = start_struct (RECORD_TYPE, get_identifier (UTAG_PROTOCOL));
2510 /* struct objc_class *isa; */
2512 decl_specs = build_tree_list (NULL_TREE, xref_tag (RECORD_TYPE,
2513 get_identifier (UTAG_CLASS)));
2514 field_decl = build1 (INDIRECT_REF, NULL_TREE, get_identifier ("isa"));
2516 = grokfield (input_filename, lineno, field_decl, decl_specs, NULL_TREE);
2517 field_decl_chain = field_decl;
2519 /* char *protocol_name; */
2521 decl_specs = build_tree_list (NULL_TREE, ridpointers[(int) RID_CHAR]);
2523 = build1 (INDIRECT_REF, NULL_TREE, get_identifier ("protocol_name"));
2525 = grokfield (input_filename, lineno, field_decl, decl_specs, NULL_TREE);
2526 chainon (field_decl_chain, field_decl);
2528 /* struct objc_protocol **protocol_list; */
2530 decl_specs = build_tree_list (NULL_TREE, template);
2532 = build1 (INDIRECT_REF, NULL_TREE, get_identifier ("protocol_list"));
2533 field_decl = build1 (INDIRECT_REF, NULL_TREE, field_decl);
2535 = grokfield (input_filename, lineno, field_decl, decl_specs, NULL_TREE);
2536 chainon (field_decl_chain, field_decl);
2538 /* struct objc_method_list *instance_methods; */
2541 = build_tree_list (NULL_TREE,
2542 xref_tag (RECORD_TYPE,
2543 get_identifier (UTAG_METHOD_PROTOTYPE_LIST)));
2545 = build1 (INDIRECT_REF, NULL_TREE, get_identifier ("instance_methods"));
2547 = grokfield (input_filename, lineno, field_decl, decl_specs, NULL_TREE);
2548 chainon (field_decl_chain, field_decl);
2550 /* struct objc_method_list *class_methods; */
2553 = build_tree_list (NULL_TREE,
2554 xref_tag (RECORD_TYPE,
2555 get_identifier (UTAG_METHOD_PROTOTYPE_LIST)));
2557 = build1 (INDIRECT_REF, NULL_TREE, get_identifier ("class_methods"));
2559 = grokfield (input_filename, lineno, field_decl, decl_specs, NULL_TREE);
2560 chainon (field_decl_chain, field_decl);
2562 return finish_struct (template, field_decl_chain, NULL_TREE);
2566 build_descriptor_table_initializer (type, entries)
2570 tree initlist = NULL_TREE;
2574 tree eltlist = NULL_TREE;
2577 = tree_cons (NULL_TREE,
2578 build_selector (METHOD_SEL_NAME (entries)), NULL_TREE);
2580 = tree_cons (NULL_TREE,
2581 add_objc_string (METHOD_ENCODING (entries),
2586 = tree_cons (NULL_TREE,
2587 build_constructor (type, nreverse (eltlist)), initlist);
2589 entries = TREE_CHAIN (entries);
2593 return build_constructor (build_array_type (type, 0), nreverse (initlist));
2596 /* struct objc_method_prototype_list {
2598 struct objc_method_prototype {
2605 build_method_prototype_list_template (list_type, size)
2609 tree objc_ivar_list_record;
2610 tree decl_specs, field_decl, field_decl_chain;
2612 /* Generate an unnamed struct definition. */
2614 objc_ivar_list_record = start_struct (RECORD_TYPE, NULL_TREE);
2616 /* int method_count; */
2618 decl_specs = build_tree_list (NULL_TREE, ridpointers[(int) RID_INT]);
2619 field_decl = get_identifier ("method_count");
2622 = grokfield (input_filename, lineno, field_decl, decl_specs, NULL_TREE);
2623 field_decl_chain = field_decl;
2625 /* struct objc_method method_list[]; */
2627 decl_specs = build_tree_list (NULL_TREE, list_type);
2628 field_decl = build_nt (ARRAY_REF, get_identifier ("method_list"),
2629 build_int_2 (size, 0));
2632 = grokfield (input_filename, lineno, field_decl, decl_specs, NULL_TREE);
2633 chainon (field_decl_chain, field_decl);
2635 finish_struct (objc_ivar_list_record, field_decl_chain, NULL_TREE);
2637 return objc_ivar_list_record;
2641 build_method_prototype_template ()
2644 tree decl_specs, field_decl, field_decl_chain;
2647 = start_struct (RECORD_TYPE, get_identifier (UTAG_METHOD_PROTOTYPE));
2649 #ifdef OBJC_INT_SELECTORS
2650 /* unsigned int _cmd; */
2652 = tree_cons (NULL_TREE, ridpointers[(int) RID_UNSIGNED], NULL_TREE);
2653 decl_specs = tree_cons (NULL_TREE, ridpointers[(int) RID_INT], decl_specs);
2654 field_decl = get_identifier ("_cmd");
2655 #else /* OBJC_INT_SELECTORS */
2656 /* struct objc_selector *_cmd; */
2657 decl_specs = tree_cons (NULL_TREE, xref_tag (RECORD_TYPE,
2658 get_identifier (TAG_SELECTOR)), NULL_TREE);
2659 field_decl = build1 (INDIRECT_REF, NULL_TREE, get_identifier ("_cmd"));
2660 #endif /* OBJC_INT_SELECTORS */
2663 = grokfield (input_filename, lineno, field_decl, decl_specs, NULL_TREE);
2664 field_decl_chain = field_decl;
2666 decl_specs = tree_cons (NULL_TREE, ridpointers[(int) RID_CHAR], NULL_TREE);
2668 = build1 (INDIRECT_REF, NULL_TREE, get_identifier ("method_types"));
2670 = grokfield (input_filename, lineno, field_decl, decl_specs, NULL_TREE);
2671 chainon (field_decl_chain, field_decl);
2673 finish_struct (proto_record, field_decl_chain, NULL_TREE);
2675 return proto_record;
2678 /* True if last call to forwarding_offset yielded a register offset. */
2679 static int offset_is_register;
2682 forwarding_offset (parm)
2685 int offset_in_bytes;
2687 if (GET_CODE (DECL_INCOMING_RTL (parm)) == MEM)
2689 rtx addr = XEXP (DECL_INCOMING_RTL (parm), 0);
2691 /* ??? Here we assume that the parm address is indexed
2692 off the frame pointer or arg pointer.
2693 If that is not true, we produce meaningless results,
2694 but do not crash. */
2695 if (GET_CODE (addr) == PLUS
2696 && GET_CODE (XEXP (addr, 1)) == CONST_INT)
2697 offset_in_bytes = INTVAL (XEXP (addr, 1));
2699 offset_in_bytes = 0;
2701 offset_in_bytes += OBJC_FORWARDING_STACK_OFFSET;
2702 offset_is_register = 0;
2704 else if (GET_CODE (DECL_INCOMING_RTL (parm)) == REG)
2706 int regno = REGNO (DECL_INCOMING_RTL (parm));
2707 offset_in_bytes = apply_args_register_offset (regno);
2708 offset_is_register = 1;
2713 /* This is the case where the parm is passed as an int or double
2714 and it is converted to a char, short or float and stored back
2715 in the parmlist. In this case, describe the parm
2716 with the variable's declared type, and adjust the address
2717 if the least significant bytes (which we are using) are not
2719 if (BYTES_BIG_ENDIAN && TREE_TYPE (parm) != DECL_ARG_TYPE (parm))
2720 offset_in_bytes += (GET_MODE_SIZE (TYPE_MODE (DECL_ARG_TYPE (parm)))
2721 - GET_MODE_SIZE (GET_MODE (DECL_RTL (parm))));
2723 return offset_in_bytes;
2727 encode_method_prototype (method_decl, func_decl)
2734 int max_parm_end = 0;
2738 /* ONEWAY and BYCOPY, for remote object are the only method qualifiers. */
2739 encode_type_qualifiers (TREE_PURPOSE (TREE_TYPE (method_decl)));
2742 encode_type (TREE_TYPE (TREE_TYPE (func_decl)),
2743 obstack_object_size (&util_obstack),
2744 OBJC_ENCODE_INLINE_DEFS);
2747 for (parms = DECL_ARGUMENTS (func_decl); parms;
2748 parms = TREE_CHAIN (parms))
2750 int parm_end = (forwarding_offset (parms)
2751 + (TREE_INT_CST_LOW (TYPE_SIZE (TREE_TYPE (parms)))
2754 if (!offset_is_register && max_parm_end < parm_end)
2755 max_parm_end = parm_end;
2758 stack_size = max_parm_end - OBJC_FORWARDING_MIN_OFFSET;
2760 sprintf (buf, "%d", stack_size);
2761 obstack_grow (&util_obstack, buf, strlen (buf));
2763 user_args = METHOD_SEL_ARGS (method_decl);
2765 /* Argument types. */
2766 for (parms = DECL_ARGUMENTS (func_decl), i = 0; parms;
2767 parms = TREE_CHAIN (parms), i++)
2769 /* Process argument qualifiers for user supplied arguments. */
2772 encode_type_qualifiers (TREE_PURPOSE (TREE_TYPE (user_args)));
2773 user_args = TREE_CHAIN (user_args);
2777 encode_type (TREE_TYPE (parms),
2778 obstack_object_size (&util_obstack),
2779 OBJC_ENCODE_INLINE_DEFS);
2781 /* Compute offset. */
2782 sprintf (buf, "%d", forwarding_offset (parms));
2784 /* Indicate register. */
2785 if (offset_is_register)
2786 obstack_1grow (&util_obstack, '+');
2788 obstack_grow (&util_obstack, buf, strlen (buf));
2791 obstack_1grow (&util_obstack, '\0');
2792 result = get_identifier (obstack_finish (&util_obstack));
2793 obstack_free (&util_obstack, util_firstobj);
2798 generate_descriptor_table (type, name, size, list, proto)
2805 tree sc_spec, decl_specs, decl, initlist;
2807 sc_spec = tree_cons (NULL_TREE, ridpointers[(int) RID_STATIC], NULL_TREE);
2808 decl_specs = tree_cons (NULL_TREE, type, sc_spec);
2810 decl = start_decl (synth_id_with_class_suffix (name, proto),
2811 decl_specs, 1, NULL_TREE, NULL_TREE);
2813 initlist = build_tree_list (NULL_TREE, build_int_2 (size, 0));
2814 initlist = tree_cons (NULL_TREE, list, initlist);
2816 finish_decl (decl, build_constructor (type, nreverse (initlist)),
2823 generate_method_descriptors (protocol) /* generate_dispatch_tables */
2826 static tree objc_method_prototype_template;
2827 tree initlist, chain, method_list_template;
2828 tree cast, variable_length_type;
2831 if (!objc_method_prototype_template)
2832 objc_method_prototype_template = build_method_prototype_template ();
2834 cast = build_tree_list (build_tree_list (NULL_TREE, xref_tag (RECORD_TYPE,
2835 get_identifier (UTAG_METHOD_PROTOTYPE_LIST))),
2837 variable_length_type = groktypename (cast);
2839 chain = PROTOCOL_CLS_METHODS (protocol);
2842 size = list_length (chain);
2844 method_list_template
2845 = build_method_prototype_list_template (objc_method_prototype_template,
2849 = build_descriptor_table_initializer (objc_method_prototype_template,
2852 UOBJC_CLASS_METHODS_decl
2853 = generate_descriptor_table (method_list_template,
2854 "_OBJC_PROTOCOL_CLASS_METHODS",
2855 size, initlist, protocol);
2856 TREE_TYPE (UOBJC_CLASS_METHODS_decl) = variable_length_type;
2859 UOBJC_CLASS_METHODS_decl = 0;
2861 chain = PROTOCOL_NST_METHODS (protocol);
2864 size = list_length (chain);
2866 method_list_template
2867 = build_method_prototype_list_template (objc_method_prototype_template,
2870 = build_descriptor_table_initializer (objc_method_prototype_template,
2873 UOBJC_INSTANCE_METHODS_decl
2874 = generate_descriptor_table (method_list_template,
2875 "_OBJC_PROTOCOL_INSTANCE_METHODS",
2876 size, initlist, protocol);
2877 TREE_TYPE (UOBJC_INSTANCE_METHODS_decl) = variable_length_type;
2880 UOBJC_INSTANCE_METHODS_decl = 0;
2884 build_tmp_function_decl ()
2886 tree decl_specs, expr_decl, parms;
2890 /* struct objc_object *objc_xxx (id, SEL, ...); */
2892 decl_specs = build_tree_list (NULL_TREE, objc_object_reference);
2893 push_parm_decl (build_tree_list
2894 (build_tree_list (decl_specs,
2895 build1 (INDIRECT_REF, NULL_TREE,
2897 build_tree_list (NULL_TREE, NULL_TREE)));
2899 decl_specs = build_tree_list (NULL_TREE, xref_tag (RECORD_TYPE,
2900 get_identifier (TAG_SELECTOR)));
2901 expr_decl = build1 (INDIRECT_REF, NULL_TREE, NULL_TREE);
2903 push_parm_decl (build_tree_list (build_tree_list (decl_specs, expr_decl),
2904 build_tree_list (NULL_TREE, NULL_TREE)));
2905 parms = get_parm_info (0);
2908 decl_specs = build_tree_list (NULL_TREE, objc_object_reference);
2909 sprintf (buffer, "__objc_tmp_%x", xxx++);
2910 expr_decl = build_nt (CALL_EXPR, get_identifier (buffer), parms, NULL_TREE);
2911 expr_decl = build1 (INDIRECT_REF, NULL_TREE, expr_decl);
2913 return define_decl (expr_decl, decl_specs);
2917 hack_method_prototype (nst_methods, tmp_decl)
2924 /* Hack to avoid problem with static typing of self arg. */
2925 TREE_SET_CODE (nst_methods, CLASS_METHOD_DECL);
2926 start_method_def (nst_methods);
2927 TREE_SET_CODE (nst_methods, INSTANCE_METHOD_DECL);
2929 if (METHOD_ADD_ARGS (nst_methods) == (tree) 1)
2930 parms = get_parm_info (0); /* we have a `, ...' */
2932 parms = get_parm_info (1); /* place a `void_at_end' */
2934 poplevel (0, 0, 0); /* Must be called BEFORE start_function. */
2936 /* Usually called from store_parm_decls -> init_function_start. */
2938 DECL_ARGUMENTS (tmp_decl) = TREE_PURPOSE (parms);
2939 current_function_decl = tmp_decl;
2942 /* Code taken from start_function. */
2943 tree restype = TREE_TYPE (TREE_TYPE (tmp_decl));
2944 /* Promote the value to int before returning it. */
2945 if (TREE_CODE (restype) == INTEGER_TYPE
2946 && TYPE_PRECISION (restype) < TYPE_PRECISION (integer_type_node))
2947 restype = integer_type_node;
2948 DECL_RESULT (tmp_decl) = build_decl (RESULT_DECL, 0, restype);
2951 for (parm = DECL_ARGUMENTS (tmp_decl); parm; parm = TREE_CHAIN (parm))
2952 DECL_CONTEXT (parm) = tmp_decl;
2954 init_function_start (tmp_decl, "objc-act", 0);
2956 /* Typically called from expand_function_start for function definitions. */
2957 assign_parms (tmp_decl, 0);
2959 /* install return type */
2960 TREE_TYPE (TREE_TYPE (tmp_decl)) = groktypename (TREE_TYPE (nst_methods));
2965 generate_protocol_references (plist)
2970 /* Forward declare protocols referenced. */
2971 for (lproto = plist; lproto; lproto = TREE_CHAIN (lproto))
2973 tree proto = TREE_VALUE (lproto);
2975 if (TREE_CODE (proto) == PROTOCOL_INTERFACE_TYPE
2976 && PROTOCOL_NAME (proto))
2978 if (! PROTOCOL_FORWARD_DECL (proto))
2979 build_protocol_reference (proto);
2981 if (PROTOCOL_LIST (proto))
2982 generate_protocol_references (PROTOCOL_LIST (proto));
2988 generate_protocols ()
2990 tree p, tmp_decl, encoding;
2991 tree sc_spec, decl_specs, decl;
2992 tree initlist, protocol_name_expr, refs_decl, refs_expr;
2993 tree cast_type2 = 0;
2995 tmp_decl = build_tmp_function_decl ();
2997 if (! objc_protocol_template)
2998 objc_protocol_template = build_protocol_template ();
3000 /* If a protocol was directly referenced, pull in indirect references. */
3001 for (p = protocol_chain; p; p = TREE_CHAIN (p))
3002 if (PROTOCOL_FORWARD_DECL (p) && PROTOCOL_LIST (p))
3003 generate_protocol_references (PROTOCOL_LIST (p));
3005 for (p = protocol_chain; p; p = TREE_CHAIN (p))
3007 tree nst_methods = PROTOCOL_NST_METHODS (p);
3008 tree cls_methods = PROTOCOL_CLS_METHODS (p);
3010 /* If protocol wasn't referenced, don't generate any code. */
3011 if (! PROTOCOL_FORWARD_DECL (p))
3014 /* Make sure we link in the Protocol class. */
3015 add_class_reference (get_identifier (PROTOCOL_OBJECT_CLASS_NAME));
3019 if (! METHOD_ENCODING (nst_methods))
3021 hack_method_prototype (nst_methods, tmp_decl);
3022 encoding = encode_method_prototype (nst_methods, tmp_decl);
3023 METHOD_ENCODING (nst_methods) = encoding;
3025 nst_methods = TREE_CHAIN (nst_methods);
3030 if (! METHOD_ENCODING (cls_methods))
3032 hack_method_prototype (cls_methods, tmp_decl);
3033 encoding = encode_method_prototype (cls_methods, tmp_decl);
3034 METHOD_ENCODING (cls_methods) = encoding;
3037 cls_methods = TREE_CHAIN (cls_methods);
3039 generate_method_descriptors (p);
3041 if (PROTOCOL_LIST (p))
3042 refs_decl = generate_protocol_list (p);
3046 /* static struct objc_protocol _OBJC_PROTOCOL_<mumble>; */
3048 sc_spec = tree_cons (NULL_TREE, ridpointers[(int) RID_STATIC],
3050 decl_specs = tree_cons (NULL_TREE, objc_protocol_template, sc_spec);
3052 decl = start_decl (synth_id_with_class_suffix ("_OBJC_PROTOCOL", p),
3053 decl_specs, 1, NULL_TREE, NULL_TREE);
3055 protocol_name_expr = add_objc_string (PROTOCOL_NAME (p), class_names);
3062 (build_tree_list (build_tree_list (NULL_TREE,
3063 objc_protocol_template),
3064 build1 (INDIRECT_REF, NULL_TREE,
3065 build1 (INDIRECT_REF, NULL_TREE,
3068 refs_expr = build_unary_op (ADDR_EXPR, refs_decl, 0);
3069 TREE_TYPE (refs_expr) = cast_type2;
3072 refs_expr = build_int_2 (0, 0);
3074 /* UOBJC_INSTANCE_METHODS_decl/UOBJC_CLASS_METHODS_decl are set
3075 by generate_method_descriptors, which is called above. */
3076 initlist = build_protocol_initializer (TREE_TYPE (decl),
3077 protocol_name_expr, refs_expr,
3078 UOBJC_INSTANCE_METHODS_decl,
3079 UOBJC_CLASS_METHODS_decl);
3080 finish_decl (decl, initlist, NULL_TREE);
3082 /* Mark the decl as used to avoid "defined but not used" warning. */
3083 TREE_USED (decl) = 1;
3088 build_protocol_initializer (type, protocol_name, protocol_list,
3089 instance_methods, class_methods)
3093 tree instance_methods;
3096 tree initlist = NULL_TREE, expr;
3097 static tree cast_type = 0;
3103 (build_tree_list (NULL_TREE,
3104 xref_tag (RECORD_TYPE,
3105 get_identifier (UTAG_CLASS))),
3106 build1 (INDIRECT_REF, NULL_TREE, NULL_TREE)));
3108 /* Filling the "isa" in with one allows the runtime system to
3109 detect that the version change...should remove before final release. */
3111 expr = build_int_2 (PROTOCOL_VERSION, 0);
3112 TREE_TYPE (expr) = cast_type;
3113 initlist = tree_cons (NULL_TREE, expr, initlist);
3114 initlist = tree_cons (NULL_TREE, protocol_name, initlist);
3115 initlist = tree_cons (NULL_TREE, protocol_list, initlist);
3117 if (!instance_methods)
3118 initlist = tree_cons (NULL_TREE, build_int_2 (0, 0), initlist);
3121 expr = build_unary_op (ADDR_EXPR, instance_methods, 0);
3122 initlist = tree_cons (NULL_TREE, expr, initlist);
3126 initlist = tree_cons (NULL_TREE, build_int_2 (0, 0), initlist);
3129 expr = build_unary_op (ADDR_EXPR, class_methods, 0);
3130 initlist = tree_cons (NULL_TREE, expr, initlist);
3133 return build_constructor (type, nreverse (initlist));
3136 /* struct objc_category {
3137 char *category_name;
3139 struct objc_method_list *instance_methods;
3140 struct objc_method_list *class_methods;
3141 struct objc_protocol_list *protocols;
3145 build_category_template ()
3147 tree decl_specs, field_decl, field_decl_chain;
3149 objc_category_template = start_struct (RECORD_TYPE,
3150 get_identifier (UTAG_CATEGORY));
3151 /* char *category_name; */
3153 decl_specs = build_tree_list (NULL_TREE, ridpointers[(int) RID_CHAR]);
3155 = build1 (INDIRECT_REF, NULL_TREE, get_identifier ("category_name"));
3157 = grokfield (input_filename, lineno, field_decl, decl_specs, NULL_TREE);
3158 field_decl_chain = field_decl;
3160 /* char *class_name; */
3162 decl_specs = build_tree_list (NULL_TREE, ridpointers[(int) RID_CHAR]);
3163 field_decl = build1 (INDIRECT_REF, NULL_TREE, get_identifier ("class_name"));
3165 = grokfield (input_filename, lineno, field_decl, decl_specs, NULL_TREE);
3166 chainon (field_decl_chain, field_decl);
3168 /* struct objc_method_list *instance_methods; */
3170 decl_specs = build_tree_list (NULL_TREE,
3171 xref_tag (RECORD_TYPE,
3172 get_identifier (UTAG_METHOD_LIST)));
3174 = build1 (INDIRECT_REF, NULL_TREE, get_identifier ("instance_methods"));
3176 = grokfield (input_filename, lineno, field_decl, decl_specs, NULL_TREE);
3177 chainon (field_decl_chain, field_decl);
3179 /* struct objc_method_list *class_methods; */
3181 decl_specs = build_tree_list (NULL_TREE,
3182 xref_tag (RECORD_TYPE,
3183 get_identifier (UTAG_METHOD_LIST)));
3185 = build1 (INDIRECT_REF, NULL_TREE, get_identifier ("class_methods"));
3187 = grokfield (input_filename, lineno, field_decl, decl_specs, NULL_TREE);
3188 chainon (field_decl_chain, field_decl);
3190 /* struct objc_protocol **protocol_list; */
3192 decl_specs = build_tree_list (NULL_TREE,
3193 xref_tag (RECORD_TYPE,
3194 get_identifier (UTAG_PROTOCOL)));
3196 = build1 (INDIRECT_REF, NULL_TREE, get_identifier ("protocol_list"));
3197 field_decl = build1 (INDIRECT_REF, NULL_TREE, field_decl);
3199 = grokfield (input_filename, lineno, field_decl, decl_specs, NULL_TREE);
3200 chainon (field_decl_chain, field_decl);
3202 finish_struct (objc_category_template, field_decl_chain, NULL_TREE);
3205 /* struct objc_selector {
3211 build_selector_template ()
3214 tree decl_specs, field_decl, field_decl_chain;
3216 objc_selector_template
3217 = start_struct (RECORD_TYPE, get_identifier (UTAG_SELECTOR));
3221 decl_specs = build_tree_list (NULL_TREE, ridpointers[(int) RID_VOID]);
3222 field_decl = build1 (INDIRECT_REF, NULL_TREE, get_identifier ("sel_id"));
3224 = grokfield (input_filename, lineno, field_decl, decl_specs, NULL_TREE);
3225 field_decl_chain = field_decl;
3227 /* char *sel_type; */
3229 decl_specs = build_tree_list (NULL_TREE, ridpointers[(int) RID_CHAR]);
3230 field_decl = build1 (INDIRECT_REF, NULL_TREE, get_identifier ("sel_type"));
3232 = grokfield (input_filename, lineno, field_decl, decl_specs, NULL_TREE);
3233 chainon (field_decl_chain, field_decl);
3235 finish_struct (objc_selector_template, field_decl_chain, NULL_TREE);
3238 /* struct objc_class {
3239 struct objc_class *isa;
3240 struct objc_class *super_class;
3245 struct objc_ivar_list *ivars;
3246 struct objc_method_list *methods;
3247 if (flag_next_runtime)
3248 struct objc_cache *cache;
3250 struct sarray *dtable;
3251 struct objc_class *subclass_list;
3252 struct objc_class *sibling_class;
3254 struct objc_protocol_list *protocols;
3258 build_class_template ()
3260 tree decl_specs, field_decl, field_decl_chain;
3263 = start_struct (RECORD_TYPE, get_identifier (UTAG_CLASS));
3265 /* struct objc_class *isa; */
3267 decl_specs = build_tree_list (NULL_TREE, objc_class_template);
3268 field_decl = build1 (INDIRECT_REF, NULL_TREE, get_identifier ("isa"));
3270 = grokfield (input_filename, lineno, field_decl, decl_specs, NULL_TREE);
3271 field_decl_chain = field_decl;
3273 /* struct objc_class *super_class; */
3275 decl_specs = build_tree_list (NULL_TREE, objc_class_template);
3277 = build1 (INDIRECT_REF, NULL_TREE, get_identifier ("super_class"));
3279 = grokfield (input_filename, lineno, field_decl, decl_specs, NULL_TREE);
3280 chainon (field_decl_chain, field_decl);
3284 decl_specs = build_tree_list (NULL_TREE, ridpointers[(int) RID_CHAR]);
3285 field_decl = build1 (INDIRECT_REF, NULL_TREE, get_identifier ("name"));
3287 = grokfield (input_filename, lineno, field_decl, decl_specs, NULL_TREE);
3288 chainon (field_decl_chain, field_decl);
3292 decl_specs = build_tree_list (NULL_TREE, ridpointers[(int) RID_LONG]);
3293 field_decl = get_identifier ("version");
3295 = grokfield (input_filename, lineno, field_decl, decl_specs, NULL_TREE);
3296 chainon (field_decl_chain, field_decl);
3300 decl_specs = build_tree_list (NULL_TREE, ridpointers[(int) RID_LONG]);
3301 field_decl = get_identifier ("info");
3303 = grokfield (input_filename, lineno, field_decl, decl_specs, NULL_TREE);
3304 chainon (field_decl_chain, field_decl);
3306 /* long instance_size; */
3308 decl_specs = build_tree_list (NULL_TREE, ridpointers[(int) RID_LONG]);
3309 field_decl = get_identifier ("instance_size");
3311 = grokfield (input_filename, lineno, field_decl, decl_specs, NULL_TREE);
3312 chainon (field_decl_chain, field_decl);
3314 /* struct objc_ivar_list *ivars; */
3316 decl_specs = build_tree_list (NULL_TREE,
3317 xref_tag (RECORD_TYPE,
3318 get_identifier (UTAG_IVAR_LIST)));
3319 field_decl = build1 (INDIRECT_REF, NULL_TREE, get_identifier ("ivars"));
3321 = grokfield (input_filename, lineno, field_decl, decl_specs, NULL_TREE);
3322 chainon (field_decl_chain, field_decl);
3324 /* struct objc_method_list *methods; */
3326 decl_specs = build_tree_list (NULL_TREE,
3327 xref_tag (RECORD_TYPE,
3328 get_identifier (UTAG_METHOD_LIST)));
3329 field_decl = build1 (INDIRECT_REF, NULL_TREE, get_identifier ("methods"));
3331 = grokfield (input_filename, lineno, field_decl, decl_specs, NULL_TREE);
3332 chainon (field_decl_chain, field_decl);
3334 if (flag_next_runtime)
3336 /* struct objc_cache *cache; */
3338 decl_specs = build_tree_list (NULL_TREE,
3339 xref_tag (RECORD_TYPE,
3340 get_identifier ("objc_cache")));
3341 field_decl = build1 (INDIRECT_REF, NULL_TREE, get_identifier ("cache"));
3342 field_decl = grokfield (input_filename, lineno, field_decl,
3343 decl_specs, NULL_TREE);
3344 chainon (field_decl_chain, field_decl);
3348 /* struct sarray *dtable; */
3350 decl_specs = build_tree_list (NULL_TREE,
3351 xref_tag (RECORD_TYPE,
3352 get_identifier ("sarray")));
3353 field_decl = build1 (INDIRECT_REF, NULL_TREE, get_identifier ("dtable"));
3354 field_decl = grokfield (input_filename, lineno, field_decl,
3355 decl_specs, NULL_TREE);
3356 chainon (field_decl_chain, field_decl);
3358 /* struct objc_class *subclass_list; */
3360 decl_specs = build_tree_list (NULL_TREE, objc_class_template);
3362 = build1 (INDIRECT_REF, NULL_TREE, get_identifier ("subclass_list"));
3363 field_decl = grokfield (input_filename, lineno, field_decl,
3364 decl_specs, NULL_TREE);
3365 chainon (field_decl_chain, field_decl);
3367 /* struct objc_class *sibling_class; */
3369 decl_specs = build_tree_list (NULL_TREE, objc_class_template);
3371 = build1 (INDIRECT_REF, NULL_TREE, get_identifier ("sibling_class"));
3372 field_decl = grokfield (input_filename, lineno, field_decl,
3373 decl_specs, NULL_TREE);
3374 chainon (field_decl_chain, field_decl);
3377 /* struct objc_protocol **protocol_list; */
3379 decl_specs = build_tree_list (NULL_TREE,
3380 xref_tag (RECORD_TYPE,
3381 get_identifier (UTAG_PROTOCOL)));
3383 = build1 (INDIRECT_REF, NULL_TREE, get_identifier ("protocol_list"));
3385 = build1 (INDIRECT_REF, NULL_TREE, field_decl);
3386 field_decl = grokfield (input_filename, lineno, field_decl,
3387 decl_specs, NULL_TREE);
3388 chainon (field_decl_chain, field_decl);
3391 finish_struct (objc_class_template, field_decl_chain, NULL_TREE);
3394 /* Generate appropriate forward declarations for an implementation. */
3397 synth_forward_declarations ()
3399 tree sc_spec, decl_specs, an_id;
3401 /* extern struct objc_class _OBJC_CLASS_<my_name>; */
3403 an_id = synth_id_with_class_suffix ("_OBJC_CLASS", implementation_context);
3405 sc_spec = build_tree_list (NULL_TREE, ridpointers[(int) RID_EXTERN]);
3406 decl_specs = tree_cons (NULL_TREE, objc_class_template, sc_spec);
3407 UOBJC_CLASS_decl = define_decl (an_id, decl_specs);
3408 TREE_USED (UOBJC_CLASS_decl) = 1;
3409 DECL_ARTIFICIAL (UOBJC_CLASS_decl) = 1;
3411 /* extern struct objc_class _OBJC_METACLASS_<my_name>; */
3413 an_id = synth_id_with_class_suffix ("_OBJC_METACLASS",
3414 implementation_context);
3416 UOBJC_METACLASS_decl = define_decl (an_id, decl_specs);
3417 TREE_USED (UOBJC_METACLASS_decl) = 1;
3418 DECL_ARTIFICIAL(UOBJC_METACLASS_decl) = 1;
3420 /* Pre-build the following entities - for speed/convenience. */
3422 an_id = get_identifier ("super_class");
3423 ucls_super_ref = build_component_ref (UOBJC_CLASS_decl, an_id);
3424 uucls_super_ref = build_component_ref (UOBJC_METACLASS_decl, an_id);
3428 error_with_ivar (message, decl, rawdecl)
3435 report_error_function (DECL_SOURCE_FILE (decl));
3437 fprintf (stderr, "%s:%d: ",
3438 DECL_SOURCE_FILE (decl), DECL_SOURCE_LINE (decl));
3439 bzero (errbuf, BUFSIZE);
3440 fprintf (stderr, "%s `%s'\n", message, gen_declaration (rawdecl, errbuf));
3443 #define USERTYPE(t) \
3444 (TREE_CODE (t) == RECORD_TYPE || TREE_CODE (t) == UNION_TYPE \
3445 || TREE_CODE (t) == ENUMERAL_TYPE)
3448 check_ivars (inter, imp)
3452 tree intdecls = CLASS_IVARS (inter);
3453 tree impdecls = CLASS_IVARS (imp);
3454 tree rawintdecls = CLASS_RAW_IVARS (inter);
3455 tree rawimpdecls = CLASS_RAW_IVARS (imp);
3461 if (intdecls == 0 && impdecls == 0)
3463 if (intdecls == 0 || impdecls == 0)
3465 error ("inconsistent instance variable specification");
3469 t1 = TREE_TYPE (intdecls); t2 = TREE_TYPE (impdecls);
3471 if (!comptypes (t1, t2))
3473 if (DECL_NAME (intdecls) == DECL_NAME (impdecls))
3475 error_with_ivar ("conflicting instance variable type",
3476 impdecls, rawimpdecls);
3477 error_with_ivar ("previous declaration of",
3478 intdecls, rawintdecls);
3480 else /* both the type and the name don't match */
3482 error ("inconsistent instance variable specification");
3487 else if (DECL_NAME (intdecls) != DECL_NAME (impdecls))
3489 error_with_ivar ("conflicting instance variable name",
3490 impdecls, rawimpdecls);
3491 error_with_ivar ("previous declaration of",
3492 intdecls, rawintdecls);
3495 intdecls = TREE_CHAIN (intdecls);
3496 impdecls = TREE_CHAIN (impdecls);
3497 rawintdecls = TREE_CHAIN (rawintdecls);
3498 rawimpdecls = TREE_CHAIN (rawimpdecls);
3502 /* Set super_type to the data type node for struct objc_super *,
3503 first defining struct objc_super itself.
3504 This needs to be done just once per compilation. */
3507 build_super_template ()
3509 tree record, decl_specs, field_decl, field_decl_chain;
3511 record = start_struct (RECORD_TYPE, get_identifier (UTAG_SUPER));
3513 /* struct objc_object *self; */
3515 decl_specs = build_tree_list (NULL_TREE, objc_object_reference);
3516 field_decl = get_identifier ("self");
3517 field_decl = build1 (INDIRECT_REF, NULL_TREE, field_decl);
3518 field_decl = grokfield (input_filename, lineno,
3519 field_decl, decl_specs, NULL_TREE);
3520 field_decl_chain = field_decl;
3522 /* struct objc_class *class; */
3524 decl_specs = get_identifier (UTAG_CLASS);
3525 decl_specs = build_tree_list (NULL_TREE, xref_tag (RECORD_TYPE, decl_specs));
3526 field_decl = build1 (INDIRECT_REF, NULL_TREE, get_identifier ("class"));
3528 field_decl = grokfield (input_filename, lineno,
3529 field_decl, decl_specs, NULL_TREE);
3530 chainon (field_decl_chain, field_decl);
3532 finish_struct (record, field_decl_chain, NULL_TREE);
3534 /* `struct objc_super *' */
3535 super_type = groktypename (build_tree_list (build_tree_list (NULL_TREE,
3537 build1 (INDIRECT_REF,
3538 NULL_TREE, NULL_TREE)));
3542 /* struct objc_ivar {
3549 build_ivar_template ()
3551 tree objc_ivar_id, objc_ivar_record;
3552 tree decl_specs, field_decl, field_decl_chain;
3554 objc_ivar_id = get_identifier (UTAG_IVAR);
3555 objc_ivar_record = start_struct (RECORD_TYPE, objc_ivar_id);
3557 /* char *ivar_name; */
3559 decl_specs = build_tree_list (NULL_TREE, ridpointers[(int) RID_CHAR]);
3560 field_decl = build1 (INDIRECT_REF, NULL_TREE, get_identifier ("ivar_name"));
3562 field_decl = grokfield (input_filename, lineno, field_decl,
3563 decl_specs, NULL_TREE);
3564 field_decl_chain = field_decl;
3566 /* char *ivar_type; */
3568 decl_specs = build_tree_list (NULL_TREE, ridpointers[(int) RID_CHAR]);
3569 field_decl = build1 (INDIRECT_REF, NULL_TREE, get_identifier ("ivar_type"));
3571 field_decl = grokfield (input_filename, lineno, field_decl,
3572 decl_specs, NULL_TREE);
3573 chainon (field_decl_chain, field_decl);
3575 /* int ivar_offset; */
3577 decl_specs = build_tree_list (NULL_TREE, ridpointers[(int) RID_INT]);
3578 field_decl = get_identifier ("ivar_offset");
3580 field_decl = grokfield (input_filename, lineno, field_decl,
3581 decl_specs, NULL_TREE);
3582 chainon (field_decl_chain, field_decl);
3584 finish_struct (objc_ivar_record, field_decl_chain, NULL_TREE);
3586 return objc_ivar_record;
3591 struct objc_ivar ivar_list[ivar_count];
3595 build_ivar_list_template (list_type, size)
3599 tree objc_ivar_list_record;
3600 tree decl_specs, field_decl, field_decl_chain;
3602 objc_ivar_list_record = start_struct (RECORD_TYPE, NULL_TREE);
3604 /* int ivar_count; */
3606 decl_specs = build_tree_list (NULL_TREE, ridpointers[(int) RID_INT]);
3607 field_decl = get_identifier ("ivar_count");
3609 field_decl = grokfield (input_filename, lineno, field_decl,
3610 decl_specs, NULL_TREE);
3611 field_decl_chain = field_decl;
3613 /* struct objc_ivar ivar_list[]; */
3615 decl_specs = build_tree_list (NULL_TREE, list_type);
3616 field_decl = build_nt (ARRAY_REF, get_identifier ("ivar_list"),
3617 build_int_2 (size, 0));
3619 field_decl = grokfield (input_filename, lineno,
3620 field_decl, decl_specs, NULL_TREE);
3621 chainon (field_decl_chain, field_decl);
3623 finish_struct (objc_ivar_list_record, field_decl_chain, NULL_TREE);
3625 return objc_ivar_list_record;
3631 struct objc_method method_list[method_count];
3635 build_method_list_template (list_type, size)
3639 tree objc_ivar_list_record;
3640 tree decl_specs, field_decl, field_decl_chain;
3642 objc_ivar_list_record = start_struct (RECORD_TYPE, NULL_TREE);
3644 /* int method_next; */
3649 xref_tag (RECORD_TYPE,
3650 get_identifier (UTAG_METHOD_PROTOTYPE_LIST)));
3652 = build1 (INDIRECT_REF, NULL_TREE, get_identifier ("method_next"));
3653 field_decl = grokfield (input_filename, lineno, field_decl,
3654 decl_specs, NULL_TREE);
3655 field_decl_chain = field_decl;
3657 /* int method_count; */
3659 decl_specs = build_tree_list (NULL_TREE, ridpointers[(int) RID_INT]);
3660 field_decl = get_identifier ("method_count");
3662 field_decl = grokfield (input_filename, lineno,
3663 field_decl, decl_specs, NULL_TREE);
3664 chainon (field_decl_chain, field_decl);
3666 /* struct objc_method method_list[]; */
3668 decl_specs = build_tree_list (NULL_TREE, list_type);
3669 field_decl = build_nt (ARRAY_REF, get_identifier ("method_list"),
3670 build_int_2 (size, 0));
3672 field_decl = grokfield (input_filename, lineno,
3673 field_decl, decl_specs, NULL_TREE);
3674 chainon (field_decl_chain, field_decl);
3676 finish_struct (objc_ivar_list_record, field_decl_chain, NULL_TREE);
3678 return objc_ivar_list_record;
3682 build_ivar_list_initializer (type, field_decl)
3686 tree initlist = NULL_TREE;
3690 tree ivar = NULL_TREE;
3693 if (DECL_NAME (field_decl))
3694 ivar = tree_cons (NULL_TREE,
3695 add_objc_string (DECL_NAME (field_decl),
3699 /* Unnamed bit-field ivar (yuck). */
3700 ivar = tree_cons (NULL_TREE, build_int_2 (0, 0), ivar);
3703 encode_field_decl (field_decl,
3704 obstack_object_size (&util_obstack),
3705 OBJC_ENCODE_DONT_INLINE_DEFS);
3707 /* Null terminate string. */
3708 obstack_1grow (&util_obstack, 0);
3712 add_objc_string (get_identifier (obstack_finish (&util_obstack)),
3715 obstack_free (&util_obstack, util_firstobj);
3721 build_int_2 ((TREE_INT_CST_LOW (DECL_FIELD_BITPOS (field_decl))
3726 initlist = tree_cons (NULL_TREE,
3727 build_constructor (type, nreverse (ivar)),
3730 field_decl = TREE_CHAIN (field_decl);
3734 return build_constructor (build_array_type (type, 0), nreverse (initlist));
3738 generate_ivars_list (type, name, size, list)
3744 tree sc_spec, decl_specs, decl, initlist;
3746 sc_spec = tree_cons (NULL_TREE, ridpointers[(int) RID_STATIC], NULL_TREE);
3747 decl_specs = tree_cons (NULL_TREE, type, sc_spec);
3749 decl = start_decl (synth_id_with_class_suffix (name, implementation_context),
3750 decl_specs, 1, NULL_TREE, NULL_TREE);
3752 initlist = build_tree_list (NULL_TREE, build_int_2 (size, 0));
3753 initlist = tree_cons (NULL_TREE, list, initlist);
3756 build_constructor (TREE_TYPE (decl), nreverse (initlist)),
3763 generate_ivar_lists ()
3765 tree initlist, ivar_list_template, chain;
3766 tree cast, variable_length_type;
3769 generating_instance_variables = 1;
3771 if (!objc_ivar_template)
3772 objc_ivar_template = build_ivar_template ();
3776 (build_tree_list (NULL_TREE, xref_tag (RECORD_TYPE,
3777 get_identifier (UTAG_IVAR_LIST))),
3779 variable_length_type = groktypename (cast);
3781 /* Only generate class variables for the root of the inheritance
3782 hierarchy since these will be the same for every class. */
3784 if (CLASS_SUPER_NAME (implementation_template) == NULL_TREE
3785 && (chain = TYPE_FIELDS (objc_class_template)))
3787 size = list_length (chain);
3789 ivar_list_template = build_ivar_list_template (objc_ivar_template, size);
3790 initlist = build_ivar_list_initializer (objc_ivar_template, chain);
3792 UOBJC_CLASS_VARIABLES_decl
3793 = generate_ivars_list (ivar_list_template, "_OBJC_CLASS_VARIABLES",
3795 TREE_TYPE (UOBJC_CLASS_VARIABLES_decl) = variable_length_type;
3798 UOBJC_CLASS_VARIABLES_decl = 0;
3800 chain = CLASS_IVARS (implementation_template);
3803 size = list_length (chain);
3804 ivar_list_template = build_ivar_list_template (objc_ivar_template, size);
3805 initlist = build_ivar_list_initializer (objc_ivar_template, chain);
3807 UOBJC_INSTANCE_VARIABLES_decl
3808 = generate_ivars_list (ivar_list_template, "_OBJC_INSTANCE_VARIABLES",
3810 TREE_TYPE (UOBJC_INSTANCE_VARIABLES_decl) = variable_length_type;
3813 UOBJC_INSTANCE_VARIABLES_decl = 0;
3815 generating_instance_variables = 0;
3819 build_dispatch_table_initializer (type, entries)
3823 tree initlist = NULL_TREE;
3827 tree elemlist = NULL_TREE;
3829 elemlist = tree_cons (NULL_TREE,
3830 build_selector (METHOD_SEL_NAME (entries)),
3833 elemlist = tree_cons (NULL_TREE,
3834 add_objc_string (METHOD_ENCODING (entries),
3838 elemlist = tree_cons (NULL_TREE,
3839 build_unary_op (ADDR_EXPR,
3840 METHOD_DEFINITION (entries), 1),
3843 initlist = tree_cons (NULL_TREE,
3844 build_constructor (type, nreverse (elemlist)),
3847 entries = TREE_CHAIN (entries);
3851 return build_constructor (build_array_type (type, 0), nreverse (initlist));
3854 /* To accomplish method prototyping without generating all kinds of
3855 inane warnings, the definition of the dispatch table entries were
3858 struct objc_method { SEL _cmd; ...; id (*_imp)(); };
3860 struct objc_method { SEL _cmd; ...; void *_imp; }; */
3863 build_method_template ()
3866 tree decl_specs, field_decl, field_decl_chain;
3868 _SLT_record = start_struct (RECORD_TYPE, get_identifier (UTAG_METHOD));
3870 #ifdef OBJC_INT_SELECTORS
3871 /* unsigned int _cmd; */
3872 decl_specs = tree_cons (NULL_TREE, ridpointers[(int) RID_UNSIGNED],
3874 decl_specs = tree_cons (NULL_TREE, ridpointers[(int) RID_INT], decl_specs);
3875 field_decl = get_identifier ("_cmd");
3876 #else /* not OBJC_INT_SELECTORS */
3877 /* struct objc_selector *_cmd; */
3878 decl_specs = tree_cons (NULL_TREE,
3879 xref_tag (RECORD_TYPE,
3880 get_identifier (TAG_SELECTOR)),
3882 field_decl = build1 (INDIRECT_REF, NULL_TREE, get_identifier ("_cmd"));
3883 #endif /* not OBJC_INT_SELECTORS */
3885 field_decl = grokfield (input_filename, lineno, field_decl,
3886 decl_specs, NULL_TREE);
3887 field_decl_chain = field_decl;
3889 decl_specs = tree_cons (NULL_TREE, ridpointers[(int) RID_CHAR], NULL_TREE);
3890 field_decl = build1 (INDIRECT_REF, NULL_TREE,
3891 get_identifier ("method_types"));
3892 field_decl = grokfield (input_filename, lineno, field_decl,
3893 decl_specs, NULL_TREE);
3894 chainon (field_decl_chain, field_decl);
3898 decl_specs = tree_cons (NULL_TREE, ridpointers[(int) RID_VOID], NULL_TREE);
3899 field_decl = build1 (INDIRECT_REF, NULL_TREE, get_identifier ("_imp"));
3900 field_decl = grokfield (input_filename, lineno, field_decl,
3901 decl_specs, NULL_TREE);
3902 chainon (field_decl_chain, field_decl);
3904 finish_struct (_SLT_record, field_decl_chain, NULL_TREE);
3911 generate_dispatch_table (type, name, size, list)
3917 tree sc_spec, decl_specs, decl, initlist;
3919 sc_spec = tree_cons (NULL_TREE, ridpointers[(int) RID_STATIC], NULL_TREE);
3920 decl_specs = tree_cons (NULL_TREE, type, sc_spec);
3922 decl = start_decl (synth_id_with_class_suffix (name, implementation_context),
3923 decl_specs, 1, NULL_TREE, NULL_TREE);
3925 initlist = build_tree_list (NULL_TREE, build_int_2 (0, 0));
3926 initlist = tree_cons (NULL_TREE, build_int_2 (size, 0), initlist);
3927 initlist = tree_cons (NULL_TREE, list, initlist);
3930 build_constructor (TREE_TYPE (decl), nreverse (initlist)),
3937 generate_dispatch_tables ()
3939 tree initlist, chain, method_list_template;
3940 tree cast, variable_length_type;
3943 if (!objc_method_template)
3944 objc_method_template = build_method_template ();
3948 (build_tree_list (NULL_TREE,
3949 xref_tag (RECORD_TYPE,
3950 get_identifier (UTAG_METHOD_LIST))),
3953 variable_length_type = groktypename (cast);
3955 chain = CLASS_CLS_METHODS (implementation_context);
3958 size = list_length (chain);
3960 method_list_template
3961 = build_method_list_template (objc_method_template, size);
3963 = build_dispatch_table_initializer (objc_method_template, chain);
3965 UOBJC_CLASS_METHODS_decl
3966 = generate_dispatch_table (method_list_template,
3967 ((TREE_CODE (implementation_context)
3968 == CLASS_IMPLEMENTATION_TYPE)
3969 ? "_OBJC_CLASS_METHODS"
3970 : "_OBJC_CATEGORY_CLASS_METHODS"),
3972 TREE_TYPE (UOBJC_CLASS_METHODS_decl) = variable_length_type;
3975 UOBJC_CLASS_METHODS_decl = 0;
3977 chain = CLASS_NST_METHODS (implementation_context);
3980 size = list_length (chain);
3982 method_list_template
3983 = build_method_list_template (objc_method_template, size);
3985 = build_dispatch_table_initializer (objc_method_template, chain);
3987 if (TREE_CODE (implementation_context) == CLASS_IMPLEMENTATION_TYPE)
3988 UOBJC_INSTANCE_METHODS_decl
3989 = generate_dispatch_table (method_list_template,
3990 "_OBJC_INSTANCE_METHODS",
3993 /* We have a category. */
3994 UOBJC_INSTANCE_METHODS_decl
3995 = generate_dispatch_table (method_list_template,
3996 "_OBJC_CATEGORY_INSTANCE_METHODS",
3998 TREE_TYPE (UOBJC_INSTANCE_METHODS_decl) = variable_length_type;
4001 UOBJC_INSTANCE_METHODS_decl = 0;
4005 generate_protocol_list (i_or_p)
4008 static tree cast_type = 0;
4009 tree initlist, decl_specs, sc_spec;
4010 tree refs_decl, expr_decl, lproto, e, plist;
4013 if (TREE_CODE (i_or_p) == CLASS_INTERFACE_TYPE
4014 || TREE_CODE (i_or_p) == CATEGORY_INTERFACE_TYPE)
4015 plist = CLASS_PROTOCOL_LIST (i_or_p);
4016 else if (TREE_CODE (i_or_p) == PROTOCOL_INTERFACE_TYPE)
4017 plist = PROTOCOL_LIST (i_or_p);
4025 (build_tree_list (NULL_TREE,
4026 xref_tag (RECORD_TYPE,
4027 get_identifier (UTAG_PROTOCOL))),
4028 build1 (INDIRECT_REF, NULL_TREE, NULL_TREE)));
4031 for (lproto = plist; lproto; lproto = TREE_CHAIN (lproto))
4032 if (TREE_CODE (TREE_VALUE (lproto)) == PROTOCOL_INTERFACE_TYPE
4033 && PROTOCOL_FORWARD_DECL (TREE_VALUE (lproto)))
4036 /* Build initializer. */
4037 initlist = tree_cons (NULL_TREE, build_int_2 (0, 0), NULL_TREE);
4039 e = build_int_2 (size, 0);
4040 TREE_TYPE (e) = cast_type;
4041 initlist = tree_cons (NULL_TREE, e, initlist);
4043 for (lproto = plist; lproto; lproto = TREE_CHAIN (lproto))
4045 tree pval = TREE_VALUE (lproto);
4047 if (TREE_CODE (pval) == PROTOCOL_INTERFACE_TYPE
4048 && PROTOCOL_FORWARD_DECL (pval))
4050 e = build_unary_op (ADDR_EXPR, PROTOCOL_FORWARD_DECL (pval), 0);
4051 initlist = tree_cons (NULL_TREE, e, initlist);
4055 /* static struct objc_protocol *refs[n]; */
4057 sc_spec = tree_cons (NULL_TREE, ridpointers[(int) RID_STATIC], NULL_TREE);
4058 decl_specs = tree_cons (NULL_TREE, xref_tag (RECORD_TYPE,
4059 get_identifier (UTAG_PROTOCOL)),
4062 if (TREE_CODE (i_or_p) == PROTOCOL_INTERFACE_TYPE)
4063 expr_decl = build_nt (ARRAY_REF,
4064 synth_id_with_class_suffix ("_OBJC_PROTOCOL_REFS",
4066 build_int_2 (size + 2, 0));
4067 else if (TREE_CODE (i_or_p) == CLASS_INTERFACE_TYPE)
4068 expr_decl = build_nt (ARRAY_REF,
4069 synth_id_with_class_suffix ("_OBJC_CLASS_PROTOCOLS",
4071 build_int_2 (size + 2, 0));
4072 else if (TREE_CODE (i_or_p) == CATEGORY_INTERFACE_TYPE)
4074 = build_nt (ARRAY_REF,
4075 synth_id_with_class_suffix ("_OBJC_CATEGORY_PROTOCOLS",
4077 build_int_2 (size + 2, 0));
4079 expr_decl = build1 (INDIRECT_REF, NULL_TREE, expr_decl);
4081 refs_decl = start_decl (expr_decl, decl_specs, 1, NULL_TREE, NULL_TREE);
4083 finish_decl (refs_decl, build_constructor (TREE_TYPE (refs_decl),
4084 nreverse (initlist)),
4091 build_category_initializer (type, cat_name, class_name,
4092 instance_methods, class_methods, protocol_list)
4096 tree instance_methods;
4100 tree initlist = NULL_TREE, expr;
4102 initlist = tree_cons (NULL_TREE, cat_name, initlist);
4103 initlist = tree_cons (NULL_TREE, class_name, initlist);
4105 if (!instance_methods)
4106 initlist = tree_cons (NULL_TREE, build_int_2 (0, 0), initlist);
4109 expr = build_unary_op (ADDR_EXPR, instance_methods, 0);
4110 initlist = tree_cons (NULL_TREE, expr, initlist);
4113 initlist = tree_cons (NULL_TREE, build_int_2 (0, 0), initlist);
4116 expr = build_unary_op (ADDR_EXPR, class_methods, 0);
4117 initlist = tree_cons (NULL_TREE, expr, initlist);
4120 /* protocol_list = */
4122 initlist = tree_cons (NULL_TREE, build_int_2 (0, 0), initlist);
4125 static tree cast_type2;
4131 (build_tree_list (NULL_TREE,
4132 xref_tag (RECORD_TYPE,
4133 get_identifier (UTAG_PROTOCOL))),
4134 build1 (INDIRECT_REF, NULL_TREE,
4135 build1 (INDIRECT_REF, NULL_TREE, NULL_TREE))));
4137 expr = build_unary_op (ADDR_EXPR, protocol_list, 0);
4138 TREE_TYPE (expr) = cast_type2;
4139 initlist = tree_cons (NULL_TREE, expr, initlist);
4142 return build_constructor (type, nreverse (initlist));
4145 /* struct objc_class {
4146 struct objc_class *isa;
4147 struct objc_class *super_class;
4152 struct objc_ivar_list *ivars;
4153 struct objc_method_list *methods;
4154 if (flag_next_runtime)
4155 struct objc_cache *cache;
4157 struct sarray *dtable;
4158 struct objc_class *subclass_list;
4159 struct objc_class *sibling_class;
4161 struct objc_protocol_list *protocols;
4165 build_shared_structure_initializer (type, isa, super, name, size, status,
4166 dispatch_table, ivar_list, protocol_list)
4173 tree dispatch_table;
4177 tree initlist = NULL_TREE, expr;
4180 initlist = tree_cons (NULL_TREE, isa, initlist);
4183 initlist = tree_cons (NULL_TREE, super, initlist);
4186 initlist = tree_cons (NULL_TREE, default_conversion (name), initlist);
4189 initlist = tree_cons (NULL_TREE, build_int_2 (0, 0), initlist);
4192 initlist = tree_cons (NULL_TREE, build_int_2 (status, 0), initlist);
4194 /* instance_size = */
4195 initlist = tree_cons (NULL_TREE, size, initlist);
4197 /* objc_ivar_list = */
4199 initlist = tree_cons (NULL_TREE, build_int_2 (0, 0), initlist);
4202 expr = build_unary_op (ADDR_EXPR, ivar_list, 0);
4203 initlist = tree_cons (NULL_TREE, expr, initlist);
4206 /* objc_method_list = */
4207 if (!dispatch_table)
4208 initlist = tree_cons (NULL_TREE, build_int_2 (0, 0), initlist);
4211 expr = build_unary_op (ADDR_EXPR, dispatch_table, 0);
4212 initlist = tree_cons (NULL_TREE, expr, initlist);
4215 if (flag_next_runtime)
4216 /* method_cache = */
4217 initlist = tree_cons (NULL_TREE, build_int_2 (0, 0), initlist);
4221 initlist = tree_cons (NULL_TREE, build_int_2 (0, 0), initlist);
4223 /* subclass_list = */
4224 initlist = tree_cons (NULL_TREE, build_int_2 (0, 0), initlist);
4226 /* sibling_class = */
4227 initlist = tree_cons (NULL_TREE, build_int_2 (0, 0), initlist);
4230 /* protocol_list = */
4231 if (! protocol_list)
4232 initlist = tree_cons (NULL_TREE, build_int_2 (0, 0), initlist);
4235 static tree cast_type2;
4241 (build_tree_list (NULL_TREE,
4242 xref_tag (RECORD_TYPE,
4243 get_identifier (UTAG_PROTOCOL))),
4244 build1 (INDIRECT_REF, NULL_TREE,
4245 build1 (INDIRECT_REF, NULL_TREE, NULL_TREE))));
4247 expr = build_unary_op (ADDR_EXPR, protocol_list, 0);
4248 TREE_TYPE (expr) = cast_type2;
4249 initlist = tree_cons (NULL_TREE, expr, initlist);
4252 return build_constructor (type, nreverse (initlist));
4255 /* static struct objc_category _OBJC_CATEGORY_<name> = { ... }; */
4258 generate_category (cat)
4261 tree sc_spec, decl_specs, decl;
4262 tree initlist, cat_name_expr, class_name_expr;
4263 tree protocol_decl, category;
4265 add_class_reference (CLASS_NAME (cat));
4266 cat_name_expr = add_objc_string (CLASS_SUPER_NAME (cat), class_names);
4268 class_name_expr = add_objc_string (CLASS_NAME (cat), class_names);
4270 category = CLASS_CATEGORY_LIST (implementation_template);
4272 /* find the category interface from the class it is associated with */
4275 if (CLASS_SUPER_NAME (cat) == CLASS_SUPER_NAME (category))
4277 category = CLASS_CATEGORY_LIST (category);
4280 if (category && CLASS_PROTOCOL_LIST (category))
4282 generate_protocol_references (CLASS_PROTOCOL_LIST (category));
4283 protocol_decl = generate_protocol_list (category);
4288 sc_spec = tree_cons (NULL_TREE, ridpointers[(int) RID_STATIC], NULL_TREE);
4289 decl_specs = tree_cons (NULL_TREE, objc_category_template, sc_spec);
4291 decl = start_decl (synth_id_with_class_suffix ("_OBJC_CATEGORY",
4292 implementation_context),
4293 decl_specs, 1, NULL_TREE, NULL_TREE);
4295 initlist = build_category_initializer (TREE_TYPE (decl),
4296 cat_name_expr, class_name_expr,
4297 UOBJC_INSTANCE_METHODS_decl,
4298 UOBJC_CLASS_METHODS_decl,
4301 TREE_USED (decl) = 1;
4302 finish_decl (decl, initlist, NULL_TREE);
4305 /* static struct objc_class _OBJC_METACLASS_Foo={ ... };
4306 static struct objc_class _OBJC_CLASS_Foo={ ... }; */
4309 generate_shared_structures ()
4311 tree sc_spec, decl_specs, decl;
4312 tree name_expr, super_expr, root_expr;
4313 tree my_root_id = NULL_TREE, my_super_id = NULL_TREE;
4314 tree cast_type, initlist, protocol_decl;
4316 my_super_id = CLASS_SUPER_NAME (implementation_template);
4319 add_class_reference (my_super_id);
4321 /* Compute "my_root_id" - this is required for code generation.
4322 the "isa" for all meta class structures points to the root of
4323 the inheritance hierarchy (e.g. "__Object")... */
4324 my_root_id = my_super_id;
4327 tree my_root_int = lookup_interface (my_root_id);
4329 if (my_root_int && CLASS_SUPER_NAME (my_root_int))
4330 my_root_id = CLASS_SUPER_NAME (my_root_int);
4337 /* No super class. */
4338 my_root_id = CLASS_NAME (implementation_template);
4341 = groktypename (build_tree_list (build_tree_list (NULL_TREE,
4342 objc_class_template),
4343 build1 (INDIRECT_REF,
4344 NULL_TREE, NULL_TREE)));
4346 name_expr = add_objc_string (CLASS_NAME (implementation_template),
4349 /* Install class `isa' and `super' pointers at runtime. */
4352 super_expr = add_objc_string (my_super_id, class_names);
4353 super_expr = build_c_cast (cast_type, super_expr); /* cast! */
4356 super_expr = build_int_2 (0, 0);
4358 root_expr = add_objc_string (my_root_id, class_names);
4359 root_expr = build_c_cast (cast_type, root_expr); /* cast! */
4361 if (CLASS_PROTOCOL_LIST (implementation_template))
4363 generate_protocol_references
4364 (CLASS_PROTOCOL_LIST (implementation_template));
4365 protocol_decl = generate_protocol_list (implementation_template);
4370 /* static struct objc_class _OBJC_METACLASS_Foo = { ... }; */
4372 sc_spec = build_tree_list (NULL_TREE, ridpointers[(int) RID_STATIC]);
4373 decl_specs = tree_cons (NULL_TREE, objc_class_template, sc_spec);
4375 decl = start_decl (DECL_NAME (UOBJC_METACLASS_decl), decl_specs, 1,
4376 NULL_TREE, NULL_TREE);
4379 = build_shared_structure_initializer
4381 root_expr, super_expr, name_expr,
4382 build_int_2 ((TREE_INT_CST_LOW (TYPE_SIZE (objc_class_template))
4386 UOBJC_CLASS_METHODS_decl,
4387 UOBJC_CLASS_VARIABLES_decl,
4390 finish_decl (decl, initlist, NULL_TREE);
4392 /* static struct objc_class _OBJC_CLASS_Foo={ ... }; */
4394 decl = start_decl (DECL_NAME (UOBJC_CLASS_decl), decl_specs, 1,
4395 NULL_TREE, NULL_TREE);
4398 = build_shared_structure_initializer
4400 build_unary_op (ADDR_EXPR, UOBJC_METACLASS_decl, 0),
4401 super_expr, name_expr,
4404 (TYPE_SIZE (CLASS_STATIC_TEMPLATE (implementation_template)))
4408 UOBJC_INSTANCE_METHODS_decl,
4409 UOBJC_INSTANCE_VARIABLES_decl,
4412 finish_decl (decl, initlist, NULL_TREE);
4416 synth_id_with_class_suffix (preamble, ctxt)
4421 if (TREE_CODE (ctxt) == CLASS_IMPLEMENTATION_TYPE
4422 || TREE_CODE (ctxt) == CLASS_INTERFACE_TYPE)
4425 = IDENTIFIER_POINTER (CLASS_NAME (implementation_context));
4426 string = (char *) alloca (strlen (preamble) + strlen (class_name) + 3);
4427 sprintf (string, "%s_%s", preamble,
4428 IDENTIFIER_POINTER (CLASS_NAME (ctxt)));
4430 else if (TREE_CODE (ctxt) == CATEGORY_IMPLEMENTATION_TYPE
4431 || TREE_CODE (ctxt) == CATEGORY_INTERFACE_TYPE)
4433 /* We have a category. */
4435 = IDENTIFIER_POINTER (CLASS_NAME (implementation_context));
4436 char *class_super_name
4437 = IDENTIFIER_POINTER (CLASS_SUPER_NAME (implementation_context));
4438 string = (char *) alloca (strlen (preamble)
4439 + strlen (class_name)
4440 + strlen (class_super_name)
4442 sprintf (string, "%s_%s_%s", preamble, class_name, class_super_name);
4444 else if (TREE_CODE (ctxt) == PROTOCOL_INTERFACE_TYPE)
4446 char *protocol_name = IDENTIFIER_POINTER (PROTOCOL_NAME (ctxt));
4448 = (char *) alloca (strlen (preamble) + strlen (protocol_name) + 3);
4449 sprintf (string, "%s_%s", preamble, protocol_name);
4451 return get_identifier (string);
4455 is_objc_type_qualifier (node)
4458 return (TREE_CODE (node) == IDENTIFIER_NODE
4459 && (node == ridpointers [(int) RID_CONST]
4460 || node == ridpointers [(int) RID_VOLATILE]
4461 || node == ridpointers [(int) RID_IN]
4462 || node == ridpointers [(int) RID_OUT]
4463 || node == ridpointers [(int) RID_INOUT]
4464 || node == ridpointers [(int) RID_BYCOPY]
4465 || node == ridpointers [(int) RID_ONEWAY]));
4468 /* If type is empty or only type qualifiers are present, add default
4469 type of id (otherwise grokdeclarator will default to int). */
4472 adjust_type_for_id_default (type)
4475 tree declspecs, chain;
4478 return build_tree_list (build_tree_list (NULL_TREE, objc_object_reference),
4479 build1 (INDIRECT_REF, NULL_TREE, NULL_TREE));
4481 declspecs = TREE_PURPOSE (type);
4483 /* Determine if a typespec is present. */
4484 for (chain = declspecs;
4486 chain = TREE_CHAIN (chain))
4488 if (!is_objc_type_qualifier (TREE_VALUE (chain)))
4492 return build_tree_list (tree_cons (NULL_TREE, objc_object_reference,
4494 build1 (INDIRECT_REF, NULL_TREE, NULL_TREE));
4499 selector ':' '(' typename ')' identifier
4502 Transform an Objective-C keyword argument into
4503 the C equivalent parameter declarator.
4505 In: key_name, an "identifier_node" (optional).
4506 arg_type, a "tree_list" (optional).
4507 arg_name, an "identifier_node".
4509 Note: It would be really nice to strongly type the preceding
4510 arguments in the function prototype; however, then I
4511 could not use the "accessor" macros defined in "tree.h".
4513 Out: an instance of "keyword_decl". */
4516 build_keyword_decl (key_name, arg_type, arg_name)
4523 /* If no type is specified, default to "id". */
4524 arg_type = adjust_type_for_id_default (arg_type);
4526 keyword_decl = make_node (KEYWORD_DECL);
4528 TREE_TYPE (keyword_decl) = arg_type;
4529 KEYWORD_ARG_NAME (keyword_decl) = arg_name;
4530 KEYWORD_KEY_NAME (keyword_decl) = key_name;
4532 return keyword_decl;
4535 /* Given a chain of keyword_decl's, synthesize the full keyword selector. */
4538 build_keyword_selector (selector)
4542 tree key_chain, key_name;
4545 for (key_chain = selector; key_chain; key_chain = TREE_CHAIN (key_chain))
4547 if (TREE_CODE (selector) == KEYWORD_DECL)
4548 key_name = KEYWORD_KEY_NAME (key_chain);
4549 else if (TREE_CODE (selector) == TREE_LIST)
4550 key_name = TREE_PURPOSE (key_chain);
4553 len += IDENTIFIER_LENGTH (key_name) + 1;
4555 /* Just a ':' arg. */
4559 buf = (char *)alloca (len + 1);
4560 bzero (buf, len + 1);
4562 for (key_chain = selector; key_chain; key_chain = TREE_CHAIN (key_chain))
4564 if (TREE_CODE (selector) == KEYWORD_DECL)
4565 key_name = KEYWORD_KEY_NAME (key_chain);
4566 else if (TREE_CODE (selector) == TREE_LIST)
4567 key_name = TREE_PURPOSE (key_chain);
4570 strcat (buf, IDENTIFIER_POINTER (key_name));
4574 return get_identifier (buf);
4577 /* Used for declarations and definitions. */
4580 build_method_decl (code, ret_type, selector, add_args)
4581 enum tree_code code;
4588 /* If no type is specified, default to "id". */
4589 ret_type = adjust_type_for_id_default (ret_type);
4591 method_decl = make_node (code);
4592 TREE_TYPE (method_decl) = ret_type;
4594 /* If we have a keyword selector, create an identifier_node that
4595 represents the full selector name (`:' included)... */
4596 if (TREE_CODE (selector) == KEYWORD_DECL)
4598 METHOD_SEL_NAME (method_decl) = build_keyword_selector (selector);
4599 METHOD_SEL_ARGS (method_decl) = selector;
4600 METHOD_ADD_ARGS (method_decl) = add_args;
4604 METHOD_SEL_NAME (method_decl) = selector;
4605 METHOD_SEL_ARGS (method_decl) = NULL_TREE;
4606 METHOD_ADD_ARGS (method_decl) = NULL_TREE;
4612 #define METHOD_DEF 0
4613 #define METHOD_REF 1
4615 /* Used by `build_message_expr' and `comp_method_types'. Return an
4616 argument list for method METH. CONTEXT is either METHOD_DEF or
4617 METHOD_REF, saying whether we are trying to define a method or call
4618 one. SUPERFLAG says this is for a send to super; this makes a
4619 difference for the NeXT calling sequence in which the lookup and
4620 the method call are done together. */
4623 get_arg_type_list (meth, context, superflag)
4630 /* Receiver type. */
4631 if (flag_next_runtime && superflag)
4632 arglist = build_tree_list (NULL_TREE, super_type);
4633 else if (context == METHOD_DEF)
4634 arglist = build_tree_list (NULL_TREE, TREE_TYPE (self_decl));
4636 arglist = build_tree_list (NULL_TREE, id_type);
4638 /* Selector type - will eventually change to `int'. */
4639 chainon (arglist, build_tree_list (NULL_TREE, selector_type));
4641 /* Build a list of argument types. */
4642 for (akey = METHOD_SEL_ARGS (meth); akey; akey = TREE_CHAIN (akey))
4644 tree arg_decl = groktypename_in_parm_context (TREE_TYPE (akey));
4645 chainon (arglist, build_tree_list (NULL_TREE, TREE_TYPE (arg_decl)));
4648 if (METHOD_ADD_ARGS (meth) == (tree)1)
4649 /* We have a `, ...' immediately following the selector,
4650 finalize the arglist...simulate get_parm_info (0). */
4652 else if (METHOD_ADD_ARGS (meth))
4654 /* we have a variable length selector */
4655 tree add_arg_list = TREE_CHAIN (METHOD_ADD_ARGS (meth));
4656 chainon (arglist, add_arg_list);
4659 /* finalize the arglist...simulate get_parm_info (1) */
4660 chainon (arglist, build_tree_list (NULL_TREE, void_type_node));
4666 check_duplicates (hsh)
4669 tree meth = NULL_TREE;
4677 /* We have two methods with the same name and different types. */
4679 char type = (TREE_CODE (meth) == INSTANCE_METHOD_DECL) ? '-' : '+';
4681 warning ("multiple declarations for method `%s'",
4682 IDENTIFIER_POINTER (METHOD_SEL_NAME (meth)));
4684 warn_with_method ("using", type, meth);
4685 for (loop = hsh->list; loop; loop = loop->next)
4686 warn_with_method ("also found", type, loop->value);
4692 /* If RECEIVER is a class reference, return the identifier node for the
4693 referenced class. RECEIVER is created by get_class_reference, so we
4694 check the exact form created depending on which runtimes are used. */
4697 receiver_is_class_object (receiver)
4700 tree chain, exp, arg;
4701 if (flag_next_runtime)
4703 /* The receiver is a variable created by build_class_reference_decl. */
4704 if (TREE_CODE (receiver) == VAR_DECL
4705 && TREE_TYPE (receiver) == objc_class_type)
4706 /* Look up the identifier. */
4707 for (chain = cls_ref_chain; chain; chain = TREE_CHAIN (chain))
4708 if (TREE_PURPOSE (chain) == receiver)
4709 return TREE_VALUE (chain);
4713 /* The receiver is a function call that returns an id. Check if
4714 it is a call to objc_getClass, if so, pick up the class name. */
4715 if ((exp = TREE_OPERAND (receiver, 0))
4716 && TREE_CODE (exp) == ADDR_EXPR
4717 && (exp = TREE_OPERAND (exp, 0))
4718 && TREE_CODE (exp) == FUNCTION_DECL
4719 && exp == objc_get_class_decl
4720 /* we have a call to objc_getClass! */
4721 && (arg = TREE_OPERAND (receiver, 1))
4722 && TREE_CODE (arg) == TREE_LIST
4723 && (arg = TREE_VALUE (arg)))
4726 if (TREE_CODE (arg) == ADDR_EXPR
4727 && (arg = TREE_OPERAND (arg, 0))
4728 && TREE_CODE (arg) == STRING_CST)
4729 /* Finally, we have the class name. */
4730 return get_identifier (TREE_STRING_POINTER (arg));
4736 /* If we are currently building a message expr, this holds
4737 the identifier of the selector of the message. This is
4738 used when printing warnings about argument mismatches. */
4740 static tree building_objc_message_expr = 0;
4743 maybe_building_objc_message_expr ()
4745 return building_objc_message_expr;
4748 /* Construct an expression for sending a message.
4749 MESS has the object to send to in TREE_PURPOSE
4750 and the argument list (including selector) in TREE_VALUE.
4752 (*(<abstract_decl>(*)())_msg)(receiver, selTransTbl[n], ...);
4753 (*(<abstract_decl>(*)())_msgSuper)(receiver, selTransTbl[n], ...); */
4756 build_message_expr (mess)
4759 tree receiver = TREE_PURPOSE (mess);
4760 tree selector, self_object;
4761 tree rtype, sel_name;
4762 tree args = TREE_VALUE (mess);
4763 tree method_params = NULL_TREE;
4764 tree method_prototype = NULL_TREE;
4766 int statically_typed = 0, statically_allocated = 0;
4767 tree class_ident = 0;
4769 /* 1 if this is sending to the superclass. */
4772 if (!doing_objc_thang)
4775 if (TREE_CODE (receiver) == ERROR_MARK)
4776 return error_mark_node;
4778 /* Determine receiver type. */
4779 rtype = TREE_TYPE (receiver);
4780 super = IS_SUPER (rtype);
4784 if (TREE_STATIC_TEMPLATE (rtype))
4785 statically_allocated = 1;
4786 else if (TREE_CODE (rtype) == POINTER_TYPE
4787 && TREE_STATIC_TEMPLATE (TREE_TYPE (rtype)))
4788 statically_typed = 1;
4789 else if ((flag_next_runtime
4790 || (TREE_CODE (receiver) == CALL_EXPR && IS_ID (rtype)))
4791 && (class_ident = receiver_is_class_object (receiver)))
4793 else if (! IS_ID (rtype)
4794 /* Allow any type that matches objc_class_type. */
4795 && ! comptypes (rtype, objc_class_type))
4797 bzero (errbuf, BUFSIZE);
4798 warning ("invalid receiver type `%s'",
4799 gen_declaration (rtype, errbuf));
4802 if (statically_allocated)
4803 receiver = build_unary_op (ADDR_EXPR, receiver, 0);
4805 /* Don't evaluate the receiver twice. */
4806 receiver = save_expr (receiver);
4807 self_object = receiver;
4810 /* If sending to `super', use current self as the object. */
4811 self_object = self_decl;
4813 /* Obtain the full selector name. */
4815 if (TREE_CODE (args) == IDENTIFIER_NODE)
4816 /* A unary selector. */
4818 else if (TREE_CODE (args) == TREE_LIST)
4819 sel_name = build_keyword_selector (args);
4821 /* Build the parameter list to give to the method. */
4823 method_params = NULL_TREE;
4824 if (TREE_CODE (args) == TREE_LIST)
4826 tree chain = args, prev = NULL_TREE;
4828 /* We have a keyword selector--check for comma expressions. */
4831 tree element = TREE_VALUE (chain);
4833 /* We have a comma expression, must collapse... */
4834 if (TREE_CODE (element) == TREE_LIST)
4837 TREE_CHAIN (prev) = element;
4842 chain = TREE_CHAIN (chain);
4844 method_params = args;
4847 /* Determine operation return type. */
4849 if (IS_SUPER (rtype))
4853 if (CLASS_SUPER_NAME (implementation_template))
4856 = lookup_interface (CLASS_SUPER_NAME (implementation_template));
4858 if (TREE_CODE (method_context) == INSTANCE_METHOD_DECL)
4859 method_prototype = lookup_instance_method_static (iface, sel_name);
4861 method_prototype = lookup_class_method_static (iface, sel_name);
4863 if (iface && !method_prototype)
4864 warning ("`%s' does not respond to `%s'",
4865 IDENTIFIER_POINTER (CLASS_SUPER_NAME (implementation_template)),
4866 IDENTIFIER_POINTER (sel_name));
4870 error ("no super class declared in interface for `%s'",
4871 IDENTIFIER_POINTER (CLASS_NAME (implementation_template)));
4872 return error_mark_node;
4876 else if (statically_allocated)
4878 tree ctype = TREE_TYPE (rtype);
4879 tree iface = lookup_interface (TYPE_NAME (rtype));
4882 method_prototype = lookup_instance_method_static (iface, sel_name);
4884 if (! method_prototype && TYPE_PROTOCOL_LIST (ctype))
4886 = lookup_method_in_protocol_list (TYPE_PROTOCOL_LIST (ctype),
4889 if (!method_prototype)
4890 warning ("`%s' does not respond to `%s'",
4891 IDENTIFIER_POINTER (TYPE_NAME (rtype)),
4892 IDENTIFIER_POINTER (sel_name));
4894 else if (statically_typed)
4896 tree ctype = TREE_TYPE (rtype);
4898 /* `self' is now statically_typed. All methods should be visible
4899 within the context of the implementation. */
4900 if (implementation_context
4901 && CLASS_NAME (implementation_context) == TYPE_NAME (ctype))
4904 = lookup_instance_method_static (implementation_template,
4907 if (! method_prototype && TYPE_PROTOCOL_LIST (ctype))
4909 = lookup_method_in_protocol_list (TYPE_PROTOCOL_LIST (ctype),
4912 if (! method_prototype
4913 && implementation_template != implementation_context)
4914 /* The method is not published in the interface. Check
4917 = lookup_method (CLASS_NST_METHODS (implementation_context),
4924 if ((iface = lookup_interface (TYPE_NAME (ctype))))
4925 method_prototype = lookup_instance_method_static (iface, sel_name);
4927 if (! method_prototype)
4929 tree protocol_list = TYPE_PROTOCOL_LIST (ctype);
4932 = lookup_method_in_protocol_list (protocol_list,
4937 if (!method_prototype)
4938 warning ("`%s' does not respond to `%s'",
4939 IDENTIFIER_POINTER (TYPE_NAME (ctype)),
4940 IDENTIFIER_POINTER (sel_name));
4942 else if (class_ident)
4944 if (implementation_context
4945 && CLASS_NAME (implementation_context) == class_ident)
4948 = lookup_class_method_static (implementation_template, sel_name);
4950 if (!method_prototype
4951 && implementation_template != implementation_context)
4952 /* The method is not published in the interface. Check
4955 = lookup_method (CLASS_CLS_METHODS (implementation_context),
4962 if ((iface = lookup_interface (class_ident)))
4963 method_prototype = lookup_class_method_static (iface, sel_name);
4966 if (!method_prototype)
4968 warning ("cannot find class (factory) method.");
4969 warning ("return type for `%s' defaults to id",
4970 IDENTIFIER_POINTER (sel_name));
4973 else if (IS_PROTOCOL_QUALIFIED_ID (rtype))
4975 /* An anonymous object that has been qualified with a protocol. */
4977 tree protocol_list = TYPE_PROTOCOL_LIST (rtype);
4979 method_prototype = lookup_method_in_protocol_list (protocol_list,
4982 if (!method_prototype)
4986 warning ("method `%s' not implemented by protocol.",
4987 IDENTIFIER_POINTER (sel_name));
4989 /* Try and find the method signature in the global pools. */
4991 if (!(hsh = hash_lookup (nst_method_hash_list, sel_name)))
4992 hsh = hash_lookup (cls_method_hash_list, sel_name);
4994 if (!(method_prototype = check_duplicates (hsh)))
4995 warning ("return type defaults to id");
5002 /* We think we have an instance...loophole: extern id Object; */
5003 hsh = hash_lookup (nst_method_hash_list, sel_name);
5005 /* For various loopholes, like sending messages to self in a
5007 hsh = hash_lookup (cls_method_hash_list, sel_name);
5009 method_prototype = check_duplicates (hsh);
5010 if (!method_prototype)
5012 warning ("cannot find method.");
5013 warning ("return type for `%s' defaults to id",
5014 IDENTIFIER_POINTER (sel_name));
5018 /* Save the selector name for printing error messages. */
5019 building_objc_message_expr = sel_name;
5021 /* Build the parameters list for looking up the method.
5022 These are the object itself and the selector. */
5024 if (flag_typed_selectors)
5025 selector = build_typed_selector_reference (sel_name, method_prototype);
5027 selector = build_selector_reference (sel_name);
5029 retval = build_objc_method_call (super, method_prototype,
5030 receiver, self_object,
5031 selector, method_params);
5033 building_objc_message_expr = 0;
5038 /* Build a tree expression to send OBJECT the operation SELECTOR,
5039 looking up the method on object LOOKUP_OBJECT (often same as OBJECT),
5040 assuming the method has prototype METHOD_PROTOTYPE.
5041 (That is an INSTANCE_METHOD_DECL or CLASS_METHOD_DECL.)
5042 Use METHOD_PARAMS as list of args to pass to the method.
5043 If SUPER_FLAG is nonzero, we look up the superclass's method. */
5046 build_objc_method_call (super_flag, method_prototype, lookup_object, object,
5047 selector, method_params)
5049 tree method_prototype, lookup_object, object, selector, method_params;
5051 tree sender = (super_flag ? umsg_super_decl : umsg_decl);
5052 tree rcv_p = (super_flag
5053 ? build_pointer_type (xref_tag (RECORD_TYPE,
5054 get_identifier (TAG_SUPER)))
5057 if (flag_next_runtime)
5059 if (! method_prototype)
5061 method_params = tree_cons (NULL_TREE, lookup_object,
5062 tree_cons (NULL_TREE, selector,
5064 assemble_external (sender);
5065 return build_function_call (sender, method_params);
5069 /* This is a real kludge, but it is used only for the Next.
5070 Clobber the data type of SENDER temporarily to accept
5071 all the arguments for this operation, and to return
5072 whatever this operation returns. */
5073 tree arglist = NULL_TREE;
5076 /* Save the proper contents of SENDER's data type. */
5077 tree savarg = TYPE_ARG_TYPES (TREE_TYPE (sender));
5078 tree savret = TREE_TYPE (TREE_TYPE (sender));
5080 /* Install this method's argument types. */
5081 arglist = get_arg_type_list (method_prototype, METHOD_REF,
5083 TYPE_ARG_TYPES (TREE_TYPE (sender)) = arglist;
5085 /* Install this method's return type. */
5086 TREE_TYPE (TREE_TYPE (sender))
5087 = groktypename (TREE_TYPE (method_prototype));
5089 /* Call SENDER with all the parameters. This will do type
5090 checking using the arg types for this method. */
5091 method_params = tree_cons (NULL_TREE, lookup_object,
5092 tree_cons (NULL_TREE, selector,
5094 assemble_external (sender);
5095 retval = build_function_call (sender, method_params);
5097 /* Restore SENDER's return/argument types. */
5098 TYPE_ARG_TYPES (TREE_TYPE (sender)) = savarg;
5099 TREE_TYPE (TREE_TYPE (sender)) = savret;
5105 /* This is the portable way.
5106 First call the lookup function to get a pointer to the method,
5107 then cast the pointer, then call it with the method arguments. */
5110 /* Avoid trouble since we may evaluate each of these twice. */
5111 object = save_expr (object);
5112 selector = save_expr (selector);
5114 lookup_object = build_c_cast (rcv_p, lookup_object);
5116 assemble_external (sender);
5118 = build_function_call (sender,
5119 tree_cons (NULL_TREE, lookup_object,
5120 tree_cons (NULL_TREE, selector,
5123 /* If we have a method prototype, construct the data type this
5124 method needs, and cast what we got from SENDER into a pointer
5126 if (method_prototype)
5128 tree arglist = get_arg_type_list (method_prototype, METHOD_REF,
5130 tree valtype = groktypename (TREE_TYPE (method_prototype));
5131 tree fake_function_type = build_function_type (valtype, arglist);
5132 TREE_TYPE (method) = build_pointer_type (fake_function_type);
5136 = build_pointer_type (build_function_type (ptr_type_node, NULL_TREE));
5138 /* Pass the object to the method. */
5139 assemble_external (method);
5140 return build_function_call (method,
5141 tree_cons (NULL_TREE, object,
5142 tree_cons (NULL_TREE, selector,
5148 build_protocol_reference (p)
5151 tree decl, ident, ptype;
5153 push_obstacks_nochange ();
5154 end_temporary_allocation ();
5156 /* extern struct objc_protocol _OBJC_PROTOCOL_<mumble>; */
5158 ident = synth_id_with_class_suffix ("_OBJC_PROTOCOL", p);
5160 = groktypename (build_tree_list (build_tree_list (NULL_TREE,
5161 objc_protocol_template),
5164 if (IDENTIFIER_GLOBAL_VALUE (ident))
5165 decl = IDENTIFIER_GLOBAL_VALUE (ident); /* Set by pushdecl. */
5168 decl = build_decl (VAR_DECL, ident, ptype);
5169 DECL_EXTERNAL (decl) = 1;
5170 TREE_PUBLIC (decl) = 1;
5171 TREE_USED (decl) = 1;
5172 DECL_ARTIFICIAL (decl) = 1;
5174 make_decl_rtl (decl, 0, 1);
5175 pushdecl_top_level (decl);
5178 PROTOCOL_FORWARD_DECL (p) = decl;
5183 build_protocol_expr (protoname)
5189 if (!doing_objc_thang)
5192 p = lookup_protocol (protoname);
5196 error ("Cannot find protocol declaration for `%s'",
5197 IDENTIFIER_POINTER (protoname));
5198 return error_mark_node;
5201 if (!PROTOCOL_FORWARD_DECL (p))
5202 build_protocol_reference (p);
5204 expr = build_unary_op (ADDR_EXPR, PROTOCOL_FORWARD_DECL (p), 0);
5206 TREE_TYPE (expr) = protocol_type;
5212 build_selector_expr (selnamelist)
5217 if (!doing_objc_thang)
5220 /* Obtain the full selector name. */
5221 if (TREE_CODE (selnamelist) == IDENTIFIER_NODE)
5222 /* A unary selector. */
5223 selname = selnamelist;
5224 else if (TREE_CODE (selnamelist) == TREE_LIST)
5225 selname = build_keyword_selector (selnamelist);
5227 if (flag_typed_selectors)
5228 return build_typed_selector_reference (selname, 0);
5230 return build_selector_reference (selname);
5234 build_encode_expr (type)
5240 if (!doing_objc_thang)
5243 encode_type (type, obstack_object_size (&util_obstack),
5244 OBJC_ENCODE_INLINE_DEFS);
5245 obstack_1grow (&util_obstack, 0); /* null terminate string */
5246 string = obstack_finish (&util_obstack);
5248 /* Synthesize a string that represents the encoded struct/union. */
5249 result = my_build_string (strlen (string) + 1, string);
5250 obstack_free (&util_obstack, util_firstobj);
5255 build_ivar_reference (id)
5258 if (TREE_CODE (method_context) == CLASS_METHOD_DECL)
5260 /* Historically, a class method that produced objects (factory
5261 method) would assign `self' to the instance that it
5262 allocated. This would effectively turn the class method into
5263 an instance method. Following this assignment, the instance
5264 variables could be accessed. That practice, while safe,
5265 violates the simple rule that a class method should not refer
5266 to an instance variable. It's better to catch the cases
5267 where this is done unknowingly than to support the above
5269 warning ("instance variable `%s' accessed in class method",
5270 IDENTIFIER_POINTER (id));
5271 TREE_TYPE (self_decl) = instance_type; /* cast */
5274 return build_component_ref (build_indirect_ref (self_decl, "->"), id);
5277 #define HASH_ALLOC_LIST_SIZE 170
5278 #define ATTR_ALLOC_LIST_SIZE 170
5279 #define SIZEHASHTABLE 257
5282 #define HASHFUNCTION(key) ((HOST_WIDE_INT) key & 0x7fffffff)
5287 nst_method_hash_list = (hash *)xmalloc (SIZEHASHTABLE * sizeof (hash));
5288 cls_method_hash_list = (hash *)xmalloc (SIZEHASHTABLE * sizeof (hash));
5290 if (!nst_method_hash_list || !cls_method_hash_list)
5291 perror ("unable to allocate space in objc-tree.c");
5296 for (i = 0; i < SIZEHASHTABLE; i++)
5298 nst_method_hash_list[i] = 0;
5299 cls_method_hash_list[i] = 0;
5305 hash_enter (hashlist, method)
5309 static hash hash_alloc_list = 0;
5310 static int hash_alloc_index = 0;
5312 int slot = HASHFUNCTION (METHOD_SEL_NAME (method)) % SIZEHASHTABLE;
5314 if (! hash_alloc_list || hash_alloc_index >= HASH_ALLOC_LIST_SIZE)
5316 hash_alloc_index = 0;
5317 hash_alloc_list = (hash) xmalloc (sizeof (struct hashed_entry)
5318 * HASH_ALLOC_LIST_SIZE);
5319 if (! hash_alloc_list)
5320 perror ("unable to allocate in objc-tree.c");
5322 obj = &hash_alloc_list[hash_alloc_index++];
5324 obj->next = hashlist[slot];
5327 hashlist[slot] = obj; /* append to front */
5331 hash_lookup (hashlist, sel_name)
5337 target = hashlist[HASHFUNCTION (sel_name) % SIZEHASHTABLE];
5341 if (sel_name == METHOD_SEL_NAME (target->key))
5344 target = target->next;
5350 hash_add_attr (entry, value)
5354 static attr attr_alloc_list = 0;
5355 static int attr_alloc_index = 0;
5358 if (! attr_alloc_list || attr_alloc_index >= ATTR_ALLOC_LIST_SIZE)
5360 attr_alloc_index = 0;
5361 attr_alloc_list = (attr) xmalloc (sizeof (struct hashed_attribute)
5362 * ATTR_ALLOC_LIST_SIZE);
5363 if (! attr_alloc_list)
5364 perror ("unable to allocate in objc-tree.c");
5366 obj = &attr_alloc_list[attr_alloc_index++];
5367 obj->next = entry->list;
5370 entry->list = obj; /* append to front */
5374 lookup_method (mchain, method)
5380 if (TREE_CODE (method) == IDENTIFIER_NODE)
5383 key = METHOD_SEL_NAME (method);
5387 if (METHOD_SEL_NAME (mchain) == key)
5389 mchain = TREE_CHAIN (mchain);
5395 lookup_instance_method_static (interface, ident)
5399 tree inter = interface;
5400 tree chain = CLASS_NST_METHODS (inter);
5401 tree meth = NULL_TREE;
5405 if ((meth = lookup_method (chain, ident)))
5408 if (CLASS_CATEGORY_LIST (inter))
5410 tree category = CLASS_CATEGORY_LIST (inter);
5411 chain = CLASS_NST_METHODS (category);
5415 if ((meth = lookup_method (chain, ident)))
5418 /* Check for instance methods in protocols in categories. */
5419 if (CLASS_PROTOCOL_LIST (category))
5421 if ((meth = (lookup_method_in_protocol_list
5422 (CLASS_PROTOCOL_LIST (category), ident, 0))))
5426 if ((category = CLASS_CATEGORY_LIST (category)))
5427 chain = CLASS_NST_METHODS (category);
5432 if (CLASS_PROTOCOL_LIST (inter))
5434 if ((meth = (lookup_method_in_protocol_list
5435 (CLASS_PROTOCOL_LIST (inter), ident, 0))))
5439 if ((inter = lookup_interface (CLASS_SUPER_NAME (inter))))
5440 chain = CLASS_NST_METHODS (inter);
5448 lookup_class_method_static (interface, ident)
5452 tree inter = interface;
5453 tree chain = CLASS_CLS_METHODS (inter);
5454 tree meth = NULL_TREE;
5455 tree root_inter = NULL_TREE;
5459 if ((meth = lookup_method (chain, ident)))
5462 if (CLASS_CATEGORY_LIST (inter))
5464 tree category = CLASS_CATEGORY_LIST (inter);
5465 chain = CLASS_CLS_METHODS (category);
5469 if ((meth = lookup_method (chain, ident)))
5472 /* Check for class methods in protocols in categories. */
5473 if (CLASS_PROTOCOL_LIST (category))
5475 if ((meth = (lookup_method_in_protocol_list
5476 (CLASS_PROTOCOL_LIST (category), ident, 1))))
5480 if ((category = CLASS_CATEGORY_LIST (category)))
5481 chain = CLASS_CLS_METHODS (category);
5486 /* Check for class methods in protocols. */
5487 if (CLASS_PROTOCOL_LIST (inter))
5489 if ((meth = (lookup_method_in_protocol_list
5490 (CLASS_PROTOCOL_LIST (inter), ident, 1))))
5495 if ((inter = lookup_interface (CLASS_SUPER_NAME (inter))))
5496 chain = CLASS_CLS_METHODS (inter);
5500 /* Simulate wrap around. */
5501 return lookup_instance_method_static (root_inter, ident);
5505 add_class_method (class, method)
5512 /* We will have allocated the method parameter declarations on the
5513 maybepermanent_obstack. Need to make sure they stick around! */
5516 if (!(mth = lookup_method (CLASS_CLS_METHODS (class), method)))
5518 /* put method on list in reverse order */
5519 TREE_CHAIN (method) = CLASS_CLS_METHODS (class);
5520 CLASS_CLS_METHODS (class) = method;
5524 if (TREE_CODE (class) == CLASS_IMPLEMENTATION_TYPE)
5525 error ("duplicate definition of class method `%s'.",
5526 IDENTIFIER_POINTER (METHOD_SEL_NAME (mth)));
5529 /* Check types; if different, complain. */
5530 if (!comp_proto_with_proto (method, mth))
5531 error ("duplicate declaration of class method `%s'.",
5532 IDENTIFIER_POINTER (METHOD_SEL_NAME (mth)));
5536 if (!(hsh = hash_lookup (cls_method_hash_list, METHOD_SEL_NAME (method))))
5538 /* Install on a global chain. */
5539 hash_enter (cls_method_hash_list, method);
5543 /* Check types; if different, add to a list. */
5544 if (!comp_proto_with_proto (method, hsh->key))
5545 hash_add_attr (hsh, method);
5551 add_instance_method (class, method)
5558 /* We will have allocated the method parameter declarations on the
5559 maybepermanent_obstack. Need to make sure they stick around! */
5562 if (!(mth = lookup_method (CLASS_NST_METHODS (class), method)))
5564 /* Put method on list in reverse order. */
5565 TREE_CHAIN (method) = CLASS_NST_METHODS (class);
5566 CLASS_NST_METHODS (class) = method;
5570 if (TREE_CODE (class) == CLASS_IMPLEMENTATION_TYPE)
5571 error ("duplicate definition of instance method `%s'.",
5572 IDENTIFIER_POINTER (METHOD_SEL_NAME (mth)));
5575 /* Check types; if different, complain. */
5576 if (!comp_proto_with_proto (method, mth))
5577 error ("duplicate declaration of instance method `%s'.",
5578 IDENTIFIER_POINTER (METHOD_SEL_NAME (mth)));
5582 if (!(hsh = hash_lookup (nst_method_hash_list, METHOD_SEL_NAME (method))))
5584 /* Install on a global chain. */
5585 hash_enter (nst_method_hash_list, method);
5589 /* Check types; if different, add to a list. */
5590 if (!comp_proto_with_proto (method, hsh->key))
5591 hash_add_attr (hsh, method);
5600 /* Put interfaces on list in reverse order. */
5601 TREE_CHAIN (class) = interface_chain;
5602 interface_chain = class;
5603 return interface_chain;
5607 add_category (class, category)
5611 /* Put categories on list in reverse order. */
5612 tree cat = CLASS_CATEGORY_LIST (class);
5616 if (CLASS_SUPER_NAME (cat) == CLASS_SUPER_NAME (category))
5617 warning ("duplicate interface declaration for category `%s(%s)'",
5618 IDENTIFIER_POINTER (CLASS_NAME (class)),
5619 IDENTIFIER_POINTER (CLASS_SUPER_NAME (category)));
5620 cat = CLASS_CATEGORY_LIST (cat);
5623 CLASS_CATEGORY_LIST (category) = CLASS_CATEGORY_LIST (class);
5624 CLASS_CATEGORY_LIST (class) = category;
5627 /* Called after parsing each instance variable declaration. Necessary to
5628 preserve typedefs and implement public/private...
5630 PUBLIC is 1 for public, 0 for protected, and 2 for private. */
5633 add_instance_variable (class, public, declarator, declspecs, width)
5640 tree field_decl, raw_decl;
5642 raw_decl = build_tree_list (declspecs, declarator);
5644 if (CLASS_RAW_IVARS (class))
5645 chainon (CLASS_RAW_IVARS (class), raw_decl);
5647 CLASS_RAW_IVARS (class) = raw_decl;
5649 field_decl = grokfield (input_filename, lineno,
5650 declarator, declspecs, width);
5652 /* Overload the public attribute, it is not used for FIELD_DECLs. */
5656 TREE_PUBLIC (field_decl) = 0;
5657 TREE_PRIVATE (field_decl) = 0;
5658 TREE_PROTECTED (field_decl) = 1;
5662 TREE_PUBLIC (field_decl) = 1;
5663 TREE_PRIVATE (field_decl) = 0;
5664 TREE_PROTECTED (field_decl) = 0;
5668 TREE_PUBLIC (field_decl) = 0;
5669 TREE_PRIVATE (field_decl) = 1;
5670 TREE_PROTECTED (field_decl) = 0;
5675 if (CLASS_IVARS (class))
5676 chainon (CLASS_IVARS (class), field_decl);
5678 CLASS_IVARS (class) = field_decl;
5684 is_ivar (decl_chain, ident)
5688 for ( ; decl_chain; decl_chain = TREE_CHAIN (decl_chain))
5689 if (DECL_NAME (decl_chain) == ident)
5694 /* True if the ivar is private and we are not in its implementation. */
5700 if (TREE_PRIVATE (decl)
5701 && ! is_ivar (CLASS_IVARS (implementation_template), DECL_NAME (decl)))
5703 error ("instance variable `%s' is declared private",
5704 IDENTIFIER_POINTER (DECL_NAME (decl)));
5711 /* We have an instance variable reference;, check to see if it is public. */
5714 is_public (expr, identifier)
5718 tree basetype = TREE_TYPE (expr);
5719 enum tree_code code = TREE_CODE (basetype);
5722 if (code == RECORD_TYPE)
5724 if (TREE_STATIC_TEMPLATE (basetype))
5726 if (!lookup_interface (TYPE_NAME (basetype)))
5728 error ("Cannot find interface declaration for `%s'",
5729 IDENTIFIER_POINTER (TYPE_NAME (basetype)));
5733 if ((decl = is_ivar (TYPE_FIELDS (basetype), identifier)))
5735 if (TREE_PUBLIC (decl))
5738 /* Important difference between the Stepstone translator:
5739 all instance variables should be public within the context
5740 of the implementation. */
5741 if (implementation_context
5742 && (((TREE_CODE (implementation_context)
5743 == CLASS_IMPLEMENTATION_TYPE)
5744 || (TREE_CODE (implementation_context)
5745 == CATEGORY_IMPLEMENTATION_TYPE))
5746 && (CLASS_NAME (implementation_context)
5747 == TYPE_NAME (basetype))))
5748 return ! is_private (decl);
5750 error ("instance variable `%s' is declared %s",
5751 IDENTIFIER_POINTER (identifier),
5752 TREE_PRIVATE (decl) ? "private" : "protected");
5757 else if (implementation_context && (basetype == objc_object_reference))
5759 TREE_TYPE (expr) = uprivate_record;
5760 warning ("static access to object of type `id'");
5767 /* Implement @defs (<classname>) within struct bodies. */
5770 get_class_ivars (interface)
5773 if (!doing_objc_thang)
5776 return build_ivar_chain (interface, 1);
5779 /* Make sure all entries in CHAIN are also in LIST. */
5782 check_methods (chain, list, mtype)
5791 if (!lookup_method (list, chain))
5795 if (TREE_CODE (implementation_context)
5796 == CLASS_IMPLEMENTATION_TYPE)
5797 warning ("incomplete implementation of class `%s'",
5798 IDENTIFIER_POINTER (CLASS_NAME (implementation_context)));
5799 else if (TREE_CODE (implementation_context)
5800 == CATEGORY_IMPLEMENTATION_TYPE)
5801 warning ("incomplete implementation of category `%s'",
5802 IDENTIFIER_POINTER (CLASS_SUPER_NAME (implementation_context)));
5806 warning ("method definition for `%c%s' not found",
5807 mtype, IDENTIFIER_POINTER (METHOD_SEL_NAME (chain)));
5810 chain = TREE_CHAIN (chain);
5817 conforms_to_protocol (class, protocol)
5823 tree p = CLASS_PROTOCOL_LIST (class);
5825 while (p && TREE_VALUE (p) != TREE_VALUE (protocol))
5830 tree super = (CLASS_SUPER_NAME (class)
5831 ? lookup_interface (CLASS_SUPER_NAME (class))
5833 int tmp = super ? conforms_to_protocol (super, protocol) : 0;
5838 protocol = TREE_CHAIN (protocol);
5844 /* Make sure all methods in CHAIN are accessible as MTYPE methods in
5845 CONTEXT. This is one of two mechanisms to check protocol integrity. */
5848 check_methods_accessible (chain, context, mtype)
5855 tree base_context = context;
5859 context = base_context;
5863 list = CLASS_CLS_METHODS (context);
5865 list = CLASS_NST_METHODS (context);
5867 if (lookup_method (list, chain))
5870 else if (TREE_CODE (context) == CLASS_IMPLEMENTATION_TYPE
5871 || TREE_CODE (context) == CLASS_INTERFACE_TYPE)
5872 context = (CLASS_SUPER_NAME (context)
5873 ? lookup_interface (CLASS_SUPER_NAME (context))
5876 else if (TREE_CODE (context) == CATEGORY_IMPLEMENTATION_TYPE
5877 || TREE_CODE (context) == CATEGORY_INTERFACE_TYPE)
5878 context = (CLASS_NAME (context)
5879 ? lookup_interface (CLASS_NAME (context))
5885 if (context == NULL_TREE)
5889 if (TREE_CODE (implementation_context)
5890 == CLASS_IMPLEMENTATION_TYPE)
5891 warning ("incomplete implementation of class `%s'",
5893 (CLASS_NAME (implementation_context)));
5894 else if (TREE_CODE (implementation_context)
5895 == CATEGORY_IMPLEMENTATION_TYPE)
5896 warning ("incomplete implementation of category `%s'",
5898 (CLASS_SUPER_NAME (implementation_context)));
5901 warning ("method definition for `%c%s' not found",
5902 mtype, IDENTIFIER_POINTER (METHOD_SEL_NAME (chain)));
5905 chain = TREE_CHAIN (chain); /* next method... */
5911 check_protocols (proto_list, type, name)
5916 for ( ; proto_list; proto_list = TREE_CHAIN (proto_list))
5918 tree p = TREE_VALUE (proto_list);
5920 if (TREE_CODE (p) == PROTOCOL_INTERFACE_TYPE)
5924 /* Ensure that all protocols have bodies. */
5925 if (flag_warn_protocol) {
5926 f1 = check_methods (PROTOCOL_CLS_METHODS (p),
5927 CLASS_CLS_METHODS (implementation_context),
5929 f2 = check_methods (PROTOCOL_NST_METHODS (p),
5930 CLASS_NST_METHODS (implementation_context),
5933 f1 = check_methods_accessible (PROTOCOL_CLS_METHODS (p),
5934 implementation_context,
5936 f2 = check_methods_accessible (PROTOCOL_NST_METHODS (p),
5937 implementation_context,
5942 warning ("%s `%s' does not fully implement the `%s' protocol",
5943 type, name, IDENTIFIER_POINTER (PROTOCOL_NAME (p)));
5947 ; /* An identifier if we could not find a protocol. */
5949 /* Check protocols recursively. */
5950 if (PROTOCOL_LIST (p))
5953 = lookup_interface (CLASS_SUPER_NAME (implementation_template));
5954 if (! conforms_to_protocol (super_class, PROTOCOL_LIST (p)))
5955 check_protocols (PROTOCOL_LIST (p), type, name);
5960 /* Make sure that the class CLASS_NAME is defined
5961 CODE says which kind of thing CLASS_NAME ought to be.
5962 It can be CLASS_INTERFACE_TYPE, CLASS_IMPLEMENTATION_TYPE,
5963 CATEGORY_INTERFACE_TYPE, or CATEGORY_IMPLEMENTATION_TYPE.
5965 If CODE is CLASS_INTERFACE_TYPE, we also do a push_obstacks_nochange
5966 whose matching pop is in continue_class. */
5969 start_class (code, class_name, super_name, protocol_list)
5970 enum tree_code code;
5977 if (code == CLASS_INTERFACE_TYPE)
5979 push_obstacks_nochange ();
5980 end_temporary_allocation ();
5983 if (!doing_objc_thang)
5986 class = make_node (code);
5987 TYPE_BINFO (class) = make_tree_vec (5);
5989 CLASS_NAME (class) = class_name;
5990 CLASS_SUPER_NAME (class) = super_name;
5991 CLASS_CLS_METHODS (class) = NULL_TREE;
5993 if (! is_class_name (class_name) && (decl = lookup_name (class_name)))
5995 error ("`%s' redeclared as different kind of symbol",
5996 IDENTIFIER_POINTER (class_name));
5997 error_with_decl (decl, "previous declaration of `%s'");
6000 if (code == CLASS_IMPLEMENTATION_TYPE)
6003 static tree implemented_classes = 0;
6004 tree chain = implemented_classes;
6005 for (chain = implemented_classes; chain; chain = TREE_CHAIN (chain))
6006 if (TREE_VALUE (chain) == class_name)
6008 error ("reimplementation of class `%s'",
6009 IDENTIFIER_POINTER (class_name));
6010 return error_mark_node;
6012 implemented_classes = perm_tree_cons (NULL_TREE, class_name,
6013 implemented_classes);
6016 /* Pre-build the following entities - for speed/convenience. */
6018 self_id = get_identifier ("self");
6020 ucmd_id = get_identifier ("_cmd");
6023 = build_tree_list (get_identifier ("__unused__"), NULL_TREE);
6024 if (!objc_super_template)
6025 objc_super_template = build_super_template ();
6027 /* Reset for multiple classes per file. */
6030 implementation_context = class;
6032 /* Lookup the interface for this implementation. */
6034 if (!(implementation_template = lookup_interface (class_name)))
6036 warning ("Cannot find interface declaration for `%s'",
6037 IDENTIFIER_POINTER (class_name));
6038 add_class (implementation_template = implementation_context);
6041 /* If a super class has been specified in the implementation,
6042 insure it conforms to the one specified in the interface. */
6045 && (super_name != CLASS_SUPER_NAME (implementation_template)))
6047 tree previous_name = CLASS_SUPER_NAME (implementation_template);
6048 char *name = previous_name ? IDENTIFIER_POINTER (previous_name) : "";
6049 error ("conflicting super class name `%s'",
6050 IDENTIFIER_POINTER (super_name));
6051 error ("previous declaration of `%s'", name);
6054 else if (! super_name)
6056 CLASS_SUPER_NAME (implementation_context)
6057 = CLASS_SUPER_NAME (implementation_template);
6061 else if (code == CLASS_INTERFACE_TYPE)
6063 if (lookup_interface (class_name))
6064 warning ("duplicate interface declaration for class `%s'",
6065 IDENTIFIER_POINTER (class_name));
6070 CLASS_PROTOCOL_LIST (class)
6071 = lookup_and_install_protocols (protocol_list);
6074 else if (code == CATEGORY_INTERFACE_TYPE)
6076 tree class_category_is_assoc_with;
6078 /* For a category, class_name is really the name of the class that
6079 the following set of methods will be associated with. We must
6080 find the interface so that can derive the objects template. */
6082 if (!(class_category_is_assoc_with = lookup_interface (class_name)))
6084 error ("Cannot find interface declaration for `%s'",
6085 IDENTIFIER_POINTER (class_name));
6086 exit (FATAL_EXIT_CODE);
6089 add_category (class_category_is_assoc_with, class);
6092 CLASS_PROTOCOL_LIST (class)
6093 = lookup_and_install_protocols (protocol_list);
6096 else if (code == CATEGORY_IMPLEMENTATION_TYPE)
6098 /* Pre-build the following entities for speed/convenience. */
6100 self_id = get_identifier ("self");
6102 ucmd_id = get_identifier ("_cmd");
6105 = build_tree_list (get_identifier ("__unused__"), NULL_TREE);
6106 if (!objc_super_template)
6107 objc_super_template = build_super_template ();
6109 /* Reset for multiple classes per file. */
6112 implementation_context = class;
6114 /* For a category, class_name is really the name of the class that
6115 the following set of methods will be associated with. We must
6116 find the interface so that can derive the objects template. */
6118 if (!(implementation_template = lookup_interface (class_name)))
6120 error ("Cannot find interface declaration for `%s'",
6121 IDENTIFIER_POINTER (class_name));
6122 exit (FATAL_EXIT_CODE);
6129 continue_class (class)
6132 if (TREE_CODE (class) == CLASS_IMPLEMENTATION_TYPE
6133 || TREE_CODE (class) == CATEGORY_IMPLEMENTATION_TYPE)
6135 struct imp_entry *imp_entry;
6138 /* Check consistency of the instance variables. */
6140 if (CLASS_IVARS (class))
6141 check_ivars (implementation_template, class);
6143 /* code generation */
6145 ivar_context = build_private_template (implementation_template);
6147 if (!objc_class_template)
6148 build_class_template ();
6151 = (struct imp_entry *) xmalloc (sizeof (struct imp_entry))))
6152 perror ("unable to allocate in objc-tree.c");
6154 imp_entry->next = imp_list;
6155 imp_entry->imp_context = class;
6156 imp_entry->imp_template = implementation_template;
6158 synth_forward_declarations ();
6159 imp_entry->class_decl = UOBJC_CLASS_decl;
6160 imp_entry->meta_decl = UOBJC_METACLASS_decl;
6162 /* Append to front and increment count. */
6163 imp_list = imp_entry;
6164 if (TREE_CODE (class) == CLASS_IMPLEMENTATION_TYPE)
6169 return ivar_context;
6172 else if (TREE_CODE (class) == CLASS_INTERFACE_TYPE)
6174 tree record = xref_tag (RECORD_TYPE, CLASS_NAME (class));
6176 if (!TYPE_FIELDS (record))
6178 finish_struct (record, build_ivar_chain (class, 0), NULL_TREE);
6179 CLASS_STATIC_TEMPLATE (class) = record;
6181 /* Mark this record as a class template for static typing. */
6182 TREE_STATIC_TEMPLATE (record) = 1;
6189 return error_mark_node;
6192 /* This is called once we see the "@end" in an interface/implementation. */
6195 finish_class (class)
6198 if (TREE_CODE (class) == CLASS_IMPLEMENTATION_TYPE)
6200 /* All code generation is done in finish_objc. */
6202 if (implementation_template != implementation_context)
6204 /* Ensure that all method listed in the interface contain bodies. */
6205 check_methods (CLASS_CLS_METHODS (implementation_template),
6206 CLASS_CLS_METHODS (implementation_context), '+');
6207 check_methods (CLASS_NST_METHODS (implementation_template),
6208 CLASS_NST_METHODS (implementation_context), '-');
6210 if (CLASS_PROTOCOL_LIST (implementation_template))
6211 check_protocols (CLASS_PROTOCOL_LIST (implementation_template),
6213 IDENTIFIER_POINTER (CLASS_NAME (implementation_context)));
6217 else if (TREE_CODE (class) == CATEGORY_IMPLEMENTATION_TYPE)
6219 tree category = CLASS_CATEGORY_LIST (implementation_template);
6221 /* Find the category interface from the class it is associated with. */
6224 if (CLASS_SUPER_NAME (class) == CLASS_SUPER_NAME (category))
6226 category = CLASS_CATEGORY_LIST (category);
6231 /* Ensure all method listed in the interface contain bodies. */
6232 check_methods (CLASS_CLS_METHODS (category),
6233 CLASS_CLS_METHODS (implementation_context), '+');
6234 check_methods (CLASS_NST_METHODS (category),
6235 CLASS_NST_METHODS (implementation_context), '-');
6237 if (CLASS_PROTOCOL_LIST (category))
6238 check_protocols (CLASS_PROTOCOL_LIST (category),
6240 IDENTIFIER_POINTER (CLASS_SUPER_NAME (implementation_context)));
6244 else if (TREE_CODE (class) == CLASS_INTERFACE_TYPE)
6247 char *class_name = IDENTIFIER_POINTER (CLASS_NAME (class));
6248 char *string = (char *) alloca (strlen (class_name) + 3);
6250 /* extern struct objc_object *_<my_name>; */
6252 sprintf (string, "_%s", class_name);
6254 decl_specs = build_tree_list (NULL_TREE, ridpointers[(int) RID_EXTERN]);
6255 decl_specs = tree_cons (NULL_TREE, objc_object_reference, decl_specs);
6256 define_decl (build1 (INDIRECT_REF, NULL_TREE, get_identifier (string)),
6262 add_protocol (protocol)
6265 /* Put protocol on list in reverse order. */
6266 TREE_CHAIN (protocol) = protocol_chain;
6267 protocol_chain = protocol;
6268 return protocol_chain;
6272 lookup_protocol (ident)
6277 for (chain = protocol_chain; chain; chain = TREE_CHAIN (chain))
6279 if (ident == PROTOCOL_NAME (chain))
6287 start_protocol (code, name, list)
6288 enum tree_code code;
6294 if (!doing_objc_thang)
6297 /* This is as good a place as any. Need to invoke push_tag_toplevel. */
6298 if (!objc_protocol_template)
6299 objc_protocol_template = build_protocol_template ();
6301 protocol = make_node (code);
6302 TYPE_BINFO (protocol) = make_tree_vec (2);
6304 PROTOCOL_NAME (protocol) = name;
6305 PROTOCOL_LIST (protocol) = list;
6307 lookup_and_install_protocols (list);
6309 if (lookup_protocol (name))
6310 warning ("duplicate declaration for protocol `%s'",
6311 IDENTIFIER_POINTER (name));
6313 add_protocol (protocol);
6315 PROTOCOL_FORWARD_DECL (protocol) = NULL_TREE;
6321 finish_protocol (protocol)
6327 /* "Encode" a data type into a string, which grows in util_obstack.
6328 ??? What is the FORMAT? Someone please document this! */
6331 encode_type_qualifiers (declspecs)
6336 for (spec = declspecs; spec; spec = TREE_CHAIN (spec))
6338 if (ridpointers[(int) RID_CONST] == TREE_VALUE (spec))
6339 obstack_1grow (&util_obstack, 'r');
6340 else if (ridpointers[(int) RID_IN] == TREE_VALUE (spec))
6341 obstack_1grow (&util_obstack, 'n');
6342 else if (ridpointers[(int) RID_INOUT] == TREE_VALUE (spec))
6343 obstack_1grow (&util_obstack, 'N');
6344 else if (ridpointers[(int) RID_OUT] == TREE_VALUE (spec))
6345 obstack_1grow (&util_obstack, 'o');
6346 else if (ridpointers[(int) RID_BYCOPY] == TREE_VALUE (spec))
6347 obstack_1grow (&util_obstack, 'O');
6348 else if (ridpointers[(int) RID_ONEWAY] == TREE_VALUE (spec))
6349 obstack_1grow (&util_obstack, 'V');
6353 /* Encode a pointer type. */
6356 encode_pointer (type, curtype, format)
6361 tree pointer_to = TREE_TYPE (type);
6363 if (TREE_CODE (pointer_to) == RECORD_TYPE)
6365 if (TYPE_NAME (pointer_to)
6366 && TREE_CODE (TYPE_NAME (pointer_to)) == IDENTIFIER_NODE)
6368 char *name = IDENTIFIER_POINTER (TYPE_NAME (pointer_to));
6370 if (strcmp (name, TAG_OBJECT) == 0) /* '@' */
6372 obstack_1grow (&util_obstack, '@');
6375 else if (TREE_STATIC_TEMPLATE (pointer_to))
6377 if (generating_instance_variables)
6379 obstack_1grow (&util_obstack, '@');
6380 obstack_1grow (&util_obstack, '"');
6381 obstack_grow (&util_obstack, name, strlen (name));
6382 obstack_1grow (&util_obstack, '"');
6387 obstack_1grow (&util_obstack, '@');
6391 else if (strcmp (name, TAG_CLASS) == 0) /* '#' */
6393 obstack_1grow (&util_obstack, '#');
6396 #ifndef OBJC_INT_SELECTORS
6397 else if (strcmp (name, TAG_SELECTOR) == 0) /* ':' */
6399 obstack_1grow (&util_obstack, ':');
6402 #endif /* OBJC_INT_SELECTORS */
6405 else if (TREE_CODE (pointer_to) == INTEGER_TYPE
6406 && TYPE_MODE (pointer_to) == QImode)
6408 obstack_1grow (&util_obstack, '*');
6412 /* We have a type that does not get special treatment. */
6414 /* NeXT extension */
6415 obstack_1grow (&util_obstack, '^');
6416 encode_type (pointer_to, curtype, format);
6420 encode_array (type, curtype, format)
6425 tree an_int_cst = TYPE_SIZE (type);
6426 tree array_of = TREE_TYPE (type);
6429 /* An incomplete array is treated like a pointer. */
6430 if (an_int_cst == NULL)
6432 encode_pointer (type, curtype, format);
6436 sprintf (buffer, "[%d",
6437 (TREE_INT_CST_LOW (an_int_cst)
6438 / TREE_INT_CST_LOW (TYPE_SIZE (array_of))));
6440 obstack_grow (&util_obstack, buffer, strlen (buffer));
6441 encode_type (array_of, curtype, format);
6442 obstack_1grow (&util_obstack, ']');
6447 encode_aggregate_within (type, curtype, format, left, right)
6454 if (obstack_object_size (&util_obstack) > 0
6455 && *(obstack_next_free (&util_obstack) - 1) == '^')
6457 tree name = TYPE_NAME (type);
6459 /* we have a reference; this is a NeXT extension. */
6461 if (obstack_object_size (&util_obstack) - curtype == 1
6462 && format == OBJC_ENCODE_INLINE_DEFS)
6464 /* Output format of struct for first level only. */
6465 tree fields = TYPE_FIELDS (type);
6467 if (name && TREE_CODE (name) == IDENTIFIER_NODE)
6469 obstack_1grow (&util_obstack, left);
6470 obstack_grow (&util_obstack,
6471 IDENTIFIER_POINTER (name),
6472 strlen (IDENTIFIER_POINTER (name)));
6473 obstack_1grow (&util_obstack, '=');
6477 obstack_1grow (&util_obstack, left);
6478 obstack_grow (&util_obstack, "?=", 2);
6481 for ( ; fields; fields = TREE_CHAIN (fields))
6482 encode_field_decl (fields, curtype, format);
6484 obstack_1grow (&util_obstack, right);
6487 else if (name && TREE_CODE (name) == IDENTIFIER_NODE)
6489 obstack_1grow (&util_obstack, left);
6490 obstack_grow (&util_obstack,
6491 IDENTIFIER_POINTER (name),
6492 strlen (IDENTIFIER_POINTER (name)));
6493 obstack_1grow (&util_obstack, right);
6498 /* We have an untagged structure or a typedef. */
6499 obstack_1grow (&util_obstack, left);
6500 obstack_1grow (&util_obstack, '?');
6501 obstack_1grow (&util_obstack, right);
6507 tree name = TYPE_NAME (type);
6508 tree fields = TYPE_FIELDS (type);
6510 if (format == OBJC_ENCODE_INLINE_DEFS
6511 || generating_instance_variables)
6513 obstack_1grow (&util_obstack, left);
6514 if (name && TREE_CODE (name) == IDENTIFIER_NODE)
6515 obstack_grow (&util_obstack,
6516 IDENTIFIER_POINTER (name),
6517 strlen (IDENTIFIER_POINTER (name)));
6519 obstack_1grow (&util_obstack, '?');
6521 obstack_1grow (&util_obstack, '=');
6523 for (; fields; fields = TREE_CHAIN (fields))
6525 if (generating_instance_variables)
6527 tree fname = DECL_NAME (fields);
6529 obstack_1grow (&util_obstack, '"');
6530 if (fname && TREE_CODE (fname) == IDENTIFIER_NODE)
6532 obstack_grow (&util_obstack,
6533 IDENTIFIER_POINTER (fname),
6534 strlen (IDENTIFIER_POINTER (fname)));
6537 obstack_1grow (&util_obstack, '"');
6540 encode_field_decl (fields, curtype, format);
6543 obstack_1grow (&util_obstack, right);
6548 obstack_1grow (&util_obstack, left);
6549 if (name && TREE_CODE (name) == IDENTIFIER_NODE)
6550 obstack_grow (&util_obstack,
6551 IDENTIFIER_POINTER (name),
6552 strlen (IDENTIFIER_POINTER (name)));
6554 /* We have an untagged structure or a typedef. */
6555 obstack_1grow (&util_obstack, '?');
6557 obstack_1grow (&util_obstack, right);
6563 encode_aggregate (type, curtype, format)
6568 enum tree_code code = TREE_CODE (type);
6574 encode_aggregate_within(type, curtype, format, '{', '}');
6579 encode_aggregate_within(type, curtype, format, '(', ')');
6584 obstack_1grow (&util_obstack, 'i');
6589 /* Support bitfields. The current version of Objective-C does not support
6590 them. The string will consist of one or more "b:n"'s where n is an
6591 integer describing the width of the bitfield. Currently, classes in
6592 the kit implement a method "-(char *)describeBitfieldStruct:" that
6593 simulates this. If they do not implement this method, the archiver
6594 assumes the bitfield is 16 bits wide (padded if necessary) and packed
6595 according to the GNU compiler. After looking at the "kit", it appears
6596 that all classes currently rely on this default behavior, rather than
6597 hand generating this string (which is tedious). */
6600 encode_bitfield (width, format)
6605 sprintf (buffer, "b%d", width);
6606 obstack_grow (&util_obstack, buffer, strlen (buffer));
6609 /* FORMAT will be OBJC_ENCODE_INLINE_DEFS or OBJC_ENCODE_DONT_INLINE_DEFS. */
6612 encode_type (type, curtype, format)
6617 enum tree_code code = TREE_CODE (type);
6619 if (code == INTEGER_TYPE)
6621 if (TREE_INT_CST_LOW (TYPE_MIN_VALUE (type)) == 0
6622 && TREE_INT_CST_HIGH (TYPE_MIN_VALUE (type)) == 0)
6624 /* Unsigned integer types. */
6626 if (TYPE_MODE (type) == QImode)
6627 obstack_1grow (&util_obstack, 'C');
6628 else if (TYPE_MODE (type) == HImode)
6629 obstack_1grow (&util_obstack, 'S');
6630 else if (TYPE_MODE (type) == SImode)
6632 if (type == long_unsigned_type_node)
6633 obstack_1grow (&util_obstack, 'L');
6635 obstack_1grow (&util_obstack, 'I');
6637 else if (TYPE_MODE (type) == DImode)
6638 obstack_1grow (&util_obstack, 'Q');
6642 /* Signed integer types. */
6644 if (TYPE_MODE (type) == QImode)
6645 obstack_1grow (&util_obstack, 'c');
6646 else if (TYPE_MODE (type) == HImode)
6647 obstack_1grow (&util_obstack, 's');
6648 else if (TYPE_MODE (type) == SImode)
6650 if (type == long_integer_type_node)
6651 obstack_1grow (&util_obstack, 'l');
6653 obstack_1grow (&util_obstack, 'i');
6656 else if (TYPE_MODE (type) == DImode)
6657 obstack_1grow (&util_obstack, 'q');
6661 else if (code == REAL_TYPE)
6663 /* Floating point types. */
6665 if (TYPE_MODE (type) == SFmode)
6666 obstack_1grow (&util_obstack, 'f');
6667 else if (TYPE_MODE (type) == DFmode
6668 || TYPE_MODE (type) == TFmode)
6669 obstack_1grow (&util_obstack, 'd');
6672 else if (code == VOID_TYPE)
6673 obstack_1grow (&util_obstack, 'v');
6675 else if (code == ARRAY_TYPE)
6676 encode_array (type, curtype, format);
6678 else if (code == POINTER_TYPE)
6679 encode_pointer (type, curtype, format);
6681 else if (code == RECORD_TYPE || code == UNION_TYPE || code == ENUMERAL_TYPE)
6682 encode_aggregate (type, curtype, format);
6684 else if (code == FUNCTION_TYPE) /* '?' */
6685 obstack_1grow (&util_obstack, '?');
6689 encode_field_decl (field_decl, curtype, format)
6696 /* If this field is obviously a bitfield, or is a bitfield that has been
6697 clobbered to look like a ordinary integer mode, go ahead and generate
6698 the bitfield typing information. */
6699 type = TREE_TYPE (field_decl);
6700 if (DECL_BIT_FIELD (field_decl))
6701 encode_bitfield (DECL_FIELD_SIZE (field_decl), format);
6702 else if (TREE_CODE (TYPE_SIZE (type)) == INTEGER_CST
6703 && DECL_FIELD_SIZE (field_decl)
6704 && TYPE_MODE (type) > DECL_MODE (field_decl))
6705 encode_bitfield (DECL_FIELD_SIZE (field_decl), format);
6707 encode_type (TREE_TYPE (field_decl), curtype, format);
6711 expr_last (complex_expr)
6717 while ((next = TREE_OPERAND (complex_expr, 0)))
6718 complex_expr = next;
6720 return complex_expr;
6723 /* The selector of the current method,
6724 or NULL if we aren't compiling a method. */
6727 maybe_objc_method_name (decl)
6731 return METHOD_SEL_NAME (method_context);
6736 /* Transform a method definition into a function definition as follows:
6737 - synthesize the first two arguments, "self" and "_cmd". */
6740 start_method_def (method)
6745 /* Required to implement _msgSuper. */
6746 method_context = method;
6747 UOBJC_SUPER_decl = NULL_TREE;
6749 /* Must be called BEFORE start_function. */
6752 /* Generate prototype declarations for arguments..."new-style". */
6754 if (TREE_CODE (method_context) == INSTANCE_METHOD_DECL)
6755 decl_specs = build_tree_list (NULL_TREE, uprivate_record);
6757 /* Really a `struct objc_class *'. However, we allow people to
6758 assign to self, which changes its type midstream. */
6759 decl_specs = build_tree_list (NULL_TREE, objc_object_reference);
6761 push_parm_decl (build_tree_list
6762 (build_tree_list (decl_specs,
6763 build1 (INDIRECT_REF, NULL_TREE, self_id)),
6764 build_tree_list (unused_list, NULL_TREE)));
6766 #ifdef OBJC_INT_SELECTORS
6767 decl_specs = build_tree_list (NULL_TREE, ridpointers[(int) RID_UNSIGNED]);
6768 decl_specs = tree_cons (NULL_TREE, ridpointers[(int) RID_INT], decl_specs);
6769 push_parm_decl (build_tree_list (build_tree_list (decl_specs, ucmd_id),
6770 build_tree_list (unused_list, NULL_TREE)));
6771 #else /* not OBJC_INT_SELECTORS */
6772 decl_specs = build_tree_list (NULL_TREE,
6773 xref_tag (RECORD_TYPE,
6774 get_identifier (TAG_SELECTOR)));
6775 push_parm_decl (build_tree_list
6776 (build_tree_list (decl_specs,
6777 build1 (INDIRECT_REF, NULL_TREE, ucmd_id)),
6778 build_tree_list (unused_list, NULL_TREE)));
6779 #endif /* not OBJC_INT_SELECTORS */
6781 /* Generate argument declarations if a keyword_decl. */
6782 if (METHOD_SEL_ARGS (method))
6784 tree arglist = METHOD_SEL_ARGS (method);
6787 tree arg_spec = TREE_PURPOSE (TREE_TYPE (arglist));
6788 tree arg_decl = TREE_VALUE (TREE_TYPE (arglist));
6792 tree last_expr = expr_last (arg_decl);
6794 /* Unite the abstract decl with its name. */
6795 TREE_OPERAND (last_expr, 0) = KEYWORD_ARG_NAME (arglist);
6796 push_parm_decl (build_tree_list
6797 (build_tree_list (arg_spec, arg_decl),
6798 build_tree_list (NULL_TREE, NULL_TREE)));
6800 /* Unhook: restore the abstract declarator. */
6801 TREE_OPERAND (last_expr, 0) = NULL_TREE;
6805 push_parm_decl (build_tree_list
6806 (build_tree_list (arg_spec,
6807 KEYWORD_ARG_NAME (arglist)),
6808 build_tree_list (NULL_TREE, NULL_TREE)));
6810 arglist = TREE_CHAIN (arglist);
6815 if (METHOD_ADD_ARGS (method) > (tree)1)
6817 /* We have a variable length selector - in "prototype" format. */
6818 tree akey = TREE_PURPOSE (METHOD_ADD_ARGS (method));
6821 /* This must be done prior to calling pushdecl. pushdecl is
6822 going to change our chain on us. */
6823 tree nextkey = TREE_CHAIN (akey);
6831 warn_with_method (message, mtype, method)
6836 if (count_error (1) == 0)
6839 report_error_function (DECL_SOURCE_FILE (method));
6841 fprintf (stderr, "%s:%d: warning: ",
6842 DECL_SOURCE_FILE (method), DECL_SOURCE_LINE (method));
6843 bzero (errbuf, BUFSIZE);
6844 fprintf (stderr, "%s `%c%s'\n",
6845 message, mtype, gen_method_decl (method, errbuf));
6848 /* Return 1 if METHOD is consistent with PROTO. */
6851 comp_method_with_proto (method, proto)
6854 static tree function_type = 0;
6856 /* Create a function_type node once. */
6859 push_obstacks_nochange ();
6860 end_temporary_allocation ();
6861 function_type = make_node (FUNCTION_TYPE);
6865 /* Install argument types - normally set by build_function_type. */
6866 TYPE_ARG_TYPES (function_type) = get_arg_type_list (proto, METHOD_DEF, 0);
6868 /* install return type */
6869 TREE_TYPE (function_type) = groktypename (TREE_TYPE (proto));
6871 return comptypes (TREE_TYPE (METHOD_DEFINITION (method)), function_type);
6874 /* Return 1 if PROTO1 is consistent with PROTO2. */
6877 comp_proto_with_proto (proto1, proto2)
6878 tree proto1, proto2;
6880 static tree function_type1 = 0, function_type2 = 0;
6882 /* Create a couple function_type node's once. */
6883 if (!function_type1)
6885 push_obstacks_nochange ();
6886 end_temporary_allocation ();
6887 function_type1 = make_node (FUNCTION_TYPE);
6888 function_type2 = make_node (FUNCTION_TYPE);
6892 /* Install argument types; normally set by build_function_type. */
6893 TYPE_ARG_TYPES (function_type1) = get_arg_type_list (proto1, METHOD_REF, 0);
6894 TYPE_ARG_TYPES (function_type2) = get_arg_type_list (proto2, METHOD_REF, 0);
6896 /* Install return type. */
6897 TREE_TYPE (function_type1) = groktypename (TREE_TYPE (proto1));
6898 TREE_TYPE (function_type2) = groktypename (TREE_TYPE (proto2));
6900 return comptypes (function_type1, function_type2);
6903 /* - Generate an identifier for the function. the format is "_n_cls",
6904 where 1 <= n <= nMethods, and cls is the name the implementation we
6906 - Install the return type from the method declaration.
6907 - If we have a prototype, check for type consistency. */
6910 really_start_method (method, parmlist)
6911 tree method, parmlist;
6913 tree sc_spec, ret_spec, ret_decl, decl_specs;
6914 tree method_decl, method_id;
6915 char *buf, *sel_name, *class_name, *cat_name;
6917 /* Synth the storage class & assemble the return type. */
6918 sc_spec = tree_cons (NULL_TREE, ridpointers[(int) RID_STATIC], NULL_TREE);
6919 ret_spec = TREE_PURPOSE (TREE_TYPE (method));
6920 decl_specs = chainon (sc_spec, ret_spec);
6922 sel_name = IDENTIFIER_POINTER (METHOD_SEL_NAME (method));
6923 class_name = IDENTIFIER_POINTER (CLASS_NAME (implementation_context));
6924 cat_name = ((TREE_CODE (implementation_context)
6925 == CLASS_IMPLEMENTATION_TYPE)
6927 : IDENTIFIER_POINTER (CLASS_SUPER_NAME (implementation_context)));
6930 /* Make sure this is big enough for any plausible method label. */
6931 buf = (char *) alloca (50 + strlen (sel_name) + strlen (class_name)
6932 + (cat_name ? strlen (cat_name) : 0));
6934 OBJC_GEN_METHOD_LABEL (buf, TREE_CODE (method) == INSTANCE_METHOD_DECL,
6935 class_name, cat_name, sel_name, method_slot);
6937 method_id = get_identifier (buf);
6939 method_decl = build_nt (CALL_EXPR, method_id, parmlist, NULL_TREE);
6941 /* Check the declarator portion of the return type for the method. */
6942 if ((ret_decl = TREE_VALUE (TREE_TYPE (method))))
6944 /* Unite the complex decl (specified in the abstract decl) with the
6945 function decl just synthesized..(int *), (int (*)()), (int (*)[]). */
6946 tree save_expr = expr_last (ret_decl);
6948 TREE_OPERAND (save_expr, 0) = method_decl;
6949 method_decl = ret_decl;
6951 /* Fool the parser into thinking it is starting a function. */
6952 start_function (decl_specs, method_decl, NULL_TREE, NULL_TREE, 0);
6954 /* Unhook: this has the effect of restoring the abstract declarator. */
6955 TREE_OPERAND (save_expr, 0) = NULL_TREE;
6960 TREE_VALUE (TREE_TYPE (method)) = method_decl;
6962 /* Fool the parser into thinking it is starting a function. */
6963 start_function (decl_specs, method_decl, NULL_TREE, NULL_TREE, 0);
6965 /* Unhook: this has the effect of restoring the abstract declarator. */
6966 TREE_VALUE (TREE_TYPE (method)) = NULL_TREE;
6969 METHOD_DEFINITION (method) = current_function_decl;
6971 if (implementation_template != implementation_context)
6975 if (TREE_CODE (method) == INSTANCE_METHOD_DECL)
6976 proto = lookup_instance_method_static (implementation_template,
6977 METHOD_SEL_NAME (method));
6979 proto = lookup_class_method_static (implementation_template,
6980 METHOD_SEL_NAME (method));
6982 if (proto && ! comp_method_with_proto (method, proto))
6984 char type = (TREE_CODE (method) == INSTANCE_METHOD_DECL ? '-' : '+');
6986 warn_with_method ("conflicting types for", type, method);
6987 warn_with_method ("previous declaration of", type, proto);
6992 /* The following routine is always called...this "architecture" is to
6993 accommodate "old-style" variable length selectors.
6995 - a:a b:b // prototype ; id c; id d; // old-style. */
6998 continue_method_def ()
7002 if (METHOD_ADD_ARGS (method_context) == (tree)1)
7003 /* We have a `, ...' immediately following the selector. */
7004 parmlist = get_parm_info (0);
7006 parmlist = get_parm_info (1); /* place a `void_at_end' */
7008 /* Set self_decl from the first argument...this global is used by
7009 build_ivar_reference calling build_indirect_ref. */
7010 self_decl = TREE_PURPOSE (parmlist);
7013 really_start_method (method_context, parmlist);
7014 store_parm_decls ();
7017 /* Called by the parser, from the `pushlevel' production. */
7022 if (!UOBJC_SUPER_decl)
7024 UOBJC_SUPER_decl = start_decl (get_identifier (UTAG_SUPER),
7025 build_tree_list (NULL_TREE,
7026 objc_super_template),
7027 0, NULL_TREE, NULL_TREE);
7029 finish_decl (UOBJC_SUPER_decl, NULL_TREE, NULL_TREE);
7031 /* This prevents `unused variable' warnings when compiling with -Wall. */
7032 TREE_USED (UOBJC_SUPER_decl) = 1;
7033 DECL_ARTIFICIAL (UOBJC_SUPER_decl) = 1;
7037 /* _n_Method (id self, SEL sel, ...)
7039 struct objc_super _S;
7040 _msgSuper ((_S.self = self, _S.class = _cls, &_S), ...);
7044 get_super_receiver ()
7048 tree super_expr, super_expr_list;
7050 /* Set receiver to self. */
7051 super_expr = build_component_ref (UOBJC_SUPER_decl, self_id);
7052 super_expr = build_modify_expr (super_expr, NOP_EXPR, self_decl);
7053 super_expr_list = build_tree_list (NULL_TREE, super_expr);
7055 /* Set class to begin searching. */
7056 super_expr = build_component_ref (UOBJC_SUPER_decl,
7057 get_identifier ("class"));
7059 if (TREE_CODE (implementation_context) == CLASS_IMPLEMENTATION_TYPE)
7061 /* [_cls, __cls]Super are "pre-built" in
7062 synth_forward_declarations. */
7064 super_expr = build_modify_expr (super_expr, NOP_EXPR,
7065 ((TREE_CODE (method_context)
7066 == INSTANCE_METHOD_DECL)
7068 : uucls_super_ref));
7072 /* We have a category. */
7074 tree super_name = CLASS_SUPER_NAME (implementation_template);
7079 error ("no super class declared in interface for `%s'",
7080 IDENTIFIER_POINTER (CLASS_NAME (implementation_template)));
7081 return error_mark_node;
7084 if (flag_next_runtime)
7086 super_class = get_class_reference (super_name);
7087 if (TREE_CODE (method_context) == CLASS_METHOD_DECL)
7089 = build_component_ref (build_indirect_ref (super_class, "->"),
7090 get_identifier ("isa"));
7094 add_class_reference (super_name);
7095 super_class = (TREE_CODE (method_context) == INSTANCE_METHOD_DECL
7096 ? objc_get_class_decl : objc_get_meta_class_decl);
7097 assemble_external (super_class);
7099 = build_function_call
7103 my_build_string (IDENTIFIER_LENGTH (super_name) + 1,
7104 IDENTIFIER_POINTER (super_name))));
7107 TREE_TYPE (super_class) = TREE_TYPE (ucls_super_ref);
7108 super_expr = build_modify_expr (super_expr, NOP_EXPR, super_class);
7111 chainon (super_expr_list, build_tree_list (NULL_TREE, super_expr));
7113 super_expr = build_unary_op (ADDR_EXPR, UOBJC_SUPER_decl, 0);
7114 chainon (super_expr_list, build_tree_list (NULL_TREE, super_expr));
7116 return build_compound_expr (super_expr_list);
7120 error ("[super ...] must appear in a method context");
7121 return error_mark_node;
7126 encode_method_def (func_decl)
7131 int max_parm_end = 0;
7136 encode_type (TREE_TYPE (TREE_TYPE (func_decl)),
7137 obstack_object_size (&util_obstack),
7138 OBJC_ENCODE_INLINE_DEFS);
7141 for (parms = DECL_ARGUMENTS (func_decl); parms;
7142 parms = TREE_CHAIN (parms))
7144 int parm_end = (forwarding_offset (parms)
7145 + (TREE_INT_CST_LOW (TYPE_SIZE (TREE_TYPE (parms)))
7148 if (!offset_is_register && parm_end > max_parm_end)
7149 max_parm_end = parm_end;
7152 stack_size = max_parm_end - OBJC_FORWARDING_MIN_OFFSET;
7154 sprintf (buffer, "%d", stack_size);
7155 obstack_grow (&util_obstack, buffer, strlen (buffer));
7157 /* Argument types. */
7158 for (parms = DECL_ARGUMENTS (func_decl); parms;
7159 parms = TREE_CHAIN (parms))
7162 encode_type (TREE_TYPE (parms),
7163 obstack_object_size (&util_obstack),
7164 OBJC_ENCODE_INLINE_DEFS);
7166 /* Compute offset. */
7167 sprintf (buffer, "%d", forwarding_offset (parms));
7169 /* Indicate register. */
7170 if (offset_is_register)
7171 obstack_1grow (&util_obstack, '+');
7173 obstack_grow (&util_obstack, buffer, strlen (buffer));
7176 obstack_1grow (&util_obstack, 0);
7177 result = get_identifier (obstack_finish (&util_obstack));
7178 obstack_free (&util_obstack, util_firstobj);
7183 finish_method_def ()
7185 METHOD_ENCODING (method_context) = encode_method_def (current_function_decl);
7187 finish_function (0);
7189 /* Required to implement _msgSuper. This must be done AFTER finish_function,
7190 since the optimizer may find "may be used before set" errors. */
7191 method_context = NULL_TREE;
7195 lang_report_error_function (decl)
7200 fprintf (stderr, "In method `%s'\n",
7201 IDENTIFIER_POINTER (METHOD_SEL_NAME (method_context)));
7210 is_complex_decl (type)
7213 return (TREE_CODE (type) == ARRAY_TYPE
7214 || TREE_CODE (type) == FUNCTION_TYPE
7215 || (TREE_CODE (type) == POINTER_TYPE && ! IS_ID (type)));
7219 /* Code to convert a decl node into text for a declaration in C. */
7221 static char tmpbuf[256];
7224 adorn_decl (decl, str)
7228 enum tree_code code = TREE_CODE (decl);
7230 if (code == ARRAY_REF)
7232 tree an_int_cst = TREE_OPERAND (decl, 1);
7234 if (an_int_cst && TREE_CODE (an_int_cst) == INTEGER_CST)
7235 sprintf (str + strlen (str), "[%d]", TREE_INT_CST_LOW (an_int_cst));
7240 else if (code == ARRAY_TYPE)
7242 tree an_int_cst = TYPE_SIZE (decl);
7243 tree array_of = TREE_TYPE (decl);
7245 if (an_int_cst && TREE_CODE (an_int_cst) == INTEGER_TYPE)
7246 sprintf (str + strlen (str), "[%d]",
7247 (TREE_INT_CST_LOW (an_int_cst)
7248 / TREE_INT_CST_LOW (TYPE_SIZE (array_of))));
7253 else if (code == CALL_EXPR)
7255 tree chain = TREE_PURPOSE (TREE_OPERAND (decl, 1));
7260 gen_declaration (chain, str);
7261 chain = TREE_CHAIN (chain);
7268 else if (code == FUNCTION_TYPE)
7270 tree chain = TYPE_ARG_TYPES (decl);
7273 while (chain && TREE_VALUE (chain) != void_type_node)
7275 gen_declaration (TREE_VALUE (chain), str);
7276 chain = TREE_CHAIN (chain);
7277 if (chain && TREE_VALUE (chain) != void_type_node)
7283 else if (code == INDIRECT_REF)
7285 strcpy (tmpbuf, "*");
7286 if (TREE_TYPE (decl) && TREE_CODE (TREE_TYPE (decl)) == TREE_LIST)
7290 for (chain = nreverse (copy_list (TREE_TYPE (decl)));
7292 chain = TREE_CHAIN (chain))
7294 if (TREE_CODE (TREE_VALUE (chain)) == IDENTIFIER_NODE)
7296 strcat (tmpbuf, " ");
7297 strcat (tmpbuf, IDENTIFIER_POINTER (TREE_VALUE (chain)));
7301 strcat (tmpbuf, " ");
7303 strcat (tmpbuf, str);
7304 strcpy (str, tmpbuf);
7307 else if (code == POINTER_TYPE)
7309 strcpy (tmpbuf, "*");
7310 if (TREE_READONLY (decl) || TYPE_VOLATILE (decl))
7312 if (TREE_READONLY (decl))
7313 strcat (tmpbuf, " const");
7314 if (TYPE_VOLATILE (decl))
7315 strcat (tmpbuf, " volatile");
7317 strcat (tmpbuf, " ");
7319 strcat (tmpbuf, str);
7320 strcpy (str, tmpbuf);
7325 gen_declarator (decl, buf, name)
7332 enum tree_code code = TREE_CODE (decl);
7342 op = TREE_OPERAND (decl, 0);
7344 /* We have a pointer to a function or array...(*)(), (*)[] */
7345 if ((code == ARRAY_REF || code == CALL_EXPR)
7346 && op && TREE_CODE (op) == INDIRECT_REF)
7349 str = gen_declarator (op, buf, name);
7353 strcpy (tmpbuf, "(");
7354 strcat (tmpbuf, str);
7355 strcat (tmpbuf, ")");
7356 strcpy (str, tmpbuf);
7359 adorn_decl (decl, str);
7368 /* This clause is done iteratively rather than recursively. */
7371 op = (is_complex_decl (TREE_TYPE (decl))
7372 ? TREE_TYPE (decl) : NULL_TREE);
7374 adorn_decl (decl, str);
7376 /* We have a pointer to a function or array...(*)(), (*)[] */
7377 if (code == POINTER_TYPE
7378 && op && (TREE_CODE (op) == FUNCTION_TYPE
7379 || TREE_CODE (op) == ARRAY_TYPE))
7381 strcpy (tmpbuf, "(");
7382 strcat (tmpbuf, str);
7383 strcat (tmpbuf, ")");
7384 strcpy (str, tmpbuf);
7387 decl = (is_complex_decl (TREE_TYPE (decl))
7388 ? TREE_TYPE (decl) : NULL_TREE);
7391 while (decl && (code = TREE_CODE (decl)))
7396 case IDENTIFIER_NODE:
7397 /* Will only happen if we are processing a "raw" expr-decl. */
7398 strcpy (buf, IDENTIFIER_POINTER (decl));
7406 /* We have an abstract declarator or a _DECL node. */
7414 gen_declspecs (declspecs, buf, raw)
7423 for (chain = nreverse (copy_list (declspecs));
7424 chain; chain = TREE_CHAIN (chain))
7426 tree aspec = TREE_VALUE (chain);
7428 if (TREE_CODE (aspec) == IDENTIFIER_NODE)
7429 strcat (buf, IDENTIFIER_POINTER (aspec));
7430 else if (TREE_CODE (aspec) == RECORD_TYPE)
7432 if (TYPE_NAME (aspec))
7434 tree protocol_list = TYPE_PROTOCOL_LIST (aspec);
7436 if (! TREE_STATIC_TEMPLATE (aspec))
7437 strcat (buf, "struct ");
7438 strcat (buf, IDENTIFIER_POINTER (TYPE_NAME (aspec)));
7443 tree chain = protocol_list;
7450 (PROTOCOL_NAME (TREE_VALUE (chain))));
7451 chain = TREE_CHAIN (chain);
7460 strcat (buf, "untagged struct");
7463 else if (TREE_CODE (aspec) == UNION_TYPE)
7465 if (TYPE_NAME (aspec))
7467 if (! TREE_STATIC_TEMPLATE (aspec))
7468 strcat (buf, "union ");
7469 strcat (buf, IDENTIFIER_POINTER (TYPE_NAME (aspec)));
7472 strcat (buf, "untagged union");
7475 else if (TREE_CODE (aspec) == ENUMERAL_TYPE)
7477 if (TYPE_NAME (aspec))
7479 if (! TREE_STATIC_TEMPLATE (aspec))
7480 strcat (buf, "enum ");
7481 strcat (buf, IDENTIFIER_POINTER (TYPE_NAME (aspec)));
7484 strcat (buf, "untagged enum");
7487 else if (TREE_CODE (aspec) == TYPE_DECL && DECL_NAME (aspec))
7488 strcat (buf, IDENTIFIER_POINTER (DECL_NAME (aspec)));
7490 else if (IS_ID (aspec))
7492 tree protocol_list = TYPE_PROTOCOL_LIST (aspec);
7497 tree chain = protocol_list;
7504 (PROTOCOL_NAME (TREE_VALUE (chain))));
7505 chain = TREE_CHAIN (chain);
7512 if (TREE_CHAIN (chain))
7518 /* Type qualifiers. */
7519 if (TREE_READONLY (declspecs))
7520 strcat (buf, "const ");
7521 if (TYPE_VOLATILE (declspecs))
7522 strcat (buf, "volatile ");
7524 switch (TREE_CODE (declspecs))
7526 /* Type specifiers. */
7529 declspecs = TYPE_MAIN_VARIANT (declspecs);
7531 /* Signed integer types. */
7533 if (declspecs == short_integer_type_node)
7534 strcat (buf, "short int ");
7535 else if (declspecs == integer_type_node)
7536 strcat (buf, "int ");
7537 else if (declspecs == long_integer_type_node)
7538 strcat (buf, "long int ");
7539 else if (declspecs == long_long_integer_type_node)
7540 strcat (buf, "long long int ");
7541 else if (declspecs == signed_char_type_node
7542 || declspecs == char_type_node)
7543 strcat (buf, "char ");
7545 /* Unsigned integer types. */
7547 else if (declspecs == short_unsigned_type_node)
7548 strcat (buf, "unsigned short ");
7549 else if (declspecs == unsigned_type_node)
7550 strcat (buf, "unsigned int ");
7551 else if (declspecs == long_unsigned_type_node)
7552 strcat (buf, "unsigned long ");
7553 else if (declspecs == long_long_unsigned_type_node)
7554 strcat (buf, "unsigned long long ");
7555 else if (declspecs == unsigned_char_type_node)
7556 strcat (buf, "unsigned char ");
7560 declspecs = TYPE_MAIN_VARIANT (declspecs);
7562 if (declspecs == float_type_node)
7563 strcat (buf, "float ");
7564 else if (declspecs == double_type_node)
7565 strcat (buf, "double ");
7566 else if (declspecs == long_double_type_node)
7567 strcat (buf, "long double ");
7571 if (TYPE_NAME (declspecs)
7572 && TREE_CODE (TYPE_NAME (declspecs)) == IDENTIFIER_NODE)
7574 tree protocol_list = TYPE_PROTOCOL_LIST (declspecs);
7576 if (! TREE_STATIC_TEMPLATE (declspecs))
7577 strcat (buf, "struct ");
7578 strcat (buf, IDENTIFIER_POINTER (TYPE_NAME (declspecs)));
7582 tree chain = protocol_list;
7589 (PROTOCOL_NAME (TREE_VALUE (chain))));
7590 chain = TREE_CHAIN (chain);
7599 strcat (buf, "untagged struct");
7605 if (TYPE_NAME (declspecs)
7606 && TREE_CODE (TYPE_NAME (declspecs)) == IDENTIFIER_NODE)
7608 strcat (buf, "union ");
7609 strcat (buf, IDENTIFIER_POINTER (TYPE_NAME (declspecs)));
7614 strcat (buf, "untagged union ");
7618 if (TYPE_NAME (declspecs)
7619 && TREE_CODE (TYPE_NAME (declspecs)) == IDENTIFIER_NODE)
7621 strcat (buf, "enum ");
7622 strcat (buf, IDENTIFIER_POINTER (TYPE_NAME (declspecs)));
7627 strcat (buf, "untagged enum ");
7631 strcat (buf, "void ");
7636 tree protocol_list = TYPE_PROTOCOL_LIST (declspecs);
7641 tree chain = protocol_list;
7648 (PROTOCOL_NAME (TREE_VALUE (chain))));
7649 chain = TREE_CHAIN (chain);
7662 gen_declaration (atype_or_adecl, buf)
7663 tree atype_or_adecl;
7668 if (TREE_CODE (atype_or_adecl) == TREE_LIST)
7670 tree declspecs; /* "identifier_node", "record_type" */
7671 tree declarator; /* "array_ref", "indirect_ref", "call_expr"... */
7673 /* We have a "raw", abstract declarator (typename). */
7674 declarator = TREE_VALUE (atype_or_adecl);
7675 declspecs = TREE_PURPOSE (atype_or_adecl);
7677 gen_declspecs (declspecs, buf, 1);
7681 strcat (buf, gen_declarator (declarator, declbuf, ""));
7688 tree declspecs; /* "integer_type", "real_type", "record_type"... */
7689 tree declarator; /* "array_type", "function_type", "pointer_type". */
7691 if (TREE_CODE (atype_or_adecl) == FIELD_DECL
7692 || TREE_CODE (atype_or_adecl) == PARM_DECL
7693 || TREE_CODE (atype_or_adecl) == FUNCTION_DECL)
7694 atype = TREE_TYPE (atype_or_adecl);
7696 /* Assume we have a *_type node. */
7697 atype = atype_or_adecl;
7699 if (is_complex_decl (atype))
7703 /* Get the declaration specifier; it is at the end of the list. */
7704 declarator = chain = atype;
7706 chain = TREE_TYPE (chain); /* not TREE_CHAIN (chain); */
7707 while (is_complex_decl (chain));
7714 declarator = NULL_TREE;
7717 gen_declspecs (declspecs, buf, 0);
7719 if (TREE_CODE (atype_or_adecl) == FIELD_DECL
7720 || TREE_CODE (atype_or_adecl) == PARM_DECL
7721 || TREE_CODE (atype_or_adecl) == FUNCTION_DECL)
7723 char *decl_name = (DECL_NAME (atype_or_adecl)
7724 ? IDENTIFIER_POINTER (DECL_NAME (atype_or_adecl))
7730 strcat (buf, gen_declarator (declarator, declbuf, decl_name));
7733 else if (decl_name[0])
7736 strcat (buf, decl_name);
7739 else if (declarator)
7742 strcat (buf, gen_declarator (declarator, declbuf, ""));
7749 #define RAW_TYPESPEC(meth) (TREE_VALUE (TREE_PURPOSE (TREE_TYPE (meth))))
7752 gen_method_decl (method, buf)
7758 if (RAW_TYPESPEC (method) != objc_object_reference)
7761 gen_declaration (TREE_TYPE (method), buf);
7765 chain = METHOD_SEL_ARGS (method);
7768 /* We have a chain of keyword_decls. */
7771 if (KEYWORD_KEY_NAME (chain))
7772 strcat (buf, IDENTIFIER_POINTER (KEYWORD_KEY_NAME (chain)));
7775 if (RAW_TYPESPEC (chain) != objc_object_reference)
7778 gen_declaration (TREE_TYPE (chain), buf);
7782 strcat (buf, IDENTIFIER_POINTER (KEYWORD_ARG_NAME (chain)));
7783 if ((chain = TREE_CHAIN (chain)))
7788 if (METHOD_ADD_ARGS (method) == (tree)1)
7789 strcat (buf, ", ...");
7790 else if (METHOD_ADD_ARGS (method))
7792 /* We have a tree list node as generate by get_parm_info. */
7793 chain = TREE_PURPOSE (METHOD_ADD_ARGS (method));
7795 /* Know we have a chain of parm_decls. */
7799 gen_declaration (chain, buf);
7800 chain = TREE_CHAIN (chain);
7806 /* We have a unary selector. */
7807 strcat (buf, IDENTIFIER_POINTER (METHOD_SEL_NAME (method)));
7815 dump_interface (fp, chain)
7819 char *buf = (char *)xmalloc (256);
7820 char *my_name = IDENTIFIER_POINTER (CLASS_NAME (chain));
7821 tree ivar_decls = CLASS_RAW_IVARS (chain);
7822 tree nst_methods = CLASS_NST_METHODS (chain);
7823 tree cls_methods = CLASS_CLS_METHODS (chain);
7825 fprintf (fp, "\n@interface %s", my_name);
7827 if (CLASS_SUPER_NAME (chain))
7829 char *super_name = IDENTIFIER_POINTER (CLASS_SUPER_NAME (chain));
7830 fprintf (fp, " : %s\n", super_name);
7837 fprintf (fp, "{\n");
7841 fprintf (fp, "\t%s;\n", gen_declaration (ivar_decls, buf));
7842 ivar_decls = TREE_CHAIN (ivar_decls);
7845 fprintf (fp, "}\n");
7851 fprintf (fp, "- %s;\n", gen_method_decl (nst_methods, buf));
7852 nst_methods = TREE_CHAIN (nst_methods);
7858 fprintf (fp, "+ %s;\n", gen_method_decl (cls_methods, buf));
7859 cls_methods = TREE_CHAIN (cls_methods);
7861 fprintf (fp, "\n@end");
7867 /* Add the special tree codes of Objective C to the tables. */
7869 #define LAST_CODE LAST_AND_UNUSED_TREE_CODE
7871 gcc_obstack_init (&util_obstack);
7872 util_firstobj = (char *) obstack_finish (&util_obstack);
7875 = (char **) xrealloc (tree_code_type,
7876 sizeof (char *) * LAST_OBJC_TREE_CODE);
7878 = (int *) xrealloc (tree_code_length,
7879 sizeof (int) * LAST_OBJC_TREE_CODE);
7881 = (char **) xrealloc (tree_code_name,
7882 sizeof (char *) * LAST_OBJC_TREE_CODE);
7883 bcopy ((char *) objc_tree_code_type,
7884 (char *) (tree_code_type + (int) LAST_CODE),
7885 (((int) LAST_OBJC_TREE_CODE - (int) LAST_CODE)
7886 * sizeof (char *)));
7887 bcopy ((char *) objc_tree_code_length,
7888 (char *) (tree_code_length + (int) LAST_CODE),
7889 (((int) LAST_OBJC_TREE_CODE - (int) LAST_CODE)
7891 bcopy ((char *) objc_tree_code_name,
7892 (char *) (tree_code_name + (int) LAST_CODE),
7893 (((int) LAST_OBJC_TREE_CODE - (int) LAST_CODE)
7894 * sizeof (char *)));
7896 errbuf = (char *)xmalloc (BUFSIZE);
7898 synth_module_prologue ();
7904 struct imp_entry *impent;
7906 /* The internally generated initializers appear to have missing braces.
7907 Don't warn about this. */
7908 int save_warn_missing_braces = warn_missing_braces;
7909 warn_missing_braces = 0;
7911 generate_forward_declaration_to_string_table ();
7913 #ifdef OBJC_PROLOGUE
7917 /* Process the static instances here because initialization of objc_symtab
7918 dependens on them. */
7919 if (objc_static_instances)
7920 generate_static_references ();
7922 if (implementation_context || class_names_chain
7923 || meth_var_names_chain || meth_var_types_chain || sel_ref_chain)
7924 generate_objc_symtab_decl ();
7926 for (impent = imp_list; impent; impent = impent->next)
7928 implementation_context = impent->imp_context;
7929 implementation_template = impent->imp_template;
7931 UOBJC_CLASS_decl = impent->class_decl;
7932 UOBJC_METACLASS_decl = impent->meta_decl;
7934 if (TREE_CODE (implementation_context) == CLASS_IMPLEMENTATION_TYPE)
7936 /* all of the following reference the string pool... */
7937 generate_ivar_lists ();
7938 generate_dispatch_tables ();
7939 generate_shared_structures ();
7943 generate_dispatch_tables ();
7944 generate_category (implementation_context);
7948 /* If we are using an array of selectors, we must always
7949 finish up the array decl even if no selectors were used. */
7950 if (! flag_next_runtime || sel_ref_chain)
7951 build_selector_translation_table ();
7954 generate_protocols ();
7956 if (implementation_context || class_names_chain || objc_static_instances
7957 || meth_var_names_chain || meth_var_types_chain || sel_ref_chain)
7959 /* Arrange for Objc data structures to be initialized at run time. */
7960 char *init_name = build_module_descriptor ();
7962 assemble_constructor (init_name);
7965 /* Dump the class references. This forces the appropriate classes
7966 to be linked into the executable image, preserving unix archive
7967 semantics. This can be removed when we move to a more dynamically
7968 linked environment. */
7970 for (chain = cls_ref_chain; chain; chain = TREE_CHAIN (chain))
7972 handle_class_ref (chain);
7973 if (TREE_PURPOSE (chain))
7974 generate_classref_translation_entry (chain);
7977 for (impent = imp_list; impent; impent = impent->next)
7978 handle_impent (impent);
7980 /* Dump the string table last. */
7982 generate_strings ();
7984 if (flag_gen_declaration)
7986 add_class (implementation_context);
7987 dump_interface (gen_declaration_file, implementation_context);
7995 /* Run through the selector hash tables and print a warning for any
7996 selector which has multiple methods. */
7998 for (slot = 0; slot < SIZEHASHTABLE; slot++)
7999 for (hsh = cls_method_hash_list[slot]; hsh; hsh = hsh->next)
8002 tree meth = hsh->key;
8003 char type = (TREE_CODE (meth) == INSTANCE_METHOD_DECL
8007 warning ("potential selector conflict for method `%s'",
8008 IDENTIFIER_POINTER (METHOD_SEL_NAME (meth)));
8009 warn_with_method ("found", type, meth);
8010 for (loop = hsh->list; loop; loop = loop->next)
8011 warn_with_method ("found", type, loop->value);
8014 for (slot = 0; slot < SIZEHASHTABLE; slot++)
8015 for (hsh = nst_method_hash_list[slot]; hsh; hsh = hsh->next)
8018 tree meth = hsh->key;
8019 char type = (TREE_CODE (meth) == INSTANCE_METHOD_DECL
8023 warning ("potential selector conflict for method `%s'",
8024 IDENTIFIER_POINTER (METHOD_SEL_NAME (meth)));
8025 warn_with_method ("found", type, meth);
8026 for (loop = hsh->list; loop; loop = loop->next)
8027 warn_with_method ("found", type, loop->value);
8031 warn_missing_braces = save_warn_missing_braces;
8034 /* Subroutines of finish_objc. */
8037 generate_classref_translation_entry (chain)
8040 tree expr, name, decl_specs, decl, sc_spec;
8043 type = TREE_TYPE (TREE_PURPOSE (chain));
8045 expr = add_objc_string (TREE_VALUE (chain), class_names);
8046 expr = build_c_cast (type, expr); /* cast! */
8048 name = DECL_NAME (TREE_PURPOSE (chain));
8050 sc_spec = build_tree_list (NULL_TREE, ridpointers[(int) RID_STATIC]);
8052 /* static struct objc_class * _OBJC_CLASS_REFERENCES_n = ...; */
8053 decl_specs = tree_cons (NULL_TREE, type, sc_spec);
8055 /* The decl that is returned from start_decl is the one that we
8056 forward declared in build_class_reference. */
8057 decl = start_decl (name, decl_specs, 1, NULL_TREE, NULL_TREE);
8058 finish_decl (decl, expr, NULL_TREE);
8063 handle_class_ref (chain)
8066 char *name = IDENTIFIER_POINTER (TREE_VALUE (chain));
8067 if (! flag_next_runtime)
8070 char *string = (char *) alloca (strlen (name) + 30);
8073 sprintf (string, "%sobjc_class_name_%s",
8074 (flag_next_runtime ? "." : "__"), name);
8076 /* Make a decl for this name, so we can use its address in a tree. */
8077 decl = build_decl (VAR_DECL, get_identifier (string), char_type_node);
8078 DECL_EXTERNAL (decl) = 1;
8079 TREE_PUBLIC (decl) = 1;
8082 rest_of_decl_compilation (decl, 0, 0, 0);
8084 /* Make following constant read-only (why not)? */
8085 readonly_data_section ();
8087 exp = build1 (ADDR_EXPR, string_type_node, decl);
8089 /* Align the section properly. */
8090 assemble_constant_align (exp);
8092 /* Inform the assembler about this new external thing. */
8093 assemble_external (decl);
8095 /* Output a constant to reference this address. */
8096 output_constant (exp, int_size_in_bytes (string_type_node));
8100 /* This overreliance on our assembler (i.e. lack of portability)
8101 should be dealt with at some point. The GNU strategy (above)
8102 won't work either, but it is a start. */
8103 char *string = (char *) alloca (strlen (name) + 30);
8104 sprintf (string, ".reference .objc_class_name_%s", name);
8105 assemble_asm (my_build_string (strlen (string) + 1, string));
8110 handle_impent (impent)
8111 struct imp_entry *impent;
8113 implementation_context = impent->imp_context;
8114 implementation_template = impent->imp_template;
8116 if (TREE_CODE (impent->imp_context) == CLASS_IMPLEMENTATION_TYPE)
8118 char *class_name = IDENTIFIER_POINTER (CLASS_NAME (impent->imp_context));
8119 char *string = (char *) alloca (strlen (class_name) + 30);
8121 if (flag_next_runtime)
8123 /* Grossly unportable.
8124 People should know better than to assume
8125 such things about assembler syntax! */
8126 sprintf (string, ".objc_class_name_%s=0", class_name);
8127 assemble_asm (my_build_string (strlen (string) + 1, string));
8129 sprintf (string, ".globl .objc_class_name_%s", class_name);
8130 assemble_asm (my_build_string (strlen (string) + 1, string));
8135 sprintf (string, "%sobjc_class_name_%s",
8136 (flag_next_runtime ? "." : "__"), class_name);
8137 assemble_global (string);
8138 assemble_label (string);
8142 else if (TREE_CODE (impent->imp_context) == CATEGORY_IMPLEMENTATION_TYPE)
8144 char *class_name = IDENTIFIER_POINTER (CLASS_NAME (impent->imp_context));
8145 char *class_super_name
8146 = IDENTIFIER_POINTER (CLASS_SUPER_NAME (impent->imp_context));
8147 char *string = (char *) alloca (strlen (class_name)
8148 + strlen (class_super_name) + 30);
8150 /* Do the same for categories. Even though no references to these
8151 symbols are generated automatically by the compiler, it gives
8152 you a handle to pull them into an archive by hand. */
8153 if (flag_next_runtime)
8155 /* Grossly unportable. */
8156 sprintf (string, ".objc_category_name_%s_%s=0",
8157 class_name, class_super_name);
8158 assemble_asm (my_build_string (strlen (string) + 1, string));
8160 sprintf (string, ".globl .objc_category_name_%s_%s",
8161 class_name, class_super_name);
8162 assemble_asm (my_build_string (strlen (string) + 1, string));
8167 sprintf (string, "%sobjc_category_name_%s_%s",
8168 (flag_next_runtime ? "." : "__"),
8169 class_name, class_super_name);
8170 assemble_global (string);
8171 assemble_label (string);
8182 char *buf = (char *)xmalloc (256);
8184 { /* dump function prototypes */
8185 tree loop = UOBJC_MODULES_decl;
8187 fprintf (fp, "\n\nfunction prototypes:\n");
8190 if (TREE_CODE (loop) == FUNCTION_DECL && DECL_INITIAL (loop))
8192 /* We have a function definition: generate prototype. */
8193 bzero (errbuf, BUFSIZE);
8194 gen_declaration (loop, errbuf);
8195 fprintf (fp, "%s;\n", errbuf);
8197 loop = TREE_CHAIN (loop);
8201 /* Dump global chains. */
8203 int i, index = 0, offset = 0;
8206 for (i = 0; i < SIZEHASHTABLE; i++)
8208 if (hashlist = nst_method_hash_list[i])
8210 fprintf (fp, "\n\nnst_method_hash_list[%d]:\n", i);
8214 fprintf (fp, "-%s;\n", gen_method_decl (hashlist->key, buf));
8215 hashlist = hashlist->next;
8221 for (i = 0; i < SIZEHASHTABLE; i++)
8223 if (hashlist = cls_method_hash_list[i])
8225 fprintf (fp, "\n\ncls_method_hash_list[%d]:\n", i);
8229 fprintf (fp, "-%s;\n", gen_method_decl (hashlist->key, buf));
8230 hashlist = hashlist->next;
8236 fprintf (fp, "\nsel_refdef_chain:\n");
8237 for (loop = sel_refdef_chain; loop; loop = TREE_CHAIN (loop))
8239 fprintf (fp, "(index: %4d offset: %4d) %s\n", index, offset,
8240 IDENTIFIER_POINTER (TREE_VALUE (loop)));
8242 /* add one for the '\0' character */
8243 offset += IDENTIFIER_LENGTH (TREE_VALUE (loop)) + 1;
8246 fprintf (fp, "\n (max_selector_index: %4d.\n", max_selector_index);
8252 print_lang_statistics ()