1 /* Implement classes and message passing for Objective C.
2 Copyright (C) 1992, 1993, 1994 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. */
21 /* Purpose: This module implements the Objective-C 4.0 language.
23 compatibility issues (with the Stepstone translator):
25 - does not recognize the following 3.3 constructs.
26 @requires, @classes, @messages, = (...)
27 - methods with variable arguments must conform to ANSI standard.
28 - tagged structure definitions that appear in BOTH the interface
29 and implementation are not allowed.
30 - public/private: all instance variables are public within the
31 context of the implementation...I consider this to be a bug in
33 - statically allocated objects are not supported. the user will
34 receive an error if this service is requested.
36 code generation `options':
38 - OBJC_INT_SELECTORS */
51 /* This is the default way of generating a method name. */
52 /* I am not sure it is really correct.
53 Perhaps there's a danger that it will make name conflicts
54 if method names contain underscores. -- rms. */
55 #ifndef OBJC_GEN_METHOD_LABEL
56 #define OBJC_GEN_METHOD_LABEL(BUF, IS_INST, CLASS_NAME, CAT_NAME, SEL_NAME, NUM) \
59 sprintf ((BUF), "_%s_%s_%s_%s", \
60 ((IS_INST) ? "i" : "c"), \
62 ((CAT_NAME)? (CAT_NAME) : ""), \
64 for (temp = (BUF); *temp; temp++) \
65 if (*temp == ':') *temp = '_'; \
69 /* These need specifying. */
70 #ifndef OBJC_FORWARDING_STACK_OFFSET
71 #define OBJC_FORWARDING_STACK_OFFSET 0
74 #ifndef OBJC_FORWARDING_MIN_OFFSET
75 #define OBJC_FORWARDING_MIN_OFFSET 0
78 /* Define the special tree codes that we use. */
80 /* Table indexed by tree code giving a string containing a character
81 classifying the tree code. Possibilities are
82 t, d, s, c, r, <, 1 and 2. See objc-tree.def for details. */
84 #define DEFTREECODE(SYM, NAME, TYPE, LENGTH) TYPE,
86 char *objc_tree_code_type[] = {
88 #include "objc-tree.def"
92 /* Table indexed by tree code giving number of expression
93 operands beyond the fixed part of the node structure.
94 Not used for types or decls. */
96 #define DEFTREECODE(SYM, NAME, TYPE, LENGTH) LENGTH,
98 int objc_tree_code_length[] = {
100 #include "objc-tree.def"
104 /* Names of tree components.
105 Used for printing out the tree and error messages. */
106 #define DEFTREECODE(SYM, NAME, TYPE, LEN) NAME,
108 char *objc_tree_code_name[] = {
110 #include "objc-tree.def"
114 /* Set up for use of obstacks. */
118 #define obstack_chunk_alloc xmalloc
119 #define obstack_chunk_free free
121 /* This obstack is used to accumulate the encoding of a data type. */
122 static struct obstack util_obstack;
123 /* This points to the beginning of obstack contents,
124 so we can free the whole contents. */
127 /* for encode_method_def */
131 #define OBJC_VERSION (flag_next_runtime ? 5 : 6)
132 #define PROTOCOL_VERSION 2
134 #define NULLT (tree) 0
136 #define OBJC_ENCODE_INLINE_DEFS 0
137 #define OBJC_ENCODE_DONT_INLINE_DEFS 1
139 /*** Private Interface (procedures) ***/
141 /* used by compile_file */
143 static void init_objc PROTO((void));
144 static void finish_objc PROTO((void));
146 /* code generation */
148 static void synth_module_prologue PROTO((void));
149 static tree build_constructor PROTO((tree, tree));
150 static char *build_module_descriptor PROTO((void));
151 static tree init_module_descriptor PROTO((tree));
152 static tree build_objc_method_call PROTO((int, tree, tree, tree, tree, tree));
153 static void generate_strings PROTO((void));
154 static tree get_proto_encoding PROTO((tree));
155 static void build_selector_translation_table PROTO((void));
156 static tree build_ivar_chain PROTO((tree, int));
158 static tree build_ivar_template PROTO((void));
159 static tree build_method_template PROTO((void));
160 static tree build_private_template PROTO((tree));
161 static void build_class_template PROTO((void));
162 static void build_selector_template PROTO((void));
163 static void build_category_template PROTO((void));
164 static tree build_super_template PROTO((void));
165 static tree build_category_initializer PROTO((tree, tree, tree, tree, tree, tree));
166 static tree build_protocol_initializer PROTO((tree, tree, tree, tree, tree));
168 static void synth_forward_declarations PROTO((void));
169 static void generate_ivar_lists PROTO((void));
170 static void generate_dispatch_tables PROTO((void));
171 static void generate_shared_structures PROTO((void));
172 static tree generate_protocol_list PROTO((tree));
173 static void generate_forward_declaration_to_string_table PROTO((void));
174 static void build_protocol_reference PROTO((tree));
176 static tree init_selector PROTO((int));
177 static tree build_keyword_selector PROTO((tree));
178 static tree synth_id_with_class_suffix PROTO((char *, tree));
181 extern int apply_args_register_offset PROTO((int));
183 /* misc. bookkeeping */
185 typedef struct hashed_entry *hash;
186 typedef struct hashed_attribute *attr;
188 struct hashed_attribute
200 static void hash_init PROTO((void));
201 static void hash_enter PROTO((hash *, tree));
202 static hash hash_lookup PROTO((hash *, tree));
203 static void hash_add_attr PROTO((hash, tree));
204 static tree lookup_method PROTO((tree, tree));
205 static tree lookup_instance_method_static PROTO((tree, tree));
206 static tree lookup_class_method_static PROTO((tree, tree));
207 static tree add_class PROTO((tree));
208 static void add_category PROTO((tree, tree));
212 class_names, /* class, category, protocol, module names */
213 meth_var_names, /* method and variable names */
214 meth_var_types /* method and variable type descriptors */
217 static tree add_objc_string PROTO((tree, enum string_section));
218 static tree build_objc_string_decl PROTO((tree, enum string_section));
219 static tree build_selector_reference_decl PROTO((tree));
221 /* protocol additions */
223 static tree add_protocol PROTO((tree));
224 static tree lookup_protocol PROTO((tree));
225 static tree lookup_and_install_protocols PROTO((tree));
229 static void encode_type_qualifiers PROTO((tree));
230 static void encode_pointer PROTO((tree, int, int));
231 static void encode_array PROTO((tree, int, int));
232 static void encode_aggregate PROTO((tree, int, int));
233 static void encode_bitfield PROTO((int, int));
234 static void encode_type PROTO((tree, int, int));
235 static void encode_field_decl PROTO((tree, int, int));
237 static void really_start_method PROTO((tree, tree));
238 static int comp_method_with_proto PROTO((tree, tree));
239 static int comp_proto_with_proto PROTO((tree, tree));
240 static tree get_arg_type_list PROTO((tree, int, int));
241 static tree expr_last PROTO((tree));
243 /* utilities for debugging and error diagnostics: */
245 static void warn_with_method PROTO((char *, int, tree));
246 static void error_with_ivar PROTO((char *, tree, tree));
247 static char *gen_method_decl PROTO((tree, char *));
248 static char *gen_declaration PROTO((tree, char *));
249 static char *gen_declarator PROTO((tree, char *, char *));
250 static int is_complex_decl PROTO((tree));
251 static void adorn_decl PROTO((tree, char *));
252 static void dump_interface PROTO((FILE *, tree));
254 /* everything else. */
256 static void objc_fatal PROTO((void));
257 static tree define_decl PROTO((tree, tree));
258 static tree lookup_method_in_protocol_list PROTO((tree, tree, int));
259 static tree lookup_protocol_in_reflist PROTO((tree, tree));
260 static tree create_builtin_decl PROTO((enum tree_code, tree, char *));
261 static tree my_build_string PROTO((int, char *));
262 static void build_objc_symtab_template PROTO((void));
263 static tree init_def_list PROTO((tree));
264 static tree init_objc_symtab PROTO((tree));
265 static void forward_declare_categories PROTO((void));
266 static void generate_objc_symtab_decl PROTO((void));
267 static tree build_selector PROTO((tree));
268 static tree build_msg_pool_reference PROTO((int));
269 static tree build_typed_selector_reference PROTO((tree, tree));
270 static tree build_selector_reference PROTO((tree));
271 static tree build_class_reference_decl PROTO((tree));
272 static void add_class_reference PROTO((tree));
273 static tree objc_copy_list PROTO((tree, tree *));
274 static tree build_protocol_template PROTO((void));
275 static tree build_descriptor_table_initializer PROTO((tree, tree));
276 static tree build_method_prototype_list_template PROTO((tree, int));
277 static tree build_method_prototype_template PROTO((void));
278 static int forwarding_offset PROTO((tree));
279 static tree encode_method_prototype PROTO((tree, tree));
280 static tree generate_descriptor_table PROTO((tree, char *, int, tree, tree));
281 static void generate_method_descriptors PROTO((tree));
282 static tree build_tmp_function_decl PROTO((void));
283 static void hack_method_prototype PROTO((tree, tree));
284 static void generate_protocol_references PROTO((tree));
285 static void generate_protocols PROTO((void));
286 static void check_ivars PROTO((tree, tree));
287 static tree build_ivar_list_template PROTO((tree, int));
288 static tree build_method_list_template PROTO((tree, int));
289 static tree build_ivar_list_initializer PROTO((tree, tree));
290 static tree generate_ivars_list PROTO((tree, char *, int, tree));
291 static tree build_dispatch_table_initializer PROTO((tree, tree));
292 static tree generate_dispatch_table PROTO((tree, char *, int, tree));
293 static tree build_shared_structure_initializer PROTO((tree, tree, tree, tree, tree, int, tree, tree, tree));
294 static void generate_category PROTO((tree));
295 static int is_objc_type_qualifier PROTO((tree));
296 static tree adjust_type_for_id_default PROTO((tree));
297 static tree check_duplicates PROTO((hash));
298 static tree receiver_is_class_object PROTO((tree));
299 static int check_methods PROTO((tree, tree, int));
300 static int conforms_to_protocol PROTO((tree, tree));
301 static void check_protocols PROTO((tree, char *, char *));
302 static tree encode_method_def PROTO((tree));
303 static void gen_declspecs PROTO((tree, char *, int));
304 static void generate_classref_translation_entry PROTO((tree));
305 static void handle_class_ref PROTO((tree));
307 /*** Private Interface (data) ***/
309 /* reserved tag definitions: */
312 #define TAG_OBJECT "objc_object"
313 #define TAG_CLASS "objc_class"
314 #define TAG_SUPER "objc_super"
315 #define TAG_SELECTOR "objc_selector"
317 #define UTAG_CLASS "_objc_class"
318 #define UTAG_IVAR "_objc_ivar"
319 #define UTAG_IVAR_LIST "_objc_ivar_list"
320 #define UTAG_METHOD "_objc_method"
321 #define UTAG_METHOD_LIST "_objc_method_list"
322 #define UTAG_CATEGORY "_objc_category"
323 #define UTAG_MODULE "_objc_module"
324 #define UTAG_SYMTAB "_objc_symtab"
325 #define UTAG_SUPER "_objc_super"
326 #define UTAG_SELECTOR "_objc_selector"
328 #define UTAG_PROTOCOL "_objc_protocol"
329 #define UTAG_PROTOCOL_LIST "_objc_protocol_list"
330 #define UTAG_METHOD_PROTOTYPE "_objc_method_prototype"
331 #define UTAG_METHOD_PROTOTYPE_LIST "_objc__method_prototype_list"
333 #define STRING_OBJECT_CLASS_NAME "NXConstantString"
334 #define PROTOCOL_OBJECT_CLASS_NAME "Protocol"
336 static char* TAG_GETCLASS;
337 static char* TAG_GETMETACLASS;
338 static char* TAG_MSGSEND;
339 static char* TAG_MSGSENDSUPER;
340 static char* TAG_EXECCLASS;
342 /* Set by `continue_class' and checked by `is_public'. */
344 #define TREE_STATIC_TEMPLATE(record_type) (TREE_PUBLIC (record_type))
345 #define TYPED_OBJECT(type) \
346 (TREE_CODE (type) == RECORD_TYPE && TREE_STATIC_TEMPLATE (type))
348 /* Some commonly used instances of "identifier_node". */
350 static tree self_id, ucmd_id;
352 static tree self_decl, umsg_decl, umsg_super_decl;
353 static tree objc_get_class_decl, objc_get_meta_class_decl;
355 static tree super_type, selector_type, id_type, objc_class_type;
356 static tree instance_type, protocol_type;
358 /* Type checking macros. */
360 #define IS_ID(TYPE) \
361 (TYPE_MAIN_VARIANT (TYPE) == TYPE_MAIN_VARIANT (id_type))
362 #define IS_PROTOCOL_QUALIFIED_ID(TYPE) \
363 (IS_ID (TYPE) && TYPE_PROTOCOL_LIST (TYPE))
364 #define IS_SUPER(TYPE) \
365 (super_type && TYPE_MAIN_VARIANT (TYPE) == TYPE_MAIN_VARIANT (super_type))
367 static tree class_chain = NULLT;
368 static tree alias_chain = NULLT;
369 static tree interface_chain = NULLT;
370 static tree protocol_chain = NULLT;
372 /* chains to manage selectors that are referenced and defined in the module */
374 static tree cls_ref_chain = NULLT; /* classes referenced */
375 static tree sel_ref_chain = NULLT; /* selectors referenced */
377 /* chains to manage uniquing of strings */
379 static tree class_names_chain = NULLT;
380 static tree meth_var_names_chain = NULLT;
381 static tree meth_var_types_chain = NULLT;
383 /* hash tables to manage the global pool of method prototypes */
385 static hash *nst_method_hash_list = 0;
386 static hash *cls_method_hash_list = 0;
388 /* backend data declarations */
390 static tree UOBJC_SYMBOLS_decl;
391 static tree UOBJC_INSTANCE_VARIABLES_decl, UOBJC_CLASS_VARIABLES_decl;
392 static tree UOBJC_INSTANCE_METHODS_decl, UOBJC_CLASS_METHODS_decl;
393 static tree UOBJC_CLASS_decl, UOBJC_METACLASS_decl;
394 static tree UOBJC_SELECTOR_TABLE_decl;
395 static tree UOBJC_MODULES_decl;
396 static tree UOBJC_STRINGS_decl;
398 /* The following are used when compiling a class implementation.
399 implementation_template will normally be an interface, however if
400 none exists this will be equal to implementation_context...it is
401 set in start_class. */
403 static tree implementation_context = NULLT,
404 implementation_template = NULLT;
408 struct imp_entry *next;
411 tree class_decl; /* _OBJC_CLASS_<my_name>; */
412 tree meta_decl; /* _OBJC_METACLASS_<my_name>; */
415 static void handle_impent PROTO((struct imp_entry *));
417 static struct imp_entry *imp_list = 0;
418 static int imp_count = 0; /* `@implementation' */
419 static int cat_count = 0; /* `@category' */
421 static tree objc_class_template, objc_category_template, uprivate_record;
422 static tree objc_protocol_template, objc_selector_template;
423 static tree ucls_super_ref, uucls_super_ref;
425 static tree objc_method_template, objc_ivar_template;
426 static tree objc_symtab_template, objc_module_template;
427 static tree objc_super_template, objc_object_reference;
429 static tree objc_object_id, objc_class_id, objc_id_id;
430 static tree constant_string_id;
431 static tree constant_string_type;
432 static tree UOBJC_SUPER_decl;
434 static tree method_context = NULLT;
435 static int method_slot = 0; /* used by start_method_def */
439 static char *errbuf; /* a buffer for error diagnostics */
441 /* data imported from tree.c */
443 extern struct obstack permanent_obstack, *current_obstack, *rtl_obstack;
444 extern enum debug_info_type write_symbols;
446 /* data imported from toplev.c */
448 extern char *dump_base_name;
450 /* Generate code for GNU or NeXT runtime environment. */
452 #ifdef NEXT_OBJC_RUNTIME
453 int flag_next_runtime = 1;
455 int flag_next_runtime = 0;
458 int flag_typed_selectors;
460 /* Open and close the file for outputting class declarations, if requested. */
462 int flag_gen_declaration = 0;
464 FILE *gen_declaration_file;
466 /* Warn if multiple methods are seen for the same selector, but with
467 different argument types. */
469 int warn_selector = 0;
471 /* Warn if methods required by a protocol are not implemented in the
472 class adopting it. When turned off, methods inherited to that
473 class are also considered implemented */
475 int flag_warn_protocol = 1;
477 /* tells "encode_pointer/encode_aggregate" whether we are generating
478 type descriptors for instance variables (as opposed to methods).
479 Type descriptors for instance variables contain more information
480 than methods (for static typing and embedded structures). This
481 was added to support features being planned for dbkit2. */
483 static int generating_instance_variables = 0;
488 /* the beginning of the file is a new line; check for # */
489 /* With luck, we discover the real source file's name from that
490 and put it in input_filename. */
491 ungetc (check_newline (), finput);
493 /* The line number can be -1 if we had -g3 and the input file
494 had a directive specifying line 0. But we want predefined
495 functions to have a line number of 0, not -1. */
499 /* If gen_declaration desired, open the output file. */
500 if (flag_gen_declaration)
502 int dump_base_name_length = strlen (dump_base_name);
503 register char *dumpname = (char *) xmalloc (dump_base_name_length + 7);
504 strcpy (dumpname, dump_base_name);
505 strcat (dumpname, ".decl");
506 gen_declaration_file = fopen (dumpname, "w");
507 if (gen_declaration_file == 0)
508 pfatal_with_name (dumpname);
511 if (flag_next_runtime)
513 TAG_GETCLASS = "objc_getClass";
514 TAG_GETMETACLASS = "objc_getMetaClass";
515 TAG_MSGSEND = "objc_msgSend";
516 TAG_MSGSENDSUPER = "objc_msgSendSuper";
517 TAG_EXECCLASS = "__objc_execClass";
521 TAG_GETCLASS = "objc_get_class";
522 TAG_GETMETACLASS = "objc_get_meta_class";
523 TAG_MSGSEND = "objc_msg_lookup";
524 TAG_MSGSENDSUPER = "objc_msg_lookup_super";
525 TAG_EXECCLASS = "__objc_exec_class";
526 flag_typed_selectors = 1;
529 if (doing_objc_thang)
536 fatal ("Objective-C text in C source file");
542 if (doing_objc_thang)
543 finish_objc (); /* Objective-C finalization */
545 if (gen_declaration_file)
546 fclose (gen_declaration_file);
561 lang_decode_option (p)
564 if (!strcmp (p, "-lang-objc"))
565 doing_objc_thang = 1;
566 else if (!strcmp (p, "-gen-decls"))
567 flag_gen_declaration = 1;
568 else if (!strcmp (p, "-Wselector"))
570 else if (!strcmp (p, "-Wno-selector"))
572 else if (!strcmp (p, "-Wprotocol"))
573 flag_warn_protocol = 1;
574 else if (!strcmp (p, "-Wno-protocol"))
575 flag_warn_protocol = 0;
576 else if (!strcmp (p, "-fgnu-runtime"))
577 flag_next_runtime = 0;
578 else if (!strcmp (p, "-fno-next-runtime"))
579 flag_next_runtime = 0;
580 else if (!strcmp (p, "-fno-gnu-runtime"))
581 flag_next_runtime = 1;
582 else if (!strcmp (p, "-fnext-runtime"))
583 flag_next_runtime = 1;
585 return c_decode_option (p);
591 define_decl (declarator, declspecs)
595 tree decl = start_decl (declarator, declspecs, 0);
596 finish_decl (decl, NULLT, NULLT);
600 /* Return 1 if LHS and RHS are compatible types for assignment or
601 various other operations. Return 0 if they are incompatible, and
602 return -1 if we choose to not decide. When the operation is
603 REFLEXIVE, check for compatibility in either direction.
605 For statically typed objects, an assignment of the form `a' = `b'
609 `a' and `b' are the same class type, or
610 `a' and `b' are of class types A and B such that B is a descendant of A. */
613 maybe_objc_comptypes (lhs, rhs, reflexive)
617 if (doing_objc_thang)
618 return objc_comptypes (lhs, rhs, reflexive);
623 lookup_method_in_protocol_list (rproto_list, sel_name, class_meth)
631 for (rproto = rproto_list; rproto; rproto = TREE_CHAIN (rproto))
633 p = TREE_VALUE (rproto);
635 if (TREE_CODE (p) == PROTOCOL_INTERFACE_TYPE)
637 if ((fnd = lookup_method (class_meth
638 ? PROTOCOL_CLS_METHODS (p)
639 : PROTOCOL_NST_METHODS (p), sel_name)))
641 else if (PROTOCOL_LIST (p))
642 fnd = lookup_method_in_protocol_list (PROTOCOL_LIST (p), sel_name, class_meth);
645 ; /* an identifier...if we could not find a protocol. */
654 lookup_protocol_in_reflist (rproto_list, lproto)
660 /* make sure the protocol is support by the object on the rhs */
661 if (TREE_CODE (lproto) == PROTOCOL_INTERFACE_TYPE)
664 for (rproto = rproto_list; rproto; rproto = TREE_CHAIN (rproto))
666 p = TREE_VALUE (rproto);
668 if (TREE_CODE (p) == PROTOCOL_INTERFACE_TYPE)
673 else if (PROTOCOL_LIST (p))
674 fnd = lookup_protocol_in_reflist (PROTOCOL_LIST (p), lproto);
682 ; /* an identifier...if we could not find a protocol. */
687 /* Return 1 if LHS and RHS are compatible types for assignment
688 or various other operations. Return 0 if they are incompatible,
689 and return -1 if we choose to not decide. When the operation
690 is REFLEXIVE, check for compatibility in either direction. */
693 objc_comptypes (lhs, rhs, reflexive)
698 /* new clause for protocols */
700 if (TREE_CODE (lhs) == POINTER_TYPE
701 && TREE_CODE (TREE_TYPE (lhs)) == RECORD_TYPE
702 && TREE_CODE (rhs) == POINTER_TYPE
703 && TREE_CODE (TREE_TYPE (rhs)) == RECORD_TYPE)
705 int lhs_is_proto = IS_PROTOCOL_QUALIFIED_ID (lhs);
706 int rhs_is_proto = IS_PROTOCOL_QUALIFIED_ID (rhs);
710 tree lproto, lproto_list = TYPE_PROTOCOL_LIST (lhs);
711 tree rproto, rproto_list;
716 rproto_list = TYPE_PROTOCOL_LIST (rhs);
718 /* Make sure the protocol is supported by the object
720 for (lproto = lproto_list; lproto; lproto = TREE_CHAIN (lproto))
722 p = TREE_VALUE (lproto);
723 rproto = lookup_protocol_in_reflist (rproto_list, p);
726 warning ("object does not conform to the `%s' protocol",
727 IDENTIFIER_POINTER (PROTOCOL_NAME (p)));
730 else if (TYPED_OBJECT (TREE_TYPE (rhs)))
732 tree rname = TYPE_NAME (TREE_TYPE (rhs));
735 /* Make sure the protocol is supported by the object
737 for (lproto = lproto_list; lproto; lproto = TREE_CHAIN (lproto))
739 p = TREE_VALUE (lproto);
741 rinter = lookup_interface (rname);
743 while (rinter && !rproto)
747 rproto_list = CLASS_PROTOCOL_LIST (rinter);
748 rproto = lookup_protocol_in_reflist (rproto_list, p);
751 /* Check for protocols adopted by categories. */
752 cat = CLASS_CATEGORY_LIST (rinter);
753 while (cat && !rproto)
755 rproto_list = CLASS_PROTOCOL_LIST (cat);
756 rproto = lookup_protocol_in_reflist (rproto_list, p);
758 cat = CLASS_CATEGORY_LIST (cat);
761 rinter = lookup_interface (CLASS_SUPER_NAME (rinter));
764 warning ("class `%s' does not implement the `%s' protocol",
765 IDENTIFIER_POINTER (TYPE_NAME (TREE_TYPE (rhs))),
766 IDENTIFIER_POINTER (PROTOCOL_NAME (p)));
770 return 1; /* may change...based on whether there was any mismatch */
772 else if (rhs_is_proto)
774 /* lhs is not a protocol...warn if it is statically typed */
776 if (TYPED_OBJECT (TREE_TYPE (lhs)))
779 return 1; /* one of the types is a protocol */
782 return -1; /* defer to comptypes */
784 else if (TREE_CODE (lhs) == RECORD_TYPE && TREE_CODE (rhs) == RECORD_TYPE)
785 ; /* fall thru...this is the case we have been handling all along */
787 return -1; /* defer to comptypes */
789 /* End of new protocol support. */
791 /* `id' = `<class> *', `<class> *' = `id' */
793 if ((TYPE_NAME (lhs) == objc_object_id && TYPED_OBJECT (rhs))
794 || (TYPE_NAME (rhs) == objc_object_id && TYPED_OBJECT (lhs)))
797 /* `id' = `Class', `Class' = `id' */
799 else if ((TYPE_NAME (lhs) == objc_object_id
800 && TYPE_NAME (rhs) == objc_class_id)
801 || (TYPE_NAME (lhs) == objc_class_id
802 && TYPE_NAME (rhs) == objc_object_id))
805 /* `<class> *' = `<class> *' */
807 else if (TYPED_OBJECT (lhs) && TYPED_OBJECT (rhs))
809 tree lname = TYPE_NAME (lhs);
810 tree rname = TYPE_NAME (rhs);
816 /* If the left hand side is a super class of the right hand side,
818 for (inter = lookup_interface (rname); inter;
819 inter = lookup_interface (CLASS_SUPER_NAME (inter)))
820 if (lname == CLASS_SUPER_NAME (inter))
823 /* Allow the reverse when reflexive. */
825 for (inter = lookup_interface (lname); inter;
826 inter = lookup_interface (CLASS_SUPER_NAME (inter)))
827 if (rname == CLASS_SUPER_NAME (inter))
833 return -1; /* defer to comptypes */
836 /* Called from c-decl.c before all calls to rest_of_decl_compilation. */
839 objc_check_decl (decl)
842 tree type = TREE_TYPE (decl);
844 if (TREE_CODE (type) == RECORD_TYPE
845 && TREE_STATIC_TEMPLATE (type)
846 && type != constant_string_type)
848 error_with_decl (decl, "`%s' cannot be statically allocated");
849 fatal ("statically allocated objects not supported");
854 maybe_objc_check_decl (decl)
857 if (doing_objc_thang)
858 objc_check_decl (decl);
861 /* Implement static typing. At this point, we know we have an interface. */
864 get_static_reference (interface, protocols)
868 tree type = xref_tag (RECORD_TYPE, interface);
872 tree t, m = TYPE_MAIN_VARIANT (type);
873 struct obstack *ambient_obstack = current_obstack;
875 current_obstack = &permanent_obstack;
876 t = copy_node (type);
877 TYPE_BINFO (t) = make_tree_vec (2);
879 /* Add this type to the chain of variants of TYPE. */
880 TYPE_NEXT_VARIANT (t) = TYPE_NEXT_VARIANT (m);
881 TYPE_NEXT_VARIANT (m) = t;
883 current_obstack = ambient_obstack;
885 /* Look up protocols and install in lang specific list. */
886 TYPE_PROTOCOL_LIST (t) = lookup_and_install_protocols (protocols);
888 /* This forces a new pointer type to be created later
889 (in build_pointer_type)...so that the new template
890 we just created will actually be used...what a hack! */
891 if (TYPE_POINTER_TO (t))
892 TYPE_POINTER_TO (t) = NULL;
901 get_object_reference (protocols)
904 tree type_decl = lookup_name (objc_id_id);
907 if (type_decl && TREE_CODE (type_decl) == TYPE_DECL)
909 type = TREE_TYPE (type_decl);
910 if (TYPE_MAIN_VARIANT (type) != id_type)
911 warning ("Unexpected type for `id' (%s)",
912 gen_declaration (type, errbuf));
916 fatal ("Undefined type `id', please import <objc/objc.h>");
919 /* This clause creates a new pointer type that is qualified with
920 the protocol specification...this info is used later to do more
921 elaborate type checking. */
924 tree t, m = TYPE_MAIN_VARIANT (type);
925 struct obstack *ambient_obstack = current_obstack;
927 current_obstack = &permanent_obstack;
928 t = copy_node (type);
929 TYPE_BINFO (t) = make_tree_vec (2);
931 /* Add this type to the chain of variants of TYPE. */
932 TYPE_NEXT_VARIANT (t) = TYPE_NEXT_VARIANT (m);
933 TYPE_NEXT_VARIANT (m) = t;
935 current_obstack = ambient_obstack;
937 /* look up protocols...and install in lang specific list */
938 TYPE_PROTOCOL_LIST (t) = lookup_and_install_protocols (protocols);
940 /* This forces a new pointer type to be created later
941 (in build_pointer_type)...so that the new template
942 we just created will actually be used...what a hack! */
943 if (TYPE_POINTER_TO (t))
944 TYPE_POINTER_TO (t) = NULL;
952 lookup_and_install_protocols (protocols)
957 tree return_value = protocols;
959 for (proto = protocols; proto; proto = TREE_CHAIN (proto))
961 tree ident = TREE_VALUE (proto);
962 tree p = lookup_protocol (ident);
966 error ("Cannot find protocol declaration for `%s'",
967 IDENTIFIER_POINTER (ident));
969 TREE_CHAIN (prev) = TREE_CHAIN (proto);
971 return_value = TREE_CHAIN (proto);
975 /* replace identifier with actual protocol node */
976 TREE_VALUE (proto) = p;
983 /* Create and push a decl for a built-in external variable or field NAME.
985 TYPE is its data type. */
988 create_builtin_decl (code, type, name)
993 tree decl = build_decl (code, get_identifier (name), type);
994 if (code == VAR_DECL)
996 TREE_STATIC (decl) = 1;
997 make_decl_rtl (decl, 0, 1);
1003 /* purpose: "play" parser, creating/installing representations
1004 of the declarations that are required by Objective-C.
1008 type_spec--------->sc_spec
1009 (tree_list) (tree_list)
1012 identifier_node identifier_node */
1015 synth_module_prologue ()
1020 /* defined in `objc.h' */
1021 objc_object_id = get_identifier (TAG_OBJECT);
1023 objc_object_reference = xref_tag (RECORD_TYPE, objc_object_id);
1025 id_type = build_pointer_type (objc_object_reference);
1027 objc_id_id = get_identifier (TYPE_ID);
1028 objc_class_id = get_identifier (TAG_CLASS);
1030 objc_class_type = build_pointer_type (xref_tag (RECORD_TYPE, objc_class_id));
1031 protocol_type = build_pointer_type (xref_tag (RECORD_TYPE,
1032 get_identifier (PROTOCOL_OBJECT_CLASS_NAME)));
1034 /* Declare type of selector-objects that represent an operation name. */
1036 #ifdef OBJC_INT_SELECTORS
1037 /* `unsigned int' */
1038 selector_type = unsigned_type_node;
1040 /* `struct objc_selector *' */
1042 = build_pointer_type (xref_tag (RECORD_TYPE,
1043 get_identifier (TAG_SELECTOR)));
1044 #endif /* not OBJC_INT_SELECTORS */
1046 /* Forward declare type, or else the prototype for msgSendSuper will
1049 super_p = build_pointer_type (xref_tag (RECORD_TYPE,
1050 get_identifier (TAG_SUPER)));
1053 /* id objc_msgSend (id, SEL, ...); */
1056 = build_function_type (id_type,
1057 tree_cons (NULL_TREE, id_type,
1058 tree_cons (NULLT, selector_type, NULLT)));
1060 if (! flag_next_runtime)
1062 umsg_decl = build_decl (FUNCTION_DECL,
1063 get_identifier (TAG_MSGSEND), temp_type);
1064 DECL_EXTERNAL (umsg_decl) = 1;
1065 TREE_PUBLIC (umsg_decl) = 1;
1066 DECL_INLINE (umsg_decl) = 1;
1068 if (flag_traditional && TAG_MSGSEND[0] != '_')
1069 DECL_BUILT_IN_NONANSI (umsg_decl) = 1;
1071 make_decl_rtl (umsg_decl, NULL_PTR, 1);
1072 pushdecl (umsg_decl);
1075 umsg_decl = builtin_function (TAG_MSGSEND, temp_type, NOT_BUILT_IN, 0);
1077 /* id objc_msgSendSuper (struct objc_super *, SEL, ...); */
1080 = build_function_type (id_type,
1081 tree_cons (NULL_TREE, super_p,
1082 tree_cons (NULLT, selector_type, NULLT)));
1084 umsg_super_decl = builtin_function (TAG_MSGSENDSUPER,
1085 temp_type, NOT_BUILT_IN, 0);
1087 /* id objc_getClass (const char *); */
1089 temp_type = build_function_type (id_type,
1091 const_string_type_node,
1092 tree_cons (NULLT, void_type_node, NULLT)));
1095 = builtin_function (TAG_GETCLASS, temp_type, NOT_BUILT_IN, 0);
1097 /* id objc_getMetaClass (const char *); */
1099 objc_get_meta_class_decl
1100 = builtin_function (TAG_GETMETACLASS, temp_type, NOT_BUILT_IN, 0);
1102 /* static SEL _OBJC_SELECTOR_TABLE[]; */
1104 if (! flag_next_runtime)
1106 if (flag_typed_selectors)
1108 /* supress outputting debug symbols, because
1109 dbxout_init hasn'r been called yet... */
1110 enum debug_info_type save_write_symbols = write_symbols;
1111 write_symbols = NO_DEBUG;
1113 build_selector_template ();
1114 temp_type = build_array_type (objc_selector_template, NULLT);
1116 write_symbols = save_write_symbols;
1119 temp_type = build_array_type (selector_type, NULLT);
1121 layout_type (temp_type);
1122 UOBJC_SELECTOR_TABLE_decl
1123 = create_builtin_decl (VAR_DECL, temp_type,
1124 "_OBJC_SELECTOR_TABLE");
1128 generate_forward_declaration_to_string_table ();
1130 /* Forward declare constant_string_id and constant_string_type. */
1131 constant_string_id = get_identifier (STRING_OBJECT_CLASS_NAME);
1132 constant_string_type = xref_tag (RECORD_TYPE, constant_string_id);
1135 /* Custom build_string which sets TREE_TYPE! */
1138 my_build_string (len, str)
1143 tree a_string = build_string (len, str);
1144 /* Some code from combine_strings, which is local to c-parse.y. */
1145 if (TREE_TYPE (a_string) == int_array_type_node)
1148 TREE_TYPE (a_string) =
1149 build_array_type (wide_flag ? integer_type_node : char_type_node,
1150 build_index_type (build_int_2 (len - 1, 0)));
1152 TREE_CONSTANT (a_string) = 1; /* puts string in the ".text" segment */
1153 TREE_STATIC (a_string) = 1;
1158 /* Return a newly constructed OBJC_STRING_CST node whose value is
1159 the LEN characters at STR.
1160 The TREE_TYPE is not initialized. */
1163 build_objc_string (len, str)
1167 tree s = build_string (len, str);
1169 TREE_SET_CODE (s, OBJC_STRING_CST);
1173 /* Given a chain of OBJC_STRING_CST's, build a static instance of
1174 NXConstantString which points at the concatenation of those strings.
1175 We place the string object in the __string_objects section of the
1176 __OBJC segment. The Objective-C runtime will initialize the isa
1177 pointers of the string objects to point at the NXConstantString
1181 build_objc_string_object (strings)
1184 tree string, initlist, constructor;
1187 if (!doing_objc_thang)
1190 if (lookup_interface (constant_string_id) == NULLT)
1192 error ("Cannot find interface declaration for `%s'",
1193 IDENTIFIER_POINTER (constant_string_id));
1194 return error_mark_node;
1197 add_class_reference (constant_string_id);
1199 /* combine_strings will work for OBJC_STRING_CST's too. */
1200 string = combine_strings (strings);
1201 TREE_SET_CODE (string, STRING_CST);
1202 length = TREE_STRING_LENGTH (string) - 1;
1204 /* & ((NXConstantString) {0, string, length}) */
1206 initlist = build_tree_list (NULLT, build_int_2 (0, 0));
1207 initlist = tree_cons (NULLT, build_unary_op (ADDR_EXPR, string, 1),
1209 initlist = tree_cons (NULLT, build_int_2 (length, 0), initlist);
1210 constructor = build_constructor (constant_string_type,
1211 nreverse (initlist));
1213 return build_unary_op (ADDR_EXPR, constructor, 1);
1216 /* Build a static constant CONSTRUCTOR
1217 with type TYPE and elements ELTS. */
1220 build_constructor (type, elts)
1223 tree constructor = build (CONSTRUCTOR, type, NULL_TREE, elts);
1225 TREE_CONSTANT (constructor) = 1;
1226 TREE_STATIC (constructor) = 1;
1227 TREE_READONLY (constructor) = 1;
1232 /* Take care of defining and initializing _OBJC_SYMBOLS. */
1234 /* Predefine the following data type:
1242 void *defs[cls_def_cnt + cat_def_cnt];
1246 build_objc_symtab_template ()
1248 tree field_decl, field_decl_chain, index;
1250 objc_symtab_template = start_struct (RECORD_TYPE, get_identifier (UTAG_SYMTAB));
1252 /* long sel_ref_cnt; */
1254 field_decl = create_builtin_decl (FIELD_DECL,
1255 long_integer_type_node,
1257 field_decl_chain = field_decl;
1261 field_decl = create_builtin_decl (FIELD_DECL,
1262 build_pointer_type (selector_type),
1264 chainon (field_decl_chain, field_decl);
1266 /* short cls_def_cnt; */
1268 field_decl = create_builtin_decl (FIELD_DECL,
1269 short_integer_type_node,
1271 chainon (field_decl_chain, field_decl);
1273 /* short cat_def_cnt; */
1275 field_decl = create_builtin_decl (FIELD_DECL,
1276 short_integer_type_node,
1278 chainon (field_decl_chain, field_decl);
1280 /* void *defs[cls_def_cnt + cat_def_cnt]; */
1282 index = build_index_type (build_int_2 (imp_count + cat_count - 1,
1283 imp_count == 0 && cat_count == 0
1285 field_decl = create_builtin_decl (FIELD_DECL,
1286 build_array_type (ptr_type_node, index),
1288 chainon (field_decl_chain, field_decl);
1290 finish_struct (objc_symtab_template, field_decl_chain);
1293 /* Create the initial value for the `defs' field of _objc_symtab.
1294 This is a CONSTRUCTOR. */
1297 init_def_list (type)
1300 tree expr, initlist = NULLT;
1301 struct imp_entry *impent;
1304 for (impent = imp_list; impent; impent = impent->next)
1306 if (TREE_CODE (impent->imp_context) == CLASS_IMPLEMENTATION_TYPE)
1308 expr = build_unary_op (ADDR_EXPR, impent->class_decl, 0);
1309 initlist = tree_cons (NULLT, expr, initlist);
1314 for (impent = imp_list; impent; impent = impent->next)
1316 if (TREE_CODE (impent->imp_context) == CATEGORY_IMPLEMENTATION_TYPE)
1318 expr = build_unary_op (ADDR_EXPR, impent->class_decl, 0);
1319 initlist = tree_cons (NULLT, expr, initlist);
1322 return build_constructor (type, nreverse (initlist));
1325 /* Construct the initial value for all of _objc_symtab. */
1328 init_objc_symtab (type)
1333 /* sel_ref_cnt = { ..., 5, ... } */
1335 initlist = build_tree_list (NULLT, build_int_2 (0, 0));
1337 /* refs = { ..., _OBJC_SELECTOR_TABLE, ... } */
1339 if (flag_next_runtime || ! sel_ref_chain)
1340 initlist = tree_cons (NULLT, build_int_2 (0, 0), initlist);
1342 initlist = tree_cons (NULLT,
1343 build_unary_op (ADDR_EXPR,
1344 UOBJC_SELECTOR_TABLE_decl, 1),
1347 /* cls_def_cnt = { ..., 5, ... } */
1349 initlist = tree_cons (NULLT, build_int_2 (imp_count, 0), initlist);
1351 /* cat_def_cnt = { ..., 5, ... } */
1353 initlist = tree_cons (NULLT, build_int_2 (cat_count, 0), initlist);
1355 /* cls_def = { ..., { &Foo, &Bar, ...}, ... } */
1357 if (imp_count || cat_count)
1359 tree field = TYPE_FIELDS (type);
1360 field = TREE_CHAIN (TREE_CHAIN (TREE_CHAIN (TREE_CHAIN (field))));
1362 initlist = tree_cons (NULLT, init_def_list (TREE_TYPE (field)),
1366 return build_constructor (type, nreverse (initlist));
1369 /* Push forward-declarations of all the categories
1370 so that init_def_list can use them in a CONSTRUCTOR. */
1373 forward_declare_categories ()
1375 struct imp_entry *impent;
1376 tree sav = implementation_context;
1377 for (impent = imp_list; impent; impent = impent->next)
1379 if (TREE_CODE (impent->imp_context) == CATEGORY_IMPLEMENTATION_TYPE)
1381 /* Set an invisible arg to synth_id_with_class_suffix. */
1382 implementation_context = impent->imp_context;
1384 = create_builtin_decl (VAR_DECL, objc_category_template,
1385 IDENTIFIER_POINTER (synth_id_with_class_suffix ("_OBJC_CATEGORY", implementation_context)));
1388 implementation_context = sav;
1391 /* Create the declaration of _OBJC_SYMBOLS, with type `strict _objc_symtab'
1392 and initialized appropriately. */
1395 generate_objc_symtab_decl ()
1399 if (!objc_category_template)
1400 build_category_template ();
1402 /* forward declare categories */
1404 forward_declare_categories ();
1406 if (!objc_symtab_template)
1407 build_objc_symtab_template ();
1409 sc_spec = build_tree_list (NULLT, ridpointers[(int) RID_STATIC]);
1411 UOBJC_SYMBOLS_decl = start_decl (get_identifier ("_OBJC_SYMBOLS"),
1412 tree_cons (NULLT, objc_symtab_template, sc_spec), 1);
1414 end_temporary_allocation (); /* start_decl trying to be smart about inits */
1415 TREE_USED (UOBJC_SYMBOLS_decl) = 1;
1416 DECL_IGNORED_P (UOBJC_SYMBOLS_decl) = 1;
1417 finish_decl (UOBJC_SYMBOLS_decl,
1418 init_objc_symtab (TREE_TYPE (UOBJC_SYMBOLS_decl)),
1423 init_module_descriptor (type)
1426 tree initlist, expr;
1428 /* version = { 1, ... } */
1430 expr = build_int_2 (OBJC_VERSION, 0);
1431 initlist = build_tree_list (NULLT, expr);
1433 /* size = { ..., sizeof (struct objc_module), ... } */
1435 expr = size_in_bytes (objc_module_template);
1436 initlist = tree_cons (NULLT, expr, initlist);
1438 /* name = { ..., "foo.m", ... } */
1440 expr = add_objc_string (get_identifier (input_filename), class_names);
1441 initlist = tree_cons (NULLT, expr, initlist);
1443 /* symtab = { ..., _OBJC_SYMBOLS, ... } */
1445 if (UOBJC_SYMBOLS_decl)
1446 expr = build_unary_op (ADDR_EXPR, UOBJC_SYMBOLS_decl, 0);
1448 expr = build_int_2 (0, 0);
1449 initlist = tree_cons (NULLT, expr, initlist);
1451 return build_constructor (type, nreverse (initlist));
1454 /* Write out the data structures to describe Objective C classes defined.
1455 If appropriate, compile and output a setup function to initialize them.
1456 Return a string which is the name of a function to call to initialize
1457 the Objective C data structures for this file (and perhaps for other files
1460 struct objc_module { ... } _OBJC_MODULE = { ... };
1465 build_module_descriptor ()
1467 tree decl_specs, field_decl, field_decl_chain;
1469 objc_module_template = start_struct (RECORD_TYPE, get_identifier (UTAG_MODULE));
1473 decl_specs = build_tree_list (NULLT, ridpointers[(int) RID_LONG]);
1474 field_decl = get_identifier ("version");
1475 field_decl = grokfield (input_filename, lineno, field_decl, decl_specs, NULLT);
1476 field_decl_chain = field_decl;
1480 decl_specs = build_tree_list (NULLT, ridpointers[(int) RID_LONG]);
1481 field_decl = get_identifier ("size");
1482 field_decl = grokfield (input_filename, lineno, field_decl, decl_specs, NULLT);
1483 chainon (field_decl_chain, field_decl);
1487 decl_specs = build_tree_list (NULLT, ridpointers[(int) RID_CHAR]);
1488 field_decl = build1 (INDIRECT_REF, NULLT, get_identifier ("name"));
1489 field_decl = grokfield (input_filename, lineno, field_decl, decl_specs, NULLT);
1490 chainon (field_decl_chain, field_decl);
1492 /* struct objc_symtab *symtab; */
1494 decl_specs = get_identifier (UTAG_SYMTAB);
1495 decl_specs = build_tree_list (NULLT, xref_tag (RECORD_TYPE, decl_specs));
1496 field_decl = build1 (INDIRECT_REF, NULLT, get_identifier ("symtab"));
1497 field_decl = grokfield (input_filename, lineno, field_decl, decl_specs, NULLT);
1498 chainon (field_decl_chain, field_decl);
1500 finish_struct (objc_module_template, field_decl_chain);
1502 /* create an instance of "objc_module" */
1504 decl_specs = tree_cons (NULLT, objc_module_template,
1505 build_tree_list (NULLT, ridpointers[(int) RID_STATIC]));
1507 UOBJC_MODULES_decl = start_decl (get_identifier ("_OBJC_MODULES"),
1510 end_temporary_allocation (); /* start_decl trying to be smart about inits */
1511 DECL_IGNORED_P (UOBJC_MODULES_decl) = 1;
1512 finish_decl (UOBJC_MODULES_decl,
1513 init_module_descriptor (TREE_TYPE (UOBJC_MODULES_decl)),
1516 /* Mark the decl to avoid "defined but not used" warning. */
1517 DECL_IN_SYSTEM_HEADER (UOBJC_MODULES_decl) = 1;
1519 /* Generate a constructor call for the module descriptor.
1520 This code was generated by reading the grammar rules
1521 of c-parse.y; Therefore, it may not be the most efficient
1522 way of generating the requisite code. */
1524 if (flag_next_runtime)
1528 tree parms, function_decl, decelerator, void_list_node;
1530 extern tree get_file_function_name ();
1531 tree init_function_name = get_file_function_name ('I');
1533 /* Declare void __objc_execClass (void*); */
1535 void_list_node = build_tree_list (NULL_TREE, void_type_node);
1537 = build_function_type (void_type_node,
1538 tree_cons (NULL_TREE, ptr_type_node,
1540 function_decl = build_decl (FUNCTION_DECL,
1541 get_identifier (TAG_EXECCLASS),
1543 DECL_EXTERNAL (function_decl) = 1;
1544 TREE_PUBLIC (function_decl) = 1;
1546 pushdecl (function_decl);
1547 rest_of_decl_compilation (function_decl, 0, 0, 0);
1550 = build_tree_list (NULLT,
1551 build_unary_op (ADDR_EXPR, UOBJC_MODULES_decl, 0));
1552 decelerator = build_function_call (function_decl, parms);
1554 /* void _GLOBAL_$I$<gnyf> () {objc_execClass (&L_OBJC_MODULES);} */
1556 start_function (void_list_node,
1557 build_parse_node (CALL_EXPR, init_function_name,
1558 /* This has the format of the output
1559 of get_parm_info. */
1560 tree_cons (NULL_TREE, NULL_TREE,
1564 #if 0 /* This should be turned back on later
1565 for the systems where collect is not needed. */
1566 /* Make these functions nonglobal
1567 so each file can use the same name. */
1568 TREE_PUBLIC (current_function_decl) = 0;
1570 TREE_USED (current_function_decl) = 1;
1571 store_parm_decls ();
1573 assemble_external (function_decl);
1574 c_expand_expr_stmt (decelerator);
1576 TREE_PUBLIC (current_function_decl) = 1;
1578 function_decl = current_function_decl;
1579 finish_function (0);
1581 /* Return the name of the constructor function. */
1582 return XSTR (XEXP (DECL_RTL (function_decl), 0), 0);
1586 /* extern const char _OBJC_STRINGS[]; */
1589 generate_forward_declaration_to_string_table ()
1591 tree sc_spec, decl_specs, expr_decl;
1593 sc_spec = tree_cons (NULLT, ridpointers[(int) RID_EXTERN], NULLT);
1594 decl_specs = tree_cons (NULLT, ridpointers[(int) RID_CHAR], sc_spec);
1596 expr_decl = build_nt (ARRAY_REF, get_identifier ("_OBJC_STRINGS"), NULLT);
1598 UOBJC_STRINGS_decl = define_decl (expr_decl, decl_specs);
1601 /* Output all strings. */
1606 tree sc_spec, decl_specs, expr_decl;
1607 tree chain, string_expr;
1610 for (chain = class_names_chain; chain; chain = TREE_CHAIN (chain))
1612 string = TREE_VALUE (chain);
1613 decl = TREE_PURPOSE (chain);
1614 sc_spec = tree_cons (NULLT, ridpointers[(int) RID_STATIC], NULLT);
1615 decl_specs = tree_cons (NULLT, ridpointers[(int) RID_CHAR], sc_spec);
1616 expr_decl = build_nt (ARRAY_REF, DECL_NAME (decl), NULLT);
1617 decl = start_decl (expr_decl, decl_specs, 1);
1618 end_temporary_allocation ();
1619 string_expr = my_build_string (IDENTIFIER_LENGTH (string) + 1,
1620 IDENTIFIER_POINTER (string));
1621 finish_decl (decl, string_expr, NULLT);
1624 for (chain = meth_var_names_chain; chain; chain = TREE_CHAIN (chain))
1626 string = TREE_VALUE (chain);
1627 decl = TREE_PURPOSE (chain);
1628 sc_spec = tree_cons (NULLT, ridpointers[(int) RID_STATIC], NULLT);
1629 decl_specs = tree_cons (NULLT, ridpointers[(int) RID_CHAR], sc_spec);
1630 expr_decl = build_nt (ARRAY_REF, DECL_NAME (decl), NULLT);
1631 decl = start_decl (expr_decl, decl_specs, 1);
1632 end_temporary_allocation ();
1633 string_expr = my_build_string (IDENTIFIER_LENGTH (string) + 1,
1634 IDENTIFIER_POINTER (string));
1635 finish_decl (decl, string_expr, NULLT);
1638 for (chain = meth_var_types_chain; chain; chain = TREE_CHAIN (chain))
1640 string = TREE_VALUE (chain);
1641 decl = TREE_PURPOSE (chain);
1642 sc_spec = tree_cons (NULLT, ridpointers[(int) RID_STATIC], NULLT);
1643 decl_specs = tree_cons (NULLT, ridpointers[(int) RID_CHAR], sc_spec);
1644 expr_decl = build_nt (ARRAY_REF, DECL_NAME (decl), NULLT);
1645 decl = start_decl (expr_decl, decl_specs, 1);
1646 end_temporary_allocation ();
1647 string_expr = my_build_string (IDENTIFIER_LENGTH (string) + 1,
1648 IDENTIFIER_POINTER (string));
1649 finish_decl (decl, string_expr, NULLT);
1654 build_selector_reference_decl (name)
1659 struct obstack *save_current_obstack = current_obstack;
1660 struct obstack *save_rtl_obstack = rtl_obstack;
1663 sprintf (buf, "_OBJC_SELECTOR_REFERENCES_%d", idx++);
1666 rtl_obstack = current_obstack = &permanent_obstack;
1667 ident = get_identifier (buf);
1669 decl = build_decl (VAR_DECL, ident, selector_type);
1670 DECL_EXTERNAL (decl) = 1;
1671 TREE_PUBLIC (decl) = 1;
1672 TREE_USED (decl) = 1;
1673 TREE_READONLY (decl) = 1;
1675 make_decl_rtl (decl, 0, 1); /* usually called from `rest_of_decl_compilation' */
1676 pushdecl_top_level (decl); /* our `extended/custom' pushdecl in c-decl.c */
1678 current_obstack = save_current_obstack;
1679 rtl_obstack = save_rtl_obstack;
1684 /* Just a handy wrapper for add_objc_string. */
1687 build_selector (ident)
1690 tree expr = add_objc_string (ident, meth_var_names);
1691 if (flag_typed_selectors)
1694 return build_c_cast (selector_type, expr); /* cast! */
1697 /* Synthesize the following expr: (char *)&_OBJC_STRINGS[<offset>]
1698 The cast stops the compiler from issuing the following message:
1699 grok.m: warning: initialization of non-const * pointer from const *
1700 grok.m: warning: initialization between incompatible pointer types. */
1703 build_msg_pool_reference (offset)
1706 tree expr = build_int_2 (offset, 0);
1709 expr = build_array_ref (UOBJC_STRINGS_decl, expr);
1710 expr = build_unary_op (ADDR_EXPR, expr, 0);
1712 cast = build_tree_list (build_tree_list (NULLT, ridpointers[(int) RID_CHAR]),
1713 build1 (INDIRECT_REF, NULLT, NULLT));
1714 TREE_TYPE (expr) = groktypename (cast);
1719 init_selector (offset)
1722 tree expr = build_msg_pool_reference (offset);
1723 TREE_TYPE (expr) = selector_type; /* cast */
1728 build_selector_translation_table ()
1730 tree sc_spec, decl_specs;
1731 tree chain, initlist = NULLT;
1733 tree decl, var_decl, name;
1735 /* The corresponding pop_obstacks is in finish_decl,
1736 called at the end of this function. */
1737 if (! flag_next_runtime)
1738 push_obstacks_nochange ();
1740 for (chain = sel_ref_chain; chain; chain = TREE_CHAIN (chain))
1744 expr = build_selector (TREE_VALUE (chain));
1746 if (flag_next_runtime)
1748 name = DECL_NAME (TREE_PURPOSE (chain));
1750 sc_spec = build_tree_list (NULLT, ridpointers[(int) RID_STATIC]);
1752 /* static SEL _OBJC_SELECTOR_REFERENCES_n = ...; */
1753 decl_specs = tree_cons (NULLT, selector_type, sc_spec);
1757 /* the `decl' that is returned from start_decl is the one that we
1758 forward declared in `build_selector_reference' */
1759 decl = start_decl (var_decl, decl_specs, 1);
1762 /* add one for the '\0' character */
1763 offset += IDENTIFIER_LENGTH (TREE_VALUE (chain)) + 1;
1765 if (flag_next_runtime)
1767 end_temporary_allocation ();
1768 finish_decl (decl, expr, NULLT);
1772 if (flag_typed_selectors)
1774 tree eltlist = NULLT;
1775 tree encoding = get_proto_encoding (TREE_PURPOSE (chain));
1776 eltlist = tree_cons (NULLT, expr, NULLT);
1777 eltlist = tree_cons (NULLT, encoding, eltlist);
1778 expr = build_constructor (objc_selector_template,
1779 nreverse (eltlist));
1781 initlist = tree_cons (NULLT, expr, initlist);
1786 if (! flag_next_runtime)
1788 /* Cause the variable and its initial value to be actually output. */
1789 DECL_EXTERNAL (UOBJC_SELECTOR_TABLE_decl) = 0;
1790 TREE_STATIC (UOBJC_SELECTOR_TABLE_decl) = 1;
1791 /* NULL terminate the list and fix the decl for output. */
1792 initlist = tree_cons (NULLT, build_int_2 (0, 0), initlist);
1793 DECL_INITIAL (UOBJC_SELECTOR_TABLE_decl) = (tree) 1;
1794 initlist = build_constructor (TREE_TYPE (UOBJC_SELECTOR_TABLE_decl),
1795 nreverse (initlist));
1796 finish_decl (UOBJC_SELECTOR_TABLE_decl, initlist, NULLT);
1797 current_function_decl = NULLT;
1803 get_proto_encoding (proto)
1811 if (! METHOD_ENCODING (proto))
1813 tmp_decl = build_tmp_function_decl ();
1814 hack_method_prototype (proto, tmp_decl);
1815 encoding = encode_method_prototype (proto, tmp_decl);
1816 METHOD_ENCODING (proto) = encoding;
1819 encoding = METHOD_ENCODING (proto);
1821 return add_objc_string (encoding, meth_var_types);
1824 return build_int_2 (0, 0);
1827 /* sel_ref_chain is a list whose "value" fields will be instances of
1828 identifier_node that represent the selector. */
1831 build_typed_selector_reference (ident, proto)
1834 tree *chain = &sel_ref_chain;
1840 if (TREE_PURPOSE (*chain) == ident && TREE_VALUE (*chain) == proto)
1841 goto return_at_index;
1843 chain = &TREE_CHAIN (*chain);
1846 *chain = perm_tree_cons (proto, ident, NULLT);
1849 expr = build_unary_op (ADDR_EXPR,
1850 build_array_ref (UOBJC_SELECTOR_TABLE_decl,
1851 build_int_2 (index, 0)),
1853 return build_c_cast (selector_type, expr);
1857 build_selector_reference (ident)
1860 tree *chain = &sel_ref_chain;
1866 if (TREE_VALUE (*chain) == ident)
1867 return (flag_next_runtime
1868 ? TREE_PURPOSE (*chain)
1869 : build_array_ref (UOBJC_SELECTOR_TABLE_decl,
1870 build_int_2 (index, 0)));
1873 chain = &TREE_CHAIN (*chain);
1876 expr = build_selector_reference_decl (ident);
1878 *chain = perm_tree_cons (expr, ident, NULLT);
1880 return (flag_next_runtime
1882 : build_array_ref (UOBJC_SELECTOR_TABLE_decl,
1883 build_int_2 (index, 0)));
1887 build_class_reference_decl (name)
1892 struct obstack *save_current_obstack = current_obstack;
1893 struct obstack *save_rtl_obstack = rtl_obstack;
1896 sprintf (buf, "_OBJC_CLASS_REFERENCES_%d", idx++);
1899 rtl_obstack = current_obstack = &permanent_obstack;
1900 ident = get_identifier (buf);
1902 decl = build_decl (VAR_DECL, ident, objc_class_type);
1903 DECL_EXTERNAL (decl) = 1;
1904 TREE_PUBLIC (decl) = 1;
1905 TREE_USED (decl) = 1;
1906 TREE_READONLY (decl) = 1;
1908 make_decl_rtl (decl, 0, 1); /* usually called from `rest_of_decl_compilation' */
1909 pushdecl_top_level (decl); /* our `extended/custom' pushdecl in c-decl.c */
1911 current_obstack = save_current_obstack;
1912 rtl_obstack = save_rtl_obstack;
1917 /* Create a class reference, but don't create a variable to reference
1921 add_class_reference (ident)
1926 if ((chain = cls_ref_chain))
1931 if (ident == TREE_VALUE (chain))
1935 chain = TREE_CHAIN (chain);
1939 /* append to the end of the list */
1940 TREE_CHAIN (tail) = perm_tree_cons (NULLT, ident, NULLT);
1943 cls_ref_chain = perm_tree_cons (NULLT, ident, NULLT);
1946 /* Get a class reference, creating it if necessary. Also create the
1947 reference variable. */
1950 get_class_reference (ident)
1953 if (flag_next_runtime)
1958 for (chain = &cls_ref_chain; *chain; chain = &TREE_CHAIN (*chain))
1959 if (TREE_VALUE (*chain) == ident)
1961 if (! TREE_PURPOSE (*chain))
1962 TREE_PURPOSE (*chain) = build_class_reference_decl (ident);
1963 return TREE_PURPOSE (*chain);
1966 decl = build_class_reference_decl (ident);
1967 *chain = perm_tree_cons (decl, ident, NULLT);
1974 add_class_reference (ident);
1976 params = build_tree_list (NULLT,
1977 my_build_string (IDENTIFIER_LENGTH (ident) + 1,
1978 IDENTIFIER_POINTER (ident)));
1980 assemble_external (objc_get_class_decl);
1981 return build_function_call (objc_get_class_decl, params);
1985 /* sel_refdef_chain is a list whose "value" fields will be instances
1986 of identifier_node that represent the selector. It returns the
1987 offset of the selector from the beginning of the _OBJC_STRINGS
1988 pool. This offset is typically used by init_selector during code
1991 For each string section we have a chain which maps identifier nodes
1992 to decls for the strings. */
1995 add_objc_string (ident, section)
1997 enum string_section section;
2001 if (section == class_names)
2002 chain = &class_names_chain;
2003 else if (section == meth_var_names)
2004 chain = &meth_var_names_chain;
2005 else if (section == meth_var_types)
2006 chain = &meth_var_types_chain;
2010 if (TREE_VALUE (*chain) == ident)
2011 return build_unary_op (ADDR_EXPR, TREE_PURPOSE (*chain), 1);
2013 chain = &TREE_CHAIN (*chain);
2016 decl = build_objc_string_decl (ident, section);
2018 *chain = perm_tree_cons (decl, ident, NULLT);
2020 return build_unary_op (ADDR_EXPR, decl, 1);
2024 build_objc_string_decl (name, section)
2026 enum string_section section;
2030 struct obstack *save_current_obstack = current_obstack;
2031 struct obstack *save_rtl_obstack = rtl_obstack;
2032 static int class_names_idx = 0;
2033 static int meth_var_names_idx = 0;
2034 static int meth_var_types_idx = 0;
2036 if (section == class_names)
2037 sprintf (buf, "_OBJC_CLASS_NAME_%d", class_names_idx++);
2038 else if (section == meth_var_names)
2039 sprintf (buf, "_OBJC_METH_VAR_NAME_%d", meth_var_names_idx++);
2040 else if (section == meth_var_types)
2041 sprintf (buf, "_OBJC_METH_VAR_TYPE_%d", meth_var_types_idx++);
2043 rtl_obstack = current_obstack = &permanent_obstack;
2044 ident = get_identifier (buf);
2046 decl = build_decl (VAR_DECL, ident, build_array_type (char_type_node, 0));
2047 DECL_EXTERNAL (decl) = 1;
2048 TREE_PUBLIC (decl) = 1;
2049 TREE_USED (decl) = 1;
2050 TREE_READONLY (decl) = 1;
2051 TREE_CONSTANT (decl) = 1;
2053 make_decl_rtl (decl, 0, 1); /* usually called from `rest_of_decl_compilation */
2054 pushdecl_top_level (decl); /* our `extended/custom' pushdecl in c-decl.c */
2056 current_obstack = save_current_obstack;
2057 rtl_obstack = save_rtl_obstack;
2064 objc_declare_alias (alias_ident, class_ident)
2068 if (!doing_objc_thang)
2071 if (is_class_name (class_ident) != class_ident)
2072 warning ("Cannot find class `%s'", IDENTIFIER_POINTER (class_ident));
2073 else if (is_class_name (alias_ident))
2074 warning ("Class `%s' already exists", IDENTIFIER_POINTER (alias_ident));
2076 alias_chain = tree_cons (class_ident, alias_ident, alias_chain);
2080 objc_declare_class (ident_list)
2085 if (!doing_objc_thang)
2088 for (list = ident_list; list; list = TREE_CHAIN (list))
2090 tree ident = TREE_VALUE (list);
2093 if ((decl = lookup_name (ident)))
2095 error ("`%s' redeclared as different kind of symbol",
2096 IDENTIFIER_POINTER (ident));
2097 error_with_decl (decl, "previous declaration of `%s'");
2100 if (! is_class_name (ident))
2102 tree record = xref_tag (RECORD_TYPE, ident);
2103 TREE_STATIC_TEMPLATE (record) = 1;
2104 class_chain = tree_cons (NULLT, ident, class_chain);
2110 is_class_name (ident)
2115 if (lookup_interface (ident))
2118 for (chain = class_chain; chain; chain = TREE_CHAIN (chain))
2120 if (ident == TREE_VALUE (chain))
2124 for (chain = alias_chain; chain; chain = TREE_CHAIN (chain))
2126 if (ident == TREE_VALUE (chain))
2127 return TREE_PURPOSE (chain);
2134 lookup_interface (ident)
2139 for (chain = interface_chain; chain; chain = TREE_CHAIN (chain))
2141 if (ident == CLASS_NAME (chain))
2148 objc_copy_list (list, head)
2152 tree newlist = NULL_TREE, tail = NULL_TREE;
2156 tail = copy_node (list);
2158 /* The following statement fixes a bug when inheriting instance
2159 variables that are declared to be bitfields. finish_struct
2160 expects to find the width of the bitfield in DECL_INITIAL,
2161 which it nulls out after processing the decl of the super
2162 class...rather than change the way finish_struct works (which
2163 is risky), I create the situation it expects...s.naroff
2166 if (DECL_BIT_FIELD (tail) && DECL_INITIAL (tail) == 0)
2167 DECL_INITIAL (tail) = build_int_2 (DECL_FIELD_SIZE (tail), 0);
2169 newlist = chainon (newlist, tail);
2170 list = TREE_CHAIN (list);
2176 /* Used by: build_private_template, get_class_ivars, and
2177 continue_class. COPY is 1 when called from @defs. In this case
2178 copy all fields. Otherwise don't copy leaf ivars since we rely on
2179 them being side-effected exactly once by finish_struct. */
2182 build_ivar_chain (interface, copy)
2186 tree my_name, super_name, ivar_chain;
2188 my_name = CLASS_NAME (interface);
2189 super_name = CLASS_SUPER_NAME (interface);
2191 /* Possibly copy leaf ivars. */
2193 objc_copy_list (CLASS_IVARS (interface), &ivar_chain);
2195 ivar_chain = CLASS_IVARS (interface);
2200 tree super_interface = lookup_interface (super_name);
2202 if (!super_interface)
2204 /* fatal did not work with 2 args...should fix */
2205 error ("Cannot find interface declaration for `%s', superclass of `%s'",
2206 IDENTIFIER_POINTER (super_name),
2207 IDENTIFIER_POINTER (my_name));
2210 if (super_interface == interface)
2212 fatal ("Circular inheritance in interface declaration for `%s'",
2213 IDENTIFIER_POINTER (super_name));
2215 interface = super_interface;
2216 my_name = CLASS_NAME (interface);
2217 super_name = CLASS_SUPER_NAME (interface);
2219 op1 = CLASS_IVARS (interface);
2222 tree head, tail = objc_copy_list (op1, &head);
2224 /* Prepend super class ivars...make a copy of the list, we
2225 do not want to alter the original. */
2226 TREE_CHAIN (tail) = ivar_chain;
2233 /* struct <classname> {
2234 struct objc_class *isa;
2239 build_private_template (class)
2244 if (CLASS_STATIC_TEMPLATE (class))
2246 uprivate_record = CLASS_STATIC_TEMPLATE (class);
2247 ivar_context = TYPE_FIELDS (CLASS_STATIC_TEMPLATE (class));
2251 uprivate_record = start_struct (RECORD_TYPE, CLASS_NAME (class));
2253 ivar_context = build_ivar_chain (class, 0);
2255 finish_struct (uprivate_record, ivar_context);
2257 CLASS_STATIC_TEMPLATE (class) = uprivate_record;
2259 /* mark this record as class template - for class type checking */
2260 TREE_STATIC_TEMPLATE (uprivate_record) = 1;
2262 instance_type = groktypename (build_tree_list (build_tree_list (NULLT, uprivate_record),
2263 build1 (INDIRECT_REF, NULLT, NULLT)));
2264 return ivar_context;
2267 /* Begin code generation for protocols... */
2269 /* struct objc_protocol {
2270 char *protocol_name;
2271 struct objc_protocol **protocol_list;
2272 struct objc_method_desc *instance_methods;
2273 struct objc_method_desc *class_methods;
2277 build_protocol_template ()
2279 tree decl_specs, field_decl, field_decl_chain;
2282 template = start_struct (RECORD_TYPE, get_identifier (UTAG_PROTOCOL));
2284 /* struct objc_class *isa; */
2286 decl_specs = build_tree_list (NULLT, xref_tag (RECORD_TYPE,
2287 get_identifier (UTAG_CLASS)));
2288 field_decl = build1 (INDIRECT_REF, NULLT, get_identifier ("isa"));
2289 field_decl = grokfield (input_filename, lineno, field_decl, decl_specs, NULLT);
2290 field_decl_chain = field_decl;
2292 /* char *protocol_name; */
2294 decl_specs = build_tree_list (NULLT, ridpointers[(int) RID_CHAR]);
2295 field_decl = build1 (INDIRECT_REF, NULLT, get_identifier ("protocol_name"));
2296 field_decl = grokfield (input_filename, lineno, field_decl, decl_specs, NULLT);
2297 chainon (field_decl_chain, field_decl);
2299 /* struct objc_protocol **protocol_list; */
2301 decl_specs = build_tree_list (NULLT, template);
2302 field_decl = build1 (INDIRECT_REF, NULLT, get_identifier ("protocol_list"));
2303 field_decl = build1 (INDIRECT_REF, NULLT, field_decl);
2304 field_decl = grokfield (input_filename, lineno, field_decl, decl_specs, NULLT);
2305 chainon (field_decl_chain, field_decl);
2307 /* struct objc_method_list *instance_methods; */
2309 decl_specs = build_tree_list (NULLT, xref_tag (RECORD_TYPE,
2310 get_identifier (UTAG_METHOD_PROTOTYPE_LIST)));
2311 field_decl = build1 (INDIRECT_REF, NULLT, get_identifier ("instance_methods"));
2312 field_decl = grokfield (input_filename, lineno, field_decl, decl_specs, NULLT);
2313 chainon (field_decl_chain, field_decl);
2315 /* struct objc_method_list *class_methods; */
2317 decl_specs = build_tree_list (NULLT, xref_tag (RECORD_TYPE,
2318 get_identifier (UTAG_METHOD_PROTOTYPE_LIST)));
2319 field_decl = build1 (INDIRECT_REF, NULLT, get_identifier ("class_methods"));
2320 field_decl = grokfield (input_filename, lineno, field_decl, decl_specs, NULLT);
2321 chainon (field_decl_chain, field_decl);
2323 return finish_struct (template, field_decl_chain);
2327 build_descriptor_table_initializer (type, entries)
2331 tree initlist = NULLT;
2335 tree eltlist = NULLT;
2337 eltlist = tree_cons (NULLT, build_selector (METHOD_SEL_NAME (entries)), NULLT);
2338 eltlist = tree_cons (NULLT, add_objc_string (METHOD_ENCODING (entries), meth_var_types), eltlist);
2340 initlist = tree_cons (NULLT, build_constructor (type, nreverse (eltlist)), initlist);
2342 entries = TREE_CHAIN (entries);
2346 return build_constructor (build_array_type (type, 0), nreverse (initlist));
2349 /* struct objc_method_prototype_list {
2351 struct objc_method_prototype {
2358 build_method_prototype_list_template (list_type, size)
2362 tree objc_ivar_list_record;
2363 tree decl_specs, field_decl, field_decl_chain;
2365 /* generate an unnamed struct definition */
2367 objc_ivar_list_record = start_struct (RECORD_TYPE, NULLT);
2369 /* int method_count; */
2371 decl_specs = build_tree_list (NULLT, ridpointers[(int) RID_INT]);
2372 field_decl = get_identifier ("method_count");
2374 field_decl = grokfield (input_filename, lineno, field_decl, decl_specs, NULLT);
2375 field_decl_chain = field_decl;
2377 /* struct objc_method method_list[]; */
2379 decl_specs = build_tree_list (NULLT, list_type);
2380 field_decl = build_nt (ARRAY_REF, get_identifier ("method_list"),
2381 build_int_2 (size, 0));
2383 field_decl = grokfield (input_filename, lineno, field_decl, decl_specs, NULLT);
2384 chainon (field_decl_chain, field_decl);
2386 finish_struct (objc_ivar_list_record, field_decl_chain);
2388 return objc_ivar_list_record;
2392 build_method_prototype_template ()
2395 tree decl_specs, field_decl, field_decl_chain;
2397 proto_record = start_struct (RECORD_TYPE, get_identifier (UTAG_METHOD_PROTOTYPE));
2399 #ifdef OBJC_INT_SELECTORS
2400 /* unsigned int _cmd; */
2401 decl_specs = tree_cons (NULLT, ridpointers[(int) RID_UNSIGNED], NULLT);
2402 decl_specs = tree_cons (NULLT, ridpointers[(int) RID_INT], decl_specs);
2403 field_decl = get_identifier ("_cmd");
2404 #else /* OBJC_INT_SELECTORS */
2405 /* struct objc_selector *_cmd; */
2406 decl_specs = tree_cons (NULLT, xref_tag (RECORD_TYPE,
2407 get_identifier (TAG_SELECTOR)), NULLT);
2408 field_decl = build1 (INDIRECT_REF, NULLT, get_identifier ("_cmd"));
2409 #endif /* OBJC_INT_SELECTORS */
2411 field_decl = grokfield (input_filename, lineno, field_decl, decl_specs, NULLT);
2412 field_decl_chain = field_decl;
2414 decl_specs = tree_cons (NULLT, ridpointers[(int) RID_CHAR], NULLT);
2415 field_decl = build1 (INDIRECT_REF, NULLT, get_identifier ("method_types"));
2416 field_decl = grokfield (input_filename, lineno, field_decl, decl_specs, NULLT);
2417 chainon (field_decl_chain, field_decl);
2419 finish_struct (proto_record, field_decl_chain);
2421 return proto_record;
2424 /* True if last call to forwarding_offset yielded a register offset */
2425 static int offset_is_register;
2428 forwarding_offset (parm)
2431 int offset_in_bytes;
2433 if (GET_CODE (DECL_INCOMING_RTL (parm)) == MEM)
2435 rtx addr = XEXP (DECL_INCOMING_RTL (parm), 0);
2437 /* ??? Here we assume that the parm address is indexed
2438 off the frame pointer or arg pointer.
2439 If that is not true, we produce meaningless results,
2440 but do not crash. */
2441 if (GET_CODE (addr) == PLUS
2442 && GET_CODE (XEXP (addr, 1)) == CONST_INT)
2443 offset_in_bytes = INTVAL (XEXP (addr, 1));
2445 offset_in_bytes = 0;
2447 offset_in_bytes += OBJC_FORWARDING_STACK_OFFSET;
2448 offset_is_register = 0;
2450 else if (GET_CODE (DECL_INCOMING_RTL (parm)) == REG)
2452 int regno = REGNO (DECL_INCOMING_RTL (parm));
2453 offset_in_bytes = apply_args_register_offset (regno);
2454 offset_is_register = 1;
2459 /* This is the case where the parm is passed as an int or double
2460 and it is converted to a char, short or float and stored back
2461 in the parmlist. In this case, describe the parm
2462 with the variable's declared type, and adjust the address
2463 if the least significant bytes (which we are using) are not
2465 #if BYTES_BIG_ENDIAN
2466 if (TREE_TYPE (parm) != DECL_ARG_TYPE (parm))
2467 offset_in_bytes += (GET_MODE_SIZE (TYPE_MODE (DECL_ARG_TYPE (parm)))
2468 - GET_MODE_SIZE (GET_MODE (DECL_RTL (parm))));
2471 return offset_in_bytes;
2475 encode_method_prototype (method_decl, func_decl)
2482 int max_parm_end = 0;
2486 /* `oneway' and 'bycopy', for remote object are the only method qualifiers */
2487 encode_type_qualifiers (TREE_PURPOSE (TREE_TYPE (method_decl)));
2490 encode_type (TREE_TYPE (TREE_TYPE (func_decl)),
2491 obstack_object_size (&util_obstack),
2492 OBJC_ENCODE_INLINE_DEFS);
2495 for (parms = DECL_ARGUMENTS (func_decl); parms;
2496 parms = TREE_CHAIN (parms))
2498 int parm_end = (forwarding_offset (parms)
2499 + (TREE_INT_CST_LOW (TYPE_SIZE (TREE_TYPE (parms)))
2502 if (!offset_is_register && max_parm_end < parm_end)
2503 max_parm_end = parm_end;
2506 stack_size = max_parm_end - OBJC_FORWARDING_MIN_OFFSET;
2508 sprintf (buf, "%d", stack_size);
2509 obstack_grow (&util_obstack, buf, strlen (buf));
2511 user_args = METHOD_SEL_ARGS (method_decl);
2513 /* argument types */
2514 for (parms = DECL_ARGUMENTS (func_decl), i = 0; parms;
2515 parms = TREE_CHAIN (parms), i++)
2517 /* process argument qualifiers for user supplied arguments */
2520 encode_type_qualifiers (TREE_PURPOSE (TREE_TYPE (user_args)));
2521 user_args = TREE_CHAIN (user_args);
2525 encode_type (TREE_TYPE (parms),
2526 obstack_object_size (&util_obstack),
2527 OBJC_ENCODE_INLINE_DEFS);
2529 /* compute offset */
2530 sprintf (buf, "%d", forwarding_offset (parms));
2532 /* indicate register */
2533 if (offset_is_register)
2534 obstack_1grow (&util_obstack, '+');
2536 obstack_grow (&util_obstack, buf, strlen (buf));
2539 obstack_1grow (&util_obstack, '\0');
2540 result = get_identifier (obstack_finish (&util_obstack));
2541 obstack_free (&util_obstack, util_firstobj);
2546 generate_descriptor_table (type, name, size, list, proto)
2553 tree sc_spec, decl_specs, decl, initlist;
2555 sc_spec = tree_cons (NULLT, ridpointers[(int) RID_STATIC], NULLT);
2556 decl_specs = tree_cons (NULLT, type, sc_spec);
2558 decl = start_decl (synth_id_with_class_suffix (name, proto),
2560 end_temporary_allocation ();
2562 initlist = build_tree_list (NULLT, build_int_2 (size, 0));
2563 initlist = tree_cons (NULLT, list, initlist);
2565 finish_decl (decl, build_constructor (type, nreverse (initlist)),
2572 generate_method_descriptors (protocol) /* generate_dispatch_tables */
2575 static tree objc_method_prototype_template;
2576 tree initlist, chain, method_list_template;
2577 tree cast, variable_length_type;
2580 if (!objc_method_prototype_template)
2581 objc_method_prototype_template = build_method_prototype_template ();
2583 cast = build_tree_list (build_tree_list (NULLT, xref_tag (RECORD_TYPE,
2584 get_identifier (UTAG_METHOD_PROTOTYPE_LIST))), NULLT);
2585 variable_length_type = groktypename (cast);
2587 chain = PROTOCOL_CLS_METHODS (protocol);
2590 size = list_length (chain);
2592 method_list_template
2593 = build_method_prototype_list_template (objc_method_prototype_template,
2597 = build_descriptor_table_initializer (objc_method_prototype_template,
2600 UOBJC_CLASS_METHODS_decl
2601 = generate_descriptor_table (method_list_template,
2602 "_OBJC_PROTOCOL_CLASS_METHODS",
2603 size, initlist, protocol);
2605 TREE_TYPE (UOBJC_CLASS_METHODS_decl) = variable_length_type;
2608 UOBJC_CLASS_METHODS_decl = 0;
2610 chain = PROTOCOL_NST_METHODS (protocol);
2613 size = list_length (chain);
2615 method_list_template
2616 = build_method_prototype_list_template (objc_method_prototype_template,
2619 = build_descriptor_table_initializer (objc_method_prototype_template,
2622 UOBJC_INSTANCE_METHODS_decl
2623 = generate_descriptor_table (method_list_template,
2624 "_OBJC_PROTOCOL_INSTANCE_METHODS",
2625 size, initlist, protocol);
2627 TREE_TYPE (UOBJC_INSTANCE_METHODS_decl) = variable_length_type;
2630 UOBJC_INSTANCE_METHODS_decl = 0;
2634 build_tmp_function_decl ()
2636 tree decl_specs, expr_decl, parms;
2640 /* struct objc_object *objc_xxx (id, SEL, ...); */
2642 decl_specs = build_tree_list (NULLT, objc_object_reference);
2643 push_parm_decl (build_tree_list (decl_specs,
2644 build1 (INDIRECT_REF, NULLT, NULLT)));
2646 decl_specs = build_tree_list (NULLT, xref_tag (RECORD_TYPE,
2647 get_identifier (TAG_SELECTOR)));
2648 expr_decl = build1 (INDIRECT_REF, NULLT, NULLT);
2650 push_parm_decl (build_tree_list (decl_specs, expr_decl));
2651 parms = get_parm_info (0);
2654 decl_specs = build_tree_list (NULLT, objc_object_reference);
2655 sprintf (buffer, "__objc_tmp_%x", xxx++);
2656 expr_decl = build_nt (CALL_EXPR, get_identifier (buffer), parms, NULLT);
2657 expr_decl = build1 (INDIRECT_REF, NULLT, expr_decl);
2659 return define_decl (expr_decl, decl_specs);
2663 hack_method_prototype (nst_methods, tmp_decl)
2669 /* Hack to avoid problem with static typing of self arg. */
2670 TREE_SET_CODE (nst_methods, CLASS_METHOD_DECL);
2671 start_method_def (nst_methods);
2672 TREE_SET_CODE (nst_methods, INSTANCE_METHOD_DECL);
2674 if (METHOD_ADD_ARGS (nst_methods) == (tree) 1)
2675 parms = get_parm_info (0); /* we have a `, ...' */
2677 parms = get_parm_info (1); /* place a `void_at_end' */
2679 poplevel (0, 0, 0); /* Must be called BEFORE start_function. */
2681 /* Usually called from store_parm_decls -> init_function_start. */
2683 DECL_ARGUMENTS (tmp_decl) = TREE_PURPOSE (parms);
2684 current_function_decl = tmp_decl;
2687 /* Code taken from start_function. */
2688 tree restype = TREE_TYPE (TREE_TYPE (tmp_decl));
2689 /* Promote the value to int before returning it. */
2690 if (TREE_CODE (restype) == INTEGER_TYPE
2691 && TYPE_PRECISION (restype) < TYPE_PRECISION (integer_type_node))
2692 restype = integer_type_node;
2693 DECL_RESULT (tmp_decl) = build_decl (RESULT_DECL, 0, restype);
2696 init_function_start (tmp_decl, "objc-act", 0);
2698 /* Typically called from expand_function_start for function definitions. */
2699 assign_parms (tmp_decl, 0);
2701 /* install return type */
2702 TREE_TYPE (TREE_TYPE (tmp_decl)) = groktypename (TREE_TYPE (nst_methods));
2707 generate_protocol_references (plist)
2712 /* forward declare protocols referenced */
2713 for (lproto = plist; lproto; lproto = TREE_CHAIN (lproto))
2715 tree proto = TREE_VALUE (lproto);
2717 if (TREE_CODE (proto) == PROTOCOL_INTERFACE_TYPE
2718 && PROTOCOL_NAME (proto))
2720 if (! PROTOCOL_FORWARD_DECL (proto))
2721 build_protocol_reference (proto);
2723 if (PROTOCOL_LIST (proto))
2724 generate_protocol_references (PROTOCOL_LIST (proto));
2730 generate_protocols ()
2732 tree p, tmp_decl, encoding;
2733 tree sc_spec, decl_specs, decl;
2734 tree initlist, protocol_name_expr, refs_decl, refs_expr;
2735 tree cast_type2 = 0;
2737 tmp_decl = build_tmp_function_decl ();
2739 if (! objc_protocol_template)
2740 objc_protocol_template = build_protocol_template ();
2742 /* if a protocol was directly referenced, pull in indirect references */
2743 for (p = protocol_chain; p; p = TREE_CHAIN (p))
2744 if (PROTOCOL_FORWARD_DECL (p) && PROTOCOL_LIST (p))
2745 generate_protocol_references (PROTOCOL_LIST (p));
2747 for (p = protocol_chain; p; p = TREE_CHAIN (p))
2749 tree nst_methods = PROTOCOL_NST_METHODS (p);
2750 tree cls_methods = PROTOCOL_CLS_METHODS (p);
2752 /* if protocol wasn't referenced, don't generate any code */
2753 if (! PROTOCOL_FORWARD_DECL (p))
2756 /* Make sure we link in the Protocol class. */
2757 add_class_reference (get_identifier (PROTOCOL_OBJECT_CLASS_NAME));
2761 if (! METHOD_ENCODING (nst_methods))
2763 hack_method_prototype (nst_methods, tmp_decl);
2764 encoding = encode_method_prototype (nst_methods, tmp_decl);
2765 METHOD_ENCODING (nst_methods) = encoding;
2767 nst_methods = TREE_CHAIN (nst_methods);
2772 if (! METHOD_ENCODING (cls_methods))
2774 hack_method_prototype (cls_methods, tmp_decl);
2775 encoding = encode_method_prototype (cls_methods, tmp_decl);
2776 METHOD_ENCODING (cls_methods) = encoding;
2779 cls_methods = TREE_CHAIN (cls_methods);
2781 generate_method_descriptors (p);
2783 if (PROTOCOL_LIST (p))
2784 refs_decl = generate_protocol_list (p);
2788 /* static struct objc_protocol _OBJC_PROTOCOL_<mumble>; */
2790 sc_spec = tree_cons (NULLT, ridpointers[(int) RID_STATIC], NULLT);
2791 decl_specs = tree_cons (NULLT, objc_protocol_template, sc_spec);
2793 decl = start_decl (synth_id_with_class_suffix ("_OBJC_PROTOCOL", p),
2795 end_temporary_allocation ();
2797 protocol_name_expr = add_objc_string (PROTOCOL_NAME (p), class_names);
2803 = groktypename (build_tree_list (build_tree_list (NULLT, objc_protocol_template),
2804 build1 (INDIRECT_REF, NULLT,
2805 build1 (INDIRECT_REF, NULLT, NULLT))));
2807 refs_expr = build_unary_op (ADDR_EXPR, refs_decl, 0);
2808 TREE_TYPE (refs_expr) = cast_type2;
2811 refs_expr = build_int_2 (0, 0);
2813 /* UOBJC_INSTANCE_METHODS_decl/UOBJC_CLASS_METHODS_decl are set
2814 by generate_method_descriptors, which is called above. */
2815 initlist = build_protocol_initializer (TREE_TYPE (decl),
2816 protocol_name_expr, refs_expr,
2817 UOBJC_INSTANCE_METHODS_decl,
2818 UOBJC_CLASS_METHODS_decl);
2819 finish_decl (decl, initlist, NULLT);
2821 /* Mark the decl as used to avoid "defined but not used" warning. */
2822 TREE_USED (decl) = 1;
2827 build_protocol_initializer (type, protocol_name, protocol_list,
2828 instance_methods, class_methods)
2832 tree instance_methods;
2835 tree initlist = NULLT, expr;
2836 static tree cast_type = 0;
2840 = groktypename (build_tree_list
2841 (build_tree_list (NULLT,
2842 xref_tag (RECORD_TYPE,
2843 get_identifier (UTAG_CLASS))),
2844 build1 (INDIRECT_REF, NULLT, NULLT)));
2846 /* filling the "isa" in with one allows the runtime system to
2847 detect that the version change...should remove before final release */
2849 expr = build_int_2 (PROTOCOL_VERSION, 0);
2850 TREE_TYPE (expr) = cast_type;
2851 initlist = tree_cons (NULLT, expr, initlist);
2852 initlist = tree_cons (NULLT, protocol_name, initlist);
2853 initlist = tree_cons (NULLT, protocol_list, initlist);
2855 if (!instance_methods)
2856 initlist = tree_cons (NULLT, build_int_2 (0, 0), initlist);
2859 expr = build_unary_op (ADDR_EXPR, instance_methods, 0);
2860 initlist = tree_cons (NULLT, expr, initlist);
2863 initlist = tree_cons (NULLT, build_int_2 (0, 0), initlist);
2866 expr = build_unary_op (ADDR_EXPR, class_methods, 0);
2867 initlist = tree_cons (NULLT, expr, initlist);
2869 return build_constructor (type, nreverse (initlist));
2871 /* end code generation for protocols... */
2873 /* struct objc_category {
2874 char *category_name;
2876 struct objc_method_list *instance_methods;
2877 struct objc_method_list *class_methods;
2878 struct objc_protocol_list *protocols;
2882 build_category_template ()
2884 tree decl_specs, field_decl, field_decl_chain;
2886 objc_category_template = start_struct (RECORD_TYPE,
2887 get_identifier (UTAG_CATEGORY));
2888 /* char *category_name; */
2890 decl_specs = build_tree_list (NULLT, ridpointers[(int) RID_CHAR]);
2891 field_decl = build1 (INDIRECT_REF, NULLT, get_identifier ("category_name"));
2892 field_decl = grokfield (input_filename, lineno, field_decl, decl_specs, NULLT);
2893 field_decl_chain = field_decl;
2895 /* char *class_name; */
2897 decl_specs = build_tree_list (NULLT, ridpointers[(int) RID_CHAR]);
2898 field_decl = build1 (INDIRECT_REF, NULLT, get_identifier ("class_name"));
2899 field_decl = grokfield (input_filename, lineno, field_decl, decl_specs, NULLT);
2900 chainon (field_decl_chain, field_decl);
2902 /* struct objc_method_list *instance_methods; */
2904 decl_specs = build_tree_list (NULLT, xref_tag (RECORD_TYPE,
2905 get_identifier (UTAG_METHOD_LIST)));
2906 field_decl = build1 (INDIRECT_REF, NULLT, get_identifier ("instance_methods"));
2907 field_decl = grokfield (input_filename, lineno, field_decl, decl_specs, NULLT);
2908 chainon (field_decl_chain, field_decl);
2910 /* struct objc_method_list *class_methods; */
2912 decl_specs = build_tree_list (NULLT, xref_tag (RECORD_TYPE,
2913 get_identifier (UTAG_METHOD_LIST)));
2914 field_decl = build1 (INDIRECT_REF, NULLT, get_identifier ("class_methods"));
2915 field_decl = grokfield (input_filename, lineno, field_decl, decl_specs, NULLT);
2916 chainon (field_decl_chain, field_decl);
2918 /* struct objc_protocol **protocol_list; */
2920 decl_specs = build_tree_list (NULLT, xref_tag (RECORD_TYPE,
2921 get_identifier (UTAG_PROTOCOL)));
2922 field_decl = build1 (INDIRECT_REF, NULLT, get_identifier ("protocol_list"));
2923 field_decl = build1 (INDIRECT_REF, NULLT, field_decl);
2924 field_decl = grokfield (input_filename, lineno, field_decl, decl_specs, NULLT)
2926 chainon (field_decl_chain, field_decl);
2928 finish_struct (objc_category_template, field_decl_chain);
2931 /* struct objc_selector {
2937 build_selector_template ()
2940 tree decl_specs, field_decl, field_decl_chain;
2942 objc_selector_template
2943 = start_struct (RECORD_TYPE, get_identifier (UTAG_SELECTOR));
2947 decl_specs = build_tree_list (NULLT, ridpointers[(int) RID_VOID]);
2948 field_decl = build1 (INDIRECT_REF, NULLT, get_identifier ("sel_id"));
2949 field_decl = grokfield (input_filename, lineno, field_decl, decl_specs, NULLT);
2950 field_decl_chain = field_decl;
2952 /* char *sel_type; */
2954 decl_specs = build_tree_list (NULLT, ridpointers[(int) RID_CHAR]);
2955 field_decl = build1 (INDIRECT_REF, NULLT, get_identifier ("sel_type"));
2956 field_decl = grokfield (input_filename, lineno, field_decl, decl_specs, NULLT);
2957 chainon (field_decl_chain, field_decl);
2959 finish_struct (objc_selector_template, field_decl_chain);
2962 /* struct objc_class {
2963 struct objc_class *isa;
2964 struct objc_class *super_class;
2969 struct objc_ivar_list *ivars;
2970 struct objc_method_list *methods;
2971 if (flag_next_runtime)
2972 struct objc_cache *cache;
2974 struct sarray *dtable;
2975 struct objc_class *subclass_list;
2976 struct objc_class *sibling_class;
2978 struct objc_protocol_list *protocols;
2982 build_class_template ()
2984 tree decl_specs, field_decl, field_decl_chain;
2986 objc_class_template = start_struct (RECORD_TYPE, get_identifier (UTAG_CLASS));
2988 /* struct objc_class *isa; */
2990 decl_specs = build_tree_list (NULLT, objc_class_template);
2991 field_decl = build1 (INDIRECT_REF, NULLT, get_identifier ("isa"));
2992 field_decl = grokfield (input_filename, lineno, field_decl, decl_specs, NULLT);
2993 field_decl_chain = field_decl;
2995 /* struct objc_class *super_class; */
2997 decl_specs = build_tree_list (NULLT, objc_class_template);
2998 field_decl = build1 (INDIRECT_REF, NULLT, get_identifier ("super_class"));
2999 field_decl = grokfield (input_filename, lineno, field_decl, decl_specs, NULLT);
3000 chainon (field_decl_chain, field_decl);
3004 decl_specs = build_tree_list (NULLT, ridpointers[(int) RID_CHAR]);
3005 field_decl = build1 (INDIRECT_REF, NULLT, get_identifier ("name"));
3006 field_decl = grokfield (input_filename, lineno, field_decl, decl_specs, NULLT);
3007 chainon (field_decl_chain, field_decl);
3011 decl_specs = build_tree_list (NULLT, ridpointers[(int) RID_LONG]);
3012 field_decl = get_identifier ("version");
3013 field_decl = grokfield (input_filename, lineno, field_decl, decl_specs, NULLT);
3014 chainon (field_decl_chain, field_decl);
3018 decl_specs = build_tree_list (NULLT, ridpointers[(int) RID_LONG]);
3019 field_decl = get_identifier ("info");
3020 field_decl = grokfield (input_filename, lineno, field_decl, decl_specs, NULLT);
3021 chainon (field_decl_chain, field_decl);
3023 /* long instance_size; */
3025 decl_specs = build_tree_list (NULLT, ridpointers[(int) RID_LONG]);
3026 field_decl = get_identifier ("instance_size");
3027 field_decl = grokfield (input_filename, lineno, field_decl, decl_specs, NULLT);
3028 chainon (field_decl_chain, field_decl);
3030 /* struct objc_ivar_list *ivars; */
3032 decl_specs = build_tree_list (NULLT, xref_tag (RECORD_TYPE,
3033 get_identifier (UTAG_IVAR_LIST)));
3034 field_decl = build1 (INDIRECT_REF, NULLT, get_identifier ("ivars"));
3035 field_decl = grokfield (input_filename, lineno, field_decl, decl_specs, NULLT);
3036 chainon (field_decl_chain, field_decl);
3038 /* struct objc_method_list *methods; */
3040 decl_specs = build_tree_list (NULLT, xref_tag (RECORD_TYPE,
3041 get_identifier (UTAG_METHOD_LIST)));
3042 field_decl = build1 (INDIRECT_REF, NULLT, get_identifier ("methods"));
3043 field_decl = grokfield (input_filename, lineno, field_decl, decl_specs, NULLT);
3044 chainon (field_decl_chain, field_decl);
3046 if (flag_next_runtime)
3048 /* struct objc_cache *cache; */
3050 decl_specs = build_tree_list (NULLT, xref_tag (RECORD_TYPE,
3051 get_identifier ("objc_cache")));
3052 field_decl = build1 (INDIRECT_REF, NULLT, get_identifier ("cache"));
3053 field_decl = grokfield (input_filename, lineno, field_decl, decl_specs, NULLT);
3054 chainon (field_decl_chain, field_decl);
3058 /* struct sarray *dtable; */
3060 decl_specs = build_tree_list (NULLT, xref_tag (RECORD_TYPE,
3061 get_identifier ("sarray")));
3062 field_decl = build1 (INDIRECT_REF, NULLT, get_identifier ("dtable"));
3063 field_decl = grokfield (input_filename, lineno, field_decl, decl_specs, NULLT);
3064 chainon (field_decl_chain, field_decl);
3066 /* struct objc_class *subclass_list; */
3068 decl_specs = build_tree_list (NULLT, objc_class_template);
3069 field_decl = build1 (INDIRECT_REF, NULLT, get_identifier ("subclass_list"));
3070 field_decl = grokfield (input_filename, lineno, field_decl, decl_specs, NULLT);
3071 chainon (field_decl_chain, field_decl);
3073 /* struct objc_class *sibling_class; */
3075 decl_specs = build_tree_list (NULLT, objc_class_template);
3076 field_decl = build1 (INDIRECT_REF, NULLT, get_identifier ("sibling_class"));
3077 field_decl = grokfield (input_filename, lineno, field_decl, decl_specs, NULLT);
3078 chainon (field_decl_chain, field_decl);
3081 /* struct objc_protocol **protocol_list; */
3083 decl_specs = build_tree_list (NULLT, xref_tag (RECORD_TYPE,
3084 get_identifier (UTAG_PROTOCOL)));
3085 field_decl = build1 (INDIRECT_REF, NULLT, get_identifier ("protocol_list"));
3086 field_decl = build1 (INDIRECT_REF, NULLT, field_decl);
3087 field_decl = grokfield (input_filename, lineno, field_decl, decl_specs, NULLT);
3088 chainon (field_decl_chain, field_decl);
3091 finish_struct (objc_class_template, field_decl_chain);
3094 /* Generate appropriate forward declarations for an implementation. */
3097 synth_forward_declarations ()
3099 tree sc_spec, decl_specs, an_id;
3101 /* extern struct objc_class _OBJC_CLASS_<my_name>; */
3103 an_id = synth_id_with_class_suffix ("_OBJC_CLASS", implementation_context);
3105 sc_spec = build_tree_list (NULLT, ridpointers[(int) RID_EXTERN]);
3106 decl_specs = tree_cons (NULLT, objc_class_template, sc_spec);
3107 UOBJC_CLASS_decl = define_decl (an_id, decl_specs);
3108 TREE_USED (UOBJC_CLASS_decl) = 1;
3110 /* extern struct objc_class _OBJC_METACLASS_<my_name>; */
3112 an_id = synth_id_with_class_suffix ("_OBJC_METACLASS",
3113 implementation_context);
3115 UOBJC_METACLASS_decl = define_decl (an_id, decl_specs);
3116 TREE_USED (UOBJC_METACLASS_decl) = 1;
3118 /* pre-build the following entities - for speed/convenience. */
3120 an_id = get_identifier ("super_class");
3121 ucls_super_ref = build_component_ref (UOBJC_CLASS_decl, an_id);
3122 uucls_super_ref = build_component_ref (UOBJC_METACLASS_decl, an_id);
3126 error_with_ivar (message, decl, rawdecl)
3133 report_error_function (DECL_SOURCE_FILE (decl));
3135 fprintf (stderr, "%s:%d: ",
3136 DECL_SOURCE_FILE (decl), DECL_SOURCE_LINE (decl));
3137 bzero (errbuf, BUFSIZE);
3138 fprintf (stderr, "%s `%s'\n", message, gen_declaration (rawdecl, errbuf));
3141 #define USERTYPE(t) (TREE_CODE (t) == RECORD_TYPE || \
3142 TREE_CODE (t) == UNION_TYPE || \
3143 TREE_CODE (t) == ENUMERAL_TYPE)
3146 check_ivars (inter, imp)
3150 tree intdecls = CLASS_IVARS (inter);
3151 tree impdecls = CLASS_IVARS (imp);
3152 tree rawintdecls = CLASS_RAW_IVARS (inter);
3153 tree rawimpdecls = CLASS_RAW_IVARS (imp);
3159 if (intdecls == 0 && impdecls == 0)
3161 if (intdecls == 0 || impdecls == 0)
3163 error ("inconsistent instance variable specification");
3166 t1 = TREE_TYPE (intdecls); t2 = TREE_TYPE (impdecls);
3168 if (!comptypes (t1, t2))
3170 if (DECL_NAME (intdecls) == DECL_NAME (impdecls))
3172 error_with_ivar ("conflicting instance variable type",
3173 impdecls, rawimpdecls);
3174 error_with_ivar ("previous declaration of",
3175 intdecls, rawintdecls);
3177 else /* both the type and the name don't match */
3179 error ("inconsistent instance variable specification");
3183 else if (DECL_NAME (intdecls) != DECL_NAME (impdecls))
3185 error_with_ivar ("conflicting instance variable name",
3186 impdecls, rawimpdecls);
3187 error_with_ivar ("previous declaration of",
3188 intdecls, rawintdecls);
3190 intdecls = TREE_CHAIN (intdecls);
3191 impdecls = TREE_CHAIN (impdecls);
3192 rawintdecls = TREE_CHAIN (rawintdecls);
3193 rawimpdecls = TREE_CHAIN (rawimpdecls);
3197 /* Set super_type to the data type node for struct objc_super *,
3198 first defining struct objc_super itself.
3199 This needs to be done just once per compilation. */
3202 build_super_template ()
3204 tree record, decl_specs, field_decl, field_decl_chain;
3206 record = start_struct (RECORD_TYPE, get_identifier (UTAG_SUPER));
3208 /* struct objc_object *self; */
3210 decl_specs = build_tree_list (NULLT, objc_object_reference);
3211 field_decl = get_identifier ("self");
3212 field_decl = build1 (INDIRECT_REF, NULLT, field_decl);
3213 field_decl = grokfield (input_filename, lineno,
3214 field_decl, decl_specs, NULLT);
3215 field_decl_chain = field_decl;
3217 /* struct objc_class *class; */
3219 decl_specs = get_identifier (UTAG_CLASS);
3220 decl_specs = build_tree_list (NULLT, xref_tag (RECORD_TYPE, decl_specs));
3221 field_decl = build1 (INDIRECT_REF, NULLT, get_identifier ("class"));
3223 field_decl = grokfield (input_filename, lineno,
3224 field_decl, decl_specs, NULLT);
3225 chainon (field_decl_chain, field_decl);
3227 finish_struct (record, field_decl_chain);
3229 /* `struct objc_super *' */
3230 super_type = groktypename (build_tree_list (build_tree_list (NULLT, record),
3231 build1 (INDIRECT_REF,
3236 /* struct objc_ivar {
3243 build_ivar_template ()
3245 tree objc_ivar_id, objc_ivar_record;
3246 tree decl_specs, field_decl, field_decl_chain;
3248 objc_ivar_id = get_identifier (UTAG_IVAR);
3249 objc_ivar_record = start_struct (RECORD_TYPE, objc_ivar_id);
3251 /* char *ivar_name; */
3253 decl_specs = build_tree_list (NULLT, ridpointers[(int) RID_CHAR]);
3254 field_decl = build1 (INDIRECT_REF, NULLT, get_identifier ("ivar_name"));
3256 field_decl = grokfield (input_filename, lineno, field_decl,
3258 field_decl_chain = field_decl;
3260 /* char *ivar_type; */
3262 decl_specs = build_tree_list (NULLT, ridpointers[(int) RID_CHAR]);
3263 field_decl = build1 (INDIRECT_REF, NULLT, get_identifier ("ivar_type"));
3265 field_decl = grokfield (input_filename, lineno, field_decl,
3267 chainon (field_decl_chain, field_decl);
3269 /* int ivar_offset; */
3271 decl_specs = build_tree_list (NULLT, ridpointers[(int) RID_INT]);
3272 field_decl = get_identifier ("ivar_offset");
3274 field_decl = grokfield (input_filename, lineno, field_decl,
3276 chainon (field_decl_chain, field_decl);
3278 finish_struct (objc_ivar_record, field_decl_chain);
3280 return objc_ivar_record;
3285 struct objc_ivar ivar_list[ivar_count];
3289 build_ivar_list_template (list_type, size)
3293 tree objc_ivar_list_record;
3294 tree decl_specs, field_decl, field_decl_chain;
3296 objc_ivar_list_record = start_struct (RECORD_TYPE, NULLT);
3298 /* int ivar_count; */
3300 decl_specs = build_tree_list (NULLT, ridpointers[(int) RID_INT]);
3301 field_decl = get_identifier ("ivar_count");
3303 field_decl = grokfield (input_filename, lineno, field_decl,
3305 field_decl_chain = field_decl;
3307 /* struct objc_ivar ivar_list[]; */
3309 decl_specs = build_tree_list (NULLT, list_type);
3310 field_decl = build_nt (ARRAY_REF, get_identifier ("ivar_list"),
3311 build_int_2 (size, 0));
3313 field_decl = grokfield (input_filename, lineno,
3314 field_decl, decl_specs, NULLT);
3315 chainon (field_decl_chain, field_decl);
3317 finish_struct (objc_ivar_list_record, field_decl_chain);
3319 return objc_ivar_list_record;
3325 struct objc_method method_list[method_count];
3329 build_method_list_template (list_type, size)
3333 tree objc_ivar_list_record;
3334 tree decl_specs, field_decl, field_decl_chain;
3336 objc_ivar_list_record = start_struct (RECORD_TYPE, NULLT);
3338 /* int method_next; */
3340 decl_specs = build_tree_list (NULLT,
3341 xref_tag (RECORD_TYPE,
3342 get_identifier (UTAG_METHOD_PROTOTYPE_LIST)));
3343 field_decl = build1 (INDIRECT_REF, NULLT, get_identifier ("method_next"));
3344 field_decl = grokfield (input_filename, lineno, field_decl, decl_specs, NULLT);
3345 field_decl_chain = field_decl;
3347 /* int method_count; */
3349 decl_specs = build_tree_list (NULLT, ridpointers[(int) RID_INT]);
3350 field_decl = get_identifier ("method_count");
3352 field_decl = grokfield (input_filename, lineno,
3353 field_decl, decl_specs, NULLT);
3354 chainon (field_decl_chain, field_decl);
3356 /* struct objc_method method_list[]; */
3358 decl_specs = build_tree_list (NULLT, list_type);
3359 field_decl = build_nt (ARRAY_REF, get_identifier ("method_list"),
3360 build_int_2 (size, 0));
3362 field_decl = grokfield (input_filename, lineno,
3363 field_decl, decl_specs, NULLT);
3364 chainon (field_decl_chain, field_decl);
3366 finish_struct (objc_ivar_list_record, field_decl_chain);
3368 return objc_ivar_list_record;
3372 build_ivar_list_initializer (type, field_decl)
3376 tree initlist = NULLT;
3383 if (DECL_NAME (field_decl))
3384 ivar = tree_cons (NULLT,
3385 add_objc_string (DECL_NAME (field_decl),
3389 /* unnamed bit-field ivar (yuck). */
3390 ivar = tree_cons (NULLT, build_int_2 (0, 0), ivar);
3393 encode_field_decl (field_decl,
3394 obstack_object_size (&util_obstack),
3395 OBJC_ENCODE_DONT_INLINE_DEFS);
3396 obstack_1grow (&util_obstack, 0); /* null terminate string */
3400 add_objc_string (get_identifier (obstack_finish (&util_obstack)),
3403 obstack_free (&util_obstack, util_firstobj);
3409 build_int_2 ((TREE_INT_CST_LOW (DECL_FIELD_BITPOS (field_decl))
3414 initlist = tree_cons (NULLT,
3415 build_constructor (type, nreverse (ivar)),
3418 field_decl = TREE_CHAIN (field_decl);
3422 return build_constructor (build_array_type (type, 0), nreverse (initlist));
3426 generate_ivars_list (type, name, size, list)
3432 tree sc_spec, decl_specs, decl, initlist;
3434 sc_spec = tree_cons (NULLT, ridpointers[(int) RID_STATIC], NULLT);
3435 decl_specs = tree_cons (NULLT, type, sc_spec);
3437 decl = start_decl (synth_id_with_class_suffix (name, implementation_context),
3439 end_temporary_allocation ();
3441 initlist = build_tree_list (NULLT, build_int_2 (size, 0));
3442 initlist = tree_cons (NULLT, list, initlist);
3445 build_constructor (TREE_TYPE (decl), nreverse (initlist)),
3452 generate_ivar_lists ()
3454 tree initlist, ivar_list_template, chain;
3455 tree cast, variable_length_type;
3458 generating_instance_variables = 1;
3460 if (!objc_ivar_template)
3461 objc_ivar_template = build_ivar_template ();
3465 (build_tree_list (NULLT, xref_tag (RECORD_TYPE,
3466 get_identifier (UTAG_IVAR_LIST))),
3468 variable_length_type = groktypename (cast);
3470 /* only generate class variables for the root of the inheritance
3471 hierarchy since these will be the same for every class */
3473 if (CLASS_SUPER_NAME (implementation_template) == NULLT
3474 && (chain = TYPE_FIELDS (objc_class_template)))
3476 size = list_length (chain);
3478 ivar_list_template = build_ivar_list_template (objc_ivar_template, size);
3479 initlist = build_ivar_list_initializer (objc_ivar_template, chain);
3481 UOBJC_CLASS_VARIABLES_decl
3482 = generate_ivars_list (ivar_list_template, "_OBJC_CLASS_VARIABLES",
3485 TREE_TYPE (UOBJC_CLASS_VARIABLES_decl) = variable_length_type;
3488 UOBJC_CLASS_VARIABLES_decl = 0;
3490 chain = CLASS_IVARS (implementation_template);
3493 size = list_length (chain);
3494 ivar_list_template = build_ivar_list_template (objc_ivar_template, size);
3495 initlist = build_ivar_list_initializer (objc_ivar_template, chain);
3497 UOBJC_INSTANCE_VARIABLES_decl
3498 = generate_ivars_list (ivar_list_template, "_OBJC_INSTANCE_VARIABLES",
3501 TREE_TYPE (UOBJC_INSTANCE_VARIABLES_decl) = variable_length_type;
3504 UOBJC_INSTANCE_VARIABLES_decl = 0;
3506 generating_instance_variables = 0;
3510 build_dispatch_table_initializer (type, entries)
3514 tree initlist = NULLT;
3518 tree elemlist = NULLT;
3520 elemlist = tree_cons (NULLT, build_selector (METHOD_SEL_NAME (entries)),
3523 elemlist = tree_cons (NULLT, add_objc_string (METHOD_ENCODING (entries),
3527 elemlist = tree_cons (NULLT,
3528 build_unary_op (ADDR_EXPR, METHOD_DEFINITION (entries), 1),
3531 initlist = tree_cons (NULLT,
3532 build_constructor (type, nreverse (elemlist)),
3535 entries = TREE_CHAIN (entries);
3539 return build_constructor (build_array_type (type, 0), nreverse (initlist));
3542 /* To accomplish method prototyping without generating all kinds of
3543 inane warnings, the definition of the dispatch table entries were
3546 struct objc_method { SEL _cmd; ...; id (*_imp)(); };
3548 struct objc_method { SEL _cmd; ...; void *_imp; }; */
3551 build_method_template ()
3554 tree decl_specs, field_decl, field_decl_chain;
3556 _SLT_record = start_struct (RECORD_TYPE, get_identifier (UTAG_METHOD));
3558 #ifdef OBJC_INT_SELECTORS
3559 /* unsigned int _cmd; */
3560 decl_specs = tree_cons (NULLT, ridpointers[(int) RID_UNSIGNED], NULLT);
3561 decl_specs = tree_cons (NULLT, ridpointers[(int) RID_INT], decl_specs);
3562 field_decl = get_identifier ("_cmd");
3563 #else /* not OBJC_INT_SELECTORS */
3564 /* struct objc_selector *_cmd; */
3565 decl_specs = tree_cons (NULLT,
3566 xref_tag (RECORD_TYPE,
3567 get_identifier (TAG_SELECTOR)),
3569 field_decl = build1 (INDIRECT_REF, NULLT, get_identifier ("_cmd"));
3570 #endif /* not OBJC_INT_SELECTORS */
3572 field_decl = grokfield (input_filename, lineno, field_decl, decl_specs, NULLT);
3573 field_decl_chain = field_decl;
3575 decl_specs = tree_cons (NULLT, ridpointers[(int) RID_CHAR], NULLT);
3576 field_decl = build1 (INDIRECT_REF, NULLT, get_identifier ("method_types"));
3577 field_decl = grokfield (input_filename, lineno, field_decl, decl_specs, NULLT);
3578 chainon (field_decl_chain, field_decl);
3582 decl_specs = tree_cons (NULLT, ridpointers[(int) RID_VOID], NULLT);
3583 field_decl = build1 (INDIRECT_REF, NULLT, get_identifier ("_imp"));
3584 field_decl = grokfield (input_filename, lineno, field_decl, decl_specs, NULLT);
3585 chainon (field_decl_chain, field_decl);
3587 finish_struct (_SLT_record, field_decl_chain);
3594 generate_dispatch_table (type, name, size, list)
3600 tree sc_spec, decl_specs, decl, initlist;
3602 sc_spec = tree_cons (NULLT, ridpointers[(int) RID_STATIC], NULLT);
3603 decl_specs = tree_cons (NULLT, type, sc_spec);
3605 decl = start_decl (synth_id_with_class_suffix (name, implementation_context),
3607 end_temporary_allocation ();
3609 initlist = build_tree_list (NULLT, build_int_2 (0, 0));
3610 initlist = tree_cons (NULLT, build_int_2 (size, 0), initlist);
3611 initlist = tree_cons (NULLT, list, initlist);
3614 build_constructor (TREE_TYPE (decl), nreverse (initlist)),
3621 generate_dispatch_tables ()
3623 tree initlist, chain, method_list_template;
3624 tree cast, variable_length_type;
3627 if (!objc_method_template)
3628 objc_method_template = build_method_template ();
3632 (build_tree_list (NULLT, xref_tag (RECORD_TYPE,
3633 get_identifier (UTAG_METHOD_LIST))),
3635 variable_length_type = groktypename (cast);
3637 chain = CLASS_CLS_METHODS (implementation_context);
3640 size = list_length (chain);
3642 method_list_template = build_method_list_template (objc_method_template, size);
3643 initlist = build_dispatch_table_initializer (objc_method_template, chain);
3645 UOBJC_CLASS_METHODS_decl
3646 = generate_dispatch_table (method_list_template,
3647 ((TREE_CODE (implementation_context)
3648 == CLASS_IMPLEMENTATION_TYPE)
3649 ? "_OBJC_CLASS_METHODS"
3650 : "_OBJC_CATEGORY_CLASS_METHODS"),
3653 TREE_TYPE (UOBJC_CLASS_METHODS_decl) = variable_length_type;
3656 UOBJC_CLASS_METHODS_decl = 0;
3658 chain = CLASS_NST_METHODS (implementation_context);
3661 size = list_length (chain);
3663 method_list_template = build_method_list_template (objc_method_template, size);
3664 initlist = build_dispatch_table_initializer (objc_method_template, chain);
3666 if (TREE_CODE (implementation_context) == CLASS_IMPLEMENTATION_TYPE)
3667 UOBJC_INSTANCE_METHODS_decl
3668 = generate_dispatch_table (method_list_template,
3669 "_OBJC_INSTANCE_METHODS",
3672 /* we have a category */
3673 UOBJC_INSTANCE_METHODS_decl
3674 = generate_dispatch_table (method_list_template,
3675 "_OBJC_CATEGORY_INSTANCE_METHODS",
3678 TREE_TYPE (UOBJC_INSTANCE_METHODS_decl) = variable_length_type;
3681 UOBJC_INSTANCE_METHODS_decl = 0;
3685 generate_protocol_list (i_or_p)
3688 static tree cast_type = 0;
3689 tree initlist, decl_specs, sc_spec;
3690 tree refs_decl, expr_decl, lproto, e, plist;
3693 if (TREE_CODE (i_or_p) == CLASS_INTERFACE_TYPE
3694 || TREE_CODE (i_or_p) == CATEGORY_INTERFACE_TYPE)
3695 plist = CLASS_PROTOCOL_LIST (i_or_p);
3696 else if (TREE_CODE (i_or_p) == PROTOCOL_INTERFACE_TYPE)
3697 plist = PROTOCOL_LIST (i_or_p);
3705 (build_tree_list (NULLT,
3706 xref_tag (RECORD_TYPE,
3707 get_identifier (UTAG_PROTOCOL))),
3708 build1 (INDIRECT_REF, NULLT, NULLT)));
3711 for (lproto = plist; lproto; lproto = TREE_CHAIN (lproto))
3712 if (TREE_CODE (TREE_VALUE (lproto)) == PROTOCOL_INTERFACE_TYPE
3713 && PROTOCOL_FORWARD_DECL (TREE_VALUE (lproto)))
3716 /* build initializer */
3717 initlist = tree_cons (NULLT, build_int_2 (0, 0), NULLT);
3719 e = build_int_2 (size, 0);
3720 TREE_TYPE (e) = cast_type;
3721 initlist = tree_cons (NULLT, e, initlist);
3723 for (lproto = plist; lproto; lproto = TREE_CHAIN (lproto))
3725 tree pval = TREE_VALUE (lproto);
3727 if (TREE_CODE (pval) == PROTOCOL_INTERFACE_TYPE
3728 && PROTOCOL_FORWARD_DECL (pval))
3730 e = build_unary_op (ADDR_EXPR, PROTOCOL_FORWARD_DECL (pval), 0);
3731 initlist = tree_cons (NULLT, e, initlist);
3735 /* static struct objc_protocol *refs[n]; */
3737 sc_spec = tree_cons (NULLT, ridpointers[(int) RID_STATIC], NULLT);
3738 decl_specs = tree_cons (NULLT, xref_tag (RECORD_TYPE,
3739 get_identifier (UTAG_PROTOCOL)),
3742 if (TREE_CODE (i_or_p) == PROTOCOL_INTERFACE_TYPE)
3743 expr_decl = build_nt (ARRAY_REF,
3744 synth_id_with_class_suffix ("_OBJC_PROTOCOL_REFS",
3746 build_int_2 (size + 2, 0));
3747 else if (TREE_CODE (i_or_p) == CLASS_INTERFACE_TYPE)
3748 expr_decl = build_nt (ARRAY_REF,
3749 synth_id_with_class_suffix ("_OBJC_CLASS_PROTOCOLS",
3751 build_int_2 (size + 2, 0));
3752 else if (TREE_CODE (i_or_p) == CATEGORY_INTERFACE_TYPE)
3753 expr_decl = build_nt (ARRAY_REF,
3754 synth_id_with_class_suffix ("_OBJC_CATEGORY_PROTOCOLS",
3756 build_int_2 (size + 2, 0));
3758 expr_decl = build1 (INDIRECT_REF, NULLT, expr_decl);
3760 refs_decl = start_decl (expr_decl, decl_specs, 1);
3761 end_temporary_allocation ();
3763 finish_decl (refs_decl, build_constructor (TREE_TYPE (refs_decl),
3764 nreverse (initlist)),
3771 build_category_initializer (type, cat_name, class_name,
3772 instance_methods, class_methods, protocol_list)
3776 tree instance_methods;
3780 tree initlist = NULLT, expr;
3782 initlist = tree_cons (NULLT, cat_name, initlist);
3783 initlist = tree_cons (NULLT, class_name, initlist);
3785 if (!instance_methods)
3786 initlist = tree_cons (NULLT, build_int_2 (0, 0), initlist);
3789 expr = build_unary_op (ADDR_EXPR, instance_methods, 0);
3790 initlist = tree_cons (NULLT, expr, initlist);
3793 initlist = tree_cons (NULLT, build_int_2 (0, 0), initlist);
3796 expr = build_unary_op (ADDR_EXPR, class_methods, 0);
3797 initlist = tree_cons (NULLT, expr, initlist);
3800 /* protocol_list = */
3802 initlist = tree_cons (NULLT, build_int_2 (0, 0), initlist);
3805 static tree cast_type2;
3811 (build_tree_list (NULLT,
3812 xref_tag (RECORD_TYPE,
3813 get_identifier (UTAG_PROTOCOL))),
3814 build1 (INDIRECT_REF, NULLT,
3815 build1 (INDIRECT_REF, NULLT, NULLT))));
3817 expr = build_unary_op (ADDR_EXPR, protocol_list, 0);
3818 TREE_TYPE (expr) = cast_type2;
3819 initlist = tree_cons (NULLT, expr, initlist);
3822 return build_constructor (type, nreverse (initlist));
3825 /* struct objc_class {
3826 struct objc_class *isa;
3827 struct objc_class *super_class;
3832 struct objc_ivar_list *ivars;
3833 struct objc_method_list *methods;
3834 if (flag_next_runtime)
3835 struct objc_cache *cache;
3837 struct sarray *dtable;
3838 struct objc_class *subclass_list;
3839 struct objc_class *sibling_class;
3841 struct objc_protocol_list *protocols;
3845 build_shared_structure_initializer (type, isa, super, name, size, status,
3846 dispatch_table, ivar_list, protocol_list)
3853 tree dispatch_table;
3857 tree initlist = NULLT, expr;
3860 initlist = tree_cons (NULLT, isa, initlist);
3863 initlist = tree_cons (NULLT, super, initlist);
3866 initlist = tree_cons (NULLT, default_conversion (name), initlist);
3869 initlist = tree_cons (NULLT, build_int_2 (0, 0), initlist);
3872 initlist = tree_cons (NULLT, build_int_2 (status, 0), initlist);
3874 /* instance_size = */
3875 initlist = tree_cons (NULLT, size, initlist);
3877 /* objc_ivar_list = */
3879 initlist = tree_cons (NULLT, build_int_2 (0, 0), initlist);
3882 expr = build_unary_op (ADDR_EXPR, ivar_list, 0);
3883 initlist = tree_cons (NULLT, expr, initlist);
3886 /* objc_method_list = */
3887 if (!dispatch_table)
3888 initlist = tree_cons (NULLT, build_int_2 (0, 0), initlist);
3891 expr = build_unary_op (ADDR_EXPR, dispatch_table, 0);
3892 initlist = tree_cons (NULLT, expr, initlist);
3895 if (flag_next_runtime)
3896 /* method_cache = */
3897 initlist = tree_cons (NULLT, build_int_2 (0, 0), initlist);
3901 initlist = tree_cons (NULLT, build_int_2 (0, 0), initlist);
3903 /* subclass_list = */
3904 initlist = tree_cons (NULLT, build_int_2 (0, 0), initlist);
3906 /* sibling_class = */
3907 initlist = tree_cons (NULLT, build_int_2 (0, 0), initlist);
3910 /* protocol_list = */
3911 if (! protocol_list)
3912 initlist = tree_cons (NULLT, build_int_2 (0, 0), initlist);
3915 static tree cast_type2;
3921 (build_tree_list (NULLT,
3922 xref_tag (RECORD_TYPE,
3923 get_identifier (UTAG_PROTOCOL))),
3924 build1 (INDIRECT_REF, NULLT,
3925 build1 (INDIRECT_REF, NULLT, NULLT))));
3927 expr = build_unary_op (ADDR_EXPR, protocol_list, 0);
3928 TREE_TYPE (expr) = cast_type2;
3929 initlist = tree_cons (NULLT, expr, initlist);
3932 return build_constructor (type, nreverse (initlist));
3935 /* static struct objc_category _OBJC_CATEGORY_<name> = { ... }; */
3937 generate_category (cat)
3940 tree sc_spec, decl_specs, decl;
3941 tree initlist, cat_name_expr, class_name_expr;
3942 tree protocol_decl, category;
3944 add_class_reference (CLASS_NAME (cat));
3945 cat_name_expr = add_objc_string (CLASS_SUPER_NAME (cat), class_names);
3947 class_name_expr = add_objc_string (CLASS_NAME (cat), class_names);
3949 category = CLASS_CATEGORY_LIST (implementation_template);
3951 /* find the category interface from the class it is associated with */
3954 if (CLASS_SUPER_NAME (cat) == CLASS_SUPER_NAME (category))
3956 category = CLASS_CATEGORY_LIST (category);
3959 if (category && CLASS_PROTOCOL_LIST (category))
3961 generate_protocol_references (CLASS_PROTOCOL_LIST (category));
3962 protocol_decl = generate_protocol_list (category);
3967 sc_spec = tree_cons (NULLT, ridpointers[(int) RID_STATIC], NULLT);
3968 decl_specs = tree_cons (NULLT, objc_category_template, sc_spec);
3970 decl = start_decl (synth_id_with_class_suffix ("_OBJC_CATEGORY",
3971 implementation_context),
3973 end_temporary_allocation ();
3975 initlist = build_category_initializer (TREE_TYPE (decl),
3976 cat_name_expr, class_name_expr,
3977 UOBJC_INSTANCE_METHODS_decl,
3978 UOBJC_CLASS_METHODS_decl,
3981 TREE_USED (decl) = 1;
3982 finish_decl (decl, initlist, NULLT);
3985 /* static struct objc_class _OBJC_METACLASS_Foo={ ... };
3986 static struct objc_class _OBJC_CLASS_Foo={ ... }; */
3989 generate_shared_structures ()
3991 tree sc_spec, decl_specs, decl;
3992 tree name_expr, super_expr, root_expr;
3993 tree my_root_id = NULLT, my_super_id = NULLT;
3994 tree cast_type, initlist, protocol_decl;
3996 my_super_id = CLASS_SUPER_NAME (implementation_template);
3999 add_class_reference (my_super_id);
4001 /* Compute "my_root_id" - this is required for code generation.
4002 the "isa" for all meta class structures points to the root of
4003 the inheritance hierarchy (e.g. "__Object")... */
4004 my_root_id = my_super_id;
4007 tree my_root_int = lookup_interface (my_root_id);
4009 if (my_root_int && CLASS_SUPER_NAME (my_root_int))
4010 my_root_id = CLASS_SUPER_NAME (my_root_int);
4016 else /* no super class */
4018 my_root_id = CLASS_NAME (implementation_template);
4022 = groktypename (build_tree_list (build_tree_list (NULLT,
4023 objc_class_template),
4024 build1 (INDIRECT_REF, NULLT, NULLT)));
4026 name_expr = add_objc_string (CLASS_NAME (implementation_template),
4029 /* install class `isa' and `super' pointers at runtime */
4032 super_expr = add_objc_string (my_super_id, class_names);
4033 super_expr = build_c_cast (cast_type, super_expr); /* cast! */
4036 super_expr = build_int_2 (0, 0);
4038 root_expr = add_objc_string (my_root_id, class_names);
4039 root_expr = build_c_cast (cast_type, root_expr); /* cast! */
4041 if (CLASS_PROTOCOL_LIST (implementation_template))
4043 generate_protocol_references (CLASS_PROTOCOL_LIST (implementation_template));
4044 protocol_decl = generate_protocol_list (implementation_template);
4049 /* static struct objc_class _OBJC_METACLASS_Foo = { ... }; */
4051 sc_spec = build_tree_list (NULLT, ridpointers[(int) RID_STATIC]);
4052 decl_specs = tree_cons (NULLT, objc_class_template, sc_spec);
4054 decl = start_decl (DECL_NAME (UOBJC_METACLASS_decl), decl_specs, 1);
4055 end_temporary_allocation ();
4058 = build_shared_structure_initializer
4060 root_expr, super_expr, name_expr,
4061 build_int_2 ((TREE_INT_CST_LOW (TYPE_SIZE (objc_class_template))
4065 UOBJC_CLASS_METHODS_decl,
4066 UOBJC_CLASS_VARIABLES_decl,
4069 finish_decl (decl, initlist, NULLT);
4071 /* static struct objc_class _OBJC_CLASS_Foo={ ... }; */
4073 decl = start_decl (DECL_NAME (UOBJC_CLASS_decl), decl_specs, 1);
4074 end_temporary_allocation ();
4077 = build_shared_structure_initializer
4079 build_unary_op (ADDR_EXPR, UOBJC_METACLASS_decl, 0),
4080 super_expr, name_expr,
4081 build_int_2 ((TREE_INT_CST_LOW (TYPE_SIZE (CLASS_STATIC_TEMPLATE (implementation_template)))
4085 UOBJC_INSTANCE_METHODS_decl,
4086 UOBJC_INSTANCE_VARIABLES_decl,
4089 finish_decl (decl, initlist, NULLT);
4093 synth_id_with_class_suffix (preamble, ctxt)
4098 if (TREE_CODE (ctxt) == CLASS_IMPLEMENTATION_TYPE
4099 || TREE_CODE (ctxt) == CLASS_INTERFACE_TYPE)
4102 = IDENTIFIER_POINTER (CLASS_NAME (implementation_context));
4103 string = (char *) alloca (strlen (preamble) + strlen (class_name) + 3);
4104 sprintf (string, "%s_%s", preamble,
4105 IDENTIFIER_POINTER (CLASS_NAME (ctxt)));
4107 else if (TREE_CODE (ctxt) == CATEGORY_IMPLEMENTATION_TYPE
4108 || TREE_CODE (ctxt) == CATEGORY_INTERFACE_TYPE)
4110 /* we have a category */
4112 = IDENTIFIER_POINTER (CLASS_NAME (implementation_context));
4113 char *class_super_name
4114 = IDENTIFIER_POINTER (CLASS_SUPER_NAME (implementation_context));
4115 string = (char *) alloca (strlen (preamble)
4116 + strlen (class_name)
4117 + strlen (class_super_name)
4119 sprintf (string, "%s_%s_%s", preamble, class_name, class_super_name);
4121 else if (TREE_CODE (ctxt) == PROTOCOL_INTERFACE_TYPE)
4123 char *protocol_name = IDENTIFIER_POINTER (PROTOCOL_NAME (ctxt));
4124 string = (char *) alloca (strlen (preamble) + strlen (protocol_name) + 3);
4125 sprintf (string, "%s_%s", preamble, protocol_name);
4127 return get_identifier (string);
4131 is_objc_type_qualifier (node)
4134 return (TREE_CODE (node) == IDENTIFIER_NODE
4135 && (node == ridpointers [(int) RID_CONST]
4136 || node == ridpointers [(int) RID_VOLATILE]
4137 || node == ridpointers [(int) RID_IN]
4138 || node == ridpointers [(int) RID_OUT]
4139 || node == ridpointers [(int) RID_INOUT]
4140 || node == ridpointers [(int) RID_BYCOPY]
4141 || node == ridpointers [(int) RID_ONEWAY]));
4144 /* If type is empty or only type qualifiers are present, add default
4145 type of id (otherwise grokdeclarator will default to int). */
4148 adjust_type_for_id_default (type)
4151 tree declspecs, chain;
4154 return build_tree_list (build_tree_list (NULLT, objc_object_reference),
4155 build1 (INDIRECT_REF, NULLT, NULLT));
4157 declspecs = TREE_PURPOSE (type);
4159 /* Determine if a typespec is present. */
4160 for (chain = declspecs;
4162 chain = TREE_CHAIN (chain))
4164 if (!is_objc_type_qualifier (TREE_VALUE (chain)))
4168 return build_tree_list (tree_cons (NULLT, objc_object_reference, declspecs),
4169 build1 (INDIRECT_REF, NULLT, NULLT));
4174 selector ':' '(' typename ')' identifier
4177 transform an Objective-C keyword argument into
4178 the C equivalent parameter declarator.
4180 in: key_name, an "identifier_node" (optional).
4181 arg_type, a "tree_list" (optional).
4182 arg_name, an "identifier_node".
4184 note: it would be really nice to strongly type the preceding
4185 arguments in the function prototype; however, then i
4186 could not use the "accessor" macros defined in "tree.h".
4188 out: an instance of "keyword_decl". */
4191 build_keyword_decl (key_name, arg_type, arg_name)
4198 /* if no type is specified, default to "id" */
4199 arg_type = adjust_type_for_id_default (arg_type);
4201 keyword_decl = make_node (KEYWORD_DECL);
4203 TREE_TYPE (keyword_decl) = arg_type;
4204 KEYWORD_ARG_NAME (keyword_decl) = arg_name;
4205 KEYWORD_KEY_NAME (keyword_decl) = key_name;
4207 return keyword_decl;
4210 /* Given a chain of keyword_decl's, synthesize the full keyword selector. */
4212 build_keyword_selector (selector)
4216 tree key_chain, key_name;
4219 for (key_chain = selector; key_chain; key_chain = TREE_CHAIN (key_chain))
4221 if (TREE_CODE (selector) == KEYWORD_DECL)
4222 key_name = KEYWORD_KEY_NAME (key_chain);
4223 else if (TREE_CODE (selector) == TREE_LIST)
4224 key_name = TREE_PURPOSE (key_chain);
4227 len += IDENTIFIER_LENGTH (key_name) + 1;
4228 else /* just a ':' arg */
4231 buf = (char *)alloca (len + 1);
4232 bzero (buf, len + 1);
4234 for (key_chain = selector; key_chain; key_chain = TREE_CHAIN (key_chain))
4236 if (TREE_CODE (selector) == KEYWORD_DECL)
4237 key_name = KEYWORD_KEY_NAME (key_chain);
4238 else if (TREE_CODE (selector) == TREE_LIST)
4239 key_name = TREE_PURPOSE (key_chain);
4242 strcat (buf, IDENTIFIER_POINTER (key_name));
4245 return get_identifier (buf);
4248 /* used for declarations and definitions */
4251 build_method_decl (code, ret_type, selector, add_args)
4252 enum tree_code code;
4259 /* if no type is specified, default to "id" */
4260 ret_type = adjust_type_for_id_default (ret_type);
4262 method_decl = make_node (code);
4263 TREE_TYPE (method_decl) = ret_type;
4265 /* If we have a keyword selector, create an identifier_node that
4266 represents the full selector name (`:' included)... */
4267 if (TREE_CODE (selector) == KEYWORD_DECL)
4269 METHOD_SEL_NAME (method_decl) = build_keyword_selector (selector);
4270 METHOD_SEL_ARGS (method_decl) = selector;
4271 METHOD_ADD_ARGS (method_decl) = add_args;
4275 METHOD_SEL_NAME (method_decl) = selector;
4276 METHOD_SEL_ARGS (method_decl) = NULLT;
4277 METHOD_ADD_ARGS (method_decl) = NULLT;
4283 #define METHOD_DEF 0
4284 #define METHOD_REF 1
4286 /* Used by `build_message_expr' and `comp_method_types'. Return an
4287 argument list for method METH. CONTEXT is either METHOD_DEF or
4288 METHOD_REF, saying whether we are trying to define a method or call
4289 one. SUPERFLAG says this is for a send to super; this makes a
4290 difference for the NeXT calling sequence in which the lookup and
4291 the method call are done together. */
4294 get_arg_type_list (meth, context, superflag)
4302 if (flag_next_runtime && superflag)
4303 arglist = build_tree_list (NULLT, super_type);
4304 else if (context == METHOD_DEF)
4305 arglist = build_tree_list (NULLT, TREE_TYPE (self_decl));
4307 arglist = build_tree_list (NULLT, id_type);
4309 /* selector type - will eventually change to `int' */
4310 chainon (arglist, build_tree_list (NULLT, selector_type));
4312 /* build a list of argument types */
4313 for (akey = METHOD_SEL_ARGS (meth); akey; akey = TREE_CHAIN (akey))
4315 tree arg_decl = groktypename_in_parm_context (TREE_TYPE (akey));
4316 chainon (arglist, build_tree_list (NULLT, TREE_TYPE (arg_decl)));
4319 if (METHOD_ADD_ARGS (meth) == (tree)1)
4320 /* We have a `, ...' immediately following the selector,
4321 finalize the arglist...simulate get_parm_info (0). */
4323 else if (METHOD_ADD_ARGS (meth))
4325 /* we have a variable length selector */
4326 tree add_arg_list = TREE_CHAIN (METHOD_ADD_ARGS (meth));
4327 chainon (arglist, add_arg_list);
4330 /* finalize the arglist...simulate get_parm_info (1) */
4331 chainon (arglist, build_tree_list (NULLT, void_type_node));
4337 check_duplicates (hsh)
4348 /* we have two methods with the same name and different types */
4350 char type = (TREE_CODE (meth) == INSTANCE_METHOD_DECL) ? '-' : '+';
4352 warning ("multiple declarations for method `%s'",
4353 IDENTIFIER_POINTER (METHOD_SEL_NAME (meth)));
4355 warn_with_method ("using", type, meth);
4356 for (loop = hsh->list; loop; loop = loop->next)
4357 warn_with_method ("also found", type, loop->value);
4363 /* If RECEIVER is a class reference, return the identifier node for the
4364 referenced class. RECEIVER is created by get_class_reference, so we
4365 check the exact form created depending on which runtimes are used. */
4368 receiver_is_class_object (receiver)
4371 tree chain, exp, arg;
4372 if (flag_next_runtime)
4374 /* The receiver is a variable created by build_class_reference_decl. */
4375 if (TREE_CODE (receiver) == VAR_DECL
4376 && TREE_TYPE (receiver) == objc_class_type)
4377 /* Look up the identifier. */
4378 for (chain = cls_ref_chain; chain; chain = TREE_CHAIN (chain))
4379 if (TREE_PURPOSE (chain) == receiver)
4380 return TREE_VALUE (chain);
4384 /* The receiver is a function call that returns an id. Check if
4385 it is a call to objc_getClass, if so, pick up the class name. */
4386 if ((exp = TREE_OPERAND (receiver, 0))
4387 && TREE_CODE (exp) == ADDR_EXPR
4388 && (exp = TREE_OPERAND (exp, 0))
4389 && TREE_CODE (exp) == FUNCTION_DECL
4390 && exp == objc_get_class_decl
4391 /* we have a call to objc_getClass! */
4392 && (arg = TREE_OPERAND (receiver, 1))
4393 && TREE_CODE (arg) == TREE_LIST
4394 && (arg = TREE_VALUE (arg)))
4397 if (TREE_CODE (arg) == ADDR_EXPR
4398 && (arg = TREE_OPERAND (arg, 0))
4399 && TREE_CODE (arg) == STRING_CST)
4400 /* finally, we have the class name */
4401 return get_identifier (TREE_STRING_POINTER (arg));
4407 /* If we are currently building a message expr, this holds
4408 the identifier of the selector of the message. This is
4409 used when printing warnings about argument mismatches. */
4411 static tree building_objc_message_expr = 0;
4414 maybe_building_objc_message_expr ()
4416 return building_objc_message_expr;
4419 /* Construct an expression for sending a message.
4420 MESS has the object to send to in TREE_PURPOSE
4421 and the argument list (including selector) in TREE_VALUE.
4423 (*(<abstract_decl>(*)())_msg)(receiver, selTransTbl[n], ...);
4424 (*(<abstract_decl>(*)())_msgSuper)(receiver, selTransTbl[n], ...); */
4427 build_message_expr (mess)
4430 tree receiver = TREE_PURPOSE (mess);
4431 tree selector, self_object;
4432 tree rtype, sel_name;
4433 tree args = TREE_VALUE (mess);
4434 tree method_params = NULLT;
4435 tree method_prototype = NULLT;
4437 int statically_typed = 0, statically_allocated = 0;
4438 tree class_ident = 0;
4440 /* 1 if this is sending to the superclass. */
4443 if (!doing_objc_thang)
4446 if (TREE_CODE (receiver) == ERROR_MARK)
4447 return error_mark_node;
4449 /* determine receiver type */
4450 rtype = TREE_TYPE (receiver);
4451 super = IS_SUPER (rtype);
4455 if (TREE_STATIC_TEMPLATE (rtype))
4456 statically_allocated = 1;
4457 else if (TREE_CODE (rtype) == POINTER_TYPE
4458 && TREE_STATIC_TEMPLATE (TREE_TYPE (rtype)))
4459 statically_typed = 1;
4460 else if ((flag_next_runtime
4461 || (TREE_CODE (receiver) == CALL_EXPR && IS_ID (rtype)))
4462 && (class_ident = receiver_is_class_object (receiver)))
4464 else if (! IS_ID (rtype)
4465 /* Allow any type that matches objc_class_type. */
4466 && ! comptypes (rtype, objc_class_type))
4468 bzero (errbuf, BUFSIZE);
4469 warning ("invalid receiver type `%s'",
4470 gen_declaration (rtype, errbuf));
4472 if (statically_allocated)
4473 receiver = build_unary_op (ADDR_EXPR, receiver, 0);
4475 /* Don't evaluate the receiver twice. */
4476 receiver = save_expr (receiver);
4477 self_object = receiver;
4480 /* If sending to `super', use current self as the object. */
4481 self_object = self_decl;
4483 /* Obtain the full selector name. */
4485 if (TREE_CODE (args) == IDENTIFIER_NODE)
4486 /* a unary selector */
4488 else if (TREE_CODE (args) == TREE_LIST)
4489 sel_name = build_keyword_selector (args);
4491 /* Build the parameter list to give to the method. */
4493 method_params = NULLT;
4494 if (TREE_CODE (args) == TREE_LIST)
4496 tree chain = args, prev = NULLT;
4498 /* We have a keyword selector--check for comma expressions. */
4501 tree element = TREE_VALUE (chain);
4503 /* We have a comma expression, must collapse... */
4504 if (TREE_CODE (element) == TREE_LIST)
4507 TREE_CHAIN (prev) = element;
4512 chain = TREE_CHAIN (chain);
4514 method_params = args;
4517 /* Determine operation return type. */
4519 if (IS_SUPER (rtype))
4523 if (CLASS_SUPER_NAME (implementation_template))
4525 iface = lookup_interface (CLASS_SUPER_NAME (implementation_template));
4527 if (TREE_CODE (method_context) == INSTANCE_METHOD_DECL)
4528 method_prototype = lookup_instance_method_static (iface, sel_name);
4530 method_prototype = lookup_class_method_static (iface, sel_name);
4532 if (iface && !method_prototype)
4533 warning ("`%s' does not respond to `%s'",
4534 IDENTIFIER_POINTER (CLASS_SUPER_NAME (implementation_template)),
4535 IDENTIFIER_POINTER (sel_name));
4539 error ("no super class declared in interface for `%s'",
4540 IDENTIFIER_POINTER (CLASS_NAME (implementation_template)));
4541 return error_mark_node;
4545 else if (statically_allocated)
4547 tree ctype = TREE_TYPE (rtype);
4548 tree iface = lookup_interface (TYPE_NAME (rtype));
4551 method_prototype = lookup_instance_method_static (iface, sel_name);
4554 if (! method_prototype && TYPE_PROTOCOL_LIST (ctype))
4556 = lookup_method_in_protocol_list (TYPE_PROTOCOL_LIST (ctype),
4559 if (!method_prototype)
4560 warning ("`%s' does not respond to `%s'",
4561 IDENTIFIER_POINTER (TYPE_NAME (rtype)),
4562 IDENTIFIER_POINTER (sel_name));
4564 else if (statically_typed)
4566 tree ctype = TREE_TYPE (rtype);
4568 /* `self' is now statically_typed...all methods should be visible
4569 within the context of the implementation... */
4570 if (implementation_context
4571 && CLASS_NAME (implementation_context) == TYPE_NAME (ctype))
4573 method_prototype = lookup_instance_method_static (implementation_template, sel_name);
4576 if (! method_prototype && TYPE_PROTOCOL_LIST (ctype))
4578 = lookup_method_in_protocol_list (TYPE_PROTOCOL_LIST (ctype),
4581 if (! method_prototype
4582 && implementation_template != implementation_context)
4583 /* the method is not published in the interface...check locally */
4585 = lookup_method (CLASS_NST_METHODS (implementation_context),
4592 if ((iface = lookup_interface (TYPE_NAME (ctype))))
4593 method_prototype = lookup_instance_method_static (iface, sel_name);
4595 if (! method_prototype)
4597 tree protocol_list = TYPE_PROTOCOL_LIST (ctype);
4600 = lookup_method_in_protocol_list (protocol_list, sel_name, 0);
4604 if (!method_prototype)
4605 warning ("`%s' does not respond to `%s'",
4606 IDENTIFIER_POINTER (TYPE_NAME (ctype)),
4607 IDENTIFIER_POINTER (sel_name));
4609 else if (class_ident)
4611 if (implementation_context
4612 && CLASS_NAME (implementation_context) == class_ident)
4615 = lookup_class_method_static (implementation_template, sel_name);
4617 if (!method_prototype
4618 && implementation_template != implementation_context)
4619 /* the method is not published in the interface...check locally */
4621 = lookup_method (CLASS_CLS_METHODS (implementation_context),
4628 if ((iface = lookup_interface (class_ident)))
4629 method_prototype = lookup_class_method_static (iface, sel_name);
4632 if (!method_prototype)
4634 warning ("cannot find class (factory) method.");
4635 warning ("return type for `%s' defaults to id",
4636 IDENTIFIER_POINTER (sel_name));
4639 else if (IS_PROTOCOL_QUALIFIED_ID (rtype))
4641 /* An anonymous object that has been qualified with a protocol. */
4643 tree protocol_list = TYPE_PROTOCOL_LIST (rtype);
4645 method_prototype = lookup_method_in_protocol_list (protocol_list,
4648 if (!method_prototype)
4652 warning ("method `%s' not implemented by protocol.",
4653 IDENTIFIER_POINTER (sel_name));
4655 /* try and find the method signiture in the global pools! */
4657 if (!(hsh = hash_lookup (nst_method_hash_list, sel_name)))
4658 hsh = hash_lookup (cls_method_hash_list, sel_name);
4660 if (!(method_prototype = check_duplicates (hsh)))
4661 warning ("return type defaults to id");
4668 /* we think we have an instance...loophole: extern id Object; */
4669 hsh = hash_lookup (nst_method_hash_list, sel_name);
4671 /* for various loopholes...like sending messages to self in a
4672 factory context... */
4673 hsh = hash_lookup (cls_method_hash_list, sel_name);
4675 method_prototype = check_duplicates (hsh);
4676 if (!method_prototype)
4678 warning ("cannot find method.");
4679 warning ("return type for `%s' defaults to id",
4680 IDENTIFIER_POINTER (sel_name));
4684 /* Save the selector name for printing error messages. */
4685 building_objc_message_expr = sel_name;
4687 /* Build the parameters list for looking up the method.
4688 These are the object itself and the selector. */
4690 if (flag_typed_selectors)
4691 selector = build_typed_selector_reference (sel_name, method_prototype);
4693 selector = build_selector_reference (sel_name);
4695 retval = build_objc_method_call (super, method_prototype,
4696 receiver, self_object,
4697 selector, method_params);
4699 building_objc_message_expr = 0;
4704 /* Build a tree expression to send OBJECT the operation SELECTOR,
4705 looking up the method on object LOOKUP_OBJECT (often same as OBJECT),
4706 assuming the method has prototype METHOD_PROTOTYPE.
4707 (That is an INSTANCE_METHOD_DECL or CLASS_METHOD_DECL.)
4708 Use METHOD_PARAMS as list of args to pass to the method.
4709 If SUPER_FLAG is nonzero, we look up the superclass's method. */
4712 build_objc_method_call (super_flag, method_prototype, lookup_object, object,
4713 selector, method_params)
4715 tree method_prototype, lookup_object, object, selector, method_params;
4717 tree sender = (super_flag ? umsg_super_decl : umsg_decl);
4718 tree rcv_p = (super_flag
4719 ? build_pointer_type (xref_tag (RECORD_TYPE,
4720 get_identifier (TAG_SUPER)))
4723 if (flag_next_runtime)
4725 if (! method_prototype)
4727 method_params = tree_cons (NULLT, lookup_object,
4728 tree_cons (NULLT, selector,
4730 assemble_external (sender);
4731 return build_function_call (sender, method_params);
4735 /* This is a real kludge, but it is used only for the Next.
4736 Clobber the data type of SENDER temporarily to accept
4737 all the arguments for this operation, and to return
4738 whatever this operation returns. */
4739 tree arglist = NULLT;
4742 /* Save the proper contents of SENDER's data type. */
4743 tree savarg = TYPE_ARG_TYPES (TREE_TYPE (sender));
4744 tree savret = TREE_TYPE (TREE_TYPE (sender));
4746 /* Install this method's argument types. */
4747 arglist = get_arg_type_list (method_prototype, METHOD_REF,
4749 TYPE_ARG_TYPES (TREE_TYPE (sender)) = arglist;
4751 /* Install this method's return type. */
4752 TREE_TYPE (TREE_TYPE (sender))
4753 = groktypename (TREE_TYPE (method_prototype));
4755 /* Call SENDER with all the parameters. This will do type
4756 checking using the arg types for this method. */
4757 method_params = tree_cons (NULLT, lookup_object,
4758 tree_cons (NULLT, selector,
4760 assemble_external (sender);
4761 retval = build_function_call (sender, method_params);
4763 /* Restore SENDER's return/argument types. */
4764 TYPE_ARG_TYPES (TREE_TYPE (sender)) = savarg;
4765 TREE_TYPE (TREE_TYPE (sender)) = savret;
4771 /* This is the portable way.
4772 First call the lookup function to get a pointer to the method,
4773 then cast the pointer, then call it with the method arguments. */
4776 /* Avoid trouble since we may evaluate each of these twice. */
4777 object = save_expr (object);
4778 selector = save_expr (selector);
4780 lookup_object = build_c_cast (rcv_p, lookup_object); /* cast! */
4782 assemble_external (sender);
4784 = build_function_call (sender,
4785 tree_cons (NULLT, lookup_object,
4786 tree_cons (NULLT, selector, NULLT)));
4788 /* If we have a method prototype, construct the data type this
4789 method needs, and cast what we got from SENDER into a pointer
4791 if (method_prototype)
4793 tree arglist = get_arg_type_list (method_prototype, METHOD_REF,
4795 tree valtype = groktypename (TREE_TYPE (method_prototype));
4796 tree fake_function_type = build_function_type (valtype, arglist);
4797 TREE_TYPE (method) = build_pointer_type (fake_function_type);
4801 = build_pointer_type (build_function_type (ptr_type_node, NULLT));
4803 /* Pass the object to the method. */
4804 assemble_external (method);
4805 return build_function_call (method,
4806 tree_cons (NULLT, object,
4807 tree_cons (NULLT, selector,
4813 build_protocol_reference (p)
4816 tree decl, ident, ptype;
4817 struct obstack *save_current_obstack = current_obstack;
4818 struct obstack *save_rtl_obstack = rtl_obstack;
4820 rtl_obstack = current_obstack = &permanent_obstack;
4822 /* extern struct objc_protocol _OBJC_PROTOCOL_<mumble>; */
4824 ident = synth_id_with_class_suffix ("_OBJC_PROTOCOL", p);
4826 = groktypename (build_tree_list (build_tree_list (NULLT,
4827 objc_protocol_template),
4830 if (IDENTIFIER_GLOBAL_VALUE (ident))
4831 decl = IDENTIFIER_GLOBAL_VALUE (ident); /* Set by pushdecl. */
4834 decl = build_decl (VAR_DECL, ident, ptype);
4835 DECL_EXTERNAL (decl) = 1;
4836 TREE_PUBLIC (decl) = 1;
4837 TREE_USED (decl) = 1;
4839 /* usually called from `rest_of_decl_compilation' */
4840 make_decl_rtl (decl, 0, 1);
4841 /* our `extended/custom' pushdecl in c-decl.c */
4842 pushdecl_top_level (decl);
4844 current_obstack = save_current_obstack;
4845 rtl_obstack = save_rtl_obstack;
4847 PROTOCOL_FORWARD_DECL (p) = decl;
4851 build_protocol_expr (protoname)
4857 if (!doing_objc_thang)
4860 p = lookup_protocol (protoname);
4864 error ("Cannot find protocol declaration for `%s'",
4865 IDENTIFIER_POINTER (protoname));
4866 return error_mark_node;
4869 if (!PROTOCOL_FORWARD_DECL (p))
4870 build_protocol_reference (p);
4872 expr = build_unary_op (ADDR_EXPR, PROTOCOL_FORWARD_DECL (p), 0);
4874 TREE_TYPE (expr) = protocol_type;
4880 build_selector_expr (selnamelist)
4885 if (!doing_objc_thang)
4888 /* obtain the full selector name */
4889 if (TREE_CODE (selnamelist) == IDENTIFIER_NODE)
4890 /* a unary selector */
4891 selname = selnamelist;
4892 else if (TREE_CODE (selnamelist) == TREE_LIST)
4893 selname = build_keyword_selector (selnamelist);
4895 if (flag_typed_selectors)
4896 return build_typed_selector_reference (selname, 0);
4898 return build_selector_reference (selname);
4902 build_encode_expr (type)
4908 if (!doing_objc_thang)
4911 encode_type (type, obstack_object_size (&util_obstack),
4912 OBJC_ENCODE_INLINE_DEFS);
4913 obstack_1grow (&util_obstack, 0); /* null terminate string */
4914 string = obstack_finish (&util_obstack);
4916 /* synthesize a string that represents the encoded struct/union */
4917 result = my_build_string (strlen (string) + 1, string);
4918 obstack_free (&util_obstack, util_firstobj);
4923 build_ivar_reference (id)
4926 if (TREE_CODE (method_context) == CLASS_METHOD_DECL)
4928 /* Historically, a class method that produced objects (factory
4929 method) would assign `self' to the instance that it
4930 allocated. This would effectively turn the class method into
4931 an instance method. Following this assignment, the instance
4932 variables could be accessed. That practice, while safe,
4933 violates the simple rule that a class method should not refer
4934 to an instance variable. It's better to catch the cases
4935 where this is done unknowingly than to support the above
4937 warning ("instance variable `%s' accessed in class method",
4938 IDENTIFIER_POINTER (id));
4939 TREE_TYPE (self_decl) = instance_type; /* cast */
4942 return build_component_ref (build_indirect_ref (self_decl, "->"), id);
4945 #define HASH_ALLOC_LIST_SIZE 170
4946 #define ATTR_ALLOC_LIST_SIZE 170
4947 #define SIZEHASHTABLE 257
4950 #define HASHFUNCTION(key) ((HOST_WIDE_INT) key & 0x7fffffff)
4955 nst_method_hash_list = (hash *)xmalloc (SIZEHASHTABLE * sizeof (hash));
4956 cls_method_hash_list = (hash *)xmalloc (SIZEHASHTABLE * sizeof (hash));
4958 if (!nst_method_hash_list || !cls_method_hash_list)
4959 perror ("unable to allocate space in objc-tree.c");
4964 for (i = 0; i < SIZEHASHTABLE; i++)
4966 nst_method_hash_list[i] = 0;
4967 cls_method_hash_list[i] = 0;
4973 hash_enter (hashlist, method)
4977 static hash hash_alloc_list = 0;
4978 static int hash_alloc_index = 0;
4980 int slot = HASHFUNCTION (METHOD_SEL_NAME (method)) % SIZEHASHTABLE;
4982 if (! hash_alloc_list || hash_alloc_index >= HASH_ALLOC_LIST_SIZE)
4984 hash_alloc_index = 0;
4985 hash_alloc_list = (hash) xmalloc (sizeof (struct hashed_entry)
4986 * HASH_ALLOC_LIST_SIZE);
4987 if (! hash_alloc_list)
4988 perror ("unable to allocate in objc-tree.c");
4990 obj = &hash_alloc_list[hash_alloc_index++];
4992 obj->next = hashlist[slot];
4995 hashlist[slot] = obj; /* append to front */
4999 hash_lookup (hashlist, sel_name)
5005 target = hashlist[HASHFUNCTION (sel_name) % SIZEHASHTABLE];
5009 if (sel_name == METHOD_SEL_NAME (target->key))
5012 target = target->next;
5018 hash_add_attr (entry, value)
5022 static attr attr_alloc_list = 0;
5023 static int attr_alloc_index = 0;
5026 if (! attr_alloc_list || attr_alloc_index >= ATTR_ALLOC_LIST_SIZE)
5028 attr_alloc_index = 0;
5029 attr_alloc_list = (attr) xmalloc (sizeof (struct hashed_attribute)
5030 * ATTR_ALLOC_LIST_SIZE);
5031 if (! attr_alloc_list)
5032 perror ("unable to allocate in objc-tree.c");
5034 obj = &attr_alloc_list[attr_alloc_index++];
5035 obj->next = entry->list;
5038 entry->list = obj; /* append to front */
5042 lookup_method (mchain, method)
5048 if (TREE_CODE (method) == IDENTIFIER_NODE)
5051 key = METHOD_SEL_NAME (method);
5055 if (METHOD_SEL_NAME (mchain) == key)
5057 mchain = TREE_CHAIN (mchain);
5063 lookup_instance_method_static (interface, ident)
5067 tree inter = interface;
5068 tree chain = CLASS_NST_METHODS (inter);
5073 if ((meth = lookup_method (chain, ident)))
5076 if (CLASS_CATEGORY_LIST (inter))
5078 tree category = CLASS_CATEGORY_LIST (inter);
5079 chain = CLASS_NST_METHODS (category);
5083 if ((meth = lookup_method (chain, ident)))
5087 /* Check for instance methods in protocols in categories. */
5088 if (CLASS_PROTOCOL_LIST (category))
5090 if ((meth = (lookup_method_in_protocol_list
5091 (CLASS_PROTOCOL_LIST (category), ident, 0))))
5095 if ((category = CLASS_CATEGORY_LIST (category)))
5096 chain = CLASS_NST_METHODS (category);
5101 if (CLASS_PROTOCOL_LIST (inter))
5103 if ((meth = (lookup_method_in_protocol_list
5104 (CLASS_PROTOCOL_LIST (inter), ident, 0))))
5108 if ((inter = lookup_interface (CLASS_SUPER_NAME (inter))))
5109 chain = CLASS_NST_METHODS (inter);
5117 lookup_class_method_static (interface, ident)
5121 tree inter = interface;
5122 tree chain = CLASS_CLS_METHODS (inter);
5124 tree root_inter = NULLT;
5128 if ((meth = lookup_method (chain, ident)))
5131 if (CLASS_CATEGORY_LIST (inter))
5133 tree category = CLASS_CATEGORY_LIST (inter);
5134 chain = CLASS_CLS_METHODS (category);
5138 if ((meth = lookup_method (chain, ident)))
5142 /* Check for class methods in protocols in categories. */
5143 if (CLASS_PROTOCOL_LIST (category))
5145 if ((meth = (lookup_method_in_protocol_list
5146 (CLASS_PROTOCOL_LIST (category), ident, 1))))
5150 if ((category = CLASS_CATEGORY_LIST (category)))
5151 chain = CLASS_CLS_METHODS (category);
5157 /* Check for class methods in protocols. */
5158 if (CLASS_PROTOCOL_LIST (inter))
5160 if ((meth = (lookup_method_in_protocol_list
5161 (CLASS_PROTOCOL_LIST (inter), ident, 1))))
5166 if ((inter = lookup_interface (CLASS_SUPER_NAME (inter))))
5167 chain = CLASS_CLS_METHODS (inter);
5172 /* Simulate wrap around. */
5173 return lookup_instance_method_static (root_inter, ident);
5177 add_class_method (class, method)
5184 /* We will have allocated the method parameter declarations on the
5185 maybepermanent_obstack. Need to make sure they stick around! */
5188 if (!(mth = lookup_method (CLASS_CLS_METHODS (class), method)))
5190 /* put method on list in reverse order */
5191 TREE_CHAIN (method) = CLASS_CLS_METHODS (class);
5192 CLASS_CLS_METHODS (class) = method;
5196 if (TREE_CODE (class) == CLASS_IMPLEMENTATION_TYPE)
5197 error ("duplicate definition of class method `%s'.",
5198 IDENTIFIER_POINTER (METHOD_SEL_NAME (mth)));
5201 /* check types, if different complain */
5202 if (!comp_proto_with_proto (method, mth))
5203 error ("duplicate declaration of class method `%s'.",
5204 IDENTIFIER_POINTER (METHOD_SEL_NAME (mth)));
5208 if (!(hsh = hash_lookup (cls_method_hash_list, METHOD_SEL_NAME (method))))
5210 /* install on a global chain */
5211 hash_enter (cls_method_hash_list, method);
5215 /* check types, if different add to a list */
5216 if (!comp_proto_with_proto (method, hsh->key))
5217 hash_add_attr (hsh, method);
5223 add_instance_method (class, method)
5230 /* We will have allocated the method parameter declarations on the
5231 maybepermanent_obstack. Need to make sure they stick around! */
5234 if (!(mth = lookup_method (CLASS_NST_METHODS (class), method)))
5236 /* put method on list in reverse order */
5237 TREE_CHAIN (method) = CLASS_NST_METHODS (class);
5238 CLASS_NST_METHODS (class) = method;
5242 if (TREE_CODE (class) == CLASS_IMPLEMENTATION_TYPE)
5243 error ("duplicate definition of instance method `%s'.",
5244 IDENTIFIER_POINTER (METHOD_SEL_NAME (mth)));
5247 /* check types, if different complain */
5248 if (!comp_proto_with_proto (method, mth))
5249 error ("duplicate declaration of instance method `%s'.",
5250 IDENTIFIER_POINTER (METHOD_SEL_NAME (mth)));
5254 if (!(hsh = hash_lookup (nst_method_hash_list, METHOD_SEL_NAME (method))))
5256 /* install on a global chain */
5257 hash_enter (nst_method_hash_list, method);
5261 /* check types, if different add to a list */
5262 if (!comp_proto_with_proto (method, hsh->key))
5263 hash_add_attr (hsh, method);
5272 /* put interfaces on list in reverse order */
5273 TREE_CHAIN (class) = interface_chain;
5274 interface_chain = class;
5275 return interface_chain;
5279 add_category (class, category)
5283 /* put categories on list in reverse order */
5285 tree cat = CLASS_CATEGORY_LIST (class);
5288 if (CLASS_SUPER_NAME (cat) == CLASS_SUPER_NAME (category))
5289 warning ("duplicate interface declaration for category `%s(%s)'",
5290 IDENTIFIER_POINTER (CLASS_NAME (class)),
5291 IDENTIFIER_POINTER (CLASS_SUPER_NAME (category)));
5292 cat = CLASS_CATEGORY_LIST (cat);
5295 CLASS_CATEGORY_LIST (category) = CLASS_CATEGORY_LIST (class);
5296 CLASS_CATEGORY_LIST (class) = category;
5299 /* Called after parsing each instance variable declaration. Necessary to
5300 preserve typedefs and implement public/private...
5302 PUBLIC is 1 for public, 0 for protected, and 2 for private. */
5305 add_instance_variable (class, public, declarator, declspecs, width)
5312 tree field_decl, raw_decl;
5314 raw_decl = build_tree_list (declspecs /*purpose*/, declarator/*value*/);
5316 if (CLASS_RAW_IVARS (class))
5317 chainon (CLASS_RAW_IVARS (class), raw_decl);
5319 CLASS_RAW_IVARS (class) = raw_decl;
5321 field_decl = grokfield (input_filename, lineno,
5322 declarator, declspecs, width);
5324 /* overload the public attribute, it is not used for FIELD_DECL's */
5328 TREE_PUBLIC (field_decl) = 0;
5329 TREE_PRIVATE (field_decl) = 0;
5330 TREE_PROTECTED (field_decl) = 1;
5334 TREE_PUBLIC (field_decl) = 1;
5335 TREE_PRIVATE (field_decl) = 0;
5336 TREE_PROTECTED (field_decl) = 0;
5340 TREE_PUBLIC (field_decl) = 0;
5341 TREE_PRIVATE (field_decl) = 1;
5342 TREE_PROTECTED (field_decl) = 0;
5347 if (CLASS_IVARS (class))
5348 chainon (CLASS_IVARS (class), field_decl);
5350 CLASS_IVARS (class) = field_decl;
5356 is_ivar (decl_chain, ident)
5360 for ( ; decl_chain; decl_chain = TREE_CHAIN (decl_chain))
5361 if (DECL_NAME (decl_chain) == ident)
5366 /* True if the ivar is private and we are not in its implementation. */
5372 if (TREE_PRIVATE (decl)
5373 && ! is_ivar (CLASS_IVARS (implementation_template), DECL_NAME (decl)))
5375 error ("instance variable `%s' is declared private",
5376 IDENTIFIER_POINTER (DECL_NAME (decl)));
5383 /* we have an instance variable reference, check to see if it is public...*/
5386 is_public (expr, identifier)
5390 tree basetype = TREE_TYPE (expr);
5391 enum tree_code code = TREE_CODE (basetype);
5394 if (code == RECORD_TYPE)
5396 if (TREE_STATIC_TEMPLATE (basetype))
5398 if (!lookup_interface (TYPE_NAME (basetype)))
5400 error ("Cannot find interface declaration for `%s'",
5401 IDENTIFIER_POINTER (TYPE_NAME (basetype)));
5405 if ((decl = is_ivar (TYPE_FIELDS (basetype), identifier)))
5407 if (TREE_PUBLIC (decl))
5410 /* important difference between the Stepstone translator:
5411 all instance variables should be public within the context
5412 of the implementation. */
5413 if (implementation_context
5414 && (((TREE_CODE (implementation_context)
5415 == CLASS_IMPLEMENTATION_TYPE)
5416 || (TREE_CODE (implementation_context)
5417 == CATEGORY_IMPLEMENTATION_TYPE))
5418 && (CLASS_NAME (implementation_context)
5419 == TYPE_NAME (basetype))))
5420 return ! is_private (decl);
5422 error ("instance variable `%s' is declared %s",
5423 IDENTIFIER_POINTER (identifier),
5424 TREE_PRIVATE (decl) ? "private" : "protected");
5428 else if (implementation_context && (basetype == objc_object_reference))
5430 TREE_TYPE (expr) = uprivate_record;
5431 warning ("static access to object of type `id'");
5437 /* implement @defs (<classname>) within struct bodies. */
5440 get_class_ivars (interface)
5443 if (!doing_objc_thang)
5446 return build_ivar_chain (interface, 1);
5449 /* make sure all entries in "chain" are also in "list" */
5452 check_methods (chain, list, mtype)
5461 if (!lookup_method (list, chain))
5465 if (TREE_CODE (implementation_context) == CLASS_IMPLEMENTATION_TYPE)
5466 warning ("incomplete implementation of class `%s'",
5467 IDENTIFIER_POINTER (CLASS_NAME (implementation_context)));
5468 else if (TREE_CODE (implementation_context) == CATEGORY_IMPLEMENTATION_TYPE)
5469 warning ("incomplete implementation of category `%s'",
5470 IDENTIFIER_POINTER (CLASS_SUPER_NAME (implementation_context)));
5473 warning ("method definition for `%c%s' not found",
5474 mtype, IDENTIFIER_POINTER (METHOD_SEL_NAME (chain)));
5476 chain = TREE_CHAIN (chain);
5482 conforms_to_protocol (class, protocol)
5488 tree p = CLASS_PROTOCOL_LIST (class);
5489 while (p && TREE_VALUE (p) != TREE_VALUE (protocol))
5493 tree super = (CLASS_SUPER_NAME (class)
5494 ? lookup_interface (CLASS_SUPER_NAME (class))
5496 int tmp = super ? conforms_to_protocol (super, protocol) : 0;
5500 protocol = TREE_CHAIN (protocol);
5505 /* Make sure all methods in CHAIN are accessible as MTYPE methods in
5506 CONTEXT. This is one of two mechanisms to check protocol integrity
5510 check_methods_accessible (chain, context, mtype)
5512 tree context; /* implementation_context */
5517 tree base_context = context;
5521 context = base_context;
5525 list = CLASS_CLS_METHODS (context);
5527 list = CLASS_NST_METHODS (context);
5529 if (lookup_method (list, chain))
5532 else if (TREE_CODE (context) == CLASS_IMPLEMENTATION_TYPE
5533 || TREE_CODE (context) == CLASS_INTERFACE_TYPE)
5534 context = (CLASS_SUPER_NAME (context)
5535 ? lookup_interface (CLASS_SUPER_NAME (context))
5538 else if (TREE_CODE (context) == CATEGORY_IMPLEMENTATION_TYPE
5539 || TREE_CODE (context) == CATEGORY_INTERFACE_TYPE)
5540 context = (CLASS_NAME (context)
5541 ? lookup_interface (CLASS_NAME (context))
5547 if (context == NULL_TREE)
5551 if (TREE_CODE (implementation_context)
5552 == CLASS_IMPLEMENTATION_TYPE)
5553 warning ("incomplete implementation of class `%s'",
5555 (CLASS_NAME (implementation_context)));
5556 else if (TREE_CODE (implementation_context)
5557 == CATEGORY_IMPLEMENTATION_TYPE)
5558 warning ("incomplete implementation of category `%s'",
5560 (CLASS_SUPER_NAME (implementation_context)));
5563 warning ("method definition for `%c%s' not found",
5564 mtype, IDENTIFIER_POINTER (METHOD_SEL_NAME (chain)));
5567 chain = TREE_CHAIN (chain); /* next method... */
5573 check_protocols (proto_list, type, name)
5578 for ( ; proto_list; proto_list = TREE_CHAIN (proto_list))
5580 tree p = TREE_VALUE (proto_list);
5582 if (TREE_CODE (p) == PROTOCOL_INTERFACE_TYPE)
5586 /* Ensure that all protocols have bodies! */
5587 if (flag_warn_protocol) {
5588 f1 = check_methods (PROTOCOL_CLS_METHODS (p),
5589 CLASS_CLS_METHODS (implementation_context),
5591 f2 = check_methods (PROTOCOL_NST_METHODS (p),
5592 CLASS_NST_METHODS (implementation_context),
5595 f1 = check_methods_accessible (PROTOCOL_CLS_METHODS (p),
5596 implementation_context,
5598 f2 = check_methods_accessible (PROTOCOL_NST_METHODS (p),
5599 implementation_context,
5604 warning ("%s `%s' does not fully implement the `%s' protocol",
5605 type, name, IDENTIFIER_POINTER (PROTOCOL_NAME (p)));
5609 ; /* an identifier...if we could not find a protocol. */
5611 /* Check protocols recursively. */
5612 if (PROTOCOL_LIST (p))
5615 = lookup_interface (CLASS_SUPER_NAME (implementation_template));
5616 if (! conforms_to_protocol (super_class, PROTOCOL_LIST (p)))
5617 check_protocols (PROTOCOL_LIST (p), type, name);
5622 /* Make sure that the class CLASS_NAME is defined
5623 CODE says which kind of thing CLASS_NAME ought to be.
5624 It can be CLASS_INTERFACE_TYPE, CLASS_IMPLEMENTATION_TYPE,
5625 CATEGORY_INTERFACE_TYPE, or CATEGORY_IMPLEMENTATION_TYPE.
5627 If CODE is CLASS_INTERFACE_TYPE, we also do a push_obstacks_nochange
5628 whose matching pop is in continue_class. */
5631 start_class (code, class_name, super_name, protocol_list)
5632 enum tree_code code;
5639 if (code == CLASS_INTERFACE_TYPE)
5641 push_obstacks_nochange ();
5642 end_temporary_allocation ();
5645 if (!doing_objc_thang)
5648 class = make_node (code);
5649 TYPE_BINFO (class) = make_tree_vec (5);
5651 CLASS_NAME (class) = class_name;
5652 CLASS_SUPER_NAME (class) = super_name;
5653 CLASS_CLS_METHODS (class) = NULL_TREE;
5655 if (! is_class_name (class_name) && (decl = lookup_name (class_name)))
5657 error ("`%s' redeclared as different kind of symbol",
5658 IDENTIFIER_POINTER (class_name));
5659 error_with_decl (decl, "previous declaration of `%s'");
5662 if (code == CLASS_IMPLEMENTATION_TYPE)
5665 static tree implemented_classes = 0;
5666 tree chain = implemented_classes;
5667 for (chain = implemented_classes; chain; chain = TREE_CHAIN (chain))
5668 if (TREE_VALUE (chain) == class_name)
5670 error ("reimplementation of class `%s'",
5671 IDENTIFIER_POINTER (class_name));
5672 return error_mark_node;
5674 implemented_classes = perm_tree_cons (NULLT, class_name,
5675 implemented_classes);
5678 /* pre-build the following entities - for speed/convenience. */
5680 self_id = get_identifier ("self");
5682 ucmd_id = get_identifier ("_cmd");
5684 if (!objc_super_template)
5685 objc_super_template = build_super_template ();
5687 method_slot = 0; /* reset for multiple classes per file */
5689 implementation_context = class;
5691 /* lookup the interface for this implementation. */
5693 if (!(implementation_template = lookup_interface (class_name)))
5695 warning ("Cannot find interface declaration for `%s'",
5696 IDENTIFIER_POINTER (class_name));
5697 add_class (implementation_template = implementation_context);
5700 /* if a super class has been specified in the implementation,
5701 insure it conforms to the one specified in the interface */
5704 && (super_name != CLASS_SUPER_NAME (implementation_template)))
5706 tree previous_name = CLASS_SUPER_NAME (implementation_template);
5707 char *name = previous_name ? IDENTIFIER_POINTER (previous_name) : "";
5708 error ("conflicting super class name `%s'",
5709 IDENTIFIER_POINTER (super_name));
5710 error ("previous declaration of `%s'", name);
5712 else if (! super_name)
5714 CLASS_SUPER_NAME (implementation_context)
5715 = CLASS_SUPER_NAME (implementation_template);
5718 else if (code == CLASS_INTERFACE_TYPE)
5720 if (lookup_interface (class_name))
5721 warning ("duplicate interface declaration for class `%s'",
5722 IDENTIFIER_POINTER (class_name));
5727 CLASS_PROTOCOL_LIST (class)
5728 = lookup_and_install_protocols (protocol_list);
5730 else if (code == CATEGORY_INTERFACE_TYPE)
5732 tree class_category_is_assoc_with;
5734 /* for a category, class_name is really the name of the class that
5735 the following set of methods will be associated with...we must
5736 find the interface so that can derive the objects template */
5738 if (!(class_category_is_assoc_with = lookup_interface (class_name)))
5740 error ("Cannot find interface declaration for `%s'",
5741 IDENTIFIER_POINTER (class_name));
5745 add_category (class_category_is_assoc_with, class);
5748 CLASS_PROTOCOL_LIST (class)
5749 = lookup_and_install_protocols (protocol_list);
5751 else if (code == CATEGORY_IMPLEMENTATION_TYPE)
5753 /* pre-build the following entities - for speed/convenience. */
5755 self_id = get_identifier ("self");
5757 ucmd_id = get_identifier ("_cmd");
5759 if (!objc_super_template)
5760 objc_super_template = build_super_template ();
5762 method_slot = 0; /* reset for multiple classes per file */
5764 implementation_context = class;
5766 /* for a category, class_name is really the name of the class that
5767 the following set of methods will be associated with...we must
5768 find the interface so that can derive the objects template */
5770 if (!(implementation_template = lookup_interface (class_name)))
5772 error ("Cannot find interface declaration for `%s'",
5773 IDENTIFIER_POINTER (class_name));
5781 continue_class (class)
5784 if (TREE_CODE (class) == CLASS_IMPLEMENTATION_TYPE
5785 || TREE_CODE (class) == CATEGORY_IMPLEMENTATION_TYPE)
5787 struct imp_entry *imp_entry;
5790 /* check consistency of the instance variables. */
5792 if (CLASS_IVARS (class))
5793 check_ivars (implementation_template, class);
5795 /* code generation */
5797 ivar_context = build_private_template (implementation_template);
5799 if (!objc_class_template)
5800 build_class_template ();
5802 if (!(imp_entry = (struct imp_entry *) xmalloc (sizeof (struct imp_entry))))
5803 perror ("unable to allocate in objc-tree.c");
5805 imp_entry->next = imp_list;
5806 imp_entry->imp_context = class;
5807 imp_entry->imp_template = implementation_template;
5809 synth_forward_declarations ();
5810 imp_entry->class_decl = UOBJC_CLASS_decl;
5811 imp_entry->meta_decl = UOBJC_METACLASS_decl;
5813 /* append to front and increment count */
5814 imp_list = imp_entry;
5815 if (TREE_CODE (class) == CLASS_IMPLEMENTATION_TYPE)
5820 return ivar_context;
5822 else if (TREE_CODE (class) == CLASS_INTERFACE_TYPE)
5824 tree record = xref_tag (RECORD_TYPE, CLASS_NAME (class));
5826 if (!TYPE_FIELDS (record))
5828 finish_struct (record, build_ivar_chain (class, 0));
5829 CLASS_STATIC_TEMPLATE (class) = record;
5831 /* mark this record as a class template - for static typing */
5832 TREE_STATIC_TEMPLATE (record) = 1;
5837 return error_mark_node;
5840 /* This is called once we see the "@end" in an interface/implementation. */
5843 finish_class (class)
5846 if (TREE_CODE (class) == CLASS_IMPLEMENTATION_TYPE)
5848 /* all code generation is done in finish_objc */
5850 if (implementation_template != implementation_context)
5852 /* ensure that all method listed in the interface contain bodies! */
5853 check_methods (CLASS_CLS_METHODS (implementation_template),
5854 CLASS_CLS_METHODS (implementation_context), '+');
5855 check_methods (CLASS_NST_METHODS (implementation_template),
5856 CLASS_NST_METHODS (implementation_context), '-');
5858 if (CLASS_PROTOCOL_LIST (implementation_template))
5859 check_protocols (CLASS_PROTOCOL_LIST (implementation_template),
5861 IDENTIFIER_POINTER (CLASS_NAME (implementation_context)));
5864 else if (TREE_CODE (class) == CATEGORY_IMPLEMENTATION_TYPE)
5866 tree category = CLASS_CATEGORY_LIST (implementation_template);
5868 /* find the category interface from the class it is associated with */
5871 if (CLASS_SUPER_NAME (class) == CLASS_SUPER_NAME (category))
5873 category = CLASS_CATEGORY_LIST (category);
5878 /* ensure that all method listed in the interface contain bodies! */
5879 check_methods (CLASS_CLS_METHODS (category),
5880 CLASS_CLS_METHODS (implementation_context), '+');
5881 check_methods (CLASS_NST_METHODS (category),
5882 CLASS_NST_METHODS (implementation_context), '-');
5884 if (CLASS_PROTOCOL_LIST (category))
5885 check_protocols (CLASS_PROTOCOL_LIST (category),
5887 IDENTIFIER_POINTER (CLASS_SUPER_NAME (implementation_context)));
5890 else if (TREE_CODE (class) == CLASS_INTERFACE_TYPE)
5893 char *class_name = IDENTIFIER_POINTER (CLASS_NAME (class));
5894 char *string = (char *) alloca (strlen (class_name) + 3);
5896 /* extern struct objc_object *_<my_name>; */
5898 sprintf (string, "_%s", class_name);
5900 decl_specs = build_tree_list (NULLT, ridpointers[(int) RID_EXTERN]);
5901 decl_specs = tree_cons (NULLT, objc_object_reference, decl_specs);
5902 define_decl (build1 (INDIRECT_REF, NULLT, get_identifier (string)),
5908 add_protocol (protocol)
5911 /* put protocol on list in reverse order */
5912 TREE_CHAIN (protocol) = protocol_chain;
5913 protocol_chain = protocol;
5914 return protocol_chain;
5918 lookup_protocol (ident)
5923 for (chain = protocol_chain; chain; chain = TREE_CHAIN (chain))
5925 if (ident == PROTOCOL_NAME (chain))
5932 start_protocol (code, name, list)
5933 enum tree_code code;
5939 if (!doing_objc_thang)
5942 /* This is as good a place as any. Need to invoke push_tag_toplevel. */
5943 if (!objc_protocol_template)
5944 objc_protocol_template = build_protocol_template ();
5946 protocol = make_node (code);
5947 TYPE_BINFO (protocol) = make_tree_vec (2);
5949 PROTOCOL_NAME (protocol) = name;
5950 PROTOCOL_LIST (protocol) = list;
5952 lookup_and_install_protocols (list);
5954 if (lookup_protocol (name))
5955 warning ("duplicate declaration for protocol `%s'",
5956 IDENTIFIER_POINTER (name));
5958 add_protocol (protocol);
5960 PROTOCOL_FORWARD_DECL (protocol) = NULL_TREE;
5966 finish_protocol (protocol)
5972 /* "Encode" a data type into a string, which grows in util_obstack.
5973 ??? What is the FORMAT? Someone please document this! */
5976 encode_type_qualifiers (declspecs)
5981 for (spec = declspecs; spec; spec = TREE_CHAIN (spec))
5983 if (ridpointers[(int) RID_CONST] == TREE_VALUE (spec))
5984 obstack_1grow (&util_obstack, 'r');
5985 else if (ridpointers[(int) RID_IN] == TREE_VALUE (spec))
5986 obstack_1grow (&util_obstack, 'n');
5987 else if (ridpointers[(int) RID_INOUT] == TREE_VALUE (spec))
5988 obstack_1grow (&util_obstack, 'N');
5989 else if (ridpointers[(int) RID_OUT] == TREE_VALUE (spec))
5990 obstack_1grow (&util_obstack, 'o');
5991 else if (ridpointers[(int) RID_BYCOPY] == TREE_VALUE (spec))
5992 obstack_1grow (&util_obstack, 'O');
5993 else if (ridpointers[(int) RID_ONEWAY] == TREE_VALUE (spec))
5994 obstack_1grow (&util_obstack, 'V');
5998 /* Encode a pointer type. */
6001 encode_pointer (type, curtype, format)
6006 tree pointer_to = TREE_TYPE (type);
6008 if (TREE_CODE (pointer_to) == RECORD_TYPE)
6010 if (TYPE_NAME (pointer_to)
6011 && TREE_CODE (TYPE_NAME (pointer_to)) == IDENTIFIER_NODE)
6013 char *name = IDENTIFIER_POINTER (TYPE_NAME (pointer_to));
6015 if (strcmp (name, TAG_OBJECT) == 0) /* '@' */
6017 obstack_1grow (&util_obstack, '@');
6020 else if (TREE_STATIC_TEMPLATE (pointer_to))
6022 if (generating_instance_variables)
6024 obstack_1grow (&util_obstack, '@');
6025 obstack_1grow (&util_obstack, '"');
6026 obstack_grow (&util_obstack, name, strlen (name));
6027 obstack_1grow (&util_obstack, '"');
6032 obstack_1grow (&util_obstack, '@');
6036 else if (strcmp (name, TAG_CLASS) == 0) /* '#' */
6038 obstack_1grow (&util_obstack, '#');
6041 #ifndef OBJC_INT_SELECTORS
6042 else if (strcmp (name, TAG_SELECTOR) == 0) /* ':' */
6044 obstack_1grow (&util_obstack, ':');
6047 #endif /* OBJC_INT_SELECTORS */
6050 else if (TREE_CODE (pointer_to) == INTEGER_TYPE
6051 && TYPE_MODE (pointer_to) == QImode)
6053 obstack_1grow (&util_obstack, '*');
6057 /* we have a type that does not get special treatment... */
6059 /* NeXT extension */
6060 obstack_1grow (&util_obstack, '^');
6061 encode_type (pointer_to, curtype, format);
6065 encode_array (type, curtype, format)
6070 tree an_int_cst = TYPE_SIZE (type);
6071 tree array_of = TREE_TYPE (type);
6074 /* An incomplete array is treated like a pointer. */
6075 if (an_int_cst == NULL)
6077 /* split for obvious reasons. North-Keys 30 Mar 1991 */
6078 encode_pointer (type, curtype, format);
6082 sprintf (buffer, "[%d",
6083 (TREE_INT_CST_LOW (an_int_cst)
6084 / TREE_INT_CST_LOW (TYPE_SIZE (array_of))));
6085 obstack_grow (&util_obstack, buffer, strlen (buffer));
6086 encode_type (array_of, curtype, format);
6087 obstack_1grow (&util_obstack, ']');
6092 encode_aggregate (type, curtype, format)
6097 enum tree_code code = TREE_CODE (type);
6103 if (obstack_object_size (&util_obstack) > 0
6104 && *(obstack_next_free (&util_obstack) - 1) == '^')
6106 tree name = TYPE_NAME (type);
6108 /* we have a reference - this is a NeXT extension */
6110 if (obstack_object_size (&util_obstack) - curtype == 1
6111 && format == OBJC_ENCODE_INLINE_DEFS)
6113 /* output format of struct for first level only! */
6115 tree fields = TYPE_FIELDS (type);
6117 if (name && TREE_CODE (name) == IDENTIFIER_NODE)
6119 obstack_1grow (&util_obstack, '{');
6120 obstack_grow (&util_obstack,
6121 IDENTIFIER_POINTER (name),
6122 strlen (IDENTIFIER_POINTER (name)));
6123 obstack_1grow (&util_obstack, '=');
6126 obstack_grow (&util_obstack, "{?=", 3);
6128 for ( ; fields; fields = TREE_CHAIN (fields))
6129 encode_field_decl (fields, curtype, format);
6130 obstack_1grow (&util_obstack, '}');
6132 else if (name && TREE_CODE (name) == IDENTIFIER_NODE)
6134 obstack_1grow (&util_obstack, '{');
6135 obstack_grow (&util_obstack,
6136 IDENTIFIER_POINTER (name),
6137 strlen (IDENTIFIER_POINTER (name)));
6138 obstack_1grow (&util_obstack, '}');
6140 else /* we have an untagged structure or a typedef */
6141 obstack_grow (&util_obstack, "{?}", 3);
6145 tree name = TYPE_NAME (type);
6146 tree fields = TYPE_FIELDS (type);
6148 if (format == OBJC_ENCODE_INLINE_DEFS
6149 || generating_instance_variables)
6151 obstack_1grow (&util_obstack, '{');
6152 if (name && TREE_CODE (name) == IDENTIFIER_NODE)
6153 obstack_grow (&util_obstack,
6154 IDENTIFIER_POINTER (name),
6155 strlen (IDENTIFIER_POINTER (name)));
6157 obstack_1grow (&util_obstack, '?');
6159 obstack_1grow (&util_obstack, '=');
6161 for (; fields; fields = TREE_CHAIN (fields))
6163 if (generating_instance_variables)
6165 tree fname = DECL_NAME (fields);
6167 obstack_1grow (&util_obstack, '"');
6168 if (fname && TREE_CODE (fname) == IDENTIFIER_NODE)
6170 obstack_grow (&util_obstack,
6171 IDENTIFIER_POINTER (fname),
6172 strlen (IDENTIFIER_POINTER (fname)));
6174 obstack_1grow (&util_obstack, '"');
6176 encode_field_decl (fields, curtype, format);
6178 obstack_1grow (&util_obstack, '}');
6182 obstack_1grow (&util_obstack, '{');
6183 if (name && TREE_CODE (name) == IDENTIFIER_NODE)
6184 obstack_grow (&util_obstack,
6185 IDENTIFIER_POINTER (name),
6186 strlen (IDENTIFIER_POINTER (name)));
6187 else /* we have an untagged structure or a typedef */
6188 obstack_1grow (&util_obstack, '?');
6189 obstack_1grow (&util_obstack, '}');
6196 if (*obstack_next_free (&util_obstack) == '^'
6197 || format != OBJC_ENCODE_INLINE_DEFS)
6199 /* we have a reference - this is a NeXT extension--
6200 or we don't want the details. */
6201 if (TYPE_NAME (type)
6202 && TREE_CODE (TYPE_NAME (type)) == IDENTIFIER_NODE)
6204 obstack_1grow (&util_obstack, '(');
6205 obstack_grow (&util_obstack,
6206 IDENTIFIER_POINTER (TYPE_NAME (type)),
6207 strlen (IDENTIFIER_POINTER (TYPE_NAME (type))));
6208 obstack_1grow (&util_obstack, ')');
6210 else /* we have an untagged structure or a typedef */
6211 obstack_grow (&util_obstack, "(?)", 3);
6215 tree fields = TYPE_FIELDS (type);
6216 obstack_1grow (&util_obstack, '(');
6217 for ( ; fields; fields = TREE_CHAIN (fields))
6218 encode_field_decl (fields, curtype, format);
6219 obstack_1grow (&util_obstack, ')');
6225 obstack_1grow (&util_obstack, 'i');
6230 /* Support bitfields, the current version of Objective-C does not support
6231 them. the string will consist of one or more "b:n"'s where n is an
6232 integer describing the width of the bitfield. Currently, classes in
6233 the kit implement a method "-(char *)describeBitfieldStruct:" that
6234 simulates this...if they do not implement this method, the archiver
6235 assumes the bitfield is 16 bits wide (padded if necessary) and packed
6236 according to the GNU compiler. After looking at the "kit", it appears
6237 that all classes currently rely on this default behavior, rather than
6238 hand generating this string (which is tedious). */
6241 encode_bitfield (width, format)
6246 sprintf (buffer, "b%d", width);
6247 obstack_grow (&util_obstack, buffer, strlen (buffer));
6250 /* FORMAT will be OBJC_ENCODE_INLINE_DEFS or OBJC_ENCODE_DONT_INLINE_DEFS. */
6253 encode_type (type, curtype, format)
6258 enum tree_code code = TREE_CODE (type);
6260 if (code == INTEGER_TYPE)
6262 if (TREE_INT_CST_LOW (TYPE_MIN_VALUE (type)) == 0
6263 && TREE_INT_CST_HIGH (TYPE_MIN_VALUE (type)) == 0)
6265 /* unsigned integer types */
6267 if (TYPE_MODE (type) == QImode) /* 'C' */
6268 obstack_1grow (&util_obstack, 'C');
6269 else if (TYPE_MODE (type) == HImode) /* 'S' */
6270 obstack_1grow (&util_obstack, 'S');
6271 else if (TYPE_MODE (type) == SImode)
6273 if (type == long_unsigned_type_node)
6274 obstack_1grow (&util_obstack, 'L'); /* 'L' */
6276 obstack_1grow (&util_obstack, 'I'); /* 'I' */
6278 else if (TYPE_MODE (type) == DImode) /* 'Q' */
6279 obstack_1grow (&util_obstack, 'Q');
6281 else /* signed integer types */
6283 if (TYPE_MODE (type) == QImode) /* 'c' */
6284 obstack_1grow (&util_obstack, 'c');
6285 else if (TYPE_MODE (type) == HImode) /* 's' */
6286 obstack_1grow (&util_obstack, 's');
6287 else if (TYPE_MODE (type) == SImode) /* 'i' */
6289 if (type == long_integer_type_node)
6290 obstack_1grow (&util_obstack, 'l'); /* 'l' */
6292 obstack_1grow (&util_obstack, 'i'); /* 'i' */
6294 else if (TYPE_MODE (type) == DImode) /* 'q' */
6295 obstack_1grow (&util_obstack, 'q');
6298 else if (code == REAL_TYPE)
6300 /* floating point types */
6302 if (TYPE_MODE (type) == SFmode) /* 'f' */
6303 obstack_1grow (&util_obstack, 'f');
6304 else if (TYPE_MODE (type) == DFmode
6305 || TYPE_MODE (type) == TFmode) /* 'd' */
6306 obstack_1grow (&util_obstack, 'd');
6309 else if (code == VOID_TYPE) /* 'v' */
6310 obstack_1grow (&util_obstack, 'v');
6312 else if (code == ARRAY_TYPE)
6313 encode_array (type, curtype, format);
6315 else if (code == POINTER_TYPE)
6316 encode_pointer (type, curtype, format);
6318 else if (code == RECORD_TYPE || code == UNION_TYPE || code == ENUMERAL_TYPE)
6319 encode_aggregate (type, curtype, format);
6321 else if (code == FUNCTION_TYPE) /* '?' */
6322 obstack_1grow (&util_obstack, '?');
6326 encode_field_decl (field_decl, curtype, format)
6333 /* If this field is obviously a bitfield, or is a bitfield that has been
6334 clobbered to look like a ordinary integer mode, go ahead and generate
6335 the bitfield typing information. */
6336 type = TREE_TYPE (field_decl);
6337 if (DECL_BIT_FIELD (field_decl))
6338 encode_bitfield (DECL_FIELD_SIZE (field_decl), format);
6339 else if (TREE_CODE (TYPE_SIZE (type)) == INTEGER_CST
6340 && DECL_FIELD_SIZE (field_decl)
6341 && TYPE_MODE (type) > DECL_MODE (field_decl))
6342 encode_bitfield (DECL_FIELD_SIZE (field_decl), format);
6344 encode_type (TREE_TYPE (field_decl), curtype, format);
6348 expr_last (complex_expr)
6354 while ((next = TREE_OPERAND (complex_expr, 0)))
6355 complex_expr = next;
6356 return complex_expr;
6359 /* The selector of the current method,
6360 or NULL if we aren't compiling a method. */
6363 maybe_objc_method_name (decl)
6367 return METHOD_SEL_NAME (method_context);
6372 /* Transform a method definition into a function definition as follows:
6373 - synthesize the first two arguments, "self" and "_cmd". */
6376 start_method_def (method)
6381 /* Required to implement _msgSuper. */
6382 method_context = method;
6383 UOBJC_SUPER_decl = NULLT;
6385 pushlevel (0); /* Must be called BEFORE start_function. */
6387 /* Generate prototype declarations for arguments..."new-style". */
6389 if (TREE_CODE (method_context) == INSTANCE_METHOD_DECL)
6390 decl_specs = build_tree_list (NULLT, uprivate_record);
6392 /* really a `struct objc_class *'...however we allow people to
6393 assign to self...which changes its type midstream. */
6394 decl_specs = build_tree_list (NULLT, objc_object_reference);
6396 push_parm_decl (build_tree_list (decl_specs,
6397 build1 (INDIRECT_REF, NULLT, self_id)));
6399 #ifdef OBJC_INT_SELECTORS
6400 decl_specs = build_tree_list (NULLT, ridpointers[(int) RID_UNSIGNED]);
6401 decl_specs = tree_cons (NULLT, ridpointers[(int) RID_INT], decl_specs);
6402 push_parm_decl (build_tree_list (decl_specs, ucmd_id));
6403 #else /* not OBJC_INT_SELECTORS */
6404 decl_specs = build_tree_list (NULLT,
6405 xref_tag (RECORD_TYPE,
6406 get_identifier (TAG_SELECTOR)));
6407 push_parm_decl (build_tree_list (decl_specs,
6408 build1 (INDIRECT_REF, NULLT, ucmd_id)));
6409 #endif /* not OBJC_INT_SELECTORS */
6411 /* generate argument declarations if a keyword_decl */
6412 if (METHOD_SEL_ARGS (method))
6414 tree arglist = METHOD_SEL_ARGS (method);
6417 tree arg_spec = TREE_PURPOSE (TREE_TYPE (arglist));
6418 tree arg_decl = TREE_VALUE (TREE_TYPE (arglist));
6422 tree last_expr = expr_last (arg_decl);
6424 /* unite the abstract decl with its name */
6425 TREE_OPERAND (last_expr, 0) = KEYWORD_ARG_NAME (arglist);
6426 push_parm_decl (build_tree_list (arg_spec, arg_decl));
6427 /* unhook...restore the abstract declarator */
6428 TREE_OPERAND (last_expr, 0) = NULLT;
6431 push_parm_decl (build_tree_list (arg_spec,
6432 KEYWORD_ARG_NAME (arglist)));
6434 arglist = TREE_CHAIN (arglist);
6439 if (METHOD_ADD_ARGS (method) > (tree)1)
6441 /* we have a variable length selector - in "prototype" format */
6442 tree akey = TREE_PURPOSE (METHOD_ADD_ARGS (method));
6445 /* This must be done prior to calling pushdecl. pushdecl is
6446 going to change our chain on us. */
6447 tree nextkey = TREE_CHAIN (akey);
6455 warn_with_method (message, mtype, method)
6460 if (count_error (1) == 0)
6463 report_error_function (DECL_SOURCE_FILE (method));
6465 fprintf (stderr, "%s:%d: warning: ",
6466 DECL_SOURCE_FILE (method), DECL_SOURCE_LINE (method));
6467 bzero (errbuf, BUFSIZE);
6468 fprintf (stderr, "%s `%c%s'\n",
6469 message, mtype, gen_method_decl (method, errbuf));
6472 /* return 1 if `method' is consistent with `proto' */
6475 comp_method_with_proto (method, proto)
6478 static tree function_type = 0;
6480 /* create a function_type node once */
6483 struct obstack *ambient_obstack = current_obstack;
6485 current_obstack = &permanent_obstack;
6486 function_type = make_node (FUNCTION_TYPE);
6487 current_obstack = ambient_obstack;
6490 /* Install argument types - normally set by build_function_type. */
6491 TYPE_ARG_TYPES (function_type) = get_arg_type_list (proto, METHOD_DEF, 0);
6493 /* install return type */
6494 TREE_TYPE (function_type) = groktypename (TREE_TYPE (proto));
6496 return comptypes (TREE_TYPE (METHOD_DEFINITION (method)), function_type);
6499 /* return 1 if `proto1' is consistent with `proto2' */
6502 comp_proto_with_proto (proto1, proto2)
6503 tree proto1, proto2;
6505 static tree function_type1 = 0, function_type2 = 0;
6507 /* create a couple function_type node's once */
6508 if (!function_type1)
6510 struct obstack *ambient_obstack = current_obstack;
6512 current_obstack = &permanent_obstack;
6513 function_type1 = make_node (FUNCTION_TYPE);
6514 function_type2 = make_node (FUNCTION_TYPE);
6515 current_obstack = ambient_obstack;
6518 /* Install argument types - normally set by build_function_type. */
6519 TYPE_ARG_TYPES (function_type1) = get_arg_type_list (proto1, METHOD_REF, 0);
6520 TYPE_ARG_TYPES (function_type2) = get_arg_type_list (proto2, METHOD_REF, 0);
6522 /* install return type */
6523 TREE_TYPE (function_type1) = groktypename (TREE_TYPE (proto1));
6524 TREE_TYPE (function_type2) = groktypename (TREE_TYPE (proto2));
6526 return comptypes (function_type1, function_type2);
6529 /* - generate an identifier for the function. the format is "_n_cls",
6530 where 1 <= n <= nMethods, and cls is the name the implementation we
6532 - install the return type from the method declaration.
6533 - if we have a prototype, check for type consistency. */
6536 really_start_method (method, parmlist)
6537 tree method, parmlist;
6539 tree sc_spec, ret_spec, ret_decl, decl_specs;
6540 tree method_decl, method_id;
6541 char *buf, *sel_name, *class_name, *cat_name;
6543 /* synth the storage class & assemble the return type */
6544 sc_spec = tree_cons (NULLT, ridpointers[(int) RID_STATIC], NULLT);
6545 ret_spec = TREE_PURPOSE (TREE_TYPE (method));
6546 decl_specs = chainon (sc_spec, ret_spec);
6548 sel_name = IDENTIFIER_POINTER (METHOD_SEL_NAME (method));
6549 class_name = IDENTIFIER_POINTER (CLASS_NAME (implementation_context));
6550 cat_name = ((TREE_CODE (implementation_context)
6551 == CLASS_IMPLEMENTATION_TYPE)
6553 : IDENTIFIER_POINTER (CLASS_SUPER_NAME (implementation_context)));
6555 /* Make sure this is big enough for any plausible method label. */
6556 buf = (char *) alloca (50 + strlen (sel_name) + strlen (class_name)
6557 + (cat_name ? strlen (cat_name) : 0));
6559 OBJC_GEN_METHOD_LABEL (buf, TREE_CODE (method) == INSTANCE_METHOD_DECL,
6560 class_name, cat_name, sel_name, method_slot);
6562 method_id = get_identifier (buf);
6564 method_decl = build_nt (CALL_EXPR, method_id, parmlist, NULLT);
6566 /* check the declarator portion of the return type for the method */
6567 if ((ret_decl = TREE_VALUE (TREE_TYPE (method))))
6569 /* unite the complex decl (specified in the abstract decl) with the
6570 function decl just synthesized..(int *), (int (*)()), (int (*)[]). */
6571 tree save_expr = expr_last (ret_decl);
6573 TREE_OPERAND (save_expr, 0) = method_decl;
6574 method_decl = ret_decl;
6575 /* fool the parser into thinking it is starting a function */
6576 start_function (decl_specs, method_decl, 0);
6577 /* unhook...this has the effect of restoring the abstract declarator */
6578 TREE_OPERAND (save_expr, 0) = NULLT;
6582 TREE_VALUE (TREE_TYPE (method)) = method_decl;
6583 /* fool the parser into thinking it is starting a function */
6584 start_function (decl_specs, method_decl, 0);
6585 /* unhook...this has the effect of restoring the abstract declarator */
6586 TREE_VALUE (TREE_TYPE (method)) = NULLT;
6589 METHOD_DEFINITION (method) = current_function_decl;
6591 /* Check consistency...start_function, pushdecl, duplicate_decls. */
6593 if (implementation_template != implementation_context)
6597 if (TREE_CODE (method) == INSTANCE_METHOD_DECL)
6598 proto = lookup_instance_method_static (implementation_template,
6599 METHOD_SEL_NAME (method));
6601 proto = lookup_class_method_static (implementation_template,
6602 METHOD_SEL_NAME (method));
6604 if (proto && ! comp_method_with_proto (method, proto))
6606 char type = (TREE_CODE (method) == INSTANCE_METHOD_DECL ? '-' : '+');
6608 warn_with_method ("conflicting types for", type, method);
6609 warn_with_method ("previous declaration of", type, proto);
6614 /* The following routine is always called...this "architecture" is to
6615 accommodate "old-style" variable length selectors.
6617 - a:a b:b // prototype ; id c; id d; // old-style. */
6620 continue_method_def ()
6624 if (METHOD_ADD_ARGS (method_context) == (tree)1)
6625 /* We have a `, ...' immediately following the selector. */
6626 parmlist = get_parm_info (0);
6628 parmlist = get_parm_info (1); /* place a `void_at_end' */
6630 /* Set self_decl from the first argument...this global is used by
6631 build_ivar_reference calling build_indirect_ref. */
6632 self_decl = TREE_PURPOSE (parmlist);
6634 poplevel (0, 0, 0); /* must be called BEFORE start_function. */
6636 really_start_method (method_context, parmlist);
6638 store_parm_decls (); /* must be called AFTER start_function. */
6641 /* Called by the parser, from the `pushlevel' production. */
6646 if (!UOBJC_SUPER_decl)
6648 UOBJC_SUPER_decl = start_decl (get_identifier (UTAG_SUPER),
6649 build_tree_list (NULLT,
6650 objc_super_template),
6653 finish_decl (UOBJC_SUPER_decl, NULLT, NULLT);
6655 /* this prevents `unused variable' warnings when compiling with -Wall. */
6656 DECL_IN_SYSTEM_HEADER (UOBJC_SUPER_decl) = 1;
6660 /* _n_Method (id self, SEL sel, ...)
6662 struct objc_super _S;
6663 _msgSuper ((_S.self = self, _S.class = _cls, &_S), ...);
6667 get_super_receiver ()
6671 tree super_expr, super_expr_list;
6673 /* set receiver to self */
6674 super_expr = build_component_ref (UOBJC_SUPER_decl, self_id);
6675 super_expr = build_modify_expr (super_expr, NOP_EXPR, self_decl);
6676 super_expr_list = build_tree_list (NULLT, super_expr);
6678 /* set class to begin searching */
6679 super_expr = build_component_ref (UOBJC_SUPER_decl,
6680 get_identifier ("class"));
6682 if (TREE_CODE (implementation_context) == CLASS_IMPLEMENTATION_TYPE)
6684 /* [_cls, __cls]Super are "pre-built" in
6685 synth_forward_declarations. */
6687 super_expr = build_modify_expr (super_expr, NOP_EXPR,
6688 ((TREE_CODE (method_context)
6689 == INSTANCE_METHOD_DECL)
6691 : uucls_super_ref));
6693 else /* we have a category... */
6695 tree super_name = CLASS_SUPER_NAME (implementation_template);
6698 if (!super_name) /* Barf if super used in a category of Object. */
6700 error ("no super class declared in interface for `%s'",
6701 IDENTIFIER_POINTER (CLASS_NAME (implementation_template)));
6702 return error_mark_node;
6705 if (flag_next_runtime)
6707 super_class = get_class_reference (super_name);
6708 if (TREE_CODE (method_context) == CLASS_METHOD_DECL)
6710 = build_component_ref (build_indirect_ref (super_class, "->"),
6711 get_identifier ("isa"));
6715 add_class_reference (super_name);
6716 super_class = (TREE_CODE (method_context) == INSTANCE_METHOD_DECL
6717 ? objc_get_class_decl : objc_get_meta_class_decl);
6718 assemble_external (super_class);
6720 = build_function_call
6722 build_tree_list (NULLT,
6723 my_build_string (IDENTIFIER_LENGTH (super_name) + 1,
6724 IDENTIFIER_POINTER (super_name))));
6728 TREE_TYPE (super_class) = TREE_TYPE (ucls_super_ref);
6729 super_expr = build_modify_expr (super_expr, NOP_EXPR, super_class);
6731 chainon (super_expr_list, build_tree_list (NULL_TREE, super_expr));
6733 super_expr = build_unary_op (ADDR_EXPR, UOBJC_SUPER_decl, 0);
6734 chainon (super_expr_list, build_tree_list (NULL_TREE, super_expr));
6736 return build_compound_expr (super_expr_list);
6740 error ("[super ...] must appear in a method context");
6741 return error_mark_node;
6746 encode_method_def (func_decl)
6751 int max_parm_end = 0;
6756 encode_type (TREE_TYPE (TREE_TYPE (func_decl)),
6757 obstack_object_size (&util_obstack),
6758 OBJC_ENCODE_INLINE_DEFS);
6760 for (parms = DECL_ARGUMENTS (func_decl); parms;
6761 parms = TREE_CHAIN (parms))
6763 int parm_end = (forwarding_offset (parms)
6764 + (TREE_INT_CST_LOW (TYPE_SIZE (TREE_TYPE (parms)))
6767 if (!offset_is_register && parm_end > max_parm_end)
6768 max_parm_end = parm_end;
6771 stack_size = max_parm_end - OBJC_FORWARDING_MIN_OFFSET;
6773 sprintf (buffer, "%d", stack_size);
6774 obstack_grow (&util_obstack, buffer, strlen (buffer));
6776 /* argument types */
6777 for (parms = DECL_ARGUMENTS (func_decl); parms;
6778 parms = TREE_CHAIN (parms))
6781 encode_type (TREE_TYPE (parms),
6782 obstack_object_size (&util_obstack),
6783 OBJC_ENCODE_INLINE_DEFS);
6785 /* compute offset */
6786 sprintf (buffer, "%d", forwarding_offset (parms));
6788 /* indicate register */
6789 if (offset_is_register)
6790 obstack_1grow (&util_obstack, '+');
6792 obstack_grow (&util_obstack, buffer, strlen (buffer));
6795 obstack_1grow (&util_obstack, 0); /* null terminate string */
6796 result = get_identifier (obstack_finish (&util_obstack));
6797 obstack_free (&util_obstack, util_firstobj);
6802 finish_method_def ()
6804 METHOD_ENCODING (method_context) = encode_method_def (current_function_decl);
6806 finish_function (0);
6808 /* this must be done AFTER finish_function, since the optimizer may
6809 find "may be used before set" errors. */
6810 method_context = NULLT; /* required to implement _msgSuper. */
6814 lang_report_error_function (decl)
6819 fprintf (stderr, "In method `%s'\n",
6820 IDENTIFIER_POINTER (METHOD_SEL_NAME (method_context)));
6828 is_complex_decl (type)
6831 return (TREE_CODE (type) == ARRAY_TYPE
6832 || TREE_CODE (type) == FUNCTION_TYPE
6833 || (TREE_CODE (type) == POINTER_TYPE && ! IS_ID (type)));
6837 /* Code to convert a decl node into text for a declaration in C. */
6839 static char tmpbuf[256];
6842 adorn_decl (decl, str)
6846 enum tree_code code = TREE_CODE (decl);
6848 if (code == ARRAY_REF)
6850 tree an_int_cst = TREE_OPERAND (decl, 1);
6852 if (an_int_cst && TREE_CODE (an_int_cst) == INTEGER_CST)
6853 sprintf (str + strlen (str), "[%d]", TREE_INT_CST_LOW (an_int_cst));
6857 else if (code == ARRAY_TYPE)
6859 tree an_int_cst = TYPE_SIZE (decl);
6860 tree array_of = TREE_TYPE (decl);
6862 if (an_int_cst && TREE_CODE (an_int_cst) == INTEGER_TYPE)
6863 sprintf (str + strlen (str), "[%d]",
6864 (TREE_INT_CST_LOW (an_int_cst)
6865 / TREE_INT_CST_LOW (TYPE_SIZE (array_of))));
6869 else if (code == CALL_EXPR)
6871 tree chain = TREE_PURPOSE (TREE_OPERAND (decl, 1));
6876 gen_declaration (chain, str);
6877 chain = TREE_CHAIN (chain);
6883 else if (code == FUNCTION_TYPE)
6885 tree chain = TYPE_ARG_TYPES (decl); /* a list of types */
6888 while (chain && TREE_VALUE (chain) != void_type_node)
6890 gen_declaration (TREE_VALUE (chain), str);
6891 chain = TREE_CHAIN (chain);
6892 if (chain && TREE_VALUE (chain) != void_type_node)
6897 else if (code == INDIRECT_REF)
6899 strcpy (tmpbuf, "*");
6900 if (TREE_TYPE (decl) && TREE_CODE (TREE_TYPE (decl)) == TREE_LIST)
6904 for (chain = nreverse (copy_list (TREE_TYPE (decl)));
6906 chain = TREE_CHAIN (chain))
6908 if (TREE_CODE (TREE_VALUE (chain)) == IDENTIFIER_NODE)
6910 strcat (tmpbuf, " ");
6911 strcat (tmpbuf, IDENTIFIER_POINTER (TREE_VALUE (chain)));
6915 strcat (tmpbuf, " ");
6917 strcat (tmpbuf, str);
6918 strcpy (str, tmpbuf);
6920 else if (code == POINTER_TYPE)
6922 strcpy (tmpbuf, "*");
6923 if (TREE_READONLY (decl) || TYPE_VOLATILE (decl))
6925 if (TREE_READONLY (decl))
6926 strcat (tmpbuf, " const");
6927 if (TYPE_VOLATILE (decl))
6928 strcat (tmpbuf, " volatile");
6930 strcat (tmpbuf, " ");
6932 strcat (tmpbuf, str);
6933 strcpy (str, tmpbuf);
6938 gen_declarator (decl, buf, name)
6945 enum tree_code code = TREE_CODE (decl);
6955 op = TREE_OPERAND (decl, 0);
6957 /* we have a pointer to a function or array...(*)(), (*)[] */
6958 if ((code == ARRAY_REF || code == CALL_EXPR)
6959 && op && TREE_CODE (op) == INDIRECT_REF)
6962 str = gen_declarator (op, buf, name);
6966 strcpy (tmpbuf, "(");
6967 strcat (tmpbuf, str);
6968 strcat (tmpbuf, ")");
6969 strcpy (str, tmpbuf);
6972 adorn_decl (decl, str);
6981 /* this clause is done iteratively...rather than recursively */
6984 op = (is_complex_decl (TREE_TYPE (decl))
6985 ? TREE_TYPE (decl) : NULLT);
6987 adorn_decl (decl, str);
6989 /* we have a pointer to a function or array...(*)(), (*)[] */
6990 if (code == POINTER_TYPE
6991 && op && (TREE_CODE (op) == FUNCTION_TYPE
6992 || TREE_CODE (op) == ARRAY_TYPE))
6994 strcpy (tmpbuf, "(");
6995 strcat (tmpbuf, str);
6996 strcat (tmpbuf, ")");
6997 strcpy (str, tmpbuf);
7000 decl = (is_complex_decl (TREE_TYPE (decl))
7001 ? TREE_TYPE (decl) : NULLT);
7003 while (decl && (code = TREE_CODE (decl)));
7007 case IDENTIFIER_NODE:
7008 /* will only happen if we are processing a "raw" expr-decl. */
7009 strcpy (buf, IDENTIFIER_POINTER (decl));
7015 else /* we have an abstract declarator or a _DECL node */
7023 gen_declspecs (declspecs, buf, raw)
7032 for (chain = nreverse (copy_list (declspecs));
7033 chain; chain = TREE_CHAIN (chain))
7035 tree aspec = TREE_VALUE (chain);
7037 if (TREE_CODE (aspec) == IDENTIFIER_NODE)
7038 strcat (buf, IDENTIFIER_POINTER (aspec));
7039 else if (TREE_CODE (aspec) == RECORD_TYPE)
7041 if (TYPE_NAME (aspec))
7043 tree protocol_list = TYPE_PROTOCOL_LIST (aspec);
7045 if (! TREE_STATIC_TEMPLATE (aspec))
7046 strcat (buf, "struct ");
7047 strcat (buf, IDENTIFIER_POINTER (TYPE_NAME (aspec)));
7052 tree chain = protocol_list;
7057 strcat (buf, IDENTIFIER_POINTER (PROTOCOL_NAME (TREE_VALUE (chain))));
7058 chain = TREE_CHAIN (chain);
7066 strcat (buf, "untagged struct");
7068 else if (TREE_CODE (aspec) == UNION_TYPE)
7070 if (TYPE_NAME (aspec))
7072 if (! TREE_STATIC_TEMPLATE (aspec))
7073 strcat (buf, "union ");
7074 strcat (buf, IDENTIFIER_POINTER (TYPE_NAME (aspec)));
7077 strcat (buf, "untagged union");
7079 else if (TREE_CODE (aspec) == ENUMERAL_TYPE)
7081 if (TYPE_NAME (aspec))
7083 if (! TREE_STATIC_TEMPLATE (aspec))
7084 strcat (buf, "enum ");
7085 strcat (buf, IDENTIFIER_POINTER (TYPE_NAME (aspec)));
7088 strcat (buf, "untagged enum");
7090 else if (TREE_CODE (aspec) == TYPE_DECL && DECL_NAME (aspec))
7092 strcat (buf, IDENTIFIER_POINTER (DECL_NAME (aspec)));
7095 else if (IS_ID (aspec))
7097 tree protocol_list = TYPE_PROTOCOL_LIST (aspec);
7102 tree chain = protocol_list;
7107 strcat (buf, IDENTIFIER_POINTER (PROTOCOL_NAME (TREE_VALUE (chain))));
7108 chain = TREE_CHAIN (chain);
7115 if (TREE_CHAIN (chain))
7121 /* type qualifiers */
7123 if (TREE_READONLY (declspecs))
7124 strcat (buf, "const ");
7125 if (TYPE_VOLATILE (declspecs))
7126 strcat (buf, "volatile ");
7128 switch (TREE_CODE (declspecs))
7130 /* type specifiers */
7132 case INTEGER_TYPE: /* signed integer types */
7133 declspecs = TYPE_MAIN_VARIANT (declspecs);
7135 if (declspecs == short_integer_type_node) /* 's' */
7136 strcat (buf, "short int ");
7137 else if (declspecs == integer_type_node) /* 'i' */
7138 strcat (buf, "int ");
7139 else if (declspecs == long_integer_type_node) /* 'l' */
7140 strcat (buf, "long int ");
7141 else if (declspecs == long_long_integer_type_node) /* 'l' */
7142 strcat (buf, "long long int ");
7143 else if (declspecs == signed_char_type_node /* 'c' */
7144 || declspecs == char_type_node)
7145 strcat (buf, "char ");
7147 /* unsigned integer types */
7149 else if (declspecs == short_unsigned_type_node) /* 'S' */
7150 strcat (buf, "unsigned short ");
7151 else if (declspecs == unsigned_type_node) /* 'I' */
7152 strcat (buf, "unsigned int ");
7153 else if (declspecs == long_unsigned_type_node) /* 'L' */
7154 strcat (buf, "unsigned long ");
7155 else if (declspecs == long_long_unsigned_type_node) /* 'L' */
7156 strcat (buf, "unsigned long long ");
7157 else if (declspecs == unsigned_char_type_node) /* 'C' */
7158 strcat (buf, "unsigned char ");
7161 case REAL_TYPE: /* floating point types */
7162 declspecs = TYPE_MAIN_VARIANT (declspecs);
7164 if (declspecs == float_type_node) /* 'f' */
7165 strcat (buf, "float ");
7166 else if (declspecs == double_type_node) /* 'd' */
7167 strcat (buf, "double ");
7168 else if (declspecs == long_double_type_node) /* 'd' */
7169 strcat (buf, "long double ");
7173 if (TYPE_NAME (declspecs)
7174 && TREE_CODE (TYPE_NAME (declspecs)) == IDENTIFIER_NODE)
7176 tree protocol_list = TYPE_PROTOCOL_LIST (declspecs);
7178 if (! TREE_STATIC_TEMPLATE (declspecs))
7179 strcat (buf, "struct ");
7180 strcat (buf, IDENTIFIER_POINTER (TYPE_NAME (declspecs)));
7184 tree chain = protocol_list;
7189 strcat (buf, IDENTIFIER_POINTER (PROTOCOL_NAME (TREE_VALUE (chain))));
7190 chain = TREE_CHAIN (chain);
7198 strcat (buf, "untagged struct");
7204 if (TYPE_NAME (declspecs)
7205 && TREE_CODE (TYPE_NAME (declspecs)) == IDENTIFIER_NODE)
7207 strcat (buf, "union ");
7208 strcat (buf, IDENTIFIER_POINTER (TYPE_NAME (declspecs)));
7212 strcat (buf, "untagged union ");
7216 if (TYPE_NAME (declspecs)
7217 && TREE_CODE (TYPE_NAME (declspecs)) == IDENTIFIER_NODE)
7219 strcat (buf, "enum ");
7220 strcat (buf, IDENTIFIER_POINTER (TYPE_NAME (declspecs)));
7224 strcat (buf, "untagged enum ");
7228 strcat (buf, "void ");
7234 tree protocol_list = TYPE_PROTOCOL_LIST (declspecs);
7239 tree chain = protocol_list;
7244 strcat (buf, IDENTIFIER_POINTER (PROTOCOL_NAME (TREE_VALUE (chain))));
7245 chain = TREE_CHAIN (chain);
7257 gen_declaration (atype_or_adecl, buf)
7258 tree atype_or_adecl;
7263 if (TREE_CODE (atype_or_adecl) == TREE_LIST)
7265 tree declspecs; /* "identifier_node", "record_type" */
7266 tree declarator; /* "array_ref", "indirect_ref", "call_expr"... */
7268 /* we have a "raw", abstract declarator (typename) */
7269 declarator = TREE_VALUE (atype_or_adecl);
7270 declspecs = TREE_PURPOSE (atype_or_adecl);
7272 gen_declspecs (declspecs, buf, 1);
7276 strcat (buf, gen_declarator (declarator, declbuf, ""));
7282 tree declspecs; /* "integer_type", "real_type", "record_type"... */
7283 tree declarator; /* "array_type", "function_type", "pointer_type". */
7285 if (TREE_CODE (atype_or_adecl) == FIELD_DECL
7286 || TREE_CODE (atype_or_adecl) == PARM_DECL
7287 || TREE_CODE (atype_or_adecl) == FUNCTION_DECL)
7288 atype = TREE_TYPE (atype_or_adecl);
7290 atype = atype_or_adecl; /* assume we have a *_type node */
7292 if (is_complex_decl (atype))
7296 /* get the declaration specifier...it is at the end of the list */
7297 declarator = chain = atype;
7299 chain = TREE_TYPE (chain); /* not TREE_CHAIN (chain); */
7300 while (is_complex_decl (chain));
7309 gen_declspecs (declspecs, buf, 0);
7311 if (TREE_CODE (atype_or_adecl) == FIELD_DECL
7312 || TREE_CODE (atype_or_adecl) == PARM_DECL
7313 || TREE_CODE (atype_or_adecl) == FUNCTION_DECL)
7315 char *decl_name = (DECL_NAME (atype_or_adecl)
7316 ? IDENTIFIER_POINTER (DECL_NAME (atype_or_adecl))
7322 strcat (buf, gen_declarator (declarator, declbuf, decl_name));
7324 else if (decl_name[0])
7327 strcat (buf, decl_name);
7330 else if (declarator)
7333 strcat (buf, gen_declarator (declarator, declbuf, ""));
7339 #define RAW_TYPESPEC(meth) (TREE_VALUE (TREE_PURPOSE (TREE_TYPE (meth))))
7342 gen_method_decl (method, buf)
7348 if (RAW_TYPESPEC (method) != objc_object_reference)
7351 gen_declaration (TREE_TYPE (method), buf);
7355 chain = METHOD_SEL_ARGS (method);
7357 { /* we have a chain of keyword_decls */
7360 if (KEYWORD_KEY_NAME (chain))
7361 strcat (buf, IDENTIFIER_POINTER (KEYWORD_KEY_NAME (chain)));
7364 if (RAW_TYPESPEC (chain) != objc_object_reference)
7367 gen_declaration (TREE_TYPE (chain), buf);
7370 strcat (buf, IDENTIFIER_POINTER (KEYWORD_ARG_NAME (chain)));
7371 if ((chain = TREE_CHAIN (chain)))
7376 if (METHOD_ADD_ARGS (method) == (tree)1)
7377 strcat (buf, ", ...");
7378 else if (METHOD_ADD_ARGS (method))
7380 /* we have a tree list node as generate by get_parm_info. */
7381 chain = TREE_PURPOSE (METHOD_ADD_ARGS (method));
7382 /* know we have a chain of parm_decls */
7386 gen_declaration (chain, buf);
7387 chain = TREE_CHAIN (chain);
7391 else /* we have a unary selector */
7392 strcat (buf, IDENTIFIER_POINTER (METHOD_SEL_NAME (method)));
7400 dump_interface (fp, chain)
7404 char *buf = (char *)xmalloc (256);
7405 char *my_name = IDENTIFIER_POINTER (CLASS_NAME (chain));
7406 tree ivar_decls = CLASS_RAW_IVARS (chain);
7407 tree nst_methods = CLASS_NST_METHODS (chain);
7408 tree cls_methods = CLASS_CLS_METHODS (chain);
7410 fprintf (fp, "\n@interface %s", my_name);
7412 if (CLASS_SUPER_NAME (chain))
7414 char *super_name = IDENTIFIER_POINTER (CLASS_SUPER_NAME (chain));
7415 fprintf (fp, " : %s\n", super_name);
7422 fprintf (fp, "{\n");
7426 fprintf (fp, "\t%s;\n", gen_declaration (ivar_decls, buf));
7427 ivar_decls = TREE_CHAIN (ivar_decls);
7430 fprintf (fp, "}\n");
7436 fprintf (fp, "- %s;\n", gen_method_decl (nst_methods, buf));
7437 nst_methods = TREE_CHAIN (nst_methods);
7443 fprintf (fp, "+ %s;\n", gen_method_decl (cls_methods, buf));
7444 cls_methods = TREE_CHAIN (cls_methods);
7446 fprintf (fp, "\n@end");
7452 /* Add the special tree codes of Objective C to the tables. */
7454 #define LAST_CODE LAST_AND_UNUSED_TREE_CODE
7456 gcc_obstack_init (&util_obstack);
7457 util_firstobj = (char *) obstack_finish (&util_obstack);
7460 = (char **) xrealloc (tree_code_type,
7461 sizeof (char *) * LAST_OBJC_TREE_CODE);
7463 = (int *) xrealloc (tree_code_length,
7464 sizeof (int) * LAST_OBJC_TREE_CODE);
7466 = (char **) xrealloc (tree_code_name,
7467 sizeof (char *) * LAST_OBJC_TREE_CODE);
7468 bcopy (objc_tree_code_type,
7469 tree_code_type + (int) LAST_CODE,
7470 (((int) LAST_OBJC_TREE_CODE - (int) LAST_CODE)
7471 * sizeof (char *)));
7472 bcopy (objc_tree_code_length,
7473 tree_code_length + (int) LAST_CODE,
7474 (((int) LAST_OBJC_TREE_CODE - (int) LAST_CODE)
7476 bcopy (objc_tree_code_name,
7477 tree_code_name + (int) LAST_CODE,
7478 (((int) LAST_OBJC_TREE_CODE - (int) LAST_CODE)
7479 * sizeof (char *)));
7481 errbuf = (char *)xmalloc (BUFSIZE);
7483 synth_module_prologue ();
7489 struct imp_entry *impent;
7491 /* The internally generated initializers appear to have missing braces.
7492 Don't warn about this. */
7493 int save_warn_missing_braces = warn_missing_braces;
7494 warn_missing_braces = 0;
7496 generate_forward_declaration_to_string_table ();
7498 #ifdef OBJC_PROLOGUE
7502 if (implementation_context || class_names_chain
7503 || meth_var_names_chain || meth_var_types_chain || sel_ref_chain)
7504 generate_objc_symtab_decl ();
7506 for (impent = imp_list; impent; impent = impent->next)
7508 implementation_context = impent->imp_context;
7509 implementation_template = impent->imp_template;
7511 UOBJC_CLASS_decl = impent->class_decl;
7512 UOBJC_METACLASS_decl = impent->meta_decl;
7514 if (TREE_CODE (implementation_context) == CLASS_IMPLEMENTATION_TYPE)
7516 /* all of the following reference the string pool... */
7517 generate_ivar_lists ();
7518 generate_dispatch_tables ();
7519 generate_shared_structures ();
7523 generate_dispatch_tables ();
7524 generate_category (implementation_context);
7528 /* If we are using an array of selectors, we must always
7529 finish up the array decl even if no selectors were used. */
7530 if (! flag_next_runtime || sel_ref_chain)
7531 build_selector_translation_table ();
7534 generate_protocols ();
7536 if (implementation_context || class_names_chain
7537 || meth_var_names_chain || meth_var_types_chain || sel_ref_chain)
7539 /* Arrange for Objc data structures to be initialized at run time. */
7540 char *init_name = build_module_descriptor ();
7542 assemble_constructor (init_name);
7545 /* dump the class references...this forces the appropriate classes
7546 to be linked into the executable image, preserving unix archive
7547 semantics...this can be removed when we move to a more dynamically
7548 linked environment. */
7549 for (chain = cls_ref_chain; chain; chain = TREE_CHAIN (chain))
7551 handle_class_ref (chain);
7552 if (TREE_PURPOSE (chain))
7553 generate_classref_translation_entry (chain);
7556 for (impent = imp_list; impent; impent = impent->next)
7557 handle_impent (impent);
7559 /* dump the string table last */
7561 generate_strings ();
7563 if (flag_gen_declaration)
7565 add_class (implementation_context);
7566 dump_interface (gen_declaration_file, implementation_context);
7574 /* Run through the selector hash tables and print a warning for any
7575 selector which has multiple methods. */
7577 for (slot = 0; slot < SIZEHASHTABLE; slot++)
7578 for (hsh = cls_method_hash_list[slot]; hsh; hsh = hsh->next)
7581 tree meth = hsh->key;
7582 char type = (TREE_CODE (meth) == INSTANCE_METHOD_DECL
7586 warning ("potential selector conflict for method `%s'",
7587 IDENTIFIER_POINTER (METHOD_SEL_NAME (meth)));
7588 warn_with_method ("found", type, meth);
7589 for (loop = hsh->list; loop; loop = loop->next)
7590 warn_with_method ("found", type, loop->value);
7593 for (slot = 0; slot < SIZEHASHTABLE; slot++)
7594 for (hsh = nst_method_hash_list[slot]; hsh; hsh = hsh->next)
7597 tree meth = hsh->key;
7598 char type = (TREE_CODE (meth) == INSTANCE_METHOD_DECL
7602 warning ("potential selector conflict for method `%s'",
7603 IDENTIFIER_POINTER (METHOD_SEL_NAME (meth)));
7604 warn_with_method ("found", type, meth);
7605 for (loop = hsh->list; loop; loop = loop->next)
7606 warn_with_method ("found", type, loop->value);
7610 warn_missing_braces = save_warn_missing_braces;
7613 /* Subroutines of finish_objc. */
7616 generate_classref_translation_entry (chain)
7619 tree expr, name, decl_specs, decl, sc_spec;
7622 type = TREE_TYPE (TREE_PURPOSE (chain));
7624 expr = add_objc_string (TREE_VALUE (chain), class_names);
7625 expr = build_c_cast (type, expr); /* cast! */
7627 name = DECL_NAME (TREE_PURPOSE (chain));
7629 sc_spec = build_tree_list (NULLT, ridpointers[(int) RID_STATIC]);
7631 /* static struct objc_class * _OBJC_CLASS_REFERENCES_n = ...; */
7632 decl_specs = tree_cons (NULLT, type, sc_spec);
7634 /* the `decl' that is returned from start_decl is the one that we
7635 forward declared in `build_class_reference'. */
7636 decl = start_decl (name, decl_specs, 1);
7637 end_temporary_allocation ();
7638 finish_decl (decl, expr, NULLT);
7643 handle_class_ref (chain)
7646 char *name = IDENTIFIER_POINTER (TREE_VALUE (chain));
7647 if (! flag_next_runtime)
7650 char *string = (char *) alloca (strlen (name) + 30);
7653 sprintf (string, "%sobjc_class_name_%s",
7654 (flag_next_runtime ? "." : "__"), name);
7656 /* Make a decl for this name, so we can use its address in a tree. */
7657 decl = build_decl (VAR_DECL, get_identifier (string), char_type_node);
7658 DECL_EXTERNAL (decl) = 1;
7659 TREE_PUBLIC (decl) = 1;
7662 rest_of_decl_compilation (decl, 0, 0, 0);
7664 /* Make following constant read-only (why not)? */
7665 readonly_data_section ();
7667 exp = build1 (ADDR_EXPR, string_type_node, decl);
7669 /* Align the section properly. */
7670 assemble_constant_align (exp);
7672 /* Inform the assembler about this new external thing. */
7673 assemble_external (decl);
7675 /* Output a constant to reference this address. */
7676 output_constant (exp, int_size_in_bytes (string_type_node));
7680 /* This overreliance on our assembler (i.e. lack of portability)
7681 should be dealt with at some point. The GNU strategy (above)
7682 won't work either, but it is a start. */
7683 char *string = (char *) alloca (strlen (name) + 30);
7684 sprintf (string, ".reference .objc_class_name_%s", name);
7685 assemble_asm (my_build_string (strlen (string) + 1, string));
7690 handle_impent (impent)
7691 struct imp_entry *impent;
7693 implementation_context = impent->imp_context;
7694 implementation_template = impent->imp_template;
7696 if (TREE_CODE (impent->imp_context) == CLASS_IMPLEMENTATION_TYPE)
7698 char *class_name = IDENTIFIER_POINTER (CLASS_NAME (impent->imp_context));
7699 char *string = (char *) alloca (strlen (class_name) + 30);
7701 if (flag_next_runtime)
7703 /* Grossly unportable.
7704 People should know better than to assume
7705 such things about assembler syntax! */
7706 sprintf (string, ".objc_class_name_%s=0", class_name);
7707 assemble_asm (my_build_string (strlen (string) + 1, string));
7709 sprintf (string, ".globl .objc_class_name_%s", class_name);
7710 assemble_asm (my_build_string (strlen (string) + 1, string));
7714 sprintf (string, "%sobjc_class_name_%s",
7715 (flag_next_runtime ? "." : "__"), class_name);
7716 assemble_global (string);
7717 assemble_label (string);
7720 else if (TREE_CODE (impent->imp_context) == CATEGORY_IMPLEMENTATION_TYPE)
7722 char *class_name = IDENTIFIER_POINTER (CLASS_NAME (impent->imp_context));
7723 char *class_super_name
7724 = IDENTIFIER_POINTER (CLASS_SUPER_NAME (impent->imp_context));
7725 char *string = (char *) alloca (strlen (class_name)
7726 + strlen (class_super_name) + 30);
7728 /* Do the same for categories. Even though no references to these
7729 symbols are generated automatically by the compiler, it gives
7730 you a handle to pull them into an archive by hand. */
7731 if (flag_next_runtime)
7733 /* Grossly unportable. */
7734 sprintf (string, ".objc_category_name_%s_%s=0",
7735 class_name, class_super_name);
7736 assemble_asm (my_build_string (strlen (string) + 1, string));
7738 sprintf (string, ".globl .objc_category_name_%s_%s",
7739 class_name, class_super_name);
7740 assemble_asm (my_build_string (strlen (string) + 1, string));
7744 sprintf (string, "%sobjc_category_name_%s_%s",
7745 (flag_next_runtime ? "." : "__"),
7746 class_name, class_super_name);
7747 assemble_global (string);
7748 assemble_label (string);
7759 char *buf = (char *)xmalloc (256);
7761 { /* dump function prototypes */
7762 tree loop = UOBJC_MODULES_decl;
7764 fprintf (fp, "\n\nfunction prototypes:\n");
7767 if (TREE_CODE (loop) == FUNCTION_DECL && DECL_INITIAL (loop))
7769 /* we have a function definition - generate prototype */
7770 bzero (errbuf, BUFSIZE);
7771 gen_declaration (loop, errbuf);
7772 fprintf (fp, "%s;\n", errbuf);
7774 loop = TREE_CHAIN (loop);
7777 { /* dump global chains */
7779 int i, index = 0, offset = 0;
7782 for (i = 0; i < SIZEHASHTABLE; i++)
7784 if (hashlist = nst_method_hash_list[i])
7786 fprintf (fp, "\n\nnst_method_hash_list[%d]:\n", i);
7790 fprintf (fp, "-%s;\n", gen_method_decl (hashlist->key, buf));
7791 hashlist = hashlist->next;
7796 for (i = 0; i < SIZEHASHTABLE; i++)
7798 if (hashlist = cls_method_hash_list[i])
7800 fprintf (fp, "\n\ncls_method_hash_list[%d]:\n", i);
7804 fprintf (fp, "-%s;\n", gen_method_decl (hashlist->key, buf));
7805 hashlist = hashlist->next;
7810 fprintf (fp, "\nsel_refdef_chain:\n");
7811 for (loop = sel_refdef_chain; loop; loop = TREE_CHAIN (loop))
7813 fprintf (fp, "(index: %4d offset: %4d) %s\n", index, offset,
7814 IDENTIFIER_POINTER (TREE_VALUE (loop)));
7816 /* add one for the '\0' character */
7817 offset += IDENTIFIER_LENGTH (TREE_VALUE (loop)) + 1;
7819 fprintf (fp, "\n (max_selector_index: %4d.\n", max_selector_index);
7825 print_lang_statistics ()