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_%s", \
59 ((IS_INST) ? "i" : "c"), \
61 ((CAT_NAME)? (CAT_NAME) : ""), \
63 for (temp = (BUF); *temp; temp++) \
64 if (*temp == ':') *temp = '_'; \
68 /* These need specifying. */
69 #ifndef OBJC_FORWARDING_STACK_OFFSET
70 #define OBJC_FORWARDING_STACK_OFFSET 0
73 #ifndef OBJC_FORWARDING_MIN_OFFSET
74 #define OBJC_FORWARDING_MIN_OFFSET 0
77 /* Define the special tree codes that we use. */
79 /* Table indexed by tree code giving a string containing a character
80 classifying the tree code. Possibilities are
81 t, d, s, c, r, <, 1 and 2. See objc-tree.def for details. */
83 #define DEFTREECODE(SYM, NAME, TYPE, LENGTH) TYPE,
85 char *objc_tree_code_type[] = {
87 #include "objc-tree.def"
91 /* Table indexed by tree code giving number of expression
92 operands beyond the fixed part of the node structure.
93 Not used for types or decls. */
95 #define DEFTREECODE(SYM, NAME, TYPE, LENGTH) LENGTH,
97 int objc_tree_code_length[] = {
99 #include "objc-tree.def"
103 /* Names of tree components.
104 Used for printing out the tree and error messages. */
105 #define DEFTREECODE(SYM, NAME, TYPE, LEN) NAME,
107 char *objc_tree_code_name[] = {
109 #include "objc-tree.def"
113 /* Set up for use of obstacks. */
117 #define obstack_chunk_alloc xmalloc
118 #define obstack_chunk_free free
120 /* This obstack is used to accumulate the encoding of a data type. */
121 static struct obstack util_obstack;
122 /* This points to the beginning of obstack contents,
123 so we can free the whole contents. */
126 /* for encode_method_def */
130 #define OBJC_VERSION 5
131 #define PROTOCOL_VERSION 2
133 #define NULLT (tree) 0
135 #define OBJC_ENCODE_INLINE_DEFS 0
136 #define OBJC_ENCODE_DONT_INLINE_DEFS 1
138 /*** Private Interface (procedures) ***/
140 /* used by compile_file */
142 static void init_objc PROTO((void));
143 static void finish_objc PROTO((void));
145 /* code generation */
147 static void synth_module_prologue PROTO((void));
148 static char *build_module_descriptor PROTO((void));
149 static tree init_module_descriptor PROTO((void));
150 static tree build_objc_method_call PROTO((int, tree, tree, tree, tree, tree));
151 static void generate_strings PROTO((void));
152 static void build_selector_translation_table PROTO((void));
153 static tree build_ivar_chain PROTO((tree, int));
155 static tree build_ivar_template PROTO((void));
156 static tree build_method_template PROTO((void));
157 static tree build_private_template PROTO((tree));
158 static void build_class_template PROTO((void));
159 static void build_category_template PROTO((void));
160 static tree build_super_template PROTO((void));
161 static tree build_category_initializer PROTO((tree, tree, tree, tree, tree));
162 static tree build_protocol_initializer PROTO((tree, tree, tree, tree));
164 static void synth_forward_declarations PROTO((void));
165 static void generate_ivar_lists PROTO((void));
166 static void generate_dispatch_tables PROTO((void));
167 static void generate_shared_structures PROTO((void));
168 static tree generate_protocol_list PROTO((tree));
169 static void generate_forward_declaration_to_string_table PROTO((void));
170 static void build_protocol_reference PROTO((tree));
172 static tree init_selector PROTO((int));
173 static tree build_keyword_selector PROTO((tree));
174 static tree synth_id_with_class_suffix PROTO((char *, tree));
176 /* misc. bookkeeping */
178 typedef struct hashed_entry *hash;
179 typedef struct hashed_attribute *attr;
181 struct hashed_attribute
193 static void hash_init PROTO((void));
194 static void hash_enter PROTO((hash *, tree));
195 static hash hash_lookup PROTO((hash *, tree));
196 static void hash_add_attr PROTO((hash, tree));
197 static tree lookup_method PROTO((tree, tree));
198 static tree lookup_instance_method_static PROTO((tree, tree));
199 static tree lookup_class_method_static PROTO((tree, tree));
200 static tree add_class PROTO((tree));
201 static void add_category PROTO((tree, tree));
205 class_names, /* class, category, protocol, module names */
206 meth_var_names, /* method and variable names */
207 meth_var_types /* method and variable type descriptors */
210 static tree add_objc_string PROTO((tree, enum string_section));
211 static tree build_objc_string_decl PROTO((tree, enum string_section));
212 static tree build_selector_reference_decl PROTO((tree));
214 /* protocol additions */
216 static tree add_protocol PROTO((tree));
217 static tree lookup_protocol PROTO((tree));
218 static tree lookup_and_install_protocols PROTO((tree));
222 static void encode_type_qualifiers PROTO((tree));
223 static void encode_pointer PROTO((tree, int, int));
224 static void encode_array PROTO((tree, int, int));
225 static void encode_aggregate PROTO((tree, int, int));
226 static void encode_bitfield PROTO((int, int));
227 static void encode_type PROTO((tree, int, int));
228 static void encode_field_decl PROTO((tree, int, int));
230 static void really_start_method PROTO((tree, tree));
231 static int comp_method_with_proto PROTO((tree, tree));
232 static int comp_proto_with_proto PROTO((tree, tree));
233 static tree get_arg_type_list PROTO((tree, int, int));
234 static tree expr_last PROTO((tree));
236 /* utilities for debugging and error diagnostics: */
238 static void warn_with_method PROTO((char *, int, tree));
239 static void error_with_ivar PROTO((char *, tree, tree));
240 static char *gen_method_decl PROTO((tree, char *));
241 static char *gen_declaration PROTO((tree, char *));
242 static char *gen_declarator PROTO((tree, char *, char *));
243 static int is_complex_decl PROTO((tree));
244 static void adorn_decl PROTO((tree, char *));
245 static void dump_interface PROTO((FILE *, tree));
247 /* everything else. */
249 static void objc_fatal PROTO((void));
250 static tree define_decl PROTO((tree, tree));
251 static tree lookup_method_in_protocol_list PROTO((tree, tree, int));
252 static tree lookup_protocol_in_reflist PROTO((tree, tree));
253 static tree create_builtin_decl PROTO((enum tree_code, tree, char *));
254 static tree my_build_string PROTO((int, char *));
255 static void build_objc_symtab_template PROTO((void));
256 static tree init_def_list PROTO((void));
257 static tree init_objc_symtab PROTO((void));
258 static void forward_declare_categories PROTO((void));
259 static void generate_objc_symtab_decl PROTO((void));
260 static tree build_selector PROTO((tree));
261 static tree build_msg_pool_reference PROTO((int));
262 static tree build_selector_reference PROTO((tree));
263 static tree build_class_reference_decl PROTO((tree));
264 static void add_class_reference PROTO((tree));
265 static tree objc_copy_list PROTO((tree, tree *));
266 static tree build_protocol_template PROTO((void));
267 static tree build_descriptor_table_initializer PROTO((tree, int *));
268 static tree build_method_prototype_list_template PROTO((tree, int));
269 static tree build_method_prototype_template PROTO((void));
270 static int forwarding_offset PROTO((tree));
271 static tree encode_method_prototype PROTO((tree, tree));
272 static tree generate_descriptor_table PROTO((tree, char *, int, tree, tree));
273 static void generate_method_descriptors PROTO((tree));
274 static tree build_tmp_function_decl PROTO((void));
275 static void hack_method_prototype PROTO((tree, tree));
276 static void generate_protocol_references PROTO((tree));
277 static void generate_protocols PROTO((void));
278 static void check_ivars PROTO((tree, tree));
279 static tree build_ivar_list_template PROTO((tree, int));
280 static tree build_method_list_template PROTO((tree, int));
281 static tree build_ivar_list_initializer PROTO((tree, int *));
282 static tree generate_ivars_list PROTO((tree, char *, int, tree));
283 static tree build_dispatch_table_initializer PROTO((tree, int *));
284 static tree generate_dispatch_table PROTO((tree, char *, int, tree));
285 static tree build_shared_structure_initializer PROTO((tree, tree, tree, tree, int, tree, tree, tree));
286 static void generate_category PROTO((tree));
287 static int is_objc_type_qualifier PROTO((tree));
288 static tree adjust_type_for_id_default PROTO((tree));
289 static tree check_duplicates PROTO((hash));
290 static tree receiver_is_class_object PROTO((tree));
291 static int check_methods PROTO((tree, tree, int));
292 static int conforms_to_protocol PROTO((tree, tree));
293 static void check_protocols PROTO((tree, char *, char *));
294 static tree encode_method_def PROTO((tree));
295 static void gen_declspecs PROTO((tree, char *, int));
296 static void generate_classref_translation_entry PROTO((tree));
297 static void handle_class_ref PROTO((tree));
299 /*** Private Interface (data) ***/
301 /* reserved tag definitions: */
304 #define TAG_OBJECT "objc_object"
305 #define TAG_CLASS "objc_class"
306 #define TAG_SUPER "objc_super"
307 #define TAG_SELECTOR "objc_selector"
309 #define UTAG_CLASS "_objc_class"
310 #define UTAG_IVAR "_objc_ivar"
311 #define UTAG_IVAR_LIST "_objc_ivar_list"
312 #define UTAG_METHOD "_objc_method"
313 #define UTAG_METHOD_LIST "_objc_method_list"
314 #define UTAG_CATEGORY "_objc_category"
315 #define UTAG_MODULE "_objc_module"
316 #define UTAG_SYMTAB "_objc_symtab"
317 #define UTAG_SUPER "_objc_super"
319 #define UTAG_PROTOCOL "_objc_protocol"
320 #define UTAG_PROTOCOL_LIST "_objc_protocol_list"
321 #define UTAG_METHOD_PROTOTYPE "_objc_method_prototype"
322 #define UTAG_METHOD_PROTOTYPE_LIST "_objc__method_prototype_list"
324 #define STRING_OBJECT_CLASS_NAME "NXConstantString"
325 #define PROTOCOL_OBJECT_CLASS_NAME "Protocol"
327 static char* TAG_GETCLASS;
328 static char* TAG_GETMETACLASS;
329 static char* TAG_MSGSEND;
330 static char* TAG_MSGSENDSUPER;
331 static char* TAG_EXECCLASS;
333 /* Set by `continue_class' and checked by `is_public'. */
335 #define TREE_STATIC_TEMPLATE(record_type) (TREE_PUBLIC (record_type))
336 #define TYPED_OBJECT(type) \
337 (TREE_CODE (type) == RECORD_TYPE && TREE_STATIC_TEMPLATE (type))
339 /* Some commonly used instances of "identifier_node". */
341 static tree self_id, ucmd_id;
343 static tree self_decl, umsg_decl, umsg_super_decl;
344 static tree objc_get_class_decl, objc_get_meta_class_decl;
346 static tree super_type, selector_type, id_type, objc_class_type;
347 static tree instance_type, protocol_type;
349 /* Type checking macros. */
351 #define IS_ID(TYPE) \
352 (TYPE_MAIN_VARIANT (TYPE) == TYPE_MAIN_VARIANT (id_type))
353 #define IS_PROTOCOL_QUALIFIED_ID(TYPE) \
354 (IS_ID (TYPE) && TYPE_PROTOCOL_LIST (TYPE))
355 #define IS_SUPER(TYPE) \
356 (super_type && TYPE_MAIN_VARIANT (TYPE) == TYPE_MAIN_VARIANT (super_type))
358 static tree class_chain = NULLT;
359 static tree alias_chain = NULLT;
360 static tree interface_chain = NULLT;
361 static tree protocol_chain = NULLT;
363 /* chains to manage selectors that are referenced and defined in the module */
365 static tree cls_ref_chain = NULLT; /* classes referenced */
366 static tree sel_ref_chain = NULLT; /* selectors referenced */
368 /* chains to manage uniquing of strings */
370 static tree class_names_chain = NULLT;
371 static tree meth_var_names_chain = NULLT;
372 static tree meth_var_types_chain = NULLT;
374 /* hash tables to manage the global pool of method prototypes */
376 static hash *nst_method_hash_list = 0;
377 static hash *cls_method_hash_list = 0;
379 /* backend data declarations */
381 static tree UOBJC_SYMBOLS_decl;
382 static tree UOBJC_INSTANCE_VARIABLES_decl, UOBJC_CLASS_VARIABLES_decl;
383 static tree UOBJC_INSTANCE_METHODS_decl, UOBJC_CLASS_METHODS_decl;
384 static tree UOBJC_CLASS_decl, UOBJC_METACLASS_decl;
385 static tree UOBJC_SELECTOR_TABLE_decl;
386 static tree UOBJC_MODULES_decl;
387 static tree UOBJC_STRINGS_decl;
389 /* The following are used when compiling a class implementation.
390 implementation_template will normally be an interface, however if
391 none exists this will be equal to implementation_context...it is
392 set in start_class. */
394 static tree implementation_context = NULLT,
395 implementation_template = NULLT;
399 struct imp_entry *next;
402 tree class_decl; /* _OBJC_CLASS_<my_name>; */
403 tree meta_decl; /* _OBJC_METACLASS_<my_name>; */
406 static void handle_impent PROTO((struct imp_entry *));
408 static struct imp_entry *imp_list = 0;
409 static int imp_count = 0; /* `@implementation' */
410 static int cat_count = 0; /* `@category' */
412 static tree objc_class_template, objc_category_template, uprivate_record;
413 static tree objc_protocol_template;
414 static tree ucls_super_ref, uucls_super_ref;
416 static tree objc_method_template, objc_ivar_template;
417 static tree objc_symtab_template, objc_module_template;
418 static tree objc_super_template, objc_object_reference;
420 static tree objc_object_id, objc_class_id, objc_id_id;
421 static tree constant_string_id;
422 static tree constant_string_type;
423 static tree UOBJC_SUPER_decl;
425 static tree method_context = NULLT;
426 static int method_slot = 0; /* used by start_method_def */
430 static char *errbuf; /* a buffer for error diagnostics */
432 /* data imported from tree.c */
434 extern struct obstack permanent_obstack, *current_obstack, *rtl_obstack;
436 /* data imported from toplev.c */
438 extern char *dump_base_name;
440 /* Generate code for GNU or NeXT runtime environment. */
442 #ifdef NEXT_OBJC_RUNTIME
443 int flag_next_runtime = 1;
445 int flag_next_runtime = 0;
448 /* Open and close the file for outputting class declarations, if requested. */
450 int flag_gen_declaration = 0;
452 FILE *gen_declaration_file;
454 /* Warn if multiple methods are seen for the same selector, but with
455 different argument types. */
457 int warn_selector = 0;
459 /* Warn if methods required by a protocol are not implemented in the
460 class adopting it. When turned off, methods inherited to that
461 class are also considered implemented */
463 int flag_warn_protocol = 1;
465 /* tells "encode_pointer/encode_aggregate" whether we are generating
466 type descriptors for instance variables (as opposed to methods).
467 Type descriptors for instance variables contain more information
468 than methods (for static typing and embedded structures). This
469 was added to support features being planned for dbkit2. */
471 static int generating_instance_variables = 0;
476 /* the beginning of the file is a new line; check for # */
477 /* With luck, we discover the real source file's name from that
478 and put it in input_filename. */
479 ungetc (check_newline (), finput);
481 /* If gen_declaration desired, open the output file. */
482 if (flag_gen_declaration)
484 int dump_base_name_length = strlen (dump_base_name);
485 register char *dumpname = (char *) xmalloc (dump_base_name_length + 7);
486 strcpy (dumpname, dump_base_name);
487 strcat (dumpname, ".decl");
488 gen_declaration_file = fopen (dumpname, "w");
489 if (gen_declaration_file == 0)
490 pfatal_with_name (dumpname);
493 if (flag_next_runtime)
495 TAG_GETCLASS = "objc_getClass";
496 TAG_GETMETACLASS = "objc_getMetaClass";
497 TAG_MSGSEND = "objc_msgSend";
498 TAG_MSGSENDSUPER = "objc_msgSendSuper";
499 TAG_EXECCLASS = "__objc_execClass";
503 TAG_GETCLASS = "objc_get_class";
504 TAG_GETMETACLASS = "objc_get_meta_class";
505 TAG_MSGSEND = "objc_msg_lookup";
506 TAG_MSGSENDSUPER = "objc_msg_lookup_super";
507 TAG_EXECCLASS = "__objc_exec_class";
510 if (doing_objc_thang)
517 fatal ("Objective-C text in C source file");
523 if (doing_objc_thang)
524 finish_objc (); /* Objective-C finalization */
526 if (gen_declaration_file)
527 fclose (gen_declaration_file);
542 lang_decode_option (p)
545 if (!strcmp (p, "-lang-objc"))
546 doing_objc_thang = 1;
547 else if (!strcmp (p, "-gen-decls"))
548 flag_gen_declaration = 1;
549 else if (!strcmp (p, "-Wselector"))
551 else if (!strcmp (p, "-Wno-selector"))
553 else if (!strcmp (p, "-Wprotocol"))
554 flag_warn_protocol = 1;
555 else if (!strcmp (p, "-Wno-protocol"))
556 flag_warn_protocol = 0;
557 else if (!strcmp (p, "-fgnu-runtime"))
558 flag_next_runtime = 0;
559 else if (!strcmp (p, "-fno-next-runtime"))
560 flag_next_runtime = 0;
561 else if (!strcmp (p, "-fno-gnu-runtime"))
562 flag_next_runtime = 1;
563 else if (!strcmp (p, "-fnext-runtime"))
564 flag_next_runtime = 1;
566 return c_decode_option (p);
572 define_decl (declarator, declspecs)
576 tree decl = start_decl (declarator, declspecs, 0);
577 finish_decl (decl, NULLT, NULLT);
581 /* Return 1 if LHS and RHS are compatible types for assignment or
582 various other operations. Return 0 if they are incompatible, and
583 return -1 if we choose to not decide. When the operation is
584 REFLEXIVE, check for compatibility in either direction.
586 For statically typed objects, an assignment of the form `a' = `b'
590 `a' and `b' are the same class type, or
591 `a' and `b' are of class types A and B such that B is a descendant of A. */
594 maybe_objc_comptypes (lhs, rhs, reflexive)
598 if (doing_objc_thang)
599 return objc_comptypes (lhs, rhs, reflexive);
604 lookup_method_in_protocol_list (rproto_list, sel_name, class_meth)
612 for (rproto = rproto_list; rproto; rproto = TREE_CHAIN (rproto))
614 p = TREE_VALUE (rproto);
616 if (TREE_CODE (p) == PROTOCOL_INTERFACE_TYPE)
618 if ((fnd = lookup_method (class_meth
619 ? PROTOCOL_CLS_METHODS (p)
620 : PROTOCOL_NST_METHODS (p), sel_name)))
622 else if (PROTOCOL_LIST (p))
623 fnd = lookup_method_in_protocol_list (PROTOCOL_LIST (p), sel_name, class_meth);
626 ; /* an identifier...if we could not find a protocol. */
635 lookup_protocol_in_reflist (rproto_list, lproto)
641 /* make sure the protocol is support by the object on the rhs */
642 if (TREE_CODE (lproto) == PROTOCOL_INTERFACE_TYPE)
645 for (rproto = rproto_list; rproto; rproto = TREE_CHAIN (rproto))
647 p = TREE_VALUE (rproto);
649 if (TREE_CODE (p) == PROTOCOL_INTERFACE_TYPE)
654 else if (PROTOCOL_LIST (p))
655 fnd = lookup_protocol_in_reflist (PROTOCOL_LIST (p), lproto);
663 ; /* an identifier...if we could not find a protocol. */
668 /* Return 1 if LHS and RHS are compatible types for assignment
669 or various other operations. Return 0 if they are incompatible,
670 and return -1 if we choose to not decide. When the operation
671 is REFLEXIVE, check for compatibility in either direction. */
674 objc_comptypes (lhs, rhs, reflexive)
679 /* new clause for protocols */
681 if (TREE_CODE (lhs) == POINTER_TYPE
682 && TREE_CODE (TREE_TYPE (lhs)) == RECORD_TYPE
683 && TREE_CODE (rhs) == POINTER_TYPE
684 && TREE_CODE (TREE_TYPE (rhs)) == RECORD_TYPE)
686 int lhs_is_proto = IS_PROTOCOL_QUALIFIED_ID (lhs);
687 int rhs_is_proto = IS_PROTOCOL_QUALIFIED_ID (rhs);
691 tree lproto, lproto_list = TYPE_PROTOCOL_LIST (lhs);
692 tree rproto, rproto_list;
697 rproto_list = TYPE_PROTOCOL_LIST (rhs);
699 /* Make sure the protocol is supported by the object
701 for (lproto = lproto_list; lproto; lproto = TREE_CHAIN (lproto))
703 p = TREE_VALUE (lproto);
704 rproto = lookup_protocol_in_reflist (rproto_list, p);
707 warning ("object does not conform to the `%s' protocol",
708 IDENTIFIER_POINTER (PROTOCOL_NAME (p)));
711 else if (TYPED_OBJECT (TREE_TYPE (rhs)))
713 tree rname = TYPE_NAME (TREE_TYPE (rhs));
716 /* Make sure the protocol is supported by the object
718 for (lproto = lproto_list; lproto; lproto = TREE_CHAIN (lproto))
720 p = TREE_VALUE (lproto);
722 rinter = lookup_interface (rname);
724 while (rinter && !rproto)
728 rproto_list = CLASS_PROTOCOL_LIST (rinter);
729 rproto = lookup_protocol_in_reflist (rproto_list, p);
732 /* Check for protocols adopted by categories. */
733 cat = CLASS_CATEGORY_LIST (rinter);
734 while (cat && !rproto)
736 rproto_list = CLASS_PROTOCOL_LIST (cat);
737 rproto = lookup_protocol_in_reflist (rproto_list, p);
739 cat = CLASS_CATEGORY_LIST (cat);
742 rinter = lookup_interface (CLASS_SUPER_NAME (rinter));
745 warning ("class `%s' does not implement the `%s' protocol",
746 IDENTIFIER_POINTER (TYPE_NAME (TREE_TYPE (rhs))),
747 IDENTIFIER_POINTER (PROTOCOL_NAME (p)));
751 return 1; /* may change...based on whether there was any mismatch */
753 else if (rhs_is_proto)
755 /* lhs is not a protocol...warn if it is statically typed */
757 if (TYPED_OBJECT (TREE_TYPE (lhs)))
760 return 1; /* one of the types is a protocol */
763 return -1; /* defer to comptypes */
765 else if (TREE_CODE (lhs) == RECORD_TYPE && TREE_CODE (rhs) == RECORD_TYPE)
766 ; /* fall thru...this is the case we have been handling all along */
768 return -1; /* defer to comptypes */
770 /* End of new protocol support. */
772 /* `id' = `<class> *', `<class> *' = `id' */
774 if ((TYPE_NAME (lhs) == objc_object_id && TYPED_OBJECT (rhs))
775 || (TYPE_NAME (rhs) == objc_object_id && TYPED_OBJECT (lhs)))
778 /* `id' = `Class', `Class' = `id' */
780 else if ((TYPE_NAME (lhs) == objc_object_id
781 && TYPE_NAME (rhs) == objc_class_id)
782 || (TYPE_NAME (lhs) == objc_class_id
783 && TYPE_NAME (rhs) == objc_object_id))
786 /* `<class> *' = `<class> *' */
788 else if (TYPED_OBJECT (lhs) && TYPED_OBJECT (rhs))
790 tree lname = TYPE_NAME (lhs);
791 tree rname = TYPE_NAME (rhs);
797 /* If the left hand side is a super class of the right hand side,
799 for (inter = lookup_interface (rname); inter;
800 inter = lookup_interface (CLASS_SUPER_NAME (inter)))
801 if (lname == CLASS_SUPER_NAME (inter))
804 /* Allow the reverse when reflexive. */
806 for (inter = lookup_interface (lname); inter;
807 inter = lookup_interface (CLASS_SUPER_NAME (inter)))
808 if (rname == CLASS_SUPER_NAME (inter))
814 return -1; /* defer to comptypes */
817 /* Called from c-decl.c before all calls to rest_of_decl_compilation. */
820 objc_check_decl (decl)
823 tree type = TREE_TYPE (decl);
825 if (TREE_CODE (type) == RECORD_TYPE
826 && TREE_STATIC_TEMPLATE (type)
827 && type != constant_string_type)
829 error_with_decl (decl, "`%s' cannot be statically allocated");
830 fatal ("statically allocated objects not supported");
835 maybe_objc_check_decl (decl)
838 if (doing_objc_thang)
839 objc_check_decl (decl);
842 /* Implement static typing. At this point, we know we have an interface. */
845 get_static_reference (interface, protocols)
849 tree type = xref_tag (RECORD_TYPE, interface);
853 tree t, m = TYPE_MAIN_VARIANT (type);
854 struct obstack *ambient_obstack = current_obstack;
856 current_obstack = &permanent_obstack;
857 t = copy_node (type);
858 TYPE_BINFO (t) = make_tree_vec (2);
860 /* Add this type to the chain of variants of TYPE. */
861 TYPE_NEXT_VARIANT (t) = TYPE_NEXT_VARIANT (m);
862 TYPE_NEXT_VARIANT (m) = t;
864 current_obstack = ambient_obstack;
866 /* Look up protocols and install in lang specific list. */
867 TYPE_PROTOCOL_LIST (t) = lookup_and_install_protocols (protocols);
869 /* This forces a new pointer type to be created later
870 (in build_pointer_type)...so that the new template
871 we just created will actually be used...what a hack! */
872 if (TYPE_POINTER_TO (t))
873 TYPE_POINTER_TO (t) = NULL;
882 get_object_reference (protocols)
885 tree type_decl = lookup_name (objc_id_id);
888 if (type_decl && TREE_CODE (type_decl) == TYPE_DECL)
890 type = TREE_TYPE (type_decl);
891 if (TYPE_MAIN_VARIANT (type) != id_type)
892 warning ("Unexpected type for `id' (%s)",
893 gen_declaration (type, errbuf));
897 fatal ("Undefined type `id', please import <objc/objc.h>");
900 /* This clause creates a new pointer type that is qualified with
901 the protocol specification...this info is used later to do more
902 elaborate type checking. */
905 tree t, m = TYPE_MAIN_VARIANT (type);
906 struct obstack *ambient_obstack = current_obstack;
908 current_obstack = &permanent_obstack;
909 t = copy_node (type);
910 TYPE_BINFO (t) = make_tree_vec (2);
912 /* Add this type to the chain of variants of TYPE. */
913 TYPE_NEXT_VARIANT (t) = TYPE_NEXT_VARIANT (m);
914 TYPE_NEXT_VARIANT (m) = t;
916 current_obstack = ambient_obstack;
918 /* look up protocols...and install in lang specific list */
919 TYPE_PROTOCOL_LIST (t) = lookup_and_install_protocols (protocols);
921 /* This forces a new pointer type to be created later
922 (in build_pointer_type)...so that the new template
923 we just created will actually be used...what a hack! */
924 if (TYPE_POINTER_TO (t))
925 TYPE_POINTER_TO (t) = NULL;
933 lookup_and_install_protocols (protocols)
938 tree return_value = protocols;
940 for (proto = protocols; proto; proto = TREE_CHAIN (proto))
942 tree ident = TREE_VALUE (proto);
943 tree p = lookup_protocol (ident);
947 error ("Cannot find protocol declaration for `%s'",
948 IDENTIFIER_POINTER (ident));
950 TREE_CHAIN (prev) = TREE_CHAIN (proto);
952 return_value = TREE_CHAIN (proto);
956 /* replace identifier with actual protocol node */
957 TREE_VALUE (proto) = p;
964 /* Create and push a decl for a built-in external variable or field NAME.
966 TYPE is its data type. */
969 create_builtin_decl (code, type, name)
974 tree decl = build_decl (code, get_identifier (name), type);
975 if (code == VAR_DECL)
977 TREE_STATIC (decl) = 1;
978 make_decl_rtl (decl, 0, 1);
984 /* purpose: "play" parser, creating/installing representations
985 of the declarations that are required by Objective-C.
989 type_spec--------->sc_spec
990 (tree_list) (tree_list)
993 identifier_node identifier_node */
996 synth_module_prologue ()
1001 /* defined in `objc.h' */
1002 objc_object_id = get_identifier (TAG_OBJECT);
1004 objc_object_reference = xref_tag (RECORD_TYPE, objc_object_id);
1006 id_type = build_pointer_type (objc_object_reference);
1008 objc_id_id = get_identifier (TYPE_ID);
1009 objc_class_id = get_identifier (TAG_CLASS);
1011 objc_class_type = build_pointer_type (xref_tag (RECORD_TYPE, objc_class_id));
1012 protocol_type = build_pointer_type (xref_tag (RECORD_TYPE,
1013 get_identifier (PROTOCOL_OBJECT_CLASS_NAME)));
1015 /* Declare type of selector-objects that represent an operation name. */
1017 #ifdef OBJC_INT_SELECTORS
1018 /* `unsigned int' */
1019 selector_type = unsigned_type_node;
1021 /* `struct objc_selector *' */
1023 = build_pointer_type (xref_tag (RECORD_TYPE,
1024 get_identifier (TAG_SELECTOR)));
1025 #endif /* not OBJC_INT_SELECTORS */
1027 /* Forward declare type, or else the prototype for msgSendSuper will
1030 super_p = build_pointer_type (xref_tag (RECORD_TYPE,
1031 get_identifier (TAG_SUPER)));
1034 /* id objc_msgSend (id, SEL, ...); */
1037 = build_function_type (id_type,
1038 tree_cons (NULL_TREE, id_type,
1039 tree_cons (NULLT, selector_type, NULLT)));
1041 if (! flag_next_runtime)
1043 umsg_decl = build_decl (FUNCTION_DECL,
1044 get_identifier (TAG_MSGSEND), temp_type);
1045 DECL_EXTERNAL (umsg_decl) = 1;
1046 TREE_PUBLIC (umsg_decl) = 0;
1047 DECL_INLINE (umsg_decl) = 1;
1049 if (flag_traditional && TAG_MSGSEND[0] != '_')
1050 DECL_BUILT_IN_NONANSI (umsg_decl) = 1;
1052 make_decl_rtl (umsg_decl, NULL_PTR, 1);
1053 pushdecl (umsg_decl);
1056 umsg_decl = builtin_function (TAG_MSGSEND, temp_type, NOT_BUILT_IN, 0);
1058 /* id objc_msgSendSuper (struct objc_super *, SEL, ...); */
1061 = build_function_type (id_type,
1062 tree_cons (NULL_TREE, super_p,
1063 tree_cons (NULLT, selector_type, NULLT)));
1065 umsg_super_decl = builtin_function (TAG_MSGSENDSUPER,
1066 temp_type, NOT_BUILT_IN, 0);
1068 /* id objc_getClass (const char *); */
1070 temp_type = build_function_type (id_type,
1072 const_string_type_node,
1073 tree_cons (NULLT, void_type_node, NULLT)));
1076 = builtin_function (TAG_GETCLASS, temp_type, NOT_BUILT_IN, 0);
1078 /* id objc_getMetaClass (const char *); */
1080 objc_get_meta_class_decl
1081 = builtin_function (TAG_GETMETACLASS, temp_type, NOT_BUILT_IN, 0);
1083 /* static SEL _OBJC_SELECTOR_TABLE[]; */
1085 if (! flag_next_runtime)
1086 UOBJC_SELECTOR_TABLE_decl
1087 = create_builtin_decl (VAR_DECL, build_array_type (selector_type, NULLT),
1088 "_OBJC_SELECTOR_TABLE");
1090 generate_forward_declaration_to_string_table ();
1092 /* Forward declare constant_string_id and constant_string_type. */
1093 constant_string_id = get_identifier (STRING_OBJECT_CLASS_NAME);
1094 constant_string_type = xref_tag (RECORD_TYPE, constant_string_id);
1097 /* Custom build_string which sets TREE_TYPE! */
1100 my_build_string (len, str)
1105 tree a_string = build_string (len, str);
1106 /* Some code from combine_strings, which is local to c-parse.y. */
1107 if (TREE_TYPE (a_string) == int_array_type_node)
1110 TREE_TYPE (a_string) =
1111 build_array_type (wide_flag ? integer_type_node : char_type_node,
1112 build_index_type (build_int_2 (len - 1, 0)));
1114 TREE_CONSTANT (a_string) = 1; /* puts string in the ".text" segment */
1115 TREE_STATIC (a_string) = 1;
1120 /* Return a newly constructed OBJC_STRING_CST node whose value is
1121 the LEN characters at STR.
1122 The TREE_TYPE is not initialized. */
1125 build_objc_string (len, str)
1129 tree s = build_string (len, str);
1131 TREE_SET_CODE (s, OBJC_STRING_CST);
1135 /* Given a chain of OBJC_STRING_CST's, build a static instance of
1136 NXConstantString which points at the concatenation of those strings.
1137 We place the string object in the __string_objects section of the
1138 __OBJC segment. The Objective-C runtime will initialize the isa
1139 pointers of the string objects to point at the NXConstantString
1143 build_objc_string_object (strings)
1146 tree string, initlist, constructor;
1149 if (!doing_objc_thang)
1152 if (lookup_interface (constant_string_id) == NULLT)
1154 error ("Cannot find interface declaration for `%s'",
1155 IDENTIFIER_POINTER (constant_string_id));
1156 return error_mark_node;
1159 add_class_reference (constant_string_id);
1161 /* combine_strings will work for OBJC_STRING_CST's too. */
1162 string = combine_strings (strings);
1163 TREE_SET_CODE (string, STRING_CST);
1164 length = TREE_STRING_LENGTH (string) - 1;
1166 /* & ((NXConstantString) {0, string, length}) */
1168 initlist = build_tree_list (NULLT, build_int_2 (0, 0));
1169 initlist = tree_cons (NULLT, build_unary_op (ADDR_EXPR, string, 1),
1171 initlist = tree_cons (NULLT, build_int_2 (length, 0), initlist);
1172 constructor = build (CONSTRUCTOR, constant_string_type, NULLT,
1173 nreverse (initlist));
1174 TREE_CONSTANT (constructor) = 1;
1175 TREE_STATIC (constructor) = 1;
1176 TREE_READONLY (constructor) = 1;
1178 return build_unary_op (ADDR_EXPR, constructor, 1);
1181 /* Take care of defining and initializing _OBJC_SYMBOLS. */
1183 /* Predefine the following data type:
1191 void *defs[cls_def_cnt + cat_def_cnt];
1195 build_objc_symtab_template ()
1197 tree field_decl, field_decl_chain, index;
1199 objc_symtab_template = start_struct (RECORD_TYPE, get_identifier (UTAG_SYMTAB));
1201 /* long sel_ref_cnt; */
1203 field_decl = create_builtin_decl (FIELD_DECL,
1204 long_integer_type_node,
1206 field_decl_chain = field_decl;
1210 field_decl = create_builtin_decl (FIELD_DECL,
1211 build_pointer_type (selector_type),
1213 chainon (field_decl_chain, field_decl);
1215 /* short cls_def_cnt; */
1217 field_decl = create_builtin_decl (FIELD_DECL,
1218 short_integer_type_node,
1220 chainon (field_decl_chain, field_decl);
1222 /* short cat_def_cnt; */
1224 field_decl = create_builtin_decl (FIELD_DECL,
1225 short_integer_type_node,
1227 chainon (field_decl_chain, field_decl);
1229 /* void *defs[cls_def_cnt + cat_def_cnt]; */
1231 index = build_index_type (build_int_2 (imp_count + cat_count - 1,
1232 imp_count == 0 && cat_count == 0
1234 field_decl = create_builtin_decl (FIELD_DECL,
1235 build_array_type (ptr_type_node, index),
1237 chainon (field_decl_chain, field_decl);
1239 finish_struct (objc_symtab_template, field_decl_chain);
1242 /* Create the initial value for the `defs' field of _objc_symtab.
1243 This is a CONSTRUCTOR. */
1248 tree expr, initlist = NULLT;
1249 struct imp_entry *impent;
1252 for (impent = imp_list; impent; impent = impent->next)
1254 if (TREE_CODE (impent->imp_context) == CLASS_IMPLEMENTATION_TYPE)
1256 expr = build_unary_op (ADDR_EXPR, impent->class_decl, 0);
1257 initlist = tree_cons (NULLT, expr, initlist);
1262 for (impent = imp_list; impent; impent = impent->next)
1264 if (TREE_CODE (impent->imp_context) == CATEGORY_IMPLEMENTATION_TYPE)
1266 expr = build_unary_op (ADDR_EXPR, impent->class_decl, 0);
1267 initlist = tree_cons (NULLT, expr, initlist);
1270 return build_nt (CONSTRUCTOR, NULLT, nreverse (initlist));
1273 /* Construct the initial value for all of _objc_symtab. */
1280 /* sel_ref_cnt = { ..., 5, ... } */
1282 initlist = build_tree_list (NULLT, build_int_2 (0, 0));
1284 /* refs = { ..., _OBJC_SELECTOR_TABLE, ... } */
1286 if (flag_next_runtime || ! sel_ref_chain)
1287 initlist = tree_cons (NULLT, build_int_2 (0, 0), initlist);
1289 initlist = tree_cons (NULLT, UOBJC_SELECTOR_TABLE_decl, initlist);
1291 /* cls_def_cnt = { ..., 5, ... } */
1293 initlist = tree_cons (NULLT, build_int_2 (imp_count, 0), initlist);
1295 /* cat_def_cnt = { ..., 5, ... } */
1297 initlist = tree_cons (NULLT, build_int_2 (cat_count, 0), initlist);
1299 /* cls_def = { ..., { &Foo, &Bar, ...}, ... } */
1301 if (imp_count || cat_count)
1302 initlist = tree_cons (NULLT, init_def_list (), initlist);
1304 return build_nt (CONSTRUCTOR, NULLT, nreverse (initlist));
1307 /* Push forward-declarations of all the categories
1308 so that init_def_list can use them in a CONSTRUCTOR. */
1311 forward_declare_categories ()
1313 struct imp_entry *impent;
1314 tree sav = implementation_context;
1315 for (impent = imp_list; impent; impent = impent->next)
1317 if (TREE_CODE (impent->imp_context) == CATEGORY_IMPLEMENTATION_TYPE)
1319 /* Set an invisible arg to synth_id_with_class_suffix. */
1320 implementation_context = impent->imp_context;
1322 = create_builtin_decl (VAR_DECL, objc_category_template,
1323 IDENTIFIER_POINTER (synth_id_with_class_suffix ("_OBJC_CATEGORY", implementation_context)));
1326 implementation_context = sav;
1329 /* Create the declaration of _OBJC_SYMBOLS, with type `strict _objc_symtab'
1330 and initialized appropriately. */
1333 generate_objc_symtab_decl ()
1337 if (!objc_category_template)
1338 build_category_template ();
1340 /* forward declare categories */
1342 forward_declare_categories ();
1344 if (!objc_symtab_template)
1345 build_objc_symtab_template ();
1347 sc_spec = build_tree_list (NULLT, ridpointers[(int) RID_STATIC]);
1349 UOBJC_SYMBOLS_decl = start_decl (get_identifier ("_OBJC_SYMBOLS"),
1350 tree_cons (NULLT, objc_symtab_template, sc_spec), 1);
1352 end_temporary_allocation (); /* start_decl trying to be smart about inits */
1353 TREE_USED (UOBJC_SYMBOLS_decl) = 1;
1354 DECL_IGNORED_P (UOBJC_SYMBOLS_decl) = 1;
1355 finish_decl (UOBJC_SYMBOLS_decl, init_objc_symtab (), NULLT);
1359 init_module_descriptor ()
1361 tree initlist, expr;
1363 /* version = { 1, ... } */
1365 expr = build_int_2 (OBJC_VERSION, 0);
1366 initlist = build_tree_list (NULLT, expr);
1368 /* size = { ..., sizeof (struct objc_module), ... } */
1370 expr = size_in_bytes (objc_module_template);
1371 initlist = tree_cons (NULLT, expr, initlist);
1373 /* name = { ..., "foo.m", ... } */
1375 expr = add_objc_string (get_identifier (input_filename), class_names);
1376 initlist = tree_cons (NULLT, expr, initlist);
1378 /* symtab = { ..., _OBJC_SYMBOLS, ... } */
1380 if (UOBJC_SYMBOLS_decl)
1381 expr = build_unary_op (ADDR_EXPR, UOBJC_SYMBOLS_decl, 0);
1383 expr = build_int_2 (0, 0);
1384 initlist = tree_cons (NULLT, expr, initlist);
1386 return build_nt (CONSTRUCTOR, NULLT, nreverse (initlist));
1389 /* Write out the data structures to describe Objective C classes defined.
1390 If appropriate, compile and output a setup function to initialize them.
1391 Return a string which is the name of a function to call to initialize
1392 the Objective C data structures for this file (and perhaps for other files
1395 struct objc_module { ... } _OBJC_MODULE = { ... };
1400 build_module_descriptor ()
1402 tree decl_specs, field_decl, field_decl_chain;
1404 objc_module_template = start_struct (RECORD_TYPE, get_identifier (UTAG_MODULE));
1408 decl_specs = build_tree_list (NULLT, ridpointers[(int) RID_LONG]);
1409 field_decl = get_identifier ("version");
1410 field_decl = grokfield (input_filename, lineno, field_decl, decl_specs, NULLT);
1411 field_decl_chain = field_decl;
1415 decl_specs = build_tree_list (NULLT, ridpointers[(int) RID_LONG]);
1416 field_decl = get_identifier ("size");
1417 field_decl = grokfield (input_filename, lineno, field_decl, decl_specs, NULLT);
1418 chainon (field_decl_chain, field_decl);
1422 decl_specs = build_tree_list (NULLT, ridpointers[(int) RID_CHAR]);
1423 field_decl = build1 (INDIRECT_REF, NULLT, get_identifier ("name"));
1424 field_decl = grokfield (input_filename, lineno, field_decl, decl_specs, NULLT);
1425 chainon (field_decl_chain, field_decl);
1427 /* struct objc_symtab *symtab; */
1429 decl_specs = get_identifier (UTAG_SYMTAB);
1430 decl_specs = build_tree_list (NULLT, xref_tag (RECORD_TYPE, decl_specs));
1431 field_decl = build1 (INDIRECT_REF, NULLT, get_identifier ("symtab"));
1432 field_decl = grokfield (input_filename, lineno, field_decl, decl_specs, NULLT);
1433 chainon (field_decl_chain, field_decl);
1435 finish_struct (objc_module_template, field_decl_chain);
1437 /* create an instance of "objc_module" */
1439 decl_specs = tree_cons (NULLT, objc_module_template,
1440 build_tree_list (NULLT, ridpointers[(int) RID_STATIC]));
1442 UOBJC_MODULES_decl = start_decl (get_identifier ("_OBJC_MODULES"),
1445 end_temporary_allocation (); /* start_decl trying to be smart about inits */
1446 DECL_IGNORED_P (UOBJC_MODULES_decl) = 1;
1447 finish_decl (UOBJC_MODULES_decl, init_module_descriptor (), NULLT);
1449 /* Mark the decl to avoid "defined but not used" warning. */
1450 DECL_IN_SYSTEM_HEADER (UOBJC_MODULES_decl) = 1;
1452 /* Generate a constructor call for the module descriptor.
1453 This code was generated by reading the grammar rules
1454 of c-parse.y; Therefore, it may not be the most efficient
1455 way of generating the requisite code. */
1457 if (flag_next_runtime)
1461 tree parms, function_decl, decelerator, void_list_node;
1464 char *global_object_name = 0;
1467 /* Use a global object (which is already required to be unique over
1468 the program) rather than the file name (which imposes extra
1469 constraints). -- Raeburn@MIT.EDU, 10 Jan 1990. */
1471 /* Find the name of some global object defined in this file. */
1472 for (t = getdecls (); t; t = TREE_CHAIN (t))
1473 if (TREE_PUBLIC (t) && !DECL_EXTERNAL (t) && DECL_INITIAL (t) != 0)
1475 global_object_name = IDENTIFIER_POINTER (DECL_NAME (t));
1479 /* If none, use the name of the file. */
1480 if (!global_object_name)
1484 = (char *) alloca (strlen (main_input_filename) + 1);
1486 p = main_input_filename;
1487 q = global_object_name;
1489 /* Replace any weird characters in the file name. */
1491 if (! ((*p >= '0' && *p <= '9')
1492 || (*p >= 'A' && *p <= 'Z')
1493 || (*p >= 'a' && *p <= 'z')))
1500 /* Make the constructor name from the name we have found. */
1501 buf = (char *) xmalloc (sizeof (CONSTRUCTOR_NAME_FORMAT)
1502 + strlen (global_object_name));
1503 sprintf (buf, CONSTRUCTOR_NAME_FORMAT, global_object_name);
1505 /* Declare void __objc_execClass (void*); */
1507 void_list_node = build_tree_list (NULL_TREE, void_type_node);
1509 = build_function_type (void_type_node,
1510 tree_cons (NULL_TREE, ptr_type_node,
1512 function_decl = build_decl (FUNCTION_DECL,
1513 get_identifier (TAG_EXECCLASS),
1515 DECL_EXTERNAL (function_decl) = 1;
1516 TREE_PUBLIC (function_decl) = 1;
1517 pushdecl (function_decl);
1518 rest_of_decl_compilation (function_decl, 0, 0, 0);
1521 = build_tree_list (NULLT,
1522 build_unary_op (ADDR_EXPR, UOBJC_MODULES_decl, 0));
1523 decelerator = build_function_call (function_decl, parms);
1525 /* void _GLOBAL_$I$<gnyf> () {objc_execClass (&L_OBJC_MODULES);} */
1527 start_function (void_list_node,
1528 build_parse_node (CALL_EXPR, get_identifier (buf),
1529 /* This has the format of the output
1530 of get_parm_info. */
1531 tree_cons (NULL_TREE, NULL_TREE,
1535 #if 0 /* This should be turned back on later
1536 for the systems where collect is not needed. */
1537 /* Make these functions nonglobal
1538 so each file can use the same name. */
1539 TREE_PUBLIC (current_function_decl) = 0;
1541 TREE_USED (current_function_decl) = 1;
1542 store_parm_decls ();
1544 assemble_external (function_decl);
1545 c_expand_expr_stmt (decelerator);
1547 finish_function (0);
1549 /* Return the name of the constructor function. */
1554 /* extern const char _OBJC_STRINGS[]; */
1557 generate_forward_declaration_to_string_table ()
1559 tree sc_spec, decl_specs, expr_decl;
1561 sc_spec = tree_cons (NULLT, ridpointers[(int) RID_EXTERN], NULLT);
1562 decl_specs = tree_cons (NULLT, ridpointers[(int) RID_CHAR], sc_spec);
1564 expr_decl = build_nt (ARRAY_REF, get_identifier ("_OBJC_STRINGS"), NULLT);
1566 UOBJC_STRINGS_decl = define_decl (expr_decl, decl_specs);
1569 /* Output all strings. */
1574 tree sc_spec, decl_specs, expr_decl;
1575 tree chain, string_expr;
1578 for (chain = class_names_chain; chain; chain = TREE_CHAIN (chain))
1580 string = TREE_VALUE (chain);
1581 decl = TREE_PURPOSE (chain);
1582 sc_spec = tree_cons (NULLT, ridpointers[(int) RID_STATIC], NULLT);
1583 decl_specs = tree_cons (NULLT, ridpointers[(int) RID_CHAR], sc_spec);
1584 expr_decl = build_nt (ARRAY_REF, DECL_NAME (decl), NULLT);
1585 decl = start_decl (expr_decl, decl_specs, 1);
1586 end_temporary_allocation ();
1587 string_expr = my_build_string (IDENTIFIER_LENGTH (string) + 1,
1588 IDENTIFIER_POINTER (string));
1589 finish_decl (decl, string_expr, NULLT);
1592 for (chain = meth_var_names_chain; chain; chain = TREE_CHAIN (chain))
1594 string = TREE_VALUE (chain);
1595 decl = TREE_PURPOSE (chain);
1596 sc_spec = tree_cons (NULLT, ridpointers[(int) RID_STATIC], NULLT);
1597 decl_specs = tree_cons (NULLT, ridpointers[(int) RID_CHAR], sc_spec);
1598 expr_decl = build_nt (ARRAY_REF, DECL_NAME (decl), NULLT);
1599 decl = start_decl (expr_decl, decl_specs, 1);
1600 end_temporary_allocation ();
1601 string_expr = my_build_string (IDENTIFIER_LENGTH (string) + 1,
1602 IDENTIFIER_POINTER (string));
1603 finish_decl (decl, string_expr, NULLT);
1606 for (chain = meth_var_types_chain; chain; chain = TREE_CHAIN (chain))
1608 string = TREE_VALUE (chain);
1609 decl = TREE_PURPOSE (chain);
1610 sc_spec = tree_cons (NULLT, ridpointers[(int) RID_STATIC], NULLT);
1611 decl_specs = tree_cons (NULLT, ridpointers[(int) RID_CHAR], sc_spec);
1612 expr_decl = build_nt (ARRAY_REF, DECL_NAME (decl), NULLT);
1613 decl = start_decl (expr_decl, decl_specs, 1);
1614 end_temporary_allocation ();
1615 string_expr = my_build_string (IDENTIFIER_LENGTH (string) + 1,
1616 IDENTIFIER_POINTER (string));
1617 finish_decl (decl, string_expr, NULLT);
1622 build_selector_reference_decl (name)
1627 struct obstack *save_current_obstack = current_obstack;
1628 struct obstack *save_rtl_obstack = rtl_obstack;
1631 sprintf (buf, "_OBJC_SELECTOR_REFERENCES_%d", idx++);
1634 rtl_obstack = current_obstack = &permanent_obstack;
1635 ident = get_identifier (buf);
1637 decl = build_decl (VAR_DECL, ident, selector_type);
1638 DECL_EXTERNAL (decl) = 1;
1639 TREE_PUBLIC (decl) = 1;
1640 TREE_USED (decl) = 1;
1641 TREE_READONLY (decl) = 1;
1643 make_decl_rtl (decl, 0, 1); /* usually called from `rest_of_decl_compilation' */
1644 pushdecl_top_level (decl); /* our `extended/custom' pushdecl in c-decl.c */
1646 current_obstack = save_current_obstack;
1647 rtl_obstack = save_rtl_obstack;
1652 /* Just a handy wrapper for add_objc_string. */
1655 build_selector (ident)
1658 tree expr = add_objc_string (ident, meth_var_names);
1660 return build_c_cast (selector_type, expr); /* cast! */
1663 /* Synthesize the following expr: (char *)&_OBJC_STRINGS[<offset>]
1664 The cast stops the compiler from issuing the following message:
1665 grok.m: warning: initialization of non-const * pointer from const *
1666 grok.m: warning: initialization between incompatible pointer types. */
1669 build_msg_pool_reference (offset)
1672 tree expr = build_int_2 (offset, 0);
1675 expr = build_array_ref (UOBJC_STRINGS_decl, expr);
1676 expr = build_unary_op (ADDR_EXPR, expr, 0);
1678 cast = build_tree_list (build_tree_list (NULLT, ridpointers[(int) RID_CHAR]),
1679 build1 (INDIRECT_REF, NULLT, NULLT));
1680 TREE_TYPE (expr) = groktypename (cast);
1685 init_selector (offset)
1688 tree expr = build_msg_pool_reference (offset);
1689 TREE_TYPE (expr) = selector_type; /* cast */
1694 build_selector_translation_table ()
1696 tree sc_spec, decl_specs;
1697 tree chain, initlist = NULLT;
1699 tree decl, var_decl, name;
1701 /* The corresponding pop_obstacks is in finish_decl,
1702 called at the end of this function. */
1703 if (! flag_next_runtime)
1704 push_obstacks_nochange ();
1706 for (chain = sel_ref_chain; chain; chain = TREE_CHAIN (chain))
1710 expr = build_selector (TREE_VALUE (chain));
1712 if (flag_next_runtime)
1714 name = DECL_NAME (TREE_PURPOSE (chain));
1716 sc_spec = build_tree_list (NULLT, ridpointers[(int) RID_STATIC]);
1718 /* static SEL _OBJC_SELECTOR_REFERENCES_n = ...; */
1719 decl_specs = tree_cons (NULLT, selector_type, sc_spec);
1723 /* the `decl' that is returned from start_decl is the one that we
1724 forward declared in `build_selector_reference' */
1725 decl = start_decl (var_decl, decl_specs, 1);
1728 /* add one for the '\0' character */
1729 offset += IDENTIFIER_LENGTH (TREE_VALUE (chain)) + 1;
1731 if (flag_next_runtime)
1733 end_temporary_allocation ();
1734 finish_decl (decl, expr, NULLT);
1737 initlist = tree_cons (NULLT, expr, initlist);
1740 if (! flag_next_runtime)
1742 /* Cause the variable and its initial value to be actually output. */
1743 DECL_EXTERNAL (UOBJC_SELECTOR_TABLE_decl) = 0;
1744 TREE_STATIC (UOBJC_SELECTOR_TABLE_decl) = 1;
1745 /* NULL terminate the list and fix the decl for output. */
1746 initlist = tree_cons (NULLT, build_int_2 (0, 0), initlist);
1747 DECL_INITIAL (UOBJC_SELECTOR_TABLE_decl) = (tree) 1;
1748 initlist = build_nt (CONSTRUCTOR, NULLT, nreverse (initlist));
1749 finish_decl (UOBJC_SELECTOR_TABLE_decl, initlist, NULLT);
1753 /* sel_ref_chain is a list whose "value" fields will be instances of
1754 identifier_node that represent the selector. */
1757 build_selector_reference (ident)
1760 tree *chain = &sel_ref_chain;
1766 if (TREE_VALUE (*chain) == ident)
1767 return (flag_next_runtime
1768 ? TREE_PURPOSE (*chain)
1769 : build_array_ref (UOBJC_SELECTOR_TABLE_decl,
1770 build_int_2 (index, 0)));
1773 chain = &TREE_CHAIN (*chain);
1776 decl = build_selector_reference_decl (ident);
1778 *chain = perm_tree_cons (decl, ident, NULLT);
1780 return (flag_next_runtime
1782 : build_array_ref (UOBJC_SELECTOR_TABLE_decl,
1783 build_int_2 (index, 0)));
1787 build_class_reference_decl (name)
1792 struct obstack *save_current_obstack = current_obstack;
1793 struct obstack *save_rtl_obstack = rtl_obstack;
1796 sprintf (buf, "_OBJC_CLASS_REFERENCES_%d", idx++);
1799 rtl_obstack = current_obstack = &permanent_obstack;
1800 ident = get_identifier (buf);
1802 decl = build_decl (VAR_DECL, ident, objc_class_type);
1803 DECL_EXTERNAL (decl) = 1;
1804 TREE_PUBLIC (decl) = 1;
1805 TREE_USED (decl) = 1;
1806 TREE_READONLY (decl) = 1;
1808 make_decl_rtl (decl, 0, 1); /* usually called from `rest_of_decl_compilation' */
1809 pushdecl_top_level (decl); /* our `extended/custom' pushdecl in c-decl.c */
1811 current_obstack = save_current_obstack;
1812 rtl_obstack = save_rtl_obstack;
1817 /* Create a class reference, but don't create a variable to reference
1821 add_class_reference (ident)
1826 if ((chain = cls_ref_chain))
1831 if (ident == TREE_VALUE (chain))
1835 chain = TREE_CHAIN (chain);
1839 /* append to the end of the list */
1840 TREE_CHAIN (tail) = perm_tree_cons (NULLT, ident, NULLT);
1843 cls_ref_chain = perm_tree_cons (NULLT, ident, NULLT);
1846 /* Get a class reference, creating it if necessary. Also create the
1847 reference variable. */
1850 get_class_reference (ident)
1853 if (flag_next_runtime)
1858 for (chain = &cls_ref_chain; *chain; chain = &TREE_CHAIN (*chain))
1859 if (TREE_VALUE (*chain) == ident)
1861 if (! TREE_PURPOSE (*chain))
1862 TREE_PURPOSE (*chain) = build_class_reference_decl (ident);
1863 return TREE_PURPOSE (*chain);
1866 decl = build_class_reference_decl (ident);
1867 *chain = perm_tree_cons (decl, ident, NULLT);
1874 add_class_reference (ident);
1876 params = build_tree_list (NULLT,
1877 my_build_string (IDENTIFIER_LENGTH (ident) + 1,
1878 IDENTIFIER_POINTER (ident)));
1880 assemble_external (objc_get_class_decl);
1881 return build_function_call (objc_get_class_decl, params);
1885 /* sel_refdef_chain is a list whose "value" fields will be instances
1886 of identifier_node that represent the selector. It returns the
1887 offset of the selector from the beginning of the _OBJC_STRINGS
1888 pool. This offset is typically used by init_selector during code
1891 For each string section we have a chain which maps identifier nodes
1892 to decls for the strings. */
1895 add_objc_string (ident, section)
1897 enum string_section section;
1901 if (section == class_names)
1902 chain = &class_names_chain;
1903 else if (section == meth_var_names)
1904 chain = &meth_var_names_chain;
1905 else if (section == meth_var_types)
1906 chain = &meth_var_types_chain;
1910 if (TREE_VALUE (*chain) == ident)
1911 return TREE_PURPOSE (*chain);
1913 chain = &TREE_CHAIN (*chain);
1916 decl = build_objc_string_decl (ident, section);
1918 *chain = perm_tree_cons (decl, ident, NULLT);
1924 build_objc_string_decl (name, section)
1926 enum string_section section;
1930 struct obstack *save_current_obstack = current_obstack;
1931 struct obstack *save_rtl_obstack = rtl_obstack;
1932 static int class_names_idx = 0;
1933 static int meth_var_names_idx = 0;
1934 static int meth_var_types_idx = 0;
1936 if (section == class_names)
1937 sprintf (buf, "_OBJC_CLASS_NAME_%d", class_names_idx++);
1938 else if (section == meth_var_names)
1939 sprintf (buf, "_OBJC_METH_VAR_NAME_%d", meth_var_names_idx++);
1940 else if (section == meth_var_types)
1941 sprintf (buf, "_OBJC_METH_VAR_TYPE_%d", meth_var_types_idx++);
1943 rtl_obstack = current_obstack = &permanent_obstack;
1944 ident = get_identifier (buf);
1946 decl = build_decl (VAR_DECL, ident, build_array_type (char_type_node, 0));
1947 DECL_EXTERNAL (decl) = 1;
1948 TREE_PUBLIC (decl) = 1;
1949 TREE_USED (decl) = 1;
1950 TREE_READONLY (decl) = 1;
1951 TREE_CONSTANT (decl) = 1;
1953 make_decl_rtl (decl, 0, 1); /* usually called from `rest_of_decl_compilation */
1954 pushdecl_top_level (decl); /* our `extended/custom' pushdecl in c-decl.c */
1956 current_obstack = save_current_obstack;
1957 rtl_obstack = save_rtl_obstack;
1964 objc_declare_alias (alias_ident, class_ident)
1968 if (!doing_objc_thang)
1971 if (is_class_name (class_ident) != class_ident)
1972 warning ("Cannot find class `%s'", IDENTIFIER_POINTER (class_ident));
1973 else if (is_class_name (alias_ident))
1974 warning ("Class `%s' already exists", IDENTIFIER_POINTER (alias_ident));
1976 alias_chain = tree_cons (class_ident, alias_ident, alias_chain);
1980 objc_declare_class (ident_list)
1985 if (!doing_objc_thang)
1988 for (list = ident_list; list; list = TREE_CHAIN (list))
1990 tree ident = TREE_VALUE (list);
1993 if ((decl = lookup_name (ident)))
1995 error ("`%s' redeclared as different kind of symbol",
1996 IDENTIFIER_POINTER (ident));
1997 error_with_decl (decl, "previous declaration of `%s'");
2000 if (! is_class_name (ident))
2002 tree record = xref_tag (RECORD_TYPE, ident);
2003 TREE_STATIC_TEMPLATE (record) = 1;
2004 class_chain = tree_cons (NULLT, ident, class_chain);
2010 is_class_name (ident)
2015 if (lookup_interface (ident))
2018 for (chain = class_chain; chain; chain = TREE_CHAIN (chain))
2020 if (ident == TREE_VALUE (chain))
2024 for (chain = alias_chain; chain; chain = TREE_CHAIN (chain))
2026 if (ident == TREE_VALUE (chain))
2027 return TREE_PURPOSE (chain);
2034 lookup_interface (ident)
2039 for (chain = interface_chain; chain; chain = TREE_CHAIN (chain))
2041 if (ident == CLASS_NAME (chain))
2048 objc_copy_list (list, head)
2052 tree newlist = NULL_TREE, tail = NULL_TREE;
2056 tail = copy_node (list);
2058 /* The following statement fixes a bug when inheriting instance
2059 variables that are declared to be bitfields. finish_struct
2060 expects to find the width of the bitfield in DECL_INITIAL,
2061 which it nulls out after processing the decl of the super
2062 class...rather than change the way finish_struct works (which
2063 is risky), I create the situation it expects...s.naroff
2066 if (DECL_BIT_FIELD (tail) && DECL_INITIAL (tail) == 0)
2067 DECL_INITIAL (tail) = build_int_2 (DECL_FIELD_SIZE (tail), 0);
2069 newlist = chainon (newlist, tail);
2070 list = TREE_CHAIN (list);
2076 /* Used by: build_private_template, get_class_ivars, and
2077 continue_class. COPY is 1 when called from @defs. In this case
2078 copy all fields. Otherwise don't copy leaf ivars since we rely on
2079 them being side-effected exactly once by finish_struct. */
2082 build_ivar_chain (interface, copy)
2086 tree my_name, super_name, ivar_chain;
2088 my_name = CLASS_NAME (interface);
2089 super_name = CLASS_SUPER_NAME (interface);
2091 /* Possibly copy leaf ivars. */
2093 objc_copy_list (CLASS_IVARS (interface), &ivar_chain);
2095 ivar_chain = CLASS_IVARS (interface);
2100 tree super_interface = lookup_interface (super_name);
2102 if (!super_interface)
2104 /* fatal did not work with 2 args...should fix */
2105 error ("Cannot find interface declaration for `%s', superclass of `%s'",
2106 IDENTIFIER_POINTER (super_name),
2107 IDENTIFIER_POINTER (my_name));
2110 if (super_interface == interface)
2112 fatal ("Circular inheritance in interface declaration for `%s'",
2113 IDENTIFIER_POINTER (super_name));
2115 interface = super_interface;
2116 my_name = CLASS_NAME (interface);
2117 super_name = CLASS_SUPER_NAME (interface);
2119 op1 = CLASS_IVARS (interface);
2122 tree head, tail = objc_copy_list (op1, &head);
2124 /* Prepend super class ivars...make a copy of the list, we
2125 do not want to alter the original. */
2126 TREE_CHAIN (tail) = ivar_chain;
2133 /* struct <classname> {
2134 struct objc_class *isa;
2139 build_private_template (class)
2144 if (CLASS_STATIC_TEMPLATE (class))
2146 uprivate_record = CLASS_STATIC_TEMPLATE (class);
2147 ivar_context = TYPE_FIELDS (CLASS_STATIC_TEMPLATE (class));
2151 uprivate_record = start_struct (RECORD_TYPE, CLASS_NAME (class));
2153 ivar_context = build_ivar_chain (class, 0);
2155 finish_struct (uprivate_record, ivar_context);
2157 CLASS_STATIC_TEMPLATE (class) = uprivate_record;
2159 /* mark this record as class template - for class type checking */
2160 TREE_STATIC_TEMPLATE (uprivate_record) = 1;
2162 instance_type = groktypename (build_tree_list (build_tree_list (NULLT, uprivate_record),
2163 build1 (INDIRECT_REF, NULLT, NULLT)));
2164 return ivar_context;
2167 /* Begin code generation for protocols... */
2169 /* struct objc_protocol {
2170 char *protocol_name;
2171 struct objc_protocol **protocol_list;
2172 struct objc_method_desc *instance_methods;
2173 struct objc_method_desc *class_methods;
2177 build_protocol_template ()
2179 tree decl_specs, field_decl, field_decl_chain;
2182 template = start_struct (RECORD_TYPE, get_identifier (UTAG_PROTOCOL));
2184 /* struct objc_class *isa; */
2186 decl_specs = build_tree_list (NULLT, xref_tag (RECORD_TYPE,
2187 get_identifier (UTAG_CLASS)));
2188 field_decl = build1 (INDIRECT_REF, NULLT, get_identifier ("isa"));
2189 field_decl = grokfield (input_filename, lineno, field_decl, decl_specs, NULLT);
2190 field_decl_chain = field_decl;
2192 /* char *protocol_name; */
2194 decl_specs = build_tree_list (NULLT, ridpointers[(int) RID_CHAR]);
2195 field_decl = build1 (INDIRECT_REF, NULLT, get_identifier ("protocol_name"));
2196 field_decl = grokfield (input_filename, lineno, field_decl, decl_specs, NULLT);
2197 chainon (field_decl_chain, field_decl);
2199 /* struct objc_protocol **protocol_list; */
2201 decl_specs = build_tree_list (NULLT, template);
2202 field_decl = build1 (INDIRECT_REF, NULLT, get_identifier ("protocol_list"));
2203 field_decl = build1 (INDIRECT_REF, NULLT, field_decl);
2204 field_decl = grokfield (input_filename, lineno, field_decl, decl_specs, NULLT);
2205 chainon (field_decl_chain, field_decl);
2207 /* struct objc_method_list *instance_methods; */
2209 decl_specs = build_tree_list (NULLT, xref_tag (RECORD_TYPE,
2210 get_identifier (UTAG_METHOD_PROTOTYPE_LIST)));
2211 field_decl = build1 (INDIRECT_REF, NULLT, get_identifier ("instance_methods"));
2212 field_decl = grokfield (input_filename, lineno, field_decl, decl_specs, NULLT);
2213 chainon (field_decl_chain, field_decl);
2215 /* struct objc_method_list *class_methods; */
2217 decl_specs = build_tree_list (NULLT, xref_tag (RECORD_TYPE,
2218 get_identifier (UTAG_METHOD_PROTOTYPE_LIST)));
2219 field_decl = build1 (INDIRECT_REF, NULLT, get_identifier ("class_methods"));
2220 field_decl = grokfield (input_filename, lineno, field_decl, decl_specs, NULLT);
2221 chainon (field_decl_chain, field_decl);
2223 return finish_struct (template, field_decl_chain);
2227 build_descriptor_table_initializer (entries, size)
2231 tree initlist = NULLT;
2235 initlist = tree_cons (NULLT, build_selector (METHOD_SEL_NAME (entries)), initlist);
2237 initlist = tree_cons (NULLT, add_objc_string (METHOD_ENCODING (entries), meth_var_types), initlist);
2240 entries = TREE_CHAIN (entries);
2244 return build_nt (CONSTRUCTOR, NULLT, nreverse (initlist));
2247 /* struct objc_method_prototype_list {
2249 struct objc_method_prototype {
2256 build_method_prototype_list_template (list_type, size)
2260 tree objc_ivar_list_record;
2261 tree decl_specs, field_decl, field_decl_chain;
2263 /* generate an unnamed struct definition */
2265 objc_ivar_list_record = start_struct (RECORD_TYPE, NULLT);
2267 /* int method_count; */
2269 decl_specs = build_tree_list (NULLT, ridpointers[(int) RID_INT]);
2270 field_decl = get_identifier ("method_count");
2272 field_decl = grokfield (input_filename, lineno, field_decl, decl_specs, NULLT);
2273 field_decl_chain = field_decl;
2275 /* struct objc_method method_list[]; */
2277 decl_specs = build_tree_list (NULLT, list_type);
2278 field_decl = build_nt (ARRAY_REF, get_identifier ("method_list"),
2279 build_int_2 (size, 0));
2281 field_decl = grokfield (input_filename, lineno, field_decl, decl_specs, NULLT);
2282 chainon (field_decl_chain, field_decl);
2284 finish_struct (objc_ivar_list_record, field_decl_chain);
2286 return objc_ivar_list_record;
2290 build_method_prototype_template ()
2293 tree decl_specs, field_decl, field_decl_chain;
2295 proto_record = start_struct (RECORD_TYPE, get_identifier (UTAG_METHOD_PROTOTYPE));
2297 #ifdef OBJC_INT_SELECTORS
2298 /* unsigned int _cmd; */
2299 decl_specs = tree_cons (NULLT, ridpointers[(int) RID_UNSIGNED], NULLT);
2300 decl_specs = tree_cons (NULLT, ridpointers[(int) RID_INT], decl_specs);
2301 field_decl = get_identifier ("_cmd");
2302 #else /* OBJC_INT_SELECTORS */
2303 /* struct objc_selector *_cmd; */
2304 decl_specs = tree_cons (NULLT, xref_tag (RECORD_TYPE,
2305 get_identifier (TAG_SELECTOR)), NULLT);
2306 field_decl = build1 (INDIRECT_REF, NULLT, get_identifier ("_cmd"));
2307 #endif /* OBJC_INT_SELECTORS */
2309 field_decl = grokfield (input_filename, lineno, field_decl, decl_specs, NULLT);
2310 field_decl_chain = field_decl;
2312 decl_specs = tree_cons (NULLT, ridpointers[(int) RID_CHAR], NULLT);
2313 field_decl = build1 (INDIRECT_REF, NULLT, get_identifier ("method_types"));
2314 field_decl = grokfield (input_filename, lineno, field_decl, decl_specs, NULLT);
2315 chainon (field_decl_chain, field_decl);
2317 finish_struct (proto_record, field_decl_chain);
2319 return proto_record;
2323 forwarding_offset (parm)
2326 int offset_in_bytes;
2328 if (GET_CODE (DECL_INCOMING_RTL (parm)) == MEM)
2330 rtx addr = XEXP (DECL_INCOMING_RTL (parm), 0);
2332 /* ??? Here we assume that the parm address is indexed
2333 off the frame pointer or arg pointer.
2334 If that is not true, we produce meaningless results,
2335 but do not crash. */
2336 if (GET_CODE (addr) == PLUS
2337 && GET_CODE (XEXP (addr, 1)) == CONST_INT)
2338 offset_in_bytes = INTVAL (XEXP (addr, 1));
2340 offset_in_bytes = 0;
2342 offset_in_bytes += OBJC_FORWARDING_STACK_OFFSET;
2344 #ifdef OBJC_FORWARDING_REG_OFFSET
2345 else if (GET_CODE (DECL_INCOMING_RTL (parm)) == REG)
2347 int regno = REGNO (DECL_INCOMING_RTL (parm));
2349 offset_in_bytes = 4 * (regno - OBJC_FORWARDING_FIRST_REG)
2350 + OBJC_FORWARDING_REG_OFFSET;
2352 #endif /* OBJC_FORWARDING_REG_OFFSET */
2356 /* This is the case where the parm is passed as an int or double
2357 and it is converted to a char, short or float and stored back
2358 in the parmlist. In this case, describe the parm
2359 with the variable's declared type, and adjust the address
2360 if the least significant bytes (which we are using) are not
2362 #if BYTES_BIG_ENDIAN
2363 if (TREE_TYPE (parm) != DECL_ARG_TYPE (parm))
2364 offset_in_bytes += (GET_MODE_SIZE (TYPE_MODE (DECL_ARG_TYPE (parm)))
2365 - GET_MODE_SIZE (GET_MODE (DECL_RTL (parm))));
2368 return offset_in_bytes;
2372 encode_method_prototype (method_decl, func_decl)
2379 int max_parm_end = 0;
2383 /* `oneway' and 'bycopy', for remote object are the only method qualifiers */
2384 encode_type_qualifiers (TREE_PURPOSE (TREE_TYPE (method_decl)));
2387 encode_type (TREE_TYPE (TREE_TYPE (func_decl)),
2388 obstack_object_size (&util_obstack),
2389 OBJC_ENCODE_INLINE_DEFS);
2392 for (parms = DECL_ARGUMENTS (func_decl); parms;
2393 parms = TREE_CHAIN (parms))
2395 int parm_end = (forwarding_offset (parms)
2396 + (TREE_INT_CST_LOW (TYPE_SIZE (TREE_TYPE (parms)))
2399 if (parm_end > max_parm_end)
2400 max_parm_end = parm_end;
2403 stack_size = max_parm_end - OBJC_FORWARDING_MIN_OFFSET;
2405 sprintf (buf, "%d", stack_size);
2406 obstack_grow (&util_obstack, buf, strlen (buf));
2408 user_args = METHOD_SEL_ARGS (method_decl);
2410 /* argument types */
2411 for (parms = DECL_ARGUMENTS (func_decl), i = 0; parms;
2412 parms = TREE_CHAIN (parms), i++)
2414 /* process argument qualifiers for user supplied arguments */
2417 encode_type_qualifiers (TREE_PURPOSE (TREE_TYPE (user_args)));
2418 user_args = TREE_CHAIN (user_args);
2422 encode_type (TREE_TYPE (parms),
2423 obstack_object_size (&util_obstack),
2424 OBJC_ENCODE_INLINE_DEFS);
2426 /* compute offset */
2427 sprintf (buf, "%d", forwarding_offset (parms));
2428 obstack_grow (&util_obstack, buf, strlen (buf));
2431 obstack_1grow (&util_obstack, '\0');
2432 result = get_identifier (obstack_finish (&util_obstack));
2433 obstack_free (&util_obstack, util_firstobj);
2438 generate_descriptor_table (type, name, size, list, proto)
2445 tree sc_spec, decl_specs, decl, initlist;
2447 sc_spec = tree_cons (NULLT, ridpointers[(int) RID_STATIC], NULLT);
2448 decl_specs = tree_cons (NULLT, type, sc_spec);
2450 decl = start_decl (synth_id_with_class_suffix (name, proto),
2452 end_temporary_allocation ();
2454 initlist = build_tree_list (NULLT, build_int_2 (size, 0));
2455 initlist = tree_cons (NULLT, list, initlist);
2457 finish_decl (decl, build_nt (CONSTRUCTOR, NULLT, nreverse (initlist)), NULLT);
2463 generate_method_descriptors (protocol) /* generate_dispatch_tables */
2466 static tree objc_method_prototype_template;
2467 tree initlist, chain, method_list_template;
2468 tree cast, variable_length_type;
2471 if (!objc_method_prototype_template)
2472 objc_method_prototype_template = build_method_prototype_template ();
2474 cast = build_tree_list (build_tree_list (NULLT, xref_tag (RECORD_TYPE,
2475 get_identifier (UTAG_METHOD_PROTOTYPE_LIST))), NULLT);
2476 variable_length_type = groktypename (cast);
2478 chain = PROTOCOL_CLS_METHODS (protocol);
2483 initlist = build_descriptor_table_initializer (chain, &size);
2485 method_list_template
2486 = build_method_prototype_list_template (objc_method_prototype_template,
2489 UOBJC_CLASS_METHODS_decl
2490 = generate_descriptor_table (method_list_template,
2491 "_OBJC_PROTOCOL_CLASS_METHODS",
2492 size, initlist, protocol);
2494 TREE_TYPE (UOBJC_CLASS_METHODS_decl) = variable_length_type;
2497 UOBJC_CLASS_METHODS_decl = 0;
2499 chain = PROTOCOL_NST_METHODS (protocol);
2503 initlist = build_descriptor_table_initializer (chain, &size);
2505 method_list_template
2506 = build_method_prototype_list_template (objc_method_prototype_template,
2509 UOBJC_INSTANCE_METHODS_decl
2510 = generate_descriptor_table (method_list_template,
2511 "_OBJC_PROTOCOL_INSTANCE_METHODS",
2512 size, initlist, protocol);
2514 TREE_TYPE (UOBJC_INSTANCE_METHODS_decl) = variable_length_type;
2517 UOBJC_INSTANCE_METHODS_decl = 0;
2521 build_tmp_function_decl ()
2523 tree decl_specs, expr_decl, parms;
2525 /* struct objc_object *objc_xxx (id, SEL, ...); */
2527 decl_specs = build_tree_list (NULLT, objc_object_reference);
2528 push_parm_decl (build_tree_list (decl_specs,
2529 build1 (INDIRECT_REF, NULLT, NULLT)));
2531 decl_specs = build_tree_list (NULLT, xref_tag (RECORD_TYPE,
2532 get_identifier (TAG_SELECTOR)));
2533 expr_decl = build1 (INDIRECT_REF, NULLT, NULLT);
2535 push_parm_decl (build_tree_list (decl_specs, expr_decl));
2536 parms = get_parm_info (0);
2539 decl_specs = build_tree_list (NULLT, objc_object_reference);
2540 expr_decl = build_nt (CALL_EXPR, get_identifier ("objc_xxx"), parms, NULLT);
2541 expr_decl = build1 (INDIRECT_REF, NULLT, expr_decl);
2543 return define_decl (expr_decl, decl_specs);
2547 hack_method_prototype (nst_methods, tmp_decl)
2553 /* Hack to avoid problem with static typing of self arg. */
2554 TREE_SET_CODE (nst_methods, CLASS_METHOD_DECL);
2555 start_method_def (nst_methods);
2556 TREE_SET_CODE (nst_methods, INSTANCE_METHOD_DECL);
2558 if (METHOD_ADD_ARGS (nst_methods) == (tree) 1)
2559 parms = get_parm_info (0); /* we have a `, ...' */
2561 parms = get_parm_info (1); /* place a `void_at_end' */
2563 poplevel (0, 0, 0); /* Must be called BEFORE start_function. */
2565 /* Usually called from store_parm_decls -> init_function_start. */
2567 init_emit (); /* needed to make assign_parms work (with -O). */
2569 DECL_ARGUMENTS (tmp_decl) = TREE_PURPOSE (parms);
2572 /* Code taken from start_function. */
2573 tree restype = TREE_TYPE (TREE_TYPE (tmp_decl));
2574 /* Promote the value to int before returning it. */
2575 if (TREE_CODE (restype) == INTEGER_TYPE
2576 && TYPE_PRECISION (restype) < TYPE_PRECISION (integer_type_node))
2577 restype = integer_type_node;
2578 DECL_RESULT (tmp_decl) = build_decl (RESULT_DECL, 0, restype);
2581 /* Typically called from expand_function_start for function definitions. */
2582 assign_parms (tmp_decl, 0);
2584 /* install return type */
2585 TREE_TYPE (TREE_TYPE (tmp_decl)) = groktypename (TREE_TYPE (nst_methods));
2589 generate_protocol_references (plist)
2594 /* forward declare protocols referenced */
2595 for (lproto = plist; lproto; lproto = TREE_CHAIN (lproto))
2597 tree proto = TREE_VALUE (lproto);
2599 if (TREE_CODE (proto) == PROTOCOL_INTERFACE_TYPE
2600 && PROTOCOL_NAME (proto))
2602 if (! PROTOCOL_FORWARD_DECL (proto))
2603 build_protocol_reference (proto);
2605 if (PROTOCOL_LIST (proto))
2606 generate_protocol_references (PROTOCOL_LIST (proto));
2612 generate_protocols ()
2614 tree p, tmp_decl, encoding;
2615 tree sc_spec, decl_specs, decl;
2616 tree initlist, protocol_name_expr, refs_decl, refs_expr;
2617 tree cast_type2 = 0;
2619 tmp_decl = build_tmp_function_decl ();
2621 if (! objc_protocol_template)
2622 objc_protocol_template = build_protocol_template ();
2624 /* if a protocol was directly referenced, pull in indirect references */
2625 for (p = protocol_chain; p; p = TREE_CHAIN (p))
2626 if (PROTOCOL_FORWARD_DECL (p) && PROTOCOL_LIST (p))
2627 generate_protocol_references (PROTOCOL_LIST (p));
2629 for (p = protocol_chain; p; p = TREE_CHAIN (p))
2631 tree nst_methods = PROTOCOL_NST_METHODS (p);
2632 tree cls_methods = PROTOCOL_CLS_METHODS (p);
2634 /* if protocol wasn't referenced, don't generate any code */
2635 if (! PROTOCOL_FORWARD_DECL (p))
2638 /* Make sure we link in the Protocol class. */
2639 add_class_reference (get_identifier (PROTOCOL_OBJECT_CLASS_NAME));
2643 hack_method_prototype (nst_methods, tmp_decl);
2644 encoding = encode_method_prototype (nst_methods, tmp_decl);
2645 METHOD_ENCODING (nst_methods) = encoding;
2647 nst_methods = TREE_CHAIN (nst_methods);
2652 hack_method_prototype (cls_methods, tmp_decl);
2653 encoding = encode_method_prototype (cls_methods, tmp_decl);
2654 METHOD_ENCODING (cls_methods) = encoding;
2656 cls_methods = TREE_CHAIN (cls_methods);
2658 generate_method_descriptors (p);
2660 if (PROTOCOL_LIST (p))
2661 refs_decl = generate_protocol_list (p);
2665 /* static struct objc_protocol _OBJC_PROTOCOL_<mumble>; */
2667 sc_spec = tree_cons (NULLT, ridpointers[(int) RID_STATIC], NULLT);
2668 decl_specs = tree_cons (NULLT, objc_protocol_template, sc_spec);
2670 decl = start_decl (synth_id_with_class_suffix ("_OBJC_PROTOCOL", p),
2672 end_temporary_allocation ();
2674 protocol_name_expr = add_objc_string (PROTOCOL_NAME (p), class_names);
2680 = groktypename (build_tree_list (build_tree_list (NULLT, objc_protocol_template),
2681 build1 (INDIRECT_REF, NULLT,
2682 build1 (INDIRECT_REF, NULLT, NULLT))));
2684 refs_expr = build_unary_op (ADDR_EXPR, refs_decl, 0);
2685 TREE_TYPE (refs_expr) = cast_type2;
2688 refs_expr = build_int_2 (0, 0);
2690 /* UOBJC_INSTANCE_METHODS_decl/UOBJC_CLASS_METHODS_decl are set
2691 by generate_method_descriptors, which is called above. */
2692 initlist = build_protocol_initializer (protocol_name_expr, refs_expr,
2693 UOBJC_INSTANCE_METHODS_decl,
2694 UOBJC_CLASS_METHODS_decl);
2695 finish_decl (decl, initlist, NULLT);
2697 /* Mark the decl as used to avoid "defined but not used" warning. */
2698 TREE_USED (decl) = 1;
2703 build_protocol_initializer (protocol_name, protocol_list,
2704 instance_methods, class_methods)
2707 tree instance_methods;
2710 tree initlist = NULLT, expr;
2711 static tree cast_type = 0;
2715 = groktypename (build_tree_list
2716 (build_tree_list (NULLT,
2717 xref_tag (RECORD_TYPE,
2718 get_identifier (UTAG_CLASS))),
2719 build1 (INDIRECT_REF, NULLT, NULLT)));
2721 /* filling the "isa" in with one allows the runtime system to
2722 detect that the version change...should remove before final release */
2724 expr = build_int_2 (PROTOCOL_VERSION, 0);
2725 TREE_TYPE (expr) = cast_type;
2726 initlist = tree_cons (NULLT, expr, initlist);
2727 initlist = tree_cons (NULLT, protocol_name, initlist);
2728 initlist = tree_cons (NULLT, protocol_list, initlist);
2730 if (!instance_methods)
2731 initlist = tree_cons (NULLT, build_int_2 (0, 0), initlist);
2734 expr = build_unary_op (ADDR_EXPR, instance_methods, 0);
2735 initlist = tree_cons (NULLT, expr, initlist);
2738 initlist = tree_cons (NULLT, build_int_2 (0, 0), initlist);
2741 expr = build_unary_op (ADDR_EXPR, class_methods, 0);
2742 initlist = tree_cons (NULLT, expr, initlist);
2744 return build_nt (CONSTRUCTOR, NULLT, nreverse (initlist));
2746 /* end code generation for protocols... */
2748 /* struct objc_category {
2749 char *category_name;
2751 struct objc_method_list *instance_methods;
2752 struct objc_method_list *class_methods;
2753 struct objc_protocol_list *protocols;
2757 build_category_template ()
2759 tree decl_specs, field_decl, field_decl_chain;
2761 objc_category_template = start_struct (RECORD_TYPE,
2762 get_identifier (UTAG_CATEGORY));
2763 /* char *category_name; */
2765 decl_specs = build_tree_list (NULLT, ridpointers[(int) RID_CHAR]);
2766 field_decl = build1 (INDIRECT_REF, NULLT, get_identifier ("category_name"));
2767 field_decl = grokfield (input_filename, lineno, field_decl, decl_specs, NULLT);
2768 field_decl_chain = field_decl;
2770 /* char *class_name; */
2772 decl_specs = build_tree_list (NULLT, ridpointers[(int) RID_CHAR]);
2773 field_decl = build1 (INDIRECT_REF, NULLT, get_identifier ("class_name"));
2774 field_decl = grokfield (input_filename, lineno, field_decl, decl_specs, NULLT);
2775 chainon (field_decl_chain, field_decl);
2777 /* struct objc_method_list *instance_methods; */
2779 decl_specs = build_tree_list (NULLT, xref_tag (RECORD_TYPE,
2780 get_identifier (UTAG_METHOD_LIST)));
2781 field_decl = build1 (INDIRECT_REF, NULLT, get_identifier ("instance_methods"));
2782 field_decl = grokfield (input_filename, lineno, field_decl, decl_specs, NULLT);
2783 chainon (field_decl_chain, field_decl);
2785 /* struct objc_method_list *class_methods; */
2787 decl_specs = build_tree_list (NULLT, xref_tag (RECORD_TYPE,
2788 get_identifier (UTAG_METHOD_LIST)));
2789 field_decl = build1 (INDIRECT_REF, NULLT, get_identifier ("class_methods"));
2790 field_decl = grokfield (input_filename, lineno, field_decl, decl_specs, NULLT);
2791 chainon (field_decl_chain, field_decl);
2793 /* struct objc_protocol **protocol_list; */
2795 decl_specs = build_tree_list (NULLT, xref_tag (RECORD_TYPE,
2796 get_identifier (UTAG_PROTOCOL)));
2797 field_decl = build1 (INDIRECT_REF, NULLT, get_identifier ("protocol_list"));
2798 field_decl = build1 (INDIRECT_REF, NULLT, field_decl);
2799 field_decl = grokfield (input_filename, lineno, field_decl, decl_specs, NULLT)
2801 chainon (field_decl_chain, field_decl);
2803 finish_struct (objc_category_template, field_decl_chain);
2806 /* struct objc_class {
2807 struct objc_class *isa;
2808 struct objc_class *super_class;
2813 struct objc_ivar_list *ivars;
2814 struct objc_method_list *methods;
2815 if (flag_next_runtime)
2816 struct objc_cache *cache;
2818 struct sarray *dtable;
2819 struct objc_class *subclass_list;
2820 struct objc_class *sibling_class;
2822 struct objc_protocol_list *protocols;
2826 build_class_template ()
2828 tree decl_specs, field_decl, field_decl_chain;
2830 objc_class_template = start_struct (RECORD_TYPE, get_identifier (UTAG_CLASS));
2832 /* struct objc_class *isa; */
2834 decl_specs = build_tree_list (NULLT, objc_class_template);
2835 field_decl = build1 (INDIRECT_REF, NULLT, get_identifier ("isa"));
2836 field_decl = grokfield (input_filename, lineno, field_decl, decl_specs, NULLT);
2837 field_decl_chain = field_decl;
2839 /* struct objc_class *super_class; */
2841 decl_specs = build_tree_list (NULLT, objc_class_template);
2842 field_decl = build1 (INDIRECT_REF, NULLT, get_identifier ("super_class"));
2843 field_decl = grokfield (input_filename, lineno, field_decl, decl_specs, NULLT);
2844 chainon (field_decl_chain, field_decl);
2848 decl_specs = build_tree_list (NULLT, ridpointers[(int) RID_CHAR]);
2849 field_decl = build1 (INDIRECT_REF, NULLT, get_identifier ("name"));
2850 field_decl = grokfield (input_filename, lineno, field_decl, decl_specs, NULLT);
2851 chainon (field_decl_chain, field_decl);
2855 decl_specs = build_tree_list (NULLT, ridpointers[(int) RID_LONG]);
2856 field_decl = get_identifier ("version");
2857 field_decl = grokfield (input_filename, lineno, field_decl, decl_specs, NULLT);
2858 chainon (field_decl_chain, field_decl);
2862 decl_specs = build_tree_list (NULLT, ridpointers[(int) RID_LONG]);
2863 field_decl = get_identifier ("info");
2864 field_decl = grokfield (input_filename, lineno, field_decl, decl_specs, NULLT);
2865 chainon (field_decl_chain, field_decl);
2867 /* long instance_size; */
2869 decl_specs = build_tree_list (NULLT, ridpointers[(int) RID_LONG]);
2870 field_decl = get_identifier ("instance_size");
2871 field_decl = grokfield (input_filename, lineno, field_decl, decl_specs, NULLT);
2872 chainon (field_decl_chain, field_decl);
2874 /* struct objc_ivar_list *ivars; */
2876 decl_specs = build_tree_list (NULLT, xref_tag (RECORD_TYPE,
2877 get_identifier (UTAG_IVAR_LIST)));
2878 field_decl = build1 (INDIRECT_REF, NULLT, get_identifier ("ivars"));
2879 field_decl = grokfield (input_filename, lineno, field_decl, decl_specs, NULLT);
2880 chainon (field_decl_chain, field_decl);
2882 /* struct objc_method_list *methods; */
2884 decl_specs = build_tree_list (NULLT, xref_tag (RECORD_TYPE,
2885 get_identifier (UTAG_METHOD_LIST)));
2886 field_decl = build1 (INDIRECT_REF, NULLT, get_identifier ("methods"));
2887 field_decl = grokfield (input_filename, lineno, field_decl, decl_specs, NULLT);
2888 chainon (field_decl_chain, field_decl);
2890 if (flag_next_runtime)
2892 /* struct objc_cache *cache; */
2894 decl_specs = build_tree_list (NULLT, xref_tag (RECORD_TYPE,
2895 get_identifier ("objc_cache")));
2896 field_decl = build1 (INDIRECT_REF, NULLT, get_identifier ("cache"));
2897 field_decl = grokfield (input_filename, lineno, field_decl, decl_specs, NULLT);
2898 chainon (field_decl_chain, field_decl);
2902 /* struct sarray *dtable; */
2904 decl_specs = build_tree_list (NULLT, xref_tag (RECORD_TYPE,
2905 get_identifier ("sarray")));
2906 field_decl = build1 (INDIRECT_REF, NULLT, get_identifier ("dtable"));
2907 field_decl = grokfield (input_filename, lineno, field_decl, decl_specs, NULLT);
2908 chainon (field_decl_chain, field_decl);
2910 /* struct objc_class *subclass_list; */
2912 decl_specs = build_tree_list (NULLT, objc_class_template);
2913 field_decl = build1 (INDIRECT_REF, NULLT, get_identifier ("subclass_list"));
2914 field_decl = grokfield (input_filename, lineno, field_decl, decl_specs, NULLT);
2915 chainon (field_decl_chain, field_decl);
2917 /* struct objc_class *sibling_class; */
2919 decl_specs = build_tree_list (NULLT, objc_class_template);
2920 field_decl = build1 (INDIRECT_REF, NULLT, get_identifier ("sibling_class"));
2921 field_decl = grokfield (input_filename, lineno, field_decl, decl_specs, NULLT);
2922 chainon (field_decl_chain, field_decl);
2925 /* struct objc_protocol **protocol_list; */
2927 decl_specs = build_tree_list (NULLT, xref_tag (RECORD_TYPE,
2928 get_identifier (UTAG_PROTOCOL)));
2929 field_decl = build1 (INDIRECT_REF, NULLT, get_identifier ("protocol_list"));
2930 field_decl = build1 (INDIRECT_REF, NULLT, field_decl);
2931 field_decl = grokfield (input_filename, lineno, field_decl, decl_specs, NULLT);
2932 chainon (field_decl_chain, field_decl);
2935 finish_struct (objc_class_template, field_decl_chain);
2938 /* Generate appropriate forward declarations for an implementation. */
2941 synth_forward_declarations ()
2943 tree sc_spec, decl_specs, an_id;
2945 /* extern struct objc_class _OBJC_CLASS_<my_name>; */
2947 an_id = synth_id_with_class_suffix ("_OBJC_CLASS", implementation_context);
2949 sc_spec = build_tree_list (NULLT, ridpointers[(int) RID_EXTERN]);
2950 decl_specs = tree_cons (NULLT, objc_class_template, sc_spec);
2951 UOBJC_CLASS_decl = define_decl (an_id, decl_specs);
2952 TREE_USED (UOBJC_CLASS_decl) = 1;
2954 /* extern struct objc_class _OBJC_METACLASS_<my_name>; */
2956 an_id = synth_id_with_class_suffix ("_OBJC_METACLASS",
2957 implementation_context);
2959 UOBJC_METACLASS_decl = define_decl (an_id, decl_specs);
2960 TREE_USED (UOBJC_METACLASS_decl) = 1;
2962 /* pre-build the following entities - for speed/convenience. */
2964 an_id = get_identifier ("super_class");
2965 ucls_super_ref = build_component_ref (UOBJC_CLASS_decl, an_id);
2966 uucls_super_ref = build_component_ref (UOBJC_METACLASS_decl, an_id);
2970 error_with_ivar (message, decl, rawdecl)
2977 report_error_function (DECL_SOURCE_FILE (decl));
2979 fprintf (stderr, "%s:%d: ",
2980 DECL_SOURCE_FILE (decl), DECL_SOURCE_LINE (decl));
2981 bzero (errbuf, BUFSIZE);
2982 fprintf (stderr, "%s `%s'\n", message, gen_declaration (rawdecl, errbuf));
2985 #define USERTYPE(t) (TREE_CODE (t) == RECORD_TYPE || \
2986 TREE_CODE (t) == UNION_TYPE || \
2987 TREE_CODE (t) == ENUMERAL_TYPE)
2990 check_ivars (inter, imp)
2994 tree intdecls = CLASS_IVARS (inter);
2995 tree impdecls = CLASS_IVARS (imp);
2996 tree rawintdecls = CLASS_RAW_IVARS (inter);
2997 tree rawimpdecls = CLASS_RAW_IVARS (imp);
3003 if (intdecls == 0 && impdecls == 0)
3005 if (intdecls == 0 || impdecls == 0)
3007 error ("inconsistent instance variable specification");
3010 t1 = TREE_TYPE (intdecls); t2 = TREE_TYPE (impdecls);
3012 if (!comptypes (t1, t2))
3014 if (DECL_NAME (intdecls) == DECL_NAME (impdecls))
3016 error_with_ivar ("conflicting instance variable type",
3017 impdecls, rawimpdecls);
3018 error_with_ivar ("previous declaration of",
3019 intdecls, rawintdecls);
3021 else /* both the type and the name don't match */
3023 error ("inconsistent instance variable specification");
3027 else if (DECL_NAME (intdecls) != DECL_NAME (impdecls))
3029 error_with_ivar ("conflicting instance variable name",
3030 impdecls, rawimpdecls);
3031 error_with_ivar ("previous declaration of",
3032 intdecls, rawintdecls);
3034 intdecls = TREE_CHAIN (intdecls);
3035 impdecls = TREE_CHAIN (impdecls);
3036 rawintdecls = TREE_CHAIN (rawintdecls);
3037 rawimpdecls = TREE_CHAIN (rawimpdecls);
3041 /* Set super_type to the data type node for struct objc_super *,
3042 first defining struct objc_super itself.
3043 This needs to be done just once per compilation. */
3046 build_super_template ()
3048 tree record, decl_specs, field_decl, field_decl_chain;
3050 record = start_struct (RECORD_TYPE, get_identifier (UTAG_SUPER));
3052 /* struct objc_object *self; */
3054 decl_specs = build_tree_list (NULLT, objc_object_reference);
3055 field_decl = get_identifier ("self");
3056 field_decl = build1 (INDIRECT_REF, NULLT, field_decl);
3057 field_decl = grokfield (input_filename, lineno,
3058 field_decl, decl_specs, NULLT);
3059 field_decl_chain = field_decl;
3061 /* struct objc_class *class; */
3063 decl_specs = get_identifier (UTAG_CLASS);
3064 decl_specs = build_tree_list (NULLT, xref_tag (RECORD_TYPE, decl_specs));
3065 field_decl = build1 (INDIRECT_REF, NULLT, get_identifier ("class"));
3067 field_decl = grokfield (input_filename, lineno,
3068 field_decl, decl_specs, NULLT);
3069 chainon (field_decl_chain, field_decl);
3071 finish_struct (record, field_decl_chain);
3073 /* `struct objc_super *' */
3074 super_type = groktypename (build_tree_list (build_tree_list (NULLT, record),
3075 build1 (INDIRECT_REF,
3080 /* struct objc_ivar {
3087 build_ivar_template ()
3089 tree objc_ivar_id, objc_ivar_record;
3090 tree decl_specs, field_decl, field_decl_chain;
3092 objc_ivar_id = get_identifier (UTAG_IVAR);
3093 objc_ivar_record = start_struct (RECORD_TYPE, objc_ivar_id);
3095 /* char *ivar_name; */
3097 decl_specs = build_tree_list (NULLT, ridpointers[(int) RID_CHAR]);
3098 field_decl = build1 (INDIRECT_REF, NULLT, get_identifier ("ivar_name"));
3100 field_decl = grokfield (input_filename, lineno, field_decl,
3102 field_decl_chain = field_decl;
3104 /* char *ivar_type; */
3106 decl_specs = build_tree_list (NULLT, ridpointers[(int) RID_CHAR]);
3107 field_decl = build1 (INDIRECT_REF, NULLT, get_identifier ("ivar_type"));
3109 field_decl = grokfield (input_filename, lineno, field_decl,
3111 chainon (field_decl_chain, field_decl);
3113 /* int ivar_offset; */
3115 decl_specs = build_tree_list (NULLT, ridpointers[(int) RID_INT]);
3116 field_decl = get_identifier ("ivar_offset");
3118 field_decl = grokfield (input_filename, lineno, field_decl,
3120 chainon (field_decl_chain, field_decl);
3122 finish_struct (objc_ivar_record, field_decl_chain);
3124 return objc_ivar_record;
3129 struct objc_ivar ivar_list[ivar_count];
3133 build_ivar_list_template (list_type, size)
3137 tree objc_ivar_list_record;
3138 tree decl_specs, field_decl, field_decl_chain;
3140 objc_ivar_list_record = start_struct (RECORD_TYPE, NULLT);
3142 /* int ivar_count; */
3144 decl_specs = build_tree_list (NULLT, ridpointers[(int) RID_INT]);
3145 field_decl = get_identifier ("ivar_count");
3147 field_decl = grokfield (input_filename, lineno, field_decl,
3149 field_decl_chain = field_decl;
3151 /* struct objc_ivar ivar_list[]; */
3153 decl_specs = build_tree_list (NULLT, list_type);
3154 field_decl = build_nt (ARRAY_REF, get_identifier ("ivar_list"),
3155 build_int_2 (size, 0));
3157 field_decl = grokfield (input_filename, lineno,
3158 field_decl, decl_specs, NULLT);
3159 chainon (field_decl_chain, field_decl);
3161 finish_struct (objc_ivar_list_record, field_decl_chain);
3163 return objc_ivar_list_record;
3169 struct objc_method method_list[method_count];
3173 build_method_list_template (list_type, size)
3177 tree objc_ivar_list_record;
3178 tree decl_specs, field_decl, field_decl_chain;
3180 objc_ivar_list_record = start_struct (RECORD_TYPE, NULLT);
3182 /* int method_next; */
3184 decl_specs = build_tree_list (NULLT, ridpointers[(int) RID_INT]);
3185 field_decl = get_identifier ("method_next");
3187 field_decl = grokfield (input_filename, lineno, field_decl, decl_specs, NULLT);
3188 field_decl_chain = field_decl;
3190 /* int method_count; */
3192 decl_specs = build_tree_list (NULLT, ridpointers[(int) RID_INT]);
3193 field_decl = get_identifier ("method_count");
3195 field_decl = grokfield (input_filename, lineno,
3196 field_decl, decl_specs, NULLT);
3197 chainon (field_decl_chain, field_decl);
3199 /* struct objc_method method_list[]; */
3201 decl_specs = build_tree_list (NULLT, list_type);
3202 field_decl = build_nt (ARRAY_REF, get_identifier ("method_list"),
3203 build_int_2 (size, 0));
3205 field_decl = grokfield (input_filename, lineno,
3206 field_decl, decl_specs, NULLT);
3207 chainon (field_decl_chain, field_decl);
3209 finish_struct (objc_ivar_list_record, field_decl_chain);
3211 return objc_ivar_list_record;
3215 build_ivar_list_initializer (field_decl, size)
3219 tree initlist = NULLT;
3224 if (DECL_NAME (field_decl))
3225 initlist = tree_cons (NULLT,
3226 add_objc_string (DECL_NAME (field_decl),
3230 /* unnamed bit-field ivar (yuck). */
3231 initlist = tree_cons (NULLT, build_int_2 (0, 0), initlist);
3234 encode_field_decl (field_decl,
3235 obstack_object_size (&util_obstack),
3236 OBJC_ENCODE_DONT_INLINE_DEFS);
3237 obstack_1grow (&util_obstack, 0); /* null terminate string */
3241 add_objc_string (get_identifier (obstack_finish (&util_obstack)),
3244 obstack_free (&util_obstack, util_firstobj);
3250 build_int_2 ((TREE_INT_CST_LOW (DECL_FIELD_BITPOS (field_decl))
3255 field_decl = TREE_CHAIN (field_decl);
3259 return build_nt (CONSTRUCTOR, NULLT, nreverse (initlist));
3263 generate_ivars_list (type, name, size, list)
3269 tree sc_spec, decl_specs, decl, initlist;
3271 sc_spec = tree_cons (NULLT, ridpointers[(int) RID_STATIC], NULLT);
3272 decl_specs = tree_cons (NULLT, type, sc_spec);
3274 decl = start_decl (synth_id_with_class_suffix (name, implementation_context),
3276 end_temporary_allocation ();
3278 initlist = build_tree_list (NULLT, build_int_2 (size, 0));
3279 initlist = tree_cons (NULLT, list, initlist);
3281 finish_decl (decl, build_nt (CONSTRUCTOR, NULLT, nreverse (initlist)), NULLT);
3287 generate_ivar_lists ()
3289 tree initlist, ivar_list_template, chain;
3290 tree cast, variable_length_type;
3293 generating_instance_variables = 1;
3295 if (!objc_ivar_template)
3296 objc_ivar_template = build_ivar_template ();
3300 (build_tree_list (NULLT, xref_tag (RECORD_TYPE,
3301 get_identifier (UTAG_IVAR_LIST))),
3303 variable_length_type = groktypename (cast);
3305 /* only generate class variables for the root of the inheritance
3306 hierarchy since these will be the same for every class */
3308 if (CLASS_SUPER_NAME (implementation_template) == NULLT
3309 && (chain = TYPE_FIELDS (objc_class_template)))
3312 initlist = build_ivar_list_initializer (chain, &size);
3314 ivar_list_template = build_ivar_list_template (objc_ivar_template, size);
3316 UOBJC_CLASS_VARIABLES_decl =
3317 generate_ivars_list (ivar_list_template, "_OBJC_CLASS_VARIABLES",
3320 TREE_TYPE (UOBJC_CLASS_VARIABLES_decl) = variable_length_type;
3323 UOBJC_CLASS_VARIABLES_decl = 0;
3325 chain = CLASS_IVARS (implementation_template);
3329 initlist = build_ivar_list_initializer (chain, &size);
3331 ivar_list_template = build_ivar_list_template (objc_ivar_template, size);
3333 UOBJC_INSTANCE_VARIABLES_decl =
3334 generate_ivars_list (ivar_list_template, "_OBJC_INSTANCE_VARIABLES",
3337 TREE_TYPE (UOBJC_INSTANCE_VARIABLES_decl) = variable_length_type;
3340 UOBJC_INSTANCE_VARIABLES_decl = 0;
3342 generating_instance_variables = 0;
3346 build_dispatch_table_initializer (entries, size)
3350 tree initlist = NULLT;
3354 initlist = tree_cons (NULLT, build_selector (METHOD_SEL_NAME (entries)),
3357 initlist = tree_cons (NULLT, add_objc_string (METHOD_ENCODING (entries),
3361 initlist = tree_cons (NULLT, METHOD_DEFINITION (entries), initlist);
3364 entries = TREE_CHAIN (entries);
3368 return build_nt (CONSTRUCTOR, NULLT, nreverse (initlist));
3371 /* To accomplish method prototyping without generating all kinds of
3372 inane warnings, the definition of the dispatch table entries were
3375 struct objc_method { SEL _cmd; id (*_imp)(); };
3377 struct objc_method { SEL _cmd; void *_imp; }; */
3380 build_method_template ()
3383 tree decl_specs, field_decl, field_decl_chain;
3385 _SLT_record = start_struct (RECORD_TYPE, get_identifier (UTAG_METHOD));
3387 #ifdef OBJC_INT_SELECTORS
3388 /* unsigned int _cmd; */
3389 decl_specs = tree_cons (NULLT, ridpointers[(int) RID_UNSIGNED], NULLT);
3390 decl_specs = tree_cons (NULLT, ridpointers[(int) RID_INT], decl_specs);
3391 field_decl = get_identifier ("_cmd");
3392 #else /* not OBJC_INT_SELECTORS */
3393 /* struct objc_selector *_cmd; */
3394 decl_specs = tree_cons (NULLT,
3395 xref_tag (RECORD_TYPE,
3396 get_identifier (TAG_SELECTOR)),
3398 field_decl = build1 (INDIRECT_REF, NULLT, get_identifier ("_cmd"));
3399 #endif /* not OBJC_INT_SELECTORS */
3401 field_decl = grokfield (input_filename, lineno, field_decl, decl_specs, NULLT);
3402 field_decl_chain = field_decl;
3404 decl_specs = tree_cons (NULLT, ridpointers[(int) RID_CHAR], NULLT);
3405 field_decl = build1 (INDIRECT_REF, NULLT, get_identifier ("method_types"));
3406 field_decl = grokfield (input_filename, lineno, field_decl, decl_specs, NULLT);
3407 chainon (field_decl_chain, field_decl);
3411 decl_specs = tree_cons (NULLT, ridpointers[(int) RID_VOID], NULLT);
3412 field_decl = build1 (INDIRECT_REF, NULLT, get_identifier ("_imp"));
3413 field_decl = grokfield (input_filename, lineno, field_decl, decl_specs, NULLT);
3414 chainon (field_decl_chain, field_decl);
3416 finish_struct (_SLT_record, field_decl_chain);
3423 generate_dispatch_table (type, name, size, list)
3429 tree sc_spec, decl_specs, decl, initlist;
3431 sc_spec = tree_cons (NULLT, ridpointers[(int) RID_STATIC], NULLT);
3432 decl_specs = tree_cons (NULLT, type, sc_spec);
3434 decl = start_decl (synth_id_with_class_suffix (name, implementation_context),
3436 end_temporary_allocation ();
3438 initlist = build_tree_list (NULLT, build_int_2 (0, 0));
3439 initlist = tree_cons (NULLT, build_int_2 (size, 0), initlist);
3440 initlist = tree_cons (NULLT, list, initlist);
3442 finish_decl (decl, build_nt (CONSTRUCTOR, NULLT, nreverse (initlist)), NULLT);
3448 generate_dispatch_tables ()
3450 tree initlist, chain, method_list_template;
3451 tree cast, variable_length_type;
3454 if (!objc_method_template)
3455 objc_method_template = build_method_template ();
3459 (build_tree_list (NULLT, xref_tag (RECORD_TYPE,
3460 get_identifier (UTAG_METHOD_LIST))),
3462 variable_length_type = groktypename (cast);
3464 chain = CLASS_CLS_METHODS (implementation_context);
3468 initlist = build_dispatch_table_initializer (chain, &size);
3470 method_list_template = build_method_list_template (objc_method_template,
3473 UOBJC_CLASS_METHODS_decl
3474 = generate_dispatch_table (method_list_template,
3475 ((TREE_CODE (implementation_context)
3476 == CLASS_IMPLEMENTATION_TYPE)
3477 ? "_OBJC_CLASS_METHODS"
3478 : "_OBJC_CATEGORY_CLASS_METHODS"),
3481 TREE_TYPE (UOBJC_CLASS_METHODS_decl) = variable_length_type;
3484 UOBJC_CLASS_METHODS_decl = 0;
3486 chain = CLASS_NST_METHODS (implementation_context);
3490 initlist = build_dispatch_table_initializer (chain, &size);
3492 method_list_template = build_method_list_template (objc_method_template,
3494 if (TREE_CODE (implementation_context) == CLASS_IMPLEMENTATION_TYPE)
3495 UOBJC_INSTANCE_METHODS_decl =
3496 generate_dispatch_table (method_list_template,
3497 "_OBJC_INSTANCE_METHODS",
3500 /* we have a category */
3501 UOBJC_INSTANCE_METHODS_decl =
3502 generate_dispatch_table (method_list_template,
3503 "_OBJC_CATEGORY_INSTANCE_METHODS",
3506 TREE_TYPE (UOBJC_INSTANCE_METHODS_decl) = variable_length_type;
3509 UOBJC_INSTANCE_METHODS_decl = 0;
3513 generate_protocol_list (i_or_p)
3516 static tree cast_type = 0;
3517 tree initlist, decl_specs, sc_spec;
3518 tree refs_decl, expr_decl, lproto, e, plist;
3521 if (TREE_CODE (i_or_p) == CLASS_INTERFACE_TYPE
3522 || TREE_CODE (i_or_p) == CATEGORY_INTERFACE_TYPE)
3523 plist = CLASS_PROTOCOL_LIST (i_or_p);
3524 else if (TREE_CODE (i_or_p) == PROTOCOL_INTERFACE_TYPE)
3525 plist = PROTOCOL_LIST (i_or_p);
3533 (build_tree_list (NULLT,
3534 xref_tag (RECORD_TYPE,
3535 get_identifier (UTAG_PROTOCOL))),
3536 build1 (INDIRECT_REF, NULLT, NULLT)));
3539 for (lproto = plist; lproto; lproto = TREE_CHAIN (lproto))
3540 if (TREE_CODE (TREE_VALUE (lproto)) == PROTOCOL_INTERFACE_TYPE
3541 && PROTOCOL_FORWARD_DECL (TREE_VALUE (lproto)))
3544 /* build initializer */
3545 initlist = tree_cons (NULLT, build_int_2 (0, 0), NULLT);
3547 e = build_int_2 (size, 0);
3548 TREE_TYPE (e) = cast_type;
3549 initlist = tree_cons (NULLT, e, initlist);
3551 for (lproto = plist; lproto; lproto = TREE_CHAIN (lproto))
3553 tree pval = TREE_VALUE (lproto);
3555 if (TREE_CODE (pval) == PROTOCOL_INTERFACE_TYPE
3556 && PROTOCOL_FORWARD_DECL (pval))
3558 e = build_unary_op (ADDR_EXPR, PROTOCOL_FORWARD_DECL (pval), 0);
3559 initlist = tree_cons (NULLT, e, initlist);
3563 /* static struct objc_protocol *refs[n]; */
3565 sc_spec = tree_cons (NULLT, ridpointers[(int) RID_STATIC], NULLT);
3566 decl_specs = tree_cons (NULLT, xref_tag (RECORD_TYPE,
3567 get_identifier (UTAG_PROTOCOL)),
3570 if (TREE_CODE (i_or_p) == PROTOCOL_INTERFACE_TYPE)
3571 expr_decl = build_nt (ARRAY_REF,
3572 synth_id_with_class_suffix ("_OBJC_PROTOCOL_REFS",
3574 build_int_2 (size + 2, 0));
3575 else if (TREE_CODE (i_or_p) == CLASS_INTERFACE_TYPE)
3576 expr_decl = build_nt (ARRAY_REF,
3577 synth_id_with_class_suffix ("_OBJC_CLASS_PROTOCOLS",
3579 build_int_2 (size + 2, 0));
3580 else if (TREE_CODE (i_or_p) == CATEGORY_INTERFACE_TYPE)
3581 expr_decl = build_nt (ARRAY_REF,
3582 synth_id_with_class_suffix ("_OBJC_CATEGORY_PROTOCOLS",
3584 build_int_2 (size + 2, 0));
3586 expr_decl = build1 (INDIRECT_REF, NULLT, expr_decl);
3588 refs_decl = start_decl (expr_decl, decl_specs, 1);
3589 end_temporary_allocation ();
3591 finish_decl (refs_decl, build_nt (CONSTRUCTOR, NULLT,
3592 nreverse (initlist)), NULLT);
3598 build_category_initializer (cat_name, class_name,
3599 instance_methods, class_methods, protocol_list)
3602 tree instance_methods;
3606 tree initlist = NULLT, expr;
3608 initlist = tree_cons (NULLT, cat_name, initlist);
3609 initlist = tree_cons (NULLT, class_name, initlist);
3611 if (!instance_methods)
3612 initlist = tree_cons (NULLT, build_int_2 (0, 0), initlist);
3615 expr = build_unary_op (ADDR_EXPR, instance_methods, 0);
3616 initlist = tree_cons (NULLT, expr, initlist);
3619 initlist = tree_cons (NULLT, build_int_2 (0, 0), initlist);
3622 expr = build_unary_op (ADDR_EXPR, class_methods, 0);
3623 initlist = tree_cons (NULLT, expr, initlist);
3626 /* protocol_list = */
3628 initlist = tree_cons (NULLT, build_int_2 (0, 0), initlist);
3631 static tree cast_type2;
3637 (build_tree_list (NULLT,
3638 xref_tag (RECORD_TYPE,
3639 get_identifier (UTAG_PROTOCOL))),
3640 build1 (INDIRECT_REF, NULLT,
3641 build1 (INDIRECT_REF, NULLT, NULLT))));
3643 expr = build_unary_op (ADDR_EXPR, protocol_list, 0);
3644 TREE_TYPE (expr) = cast_type2;
3645 initlist = tree_cons (NULLT, expr, initlist);
3648 return build_nt (CONSTRUCTOR, NULLT, nreverse (initlist));
3651 /* struct objc_class {
3652 struct objc_class *isa;
3653 struct objc_class *super_class;
3658 struct objc_ivar_list *ivars;
3659 struct objc_method_list *methods;
3660 if (flag_next_runtime)
3661 struct objc_cache *cache;
3663 struct sarray *dtable;
3664 struct objc_class *subclass_list;
3665 struct objc_class *sibling_class;
3667 struct objc_protocol_list *protocols;
3671 build_shared_structure_initializer (isa, super, name, size, status,
3672 dispatch_table, ivar_list, protocol_list)
3678 tree dispatch_table;
3682 tree initlist = NULLT, expr;
3685 initlist = tree_cons (NULLT, isa, initlist);
3688 initlist = tree_cons (NULLT, super, initlist);
3691 initlist = tree_cons (NULLT, name, initlist);
3694 initlist = tree_cons (NULLT, build_int_2 (0, 0), initlist);
3697 initlist = tree_cons (NULLT, build_int_2 (status, 0), initlist);
3699 /* instance_size = */
3700 initlist = tree_cons (NULLT, size, initlist);
3702 /* objc_ivar_list = */
3704 initlist = tree_cons (NULLT, build_int_2 (0, 0), initlist);
3707 expr = build_unary_op (ADDR_EXPR, ivar_list, 0);
3708 initlist = tree_cons (NULLT, expr, initlist);
3711 /* objc_method_list = */
3712 if (!dispatch_table)
3713 initlist = tree_cons (NULLT, build_int_2 (0, 0), initlist);
3716 expr = build_unary_op (ADDR_EXPR, dispatch_table, 0);
3717 initlist = tree_cons (NULLT, expr, initlist);
3720 if (flag_next_runtime)
3721 /* method_cache = */
3722 initlist = tree_cons (NULLT, build_int_2 (0, 0), initlist);
3726 initlist = tree_cons (NULLT, build_int_2 (0, 0), initlist);
3728 /* subclass_list = */
3729 initlist = tree_cons (NULLT, build_int_2 (0, 0), initlist);
3731 /* sibling_class = */
3732 initlist = tree_cons (NULLT, build_int_2 (0, 0), initlist);
3735 /* protocol_list = */
3736 if (! protocol_list)
3737 initlist = tree_cons (NULLT, build_int_2 (0, 0), initlist);
3740 static tree cast_type2;
3746 (build_tree_list (NULLT,
3747 xref_tag (RECORD_TYPE,
3748 get_identifier (UTAG_PROTOCOL))),
3749 build1 (INDIRECT_REF, NULLT,
3750 build1 (INDIRECT_REF, NULLT, NULLT))));
3752 expr = build_unary_op (ADDR_EXPR, protocol_list, 0);
3753 TREE_TYPE (expr) = cast_type2;
3754 initlist = tree_cons (NULLT, expr, initlist);
3757 return build_nt (CONSTRUCTOR, NULLT, nreverse (initlist));
3760 /* static struct objc_category _OBJC_CATEGORY_<name> = { ... }; */
3762 generate_category (cat)
3765 tree sc_spec, decl_specs, decl;
3766 tree initlist, cat_name_expr, class_name_expr;
3767 tree protocol_decl, category;
3769 add_class_reference (CLASS_NAME (cat));
3770 cat_name_expr = add_objc_string (CLASS_SUPER_NAME (cat), class_names);
3772 class_name_expr = add_objc_string (CLASS_NAME (cat), class_names);
3774 category = CLASS_CATEGORY_LIST (implementation_template);
3776 /* find the category interface from the class it is associated with */
3779 if (CLASS_SUPER_NAME (cat) == CLASS_SUPER_NAME (category))
3781 category = CLASS_CATEGORY_LIST (category);
3784 if (category && CLASS_PROTOCOL_LIST (category))
3786 generate_protocol_references (CLASS_PROTOCOL_LIST (category));
3787 protocol_decl = generate_protocol_list (category);
3792 sc_spec = tree_cons (NULLT, ridpointers[(int) RID_STATIC], NULLT);
3793 decl_specs = tree_cons (NULLT, objc_category_template, sc_spec);
3795 decl = start_decl (synth_id_with_class_suffix ("_OBJC_CATEGORY",
3796 implementation_context),
3798 end_temporary_allocation ();
3800 initlist = build_category_initializer (cat_name_expr, class_name_expr,
3801 UOBJC_INSTANCE_METHODS_decl,
3802 UOBJC_CLASS_METHODS_decl,
3805 TREE_USED (decl) = 1;
3806 finish_decl (decl, initlist, NULLT);
3809 /* static struct objc_class _OBJC_METACLASS_Foo={ ... };
3810 static struct objc_class _OBJC_CLASS_Foo={ ... }; */
3813 generate_shared_structures ()
3815 tree sc_spec, decl_specs, decl;
3816 tree name_expr, super_expr, root_expr;
3817 tree my_root_id = NULLT, my_super_id = NULLT;
3818 tree cast_type, initlist, protocol_decl;
3820 my_super_id = CLASS_SUPER_NAME (implementation_template);
3823 add_class_reference (my_super_id);
3825 /* Compute "my_root_id" - this is required for code generation.
3826 the "isa" for all meta class structures points to the root of
3827 the inheritance hierarchy (e.g. "__Object")... */
3828 my_root_id = my_super_id;
3831 tree my_root_int = lookup_interface (my_root_id);
3833 if (my_root_int && CLASS_SUPER_NAME (my_root_int))
3834 my_root_id = CLASS_SUPER_NAME (my_root_int);
3840 else /* no super class */
3842 my_root_id = CLASS_NAME (implementation_template);
3846 = groktypename (build_tree_list (build_tree_list (NULLT,
3847 objc_class_template),
3848 build1 (INDIRECT_REF, NULLT, NULLT)));
3850 name_expr = add_objc_string (CLASS_NAME (implementation_template),
3853 /* install class `isa' and `super' pointers at runtime */
3856 super_expr = add_objc_string (my_super_id, class_names);
3857 super_expr = build_c_cast (cast_type, super_expr); /* cast! */
3860 super_expr = build_int_2 (0, 0);
3862 root_expr = add_objc_string (my_root_id, class_names);
3863 root_expr = build_c_cast (cast_type, root_expr); /* cast! */
3865 if (CLASS_PROTOCOL_LIST (implementation_template))
3867 generate_protocol_references (CLASS_PROTOCOL_LIST (implementation_template));
3868 protocol_decl = generate_protocol_list (implementation_template);
3873 /* static struct objc_class _OBJC_METACLASS_Foo = { ... }; */
3875 sc_spec = build_tree_list (NULLT, ridpointers[(int) RID_STATIC]);
3876 decl_specs = tree_cons (NULLT, objc_class_template, sc_spec);
3878 decl = start_decl (DECL_NAME (UOBJC_METACLASS_decl), decl_specs, 1);
3879 end_temporary_allocation ();
3882 = build_shared_structure_initializer
3883 (root_expr, super_expr, name_expr,
3884 build_int_2 ((TREE_INT_CST_LOW (TYPE_SIZE (objc_class_template))
3888 UOBJC_CLASS_METHODS_decl,
3889 UOBJC_CLASS_VARIABLES_decl,
3892 finish_decl (decl, initlist, NULLT);
3894 /* static struct objc_class _OBJC_CLASS_Foo={ ... }; */
3896 decl = start_decl (DECL_NAME (UOBJC_CLASS_decl), decl_specs, 1);
3897 end_temporary_allocation ();
3900 = build_shared_structure_initializer
3901 (build_unary_op (ADDR_EXPR, UOBJC_METACLASS_decl, 0),
3902 super_expr, name_expr,
3903 build_int_2 ((TREE_INT_CST_LOW (TYPE_SIZE (CLASS_STATIC_TEMPLATE (implementation_template)))
3907 UOBJC_INSTANCE_METHODS_decl,
3908 UOBJC_INSTANCE_VARIABLES_decl,
3911 finish_decl (decl, initlist, NULLT);
3915 synth_id_with_class_suffix (preamble, ctxt)
3920 if (TREE_CODE (ctxt) == CLASS_IMPLEMENTATION_TYPE
3921 || TREE_CODE (ctxt) == CLASS_INTERFACE_TYPE)
3924 = IDENTIFIER_POINTER (CLASS_NAME (implementation_context));
3925 string = (char *) alloca (strlen (preamble) + strlen (class_name) + 3);
3926 sprintf (string, "%s_%s", preamble,
3927 IDENTIFIER_POINTER (CLASS_NAME (ctxt)));
3929 else if (TREE_CODE (ctxt) == CATEGORY_IMPLEMENTATION_TYPE
3930 || TREE_CODE (ctxt) == CATEGORY_INTERFACE_TYPE)
3932 /* we have a category */
3934 = IDENTIFIER_POINTER (CLASS_NAME (implementation_context));
3935 char *class_super_name
3936 = IDENTIFIER_POINTER (CLASS_SUPER_NAME (implementation_context));
3937 string = (char *) alloca (strlen (preamble)
3938 + strlen (class_name)
3939 + strlen (class_super_name)
3941 sprintf (string, "%s_%s_%s", preamble, class_name, class_super_name);
3943 else if (TREE_CODE (ctxt) == PROTOCOL_INTERFACE_TYPE)
3945 char *protocol_name = IDENTIFIER_POINTER (PROTOCOL_NAME (ctxt));
3946 string = (char *) alloca (strlen (preamble) + strlen (protocol_name) + 3);
3947 sprintf (string, "%s_%s", preamble, protocol_name);
3949 return get_identifier (string);
3953 is_objc_type_qualifier (node)
3956 return (TREE_CODE (node) == IDENTIFIER_NODE
3957 && (node == ridpointers [(int) RID_CONST]
3958 || node == ridpointers [(int) RID_VOLATILE]
3959 || node == ridpointers [(int) RID_IN]
3960 || node == ridpointers [(int) RID_OUT]
3961 || node == ridpointers [(int) RID_INOUT]
3962 || node == ridpointers [(int) RID_BYCOPY]
3963 || node == ridpointers [(int) RID_ONEWAY]));
3966 /* If type is empty or only type qualifiers are present, add default
3967 type of id (otherwise grokdeclarator will default to int). */
3970 adjust_type_for_id_default (type)
3973 tree declspecs, chain;
3976 return build_tree_list (build_tree_list (NULLT, objc_object_reference),
3977 build1 (INDIRECT_REF, NULLT, NULLT));
3979 declspecs = TREE_PURPOSE (type);
3981 /* Determine if a typespec is present. */
3982 for (chain = declspecs;
3984 chain = TREE_CHAIN (chain))
3986 if (!is_objc_type_qualifier (TREE_VALUE (chain)))
3990 return build_tree_list (tree_cons (NULLT, objc_object_reference, declspecs),
3991 build1 (INDIRECT_REF, NULLT, NULLT));
3996 selector ':' '(' typename ')' identifier
3999 transform an Objective-C keyword argument into
4000 the C equivalent parameter declarator.
4002 in: key_name, an "identifier_node" (optional).
4003 arg_type, a "tree_list" (optional).
4004 arg_name, an "identifier_node".
4006 note: it would be really nice to strongly type the preceding
4007 arguments in the function prototype; however, then i
4008 could not use the "accessor" macros defined in "tree.h".
4010 out: an instance of "keyword_decl". */
4013 build_keyword_decl (key_name, arg_type, arg_name)
4020 /* if no type is specified, default to "id" */
4021 arg_type = adjust_type_for_id_default (arg_type);
4023 keyword_decl = make_node (KEYWORD_DECL);
4025 TREE_TYPE (keyword_decl) = arg_type;
4026 KEYWORD_ARG_NAME (keyword_decl) = arg_name;
4027 KEYWORD_KEY_NAME (keyword_decl) = key_name;
4029 return keyword_decl;
4032 /* Given a chain of keyword_decl's, synthesize the full keyword selector. */
4034 build_keyword_selector (selector)
4038 tree key_chain, key_name;
4041 for (key_chain = selector; key_chain; key_chain = TREE_CHAIN (key_chain))
4043 if (TREE_CODE (selector) == KEYWORD_DECL)
4044 key_name = KEYWORD_KEY_NAME (key_chain);
4045 else if (TREE_CODE (selector) == TREE_LIST)
4046 key_name = TREE_PURPOSE (key_chain);
4049 len += IDENTIFIER_LENGTH (key_name) + 1;
4050 else /* just a ':' arg */
4053 buf = (char *)alloca (len + 1);
4054 bzero (buf, len + 1);
4056 for (key_chain = selector; key_chain; key_chain = TREE_CHAIN (key_chain))
4058 if (TREE_CODE (selector) == KEYWORD_DECL)
4059 key_name = KEYWORD_KEY_NAME (key_chain);
4060 else if (TREE_CODE (selector) == TREE_LIST)
4061 key_name = TREE_PURPOSE (key_chain);
4064 strcat (buf, IDENTIFIER_POINTER (key_name));
4067 return get_identifier (buf);
4070 /* used for declarations and definitions */
4073 build_method_decl (code, ret_type, selector, add_args)
4074 enum tree_code code;
4081 /* if no type is specified, default to "id" */
4082 ret_type = adjust_type_for_id_default (ret_type);
4084 method_decl = make_node (code);
4085 TREE_TYPE (method_decl) = ret_type;
4087 /* If we have a keyword selector, create an identifier_node that
4088 represents the full selector name (`:' included)... */
4089 if (TREE_CODE (selector) == KEYWORD_DECL)
4091 METHOD_SEL_NAME (method_decl) = build_keyword_selector (selector);
4092 METHOD_SEL_ARGS (method_decl) = selector;
4093 METHOD_ADD_ARGS (method_decl) = add_args;
4097 METHOD_SEL_NAME (method_decl) = selector;
4098 METHOD_SEL_ARGS (method_decl) = NULLT;
4099 METHOD_ADD_ARGS (method_decl) = NULLT;
4105 #define METHOD_DEF 0
4106 #define METHOD_REF 1
4108 /* Used by `build_message_expr' and `comp_method_types'. Return an
4109 argument list for method METH. CONTEXT is either METHOD_DEF or
4110 METHOD_REF, saying whether we are trying to define a method or call
4111 one. SUPERFLAG says this is for a send to super; this makes a
4112 difference for the NeXT calling sequence in which the lookup and
4113 the method call are done together. */
4116 get_arg_type_list (meth, context, superflag)
4124 if (flag_next_runtime && superflag)
4125 arglist = build_tree_list (NULLT, super_type);
4126 else if (context == METHOD_DEF)
4127 arglist = build_tree_list (NULLT, TREE_TYPE (self_decl));
4129 arglist = build_tree_list (NULLT, id_type);
4131 /* selector type - will eventually change to `int' */
4132 chainon (arglist, build_tree_list (NULLT, selector_type));
4134 /* build a list of argument types */
4135 for (akey = METHOD_SEL_ARGS (meth); akey; akey = TREE_CHAIN (akey))
4137 tree arg_decl = groktypename_in_parm_context (TREE_TYPE (akey));
4138 chainon (arglist, build_tree_list (NULLT, TREE_TYPE (arg_decl)));
4141 if (METHOD_ADD_ARGS (meth) == (tree)1)
4142 /* We have a `, ...' immediately following the selector,
4143 finalize the arglist...simulate get_parm_info (0). */
4145 else if (METHOD_ADD_ARGS (meth))
4147 /* we have a variable length selector */
4148 tree add_arg_list = TREE_CHAIN (METHOD_ADD_ARGS (meth));
4149 chainon (arglist, add_arg_list);
4152 /* finalize the arglist...simulate get_parm_info (1) */
4153 chainon (arglist, build_tree_list (NULLT, void_type_node));
4159 check_duplicates (hsh)
4170 /* we have two methods with the same name and different types */
4172 char type = (TREE_CODE (meth) == INSTANCE_METHOD_DECL) ? '-' : '+';
4174 warning ("multiple declarations for method `%s'",
4175 IDENTIFIER_POINTER (METHOD_SEL_NAME (meth)));
4177 warn_with_method ("using", type, meth);
4178 for (loop = hsh->list; loop; loop = loop->next)
4179 warn_with_method ("also found", type, loop->value);
4185 /* If RECEIVER is a class reference, return the identifier node for the
4186 referenced class. RECEIVER is created by get_class_reference, so we
4187 check the exact form created depending on which runtimes are used. */
4190 receiver_is_class_object (receiver)
4193 tree chain, exp, arg;
4194 if (flag_next_runtime)
4196 /* The receiver is a variable created by build_class_reference_decl. */
4197 if (TREE_CODE (receiver) == VAR_DECL
4198 && TREE_TYPE (receiver) == objc_class_type)
4199 /* Look up the identifier. */
4200 for (chain = cls_ref_chain; chain; chain = TREE_CHAIN (chain))
4201 if (TREE_PURPOSE (chain) == receiver)
4202 return TREE_VALUE (chain);
4206 /* The receiver is a function call that returns an id. Check if
4207 it is a call to objc_getClass, if so, pick up the class name. */
4208 if ((exp = TREE_OPERAND (receiver, 0))
4209 && TREE_CODE (exp) == ADDR_EXPR
4210 && (exp = TREE_OPERAND (exp, 0))
4211 && TREE_CODE (exp) == FUNCTION_DECL
4212 && exp == objc_get_class_decl
4213 /* we have a call to objc_getClass! */
4214 && (arg = TREE_OPERAND (receiver, 1))
4215 && TREE_CODE (arg) == TREE_LIST
4216 && (arg = TREE_VALUE (arg)))
4219 if (TREE_CODE (arg) == ADDR_EXPR
4220 && (arg = TREE_OPERAND (arg, 0))
4221 && TREE_CODE (arg) == STRING_CST)
4222 /* finally, we have the class name */
4223 return get_identifier (TREE_STRING_POINTER (arg));
4229 /* If we are currently building a message expr, this holds
4230 the identifier of the selector of the message. This is
4231 used when printing warnings about argument mismatches. */
4233 static tree building_objc_message_expr = 0;
4236 maybe_building_objc_message_expr ()
4238 return building_objc_message_expr;
4241 /* Construct an expression for sending a message.
4242 MESS has the object to send to in TREE_PURPOSE
4243 and the argument list (including selector) in TREE_VALUE.
4245 (*(<abstract_decl>(*)())_msg)(receiver, selTransTbl[n], ...);
4246 (*(<abstract_decl>(*)())_msgSuper)(receiver, selTransTbl[n], ...); */
4249 build_message_expr (mess)
4252 tree receiver = TREE_PURPOSE (mess);
4253 tree selector, self_object;
4254 tree rtype, sel_name;
4255 tree args = TREE_VALUE (mess);
4256 tree method_params = NULLT;
4257 tree method_prototype = NULLT;
4259 int statically_typed = 0, statically_allocated = 0;
4260 tree class_ident = 0;
4262 /* 1 if this is sending to the superclass. */
4265 if (!doing_objc_thang)
4268 if (TREE_CODE (receiver) == ERROR_MARK)
4269 return error_mark_node;
4271 /* determine receiver type */
4272 rtype = TREE_TYPE (receiver);
4273 super = IS_SUPER (rtype);
4277 if (TREE_STATIC_TEMPLATE (rtype))
4278 statically_allocated = 1;
4279 else if (TREE_CODE (rtype) == POINTER_TYPE
4280 && TREE_STATIC_TEMPLATE (TREE_TYPE (rtype)))
4281 statically_typed = 1;
4282 else if ((flag_next_runtime
4283 || (TREE_CODE (receiver) == CALL_EXPR && IS_ID (rtype)))
4284 && (class_ident = receiver_is_class_object (receiver)))
4286 else if (! IS_ID (rtype)
4287 /* Allow any type that matches objc_class_type. */
4288 && ! comptypes (rtype, objc_class_type))
4290 bzero (errbuf, BUFSIZE);
4291 warning ("invalid receiver type `%s'",
4292 gen_declaration (rtype, errbuf));
4294 if (statically_allocated)
4295 receiver = build_unary_op (ADDR_EXPR, receiver, 0);
4297 /* Don't evaluate the receiver twice. */
4298 receiver = save_expr (receiver);
4299 self_object = receiver;
4302 /* If sending to `super', use current self as the object. */
4303 self_object = self_decl;
4305 /* Obtain the full selector name. */
4307 if (TREE_CODE (args) == IDENTIFIER_NODE)
4308 /* a unary selector */
4310 else if (TREE_CODE (args) == TREE_LIST)
4311 sel_name = build_keyword_selector (args);
4313 /* Build the parameters list for looking up the method.
4314 These are the object itself and the selector. */
4316 selector = build_selector_reference (sel_name);
4318 /* Build the parameter list to give to the method. */
4320 method_params = NULLT;
4321 if (TREE_CODE (args) == TREE_LIST)
4323 tree chain = args, prev = NULLT;
4325 /* We have a keyword selector--check for comma expressions. */
4328 tree element = TREE_VALUE (chain);
4330 /* We have a comma expression, must collapse... */
4331 if (TREE_CODE (element) == TREE_LIST)
4334 TREE_CHAIN (prev) = element;
4339 chain = TREE_CHAIN (chain);
4341 method_params = args;
4344 /* Determine operation return type. */
4346 if (IS_SUPER (rtype))
4350 if (CLASS_SUPER_NAME (implementation_template))
4352 iface = lookup_interface (CLASS_SUPER_NAME (implementation_template));
4354 if (TREE_CODE (method_context) == INSTANCE_METHOD_DECL)
4355 method_prototype = lookup_instance_method_static (iface, sel_name);
4357 method_prototype = lookup_class_method_static (iface, sel_name);
4359 if (iface && !method_prototype)
4360 warning ("`%s' does not respond to `%s'",
4361 IDENTIFIER_POINTER (CLASS_SUPER_NAME (implementation_template)),
4362 IDENTIFIER_POINTER (sel_name));
4366 error ("no super class declared in interface for `%s'",
4367 IDENTIFIER_POINTER (CLASS_NAME (implementation_template)));
4368 return error_mark_node;
4372 else if (statically_allocated)
4374 tree ctype = TREE_TYPE (rtype);
4375 tree iface = lookup_interface (TYPE_NAME (rtype));
4378 method_prototype = lookup_instance_method_static (iface, sel_name);
4381 if (! method_prototype && TYPE_PROTOCOL_LIST (ctype))
4383 = lookup_method_in_protocol_list (TYPE_PROTOCOL_LIST (ctype),
4386 if (!method_prototype)
4387 warning ("`%s' does not respond to `%s'",
4388 IDENTIFIER_POINTER (TYPE_NAME (rtype)),
4389 IDENTIFIER_POINTER (sel_name));
4391 else if (statically_typed)
4393 tree ctype = TREE_TYPE (rtype);
4395 /* `self' is now statically_typed...all methods should be visible
4396 within the context of the implementation... */
4397 if (implementation_context
4398 && CLASS_NAME (implementation_context) == TYPE_NAME (ctype))
4400 method_prototype = lookup_instance_method_static (implementation_template, sel_name);
4403 if (! method_prototype && TYPE_PROTOCOL_LIST (ctype))
4405 = lookup_method_in_protocol_list (TYPE_PROTOCOL_LIST (ctype),
4408 if (! method_prototype
4409 && implementation_template != implementation_context)
4410 /* the method is not published in the interface...check locally */
4412 = lookup_method (CLASS_NST_METHODS (implementation_context),
4419 if ((iface = lookup_interface (TYPE_NAME (ctype))))
4420 method_prototype = lookup_instance_method_static (iface, sel_name);
4422 if (! method_prototype)
4424 tree protocol_list = TYPE_PROTOCOL_LIST (ctype);
4427 = lookup_method_in_protocol_list (protocol_list, sel_name, 0);
4431 if (!method_prototype)
4432 warning ("`%s' does not respond to `%s'",
4433 IDENTIFIER_POINTER (TYPE_NAME (ctype)),
4434 IDENTIFIER_POINTER (sel_name));
4436 else if (class_ident)
4438 if (implementation_context
4439 && CLASS_NAME (implementation_context) == class_ident)
4442 = lookup_class_method_static (implementation_template, sel_name);
4444 if (!method_prototype
4445 && implementation_template != implementation_context)
4446 /* the method is not published in the interface...check locally */
4448 = lookup_method (CLASS_CLS_METHODS (implementation_context),
4455 if ((iface = lookup_interface (class_ident)))
4456 method_prototype = lookup_class_method_static (iface, sel_name);
4459 if (!method_prototype)
4461 warning ("cannot find class (factory) method.");
4462 warning ("return type for `%s' defaults to id",
4463 IDENTIFIER_POINTER (sel_name));
4466 else if (IS_PROTOCOL_QUALIFIED_ID (rtype))
4468 /* An anonymous object that has been qualified with a protocol. */
4470 tree protocol_list = TYPE_PROTOCOL_LIST (rtype);
4472 method_prototype = lookup_method_in_protocol_list (protocol_list,
4475 if (!method_prototype)
4479 warning ("method `%s' not implemented by protocol.",
4480 IDENTIFIER_POINTER (sel_name));
4482 /* try and find the method signiture in the global pools! */
4484 if (!(hsh = hash_lookup (nst_method_hash_list, sel_name)))
4485 hsh = hash_lookup (cls_method_hash_list, sel_name);
4487 if (!(method_prototype = check_duplicates (hsh)))
4488 warning ("return type defaults to id");
4495 /* we think we have an instance...loophole: extern id Object; */
4496 hsh = hash_lookup (nst_method_hash_list, sel_name);
4498 /* for various loopholes...like sending messages to self in a
4499 factory context... */
4500 hsh = hash_lookup (cls_method_hash_list, sel_name);
4502 method_prototype = check_duplicates (hsh);
4503 if (!method_prototype)
4505 warning ("cannot find method.");
4506 warning ("return type for `%s' defaults to id",
4507 IDENTIFIER_POINTER (sel_name));
4511 /* Save the selector name for printing error messages. */
4512 building_objc_message_expr = sel_name;
4514 retval = build_objc_method_call (super, method_prototype,
4515 receiver, self_object,
4516 selector, method_params);
4518 building_objc_message_expr = 0;
4523 /* Build a tree expression to send OBJECT the operation SELECTOR,
4524 looking up the method on object LOOKUP_OBJECT (often same as OBJECT),
4525 assuming the method has prototype METHOD_PROTOTYPE.
4526 (That is an INSTANCE_METHOD_DECL or CLASS_METHOD_DECL.)
4527 Use METHOD_PARAMS as list of args to pass to the method.
4528 If SUPER_FLAG is nonzero, we look up the superclass's method. */
4531 build_objc_method_call (super_flag, method_prototype, lookup_object, object,
4532 selector, method_params)
4534 tree method_prototype, lookup_object, object, selector, method_params;
4536 tree sender = (super_flag ? umsg_super_decl : umsg_decl);
4537 tree rcv_p = (super_flag
4538 ? build_pointer_type (xref_tag (RECORD_TYPE,
4539 get_identifier (TAG_SUPER)))
4542 if (flag_next_runtime)
4544 if (! method_prototype)
4546 method_params = tree_cons (NULLT, lookup_object,
4547 tree_cons (NULLT, selector,
4549 assemble_external (sender);
4550 return build_function_call (sender, method_params);
4554 /* This is a real kludge, but it is used only for the Next.
4555 Clobber the data type of SENDER temporarily to accept
4556 all the arguments for this operation, and to return
4557 whatever this operation returns. */
4558 tree arglist = NULLT;
4561 /* Save the proper contents of SENDER's data type. */
4562 tree savarg = TYPE_ARG_TYPES (TREE_TYPE (sender));
4563 tree savret = TREE_TYPE (TREE_TYPE (sender));
4565 /* Install this method's argument types. */
4566 arglist = get_arg_type_list (method_prototype, METHOD_REF,
4568 TYPE_ARG_TYPES (TREE_TYPE (sender)) = arglist;
4570 /* Install this method's return type. */
4571 TREE_TYPE (TREE_TYPE (sender))
4572 = groktypename (TREE_TYPE (method_prototype));
4574 /* Call SENDER with all the parameters. This will do type
4575 checking using the arg types for this method. */
4576 method_params = tree_cons (NULLT, lookup_object,
4577 tree_cons (NULLT, selector,
4579 assemble_external (sender);
4580 retval = build_function_call (sender, method_params);
4582 /* Restore SENDER's return/argument types. */
4583 TYPE_ARG_TYPES (TREE_TYPE (sender)) = savarg;
4584 TREE_TYPE (TREE_TYPE (sender)) = savret;
4590 /* This is the portable way.
4591 First call the lookup function to get a pointer to the method,
4592 then cast the pointer, then call it with the method arguments. */
4595 /* Avoid trouble since we may evaluate each of these twice. */
4596 object = save_expr (object);
4597 selector = save_expr (selector);
4599 lookup_object = build_c_cast (rcv_p, lookup_object); /* cast! */
4601 assemble_external (sender);
4603 = build_function_call (sender,
4604 tree_cons (NULLT, lookup_object,
4605 tree_cons (NULLT, selector, NULLT)));
4607 /* If we have a method prototype, construct the data type this
4608 method needs, and cast what we got from SENDER into a pointer
4610 if (method_prototype)
4612 tree arglist = get_arg_type_list (method_prototype, METHOD_REF,
4614 tree valtype = groktypename (TREE_TYPE (method_prototype));
4615 tree fake_function_type = build_function_type (valtype, arglist);
4616 TREE_TYPE (method) = build_pointer_type (fake_function_type);
4620 = build_pointer_type (build_function_type (ptr_type_node, NULLT));
4622 /* Pass the object to the method. */
4623 assemble_external (method);
4624 return build_function_call (method,
4625 tree_cons (NULLT, object,
4626 tree_cons (NULLT, selector,
4632 build_protocol_reference (p)
4635 tree decl, ident, ptype;
4636 struct obstack *save_current_obstack = current_obstack;
4637 struct obstack *save_rtl_obstack = rtl_obstack;
4639 rtl_obstack = current_obstack = &permanent_obstack;
4641 /* extern struct objc_protocol _OBJC_PROTOCOL_<mumble>; */
4643 ident = synth_id_with_class_suffix ("_OBJC_PROTOCOL", p);
4645 = groktypename (build_tree_list (build_tree_list (NULLT,
4646 objc_protocol_template),
4649 if (IDENTIFIER_GLOBAL_VALUE (ident))
4650 decl = IDENTIFIER_GLOBAL_VALUE (ident); /* Set by pushdecl. */
4653 decl = build_decl (VAR_DECL, ident, ptype);
4654 DECL_EXTERNAL (decl) = 1;
4655 TREE_PUBLIC (decl) = 1;
4656 TREE_USED (decl) = 1;
4658 /* usually called from `rest_of_decl_compilation' */
4659 make_decl_rtl (decl, 0, 1);
4660 /* our `extended/custom' pushdecl in c-decl.c */
4661 pushdecl_top_level (decl);
4663 current_obstack = save_current_obstack;
4664 rtl_obstack = save_rtl_obstack;
4666 PROTOCOL_FORWARD_DECL (p) = decl;
4670 build_protocol_expr (protoname)
4676 if (!doing_objc_thang)
4679 p = lookup_protocol (protoname);
4683 error ("Cannot find protocol declaration for `%s'",
4684 IDENTIFIER_POINTER (protoname));
4685 return error_mark_node;
4688 if (!PROTOCOL_FORWARD_DECL (p))
4689 build_protocol_reference (p);
4691 expr = build_unary_op (ADDR_EXPR, PROTOCOL_FORWARD_DECL (p), 0);
4693 TREE_TYPE (expr) = protocol_type;
4699 build_selector_expr (selnamelist)
4704 if (!doing_objc_thang)
4707 /* obtain the full selector name */
4708 if (TREE_CODE (selnamelist) == IDENTIFIER_NODE)
4709 /* a unary selector */
4710 selname = selnamelist;
4711 else if (TREE_CODE (selnamelist) == TREE_LIST)
4712 selname = build_keyword_selector (selnamelist);
4714 return build_selector_reference (selname);
4718 build_encode_expr (type)
4724 if (!doing_objc_thang)
4727 encode_type (type, obstack_object_size (&util_obstack),
4728 OBJC_ENCODE_INLINE_DEFS);
4729 obstack_1grow (&util_obstack, 0); /* null terminate string */
4730 string = obstack_finish (&util_obstack);
4732 /* synthesize a string that represents the encoded struct/union */
4733 result = my_build_string (strlen (string) + 1, string);
4734 obstack_free (&util_obstack, util_firstobj);
4739 build_ivar_reference (id)
4742 if (TREE_CODE (method_context) == CLASS_METHOD_DECL)
4744 /* Historically, a class method that produced objects (factory
4745 method) would assign `self' to the instance that it
4746 allocated. This would effectively turn the class method into
4747 an instance method. Following this assignment, the instance
4748 variables could be accessed. That practice, while safe,
4749 violates the simple rule that a class method should not refer
4750 to an instance variable. It's better to catch the cases
4751 where this is done unknowingly than to support the above
4753 warning ("instance variable `%s' accessed in class method",
4754 IDENTIFIER_POINTER (id));
4755 TREE_TYPE (self_decl) = instance_type; /* cast */
4758 return build_component_ref (build_indirect_ref (self_decl, "->"), id);
4761 #define HASH_ALLOC_LIST_SIZE 170
4762 #define ATTR_ALLOC_LIST_SIZE 170
4763 #define SIZEHASHTABLE 257
4766 #define HASHFUNCTION(key) ((HOST_WIDE_INT) key & 0x7fffffff)
4771 nst_method_hash_list = (hash *)xmalloc (SIZEHASHTABLE * sizeof (hash));
4772 cls_method_hash_list = (hash *)xmalloc (SIZEHASHTABLE * sizeof (hash));
4774 if (!nst_method_hash_list || !cls_method_hash_list)
4775 perror ("unable to allocate space in objc-tree.c");
4780 for (i = 0; i < SIZEHASHTABLE; i++)
4782 nst_method_hash_list[i] = 0;
4783 cls_method_hash_list[i] = 0;
4789 hash_enter (hashlist, method)
4793 static hash hash_alloc_list = 0;
4794 static int hash_alloc_index = 0;
4796 int slot = HASHFUNCTION (METHOD_SEL_NAME (method)) % SIZEHASHTABLE;
4798 if (! hash_alloc_list || hash_alloc_index >= HASH_ALLOC_LIST_SIZE)
4800 hash_alloc_index = 0;
4801 hash_alloc_list = (hash) xmalloc (sizeof (struct hashed_entry)
4802 * HASH_ALLOC_LIST_SIZE);
4803 if (! hash_alloc_list)
4804 perror ("unable to allocate in objc-tree.c");
4806 obj = &hash_alloc_list[hash_alloc_index++];
4808 obj->next = hashlist[slot];
4811 hashlist[slot] = obj; /* append to front */
4815 hash_lookup (hashlist, sel_name)
4821 target = hashlist[HASHFUNCTION (sel_name) % SIZEHASHTABLE];
4825 if (sel_name == METHOD_SEL_NAME (target->key))
4828 target = target->next;
4834 hash_add_attr (entry, value)
4838 static attr attr_alloc_list = 0;
4839 static int attr_alloc_index = 0;
4842 if (! attr_alloc_list || attr_alloc_index >= ATTR_ALLOC_LIST_SIZE)
4844 attr_alloc_index = 0;
4845 attr_alloc_list = (attr) xmalloc (sizeof (struct hashed_attribute)
4846 * ATTR_ALLOC_LIST_SIZE);
4847 if (! attr_alloc_list)
4848 perror ("unable to allocate in objc-tree.c");
4850 obj = &attr_alloc_list[attr_alloc_index++];
4851 obj->next = entry->list;
4854 entry->list = obj; /* append to front */
4858 lookup_method (mchain, method)
4864 if (TREE_CODE (method) == IDENTIFIER_NODE)
4867 key = METHOD_SEL_NAME (method);
4871 if (METHOD_SEL_NAME (mchain) == key)
4873 mchain = TREE_CHAIN (mchain);
4879 lookup_instance_method_static (interface, ident)
4883 tree inter = interface;
4884 tree chain = CLASS_NST_METHODS (inter);
4889 if ((meth = lookup_method (chain, ident)))
4892 if (CLASS_CATEGORY_LIST (inter))
4894 tree category = CLASS_CATEGORY_LIST (inter);
4895 chain = CLASS_NST_METHODS (category);
4899 if ((meth = lookup_method (chain, ident)))
4903 /* Check for instance methods in protocols in categories. */
4904 if (CLASS_PROTOCOL_LIST (category))
4906 if ((meth = (lookup_method_in_protocol_list
4907 (CLASS_PROTOCOL_LIST (category), ident, 0))))
4911 if ((category = CLASS_CATEGORY_LIST (category)))
4912 chain = CLASS_NST_METHODS (category);
4917 if (CLASS_PROTOCOL_LIST (inter))
4919 if ((meth = (lookup_method_in_protocol_list
4920 (CLASS_PROTOCOL_LIST (inter), ident, 0))))
4924 if ((inter = lookup_interface (CLASS_SUPER_NAME (inter))))
4925 chain = CLASS_NST_METHODS (inter);
4933 lookup_class_method_static (interface, ident)
4937 tree inter = interface;
4938 tree chain = CLASS_CLS_METHODS (inter);
4940 tree root_inter = NULLT;
4944 if ((meth = lookup_method (chain, ident)))
4947 if (CLASS_CATEGORY_LIST (inter))
4949 tree category = CLASS_CATEGORY_LIST (inter);
4950 chain = CLASS_CLS_METHODS (category);
4954 if ((meth = lookup_method (chain, ident)))
4958 /* Check for class methods in protocols in categories. */
4959 if (CLASS_PROTOCOL_LIST (category))
4961 if ((meth = (lookup_method_in_protocol_list
4962 (CLASS_PROTOCOL_LIST (category), ident, 1))))
4966 if ((category = CLASS_CATEGORY_LIST (category)))
4967 chain = CLASS_CLS_METHODS (category);
4973 /* Check for class methods in protocols. */
4974 if (CLASS_PROTOCOL_LIST (inter))
4976 if ((meth = (lookup_method_in_protocol_list
4977 (CLASS_PROTOCOL_LIST (inter), ident, 1))))
4982 if ((inter = lookup_interface (CLASS_SUPER_NAME (inter))))
4983 chain = CLASS_CLS_METHODS (inter);
4988 /* Simulate wrap around. */
4989 return lookup_instance_method_static (root_inter, ident);
4993 add_class_method (class, method)
5000 /* We will have allocated the method parameter declarations on the
5001 maybepermanent_obstack. Need to make sure they stick around! */
5004 if (!(mth = lookup_method (CLASS_CLS_METHODS (class), method)))
5006 /* put method on list in reverse order */
5007 TREE_CHAIN (method) = CLASS_CLS_METHODS (class);
5008 CLASS_CLS_METHODS (class) = method;
5012 if (TREE_CODE (class) == CLASS_IMPLEMENTATION_TYPE)
5013 error ("duplicate definition of class method `%s'.",
5014 IDENTIFIER_POINTER (METHOD_SEL_NAME (mth)));
5017 /* check types, if different complain */
5018 if (!comp_proto_with_proto (method, mth))
5019 error ("duplicate declaration of class method `%s'.",
5020 IDENTIFIER_POINTER (METHOD_SEL_NAME (mth)));
5024 if (!(hsh = hash_lookup (cls_method_hash_list, METHOD_SEL_NAME (method))))
5026 /* install on a global chain */
5027 hash_enter (cls_method_hash_list, method);
5031 /* check types, if different add to a list */
5032 if (!comp_proto_with_proto (method, hsh->key))
5033 hash_add_attr (hsh, method);
5039 add_instance_method (class, method)
5046 /* We will have allocated the method parameter declarations on the
5047 maybepermanent_obstack. Need to make sure they stick around! */
5050 if (!(mth = lookup_method (CLASS_NST_METHODS (class), method)))
5052 /* put method on list in reverse order */
5053 TREE_CHAIN (method) = CLASS_NST_METHODS (class);
5054 CLASS_NST_METHODS (class) = method;
5058 if (TREE_CODE (class) == CLASS_IMPLEMENTATION_TYPE)
5059 error ("duplicate definition of instance method `%s'.",
5060 IDENTIFIER_POINTER (METHOD_SEL_NAME (mth)));
5063 /* check types, if different complain */
5064 if (!comp_proto_with_proto (method, mth))
5065 error ("duplicate declaration of instance method `%s'.",
5066 IDENTIFIER_POINTER (METHOD_SEL_NAME (mth)));
5070 if (!(hsh = hash_lookup (nst_method_hash_list, METHOD_SEL_NAME (method))))
5072 /* install on a global chain */
5073 hash_enter (nst_method_hash_list, method);
5077 /* check types, if different add to a list */
5078 if (!comp_proto_with_proto (method, hsh->key))
5079 hash_add_attr (hsh, method);
5088 /* put interfaces on list in reverse order */
5089 TREE_CHAIN (class) = interface_chain;
5090 interface_chain = class;
5091 return interface_chain;
5095 add_category (class, category)
5099 /* put categories on list in reverse order */
5101 tree cat = CLASS_CATEGORY_LIST (class);
5104 if (CLASS_SUPER_NAME (cat) == CLASS_SUPER_NAME (category))
5105 warning ("duplicate interface declaration for category `%s(%s)'",
5106 IDENTIFIER_POINTER (CLASS_NAME (class)),
5107 IDENTIFIER_POINTER (CLASS_SUPER_NAME (category)));
5108 cat = CLASS_CATEGORY_LIST (cat);
5111 CLASS_CATEGORY_LIST (category) = CLASS_CATEGORY_LIST (class);
5112 CLASS_CATEGORY_LIST (class) = category;
5115 /* Called after parsing each instance variable declaration. Necessary to
5116 preserve typedefs and implement public/private...
5118 PUBLIC is 1 for public, 0 for protected, and 2 for private. */
5121 add_instance_variable (class, public, declarator, declspecs, width)
5128 tree field_decl, raw_decl;
5130 raw_decl = build_tree_list (declspecs /*purpose*/, declarator/*value*/);
5132 if (CLASS_RAW_IVARS (class))
5133 chainon (CLASS_RAW_IVARS (class), raw_decl);
5135 CLASS_RAW_IVARS (class) = raw_decl;
5137 field_decl = grokfield (input_filename, lineno,
5138 declarator, declspecs, width);
5140 /* overload the public attribute, it is not used for FIELD_DECL's */
5144 TREE_PUBLIC (field_decl) = 0;
5145 TREE_PRIVATE (field_decl) = 0;
5146 TREE_PROTECTED (field_decl) = 1;
5150 TREE_PUBLIC (field_decl) = 1;
5151 TREE_PRIVATE (field_decl) = 0;
5152 TREE_PROTECTED (field_decl) = 0;
5156 TREE_PUBLIC (field_decl) = 0;
5157 TREE_PRIVATE (field_decl) = 1;
5158 TREE_PROTECTED (field_decl) = 0;
5163 if (CLASS_IVARS (class))
5164 chainon (CLASS_IVARS (class), field_decl);
5166 CLASS_IVARS (class) = field_decl;
5172 is_ivar (decl_chain, ident)
5176 for ( ; decl_chain; decl_chain = TREE_CHAIN (decl_chain))
5177 if (DECL_NAME (decl_chain) == ident)
5182 /* True if the ivar is private and we are not in its implementation. */
5188 if (TREE_PRIVATE (decl)
5189 && ! is_ivar (CLASS_IVARS (implementation_template), DECL_NAME (decl)))
5191 error ("instance variable `%s' is declared private",
5192 IDENTIFIER_POINTER (DECL_NAME (decl)));
5199 /* we have an instance variable reference, check to see if it is public...*/
5202 is_public (expr, identifier)
5206 tree basetype = TREE_TYPE (expr);
5207 enum tree_code code = TREE_CODE (basetype);
5210 if (code == RECORD_TYPE)
5212 if (TREE_STATIC_TEMPLATE (basetype))
5214 if (!lookup_interface (TYPE_NAME (basetype)))
5216 error ("Cannot find interface declaration for `%s'",
5217 IDENTIFIER_POINTER (TYPE_NAME (basetype)));
5221 if ((decl = is_ivar (TYPE_FIELDS (basetype), identifier)))
5223 if (TREE_PUBLIC (decl))
5226 /* important difference between the Stepstone translator:
5227 all instance variables should be public within the context
5228 of the implementation. */
5229 if (implementation_context
5230 && (((TREE_CODE (implementation_context)
5231 == CLASS_IMPLEMENTATION_TYPE)
5232 || (TREE_CODE (implementation_context)
5233 == CATEGORY_IMPLEMENTATION_TYPE))
5234 && (CLASS_NAME (implementation_context)
5235 == TYPE_NAME (basetype))))
5236 return ! is_private (decl);
5238 error ("instance variable `%s' is declared %s",
5239 IDENTIFIER_POINTER (identifier),
5240 TREE_PRIVATE (decl) ? "private" : "protected");
5244 else if (implementation_context && (basetype == objc_object_reference))
5246 TREE_TYPE (expr) = uprivate_record;
5247 warning ("static access to object of type `id'");
5253 /* implement @defs (<classname>) within struct bodies. */
5256 get_class_ivars (interface)
5259 if (!doing_objc_thang)
5262 return build_ivar_chain (interface, 1);
5265 /* make sure all entries in "chain" are also in "list" */
5268 check_methods (chain, list, mtype)
5277 if (!lookup_method (list, chain))
5281 if (TREE_CODE (implementation_context) == CLASS_IMPLEMENTATION_TYPE)
5282 warning ("incomplete implementation of class `%s'",
5283 IDENTIFIER_POINTER (CLASS_NAME (implementation_context)));
5284 else if (TREE_CODE (implementation_context) == CATEGORY_IMPLEMENTATION_TYPE)
5285 warning ("incomplete implementation of category `%s'",
5286 IDENTIFIER_POINTER (CLASS_SUPER_NAME (implementation_context)));
5289 warning ("method definition for `%c%s' not found",
5290 mtype, IDENTIFIER_POINTER (METHOD_SEL_NAME (chain)));
5292 chain = TREE_CHAIN (chain);
5298 conforms_to_protocol (class, protocol)
5304 tree p = CLASS_PROTOCOL_LIST (class);
5305 while (p && TREE_VALUE (p) != TREE_VALUE (protocol))
5309 tree super = (CLASS_SUPER_NAME (class)
5310 ? lookup_interface (CLASS_SUPER_NAME (class))
5312 int tmp = super ? conforms_to_protocol (super, protocol) : 0;
5316 protocol = TREE_CHAIN (protocol);
5321 /* Make sure all methods in CHAIN are accessible as MTYPE methods in
5322 CONTEXT. This is one of two mechanisms to check protocol integrity
5326 check_methods_accessible (chain, context, mtype)
5328 tree context; /* implementation_context */
5339 list = CLASS_CLS_METHODS (context);
5341 list = CLASS_NST_METHODS (context);
5343 if (lookup_method (list, chain))
5346 else if (TREE_CODE (context) == CLASS_IMPLEMENTATION_TYPE
5347 || TREE_CODE (context) == CLASS_INTERFACE_TYPE)
5348 context = (CLASS_SUPER_NAME (context)
5349 ? lookup_interface (CLASS_SUPER_NAME (context))
5352 else if (TREE_CODE (context) == CATEGORY_IMPLEMENTATION_TYPE
5353 || TREE_CODE (context) == CATEGORY_INTERFACE_TYPE)
5354 context = (CLASS_NAME (context)
5355 ? lookup_interface (CLASS_NAME (context))
5361 if (context == NULL_TREE)
5365 if (TREE_CODE (implementation_context)
5366 == CLASS_IMPLEMENTATION_TYPE)
5367 warning ("incomplete implementation of class `%s'",
5369 (CLASS_NAME (implementation_context)));
5370 else if (TREE_CODE (implementation_context)
5371 == CATEGORY_IMPLEMENTATION_TYPE)
5372 warning ("incomplete implementation of category `%s'",
5374 (CLASS_SUPER_NAME (implementation_context)));
5377 warning ("method definition for `%c%s' not found",
5378 mtype, IDENTIFIER_POINTER (METHOD_SEL_NAME (chain)));
5381 chain = TREE_CHAIN (chain); /* next method... */
5387 check_protocols (proto_list, type, name)
5392 for ( ; proto_list; proto_list = TREE_CHAIN (proto_list))
5394 tree p = TREE_VALUE (proto_list);
5396 if (TREE_CODE (p) == PROTOCOL_INTERFACE_TYPE)
5400 /* Ensure that all protocols have bodies! */
5401 if (flag_warn_protocol) {
5402 f1 = check_methods (PROTOCOL_CLS_METHODS (p),
5403 CLASS_CLS_METHODS (implementation_context),
5405 f2 = check_methods (PROTOCOL_NST_METHODS (p),
5406 CLASS_NST_METHODS (implementation_context),
5409 f1 = check_methods_accessible (PROTOCOL_CLS_METHODS (p),
5410 implementation_context,
5412 f2 = check_methods_accessible (PROTOCOL_NST_METHODS (p),
5413 implementation_context,
5418 warning ("%s `%s' does not fully implement the `%s' protocol",
5419 type, name, IDENTIFIER_POINTER (PROTOCOL_NAME (p)));
5423 ; /* an identifier...if we could not find a protocol. */
5425 /* Check protocols recursively. */
5426 if (PROTOCOL_LIST (p))
5429 = lookup_interface (CLASS_SUPER_NAME (implementation_template));
5430 if (! conforms_to_protocol (super_class, PROTOCOL_LIST (p)))
5431 check_protocols (PROTOCOL_LIST (p), type, name);
5436 /* Make sure that the class CLASS_NAME is defined
5437 CODE says which kind of thing CLASS_NAME ought to be.
5438 It can be CLASS_INTERFACE_TYPE, CLASS_IMPLEMENTATION_TYPE,
5439 CATEGORY_INTERFACE_TYPE, or CATEGORY_IMPLEMENTATION_TYPE.
5441 If CODE is CLASS_INTERFACE_TYPE, we also do a push_obstacks_nochange
5442 whose matching pop is in continue_class. */
5445 start_class (code, class_name, super_name, protocol_list)
5446 enum tree_code code;
5453 if (code == CLASS_INTERFACE_TYPE)
5455 push_obstacks_nochange ();
5456 end_temporary_allocation ();
5459 if (!doing_objc_thang)
5462 class = make_node (code);
5463 TYPE_BINFO (class) = make_tree_vec (5);
5465 CLASS_NAME (class) = class_name;
5466 CLASS_SUPER_NAME (class) = super_name;
5467 CLASS_CLS_METHODS (class) = NULL_TREE;
5469 if (! is_class_name (class_name) && (decl = lookup_name (class_name)))
5471 error ("`%s' redeclared as different kind of symbol",
5472 IDENTIFIER_POINTER (class_name));
5473 error_with_decl (decl, "previous declaration of `%s'");
5476 if (code == CLASS_IMPLEMENTATION_TYPE)
5479 static tree implemented_classes = 0;
5480 tree chain = implemented_classes;
5481 for (chain = implemented_classes; chain; chain = TREE_CHAIN (chain))
5482 if (TREE_VALUE (chain) == class_name)
5484 error ("reimplementation of class `%s'",
5485 IDENTIFIER_POINTER (class_name));
5486 return error_mark_node;
5488 implemented_classes = perm_tree_cons (NULLT, class_name,
5489 implemented_classes);
5492 /* pre-build the following entities - for speed/convenience. */
5494 self_id = get_identifier ("self");
5496 ucmd_id = get_identifier ("_cmd");
5498 if (!objc_super_template)
5499 objc_super_template = build_super_template ();
5501 method_slot = 0; /* reset for multiple classes per file */
5503 implementation_context = class;
5505 /* lookup the interface for this implementation. */
5507 if (!(implementation_template = lookup_interface (class_name)))
5509 warning ("Cannot find interface declaration for `%s'",
5510 IDENTIFIER_POINTER (class_name));
5511 add_class (implementation_template = implementation_context);
5514 /* if a super class has been specified in the implementation,
5515 insure it conforms to the one specified in the interface */
5518 && (super_name != CLASS_SUPER_NAME (implementation_template)))
5520 tree previous_name = CLASS_SUPER_NAME (implementation_template);
5521 char *name = previous_name ? IDENTIFIER_POINTER (previous_name) : "";
5522 error ("conflicting super class name `%s'",
5523 IDENTIFIER_POINTER (super_name));
5524 error ("previous declaration of `%s'", name);
5526 else if (! super_name)
5528 CLASS_SUPER_NAME (implementation_context)
5529 = CLASS_SUPER_NAME (implementation_template);
5532 else if (code == CLASS_INTERFACE_TYPE)
5534 if (lookup_interface (class_name))
5535 warning ("duplicate interface declaration for class `%s'",
5536 IDENTIFIER_POINTER (class_name));
5541 CLASS_PROTOCOL_LIST (class)
5542 = lookup_and_install_protocols (protocol_list);
5544 else if (code == CATEGORY_INTERFACE_TYPE)
5546 tree class_category_is_assoc_with;
5548 /* for a category, class_name is really the name of the class that
5549 the following set of methods will be associated with...we must
5550 find the interface so that can derive the objects template */
5552 if (!(class_category_is_assoc_with = lookup_interface (class_name)))
5554 error ("Cannot find interface declaration for `%s'",
5555 IDENTIFIER_POINTER (class_name));
5559 add_category (class_category_is_assoc_with, class);
5562 CLASS_PROTOCOL_LIST (class)
5563 = lookup_and_install_protocols (protocol_list);
5565 else if (code == CATEGORY_IMPLEMENTATION_TYPE)
5567 /* pre-build the following entities - for speed/convenience. */
5569 self_id = get_identifier ("self");
5571 ucmd_id = get_identifier ("_cmd");
5573 if (!objc_super_template)
5574 objc_super_template = build_super_template ();
5576 method_slot = 0; /* reset for multiple classes per file */
5578 implementation_context = class;
5580 /* for a category, class_name is really the name of the class that
5581 the following set of methods will be associated with...we must
5582 find the interface so that can derive the objects template */
5584 if (!(implementation_template = lookup_interface (class_name)))
5586 error ("Cannot find interface declaration for `%s'",
5587 IDENTIFIER_POINTER (class_name));
5595 continue_class (class)
5598 if (TREE_CODE (class) == CLASS_IMPLEMENTATION_TYPE
5599 || TREE_CODE (class) == CATEGORY_IMPLEMENTATION_TYPE)
5601 struct imp_entry *imp_entry;
5604 /* check consistency of the instance variables. */
5606 if (CLASS_IVARS (class))
5607 check_ivars (implementation_template, class);
5609 /* code generation */
5611 ivar_context = build_private_template (implementation_template);
5613 if (!objc_class_template)
5614 build_class_template ();
5616 if (!(imp_entry = (struct imp_entry *) xmalloc (sizeof (struct imp_entry))))
5617 perror ("unable to allocate in objc-tree.c");
5619 imp_entry->next = imp_list;
5620 imp_entry->imp_context = class;
5621 imp_entry->imp_template = implementation_template;
5623 synth_forward_declarations ();
5624 imp_entry->class_decl = UOBJC_CLASS_decl;
5625 imp_entry->meta_decl = UOBJC_METACLASS_decl;
5627 /* append to front and increment count */
5628 imp_list = imp_entry;
5629 if (TREE_CODE (class) == CLASS_IMPLEMENTATION_TYPE)
5634 return ivar_context;
5636 else if (TREE_CODE (class) == CLASS_INTERFACE_TYPE)
5638 tree record = xref_tag (RECORD_TYPE, CLASS_NAME (class));
5640 if (!TYPE_FIELDS (record))
5642 finish_struct (record, build_ivar_chain (class, 0));
5643 CLASS_STATIC_TEMPLATE (class) = record;
5645 /* mark this record as a class template - for static typing */
5646 TREE_STATIC_TEMPLATE (record) = 1;
5651 return error_mark_node;
5654 /* This is called once we see the "@end" in an interface/implementation. */
5657 finish_class (class)
5660 if (TREE_CODE (class) == CLASS_IMPLEMENTATION_TYPE)
5662 /* all code generation is done in finish_objc */
5664 if (implementation_template != implementation_context)
5666 /* ensure that all method listed in the interface contain bodies! */
5667 check_methods (CLASS_CLS_METHODS (implementation_template),
5668 CLASS_CLS_METHODS (implementation_context), '+');
5669 check_methods (CLASS_NST_METHODS (implementation_template),
5670 CLASS_NST_METHODS (implementation_context), '-');
5672 if (CLASS_PROTOCOL_LIST (implementation_template))
5673 check_protocols (CLASS_PROTOCOL_LIST (implementation_template),
5675 IDENTIFIER_POINTER (CLASS_NAME (implementation_context)));
5678 else if (TREE_CODE (class) == CATEGORY_IMPLEMENTATION_TYPE)
5680 tree category = CLASS_CATEGORY_LIST (implementation_template);
5682 /* find the category interface from the class it is associated with */
5685 if (CLASS_SUPER_NAME (class) == CLASS_SUPER_NAME (category))
5687 category = CLASS_CATEGORY_LIST (category);
5692 /* ensure that all method listed in the interface contain bodies! */
5693 check_methods (CLASS_CLS_METHODS (category),
5694 CLASS_CLS_METHODS (implementation_context), '+');
5695 check_methods (CLASS_NST_METHODS (category),
5696 CLASS_NST_METHODS (implementation_context), '-');
5698 if (CLASS_PROTOCOL_LIST (category))
5699 check_protocols (CLASS_PROTOCOL_LIST (category),
5701 IDENTIFIER_POINTER (CLASS_SUPER_NAME (implementation_context)));
5704 else if (TREE_CODE (class) == CLASS_INTERFACE_TYPE)
5707 char *class_name = IDENTIFIER_POINTER (CLASS_NAME (class));
5708 char *string = (char *) alloca (strlen (class_name) + 3);
5710 /* extern struct objc_object *_<my_name>; */
5712 sprintf (string, "_%s", class_name);
5714 decl_specs = build_tree_list (NULLT, ridpointers[(int) RID_EXTERN]);
5715 decl_specs = tree_cons (NULLT, objc_object_reference, decl_specs);
5716 define_decl (build1 (INDIRECT_REF, NULLT, get_identifier (string)),
5722 add_protocol (protocol)
5725 /* put protocol on list in reverse order */
5726 TREE_CHAIN (protocol) = protocol_chain;
5727 protocol_chain = protocol;
5728 return protocol_chain;
5732 lookup_protocol (ident)
5737 for (chain = protocol_chain; chain; chain = TREE_CHAIN (chain))
5739 if (ident == PROTOCOL_NAME (chain))
5746 start_protocol (code, name, list)
5747 enum tree_code code;
5753 if (!doing_objc_thang)
5756 /* This is as good a place as any. Need to invoke push_tag_toplevel. */
5757 if (!objc_protocol_template)
5758 objc_protocol_template = build_protocol_template ();
5760 protocol = make_node (code);
5761 TYPE_BINFO (protocol) = make_tree_vec (2);
5763 PROTOCOL_NAME (protocol) = name;
5764 PROTOCOL_LIST (protocol) = list;
5766 lookup_and_install_protocols (list);
5768 if (lookup_protocol (name))
5769 warning ("duplicate declaration for protocol `%s'",
5770 IDENTIFIER_POINTER (name));
5772 add_protocol (protocol);
5774 PROTOCOL_FORWARD_DECL (protocol) = NULL_TREE;
5780 finish_protocol (protocol)
5786 /* "Encode" a data type into a string, which grows in util_obstack.
5787 ??? What is the FORMAT? Someone please document this! */
5790 encode_type_qualifiers (declspecs)
5795 for (spec = declspecs; spec; spec = TREE_CHAIN (spec))
5797 if (ridpointers[RID_CONST] == TREE_VALUE (spec))
5798 obstack_1grow (&util_obstack, 'r');
5799 else if (ridpointers[RID_IN] == TREE_VALUE (spec))
5800 obstack_1grow (&util_obstack, 'n');
5801 else if (ridpointers[RID_INOUT] == TREE_VALUE (spec))
5802 obstack_1grow (&util_obstack, 'N');
5803 else if (ridpointers[RID_OUT] == TREE_VALUE (spec))
5804 obstack_1grow (&util_obstack, 'o');
5805 else if (ridpointers[RID_BYCOPY] == TREE_VALUE (spec))
5806 obstack_1grow (&util_obstack, 'O');
5807 else if (ridpointers[RID_ONEWAY] == TREE_VALUE (spec))
5808 obstack_1grow (&util_obstack, 'V');
5812 /* Encode a pointer type. */
5815 encode_pointer (type, curtype, format)
5820 tree pointer_to = TREE_TYPE (type);
5822 if (TREE_CODE (pointer_to) == RECORD_TYPE)
5824 if (TYPE_NAME (pointer_to)
5825 && TREE_CODE (TYPE_NAME (pointer_to)) == IDENTIFIER_NODE)
5827 char *name = IDENTIFIER_POINTER (TYPE_NAME (pointer_to));
5829 if (strcmp (name, TAG_OBJECT) == 0) /* '@' */
5831 obstack_1grow (&util_obstack, '@');
5834 else if (TREE_STATIC_TEMPLATE (pointer_to))
5836 if (generating_instance_variables)
5838 obstack_1grow (&util_obstack, '@');
5839 obstack_1grow (&util_obstack, '"');
5840 obstack_grow (&util_obstack, name, strlen (name));
5841 obstack_1grow (&util_obstack, '"');
5846 obstack_1grow (&util_obstack, '@');
5850 else if (strcmp (name, TAG_CLASS) == 0) /* '#' */
5852 obstack_1grow (&util_obstack, '#');
5855 #ifndef OBJC_INT_SELECTORS
5856 else if (strcmp (name, TAG_SELECTOR) == 0) /* ':' */
5858 obstack_1grow (&util_obstack, ':');
5861 #endif /* OBJC_INT_SELECTORS */
5864 else if (TREE_CODE (pointer_to) == INTEGER_TYPE
5865 && TYPE_MODE (pointer_to) == QImode)
5867 obstack_1grow (&util_obstack, '*');
5871 /* we have a type that does not get special treatment... */
5873 /* NeXT extension */
5874 obstack_1grow (&util_obstack, '^');
5875 encode_type (pointer_to, curtype, format);
5879 encode_array (type, curtype, format)
5884 tree an_int_cst = TYPE_SIZE (type);
5885 tree array_of = TREE_TYPE (type);
5888 /* An incomplete array is treated like a pointer. */
5889 if (an_int_cst == NULL)
5891 /* split for obvious reasons. North-Keys 30 Mar 1991 */
5892 encode_pointer (type, curtype, format);
5896 sprintf (buffer, "[%d",
5897 (TREE_INT_CST_LOW (an_int_cst)
5898 / TREE_INT_CST_LOW (TYPE_SIZE (array_of))));
5899 obstack_grow (&util_obstack, buffer, strlen (buffer));
5900 encode_type (array_of, curtype, format);
5901 obstack_1grow (&util_obstack, ']');
5906 encode_aggregate (type, curtype, format)
5911 enum tree_code code = TREE_CODE (type);
5917 if (obstack_object_size (&util_obstack) > 0
5918 && *(obstack_next_free (&util_obstack) - 1) == '^')
5920 tree name = TYPE_NAME (type);
5922 /* we have a reference - this is a NeXT extension */
5924 if (obstack_object_size (&util_obstack) - curtype == 1
5925 && format == OBJC_ENCODE_INLINE_DEFS)
5927 /* output format of struct for first level only! */
5929 tree fields = TYPE_FIELDS (type);
5931 if (name && TREE_CODE (name) == IDENTIFIER_NODE)
5933 obstack_1grow (&util_obstack, '{');
5934 obstack_grow (&util_obstack,
5935 IDENTIFIER_POINTER (name),
5936 strlen (IDENTIFIER_POINTER (name)));
5937 obstack_1grow (&util_obstack, '=');
5940 obstack_grow (&util_obstack, "{?=", 3);
5942 for ( ; fields; fields = TREE_CHAIN (fields))
5943 encode_field_decl (fields, curtype, format);
5944 obstack_1grow (&util_obstack, '}');
5946 else if (name && TREE_CODE (name) == IDENTIFIER_NODE)
5948 obstack_1grow (&util_obstack, '{');
5949 obstack_grow (&util_obstack,
5950 IDENTIFIER_POINTER (name),
5951 strlen (IDENTIFIER_POINTER (name)));
5952 obstack_1grow (&util_obstack, '}');
5954 else /* we have an untagged structure or a typedef */
5955 obstack_grow (&util_obstack, "{?}", 3);
5959 tree name = TYPE_NAME (type);
5960 tree fields = TYPE_FIELDS (type);
5962 if (format == OBJC_ENCODE_INLINE_DEFS
5963 || generating_instance_variables)
5965 obstack_1grow (&util_obstack, '{');
5966 if (name && TREE_CODE (name) == IDENTIFIER_NODE)
5967 obstack_grow (&util_obstack,
5968 IDENTIFIER_POINTER (name),
5969 strlen (IDENTIFIER_POINTER (name)));
5971 obstack_1grow (&util_obstack, '?');
5973 obstack_1grow (&util_obstack, '=');
5975 for (; fields; fields = TREE_CHAIN (fields))
5977 if (generating_instance_variables)
5979 tree fname = DECL_NAME (fields);
5981 obstack_1grow (&util_obstack, '"');
5982 if (fname && TREE_CODE (fname) == IDENTIFIER_NODE)
5984 obstack_grow (&util_obstack,
5985 IDENTIFIER_POINTER (fname),
5986 strlen (IDENTIFIER_POINTER (fname)));
5988 obstack_1grow (&util_obstack, '"');
5990 encode_field_decl (fields, curtype, format);
5992 obstack_1grow (&util_obstack, '}');
5996 obstack_1grow (&util_obstack, '{');
5997 if (name && TREE_CODE (name) == IDENTIFIER_NODE)
5998 obstack_grow (&util_obstack,
5999 IDENTIFIER_POINTER (name),
6000 strlen (IDENTIFIER_POINTER (name)));
6001 else /* we have an untagged structure or a typedef */
6002 obstack_1grow (&util_obstack, '?');
6003 obstack_1grow (&util_obstack, '}');
6010 if (*obstack_next_free (&util_obstack) == '^'
6011 || format != OBJC_ENCODE_INLINE_DEFS)
6013 /* we have a reference - this is a NeXT extension--
6014 or we don't want the details. */
6015 if (TYPE_NAME (type)
6016 && TREE_CODE (TYPE_NAME (type)) == IDENTIFIER_NODE)
6018 obstack_1grow (&util_obstack, '(');
6019 obstack_grow (&util_obstack,
6020 IDENTIFIER_POINTER (TYPE_NAME (type)),
6021 strlen (IDENTIFIER_POINTER (TYPE_NAME (type))));
6022 obstack_1grow (&util_obstack, ')');
6024 else /* we have an untagged structure or a typedef */
6025 obstack_grow (&util_obstack, "(?)", 3);
6029 tree fields = TYPE_FIELDS (type);
6030 obstack_1grow (&util_obstack, '(');
6031 for ( ; fields; fields = TREE_CHAIN (fields))
6032 encode_field_decl (fields, curtype, format);
6033 obstack_1grow (&util_obstack, ')');
6039 obstack_1grow (&util_obstack, 'i');
6044 /* Support bitfields, the current version of Objective-C does not support
6045 them. the string will consist of one or more "b:n"'s where n is an
6046 integer describing the width of the bitfield. Currently, classes in
6047 the kit implement a method "-(char *)describeBitfieldStruct:" that
6048 simulates this...if they do not implement this method, the archiver
6049 assumes the bitfield is 16 bits wide (padded if necessary) and packed
6050 according to the GNU compiler. After looking at the "kit", it appears
6051 that all classes currently rely on this default behavior, rather than
6052 hand generating this string (which is tedious). */
6055 encode_bitfield (width, format)
6060 sprintf (buffer, "b%d", width);
6061 obstack_grow (&util_obstack, buffer, strlen (buffer));
6064 /* FORMAT will be OBJC_ENCODE_INLINE_DEFS or OBJC_ENCODE_DONT_INLINE_DEFS. */
6067 encode_type (type, curtype, format)
6072 enum tree_code code = TREE_CODE (type);
6074 if (code == INTEGER_TYPE)
6076 if (TREE_INT_CST_LOW (TYPE_MIN_VALUE (type)) == 0)
6078 /* unsigned integer types */
6080 if (TYPE_MODE (type) == QImode) /* 'C' */
6081 obstack_1grow (&util_obstack, 'C');
6082 else if (TYPE_MODE (type) == HImode) /* 'S' */
6083 obstack_1grow (&util_obstack, 'S');
6084 else if (TYPE_MODE (type) == SImode)
6086 if (type == long_unsigned_type_node)
6087 obstack_1grow (&util_obstack, 'L'); /* 'L' */
6089 obstack_1grow (&util_obstack, 'I'); /* 'I' */
6092 else /* signed integer types */
6094 if (TYPE_MODE (type) == QImode) /* 'c' */
6095 obstack_1grow (&util_obstack, 'c');
6096 else if (TYPE_MODE (type) == HImode) /* 's' */
6097 obstack_1grow (&util_obstack, 's');
6098 else if (TYPE_MODE (type) == SImode) /* 'i' */
6100 if (type == long_integer_type_node)
6101 obstack_1grow (&util_obstack, 'l'); /* 'l' */
6103 obstack_1grow (&util_obstack, 'i'); /* 'i' */
6107 else if (code == REAL_TYPE)
6109 /* floating point types */
6111 if (TYPE_MODE (type) == SFmode) /* 'f' */
6112 obstack_1grow (&util_obstack, 'f');
6113 else if (TYPE_MODE (type) == DFmode
6114 || TYPE_MODE (type) == TFmode) /* 'd' */
6115 obstack_1grow (&util_obstack, 'd');
6118 else if (code == VOID_TYPE) /* 'v' */
6119 obstack_1grow (&util_obstack, 'v');
6121 else if (code == ARRAY_TYPE)
6122 encode_array (type, curtype, format);
6124 else if (code == POINTER_TYPE)
6125 encode_pointer (type, curtype, format);
6127 else if (code == RECORD_TYPE || code == UNION_TYPE || code == ENUMERAL_TYPE)
6128 encode_aggregate (type, curtype, format);
6130 else if (code == FUNCTION_TYPE) /* '?' */
6131 obstack_1grow (&util_obstack, '?');
6135 encode_field_decl (field_decl, curtype, format)
6142 /* If this field is obviously a bitfield, or is a bitfield that has been
6143 clobbered to look like a ordinary integer mode, go ahead and generate
6144 the bitfield typing information. */
6145 type = TREE_TYPE (field_decl);
6146 if (DECL_BIT_FIELD (field_decl))
6147 encode_bitfield (DECL_FIELD_SIZE (field_decl), format);
6148 else if (TREE_CODE (TYPE_SIZE (type)) == INTEGER_CST
6149 && DECL_FIELD_SIZE (field_decl)
6150 && TYPE_MODE (type) > DECL_MODE (field_decl))
6151 encode_bitfield (DECL_FIELD_SIZE (field_decl), format);
6153 encode_type (TREE_TYPE (field_decl), curtype, format);
6157 expr_last (complex_expr)
6163 while ((next = TREE_OPERAND (complex_expr, 0)))
6164 complex_expr = next;
6165 return complex_expr;
6168 /* The selector of the current method,
6169 or NULL if we aren't compiling a method. */
6172 maybe_objc_method_name (decl)
6176 return METHOD_SEL_NAME (method_context);
6181 /* Transform a method definition into a function definition as follows:
6182 - synthesize the first two arguments, "self" and "_cmd". */
6185 start_method_def (method)
6190 /* Required to implement _msgSuper. */
6191 method_context = method;
6192 UOBJC_SUPER_decl = NULLT;
6194 pushlevel (0); /* Must be called BEFORE start_function. */
6196 /* Generate prototype declarations for arguments..."new-style". */
6198 if (TREE_CODE (method_context) == INSTANCE_METHOD_DECL)
6199 decl_specs = build_tree_list (NULLT, uprivate_record);
6201 /* really a `struct objc_class *'...however we allow people to
6202 assign to self...which changes its type midstream. */
6203 decl_specs = build_tree_list (NULLT, objc_object_reference);
6205 push_parm_decl (build_tree_list (decl_specs,
6206 build1 (INDIRECT_REF, NULLT, self_id)));
6208 #ifdef OBJC_INT_SELECTORS
6209 decl_specs = build_tree_list (NULLT, ridpointers[(int) RID_UNSIGNED]);
6210 decl_specs = tree_cons (NULLT, ridpointers[(int) RID_INT], decl_specs);
6211 push_parm_decl (build_tree_list (decl_specs, ucmd_id));
6212 #else /* not OBJC_INT_SELECTORS */
6213 decl_specs = build_tree_list (NULLT,
6214 xref_tag (RECORD_TYPE,
6215 get_identifier (TAG_SELECTOR)));
6216 push_parm_decl (build_tree_list (decl_specs,
6217 build1 (INDIRECT_REF, NULLT, ucmd_id)));
6218 #endif /* not OBJC_INT_SELECTORS */
6220 /* generate argument declarations if a keyword_decl */
6221 if (METHOD_SEL_ARGS (method))
6223 tree arglist = METHOD_SEL_ARGS (method);
6226 tree arg_spec = TREE_PURPOSE (TREE_TYPE (arglist));
6227 tree arg_decl = TREE_VALUE (TREE_TYPE (arglist));
6231 tree last_expr = expr_last (arg_decl);
6233 /* unite the abstract decl with its name */
6234 TREE_OPERAND (last_expr, 0) = KEYWORD_ARG_NAME (arglist);
6235 push_parm_decl (build_tree_list (arg_spec, arg_decl));
6236 /* unhook...restore the abstract declarator */
6237 TREE_OPERAND (last_expr, 0) = NULLT;
6240 push_parm_decl (build_tree_list (arg_spec,
6241 KEYWORD_ARG_NAME (arglist)));
6243 arglist = TREE_CHAIN (arglist);
6248 if (METHOD_ADD_ARGS (method) > (tree)1)
6250 /* we have a variable length selector - in "prototype" format */
6251 tree akey = TREE_PURPOSE (METHOD_ADD_ARGS (method));
6254 /* This must be done prior to calling pushdecl. pushdecl is
6255 going to change our chain on us. */
6256 tree nextkey = TREE_CHAIN (akey);
6264 warn_with_method (message, mtype, method)
6269 if (count_error (1) == 0)
6272 report_error_function (DECL_SOURCE_FILE (method));
6274 fprintf (stderr, "%s:%d: warning: ",
6275 DECL_SOURCE_FILE (method), DECL_SOURCE_LINE (method));
6276 bzero (errbuf, BUFSIZE);
6277 fprintf (stderr, "%s `%c%s'\n",
6278 message, mtype, gen_method_decl (method, errbuf));
6281 /* return 1 if `method' is consistent with `proto' */
6284 comp_method_with_proto (method, proto)
6287 static tree function_type = 0;
6289 /* create a function_type node once */
6292 struct obstack *ambient_obstack = current_obstack;
6294 current_obstack = &permanent_obstack;
6295 function_type = make_node (FUNCTION_TYPE);
6296 current_obstack = ambient_obstack;
6299 /* Install argument types - normally set by build_function_type. */
6300 TYPE_ARG_TYPES (function_type) = get_arg_type_list (proto, METHOD_DEF, 0);
6302 /* install return type */
6303 TREE_TYPE (function_type) = groktypename (TREE_TYPE (proto));
6305 return comptypes (TREE_TYPE (METHOD_DEFINITION (method)), function_type);
6308 /* return 1 if `proto1' is consistent with `proto2' */
6311 comp_proto_with_proto (proto1, proto2)
6312 tree proto1, proto2;
6314 static tree function_type1 = 0, function_type2 = 0;
6316 /* create a couple function_type node's once */
6317 if (!function_type1)
6319 struct obstack *ambient_obstack = current_obstack;
6321 current_obstack = &permanent_obstack;
6322 function_type1 = make_node (FUNCTION_TYPE);
6323 function_type2 = make_node (FUNCTION_TYPE);
6324 current_obstack = ambient_obstack;
6327 /* Install argument types - normally set by build_function_type. */
6328 TYPE_ARG_TYPES (function_type1) = get_arg_type_list (proto1, METHOD_REF, 0);
6329 TYPE_ARG_TYPES (function_type2) = get_arg_type_list (proto2, METHOD_REF, 0);
6331 /* install return type */
6332 TREE_TYPE (function_type1) = groktypename (TREE_TYPE (proto1));
6333 TREE_TYPE (function_type2) = groktypename (TREE_TYPE (proto2));
6335 return comptypes (function_type1, function_type2);
6338 /* - generate an identifier for the function. the format is "_n_cls",
6339 where 1 <= n <= nMethods, and cls is the name the implementation we
6341 - install the return type from the method declaration.
6342 - if we have a prototype, check for type consistency. */
6345 really_start_method (method, parmlist)
6346 tree method, parmlist;
6348 tree sc_spec, ret_spec, ret_decl, decl_specs;
6349 tree method_decl, method_id;
6350 char *buf, *sel_name, *class_name, *cat_name;
6352 /* synth the storage class & assemble the return type */
6353 sc_spec = tree_cons (NULLT, ridpointers[(int) RID_STATIC], NULLT);
6354 ret_spec = TREE_PURPOSE (TREE_TYPE (method));
6355 decl_specs = chainon (sc_spec, ret_spec);
6357 sel_name = IDENTIFIER_POINTER (METHOD_SEL_NAME (method));
6358 class_name = IDENTIFIER_POINTER (CLASS_NAME (implementation_context));
6359 cat_name = ((TREE_CODE (implementation_context)
6360 == CLASS_IMPLEMENTATION_TYPE)
6362 : IDENTIFIER_POINTER (CLASS_SUPER_NAME (implementation_context)));
6364 /* Make sure this is big enough for any plausible method label. */
6365 buf = (char *) alloca (50 + strlen (sel_name) + strlen (class_name)
6366 + (cat_name ? strlen (cat_name) : 0));
6368 OBJC_GEN_METHOD_LABEL (buf, TREE_CODE (method) == INSTANCE_METHOD_DECL,
6369 class_name, cat_name, sel_name, method_slot);
6371 method_id = get_identifier (buf);
6373 method_decl = build_nt (CALL_EXPR, method_id, parmlist, NULLT);
6375 /* check the declarator portion of the return type for the method */
6376 if ((ret_decl = TREE_VALUE (TREE_TYPE (method))))
6378 /* unite the complex decl (specified in the abstract decl) with the
6379 function decl just synthesized..(int *), (int (*)()), (int (*)[]). */
6380 tree save_expr = expr_last (ret_decl);
6382 TREE_OPERAND (save_expr, 0) = method_decl;
6383 method_decl = ret_decl;
6384 /* fool the parser into thinking it is starting a function */
6385 start_function (decl_specs, method_decl, 0);
6386 /* unhook...this has the effect of restoring the abstract declarator */
6387 TREE_OPERAND (save_expr, 0) = NULLT;
6391 TREE_VALUE (TREE_TYPE (method)) = method_decl;
6392 /* fool the parser into thinking it is starting a function */
6393 start_function (decl_specs, method_decl, 0);
6394 /* unhook...this has the effect of restoring the abstract declarator */
6395 TREE_VALUE (TREE_TYPE (method)) = NULLT;
6398 METHOD_DEFINITION (method) = current_function_decl;
6400 /* Check consistency...start_function, pushdecl, duplicate_decls. */
6402 if (implementation_template != implementation_context)
6406 if (TREE_CODE (method) == INSTANCE_METHOD_DECL)
6407 proto = lookup_instance_method_static (implementation_template,
6408 METHOD_SEL_NAME (method));
6410 proto = lookup_class_method_static (implementation_template,
6411 METHOD_SEL_NAME (method));
6413 if (proto && ! comp_method_with_proto (method, proto))
6415 char type = (TREE_CODE (method) == INSTANCE_METHOD_DECL ? '-' : '+');
6417 warn_with_method ("conflicting types for", type, method);
6418 warn_with_method ("previous declaration of", type, proto);
6423 /* The following routine is always called...this "architecture" is to
6424 accommodate "old-style" variable length selectors.
6426 - a:a b:b // prototype ; id c; id d; // old-style. */
6429 continue_method_def ()
6433 if (METHOD_ADD_ARGS (method_context) == (tree)1)
6434 /* We have a `, ...' immediately following the selector. */
6435 parmlist = get_parm_info (0);
6437 parmlist = get_parm_info (1); /* place a `void_at_end' */
6439 /* Set self_decl from the first argument...this global is used by
6440 build_ivar_reference calling build_indirect_ref. */
6441 self_decl = TREE_PURPOSE (parmlist);
6443 poplevel (0, 0, 0); /* must be called BEFORE start_function. */
6445 really_start_method (method_context, parmlist);
6447 store_parm_decls (); /* must be called AFTER start_function. */
6450 /* Called by the parser, from the `pushlevel' production. */
6455 if (!UOBJC_SUPER_decl)
6457 UOBJC_SUPER_decl = start_decl (get_identifier (UTAG_SUPER),
6458 build_tree_list (NULLT,
6459 objc_super_template),
6462 finish_decl (UOBJC_SUPER_decl, NULLT, NULLT);
6464 /* this prevents `unused variable' warnings when compiling with -Wall. */
6465 DECL_IN_SYSTEM_HEADER (UOBJC_SUPER_decl) = 1;
6469 /* _n_Method (id self, SEL sel, ...)
6471 struct objc_super _S;
6472 _msgSuper ((_S.self = self, _S.class = _cls, &_S), ...);
6476 get_super_receiver ()
6480 tree super_expr, super_expr_list;
6482 /* set receiver to self */
6483 super_expr = build_component_ref (UOBJC_SUPER_decl, self_id);
6484 super_expr = build_modify_expr (super_expr, NOP_EXPR, self_decl);
6485 super_expr_list = build_tree_list (NULLT, super_expr);
6487 /* set class to begin searching */
6488 super_expr = build_component_ref (UOBJC_SUPER_decl,
6489 get_identifier ("class"));
6491 if (TREE_CODE (implementation_context) == CLASS_IMPLEMENTATION_TYPE)
6493 /* [_cls, __cls]Super are "pre-built" in
6494 synth_forward_declarations. */
6496 super_expr = build_modify_expr (super_expr, NOP_EXPR,
6497 ((TREE_CODE (method_context)
6498 == INSTANCE_METHOD_DECL)
6500 : uucls_super_ref));
6502 else /* we have a category... */
6504 tree super_name = CLASS_SUPER_NAME (implementation_template);
6507 if (!super_name) /* Barf if super used in a category of Object. */
6509 error ("no super class declared in interface for `%s'",
6510 IDENTIFIER_POINTER (CLASS_NAME (implementation_template)));
6511 return error_mark_node;
6514 if (flag_next_runtime)
6516 super_class = get_class_reference (super_name);
6517 if (TREE_CODE (method_context) == CLASS_METHOD_DECL)
6519 = build_component_ref (build_indirect_ref (super_class, "->"),
6520 get_identifier ("isa"));
6524 add_class_reference (super_name);
6525 super_class = (TREE_CODE (method_context) == INSTANCE_METHOD_DECL
6526 ? objc_get_class_decl : objc_get_meta_class_decl);
6527 assemble_external (super_class);
6529 = build_function_call
6531 build_tree_list (NULLT,
6532 my_build_string (IDENTIFIER_LENGTH (super_name) + 1,
6533 IDENTIFIER_POINTER (super_name))));
6537 TREE_TYPE (super_class) = TREE_TYPE (ucls_super_ref);
6538 super_expr = build_modify_expr (super_expr, NOP_EXPR, super_class);
6540 chainon (super_expr_list, build_tree_list (NULL_TREE, super_expr));
6542 super_expr = build_unary_op (ADDR_EXPR, UOBJC_SUPER_decl, 0);
6543 chainon (super_expr_list, build_tree_list (NULL_TREE, super_expr));
6545 return build_compound_expr (super_expr_list);
6549 error ("[super ...] must appear in a method context");
6550 return error_mark_node;
6555 encode_method_def (func_decl)
6560 int max_parm_end = 0;
6565 encode_type (TREE_TYPE (TREE_TYPE (func_decl)),
6566 obstack_object_size (&util_obstack),
6567 OBJC_ENCODE_INLINE_DEFS);
6569 for (parms = DECL_ARGUMENTS (func_decl); parms;
6570 parms = TREE_CHAIN (parms))
6572 int parm_end = (forwarding_offset (parms)
6573 + (TREE_INT_CST_LOW (TYPE_SIZE (TREE_TYPE (parms)))
6576 if (parm_end > max_parm_end)
6577 max_parm_end = parm_end;
6580 stack_size = max_parm_end - OBJC_FORWARDING_MIN_OFFSET;
6582 sprintf (buffer, "%d", stack_size);
6583 obstack_grow (&util_obstack, buffer, strlen (buffer));
6585 /* argument types */
6586 for (parms = DECL_ARGUMENTS (func_decl); parms;
6587 parms = TREE_CHAIN (parms))
6590 encode_type (TREE_TYPE (parms),
6591 obstack_object_size (&util_obstack),
6592 OBJC_ENCODE_INLINE_DEFS);
6594 /* compute offset */
6595 sprintf (buffer, "%d", forwarding_offset (parms));
6596 obstack_grow (&util_obstack, buffer, strlen (buffer));
6599 obstack_1grow (&util_obstack, 0); /* null terminate string */
6600 result = get_identifier (obstack_finish (&util_obstack));
6601 obstack_free (&util_obstack, util_firstobj);
6606 finish_method_def ()
6608 METHOD_ENCODING (method_context) = encode_method_def (current_function_decl);
6610 finish_function (0);
6612 /* this must be done AFTER finish_function, since the optimizer may
6613 find "may be used before set" errors. */
6614 method_context = NULLT; /* required to implement _msgSuper. */
6618 lang_report_error_function (decl)
6623 fprintf (stderr, "In method `%s'\n",
6624 IDENTIFIER_POINTER (METHOD_SEL_NAME (method_context)));
6632 is_complex_decl (type)
6635 return (TREE_CODE (type) == ARRAY_TYPE
6636 || TREE_CODE (type) == FUNCTION_TYPE
6637 || (TREE_CODE (type) == POINTER_TYPE && ! IS_ID (type)));
6641 /* Code to convert a decl node into text for a declaration in C. */
6643 static char tmpbuf[256];
6646 adorn_decl (decl, str)
6650 enum tree_code code = TREE_CODE (decl);
6652 if (code == ARRAY_REF)
6654 tree an_int_cst = TREE_OPERAND (decl, 1);
6656 if (an_int_cst && TREE_CODE (an_int_cst) == INTEGER_CST)
6657 sprintf (str + strlen (str), "[%d]", TREE_INT_CST_LOW (an_int_cst));
6661 else if (code == ARRAY_TYPE)
6663 tree an_int_cst = TYPE_SIZE (decl);
6664 tree array_of = TREE_TYPE (decl);
6666 if (an_int_cst && TREE_CODE (an_int_cst) == INTEGER_TYPE)
6667 sprintf (str + strlen (str), "[%d]",
6668 (TREE_INT_CST_LOW (an_int_cst)
6669 / TREE_INT_CST_LOW (TYPE_SIZE (array_of))));
6673 else if (code == CALL_EXPR)
6675 tree chain = TREE_PURPOSE (TREE_OPERAND (decl, 1));
6680 gen_declaration (chain, str);
6681 chain = TREE_CHAIN (chain);
6687 else if (code == FUNCTION_TYPE)
6689 tree chain = TYPE_ARG_TYPES (decl); /* a list of types */
6692 while (chain && TREE_VALUE (chain) != void_type_node)
6694 gen_declaration (TREE_VALUE (chain), str);
6695 chain = TREE_CHAIN (chain);
6696 if (chain && TREE_VALUE (chain) != void_type_node)
6701 else if (code == INDIRECT_REF)
6703 strcpy (tmpbuf, "*");
6704 if (TREE_TYPE (decl) && TREE_CODE (TREE_TYPE (decl)) == TREE_LIST)
6708 for (chain = nreverse (copy_list (TREE_TYPE (decl)));
6710 chain = TREE_CHAIN (chain))
6712 if (TREE_CODE (TREE_VALUE (chain)) == IDENTIFIER_NODE)
6714 strcat (tmpbuf, " ");
6715 strcat (tmpbuf, IDENTIFIER_POINTER (TREE_VALUE (chain)));
6719 strcat (tmpbuf, " ");
6721 strcat (tmpbuf, str);
6722 strcpy (str, tmpbuf);
6724 else if (code == POINTER_TYPE)
6726 strcpy (tmpbuf, "*");
6727 if (TREE_READONLY (decl) || TYPE_VOLATILE (decl))
6729 if (TREE_READONLY (decl))
6730 strcat (tmpbuf, " const");
6731 if (TYPE_VOLATILE (decl))
6732 strcat (tmpbuf, " volatile");
6734 strcat (tmpbuf, " ");
6736 strcat (tmpbuf, str);
6737 strcpy (str, tmpbuf);
6742 gen_declarator (decl, buf, name)
6749 enum tree_code code = TREE_CODE (decl);
6759 op = TREE_OPERAND (decl, 0);
6761 /* we have a pointer to a function or array...(*)(), (*)[] */
6762 if ((code == ARRAY_REF || code == CALL_EXPR)
6763 && op && TREE_CODE (op) == INDIRECT_REF)
6766 str = gen_declarator (op, buf, name);
6770 strcpy (tmpbuf, "(");
6771 strcat (tmpbuf, str);
6772 strcat (tmpbuf, ")");
6773 strcpy (str, tmpbuf);
6776 adorn_decl (decl, str);
6785 /* this clause is done iteratively...rather than recursively */
6788 op = (is_complex_decl (TREE_TYPE (decl))
6789 ? TREE_TYPE (decl) : NULLT);
6791 adorn_decl (decl, str);
6793 /* we have a pointer to a function or array...(*)(), (*)[] */
6794 if (code == POINTER_TYPE
6795 && op && (TREE_CODE (op) == FUNCTION_TYPE
6796 || TREE_CODE (op) == ARRAY_TYPE))
6798 strcpy (tmpbuf, "(");
6799 strcat (tmpbuf, str);
6800 strcat (tmpbuf, ")");
6801 strcpy (str, tmpbuf);
6804 decl = (is_complex_decl (TREE_TYPE (decl))
6805 ? TREE_TYPE (decl) : NULLT);
6807 while (decl && (code = TREE_CODE (decl)));
6811 case IDENTIFIER_NODE:
6812 /* will only happen if we are processing a "raw" expr-decl. */
6813 strcpy (buf, IDENTIFIER_POINTER (decl));
6819 else /* we have an abstract declarator or a _DECL node */
6827 gen_declspecs (declspecs, buf, raw)
6836 for (chain = nreverse (copy_list (declspecs));
6837 chain; chain = TREE_CHAIN (chain))
6839 tree aspec = TREE_VALUE (chain);
6841 if (TREE_CODE (aspec) == IDENTIFIER_NODE)
6842 strcat (buf, IDENTIFIER_POINTER (aspec));
6843 else if (TREE_CODE (aspec) == RECORD_TYPE)
6845 if (TYPE_NAME (aspec))
6847 tree protocol_list = TYPE_PROTOCOL_LIST (aspec);
6849 if (! TREE_STATIC_TEMPLATE (aspec))
6850 strcat (buf, "struct ");
6851 strcat (buf, IDENTIFIER_POINTER (TYPE_NAME (aspec)));
6856 tree chain = protocol_list;
6861 strcat (buf, IDENTIFIER_POINTER (PROTOCOL_NAME (TREE_VALUE (chain))));
6862 chain = TREE_CHAIN (chain);
6870 strcat (buf, "untagged struct");
6872 else if (TREE_CODE (aspec) == UNION_TYPE)
6874 if (TYPE_NAME (aspec))
6876 if (! TREE_STATIC_TEMPLATE (aspec))
6877 strcat (buf, "union ");
6878 strcat (buf, IDENTIFIER_POINTER (TYPE_NAME (aspec)));
6881 strcat (buf, "untagged union");
6883 else if (TREE_CODE (aspec) == ENUMERAL_TYPE)
6885 if (TYPE_NAME (aspec))
6887 if (! TREE_STATIC_TEMPLATE (aspec))
6888 strcat (buf, "enum ");
6889 strcat (buf, IDENTIFIER_POINTER (TYPE_NAME (aspec)));
6892 strcat (buf, "untagged enum");
6894 else if (TREE_CODE (aspec) == TYPE_DECL && DECL_NAME (aspec))
6896 strcat (buf, IDENTIFIER_POINTER (DECL_NAME (aspec)));
6899 else if (IS_ID (aspec))
6901 tree protocol_list = TYPE_PROTOCOL_LIST (aspec);
6906 tree chain = protocol_list;
6911 strcat (buf, IDENTIFIER_POINTER (PROTOCOL_NAME (TREE_VALUE (chain))));
6912 chain = TREE_CHAIN (chain);
6919 if (TREE_CHAIN (chain))
6925 /* type qualifiers */
6927 if (TREE_READONLY (declspecs))
6928 strcat (buf, "const ");
6929 if (TYPE_VOLATILE (declspecs))
6930 strcat (buf, "volatile ");
6932 switch (TREE_CODE (declspecs))
6934 /* type specifiers */
6936 case INTEGER_TYPE: /* signed integer types */
6937 declspecs = TYPE_MAIN_VARIANT (declspecs);
6939 if (declspecs == short_integer_type_node) /* 's' */
6940 strcat (buf, "short int ");
6941 else if (declspecs == integer_type_node) /* 'i' */
6942 strcat (buf, "int ");
6943 else if (declspecs == long_integer_type_node) /* 'l' */
6944 strcat (buf, "long int ");
6945 else if (declspecs == long_long_integer_type_node) /* 'l' */
6946 strcat (buf, "long long int ");
6947 else if (declspecs == signed_char_type_node /* 'c' */
6948 || declspecs == char_type_node)
6949 strcat (buf, "char ");
6951 /* unsigned integer types */
6953 else if (declspecs == short_unsigned_type_node) /* 'S' */
6954 strcat (buf, "unsigned short ");
6955 else if (declspecs == unsigned_type_node) /* 'I' */
6956 strcat (buf, "unsigned int ");
6957 else if (declspecs == long_unsigned_type_node) /* 'L' */
6958 strcat (buf, "unsigned long ");
6959 else if (declspecs == long_long_unsigned_type_node) /* 'L' */
6960 strcat (buf, "unsigned long long ");
6961 else if (declspecs == unsigned_char_type_node) /* 'C' */
6962 strcat (buf, "unsigned char ");
6965 case REAL_TYPE: /* floating point types */
6966 declspecs = TYPE_MAIN_VARIANT (declspecs);
6968 if (declspecs == float_type_node) /* 'f' */
6969 strcat (buf, "float ");
6970 else if (declspecs == double_type_node) /* 'd' */
6971 strcat (buf, "double ");
6972 else if (declspecs == long_double_type_node) /* 'd' */
6973 strcat (buf, "long double ");
6977 if (TYPE_NAME (declspecs)
6978 && TREE_CODE (TYPE_NAME (declspecs)) == IDENTIFIER_NODE)
6980 tree protocol_list = TYPE_PROTOCOL_LIST (declspecs);
6982 if (! TREE_STATIC_TEMPLATE (declspecs))
6983 strcat (buf, "struct ");
6984 strcat (buf, IDENTIFIER_POINTER (TYPE_NAME (declspecs)));
6988 tree chain = protocol_list;
6993 strcat (buf, IDENTIFIER_POINTER (PROTOCOL_NAME (TREE_VALUE (chain))));
6994 chain = TREE_CHAIN (chain);
7002 strcat (buf, "untagged struct");
7008 if (TYPE_NAME (declspecs)
7009 && TREE_CODE (TYPE_NAME (declspecs)) == IDENTIFIER_NODE)
7011 strcat (buf, "union ");
7012 strcat (buf, IDENTIFIER_POINTER (TYPE_NAME (declspecs)));
7016 strcat (buf, "untagged union ");
7020 if (TYPE_NAME (declspecs)
7021 && TREE_CODE (TYPE_NAME (declspecs)) == IDENTIFIER_NODE)
7023 strcat (buf, "enum ");
7024 strcat (buf, IDENTIFIER_POINTER (TYPE_NAME (declspecs)));
7028 strcat (buf, "untagged enum ");
7032 strcat (buf, "void ");
7038 tree protocol_list = TYPE_PROTOCOL_LIST (declspecs);
7043 tree chain = protocol_list;
7048 strcat (buf, IDENTIFIER_POINTER (PROTOCOL_NAME (TREE_VALUE (chain))));
7049 chain = TREE_CHAIN (chain);
7061 gen_declaration (atype_or_adecl, buf)
7062 tree atype_or_adecl;
7067 if (TREE_CODE (atype_or_adecl) == TREE_LIST)
7069 tree declspecs; /* "identifier_node", "record_type" */
7070 tree declarator; /* "array_ref", "indirect_ref", "call_expr"... */
7072 /* we have a "raw", abstract declarator (typename) */
7073 declarator = TREE_VALUE (atype_or_adecl);
7074 declspecs = TREE_PURPOSE (atype_or_adecl);
7076 gen_declspecs (declspecs, buf, 1);
7080 strcat (buf, gen_declarator (declarator, declbuf, ""));
7086 tree declspecs; /* "integer_type", "real_type", "record_type"... */
7087 tree declarator; /* "array_type", "function_type", "pointer_type". */
7089 if (TREE_CODE (atype_or_adecl) == FIELD_DECL
7090 || TREE_CODE (atype_or_adecl) == PARM_DECL
7091 || TREE_CODE (atype_or_adecl) == FUNCTION_DECL)
7092 atype = TREE_TYPE (atype_or_adecl);
7094 atype = atype_or_adecl; /* assume we have a *_type node */
7096 if (is_complex_decl (atype))
7100 /* get the declaration specifier...it is at the end of the list */
7101 declarator = chain = atype;
7103 chain = TREE_TYPE (chain); /* not TREE_CHAIN (chain); */
7104 while (is_complex_decl (chain));
7113 gen_declspecs (declspecs, buf, 0);
7115 if (TREE_CODE (atype_or_adecl) == FIELD_DECL
7116 || TREE_CODE (atype_or_adecl) == PARM_DECL
7117 || TREE_CODE (atype_or_adecl) == FUNCTION_DECL)
7119 char *decl_name = (DECL_NAME (atype_or_adecl)
7120 ? IDENTIFIER_POINTER (DECL_NAME (atype_or_adecl))
7126 strcat (buf, gen_declarator (declarator, declbuf, decl_name));
7128 else if (decl_name[0])
7131 strcat (buf, decl_name);
7134 else if (declarator)
7137 strcat (buf, gen_declarator (declarator, declbuf, ""));
7143 #define RAW_TYPESPEC(meth) (TREE_VALUE (TREE_PURPOSE (TREE_TYPE (meth))))
7146 gen_method_decl (method, buf)
7152 if (RAW_TYPESPEC (method) != objc_object_reference)
7155 gen_declaration (TREE_TYPE (method), buf);
7159 chain = METHOD_SEL_ARGS (method);
7161 { /* we have a chain of keyword_decls */
7164 if (KEYWORD_KEY_NAME (chain))
7165 strcat (buf, IDENTIFIER_POINTER (KEYWORD_KEY_NAME (chain)));
7168 if (RAW_TYPESPEC (chain) != objc_object_reference)
7171 gen_declaration (TREE_TYPE (chain), buf);
7174 strcat (buf, IDENTIFIER_POINTER (KEYWORD_ARG_NAME (chain)));
7175 if ((chain = TREE_CHAIN (chain)))
7180 if (METHOD_ADD_ARGS (method) == (tree)1)
7181 strcat (buf, ", ...");
7182 else if (METHOD_ADD_ARGS (method))
7184 /* we have a tree list node as generate by get_parm_info. */
7185 chain = TREE_PURPOSE (METHOD_ADD_ARGS (method));
7186 /* know we have a chain of parm_decls */
7190 gen_declaration (chain, buf);
7191 chain = TREE_CHAIN (chain);
7195 else /* we have a unary selector */
7196 strcat (buf, IDENTIFIER_POINTER (METHOD_SEL_NAME (method)));
7204 dump_interface (fp, chain)
7208 char *buf = (char *)xmalloc (256);
7209 char *my_name = IDENTIFIER_POINTER (CLASS_NAME (chain));
7210 tree ivar_decls = CLASS_RAW_IVARS (chain);
7211 tree nst_methods = CLASS_NST_METHODS (chain);
7212 tree cls_methods = CLASS_CLS_METHODS (chain);
7214 fprintf (fp, "\n@interface %s", my_name);
7216 if (CLASS_SUPER_NAME (chain))
7218 char *super_name = IDENTIFIER_POINTER (CLASS_SUPER_NAME (chain));
7219 fprintf (fp, " : %s\n", super_name);
7226 fprintf (fp, "{\n");
7230 fprintf (fp, "\t%s;\n", gen_declaration (ivar_decls, buf));
7231 ivar_decls = TREE_CHAIN (ivar_decls);
7234 fprintf (fp, "}\n");
7240 fprintf (fp, "- %s;\n", gen_method_decl (nst_methods, buf));
7241 nst_methods = TREE_CHAIN (nst_methods);
7247 fprintf (fp, "+ %s;\n", gen_method_decl (cls_methods, buf));
7248 cls_methods = TREE_CHAIN (cls_methods);
7250 fprintf (fp, "\n@end");
7256 /* Add the special tree codes of Objective C to the tables. */
7258 #define LAST_CODE LAST_AND_UNUSED_TREE_CODE
7260 gcc_obstack_init (&util_obstack);
7261 util_firstobj = (char *) obstack_finish (&util_obstack);
7264 = (char **) xrealloc (tree_code_type,
7265 sizeof (char *) * LAST_OBJC_TREE_CODE);
7267 = (int *) xrealloc (tree_code_length,
7268 sizeof (int) * LAST_OBJC_TREE_CODE);
7270 = (char **) xrealloc (tree_code_name,
7271 sizeof (char *) * LAST_OBJC_TREE_CODE);
7272 bcopy (objc_tree_code_type,
7273 tree_code_type + (int) LAST_CODE,
7274 (((int) LAST_OBJC_TREE_CODE - (int) LAST_CODE)
7275 * sizeof (char *)));
7276 bcopy (objc_tree_code_length,
7277 tree_code_length + (int) LAST_CODE,
7278 (((int) LAST_OBJC_TREE_CODE - (int) LAST_CODE)
7280 bcopy (objc_tree_code_name,
7281 tree_code_name + (int) LAST_CODE,
7282 (((int) LAST_OBJC_TREE_CODE - (int) LAST_CODE)
7283 * sizeof (char *)));
7285 errbuf = (char *)xmalloc (BUFSIZE);
7287 synth_module_prologue ();
7293 struct imp_entry *impent;
7295 /* The internally generated initializers appear to have missing braces.
7296 Don't warn about this. */
7297 int save_warn_missing_braces = warn_missing_braces;
7298 warn_missing_braces = 0;
7300 generate_forward_declaration_to_string_table ();
7302 #ifdef OBJC_PROLOGUE
7306 if (implementation_context || class_names_chain
7307 || meth_var_names_chain || meth_var_types_chain || sel_ref_chain)
7308 generate_objc_symtab_decl ();
7310 for (impent = imp_list; impent; impent = impent->next)
7312 implementation_context = impent->imp_context;
7313 implementation_template = impent->imp_template;
7315 UOBJC_CLASS_decl = impent->class_decl;
7316 UOBJC_METACLASS_decl = impent->meta_decl;
7318 if (TREE_CODE (implementation_context) == CLASS_IMPLEMENTATION_TYPE)
7320 /* all of the following reference the string pool... */
7321 generate_ivar_lists ();
7322 generate_dispatch_tables ();
7323 generate_shared_structures ();
7327 generate_dispatch_tables ();
7328 generate_category (implementation_context);
7332 /* If we are using an array of selectors, we must always
7333 finish up the array decl even if no selectors were used. */
7334 if (! flag_next_runtime || sel_ref_chain)
7335 build_selector_translation_table ();
7338 generate_protocols ();
7340 if (implementation_context || class_names_chain
7341 || meth_var_names_chain || meth_var_types_chain || sel_ref_chain)
7343 /* Arrange for Objc data structures to be initialized at run time. */
7344 char *init_name = build_module_descriptor ();
7346 assemble_constructor (init_name);
7349 /* dump the class references...this forces the appropriate classes
7350 to be linked into the executable image, preserving unix archive
7351 semantics...this can be removed when we move to a more dynamically
7352 linked environment. */
7353 for (chain = cls_ref_chain; chain; chain = TREE_CHAIN (chain))
7355 handle_class_ref (chain);
7356 if (TREE_PURPOSE (chain))
7357 generate_classref_translation_entry (chain);
7360 for (impent = imp_list; impent; impent = impent->next)
7361 handle_impent (impent);
7363 /* dump the string table last */
7365 generate_strings ();
7367 if (flag_gen_declaration)
7369 add_class (implementation_context);
7370 dump_interface (gen_declaration_file, implementation_context);
7378 /* Run through the selector hash tables and print a warning for any
7379 selector which has multiple methods. */
7381 for (slot = 0; slot < SIZEHASHTABLE; slot++)
7382 for (hsh = cls_method_hash_list[slot]; hsh; hsh = hsh->next)
7385 tree meth = hsh->key;
7386 char type = (TREE_CODE (meth) == INSTANCE_METHOD_DECL
7390 warning ("potential selector conflict for method `%s'",
7391 IDENTIFIER_POINTER (METHOD_SEL_NAME (meth)));
7392 warn_with_method ("found", type, meth);
7393 for (loop = hsh->list; loop; loop = loop->next)
7394 warn_with_method ("found", type, loop->value);
7397 for (slot = 0; slot < SIZEHASHTABLE; slot++)
7398 for (hsh = nst_method_hash_list[slot]; hsh; hsh = hsh->next)
7401 tree meth = hsh->key;
7402 char type = (TREE_CODE (meth) == INSTANCE_METHOD_DECL
7406 warning ("potential selector conflict for method `%s'",
7407 IDENTIFIER_POINTER (METHOD_SEL_NAME (meth)));
7408 warn_with_method ("found", type, meth);
7409 for (loop = hsh->list; loop; loop = loop->next)
7410 warn_with_method ("found", type, loop->value);
7414 warn_missing_braces = save_warn_missing_braces;
7417 /* Subroutines of finish_objc. */
7420 generate_classref_translation_entry (chain)
7423 tree expr, name, decl_specs, decl, sc_spec;
7426 type = TREE_TYPE (TREE_PURPOSE (chain));
7428 expr = add_objc_string (TREE_VALUE (chain), class_names);
7429 expr = build_c_cast (type, expr); /* cast! */
7431 name = DECL_NAME (TREE_PURPOSE (chain));
7433 sc_spec = build_tree_list (NULLT, ridpointers[(int) RID_STATIC]);
7435 /* static struct objc_class * _OBJC_CLASS_REFERENCES_n = ...; */
7436 decl_specs = tree_cons (NULLT, type, sc_spec);
7438 /* the `decl' that is returned from start_decl is the one that we
7439 forward declared in `build_class_reference'. */
7440 decl = start_decl (name, decl_specs, 1);
7441 end_temporary_allocation ();
7442 finish_decl (decl, expr, NULLT);
7447 handle_class_ref (chain)
7450 char *name = IDENTIFIER_POINTER (TREE_VALUE (chain));
7451 if (! flag_next_runtime)
7454 char *string = (char *) alloca (strlen (name) + 30);
7456 sprintf (string, "%sobjc_class_name_%s",
7457 (flag_next_runtime ? "." : "__"), name);
7459 /* Make a decl for this name, so we can use its address in a tree. */
7460 decl = build_decl (VAR_DECL, get_identifier (string), char_type_node);
7461 DECL_EXTERNAL (decl) = 1;
7462 TREE_PUBLIC (decl) = 1;
7465 rest_of_decl_compilation (decl, 0, 0, 0);
7467 /* Make following constant read-only (why not)? */
7468 readonly_data_section ();
7470 /* Inform the assembler about this new external thing. */
7471 assemble_external (decl);
7473 /* Output a constant to reference this address. */
7474 output_constant (build1 (ADDR_EXPR, string_type_node, decl),
7475 int_size_in_bytes (string_type_node));
7479 /* This overreliance on our assembler (i.e. lack of portability)
7480 should be dealt with at some point. The GNU strategy (above)
7481 won't work either, but it is a start. */
7482 char *string = (char *) alloca (strlen (name) + 30);
7483 sprintf (string, ".reference .objc_class_name_%s", name);
7484 assemble_asm (my_build_string (strlen (string) + 1, string));
7489 handle_impent (impent)
7490 struct imp_entry *impent;
7492 implementation_context = impent->imp_context;
7493 implementation_template = impent->imp_template;
7495 if (TREE_CODE (impent->imp_context) == CLASS_IMPLEMENTATION_TYPE)
7497 char *class_name = IDENTIFIER_POINTER (CLASS_NAME (impent->imp_context));
7498 char *string = (char *) alloca (strlen (class_name) + 30);
7500 if (flag_next_runtime)
7502 /* Grossly unportable.
7503 People should know better than to assume
7504 such things about assembler syntax! */
7505 sprintf (string, ".objc_class_name_%s=0", class_name);
7506 assemble_asm (my_build_string (strlen (string) + 1, string));
7508 sprintf (string, ".globl .objc_class_name_%s", class_name);
7509 assemble_asm (my_build_string (strlen (string) + 1, string));
7513 sprintf (string, "%sobjc_class_name_%s",
7514 (flag_next_runtime ? "." : "__"), class_name);
7515 assemble_global (string);
7516 assemble_label (string);
7519 else if (TREE_CODE (impent->imp_context) == CATEGORY_IMPLEMENTATION_TYPE)
7521 char *class_name = IDENTIFIER_POINTER (CLASS_NAME (impent->imp_context));
7522 char *class_super_name
7523 = IDENTIFIER_POINTER (CLASS_SUPER_NAME (impent->imp_context));
7524 char *string = (char *) alloca (strlen (class_name)
7525 + strlen (class_super_name) + 30);
7527 /* Do the same for categories. Even though no references to these
7528 symbols are generated automatically by the compiler, it gives
7529 you a handle to pull them into an archive by hand. */
7530 if (flag_next_runtime)
7532 /* Grossly unportable. */
7533 sprintf (string, ".objc_category_name_%s_%s=0",
7534 class_name, class_super_name);
7535 assemble_asm (my_build_string (strlen (string) + 1, string));
7537 sprintf (string, ".globl .objc_category_name_%s_%s",
7538 class_name, class_super_name);
7539 assemble_asm (my_build_string (strlen (string) + 1, string));
7543 sprintf (string, "%sobjc_category_name_%s_%s",
7544 (flag_next_runtime ? "." : "__"),
7545 class_name, class_super_name);
7546 assemble_global (string);
7547 assemble_label (string);
7558 char *buf = (char *)xmalloc (256);
7560 { /* dump function prototypes */
7561 tree loop = UOBJC_MODULES_decl;
7563 fprintf (fp, "\n\nfunction prototypes:\n");
7566 if (TREE_CODE (loop) == FUNCTION_DECL && DECL_INITIAL (loop))
7568 /* we have a function definition - generate prototype */
7569 bzero (errbuf, BUFSIZE);
7570 gen_declaration (loop, errbuf);
7571 fprintf (fp, "%s;\n", errbuf);
7573 loop = TREE_CHAIN (loop);
7576 { /* dump global chains */
7578 int i, index = 0, offset = 0;
7581 for (i = 0; i < SIZEHASHTABLE; i++)
7583 if (hashlist = nst_method_hash_list[i])
7585 fprintf (fp, "\n\nnst_method_hash_list[%d]:\n", i);
7589 fprintf (fp, "-%s;\n", gen_method_decl (hashlist->key, buf));
7590 hashlist = hashlist->next;
7595 for (i = 0; i < SIZEHASHTABLE; i++)
7597 if (hashlist = cls_method_hash_list[i])
7599 fprintf (fp, "\n\ncls_method_hash_list[%d]:\n", i);
7603 fprintf (fp, "-%s;\n", gen_method_decl (hashlist->key, buf));
7604 hashlist = hashlist->next;
7609 fprintf (fp, "\nsel_refdef_chain:\n");
7610 for (loop = sel_refdef_chain; loop; loop = TREE_CHAIN (loop))
7612 fprintf (fp, "(index: %4d offset: %4d) %s\n", index, offset,
7613 IDENTIFIER_POINTER (TREE_VALUE (loop)));
7615 /* add one for the '\0' character */
7616 offset += IDENTIFIER_LENGTH (TREE_VALUE (loop)) + 1;
7618 fprintf (fp, "\n (max_selector_index: %4d.\n", max_selector_index);
7624 print_lang_statistics ()