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 = size_in_bytes (objc_module_template);
816 initlist = tree_cons (NULLT, expr, initlist);
818 /* name = { ..., "foo.m", ... } */
820 expr = build_msg_pool_reference (
821 add_objc_string (get_identifier (input_filename)));
822 initlist = tree_cons (NULLT, expr, initlist);
824 /* symtab = { ..., _OBJC_SYMBOLS, ... } */
826 if (_OBJC_SYMBOLS_decl)
827 expr = build_unary_op (ADDR_EXPR, _OBJC_SYMBOLS_decl, 0);
829 expr = build_int_2 (0, 0);
830 initlist = tree_cons (NULLT, expr, initlist);
832 return build_nt (CONSTRUCTOR, NULLT, nreverse (initlist));
835 /* Write out the data structures to describe Objective C classes defined.
836 If appropriate, compile and output a setup function to initialize them.
837 Return a string which is the name of a function to call to initialize
838 the Objective C data structures for this file (and perhaps for other files
842 build_module_descriptor ()
844 tree decl_specs, field_decl, field_decl_chain;
846 objc_module_template = start_struct (RECORD_TYPE, get_identifier (_TAG_MODULE));
850 decl_specs = build_tree_list (NULLT, ridpointers[(int) RID_LONG]);
851 field_decl = get_identifier ("version");
852 field_decl = grokfield (input_filename, lineno, field_decl, decl_specs, NULLT);
853 field_decl_chain = field_decl;
857 decl_specs = build_tree_list (NULLT, ridpointers[(int) RID_LONG]);
858 field_decl = get_identifier ("size");
859 field_decl = grokfield (input_filename, lineno, field_decl, decl_specs, NULLT);
860 chainon (field_decl_chain, field_decl);
864 decl_specs = build_tree_list (NULLT, ridpointers[(int) RID_CHAR]);
865 field_decl = build1 (INDIRECT_REF, NULLT, get_identifier ("name"));
866 field_decl = grokfield (input_filename, lineno, field_decl, decl_specs, NULLT);
867 chainon (field_decl_chain, field_decl);
869 /* struct objc_symtab *symtab; */
871 decl_specs = get_identifier (_TAG_SYMTAB);
872 decl_specs = build_tree_list (NULLT, xref_tag (RECORD_TYPE, decl_specs));
873 field_decl = build1 (INDIRECT_REF, NULLT, get_identifier ("symtab"));
874 field_decl = grokfield (input_filename, lineno, field_decl, decl_specs, NULLT);
875 chainon (field_decl_chain, field_decl);
877 finish_struct (objc_module_template, field_decl_chain);
879 /* create an instance of "objc_module" */
881 decl_specs = tree_cons (NULLT, objc_module_template,
882 build_tree_list (NULLT, ridpointers[(int) RID_STATIC]));
884 _OBJC_MODULES_decl = start_decl (get_identifier ("_OBJC_MODULES"),
887 finish_decl (_OBJC_MODULES_decl, init_module_descriptor (), NULLT);
889 /* Mark the decl to avoid "defined but not used" warning. */
890 DECL_IN_SYSTEM_HEADER (_OBJC_MODULES_decl) = 1;
892 /* Generate a constructor call for the module descriptor.
893 This code was generated by reading the grammar rules
894 of c-parse.y; Therefore, it may not be the most efficient
895 way of generating the requisite code. */
896 #ifndef NEXT_OBJC_RUNTIME
898 tree parms, function_decl, decelerator, void_list_node;
901 char *global_object_name = 0;
904 /* Use a global object (which is already required to be unique over
905 the program) rather than the file name (which imposes extra
906 constraints). -- Raeburn@MIT.EDU, 10 Jan 1990. */
908 /* Find the name of some global object defined in this file. */
909 for (t = getdecls (); t; t = TREE_CHAIN (t))
910 if (TREE_PUBLIC (t) && !DECL_EXTERNAL (t) && DECL_INITIAL (t) != 0)
912 global_object_name = IDENTIFIER_POINTER (DECL_NAME (t));
916 /* If none, use the name of the file. */
917 if (!global_object_name)
921 = (char *) alloca (strlen (main_input_filename) + 1);
923 p = main_input_filename;
924 q = global_object_name;
926 /* Replace any weird characters in the file name. */
928 if (! ((*p >= '0' && *p <= '9')
929 || (*p >= 'A' && *p <= 'Z')
930 || (*p >= 'a' && *p <= 'z')))
937 /* Make the constructor name from the name we have found. */
938 buf = (char *) xmalloc (sizeof (CONSTRUCTOR_NAME_FORMAT)
939 + strlen (global_object_name));
940 sprintf (buf, CONSTRUCTOR_NAME_FORMAT, global_object_name);
942 /* Declare void __objc_execClass (void*); */
944 void_list_node = build_tree_list (NULL_TREE, void_type_node);
946 = build_function_type (void_type_node,
947 tree_cons (NULL_TREE, ptr_type_node,
949 function_decl = build_decl (FUNCTION_DECL,
950 get_identifier ("__objc_execClass"),
952 DECL_EXTERNAL (function_decl) = 1;
953 TREE_PUBLIC (function_decl) = 1;
954 pushdecl (function_decl);
955 rest_of_decl_compilation (function_decl, 0, 0, 0);
958 = build_tree_list (NULLT,
959 build_unary_op (ADDR_EXPR, _OBJC_MODULES_decl, 0));
960 decelerator = build_function_call (function_decl, parms);
962 /* void __objc_file_init () {objc_execClass(&L_OBJC_MODULES);} */
964 start_function (void_list_node,
965 build_parse_node (CALL_EXPR, get_identifier (buf),
966 /* This has the format of the output
968 tree_cons (NULL_TREE, NULL_TREE,
972 #if 0 /* This should be turned back on later
973 for the systems where collect is not needed. */
974 /* Make these functions nonglobal
975 so each file can use the same name. */
976 TREE_PUBLIC (current_function_decl) = 0;
978 TREE_USED (current_function_decl) = 1;
981 assemble_external (function_decl);
982 c_expand_expr_stmt (decelerator);
986 /* Return the name of the constructor function. */
989 #else /* NEXT_OBJC_RUNTIME */
991 #endif /* NEXT_OBJC_RUNTIME */
994 /* extern const char _OBJC_STRINGS[]; */
997 generate_forward_declaration_to_string_table ()
999 tree sc_spec, decl_specs, expr_decl;
1001 sc_spec = tree_cons (NULLT, ridpointers[(int) RID_EXTERN], NULLT);
1002 decl_specs = tree_cons (NULLT, ridpointers[(int) RID_CHAR], sc_spec);
1004 expr_decl = build_nt (ARRAY_REF, get_identifier ("_OBJC_STRINGS"), NULLT);
1006 _OBJC_STRINGS_decl = define_decl (expr_decl, decl_specs);
1009 /* static char _OBJC_STRINGS[] = "..."; */
1012 build_message_selector_pool ()
1014 tree sc_spec, decl_specs, expr_decl;
1015 tree chain, string_expr;
1016 int goolengthtmp = 0, msg_pool_size = 0;
1019 sc_spec = tree_cons (NULLT, ridpointers[(int) RID_STATIC], NULLT);
1020 decl_specs = tree_cons (NULLT, ridpointers[(int) RID_CHAR], sc_spec);
1022 expr_decl = build_nt (ARRAY_REF, get_identifier ("_OBJC_STRINGS"), NULLT);
1024 _OBJC_STRINGS_decl = start_decl (expr_decl, decl_specs, 1);
1026 for (chain = sel_refdef_chain; chain; chain = TREE_CHAIN (chain))
1027 msg_pool_size += IDENTIFIER_LENGTH (TREE_VALUE (chain)) + 1;
1031 string_goo = (char *)xmalloc (msg_pool_size);
1032 bzero (string_goo, msg_pool_size);
1034 for (chain = sel_refdef_chain; chain; chain = TREE_CHAIN (chain))
1036 strcpy (string_goo + goolengthtmp, IDENTIFIER_POINTER (TREE_VALUE (chain)));
1037 goolengthtmp += IDENTIFIER_LENGTH (TREE_VALUE (chain)) + 1;
1040 string_expr = my_build_string (msg_pool_size, string_goo);
1042 finish_decl (_OBJC_STRINGS_decl, string_expr, NULLT);
1046 * synthesize the following expr: (char *)&_OBJC_STRINGS[<offset>]
1048 * the cast stops the compiler from issuing the following message:
1050 * grok.m: warning: initialization of non-const * pointer from const *
1051 * grok.m: warning: initialization between incompatible pointer types
1054 build_msg_pool_reference (offset)
1057 tree expr = build_int_2 (offset, 0);
1060 expr = build_array_ref (_OBJC_STRINGS_decl, expr);
1061 expr = build_unary_op (ADDR_EXPR, expr, 0);
1063 cast = build_tree_list (build_tree_list (NULLT, ridpointers[(int) RID_CHAR]),
1064 build1 (INDIRECT_REF, NULLT, NULLT));
1065 TREE_TYPE (expr) = groktypename (cast);
1069 #ifndef OBJC_SELECTORS_WITHOUT_LABELS
1071 build_selector_reference (idx)
1074 tree ref, decl, name, ident;
1076 struct obstack *save_current_obstack = current_obstack;
1077 struct obstack *save_rtl_obstack = rtl_obstack;
1079 sprintf (buf, "_OBJC_SELECTOR_REFERENCES_%d", idx);
1082 rtl_obstack = current_obstack = &permanent_obstack;
1083 ident = get_identifier (buf);
1085 if (IDENTIFIER_GLOBAL_VALUE (ident))
1086 decl = IDENTIFIER_GLOBAL_VALUE (ident); /* set by pushdecl() */
1089 decl = build_decl (VAR_DECL, ident, selector_type);
1090 DECL_EXTERNAL (decl) = 1;
1091 TREE_PUBLIC (decl) = 1;
1092 TREE_USED (decl) = 1;
1094 make_decl_rtl (decl, 0, 1); /* usually called from `rest_of_decl_compilation' */
1095 pushdecl_top_level (decl); /* our `extended/custom' pushdecl in c-decl.c */
1097 current_obstack = save_current_obstack;
1098 rtl_obstack = save_rtl_obstack;
1105 init_selector (offset)
1108 tree expr = build_msg_pool_reference (offset);
1109 TREE_TYPE (expr) = selector_type; /* cast */
1114 build_selector_translation_table ()
1116 tree sc_spec, decl_specs, expr_decl;
1117 tree chain, initlist = NULLT;
1119 #ifndef OBJC_SELECTORS_WITHOUT_LABELS
1120 tree decl, var_decl;
1124 /* The corresponding pop_obstacks is in finish_decl,
1125 called at the end of this function. */
1126 push_obstacks_nochange ();
1129 for (chain = sel_ref_chain; chain; chain = TREE_CHAIN (chain))
1133 #ifndef OBJC_SELECTORS_WITHOUT_LABELS
1134 sprintf (buf, "_OBJC_SELECTOR_REFERENCES_%d", idx);
1135 sc_spec = build_tree_list (NULLT, ridpointers[(int) RID_STATIC]);
1137 /* static SEL _OBJC_SELECTOR_REFERENCES_n = ...; */
1138 decl_specs = tree_cons (NULLT, selector_type, sc_spec);
1139 var_decl = get_identifier (buf);
1141 /* the `decl' that is returned from start_decl is the one that we
1142 * forward declared in `build_selector_reference()'
1144 decl = start_decl (var_decl, decl_specs, 1);
1147 expr = init_selector (offset);
1149 /* add one for the '\0' character */
1150 offset += IDENTIFIER_LENGTH (TREE_VALUE (chain)) + 1;
1152 #ifndef OBJC_SELECTORS_WITHOUT_LABELS
1153 finish_decl (decl, expr, NULLT);
1156 initlist = tree_cons (NULLT, expr, initlist);
1160 #ifdef OBJC_SELECTORS_WITHOUT_LABELS
1161 /* Cause the variable and its initial value to be actually output. */
1162 DECL_EXTERNAL (_OBJC_SELECTOR_REFERENCES_decl) = 0;
1163 TREE_STATIC (_OBJC_SELECTOR_REFERENCES_decl) = 1;
1164 /* NULL terminate the list and fix the decl for output. */
1165 initlist = tree_cons (NULLT, build_int_2 (0, 0), initlist);
1166 DECL_INITIAL (_OBJC_SELECTOR_REFERENCES_decl) = (tree) 1;
1167 initlist = build_nt (CONSTRUCTOR, NULLT, nreverse (initlist));
1168 finish_decl (_OBJC_SELECTOR_REFERENCES_decl, initlist, NULLT);
1173 add_class_reference (ident)
1178 if (chain = cls_ref_chain)
1183 if (ident == TREE_VALUE (chain))
1187 chain = TREE_CHAIN (chain);
1191 /* append to the end of the list */
1192 TREE_CHAIN (tail) = perm_tree_cons (NULLT, ident, NULLT);
1195 cls_ref_chain = perm_tree_cons (NULLT, ident, NULLT);
1199 * sel_ref_chain is a list whose "value" fields will be instances of
1200 * identifier_node that represent the selector.
1203 add_selector_reference (ident)
1209 /* this adds it to sel_refdef_chain, the global pool of selectors */
1210 add_objc_string (ident);
1212 if (chain = sel_ref_chain)
1217 if (ident == TREE_VALUE (chain))
1222 chain = TREE_CHAIN (chain);
1226 /* append to the end of the list */
1227 TREE_CHAIN (tail) = perm_tree_cons (NULLT, ident, NULLT);
1230 sel_ref_chain = perm_tree_cons (NULLT, ident, NULLT);
1232 max_selector_index++;
1237 * sel_refdef_chain is a list whose "value" fields will be instances of
1238 * identifier_node that represent the selector. It returns the offset of
1239 * the selector from the beginning of the _OBJC_STRINGS pool. This offset
1240 * is typically used by "init_selector ()" during code generation.
1243 add_objc_string (ident)
1249 if (chain = sel_refdef_chain)
1254 if (ident == TREE_VALUE (chain))
1257 /* add one for the '\0' character */
1258 offset += IDENTIFIER_LENGTH (TREE_VALUE (chain)) + 1;
1260 chain = TREE_CHAIN (chain);
1264 /* append to the end of the list */
1265 TREE_CHAIN (tail) = perm_tree_cons (NULLT, ident, NULLT);
1268 sel_refdef_chain = perm_tree_cons (NULLT, ident, NULLT);
1274 lookup_interface (ident)
1279 for (chain = interface_chain; chain; chain = TREE_CHAIN (chain))
1281 if (ident == CLASS_NAME (chain))
1288 objc_copy_list (list, head)
1292 tree newlist = NULL_TREE, tail = NULL_TREE;
1296 tail = copy_node (list);
1298 /* the following statement fixes a bug when inheriting instance
1299 variables that are declared to be bitfields. finish_struct () expects
1300 to find the width of the bitfield in DECL_INITIAL (), which it
1301 nulls out after processing the decl of the super class...rather
1302 than change the way finish_struct () works (which is risky),
1303 I create the situation it expects...s.naroff (7/23/89).
1305 if (DECL_BIT_FIELD (tail) && DECL_INITIAL (tail) == 0)
1306 DECL_INITIAL (tail) = build_int_2 (DECL_FIELD_SIZE (tail), 0);
1308 newlist = chainon (newlist, tail);
1309 list = TREE_CHAIN (list);
1316 * build_private_template (), get_class_ivars (), and get_static_reference ().
1319 build_ivar_chain (interface)
1322 tree my_name, super_name, ivar_chain;
1324 my_name = CLASS_NAME (interface);
1325 super_name = CLASS_SUPER_NAME (interface);
1327 /* "leaf" ivars never get copied...there is no reason to. */
1328 ivar_chain = CLASS_IVARS (interface);
1333 tree super_interface = lookup_interface (super_name);
1335 if (!super_interface)
1337 /* fatal did not work with 2 args...should fix */
1338 error ("Cannot find interface declaration for `%s', superclass of `%s'",
1339 IDENTIFIER_POINTER (super_name), IDENTIFIER_POINTER (my_name));
1342 if (super_interface == interface)
1344 fatal ("Circular inheritance in interface declaration for `%s'",
1345 IDENTIFIER_POINTER (super_name));
1347 interface = super_interface;
1348 my_name = CLASS_NAME (interface);
1349 super_name = CLASS_SUPER_NAME (interface);
1351 op1 = CLASS_IVARS (interface);
1354 tree head, tail = objc_copy_list (op1, &head);
1356 /* prepend super class ivars...make a copy of the list, we
1357 * do not want to alter the original.
1359 TREE_CHAIN (tail) = ivar_chain;
1367 * struct <classname> {
1368 * struct objc_class *isa;
1373 build_private_template (class)
1378 if (CLASS_STATIC_TEMPLATE (class))
1380 _PRIVATE_record = CLASS_STATIC_TEMPLATE (class);
1381 ivar_context = TYPE_FIELDS (CLASS_STATIC_TEMPLATE (class));
1385 _PRIVATE_record = start_struct (RECORD_TYPE, CLASS_NAME (class));
1387 ivar_context = build_ivar_chain (class);
1389 finish_struct (_PRIVATE_record, ivar_context);
1391 CLASS_STATIC_TEMPLATE (class) = _PRIVATE_record;
1393 /* mark this record as class template - for class type checking */
1394 TREE_STATIC_TEMPLATE (_PRIVATE_record) = 1;
1396 instance_type = groktypename (
1397 build_tree_list (build_tree_list (NULLT, _PRIVATE_record),
1398 build1 (INDIRECT_REF, NULLT, NULLT)));
1399 return ivar_context;
1403 * struct objc_category {
1404 * char *category_name;
1406 * struct objc_method_list *instance_methods;
1407 * struct objc_method_list *class_methods;
1411 build_category_template ()
1413 tree decl_specs, field_decl, field_decl_chain;
1415 objc_category_template = start_struct (RECORD_TYPE,
1416 get_identifier (_TAG_CATEGORY));
1417 /* char *category_name; */
1419 decl_specs = build_tree_list (NULLT, ridpointers[(int) RID_CHAR]);
1420 field_decl = build1 (INDIRECT_REF, NULLT, get_identifier ("category_name"));
1421 field_decl = grokfield (input_filename, lineno, field_decl, decl_specs, NULLT);
1422 field_decl_chain = field_decl;
1424 /* char *class_name; */
1426 decl_specs = build_tree_list (NULLT, ridpointers[(int) RID_CHAR]);
1427 field_decl = build1 (INDIRECT_REF, NULLT, get_identifier ("class_name"));
1428 field_decl = grokfield (input_filename, lineno, field_decl, decl_specs, NULLT);
1429 chainon (field_decl_chain, field_decl);
1431 /* struct objc_method_list *instance_methods; */
1433 decl_specs = build_tree_list (NULLT, xref_tag (RECORD_TYPE,
1434 get_identifier (_TAG_METHOD_LIST)));
1435 field_decl = build1 (INDIRECT_REF, NULLT, get_identifier ("instance_methods"));
1436 field_decl = grokfield (input_filename, lineno, field_decl, decl_specs, NULLT);
1437 chainon (field_decl_chain, field_decl);
1439 /* struct objc_method_list *class_methods; */
1441 decl_specs = build_tree_list (NULLT, xref_tag (RECORD_TYPE,
1442 get_identifier (_TAG_METHOD_LIST)));
1443 field_decl = build1 (INDIRECT_REF, NULLT, get_identifier ("class_methods"));
1444 field_decl = grokfield (input_filename, lineno, field_decl, decl_specs, NULLT);
1445 chainon (field_decl_chain, field_decl);
1447 finish_struct (objc_category_template, field_decl_chain);
1451 * struct objc_class {
1452 * struct objc_class *isa;
1453 * struct objc_class *super_class;
1457 * long instance_size;
1458 * struct objc_ivar_list *ivars;
1459 * struct objc_method_list *methods;
1460 * struct objc_cache *cache;
1464 build_class_template ()
1466 tree decl_specs, field_decl, field_decl_chain;
1468 objc_class_template = start_struct (RECORD_TYPE, get_identifier (_TAG_CLASS));
1470 /* struct objc_class *isa; */
1472 decl_specs = build_tree_list (NULLT, objc_class_template);
1473 field_decl = build1 (INDIRECT_REF, NULLT, get_identifier ("isa"));
1474 field_decl = grokfield (input_filename, lineno, field_decl, decl_specs, NULLT);
1475 field_decl_chain = field_decl;
1477 /* struct objc_class *super_class; */
1479 decl_specs = build_tree_list (NULLT, objc_class_template);
1480 field_decl = build1 (INDIRECT_REF, NULLT, get_identifier ("super_class"));
1481 field_decl = grokfield (input_filename, lineno, field_decl, decl_specs, NULLT);
1482 chainon (field_decl_chain, field_decl);
1486 decl_specs = build_tree_list (NULLT, ridpointers[(int) RID_CHAR]);
1487 field_decl = build1 (INDIRECT_REF, NULLT, get_identifier ("name"));
1488 field_decl = grokfield (input_filename, lineno, field_decl, decl_specs, NULLT);
1489 chainon (field_decl_chain, field_decl);
1493 decl_specs = build_tree_list (NULLT, ridpointers[(int) RID_LONG]);
1494 field_decl = get_identifier ("version");
1495 field_decl = grokfield (input_filename, lineno, field_decl, decl_specs, NULLT);
1496 chainon (field_decl_chain, field_decl);
1500 decl_specs = build_tree_list (NULLT, ridpointers[(int) RID_LONG]);
1501 field_decl = get_identifier ("info");
1502 field_decl = grokfield (input_filename, lineno, field_decl, decl_specs, NULLT);
1503 chainon (field_decl_chain, field_decl);
1505 /* long instance_size; */
1507 decl_specs = build_tree_list (NULLT, ridpointers[(int) RID_LONG]);
1508 field_decl = get_identifier ("instance_size");
1509 field_decl = grokfield (input_filename, lineno, field_decl, decl_specs, NULLT);
1510 chainon (field_decl_chain, field_decl);
1512 /* struct objc_ivar_list *ivars; */
1514 decl_specs = build_tree_list (NULLT, xref_tag (RECORD_TYPE,
1515 get_identifier (_TAG_IVAR_LIST)));
1516 field_decl = build1 (INDIRECT_REF, NULLT, get_identifier ("ivars"));
1517 field_decl = grokfield (input_filename, lineno, field_decl, decl_specs, NULLT);
1518 chainon (field_decl_chain, field_decl);
1520 /* struct objc_method_list *methods; */
1522 decl_specs = build_tree_list (NULLT, xref_tag (RECORD_TYPE,
1523 get_identifier (_TAG_METHOD_LIST)));
1524 field_decl = build1 (INDIRECT_REF, NULLT, get_identifier ("methods"));
1525 field_decl = grokfield (input_filename, lineno, field_decl, decl_specs, NULLT);
1526 chainon (field_decl_chain, field_decl);
1528 /* struct objc_cache *cache; */
1530 decl_specs = build_tree_list (NULLT, xref_tag (RECORD_TYPE,
1531 get_identifier ("objc_cache")));
1532 field_decl = build1 (INDIRECT_REF, NULLT, get_identifier ("cache"));
1533 field_decl = grokfield (input_filename, lineno, field_decl, decl_specs, NULLT);
1534 chainon (field_decl_chain, field_decl);
1536 finish_struct (objc_class_template, field_decl_chain);
1540 * generate appropriate forward declarations for an implementation
1543 synth_forward_declarations ()
1545 tree sc_spec, decl_specs, factory_id, anId;
1547 /* extern struct objc_class _OBJC_CLASS_<my_name>; */
1549 anId = synth_id_with_class_suffix ("_OBJC_CLASS");
1551 sc_spec = build_tree_list (NULLT, ridpointers[(int) RID_EXTERN]);
1552 decl_specs = tree_cons (NULLT, objc_class_template, sc_spec);
1553 _OBJC_CLASS_decl = define_decl (anId, decl_specs);
1555 /* extern struct objc_class _OBJC_METACLASS_<my_name>; */
1557 anId = synth_id_with_class_suffix ("_OBJC_METACLASS");
1559 _OBJC_METACLASS_decl = define_decl (anId, decl_specs);
1561 /* pre-build the following entities - for speed/convenience. */
1563 anId = get_identifier ("super_class");
1564 _clsSuper_ref = build_component_ref (_OBJC_CLASS_decl, anId);
1565 __clsSuper_ref = build_component_ref (_OBJC_METACLASS_decl, anId);
1569 error_with_ivar (message, decl, rawdecl)
1575 fprintf (stderr, "%s:%d: ",
1576 DECL_SOURCE_FILE (decl), DECL_SOURCE_LINE (decl));
1577 bzero (errbuf, BUFSIZE);
1578 fprintf (stderr, "%s `%s'\n", message, gen_declaration (rawdecl, errbuf));
1581 #define USERTYPE(t) (TREE_CODE (t) == RECORD_TYPE || \
1582 TREE_CODE (t) == UNION_TYPE || \
1583 TREE_CODE (t) == ENUMERAL_TYPE)
1586 check_ivars (inter, imp)
1590 tree intdecls = CLASS_IVARS (inter);
1591 tree impdecls = CLASS_IVARS (imp);
1592 tree rawintdecls = CLASS_RAW_IVARS (inter);
1593 tree rawimpdecls = CLASS_RAW_IVARS (imp);
1599 if (intdecls == 0 && impdecls == 0)
1601 if (intdecls == 0 || impdecls == 0)
1603 error ("inconsistent instance variable specification");
1606 t1 = TREE_TYPE (intdecls); t2 = TREE_TYPE (impdecls);
1608 if (!comptypes (t1, t2))
1610 if (DECL_NAME (intdecls) == DECL_NAME (impdecls))
1612 error_with_ivar ("conflicting instance variable type",
1613 impdecls, rawimpdecls);
1614 error_with_ivar ("previous declaration of",
1615 intdecls, rawintdecls);
1617 else /* both the type and the name don't match */
1619 error ("inconsistent instance variable specification");
1623 else if (DECL_NAME (intdecls) != DECL_NAME (impdecls))
1625 error_with_ivar ("conflicting instance variable name",
1626 impdecls, rawimpdecls);
1627 error_with_ivar ("previous declaration of",
1628 intdecls, rawintdecls);
1630 intdecls = TREE_CHAIN (intdecls);
1631 impdecls = TREE_CHAIN (impdecls);
1632 rawintdecls = TREE_CHAIN (rawintdecls);
1633 rawimpdecls = TREE_CHAIN (rawimpdecls);
1637 /* Set super_type to the data type node for struct objc_super *,
1638 first defining struct objc_super itself.
1639 This needs to be done just once per compilation. */
1642 build_super_template ()
1644 tree record, decl_specs, field_decl, field_decl_chain;
1646 record = start_struct (RECORD_TYPE, get_identifier (_TAG_SUPER));
1648 /* struct objc_object *self; */
1650 decl_specs = build_tree_list (NULLT, objc_object_reference);
1651 field_decl = get_identifier ("self");
1652 field_decl = build1 (INDIRECT_REF, NULLT, field_decl);
1653 field_decl = grokfield (input_filename, lineno, field_decl, decl_specs, NULLT);
1654 field_decl_chain = field_decl;
1656 /* struct objc_class *class; */
1658 decl_specs = get_identifier (_TAG_CLASS);
1659 decl_specs = build_tree_list (NULLT, xref_tag (RECORD_TYPE, decl_specs));
1660 field_decl = build1 (INDIRECT_REF, NULLT, get_identifier ("class"));
1662 field_decl = grokfield (input_filename, lineno, field_decl, decl_specs, NULLT);
1663 chainon (field_decl_chain, field_decl);
1665 finish_struct (record, field_decl_chain);
1667 /* `struct objc_super *' */
1668 super_type = groktypename (build_tree_list (build_tree_list (NULLT, record),
1669 build1 (INDIRECT_REF, NULLT, NULLT)));
1674 * struct objc_ivar {
1681 build_ivar_template ()
1683 tree objc_ivar_id, objc_ivar_record;
1684 tree decl_specs, field_decl, field_decl_chain;
1686 objc_ivar_id = get_identifier (_TAG_IVAR);
1687 objc_ivar_record = start_struct (RECORD_TYPE, objc_ivar_id);
1689 /* char *ivar_name; */
1691 decl_specs = build_tree_list (NULLT, ridpointers[(int) RID_CHAR]);
1692 field_decl = build1 (INDIRECT_REF, NULLT, get_identifier ("ivar_name"));
1694 field_decl = grokfield (input_filename, lineno, field_decl, decl_specs, NULLT);
1695 field_decl_chain = field_decl;
1697 /* char *ivar_type; */
1699 decl_specs = build_tree_list (NULLT, ridpointers[(int) RID_CHAR]);
1700 field_decl = build1 (INDIRECT_REF, NULLT, get_identifier ("ivar_type"));
1702 field_decl = grokfield (input_filename, lineno, field_decl, decl_specs, NULLT);
1703 chainon (field_decl_chain, field_decl);
1705 /* int ivar_offset; */
1707 decl_specs = build_tree_list (NULLT, ridpointers[(int) RID_INT]);
1708 field_decl = get_identifier ("ivar_offset");
1710 field_decl = grokfield (input_filename, lineno, field_decl, decl_specs, NULLT);
1711 chainon (field_decl_chain, field_decl);
1713 finish_struct (objc_ivar_record, field_decl_chain);
1715 return objc_ivar_record;
1721 * struct objc_ivar ivar_list[ivar_count];
1725 build_ivar_list_template (list_type, size)
1729 tree objc_ivar_list_id, objc_ivar_list_record;
1730 tree decl_specs, field_decl, field_decl_chain;
1732 objc_ivar_list_record = start_struct (RECORD_TYPE, NULLT);
1734 /* int ivar_count; */
1736 decl_specs = build_tree_list (NULLT, ridpointers[(int) RID_INT]);
1737 field_decl = get_identifier ("ivar_count");
1739 field_decl = grokfield (input_filename, lineno, field_decl, decl_specs, NULLT);
1740 field_decl_chain = field_decl;
1742 /* struct objc_ivar ivar_list[]; */
1744 decl_specs = build_tree_list (NULLT, list_type);
1745 field_decl = build_nt (ARRAY_REF, get_identifier ("ivar_list"),
1746 build_int_2 (size, 0));
1748 field_decl = grokfield (input_filename, lineno, field_decl, decl_specs, NULLT);
1749 chainon (field_decl_chain, field_decl);
1751 finish_struct (objc_ivar_list_record, field_decl_chain);
1753 return objc_ivar_list_record;
1760 * struct objc_method method_list[method_count];
1764 build_method_list_template (list_type, size)
1768 tree objc_ivar_list_id, objc_ivar_list_record;
1769 tree decl_specs, field_decl, field_decl_chain;
1771 objc_ivar_list_record = start_struct (RECORD_TYPE, NULLT);
1773 /* int method_next; */
1775 decl_specs = build_tree_list (NULLT, ridpointers[(int) RID_INT]);
1776 field_decl = get_identifier ("method_next");
1778 field_decl = grokfield (input_filename, lineno, field_decl, decl_specs, NULLT);
1779 field_decl_chain = field_decl;
1781 /* int method_count; */
1783 decl_specs = build_tree_list (NULLT, ridpointers[(int) RID_INT]);
1784 field_decl = get_identifier ("method_count");
1786 field_decl = grokfield (input_filename, lineno, field_decl, decl_specs, NULLT);
1787 chainon (field_decl_chain, field_decl);
1789 /* struct objc_method method_list[]; */
1791 decl_specs = build_tree_list (NULLT, list_type);
1792 field_decl = build_nt (ARRAY_REF, get_identifier ("method_list"),
1793 build_int_2 (size, 0));
1795 field_decl = grokfield (input_filename, lineno, field_decl, decl_specs, NULLT);
1796 chainon (field_decl_chain, field_decl);
1798 finish_struct (objc_ivar_list_record, field_decl_chain);
1800 return objc_ivar_list_record;
1804 build_ivar_list_initializer (field_decl, size)
1808 tree initlist = NULLT;
1815 if (DECL_NAME (field_decl))
1817 offset = add_objc_string (DECL_NAME (field_decl));
1818 initlist = tree_cons (NULLT, build_msg_pool_reference (offset), initlist);
1822 /* unnamed bit-field ivar (yuck). */
1823 initlist = tree_cons (NULLT, build_int_2 (0, 0), initlist);
1827 encode_field_decl (field_decl, OBJC_ENCODE_DONT_INLINE_DEFS);
1828 offset = add_objc_string (get_identifier (obstack_finish (&util_obstack)));
1829 obstack_free (&util_obstack, util_firstobj);
1831 initlist = tree_cons (NULLT, build_msg_pool_reference (offset), initlist);
1834 initlist = tree_cons (NULLT,
1835 build_int_2 (TREE_INT_CST_LOW (DECL_FIELD_BITPOS (field_decl)) / BITS_PER_UNIT, 0),
1839 field_decl = TREE_CHAIN (field_decl);
1843 return build_nt (CONSTRUCTOR, NULLT, nreverse (initlist));
1847 generate_ivars_list (type, name, size, list)
1853 tree sc_spec, decl_specs, decl, initlist;
1855 sc_spec = tree_cons (NULLT, ridpointers[(int) RID_STATIC], NULLT);
1856 decl_specs = tree_cons (NULLT, type, sc_spec);
1858 decl = start_decl (synth_id_with_class_suffix (name), decl_specs, 1);
1860 initlist = build_tree_list (NULLT, build_int_2 (size, 0));
1861 initlist = tree_cons (NULLT, list, initlist);
1863 finish_decl (decl, build_nt (CONSTRUCTOR, NULLT, nreverse (initlist)), NULLT);
1869 generate_ivar_lists ()
1871 tree initlist, ivar_list_template, chain;
1872 tree cast, variable_length_type;
1875 if (!objc_ivar_template)
1876 objc_ivar_template = build_ivar_template ();
1878 cast = build_tree_list (build_tree_list (NULLT, xref_tag (RECORD_TYPE,
1879 get_identifier (_TAG_IVAR_LIST))), NULLT);
1880 variable_length_type = groktypename (cast);
1882 /* only generate class variables for the root of the inheritance
1883 hierarchy since these will be the same for every class */
1885 if (CLASS_SUPER_NAME (implementation_template) == NULLT
1886 && (chain = TYPE_FIELDS (objc_class_template)))
1889 initlist = build_ivar_list_initializer (chain, &size);
1891 ivar_list_template = build_ivar_list_template (objc_ivar_template, size);
1893 _OBJC_CLASS_VARIABLES_decl =
1894 generate_ivars_list (ivar_list_template, "_OBJC_CLASS_VARIABLES",
1897 TREE_TYPE (_OBJC_CLASS_VARIABLES_decl) = variable_length_type;
1900 _OBJC_CLASS_VARIABLES_decl = 0;
1902 chain = CLASS_IVARS (implementation_template);
1906 initlist = build_ivar_list_initializer (chain, &size);
1908 ivar_list_template = build_ivar_list_template (objc_ivar_template, size);
1910 _OBJC_INSTANCE_VARIABLES_decl =
1911 generate_ivars_list (ivar_list_template, "_OBJC_INSTANCE_VARIABLES",
1914 TREE_TYPE (_OBJC_INSTANCE_VARIABLES_decl) = variable_length_type;
1917 _OBJC_INSTANCE_VARIABLES_decl = 0;
1921 build_dispatch_table_initializer (entries, size)
1925 tree initlist = NULLT;
1929 int offset = add_objc_string (METHOD_SEL_NAME (entries));
1931 initlist = tree_cons (NULLT, init_selector (offset), initlist);
1933 offset = add_objc_string (METHOD_ENCODING (entries));
1934 initlist = tree_cons (NULLT, build_msg_pool_reference (offset), initlist);
1936 initlist = tree_cons (NULLT, METHOD_DEFINITION (entries), initlist);
1939 entries = TREE_CHAIN (entries);
1943 return build_nt (CONSTRUCTOR, NULLT, nreverse (initlist));
1947 * To accomplish method prototyping without generating all kinds of
1948 * inane warnings, the definition of the dispatch table entries were
1951 * struct objc_method { SEL _cmd; id (*_imp)(); };
1953 * struct objc_method { SEL _cmd; void *_imp; };
1956 build_method_template ()
1959 tree decl_specs, field_decl, field_decl_chain, parms;
1961 _SLT_record = start_struct (RECORD_TYPE, get_identifier (_TAG_METHOD));
1963 #ifdef OBJC_INT_SELECTORS
1964 /* unsigned int _cmd; */
1965 decl_specs = tree_cons (NULLT, ridpointers[(int) RID_UNSIGNED], NULLT);
1966 decl_specs = tree_cons (NULLT, ridpointers[(int) RID_INT], decl_specs);
1967 field_decl = get_identifier ("_cmd");
1968 #else /* not OBJC_INT_SELECTORS */
1969 /* struct objc_selector *_cmd; */
1970 decl_specs = tree_cons (NULLT,
1971 xref_tag (RECORD_TYPE,
1972 get_identifier (TAG_SELECTOR)),
1974 field_decl = build1 (INDIRECT_REF, NULLT, get_identifier ("_cmd"));
1975 #endif /* not OBJC_INT_SELECTORS */
1977 field_decl = grokfield (input_filename, lineno, field_decl, decl_specs, NULLT);
1978 field_decl_chain = field_decl;
1980 decl_specs = tree_cons (NULLT, ridpointers[(int) RID_CHAR], NULLT);
1981 field_decl = build1 (INDIRECT_REF, NULLT, get_identifier ("method_types"));
1982 field_decl = grokfield (input_filename, lineno, field_decl, decl_specs, NULLT);
1983 chainon (field_decl_chain, field_decl);
1987 decl_specs = tree_cons (NULLT, ridpointers[(int) RID_VOID], NULLT);
1988 field_decl = build1 (INDIRECT_REF, NULLT, get_identifier ("_imp"));
1989 field_decl = grokfield (input_filename, lineno, field_decl, decl_specs, NULLT);
1990 chainon (field_decl_chain, field_decl);
1992 finish_struct (_SLT_record, field_decl_chain);
1999 generate_dispatch_table (type, name, size, list)
2005 tree sc_spec, decl_specs, decl, initlist;
2007 sc_spec = tree_cons (NULLT, ridpointers[(int) RID_STATIC], NULLT);
2008 decl_specs = tree_cons (NULLT, type, sc_spec);
2010 decl = start_decl (synth_id_with_class_suffix (name), decl_specs, 1);
2012 initlist = build_tree_list (NULLT, build_int_2 (0, 0));
2013 initlist = tree_cons (NULLT, build_int_2 (size, 0), initlist);
2014 initlist = tree_cons (NULLT, list, initlist);
2016 finish_decl (decl, build_nt (CONSTRUCTOR, NULLT, nreverse (initlist)), NULLT);
2022 generate_dispatch_tables ()
2024 tree initlist, chain, method_list_template;
2025 tree cast, variable_length_type;
2028 if (!objc_method_template)
2029 objc_method_template = build_method_template ();
2031 cast = build_tree_list (build_tree_list (NULLT, xref_tag (RECORD_TYPE,
2032 get_identifier (_TAG_METHOD_LIST))), NULLT);
2033 variable_length_type = groktypename (cast);
2035 chain = CLASS_CLS_METHODS (implementation_context);
2039 initlist = build_dispatch_table_initializer (chain, &size);
2041 method_list_template = build_method_list_template (objc_method_template,
2043 if (TREE_CODE (implementation_context) == IMPLEMENTATION_TYPE)
2044 _OBJC_CLASS_METHODS_decl =
2045 generate_dispatch_table (method_list_template,
2046 "_OBJC_CLASS_METHODS",
2049 /* we have a category */
2050 _OBJC_CLASS_METHODS_decl =
2051 generate_dispatch_table (method_list_template,
2052 "_OBJC_CATEGORY_CLASS_METHODS",
2055 TREE_TYPE (_OBJC_CLASS_METHODS_decl) = variable_length_type;
2058 _OBJC_CLASS_METHODS_decl = 0;
2060 chain = CLASS_NST_METHODS (implementation_context);
2064 initlist = build_dispatch_table_initializer (chain, &size);
2066 method_list_template = build_method_list_template (objc_method_template,
2068 if (TREE_CODE (implementation_context) == IMPLEMENTATION_TYPE)
2069 _OBJC_INSTANCE_METHODS_decl =
2070 generate_dispatch_table (method_list_template,
2071 "_OBJC_INSTANCE_METHODS",
2074 /* we have a category */
2075 _OBJC_INSTANCE_METHODS_decl =
2076 generate_dispatch_table (method_list_template,
2077 "_OBJC_CATEGORY_INSTANCE_METHODS",
2080 TREE_TYPE (_OBJC_INSTANCE_METHODS_decl) = variable_length_type;
2083 _OBJC_INSTANCE_METHODS_decl = 0;
2087 build_category_initializer (cat_name, class_name,
2088 instance_methods, class_methods)
2091 tree instance_methods;
2094 tree initlist = NULLT, expr;
2096 initlist = tree_cons (NULLT, cat_name, initlist);
2097 initlist = tree_cons (NULLT, class_name, initlist);
2099 if (!instance_methods)
2100 initlist = tree_cons (NULLT, build_int_2 (0, 0), initlist);
2103 expr = build_unary_op (ADDR_EXPR, instance_methods, 0);
2104 initlist = tree_cons (NULLT, expr, initlist);
2107 initlist = tree_cons (NULLT, build_int_2 (0, 0), initlist);
2110 expr = build_unary_op (ADDR_EXPR, class_methods, 0);
2111 initlist = tree_cons (NULLT, expr, initlist);
2113 return build_nt (CONSTRUCTOR, NULLT, nreverse (initlist));
2117 * struct objc_class {
2118 * struct objc_class *isa;
2119 * struct objc_class *super_class;
2123 * long instance_size;
2124 * struct objc_ivar_list *ivars;
2125 * struct objc_method_list *methods;
2126 * struct objc_cache *cache;
2130 build_shared_structure_initializer (isa, super, name, size, status,
2131 dispatch_table, ivar_list)
2137 tree dispatch_table;
2140 tree initlist = NULLT, expr;
2143 initlist = tree_cons (NULLT, isa, initlist);
2146 initlist = tree_cons (NULLT, super, initlist);
2149 initlist = tree_cons (NULLT, name, initlist);
2152 initlist = tree_cons (NULLT, build_int_2 (0, 0), initlist);
2155 initlist = tree_cons (NULLT, build_int_2 (status, 0), initlist);
2157 /* instance_size = */
2158 initlist = tree_cons (NULLT, size, initlist);
2160 /* objc_ivar_list = */
2162 initlist = tree_cons (NULLT, build_int_2 (0, 0), initlist);
2165 expr = build_unary_op (ADDR_EXPR, ivar_list, 0);
2166 initlist = tree_cons (NULLT, expr, initlist);
2169 /* objc_method_list = */
2170 if (!dispatch_table)
2171 initlist = tree_cons (NULLT, build_int_2 (0, 0), initlist);
2174 expr = build_unary_op (ADDR_EXPR, dispatch_table, 0);
2175 initlist = tree_cons (NULLT, expr, initlist);
2178 /* method_cache = */
2179 initlist = tree_cons (NULLT, build_int_2 (0, 0), initlist);
2181 return build_nt (CONSTRUCTOR, NULLT, nreverse (initlist));
2185 * static struct objc_category _OBJC_CATEGORY_<name> = { ... };
2188 generate_category (cat)
2191 tree sc_spec, decl_specs, decl;
2192 tree initlist, cat_name_expr, class_name_expr;
2195 sc_spec = tree_cons (NULLT, ridpointers[(int) RID_STATIC], NULLT);
2196 decl_specs = tree_cons (NULLT, objc_category_template, sc_spec);
2198 decl = start_decl (synth_id_with_class_suffix ("_OBJC_CATEGORY"),
2201 offset = add_objc_string (CLASS_SUPER_NAME (cat));
2202 cat_name_expr = build_msg_pool_reference (offset);
2204 offset = add_objc_string (CLASS_NAME (cat));
2205 class_name_expr = build_msg_pool_reference (offset);
2207 initlist = build_category_initializer (
2208 cat_name_expr, class_name_expr,
2209 _OBJC_INSTANCE_METHODS_decl, _OBJC_CLASS_METHODS_decl);
2211 finish_decl (decl, initlist, NULLT);
2215 * static struct objc_class _OBJC_METACLASS_Foo={ ... };
2216 * static struct objc_class _OBJC_CLASS_Foo={ ... };
2219 generate_shared_structures ()
2221 tree sc_spec, decl_specs, expr_decl, decl;
2222 tree name_expr, super_expr, root_expr;
2223 tree my_root_id = NULLT, my_super_id = NULLT;
2224 tree cast_type, initlist;
2227 my_super_id = CLASS_SUPER_NAME (implementation_template);
2230 add_class_reference (my_super_id);
2232 /* compute "my_root_id" - this is required for code generation.
2233 * the "isa" for all meta class structures points to the root of
2234 * the inheritance hierarchy (e.g. "__Object")...
2236 my_root_id = my_super_id;
2239 tree my_root_int = lookup_interface (my_root_id);
2241 if (my_root_int && CLASS_SUPER_NAME (my_root_int))
2242 my_root_id = CLASS_SUPER_NAME (my_root_int);
2248 else /* no super class */
2250 my_root_id = CLASS_NAME (implementation_template);
2253 cast_type = groktypename (build_tree_list (build_tree_list (NULLT,
2254 objc_class_template), build1 (INDIRECT_REF, NULLT, NULLT)));
2256 offset = add_objc_string (CLASS_NAME (implementation_template));
2257 name_expr = build_msg_pool_reference (offset);
2259 /* install class `isa' and `super' pointers at runtime */
2262 offset = add_objc_string (my_super_id);
2263 super_expr = build_msg_pool_reference (offset);
2264 TREE_TYPE (super_expr) = cast_type; /* cast! */
2267 super_expr = build_int_2 (0, 0);
2269 offset = add_objc_string (my_root_id);
2270 root_expr = build_msg_pool_reference (offset);
2271 TREE_TYPE (root_expr) = cast_type; /* cast! */
2273 /* static struct objc_class _OBJC_METACLASS_Foo = { ... }; */
2275 sc_spec = build_tree_list (NULLT, ridpointers[(int) RID_STATIC]);
2276 decl_specs = tree_cons (NULLT, objc_class_template, sc_spec);
2278 decl = start_decl (DECL_NAME (_OBJC_METACLASS_decl), decl_specs, 1);
2280 initlist = build_shared_structure_initializer (
2281 root_expr, super_expr, name_expr,
2282 build_int_2 (TREE_INT_CST_LOW (TYPE_SIZE (objc_class_template)) / BITS_PER_UNIT, 0),
2284 _OBJC_CLASS_METHODS_decl, _OBJC_CLASS_VARIABLES_decl);
2286 finish_decl (decl, initlist, NULLT);
2288 /* static struct objc_class _OBJC_CLASS_Foo={ ... }; */
2290 decl = start_decl (DECL_NAME (_OBJC_CLASS_decl), decl_specs, 1);
2292 initlist = build_shared_structure_initializer (
2293 build_unary_op (ADDR_EXPR, _OBJC_METACLASS_decl, 0),
2294 super_expr, name_expr,
2295 build_int_2 (TREE_INT_CST_LOW (TYPE_SIZE (CLASS_STATIC_TEMPLATE (implementation_template))) / BITS_PER_UNIT, 0),
2297 _OBJC_INSTANCE_METHODS_decl, _OBJC_INSTANCE_VARIABLES_decl);
2299 finish_decl (decl, initlist, NULLT);
2303 synth_id_with_class_suffix (preamble)
2307 if (TREE_CODE (implementation_context) == IMPLEMENTATION_TYPE)
2309 string = (char *) alloca (strlen (preamble)
2310 + strlen (IDENTIFIER_POINTER (CLASS_NAME (implementation_context)))
2312 sprintf (string, "%s_%s", preamble,
2313 IDENTIFIER_POINTER (CLASS_NAME (implementation_context)));
2317 /* we have a category */
2318 string = (char *) alloca (strlen (preamble)
2319 + strlen (IDENTIFIER_POINTER (CLASS_NAME (implementation_context)))
2320 + strlen (IDENTIFIER_POINTER (CLASS_SUPER_NAME (implementation_context)))
2322 sprintf (string, "%s_%s_%s", preamble,
2323 IDENTIFIER_POINTER (CLASS_NAME (implementation_context)),
2324 IDENTIFIER_POINTER (CLASS_SUPER_NAME (implementation_context)));
2326 return get_identifier (string);
2332 * selector ':' '(' typename ')' identifier
2335 * transform an Objective-C keyword argument into
2336 * the C equivalent parameter declarator.
2338 * in: key_name, an "identifier_node" (optional).
2339 * arg_type, a "tree_list" (optional).
2340 * arg_name, an "identifier_node".
2342 * note: it would be really nice to strongly type the preceding
2343 * arguments in the function prototype; however, then i
2344 * could not use the "accessor" macros defined in "tree.h".
2346 * out: an instance of "keyword_decl".
2351 build_keyword_decl (key_name, arg_type, arg_name)
2358 /* if no type is specified, default to "id" */
2359 if (arg_type == NULLT)
2360 arg_type = build_tree_list (build_tree_list (NULLT, objc_object_reference),
2361 build1 (INDIRECT_REF, NULLT, NULLT));
2363 keyword_decl = make_node (KEYWORD_DECL);
2365 TREE_TYPE (keyword_decl) = arg_type;
2366 KEYWORD_ARG_NAME (keyword_decl) = arg_name;
2367 KEYWORD_KEY_NAME (keyword_decl) = key_name;
2369 return keyword_decl;
2373 * given a chain of keyword_decl's, synthesize the full keyword selector.
2376 build_keyword_selector (selector)
2380 tree key_chain, key_name;
2383 for (key_chain = selector; key_chain; key_chain = TREE_CHAIN (key_chain))
2385 if (TREE_CODE (selector) == KEYWORD_DECL)
2386 key_name = KEYWORD_KEY_NAME (key_chain);
2387 else if (TREE_CODE (selector) == TREE_LIST)
2388 key_name = TREE_PURPOSE (key_chain);
2391 len += IDENTIFIER_LENGTH (key_name) + 1;
2392 else /* just a ':' arg */
2395 buf = (char *)alloca (len + 1);
2396 bzero (buf, len + 1);
2398 for (key_chain = selector; key_chain; key_chain = TREE_CHAIN (key_chain))
2400 if (TREE_CODE (selector) == KEYWORD_DECL)
2401 key_name = KEYWORD_KEY_NAME (key_chain);
2402 else if (TREE_CODE (selector) == TREE_LIST)
2403 key_name = TREE_PURPOSE (key_chain);
2406 strcat (buf, IDENTIFIER_POINTER (key_name));
2409 return get_identifier (buf);
2412 /* used for declarations and definitions */
2415 build_method_decl (code, ret_type, selector, add_args)
2416 enum tree_code code;
2423 /* if no type is specified, default to "id" */
2424 if (ret_type == NULLT)
2425 ret_type = build_tree_list (build_tree_list (NULLT, objc_object_reference),
2426 build1 (INDIRECT_REF, NULLT, NULLT));
2428 method_decl = make_node (code);
2429 TREE_TYPE (method_decl) = ret_type;
2432 * if we have a keyword selector, create an identifier_node that
2433 * represents the full selector name (`:' included)...
2435 if (TREE_CODE (selector) == KEYWORD_DECL)
2437 METHOD_SEL_NAME (method_decl) = build_keyword_selector (selector);
2438 METHOD_SEL_ARGS (method_decl) = selector;
2439 METHOD_ADD_ARGS (method_decl) = add_args;
2443 METHOD_SEL_NAME (method_decl) = selector;
2444 METHOD_SEL_ARGS (method_decl) = NULLT;
2445 METHOD_ADD_ARGS (method_decl) = NULLT;
2451 #define METHOD_DEF 0
2452 #define METHOD_REF 1
2453 /* Used by `build_message_expr' and `comp_method_types'.
2454 Return an argument list for method METH.
2455 CONTEXT is either METHOD_DEF or METHOD_REF,
2456 saying whether we are trying to define a method or call one.
2457 SUPERFLAG says this is for a send to super;
2458 this makes a difference for the NeXT calling sequence
2459 in which the lookup and the method call are done together. */
2462 get_arg_type_list (meth, context, superflag)
2469 #ifdef NEXT_OBJC_RUNTIME
2473 arglist = build_tree_list (NULLT, super_type);
2478 if (context == METHOD_DEF)
2479 arglist = build_tree_list (NULLT, TREE_TYPE (self_decl));
2481 arglist = build_tree_list (NULLT, id_type);
2484 /* selector type - will eventually change to `int' */
2485 chainon (arglist, build_tree_list (NULLT, selector_type));
2487 /* build a list of argument types */
2488 for (akey = METHOD_SEL_ARGS (meth); akey; akey = TREE_CHAIN (akey))
2490 tree arg_decl = groktypename_in_parm_context (TREE_TYPE (akey));
2491 chainon (arglist, build_tree_list (NULLT, TREE_TYPE (arg_decl)));
2494 if (METHOD_ADD_ARGS (meth) == (tree)1)
2496 * we have a `, ...' immediately following the selector,
2497 * finalize the arglist...simulate get_parm_info (0)
2500 else if (METHOD_ADD_ARGS (meth))
2502 /* we have a variable length selector */
2503 tree add_arg_list = TREE_CHAIN (METHOD_ADD_ARGS (meth));
2504 chainon (arglist, add_arg_list);
2506 else /* finalize the arglist...simulate get_parm_info (1) */
2507 chainon (arglist, build_tree_list (NULLT, void_type_node));
2513 check_duplicates (hsh)
2524 /* we have two methods with the same name and different types */
2528 type = (TREE_CODE (meth) == INSTANCE_METHOD_DECL) ? '-' : '+';
2530 warning ("multiple declarations for method `%s'",
2531 IDENTIFIER_POINTER (METHOD_SEL_NAME (meth)));
2533 warn_with_method ("using", type, meth);
2534 for (loop = hsh->list; loop; loop = loop->next)
2535 warn_with_method ("also found", type, loop->value);
2542 receiver_is_class_object (receiver)
2545 /* the receiver is a function call that returns an id...
2546 * ...check if it is a call to objc_getClass, if so, give it
2547 * special treatment.
2549 tree exp = TREE_OPERAND (receiver, 0);
2551 if (exp != 0 && (TREE_CODE (exp) == ADDR_EXPR))
2553 exp = TREE_OPERAND (exp, 0);
2555 && TREE_CODE (exp) == FUNCTION_DECL && exp == objc_getClass_decl)
2557 /* we have a call to objc_getClass! */
2558 tree arg = TREE_OPERAND (receiver, 1);
2561 && TREE_CODE (arg) == TREE_LIST
2562 && (arg = TREE_VALUE (arg))
2563 && TREE_CODE (arg) == NOP_EXPR
2564 && (arg = TREE_OPERAND (arg, 0))
2565 && TREE_CODE (arg) == ADDR_EXPR
2566 && (arg = TREE_OPERAND (arg, 0))
2567 && TREE_CODE (arg) == STRING_CST)
2568 /* finally, we have the class name */
2569 return get_identifier (TREE_STRING_POINTER (arg));
2575 /* If we are currently building a message expr, this holds
2576 the identifier of the selector of the message. This is
2577 used when printing warnings about argument mismatches. */
2579 static tree building_objc_message_expr = 0;
2582 maybe_building_objc_message_expr ()
2584 return building_objc_message_expr;
2587 /* Construct an expression for sending a message.
2588 MESS has the object to send to in TREE_PURPOSE
2589 and the argument list (including selector) in TREE_VALUE. */
2592 build_message_expr (mess)
2595 tree receiver = TREE_PURPOSE (mess);
2596 tree selector, self_object;
2597 tree rtype, sel_name;
2598 tree args = TREE_VALUE (mess);
2599 tree method_params = NULLT;
2600 tree method_prototype = NULLT;
2601 int selTransTbl_index;
2603 int statically_typed = 0, statically_allocated = 0;
2604 tree class_ident = 0;
2606 /* 1 if this is sending to the superclass. */
2609 if (!doing_objc_thang)
2610 fatal ("Objective-C text in C source file");
2612 if (TREE_CODE (receiver) == ERROR_MARK)
2613 return error_mark_node;
2615 /* determine receiver type */
2616 rtype = TREE_TYPE (receiver);
2617 super = (TREE_TYPE (receiver) == super_type);
2621 if (TREE_STATIC_TEMPLATE (rtype))
2622 statically_allocated = 1;
2623 else if (TREE_CODE (rtype) == POINTER_TYPE
2624 && TREE_STATIC_TEMPLATE (TREE_TYPE (rtype)))
2625 statically_typed = 1;
2627 else if (TREE_CODE (receiver) == CALL_EXPR && rtype == id_type
2628 && (class_ident = receiver_is_class_object (receiver)))
2630 else if (TYPE_MAIN_VARIANT (rtype) != TYPE_MAIN_VARIANT (id_type)
2631 && TYPE_MAIN_VARIANT (rtype) != TYPE_MAIN_VARIANT (class_type))
2633 bzero (errbuf, BUFSIZE);
2634 warning ("invalid receiver type `%s'", gen_declaration (rtype, errbuf));
2636 if (statically_allocated)
2637 receiver = build_unary_op (ADDR_EXPR, receiver, 0);
2639 /* Don't evaluate the receiver twice. */
2640 receiver = save_expr (receiver);
2641 self_object = receiver;
2644 /* If sending to `super', use current self as the object. */
2645 self_object = self_decl;
2647 /* Obtain the full selector name. */
2649 if (TREE_CODE (args) == IDENTIFIER_NODE)
2650 /* a unary selector */
2652 else if (TREE_CODE (args) == TREE_LIST)
2653 sel_name = build_keyword_selector (args);
2655 selTransTbl_index = add_selector_reference (sel_name);
2657 /* Build the parameters list for looking up the method.
2658 These are the object itself and the selector. */
2660 #ifndef OBJC_SELECTORS_WITHOUT_LABELS
2661 selector = build_selector_reference (selTransTbl_index);
2663 selector = build_array_ref (_OBJC_SELECTOR_REFERENCES_decl,
2664 build_int_2 (selTransTbl_index, 0));
2667 /* Build the parameter list to give to the method. */
2669 method_params = NULLT;
2670 if (TREE_CODE (args) == TREE_LIST)
2672 tree chain = args, prev = NULLT;
2674 /* We have a keyword selector--check for comma expressions. */
2677 tree element = TREE_VALUE (chain);
2679 /* We have a comma expression, must collapse... */
2680 if (TREE_CODE (element) == TREE_LIST)
2683 TREE_CHAIN (prev) = element;
2688 chain = TREE_CHAIN (chain);
2690 method_params = args;
2693 /* Determine operation return type. */
2696 && 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 obstack_1grow (&util_obstack, 0); /* null terminate string */
2954 string = obstack_finish (&util_obstack);
2956 /* synthesize a string that represents the encoded struct/union */
2957 result = my_build_string (strlen (string) + 1, string);
2958 obstack_free (&util_obstack, util_firstobj);
2963 build_ivar_reference (id)
2966 if (TREE_CODE (method_context) == CLASS_METHOD_DECL)
2967 TREE_TYPE (self_decl) = instance_type; /* cast */
2969 return build_component_ref (build_indirect_ref (self_decl, "->"), id);
2972 #define HASH_ALLOC_LIST_SIZE 170
2973 #define ATTR_ALLOC_LIST_SIZE 170
2974 #define SIZEHASHTABLE 257
2975 #define HASHFUNCTION(key) ((int)key >> 2) /* divide by 4 */
2980 nst_method_hash_list = (hash *)xmalloc (SIZEHASHTABLE * sizeof (hash));
2981 cls_method_hash_list = (hash *)xmalloc (SIZEHASHTABLE * sizeof (hash));
2983 if (!nst_method_hash_list || !cls_method_hash_list)
2984 perror ("unable to allocate space in objc-tree.c");
2989 for (i = 0; i < SIZEHASHTABLE; i++)
2991 nst_method_hash_list[i] = 0;
2992 cls_method_hash_list[i] = 0;
2998 hash_enter (hashlist, method)
3002 static hash hash_alloc_list = 0;
3003 static int hash_alloc_index = 0;
3005 int slot = HASHFUNCTION (METHOD_SEL_NAME (method)) % SIZEHASHTABLE;
3007 if (!hash_alloc_list || hash_alloc_index >= HASH_ALLOC_LIST_SIZE)
3009 hash_alloc_index = 0;
3010 hash_alloc_list = (hash)xmalloc (sizeof (struct hashedEntry) *
3011 HASH_ALLOC_LIST_SIZE);
3012 if (!hash_alloc_list)
3013 perror ("unable to allocate in objc-tree.c");
3015 obj = &hash_alloc_list[hash_alloc_index++];
3017 obj->next = hashlist[slot];
3020 hashlist[slot] = obj; /* append to front */
3024 hash_lookup (hashlist, sel_name)
3030 target = hashlist[HASHFUNCTION (sel_name) % SIZEHASHTABLE];
3034 if (sel_name == METHOD_SEL_NAME (target->key))
3037 target = target->next;
3043 hash_add_attr (entry, value)
3047 static attr attr_alloc_list = 0;
3048 static int attr_alloc_index = 0;
3051 if (!attr_alloc_list || attr_alloc_index >= ATTR_ALLOC_LIST_SIZE)
3053 attr_alloc_index = 0;
3054 attr_alloc_list = (attr)xmalloc (sizeof (struct hashedAttribute) *
3055 ATTR_ALLOC_LIST_SIZE);
3056 if (!attr_alloc_list)
3057 perror ("unable to allocate in objc-tree.c");
3059 obj = &attr_alloc_list[attr_alloc_index++];
3060 obj->next = entry->list;
3063 entry->list = obj; /* append to front */
3067 lookup_method (mchain, method)
3073 if (TREE_CODE (method) == IDENTIFIER_NODE)
3076 key = METHOD_SEL_NAME (method);
3080 if (METHOD_SEL_NAME (mchain) == key)
3082 mchain = TREE_CHAIN (mchain);
3088 lookup_instance_method_static (interface, ident)
3092 tree inter = interface;
3093 tree chain = CLASS_NST_METHODS (inter);
3098 if (meth = lookup_method (chain, ident))
3101 if (CLASS_CATEGORY_LIST (inter))
3103 tree category = CLASS_CATEGORY_LIST (inter);
3104 chain = CLASS_NST_METHODS (category);
3108 if (meth = lookup_method (chain, ident))
3111 if (category = CLASS_CATEGORY_LIST (category))
3112 chain = CLASS_NST_METHODS (category);
3117 if (inter = lookup_interface (CLASS_SUPER_NAME (inter)))
3118 chain = CLASS_NST_METHODS (inter);
3126 lookup_class_method_static (interface, ident)
3130 tree inter = interface;
3131 tree chain = CLASS_CLS_METHODS (inter);
3136 if (meth = lookup_method (chain, ident))
3139 if (CLASS_CATEGORY_LIST (inter))
3141 tree category = CLASS_CATEGORY_LIST (inter);
3142 chain = CLASS_CLS_METHODS (category);
3146 if (meth = lookup_method (chain, ident))
3149 if (category = CLASS_CATEGORY_LIST (category))
3150 chain = CLASS_CLS_METHODS (category);
3155 if (inter = lookup_interface (CLASS_SUPER_NAME (inter)))
3156 chain = CLASS_CLS_METHODS (inter);
3164 add_class_method (class, method)
3171 if (!(mth = lookup_method (CLASS_CLS_METHODS (class), method)))
3173 /* put method on list in reverse order */
3174 TREE_CHAIN (method) = CLASS_CLS_METHODS (class);
3175 CLASS_CLS_METHODS (class) = method;
3179 if (TREE_CODE (class) == IMPLEMENTATION_TYPE)
3180 error ("duplicate definition of class method `%s'.",
3181 IDENTIFIER_POINTER (METHOD_SEL_NAME (mth)));
3184 /* check types, if different complain */
3185 if (!comp_proto_with_proto (method, mth))
3186 error ("duplicate declaration of class method `%s'.",
3187 IDENTIFIER_POINTER (METHOD_SEL_NAME (mth)));
3191 if (!(hsh = hash_lookup (cls_method_hash_list, METHOD_SEL_NAME (method))))
3193 /* install on a global chain */
3194 hash_enter (cls_method_hash_list, method);
3198 /* check types, if different add to a list */
3199 if (!comp_proto_with_proto (method, hsh->key))
3200 hash_add_attr (hsh, method);
3206 add_instance_method (class, method)
3213 if (!(mth = lookup_method (CLASS_NST_METHODS (class), method)))
3215 /* put method on list in reverse order */
3216 TREE_CHAIN (method) = CLASS_NST_METHODS (class);
3217 CLASS_NST_METHODS (class) = method;
3221 if (TREE_CODE (class) == IMPLEMENTATION_TYPE)
3222 error ("duplicate definition of instance method `%s'.",
3223 IDENTIFIER_POINTER (METHOD_SEL_NAME (mth)));
3226 /* check types, if different complain */
3227 if (!comp_proto_with_proto (method, mth))
3228 error ("duplicate declaration of instance method `%s'.",
3229 IDENTIFIER_POINTER (METHOD_SEL_NAME (mth)));
3233 if (!(hsh = hash_lookup (nst_method_hash_list, METHOD_SEL_NAME (method))))
3235 /* install on a global chain */
3236 hash_enter (nst_method_hash_list, method);
3240 /* check types, if different add to a list */
3241 if (!comp_proto_with_proto (method, hsh->key))
3242 hash_add_attr (hsh, method);
3251 /* put interfaces on list in reverse order */
3252 TREE_CHAIN (class) = interface_chain;
3253 interface_chain = class;
3254 return interface_chain;
3258 add_category (class, category)
3262 /* put categories on list in reverse order */
3263 CLASS_CATEGORY_LIST (category) = CLASS_CATEGORY_LIST (class);
3264 CLASS_CATEGORY_LIST (class) = category;
3267 /* called after parsing each instance variable declaration. Necessary to
3268 * preserve typedefs and implement public/private...
3271 add_instance_variable (class, public, declarator, declspecs, width)
3278 tree field_decl, raw_decl;
3280 raw_decl = build_tree_list (declspecs /*purpose*/, declarator/*value*/);
3282 if (CLASS_RAW_IVARS (class))
3283 chainon (CLASS_RAW_IVARS (class), raw_decl);
3285 CLASS_RAW_IVARS (class) = raw_decl;
3287 field_decl = grokfield (input_filename, lineno,
3288 declarator, declspecs, width);
3290 /* overload the public attribute, it is not used for FIELD_DECL's */
3292 TREE_PUBLIC (field_decl) = 1;
3294 if (CLASS_IVARS (class))
3295 chainon (CLASS_IVARS (class), field_decl);
3297 CLASS_IVARS (class) = field_decl;
3303 is_ivar (decl_chain, ident)
3307 for ( ; decl_chain; decl_chain = TREE_CHAIN (decl_chain))
3308 if (DECL_NAME (decl_chain) == ident)
3313 /* we have an instance variable reference, check to see if it is public...*/
3316 is_public (expr, identifier)
3320 tree basetype = TREE_TYPE (expr);
3321 enum tree_code code = TREE_CODE (basetype);
3324 if (code == RECORD_TYPE)
3326 if (TREE_STATIC_TEMPLATE (basetype))
3328 if (decl = is_ivar (TYPE_FIELDS (basetype), identifier))
3330 /* important difference between the Stepstone translator:
3332 all instance variables should be public within the context
3333 of the implementation...
3335 if (implementation_context)
3337 if ((TREE_CODE (implementation_context) == IMPLEMENTATION_TYPE
3338 && CLASS_NAME (implementation_context) == TYPE_NAME (basetype))
3339 || (TREE_CODE (implementation_context) == CATEGORY_TYPE
3340 && CLASS_NAME (implementation_context) == TYPE_NAME (basetype)))
3344 if (TREE_PUBLIC (decl))
3347 error ("instance variable `%s' is declared private",
3348 IDENTIFIER_POINTER (identifier));
3352 else if (implementation_context && (basetype == objc_object_reference))
3354 TREE_TYPE (expr) = _PRIVATE_record;
3357 warning ("static access to object of type `id'");
3358 warning ("please change to type `%s *'",
3359 IDENTIFIER_POINTER (CLASS_NAME (implementation_context)));
3366 /* implement @defs (<classname>) within struct bodies. */
3369 get_class_ivars (interface)
3372 if (!doing_objc_thang)
3373 fatal ("Objective-C text in C source file");
3375 return build_ivar_chain (interface);
3379 get_class_reference (interface)
3384 add_class_reference (CLASS_NAME (interface));
3386 params = build_tree_list (NULLT,
3387 my_build_string (IDENTIFIER_LENGTH (CLASS_NAME (interface)) + 1,
3388 IDENTIFIER_POINTER (CLASS_NAME (interface))));
3390 return build_function_call (objc_getClass_decl, params);
3393 /* make sure all entries in "chain" are also in "list" */
3396 check_methods (chain, list, mtype)
3405 if (!lookup_method (list, chain))
3409 if (TREE_CODE (implementation_context) == IMPLEMENTATION_TYPE)
3410 warning ("incomplete implementation of class `%s'",
3411 IDENTIFIER_POINTER (CLASS_NAME (implementation_context)));
3412 else if (TREE_CODE (implementation_context) == CATEGORY_TYPE)
3413 warning ("incomplete implementation of category `%s'",
3414 IDENTIFIER_POINTER (CLASS_SUPER_NAME (implementation_context)));
3417 warning ("method definition for `%c%s' not found",
3418 mtype, IDENTIFIER_POINTER (METHOD_SEL_NAME (chain)));
3420 chain = TREE_CHAIN (chain);
3424 /* Make sure that the class CLASS_NAME is defined
3425 CODE says which kind of thing CLASS_NAME ought to be.
3426 It can be INTERFACE_TYPE, IMPLEMENTATION_TYPE, PROTOCOL_TYPE
3429 If CODE is INTERFACE_TYPE, we also do a push_obstacks_nochange
3430 whose matching pop is in continue_class. */
3433 start_class (code, class_name, super_name)
3434 enum tree_code code;
3440 if (code == INTERFACE_TYPE)
3442 push_obstacks_nochange ();
3443 end_temporary_allocation ();
3446 if (!doing_objc_thang)
3447 fatal ("Objective-C text in C source file");
3449 class = make_node (code);
3451 CLASS_NAME (class) = class_name;
3452 CLASS_SUPER_NAME (class) = super_name;
3453 CLASS_CLS_METHODS (class) = NULL_TREE;
3455 if (code == IMPLEMENTATION_TYPE)
3457 /* pre-build the following entities - for speed/convenience. */
3459 self_id = get_identifier ("self");
3461 _cmd_id = get_identifier ("_cmd");
3463 if (!objc_super_template)
3464 objc_super_template = build_super_template ();
3466 method_slot = 0; /* reset for multiple classes per file */
3468 implementation_context = class;
3470 /* lookup the interface for this implementation. */
3472 if (!(implementation_template = lookup_interface (class_name)))
3474 warning ("Cannot find interface declaration for `%s'",
3475 IDENTIFIER_POINTER (class_name));
3476 add_class (implementation_template = implementation_context);
3479 /* if a super class has been specified in the implementation,
3480 insure it conforms to the one specified in the interface */
3483 && (super_name != CLASS_SUPER_NAME (implementation_template)))
3485 error ("conflicting super class name `%s'",
3486 IDENTIFIER_POINTER (super_name));
3487 error ("previous declaration of `%s'",
3488 IDENTIFIER_POINTER (CLASS_SUPER_NAME (implementation_template)));
3491 else if (code == INTERFACE_TYPE)
3493 if (lookup_interface (class_name))
3494 warning ("duplicate interface declaration for class `%s'",
3495 IDENTIFIER_POINTER (class_name));
3499 else if (code == PROTOCOL_TYPE)
3501 tree class_category_is_assoc_with;
3503 /* for a category, class_name is really the name of the class that
3504 the following set of methods will be associated with...we must
3505 find the interface so that can derive the objects template */
3507 if (!(class_category_is_assoc_with = lookup_interface (class_name)))
3509 error ("Cannot find interface declaration for `%s'",
3510 IDENTIFIER_POINTER (class_name));
3514 add_category (class_category_is_assoc_with, class);
3516 else if (code == CATEGORY_TYPE)
3518 /* pre-build the following entities - for speed/convenience. */
3520 self_id = get_identifier ("self");
3522 _cmd_id = get_identifier ("_cmd");
3524 if (!objc_super_template)
3525 objc_super_template = build_super_template ();
3527 method_slot = 0; /* reset for multiple classes per file */
3529 implementation_context = class;
3531 /* for a category, class_name is really the name of the class that
3532 the following set of methods will be associated with...we must
3533 find the interface so that can derive the objects template */
3535 if (!(implementation_template = lookup_interface (class_name)))
3537 error ("Cannot find interface declaration for `%s'",
3538 IDENTIFIER_POINTER (class_name));
3546 continue_class (class)
3549 if (TREE_CODE (class) == IMPLEMENTATION_TYPE
3550 || TREE_CODE (class) == CATEGORY_TYPE)
3552 struct imp_entry *impEntry;
3555 /* check consistency of the instance variables. */
3557 if (CLASS_IVARS (class))
3558 check_ivars (implementation_template, class);
3560 /* code generation */
3562 ivar_context = build_private_template (implementation_template);
3564 if (!objc_class_template)
3565 build_class_template ();
3567 if (!(impEntry = (struct imp_entry *)xmalloc (sizeof (struct imp_entry))))
3568 perror ("unable to allocate in objc-tree.c");
3570 impEntry->next = imp_list;
3571 impEntry->imp_context = class;
3572 impEntry->imp_template = implementation_template;
3574 synth_forward_declarations ();
3575 impEntry->class_decl = _OBJC_CLASS_decl;
3576 impEntry->meta_decl = _OBJC_METACLASS_decl;
3578 /* append to front and increment count */
3579 imp_list = impEntry;
3580 if (TREE_CODE (class) == IMPLEMENTATION_TYPE)
3585 return ivar_context;
3587 else if (TREE_CODE (class) == INTERFACE_TYPE)
3589 tree record = xref_tag (RECORD_TYPE, CLASS_NAME (class));
3591 if (!TYPE_FIELDS (record))
3593 finish_struct (record, build_ivar_chain (class));
3594 CLASS_STATIC_TEMPLATE (class) = record;
3596 /* mark this record as a class template - for static typing */
3597 TREE_STATIC_TEMPLATE (record) = 1;
3602 return error_mark_node;
3606 * this is called once we see the "@end" in an interface/implementation.
3609 finish_class (class)
3612 if (TREE_CODE (class) == IMPLEMENTATION_TYPE)
3614 /* all code generation is done in finish_objc */
3616 if (implementation_template != implementation_context)
3618 /* ensure that all method listed in the interface contain bodies! */
3619 check_methods (CLASS_CLS_METHODS (implementation_template),
3620 CLASS_CLS_METHODS (implementation_context), '+');
3621 check_methods (CLASS_NST_METHODS (implementation_template),
3622 CLASS_NST_METHODS (implementation_context), '-');
3625 else if (TREE_CODE (class) == CATEGORY_TYPE)
3627 tree category = CLASS_CATEGORY_LIST (implementation_template);
3629 /* find the category interface from the class it is associated with */
3632 if (CLASS_SUPER_NAME (class) == CLASS_SUPER_NAME (category))
3634 category = CLASS_CATEGORY_LIST (category);
3639 /* ensure that all method listed in the interface contain bodies! */
3640 check_methods (CLASS_CLS_METHODS (category),
3641 CLASS_CLS_METHODS (implementation_context), '+');
3642 check_methods (CLASS_NST_METHODS (category),
3643 CLASS_NST_METHODS (implementation_context), '-');
3646 else if (TREE_CODE (class) == INTERFACE_TYPE)
3649 char *string = (char *) alloca (strlen (IDENTIFIER_POINTER (CLASS_NAME (class))) + 3);
3651 /* extern struct objc_object *_<my_name>; */
3653 sprintf (string, "_%s", IDENTIFIER_POINTER (CLASS_NAME (class)));
3655 decl_specs = build_tree_list (NULLT, ridpointers[(int) RID_EXTERN]);
3656 decl_specs = tree_cons (NULLT, objc_object_reference, decl_specs);
3657 define_decl (build1 (INDIRECT_REF, NULLT, get_identifier (string)),
3662 /* "Encode" a data type into a string, whichg rows in util_obstack.
3663 ??? What is the FORMAT? Someone please document this! */
3665 /* Encode a pointer type. */
3668 encode_pointer (type, format)
3672 tree pointer_to = TREE_TYPE (type);
3674 if (TREE_CODE (pointer_to) == RECORD_TYPE)
3676 if (TYPE_NAME (pointer_to)
3677 && TREE_CODE (TYPE_NAME (pointer_to)) == IDENTIFIER_NODE)
3679 char *name = IDENTIFIER_POINTER (TYPE_NAME (pointer_to));
3681 if ((strcmp (name, TAG_OBJECT) == 0) /* '@' */
3682 || TREE_STATIC_TEMPLATE (pointer_to))
3684 obstack_1grow (&util_obstack, '@');
3687 else if (strcmp (name, TAG_CLASS) == 0) /* '#' */
3689 obstack_1grow (&util_obstack, '#');
3692 #ifndef OBJC_INT_SELECTORS
3693 else if (strcmp (name, TAG_SELECTOR) == 0) /* ':' */
3695 obstack_1grow (&util_obstack, ':');
3698 #endif /* OBJC_INT_SELECTORS */
3701 else if (TREE_CODE (pointer_to) == INTEGER_TYPE
3702 && TYPE_MODE (pointer_to) == QImode)
3704 obstack_1grow (&util_obstack, '*');
3708 /* we have a type that does not get special treatment... */
3710 /* NeXT extension */
3711 obstack_1grow (&util_obstack, '^');
3712 encode_type (pointer_to, format);
3716 encode_array (type, format)
3720 tree anIntCst = TYPE_SIZE (type);
3721 tree array_of = TREE_TYPE (type);
3724 /* An incomplete array is treated like a pointer. */
3725 if (anIntCst == NULL)
3727 /* split for obvious reasons. North-Keys 30 Mar 1991 */
3728 encode_pointer (type, format);
3732 sprintf (buffer, "[%d",
3733 TREE_INT_CST_LOW (anIntCst)
3734 / TREE_INT_CST_LOW (TYPE_SIZE (array_of)));
3735 obstack_grow (&util_obstack, buffer, strlen (buffer));
3736 encode_type (array_of, format);
3737 obstack_1grow (&util_obstack, ']');
3742 encode_aggregate (type, format)
3746 enum tree_code code = TREE_CODE (type);
3752 int have_pointer = 0;
3754 if (obstack_object_size (&util_obstack) > 0
3755 && *(obstack_next_free (&util_obstack)-1) == '^')
3758 obstack_1grow (&util_obstack, '{');
3759 if (TYPE_NAME (type))
3761 if (TREE_CODE (TYPE_NAME (type)) == IDENTIFIER_NODE)
3763 obstack_grow (&util_obstack,
3764 IDENTIFIER_POINTER (TYPE_NAME (type)),
3765 strlen (IDENTIFIER_POINTER (TYPE_NAME (type))));
3767 else /* we have an untagged structure or a typedef */
3769 obstack_1grow (&util_obstack, '?');
3774 || format == OBJC_ENCODE_DONT_INLINE_DEFS)
3776 /* we have a pointer
3777 or we don't want the details. */
3778 obstack_1grow (&util_obstack, '}');
3782 tree fields = TYPE_FIELDS (type);
3783 obstack_1grow (&util_obstack, '=');
3784 for ( ; fields; fields = TREE_CHAIN (fields))
3785 encode_field_decl (fields, format);
3786 obstack_1grow (&util_obstack, '}');
3793 int have_pointer = 0;
3795 if (obstack_object_size (&util_obstack) > 0
3796 && *(obstack_next_free (&util_obstack)-1) == '^')
3799 obstack_1grow (&util_obstack, '(');
3800 if (have_pointer && TYPE_NAME (type))
3802 if (TREE_CODE (TYPE_NAME (type)) == IDENTIFIER_NODE)
3804 obstack_grow (&util_obstack,
3805 IDENTIFIER_POINTER (TYPE_NAME (type)),
3806 strlen (IDENTIFIER_POINTER (TYPE_NAME (type))));
3808 else /* we have an untagged structure or a typedef */
3810 obstack_1grow (&util_obstack, '?');
3815 || format == OBJC_ENCODE_DONT_INLINE_DEFS)
3817 /* we have a pointer
3818 or we don't want the details. */
3819 obstack_1grow (&util_obstack, ')');
3823 tree fields = TYPE_FIELDS (type);
3824 for ( ; fields; fields = TREE_CHAIN (fields))
3825 encode_field_decl (fields, format);
3826 obstack_1grow (&util_obstack, ')');
3833 obstack_1grow (&util_obstack, 'i');
3839 * support bitfields, the current version of Objective-C does not support
3840 * them. the string will consist of one or more "b:n"'s where n is an
3841 * integer describing the width of the bitfield. Currently, classes in
3842 * the kit implement a method "-(char *)describeBitfieldStruct:" that
3843 * simulates this...if they do not implement this method, the archiver
3844 * assumes the bitfield is 16 bits wide (padded if necessary) and packed
3845 * according to the GNU compiler. After looking at the "kit", it appears
3846 * that all classes currently rely on this default behavior, rather than
3847 * hand generating this string (which is tedious).
3850 encode_bitfield (width, format)
3855 sprintf (buffer, "b%d", width);
3856 obstack_grow (&util_obstack, buffer, strlen (buffer));
3862 * OBJC_ENCODE_INLINE_DEFS or OBJC_ENCODE_DONT_INLINE_DEFS
3865 encode_type (type, format)
3869 enum tree_code code = TREE_CODE (type);
3871 if (code == INTEGER_TYPE)
3873 if (TREE_INT_CST_LOW (TYPE_MIN_VALUE (type)) == 0)
3875 /* unsigned integer types */
3877 if (TYPE_MODE (type) == QImode) /* 'C' */
3878 obstack_1grow (&util_obstack, 'C');
3879 else if (TYPE_MODE (type) == HImode) /* 'S' */
3880 obstack_1grow (&util_obstack, 'S');
3881 else if (TYPE_MODE (type) == SImode)
3883 if (type == long_unsigned_type_node)
3884 obstack_1grow (&util_obstack, 'L'); /* 'L' */
3886 obstack_1grow (&util_obstack, 'I'); /* 'I' */
3889 else /* signed integer types */
3891 if (TYPE_MODE (type) == QImode) /* 'c' */
3892 obstack_1grow (&util_obstack, 'c');
3893 else if (TYPE_MODE (type) == HImode) /* 's' */
3894 obstack_1grow (&util_obstack, 's');
3895 else if (TYPE_MODE (type) == SImode) /* 'i' */
3897 if (type == long_integer_type_node)
3898 obstack_1grow (&util_obstack, 'l'); /* 'l' */
3900 obstack_1grow (&util_obstack, 'i'); /* 'i' */
3904 else if (code == REAL_TYPE)
3906 /* floating point types */
3908 if (TYPE_MODE (type) == SFmode) /* 'f' */
3909 obstack_1grow (&util_obstack, 'f');
3910 else if (TYPE_MODE (type) == DFmode
3911 || TYPE_MODE (type) == TFmode) /* 'd' */
3912 obstack_1grow (&util_obstack, 'd');
3915 else if (code == VOID_TYPE) /* 'v' */
3916 obstack_1grow (&util_obstack, 'v');
3918 else if (code == ARRAY_TYPE)
3919 encode_array (type, format);
3921 else if (code == POINTER_TYPE)
3922 encode_pointer (type, format);
3924 else if (code == RECORD_TYPE || code == UNION_TYPE || code == ENUMERAL_TYPE)
3925 encode_aggregate (type, format);
3927 else if (code == FUNCTION_TYPE) /* '?' */
3928 obstack_1grow (&util_obstack, '?');
3932 encode_field_decl (field_decl, format)
3936 if (DECL_BIT_FIELD (field_decl))
3937 encode_bitfield (DECL_FIELD_SIZE (field_decl), format);
3939 encode_type (TREE_TYPE (field_decl), format);
3943 expr_last (complex_expr)
3949 while (next = TREE_OPERAND (complex_expr, 0))
3950 complex_expr = next;
3951 return complex_expr;
3954 /* The selector of the current method,
3955 or NULL if we aren't compiling a method. */
3958 maybe_objc_method_name (decl)
3962 return METHOD_SEL_NAME (method_context);
3968 * Transform a method definition into a function definition as follows:
3970 * - synthesize the first two arguments, "self" and "_cmd".
3974 start_method_def (method)
3979 /* required to implement _msgSuper () */
3980 method_context = method;
3981 _OBJC_SUPER_decl = NULLT;
3983 pushlevel (0); /* must be called BEFORE "start_function ()" */
3985 /* generate prototype declarations for arguments..."new-style" */
3987 if (TREE_CODE (method_context) == INSTANCE_METHOD_DECL)
3988 decl_specs = build_tree_list (NULLT, _PRIVATE_record);
3990 /* really a `struct objc_class *'...however we allow people to
3991 assign to self...which changes its type midstream.
3993 decl_specs = build_tree_list (NULLT, objc_object_reference);
3995 push_parm_decl (build_tree_list (decl_specs,
3996 build1 (INDIRECT_REF, NULLT, self_id)));
3998 #ifdef OBJC_INT_SELECTORS
3999 decl_specs = build_tree_list (NULLT, ridpointers[(int) RID_UNSIGNED]);
4000 decl_specs = tree_cons (NULLT, ridpointers[(int) RID_INT], decl_specs);
4001 push_parm_decl (build_tree_list (decl_specs, _cmd_id));
4002 #else /* not OBJC_INT_SELECTORS */
4003 decl_specs = build_tree_list (NULLT,
4004 xref_tag (RECORD_TYPE,
4005 get_identifier (TAG_SELECTOR)));
4006 push_parm_decl (build_tree_list (decl_specs,
4007 build1 (INDIRECT_REF, NULLT, _cmd_id)));
4008 #endif /* not OBJC_INT_SELECTORS */
4010 /* generate argument declarations if a keyword_decl */
4011 if (METHOD_SEL_ARGS (method))
4013 tree arglist = METHOD_SEL_ARGS (method);
4016 tree arg_spec = TREE_PURPOSE (TREE_TYPE (arglist));
4017 tree arg_decl = TREE_VALUE (TREE_TYPE (arglist));
4021 tree last_expr = expr_last (arg_decl);
4023 /* unite the abstract decl with its name */
4024 TREE_OPERAND (last_expr, 0) = KEYWORD_ARG_NAME (arglist);
4025 push_parm_decl (build_tree_list (arg_spec, arg_decl));
4026 /* unhook...restore the abstract declarator */
4027 TREE_OPERAND (last_expr, 0) = NULLT;
4030 push_parm_decl (build_tree_list (arg_spec, KEYWORD_ARG_NAME (arglist)));
4032 arglist = TREE_CHAIN (arglist);
4037 if (METHOD_ADD_ARGS (method) > (tree)1)
4039 /* we have a variable length selector - in "prototype" format */
4040 tree akey = TREE_PURPOSE (METHOD_ADD_ARGS (method));
4043 /* this must be done prior to calling pushdecl (). pushdecl () is
4044 * going to change our chain on us...
4046 tree nextkey = TREE_CHAIN (akey);
4054 error_with_method (message, mtype, method)
4060 fprintf (stderr, "%s:%d: ",
4061 DECL_SOURCE_FILE (method), DECL_SOURCE_LINE (method));
4062 bzero (errbuf, BUFSIZE);
4063 fprintf (stderr, "%s `%c%s'\n", message, mtype, gen_method_decl (method, errbuf));
4067 warn_with_method (message, mtype, method)
4073 fprintf (stderr, "%s:%d: ",
4074 DECL_SOURCE_FILE (method), DECL_SOURCE_LINE (method));
4075 bzero (errbuf, BUFSIZE);
4076 fprintf (stderr, "%s `%c%s'\n", message, mtype, gen_method_decl (method, errbuf));
4079 /* return 1 if `method' is consistent with `proto' */
4082 comp_method_with_proto (method, proto)
4085 static tree function_type = 0;
4087 /* create a function_type node once */
4090 struct obstack *ambient_obstack = current_obstack;
4092 current_obstack = &permanent_obstack;
4093 function_type = make_node (FUNCTION_TYPE);
4094 current_obstack = ambient_obstack;
4097 /* install argument types - normally set by "build_function_type ()". */
4098 TYPE_ARG_TYPES (function_type) = get_arg_type_list (proto, METHOD_DEF, 0);
4100 /* install return type */
4101 TREE_TYPE (function_type) = groktypename (TREE_TYPE (proto));
4103 return comptypes (TREE_TYPE (METHOD_DEFINITION (method)), function_type);
4106 /* return 1 if `proto1' is consistent with `proto2' */
4109 comp_proto_with_proto (proto1, proto2)
4110 tree proto1, proto2;
4112 static tree function_type1 = 0, function_type2 = 0;
4114 /* create a couple function_type node's once */
4115 if (!function_type1)
4117 struct obstack *ambient_obstack = current_obstack;
4119 current_obstack = &permanent_obstack;
4120 function_type1 = make_node (FUNCTION_TYPE);
4121 function_type2 = make_node (FUNCTION_TYPE);
4122 current_obstack = ambient_obstack;
4125 /* install argument types - normally set by "build_function_type ()". */
4126 TYPE_ARG_TYPES (function_type1) = get_arg_type_list (proto1, METHOD_REF, 0);
4127 TYPE_ARG_TYPES (function_type2) = get_arg_type_list (proto2, METHOD_REF, 0);
4129 /* install return type */
4130 TREE_TYPE (function_type1) = groktypename (TREE_TYPE (proto1));
4131 TREE_TYPE (function_type2) = groktypename (TREE_TYPE (proto2));
4133 return comptypes (function_type1, function_type2);
4137 * - generate an identifier for the function. the format is "_n_cls",
4138 * where 1 <= n <= nMethods, and cls is the name the implementation we
4140 * - install the return type from the method declaration.
4141 * - if we have a prototype, check for type consistency.
4144 really_start_method (method, parmlist)
4145 tree method, parmlist;
4147 tree sc_spec, ret_spec, ret_decl, decl_specs;
4148 tree method_decl, method_id;
4151 /* synth the storage class & assemble the return type */
4152 sc_spec = tree_cons (NULLT, ridpointers[(int) RID_STATIC], NULLT);
4153 ret_spec = TREE_PURPOSE (TREE_TYPE (method));
4154 decl_specs = chainon (sc_spec, ret_spec);
4156 if (TREE_CODE (implementation_context) == IMPLEMENTATION_TYPE)
4158 /* Make sure this is big enough for any plausible method label. */
4159 buf = (char *) alloca (50
4160 + strlen (IDENTIFIER_POINTER (METHOD_SEL_NAME (method)))
4161 + strlen (IDENTIFIER_POINTER (CLASS_NAME (implementation_context))));
4162 #ifdef OBJC_GEN_METHOD_LABEL
4163 OBJC_GEN_METHOD_LABEL (buf,
4164 TREE_CODE (method) == INSTANCE_METHOD_DECL,
4165 IDENTIFIER_POINTER (CLASS_NAME (implementation_context)),
4167 IDENTIFIER_POINTER (METHOD_SEL_NAME (method)));
4169 sprintf (buf, "_%d_%s", ++method_slot,
4170 IDENTIFIER_POINTER (CLASS_NAME (implementation_context)));
4173 else /* we have a category */
4175 /* Make sure this is big enough for any plausible method label. */
4176 buf = (char *) alloca (50
4177 + strlen (IDENTIFIER_POINTER (METHOD_SEL_NAME (method)))
4178 + strlen (IDENTIFIER_POINTER (CLASS_SUPER_NAME (implementation_context)))
4179 + strlen (IDENTIFIER_POINTER (CLASS_NAME (implementation_context))));
4180 #ifdef OBJC_GEN_METHOD_LABEL
4181 OBJC_GEN_METHOD_LABEL (buf,
4182 TREE_CODE (method) == INSTANCE_METHOD_DECL,
4183 IDENTIFIER_POINTER (CLASS_NAME (implementation_context)),
4184 IDENTIFIER_POINTER (CLASS_SUPER_NAME (implementation_context)),
4185 IDENTIFIER_POINTER (METHOD_SEL_NAME (method)));
4187 sprintf (buf, "_%d_%s_%s", ++method_slot,
4188 IDENTIFIER_POINTER (CLASS_NAME (implementation_context)),
4189 IDENTIFIER_POINTER (CLASS_SUPER_NAME (implementation_context)));
4193 method_id = get_identifier (buf);
4195 method_decl = build_nt (CALL_EXPR, method_id, parmlist, NULLT);
4197 /* check the declarator portion of the return type for the method */
4198 if (ret_decl = TREE_VALUE (TREE_TYPE (method)))
4201 * unite the complex decl (specified in the abstract decl) with the
4202 * function decl just synthesized...(int *), (int (*)()), (int (*)[]).
4204 tree save_expr = expr_last (ret_decl);
4206 TREE_OPERAND (save_expr, 0) = method_decl;
4207 method_decl = ret_decl;
4208 /* fool the parser into thinking it is starting a function */
4209 start_function (decl_specs, method_decl, 0);
4210 /* unhook...this has the effect of restoring the abstract declarator */
4211 TREE_OPERAND (save_expr, 0) = NULLT;
4215 TREE_VALUE (TREE_TYPE (method)) = method_decl;
4216 /* fool the parser into thinking it is starting a function */
4217 start_function (decl_specs, method_decl, 0);
4218 /* unhook...this has the effect of restoring the abstract declarator */
4219 TREE_VALUE (TREE_TYPE (method)) = NULLT;
4222 METHOD_DEFINITION (method) = current_function_decl;
4224 /* check consistency...start_function (), pushdecl (), duplicate_decls (). */
4226 if (implementation_template != implementation_context)
4230 if (TREE_CODE (method) == INSTANCE_METHOD_DECL)
4231 chain = CLASS_NST_METHODS (implementation_template);
4233 chain = CLASS_CLS_METHODS (implementation_template);
4235 if (proto = lookup_method (chain, METHOD_SEL_NAME (method)))
4237 if (!comp_method_with_proto (method, proto))
4239 fprintf (stderr, "%s: In method `%s'\n", input_filename,
4240 IDENTIFIER_POINTER (METHOD_SEL_NAME (method)));
4241 if (TREE_CODE (method) == INSTANCE_METHOD_DECL)
4243 error_with_method ("conflicting types for", '-', method);
4244 error_with_method ("previous declaration of", '-', proto);
4248 error_with_method ("conflicting types for", '+', method);
4249 error_with_method ("previous declaration of", '+', proto);
4257 * the following routine is always called...this "architecture" is to
4258 * accommodate "old-style" variable length selectors.
4260 * - a:a b:b // prototype ; id c; id d; // old-style
4263 continue_method_def ()
4267 if (METHOD_ADD_ARGS (method_context) == (tree)1)
4269 * we have a `, ...' immediately following the selector.
4271 parmlist = get_parm_info (0);
4273 parmlist = get_parm_info (1); /* place a `void_at_end' */
4275 /* set self_decl from the first argument...this global is used by
4276 * build_ivar_reference ().build_indirect_ref ().
4278 self_decl = TREE_PURPOSE (parmlist);
4280 poplevel (0, 0, 0); /* must be called BEFORE "start_function ()" */
4282 really_start_method (method_context, parmlist);
4284 store_parm_decls (); /* must be called AFTER "start_function ()" */
4290 if (!_OBJC_SUPER_decl)
4291 _OBJC_SUPER_decl = start_decl (get_identifier (_TAG_SUPER),
4292 build_tree_list (NULLT, objc_super_template), 0);
4294 /* this prevents `unused variable' warnings when compiling with `-Wall' */
4295 DECL_IN_SYSTEM_HEADER (_OBJC_SUPER_decl) = 1;
4299 * _n_Method (id self, SEL sel, ...)
4301 * struct objc_super _S;
4303 * _msgSuper ((_S.self = self, _S.class = _cls, &_S), ...);
4307 get_super_receiver ()
4311 tree super_expr, super_expr_list;
4313 /* set receiver to self */
4314 super_expr = build_component_ref (_OBJC_SUPER_decl, self_id);
4315 super_expr = build_modify_expr (super_expr, NOP_EXPR, self_decl);
4316 super_expr_list = build_tree_list (NULLT, super_expr);
4318 /* set class to begin searching */
4319 super_expr = build_component_ref (_OBJC_SUPER_decl, get_identifier ("class"));
4321 if (TREE_CODE (implementation_context) == IMPLEMENTATION_TYPE)
4323 /* [_cls, __cls]Super are "pre-built" in synth_foward_declarations () */
4325 if (TREE_CODE (method_context) == INSTANCE_METHOD_DECL)
4326 super_expr = build_modify_expr (super_expr, NOP_EXPR, _clsSuper_ref);
4328 super_expr = build_modify_expr (super_expr, NOP_EXPR, __clsSuper_ref);
4330 else /* we have a category... */
4332 tree params, super_name = CLASS_SUPER_NAME (implementation_template);
4335 if (!super_name) /* Barf if super used in a category of Object. */
4337 error("no super class declared in interface for `%s'",
4338 IDENTIFIER_POINTER (CLASS_NAME (implementation_template)));
4339 return error_mark_node;
4342 add_class_reference (super_name);
4344 params = build_tree_list (NULLT,
4345 my_build_string (IDENTIFIER_LENGTH (super_name) + 1,
4346 IDENTIFIER_POINTER (super_name)));
4348 if (TREE_CODE (method_context) == INSTANCE_METHOD_DECL)
4349 funcCall = build_function_call (objc_getClass_decl, params);
4351 funcCall = build_function_call (objc_getMetaClass_decl, params);
4354 TREE_TYPE (funcCall) = TREE_TYPE (_clsSuper_ref);
4355 super_expr = build_modify_expr (super_expr, NOP_EXPR, funcCall);
4357 chainon (super_expr_list, build_tree_list (NULL_TREE, super_expr));
4359 super_expr = build_unary_op (ADDR_EXPR, _OBJC_SUPER_decl, 0);
4360 chainon (super_expr_list, build_tree_list (NULL_TREE, super_expr));
4362 return build_compound_expr (super_expr_list);
4366 error ("[super ...] must appear in a method context");
4367 return error_mark_node;
4372 encode_method_def (func_decl)
4381 encode_type (TREE_TYPE (TREE_TYPE (func_decl)),
4382 OBJC_ENCODE_DONT_INLINE_DEFS);
4384 for (parms = DECL_ARGUMENTS (func_decl); parms;
4385 parms = TREE_CHAIN (parms))
4386 stack_size += TREE_INT_CST_LOW (TYPE_SIZE (DECL_ARG_TYPE (parms)))
4389 sprintf (buffer, "%d", stack_size);
4390 obstack_grow (&util_obstack, buffer, strlen (buffer));
4392 /* argument types */
4393 for (parms = DECL_ARGUMENTS (func_decl); parms;
4394 parms = TREE_CHAIN (parms))
4396 int offset_in_bytes;
4399 encode_type (TREE_TYPE (parms), OBJC_ENCODE_DONT_INLINE_DEFS);
4401 /* compute offset */
4402 if (GET_CODE (DECL_INCOMING_RTL (parms)) == MEM)
4404 rtx addr = XEXP (DECL_INCOMING_RTL (parms), 0);
4406 /* ??? Here we assume that the parm address is indexed
4407 off the frame pointer or arg pointer.
4408 If that is not true, we produce meaningless results,
4409 but do not crash. */
4410 if (GET_CODE (addr) == PLUS
4411 && GET_CODE (XEXP (addr, 1)) == CONST_INT)
4412 offset_in_bytes = INTVAL (XEXP (addr, 1));
4414 offset_in_bytes = 0;
4416 /* This is the case where the parm is passed as an int or double
4417 and it is converted to a char, short or float and stored back
4418 in the parmlist. In this case, describe the parm
4419 with the variable's declared type, and adjust the address
4420 if the least significant bytes (which we are using) are not
4422 #if BYTES_BIG_ENDIAN
4423 if (TREE_TYPE (parms) != DECL_ARG_TYPE (parms))
4424 offset_in_bytes += (GET_MODE_SIZE (TYPE_MODE (DECL_ARG_TYPE (parms)))
4425 - GET_MODE_SIZE (GET_MODE (DECL_RTL (parms))));
4429 offset_in_bytes = 0;
4431 /* The "+ 4" is a total hack to account for the return pc and
4432 saved fp on the 68k. We should redefine this format! */
4433 sprintf (buffer, "%d", offset_in_bytes + 8);
4434 obstack_grow (&util_obstack, buffer, strlen (buffer));
4437 result = get_identifier (obstack_finish (&util_obstack));
4438 obstack_free (&util_obstack, util_firstobj);
4443 finish_method_def ()
4445 METHOD_ENCODING (method_context) =
4446 encode_method_def (current_function_decl);
4448 finish_function (0);
4450 /* this must be done AFTER finish_function, since the optimizer may
4451 find "may be used before set" errors. */
4452 method_context = NULLT; /* required to implement _msgSuper () */
4456 lang_report_error_function (decl)
4461 fprintf (stderr, "In method `%s'\n",
4462 IDENTIFIER_POINTER (METHOD_SEL_NAME (method_context)));
4470 is_complex_decl (type)
4473 return (TREE_CODE (type) == ARRAY_TYPE
4474 || TREE_CODE (type) == FUNCTION_TYPE
4475 || TREE_CODE (type) == POINTER_TYPE);
4479 /* Code to convert a decl node into text for a declaration in C. */
4481 static char tmpbuf[256];
4484 adorn_decl (decl, str)
4488 enum tree_code code = TREE_CODE (decl);
4490 if (code == ARRAY_REF)
4492 tree anIntCst = TREE_OPERAND (decl, 1);
4494 sprintf (str + strlen (str), "[%d]", TREE_INT_CST_LOW (anIntCst));
4496 else if (code == ARRAY_TYPE)
4498 tree anIntCst = TYPE_SIZE (decl);
4499 tree array_of = TREE_TYPE (decl);
4501 sprintf (str + strlen (str), "[%d]",
4502 TREE_INT_CST_LOW (anIntCst)/TREE_INT_CST_LOW (TYPE_SIZE (array_of)));
4504 else if (code == CALL_EXPR)
4506 else if (code == FUNCTION_TYPE)
4508 tree chain = TYPE_ARG_TYPES (decl); /* a list of types */
4510 while (chain && TREE_VALUE (chain) != void_type_node)
4512 gen_declaration (TREE_VALUE (chain), str);
4513 chain = TREE_CHAIN (chain);
4514 if (chain && TREE_VALUE (chain) != void_type_node)
4521 strcpy (tmpbuf, "*"); strcat (tmpbuf, str);
4522 strcpy (str, tmpbuf);
4527 gen_declarator (decl, buf, name)
4534 enum tree_code code = TREE_CODE (decl);
4541 case ARRAY_REF: case INDIRECT_REF: case CALL_EXPR:
4543 op = TREE_OPERAND (decl, 0);
4545 /* we have a pointer to a function or array...(*)(), (*)[] */
4546 if ((code == ARRAY_REF || code == CALL_EXPR) &&
4547 (op && TREE_CODE (op) == INDIRECT_REF))
4550 str = gen_declarator (op, buf, name);
4554 strcpy (tmpbuf, "("); strcat (tmpbuf, str); strcat (tmpbuf, ")");
4555 strcpy (str, tmpbuf);
4558 adorn_decl (decl, str);
4561 case ARRAY_TYPE: case FUNCTION_TYPE: case POINTER_TYPE:
4563 str = strcpy (buf, name);
4565 /* this clause is done iteratively...rather than recursively */
4568 op = is_complex_decl (TREE_TYPE (decl))
4572 adorn_decl (decl, str);
4574 /* we have a pointer to a function or array...(*)(), (*)[] */
4575 if ((code == POINTER_TYPE) &&
4576 (op && (TREE_CODE (op) == FUNCTION_TYPE
4577 || TREE_CODE (op) == ARRAY_TYPE)))
4579 strcpy (tmpbuf, "("); strcat (tmpbuf, str); strcat (tmpbuf, ")");
4580 strcpy (str, tmpbuf);
4583 decl = is_complex_decl (TREE_TYPE (decl))
4587 while (decl && (code = TREE_CODE (decl)));
4591 case IDENTIFIER_NODE:
4592 /* will only happen if we are processing a "raw" expr-decl. */
4593 return strcpy (buf, IDENTIFIER_POINTER (decl));
4598 else /* we have an abstract declarator or a _DECL node */
4600 return strcpy (buf, name);
4605 gen_declspecs (declspecs, buf, raw)
4614 for (chain = declspecs; chain; chain = TREE_CHAIN (chain))
4616 tree aspec = TREE_VALUE (chain);
4618 if (TREE_CODE (aspec) == IDENTIFIER_NODE)
4619 strcat (buf, IDENTIFIER_POINTER (aspec));
4620 else if (TREE_CODE (aspec) == RECORD_TYPE)
4622 if (TYPE_NAME (aspec))
4624 if (!TREE_STATIC_TEMPLATE (aspec))
4625 strcat (buf, "struct ");
4626 strcat (buf, IDENTIFIER_POINTER (TYPE_NAME (aspec)));
4629 strcat (buf, "untagged struct");
4631 else if (TREE_CODE (aspec) == UNION_TYPE)
4633 if (TYPE_NAME (aspec))
4635 if (!TREE_STATIC_TEMPLATE (aspec))
4636 strcat (buf, "union ");
4637 strcat (buf, IDENTIFIER_POINTER (TYPE_NAME (aspec)));
4640 strcat (buf, "untagged union");
4642 else if (TREE_CODE (aspec) == ENUMERAL_TYPE)
4644 if (TYPE_NAME (aspec))
4646 if (!TREE_STATIC_TEMPLATE (aspec))
4647 strcat (buf, "enum ");
4648 strcat (buf, IDENTIFIER_POINTER (TYPE_NAME (aspec)));
4651 strcat (buf, "untagged enum");
4657 switch (TREE_CODE (declspecs))
4659 /* type specifiers */
4661 case INTEGER_TYPE: /* signed integer types */
4663 if (declspecs == short_integer_type_node) /* 's' */
4664 strcat (buf, "short int ");
4665 else if (declspecs == integer_type_node) /* 'i' */
4666 strcat (buf, "int ");
4667 else if (declspecs == long_integer_type_node) /* 'l' */
4668 strcat (buf, "long int ");
4669 else if (declspecs == signed_char_type_node || /* 'c' */
4670 declspecs == char_type_node)
4671 strcat (buf, "char ");
4673 /* unsigned integer types */
4675 else if (declspecs == short_unsigned_type_node) /* 'S' */
4676 strcat (buf, "unsigned short ");
4677 else if (declspecs == unsigned_type_node) /* 'I' */
4678 strcat (buf, "unsigned int ");
4679 else if (declspecs == long_unsigned_type_node) /* 'L' */
4680 strcat (buf, "unsigned long ");
4681 else if (declspecs == unsigned_char_type_node) /* 'C' */
4682 strcat (buf, "unsigned char ");
4685 case REAL_TYPE: /* floating point types */
4687 if (declspecs == float_type_node) /* 'f' */
4688 strcat (buf, "float ");
4689 else if (declspecs == double_type_node) /* 'd' */
4690 strcat (buf, "double ");
4691 else if (declspecs == long_double_type_node) /* 'd' */
4692 strcat (buf, "long double ");
4696 if (!TREE_STATIC_TEMPLATE (declspecs))
4697 strcat (buf, "struct ");
4698 if (TYPE_NAME (declspecs) &&
4699 (TREE_CODE (TYPE_NAME (declspecs)) == IDENTIFIER_NODE))
4701 strcat (buf, IDENTIFIER_POINTER (TYPE_NAME (declspecs)));
4706 strcat (buf, "union ");
4707 if (TYPE_NAME (declspecs) &&
4708 (TREE_CODE (TYPE_NAME (declspecs)) == IDENTIFIER_NODE))
4710 strcat (buf, IDENTIFIER_POINTER (TYPE_NAME (declspecs)));
4715 strcat (buf, "enum ");
4716 if (TYPE_NAME (declspecs) &&
4717 (TREE_CODE (TYPE_NAME (declspecs)) == IDENTIFIER_NODE))
4719 strcat (buf, IDENTIFIER_POINTER (TYPE_NAME (declspecs)));
4724 strcat (buf, "void ");
4729 gen_declaration (atype_or_adecl, buf)
4730 tree atype_or_adecl;
4735 if (TREE_CODE (atype_or_adecl) == TREE_LIST)
4737 tree declspecs; /* "identifier_node", "record_type" */
4738 tree declarator; /* "array_ref", "indirect_ref", "call_expr"... */
4740 /* we have a "raw", abstract declarator (typename) */
4741 declarator = TREE_VALUE (atype_or_adecl);
4742 declspecs = TREE_PURPOSE (atype_or_adecl);
4744 gen_declspecs (declspecs, buf, 1);
4745 strcat (buf, gen_declarator (declarator, declbuf, ""));
4750 tree declspecs; /* "integer_type", "real_type", "record_type"... */
4751 tree declarator; /* "array_type", "function_type", "pointer_type". */
4753 if (TREE_CODE (atype_or_adecl) == FIELD_DECL
4754 || TREE_CODE (atype_or_adecl) == PARM_DECL
4755 || TREE_CODE (atype_or_adecl) == FUNCTION_DECL)
4756 atype = TREE_TYPE (atype_or_adecl);
4758 atype = atype_or_adecl; /* assume we have a *_type node */
4760 if (is_complex_decl (atype))
4764 /* get the declaration specifier...it is at the end of the list */
4765 declarator = chain = atype;
4767 chain = TREE_TYPE (chain); /* not TREE_CHAIN (chain); */
4768 while (is_complex_decl (chain));
4777 gen_declspecs (declspecs, buf, 0);
4779 if (TREE_CODE (atype_or_adecl) == FIELD_DECL
4780 || TREE_CODE (atype_or_adecl) == PARM_DECL
4781 || TREE_CODE (atype_or_adecl) == FUNCTION_DECL)
4785 strcat (buf, gen_declarator (declarator, declbuf,
4786 IDENTIFIER_POINTER (DECL_NAME (atype_or_adecl))));
4789 strcat (buf, IDENTIFIER_POINTER (DECL_NAME (atype_or_adecl)));
4793 strcat (buf, gen_declarator (declarator, declbuf, ""));
4799 #define RAW_TYPESPEC(meth) (TREE_VALUE (TREE_PURPOSE (TREE_TYPE (meth))))
4802 gen_method_decl (method, buf)
4808 if (RAW_TYPESPEC (method) != objc_object_reference)
4811 gen_declaration (TREE_TYPE (method), buf);
4815 chain = METHOD_SEL_ARGS (method);
4817 { /* we have a chain of keyword_decls */
4820 if (KEYWORD_KEY_NAME (chain))
4821 strcat (buf, IDENTIFIER_POINTER (KEYWORD_KEY_NAME (chain)));
4824 if (RAW_TYPESPEC (chain) != objc_object_reference)
4827 gen_declaration (TREE_TYPE (chain), buf);
4830 strcat (buf, IDENTIFIER_POINTER (KEYWORD_ARG_NAME (chain)));
4831 if (chain = TREE_CHAIN (chain))
4836 if (METHOD_ADD_ARGS (method) == (tree)1)
4837 strcat (buf, ", ...");
4838 else if (METHOD_ADD_ARGS (method))
4839 { /* we have a tree list node as generate by `get_parm_info ()' */
4840 chain = TREE_PURPOSE (METHOD_ADD_ARGS (method));
4841 /* know we have a chain of parm_decls */
4845 gen_declaration (chain, buf);
4846 chain = TREE_CHAIN (chain);
4850 else /* we have a unary selector */
4852 strcat (buf, IDENTIFIER_POINTER (METHOD_SEL_NAME (method)));
4859 gen_prototype (fp, decl)
4863 /* we have a function definition - generate prototype */
4864 bzero (errbuf, BUFSIZE);
4865 gen_declaration (decl, errbuf);
4866 fprintf (fp, "%s;\n", errbuf);
4872 dump_interface (fp, chain)
4876 char *buf = (char *)xmalloc (256);
4877 char *my_name = IDENTIFIER_POINTER (CLASS_NAME (chain));
4878 tree ivar_decls = CLASS_RAW_IVARS (chain);
4879 tree nst_methods = CLASS_NST_METHODS (chain);
4880 tree cls_methods = CLASS_CLS_METHODS (chain);
4882 fprintf (fp, "\n@interface %s", my_name);
4884 if (CLASS_SUPER_NAME (chain))
4886 char *super_name = IDENTIFIER_POINTER (CLASS_SUPER_NAME (chain));
4887 fprintf (fp, " : %s\n", super_name);
4894 fprintf (fp, "{\n");
4898 fprintf (fp, "\t%s;\n", gen_declaration (ivar_decls, buf));
4899 ivar_decls = TREE_CHAIN (ivar_decls);
4902 fprintf (fp, "}\n");
4908 fprintf (fp, "- %s;\n", gen_method_decl (nst_methods, buf));
4909 nst_methods = TREE_CHAIN (nst_methods);
4915 fprintf (fp, "+ %s;\n", gen_method_decl (cls_methods, buf));
4916 cls_methods = TREE_CHAIN (cls_methods);
4918 fprintf (fp, "\n@end");
4924 /* Add the special tree codes of Objective C to the tables. */
4926 gcc_obstack_init (&util_obstack);
4927 util_firstobj = (char *) obstack_finish (&util_obstack);
4930 = (char **) realloc (tree_code_type,
4931 sizeof (char *) * LAST_OBJC_TREE_CODE);
4933 = (int *) realloc (tree_code_length,
4934 sizeof (int) * LAST_OBJC_TREE_CODE);
4936 = (char **) realloc (tree_code_name,
4937 sizeof (char *) * LAST_OBJC_TREE_CODE);
4938 bcopy (objc_tree_code_type,
4939 tree_code_type + (int) LAST_AND_UNUSED_TREE_CODE,
4940 (((int) LAST_OBJC_TREE_CODE - (int) LAST_AND_UNUSED_TREE_CODE)
4941 * sizeof (char *)));
4942 bcopy (objc_tree_code_length,
4943 tree_code_length + (int) LAST_AND_UNUSED_TREE_CODE,
4944 (((int) LAST_OBJC_TREE_CODE - (int) LAST_AND_UNUSED_TREE_CODE)
4946 bcopy (objc_tree_code_name,
4947 tree_code_name + (int) LAST_AND_UNUSED_TREE_CODE,
4948 (((int) LAST_OBJC_TREE_CODE - (int) LAST_AND_UNUSED_TREE_CODE)
4949 * sizeof (char *)));
4951 errbuf = (char *)xmalloc (BUFSIZE);
4953 synth_module_prologue ();
4959 struct imp_entry *impent;
4962 generate_forward_declaration_to_string_table ();
4964 #ifdef OBJC_PROLOGUE
4968 if (implementation_context || sel_refdef_chain)
4969 generate_objc_symtab_decl ();
4971 for (impent = imp_list; impent; impent = impent->next)
4973 implementation_context = impent->imp_context;
4974 implementation_template = impent->imp_template;
4976 _OBJC_CLASS_decl = impent->class_decl;
4977 _OBJC_METACLASS_decl = impent->meta_decl;
4979 if (TREE_CODE (implementation_context) == IMPLEMENTATION_TYPE)
4981 /* all of the following reference the string pool... */
4982 generate_ivar_lists ();
4983 generate_dispatch_tables ();
4984 generate_shared_structures ();
4988 generate_dispatch_tables ();
4989 generate_category (implementation_context);
4993 /* If we are using an array of selectors, we must always
4994 finish up the array decl even if no selectors were used. */
4995 #ifndef OBJC_SELECTORS_WITHOUT_LABELS
4998 build_selector_translation_table ();
5000 if (implementation_context || sel_refdef_chain)
5002 /* Arrange for Objc data structures to be initialized at run time. */
5004 char *init_name = build_module_descriptor ();
5006 assemble_constructor (init_name);
5009 /* dump the string table last */
5011 if (sel_refdef_chain)
5013 build_message_selector_pool ();
5016 /* dump the class references...this forces the appropriate classes
5017 to be linked into the executable image, preserving unix archive
5018 semantics...this can be removed when we move to a more dynamically
5021 for (chain = cls_ref_chain; chain; chain = TREE_CHAIN (chain))
5022 handle_class_ref (chain);
5024 for (impent = imp_list; impent; impent = impent->next)
5025 handle_impent (impent);
5027 #if 0 /* If GAS has such a bug, let's fix it. */
5028 /*** this fixes a gross bug in the assembler...it `expects' #APP to have
5029 *** a matching #NO_APP, or it crashes (sometimes). app_disable () will
5030 *** insure this is the case. 5/19/89, s.naroff.
5032 if (cls_ref_chain || imp_list)
5036 if (flag_gen_declaration)
5038 add_class (implementation_context);
5039 dump_interface (gen_declaration_file, implementation_context);
5045 /* Run through the selector hash tables and print a warning for any
5046 selector which has multiple methods. */
5048 for (slot = 0; slot < SIZEHASHTABLE; slot++)
5052 for (hsh = cls_method_hash_list[slot]; hsh; hsh = hsh->next)
5056 tree meth = hsh->key;
5057 char type = (TREE_CODE (meth) == INSTANCE_METHOD_DECL)
5061 warning ("potential selector conflict for method `%s'",
5062 IDENTIFIER_POINTER (METHOD_SEL_NAME (meth)));
5063 warn_with_method ("found", type, meth);
5064 for (loop = hsh->list; loop; loop = loop->next)
5065 warn_with_method ("found", type, loop->value);
5070 for (slot = 0; slot < SIZEHASHTABLE; slot++)
5074 for (hsh = nst_method_hash_list[slot]; hsh; hsh = hsh->next)
5078 tree meth = hsh->key;
5079 char type = (TREE_CODE (meth) == INSTANCE_METHOD_DECL)
5083 warning ("potential selector conflict for method `%s'",
5084 IDENTIFIER_POINTER (METHOD_SEL_NAME (meth)));
5085 warn_with_method ("found", type, meth);
5086 for (loop = hsh->list; loop; loop = loop->next)
5087 warn_with_method ("found", type, loop->value);
5094 /* Subroutines of finish_objc. */
5096 handle_class_ref (chain)
5101 = (char *) alloca (strlen (IDENTIFIER_POINTER (TREE_VALUE (chain))) + 30);
5103 sprintf (string, "__objc_class_name_%s",
5104 IDENTIFIER_POINTER (TREE_VALUE (chain)));
5106 /* Make a decl for this name, so we can use its address in a tree. */
5107 decl = build_decl (VAR_DECL, get_identifier (string), char_type_node);
5108 DECL_EXTERNAL (decl) = 1;
5109 TREE_PUBLIC (decl) = 1;
5112 rest_of_decl_compilation (decl, 0, 0, 0);
5114 /* Make following constant read-only (why not)? */
5117 /* Output a constant to reference this address. */
5118 output_constant (build1 (ADDR_EXPR, string_type_node, decl),
5119 int_size_in_bytes (string_type_node));
5122 handle_impent (impent)
5123 struct imp_entry *impent;
5125 implementation_context = impent->imp_context;
5126 implementation_template = impent->imp_template;
5128 if (TREE_CODE (impent->imp_context) == IMPLEMENTATION_TYPE)
5131 = (char *) alloca (strlen (IDENTIFIER_POINTER (CLASS_NAME (impent->imp_context))) + 30);
5133 sprintf (string, "__objc_class_name_%s",
5134 IDENTIFIER_POINTER (CLASS_NAME (impent->imp_context)));
5135 assemble_global (string);
5136 assemble_label (string);
5138 else if (TREE_CODE (impent->imp_context) == CATEGORY_TYPE)
5141 = (char *) alloca (strlen (IDENTIFIER_POINTER (CLASS_NAME (impent->imp_context)))
5142 + strlen (IDENTIFIER_POINTER (CLASS_SUPER_NAME (impent->imp_context)))
5145 /* Do the same for categories. Even though no references to these
5146 symbols are generated automatically by the compiler, it gives
5147 you a handle to pull them into an archive by hand. */
5148 sprintf (string, "__objc_category_name_%s_%s",
5149 IDENTIFIER_POINTER (CLASS_NAME (impent->imp_context)),
5150 IDENTIFIER_POINTER (CLASS_SUPER_NAME (impent->imp_context)));
5151 assemble_global (string);
5152 assemble_label (string);
5162 char *buf = (char *)xmalloc (256);
5164 { /* dump function prototypes */
5165 tree loop = _OBJC_MODULES_decl;
5167 fprintf (fp, "\n\nfunction prototypes:\n");
5170 if (TREE_CODE (loop) == FUNCTION_DECL && DECL_INITIAL (loop))
5172 /* we have a function definition - generate prototype */
5173 bzero (errbuf, BUFSIZE);
5174 gen_declaration (loop, errbuf);
5175 fprintf (fp, "%s;\n", errbuf);
5177 loop = TREE_CHAIN (loop);
5180 { /* dump global chains */
5182 int i, index = 0, offset = 0;
5185 for (i = 0; i < SIZEHASHTABLE; i++)
5187 if (hashlist = nst_method_hash_list[i])
5189 fprintf (fp, "\n\nnst_method_hash_list[%d]:\n", i);
5193 fprintf (fp, "-%s;\n", gen_method_decl (hashlist->key, buf));
5194 hashlist = hashlist->next;
5199 for (i = 0; i < SIZEHASHTABLE; i++)
5201 if (hashlist = cls_method_hash_list[i])
5203 fprintf (fp, "\n\ncls_method_hash_list[%d]:\n", i);
5207 fprintf (fp, "-%s;\n", gen_method_decl (hashlist->key, buf));
5208 hashlist = hashlist->next;
5213 fprintf (fp, "\nsel_refdef_chain:\n");
5214 for (loop = sel_refdef_chain; loop; loop = TREE_CHAIN (loop))
5216 fprintf (fp, "(index: %4d offset: %4d) %s\n", index, offset,
5217 IDENTIFIER_POINTER (TREE_VALUE (loop)));
5219 /* add one for the '\0' character */
5220 offset += IDENTIFIER_LENGTH (TREE_VALUE (loop)) + 1;
5222 fprintf (fp, "\n (max_selector_index: %4d.\n", max_selector_index);
5228 print_lang_statistics ()