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 /* If gen_declaration desired, open the output file. */
494 if (flag_gen_declaration)
496 int dump_base_name_length = strlen (dump_base_name);
497 register char *dumpname = (char *) xmalloc (dump_base_name_length + 7);
498 strcpy (dumpname, dump_base_name);
499 strcat (dumpname, ".decl");
500 gen_declaration_file = fopen (dumpname, "w");
501 if (gen_declaration_file == 0)
502 pfatal_with_name (dumpname);
505 if (flag_next_runtime)
507 TAG_GETCLASS = "objc_getClass";
508 TAG_GETMETACLASS = "objc_getMetaClass";
509 TAG_MSGSEND = "objc_msgSend";
510 TAG_MSGSENDSUPER = "objc_msgSendSuper";
511 TAG_EXECCLASS = "__objc_execClass";
515 TAG_GETCLASS = "objc_get_class";
516 TAG_GETMETACLASS = "objc_get_meta_class";
517 TAG_MSGSEND = "objc_msg_lookup";
518 TAG_MSGSENDSUPER = "objc_msg_lookup_super";
519 TAG_EXECCLASS = "__objc_exec_class";
520 flag_typed_selectors = 1;
523 if (doing_objc_thang)
530 fatal ("Objective-C text in C source file");
536 if (doing_objc_thang)
537 finish_objc (); /* Objective-C finalization */
539 if (gen_declaration_file)
540 fclose (gen_declaration_file);
555 lang_decode_option (p)
558 if (!strcmp (p, "-lang-objc"))
559 doing_objc_thang = 1;
560 else if (!strcmp (p, "-gen-decls"))
561 flag_gen_declaration = 1;
562 else if (!strcmp (p, "-Wselector"))
564 else if (!strcmp (p, "-Wno-selector"))
566 else if (!strcmp (p, "-Wprotocol"))
567 flag_warn_protocol = 1;
568 else if (!strcmp (p, "-Wno-protocol"))
569 flag_warn_protocol = 0;
570 else if (!strcmp (p, "-fgnu-runtime"))
571 flag_next_runtime = 0;
572 else if (!strcmp (p, "-fno-next-runtime"))
573 flag_next_runtime = 0;
574 else if (!strcmp (p, "-fno-gnu-runtime"))
575 flag_next_runtime = 1;
576 else if (!strcmp (p, "-fnext-runtime"))
577 flag_next_runtime = 1;
579 return c_decode_option (p);
585 define_decl (declarator, declspecs)
589 tree decl = start_decl (declarator, declspecs, 0);
590 finish_decl (decl, NULLT, NULLT);
594 /* Return 1 if LHS and RHS are compatible types for assignment or
595 various other operations. Return 0 if they are incompatible, and
596 return -1 if we choose to not decide. When the operation is
597 REFLEXIVE, check for compatibility in either direction.
599 For statically typed objects, an assignment of the form `a' = `b'
603 `a' and `b' are the same class type, or
604 `a' and `b' are of class types A and B such that B is a descendant of A. */
607 maybe_objc_comptypes (lhs, rhs, reflexive)
611 if (doing_objc_thang)
612 return objc_comptypes (lhs, rhs, reflexive);
617 lookup_method_in_protocol_list (rproto_list, sel_name, class_meth)
625 for (rproto = rproto_list; rproto; rproto = TREE_CHAIN (rproto))
627 p = TREE_VALUE (rproto);
629 if (TREE_CODE (p) == PROTOCOL_INTERFACE_TYPE)
631 if ((fnd = lookup_method (class_meth
632 ? PROTOCOL_CLS_METHODS (p)
633 : PROTOCOL_NST_METHODS (p), sel_name)))
635 else if (PROTOCOL_LIST (p))
636 fnd = lookup_method_in_protocol_list (PROTOCOL_LIST (p), sel_name, class_meth);
639 ; /* an identifier...if we could not find a protocol. */
648 lookup_protocol_in_reflist (rproto_list, lproto)
654 /* make sure the protocol is support by the object on the rhs */
655 if (TREE_CODE (lproto) == PROTOCOL_INTERFACE_TYPE)
658 for (rproto = rproto_list; rproto; rproto = TREE_CHAIN (rproto))
660 p = TREE_VALUE (rproto);
662 if (TREE_CODE (p) == PROTOCOL_INTERFACE_TYPE)
667 else if (PROTOCOL_LIST (p))
668 fnd = lookup_protocol_in_reflist (PROTOCOL_LIST (p), lproto);
676 ; /* an identifier...if we could not find a protocol. */
681 /* Return 1 if LHS and RHS are compatible types for assignment
682 or various other operations. Return 0 if they are incompatible,
683 and return -1 if we choose to not decide. When the operation
684 is REFLEXIVE, check for compatibility in either direction. */
687 objc_comptypes (lhs, rhs, reflexive)
692 /* new clause for protocols */
694 if (TREE_CODE (lhs) == POINTER_TYPE
695 && TREE_CODE (TREE_TYPE (lhs)) == RECORD_TYPE
696 && TREE_CODE (rhs) == POINTER_TYPE
697 && TREE_CODE (TREE_TYPE (rhs)) == RECORD_TYPE)
699 int lhs_is_proto = IS_PROTOCOL_QUALIFIED_ID (lhs);
700 int rhs_is_proto = IS_PROTOCOL_QUALIFIED_ID (rhs);
704 tree lproto, lproto_list = TYPE_PROTOCOL_LIST (lhs);
705 tree rproto, rproto_list;
710 rproto_list = TYPE_PROTOCOL_LIST (rhs);
712 /* Make sure the protocol is supported by the object
714 for (lproto = lproto_list; lproto; lproto = TREE_CHAIN (lproto))
716 p = TREE_VALUE (lproto);
717 rproto = lookup_protocol_in_reflist (rproto_list, p);
720 warning ("object does not conform to the `%s' protocol",
721 IDENTIFIER_POINTER (PROTOCOL_NAME (p)));
724 else if (TYPED_OBJECT (TREE_TYPE (rhs)))
726 tree rname = TYPE_NAME (TREE_TYPE (rhs));
729 /* Make sure the protocol is supported by the object
731 for (lproto = lproto_list; lproto; lproto = TREE_CHAIN (lproto))
733 p = TREE_VALUE (lproto);
735 rinter = lookup_interface (rname);
737 while (rinter && !rproto)
741 rproto_list = CLASS_PROTOCOL_LIST (rinter);
742 rproto = lookup_protocol_in_reflist (rproto_list, p);
745 /* Check for protocols adopted by categories. */
746 cat = CLASS_CATEGORY_LIST (rinter);
747 while (cat && !rproto)
749 rproto_list = CLASS_PROTOCOL_LIST (cat);
750 rproto = lookup_protocol_in_reflist (rproto_list, p);
752 cat = CLASS_CATEGORY_LIST (cat);
755 rinter = lookup_interface (CLASS_SUPER_NAME (rinter));
758 warning ("class `%s' does not implement the `%s' protocol",
759 IDENTIFIER_POINTER (TYPE_NAME (TREE_TYPE (rhs))),
760 IDENTIFIER_POINTER (PROTOCOL_NAME (p)));
764 return 1; /* may change...based on whether there was any mismatch */
766 else if (rhs_is_proto)
768 /* lhs is not a protocol...warn if it is statically typed */
770 if (TYPED_OBJECT (TREE_TYPE (lhs)))
773 return 1; /* one of the types is a protocol */
776 return -1; /* defer to comptypes */
778 else if (TREE_CODE (lhs) == RECORD_TYPE && TREE_CODE (rhs) == RECORD_TYPE)
779 ; /* fall thru...this is the case we have been handling all along */
781 return -1; /* defer to comptypes */
783 /* End of new protocol support. */
785 /* `id' = `<class> *', `<class> *' = `id' */
787 if ((TYPE_NAME (lhs) == objc_object_id && TYPED_OBJECT (rhs))
788 || (TYPE_NAME (rhs) == objc_object_id && TYPED_OBJECT (lhs)))
791 /* `id' = `Class', `Class' = `id' */
793 else if ((TYPE_NAME (lhs) == objc_object_id
794 && TYPE_NAME (rhs) == objc_class_id)
795 || (TYPE_NAME (lhs) == objc_class_id
796 && TYPE_NAME (rhs) == objc_object_id))
799 /* `<class> *' = `<class> *' */
801 else if (TYPED_OBJECT (lhs) && TYPED_OBJECT (rhs))
803 tree lname = TYPE_NAME (lhs);
804 tree rname = TYPE_NAME (rhs);
810 /* If the left hand side is a super class of the right hand side,
812 for (inter = lookup_interface (rname); inter;
813 inter = lookup_interface (CLASS_SUPER_NAME (inter)))
814 if (lname == CLASS_SUPER_NAME (inter))
817 /* Allow the reverse when reflexive. */
819 for (inter = lookup_interface (lname); inter;
820 inter = lookup_interface (CLASS_SUPER_NAME (inter)))
821 if (rname == CLASS_SUPER_NAME (inter))
827 return -1; /* defer to comptypes */
830 /* Called from c-decl.c before all calls to rest_of_decl_compilation. */
833 objc_check_decl (decl)
836 tree type = TREE_TYPE (decl);
838 if (TREE_CODE (type) == RECORD_TYPE
839 && TREE_STATIC_TEMPLATE (type)
840 && type != constant_string_type)
842 error_with_decl (decl, "`%s' cannot be statically allocated");
843 fatal ("statically allocated objects not supported");
848 maybe_objc_check_decl (decl)
851 if (doing_objc_thang)
852 objc_check_decl (decl);
855 /* Implement static typing. At this point, we know we have an interface. */
858 get_static_reference (interface, protocols)
862 tree type = xref_tag (RECORD_TYPE, interface);
866 tree t, m = TYPE_MAIN_VARIANT (type);
867 struct obstack *ambient_obstack = current_obstack;
869 current_obstack = &permanent_obstack;
870 t = copy_node (type);
871 TYPE_BINFO (t) = make_tree_vec (2);
873 /* Add this type to the chain of variants of TYPE. */
874 TYPE_NEXT_VARIANT (t) = TYPE_NEXT_VARIANT (m);
875 TYPE_NEXT_VARIANT (m) = t;
877 current_obstack = ambient_obstack;
879 /* Look up protocols and install in lang specific list. */
880 TYPE_PROTOCOL_LIST (t) = lookup_and_install_protocols (protocols);
882 /* This forces a new pointer type to be created later
883 (in build_pointer_type)...so that the new template
884 we just created will actually be used...what a hack! */
885 if (TYPE_POINTER_TO (t))
886 TYPE_POINTER_TO (t) = NULL;
895 get_object_reference (protocols)
898 tree type_decl = lookup_name (objc_id_id);
901 if (type_decl && TREE_CODE (type_decl) == TYPE_DECL)
903 type = TREE_TYPE (type_decl);
904 if (TYPE_MAIN_VARIANT (type) != id_type)
905 warning ("Unexpected type for `id' (%s)",
906 gen_declaration (type, errbuf));
910 fatal ("Undefined type `id', please import <objc/objc.h>");
913 /* This clause creates a new pointer type that is qualified with
914 the protocol specification...this info is used later to do more
915 elaborate type checking. */
918 tree t, m = TYPE_MAIN_VARIANT (type);
919 struct obstack *ambient_obstack = current_obstack;
921 current_obstack = &permanent_obstack;
922 t = copy_node (type);
923 TYPE_BINFO (t) = make_tree_vec (2);
925 /* Add this type to the chain of variants of TYPE. */
926 TYPE_NEXT_VARIANT (t) = TYPE_NEXT_VARIANT (m);
927 TYPE_NEXT_VARIANT (m) = t;
929 current_obstack = ambient_obstack;
931 /* look up protocols...and install in lang specific list */
932 TYPE_PROTOCOL_LIST (t) = lookup_and_install_protocols (protocols);
934 /* This forces a new pointer type to be created later
935 (in build_pointer_type)...so that the new template
936 we just created will actually be used...what a hack! */
937 if (TYPE_POINTER_TO (t))
938 TYPE_POINTER_TO (t) = NULL;
946 lookup_and_install_protocols (protocols)
951 tree return_value = protocols;
953 for (proto = protocols; proto; proto = TREE_CHAIN (proto))
955 tree ident = TREE_VALUE (proto);
956 tree p = lookup_protocol (ident);
960 error ("Cannot find protocol declaration for `%s'",
961 IDENTIFIER_POINTER (ident));
963 TREE_CHAIN (prev) = TREE_CHAIN (proto);
965 return_value = TREE_CHAIN (proto);
969 /* replace identifier with actual protocol node */
970 TREE_VALUE (proto) = p;
977 /* Create and push a decl for a built-in external variable or field NAME.
979 TYPE is its data type. */
982 create_builtin_decl (code, type, name)
987 tree decl = build_decl (code, get_identifier (name), type);
988 if (code == VAR_DECL)
990 TREE_STATIC (decl) = 1;
991 make_decl_rtl (decl, 0, 1);
997 /* purpose: "play" parser, creating/installing representations
998 of the declarations that are required by Objective-C.
1002 type_spec--------->sc_spec
1003 (tree_list) (tree_list)
1006 identifier_node identifier_node */
1009 synth_module_prologue ()
1014 /* defined in `objc.h' */
1015 objc_object_id = get_identifier (TAG_OBJECT);
1017 objc_object_reference = xref_tag (RECORD_TYPE, objc_object_id);
1019 id_type = build_pointer_type (objc_object_reference);
1021 objc_id_id = get_identifier (TYPE_ID);
1022 objc_class_id = get_identifier (TAG_CLASS);
1024 objc_class_type = build_pointer_type (xref_tag (RECORD_TYPE, objc_class_id));
1025 protocol_type = build_pointer_type (xref_tag (RECORD_TYPE,
1026 get_identifier (PROTOCOL_OBJECT_CLASS_NAME)));
1028 /* Declare type of selector-objects that represent an operation name. */
1030 #ifdef OBJC_INT_SELECTORS
1031 /* `unsigned int' */
1032 selector_type = unsigned_type_node;
1034 /* `struct objc_selector *' */
1036 = build_pointer_type (xref_tag (RECORD_TYPE,
1037 get_identifier (TAG_SELECTOR)));
1038 #endif /* not OBJC_INT_SELECTORS */
1040 /* Forward declare type, or else the prototype for msgSendSuper will
1043 super_p = build_pointer_type (xref_tag (RECORD_TYPE,
1044 get_identifier (TAG_SUPER)));
1047 /* id objc_msgSend (id, SEL, ...); */
1050 = build_function_type (id_type,
1051 tree_cons (NULL_TREE, id_type,
1052 tree_cons (NULLT, selector_type, NULLT)));
1054 if (! flag_next_runtime)
1056 umsg_decl = build_decl (FUNCTION_DECL,
1057 get_identifier (TAG_MSGSEND), temp_type);
1058 DECL_EXTERNAL (umsg_decl) = 1;
1059 TREE_PUBLIC (umsg_decl) = 1;
1060 DECL_INLINE (umsg_decl) = 1;
1062 if (flag_traditional && TAG_MSGSEND[0] != '_')
1063 DECL_BUILT_IN_NONANSI (umsg_decl) = 1;
1065 make_decl_rtl (umsg_decl, NULL_PTR, 1);
1066 pushdecl (umsg_decl);
1069 umsg_decl = builtin_function (TAG_MSGSEND, temp_type, NOT_BUILT_IN, 0);
1071 /* id objc_msgSendSuper (struct objc_super *, SEL, ...); */
1074 = build_function_type (id_type,
1075 tree_cons (NULL_TREE, super_p,
1076 tree_cons (NULLT, selector_type, NULLT)));
1078 umsg_super_decl = builtin_function (TAG_MSGSENDSUPER,
1079 temp_type, NOT_BUILT_IN, 0);
1081 /* id objc_getClass (const char *); */
1083 temp_type = build_function_type (id_type,
1085 const_string_type_node,
1086 tree_cons (NULLT, void_type_node, NULLT)));
1089 = builtin_function (TAG_GETCLASS, temp_type, NOT_BUILT_IN, 0);
1091 /* id objc_getMetaClass (const char *); */
1093 objc_get_meta_class_decl
1094 = builtin_function (TAG_GETMETACLASS, temp_type, NOT_BUILT_IN, 0);
1096 /* static SEL _OBJC_SELECTOR_TABLE[]; */
1098 if (! flag_next_runtime)
1100 if (flag_typed_selectors)
1102 /* supress outputting debug symbols, because
1103 dbxout_init hasn'r been called yet... */
1104 enum debug_info_type save_write_symbols = write_symbols;
1105 write_symbols = NO_DEBUG;
1107 build_selector_template ();
1108 temp_type = build_array_type (objc_selector_template, NULLT);
1110 write_symbols = save_write_symbols;
1113 temp_type = build_array_type (selector_type, NULLT);
1115 layout_type (temp_type);
1116 UOBJC_SELECTOR_TABLE_decl
1117 = create_builtin_decl (VAR_DECL, temp_type,
1118 "_OBJC_SELECTOR_TABLE");
1122 generate_forward_declaration_to_string_table ();
1124 /* Forward declare constant_string_id and constant_string_type. */
1125 constant_string_id = get_identifier (STRING_OBJECT_CLASS_NAME);
1126 constant_string_type = xref_tag (RECORD_TYPE, constant_string_id);
1129 /* Custom build_string which sets TREE_TYPE! */
1132 my_build_string (len, str)
1137 tree a_string = build_string (len, str);
1138 /* Some code from combine_strings, which is local to c-parse.y. */
1139 if (TREE_TYPE (a_string) == int_array_type_node)
1142 TREE_TYPE (a_string) =
1143 build_array_type (wide_flag ? integer_type_node : char_type_node,
1144 build_index_type (build_int_2 (len - 1, 0)));
1146 TREE_CONSTANT (a_string) = 1; /* puts string in the ".text" segment */
1147 TREE_STATIC (a_string) = 1;
1152 /* Return a newly constructed OBJC_STRING_CST node whose value is
1153 the LEN characters at STR.
1154 The TREE_TYPE is not initialized. */
1157 build_objc_string (len, str)
1161 tree s = build_string (len, str);
1163 TREE_SET_CODE (s, OBJC_STRING_CST);
1167 /* Given a chain of OBJC_STRING_CST's, build a static instance of
1168 NXConstantString which points at the concatenation of those strings.
1169 We place the string object in the __string_objects section of the
1170 __OBJC segment. The Objective-C runtime will initialize the isa
1171 pointers of the string objects to point at the NXConstantString
1175 build_objc_string_object (strings)
1178 tree string, initlist, constructor;
1181 if (!doing_objc_thang)
1184 if (lookup_interface (constant_string_id) == NULLT)
1186 error ("Cannot find interface declaration for `%s'",
1187 IDENTIFIER_POINTER (constant_string_id));
1188 return error_mark_node;
1191 add_class_reference (constant_string_id);
1193 /* combine_strings will work for OBJC_STRING_CST's too. */
1194 string = combine_strings (strings);
1195 TREE_SET_CODE (string, STRING_CST);
1196 length = TREE_STRING_LENGTH (string) - 1;
1198 /* & ((NXConstantString) {0, string, length}) */
1200 initlist = build_tree_list (NULLT, build_int_2 (0, 0));
1201 initlist = tree_cons (NULLT, build_unary_op (ADDR_EXPR, string, 1),
1203 initlist = tree_cons (NULLT, build_int_2 (length, 0), initlist);
1204 constructor = build_constructor (constant_string_type,
1205 nreverse (initlist));
1207 return build_unary_op (ADDR_EXPR, constructor, 1);
1210 /* Build a static constant CONSTRUCTOR
1211 with type TYPE and elements ELTS. */
1214 build_constructor (type, elts)
1217 tree constructor = build (CONSTRUCTOR, type, NULL_TREE, elts);
1219 TREE_CONSTANT (constructor) = 1;
1220 TREE_STATIC (constructor) = 1;
1221 TREE_READONLY (constructor) = 1;
1226 /* Take care of defining and initializing _OBJC_SYMBOLS. */
1228 /* Predefine the following data type:
1236 void *defs[cls_def_cnt + cat_def_cnt];
1240 build_objc_symtab_template ()
1242 tree field_decl, field_decl_chain, index;
1244 objc_symtab_template = start_struct (RECORD_TYPE, get_identifier (UTAG_SYMTAB));
1246 /* long sel_ref_cnt; */
1248 field_decl = create_builtin_decl (FIELD_DECL,
1249 long_integer_type_node,
1251 field_decl_chain = field_decl;
1255 field_decl = create_builtin_decl (FIELD_DECL,
1256 build_pointer_type (selector_type),
1258 chainon (field_decl_chain, field_decl);
1260 /* short cls_def_cnt; */
1262 field_decl = create_builtin_decl (FIELD_DECL,
1263 short_integer_type_node,
1265 chainon (field_decl_chain, field_decl);
1267 /* short cat_def_cnt; */
1269 field_decl = create_builtin_decl (FIELD_DECL,
1270 short_integer_type_node,
1272 chainon (field_decl_chain, field_decl);
1274 /* void *defs[cls_def_cnt + cat_def_cnt]; */
1276 index = build_index_type (build_int_2 (imp_count + cat_count - 1,
1277 imp_count == 0 && cat_count == 0
1279 field_decl = create_builtin_decl (FIELD_DECL,
1280 build_array_type (ptr_type_node, index),
1282 chainon (field_decl_chain, field_decl);
1284 finish_struct (objc_symtab_template, field_decl_chain);
1287 /* Create the initial value for the `defs' field of _objc_symtab.
1288 This is a CONSTRUCTOR. */
1291 init_def_list (type)
1294 tree expr, initlist = NULLT;
1295 struct imp_entry *impent;
1298 for (impent = imp_list; impent; impent = impent->next)
1300 if (TREE_CODE (impent->imp_context) == CLASS_IMPLEMENTATION_TYPE)
1302 expr = build_unary_op (ADDR_EXPR, impent->class_decl, 0);
1303 initlist = tree_cons (NULLT, expr, initlist);
1308 for (impent = imp_list; impent; impent = impent->next)
1310 if (TREE_CODE (impent->imp_context) == CATEGORY_IMPLEMENTATION_TYPE)
1312 expr = build_unary_op (ADDR_EXPR, impent->class_decl, 0);
1313 initlist = tree_cons (NULLT, expr, initlist);
1316 return build_constructor (type, nreverse (initlist));
1319 /* Construct the initial value for all of _objc_symtab. */
1322 init_objc_symtab (type)
1327 /* sel_ref_cnt = { ..., 5, ... } */
1329 initlist = build_tree_list (NULLT, build_int_2 (0, 0));
1331 /* refs = { ..., _OBJC_SELECTOR_TABLE, ... } */
1333 if (flag_next_runtime || ! sel_ref_chain)
1334 initlist = tree_cons (NULLT, build_int_2 (0, 0), initlist);
1336 initlist = tree_cons (NULLT,
1337 build_unary_op (ADDR_EXPR,
1338 UOBJC_SELECTOR_TABLE_decl, 1),
1341 /* cls_def_cnt = { ..., 5, ... } */
1343 initlist = tree_cons (NULLT, build_int_2 (imp_count, 0), initlist);
1345 /* cat_def_cnt = { ..., 5, ... } */
1347 initlist = tree_cons (NULLT, build_int_2 (cat_count, 0), initlist);
1349 /* cls_def = { ..., { &Foo, &Bar, ...}, ... } */
1351 if (imp_count || cat_count)
1353 tree field = TYPE_FIELDS (type);
1354 field = TREE_CHAIN (TREE_CHAIN (TREE_CHAIN (TREE_CHAIN (field))));
1356 initlist = tree_cons (NULLT, init_def_list (TREE_TYPE (field)),
1360 return build_constructor (type, nreverse (initlist));
1363 /* Push forward-declarations of all the categories
1364 so that init_def_list can use them in a CONSTRUCTOR. */
1367 forward_declare_categories ()
1369 struct imp_entry *impent;
1370 tree sav = implementation_context;
1371 for (impent = imp_list; impent; impent = impent->next)
1373 if (TREE_CODE (impent->imp_context) == CATEGORY_IMPLEMENTATION_TYPE)
1375 /* Set an invisible arg to synth_id_with_class_suffix. */
1376 implementation_context = impent->imp_context;
1378 = create_builtin_decl (VAR_DECL, objc_category_template,
1379 IDENTIFIER_POINTER (synth_id_with_class_suffix ("_OBJC_CATEGORY", implementation_context)));
1382 implementation_context = sav;
1385 /* Create the declaration of _OBJC_SYMBOLS, with type `strict _objc_symtab'
1386 and initialized appropriately. */
1389 generate_objc_symtab_decl ()
1393 if (!objc_category_template)
1394 build_category_template ();
1396 /* forward declare categories */
1398 forward_declare_categories ();
1400 if (!objc_symtab_template)
1401 build_objc_symtab_template ();
1403 sc_spec = build_tree_list (NULLT, ridpointers[(int) RID_STATIC]);
1405 UOBJC_SYMBOLS_decl = start_decl (get_identifier ("_OBJC_SYMBOLS"),
1406 tree_cons (NULLT, objc_symtab_template, sc_spec), 1);
1408 end_temporary_allocation (); /* start_decl trying to be smart about inits */
1409 TREE_USED (UOBJC_SYMBOLS_decl) = 1;
1410 DECL_IGNORED_P (UOBJC_SYMBOLS_decl) = 1;
1411 finish_decl (UOBJC_SYMBOLS_decl,
1412 init_objc_symtab (TREE_TYPE (UOBJC_SYMBOLS_decl)),
1417 init_module_descriptor (type)
1420 tree initlist, expr;
1422 /* version = { 1, ... } */
1424 expr = build_int_2 (OBJC_VERSION, 0);
1425 initlist = build_tree_list (NULLT, expr);
1427 /* size = { ..., sizeof (struct objc_module), ... } */
1429 expr = size_in_bytes (objc_module_template);
1430 initlist = tree_cons (NULLT, expr, initlist);
1432 /* name = { ..., "foo.m", ... } */
1434 expr = add_objc_string (get_identifier (input_filename), class_names);
1435 initlist = tree_cons (NULLT, expr, initlist);
1437 /* symtab = { ..., _OBJC_SYMBOLS, ... } */
1439 if (UOBJC_SYMBOLS_decl)
1440 expr = build_unary_op (ADDR_EXPR, UOBJC_SYMBOLS_decl, 0);
1442 expr = build_int_2 (0, 0);
1443 initlist = tree_cons (NULLT, expr, initlist);
1445 return build_constructor (type, nreverse (initlist));
1448 /* Write out the data structures to describe Objective C classes defined.
1449 If appropriate, compile and output a setup function to initialize them.
1450 Return a string which is the name of a function to call to initialize
1451 the Objective C data structures for this file (and perhaps for other files
1454 struct objc_module { ... } _OBJC_MODULE = { ... };
1459 build_module_descriptor ()
1461 tree decl_specs, field_decl, field_decl_chain;
1463 objc_module_template = start_struct (RECORD_TYPE, get_identifier (UTAG_MODULE));
1467 decl_specs = build_tree_list (NULLT, ridpointers[(int) RID_LONG]);
1468 field_decl = get_identifier ("version");
1469 field_decl = grokfield (input_filename, lineno, field_decl, decl_specs, NULLT);
1470 field_decl_chain = field_decl;
1474 decl_specs = build_tree_list (NULLT, ridpointers[(int) RID_LONG]);
1475 field_decl = get_identifier ("size");
1476 field_decl = grokfield (input_filename, lineno, field_decl, decl_specs, NULLT);
1477 chainon (field_decl_chain, field_decl);
1481 decl_specs = build_tree_list (NULLT, ridpointers[(int) RID_CHAR]);
1482 field_decl = build1 (INDIRECT_REF, NULLT, get_identifier ("name"));
1483 field_decl = grokfield (input_filename, lineno, field_decl, decl_specs, NULLT);
1484 chainon (field_decl_chain, field_decl);
1486 /* struct objc_symtab *symtab; */
1488 decl_specs = get_identifier (UTAG_SYMTAB);
1489 decl_specs = build_tree_list (NULLT, xref_tag (RECORD_TYPE, decl_specs));
1490 field_decl = build1 (INDIRECT_REF, NULLT, get_identifier ("symtab"));
1491 field_decl = grokfield (input_filename, lineno, field_decl, decl_specs, NULLT);
1492 chainon (field_decl_chain, field_decl);
1494 finish_struct (objc_module_template, field_decl_chain);
1496 /* create an instance of "objc_module" */
1498 decl_specs = tree_cons (NULLT, objc_module_template,
1499 build_tree_list (NULLT, ridpointers[(int) RID_STATIC]));
1501 UOBJC_MODULES_decl = start_decl (get_identifier ("_OBJC_MODULES"),
1504 end_temporary_allocation (); /* start_decl trying to be smart about inits */
1505 DECL_IGNORED_P (UOBJC_MODULES_decl) = 1;
1506 finish_decl (UOBJC_MODULES_decl,
1507 init_module_descriptor (TREE_TYPE (UOBJC_MODULES_decl)),
1510 /* Mark the decl to avoid "defined but not used" warning. */
1511 DECL_IN_SYSTEM_HEADER (UOBJC_MODULES_decl) = 1;
1513 /* Generate a constructor call for the module descriptor.
1514 This code was generated by reading the grammar rules
1515 of c-parse.y; Therefore, it may not be the most efficient
1516 way of generating the requisite code. */
1518 if (flag_next_runtime)
1522 tree parms, function_decl, decelerator, void_list_node;
1524 extern tree get_file_function_name ();
1525 tree init_function_name = get_file_function_name ('I');
1527 /* Declare void __objc_execClass (void*); */
1529 void_list_node = build_tree_list (NULL_TREE, void_type_node);
1531 = build_function_type (void_type_node,
1532 tree_cons (NULL_TREE, ptr_type_node,
1534 function_decl = build_decl (FUNCTION_DECL,
1535 get_identifier (TAG_EXECCLASS),
1537 DECL_EXTERNAL (function_decl) = 1;
1538 TREE_PUBLIC (function_decl) = 1;
1540 pushdecl (function_decl);
1541 rest_of_decl_compilation (function_decl, 0, 0, 0);
1544 = build_tree_list (NULLT,
1545 build_unary_op (ADDR_EXPR, UOBJC_MODULES_decl, 0));
1546 decelerator = build_function_call (function_decl, parms);
1548 /* void _GLOBAL_$I$<gnyf> () {objc_execClass (&L_OBJC_MODULES);} */
1550 start_function (void_list_node,
1551 build_parse_node (CALL_EXPR, init_function_name,
1552 /* This has the format of the output
1553 of get_parm_info. */
1554 tree_cons (NULL_TREE, NULL_TREE,
1558 #if 0 /* This should be turned back on later
1559 for the systems where collect is not needed. */
1560 /* Make these functions nonglobal
1561 so each file can use the same name. */
1562 TREE_PUBLIC (current_function_decl) = 0;
1564 TREE_USED (current_function_decl) = 1;
1565 store_parm_decls ();
1567 assemble_external (function_decl);
1568 c_expand_expr_stmt (decelerator);
1570 TREE_PUBLIC (current_function_decl) = 1;
1572 function_decl = current_function_decl;
1573 finish_function (0);
1575 /* Return the name of the constructor function. */
1576 return XSTR (XEXP (DECL_RTL (function_decl), 0), 0);
1580 /* extern const char _OBJC_STRINGS[]; */
1583 generate_forward_declaration_to_string_table ()
1585 tree sc_spec, decl_specs, expr_decl;
1587 sc_spec = tree_cons (NULLT, ridpointers[(int) RID_EXTERN], NULLT);
1588 decl_specs = tree_cons (NULLT, ridpointers[(int) RID_CHAR], sc_spec);
1590 expr_decl = build_nt (ARRAY_REF, get_identifier ("_OBJC_STRINGS"), NULLT);
1592 UOBJC_STRINGS_decl = define_decl (expr_decl, decl_specs);
1595 /* Output all strings. */
1600 tree sc_spec, decl_specs, expr_decl;
1601 tree chain, string_expr;
1604 for (chain = class_names_chain; chain; chain = TREE_CHAIN (chain))
1606 string = TREE_VALUE (chain);
1607 decl = TREE_PURPOSE (chain);
1608 sc_spec = tree_cons (NULLT, ridpointers[(int) RID_STATIC], NULLT);
1609 decl_specs = tree_cons (NULLT, ridpointers[(int) RID_CHAR], sc_spec);
1610 expr_decl = build_nt (ARRAY_REF, DECL_NAME (decl), NULLT);
1611 decl = start_decl (expr_decl, decl_specs, 1);
1612 end_temporary_allocation ();
1613 string_expr = my_build_string (IDENTIFIER_LENGTH (string) + 1,
1614 IDENTIFIER_POINTER (string));
1615 finish_decl (decl, string_expr, NULLT);
1618 for (chain = meth_var_names_chain; chain; chain = TREE_CHAIN (chain))
1620 string = TREE_VALUE (chain);
1621 decl = TREE_PURPOSE (chain);
1622 sc_spec = tree_cons (NULLT, ridpointers[(int) RID_STATIC], NULLT);
1623 decl_specs = tree_cons (NULLT, ridpointers[(int) RID_CHAR], sc_spec);
1624 expr_decl = build_nt (ARRAY_REF, DECL_NAME (decl), NULLT);
1625 decl = start_decl (expr_decl, decl_specs, 1);
1626 end_temporary_allocation ();
1627 string_expr = my_build_string (IDENTIFIER_LENGTH (string) + 1,
1628 IDENTIFIER_POINTER (string));
1629 finish_decl (decl, string_expr, NULLT);
1632 for (chain = meth_var_types_chain; chain; chain = TREE_CHAIN (chain))
1634 string = TREE_VALUE (chain);
1635 decl = TREE_PURPOSE (chain);
1636 sc_spec = tree_cons (NULLT, ridpointers[(int) RID_STATIC], NULLT);
1637 decl_specs = tree_cons (NULLT, ridpointers[(int) RID_CHAR], sc_spec);
1638 expr_decl = build_nt (ARRAY_REF, DECL_NAME (decl), NULLT);
1639 decl = start_decl (expr_decl, decl_specs, 1);
1640 end_temporary_allocation ();
1641 string_expr = my_build_string (IDENTIFIER_LENGTH (string) + 1,
1642 IDENTIFIER_POINTER (string));
1643 finish_decl (decl, string_expr, NULLT);
1648 build_selector_reference_decl (name)
1653 struct obstack *save_current_obstack = current_obstack;
1654 struct obstack *save_rtl_obstack = rtl_obstack;
1657 sprintf (buf, "_OBJC_SELECTOR_REFERENCES_%d", idx++);
1660 rtl_obstack = current_obstack = &permanent_obstack;
1661 ident = get_identifier (buf);
1663 decl = build_decl (VAR_DECL, ident, selector_type);
1664 DECL_EXTERNAL (decl) = 1;
1665 TREE_PUBLIC (decl) = 1;
1666 TREE_USED (decl) = 1;
1667 TREE_READONLY (decl) = 1;
1669 make_decl_rtl (decl, 0, 1); /* usually called from `rest_of_decl_compilation' */
1670 pushdecl_top_level (decl); /* our `extended/custom' pushdecl in c-decl.c */
1672 current_obstack = save_current_obstack;
1673 rtl_obstack = save_rtl_obstack;
1678 /* Just a handy wrapper for add_objc_string. */
1681 build_selector (ident)
1684 tree expr = add_objc_string (ident, meth_var_names);
1685 if (flag_typed_selectors)
1688 return build_c_cast (selector_type, expr); /* cast! */
1691 /* Synthesize the following expr: (char *)&_OBJC_STRINGS[<offset>]
1692 The cast stops the compiler from issuing the following message:
1693 grok.m: warning: initialization of non-const * pointer from const *
1694 grok.m: warning: initialization between incompatible pointer types. */
1697 build_msg_pool_reference (offset)
1700 tree expr = build_int_2 (offset, 0);
1703 expr = build_array_ref (UOBJC_STRINGS_decl, expr);
1704 expr = build_unary_op (ADDR_EXPR, expr, 0);
1706 cast = build_tree_list (build_tree_list (NULLT, ridpointers[(int) RID_CHAR]),
1707 build1 (INDIRECT_REF, NULLT, NULLT));
1708 TREE_TYPE (expr) = groktypename (cast);
1713 init_selector (offset)
1716 tree expr = build_msg_pool_reference (offset);
1717 TREE_TYPE (expr) = selector_type; /* cast */
1722 build_selector_translation_table ()
1724 tree sc_spec, decl_specs;
1725 tree chain, initlist = NULLT;
1727 tree decl, var_decl, name;
1729 /* The corresponding pop_obstacks is in finish_decl,
1730 called at the end of this function. */
1731 if (! flag_next_runtime)
1732 push_obstacks_nochange ();
1734 for (chain = sel_ref_chain; chain; chain = TREE_CHAIN (chain))
1738 expr = build_selector (TREE_VALUE (chain));
1740 if (flag_next_runtime)
1742 name = DECL_NAME (TREE_PURPOSE (chain));
1744 sc_spec = build_tree_list (NULLT, ridpointers[(int) RID_STATIC]);
1746 /* static SEL _OBJC_SELECTOR_REFERENCES_n = ...; */
1747 decl_specs = tree_cons (NULLT, selector_type, sc_spec);
1751 /* the `decl' that is returned from start_decl is the one that we
1752 forward declared in `build_selector_reference' */
1753 decl = start_decl (var_decl, decl_specs, 1);
1756 /* add one for the '\0' character */
1757 offset += IDENTIFIER_LENGTH (TREE_VALUE (chain)) + 1;
1759 if (flag_next_runtime)
1761 end_temporary_allocation ();
1762 finish_decl (decl, expr, NULLT);
1766 if (flag_typed_selectors)
1768 tree eltlist = NULLT;
1769 tree encoding = get_proto_encoding (TREE_PURPOSE (chain));
1770 eltlist = tree_cons (NULLT, expr, NULLT);
1771 eltlist = tree_cons (NULLT, encoding, eltlist);
1772 expr = build_constructor (objc_selector_template,
1773 nreverse (eltlist));
1775 initlist = tree_cons (NULLT, expr, initlist);
1780 if (! flag_next_runtime)
1782 /* Cause the variable and its initial value to be actually output. */
1783 DECL_EXTERNAL (UOBJC_SELECTOR_TABLE_decl) = 0;
1784 TREE_STATIC (UOBJC_SELECTOR_TABLE_decl) = 1;
1785 /* NULL terminate the list and fix the decl for output. */
1786 initlist = tree_cons (NULLT, build_int_2 (0, 0), initlist);
1787 DECL_INITIAL (UOBJC_SELECTOR_TABLE_decl) = (tree) 1;
1788 initlist = build_constructor (TREE_TYPE (UOBJC_SELECTOR_TABLE_decl),
1789 nreverse (initlist));
1790 finish_decl (UOBJC_SELECTOR_TABLE_decl, initlist, NULLT);
1791 current_function_decl = NULLT;
1797 get_proto_encoding (proto)
1805 if (! METHOD_ENCODING (proto))
1807 tmp_decl = build_tmp_function_decl ();
1808 hack_method_prototype (proto, tmp_decl);
1809 encoding = encode_method_prototype (proto, tmp_decl);
1810 METHOD_ENCODING (proto) = encoding;
1813 encoding = METHOD_ENCODING (proto);
1815 return add_objc_string (encoding, meth_var_types);
1818 return build_int_2 (0, 0);
1821 /* sel_ref_chain is a list whose "value" fields will be instances of
1822 identifier_node that represent the selector. */
1825 build_typed_selector_reference (ident, proto)
1828 tree *chain = &sel_ref_chain;
1834 if (TREE_PURPOSE (*chain) == ident && TREE_VALUE (*chain) == proto)
1835 goto return_at_index;
1837 chain = &TREE_CHAIN (*chain);
1840 *chain = perm_tree_cons (proto, ident, NULLT);
1843 expr = build_unary_op (ADDR_EXPR,
1844 build_array_ref (UOBJC_SELECTOR_TABLE_decl,
1845 build_int_2 (index, 0)),
1847 return build_c_cast (selector_type, expr);
1851 build_selector_reference (ident)
1854 tree *chain = &sel_ref_chain;
1860 if (TREE_VALUE (*chain) == ident)
1861 return (flag_next_runtime
1862 ? TREE_PURPOSE (*chain)
1863 : build_array_ref (UOBJC_SELECTOR_TABLE_decl,
1864 build_int_2 (index, 0)));
1867 chain = &TREE_CHAIN (*chain);
1870 expr = build_selector_reference_decl (ident);
1872 *chain = perm_tree_cons (expr, ident, NULLT);
1874 return (flag_next_runtime
1876 : build_array_ref (UOBJC_SELECTOR_TABLE_decl,
1877 build_int_2 (index, 0)));
1881 build_class_reference_decl (name)
1886 struct obstack *save_current_obstack = current_obstack;
1887 struct obstack *save_rtl_obstack = rtl_obstack;
1890 sprintf (buf, "_OBJC_CLASS_REFERENCES_%d", idx++);
1893 rtl_obstack = current_obstack = &permanent_obstack;
1894 ident = get_identifier (buf);
1896 decl = build_decl (VAR_DECL, ident, objc_class_type);
1897 DECL_EXTERNAL (decl) = 1;
1898 TREE_PUBLIC (decl) = 1;
1899 TREE_USED (decl) = 1;
1900 TREE_READONLY (decl) = 1;
1902 make_decl_rtl (decl, 0, 1); /* usually called from `rest_of_decl_compilation' */
1903 pushdecl_top_level (decl); /* our `extended/custom' pushdecl in c-decl.c */
1905 current_obstack = save_current_obstack;
1906 rtl_obstack = save_rtl_obstack;
1911 /* Create a class reference, but don't create a variable to reference
1915 add_class_reference (ident)
1920 if ((chain = cls_ref_chain))
1925 if (ident == TREE_VALUE (chain))
1929 chain = TREE_CHAIN (chain);
1933 /* append to the end of the list */
1934 TREE_CHAIN (tail) = perm_tree_cons (NULLT, ident, NULLT);
1937 cls_ref_chain = perm_tree_cons (NULLT, ident, NULLT);
1940 /* Get a class reference, creating it if necessary. Also create the
1941 reference variable. */
1944 get_class_reference (ident)
1947 if (flag_next_runtime)
1952 for (chain = &cls_ref_chain; *chain; chain = &TREE_CHAIN (*chain))
1953 if (TREE_VALUE (*chain) == ident)
1955 if (! TREE_PURPOSE (*chain))
1956 TREE_PURPOSE (*chain) = build_class_reference_decl (ident);
1957 return TREE_PURPOSE (*chain);
1960 decl = build_class_reference_decl (ident);
1961 *chain = perm_tree_cons (decl, ident, NULLT);
1968 add_class_reference (ident);
1970 params = build_tree_list (NULLT,
1971 my_build_string (IDENTIFIER_LENGTH (ident) + 1,
1972 IDENTIFIER_POINTER (ident)));
1974 assemble_external (objc_get_class_decl);
1975 return build_function_call (objc_get_class_decl, params);
1979 /* sel_refdef_chain is a list whose "value" fields will be instances
1980 of identifier_node that represent the selector. It returns the
1981 offset of the selector from the beginning of the _OBJC_STRINGS
1982 pool. This offset is typically used by init_selector during code
1985 For each string section we have a chain which maps identifier nodes
1986 to decls for the strings. */
1989 add_objc_string (ident, section)
1991 enum string_section section;
1995 if (section == class_names)
1996 chain = &class_names_chain;
1997 else if (section == meth_var_names)
1998 chain = &meth_var_names_chain;
1999 else if (section == meth_var_types)
2000 chain = &meth_var_types_chain;
2004 if (TREE_VALUE (*chain) == ident)
2005 return build_unary_op (ADDR_EXPR, TREE_PURPOSE (*chain), 1);
2007 chain = &TREE_CHAIN (*chain);
2010 decl = build_objc_string_decl (ident, section);
2012 *chain = perm_tree_cons (decl, ident, NULLT);
2014 return build_unary_op (ADDR_EXPR, decl, 1);
2018 build_objc_string_decl (name, section)
2020 enum string_section section;
2024 struct obstack *save_current_obstack = current_obstack;
2025 struct obstack *save_rtl_obstack = rtl_obstack;
2026 static int class_names_idx = 0;
2027 static int meth_var_names_idx = 0;
2028 static int meth_var_types_idx = 0;
2030 if (section == class_names)
2031 sprintf (buf, "_OBJC_CLASS_NAME_%d", class_names_idx++);
2032 else if (section == meth_var_names)
2033 sprintf (buf, "_OBJC_METH_VAR_NAME_%d", meth_var_names_idx++);
2034 else if (section == meth_var_types)
2035 sprintf (buf, "_OBJC_METH_VAR_TYPE_%d", meth_var_types_idx++);
2037 rtl_obstack = current_obstack = &permanent_obstack;
2038 ident = get_identifier (buf);
2040 decl = build_decl (VAR_DECL, ident, build_array_type (char_type_node, 0));
2041 DECL_EXTERNAL (decl) = 1;
2042 TREE_PUBLIC (decl) = 1;
2043 TREE_USED (decl) = 1;
2044 TREE_READONLY (decl) = 1;
2045 TREE_CONSTANT (decl) = 1;
2047 make_decl_rtl (decl, 0, 1); /* usually called from `rest_of_decl_compilation */
2048 pushdecl_top_level (decl); /* our `extended/custom' pushdecl in c-decl.c */
2050 current_obstack = save_current_obstack;
2051 rtl_obstack = save_rtl_obstack;
2058 objc_declare_alias (alias_ident, class_ident)
2062 if (!doing_objc_thang)
2065 if (is_class_name (class_ident) != class_ident)
2066 warning ("Cannot find class `%s'", IDENTIFIER_POINTER (class_ident));
2067 else if (is_class_name (alias_ident))
2068 warning ("Class `%s' already exists", IDENTIFIER_POINTER (alias_ident));
2070 alias_chain = tree_cons (class_ident, alias_ident, alias_chain);
2074 objc_declare_class (ident_list)
2079 if (!doing_objc_thang)
2082 for (list = ident_list; list; list = TREE_CHAIN (list))
2084 tree ident = TREE_VALUE (list);
2087 if ((decl = lookup_name (ident)))
2089 error ("`%s' redeclared as different kind of symbol",
2090 IDENTIFIER_POINTER (ident));
2091 error_with_decl (decl, "previous declaration of `%s'");
2094 if (! is_class_name (ident))
2096 tree record = xref_tag (RECORD_TYPE, ident);
2097 TREE_STATIC_TEMPLATE (record) = 1;
2098 class_chain = tree_cons (NULLT, ident, class_chain);
2104 is_class_name (ident)
2109 if (lookup_interface (ident))
2112 for (chain = class_chain; chain; chain = TREE_CHAIN (chain))
2114 if (ident == TREE_VALUE (chain))
2118 for (chain = alias_chain; chain; chain = TREE_CHAIN (chain))
2120 if (ident == TREE_VALUE (chain))
2121 return TREE_PURPOSE (chain);
2128 lookup_interface (ident)
2133 for (chain = interface_chain; chain; chain = TREE_CHAIN (chain))
2135 if (ident == CLASS_NAME (chain))
2142 objc_copy_list (list, head)
2146 tree newlist = NULL_TREE, tail = NULL_TREE;
2150 tail = copy_node (list);
2152 /* The following statement fixes a bug when inheriting instance
2153 variables that are declared to be bitfields. finish_struct
2154 expects to find the width of the bitfield in DECL_INITIAL,
2155 which it nulls out after processing the decl of the super
2156 class...rather than change the way finish_struct works (which
2157 is risky), I create the situation it expects...s.naroff
2160 if (DECL_BIT_FIELD (tail) && DECL_INITIAL (tail) == 0)
2161 DECL_INITIAL (tail) = build_int_2 (DECL_FIELD_SIZE (tail), 0);
2163 newlist = chainon (newlist, tail);
2164 list = TREE_CHAIN (list);
2170 /* Used by: build_private_template, get_class_ivars, and
2171 continue_class. COPY is 1 when called from @defs. In this case
2172 copy all fields. Otherwise don't copy leaf ivars since we rely on
2173 them being side-effected exactly once by finish_struct. */
2176 build_ivar_chain (interface, copy)
2180 tree my_name, super_name, ivar_chain;
2182 my_name = CLASS_NAME (interface);
2183 super_name = CLASS_SUPER_NAME (interface);
2185 /* Possibly copy leaf ivars. */
2187 objc_copy_list (CLASS_IVARS (interface), &ivar_chain);
2189 ivar_chain = CLASS_IVARS (interface);
2194 tree super_interface = lookup_interface (super_name);
2196 if (!super_interface)
2198 /* fatal did not work with 2 args...should fix */
2199 error ("Cannot find interface declaration for `%s', superclass of `%s'",
2200 IDENTIFIER_POINTER (super_name),
2201 IDENTIFIER_POINTER (my_name));
2204 if (super_interface == interface)
2206 fatal ("Circular inheritance in interface declaration for `%s'",
2207 IDENTIFIER_POINTER (super_name));
2209 interface = super_interface;
2210 my_name = CLASS_NAME (interface);
2211 super_name = CLASS_SUPER_NAME (interface);
2213 op1 = CLASS_IVARS (interface);
2216 tree head, tail = objc_copy_list (op1, &head);
2218 /* Prepend super class ivars...make a copy of the list, we
2219 do not want to alter the original. */
2220 TREE_CHAIN (tail) = ivar_chain;
2227 /* struct <classname> {
2228 struct objc_class *isa;
2233 build_private_template (class)
2238 if (CLASS_STATIC_TEMPLATE (class))
2240 uprivate_record = CLASS_STATIC_TEMPLATE (class);
2241 ivar_context = TYPE_FIELDS (CLASS_STATIC_TEMPLATE (class));
2245 uprivate_record = start_struct (RECORD_TYPE, CLASS_NAME (class));
2247 ivar_context = build_ivar_chain (class, 0);
2249 finish_struct (uprivate_record, ivar_context);
2251 CLASS_STATIC_TEMPLATE (class) = uprivate_record;
2253 /* mark this record as class template - for class type checking */
2254 TREE_STATIC_TEMPLATE (uprivate_record) = 1;
2256 instance_type = groktypename (build_tree_list (build_tree_list (NULLT, uprivate_record),
2257 build1 (INDIRECT_REF, NULLT, NULLT)));
2258 return ivar_context;
2261 /* Begin code generation for protocols... */
2263 /* struct objc_protocol {
2264 char *protocol_name;
2265 struct objc_protocol **protocol_list;
2266 struct objc_method_desc *instance_methods;
2267 struct objc_method_desc *class_methods;
2271 build_protocol_template ()
2273 tree decl_specs, field_decl, field_decl_chain;
2276 template = start_struct (RECORD_TYPE, get_identifier (UTAG_PROTOCOL));
2278 /* struct objc_class *isa; */
2280 decl_specs = build_tree_list (NULLT, xref_tag (RECORD_TYPE,
2281 get_identifier (UTAG_CLASS)));
2282 field_decl = build1 (INDIRECT_REF, NULLT, get_identifier ("isa"));
2283 field_decl = grokfield (input_filename, lineno, field_decl, decl_specs, NULLT);
2284 field_decl_chain = field_decl;
2286 /* char *protocol_name; */
2288 decl_specs = build_tree_list (NULLT, ridpointers[(int) RID_CHAR]);
2289 field_decl = build1 (INDIRECT_REF, NULLT, get_identifier ("protocol_name"));
2290 field_decl = grokfield (input_filename, lineno, field_decl, decl_specs, NULLT);
2291 chainon (field_decl_chain, field_decl);
2293 /* struct objc_protocol **protocol_list; */
2295 decl_specs = build_tree_list (NULLT, template);
2296 field_decl = build1 (INDIRECT_REF, NULLT, get_identifier ("protocol_list"));
2297 field_decl = build1 (INDIRECT_REF, NULLT, field_decl);
2298 field_decl = grokfield (input_filename, lineno, field_decl, decl_specs, NULLT);
2299 chainon (field_decl_chain, field_decl);
2301 /* struct objc_method_list *instance_methods; */
2303 decl_specs = build_tree_list (NULLT, xref_tag (RECORD_TYPE,
2304 get_identifier (UTAG_METHOD_PROTOTYPE_LIST)));
2305 field_decl = build1 (INDIRECT_REF, NULLT, get_identifier ("instance_methods"));
2306 field_decl = grokfield (input_filename, lineno, field_decl, decl_specs, NULLT);
2307 chainon (field_decl_chain, field_decl);
2309 /* struct objc_method_list *class_methods; */
2311 decl_specs = build_tree_list (NULLT, xref_tag (RECORD_TYPE,
2312 get_identifier (UTAG_METHOD_PROTOTYPE_LIST)));
2313 field_decl = build1 (INDIRECT_REF, NULLT, get_identifier ("class_methods"));
2314 field_decl = grokfield (input_filename, lineno, field_decl, decl_specs, NULLT);
2315 chainon (field_decl_chain, field_decl);
2317 return finish_struct (template, field_decl_chain);
2321 build_descriptor_table_initializer (type, entries)
2325 tree initlist = NULLT;
2329 tree eltlist = NULLT;
2331 eltlist = tree_cons (NULLT, build_selector (METHOD_SEL_NAME (entries)), NULLT);
2332 eltlist = tree_cons (NULLT, add_objc_string (METHOD_ENCODING (entries), meth_var_types), eltlist);
2334 initlist = tree_cons (NULLT, build_constructor (type, nreverse (eltlist)), initlist);
2336 entries = TREE_CHAIN (entries);
2340 return build_constructor (build_array_type (type, 0), nreverse (initlist));
2343 /* struct objc_method_prototype_list {
2345 struct objc_method_prototype {
2352 build_method_prototype_list_template (list_type, size)
2356 tree objc_ivar_list_record;
2357 tree decl_specs, field_decl, field_decl_chain;
2359 /* generate an unnamed struct definition */
2361 objc_ivar_list_record = start_struct (RECORD_TYPE, NULLT);
2363 /* int method_count; */
2365 decl_specs = build_tree_list (NULLT, ridpointers[(int) RID_INT]);
2366 field_decl = get_identifier ("method_count");
2368 field_decl = grokfield (input_filename, lineno, field_decl, decl_specs, NULLT);
2369 field_decl_chain = field_decl;
2371 /* struct objc_method method_list[]; */
2373 decl_specs = build_tree_list (NULLT, list_type);
2374 field_decl = build_nt (ARRAY_REF, get_identifier ("method_list"),
2375 build_int_2 (size, 0));
2377 field_decl = grokfield (input_filename, lineno, field_decl, decl_specs, NULLT);
2378 chainon (field_decl_chain, field_decl);
2380 finish_struct (objc_ivar_list_record, field_decl_chain);
2382 return objc_ivar_list_record;
2386 build_method_prototype_template ()
2389 tree decl_specs, field_decl, field_decl_chain;
2391 proto_record = start_struct (RECORD_TYPE, get_identifier (UTAG_METHOD_PROTOTYPE));
2393 #ifdef OBJC_INT_SELECTORS
2394 /* unsigned int _cmd; */
2395 decl_specs = tree_cons (NULLT, ridpointers[(int) RID_UNSIGNED], NULLT);
2396 decl_specs = tree_cons (NULLT, ridpointers[(int) RID_INT], decl_specs);
2397 field_decl = get_identifier ("_cmd");
2398 #else /* OBJC_INT_SELECTORS */
2399 /* struct objc_selector *_cmd; */
2400 decl_specs = tree_cons (NULLT, xref_tag (RECORD_TYPE,
2401 get_identifier (TAG_SELECTOR)), NULLT);
2402 field_decl = build1 (INDIRECT_REF, NULLT, get_identifier ("_cmd"));
2403 #endif /* OBJC_INT_SELECTORS */
2405 field_decl = grokfield (input_filename, lineno, field_decl, decl_specs, NULLT);
2406 field_decl_chain = field_decl;
2408 decl_specs = tree_cons (NULLT, ridpointers[(int) RID_CHAR], NULLT);
2409 field_decl = build1 (INDIRECT_REF, NULLT, get_identifier ("method_types"));
2410 field_decl = grokfield (input_filename, lineno, field_decl, decl_specs, NULLT);
2411 chainon (field_decl_chain, field_decl);
2413 finish_struct (proto_record, field_decl_chain);
2415 return proto_record;
2418 /* True if last call to forwarding_offset yielded a register offset */
2419 static int offset_is_register;
2422 forwarding_offset (parm)
2425 int offset_in_bytes;
2427 if (GET_CODE (DECL_INCOMING_RTL (parm)) == MEM)
2429 rtx addr = XEXP (DECL_INCOMING_RTL (parm), 0);
2431 /* ??? Here we assume that the parm address is indexed
2432 off the frame pointer or arg pointer.
2433 If that is not true, we produce meaningless results,
2434 but do not crash. */
2435 if (GET_CODE (addr) == PLUS
2436 && GET_CODE (XEXP (addr, 1)) == CONST_INT)
2437 offset_in_bytes = INTVAL (XEXP (addr, 1));
2439 offset_in_bytes = 0;
2441 offset_in_bytes += OBJC_FORWARDING_STACK_OFFSET;
2442 offset_is_register = 0;
2444 else if (GET_CODE (DECL_INCOMING_RTL (parm)) == REG)
2446 int regno = REGNO (DECL_INCOMING_RTL (parm));
2447 offset_in_bytes = apply_args_register_offset (regno);
2448 offset_is_register = 1;
2453 /* This is the case where the parm is passed as an int or double
2454 and it is converted to a char, short or float and stored back
2455 in the parmlist. In this case, describe the parm
2456 with the variable's declared type, and adjust the address
2457 if the least significant bytes (which we are using) are not
2459 #if BYTES_BIG_ENDIAN
2460 if (TREE_TYPE (parm) != DECL_ARG_TYPE (parm))
2461 offset_in_bytes += (GET_MODE_SIZE (TYPE_MODE (DECL_ARG_TYPE (parm)))
2462 - GET_MODE_SIZE (GET_MODE (DECL_RTL (parm))));
2465 return offset_in_bytes;
2469 encode_method_prototype (method_decl, func_decl)
2476 int max_parm_end = 0;
2480 /* `oneway' and 'bycopy', for remote object are the only method qualifiers */
2481 encode_type_qualifiers (TREE_PURPOSE (TREE_TYPE (method_decl)));
2484 encode_type (TREE_TYPE (TREE_TYPE (func_decl)),
2485 obstack_object_size (&util_obstack),
2486 OBJC_ENCODE_INLINE_DEFS);
2489 for (parms = DECL_ARGUMENTS (func_decl); parms;
2490 parms = TREE_CHAIN (parms))
2492 int parm_end = (forwarding_offset (parms)
2493 + (TREE_INT_CST_LOW (TYPE_SIZE (TREE_TYPE (parms)))
2496 if (!offset_is_register && max_parm_end < parm_end)
2497 max_parm_end = parm_end;
2500 stack_size = max_parm_end - OBJC_FORWARDING_MIN_OFFSET;
2502 sprintf (buf, "%d", stack_size);
2503 obstack_grow (&util_obstack, buf, strlen (buf));
2505 user_args = METHOD_SEL_ARGS (method_decl);
2507 /* argument types */
2508 for (parms = DECL_ARGUMENTS (func_decl), i = 0; parms;
2509 parms = TREE_CHAIN (parms), i++)
2511 /* process argument qualifiers for user supplied arguments */
2514 encode_type_qualifiers (TREE_PURPOSE (TREE_TYPE (user_args)));
2515 user_args = TREE_CHAIN (user_args);
2519 encode_type (TREE_TYPE (parms),
2520 obstack_object_size (&util_obstack),
2521 OBJC_ENCODE_INLINE_DEFS);
2523 /* compute offset */
2524 sprintf (buf, "%d", forwarding_offset (parms));
2526 /* indicate register */
2527 if (offset_is_register)
2528 obstack_1grow (&util_obstack, '+');
2530 obstack_grow (&util_obstack, buf, strlen (buf));
2533 obstack_1grow (&util_obstack, '\0');
2534 result = get_identifier (obstack_finish (&util_obstack));
2535 obstack_free (&util_obstack, util_firstobj);
2540 generate_descriptor_table (type, name, size, list, proto)
2547 tree sc_spec, decl_specs, decl, initlist;
2549 sc_spec = tree_cons (NULLT, ridpointers[(int) RID_STATIC], NULLT);
2550 decl_specs = tree_cons (NULLT, type, sc_spec);
2552 decl = start_decl (synth_id_with_class_suffix (name, proto),
2554 end_temporary_allocation ();
2556 initlist = build_tree_list (NULLT, build_int_2 (size, 0));
2557 initlist = tree_cons (NULLT, list, initlist);
2559 finish_decl (decl, build_constructor (type, nreverse (initlist)),
2566 generate_method_descriptors (protocol) /* generate_dispatch_tables */
2569 static tree objc_method_prototype_template;
2570 tree initlist, chain, method_list_template;
2571 tree cast, variable_length_type;
2574 if (!objc_method_prototype_template)
2575 objc_method_prototype_template = build_method_prototype_template ();
2577 cast = build_tree_list (build_tree_list (NULLT, xref_tag (RECORD_TYPE,
2578 get_identifier (UTAG_METHOD_PROTOTYPE_LIST))), NULLT);
2579 variable_length_type = groktypename (cast);
2581 chain = PROTOCOL_CLS_METHODS (protocol);
2584 size = list_length (chain);
2586 method_list_template
2587 = build_method_prototype_list_template (objc_method_prototype_template,
2591 = build_descriptor_table_initializer (objc_method_prototype_template,
2594 UOBJC_CLASS_METHODS_decl
2595 = generate_descriptor_table (method_list_template,
2596 "_OBJC_PROTOCOL_CLASS_METHODS",
2597 size, initlist, protocol);
2599 TREE_TYPE (UOBJC_CLASS_METHODS_decl) = variable_length_type;
2602 UOBJC_CLASS_METHODS_decl = 0;
2604 chain = PROTOCOL_NST_METHODS (protocol);
2607 size = list_length (chain);
2609 method_list_template
2610 = build_method_prototype_list_template (objc_method_prototype_template,
2613 = build_descriptor_table_initializer (objc_method_prototype_template,
2616 UOBJC_INSTANCE_METHODS_decl
2617 = generate_descriptor_table (method_list_template,
2618 "_OBJC_PROTOCOL_INSTANCE_METHODS",
2619 size, initlist, protocol);
2621 TREE_TYPE (UOBJC_INSTANCE_METHODS_decl) = variable_length_type;
2624 UOBJC_INSTANCE_METHODS_decl = 0;
2628 build_tmp_function_decl ()
2630 tree decl_specs, expr_decl, parms;
2634 /* struct objc_object *objc_xxx (id, SEL, ...); */
2636 decl_specs = build_tree_list (NULLT, objc_object_reference);
2637 push_parm_decl (build_tree_list (decl_specs,
2638 build1 (INDIRECT_REF, NULLT, NULLT)));
2640 decl_specs = build_tree_list (NULLT, xref_tag (RECORD_TYPE,
2641 get_identifier (TAG_SELECTOR)));
2642 expr_decl = build1 (INDIRECT_REF, NULLT, NULLT);
2644 push_parm_decl (build_tree_list (decl_specs, expr_decl));
2645 parms = get_parm_info (0);
2648 decl_specs = build_tree_list (NULLT, objc_object_reference);
2649 sprintf (buffer, "__objc_tmp_%x", xxx++);
2650 expr_decl = build_nt (CALL_EXPR, get_identifier (buffer), parms, NULLT);
2651 expr_decl = build1 (INDIRECT_REF, NULLT, expr_decl);
2653 return define_decl (expr_decl, decl_specs);
2657 hack_method_prototype (nst_methods, tmp_decl)
2663 /* Hack to avoid problem with static typing of self arg. */
2664 TREE_SET_CODE (nst_methods, CLASS_METHOD_DECL);
2665 start_method_def (nst_methods);
2666 TREE_SET_CODE (nst_methods, INSTANCE_METHOD_DECL);
2668 if (METHOD_ADD_ARGS (nst_methods) == (tree) 1)
2669 parms = get_parm_info (0); /* we have a `, ...' */
2671 parms = get_parm_info (1); /* place a `void_at_end' */
2673 poplevel (0, 0, 0); /* Must be called BEFORE start_function. */
2675 /* Usually called from store_parm_decls -> init_function_start. */
2677 DECL_ARGUMENTS (tmp_decl) = TREE_PURPOSE (parms);
2678 current_function_decl = tmp_decl;
2681 /* Code taken from start_function. */
2682 tree restype = TREE_TYPE (TREE_TYPE (tmp_decl));
2683 /* Promote the value to int before returning it. */
2684 if (TREE_CODE (restype) == INTEGER_TYPE
2685 && TYPE_PRECISION (restype) < TYPE_PRECISION (integer_type_node))
2686 restype = integer_type_node;
2687 DECL_RESULT (tmp_decl) = build_decl (RESULT_DECL, 0, restype);
2690 init_function_start (tmp_decl, "objc-act", 0);
2692 /* Typically called from expand_function_start for function definitions. */
2693 assign_parms (tmp_decl, 0);
2695 /* install return type */
2696 TREE_TYPE (TREE_TYPE (tmp_decl)) = groktypename (TREE_TYPE (nst_methods));
2701 generate_protocol_references (plist)
2706 /* forward declare protocols referenced */
2707 for (lproto = plist; lproto; lproto = TREE_CHAIN (lproto))
2709 tree proto = TREE_VALUE (lproto);
2711 if (TREE_CODE (proto) == PROTOCOL_INTERFACE_TYPE
2712 && PROTOCOL_NAME (proto))
2714 if (! PROTOCOL_FORWARD_DECL (proto))
2715 build_protocol_reference (proto);
2717 if (PROTOCOL_LIST (proto))
2718 generate_protocol_references (PROTOCOL_LIST (proto));
2724 generate_protocols ()
2726 tree p, tmp_decl, encoding;
2727 tree sc_spec, decl_specs, decl;
2728 tree initlist, protocol_name_expr, refs_decl, refs_expr;
2729 tree cast_type2 = 0;
2731 tmp_decl = build_tmp_function_decl ();
2733 if (! objc_protocol_template)
2734 objc_protocol_template = build_protocol_template ();
2736 /* if a protocol was directly referenced, pull in indirect references */
2737 for (p = protocol_chain; p; p = TREE_CHAIN (p))
2738 if (PROTOCOL_FORWARD_DECL (p) && PROTOCOL_LIST (p))
2739 generate_protocol_references (PROTOCOL_LIST (p));
2741 for (p = protocol_chain; p; p = TREE_CHAIN (p))
2743 tree nst_methods = PROTOCOL_NST_METHODS (p);
2744 tree cls_methods = PROTOCOL_CLS_METHODS (p);
2746 /* if protocol wasn't referenced, don't generate any code */
2747 if (! PROTOCOL_FORWARD_DECL (p))
2750 /* Make sure we link in the Protocol class. */
2751 add_class_reference (get_identifier (PROTOCOL_OBJECT_CLASS_NAME));
2755 if (! METHOD_ENCODING (nst_methods))
2757 hack_method_prototype (nst_methods, tmp_decl);
2758 encoding = encode_method_prototype (nst_methods, tmp_decl);
2759 METHOD_ENCODING (nst_methods) = encoding;
2761 nst_methods = TREE_CHAIN (nst_methods);
2766 if (! METHOD_ENCODING (cls_methods))
2768 hack_method_prototype (cls_methods, tmp_decl);
2769 encoding = encode_method_prototype (cls_methods, tmp_decl);
2770 METHOD_ENCODING (cls_methods) = encoding;
2773 cls_methods = TREE_CHAIN (cls_methods);
2775 generate_method_descriptors (p);
2777 if (PROTOCOL_LIST (p))
2778 refs_decl = generate_protocol_list (p);
2782 /* static struct objc_protocol _OBJC_PROTOCOL_<mumble>; */
2784 sc_spec = tree_cons (NULLT, ridpointers[(int) RID_STATIC], NULLT);
2785 decl_specs = tree_cons (NULLT, objc_protocol_template, sc_spec);
2787 decl = start_decl (synth_id_with_class_suffix ("_OBJC_PROTOCOL", p),
2789 end_temporary_allocation ();
2791 protocol_name_expr = add_objc_string (PROTOCOL_NAME (p), class_names);
2797 = groktypename (build_tree_list (build_tree_list (NULLT, objc_protocol_template),
2798 build1 (INDIRECT_REF, NULLT,
2799 build1 (INDIRECT_REF, NULLT, NULLT))));
2801 refs_expr = build_unary_op (ADDR_EXPR, refs_decl, 0);
2802 TREE_TYPE (refs_expr) = cast_type2;
2805 refs_expr = build_int_2 (0, 0);
2807 /* UOBJC_INSTANCE_METHODS_decl/UOBJC_CLASS_METHODS_decl are set
2808 by generate_method_descriptors, which is called above. */
2809 initlist = build_protocol_initializer (TREE_TYPE (decl),
2810 protocol_name_expr, refs_expr,
2811 UOBJC_INSTANCE_METHODS_decl,
2812 UOBJC_CLASS_METHODS_decl);
2813 finish_decl (decl, initlist, NULLT);
2815 /* Mark the decl as used to avoid "defined but not used" warning. */
2816 TREE_USED (decl) = 1;
2821 build_protocol_initializer (type, protocol_name, protocol_list,
2822 instance_methods, class_methods)
2826 tree instance_methods;
2829 tree initlist = NULLT, expr;
2830 static tree cast_type = 0;
2834 = groktypename (build_tree_list
2835 (build_tree_list (NULLT,
2836 xref_tag (RECORD_TYPE,
2837 get_identifier (UTAG_CLASS))),
2838 build1 (INDIRECT_REF, NULLT, NULLT)));
2840 /* filling the "isa" in with one allows the runtime system to
2841 detect that the version change...should remove before final release */
2843 expr = build_int_2 (PROTOCOL_VERSION, 0);
2844 TREE_TYPE (expr) = cast_type;
2845 initlist = tree_cons (NULLT, expr, initlist);
2846 initlist = tree_cons (NULLT, protocol_name, initlist);
2847 initlist = tree_cons (NULLT, protocol_list, initlist);
2849 if (!instance_methods)
2850 initlist = tree_cons (NULLT, build_int_2 (0, 0), initlist);
2853 expr = build_unary_op (ADDR_EXPR, instance_methods, 0);
2854 initlist = tree_cons (NULLT, expr, initlist);
2857 initlist = tree_cons (NULLT, build_int_2 (0, 0), initlist);
2860 expr = build_unary_op (ADDR_EXPR, class_methods, 0);
2861 initlist = tree_cons (NULLT, expr, initlist);
2863 return build_constructor (type, nreverse (initlist));
2865 /* end code generation for protocols... */
2867 /* struct objc_category {
2868 char *category_name;
2870 struct objc_method_list *instance_methods;
2871 struct objc_method_list *class_methods;
2872 struct objc_protocol_list *protocols;
2876 build_category_template ()
2878 tree decl_specs, field_decl, field_decl_chain;
2880 objc_category_template = start_struct (RECORD_TYPE,
2881 get_identifier (UTAG_CATEGORY));
2882 /* char *category_name; */
2884 decl_specs = build_tree_list (NULLT, ridpointers[(int) RID_CHAR]);
2885 field_decl = build1 (INDIRECT_REF, NULLT, get_identifier ("category_name"));
2886 field_decl = grokfield (input_filename, lineno, field_decl, decl_specs, NULLT);
2887 field_decl_chain = field_decl;
2889 /* char *class_name; */
2891 decl_specs = build_tree_list (NULLT, ridpointers[(int) RID_CHAR]);
2892 field_decl = build1 (INDIRECT_REF, NULLT, get_identifier ("class_name"));
2893 field_decl = grokfield (input_filename, lineno, field_decl, decl_specs, NULLT);
2894 chainon (field_decl_chain, field_decl);
2896 /* struct objc_method_list *instance_methods; */
2898 decl_specs = build_tree_list (NULLT, xref_tag (RECORD_TYPE,
2899 get_identifier (UTAG_METHOD_LIST)));
2900 field_decl = build1 (INDIRECT_REF, NULLT, get_identifier ("instance_methods"));
2901 field_decl = grokfield (input_filename, lineno, field_decl, decl_specs, NULLT);
2902 chainon (field_decl_chain, field_decl);
2904 /* struct objc_method_list *class_methods; */
2906 decl_specs = build_tree_list (NULLT, xref_tag (RECORD_TYPE,
2907 get_identifier (UTAG_METHOD_LIST)));
2908 field_decl = build1 (INDIRECT_REF, NULLT, get_identifier ("class_methods"));
2909 field_decl = grokfield (input_filename, lineno, field_decl, decl_specs, NULLT);
2910 chainon (field_decl_chain, field_decl);
2912 /* struct objc_protocol **protocol_list; */
2914 decl_specs = build_tree_list (NULLT, xref_tag (RECORD_TYPE,
2915 get_identifier (UTAG_PROTOCOL)));
2916 field_decl = build1 (INDIRECT_REF, NULLT, get_identifier ("protocol_list"));
2917 field_decl = build1 (INDIRECT_REF, NULLT, field_decl);
2918 field_decl = grokfield (input_filename, lineno, field_decl, decl_specs, NULLT)
2920 chainon (field_decl_chain, field_decl);
2922 finish_struct (objc_category_template, field_decl_chain);
2925 /* struct objc_selector {
2931 build_selector_template ()
2934 tree decl_specs, field_decl, field_decl_chain;
2936 objc_selector_template
2937 = start_struct (RECORD_TYPE, get_identifier (UTAG_SELECTOR));
2941 decl_specs = build_tree_list (NULLT, ridpointers[(int) RID_VOID]);
2942 field_decl = build1 (INDIRECT_REF, NULLT, get_identifier ("sel_id"));
2943 field_decl = grokfield (input_filename, lineno, field_decl, decl_specs, NULLT);
2944 field_decl_chain = field_decl;
2946 /* char *sel_type; */
2948 decl_specs = build_tree_list (NULLT, ridpointers[(int) RID_CHAR]);
2949 field_decl = build1 (INDIRECT_REF, NULLT, get_identifier ("sel_type"));
2950 field_decl = grokfield (input_filename, lineno, field_decl, decl_specs, NULLT);
2951 chainon (field_decl_chain, field_decl);
2953 finish_struct (objc_selector_template, field_decl_chain);
2956 /* struct objc_class {
2957 struct objc_class *isa;
2958 struct objc_class *super_class;
2963 struct objc_ivar_list *ivars;
2964 struct objc_method_list *methods;
2965 if (flag_next_runtime)
2966 struct objc_cache *cache;
2968 struct sarray *dtable;
2969 struct objc_class *subclass_list;
2970 struct objc_class *sibling_class;
2972 struct objc_protocol_list *protocols;
2976 build_class_template ()
2978 tree decl_specs, field_decl, field_decl_chain;
2980 objc_class_template = start_struct (RECORD_TYPE, get_identifier (UTAG_CLASS));
2982 /* struct objc_class *isa; */
2984 decl_specs = build_tree_list (NULLT, objc_class_template);
2985 field_decl = build1 (INDIRECT_REF, NULLT, get_identifier ("isa"));
2986 field_decl = grokfield (input_filename, lineno, field_decl, decl_specs, NULLT);
2987 field_decl_chain = field_decl;
2989 /* struct objc_class *super_class; */
2991 decl_specs = build_tree_list (NULLT, objc_class_template);
2992 field_decl = build1 (INDIRECT_REF, NULLT, get_identifier ("super_class"));
2993 field_decl = grokfield (input_filename, lineno, field_decl, decl_specs, NULLT);
2994 chainon (field_decl_chain, field_decl);
2998 decl_specs = build_tree_list (NULLT, ridpointers[(int) RID_CHAR]);
2999 field_decl = build1 (INDIRECT_REF, NULLT, get_identifier ("name"));
3000 field_decl = grokfield (input_filename, lineno, field_decl, decl_specs, NULLT);
3001 chainon (field_decl_chain, field_decl);
3005 decl_specs = build_tree_list (NULLT, ridpointers[(int) RID_LONG]);
3006 field_decl = get_identifier ("version");
3007 field_decl = grokfield (input_filename, lineno, field_decl, decl_specs, NULLT);
3008 chainon (field_decl_chain, field_decl);
3012 decl_specs = build_tree_list (NULLT, ridpointers[(int) RID_LONG]);
3013 field_decl = get_identifier ("info");
3014 field_decl = grokfield (input_filename, lineno, field_decl, decl_specs, NULLT);
3015 chainon (field_decl_chain, field_decl);
3017 /* long instance_size; */
3019 decl_specs = build_tree_list (NULLT, ridpointers[(int) RID_LONG]);
3020 field_decl = get_identifier ("instance_size");
3021 field_decl = grokfield (input_filename, lineno, field_decl, decl_specs, NULLT);
3022 chainon (field_decl_chain, field_decl);
3024 /* struct objc_ivar_list *ivars; */
3026 decl_specs = build_tree_list (NULLT, xref_tag (RECORD_TYPE,
3027 get_identifier (UTAG_IVAR_LIST)));
3028 field_decl = build1 (INDIRECT_REF, NULLT, get_identifier ("ivars"));
3029 field_decl = grokfield (input_filename, lineno, field_decl, decl_specs, NULLT);
3030 chainon (field_decl_chain, field_decl);
3032 /* struct objc_method_list *methods; */
3034 decl_specs = build_tree_list (NULLT, xref_tag (RECORD_TYPE,
3035 get_identifier (UTAG_METHOD_LIST)));
3036 field_decl = build1 (INDIRECT_REF, NULLT, get_identifier ("methods"));
3037 field_decl = grokfield (input_filename, lineno, field_decl, decl_specs, NULLT);
3038 chainon (field_decl_chain, field_decl);
3040 if (flag_next_runtime)
3042 /* struct objc_cache *cache; */
3044 decl_specs = build_tree_list (NULLT, xref_tag (RECORD_TYPE,
3045 get_identifier ("objc_cache")));
3046 field_decl = build1 (INDIRECT_REF, NULLT, get_identifier ("cache"));
3047 field_decl = grokfield (input_filename, lineno, field_decl, decl_specs, NULLT);
3048 chainon (field_decl_chain, field_decl);
3052 /* struct sarray *dtable; */
3054 decl_specs = build_tree_list (NULLT, xref_tag (RECORD_TYPE,
3055 get_identifier ("sarray")));
3056 field_decl = build1 (INDIRECT_REF, NULLT, get_identifier ("dtable"));
3057 field_decl = grokfield (input_filename, lineno, field_decl, decl_specs, NULLT);
3058 chainon (field_decl_chain, field_decl);
3060 /* struct objc_class *subclass_list; */
3062 decl_specs = build_tree_list (NULLT, objc_class_template);
3063 field_decl = build1 (INDIRECT_REF, NULLT, get_identifier ("subclass_list"));
3064 field_decl = grokfield (input_filename, lineno, field_decl, decl_specs, NULLT);
3065 chainon (field_decl_chain, field_decl);
3067 /* struct objc_class *sibling_class; */
3069 decl_specs = build_tree_list (NULLT, objc_class_template);
3070 field_decl = build1 (INDIRECT_REF, NULLT, get_identifier ("sibling_class"));
3071 field_decl = grokfield (input_filename, lineno, field_decl, decl_specs, NULLT);
3072 chainon (field_decl_chain, field_decl);
3075 /* struct objc_protocol **protocol_list; */
3077 decl_specs = build_tree_list (NULLT, xref_tag (RECORD_TYPE,
3078 get_identifier (UTAG_PROTOCOL)));
3079 field_decl = build1 (INDIRECT_REF, NULLT, get_identifier ("protocol_list"));
3080 field_decl = build1 (INDIRECT_REF, NULLT, field_decl);
3081 field_decl = grokfield (input_filename, lineno, field_decl, decl_specs, NULLT);
3082 chainon (field_decl_chain, field_decl);
3085 finish_struct (objc_class_template, field_decl_chain);
3088 /* Generate appropriate forward declarations for an implementation. */
3091 synth_forward_declarations ()
3093 tree sc_spec, decl_specs, an_id;
3095 /* extern struct objc_class _OBJC_CLASS_<my_name>; */
3097 an_id = synth_id_with_class_suffix ("_OBJC_CLASS", implementation_context);
3099 sc_spec = build_tree_list (NULLT, ridpointers[(int) RID_EXTERN]);
3100 decl_specs = tree_cons (NULLT, objc_class_template, sc_spec);
3101 UOBJC_CLASS_decl = define_decl (an_id, decl_specs);
3102 TREE_USED (UOBJC_CLASS_decl) = 1;
3104 /* extern struct objc_class _OBJC_METACLASS_<my_name>; */
3106 an_id = synth_id_with_class_suffix ("_OBJC_METACLASS",
3107 implementation_context);
3109 UOBJC_METACLASS_decl = define_decl (an_id, decl_specs);
3110 TREE_USED (UOBJC_METACLASS_decl) = 1;
3112 /* pre-build the following entities - for speed/convenience. */
3114 an_id = get_identifier ("super_class");
3115 ucls_super_ref = build_component_ref (UOBJC_CLASS_decl, an_id);
3116 uucls_super_ref = build_component_ref (UOBJC_METACLASS_decl, an_id);
3120 error_with_ivar (message, decl, rawdecl)
3127 report_error_function (DECL_SOURCE_FILE (decl));
3129 fprintf (stderr, "%s:%d: ",
3130 DECL_SOURCE_FILE (decl), DECL_SOURCE_LINE (decl));
3131 bzero (errbuf, BUFSIZE);
3132 fprintf (stderr, "%s `%s'\n", message, gen_declaration (rawdecl, errbuf));
3135 #define USERTYPE(t) (TREE_CODE (t) == RECORD_TYPE || \
3136 TREE_CODE (t) == UNION_TYPE || \
3137 TREE_CODE (t) == ENUMERAL_TYPE)
3140 check_ivars (inter, imp)
3144 tree intdecls = CLASS_IVARS (inter);
3145 tree impdecls = CLASS_IVARS (imp);
3146 tree rawintdecls = CLASS_RAW_IVARS (inter);
3147 tree rawimpdecls = CLASS_RAW_IVARS (imp);
3153 if (intdecls == 0 && impdecls == 0)
3155 if (intdecls == 0 || impdecls == 0)
3157 error ("inconsistent instance variable specification");
3160 t1 = TREE_TYPE (intdecls); t2 = TREE_TYPE (impdecls);
3162 if (!comptypes (t1, t2))
3164 if (DECL_NAME (intdecls) == DECL_NAME (impdecls))
3166 error_with_ivar ("conflicting instance variable type",
3167 impdecls, rawimpdecls);
3168 error_with_ivar ("previous declaration of",
3169 intdecls, rawintdecls);
3171 else /* both the type and the name don't match */
3173 error ("inconsistent instance variable specification");
3177 else if (DECL_NAME (intdecls) != DECL_NAME (impdecls))
3179 error_with_ivar ("conflicting instance variable name",
3180 impdecls, rawimpdecls);
3181 error_with_ivar ("previous declaration of",
3182 intdecls, rawintdecls);
3184 intdecls = TREE_CHAIN (intdecls);
3185 impdecls = TREE_CHAIN (impdecls);
3186 rawintdecls = TREE_CHAIN (rawintdecls);
3187 rawimpdecls = TREE_CHAIN (rawimpdecls);
3191 /* Set super_type to the data type node for struct objc_super *,
3192 first defining struct objc_super itself.
3193 This needs to be done just once per compilation. */
3196 build_super_template ()
3198 tree record, decl_specs, field_decl, field_decl_chain;
3200 record = start_struct (RECORD_TYPE, get_identifier (UTAG_SUPER));
3202 /* struct objc_object *self; */
3204 decl_specs = build_tree_list (NULLT, objc_object_reference);
3205 field_decl = get_identifier ("self");
3206 field_decl = build1 (INDIRECT_REF, NULLT, field_decl);
3207 field_decl = grokfield (input_filename, lineno,
3208 field_decl, decl_specs, NULLT);
3209 field_decl_chain = field_decl;
3211 /* struct objc_class *class; */
3213 decl_specs = get_identifier (UTAG_CLASS);
3214 decl_specs = build_tree_list (NULLT, xref_tag (RECORD_TYPE, decl_specs));
3215 field_decl = build1 (INDIRECT_REF, NULLT, get_identifier ("class"));
3217 field_decl = grokfield (input_filename, lineno,
3218 field_decl, decl_specs, NULLT);
3219 chainon (field_decl_chain, field_decl);
3221 finish_struct (record, field_decl_chain);
3223 /* `struct objc_super *' */
3224 super_type = groktypename (build_tree_list (build_tree_list (NULLT, record),
3225 build1 (INDIRECT_REF,
3230 /* struct objc_ivar {
3237 build_ivar_template ()
3239 tree objc_ivar_id, objc_ivar_record;
3240 tree decl_specs, field_decl, field_decl_chain;
3242 objc_ivar_id = get_identifier (UTAG_IVAR);
3243 objc_ivar_record = start_struct (RECORD_TYPE, objc_ivar_id);
3245 /* char *ivar_name; */
3247 decl_specs = build_tree_list (NULLT, ridpointers[(int) RID_CHAR]);
3248 field_decl = build1 (INDIRECT_REF, NULLT, get_identifier ("ivar_name"));
3250 field_decl = grokfield (input_filename, lineno, field_decl,
3252 field_decl_chain = field_decl;
3254 /* char *ivar_type; */
3256 decl_specs = build_tree_list (NULLT, ridpointers[(int) RID_CHAR]);
3257 field_decl = build1 (INDIRECT_REF, NULLT, get_identifier ("ivar_type"));
3259 field_decl = grokfield (input_filename, lineno, field_decl,
3261 chainon (field_decl_chain, field_decl);
3263 /* int ivar_offset; */
3265 decl_specs = build_tree_list (NULLT, ridpointers[(int) RID_INT]);
3266 field_decl = get_identifier ("ivar_offset");
3268 field_decl = grokfield (input_filename, lineno, field_decl,
3270 chainon (field_decl_chain, field_decl);
3272 finish_struct (objc_ivar_record, field_decl_chain);
3274 return objc_ivar_record;
3279 struct objc_ivar ivar_list[ivar_count];
3283 build_ivar_list_template (list_type, size)
3287 tree objc_ivar_list_record;
3288 tree decl_specs, field_decl, field_decl_chain;
3290 objc_ivar_list_record = start_struct (RECORD_TYPE, NULLT);
3292 /* int ivar_count; */
3294 decl_specs = build_tree_list (NULLT, ridpointers[(int) RID_INT]);
3295 field_decl = get_identifier ("ivar_count");
3297 field_decl = grokfield (input_filename, lineno, field_decl,
3299 field_decl_chain = field_decl;
3301 /* struct objc_ivar ivar_list[]; */
3303 decl_specs = build_tree_list (NULLT, list_type);
3304 field_decl = build_nt (ARRAY_REF, get_identifier ("ivar_list"),
3305 build_int_2 (size, 0));
3307 field_decl = grokfield (input_filename, lineno,
3308 field_decl, decl_specs, NULLT);
3309 chainon (field_decl_chain, field_decl);
3311 finish_struct (objc_ivar_list_record, field_decl_chain);
3313 return objc_ivar_list_record;
3319 struct objc_method method_list[method_count];
3323 build_method_list_template (list_type, size)
3327 tree objc_ivar_list_record;
3328 tree decl_specs, field_decl, field_decl_chain;
3330 objc_ivar_list_record = start_struct (RECORD_TYPE, NULLT);
3332 /* int method_next; */
3334 decl_specs = build_tree_list (NULLT,
3335 xref_tag (RECORD_TYPE,
3336 get_identifier (UTAG_METHOD_PROTOTYPE_LIST)));
3337 field_decl = build1 (INDIRECT_REF, NULLT, get_identifier ("method_next"));
3338 field_decl = grokfield (input_filename, lineno, field_decl, decl_specs, NULLT);
3339 field_decl_chain = field_decl;
3341 /* int method_count; */
3343 decl_specs = build_tree_list (NULLT, ridpointers[(int) RID_INT]);
3344 field_decl = get_identifier ("method_count");
3346 field_decl = grokfield (input_filename, lineno,
3347 field_decl, decl_specs, NULLT);
3348 chainon (field_decl_chain, field_decl);
3350 /* struct objc_method method_list[]; */
3352 decl_specs = build_tree_list (NULLT, list_type);
3353 field_decl = build_nt (ARRAY_REF, get_identifier ("method_list"),
3354 build_int_2 (size, 0));
3356 field_decl = grokfield (input_filename, lineno,
3357 field_decl, decl_specs, NULLT);
3358 chainon (field_decl_chain, field_decl);
3360 finish_struct (objc_ivar_list_record, field_decl_chain);
3362 return objc_ivar_list_record;
3366 build_ivar_list_initializer (type, field_decl)
3370 tree initlist = NULLT;
3377 if (DECL_NAME (field_decl))
3378 ivar = tree_cons (NULLT,
3379 add_objc_string (DECL_NAME (field_decl),
3383 /* unnamed bit-field ivar (yuck). */
3384 ivar = tree_cons (NULLT, build_int_2 (0, 0), ivar);
3387 encode_field_decl (field_decl,
3388 obstack_object_size (&util_obstack),
3389 OBJC_ENCODE_DONT_INLINE_DEFS);
3390 obstack_1grow (&util_obstack, 0); /* null terminate string */
3394 add_objc_string (get_identifier (obstack_finish (&util_obstack)),
3397 obstack_free (&util_obstack, util_firstobj);
3403 build_int_2 ((TREE_INT_CST_LOW (DECL_FIELD_BITPOS (field_decl))
3408 initlist = tree_cons (NULLT,
3409 build_constructor (type, nreverse (ivar)),
3412 field_decl = TREE_CHAIN (field_decl);
3416 return build_constructor (build_array_type (type, 0), nreverse (initlist));
3420 generate_ivars_list (type, name, size, list)
3426 tree sc_spec, decl_specs, decl, initlist;
3428 sc_spec = tree_cons (NULLT, ridpointers[(int) RID_STATIC], NULLT);
3429 decl_specs = tree_cons (NULLT, type, sc_spec);
3431 decl = start_decl (synth_id_with_class_suffix (name, implementation_context),
3433 end_temporary_allocation ();
3435 initlist = build_tree_list (NULLT, build_int_2 (size, 0));
3436 initlist = tree_cons (NULLT, list, initlist);
3439 build_constructor (TREE_TYPE (decl), nreverse (initlist)),
3446 generate_ivar_lists ()
3448 tree initlist, ivar_list_template, chain;
3449 tree cast, variable_length_type;
3452 generating_instance_variables = 1;
3454 if (!objc_ivar_template)
3455 objc_ivar_template = build_ivar_template ();
3459 (build_tree_list (NULLT, xref_tag (RECORD_TYPE,
3460 get_identifier (UTAG_IVAR_LIST))),
3462 variable_length_type = groktypename (cast);
3464 /* only generate class variables for the root of the inheritance
3465 hierarchy since these will be the same for every class */
3467 if (CLASS_SUPER_NAME (implementation_template) == NULLT
3468 && (chain = TYPE_FIELDS (objc_class_template)))
3470 size = list_length (chain);
3472 ivar_list_template = build_ivar_list_template (objc_ivar_template, size);
3473 initlist = build_ivar_list_initializer (objc_ivar_template, chain);
3475 UOBJC_CLASS_VARIABLES_decl
3476 = generate_ivars_list (ivar_list_template, "_OBJC_CLASS_VARIABLES",
3479 TREE_TYPE (UOBJC_CLASS_VARIABLES_decl) = variable_length_type;
3482 UOBJC_CLASS_VARIABLES_decl = 0;
3484 chain = CLASS_IVARS (implementation_template);
3487 size = list_length (chain);
3488 ivar_list_template = build_ivar_list_template (objc_ivar_template, size);
3489 initlist = build_ivar_list_initializer (objc_ivar_template, chain);
3491 UOBJC_INSTANCE_VARIABLES_decl
3492 = generate_ivars_list (ivar_list_template, "_OBJC_INSTANCE_VARIABLES",
3495 TREE_TYPE (UOBJC_INSTANCE_VARIABLES_decl) = variable_length_type;
3498 UOBJC_INSTANCE_VARIABLES_decl = 0;
3500 generating_instance_variables = 0;
3504 build_dispatch_table_initializer (type, entries)
3508 tree initlist = NULLT;
3512 tree elemlist = NULLT;
3514 elemlist = tree_cons (NULLT, build_selector (METHOD_SEL_NAME (entries)),
3517 elemlist = tree_cons (NULLT, add_objc_string (METHOD_ENCODING (entries),
3521 elemlist = tree_cons (NULLT,
3522 build_unary_op (ADDR_EXPR, METHOD_DEFINITION (entries), 1),
3525 initlist = tree_cons (NULLT,
3526 build_constructor (type, nreverse (elemlist)),
3529 entries = TREE_CHAIN (entries);
3533 return build_constructor (build_array_type (type, 0), nreverse (initlist));
3536 /* To accomplish method prototyping without generating all kinds of
3537 inane warnings, the definition of the dispatch table entries were
3540 struct objc_method { SEL _cmd; ...; id (*_imp)(); };
3542 struct objc_method { SEL _cmd; ...; void *_imp; }; */
3545 build_method_template ()
3548 tree decl_specs, field_decl, field_decl_chain;
3550 _SLT_record = start_struct (RECORD_TYPE, get_identifier (UTAG_METHOD));
3552 #ifdef OBJC_INT_SELECTORS
3553 /* unsigned int _cmd; */
3554 decl_specs = tree_cons (NULLT, ridpointers[(int) RID_UNSIGNED], NULLT);
3555 decl_specs = tree_cons (NULLT, ridpointers[(int) RID_INT], decl_specs);
3556 field_decl = get_identifier ("_cmd");
3557 #else /* not OBJC_INT_SELECTORS */
3558 /* struct objc_selector *_cmd; */
3559 decl_specs = tree_cons (NULLT,
3560 xref_tag (RECORD_TYPE,
3561 get_identifier (TAG_SELECTOR)),
3563 field_decl = build1 (INDIRECT_REF, NULLT, get_identifier ("_cmd"));
3564 #endif /* not OBJC_INT_SELECTORS */
3566 field_decl = grokfield (input_filename, lineno, field_decl, decl_specs, NULLT);
3567 field_decl_chain = field_decl;
3569 decl_specs = tree_cons (NULLT, ridpointers[(int) RID_CHAR], NULLT);
3570 field_decl = build1 (INDIRECT_REF, NULLT, get_identifier ("method_types"));
3571 field_decl = grokfield (input_filename, lineno, field_decl, decl_specs, NULLT);
3572 chainon (field_decl_chain, field_decl);
3576 decl_specs = tree_cons (NULLT, ridpointers[(int) RID_VOID], NULLT);
3577 field_decl = build1 (INDIRECT_REF, NULLT, get_identifier ("_imp"));
3578 field_decl = grokfield (input_filename, lineno, field_decl, decl_specs, NULLT);
3579 chainon (field_decl_chain, field_decl);
3581 finish_struct (_SLT_record, field_decl_chain);
3588 generate_dispatch_table (type, name, size, list)
3594 tree sc_spec, decl_specs, decl, initlist;
3596 sc_spec = tree_cons (NULLT, ridpointers[(int) RID_STATIC], NULLT);
3597 decl_specs = tree_cons (NULLT, type, sc_spec);
3599 decl = start_decl (synth_id_with_class_suffix (name, implementation_context),
3601 end_temporary_allocation ();
3603 initlist = build_tree_list (NULLT, build_int_2 (0, 0));
3604 initlist = tree_cons (NULLT, build_int_2 (size, 0), initlist);
3605 initlist = tree_cons (NULLT, list, initlist);
3608 build_constructor (TREE_TYPE (decl), nreverse (initlist)),
3615 generate_dispatch_tables ()
3617 tree initlist, chain, method_list_template;
3618 tree cast, variable_length_type;
3621 if (!objc_method_template)
3622 objc_method_template = build_method_template ();
3626 (build_tree_list (NULLT, xref_tag (RECORD_TYPE,
3627 get_identifier (UTAG_METHOD_LIST))),
3629 variable_length_type = groktypename (cast);
3631 chain = CLASS_CLS_METHODS (implementation_context);
3634 size = list_length (chain);
3636 method_list_template = build_method_list_template (objc_method_template, size);
3637 initlist = build_dispatch_table_initializer (objc_method_template, chain);
3639 UOBJC_CLASS_METHODS_decl
3640 = generate_dispatch_table (method_list_template,
3641 ((TREE_CODE (implementation_context)
3642 == CLASS_IMPLEMENTATION_TYPE)
3643 ? "_OBJC_CLASS_METHODS"
3644 : "_OBJC_CATEGORY_CLASS_METHODS"),
3647 TREE_TYPE (UOBJC_CLASS_METHODS_decl) = variable_length_type;
3650 UOBJC_CLASS_METHODS_decl = 0;
3652 chain = CLASS_NST_METHODS (implementation_context);
3655 size = list_length (chain);
3657 method_list_template = build_method_list_template (objc_method_template, size);
3658 initlist = build_dispatch_table_initializer (objc_method_template, chain);
3660 if (TREE_CODE (implementation_context) == CLASS_IMPLEMENTATION_TYPE)
3661 UOBJC_INSTANCE_METHODS_decl
3662 = generate_dispatch_table (method_list_template,
3663 "_OBJC_INSTANCE_METHODS",
3666 /* we have a category */
3667 UOBJC_INSTANCE_METHODS_decl
3668 = generate_dispatch_table (method_list_template,
3669 "_OBJC_CATEGORY_INSTANCE_METHODS",
3672 TREE_TYPE (UOBJC_INSTANCE_METHODS_decl) = variable_length_type;
3675 UOBJC_INSTANCE_METHODS_decl = 0;
3679 generate_protocol_list (i_or_p)
3682 static tree cast_type = 0;
3683 tree initlist, decl_specs, sc_spec;
3684 tree refs_decl, expr_decl, lproto, e, plist;
3687 if (TREE_CODE (i_or_p) == CLASS_INTERFACE_TYPE
3688 || TREE_CODE (i_or_p) == CATEGORY_INTERFACE_TYPE)
3689 plist = CLASS_PROTOCOL_LIST (i_or_p);
3690 else if (TREE_CODE (i_or_p) == PROTOCOL_INTERFACE_TYPE)
3691 plist = PROTOCOL_LIST (i_or_p);
3699 (build_tree_list (NULLT,
3700 xref_tag (RECORD_TYPE,
3701 get_identifier (UTAG_PROTOCOL))),
3702 build1 (INDIRECT_REF, NULLT, NULLT)));
3705 for (lproto = plist; lproto; lproto = TREE_CHAIN (lproto))
3706 if (TREE_CODE (TREE_VALUE (lproto)) == PROTOCOL_INTERFACE_TYPE
3707 && PROTOCOL_FORWARD_DECL (TREE_VALUE (lproto)))
3710 /* build initializer */
3711 initlist = tree_cons (NULLT, build_int_2 (0, 0), NULLT);
3713 e = build_int_2 (size, 0);
3714 TREE_TYPE (e) = cast_type;
3715 initlist = tree_cons (NULLT, e, initlist);
3717 for (lproto = plist; lproto; lproto = TREE_CHAIN (lproto))
3719 tree pval = TREE_VALUE (lproto);
3721 if (TREE_CODE (pval) == PROTOCOL_INTERFACE_TYPE
3722 && PROTOCOL_FORWARD_DECL (pval))
3724 e = build_unary_op (ADDR_EXPR, PROTOCOL_FORWARD_DECL (pval), 0);
3725 initlist = tree_cons (NULLT, e, initlist);
3729 /* static struct objc_protocol *refs[n]; */
3731 sc_spec = tree_cons (NULLT, ridpointers[(int) RID_STATIC], NULLT);
3732 decl_specs = tree_cons (NULLT, xref_tag (RECORD_TYPE,
3733 get_identifier (UTAG_PROTOCOL)),
3736 if (TREE_CODE (i_or_p) == PROTOCOL_INTERFACE_TYPE)
3737 expr_decl = build_nt (ARRAY_REF,
3738 synth_id_with_class_suffix ("_OBJC_PROTOCOL_REFS",
3740 build_int_2 (size + 2, 0));
3741 else if (TREE_CODE (i_or_p) == CLASS_INTERFACE_TYPE)
3742 expr_decl = build_nt (ARRAY_REF,
3743 synth_id_with_class_suffix ("_OBJC_CLASS_PROTOCOLS",
3745 build_int_2 (size + 2, 0));
3746 else if (TREE_CODE (i_or_p) == CATEGORY_INTERFACE_TYPE)
3747 expr_decl = build_nt (ARRAY_REF,
3748 synth_id_with_class_suffix ("_OBJC_CATEGORY_PROTOCOLS",
3750 build_int_2 (size + 2, 0));
3752 expr_decl = build1 (INDIRECT_REF, NULLT, expr_decl);
3754 refs_decl = start_decl (expr_decl, decl_specs, 1);
3755 end_temporary_allocation ();
3757 finish_decl (refs_decl, build_constructor (TREE_TYPE (refs_decl),
3758 nreverse (initlist)),
3765 build_category_initializer (type, cat_name, class_name,
3766 instance_methods, class_methods, protocol_list)
3770 tree instance_methods;
3774 tree initlist = NULLT, expr;
3776 initlist = tree_cons (NULLT, cat_name, initlist);
3777 initlist = tree_cons (NULLT, class_name, initlist);
3779 if (!instance_methods)
3780 initlist = tree_cons (NULLT, build_int_2 (0, 0), initlist);
3783 expr = build_unary_op (ADDR_EXPR, instance_methods, 0);
3784 initlist = tree_cons (NULLT, expr, initlist);
3787 initlist = tree_cons (NULLT, build_int_2 (0, 0), initlist);
3790 expr = build_unary_op (ADDR_EXPR, class_methods, 0);
3791 initlist = tree_cons (NULLT, expr, initlist);
3794 /* protocol_list = */
3796 initlist = tree_cons (NULLT, build_int_2 (0, 0), initlist);
3799 static tree cast_type2;
3805 (build_tree_list (NULLT,
3806 xref_tag (RECORD_TYPE,
3807 get_identifier (UTAG_PROTOCOL))),
3808 build1 (INDIRECT_REF, NULLT,
3809 build1 (INDIRECT_REF, NULLT, NULLT))));
3811 expr = build_unary_op (ADDR_EXPR, protocol_list, 0);
3812 TREE_TYPE (expr) = cast_type2;
3813 initlist = tree_cons (NULLT, expr, initlist);
3816 return build_constructor (type, nreverse (initlist));
3819 /* struct objc_class {
3820 struct objc_class *isa;
3821 struct objc_class *super_class;
3826 struct objc_ivar_list *ivars;
3827 struct objc_method_list *methods;
3828 if (flag_next_runtime)
3829 struct objc_cache *cache;
3831 struct sarray *dtable;
3832 struct objc_class *subclass_list;
3833 struct objc_class *sibling_class;
3835 struct objc_protocol_list *protocols;
3839 build_shared_structure_initializer (type, isa, super, name, size, status,
3840 dispatch_table, ivar_list, protocol_list)
3847 tree dispatch_table;
3851 tree initlist = NULLT, expr;
3854 initlist = tree_cons (NULLT, isa, initlist);
3857 initlist = tree_cons (NULLT, super, initlist);
3860 initlist = tree_cons (NULLT, default_conversion (name), initlist);
3863 initlist = tree_cons (NULLT, build_int_2 (0, 0), initlist);
3866 initlist = tree_cons (NULLT, build_int_2 (status, 0), initlist);
3868 /* instance_size = */
3869 initlist = tree_cons (NULLT, size, initlist);
3871 /* objc_ivar_list = */
3873 initlist = tree_cons (NULLT, build_int_2 (0, 0), initlist);
3876 expr = build_unary_op (ADDR_EXPR, ivar_list, 0);
3877 initlist = tree_cons (NULLT, expr, initlist);
3880 /* objc_method_list = */
3881 if (!dispatch_table)
3882 initlist = tree_cons (NULLT, build_int_2 (0, 0), initlist);
3885 expr = build_unary_op (ADDR_EXPR, dispatch_table, 0);
3886 initlist = tree_cons (NULLT, expr, initlist);
3889 if (flag_next_runtime)
3890 /* method_cache = */
3891 initlist = tree_cons (NULLT, build_int_2 (0, 0), initlist);
3895 initlist = tree_cons (NULLT, build_int_2 (0, 0), initlist);
3897 /* subclass_list = */
3898 initlist = tree_cons (NULLT, build_int_2 (0, 0), initlist);
3900 /* sibling_class = */
3901 initlist = tree_cons (NULLT, build_int_2 (0, 0), initlist);
3904 /* protocol_list = */
3905 if (! protocol_list)
3906 initlist = tree_cons (NULLT, build_int_2 (0, 0), initlist);
3909 static tree cast_type2;
3915 (build_tree_list (NULLT,
3916 xref_tag (RECORD_TYPE,
3917 get_identifier (UTAG_PROTOCOL))),
3918 build1 (INDIRECT_REF, NULLT,
3919 build1 (INDIRECT_REF, NULLT, NULLT))));
3921 expr = build_unary_op (ADDR_EXPR, protocol_list, 0);
3922 TREE_TYPE (expr) = cast_type2;
3923 initlist = tree_cons (NULLT, expr, initlist);
3926 return build_constructor (type, nreverse (initlist));
3929 /* static struct objc_category _OBJC_CATEGORY_<name> = { ... }; */
3931 generate_category (cat)
3934 tree sc_spec, decl_specs, decl;
3935 tree initlist, cat_name_expr, class_name_expr;
3936 tree protocol_decl, category;
3938 add_class_reference (CLASS_NAME (cat));
3939 cat_name_expr = add_objc_string (CLASS_SUPER_NAME (cat), class_names);
3941 class_name_expr = add_objc_string (CLASS_NAME (cat), class_names);
3943 category = CLASS_CATEGORY_LIST (implementation_template);
3945 /* find the category interface from the class it is associated with */
3948 if (CLASS_SUPER_NAME (cat) == CLASS_SUPER_NAME (category))
3950 category = CLASS_CATEGORY_LIST (category);
3953 if (category && CLASS_PROTOCOL_LIST (category))
3955 generate_protocol_references (CLASS_PROTOCOL_LIST (category));
3956 protocol_decl = generate_protocol_list (category);
3961 sc_spec = tree_cons (NULLT, ridpointers[(int) RID_STATIC], NULLT);
3962 decl_specs = tree_cons (NULLT, objc_category_template, sc_spec);
3964 decl = start_decl (synth_id_with_class_suffix ("_OBJC_CATEGORY",
3965 implementation_context),
3967 end_temporary_allocation ();
3969 initlist = build_category_initializer (TREE_TYPE (decl),
3970 cat_name_expr, class_name_expr,
3971 UOBJC_INSTANCE_METHODS_decl,
3972 UOBJC_CLASS_METHODS_decl,
3975 TREE_USED (decl) = 1;
3976 finish_decl (decl, initlist, NULLT);
3979 /* static struct objc_class _OBJC_METACLASS_Foo={ ... };
3980 static struct objc_class _OBJC_CLASS_Foo={ ... }; */
3983 generate_shared_structures ()
3985 tree sc_spec, decl_specs, decl;
3986 tree name_expr, super_expr, root_expr;
3987 tree my_root_id = NULLT, my_super_id = NULLT;
3988 tree cast_type, initlist, protocol_decl;
3990 my_super_id = CLASS_SUPER_NAME (implementation_template);
3993 add_class_reference (my_super_id);
3995 /* Compute "my_root_id" - this is required for code generation.
3996 the "isa" for all meta class structures points to the root of
3997 the inheritance hierarchy (e.g. "__Object")... */
3998 my_root_id = my_super_id;
4001 tree my_root_int = lookup_interface (my_root_id);
4003 if (my_root_int && CLASS_SUPER_NAME (my_root_int))
4004 my_root_id = CLASS_SUPER_NAME (my_root_int);
4010 else /* no super class */
4012 my_root_id = CLASS_NAME (implementation_template);
4016 = groktypename (build_tree_list (build_tree_list (NULLT,
4017 objc_class_template),
4018 build1 (INDIRECT_REF, NULLT, NULLT)));
4020 name_expr = add_objc_string (CLASS_NAME (implementation_template),
4023 /* install class `isa' and `super' pointers at runtime */
4026 super_expr = add_objc_string (my_super_id, class_names);
4027 super_expr = build_c_cast (cast_type, super_expr); /* cast! */
4030 super_expr = build_int_2 (0, 0);
4032 root_expr = add_objc_string (my_root_id, class_names);
4033 root_expr = build_c_cast (cast_type, root_expr); /* cast! */
4035 if (CLASS_PROTOCOL_LIST (implementation_template))
4037 generate_protocol_references (CLASS_PROTOCOL_LIST (implementation_template));
4038 protocol_decl = generate_protocol_list (implementation_template);
4043 /* static struct objc_class _OBJC_METACLASS_Foo = { ... }; */
4045 sc_spec = build_tree_list (NULLT, ridpointers[(int) RID_STATIC]);
4046 decl_specs = tree_cons (NULLT, objc_class_template, sc_spec);
4048 decl = start_decl (DECL_NAME (UOBJC_METACLASS_decl), decl_specs, 1);
4049 end_temporary_allocation ();
4052 = build_shared_structure_initializer
4054 root_expr, super_expr, name_expr,
4055 build_int_2 ((TREE_INT_CST_LOW (TYPE_SIZE (objc_class_template))
4059 UOBJC_CLASS_METHODS_decl,
4060 UOBJC_CLASS_VARIABLES_decl,
4063 finish_decl (decl, initlist, NULLT);
4065 /* static struct objc_class _OBJC_CLASS_Foo={ ... }; */
4067 decl = start_decl (DECL_NAME (UOBJC_CLASS_decl), decl_specs, 1);
4068 end_temporary_allocation ();
4071 = build_shared_structure_initializer
4073 build_unary_op (ADDR_EXPR, UOBJC_METACLASS_decl, 0),
4074 super_expr, name_expr,
4075 build_int_2 ((TREE_INT_CST_LOW (TYPE_SIZE (CLASS_STATIC_TEMPLATE (implementation_template)))
4079 UOBJC_INSTANCE_METHODS_decl,
4080 UOBJC_INSTANCE_VARIABLES_decl,
4083 finish_decl (decl, initlist, NULLT);
4087 synth_id_with_class_suffix (preamble, ctxt)
4092 if (TREE_CODE (ctxt) == CLASS_IMPLEMENTATION_TYPE
4093 || TREE_CODE (ctxt) == CLASS_INTERFACE_TYPE)
4096 = IDENTIFIER_POINTER (CLASS_NAME (implementation_context));
4097 string = (char *) alloca (strlen (preamble) + strlen (class_name) + 3);
4098 sprintf (string, "%s_%s", preamble,
4099 IDENTIFIER_POINTER (CLASS_NAME (ctxt)));
4101 else if (TREE_CODE (ctxt) == CATEGORY_IMPLEMENTATION_TYPE
4102 || TREE_CODE (ctxt) == CATEGORY_INTERFACE_TYPE)
4104 /* we have a category */
4106 = IDENTIFIER_POINTER (CLASS_NAME (implementation_context));
4107 char *class_super_name
4108 = IDENTIFIER_POINTER (CLASS_SUPER_NAME (implementation_context));
4109 string = (char *) alloca (strlen (preamble)
4110 + strlen (class_name)
4111 + strlen (class_super_name)
4113 sprintf (string, "%s_%s_%s", preamble, class_name, class_super_name);
4115 else if (TREE_CODE (ctxt) == PROTOCOL_INTERFACE_TYPE)
4117 char *protocol_name = IDENTIFIER_POINTER (PROTOCOL_NAME (ctxt));
4118 string = (char *) alloca (strlen (preamble) + strlen (protocol_name) + 3);
4119 sprintf (string, "%s_%s", preamble, protocol_name);
4121 return get_identifier (string);
4125 is_objc_type_qualifier (node)
4128 return (TREE_CODE (node) == IDENTIFIER_NODE
4129 && (node == ridpointers [(int) RID_CONST]
4130 || node == ridpointers [(int) RID_VOLATILE]
4131 || node == ridpointers [(int) RID_IN]
4132 || node == ridpointers [(int) RID_OUT]
4133 || node == ridpointers [(int) RID_INOUT]
4134 || node == ridpointers [(int) RID_BYCOPY]
4135 || node == ridpointers [(int) RID_ONEWAY]));
4138 /* If type is empty or only type qualifiers are present, add default
4139 type of id (otherwise grokdeclarator will default to int). */
4142 adjust_type_for_id_default (type)
4145 tree declspecs, chain;
4148 return build_tree_list (build_tree_list (NULLT, objc_object_reference),
4149 build1 (INDIRECT_REF, NULLT, NULLT));
4151 declspecs = TREE_PURPOSE (type);
4153 /* Determine if a typespec is present. */
4154 for (chain = declspecs;
4156 chain = TREE_CHAIN (chain))
4158 if (!is_objc_type_qualifier (TREE_VALUE (chain)))
4162 return build_tree_list (tree_cons (NULLT, objc_object_reference, declspecs),
4163 build1 (INDIRECT_REF, NULLT, NULLT));
4168 selector ':' '(' typename ')' identifier
4171 transform an Objective-C keyword argument into
4172 the C equivalent parameter declarator.
4174 in: key_name, an "identifier_node" (optional).
4175 arg_type, a "tree_list" (optional).
4176 arg_name, an "identifier_node".
4178 note: it would be really nice to strongly type the preceding
4179 arguments in the function prototype; however, then i
4180 could not use the "accessor" macros defined in "tree.h".
4182 out: an instance of "keyword_decl". */
4185 build_keyword_decl (key_name, arg_type, arg_name)
4192 /* if no type is specified, default to "id" */
4193 arg_type = adjust_type_for_id_default (arg_type);
4195 keyword_decl = make_node (KEYWORD_DECL);
4197 TREE_TYPE (keyword_decl) = arg_type;
4198 KEYWORD_ARG_NAME (keyword_decl) = arg_name;
4199 KEYWORD_KEY_NAME (keyword_decl) = key_name;
4201 return keyword_decl;
4204 /* Given a chain of keyword_decl's, synthesize the full keyword selector. */
4206 build_keyword_selector (selector)
4210 tree key_chain, key_name;
4213 for (key_chain = selector; key_chain; key_chain = TREE_CHAIN (key_chain))
4215 if (TREE_CODE (selector) == KEYWORD_DECL)
4216 key_name = KEYWORD_KEY_NAME (key_chain);
4217 else if (TREE_CODE (selector) == TREE_LIST)
4218 key_name = TREE_PURPOSE (key_chain);
4221 len += IDENTIFIER_LENGTH (key_name) + 1;
4222 else /* just a ':' arg */
4225 buf = (char *)alloca (len + 1);
4226 bzero (buf, len + 1);
4228 for (key_chain = selector; key_chain; key_chain = TREE_CHAIN (key_chain))
4230 if (TREE_CODE (selector) == KEYWORD_DECL)
4231 key_name = KEYWORD_KEY_NAME (key_chain);
4232 else if (TREE_CODE (selector) == TREE_LIST)
4233 key_name = TREE_PURPOSE (key_chain);
4236 strcat (buf, IDENTIFIER_POINTER (key_name));
4239 return get_identifier (buf);
4242 /* used for declarations and definitions */
4245 build_method_decl (code, ret_type, selector, add_args)
4246 enum tree_code code;
4253 /* if no type is specified, default to "id" */
4254 ret_type = adjust_type_for_id_default (ret_type);
4256 method_decl = make_node (code);
4257 TREE_TYPE (method_decl) = ret_type;
4259 /* If we have a keyword selector, create an identifier_node that
4260 represents the full selector name (`:' included)... */
4261 if (TREE_CODE (selector) == KEYWORD_DECL)
4263 METHOD_SEL_NAME (method_decl) = build_keyword_selector (selector);
4264 METHOD_SEL_ARGS (method_decl) = selector;
4265 METHOD_ADD_ARGS (method_decl) = add_args;
4269 METHOD_SEL_NAME (method_decl) = selector;
4270 METHOD_SEL_ARGS (method_decl) = NULLT;
4271 METHOD_ADD_ARGS (method_decl) = NULLT;
4277 #define METHOD_DEF 0
4278 #define METHOD_REF 1
4280 /* Used by `build_message_expr' and `comp_method_types'. Return an
4281 argument list for method METH. CONTEXT is either METHOD_DEF or
4282 METHOD_REF, saying whether we are trying to define a method or call
4283 one. SUPERFLAG says this is for a send to super; this makes a
4284 difference for the NeXT calling sequence in which the lookup and
4285 the method call are done together. */
4288 get_arg_type_list (meth, context, superflag)
4296 if (flag_next_runtime && superflag)
4297 arglist = build_tree_list (NULLT, super_type);
4298 else if (context == METHOD_DEF)
4299 arglist = build_tree_list (NULLT, TREE_TYPE (self_decl));
4301 arglist = build_tree_list (NULLT, id_type);
4303 /* selector type - will eventually change to `int' */
4304 chainon (arglist, build_tree_list (NULLT, selector_type));
4306 /* build a list of argument types */
4307 for (akey = METHOD_SEL_ARGS (meth); akey; akey = TREE_CHAIN (akey))
4309 tree arg_decl = groktypename_in_parm_context (TREE_TYPE (akey));
4310 chainon (arglist, build_tree_list (NULLT, TREE_TYPE (arg_decl)));
4313 if (METHOD_ADD_ARGS (meth) == (tree)1)
4314 /* We have a `, ...' immediately following the selector,
4315 finalize the arglist...simulate get_parm_info (0). */
4317 else if (METHOD_ADD_ARGS (meth))
4319 /* we have a variable length selector */
4320 tree add_arg_list = TREE_CHAIN (METHOD_ADD_ARGS (meth));
4321 chainon (arglist, add_arg_list);
4324 /* finalize the arglist...simulate get_parm_info (1) */
4325 chainon (arglist, build_tree_list (NULLT, void_type_node));
4331 check_duplicates (hsh)
4342 /* we have two methods with the same name and different types */
4344 char type = (TREE_CODE (meth) == INSTANCE_METHOD_DECL) ? '-' : '+';
4346 warning ("multiple declarations for method `%s'",
4347 IDENTIFIER_POINTER (METHOD_SEL_NAME (meth)));
4349 warn_with_method ("using", type, meth);
4350 for (loop = hsh->list; loop; loop = loop->next)
4351 warn_with_method ("also found", type, loop->value);
4357 /* If RECEIVER is a class reference, return the identifier node for the
4358 referenced class. RECEIVER is created by get_class_reference, so we
4359 check the exact form created depending on which runtimes are used. */
4362 receiver_is_class_object (receiver)
4365 tree chain, exp, arg;
4366 if (flag_next_runtime)
4368 /* The receiver is a variable created by build_class_reference_decl. */
4369 if (TREE_CODE (receiver) == VAR_DECL
4370 && TREE_TYPE (receiver) == objc_class_type)
4371 /* Look up the identifier. */
4372 for (chain = cls_ref_chain; chain; chain = TREE_CHAIN (chain))
4373 if (TREE_PURPOSE (chain) == receiver)
4374 return TREE_VALUE (chain);
4378 /* The receiver is a function call that returns an id. Check if
4379 it is a call to objc_getClass, if so, pick up the class name. */
4380 if ((exp = TREE_OPERAND (receiver, 0))
4381 && TREE_CODE (exp) == ADDR_EXPR
4382 && (exp = TREE_OPERAND (exp, 0))
4383 && TREE_CODE (exp) == FUNCTION_DECL
4384 && exp == objc_get_class_decl
4385 /* we have a call to objc_getClass! */
4386 && (arg = TREE_OPERAND (receiver, 1))
4387 && TREE_CODE (arg) == TREE_LIST
4388 && (arg = TREE_VALUE (arg)))
4391 if (TREE_CODE (arg) == ADDR_EXPR
4392 && (arg = TREE_OPERAND (arg, 0))
4393 && TREE_CODE (arg) == STRING_CST)
4394 /* finally, we have the class name */
4395 return get_identifier (TREE_STRING_POINTER (arg));
4401 /* If we are currently building a message expr, this holds
4402 the identifier of the selector of the message. This is
4403 used when printing warnings about argument mismatches. */
4405 static tree building_objc_message_expr = 0;
4408 maybe_building_objc_message_expr ()
4410 return building_objc_message_expr;
4413 /* Construct an expression for sending a message.
4414 MESS has the object to send to in TREE_PURPOSE
4415 and the argument list (including selector) in TREE_VALUE.
4417 (*(<abstract_decl>(*)())_msg)(receiver, selTransTbl[n], ...);
4418 (*(<abstract_decl>(*)())_msgSuper)(receiver, selTransTbl[n], ...); */
4421 build_message_expr (mess)
4424 tree receiver = TREE_PURPOSE (mess);
4425 tree selector, self_object;
4426 tree rtype, sel_name;
4427 tree args = TREE_VALUE (mess);
4428 tree method_params = NULLT;
4429 tree method_prototype = NULLT;
4431 int statically_typed = 0, statically_allocated = 0;
4432 tree class_ident = 0;
4434 /* 1 if this is sending to the superclass. */
4437 if (!doing_objc_thang)
4440 if (TREE_CODE (receiver) == ERROR_MARK)
4441 return error_mark_node;
4443 /* determine receiver type */
4444 rtype = TREE_TYPE (receiver);
4445 super = IS_SUPER (rtype);
4449 if (TREE_STATIC_TEMPLATE (rtype))
4450 statically_allocated = 1;
4451 else if (TREE_CODE (rtype) == POINTER_TYPE
4452 && TREE_STATIC_TEMPLATE (TREE_TYPE (rtype)))
4453 statically_typed = 1;
4454 else if ((flag_next_runtime
4455 || (TREE_CODE (receiver) == CALL_EXPR && IS_ID (rtype)))
4456 && (class_ident = receiver_is_class_object (receiver)))
4458 else if (! IS_ID (rtype)
4459 /* Allow any type that matches objc_class_type. */
4460 && ! comptypes (rtype, objc_class_type))
4462 bzero (errbuf, BUFSIZE);
4463 warning ("invalid receiver type `%s'",
4464 gen_declaration (rtype, errbuf));
4466 if (statically_allocated)
4467 receiver = build_unary_op (ADDR_EXPR, receiver, 0);
4469 /* Don't evaluate the receiver twice. */
4470 receiver = save_expr (receiver);
4471 self_object = receiver;
4474 /* If sending to `super', use current self as the object. */
4475 self_object = self_decl;
4477 /* Obtain the full selector name. */
4479 if (TREE_CODE (args) == IDENTIFIER_NODE)
4480 /* a unary selector */
4482 else if (TREE_CODE (args) == TREE_LIST)
4483 sel_name = build_keyword_selector (args);
4485 /* Build the parameter list to give to the method. */
4487 method_params = NULLT;
4488 if (TREE_CODE (args) == TREE_LIST)
4490 tree chain = args, prev = NULLT;
4492 /* We have a keyword selector--check for comma expressions. */
4495 tree element = TREE_VALUE (chain);
4497 /* We have a comma expression, must collapse... */
4498 if (TREE_CODE (element) == TREE_LIST)
4501 TREE_CHAIN (prev) = element;
4506 chain = TREE_CHAIN (chain);
4508 method_params = args;
4511 /* Determine operation return type. */
4513 if (IS_SUPER (rtype))
4517 if (CLASS_SUPER_NAME (implementation_template))
4519 iface = lookup_interface (CLASS_SUPER_NAME (implementation_template));
4521 if (TREE_CODE (method_context) == INSTANCE_METHOD_DECL)
4522 method_prototype = lookup_instance_method_static (iface, sel_name);
4524 method_prototype = lookup_class_method_static (iface, sel_name);
4526 if (iface && !method_prototype)
4527 warning ("`%s' does not respond to `%s'",
4528 IDENTIFIER_POINTER (CLASS_SUPER_NAME (implementation_template)),
4529 IDENTIFIER_POINTER (sel_name));
4533 error ("no super class declared in interface for `%s'",
4534 IDENTIFIER_POINTER (CLASS_NAME (implementation_template)));
4535 return error_mark_node;
4539 else if (statically_allocated)
4541 tree ctype = TREE_TYPE (rtype);
4542 tree iface = lookup_interface (TYPE_NAME (rtype));
4545 method_prototype = lookup_instance_method_static (iface, sel_name);
4548 if (! method_prototype && TYPE_PROTOCOL_LIST (ctype))
4550 = lookup_method_in_protocol_list (TYPE_PROTOCOL_LIST (ctype),
4553 if (!method_prototype)
4554 warning ("`%s' does not respond to `%s'",
4555 IDENTIFIER_POINTER (TYPE_NAME (rtype)),
4556 IDENTIFIER_POINTER (sel_name));
4558 else if (statically_typed)
4560 tree ctype = TREE_TYPE (rtype);
4562 /* `self' is now statically_typed...all methods should be visible
4563 within the context of the implementation... */
4564 if (implementation_context
4565 && CLASS_NAME (implementation_context) == TYPE_NAME (ctype))
4567 method_prototype = lookup_instance_method_static (implementation_template, sel_name);
4570 if (! method_prototype && TYPE_PROTOCOL_LIST (ctype))
4572 = lookup_method_in_protocol_list (TYPE_PROTOCOL_LIST (ctype),
4575 if (! method_prototype
4576 && implementation_template != implementation_context)
4577 /* the method is not published in the interface...check locally */
4579 = lookup_method (CLASS_NST_METHODS (implementation_context),
4586 if ((iface = lookup_interface (TYPE_NAME (ctype))))
4587 method_prototype = lookup_instance_method_static (iface, sel_name);
4589 if (! method_prototype)
4591 tree protocol_list = TYPE_PROTOCOL_LIST (ctype);
4594 = lookup_method_in_protocol_list (protocol_list, sel_name, 0);
4598 if (!method_prototype)
4599 warning ("`%s' does not respond to `%s'",
4600 IDENTIFIER_POINTER (TYPE_NAME (ctype)),
4601 IDENTIFIER_POINTER (sel_name));
4603 else if (class_ident)
4605 if (implementation_context
4606 && CLASS_NAME (implementation_context) == class_ident)
4609 = lookup_class_method_static (implementation_template, sel_name);
4611 if (!method_prototype
4612 && implementation_template != implementation_context)
4613 /* the method is not published in the interface...check locally */
4615 = lookup_method (CLASS_CLS_METHODS (implementation_context),
4622 if ((iface = lookup_interface (class_ident)))
4623 method_prototype = lookup_class_method_static (iface, sel_name);
4626 if (!method_prototype)
4628 warning ("cannot find class (factory) method.");
4629 warning ("return type for `%s' defaults to id",
4630 IDENTIFIER_POINTER (sel_name));
4633 else if (IS_PROTOCOL_QUALIFIED_ID (rtype))
4635 /* An anonymous object that has been qualified with a protocol. */
4637 tree protocol_list = TYPE_PROTOCOL_LIST (rtype);
4639 method_prototype = lookup_method_in_protocol_list (protocol_list,
4642 if (!method_prototype)
4646 warning ("method `%s' not implemented by protocol.",
4647 IDENTIFIER_POINTER (sel_name));
4649 /* try and find the method signiture in the global pools! */
4651 if (!(hsh = hash_lookup (nst_method_hash_list, sel_name)))
4652 hsh = hash_lookup (cls_method_hash_list, sel_name);
4654 if (!(method_prototype = check_duplicates (hsh)))
4655 warning ("return type defaults to id");
4662 /* we think we have an instance...loophole: extern id Object; */
4663 hsh = hash_lookup (nst_method_hash_list, sel_name);
4665 /* for various loopholes...like sending messages to self in a
4666 factory context... */
4667 hsh = hash_lookup (cls_method_hash_list, sel_name);
4669 method_prototype = check_duplicates (hsh);
4670 if (!method_prototype)
4672 warning ("cannot find method.");
4673 warning ("return type for `%s' defaults to id",
4674 IDENTIFIER_POINTER (sel_name));
4678 /* Save the selector name for printing error messages. */
4679 building_objc_message_expr = sel_name;
4681 /* Build the parameters list for looking up the method.
4682 These are the object itself and the selector. */
4684 if (flag_typed_selectors)
4685 selector = build_typed_selector_reference (sel_name, method_prototype);
4687 selector = build_selector_reference (sel_name);
4689 retval = build_objc_method_call (super, method_prototype,
4690 receiver, self_object,
4691 selector, method_params);
4693 building_objc_message_expr = 0;
4698 /* Build a tree expression to send OBJECT the operation SELECTOR,
4699 looking up the method on object LOOKUP_OBJECT (often same as OBJECT),
4700 assuming the method has prototype METHOD_PROTOTYPE.
4701 (That is an INSTANCE_METHOD_DECL or CLASS_METHOD_DECL.)
4702 Use METHOD_PARAMS as list of args to pass to the method.
4703 If SUPER_FLAG is nonzero, we look up the superclass's method. */
4706 build_objc_method_call (super_flag, method_prototype, lookup_object, object,
4707 selector, method_params)
4709 tree method_prototype, lookup_object, object, selector, method_params;
4711 tree sender = (super_flag ? umsg_super_decl : umsg_decl);
4712 tree rcv_p = (super_flag
4713 ? build_pointer_type (xref_tag (RECORD_TYPE,
4714 get_identifier (TAG_SUPER)))
4717 if (flag_next_runtime)
4719 if (! method_prototype)
4721 method_params = tree_cons (NULLT, lookup_object,
4722 tree_cons (NULLT, selector,
4724 assemble_external (sender);
4725 return build_function_call (sender, method_params);
4729 /* This is a real kludge, but it is used only for the Next.
4730 Clobber the data type of SENDER temporarily to accept
4731 all the arguments for this operation, and to return
4732 whatever this operation returns. */
4733 tree arglist = NULLT;
4736 /* Save the proper contents of SENDER's data type. */
4737 tree savarg = TYPE_ARG_TYPES (TREE_TYPE (sender));
4738 tree savret = TREE_TYPE (TREE_TYPE (sender));
4740 /* Install this method's argument types. */
4741 arglist = get_arg_type_list (method_prototype, METHOD_REF,
4743 TYPE_ARG_TYPES (TREE_TYPE (sender)) = arglist;
4745 /* Install this method's return type. */
4746 TREE_TYPE (TREE_TYPE (sender))
4747 = groktypename (TREE_TYPE (method_prototype));
4749 /* Call SENDER with all the parameters. This will do type
4750 checking using the arg types for this method. */
4751 method_params = tree_cons (NULLT, lookup_object,
4752 tree_cons (NULLT, selector,
4754 assemble_external (sender);
4755 retval = build_function_call (sender, method_params);
4757 /* Restore SENDER's return/argument types. */
4758 TYPE_ARG_TYPES (TREE_TYPE (sender)) = savarg;
4759 TREE_TYPE (TREE_TYPE (sender)) = savret;
4765 /* This is the portable way.
4766 First call the lookup function to get a pointer to the method,
4767 then cast the pointer, then call it with the method arguments. */
4770 /* Avoid trouble since we may evaluate each of these twice. */
4771 object = save_expr (object);
4772 selector = save_expr (selector);
4774 lookup_object = build_c_cast (rcv_p, lookup_object); /* cast! */
4776 assemble_external (sender);
4778 = build_function_call (sender,
4779 tree_cons (NULLT, lookup_object,
4780 tree_cons (NULLT, selector, NULLT)));
4782 /* If we have a method prototype, construct the data type this
4783 method needs, and cast what we got from SENDER into a pointer
4785 if (method_prototype)
4787 tree arglist = get_arg_type_list (method_prototype, METHOD_REF,
4789 tree valtype = groktypename (TREE_TYPE (method_prototype));
4790 tree fake_function_type = build_function_type (valtype, arglist);
4791 TREE_TYPE (method) = build_pointer_type (fake_function_type);
4795 = build_pointer_type (build_function_type (ptr_type_node, NULLT));
4797 /* Pass the object to the method. */
4798 assemble_external (method);
4799 return build_function_call (method,
4800 tree_cons (NULLT, object,
4801 tree_cons (NULLT, selector,
4807 build_protocol_reference (p)
4810 tree decl, ident, ptype;
4811 struct obstack *save_current_obstack = current_obstack;
4812 struct obstack *save_rtl_obstack = rtl_obstack;
4814 rtl_obstack = current_obstack = &permanent_obstack;
4816 /* extern struct objc_protocol _OBJC_PROTOCOL_<mumble>; */
4818 ident = synth_id_with_class_suffix ("_OBJC_PROTOCOL", p);
4820 = groktypename (build_tree_list (build_tree_list (NULLT,
4821 objc_protocol_template),
4824 if (IDENTIFIER_GLOBAL_VALUE (ident))
4825 decl = IDENTIFIER_GLOBAL_VALUE (ident); /* Set by pushdecl. */
4828 decl = build_decl (VAR_DECL, ident, ptype);
4829 DECL_EXTERNAL (decl) = 1;
4830 TREE_PUBLIC (decl) = 1;
4831 TREE_USED (decl) = 1;
4833 /* usually called from `rest_of_decl_compilation' */
4834 make_decl_rtl (decl, 0, 1);
4835 /* our `extended/custom' pushdecl in c-decl.c */
4836 pushdecl_top_level (decl);
4838 current_obstack = save_current_obstack;
4839 rtl_obstack = save_rtl_obstack;
4841 PROTOCOL_FORWARD_DECL (p) = decl;
4845 build_protocol_expr (protoname)
4851 if (!doing_objc_thang)
4854 p = lookup_protocol (protoname);
4858 error ("Cannot find protocol declaration for `%s'",
4859 IDENTIFIER_POINTER (protoname));
4860 return error_mark_node;
4863 if (!PROTOCOL_FORWARD_DECL (p))
4864 build_protocol_reference (p);
4866 expr = build_unary_op (ADDR_EXPR, PROTOCOL_FORWARD_DECL (p), 0);
4868 TREE_TYPE (expr) = protocol_type;
4874 build_selector_expr (selnamelist)
4879 if (!doing_objc_thang)
4882 /* obtain the full selector name */
4883 if (TREE_CODE (selnamelist) == IDENTIFIER_NODE)
4884 /* a unary selector */
4885 selname = selnamelist;
4886 else if (TREE_CODE (selnamelist) == TREE_LIST)
4887 selname = build_keyword_selector (selnamelist);
4889 if (flag_typed_selectors)
4890 return build_typed_selector_reference (selname, 0);
4892 return build_selector_reference (selname);
4896 build_encode_expr (type)
4902 if (!doing_objc_thang)
4905 encode_type (type, obstack_object_size (&util_obstack),
4906 OBJC_ENCODE_INLINE_DEFS);
4907 obstack_1grow (&util_obstack, 0); /* null terminate string */
4908 string = obstack_finish (&util_obstack);
4910 /* synthesize a string that represents the encoded struct/union */
4911 result = my_build_string (strlen (string) + 1, string);
4912 obstack_free (&util_obstack, util_firstobj);
4917 build_ivar_reference (id)
4920 if (TREE_CODE (method_context) == CLASS_METHOD_DECL)
4922 /* Historically, a class method that produced objects (factory
4923 method) would assign `self' to the instance that it
4924 allocated. This would effectively turn the class method into
4925 an instance method. Following this assignment, the instance
4926 variables could be accessed. That practice, while safe,
4927 violates the simple rule that a class method should not refer
4928 to an instance variable. It's better to catch the cases
4929 where this is done unknowingly than to support the above
4931 warning ("instance variable `%s' accessed in class method",
4932 IDENTIFIER_POINTER (id));
4933 TREE_TYPE (self_decl) = instance_type; /* cast */
4936 return build_component_ref (build_indirect_ref (self_decl, "->"), id);
4939 #define HASH_ALLOC_LIST_SIZE 170
4940 #define ATTR_ALLOC_LIST_SIZE 170
4941 #define SIZEHASHTABLE 257
4944 #define HASHFUNCTION(key) ((HOST_WIDE_INT) key & 0x7fffffff)
4949 nst_method_hash_list = (hash *)xmalloc (SIZEHASHTABLE * sizeof (hash));
4950 cls_method_hash_list = (hash *)xmalloc (SIZEHASHTABLE * sizeof (hash));
4952 if (!nst_method_hash_list || !cls_method_hash_list)
4953 perror ("unable to allocate space in objc-tree.c");
4958 for (i = 0; i < SIZEHASHTABLE; i++)
4960 nst_method_hash_list[i] = 0;
4961 cls_method_hash_list[i] = 0;
4967 hash_enter (hashlist, method)
4971 static hash hash_alloc_list = 0;
4972 static int hash_alloc_index = 0;
4974 int slot = HASHFUNCTION (METHOD_SEL_NAME (method)) % SIZEHASHTABLE;
4976 if (! hash_alloc_list || hash_alloc_index >= HASH_ALLOC_LIST_SIZE)
4978 hash_alloc_index = 0;
4979 hash_alloc_list = (hash) xmalloc (sizeof (struct hashed_entry)
4980 * HASH_ALLOC_LIST_SIZE);
4981 if (! hash_alloc_list)
4982 perror ("unable to allocate in objc-tree.c");
4984 obj = &hash_alloc_list[hash_alloc_index++];
4986 obj->next = hashlist[slot];
4989 hashlist[slot] = obj; /* append to front */
4993 hash_lookup (hashlist, sel_name)
4999 target = hashlist[HASHFUNCTION (sel_name) % SIZEHASHTABLE];
5003 if (sel_name == METHOD_SEL_NAME (target->key))
5006 target = target->next;
5012 hash_add_attr (entry, value)
5016 static attr attr_alloc_list = 0;
5017 static int attr_alloc_index = 0;
5020 if (! attr_alloc_list || attr_alloc_index >= ATTR_ALLOC_LIST_SIZE)
5022 attr_alloc_index = 0;
5023 attr_alloc_list = (attr) xmalloc (sizeof (struct hashed_attribute)
5024 * ATTR_ALLOC_LIST_SIZE);
5025 if (! attr_alloc_list)
5026 perror ("unable to allocate in objc-tree.c");
5028 obj = &attr_alloc_list[attr_alloc_index++];
5029 obj->next = entry->list;
5032 entry->list = obj; /* append to front */
5036 lookup_method (mchain, method)
5042 if (TREE_CODE (method) == IDENTIFIER_NODE)
5045 key = METHOD_SEL_NAME (method);
5049 if (METHOD_SEL_NAME (mchain) == key)
5051 mchain = TREE_CHAIN (mchain);
5057 lookup_instance_method_static (interface, ident)
5061 tree inter = interface;
5062 tree chain = CLASS_NST_METHODS (inter);
5067 if ((meth = lookup_method (chain, ident)))
5070 if (CLASS_CATEGORY_LIST (inter))
5072 tree category = CLASS_CATEGORY_LIST (inter);
5073 chain = CLASS_NST_METHODS (category);
5077 if ((meth = lookup_method (chain, ident)))
5081 /* Check for instance methods in protocols in categories. */
5082 if (CLASS_PROTOCOL_LIST (category))
5084 if ((meth = (lookup_method_in_protocol_list
5085 (CLASS_PROTOCOL_LIST (category), ident, 0))))
5089 if ((category = CLASS_CATEGORY_LIST (category)))
5090 chain = CLASS_NST_METHODS (category);
5095 if (CLASS_PROTOCOL_LIST (inter))
5097 if ((meth = (lookup_method_in_protocol_list
5098 (CLASS_PROTOCOL_LIST (inter), ident, 0))))
5102 if ((inter = lookup_interface (CLASS_SUPER_NAME (inter))))
5103 chain = CLASS_NST_METHODS (inter);
5111 lookup_class_method_static (interface, ident)
5115 tree inter = interface;
5116 tree chain = CLASS_CLS_METHODS (inter);
5118 tree root_inter = NULLT;
5122 if ((meth = lookup_method (chain, ident)))
5125 if (CLASS_CATEGORY_LIST (inter))
5127 tree category = CLASS_CATEGORY_LIST (inter);
5128 chain = CLASS_CLS_METHODS (category);
5132 if ((meth = lookup_method (chain, ident)))
5136 /* Check for class methods in protocols in categories. */
5137 if (CLASS_PROTOCOL_LIST (category))
5139 if ((meth = (lookup_method_in_protocol_list
5140 (CLASS_PROTOCOL_LIST (category), ident, 1))))
5144 if ((category = CLASS_CATEGORY_LIST (category)))
5145 chain = CLASS_CLS_METHODS (category);
5151 /* Check for class methods in protocols. */
5152 if (CLASS_PROTOCOL_LIST (inter))
5154 if ((meth = (lookup_method_in_protocol_list
5155 (CLASS_PROTOCOL_LIST (inter), ident, 1))))
5160 if ((inter = lookup_interface (CLASS_SUPER_NAME (inter))))
5161 chain = CLASS_CLS_METHODS (inter);
5166 /* Simulate wrap around. */
5167 return lookup_instance_method_static (root_inter, ident);
5171 add_class_method (class, method)
5178 /* We will have allocated the method parameter declarations on the
5179 maybepermanent_obstack. Need to make sure they stick around! */
5182 if (!(mth = lookup_method (CLASS_CLS_METHODS (class), method)))
5184 /* put method on list in reverse order */
5185 TREE_CHAIN (method) = CLASS_CLS_METHODS (class);
5186 CLASS_CLS_METHODS (class) = method;
5190 if (TREE_CODE (class) == CLASS_IMPLEMENTATION_TYPE)
5191 error ("duplicate definition of class method `%s'.",
5192 IDENTIFIER_POINTER (METHOD_SEL_NAME (mth)));
5195 /* check types, if different complain */
5196 if (!comp_proto_with_proto (method, mth))
5197 error ("duplicate declaration of class method `%s'.",
5198 IDENTIFIER_POINTER (METHOD_SEL_NAME (mth)));
5202 if (!(hsh = hash_lookup (cls_method_hash_list, METHOD_SEL_NAME (method))))
5204 /* install on a global chain */
5205 hash_enter (cls_method_hash_list, method);
5209 /* check types, if different add to a list */
5210 if (!comp_proto_with_proto (method, hsh->key))
5211 hash_add_attr (hsh, method);
5217 add_instance_method (class, method)
5224 /* We will have allocated the method parameter declarations on the
5225 maybepermanent_obstack. Need to make sure they stick around! */
5228 if (!(mth = lookup_method (CLASS_NST_METHODS (class), method)))
5230 /* put method on list in reverse order */
5231 TREE_CHAIN (method) = CLASS_NST_METHODS (class);
5232 CLASS_NST_METHODS (class) = method;
5236 if (TREE_CODE (class) == CLASS_IMPLEMENTATION_TYPE)
5237 error ("duplicate definition of instance method `%s'.",
5238 IDENTIFIER_POINTER (METHOD_SEL_NAME (mth)));
5241 /* check types, if different complain */
5242 if (!comp_proto_with_proto (method, mth))
5243 error ("duplicate declaration of instance method `%s'.",
5244 IDENTIFIER_POINTER (METHOD_SEL_NAME (mth)));
5248 if (!(hsh = hash_lookup (nst_method_hash_list, METHOD_SEL_NAME (method))))
5250 /* install on a global chain */
5251 hash_enter (nst_method_hash_list, method);
5255 /* check types, if different add to a list */
5256 if (!comp_proto_with_proto (method, hsh->key))
5257 hash_add_attr (hsh, method);
5266 /* put interfaces on list in reverse order */
5267 TREE_CHAIN (class) = interface_chain;
5268 interface_chain = class;
5269 return interface_chain;
5273 add_category (class, category)
5277 /* put categories on list in reverse order */
5279 tree cat = CLASS_CATEGORY_LIST (class);
5282 if (CLASS_SUPER_NAME (cat) == CLASS_SUPER_NAME (category))
5283 warning ("duplicate interface declaration for category `%s(%s)'",
5284 IDENTIFIER_POINTER (CLASS_NAME (class)),
5285 IDENTIFIER_POINTER (CLASS_SUPER_NAME (category)));
5286 cat = CLASS_CATEGORY_LIST (cat);
5289 CLASS_CATEGORY_LIST (category) = CLASS_CATEGORY_LIST (class);
5290 CLASS_CATEGORY_LIST (class) = category;
5293 /* Called after parsing each instance variable declaration. Necessary to
5294 preserve typedefs and implement public/private...
5296 PUBLIC is 1 for public, 0 for protected, and 2 for private. */
5299 add_instance_variable (class, public, declarator, declspecs, width)
5306 tree field_decl, raw_decl;
5308 raw_decl = build_tree_list (declspecs /*purpose*/, declarator/*value*/);
5310 if (CLASS_RAW_IVARS (class))
5311 chainon (CLASS_RAW_IVARS (class), raw_decl);
5313 CLASS_RAW_IVARS (class) = raw_decl;
5315 field_decl = grokfield (input_filename, lineno,
5316 declarator, declspecs, width);
5318 /* overload the public attribute, it is not used for FIELD_DECL's */
5322 TREE_PUBLIC (field_decl) = 0;
5323 TREE_PRIVATE (field_decl) = 0;
5324 TREE_PROTECTED (field_decl) = 1;
5328 TREE_PUBLIC (field_decl) = 1;
5329 TREE_PRIVATE (field_decl) = 0;
5330 TREE_PROTECTED (field_decl) = 0;
5334 TREE_PUBLIC (field_decl) = 0;
5335 TREE_PRIVATE (field_decl) = 1;
5336 TREE_PROTECTED (field_decl) = 0;
5341 if (CLASS_IVARS (class))
5342 chainon (CLASS_IVARS (class), field_decl);
5344 CLASS_IVARS (class) = field_decl;
5350 is_ivar (decl_chain, ident)
5354 for ( ; decl_chain; decl_chain = TREE_CHAIN (decl_chain))
5355 if (DECL_NAME (decl_chain) == ident)
5360 /* True if the ivar is private and we are not in its implementation. */
5366 if (TREE_PRIVATE (decl)
5367 && ! is_ivar (CLASS_IVARS (implementation_template), DECL_NAME (decl)))
5369 error ("instance variable `%s' is declared private",
5370 IDENTIFIER_POINTER (DECL_NAME (decl)));
5377 /* we have an instance variable reference, check to see if it is public...*/
5380 is_public (expr, identifier)
5384 tree basetype = TREE_TYPE (expr);
5385 enum tree_code code = TREE_CODE (basetype);
5388 if (code == RECORD_TYPE)
5390 if (TREE_STATIC_TEMPLATE (basetype))
5392 if (!lookup_interface (TYPE_NAME (basetype)))
5394 error ("Cannot find interface declaration for `%s'",
5395 IDENTIFIER_POINTER (TYPE_NAME (basetype)));
5399 if ((decl = is_ivar (TYPE_FIELDS (basetype), identifier)))
5401 if (TREE_PUBLIC (decl))
5404 /* important difference between the Stepstone translator:
5405 all instance variables should be public within the context
5406 of the implementation. */
5407 if (implementation_context
5408 && (((TREE_CODE (implementation_context)
5409 == CLASS_IMPLEMENTATION_TYPE)
5410 || (TREE_CODE (implementation_context)
5411 == CATEGORY_IMPLEMENTATION_TYPE))
5412 && (CLASS_NAME (implementation_context)
5413 == TYPE_NAME (basetype))))
5414 return ! is_private (decl);
5416 error ("instance variable `%s' is declared %s",
5417 IDENTIFIER_POINTER (identifier),
5418 TREE_PRIVATE (decl) ? "private" : "protected");
5422 else if (implementation_context && (basetype == objc_object_reference))
5424 TREE_TYPE (expr) = uprivate_record;
5425 warning ("static access to object of type `id'");
5431 /* implement @defs (<classname>) within struct bodies. */
5434 get_class_ivars (interface)
5437 if (!doing_objc_thang)
5440 return build_ivar_chain (interface, 1);
5443 /* make sure all entries in "chain" are also in "list" */
5446 check_methods (chain, list, mtype)
5455 if (!lookup_method (list, chain))
5459 if (TREE_CODE (implementation_context) == CLASS_IMPLEMENTATION_TYPE)
5460 warning ("incomplete implementation of class `%s'",
5461 IDENTIFIER_POINTER (CLASS_NAME (implementation_context)));
5462 else if (TREE_CODE (implementation_context) == CATEGORY_IMPLEMENTATION_TYPE)
5463 warning ("incomplete implementation of category `%s'",
5464 IDENTIFIER_POINTER (CLASS_SUPER_NAME (implementation_context)));
5467 warning ("method definition for `%c%s' not found",
5468 mtype, IDENTIFIER_POINTER (METHOD_SEL_NAME (chain)));
5470 chain = TREE_CHAIN (chain);
5476 conforms_to_protocol (class, protocol)
5482 tree p = CLASS_PROTOCOL_LIST (class);
5483 while (p && TREE_VALUE (p) != TREE_VALUE (protocol))
5487 tree super = (CLASS_SUPER_NAME (class)
5488 ? lookup_interface (CLASS_SUPER_NAME (class))
5490 int tmp = super ? conforms_to_protocol (super, protocol) : 0;
5494 protocol = TREE_CHAIN (protocol);
5499 /* Make sure all methods in CHAIN are accessible as MTYPE methods in
5500 CONTEXT. This is one of two mechanisms to check protocol integrity
5504 check_methods_accessible (chain, context, mtype)
5506 tree context; /* implementation_context */
5511 tree base_context = context;
5515 context = base_context;
5519 list = CLASS_CLS_METHODS (context);
5521 list = CLASS_NST_METHODS (context);
5523 if (lookup_method (list, chain))
5526 else if (TREE_CODE (context) == CLASS_IMPLEMENTATION_TYPE
5527 || TREE_CODE (context) == CLASS_INTERFACE_TYPE)
5528 context = (CLASS_SUPER_NAME (context)
5529 ? lookup_interface (CLASS_SUPER_NAME (context))
5532 else if (TREE_CODE (context) == CATEGORY_IMPLEMENTATION_TYPE
5533 || TREE_CODE (context) == CATEGORY_INTERFACE_TYPE)
5534 context = (CLASS_NAME (context)
5535 ? lookup_interface (CLASS_NAME (context))
5541 if (context == NULL_TREE)
5545 if (TREE_CODE (implementation_context)
5546 == CLASS_IMPLEMENTATION_TYPE)
5547 warning ("incomplete implementation of class `%s'",
5549 (CLASS_NAME (implementation_context)));
5550 else if (TREE_CODE (implementation_context)
5551 == CATEGORY_IMPLEMENTATION_TYPE)
5552 warning ("incomplete implementation of category `%s'",
5554 (CLASS_SUPER_NAME (implementation_context)));
5557 warning ("method definition for `%c%s' not found",
5558 mtype, IDENTIFIER_POINTER (METHOD_SEL_NAME (chain)));
5561 chain = TREE_CHAIN (chain); /* next method... */
5567 check_protocols (proto_list, type, name)
5572 for ( ; proto_list; proto_list = TREE_CHAIN (proto_list))
5574 tree p = TREE_VALUE (proto_list);
5576 if (TREE_CODE (p) == PROTOCOL_INTERFACE_TYPE)
5580 /* Ensure that all protocols have bodies! */
5581 if (flag_warn_protocol) {
5582 f1 = check_methods (PROTOCOL_CLS_METHODS (p),
5583 CLASS_CLS_METHODS (implementation_context),
5585 f2 = check_methods (PROTOCOL_NST_METHODS (p),
5586 CLASS_NST_METHODS (implementation_context),
5589 f1 = check_methods_accessible (PROTOCOL_CLS_METHODS (p),
5590 implementation_context,
5592 f2 = check_methods_accessible (PROTOCOL_NST_METHODS (p),
5593 implementation_context,
5598 warning ("%s `%s' does not fully implement the `%s' protocol",
5599 type, name, IDENTIFIER_POINTER (PROTOCOL_NAME (p)));
5603 ; /* an identifier...if we could not find a protocol. */
5605 /* Check protocols recursively. */
5606 if (PROTOCOL_LIST (p))
5609 = lookup_interface (CLASS_SUPER_NAME (implementation_template));
5610 if (! conforms_to_protocol (super_class, PROTOCOL_LIST (p)))
5611 check_protocols (PROTOCOL_LIST (p), type, name);
5616 /* Make sure that the class CLASS_NAME is defined
5617 CODE says which kind of thing CLASS_NAME ought to be.
5618 It can be CLASS_INTERFACE_TYPE, CLASS_IMPLEMENTATION_TYPE,
5619 CATEGORY_INTERFACE_TYPE, or CATEGORY_IMPLEMENTATION_TYPE.
5621 If CODE is CLASS_INTERFACE_TYPE, we also do a push_obstacks_nochange
5622 whose matching pop is in continue_class. */
5625 start_class (code, class_name, super_name, protocol_list)
5626 enum tree_code code;
5633 if (code == CLASS_INTERFACE_TYPE)
5635 push_obstacks_nochange ();
5636 end_temporary_allocation ();
5639 if (!doing_objc_thang)
5642 class = make_node (code);
5643 TYPE_BINFO (class) = make_tree_vec (5);
5645 CLASS_NAME (class) = class_name;
5646 CLASS_SUPER_NAME (class) = super_name;
5647 CLASS_CLS_METHODS (class) = NULL_TREE;
5649 if (! is_class_name (class_name) && (decl = lookup_name (class_name)))
5651 error ("`%s' redeclared as different kind of symbol",
5652 IDENTIFIER_POINTER (class_name));
5653 error_with_decl (decl, "previous declaration of `%s'");
5656 if (code == CLASS_IMPLEMENTATION_TYPE)
5659 static tree implemented_classes = 0;
5660 tree chain = implemented_classes;
5661 for (chain = implemented_classes; chain; chain = TREE_CHAIN (chain))
5662 if (TREE_VALUE (chain) == class_name)
5664 error ("reimplementation of class `%s'",
5665 IDENTIFIER_POINTER (class_name));
5666 return error_mark_node;
5668 implemented_classes = perm_tree_cons (NULLT, class_name,
5669 implemented_classes);
5672 /* pre-build the following entities - for speed/convenience. */
5674 self_id = get_identifier ("self");
5676 ucmd_id = get_identifier ("_cmd");
5678 if (!objc_super_template)
5679 objc_super_template = build_super_template ();
5681 method_slot = 0; /* reset for multiple classes per file */
5683 implementation_context = class;
5685 /* lookup the interface for this implementation. */
5687 if (!(implementation_template = lookup_interface (class_name)))
5689 warning ("Cannot find interface declaration for `%s'",
5690 IDENTIFIER_POINTER (class_name));
5691 add_class (implementation_template = implementation_context);
5694 /* if a super class has been specified in the implementation,
5695 insure it conforms to the one specified in the interface */
5698 && (super_name != CLASS_SUPER_NAME (implementation_template)))
5700 tree previous_name = CLASS_SUPER_NAME (implementation_template);
5701 char *name = previous_name ? IDENTIFIER_POINTER (previous_name) : "";
5702 error ("conflicting super class name `%s'",
5703 IDENTIFIER_POINTER (super_name));
5704 error ("previous declaration of `%s'", name);
5706 else if (! super_name)
5708 CLASS_SUPER_NAME (implementation_context)
5709 = CLASS_SUPER_NAME (implementation_template);
5712 else if (code == CLASS_INTERFACE_TYPE)
5714 if (lookup_interface (class_name))
5715 warning ("duplicate interface declaration for class `%s'",
5716 IDENTIFIER_POINTER (class_name));
5721 CLASS_PROTOCOL_LIST (class)
5722 = lookup_and_install_protocols (protocol_list);
5724 else if (code == CATEGORY_INTERFACE_TYPE)
5726 tree class_category_is_assoc_with;
5728 /* for a category, class_name is really the name of the class that
5729 the following set of methods will be associated with...we must
5730 find the interface so that can derive the objects template */
5732 if (!(class_category_is_assoc_with = lookup_interface (class_name)))
5734 error ("Cannot find interface declaration for `%s'",
5735 IDENTIFIER_POINTER (class_name));
5739 add_category (class_category_is_assoc_with, class);
5742 CLASS_PROTOCOL_LIST (class)
5743 = lookup_and_install_protocols (protocol_list);
5745 else if (code == CATEGORY_IMPLEMENTATION_TYPE)
5747 /* pre-build the following entities - for speed/convenience. */
5749 self_id = get_identifier ("self");
5751 ucmd_id = get_identifier ("_cmd");
5753 if (!objc_super_template)
5754 objc_super_template = build_super_template ();
5756 method_slot = 0; /* reset for multiple classes per file */
5758 implementation_context = class;
5760 /* for a category, class_name is really the name of the class that
5761 the following set of methods will be associated with...we must
5762 find the interface so that can derive the objects template */
5764 if (!(implementation_template = lookup_interface (class_name)))
5766 error ("Cannot find interface declaration for `%s'",
5767 IDENTIFIER_POINTER (class_name));
5775 continue_class (class)
5778 if (TREE_CODE (class) == CLASS_IMPLEMENTATION_TYPE
5779 || TREE_CODE (class) == CATEGORY_IMPLEMENTATION_TYPE)
5781 struct imp_entry *imp_entry;
5784 /* check consistency of the instance variables. */
5786 if (CLASS_IVARS (class))
5787 check_ivars (implementation_template, class);
5789 /* code generation */
5791 ivar_context = build_private_template (implementation_template);
5793 if (!objc_class_template)
5794 build_class_template ();
5796 if (!(imp_entry = (struct imp_entry *) xmalloc (sizeof (struct imp_entry))))
5797 perror ("unable to allocate in objc-tree.c");
5799 imp_entry->next = imp_list;
5800 imp_entry->imp_context = class;
5801 imp_entry->imp_template = implementation_template;
5803 synth_forward_declarations ();
5804 imp_entry->class_decl = UOBJC_CLASS_decl;
5805 imp_entry->meta_decl = UOBJC_METACLASS_decl;
5807 /* append to front and increment count */
5808 imp_list = imp_entry;
5809 if (TREE_CODE (class) == CLASS_IMPLEMENTATION_TYPE)
5814 return ivar_context;
5816 else if (TREE_CODE (class) == CLASS_INTERFACE_TYPE)
5818 tree record = xref_tag (RECORD_TYPE, CLASS_NAME (class));
5820 if (!TYPE_FIELDS (record))
5822 finish_struct (record, build_ivar_chain (class, 0));
5823 CLASS_STATIC_TEMPLATE (class) = record;
5825 /* mark this record as a class template - for static typing */
5826 TREE_STATIC_TEMPLATE (record) = 1;
5831 return error_mark_node;
5834 /* This is called once we see the "@end" in an interface/implementation. */
5837 finish_class (class)
5840 if (TREE_CODE (class) == CLASS_IMPLEMENTATION_TYPE)
5842 /* all code generation is done in finish_objc */
5844 if (implementation_template != implementation_context)
5846 /* ensure that all method listed in the interface contain bodies! */
5847 check_methods (CLASS_CLS_METHODS (implementation_template),
5848 CLASS_CLS_METHODS (implementation_context), '+');
5849 check_methods (CLASS_NST_METHODS (implementation_template),
5850 CLASS_NST_METHODS (implementation_context), '-');
5852 if (CLASS_PROTOCOL_LIST (implementation_template))
5853 check_protocols (CLASS_PROTOCOL_LIST (implementation_template),
5855 IDENTIFIER_POINTER (CLASS_NAME (implementation_context)));
5858 else if (TREE_CODE (class) == CATEGORY_IMPLEMENTATION_TYPE)
5860 tree category = CLASS_CATEGORY_LIST (implementation_template);
5862 /* find the category interface from the class it is associated with */
5865 if (CLASS_SUPER_NAME (class) == CLASS_SUPER_NAME (category))
5867 category = CLASS_CATEGORY_LIST (category);
5872 /* ensure that all method listed in the interface contain bodies! */
5873 check_methods (CLASS_CLS_METHODS (category),
5874 CLASS_CLS_METHODS (implementation_context), '+');
5875 check_methods (CLASS_NST_METHODS (category),
5876 CLASS_NST_METHODS (implementation_context), '-');
5878 if (CLASS_PROTOCOL_LIST (category))
5879 check_protocols (CLASS_PROTOCOL_LIST (category),
5881 IDENTIFIER_POINTER (CLASS_SUPER_NAME (implementation_context)));
5884 else if (TREE_CODE (class) == CLASS_INTERFACE_TYPE)
5887 char *class_name = IDENTIFIER_POINTER (CLASS_NAME (class));
5888 char *string = (char *) alloca (strlen (class_name) + 3);
5890 /* extern struct objc_object *_<my_name>; */
5892 sprintf (string, "_%s", class_name);
5894 decl_specs = build_tree_list (NULLT, ridpointers[(int) RID_EXTERN]);
5895 decl_specs = tree_cons (NULLT, objc_object_reference, decl_specs);
5896 define_decl (build1 (INDIRECT_REF, NULLT, get_identifier (string)),
5902 add_protocol (protocol)
5905 /* put protocol on list in reverse order */
5906 TREE_CHAIN (protocol) = protocol_chain;
5907 protocol_chain = protocol;
5908 return protocol_chain;
5912 lookup_protocol (ident)
5917 for (chain = protocol_chain; chain; chain = TREE_CHAIN (chain))
5919 if (ident == PROTOCOL_NAME (chain))
5926 start_protocol (code, name, list)
5927 enum tree_code code;
5933 if (!doing_objc_thang)
5936 /* This is as good a place as any. Need to invoke push_tag_toplevel. */
5937 if (!objc_protocol_template)
5938 objc_protocol_template = build_protocol_template ();
5940 protocol = make_node (code);
5941 TYPE_BINFO (protocol) = make_tree_vec (2);
5943 PROTOCOL_NAME (protocol) = name;
5944 PROTOCOL_LIST (protocol) = list;
5946 lookup_and_install_protocols (list);
5948 if (lookup_protocol (name))
5949 warning ("duplicate declaration for protocol `%s'",
5950 IDENTIFIER_POINTER (name));
5952 add_protocol (protocol);
5954 PROTOCOL_FORWARD_DECL (protocol) = NULL_TREE;
5960 finish_protocol (protocol)
5966 /* "Encode" a data type into a string, which grows in util_obstack.
5967 ??? What is the FORMAT? Someone please document this! */
5970 encode_type_qualifiers (declspecs)
5975 for (spec = declspecs; spec; spec = TREE_CHAIN (spec))
5977 if (ridpointers[(int) RID_CONST] == TREE_VALUE (spec))
5978 obstack_1grow (&util_obstack, 'r');
5979 else if (ridpointers[(int) RID_IN] == TREE_VALUE (spec))
5980 obstack_1grow (&util_obstack, 'n');
5981 else if (ridpointers[(int) RID_INOUT] == TREE_VALUE (spec))
5982 obstack_1grow (&util_obstack, 'N');
5983 else if (ridpointers[(int) RID_OUT] == TREE_VALUE (spec))
5984 obstack_1grow (&util_obstack, 'o');
5985 else if (ridpointers[(int) RID_BYCOPY] == TREE_VALUE (spec))
5986 obstack_1grow (&util_obstack, 'O');
5987 else if (ridpointers[(int) RID_ONEWAY] == TREE_VALUE (spec))
5988 obstack_1grow (&util_obstack, 'V');
5992 /* Encode a pointer type. */
5995 encode_pointer (type, curtype, format)
6000 tree pointer_to = TREE_TYPE (type);
6002 if (TREE_CODE (pointer_to) == RECORD_TYPE)
6004 if (TYPE_NAME (pointer_to)
6005 && TREE_CODE (TYPE_NAME (pointer_to)) == IDENTIFIER_NODE)
6007 char *name = IDENTIFIER_POINTER (TYPE_NAME (pointer_to));
6009 if (strcmp (name, TAG_OBJECT) == 0) /* '@' */
6011 obstack_1grow (&util_obstack, '@');
6014 else if (TREE_STATIC_TEMPLATE (pointer_to))
6016 if (generating_instance_variables)
6018 obstack_1grow (&util_obstack, '@');
6019 obstack_1grow (&util_obstack, '"');
6020 obstack_grow (&util_obstack, name, strlen (name));
6021 obstack_1grow (&util_obstack, '"');
6026 obstack_1grow (&util_obstack, '@');
6030 else if (strcmp (name, TAG_CLASS) == 0) /* '#' */
6032 obstack_1grow (&util_obstack, '#');
6035 #ifndef OBJC_INT_SELECTORS
6036 else if (strcmp (name, TAG_SELECTOR) == 0) /* ':' */
6038 obstack_1grow (&util_obstack, ':');
6041 #endif /* OBJC_INT_SELECTORS */
6044 else if (TREE_CODE (pointer_to) == INTEGER_TYPE
6045 && TYPE_MODE (pointer_to) == QImode)
6047 obstack_1grow (&util_obstack, '*');
6051 /* we have a type that does not get special treatment... */
6053 /* NeXT extension */
6054 obstack_1grow (&util_obstack, '^');
6055 encode_type (pointer_to, curtype, format);
6059 encode_array (type, curtype, format)
6064 tree an_int_cst = TYPE_SIZE (type);
6065 tree array_of = TREE_TYPE (type);
6068 /* An incomplete array is treated like a pointer. */
6069 if (an_int_cst == NULL)
6071 /* split for obvious reasons. North-Keys 30 Mar 1991 */
6072 encode_pointer (type, curtype, format);
6076 sprintf (buffer, "[%d",
6077 (TREE_INT_CST_LOW (an_int_cst)
6078 / TREE_INT_CST_LOW (TYPE_SIZE (array_of))));
6079 obstack_grow (&util_obstack, buffer, strlen (buffer));
6080 encode_type (array_of, curtype, format);
6081 obstack_1grow (&util_obstack, ']');
6086 encode_aggregate (type, curtype, format)
6091 enum tree_code code = TREE_CODE (type);
6097 if (obstack_object_size (&util_obstack) > 0
6098 && *(obstack_next_free (&util_obstack) - 1) == '^')
6100 tree name = TYPE_NAME (type);
6102 /* we have a reference - this is a NeXT extension */
6104 if (obstack_object_size (&util_obstack) - curtype == 1
6105 && format == OBJC_ENCODE_INLINE_DEFS)
6107 /* output format of struct for first level only! */
6109 tree fields = TYPE_FIELDS (type);
6111 if (name && TREE_CODE (name) == IDENTIFIER_NODE)
6113 obstack_1grow (&util_obstack, '{');
6114 obstack_grow (&util_obstack,
6115 IDENTIFIER_POINTER (name),
6116 strlen (IDENTIFIER_POINTER (name)));
6117 obstack_1grow (&util_obstack, '=');
6120 obstack_grow (&util_obstack, "{?=", 3);
6122 for ( ; fields; fields = TREE_CHAIN (fields))
6123 encode_field_decl (fields, curtype, format);
6124 obstack_1grow (&util_obstack, '}');
6126 else if (name && TREE_CODE (name) == IDENTIFIER_NODE)
6128 obstack_1grow (&util_obstack, '{');
6129 obstack_grow (&util_obstack,
6130 IDENTIFIER_POINTER (name),
6131 strlen (IDENTIFIER_POINTER (name)));
6132 obstack_1grow (&util_obstack, '}');
6134 else /* we have an untagged structure or a typedef */
6135 obstack_grow (&util_obstack, "{?}", 3);
6139 tree name = TYPE_NAME (type);
6140 tree fields = TYPE_FIELDS (type);
6142 if (format == OBJC_ENCODE_INLINE_DEFS
6143 || generating_instance_variables)
6145 obstack_1grow (&util_obstack, '{');
6146 if (name && TREE_CODE (name) == IDENTIFIER_NODE)
6147 obstack_grow (&util_obstack,
6148 IDENTIFIER_POINTER (name),
6149 strlen (IDENTIFIER_POINTER (name)));
6151 obstack_1grow (&util_obstack, '?');
6153 obstack_1grow (&util_obstack, '=');
6155 for (; fields; fields = TREE_CHAIN (fields))
6157 if (generating_instance_variables)
6159 tree fname = DECL_NAME (fields);
6161 obstack_1grow (&util_obstack, '"');
6162 if (fname && TREE_CODE (fname) == IDENTIFIER_NODE)
6164 obstack_grow (&util_obstack,
6165 IDENTIFIER_POINTER (fname),
6166 strlen (IDENTIFIER_POINTER (fname)));
6168 obstack_1grow (&util_obstack, '"');
6170 encode_field_decl (fields, curtype, format);
6172 obstack_1grow (&util_obstack, '}');
6176 obstack_1grow (&util_obstack, '{');
6177 if (name && TREE_CODE (name) == IDENTIFIER_NODE)
6178 obstack_grow (&util_obstack,
6179 IDENTIFIER_POINTER (name),
6180 strlen (IDENTIFIER_POINTER (name)));
6181 else /* we have an untagged structure or a typedef */
6182 obstack_1grow (&util_obstack, '?');
6183 obstack_1grow (&util_obstack, '}');
6190 if (*obstack_next_free (&util_obstack) == '^'
6191 || format != OBJC_ENCODE_INLINE_DEFS)
6193 /* we have a reference - this is a NeXT extension--
6194 or we don't want the details. */
6195 if (TYPE_NAME (type)
6196 && TREE_CODE (TYPE_NAME (type)) == IDENTIFIER_NODE)
6198 obstack_1grow (&util_obstack, '(');
6199 obstack_grow (&util_obstack,
6200 IDENTIFIER_POINTER (TYPE_NAME (type)),
6201 strlen (IDENTIFIER_POINTER (TYPE_NAME (type))));
6202 obstack_1grow (&util_obstack, ')');
6204 else /* we have an untagged structure or a typedef */
6205 obstack_grow (&util_obstack, "(?)", 3);
6209 tree fields = TYPE_FIELDS (type);
6210 obstack_1grow (&util_obstack, '(');
6211 for ( ; fields; fields = TREE_CHAIN (fields))
6212 encode_field_decl (fields, curtype, format);
6213 obstack_1grow (&util_obstack, ')');
6219 obstack_1grow (&util_obstack, 'i');
6224 /* Support bitfields, the current version of Objective-C does not support
6225 them. the string will consist of one or more "b:n"'s where n is an
6226 integer describing the width of the bitfield. Currently, classes in
6227 the kit implement a method "-(char *)describeBitfieldStruct:" that
6228 simulates this...if they do not implement this method, the archiver
6229 assumes the bitfield is 16 bits wide (padded if necessary) and packed
6230 according to the GNU compiler. After looking at the "kit", it appears
6231 that all classes currently rely on this default behavior, rather than
6232 hand generating this string (which is tedious). */
6235 encode_bitfield (width, format)
6240 sprintf (buffer, "b%d", width);
6241 obstack_grow (&util_obstack, buffer, strlen (buffer));
6244 /* FORMAT will be OBJC_ENCODE_INLINE_DEFS or OBJC_ENCODE_DONT_INLINE_DEFS. */
6247 encode_type (type, curtype, format)
6252 enum tree_code code = TREE_CODE (type);
6254 if (code == INTEGER_TYPE)
6256 if (TREE_INT_CST_LOW (TYPE_MIN_VALUE (type)) == 0
6257 && TREE_INT_CST_HIGH (TYPE_MIN_VALUE (type)) == 0)
6259 /* unsigned integer types */
6261 if (TYPE_MODE (type) == QImode) /* 'C' */
6262 obstack_1grow (&util_obstack, 'C');
6263 else if (TYPE_MODE (type) == HImode) /* 'S' */
6264 obstack_1grow (&util_obstack, 'S');
6265 else if (TYPE_MODE (type) == SImode)
6267 if (type == long_unsigned_type_node)
6268 obstack_1grow (&util_obstack, 'L'); /* 'L' */
6270 obstack_1grow (&util_obstack, 'I'); /* 'I' */
6272 else if (TYPE_MODE (type) == DImode) /* 'Q' */
6273 obstack_1grow (&util_obstack, 'Q');
6275 else /* signed integer types */
6277 if (TYPE_MODE (type) == QImode) /* 'c' */
6278 obstack_1grow (&util_obstack, 'c');
6279 else if (TYPE_MODE (type) == HImode) /* 's' */
6280 obstack_1grow (&util_obstack, 's');
6281 else if (TYPE_MODE (type) == SImode) /* 'i' */
6283 if (type == long_integer_type_node)
6284 obstack_1grow (&util_obstack, 'l'); /* 'l' */
6286 obstack_1grow (&util_obstack, 'i'); /* 'i' */
6288 else if (TYPE_MODE (type) == DImode) /* 'q' */
6289 obstack_1grow (&util_obstack, 'q');
6292 else if (code == REAL_TYPE)
6294 /* floating point types */
6296 if (TYPE_MODE (type) == SFmode) /* 'f' */
6297 obstack_1grow (&util_obstack, 'f');
6298 else if (TYPE_MODE (type) == DFmode
6299 || TYPE_MODE (type) == TFmode) /* 'd' */
6300 obstack_1grow (&util_obstack, 'd');
6303 else if (code == VOID_TYPE) /* 'v' */
6304 obstack_1grow (&util_obstack, 'v');
6306 else if (code == ARRAY_TYPE)
6307 encode_array (type, curtype, format);
6309 else if (code == POINTER_TYPE)
6310 encode_pointer (type, curtype, format);
6312 else if (code == RECORD_TYPE || code == UNION_TYPE || code == ENUMERAL_TYPE)
6313 encode_aggregate (type, curtype, format);
6315 else if (code == FUNCTION_TYPE) /* '?' */
6316 obstack_1grow (&util_obstack, '?');
6320 encode_field_decl (field_decl, curtype, format)
6327 /* If this field is obviously a bitfield, or is a bitfield that has been
6328 clobbered to look like a ordinary integer mode, go ahead and generate
6329 the bitfield typing information. */
6330 type = TREE_TYPE (field_decl);
6331 if (DECL_BIT_FIELD (field_decl))
6332 encode_bitfield (DECL_FIELD_SIZE (field_decl), format);
6333 else if (TREE_CODE (TYPE_SIZE (type)) == INTEGER_CST
6334 && DECL_FIELD_SIZE (field_decl)
6335 && TYPE_MODE (type) > DECL_MODE (field_decl))
6336 encode_bitfield (DECL_FIELD_SIZE (field_decl), format);
6338 encode_type (TREE_TYPE (field_decl), curtype, format);
6342 expr_last (complex_expr)
6348 while ((next = TREE_OPERAND (complex_expr, 0)))
6349 complex_expr = next;
6350 return complex_expr;
6353 /* The selector of the current method,
6354 or NULL if we aren't compiling a method. */
6357 maybe_objc_method_name (decl)
6361 return METHOD_SEL_NAME (method_context);
6366 /* Transform a method definition into a function definition as follows:
6367 - synthesize the first two arguments, "self" and "_cmd". */
6370 start_method_def (method)
6375 /* Required to implement _msgSuper. */
6376 method_context = method;
6377 UOBJC_SUPER_decl = NULLT;
6379 pushlevel (0); /* Must be called BEFORE start_function. */
6381 /* Generate prototype declarations for arguments..."new-style". */
6383 if (TREE_CODE (method_context) == INSTANCE_METHOD_DECL)
6384 decl_specs = build_tree_list (NULLT, uprivate_record);
6386 /* really a `struct objc_class *'...however we allow people to
6387 assign to self...which changes its type midstream. */
6388 decl_specs = build_tree_list (NULLT, objc_object_reference);
6390 push_parm_decl (build_tree_list (decl_specs,
6391 build1 (INDIRECT_REF, NULLT, self_id)));
6393 #ifdef OBJC_INT_SELECTORS
6394 decl_specs = build_tree_list (NULLT, ridpointers[(int) RID_UNSIGNED]);
6395 decl_specs = tree_cons (NULLT, ridpointers[(int) RID_INT], decl_specs);
6396 push_parm_decl (build_tree_list (decl_specs, ucmd_id));
6397 #else /* not OBJC_INT_SELECTORS */
6398 decl_specs = build_tree_list (NULLT,
6399 xref_tag (RECORD_TYPE,
6400 get_identifier (TAG_SELECTOR)));
6401 push_parm_decl (build_tree_list (decl_specs,
6402 build1 (INDIRECT_REF, NULLT, ucmd_id)));
6403 #endif /* not OBJC_INT_SELECTORS */
6405 /* generate argument declarations if a keyword_decl */
6406 if (METHOD_SEL_ARGS (method))
6408 tree arglist = METHOD_SEL_ARGS (method);
6411 tree arg_spec = TREE_PURPOSE (TREE_TYPE (arglist));
6412 tree arg_decl = TREE_VALUE (TREE_TYPE (arglist));
6416 tree last_expr = expr_last (arg_decl);
6418 /* unite the abstract decl with its name */
6419 TREE_OPERAND (last_expr, 0) = KEYWORD_ARG_NAME (arglist);
6420 push_parm_decl (build_tree_list (arg_spec, arg_decl));
6421 /* unhook...restore the abstract declarator */
6422 TREE_OPERAND (last_expr, 0) = NULLT;
6425 push_parm_decl (build_tree_list (arg_spec,
6426 KEYWORD_ARG_NAME (arglist)));
6428 arglist = TREE_CHAIN (arglist);
6433 if (METHOD_ADD_ARGS (method) > (tree)1)
6435 /* we have a variable length selector - in "prototype" format */
6436 tree akey = TREE_PURPOSE (METHOD_ADD_ARGS (method));
6439 /* This must be done prior to calling pushdecl. pushdecl is
6440 going to change our chain on us. */
6441 tree nextkey = TREE_CHAIN (akey);
6449 warn_with_method (message, mtype, method)
6454 if (count_error (1) == 0)
6457 report_error_function (DECL_SOURCE_FILE (method));
6459 fprintf (stderr, "%s:%d: warning: ",
6460 DECL_SOURCE_FILE (method), DECL_SOURCE_LINE (method));
6461 bzero (errbuf, BUFSIZE);
6462 fprintf (stderr, "%s `%c%s'\n",
6463 message, mtype, gen_method_decl (method, errbuf));
6466 /* return 1 if `method' is consistent with `proto' */
6469 comp_method_with_proto (method, proto)
6472 static tree function_type = 0;
6474 /* create a function_type node once */
6477 struct obstack *ambient_obstack = current_obstack;
6479 current_obstack = &permanent_obstack;
6480 function_type = make_node (FUNCTION_TYPE);
6481 current_obstack = ambient_obstack;
6484 /* Install argument types - normally set by build_function_type. */
6485 TYPE_ARG_TYPES (function_type) = get_arg_type_list (proto, METHOD_DEF, 0);
6487 /* install return type */
6488 TREE_TYPE (function_type) = groktypename (TREE_TYPE (proto));
6490 return comptypes (TREE_TYPE (METHOD_DEFINITION (method)), function_type);
6493 /* return 1 if `proto1' is consistent with `proto2' */
6496 comp_proto_with_proto (proto1, proto2)
6497 tree proto1, proto2;
6499 static tree function_type1 = 0, function_type2 = 0;
6501 /* create a couple function_type node's once */
6502 if (!function_type1)
6504 struct obstack *ambient_obstack = current_obstack;
6506 current_obstack = &permanent_obstack;
6507 function_type1 = make_node (FUNCTION_TYPE);
6508 function_type2 = make_node (FUNCTION_TYPE);
6509 current_obstack = ambient_obstack;
6512 /* Install argument types - normally set by build_function_type. */
6513 TYPE_ARG_TYPES (function_type1) = get_arg_type_list (proto1, METHOD_REF, 0);
6514 TYPE_ARG_TYPES (function_type2) = get_arg_type_list (proto2, METHOD_REF, 0);
6516 /* install return type */
6517 TREE_TYPE (function_type1) = groktypename (TREE_TYPE (proto1));
6518 TREE_TYPE (function_type2) = groktypename (TREE_TYPE (proto2));
6520 return comptypes (function_type1, function_type2);
6523 /* - generate an identifier for the function. the format is "_n_cls",
6524 where 1 <= n <= nMethods, and cls is the name the implementation we
6526 - install the return type from the method declaration.
6527 - if we have a prototype, check for type consistency. */
6530 really_start_method (method, parmlist)
6531 tree method, parmlist;
6533 tree sc_spec, ret_spec, ret_decl, decl_specs;
6534 tree method_decl, method_id;
6535 char *buf, *sel_name, *class_name, *cat_name;
6537 /* synth the storage class & assemble the return type */
6538 sc_spec = tree_cons (NULLT, ridpointers[(int) RID_STATIC], NULLT);
6539 ret_spec = TREE_PURPOSE (TREE_TYPE (method));
6540 decl_specs = chainon (sc_spec, ret_spec);
6542 sel_name = IDENTIFIER_POINTER (METHOD_SEL_NAME (method));
6543 class_name = IDENTIFIER_POINTER (CLASS_NAME (implementation_context));
6544 cat_name = ((TREE_CODE (implementation_context)
6545 == CLASS_IMPLEMENTATION_TYPE)
6547 : IDENTIFIER_POINTER (CLASS_SUPER_NAME (implementation_context)));
6549 /* Make sure this is big enough for any plausible method label. */
6550 buf = (char *) alloca (50 + strlen (sel_name) + strlen (class_name)
6551 + (cat_name ? strlen (cat_name) : 0));
6553 OBJC_GEN_METHOD_LABEL (buf, TREE_CODE (method) == INSTANCE_METHOD_DECL,
6554 class_name, cat_name, sel_name, method_slot);
6556 method_id = get_identifier (buf);
6558 method_decl = build_nt (CALL_EXPR, method_id, parmlist, NULLT);
6560 /* check the declarator portion of the return type for the method */
6561 if ((ret_decl = TREE_VALUE (TREE_TYPE (method))))
6563 /* unite the complex decl (specified in the abstract decl) with the
6564 function decl just synthesized..(int *), (int (*)()), (int (*)[]). */
6565 tree save_expr = expr_last (ret_decl);
6567 TREE_OPERAND (save_expr, 0) = method_decl;
6568 method_decl = ret_decl;
6569 /* fool the parser into thinking it is starting a function */
6570 start_function (decl_specs, method_decl, 0);
6571 /* unhook...this has the effect of restoring the abstract declarator */
6572 TREE_OPERAND (save_expr, 0) = NULLT;
6576 TREE_VALUE (TREE_TYPE (method)) = method_decl;
6577 /* fool the parser into thinking it is starting a function */
6578 start_function (decl_specs, method_decl, 0);
6579 /* unhook...this has the effect of restoring the abstract declarator */
6580 TREE_VALUE (TREE_TYPE (method)) = NULLT;
6583 METHOD_DEFINITION (method) = current_function_decl;
6585 /* Check consistency...start_function, pushdecl, duplicate_decls. */
6587 if (implementation_template != implementation_context)
6591 if (TREE_CODE (method) == INSTANCE_METHOD_DECL)
6592 proto = lookup_instance_method_static (implementation_template,
6593 METHOD_SEL_NAME (method));
6595 proto = lookup_class_method_static (implementation_template,
6596 METHOD_SEL_NAME (method));
6598 if (proto && ! comp_method_with_proto (method, proto))
6600 char type = (TREE_CODE (method) == INSTANCE_METHOD_DECL ? '-' : '+');
6602 warn_with_method ("conflicting types for", type, method);
6603 warn_with_method ("previous declaration of", type, proto);
6608 /* The following routine is always called...this "architecture" is to
6609 accommodate "old-style" variable length selectors.
6611 - a:a b:b // prototype ; id c; id d; // old-style. */
6614 continue_method_def ()
6618 if (METHOD_ADD_ARGS (method_context) == (tree)1)
6619 /* We have a `, ...' immediately following the selector. */
6620 parmlist = get_parm_info (0);
6622 parmlist = get_parm_info (1); /* place a `void_at_end' */
6624 /* Set self_decl from the first argument...this global is used by
6625 build_ivar_reference calling build_indirect_ref. */
6626 self_decl = TREE_PURPOSE (parmlist);
6628 poplevel (0, 0, 0); /* must be called BEFORE start_function. */
6630 really_start_method (method_context, parmlist);
6632 store_parm_decls (); /* must be called AFTER start_function. */
6635 /* Called by the parser, from the `pushlevel' production. */
6640 if (!UOBJC_SUPER_decl)
6642 UOBJC_SUPER_decl = start_decl (get_identifier (UTAG_SUPER),
6643 build_tree_list (NULLT,
6644 objc_super_template),
6647 finish_decl (UOBJC_SUPER_decl, NULLT, NULLT);
6649 /* this prevents `unused variable' warnings when compiling with -Wall. */
6650 DECL_IN_SYSTEM_HEADER (UOBJC_SUPER_decl) = 1;
6654 /* _n_Method (id self, SEL sel, ...)
6656 struct objc_super _S;
6657 _msgSuper ((_S.self = self, _S.class = _cls, &_S), ...);
6661 get_super_receiver ()
6665 tree super_expr, super_expr_list;
6667 /* set receiver to self */
6668 super_expr = build_component_ref (UOBJC_SUPER_decl, self_id);
6669 super_expr = build_modify_expr (super_expr, NOP_EXPR, self_decl);
6670 super_expr_list = build_tree_list (NULLT, super_expr);
6672 /* set class to begin searching */
6673 super_expr = build_component_ref (UOBJC_SUPER_decl,
6674 get_identifier ("class"));
6676 if (TREE_CODE (implementation_context) == CLASS_IMPLEMENTATION_TYPE)
6678 /* [_cls, __cls]Super are "pre-built" in
6679 synth_forward_declarations. */
6681 super_expr = build_modify_expr (super_expr, NOP_EXPR,
6682 ((TREE_CODE (method_context)
6683 == INSTANCE_METHOD_DECL)
6685 : uucls_super_ref));
6687 else /* we have a category... */
6689 tree super_name = CLASS_SUPER_NAME (implementation_template);
6692 if (!super_name) /* Barf if super used in a category of Object. */
6694 error ("no super class declared in interface for `%s'",
6695 IDENTIFIER_POINTER (CLASS_NAME (implementation_template)));
6696 return error_mark_node;
6699 if (flag_next_runtime)
6701 super_class = get_class_reference (super_name);
6702 if (TREE_CODE (method_context) == CLASS_METHOD_DECL)
6704 = build_component_ref (build_indirect_ref (super_class, "->"),
6705 get_identifier ("isa"));
6709 add_class_reference (super_name);
6710 super_class = (TREE_CODE (method_context) == INSTANCE_METHOD_DECL
6711 ? objc_get_class_decl : objc_get_meta_class_decl);
6712 assemble_external (super_class);
6714 = build_function_call
6716 build_tree_list (NULLT,
6717 my_build_string (IDENTIFIER_LENGTH (super_name) + 1,
6718 IDENTIFIER_POINTER (super_name))));
6722 TREE_TYPE (super_class) = TREE_TYPE (ucls_super_ref);
6723 super_expr = build_modify_expr (super_expr, NOP_EXPR, super_class);
6725 chainon (super_expr_list, build_tree_list (NULL_TREE, super_expr));
6727 super_expr = build_unary_op (ADDR_EXPR, UOBJC_SUPER_decl, 0);
6728 chainon (super_expr_list, build_tree_list (NULL_TREE, super_expr));
6730 return build_compound_expr (super_expr_list);
6734 error ("[super ...] must appear in a method context");
6735 return error_mark_node;
6740 encode_method_def (func_decl)
6745 int max_parm_end = 0;
6750 encode_type (TREE_TYPE (TREE_TYPE (func_decl)),
6751 obstack_object_size (&util_obstack),
6752 OBJC_ENCODE_INLINE_DEFS);
6754 for (parms = DECL_ARGUMENTS (func_decl); parms;
6755 parms = TREE_CHAIN (parms))
6757 int parm_end = (forwarding_offset (parms)
6758 + (TREE_INT_CST_LOW (TYPE_SIZE (TREE_TYPE (parms)))
6761 if (!offset_is_register && parm_end > max_parm_end)
6762 max_parm_end = parm_end;
6765 stack_size = max_parm_end - OBJC_FORWARDING_MIN_OFFSET;
6767 sprintf (buffer, "%d", stack_size);
6768 obstack_grow (&util_obstack, buffer, strlen (buffer));
6770 /* argument types */
6771 for (parms = DECL_ARGUMENTS (func_decl); parms;
6772 parms = TREE_CHAIN (parms))
6775 encode_type (TREE_TYPE (parms),
6776 obstack_object_size (&util_obstack),
6777 OBJC_ENCODE_INLINE_DEFS);
6779 /* compute offset */
6780 sprintf (buffer, "%d", forwarding_offset (parms));
6782 /* indicate register */
6783 if (offset_is_register)
6784 obstack_1grow (&util_obstack, '+');
6786 obstack_grow (&util_obstack, buffer, strlen (buffer));
6789 obstack_1grow (&util_obstack, 0); /* null terminate string */
6790 result = get_identifier (obstack_finish (&util_obstack));
6791 obstack_free (&util_obstack, util_firstobj);
6796 finish_method_def ()
6798 METHOD_ENCODING (method_context) = encode_method_def (current_function_decl);
6800 finish_function (0);
6802 /* this must be done AFTER finish_function, since the optimizer may
6803 find "may be used before set" errors. */
6804 method_context = NULLT; /* required to implement _msgSuper. */
6808 lang_report_error_function (decl)
6813 fprintf (stderr, "In method `%s'\n",
6814 IDENTIFIER_POINTER (METHOD_SEL_NAME (method_context)));
6822 is_complex_decl (type)
6825 return (TREE_CODE (type) == ARRAY_TYPE
6826 || TREE_CODE (type) == FUNCTION_TYPE
6827 || (TREE_CODE (type) == POINTER_TYPE && ! IS_ID (type)));
6831 /* Code to convert a decl node into text for a declaration in C. */
6833 static char tmpbuf[256];
6836 adorn_decl (decl, str)
6840 enum tree_code code = TREE_CODE (decl);
6842 if (code == ARRAY_REF)
6844 tree an_int_cst = TREE_OPERAND (decl, 1);
6846 if (an_int_cst && TREE_CODE (an_int_cst) == INTEGER_CST)
6847 sprintf (str + strlen (str), "[%d]", TREE_INT_CST_LOW (an_int_cst));
6851 else if (code == ARRAY_TYPE)
6853 tree an_int_cst = TYPE_SIZE (decl);
6854 tree array_of = TREE_TYPE (decl);
6856 if (an_int_cst && TREE_CODE (an_int_cst) == INTEGER_TYPE)
6857 sprintf (str + strlen (str), "[%d]",
6858 (TREE_INT_CST_LOW (an_int_cst)
6859 / TREE_INT_CST_LOW (TYPE_SIZE (array_of))));
6863 else if (code == CALL_EXPR)
6865 tree chain = TREE_PURPOSE (TREE_OPERAND (decl, 1));
6870 gen_declaration (chain, str);
6871 chain = TREE_CHAIN (chain);
6877 else if (code == FUNCTION_TYPE)
6879 tree chain = TYPE_ARG_TYPES (decl); /* a list of types */
6882 while (chain && TREE_VALUE (chain) != void_type_node)
6884 gen_declaration (TREE_VALUE (chain), str);
6885 chain = TREE_CHAIN (chain);
6886 if (chain && TREE_VALUE (chain) != void_type_node)
6891 else if (code == INDIRECT_REF)
6893 strcpy (tmpbuf, "*");
6894 if (TREE_TYPE (decl) && TREE_CODE (TREE_TYPE (decl)) == TREE_LIST)
6898 for (chain = nreverse (copy_list (TREE_TYPE (decl)));
6900 chain = TREE_CHAIN (chain))
6902 if (TREE_CODE (TREE_VALUE (chain)) == IDENTIFIER_NODE)
6904 strcat (tmpbuf, " ");
6905 strcat (tmpbuf, IDENTIFIER_POINTER (TREE_VALUE (chain)));
6909 strcat (tmpbuf, " ");
6911 strcat (tmpbuf, str);
6912 strcpy (str, tmpbuf);
6914 else if (code == POINTER_TYPE)
6916 strcpy (tmpbuf, "*");
6917 if (TREE_READONLY (decl) || TYPE_VOLATILE (decl))
6919 if (TREE_READONLY (decl))
6920 strcat (tmpbuf, " const");
6921 if (TYPE_VOLATILE (decl))
6922 strcat (tmpbuf, " volatile");
6924 strcat (tmpbuf, " ");
6926 strcat (tmpbuf, str);
6927 strcpy (str, tmpbuf);
6932 gen_declarator (decl, buf, name)
6939 enum tree_code code = TREE_CODE (decl);
6949 op = TREE_OPERAND (decl, 0);
6951 /* we have a pointer to a function or array...(*)(), (*)[] */
6952 if ((code == ARRAY_REF || code == CALL_EXPR)
6953 && op && TREE_CODE (op) == INDIRECT_REF)
6956 str = gen_declarator (op, buf, name);
6960 strcpy (tmpbuf, "(");
6961 strcat (tmpbuf, str);
6962 strcat (tmpbuf, ")");
6963 strcpy (str, tmpbuf);
6966 adorn_decl (decl, str);
6975 /* this clause is done iteratively...rather than recursively */
6978 op = (is_complex_decl (TREE_TYPE (decl))
6979 ? TREE_TYPE (decl) : NULLT);
6981 adorn_decl (decl, str);
6983 /* we have a pointer to a function or array...(*)(), (*)[] */
6984 if (code == POINTER_TYPE
6985 && op && (TREE_CODE (op) == FUNCTION_TYPE
6986 || TREE_CODE (op) == ARRAY_TYPE))
6988 strcpy (tmpbuf, "(");
6989 strcat (tmpbuf, str);
6990 strcat (tmpbuf, ")");
6991 strcpy (str, tmpbuf);
6994 decl = (is_complex_decl (TREE_TYPE (decl))
6995 ? TREE_TYPE (decl) : NULLT);
6997 while (decl && (code = TREE_CODE (decl)));
7001 case IDENTIFIER_NODE:
7002 /* will only happen if we are processing a "raw" expr-decl. */
7003 strcpy (buf, IDENTIFIER_POINTER (decl));
7009 else /* we have an abstract declarator or a _DECL node */
7017 gen_declspecs (declspecs, buf, raw)
7026 for (chain = nreverse (copy_list (declspecs));
7027 chain; chain = TREE_CHAIN (chain))
7029 tree aspec = TREE_VALUE (chain);
7031 if (TREE_CODE (aspec) == IDENTIFIER_NODE)
7032 strcat (buf, IDENTIFIER_POINTER (aspec));
7033 else if (TREE_CODE (aspec) == RECORD_TYPE)
7035 if (TYPE_NAME (aspec))
7037 tree protocol_list = TYPE_PROTOCOL_LIST (aspec);
7039 if (! TREE_STATIC_TEMPLATE (aspec))
7040 strcat (buf, "struct ");
7041 strcat (buf, IDENTIFIER_POINTER (TYPE_NAME (aspec)));
7046 tree chain = protocol_list;
7051 strcat (buf, IDENTIFIER_POINTER (PROTOCOL_NAME (TREE_VALUE (chain))));
7052 chain = TREE_CHAIN (chain);
7060 strcat (buf, "untagged struct");
7062 else if (TREE_CODE (aspec) == UNION_TYPE)
7064 if (TYPE_NAME (aspec))
7066 if (! TREE_STATIC_TEMPLATE (aspec))
7067 strcat (buf, "union ");
7068 strcat (buf, IDENTIFIER_POINTER (TYPE_NAME (aspec)));
7071 strcat (buf, "untagged union");
7073 else if (TREE_CODE (aspec) == ENUMERAL_TYPE)
7075 if (TYPE_NAME (aspec))
7077 if (! TREE_STATIC_TEMPLATE (aspec))
7078 strcat (buf, "enum ");
7079 strcat (buf, IDENTIFIER_POINTER (TYPE_NAME (aspec)));
7082 strcat (buf, "untagged enum");
7084 else if (TREE_CODE (aspec) == TYPE_DECL && DECL_NAME (aspec))
7086 strcat (buf, IDENTIFIER_POINTER (DECL_NAME (aspec)));
7089 else if (IS_ID (aspec))
7091 tree protocol_list = TYPE_PROTOCOL_LIST (aspec);
7096 tree chain = protocol_list;
7101 strcat (buf, IDENTIFIER_POINTER (PROTOCOL_NAME (TREE_VALUE (chain))));
7102 chain = TREE_CHAIN (chain);
7109 if (TREE_CHAIN (chain))
7115 /* type qualifiers */
7117 if (TREE_READONLY (declspecs))
7118 strcat (buf, "const ");
7119 if (TYPE_VOLATILE (declspecs))
7120 strcat (buf, "volatile ");
7122 switch (TREE_CODE (declspecs))
7124 /* type specifiers */
7126 case INTEGER_TYPE: /* signed integer types */
7127 declspecs = TYPE_MAIN_VARIANT (declspecs);
7129 if (declspecs == short_integer_type_node) /* 's' */
7130 strcat (buf, "short int ");
7131 else if (declspecs == integer_type_node) /* 'i' */
7132 strcat (buf, "int ");
7133 else if (declspecs == long_integer_type_node) /* 'l' */
7134 strcat (buf, "long int ");
7135 else if (declspecs == long_long_integer_type_node) /* 'l' */
7136 strcat (buf, "long long int ");
7137 else if (declspecs == signed_char_type_node /* 'c' */
7138 || declspecs == char_type_node)
7139 strcat (buf, "char ");
7141 /* unsigned integer types */
7143 else if (declspecs == short_unsigned_type_node) /* 'S' */
7144 strcat (buf, "unsigned short ");
7145 else if (declspecs == unsigned_type_node) /* 'I' */
7146 strcat (buf, "unsigned int ");
7147 else if (declspecs == long_unsigned_type_node) /* 'L' */
7148 strcat (buf, "unsigned long ");
7149 else if (declspecs == long_long_unsigned_type_node) /* 'L' */
7150 strcat (buf, "unsigned long long ");
7151 else if (declspecs == unsigned_char_type_node) /* 'C' */
7152 strcat (buf, "unsigned char ");
7155 case REAL_TYPE: /* floating point types */
7156 declspecs = TYPE_MAIN_VARIANT (declspecs);
7158 if (declspecs == float_type_node) /* 'f' */
7159 strcat (buf, "float ");
7160 else if (declspecs == double_type_node) /* 'd' */
7161 strcat (buf, "double ");
7162 else if (declspecs == long_double_type_node) /* 'd' */
7163 strcat (buf, "long double ");
7167 if (TYPE_NAME (declspecs)
7168 && TREE_CODE (TYPE_NAME (declspecs)) == IDENTIFIER_NODE)
7170 tree protocol_list = TYPE_PROTOCOL_LIST (declspecs);
7172 if (! TREE_STATIC_TEMPLATE (declspecs))
7173 strcat (buf, "struct ");
7174 strcat (buf, IDENTIFIER_POINTER (TYPE_NAME (declspecs)));
7178 tree chain = protocol_list;
7183 strcat (buf, IDENTIFIER_POINTER (PROTOCOL_NAME (TREE_VALUE (chain))));
7184 chain = TREE_CHAIN (chain);
7192 strcat (buf, "untagged struct");
7198 if (TYPE_NAME (declspecs)
7199 && TREE_CODE (TYPE_NAME (declspecs)) == IDENTIFIER_NODE)
7201 strcat (buf, "union ");
7202 strcat (buf, IDENTIFIER_POINTER (TYPE_NAME (declspecs)));
7206 strcat (buf, "untagged union ");
7210 if (TYPE_NAME (declspecs)
7211 && TREE_CODE (TYPE_NAME (declspecs)) == IDENTIFIER_NODE)
7213 strcat (buf, "enum ");
7214 strcat (buf, IDENTIFIER_POINTER (TYPE_NAME (declspecs)));
7218 strcat (buf, "untagged enum ");
7222 strcat (buf, "void ");
7228 tree protocol_list = TYPE_PROTOCOL_LIST (declspecs);
7233 tree chain = protocol_list;
7238 strcat (buf, IDENTIFIER_POINTER (PROTOCOL_NAME (TREE_VALUE (chain))));
7239 chain = TREE_CHAIN (chain);
7251 gen_declaration (atype_or_adecl, buf)
7252 tree atype_or_adecl;
7257 if (TREE_CODE (atype_or_adecl) == TREE_LIST)
7259 tree declspecs; /* "identifier_node", "record_type" */
7260 tree declarator; /* "array_ref", "indirect_ref", "call_expr"... */
7262 /* we have a "raw", abstract declarator (typename) */
7263 declarator = TREE_VALUE (atype_or_adecl);
7264 declspecs = TREE_PURPOSE (atype_or_adecl);
7266 gen_declspecs (declspecs, buf, 1);
7270 strcat (buf, gen_declarator (declarator, declbuf, ""));
7276 tree declspecs; /* "integer_type", "real_type", "record_type"... */
7277 tree declarator; /* "array_type", "function_type", "pointer_type". */
7279 if (TREE_CODE (atype_or_adecl) == FIELD_DECL
7280 || TREE_CODE (atype_or_adecl) == PARM_DECL
7281 || TREE_CODE (atype_or_adecl) == FUNCTION_DECL)
7282 atype = TREE_TYPE (atype_or_adecl);
7284 atype = atype_or_adecl; /* assume we have a *_type node */
7286 if (is_complex_decl (atype))
7290 /* get the declaration specifier...it is at the end of the list */
7291 declarator = chain = atype;
7293 chain = TREE_TYPE (chain); /* not TREE_CHAIN (chain); */
7294 while (is_complex_decl (chain));
7303 gen_declspecs (declspecs, buf, 0);
7305 if (TREE_CODE (atype_or_adecl) == FIELD_DECL
7306 || TREE_CODE (atype_or_adecl) == PARM_DECL
7307 || TREE_CODE (atype_or_adecl) == FUNCTION_DECL)
7309 char *decl_name = (DECL_NAME (atype_or_adecl)
7310 ? IDENTIFIER_POINTER (DECL_NAME (atype_or_adecl))
7316 strcat (buf, gen_declarator (declarator, declbuf, decl_name));
7318 else if (decl_name[0])
7321 strcat (buf, decl_name);
7324 else if (declarator)
7327 strcat (buf, gen_declarator (declarator, declbuf, ""));
7333 #define RAW_TYPESPEC(meth) (TREE_VALUE (TREE_PURPOSE (TREE_TYPE (meth))))
7336 gen_method_decl (method, buf)
7342 if (RAW_TYPESPEC (method) != objc_object_reference)
7345 gen_declaration (TREE_TYPE (method), buf);
7349 chain = METHOD_SEL_ARGS (method);
7351 { /* we have a chain of keyword_decls */
7354 if (KEYWORD_KEY_NAME (chain))
7355 strcat (buf, IDENTIFIER_POINTER (KEYWORD_KEY_NAME (chain)));
7358 if (RAW_TYPESPEC (chain) != objc_object_reference)
7361 gen_declaration (TREE_TYPE (chain), buf);
7364 strcat (buf, IDENTIFIER_POINTER (KEYWORD_ARG_NAME (chain)));
7365 if ((chain = TREE_CHAIN (chain)))
7370 if (METHOD_ADD_ARGS (method) == (tree)1)
7371 strcat (buf, ", ...");
7372 else if (METHOD_ADD_ARGS (method))
7374 /* we have a tree list node as generate by get_parm_info. */
7375 chain = TREE_PURPOSE (METHOD_ADD_ARGS (method));
7376 /* know we have a chain of parm_decls */
7380 gen_declaration (chain, buf);
7381 chain = TREE_CHAIN (chain);
7385 else /* we have a unary selector */
7386 strcat (buf, IDENTIFIER_POINTER (METHOD_SEL_NAME (method)));
7394 dump_interface (fp, chain)
7398 char *buf = (char *)xmalloc (256);
7399 char *my_name = IDENTIFIER_POINTER (CLASS_NAME (chain));
7400 tree ivar_decls = CLASS_RAW_IVARS (chain);
7401 tree nst_methods = CLASS_NST_METHODS (chain);
7402 tree cls_methods = CLASS_CLS_METHODS (chain);
7404 fprintf (fp, "\n@interface %s", my_name);
7406 if (CLASS_SUPER_NAME (chain))
7408 char *super_name = IDENTIFIER_POINTER (CLASS_SUPER_NAME (chain));
7409 fprintf (fp, " : %s\n", super_name);
7416 fprintf (fp, "{\n");
7420 fprintf (fp, "\t%s;\n", gen_declaration (ivar_decls, buf));
7421 ivar_decls = TREE_CHAIN (ivar_decls);
7424 fprintf (fp, "}\n");
7430 fprintf (fp, "- %s;\n", gen_method_decl (nst_methods, buf));
7431 nst_methods = TREE_CHAIN (nst_methods);
7437 fprintf (fp, "+ %s;\n", gen_method_decl (cls_methods, buf));
7438 cls_methods = TREE_CHAIN (cls_methods);
7440 fprintf (fp, "\n@end");
7446 /* Add the special tree codes of Objective C to the tables. */
7448 #define LAST_CODE LAST_AND_UNUSED_TREE_CODE
7450 gcc_obstack_init (&util_obstack);
7451 util_firstobj = (char *) obstack_finish (&util_obstack);
7454 = (char **) xrealloc (tree_code_type,
7455 sizeof (char *) * LAST_OBJC_TREE_CODE);
7457 = (int *) xrealloc (tree_code_length,
7458 sizeof (int) * LAST_OBJC_TREE_CODE);
7460 = (char **) xrealloc (tree_code_name,
7461 sizeof (char *) * LAST_OBJC_TREE_CODE);
7462 bcopy (objc_tree_code_type,
7463 tree_code_type + (int) LAST_CODE,
7464 (((int) LAST_OBJC_TREE_CODE - (int) LAST_CODE)
7465 * sizeof (char *)));
7466 bcopy (objc_tree_code_length,
7467 tree_code_length + (int) LAST_CODE,
7468 (((int) LAST_OBJC_TREE_CODE - (int) LAST_CODE)
7470 bcopy (objc_tree_code_name,
7471 tree_code_name + (int) LAST_CODE,
7472 (((int) LAST_OBJC_TREE_CODE - (int) LAST_CODE)
7473 * sizeof (char *)));
7475 errbuf = (char *)xmalloc (BUFSIZE);
7477 synth_module_prologue ();
7483 struct imp_entry *impent;
7485 /* The internally generated initializers appear to have missing braces.
7486 Don't warn about this. */
7487 int save_warn_missing_braces = warn_missing_braces;
7488 warn_missing_braces = 0;
7490 generate_forward_declaration_to_string_table ();
7492 #ifdef OBJC_PROLOGUE
7496 if (implementation_context || class_names_chain
7497 || meth_var_names_chain || meth_var_types_chain || sel_ref_chain)
7498 generate_objc_symtab_decl ();
7500 for (impent = imp_list; impent; impent = impent->next)
7502 implementation_context = impent->imp_context;
7503 implementation_template = impent->imp_template;
7505 UOBJC_CLASS_decl = impent->class_decl;
7506 UOBJC_METACLASS_decl = impent->meta_decl;
7508 if (TREE_CODE (implementation_context) == CLASS_IMPLEMENTATION_TYPE)
7510 /* all of the following reference the string pool... */
7511 generate_ivar_lists ();
7512 generate_dispatch_tables ();
7513 generate_shared_structures ();
7517 generate_dispatch_tables ();
7518 generate_category (implementation_context);
7522 /* If we are using an array of selectors, we must always
7523 finish up the array decl even if no selectors were used. */
7524 if (! flag_next_runtime || sel_ref_chain)
7525 build_selector_translation_table ();
7528 generate_protocols ();
7530 if (implementation_context || class_names_chain
7531 || meth_var_names_chain || meth_var_types_chain || sel_ref_chain)
7533 /* Arrange for Objc data structures to be initialized at run time. */
7534 char *init_name = build_module_descriptor ();
7536 assemble_constructor (init_name);
7539 /* dump the class references...this forces the appropriate classes
7540 to be linked into the executable image, preserving unix archive
7541 semantics...this can be removed when we move to a more dynamically
7542 linked environment. */
7543 for (chain = cls_ref_chain; chain; chain = TREE_CHAIN (chain))
7545 handle_class_ref (chain);
7546 if (TREE_PURPOSE (chain))
7547 generate_classref_translation_entry (chain);
7550 for (impent = imp_list; impent; impent = impent->next)
7551 handle_impent (impent);
7553 /* dump the string table last */
7555 generate_strings ();
7557 if (flag_gen_declaration)
7559 add_class (implementation_context);
7560 dump_interface (gen_declaration_file, implementation_context);
7568 /* Run through the selector hash tables and print a warning for any
7569 selector which has multiple methods. */
7571 for (slot = 0; slot < SIZEHASHTABLE; slot++)
7572 for (hsh = cls_method_hash_list[slot]; hsh; hsh = hsh->next)
7575 tree meth = hsh->key;
7576 char type = (TREE_CODE (meth) == INSTANCE_METHOD_DECL
7580 warning ("potential selector conflict for method `%s'",
7581 IDENTIFIER_POINTER (METHOD_SEL_NAME (meth)));
7582 warn_with_method ("found", type, meth);
7583 for (loop = hsh->list; loop; loop = loop->next)
7584 warn_with_method ("found", type, loop->value);
7587 for (slot = 0; slot < SIZEHASHTABLE; slot++)
7588 for (hsh = nst_method_hash_list[slot]; hsh; hsh = hsh->next)
7591 tree meth = hsh->key;
7592 char type = (TREE_CODE (meth) == INSTANCE_METHOD_DECL
7596 warning ("potential selector conflict for method `%s'",
7597 IDENTIFIER_POINTER (METHOD_SEL_NAME (meth)));
7598 warn_with_method ("found", type, meth);
7599 for (loop = hsh->list; loop; loop = loop->next)
7600 warn_with_method ("found", type, loop->value);
7604 warn_missing_braces = save_warn_missing_braces;
7607 /* Subroutines of finish_objc. */
7610 generate_classref_translation_entry (chain)
7613 tree expr, name, decl_specs, decl, sc_spec;
7616 type = TREE_TYPE (TREE_PURPOSE (chain));
7618 expr = add_objc_string (TREE_VALUE (chain), class_names);
7619 expr = build_c_cast (type, expr); /* cast! */
7621 name = DECL_NAME (TREE_PURPOSE (chain));
7623 sc_spec = build_tree_list (NULLT, ridpointers[(int) RID_STATIC]);
7625 /* static struct objc_class * _OBJC_CLASS_REFERENCES_n = ...; */
7626 decl_specs = tree_cons (NULLT, type, sc_spec);
7628 /* the `decl' that is returned from start_decl is the one that we
7629 forward declared in `build_class_reference'. */
7630 decl = start_decl (name, decl_specs, 1);
7631 end_temporary_allocation ();
7632 finish_decl (decl, expr, NULLT);
7637 handle_class_ref (chain)
7640 char *name = IDENTIFIER_POINTER (TREE_VALUE (chain));
7641 if (! flag_next_runtime)
7644 char *string = (char *) alloca (strlen (name) + 30);
7647 sprintf (string, "%sobjc_class_name_%s",
7648 (flag_next_runtime ? "." : "__"), name);
7650 /* Make a decl for this name, so we can use its address in a tree. */
7651 decl = build_decl (VAR_DECL, get_identifier (string), char_type_node);
7652 DECL_EXTERNAL (decl) = 1;
7653 TREE_PUBLIC (decl) = 1;
7656 rest_of_decl_compilation (decl, 0, 0, 0);
7658 /* Make following constant read-only (why not)? */
7659 readonly_data_section ();
7661 exp = build1 (ADDR_EXPR, string_type_node, decl);
7663 /* Align the section properly. */
7664 assemble_constant_align (exp);
7666 /* Inform the assembler about this new external thing. */
7667 assemble_external (decl);
7669 /* Output a constant to reference this address. */
7670 output_constant (exp, int_size_in_bytes (string_type_node));
7674 /* This overreliance on our assembler (i.e. lack of portability)
7675 should be dealt with at some point. The GNU strategy (above)
7676 won't work either, but it is a start. */
7677 char *string = (char *) alloca (strlen (name) + 30);
7678 sprintf (string, ".reference .objc_class_name_%s", name);
7679 assemble_asm (my_build_string (strlen (string) + 1, string));
7684 handle_impent (impent)
7685 struct imp_entry *impent;
7687 implementation_context = impent->imp_context;
7688 implementation_template = impent->imp_template;
7690 if (TREE_CODE (impent->imp_context) == CLASS_IMPLEMENTATION_TYPE)
7692 char *class_name = IDENTIFIER_POINTER (CLASS_NAME (impent->imp_context));
7693 char *string = (char *) alloca (strlen (class_name) + 30);
7695 if (flag_next_runtime)
7697 /* Grossly unportable.
7698 People should know better than to assume
7699 such things about assembler syntax! */
7700 sprintf (string, ".objc_class_name_%s=0", class_name);
7701 assemble_asm (my_build_string (strlen (string) + 1, string));
7703 sprintf (string, ".globl .objc_class_name_%s", class_name);
7704 assemble_asm (my_build_string (strlen (string) + 1, string));
7708 sprintf (string, "%sobjc_class_name_%s",
7709 (flag_next_runtime ? "." : "__"), class_name);
7710 assemble_global (string);
7711 assemble_label (string);
7714 else if (TREE_CODE (impent->imp_context) == CATEGORY_IMPLEMENTATION_TYPE)
7716 char *class_name = IDENTIFIER_POINTER (CLASS_NAME (impent->imp_context));
7717 char *class_super_name
7718 = IDENTIFIER_POINTER (CLASS_SUPER_NAME (impent->imp_context));
7719 char *string = (char *) alloca (strlen (class_name)
7720 + strlen (class_super_name) + 30);
7722 /* Do the same for categories. Even though no references to these
7723 symbols are generated automatically by the compiler, it gives
7724 you a handle to pull them into an archive by hand. */
7725 if (flag_next_runtime)
7727 /* Grossly unportable. */
7728 sprintf (string, ".objc_category_name_%s_%s=0",
7729 class_name, class_super_name);
7730 assemble_asm (my_build_string (strlen (string) + 1, string));
7732 sprintf (string, ".globl .objc_category_name_%s_%s",
7733 class_name, class_super_name);
7734 assemble_asm (my_build_string (strlen (string) + 1, string));
7738 sprintf (string, "%sobjc_category_name_%s_%s",
7739 (flag_next_runtime ? "." : "__"),
7740 class_name, class_super_name);
7741 assemble_global (string);
7742 assemble_label (string);
7753 char *buf = (char *)xmalloc (256);
7755 { /* dump function prototypes */
7756 tree loop = UOBJC_MODULES_decl;
7758 fprintf (fp, "\n\nfunction prototypes:\n");
7761 if (TREE_CODE (loop) == FUNCTION_DECL && DECL_INITIAL (loop))
7763 /* we have a function definition - generate prototype */
7764 bzero (errbuf, BUFSIZE);
7765 gen_declaration (loop, errbuf);
7766 fprintf (fp, "%s;\n", errbuf);
7768 loop = TREE_CHAIN (loop);
7771 { /* dump global chains */
7773 int i, index = 0, offset = 0;
7776 for (i = 0; i < SIZEHASHTABLE; i++)
7778 if (hashlist = nst_method_hash_list[i])
7780 fprintf (fp, "\n\nnst_method_hash_list[%d]:\n", i);
7784 fprintf (fp, "-%s;\n", gen_method_decl (hashlist->key, buf));
7785 hashlist = hashlist->next;
7790 for (i = 0; i < SIZEHASHTABLE; i++)
7792 if (hashlist = cls_method_hash_list[i])
7794 fprintf (fp, "\n\ncls_method_hash_list[%d]:\n", i);
7798 fprintf (fp, "-%s;\n", gen_method_decl (hashlist->key, buf));
7799 hashlist = hashlist->next;
7804 fprintf (fp, "\nsel_refdef_chain:\n");
7805 for (loop = sel_refdef_chain; loop; loop = TREE_CHAIN (loop))
7807 fprintf (fp, "(index: %4d offset: %4d) %s\n", index, offset,
7808 IDENTIFIER_POINTER (TREE_VALUE (loop)));
7810 /* add one for the '\0' character */
7811 offset += IDENTIFIER_LENGTH (TREE_VALUE (loop)) + 1;
7813 fprintf (fp, "\n (max_selector_index: %4d.\n", max_selector_index);
7819 print_lang_statistics ()