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 /* The GNU run time requires the selectors in a vector
52 so it can store the operation numbers in them. */
53 #ifndef NEXT_OBJC_RUNTIME
54 #define OBJC_SELECTORS_WITHOUT_LABELS
57 /* Define the special tree codes that we use. */
59 /* Table indexed by tree code giving a string containing a character
60 classifying the tree code. Possibilities are
61 t, d, s, c, r, <, 1 and 2. See objc-tree.def for details. */
63 #define DEFTREECODE(SYM, NAME, TYPE, LENGTH) TYPE,
65 char *objc_tree_code_type[] = {
67 #include "objc-tree.def"
71 /* Table indexed by tree code giving number of expression
72 operands beyond the fixed part of the node structure.
73 Not used for types or decls. */
75 #define DEFTREECODE(SYM, NAME, TYPE, LENGTH) LENGTH,
77 int objc_tree_code_length[] = {
79 #include "objc-tree.def"
83 /* Names of tree components.
84 Used for printing out the tree and error messages. */
85 #define DEFTREECODE(SYM, NAME, TYPE, LEN) NAME,
87 char *objc_tree_code_name[] = {
89 #include "objc-tree.def"
93 /* Set up for use of obstacks. */
97 #define obstack_chunk_alloc xmalloc
98 #define obstack_chunk_free free
100 /* This obstack is used to accumulate the encoding of a data type. */
101 static struct obstack util_obstack;
102 /* This points to the beginning of obstack contents,
103 so we can free the whole contents. */
106 /* for encode_method_def */
109 #define OBJC_VERSION 2
111 #define NULLT (tree) 0
113 #define OBJC_ENCODE_INLINE_DEFS 0
114 #define OBJC_ENCODE_DONT_INLINE_DEFS 1
116 /*** Private Interface (procedures) ***/
118 /* code generation */
120 static void synth_module_prologue ();
121 static char *build_module_descriptor ();
122 static tree init_module_descriptor ();
123 static void build_module_entry ();
124 static tree build_objc_method_call ();
125 static void build_message_selector_pool ();
126 static void build_selector_translation_table ();
127 static tree build_ivar_chain ();
129 static tree build_ivar_template ();
130 static tree build_method_template ();
131 static tree build_private_template ();
132 static void build_class_template ();
133 static void build_category_template ();
134 static tree build_super_template ();
136 static void synth_forward_declarations ();
137 static void generate_ivar_lists ();
138 static void generate_dispatch_tables ();
139 static void generate_shared_structures ();
141 static tree build_msg_pool_reference ();
142 static tree init_selector ();
143 static tree build_keword_selector ();
144 static tree synth_id_with_class_suffix ();
146 /* misc. bookkeeping */
148 typedef struct hashedEntry *hash;
149 typedef struct hashedAttribute *attr;
151 struct hashedAttribute {
160 static void hash_init ();
161 static void hash_enter ();
162 static hash hash_lookup ();
163 static void hash_add_attr ();
164 static tree lookup_method ();
165 static tree lookup_instance_method_static ();
166 static tree lookup_class_method_static ();
167 static tree add_class ();
168 static int add_selector_reference ();
169 static void add_class_reference ();
170 static int add_objc_string ();
174 static void encode_aggregate ();
175 static void encode_bitfield ();
176 static void encode_type ();
177 static void encode_field_decl ();
179 static void really_start_method ();
180 static int comp_method_with_proto ();
181 static int comp_proto_with_proto ();
182 static tree get_arg_type_list ();
183 static tree expr_last ();
185 /* utilities for debugging and error diagnostics: */
187 static void warn_with_method ();
188 static void error_with_method ();
189 static void error_with_ivar ();
190 static char *gen_method_decl ();
191 static char *gen_declaration ();
192 static char *gen_declarator ();
193 static int is_complex_decl ();
194 static void adorn_decl ();
195 static void dump_interfaces ();
197 /*** Private Interface (data) ***/
199 /* reserved tag definitions: */
202 #define TAG_OBJECT "objc_object"
203 #define TAG_CLASS "objc_class"
204 #define TAG_SUPER "objc_super"
205 #define TAG_SELECTOR "objc_selector"
207 #define _TAG_CLASS "_objc_class"
208 #define _TAG_IVAR "_objc_ivar"
209 #define _TAG_IVAR_LIST "_objc_ivar_list"
210 #define _TAG_METHOD "_objc_method"
211 #define _TAG_METHOD_LIST "_objc_method_list"
212 #define _TAG_CATEGORY "_objc_category"
213 #define _TAG_MODULE "_objc_module"
214 #define _TAG_SYMTAB "_objc_symtab"
215 #define _TAG_SUPER "_objc_super"
217 /* set by `continue_class ()' and checked by `is_public ()' */
219 #define TREE_STATIC_TEMPLATE(record_type) (TREE_PUBLIC(record_type))
220 #define TYPED_OBJECT(type) \
221 (TREE_CODE (type) == RECORD_TYPE && TREE_STATIC_TEMPLATE (type))
223 /* some commonly used instances of "identifier_node". */
225 static tree self_id, _cmd_id;
227 static tree self_decl, _msg_decl, _msgSuper_decl;
228 static tree objc_getClass_decl, objc_getMetaClass_decl;
230 static tree super_type, selector_type, id_type, class_type;
231 static tree instance_type;
233 static tree interface_chain = NULLT;
235 /* chains to manage selectors that are referenced and defined in the module */
237 static tree cls_ref_chain = NULLT; /* classes referenced */
238 static tree sel_ref_chain = NULLT; /* selectors referenced */
239 static tree sel_refdef_chain = NULLT; /* selectors references & defined */
240 static int max_selector_index; /* total # of selector referenced */
242 /* hash tables to manage the global pool of method prototypes */
244 static hash *nst_method_hash_list = 0;
245 static hash *cls_method_hash_list = 0;
247 /* the following are used when compiling a class implementation.
249 * implementation_template will normally be an anInterface, however if
250 * none exists this will be equal to implementation_context...it is
251 * set in start_class.
254 /* backend data declarations */
256 static tree _OBJC_SYMBOLS_decl;
257 static tree _OBJC_INSTANCE_VARIABLES_decl, _OBJC_CLASS_VARIABLES_decl;
258 static tree _OBJC_INSTANCE_METHODS_decl, _OBJC_CLASS_METHODS_decl;
259 static tree _OBJC_CLASS_decl, _OBJC_METACLASS_decl;
260 #ifdef OBJC_SELECTORS_WITHOUT_LABELS
261 static tree _OBJC_SELECTOR_REFERENCES_decl;
263 static tree _OBJC_MODULES_decl;
264 static tree _OBJC_STRINGS_decl;
266 static tree implementation_context = NULLT,
267 implementation_template = NULLT;
270 struct imp_entry *next;
273 tree class_decl; /* _OBJC_CLASS_<my_name>; */
274 tree meta_decl; /* _OBJC_METACLASS_<my_name>; */
276 static struct imp_entry *imp_list = 0;
277 static int imp_count = 0; /* `@implementation' */
278 static int cat_count = 0; /* `@category' */
280 static tree objc_class_template, objc_category_template, _PRIVATE_record;
281 static tree _clsSuper_ref, __clsSuper_ref;
283 static tree objc_method_template, objc_ivar_template;
284 static tree objc_symtab_template, objc_module_template;
285 static tree objc_super_template, objc_object_reference;
287 static tree objc_object_id, objc_class_id;
288 static tree _OBJC_SUPER_decl;
290 static tree method_context = NULLT;
291 static int method_slot = 0; /* used by start_method_def */
295 static char *errbuf; /* a buffer for error diagnostics */
297 extern char *strcpy (), *strcat ();
299 extern tree groktypename_in_parm_context ();
301 extern struct obstack permanent_obstack, *current_obstack, *rtl_obstack;
303 /* data imported from toplev.c */
305 extern char *dump_base_name;
307 /* Open and close the file for outputting class declarations, if requested. */
309 int flag_gen_declaration = 0;
311 FILE *gen_declaration_file;
313 /* Warn if multiple methods are seen for the same selector, but with
314 different argument types. */
316 int warn_selector = 0;
321 /* the beginning of the file is a new line; check for # */
322 /* With luck, we discover the real source file's name from that
323 and put it in input_filename. */
324 ungetc (check_newline (), finput);
326 /* If gen_declaration desired, open the output file. */
327 if (flag_gen_declaration)
329 int dump_base_name_length = strlen (dump_base_name);
330 register char *dumpname = (char *) xmalloc (dump_base_name_length + 7);
331 strcpy (dumpname, dump_base_name);
332 strcat (dumpname, ".decl");
333 gen_declaration_file = fopen (dumpname, "w");
334 if (gen_declaration_file == 0)
335 pfatal_with_name (dumpname);
338 if (doing_objc_thang)
345 if (doing_objc_thang)
346 finish_objc (); /* Objective-C finalization */
348 if (gen_declaration_file)
349 fclose (gen_declaration_file);
358 lang_decode_option (p)
361 if (!strcmp (p, "-lang-objc"))
362 doing_objc_thang = 1;
363 else if (!strcmp (p, "-gen-decls"))
364 flag_gen_declaration = 1;
365 else if (!strcmp (p, "-Wselector"))
367 else if (!strcmp (p, "-Wno-selector"))
370 return c_decode_option (p);
376 define_decl (declarator, declspecs)
380 tree decl = start_decl (declarator, declspecs, 0);
381 finish_decl (decl, NULLT, NULLT);
386 * rules for statically typed objects...called from `c-typeck.comptypes'.
388 * an assignment of the form `a' = `b' is permitted if:
390 * - `a' is of type "id".
391 * - `a' and `b' are the same class type.
392 * - `a' and `b' are of class types A and B such that B is a descendant
397 maybe_objc_comptypes (lhs, rhs)
400 if (doing_objc_thang)
401 return objc_comptypes (lhs, rhs);
406 objc_comptypes (lhs, rhs)
410 /* `id' = `<class> *', `<class> *' = `id' */
412 if ((TYPE_NAME (lhs) == objc_object_id && TYPED_OBJECT (rhs))
413 || (TYPED_OBJECT (lhs) && TYPE_NAME (rhs) == objc_object_id))
416 /* `id' = `Class', `Class' = `id' */
419 else if ((TYPE_NAME (lhs) == objc_object_id &&
420 TYPE_NAME (rhs) == objc_class_id) ||
421 (TYPE_NAME (lhs) == objc_class_id &&
422 TYPE_NAME (rhs) == objc_object_id))
425 /* `<class> *' = `<class> *' */
427 else if (TYPED_OBJECT (lhs) && TYPED_OBJECT (rhs))
429 tree lname = TYPE_NAME (lhs), rname = TYPE_NAME (rhs);
435 /* if the left hand side is a super class of the right hand side,
438 tree rinter = lookup_interface (rname);
442 if (lname == CLASS_SUPER_NAME (rinter))
445 rinter = lookup_interface (CLASS_SUPER_NAME (rinter));
455 /* Called from c-decl.c before all calls to rest_of_decl_compilation. */
458 maybe_objc_check_decl (decl)
461 if (doing_objc_thang)
462 objc_check_decl (decl);
466 objc_check_decl (decl)
469 tree type = TREE_TYPE (decl);
470 static int alreadyWarned = 0;
472 if (TREE_CODE (type) == RECORD_TYPE && TREE_STATIC_TEMPLATE (type))
476 error ("GNU compiler does not support statically allocated objects");
479 error_with_decl (decl, "`%s' cannot be statically allocated");
483 /* implement static typing. at this point, we know we have an interface... */
486 get_static_reference (interface)
489 return xref_tag (RECORD_TYPE, CLASS_NAME (interface));
492 /* Create and push a decl for a built-in external variable or field NAME.
494 TYPE is its data type. */
497 create_builtin_decl (code, type, name)
502 tree decl = build_decl (code, get_identifier (name), type);
503 if (code == VAR_DECL)
505 TREE_STATIC (decl) = 1;
506 make_decl_rtl (decl, 0, 1);
513 * purpose: "play" parser, creating/installing representations
514 * of the declarations that are required by Objective-C.
518 * type_spec--------->sc_spec
519 * (tree_list) (tree_list)
522 * identifier_node identifier_node
525 synth_module_prologue ()
527 tree expr_decl, temp_type;
529 /* defined in `objc.h' */
530 objc_object_id = get_identifier (TAG_OBJECT);
532 objc_object_reference = xref_tag (RECORD_TYPE, objc_object_id);
534 id_type = build_pointer_type (objc_object_reference);
536 objc_class_id = get_identifier (TAG_CLASS);
538 class_type = build_pointer_type (xref_tag (RECORD_TYPE, objc_class_id));
540 /* Declare type of selector-objects that represent an operation name. */
542 #ifdef OBJC_INT_SELECTORS
544 selector_type = unsigned_type_node;
546 /* `struct objc_selector *' */
548 = build_pointer_type (xref_tag (RECORD_TYPE,
549 get_identifier (TAG_SELECTOR)));
550 #endif /* not OBJC_INT_SELECTORS */
552 /* struct objc_object *objc_msgSend (id, SEL, ...); */
555 = build_function_type (id_type,
556 tree_cons (NULL_TREE, id_type,
557 tree_cons (NULLT, selector_type, NULLT)));
559 _msg_decl = builtin_function ("objc_msgSend", temp_type, NOT_BUILT_IN, 0);
561 /* struct objc_object *objc_msgSendSuper (void *, SEL, ...); */
564 = build_function_type (id_type,
565 tree_cons (NULL_TREE, ptr_type_node,
566 tree_cons (NULLT, selector_type, NULLT)));
568 _msgSuper_decl = builtin_function ("objc_msgSendSuper",
569 temp_type, NOT_BUILT_IN, 0);
571 /* id objc_getClass (); */
573 temp_type = build_function_type (id_type, NULLT);
576 = builtin_function ("objc_getClass", temp_type, NOT_BUILT_IN, 0);
578 /* id objc_getMetaClass (); */
580 objc_getMetaClass_decl
581 = builtin_function ("objc_getMetaClass", temp_type, NOT_BUILT_IN, 0);
583 /* extern SEL _OBJC_SELECTOR_REFERENCES[]; */
585 #ifdef OBJC_SELECTORS_WITHOUT_LABELS
586 _OBJC_SELECTOR_REFERENCES_decl
587 = create_builtin_decl (VAR_DECL, build_array_type (selector_type, NULLT),
588 "_OBJC_SELECTOR_REFERENCES");
593 * custom "build_string ()" which sets TREE_TYPE!
596 my_build_string (len, str)
601 tree aString = build_string (len, str);
603 * some code from "combine_strings ()", which is local to c-parse.y.
605 if (TREE_TYPE (aString) == int_array_type_node)
608 TREE_TYPE (aString) =
609 build_array_type (wide_flag ? integer_type_node : char_type_node,
610 build_index_type (build_int_2 (len - 1, 0)));
612 TREE_CONSTANT (aString) = 1; /* puts string in the ".text" segment */
613 TREE_STATIC (aString) = 1;
618 /* Take care of defining and initializing _OBJC_SYMBOLS. */
620 /* Predefine the following data type:
622 struct _objc_symtab {
627 void *defs[cls_def_cnt + cat_def_cnt];
631 build_objc_symtab_template ()
633 tree field_decl, field_decl_chain, index;
635 objc_symtab_template = start_struct (RECORD_TYPE, get_identifier (_TAG_SYMTAB));
637 /* long sel_ref_cnt; */
639 field_decl = create_builtin_decl (FIELD_DECL,
640 long_integer_type_node,
642 field_decl_chain = field_decl;
646 field_decl = create_builtin_decl (FIELD_DECL,
647 build_pointer_type (selector_type),
649 chainon (field_decl_chain, field_decl);
651 /* short cls_def_cnt; */
653 field_decl = create_builtin_decl (FIELD_DECL,
654 short_integer_type_node,
656 chainon (field_decl_chain, field_decl);
658 /* short cat_def_cnt; */
660 field_decl = create_builtin_decl (FIELD_DECL,
661 short_integer_type_node,
663 chainon (field_decl_chain, field_decl);
665 /* void *defs[cls_def_cnt + cat_def_cnt]; */
667 index = build_index_type (build_int_2 (imp_count + cat_count - 1, 0));
668 field_decl = create_builtin_decl (FIELD_DECL,
669 build_array_type (ptr_type_node, index),
671 chainon (field_decl_chain, field_decl);
673 finish_struct (objc_symtab_template, field_decl_chain);
676 /* Create the initial value for the `defs' field of _objc_symtab.
677 This is a CONSTRUCTOR. */
682 tree expr, initlist = NULLT;
683 struct imp_entry *impent;
686 for (impent = imp_list; impent; impent = impent->next)
688 if (TREE_CODE (impent->imp_context) == IMPLEMENTATION_TYPE)
690 expr = build_unary_op (ADDR_EXPR, impent->class_decl, 0);
691 initlist = tree_cons (NULLT, expr, initlist);
696 for (impent = imp_list; impent; impent = impent->next)
698 if (TREE_CODE (impent->imp_context) == CATEGORY_TYPE)
700 expr = build_unary_op (ADDR_EXPR, impent->class_decl, 0);
701 initlist = tree_cons (NULLT, expr, initlist);
704 return build_nt (CONSTRUCTOR, NULLT, nreverse (initlist));
707 /* Construct the initial value for all of _objc_symtab. */
714 /* sel_ref_cnt = { ..., 5, ... } */
717 initlist = build_tree_list (NULLT, build_int_2 (max_selector_index, 0));
719 initlist = build_tree_list (NULLT, build_int_2 (0, 0));
721 /* refs = { ..., _OBJC_SELECTOR_REFERENCES, ... } */
723 #ifndef OBJC_SELECTORS_WITHOUT_LABELS
724 initlist = tree_cons (NULLT, build_int_2 (0, 0), initlist);
727 initlist = tree_cons (NULLT, _OBJC_SELECTOR_REFERENCES_decl, initlist);
729 initlist = tree_cons (NULLT, build_int_2 (0, 0), initlist);
732 /* cls_def_cnt = { ..., 5, ... } */
734 initlist = tree_cons (NULLT, build_int_2 (imp_count, 0), initlist);
736 /* cat_def_cnt = { ..., 5, ... } */
738 initlist = tree_cons (NULLT, build_int_2 (cat_count, 0), initlist);
740 /* cls_def = { ..., { &Foo, &Bar, ...}, ... } */
742 if (imp_count || cat_count)
743 initlist = tree_cons (NULLT, init_def_list (), initlist);
745 return build_nt (CONSTRUCTOR, NULLT, nreverse (initlist));
748 /* Push forward-declarations of all the categories
749 so that init_def_list can use them in a CONSTRUCTOR. */
752 forward_declare_categories ()
754 struct imp_entry *impent;
755 tree sav = implementation_context;
756 for (impent = imp_list; impent; impent = impent->next)
758 if (TREE_CODE (impent->imp_context) == CATEGORY_TYPE)
760 /* Set an invisible arg to synth_id_with_class_suffix. */
761 implementation_context = impent->imp_context;
763 = create_builtin_decl (VAR_DECL, objc_category_template,
764 IDENTIFIER_POINTER (synth_id_with_class_suffix ("_OBJC_CATEGORY")));
767 implementation_context = sav;
770 /* Create the declaration of _OBJC_SYMBOLS, with type `strict _objc_symtab'
771 and initialized appropriately. */
774 generate_objc_symtab_decl ()
778 if (!objc_category_template)
779 build_category_template ();
781 /* forward declare categories */
783 forward_declare_categories ();
785 if (!objc_symtab_template)
786 build_objc_symtab_template ();
788 sc_spec = build_tree_list (NULLT, ridpointers[(int) RID_STATIC]);
790 _OBJC_SYMBOLS_decl = start_decl (get_identifier ("_OBJC_SYMBOLS"),
791 tree_cons (NULLT, objc_symtab_template, sc_spec), 1);
793 finish_decl (_OBJC_SYMBOLS_decl, init_objc_symtab (), NULLT);
797 * tree_node------->tree_node----->...
799 * | (value) | (value)
804 init_module_descriptor ()
808 /* version = { 1, ... } */
810 expr = build_int_2 (OBJC_VERSION, 0);
811 initlist = build_tree_list (NULLT, expr);
813 /* size = { ..., sizeof (struct objc_module), ... } */
815 expr = build_int_2 (TREE_INT_CST_LOW (TYPE_SIZE (objc_module_template)) /
817 initlist = tree_cons (NULLT, expr, initlist);
819 /* name = { ..., "foo.m", ... } */
821 expr = build_msg_pool_reference (
822 add_objc_string (get_identifier (input_filename)));
823 initlist = tree_cons (NULLT, expr, initlist);
825 /* symtab = { ..., _OBJC_SYMBOLS, ... } */
827 if (_OBJC_SYMBOLS_decl)
828 expr = build_unary_op (ADDR_EXPR, _OBJC_SYMBOLS_decl, 0);
830 expr = build_int_2 (0, 0);
831 initlist = tree_cons (NULLT, expr, initlist);
833 return build_nt (CONSTRUCTOR, NULLT, nreverse (initlist));
836 /* Write out the data structures to describe Objective C classes defined.
837 If appropriate, compile and output a setup function to initialize them.
838 Return a string which is the name of a function to call to initialize
839 the Objective C data structures for this file (and perhaps for other files
843 build_module_descriptor ()
845 tree decl_specs, field_decl, field_decl_chain;
847 objc_module_template = start_struct (RECORD_TYPE, get_identifier (_TAG_MODULE));
851 decl_specs = build_tree_list (NULLT, ridpointers[(int) RID_LONG]);
852 field_decl = get_identifier ("version");
853 field_decl = grokfield (input_filename, lineno, field_decl, decl_specs, NULLT);
854 field_decl_chain = field_decl;
858 decl_specs = build_tree_list (NULLT, ridpointers[(int) RID_LONG]);
859 field_decl = get_identifier ("size");
860 field_decl = grokfield (input_filename, lineno, field_decl, decl_specs, NULLT);
861 chainon (field_decl_chain, field_decl);
865 decl_specs = build_tree_list (NULLT, ridpointers[(int) RID_CHAR]);
866 field_decl = build1 (INDIRECT_REF, NULLT, get_identifier ("name"));
867 field_decl = grokfield (input_filename, lineno, field_decl, decl_specs, NULLT);
868 chainon (field_decl_chain, field_decl);
870 /* struct objc_symtab *symtab; */
872 decl_specs = get_identifier (_TAG_SYMTAB);
873 decl_specs = build_tree_list (NULLT, xref_tag (RECORD_TYPE, decl_specs));
874 field_decl = build1 (INDIRECT_REF, NULLT, get_identifier ("symtab"));
875 field_decl = grokfield (input_filename, lineno, field_decl, decl_specs, NULLT);
876 chainon (field_decl_chain, field_decl);
878 finish_struct (objc_module_template, field_decl_chain);
880 /* create an instance of "objc_module" */
882 decl_specs = tree_cons (NULLT, objc_module_template,
883 build_tree_list (NULLT, ridpointers[(int) RID_STATIC]));
885 _OBJC_MODULES_decl = start_decl (get_identifier ("_OBJC_MODULES"),
888 finish_decl (_OBJC_MODULES_decl, init_module_descriptor (), NULLT);
890 /* Mark the decl to avoid "defined but not used" warning. */
891 DECL_IN_SYSTEM_HEADER (_OBJC_MODULES_decl) = 1;
893 /* Generate a constructor call for the module descriptor.
894 This code was generated by reading the grammar rules
895 of c-parse.y; Therefore, it may not be the most efficient
896 way of generating the requisite code. */
897 #ifndef NEXT_OBJC_RUNTIME
899 tree parms, function_decl, decelerator, void_list_node;
902 char *global_object_name = 0;
905 /* Use a global object (which is already required to be unique over
906 the program) rather than the file name (which imposes extra
907 constraints). -- Raeburn@MIT.EDU, 10 Jan 1990. */
909 /* Find the name of some global object defined in this file. */
910 for (t = getdecls (); t; t = TREE_CHAIN (t))
911 if (TREE_PUBLIC (t) && !DECL_EXTERNAL (t) && DECL_INITIAL (t) != 0)
913 global_object_name = IDENTIFIER_POINTER (DECL_NAME (t));
917 /* If none, use the name of the file. */
918 if (!global_object_name)
922 = (char *) alloca (strlen (main_input_filename) + 1);
924 p = main_input_filename;
925 q = global_object_name;
927 /* Replace any weird characters in the file name. */
929 if (! ((*p >= '0' && *p <= '9')
930 || (*p >= 'A' && *p <= 'Z')
931 || (*p >= 'a' && *p <= 'z')))
938 /* Make the constructor name from the name we have found. */
939 buf = (char *) xmalloc (sizeof (CONSTRUCTOR_NAME_FORMAT)
940 + strlen (global_object_name));
941 sprintf (buf, CONSTRUCTOR_NAME_FORMAT, global_object_name);
943 /* Declare void __objc_execClass (void*); */
945 void_list_node = build_tree_list (NULL_TREE, void_type_node);
947 = build_function_type (void_type_node,
948 tree_cons (NULL_TREE, ptr_type_node,
950 function_decl = build_decl (FUNCTION_DECL,
951 get_identifier ("__objc_execClass"),
953 DECL_EXTERNAL (function_decl) = 1;
954 TREE_PUBLIC (function_decl) = 1;
955 pushdecl (function_decl);
956 rest_of_decl_compilation (function_decl, 0, 0, 0);
959 = build_tree_list (NULLT,
960 build_unary_op (ADDR_EXPR, _OBJC_MODULES_decl, 0));
961 decelerator = build_function_call (function_decl, parms);
963 /* void __objc_file_init () {objc_execClass(&L_OBJC_MODULES);} */
965 start_function (void_list_node,
966 build_parse_node (CALL_EXPR, get_identifier (buf),
967 /* This has the format of the output
969 tree_cons (NULL_TREE, NULL_TREE,
973 #if 0 /* This should be turned back on later
974 for the systems where collect is not needed. */
975 /* Make these functions nonglobal
976 so each file can use the same name. */
977 TREE_PUBLIC (current_function_decl) = 0;
979 TREE_USED (current_function_decl) = 1;
982 assemble_external (function_decl);
983 c_expand_expr_stmt (decelerator);
987 /* Return the name of the constructor function. */
990 #else /* NEXT_OBJC_RUNTIME */
992 #endif /* NEXT_OBJC_RUNTIME */
995 /* extern const char _OBJC_STRINGS[]; */
998 generate_forward_declaration_to_string_table ()
1000 tree sc_spec, decl_specs, expr_decl;
1002 sc_spec = tree_cons (NULLT, ridpointers[(int) RID_EXTERN], NULLT);
1003 decl_specs = tree_cons (NULLT, ridpointers[(int) RID_CHAR], sc_spec);
1005 expr_decl = build_nt (ARRAY_REF, get_identifier ("_OBJC_STRINGS"), NULLT);
1007 _OBJC_STRINGS_decl = define_decl (expr_decl, decl_specs);
1010 /* static char _OBJC_STRINGS[] = "..."; */
1013 build_message_selector_pool ()
1015 tree sc_spec, decl_specs, expr_decl;
1016 tree chain, string_expr;
1017 int goolengthtmp = 0, msg_pool_size = 0;
1020 sc_spec = tree_cons (NULLT, ridpointers[(int) RID_STATIC], NULLT);
1021 decl_specs = tree_cons (NULLT, ridpointers[(int) RID_CHAR], sc_spec);
1023 expr_decl = build_nt (ARRAY_REF, get_identifier ("_OBJC_STRINGS"), NULLT);
1025 _OBJC_STRINGS_decl = start_decl (expr_decl, decl_specs, 1);
1027 for (chain = sel_refdef_chain; chain; chain = TREE_CHAIN (chain))
1028 msg_pool_size += IDENTIFIER_LENGTH (TREE_VALUE (chain)) + 1;
1032 string_goo = (char *)xmalloc (msg_pool_size);
1033 bzero (string_goo, msg_pool_size);
1035 for (chain = sel_refdef_chain; chain; chain = TREE_CHAIN (chain))
1037 strcpy (string_goo + goolengthtmp, IDENTIFIER_POINTER (TREE_VALUE (chain)));
1038 goolengthtmp += IDENTIFIER_LENGTH (TREE_VALUE (chain)) + 1;
1041 string_expr = my_build_string (msg_pool_size, string_goo);
1043 finish_decl (_OBJC_STRINGS_decl, string_expr, NULLT);
1047 * synthesize the following expr: (char *)&_OBJC_STRINGS[<offset>]
1049 * the cast stops the compiler from issuing the following message:
1051 * grok.m: warning: initialization of non-const * pointer from const *
1052 * grok.m: warning: initialization between incompatible pointer types
1055 build_msg_pool_reference (offset)
1058 tree expr = build_int_2 (offset, 0);
1061 expr = build_array_ref (_OBJC_STRINGS_decl, expr);
1062 expr = build_unary_op (ADDR_EXPR, expr, 0);
1064 cast = build_tree_list (build_tree_list (NULLT, ridpointers[(int) RID_CHAR]),
1065 build1 (INDIRECT_REF, NULLT, NULLT));
1066 TREE_TYPE (expr) = groktypename (cast);
1070 #ifndef OBJC_SELECTORS_WITHOUT_LABELS
1072 build_selector_reference (idx)
1075 tree ref, decl, name, ident;
1077 struct obstack *save_current_obstack = current_obstack;
1078 struct obstack *save_rtl_obstack = rtl_obstack;
1080 sprintf (buf, "_OBJC_SELECTOR_REFERENCES_%d", idx);
1083 rtl_obstack = current_obstack = &permanent_obstack;
1084 ident = get_identifier (buf);
1086 if (IDENTIFIER_GLOBAL_VALUE (ident))
1087 decl = IDENTIFIER_GLOBAL_VALUE (ident); /* set by pushdecl() */
1090 decl = build_decl (VAR_DECL, ident, selector_type);
1091 DECL_EXTERNAL (decl) = 1;
1092 TREE_PUBLIC (decl) = 1;
1093 TREE_USED (decl) = 1;
1095 make_decl_rtl (decl, 0, 1); /* usually called from `rest_of_decl_compilation' */
1096 pushdecl_top_level (decl); /* our `extended/custom' pushdecl in c-decl.c */
1098 current_obstack = save_current_obstack;
1099 rtl_obstack = save_rtl_obstack;
1106 init_selector (offset)
1109 tree expr = build_msg_pool_reference (offset);
1110 TREE_TYPE (expr) = selector_type; /* cast */
1115 build_selector_translation_table ()
1117 tree sc_spec, decl_specs, expr_decl;
1118 tree chain, initlist = NULLT;
1120 #ifndef OBJC_SELECTORS_WITHOUT_LABELS
1121 tree decl, var_decl;
1125 /* The corresponding pop_obstacks is in finish_decl,
1126 called at the end of this function. */
1127 push_obstacks_nochange ();
1130 for (chain = sel_ref_chain; chain; chain = TREE_CHAIN (chain))
1134 #ifndef OBJC_SELECTORS_WITHOUT_LABELS
1135 sprintf (buf, "_OBJC_SELECTOR_REFERENCES_%d", idx);
1136 sc_spec = build_tree_list (NULLT, ridpointers[(int) RID_STATIC]);
1138 /* static SEL _OBJC_SELECTOR_REFERENCES_n = ...; */
1139 decl_specs = tree_cons (NULLT, selector_type, sc_spec);
1140 var_decl = get_identifier (buf);
1142 /* the `decl' that is returned from start_decl is the one that we
1143 * forward declared in `build_selector_reference()'
1145 decl = start_decl (var_decl, decl_specs, 1);
1148 expr = init_selector (offset);
1150 /* add one for the '\0' character */
1151 offset += IDENTIFIER_LENGTH (TREE_VALUE (chain)) + 1;
1153 #ifndef OBJC_SELECTORS_WITHOUT_LABELS
1154 finish_decl (decl, expr, NULLT);
1157 initlist = tree_cons (NULLT, expr, initlist);
1161 #ifdef OBJC_SELECTORS_WITHOUT_LABELS
1162 /* Cause the variable and its initial value to be actually output. */
1163 DECL_EXTERNAL (_OBJC_SELECTOR_REFERENCES_decl) = 0;
1164 TREE_STATIC (_OBJC_SELECTOR_REFERENCES_decl) = 1;
1165 /* NULL terminate the list and fix the decl for output. */
1166 initlist = tree_cons (NULLT, build_int_2 (0, 0), initlist);
1167 DECL_INITIAL (_OBJC_SELECTOR_REFERENCES_decl) = (tree) 1;
1168 initlist = build_nt (CONSTRUCTOR, NULLT, nreverse (initlist));
1169 finish_decl (_OBJC_SELECTOR_REFERENCES_decl, initlist, NULLT);
1174 add_class_reference (ident)
1179 if (chain = cls_ref_chain)
1184 if (ident == TREE_VALUE (chain))
1188 chain = TREE_CHAIN (chain);
1192 /* append to the end of the list */
1193 TREE_CHAIN (tail) = perm_tree_cons (NULLT, ident, NULLT);
1196 cls_ref_chain = perm_tree_cons (NULLT, ident, NULLT);
1200 * sel_ref_chain is a list whose "value" fields will be instances of
1201 * identifier_node that represent the selector.
1204 add_selector_reference (ident)
1210 /* this adds it to sel_refdef_chain, the global pool of selectors */
1211 add_objc_string (ident);
1213 if (chain = sel_ref_chain)
1218 if (ident == TREE_VALUE (chain))
1223 chain = TREE_CHAIN (chain);
1227 /* append to the end of the list */
1228 TREE_CHAIN (tail) = perm_tree_cons (NULLT, ident, NULLT);
1231 sel_ref_chain = perm_tree_cons (NULLT, ident, NULLT);
1233 max_selector_index++;
1238 * sel_refdef_chain is a list whose "value" fields will be instances of
1239 * identifier_node that represent the selector. It returns the offset of
1240 * the selector from the beginning of the _OBJC_STRINGS pool. This offset
1241 * is typically used by "init_selector ()" during code generation.
1244 add_objc_string (ident)
1250 if (chain = sel_refdef_chain)
1255 if (ident == TREE_VALUE (chain))
1258 /* add one for the '\0' character */
1259 offset += IDENTIFIER_LENGTH (TREE_VALUE (chain)) + 1;
1261 chain = TREE_CHAIN (chain);
1265 /* append to the end of the list */
1266 TREE_CHAIN (tail) = perm_tree_cons (NULLT, ident, NULLT);
1269 sel_refdef_chain = perm_tree_cons (NULLT, ident, NULLT);
1275 lookup_interface (ident)
1280 for (chain = interface_chain; chain; chain = TREE_CHAIN (chain))
1282 if (ident == CLASS_NAME (chain))
1289 objc_copy_list (list, head)
1293 tree newlist = NULL_TREE, tail = NULL_TREE;
1297 tail = copy_node (list);
1299 /* the following statement fixes a bug when inheriting instance
1300 variables that are declared to be bitfields. finish_struct () expects
1301 to find the width of the bitfield in DECL_INITIAL (), which it
1302 nulls out after processing the decl of the super class...rather
1303 than change the way finish_struct () works (which is risky),
1304 I create the situation it expects...s.naroff (7/23/89).
1306 if (DECL_BIT_FIELD (tail) && DECL_INITIAL (tail) == 0)
1307 DECL_INITIAL (tail) = build_int_2 (DECL_FIELD_SIZE (tail), 0);
1309 newlist = chainon (newlist, tail);
1310 list = TREE_CHAIN (list);
1317 * build_private_template (), get_class_ivars (), and get_static_reference ().
1320 build_ivar_chain (interface)
1323 tree my_name, super_name, ivar_chain;
1325 my_name = CLASS_NAME (interface);
1326 super_name = CLASS_SUPER_NAME (interface);
1328 /* "leaf" ivars never get copied...there is no reason to. */
1329 ivar_chain = CLASS_IVARS (interface);
1334 tree super_interface = lookup_interface (super_name);
1336 if (!super_interface)
1338 /* fatal did not work with 2 args...should fix */
1339 error ("Cannot find interface declaration for `%s', superclass of `%s'",
1340 IDENTIFIER_POINTER (super_name), IDENTIFIER_POINTER (my_name));
1343 if (super_interface == interface)
1345 fatal ("Circular inheritance in interface declaration for `%s'",
1346 IDENTIFIER_POINTER (super_name));
1348 interface = super_interface;
1349 my_name = CLASS_NAME (interface);
1350 super_name = CLASS_SUPER_NAME (interface);
1352 op1 = CLASS_IVARS (interface);
1355 tree head, tail = objc_copy_list (op1, &head);
1357 /* prepend super class ivars...make a copy of the list, we
1358 * do not want to alter the original.
1360 TREE_CHAIN (tail) = ivar_chain;
1368 * struct <classname> {
1369 * struct objc_class *isa;
1374 build_private_template (class)
1379 if (CLASS_STATIC_TEMPLATE (class))
1381 _PRIVATE_record = CLASS_STATIC_TEMPLATE (class);
1382 ivar_context = TYPE_FIELDS (CLASS_STATIC_TEMPLATE (class));
1386 _PRIVATE_record = start_struct (RECORD_TYPE, CLASS_NAME (class));
1388 ivar_context = build_ivar_chain (class);
1390 finish_struct (_PRIVATE_record, ivar_context);
1392 CLASS_STATIC_TEMPLATE (class) = _PRIVATE_record;
1394 /* mark this record as class template - for class type checking */
1395 TREE_STATIC_TEMPLATE (_PRIVATE_record) = 1;
1397 instance_type = groktypename (
1398 build_tree_list (build_tree_list (NULLT, _PRIVATE_record),
1399 build1 (INDIRECT_REF, NULLT, NULLT)));
1400 return ivar_context;
1404 * struct objc_category {
1405 * char *category_name;
1407 * struct objc_method_list *instance_methods;
1408 * struct objc_method_list *class_methods;
1412 build_category_template ()
1414 tree decl_specs, field_decl, field_decl_chain;
1416 objc_category_template = start_struct (RECORD_TYPE,
1417 get_identifier (_TAG_CATEGORY));
1418 /* char *category_name; */
1420 decl_specs = build_tree_list (NULLT, ridpointers[(int) RID_CHAR]);
1421 field_decl = build1 (INDIRECT_REF, NULLT, get_identifier ("category_name"));
1422 field_decl = grokfield (input_filename, lineno, field_decl, decl_specs, NULLT);
1423 field_decl_chain = field_decl;
1425 /* char *class_name; */
1427 decl_specs = build_tree_list (NULLT, ridpointers[(int) RID_CHAR]);
1428 field_decl = build1 (INDIRECT_REF, NULLT, get_identifier ("class_name"));
1429 field_decl = grokfield (input_filename, lineno, field_decl, decl_specs, NULLT);
1430 chainon (field_decl_chain, field_decl);
1432 /* struct objc_method_list *instance_methods; */
1434 decl_specs = build_tree_list (NULLT, xref_tag (RECORD_TYPE,
1435 get_identifier (_TAG_METHOD_LIST)));
1436 field_decl = build1 (INDIRECT_REF, NULLT, get_identifier ("instance_methods"));
1437 field_decl = grokfield (input_filename, lineno, field_decl, decl_specs, NULLT);
1438 chainon (field_decl_chain, field_decl);
1440 /* struct objc_method_list *class_methods; */
1442 decl_specs = build_tree_list (NULLT, xref_tag (RECORD_TYPE,
1443 get_identifier (_TAG_METHOD_LIST)));
1444 field_decl = build1 (INDIRECT_REF, NULLT, get_identifier ("class_methods"));
1445 field_decl = grokfield (input_filename, lineno, field_decl, decl_specs, NULLT);
1446 chainon (field_decl_chain, field_decl);
1448 finish_struct (objc_category_template, field_decl_chain);
1452 * struct objc_class {
1453 * struct objc_class *isa;
1454 * struct objc_class *super_class;
1458 * long instance_size;
1459 * struct objc_ivar_list *ivars;
1460 * struct objc_method_list *methods;
1461 * struct objc_cache *cache;
1465 build_class_template ()
1467 tree decl_specs, field_decl, field_decl_chain;
1469 objc_class_template = start_struct (RECORD_TYPE, get_identifier (_TAG_CLASS));
1471 /* struct objc_class *isa; */
1473 decl_specs = build_tree_list (NULLT, objc_class_template);
1474 field_decl = build1 (INDIRECT_REF, NULLT, get_identifier ("isa"));
1475 field_decl = grokfield (input_filename, lineno, field_decl, decl_specs, NULLT);
1476 field_decl_chain = field_decl;
1478 /* struct objc_class *super_class; */
1480 decl_specs = build_tree_list (NULLT, objc_class_template);
1481 field_decl = build1 (INDIRECT_REF, NULLT, get_identifier ("super_class"));
1482 field_decl = grokfield (input_filename, lineno, field_decl, decl_specs, NULLT);
1483 chainon (field_decl_chain, field_decl);
1487 decl_specs = build_tree_list (NULLT, ridpointers[(int) RID_CHAR]);
1488 field_decl = build1 (INDIRECT_REF, NULLT, get_identifier ("name"));
1489 field_decl = grokfield (input_filename, lineno, field_decl, decl_specs, NULLT);
1490 chainon (field_decl_chain, field_decl);
1494 decl_specs = build_tree_list (NULLT, ridpointers[(int) RID_LONG]);
1495 field_decl = get_identifier ("version");
1496 field_decl = grokfield (input_filename, lineno, field_decl, decl_specs, NULLT);
1497 chainon (field_decl_chain, field_decl);
1501 decl_specs = build_tree_list (NULLT, ridpointers[(int) RID_LONG]);
1502 field_decl = get_identifier ("info");
1503 field_decl = grokfield (input_filename, lineno, field_decl, decl_specs, NULLT);
1504 chainon (field_decl_chain, field_decl);
1506 /* long instance_size; */
1508 decl_specs = build_tree_list (NULLT, ridpointers[(int) RID_LONG]);
1509 field_decl = get_identifier ("instance_size");
1510 field_decl = grokfield (input_filename, lineno, field_decl, decl_specs, NULLT);
1511 chainon (field_decl_chain, field_decl);
1513 /* struct objc_ivar_list *ivars; */
1515 decl_specs = build_tree_list (NULLT, xref_tag (RECORD_TYPE,
1516 get_identifier (_TAG_IVAR_LIST)));
1517 field_decl = build1 (INDIRECT_REF, NULLT, get_identifier ("ivars"));
1518 field_decl = grokfield (input_filename, lineno, field_decl, decl_specs, NULLT);
1519 chainon (field_decl_chain, field_decl);
1521 /* struct objc_method_list *methods; */
1523 decl_specs = build_tree_list (NULLT, xref_tag (RECORD_TYPE,
1524 get_identifier (_TAG_METHOD_LIST)));
1525 field_decl = build1 (INDIRECT_REF, NULLT, get_identifier ("methods"));
1526 field_decl = grokfield (input_filename, lineno, field_decl, decl_specs, NULLT);
1527 chainon (field_decl_chain, field_decl);
1529 /* struct objc_cache *cache; */
1531 decl_specs = build_tree_list (NULLT, xref_tag (RECORD_TYPE,
1532 get_identifier ("objc_cache")));
1533 field_decl = build1 (INDIRECT_REF, NULLT, get_identifier ("cache"));
1534 field_decl = grokfield (input_filename, lineno, field_decl, decl_specs, NULLT);
1535 chainon (field_decl_chain, field_decl);
1537 finish_struct (objc_class_template, field_decl_chain);
1541 * generate appropriate forward declarations for an implementation
1544 synth_forward_declarations ()
1546 tree sc_spec, decl_specs, factory_id, anId;
1548 /* extern struct objc_class _OBJC_CLASS_<my_name>; */
1550 anId = synth_id_with_class_suffix ("_OBJC_CLASS");
1552 sc_spec = build_tree_list (NULLT, ridpointers[(int) RID_EXTERN]);
1553 decl_specs = tree_cons (NULLT, objc_class_template, sc_spec);
1554 _OBJC_CLASS_decl = define_decl (anId, decl_specs);
1556 /* extern struct objc_class _OBJC_METACLASS_<my_name>; */
1558 anId = synth_id_with_class_suffix ("_OBJC_METACLASS");
1560 _OBJC_METACLASS_decl = define_decl (anId, decl_specs);
1562 /* pre-build the following entities - for speed/convenience. */
1564 anId = get_identifier ("super_class");
1565 _clsSuper_ref = build_component_ref (_OBJC_CLASS_decl, anId);
1566 __clsSuper_ref = build_component_ref (_OBJC_METACLASS_decl, anId);
1570 error_with_ivar (message, decl, rawdecl)
1576 fprintf (stderr, "%s:%d: ",
1577 DECL_SOURCE_FILE (decl), DECL_SOURCE_LINE (decl));
1578 bzero (errbuf, BUFSIZE);
1579 fprintf (stderr, "%s `%s'\n", message, gen_declaration (rawdecl, errbuf));
1582 #define USERTYPE(t) (TREE_CODE (t) == RECORD_TYPE || \
1583 TREE_CODE (t) == UNION_TYPE || \
1584 TREE_CODE (t) == ENUMERAL_TYPE)
1587 check_ivars (inter, imp)
1591 tree intdecls = CLASS_IVARS (inter);
1592 tree impdecls = CLASS_IVARS (imp);
1593 tree rawintdecls = CLASS_RAW_IVARS (inter);
1594 tree rawimpdecls = CLASS_RAW_IVARS (imp);
1600 if (intdecls == 0 && impdecls == 0)
1602 if (intdecls == 0 || impdecls == 0)
1604 error ("inconsistent instance variable specification");
1607 t1 = TREE_TYPE (intdecls); t2 = TREE_TYPE (impdecls);
1609 if (!comptypes (t1, t2))
1611 if (DECL_NAME (intdecls) == DECL_NAME (impdecls))
1613 error_with_ivar ("conflicting instance variable type",
1614 impdecls, rawimpdecls);
1615 error_with_ivar ("previous declaration of",
1616 intdecls, rawintdecls);
1618 else /* both the type and the name don't match */
1620 error ("inconsistent instance variable specification");
1624 else if (DECL_NAME (intdecls) != DECL_NAME (impdecls))
1626 error_with_ivar ("conflicting instance variable name",
1627 impdecls, rawimpdecls);
1628 error_with_ivar ("previous declaration of",
1629 intdecls, rawintdecls);
1631 intdecls = TREE_CHAIN (intdecls);
1632 impdecls = TREE_CHAIN (impdecls);
1633 rawintdecls = TREE_CHAIN (rawintdecls);
1634 rawimpdecls = TREE_CHAIN (rawimpdecls);
1639 * struct objc_super {
1641 * struct objc_class *class;
1645 build_super_template ()
1647 tree record, decl_specs, field_decl, field_decl_chain;
1649 record = start_struct (RECORD_TYPE, get_identifier (_TAG_SUPER));
1651 /* struct objc_object *self; */
1653 decl_specs = build_tree_list (NULLT, objc_object_reference);
1654 field_decl = get_identifier ("self");
1655 field_decl = build1 (INDIRECT_REF, NULLT, field_decl);
1656 field_decl = grokfield (input_filename, lineno, field_decl, decl_specs, NULLT);
1657 field_decl_chain = field_decl;
1659 /* struct objc_class *class; */
1661 decl_specs = get_identifier (_TAG_CLASS);
1662 decl_specs = build_tree_list (NULLT, xref_tag (RECORD_TYPE, decl_specs));
1663 field_decl = build1 (INDIRECT_REF, NULLT, get_identifier ("class"));
1665 field_decl = grokfield (input_filename, lineno, field_decl, decl_specs, NULLT);
1666 chainon (field_decl_chain, field_decl);
1668 finish_struct (record, field_decl_chain);
1670 /* `struct objc_super *' */
1671 super_type = groktypename (build_tree_list (build_tree_list (NULLT, record),
1672 build1 (INDIRECT_REF, NULLT, NULLT)));
1677 * struct objc_ivar {
1684 build_ivar_template ()
1686 tree objc_ivar_id, objc_ivar_record;
1687 tree decl_specs, field_decl, field_decl_chain;
1689 objc_ivar_id = get_identifier (_TAG_IVAR);
1690 objc_ivar_record = start_struct (RECORD_TYPE, objc_ivar_id);
1692 /* char *ivar_name; */
1694 decl_specs = build_tree_list (NULLT, ridpointers[(int) RID_CHAR]);
1695 field_decl = build1 (INDIRECT_REF, NULLT, get_identifier ("ivar_name"));
1697 field_decl = grokfield (input_filename, lineno, field_decl, decl_specs, NULLT);
1698 field_decl_chain = field_decl;
1700 /* char *ivar_type; */
1702 decl_specs = build_tree_list (NULLT, ridpointers[(int) RID_CHAR]);
1703 field_decl = build1 (INDIRECT_REF, NULLT, get_identifier ("ivar_type"));
1705 field_decl = grokfield (input_filename, lineno, field_decl, decl_specs, NULLT);
1706 chainon (field_decl_chain, field_decl);
1708 /* int ivar_offset; */
1710 decl_specs = build_tree_list (NULLT, ridpointers[(int) RID_INT]);
1711 field_decl = get_identifier ("ivar_offset");
1713 field_decl = grokfield (input_filename, lineno, field_decl, decl_specs, NULLT);
1714 chainon (field_decl_chain, field_decl);
1716 finish_struct (objc_ivar_record, field_decl_chain);
1718 return objc_ivar_record;
1724 * struct objc_ivar ivar_list[ivar_count];
1728 build_ivar_list_template (list_type, size)
1732 tree objc_ivar_list_id, objc_ivar_list_record;
1733 tree decl_specs, field_decl, field_decl_chain;
1735 objc_ivar_list_record = start_struct (RECORD_TYPE, NULLT);
1737 /* int ivar_count; */
1739 decl_specs = build_tree_list (NULLT, ridpointers[(int) RID_INT]);
1740 field_decl = get_identifier ("ivar_count");
1742 field_decl = grokfield (input_filename, lineno, field_decl, decl_specs, NULLT);
1743 field_decl_chain = field_decl;
1745 /* struct objc_ivar ivar_list[]; */
1747 decl_specs = build_tree_list (NULLT, list_type);
1748 field_decl = build_nt (ARRAY_REF, get_identifier ("ivar_list"),
1749 build_int_2 (size, 0));
1751 field_decl = grokfield (input_filename, lineno, field_decl, decl_specs, NULLT);
1752 chainon (field_decl_chain, field_decl);
1754 finish_struct (objc_ivar_list_record, field_decl_chain);
1756 return objc_ivar_list_record;
1763 * struct objc_method method_list[method_count];
1767 build_method_list_template (list_type, size)
1771 tree objc_ivar_list_id, objc_ivar_list_record;
1772 tree decl_specs, field_decl, field_decl_chain;
1774 objc_ivar_list_record = start_struct (RECORD_TYPE, NULLT);
1776 /* int method_next; */
1778 decl_specs = build_tree_list (NULLT, ridpointers[(int) RID_INT]);
1779 field_decl = get_identifier ("method_next");
1781 field_decl = grokfield (input_filename, lineno, field_decl, decl_specs, NULLT);
1782 field_decl_chain = field_decl;
1784 /* int method_count; */
1786 decl_specs = build_tree_list (NULLT, ridpointers[(int) RID_INT]);
1787 field_decl = get_identifier ("method_count");
1789 field_decl = grokfield (input_filename, lineno, field_decl, decl_specs, NULLT);
1790 chainon (field_decl_chain, field_decl);
1792 /* struct objc_method method_list[]; */
1794 decl_specs = build_tree_list (NULLT, list_type);
1795 field_decl = build_nt (ARRAY_REF, get_identifier ("method_list"),
1796 build_int_2 (size, 0));
1798 field_decl = grokfield (input_filename, lineno, field_decl, decl_specs, NULLT);
1799 chainon (field_decl_chain, field_decl);
1801 finish_struct (objc_ivar_list_record, field_decl_chain);
1803 return objc_ivar_list_record;
1807 build_ivar_list_initializer (field_decl, size)
1811 tree initlist = NULLT;
1818 if (DECL_NAME (field_decl))
1820 offset = add_objc_string (DECL_NAME (field_decl));
1821 initlist = tree_cons (NULLT, build_msg_pool_reference (offset), initlist);
1825 /* unnamed bit-field ivar (yuck). */
1826 initlist = tree_cons (NULLT, build_int_2 (0, 0), initlist);
1830 encode_field_decl (field_decl, OBJC_ENCODE_DONT_INLINE_DEFS);
1831 offset = add_objc_string (get_identifier (obstack_finish (&util_obstack)));
1832 obstack_free (&util_obstack, util_firstobj);
1834 initlist = tree_cons (NULLT, build_msg_pool_reference (offset), initlist);
1837 initlist = tree_cons (NULLT,
1838 build_int_2 (TREE_INT_CST_LOW (DECL_FIELD_BITPOS (field_decl)) / BITS_PER_UNIT, 0),
1842 field_decl = TREE_CHAIN (field_decl);
1846 return build_nt (CONSTRUCTOR, NULLT, nreverse (initlist));
1850 generate_ivars_list (type, name, size, list)
1856 tree sc_spec, decl_specs, decl, initlist;
1858 sc_spec = tree_cons (NULLT, ridpointers[(int) RID_STATIC], NULLT);
1859 decl_specs = tree_cons (NULLT, type, sc_spec);
1861 decl = start_decl (synth_id_with_class_suffix (name), decl_specs, 1);
1863 initlist = build_tree_list (NULLT, build_int_2 (size, 0));
1864 initlist = tree_cons (NULLT, list, initlist);
1866 finish_decl (decl, build_nt (CONSTRUCTOR, NULLT, nreverse (initlist)), NULLT);
1872 generate_ivar_lists ()
1874 tree initlist, ivar_list_template, chain;
1875 tree cast, variable_length_type;
1878 if (!objc_ivar_template)
1879 objc_ivar_template = build_ivar_template ();
1881 cast = build_tree_list (build_tree_list (NULLT, xref_tag (RECORD_TYPE,
1882 get_identifier (_TAG_IVAR_LIST))), NULLT);
1883 variable_length_type = groktypename (cast);
1885 /* only generate class variables for the root of the inheritance
1886 hierarchy since these will be the same for every class */
1888 if (CLASS_SUPER_NAME (implementation_template) == NULLT
1889 && (chain = TYPE_FIELDS (objc_class_template)))
1892 initlist = build_ivar_list_initializer (chain, &size);
1894 ivar_list_template = build_ivar_list_template (objc_ivar_template, size);
1896 _OBJC_CLASS_VARIABLES_decl =
1897 generate_ivars_list (ivar_list_template, "_OBJC_CLASS_VARIABLES",
1900 TREE_TYPE (_OBJC_CLASS_VARIABLES_decl) = variable_length_type;
1903 _OBJC_CLASS_VARIABLES_decl = 0;
1905 chain = CLASS_IVARS (implementation_template);
1909 initlist = build_ivar_list_initializer (chain, &size);
1911 ivar_list_template = build_ivar_list_template (objc_ivar_template, size);
1913 _OBJC_INSTANCE_VARIABLES_decl =
1914 generate_ivars_list (ivar_list_template, "_OBJC_INSTANCE_VARIABLES",
1917 TREE_TYPE (_OBJC_INSTANCE_VARIABLES_decl) = variable_length_type;
1920 _OBJC_INSTANCE_VARIABLES_decl = 0;
1924 build_dispatch_table_initializer (entries, size)
1928 tree initlist = NULLT;
1932 int offset = add_objc_string (METHOD_SEL_NAME (entries));
1934 initlist = tree_cons (NULLT, init_selector (offset), initlist);
1936 offset = add_objc_string (METHOD_ENCODING (entries));
1937 initlist = tree_cons (NULLT, build_msg_pool_reference (offset), initlist);
1939 initlist = tree_cons (NULLT, METHOD_DEFINITION (entries), initlist);
1942 entries = TREE_CHAIN (entries);
1946 return build_nt (CONSTRUCTOR, NULLT, nreverse (initlist));
1950 * To accomplish method prototyping without generating all kinds of
1951 * inane warnings, the definition of the dispatch table entries were
1954 * struct objc_method { SEL _cmd; id (*_imp)(); };
1956 * struct objc_method { SEL _cmd; void *_imp; };
1959 build_method_template ()
1962 tree decl_specs, field_decl, field_decl_chain, parms;
1964 _SLT_record = start_struct (RECORD_TYPE, get_identifier (_TAG_METHOD));
1966 #ifdef OBJC_INT_SELECTORS
1967 /* unsigned int _cmd; */
1968 decl_specs = tree_cons (NULLT, ridpointers[(int) RID_UNSIGNED], NULLT);
1969 decl_specs = tree_cons (NULLT, ridpointers[(int) RID_INT], decl_specs);
1970 field_decl = get_identifier ("_cmd");
1971 #else /* not OBJC_INT_SELECTORS */
1972 /* struct objc_selector *_cmd; */
1973 decl_specs = tree_cons (NULLT,
1974 xref_tag (RECORD_TYPE,
1975 get_identifier (TAG_SELECTOR)),
1977 field_decl = build1 (INDIRECT_REF, NULLT, get_identifier ("_cmd"));
1978 #endif /* not OBJC_INT_SELECTORS */
1980 field_decl = grokfield (input_filename, lineno, field_decl, decl_specs, NULLT);
1981 field_decl_chain = field_decl;
1983 decl_specs = tree_cons (NULLT, ridpointers[(int) RID_CHAR], NULLT);
1984 field_decl = build1 (INDIRECT_REF, NULLT, get_identifier ("method_types"));
1985 field_decl = grokfield (input_filename, lineno, field_decl, decl_specs, NULLT);
1986 chainon (field_decl_chain, field_decl);
1990 decl_specs = tree_cons (NULLT, ridpointers[(int) RID_VOID], NULLT);
1991 field_decl = build1 (INDIRECT_REF, NULLT, get_identifier ("_imp"));
1992 field_decl = grokfield (input_filename, lineno, field_decl, decl_specs, NULLT);
1993 chainon (field_decl_chain, field_decl);
1995 finish_struct (_SLT_record, field_decl_chain);
2002 generate_dispatch_table (type, name, size, list)
2008 tree sc_spec, decl_specs, decl, initlist;
2010 sc_spec = tree_cons (NULLT, ridpointers[(int) RID_STATIC], NULLT);
2011 decl_specs = tree_cons (NULLT, type, sc_spec);
2013 decl = start_decl (synth_id_with_class_suffix (name), decl_specs, 1);
2015 initlist = build_tree_list (NULLT, build_int_2 (0, 0));
2016 initlist = tree_cons (NULLT, build_int_2 (size, 0), initlist);
2017 initlist = tree_cons (NULLT, list, initlist);
2019 finish_decl (decl, build_nt (CONSTRUCTOR, NULLT, nreverse (initlist)), NULLT);
2025 generate_dispatch_tables ()
2027 tree initlist, chain, method_list_template;
2028 tree cast, variable_length_type;
2031 if (!objc_method_template)
2032 objc_method_template = build_method_template ();
2034 cast = build_tree_list (build_tree_list (NULLT, xref_tag (RECORD_TYPE,
2035 get_identifier (_TAG_METHOD_LIST))), NULLT);
2036 variable_length_type = groktypename (cast);
2038 chain = CLASS_CLS_METHODS (implementation_context);
2042 initlist = build_dispatch_table_initializer (chain, &size);
2044 method_list_template = build_method_list_template (objc_method_template,
2046 if (TREE_CODE (implementation_context) == IMPLEMENTATION_TYPE)
2047 _OBJC_CLASS_METHODS_decl =
2048 generate_dispatch_table (method_list_template,
2049 "_OBJC_CLASS_METHODS",
2052 /* we have a category */
2053 _OBJC_CLASS_METHODS_decl =
2054 generate_dispatch_table (method_list_template,
2055 "_OBJC_CATEGORY_CLASS_METHODS",
2058 TREE_TYPE (_OBJC_CLASS_METHODS_decl) = variable_length_type;
2061 _OBJC_CLASS_METHODS_decl = 0;
2063 chain = CLASS_NST_METHODS (implementation_context);
2067 initlist = build_dispatch_table_initializer (chain, &size);
2069 method_list_template = build_method_list_template (objc_method_template,
2071 if (TREE_CODE (implementation_context) == IMPLEMENTATION_TYPE)
2072 _OBJC_INSTANCE_METHODS_decl =
2073 generate_dispatch_table (method_list_template,
2074 "_OBJC_INSTANCE_METHODS",
2077 /* we have a category */
2078 _OBJC_INSTANCE_METHODS_decl =
2079 generate_dispatch_table (method_list_template,
2080 "_OBJC_CATEGORY_INSTANCE_METHODS",
2083 TREE_TYPE (_OBJC_INSTANCE_METHODS_decl) = variable_length_type;
2086 _OBJC_INSTANCE_METHODS_decl = 0;
2090 build_category_initializer (cat_name, class_name,
2091 instance_methods, class_methods)
2094 tree instance_methods;
2097 tree initlist = NULLT, expr;
2099 initlist = tree_cons (NULLT, cat_name, initlist);
2100 initlist = tree_cons (NULLT, class_name, initlist);
2102 if (!instance_methods)
2103 initlist = tree_cons (NULLT, build_int_2 (0, 0), initlist);
2106 expr = build_unary_op (ADDR_EXPR, instance_methods, 0);
2107 initlist = tree_cons (NULLT, expr, initlist);
2110 initlist = tree_cons (NULLT, build_int_2 (0, 0), initlist);
2113 expr = build_unary_op (ADDR_EXPR, class_methods, 0);
2114 initlist = tree_cons (NULLT, expr, initlist);
2116 return build_nt (CONSTRUCTOR, NULLT, nreverse (initlist));
2120 * struct objc_class {
2121 * struct objc_class *isa;
2122 * struct objc_class *super_class;
2126 * long instance_size;
2127 * struct objc_ivar_list *ivars;
2128 * struct objc_method_list *methods;
2129 * struct objc_cache *cache;
2133 build_shared_structure_initializer (isa, super, name, size, status,
2134 dispatch_table, ivar_list)
2140 tree dispatch_table;
2143 tree initlist = NULLT, expr;
2146 initlist = tree_cons (NULLT, isa, initlist);
2149 initlist = tree_cons (NULLT, super, initlist);
2152 initlist = tree_cons (NULLT, name, initlist);
2155 initlist = tree_cons (NULLT, build_int_2 (0, 0), initlist);
2158 initlist = tree_cons (NULLT, build_int_2 (status, 0), initlist);
2160 /* instance_size = */
2161 initlist = tree_cons (NULLT, size, initlist);
2163 /* objc_ivar_list = */
2165 initlist = tree_cons (NULLT, build_int_2 (0, 0), initlist);
2168 expr = build_unary_op (ADDR_EXPR, ivar_list, 0);
2169 initlist = tree_cons (NULLT, expr, initlist);
2172 /* objc_method_list = */
2173 if (!dispatch_table)
2174 initlist = tree_cons (NULLT, build_int_2 (0, 0), initlist);
2177 expr = build_unary_op (ADDR_EXPR, dispatch_table, 0);
2178 initlist = tree_cons (NULLT, expr, initlist);
2181 /* method_cache = */
2182 initlist = tree_cons (NULLT, build_int_2 (0, 0), initlist);
2184 return build_nt (CONSTRUCTOR, NULLT, nreverse (initlist));
2188 * static struct objc_category _OBJC_CATEGORY_<name> = { ... };
2191 generate_category (cat)
2194 tree sc_spec, decl_specs, decl;
2195 tree initlist, cat_name_expr, class_name_expr;
2198 sc_spec = tree_cons (NULLT, ridpointers[(int) RID_STATIC], NULLT);
2199 decl_specs = tree_cons (NULLT, objc_category_template, sc_spec);
2201 decl = start_decl (synth_id_with_class_suffix ("_OBJC_CATEGORY"),
2204 offset = add_objc_string (CLASS_SUPER_NAME (cat));
2205 cat_name_expr = build_msg_pool_reference (offset);
2207 offset = add_objc_string (CLASS_NAME (cat));
2208 class_name_expr = build_msg_pool_reference (offset);
2210 initlist = build_category_initializer (
2211 cat_name_expr, class_name_expr,
2212 _OBJC_INSTANCE_METHODS_decl, _OBJC_CLASS_METHODS_decl);
2214 finish_decl (decl, initlist, NULLT);
2218 * static struct objc_class _OBJC_METACLASS_Foo={ ... };
2219 * static struct objc_class _OBJC_CLASS_Foo={ ... };
2222 generate_shared_structures ()
2224 tree sc_spec, decl_specs, expr_decl, decl;
2225 tree name_expr, super_expr, root_expr;
2226 tree my_root_id = NULLT, my_super_id = NULLT;
2227 tree cast_type, initlist;
2230 my_super_id = CLASS_SUPER_NAME (implementation_template);
2233 add_class_reference (my_super_id);
2235 /* compute "my_root_id" - this is required for code generation.
2236 * the "isa" for all meta class structures points to the root of
2237 * the inheritance hierarchy (e.g. "__Object")...
2239 my_root_id = my_super_id;
2242 tree my_root_int = lookup_interface (my_root_id);
2244 if (my_root_int && CLASS_SUPER_NAME (my_root_int))
2245 my_root_id = CLASS_SUPER_NAME (my_root_int);
2251 else /* no super class */
2253 my_root_id = CLASS_NAME (implementation_template);
2256 cast_type = groktypename (build_tree_list (build_tree_list (NULLT,
2257 objc_class_template), build1 (INDIRECT_REF, NULLT, NULLT)));
2259 offset = add_objc_string (CLASS_NAME (implementation_template));
2260 name_expr = build_msg_pool_reference (offset);
2262 /* install class `isa' and `super' pointers at runtime */
2265 offset = add_objc_string (my_super_id);
2266 super_expr = build_msg_pool_reference (offset);
2267 TREE_TYPE (super_expr) = cast_type; /* cast! */
2270 super_expr = build_int_2 (0, 0);
2272 offset = add_objc_string (my_root_id);
2273 root_expr = build_msg_pool_reference (offset);
2274 TREE_TYPE (root_expr) = cast_type; /* cast! */
2276 /* static struct objc_class _OBJC_METACLASS_Foo = { ... }; */
2278 sc_spec = build_tree_list (NULLT, ridpointers[(int) RID_STATIC]);
2279 decl_specs = tree_cons (NULLT, objc_class_template, sc_spec);
2281 decl = start_decl (DECL_NAME (_OBJC_METACLASS_decl), decl_specs, 1);
2283 initlist = build_shared_structure_initializer (
2284 root_expr, super_expr, name_expr,
2285 build_int_2 (TREE_INT_CST_LOW (TYPE_SIZE (objc_class_template)) / BITS_PER_UNIT, 0),
2287 _OBJC_CLASS_METHODS_decl, _OBJC_CLASS_VARIABLES_decl);
2289 finish_decl (decl, initlist, NULLT);
2291 /* static struct objc_class _OBJC_CLASS_Foo={ ... }; */
2293 decl = start_decl (DECL_NAME (_OBJC_CLASS_decl), decl_specs, 1);
2295 initlist = build_shared_structure_initializer (
2296 build_unary_op (ADDR_EXPR, _OBJC_METACLASS_decl, 0),
2297 super_expr, name_expr,
2298 build_int_2 (TREE_INT_CST_LOW (TYPE_SIZE (CLASS_STATIC_TEMPLATE (implementation_template))) / BITS_PER_UNIT, 0),
2300 _OBJC_INSTANCE_METHODS_decl, _OBJC_INSTANCE_VARIABLES_decl);
2302 finish_decl (decl, initlist, NULLT);
2306 synth_id_with_class_suffix (preamble)
2310 if (TREE_CODE (implementation_context) == IMPLEMENTATION_TYPE)
2312 string = (char *) alloca (strlen (preamble)
2313 + strlen (IDENTIFIER_POINTER (CLASS_NAME (implementation_context)))
2315 sprintf (string, "%s_%s", preamble,
2316 IDENTIFIER_POINTER (CLASS_NAME (implementation_context)));
2320 /* we have a category */
2321 string = (char *) alloca (strlen (preamble)
2322 + strlen (IDENTIFIER_POINTER (CLASS_NAME (implementation_context)))
2323 + strlen (IDENTIFIER_POINTER (CLASS_SUPER_NAME (implementation_context)))
2325 sprintf (string, "%s_%s_%s", preamble,
2326 IDENTIFIER_POINTER (CLASS_NAME (implementation_context)),
2327 IDENTIFIER_POINTER (CLASS_SUPER_NAME (implementation_context)));
2329 return get_identifier (string);
2335 * selector ':' '(' typename ')' identifier
2338 * transform an Objective-C keyword argument into
2339 * the C equivalent parameter declarator.
2341 * in: key_name, an "identifier_node" (optional).
2342 * arg_type, a "tree_list" (optional).
2343 * arg_name, an "identifier_node".
2345 * note: it would be really nice to strongly type the preceding
2346 * arguments in the function prototype; however, then i
2347 * could not use the "accessor" macros defined in "tree.h".
2349 * out: an instance of "keyword_decl".
2354 build_keyword_decl (key_name, arg_type, arg_name)
2361 /* if no type is specified, default to "id" */
2362 if (arg_type == NULLT)
2363 arg_type = build_tree_list (build_tree_list (NULLT, objc_object_reference),
2364 build1 (INDIRECT_REF, NULLT, NULLT));
2366 keyword_decl = make_node (KEYWORD_DECL);
2368 TREE_TYPE (keyword_decl) = arg_type;
2369 KEYWORD_ARG_NAME (keyword_decl) = arg_name;
2370 KEYWORD_KEY_NAME (keyword_decl) = key_name;
2372 return keyword_decl;
2376 * given a chain of keyword_decl's, synthesize the full keyword selector.
2379 build_keyword_selector (selector)
2383 tree key_chain, key_name;
2386 for (key_chain = selector; key_chain; key_chain = TREE_CHAIN (key_chain))
2388 if (TREE_CODE (selector) == KEYWORD_DECL)
2389 key_name = KEYWORD_KEY_NAME (key_chain);
2390 else if (TREE_CODE (selector) == TREE_LIST)
2391 key_name = TREE_PURPOSE (key_chain);
2394 len += IDENTIFIER_LENGTH (key_name) + 1;
2395 else /* just a ':' arg */
2398 buf = (char *)alloca (len + 1);
2399 bzero (buf, len + 1);
2401 for (key_chain = selector; key_chain; key_chain = TREE_CHAIN (key_chain))
2403 if (TREE_CODE (selector) == KEYWORD_DECL)
2404 key_name = KEYWORD_KEY_NAME (key_chain);
2405 else if (TREE_CODE (selector) == TREE_LIST)
2406 key_name = TREE_PURPOSE (key_chain);
2409 strcat (buf, IDENTIFIER_POINTER (key_name));
2412 return get_identifier (buf);
2415 /* used for declarations and definitions */
2418 build_method_decl (code, ret_type, selector, add_args)
2419 enum tree_code code;
2426 /* if no type is specified, default to "id" */
2427 if (ret_type == NULLT)
2428 ret_type = build_tree_list (build_tree_list (NULLT, objc_object_reference),
2429 build1 (INDIRECT_REF, NULLT, NULLT));
2431 method_decl = make_node (code);
2432 TREE_TYPE (method_decl) = ret_type;
2435 * if we have a keyword selector, create an identifier_node that
2436 * represents the full selector name (`:' included)...
2438 if (TREE_CODE (selector) == KEYWORD_DECL)
2440 METHOD_SEL_NAME (method_decl) = build_keyword_selector (selector);
2441 METHOD_SEL_ARGS (method_decl) = selector;
2442 METHOD_ADD_ARGS (method_decl) = add_args;
2446 METHOD_SEL_NAME (method_decl) = selector;
2447 METHOD_SEL_ARGS (method_decl) = NULLT;
2448 METHOD_ADD_ARGS (method_decl) = NULLT;
2454 #define METHOD_DEF 0
2455 #define METHOD_REF 1
2456 /* Used by `build_message_expr' and `comp_method_types'.
2457 Return an argument list for method METH.
2458 CONTEXT is either METHOD_DEF or METHOD_REF,
2459 saying whether we are trying to define a method or call one.
2460 SUPERFLAG says this is for a send to super;
2461 this makes a difference for the NeXT calling sequence
2462 in which the lookup and the method call are done together. */
2465 get_arg_type_list (meth, context, superflag)
2472 #ifdef NEXT_OBJC_RUNTIME
2476 arglist = build_tree_list (NULLT, super_type);
2481 if (context == METHOD_DEF)
2482 arglist = build_tree_list (NULLT, TREE_TYPE (self_decl));
2484 arglist = build_tree_list (NULLT, id_type);
2487 /* selector type - will eventually change to `int' */
2488 chainon (arglist, build_tree_list (NULLT, selector_type));
2490 /* build a list of argument types */
2491 for (akey = METHOD_SEL_ARGS (meth); akey; akey = TREE_CHAIN (akey))
2493 tree arg_decl = groktypename_in_parm_context (TREE_TYPE (akey));
2494 chainon (arglist, build_tree_list (NULLT, TREE_TYPE (arg_decl)));
2497 if (METHOD_ADD_ARGS (meth) == (tree)1)
2499 * we have a `, ...' immediately following the selector,
2500 * finalize the arglist...simulate get_parm_info (0)
2503 else if (METHOD_ADD_ARGS (meth))
2505 /* we have a variable length selector */
2506 tree add_arg_list = TREE_CHAIN (METHOD_ADD_ARGS (meth));
2507 chainon (arglist, add_arg_list);
2509 else /* finalize the arglist...simulate get_parm_info (1) */
2510 chainon (arglist, build_tree_list (NULLT, void_type_node));
2516 check_duplicates (hsh)
2527 /* we have two methods with the same name and different types */
2531 type = (TREE_CODE (meth) == INSTANCE_METHOD_DECL) ? '-' : '+';
2533 warning ("multiple declarations for method `%s'",
2534 IDENTIFIER_POINTER (METHOD_SEL_NAME (meth)));
2536 warn_with_method ("using", type, meth);
2537 for (loop = hsh->list; loop; loop = loop->next)
2538 warn_with_method ("also found", type, loop->value);
2545 receiver_is_class_object (receiver)
2548 /* the receiver is a function call that returns an id...
2549 * ...check if it is a call to objc_getClass, if so, give it
2550 * special treatment.
2552 tree exp = TREE_OPERAND (receiver, 0);
2554 if (exp != 0 && (TREE_CODE (exp) == ADDR_EXPR))
2556 exp = TREE_OPERAND (exp, 0);
2558 && TREE_CODE (exp) == FUNCTION_DECL && exp == objc_getClass_decl)
2560 /* we have a call to objc_getClass! */
2561 tree arg = TREE_OPERAND (receiver, 1);
2564 && TREE_CODE (arg) == TREE_LIST
2565 && (arg = TREE_VALUE (arg))
2566 && TREE_CODE (arg) == NOP_EXPR
2567 && (arg = TREE_OPERAND (arg, 0))
2568 && TREE_CODE (arg) == ADDR_EXPR
2569 && (arg = TREE_OPERAND (arg, 0))
2570 && TREE_CODE (arg) == STRING_CST)
2571 /* finally, we have the class name */
2572 return get_identifier (TREE_STRING_POINTER (arg));
2578 /* If we are currently building a message expr, this holds
2579 the identifier of the selector of the message. This is
2580 used when printing warnings about argument mismatches. */
2582 static tree building_objc_message_expr = 0;
2585 maybe_building_objc_message_expr ()
2587 return building_objc_message_expr;
2590 /* Construct an expression for sending a message.
2591 MESS has the object to send to in TREE_PURPOSE
2592 and the argument list (including selector) in TREE_VALUE. */
2595 build_message_expr (mess)
2598 tree receiver = TREE_PURPOSE (mess);
2599 tree selector, self_object;
2600 tree rtype, sel_name;
2601 tree args = TREE_VALUE (mess);
2602 tree method_params = NULLT;
2603 tree method_prototype = NULLT;
2604 int selTransTbl_index;
2606 int statically_typed = 0, statically_allocated = 0;
2607 tree class_ident = 0;
2609 /* 1 if this is sending to the superclass. */
2612 if (!doing_objc_thang)
2613 fatal ("Objective-C text in C source file");
2615 if (TREE_CODE (receiver) == ERROR_MARK)
2616 return error_mark_node;
2618 /* determine receiver type */
2619 rtype = TREE_TYPE (receiver);
2620 super = (TREE_TYPE (receiver) == super_type);
2624 if (TREE_STATIC_TEMPLATE (rtype))
2625 statically_allocated = 1;
2626 else if (TREE_CODE (rtype) == POINTER_TYPE
2627 && TREE_STATIC_TEMPLATE (TREE_TYPE (rtype)))
2628 statically_typed = 1;
2630 else if (TREE_CODE (receiver) == CALL_EXPR && rtype == id_type
2631 && (class_ident = receiver_is_class_object (receiver)))
2633 else if (TYPE_MAIN_VARIANT (rtype) != TYPE_MAIN_VARIANT (id_type)
2634 && TYPE_MAIN_VARIANT (rtype) != TYPE_MAIN_VARIANT (class_type))
2636 bzero (errbuf, BUFSIZE);
2637 warning ("invalid receiver type `%s'", gen_declaration (rtype, errbuf));
2639 if (statically_allocated)
2640 receiver = build_unary_op (ADDR_EXPR, receiver, 0);
2642 self_object = receiver;
2645 /* If sending to `super', use current self as the object. */
2646 self_object = self_decl;
2648 /* Obtain the full selector name. */
2650 if (TREE_CODE (args) == IDENTIFIER_NODE)
2651 /* a unary selector */
2653 else if (TREE_CODE (args) == TREE_LIST)
2654 sel_name = build_keyword_selector (args);
2656 selTransTbl_index = add_selector_reference (sel_name);
2658 /* Build the parameters list for looking up the method.
2659 These are the object itself and the selector. */
2661 #ifndef OBJC_SELECTORS_WITHOUT_LABELS
2662 selector = build_selector_reference (selTransTbl_index);
2664 selector = build_array_ref (_OBJC_SELECTOR_REFERENCES_decl,
2665 build_int_2 (selTransTbl_index, 0));
2668 /* Build the parameter list to give to the method. */
2670 method_params = NULLT;
2671 if (TREE_CODE (args) == TREE_LIST)
2673 tree chain = args, prev = NULLT;
2675 /* We have a keyword selector--check for comma expressions. */
2678 tree element = TREE_VALUE (chain);
2680 /* We have a comma expression, must collapse... */
2681 if (TREE_CODE (element) == TREE_LIST)
2684 TREE_CHAIN (prev) = element;
2689 chain = TREE_CHAIN (chain);
2691 method_params = args;
2694 /* Determine operation return type. */
2696 if (TYPE_MAIN_VARIANT (rtype) == TYPE_MAIN_VARIANT (super_type))
2700 if (CLASS_SUPER_NAME (implementation_template))
2702 iface = lookup_interface (CLASS_SUPER_NAME (implementation_template));
2704 if (TREE_CODE (method_context) == INSTANCE_METHOD_DECL)
2705 method_prototype = lookup_instance_method_static (iface, sel_name);
2707 method_prototype = lookup_class_method_static (iface, sel_name);
2709 if (iface && !method_prototype)
2710 warning ("`%s' does not respond to `%s'",
2711 IDENTIFIER_POINTER (CLASS_SUPER_NAME (implementation_template)),
2712 IDENTIFIER_POINTER (sel_name));
2716 error ("no super class declared in interface for `%s'",
2717 IDENTIFIER_POINTER (CLASS_NAME (implementation_template)));
2718 return error_mark_node;
2722 else if (statically_allocated)
2724 tree iface = lookup_interface (TYPE_NAME (rtype));
2726 if (iface && !(method_prototype = lookup_instance_method_static (iface, sel_name)))
2727 warning ("`%s' does not respond to `%s'",
2728 IDENTIFIER_POINTER (TYPE_NAME (rtype)),
2729 IDENTIFIER_POINTER (sel_name));
2731 else if (statically_typed)
2733 tree ctype = TREE_TYPE (rtype);
2735 /* `self' is now statically_typed...all methods should be visible
2736 * within the context of the implementation...
2738 if (implementation_context
2739 && CLASS_NAME (implementation_context) == TYPE_NAME (ctype))
2741 method_prototype = lookup_instance_method_static (implementation_template, sel_name);
2743 if (!method_prototype && implementation_template != implementation_context)
2744 /* the method is not published in the interface...check locally */
2745 method_prototype = lookup_method (CLASS_NST_METHODS (implementation_context),
2752 if (iface = lookup_interface (TYPE_NAME (ctype)))
2753 method_prototype = lookup_instance_method_static (iface, sel_name);
2756 if (!method_prototype)
2757 warning ("`%s' does not respond to `%s'",
2758 IDENTIFIER_POINTER (TYPE_NAME (ctype)),
2759 IDENTIFIER_POINTER (sel_name));
2761 else if (class_ident)
2763 if (implementation_context
2764 && CLASS_NAME (implementation_context) == class_ident)
2767 = lookup_class_method_static (implementation_template, sel_name);
2769 if (!method_prototype
2770 && implementation_template != implementation_context)
2771 /* the method is not published in the interface...check locally */
2773 = lookup_method (CLASS_CLS_METHODS (implementation_context),
2780 if (iface = lookup_interface (class_ident))
2781 method_prototype = lookup_class_method_static (iface, sel_name);
2784 if (!method_prototype)
2786 warning ("cannot find class (factory) method.");
2787 warning ("return type for `%s' defaults to id",
2788 IDENTIFIER_POINTER (sel_name));
2795 /* we think we have an instance...loophole: extern id Object; */
2796 hsh = hash_lookup (nst_method_hash_list, sel_name);
2798 /* for various loopholes...like sending messages to self in a
2799 factory context... */
2800 hsh = hash_lookup (cls_method_hash_list, sel_name);
2802 method_prototype = check_duplicates (hsh);
2803 if (!method_prototype)
2805 warning ("cannot find method.");
2806 warning ("return type for `%s' defaults to id",
2807 IDENTIFIER_POINTER (sel_name));
2811 /* Save the selector name for printing error messages. */
2812 building_objc_message_expr = sel_name;
2814 retval = build_objc_method_call (super, method_prototype,
2815 receiver, self_object,
2816 selector, method_params);
2818 building_objc_message_expr = 0;
2823 /* Build a tree expression to send OBJECT the operation SELECTOR,
2824 looking up the method on object LOOKUP_OBJECT (often same as OBJECT),
2825 assuming the method has prototype METHOD_PROTOTYPE.
2826 (That is an INSTANCE_METHOD_DECL or CLASS_METHOD_DECL.)
2827 Use METHOD_PARAMS as list of args to pass to the method.
2828 If SUPER_FLAG is nonzero, we look up the superclass's method. */
2831 build_objc_method_call (super_flag, method_prototype, lookup_object, object,
2832 selector, method_params)
2834 tree method_prototype, lookup_object, object, selector, method_params;
2836 tree sender = (super_flag ? _msgSuper_decl : _msg_decl);
2838 #ifdef NEXT_OBJC_RUNTIME
2839 if (!method_prototype)
2841 method_params = tree_cons (NULLT, lookup_object,
2842 tree_cons (NULLT, selector, method_params));
2843 return build_function_call (sender, method_params);
2847 /* This is a real kludge, but it is used only for the Next.
2848 Clobber the data type of SENDER temporarily to accept
2849 all the arguments for this operation, and to return
2850 whatever this operation returns. */
2851 tree arglist = NULLT;
2854 /* Save the proper contents of SENDER's data type. */
2855 tree savarg = TYPE_ARG_TYPES (TREE_TYPE (sender));
2856 tree savret = TREE_TYPE (TREE_TYPE (sender));
2858 /* Install this method's argument types. */
2859 arglist = get_arg_type_list (method_prototype, METHOD_REF, super_flag);
2860 TYPE_ARG_TYPES (TREE_TYPE (sender)) = arglist;
2862 /* Install this method's return type. */
2863 TREE_TYPE (TREE_TYPE (sender))
2864 = groktypename (TREE_TYPE (method_prototype));
2866 /* Call SENDER with all the parameters.
2867 This will do type checking using the arg types for this method. */
2868 method_params = tree_cons (NULLT, lookup_object,
2869 tree_cons (NULLT, selector, method_params));
2870 retval = build_function_call (sender, method_params);
2872 /* Restore SENDER's return/argument types. */
2873 TYPE_ARG_TYPES (TREE_TYPE (sender)) = savarg;
2874 TREE_TYPE (TREE_TYPE (sender)) = savret;
2877 #else /* not NEXT_OBJC_RUNTIME */
2878 /* This is the portable way.
2879 First call the lookup function to get a pointer to the method,
2880 then cast the pointer, then call it with the method arguments. */
2883 /* Avoid trouble since we may evaluate each of these twice. */
2884 object = save_expr (object);
2885 selector = save_expr (selector);
2888 = build_function_call (sender,
2889 tree_cons (NULLT, lookup_object,
2890 tree_cons (NULLT, selector, NULLT)));
2892 /* If we have a method prototype, construct the data type this method needs,
2893 and cast what we got from SENDER into a pointer to that type. */
2894 if (method_prototype)
2896 tree arglist = get_arg_type_list (method_prototype, METHOD_REF, super_flag);
2897 tree valtype = groktypename (TREE_TYPE (method_prototype));
2898 tree fake_function_type = build_function_type (valtype, arglist);
2899 TREE_TYPE (method) = build_pointer_type (fake_function_type);
2904 = build_pointer_type (build_function_type (ptr_type_node, NULLT));
2906 /* Pass the object to the method. */
2907 return build_function_call (method,
2908 tree_cons (NULLT, object,
2909 tree_cons (NULLT, selector,
2911 #endif /* not NEXT_OBJC_RUNTIME */
2915 build_selector_expr (selnamelist)
2919 int selTransTbl_index;
2921 if (!doing_objc_thang)
2922 fatal ("Objective-C text in C source file");
2924 /* obtain the full selector name */
2925 if (TREE_CODE (selnamelist) == IDENTIFIER_NODE)
2926 /* a unary selector */
2927 selname = selnamelist;
2928 else if (TREE_CODE (selnamelist) == TREE_LIST)
2929 selname = build_keyword_selector (selnamelist);
2931 selTransTbl_index = add_selector_reference (selname);
2933 #ifndef OBJC_SELECTORS_WITHOUT_LABELS
2934 return build_selector_reference (selTransTbl_index);
2936 /* synthesize a reference into the selector translation table */
2937 return build_array_ref (_OBJC_SELECTOR_REFERENCES_decl,
2938 build_int_2 (selTransTbl_index, 0));
2943 build_encode_expr (type)
2949 if (!doing_objc_thang)
2950 fatal ("Objective-C text in C source file");
2952 encode_type (type, OBJC_ENCODE_INLINE_DEFS);
2953 string = obstack_finish (&util_obstack);
2955 /* synthesize a string that represents the encoded struct/union */
2956 result = my_build_string (strlen (string) + 1, string);
2957 obstack_free (&util_obstack, util_firstobj);
2962 build_ivar_reference (id)
2965 if (TREE_CODE (method_context) == CLASS_METHOD_DECL)
2966 TREE_TYPE (self_decl) = instance_type; /* cast */
2968 return build_component_ref (build_indirect_ref (self_decl, "->"), id);
2971 #define HASH_ALLOC_LIST_SIZE 170
2972 #define ATTR_ALLOC_LIST_SIZE 170
2973 #define SIZEHASHTABLE 257
2974 #define HASHFUNCTION(key) ((int)key >> 2) /* divide by 4 */
2979 nst_method_hash_list = (hash *)xmalloc (SIZEHASHTABLE * sizeof (hash));
2980 cls_method_hash_list = (hash *)xmalloc (SIZEHASHTABLE * sizeof (hash));
2982 if (!nst_method_hash_list || !cls_method_hash_list)
2983 perror ("unable to allocate space in objc-tree.c");
2988 for (i = 0; i < SIZEHASHTABLE; i++)
2990 nst_method_hash_list[i] = 0;
2991 cls_method_hash_list[i] = 0;
2997 hash_enter (hashlist, method)
3001 static hash hash_alloc_list = 0;
3002 static int hash_alloc_index = 0;
3004 int slot = HASHFUNCTION (METHOD_SEL_NAME (method)) % SIZEHASHTABLE;
3006 if (!hash_alloc_list || hash_alloc_index >= HASH_ALLOC_LIST_SIZE)
3008 hash_alloc_index = 0;
3009 hash_alloc_list = (hash)xmalloc (sizeof (struct hashedEntry) *
3010 HASH_ALLOC_LIST_SIZE);
3011 if (!hash_alloc_list)
3012 perror ("unable to allocate in objc-tree.c");
3014 obj = &hash_alloc_list[hash_alloc_index++];
3016 obj->next = hashlist[slot];
3019 hashlist[slot] = obj; /* append to front */
3023 hash_lookup (hashlist, sel_name)
3029 target = hashlist[HASHFUNCTION (sel_name) % SIZEHASHTABLE];
3033 if (sel_name == METHOD_SEL_NAME (target->key))
3036 target = target->next;
3042 hash_add_attr (entry, value)
3046 static attr attr_alloc_list = 0;
3047 static int attr_alloc_index = 0;
3050 if (!attr_alloc_list || attr_alloc_index >= ATTR_ALLOC_LIST_SIZE)
3052 attr_alloc_index = 0;
3053 attr_alloc_list = (attr)xmalloc (sizeof (struct hashedAttribute) *
3054 ATTR_ALLOC_LIST_SIZE);
3055 if (!attr_alloc_list)
3056 perror ("unable to allocate in objc-tree.c");
3058 obj = &attr_alloc_list[attr_alloc_index++];
3059 obj->next = entry->list;
3062 entry->list = obj; /* append to front */
3066 lookup_method (mchain, method)
3072 if (TREE_CODE (method) == IDENTIFIER_NODE)
3075 key = METHOD_SEL_NAME (method);
3079 if (METHOD_SEL_NAME (mchain) == key)
3081 mchain = TREE_CHAIN (mchain);
3087 lookup_instance_method_static (interface, ident)
3091 tree inter = interface;
3092 tree chain = CLASS_NST_METHODS (inter);
3097 if (meth = lookup_method (chain, ident))
3100 if (CLASS_CATEGORY_LIST (inter))
3102 tree category = CLASS_CATEGORY_LIST (inter);
3103 chain = CLASS_NST_METHODS (category);
3107 if (meth = lookup_method (chain, ident))
3110 if (category = CLASS_CATEGORY_LIST (category))
3111 chain = CLASS_NST_METHODS (category);
3116 if (inter = lookup_interface (CLASS_SUPER_NAME (inter)))
3117 chain = CLASS_NST_METHODS (inter);
3125 lookup_class_method_static (interface, ident)
3129 tree inter = interface;
3130 tree chain = CLASS_CLS_METHODS (inter);
3135 if (meth = lookup_method (chain, ident))
3138 if (CLASS_CATEGORY_LIST (inter))
3140 tree category = CLASS_CATEGORY_LIST (inter);
3141 chain = CLASS_CLS_METHODS (category);
3145 if (meth = lookup_method (chain, ident))
3148 if (category = CLASS_CATEGORY_LIST (category))
3149 chain = CLASS_CLS_METHODS (category);
3154 if (inter = lookup_interface (CLASS_SUPER_NAME (inter)))
3155 chain = CLASS_CLS_METHODS (inter);
3163 add_class_method (class, method)
3170 if (!(mth = lookup_method (CLASS_CLS_METHODS (class), method)))
3172 /* put method on list in reverse order */
3173 TREE_CHAIN (method) = CLASS_CLS_METHODS (class);
3174 CLASS_CLS_METHODS (class) = method;
3178 if (TREE_CODE (class) == IMPLEMENTATION_TYPE)
3179 error ("duplicate definition of class method `%s'.",
3180 IDENTIFIER_POINTER (METHOD_SEL_NAME (mth)));
3183 /* check types, if different complain */
3184 if (!comp_proto_with_proto (method, mth))
3185 error ("duplicate declaration of class method `%s'.",
3186 IDENTIFIER_POINTER (METHOD_SEL_NAME (mth)));
3190 if (!(hsh = hash_lookup (cls_method_hash_list, METHOD_SEL_NAME (method))))
3192 /* install on a global chain */
3193 hash_enter (cls_method_hash_list, method);
3197 /* check types, if different add to a list */
3198 if (!comp_proto_with_proto (method, hsh->key))
3199 hash_add_attr (hsh, method);
3205 add_instance_method (class, method)
3212 if (!(mth = lookup_method (CLASS_NST_METHODS (class), method)))
3214 /* put method on list in reverse order */
3215 TREE_CHAIN (method) = CLASS_NST_METHODS (class);
3216 CLASS_NST_METHODS (class) = method;
3220 if (TREE_CODE (class) == IMPLEMENTATION_TYPE)
3221 error ("duplicate definition of instance method `%s'.",
3222 IDENTIFIER_POINTER (METHOD_SEL_NAME (mth)));
3225 /* check types, if different complain */
3226 if (!comp_proto_with_proto (method, mth))
3227 error ("duplicate declaration of instance method `%s'.",
3228 IDENTIFIER_POINTER (METHOD_SEL_NAME (mth)));
3232 if (!(hsh = hash_lookup (nst_method_hash_list, METHOD_SEL_NAME (method))))
3234 /* install on a global chain */
3235 hash_enter (nst_method_hash_list, method);
3239 /* check types, if different add to a list */
3240 if (!comp_proto_with_proto (method, hsh->key))
3241 hash_add_attr (hsh, method);
3250 /* put interfaces on list in reverse order */
3251 TREE_CHAIN (class) = interface_chain;
3252 interface_chain = class;
3253 return interface_chain;
3257 add_category (class, category)
3261 /* put categories on list in reverse order */
3262 CLASS_CATEGORY_LIST (category) = CLASS_CATEGORY_LIST (class);
3263 CLASS_CATEGORY_LIST (class) = category;
3266 /* called after parsing each instance variable declaration. Necessary to
3267 * preserve typedefs and implement public/private...
3270 add_instance_variable (class, public, declarator, declspecs, width)
3277 tree field_decl, raw_decl;
3279 raw_decl = build_tree_list (declspecs /*purpose*/, declarator/*value*/);
3281 if (CLASS_RAW_IVARS (class))
3282 chainon (CLASS_RAW_IVARS (class), raw_decl);
3284 CLASS_RAW_IVARS (class) = raw_decl;
3286 field_decl = grokfield (input_filename, lineno,
3287 declarator, declspecs, width);
3289 /* overload the public attribute, it is not used for FIELD_DECL's */
3291 TREE_PUBLIC (field_decl) = 1;
3293 if (CLASS_IVARS (class))
3294 chainon (CLASS_IVARS (class), field_decl);
3296 CLASS_IVARS (class) = field_decl;
3302 is_ivar (decl_chain, ident)
3306 for ( ; decl_chain; decl_chain = TREE_CHAIN (decl_chain))
3307 if (DECL_NAME (decl_chain) == ident)
3312 /* we have an instance variable reference, check to see if it is public...*/
3315 is_public (expr, identifier)
3319 tree basetype = TREE_TYPE (expr);
3320 enum tree_code code = TREE_CODE (basetype);
3323 if (code == RECORD_TYPE)
3325 if (TREE_STATIC_TEMPLATE (basetype))
3327 if (decl = is_ivar (TYPE_FIELDS (basetype), identifier))
3329 /* important difference between the Stepstone translator:
3331 all instance variables should be public within the context
3332 of the implementation...
3334 if (implementation_context)
3336 if ((TREE_CODE (implementation_context) == IMPLEMENTATION_TYPE
3337 && CLASS_NAME (implementation_context) == TYPE_NAME (basetype))
3338 || (TREE_CODE (implementation_context) == CATEGORY_TYPE
3339 && CLASS_NAME (implementation_context) == TYPE_NAME (basetype)))
3343 if (TREE_PUBLIC (decl))
3346 error ("instance variable `%s' is declared private",
3347 IDENTIFIER_POINTER (identifier));
3351 else if (implementation_context && (basetype == objc_object_reference))
3353 TREE_TYPE (expr) = _PRIVATE_record;
3356 warning ("static access to object of type `id'");
3357 warning ("please change to type `%s *'",
3358 IDENTIFIER_POINTER (CLASS_NAME (implementation_context)));
3365 /* implement @defs (<classname>) within struct bodies. */
3368 get_class_ivars (interface)
3371 if (!doing_objc_thang)
3372 fatal ("Objective-C text in C source file");
3374 return build_ivar_chain (interface);
3378 get_class_reference (interface)
3383 add_class_reference (CLASS_NAME (interface));
3385 params = build_tree_list (NULLT,
3386 my_build_string (IDENTIFIER_LENGTH (CLASS_NAME (interface)) + 1,
3387 IDENTIFIER_POINTER (CLASS_NAME (interface))));
3389 return build_function_call (objc_getClass_decl, params);
3392 /* make sure all entries in "chain" are also in "list" */
3395 check_methods (chain, list, mtype)
3404 if (!lookup_method (list, chain))
3408 if (TREE_CODE (implementation_context) == IMPLEMENTATION_TYPE)
3409 warning ("incomplete implementation of class `%s'",
3410 IDENTIFIER_POINTER (CLASS_NAME (implementation_context)));
3411 else if (TREE_CODE (implementation_context) == CATEGORY_TYPE)
3412 warning ("incomplete implementation of category `%s'",
3413 IDENTIFIER_POINTER (CLASS_SUPER_NAME (implementation_context)));
3416 warning ("method definition for `%c%s' not found",
3417 mtype, IDENTIFIER_POINTER (METHOD_SEL_NAME (chain)));
3419 chain = TREE_CHAIN (chain);
3423 /* Make sure that the class CLASS_NAME is defined
3424 CODE says which kind of thing CLASS_NAME ought to be.
3425 It can be INTERFACE_TYPE, IMPLEMENTATION_TYPE, PROTOCOL_TYPE
3428 If CODE is INTERFACE_TYPE, we also do a push_obstacks_nochange
3429 whose matching pop is in continue_class. */
3432 start_class (code, class_name, super_name)
3433 enum tree_code code;
3439 if (code == INTERFACE_TYPE)
3441 push_obstacks_nochange ();
3442 end_temporary_allocation ();
3445 if (!doing_objc_thang)
3446 fatal ("Objective-C text in C source file");
3448 class = make_node (code);
3450 CLASS_NAME (class) = class_name;
3451 CLASS_SUPER_NAME (class) = super_name;
3452 CLASS_CLS_METHODS (class) = NULL_TREE;
3454 if (code == IMPLEMENTATION_TYPE)
3456 /* pre-build the following entities - for speed/convenience. */
3458 self_id = get_identifier ("self");
3460 _cmd_id = get_identifier ("_cmd");
3462 if (!objc_super_template)
3463 objc_super_template = build_super_template ();
3465 method_slot = 0; /* reset for multiple classes per file */
3467 implementation_context = class;
3469 /* lookup the interface for this implementation. */
3471 if (!(implementation_template = lookup_interface (class_name)))
3473 warning ("Cannot find interface declaration for `%s'",
3474 IDENTIFIER_POINTER (class_name));
3475 add_class (implementation_template = implementation_context);
3478 /* if a super class has been specified in the implementation,
3479 insure it conforms to the one specified in the interface */
3482 && (super_name != CLASS_SUPER_NAME (implementation_template)))
3484 error ("conflicting super class name `%s'",
3485 IDENTIFIER_POINTER (super_name));
3486 error ("previous declaration of `%s'",
3487 IDENTIFIER_POINTER (CLASS_SUPER_NAME (implementation_template)));
3490 else if (code == INTERFACE_TYPE)
3492 if (lookup_interface (class_name))
3493 warning ("duplicate interface declaration for class `%s'",
3494 IDENTIFIER_POINTER (class_name));
3498 else if (code == PROTOCOL_TYPE)
3500 tree class_category_is_assoc_with;
3502 /* for a category, class_name is really the name of the class that
3503 the following set of methods will be associated with...we must
3504 find the interface so that can derive the objects template */
3506 if (!(class_category_is_assoc_with = lookup_interface (class_name)))
3508 error ("Cannot find interface declaration for `%s'",
3509 IDENTIFIER_POINTER (class_name));
3513 add_category (class_category_is_assoc_with, class);
3515 else if (code == CATEGORY_TYPE)
3517 /* pre-build the following entities - for speed/convenience. */
3519 self_id = get_identifier ("self");
3521 _cmd_id = get_identifier ("_cmd");
3523 if (!objc_super_template)
3524 objc_super_template = build_super_template ();
3526 method_slot = 0; /* reset for multiple classes per file */
3528 implementation_context = class;
3530 /* for a category, class_name is really the name of the class that
3531 the following set of methods will be associated with...we must
3532 find the interface so that can derive the objects template */
3534 if (!(implementation_template = lookup_interface (class_name)))
3536 error ("Cannot find interface declaration for `%s'",
3537 IDENTIFIER_POINTER (class_name));
3545 continue_class (class)
3548 if (TREE_CODE (class) == IMPLEMENTATION_TYPE
3549 || TREE_CODE (class) == CATEGORY_TYPE)
3551 struct imp_entry *impEntry;
3554 /* check consistency of the instance variables. */
3556 if (CLASS_IVARS (class))
3557 check_ivars (implementation_template, class);
3559 /* code generation */
3561 ivar_context = build_private_template (implementation_template);
3563 if (!objc_class_template)
3564 build_class_template ();
3566 if (!(impEntry = (struct imp_entry *)xmalloc (sizeof (struct imp_entry))))
3567 perror ("unable to allocate in objc-tree.c");
3569 impEntry->next = imp_list;
3570 impEntry->imp_context = class;
3571 impEntry->imp_template = implementation_template;
3573 synth_forward_declarations ();
3574 impEntry->class_decl = _OBJC_CLASS_decl;
3575 impEntry->meta_decl = _OBJC_METACLASS_decl;
3577 /* append to front and increment count */
3578 imp_list = impEntry;
3579 if (TREE_CODE (class) == IMPLEMENTATION_TYPE)
3584 return ivar_context;
3586 else if (TREE_CODE (class) == INTERFACE_TYPE)
3588 tree record = xref_tag (RECORD_TYPE, CLASS_NAME (class));
3590 if (!TYPE_FIELDS (record))
3592 finish_struct (record, build_ivar_chain (class));
3593 CLASS_STATIC_TEMPLATE (class) = record;
3595 /* mark this record as a class template - for static typing */
3596 TREE_STATIC_TEMPLATE (record) = 1;
3601 return error_mark_node;
3605 * this is called once we see the "@end" in an interface/implementation.
3608 finish_class (class)
3611 if (TREE_CODE (class) == IMPLEMENTATION_TYPE)
3613 /* all code generation is done in finish_objc */
3615 if (implementation_template != implementation_context)
3617 /* ensure that all method listed in the interface contain bodies! */
3618 check_methods (CLASS_CLS_METHODS (implementation_template),
3619 CLASS_CLS_METHODS (implementation_context), '+');
3620 check_methods (CLASS_NST_METHODS (implementation_template),
3621 CLASS_NST_METHODS (implementation_context), '-');
3624 else if (TREE_CODE (class) == CATEGORY_TYPE)
3626 tree category = CLASS_CATEGORY_LIST (implementation_template);
3628 /* find the category interface from the class it is associated with */
3631 if (CLASS_SUPER_NAME (class) == CLASS_SUPER_NAME (category))
3633 category = CLASS_CATEGORY_LIST (category);
3638 /* ensure that all method listed in the interface contain bodies! */
3639 check_methods (CLASS_CLS_METHODS (category),
3640 CLASS_CLS_METHODS (implementation_context), '+');
3641 check_methods (CLASS_NST_METHODS (category),
3642 CLASS_NST_METHODS (implementation_context), '-');
3645 else if (TREE_CODE (class) == INTERFACE_TYPE)
3648 char *string = (char *) alloca (strlen (IDENTIFIER_POINTER (CLASS_NAME (class))) + 3);
3650 /* extern struct objc_object *_<my_name>; */
3652 sprintf (string, "_%s", IDENTIFIER_POINTER (CLASS_NAME (class)));
3654 decl_specs = build_tree_list (NULLT, ridpointers[(int) RID_EXTERN]);
3655 decl_specs = tree_cons (NULLT, objc_object_reference, decl_specs);
3656 define_decl (build1 (INDIRECT_REF, NULLT, get_identifier (string)),
3661 /* "Encode" a data type into a string, whichg rows in util_obstack.
3662 ??? What is the FORMAT? Someone please document this! */
3664 /* Encode a pointer type. */
3667 encode_pointer (type, format)
3671 tree pointer_to = TREE_TYPE (type);
3673 if (TREE_CODE (pointer_to) == RECORD_TYPE)
3675 if (TYPE_NAME (pointer_to)
3676 && TREE_CODE (TYPE_NAME (pointer_to)) == IDENTIFIER_NODE)
3678 char *name = IDENTIFIER_POINTER (TYPE_NAME (pointer_to));
3680 if ((strcmp (name, TAG_OBJECT) == 0) /* '@' */
3681 || TREE_STATIC_TEMPLATE (pointer_to))
3683 obstack_1grow (&util_obstack, '@');
3686 else if (strcmp (name, TAG_CLASS) == 0) /* '#' */
3688 obstack_1grow (&util_obstack, '#');
3691 #ifndef OBJC_INT_SELECTORS
3692 else if (strcmp (name, TAG_SELECTOR) == 0) /* ':' */
3694 obstack_1grow (&util_obstack, ':');
3697 #endif /* OBJC_INT_SELECTORS */
3700 else if (TREE_CODE (pointer_to) == INTEGER_TYPE
3701 && TYPE_MODE (pointer_to) == QImode)
3703 obstack_1grow (&util_obstack, '*');
3707 /* we have a type that does not get special treatment... */
3709 /* NeXT extension */
3710 obstack_1grow (&util_obstack, '^');
3711 encode_type (pointer_to, format);
3715 encode_array (type, format)
3719 tree anIntCst = TYPE_SIZE (type);
3720 tree array_of = TREE_TYPE (type);
3723 /* An incomplete array is treated like a pointer. */
3724 if (anIntCst == NULL)
3726 /* split for obvious reasons. North-Keys 30 Mar 1991 */
3727 encode_pointer (type, format);
3731 sprintf (buffer, "[%d",
3732 TREE_INT_CST_LOW (anIntCst)
3733 / TREE_INT_CST_LOW (TYPE_SIZE (array_of)));
3734 obstack_grow (&util_obstack, buffer, strlen (buffer));
3735 encode_type (array_of, format);
3736 obstack_1grow (&util_obstack, ']');
3741 encode_aggregate (type, format)
3745 enum tree_code code = TREE_CODE (type);
3751 if (*obstack_next_free (&util_obstack) == '^'
3752 || format != OBJC_ENCODE_INLINE_DEFS)
3754 /* we have a reference - this is a NeXT extension--
3755 or we don't want the details. */
3756 if (TYPE_NAME (type)
3757 && (TREE_CODE (TYPE_NAME (type)) == IDENTIFIER_NODE))
3759 obstack_1grow (&util_obstack, '{');
3760 obstack_grow (&util_obstack,
3761 IDENTIFIER_POINTER (TYPE_NAME (type)),
3762 strlen (IDENTIFIER_POINTER (TYPE_NAME (type))));
3763 obstack_1grow (&util_obstack, '}');
3765 else /* we have an untagged structure or a typedef */
3766 obstack_grow (&util_obstack, "{?}", 3);
3770 tree fields = TYPE_FIELDS (type);
3771 obstack_1grow (&util_obstack, '{');
3772 for ( ; fields; fields = TREE_CHAIN (fields))
3773 encode_field_decl (fields, format);
3774 obstack_1grow (&util_obstack, '}');
3780 if (*obstack_next_free (&util_obstack) == '^'
3781 || format != OBJC_ENCODE_INLINE_DEFS)
3783 /* we have a reference - this is a NeXT extension--
3784 or we don't want the details. */
3785 if (TYPE_NAME (type)
3786 && (TREE_CODE (TYPE_NAME (type)) == IDENTIFIER_NODE))
3788 obstack_1grow (&util_obstack, '<');
3789 obstack_grow (&util_obstack,
3790 IDENTIFIER_POINTER (TYPE_NAME (type)),
3791 strlen (IDENTIFIER_POINTER (TYPE_NAME (type))));
3792 obstack_1grow (&util_obstack, '>');
3794 else /* we have an untagged structure or a typedef */
3795 obstack_grow (&util_obstack, "<?>", 3);
3799 tree fields = TYPE_FIELDS (type);
3800 obstack_1grow (&util_obstack, '<');
3801 for ( ; fields; fields = TREE_CHAIN (fields))
3802 encode_field_decl (fields, format);
3803 obstack_1grow (&util_obstack, '>');
3809 obstack_1grow (&util_obstack, 'i');
3815 * support bitfields, the current version of Objective-C does not support
3816 * them. the string will consist of one or more "b:n"'s where n is an
3817 * integer describing the width of the bitfield. Currently, classes in
3818 * the kit implement a method "-(char *)describeBitfieldStruct:" that
3819 * simulates this...if they do not implement this method, the archiver
3820 * assumes the bitfield is 16 bits wide (padded if necessary) and packed
3821 * according to the GNU compiler. After looking at the "kit", it appears
3822 * that all classes currently rely on this default behavior, rather than
3823 * hand generating this string (which is tedious).
3826 encode_bitfield (width, format)
3831 sprintf (buffer, "b%d", width);
3832 obstack_grow (&util_obstack, buffer, strlen (buffer));
3838 * OBJC_ENCODE_INLINE_DEFS or OBJC_ENCODE_DONT_INLINE_DEFS
3841 encode_type (type, format)
3845 enum tree_code code = TREE_CODE (type);
3847 if (code == INTEGER_TYPE)
3849 if (TREE_INT_CST_LOW (TYPE_MIN_VALUE (type)) == 0)
3851 /* unsigned integer types */
3853 if (TYPE_MODE (type) == QImode) /* 'C' */
3854 obstack_1grow (&util_obstack, 'C');
3855 else if (TYPE_MODE (type) == HImode) /* 'S' */
3856 obstack_1grow (&util_obstack, 'S');
3857 else if (TYPE_MODE (type) == SImode)
3859 if (type == long_unsigned_type_node)
3860 obstack_1grow (&util_obstack, 'L'); /* 'L' */
3862 obstack_1grow (&util_obstack, 'I'); /* 'I' */
3865 else /* signed integer types */
3867 if (TYPE_MODE (type) == QImode) /* 'c' */
3868 obstack_1grow (&util_obstack, 'c');
3869 else if (TYPE_MODE (type) == HImode) /* 's' */
3870 obstack_1grow (&util_obstack, 's');
3871 else if (TYPE_MODE (type) == SImode) /* 'i' */
3873 if (type == long_integer_type_node)
3874 obstack_1grow (&util_obstack, 'l'); /* 'l' */
3876 obstack_1grow (&util_obstack, 'i'); /* 'i' */
3880 else if (code == REAL_TYPE)
3882 /* floating point types */
3884 if (TYPE_MODE (type) == SFmode) /* 'f' */
3885 obstack_1grow (&util_obstack, 'f');
3886 else if (TYPE_MODE (type) == DFmode
3887 || TYPE_MODE (type) == TFmode) /* 'd' */
3888 obstack_1grow (&util_obstack, 'd');
3891 else if (code == VOID_TYPE) /* 'v' */
3892 obstack_1grow (&util_obstack, 'v');
3894 else if (code == ARRAY_TYPE)
3895 encode_array (type, format);
3897 else if (code == POINTER_TYPE)
3898 encode_pointer (type, format);
3900 else if (code == RECORD_TYPE || code == UNION_TYPE || code == ENUMERAL_TYPE)
3901 encode_aggregate (type, format);
3903 else if (code == FUNCTION_TYPE) /* '?' */
3904 obstack_1grow (&util_obstack, '?');
3908 encode_field_decl (field_decl, format)
3912 if (DECL_BIT_FIELD (field_decl))
3913 encode_bitfield (DECL_FIELD_SIZE (field_decl), format);
3915 encode_type (TREE_TYPE (field_decl), format);
3919 expr_last (complex_expr)
3925 while (next = TREE_OPERAND (complex_expr, 0))
3926 complex_expr = next;
3927 return complex_expr;
3930 /* The selector of the current method,
3931 or NULL if we aren't compiling a method. */
3934 maybe_objc_method_name (decl)
3938 return METHOD_SEL_NAME (method_context);
3944 * Transform a method definition into a function definition as follows:
3946 * - synthesize the first two arguments, "self" and "_cmd".
3950 start_method_def (method)
3955 /* required to implement _msgSuper () */
3956 method_context = method;
3957 _OBJC_SUPER_decl = NULLT;
3959 pushlevel (0); /* must be called BEFORE "start_function ()" */
3961 /* generate prototype declarations for arguments..."new-style" */
3963 if (TREE_CODE (method_context) == INSTANCE_METHOD_DECL)
3964 decl_specs = build_tree_list (NULLT, _PRIVATE_record);
3966 /* really a `struct objc_class *'...however we allow people to
3967 assign to self...which changes its type midstream.
3969 decl_specs = build_tree_list (NULLT, objc_object_reference);
3971 push_parm_decl (build_tree_list (decl_specs,
3972 build1 (INDIRECT_REF, NULLT, self_id)));
3974 #ifdef OBJC_INT_SELECTORS
3975 decl_specs = build_tree_list (NULLT, ridpointers[(int) RID_UNSIGNED]);
3976 decl_specs = tree_cons (NULLT, ridpointers[(int) RID_INT], decl_specs);
3977 push_parm_decl (build_tree_list (decl_specs, _cmd_id));
3978 #else /* not OBJC_INT_SELECTORS */
3979 decl_specs = build_tree_list (NULLT,
3980 xref_tag (RECORD_TYPE,
3981 get_identifier (TAG_SELECTOR)));
3982 push_parm_decl (build_tree_list (decl_specs,
3983 build1 (INDIRECT_REF, NULLT, _cmd_id)));
3984 #endif /* not OBJC_INT_SELECTORS */
3986 /* generate argument declarations if a keyword_decl */
3987 if (METHOD_SEL_ARGS (method))
3989 tree arglist = METHOD_SEL_ARGS (method);
3992 tree arg_spec = TREE_PURPOSE (TREE_TYPE (arglist));
3993 tree arg_decl = TREE_VALUE (TREE_TYPE (arglist));
3997 tree last_expr = expr_last (arg_decl);
3999 /* unite the abstract decl with its name */
4000 TREE_OPERAND (last_expr, 0) = KEYWORD_ARG_NAME (arglist);
4001 push_parm_decl (build_tree_list (arg_spec, arg_decl));
4002 /* unhook...restore the abstract declarator */
4003 TREE_OPERAND (last_expr, 0) = NULLT;
4006 push_parm_decl (build_tree_list (arg_spec, KEYWORD_ARG_NAME (arglist)));
4008 arglist = TREE_CHAIN (arglist);
4013 if (METHOD_ADD_ARGS (method) > (tree)1)
4015 /* we have a variable length selector - in "prototype" format */
4016 tree akey = TREE_PURPOSE (METHOD_ADD_ARGS (method));
4019 /* this must be done prior to calling pushdecl (). pushdecl () is
4020 * going to change our chain on us...
4022 tree nextkey = TREE_CHAIN (akey);
4030 error_with_method (message, mtype, method)
4036 fprintf (stderr, "%s:%d: ",
4037 DECL_SOURCE_FILE (method), DECL_SOURCE_LINE (method));
4038 bzero (errbuf, BUFSIZE);
4039 fprintf (stderr, "%s `%c%s'\n", message, mtype, gen_method_decl (method, errbuf));
4043 warn_with_method (message, mtype, method)
4049 fprintf (stderr, "%s:%d: ",
4050 DECL_SOURCE_FILE (method), DECL_SOURCE_LINE (method));
4051 bzero (errbuf, BUFSIZE);
4052 fprintf (stderr, "%s `%c%s'\n", message, mtype, gen_method_decl (method, errbuf));
4055 /* return 1 if `method' is consistent with `proto' */
4058 comp_method_with_proto (method, proto)
4061 static tree function_type = 0;
4063 /* create a function_type node once */
4066 struct obstack *ambient_obstack = current_obstack;
4068 current_obstack = &permanent_obstack;
4069 function_type = make_node (FUNCTION_TYPE);
4070 current_obstack = ambient_obstack;
4073 /* install argument types - normally set by "build_function_type ()". */
4074 TYPE_ARG_TYPES (function_type) = get_arg_type_list (proto, METHOD_DEF, 0);
4076 /* install return type */
4077 TREE_TYPE (function_type) = groktypename (TREE_TYPE (proto));
4079 return comptypes (TREE_TYPE (METHOD_DEFINITION (method)), function_type);
4082 /* return 1 if `proto1' is consistent with `proto2' */
4085 comp_proto_with_proto (proto1, proto2)
4086 tree proto1, proto2;
4088 static tree function_type1 = 0, function_type2 = 0;
4090 /* create a couple function_type node's once */
4091 if (!function_type1)
4093 struct obstack *ambient_obstack = current_obstack;
4095 current_obstack = &permanent_obstack;
4096 function_type1 = make_node (FUNCTION_TYPE);
4097 function_type2 = make_node (FUNCTION_TYPE);
4098 current_obstack = ambient_obstack;
4101 /* install argument types - normally set by "build_function_type ()". */
4102 TYPE_ARG_TYPES (function_type1) = get_arg_type_list (proto1, METHOD_REF, 0);
4103 TYPE_ARG_TYPES (function_type2) = get_arg_type_list (proto2, METHOD_REF, 0);
4105 /* install return type */
4106 TREE_TYPE (function_type1) = groktypename (TREE_TYPE (proto1));
4107 TREE_TYPE (function_type2) = groktypename (TREE_TYPE (proto2));
4109 return comptypes (function_type1, function_type2);
4113 * - generate an identifier for the function. the format is "_n_cls",
4114 * where 1 <= n <= nMethods, and cls is the name the implementation we
4116 * - install the return type from the method declaration.
4117 * - if we have a prototype, check for type consistency.
4120 really_start_method (method, parmlist)
4121 tree method, parmlist;
4123 tree sc_spec, ret_spec, ret_decl, decl_specs;
4124 tree method_decl, method_id;
4127 /* synth the storage class & assemble the return type */
4128 sc_spec = tree_cons (NULLT, ridpointers[(int) RID_STATIC], NULLT);
4129 ret_spec = TREE_PURPOSE (TREE_TYPE (method));
4130 decl_specs = chainon (sc_spec, ret_spec);
4132 if (TREE_CODE (implementation_context) == IMPLEMENTATION_TYPE)
4134 /* Make sure this is big enough for any plausible method label. */
4135 buf = (char *) alloca (50
4136 + strlen (IDENTIFIER_POINTER (METHOD_SEL_NAME (method)))
4137 + strlen (IDENTIFIER_POINTER (CLASS_NAME (implementation_context))));
4138 #ifdef OBJC_GEN_METHOD_LABEL
4139 OBJC_GEN_METHOD_LABEL (buf,
4140 TREE_CODE (method) == INSTANCE_METHOD_DECL,
4141 IDENTIFIER_POINTER (CLASS_NAME (implementation_context)),
4143 IDENTIFIER_POINTER (METHOD_SEL_NAME (method)));
4145 sprintf (buf, "_%d_%s", ++method_slot,
4146 IDENTIFIER_POINTER (CLASS_NAME (implementation_context)));
4149 else /* we have a category */
4151 /* Make sure this is big enough for any plausible method label. */
4152 buf = (char *) alloca (50
4153 + strlen (IDENTIFIER_POINTER (METHOD_SEL_NAME (method)))
4154 + strlen (IDENTIFIER_POINTER (CLASS_SUPER_NAME (implementation_context)))
4155 + strlen (IDENTIFIER_POINTER (CLASS_NAME (implementation_context))));
4156 #ifdef OBJC_GEN_METHOD_LABEL
4157 OBJC_GEN_METHOD_LABEL (buf,
4158 TREE_CODE (method) == INSTANCE_METHOD_DECL,
4159 IDENTIFIER_POINTER (CLASS_NAME (implementation_context)),
4160 IDENTIFIER_POINTER (CLASS_SUPER_NAME (implementation_context)),
4161 IDENTIFIER_POINTER (METHOD_SEL_NAME (method)));
4163 sprintf (buf, "_%d_%s_%s", ++method_slot,
4164 IDENTIFIER_POINTER (CLASS_NAME (implementation_context)),
4165 IDENTIFIER_POINTER (CLASS_SUPER_NAME (implementation_context)));
4169 method_id = get_identifier (buf);
4171 method_decl = build_nt (CALL_EXPR, method_id, parmlist, NULLT);
4173 /* check the declarator portion of the return type for the method */
4174 if (ret_decl = TREE_VALUE (TREE_TYPE (method)))
4177 * unite the complex decl (specified in the abstract decl) with the
4178 * function decl just synthesized...(int *), (int (*)()), (int (*)[]).
4180 tree save_expr = expr_last (ret_decl);
4182 TREE_OPERAND (save_expr, 0) = method_decl;
4183 method_decl = ret_decl;
4184 /* fool the parser into thinking it is starting a function */
4185 start_function (decl_specs, method_decl, 0);
4186 /* unhook...this has the effect of restoring the abstract declarator */
4187 TREE_OPERAND (save_expr, 0) = NULLT;
4191 TREE_VALUE (TREE_TYPE (method)) = method_decl;
4192 /* fool the parser into thinking it is starting a function */
4193 start_function (decl_specs, method_decl, 0);
4194 /* unhook...this has the effect of restoring the abstract declarator */
4195 TREE_VALUE (TREE_TYPE (method)) = NULLT;
4198 METHOD_DEFINITION (method) = current_function_decl;
4200 /* check consistency...start_function (), pushdecl (), duplicate_decls (). */
4202 if (implementation_template != implementation_context)
4206 if (TREE_CODE (method) == INSTANCE_METHOD_DECL)
4207 chain = CLASS_NST_METHODS (implementation_template);
4209 chain = CLASS_CLS_METHODS (implementation_template);
4211 if (proto = lookup_method (chain, METHOD_SEL_NAME (method)))
4213 if (!comp_method_with_proto (method, proto))
4215 fprintf (stderr, "%s: In method `%s'\n", input_filename,
4216 IDENTIFIER_POINTER (METHOD_SEL_NAME (method)));
4217 if (TREE_CODE (method) == INSTANCE_METHOD_DECL)
4219 error_with_method ("conflicting types for", '-', method);
4220 error_with_method ("previous declaration of", '-', proto);
4224 error_with_method ("conflicting types for", '+', method);
4225 error_with_method ("previous declaration of", '+', proto);
4233 * the following routine is always called...this "architecture" is to
4234 * accommodate "old-style" variable length selectors.
4236 * - a:a b:b // prototype ; id c; id d; // old-style
4239 continue_method_def ()
4243 if (METHOD_ADD_ARGS (method_context) == (tree)1)
4245 * we have a `, ...' immediately following the selector.
4247 parmlist = get_parm_info (0);
4249 parmlist = get_parm_info (1); /* place a `void_at_end' */
4251 /* set self_decl from the first argument...this global is used by
4252 * build_ivar_reference ().build_indirect_ref ().
4254 self_decl = TREE_PURPOSE (parmlist);
4256 poplevel (0, 0, 0); /* must be called BEFORE "start_function ()" */
4258 really_start_method (method_context, parmlist);
4260 store_parm_decls (); /* must be called AFTER "start_function ()" */
4266 if (!_OBJC_SUPER_decl)
4267 _OBJC_SUPER_decl = start_decl (get_identifier (_TAG_SUPER),
4268 build_tree_list (NULLT, objc_super_template), 0);
4270 /* this prevents `unused variable' warnings when compiling with `-Wall' */
4271 DECL_IN_SYSTEM_HEADER (_OBJC_SUPER_decl) = 1;
4275 * _n_Method (id self, SEL sel, ...)
4277 * struct objc_super _S;
4279 * _msgSuper ((_S.self = self, _S.class = _cls, &_S), ...);
4283 get_super_receiver ()
4287 tree super_expr, super_expr_list;
4289 /* set receiver to self */
4290 super_expr = build_component_ref (_OBJC_SUPER_decl, self_id);
4291 super_expr = build_modify_expr (super_expr, NOP_EXPR, self_decl);
4292 super_expr_list = build_tree_list (NULLT, super_expr);
4294 /* set class to begin searching */
4295 super_expr = build_component_ref (_OBJC_SUPER_decl, get_identifier ("class"));
4297 if (TREE_CODE (implementation_context) == IMPLEMENTATION_TYPE)
4299 /* [_cls, __cls]Super are "pre-built" in synth_foward_declarations () */
4301 if (TREE_CODE (method_context) == INSTANCE_METHOD_DECL)
4302 super_expr = build_modify_expr (super_expr, NOP_EXPR, _clsSuper_ref);
4304 super_expr = build_modify_expr (super_expr, NOP_EXPR, __clsSuper_ref);
4306 else /* we have a category... */
4308 tree params, super_name = CLASS_SUPER_NAME (implementation_template);
4311 if (!super_name) /* Barf if super used in a category of Object. */
4313 error("no super class declared in interface for `%s'",
4314 IDENTIFIER_POINTER (CLASS_NAME (implementation_template)));
4315 return error_mark_node;
4318 add_class_reference (super_name);
4320 params = build_tree_list (NULLT,
4321 my_build_string (IDENTIFIER_LENGTH (super_name) + 1,
4322 IDENTIFIER_POINTER (super_name)));
4324 if (TREE_CODE (method_context) == INSTANCE_METHOD_DECL)
4325 funcCall = build_function_call (objc_getClass_decl, params);
4327 funcCall = build_function_call (objc_getMetaClass_decl, params);
4330 TREE_TYPE (funcCall) = TREE_TYPE (_clsSuper_ref);
4331 super_expr = build_modify_expr (super_expr, NOP_EXPR, funcCall);
4333 chainon (super_expr_list, build_tree_list (NULL_TREE, super_expr));
4335 super_expr = build_unary_op (ADDR_EXPR, _OBJC_SUPER_decl, 0);
4336 chainon (super_expr_list, build_tree_list (NULL_TREE, super_expr));
4338 return build_compound_expr (super_expr_list);
4342 error ("[super ...] must appear in a method context");
4343 return error_mark_node;
4348 encode_method_def (func_decl)
4357 encode_type (TREE_TYPE (TREE_TYPE (func_decl)),
4358 OBJC_ENCODE_DONT_INLINE_DEFS);
4360 for (parms = DECL_ARGUMENTS (func_decl); parms;
4361 parms = TREE_CHAIN (parms))
4362 stack_size += TREE_INT_CST_LOW (TYPE_SIZE (DECL_ARG_TYPE (parms)))
4365 sprintf (buffer, "%d", stack_size);
4366 obstack_grow (&util_obstack, buffer, strlen (buffer));
4368 /* argument types */
4369 for (parms = DECL_ARGUMENTS (func_decl); parms;
4370 parms = TREE_CHAIN (parms))
4372 int offset_in_bytes;
4375 encode_type (TREE_TYPE (parms), OBJC_ENCODE_DONT_INLINE_DEFS);
4377 /* compute offset */
4378 if (GET_CODE (DECL_INCOMING_RTL (parms)) == MEM)
4380 rtx addr = XEXP (DECL_INCOMING_RTL (parms), 0);
4382 /* ??? Here we assume that the parm address is indexed
4383 off the frame pointer or arg pointer.
4384 If that is not true, we produce meaningless results,
4385 but do not crash. */
4386 if (GET_CODE (addr) == PLUS
4387 && GET_CODE (XEXP (addr, 1)) == CONST_INT)
4388 offset_in_bytes = INTVAL (XEXP (addr, 1));
4390 offset_in_bytes = 0;
4392 /* This is the case where the parm is passed as an int or double
4393 and it is converted to a char, short or float and stored back
4394 in the parmlist. In this case, describe the parm
4395 with the variable's declared type, and adjust the address
4396 if the least significant bytes (which we are using) are not
4398 #if BYTES_BIG_ENDIAN
4399 if (TREE_TYPE (parms) != DECL_ARG_TYPE (parms))
4400 offset_in_bytes += (GET_MODE_SIZE (TYPE_MODE (DECL_ARG_TYPE (parms)))
4401 - GET_MODE_SIZE (GET_MODE (DECL_RTL (parms))));
4405 offset_in_bytes = 0;
4407 /* The "+ 4" is a total hack to account for the return pc and
4408 saved fp on the 68k. We should redefine this format! */
4409 sprintf (buffer, "%d", offset_in_bytes + 8);
4410 obstack_grow (&util_obstack, buffer, strlen (buffer));
4413 result = get_identifier (obstack_finish (&util_obstack));
4414 obstack_free (&util_obstack, util_firstobj);
4419 finish_method_def ()
4421 METHOD_ENCODING (method_context) =
4422 encode_method_def (current_function_decl);
4424 finish_function (0);
4426 /* this must be done AFTER finish_function, since the optimizer may
4427 find "may be used before set" errors. */
4428 method_context = NULLT; /* required to implement _msgSuper () */
4432 lang_report_error_function (decl)
4437 fprintf (stderr, "In method `%s'\n",
4438 IDENTIFIER_POINTER (METHOD_SEL_NAME (method_context)));
4446 is_complex_decl (type)
4449 return (TREE_CODE (type) == ARRAY_TYPE
4450 || TREE_CODE (type) == FUNCTION_TYPE
4451 || TREE_CODE (type) == POINTER_TYPE);
4455 /* Code to convert a decl node into text for a declaration in C. */
4457 static char tmpbuf[256];
4460 adorn_decl (decl, str)
4464 enum tree_code code = TREE_CODE (decl);
4466 if (code == ARRAY_REF)
4468 tree anIntCst = TREE_OPERAND (decl, 1);
4470 sprintf (str + strlen (str), "[%d]", TREE_INT_CST_LOW (anIntCst));
4472 else if (code == ARRAY_TYPE)
4474 tree anIntCst = TYPE_SIZE (decl);
4475 tree array_of = TREE_TYPE (decl);
4477 sprintf (str + strlen (str), "[%d]",
4478 TREE_INT_CST_LOW (anIntCst)/TREE_INT_CST_LOW (TYPE_SIZE (array_of)));
4480 else if (code == CALL_EXPR)
4482 else if (code == FUNCTION_TYPE)
4484 tree chain = TYPE_ARG_TYPES (decl); /* a list of types */
4486 while (chain && TREE_VALUE (chain) != void_type_node)
4488 gen_declaration (TREE_VALUE (chain), str);
4489 chain = TREE_CHAIN (chain);
4490 if (chain && TREE_VALUE (chain) != void_type_node)
4497 strcpy (tmpbuf, "*"); strcat (tmpbuf, str);
4498 strcpy (str, tmpbuf);
4503 gen_declarator (decl, buf, name)
4510 enum tree_code code = TREE_CODE (decl);
4517 case ARRAY_REF: case INDIRECT_REF: case CALL_EXPR:
4519 op = TREE_OPERAND (decl, 0);
4521 /* we have a pointer to a function or array...(*)(), (*)[] */
4522 if ((code == ARRAY_REF || code == CALL_EXPR) &&
4523 (op && TREE_CODE (op) == INDIRECT_REF))
4526 str = gen_declarator (op, buf, name);
4530 strcpy (tmpbuf, "("); strcat (tmpbuf, str); strcat (tmpbuf, ")");
4531 strcpy (str, tmpbuf);
4534 adorn_decl (decl, str);
4537 case ARRAY_TYPE: case FUNCTION_TYPE: case POINTER_TYPE:
4539 str = strcpy (buf, name);
4541 /* this clause is done iteratively...rather than recursively */
4544 op = is_complex_decl (TREE_TYPE (decl))
4548 adorn_decl (decl, str);
4550 /* we have a pointer to a function or array...(*)(), (*)[] */
4551 if ((code == POINTER_TYPE) &&
4552 (op && (TREE_CODE (op) == FUNCTION_TYPE
4553 || TREE_CODE (op) == ARRAY_TYPE)))
4555 strcpy (tmpbuf, "("); strcat (tmpbuf, str); strcat (tmpbuf, ")");
4556 strcpy (str, tmpbuf);
4559 decl = is_complex_decl (TREE_TYPE (decl))
4563 while (decl && (code = TREE_CODE (decl)));
4567 case IDENTIFIER_NODE:
4568 /* will only happen if we are processing a "raw" expr-decl. */
4569 return strcpy (buf, IDENTIFIER_POINTER (decl));
4574 else /* we have an abstract declarator or a _DECL node */
4576 return strcpy (buf, name);
4581 gen_declspecs (declspecs, buf, raw)
4590 for (chain = declspecs; chain; chain = TREE_CHAIN (chain))
4592 tree aspec = TREE_VALUE (chain);
4594 if (TREE_CODE (aspec) == IDENTIFIER_NODE)
4595 strcat (buf, IDENTIFIER_POINTER (aspec));
4596 else if (TREE_CODE (aspec) == RECORD_TYPE)
4598 if (TYPE_NAME (aspec))
4600 if (!TREE_STATIC_TEMPLATE (aspec))
4601 strcat (buf, "struct ");
4602 strcat (buf, IDENTIFIER_POINTER (TYPE_NAME (aspec)));
4605 strcat (buf, "untagged struct");
4607 else if (TREE_CODE (aspec) == UNION_TYPE)
4609 if (TYPE_NAME (aspec))
4611 if (!TREE_STATIC_TEMPLATE (aspec))
4612 strcat (buf, "union ");
4613 strcat (buf, IDENTIFIER_POINTER (TYPE_NAME (aspec)));
4616 strcat (buf, "untagged union");
4618 else if (TREE_CODE (aspec) == ENUMERAL_TYPE)
4620 if (TYPE_NAME (aspec))
4622 if (!TREE_STATIC_TEMPLATE (aspec))
4623 strcat (buf, "enum ");
4624 strcat (buf, IDENTIFIER_POINTER (TYPE_NAME (aspec)));
4627 strcat (buf, "untagged enum");
4633 switch (TREE_CODE (declspecs))
4635 /* type specifiers */
4637 case INTEGER_TYPE: /* signed integer types */
4639 if (declspecs == short_integer_type_node) /* 's' */
4640 strcat (buf, "short int ");
4641 else if (declspecs == integer_type_node) /* 'i' */
4642 strcat (buf, "int ");
4643 else if (declspecs == long_integer_type_node) /* 'l' */
4644 strcat (buf, "long int ");
4645 else if (declspecs == signed_char_type_node || /* 'c' */
4646 declspecs == char_type_node)
4647 strcat (buf, "char ");
4649 /* unsigned integer types */
4651 else if (declspecs == short_unsigned_type_node) /* 'S' */
4652 strcat (buf, "unsigned short ");
4653 else if (declspecs == unsigned_type_node) /* 'I' */
4654 strcat (buf, "unsigned int ");
4655 else if (declspecs == long_unsigned_type_node) /* 'L' */
4656 strcat (buf, "unsigned long ");
4657 else if (declspecs == unsigned_char_type_node) /* 'C' */
4658 strcat (buf, "unsigned char ");
4661 case REAL_TYPE: /* floating point types */
4663 if (declspecs == float_type_node) /* 'f' */
4664 strcat (buf, "float ");
4665 else if (declspecs == double_type_node) /* 'd' */
4666 strcat (buf, "double ");
4667 else if (declspecs == long_double_type_node) /* 'd' */
4668 strcat (buf, "long double ");
4672 if (!TREE_STATIC_TEMPLATE (declspecs))
4673 strcat (buf, "struct ");
4674 if (TYPE_NAME (declspecs) &&
4675 (TREE_CODE (TYPE_NAME (declspecs)) == IDENTIFIER_NODE))
4677 strcat (buf, IDENTIFIER_POINTER (TYPE_NAME (declspecs)));
4682 strcat (buf, "union ");
4683 if (TYPE_NAME (declspecs) &&
4684 (TREE_CODE (TYPE_NAME (declspecs)) == IDENTIFIER_NODE))
4686 strcat (buf, IDENTIFIER_POINTER (TYPE_NAME (declspecs)));
4691 strcat (buf, "enum ");
4692 if (TYPE_NAME (declspecs) &&
4693 (TREE_CODE (TYPE_NAME (declspecs)) == IDENTIFIER_NODE))
4695 strcat (buf, IDENTIFIER_POINTER (TYPE_NAME (declspecs)));
4700 strcat (buf, "void ");
4705 gen_declaration (atype_or_adecl, buf)
4706 tree atype_or_adecl;
4711 if (TREE_CODE (atype_or_adecl) == TREE_LIST)
4713 tree declspecs; /* "identifier_node", "record_type" */
4714 tree declarator; /* "array_ref", "indirect_ref", "call_expr"... */
4716 /* we have a "raw", abstract declarator (typename) */
4717 declarator = TREE_VALUE (atype_or_adecl);
4718 declspecs = TREE_PURPOSE (atype_or_adecl);
4720 gen_declspecs (declspecs, buf, 1);
4721 strcat (buf, gen_declarator (declarator, declbuf, ""));
4726 tree declspecs; /* "integer_type", "real_type", "record_type"... */
4727 tree declarator; /* "array_type", "function_type", "pointer_type". */
4729 if (TREE_CODE (atype_or_adecl) == FIELD_DECL
4730 || TREE_CODE (atype_or_adecl) == PARM_DECL
4731 || TREE_CODE (atype_or_adecl) == FUNCTION_DECL)
4732 atype = TREE_TYPE (atype_or_adecl);
4734 atype = atype_or_adecl; /* assume we have a *_type node */
4736 if (is_complex_decl (atype))
4740 /* get the declaration specifier...it is at the end of the list */
4741 declarator = chain = atype;
4743 chain = TREE_TYPE (chain); /* not TREE_CHAIN (chain); */
4744 while (is_complex_decl (chain));
4753 gen_declspecs (declspecs, buf, 0);
4755 if (TREE_CODE (atype_or_adecl) == FIELD_DECL
4756 || TREE_CODE (atype_or_adecl) == PARM_DECL
4757 || TREE_CODE (atype_or_adecl) == FUNCTION_DECL)
4761 strcat (buf, gen_declarator (declarator, declbuf,
4762 IDENTIFIER_POINTER (DECL_NAME (atype_or_adecl))));
4765 strcat (buf, IDENTIFIER_POINTER (DECL_NAME (atype_or_adecl)));
4769 strcat (buf, gen_declarator (declarator, declbuf, ""));
4775 #define RAW_TYPESPEC(meth) (TREE_VALUE (TREE_PURPOSE (TREE_TYPE (meth))))
4778 gen_method_decl (method, buf)
4784 if (RAW_TYPESPEC (method) != objc_object_reference)
4787 gen_declaration (TREE_TYPE (method), buf);
4791 chain = METHOD_SEL_ARGS (method);
4793 { /* we have a chain of keyword_decls */
4796 if (KEYWORD_KEY_NAME (chain))
4797 strcat (buf, IDENTIFIER_POINTER (KEYWORD_KEY_NAME (chain)));
4800 if (RAW_TYPESPEC (chain) != objc_object_reference)
4803 gen_declaration (TREE_TYPE (chain), buf);
4806 strcat (buf, IDENTIFIER_POINTER (KEYWORD_ARG_NAME (chain)));
4807 if (chain = TREE_CHAIN (chain))
4812 if (METHOD_ADD_ARGS (method) == (tree)1)
4813 strcat (buf, ", ...");
4814 else if (METHOD_ADD_ARGS (method))
4815 { /* we have a tree list node as generate by `get_parm_info ()' */
4816 chain = TREE_PURPOSE (METHOD_ADD_ARGS (method));
4817 /* know we have a chain of parm_decls */
4821 gen_declaration (chain, buf);
4822 chain = TREE_CHAIN (chain);
4826 else /* we have a unary selector */
4828 strcat (buf, IDENTIFIER_POINTER (METHOD_SEL_NAME (method)));
4835 gen_prototype (fp, decl)
4839 /* we have a function definition - generate prototype */
4840 bzero (errbuf, BUFSIZE);
4841 gen_declaration (decl, errbuf);
4842 fprintf (fp, "%s;\n", errbuf);
4848 dump_interface (fp, chain)
4852 char *buf = (char *)xmalloc (256);
4853 char *my_name = IDENTIFIER_POINTER (CLASS_NAME (chain));
4854 tree ivar_decls = CLASS_RAW_IVARS (chain);
4855 tree nst_methods = CLASS_NST_METHODS (chain);
4856 tree cls_methods = CLASS_CLS_METHODS (chain);
4858 fprintf (fp, "\n@interface %s", my_name);
4860 if (CLASS_SUPER_NAME (chain))
4862 char *super_name = IDENTIFIER_POINTER (CLASS_SUPER_NAME (chain));
4863 fprintf (fp, " : %s\n", super_name);
4870 fprintf (fp, "{\n");
4874 fprintf (fp, "\t%s;\n", gen_declaration (ivar_decls, buf));
4875 ivar_decls = TREE_CHAIN (ivar_decls);
4878 fprintf (fp, "}\n");
4884 fprintf (fp, "- %s;\n", gen_method_decl (nst_methods, buf));
4885 nst_methods = TREE_CHAIN (nst_methods);
4891 fprintf (fp, "+ %s;\n", gen_method_decl (cls_methods, buf));
4892 cls_methods = TREE_CHAIN (cls_methods);
4894 fprintf (fp, "\n@end");
4900 /* Add the special tree codes of Objective C to the tables. */
4902 gcc_obstack_init (&util_obstack);
4903 util_firstobj = (char *) obstack_finish (&util_obstack);
4906 = (char **) realloc (tree_code_type,
4907 sizeof (char *) * LAST_OBJC_TREE_CODE);
4909 = (int *) realloc (tree_code_length,
4910 sizeof (int) * LAST_OBJC_TREE_CODE);
4912 = (char **) realloc (tree_code_name,
4913 sizeof (char *) * LAST_OBJC_TREE_CODE);
4914 bcopy (objc_tree_code_type,
4915 tree_code_type + (int) LAST_AND_UNUSED_TREE_CODE,
4916 (((int) LAST_OBJC_TREE_CODE - (int) LAST_AND_UNUSED_TREE_CODE)
4917 * sizeof (char *)));
4918 bcopy (objc_tree_code_length,
4919 tree_code_length + (int) LAST_AND_UNUSED_TREE_CODE,
4920 (((int) LAST_OBJC_TREE_CODE - (int) LAST_AND_UNUSED_TREE_CODE)
4922 bcopy (objc_tree_code_name,
4923 tree_code_name + (int) LAST_AND_UNUSED_TREE_CODE,
4924 (((int) LAST_OBJC_TREE_CODE - (int) LAST_AND_UNUSED_TREE_CODE)
4925 * sizeof (char *)));
4927 errbuf = (char *)xmalloc (BUFSIZE);
4929 synth_module_prologue ();
4935 struct imp_entry *impent;
4938 generate_forward_declaration_to_string_table ();
4940 #ifdef OBJC_PROLOGUE
4944 if (implementation_context || sel_refdef_chain)
4945 generate_objc_symtab_decl ();
4947 for (impent = imp_list; impent; impent = impent->next)
4949 implementation_context = impent->imp_context;
4950 implementation_template = impent->imp_template;
4952 _OBJC_CLASS_decl = impent->class_decl;
4953 _OBJC_METACLASS_decl = impent->meta_decl;
4955 if (TREE_CODE (implementation_context) == IMPLEMENTATION_TYPE)
4957 /* all of the following reference the string pool... */
4958 generate_ivar_lists ();
4959 generate_dispatch_tables ();
4960 generate_shared_structures ();
4964 generate_dispatch_tables ();
4965 generate_category (implementation_context);
4970 build_selector_translation_table ();
4972 if (implementation_context || sel_refdef_chain)
4974 /* Arrange for Objc data structures to be initialized at run time. */
4976 char *init_name = build_module_descriptor ();
4978 assemble_constructor (init_name);
4981 /* dump the string table last */
4983 if (sel_refdef_chain)
4985 build_message_selector_pool ();
4988 /* dump the class references...this forces the appropriate classes
4989 to be linked into the executable image, preserving unix archive
4990 semantics...this can be removed when we move to a more dynamically
4993 for (chain = cls_ref_chain; chain; chain = TREE_CHAIN (chain))
4994 handle_class_ref (chain);
4996 for (impent = imp_list; impent; impent = impent->next)
4997 handle_impent (impent);
4999 #if 0 /* If GAS has such a bug, let's fix it. */
5000 /*** this fixes a gross bug in the assembler...it `expects' #APP to have
5001 *** a matching #NO_APP, or it crashes (sometimes). app_disable () will
5002 *** insure this is the case. 5/19/89, s.naroff.
5004 if (cls_ref_chain || imp_list)
5008 if (flag_gen_declaration)
5010 add_class (implementation_context);
5011 dump_interface (gen_declaration_file, implementation_context);
5017 /* Run through the selector hash tables and print a warning for any
5018 selector which has multiple methods. */
5020 for (slot = 0; slot < SIZEHASHTABLE; slot++)
5024 for (hsh = cls_method_hash_list[slot]; hsh; hsh = hsh->next)
5028 tree meth = hsh->key;
5029 char type = (TREE_CODE (meth) == INSTANCE_METHOD_DECL)
5033 warning ("potential selector conflict for method `%s'",
5034 IDENTIFIER_POINTER (METHOD_SEL_NAME (meth)));
5035 warn_with_method ("found", type, meth);
5036 for (loop = hsh->list; loop; loop = loop->next)
5037 warn_with_method ("found", type, loop->value);
5042 for (slot = 0; slot < SIZEHASHTABLE; slot++)
5046 for (hsh = nst_method_hash_list[slot]; hsh; hsh = hsh->next)
5050 tree meth = hsh->key;
5051 char type = (TREE_CODE (meth) == INSTANCE_METHOD_DECL)
5055 warning ("potential selector conflict for method `%s'",
5056 IDENTIFIER_POINTER (METHOD_SEL_NAME (meth)));
5057 warn_with_method ("found", type, meth);
5058 for (loop = hsh->list; loop; loop = loop->next)
5059 warn_with_method ("found", type, loop->value);
5066 /* Subroutines of finish_objc. */
5068 handle_class_ref (chain)
5073 = (char *) alloca (strlen (IDENTIFIER_POINTER (TREE_VALUE (chain))) + 30);
5075 sprintf (string, "__objc_class_name_%s",
5076 IDENTIFIER_POINTER (TREE_VALUE (chain)));
5078 /* Make a decl for this name, so we can use its address in a tree. */
5079 decl = build_decl (VAR_DECL, get_identifier (string), char_type_node);
5080 DECL_EXTERNAL (decl) = 1;
5081 TREE_PUBLIC (decl) = 1;
5084 rest_of_decl_compilation (decl, 0, 0, 0);
5086 /* Make following constant read-only (why not)? */
5089 /* Output a constant to reference this address. */
5090 output_constant (build1 (ADDR_EXPR, string_type_node, decl),
5091 int_size_in_bytes (string_type_node));
5094 handle_impent (impent)
5095 struct imp_entry *impent;
5097 implementation_context = impent->imp_context;
5098 implementation_template = impent->imp_template;
5100 if (TREE_CODE (impent->imp_context) == IMPLEMENTATION_TYPE)
5103 = (char *) alloca (strlen (IDENTIFIER_POINTER (CLASS_NAME (impent->imp_context))) + 30);
5105 sprintf (string, "__objc_class_name_%s",
5106 IDENTIFIER_POINTER (CLASS_NAME (impent->imp_context)));
5107 assemble_global (string);
5108 assemble_label (string);
5110 else if (TREE_CODE (impent->imp_context) == CATEGORY_TYPE)
5113 = (char *) alloca (strlen (IDENTIFIER_POINTER (CLASS_NAME (impent->imp_context)))
5114 + strlen (IDENTIFIER_POINTER (CLASS_SUPER_NAME (impent->imp_context)))
5117 /* Do the same for categories. Even though no references to these
5118 symbols are generated automatically by the compiler, it gives
5119 you a handle to pull them into an archive by hand. */
5120 sprintf (string, "__objc_category_name_%s_%s",
5121 IDENTIFIER_POINTER (CLASS_NAME (impent->imp_context)),
5122 IDENTIFIER_POINTER (CLASS_SUPER_NAME (impent->imp_context)));
5123 assemble_global (string);
5124 assemble_label (string);
5134 char *buf = (char *)xmalloc (256);
5136 { /* dump function prototypes */
5137 tree loop = _OBJC_MODULES_decl;
5139 fprintf (fp, "\n\nfunction prototypes:\n");
5142 if (TREE_CODE (loop) == FUNCTION_DECL && DECL_INITIAL (loop))
5144 /* we have a function definition - generate prototype */
5145 bzero (errbuf, BUFSIZE);
5146 gen_declaration (loop, errbuf);
5147 fprintf (fp, "%s;\n", errbuf);
5149 loop = TREE_CHAIN (loop);
5152 { /* dump global chains */
5154 int i, index = 0, offset = 0;
5157 for (i = 0; i < SIZEHASHTABLE; i++)
5159 if (hashlist = nst_method_hash_list[i])
5161 fprintf (fp, "\n\nnst_method_hash_list[%d]:\n", i);
5165 fprintf (fp, "-%s;\n", gen_method_decl (hashlist->key, buf));
5166 hashlist = hashlist->next;
5171 for (i = 0; i < SIZEHASHTABLE; i++)
5173 if (hashlist = cls_method_hash_list[i])
5175 fprintf (fp, "\n\ncls_method_hash_list[%d]:\n", i);
5179 fprintf (fp, "-%s;\n", gen_method_decl (hashlist->key, buf));
5180 hashlist = hashlist->next;
5185 fprintf (fp, "\nsel_refdef_chain:\n");
5186 for (loop = sel_refdef_chain; loop; loop = TREE_CHAIN (loop))
5188 fprintf (fp, "(index: %4d offset: %4d) %s\n", index, offset,
5189 IDENTIFIER_POINTER (TREE_VALUE (loop)));
5191 /* add one for the '\0' character */
5192 offset += IDENTIFIER_LENGTH (TREE_VALUE (loop)) + 1;
5194 fprintf (fp, "\n (max_selector_index: %4d.\n", max_selector_index);
5200 print_lang_statistics ()