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 DECL_EXTERNAL (decl) = 1;
500 TREE_PUBLIC (decl) = 1;
501 make_decl_rtl (decl, 0, 1);
508 * purpose: "play" parser, creating/installing representations
509 * of the declarations that are required by Objective-C.
513 * type_spec--------->sc_spec
514 * (tree_list) (tree_list)
517 * identifier_node identifier_node
520 synth_module_prologue ()
522 tree expr_decl, temp_type;
524 /* defined in `objc.h' */
525 objc_object_id = get_identifier (TAG_OBJECT);
527 objc_object_reference = xref_tag (RECORD_TYPE, objc_object_id);
529 id_type = build_pointer_type (objc_object_reference);
531 objc_class_id = get_identifier (TAG_CLASS);
533 class_type = build_pointer_type (xref_tag (RECORD_TYPE, objc_class_id));
535 /* Declare type of selector-objects that represent an operation name. */
537 #ifdef OBJC_INT_SELECTORS
539 selector_type = unsigned_type_node;
541 /* `struct objc_selector *' */
543 = build_pointer_type (xref_tag (RECORD_TYPE,
544 get_identifier (TAG_SELECTOR)));
545 #endif /* not OBJC_INT_SELECTORS */
547 /* struct objc_object *objc_msgSend (id, SEL, ...); */
550 = build_function_type (id_type,
551 tree_cons (NULL_TREE, id_type,
552 tree_cons (NULLT, selector_type, NULLT)));
554 _msg_decl = builtin_function ("objc_msgSend", temp_type, NOT_BUILT_IN, 0);
556 /* struct objc_object *objc_msgSendSuper (void *, SEL, ...); */
559 = build_function_type (id_type,
560 tree_cons (NULL_TREE, ptr_type_node,
561 tree_cons (NULLT, selector_type, NULLT)));
563 _msgSuper_decl = builtin_function ("objc_msgSendSuper",
564 temp_type, NOT_BUILT_IN, 0);
566 /* id objc_getClass (); */
568 temp_type = build_function_type (id_type, NULLT);
571 = builtin_function ("objc_getClass", temp_type, NOT_BUILT_IN, 0);
573 /* id objc_getMetaClass (); */
575 objc_getMetaClass_decl
576 = builtin_function ("objc_getMetaClass", temp_type, NOT_BUILT_IN, 0);
578 /* extern SEL _OBJC_SELECTOR_REFERENCES[]; */
580 #ifdef OBJC_SELECTORS_WITHOUT_LABELS
581 _OBJC_SELECTOR_REFERENCES_decl
582 = create_builtin_decl (VAR_DECL, build_array_type (selector_type, NULLT),
583 "_OBJC_SELECTOR_REFERENCES");
588 * custom "build_string ()" which sets TREE_TYPE!
591 my_build_string (len, str)
596 tree aString = build_string (len, str);
598 * some code from "combine_strings ()", which is local to c-parse.y.
600 if (TREE_TYPE (aString) == int_array_type_node)
603 TREE_TYPE (aString) =
604 build_array_type (wide_flag ? integer_type_node : char_type_node,
605 build_index_type (build_int_2 (len - 1, 0)));
607 TREE_CONSTANT (aString) = 1; /* puts string in the ".text" segment */
608 TREE_STATIC (aString) = 1;
613 /* Take care of defining and initializing _OBJC_SYMBOLS. */
615 /* Predefine the following data type:
617 struct _objc_symtab {
622 void *defs[cls_def_cnt + cat_def_cnt];
626 build_objc_symtab_template ()
628 tree field_decl, field_decl_chain, index;
630 objc_symtab_template = start_struct (RECORD_TYPE, get_identifier (_TAG_SYMTAB));
632 /* long sel_ref_cnt; */
634 field_decl = create_builtin_decl (FIELD_DECL,
635 long_integer_type_node,
637 field_decl_chain = field_decl;
641 field_decl = create_builtin_decl (FIELD_DECL,
642 build_pointer_type (selector_type),
644 chainon (field_decl_chain, field_decl);
646 /* short cls_def_cnt; */
648 field_decl = create_builtin_decl (FIELD_DECL,
649 short_integer_type_node,
651 chainon (field_decl_chain, field_decl);
653 /* short cat_def_cnt; */
655 field_decl = create_builtin_decl (FIELD_DECL,
656 short_integer_type_node,
658 chainon (field_decl_chain, field_decl);
660 /* void *defs[cls_def_cnt + cat_def_cnt]; */
662 index = build_index_type (build_int_2 (imp_count + cat_count - 1, 0));
663 field_decl = create_builtin_decl (FIELD_DECL,
664 build_array_type (ptr_type_node, index),
666 chainon (field_decl_chain, field_decl);
668 finish_struct (objc_symtab_template, field_decl_chain);
671 /* Create the initial value for the `defs' field of _objc_symtab.
672 This is a CONSTRUCTOR. */
677 tree expr, initlist = NULLT;
678 struct imp_entry *impent;
681 for (impent = imp_list; impent; impent = impent->next)
683 if (TREE_CODE (impent->imp_context) == IMPLEMENTATION_TYPE)
685 expr = build_unary_op (ADDR_EXPR, impent->class_decl, 0);
686 initlist = tree_cons (NULLT, expr, initlist);
691 for (impent = imp_list; impent; impent = impent->next)
693 if (TREE_CODE (impent->imp_context) == CATEGORY_TYPE)
695 expr = build_unary_op (ADDR_EXPR, impent->class_decl, 0);
696 initlist = tree_cons (NULLT, expr, initlist);
699 return build_nt (CONSTRUCTOR, NULLT, nreverse (initlist));
702 /* Construct the initial value for all of _objc_symtab. */
709 /* sel_ref_cnt = { ..., 5, ... } */
712 initlist = build_tree_list (NULLT, build_int_2 (max_selector_index, 0));
714 initlist = build_tree_list (NULLT, build_int_2 (0, 0));
716 /* refs = { ..., _OBJC_SELECTOR_REFERENCES, ... } */
718 #ifndef OBJC_SELECTORS_WITHOUT_LABELS
719 initlist = tree_cons (NULLT, build_int_2 (0, 0), initlist);
722 initlist = tree_cons (NULLT, _OBJC_SELECTOR_REFERENCES_decl, initlist);
724 initlist = tree_cons (NULLT, build_int_2 (0, 0), initlist);
727 /* cls_def_cnt = { ..., 5, ... } */
729 initlist = tree_cons (NULLT, build_int_2 (imp_count, 0), initlist);
731 /* cat_def_cnt = { ..., 5, ... } */
733 initlist = tree_cons (NULLT, build_int_2 (cat_count, 0), initlist);
735 /* cls_def = { ..., { &Foo, &Bar, ...}, ... } */
737 if (imp_count || cat_count)
738 initlist = tree_cons (NULLT, init_def_list (), initlist);
740 return build_nt (CONSTRUCTOR, NULLT, nreverse (initlist));
743 /* Push forward-declarations of all the categories
744 so that init_def_list can use them in a CONSTRUCTOR. */
747 forward_declare_categories ()
749 struct imp_entry *impent;
750 tree sav = implementation_context;
751 for (impent = imp_list; impent; impent = impent->next)
753 if (TREE_CODE (impent->imp_context) == CATEGORY_TYPE)
755 /* Set an invisible arg to synth_id_with_class_suffix. */
756 implementation_context = impent->imp_context;
758 = create_builtin_decl (VAR_DECL, objc_category_template,
759 IDENTIFIER_POINTER (synth_id_with_class_suffix ("_OBJC_CATEGORY")));
762 implementation_context = sav;
765 /* Create the declaration of _OBJC_SYMBOLS, with type `strict _objc_symtab'
766 and initialized appropriately. */
769 generate_objc_symtab_decl ()
773 if (!objc_category_template)
774 build_category_template ();
776 /* forward declare categories */
778 forward_declare_categories ();
780 if (!objc_symtab_template)
781 build_objc_symtab_template ();
783 sc_spec = build_tree_list (NULLT, ridpointers[(int) RID_STATIC]);
785 _OBJC_SYMBOLS_decl = start_decl (get_identifier ("_OBJC_SYMBOLS"),
786 tree_cons (NULLT, objc_symtab_template, sc_spec), 1);
788 finish_decl (_OBJC_SYMBOLS_decl, init_objc_symtab (), NULLT);
792 * tree_node------->tree_node----->...
794 * | (value) | (value)
799 init_module_descriptor ()
803 /* version = { 1, ... } */
805 expr = build_int_2 (OBJC_VERSION, 0);
806 initlist = build_tree_list (NULLT, expr);
808 /* size = { ..., sizeof (struct objc_module), ... } */
810 expr = build_int_2 (TREE_INT_CST_LOW (TYPE_SIZE (objc_module_template)) /
812 initlist = tree_cons (NULLT, expr, initlist);
814 /* name = { ..., "foo.m", ... } */
816 expr = build_msg_pool_reference (
817 add_objc_string (get_identifier (input_filename)));
818 initlist = tree_cons (NULLT, expr, initlist);
820 /* symtab = { ..., _OBJC_SYMBOLS, ... } */
822 if (_OBJC_SYMBOLS_decl)
823 expr = build_unary_op (ADDR_EXPR, _OBJC_SYMBOLS_decl, 0);
825 expr = build_int_2 (0, 0);
826 initlist = tree_cons (NULLT, expr, initlist);
828 return build_nt (CONSTRUCTOR, NULLT, nreverse (initlist));
831 /* Write out the data structures to describe Objective C classes defined.
832 If appropriate, compile and output a setup function to initialize them.
833 Return a string which is the name of a function to call to initialize
834 the Objective C data structures for this file (and perhaps for other files
838 build_module_descriptor ()
840 tree decl_specs, field_decl, field_decl_chain;
842 objc_module_template = start_struct (RECORD_TYPE, get_identifier (_TAG_MODULE));
846 decl_specs = build_tree_list (NULLT, ridpointers[(int) RID_LONG]);
847 field_decl = get_identifier ("version");
848 field_decl = grokfield (input_filename, lineno, field_decl, decl_specs, NULLT);
849 field_decl_chain = field_decl;
853 decl_specs = build_tree_list (NULLT, ridpointers[(int) RID_LONG]);
854 field_decl = get_identifier ("size");
855 field_decl = grokfield (input_filename, lineno, field_decl, decl_specs, NULLT);
856 chainon (field_decl_chain, field_decl);
860 decl_specs = build_tree_list (NULLT, ridpointers[(int) RID_CHAR]);
861 field_decl = build1 (INDIRECT_REF, NULLT, get_identifier ("name"));
862 field_decl = grokfield (input_filename, lineno, field_decl, decl_specs, NULLT);
863 chainon (field_decl_chain, field_decl);
865 /* struct objc_symtab *symtab; */
867 decl_specs = get_identifier (_TAG_SYMTAB);
868 decl_specs = build_tree_list (NULLT, xref_tag (RECORD_TYPE, decl_specs));
869 field_decl = build1 (INDIRECT_REF, NULLT, get_identifier ("symtab"));
870 field_decl = grokfield (input_filename, lineno, field_decl, decl_specs, NULLT);
871 chainon (field_decl_chain, field_decl);
873 finish_struct (objc_module_template, field_decl_chain);
875 /* create an instance of "objc_module" */
877 decl_specs = tree_cons (NULLT, objc_module_template,
878 build_tree_list (NULLT, ridpointers[(int) RID_STATIC]));
880 _OBJC_MODULES_decl = start_decl (get_identifier ("_OBJC_MODULES"),
883 finish_decl (_OBJC_MODULES_decl, init_module_descriptor (), NULLT);
885 /* Mark the decl to avoid "defined but not used" warning. */
886 DECL_IN_SYSTEM_HEADER (_OBJC_MODULES_decl) = 1;
888 /* Generate a constructor call for the module descriptor.
889 This code was generated by reading the grammar rules
890 of c-parse.y; Therefore, it may not be the most efficient
891 way of generating the requisite code. */
892 #ifndef NEXT_OBJC_RUNTIME
894 tree parms, function_decl, decelerator, void_list_node;
897 char *global_object_name = 0;
900 /* Use a global object (which is already required to be unique over
901 the program) rather than the file name (which imposes extra
902 constraints). -- Raeburn@MIT.EDU, 10 Jan 1990. */
904 /* Find the name of some global object defined in this file. */
905 for (t = getdecls (); t; t = TREE_CHAIN (t))
906 if (TREE_PUBLIC (t) && !DECL_EXTERNAL (t) && DECL_INITIAL (t) != 0)
908 global_object_name = IDENTIFIER_POINTER (DECL_NAME (t));
912 /* If none, use the name of the file. */
913 if (!global_object_name)
917 = (char *) alloca (strlen (main_input_filename) + 1);
919 p = main_input_filename;
920 q = global_object_name;
922 /* Replace any weird characters in the file name. */
924 if (! ((*p >= '0' && *p <= '9')
925 || (*p >= 'A' && *p <= 'Z')
926 || (*p >= 'a' && *p <= 'z')))
933 /* Make the constructor name from the name we have found. */
934 buf = (char *) xmalloc (sizeof (CONSTRUCTOR_NAME_FORMAT)
935 + strlen (global_object_name));
936 sprintf (buf, CONSTRUCTOR_NAME_FORMAT, global_object_name);
938 /* Declare void __objc_execClass (void*); */
940 void_list_node = build_tree_list (NULL_TREE, void_type_node);
942 = build_function_type (void_type_node,
943 tree_cons (NULL_TREE, ptr_type_node,
945 function_decl = build_decl (FUNCTION_DECL,
946 get_identifier ("__objc_execClass"),
948 DECL_EXTERNAL (function_decl) = 1;
949 TREE_PUBLIC (function_decl) = 1;
950 pushdecl (function_decl);
951 rest_of_decl_compilation (function_decl, 0, 0, 0);
954 = build_tree_list (NULLT,
955 build_unary_op (ADDR_EXPR, _OBJC_MODULES_decl, 0));
956 decelerator = build_function_call (function_decl, parms);
958 /* void __objc_file_init () {objc_execClass(&L_OBJC_MODULES);} */
960 start_function (void_list_node,
961 build_parse_node (CALL_EXPR, get_identifier (buf),
962 /* This has the format of the output
964 tree_cons (NULL_TREE, NULL_TREE,
968 #if 0 /* This should be turned back on later
969 for the systems where collect is not needed. */
970 /* Make these functions nonglobal
971 so each file can use the same name. */
972 TREE_PUBLIC (current_function_decl) = 0;
974 TREE_USED (current_function_decl) = 1;
977 assemble_external (function_decl);
978 c_expand_expr_stmt (decelerator);
982 /* Return the name of the constructor function. */
985 #else /* NEXT_OBJC_RUNTIME */
987 #endif /* NEXT_OBJC_RUNTIME */
990 /* extern const char _OBJC_STRINGS[]; */
993 generate_forward_declaration_to_string_table ()
995 tree sc_spec, decl_specs, expr_decl;
997 sc_spec = tree_cons (NULLT, ridpointers[(int) RID_EXTERN], NULLT);
998 decl_specs = tree_cons (NULLT, ridpointers[(int) RID_CHAR], sc_spec);
1000 expr_decl = build_nt (ARRAY_REF, get_identifier ("_OBJC_STRINGS"), NULLT);
1002 _OBJC_STRINGS_decl = define_decl (expr_decl, decl_specs);
1005 /* static char _OBJC_STRINGS[] = "..."; */
1008 build_message_selector_pool ()
1010 tree sc_spec, decl_specs, expr_decl;
1011 tree chain, string_expr;
1012 int goolengthtmp = 0, msg_pool_size = 0;
1015 sc_spec = tree_cons (NULLT, ridpointers[(int) RID_STATIC], NULLT);
1016 decl_specs = tree_cons (NULLT, ridpointers[(int) RID_CHAR], sc_spec);
1018 expr_decl = build_nt (ARRAY_REF, get_identifier ("_OBJC_STRINGS"), NULLT);
1020 _OBJC_STRINGS_decl = start_decl (expr_decl, decl_specs, 1);
1022 for (chain = sel_refdef_chain; chain; chain = TREE_CHAIN (chain))
1023 msg_pool_size += IDENTIFIER_LENGTH (TREE_VALUE (chain)) + 1;
1027 string_goo = (char *)xmalloc (msg_pool_size);
1028 bzero (string_goo, msg_pool_size);
1030 for (chain = sel_refdef_chain; chain; chain = TREE_CHAIN (chain))
1032 strcpy (string_goo + goolengthtmp, IDENTIFIER_POINTER (TREE_VALUE (chain)));
1033 goolengthtmp += IDENTIFIER_LENGTH (TREE_VALUE (chain)) + 1;
1036 string_expr = my_build_string (msg_pool_size, string_goo);
1038 finish_decl (_OBJC_STRINGS_decl, string_expr, NULLT);
1042 * synthesize the following expr: (char *)&_OBJC_STRINGS[<offset>]
1044 * the cast stops the compiler from issuing the following message:
1046 * grok.m: warning: initialization of non-const * pointer from const *
1047 * grok.m: warning: initialization between incompatible pointer types
1050 build_msg_pool_reference (offset)
1053 tree expr = build_int_2 (offset, 0);
1056 expr = build_array_ref (_OBJC_STRINGS_decl, expr);
1057 expr = build_unary_op (ADDR_EXPR, expr, 0);
1059 cast = build_tree_list (build_tree_list (NULLT, ridpointers[(int) RID_CHAR]),
1060 build1 (INDIRECT_REF, NULLT, NULLT));
1061 TREE_TYPE (expr) = groktypename (cast);
1065 #ifndef OBJC_SELECTORS_WITHOUT_LABELS
1067 build_selector_reference (idx)
1070 tree ref, decl, name, ident;
1072 struct obstack *save_current_obstack = current_obstack;
1073 struct obstack *save_rtl_obstack = rtl_obstack;
1075 sprintf (buf, "_OBJC_SELECTOR_REFERENCES_%d", idx);
1078 rtl_obstack = current_obstack = &permanent_obstack;
1079 ident = get_identifier (buf);
1081 if (IDENTIFIER_GLOBAL_VALUE (ident))
1082 decl = IDENTIFIER_GLOBAL_VALUE (ident); /* set by pushdecl() */
1085 decl = build_decl (VAR_DECL, ident, selector_type);
1086 DECL_EXTERNAL (decl) = 1;
1087 TREE_PUBLIC (decl) = 1;
1088 TREE_USED (decl) = 1;
1090 make_decl_rtl (decl, 0, 1); /* usually called from `rest_of_decl_compilation' */
1091 pushdecl_top_level (decl); /* our `extended/custom' pushdecl in c-decl.c */
1093 current_obstack = save_current_obstack;
1094 rtl_obstack = save_rtl_obstack;
1101 init_selector (offset)
1104 tree expr = build_msg_pool_reference (offset);
1105 TREE_TYPE (expr) = selector_type; /* cast */
1110 build_selector_translation_table ()
1112 tree sc_spec, decl_specs, expr_decl;
1113 tree chain, initlist = NULLT;
1115 #ifndef OBJC_SELECTORS_WITHOUT_LABELS
1116 tree decl, var_decl;
1120 /* The corresponding pop_obstacks is in finish_decl,
1121 called at the end of this function. */
1122 push_obstacks_nochange ();
1125 for (chain = sel_ref_chain; chain; chain = TREE_CHAIN (chain))
1129 #ifndef OBJC_SELECTORS_WITHOUT_LABELS
1130 sprintf (buf, "_OBJC_SELECTOR_REFERENCES_%d", idx);
1131 sc_spec = build_tree_list (NULLT, ridpointers[(int) RID_STATIC]);
1133 /* static SEL _OBJC_SELECTOR_REFERENCES_n = ...; */
1134 decl_specs = tree_cons (NULLT, selector_type, sc_spec);
1135 var_decl = get_identifier (buf);
1137 /* the `decl' that is returned from start_decl is the one that we
1138 * forward declared in `build_selector_reference()'
1140 decl = start_decl (var_decl, decl_specs, 1);
1143 expr = init_selector (offset);
1145 /* add one for the '\0' character */
1146 offset += IDENTIFIER_LENGTH (TREE_VALUE (chain)) + 1;
1148 #ifndef OBJC_SELECTORS_WITHOUT_LABELS
1149 finish_decl (decl, expr, NULLT);
1152 initlist = tree_cons (NULLT, expr, initlist);
1156 #ifdef OBJC_SELECTORS_WITHOUT_LABELS
1157 /* Cause the variable and its initial value to be actually output. */
1158 DECL_EXTERNAL (_OBJC_SELECTOR_REFERENCES_decl) = 0;
1159 TREE_STATIC (_OBJC_SELECTOR_REFERENCES_decl) = 1;
1160 /* NULL terminate the list and fix the decl for output. */
1161 initlist = tree_cons (NULLT, build_int_2 (0, 0), initlist);
1162 DECL_INITIAL (_OBJC_SELECTOR_REFERENCES_decl) = (tree) 1;
1163 initlist = build_nt (CONSTRUCTOR, NULLT, nreverse (initlist));
1164 finish_decl (_OBJC_SELECTOR_REFERENCES_decl, initlist, NULLT);
1169 add_class_reference (ident)
1174 if (chain = cls_ref_chain)
1179 if (ident == TREE_VALUE (chain))
1183 chain = TREE_CHAIN (chain);
1187 /* append to the end of the list */
1188 TREE_CHAIN (tail) = perm_tree_cons (NULLT, ident, NULLT);
1191 cls_ref_chain = perm_tree_cons (NULLT, ident, NULLT);
1195 * sel_ref_chain is a list whose "value" fields will be instances of
1196 * identifier_node that represent the selector.
1199 add_selector_reference (ident)
1205 /* this adds it to sel_refdef_chain, the global pool of selectors */
1206 add_objc_string (ident);
1208 if (chain = sel_ref_chain)
1213 if (ident == TREE_VALUE (chain))
1218 chain = TREE_CHAIN (chain);
1222 /* append to the end of the list */
1223 TREE_CHAIN (tail) = perm_tree_cons (NULLT, ident, NULLT);
1226 sel_ref_chain = perm_tree_cons (NULLT, ident, NULLT);
1228 max_selector_index++;
1233 * sel_refdef_chain is a list whose "value" fields will be instances of
1234 * identifier_node that represent the selector. It returns the offset of
1235 * the selector from the beginning of the _OBJC_STRINGS pool. This offset
1236 * is typically used by "init_selector ()" during code generation.
1239 add_objc_string (ident)
1245 if (chain = sel_refdef_chain)
1250 if (ident == TREE_VALUE (chain))
1253 /* add one for the '\0' character */
1254 offset += IDENTIFIER_LENGTH (TREE_VALUE (chain)) + 1;
1256 chain = TREE_CHAIN (chain);
1260 /* append to the end of the list */
1261 TREE_CHAIN (tail) = perm_tree_cons (NULLT, ident, NULLT);
1264 sel_refdef_chain = perm_tree_cons (NULLT, ident, NULLT);
1270 lookup_interface (ident)
1275 for (chain = interface_chain; chain; chain = TREE_CHAIN (chain))
1277 if (ident == CLASS_NAME (chain))
1284 objc_copy_list (list, head)
1288 tree newlist = NULL_TREE, tail = NULL_TREE;
1292 tail = copy_node (list);
1294 /* the following statement fixes a bug when inheriting instance
1295 variables that are declared to be bitfields. finish_struct () expects
1296 to find the width of the bitfield in DECL_INITIAL (), which it
1297 nulls out after processing the decl of the super class...rather
1298 than change the way finish_struct () works (which is risky),
1299 I create the situation it expects...s.naroff (7/23/89).
1301 if (DECL_BIT_FIELD (tail) && DECL_INITIAL (tail) == 0)
1302 DECL_INITIAL (tail) = build_int_2 (DECL_FIELD_SIZE (tail), 0);
1304 newlist = chainon (newlist, tail);
1305 list = TREE_CHAIN (list);
1312 * build_private_template (), get_class_ivars (), and get_static_reference ().
1315 build_ivar_chain (interface)
1318 tree my_name, super_name, ivar_chain;
1320 my_name = CLASS_NAME (interface);
1321 super_name = CLASS_SUPER_NAME (interface);
1323 /* "leaf" ivars never get copied...there is no reason to. */
1324 ivar_chain = CLASS_IVARS (interface);
1329 tree super_interface = lookup_interface (super_name);
1331 if (!super_interface)
1333 /* fatal did not work with 2 args...should fix */
1334 error ("Cannot find interface declaration for `%s', superclass of `%s'",
1335 IDENTIFIER_POINTER (super_name), IDENTIFIER_POINTER (my_name));
1338 if (super_interface == interface)
1340 fatal ("Circular inheritance in interface declaration for `%s'",
1341 IDENTIFIER_POINTER (super_name));
1343 interface = super_interface;
1344 my_name = CLASS_NAME (interface);
1345 super_name = CLASS_SUPER_NAME (interface);
1347 op1 = CLASS_IVARS (interface);
1350 tree head, tail = objc_copy_list (op1, &head);
1352 /* prepend super class ivars...make a copy of the list, we
1353 * do not want to alter the original.
1355 TREE_CHAIN (tail) = ivar_chain;
1363 * struct <classname> {
1364 * struct objc_class *isa;
1369 build_private_template (class)
1374 if (CLASS_STATIC_TEMPLATE (class))
1376 _PRIVATE_record = CLASS_STATIC_TEMPLATE (class);
1377 ivar_context = TYPE_FIELDS (CLASS_STATIC_TEMPLATE (class));
1381 _PRIVATE_record = start_struct (RECORD_TYPE, CLASS_NAME (class));
1383 ivar_context = build_ivar_chain (class);
1385 finish_struct (_PRIVATE_record, ivar_context);
1387 CLASS_STATIC_TEMPLATE (class) = _PRIVATE_record;
1389 /* mark this record as class template - for class type checking */
1390 TREE_STATIC_TEMPLATE (_PRIVATE_record) = 1;
1392 instance_type = groktypename (
1393 build_tree_list (build_tree_list (NULLT, _PRIVATE_record),
1394 build1 (INDIRECT_REF, NULLT, NULLT)));
1395 return ivar_context;
1399 * struct objc_category {
1400 * char *category_name;
1402 * struct objc_method_list *instance_methods;
1403 * struct objc_method_list *class_methods;
1407 build_category_template ()
1409 tree decl_specs, field_decl, field_decl_chain;
1411 objc_category_template = start_struct (RECORD_TYPE,
1412 get_identifier (_TAG_CATEGORY));
1413 /* char *category_name; */
1415 decl_specs = build_tree_list (NULLT, ridpointers[(int) RID_CHAR]);
1416 field_decl = build1 (INDIRECT_REF, NULLT, get_identifier ("category_name"));
1417 field_decl = grokfield (input_filename, lineno, field_decl, decl_specs, NULLT);
1418 field_decl_chain = field_decl;
1420 /* char *class_name; */
1422 decl_specs = build_tree_list (NULLT, ridpointers[(int) RID_CHAR]);
1423 field_decl = build1 (INDIRECT_REF, NULLT, get_identifier ("class_name"));
1424 field_decl = grokfield (input_filename, lineno, field_decl, decl_specs, NULLT);
1425 chainon (field_decl_chain, field_decl);
1427 /* struct objc_method_list *instance_methods; */
1429 decl_specs = build_tree_list (NULLT, xref_tag (RECORD_TYPE,
1430 get_identifier (_TAG_METHOD_LIST)));
1431 field_decl = build1 (INDIRECT_REF, NULLT, get_identifier ("instance_methods"));
1432 field_decl = grokfield (input_filename, lineno, field_decl, decl_specs, NULLT);
1433 chainon (field_decl_chain, field_decl);
1435 /* struct objc_method_list *class_methods; */
1437 decl_specs = build_tree_list (NULLT, xref_tag (RECORD_TYPE,
1438 get_identifier (_TAG_METHOD_LIST)));
1439 field_decl = build1 (INDIRECT_REF, NULLT, get_identifier ("class_methods"));
1440 field_decl = grokfield (input_filename, lineno, field_decl, decl_specs, NULLT);
1441 chainon (field_decl_chain, field_decl);
1443 finish_struct (objc_category_template, field_decl_chain);
1447 * struct objc_class {
1448 * struct objc_class *isa;
1449 * struct objc_class *super_class;
1453 * long instance_size;
1454 * struct objc_ivar_list *ivars;
1455 * struct objc_method_list *methods;
1456 * struct objc_cache *cache;
1460 build_class_template ()
1462 tree decl_specs, field_decl, field_decl_chain;
1464 objc_class_template = start_struct (RECORD_TYPE, get_identifier (_TAG_CLASS));
1466 /* struct objc_class *isa; */
1468 decl_specs = build_tree_list (NULLT, objc_class_template);
1469 field_decl = build1 (INDIRECT_REF, NULLT, get_identifier ("isa"));
1470 field_decl = grokfield (input_filename, lineno, field_decl, decl_specs, NULLT);
1471 field_decl_chain = field_decl;
1473 /* struct objc_class *super_class; */
1475 decl_specs = build_tree_list (NULLT, objc_class_template);
1476 field_decl = build1 (INDIRECT_REF, NULLT, get_identifier ("super_class"));
1477 field_decl = grokfield (input_filename, lineno, field_decl, decl_specs, NULLT);
1478 chainon (field_decl_chain, field_decl);
1482 decl_specs = build_tree_list (NULLT, ridpointers[(int) RID_CHAR]);
1483 field_decl = build1 (INDIRECT_REF, NULLT, get_identifier ("name"));
1484 field_decl = grokfield (input_filename, lineno, field_decl, decl_specs, NULLT);
1485 chainon (field_decl_chain, field_decl);
1489 decl_specs = build_tree_list (NULLT, ridpointers[(int) RID_LONG]);
1490 field_decl = get_identifier ("version");
1491 field_decl = grokfield (input_filename, lineno, field_decl, decl_specs, NULLT);
1492 chainon (field_decl_chain, field_decl);
1496 decl_specs = build_tree_list (NULLT, ridpointers[(int) RID_LONG]);
1497 field_decl = get_identifier ("info");
1498 field_decl = grokfield (input_filename, lineno, field_decl, decl_specs, NULLT);
1499 chainon (field_decl_chain, field_decl);
1501 /* long instance_size; */
1503 decl_specs = build_tree_list (NULLT, ridpointers[(int) RID_LONG]);
1504 field_decl = get_identifier ("instance_size");
1505 field_decl = grokfield (input_filename, lineno, field_decl, decl_specs, NULLT);
1506 chainon (field_decl_chain, field_decl);
1508 /* struct objc_ivar_list *ivars; */
1510 decl_specs = build_tree_list (NULLT, xref_tag (RECORD_TYPE,
1511 get_identifier (_TAG_IVAR_LIST)));
1512 field_decl = build1 (INDIRECT_REF, NULLT, get_identifier ("ivars"));
1513 field_decl = grokfield (input_filename, lineno, field_decl, decl_specs, NULLT);
1514 chainon (field_decl_chain, field_decl);
1516 /* struct objc_method_list *methods; */
1518 decl_specs = build_tree_list (NULLT, xref_tag (RECORD_TYPE,
1519 get_identifier (_TAG_METHOD_LIST)));
1520 field_decl = build1 (INDIRECT_REF, NULLT, get_identifier ("methods"));
1521 field_decl = grokfield (input_filename, lineno, field_decl, decl_specs, NULLT);
1522 chainon (field_decl_chain, field_decl);
1524 /* struct objc_cache *cache; */
1526 decl_specs = build_tree_list (NULLT, xref_tag (RECORD_TYPE,
1527 get_identifier ("objc_cache")));
1528 field_decl = build1 (INDIRECT_REF, NULLT, get_identifier ("cache"));
1529 field_decl = grokfield (input_filename, lineno, field_decl, decl_specs, NULLT);
1530 chainon (field_decl_chain, field_decl);
1532 finish_struct (objc_class_template, field_decl_chain);
1536 * generate appropriate forward declarations for an implementation
1539 synth_forward_declarations ()
1541 tree sc_spec, decl_specs, factory_id, anId;
1543 /* extern struct objc_class _OBJC_CLASS_<my_name>; */
1545 anId = synth_id_with_class_suffix ("_OBJC_CLASS");
1547 sc_spec = build_tree_list (NULLT, ridpointers[(int) RID_EXTERN]);
1548 decl_specs = tree_cons (NULLT, objc_class_template, sc_spec);
1549 _OBJC_CLASS_decl = define_decl (anId, decl_specs);
1551 /* extern struct objc_class _OBJC_METACLASS_<my_name>; */
1553 anId = synth_id_with_class_suffix ("_OBJC_METACLASS");
1555 _OBJC_METACLASS_decl = define_decl (anId, decl_specs);
1557 /* pre-build the following entities - for speed/convenience. */
1559 anId = get_identifier ("super_class");
1560 _clsSuper_ref = build_component_ref (_OBJC_CLASS_decl, anId);
1561 __clsSuper_ref = build_component_ref (_OBJC_METACLASS_decl, anId);
1565 error_with_ivar (message, decl, rawdecl)
1571 fprintf (stderr, "%s:%d: ",
1572 DECL_SOURCE_FILE (decl), DECL_SOURCE_LINE (decl));
1573 bzero (errbuf, BUFSIZE);
1574 fprintf (stderr, "%s `%s'\n", message, gen_declaration (rawdecl, errbuf));
1577 #define USERTYPE(t) (TREE_CODE (t) == RECORD_TYPE || \
1578 TREE_CODE (t) == UNION_TYPE || \
1579 TREE_CODE (t) == ENUMERAL_TYPE)
1582 check_ivars (inter, imp)
1586 tree intdecls = CLASS_IVARS (inter);
1587 tree impdecls = CLASS_IVARS (imp);
1588 tree rawintdecls = CLASS_RAW_IVARS (inter);
1589 tree rawimpdecls = CLASS_RAW_IVARS (imp);
1595 if (intdecls == 0 && impdecls == 0)
1597 if (intdecls == 0 || impdecls == 0)
1599 error ("inconsistent instance variable specification");
1602 t1 = TREE_TYPE (intdecls); t2 = TREE_TYPE (impdecls);
1604 if (!comptypes (t1, t2))
1606 if (DECL_NAME (intdecls) == DECL_NAME (impdecls))
1608 error_with_ivar ("conflicting instance variable type",
1609 impdecls, rawimpdecls);
1610 error_with_ivar ("previous declaration of",
1611 intdecls, rawintdecls);
1613 else /* both the type and the name don't match */
1615 error ("inconsistent instance variable specification");
1619 else if (DECL_NAME (intdecls) != DECL_NAME (impdecls))
1621 error_with_ivar ("conflicting instance variable name",
1622 impdecls, rawimpdecls);
1623 error_with_ivar ("previous declaration of",
1624 intdecls, rawintdecls);
1626 intdecls = TREE_CHAIN (intdecls);
1627 impdecls = TREE_CHAIN (impdecls);
1628 rawintdecls = TREE_CHAIN (rawintdecls);
1629 rawimpdecls = TREE_CHAIN (rawimpdecls);
1634 * struct objc_super {
1636 * struct objc_class *class;
1640 build_super_template ()
1642 tree record, decl_specs, field_decl, field_decl_chain;
1644 record = start_struct (RECORD_TYPE, get_identifier (_TAG_SUPER));
1646 /* struct objc_object *self; */
1648 decl_specs = build_tree_list (NULLT, objc_object_reference);
1649 field_decl = get_identifier ("self");
1650 field_decl = build1 (INDIRECT_REF, NULLT, field_decl);
1651 field_decl = grokfield (input_filename, lineno, field_decl, decl_specs, NULLT);
1652 field_decl_chain = field_decl;
1654 /* struct objc_class *class; */
1656 decl_specs = get_identifier (_TAG_CLASS);
1657 decl_specs = build_tree_list (NULLT, xref_tag (RECORD_TYPE, decl_specs));
1658 field_decl = build1 (INDIRECT_REF, NULLT, get_identifier ("class"));
1660 field_decl = grokfield (input_filename, lineno, field_decl, decl_specs, NULLT);
1661 chainon (field_decl_chain, field_decl);
1663 finish_struct (record, field_decl_chain);
1665 /* `struct objc_super *' */
1666 super_type = groktypename (build_tree_list (build_tree_list (NULLT, record),
1667 build1 (INDIRECT_REF, NULLT, NULLT)));
1672 * struct objc_ivar {
1679 build_ivar_template ()
1681 tree objc_ivar_id, objc_ivar_record;
1682 tree decl_specs, field_decl, field_decl_chain;
1684 objc_ivar_id = get_identifier (_TAG_IVAR);
1685 objc_ivar_record = start_struct (RECORD_TYPE, objc_ivar_id);
1687 /* char *ivar_name; */
1689 decl_specs = build_tree_list (NULLT, ridpointers[(int) RID_CHAR]);
1690 field_decl = build1 (INDIRECT_REF, NULLT, get_identifier ("ivar_name"));
1692 field_decl = grokfield (input_filename, lineno, field_decl, decl_specs, NULLT);
1693 field_decl_chain = field_decl;
1695 /* char *ivar_type; */
1697 decl_specs = build_tree_list (NULLT, ridpointers[(int) RID_CHAR]);
1698 field_decl = build1 (INDIRECT_REF, NULLT, get_identifier ("ivar_type"));
1700 field_decl = grokfield (input_filename, lineno, field_decl, decl_specs, NULLT);
1701 chainon (field_decl_chain, field_decl);
1703 /* int ivar_offset; */
1705 decl_specs = build_tree_list (NULLT, ridpointers[(int) RID_INT]);
1706 field_decl = get_identifier ("ivar_offset");
1708 field_decl = grokfield (input_filename, lineno, field_decl, decl_specs, NULLT);
1709 chainon (field_decl_chain, field_decl);
1711 finish_struct (objc_ivar_record, field_decl_chain);
1713 return objc_ivar_record;
1719 * struct objc_ivar ivar_list[ivar_count];
1723 build_ivar_list_template (list_type, size)
1727 tree objc_ivar_list_id, objc_ivar_list_record;
1728 tree decl_specs, field_decl, field_decl_chain;
1730 objc_ivar_list_record = start_struct (RECORD_TYPE, NULLT);
1732 /* int ivar_count; */
1734 decl_specs = build_tree_list (NULLT, ridpointers[(int) RID_INT]);
1735 field_decl = get_identifier ("ivar_count");
1737 field_decl = grokfield (input_filename, lineno, field_decl, decl_specs, NULLT);
1738 field_decl_chain = field_decl;
1740 /* struct objc_ivar ivar_list[]; */
1742 decl_specs = build_tree_list (NULLT, list_type);
1743 field_decl = build_nt (ARRAY_REF, get_identifier ("ivar_list"),
1744 build_int_2 (size, 0));
1746 field_decl = grokfield (input_filename, lineno, field_decl, decl_specs, NULLT);
1747 chainon (field_decl_chain, field_decl);
1749 finish_struct (objc_ivar_list_record, field_decl_chain);
1751 return objc_ivar_list_record;
1758 * struct objc_method method_list[method_count];
1762 build_method_list_template (list_type, size)
1766 tree objc_ivar_list_id, objc_ivar_list_record;
1767 tree decl_specs, field_decl, field_decl_chain;
1769 objc_ivar_list_record = start_struct (RECORD_TYPE, NULLT);
1771 /* int method_next; */
1773 decl_specs = build_tree_list (NULLT, ridpointers[(int) RID_INT]);
1774 field_decl = get_identifier ("method_next");
1776 field_decl = grokfield (input_filename, lineno, field_decl, decl_specs, NULLT);
1777 field_decl_chain = field_decl;
1779 /* int method_count; */
1781 decl_specs = build_tree_list (NULLT, ridpointers[(int) RID_INT]);
1782 field_decl = get_identifier ("method_count");
1784 field_decl = grokfield (input_filename, lineno, field_decl, decl_specs, NULLT);
1785 chainon (field_decl_chain, field_decl);
1787 /* struct objc_method method_list[]; */
1789 decl_specs = build_tree_list (NULLT, list_type);
1790 field_decl = build_nt (ARRAY_REF, get_identifier ("method_list"),
1791 build_int_2 (size, 0));
1793 field_decl = grokfield (input_filename, lineno, field_decl, decl_specs, NULLT);
1794 chainon (field_decl_chain, field_decl);
1796 finish_struct (objc_ivar_list_record, field_decl_chain);
1798 return objc_ivar_list_record;
1802 build_ivar_list_initializer (field_decl, size)
1806 tree initlist = NULLT;
1813 if (DECL_NAME (field_decl))
1815 offset = add_objc_string (DECL_NAME (field_decl));
1816 initlist = tree_cons (NULLT, build_msg_pool_reference (offset), initlist);
1820 /* unnamed bit-field ivar (yuck). */
1821 initlist = tree_cons (NULLT, build_int_2 (0, 0), initlist);
1825 encode_field_decl (field_decl, OBJC_ENCODE_DONT_INLINE_DEFS);
1826 offset = add_objc_string (get_identifier (obstack_finish (&util_obstack)));
1827 obstack_free (&util_obstack, util_firstobj);
1829 initlist = tree_cons (NULLT, build_msg_pool_reference (offset), initlist);
1832 initlist = tree_cons (NULLT,
1833 build_int_2 (TREE_INT_CST_LOW (DECL_FIELD_BITPOS (field_decl)) / BITS_PER_UNIT, 0),
1837 field_decl = TREE_CHAIN (field_decl);
1841 return build_nt (CONSTRUCTOR, NULLT, nreverse (initlist));
1845 generate_ivars_list (type, name, size, list)
1851 tree sc_spec, decl_specs, decl, initlist;
1853 sc_spec = tree_cons (NULLT, ridpointers[(int) RID_STATIC], NULLT);
1854 decl_specs = tree_cons (NULLT, type, sc_spec);
1856 decl = start_decl (synth_id_with_class_suffix (name), decl_specs, 1);
1858 initlist = build_tree_list (NULLT, build_int_2 (size, 0));
1859 initlist = tree_cons (NULLT, list, initlist);
1861 finish_decl (decl, build_nt (CONSTRUCTOR, NULLT, nreverse (initlist)), NULLT);
1867 generate_ivar_lists ()
1869 tree initlist, ivar_list_template, chain;
1870 tree cast, variable_length_type;
1873 if (!objc_ivar_template)
1874 objc_ivar_template = build_ivar_template ();
1876 cast = build_tree_list (build_tree_list (NULLT, xref_tag (RECORD_TYPE,
1877 get_identifier (_TAG_IVAR_LIST))), NULLT);
1878 variable_length_type = groktypename (cast);
1880 /* only generate class variables for the root of the inheritance
1881 hierarchy since these will be the same for every class */
1883 if (CLASS_SUPER_NAME (implementation_template) == NULLT
1884 && (chain = TYPE_FIELDS (objc_class_template)))
1887 initlist = build_ivar_list_initializer (chain, &size);
1889 ivar_list_template = build_ivar_list_template (objc_ivar_template, size);
1891 _OBJC_CLASS_VARIABLES_decl =
1892 generate_ivars_list (ivar_list_template, "_OBJC_CLASS_VARIABLES",
1895 TREE_TYPE (_OBJC_CLASS_VARIABLES_decl) = variable_length_type;
1898 _OBJC_CLASS_VARIABLES_decl = 0;
1900 chain = CLASS_IVARS (implementation_template);
1904 initlist = build_ivar_list_initializer (chain, &size);
1906 ivar_list_template = build_ivar_list_template (objc_ivar_template, size);
1908 _OBJC_INSTANCE_VARIABLES_decl =
1909 generate_ivars_list (ivar_list_template, "_OBJC_INSTANCE_VARIABLES",
1912 TREE_TYPE (_OBJC_INSTANCE_VARIABLES_decl) = variable_length_type;
1915 _OBJC_INSTANCE_VARIABLES_decl = 0;
1919 build_dispatch_table_initializer (entries, size)
1923 tree initlist = NULLT;
1927 int offset = add_objc_string (METHOD_SEL_NAME (entries));
1929 initlist = tree_cons (NULLT, init_selector (offset), initlist);
1931 offset = add_objc_string (METHOD_ENCODING (entries));
1932 initlist = tree_cons (NULLT, build_msg_pool_reference (offset), initlist);
1934 initlist = tree_cons (NULLT, METHOD_DEFINITION (entries), initlist);
1937 entries = TREE_CHAIN (entries);
1941 return build_nt (CONSTRUCTOR, NULLT, nreverse (initlist));
1945 * To accomplish method prototyping without generating all kinds of
1946 * inane warnings, the definition of the dispatch table entries were
1949 * struct objc_method { SEL _cmd; id (*_imp)(); };
1951 * struct objc_method { SEL _cmd; void *_imp; };
1954 build_method_template ()
1957 tree decl_specs, field_decl, field_decl_chain, parms;
1959 _SLT_record = start_struct (RECORD_TYPE, get_identifier (_TAG_METHOD));
1961 #ifdef OBJC_INT_SELECTORS
1962 /* unsigned int _cmd; */
1963 decl_specs = tree_cons (NULLT, ridpointers[(int) RID_UNSIGNED], NULLT);
1964 decl_specs = tree_cons (NULLT, ridpointers[(int) RID_INT], decl_specs);
1965 field_decl = get_identifier ("_cmd");
1966 #else /* not OBJC_INT_SELECTORS */
1967 /* struct objc_selector *_cmd; */
1968 decl_specs = tree_cons (NULLT,
1969 xref_tag (RECORD_TYPE,
1970 get_identifier (TAG_SELECTOR)),
1972 field_decl = build1 (INDIRECT_REF, NULLT, get_identifier ("_cmd"));
1973 #endif /* not OBJC_INT_SELECTORS */
1975 field_decl = grokfield (input_filename, lineno, field_decl, decl_specs, NULLT);
1976 field_decl_chain = field_decl;
1978 decl_specs = tree_cons (NULLT, ridpointers[(int) RID_CHAR], NULLT);
1979 field_decl = build1 (INDIRECT_REF, NULLT, get_identifier ("method_types"));
1980 field_decl = grokfield (input_filename, lineno, field_decl, decl_specs, NULLT);
1981 chainon (field_decl_chain, field_decl);
1985 decl_specs = tree_cons (NULLT, ridpointers[(int) RID_VOID], NULLT);
1986 field_decl = build1 (INDIRECT_REF, NULLT, get_identifier ("_imp"));
1987 field_decl = grokfield (input_filename, lineno, field_decl, decl_specs, NULLT);
1988 chainon (field_decl_chain, field_decl);
1990 finish_struct (_SLT_record, field_decl_chain);
1997 generate_dispatch_table (type, name, size, list)
2003 tree sc_spec, decl_specs, decl, initlist;
2005 sc_spec = tree_cons (NULLT, ridpointers[(int) RID_STATIC], NULLT);
2006 decl_specs = tree_cons (NULLT, type, sc_spec);
2008 decl = start_decl (synth_id_with_class_suffix (name), decl_specs, 1);
2010 initlist = build_tree_list (NULLT, build_int_2 (0, 0));
2011 initlist = tree_cons (NULLT, build_int_2 (size, 0), initlist);
2012 initlist = tree_cons (NULLT, list, initlist);
2014 finish_decl (decl, build_nt (CONSTRUCTOR, NULLT, nreverse (initlist)), NULLT);
2020 generate_dispatch_tables ()
2022 tree initlist, chain, method_list_template;
2023 tree cast, variable_length_type;
2026 if (!objc_method_template)
2027 objc_method_template = build_method_template ();
2029 cast = build_tree_list (build_tree_list (NULLT, xref_tag (RECORD_TYPE,
2030 get_identifier (_TAG_METHOD_LIST))), NULLT);
2031 variable_length_type = groktypename (cast);
2033 chain = CLASS_CLS_METHODS (implementation_context);
2037 initlist = build_dispatch_table_initializer (chain, &size);
2039 method_list_template = build_method_list_template (objc_method_template,
2041 if (TREE_CODE (implementation_context) == IMPLEMENTATION_TYPE)
2042 _OBJC_CLASS_METHODS_decl =
2043 generate_dispatch_table (method_list_template,
2044 "_OBJC_CLASS_METHODS",
2047 /* we have a category */
2048 _OBJC_CLASS_METHODS_decl =
2049 generate_dispatch_table (method_list_template,
2050 "_OBJC_CATEGORY_CLASS_METHODS",
2053 TREE_TYPE (_OBJC_CLASS_METHODS_decl) = variable_length_type;
2056 _OBJC_CLASS_METHODS_decl = 0;
2058 chain = CLASS_NST_METHODS (implementation_context);
2062 initlist = build_dispatch_table_initializer (chain, &size);
2064 method_list_template = build_method_list_template (objc_method_template,
2066 if (TREE_CODE (implementation_context) == IMPLEMENTATION_TYPE)
2067 _OBJC_INSTANCE_METHODS_decl =
2068 generate_dispatch_table (method_list_template,
2069 "_OBJC_INSTANCE_METHODS",
2072 /* we have a category */
2073 _OBJC_INSTANCE_METHODS_decl =
2074 generate_dispatch_table (method_list_template,
2075 "_OBJC_CATEGORY_INSTANCE_METHODS",
2078 TREE_TYPE (_OBJC_INSTANCE_METHODS_decl) = variable_length_type;
2081 _OBJC_INSTANCE_METHODS_decl = 0;
2085 build_category_initializer (cat_name, class_name,
2086 instance_methods, class_methods)
2089 tree instance_methods;
2092 tree initlist = NULLT, expr;
2094 initlist = tree_cons (NULLT, cat_name, initlist);
2095 initlist = tree_cons (NULLT, class_name, initlist);
2097 if (!instance_methods)
2098 initlist = tree_cons (NULLT, build_int_2 (0, 0), initlist);
2101 expr = build_unary_op (ADDR_EXPR, instance_methods, 0);
2102 initlist = tree_cons (NULLT, expr, initlist);
2105 initlist = tree_cons (NULLT, build_int_2 (0, 0), initlist);
2108 expr = build_unary_op (ADDR_EXPR, class_methods, 0);
2109 initlist = tree_cons (NULLT, expr, initlist);
2111 return build_nt (CONSTRUCTOR, NULLT, nreverse (initlist));
2115 * struct objc_class {
2116 * struct objc_class *isa;
2117 * struct objc_class *super_class;
2121 * long instance_size;
2122 * struct objc_ivar_list *ivars;
2123 * struct objc_method_list *methods;
2124 * struct objc_cache *cache;
2128 build_shared_structure_initializer (isa, super, name, size, status,
2129 dispatch_table, ivar_list)
2135 tree dispatch_table;
2138 tree initlist = NULLT, expr;
2141 initlist = tree_cons (NULLT, isa, initlist);
2144 initlist = tree_cons (NULLT, super, initlist);
2147 initlist = tree_cons (NULLT, name, initlist);
2150 initlist = tree_cons (NULLT, build_int_2 (0, 0), initlist);
2153 initlist = tree_cons (NULLT, build_int_2 (status, 0), initlist);
2155 /* instance_size = */
2156 initlist = tree_cons (NULLT, size, initlist);
2158 /* objc_ivar_list = */
2160 initlist = tree_cons (NULLT, build_int_2 (0, 0), initlist);
2163 expr = build_unary_op (ADDR_EXPR, ivar_list, 0);
2164 initlist = tree_cons (NULLT, expr, initlist);
2167 /* objc_method_list = */
2168 if (!dispatch_table)
2169 initlist = tree_cons (NULLT, build_int_2 (0, 0), initlist);
2172 expr = build_unary_op (ADDR_EXPR, dispatch_table, 0);
2173 initlist = tree_cons (NULLT, expr, initlist);
2176 /* method_cache = */
2177 initlist = tree_cons (NULLT, build_int_2 (0, 0), initlist);
2179 return build_nt (CONSTRUCTOR, NULLT, nreverse (initlist));
2183 * static struct objc_category _OBJC_CATEGORY_<name> = { ... };
2186 generate_category (cat)
2189 tree sc_spec, decl_specs, decl;
2190 tree initlist, cat_name_expr, class_name_expr;
2193 sc_spec = tree_cons (NULLT, ridpointers[(int) RID_STATIC], NULLT);
2194 decl_specs = tree_cons (NULLT, objc_category_template, sc_spec);
2196 decl = start_decl (synth_id_with_class_suffix ("_OBJC_CATEGORY"),
2199 offset = add_objc_string (CLASS_SUPER_NAME (cat));
2200 cat_name_expr = build_msg_pool_reference (offset);
2202 offset = add_objc_string (CLASS_NAME (cat));
2203 class_name_expr = build_msg_pool_reference (offset);
2205 initlist = build_category_initializer (
2206 cat_name_expr, class_name_expr,
2207 _OBJC_INSTANCE_METHODS_decl, _OBJC_CLASS_METHODS_decl);
2209 finish_decl (decl, initlist, NULLT);
2213 * static struct objc_class _OBJC_METACLASS_Foo={ ... };
2214 * static struct objc_class _OBJC_CLASS_Foo={ ... };
2217 generate_shared_structures ()
2219 tree sc_spec, decl_specs, expr_decl, decl;
2220 tree name_expr, super_expr, root_expr;
2221 tree my_root_id = NULLT, my_super_id = NULLT;
2222 tree cast_type, initlist;
2225 my_super_id = CLASS_SUPER_NAME (implementation_template);
2228 add_class_reference (my_super_id);
2230 /* compute "my_root_id" - this is required for code generation.
2231 * the "isa" for all meta class structures points to the root of
2232 * the inheritance hierarchy (e.g. "__Object")...
2234 my_root_id = my_super_id;
2237 tree my_root_int = lookup_interface (my_root_id);
2239 if (my_root_int && CLASS_SUPER_NAME (my_root_int))
2240 my_root_id = CLASS_SUPER_NAME (my_root_int);
2246 else /* no super class */
2248 my_root_id = CLASS_NAME (implementation_template);
2251 cast_type = groktypename (build_tree_list (build_tree_list (NULLT,
2252 objc_class_template), build1 (INDIRECT_REF, NULLT, NULLT)));
2254 offset = add_objc_string (CLASS_NAME (implementation_template));
2255 name_expr = build_msg_pool_reference (offset);
2257 /* install class `isa' and `super' pointers at runtime */
2260 offset = add_objc_string (my_super_id);
2261 super_expr = build_msg_pool_reference (offset);
2262 TREE_TYPE (super_expr) = cast_type; /* cast! */
2265 super_expr = build_int_2 (0, 0);
2267 offset = add_objc_string (my_root_id);
2268 root_expr = build_msg_pool_reference (offset);
2269 TREE_TYPE (root_expr) = cast_type; /* cast! */
2271 /* static struct objc_class _OBJC_METACLASS_Foo = { ... }; */
2273 sc_spec = build_tree_list (NULLT, ridpointers[(int) RID_STATIC]);
2274 decl_specs = tree_cons (NULLT, objc_class_template, sc_spec);
2276 decl = start_decl (DECL_NAME (_OBJC_METACLASS_decl), decl_specs, 1);
2278 initlist = build_shared_structure_initializer (
2279 root_expr, super_expr, name_expr,
2280 build_int_2 (TREE_INT_CST_LOW (TYPE_SIZE (objc_class_template)) / BITS_PER_UNIT, 0),
2282 _OBJC_CLASS_METHODS_decl, _OBJC_CLASS_VARIABLES_decl);
2284 finish_decl (decl, initlist, NULLT);
2286 /* static struct objc_class _OBJC_CLASS_Foo={ ... }; */
2288 decl = start_decl (DECL_NAME (_OBJC_CLASS_decl), decl_specs, 1);
2290 initlist = build_shared_structure_initializer (
2291 build_unary_op (ADDR_EXPR, _OBJC_METACLASS_decl, 0),
2292 super_expr, name_expr,
2293 build_int_2 (TREE_INT_CST_LOW (TYPE_SIZE (CLASS_STATIC_TEMPLATE (implementation_template))) / BITS_PER_UNIT, 0),
2295 _OBJC_INSTANCE_METHODS_decl, _OBJC_INSTANCE_VARIABLES_decl);
2297 finish_decl (decl, initlist, NULLT);
2301 synth_id_with_class_suffix (preamble)
2305 if (TREE_CODE (implementation_context) == IMPLEMENTATION_TYPE)
2307 string = (char *) alloca (strlen (preamble)
2308 + strlen (IDENTIFIER_POINTER (CLASS_NAME (implementation_context)))
2310 sprintf (string, "%s_%s", preamble,
2311 IDENTIFIER_POINTER (CLASS_NAME (implementation_context)));
2315 /* we have a category */
2316 string = (char *) alloca (strlen (preamble)
2317 + strlen (IDENTIFIER_POINTER (CLASS_NAME (implementation_context)))
2318 + strlen (IDENTIFIER_POINTER (CLASS_SUPER_NAME (implementation_context)))
2320 sprintf (string, "%s_%s_%s", preamble,
2321 IDENTIFIER_POINTER (CLASS_NAME (implementation_context)),
2322 IDENTIFIER_POINTER (CLASS_SUPER_NAME (implementation_context)));
2324 return get_identifier (string);
2330 * selector ':' '(' typename ')' identifier
2333 * transform an Objective-C keyword argument into
2334 * the C equivalent parameter declarator.
2336 * in: key_name, an "identifier_node" (optional).
2337 * arg_type, a "tree_list" (optional).
2338 * arg_name, an "identifier_node".
2340 * note: it would be really nice to strongly type the preceding
2341 * arguments in the function prototype; however, then i
2342 * could not use the "accessor" macros defined in "tree.h".
2344 * out: an instance of "keyword_decl".
2349 build_keyword_decl (key_name, arg_type, arg_name)
2356 /* if no type is specified, default to "id" */
2357 if (arg_type == NULLT)
2358 arg_type = build_tree_list (build_tree_list (NULLT, objc_object_reference),
2359 build1 (INDIRECT_REF, NULLT, NULLT));
2361 keyword_decl = make_node (KEYWORD_DECL);
2363 TREE_TYPE (keyword_decl) = arg_type;
2364 KEYWORD_ARG_NAME (keyword_decl) = arg_name;
2365 KEYWORD_KEY_NAME (keyword_decl) = key_name;
2367 return keyword_decl;
2371 * given a chain of keyword_decl's, synthesize the full keyword selector.
2374 build_keyword_selector (selector)
2378 tree key_chain, key_name;
2381 for (key_chain = selector; key_chain; key_chain = TREE_CHAIN (key_chain))
2383 if (TREE_CODE (selector) == KEYWORD_DECL)
2384 key_name = KEYWORD_KEY_NAME (key_chain);
2385 else if (TREE_CODE (selector) == TREE_LIST)
2386 key_name = TREE_PURPOSE (key_chain);
2389 len += IDENTIFIER_LENGTH (key_name) + 1;
2390 else /* just a ':' arg */
2393 buf = (char *)alloca (len + 1);
2394 bzero (buf, len + 1);
2396 for (key_chain = selector; key_chain; key_chain = TREE_CHAIN (key_chain))
2398 if (TREE_CODE (selector) == KEYWORD_DECL)
2399 key_name = KEYWORD_KEY_NAME (key_chain);
2400 else if (TREE_CODE (selector) == TREE_LIST)
2401 key_name = TREE_PURPOSE (key_chain);
2404 strcat (buf, IDENTIFIER_POINTER (key_name));
2407 return get_identifier (buf);
2410 /* used for declarations and definitions */
2413 build_method_decl (code, ret_type, selector, add_args)
2414 enum tree_code code;
2421 /* if no type is specified, default to "id" */
2422 if (ret_type == NULLT)
2423 ret_type = build_tree_list (build_tree_list (NULLT, objc_object_reference),
2424 build1 (INDIRECT_REF, NULLT, NULLT));
2426 method_decl = make_node (code);
2427 TREE_TYPE (method_decl) = ret_type;
2430 * if we have a keyword selector, create an identifier_node that
2431 * represents the full selector name (`:' included)...
2433 if (TREE_CODE (selector) == KEYWORD_DECL)
2435 METHOD_SEL_NAME (method_decl) = build_keyword_selector (selector);
2436 METHOD_SEL_ARGS (method_decl) = selector;
2437 METHOD_ADD_ARGS (method_decl) = add_args;
2441 METHOD_SEL_NAME (method_decl) = selector;
2442 METHOD_SEL_ARGS (method_decl) = NULLT;
2443 METHOD_ADD_ARGS (method_decl) = NULLT;
2449 #define METHOD_DEF 0
2450 #define METHOD_REF 1
2451 /* Used by `build_message_expr' and `comp_method_types'.
2452 Return an argument list for method METH.
2453 CONTEXT is either METHOD_DEF or METHOD_REF,
2454 saying whether we are trying to define a method or call one.
2455 SUPERFLAG says this is for a send to super;
2456 this makes a difference for the NeXT calling sequence
2457 in which the lookup and the method call are done together. */
2460 get_arg_type_list (meth, context, superflag)
2467 #ifdef NEXT_OBJC_RUNTIME
2471 arglist = build_tree_list (NULLT, super_type);
2476 if (context == METHOD_DEF)
2477 arglist = build_tree_list (NULLT, TREE_TYPE (self_decl));
2479 arglist = build_tree_list (NULLT, id_type);
2482 /* selector type - will eventually change to `int' */
2483 chainon (arglist, build_tree_list (NULLT, selector_type));
2485 /* build a list of argument types */
2486 for (akey = METHOD_SEL_ARGS (meth); akey; akey = TREE_CHAIN (akey))
2488 tree arg_decl = groktypename_in_parm_context (TREE_TYPE (akey));
2489 chainon (arglist, build_tree_list (NULLT, TREE_TYPE (arg_decl)));
2492 if (METHOD_ADD_ARGS (meth) == (tree)1)
2494 * we have a `, ...' immediately following the selector,
2495 * finalize the arglist...simulate get_parm_info (0)
2498 else if (METHOD_ADD_ARGS (meth))
2500 /* we have a variable length selector */
2501 tree add_arg_list = TREE_CHAIN (METHOD_ADD_ARGS (meth));
2502 chainon (arglist, add_arg_list);
2504 else /* finalize the arglist...simulate get_parm_info (1) */
2505 chainon (arglist, build_tree_list (NULLT, void_type_node));
2511 check_duplicates (hsh)
2522 /* we have two methods with the same name and different types */
2526 type = (TREE_CODE (meth) == INSTANCE_METHOD_DECL) ? '-' : '+';
2528 warning ("multiple declarations for method `%s'",
2529 IDENTIFIER_POINTER (METHOD_SEL_NAME (meth)));
2531 warn_with_method ("using", type, meth);
2532 for (loop = hsh->list; loop; loop = loop->next)
2533 warn_with_method ("also found", type, loop->value);
2540 receiver_is_class_object (receiver)
2543 /* the receiver is a function call that returns an id...
2544 * ...check if it is a call to objc_getClass, if so, give it
2545 * special treatment.
2547 tree exp = TREE_OPERAND (receiver, 0);
2549 if (exp != 0 && (TREE_CODE (exp) == ADDR_EXPR))
2551 exp = TREE_OPERAND (exp, 0);
2553 && TREE_CODE (exp) == FUNCTION_DECL && exp == objc_getClass_decl)
2555 /* we have a call to objc_getClass! */
2556 tree arg = TREE_OPERAND (receiver, 1);
2559 && TREE_CODE (arg) == TREE_LIST
2560 && (arg = TREE_VALUE (arg))
2561 && TREE_CODE (arg) == NOP_EXPR
2562 && (arg = TREE_OPERAND (arg, 0))
2563 && TREE_CODE (arg) == ADDR_EXPR
2564 && (arg = TREE_OPERAND (arg, 0))
2565 && TREE_CODE (arg) == STRING_CST)
2566 /* finally, we have the class name */
2567 return get_identifier (TREE_STRING_POINTER (arg));
2573 /* If we are currently building a message expr, this holds
2574 the identifier of the selector of the message. This is
2575 used when printing warnings about argument mismatches. */
2577 static tree building_objc_message_expr = 0;
2580 maybe_building_objc_message_expr ()
2582 return building_objc_message_expr;
2585 /* Construct an expression for sending a message.
2586 MESS has the object to send to in TREE_PURPOSE
2587 and the argument list (including selector) in TREE_VALUE. */
2590 build_message_expr (mess)
2593 tree receiver = TREE_PURPOSE (mess);
2594 tree selector, self_object;
2595 tree rtype, sel_name;
2596 tree args = TREE_VALUE (mess);
2597 tree method_params = NULLT;
2598 tree method_prototype = NULLT;
2599 int selTransTbl_index;
2601 int statically_typed = 0, statically_allocated = 0;
2602 tree class_ident = 0;
2604 /* 1 if this is sending to the superclass. */
2607 if (!doing_objc_thang)
2608 fatal ("Objective-C text in C source file");
2610 if (TREE_CODE (receiver) == ERROR_MARK)
2611 return error_mark_node;
2613 /* determine receiver type */
2614 rtype = TREE_TYPE (receiver);
2615 super = (TREE_TYPE (receiver) == super_type);
2619 if (TREE_STATIC_TEMPLATE (rtype))
2620 statically_allocated = 1;
2621 else if (TREE_CODE (rtype) == POINTER_TYPE
2622 && TREE_STATIC_TEMPLATE (TREE_TYPE (rtype)))
2623 statically_typed = 1;
2625 else if (TREE_CODE (receiver) == CALL_EXPR && rtype == id_type
2626 && (class_ident = receiver_is_class_object (receiver)))
2628 else if (rtype != id_type && rtype != 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 (rtype == 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);
3418 start_class (code, class_name, super_name)
3419 enum tree_code code;
3425 if (!doing_objc_thang)
3426 fatal ("Objective-C text in C source file");
3428 class = make_node (code);
3430 CLASS_NAME (class) = class_name;
3431 CLASS_SUPER_NAME (class) = super_name;
3432 CLASS_CLS_METHODS (class) = NULL_TREE;
3434 if (code == IMPLEMENTATION_TYPE)
3436 /* pre-build the following entities - for speed/convenience. */
3438 self_id = get_identifier ("self");
3440 _cmd_id = get_identifier ("_cmd");
3442 if (!objc_super_template)
3443 objc_super_template = build_super_template ();
3445 method_slot = 0; /* reset for multiple classes per file */
3447 implementation_context = class;
3449 /* lookup the interface for this implementation. */
3451 if (!(implementation_template = lookup_interface (class_name)))
3453 warning ("Cannot find interface declaration for `%s'",
3454 IDENTIFIER_POINTER (class_name));
3455 add_class (implementation_template = implementation_context);
3458 /* if a super class has been specified in the implementation,
3459 insure it conforms to the one specified in the interface */
3462 && (super_name != CLASS_SUPER_NAME (implementation_template)))
3464 error ("conflicting super class name `%s'",
3465 IDENTIFIER_POINTER (super_name));
3466 error ("previous declaration of `%s'",
3467 IDENTIFIER_POINTER (CLASS_SUPER_NAME (implementation_template)));
3470 else if (code == INTERFACE_TYPE)
3472 if (lookup_interface (class_name))
3473 warning ("duplicate interface declaration for class `%s'",
3474 IDENTIFIER_POINTER (class_name));
3478 else if (code == PROTOCOL_TYPE)
3480 tree class_category_is_assoc_with;
3482 /* for a category, class_name is really the name of the class that
3483 the following set of methods will be associated with...we must
3484 find the interface so that can derive the objects template */
3486 if (!(class_category_is_assoc_with = lookup_interface (class_name)))
3488 error ("Cannot find interface declaration for `%s'",
3489 IDENTIFIER_POINTER (class_name));
3493 add_category (class_category_is_assoc_with, class);
3495 else if (code == CATEGORY_TYPE)
3497 /* pre-build the following entities - for speed/convenience. */
3499 self_id = get_identifier ("self");
3501 _cmd_id = get_identifier ("_cmd");
3503 if (!objc_super_template)
3504 objc_super_template = build_super_template ();
3506 method_slot = 0; /* reset for multiple classes per file */
3508 implementation_context = class;
3510 /* for a category, class_name is really the name of the class that
3511 the following set of methods will be associated with...we must
3512 find the interface so that can derive the objects template */
3514 if (!(implementation_template = lookup_interface (class_name)))
3516 error ("Cannot find interface declaration for `%s'",
3517 IDENTIFIER_POINTER (class_name));
3525 continue_class (class)
3528 if (TREE_CODE (class) == IMPLEMENTATION_TYPE
3529 || TREE_CODE (class) == CATEGORY_TYPE)
3531 struct imp_entry *impEntry;
3534 /* check consistency of the instance variables. */
3536 if (CLASS_IVARS (class))
3537 check_ivars (implementation_template, class);
3539 /* code generation */
3541 ivar_context = build_private_template (implementation_template);
3543 if (!objc_class_template)
3544 build_class_template ();
3546 if (!(impEntry = (struct imp_entry *)xmalloc (sizeof (struct imp_entry))))
3547 perror ("unable to allocate in objc-tree.c");
3549 impEntry->next = imp_list;
3550 impEntry->imp_context = class;
3551 impEntry->imp_template = implementation_template;
3553 synth_forward_declarations ();
3554 impEntry->class_decl = _OBJC_CLASS_decl;
3555 impEntry->meta_decl = _OBJC_METACLASS_decl;
3557 /* append to front and increment count */
3558 imp_list = impEntry;
3559 if (TREE_CODE (class) == IMPLEMENTATION_TYPE)
3564 return ivar_context;
3566 else if (TREE_CODE (class) == INTERFACE_TYPE)
3568 tree record = xref_tag (RECORD_TYPE, CLASS_NAME (class));
3570 if (!TYPE_FIELDS (record))
3572 finish_struct (record, build_ivar_chain (class));
3573 CLASS_STATIC_TEMPLATE (class) = record;
3575 /* mark this record as a class template - for static typing */
3576 TREE_STATIC_TEMPLATE (record) = 1;
3581 return error_mark_node;
3585 * this is called once we see the "@end" in an interface/implementation.
3588 finish_class (class)
3591 if (TREE_CODE (class) == IMPLEMENTATION_TYPE)
3593 /* all code generation is done in finish_objc */
3595 if (implementation_template != implementation_context)
3597 /* ensure that all method listed in the interface contain bodies! */
3598 check_methods (CLASS_CLS_METHODS (implementation_template),
3599 CLASS_CLS_METHODS (implementation_context), '+');
3600 check_methods (CLASS_NST_METHODS (implementation_template),
3601 CLASS_NST_METHODS (implementation_context), '-');
3604 else if (TREE_CODE (class) == CATEGORY_TYPE)
3606 tree category = CLASS_CATEGORY_LIST (implementation_template);
3608 /* find the category interface from the class it is associated with */
3611 if (CLASS_SUPER_NAME (class) == CLASS_SUPER_NAME (category))
3613 category = CLASS_CATEGORY_LIST (category);
3618 /* ensure that all method listed in the interface contain bodies! */
3619 check_methods (CLASS_CLS_METHODS (category),
3620 CLASS_CLS_METHODS (implementation_context), '+');
3621 check_methods (CLASS_NST_METHODS (category),
3622 CLASS_NST_METHODS (implementation_context), '-');
3625 else if (TREE_CODE (class) == INTERFACE_TYPE)
3628 char *string = (char *) alloca (strlen (IDENTIFIER_POINTER (CLASS_NAME (class))) + 3);
3630 /* extern struct objc_object *_<my_name>; */
3632 sprintf (string, "_%s", IDENTIFIER_POINTER (CLASS_NAME (class)));
3634 decl_specs = build_tree_list (NULLT, ridpointers[(int) RID_EXTERN]);
3635 decl_specs = tree_cons (NULLT, objc_object_reference, decl_specs);
3636 define_decl (build1 (INDIRECT_REF, NULLT, get_identifier (string)),
3641 /* "Encode" a data type into a string, whichg rows in util_obstack.
3642 ??? What is the FORMAT? Someone please document this! */
3644 /* Encode a pointer type. */
3647 encode_pointer (type, format)
3651 tree pointer_to = TREE_TYPE (type);
3653 if (TREE_CODE (pointer_to) == RECORD_TYPE)
3655 if (TYPE_NAME (pointer_to)
3656 && TREE_CODE (TYPE_NAME (pointer_to)) == IDENTIFIER_NODE)
3658 char *name = IDENTIFIER_POINTER (TYPE_NAME (pointer_to));
3660 if ((strcmp (name, TAG_OBJECT) == 0) /* '@' */
3661 || TREE_STATIC_TEMPLATE (pointer_to))
3663 obstack_1grow (&util_obstack, '@');
3666 else if (strcmp (name, TAG_CLASS) == 0) /* '#' */
3668 obstack_1grow (&util_obstack, '#');
3671 #ifndef OBJC_INT_SELECTORS
3672 else if (strcmp (name, TAG_SELECTOR) == 0) /* ':' */
3674 obstack_1grow (&util_obstack, ':');
3677 #endif /* OBJC_INT_SELECTORS */
3680 else if (TREE_CODE (pointer_to) == INTEGER_TYPE
3681 && TYPE_MODE (pointer_to) == QImode)
3683 obstack_1grow (&util_obstack, '*');
3687 /* we have a type that does not get special treatment... */
3689 /* NeXT extension */
3690 obstack_1grow (&util_obstack, '^');
3691 encode_type (pointer_to, format);
3695 encode_array (type, format)
3699 tree anIntCst = TYPE_SIZE (type);
3700 tree array_of = TREE_TYPE (type);
3703 /* An incomplete array is treated like a pointer. */
3704 if (anIntCst == NULL)
3706 /* split for obvious reasons. North-Keys 30 Mar 1991 */
3707 encode_pointer (type, format);
3711 sprintf (buffer, "[%d",
3712 TREE_INT_CST_LOW (anIntCst)
3713 / TREE_INT_CST_LOW (TYPE_SIZE (array_of)));
3714 obstack_grow (&util_obstack, buffer, strlen (buffer));
3715 encode_type (array_of, format);
3716 obstack_1grow (&util_obstack, ']');
3721 encode_aggregate (type, format)
3725 enum tree_code code = TREE_CODE (type);
3731 if (*obstack_next_free (&util_obstack) == '^'
3732 || format != OBJC_ENCODE_INLINE_DEFS)
3734 /* we have a reference - this is a NeXT extension--
3735 or we don't want the details. */
3736 if (TYPE_NAME (type)
3737 && (TREE_CODE (TYPE_NAME (type)) == IDENTIFIER_NODE))
3739 obstack_1grow (&util_obstack, '{');
3740 obstack_grow (&util_obstack,
3741 IDENTIFIER_POINTER (TYPE_NAME (type)),
3742 strlen (IDENTIFIER_POINTER (TYPE_NAME (type))));
3743 obstack_1grow (&util_obstack, '}');
3745 else /* we have an untagged structure or a typedef */
3746 obstack_grow (&util_obstack, "{?}", 3);
3750 tree fields = TYPE_FIELDS (type);
3751 obstack_1grow (&util_obstack, '{');
3752 for ( ; fields; fields = TREE_CHAIN (fields))
3753 encode_field_decl (fields, format);
3754 obstack_1grow (&util_obstack, '}');
3760 if (*obstack_next_free (&util_obstack) == '^'
3761 || format != OBJC_ENCODE_INLINE_DEFS)
3763 /* we have a reference - this is a NeXT extension--
3764 or we don't want the details. */
3765 if (TYPE_NAME (type)
3766 && (TREE_CODE (TYPE_NAME (type)) == IDENTIFIER_NODE))
3768 obstack_1grow (&util_obstack, '<');
3769 obstack_grow (&util_obstack,
3770 IDENTIFIER_POINTER (TYPE_NAME (type)),
3771 strlen (IDENTIFIER_POINTER (TYPE_NAME (type))));
3772 obstack_1grow (&util_obstack, '>');
3774 else /* we have an untagged structure or a typedef */
3775 obstack_grow (&util_obstack, "<?>", 3);
3779 tree fields = TYPE_FIELDS (type);
3780 obstack_1grow (&util_obstack, '<');
3781 for ( ; fields; fields = TREE_CHAIN (fields))
3782 encode_field_decl (fields, format);
3783 obstack_1grow (&util_obstack, '>');
3789 obstack_1grow (&util_obstack, 'i');
3795 * support bitfields, the current version of Objective-C does not support
3796 * them. the string will consist of one or more "b:n"'s where n is an
3797 * integer describing the width of the bitfield. Currently, classes in
3798 * the kit implement a method "-(char *)describeBitfieldStruct:" that
3799 * simulates this...if they do not implement this method, the archiver
3800 * assumes the bitfield is 16 bits wide (padded if necessary) and packed
3801 * according to the GNU compiler. After looking at the "kit", it appears
3802 * that all classes currently rely on this default behavior, rather than
3803 * hand generating this string (which is tedious).
3806 encode_bitfield (width, format)
3811 sprintf (buffer, "b%d", width);
3812 obstack_grow (&util_obstack, buffer, strlen (buffer));
3818 * OBJC_ENCODE_INLINE_DEFS or OBJC_ENCODE_DONT_INLINE_DEFS
3821 encode_type (type, format)
3825 enum tree_code code = TREE_CODE (type);
3827 if (code == INTEGER_TYPE)
3829 if (TREE_INT_CST_LOW (TYPE_MIN_VALUE (type)) == 0)
3831 /* unsigned integer types */
3833 if (TYPE_MODE (type) == QImode) /* 'C' */
3834 obstack_1grow (&util_obstack, 'C');
3835 else if (TYPE_MODE (type) == HImode) /* 'S' */
3836 obstack_1grow (&util_obstack, 'S');
3837 else if (TYPE_MODE (type) == SImode)
3839 if (type == long_unsigned_type_node)
3840 obstack_1grow (&util_obstack, 'L'); /* 'L' */
3842 obstack_1grow (&util_obstack, 'I'); /* 'I' */
3845 else /* signed 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) /* 'i' */
3853 if (type == long_integer_type_node)
3854 obstack_1grow (&util_obstack, 'l'); /* 'l' */
3856 obstack_1grow (&util_obstack, 'i'); /* 'i' */
3860 else if (code == REAL_TYPE)
3862 /* floating point types */
3864 if (TYPE_MODE (type) == SFmode) /* 'f' */
3865 obstack_1grow (&util_obstack, 'f');
3866 else if (TYPE_MODE (type) == DFmode
3867 || TYPE_MODE (type) == TFmode) /* 'd' */
3868 obstack_1grow (&util_obstack, 'd');
3871 else if (code == VOID_TYPE) /* 'v' */
3872 obstack_1grow (&util_obstack, 'v');
3874 else if (code == ARRAY_TYPE)
3875 encode_array (type, format);
3877 else if (code == POINTER_TYPE)
3878 encode_pointer (type, format);
3880 else if (code == RECORD_TYPE || code == UNION_TYPE || code == ENUMERAL_TYPE)
3881 encode_aggregate (type, format);
3883 else if (code == FUNCTION_TYPE) /* '?' */
3884 obstack_1grow (&util_obstack, '?');
3888 encode_field_decl (field_decl, format)
3892 if (DECL_BIT_FIELD (field_decl))
3893 encode_bitfield (DECL_FIELD_SIZE (field_decl), format);
3895 encode_type (TREE_TYPE (field_decl), format);
3899 expr_last (complex_expr)
3905 while (next = TREE_OPERAND (complex_expr, 0))
3906 complex_expr = next;
3907 return complex_expr;
3910 /* The selector of the current method,
3911 or NULL if we aren't compiling a method. */
3914 maybe_objc_method_name (decl)
3918 return METHOD_SEL_NAME (method_context);
3924 * Transform a method definition into a function definition as follows:
3926 * - synthesize the first two arguments, "self" and "_cmd".
3930 start_method_def (method)
3935 /* required to implement _msgSuper () */
3936 method_context = method;
3937 _OBJC_SUPER_decl = NULLT;
3939 pushlevel (0); /* must be called BEFORE "start_function ()" */
3941 /* generate prototype declarations for arguments..."new-style" */
3943 if (TREE_CODE (method_context) == INSTANCE_METHOD_DECL)
3944 decl_specs = build_tree_list (NULLT, _PRIVATE_record);
3946 /* really a `struct objc_class *'...however we allow people to
3947 assign to self...which changes its type midstream.
3949 decl_specs = build_tree_list (NULLT, objc_object_reference);
3951 push_parm_decl (build_tree_list (decl_specs,
3952 build1 (INDIRECT_REF, NULLT, self_id)));
3954 #ifdef OBJC_INT_SELECTORS
3955 decl_specs = build_tree_list (NULLT, ridpointers[(int) RID_UNSIGNED]);
3956 decl_specs = tree_cons (NULLT, ridpointers[(int) RID_INT], decl_specs);
3957 push_parm_decl (build_tree_list (decl_specs, _cmd_id));
3958 #else /* not OBJC_INT_SELECTORS */
3959 decl_specs = build_tree_list (NULLT,
3960 xref_tag (RECORD_TYPE,
3961 get_identifier (TAG_SELECTOR)));
3962 push_parm_decl (build_tree_list (decl_specs,
3963 build1 (INDIRECT_REF, NULLT, _cmd_id)));
3964 #endif /* not OBJC_INT_SELECTORS */
3966 /* generate argument declarations if a keyword_decl */
3967 if (METHOD_SEL_ARGS (method))
3969 tree arglist = METHOD_SEL_ARGS (method);
3972 tree arg_spec = TREE_PURPOSE (TREE_TYPE (arglist));
3973 tree arg_decl = TREE_VALUE (TREE_TYPE (arglist));
3977 tree last_expr = expr_last (arg_decl);
3979 /* unite the abstract decl with its name */
3980 TREE_OPERAND (last_expr, 0) = KEYWORD_ARG_NAME (arglist);
3981 push_parm_decl (build_tree_list (arg_spec, arg_decl));
3982 /* unhook...restore the abstract declarator */
3983 TREE_OPERAND (last_expr, 0) = NULLT;
3986 push_parm_decl (build_tree_list (arg_spec, KEYWORD_ARG_NAME (arglist)));
3988 arglist = TREE_CHAIN (arglist);
3993 if (METHOD_ADD_ARGS (method) > (tree)1)
3995 /* we have a variable length selector - in "prototype" format */
3996 tree akey = TREE_PURPOSE (METHOD_ADD_ARGS (method));
3999 /* this must be done prior to calling pushdecl (). pushdecl () is
4000 * going to change our chain on us...
4002 tree nextkey = TREE_CHAIN (akey);
4010 error_with_method (message, mtype, method)
4016 fprintf (stderr, "%s:%d: ",
4017 DECL_SOURCE_FILE (method), DECL_SOURCE_LINE (method));
4018 bzero (errbuf, BUFSIZE);
4019 fprintf (stderr, "%s `%c%s'\n", message, mtype, gen_method_decl (method, errbuf));
4023 warn_with_method (message, mtype, method)
4029 fprintf (stderr, "%s:%d: ",
4030 DECL_SOURCE_FILE (method), DECL_SOURCE_LINE (method));
4031 bzero (errbuf, BUFSIZE);
4032 fprintf (stderr, "%s `%c%s'\n", message, mtype, gen_method_decl (method, errbuf));
4035 /* return 1 if `method' is consistent with `proto' */
4038 comp_method_with_proto (method, proto)
4041 static tree function_type = 0;
4043 /* create a function_type node once */
4046 struct obstack *ambient_obstack = current_obstack;
4048 current_obstack = &permanent_obstack;
4049 function_type = make_node (FUNCTION_TYPE);
4050 current_obstack = ambient_obstack;
4053 /* install argument types - normally set by "build_function_type ()". */
4054 TYPE_ARG_TYPES (function_type) = get_arg_type_list (proto, METHOD_DEF, 0);
4056 /* install return type */
4057 TREE_TYPE (function_type) = groktypename (TREE_TYPE (proto));
4059 return comptypes (TREE_TYPE (METHOD_DEFINITION (method)), function_type);
4062 /* return 1 if `proto1' is consistent with `proto2' */
4065 comp_proto_with_proto (proto1, proto2)
4066 tree proto1, proto2;
4068 static tree function_type1 = 0, function_type2 = 0;
4070 /* create a couple function_type node's once */
4071 if (!function_type1)
4073 struct obstack *ambient_obstack = current_obstack;
4075 current_obstack = &permanent_obstack;
4076 function_type1 = make_node (FUNCTION_TYPE);
4077 function_type2 = make_node (FUNCTION_TYPE);
4078 current_obstack = ambient_obstack;
4081 /* install argument types - normally set by "build_function_type ()". */
4082 TYPE_ARG_TYPES (function_type1) = get_arg_type_list (proto1, METHOD_REF, 0);
4083 TYPE_ARG_TYPES (function_type2) = get_arg_type_list (proto2, METHOD_REF, 0);
4085 /* install return type */
4086 TREE_TYPE (function_type1) = groktypename (TREE_TYPE (proto1));
4087 TREE_TYPE (function_type2) = groktypename (TREE_TYPE (proto2));
4089 return comptypes (function_type1, function_type2);
4093 * - generate an identifier for the function. the format is "_n_cls",
4094 * where 1 <= n <= nMethods, and cls is the name the implementation we
4096 * - install the return type from the method declaration.
4097 * - if we have a prototype, check for type consistency.
4100 really_start_method (method, parmlist)
4101 tree method, parmlist;
4103 tree sc_spec, ret_spec, ret_decl, decl_specs;
4104 tree method_decl, method_id;
4107 /* synth the storage class & assemble the return type */
4108 sc_spec = tree_cons (NULLT, ridpointers[(int) RID_STATIC], NULLT);
4109 ret_spec = TREE_PURPOSE (TREE_TYPE (method));
4110 decl_specs = chainon (sc_spec, ret_spec);
4112 if (TREE_CODE (implementation_context) == IMPLEMENTATION_TYPE)
4114 /* Make sure this is big enough for any plausible method label. */
4115 buf = (char *) alloca (50
4116 + strlen (IDENTIFIER_POINTER (METHOD_SEL_NAME (method)))
4117 + strlen (IDENTIFIER_POINTER (CLASS_NAME (implementation_context))));
4118 #ifdef OBJC_GEN_METHOD_LABEL
4119 OBJC_GEN_METHOD_LABEL (buf,
4120 TREE_CODE (method) == INSTANCE_METHOD_DECL,
4121 IDENTIFIER_POINTER (CLASS_NAME (implementation_context)),
4123 IDENTIFIER_POINTER (METHOD_SEL_NAME (method)));
4125 sprintf (buf, "_%d_%s", ++method_slot,
4126 IDENTIFIER_POINTER (CLASS_NAME (implementation_context)));
4129 else /* we have a category */
4131 /* Make sure this is big enough for any plausible method label. */
4132 buf = (char *) alloca (50
4133 + strlen (IDENTIFIER_POINTER (METHOD_SEL_NAME (method)))
4134 + strlen (IDENTIFIER_POINTER (CLASS_SUPER_NAME (implementation_context)))
4135 + strlen (IDENTIFIER_POINTER (CLASS_NAME (implementation_context))));
4136 #ifdef OBJC_GEN_METHOD_LABEL
4137 OBJC_GEN_METHOD_LABEL (buf,
4138 TREE_CODE (method) == INSTANCE_METHOD_DECL,
4139 IDENTIFIER_POINTER (CLASS_NAME (implementation_context)),
4140 IDENTIFIER_POINTER (CLASS_SUPER_NAME (implementation_context)),
4141 IDENTIFIER_POINTER (METHOD_SEL_NAME (method)));
4143 sprintf (buf, "_%d_%s_%s", ++method_slot,
4144 IDENTIFIER_POINTER (CLASS_NAME (implementation_context)),
4145 IDENTIFIER_POINTER (CLASS_SUPER_NAME (implementation_context)));
4149 method_id = get_identifier (buf);
4151 method_decl = build_nt (CALL_EXPR, method_id, parmlist, NULLT);
4153 /* check the declarator portion of the return type for the method */
4154 if (ret_decl = TREE_VALUE (TREE_TYPE (method)))
4157 * unite the complex decl (specified in the abstract decl) with the
4158 * function decl just synthesized...(int *), (int (*)()), (int (*)[]).
4160 tree save_expr = expr_last (ret_decl);
4162 TREE_OPERAND (save_expr, 0) = method_decl;
4163 method_decl = ret_decl;
4164 /* fool the parser into thinking it is starting a function */
4165 start_function (decl_specs, method_decl, 0);
4166 /* unhook...this has the effect of restoring the abstract declarator */
4167 TREE_OPERAND (save_expr, 0) = NULLT;
4171 TREE_VALUE (TREE_TYPE (method)) = method_decl;
4172 /* fool the parser into thinking it is starting a function */
4173 start_function (decl_specs, method_decl, 0);
4174 /* unhook...this has the effect of restoring the abstract declarator */
4175 TREE_VALUE (TREE_TYPE (method)) = NULLT;
4178 METHOD_DEFINITION (method) = current_function_decl;
4180 /* check consistency...start_function (), pushdecl (), duplicate_decls (). */
4182 if (implementation_template != implementation_context)
4186 if (TREE_CODE (method) == INSTANCE_METHOD_DECL)
4187 chain = CLASS_NST_METHODS (implementation_template);
4189 chain = CLASS_CLS_METHODS (implementation_template);
4191 if (proto = lookup_method (chain, METHOD_SEL_NAME (method)))
4193 if (!comp_method_with_proto (method, proto))
4195 fprintf (stderr, "%s: In method `%s'\n", input_filename,
4196 IDENTIFIER_POINTER (METHOD_SEL_NAME (method)));
4197 if (TREE_CODE (method) == INSTANCE_METHOD_DECL)
4199 error_with_method ("conflicting types for", '-', method);
4200 error_with_method ("previous declaration of", '-', proto);
4204 error_with_method ("conflicting types for", '+', method);
4205 error_with_method ("previous declaration of", '+', proto);
4213 * the following routine is always called...this "architecture" is to
4214 * accommodate "old-style" variable length selectors.
4216 * - a:a b:b // prototype ; id c; id d; // old-style
4219 continue_method_def ()
4223 if (METHOD_ADD_ARGS (method_context) == (tree)1)
4225 * we have a `, ...' immediately following the selector.
4227 parmlist = get_parm_info (0);
4229 parmlist = get_parm_info (1); /* place a `void_at_end' */
4231 /* set self_decl from the first argument...this global is used by
4232 * build_ivar_reference ().build_indirect_ref ().
4234 self_decl = TREE_PURPOSE (parmlist);
4236 poplevel (0, 0, 0); /* must be called BEFORE "start_function ()" */
4238 really_start_method (method_context, parmlist);
4240 store_parm_decls (); /* must be called AFTER "start_function ()" */
4246 if (!_OBJC_SUPER_decl)
4247 _OBJC_SUPER_decl = start_decl (get_identifier (_TAG_SUPER),
4248 build_tree_list (NULLT, objc_super_template), 0);
4250 /* this prevents `unused variable' warnings when compiling with `-Wall' */
4251 DECL_IN_SYSTEM_HEADER (_OBJC_SUPER_decl) = 1;
4255 * _n_Method (id self, SEL sel, ...)
4257 * struct objc_super _S;
4259 * _msgSuper ((_S.self = self, _S.class = _cls, &_S), ...);
4263 get_super_receiver ()
4267 tree super_expr, super_expr_list;
4269 /* set receiver to self */
4270 super_expr = build_component_ref (_OBJC_SUPER_decl, self_id);
4271 super_expr = build_modify_expr (super_expr, NOP_EXPR, self_decl);
4272 super_expr_list = build_tree_list (NULLT, super_expr);
4274 /* set class to begin searching */
4275 super_expr = build_component_ref (_OBJC_SUPER_decl, get_identifier ("class"));
4277 if (TREE_CODE (implementation_context) == IMPLEMENTATION_TYPE)
4279 /* [_cls, __cls]Super are "pre-built" in synth_foward_declarations () */
4281 if (TREE_CODE (method_context) == INSTANCE_METHOD_DECL)
4282 super_expr = build_modify_expr (super_expr, NOP_EXPR, _clsSuper_ref);
4284 super_expr = build_modify_expr (super_expr, NOP_EXPR, __clsSuper_ref);
4286 else /* we have a category... */
4288 tree params, super_name = CLASS_SUPER_NAME (implementation_template);
4291 if (!super_name) /* Barf if super used in a category of Object. */
4293 error("no super class declared in interface for `%s'",
4294 IDENTIFIER_POINTER (CLASS_NAME (implementation_template)));
4295 return error_mark_node;
4298 add_class_reference (super_name);
4300 params = build_tree_list (NULLT,
4301 my_build_string (IDENTIFIER_LENGTH (super_name) + 1,
4302 IDENTIFIER_POINTER (super_name)));
4304 if (TREE_CODE (method_context) == INSTANCE_METHOD_DECL)
4305 funcCall = build_function_call (objc_getClass_decl, params);
4307 funcCall = build_function_call (objc_getMetaClass_decl, params);
4310 TREE_TYPE (funcCall) = TREE_TYPE (_clsSuper_ref);
4311 super_expr = build_modify_expr (super_expr, NOP_EXPR, funcCall);
4313 chainon (super_expr_list, build_tree_list (NULL_TREE, super_expr));
4315 super_expr = build_unary_op (ADDR_EXPR, _OBJC_SUPER_decl, 0);
4316 chainon (super_expr_list, build_tree_list (NULL_TREE, super_expr));
4318 return build_compound_expr (super_expr_list);
4322 error ("[super ...] must appear in a method context");
4323 return error_mark_node;
4328 encode_method_def (func_decl)
4337 encode_type (TREE_TYPE (TREE_TYPE (func_decl)),
4338 OBJC_ENCODE_DONT_INLINE_DEFS);
4340 for (parms = DECL_ARGUMENTS (func_decl); parms;
4341 parms = TREE_CHAIN (parms))
4342 stack_size += TREE_INT_CST_LOW (TYPE_SIZE (DECL_ARG_TYPE (parms)))
4345 sprintf (buffer, "%d", stack_size);
4346 obstack_grow (&util_obstack, buffer, strlen (buffer));
4348 /* argument types */
4349 for (parms = DECL_ARGUMENTS (func_decl); parms;
4350 parms = TREE_CHAIN (parms))
4352 int offset_in_bytes;
4355 encode_type (TREE_TYPE (parms), OBJC_ENCODE_DONT_INLINE_DEFS);
4357 /* compute offset */
4358 if (GET_CODE (DECL_INCOMING_RTL (parms)) == MEM)
4360 rtx addr = XEXP (DECL_INCOMING_RTL (parms), 0);
4362 /* ??? Here we assume that the parm address is indexed
4363 off the frame pointer or arg pointer.
4364 If that is not true, we produce meaningless results,
4365 but do not crash. */
4366 if (GET_CODE (addr) == PLUS
4367 && GET_CODE (XEXP (addr, 1)) == CONST_INT)
4368 offset_in_bytes = INTVAL (XEXP (addr, 1));
4370 offset_in_bytes = 0;
4372 /* This is the case where the parm is passed as an int or double
4373 and it is converted to a char, short or float and stored back
4374 in the parmlist. In this case, describe the parm
4375 with the variable's declared type, and adjust the address
4376 if the least significant bytes (which we are using) are not
4378 #if BYTES_BIG_ENDIAN
4379 if (TREE_TYPE (parms) != DECL_ARG_TYPE (parms))
4380 offset_in_bytes += (GET_MODE_SIZE (TYPE_MODE (DECL_ARG_TYPE (parms)))
4381 - GET_MODE_SIZE (GET_MODE (DECL_RTL (parms))));
4385 offset_in_bytes = 0;
4387 /* The "+ 4" is a total hack to account for the return pc and
4388 saved fp on the 68k. We should redefine this format! */
4389 sprintf (buffer, "%d", offset_in_bytes + 8);
4390 obstack_grow (&util_obstack, buffer, strlen (buffer));
4393 result = get_identifier (obstack_finish (&util_obstack));
4394 obstack_free (&util_obstack, util_firstobj);
4399 finish_method_def ()
4401 METHOD_ENCODING (method_context) =
4402 encode_method_def (current_function_decl);
4404 finish_function (0);
4406 /* this must be done AFTER finish_function, since the optimizer may
4407 find "may be used before set" errors. */
4408 method_context = NULLT; /* required to implement _msgSuper () */
4412 lang_report_error_function (decl)
4417 fprintf (stderr, "In method `%s'\n",
4418 IDENTIFIER_POINTER (METHOD_SEL_NAME (method_context)));
4426 is_complex_decl (type)
4429 return (TREE_CODE (type) == ARRAY_TYPE
4430 || TREE_CODE (type) == FUNCTION_TYPE
4431 || TREE_CODE (type) == POINTER_TYPE);
4435 /* Code to convert a decl node into text for a declaration in C. */
4437 static char tmpbuf[256];
4440 adorn_decl (decl, str)
4444 enum tree_code code = TREE_CODE (decl);
4446 if (code == ARRAY_REF)
4448 tree anIntCst = TREE_OPERAND (decl, 1);
4450 sprintf (str + strlen (str), "[%d]", TREE_INT_CST_LOW (anIntCst));
4452 else if (code == ARRAY_TYPE)
4454 tree anIntCst = TYPE_SIZE (decl);
4455 tree array_of = TREE_TYPE (decl);
4457 sprintf (str + strlen (str), "[%d]",
4458 TREE_INT_CST_LOW (anIntCst)/TREE_INT_CST_LOW (TYPE_SIZE (array_of)));
4460 else if (code == CALL_EXPR)
4462 else if (code == FUNCTION_TYPE)
4464 tree chain = TYPE_ARG_TYPES (decl); /* a list of types */
4466 while (chain && TREE_VALUE (chain) != void_type_node)
4468 gen_declaration (TREE_VALUE (chain), str);
4469 chain = TREE_CHAIN (chain);
4470 if (chain && TREE_VALUE (chain) != void_type_node)
4477 strcpy (tmpbuf, "*"); strcat (tmpbuf, str);
4478 strcpy (str, tmpbuf);
4483 gen_declarator (decl, buf, name)
4490 enum tree_code code = TREE_CODE (decl);
4497 case ARRAY_REF: case INDIRECT_REF: case CALL_EXPR:
4499 op = TREE_OPERAND (decl, 0);
4501 /* we have a pointer to a function or array...(*)(), (*)[] */
4502 if ((code == ARRAY_REF || code == CALL_EXPR) &&
4503 (op && TREE_CODE (op) == INDIRECT_REF))
4506 str = gen_declarator (op, buf, name);
4510 strcpy (tmpbuf, "("); strcat (tmpbuf, str); strcat (tmpbuf, ")");
4511 strcpy (str, tmpbuf);
4514 adorn_decl (decl, str);
4517 case ARRAY_TYPE: case FUNCTION_TYPE: case POINTER_TYPE:
4519 str = strcpy (buf, name);
4521 /* this clause is done iteratively...rather than recursively */
4524 op = is_complex_decl (TREE_TYPE (decl))
4528 adorn_decl (decl, str);
4530 /* we have a pointer to a function or array...(*)(), (*)[] */
4531 if ((code == POINTER_TYPE) &&
4532 (op && (TREE_CODE (op) == FUNCTION_TYPE
4533 || TREE_CODE (op) == ARRAY_TYPE)))
4535 strcpy (tmpbuf, "("); strcat (tmpbuf, str); strcat (tmpbuf, ")");
4536 strcpy (str, tmpbuf);
4539 decl = is_complex_decl (TREE_TYPE (decl))
4543 while (decl && (code = TREE_CODE (decl)));
4547 case IDENTIFIER_NODE:
4548 /* will only happen if we are processing a "raw" expr-decl. */
4549 return strcpy (buf, IDENTIFIER_POINTER (decl));
4554 else /* we have an abstract declarator or a _DECL node */
4556 return strcpy (buf, name);
4561 gen_declspecs (declspecs, buf, raw)
4570 for (chain = declspecs; chain; chain = TREE_CHAIN (chain))
4572 tree aspec = TREE_VALUE (chain);
4574 if (TREE_CODE (aspec) == IDENTIFIER_NODE)
4575 strcat (buf, IDENTIFIER_POINTER (aspec));
4576 else if (TREE_CODE (aspec) == RECORD_TYPE)
4578 if (TYPE_NAME (aspec))
4580 if (!TREE_STATIC_TEMPLATE (aspec))
4581 strcat (buf, "struct ");
4582 strcat (buf, IDENTIFIER_POINTER (TYPE_NAME (aspec)));
4585 strcat (buf, "untagged struct");
4587 else if (TREE_CODE (aspec) == UNION_TYPE)
4589 if (TYPE_NAME (aspec))
4591 if (!TREE_STATIC_TEMPLATE (aspec))
4592 strcat (buf, "union ");
4593 strcat (buf, IDENTIFIER_POINTER (TYPE_NAME (aspec)));
4596 strcat (buf, "untagged union");
4598 else if (TREE_CODE (aspec) == ENUMERAL_TYPE)
4600 if (TYPE_NAME (aspec))
4602 if (!TREE_STATIC_TEMPLATE (aspec))
4603 strcat (buf, "enum ");
4604 strcat (buf, IDENTIFIER_POINTER (TYPE_NAME (aspec)));
4607 strcat (buf, "untagged enum");
4613 switch (TREE_CODE (declspecs))
4615 /* type specifiers */
4617 case INTEGER_TYPE: /* signed integer types */
4619 if (declspecs == short_integer_type_node) /* 's' */
4620 strcat (buf, "short int ");
4621 else if (declspecs == integer_type_node) /* 'i' */
4622 strcat (buf, "int ");
4623 else if (declspecs == long_integer_type_node) /* 'l' */
4624 strcat (buf, "long int ");
4625 else if (declspecs == signed_char_type_node || /* 'c' */
4626 declspecs == char_type_node)
4627 strcat (buf, "char ");
4629 /* unsigned integer types */
4631 else if (declspecs == short_unsigned_type_node) /* 'S' */
4632 strcat (buf, "unsigned short ");
4633 else if (declspecs == unsigned_type_node) /* 'I' */
4634 strcat (buf, "unsigned int ");
4635 else if (declspecs == long_unsigned_type_node) /* 'L' */
4636 strcat (buf, "unsigned long ");
4637 else if (declspecs == unsigned_char_type_node) /* 'C' */
4638 strcat (buf, "unsigned char ");
4641 case REAL_TYPE: /* floating point types */
4643 if (declspecs == float_type_node) /* 'f' */
4644 strcat (buf, "float ");
4645 else if (declspecs == double_type_node) /* 'd' */
4646 strcat (buf, "double ");
4647 else if (declspecs == long_double_type_node) /* 'd' */
4648 strcat (buf, "long double ");
4652 if (!TREE_STATIC_TEMPLATE (declspecs))
4653 strcat (buf, "struct ");
4654 if (TYPE_NAME (declspecs) &&
4655 (TREE_CODE (TYPE_NAME (declspecs)) == IDENTIFIER_NODE))
4657 strcat (buf, IDENTIFIER_POINTER (TYPE_NAME (declspecs)));
4662 strcat (buf, "union ");
4663 if (TYPE_NAME (declspecs) &&
4664 (TREE_CODE (TYPE_NAME (declspecs)) == IDENTIFIER_NODE))
4666 strcat (buf, IDENTIFIER_POINTER (TYPE_NAME (declspecs)));
4671 strcat (buf, "enum ");
4672 if (TYPE_NAME (declspecs) &&
4673 (TREE_CODE (TYPE_NAME (declspecs)) == IDENTIFIER_NODE))
4675 strcat (buf, IDENTIFIER_POINTER (TYPE_NAME (declspecs)));
4680 strcat (buf, "void ");
4685 gen_declaration (atype_or_adecl, buf)
4686 tree atype_or_adecl;
4691 if (TREE_CODE (atype_or_adecl) == TREE_LIST)
4693 tree declspecs; /* "identifier_node", "record_type" */
4694 tree declarator; /* "array_ref", "indirect_ref", "call_expr"... */
4696 /* we have a "raw", abstract declarator (typename) */
4697 declarator = TREE_VALUE (atype_or_adecl);
4698 declspecs = TREE_PURPOSE (atype_or_adecl);
4700 gen_declspecs (declspecs, buf, 1);
4701 strcat (buf, gen_declarator (declarator, declbuf, ""));
4706 tree declspecs; /* "integer_type", "real_type", "record_type"... */
4707 tree declarator; /* "array_type", "function_type", "pointer_type". */
4709 if (TREE_CODE (atype_or_adecl) == FIELD_DECL
4710 || TREE_CODE (atype_or_adecl) == PARM_DECL
4711 || TREE_CODE (atype_or_adecl) == FUNCTION_DECL)
4712 atype = TREE_TYPE (atype_or_adecl);
4714 atype = atype_or_adecl; /* assume we have a *_type node */
4716 if (is_complex_decl (atype))
4720 /* get the declaration specifier...it is at the end of the list */
4721 declarator = chain = atype;
4723 chain = TREE_TYPE (chain); /* not TREE_CHAIN (chain); */
4724 while (is_complex_decl (chain));
4733 gen_declspecs (declspecs, buf, 0);
4735 if (TREE_CODE (atype_or_adecl) == FIELD_DECL
4736 || TREE_CODE (atype_or_adecl) == PARM_DECL
4737 || TREE_CODE (atype_or_adecl) == FUNCTION_DECL)
4741 strcat (buf, gen_declarator (declarator, declbuf,
4742 IDENTIFIER_POINTER (DECL_NAME (atype_or_adecl))));
4745 strcat (buf, IDENTIFIER_POINTER (DECL_NAME (atype_or_adecl)));
4749 strcat (buf, gen_declarator (declarator, declbuf, ""));
4755 #define RAW_TYPESPEC(meth) (TREE_VALUE (TREE_PURPOSE (TREE_TYPE (meth))))
4758 gen_method_decl (method, buf)
4764 if (RAW_TYPESPEC (method) != objc_object_reference)
4767 gen_declaration (TREE_TYPE (method), buf);
4771 chain = METHOD_SEL_ARGS (method);
4773 { /* we have a chain of keyword_decls */
4776 if (KEYWORD_KEY_NAME (chain))
4777 strcat (buf, IDENTIFIER_POINTER (KEYWORD_KEY_NAME (chain)));
4780 if (RAW_TYPESPEC (chain) != objc_object_reference)
4783 gen_declaration (TREE_TYPE (chain), buf);
4786 strcat (buf, IDENTIFIER_POINTER (KEYWORD_ARG_NAME (chain)));
4787 if (chain = TREE_CHAIN (chain))
4792 if (METHOD_ADD_ARGS (method) == (tree)1)
4793 strcat (buf, ", ...");
4794 else if (METHOD_ADD_ARGS (method))
4795 { /* we have a tree list node as generate by `get_parm_info ()' */
4796 chain = TREE_PURPOSE (METHOD_ADD_ARGS (method));
4797 /* know we have a chain of parm_decls */
4801 gen_declaration (chain, buf);
4802 chain = TREE_CHAIN (chain);
4806 else /* we have a unary selector */
4808 strcat (buf, IDENTIFIER_POINTER (METHOD_SEL_NAME (method)));
4815 gen_prototype (fp, decl)
4819 /* we have a function definition - generate prototype */
4820 bzero (errbuf, BUFSIZE);
4821 gen_declaration (decl, errbuf);
4822 fprintf (fp, "%s;\n", errbuf);
4828 dump_interface (fp, chain)
4832 char *buf = (char *)xmalloc (256);
4833 char *my_name = IDENTIFIER_POINTER (CLASS_NAME (chain));
4834 tree ivar_decls = CLASS_RAW_IVARS (chain);
4835 tree nst_methods = CLASS_NST_METHODS (chain);
4836 tree cls_methods = CLASS_CLS_METHODS (chain);
4838 fprintf (fp, "\n@interface %s", my_name);
4840 if (CLASS_SUPER_NAME (chain))
4842 char *super_name = IDENTIFIER_POINTER (CLASS_SUPER_NAME (chain));
4843 fprintf (fp, " : %s\n", super_name);
4850 fprintf (fp, "{\n");
4854 fprintf (fp, "\t%s;\n", gen_declaration (ivar_decls, buf));
4855 ivar_decls = TREE_CHAIN (ivar_decls);
4858 fprintf (fp, "}\n");
4864 fprintf (fp, "- %s;\n", gen_method_decl (nst_methods, buf));
4865 nst_methods = TREE_CHAIN (nst_methods);
4871 fprintf (fp, "+ %s;\n", gen_method_decl (cls_methods, buf));
4872 cls_methods = TREE_CHAIN (cls_methods);
4874 fprintf (fp, "\n@end");
4880 /* Add the special tree codes of Objective C to the tables. */
4882 gcc_obstack_init (&util_obstack);
4883 util_firstobj = (char *) obstack_finish (&util_obstack);
4886 = (char **) realloc (tree_code_type,
4887 sizeof (char *) * LAST_OBJC_TREE_CODE);
4889 = (int *) realloc (tree_code_length,
4890 sizeof (int) * LAST_OBJC_TREE_CODE);
4892 = (char **) realloc (tree_code_name,
4893 sizeof (char *) * LAST_OBJC_TREE_CODE);
4894 bcopy (objc_tree_code_type,
4895 tree_code_type + (int) LAST_AND_UNUSED_TREE_CODE,
4896 (((int) LAST_OBJC_TREE_CODE - (int) LAST_AND_UNUSED_TREE_CODE)
4897 * sizeof (char *)));
4898 bcopy (objc_tree_code_length,
4899 tree_code_length + (int) LAST_AND_UNUSED_TREE_CODE,
4900 (((int) LAST_OBJC_TREE_CODE - (int) LAST_AND_UNUSED_TREE_CODE)
4902 bcopy (objc_tree_code_name,
4903 tree_code_name + (int) LAST_AND_UNUSED_TREE_CODE,
4904 (((int) LAST_OBJC_TREE_CODE - (int) LAST_AND_UNUSED_TREE_CODE)
4905 * sizeof (char *)));
4907 errbuf = (char *)xmalloc (BUFSIZE);
4909 synth_module_prologue ();
4915 struct imp_entry *impent;
4918 generate_forward_declaration_to_string_table ();
4920 #ifdef OBJC_PROLOGUE
4924 if (implementation_context || sel_refdef_chain)
4925 generate_objc_symtab_decl ();
4927 for (impent = imp_list; impent; impent = impent->next)
4929 implementation_context = impent->imp_context;
4930 implementation_template = impent->imp_template;
4932 _OBJC_CLASS_decl = impent->class_decl;
4933 _OBJC_METACLASS_decl = impent->meta_decl;
4935 if (TREE_CODE (implementation_context) == IMPLEMENTATION_TYPE)
4937 /* all of the following reference the string pool... */
4938 generate_ivar_lists ();
4939 generate_dispatch_tables ();
4940 generate_shared_structures ();
4944 generate_dispatch_tables ();
4945 generate_category (implementation_context);
4950 build_selector_translation_table ();
4952 if (implementation_context || sel_refdef_chain)
4954 /* Arrange for Objc data structures to be initialized at run time. */
4956 char *init_name = build_module_descriptor ();
4958 assemble_constructor (init_name);
4961 /* dump the string table last */
4963 if (sel_refdef_chain)
4965 build_message_selector_pool ();
4968 /* dump the class references...this forces the appropriate classes
4969 to be linked into the executable image, preserving unix archive
4970 semantics...this can be removed when we move to a more dynamically
4973 for (chain = cls_ref_chain; chain; chain = TREE_CHAIN (chain))
4974 handle_class_ref (chain);
4976 for (impent = imp_list; impent; impent = impent->next)
4977 handle_impent (impent);
4979 #if 0 /* If GAS has such a bug, let's fix it. */
4980 /*** this fixes a gross bug in the assembler...it `expects' #APP to have
4981 *** a matching #NO_APP, or it crashes (sometimes). app_disable () will
4982 *** insure this is the case. 5/19/89, s.naroff.
4984 if (cls_ref_chain || imp_list)
4988 if (flag_gen_declaration)
4990 add_class (implementation_context);
4991 dump_interface (gen_declaration_file, implementation_context);
4997 /* Run through the selector hash tables and print a warning for any
4998 selector which has multiple methods. */
5000 for (slot = 0; slot < SIZEHASHTABLE; slot++)
5004 for (hsh = cls_method_hash_list[slot]; hsh; hsh = hsh->next)
5008 tree meth = hsh->key;
5009 char type = (TREE_CODE (meth) == INSTANCE_METHOD_DECL)
5013 warning ("potential selector conflict for method `%s'",
5014 IDENTIFIER_POINTER (METHOD_SEL_NAME (meth)));
5015 warn_with_method ("found", type, meth);
5016 for (loop = hsh->list; loop; loop = loop->next)
5017 warn_with_method ("found", type, loop->value);
5022 for (slot = 0; slot < SIZEHASHTABLE; slot++)
5026 for (hsh = nst_method_hash_list[slot]; hsh; hsh = hsh->next)
5030 tree meth = hsh->key;
5031 char type = (TREE_CODE (meth) == INSTANCE_METHOD_DECL)
5035 warning ("potential selector conflict for method `%s'",
5036 IDENTIFIER_POINTER (METHOD_SEL_NAME (meth)));
5037 warn_with_method ("found", type, meth);
5038 for (loop = hsh->list; loop; loop = loop->next)
5039 warn_with_method ("found", type, loop->value);
5046 /* Subroutines of finish_objc. */
5048 handle_class_ref (chain)
5053 = (char *) alloca (strlen (IDENTIFIER_POINTER (TREE_VALUE (chain))) + 30);
5055 sprintf (string, ".objc_class_name_%s",
5056 IDENTIFIER_POINTER (TREE_VALUE (chain)));
5058 /* Make a decl for this name, so we can use its address in a tree. */
5059 decl = build_decl (VAR_DECL, get_identifier (string), char_type_node);
5060 DECL_EXTERNAL (decl) = 1;
5061 TREE_PUBLIC (decl) = 1;
5064 rest_of_decl_compilation (decl, 0, 0, 0);
5066 /* Make following constant read-only (why not)? */
5069 /* Output a constant to reference this address. */
5070 output_constant (build1 (ADDR_EXPR, string_type_node, decl),
5071 int_size_in_bytes (string_type_node));
5074 handle_impent (impent)
5075 struct imp_entry *impent;
5077 implementation_context = impent->imp_context;
5078 implementation_template = impent->imp_template;
5080 if (TREE_CODE (impent->imp_context) == IMPLEMENTATION_TYPE)
5083 = (char *) alloca (strlen (IDENTIFIER_POINTER (CLASS_NAME (impent->imp_context))) + 30);
5085 sprintf (string, ".objc_class_name_%s",
5086 IDENTIFIER_POINTER (CLASS_NAME (impent->imp_context)));
5087 assemble_global (string);
5088 assemble_label (string);
5090 else if (TREE_CODE (impent->imp_context) == CATEGORY_TYPE)
5093 = (char *) alloca (strlen (IDENTIFIER_POINTER (CLASS_NAME (impent->imp_context)))
5094 + strlen (IDENTIFIER_POINTER (CLASS_SUPER_NAME (impent->imp_context)))
5097 /* Do the same for categories. Even though no references to these
5098 symbols are generated automatically by the compiler, it gives
5099 you a handle to pull them into an archive by hand. */
5100 sprintf (string, ".objc_category_name_%s_%s",
5101 IDENTIFIER_POINTER (CLASS_NAME (impent->imp_context)),
5102 IDENTIFIER_POINTER (CLASS_SUPER_NAME (impent->imp_context)));
5103 assemble_global (string);
5104 assemble_label (string);
5114 char *buf = (char *)xmalloc (256);
5116 { /* dump function prototypes */
5117 tree loop = _OBJC_MODULES_decl;
5119 fprintf (fp, "\n\nfunction prototypes:\n");
5122 if (TREE_CODE (loop) == FUNCTION_DECL && DECL_INITIAL (loop))
5124 /* we have a function definition - generate prototype */
5125 bzero (errbuf, BUFSIZE);
5126 gen_declaration (loop, errbuf);
5127 fprintf (fp, "%s;\n", errbuf);
5129 loop = TREE_CHAIN (loop);
5132 { /* dump global chains */
5134 int i, index = 0, offset = 0;
5137 for (i = 0; i < SIZEHASHTABLE; i++)
5139 if (hashlist = nst_method_hash_list[i])
5141 fprintf (fp, "\n\nnst_method_hash_list[%d]:\n", i);
5145 fprintf (fp, "-%s;\n", gen_method_decl (hashlist->key, buf));
5146 hashlist = hashlist->next;
5151 for (i = 0; i < SIZEHASHTABLE; i++)
5153 if (hashlist = cls_method_hash_list[i])
5155 fprintf (fp, "\n\ncls_method_hash_list[%d]:\n", i);
5159 fprintf (fp, "-%s;\n", gen_method_decl (hashlist->key, buf));
5160 hashlist = hashlist->next;
5165 fprintf (fp, "\nsel_refdef_chain:\n");
5166 for (loop = sel_refdef_chain; loop; loop = TREE_CHAIN (loop))
5168 fprintf (fp, "(index: %4d offset: %4d) %s\n", index, offset,
5169 IDENTIFIER_POINTER (TREE_VALUE (loop)));
5171 /* add one for the '\0' character */
5172 offset += IDENTIFIER_LENGTH (TREE_VALUE (loop)) + 1;
5174 fprintf (fp, "\n (max_selector_index: %4d.\n", max_selector_index);
5180 print_lang_statistics ()