1 /* Implement classes and message passing for Objective C.
2 Copyright (C) 1992 Free Software Foundation, Inc.
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, 675 Mass Ave, Cambridge, MA 02139, 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, OBJC_SELECTORS_WITHOUT_LABELS, NEXT_OBJC_RUNTIME
48 #include "objc-actions.h"
51 /* Define the special tree codes that we use. */
53 /* Table indexed by tree code giving a string containing a character
54 classifying the tree code. Possibilities are
55 t, d, s, c, r, <, 1 and 2. See objc-tree.def for details. */
57 #define DEFTREECODE(SYM, NAME, TYPE, LENGTH) TYPE,
59 char *objc_tree_code_type[] = {
61 #include "objc-tree.def"
65 /* Table indexed by tree code giving number of expression
66 operands beyond the fixed part of the node structure.
67 Not used for types or decls. */
69 #define DEFTREECODE(SYM, NAME, TYPE, LENGTH) LENGTH,
71 int objc_tree_code_length[] = {
73 #include "objc-tree.def"
77 /* Names of tree components.
78 Used for printing out the tree and error messages. */
79 #define DEFTREECODE(SYM, NAME, TYPE, LEN) NAME,
81 char *objc_tree_code_name[] = {
83 #include "objc-tree.def"
87 /* Set up for use of obstacks. */
91 #define obstack_chunk_alloc xmalloc
92 #define obstack_chunk_free free
94 /* This obstack is used to accumulate the encoding of a data type. */
95 static struct obstack util_obstack;
96 /* This points to the beginning of obstack contents,
97 so we can free the whole contents. */
100 /* for encode_method_def */
103 #define OBJC_VERSION 2
105 #define NULLT (tree) 0
107 #define OBJC_ENCODE_INLINE_DEFS 0
108 #define OBJC_ENCODE_DONT_INLINE_DEFS 1
110 /*** Private Interface (procedures) ***/
112 /* code generation */
114 static void synth_module_prologue ();
115 static char *build_module_descriptor ();
116 static tree init_module_descriptor ();
117 static void build_module_entry ();
118 static tree build_objc_method_call ();
119 static void build_message_selector_pool ();
120 static void build_selector_translation_table ();
121 static tree build_ivar_chain ();
123 static tree build_ivar_template ();
124 static tree build_method_template ();
125 static tree build_private_template ();
126 static void build_class_template ();
127 static void build_category_template ();
128 static tree build_super_template ();
130 static void synth_forward_declarations ();
131 static void generate_ivar_lists ();
132 static void generate_dispatch_tables ();
133 static void generate_shared_structures ();
135 static tree build_msg_pool_reference ();
136 static tree init_selector ();
137 static tree build_keword_selector ();
138 static tree synth_id_with_class_suffix ();
140 /* misc. bookkeeping */
142 typedef struct hashedEntry *hash;
143 typedef struct hashedAttribute *attr;
145 struct hashedAttribute {
154 static void hash_init ();
155 static void hash_enter ();
156 static hash hash_lookup ();
157 static void hash_add_attr ();
158 static tree lookup_method ();
159 static tree lookup_instance_method_static ();
160 static tree lookup_class_method_static ();
161 static tree add_class ();
162 static int add_selector_reference ();
163 static void add_class_reference ();
164 static int add_objc_string ();
168 static void encode_aggregate ();
169 static void encode_bitfield ();
170 static void encode_type ();
171 static void encode_field_decl ();
173 static void really_start_method ();
174 static int comp_method_with_proto ();
175 static int comp_proto_with_proto ();
176 static tree get_arg_type_list ();
177 static tree expr_last ();
179 /* utilities for debugging and error diagnostics: */
181 static void warn_with_method ();
182 static void error_with_method ();
183 static void error_with_ivar ();
184 static char *gen_method_decl ();
185 static char *gen_declaration ();
186 static char *gen_declarator ();
187 static int is_complex_decl ();
188 static void adorn_decl ();
189 static void dump_interfaces ();
191 /*** Private Interface (data) ***/
193 /* reserved tag definitions: */
196 #define TAG_OBJECT "objc_object"
197 #define TAG_CLASS "objc_class"
198 #define TAG_SUPER "objc_super"
199 #define TAG_SELECTOR "objc_selector"
201 #define _TAG_CLASS "_objc_class"
202 #define _TAG_IVAR "_objc_ivar"
203 #define _TAG_IVAR_LIST "_objc_ivar_list"
204 #define _TAG_METHOD "_objc_method"
205 #define _TAG_METHOD_LIST "_objc_method_list"
206 #define _TAG_CATEGORY "_objc_category"
207 #define _TAG_MODULE "_objc_module"
208 #define _TAG_SYMTAB "_objc_symtab"
209 #define _TAG_SUPER "_objc_super"
211 /* set by `continue_class ()' and checked by `is_public ()' */
213 #define TREE_STATIC_TEMPLATE(record_type) (TREE_PUBLIC(record_type))
214 #define TYPED_OBJECT(type) \
215 (TREE_CODE (type) == RECORD_TYPE && TREE_STATIC_TEMPLATE (type))
217 /* some commonly used instances of "identifier_node". */
219 static tree self_id, _cmd_id;
221 static tree self_decl, _msg_decl, _msgSuper_decl;
222 static tree objc_getClass_decl, objc_getMetaClass_decl;
224 static tree super_type, selector_type, id_type, class_type;
225 static tree instance_type;
227 static tree interface_chain = NULLT;
229 /* chains to manage selectors that are referenced and defined in the module */
231 static tree cls_ref_chain = NULLT; /* classes referenced */
232 static tree sel_ref_chain = NULLT; /* selectors referenced */
233 static tree sel_refdef_chain = NULLT; /* selectors references & defined */
234 static int max_selector_index; /* total # of selector referenced */
236 /* hash tables to manage the global pool of method prototypes */
238 static hash *nst_method_hash_list = 0;
239 static hash *cls_method_hash_list = 0;
241 /* the following are used when compiling a class implementation.
243 * implementation_template will normally be an anInterface, however if
244 * none exists this will be equal to implementation_context...it is
245 * set in start_class.
248 /* backend data declarations */
250 static tree _OBJC_SYMBOLS_decl;
251 static tree _OBJC_INSTANCE_VARIABLES_decl, _OBJC_CLASS_VARIABLES_decl;
252 static tree _OBJC_INSTANCE_METHODS_decl, _OBJC_CLASS_METHODS_decl;
253 static tree _OBJC_CLASS_decl, _OBJC_METACLASS_decl;
254 #ifdef OBJC_SELECTORS_WITHOUT_LABELS
255 static tree _OBJC_SELECTOR_REFERENCES_decl;
257 static tree _OBJC_MODULES_decl;
258 static tree _OBJC_STRINGS_decl;
260 static tree implementation_context = NULLT,
261 implementation_template = NULLT;
264 struct imp_entry *next;
267 tree class_decl; /* _OBJC_CLASS_<my_name>; */
268 tree meta_decl; /* _OBJC_METACLASS_<my_name>; */
270 static struct imp_entry *imp_list = 0;
271 static int imp_count = 0; /* `@implementation' */
272 static int cat_count = 0; /* `@category' */
274 static tree objc_class_template, objc_category_template, _PRIVATE_record;
275 static tree _clsSuper_ref, __clsSuper_ref;
277 static tree objc_method_template, objc_ivar_template;
278 static tree objc_symtab_template, objc_module_template;
279 static tree objc_super_template, objc_object_reference;
281 static tree objc_object_id, objc_class_id;
282 static tree _OBJC_SUPER_decl;
284 static tree method_context = NULLT;
285 static int method_slot = 0; /* used by start_method_def */
289 static char *errbuf; /* a buffer for error diagnostics */
291 extern char *strcpy (), *strcat ();
293 extern tree groktypename_in_parm_context ();
295 extern struct obstack permanent_obstack, *current_obstack, *rtl_obstack;
297 /* data imported from toplev.c */
299 extern char *dump_base_name;
301 /* Open and close the file for outputting class declarations, if requested. */
303 int flag_gen_declaration = 0;
305 FILE *gen_declaration_file;
307 /* Warn if multiple methods are seen for the same selector, but with
308 different argument types. */
310 int warn_selector = 0;
315 /* the beginning of the file is a new line; check for # */
316 /* With luck, we discover the real source file's name from that
317 and put it in input_filename. */
318 ungetc (check_newline (), finput);
320 /* If gen_declaration desired, open the output file. */
321 if (flag_gen_declaration)
323 int dump_base_name_length = strlen (dump_base_name);
324 register char *dumpname = (char *) xmalloc (dump_base_name_length + 7);
325 strcpy (dumpname, dump_base_name);
326 strcat (dumpname, ".decl");
327 gen_declaration_file = fopen (dumpname, "w");
328 if (gen_declaration_file == 0)
329 pfatal_with_name (dumpname);
332 if (doing_objc_thang)
339 if (doing_objc_thang)
340 finish_objc (); /* Objective-C finalization */
342 if (gen_declaration_file)
343 fclose (gen_declaration_file);
352 lang_decode_option (p)
355 if (!strcmp (p, "-lang-objc"))
356 doing_objc_thang = 1;
357 else if (!strcmp (p, "-gen-decls"))
358 flag_gen_declaration = 1;
359 else if (!strcmp (p, "-Wselector"))
361 else if (!strcmp (p, "-Wno-selector"))
364 return c_decode_option (p);
370 define_decl (declarator, declspecs)
374 tree decl = start_decl (declarator, declspecs, 0);
375 finish_decl (decl, NULLT, NULLT);
380 * rules for statically typed objects...called from `c-typeck.comptypes'.
382 * an assignment of the form `a' = `b' is permitted if:
384 * - `a' is of type "id".
385 * - `a' and `b' are the same class type.
386 * - `a' and `b' are of class types A and B such that B is a descendant
391 maybe_objc_comptypes (lhs, rhs)
394 if (doing_objc_thang)
395 return objc_comptypes (lhs, rhs);
400 objc_comptypes (lhs, rhs)
404 /* `id' = `<class> *', `<class> *' = `id' */
406 if ((TYPE_NAME (lhs) == objc_object_id && TYPED_OBJECT (rhs))
407 || (TYPED_OBJECT (lhs) && TYPE_NAME (rhs) == objc_object_id))
410 /* `id' = `Class', `Class' = `id' */
413 else if ((TYPE_NAME (lhs) == objc_object_id &&
414 TYPE_NAME (rhs) == objc_class_id) ||
415 (TYPE_NAME (lhs) == objc_class_id &&
416 TYPE_NAME (rhs) == objc_object_id))
419 /* `<class> *' = `<class> *' */
421 else if (TYPED_OBJECT (lhs) && TYPED_OBJECT (rhs))
423 tree lname = TYPE_NAME (lhs), rname = TYPE_NAME (rhs);
429 /* if the left hand side is a super class of the right hand side,
432 tree rinter = lookup_interface (rname);
436 if (lname == CLASS_SUPER_NAME (rinter))
439 rinter = lookup_interface (CLASS_SUPER_NAME (rinter));
449 /* Called from c-decl.c before all calls to rest_of_decl_compilation. */
452 maybe_objc_check_decl (decl)
455 if (doing_objc_thang)
456 objc_check_decl (decl);
460 objc_check_decl (decl)
463 tree type = TREE_TYPE (decl);
464 static int alreadyWarned = 0;
466 if (TREE_CODE (type) == RECORD_TYPE && TREE_STATIC_TEMPLATE (type))
470 error ("GNU compiler does not support statically allocated objects");
473 error_with_decl (decl, "`%s' cannot be statically allocated");
477 /* implement static typing. at this point, we know we have an interface... */
480 get_static_reference (interface)
483 return xref_tag (RECORD_TYPE, CLASS_NAME (interface));
486 /* Create and push a decl for a built-in external variable or field NAME.
488 TYPE is its data type. */
491 create_builtin_decl (code, type, name)
496 tree decl = build_decl (code, get_identifier (name), type);
497 if (code == VAR_DECL)
499 TREE_STATIC (decl) = 1;
500 make_decl_rtl (decl, 0, 1);
507 * purpose: "play" parser, creating/installing representations
508 * of the declarations that are required by Objective-C.
512 * type_spec--------->sc_spec
513 * (tree_list) (tree_list)
516 * identifier_node identifier_node
519 synth_module_prologue ()
521 tree expr_decl, temp_type;
523 /* defined in `objc.h' */
524 objc_object_id = get_identifier (TAG_OBJECT);
526 objc_object_reference = xref_tag (RECORD_TYPE, objc_object_id);
528 id_type = build_pointer_type (objc_object_reference);
530 objc_class_id = get_identifier (TAG_CLASS);
532 class_type = build_pointer_type (xref_tag (RECORD_TYPE, objc_class_id));
534 /* Declare type of selector-objects that represent an operation name. */
536 #ifdef OBJC_INT_SELECTORS
538 selector_type = unsigned_type_node;
540 /* `struct objc_selector *' */
542 = build_pointer_type (xref_tag (RECORD_TYPE,
543 get_identifier (TAG_SELECTOR)));
544 #endif /* not OBJC_INT_SELECTORS */
546 /* struct objc_object *objc_msgSend (id, SEL, ...); */
549 = build_function_type (id_type,
550 tree_cons (NULL_TREE, id_type,
551 tree_cons (NULLT, selector_type, NULLT)));
553 _msg_decl = builtin_function ("objc_msgSend", temp_type, NOT_BUILT_IN, 0);
555 /* struct objc_object *objc_msgSendSuper (void *, SEL, ...); */
558 = build_function_type (id_type,
559 tree_cons (NULL_TREE, ptr_type_node,
560 tree_cons (NULLT, selector_type, NULLT)));
562 _msgSuper_decl = builtin_function ("objc_msgSendSuper",
563 temp_type, NOT_BUILT_IN, 0);
565 /* id objc_getClass (); */
567 temp_type = build_function_type (id_type, NULLT);
570 = builtin_function ("objc_getClass", temp_type, NOT_BUILT_IN, 0);
572 /* id objc_getMetaClass (); */
574 objc_getMetaClass_decl
575 = builtin_function ("objc_getMetaClass", temp_type, NOT_BUILT_IN, 0);
577 /* extern SEL _OBJC_SELECTOR_REFERENCES[]; */
579 #ifdef OBJC_SELECTORS_WITHOUT_LABELS
580 _OBJC_SELECTOR_REFERENCES_decl
581 = create_builtin_decl (VAR_DECL, build_array_type (selector_type, NULLT),
582 "_OBJC_SELECTOR_REFERENCES");
587 * custom "build_string ()" which sets TREE_TYPE!
590 my_build_string (len, str)
595 tree aString = build_string (len, str);
597 * some code from "combine_strings ()", which is local to c-parse.y.
599 if (TREE_TYPE (aString) == int_array_type_node)
602 TREE_TYPE (aString) =
603 build_array_type (wide_flag ? integer_type_node : char_type_node,
604 build_index_type (build_int_2 (len - 1, 0)));
606 TREE_CONSTANT (aString) = 1; /* puts string in the ".text" segment */
607 TREE_STATIC (aString) = 1;
612 /* Take care of defining and initializing _OBJC_SYMBOLS. */
614 /* Predefine the following data type:
616 struct _objc_symtab {
621 void *defs[cls_def_cnt + cat_def_cnt];
625 build_objc_symtab_template ()
627 tree field_decl, field_decl_chain, index;
629 objc_symtab_template = start_struct (RECORD_TYPE, get_identifier (_TAG_SYMTAB));
631 /* long sel_ref_cnt; */
633 field_decl = create_builtin_decl (FIELD_DECL,
634 long_integer_type_node,
636 field_decl_chain = field_decl;
640 field_decl = create_builtin_decl (FIELD_DECL,
641 build_pointer_type (selector_type),
643 chainon (field_decl_chain, field_decl);
645 /* short cls_def_cnt; */
647 field_decl = create_builtin_decl (FIELD_DECL,
648 short_integer_type_node,
650 chainon (field_decl_chain, field_decl);
652 /* short cat_def_cnt; */
654 field_decl = create_builtin_decl (FIELD_DECL,
655 short_integer_type_node,
657 chainon (field_decl_chain, field_decl);
659 /* void *defs[cls_def_cnt + cat_def_cnt]; */
661 index = build_index_type (build_int_2 (imp_count + cat_count - 1, 0));
662 field_decl = create_builtin_decl (FIELD_DECL,
663 build_array_type (ptr_type_node, index),
665 chainon (field_decl_chain, field_decl);
667 finish_struct (objc_symtab_template, field_decl_chain);
670 /* Create the initial value for the `defs' field of _objc_symtab.
671 This is a CONSTRUCTOR. */
676 tree expr, initlist = NULLT;
677 struct imp_entry *impent;
680 for (impent = imp_list; impent; impent = impent->next)
682 if (TREE_CODE (impent->imp_context) == IMPLEMENTATION_TYPE)
684 expr = build_unary_op (ADDR_EXPR, impent->class_decl, 0);
685 initlist = tree_cons (NULLT, expr, initlist);
690 for (impent = imp_list; impent; impent = impent->next)
692 if (TREE_CODE (impent->imp_context) == CATEGORY_TYPE)
694 expr = build_unary_op (ADDR_EXPR, impent->class_decl, 0);
695 initlist = tree_cons (NULLT, expr, initlist);
698 return build_nt (CONSTRUCTOR, NULLT, nreverse (initlist));
701 /* Construct the initial value for all of _objc_symtab. */
708 /* sel_ref_cnt = { ..., 5, ... } */
711 initlist = build_tree_list (NULLT, build_int_2 (max_selector_index, 0));
713 initlist = build_tree_list (NULLT, build_int_2 (0, 0));
715 /* refs = { ..., _OBJC_SELECTOR_REFERENCES, ... } */
717 #ifndef OBJC_SELECTORS_WITHOUT_LABELS
718 initlist = tree_cons (NULLT, build_int_2 (0, 0), initlist);
721 initlist = tree_cons (NULLT, _OBJC_SELECTOR_REFERENCES_decl, initlist);
723 initlist = tree_cons (NULLT, build_int_2 (0, 0), initlist);
726 /* cls_def_cnt = { ..., 5, ... } */
728 initlist = tree_cons (NULLT, build_int_2 (imp_count, 0), initlist);
730 /* cat_def_cnt = { ..., 5, ... } */
732 initlist = tree_cons (NULLT, build_int_2 (cat_count, 0), initlist);
734 /* cls_def = { ..., { &Foo, &Bar, ...}, ... } */
736 if (imp_count || cat_count)
737 initlist = tree_cons (NULLT, init_def_list (), initlist);
739 return build_nt (CONSTRUCTOR, NULLT, nreverse (initlist));
742 /* Push forward-declarations of all the categories
743 so that init_def_list can use them in a CONSTRUCTOR. */
746 forward_declare_categories ()
748 struct imp_entry *impent;
749 tree sav = implementation_context;
750 for (impent = imp_list; impent; impent = impent->next)
752 if (TREE_CODE (impent->imp_context) == CATEGORY_TYPE)
754 /* Set an invisible arg to synth_id_with_class_suffix. */
755 implementation_context = impent->imp_context;
757 = create_builtin_decl (VAR_DECL, objc_category_template,
758 IDENTIFIER_POINTER (synth_id_with_class_suffix ("_OBJC_CATEGORY")));
761 implementation_context = sav;
764 /* Create the declaration of _OBJC_SYMBOLS, with type `strict _objc_symtab'
765 and initialized appropriately. */
768 generate_objc_symtab_decl ()
772 if (!objc_category_template)
773 build_category_template ();
775 /* forward declare categories */
777 forward_declare_categories ();
779 if (!objc_symtab_template)
780 build_objc_symtab_template ();
782 sc_spec = build_tree_list (NULLT, ridpointers[(int) RID_STATIC]);
784 _OBJC_SYMBOLS_decl = start_decl (get_identifier ("_OBJC_SYMBOLS"),
785 tree_cons (NULLT, objc_symtab_template, sc_spec), 1);
787 finish_decl (_OBJC_SYMBOLS_decl, init_objc_symtab (), NULLT);
791 * tree_node------->tree_node----->...
793 * | (value) | (value)
798 init_module_descriptor ()
802 /* version = { 1, ... } */
804 expr = build_int_2 (OBJC_VERSION, 0);
805 initlist = build_tree_list (NULLT, expr);
807 /* size = { ..., sizeof (struct objc_module), ... } */
809 expr = build_int_2 (TREE_INT_CST_LOW (TYPE_SIZE (objc_module_template)) /
811 initlist = tree_cons (NULLT, expr, initlist);
813 /* name = { ..., "foo.m", ... } */
815 expr = build_msg_pool_reference (
816 add_objc_string (get_identifier (input_filename)));
817 initlist = tree_cons (NULLT, expr, initlist);
819 /* symtab = { ..., _OBJC_SYMBOLS, ... } */
821 if (_OBJC_SYMBOLS_decl)
822 expr = build_unary_op (ADDR_EXPR, _OBJC_SYMBOLS_decl, 0);
824 expr = build_int_2 (0, 0);
825 initlist = tree_cons (NULLT, expr, initlist);
827 return build_nt (CONSTRUCTOR, NULLT, nreverse (initlist));
830 /* Write out the data structures to describe Objective C classes defined.
831 If appropriate, compile and output a setup function to initialize them.
832 Return a string which is the name of a function to call to initialize
833 the Objective C data structures for this file (and perhaps for other files
837 build_module_descriptor ()
839 tree decl_specs, field_decl, field_decl_chain;
841 objc_module_template = start_struct (RECORD_TYPE, get_identifier (_TAG_MODULE));
845 decl_specs = build_tree_list (NULLT, ridpointers[(int) RID_LONG]);
846 field_decl = get_identifier ("version");
847 field_decl = grokfield (input_filename, lineno, field_decl, decl_specs, NULLT);
848 field_decl_chain = field_decl;
852 decl_specs = build_tree_list (NULLT, ridpointers[(int) RID_LONG]);
853 field_decl = get_identifier ("size");
854 field_decl = grokfield (input_filename, lineno, field_decl, decl_specs, NULLT);
855 chainon (field_decl_chain, field_decl);
859 decl_specs = build_tree_list (NULLT, ridpointers[(int) RID_CHAR]);
860 field_decl = build1 (INDIRECT_REF, NULLT, get_identifier ("name"));
861 field_decl = grokfield (input_filename, lineno, field_decl, decl_specs, NULLT);
862 chainon (field_decl_chain, field_decl);
864 /* struct objc_symtab *symtab; */
866 decl_specs = get_identifier (_TAG_SYMTAB);
867 decl_specs = build_tree_list (NULLT, xref_tag (RECORD_TYPE, decl_specs));
868 field_decl = build1 (INDIRECT_REF, NULLT, get_identifier ("symtab"));
869 field_decl = grokfield (input_filename, lineno, field_decl, decl_specs, NULLT);
870 chainon (field_decl_chain, field_decl);
872 finish_struct (objc_module_template, field_decl_chain);
874 /* create an instance of "objc_module" */
876 decl_specs = tree_cons (NULLT, objc_module_template,
877 build_tree_list (NULLT, ridpointers[(int) RID_STATIC]));
879 _OBJC_MODULES_decl = start_decl (get_identifier ("_OBJC_MODULES"),
882 finish_decl (_OBJC_MODULES_decl, init_module_descriptor (), NULLT);
884 /* Mark the decl to avoid "defined but not used" warning. */
885 DECL_IN_SYSTEM_HEADER (_OBJC_MODULES_decl) = 1;
887 /* Generate a constructor call for the module descriptor.
888 This code was generated by reading the grammar rules
889 of c-parse.y; Therefore, it may not be the most efficient
890 way of generating the requisite code. */
891 #ifndef NEXT_OBJC_RUNTIME
893 tree parms, function_decl, decelerator, void_list_node;
896 char *global_object_name = 0;
899 /* Use a global object (which is already required to be unique over
900 the program) rather than the file name (which imposes extra
901 constraints). -- Raeburn@MIT.EDU, 10 Jan 1990. */
903 /* Find the name of some global object defined in this file. */
904 for (t = getdecls (); t; t = TREE_CHAIN (t))
905 if (TREE_PUBLIC (t) && !DECL_EXTERNAL (t) && DECL_INITIAL (t) != 0)
907 global_object_name = IDENTIFIER_POINTER (DECL_NAME (t));
911 /* If none, use the name of the file. */
912 if (!global_object_name)
916 = (char *) alloca (strlen (main_input_filename) + 1);
918 p = main_input_filename;
919 q = global_object_name;
921 /* Replace any weird characters in the file name. */
923 if (! ((*p >= '0' && *p <= '9')
924 || (*p >= 'A' && *p <= 'Z')
925 || (*p >= 'a' && *p <= 'z')))
932 /* Make the constructor name from the name we have found. */
933 buf = (char *) xmalloc (sizeof (CONSTRUCTOR_NAME_FORMAT)
934 + strlen (global_object_name));
935 sprintf (buf, CONSTRUCTOR_NAME_FORMAT, global_object_name);
937 /* Declare void __objc_execClass (void*); */
939 void_list_node = build_tree_list (NULL_TREE, void_type_node);
941 = build_function_type (void_type_node,
942 tree_cons (NULL_TREE, ptr_type_node,
944 function_decl = build_decl (FUNCTION_DECL,
945 get_identifier ("__objc_execClass"),
947 DECL_EXTERNAL (function_decl) = 1;
948 TREE_PUBLIC (function_decl) = 1;
949 pushdecl (function_decl);
950 rest_of_decl_compilation (function_decl, 0, 0, 0);
953 = build_tree_list (NULLT,
954 build_unary_op (ADDR_EXPR, _OBJC_MODULES_decl, 0));
955 decelerator = build_function_call (function_decl, parms);
957 /* void __objc_file_init () {objc_execClass(&L_OBJC_MODULES);} */
959 start_function (void_list_node,
960 build_parse_node (CALL_EXPR, get_identifier (buf),
961 /* This has the format of the output
963 tree_cons (NULL_TREE, NULL_TREE,
967 #if 0 /* This should be turned back on later
968 for the systems where collect is not needed. */
969 /* Make these functions nonglobal
970 so each file can use the same name. */
971 TREE_PUBLIC (current_function_decl) = 0;
973 TREE_USED (current_function_decl) = 1;
976 assemble_external (function_decl);
977 c_expand_expr_stmt (decelerator);
981 /* Return the name of the constructor function. */
984 #else /* NEXT_OBJC_RUNTIME */
986 #endif /* NEXT_OBJC_RUNTIME */
989 /* extern const char _OBJC_STRINGS[]; */
992 generate_forward_declaration_to_string_table ()
994 tree sc_spec, decl_specs, expr_decl;
996 sc_spec = tree_cons (NULLT, ridpointers[(int) RID_EXTERN], NULLT);
997 decl_specs = tree_cons (NULLT, ridpointers[(int) RID_CHAR], sc_spec);
999 expr_decl = build_nt (ARRAY_REF, get_identifier ("_OBJC_STRINGS"), NULLT);
1001 _OBJC_STRINGS_decl = define_decl (expr_decl, decl_specs);
1004 /* static char _OBJC_STRINGS[] = "..."; */
1007 build_message_selector_pool ()
1009 tree sc_spec, decl_specs, expr_decl;
1010 tree chain, string_expr;
1011 int goolengthtmp = 0, msg_pool_size = 0;
1014 sc_spec = tree_cons (NULLT, ridpointers[(int) RID_STATIC], NULLT);
1015 decl_specs = tree_cons (NULLT, ridpointers[(int) RID_CHAR], sc_spec);
1017 expr_decl = build_nt (ARRAY_REF, get_identifier ("_OBJC_STRINGS"), NULLT);
1019 _OBJC_STRINGS_decl = start_decl (expr_decl, decl_specs, 1);
1021 for (chain = sel_refdef_chain; chain; chain = TREE_CHAIN (chain))
1022 msg_pool_size += IDENTIFIER_LENGTH (TREE_VALUE (chain)) + 1;
1026 string_goo = (char *)xmalloc (msg_pool_size);
1027 bzero (string_goo, msg_pool_size);
1029 for (chain = sel_refdef_chain; chain; chain = TREE_CHAIN (chain))
1031 strcpy (string_goo + goolengthtmp, IDENTIFIER_POINTER (TREE_VALUE (chain)));
1032 goolengthtmp += IDENTIFIER_LENGTH (TREE_VALUE (chain)) + 1;
1035 string_expr = my_build_string (msg_pool_size, string_goo);
1037 finish_decl (_OBJC_STRINGS_decl, string_expr, NULLT);
1041 * synthesize the following expr: (char *)&_OBJC_STRINGS[<offset>]
1043 * the cast stops the compiler from issuing the following message:
1045 * grok.m: warning: initialization of non-const * pointer from const *
1046 * grok.m: warning: initialization between incompatible pointer types
1049 build_msg_pool_reference (offset)
1052 tree expr = build_int_2 (offset, 0);
1055 expr = build_array_ref (_OBJC_STRINGS_decl, expr);
1056 expr = build_unary_op (ADDR_EXPR, expr, 0);
1058 cast = build_tree_list (build_tree_list (NULLT, ridpointers[(int) RID_CHAR]),
1059 build1 (INDIRECT_REF, NULLT, NULLT));
1060 TREE_TYPE (expr) = groktypename (cast);
1064 #ifndef OBJC_SELECTORS_WITHOUT_LABELS
1066 build_selector_reference (idx)
1069 tree ref, decl, name, ident;
1071 struct obstack *save_current_obstack = current_obstack;
1072 struct obstack *save_rtl_obstack = rtl_obstack;
1074 sprintf (buf, "_OBJC_SELECTOR_REFERENCES_%d", idx);
1077 rtl_obstack = current_obstack = &permanent_obstack;
1078 ident = get_identifier (buf);
1080 if (IDENTIFIER_GLOBAL_VALUE (ident))
1081 decl = IDENTIFIER_GLOBAL_VALUE (ident); /* set by pushdecl() */
1084 decl = build_decl (VAR_DECL, ident, selector_type);
1085 DECL_EXTERNAL (decl) = 1;
1086 TREE_PUBLIC (decl) = 1;
1087 TREE_USED (decl) = 1;
1089 make_decl_rtl (decl, 0, 1); /* usually called from `rest_of_decl_compilation' */
1090 pushdecl_top_level (decl); /* our `extended/custom' pushdecl in c-decl.c */
1092 current_obstack = save_current_obstack;
1093 rtl_obstack = save_rtl_obstack;
1100 init_selector (offset)
1103 tree expr = build_msg_pool_reference (offset);
1104 TREE_TYPE (expr) = selector_type; /* cast */
1109 build_selector_translation_table ()
1111 tree sc_spec, decl_specs, expr_decl;
1112 tree chain, initlist = NULLT;
1114 #ifndef OBJC_SELECTORS_WITHOUT_LABELS
1115 tree decl, var_decl;
1119 /* The corresponding pop_obstacks is in finish_decl,
1120 called at the end of this function. */
1121 push_obstacks_nochange ();
1124 for (chain = sel_ref_chain; chain; chain = TREE_CHAIN (chain))
1128 #ifndef OBJC_SELECTORS_WITHOUT_LABELS
1129 sprintf (buf, "_OBJC_SELECTOR_REFERENCES_%d", idx);
1130 sc_spec = build_tree_list (NULLT, ridpointers[(int) RID_STATIC]);
1132 /* static SEL _OBJC_SELECTOR_REFERENCES_n = ...; */
1133 decl_specs = tree_cons (NULLT, selector_type, sc_spec);
1134 var_decl = get_identifier (buf);
1136 /* the `decl' that is returned from start_decl is the one that we
1137 * forward declared in `build_selector_reference()'
1139 decl = start_decl (var_decl, decl_specs, 1);
1142 expr = init_selector (offset);
1144 /* add one for the '\0' character */
1145 offset += IDENTIFIER_LENGTH (TREE_VALUE (chain)) + 1;
1147 #ifndef OBJC_SELECTORS_WITHOUT_LABELS
1148 finish_decl (decl, expr, NULLT);
1151 initlist = tree_cons (NULLT, expr, initlist);
1155 #ifdef OBJC_SELECTORS_WITHOUT_LABELS
1156 /* Cause the variable and its initial value to be actually output. */
1157 DECL_EXTERNAL (_OBJC_SELECTOR_REFERENCES_decl) = 0;
1158 TREE_STATIC (_OBJC_SELECTOR_REFERENCES_decl) = 1;
1159 /* NULL terminate the list and fix the decl for output. */
1160 initlist = tree_cons (NULLT, build_int_2 (0, 0), initlist);
1161 DECL_INITIAL (_OBJC_SELECTOR_REFERENCES_decl) = (tree) 1;
1162 initlist = build_nt (CONSTRUCTOR, NULLT, nreverse (initlist));
1163 finish_decl (_OBJC_SELECTOR_REFERENCES_decl, initlist, NULLT);
1168 add_class_reference (ident)
1173 if (chain = cls_ref_chain)
1178 if (ident == TREE_VALUE (chain))
1182 chain = TREE_CHAIN (chain);
1186 /* append to the end of the list */
1187 TREE_CHAIN (tail) = perm_tree_cons (NULLT, ident, NULLT);
1190 cls_ref_chain = perm_tree_cons (NULLT, ident, NULLT);
1194 * sel_ref_chain is a list whose "value" fields will be instances of
1195 * identifier_node that represent the selector.
1198 add_selector_reference (ident)
1204 /* this adds it to sel_refdef_chain, the global pool of selectors */
1205 add_objc_string (ident);
1207 if (chain = sel_ref_chain)
1212 if (ident == TREE_VALUE (chain))
1217 chain = TREE_CHAIN (chain);
1221 /* append to the end of the list */
1222 TREE_CHAIN (tail) = perm_tree_cons (NULLT, ident, NULLT);
1225 sel_ref_chain = perm_tree_cons (NULLT, ident, NULLT);
1227 max_selector_index++;
1232 * sel_refdef_chain is a list whose "value" fields will be instances of
1233 * identifier_node that represent the selector. It returns the offset of
1234 * the selector from the beginning of the _OBJC_STRINGS pool. This offset
1235 * is typically used by "init_selector ()" during code generation.
1238 add_objc_string (ident)
1244 if (chain = sel_refdef_chain)
1249 if (ident == TREE_VALUE (chain))
1252 /* add one for the '\0' character */
1253 offset += IDENTIFIER_LENGTH (TREE_VALUE (chain)) + 1;
1255 chain = TREE_CHAIN (chain);
1259 /* append to the end of the list */
1260 TREE_CHAIN (tail) = perm_tree_cons (NULLT, ident, NULLT);
1263 sel_refdef_chain = perm_tree_cons (NULLT, ident, NULLT);
1269 lookup_interface (ident)
1274 for (chain = interface_chain; chain; chain = TREE_CHAIN (chain))
1276 if (ident == CLASS_NAME (chain))
1283 objc_copy_list (list, head)
1287 tree newlist = NULL_TREE, tail = NULL_TREE;
1291 tail = copy_node (list);
1293 /* the following statement fixes a bug when inheriting instance
1294 variables that are declared to be bitfields. finish_struct () expects
1295 to find the width of the bitfield in DECL_INITIAL (), which it
1296 nulls out after processing the decl of the super class...rather
1297 than change the way finish_struct () works (which is risky),
1298 I create the situation it expects...s.naroff (7/23/89).
1300 if (DECL_BIT_FIELD (tail) && DECL_INITIAL (tail) == 0)
1301 DECL_INITIAL (tail) = build_int_2 (DECL_FIELD_SIZE (tail), 0);
1303 newlist = chainon (newlist, tail);
1304 list = TREE_CHAIN (list);
1311 * build_private_template (), get_class_ivars (), and get_static_reference ().
1314 build_ivar_chain (interface)
1317 tree my_name, super_name, ivar_chain;
1319 my_name = CLASS_NAME (interface);
1320 super_name = CLASS_SUPER_NAME (interface);
1322 /* "leaf" ivars never get copied...there is no reason to. */
1323 ivar_chain = CLASS_IVARS (interface);
1328 tree super_interface = lookup_interface (super_name);
1330 if (!super_interface)
1332 /* fatal did not work with 2 args...should fix */
1333 error ("Cannot find interface declaration for `%s', superclass of `%s'",
1334 IDENTIFIER_POINTER (super_name), IDENTIFIER_POINTER (my_name));
1337 if (super_interface == interface)
1339 fatal ("Circular inheritance in interface declaration for `%s'",
1340 IDENTIFIER_POINTER (super_name));
1342 interface = super_interface;
1343 my_name = CLASS_NAME (interface);
1344 super_name = CLASS_SUPER_NAME (interface);
1346 op1 = CLASS_IVARS (interface);
1349 tree head, tail = objc_copy_list (op1, &head);
1351 /* prepend super class ivars...make a copy of the list, we
1352 * do not want to alter the original.
1354 TREE_CHAIN (tail) = ivar_chain;
1362 * struct <classname> {
1363 * struct objc_class *isa;
1368 build_private_template (class)
1373 if (CLASS_STATIC_TEMPLATE (class))
1375 _PRIVATE_record = CLASS_STATIC_TEMPLATE (class);
1376 ivar_context = TYPE_FIELDS (CLASS_STATIC_TEMPLATE (class));
1380 _PRIVATE_record = start_struct (RECORD_TYPE, CLASS_NAME (class));
1382 ivar_context = build_ivar_chain (class);
1384 finish_struct (_PRIVATE_record, ivar_context);
1386 CLASS_STATIC_TEMPLATE (class) = _PRIVATE_record;
1388 /* mark this record as class template - for class type checking */
1389 TREE_STATIC_TEMPLATE (_PRIVATE_record) = 1;
1391 instance_type = groktypename (
1392 build_tree_list (build_tree_list (NULLT, _PRIVATE_record),
1393 build1 (INDIRECT_REF, NULLT, NULLT)));
1394 return ivar_context;
1398 * struct objc_category {
1399 * char *category_name;
1401 * struct objc_method_list *instance_methods;
1402 * struct objc_method_list *class_methods;
1406 build_category_template ()
1408 tree decl_specs, field_decl, field_decl_chain;
1410 objc_category_template = start_struct (RECORD_TYPE,
1411 get_identifier (_TAG_CATEGORY));
1412 /* char *category_name; */
1414 decl_specs = build_tree_list (NULLT, ridpointers[(int) RID_CHAR]);
1415 field_decl = build1 (INDIRECT_REF, NULLT, get_identifier ("category_name"));
1416 field_decl = grokfield (input_filename, lineno, field_decl, decl_specs, NULLT);
1417 field_decl_chain = field_decl;
1419 /* char *class_name; */
1421 decl_specs = build_tree_list (NULLT, ridpointers[(int) RID_CHAR]);
1422 field_decl = build1 (INDIRECT_REF, NULLT, get_identifier ("class_name"));
1423 field_decl = grokfield (input_filename, lineno, field_decl, decl_specs, NULLT);
1424 chainon (field_decl_chain, field_decl);
1426 /* struct objc_method_list *instance_methods; */
1428 decl_specs = build_tree_list (NULLT, xref_tag (RECORD_TYPE,
1429 get_identifier (_TAG_METHOD_LIST)));
1430 field_decl = build1 (INDIRECT_REF, NULLT, get_identifier ("instance_methods"));
1431 field_decl = grokfield (input_filename, lineno, field_decl, decl_specs, NULLT);
1432 chainon (field_decl_chain, field_decl);
1434 /* struct objc_method_list *class_methods; */
1436 decl_specs = build_tree_list (NULLT, xref_tag (RECORD_TYPE,
1437 get_identifier (_TAG_METHOD_LIST)));
1438 field_decl = build1 (INDIRECT_REF, NULLT, get_identifier ("class_methods"));
1439 field_decl = grokfield (input_filename, lineno, field_decl, decl_specs, NULLT);
1440 chainon (field_decl_chain, field_decl);
1442 finish_struct (objc_category_template, field_decl_chain);
1446 * struct objc_class {
1447 * struct objc_class *isa;
1448 * struct objc_class *super_class;
1452 * long instance_size;
1453 * struct objc_ivar_list *ivars;
1454 * struct objc_method_list *methods;
1455 * struct objc_cache *cache;
1459 build_class_template ()
1461 tree decl_specs, field_decl, field_decl_chain;
1463 objc_class_template = start_struct (RECORD_TYPE, get_identifier (_TAG_CLASS));
1465 /* struct objc_class *isa; */
1467 decl_specs = build_tree_list (NULLT, objc_class_template);
1468 field_decl = build1 (INDIRECT_REF, NULLT, get_identifier ("isa"));
1469 field_decl = grokfield (input_filename, lineno, field_decl, decl_specs, NULLT);
1470 field_decl_chain = field_decl;
1472 /* struct objc_class *super_class; */
1474 decl_specs = build_tree_list (NULLT, objc_class_template);
1475 field_decl = build1 (INDIRECT_REF, NULLT, get_identifier ("super_class"));
1476 field_decl = grokfield (input_filename, lineno, field_decl, decl_specs, NULLT);
1477 chainon (field_decl_chain, field_decl);
1481 decl_specs = build_tree_list (NULLT, ridpointers[(int) RID_CHAR]);
1482 field_decl = build1 (INDIRECT_REF, NULLT, get_identifier ("name"));
1483 field_decl = grokfield (input_filename, lineno, field_decl, decl_specs, NULLT);
1484 chainon (field_decl_chain, field_decl);
1488 decl_specs = build_tree_list (NULLT, ridpointers[(int) RID_LONG]);
1489 field_decl = get_identifier ("version");
1490 field_decl = grokfield (input_filename, lineno, field_decl, decl_specs, NULLT);
1491 chainon (field_decl_chain, field_decl);
1495 decl_specs = build_tree_list (NULLT, ridpointers[(int) RID_LONG]);
1496 field_decl = get_identifier ("info");
1497 field_decl = grokfield (input_filename, lineno, field_decl, decl_specs, NULLT);
1498 chainon (field_decl_chain, field_decl);
1500 /* long instance_size; */
1502 decl_specs = build_tree_list (NULLT, ridpointers[(int) RID_LONG]);
1503 field_decl = get_identifier ("instance_size");
1504 field_decl = grokfield (input_filename, lineno, field_decl, decl_specs, NULLT);
1505 chainon (field_decl_chain, field_decl);
1507 /* struct objc_ivar_list *ivars; */
1509 decl_specs = build_tree_list (NULLT, xref_tag (RECORD_TYPE,
1510 get_identifier (_TAG_IVAR_LIST)));
1511 field_decl = build1 (INDIRECT_REF, NULLT, get_identifier ("ivars"));
1512 field_decl = grokfield (input_filename, lineno, field_decl, decl_specs, NULLT);
1513 chainon (field_decl_chain, field_decl);
1515 /* struct objc_method_list *methods; */
1517 decl_specs = build_tree_list (NULLT, xref_tag (RECORD_TYPE,
1518 get_identifier (_TAG_METHOD_LIST)));
1519 field_decl = build1 (INDIRECT_REF, NULLT, get_identifier ("methods"));
1520 field_decl = grokfield (input_filename, lineno, field_decl, decl_specs, NULLT);
1521 chainon (field_decl_chain, field_decl);
1523 /* struct objc_cache *cache; */
1525 decl_specs = build_tree_list (NULLT, xref_tag (RECORD_TYPE,
1526 get_identifier ("objc_cache")));
1527 field_decl = build1 (INDIRECT_REF, NULLT, get_identifier ("cache"));
1528 field_decl = grokfield (input_filename, lineno, field_decl, decl_specs, NULLT);
1529 chainon (field_decl_chain, field_decl);
1531 finish_struct (objc_class_template, field_decl_chain);
1535 * generate appropriate forward declarations for an implementation
1538 synth_forward_declarations ()
1540 tree sc_spec, decl_specs, factory_id, anId;
1542 /* extern struct objc_class _OBJC_CLASS_<my_name>; */
1544 anId = synth_id_with_class_suffix ("_OBJC_CLASS");
1546 sc_spec = build_tree_list (NULLT, ridpointers[(int) RID_EXTERN]);
1547 decl_specs = tree_cons (NULLT, objc_class_template, sc_spec);
1548 _OBJC_CLASS_decl = define_decl (anId, decl_specs);
1550 /* extern struct objc_class _OBJC_METACLASS_<my_name>; */
1552 anId = synth_id_with_class_suffix ("_OBJC_METACLASS");
1554 _OBJC_METACLASS_decl = define_decl (anId, decl_specs);
1556 /* pre-build the following entities - for speed/convenience. */
1558 anId = get_identifier ("super_class");
1559 _clsSuper_ref = build_component_ref (_OBJC_CLASS_decl, anId);
1560 __clsSuper_ref = build_component_ref (_OBJC_METACLASS_decl, anId);
1564 error_with_ivar (message, decl, rawdecl)
1570 fprintf (stderr, "%s:%d: ",
1571 DECL_SOURCE_FILE (decl), DECL_SOURCE_LINE (decl));
1572 bzero (errbuf, BUFSIZE);
1573 fprintf (stderr, "%s `%s'\n", message, gen_declaration (rawdecl, errbuf));
1576 #define USERTYPE(t) (TREE_CODE (t) == RECORD_TYPE || \
1577 TREE_CODE (t) == UNION_TYPE || \
1578 TREE_CODE (t) == ENUMERAL_TYPE)
1581 check_ivars (inter, imp)
1585 tree intdecls = CLASS_IVARS (inter);
1586 tree impdecls = CLASS_IVARS (imp);
1587 tree rawintdecls = CLASS_RAW_IVARS (inter);
1588 tree rawimpdecls = CLASS_RAW_IVARS (imp);
1594 if (intdecls == 0 && impdecls == 0)
1596 if (intdecls == 0 || impdecls == 0)
1598 error ("inconsistent instance variable specification");
1601 t1 = TREE_TYPE (intdecls); t2 = TREE_TYPE (impdecls);
1603 if (!comptypes (t1, t2))
1605 if (DECL_NAME (intdecls) == DECL_NAME (impdecls))
1607 error_with_ivar ("conflicting instance variable type",
1608 impdecls, rawimpdecls);
1609 error_with_ivar ("previous declaration of",
1610 intdecls, rawintdecls);
1612 else /* both the type and the name don't match */
1614 error ("inconsistent instance variable specification");
1618 else if (DECL_NAME (intdecls) != DECL_NAME (impdecls))
1620 error_with_ivar ("conflicting instance variable name",
1621 impdecls, rawimpdecls);
1622 error_with_ivar ("previous declaration of",
1623 intdecls, rawintdecls);
1625 intdecls = TREE_CHAIN (intdecls);
1626 impdecls = TREE_CHAIN (impdecls);
1627 rawintdecls = TREE_CHAIN (rawintdecls);
1628 rawimpdecls = TREE_CHAIN (rawimpdecls);
1633 * struct objc_super {
1635 * struct objc_class *class;
1639 build_super_template ()
1641 tree record, decl_specs, field_decl, field_decl_chain;
1643 record = start_struct (RECORD_TYPE, get_identifier (_TAG_SUPER));
1645 /* struct objc_object *self; */
1647 decl_specs = build_tree_list (NULLT, objc_object_reference);
1648 field_decl = get_identifier ("self");
1649 field_decl = build1 (INDIRECT_REF, NULLT, field_decl);
1650 field_decl = grokfield (input_filename, lineno, field_decl, decl_specs, NULLT);
1651 field_decl_chain = field_decl;
1653 /* struct objc_class *class; */
1655 decl_specs = get_identifier (_TAG_CLASS);
1656 decl_specs = build_tree_list (NULLT, xref_tag (RECORD_TYPE, decl_specs));
1657 field_decl = build1 (INDIRECT_REF, NULLT, get_identifier ("class"));
1659 field_decl = grokfield (input_filename, lineno, field_decl, decl_specs, NULLT);
1660 chainon (field_decl_chain, field_decl);
1662 finish_struct (record, field_decl_chain);
1664 /* `struct objc_super *' */
1665 super_type = groktypename (build_tree_list (build_tree_list (NULLT, record),
1666 build1 (INDIRECT_REF, NULLT, NULLT)));
1671 * struct objc_ivar {
1678 build_ivar_template ()
1680 tree objc_ivar_id, objc_ivar_record;
1681 tree decl_specs, field_decl, field_decl_chain;
1683 objc_ivar_id = get_identifier (_TAG_IVAR);
1684 objc_ivar_record = start_struct (RECORD_TYPE, objc_ivar_id);
1686 /* char *ivar_name; */
1688 decl_specs = build_tree_list (NULLT, ridpointers[(int) RID_CHAR]);
1689 field_decl = build1 (INDIRECT_REF, NULLT, get_identifier ("ivar_name"));
1691 field_decl = grokfield (input_filename, lineno, field_decl, decl_specs, NULLT);
1692 field_decl_chain = field_decl;
1694 /* char *ivar_type; */
1696 decl_specs = build_tree_list (NULLT, ridpointers[(int) RID_CHAR]);
1697 field_decl = build1 (INDIRECT_REF, NULLT, get_identifier ("ivar_type"));
1699 field_decl = grokfield (input_filename, lineno, field_decl, decl_specs, NULLT);
1700 chainon (field_decl_chain, field_decl);
1702 /* int ivar_offset; */
1704 decl_specs = build_tree_list (NULLT, ridpointers[(int) RID_INT]);
1705 field_decl = get_identifier ("ivar_offset");
1707 field_decl = grokfield (input_filename, lineno, field_decl, decl_specs, NULLT);
1708 chainon (field_decl_chain, field_decl);
1710 finish_struct (objc_ivar_record, field_decl_chain);
1712 return objc_ivar_record;
1718 * struct objc_ivar ivar_list[ivar_count];
1722 build_ivar_list_template (list_type, size)
1726 tree objc_ivar_list_id, objc_ivar_list_record;
1727 tree decl_specs, field_decl, field_decl_chain;
1729 objc_ivar_list_record = start_struct (RECORD_TYPE, NULLT);
1731 /* int ivar_count; */
1733 decl_specs = build_tree_list (NULLT, ridpointers[(int) RID_INT]);
1734 field_decl = get_identifier ("ivar_count");
1736 field_decl = grokfield (input_filename, lineno, field_decl, decl_specs, NULLT);
1737 field_decl_chain = field_decl;
1739 /* struct objc_ivar ivar_list[]; */
1741 decl_specs = build_tree_list (NULLT, list_type);
1742 field_decl = build_nt (ARRAY_REF, get_identifier ("ivar_list"),
1743 build_int_2 (size, 0));
1745 field_decl = grokfield (input_filename, lineno, field_decl, decl_specs, NULLT);
1746 chainon (field_decl_chain, field_decl);
1748 finish_struct (objc_ivar_list_record, field_decl_chain);
1750 return objc_ivar_list_record;
1757 * struct objc_method method_list[method_count];
1761 build_method_list_template (list_type, size)
1765 tree objc_ivar_list_id, objc_ivar_list_record;
1766 tree decl_specs, field_decl, field_decl_chain;
1768 objc_ivar_list_record = start_struct (RECORD_TYPE, NULLT);
1770 /* int method_next; */
1772 decl_specs = build_tree_list (NULLT, ridpointers[(int) RID_INT]);
1773 field_decl = get_identifier ("method_next");
1775 field_decl = grokfield (input_filename, lineno, field_decl, decl_specs, NULLT);
1776 field_decl_chain = field_decl;
1778 /* int method_count; */
1780 decl_specs = build_tree_list (NULLT, ridpointers[(int) RID_INT]);
1781 field_decl = get_identifier ("method_count");
1783 field_decl = grokfield (input_filename, lineno, field_decl, decl_specs, NULLT);
1784 chainon (field_decl_chain, field_decl);
1786 /* struct objc_method method_list[]; */
1788 decl_specs = build_tree_list (NULLT, list_type);
1789 field_decl = build_nt (ARRAY_REF, get_identifier ("method_list"),
1790 build_int_2 (size, 0));
1792 field_decl = grokfield (input_filename, lineno, field_decl, decl_specs, NULLT);
1793 chainon (field_decl_chain, field_decl);
1795 finish_struct (objc_ivar_list_record, field_decl_chain);
1797 return objc_ivar_list_record;
1801 build_ivar_list_initializer (field_decl, size)
1805 tree initlist = NULLT;
1812 if (DECL_NAME (field_decl))
1814 offset = add_objc_string (DECL_NAME (field_decl));
1815 initlist = tree_cons (NULLT, build_msg_pool_reference (offset), initlist);
1819 /* unnamed bit-field ivar (yuck). */
1820 initlist = tree_cons (NULLT, build_int_2 (0, 0), initlist);
1824 encode_field_decl (field_decl, OBJC_ENCODE_DONT_INLINE_DEFS);
1825 offset = add_objc_string (get_identifier (obstack_finish (&util_obstack)));
1826 obstack_free (&util_obstack, util_firstobj);
1828 initlist = tree_cons (NULLT, build_msg_pool_reference (offset), initlist);
1831 initlist = tree_cons (NULLT,
1832 build_int_2 (TREE_INT_CST_LOW (DECL_FIELD_BITPOS (field_decl)) / BITS_PER_UNIT, 0),
1836 field_decl = TREE_CHAIN (field_decl);
1840 return build_nt (CONSTRUCTOR, NULLT, nreverse (initlist));
1844 generate_ivars_list (type, name, size, list)
1850 tree sc_spec, decl_specs, decl, initlist;
1852 sc_spec = tree_cons (NULLT, ridpointers[(int) RID_STATIC], NULLT);
1853 decl_specs = tree_cons (NULLT, type, sc_spec);
1855 decl = start_decl (synth_id_with_class_suffix (name), decl_specs, 1);
1857 initlist = build_tree_list (NULLT, build_int_2 (size, 0));
1858 initlist = tree_cons (NULLT, list, initlist);
1860 finish_decl (decl, build_nt (CONSTRUCTOR, NULLT, nreverse (initlist)), NULLT);
1866 generate_ivar_lists ()
1868 tree initlist, ivar_list_template, chain;
1869 tree cast, variable_length_type;
1872 if (!objc_ivar_template)
1873 objc_ivar_template = build_ivar_template ();
1875 cast = build_tree_list (build_tree_list (NULLT, xref_tag (RECORD_TYPE,
1876 get_identifier (_TAG_IVAR_LIST))), NULLT);
1877 variable_length_type = groktypename (cast);
1879 /* only generate class variables for the root of the inheritance
1880 hierarchy since these will be the same for every class */
1882 if (CLASS_SUPER_NAME (implementation_template) == NULLT
1883 && (chain = TYPE_FIELDS (objc_class_template)))
1886 initlist = build_ivar_list_initializer (chain, &size);
1888 ivar_list_template = build_ivar_list_template (objc_ivar_template, size);
1890 _OBJC_CLASS_VARIABLES_decl =
1891 generate_ivars_list (ivar_list_template, "_OBJC_CLASS_VARIABLES",
1894 TREE_TYPE (_OBJC_CLASS_VARIABLES_decl) = variable_length_type;
1897 _OBJC_CLASS_VARIABLES_decl = 0;
1899 chain = CLASS_IVARS (implementation_template);
1903 initlist = build_ivar_list_initializer (chain, &size);
1905 ivar_list_template = build_ivar_list_template (objc_ivar_template, size);
1907 _OBJC_INSTANCE_VARIABLES_decl =
1908 generate_ivars_list (ivar_list_template, "_OBJC_INSTANCE_VARIABLES",
1911 TREE_TYPE (_OBJC_INSTANCE_VARIABLES_decl) = variable_length_type;
1914 _OBJC_INSTANCE_VARIABLES_decl = 0;
1918 build_dispatch_table_initializer (entries, size)
1922 tree initlist = NULLT;
1926 int offset = add_objc_string (METHOD_SEL_NAME (entries));
1928 initlist = tree_cons (NULLT, init_selector (offset), initlist);
1930 offset = add_objc_string (METHOD_ENCODING (entries));
1931 initlist = tree_cons (NULLT, build_msg_pool_reference (offset), initlist);
1933 initlist = tree_cons (NULLT, METHOD_DEFINITION (entries), initlist);
1936 entries = TREE_CHAIN (entries);
1940 return build_nt (CONSTRUCTOR, NULLT, nreverse (initlist));
1944 * To accomplish method prototyping without generating all kinds of
1945 * inane warnings, the definition of the dispatch table entries were
1948 * struct objc_method { SEL _cmd; id (*_imp)(); };
1950 * struct objc_method { SEL _cmd; void *_imp; };
1953 build_method_template ()
1956 tree decl_specs, field_decl, field_decl_chain, parms;
1958 _SLT_record = start_struct (RECORD_TYPE, get_identifier (_TAG_METHOD));
1960 #ifdef OBJC_INT_SELECTORS
1961 /* unsigned int _cmd; */
1962 decl_specs = tree_cons (NULLT, ridpointers[(int) RID_UNSIGNED], NULLT);
1963 decl_specs = tree_cons (NULLT, ridpointers[(int) RID_INT], decl_specs);
1964 field_decl = get_identifier ("_cmd");
1965 #else /* not OBJC_INT_SELECTORS */
1966 /* struct objc_selector *_cmd; */
1967 decl_specs = tree_cons (NULLT,
1968 xref_tag (RECORD_TYPE,
1969 get_identifier (TAG_SELECTOR)),
1971 field_decl = build1 (INDIRECT_REF, NULLT, get_identifier ("_cmd"));
1972 #endif /* not OBJC_INT_SELECTORS */
1974 field_decl = grokfield (input_filename, lineno, field_decl, decl_specs, NULLT);
1975 field_decl_chain = field_decl;
1977 decl_specs = tree_cons (NULLT, ridpointers[(int) RID_CHAR], NULLT);
1978 field_decl = build1 (INDIRECT_REF, NULLT, get_identifier ("method_types"));
1979 field_decl = grokfield (input_filename, lineno, field_decl, decl_specs, NULLT);
1980 chainon (field_decl_chain, field_decl);
1984 decl_specs = tree_cons (NULLT, ridpointers[(int) RID_VOID], NULLT);
1985 field_decl = build1 (INDIRECT_REF, NULLT, get_identifier ("_imp"));
1986 field_decl = grokfield (input_filename, lineno, field_decl, decl_specs, NULLT);
1987 chainon (field_decl_chain, field_decl);
1989 finish_struct (_SLT_record, field_decl_chain);
1996 generate_dispatch_table (type, name, size, list)
2002 tree sc_spec, decl_specs, decl, initlist;
2004 sc_spec = tree_cons (NULLT, ridpointers[(int) RID_STATIC], NULLT);
2005 decl_specs = tree_cons (NULLT, type, sc_spec);
2007 decl = start_decl (synth_id_with_class_suffix (name), decl_specs, 1);
2009 initlist = build_tree_list (NULLT, build_int_2 (0, 0));
2010 initlist = tree_cons (NULLT, build_int_2 (size, 0), initlist);
2011 initlist = tree_cons (NULLT, list, initlist);
2013 finish_decl (decl, build_nt (CONSTRUCTOR, NULLT, nreverse (initlist)), NULLT);
2019 generate_dispatch_tables ()
2021 tree initlist, chain, method_list_template;
2022 tree cast, variable_length_type;
2025 if (!objc_method_template)
2026 objc_method_template = build_method_template ();
2028 cast = build_tree_list (build_tree_list (NULLT, xref_tag (RECORD_TYPE,
2029 get_identifier (_TAG_METHOD_LIST))), NULLT);
2030 variable_length_type = groktypename (cast);
2032 chain = CLASS_CLS_METHODS (implementation_context);
2036 initlist = build_dispatch_table_initializer (chain, &size);
2038 method_list_template = build_method_list_template (objc_method_template,
2040 if (TREE_CODE (implementation_context) == IMPLEMENTATION_TYPE)
2041 _OBJC_CLASS_METHODS_decl =
2042 generate_dispatch_table (method_list_template,
2043 "_OBJC_CLASS_METHODS",
2046 /* we have a category */
2047 _OBJC_CLASS_METHODS_decl =
2048 generate_dispatch_table (method_list_template,
2049 "_OBJC_CATEGORY_CLASS_METHODS",
2052 TREE_TYPE (_OBJC_CLASS_METHODS_decl) = variable_length_type;
2055 _OBJC_CLASS_METHODS_decl = 0;
2057 chain = CLASS_NST_METHODS (implementation_context);
2061 initlist = build_dispatch_table_initializer (chain, &size);
2063 method_list_template = build_method_list_template (objc_method_template,
2065 if (TREE_CODE (implementation_context) == IMPLEMENTATION_TYPE)
2066 _OBJC_INSTANCE_METHODS_decl =
2067 generate_dispatch_table (method_list_template,
2068 "_OBJC_INSTANCE_METHODS",
2071 /* we have a category */
2072 _OBJC_INSTANCE_METHODS_decl =
2073 generate_dispatch_table (method_list_template,
2074 "_OBJC_CATEGORY_INSTANCE_METHODS",
2077 TREE_TYPE (_OBJC_INSTANCE_METHODS_decl) = variable_length_type;
2080 _OBJC_INSTANCE_METHODS_decl = 0;
2084 build_category_initializer (cat_name, class_name,
2085 instance_methods, class_methods)
2088 tree instance_methods;
2091 tree initlist = NULLT, expr;
2093 initlist = tree_cons (NULLT, cat_name, initlist);
2094 initlist = tree_cons (NULLT, class_name, initlist);
2096 if (!instance_methods)
2097 initlist = tree_cons (NULLT, build_int_2 (0, 0), initlist);
2100 expr = build_unary_op (ADDR_EXPR, instance_methods, 0);
2101 initlist = tree_cons (NULLT, expr, initlist);
2104 initlist = tree_cons (NULLT, build_int_2 (0, 0), initlist);
2107 expr = build_unary_op (ADDR_EXPR, class_methods, 0);
2108 initlist = tree_cons (NULLT, expr, initlist);
2110 return build_nt (CONSTRUCTOR, NULLT, nreverse (initlist));
2114 * struct objc_class {
2115 * struct objc_class *isa;
2116 * struct objc_class *super_class;
2120 * long instance_size;
2121 * struct objc_ivar_list *ivars;
2122 * struct objc_method_list *methods;
2123 * struct objc_cache *cache;
2127 build_shared_structure_initializer (isa, super, name, size, status,
2128 dispatch_table, ivar_list)
2134 tree dispatch_table;
2137 tree initlist = NULLT, expr;
2140 initlist = tree_cons (NULLT, isa, initlist);
2143 initlist = tree_cons (NULLT, super, initlist);
2146 initlist = tree_cons (NULLT, name, initlist);
2149 initlist = tree_cons (NULLT, build_int_2 (0, 0), initlist);
2152 initlist = tree_cons (NULLT, build_int_2 (status, 0), initlist);
2154 /* instance_size = */
2155 initlist = tree_cons (NULLT, size, initlist);
2157 /* objc_ivar_list = */
2159 initlist = tree_cons (NULLT, build_int_2 (0, 0), initlist);
2162 expr = build_unary_op (ADDR_EXPR, ivar_list, 0);
2163 initlist = tree_cons (NULLT, expr, initlist);
2166 /* objc_method_list = */
2167 if (!dispatch_table)
2168 initlist = tree_cons (NULLT, build_int_2 (0, 0), initlist);
2171 expr = build_unary_op (ADDR_EXPR, dispatch_table, 0);
2172 initlist = tree_cons (NULLT, expr, initlist);
2175 /* method_cache = */
2176 initlist = tree_cons (NULLT, build_int_2 (0, 0), initlist);
2178 return build_nt (CONSTRUCTOR, NULLT, nreverse (initlist));
2182 * static struct objc_category _OBJC_CATEGORY_<name> = { ... };
2185 generate_category (cat)
2188 tree sc_spec, decl_specs, decl;
2189 tree initlist, cat_name_expr, class_name_expr;
2192 sc_spec = tree_cons (NULLT, ridpointers[(int) RID_STATIC], NULLT);
2193 decl_specs = tree_cons (NULLT, objc_category_template, sc_spec);
2195 decl = start_decl (synth_id_with_class_suffix ("_OBJC_CATEGORY"),
2198 offset = add_objc_string (CLASS_SUPER_NAME (cat));
2199 cat_name_expr = build_msg_pool_reference (offset);
2201 offset = add_objc_string (CLASS_NAME (cat));
2202 class_name_expr = build_msg_pool_reference (offset);
2204 initlist = build_category_initializer (
2205 cat_name_expr, class_name_expr,
2206 _OBJC_INSTANCE_METHODS_decl, _OBJC_CLASS_METHODS_decl);
2208 finish_decl (decl, initlist, NULLT);
2212 * static struct objc_class _OBJC_METACLASS_Foo={ ... };
2213 * static struct objc_class _OBJC_CLASS_Foo={ ... };
2216 generate_shared_structures ()
2218 tree sc_spec, decl_specs, expr_decl, decl;
2219 tree name_expr, super_expr, root_expr;
2220 tree my_root_id = NULLT, my_super_id = NULLT;
2221 tree cast_type, initlist;
2224 my_super_id = CLASS_SUPER_NAME (implementation_template);
2227 add_class_reference (my_super_id);
2229 /* compute "my_root_id" - this is required for code generation.
2230 * the "isa" for all meta class structures points to the root of
2231 * the inheritance hierarchy (e.g. "__Object")...
2233 my_root_id = my_super_id;
2236 tree my_root_int = lookup_interface (my_root_id);
2238 if (my_root_int && CLASS_SUPER_NAME (my_root_int))
2239 my_root_id = CLASS_SUPER_NAME (my_root_int);
2245 else /* no super class */
2247 my_root_id = CLASS_NAME (implementation_template);
2250 cast_type = groktypename (build_tree_list (build_tree_list (NULLT,
2251 objc_class_template), build1 (INDIRECT_REF, NULLT, NULLT)));
2253 offset = add_objc_string (CLASS_NAME (implementation_template));
2254 name_expr = build_msg_pool_reference (offset);
2256 /* install class `isa' and `super' pointers at runtime */
2259 offset = add_objc_string (my_super_id);
2260 super_expr = build_msg_pool_reference (offset);
2261 TREE_TYPE (super_expr) = cast_type; /* cast! */
2264 super_expr = build_int_2 (0, 0);
2266 offset = add_objc_string (my_root_id);
2267 root_expr = build_msg_pool_reference (offset);
2268 TREE_TYPE (root_expr) = cast_type; /* cast! */
2270 /* static struct objc_class _OBJC_METACLASS_Foo = { ... }; */
2272 sc_spec = build_tree_list (NULLT, ridpointers[(int) RID_STATIC]);
2273 decl_specs = tree_cons (NULLT, objc_class_template, sc_spec);
2275 decl = start_decl (DECL_NAME (_OBJC_METACLASS_decl), decl_specs, 1);
2277 initlist = build_shared_structure_initializer (
2278 root_expr, super_expr, name_expr,
2279 build_int_2 (TREE_INT_CST_LOW (TYPE_SIZE (objc_class_template)) / BITS_PER_UNIT, 0),
2281 _OBJC_CLASS_METHODS_decl, _OBJC_CLASS_VARIABLES_decl);
2283 finish_decl (decl, initlist, NULLT);
2285 /* static struct objc_class _OBJC_CLASS_Foo={ ... }; */
2287 decl = start_decl (DECL_NAME (_OBJC_CLASS_decl), decl_specs, 1);
2289 initlist = build_shared_structure_initializer (
2290 build_unary_op (ADDR_EXPR, _OBJC_METACLASS_decl, 0),
2291 super_expr, name_expr,
2292 build_int_2 (TREE_INT_CST_LOW (TYPE_SIZE (CLASS_STATIC_TEMPLATE (implementation_template))) / BITS_PER_UNIT, 0),
2294 _OBJC_INSTANCE_METHODS_decl, _OBJC_INSTANCE_VARIABLES_decl);
2296 finish_decl (decl, initlist, NULLT);
2300 synth_id_with_class_suffix (preamble)
2304 if (TREE_CODE (implementation_context) == IMPLEMENTATION_TYPE)
2306 string = (char *) alloca (strlen (preamble)
2307 + strlen (IDENTIFIER_POINTER (CLASS_NAME (implementation_context)))
2309 sprintf (string, "%s_%s", preamble,
2310 IDENTIFIER_POINTER (CLASS_NAME (implementation_context)));
2314 /* we have a category */
2315 string = (char *) alloca (strlen (preamble)
2316 + strlen (IDENTIFIER_POINTER (CLASS_NAME (implementation_context)))
2317 + strlen (IDENTIFIER_POINTER (CLASS_SUPER_NAME (implementation_context)))
2319 sprintf (string, "%s_%s_%s", preamble,
2320 IDENTIFIER_POINTER (CLASS_NAME (implementation_context)),
2321 IDENTIFIER_POINTER (CLASS_SUPER_NAME (implementation_context)));
2323 return get_identifier (string);
2329 * selector ':' '(' typename ')' identifier
2332 * transform an Objective-C keyword argument into
2333 * the C equivalent parameter declarator.
2335 * in: key_name, an "identifier_node" (optional).
2336 * arg_type, a "tree_list" (optional).
2337 * arg_name, an "identifier_node".
2339 * note: it would be really nice to strongly type the preceding
2340 * arguments in the function prototype; however, then i
2341 * could not use the "accessor" macros defined in "tree.h".
2343 * out: an instance of "keyword_decl".
2348 build_keyword_decl (key_name, arg_type, arg_name)
2355 /* if no type is specified, default to "id" */
2356 if (arg_type == NULLT)
2357 arg_type = build_tree_list (build_tree_list (NULLT, objc_object_reference),
2358 build1 (INDIRECT_REF, NULLT, NULLT));
2360 keyword_decl = make_node (KEYWORD_DECL);
2362 TREE_TYPE (keyword_decl) = arg_type;
2363 KEYWORD_ARG_NAME (keyword_decl) = arg_name;
2364 KEYWORD_KEY_NAME (keyword_decl) = key_name;
2366 return keyword_decl;
2370 * given a chain of keyword_decl's, synthesize the full keyword selector.
2373 build_keyword_selector (selector)
2377 tree key_chain, key_name;
2380 for (key_chain = selector; key_chain; key_chain = TREE_CHAIN (key_chain))
2382 if (TREE_CODE (selector) == KEYWORD_DECL)
2383 key_name = KEYWORD_KEY_NAME (key_chain);
2384 else if (TREE_CODE (selector) == TREE_LIST)
2385 key_name = TREE_PURPOSE (key_chain);
2388 len += IDENTIFIER_LENGTH (key_name) + 1;
2389 else /* just a ':' arg */
2392 buf = (char *)alloca (len + 1);
2393 bzero (buf, len + 1);
2395 for (key_chain = selector; key_chain; key_chain = TREE_CHAIN (key_chain))
2397 if (TREE_CODE (selector) == KEYWORD_DECL)
2398 key_name = KEYWORD_KEY_NAME (key_chain);
2399 else if (TREE_CODE (selector) == TREE_LIST)
2400 key_name = TREE_PURPOSE (key_chain);
2403 strcat (buf, IDENTIFIER_POINTER (key_name));
2406 return get_identifier (buf);
2409 /* used for declarations and definitions */
2412 build_method_decl (code, ret_type, selector, add_args)
2413 enum tree_code code;
2420 /* if no type is specified, default to "id" */
2421 if (ret_type == NULLT)
2422 ret_type = build_tree_list (build_tree_list (NULLT, objc_object_reference),
2423 build1 (INDIRECT_REF, NULLT, NULLT));
2425 method_decl = make_node (code);
2426 TREE_TYPE (method_decl) = ret_type;
2429 * if we have a keyword selector, create an identifier_node that
2430 * represents the full selector name (`:' included)...
2432 if (TREE_CODE (selector) == KEYWORD_DECL)
2434 METHOD_SEL_NAME (method_decl) = build_keyword_selector (selector);
2435 METHOD_SEL_ARGS (method_decl) = selector;
2436 METHOD_ADD_ARGS (method_decl) = add_args;
2440 METHOD_SEL_NAME (method_decl) = selector;
2441 METHOD_SEL_ARGS (method_decl) = NULLT;
2442 METHOD_ADD_ARGS (method_decl) = NULLT;
2448 #define METHOD_DEF 0
2449 #define METHOD_REF 1
2450 /* Used by `build_message_expr' and `comp_method_types'.
2451 Return an argument list for method METH.
2452 CONTEXT is either METHOD_DEF or METHOD_REF,
2453 saying whether we are trying to define a method or call one.
2454 SUPERFLAG says this is for a send to super;
2455 this makes a difference for the NeXT calling sequence
2456 in which the lookup and the method call are done together. */
2459 get_arg_type_list (meth, context, superflag)
2466 #ifdef NEXT_OBJC_RUNTIME
2470 arglist = build_tree_list (NULLT, super_type);
2475 if (context == METHOD_DEF)
2476 arglist = build_tree_list (NULLT, TREE_TYPE (self_decl));
2478 arglist = build_tree_list (NULLT, id_type);
2481 /* selector type - will eventually change to `int' */
2482 chainon (arglist, build_tree_list (NULLT, selector_type));
2484 /* build a list of argument types */
2485 for (akey = METHOD_SEL_ARGS (meth); akey; akey = TREE_CHAIN (akey))
2487 tree arg_decl = groktypename_in_parm_context (TREE_TYPE (akey));
2488 chainon (arglist, build_tree_list (NULLT, TREE_TYPE (arg_decl)));
2491 if (METHOD_ADD_ARGS (meth) == (tree)1)
2493 * we have a `, ...' immediately following the selector,
2494 * finalize the arglist...simulate get_parm_info (0)
2497 else if (METHOD_ADD_ARGS (meth))
2499 /* we have a variable length selector */
2500 tree add_arg_list = TREE_CHAIN (METHOD_ADD_ARGS (meth));
2501 chainon (arglist, add_arg_list);
2503 else /* finalize the arglist...simulate get_parm_info (1) */
2504 chainon (arglist, build_tree_list (NULLT, void_type_node));
2510 check_duplicates (hsh)
2521 /* we have two methods with the same name and different types */
2525 type = (TREE_CODE (meth) == INSTANCE_METHOD_DECL) ? '-' : '+';
2527 warning ("multiple declarations for method `%s'",
2528 IDENTIFIER_POINTER (METHOD_SEL_NAME (meth)));
2530 warn_with_method ("using", type, meth);
2531 for (loop = hsh->list; loop; loop = loop->next)
2532 warn_with_method ("also found", type, loop->value);
2539 receiver_is_class_object (receiver)
2542 /* the receiver is a function call that returns an id...
2543 * ...check if it is a call to objc_getClass, if so, give it
2544 * special treatment.
2546 tree exp = TREE_OPERAND (receiver, 0);
2548 if (exp != 0 && (TREE_CODE (exp) == ADDR_EXPR))
2550 exp = TREE_OPERAND (exp, 0);
2552 && TREE_CODE (exp) == FUNCTION_DECL && exp == objc_getClass_decl)
2554 /* we have a call to objc_getClass! */
2555 tree arg = TREE_OPERAND (receiver, 1);
2558 && TREE_CODE (arg) == TREE_LIST
2559 && (arg = TREE_VALUE (arg))
2560 && TREE_CODE (arg) == NOP_EXPR
2561 && (arg = TREE_OPERAND (arg, 0))
2562 && TREE_CODE (arg) == ADDR_EXPR
2563 && (arg = TREE_OPERAND (arg, 0))
2564 && TREE_CODE (arg) == STRING_CST)
2565 /* finally, we have the class name */
2566 return get_identifier (TREE_STRING_POINTER (arg));
2572 /* If we are currently building a message expr, this holds
2573 the identifier of the selector of the message. This is
2574 used when printing warnings about argument mismatches. */
2576 static tree building_objc_message_expr = 0;
2579 maybe_building_objc_message_expr ()
2581 return building_objc_message_expr;
2584 /* Construct an expression for sending a message.
2585 MESS has the object to send to in TREE_PURPOSE
2586 and the argument list (including selector) in TREE_VALUE. */
2589 build_message_expr (mess)
2592 tree receiver = TREE_PURPOSE (mess);
2593 tree selector, self_object;
2594 tree rtype, sel_name;
2595 tree args = TREE_VALUE (mess);
2596 tree method_params = NULLT;
2597 tree method_prototype = NULLT;
2598 int selTransTbl_index;
2600 int statically_typed = 0, statically_allocated = 0;
2601 tree class_ident = 0;
2603 /* 1 if this is sending to the superclass. */
2606 if (!doing_objc_thang)
2607 fatal ("Objective-C text in C source file");
2609 if (TREE_CODE (receiver) == ERROR_MARK)
2610 return error_mark_node;
2612 /* determine receiver type */
2613 rtype = TREE_TYPE (receiver);
2614 super = (TREE_TYPE (receiver) == super_type);
2618 if (TREE_STATIC_TEMPLATE (rtype))
2619 statically_allocated = 1;
2620 else if (TREE_CODE (rtype) == POINTER_TYPE
2621 && TREE_STATIC_TEMPLATE (TREE_TYPE (rtype)))
2622 statically_typed = 1;
2624 else if (TREE_CODE (receiver) == CALL_EXPR && rtype == id_type
2625 && (class_ident = receiver_is_class_object (receiver)))
2627 else if (TYPE_MAIN_VARIANT (rtype) != TYPE_MAIN_VARIANT (id_type)
2628 && TYPE_MAIN_VARIANT (rtype) != TYPE_MAIN_VARIANT (class_type))
2630 bzero (errbuf, BUFSIZE);
2631 warning ("invalid receiver type `%s'", gen_declaration (rtype, errbuf));
2633 if (statically_allocated)
2634 receiver = build_unary_op (ADDR_EXPR, receiver, 0);
2636 self_object = receiver;
2639 /* If sending to `super', use current self as the object. */
2640 self_object = self_decl;
2642 /* Obtain the full selector name. */
2644 if (TREE_CODE (args) == IDENTIFIER_NODE)
2645 /* a unary selector */
2647 else if (TREE_CODE (args) == TREE_LIST)
2648 sel_name = build_keyword_selector (args);
2650 selTransTbl_index = add_selector_reference (sel_name);
2652 /* Build the parameters list for looking up the method.
2653 These are the object itself and the selector. */
2655 #ifndef OBJC_SELECTORS_WITHOUT_LABELS
2656 selector = build_selector_reference (selTransTbl_index);
2658 selector = build_array_ref (_OBJC_SELECTOR_REFERENCES_decl,
2659 build_int_2 (selTransTbl_index, 0));
2662 /* Build the parameter list to give to the method. */
2664 method_params = NULLT;
2665 if (TREE_CODE (args) == TREE_LIST)
2667 tree chain = args, prev = NULLT;
2669 /* We have a keyword selector--check for comma expressions. */
2672 tree element = TREE_VALUE (chain);
2674 /* We have a comma expression, must collapse... */
2675 if (TREE_CODE (element) == TREE_LIST)
2678 TREE_CHAIN (prev) = element;
2683 chain = TREE_CHAIN (chain);
2685 method_params = args;
2688 /* Determine operation return type. */
2690 if (TYPE_MAIN_VARIANT (rtype) == TYPE_MAIN_VARIANT (super_type))
2694 if (CLASS_SUPER_NAME (implementation_template))
2696 iface = lookup_interface (CLASS_SUPER_NAME (implementation_template));
2698 if (TREE_CODE (method_context) == INSTANCE_METHOD_DECL)
2699 method_prototype = lookup_instance_method_static (iface, sel_name);
2701 method_prototype = lookup_class_method_static (iface, sel_name);
2703 if (iface && !method_prototype)
2704 warning ("`%s' does not respond to `%s'",
2705 IDENTIFIER_POINTER (CLASS_SUPER_NAME (implementation_template)),
2706 IDENTIFIER_POINTER (sel_name));
2710 error ("no super class declared in interface for `%s'",
2711 IDENTIFIER_POINTER (CLASS_NAME (implementation_template)));
2712 return error_mark_node;
2716 else if (statically_allocated)
2718 tree iface = lookup_interface (TYPE_NAME (rtype));
2720 if (iface && !(method_prototype = lookup_instance_method_static (iface, sel_name)))
2721 warning ("`%s' does not respond to `%s'",
2722 IDENTIFIER_POINTER (TYPE_NAME (rtype)),
2723 IDENTIFIER_POINTER (sel_name));
2725 else if (statically_typed)
2727 tree ctype = TREE_TYPE (rtype);
2729 /* `self' is now statically_typed...all methods should be visible
2730 * within the context of the implementation...
2732 if (implementation_context
2733 && CLASS_NAME (implementation_context) == TYPE_NAME (ctype))
2735 method_prototype = lookup_instance_method_static (implementation_template, sel_name);
2737 if (!method_prototype && implementation_template != implementation_context)
2738 /* the method is not published in the interface...check locally */
2739 method_prototype = lookup_method (CLASS_NST_METHODS (implementation_context),
2746 if (iface = lookup_interface (TYPE_NAME (ctype)))
2747 method_prototype = lookup_instance_method_static (iface, sel_name);
2750 if (!method_prototype)
2751 warning ("`%s' does not respond to `%s'",
2752 IDENTIFIER_POINTER (TYPE_NAME (ctype)),
2753 IDENTIFIER_POINTER (sel_name));
2755 else if (class_ident)
2757 if (implementation_context
2758 && CLASS_NAME (implementation_context) == class_ident)
2761 = lookup_class_method_static (implementation_template, sel_name);
2763 if (!method_prototype
2764 && implementation_template != implementation_context)
2765 /* the method is not published in the interface...check locally */
2767 = lookup_method (CLASS_CLS_METHODS (implementation_context),
2774 if (iface = lookup_interface (class_ident))
2775 method_prototype = lookup_class_method_static (iface, sel_name);
2778 if (!method_prototype)
2780 warning ("cannot find class (factory) method.");
2781 warning ("return type for `%s' defaults to id",
2782 IDENTIFIER_POINTER (sel_name));
2789 /* we think we have an instance...loophole: extern id Object; */
2790 hsh = hash_lookup (nst_method_hash_list, sel_name);
2792 /* for various loopholes...like sending messages to self in a
2793 factory context... */
2794 hsh = hash_lookup (cls_method_hash_list, sel_name);
2796 method_prototype = check_duplicates (hsh);
2797 if (!method_prototype)
2799 warning ("cannot find method.");
2800 warning ("return type for `%s' defaults to id",
2801 IDENTIFIER_POINTER (sel_name));
2805 /* Save the selector name for printing error messages. */
2806 building_objc_message_expr = sel_name;
2808 retval = build_objc_method_call (super, method_prototype,
2809 receiver, self_object,
2810 selector, method_params);
2812 building_objc_message_expr = 0;
2817 /* Build a tree expression to send OBJECT the operation SELECTOR,
2818 looking up the method on object LOOKUP_OBJECT (often same as OBJECT),
2819 assuming the method has prototype METHOD_PROTOTYPE.
2820 (That is an INSTANCE_METHOD_DECL or CLASS_METHOD_DECL.)
2821 Use METHOD_PARAMS as list of args to pass to the method.
2822 If SUPER_FLAG is nonzero, we look up the superclass's method. */
2825 build_objc_method_call (super_flag, method_prototype, lookup_object, object,
2826 selector, method_params)
2828 tree method_prototype, lookup_object, object, selector, method_params;
2830 tree sender = (super_flag ? _msgSuper_decl : _msg_decl);
2832 #ifdef NEXT_OBJC_RUNTIME
2833 if (!method_prototype)
2835 method_params = tree_cons (NULLT, lookup_object,
2836 tree_cons (NULLT, selector, method_params));
2837 return build_function_call (sender, method_params);
2841 /* This is a real kludge, but it is used only for the Next.
2842 Clobber the data type of SENDER temporarily to accept
2843 all the arguments for this operation, and to return
2844 whatever this operation returns. */
2845 tree arglist = NULLT;
2848 /* Save the proper contents of SENDER's data type. */
2849 tree savarg = TYPE_ARG_TYPES (TREE_TYPE (sender));
2850 tree savret = TREE_TYPE (TREE_TYPE (sender));
2852 /* Install this method's argument types. */
2853 arglist = get_arg_type_list (method_prototype, METHOD_REF, super_flag);
2854 TYPE_ARG_TYPES (TREE_TYPE (sender)) = arglist;
2856 /* Install this method's return type. */
2857 TREE_TYPE (TREE_TYPE (sender))
2858 = groktypename (TREE_TYPE (method_prototype));
2860 /* Call SENDER with all the parameters.
2861 This will do type checking using the arg types for this method. */
2862 method_params = tree_cons (NULLT, lookup_object,
2863 tree_cons (NULLT, selector, method_params));
2864 retval = build_function_call (sender, method_params);
2866 /* Restore SENDER's return/argument types. */
2867 TYPE_ARG_TYPES (TREE_TYPE (sender)) = savarg;
2868 TREE_TYPE (TREE_TYPE (sender)) = savret;
2871 #else /* not NEXT_OBJC_RUNTIME */
2872 /* This is the portable way.
2873 First call the lookup function to get a pointer to the method,
2874 then cast the pointer, then call it with the method arguments. */
2877 /* Avoid trouble since we may evaluate each of these twice. */
2878 object = save_expr (object);
2879 selector = save_expr (selector);
2882 = build_function_call (sender,
2883 tree_cons (NULLT, lookup_object,
2884 tree_cons (NULLT, selector, NULLT)));
2886 /* If we have a method prototype, construct the data type this method needs,
2887 and cast what we got from SENDER into a pointer to that type. */
2888 if (method_prototype)
2890 tree arglist = get_arg_type_list (method_prototype, METHOD_REF, super_flag);
2891 tree valtype = groktypename (TREE_TYPE (method_prototype));
2892 tree fake_function_type = build_function_type (valtype, arglist);
2893 TREE_TYPE (method) = build_pointer_type (fake_function_type);
2898 = build_pointer_type (build_function_type (ptr_type_node, NULLT));
2900 /* Pass the object to the method. */
2901 return build_function_call (method,
2902 tree_cons (NULLT, object,
2903 tree_cons (NULLT, selector,
2905 #endif /* not NEXT_OBJC_RUNTIME */
2909 build_selector_expr (selnamelist)
2913 int selTransTbl_index;
2915 if (!doing_objc_thang)
2916 fatal ("Objective-C text in C source file");
2918 /* obtain the full selector name */
2919 if (TREE_CODE (selnamelist) == IDENTIFIER_NODE)
2920 /* a unary selector */
2921 selname = selnamelist;
2922 else if (TREE_CODE (selnamelist) == TREE_LIST)
2923 selname = build_keyword_selector (selnamelist);
2925 selTransTbl_index = add_selector_reference (selname);
2927 #ifndef OBJC_SELECTORS_WITHOUT_LABELS
2928 return build_selector_reference (selTransTbl_index);
2930 /* synthesize a reference into the selector translation table */
2931 return build_array_ref (_OBJC_SELECTOR_REFERENCES_decl,
2932 build_int_2 (selTransTbl_index, 0));
2937 build_encode_expr (type)
2943 if (!doing_objc_thang)
2944 fatal ("Objective-C text in C source file");
2946 encode_type (type, OBJC_ENCODE_INLINE_DEFS);
2947 string = obstack_finish (&util_obstack);
2949 /* synthesize a string that represents the encoded struct/union */
2950 result = my_build_string (strlen (string) + 1, string);
2951 obstack_free (&util_obstack, util_firstobj);
2956 build_ivar_reference (id)
2959 if (TREE_CODE (method_context) == CLASS_METHOD_DECL)
2960 TREE_TYPE (self_decl) = instance_type; /* cast */
2962 return build_component_ref (build_indirect_ref (self_decl, "->"), id);
2965 #define HASH_ALLOC_LIST_SIZE 170
2966 #define ATTR_ALLOC_LIST_SIZE 170
2967 #define SIZEHASHTABLE 257
2968 #define HASHFUNCTION(key) ((int)key >> 2) /* divide by 4 */
2973 nst_method_hash_list = (hash *)xmalloc (SIZEHASHTABLE * sizeof (hash));
2974 cls_method_hash_list = (hash *)xmalloc (SIZEHASHTABLE * sizeof (hash));
2976 if (!nst_method_hash_list || !cls_method_hash_list)
2977 perror ("unable to allocate space in objc-tree.c");
2982 for (i = 0; i < SIZEHASHTABLE; i++)
2984 nst_method_hash_list[i] = 0;
2985 cls_method_hash_list[i] = 0;
2991 hash_enter (hashlist, method)
2995 static hash hash_alloc_list = 0;
2996 static int hash_alloc_index = 0;
2998 int slot = HASHFUNCTION (METHOD_SEL_NAME (method)) % SIZEHASHTABLE;
3000 if (!hash_alloc_list || hash_alloc_index >= HASH_ALLOC_LIST_SIZE)
3002 hash_alloc_index = 0;
3003 hash_alloc_list = (hash)xmalloc (sizeof (struct hashedEntry) *
3004 HASH_ALLOC_LIST_SIZE);
3005 if (!hash_alloc_list)
3006 perror ("unable to allocate in objc-tree.c");
3008 obj = &hash_alloc_list[hash_alloc_index++];
3010 obj->next = hashlist[slot];
3013 hashlist[slot] = obj; /* append to front */
3017 hash_lookup (hashlist, sel_name)
3023 target = hashlist[HASHFUNCTION (sel_name) % SIZEHASHTABLE];
3027 if (sel_name == METHOD_SEL_NAME (target->key))
3030 target = target->next;
3036 hash_add_attr (entry, value)
3040 static attr attr_alloc_list = 0;
3041 static int attr_alloc_index = 0;
3044 if (!attr_alloc_list || attr_alloc_index >= ATTR_ALLOC_LIST_SIZE)
3046 attr_alloc_index = 0;
3047 attr_alloc_list = (attr)xmalloc (sizeof (struct hashedAttribute) *
3048 ATTR_ALLOC_LIST_SIZE);
3049 if (!attr_alloc_list)
3050 perror ("unable to allocate in objc-tree.c");
3052 obj = &attr_alloc_list[attr_alloc_index++];
3053 obj->next = entry->list;
3056 entry->list = obj; /* append to front */
3060 lookup_method (mchain, method)
3066 if (TREE_CODE (method) == IDENTIFIER_NODE)
3069 key = METHOD_SEL_NAME (method);
3073 if (METHOD_SEL_NAME (mchain) == key)
3075 mchain = TREE_CHAIN (mchain);
3081 lookup_instance_method_static (interface, ident)
3085 tree inter = interface;
3086 tree chain = CLASS_NST_METHODS (inter);
3091 if (meth = lookup_method (chain, ident))
3094 if (CLASS_CATEGORY_LIST (inter))
3096 tree category = CLASS_CATEGORY_LIST (inter);
3097 chain = CLASS_NST_METHODS (category);
3101 if (meth = lookup_method (chain, ident))
3104 if (category = CLASS_CATEGORY_LIST (category))
3105 chain = CLASS_NST_METHODS (category);
3110 if (inter = lookup_interface (CLASS_SUPER_NAME (inter)))
3111 chain = CLASS_NST_METHODS (inter);
3119 lookup_class_method_static (interface, ident)
3123 tree inter = interface;
3124 tree chain = CLASS_CLS_METHODS (inter);
3129 if (meth = lookup_method (chain, ident))
3132 if (CLASS_CATEGORY_LIST (inter))
3134 tree category = CLASS_CATEGORY_LIST (inter);
3135 chain = CLASS_CLS_METHODS (category);
3139 if (meth = lookup_method (chain, ident))
3142 if (category = CLASS_CATEGORY_LIST (category))
3143 chain = CLASS_CLS_METHODS (category);
3148 if (inter = lookup_interface (CLASS_SUPER_NAME (inter)))
3149 chain = CLASS_CLS_METHODS (inter);
3157 add_class_method (class, method)
3164 if (!(mth = lookup_method (CLASS_CLS_METHODS (class), method)))
3166 /* put method on list in reverse order */
3167 TREE_CHAIN (method) = CLASS_CLS_METHODS (class);
3168 CLASS_CLS_METHODS (class) = method;
3172 if (TREE_CODE (class) == IMPLEMENTATION_TYPE)
3173 error ("duplicate definition of class method `%s'.",
3174 IDENTIFIER_POINTER (METHOD_SEL_NAME (mth)));
3177 /* check types, if different complain */
3178 if (!comp_proto_with_proto (method, mth))
3179 error ("duplicate declaration of class method `%s'.",
3180 IDENTIFIER_POINTER (METHOD_SEL_NAME (mth)));
3184 if (!(hsh = hash_lookup (cls_method_hash_list, METHOD_SEL_NAME (method))))
3186 /* install on a global chain */
3187 hash_enter (cls_method_hash_list, method);
3191 /* check types, if different add to a list */
3192 if (!comp_proto_with_proto (method, hsh->key))
3193 hash_add_attr (hsh, method);
3199 add_instance_method (class, method)
3206 if (!(mth = lookup_method (CLASS_NST_METHODS (class), method)))
3208 /* put method on list in reverse order */
3209 TREE_CHAIN (method) = CLASS_NST_METHODS (class);
3210 CLASS_NST_METHODS (class) = method;
3214 if (TREE_CODE (class) == IMPLEMENTATION_TYPE)
3215 error ("duplicate definition of instance method `%s'.",
3216 IDENTIFIER_POINTER (METHOD_SEL_NAME (mth)));
3219 /* check types, if different complain */
3220 if (!comp_proto_with_proto (method, mth))
3221 error ("duplicate declaration of instance method `%s'.",
3222 IDENTIFIER_POINTER (METHOD_SEL_NAME (mth)));
3226 if (!(hsh = hash_lookup (nst_method_hash_list, METHOD_SEL_NAME (method))))
3228 /* install on a global chain */
3229 hash_enter (nst_method_hash_list, method);
3233 /* check types, if different add to a list */
3234 if (!comp_proto_with_proto (method, hsh->key))
3235 hash_add_attr (hsh, method);
3244 /* put interfaces on list in reverse order */
3245 TREE_CHAIN (class) = interface_chain;
3246 interface_chain = class;
3247 return interface_chain;
3251 add_category (class, category)
3255 /* put categories on list in reverse order */
3256 CLASS_CATEGORY_LIST (category) = CLASS_CATEGORY_LIST (class);
3257 CLASS_CATEGORY_LIST (class) = category;
3260 /* called after parsing each instance variable declaration. Necessary to
3261 * preserve typedefs and implement public/private...
3264 add_instance_variable (class, public, declarator, declspecs, width)
3271 tree field_decl, raw_decl;
3273 raw_decl = build_tree_list (declspecs /*purpose*/, declarator/*value*/);
3275 if (CLASS_RAW_IVARS (class))
3276 chainon (CLASS_RAW_IVARS (class), raw_decl);
3278 CLASS_RAW_IVARS (class) = raw_decl;
3280 field_decl = grokfield (input_filename, lineno,
3281 declarator, declspecs, width);
3283 /* overload the public attribute, it is not used for FIELD_DECL's */
3285 TREE_PUBLIC (field_decl) = 1;
3287 if (CLASS_IVARS (class))
3288 chainon (CLASS_IVARS (class), field_decl);
3290 CLASS_IVARS (class) = field_decl;
3296 is_ivar (decl_chain, ident)
3300 for ( ; decl_chain; decl_chain = TREE_CHAIN (decl_chain))
3301 if (DECL_NAME (decl_chain) == ident)
3306 /* we have an instance variable reference, check to see if it is public...*/
3309 is_public (expr, identifier)
3313 tree basetype = TREE_TYPE (expr);
3314 enum tree_code code = TREE_CODE (basetype);
3317 if (code == RECORD_TYPE)
3319 if (TREE_STATIC_TEMPLATE (basetype))
3321 if (decl = is_ivar (TYPE_FIELDS (basetype), identifier))
3323 /* important difference between the Stepstone translator:
3325 all instance variables should be public within the context
3326 of the implementation...
3328 if (implementation_context)
3330 if ((TREE_CODE (implementation_context) == IMPLEMENTATION_TYPE
3331 && CLASS_NAME (implementation_context) == TYPE_NAME (basetype))
3332 || (TREE_CODE (implementation_context) == CATEGORY_TYPE
3333 && CLASS_NAME (implementation_context) == TYPE_NAME (basetype)))
3337 if (TREE_PUBLIC (decl))
3340 error ("instance variable `%s' is declared private",
3341 IDENTIFIER_POINTER (identifier));
3345 else if (implementation_context && (basetype == objc_object_reference))
3347 TREE_TYPE (expr) = _PRIVATE_record;
3350 warning ("static access to object of type `id'");
3351 warning ("please change to type `%s *'",
3352 IDENTIFIER_POINTER (CLASS_NAME (implementation_context)));
3359 /* implement @defs (<classname>) within struct bodies. */
3362 get_class_ivars (interface)
3365 if (!doing_objc_thang)
3366 fatal ("Objective-C text in C source file");
3368 return build_ivar_chain (interface);
3372 get_class_reference (interface)
3377 add_class_reference (CLASS_NAME (interface));
3379 params = build_tree_list (NULLT,
3380 my_build_string (IDENTIFIER_LENGTH (CLASS_NAME (interface)) + 1,
3381 IDENTIFIER_POINTER (CLASS_NAME (interface))));
3383 return build_function_call (objc_getClass_decl, params);
3386 /* make sure all entries in "chain" are also in "list" */
3389 check_methods (chain, list, mtype)
3398 if (!lookup_method (list, chain))
3402 if (TREE_CODE (implementation_context) == IMPLEMENTATION_TYPE)
3403 warning ("incomplete implementation of class `%s'",
3404 IDENTIFIER_POINTER (CLASS_NAME (implementation_context)));
3405 else if (TREE_CODE (implementation_context) == CATEGORY_TYPE)
3406 warning ("incomplete implementation of category `%s'",
3407 IDENTIFIER_POINTER (CLASS_SUPER_NAME (implementation_context)));
3410 warning ("method definition for `%c%s' not found",
3411 mtype, IDENTIFIER_POINTER (METHOD_SEL_NAME (chain)));
3413 chain = TREE_CHAIN (chain);
3417 /* Make sure that the class CLASS_NAME is defined
3418 CODE says which kind of thing CLASS_NAME ought to be.
3419 It can be INTERFACE_TYPE, IMPLEMENTATION_TYPE, PROTOCOL_TYPE
3422 If CODE is INTERFACE_TYPE, we also do a push_obstacks_nochange
3423 whose matching pop is in continue_class. */
3426 start_class (code, class_name, super_name)
3427 enum tree_code code;
3433 if (code == INTERFACE_TYPE)
3435 push_obstacks_nochange ();
3436 end_temporary_allocation ();
3439 if (!doing_objc_thang)
3440 fatal ("Objective-C text in C source file");
3442 class = make_node (code);
3444 CLASS_NAME (class) = class_name;
3445 CLASS_SUPER_NAME (class) = super_name;
3446 CLASS_CLS_METHODS (class) = NULL_TREE;
3448 if (code == IMPLEMENTATION_TYPE)
3450 /* pre-build the following entities - for speed/convenience. */
3452 self_id = get_identifier ("self");
3454 _cmd_id = get_identifier ("_cmd");
3456 if (!objc_super_template)
3457 objc_super_template = build_super_template ();
3459 method_slot = 0; /* reset for multiple classes per file */
3461 implementation_context = class;
3463 /* lookup the interface for this implementation. */
3465 if (!(implementation_template = lookup_interface (class_name)))
3467 warning ("Cannot find interface declaration for `%s'",
3468 IDENTIFIER_POINTER (class_name));
3469 add_class (implementation_template = implementation_context);
3472 /* if a super class has been specified in the implementation,
3473 insure it conforms to the one specified in the interface */
3476 && (super_name != CLASS_SUPER_NAME (implementation_template)))
3478 error ("conflicting super class name `%s'",
3479 IDENTIFIER_POINTER (super_name));
3480 error ("previous declaration of `%s'",
3481 IDENTIFIER_POINTER (CLASS_SUPER_NAME (implementation_template)));
3484 else if (code == INTERFACE_TYPE)
3486 if (lookup_interface (class_name))
3487 warning ("duplicate interface declaration for class `%s'",
3488 IDENTIFIER_POINTER (class_name));
3492 else if (code == PROTOCOL_TYPE)
3494 tree class_category_is_assoc_with;
3496 /* for a category, class_name is really the name of the class that
3497 the following set of methods will be associated with...we must
3498 find the interface so that can derive the objects template */
3500 if (!(class_category_is_assoc_with = lookup_interface (class_name)))
3502 error ("Cannot find interface declaration for `%s'",
3503 IDENTIFIER_POINTER (class_name));
3507 add_category (class_category_is_assoc_with, class);
3509 else if (code == CATEGORY_TYPE)
3511 /* pre-build the following entities - for speed/convenience. */
3513 self_id = get_identifier ("self");
3515 _cmd_id = get_identifier ("_cmd");
3517 if (!objc_super_template)
3518 objc_super_template = build_super_template ();
3520 method_slot = 0; /* reset for multiple classes per file */
3522 implementation_context = class;
3524 /* for a category, class_name is really the name of the class that
3525 the following set of methods will be associated with...we must
3526 find the interface so that can derive the objects template */
3528 if (!(implementation_template = lookup_interface (class_name)))
3530 error ("Cannot find interface declaration for `%s'",
3531 IDENTIFIER_POINTER (class_name));
3539 continue_class (class)
3542 if (TREE_CODE (class) == IMPLEMENTATION_TYPE
3543 || TREE_CODE (class) == CATEGORY_TYPE)
3545 struct imp_entry *impEntry;
3548 /* check consistency of the instance variables. */
3550 if (CLASS_IVARS (class))
3551 check_ivars (implementation_template, class);
3553 /* code generation */
3555 ivar_context = build_private_template (implementation_template);
3557 if (!objc_class_template)
3558 build_class_template ();
3560 if (!(impEntry = (struct imp_entry *)xmalloc (sizeof (struct imp_entry))))
3561 perror ("unable to allocate in objc-tree.c");
3563 impEntry->next = imp_list;
3564 impEntry->imp_context = class;
3565 impEntry->imp_template = implementation_template;
3567 synth_forward_declarations ();
3568 impEntry->class_decl = _OBJC_CLASS_decl;
3569 impEntry->meta_decl = _OBJC_METACLASS_decl;
3571 /* append to front and increment count */
3572 imp_list = impEntry;
3573 if (TREE_CODE (class) == IMPLEMENTATION_TYPE)
3578 return ivar_context;
3580 else if (TREE_CODE (class) == INTERFACE_TYPE)
3582 tree record = xref_tag (RECORD_TYPE, CLASS_NAME (class));
3584 if (!TYPE_FIELDS (record))
3586 finish_struct (record, build_ivar_chain (class));
3587 CLASS_STATIC_TEMPLATE (class) = record;
3589 /* mark this record as a class template - for static typing */
3590 TREE_STATIC_TEMPLATE (record) = 1;
3595 return error_mark_node;
3599 * this is called once we see the "@end" in an interface/implementation.
3602 finish_class (class)
3605 if (TREE_CODE (class) == IMPLEMENTATION_TYPE)
3607 /* all code generation is done in finish_objc */
3609 if (implementation_template != implementation_context)
3611 /* ensure that all method listed in the interface contain bodies! */
3612 check_methods (CLASS_CLS_METHODS (implementation_template),
3613 CLASS_CLS_METHODS (implementation_context), '+');
3614 check_methods (CLASS_NST_METHODS (implementation_template),
3615 CLASS_NST_METHODS (implementation_context), '-');
3618 else if (TREE_CODE (class) == CATEGORY_TYPE)
3620 tree category = CLASS_CATEGORY_LIST (implementation_template);
3622 /* find the category interface from the class it is associated with */
3625 if (CLASS_SUPER_NAME (class) == CLASS_SUPER_NAME (category))
3627 category = CLASS_CATEGORY_LIST (category);
3632 /* ensure that all method listed in the interface contain bodies! */
3633 check_methods (CLASS_CLS_METHODS (category),
3634 CLASS_CLS_METHODS (implementation_context), '+');
3635 check_methods (CLASS_NST_METHODS (category),
3636 CLASS_NST_METHODS (implementation_context), '-');
3639 else if (TREE_CODE (class) == INTERFACE_TYPE)
3642 char *string = (char *) alloca (strlen (IDENTIFIER_POINTER (CLASS_NAME (class))) + 3);
3644 /* extern struct objc_object *_<my_name>; */
3646 sprintf (string, "_%s", IDENTIFIER_POINTER (CLASS_NAME (class)));
3648 decl_specs = build_tree_list (NULLT, ridpointers[(int) RID_EXTERN]);
3649 decl_specs = tree_cons (NULLT, objc_object_reference, decl_specs);
3650 define_decl (build1 (INDIRECT_REF, NULLT, get_identifier (string)),
3655 /* "Encode" a data type into a string, whichg rows in util_obstack.
3656 ??? What is the FORMAT? Someone please document this! */
3658 /* Encode a pointer type. */
3661 encode_pointer (type, format)
3665 tree pointer_to = TREE_TYPE (type);
3667 if (TREE_CODE (pointer_to) == RECORD_TYPE)
3669 if (TYPE_NAME (pointer_to)
3670 && TREE_CODE (TYPE_NAME (pointer_to)) == IDENTIFIER_NODE)
3672 char *name = IDENTIFIER_POINTER (TYPE_NAME (pointer_to));
3674 if ((strcmp (name, TAG_OBJECT) == 0) /* '@' */
3675 || TREE_STATIC_TEMPLATE (pointer_to))
3677 obstack_1grow (&util_obstack, '@');
3680 else if (strcmp (name, TAG_CLASS) == 0) /* '#' */
3682 obstack_1grow (&util_obstack, '#');
3685 #ifndef OBJC_INT_SELECTORS
3686 else if (strcmp (name, TAG_SELECTOR) == 0) /* ':' */
3688 obstack_1grow (&util_obstack, ':');
3691 #endif /* OBJC_INT_SELECTORS */
3694 else if (TREE_CODE (pointer_to) == INTEGER_TYPE
3695 && TYPE_MODE (pointer_to) == QImode)
3697 obstack_1grow (&util_obstack, '*');
3701 /* we have a type that does not get special treatment... */
3703 /* NeXT extension */
3704 obstack_1grow (&util_obstack, '^');
3705 encode_type (pointer_to, format);
3709 encode_array (type, format)
3713 tree anIntCst = TYPE_SIZE (type);
3714 tree array_of = TREE_TYPE (type);
3717 /* An incomplete array is treated like a pointer. */
3718 if (anIntCst == NULL)
3720 /* split for obvious reasons. North-Keys 30 Mar 1991 */
3721 encode_pointer (type, format);
3725 sprintf (buffer, "[%d",
3726 TREE_INT_CST_LOW (anIntCst)
3727 / TREE_INT_CST_LOW (TYPE_SIZE (array_of)));
3728 obstack_grow (&util_obstack, buffer, strlen (buffer));
3729 encode_type (array_of, format);
3730 obstack_1grow (&util_obstack, ']');
3735 encode_aggregate (type, format)
3739 enum tree_code code = TREE_CODE (type);
3745 if (*obstack_next_free (&util_obstack) == '^'
3746 || format != OBJC_ENCODE_INLINE_DEFS)
3748 /* we have a reference - this is a NeXT extension--
3749 or we don't want the details. */
3750 if (TYPE_NAME (type)
3751 && (TREE_CODE (TYPE_NAME (type)) == IDENTIFIER_NODE))
3753 obstack_1grow (&util_obstack, '{');
3754 obstack_grow (&util_obstack,
3755 IDENTIFIER_POINTER (TYPE_NAME (type)),
3756 strlen (IDENTIFIER_POINTER (TYPE_NAME (type))));
3757 obstack_1grow (&util_obstack, '}');
3759 else /* we have an untagged structure or a typedef */
3760 obstack_grow (&util_obstack, "{?}", 3);
3764 tree fields = TYPE_FIELDS (type);
3765 obstack_1grow (&util_obstack, '{');
3766 for ( ; fields; fields = TREE_CHAIN (fields))
3767 encode_field_decl (fields, format);
3768 obstack_1grow (&util_obstack, '}');
3774 if (*obstack_next_free (&util_obstack) == '^'
3775 || format != OBJC_ENCODE_INLINE_DEFS)
3777 /* we have a reference - this is a NeXT extension--
3778 or we don't want the details. */
3779 if (TYPE_NAME (type)
3780 && (TREE_CODE (TYPE_NAME (type)) == IDENTIFIER_NODE))
3782 obstack_1grow (&util_obstack, '<');
3783 obstack_grow (&util_obstack,
3784 IDENTIFIER_POINTER (TYPE_NAME (type)),
3785 strlen (IDENTIFIER_POINTER (TYPE_NAME (type))));
3786 obstack_1grow (&util_obstack, '>');
3788 else /* we have an untagged structure or a typedef */
3789 obstack_grow (&util_obstack, "<?>", 3);
3793 tree fields = TYPE_FIELDS (type);
3794 obstack_1grow (&util_obstack, '<');
3795 for ( ; fields; fields = TREE_CHAIN (fields))
3796 encode_field_decl (fields, format);
3797 obstack_1grow (&util_obstack, '>');
3803 obstack_1grow (&util_obstack, 'i');
3809 * support bitfields, the current version of Objective-C does not support
3810 * them. the string will consist of one or more "b:n"'s where n is an
3811 * integer describing the width of the bitfield. Currently, classes in
3812 * the kit implement a method "-(char *)describeBitfieldStruct:" that
3813 * simulates this...if they do not implement this method, the archiver
3814 * assumes the bitfield is 16 bits wide (padded if necessary) and packed
3815 * according to the GNU compiler. After looking at the "kit", it appears
3816 * that all classes currently rely on this default behavior, rather than
3817 * hand generating this string (which is tedious).
3820 encode_bitfield (width, format)
3825 sprintf (buffer, "b%d", width);
3826 obstack_grow (&util_obstack, buffer, strlen (buffer));
3832 * OBJC_ENCODE_INLINE_DEFS or OBJC_ENCODE_DONT_INLINE_DEFS
3835 encode_type (type, format)
3839 enum tree_code code = TREE_CODE (type);
3841 if (code == INTEGER_TYPE)
3843 if (TREE_INT_CST_LOW (TYPE_MIN_VALUE (type)) == 0)
3845 /* unsigned integer types */
3847 if (TYPE_MODE (type) == QImode) /* 'C' */
3848 obstack_1grow (&util_obstack, 'C');
3849 else if (TYPE_MODE (type) == HImode) /* 'S' */
3850 obstack_1grow (&util_obstack, 'S');
3851 else if (TYPE_MODE (type) == SImode)
3853 if (type == long_unsigned_type_node)
3854 obstack_1grow (&util_obstack, 'L'); /* 'L' */
3856 obstack_1grow (&util_obstack, 'I'); /* 'I' */
3859 else /* signed integer types */
3861 if (TYPE_MODE (type) == QImode) /* 'c' */
3862 obstack_1grow (&util_obstack, 'c');
3863 else if (TYPE_MODE (type) == HImode) /* 's' */
3864 obstack_1grow (&util_obstack, 's');
3865 else if (TYPE_MODE (type) == SImode) /* 'i' */
3867 if (type == long_integer_type_node)
3868 obstack_1grow (&util_obstack, 'l'); /* 'l' */
3870 obstack_1grow (&util_obstack, 'i'); /* 'i' */
3874 else if (code == REAL_TYPE)
3876 /* floating point types */
3878 if (TYPE_MODE (type) == SFmode) /* 'f' */
3879 obstack_1grow (&util_obstack, 'f');
3880 else if (TYPE_MODE (type) == DFmode
3881 || TYPE_MODE (type) == TFmode) /* 'd' */
3882 obstack_1grow (&util_obstack, 'd');
3885 else if (code == VOID_TYPE) /* 'v' */
3886 obstack_1grow (&util_obstack, 'v');
3888 else if (code == ARRAY_TYPE)
3889 encode_array (type, format);
3891 else if (code == POINTER_TYPE)
3892 encode_pointer (type, format);
3894 else if (code == RECORD_TYPE || code == UNION_TYPE || code == ENUMERAL_TYPE)
3895 encode_aggregate (type, format);
3897 else if (code == FUNCTION_TYPE) /* '?' */
3898 obstack_1grow (&util_obstack, '?');
3902 encode_field_decl (field_decl, format)
3906 if (DECL_BIT_FIELD (field_decl))
3907 encode_bitfield (DECL_FIELD_SIZE (field_decl), format);
3909 encode_type (TREE_TYPE (field_decl), format);
3913 expr_last (complex_expr)
3919 while (next = TREE_OPERAND (complex_expr, 0))
3920 complex_expr = next;
3921 return complex_expr;
3924 /* The selector of the current method,
3925 or NULL if we aren't compiling a method. */
3928 maybe_objc_method_name (decl)
3932 return METHOD_SEL_NAME (method_context);
3938 * Transform a method definition into a function definition as follows:
3940 * - synthesize the first two arguments, "self" and "_cmd".
3944 start_method_def (method)
3949 /* required to implement _msgSuper () */
3950 method_context = method;
3951 _OBJC_SUPER_decl = NULLT;
3953 pushlevel (0); /* must be called BEFORE "start_function ()" */
3955 /* generate prototype declarations for arguments..."new-style" */
3957 if (TREE_CODE (method_context) == INSTANCE_METHOD_DECL)
3958 decl_specs = build_tree_list (NULLT, _PRIVATE_record);
3960 /* really a `struct objc_class *'...however we allow people to
3961 assign to self...which changes its type midstream.
3963 decl_specs = build_tree_list (NULLT, objc_object_reference);
3965 push_parm_decl (build_tree_list (decl_specs,
3966 build1 (INDIRECT_REF, NULLT, self_id)));
3968 #ifdef OBJC_INT_SELECTORS
3969 decl_specs = build_tree_list (NULLT, ridpointers[(int) RID_UNSIGNED]);
3970 decl_specs = tree_cons (NULLT, ridpointers[(int) RID_INT], decl_specs);
3971 push_parm_decl (build_tree_list (decl_specs, _cmd_id));
3972 #else /* not OBJC_INT_SELECTORS */
3973 decl_specs = build_tree_list (NULLT,
3974 xref_tag (RECORD_TYPE,
3975 get_identifier (TAG_SELECTOR)));
3976 push_parm_decl (build_tree_list (decl_specs,
3977 build1 (INDIRECT_REF, NULLT, _cmd_id)));
3978 #endif /* not OBJC_INT_SELECTORS */
3980 /* generate argument declarations if a keyword_decl */
3981 if (METHOD_SEL_ARGS (method))
3983 tree arglist = METHOD_SEL_ARGS (method);
3986 tree arg_spec = TREE_PURPOSE (TREE_TYPE (arglist));
3987 tree arg_decl = TREE_VALUE (TREE_TYPE (arglist));
3991 tree last_expr = expr_last (arg_decl);
3993 /* unite the abstract decl with its name */
3994 TREE_OPERAND (last_expr, 0) = KEYWORD_ARG_NAME (arglist);
3995 push_parm_decl (build_tree_list (arg_spec, arg_decl));
3996 /* unhook...restore the abstract declarator */
3997 TREE_OPERAND (last_expr, 0) = NULLT;
4000 push_parm_decl (build_tree_list (arg_spec, KEYWORD_ARG_NAME (arglist)));
4002 arglist = TREE_CHAIN (arglist);
4007 if (METHOD_ADD_ARGS (method) > (tree)1)
4009 /* we have a variable length selector - in "prototype" format */
4010 tree akey = TREE_PURPOSE (METHOD_ADD_ARGS (method));
4013 /* this must be done prior to calling pushdecl (). pushdecl () is
4014 * going to change our chain on us...
4016 tree nextkey = TREE_CHAIN (akey);
4024 error_with_method (message, mtype, method)
4030 fprintf (stderr, "%s:%d: ",
4031 DECL_SOURCE_FILE (method), DECL_SOURCE_LINE (method));
4032 bzero (errbuf, BUFSIZE);
4033 fprintf (stderr, "%s `%c%s'\n", message, mtype, gen_method_decl (method, errbuf));
4037 warn_with_method (message, mtype, method)
4043 fprintf (stderr, "%s:%d: ",
4044 DECL_SOURCE_FILE (method), DECL_SOURCE_LINE (method));
4045 bzero (errbuf, BUFSIZE);
4046 fprintf (stderr, "%s `%c%s'\n", message, mtype, gen_method_decl (method, errbuf));
4049 /* return 1 if `method' is consistent with `proto' */
4052 comp_method_with_proto (method, proto)
4055 static tree function_type = 0;
4057 /* create a function_type node once */
4060 struct obstack *ambient_obstack = current_obstack;
4062 current_obstack = &permanent_obstack;
4063 function_type = make_node (FUNCTION_TYPE);
4064 current_obstack = ambient_obstack;
4067 /* install argument types - normally set by "build_function_type ()". */
4068 TYPE_ARG_TYPES (function_type) = get_arg_type_list (proto, METHOD_DEF, 0);
4070 /* install return type */
4071 TREE_TYPE (function_type) = groktypename (TREE_TYPE (proto));
4073 return comptypes (TREE_TYPE (METHOD_DEFINITION (method)), function_type);
4076 /* return 1 if `proto1' is consistent with `proto2' */
4079 comp_proto_with_proto (proto1, proto2)
4080 tree proto1, proto2;
4082 static tree function_type1 = 0, function_type2 = 0;
4084 /* create a couple function_type node's once */
4085 if (!function_type1)
4087 struct obstack *ambient_obstack = current_obstack;
4089 current_obstack = &permanent_obstack;
4090 function_type1 = make_node (FUNCTION_TYPE);
4091 function_type2 = make_node (FUNCTION_TYPE);
4092 current_obstack = ambient_obstack;
4095 /* install argument types - normally set by "build_function_type ()". */
4096 TYPE_ARG_TYPES (function_type1) = get_arg_type_list (proto1, METHOD_REF, 0);
4097 TYPE_ARG_TYPES (function_type2) = get_arg_type_list (proto2, METHOD_REF, 0);
4099 /* install return type */
4100 TREE_TYPE (function_type1) = groktypename (TREE_TYPE (proto1));
4101 TREE_TYPE (function_type2) = groktypename (TREE_TYPE (proto2));
4103 return comptypes (function_type1, function_type2);
4107 * - generate an identifier for the function. the format is "_n_cls",
4108 * where 1 <= n <= nMethods, and cls is the name the implementation we
4110 * - install the return type from the method declaration.
4111 * - if we have a prototype, check for type consistency.
4114 really_start_method (method, parmlist)
4115 tree method, parmlist;
4117 tree sc_spec, ret_spec, ret_decl, decl_specs;
4118 tree method_decl, method_id;
4121 /* synth the storage class & assemble the return type */
4122 sc_spec = tree_cons (NULLT, ridpointers[(int) RID_STATIC], NULLT);
4123 ret_spec = TREE_PURPOSE (TREE_TYPE (method));
4124 decl_specs = chainon (sc_spec, ret_spec);
4126 if (TREE_CODE (implementation_context) == IMPLEMENTATION_TYPE)
4128 /* Make sure this is big enough for any plausible method label. */
4129 buf = (char *) alloca (50
4130 + strlen (IDENTIFIER_POINTER (METHOD_SEL_NAME (method)))
4131 + strlen (IDENTIFIER_POINTER (CLASS_NAME (implementation_context))));
4132 #ifdef OBJC_GEN_METHOD_LABEL
4133 OBJC_GEN_METHOD_LABEL (buf,
4134 TREE_CODE (method) == INSTANCE_METHOD_DECL,
4135 IDENTIFIER_POINTER (CLASS_NAME (implementation_context)),
4137 IDENTIFIER_POINTER (METHOD_SEL_NAME (method)));
4139 sprintf (buf, "_%d_%s", ++method_slot,
4140 IDENTIFIER_POINTER (CLASS_NAME (implementation_context)));
4143 else /* we have a category */
4145 /* Make sure this is big enough for any plausible method label. */
4146 buf = (char *) alloca (50
4147 + strlen (IDENTIFIER_POINTER (METHOD_SEL_NAME (method)))
4148 + strlen (IDENTIFIER_POINTER (CLASS_SUPER_NAME (implementation_context)))
4149 + strlen (IDENTIFIER_POINTER (CLASS_NAME (implementation_context))));
4150 #ifdef OBJC_GEN_METHOD_LABEL
4151 OBJC_GEN_METHOD_LABEL (buf,
4152 TREE_CODE (method) == INSTANCE_METHOD_DECL,
4153 IDENTIFIER_POINTER (CLASS_NAME (implementation_context)),
4154 IDENTIFIER_POINTER (CLASS_SUPER_NAME (implementation_context)),
4155 IDENTIFIER_POINTER (METHOD_SEL_NAME (method)));
4157 sprintf (buf, "_%d_%s_%s", ++method_slot,
4158 IDENTIFIER_POINTER (CLASS_NAME (implementation_context)),
4159 IDENTIFIER_POINTER (CLASS_SUPER_NAME (implementation_context)));
4163 method_id = get_identifier (buf);
4165 method_decl = build_nt (CALL_EXPR, method_id, parmlist, NULLT);
4167 /* check the declarator portion of the return type for the method */
4168 if (ret_decl = TREE_VALUE (TREE_TYPE (method)))
4171 * unite the complex decl (specified in the abstract decl) with the
4172 * function decl just synthesized...(int *), (int (*)()), (int (*)[]).
4174 tree save_expr = expr_last (ret_decl);
4176 TREE_OPERAND (save_expr, 0) = method_decl;
4177 method_decl = ret_decl;
4178 /* fool the parser into thinking it is starting a function */
4179 start_function (decl_specs, method_decl, 0);
4180 /* unhook...this has the effect of restoring the abstract declarator */
4181 TREE_OPERAND (save_expr, 0) = NULLT;
4185 TREE_VALUE (TREE_TYPE (method)) = method_decl;
4186 /* fool the parser into thinking it is starting a function */
4187 start_function (decl_specs, method_decl, 0);
4188 /* unhook...this has the effect of restoring the abstract declarator */
4189 TREE_VALUE (TREE_TYPE (method)) = NULLT;
4192 METHOD_DEFINITION (method) = current_function_decl;
4194 /* check consistency...start_function (), pushdecl (), duplicate_decls (). */
4196 if (implementation_template != implementation_context)
4200 if (TREE_CODE (method) == INSTANCE_METHOD_DECL)
4201 chain = CLASS_NST_METHODS (implementation_template);
4203 chain = CLASS_CLS_METHODS (implementation_template);
4205 if (proto = lookup_method (chain, METHOD_SEL_NAME (method)))
4207 if (!comp_method_with_proto (method, proto))
4209 fprintf (stderr, "%s: In method `%s'\n", input_filename,
4210 IDENTIFIER_POINTER (METHOD_SEL_NAME (method)));
4211 if (TREE_CODE (method) == INSTANCE_METHOD_DECL)
4213 error_with_method ("conflicting types for", '-', method);
4214 error_with_method ("previous declaration of", '-', proto);
4218 error_with_method ("conflicting types for", '+', method);
4219 error_with_method ("previous declaration of", '+', proto);
4227 * the following routine is always called...this "architecture" is to
4228 * accommodate "old-style" variable length selectors.
4230 * - a:a b:b // prototype ; id c; id d; // old-style
4233 continue_method_def ()
4237 if (METHOD_ADD_ARGS (method_context) == (tree)1)
4239 * we have a `, ...' immediately following the selector.
4241 parmlist = get_parm_info (0);
4243 parmlist = get_parm_info (1); /* place a `void_at_end' */
4245 /* set self_decl from the first argument...this global is used by
4246 * build_ivar_reference ().build_indirect_ref ().
4248 self_decl = TREE_PURPOSE (parmlist);
4250 poplevel (0, 0, 0); /* must be called BEFORE "start_function ()" */
4252 really_start_method (method_context, parmlist);
4254 store_parm_decls (); /* must be called AFTER "start_function ()" */
4260 if (!_OBJC_SUPER_decl)
4261 _OBJC_SUPER_decl = start_decl (get_identifier (_TAG_SUPER),
4262 build_tree_list (NULLT, objc_super_template), 0);
4264 /* this prevents `unused variable' warnings when compiling with `-Wall' */
4265 DECL_IN_SYSTEM_HEADER (_OBJC_SUPER_decl) = 1;
4269 * _n_Method (id self, SEL sel, ...)
4271 * struct objc_super _S;
4273 * _msgSuper ((_S.self = self, _S.class = _cls, &_S), ...);
4277 get_super_receiver ()
4281 tree super_expr, super_expr_list;
4283 /* set receiver to self */
4284 super_expr = build_component_ref (_OBJC_SUPER_decl, self_id);
4285 super_expr = build_modify_expr (super_expr, NOP_EXPR, self_decl);
4286 super_expr_list = build_tree_list (NULLT, super_expr);
4288 /* set class to begin searching */
4289 super_expr = build_component_ref (_OBJC_SUPER_decl, get_identifier ("class"));
4291 if (TREE_CODE (implementation_context) == IMPLEMENTATION_TYPE)
4293 /* [_cls, __cls]Super are "pre-built" in synth_foward_declarations () */
4295 if (TREE_CODE (method_context) == INSTANCE_METHOD_DECL)
4296 super_expr = build_modify_expr (super_expr, NOP_EXPR, _clsSuper_ref);
4298 super_expr = build_modify_expr (super_expr, NOP_EXPR, __clsSuper_ref);
4300 else /* we have a category... */
4302 tree params, super_name = CLASS_SUPER_NAME (implementation_template);
4305 if (!super_name) /* Barf if super used in a category of Object. */
4307 error("no super class declared in interface for `%s'",
4308 IDENTIFIER_POINTER (CLASS_NAME (implementation_template)));
4309 return error_mark_node;
4312 add_class_reference (super_name);
4314 params = build_tree_list (NULLT,
4315 my_build_string (IDENTIFIER_LENGTH (super_name) + 1,
4316 IDENTIFIER_POINTER (super_name)));
4318 if (TREE_CODE (method_context) == INSTANCE_METHOD_DECL)
4319 funcCall = build_function_call (objc_getClass_decl, params);
4321 funcCall = build_function_call (objc_getMetaClass_decl, params);
4324 TREE_TYPE (funcCall) = TREE_TYPE (_clsSuper_ref);
4325 super_expr = build_modify_expr (super_expr, NOP_EXPR, funcCall);
4327 chainon (super_expr_list, build_tree_list (NULL_TREE, super_expr));
4329 super_expr = build_unary_op (ADDR_EXPR, _OBJC_SUPER_decl, 0);
4330 chainon (super_expr_list, build_tree_list (NULL_TREE, super_expr));
4332 return build_compound_expr (super_expr_list);
4336 error ("[super ...] must appear in a method context");
4337 return error_mark_node;
4342 encode_method_def (func_decl)
4351 encode_type (TREE_TYPE (TREE_TYPE (func_decl)),
4352 OBJC_ENCODE_DONT_INLINE_DEFS);
4354 for (parms = DECL_ARGUMENTS (func_decl); parms;
4355 parms = TREE_CHAIN (parms))
4356 stack_size += TREE_INT_CST_LOW (TYPE_SIZE (DECL_ARG_TYPE (parms)))
4359 sprintf (buffer, "%d", stack_size);
4360 obstack_grow (&util_obstack, buffer, strlen (buffer));
4362 /* argument types */
4363 for (parms = DECL_ARGUMENTS (func_decl); parms;
4364 parms = TREE_CHAIN (parms))
4366 int offset_in_bytes;
4369 encode_type (TREE_TYPE (parms), OBJC_ENCODE_DONT_INLINE_DEFS);
4371 /* compute offset */
4372 if (GET_CODE (DECL_INCOMING_RTL (parms)) == MEM)
4374 rtx addr = XEXP (DECL_INCOMING_RTL (parms), 0);
4376 /* ??? Here we assume that the parm address is indexed
4377 off the frame pointer or arg pointer.
4378 If that is not true, we produce meaningless results,
4379 but do not crash. */
4380 if (GET_CODE (addr) == PLUS
4381 && GET_CODE (XEXP (addr, 1)) == CONST_INT)
4382 offset_in_bytes = INTVAL (XEXP (addr, 1));
4384 offset_in_bytes = 0;
4386 /* This is the case where the parm is passed as an int or double
4387 and it is converted to a char, short or float and stored back
4388 in the parmlist. In this case, describe the parm
4389 with the variable's declared type, and adjust the address
4390 if the least significant bytes (which we are using) are not
4392 #if BYTES_BIG_ENDIAN
4393 if (TREE_TYPE (parms) != DECL_ARG_TYPE (parms))
4394 offset_in_bytes += (GET_MODE_SIZE (TYPE_MODE (DECL_ARG_TYPE (parms)))
4395 - GET_MODE_SIZE (GET_MODE (DECL_RTL (parms))));
4399 offset_in_bytes = 0;
4401 /* The "+ 4" is a total hack to account for the return pc and
4402 saved fp on the 68k. We should redefine this format! */
4403 sprintf (buffer, "%d", offset_in_bytes + 8);
4404 obstack_grow (&util_obstack, buffer, strlen (buffer));
4407 result = get_identifier (obstack_finish (&util_obstack));
4408 obstack_free (&util_obstack, util_firstobj);
4413 finish_method_def ()
4415 METHOD_ENCODING (method_context) =
4416 encode_method_def (current_function_decl);
4418 finish_function (0);
4420 /* this must be done AFTER finish_function, since the optimizer may
4421 find "may be used before set" errors. */
4422 method_context = NULLT; /* required to implement _msgSuper () */
4426 lang_report_error_function (decl)
4431 fprintf (stderr, "In method `%s'\n",
4432 IDENTIFIER_POINTER (METHOD_SEL_NAME (method_context)));
4440 is_complex_decl (type)
4443 return (TREE_CODE (type) == ARRAY_TYPE
4444 || TREE_CODE (type) == FUNCTION_TYPE
4445 || TREE_CODE (type) == POINTER_TYPE);
4449 /* Code to convert a decl node into text for a declaration in C. */
4451 static char tmpbuf[256];
4454 adorn_decl (decl, str)
4458 enum tree_code code = TREE_CODE (decl);
4460 if (code == ARRAY_REF)
4462 tree anIntCst = TREE_OPERAND (decl, 1);
4464 sprintf (str + strlen (str), "[%d]", TREE_INT_CST_LOW (anIntCst));
4466 else if (code == ARRAY_TYPE)
4468 tree anIntCst = TYPE_SIZE (decl);
4469 tree array_of = TREE_TYPE (decl);
4471 sprintf (str + strlen (str), "[%d]",
4472 TREE_INT_CST_LOW (anIntCst)/TREE_INT_CST_LOW (TYPE_SIZE (array_of)));
4474 else if (code == CALL_EXPR)
4476 else if (code == FUNCTION_TYPE)
4478 tree chain = TYPE_ARG_TYPES (decl); /* a list of types */
4480 while (chain && TREE_VALUE (chain) != void_type_node)
4482 gen_declaration (TREE_VALUE (chain), str);
4483 chain = TREE_CHAIN (chain);
4484 if (chain && TREE_VALUE (chain) != void_type_node)
4491 strcpy (tmpbuf, "*"); strcat (tmpbuf, str);
4492 strcpy (str, tmpbuf);
4497 gen_declarator (decl, buf, name)
4504 enum tree_code code = TREE_CODE (decl);
4511 case ARRAY_REF: case INDIRECT_REF: case CALL_EXPR:
4513 op = TREE_OPERAND (decl, 0);
4515 /* we have a pointer to a function or array...(*)(), (*)[] */
4516 if ((code == ARRAY_REF || code == CALL_EXPR) &&
4517 (op && TREE_CODE (op) == INDIRECT_REF))
4520 str = gen_declarator (op, buf, name);
4524 strcpy (tmpbuf, "("); strcat (tmpbuf, str); strcat (tmpbuf, ")");
4525 strcpy (str, tmpbuf);
4528 adorn_decl (decl, str);
4531 case ARRAY_TYPE: case FUNCTION_TYPE: case POINTER_TYPE:
4533 str = strcpy (buf, name);
4535 /* this clause is done iteratively...rather than recursively */
4538 op = is_complex_decl (TREE_TYPE (decl))
4542 adorn_decl (decl, str);
4544 /* we have a pointer to a function or array...(*)(), (*)[] */
4545 if ((code == POINTER_TYPE) &&
4546 (op && (TREE_CODE (op) == FUNCTION_TYPE
4547 || TREE_CODE (op) == ARRAY_TYPE)))
4549 strcpy (tmpbuf, "("); strcat (tmpbuf, str); strcat (tmpbuf, ")");
4550 strcpy (str, tmpbuf);
4553 decl = is_complex_decl (TREE_TYPE (decl))
4557 while (decl && (code = TREE_CODE (decl)));
4561 case IDENTIFIER_NODE:
4562 /* will only happen if we are processing a "raw" expr-decl. */
4563 return strcpy (buf, IDENTIFIER_POINTER (decl));
4568 else /* we have an abstract declarator or a _DECL node */
4570 return strcpy (buf, name);
4575 gen_declspecs (declspecs, buf, raw)
4584 for (chain = declspecs; chain; chain = TREE_CHAIN (chain))
4586 tree aspec = TREE_VALUE (chain);
4588 if (TREE_CODE (aspec) == IDENTIFIER_NODE)
4589 strcat (buf, IDENTIFIER_POINTER (aspec));
4590 else if (TREE_CODE (aspec) == RECORD_TYPE)
4592 if (TYPE_NAME (aspec))
4594 if (!TREE_STATIC_TEMPLATE (aspec))
4595 strcat (buf, "struct ");
4596 strcat (buf, IDENTIFIER_POINTER (TYPE_NAME (aspec)));
4599 strcat (buf, "untagged struct");
4601 else if (TREE_CODE (aspec) == UNION_TYPE)
4603 if (TYPE_NAME (aspec))
4605 if (!TREE_STATIC_TEMPLATE (aspec))
4606 strcat (buf, "union ");
4607 strcat (buf, IDENTIFIER_POINTER (TYPE_NAME (aspec)));
4610 strcat (buf, "untagged union");
4612 else if (TREE_CODE (aspec) == ENUMERAL_TYPE)
4614 if (TYPE_NAME (aspec))
4616 if (!TREE_STATIC_TEMPLATE (aspec))
4617 strcat (buf, "enum ");
4618 strcat (buf, IDENTIFIER_POINTER (TYPE_NAME (aspec)));
4621 strcat (buf, "untagged enum");
4627 switch (TREE_CODE (declspecs))
4629 /* type specifiers */
4631 case INTEGER_TYPE: /* signed integer types */
4633 if (declspecs == short_integer_type_node) /* 's' */
4634 strcat (buf, "short int ");
4635 else if (declspecs == integer_type_node) /* 'i' */
4636 strcat (buf, "int ");
4637 else if (declspecs == long_integer_type_node) /* 'l' */
4638 strcat (buf, "long int ");
4639 else if (declspecs == signed_char_type_node || /* 'c' */
4640 declspecs == char_type_node)
4641 strcat (buf, "char ");
4643 /* unsigned integer types */
4645 else if (declspecs == short_unsigned_type_node) /* 'S' */
4646 strcat (buf, "unsigned short ");
4647 else if (declspecs == unsigned_type_node) /* 'I' */
4648 strcat (buf, "unsigned int ");
4649 else if (declspecs == long_unsigned_type_node) /* 'L' */
4650 strcat (buf, "unsigned long ");
4651 else if (declspecs == unsigned_char_type_node) /* 'C' */
4652 strcat (buf, "unsigned char ");
4655 case REAL_TYPE: /* floating point types */
4657 if (declspecs == float_type_node) /* 'f' */
4658 strcat (buf, "float ");
4659 else if (declspecs == double_type_node) /* 'd' */
4660 strcat (buf, "double ");
4661 else if (declspecs == long_double_type_node) /* 'd' */
4662 strcat (buf, "long double ");
4666 if (!TREE_STATIC_TEMPLATE (declspecs))
4667 strcat (buf, "struct ");
4668 if (TYPE_NAME (declspecs) &&
4669 (TREE_CODE (TYPE_NAME (declspecs)) == IDENTIFIER_NODE))
4671 strcat (buf, IDENTIFIER_POINTER (TYPE_NAME (declspecs)));
4676 strcat (buf, "union ");
4677 if (TYPE_NAME (declspecs) &&
4678 (TREE_CODE (TYPE_NAME (declspecs)) == IDENTIFIER_NODE))
4680 strcat (buf, IDENTIFIER_POINTER (TYPE_NAME (declspecs)));
4685 strcat (buf, "enum ");
4686 if (TYPE_NAME (declspecs) &&
4687 (TREE_CODE (TYPE_NAME (declspecs)) == IDENTIFIER_NODE))
4689 strcat (buf, IDENTIFIER_POINTER (TYPE_NAME (declspecs)));
4694 strcat (buf, "void ");
4699 gen_declaration (atype_or_adecl, buf)
4700 tree atype_or_adecl;
4705 if (TREE_CODE (atype_or_adecl) == TREE_LIST)
4707 tree declspecs; /* "identifier_node", "record_type" */
4708 tree declarator; /* "array_ref", "indirect_ref", "call_expr"... */
4710 /* we have a "raw", abstract declarator (typename) */
4711 declarator = TREE_VALUE (atype_or_adecl);
4712 declspecs = TREE_PURPOSE (atype_or_adecl);
4714 gen_declspecs (declspecs, buf, 1);
4715 strcat (buf, gen_declarator (declarator, declbuf, ""));
4720 tree declspecs; /* "integer_type", "real_type", "record_type"... */
4721 tree declarator; /* "array_type", "function_type", "pointer_type". */
4723 if (TREE_CODE (atype_or_adecl) == FIELD_DECL
4724 || TREE_CODE (atype_or_adecl) == PARM_DECL
4725 || TREE_CODE (atype_or_adecl) == FUNCTION_DECL)
4726 atype = TREE_TYPE (atype_or_adecl);
4728 atype = atype_or_adecl; /* assume we have a *_type node */
4730 if (is_complex_decl (atype))
4734 /* get the declaration specifier...it is at the end of the list */
4735 declarator = chain = atype;
4737 chain = TREE_TYPE (chain); /* not TREE_CHAIN (chain); */
4738 while (is_complex_decl (chain));
4747 gen_declspecs (declspecs, buf, 0);
4749 if (TREE_CODE (atype_or_adecl) == FIELD_DECL
4750 || TREE_CODE (atype_or_adecl) == PARM_DECL
4751 || TREE_CODE (atype_or_adecl) == FUNCTION_DECL)
4755 strcat (buf, gen_declarator (declarator, declbuf,
4756 IDENTIFIER_POINTER (DECL_NAME (atype_or_adecl))));
4759 strcat (buf, IDENTIFIER_POINTER (DECL_NAME (atype_or_adecl)));
4763 strcat (buf, gen_declarator (declarator, declbuf, ""));
4769 #define RAW_TYPESPEC(meth) (TREE_VALUE (TREE_PURPOSE (TREE_TYPE (meth))))
4772 gen_method_decl (method, buf)
4778 if (RAW_TYPESPEC (method) != objc_object_reference)
4781 gen_declaration (TREE_TYPE (method), buf);
4785 chain = METHOD_SEL_ARGS (method);
4787 { /* we have a chain of keyword_decls */
4790 if (KEYWORD_KEY_NAME (chain))
4791 strcat (buf, IDENTIFIER_POINTER (KEYWORD_KEY_NAME (chain)));
4794 if (RAW_TYPESPEC (chain) != objc_object_reference)
4797 gen_declaration (TREE_TYPE (chain), buf);
4800 strcat (buf, IDENTIFIER_POINTER (KEYWORD_ARG_NAME (chain)));
4801 if (chain = TREE_CHAIN (chain))
4806 if (METHOD_ADD_ARGS (method) == (tree)1)
4807 strcat (buf, ", ...");
4808 else if (METHOD_ADD_ARGS (method))
4809 { /* we have a tree list node as generate by `get_parm_info ()' */
4810 chain = TREE_PURPOSE (METHOD_ADD_ARGS (method));
4811 /* know we have a chain of parm_decls */
4815 gen_declaration (chain, buf);
4816 chain = TREE_CHAIN (chain);
4820 else /* we have a unary selector */
4822 strcat (buf, IDENTIFIER_POINTER (METHOD_SEL_NAME (method)));
4829 gen_prototype (fp, decl)
4833 /* we have a function definition - generate prototype */
4834 bzero (errbuf, BUFSIZE);
4835 gen_declaration (decl, errbuf);
4836 fprintf (fp, "%s;\n", errbuf);
4842 dump_interface (fp, chain)
4846 char *buf = (char *)xmalloc (256);
4847 char *my_name = IDENTIFIER_POINTER (CLASS_NAME (chain));
4848 tree ivar_decls = CLASS_RAW_IVARS (chain);
4849 tree nst_methods = CLASS_NST_METHODS (chain);
4850 tree cls_methods = CLASS_CLS_METHODS (chain);
4852 fprintf (fp, "\n@interface %s", my_name);
4854 if (CLASS_SUPER_NAME (chain))
4856 char *super_name = IDENTIFIER_POINTER (CLASS_SUPER_NAME (chain));
4857 fprintf (fp, " : %s\n", super_name);
4864 fprintf (fp, "{\n");
4868 fprintf (fp, "\t%s;\n", gen_declaration (ivar_decls, buf));
4869 ivar_decls = TREE_CHAIN (ivar_decls);
4872 fprintf (fp, "}\n");
4878 fprintf (fp, "- %s;\n", gen_method_decl (nst_methods, buf));
4879 nst_methods = TREE_CHAIN (nst_methods);
4885 fprintf (fp, "+ %s;\n", gen_method_decl (cls_methods, buf));
4886 cls_methods = TREE_CHAIN (cls_methods);
4888 fprintf (fp, "\n@end");
4894 /* Add the special tree codes of Objective C to the tables. */
4896 gcc_obstack_init (&util_obstack);
4897 util_firstobj = (char *) obstack_finish (&util_obstack);
4900 = (char **) realloc (tree_code_type,
4901 sizeof (char *) * LAST_OBJC_TREE_CODE);
4903 = (int *) realloc (tree_code_length,
4904 sizeof (int) * LAST_OBJC_TREE_CODE);
4906 = (char **) realloc (tree_code_name,
4907 sizeof (char *) * LAST_OBJC_TREE_CODE);
4908 bcopy (objc_tree_code_type,
4909 tree_code_type + (int) LAST_AND_UNUSED_TREE_CODE,
4910 (((int) LAST_OBJC_TREE_CODE - (int) LAST_AND_UNUSED_TREE_CODE)
4911 * sizeof (char *)));
4912 bcopy (objc_tree_code_length,
4913 tree_code_length + (int) LAST_AND_UNUSED_TREE_CODE,
4914 (((int) LAST_OBJC_TREE_CODE - (int) LAST_AND_UNUSED_TREE_CODE)
4916 bcopy (objc_tree_code_name,
4917 tree_code_name + (int) LAST_AND_UNUSED_TREE_CODE,
4918 (((int) LAST_OBJC_TREE_CODE - (int) LAST_AND_UNUSED_TREE_CODE)
4919 * sizeof (char *)));
4921 errbuf = (char *)xmalloc (BUFSIZE);
4923 synth_module_prologue ();
4929 struct imp_entry *impent;
4932 generate_forward_declaration_to_string_table ();
4934 #ifdef OBJC_PROLOGUE
4938 if (implementation_context || sel_refdef_chain)
4939 generate_objc_symtab_decl ();
4941 for (impent = imp_list; impent; impent = impent->next)
4943 implementation_context = impent->imp_context;
4944 implementation_template = impent->imp_template;
4946 _OBJC_CLASS_decl = impent->class_decl;
4947 _OBJC_METACLASS_decl = impent->meta_decl;
4949 if (TREE_CODE (implementation_context) == IMPLEMENTATION_TYPE)
4951 /* all of the following reference the string pool... */
4952 generate_ivar_lists ();
4953 generate_dispatch_tables ();
4954 generate_shared_structures ();
4958 generate_dispatch_tables ();
4959 generate_category (implementation_context);
4964 build_selector_translation_table ();
4966 if (implementation_context || sel_refdef_chain)
4968 /* Arrange for Objc data structures to be initialized at run time. */
4970 char *init_name = build_module_descriptor ();
4972 assemble_constructor (init_name);
4975 /* dump the string table last */
4977 if (sel_refdef_chain)
4979 build_message_selector_pool ();
4982 /* dump the class references...this forces the appropriate classes
4983 to be linked into the executable image, preserving unix archive
4984 semantics...this can be removed when we move to a more dynamically
4987 for (chain = cls_ref_chain; chain; chain = TREE_CHAIN (chain))
4988 handle_class_ref (chain);
4990 for (impent = imp_list; impent; impent = impent->next)
4991 handle_impent (impent);
4993 #if 0 /* If GAS has such a bug, let's fix it. */
4994 /*** this fixes a gross bug in the assembler...it `expects' #APP to have
4995 *** a matching #NO_APP, or it crashes (sometimes). app_disable () will
4996 *** insure this is the case. 5/19/89, s.naroff.
4998 if (cls_ref_chain || imp_list)
5002 if (flag_gen_declaration)
5004 add_class (implementation_context);
5005 dump_interface (gen_declaration_file, implementation_context);
5011 /* Run through the selector hash tables and print a warning for any
5012 selector which has multiple methods. */
5014 for (slot = 0; slot < SIZEHASHTABLE; slot++)
5018 for (hsh = cls_method_hash_list[slot]; hsh; hsh = hsh->next)
5022 tree meth = hsh->key;
5023 char type = (TREE_CODE (meth) == INSTANCE_METHOD_DECL)
5027 warning ("potential selector conflict for method `%s'",
5028 IDENTIFIER_POINTER (METHOD_SEL_NAME (meth)));
5029 warn_with_method ("found", type, meth);
5030 for (loop = hsh->list; loop; loop = loop->next)
5031 warn_with_method ("found", type, loop->value);
5036 for (slot = 0; slot < SIZEHASHTABLE; slot++)
5040 for (hsh = nst_method_hash_list[slot]; hsh; hsh = hsh->next)
5044 tree meth = hsh->key;
5045 char type = (TREE_CODE (meth) == INSTANCE_METHOD_DECL)
5049 warning ("potential selector conflict for method `%s'",
5050 IDENTIFIER_POINTER (METHOD_SEL_NAME (meth)));
5051 warn_with_method ("found", type, meth);
5052 for (loop = hsh->list; loop; loop = loop->next)
5053 warn_with_method ("found", type, loop->value);
5060 /* Subroutines of finish_objc. */
5062 handle_class_ref (chain)
5067 = (char *) alloca (strlen (IDENTIFIER_POINTER (TREE_VALUE (chain))) + 30);
5069 sprintf (string, "__objc_class_name_%s",
5070 IDENTIFIER_POINTER (TREE_VALUE (chain)));
5072 /* Make a decl for this name, so we can use its address in a tree. */
5073 decl = build_decl (VAR_DECL, get_identifier (string), char_type_node);
5074 DECL_EXTERNAL (decl) = 1;
5075 TREE_PUBLIC (decl) = 1;
5078 rest_of_decl_compilation (decl, 0, 0, 0);
5080 /* Make following constant read-only (why not)? */
5083 /* Output a constant to reference this address. */
5084 output_constant (build1 (ADDR_EXPR, string_type_node, decl),
5085 int_size_in_bytes (string_type_node));
5088 handle_impent (impent)
5089 struct imp_entry *impent;
5091 implementation_context = impent->imp_context;
5092 implementation_template = impent->imp_template;
5094 if (TREE_CODE (impent->imp_context) == IMPLEMENTATION_TYPE)
5097 = (char *) alloca (strlen (IDENTIFIER_POINTER (CLASS_NAME (impent->imp_context))) + 30);
5099 sprintf (string, "__objc_class_name_%s",
5100 IDENTIFIER_POINTER (CLASS_NAME (impent->imp_context)));
5101 assemble_global (string);
5102 assemble_label (string);
5104 else if (TREE_CODE (impent->imp_context) == CATEGORY_TYPE)
5107 = (char *) alloca (strlen (IDENTIFIER_POINTER (CLASS_NAME (impent->imp_context)))
5108 + strlen (IDENTIFIER_POINTER (CLASS_SUPER_NAME (impent->imp_context)))
5111 /* Do the same for categories. Even though no references to these
5112 symbols are generated automatically by the compiler, it gives
5113 you a handle to pull them into an archive by hand. */
5114 sprintf (string, "__objc_category_name_%s_%s",
5115 IDENTIFIER_POINTER (CLASS_NAME (impent->imp_context)),
5116 IDENTIFIER_POINTER (CLASS_SUPER_NAME (impent->imp_context)));
5117 assemble_global (string);
5118 assemble_label (string);
5128 char *buf = (char *)xmalloc (256);
5130 { /* dump function prototypes */
5131 tree loop = _OBJC_MODULES_decl;
5133 fprintf (fp, "\n\nfunction prototypes:\n");
5136 if (TREE_CODE (loop) == FUNCTION_DECL && DECL_INITIAL (loop))
5138 /* we have a function definition - generate prototype */
5139 bzero (errbuf, BUFSIZE);
5140 gen_declaration (loop, errbuf);
5141 fprintf (fp, "%s;\n", errbuf);
5143 loop = TREE_CHAIN (loop);
5146 { /* dump global chains */
5148 int i, index = 0, offset = 0;
5151 for (i = 0; i < SIZEHASHTABLE; i++)
5153 if (hashlist = nst_method_hash_list[i])
5155 fprintf (fp, "\n\nnst_method_hash_list[%d]:\n", i);
5159 fprintf (fp, "-%s;\n", gen_method_decl (hashlist->key, buf));
5160 hashlist = hashlist->next;
5165 for (i = 0; i < SIZEHASHTABLE; i++)
5167 if (hashlist = cls_method_hash_list[i])
5169 fprintf (fp, "\n\ncls_method_hash_list[%d]:\n", i);
5173 fprintf (fp, "-%s;\n", gen_method_decl (hashlist->key, buf));
5174 hashlist = hashlist->next;
5179 fprintf (fp, "\nsel_refdef_chain:\n");
5180 for (loop = sel_refdef_chain; loop; loop = TREE_CHAIN (loop))
5182 fprintf (fp, "(index: %4d offset: %4d) %s\n", index, offset,
5183 IDENTIFIER_POINTER (TREE_VALUE (loop)));
5185 /* add one for the '\0' character */
5186 offset += IDENTIFIER_LENGTH (TREE_VALUE (loop)) + 1;
5188 fprintf (fp, "\n (max_selector_index: %4d.\n", max_selector_index);
5194 print_lang_statistics ()