1 /* Implement classes and message passing for Objective C.
2 Copyright (C) 1992 Free Software Foundation, Inc.
5 This file is part of GNU CC.
7 GNU CC is free software; you can redistribute it and/or modify
8 it under the terms of the GNU General Public License as published by
9 the Free Software Foundation; either version 2, or (at your option)
12 GNU CC is distributed in the hope that it will be useful,
13 but WITHOUT ANY WARRANTY; without even the implied warranty of
14 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
15 GNU General Public License for more details.
17 You should have received a copy of the GNU General Public License
18 along with GNU CC; see the file COPYING. If not, write to
19 the Free Software Foundation, 675 Mass Ave, Cambridge, MA 02139, USA. */
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 */
50 /* This is the default way of generating a method name. */
51 /* I am not sure it is really correct.
52 Perhaps there's a danger that it will make name conflicts
53 if method names contain underscores. -- rms. */
54 #ifndef OBJC_GEN_METHOD_LABEL
55 #define OBJC_GEN_METHOD_LABEL(BUF, IS_INST, CLASS_NAME, CAT_NAME, SEL_NAME, NUM) \
58 sprintf ((BUF), "_%s_%s_%s", \
59 ((IS_INST) ? "i" : "c"), \
62 for (temp = (BUF); *temp; temp++) \
63 if (*temp == ':') *temp = '_'; \
67 /* These need specifying. */
68 #ifndef OBJC_FORWARDING_STACK_OFFSET
69 #define OBJC_FORWARDING_STACK_OFFSET 0
72 #ifndef OBJC_FORWARDING_MIN_OFFSET
73 #define OBJC_FORWARDING_MIN_OFFSET 0
76 /* Define the special tree codes that we use. */
78 /* Table indexed by tree code giving a string containing a character
79 classifying the tree code. Possibilities are
80 t, d, s, c, r, <, 1 and 2. See objc-tree.def for details. */
82 #define DEFTREECODE(SYM, NAME, TYPE, LENGTH) TYPE,
84 char *objc_tree_code_type[] = {
86 #include "objc-tree.def"
90 /* Table indexed by tree code giving number of expression
91 operands beyond the fixed part of the node structure.
92 Not used for types or decls. */
94 #define DEFTREECODE(SYM, NAME, TYPE, LENGTH) LENGTH,
96 int objc_tree_code_length[] = {
98 #include "objc-tree.def"
102 /* Names of tree components.
103 Used for printing out the tree and error messages. */
104 #define DEFTREECODE(SYM, NAME, TYPE, LEN) NAME,
106 char *objc_tree_code_name[] = {
108 #include "objc-tree.def"
112 /* Set up for use of obstacks. */
116 #define obstack_chunk_alloc xmalloc
117 #define obstack_chunk_free free
119 /* This obstack is used to accumulate the encoding of a data type. */
120 static struct obstack util_obstack;
121 /* This points to the beginning of obstack contents,
122 so we can free the whole contents. */
125 /* for encode_method_def */
129 #define OBJC_VERSION 5
130 #define PROTOCOL_VERSION 2
132 #define NULLT (tree) 0
134 #define OBJC_ENCODE_INLINE_DEFS 0
135 #define OBJC_ENCODE_DONT_INLINE_DEFS 1
137 /*** Private Interface (procedures) ***/
139 /* used by compile_file */
141 static void init_objc PROTO((void));
142 static void finish_objc PROTO((void));
144 /* code generation */
146 static void synth_module_prologue PROTO((void));
147 static char *build_module_descriptor PROTO((void));
148 static tree init_module_descriptor PROTO((void));
149 static tree build_objc_method_call PROTO((int, tree, tree, tree, tree, tree));
150 static void generate_strings PROTO((void));
151 static void build_selector_translation_table PROTO((void));
152 static tree build_ivar_chain PROTO((tree, int));
154 static tree build_ivar_template PROTO((void));
155 static tree build_method_template PROTO((void));
156 static tree build_private_template PROTO((tree));
157 static void build_class_template PROTO((void));
158 static void build_category_template PROTO((void));
159 static tree build_super_template PROTO((void));
160 static tree build_category_initializer PROTO((tree, tree, tree, tree, tree));
161 static tree build_protocol_initializer PROTO((tree, tree, tree, tree));
163 static void synth_forward_declarations PROTO((void));
164 static void generate_ivar_lists PROTO((void));
165 static void generate_dispatch_tables PROTO((void));
166 static void generate_shared_structures PROTO((void));
167 static tree generate_protocol_list PROTO((tree));
168 static void generate_forward_declaration_to_string_table PROTO((void));
169 static void build_protocol_reference PROTO((tree));
171 static tree init_selector PROTO((int));
172 static tree build_keyword_selector PROTO((tree));
173 static tree synth_id_with_class_suffix PROTO((char *, tree));
175 /* misc. bookkeeping */
177 typedef struct hashed_entry *hash;
178 typedef struct hashed_attribute *attr;
180 struct hashed_attribute
192 static void hash_init PROTO((void));
193 static void hash_enter PROTO((hash *, tree));
194 static hash hash_lookup PROTO((hash *, tree));
195 static void hash_add_attr PROTO((hash, tree));
196 static tree lookup_method PROTO((tree, tree));
197 static tree lookup_instance_method_static PROTO((tree, tree));
198 static tree lookup_class_method_static PROTO((tree, tree));
199 static tree add_class PROTO((tree));
200 static void add_category PROTO((tree, tree));
204 class_names, /* class, category, protocol, module names */
205 meth_var_names, /* method and variable names */
206 meth_var_types, /* method and variable type descriptors */
209 static tree add_objc_string PROTO((tree, enum string_section));
210 static tree build_objc_string_decl PROTO((tree, enum string_section));
211 static tree build_selector_reference_decl PROTO((tree));
213 /* protocol additions */
215 static tree add_protocol PROTO((tree));
216 static tree lookup_protocol PROTO((tree));
217 static tree lookup_and_install_protocols PROTO((tree));
221 static void encode_type_qualifiers PROTO((tree));
222 static void encode_pointer PROTO((tree, int, int));
223 static void encode_array PROTO((tree, int, int));
224 static void encode_aggregate PROTO((tree, int, int));
225 static void encode_bitfield PROTO((int, int));
226 static void encode_type PROTO((tree, int, int));
227 static void encode_field_decl PROTO((tree, int, int));
229 static void really_start_method PROTO((tree, tree));
230 static int comp_method_with_proto PROTO((tree, tree));
231 static int comp_proto_with_proto PROTO((tree, tree));
232 static tree get_arg_type_list PROTO((tree, int, int));
233 static tree expr_last PROTO((tree));
235 /* utilities for debugging and error diagnostics: */
237 static void warn_with_method PROTO((char *, int, tree));
238 static void error_with_ivar PROTO((char *, tree, tree));
239 static char *gen_method_decl PROTO((tree, char *));
240 static char *gen_declaration PROTO((tree, char *));
241 static char *gen_declarator PROTO((tree, char *, char *));
242 static int is_complex_decl PROTO((tree));
243 static void adorn_decl PROTO((tree, char *));
244 static void dump_interface PROTO((FILE *, tree));
246 /* everything else. */
248 static void objc_fatal PROTO((void));
249 static tree define_decl PROTO((tree, tree));
250 static tree lookup_method_in_protocol_list PROTO((tree, tree, int));
251 static tree lookup_protocol_in_reflist PROTO((tree, tree));
252 static tree create_builtin_decl PROTO((enum tree_code, tree, char *));
253 static tree my_build_string PROTO((int, char *));
254 static void build_objc_symtab_template PROTO((void));
255 static tree init_def_list PROTO((void));
256 static tree init_objc_symtab PROTO((void));
257 static void forward_declare_categories PROTO((void));
258 static void generate_objc_symtab_decl PROTO((void));
259 static tree build_selector PROTO((tree));
260 static tree build_msg_pool_reference PROTO((int));
261 static tree build_selector_reference PROTO((tree));
262 static tree build_class_reference_decl PROTO((tree));
263 static void add_class_reference PROTO((tree));
264 static tree objc_copy_list PROTO((tree, tree *));
265 static tree build_protocol_template PROTO((void));
266 static tree build_descriptor_table_initializer PROTO((tree, int *));
267 static tree build_method_prototype_list_template PROTO((tree, int));
268 static tree build_method_prototype_template PROTO((void));
269 static int forwarding_offset PROTO((tree));
270 static tree encode_method_prototype PROTO((tree, tree));
271 static tree generate_descriptor_table PROTO((tree, char *, int, tree, tree));
272 static void generate_method_descriptors PROTO((tree));
273 static tree build_tmp_function_decl PROTO((void));
274 static void hack_method_prototype PROTO((tree, tree));
275 static void generate_protocol_references PROTO((tree));
276 static void generate_protocols PROTO((void));
277 static void check_ivars PROTO((tree, tree));
278 static tree build_ivar_list_template PROTO((tree, int));
279 static tree build_method_list_template PROTO((tree, int));
280 static tree build_ivar_list_initializer PROTO((tree, int *));
281 static tree generate_ivars_list PROTO((tree, char *, int, tree));
282 static tree build_dispatch_table_initializer PROTO((tree, int *));
283 static tree generate_dispatch_table PROTO((tree, char *, int, tree));
284 static tree build_shared_structure_initializer PROTO((tree, tree, tree, tree, int, tree, tree, tree));
285 static void generate_category PROTO((tree));
286 static int is_objc_type_qualifier PROTO((tree));
287 static tree adjust_type_for_id_default PROTO((tree));
288 static tree check_duplicates PROTO((hash));
289 static tree receiver_is_class_object PROTO((tree));
290 static int check_methods PROTO((tree, tree, int));
291 static int conforms_to_protocol PROTO((tree, tree));
292 static void check_protocols PROTO((tree, char *, char *));
293 static tree encode_method_def PROTO((tree));
294 static void gen_declspecs PROTO((tree, char *, int));
295 static void generate_classref_translation_entry PROTO((tree));
296 static void handle_class_ref PROTO((tree));
298 /*** Private Interface (data) ***/
300 /* reserved tag definitions: */
303 #define TAG_OBJECT "objc_object"
304 #define TAG_CLASS "objc_class"
305 #define TAG_SUPER "objc_super"
306 #define TAG_SELECTOR "objc_selector"
308 #define UTAG_CLASS "_objc_class"
309 #define UTAG_IVAR "_objc_ivar"
310 #define UTAG_IVAR_LIST "_objc_ivar_list"
311 #define UTAG_METHOD "_objc_method"
312 #define UTAG_METHOD_LIST "_objc_method_list"
313 #define UTAG_CATEGORY "_objc_category"
314 #define UTAG_MODULE "_objc_module"
315 #define UTAG_SYMTAB "_objc_symtab"
316 #define UTAG_SUPER "_objc_super"
318 #define UTAG_PROTOCOL "_objc_protocol"
319 #define UTAG_PROTOCOL_LIST "_objc_protocol_list"
320 #define UTAG_METHOD_PROTOTYPE "_objc_method_prototype"
321 #define UTAG_METHOD_PROTOTYPE_LIST "_objc__method_prototype_list"
323 #define STRING_OBJECT_CLASS_NAME "NXConstantString"
324 #define PROTOCOL_OBJECT_CLASS_NAME "Protocol"
326 static char* TAG_GETCLASS;
327 static char* TAG_GETMETACLASS;
328 static char* TAG_MSGSEND;
329 static char* TAG_MSGSENDSUPER;
330 static char* TAG_EXECCLASS;
332 /* Set by `continue_class' and checked by `is_public'. */
334 #define TREE_STATIC_TEMPLATE(record_type) (TREE_PUBLIC (record_type))
335 #define TYPED_OBJECT(type) \
336 (TREE_CODE (type) == RECORD_TYPE && TREE_STATIC_TEMPLATE (type))
337 /* Some commonly used instances of "identifier_node". */
339 static tree self_id, ucmd_id;
341 static tree self_decl, umsg_decl, umsg_super_decl;
342 static tree objc_get_class_decl, objc_get_meta_class_decl;
344 static tree super_type, selector_type, id_type, objc_class_type;
345 static tree instance_type, protocol_type;
347 static tree class_chain = NULLT;
348 static tree alias_chain = NULLT;
349 static tree interface_chain = NULLT;
350 static tree protocol_chain = NULLT;
352 /* chains to manage selectors that are referenced and defined in the module */
354 static tree cls_ref_chain = NULLT; /* classes referenced */
355 static tree sel_ref_chain = NULLT; /* selectors referenced */
357 /* chains to manage uniquing of strings */
359 static tree class_names_chain = NULLT;
360 static tree meth_var_names_chain = NULLT;
361 static tree meth_var_types_chain = NULLT;
363 /* hash tables to manage the global pool of method prototypes */
365 static hash *nst_method_hash_list = 0;
366 static hash *cls_method_hash_list = 0;
368 /* backend data declarations */
370 static tree UOBJC_SYMBOLS_decl;
371 static tree UOBJC_INSTANCE_VARIABLES_decl, UOBJC_CLASS_VARIABLES_decl;
372 static tree UOBJC_INSTANCE_METHODS_decl, UOBJC_CLASS_METHODS_decl;
373 static tree UOBJC_CLASS_decl, UOBJC_METACLASS_decl;
374 static tree UOBJC_SELECTOR_TABLE_decl;
375 static tree UOBJC_MODULES_decl;
376 static tree UOBJC_STRINGS_decl;
378 /* The following are used when compiling a class implementation.
379 implementation_template will normally be an interface, however if
380 none exists this will be equal to implementation_context...it is
381 set in start_class. */
383 static tree implementation_context = NULLT,
384 implementation_template = NULLT;
388 struct imp_entry *next;
391 tree class_decl; /* _OBJC_CLASS_<my_name>; */
392 tree meta_decl; /* _OBJC_METACLASS_<my_name>; */
395 static void handle_impent PROTO((struct imp_entry *));
397 static struct imp_entry *imp_list = 0;
398 static int imp_count = 0; /* `@implementation' */
399 static int cat_count = 0; /* `@category' */
401 static tree objc_class_template, objc_category_template, uprivate_record;
402 static tree objc_protocol_template;
403 static tree ucls_super_ref, uucls_super_ref;
405 static tree objc_method_template, objc_ivar_template;
406 static tree objc_symtab_template, objc_module_template;
407 static tree objc_super_template, objc_object_reference;
409 static tree objc_object_id, objc_class_id, objc_id_id;
410 static tree constant_string_id;
411 static tree constant_string_type;
412 static tree UOBJC_SUPER_decl;
414 static tree method_context = NULLT;
415 static int method_slot = 0; /* used by start_method_def */
419 static char *errbuf; /* a buffer for error diagnostics */
421 /* data imported from tree.c */
423 extern struct obstack permanent_obstack, *current_obstack, *rtl_obstack;
425 /* data imported from toplev.c */
427 extern char *dump_base_name;
429 /* Generate code for GNU or NeXT runtime environment. */
431 #ifdef NEXT_OBJC_RUNTIME
432 int flag_next_runtime = 1;
434 int flag_next_runtime = 0;
437 /* Open and close the file for outputting class declarations, if requested. */
439 int flag_gen_declaration = 0;
441 FILE *gen_declaration_file;
443 /* Warn if multiple methods are seen for the same selector, but with
444 different argument types. */
446 int warn_selector = 0;
448 /* Warn if methods required by a protocol are not implemented in the
449 class adopting it. When turned off, methods inherited to that
450 class are also considered implemented */
452 int flag_warn_protocol = 1;
454 /* tells "encode_pointer/encode_aggregate" whether we are generating
455 type descriptors for instance variables (as opposed to methods).
456 Type descriptors for instance variables contain more information
457 than methods (for static typing and embedded structures). This
458 was added to support features being planned for dbkit2. */
460 static int generating_instance_variables = 0;
465 /* the beginning of the file is a new line; check for # */
466 /* With luck, we discover the real source file's name from that
467 and put it in input_filename. */
468 ungetc (check_newline (), finput);
470 /* If gen_declaration desired, open the output file. */
471 if (flag_gen_declaration)
473 int dump_base_name_length = strlen (dump_base_name);
474 register char *dumpname = (char *) xmalloc (dump_base_name_length + 7);
475 strcpy (dumpname, dump_base_name);
476 strcat (dumpname, ".decl");
477 gen_declaration_file = fopen (dumpname, "w");
478 if (gen_declaration_file == 0)
479 pfatal_with_name (dumpname);
482 if (flag_next_runtime)
484 TAG_GETCLASS = "objc_getClass";
485 TAG_GETMETACLASS = "objc_getMetaClass";
486 TAG_MSGSEND = "objc_msgSend";
487 TAG_MSGSENDSUPER = "objc_msgSendSuper";
488 TAG_EXECCLASS = "__objc_execClass";
492 TAG_GETCLASS = "objc_get_class";
493 TAG_GETMETACLASS = "objc_get_meta_class";
494 TAG_MSGSEND = "objc_msg_lookup";
495 TAG_MSGSENDSUPER = "objc_msg_lookup_super";
496 TAG_EXECCLASS = "__objc_exec_class";
499 if (doing_objc_thang)
506 fatal ("Objective-C text in C source file");
512 if (doing_objc_thang)
513 finish_objc (); /* Objective-C finalization */
515 if (gen_declaration_file)
516 fclose (gen_declaration_file);
531 lang_decode_option (p)
534 if (!strcmp (p, "-lang-objc"))
535 doing_objc_thang = 1;
536 else if (!strcmp (p, "-gen-decls"))
537 flag_gen_declaration = 1;
538 else if (!strcmp (p, "-Wselector"))
540 else if (!strcmp (p, "-Wno-selector"))
542 else if (!strcmp (p, "-Wprotocol"))
543 flag_warn_protocol = 1;
544 else if (!strcmp (p, "-Wno-protocol"))
545 flag_warn_protocol = 0;
546 else if (!strcmp (p, "-fgnu-runtime"))
547 flag_next_runtime = 0;
548 else if (!strcmp (p, "-fno-next-runtime"))
549 flag_next_runtime = 0;
550 else if (!strcmp (p, "-fno-gnu-runtime"))
551 flag_next_runtime = 1;
552 else if (!strcmp (p, "-fnext-runtime"))
553 flag_next_runtime = 1;
555 return c_decode_option (p);
561 define_decl (declarator, declspecs)
565 tree decl = start_decl (declarator, declspecs, 0);
566 finish_decl (decl, NULLT, NULLT);
570 /* Rules for statically typed objects. Called from comptypes,
571 convert_for_assignment, and comp_target_types.
573 An assignment of the form `a' = `b' is permitted if:
575 - `a' is of type "id".
576 - `a' and `b' are the same class type.
577 - `a' and `b' are of class types A and B such that B is a descendant
581 maybe_objc_comptypes (lhs, rhs, reflexive)
585 if (doing_objc_thang)
586 return objc_comptypes (lhs, rhs, reflexive);
591 lookup_method_in_protocol_list (rproto_list, sel_name, class_meth)
599 for (rproto = rproto_list; rproto; rproto = TREE_CHAIN (rproto))
601 p = TREE_VALUE (rproto);
603 if (TREE_CODE (p) == PROTOCOL_INTERFACE_TYPE)
605 if ((fnd = lookup_method (class_meth
606 ? PROTOCOL_CLS_METHODS (p)
607 : PROTOCOL_NST_METHODS (p), sel_name)))
609 else if (PROTOCOL_LIST (p))
610 fnd = lookup_method_in_protocol_list (PROTOCOL_LIST (p), sel_name, class_meth);
613 ; /* an identifier...if we could not find a protocol. */
622 lookup_protocol_in_reflist (rproto_list, lproto)
628 /* make sure the protocol is support by the object on the rhs */
629 if (TREE_CODE (lproto) == PROTOCOL_INTERFACE_TYPE)
632 for (rproto = rproto_list; rproto; rproto = TREE_CHAIN (rproto))
634 p = TREE_VALUE (rproto);
636 if (TREE_CODE (p) == PROTOCOL_INTERFACE_TYPE)
641 else if (PROTOCOL_LIST (p))
642 fnd = lookup_protocol_in_reflist (PROTOCOL_LIST (p), lproto);
650 ; /* an identifier...if we could not find a protocol. */
656 objc_comptypes (lhs, rhs, reflexive)
661 /* new clause for protocols */
663 if (TREE_CODE (lhs) == POINTER_TYPE
664 && TREE_CODE (TREE_TYPE (lhs)) == RECORD_TYPE
665 && TREE_CODE (rhs) == POINTER_TYPE
666 && TREE_CODE (TREE_TYPE (rhs)) == RECORD_TYPE)
668 int lhs_is_proto = (TYPE_MAIN_VARIANT (lhs) == TYPE_MAIN_VARIANT (id_type)
669 && TYPE_PROTOCOL_LIST (lhs));
670 int rhs_is_proto = (TYPE_MAIN_VARIANT (rhs) == TYPE_MAIN_VARIANT (id_type)
671 && TYPE_PROTOCOL_LIST (rhs));
675 tree lproto, lproto_list = TYPE_PROTOCOL_LIST (lhs);
676 tree rproto, rproto_list;
681 rproto_list = TYPE_PROTOCOL_LIST (rhs);
683 /* Make sure the protocol is supported by the object
685 for (lproto = lproto_list; lproto; lproto = TREE_CHAIN (lproto))
687 p = TREE_VALUE (lproto);
688 rproto = lookup_protocol_in_reflist (rproto_list, p);
691 warning ("object does not conform to the `%s' protocol",
692 IDENTIFIER_POINTER (PROTOCOL_NAME (p)));
695 else if (TYPED_OBJECT (TREE_TYPE (rhs)))
697 tree rname = TYPE_NAME (TREE_TYPE (rhs));
700 /* Make sure the protocol is supported by the object
702 for (lproto = lproto_list; lproto; lproto = TREE_CHAIN (lproto))
704 p = TREE_VALUE (lproto);
706 rinter = lookup_interface (rname);
708 while (rinter && !rproto)
712 rproto_list = CLASS_PROTOCOL_LIST (rinter);
713 rproto = lookup_protocol_in_reflist (rproto_list, p);
716 /* Check for protocols adopted by categories. */
717 cat = CLASS_CATEGORY_LIST (rinter);
718 while (cat && !rproto)
720 rproto_list = CLASS_PROTOCOL_LIST (cat);
721 rproto = lookup_protocol_in_reflist (rproto_list, p);
723 cat = CLASS_CATEGORY_LIST (cat);
726 rinter = lookup_interface (CLASS_SUPER_NAME (rinter));
729 warning ("class `%s' does not implement the `%s' protocol",
730 IDENTIFIER_POINTER (TYPE_NAME (TREE_TYPE (rhs))),
731 IDENTIFIER_POINTER (PROTOCOL_NAME (p)));
735 return 1; /* may change...based on whether there was any mismatch */
737 else if (rhs_is_proto)
739 /* lhs is not a protocol...warn if it is statically typed */
741 if (TYPED_OBJECT (TREE_TYPE (lhs)))
744 return 1; /* one of the types is a protocol */
747 return 2; /* defer to comptypes */
749 else if (TREE_CODE (lhs) == RECORD_TYPE && TREE_CODE (rhs) == RECORD_TYPE)
750 ; /* fall thru...this is the case we have been handling all along */
752 return 2; /* defer to comptypes */
754 /* End of new protocol support. */
756 /* `id' = `<class> *', `<class> *' = `id' */
758 if ((TYPE_NAME (lhs) == objc_object_id && TYPED_OBJECT (rhs))
759 || (TYPE_NAME (rhs) == objc_object_id && TYPED_OBJECT (lhs)))
762 /* `id' = `Class', `Class' = `id' */
764 else if ((TYPE_NAME (lhs) == objc_object_id
765 && TYPE_NAME (rhs) == objc_class_id)
766 || (TYPE_NAME (lhs) == objc_class_id
767 && TYPE_NAME (rhs) == objc_object_id))
770 /* `<class> *' = `<class> *' */
772 else if (TYPED_OBJECT (lhs) && TYPED_OBJECT (rhs))
774 tree lname = TYPE_NAME (lhs);
775 tree rname = TYPE_NAME (rhs);
781 /* If the left hand side is a super class of the right hand side,
783 for (inter = lookup_interface (rname); inter;
784 inter = lookup_interface (CLASS_SUPER_NAME (inter)))
785 if (lname == CLASS_SUPER_NAME (inter))
788 /* Allow the reverse when reflexive. */
790 for (inter = lookup_interface (lname); inter;
791 inter = lookup_interface (CLASS_SUPER_NAME (inter)))
792 if (rname == CLASS_SUPER_NAME (inter))
801 /* Called from c-decl.c before all calls to rest_of_decl_compilation. */
804 objc_check_decl (decl)
807 tree type = TREE_TYPE (decl);
809 if (TREE_CODE (type) == RECORD_TYPE
810 && TREE_STATIC_TEMPLATE (type)
811 && type != constant_string_type)
813 error_with_decl (decl, "`%s' cannot be statically allocated");
814 fatal ("statically allocated objects not supported");
819 maybe_objc_check_decl (decl)
822 if (doing_objc_thang)
823 objc_check_decl (decl);
826 /* Implement static typing. At this point, we know we have an interface. */
829 get_static_reference (interface, protocols)
833 tree type = xref_tag (RECORD_TYPE, interface);
837 tree t, m = TYPE_MAIN_VARIANT (type);
838 struct obstack *ambient_obstack = current_obstack;
840 current_obstack = &permanent_obstack;
841 t = copy_node (type);
842 TYPE_BINFO (t) = make_tree_vec (2);
844 /* Add this type to the chain of variants of TYPE. */
845 TYPE_NEXT_VARIANT (t) = TYPE_NEXT_VARIANT (m);
846 TYPE_NEXT_VARIANT (m) = t;
848 current_obstack = ambient_obstack;
850 /* Look up protocols and install in lang specific list. */
851 TYPE_PROTOCOL_LIST (t) = lookup_and_install_protocols (protocols);
853 /* This forces a new pointer type to be created later
854 (in build_pointer_type)...so that the new template
855 we just created will actually be used...what a hack! */
856 if (TYPE_POINTER_TO (t))
857 TYPE_POINTER_TO (t) = NULL;
866 get_object_reference (protocols)
869 tree type_decl = lookup_name (objc_id_id);
872 if (type_decl && TREE_CODE (type_decl) == TYPE_DECL)
874 type = TREE_TYPE (type_decl);
875 if (TYPE_MAIN_VARIANT (type) != id_type)
876 warning ("Unexpected type for `id' (%s)",
877 gen_declaration (type, errbuf));
881 fatal ("Undefined type `id', please import <objc/objc.h>");
884 /* This clause creates a new pointer type that is qualified with
885 the protocol specification...this info is used later to do more
886 elaborate type checking. */
889 tree t, m = TYPE_MAIN_VARIANT (type);
890 struct obstack *ambient_obstack = current_obstack;
892 current_obstack = &permanent_obstack;
893 t = copy_node (type);
894 TYPE_BINFO (t) = make_tree_vec (2);
896 /* Add this type to the chain of variants of TYPE. */
897 TYPE_NEXT_VARIANT (t) = TYPE_NEXT_VARIANT (m);
898 TYPE_NEXT_VARIANT (m) = t;
900 current_obstack = ambient_obstack;
902 /* look up protocols...and install in lang specific list */
903 TYPE_PROTOCOL_LIST (t) = lookup_and_install_protocols (protocols);
905 /* This forces a new pointer type to be created later
906 (in build_pointer_type)...so that the new template
907 we just created will actually be used...what a hack! */
908 if (TYPE_POINTER_TO (t))
909 TYPE_POINTER_TO (t) = NULL;
917 lookup_and_install_protocols (protocols)
922 tree return_value = protocols;
924 for (proto = protocols; proto; proto = TREE_CHAIN (proto))
926 tree ident = TREE_VALUE (proto);
927 tree p = lookup_protocol (ident);
931 error ("Cannot find protocol declaration for `%s'",
932 IDENTIFIER_POINTER (ident));
934 TREE_CHAIN (prev) = TREE_CHAIN (proto);
936 return_value = TREE_CHAIN (proto);
940 /* replace identifier with actual protocol node */
941 TREE_VALUE (proto) = p;
948 /* Create and push a decl for a built-in external variable or field NAME.
950 TYPE is its data type. */
953 create_builtin_decl (code, type, name)
958 tree decl = build_decl (code, get_identifier (name), type);
959 if (code == VAR_DECL)
961 TREE_STATIC (decl) = 1;
962 make_decl_rtl (decl, 0, 1);
968 /* purpose: "play" parser, creating/installing representations
969 of the declarations that are required by Objective-C.
973 type_spec--------->sc_spec
974 (tree_list) (tree_list)
977 identifier_node identifier_node */
980 synth_module_prologue ()
985 /* defined in `objc.h' */
986 objc_object_id = get_identifier (TAG_OBJECT);
988 objc_object_reference = xref_tag (RECORD_TYPE, objc_object_id);
990 id_type = build_pointer_type (objc_object_reference);
992 objc_id_id = get_identifier (TYPE_ID);
993 objc_class_id = get_identifier (TAG_CLASS);
995 objc_class_type = build_pointer_type (xref_tag (RECORD_TYPE, objc_class_id));
996 protocol_type = build_pointer_type (xref_tag (RECORD_TYPE,
997 get_identifier (PROTOCOL_OBJECT_CLASS_NAME)));
999 /* Declare type of selector-objects that represent an operation name. */
1001 #ifdef OBJC_INT_SELECTORS
1002 /* `unsigned int' */
1003 selector_type = unsigned_type_node;
1005 /* `struct objc_selector *' */
1007 = build_pointer_type (xref_tag (RECORD_TYPE,
1008 get_identifier (TAG_SELECTOR)));
1009 #endif /* not OBJC_INT_SELECTORS */
1011 /* Forward declare type, or else the prototype for msgSendSuper will
1014 super_p = build_pointer_type (xref_tag (RECORD_TYPE,
1015 get_identifier (TAG_SUPER)));
1018 /* id objc_msgSend (id, SEL, ...); */
1021 = build_function_type (id_type,
1022 tree_cons (NULL_TREE, id_type,
1023 tree_cons (NULLT, selector_type, NULLT)));
1025 if (! flag_next_runtime)
1027 umsg_decl = build_decl (FUNCTION_DECL,
1028 get_identifier (TAG_MSGSEND), temp_type);
1029 DECL_EXTERNAL (umsg_decl) = 1;
1030 TREE_PUBLIC (umsg_decl) = 0;
1031 DECL_INLINE (umsg_decl) = 1;
1033 if (flag_traditional && TAG_MSGSEND[0] != '_')
1034 DECL_BUILT_IN_NONANSI (umsg_decl) = 1;
1036 make_decl_rtl (umsg_decl, NULL_PTR, 1);
1037 pushdecl (umsg_decl);
1040 umsg_decl = builtin_function (TAG_MSGSEND, temp_type, NOT_BUILT_IN, 0);
1042 /* id objc_msgSendSuper (struct objc_super *, SEL, ...); */
1045 = build_function_type (id_type,
1046 tree_cons (NULL_TREE, super_p,
1047 tree_cons (NULLT, selector_type, NULLT)));
1049 umsg_super_decl = builtin_function (TAG_MSGSENDSUPER,
1050 temp_type, NOT_BUILT_IN, 0);
1052 /* id objc_getClass (const char *); */
1054 temp_type = build_function_type (id_type,
1056 const_string_type_node,
1057 tree_cons (NULLT, void_type_node, NULLT)));
1060 = builtin_function (TAG_GETCLASS, temp_type, NOT_BUILT_IN, 0);
1062 /* id objc_getMetaClass (const char *); */
1064 objc_get_meta_class_decl
1065 = builtin_function (TAG_GETMETACLASS, temp_type, NOT_BUILT_IN, 0);
1067 /* static SEL _OBJC_SELECTOR_TABLE[]; */
1069 if (! flag_next_runtime)
1070 UOBJC_SELECTOR_TABLE_decl
1071 = create_builtin_decl (VAR_DECL, build_array_type (selector_type, NULLT),
1072 "_OBJC_SELECTOR_TABLE");
1074 generate_forward_declaration_to_string_table ();
1076 /* Forward declare constant_string_id and constant_string_type. */
1077 constant_string_id = get_identifier (STRING_OBJECT_CLASS_NAME);
1078 constant_string_type = xref_tag (RECORD_TYPE, constant_string_id);
1081 /* Custom build_string which sets TREE_TYPE! */
1084 my_build_string (len, str)
1089 tree a_string = build_string (len, str);
1090 /* Some code from combine_strings, which is local to c-parse.y. */
1091 if (TREE_TYPE (a_string) == int_array_type_node)
1094 TREE_TYPE (a_string) =
1095 build_array_type (wide_flag ? integer_type_node : char_type_node,
1096 build_index_type (build_int_2 (len - 1, 0)));
1098 TREE_CONSTANT (a_string) = 1; /* puts string in the ".text" segment */
1099 TREE_STATIC (a_string) = 1;
1104 /* Return a newly constructed OBJC_STRING_CST node whose value is
1105 the LEN characters at STR.
1106 The TREE_TYPE is not initialized. */
1109 build_objc_string (len, str)
1113 tree s = build_string (len, str);
1115 TREE_CODE (s) = OBJC_STRING_CST;
1119 /* Given a chain of OBJC_STRING_CST's, build a static instance of
1120 NXConstantString which points at the concatenation of those strings.
1121 We place the string object in the __string_objects section of the
1122 __OBJC segment. The Objective-C runtime will initialize the isa
1123 pointers of the string objects to point at the NXConstantString
1127 build_objc_string_object (strings)
1130 tree string, initlist, constructor;
1133 if (!doing_objc_thang)
1136 if (lookup_interface (constant_string_id) == NULLT)
1138 error ("Cannot find interface declaration for `%s'",
1139 IDENTIFIER_POINTER (constant_string_id));
1140 return error_mark_node;
1143 add_class_reference (constant_string_id);
1145 /* combine_strings will work for OBJC_STRING_CST's too. */
1146 string = combine_strings (strings);
1147 TREE_CODE (string) = STRING_CST;
1148 length = TREE_STRING_LENGTH (string) - 1;
1150 /* & ((NXConstantString) {0, string, length}) */
1152 initlist = build_tree_list (NULLT, build_int_2 (0, 0));
1153 initlist = tree_cons (NULLT, build_unary_op (ADDR_EXPR, string, 1),
1155 initlist = tree_cons (NULLT, build_int_2 (length, 0), initlist);
1156 constructor = build (CONSTRUCTOR, constant_string_type, NULLT,
1157 nreverse (initlist));
1158 TREE_CONSTANT (constructor) = 1;
1159 TREE_STATIC (constructor) = 1;
1160 TREE_READONLY (constructor) = 1;
1162 return build_unary_op (ADDR_EXPR, constructor, 1);
1165 /* Take care of defining and initializing _OBJC_SYMBOLS. */
1167 /* Predefine the following data type:
1175 void *defs[cls_def_cnt + cat_def_cnt];
1179 build_objc_symtab_template ()
1181 tree field_decl, field_decl_chain, index;
1183 objc_symtab_template = start_struct (RECORD_TYPE, get_identifier (UTAG_SYMTAB));
1185 /* long sel_ref_cnt; */
1187 field_decl = create_builtin_decl (FIELD_DECL,
1188 long_integer_type_node,
1190 field_decl_chain = field_decl;
1194 field_decl = create_builtin_decl (FIELD_DECL,
1195 build_pointer_type (selector_type),
1197 chainon (field_decl_chain, field_decl);
1199 /* short cls_def_cnt; */
1201 field_decl = create_builtin_decl (FIELD_DECL,
1202 short_integer_type_node,
1204 chainon (field_decl_chain, field_decl);
1206 /* short cat_def_cnt; */
1208 field_decl = create_builtin_decl (FIELD_DECL,
1209 short_integer_type_node,
1211 chainon (field_decl_chain, field_decl);
1213 /* void *defs[cls_def_cnt + cat_def_cnt]; */
1215 index = build_index_type (build_int_2 (imp_count + cat_count - 1,
1216 imp_count == 0 && cat_count == 0
1218 field_decl = create_builtin_decl (FIELD_DECL,
1219 build_array_type (ptr_type_node, index),
1221 chainon (field_decl_chain, field_decl);
1223 finish_struct (objc_symtab_template, field_decl_chain);
1226 /* Create the initial value for the `defs' field of _objc_symtab.
1227 This is a CONSTRUCTOR. */
1232 tree expr, initlist = NULLT;
1233 struct imp_entry *impent;
1236 for (impent = imp_list; impent; impent = impent->next)
1238 if (TREE_CODE (impent->imp_context) == CLASS_IMPLEMENTATION_TYPE)
1240 expr = build_unary_op (ADDR_EXPR, impent->class_decl, 0);
1241 initlist = tree_cons (NULLT, expr, initlist);
1246 for (impent = imp_list; impent; impent = impent->next)
1248 if (TREE_CODE (impent->imp_context) == CATEGORY_IMPLEMENTATION_TYPE)
1250 expr = build_unary_op (ADDR_EXPR, impent->class_decl, 0);
1251 initlist = tree_cons (NULLT, expr, initlist);
1254 return build_nt (CONSTRUCTOR, NULLT, nreverse (initlist));
1257 /* Construct the initial value for all of _objc_symtab. */
1264 /* sel_ref_cnt = { ..., 5, ... } */
1266 initlist = build_tree_list (NULLT, build_int_2 (0, 0));
1268 /* refs = { ..., _OBJC_SELECTOR_TABLE, ... } */
1270 if (flag_next_runtime || ! sel_ref_chain)
1271 initlist = tree_cons (NULLT, build_int_2 (0, 0), initlist);
1273 initlist = tree_cons (NULLT, UOBJC_SELECTOR_TABLE_decl, initlist);
1275 /* cls_def_cnt = { ..., 5, ... } */
1277 initlist = tree_cons (NULLT, build_int_2 (imp_count, 0), initlist);
1279 /* cat_def_cnt = { ..., 5, ... } */
1281 initlist = tree_cons (NULLT, build_int_2 (cat_count, 0), initlist);
1283 /* cls_def = { ..., { &Foo, &Bar, ...}, ... } */
1285 if (imp_count || cat_count)
1286 initlist = tree_cons (NULLT, init_def_list (), initlist);
1288 return build_nt (CONSTRUCTOR, NULLT, nreverse (initlist));
1291 /* Push forward-declarations of all the categories
1292 so that init_def_list can use them in a CONSTRUCTOR. */
1295 forward_declare_categories ()
1297 struct imp_entry *impent;
1298 tree sav = implementation_context;
1299 for (impent = imp_list; impent; impent = impent->next)
1301 if (TREE_CODE (impent->imp_context) == CATEGORY_IMPLEMENTATION_TYPE)
1303 /* Set an invisible arg to synth_id_with_class_suffix. */
1304 implementation_context = impent->imp_context;
1306 = create_builtin_decl (VAR_DECL, objc_category_template,
1307 IDENTIFIER_POINTER (synth_id_with_class_suffix ("_OBJC_CATEGORY", implementation_context)));
1310 implementation_context = sav;
1313 /* Create the declaration of _OBJC_SYMBOLS, with type `strict _objc_symtab'
1314 and initialized appropriately. */
1317 generate_objc_symtab_decl ()
1321 if (!objc_category_template)
1322 build_category_template ();
1324 /* forward declare categories */
1326 forward_declare_categories ();
1328 if (!objc_symtab_template)
1329 build_objc_symtab_template ();
1331 sc_spec = build_tree_list (NULLT, ridpointers[(int) RID_STATIC]);
1333 UOBJC_SYMBOLS_decl = start_decl (get_identifier ("_OBJC_SYMBOLS"),
1334 tree_cons (NULLT, objc_symtab_template, sc_spec), 1);
1336 end_temporary_allocation (); /* start_decl trying to be smart about inits */
1337 TREE_USED (UOBJC_SYMBOLS_decl) = 1;
1338 DECL_IGNORED_P (UOBJC_SYMBOLS_decl) = 1;
1339 finish_decl (UOBJC_SYMBOLS_decl, init_objc_symtab (), NULLT);
1343 init_module_descriptor ()
1345 tree initlist, expr;
1347 /* version = { 1, ... } */
1349 expr = build_int_2 (OBJC_VERSION, 0);
1350 initlist = build_tree_list (NULLT, expr);
1352 /* size = { ..., sizeof (struct objc_module), ... } */
1354 expr = size_in_bytes (objc_module_template);
1355 initlist = tree_cons (NULLT, expr, initlist);
1357 /* name = { ..., "foo.m", ... } */
1359 expr = add_objc_string (get_identifier (input_filename), class_names);
1360 initlist = tree_cons (NULLT, expr, initlist);
1362 /* symtab = { ..., _OBJC_SYMBOLS, ... } */
1364 if (UOBJC_SYMBOLS_decl)
1365 expr = build_unary_op (ADDR_EXPR, UOBJC_SYMBOLS_decl, 0);
1367 expr = build_int_2 (0, 0);
1368 initlist = tree_cons (NULLT, expr, initlist);
1370 return build_nt (CONSTRUCTOR, NULLT, nreverse (initlist));
1373 /* Write out the data structures to describe Objective C classes defined.
1374 If appropriate, compile and output a setup function to initialize them.
1375 Return a string which is the name of a function to call to initialize
1376 the Objective C data structures for this file (and perhaps for other files
1379 struct objc_module { ... } _OBJC_MODULE = { ... };
1384 build_module_descriptor ()
1386 tree decl_specs, field_decl, field_decl_chain;
1388 objc_module_template = start_struct (RECORD_TYPE, get_identifier (UTAG_MODULE));
1392 decl_specs = build_tree_list (NULLT, ridpointers[(int) RID_LONG]);
1393 field_decl = get_identifier ("version");
1394 field_decl = grokfield (input_filename, lineno, field_decl, decl_specs, NULLT);
1395 field_decl_chain = field_decl;
1399 decl_specs = build_tree_list (NULLT, ridpointers[(int) RID_LONG]);
1400 field_decl = get_identifier ("size");
1401 field_decl = grokfield (input_filename, lineno, field_decl, decl_specs, NULLT);
1402 chainon (field_decl_chain, field_decl);
1406 decl_specs = build_tree_list (NULLT, ridpointers[(int) RID_CHAR]);
1407 field_decl = build1 (INDIRECT_REF, NULLT, get_identifier ("name"));
1408 field_decl = grokfield (input_filename, lineno, field_decl, decl_specs, NULLT);
1409 chainon (field_decl_chain, field_decl);
1411 /* struct objc_symtab *symtab; */
1413 decl_specs = get_identifier (UTAG_SYMTAB);
1414 decl_specs = build_tree_list (NULLT, xref_tag (RECORD_TYPE, decl_specs));
1415 field_decl = build1 (INDIRECT_REF, NULLT, get_identifier ("symtab"));
1416 field_decl = grokfield (input_filename, lineno, field_decl, decl_specs, NULLT);
1417 chainon (field_decl_chain, field_decl);
1419 finish_struct (objc_module_template, field_decl_chain);
1421 /* create an instance of "objc_module" */
1423 decl_specs = tree_cons (NULLT, objc_module_template,
1424 build_tree_list (NULLT, ridpointers[(int) RID_STATIC]));
1426 UOBJC_MODULES_decl = start_decl (get_identifier ("_OBJC_MODULES"),
1429 end_temporary_allocation (); /* start_decl trying to be smart about inits */
1430 DECL_IGNORED_P (UOBJC_MODULES_decl) = 1;
1431 finish_decl (UOBJC_MODULES_decl, init_module_descriptor (), NULLT);
1433 /* Mark the decl to avoid "defined but not used" warning. */
1434 DECL_IN_SYSTEM_HEADER (UOBJC_MODULES_decl) = 1;
1436 /* Generate a constructor call for the module descriptor.
1437 This code was generated by reading the grammar rules
1438 of c-parse.y; Therefore, it may not be the most efficient
1439 way of generating the requisite code. */
1441 if (flag_next_runtime)
1445 tree parms, function_decl, decelerator, void_list_node;
1448 char *global_object_name = 0;
1451 /* Use a global object (which is already required to be unique over
1452 the program) rather than the file name (which imposes extra
1453 constraints). -- Raeburn@MIT.EDU, 10 Jan 1990. */
1455 /* Find the name of some global object defined in this file. */
1456 for (t = getdecls (); t; t = TREE_CHAIN (t))
1457 if (TREE_PUBLIC (t) && !DECL_EXTERNAL (t) && DECL_INITIAL (t) != 0)
1459 global_object_name = IDENTIFIER_POINTER (DECL_NAME (t));
1463 /* If none, use the name of the file. */
1464 if (!global_object_name)
1468 = (char *) alloca (strlen (main_input_filename) + 1);
1470 p = main_input_filename;
1471 q = global_object_name;
1473 /* Replace any weird characters in the file name. */
1475 if (! ((*p >= '0' && *p <= '9')
1476 || (*p >= 'A' && *p <= 'Z')
1477 || (*p >= 'a' && *p <= 'z')))
1484 /* Make the constructor name from the name we have found. */
1485 buf = (char *) xmalloc (sizeof (CONSTRUCTOR_NAME_FORMAT)
1486 + strlen (global_object_name));
1487 sprintf (buf, CONSTRUCTOR_NAME_FORMAT, global_object_name);
1489 /* Declare void __objc_execClass (void*); */
1491 void_list_node = build_tree_list (NULL_TREE, void_type_node);
1493 = build_function_type (void_type_node,
1494 tree_cons (NULL_TREE, ptr_type_node,
1496 function_decl = build_decl (FUNCTION_DECL,
1497 get_identifier (TAG_EXECCLASS),
1499 DECL_EXTERNAL (function_decl) = 1;
1500 TREE_PUBLIC (function_decl) = 1;
1501 pushdecl (function_decl);
1502 rest_of_decl_compilation (function_decl, 0, 0, 0);
1505 = build_tree_list (NULLT,
1506 build_unary_op (ADDR_EXPR, UOBJC_MODULES_decl, 0));
1507 decelerator = build_function_call (function_decl, parms);
1509 /* void _GLOBAL_$I$<gnyf> () {objc_execClass (&L_OBJC_MODULES);} */
1511 start_function (void_list_node,
1512 build_parse_node (CALL_EXPR, get_identifier (buf),
1513 /* This has the format of the output
1514 of get_parm_info. */
1515 tree_cons (NULL_TREE, NULL_TREE,
1519 #if 0 /* This should be turned back on later
1520 for the systems where collect is not needed. */
1521 /* Make these functions nonglobal
1522 so each file can use the same name. */
1523 TREE_PUBLIC (current_function_decl) = 0;
1525 TREE_USED (current_function_decl) = 1;
1526 store_parm_decls ();
1528 assemble_external (function_decl);
1529 c_expand_expr_stmt (decelerator);
1531 finish_function (0);
1533 /* Return the name of the constructor function. */
1538 /* extern const char _OBJC_STRINGS[]; */
1541 generate_forward_declaration_to_string_table ()
1543 tree sc_spec, decl_specs, expr_decl;
1545 sc_spec = tree_cons (NULLT, ridpointers[(int) RID_EXTERN], NULLT);
1546 decl_specs = tree_cons (NULLT, ridpointers[(int) RID_CHAR], sc_spec);
1548 expr_decl = build_nt (ARRAY_REF, get_identifier ("_OBJC_STRINGS"), NULLT);
1550 UOBJC_STRINGS_decl = define_decl (expr_decl, decl_specs);
1553 /* Output all strings. */
1558 tree sc_spec, decl_specs, expr_decl;
1559 tree chain, string_expr;
1562 for (chain = class_names_chain; chain; chain = TREE_CHAIN (chain))
1564 string = TREE_VALUE (chain);
1565 decl = TREE_PURPOSE (chain);
1566 sc_spec = tree_cons (NULLT, ridpointers[(int) RID_STATIC], NULLT);
1567 decl_specs = tree_cons (NULLT, ridpointers[(int) RID_CHAR], sc_spec);
1568 expr_decl = build_nt (ARRAY_REF, DECL_NAME (decl), NULLT);
1569 decl = start_decl (expr_decl, decl_specs, 1);
1570 end_temporary_allocation ();
1571 string_expr = my_build_string (IDENTIFIER_LENGTH (string) + 1,
1572 IDENTIFIER_POINTER (string));
1573 finish_decl (decl, string_expr, NULLT);
1576 for (chain = meth_var_names_chain; chain; chain = TREE_CHAIN (chain))
1578 string = TREE_VALUE (chain);
1579 decl = TREE_PURPOSE (chain);
1580 sc_spec = tree_cons (NULLT, ridpointers[(int) RID_STATIC], NULLT);
1581 decl_specs = tree_cons (NULLT, ridpointers[(int) RID_CHAR], sc_spec);
1582 expr_decl = build_nt (ARRAY_REF, DECL_NAME (decl), NULLT);
1583 decl = start_decl (expr_decl, decl_specs, 1);
1584 end_temporary_allocation ();
1585 string_expr = my_build_string (IDENTIFIER_LENGTH (string) + 1,
1586 IDENTIFIER_POINTER (string));
1587 finish_decl (decl, string_expr, NULLT);
1590 for (chain = meth_var_types_chain; chain; chain = TREE_CHAIN (chain))
1592 string = TREE_VALUE (chain);
1593 decl = TREE_PURPOSE (chain);
1594 sc_spec = tree_cons (NULLT, ridpointers[(int) RID_STATIC], NULLT);
1595 decl_specs = tree_cons (NULLT, ridpointers[(int) RID_CHAR], sc_spec);
1596 expr_decl = build_nt (ARRAY_REF, DECL_NAME (decl), NULLT);
1597 decl = start_decl (expr_decl, decl_specs, 1);
1598 end_temporary_allocation ();
1599 string_expr = my_build_string (IDENTIFIER_LENGTH (string) + 1,
1600 IDENTIFIER_POINTER (string));
1601 finish_decl (decl, string_expr, NULLT);
1606 build_selector_reference_decl (name)
1611 struct obstack *save_current_obstack = current_obstack;
1612 struct obstack *save_rtl_obstack = rtl_obstack;
1615 sprintf (buf, "_OBJC_SELECTOR_REFERENCES_%d", idx++);
1618 rtl_obstack = current_obstack = &permanent_obstack;
1619 ident = get_identifier (buf);
1621 decl = build_decl (VAR_DECL, ident, selector_type);
1622 DECL_EXTERNAL (decl) = 1;
1623 TREE_PUBLIC (decl) = 1;
1624 TREE_USED (decl) = 1;
1625 TREE_READONLY (decl) = 1;
1627 make_decl_rtl (decl, 0, 1); /* usually called from `rest_of_decl_compilation' */
1628 pushdecl_top_level (decl); /* our `extended/custom' pushdecl in c-decl.c */
1630 current_obstack = save_current_obstack;
1631 rtl_obstack = save_rtl_obstack;
1636 /* Just a handy wrapper for add_objc_string. */
1639 build_selector (ident)
1642 tree expr = add_objc_string (ident, meth_var_names);
1644 return build_c_cast (selector_type, expr); /* cast! */
1647 /* Synthesize the following expr: (char *)&_OBJC_STRINGS[<offset>]
1648 The cast stops the compiler from issuing the following message:
1649 grok.m: warning: initialization of non-const * pointer from const *
1650 grok.m: warning: initialization between incompatible pointer types. */
1653 build_msg_pool_reference (offset)
1656 tree expr = build_int_2 (offset, 0);
1659 expr = build_array_ref (UOBJC_STRINGS_decl, expr);
1660 expr = build_unary_op (ADDR_EXPR, expr, 0);
1662 cast = build_tree_list (build_tree_list (NULLT, ridpointers[(int) RID_CHAR]),
1663 build1 (INDIRECT_REF, NULLT, NULLT));
1664 TREE_TYPE (expr) = groktypename (cast);
1669 init_selector (offset)
1672 tree expr = build_msg_pool_reference (offset);
1673 TREE_TYPE (expr) = selector_type; /* cast */
1678 build_selector_translation_table ()
1680 tree sc_spec, decl_specs;
1681 tree chain, initlist = NULLT;
1683 tree decl, var_decl, name;
1685 /* The corresponding pop_obstacks is in finish_decl,
1686 called at the end of this function. */
1687 if (! flag_next_runtime)
1688 push_obstacks_nochange ();
1690 for (chain = sel_ref_chain; chain; chain = TREE_CHAIN (chain))
1694 expr = build_selector (TREE_VALUE (chain));
1696 if (flag_next_runtime)
1698 name = DECL_NAME (TREE_PURPOSE (chain));
1700 sc_spec = build_tree_list (NULLT, ridpointers[(int) RID_STATIC]);
1702 /* static SEL _OBJC_SELECTOR_REFERENCES_n = ...; */
1703 decl_specs = tree_cons (NULLT, selector_type, sc_spec);
1707 /* the `decl' that is returned from start_decl is the one that we
1708 forward declared in `build_selector_reference' */
1709 decl = start_decl (var_decl, decl_specs, 1);
1712 /* add one for the '\0' character */
1713 offset += IDENTIFIER_LENGTH (TREE_VALUE (chain)) + 1;
1715 if (flag_next_runtime)
1717 end_temporary_allocation ();
1718 finish_decl (decl, expr, NULLT);
1721 initlist = tree_cons (NULLT, expr, initlist);
1724 if (! flag_next_runtime)
1726 /* Cause the variable and its initial value to be actually output. */
1727 DECL_EXTERNAL (UOBJC_SELECTOR_TABLE_decl) = 0;
1728 TREE_STATIC (UOBJC_SELECTOR_TABLE_decl) = 1;
1729 /* NULL terminate the list and fix the decl for output. */
1730 initlist = tree_cons (NULLT, build_int_2 (0, 0), initlist);
1731 DECL_INITIAL (UOBJC_SELECTOR_TABLE_decl) = (tree) 1;
1732 initlist = build_nt (CONSTRUCTOR, NULLT, nreverse (initlist));
1733 finish_decl (UOBJC_SELECTOR_TABLE_decl, initlist, NULLT);
1737 /* sel_ref_chain is a list whose "value" fields will be instances of
1738 identifier_node that represent the selector. */
1741 build_selector_reference (ident)
1744 tree *chain = &sel_ref_chain;
1750 if (TREE_VALUE (*chain) == ident)
1751 return (flag_next_runtime
1752 ? TREE_PURPOSE (*chain)
1753 : build_array_ref (UOBJC_SELECTOR_TABLE_decl,
1754 build_int_2 (index, 0)));
1757 chain = &TREE_CHAIN (*chain);
1760 decl = build_selector_reference_decl (ident);
1762 *chain = perm_tree_cons (decl, ident, NULLT);
1764 return (flag_next_runtime
1766 : build_array_ref (UOBJC_SELECTOR_TABLE_decl,
1767 build_int_2 (index, 0)));
1771 build_class_reference_decl (name)
1776 struct obstack *save_current_obstack = current_obstack;
1777 struct obstack *save_rtl_obstack = rtl_obstack;
1780 sprintf (buf, "_OBJC_CLASS_REFERENCES_%d", idx++);
1783 rtl_obstack = current_obstack = &permanent_obstack;
1784 ident = get_identifier (buf);
1786 decl = build_decl (VAR_DECL, ident, objc_class_type);
1787 DECL_EXTERNAL (decl) = 1;
1788 TREE_PUBLIC (decl) = 1;
1789 TREE_USED (decl) = 1;
1790 TREE_READONLY (decl) = 1;
1792 make_decl_rtl (decl, 0, 1); /* usually called from `rest_of_decl_compilation' */
1793 pushdecl_top_level (decl); /* our `extended/custom' pushdecl in c-decl.c */
1795 current_obstack = save_current_obstack;
1796 rtl_obstack = save_rtl_obstack;
1801 /* Create a class reference, but don't create a variable to reference
1805 add_class_reference (ident)
1810 if ((chain = cls_ref_chain))
1815 if (ident == TREE_VALUE (chain))
1819 chain = TREE_CHAIN (chain);
1823 /* append to the end of the list */
1824 TREE_CHAIN (tail) = perm_tree_cons (NULLT, ident, NULLT);
1827 cls_ref_chain = perm_tree_cons (NULLT, ident, NULLT);
1830 /* Get a class reference, creating it if necessary. Also create the
1831 reference variable. */
1834 get_class_reference (ident)
1837 if (flag_next_runtime)
1842 for (chain = &cls_ref_chain; *chain; chain = &TREE_CHAIN (*chain))
1843 if (TREE_VALUE (*chain) == ident)
1845 if (! TREE_PURPOSE (*chain))
1846 TREE_PURPOSE (*chain) = build_class_reference_decl (ident);
1847 return TREE_PURPOSE (*chain);
1850 decl = build_class_reference_decl (ident);
1851 *chain = perm_tree_cons (decl, ident, NULLT);
1858 add_class_reference (CLASS_NAME (ident));
1860 params = build_tree_list (NULLT,
1861 my_build_string (IDENTIFIER_LENGTH (ident) + 1,
1862 IDENTIFIER_POINTER (ident)));
1864 assemble_external (objc_get_class_decl);
1865 return build_function_call (objc_get_class_decl, params);
1869 /* sel_refdef_chain is a list whose "value" fields will be instances
1870 of identifier_node that represent the selector. It returns the
1871 offset of the selector from the beginning of the _OBJC_STRINGS
1872 pool. This offset is typically used by init_selector during code
1875 For each string section we have a chain which maps identifier nodes
1876 to decls for the strings. */
1879 add_objc_string (ident, section)
1881 enum string_section section;
1885 if (section == class_names)
1886 chain = &class_names_chain;
1887 else if (section == meth_var_names)
1888 chain = &meth_var_names_chain;
1889 else if (section == meth_var_types)
1890 chain = &meth_var_types_chain;
1894 if (TREE_VALUE (*chain) == ident)
1895 return TREE_PURPOSE (*chain);
1897 chain = &TREE_CHAIN (*chain);
1900 decl = build_objc_string_decl (ident, section);
1902 *chain = perm_tree_cons (decl, ident, NULLT);
1908 build_objc_string_decl (name, section)
1910 enum string_section section;
1914 struct obstack *save_current_obstack = current_obstack;
1915 struct obstack *save_rtl_obstack = rtl_obstack;
1916 static int class_names_idx = 0;
1917 static int meth_var_names_idx = 0;
1918 static int meth_var_types_idx = 0;
1920 if (section == class_names)
1921 sprintf (buf, "_OBJC_CLASS_NAME_%d", class_names_idx++);
1922 else if (section == meth_var_names)
1923 sprintf (buf, "_OBJC_METH_VAR_NAME_%d", meth_var_names_idx++);
1924 else if (section == meth_var_types)
1925 sprintf (buf, "_OBJC_METH_VAR_TYPE_%d", meth_var_types_idx++);
1927 rtl_obstack = current_obstack = &permanent_obstack;
1928 ident = get_identifier (buf);
1930 decl = build_decl (VAR_DECL, ident, build_array_type (char_type_node, 0));
1931 DECL_EXTERNAL (decl) = 1;
1932 TREE_PUBLIC (decl) = 1;
1933 TREE_USED (decl) = 1;
1934 TREE_READONLY (decl) = 1;
1935 TREE_CONSTANT (decl) = 1;
1937 make_decl_rtl (decl, 0, 1); /* usually called from `rest_of_decl_compilation */
1938 pushdecl_top_level (decl); /* our `extended/custom' pushdecl in c-decl.c */
1940 current_obstack = save_current_obstack;
1941 rtl_obstack = save_rtl_obstack;
1948 objc_declare_alias (alias_ident, class_ident)
1952 if (!doing_objc_thang)
1955 if (is_class_name (class_ident) != class_ident)
1956 warning ("Cannot find class `%s'", IDENTIFIER_POINTER (class_ident));
1957 else if (is_class_name (alias_ident))
1958 warning ("Class `%s' already exists", IDENTIFIER_POINTER (alias_ident));
1960 alias_chain = tree_cons (class_ident, alias_ident, alias_chain);
1964 objc_declare_class (ident_list)
1969 if (!doing_objc_thang)
1972 for (list = ident_list; list; list = TREE_CHAIN (list))
1974 tree ident = TREE_VALUE (list);
1977 if ((decl = lookup_name (ident)))
1979 error ("`%s' redeclared as different kind of symbol",
1980 IDENTIFIER_POINTER (ident));
1981 error_with_decl (decl, "previous declaration of `%s'");
1984 if (! is_class_name (ident))
1986 tree record = xref_tag (RECORD_TYPE, ident);
1987 TREE_STATIC_TEMPLATE (record) = 1;
1988 class_chain = tree_cons (NULLT, ident, class_chain);
1994 is_class_name (ident)
1999 if (lookup_interface (ident))
2002 for (chain = class_chain; chain; chain = TREE_CHAIN (chain))
2004 if (ident == TREE_VALUE (chain))
2008 for (chain = alias_chain; chain; chain = TREE_CHAIN (chain))
2010 if (ident == TREE_VALUE (chain))
2011 return TREE_PURPOSE (chain);
2018 lookup_interface (ident)
2023 for (chain = interface_chain; chain; chain = TREE_CHAIN (chain))
2025 if (ident == CLASS_NAME (chain))
2032 objc_copy_list (list, head)
2036 tree newlist = NULL_TREE, tail = NULL_TREE;
2040 tail = copy_node (list);
2042 /* The following statement fixes a bug when inheriting instance
2043 variables that are declared to be bitfields. finish_struct
2044 expects to find the width of the bitfield in DECL_INITIAL,
2045 which it nulls out after processing the decl of the super
2046 class...rather than change the way finish_struct works (which
2047 is risky), I create the situation it expects...s.naroff
2050 if (DECL_BIT_FIELD (tail) && DECL_INITIAL (tail) == 0)
2051 DECL_INITIAL (tail) = build_int_2 (DECL_FIELD_SIZE (tail), 0);
2053 newlist = chainon (newlist, tail);
2054 list = TREE_CHAIN (list);
2060 /* Used by: build_private_template, get_class_ivars, and
2061 continue_class. COPY is 1 when called from @defs. In this case
2062 copy all fields. Otherwise don't copy leaf ivars since we rely on
2063 them being side-effected exactly once by finish_struct. */
2066 build_ivar_chain (interface, copy)
2070 tree my_name, super_name, ivar_chain;
2072 my_name = CLASS_NAME (interface);
2073 super_name = CLASS_SUPER_NAME (interface);
2075 /* Possibly copy leaf ivars. */
2077 objc_copy_list (CLASS_IVARS (interface), &ivar_chain);
2079 ivar_chain = CLASS_IVARS (interface);
2084 tree super_interface = lookup_interface (super_name);
2086 if (!super_interface)
2088 /* fatal did not work with 2 args...should fix */
2089 error ("Cannot find interface declaration for `%s', superclass of `%s'",
2090 IDENTIFIER_POINTER (super_name),
2091 IDENTIFIER_POINTER (my_name));
2094 if (super_interface == interface)
2096 fatal ("Circular inheritance in interface declaration for `%s'",
2097 IDENTIFIER_POINTER (super_name));
2099 interface = super_interface;
2100 my_name = CLASS_NAME (interface);
2101 super_name = CLASS_SUPER_NAME (interface);
2103 op1 = CLASS_IVARS (interface);
2106 tree head, tail = objc_copy_list (op1, &head);
2108 /* Prepend super class ivars...make a copy of the list, we
2109 do not want to alter the original. */
2110 TREE_CHAIN (tail) = ivar_chain;
2117 /* struct <classname> {
2118 struct objc_class *isa;
2123 build_private_template (class)
2128 if (CLASS_STATIC_TEMPLATE (class))
2130 uprivate_record = CLASS_STATIC_TEMPLATE (class);
2131 ivar_context = TYPE_FIELDS (CLASS_STATIC_TEMPLATE (class));
2135 uprivate_record = start_struct (RECORD_TYPE, CLASS_NAME (class));
2137 ivar_context = build_ivar_chain (class, 0);
2139 finish_struct (uprivate_record, ivar_context);
2141 CLASS_STATIC_TEMPLATE (class) = uprivate_record;
2143 /* mark this record as class template - for class type checking */
2144 TREE_STATIC_TEMPLATE (uprivate_record) = 1;
2146 instance_type = groktypename (build_tree_list (build_tree_list (NULLT, uprivate_record),
2147 build1 (INDIRECT_REF, NULLT, NULLT)));
2148 return ivar_context;
2151 /* Begin code generation for protocols... */
2153 /* struct objc_protocol {
2154 char *protocol_name;
2155 struct objc_protocol **protocol_list;
2156 struct objc_method_desc *instance_methods;
2157 struct objc_method_desc *class_methods;
2161 build_protocol_template ()
2163 tree decl_specs, field_decl, field_decl_chain;
2166 template = start_struct (RECORD_TYPE, get_identifier (UTAG_PROTOCOL));
2168 /* struct objc_class *isa; */
2170 decl_specs = build_tree_list (NULLT, xref_tag (RECORD_TYPE,
2171 get_identifier (UTAG_CLASS)));
2172 field_decl = build1 (INDIRECT_REF, NULLT, get_identifier ("isa"));
2173 field_decl = grokfield (input_filename, lineno, field_decl, decl_specs, NULLT);
2174 field_decl_chain = field_decl;
2176 /* char *protocol_name; */
2178 decl_specs = build_tree_list (NULLT, ridpointers[(int) RID_CHAR]);
2179 field_decl = build1 (INDIRECT_REF, NULLT, get_identifier ("protocol_name"));
2180 field_decl = grokfield (input_filename, lineno, field_decl, decl_specs, NULLT);
2181 chainon (field_decl_chain, field_decl);
2183 /* struct objc_protocol **protocol_list; */
2185 decl_specs = build_tree_list (NULLT, template);
2186 field_decl = build1 (INDIRECT_REF, NULLT, get_identifier ("protocol_list"));
2187 field_decl = build1 (INDIRECT_REF, NULLT, field_decl);
2188 field_decl = grokfield (input_filename, lineno, field_decl, decl_specs, NULLT);
2189 chainon (field_decl_chain, field_decl);
2191 /* struct objc_method_list *instance_methods; */
2193 decl_specs = build_tree_list (NULLT, xref_tag (RECORD_TYPE,
2194 get_identifier (UTAG_METHOD_PROTOTYPE_LIST)));
2195 field_decl = build1 (INDIRECT_REF, NULLT, get_identifier ("instance_methods"));
2196 field_decl = grokfield (input_filename, lineno, field_decl, decl_specs, NULLT);
2197 chainon (field_decl_chain, field_decl);
2199 /* struct objc_method_list *class_methods; */
2201 decl_specs = build_tree_list (NULLT, xref_tag (RECORD_TYPE,
2202 get_identifier (UTAG_METHOD_PROTOTYPE_LIST)));
2203 field_decl = build1 (INDIRECT_REF, NULLT, get_identifier ("class_methods"));
2204 field_decl = grokfield (input_filename, lineno, field_decl, decl_specs, NULLT);
2205 chainon (field_decl_chain, field_decl);
2207 return finish_struct (template, field_decl_chain);
2211 build_descriptor_table_initializer (entries, size)
2215 tree initlist = NULLT;
2219 initlist = tree_cons (NULLT, build_selector (METHOD_SEL_NAME (entries)), initlist);
2221 initlist = tree_cons (NULLT, add_objc_string (METHOD_ENCODING (entries), meth_var_types), initlist);
2224 entries = TREE_CHAIN (entries);
2228 return build_nt (CONSTRUCTOR, NULLT, nreverse (initlist));
2231 /* struct objc_method_prototype_list {
2233 struct objc_method_prototype {
2240 build_method_prototype_list_template (list_type, size)
2244 tree objc_ivar_list_record;
2245 tree decl_specs, field_decl, field_decl_chain;
2247 /* generate an unnamed struct definition */
2249 objc_ivar_list_record = start_struct (RECORD_TYPE, NULLT);
2251 /* int method_count; */
2253 decl_specs = build_tree_list (NULLT, ridpointers[(int) RID_INT]);
2254 field_decl = get_identifier ("method_count");
2256 field_decl = grokfield (input_filename, lineno, field_decl, decl_specs, NULLT);
2257 field_decl_chain = field_decl;
2259 /* struct objc_method method_list[]; */
2261 decl_specs = build_tree_list (NULLT, list_type);
2262 field_decl = build_nt (ARRAY_REF, get_identifier ("method_list"),
2263 build_int_2 (size, 0));
2265 field_decl = grokfield (input_filename, lineno, field_decl, decl_specs, NULLT);
2266 chainon (field_decl_chain, field_decl);
2268 finish_struct (objc_ivar_list_record, field_decl_chain);
2270 return objc_ivar_list_record;
2274 build_method_prototype_template ()
2277 tree decl_specs, field_decl, field_decl_chain;
2279 proto_record = start_struct (RECORD_TYPE, get_identifier (UTAG_METHOD_PROTOTYPE));
2281 #ifdef OBJC_INT_SELECTORS
2282 /* unsigned int _cmd; */
2283 decl_specs = tree_cons (NULLT, ridpointers[(int) RID_UNSIGNED], NULLT);
2284 decl_specs = tree_cons (NULLT, ridpointers[(int) RID_INT], decl_specs);
2285 field_decl = get_identifier ("_cmd");
2286 #else /* OBJC_INT_SELECTORS */
2287 /* struct objc_selector *_cmd; */
2288 decl_specs = tree_cons (NULLT, xref_tag (RECORD_TYPE,
2289 get_identifier (TAG_SELECTOR)), NULLT);
2290 field_decl = build1 (INDIRECT_REF, NULLT, get_identifier ("_cmd"));
2291 #endif /* OBJC_INT_SELECTORS */
2293 field_decl = grokfield (input_filename, lineno, field_decl, decl_specs, NULLT);
2294 field_decl_chain = field_decl;
2296 decl_specs = tree_cons (NULLT, ridpointers[(int) RID_CHAR], NULLT);
2297 field_decl = build1 (INDIRECT_REF, NULLT, get_identifier ("method_types"));
2298 field_decl = grokfield (input_filename, lineno, field_decl, decl_specs, NULLT);
2299 chainon (field_decl_chain, field_decl);
2301 finish_struct (proto_record, field_decl_chain);
2303 return proto_record;
2307 forwarding_offset (parm)
2310 int offset_in_bytes;
2312 if (GET_CODE (DECL_INCOMING_RTL (parm)) == MEM)
2314 rtx addr = XEXP (DECL_INCOMING_RTL (parm), 0);
2316 /* ??? Here we assume that the parm address is indexed
2317 off the frame pointer or arg pointer.
2318 If that is not true, we produce meaningless results,
2319 but do not crash. */
2320 if (GET_CODE (addr) == PLUS
2321 && GET_CODE (XEXP (addr, 1)) == CONST_INT)
2322 offset_in_bytes = INTVAL (XEXP (addr, 1));
2324 offset_in_bytes = 0;
2326 offset_in_bytes += OBJC_FORWARDING_STACK_OFFSET;
2328 #ifdef OBJC_FORWARDING_REG_OFFSET
2329 else if (GET_CODE (DECL_INCOMING_RTL (parm)) == REG)
2331 int regno = REGNO (DECL_INCOMING_RTL (parm));
2333 offset_in_bytes = 4 * (regno - OBJC_FORWARDING_FIRST_REG)
2334 + OBJC_FORWARDING_REG_OFFSET;
2336 #endif /* OBJC_FORWARDING_REG_OFFSET */
2340 /* This is the case where the parm is passed as an int or double
2341 and it is converted to a char, short or float and stored back
2342 in the parmlist. In this case, describe the parm
2343 with the variable's declared type, and adjust the address
2344 if the least significant bytes (which we are using) are not
2346 #if BYTES_BIG_ENDIAN
2347 if (TREE_TYPE (parm) != DECL_ARG_TYPE (parm))
2348 offset_in_bytes += (GET_MODE_SIZE (TYPE_MODE (DECL_ARG_TYPE (parm)))
2349 - GET_MODE_SIZE (GET_MODE (DECL_RTL (parm))));
2352 return offset_in_bytes;
2356 encode_method_prototype (method_decl, func_decl)
2363 int max_parm_end = 0;
2367 /* `oneway' and 'bycopy', for remote object are the only method qualifiers */
2368 encode_type_qualifiers (TREE_PURPOSE (TREE_TYPE (method_decl)));
2371 encode_type (TREE_TYPE (TREE_TYPE (func_decl)),
2372 obstack_object_size (&util_obstack),
2373 OBJC_ENCODE_INLINE_DEFS);
2376 for (parms = DECL_ARGUMENTS (func_decl); parms;
2377 parms = TREE_CHAIN (parms))
2379 int parm_end = (forwarding_offset (parms)
2380 + (TREE_INT_CST_LOW (TYPE_SIZE (TREE_TYPE (parms)))
2383 if (parm_end > max_parm_end)
2384 max_parm_end = parm_end;
2387 stack_size = max_parm_end - OBJC_FORWARDING_MIN_OFFSET;
2389 sprintf (buf, "%d", stack_size);
2390 obstack_grow (&util_obstack, buf, strlen (buf));
2392 user_args = METHOD_SEL_ARGS (method_decl);
2394 /* argument types */
2395 for (parms = DECL_ARGUMENTS (func_decl), i = 0; parms;
2396 parms = TREE_CHAIN (parms), i++)
2398 /* process argument qualifiers for user supplied arguments */
2401 encode_type_qualifiers (TREE_PURPOSE (TREE_TYPE (user_args)));
2402 user_args = TREE_CHAIN (user_args);
2406 encode_type (TREE_TYPE (parms),
2407 obstack_object_size (&util_obstack),
2408 OBJC_ENCODE_INLINE_DEFS);
2410 /* compute offset */
2411 sprintf (buf, "%d", forwarding_offset (parms));
2412 obstack_grow (&util_obstack, buf, strlen (buf));
2415 obstack_1grow (&util_obstack, '\0');
2416 result = get_identifier (obstack_finish (&util_obstack));
2417 obstack_free (&util_obstack, util_firstobj);
2422 generate_descriptor_table (type, name, size, list, proto)
2429 tree sc_spec, decl_specs, decl, initlist;
2431 sc_spec = tree_cons (NULLT, ridpointers[(int) RID_STATIC], NULLT);
2432 decl_specs = tree_cons (NULLT, type, sc_spec);
2434 decl = start_decl (synth_id_with_class_suffix (name, proto),
2436 end_temporary_allocation ();
2438 initlist = build_tree_list (NULLT, build_int_2 (size, 0));
2439 initlist = tree_cons (NULLT, list, initlist);
2441 finish_decl (decl, build_nt (CONSTRUCTOR, NULLT, nreverse (initlist)), NULLT);
2447 generate_method_descriptors (protocol) /* generate_dispatch_tables */
2450 static tree objc_method_prototype_template;
2451 tree initlist, chain, method_list_template;
2452 tree cast, variable_length_type;
2455 if (!objc_method_prototype_template)
2456 objc_method_prototype_template = build_method_prototype_template ();
2458 cast = build_tree_list (build_tree_list (NULLT, xref_tag (RECORD_TYPE,
2459 get_identifier (UTAG_METHOD_PROTOTYPE_LIST))), NULLT);
2460 variable_length_type = groktypename (cast);
2462 chain = PROTOCOL_CLS_METHODS (protocol);
2467 initlist = build_descriptor_table_initializer (chain, &size);
2469 method_list_template
2470 = build_method_prototype_list_template (objc_method_prototype_template,
2473 UOBJC_CLASS_METHODS_decl
2474 = generate_descriptor_table (method_list_template,
2475 "_OBJC_PROTOCOL_CLASS_METHODS",
2476 size, initlist, protocol);
2478 TREE_TYPE (UOBJC_CLASS_METHODS_decl) = variable_length_type;
2481 UOBJC_CLASS_METHODS_decl = 0;
2483 chain = PROTOCOL_NST_METHODS (protocol);
2487 initlist = build_descriptor_table_initializer (chain, &size);
2489 method_list_template
2490 = build_method_prototype_list_template (objc_method_prototype_template,
2493 UOBJC_INSTANCE_METHODS_decl
2494 = generate_descriptor_table (method_list_template,
2495 "_OBJC_PROTOCOL_INSTANCE_METHODS",
2496 size, initlist, protocol);
2498 TREE_TYPE (UOBJC_INSTANCE_METHODS_decl) = variable_length_type;
2501 UOBJC_INSTANCE_METHODS_decl = 0;
2505 build_tmp_function_decl ()
2507 tree decl_specs, expr_decl, parms;
2509 /* struct objc_object *objc_xxx (id, SEL, ...); */
2511 decl_specs = build_tree_list (NULLT, objc_object_reference);
2512 push_parm_decl (build_tree_list (decl_specs,
2513 build1 (INDIRECT_REF, NULLT, NULLT)));
2515 decl_specs = build_tree_list (NULLT, xref_tag (RECORD_TYPE,
2516 get_identifier (TAG_SELECTOR)));
2517 expr_decl = build1 (INDIRECT_REF, NULLT, NULLT);
2519 push_parm_decl (build_tree_list (decl_specs, expr_decl));
2520 parms = get_parm_info (0);
2523 decl_specs = build_tree_list (NULLT, objc_object_reference);
2524 expr_decl = build_nt (CALL_EXPR, get_identifier ("objc_xxx"), parms, NULLT);
2525 expr_decl = build1 (INDIRECT_REF, NULLT, expr_decl);
2527 return define_decl (expr_decl, decl_specs);
2531 hack_method_prototype (nst_methods, tmp_decl)
2537 /* Hack to avoid problem with static typing of self arg. */
2538 TREE_CODE (nst_methods) = CLASS_METHOD_DECL;
2539 start_method_def (nst_methods);
2540 TREE_CODE (nst_methods) = INSTANCE_METHOD_DECL;
2542 if (METHOD_ADD_ARGS (nst_methods) == (tree) 1)
2543 parms = get_parm_info (0); /* we have a `, ...' */
2545 parms = get_parm_info (1); /* place a `void_at_end' */
2547 poplevel (0, 0, 0); /* Must be called BEFORE start_function. */
2549 /* Usually called from store_parm_decls -> init_function_start. */
2551 init_emit (); /* needed to make assign_parms work (with -O). */
2553 DECL_ARGUMENTS (tmp_decl) = TREE_PURPOSE (parms);
2556 /* Code taken from start_function. */
2557 tree restype = TREE_TYPE (TREE_TYPE (tmp_decl));
2558 /* Promote the value to int before returning it. */
2559 if (TREE_CODE (restype) == INTEGER_TYPE
2560 && TYPE_PRECISION (restype) < TYPE_PRECISION (integer_type_node))
2561 restype = integer_type_node;
2562 DECL_RESULT (tmp_decl) = build_decl (RESULT_DECL, 0, restype);
2565 /* Typically called from expand_function_start for function definitions. */
2566 assign_parms (tmp_decl, 0);
2568 /* install return type */
2569 TREE_TYPE (TREE_TYPE (tmp_decl)) = groktypename (TREE_TYPE (nst_methods));
2573 generate_protocol_references (plist)
2578 /* forward declare protocols referenced */
2579 for (lproto = plist; lproto; lproto = TREE_CHAIN (lproto))
2581 tree proto = TREE_VALUE (lproto);
2583 if (TREE_CODE (proto) == PROTOCOL_INTERFACE_TYPE
2584 && PROTOCOL_NAME (proto))
2586 if (! PROTOCOL_FORWARD_DECL (proto))
2587 build_protocol_reference (proto);
2589 if (PROTOCOL_LIST (proto))
2590 generate_protocol_references (PROTOCOL_LIST (proto));
2596 generate_protocols ()
2598 tree p, tmp_decl, encoding;
2599 tree sc_spec, decl_specs, decl;
2600 tree initlist, protocol_name_expr, refs_decl, refs_expr;
2601 tree cast_type2 = 0;
2603 tmp_decl = build_tmp_function_decl ();
2605 if (! objc_protocol_template)
2606 objc_protocol_template = build_protocol_template ();
2608 /* if a protocol was directly referenced, pull in indirect references */
2609 for (p = protocol_chain; p; p = TREE_CHAIN (p))
2610 if (PROTOCOL_FORWARD_DECL (p) && PROTOCOL_LIST (p))
2611 generate_protocol_references (PROTOCOL_LIST (p));
2613 for (p = protocol_chain; p; p = TREE_CHAIN (p))
2615 tree nst_methods = PROTOCOL_NST_METHODS (p);
2616 tree cls_methods = PROTOCOL_CLS_METHODS (p);
2618 /* if protocol wasn't referenced, don't generate any code */
2619 if (! PROTOCOL_FORWARD_DECL (p))
2622 /* Make sure we link in the Protocol class. */
2623 add_class_reference (get_identifier (PROTOCOL_OBJECT_CLASS_NAME));
2627 hack_method_prototype (nst_methods, tmp_decl);
2628 encoding = encode_method_prototype (nst_methods, tmp_decl);
2629 METHOD_ENCODING (nst_methods) = encoding;
2631 nst_methods = TREE_CHAIN (nst_methods);
2636 hack_method_prototype (cls_methods, tmp_decl);
2637 encoding = encode_method_prototype (cls_methods, tmp_decl);
2638 METHOD_ENCODING (cls_methods) = encoding;
2640 cls_methods = TREE_CHAIN (cls_methods);
2642 generate_method_descriptors (p);
2644 if (PROTOCOL_LIST (p))
2645 refs_decl = generate_protocol_list (p);
2649 /* static struct objc_protocol _OBJC_PROTOCOL_<mumble>; */
2651 sc_spec = tree_cons (NULLT, ridpointers[(int) RID_STATIC], NULLT);
2652 decl_specs = tree_cons (NULLT, objc_protocol_template, sc_spec);
2654 decl = start_decl (synth_id_with_class_suffix ("_OBJC_PROTOCOL", p),
2656 end_temporary_allocation ();
2658 protocol_name_expr = add_objc_string (PROTOCOL_NAME (p), class_names);
2664 = groktypename (build_tree_list (build_tree_list (NULLT, objc_protocol_template),
2665 build1 (INDIRECT_REF, NULLT,
2666 build1 (INDIRECT_REF, NULLT, NULLT))));
2668 refs_expr = build_unary_op (ADDR_EXPR, refs_decl, 0);
2669 TREE_TYPE (refs_expr) = cast_type2;
2672 refs_expr = build_int_2 (0, 0);
2674 /* UOBJC_INSTANCE_METHODS_decl/UOBJC_CLASS_METHODS_decl are set
2675 by generate_method_descriptors, which is called above. */
2676 initlist = build_protocol_initializer (protocol_name_expr, refs_expr,
2677 UOBJC_INSTANCE_METHODS_decl,
2678 UOBJC_CLASS_METHODS_decl);
2679 finish_decl (decl, initlist, NULLT);
2681 /* Mark the decl as used to avoid "defined but not used" warning. */
2682 TREE_USED (decl) = 1;
2687 build_protocol_initializer (protocol_name, protocol_list,
2688 instance_methods, class_methods)
2691 tree instance_methods;
2694 tree initlist = NULLT, expr;
2695 static tree cast_type = 0;
2699 = groktypename (build_tree_list
2700 (build_tree_list (NULLT,
2701 xref_tag (RECORD_TYPE,
2702 get_identifier (UTAG_CLASS))),
2703 build1 (INDIRECT_REF, NULLT, NULLT)));
2705 /* filling the "isa" in with one allows the runtime system to
2706 detect that the version change...should remove before final release */
2708 expr = build_int_2 (PROTOCOL_VERSION, 0);
2709 TREE_TYPE (expr) = cast_type;
2710 initlist = tree_cons (NULLT, expr, initlist);
2711 initlist = tree_cons (NULLT, protocol_name, initlist);
2712 initlist = tree_cons (NULLT, protocol_list, initlist);
2714 if (!instance_methods)
2715 initlist = tree_cons (NULLT, build_int_2 (0, 0), initlist);
2718 expr = build_unary_op (ADDR_EXPR, instance_methods, 0);
2719 initlist = tree_cons (NULLT, expr, initlist);
2722 initlist = tree_cons (NULLT, build_int_2 (0, 0), initlist);
2725 expr = build_unary_op (ADDR_EXPR, class_methods, 0);
2726 initlist = tree_cons (NULLT, expr, initlist);
2728 return build_nt (CONSTRUCTOR, NULLT, nreverse (initlist));
2730 /* end code generation for protocols... */
2732 /* struct objc_category {
2733 char *category_name;
2735 struct objc_method_list *instance_methods;
2736 struct objc_method_list *class_methods;
2737 struct objc_protocol_list *protocols;
2741 build_category_template ()
2743 tree decl_specs, field_decl, field_decl_chain;
2745 objc_category_template = start_struct (RECORD_TYPE,
2746 get_identifier (UTAG_CATEGORY));
2747 /* char *category_name; */
2749 decl_specs = build_tree_list (NULLT, ridpointers[(int) RID_CHAR]);
2750 field_decl = build1 (INDIRECT_REF, NULLT, get_identifier ("category_name"));
2751 field_decl = grokfield (input_filename, lineno, field_decl, decl_specs, NULLT);
2752 field_decl_chain = field_decl;
2754 /* char *class_name; */
2756 decl_specs = build_tree_list (NULLT, ridpointers[(int) RID_CHAR]);
2757 field_decl = build1 (INDIRECT_REF, NULLT, get_identifier ("class_name"));
2758 field_decl = grokfield (input_filename, lineno, field_decl, decl_specs, NULLT);
2759 chainon (field_decl_chain, field_decl);
2761 /* struct objc_method_list *instance_methods; */
2763 decl_specs = build_tree_list (NULLT, xref_tag (RECORD_TYPE,
2764 get_identifier (UTAG_METHOD_LIST)));
2765 field_decl = build1 (INDIRECT_REF, NULLT, get_identifier ("instance_methods"));
2766 field_decl = grokfield (input_filename, lineno, field_decl, decl_specs, NULLT);
2767 chainon (field_decl_chain, field_decl);
2769 /* struct objc_method_list *class_methods; */
2771 decl_specs = build_tree_list (NULLT, xref_tag (RECORD_TYPE,
2772 get_identifier (UTAG_METHOD_LIST)));
2773 field_decl = build1 (INDIRECT_REF, NULLT, get_identifier ("class_methods"));
2774 field_decl = grokfield (input_filename, lineno, field_decl, decl_specs, NULLT);
2775 chainon (field_decl_chain, field_decl);
2777 /* struct objc_protocol **protocol_list; */
2779 decl_specs = build_tree_list (NULLT, xref_tag (RECORD_TYPE,
2780 get_identifier (UTAG_PROTOCOL)));
2781 field_decl = build1 (INDIRECT_REF, NULLT, get_identifier ("protocol_list"));
2782 field_decl = build1 (INDIRECT_REF, NULLT, field_decl);
2783 field_decl = grokfield (input_filename, lineno, field_decl, decl_specs, NULLT)
2785 chainon (field_decl_chain, field_decl);
2787 finish_struct (objc_category_template, field_decl_chain);
2790 /* struct objc_class {
2791 struct objc_class *isa;
2792 struct objc_class *super_class;
2797 struct objc_ivar_list *ivars;
2798 struct objc_method_list *methods;
2799 if (flag_next_runtime)
2800 struct objc_cache *cache;
2802 struct sarray *dtable;
2803 struct objc_class *subclass_list;
2804 struct objc_class *sibling_class;
2806 struct objc_protocol_list *protocols;
2810 build_class_template ()
2812 tree decl_specs, field_decl, field_decl_chain;
2814 objc_class_template = start_struct (RECORD_TYPE, get_identifier (UTAG_CLASS));
2816 /* struct objc_class *isa; */
2818 decl_specs = build_tree_list (NULLT, objc_class_template);
2819 field_decl = build1 (INDIRECT_REF, NULLT, get_identifier ("isa"));
2820 field_decl = grokfield (input_filename, lineno, field_decl, decl_specs, NULLT);
2821 field_decl_chain = field_decl;
2823 /* struct objc_class *super_class; */
2825 decl_specs = build_tree_list (NULLT, objc_class_template);
2826 field_decl = build1 (INDIRECT_REF, NULLT, get_identifier ("super_class"));
2827 field_decl = grokfield (input_filename, lineno, field_decl, decl_specs, NULLT);
2828 chainon (field_decl_chain, field_decl);
2832 decl_specs = build_tree_list (NULLT, ridpointers[(int) RID_CHAR]);
2833 field_decl = build1 (INDIRECT_REF, NULLT, get_identifier ("name"));
2834 field_decl = grokfield (input_filename, lineno, field_decl, decl_specs, NULLT);
2835 chainon (field_decl_chain, field_decl);
2839 decl_specs = build_tree_list (NULLT, ridpointers[(int) RID_LONG]);
2840 field_decl = get_identifier ("version");
2841 field_decl = grokfield (input_filename, lineno, field_decl, decl_specs, NULLT);
2842 chainon (field_decl_chain, field_decl);
2846 decl_specs = build_tree_list (NULLT, ridpointers[(int) RID_LONG]);
2847 field_decl = get_identifier ("info");
2848 field_decl = grokfield (input_filename, lineno, field_decl, decl_specs, NULLT);
2849 chainon (field_decl_chain, field_decl);
2851 /* long instance_size; */
2853 decl_specs = build_tree_list (NULLT, ridpointers[(int) RID_LONG]);
2854 field_decl = get_identifier ("instance_size");
2855 field_decl = grokfield (input_filename, lineno, field_decl, decl_specs, NULLT);
2856 chainon (field_decl_chain, field_decl);
2858 /* struct objc_ivar_list *ivars; */
2860 decl_specs = build_tree_list (NULLT, xref_tag (RECORD_TYPE,
2861 get_identifier (UTAG_IVAR_LIST)));
2862 field_decl = build1 (INDIRECT_REF, NULLT, get_identifier ("ivars"));
2863 field_decl = grokfield (input_filename, lineno, field_decl, decl_specs, NULLT);
2864 chainon (field_decl_chain, field_decl);
2866 /* struct objc_method_list *methods; */
2868 decl_specs = build_tree_list (NULLT, xref_tag (RECORD_TYPE,
2869 get_identifier (UTAG_METHOD_LIST)));
2870 field_decl = build1 (INDIRECT_REF, NULLT, get_identifier ("methods"));
2871 field_decl = grokfield (input_filename, lineno, field_decl, decl_specs, NULLT);
2872 chainon (field_decl_chain, field_decl);
2874 if (flag_next_runtime)
2876 /* struct objc_cache *cache; */
2878 decl_specs = build_tree_list (NULLT, xref_tag (RECORD_TYPE,
2879 get_identifier ("objc_cache")));
2880 field_decl = build1 (INDIRECT_REF, NULLT, get_identifier ("cache"));
2881 field_decl = grokfield (input_filename, lineno, field_decl, decl_specs, NULLT);
2882 chainon (field_decl_chain, field_decl);
2886 /* struct sarray *dtable; */
2888 decl_specs = build_tree_list (NULLT, xref_tag (RECORD_TYPE,
2889 get_identifier ("sarray")));
2890 field_decl = build1 (INDIRECT_REF, NULLT, get_identifier ("dtable"));
2891 field_decl = grokfield (input_filename, lineno, field_decl, decl_specs, NULLT);
2892 chainon (field_decl_chain, field_decl);
2894 /* struct objc_class *subclass_list; */
2896 decl_specs = build_tree_list (NULLT, objc_class_template);
2897 field_decl = build1 (INDIRECT_REF, NULLT, get_identifier ("subclass_list"));
2898 field_decl = grokfield (input_filename, lineno, field_decl, decl_specs, NULLT);
2899 chainon (field_decl_chain, field_decl);
2901 /* struct objc_class *sibling_class; */
2903 decl_specs = build_tree_list (NULLT, objc_class_template);
2904 field_decl = build1 (INDIRECT_REF, NULLT, get_identifier ("sibling_class"));
2905 field_decl = grokfield (input_filename, lineno, field_decl, decl_specs, NULLT);
2906 chainon (field_decl_chain, field_decl);
2909 /* struct objc_protocol **protocol_list; */
2911 decl_specs = build_tree_list (NULLT, xref_tag (RECORD_TYPE,
2912 get_identifier (UTAG_PROTOCOL)));
2913 field_decl = build1 (INDIRECT_REF, NULLT, get_identifier ("protocol_list"));
2914 field_decl = build1 (INDIRECT_REF, NULLT, field_decl);
2915 field_decl = grokfield (input_filename, lineno, field_decl, decl_specs, NULLT);
2916 chainon (field_decl_chain, field_decl);
2919 finish_struct (objc_class_template, field_decl_chain);
2922 /* Generate appropriate forward declarations for an implementation. */
2925 synth_forward_declarations ()
2927 tree sc_spec, decl_specs, an_id;
2929 /* extern struct objc_class _OBJC_CLASS_<my_name>; */
2931 an_id = synth_id_with_class_suffix ("_OBJC_CLASS", implementation_context);
2933 sc_spec = build_tree_list (NULLT, ridpointers[(int) RID_EXTERN]);
2934 decl_specs = tree_cons (NULLT, objc_class_template, sc_spec);
2935 UOBJC_CLASS_decl = define_decl (an_id, decl_specs);
2936 TREE_USED (UOBJC_CLASS_decl) = 1;
2938 /* extern struct objc_class _OBJC_METACLASS_<my_name>; */
2940 an_id = synth_id_with_class_suffix ("_OBJC_METACLASS",
2941 implementation_context);
2943 UOBJC_METACLASS_decl = define_decl (an_id, decl_specs);
2944 TREE_USED (UOBJC_METACLASS_decl) = 1;
2946 /* pre-build the following entities - for speed/convenience. */
2948 an_id = get_identifier ("super_class");
2949 ucls_super_ref = build_component_ref (UOBJC_CLASS_decl, an_id);
2950 uucls_super_ref = build_component_ref (UOBJC_METACLASS_decl, an_id);
2954 error_with_ivar (message, decl, rawdecl)
2961 report_error_function (DECL_SOURCE_FILE (decl));
2963 fprintf (stderr, "%s:%d: ",
2964 DECL_SOURCE_FILE (decl), DECL_SOURCE_LINE (decl));
2965 bzero (errbuf, BUFSIZE);
2966 fprintf (stderr, "%s `%s'\n", message, gen_declaration (rawdecl, errbuf));
2969 #define USERTYPE(t) (TREE_CODE (t) == RECORD_TYPE || \
2970 TREE_CODE (t) == UNION_TYPE || \
2971 TREE_CODE (t) == ENUMERAL_TYPE)
2974 check_ivars (inter, imp)
2978 tree intdecls = CLASS_IVARS (inter);
2979 tree impdecls = CLASS_IVARS (imp);
2980 tree rawintdecls = CLASS_RAW_IVARS (inter);
2981 tree rawimpdecls = CLASS_RAW_IVARS (imp);
2987 if (intdecls == 0 && impdecls == 0)
2989 if (intdecls == 0 || impdecls == 0)
2991 error ("inconsistent instance variable specification");
2994 t1 = TREE_TYPE (intdecls); t2 = TREE_TYPE (impdecls);
2996 if (!comptypes (t1, t2))
2998 if (DECL_NAME (intdecls) == DECL_NAME (impdecls))
3000 error_with_ivar ("conflicting instance variable type",
3001 impdecls, rawimpdecls);
3002 error_with_ivar ("previous declaration of",
3003 intdecls, rawintdecls);
3005 else /* both the type and the name don't match */
3007 error ("inconsistent instance variable specification");
3011 else if (DECL_NAME (intdecls) != DECL_NAME (impdecls))
3013 error_with_ivar ("conflicting instance variable name",
3014 impdecls, rawimpdecls);
3015 error_with_ivar ("previous declaration of",
3016 intdecls, rawintdecls);
3018 intdecls = TREE_CHAIN (intdecls);
3019 impdecls = TREE_CHAIN (impdecls);
3020 rawintdecls = TREE_CHAIN (rawintdecls);
3021 rawimpdecls = TREE_CHAIN (rawimpdecls);
3025 /* Set super_type to the data type node for struct objc_super *,
3026 first defining struct objc_super itself.
3027 This needs to be done just once per compilation. */
3030 build_super_template ()
3032 tree record, decl_specs, field_decl, field_decl_chain;
3034 record = start_struct (RECORD_TYPE, get_identifier (UTAG_SUPER));
3036 /* struct objc_object *self; */
3038 decl_specs = build_tree_list (NULLT, objc_object_reference);
3039 field_decl = get_identifier ("self");
3040 field_decl = build1 (INDIRECT_REF, NULLT, field_decl);
3041 field_decl = grokfield (input_filename, lineno,
3042 field_decl, decl_specs, NULLT);
3043 field_decl_chain = field_decl;
3045 /* struct objc_class *class; */
3047 decl_specs = get_identifier (UTAG_CLASS);
3048 decl_specs = build_tree_list (NULLT, xref_tag (RECORD_TYPE, decl_specs));
3049 field_decl = build1 (INDIRECT_REF, NULLT, get_identifier ("class"));
3051 field_decl = grokfield (input_filename, lineno,
3052 field_decl, decl_specs, NULLT);
3053 chainon (field_decl_chain, field_decl);
3055 finish_struct (record, field_decl_chain);
3057 /* `struct objc_super *' */
3058 super_type = groktypename (build_tree_list (build_tree_list (NULLT, record),
3059 build1 (INDIRECT_REF,
3064 /* struct objc_ivar {
3071 build_ivar_template ()
3073 tree objc_ivar_id, objc_ivar_record;
3074 tree decl_specs, field_decl, field_decl_chain;
3076 objc_ivar_id = get_identifier (UTAG_IVAR);
3077 objc_ivar_record = start_struct (RECORD_TYPE, objc_ivar_id);
3079 /* char *ivar_name; */
3081 decl_specs = build_tree_list (NULLT, ridpointers[(int) RID_CHAR]);
3082 field_decl = build1 (INDIRECT_REF, NULLT, get_identifier ("ivar_name"));
3084 field_decl = grokfield (input_filename, lineno, field_decl,
3086 field_decl_chain = field_decl;
3088 /* char *ivar_type; */
3090 decl_specs = build_tree_list (NULLT, ridpointers[(int) RID_CHAR]);
3091 field_decl = build1 (INDIRECT_REF, NULLT, get_identifier ("ivar_type"));
3093 field_decl = grokfield (input_filename, lineno, field_decl,
3095 chainon (field_decl_chain, field_decl);
3097 /* int ivar_offset; */
3099 decl_specs = build_tree_list (NULLT, ridpointers[(int) RID_INT]);
3100 field_decl = get_identifier ("ivar_offset");
3102 field_decl = grokfield (input_filename, lineno, field_decl,
3104 chainon (field_decl_chain, field_decl);
3106 finish_struct (objc_ivar_record, field_decl_chain);
3108 return objc_ivar_record;
3113 struct objc_ivar ivar_list[ivar_count];
3117 build_ivar_list_template (list_type, size)
3121 tree objc_ivar_list_record;
3122 tree decl_specs, field_decl, field_decl_chain;
3124 objc_ivar_list_record = start_struct (RECORD_TYPE, NULLT);
3126 /* int ivar_count; */
3128 decl_specs = build_tree_list (NULLT, ridpointers[(int) RID_INT]);
3129 field_decl = get_identifier ("ivar_count");
3131 field_decl = grokfield (input_filename, lineno, field_decl,
3133 field_decl_chain = field_decl;
3135 /* struct objc_ivar ivar_list[]; */
3137 decl_specs = build_tree_list (NULLT, list_type);
3138 field_decl = build_nt (ARRAY_REF, get_identifier ("ivar_list"),
3139 build_int_2 (size, 0));
3141 field_decl = grokfield (input_filename, lineno,
3142 field_decl, decl_specs, NULLT);
3143 chainon (field_decl_chain, field_decl);
3145 finish_struct (objc_ivar_list_record, field_decl_chain);
3147 return objc_ivar_list_record;
3153 struct objc_method method_list[method_count];
3157 build_method_list_template (list_type, size)
3161 tree objc_ivar_list_record;
3162 tree decl_specs, field_decl, field_decl_chain;
3164 objc_ivar_list_record = start_struct (RECORD_TYPE, NULLT);
3166 /* int method_next; */
3168 decl_specs = build_tree_list (NULLT, ridpointers[(int) RID_INT]);
3169 field_decl = get_identifier ("method_next");
3171 field_decl = grokfield (input_filename, lineno, field_decl, decl_specs, NULLT);
3172 field_decl_chain = field_decl;
3174 /* int method_count; */
3176 decl_specs = build_tree_list (NULLT, ridpointers[(int) RID_INT]);
3177 field_decl = get_identifier ("method_count");
3179 field_decl = grokfield (input_filename, lineno,
3180 field_decl, decl_specs, NULLT);
3181 chainon (field_decl_chain, field_decl);
3183 /* struct objc_method method_list[]; */
3185 decl_specs = build_tree_list (NULLT, list_type);
3186 field_decl = build_nt (ARRAY_REF, get_identifier ("method_list"),
3187 build_int_2 (size, 0));
3189 field_decl = grokfield (input_filename, lineno,
3190 field_decl, decl_specs, NULLT);
3191 chainon (field_decl_chain, field_decl);
3193 finish_struct (objc_ivar_list_record, field_decl_chain);
3195 return objc_ivar_list_record;
3199 build_ivar_list_initializer (field_decl, size)
3203 tree initlist = NULLT;
3208 if (DECL_NAME (field_decl))
3209 initlist = tree_cons (NULLT,
3210 add_objc_string (DECL_NAME (field_decl),
3214 /* unnamed bit-field ivar (yuck). */
3215 initlist = tree_cons (NULLT, build_int_2 (0, 0), initlist);
3218 encode_field_decl (field_decl,
3219 obstack_object_size (&util_obstack),
3220 OBJC_ENCODE_DONT_INLINE_DEFS);
3221 obstack_1grow (&util_obstack, 0); /* null terminate string */
3225 add_objc_string (get_identifier (obstack_finish (&util_obstack)),
3228 obstack_free (&util_obstack, util_firstobj);
3234 build_int_2 ((TREE_INT_CST_LOW (DECL_FIELD_BITPOS (field_decl))
3239 field_decl = TREE_CHAIN (field_decl);
3243 return build_nt (CONSTRUCTOR, NULLT, nreverse (initlist));
3247 generate_ivars_list (type, name, size, list)
3253 tree sc_spec, decl_specs, decl, initlist;
3255 sc_spec = tree_cons (NULLT, ridpointers[(int) RID_STATIC], NULLT);
3256 decl_specs = tree_cons (NULLT, type, sc_spec);
3258 decl = start_decl (synth_id_with_class_suffix (name, implementation_context),
3260 end_temporary_allocation ();
3262 initlist = build_tree_list (NULLT, build_int_2 (size, 0));
3263 initlist = tree_cons (NULLT, list, initlist);
3265 finish_decl (decl, build_nt (CONSTRUCTOR, NULLT, nreverse (initlist)), NULLT);
3271 generate_ivar_lists ()
3273 tree initlist, ivar_list_template, chain;
3274 tree cast, variable_length_type;
3277 generating_instance_variables = 1;
3279 if (!objc_ivar_template)
3280 objc_ivar_template = build_ivar_template ();
3284 (build_tree_list (NULLT, xref_tag (RECORD_TYPE,
3285 get_identifier (UTAG_IVAR_LIST))),
3287 variable_length_type = groktypename (cast);
3289 /* only generate class variables for the root of the inheritance
3290 hierarchy since these will be the same for every class */
3292 if (CLASS_SUPER_NAME (implementation_template) == NULLT
3293 && (chain = TYPE_FIELDS (objc_class_template)))
3296 initlist = build_ivar_list_initializer (chain, &size);
3298 ivar_list_template = build_ivar_list_template (objc_ivar_template, size);
3300 UOBJC_CLASS_VARIABLES_decl =
3301 generate_ivars_list (ivar_list_template, "_OBJC_CLASS_VARIABLES",
3304 TREE_TYPE (UOBJC_CLASS_VARIABLES_decl) = variable_length_type;
3307 UOBJC_CLASS_VARIABLES_decl = 0;
3309 chain = CLASS_IVARS (implementation_template);
3313 initlist = build_ivar_list_initializer (chain, &size);
3315 ivar_list_template = build_ivar_list_template (objc_ivar_template, size);
3317 UOBJC_INSTANCE_VARIABLES_decl =
3318 generate_ivars_list (ivar_list_template, "_OBJC_INSTANCE_VARIABLES",
3321 TREE_TYPE (UOBJC_INSTANCE_VARIABLES_decl) = variable_length_type;
3324 UOBJC_INSTANCE_VARIABLES_decl = 0;
3326 generating_instance_variables = 0;
3330 build_dispatch_table_initializer (entries, size)
3334 tree initlist = NULLT;
3338 initlist = tree_cons (NULLT, build_selector (METHOD_SEL_NAME (entries)),
3341 initlist = tree_cons (NULLT, add_objc_string (METHOD_ENCODING (entries),
3345 initlist = tree_cons (NULLT, METHOD_DEFINITION (entries), initlist);
3348 entries = TREE_CHAIN (entries);
3352 return build_nt (CONSTRUCTOR, NULLT, nreverse (initlist));
3355 /* To accomplish method prototyping without generating all kinds of
3356 inane warnings, the definition of the dispatch table entries were
3359 struct objc_method { SEL _cmd; id (*_imp)(); };
3361 struct objc_method { SEL _cmd; void *_imp; }; */
3364 build_method_template ()
3367 tree decl_specs, field_decl, field_decl_chain;
3369 _SLT_record = start_struct (RECORD_TYPE, get_identifier (UTAG_METHOD));
3371 #ifdef OBJC_INT_SELECTORS
3372 /* unsigned int _cmd; */
3373 decl_specs = tree_cons (NULLT, ridpointers[(int) RID_UNSIGNED], NULLT);
3374 decl_specs = tree_cons (NULLT, ridpointers[(int) RID_INT], decl_specs);
3375 field_decl = get_identifier ("_cmd");
3376 #else /* not OBJC_INT_SELECTORS */
3377 /* struct objc_selector *_cmd; */
3378 decl_specs = tree_cons (NULLT,
3379 xref_tag (RECORD_TYPE,
3380 get_identifier (TAG_SELECTOR)),
3382 field_decl = build1 (INDIRECT_REF, NULLT, get_identifier ("_cmd"));
3383 #endif /* not OBJC_INT_SELECTORS */
3385 field_decl = grokfield (input_filename, lineno, field_decl, decl_specs, NULLT);
3386 field_decl_chain = field_decl;
3388 decl_specs = tree_cons (NULLT, ridpointers[(int) RID_CHAR], NULLT);
3389 field_decl = build1 (INDIRECT_REF, NULLT, get_identifier ("method_types"));
3390 field_decl = grokfield (input_filename, lineno, field_decl, decl_specs, NULLT);
3391 chainon (field_decl_chain, field_decl);
3395 decl_specs = tree_cons (NULLT, ridpointers[(int) RID_VOID], NULLT);
3396 field_decl = build1 (INDIRECT_REF, NULLT, get_identifier ("_imp"));
3397 field_decl = grokfield (input_filename, lineno, field_decl, decl_specs, NULLT);
3398 chainon (field_decl_chain, field_decl);
3400 finish_struct (_SLT_record, field_decl_chain);
3407 generate_dispatch_table (type, name, size, list)
3413 tree sc_spec, decl_specs, decl, initlist;
3415 sc_spec = tree_cons (NULLT, ridpointers[(int) RID_STATIC], NULLT);
3416 decl_specs = tree_cons (NULLT, type, sc_spec);
3418 decl = start_decl (synth_id_with_class_suffix (name, implementation_context),
3420 end_temporary_allocation ();
3422 initlist = build_tree_list (NULLT, build_int_2 (0, 0));
3423 initlist = tree_cons (NULLT, build_int_2 (size, 0), initlist);
3424 initlist = tree_cons (NULLT, list, initlist);
3426 finish_decl (decl, build_nt (CONSTRUCTOR, NULLT, nreverse (initlist)), NULLT);
3432 generate_dispatch_tables ()
3434 tree initlist, chain, method_list_template;
3435 tree cast, variable_length_type;
3438 if (!objc_method_template)
3439 objc_method_template = build_method_template ();
3443 (build_tree_list (NULLT, xref_tag (RECORD_TYPE,
3444 get_identifier (UTAG_METHOD_LIST))),
3446 variable_length_type = groktypename (cast);
3448 chain = CLASS_CLS_METHODS (implementation_context);
3452 initlist = build_dispatch_table_initializer (chain, &size);
3454 method_list_template = build_method_list_template (objc_method_template,
3457 UOBJC_CLASS_METHODS_decl
3458 = generate_dispatch_table (method_list_template,
3459 ((TREE_CODE (implementation_context)
3460 == CLASS_IMPLEMENTATION_TYPE)
3461 ? "_OBJC_CLASS_METHODS"
3462 : "_OBJC_CATEGORY_CLASS_METHODS"),
3465 TREE_TYPE (UOBJC_CLASS_METHODS_decl) = variable_length_type;
3468 UOBJC_CLASS_METHODS_decl = 0;
3470 chain = CLASS_NST_METHODS (implementation_context);
3474 initlist = build_dispatch_table_initializer (chain, &size);
3476 method_list_template = build_method_list_template (objc_method_template,
3478 if (TREE_CODE (implementation_context) == CLASS_IMPLEMENTATION_TYPE)
3479 UOBJC_INSTANCE_METHODS_decl =
3480 generate_dispatch_table (method_list_template,
3481 "_OBJC_INSTANCE_METHODS",
3484 /* we have a category */
3485 UOBJC_INSTANCE_METHODS_decl =
3486 generate_dispatch_table (method_list_template,
3487 "_OBJC_CATEGORY_INSTANCE_METHODS",
3490 TREE_TYPE (UOBJC_INSTANCE_METHODS_decl) = variable_length_type;
3493 UOBJC_INSTANCE_METHODS_decl = 0;
3497 generate_protocol_list (i_or_p)
3500 static tree cast_type = 0;
3501 tree initlist, decl_specs, sc_spec;
3502 tree refs_decl, expr_decl, lproto, e, plist;
3505 if (TREE_CODE (i_or_p) == CLASS_INTERFACE_TYPE
3506 || TREE_CODE (i_or_p) == CATEGORY_INTERFACE_TYPE)
3507 plist = CLASS_PROTOCOL_LIST (i_or_p);
3508 else if (TREE_CODE (i_or_p) == PROTOCOL_INTERFACE_TYPE)
3509 plist = PROTOCOL_LIST (i_or_p);
3517 (build_tree_list (NULLT,
3518 xref_tag (RECORD_TYPE,
3519 get_identifier (UTAG_PROTOCOL))),
3520 build1 (INDIRECT_REF, NULLT, NULLT)));
3523 for (lproto = plist; lproto; lproto = TREE_CHAIN (lproto))
3524 if (TREE_CODE (TREE_VALUE (lproto)) == PROTOCOL_INTERFACE_TYPE
3525 && PROTOCOL_FORWARD_DECL (TREE_VALUE (lproto)))
3528 /* build initializer */
3529 initlist = tree_cons (NULLT, build_int_2 (0, 0), NULLT);
3531 e = build_int_2 (size, 0);
3532 TREE_TYPE (e) = cast_type;
3533 initlist = tree_cons (NULLT, e, initlist);
3535 for (lproto = plist; lproto; lproto = TREE_CHAIN (lproto))
3537 tree pval = TREE_VALUE (lproto);
3539 if (TREE_CODE (pval) == PROTOCOL_INTERFACE_TYPE
3540 && PROTOCOL_FORWARD_DECL (pval))
3542 e = build_unary_op (ADDR_EXPR, PROTOCOL_FORWARD_DECL (pval), 0);
3543 initlist = tree_cons (NULLT, e, initlist);
3547 /* static struct objc_protocol *refs[n]; */
3549 sc_spec = tree_cons (NULLT, ridpointers[(int) RID_STATIC], NULLT);
3550 decl_specs = tree_cons (NULLT, xref_tag (RECORD_TYPE,
3551 get_identifier (UTAG_PROTOCOL)),
3554 if (TREE_CODE (i_or_p) == PROTOCOL_INTERFACE_TYPE)
3555 expr_decl = build_nt (ARRAY_REF,
3556 synth_id_with_class_suffix ("_OBJC_PROTOCOL_REFS",
3558 build_int_2 (size + 2, 0));
3559 else if (TREE_CODE (i_or_p) == CLASS_INTERFACE_TYPE)
3560 expr_decl = build_nt (ARRAY_REF,
3561 synth_id_with_class_suffix ("_OBJC_CLASS_PROTOCOLS",
3563 build_int_2 (size + 2, 0));
3564 else if (TREE_CODE (i_or_p) == CATEGORY_INTERFACE_TYPE)
3565 expr_decl = build_nt (ARRAY_REF,
3566 synth_id_with_class_suffix ("_OBJC_CATEGORY_PROTOCOLS",
3568 build_int_2 (size + 2, 0));
3570 expr_decl = build1 (INDIRECT_REF, NULLT, expr_decl);
3572 refs_decl = start_decl (expr_decl, decl_specs, 1);
3573 end_temporary_allocation ();
3575 finish_decl (refs_decl, build_nt (CONSTRUCTOR, NULLT,
3576 nreverse (initlist)), NULLT);
3582 build_category_initializer (cat_name, class_name,
3583 instance_methods, class_methods, protocol_list)
3586 tree instance_methods;
3590 tree initlist = NULLT, expr;
3592 initlist = tree_cons (NULLT, cat_name, initlist);
3593 initlist = tree_cons (NULLT, class_name, initlist);
3595 if (!instance_methods)
3596 initlist = tree_cons (NULLT, build_int_2 (0, 0), initlist);
3599 expr = build_unary_op (ADDR_EXPR, instance_methods, 0);
3600 initlist = tree_cons (NULLT, expr, initlist);
3603 initlist = tree_cons (NULLT, build_int_2 (0, 0), initlist);
3606 expr = build_unary_op (ADDR_EXPR, class_methods, 0);
3607 initlist = tree_cons (NULLT, expr, initlist);
3610 /* protocol_list = */
3612 initlist = tree_cons (NULLT, build_int_2 (0, 0), initlist);
3615 static tree cast_type2;
3621 (build_tree_list (NULLT,
3622 xref_tag (RECORD_TYPE,
3623 get_identifier (UTAG_PROTOCOL))),
3624 build1 (INDIRECT_REF, NULLT,
3625 build1 (INDIRECT_REF, NULLT, NULLT))));
3627 expr = build_unary_op (ADDR_EXPR, protocol_list, 0);
3628 TREE_TYPE (expr) = cast_type2;
3629 initlist = tree_cons (NULLT, expr, initlist);
3632 return build_nt (CONSTRUCTOR, NULLT, nreverse (initlist));
3635 /* struct objc_class {
3636 struct objc_class *isa;
3637 struct objc_class *super_class;
3642 struct objc_ivar_list *ivars;
3643 struct objc_method_list *methods;
3644 if (flag_next_runtime)
3645 struct objc_cache *cache;
3647 struct sarray *dtable;
3648 struct objc_class *subclass_list;
3649 struct objc_class *sibling_class;
3651 struct objc_protocol_list *protocols;
3655 build_shared_structure_initializer (isa, super, name, size, status,
3656 dispatch_table, ivar_list, protocol_list)
3662 tree dispatch_table;
3666 tree initlist = NULLT, expr;
3669 initlist = tree_cons (NULLT, isa, initlist);
3672 initlist = tree_cons (NULLT, super, initlist);
3675 initlist = tree_cons (NULLT, name, initlist);
3678 initlist = tree_cons (NULLT, build_int_2 (0, 0), initlist);
3681 initlist = tree_cons (NULLT, build_int_2 (status, 0), initlist);
3683 /* instance_size = */
3684 initlist = tree_cons (NULLT, size, initlist);
3686 /* objc_ivar_list = */
3688 initlist = tree_cons (NULLT, build_int_2 (0, 0), initlist);
3691 expr = build_unary_op (ADDR_EXPR, ivar_list, 0);
3692 initlist = tree_cons (NULLT, expr, initlist);
3695 /* objc_method_list = */
3696 if (!dispatch_table)
3697 initlist = tree_cons (NULLT, build_int_2 (0, 0), initlist);
3700 expr = build_unary_op (ADDR_EXPR, dispatch_table, 0);
3701 initlist = tree_cons (NULLT, expr, initlist);
3704 if (flag_next_runtime)
3705 /* method_cache = */
3706 initlist = tree_cons (NULLT, build_int_2 (0, 0), initlist);
3710 initlist = tree_cons (NULLT, build_int_2 (0, 0), initlist);
3712 /* subclass_list = */
3713 initlist = tree_cons (NULLT, build_int_2 (0, 0), initlist);
3715 /* sibling_class = */
3716 initlist = tree_cons (NULLT, build_int_2 (0, 0), initlist);
3719 /* protocol_list = */
3720 if (! protocol_list)
3721 initlist = tree_cons (NULLT, build_int_2 (0, 0), initlist);
3724 static tree cast_type2;
3730 (build_tree_list (NULLT,
3731 xref_tag (RECORD_TYPE,
3732 get_identifier (UTAG_PROTOCOL))),
3733 build1 (INDIRECT_REF, NULLT,
3734 build1 (INDIRECT_REF, NULLT, NULLT))));
3736 expr = build_unary_op (ADDR_EXPR, protocol_list, 0);
3737 TREE_TYPE (expr) = cast_type2;
3738 initlist = tree_cons (NULLT, expr, initlist);
3741 return build_nt (CONSTRUCTOR, NULLT, nreverse (initlist));
3744 /* static struct objc_category _OBJC_CATEGORY_<name> = { ... }; */
3746 generate_category (cat)
3749 tree sc_spec, decl_specs, decl;
3750 tree initlist, cat_name_expr, class_name_expr;
3751 tree protocol_decl, category;
3753 add_class_reference (CLASS_NAME (cat));
3754 cat_name_expr = add_objc_string (CLASS_SUPER_NAME (cat), class_names);
3756 class_name_expr = add_objc_string (CLASS_NAME (cat), class_names);
3758 category = CLASS_CATEGORY_LIST (implementation_template);
3760 /* find the category interface from the class it is associated with */
3763 if (CLASS_SUPER_NAME (cat) == CLASS_SUPER_NAME (category))
3765 category = CLASS_CATEGORY_LIST (category);
3768 if (category && CLASS_PROTOCOL_LIST (category))
3770 generate_protocol_references (CLASS_PROTOCOL_LIST (category));
3771 protocol_decl = generate_protocol_list (category);
3776 sc_spec = tree_cons (NULLT, ridpointers[(int) RID_STATIC], NULLT);
3777 decl_specs = tree_cons (NULLT, objc_category_template, sc_spec);
3779 decl = start_decl (synth_id_with_class_suffix ("_OBJC_CATEGORY",
3780 implementation_context),
3782 end_temporary_allocation ();
3784 initlist = build_category_initializer (cat_name_expr, class_name_expr,
3785 UOBJC_INSTANCE_METHODS_decl,
3786 UOBJC_CLASS_METHODS_decl,
3789 TREE_USED (decl) = 1;
3790 finish_decl (decl, initlist, NULLT);
3793 /* static struct objc_class _OBJC_METACLASS_Foo={ ... };
3794 static struct objc_class _OBJC_CLASS_Foo={ ... }; */
3797 generate_shared_structures ()
3799 tree sc_spec, decl_specs, decl;
3800 tree name_expr, super_expr, root_expr;
3801 tree my_root_id = NULLT, my_super_id = NULLT;
3802 tree cast_type, initlist, protocol_decl;
3804 my_super_id = CLASS_SUPER_NAME (implementation_template);
3807 add_class_reference (my_super_id);
3809 /* Compute "my_root_id" - this is required for code generation.
3810 the "isa" for all meta class structures points to the root of
3811 the inheritance hierarchy (e.g. "__Object")... */
3812 my_root_id = my_super_id;
3815 tree my_root_int = lookup_interface (my_root_id);
3817 if (my_root_int && CLASS_SUPER_NAME (my_root_int))
3818 my_root_id = CLASS_SUPER_NAME (my_root_int);
3824 else /* no super class */
3826 my_root_id = CLASS_NAME (implementation_template);
3830 = groktypename (build_tree_list (build_tree_list (NULLT,
3831 objc_class_template),
3832 build1 (INDIRECT_REF, NULLT, NULLT)));
3834 name_expr = add_objc_string (CLASS_NAME (implementation_template),
3837 /* install class `isa' and `super' pointers at runtime */
3840 super_expr = add_objc_string (my_super_id, class_names);
3841 super_expr = build_c_cast (cast_type, super_expr); /* cast! */
3844 super_expr = build_int_2 (0, 0);
3846 root_expr = add_objc_string (my_root_id, class_names);
3847 root_expr = build_c_cast (cast_type, root_expr); /* cast! */
3849 if (CLASS_PROTOCOL_LIST (implementation_template))
3851 generate_protocol_references (CLASS_PROTOCOL_LIST (implementation_template));
3852 protocol_decl = generate_protocol_list (implementation_template);
3857 /* static struct objc_class _OBJC_METACLASS_Foo = { ... }; */
3859 sc_spec = build_tree_list (NULLT, ridpointers[(int) RID_STATIC]);
3860 decl_specs = tree_cons (NULLT, objc_class_template, sc_spec);
3862 decl = start_decl (DECL_NAME (UOBJC_METACLASS_decl), decl_specs, 1);
3863 end_temporary_allocation ();
3866 = build_shared_structure_initializer
3867 (root_expr, super_expr, name_expr,
3868 build_int_2 ((TREE_INT_CST_LOW (TYPE_SIZE (objc_class_template))
3872 UOBJC_CLASS_METHODS_decl,
3873 UOBJC_CLASS_VARIABLES_decl,
3876 finish_decl (decl, initlist, NULLT);
3878 /* static struct objc_class _OBJC_CLASS_Foo={ ... }; */
3880 decl = start_decl (DECL_NAME (UOBJC_CLASS_decl), decl_specs, 1);
3881 end_temporary_allocation ();
3884 = build_shared_structure_initializer
3885 (build_unary_op (ADDR_EXPR, UOBJC_METACLASS_decl, 0),
3886 super_expr, name_expr,
3887 build_int_2 ((TREE_INT_CST_LOW (TYPE_SIZE (CLASS_STATIC_TEMPLATE (implementation_template)))
3891 UOBJC_INSTANCE_METHODS_decl,
3892 UOBJC_INSTANCE_VARIABLES_decl,
3895 finish_decl (decl, initlist, NULLT);
3899 synth_id_with_class_suffix (preamble, ctxt)
3904 if (TREE_CODE (ctxt) == CLASS_IMPLEMENTATION_TYPE
3905 || TREE_CODE (ctxt) == CLASS_INTERFACE_TYPE)
3908 = IDENTIFIER_POINTER (CLASS_NAME (implementation_context));
3909 string = (char *) alloca (strlen (preamble) + strlen (class_name) + 3);
3910 sprintf (string, "%s_%s", preamble,
3911 IDENTIFIER_POINTER (CLASS_NAME (ctxt)));
3913 else if (TREE_CODE (ctxt) == CATEGORY_IMPLEMENTATION_TYPE
3914 || TREE_CODE (ctxt) == CATEGORY_INTERFACE_TYPE)
3916 /* we have a category */
3918 = IDENTIFIER_POINTER (CLASS_NAME (implementation_context));
3919 char *class_super_name
3920 = IDENTIFIER_POINTER (CLASS_SUPER_NAME (implementation_context));
3921 string = (char *) alloca (strlen (preamble)
3922 + strlen (class_name)
3923 + strlen (class_super_name)
3925 sprintf (string, "%s_%s_%s", preamble, class_name, class_super_name);
3927 else if (TREE_CODE (ctxt) == PROTOCOL_INTERFACE_TYPE)
3929 char *protocol_name = IDENTIFIER_POINTER (PROTOCOL_NAME (ctxt));
3930 string = (char *) alloca (strlen (preamble) + strlen (protocol_name) + 3);
3931 sprintf (string, "%s_%s", preamble, protocol_name);
3933 return get_identifier (string);
3937 is_objc_type_qualifier (node)
3940 return (TREE_CODE (node) == IDENTIFIER_NODE
3941 && (node == ridpointers [(int) RID_CONST]
3942 || node == ridpointers [(int) RID_VOLATILE]
3943 || node == ridpointers [(int) RID_IN]
3944 || node == ridpointers [(int) RID_OUT]
3945 || node == ridpointers [(int) RID_INOUT]
3946 || node == ridpointers [(int) RID_BYCOPY]
3947 || node == ridpointers [(int) RID_ONEWAY]));
3950 /* If type is empty or only type qualifiers are present, add default
3951 type of id (otherwise grokdeclarator will default to int). */
3954 adjust_type_for_id_default (type)
3957 tree declspecs, chain;
3960 return build_tree_list (build_tree_list (NULLT, objc_object_reference),
3961 build1 (INDIRECT_REF, NULLT, NULLT));
3963 declspecs = TREE_PURPOSE (type);
3965 /* Determine if a typespec is present. */
3966 for (chain = declspecs;
3968 chain = TREE_CHAIN (chain))
3970 if (!is_objc_type_qualifier (TREE_VALUE (chain)))
3974 return build_tree_list (tree_cons (NULLT, objc_object_reference, declspecs),
3975 build1 (INDIRECT_REF, NULLT, NULLT));
3980 selector ':' '(' typename ')' identifier
3983 transform an Objective-C keyword argument into
3984 the C equivalent parameter declarator.
3986 in: key_name, an "identifier_node" (optional).
3987 arg_type, a "tree_list" (optional).
3988 arg_name, an "identifier_node".
3990 note: it would be really nice to strongly type the preceding
3991 arguments in the function prototype; however, then i
3992 could not use the "accessor" macros defined in "tree.h".
3994 out: an instance of "keyword_decl". */
3997 build_keyword_decl (key_name, arg_type, arg_name)
4004 /* if no type is specified, default to "id" */
4005 arg_type = adjust_type_for_id_default (arg_type);
4007 keyword_decl = make_node (KEYWORD_DECL);
4009 TREE_TYPE (keyword_decl) = arg_type;
4010 KEYWORD_ARG_NAME (keyword_decl) = arg_name;
4011 KEYWORD_KEY_NAME (keyword_decl) = key_name;
4013 return keyword_decl;
4016 /* Given a chain of keyword_decl's, synthesize the full keyword selector. */
4018 build_keyword_selector (selector)
4022 tree key_chain, key_name;
4025 for (key_chain = selector; key_chain; key_chain = TREE_CHAIN (key_chain))
4027 if (TREE_CODE (selector) == KEYWORD_DECL)
4028 key_name = KEYWORD_KEY_NAME (key_chain);
4029 else if (TREE_CODE (selector) == TREE_LIST)
4030 key_name = TREE_PURPOSE (key_chain);
4033 len += IDENTIFIER_LENGTH (key_name) + 1;
4034 else /* just a ':' arg */
4037 buf = (char *)alloca (len + 1);
4038 bzero (buf, len + 1);
4040 for (key_chain = selector; key_chain; key_chain = TREE_CHAIN (key_chain))
4042 if (TREE_CODE (selector) == KEYWORD_DECL)
4043 key_name = KEYWORD_KEY_NAME (key_chain);
4044 else if (TREE_CODE (selector) == TREE_LIST)
4045 key_name = TREE_PURPOSE (key_chain);
4048 strcat (buf, IDENTIFIER_POINTER (key_name));
4051 return get_identifier (buf);
4054 /* used for declarations and definitions */
4057 build_method_decl (code, ret_type, selector, add_args)
4058 enum tree_code code;
4065 /* if no type is specified, default to "id" */
4066 ret_type = adjust_type_for_id_default (ret_type);
4068 method_decl = make_node (code);
4069 TREE_TYPE (method_decl) = ret_type;
4071 /* If we have a keyword selector, create an identifier_node that
4072 represents the full selector name (`:' included)... */
4073 if (TREE_CODE (selector) == KEYWORD_DECL)
4075 METHOD_SEL_NAME (method_decl) = build_keyword_selector (selector);
4076 METHOD_SEL_ARGS (method_decl) = selector;
4077 METHOD_ADD_ARGS (method_decl) = add_args;
4081 METHOD_SEL_NAME (method_decl) = selector;
4082 METHOD_SEL_ARGS (method_decl) = NULLT;
4083 METHOD_ADD_ARGS (method_decl) = NULLT;
4089 #define METHOD_DEF 0
4090 #define METHOD_REF 1
4092 /* Used by `build_message_expr' and `comp_method_types'. Return an
4093 argument list for method METH. CONTEXT is either METHOD_DEF or
4094 METHOD_REF, saying whether we are trying to define a method or call
4095 one. SUPERFLAG says this is for a send to super; this makes a
4096 difference for the NeXT calling sequence in which the lookup and
4097 the method call are done together. */
4100 get_arg_type_list (meth, context, superflag)
4108 if (flag_next_runtime && superflag)
4110 arglist = build_tree_list (NULLT, super_type);
4114 if (context == METHOD_DEF)
4115 arglist = build_tree_list (NULLT, TREE_TYPE (self_decl));
4117 arglist = build_tree_list (NULLT, id_type);
4120 /* selector type - will eventually change to `int' */
4121 chainon (arglist, build_tree_list (NULLT, selector_type));
4123 /* build a list of argument types */
4124 for (akey = METHOD_SEL_ARGS (meth); akey; akey = TREE_CHAIN (akey))
4126 tree arg_decl = groktypename_in_parm_context (TREE_TYPE (akey));
4127 chainon (arglist, build_tree_list (NULLT, TREE_TYPE (arg_decl)));
4130 if (METHOD_ADD_ARGS (meth) == (tree)1)
4131 /* We have a `, ...' immediately following the selector,
4132 finalize the arglist...simulate get_parm_info (0). */
4134 else if (METHOD_ADD_ARGS (meth))
4136 /* we have a variable length selector */
4137 tree add_arg_list = TREE_CHAIN (METHOD_ADD_ARGS (meth));
4138 chainon (arglist, add_arg_list);
4141 /* finalize the arglist...simulate get_parm_info (1) */
4142 chainon (arglist, build_tree_list (NULLT, void_type_node));
4148 check_duplicates (hsh)
4159 /* we have two methods with the same name and different types */
4161 char type = (TREE_CODE (meth) == INSTANCE_METHOD_DECL) ? '-' : '+';
4163 warning ("multiple declarations for method `%s'",
4164 IDENTIFIER_POINTER (METHOD_SEL_NAME (meth)));
4166 warn_with_method ("using", type, meth);
4167 for (loop = hsh->list; loop; loop = loop->next)
4168 warn_with_method ("also found", type, loop->value);
4175 receiver_is_class_object (receiver)
4178 if (flag_next_runtime)
4181 if (TREE_CODE (receiver) == VAR_DECL
4182 && TREE_TYPE (receiver) == objc_class_type)
4183 /* Look up the identifier corresponding to this string decl. */
4184 for (chain = class_names_chain; chain; chain = TREE_CHAIN (chain))
4185 if (TREE_PURPOSE (chain) == receiver)
4186 return TREE_VALUE (chain);
4190 /* The receiver is a function call that returns an id...
4191 ...check if it is a call to objc_getClass, if so, give it
4192 special treatment. */
4195 if ((exp = TREE_OPERAND (receiver, 0))
4196 && TREE_CODE (exp) == ADDR_EXPR
4197 && (exp = TREE_OPERAND (exp, 0))
4198 && TREE_CODE (exp) == FUNCTION_DECL
4199 && exp == objc_get_class_decl
4200 /* we have a call to objc_getClass! */
4201 && (arg = TREE_OPERAND (receiver, 1))
4202 && TREE_CODE (arg) == TREE_LIST
4203 && (arg = TREE_VALUE (arg))
4204 && TREE_CODE (arg) == NOP_EXPR
4205 && (arg = TREE_OPERAND (arg, 0))
4206 && TREE_CODE (arg) == ADDR_EXPR
4207 && (arg = TREE_OPERAND (arg, 0))
4208 && TREE_CODE (arg) == STRING_CST)
4209 /* finally, we have the class name */
4210 return get_identifier (TREE_STRING_POINTER (arg));
4215 /* If we are currently building a message expr, this holds
4216 the identifier of the selector of the message. This is
4217 used when printing warnings about argument mismatches. */
4219 static tree building_objc_message_expr = 0;
4222 maybe_building_objc_message_expr ()
4224 return building_objc_message_expr;
4227 /* Construct an expression for sending a message.
4228 MESS has the object to send to in TREE_PURPOSE
4229 and the argument list (including selector) in TREE_VALUE.
4231 (*(<abstract_decl>(*)())_msg)(receiver, selTransTbl[n], ...);
4232 (*(<abstract_decl>(*)())_msgSuper)(receiver, selTransTbl[n], ...); */
4235 build_message_expr (mess)
4238 tree receiver = TREE_PURPOSE (mess);
4239 tree selector, self_object;
4240 tree rtype, sel_name;
4241 tree args = TREE_VALUE (mess);
4242 tree method_params = NULLT;
4243 tree method_prototype = NULLT;
4245 int statically_typed = 0, statically_allocated = 0;
4246 tree class_ident = 0;
4248 /* 1 if this is sending to the superclass. */
4251 if (!doing_objc_thang)
4254 if (TREE_CODE (receiver) == ERROR_MARK)
4255 return error_mark_node;
4257 /* determine receiver type */
4258 rtype = TREE_TYPE (receiver);
4259 super = (TREE_TYPE (receiver) == super_type);
4263 if (TREE_STATIC_TEMPLATE (rtype))
4264 statically_allocated = 1;
4265 else if (TREE_CODE (rtype) == POINTER_TYPE
4266 && TREE_STATIC_TEMPLATE (TREE_TYPE (rtype)))
4267 statically_typed = 1;
4269 else if ((flag_next_runtime
4270 || (TREE_CODE (receiver) == CALL_EXPR
4271 && TYPE_MAIN_VARIANT (rtype) == TYPE_MAIN_VARIANT (id_type)))
4272 && (class_ident = receiver_is_class_object (receiver)))
4274 else if (TYPE_MAIN_VARIANT (rtype) != TYPE_MAIN_VARIANT (id_type)
4275 && TYPE_MAIN_VARIANT (rtype) != TYPE_MAIN_VARIANT (objc_class_type))
4277 bzero (errbuf, BUFSIZE);
4278 warning ("invalid receiver type `%s'",
4279 gen_declaration (rtype, errbuf));
4281 if (statically_allocated)
4282 receiver = build_unary_op (ADDR_EXPR, receiver, 0);
4284 /* Don't evaluate the receiver twice. */
4285 receiver = save_expr (receiver);
4286 self_object = receiver;
4289 /* If sending to `super', use current self as the object. */
4290 self_object = self_decl;
4292 /* Obtain the full selector name. */
4294 if (TREE_CODE (args) == IDENTIFIER_NODE)
4295 /* a unary selector */
4297 else if (TREE_CODE (args) == TREE_LIST)
4298 sel_name = build_keyword_selector (args);
4300 /* Build the parameters list for looking up the method.
4301 These are the object itself and the selector. */
4303 selector = build_selector_reference (sel_name);
4305 /* Build the parameter list to give to the method. */
4307 method_params = NULLT;
4308 if (TREE_CODE (args) == TREE_LIST)
4310 tree chain = args, prev = NULLT;
4312 /* We have a keyword selector--check for comma expressions. */
4315 tree element = TREE_VALUE (chain);
4317 /* We have a comma expression, must collapse... */
4318 if (TREE_CODE (element) == TREE_LIST)
4321 TREE_CHAIN (prev) = element;
4326 chain = TREE_CHAIN (chain);
4328 method_params = args;
4331 /* Determine operation return type. */
4334 && TYPE_MAIN_VARIANT (rtype) == TYPE_MAIN_VARIANT (super_type))
4338 if (CLASS_SUPER_NAME (implementation_template))
4340 iface = lookup_interface (CLASS_SUPER_NAME (implementation_template));
4342 if (TREE_CODE (method_context) == INSTANCE_METHOD_DECL)
4343 method_prototype = lookup_instance_method_static (iface, sel_name);
4345 method_prototype = lookup_class_method_static (iface, sel_name);
4347 if (iface && !method_prototype)
4348 warning ("`%s' does not respond to `%s'",
4349 IDENTIFIER_POINTER (CLASS_SUPER_NAME (implementation_template)),
4350 IDENTIFIER_POINTER (sel_name));
4354 error ("no super class declared in interface for `%s'",
4355 IDENTIFIER_POINTER (CLASS_NAME (implementation_template)));
4356 return error_mark_node;
4360 else if (statically_allocated)
4362 tree ctype = TREE_TYPE (rtype);
4363 tree iface = lookup_interface (TYPE_NAME (rtype));
4366 method_prototype = lookup_instance_method_static (iface, sel_name);
4369 if (! method_prototype && TYPE_PROTOCOL_LIST (ctype))
4371 = lookup_method_in_protocol_list (TYPE_PROTOCOL_LIST (ctype),
4374 if (!method_prototype)
4375 warning ("`%s' does not respond to `%s'",
4376 IDENTIFIER_POINTER (TYPE_NAME (rtype)),
4377 IDENTIFIER_POINTER (sel_name));
4379 else if (statically_typed)
4381 tree ctype = TREE_TYPE (rtype);
4383 /* `self' is now statically_typed...all methods should be visible
4384 within the context of the implementation... */
4385 if (implementation_context
4386 && CLASS_NAME (implementation_context) == TYPE_NAME (ctype))
4388 method_prototype = lookup_instance_method_static (implementation_template, sel_name);
4391 if (! method_prototype && TYPE_PROTOCOL_LIST (ctype))
4393 = lookup_method_in_protocol_list (TYPE_PROTOCOL_LIST (ctype),
4396 if (! method_prototype
4397 && implementation_template != implementation_context)
4398 /* the method is not published in the interface...check locally */
4400 = lookup_method (CLASS_NST_METHODS (implementation_context),
4407 if ((iface = lookup_interface (TYPE_NAME (ctype))))
4408 method_prototype = lookup_instance_method_static (iface, sel_name);
4410 if (! method_prototype)
4412 tree protocol_list = TYPE_PROTOCOL_LIST (ctype);
4415 = lookup_method_in_protocol_list (protocol_list, sel_name, 0);
4419 if (!method_prototype)
4420 warning ("`%s' does not respond to `%s'",
4421 IDENTIFIER_POINTER (TYPE_NAME (ctype)),
4422 IDENTIFIER_POINTER (sel_name));
4424 else if (class_ident)
4426 if (implementation_context
4427 && CLASS_NAME (implementation_context) == class_ident)
4430 = lookup_class_method_static (implementation_template, sel_name);
4432 if (!method_prototype
4433 && implementation_template != implementation_context)
4434 /* the method is not published in the interface...check locally */
4436 = lookup_method (CLASS_CLS_METHODS (implementation_context),
4443 if ((iface = lookup_interface (class_ident)))
4444 method_prototype = lookup_class_method_static (iface, sel_name);
4447 if (!method_prototype)
4449 warning ("cannot find class (factory) method.");
4450 warning ("return type for `%s' defaults to id",
4451 IDENTIFIER_POINTER (sel_name));
4454 else if (TYPE_MAIN_VARIANT (rtype) == TYPE_MAIN_VARIANT (id_type)
4455 && TYPE_PROTOCOL_LIST (rtype))
4457 /* An anonymous object that has been qualified with a protocol. */
4459 tree protocol_list = TYPE_PROTOCOL_LIST (rtype);
4461 method_prototype = lookup_method_in_protocol_list (protocol_list,
4464 if (!method_prototype)
4468 warning ("method `%s' not implemented by protocol.",
4469 IDENTIFIER_POINTER (sel_name));
4471 /* try and find the method signiture in the global pools! */
4473 if (!(hsh = hash_lookup (nst_method_hash_list, sel_name)))
4474 hsh = hash_lookup (cls_method_hash_list, sel_name);
4476 if (!(method_prototype = check_duplicates (hsh)))
4477 warning ("return type defaults to id");
4484 /* we think we have an instance...loophole: extern id Object; */
4485 hsh = hash_lookup (nst_method_hash_list, sel_name);
4487 /* for various loopholes...like sending messages to self in a
4488 factory context... */
4489 hsh = hash_lookup (cls_method_hash_list, sel_name);
4491 method_prototype = check_duplicates (hsh);
4492 if (!method_prototype)
4494 warning ("cannot find method.");
4495 warning ("return type for `%s' defaults to id",
4496 IDENTIFIER_POINTER (sel_name));
4500 /* Save the selector name for printing error messages. */
4501 building_objc_message_expr = sel_name;
4503 retval = build_objc_method_call (super, method_prototype,
4504 receiver, self_object,
4505 selector, method_params);
4507 building_objc_message_expr = 0;
4512 /* Build a tree expression to send OBJECT the operation SELECTOR,
4513 looking up the method on object LOOKUP_OBJECT (often same as OBJECT),
4514 assuming the method has prototype METHOD_PROTOTYPE.
4515 (That is an INSTANCE_METHOD_DECL or CLASS_METHOD_DECL.)
4516 Use METHOD_PARAMS as list of args to pass to the method.
4517 If SUPER_FLAG is nonzero, we look up the superclass's method. */
4520 build_objc_method_call (super_flag, method_prototype, lookup_object, object,
4521 selector, method_params)
4523 tree method_prototype, lookup_object, object, selector, method_params;
4525 tree sender = (super_flag ? umsg_super_decl : umsg_decl);
4526 tree rcv_p = (super_flag
4527 ? build_pointer_type (xref_tag (RECORD_TYPE,
4528 get_identifier (TAG_SUPER)))
4531 if (flag_next_runtime)
4533 if (! method_prototype)
4535 method_params = tree_cons (NULLT, lookup_object,
4536 tree_cons (NULLT, selector,
4538 assemble_external (sender);
4539 return build_function_call (sender, method_params);
4543 /* This is a real kludge, but it is used only for the Next.
4544 Clobber the data type of SENDER temporarily to accept
4545 all the arguments for this operation, and to return
4546 whatever this operation returns. */
4547 tree arglist = NULLT;
4550 /* Save the proper contents of SENDER's data type. */
4551 tree savarg = TYPE_ARG_TYPES (TREE_TYPE (sender));
4552 tree savret = TREE_TYPE (TREE_TYPE (sender));
4554 /* Install this method's argument types. */
4555 arglist = get_arg_type_list (method_prototype, METHOD_REF,
4557 TYPE_ARG_TYPES (TREE_TYPE (sender)) = arglist;
4559 /* Install this method's return type. */
4560 TREE_TYPE (TREE_TYPE (sender))
4561 = groktypename (TREE_TYPE (method_prototype));
4563 /* Call SENDER with all the parameters. This will do type
4564 checking using the arg types for this method. */
4565 method_params = tree_cons (NULLT, lookup_object,
4566 tree_cons (NULLT, selector,
4568 assemble_external (sender);
4569 retval = build_function_call (sender, method_params);
4571 /* Restore SENDER's return/argument types. */
4572 TYPE_ARG_TYPES (TREE_TYPE (sender)) = savarg;
4573 TREE_TYPE (TREE_TYPE (sender)) = savret;
4579 /* This is the portable way.
4580 First call the lookup function to get a pointer to the method,
4581 then cast the pointer, then call it with the method arguments. */
4584 /* Avoid trouble since we may evaluate each of these twice. */
4585 object = save_expr (object);
4586 selector = save_expr (selector);
4588 lookup_object = build_c_cast (rcv_p, lookup_object); /* cast! */
4590 assemble_external (sender);
4592 = build_function_call (sender,
4593 tree_cons (NULLT, lookup_object,
4594 tree_cons (NULLT, selector, NULLT)));
4596 /* If we have a method prototype, construct the data type this
4597 method needs, and cast what we got from SENDER into a pointer
4599 if (method_prototype)
4601 tree arglist = get_arg_type_list (method_prototype, METHOD_REF,
4603 tree valtype = groktypename (TREE_TYPE (method_prototype));
4604 tree fake_function_type = build_function_type (valtype, arglist);
4605 TREE_TYPE (method) = build_pointer_type (fake_function_type);
4609 = build_pointer_type (build_function_type (ptr_type_node, NULLT));
4611 /* Pass the object to the method. */
4612 assemble_external (method);
4613 return build_function_call (method,
4614 tree_cons (NULLT, object,
4615 tree_cons (NULLT, selector,
4621 build_protocol_reference (p)
4624 tree decl, ident, ptype;
4625 struct obstack *save_current_obstack = current_obstack;
4626 struct obstack *save_rtl_obstack = rtl_obstack;
4628 rtl_obstack = current_obstack = &permanent_obstack;
4630 /* extern struct objc_protocol _OBJC_PROTOCOL_<mumble>; */
4632 ident = synth_id_with_class_suffix ("_OBJC_PROTOCOL", p);
4634 = groktypename (build_tree_list (build_tree_list (NULLT,
4635 objc_protocol_template),
4638 if (IDENTIFIER_GLOBAL_VALUE (ident))
4639 decl = IDENTIFIER_GLOBAL_VALUE (ident); /* Set by pushdecl. */
4642 decl = build_decl (VAR_DECL, ident, ptype);
4643 DECL_EXTERNAL (decl) = 1;
4644 TREE_PUBLIC (decl) = 1;
4645 TREE_USED (decl) = 1;
4647 /* usually called from `rest_of_decl_compilation' */
4648 make_decl_rtl (decl, 0, 1);
4649 /* our `extended/custom' pushdecl in c-decl.c */
4650 pushdecl_top_level (decl);
4652 current_obstack = save_current_obstack;
4653 rtl_obstack = save_rtl_obstack;
4655 PROTOCOL_FORWARD_DECL (p) = decl;
4659 build_protocol_expr (protoname)
4665 if (!doing_objc_thang)
4668 p = lookup_protocol (protoname);
4672 error ("Cannot find protocol declaration for `%s'",
4673 IDENTIFIER_POINTER (protoname));
4674 return error_mark_node;
4677 if (!PROTOCOL_FORWARD_DECL (p))
4678 build_protocol_reference (p);
4680 expr = build_unary_op (ADDR_EXPR, PROTOCOL_FORWARD_DECL (p), 0);
4682 TREE_TYPE (expr) = protocol_type;
4688 build_selector_expr (selnamelist)
4693 if (!doing_objc_thang)
4696 /* obtain the full selector name */
4697 if (TREE_CODE (selnamelist) == IDENTIFIER_NODE)
4698 /* a unary selector */
4699 selname = selnamelist;
4700 else if (TREE_CODE (selnamelist) == TREE_LIST)
4701 selname = build_keyword_selector (selnamelist);
4703 return build_selector_reference (selname);
4707 build_encode_expr (type)
4713 if (!doing_objc_thang)
4716 encode_type (type, obstack_object_size (&util_obstack),
4717 OBJC_ENCODE_INLINE_DEFS);
4718 obstack_1grow (&util_obstack, 0); /* null terminate string */
4719 string = obstack_finish (&util_obstack);
4721 /* synthesize a string that represents the encoded struct/union */
4722 result = my_build_string (strlen (string) + 1, string);
4723 obstack_free (&util_obstack, util_firstobj);
4728 build_ivar_reference (id)
4731 if (TREE_CODE (method_context) == CLASS_METHOD_DECL)
4732 TREE_TYPE (self_decl) = instance_type; /* cast */
4734 return build_component_ref (build_indirect_ref (self_decl, "->"), id);
4737 #define HASH_ALLOC_LIST_SIZE 170
4738 #define ATTR_ALLOC_LIST_SIZE 170
4739 #define SIZEHASHTABLE 257
4740 #define HASHFUNCTION(key) ((int)key & 0x7fffffff) /* make positive */
4745 nst_method_hash_list = (hash *)xmalloc (SIZEHASHTABLE * sizeof (hash));
4746 cls_method_hash_list = (hash *)xmalloc (SIZEHASHTABLE * sizeof (hash));
4748 if (!nst_method_hash_list || !cls_method_hash_list)
4749 perror ("unable to allocate space in objc-tree.c");
4754 for (i = 0; i < SIZEHASHTABLE; i++)
4756 nst_method_hash_list[i] = 0;
4757 cls_method_hash_list[i] = 0;
4763 hash_enter (hashlist, method)
4767 static hash hash_alloc_list = 0;
4768 static int hash_alloc_index = 0;
4770 int slot = HASHFUNCTION (METHOD_SEL_NAME (method)) % SIZEHASHTABLE;
4772 if (! hash_alloc_list || hash_alloc_index >= HASH_ALLOC_LIST_SIZE)
4774 hash_alloc_index = 0;
4775 hash_alloc_list = (hash) xmalloc (sizeof (struct hashed_entry)
4776 * HASH_ALLOC_LIST_SIZE);
4777 if (! hash_alloc_list)
4778 perror ("unable to allocate in objc-tree.c");
4780 obj = &hash_alloc_list[hash_alloc_index++];
4782 obj->next = hashlist[slot];
4785 hashlist[slot] = obj; /* append to front */
4789 hash_lookup (hashlist, sel_name)
4795 target = hashlist[HASHFUNCTION (sel_name) % SIZEHASHTABLE];
4799 if (sel_name == METHOD_SEL_NAME (target->key))
4802 target = target->next;
4808 hash_add_attr (entry, value)
4812 static attr attr_alloc_list = 0;
4813 static int attr_alloc_index = 0;
4816 if (! attr_alloc_list || attr_alloc_index >= ATTR_ALLOC_LIST_SIZE)
4818 attr_alloc_index = 0;
4819 attr_alloc_list = (attr) xmalloc (sizeof (struct hashed_attribute)
4820 * ATTR_ALLOC_LIST_SIZE);
4821 if (! attr_alloc_list)
4822 perror ("unable to allocate in objc-tree.c");
4824 obj = &attr_alloc_list[attr_alloc_index++];
4825 obj->next = entry->list;
4828 entry->list = obj; /* append to front */
4832 lookup_method (mchain, method)
4838 if (TREE_CODE (method) == IDENTIFIER_NODE)
4841 key = METHOD_SEL_NAME (method);
4845 if (METHOD_SEL_NAME (mchain) == key)
4847 mchain = TREE_CHAIN (mchain);
4853 lookup_instance_method_static (interface, ident)
4857 tree inter = interface;
4858 tree chain = CLASS_NST_METHODS (inter);
4863 if ((meth = lookup_method (chain, ident)))
4866 if (CLASS_CATEGORY_LIST (inter))
4868 tree category = CLASS_CATEGORY_LIST (inter);
4869 chain = CLASS_NST_METHODS (category);
4873 if ((meth = lookup_method (chain, ident)))
4877 /* Check for instance methods in protocols in categories. */
4878 if (CLASS_PROTOCOL_LIST (category))
4880 if ((meth = (lookup_method_in_protocol_list
4881 (CLASS_PROTOCOL_LIST (category), ident, 0))))
4885 if ((category = CLASS_CATEGORY_LIST (category)))
4886 chain = CLASS_NST_METHODS (category);
4891 if (CLASS_PROTOCOL_LIST (inter))
4893 if ((meth = (lookup_method_in_protocol_list
4894 (CLASS_PROTOCOL_LIST (inter), ident, 0))))
4898 if ((inter = lookup_interface (CLASS_SUPER_NAME (inter))))
4899 chain = CLASS_NST_METHODS (inter);
4907 lookup_class_method_static (interface, ident)
4911 tree inter = interface;
4912 tree chain = CLASS_CLS_METHODS (inter);
4914 tree root_inter = NULLT;
4918 if ((meth = lookup_method (chain, ident)))
4921 if (CLASS_CATEGORY_LIST (inter))
4923 tree category = CLASS_CATEGORY_LIST (inter);
4924 chain = CLASS_CLS_METHODS (category);
4928 if ((meth = lookup_method (chain, ident)))
4932 /* Check for class methods in protocols in categories. */
4933 if (CLASS_PROTOCOL_LIST (category))
4935 if ((meth = (lookup_method_in_protocol_list
4936 (CLASS_PROTOCOL_LIST (category), ident, 1))))
4940 if ((category = CLASS_CATEGORY_LIST (category)))
4941 chain = CLASS_CLS_METHODS (category);
4947 /* Check for class methods in protocols. */
4948 if (CLASS_PROTOCOL_LIST (inter))
4950 if ((meth = (lookup_method_in_protocol_list
4951 (CLASS_PROTOCOL_LIST (inter), ident, 1))))
4956 if ((inter = lookup_interface (CLASS_SUPER_NAME (inter))))
4957 chain = CLASS_CLS_METHODS (inter);
4962 /* Simulate wrap around. */
4963 return lookup_instance_method_static (root_inter, ident);
4967 add_class_method (class, method)
4974 /* We will have allocated the method parameter declarations on the
4975 maybepermanent_obstack. Need to make sure they stick around! */
4978 if (!(mth = lookup_method (CLASS_CLS_METHODS (class), method)))
4980 /* put method on list in reverse order */
4981 TREE_CHAIN (method) = CLASS_CLS_METHODS (class);
4982 CLASS_CLS_METHODS (class) = method;
4986 if (TREE_CODE (class) == CLASS_IMPLEMENTATION_TYPE)
4987 error ("duplicate definition of class method `%s'.",
4988 IDENTIFIER_POINTER (METHOD_SEL_NAME (mth)));
4991 /* check types, if different complain */
4992 if (!comp_proto_with_proto (method, mth))
4993 error ("duplicate declaration of class method `%s'.",
4994 IDENTIFIER_POINTER (METHOD_SEL_NAME (mth)));
4998 if (!(hsh = hash_lookup (cls_method_hash_list, METHOD_SEL_NAME (method))))
5000 /* install on a global chain */
5001 hash_enter (cls_method_hash_list, method);
5005 /* check types, if different add to a list */
5006 if (!comp_proto_with_proto (method, hsh->key))
5007 hash_add_attr (hsh, method);
5013 add_instance_method (class, method)
5020 /* We will have allocated the method parameter declarations on the
5021 maybepermanent_obstack. Need to make sure they stick around! */
5024 if (!(mth = lookup_method (CLASS_NST_METHODS (class), method)))
5026 /* put method on list in reverse order */
5027 TREE_CHAIN (method) = CLASS_NST_METHODS (class);
5028 CLASS_NST_METHODS (class) = method;
5032 if (TREE_CODE (class) == CLASS_IMPLEMENTATION_TYPE)
5033 error ("duplicate definition of instance method `%s'.",
5034 IDENTIFIER_POINTER (METHOD_SEL_NAME (mth)));
5037 /* check types, if different complain */
5038 if (!comp_proto_with_proto (method, mth))
5039 error ("duplicate declaration of instance method `%s'.",
5040 IDENTIFIER_POINTER (METHOD_SEL_NAME (mth)));
5044 if (!(hsh = hash_lookup (nst_method_hash_list, METHOD_SEL_NAME (method))))
5046 /* install on a global chain */
5047 hash_enter (nst_method_hash_list, method);
5051 /* check types, if different add to a list */
5052 if (!comp_proto_with_proto (method, hsh->key))
5053 hash_add_attr (hsh, method);
5062 /* put interfaces on list in reverse order */
5063 TREE_CHAIN (class) = interface_chain;
5064 interface_chain = class;
5065 return interface_chain;
5069 add_category (class, category)
5073 /* put categories on list in reverse order */
5075 tree cat = CLASS_CATEGORY_LIST (class);
5078 if (CLASS_SUPER_NAME (cat) == CLASS_SUPER_NAME (category))
5079 warning ("duplicate interface declaration for category `%s(%s)'",
5080 IDENTIFIER_POINTER (CLASS_NAME (class)),
5081 IDENTIFIER_POINTER (CLASS_SUPER_NAME (category)));
5082 cat = CLASS_CATEGORY_LIST (cat);
5085 CLASS_CATEGORY_LIST (category) = CLASS_CATEGORY_LIST (class);
5086 CLASS_CATEGORY_LIST (class) = category;
5089 /* Called after parsing each instance variable declaration. Necessary to
5090 preserve typedefs and implement public/private...
5092 PUBLIC is 1 for public, 0 for protected, and 2 for private. */
5095 add_instance_variable (class, public, declarator, declspecs, width)
5102 tree field_decl, raw_decl;
5104 raw_decl = build_tree_list (declspecs /*purpose*/, declarator/*value*/);
5106 if (CLASS_RAW_IVARS (class))
5107 chainon (CLASS_RAW_IVARS (class), raw_decl);
5109 CLASS_RAW_IVARS (class) = raw_decl;
5111 field_decl = grokfield (input_filename, lineno,
5112 declarator, declspecs, width);
5114 /* overload the public attribute, it is not used for FIELD_DECL's */
5118 TREE_PUBLIC (field_decl) = 0;
5119 TREE_PRIVATE (field_decl) = 0;
5120 TREE_PROTECTED (field_decl) = 1;
5124 TREE_PUBLIC (field_decl) = 1;
5125 TREE_PRIVATE (field_decl) = 0;
5126 TREE_PROTECTED (field_decl) = 0;
5130 TREE_PUBLIC (field_decl) = 0;
5131 TREE_PRIVATE (field_decl) = 1;
5132 TREE_PROTECTED (field_decl) = 0;
5137 if (CLASS_IVARS (class))
5138 chainon (CLASS_IVARS (class), field_decl);
5140 CLASS_IVARS (class) = field_decl;
5146 is_ivar (decl_chain, ident)
5150 for ( ; decl_chain; decl_chain = TREE_CHAIN (decl_chain))
5151 if (DECL_NAME (decl_chain) == ident)
5156 /* True if the ivar is private and we are not in its implementation. */
5162 if (TREE_PRIVATE (decl)
5163 && ! is_ivar (CLASS_IVARS (implementation_template), DECL_NAME (decl)))
5165 error ("instance variable `%s' is declared private",
5166 IDENTIFIER_POINTER (DECL_NAME (decl)));
5173 /* we have an instance variable reference, check to see if it is public...*/
5176 is_public (expr, identifier)
5180 tree basetype = TREE_TYPE (expr);
5181 enum tree_code code = TREE_CODE (basetype);
5184 if (code == RECORD_TYPE)
5186 if (TREE_STATIC_TEMPLATE (basetype))
5188 if (!lookup_interface (TYPE_NAME (basetype)))
5190 error ("Cannot find interface declaration for `%s'",
5191 IDENTIFIER_POINTER (TYPE_NAME (basetype)));
5195 if ((decl = is_ivar (TYPE_FIELDS (basetype), identifier)))
5197 if (TREE_PUBLIC (decl))
5200 /* important difference between the Stepstone translator:
5201 all instance variables should be public within the context
5202 of the implementation. */
5203 if (implementation_context
5204 && (((TREE_CODE (implementation_context)
5205 == CLASS_IMPLEMENTATION_TYPE)
5206 || (TREE_CODE (implementation_context)
5207 == CATEGORY_IMPLEMENTATION_TYPE))
5208 && (CLASS_NAME (implementation_context)
5209 == TYPE_NAME (basetype))))
5210 return ! is_private (decl);
5212 error ("instance variable `%s' is declared %s",
5213 IDENTIFIER_POINTER (identifier),
5214 TREE_PRIVATE (decl) ? "private" : "protected");
5218 else if (implementation_context && (basetype == objc_object_reference))
5220 TREE_TYPE (expr) = uprivate_record;
5221 warning ("static access to object of type `id'");
5227 /* implement @defs (<classname>) within struct bodies. */
5230 get_class_ivars (interface)
5233 if (!doing_objc_thang)
5236 return build_ivar_chain (interface, 1);
5239 /* make sure all entries in "chain" are also in "list" */
5242 check_methods (chain, list, mtype)
5251 if (!lookup_method (list, chain))
5255 if (TREE_CODE (implementation_context) == CLASS_IMPLEMENTATION_TYPE)
5256 warning ("incomplete implementation of class `%s'",
5257 IDENTIFIER_POINTER (CLASS_NAME (implementation_context)));
5258 else if (TREE_CODE (implementation_context) == CATEGORY_IMPLEMENTATION_TYPE)
5259 warning ("incomplete implementation of category `%s'",
5260 IDENTIFIER_POINTER (CLASS_SUPER_NAME (implementation_context)));
5263 warning ("method definition for `%c%s' not found",
5264 mtype, IDENTIFIER_POINTER (METHOD_SEL_NAME (chain)));
5266 chain = TREE_CHAIN (chain);
5272 conforms_to_protocol (class, protocol)
5278 tree p = CLASS_PROTOCOL_LIST (class);
5279 while (p && TREE_VALUE (p) != TREE_VALUE (protocol))
5283 tree super = (CLASS_SUPER_NAME (class)
5284 ? lookup_interface (CLASS_SUPER_NAME (class))
5286 int tmp = super ? conforms_to_protocol (super, protocol) : 0;
5290 protocol = TREE_CHAIN (protocol);
5295 /* Make sure all methods in CHAIN are accessible as MTYPE methods in
5296 CONTEXT. This is one of two mechanisms to check protocol integrity
5300 check_methods_accessible (chain, context, mtype)
5302 tree context; /* implementation_context */
5313 list = CLASS_CLS_METHODS (context);
5315 list = CLASS_NST_METHODS (context);
5317 if (lookup_method (list, chain))
5320 else if (TREE_CODE (context) == CLASS_IMPLEMENTATION_TYPE)
5321 context = (CLASS_SUPER_NAME (context)
5322 ? lookup_interface (CLASS_SUPER_NAME (context))
5325 else if (TREE_CODE (context) == CATEGORY_IMPLEMENTATION_TYPE)
5326 context = (CLASS_NAME (context)
5327 ? lookup_interface (CLASS_NAME (context))
5333 if (context == NULL_TREE)
5337 if (TREE_CODE (implementation_context)
5338 == CLASS_IMPLEMENTATION_TYPE)
5339 warning ("incomplete implementation of class `%s'",
5341 (CLASS_NAME (implementation_context)));
5342 else if (TREE_CODE (implementation_context)
5343 == CATEGORY_IMPLEMENTATION_TYPE)
5344 warning ("incomplete implementation of category `%s'",
5346 (CLASS_SUPER_NAME (implementation_context)));
5349 warning ("method definition for `%c%s' not found",
5350 mtype, IDENTIFIER_POINTER (METHOD_SEL_NAME (chain)));
5353 chain = TREE_CHAIN (chain); /* next method... */
5359 check_protocols (proto_list, type, name)
5364 for ( ; proto_list; proto_list = TREE_CHAIN (proto_list))
5366 tree p = TREE_VALUE (proto_list);
5368 if (TREE_CODE (p) == PROTOCOL_INTERFACE_TYPE)
5372 /* Ensure that all protocols have bodies! */
5373 if (flag_warn_protocol) {
5374 f1 = check_methods (PROTOCOL_CLS_METHODS (p),
5375 CLASS_CLS_METHODS (implementation_context),
5377 f2 = check_methods (PROTOCOL_NST_METHODS (p),
5378 CLASS_NST_METHODS (implementation_context),
5381 f1 = check_methods_accessible (PROTOCOL_CLS_METHODS (p),
5382 implementation_context,
5384 f2 = check_methods_accessible (PROTOCOL_NST_METHODS (p),
5385 implementation_context,
5390 warning ("%s `%s' does not fully implement the `%s' protocol",
5391 type, name, IDENTIFIER_POINTER (PROTOCOL_NAME (p)));
5395 ; /* an identifier...if we could not find a protocol. */
5397 /* Check protocols recursively. */
5398 if (PROTOCOL_LIST (p))
5401 = lookup_interface (CLASS_SUPER_NAME (implementation_template));
5402 if (! conforms_to_protocol (super_class, PROTOCOL_LIST (p)))
5403 check_protocols (PROTOCOL_LIST (p), type, name);
5408 /* Make sure that the class CLASS_NAME is defined
5409 CODE says which kind of thing CLASS_NAME ought to be.
5410 It can be CLASS_INTERFACE_TYPE, CLASS_IMPLEMENTATION_TYPE,
5411 CATEGORY_INTERFACE_TYPE, or CATEGORY_IMPLEMENTATION_TYPE.
5413 If CODE is CLASS_INTERFACE_TYPE, we also do a push_obstacks_nochange
5414 whose matching pop is in continue_class. */
5417 start_class (code, class_name, super_name, protocol_list)
5418 enum tree_code code;
5425 if (code == CLASS_INTERFACE_TYPE)
5427 push_obstacks_nochange ();
5428 end_temporary_allocation ();
5431 if (!doing_objc_thang)
5434 class = make_node (code);
5435 TYPE_BINFO (class) = make_tree_vec (5);
5437 CLASS_NAME (class) = class_name;
5438 CLASS_SUPER_NAME (class) = super_name;
5439 CLASS_CLS_METHODS (class) = NULL_TREE;
5441 if (! is_class_name (class_name) && (decl = lookup_name (class_name)))
5443 error ("`%s' redeclared as different kind of symbol",
5444 IDENTIFIER_POINTER (class_name));
5445 error_with_decl (decl, "previous declaration of `%s'");
5448 if (code == CLASS_IMPLEMENTATION_TYPE)
5451 static tree implemented_classes = 0;
5452 tree chain = implemented_classes;
5453 for (chain = implemented_classes; chain; chain = TREE_CHAIN (chain))
5454 if (TREE_VALUE (chain) == class_name)
5456 error ("reimplementation of class `%s'",
5457 IDENTIFIER_POINTER (class_name));
5458 return error_mark_node;
5460 implemented_classes = perm_tree_cons (NULLT, class_name,
5461 implemented_classes);
5464 /* pre-build the following entities - for speed/convenience. */
5466 self_id = get_identifier ("self");
5468 ucmd_id = get_identifier ("_cmd");
5470 if (!objc_super_template)
5471 objc_super_template = build_super_template ();
5473 method_slot = 0; /* reset for multiple classes per file */
5475 implementation_context = class;
5477 /* lookup the interface for this implementation. */
5479 if (!(implementation_template = lookup_interface (class_name)))
5481 warning ("Cannot find interface declaration for `%s'",
5482 IDENTIFIER_POINTER (class_name));
5483 add_class (implementation_template = implementation_context);
5486 /* if a super class has been specified in the implementation,
5487 insure it conforms to the one specified in the interface */
5490 && (super_name != CLASS_SUPER_NAME (implementation_template)))
5492 tree previous_name = CLASS_SUPER_NAME (implementation_template);
5493 char *name = previous_name ? IDENTIFIER_POINTER (previous_name) : "";
5494 error ("conflicting super class name `%s'",
5495 IDENTIFIER_POINTER (super_name));
5496 error ("previous declaration of `%s'", name);
5498 else if (! super_name)
5500 CLASS_SUPER_NAME (implementation_context)
5501 = CLASS_SUPER_NAME (implementation_template);
5504 else if (code == CLASS_INTERFACE_TYPE)
5506 if (lookup_interface (class_name))
5507 warning ("duplicate interface declaration for class `%s'",
5508 IDENTIFIER_POINTER (class_name));
5513 CLASS_PROTOCOL_LIST (class)
5514 = lookup_and_install_protocols (protocol_list);
5516 else if (code == CATEGORY_INTERFACE_TYPE)
5518 tree class_category_is_assoc_with;
5520 /* for a category, class_name is really the name of the class that
5521 the following set of methods will be associated with...we must
5522 find the interface so that can derive the objects template */
5524 if (!(class_category_is_assoc_with = lookup_interface (class_name)))
5526 error ("Cannot find interface declaration for `%s'",
5527 IDENTIFIER_POINTER (class_name));
5531 add_category (class_category_is_assoc_with, class);
5534 CLASS_PROTOCOL_LIST (class)
5535 = lookup_and_install_protocols (protocol_list);
5537 else if (code == CATEGORY_IMPLEMENTATION_TYPE)
5539 /* pre-build the following entities - for speed/convenience. */
5541 self_id = get_identifier ("self");
5543 ucmd_id = get_identifier ("_cmd");
5545 if (!objc_super_template)
5546 objc_super_template = build_super_template ();
5548 method_slot = 0; /* reset for multiple classes per file */
5550 implementation_context = class;
5552 /* for a category, class_name is really the name of the class that
5553 the following set of methods will be associated with...we must
5554 find the interface so that can derive the objects template */
5556 if (!(implementation_template = lookup_interface (class_name)))
5558 error ("Cannot find interface declaration for `%s'",
5559 IDENTIFIER_POINTER (class_name));
5567 continue_class (class)
5570 if (TREE_CODE (class) == CLASS_IMPLEMENTATION_TYPE
5571 || TREE_CODE (class) == CATEGORY_IMPLEMENTATION_TYPE)
5573 struct imp_entry *imp_entry;
5576 /* check consistency of the instance variables. */
5578 if (CLASS_IVARS (class))
5579 check_ivars (implementation_template, class);
5581 /* code generation */
5583 ivar_context = build_private_template (implementation_template);
5585 if (!objc_class_template)
5586 build_class_template ();
5588 if (!(imp_entry = (struct imp_entry *) xmalloc (sizeof (struct imp_entry))))
5589 perror ("unable to allocate in objc-tree.c");
5591 imp_entry->next = imp_list;
5592 imp_entry->imp_context = class;
5593 imp_entry->imp_template = implementation_template;
5595 synth_forward_declarations ();
5596 imp_entry->class_decl = UOBJC_CLASS_decl;
5597 imp_entry->meta_decl = UOBJC_METACLASS_decl;
5599 /* append to front and increment count */
5600 imp_list = imp_entry;
5601 if (TREE_CODE (class) == CLASS_IMPLEMENTATION_TYPE)
5606 return ivar_context;
5608 else if (TREE_CODE (class) == CLASS_INTERFACE_TYPE)
5610 tree record = xref_tag (RECORD_TYPE, CLASS_NAME (class));
5612 if (!TYPE_FIELDS (record))
5614 finish_struct (record, build_ivar_chain (class, 0));
5615 CLASS_STATIC_TEMPLATE (class) = record;
5617 /* mark this record as a class template - for static typing */
5618 TREE_STATIC_TEMPLATE (record) = 1;
5623 return error_mark_node;
5626 /* This is called once we see the "@end" in an interface/implementation. */
5629 finish_class (class)
5632 if (TREE_CODE (class) == CLASS_IMPLEMENTATION_TYPE)
5634 /* all code generation is done in finish_objc */
5636 if (implementation_template != implementation_context)
5638 /* ensure that all method listed in the interface contain bodies! */
5639 check_methods (CLASS_CLS_METHODS (implementation_template),
5640 CLASS_CLS_METHODS (implementation_context), '+');
5641 check_methods (CLASS_NST_METHODS (implementation_template),
5642 CLASS_NST_METHODS (implementation_context), '-');
5644 if (CLASS_PROTOCOL_LIST (implementation_template))
5645 check_protocols (CLASS_PROTOCOL_LIST (implementation_template),
5647 IDENTIFIER_POINTER (CLASS_NAME (implementation_context)));
5650 else if (TREE_CODE (class) == CATEGORY_IMPLEMENTATION_TYPE)
5652 tree category = CLASS_CATEGORY_LIST (implementation_template);
5654 /* find the category interface from the class it is associated with */
5657 if (CLASS_SUPER_NAME (class) == CLASS_SUPER_NAME (category))
5659 category = CLASS_CATEGORY_LIST (category);
5664 /* ensure that all method listed in the interface contain bodies! */
5665 check_methods (CLASS_CLS_METHODS (category),
5666 CLASS_CLS_METHODS (implementation_context), '+');
5667 check_methods (CLASS_NST_METHODS (category),
5668 CLASS_NST_METHODS (implementation_context), '-');
5670 if (CLASS_PROTOCOL_LIST (category))
5671 check_protocols (CLASS_PROTOCOL_LIST (category),
5673 IDENTIFIER_POINTER (CLASS_SUPER_NAME (implementation_context)));
5676 else if (TREE_CODE (class) == CLASS_INTERFACE_TYPE)
5679 char *class_name = IDENTIFIER_POINTER (CLASS_NAME (class));
5680 char *string = (char *) alloca (strlen (class_name) + 3);
5682 /* extern struct objc_object *_<my_name>; */
5684 sprintf (string, "_%s", class_name);
5686 decl_specs = build_tree_list (NULLT, ridpointers[(int) RID_EXTERN]);
5687 decl_specs = tree_cons (NULLT, objc_object_reference, decl_specs);
5688 define_decl (build1 (INDIRECT_REF, NULLT, get_identifier (string)),
5694 add_protocol (protocol)
5697 /* put protocol on list in reverse order */
5698 TREE_CHAIN (protocol) = protocol_chain;
5699 protocol_chain = protocol;
5700 return protocol_chain;
5704 lookup_protocol (ident)
5709 for (chain = protocol_chain; chain; chain = TREE_CHAIN (chain))
5711 if (ident == PROTOCOL_NAME (chain))
5718 start_protocol (code, name, list)
5719 enum tree_code code;
5725 if (!doing_objc_thang)
5728 /* This is as good a place as any. Need to invoke push_tag_toplevel. */
5729 if (!objc_protocol_template)
5730 objc_protocol_template = build_protocol_template ();
5732 protocol = make_node (code);
5733 TYPE_BINFO (protocol) = make_tree_vec (2);
5735 PROTOCOL_NAME (protocol) = name;
5736 PROTOCOL_LIST (protocol) = list;
5738 lookup_and_install_protocols (list);
5740 if (lookup_protocol (name))
5741 warning ("duplicate declaration for protocol `%s'",
5742 IDENTIFIER_POINTER (name));
5744 add_protocol (protocol);
5746 PROTOCOL_FORWARD_DECL (protocol) = NULL_TREE;
5752 finish_protocol (protocol)
5758 /* "Encode" a data type into a string, which grows in util_obstack.
5759 ??? What is the FORMAT? Someone please document this! */
5762 encode_type_qualifiers (declspecs)
5767 for (spec = declspecs; spec; spec = TREE_CHAIN (spec))
5769 if (ridpointers[RID_CONST] == TREE_VALUE (spec))
5770 obstack_1grow (&util_obstack, 'r');
5771 else if (ridpointers[RID_IN] == TREE_VALUE (spec))
5772 obstack_1grow (&util_obstack, 'n');
5773 else if (ridpointers[RID_INOUT] == TREE_VALUE (spec))
5774 obstack_1grow (&util_obstack, 'N');
5775 else if (ridpointers[RID_OUT] == TREE_VALUE (spec))
5776 obstack_1grow (&util_obstack, 'o');
5777 else if (ridpointers[RID_BYCOPY] == TREE_VALUE (spec))
5778 obstack_1grow (&util_obstack, 'O');
5779 else if (ridpointers[RID_ONEWAY] == TREE_VALUE (spec))
5780 obstack_1grow (&util_obstack, 'V');
5784 /* Encode a pointer type. */
5787 encode_pointer (type, curtype, format)
5792 tree pointer_to = TREE_TYPE (type);
5794 if (TREE_CODE (pointer_to) == RECORD_TYPE)
5796 if (TYPE_NAME (pointer_to)
5797 && TREE_CODE (TYPE_NAME (pointer_to)) == IDENTIFIER_NODE)
5799 char *name = IDENTIFIER_POINTER (TYPE_NAME (pointer_to));
5801 if (strcmp (name, TAG_OBJECT) == 0) /* '@' */
5803 obstack_1grow (&util_obstack, '@');
5806 else if (TREE_STATIC_TEMPLATE (pointer_to))
5808 if (generating_instance_variables)
5810 obstack_1grow (&util_obstack, '@');
5811 obstack_1grow (&util_obstack, '"');
5812 obstack_grow (&util_obstack, name, strlen (name));
5813 obstack_1grow (&util_obstack, '"');
5818 obstack_1grow (&util_obstack, '@');
5822 else if (strcmp (name, TAG_CLASS) == 0) /* '#' */
5824 obstack_1grow (&util_obstack, '#');
5827 #ifndef OBJC_INT_SELECTORS
5828 else if (strcmp (name, TAG_SELECTOR) == 0) /* ':' */
5830 obstack_1grow (&util_obstack, ':');
5833 #endif /* OBJC_INT_SELECTORS */
5836 else if (TREE_CODE (pointer_to) == INTEGER_TYPE
5837 && TYPE_MODE (pointer_to) == QImode)
5839 obstack_1grow (&util_obstack, '*');
5843 /* we have a type that does not get special treatment... */
5845 /* NeXT extension */
5846 obstack_1grow (&util_obstack, '^');
5847 encode_type (pointer_to, curtype, format);
5851 encode_array (type, curtype, format)
5856 tree an_int_cst = TYPE_SIZE (type);
5857 tree array_of = TREE_TYPE (type);
5860 /* An incomplete array is treated like a pointer. */
5861 if (an_int_cst == NULL)
5863 /* split for obvious reasons. North-Keys 30 Mar 1991 */
5864 encode_pointer (type, curtype, format);
5868 sprintf (buffer, "[%d",
5869 (TREE_INT_CST_LOW (an_int_cst)
5870 / TREE_INT_CST_LOW (TYPE_SIZE (array_of))));
5871 obstack_grow (&util_obstack, buffer, strlen (buffer));
5872 encode_type (array_of, curtype, format);
5873 obstack_1grow (&util_obstack, ']');
5878 encode_aggregate (type, curtype, format)
5883 enum tree_code code = TREE_CODE (type);
5889 if (obstack_object_size (&util_obstack) > 0
5890 && *(obstack_next_free (&util_obstack) - 1) == '^')
5892 tree name = TYPE_NAME (type);
5894 /* we have a reference - this is a NeXT extension */
5896 if (obstack_object_size (&util_obstack) - curtype == 1
5897 && format == OBJC_ENCODE_INLINE_DEFS)
5899 /* output format of struct for first level only! */
5901 tree fields = TYPE_FIELDS (type);
5903 if (name && TREE_CODE (name) == IDENTIFIER_NODE)
5905 obstack_1grow (&util_obstack, '{');
5906 obstack_grow (&util_obstack,
5907 IDENTIFIER_POINTER (name),
5908 strlen (IDENTIFIER_POINTER (name)));
5909 obstack_1grow (&util_obstack, '=');
5912 obstack_grow (&util_obstack, "{?=", 3);
5914 for ( ; fields; fields = TREE_CHAIN (fields))
5915 encode_field_decl (fields, curtype, format);
5916 obstack_1grow (&util_obstack, '}');
5918 else if (name && TREE_CODE (name) == IDENTIFIER_NODE)
5920 obstack_1grow (&util_obstack, '{');
5921 obstack_grow (&util_obstack,
5922 IDENTIFIER_POINTER (name),
5923 strlen (IDENTIFIER_POINTER (name)));
5924 obstack_1grow (&util_obstack, '}');
5926 else /* we have an untagged structure or a typedef */
5927 obstack_grow (&util_obstack, "{?}", 3);
5931 tree name = TYPE_NAME (type);
5932 tree fields = TYPE_FIELDS (type);
5934 if (format == OBJC_ENCODE_INLINE_DEFS
5935 || generating_instance_variables)
5937 obstack_1grow (&util_obstack, '{');
5938 if (name && TREE_CODE (name) == IDENTIFIER_NODE)
5939 obstack_grow (&util_obstack,
5940 IDENTIFIER_POINTER (name),
5941 strlen (IDENTIFIER_POINTER (name)));
5943 obstack_1grow (&util_obstack, '?');
5945 obstack_1grow (&util_obstack, '=');
5947 for (; fields; fields = TREE_CHAIN (fields))
5949 if (generating_instance_variables)
5951 tree fname = DECL_NAME (fields);
5953 obstack_1grow (&util_obstack, '"');
5954 if (fname && TREE_CODE (fname) == IDENTIFIER_NODE)
5956 obstack_grow (&util_obstack,
5957 IDENTIFIER_POINTER (fname),
5958 strlen (IDENTIFIER_POINTER (fname)));
5960 obstack_1grow (&util_obstack, '"');
5962 encode_field_decl (fields, curtype, format);
5964 obstack_1grow (&util_obstack, '}');
5968 obstack_1grow (&util_obstack, '{');
5969 if (name && TREE_CODE (name) == IDENTIFIER_NODE)
5970 obstack_grow (&util_obstack,
5971 IDENTIFIER_POINTER (name),
5972 strlen (IDENTIFIER_POINTER (name)));
5973 else /* we have an untagged structure or a typedef */
5974 obstack_1grow (&util_obstack, '?');
5975 obstack_1grow (&util_obstack, '}');
5982 if (*obstack_next_free (&util_obstack) == '^'
5983 || format != OBJC_ENCODE_INLINE_DEFS)
5985 /* we have a reference - this is a NeXT extension--
5986 or we don't want the details. */
5987 if (TYPE_NAME (type)
5988 && TREE_CODE (TYPE_NAME (type)) == IDENTIFIER_NODE)
5990 obstack_1grow (&util_obstack, '(');
5991 obstack_grow (&util_obstack,
5992 IDENTIFIER_POINTER (TYPE_NAME (type)),
5993 strlen (IDENTIFIER_POINTER (TYPE_NAME (type))));
5994 obstack_1grow (&util_obstack, ')');
5996 else /* we have an untagged structure or a typedef */
5997 obstack_grow (&util_obstack, "(?)", 3);
6001 tree fields = TYPE_FIELDS (type);
6002 obstack_1grow (&util_obstack, '(');
6003 for ( ; fields; fields = TREE_CHAIN (fields))
6004 encode_field_decl (fields, curtype, format);
6005 obstack_1grow (&util_obstack, ')');
6011 obstack_1grow (&util_obstack, 'i');
6016 /* Support bitfields, the current version of Objective-C does not support
6017 them. the string will consist of one or more "b:n"'s where n is an
6018 integer describing the width of the bitfield. Currently, classes in
6019 the kit implement a method "-(char *)describeBitfieldStruct:" that
6020 simulates this...if they do not implement this method, the archiver
6021 assumes the bitfield is 16 bits wide (padded if necessary) and packed
6022 according to the GNU compiler. After looking at the "kit", it appears
6023 that all classes currently rely on this default behavior, rather than
6024 hand generating this string (which is tedious). */
6027 encode_bitfield (width, format)
6032 sprintf (buffer, "b%d", width);
6033 obstack_grow (&util_obstack, buffer, strlen (buffer));
6036 /* FORMAT will be OBJC_ENCODE_INLINE_DEFS or OBJC_ENCODE_DONT_INLINE_DEFS. */
6039 encode_type (type, curtype, format)
6044 enum tree_code code = TREE_CODE (type);
6046 if (code == INTEGER_TYPE)
6048 if (TREE_INT_CST_LOW (TYPE_MIN_VALUE (type)) == 0)
6050 /* unsigned integer types */
6052 if (TYPE_MODE (type) == QImode) /* 'C' */
6053 obstack_1grow (&util_obstack, 'C');
6054 else if (TYPE_MODE (type) == HImode) /* 'S' */
6055 obstack_1grow (&util_obstack, 'S');
6056 else if (TYPE_MODE (type) == SImode)
6058 if (type == long_unsigned_type_node)
6059 obstack_1grow (&util_obstack, 'L'); /* 'L' */
6061 obstack_1grow (&util_obstack, 'I'); /* 'I' */
6064 else /* signed integer types */
6066 if (TYPE_MODE (type) == QImode) /* 'c' */
6067 obstack_1grow (&util_obstack, 'c');
6068 else if (TYPE_MODE (type) == HImode) /* 's' */
6069 obstack_1grow (&util_obstack, 's');
6070 else if (TYPE_MODE (type) == SImode) /* 'i' */
6072 if (type == long_integer_type_node)
6073 obstack_1grow (&util_obstack, 'l'); /* 'l' */
6075 obstack_1grow (&util_obstack, 'i'); /* 'i' */
6079 else if (code == REAL_TYPE)
6081 /* floating point types */
6083 if (TYPE_MODE (type) == SFmode) /* 'f' */
6084 obstack_1grow (&util_obstack, 'f');
6085 else if (TYPE_MODE (type) == DFmode
6086 || TYPE_MODE (type) == TFmode) /* 'd' */
6087 obstack_1grow (&util_obstack, 'd');
6090 else if (code == VOID_TYPE) /* 'v' */
6091 obstack_1grow (&util_obstack, 'v');
6093 else if (code == ARRAY_TYPE)
6094 encode_array (type, curtype, format);
6096 else if (code == POINTER_TYPE)
6097 encode_pointer (type, curtype, format);
6099 else if (code == RECORD_TYPE || code == UNION_TYPE || code == ENUMERAL_TYPE)
6100 encode_aggregate (type, curtype, format);
6102 else if (code == FUNCTION_TYPE) /* '?' */
6103 obstack_1grow (&util_obstack, '?');
6107 encode_field_decl (field_decl, curtype, format)
6114 /* If this field is obviously a bitfield, or is a bitfield that has been
6115 clobbered to look like a ordinary integer mode, go ahead and generate
6116 the bitfield typing information. */
6117 type = TREE_TYPE (field_decl);
6118 if (DECL_BIT_FIELD (field_decl))
6119 encode_bitfield (DECL_FIELD_SIZE (field_decl), format);
6120 else if (TREE_CODE (TYPE_SIZE (type)) == INTEGER_CST
6121 && DECL_FIELD_SIZE (field_decl)
6122 && TYPE_MODE (type) > DECL_MODE (field_decl))
6123 encode_bitfield (DECL_FIELD_SIZE (field_decl), format);
6125 encode_type (TREE_TYPE (field_decl), curtype, format);
6129 expr_last (complex_expr)
6135 while ((next = TREE_OPERAND (complex_expr, 0)))
6136 complex_expr = next;
6137 return complex_expr;
6140 /* The selector of the current method,
6141 or NULL if we aren't compiling a method. */
6144 maybe_objc_method_name (decl)
6148 return METHOD_SEL_NAME (method_context);
6153 /* Transform a method definition into a function definition as follows:
6154 - synthesize the first two arguments, "self" and "_cmd". */
6157 start_method_def (method)
6162 /* Required to implement _msgSuper. */
6163 method_context = method;
6164 UOBJC_SUPER_decl = NULLT;
6166 pushlevel (0); /* Must be called BEFORE start_function. */
6168 /* Generate prototype declarations for arguments..."new-style". */
6170 if (TREE_CODE (method_context) == INSTANCE_METHOD_DECL)
6171 decl_specs = build_tree_list (NULLT, uprivate_record);
6173 /* really a `struct objc_class *'...however we allow people to
6174 assign to self...which changes its type midstream. */
6175 decl_specs = build_tree_list (NULLT, objc_object_reference);
6177 push_parm_decl (build_tree_list (decl_specs,
6178 build1 (INDIRECT_REF, NULLT, self_id)));
6180 #ifdef OBJC_INT_SELECTORS
6181 decl_specs = build_tree_list (NULLT, ridpointers[(int) RID_UNSIGNED]);
6182 decl_specs = tree_cons (NULLT, ridpointers[(int) RID_INT], decl_specs);
6183 push_parm_decl (build_tree_list (decl_specs, ucmd_id));
6184 #else /* not OBJC_INT_SELECTORS */
6185 decl_specs = build_tree_list (NULLT,
6186 xref_tag (RECORD_TYPE,
6187 get_identifier (TAG_SELECTOR)));
6188 push_parm_decl (build_tree_list (decl_specs,
6189 build1 (INDIRECT_REF, NULLT, ucmd_id)));
6190 #endif /* not OBJC_INT_SELECTORS */
6192 /* generate argument declarations if a keyword_decl */
6193 if (METHOD_SEL_ARGS (method))
6195 tree arglist = METHOD_SEL_ARGS (method);
6198 tree arg_spec = TREE_PURPOSE (TREE_TYPE (arglist));
6199 tree arg_decl = TREE_VALUE (TREE_TYPE (arglist));
6203 tree last_expr = expr_last (arg_decl);
6205 /* unite the abstract decl with its name */
6206 TREE_OPERAND (last_expr, 0) = KEYWORD_ARG_NAME (arglist);
6207 push_parm_decl (build_tree_list (arg_spec, arg_decl));
6208 /* unhook...restore the abstract declarator */
6209 TREE_OPERAND (last_expr, 0) = NULLT;
6212 push_parm_decl (build_tree_list (arg_spec,
6213 KEYWORD_ARG_NAME (arglist)));
6215 arglist = TREE_CHAIN (arglist);
6220 if (METHOD_ADD_ARGS (method) > (tree)1)
6222 /* we have a variable length selector - in "prototype" format */
6223 tree akey = TREE_PURPOSE (METHOD_ADD_ARGS (method));
6226 /* This must be done prior to calling pushdecl. pushdecl is
6227 going to change our chain on us. */
6228 tree nextkey = TREE_CHAIN (akey);
6236 warn_with_method (message, mtype, method)
6241 if (count_error (1) == 0)
6244 report_error_function (DECL_SOURCE_FILE (method));
6246 fprintf (stderr, "%s:%d: warning: ",
6247 DECL_SOURCE_FILE (method), DECL_SOURCE_LINE (method));
6248 bzero (errbuf, BUFSIZE);
6249 fprintf (stderr, "%s `%c%s'\n",
6250 message, mtype, gen_method_decl (method, errbuf));
6253 /* return 1 if `method' is consistent with `proto' */
6256 comp_method_with_proto (method, proto)
6259 static tree function_type = 0;
6261 /* create a function_type node once */
6264 struct obstack *ambient_obstack = current_obstack;
6266 current_obstack = &permanent_obstack;
6267 function_type = make_node (FUNCTION_TYPE);
6268 current_obstack = ambient_obstack;
6271 /* Install argument types - normally set by build_function_type. */
6272 TYPE_ARG_TYPES (function_type) = get_arg_type_list (proto, METHOD_DEF, 0);
6274 /* install return type */
6275 TREE_TYPE (function_type) = groktypename (TREE_TYPE (proto));
6277 return comptypes (TREE_TYPE (METHOD_DEFINITION (method)), function_type);
6280 /* return 1 if `proto1' is consistent with `proto2' */
6283 comp_proto_with_proto (proto1, proto2)
6284 tree proto1, proto2;
6286 static tree function_type1 = 0, function_type2 = 0;
6288 /* create a couple function_type node's once */
6289 if (!function_type1)
6291 struct obstack *ambient_obstack = current_obstack;
6293 current_obstack = &permanent_obstack;
6294 function_type1 = make_node (FUNCTION_TYPE);
6295 function_type2 = make_node (FUNCTION_TYPE);
6296 current_obstack = ambient_obstack;
6299 /* Install argument types - normally set by build_function_type. */
6300 TYPE_ARG_TYPES (function_type1) = get_arg_type_list (proto1, METHOD_REF, 0);
6301 TYPE_ARG_TYPES (function_type2) = get_arg_type_list (proto2, METHOD_REF, 0);
6303 /* install return type */
6304 TREE_TYPE (function_type1) = groktypename (TREE_TYPE (proto1));
6305 TREE_TYPE (function_type2) = groktypename (TREE_TYPE (proto2));
6307 return comptypes (function_type1, function_type2);
6310 /* - generate an identifier for the function. the format is "_n_cls",
6311 where 1 <= n <= nMethods, and cls is the name the implementation we
6313 - install the return type from the method declaration.
6314 - if we have a prototype, check for type consistency. */
6317 really_start_method (method, parmlist)
6318 tree method, parmlist;
6320 tree sc_spec, ret_spec, ret_decl, decl_specs;
6321 tree method_decl, method_id;
6322 char *buf, *sel_name, *class_name, *cat_name;
6324 /* synth the storage class & assemble the return type */
6325 sc_spec = tree_cons (NULLT, ridpointers[(int) RID_STATIC], NULLT);
6326 ret_spec = TREE_PURPOSE (TREE_TYPE (method));
6327 decl_specs = chainon (sc_spec, ret_spec);
6329 sel_name = IDENTIFIER_POINTER (METHOD_SEL_NAME (method));
6330 class_name = IDENTIFIER_POINTER (CLASS_NAME (implementation_context));
6331 cat_name = ((TREE_CODE (implementation_context)
6332 == CLASS_IMPLEMENTATION_TYPE)
6334 : IDENTIFIER_POINTER (CLASS_SUPER_NAME (implementation_context)));
6336 /* Make sure this is big enough for any plausible method label. */
6337 buf = (char *) alloca (50 + strlen (sel_name) + strlen (class_name)
6338 + (cat_name ? strlen (cat_name) : 0));
6340 OBJC_GEN_METHOD_LABEL (buf, TREE_CODE (method) == INSTANCE_METHOD_DECL,
6341 class_name, cat_name, sel_name, method_slot);
6343 method_id = get_identifier (buf);
6345 method_decl = build_nt (CALL_EXPR, method_id, parmlist, NULLT);
6347 /* check the declarator portion of the return type for the method */
6348 if ((ret_decl = TREE_VALUE (TREE_TYPE (method))))
6350 /* unite the complex decl (specified in the abstract decl) with the
6351 function decl just synthesized..(int *), (int (*)()), (int (*)[]). */
6352 tree save_expr = expr_last (ret_decl);
6354 TREE_OPERAND (save_expr, 0) = method_decl;
6355 method_decl = ret_decl;
6356 /* fool the parser into thinking it is starting a function */
6357 start_function (decl_specs, method_decl, 0);
6358 /* unhook...this has the effect of restoring the abstract declarator */
6359 TREE_OPERAND (save_expr, 0) = NULLT;
6363 TREE_VALUE (TREE_TYPE (method)) = method_decl;
6364 /* fool the parser into thinking it is starting a function */
6365 start_function (decl_specs, method_decl, 0);
6366 /* unhook...this has the effect of restoring the abstract declarator */
6367 TREE_VALUE (TREE_TYPE (method)) = NULLT;
6370 METHOD_DEFINITION (method) = current_function_decl;
6372 /* Check consistency...start_function, pushdecl, duplicate_decls. */
6374 if (implementation_template != implementation_context)
6378 if (TREE_CODE (method) == INSTANCE_METHOD_DECL)
6379 proto = lookup_instance_method_static (implementation_template,
6380 METHOD_SEL_NAME (method));
6382 proto = lookup_class_method_static (implementation_template,
6383 METHOD_SEL_NAME (method));
6385 if (proto && ! comp_method_with_proto (method, proto))
6387 char type = (TREE_CODE (method) == INSTANCE_METHOD_DECL ? '-' : '+');
6389 warn_with_method ("conflicting types for", type, method);
6390 warn_with_method ("previous declaration of", type, proto);
6395 /* The following routine is always called...this "architecture" is to
6396 accommodate "old-style" variable length selectors.
6398 - a:a b:b // prototype ; id c; id d; // old-style. */
6401 continue_method_def ()
6405 if (METHOD_ADD_ARGS (method_context) == (tree)1)
6406 /* We have a `, ...' immediately following the selector. */
6407 parmlist = get_parm_info (0);
6409 parmlist = get_parm_info (1); /* place a `void_at_end' */
6411 /* Set self_decl from the first argument...this global is used by
6412 build_ivar_reference calling build_indirect_ref. */
6413 self_decl = TREE_PURPOSE (parmlist);
6415 poplevel (0, 0, 0); /* must be called BEFORE start_function. */
6417 really_start_method (method_context, parmlist);
6419 store_parm_decls (); /* must be called AFTER start_function. */
6422 /* Called by the parser, from the `pushlevel' production. */
6427 if (!UOBJC_SUPER_decl)
6429 UOBJC_SUPER_decl = start_decl (get_identifier (UTAG_SUPER),
6430 build_tree_list (NULLT,
6431 objc_super_template),
6434 finish_decl (UOBJC_SUPER_decl, NULLT, NULLT);
6436 /* this prevents `unused variable' warnings when compiling with -Wall. */
6437 DECL_IN_SYSTEM_HEADER (UOBJC_SUPER_decl) = 1;
6441 /* _n_Method (id self, SEL sel, ...)
6443 struct objc_super _S;
6444 _msgSuper ((_S.self = self, _S.class = _cls, &_S), ...);
6448 get_super_receiver ()
6452 tree super_expr, super_expr_list;
6454 /* set receiver to self */
6455 super_expr = build_component_ref (UOBJC_SUPER_decl, self_id);
6456 super_expr = build_modify_expr (super_expr, NOP_EXPR, self_decl);
6457 super_expr_list = build_tree_list (NULLT, super_expr);
6459 /* set class to begin searching */
6460 super_expr = build_component_ref (UOBJC_SUPER_decl,
6461 get_identifier ("class"));
6463 if (TREE_CODE (implementation_context) == CLASS_IMPLEMENTATION_TYPE)
6465 /* [_cls, __cls]Super are "pre-built" in
6466 synth_forward_declarations. */
6468 super_expr = build_modify_expr (super_expr, NOP_EXPR,
6469 ((TREE_CODE (method_context)
6470 == INSTANCE_METHOD_DECL)
6472 : uucls_super_ref));
6474 else /* we have a category... */
6476 tree super_name = CLASS_SUPER_NAME (implementation_template);
6479 if (!super_name) /* Barf if super used in a category of Object. */
6481 error ("no super class declared in interface for `%s'",
6482 IDENTIFIER_POINTER (CLASS_NAME (implementation_template)));
6483 return error_mark_node;
6486 if (flag_next_runtime)
6488 super_class = get_class_reference (super_name);
6489 if (TREE_CODE (method_context) == CLASS_METHOD_DECL)
6491 = build_component_ref (build_indirect_ref (super_class, "->"),
6492 get_identifier ("isa"));
6496 add_class_reference (super_name);
6497 super_class = (TREE_CODE (method_context) == INSTANCE_METHOD_DECL
6498 ? objc_get_class_decl : objc_get_meta_class_decl);
6499 assemble_external (super_class);
6501 = build_function_call
6503 build_tree_list (NULLT,
6504 my_build_string (IDENTIFIER_LENGTH (super_name) + 1,
6505 IDENTIFIER_POINTER (super_name))));
6509 TREE_TYPE (super_class) = TREE_TYPE (ucls_super_ref);
6510 super_expr = build_modify_expr (super_expr, NOP_EXPR, super_class);
6512 chainon (super_expr_list, build_tree_list (NULL_TREE, super_expr));
6514 super_expr = build_unary_op (ADDR_EXPR, UOBJC_SUPER_decl, 0);
6515 chainon (super_expr_list, build_tree_list (NULL_TREE, super_expr));
6517 return build_compound_expr (super_expr_list);
6521 error ("[super ...] must appear in a method context");
6522 return error_mark_node;
6527 encode_method_def (func_decl)
6532 int max_parm_end = 0;
6537 encode_type (TREE_TYPE (TREE_TYPE (func_decl)),
6538 obstack_object_size (&util_obstack),
6539 OBJC_ENCODE_INLINE_DEFS);
6541 for (parms = DECL_ARGUMENTS (func_decl); parms;
6542 parms = TREE_CHAIN (parms))
6544 int parm_end = (forwarding_offset (parms)
6545 + (TREE_INT_CST_LOW (TYPE_SIZE (TREE_TYPE (parms)))
6548 if (parm_end > max_parm_end)
6549 max_parm_end = parm_end;
6552 stack_size = max_parm_end - OBJC_FORWARDING_MIN_OFFSET;
6554 sprintf (buffer, "%d", stack_size);
6555 obstack_grow (&util_obstack, buffer, strlen (buffer));
6557 /* argument types */
6558 for (parms = DECL_ARGUMENTS (func_decl); parms;
6559 parms = TREE_CHAIN (parms))
6562 encode_type (TREE_TYPE (parms),
6563 obstack_object_size (&util_obstack),
6564 OBJC_ENCODE_INLINE_DEFS);
6566 /* compute offset */
6567 sprintf (buffer, "%d", forwarding_offset (parms));
6568 obstack_grow (&util_obstack, buffer, strlen (buffer));
6571 obstack_1grow (&util_obstack, 0); /* null terminate string */
6572 result = get_identifier (obstack_finish (&util_obstack));
6573 obstack_free (&util_obstack, util_firstobj);
6578 finish_method_def ()
6580 METHOD_ENCODING (method_context) = encode_method_def (current_function_decl);
6582 finish_function (0);
6584 /* this must be done AFTER finish_function, since the optimizer may
6585 find "may be used before set" errors. */
6586 method_context = NULLT; /* required to implement _msgSuper. */
6590 lang_report_error_function (decl)
6595 fprintf (stderr, "In method `%s'\n",
6596 IDENTIFIER_POINTER (METHOD_SEL_NAME (method_context)));
6604 is_complex_decl (type)
6607 return (TREE_CODE (type) == ARRAY_TYPE
6608 || TREE_CODE (type) == FUNCTION_TYPE
6609 || (TREE_CODE (type) == POINTER_TYPE
6610 && TYPE_MAIN_VARIANT (type) != TYPE_MAIN_VARIANT (id_type)));
6614 /* Code to convert a decl node into text for a declaration in C. */
6616 static char tmpbuf[256];
6619 adorn_decl (decl, str)
6623 enum tree_code code = TREE_CODE (decl);
6625 if (code == ARRAY_REF)
6627 tree an_int_cst = TREE_OPERAND (decl, 1);
6629 if (an_int_cst && TREE_CODE (an_int_cst) == INTEGER_CST)
6630 sprintf (str + strlen (str), "[%d]", TREE_INT_CST_LOW (an_int_cst));
6634 else if (code == ARRAY_TYPE)
6636 tree an_int_cst = TYPE_SIZE (decl);
6637 tree array_of = TREE_TYPE (decl);
6639 if (an_int_cst && TREE_CODE (an_int_cst) == INTEGER_TYPE)
6640 sprintf (str + strlen (str), "[%d]",
6641 (TREE_INT_CST_LOW (an_int_cst)
6642 / TREE_INT_CST_LOW (TYPE_SIZE (array_of))));
6646 else if (code == CALL_EXPR)
6648 tree chain = TREE_PURPOSE (TREE_OPERAND (decl, 1));
6653 gen_declaration (chain, str);
6654 chain = TREE_CHAIN (chain);
6660 else if (code == FUNCTION_TYPE)
6662 tree chain = TYPE_ARG_TYPES (decl); /* a list of types */
6665 while (chain && TREE_VALUE (chain) != void_type_node)
6667 gen_declaration (TREE_VALUE (chain), str);
6668 chain = TREE_CHAIN (chain);
6669 if (chain && TREE_VALUE (chain) != void_type_node)
6674 else if (code == INDIRECT_REF)
6676 strcpy (tmpbuf, "*");
6677 if (TREE_TYPE (decl) && TREE_CODE (TREE_TYPE (decl)) == TREE_LIST)
6681 for (chain = nreverse (copy_list (TREE_TYPE (decl)));
6683 chain = TREE_CHAIN (chain))
6685 if (TREE_CODE (TREE_VALUE (chain)) == IDENTIFIER_NODE)
6687 strcat (tmpbuf, " ");
6688 strcat (tmpbuf, IDENTIFIER_POINTER (TREE_VALUE (chain)));
6692 strcat (tmpbuf, " ");
6694 strcat (tmpbuf, str);
6695 strcpy (str, tmpbuf);
6697 else if (code == POINTER_TYPE)
6699 strcpy (tmpbuf, "*");
6700 if (TREE_READONLY (decl) || TYPE_VOLATILE (decl))
6702 if (TREE_READONLY (decl))
6703 strcat (tmpbuf, " const");
6704 if (TYPE_VOLATILE (decl))
6705 strcat (tmpbuf, " volatile");
6707 strcat (tmpbuf, " ");
6709 strcat (tmpbuf, str);
6710 strcpy (str, tmpbuf);
6715 gen_declarator (decl, buf, name)
6722 enum tree_code code = TREE_CODE (decl);
6732 op = TREE_OPERAND (decl, 0);
6734 /* we have a pointer to a function or array...(*)(), (*)[] */
6735 if ((code == ARRAY_REF || code == CALL_EXPR)
6736 && op && TREE_CODE (op) == INDIRECT_REF)
6739 str = gen_declarator (op, buf, name);
6743 strcpy (tmpbuf, "(");
6744 strcat (tmpbuf, str);
6745 strcat (tmpbuf, ")");
6746 strcpy (str, tmpbuf);
6749 adorn_decl (decl, str);
6755 str = strcpy (buf, name);
6757 /* this clause is done iteratively...rather than recursively */
6760 op = (is_complex_decl (TREE_TYPE (decl))
6761 ? TREE_TYPE (decl) : NULLT);
6763 adorn_decl (decl, str);
6765 /* we have a pointer to a function or array...(*)(), (*)[] */
6766 if (code == POINTER_TYPE
6767 && op && (TREE_CODE (op) == FUNCTION_TYPE
6768 || TREE_CODE (op) == ARRAY_TYPE))
6770 strcpy (tmpbuf, "(");
6771 strcat (tmpbuf, str);
6772 strcat (tmpbuf, ")");
6773 strcpy (str, tmpbuf);
6776 decl = (is_complex_decl (TREE_TYPE (decl))
6777 ? TREE_TYPE (decl) : NULLT);
6779 while (decl && (code = TREE_CODE (decl)));
6783 case IDENTIFIER_NODE:
6784 /* will only happen if we are processing a "raw" expr-decl. */
6785 return strcpy (buf, IDENTIFIER_POINTER (decl));
6790 else /* we have an abstract declarator or a _DECL node */
6791 return strcpy (buf, name);
6795 gen_declspecs (declspecs, buf, raw)
6804 for (chain = nreverse (copy_list (declspecs));
6805 chain; chain = TREE_CHAIN (chain))
6807 tree aspec = TREE_VALUE (chain);
6809 if (TREE_CODE (aspec) == IDENTIFIER_NODE)
6810 strcat (buf, IDENTIFIER_POINTER (aspec));
6811 else if (TREE_CODE (aspec) == RECORD_TYPE)
6813 if (TYPE_NAME (aspec))
6815 tree protocol_list = TYPE_PROTOCOL_LIST (aspec);
6817 if (! TREE_STATIC_TEMPLATE (aspec))
6818 strcat (buf, "struct ");
6819 strcat (buf, IDENTIFIER_POINTER (TYPE_NAME (aspec)));
6824 tree chain = protocol_list;
6829 strcat (buf, IDENTIFIER_POINTER (PROTOCOL_NAME (TREE_VALUE (chain))));
6830 chain = TREE_CHAIN (chain);
6838 strcat (buf, "untagged struct");
6840 else if (TREE_CODE (aspec) == UNION_TYPE)
6842 if (TYPE_NAME (aspec))
6844 if (! TREE_STATIC_TEMPLATE (aspec))
6845 strcat (buf, "union ");
6846 strcat (buf, IDENTIFIER_POINTER (TYPE_NAME (aspec)));
6849 strcat (buf, "untagged union");
6851 else if (TREE_CODE (aspec) == ENUMERAL_TYPE)
6853 if (TYPE_NAME (aspec))
6855 if (! TREE_STATIC_TEMPLATE (aspec))
6856 strcat (buf, "enum ");
6857 strcat (buf, IDENTIFIER_POINTER (TYPE_NAME (aspec)));
6860 strcat (buf, "untagged enum");
6862 else if (TREE_CODE (aspec) == TYPE_DECL && DECL_NAME (aspec))
6864 strcat (buf, IDENTIFIER_POINTER (DECL_NAME (aspec)));
6867 else if (TREE_CODE (aspec) == POINTER_TYPE
6868 && TYPE_MAIN_VARIANT (aspec) == TYPE_MAIN_VARIANT (id_type))
6870 tree protocol_list = TYPE_PROTOCOL_LIST (aspec);
6875 tree chain = protocol_list;
6880 strcat (buf, IDENTIFIER_POINTER (PROTOCOL_NAME (TREE_VALUE (chain))));
6881 chain = TREE_CHAIN (chain);
6888 if (TREE_CHAIN (chain))
6894 /* type qualifiers */
6896 if (TREE_READONLY (declspecs))
6897 strcat (buf, "const ");
6898 if (TYPE_VOLATILE (declspecs))
6899 strcat (buf, "volatile ");
6901 switch (TREE_CODE (declspecs))
6903 /* type specifiers */
6905 case INTEGER_TYPE: /* signed integer types */
6906 declspecs = TYPE_MAIN_VARIANT (declspecs);
6908 if (declspecs == short_integer_type_node) /* 's' */
6909 strcat (buf, "short int ");
6910 else if (declspecs == integer_type_node) /* 'i' */
6911 strcat (buf, "int ");
6912 else if (declspecs == long_integer_type_node) /* 'l' */
6913 strcat (buf, "long int ");
6914 else if (declspecs == long_long_integer_type_node) /* 'l' */
6915 strcat (buf, "long long int ");
6916 else if (declspecs == signed_char_type_node /* 'c' */
6917 || declspecs == char_type_node)
6918 strcat (buf, "char ");
6920 /* unsigned integer types */
6922 else if (declspecs == short_unsigned_type_node) /* 'S' */
6923 strcat (buf, "unsigned short ");
6924 else if (declspecs == unsigned_type_node) /* 'I' */
6925 strcat (buf, "unsigned int ");
6926 else if (declspecs == long_unsigned_type_node) /* 'L' */
6927 strcat (buf, "unsigned long ");
6928 else if (declspecs == long_long_unsigned_type_node) /* 'L' */
6929 strcat (buf, "unsigned long long ");
6930 else if (declspecs == unsigned_char_type_node) /* 'C' */
6931 strcat (buf, "unsigned char ");
6934 case REAL_TYPE: /* floating point types */
6935 declspecs = TYPE_MAIN_VARIANT (declspecs);
6937 if (declspecs == float_type_node) /* 'f' */
6938 strcat (buf, "float ");
6939 else if (declspecs == double_type_node) /* 'd' */
6940 strcat (buf, "double ");
6941 else if (declspecs == long_double_type_node) /* 'd' */
6942 strcat (buf, "long double ");
6946 if (TYPE_NAME (declspecs)
6947 && TREE_CODE (TYPE_NAME (declspecs)) == IDENTIFIER_NODE)
6949 tree protocol_list = TYPE_PROTOCOL_LIST (declspecs);
6951 if (! TREE_STATIC_TEMPLATE (declspecs))
6952 strcat (buf, "struct ");
6953 strcat (buf, IDENTIFIER_POINTER (TYPE_NAME (declspecs)));
6957 tree chain = protocol_list;
6962 strcat (buf, IDENTIFIER_POINTER (PROTOCOL_NAME (TREE_VALUE (chain))));
6963 chain = TREE_CHAIN (chain);
6971 strcat (buf, "untagged struct");
6977 if (TYPE_NAME (declspecs)
6978 && TREE_CODE (TYPE_NAME (declspecs)) == IDENTIFIER_NODE)
6980 strcat (buf, "union ");
6981 strcat (buf, IDENTIFIER_POINTER (TYPE_NAME (declspecs)));
6985 strcat (buf, "untagged union ");
6989 if (TYPE_NAME (declspecs)
6990 && TREE_CODE (TYPE_NAME (declspecs)) == IDENTIFIER_NODE)
6992 strcat (buf, "enum ");
6993 strcat (buf, IDENTIFIER_POINTER (TYPE_NAME (declspecs)));
6997 strcat (buf, "untagged enum ");
7001 strcat (buf, "void ");
7007 tree protocol_list = TYPE_PROTOCOL_LIST (declspecs);
7012 tree chain = protocol_list;
7017 strcat (buf, IDENTIFIER_POINTER (PROTOCOL_NAME (TREE_VALUE (chain))));
7018 chain = TREE_CHAIN (chain);
7030 gen_declaration (atype_or_adecl, buf)
7031 tree atype_or_adecl;
7036 if (TREE_CODE (atype_or_adecl) == TREE_LIST)
7038 tree declspecs; /* "identifier_node", "record_type" */
7039 tree declarator; /* "array_ref", "indirect_ref", "call_expr"... */
7041 /* we have a "raw", abstract declarator (typename) */
7042 declarator = TREE_VALUE (atype_or_adecl);
7043 declspecs = TREE_PURPOSE (atype_or_adecl);
7045 gen_declspecs (declspecs, buf, 1);
7049 strcat (buf, gen_declarator (declarator, declbuf, ""));
7055 tree declspecs; /* "integer_type", "real_type", "record_type"... */
7056 tree declarator; /* "array_type", "function_type", "pointer_type". */
7058 if (TREE_CODE (atype_or_adecl) == FIELD_DECL
7059 || TREE_CODE (atype_or_adecl) == PARM_DECL
7060 || TREE_CODE (atype_or_adecl) == FUNCTION_DECL)
7061 atype = TREE_TYPE (atype_or_adecl);
7063 atype = atype_or_adecl; /* assume we have a *_type node */
7065 if (is_complex_decl (atype))
7069 /* get the declaration specifier...it is at the end of the list */
7070 declarator = chain = atype;
7072 chain = TREE_TYPE (chain); /* not TREE_CHAIN (chain); */
7073 while (is_complex_decl (chain));
7082 gen_declspecs (declspecs, buf, 0);
7084 if (TREE_CODE (atype_or_adecl) == FIELD_DECL
7085 || TREE_CODE (atype_or_adecl) == PARM_DECL
7086 || TREE_CODE (atype_or_adecl) == FUNCTION_DECL)
7088 char *decl_name = (DECL_NAME (atype_or_adecl)
7089 ? IDENTIFIER_POINTER (DECL_NAME (atype_or_adecl))
7095 strcat (buf, gen_declarator (declarator, declbuf, decl_name));
7097 else if (decl_name[0])
7100 strcat (buf, decl_name);
7103 else if (declarator)
7106 strcat (buf, gen_declarator (declarator, declbuf, ""));
7112 #define RAW_TYPESPEC(meth) (TREE_VALUE (TREE_PURPOSE (TREE_TYPE (meth))))
7115 gen_method_decl (method, buf)
7121 if (RAW_TYPESPEC (method) != objc_object_reference)
7124 gen_declaration (TREE_TYPE (method), buf);
7128 chain = METHOD_SEL_ARGS (method);
7130 { /* we have a chain of keyword_decls */
7133 if (KEYWORD_KEY_NAME (chain))
7134 strcat (buf, IDENTIFIER_POINTER (KEYWORD_KEY_NAME (chain)));
7137 if (RAW_TYPESPEC (chain) != objc_object_reference)
7140 gen_declaration (TREE_TYPE (chain), buf);
7143 strcat (buf, IDENTIFIER_POINTER (KEYWORD_ARG_NAME (chain)));
7144 if ((chain = TREE_CHAIN (chain)))
7149 if (METHOD_ADD_ARGS (method) == (tree)1)
7150 strcat (buf, ", ...");
7151 else if (METHOD_ADD_ARGS (method))
7153 /* we have a tree list node as generate by get_parm_info. */
7154 chain = TREE_PURPOSE (METHOD_ADD_ARGS (method));
7155 /* know we have a chain of parm_decls */
7159 gen_declaration (chain, buf);
7160 chain = TREE_CHAIN (chain);
7164 else /* we have a unary selector */
7165 strcat (buf, IDENTIFIER_POINTER (METHOD_SEL_NAME (method)));
7173 dump_interface (fp, chain)
7177 char *buf = (char *)xmalloc (256);
7178 char *my_name = IDENTIFIER_POINTER (CLASS_NAME (chain));
7179 tree ivar_decls = CLASS_RAW_IVARS (chain);
7180 tree nst_methods = CLASS_NST_METHODS (chain);
7181 tree cls_methods = CLASS_CLS_METHODS (chain);
7183 fprintf (fp, "\n@interface %s", my_name);
7185 if (CLASS_SUPER_NAME (chain))
7187 char *super_name = IDENTIFIER_POINTER (CLASS_SUPER_NAME (chain));
7188 fprintf (fp, " : %s\n", super_name);
7195 fprintf (fp, "{\n");
7199 fprintf (fp, "\t%s;\n", gen_declaration (ivar_decls, buf));
7200 ivar_decls = TREE_CHAIN (ivar_decls);
7203 fprintf (fp, "}\n");
7209 fprintf (fp, "- %s;\n", gen_method_decl (nst_methods, buf));
7210 nst_methods = TREE_CHAIN (nst_methods);
7216 fprintf (fp, "+ %s;\n", gen_method_decl (cls_methods, buf));
7217 cls_methods = TREE_CHAIN (cls_methods);
7219 fprintf (fp, "\n@end");
7225 /* Add the special tree codes of Objective C to the tables. */
7227 #define LAST_CODE LAST_AND_UNUSED_TREE_CODE
7229 gcc_obstack_init (&util_obstack);
7230 util_firstobj = (char *) obstack_finish (&util_obstack);
7233 = (char **) xrealloc (tree_code_type,
7234 sizeof (char *) * LAST_OBJC_TREE_CODE);
7236 = (int *) xrealloc (tree_code_length,
7237 sizeof (int) * LAST_OBJC_TREE_CODE);
7239 = (char **) xrealloc (tree_code_name,
7240 sizeof (char *) * LAST_OBJC_TREE_CODE);
7241 bcopy (objc_tree_code_type,
7242 tree_code_type + (int) LAST_CODE,
7243 (((int) LAST_OBJC_TREE_CODE - (int) LAST_CODE)
7244 * sizeof (char *)));
7245 bcopy (objc_tree_code_length,
7246 tree_code_length + (int) LAST_CODE,
7247 (((int) LAST_OBJC_TREE_CODE - (int) LAST_CODE)
7249 bcopy (objc_tree_code_name,
7250 tree_code_name + (int) LAST_CODE,
7251 (((int) LAST_OBJC_TREE_CODE - (int) LAST_CODE)
7252 * sizeof (char *)));
7254 errbuf = (char *)xmalloc (BUFSIZE);
7256 synth_module_prologue ();
7262 struct imp_entry *impent;
7264 /* The internally generated initializers appear to have missing braces.
7265 Don't warn about this. */
7266 int save_warn_missing_braces = warn_missing_braces;
7267 warn_missing_braces = 0;
7269 generate_forward_declaration_to_string_table ();
7271 #ifdef OBJC_PROLOGUE
7275 if (implementation_context || class_names_chain
7276 || meth_var_names_chain || meth_var_types_chain || sel_ref_chain)
7277 generate_objc_symtab_decl ();
7279 for (impent = imp_list; impent; impent = impent->next)
7281 implementation_context = impent->imp_context;
7282 implementation_template = impent->imp_template;
7284 UOBJC_CLASS_decl = impent->class_decl;
7285 UOBJC_METACLASS_decl = impent->meta_decl;
7287 if (TREE_CODE (implementation_context) == CLASS_IMPLEMENTATION_TYPE)
7289 /* all of the following reference the string pool... */
7290 generate_ivar_lists ();
7291 generate_dispatch_tables ();
7292 generate_shared_structures ();
7296 generate_dispatch_tables ();
7297 generate_category (implementation_context);
7301 /* If we are using an array of selectors, we must always
7302 finish up the array decl even if no selectors were used. */
7303 if (! flag_next_runtime || sel_ref_chain)
7304 build_selector_translation_table ();
7307 generate_protocols ();
7309 if (implementation_context || class_names_chain
7310 || meth_var_names_chain || meth_var_types_chain || sel_ref_chain)
7312 /* Arrange for Objc data structures to be initialized at run time. */
7313 char *init_name = build_module_descriptor ();
7315 assemble_constructor (init_name);
7318 /* dump the class references...this forces the appropriate classes
7319 to be linked into the executable image, preserving unix archive
7320 semantics...this can be removed when we move to a more dynamically
7321 linked environment. */
7322 for (chain = cls_ref_chain; chain; chain = TREE_CHAIN (chain))
7324 handle_class_ref (chain);
7325 if (TREE_PURPOSE (chain))
7326 generate_classref_translation_entry (chain);
7329 for (impent = imp_list; impent; impent = impent->next)
7330 handle_impent (impent);
7332 /* dump the string table last */
7334 generate_strings ();
7336 if (flag_gen_declaration)
7338 add_class (implementation_context);
7339 dump_interface (gen_declaration_file, implementation_context);
7347 /* Run through the selector hash tables and print a warning for any
7348 selector which has multiple methods. */
7350 for (slot = 0; slot < SIZEHASHTABLE; slot++)
7351 for (hsh = cls_method_hash_list[slot]; hsh; hsh = hsh->next)
7354 tree meth = hsh->key;
7355 char type = (TREE_CODE (meth) == INSTANCE_METHOD_DECL
7359 warning ("potential selector conflict for method `%s'",
7360 IDENTIFIER_POINTER (METHOD_SEL_NAME (meth)));
7361 warn_with_method ("found", type, meth);
7362 for (loop = hsh->list; loop; loop = loop->next)
7363 warn_with_method ("found", type, loop->value);
7366 for (slot = 0; slot < SIZEHASHTABLE; slot++)
7367 for (hsh = nst_method_hash_list[slot]; hsh; hsh = hsh->next)
7370 tree meth = hsh->key;
7371 char type = (TREE_CODE (meth) == INSTANCE_METHOD_DECL
7375 warning ("potential selector conflict for method `%s'",
7376 IDENTIFIER_POINTER (METHOD_SEL_NAME (meth)));
7377 warn_with_method ("found", type, meth);
7378 for (loop = hsh->list; loop; loop = loop->next)
7379 warn_with_method ("found", type, loop->value);
7383 warn_missing_braces = save_warn_missing_braces;
7386 /* Subroutines of finish_objc. */
7389 generate_classref_translation_entry (chain)
7392 tree expr, name, decl_specs, decl, sc_spec;
7395 type = TREE_TYPE (TREE_PURPOSE (chain));
7397 expr = add_objc_string (TREE_VALUE (chain), class_names);
7398 expr = build_c_cast (type, expr); /* cast! */
7400 name = DECL_NAME (TREE_PURPOSE (chain));
7402 sc_spec = build_tree_list (NULLT, ridpointers[(int) RID_STATIC]);
7404 /* static struct objc_class * _OBJC_CLASS_REFERENCES_n = ...; */
7405 decl_specs = tree_cons (NULLT, type, sc_spec);
7407 /* the `decl' that is returned from start_decl is the one that we
7408 forward declared in `build_class_reference'. */
7409 decl = start_decl (name, decl_specs, 1);
7410 end_temporary_allocation ();
7411 finish_decl (decl, expr, NULLT);
7416 handle_class_ref (chain)
7419 char *name = IDENTIFIER_POINTER (TREE_VALUE (chain));
7420 if (! flag_next_runtime)
7423 char *string = (char *) alloca (strlen (name) + 30);
7425 sprintf (string, "%sobjc_class_name_%s",
7426 (flag_next_runtime ? "." : "__"), name);
7428 /* Make a decl for this name, so we can use its address in a tree. */
7429 decl = build_decl (VAR_DECL, get_identifier (string), char_type_node);
7430 DECL_EXTERNAL (decl) = 1;
7431 TREE_PUBLIC (decl) = 1;
7434 rest_of_decl_compilation (decl, 0, 0, 0);
7436 /* Make following constant read-only (why not)? */
7437 readonly_data_section ();
7439 /* Inform the assembler about this new external thing. */
7440 assemble_external (decl);
7442 /* Output a constant to reference this address. */
7443 output_constant (build1 (ADDR_EXPR, string_type_node, decl),
7444 int_size_in_bytes (string_type_node));
7448 /* This overreliance on our assembler (i.e. lack of portability)
7449 should be dealt with at some point. The GNU strategy (above)
7450 won't work either, but it is a start. */
7451 char *string = (char *) alloca (strlen (name) + 30);
7452 sprintf (string, ".reference .objc_class_name_%s", name);
7453 assemble_asm (my_build_string (strlen (string) + 1, string));
7458 handle_impent (impent)
7459 struct imp_entry *impent;
7461 implementation_context = impent->imp_context;
7462 implementation_template = impent->imp_template;
7464 if (TREE_CODE (impent->imp_context) == CLASS_IMPLEMENTATION_TYPE)
7466 char *class_name = IDENTIFIER_POINTER (CLASS_NAME (impent->imp_context));
7467 char *string = (char *) alloca (strlen (class_name) + 30);
7469 if (flag_next_runtime)
7471 /* Grossly unportable.
7472 People should know better than to assume
7473 such things about assembler syntax! */
7474 sprintf (string, ".objc_class_name_%s=0", class_name);
7475 assemble_asm (my_build_string (strlen (string) + 1, string));
7477 sprintf (string, ".globl .objc_class_name_%s", class_name);
7478 assemble_asm (my_build_string (strlen (string) + 1, string));
7482 sprintf (string, "%sobjc_class_name_%s",
7483 (flag_next_runtime ? "." : "__"), class_name);
7484 assemble_global (string);
7485 assemble_label (string);
7488 else if (TREE_CODE (impent->imp_context) == CATEGORY_IMPLEMENTATION_TYPE)
7490 char *class_name = IDENTIFIER_POINTER (CLASS_NAME (impent->imp_context));
7491 char *class_super_name
7492 = IDENTIFIER_POINTER (CLASS_SUPER_NAME (impent->imp_context));
7493 char *string = (char *) alloca (strlen (class_name)
7494 + strlen (class_super_name) + 30);
7496 /* Do the same for categories. Even though no references to these
7497 symbols are generated automatically by the compiler, it gives
7498 you a handle to pull them into an archive by hand. */
7499 if (flag_next_runtime)
7501 /* Grossly unportable. */
7502 sprintf (string, ".objc_category_name_%s_%s=0",
7503 class_name, class_super_name);
7504 assemble_asm (my_build_string (strlen (string) + 1, string));
7506 sprintf (string, ".globl .objc_category_name_%s_%s",
7507 class_name, class_super_name);
7508 assemble_asm (my_build_string (strlen (string) + 1, string));
7512 sprintf (string, "%sobjc_category_name_%s_%s",
7513 (flag_next_runtime ? "." : "__"),
7514 class_name, class_super_name);
7515 assemble_global (string);
7516 assemble_label (string);
7527 char *buf = (char *)xmalloc (256);
7529 { /* dump function prototypes */
7530 tree loop = UOBJC_MODULES_decl;
7532 fprintf (fp, "\n\nfunction prototypes:\n");
7535 if (TREE_CODE (loop) == FUNCTION_DECL && DECL_INITIAL (loop))
7537 /* we have a function definition - generate prototype */
7538 bzero (errbuf, BUFSIZE);
7539 gen_declaration (loop, errbuf);
7540 fprintf (fp, "%s;\n", errbuf);
7542 loop = TREE_CHAIN (loop);
7545 { /* dump global chains */
7547 int i, index = 0, offset = 0;
7550 for (i = 0; i < SIZEHASHTABLE; i++)
7552 if (hashlist = nst_method_hash_list[i])
7554 fprintf (fp, "\n\nnst_method_hash_list[%d]:\n", i);
7558 fprintf (fp, "-%s;\n", gen_method_decl (hashlist->key, buf));
7559 hashlist = hashlist->next;
7564 for (i = 0; i < SIZEHASHTABLE; i++)
7566 if (hashlist = cls_method_hash_list[i])
7568 fprintf (fp, "\n\ncls_method_hash_list[%d]:\n", i);
7572 fprintf (fp, "-%s;\n", gen_method_decl (hashlist->key, buf));
7573 hashlist = hashlist->next;
7578 fprintf (fp, "\nsel_refdef_chain:\n");
7579 for (loop = sel_refdef_chain; loop; loop = TREE_CHAIN (loop))
7581 fprintf (fp, "(index: %4d offset: %4d) %s\n", index, offset,
7582 IDENTIFIER_POINTER (TREE_VALUE (loop)));
7584 /* add one for the '\0' character */
7585 offset += IDENTIFIER_LENGTH (TREE_VALUE (loop)) + 1;
7587 fprintf (fp, "\n (max_selector_index: %4d.\n", max_selector_index);
7593 print_lang_statistics ()