1 /* Implement classes and message passing for Objective C.
2 Copyright (C) 1992, 1993 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 tree build_constructor PROTO((tree, tree));
149 static char *build_module_descriptor PROTO((void));
150 static tree init_module_descriptor PROTO((tree));
151 static tree build_objc_method_call PROTO((int, tree, tree, tree, tree, tree));
152 static void generate_strings PROTO((void));
153 static void build_selector_translation_table PROTO((void));
154 static tree build_ivar_chain PROTO((tree, int));
156 static tree build_ivar_template PROTO((void));
157 static tree build_method_template PROTO((void));
158 static tree build_private_template PROTO((tree));
159 static void build_class_template PROTO((void));
160 static void build_category_template PROTO((void));
161 static tree build_super_template PROTO((void));
162 static tree build_category_initializer PROTO((tree, tree, tree, tree, tree, tree));
163 static tree build_protocol_initializer PROTO((tree, tree, tree, tree, tree));
165 static void synth_forward_declarations PROTO((void));
166 static void generate_ivar_lists PROTO((void));
167 static void generate_dispatch_tables PROTO((void));
168 static void generate_shared_structures PROTO((void));
169 static tree generate_protocol_list PROTO((tree));
170 static void generate_forward_declaration_to_string_table PROTO((void));
171 static void build_protocol_reference PROTO((tree));
173 static tree init_selector PROTO((int));
174 static tree build_keyword_selector PROTO((tree));
175 static tree synth_id_with_class_suffix PROTO((char *, tree));
178 extern int apply_args_register_offset PROTO((int));
180 /* misc. bookkeeping */
182 typedef struct hashed_entry *hash;
183 typedef struct hashed_attribute *attr;
185 struct hashed_attribute
197 static void hash_init PROTO((void));
198 static void hash_enter PROTO((hash *, tree));
199 static hash hash_lookup PROTO((hash *, tree));
200 static void hash_add_attr PROTO((hash, tree));
201 static tree lookup_method PROTO((tree, tree));
202 static tree lookup_instance_method_static PROTO((tree, tree));
203 static tree lookup_class_method_static PROTO((tree, tree));
204 static tree add_class PROTO((tree));
205 static void add_category PROTO((tree, tree));
209 class_names, /* class, category, protocol, module names */
210 meth_var_names, /* method and variable names */
211 meth_var_types /* method and variable type descriptors */
214 static tree add_objc_string PROTO((tree, enum string_section));
215 static tree build_objc_string_decl PROTO((tree, enum string_section));
216 static tree build_selector_reference_decl PROTO((tree));
218 /* protocol additions */
220 static tree add_protocol PROTO((tree));
221 static tree lookup_protocol PROTO((tree));
222 static tree lookup_and_install_protocols PROTO((tree));
226 static void encode_type_qualifiers PROTO((tree));
227 static void encode_pointer PROTO((tree, int, int));
228 static void encode_array PROTO((tree, int, int));
229 static void encode_aggregate PROTO((tree, int, int));
230 static void encode_bitfield PROTO((int, int));
231 static void encode_type PROTO((tree, int, int));
232 static void encode_field_decl PROTO((tree, int, int));
234 static void really_start_method PROTO((tree, tree));
235 static int comp_method_with_proto PROTO((tree, tree));
236 static int comp_proto_with_proto PROTO((tree, tree));
237 static tree get_arg_type_list PROTO((tree, int, int));
238 static tree expr_last PROTO((tree));
240 /* utilities for debugging and error diagnostics: */
242 static void warn_with_method PROTO((char *, int, tree));
243 static void error_with_ivar PROTO((char *, tree, tree));
244 static char *gen_method_decl PROTO((tree, char *));
245 static char *gen_declaration PROTO((tree, char *));
246 static char *gen_declarator PROTO((tree, char *, char *));
247 static int is_complex_decl PROTO((tree));
248 static void adorn_decl PROTO((tree, char *));
249 static void dump_interface PROTO((FILE *, tree));
251 /* everything else. */
253 static void objc_fatal PROTO((void));
254 static tree define_decl PROTO((tree, tree));
255 static tree lookup_method_in_protocol_list PROTO((tree, tree, int));
256 static tree lookup_protocol_in_reflist PROTO((tree, tree));
257 static tree create_builtin_decl PROTO((enum tree_code, tree, char *));
258 static tree my_build_string PROTO((int, char *));
259 static void build_objc_symtab_template PROTO((void));
260 static tree init_def_list PROTO((tree));
261 static tree init_objc_symtab PROTO((tree));
262 static void forward_declare_categories PROTO((void));
263 static void generate_objc_symtab_decl PROTO((void));
264 static tree build_selector PROTO((tree));
265 static tree build_msg_pool_reference PROTO((int));
266 static tree build_selector_reference PROTO((tree));
267 static tree build_class_reference_decl PROTO((tree));
268 static void add_class_reference PROTO((tree));
269 static tree objc_copy_list PROTO((tree, tree *));
270 static tree build_protocol_template PROTO((void));
271 static tree build_descriptor_table_initializer PROTO((tree, tree));
272 static tree build_method_prototype_list_template PROTO((tree, int));
273 static tree build_method_prototype_template PROTO((void));
274 static int forwarding_offset PROTO((tree));
275 static tree encode_method_prototype PROTO((tree, tree));
276 static tree generate_descriptor_table PROTO((tree, char *, int, tree, tree));
277 static void generate_method_descriptors PROTO((tree));
278 static tree build_tmp_function_decl PROTO((void));
279 static void hack_method_prototype PROTO((tree, tree));
280 static void generate_protocol_references PROTO((tree));
281 static void generate_protocols PROTO((void));
282 static void check_ivars PROTO((tree, tree));
283 static tree build_ivar_list_template PROTO((tree, int));
284 static tree build_method_list_template PROTO((tree, int));
285 static tree build_ivar_list_initializer PROTO((tree, tree));
286 static tree generate_ivars_list PROTO((tree, char *, int, tree));
287 static tree build_dispatch_table_initializer PROTO((tree, tree));
288 static tree generate_dispatch_table PROTO((tree, char *, int, tree));
289 static tree build_shared_structure_initializer PROTO((tree, tree, tree, tree, tree, int, tree, tree, tree));
290 static void generate_category PROTO((tree));
291 static int is_objc_type_qualifier PROTO((tree));
292 static tree adjust_type_for_id_default PROTO((tree));
293 static tree check_duplicates PROTO((hash));
294 static tree receiver_is_class_object PROTO((tree));
295 static int check_methods PROTO((tree, tree, int));
296 static int conforms_to_protocol PROTO((tree, tree));
297 static void check_protocols PROTO((tree, char *, char *));
298 static tree encode_method_def PROTO((tree));
299 static void gen_declspecs PROTO((tree, char *, int));
300 static void generate_classref_translation_entry PROTO((tree));
301 static void handle_class_ref PROTO((tree));
303 /*** Private Interface (data) ***/
305 /* reserved tag definitions: */
308 #define TAG_OBJECT "objc_object"
309 #define TAG_CLASS "objc_class"
310 #define TAG_SUPER "objc_super"
311 #define TAG_SELECTOR "objc_selector"
313 #define UTAG_CLASS "_objc_class"
314 #define UTAG_IVAR "_objc_ivar"
315 #define UTAG_IVAR_LIST "_objc_ivar_list"
316 #define UTAG_METHOD "_objc_method"
317 #define UTAG_METHOD_LIST "_objc_method_list"
318 #define UTAG_CATEGORY "_objc_category"
319 #define UTAG_MODULE "_objc_module"
320 #define UTAG_SYMTAB "_objc_symtab"
321 #define UTAG_SUPER "_objc_super"
323 #define UTAG_PROTOCOL "_objc_protocol"
324 #define UTAG_PROTOCOL_LIST "_objc_protocol_list"
325 #define UTAG_METHOD_PROTOTYPE "_objc_method_prototype"
326 #define UTAG_METHOD_PROTOTYPE_LIST "_objc__method_prototype_list"
328 #define STRING_OBJECT_CLASS_NAME "NXConstantString"
329 #define PROTOCOL_OBJECT_CLASS_NAME "Protocol"
331 static char* TAG_GETCLASS;
332 static char* TAG_GETMETACLASS;
333 static char* TAG_MSGSEND;
334 static char* TAG_MSGSENDSUPER;
335 static char* TAG_EXECCLASS;
337 /* Set by `continue_class' and checked by `is_public'. */
339 #define TREE_STATIC_TEMPLATE(record_type) (TREE_PUBLIC (record_type))
340 #define TYPED_OBJECT(type) \
341 (TREE_CODE (type) == RECORD_TYPE && TREE_STATIC_TEMPLATE (type))
343 /* Some commonly used instances of "identifier_node". */
345 static tree self_id, ucmd_id;
347 static tree self_decl, umsg_decl, umsg_super_decl;
348 static tree objc_get_class_decl, objc_get_meta_class_decl;
350 static tree super_type, selector_type, id_type, objc_class_type;
351 static tree instance_type, protocol_type;
353 /* Type checking macros. */
355 #define IS_ID(TYPE) \
356 (TYPE_MAIN_VARIANT (TYPE) == TYPE_MAIN_VARIANT (id_type))
357 #define IS_PROTOCOL_QUALIFIED_ID(TYPE) \
358 (IS_ID (TYPE) && TYPE_PROTOCOL_LIST (TYPE))
359 #define IS_SUPER(TYPE) \
360 (super_type && TYPE_MAIN_VARIANT (TYPE) == TYPE_MAIN_VARIANT (super_type))
362 static tree class_chain = NULLT;
363 static tree alias_chain = NULLT;
364 static tree interface_chain = NULLT;
365 static tree protocol_chain = NULLT;
367 /* chains to manage selectors that are referenced and defined in the module */
369 static tree cls_ref_chain = NULLT; /* classes referenced */
370 static tree sel_ref_chain = NULLT; /* selectors referenced */
372 /* chains to manage uniquing of strings */
374 static tree class_names_chain = NULLT;
375 static tree meth_var_names_chain = NULLT;
376 static tree meth_var_types_chain = NULLT;
378 /* hash tables to manage the global pool of method prototypes */
380 static hash *nst_method_hash_list = 0;
381 static hash *cls_method_hash_list = 0;
383 /* backend data declarations */
385 static tree UOBJC_SYMBOLS_decl;
386 static tree UOBJC_INSTANCE_VARIABLES_decl, UOBJC_CLASS_VARIABLES_decl;
387 static tree UOBJC_INSTANCE_METHODS_decl, UOBJC_CLASS_METHODS_decl;
388 static tree UOBJC_CLASS_decl, UOBJC_METACLASS_decl;
389 static tree UOBJC_SELECTOR_TABLE_decl;
390 static tree UOBJC_MODULES_decl;
391 static tree UOBJC_STRINGS_decl;
393 /* The following are used when compiling a class implementation.
394 implementation_template will normally be an interface, however if
395 none exists this will be equal to implementation_context...it is
396 set in start_class. */
398 static tree implementation_context = NULLT,
399 implementation_template = NULLT;
403 struct imp_entry *next;
406 tree class_decl; /* _OBJC_CLASS_<my_name>; */
407 tree meta_decl; /* _OBJC_METACLASS_<my_name>; */
410 static void handle_impent PROTO((struct imp_entry *));
412 static struct imp_entry *imp_list = 0;
413 static int imp_count = 0; /* `@implementation' */
414 static int cat_count = 0; /* `@category' */
416 static tree objc_class_template, objc_category_template, uprivate_record;
417 static tree objc_protocol_template;
418 static tree ucls_super_ref, uucls_super_ref;
420 static tree objc_method_template, objc_ivar_template;
421 static tree objc_symtab_template, objc_module_template;
422 static tree objc_super_template, objc_object_reference;
424 static tree objc_object_id, objc_class_id, objc_id_id;
425 static tree constant_string_id;
426 static tree constant_string_type;
427 static tree UOBJC_SUPER_decl;
429 static tree method_context = NULLT;
430 static int method_slot = 0; /* used by start_method_def */
434 static char *errbuf; /* a buffer for error diagnostics */
436 /* data imported from tree.c */
438 extern struct obstack permanent_obstack, *current_obstack, *rtl_obstack;
440 /* data imported from toplev.c */
442 extern char *dump_base_name;
444 /* Generate code for GNU or NeXT runtime environment. */
446 #ifdef NEXT_OBJC_RUNTIME
447 int flag_next_runtime = 1;
449 int flag_next_runtime = 0;
452 /* Open and close the file for outputting class declarations, if requested. */
454 int flag_gen_declaration = 0;
456 FILE *gen_declaration_file;
458 /* Warn if multiple methods are seen for the same selector, but with
459 different argument types. */
461 int warn_selector = 0;
463 /* Warn if methods required by a protocol are not implemented in the
464 class adopting it. When turned off, methods inherited to that
465 class are also considered implemented */
467 int flag_warn_protocol = 1;
469 /* tells "encode_pointer/encode_aggregate" whether we are generating
470 type descriptors for instance variables (as opposed to methods).
471 Type descriptors for instance variables contain more information
472 than methods (for static typing and embedded structures). This
473 was added to support features being planned for dbkit2. */
475 static int generating_instance_variables = 0;
480 /* the beginning of the file is a new line; check for # */
481 /* With luck, we discover the real source file's name from that
482 and put it in input_filename. */
483 ungetc (check_newline (), finput);
485 /* If gen_declaration desired, open the output file. */
486 if (flag_gen_declaration)
488 int dump_base_name_length = strlen (dump_base_name);
489 register char *dumpname = (char *) xmalloc (dump_base_name_length + 7);
490 strcpy (dumpname, dump_base_name);
491 strcat (dumpname, ".decl");
492 gen_declaration_file = fopen (dumpname, "w");
493 if (gen_declaration_file == 0)
494 pfatal_with_name (dumpname);
497 if (flag_next_runtime)
499 TAG_GETCLASS = "objc_getClass";
500 TAG_GETMETACLASS = "objc_getMetaClass";
501 TAG_MSGSEND = "objc_msgSend";
502 TAG_MSGSENDSUPER = "objc_msgSendSuper";
503 TAG_EXECCLASS = "__objc_execClass";
507 TAG_GETCLASS = "objc_get_class";
508 TAG_GETMETACLASS = "objc_get_meta_class";
509 TAG_MSGSEND = "objc_msg_lookup";
510 TAG_MSGSENDSUPER = "objc_msg_lookup_super";
511 TAG_EXECCLASS = "__objc_exec_class";
514 if (doing_objc_thang)
521 fatal ("Objective-C text in C source file");
527 if (doing_objc_thang)
528 finish_objc (); /* Objective-C finalization */
530 if (gen_declaration_file)
531 fclose (gen_declaration_file);
546 lang_decode_option (p)
549 if (!strcmp (p, "-lang-objc"))
550 doing_objc_thang = 1;
551 else if (!strcmp (p, "-gen-decls"))
552 flag_gen_declaration = 1;
553 else if (!strcmp (p, "-Wselector"))
555 else if (!strcmp (p, "-Wno-selector"))
557 else if (!strcmp (p, "-Wprotocol"))
558 flag_warn_protocol = 1;
559 else if (!strcmp (p, "-Wno-protocol"))
560 flag_warn_protocol = 0;
561 else if (!strcmp (p, "-fgnu-runtime"))
562 flag_next_runtime = 0;
563 else if (!strcmp (p, "-fno-next-runtime"))
564 flag_next_runtime = 0;
565 else if (!strcmp (p, "-fno-gnu-runtime"))
566 flag_next_runtime = 1;
567 else if (!strcmp (p, "-fnext-runtime"))
568 flag_next_runtime = 1;
570 return c_decode_option (p);
576 define_decl (declarator, declspecs)
580 tree decl = start_decl (declarator, declspecs, 0);
581 finish_decl (decl, NULLT, NULLT);
585 /* Return 1 if LHS and RHS are compatible types for assignment or
586 various other operations. Return 0 if they are incompatible, and
587 return -1 if we choose to not decide. When the operation is
588 REFLEXIVE, check for compatibility in either direction.
590 For statically typed objects, an assignment of the form `a' = `b'
594 `a' and `b' are the same class type, or
595 `a' and `b' are of class types A and B such that B is a descendant of A. */
598 maybe_objc_comptypes (lhs, rhs, reflexive)
602 if (doing_objc_thang)
603 return objc_comptypes (lhs, rhs, reflexive);
608 lookup_method_in_protocol_list (rproto_list, sel_name, class_meth)
616 for (rproto = rproto_list; rproto; rproto = TREE_CHAIN (rproto))
618 p = TREE_VALUE (rproto);
620 if (TREE_CODE (p) == PROTOCOL_INTERFACE_TYPE)
622 if ((fnd = lookup_method (class_meth
623 ? PROTOCOL_CLS_METHODS (p)
624 : PROTOCOL_NST_METHODS (p), sel_name)))
626 else if (PROTOCOL_LIST (p))
627 fnd = lookup_method_in_protocol_list (PROTOCOL_LIST (p), sel_name, class_meth);
630 ; /* an identifier...if we could not find a protocol. */
639 lookup_protocol_in_reflist (rproto_list, lproto)
645 /* make sure the protocol is support by the object on the rhs */
646 if (TREE_CODE (lproto) == PROTOCOL_INTERFACE_TYPE)
649 for (rproto = rproto_list; rproto; rproto = TREE_CHAIN (rproto))
651 p = TREE_VALUE (rproto);
653 if (TREE_CODE (p) == PROTOCOL_INTERFACE_TYPE)
658 else if (PROTOCOL_LIST (p))
659 fnd = lookup_protocol_in_reflist (PROTOCOL_LIST (p), lproto);
667 ; /* an identifier...if we could not find a protocol. */
672 /* Return 1 if LHS and RHS are compatible types for assignment
673 or various other operations. Return 0 if they are incompatible,
674 and return -1 if we choose to not decide. When the operation
675 is REFLEXIVE, check for compatibility in either direction. */
678 objc_comptypes (lhs, rhs, reflexive)
683 /* new clause for protocols */
685 if (TREE_CODE (lhs) == POINTER_TYPE
686 && TREE_CODE (TREE_TYPE (lhs)) == RECORD_TYPE
687 && TREE_CODE (rhs) == POINTER_TYPE
688 && TREE_CODE (TREE_TYPE (rhs)) == RECORD_TYPE)
690 int lhs_is_proto = IS_PROTOCOL_QUALIFIED_ID (lhs);
691 int rhs_is_proto = IS_PROTOCOL_QUALIFIED_ID (rhs);
695 tree lproto, lproto_list = TYPE_PROTOCOL_LIST (lhs);
696 tree rproto, rproto_list;
701 rproto_list = TYPE_PROTOCOL_LIST (rhs);
703 /* Make sure the protocol is supported by the object
705 for (lproto = lproto_list; lproto; lproto = TREE_CHAIN (lproto))
707 p = TREE_VALUE (lproto);
708 rproto = lookup_protocol_in_reflist (rproto_list, p);
711 warning ("object does not conform to the `%s' protocol",
712 IDENTIFIER_POINTER (PROTOCOL_NAME (p)));
715 else if (TYPED_OBJECT (TREE_TYPE (rhs)))
717 tree rname = TYPE_NAME (TREE_TYPE (rhs));
720 /* Make sure the protocol is supported by the object
722 for (lproto = lproto_list; lproto; lproto = TREE_CHAIN (lproto))
724 p = TREE_VALUE (lproto);
726 rinter = lookup_interface (rname);
728 while (rinter && !rproto)
732 rproto_list = CLASS_PROTOCOL_LIST (rinter);
733 rproto = lookup_protocol_in_reflist (rproto_list, p);
736 /* Check for protocols adopted by categories. */
737 cat = CLASS_CATEGORY_LIST (rinter);
738 while (cat && !rproto)
740 rproto_list = CLASS_PROTOCOL_LIST (cat);
741 rproto = lookup_protocol_in_reflist (rproto_list, p);
743 cat = CLASS_CATEGORY_LIST (cat);
746 rinter = lookup_interface (CLASS_SUPER_NAME (rinter));
749 warning ("class `%s' does not implement the `%s' protocol",
750 IDENTIFIER_POINTER (TYPE_NAME (TREE_TYPE (rhs))),
751 IDENTIFIER_POINTER (PROTOCOL_NAME (p)));
755 return 1; /* may change...based on whether there was any mismatch */
757 else if (rhs_is_proto)
759 /* lhs is not a protocol...warn if it is statically typed */
761 if (TYPED_OBJECT (TREE_TYPE (lhs)))
764 return 1; /* one of the types is a protocol */
767 return -1; /* defer to comptypes */
769 else if (TREE_CODE (lhs) == RECORD_TYPE && TREE_CODE (rhs) == RECORD_TYPE)
770 ; /* fall thru...this is the case we have been handling all along */
772 return -1; /* defer to comptypes */
774 /* End of new protocol support. */
776 /* `id' = `<class> *', `<class> *' = `id' */
778 if ((TYPE_NAME (lhs) == objc_object_id && TYPED_OBJECT (rhs))
779 || (TYPE_NAME (rhs) == objc_object_id && TYPED_OBJECT (lhs)))
782 /* `id' = `Class', `Class' = `id' */
784 else if ((TYPE_NAME (lhs) == objc_object_id
785 && TYPE_NAME (rhs) == objc_class_id)
786 || (TYPE_NAME (lhs) == objc_class_id
787 && TYPE_NAME (rhs) == objc_object_id))
790 /* `<class> *' = `<class> *' */
792 else if (TYPED_OBJECT (lhs) && TYPED_OBJECT (rhs))
794 tree lname = TYPE_NAME (lhs);
795 tree rname = TYPE_NAME (rhs);
801 /* If the left hand side is a super class of the right hand side,
803 for (inter = lookup_interface (rname); inter;
804 inter = lookup_interface (CLASS_SUPER_NAME (inter)))
805 if (lname == CLASS_SUPER_NAME (inter))
808 /* Allow the reverse when reflexive. */
810 for (inter = lookup_interface (lname); inter;
811 inter = lookup_interface (CLASS_SUPER_NAME (inter)))
812 if (rname == CLASS_SUPER_NAME (inter))
818 return -1; /* defer to comptypes */
821 /* Called from c-decl.c before all calls to rest_of_decl_compilation. */
824 objc_check_decl (decl)
827 tree type = TREE_TYPE (decl);
829 if (TREE_CODE (type) == RECORD_TYPE
830 && TREE_STATIC_TEMPLATE (type)
831 && type != constant_string_type)
833 error_with_decl (decl, "`%s' cannot be statically allocated");
834 fatal ("statically allocated objects not supported");
839 maybe_objc_check_decl (decl)
842 if (doing_objc_thang)
843 objc_check_decl (decl);
846 /* Implement static typing. At this point, we know we have an interface. */
849 get_static_reference (interface, protocols)
853 tree type = xref_tag (RECORD_TYPE, interface);
857 tree t, m = TYPE_MAIN_VARIANT (type);
858 struct obstack *ambient_obstack = current_obstack;
860 current_obstack = &permanent_obstack;
861 t = copy_node (type);
862 TYPE_BINFO (t) = make_tree_vec (2);
864 /* Add this type to the chain of variants of TYPE. */
865 TYPE_NEXT_VARIANT (t) = TYPE_NEXT_VARIANT (m);
866 TYPE_NEXT_VARIANT (m) = t;
868 current_obstack = ambient_obstack;
870 /* Look up protocols and install in lang specific list. */
871 TYPE_PROTOCOL_LIST (t) = lookup_and_install_protocols (protocols);
873 /* This forces a new pointer type to be created later
874 (in build_pointer_type)...so that the new template
875 we just created will actually be used...what a hack! */
876 if (TYPE_POINTER_TO (t))
877 TYPE_POINTER_TO (t) = NULL;
886 get_object_reference (protocols)
889 tree type_decl = lookup_name (objc_id_id);
892 if (type_decl && TREE_CODE (type_decl) == TYPE_DECL)
894 type = TREE_TYPE (type_decl);
895 if (TYPE_MAIN_VARIANT (type) != id_type)
896 warning ("Unexpected type for `id' (%s)",
897 gen_declaration (type, errbuf));
901 fatal ("Undefined type `id', please import <objc/objc.h>");
904 /* This clause creates a new pointer type that is qualified with
905 the protocol specification...this info is used later to do more
906 elaborate type checking. */
909 tree t, m = TYPE_MAIN_VARIANT (type);
910 struct obstack *ambient_obstack = current_obstack;
912 current_obstack = &permanent_obstack;
913 t = copy_node (type);
914 TYPE_BINFO (t) = make_tree_vec (2);
916 /* Add this type to the chain of variants of TYPE. */
917 TYPE_NEXT_VARIANT (t) = TYPE_NEXT_VARIANT (m);
918 TYPE_NEXT_VARIANT (m) = t;
920 current_obstack = ambient_obstack;
922 /* look up protocols...and install in lang specific list */
923 TYPE_PROTOCOL_LIST (t) = lookup_and_install_protocols (protocols);
925 /* This forces a new pointer type to be created later
926 (in build_pointer_type)...so that the new template
927 we just created will actually be used...what a hack! */
928 if (TYPE_POINTER_TO (t))
929 TYPE_POINTER_TO (t) = NULL;
937 lookup_and_install_protocols (protocols)
942 tree return_value = protocols;
944 for (proto = protocols; proto; proto = TREE_CHAIN (proto))
946 tree ident = TREE_VALUE (proto);
947 tree p = lookup_protocol (ident);
951 error ("Cannot find protocol declaration for `%s'",
952 IDENTIFIER_POINTER (ident));
954 TREE_CHAIN (prev) = TREE_CHAIN (proto);
956 return_value = TREE_CHAIN (proto);
960 /* replace identifier with actual protocol node */
961 TREE_VALUE (proto) = p;
968 /* Create and push a decl for a built-in external variable or field NAME.
970 TYPE is its data type. */
973 create_builtin_decl (code, type, name)
978 tree decl = build_decl (code, get_identifier (name), type);
979 if (code == VAR_DECL)
981 TREE_STATIC (decl) = 1;
982 make_decl_rtl (decl, 0, 1);
988 /* purpose: "play" parser, creating/installing representations
989 of the declarations that are required by Objective-C.
993 type_spec--------->sc_spec
994 (tree_list) (tree_list)
997 identifier_node identifier_node */
1000 synth_module_prologue ()
1005 /* defined in `objc.h' */
1006 objc_object_id = get_identifier (TAG_OBJECT);
1008 objc_object_reference = xref_tag (RECORD_TYPE, objc_object_id);
1010 id_type = build_pointer_type (objc_object_reference);
1012 objc_id_id = get_identifier (TYPE_ID);
1013 objc_class_id = get_identifier (TAG_CLASS);
1015 objc_class_type = build_pointer_type (xref_tag (RECORD_TYPE, objc_class_id));
1016 protocol_type = build_pointer_type (xref_tag (RECORD_TYPE,
1017 get_identifier (PROTOCOL_OBJECT_CLASS_NAME)));
1019 /* Declare type of selector-objects that represent an operation name. */
1021 #ifdef OBJC_INT_SELECTORS
1022 /* `unsigned int' */
1023 selector_type = unsigned_type_node;
1025 /* `struct objc_selector *' */
1027 = build_pointer_type (xref_tag (RECORD_TYPE,
1028 get_identifier (TAG_SELECTOR)));
1029 #endif /* not OBJC_INT_SELECTORS */
1031 /* Forward declare type, or else the prototype for msgSendSuper will
1034 super_p = build_pointer_type (xref_tag (RECORD_TYPE,
1035 get_identifier (TAG_SUPER)));
1038 /* id objc_msgSend (id, SEL, ...); */
1041 = build_function_type (id_type,
1042 tree_cons (NULL_TREE, id_type,
1043 tree_cons (NULLT, selector_type, NULLT)));
1045 if (! flag_next_runtime)
1047 umsg_decl = build_decl (FUNCTION_DECL,
1048 get_identifier (TAG_MSGSEND), temp_type);
1049 DECL_EXTERNAL (umsg_decl) = 1;
1050 TREE_PUBLIC (umsg_decl) = 1;
1051 DECL_INLINE (umsg_decl) = 1;
1053 if (flag_traditional && TAG_MSGSEND[0] != '_')
1054 DECL_BUILT_IN_NONANSI (umsg_decl) = 1;
1056 make_decl_rtl (umsg_decl, NULL_PTR, 1);
1057 pushdecl (umsg_decl);
1060 umsg_decl = builtin_function (TAG_MSGSEND, temp_type, NOT_BUILT_IN, 0);
1062 /* id objc_msgSendSuper (struct objc_super *, SEL, ...); */
1065 = build_function_type (id_type,
1066 tree_cons (NULL_TREE, super_p,
1067 tree_cons (NULLT, selector_type, NULLT)));
1069 umsg_super_decl = builtin_function (TAG_MSGSENDSUPER,
1070 temp_type, NOT_BUILT_IN, 0);
1072 /* id objc_getClass (const char *); */
1074 temp_type = build_function_type (id_type,
1076 const_string_type_node,
1077 tree_cons (NULLT, void_type_node, NULLT)));
1080 = builtin_function (TAG_GETCLASS, temp_type, NOT_BUILT_IN, 0);
1082 /* id objc_getMetaClass (const char *); */
1084 objc_get_meta_class_decl
1085 = builtin_function (TAG_GETMETACLASS, temp_type, NOT_BUILT_IN, 0);
1087 /* static SEL _OBJC_SELECTOR_TABLE[]; */
1089 temp_type = build_array_type (selector_type, NULLT);
1090 layout_type (temp_type);
1091 if (! flag_next_runtime)
1092 UOBJC_SELECTOR_TABLE_decl
1093 = create_builtin_decl (VAR_DECL, temp_type,
1094 "_OBJC_SELECTOR_TABLE");
1096 generate_forward_declaration_to_string_table ();
1098 /* Forward declare constant_string_id and constant_string_type. */
1099 constant_string_id = get_identifier (STRING_OBJECT_CLASS_NAME);
1100 constant_string_type = xref_tag (RECORD_TYPE, constant_string_id);
1103 /* Custom build_string which sets TREE_TYPE! */
1106 my_build_string (len, str)
1111 tree a_string = build_string (len, str);
1112 /* Some code from combine_strings, which is local to c-parse.y. */
1113 if (TREE_TYPE (a_string) == int_array_type_node)
1116 TREE_TYPE (a_string) =
1117 build_array_type (wide_flag ? integer_type_node : char_type_node,
1118 build_index_type (build_int_2 (len - 1, 0)));
1120 TREE_CONSTANT (a_string) = 1; /* puts string in the ".text" segment */
1121 TREE_STATIC (a_string) = 1;
1126 /* Return a newly constructed OBJC_STRING_CST node whose value is
1127 the LEN characters at STR.
1128 The TREE_TYPE is not initialized. */
1131 build_objc_string (len, str)
1135 tree s = build_string (len, str);
1137 TREE_SET_CODE (s, OBJC_STRING_CST);
1141 /* Given a chain of OBJC_STRING_CST's, build a static instance of
1142 NXConstantString which points at the concatenation of those strings.
1143 We place the string object in the __string_objects section of the
1144 __OBJC segment. The Objective-C runtime will initialize the isa
1145 pointers of the string objects to point at the NXConstantString
1149 build_objc_string_object (strings)
1152 tree string, initlist, constructor;
1155 if (!doing_objc_thang)
1158 if (lookup_interface (constant_string_id) == NULLT)
1160 error ("Cannot find interface declaration for `%s'",
1161 IDENTIFIER_POINTER (constant_string_id));
1162 return error_mark_node;
1165 add_class_reference (constant_string_id);
1167 /* combine_strings will work for OBJC_STRING_CST's too. */
1168 string = combine_strings (strings);
1169 TREE_SET_CODE (string, STRING_CST);
1170 length = TREE_STRING_LENGTH (string) - 1;
1172 /* & ((NXConstantString) {0, string, length}) */
1174 initlist = build_tree_list (NULLT, build_int_2 (0, 0));
1175 initlist = tree_cons (NULLT, build_unary_op (ADDR_EXPR, string, 1),
1177 initlist = tree_cons (NULLT, build_int_2 (length, 0), initlist);
1178 constructor = build_constructor (constant_string_type,
1179 nreverse (initlist));
1181 return build_unary_op (ADDR_EXPR, constructor, 1);
1184 /* Build a static constant CONSTRUCTOR
1185 with type TYPE and elements ELTS. */
1188 build_constructor (type, elts)
1191 tree constructor = build (CONSTRUCTOR, type, NULL_TREE, elts);
1193 TREE_CONSTANT (constructor) = 1;
1194 TREE_STATIC (constructor) = 1;
1195 TREE_READONLY (constructor) = 1;
1200 /* Take care of defining and initializing _OBJC_SYMBOLS. */
1202 /* Predefine the following data type:
1210 void *defs[cls_def_cnt + cat_def_cnt];
1214 build_objc_symtab_template ()
1216 tree field_decl, field_decl_chain, index;
1218 objc_symtab_template = start_struct (RECORD_TYPE, get_identifier (UTAG_SYMTAB));
1220 /* long sel_ref_cnt; */
1222 field_decl = create_builtin_decl (FIELD_DECL,
1223 long_integer_type_node,
1225 field_decl_chain = field_decl;
1229 field_decl = create_builtin_decl (FIELD_DECL,
1230 build_pointer_type (selector_type),
1232 chainon (field_decl_chain, field_decl);
1234 /* short cls_def_cnt; */
1236 field_decl = create_builtin_decl (FIELD_DECL,
1237 short_integer_type_node,
1239 chainon (field_decl_chain, field_decl);
1241 /* short cat_def_cnt; */
1243 field_decl = create_builtin_decl (FIELD_DECL,
1244 short_integer_type_node,
1246 chainon (field_decl_chain, field_decl);
1248 /* void *defs[cls_def_cnt + cat_def_cnt]; */
1250 index = build_index_type (build_int_2 (imp_count + cat_count - 1,
1251 imp_count == 0 && cat_count == 0
1253 field_decl = create_builtin_decl (FIELD_DECL,
1254 build_array_type (ptr_type_node, index),
1256 chainon (field_decl_chain, field_decl);
1258 finish_struct (objc_symtab_template, field_decl_chain);
1261 /* Create the initial value for the `defs' field of _objc_symtab.
1262 This is a CONSTRUCTOR. */
1265 init_def_list (type)
1268 tree expr, initlist = NULLT;
1269 struct imp_entry *impent;
1272 for (impent = imp_list; impent; impent = impent->next)
1274 if (TREE_CODE (impent->imp_context) == CLASS_IMPLEMENTATION_TYPE)
1276 expr = build_unary_op (ADDR_EXPR, impent->class_decl, 0);
1277 initlist = tree_cons (NULLT, expr, initlist);
1282 for (impent = imp_list; impent; impent = impent->next)
1284 if (TREE_CODE (impent->imp_context) == CATEGORY_IMPLEMENTATION_TYPE)
1286 expr = build_unary_op (ADDR_EXPR, impent->class_decl, 0);
1287 initlist = tree_cons (NULLT, expr, initlist);
1290 return build_constructor (type, nreverse (initlist));
1293 /* Construct the initial value for all of _objc_symtab. */
1296 init_objc_symtab (type)
1301 /* sel_ref_cnt = { ..., 5, ... } */
1303 initlist = build_tree_list (NULLT, build_int_2 (0, 0));
1305 /* refs = { ..., _OBJC_SELECTOR_TABLE, ... } */
1307 if (flag_next_runtime || ! sel_ref_chain)
1308 initlist = tree_cons (NULLT, build_int_2 (0, 0), initlist);
1310 initlist = tree_cons (NULLT,
1311 build_unary_op (ADDR_EXPR,
1312 UOBJC_SELECTOR_TABLE_decl, 1),
1315 /* cls_def_cnt = { ..., 5, ... } */
1317 initlist = tree_cons (NULLT, build_int_2 (imp_count, 0), initlist);
1319 /* cat_def_cnt = { ..., 5, ... } */
1321 initlist = tree_cons (NULLT, build_int_2 (cat_count, 0), initlist);
1323 /* cls_def = { ..., { &Foo, &Bar, ...}, ... } */
1325 if (imp_count || cat_count)
1327 tree field = TYPE_FIELDS (type);
1328 field = TREE_CHAIN (TREE_CHAIN (TREE_CHAIN (TREE_CHAIN (field))));
1330 initlist = tree_cons (NULLT, init_def_list (TREE_TYPE (field)),
1334 return build_constructor (type, nreverse (initlist));
1337 /* Push forward-declarations of all the categories
1338 so that init_def_list can use them in a CONSTRUCTOR. */
1341 forward_declare_categories ()
1343 struct imp_entry *impent;
1344 tree sav = implementation_context;
1345 for (impent = imp_list; impent; impent = impent->next)
1347 if (TREE_CODE (impent->imp_context) == CATEGORY_IMPLEMENTATION_TYPE)
1349 /* Set an invisible arg to synth_id_with_class_suffix. */
1350 implementation_context = impent->imp_context;
1352 = create_builtin_decl (VAR_DECL, objc_category_template,
1353 IDENTIFIER_POINTER (synth_id_with_class_suffix ("_OBJC_CATEGORY", implementation_context)));
1356 implementation_context = sav;
1359 /* Create the declaration of _OBJC_SYMBOLS, with type `strict _objc_symtab'
1360 and initialized appropriately. */
1363 generate_objc_symtab_decl ()
1367 if (!objc_category_template)
1368 build_category_template ();
1370 /* forward declare categories */
1372 forward_declare_categories ();
1374 if (!objc_symtab_template)
1375 build_objc_symtab_template ();
1377 sc_spec = build_tree_list (NULLT, ridpointers[(int) RID_STATIC]);
1379 UOBJC_SYMBOLS_decl = start_decl (get_identifier ("_OBJC_SYMBOLS"),
1380 tree_cons (NULLT, objc_symtab_template, sc_spec), 1);
1382 end_temporary_allocation (); /* start_decl trying to be smart about inits */
1383 TREE_USED (UOBJC_SYMBOLS_decl) = 1;
1384 DECL_IGNORED_P (UOBJC_SYMBOLS_decl) = 1;
1385 finish_decl (UOBJC_SYMBOLS_decl,
1386 init_objc_symtab (TREE_TYPE (UOBJC_SYMBOLS_decl)),
1391 init_module_descriptor (type)
1394 tree initlist, expr;
1396 /* version = { 1, ... } */
1398 expr = build_int_2 (OBJC_VERSION, 0);
1399 initlist = build_tree_list (NULLT, expr);
1401 /* size = { ..., sizeof (struct objc_module), ... } */
1403 expr = size_in_bytes (objc_module_template);
1404 initlist = tree_cons (NULLT, expr, initlist);
1406 /* name = { ..., "foo.m", ... } */
1408 expr = add_objc_string (get_identifier (input_filename), class_names);
1409 initlist = tree_cons (NULLT, expr, initlist);
1411 /* symtab = { ..., _OBJC_SYMBOLS, ... } */
1413 if (UOBJC_SYMBOLS_decl)
1414 expr = build_unary_op (ADDR_EXPR, UOBJC_SYMBOLS_decl, 0);
1416 expr = build_int_2 (0, 0);
1417 initlist = tree_cons (NULLT, expr, initlist);
1419 return build_constructor (type, nreverse (initlist));
1422 /* Write out the data structures to describe Objective C classes defined.
1423 If appropriate, compile and output a setup function to initialize them.
1424 Return a string which is the name of a function to call to initialize
1425 the Objective C data structures for this file (and perhaps for other files
1428 struct objc_module { ... } _OBJC_MODULE = { ... };
1433 build_module_descriptor ()
1435 tree decl_specs, field_decl, field_decl_chain;
1437 objc_module_template = start_struct (RECORD_TYPE, get_identifier (UTAG_MODULE));
1441 decl_specs = build_tree_list (NULLT, ridpointers[(int) RID_LONG]);
1442 field_decl = get_identifier ("version");
1443 field_decl = grokfield (input_filename, lineno, field_decl, decl_specs, NULLT);
1444 field_decl_chain = field_decl;
1448 decl_specs = build_tree_list (NULLT, ridpointers[(int) RID_LONG]);
1449 field_decl = get_identifier ("size");
1450 field_decl = grokfield (input_filename, lineno, field_decl, decl_specs, NULLT);
1451 chainon (field_decl_chain, field_decl);
1455 decl_specs = build_tree_list (NULLT, ridpointers[(int) RID_CHAR]);
1456 field_decl = build1 (INDIRECT_REF, NULLT, get_identifier ("name"));
1457 field_decl = grokfield (input_filename, lineno, field_decl, decl_specs, NULLT);
1458 chainon (field_decl_chain, field_decl);
1460 /* struct objc_symtab *symtab; */
1462 decl_specs = get_identifier (UTAG_SYMTAB);
1463 decl_specs = build_tree_list (NULLT, xref_tag (RECORD_TYPE, decl_specs));
1464 field_decl = build1 (INDIRECT_REF, NULLT, get_identifier ("symtab"));
1465 field_decl = grokfield (input_filename, lineno, field_decl, decl_specs, NULLT);
1466 chainon (field_decl_chain, field_decl);
1468 finish_struct (objc_module_template, field_decl_chain);
1470 /* create an instance of "objc_module" */
1472 decl_specs = tree_cons (NULLT, objc_module_template,
1473 build_tree_list (NULLT, ridpointers[(int) RID_STATIC]));
1475 UOBJC_MODULES_decl = start_decl (get_identifier ("_OBJC_MODULES"),
1478 end_temporary_allocation (); /* start_decl trying to be smart about inits */
1479 DECL_IGNORED_P (UOBJC_MODULES_decl) = 1;
1480 finish_decl (UOBJC_MODULES_decl,
1481 init_module_descriptor (TREE_TYPE (UOBJC_MODULES_decl)),
1484 /* Mark the decl to avoid "defined but not used" warning. */
1485 DECL_IN_SYSTEM_HEADER (UOBJC_MODULES_decl) = 1;
1487 /* Generate a constructor call for the module descriptor.
1488 This code was generated by reading the grammar rules
1489 of c-parse.y; Therefore, it may not be the most efficient
1490 way of generating the requisite code. */
1492 if (flag_next_runtime)
1496 tree parms, function_decl, decelerator, void_list_node;
1498 extern tree get_file_function_name ();
1499 tree init_function_name = get_file_function_name ('I');
1501 /* Declare void __objc_execClass (void*); */
1503 void_list_node = build_tree_list (NULL_TREE, void_type_node);
1505 = build_function_type (void_type_node,
1506 tree_cons (NULL_TREE, ptr_type_node,
1508 function_decl = build_decl (FUNCTION_DECL,
1509 get_identifier (TAG_EXECCLASS),
1511 DECL_EXTERNAL (function_decl) = 1;
1512 TREE_PUBLIC (function_decl) = 1;
1513 pushdecl (function_decl);
1514 rest_of_decl_compilation (function_decl, 0, 0, 0);
1517 = build_tree_list (NULLT,
1518 build_unary_op (ADDR_EXPR, UOBJC_MODULES_decl, 0));
1519 decelerator = build_function_call (function_decl, parms);
1521 /* void _GLOBAL_$I$<gnyf> () {objc_execClass (&L_OBJC_MODULES);} */
1523 start_function (void_list_node,
1524 build_parse_node (CALL_EXPR, init_function_name,
1525 /* This has the format of the output
1526 of get_parm_info. */
1527 tree_cons (NULL_TREE, NULL_TREE,
1531 #if 0 /* This should be turned back on later
1532 for the systems where collect is not needed. */
1533 /* Make these functions nonglobal
1534 so each file can use the same name. */
1535 TREE_PUBLIC (current_function_decl) = 0;
1537 TREE_USED (current_function_decl) = 1;
1538 store_parm_decls ();
1540 assemble_external (function_decl);
1541 c_expand_expr_stmt (decelerator);
1543 finish_function (0);
1545 /* Return the name of the constructor function. */
1546 return IDENTIFIER_POINTER (init_function_name);
1550 /* extern const char _OBJC_STRINGS[]; */
1553 generate_forward_declaration_to_string_table ()
1555 tree sc_spec, decl_specs, expr_decl;
1557 sc_spec = tree_cons (NULLT, ridpointers[(int) RID_EXTERN], NULLT);
1558 decl_specs = tree_cons (NULLT, ridpointers[(int) RID_CHAR], sc_spec);
1560 expr_decl = build_nt (ARRAY_REF, get_identifier ("_OBJC_STRINGS"), NULLT);
1562 UOBJC_STRINGS_decl = define_decl (expr_decl, decl_specs);
1565 /* Output all strings. */
1570 tree sc_spec, decl_specs, expr_decl;
1571 tree chain, string_expr;
1574 for (chain = class_names_chain; chain; chain = TREE_CHAIN (chain))
1576 string = TREE_VALUE (chain);
1577 decl = TREE_PURPOSE (chain);
1578 sc_spec = tree_cons (NULLT, ridpointers[(int) RID_STATIC], NULLT);
1579 decl_specs = tree_cons (NULLT, ridpointers[(int) RID_CHAR], sc_spec);
1580 expr_decl = build_nt (ARRAY_REF, DECL_NAME (decl), NULLT);
1581 decl = start_decl (expr_decl, decl_specs, 1);
1582 end_temporary_allocation ();
1583 string_expr = my_build_string (IDENTIFIER_LENGTH (string) + 1,
1584 IDENTIFIER_POINTER (string));
1585 finish_decl (decl, string_expr, NULLT);
1588 for (chain = meth_var_names_chain; chain; chain = TREE_CHAIN (chain))
1590 string = TREE_VALUE (chain);
1591 decl = TREE_PURPOSE (chain);
1592 sc_spec = tree_cons (NULLT, ridpointers[(int) RID_STATIC], NULLT);
1593 decl_specs = tree_cons (NULLT, ridpointers[(int) RID_CHAR], sc_spec);
1594 expr_decl = build_nt (ARRAY_REF, DECL_NAME (decl), NULLT);
1595 decl = start_decl (expr_decl, decl_specs, 1);
1596 end_temporary_allocation ();
1597 string_expr = my_build_string (IDENTIFIER_LENGTH (string) + 1,
1598 IDENTIFIER_POINTER (string));
1599 finish_decl (decl, string_expr, NULLT);
1602 for (chain = meth_var_types_chain; chain; chain = TREE_CHAIN (chain))
1604 string = TREE_VALUE (chain);
1605 decl = TREE_PURPOSE (chain);
1606 sc_spec = tree_cons (NULLT, ridpointers[(int) RID_STATIC], NULLT);
1607 decl_specs = tree_cons (NULLT, ridpointers[(int) RID_CHAR], sc_spec);
1608 expr_decl = build_nt (ARRAY_REF, DECL_NAME (decl), NULLT);
1609 decl = start_decl (expr_decl, decl_specs, 1);
1610 end_temporary_allocation ();
1611 string_expr = my_build_string (IDENTIFIER_LENGTH (string) + 1,
1612 IDENTIFIER_POINTER (string));
1613 finish_decl (decl, string_expr, NULLT);
1618 build_selector_reference_decl (name)
1623 struct obstack *save_current_obstack = current_obstack;
1624 struct obstack *save_rtl_obstack = rtl_obstack;
1627 sprintf (buf, "_OBJC_SELECTOR_REFERENCES_%d", idx++);
1630 rtl_obstack = current_obstack = &permanent_obstack;
1631 ident = get_identifier (buf);
1633 decl = build_decl (VAR_DECL, ident, selector_type);
1634 DECL_EXTERNAL (decl) = 1;
1635 TREE_PUBLIC (decl) = 1;
1636 TREE_USED (decl) = 1;
1637 TREE_READONLY (decl) = 1;
1639 make_decl_rtl (decl, 0, 1); /* usually called from `rest_of_decl_compilation' */
1640 pushdecl_top_level (decl); /* our `extended/custom' pushdecl in c-decl.c */
1642 current_obstack = save_current_obstack;
1643 rtl_obstack = save_rtl_obstack;
1648 /* Just a handy wrapper for add_objc_string. */
1651 build_selector (ident)
1654 tree expr = add_objc_string (ident, meth_var_names);
1656 return build_c_cast (selector_type, expr); /* cast! */
1659 /* Synthesize the following expr: (char *)&_OBJC_STRINGS[<offset>]
1660 The cast stops the compiler from issuing the following message:
1661 grok.m: warning: initialization of non-const * pointer from const *
1662 grok.m: warning: initialization between incompatible pointer types. */
1665 build_msg_pool_reference (offset)
1668 tree expr = build_int_2 (offset, 0);
1671 expr = build_array_ref (UOBJC_STRINGS_decl, expr);
1672 expr = build_unary_op (ADDR_EXPR, expr, 0);
1674 cast = build_tree_list (build_tree_list (NULLT, ridpointers[(int) RID_CHAR]),
1675 build1 (INDIRECT_REF, NULLT, NULLT));
1676 TREE_TYPE (expr) = groktypename (cast);
1681 init_selector (offset)
1684 tree expr = build_msg_pool_reference (offset);
1685 TREE_TYPE (expr) = selector_type; /* cast */
1690 build_selector_translation_table ()
1692 tree sc_spec, decl_specs;
1693 tree chain, initlist = NULLT;
1695 tree decl, var_decl, name;
1697 /* The corresponding pop_obstacks is in finish_decl,
1698 called at the end of this function. */
1699 if (! flag_next_runtime)
1700 push_obstacks_nochange ();
1702 for (chain = sel_ref_chain; chain; chain = TREE_CHAIN (chain))
1706 expr = build_selector (TREE_VALUE (chain));
1708 if (flag_next_runtime)
1710 name = DECL_NAME (TREE_PURPOSE (chain));
1712 sc_spec = build_tree_list (NULLT, ridpointers[(int) RID_STATIC]);
1714 /* static SEL _OBJC_SELECTOR_REFERENCES_n = ...; */
1715 decl_specs = tree_cons (NULLT, selector_type, sc_spec);
1719 /* the `decl' that is returned from start_decl is the one that we
1720 forward declared in `build_selector_reference' */
1721 decl = start_decl (var_decl, decl_specs, 1);
1724 /* add one for the '\0' character */
1725 offset += IDENTIFIER_LENGTH (TREE_VALUE (chain)) + 1;
1727 if (flag_next_runtime)
1729 end_temporary_allocation ();
1730 finish_decl (decl, expr, NULLT);
1733 initlist = tree_cons (NULLT, expr, initlist);
1736 if (! flag_next_runtime)
1738 /* Cause the variable and its initial value to be actually output. */
1739 DECL_EXTERNAL (UOBJC_SELECTOR_TABLE_decl) = 0;
1740 TREE_STATIC (UOBJC_SELECTOR_TABLE_decl) = 1;
1741 /* NULL terminate the list and fix the decl for output. */
1742 initlist = tree_cons (NULLT, build_int_2 (0, 0), initlist);
1743 DECL_INITIAL (UOBJC_SELECTOR_TABLE_decl) = (tree) 1;
1744 initlist = build_constructor (TREE_TYPE (UOBJC_SELECTOR_TABLE_decl),
1745 nreverse (initlist));
1746 finish_decl (UOBJC_SELECTOR_TABLE_decl, initlist, NULLT);
1750 /* sel_ref_chain is a list whose "value" fields will be instances of
1751 identifier_node that represent the selector. */
1754 build_selector_reference (ident)
1757 tree *chain = &sel_ref_chain;
1763 if (TREE_VALUE (*chain) == ident)
1764 return (flag_next_runtime
1765 ? TREE_PURPOSE (*chain)
1766 : build_array_ref (UOBJC_SELECTOR_TABLE_decl,
1767 build_int_2 (index, 0)));
1770 chain = &TREE_CHAIN (*chain);
1773 decl = build_selector_reference_decl (ident);
1775 *chain = perm_tree_cons (decl, ident, NULLT);
1777 return (flag_next_runtime
1779 : build_array_ref (UOBJC_SELECTOR_TABLE_decl,
1780 build_int_2 (index, 0)));
1784 build_class_reference_decl (name)
1789 struct obstack *save_current_obstack = current_obstack;
1790 struct obstack *save_rtl_obstack = rtl_obstack;
1793 sprintf (buf, "_OBJC_CLASS_REFERENCES_%d", idx++);
1796 rtl_obstack = current_obstack = &permanent_obstack;
1797 ident = get_identifier (buf);
1799 decl = build_decl (VAR_DECL, ident, objc_class_type);
1800 DECL_EXTERNAL (decl) = 1;
1801 TREE_PUBLIC (decl) = 1;
1802 TREE_USED (decl) = 1;
1803 TREE_READONLY (decl) = 1;
1805 make_decl_rtl (decl, 0, 1); /* usually called from `rest_of_decl_compilation' */
1806 pushdecl_top_level (decl); /* our `extended/custom' pushdecl in c-decl.c */
1808 current_obstack = save_current_obstack;
1809 rtl_obstack = save_rtl_obstack;
1814 /* Create a class reference, but don't create a variable to reference
1818 add_class_reference (ident)
1823 if ((chain = cls_ref_chain))
1828 if (ident == TREE_VALUE (chain))
1832 chain = TREE_CHAIN (chain);
1836 /* append to the end of the list */
1837 TREE_CHAIN (tail) = perm_tree_cons (NULLT, ident, NULLT);
1840 cls_ref_chain = perm_tree_cons (NULLT, ident, NULLT);
1843 /* Get a class reference, creating it if necessary. Also create the
1844 reference variable. */
1847 get_class_reference (ident)
1850 if (flag_next_runtime)
1855 for (chain = &cls_ref_chain; *chain; chain = &TREE_CHAIN (*chain))
1856 if (TREE_VALUE (*chain) == ident)
1858 if (! TREE_PURPOSE (*chain))
1859 TREE_PURPOSE (*chain) = build_class_reference_decl (ident);
1860 return TREE_PURPOSE (*chain);
1863 decl = build_class_reference_decl (ident);
1864 *chain = perm_tree_cons (decl, ident, NULLT);
1871 add_class_reference (ident);
1873 params = build_tree_list (NULLT,
1874 my_build_string (IDENTIFIER_LENGTH (ident) + 1,
1875 IDENTIFIER_POINTER (ident)));
1877 assemble_external (objc_get_class_decl);
1878 return build_function_call (objc_get_class_decl, params);
1882 /* sel_refdef_chain is a list whose "value" fields will be instances
1883 of identifier_node that represent the selector. It returns the
1884 offset of the selector from the beginning of the _OBJC_STRINGS
1885 pool. This offset is typically used by init_selector during code
1888 For each string section we have a chain which maps identifier nodes
1889 to decls for the strings. */
1892 add_objc_string (ident, section)
1894 enum string_section section;
1898 if (section == class_names)
1899 chain = &class_names_chain;
1900 else if (section == meth_var_names)
1901 chain = &meth_var_names_chain;
1902 else if (section == meth_var_types)
1903 chain = &meth_var_types_chain;
1907 if (TREE_VALUE (*chain) == ident)
1908 return build_unary_op (ADDR_EXPR, TREE_PURPOSE (*chain), 1);
1910 chain = &TREE_CHAIN (*chain);
1913 decl = build_objc_string_decl (ident, section);
1915 *chain = perm_tree_cons (decl, ident, NULLT);
1917 return build_unary_op (ADDR_EXPR, decl, 1);
1921 build_objc_string_decl (name, section)
1923 enum string_section section;
1927 struct obstack *save_current_obstack = current_obstack;
1928 struct obstack *save_rtl_obstack = rtl_obstack;
1929 static int class_names_idx = 0;
1930 static int meth_var_names_idx = 0;
1931 static int meth_var_types_idx = 0;
1933 if (section == class_names)
1934 sprintf (buf, "_OBJC_CLASS_NAME_%d", class_names_idx++);
1935 else if (section == meth_var_names)
1936 sprintf (buf, "_OBJC_METH_VAR_NAME_%d", meth_var_names_idx++);
1937 else if (section == meth_var_types)
1938 sprintf (buf, "_OBJC_METH_VAR_TYPE_%d", meth_var_types_idx++);
1940 rtl_obstack = current_obstack = &permanent_obstack;
1941 ident = get_identifier (buf);
1943 decl = build_decl (VAR_DECL, ident, build_array_type (char_type_node, 0));
1944 DECL_EXTERNAL (decl) = 1;
1945 TREE_PUBLIC (decl) = 1;
1946 TREE_USED (decl) = 1;
1947 TREE_READONLY (decl) = 1;
1948 TREE_CONSTANT (decl) = 1;
1950 make_decl_rtl (decl, 0, 1); /* usually called from `rest_of_decl_compilation */
1951 pushdecl_top_level (decl); /* our `extended/custom' pushdecl in c-decl.c */
1953 current_obstack = save_current_obstack;
1954 rtl_obstack = save_rtl_obstack;
1961 objc_declare_alias (alias_ident, class_ident)
1965 if (!doing_objc_thang)
1968 if (is_class_name (class_ident) != class_ident)
1969 warning ("Cannot find class `%s'", IDENTIFIER_POINTER (class_ident));
1970 else if (is_class_name (alias_ident))
1971 warning ("Class `%s' already exists", IDENTIFIER_POINTER (alias_ident));
1973 alias_chain = tree_cons (class_ident, alias_ident, alias_chain);
1977 objc_declare_class (ident_list)
1982 if (!doing_objc_thang)
1985 for (list = ident_list; list; list = TREE_CHAIN (list))
1987 tree ident = TREE_VALUE (list);
1990 if ((decl = lookup_name (ident)))
1992 error ("`%s' redeclared as different kind of symbol",
1993 IDENTIFIER_POINTER (ident));
1994 error_with_decl (decl, "previous declaration of `%s'");
1997 if (! is_class_name (ident))
1999 tree record = xref_tag (RECORD_TYPE, ident);
2000 TREE_STATIC_TEMPLATE (record) = 1;
2001 class_chain = tree_cons (NULLT, ident, class_chain);
2007 is_class_name (ident)
2012 if (lookup_interface (ident))
2015 for (chain = class_chain; chain; chain = TREE_CHAIN (chain))
2017 if (ident == TREE_VALUE (chain))
2021 for (chain = alias_chain; chain; chain = TREE_CHAIN (chain))
2023 if (ident == TREE_VALUE (chain))
2024 return TREE_PURPOSE (chain);
2031 lookup_interface (ident)
2036 for (chain = interface_chain; chain; chain = TREE_CHAIN (chain))
2038 if (ident == CLASS_NAME (chain))
2045 objc_copy_list (list, head)
2049 tree newlist = NULL_TREE, tail = NULL_TREE;
2053 tail = copy_node (list);
2055 /* The following statement fixes a bug when inheriting instance
2056 variables that are declared to be bitfields. finish_struct
2057 expects to find the width of the bitfield in DECL_INITIAL,
2058 which it nulls out after processing the decl of the super
2059 class...rather than change the way finish_struct works (which
2060 is risky), I create the situation it expects...s.naroff
2063 if (DECL_BIT_FIELD (tail) && DECL_INITIAL (tail) == 0)
2064 DECL_INITIAL (tail) = build_int_2 (DECL_FIELD_SIZE (tail), 0);
2066 newlist = chainon (newlist, tail);
2067 list = TREE_CHAIN (list);
2073 /* Used by: build_private_template, get_class_ivars, and
2074 continue_class. COPY is 1 when called from @defs. In this case
2075 copy all fields. Otherwise don't copy leaf ivars since we rely on
2076 them being side-effected exactly once by finish_struct. */
2079 build_ivar_chain (interface, copy)
2083 tree my_name, super_name, ivar_chain;
2085 my_name = CLASS_NAME (interface);
2086 super_name = CLASS_SUPER_NAME (interface);
2088 /* Possibly copy leaf ivars. */
2090 objc_copy_list (CLASS_IVARS (interface), &ivar_chain);
2092 ivar_chain = CLASS_IVARS (interface);
2097 tree super_interface = lookup_interface (super_name);
2099 if (!super_interface)
2101 /* fatal did not work with 2 args...should fix */
2102 error ("Cannot find interface declaration for `%s', superclass of `%s'",
2103 IDENTIFIER_POINTER (super_name),
2104 IDENTIFIER_POINTER (my_name));
2107 if (super_interface == interface)
2109 fatal ("Circular inheritance in interface declaration for `%s'",
2110 IDENTIFIER_POINTER (super_name));
2112 interface = super_interface;
2113 my_name = CLASS_NAME (interface);
2114 super_name = CLASS_SUPER_NAME (interface);
2116 op1 = CLASS_IVARS (interface);
2119 tree head, tail = objc_copy_list (op1, &head);
2121 /* Prepend super class ivars...make a copy of the list, we
2122 do not want to alter the original. */
2123 TREE_CHAIN (tail) = ivar_chain;
2130 /* struct <classname> {
2131 struct objc_class *isa;
2136 build_private_template (class)
2141 if (CLASS_STATIC_TEMPLATE (class))
2143 uprivate_record = CLASS_STATIC_TEMPLATE (class);
2144 ivar_context = TYPE_FIELDS (CLASS_STATIC_TEMPLATE (class));
2148 uprivate_record = start_struct (RECORD_TYPE, CLASS_NAME (class));
2150 ivar_context = build_ivar_chain (class, 0);
2152 finish_struct (uprivate_record, ivar_context);
2154 CLASS_STATIC_TEMPLATE (class) = uprivate_record;
2156 /* mark this record as class template - for class type checking */
2157 TREE_STATIC_TEMPLATE (uprivate_record) = 1;
2159 instance_type = groktypename (build_tree_list (build_tree_list (NULLT, uprivate_record),
2160 build1 (INDIRECT_REF, NULLT, NULLT)));
2161 return ivar_context;
2164 /* Begin code generation for protocols... */
2166 /* struct objc_protocol {
2167 char *protocol_name;
2168 struct objc_protocol **protocol_list;
2169 struct objc_method_desc *instance_methods;
2170 struct objc_method_desc *class_methods;
2174 build_protocol_template ()
2176 tree decl_specs, field_decl, field_decl_chain;
2179 template = start_struct (RECORD_TYPE, get_identifier (UTAG_PROTOCOL));
2181 /* struct objc_class *isa; */
2183 decl_specs = build_tree_list (NULLT, xref_tag (RECORD_TYPE,
2184 get_identifier (UTAG_CLASS)));
2185 field_decl = build1 (INDIRECT_REF, NULLT, get_identifier ("isa"));
2186 field_decl = grokfield (input_filename, lineno, field_decl, decl_specs, NULLT);
2187 field_decl_chain = field_decl;
2189 /* char *protocol_name; */
2191 decl_specs = build_tree_list (NULLT, ridpointers[(int) RID_CHAR]);
2192 field_decl = build1 (INDIRECT_REF, NULLT, get_identifier ("protocol_name"));
2193 field_decl = grokfield (input_filename, lineno, field_decl, decl_specs, NULLT);
2194 chainon (field_decl_chain, field_decl);
2196 /* struct objc_protocol **protocol_list; */
2198 decl_specs = build_tree_list (NULLT, template);
2199 field_decl = build1 (INDIRECT_REF, NULLT, get_identifier ("protocol_list"));
2200 field_decl = build1 (INDIRECT_REF, NULLT, field_decl);
2201 field_decl = grokfield (input_filename, lineno, field_decl, decl_specs, NULLT);
2202 chainon (field_decl_chain, field_decl);
2204 /* struct objc_method_list *instance_methods; */
2206 decl_specs = build_tree_list (NULLT, xref_tag (RECORD_TYPE,
2207 get_identifier (UTAG_METHOD_PROTOTYPE_LIST)));
2208 field_decl = build1 (INDIRECT_REF, NULLT, get_identifier ("instance_methods"));
2209 field_decl = grokfield (input_filename, lineno, field_decl, decl_specs, NULLT);
2210 chainon (field_decl_chain, field_decl);
2212 /* struct objc_method_list *class_methods; */
2214 decl_specs = build_tree_list (NULLT, xref_tag (RECORD_TYPE,
2215 get_identifier (UTAG_METHOD_PROTOTYPE_LIST)));
2216 field_decl = build1 (INDIRECT_REF, NULLT, get_identifier ("class_methods"));
2217 field_decl = grokfield (input_filename, lineno, field_decl, decl_specs, NULLT);
2218 chainon (field_decl_chain, field_decl);
2220 return finish_struct (template, field_decl_chain);
2224 build_descriptor_table_initializer (type, entries)
2228 tree initlist = NULLT;
2232 tree eltlist = NULLT;
2234 eltlist = tree_cons (NULLT, build_selector (METHOD_SEL_NAME (entries)), NULLT);
2235 eltlist = tree_cons (NULLT, add_objc_string (METHOD_ENCODING (entries), meth_var_types), eltlist);
2237 initlist = tree_cons (NULLT, build_constructor (type, nreverse (eltlist)), initlist);
2239 entries = TREE_CHAIN (entries);
2243 return build_constructor (build_array_type (type, 0), nreverse (initlist));
2246 /* struct objc_method_prototype_list {
2248 struct objc_method_prototype {
2255 build_method_prototype_list_template (list_type, size)
2259 tree objc_ivar_list_record;
2260 tree decl_specs, field_decl, field_decl_chain;
2262 /* generate an unnamed struct definition */
2264 objc_ivar_list_record = start_struct (RECORD_TYPE, NULLT);
2266 /* int method_count; */
2268 decl_specs = build_tree_list (NULLT, ridpointers[(int) RID_INT]);
2269 field_decl = get_identifier ("method_count");
2271 field_decl = grokfield (input_filename, lineno, field_decl, decl_specs, NULLT);
2272 field_decl_chain = field_decl;
2274 /* struct objc_method method_list[]; */
2276 decl_specs = build_tree_list (NULLT, list_type);
2277 field_decl = build_nt (ARRAY_REF, get_identifier ("method_list"),
2278 build_int_2 (size, 0));
2280 field_decl = grokfield (input_filename, lineno, field_decl, decl_specs, NULLT);
2281 chainon (field_decl_chain, field_decl);
2283 finish_struct (objc_ivar_list_record, field_decl_chain);
2285 return objc_ivar_list_record;
2289 build_method_prototype_template ()
2292 tree decl_specs, field_decl, field_decl_chain;
2294 proto_record = start_struct (RECORD_TYPE, get_identifier (UTAG_METHOD_PROTOTYPE));
2296 #ifdef OBJC_INT_SELECTORS
2297 /* unsigned int _cmd; */
2298 decl_specs = tree_cons (NULLT, ridpointers[(int) RID_UNSIGNED], NULLT);
2299 decl_specs = tree_cons (NULLT, ridpointers[(int) RID_INT], decl_specs);
2300 field_decl = get_identifier ("_cmd");
2301 #else /* OBJC_INT_SELECTORS */
2302 /* struct objc_selector *_cmd; */
2303 decl_specs = tree_cons (NULLT, xref_tag (RECORD_TYPE,
2304 get_identifier (TAG_SELECTOR)), NULLT);
2305 field_decl = build1 (INDIRECT_REF, NULLT, get_identifier ("_cmd"));
2306 #endif /* OBJC_INT_SELECTORS */
2308 field_decl = grokfield (input_filename, lineno, field_decl, decl_specs, NULLT);
2309 field_decl_chain = field_decl;
2311 decl_specs = tree_cons (NULLT, ridpointers[(int) RID_CHAR], NULLT);
2312 field_decl = build1 (INDIRECT_REF, NULLT, get_identifier ("method_types"));
2313 field_decl = grokfield (input_filename, lineno, field_decl, decl_specs, NULLT);
2314 chainon (field_decl_chain, field_decl);
2316 finish_struct (proto_record, field_decl_chain);
2318 return proto_record;
2321 /* True if last call to forwarding_offset yielded a register offset */
2322 static int offset_is_register;
2325 forwarding_offset (parm)
2328 int offset_in_bytes;
2330 if (GET_CODE (DECL_INCOMING_RTL (parm)) == MEM)
2332 rtx addr = XEXP (DECL_INCOMING_RTL (parm), 0);
2334 /* ??? Here we assume that the parm address is indexed
2335 off the frame pointer or arg pointer.
2336 If that is not true, we produce meaningless results,
2337 but do not crash. */
2338 if (GET_CODE (addr) == PLUS
2339 && GET_CODE (XEXP (addr, 1)) == CONST_INT)
2340 offset_in_bytes = INTVAL (XEXP (addr, 1));
2342 offset_in_bytes = 0;
2344 offset_in_bytes += OBJC_FORWARDING_STACK_OFFSET;
2345 offset_is_register = 0;
2347 else if (GET_CODE (DECL_INCOMING_RTL (parm)) == REG)
2349 int regno = REGNO (DECL_INCOMING_RTL (parm));
2350 offset_in_bytes = apply_args_register_offset (regno);
2351 offset_is_register = 1;
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 (!offset_is_register && max_parm_end < 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));
2429 /* indicate register */
2430 if (offset_is_register)
2431 obstack_1grow (&util_obstack, '+');
2433 obstack_grow (&util_obstack, buf, strlen (buf));
2436 obstack_1grow (&util_obstack, '\0');
2437 result = get_identifier (obstack_finish (&util_obstack));
2438 obstack_free (&util_obstack, util_firstobj);
2443 generate_descriptor_table (type, name, size, list, proto)
2450 tree sc_spec, decl_specs, decl, initlist;
2452 sc_spec = tree_cons (NULLT, ridpointers[(int) RID_STATIC], NULLT);
2453 decl_specs = tree_cons (NULLT, type, sc_spec);
2455 decl = start_decl (synth_id_with_class_suffix (name, proto),
2457 end_temporary_allocation ();
2459 initlist = build_tree_list (NULLT, build_int_2 (size, 0));
2460 initlist = tree_cons (NULLT, list, initlist);
2462 finish_decl (decl, build_constructor (type, nreverse (initlist)),
2469 generate_method_descriptors (protocol) /* generate_dispatch_tables */
2472 static tree objc_method_prototype_template;
2473 tree initlist, chain, method_list_template;
2474 tree cast, variable_length_type;
2477 if (!objc_method_prototype_template)
2478 objc_method_prototype_template = build_method_prototype_template ();
2480 cast = build_tree_list (build_tree_list (NULLT, xref_tag (RECORD_TYPE,
2481 get_identifier (UTAG_METHOD_PROTOTYPE_LIST))), NULLT);
2482 variable_length_type = groktypename (cast);
2484 chain = PROTOCOL_CLS_METHODS (protocol);
2487 size = list_length (chain);
2489 method_list_template
2490 = build_method_prototype_list_template (objc_method_prototype_template,
2494 = build_descriptor_table_initializer (objc_method_prototype_template,
2497 UOBJC_CLASS_METHODS_decl
2498 = generate_descriptor_table (method_list_template,
2499 "_OBJC_PROTOCOL_CLASS_METHODS",
2500 size, initlist, protocol);
2502 TREE_TYPE (UOBJC_CLASS_METHODS_decl) = variable_length_type;
2505 UOBJC_CLASS_METHODS_decl = 0;
2507 chain = PROTOCOL_NST_METHODS (protocol);
2510 size = list_length (chain);
2512 method_list_template
2513 = build_method_prototype_list_template (objc_method_prototype_template,
2516 = build_descriptor_table_initializer (objc_method_prototype_template,
2519 UOBJC_INSTANCE_METHODS_decl
2520 = generate_descriptor_table (method_list_template,
2521 "_OBJC_PROTOCOL_INSTANCE_METHODS",
2522 size, initlist, protocol);
2524 TREE_TYPE (UOBJC_INSTANCE_METHODS_decl) = variable_length_type;
2527 UOBJC_INSTANCE_METHODS_decl = 0;
2531 build_tmp_function_decl ()
2533 tree decl_specs, expr_decl, parms;
2535 /* struct objc_object *objc_xxx (id, SEL, ...); */
2537 decl_specs = build_tree_list (NULLT, objc_object_reference);
2538 push_parm_decl (build_tree_list (decl_specs,
2539 build1 (INDIRECT_REF, NULLT, NULLT)));
2541 decl_specs = build_tree_list (NULLT, xref_tag (RECORD_TYPE,
2542 get_identifier (TAG_SELECTOR)));
2543 expr_decl = build1 (INDIRECT_REF, NULLT, NULLT);
2545 push_parm_decl (build_tree_list (decl_specs, expr_decl));
2546 parms = get_parm_info (0);
2549 decl_specs = build_tree_list (NULLT, objc_object_reference);
2550 expr_decl = build_nt (CALL_EXPR, get_identifier ("objc_xxx"), parms, NULLT);
2551 expr_decl = build1 (INDIRECT_REF, NULLT, expr_decl);
2553 return define_decl (expr_decl, decl_specs);
2557 hack_method_prototype (nst_methods, tmp_decl)
2563 /* Hack to avoid problem with static typing of self arg. */
2564 TREE_SET_CODE (nst_methods, CLASS_METHOD_DECL);
2565 start_method_def (nst_methods);
2566 TREE_SET_CODE (nst_methods, INSTANCE_METHOD_DECL);
2568 if (METHOD_ADD_ARGS (nst_methods) == (tree) 1)
2569 parms = get_parm_info (0); /* we have a `, ...' */
2571 parms = get_parm_info (1); /* place a `void_at_end' */
2573 poplevel (0, 0, 0); /* Must be called BEFORE start_function. */
2575 /* Usually called from store_parm_decls -> init_function_start. */
2577 init_emit (); /* needed to make assign_parms work (with -O). */
2579 DECL_ARGUMENTS (tmp_decl) = TREE_PURPOSE (parms);
2582 /* Code taken from start_function. */
2583 tree restype = TREE_TYPE (TREE_TYPE (tmp_decl));
2584 /* Promote the value to int before returning it. */
2585 if (TREE_CODE (restype) == INTEGER_TYPE
2586 && TYPE_PRECISION (restype) < TYPE_PRECISION (integer_type_node))
2587 restype = integer_type_node;
2588 DECL_RESULT (tmp_decl) = build_decl (RESULT_DECL, 0, restype);
2591 /* Typically called from expand_function_start for function definitions. */
2592 assign_parms (tmp_decl, 0);
2594 /* install return type */
2595 TREE_TYPE (TREE_TYPE (tmp_decl)) = groktypename (TREE_TYPE (nst_methods));
2599 generate_protocol_references (plist)
2604 /* forward declare protocols referenced */
2605 for (lproto = plist; lproto; lproto = TREE_CHAIN (lproto))
2607 tree proto = TREE_VALUE (lproto);
2609 if (TREE_CODE (proto) == PROTOCOL_INTERFACE_TYPE
2610 && PROTOCOL_NAME (proto))
2612 if (! PROTOCOL_FORWARD_DECL (proto))
2613 build_protocol_reference (proto);
2615 if (PROTOCOL_LIST (proto))
2616 generate_protocol_references (PROTOCOL_LIST (proto));
2622 generate_protocols ()
2624 tree p, tmp_decl, encoding;
2625 tree sc_spec, decl_specs, decl;
2626 tree initlist, protocol_name_expr, refs_decl, refs_expr;
2627 tree cast_type2 = 0;
2629 tmp_decl = build_tmp_function_decl ();
2631 if (! objc_protocol_template)
2632 objc_protocol_template = build_protocol_template ();
2634 /* if a protocol was directly referenced, pull in indirect references */
2635 for (p = protocol_chain; p; p = TREE_CHAIN (p))
2636 if (PROTOCOL_FORWARD_DECL (p) && PROTOCOL_LIST (p))
2637 generate_protocol_references (PROTOCOL_LIST (p));
2639 for (p = protocol_chain; p; p = TREE_CHAIN (p))
2641 tree nst_methods = PROTOCOL_NST_METHODS (p);
2642 tree cls_methods = PROTOCOL_CLS_METHODS (p);
2644 /* if protocol wasn't referenced, don't generate any code */
2645 if (! PROTOCOL_FORWARD_DECL (p))
2648 /* Make sure we link in the Protocol class. */
2649 add_class_reference (get_identifier (PROTOCOL_OBJECT_CLASS_NAME));
2653 hack_method_prototype (nst_methods, tmp_decl);
2654 encoding = encode_method_prototype (nst_methods, tmp_decl);
2655 METHOD_ENCODING (nst_methods) = encoding;
2657 nst_methods = TREE_CHAIN (nst_methods);
2662 hack_method_prototype (cls_methods, tmp_decl);
2663 encoding = encode_method_prototype (cls_methods, tmp_decl);
2664 METHOD_ENCODING (cls_methods) = encoding;
2666 cls_methods = TREE_CHAIN (cls_methods);
2668 generate_method_descriptors (p);
2670 if (PROTOCOL_LIST (p))
2671 refs_decl = generate_protocol_list (p);
2675 /* static struct objc_protocol _OBJC_PROTOCOL_<mumble>; */
2677 sc_spec = tree_cons (NULLT, ridpointers[(int) RID_STATIC], NULLT);
2678 decl_specs = tree_cons (NULLT, objc_protocol_template, sc_spec);
2680 decl = start_decl (synth_id_with_class_suffix ("_OBJC_PROTOCOL", p),
2682 end_temporary_allocation ();
2684 protocol_name_expr = add_objc_string (PROTOCOL_NAME (p), class_names);
2690 = groktypename (build_tree_list (build_tree_list (NULLT, objc_protocol_template),
2691 build1 (INDIRECT_REF, NULLT,
2692 build1 (INDIRECT_REF, NULLT, NULLT))));
2694 refs_expr = build_unary_op (ADDR_EXPR, refs_decl, 0);
2695 TREE_TYPE (refs_expr) = cast_type2;
2698 refs_expr = build_int_2 (0, 0);
2700 /* UOBJC_INSTANCE_METHODS_decl/UOBJC_CLASS_METHODS_decl are set
2701 by generate_method_descriptors, which is called above. */
2702 initlist = build_protocol_initializer (TREE_TYPE (decl),
2703 protocol_name_expr, refs_expr,
2704 UOBJC_INSTANCE_METHODS_decl,
2705 UOBJC_CLASS_METHODS_decl);
2706 finish_decl (decl, initlist, NULLT);
2708 /* Mark the decl as used to avoid "defined but not used" warning. */
2709 TREE_USED (decl) = 1;
2714 build_protocol_initializer (type, protocol_name, protocol_list,
2715 instance_methods, class_methods)
2719 tree instance_methods;
2722 tree initlist = NULLT, expr;
2723 static tree cast_type = 0;
2727 = groktypename (build_tree_list
2728 (build_tree_list (NULLT,
2729 xref_tag (RECORD_TYPE,
2730 get_identifier (UTAG_CLASS))),
2731 build1 (INDIRECT_REF, NULLT, NULLT)));
2733 /* filling the "isa" in with one allows the runtime system to
2734 detect that the version change...should remove before final release */
2736 expr = build_int_2 (PROTOCOL_VERSION, 0);
2737 TREE_TYPE (expr) = cast_type;
2738 initlist = tree_cons (NULLT, expr, initlist);
2739 initlist = tree_cons (NULLT, protocol_name, initlist);
2740 initlist = tree_cons (NULLT, protocol_list, initlist);
2742 if (!instance_methods)
2743 initlist = tree_cons (NULLT, build_int_2 (0, 0), initlist);
2746 expr = build_unary_op (ADDR_EXPR, instance_methods, 0);
2747 initlist = tree_cons (NULLT, expr, initlist);
2750 initlist = tree_cons (NULLT, build_int_2 (0, 0), initlist);
2753 expr = build_unary_op (ADDR_EXPR, class_methods, 0);
2754 initlist = tree_cons (NULLT, expr, initlist);
2756 return build_constructor (type, nreverse (initlist));
2758 /* end code generation for protocols... */
2760 /* struct objc_category {
2761 char *category_name;
2763 struct objc_method_list *instance_methods;
2764 struct objc_method_list *class_methods;
2765 struct objc_protocol_list *protocols;
2769 build_category_template ()
2771 tree decl_specs, field_decl, field_decl_chain;
2773 objc_category_template = start_struct (RECORD_TYPE,
2774 get_identifier (UTAG_CATEGORY));
2775 /* char *category_name; */
2777 decl_specs = build_tree_list (NULLT, ridpointers[(int) RID_CHAR]);
2778 field_decl = build1 (INDIRECT_REF, NULLT, get_identifier ("category_name"));
2779 field_decl = grokfield (input_filename, lineno, field_decl, decl_specs, NULLT);
2780 field_decl_chain = field_decl;
2782 /* char *class_name; */
2784 decl_specs = build_tree_list (NULLT, ridpointers[(int) RID_CHAR]);
2785 field_decl = build1 (INDIRECT_REF, NULLT, get_identifier ("class_name"));
2786 field_decl = grokfield (input_filename, lineno, field_decl, decl_specs, NULLT);
2787 chainon (field_decl_chain, field_decl);
2789 /* struct objc_method_list *instance_methods; */
2791 decl_specs = build_tree_list (NULLT, xref_tag (RECORD_TYPE,
2792 get_identifier (UTAG_METHOD_LIST)));
2793 field_decl = build1 (INDIRECT_REF, NULLT, get_identifier ("instance_methods"));
2794 field_decl = grokfield (input_filename, lineno, field_decl, decl_specs, NULLT);
2795 chainon (field_decl_chain, field_decl);
2797 /* struct objc_method_list *class_methods; */
2799 decl_specs = build_tree_list (NULLT, xref_tag (RECORD_TYPE,
2800 get_identifier (UTAG_METHOD_LIST)));
2801 field_decl = build1 (INDIRECT_REF, NULLT, get_identifier ("class_methods"));
2802 field_decl = grokfield (input_filename, lineno, field_decl, decl_specs, NULLT);
2803 chainon (field_decl_chain, field_decl);
2805 /* struct objc_protocol **protocol_list; */
2807 decl_specs = build_tree_list (NULLT, xref_tag (RECORD_TYPE,
2808 get_identifier (UTAG_PROTOCOL)));
2809 field_decl = build1 (INDIRECT_REF, NULLT, get_identifier ("protocol_list"));
2810 field_decl = build1 (INDIRECT_REF, NULLT, field_decl);
2811 field_decl = grokfield (input_filename, lineno, field_decl, decl_specs, NULLT)
2813 chainon (field_decl_chain, field_decl);
2815 finish_struct (objc_category_template, field_decl_chain);
2818 /* struct objc_class {
2819 struct objc_class *isa;
2820 struct objc_class *super_class;
2825 struct objc_ivar_list *ivars;
2826 struct objc_method_list *methods;
2827 if (flag_next_runtime)
2828 struct objc_cache *cache;
2830 struct sarray *dtable;
2831 struct objc_class *subclass_list;
2832 struct objc_class *sibling_class;
2834 struct objc_protocol_list *protocols;
2838 build_class_template ()
2840 tree decl_specs, field_decl, field_decl_chain;
2842 objc_class_template = start_struct (RECORD_TYPE, get_identifier (UTAG_CLASS));
2844 /* struct objc_class *isa; */
2846 decl_specs = build_tree_list (NULLT, objc_class_template);
2847 field_decl = build1 (INDIRECT_REF, NULLT, get_identifier ("isa"));
2848 field_decl = grokfield (input_filename, lineno, field_decl, decl_specs, NULLT);
2849 field_decl_chain = field_decl;
2851 /* struct objc_class *super_class; */
2853 decl_specs = build_tree_list (NULLT, objc_class_template);
2854 field_decl = build1 (INDIRECT_REF, NULLT, get_identifier ("super_class"));
2855 field_decl = grokfield (input_filename, lineno, field_decl, decl_specs, NULLT);
2856 chainon (field_decl_chain, field_decl);
2860 decl_specs = build_tree_list (NULLT, ridpointers[(int) RID_CHAR]);
2861 field_decl = build1 (INDIRECT_REF, NULLT, get_identifier ("name"));
2862 field_decl = grokfield (input_filename, lineno, field_decl, decl_specs, NULLT);
2863 chainon (field_decl_chain, field_decl);
2867 decl_specs = build_tree_list (NULLT, ridpointers[(int) RID_LONG]);
2868 field_decl = get_identifier ("version");
2869 field_decl = grokfield (input_filename, lineno, field_decl, decl_specs, NULLT);
2870 chainon (field_decl_chain, field_decl);
2874 decl_specs = build_tree_list (NULLT, ridpointers[(int) RID_LONG]);
2875 field_decl = get_identifier ("info");
2876 field_decl = grokfield (input_filename, lineno, field_decl, decl_specs, NULLT);
2877 chainon (field_decl_chain, field_decl);
2879 /* long instance_size; */
2881 decl_specs = build_tree_list (NULLT, ridpointers[(int) RID_LONG]);
2882 field_decl = get_identifier ("instance_size");
2883 field_decl = grokfield (input_filename, lineno, field_decl, decl_specs, NULLT);
2884 chainon (field_decl_chain, field_decl);
2886 /* struct objc_ivar_list *ivars; */
2888 decl_specs = build_tree_list (NULLT, xref_tag (RECORD_TYPE,
2889 get_identifier (UTAG_IVAR_LIST)));
2890 field_decl = build1 (INDIRECT_REF, NULLT, get_identifier ("ivars"));
2891 field_decl = grokfield (input_filename, lineno, field_decl, decl_specs, NULLT);
2892 chainon (field_decl_chain, field_decl);
2894 /* struct objc_method_list *methods; */
2896 decl_specs = build_tree_list (NULLT, xref_tag (RECORD_TYPE,
2897 get_identifier (UTAG_METHOD_LIST)));
2898 field_decl = build1 (INDIRECT_REF, NULLT, get_identifier ("methods"));
2899 field_decl = grokfield (input_filename, lineno, field_decl, decl_specs, NULLT);
2900 chainon (field_decl_chain, field_decl);
2902 if (flag_next_runtime)
2904 /* struct objc_cache *cache; */
2906 decl_specs = build_tree_list (NULLT, xref_tag (RECORD_TYPE,
2907 get_identifier ("objc_cache")));
2908 field_decl = build1 (INDIRECT_REF, NULLT, get_identifier ("cache"));
2909 field_decl = grokfield (input_filename, lineno, field_decl, decl_specs, NULLT);
2910 chainon (field_decl_chain, field_decl);
2914 /* struct sarray *dtable; */
2916 decl_specs = build_tree_list (NULLT, xref_tag (RECORD_TYPE,
2917 get_identifier ("sarray")));
2918 field_decl = build1 (INDIRECT_REF, NULLT, get_identifier ("dtable"));
2919 field_decl = grokfield (input_filename, lineno, field_decl, decl_specs, NULLT);
2920 chainon (field_decl_chain, field_decl);
2922 /* struct objc_class *subclass_list; */
2924 decl_specs = build_tree_list (NULLT, objc_class_template);
2925 field_decl = build1 (INDIRECT_REF, NULLT, get_identifier ("subclass_list"));
2926 field_decl = grokfield (input_filename, lineno, field_decl, decl_specs, NULLT);
2927 chainon (field_decl_chain, field_decl);
2929 /* struct objc_class *sibling_class; */
2931 decl_specs = build_tree_list (NULLT, objc_class_template);
2932 field_decl = build1 (INDIRECT_REF, NULLT, get_identifier ("sibling_class"));
2933 field_decl = grokfield (input_filename, lineno, field_decl, decl_specs, NULLT);
2934 chainon (field_decl_chain, field_decl);
2937 /* struct objc_protocol **protocol_list; */
2939 decl_specs = build_tree_list (NULLT, xref_tag (RECORD_TYPE,
2940 get_identifier (UTAG_PROTOCOL)));
2941 field_decl = build1 (INDIRECT_REF, NULLT, get_identifier ("protocol_list"));
2942 field_decl = build1 (INDIRECT_REF, NULLT, field_decl);
2943 field_decl = grokfield (input_filename, lineno, field_decl, decl_specs, NULLT);
2944 chainon (field_decl_chain, field_decl);
2947 finish_struct (objc_class_template, field_decl_chain);
2950 /* Generate appropriate forward declarations for an implementation. */
2953 synth_forward_declarations ()
2955 tree sc_spec, decl_specs, an_id;
2957 /* extern struct objc_class _OBJC_CLASS_<my_name>; */
2959 an_id = synth_id_with_class_suffix ("_OBJC_CLASS", implementation_context);
2961 sc_spec = build_tree_list (NULLT, ridpointers[(int) RID_EXTERN]);
2962 decl_specs = tree_cons (NULLT, objc_class_template, sc_spec);
2963 UOBJC_CLASS_decl = define_decl (an_id, decl_specs);
2964 TREE_USED (UOBJC_CLASS_decl) = 1;
2966 /* extern struct objc_class _OBJC_METACLASS_<my_name>; */
2968 an_id = synth_id_with_class_suffix ("_OBJC_METACLASS",
2969 implementation_context);
2971 UOBJC_METACLASS_decl = define_decl (an_id, decl_specs);
2972 TREE_USED (UOBJC_METACLASS_decl) = 1;
2974 /* pre-build the following entities - for speed/convenience. */
2976 an_id = get_identifier ("super_class");
2977 ucls_super_ref = build_component_ref (UOBJC_CLASS_decl, an_id);
2978 uucls_super_ref = build_component_ref (UOBJC_METACLASS_decl, an_id);
2982 error_with_ivar (message, decl, rawdecl)
2989 report_error_function (DECL_SOURCE_FILE (decl));
2991 fprintf (stderr, "%s:%d: ",
2992 DECL_SOURCE_FILE (decl), DECL_SOURCE_LINE (decl));
2993 bzero (errbuf, BUFSIZE);
2994 fprintf (stderr, "%s `%s'\n", message, gen_declaration (rawdecl, errbuf));
2997 #define USERTYPE(t) (TREE_CODE (t) == RECORD_TYPE || \
2998 TREE_CODE (t) == UNION_TYPE || \
2999 TREE_CODE (t) == ENUMERAL_TYPE)
3002 check_ivars (inter, imp)
3006 tree intdecls = CLASS_IVARS (inter);
3007 tree impdecls = CLASS_IVARS (imp);
3008 tree rawintdecls = CLASS_RAW_IVARS (inter);
3009 tree rawimpdecls = CLASS_RAW_IVARS (imp);
3015 if (intdecls == 0 && impdecls == 0)
3017 if (intdecls == 0 || impdecls == 0)
3019 error ("inconsistent instance variable specification");
3022 t1 = TREE_TYPE (intdecls); t2 = TREE_TYPE (impdecls);
3024 if (!comptypes (t1, t2))
3026 if (DECL_NAME (intdecls) == DECL_NAME (impdecls))
3028 error_with_ivar ("conflicting instance variable type",
3029 impdecls, rawimpdecls);
3030 error_with_ivar ("previous declaration of",
3031 intdecls, rawintdecls);
3033 else /* both the type and the name don't match */
3035 error ("inconsistent instance variable specification");
3039 else if (DECL_NAME (intdecls) != DECL_NAME (impdecls))
3041 error_with_ivar ("conflicting instance variable name",
3042 impdecls, rawimpdecls);
3043 error_with_ivar ("previous declaration of",
3044 intdecls, rawintdecls);
3046 intdecls = TREE_CHAIN (intdecls);
3047 impdecls = TREE_CHAIN (impdecls);
3048 rawintdecls = TREE_CHAIN (rawintdecls);
3049 rawimpdecls = TREE_CHAIN (rawimpdecls);
3053 /* Set super_type to the data type node for struct objc_super *,
3054 first defining struct objc_super itself.
3055 This needs to be done just once per compilation. */
3058 build_super_template ()
3060 tree record, decl_specs, field_decl, field_decl_chain;
3062 record = start_struct (RECORD_TYPE, get_identifier (UTAG_SUPER));
3064 /* struct objc_object *self; */
3066 decl_specs = build_tree_list (NULLT, objc_object_reference);
3067 field_decl = get_identifier ("self");
3068 field_decl = build1 (INDIRECT_REF, NULLT, field_decl);
3069 field_decl = grokfield (input_filename, lineno,
3070 field_decl, decl_specs, NULLT);
3071 field_decl_chain = field_decl;
3073 /* struct objc_class *class; */
3075 decl_specs = get_identifier (UTAG_CLASS);
3076 decl_specs = build_tree_list (NULLT, xref_tag (RECORD_TYPE, decl_specs));
3077 field_decl = build1 (INDIRECT_REF, NULLT, get_identifier ("class"));
3079 field_decl = grokfield (input_filename, lineno,
3080 field_decl, decl_specs, NULLT);
3081 chainon (field_decl_chain, field_decl);
3083 finish_struct (record, field_decl_chain);
3085 /* `struct objc_super *' */
3086 super_type = groktypename (build_tree_list (build_tree_list (NULLT, record),
3087 build1 (INDIRECT_REF,
3092 /* struct objc_ivar {
3099 build_ivar_template ()
3101 tree objc_ivar_id, objc_ivar_record;
3102 tree decl_specs, field_decl, field_decl_chain;
3104 objc_ivar_id = get_identifier (UTAG_IVAR);
3105 objc_ivar_record = start_struct (RECORD_TYPE, objc_ivar_id);
3107 /* char *ivar_name; */
3109 decl_specs = build_tree_list (NULLT, ridpointers[(int) RID_CHAR]);
3110 field_decl = build1 (INDIRECT_REF, NULLT, get_identifier ("ivar_name"));
3112 field_decl = grokfield (input_filename, lineno, field_decl,
3114 field_decl_chain = field_decl;
3116 /* char *ivar_type; */
3118 decl_specs = build_tree_list (NULLT, ridpointers[(int) RID_CHAR]);
3119 field_decl = build1 (INDIRECT_REF, NULLT, get_identifier ("ivar_type"));
3121 field_decl = grokfield (input_filename, lineno, field_decl,
3123 chainon (field_decl_chain, field_decl);
3125 /* int ivar_offset; */
3127 decl_specs = build_tree_list (NULLT, ridpointers[(int) RID_INT]);
3128 field_decl = get_identifier ("ivar_offset");
3130 field_decl = grokfield (input_filename, lineno, field_decl,
3132 chainon (field_decl_chain, field_decl);
3134 finish_struct (objc_ivar_record, field_decl_chain);
3136 return objc_ivar_record;
3141 struct objc_ivar ivar_list[ivar_count];
3145 build_ivar_list_template (list_type, size)
3149 tree objc_ivar_list_record;
3150 tree decl_specs, field_decl, field_decl_chain;
3152 objc_ivar_list_record = start_struct (RECORD_TYPE, NULLT);
3154 /* int ivar_count; */
3156 decl_specs = build_tree_list (NULLT, ridpointers[(int) RID_INT]);
3157 field_decl = get_identifier ("ivar_count");
3159 field_decl = grokfield (input_filename, lineno, field_decl,
3161 field_decl_chain = field_decl;
3163 /* struct objc_ivar ivar_list[]; */
3165 decl_specs = build_tree_list (NULLT, list_type);
3166 field_decl = build_nt (ARRAY_REF, get_identifier ("ivar_list"),
3167 build_int_2 (size, 0));
3169 field_decl = grokfield (input_filename, lineno,
3170 field_decl, decl_specs, NULLT);
3171 chainon (field_decl_chain, field_decl);
3173 finish_struct (objc_ivar_list_record, field_decl_chain);
3175 return objc_ivar_list_record;
3181 struct objc_method method_list[method_count];
3185 build_method_list_template (list_type, size)
3189 tree objc_ivar_list_record;
3190 tree decl_specs, field_decl, field_decl_chain;
3192 objc_ivar_list_record = start_struct (RECORD_TYPE, NULLT);
3194 /* int method_next; */
3196 decl_specs = build_tree_list (NULLT, ridpointers[(int) RID_INT]);
3197 field_decl = get_identifier ("method_next");
3199 field_decl = grokfield (input_filename, lineno, field_decl, decl_specs, NULLT);
3200 field_decl_chain = field_decl;
3202 /* int method_count; */
3204 decl_specs = build_tree_list (NULLT, ridpointers[(int) RID_INT]);
3205 field_decl = get_identifier ("method_count");
3207 field_decl = grokfield (input_filename, lineno,
3208 field_decl, decl_specs, NULLT);
3209 chainon (field_decl_chain, field_decl);
3211 /* struct objc_method method_list[]; */
3213 decl_specs = build_tree_list (NULLT, list_type);
3214 field_decl = build_nt (ARRAY_REF, get_identifier ("method_list"),
3215 build_int_2 (size, 0));
3217 field_decl = grokfield (input_filename, lineno,
3218 field_decl, decl_specs, NULLT);
3219 chainon (field_decl_chain, field_decl);
3221 finish_struct (objc_ivar_list_record, field_decl_chain);
3223 return objc_ivar_list_record;
3227 build_ivar_list_initializer (type, field_decl)
3231 tree initlist = NULLT;
3238 if (DECL_NAME (field_decl))
3239 ivar = tree_cons (NULLT,
3240 add_objc_string (DECL_NAME (field_decl),
3244 /* unnamed bit-field ivar (yuck). */
3245 ivar = tree_cons (NULLT, build_int_2 (0, 0), ivar);
3248 encode_field_decl (field_decl,
3249 obstack_object_size (&util_obstack),
3250 OBJC_ENCODE_DONT_INLINE_DEFS);
3251 obstack_1grow (&util_obstack, 0); /* null terminate string */
3255 add_objc_string (get_identifier (obstack_finish (&util_obstack)),
3258 obstack_free (&util_obstack, util_firstobj);
3264 build_int_2 ((TREE_INT_CST_LOW (DECL_FIELD_BITPOS (field_decl))
3269 initlist = tree_cons (NULLT,
3270 build_constructor (type, nreverse (ivar)),
3273 field_decl = TREE_CHAIN (field_decl);
3277 return build_constructor (build_array_type (type, 0), nreverse (initlist));
3281 generate_ivars_list (type, name, size, list)
3287 tree sc_spec, decl_specs, decl, initlist;
3289 sc_spec = tree_cons (NULLT, ridpointers[(int) RID_STATIC], NULLT);
3290 decl_specs = tree_cons (NULLT, type, sc_spec);
3292 decl = start_decl (synth_id_with_class_suffix (name, implementation_context),
3294 end_temporary_allocation ();
3296 initlist = build_tree_list (NULLT, build_int_2 (size, 0));
3297 initlist = tree_cons (NULLT, list, initlist);
3300 build_constructor (TREE_TYPE (decl), nreverse (initlist)),
3307 generate_ivar_lists ()
3309 tree initlist, ivar_list_template, chain;
3310 tree cast, variable_length_type;
3313 generating_instance_variables = 1;
3315 if (!objc_ivar_template)
3316 objc_ivar_template = build_ivar_template ();
3320 (build_tree_list (NULLT, xref_tag (RECORD_TYPE,
3321 get_identifier (UTAG_IVAR_LIST))),
3323 variable_length_type = groktypename (cast);
3325 /* only generate class variables for the root of the inheritance
3326 hierarchy since these will be the same for every class */
3328 if (CLASS_SUPER_NAME (implementation_template) == NULLT
3329 && (chain = TYPE_FIELDS (objc_class_template)))
3331 size = list_length (chain);
3333 ivar_list_template = build_ivar_list_template (objc_ivar_template, size);
3334 initlist = build_ivar_list_initializer (objc_ivar_template, chain);
3336 UOBJC_CLASS_VARIABLES_decl
3337 = generate_ivars_list (ivar_list_template, "_OBJC_CLASS_VARIABLES",
3340 TREE_TYPE (UOBJC_CLASS_VARIABLES_decl) = variable_length_type;
3343 UOBJC_CLASS_VARIABLES_decl = 0;
3345 chain = CLASS_IVARS (implementation_template);
3348 size = list_length (chain);
3349 ivar_list_template = build_ivar_list_template (objc_ivar_template, size);
3350 initlist = build_ivar_list_initializer (objc_ivar_template, chain);
3352 UOBJC_INSTANCE_VARIABLES_decl
3353 = generate_ivars_list (ivar_list_template, "_OBJC_INSTANCE_VARIABLES",
3356 TREE_TYPE (UOBJC_INSTANCE_VARIABLES_decl) = variable_length_type;
3359 UOBJC_INSTANCE_VARIABLES_decl = 0;
3361 generating_instance_variables = 0;
3365 build_dispatch_table_initializer (type, entries)
3369 tree initlist = NULLT;
3373 tree elemlist = NULLT;
3375 elemlist = tree_cons (NULLT, build_selector (METHOD_SEL_NAME (entries)),
3378 elemlist = tree_cons (NULLT, add_objc_string (METHOD_ENCODING (entries),
3382 elemlist = tree_cons (NULLT,
3383 build_unary_op (ADDR_EXPR, METHOD_DEFINITION (entries), 1),
3386 initlist = tree_cons (NULLT,
3387 build_constructor (type, nreverse (elemlist)),
3390 entries = TREE_CHAIN (entries);
3394 return build_constructor (build_array_type (type, 0), nreverse (initlist));
3397 /* To accomplish method prototyping without generating all kinds of
3398 inane warnings, the definition of the dispatch table entries were
3401 struct objc_method { SEL _cmd; ...; id (*_imp)(); };
3403 struct objc_method { SEL _cmd; ...; void *_imp; }; */
3406 build_method_template ()
3409 tree decl_specs, field_decl, field_decl_chain;
3411 _SLT_record = start_struct (RECORD_TYPE, get_identifier (UTAG_METHOD));
3413 #ifdef OBJC_INT_SELECTORS
3414 /* unsigned int _cmd; */
3415 decl_specs = tree_cons (NULLT, ridpointers[(int) RID_UNSIGNED], NULLT);
3416 decl_specs = tree_cons (NULLT, ridpointers[(int) RID_INT], decl_specs);
3417 field_decl = get_identifier ("_cmd");
3418 #else /* not OBJC_INT_SELECTORS */
3419 /* struct objc_selector *_cmd; */
3420 decl_specs = tree_cons (NULLT,
3421 xref_tag (RECORD_TYPE,
3422 get_identifier (TAG_SELECTOR)),
3424 field_decl = build1 (INDIRECT_REF, NULLT, get_identifier ("_cmd"));
3425 #endif /* not OBJC_INT_SELECTORS */
3427 field_decl = grokfield (input_filename, lineno, field_decl, decl_specs, NULLT);
3428 field_decl_chain = field_decl;
3430 decl_specs = tree_cons (NULLT, ridpointers[(int) RID_CHAR], NULLT);
3431 field_decl = build1 (INDIRECT_REF, NULLT, get_identifier ("method_types"));
3432 field_decl = grokfield (input_filename, lineno, field_decl, decl_specs, NULLT);
3433 chainon (field_decl_chain, field_decl);
3437 decl_specs = tree_cons (NULLT, ridpointers[(int) RID_VOID], NULLT);
3438 field_decl = build1 (INDIRECT_REF, NULLT, get_identifier ("_imp"));
3439 field_decl = grokfield (input_filename, lineno, field_decl, decl_specs, NULLT);
3440 chainon (field_decl_chain, field_decl);
3442 finish_struct (_SLT_record, field_decl_chain);
3449 generate_dispatch_table (type, name, size, list)
3455 tree sc_spec, decl_specs, decl, initlist;
3457 sc_spec = tree_cons (NULLT, ridpointers[(int) RID_STATIC], NULLT);
3458 decl_specs = tree_cons (NULLT, type, sc_spec);
3460 decl = start_decl (synth_id_with_class_suffix (name, implementation_context),
3462 end_temporary_allocation ();
3464 initlist = build_tree_list (NULLT, build_int_2 (0, 0));
3465 initlist = tree_cons (NULLT, build_int_2 (size, 0), initlist);
3466 initlist = tree_cons (NULLT, list, initlist);
3469 build_constructor (TREE_TYPE (decl), nreverse (initlist)),
3476 generate_dispatch_tables ()
3478 tree initlist, chain, method_list_template;
3479 tree cast, variable_length_type;
3482 if (!objc_method_template)
3483 objc_method_template = build_method_template ();
3487 (build_tree_list (NULLT, xref_tag (RECORD_TYPE,
3488 get_identifier (UTAG_METHOD_LIST))),
3490 variable_length_type = groktypename (cast);
3492 chain = CLASS_CLS_METHODS (implementation_context);
3495 size = list_length (chain);
3497 method_list_template = build_method_list_template (objc_method_template, size);
3498 initlist = build_dispatch_table_initializer (objc_method_template, chain);
3500 UOBJC_CLASS_METHODS_decl
3501 = generate_dispatch_table (method_list_template,
3502 ((TREE_CODE (implementation_context)
3503 == CLASS_IMPLEMENTATION_TYPE)
3504 ? "_OBJC_CLASS_METHODS"
3505 : "_OBJC_CATEGORY_CLASS_METHODS"),
3508 TREE_TYPE (UOBJC_CLASS_METHODS_decl) = variable_length_type;
3511 UOBJC_CLASS_METHODS_decl = 0;
3513 chain = CLASS_NST_METHODS (implementation_context);
3516 size = list_length (chain);
3518 method_list_template = build_method_list_template (objc_method_template, size);
3519 initlist = build_dispatch_table_initializer (objc_method_template, chain);
3521 if (TREE_CODE (implementation_context) == CLASS_IMPLEMENTATION_TYPE)
3522 UOBJC_INSTANCE_METHODS_decl
3523 = generate_dispatch_table (method_list_template,
3524 "_OBJC_INSTANCE_METHODS",
3527 /* we have a category */
3528 UOBJC_INSTANCE_METHODS_decl
3529 = generate_dispatch_table (method_list_template,
3530 "_OBJC_CATEGORY_INSTANCE_METHODS",
3533 TREE_TYPE (UOBJC_INSTANCE_METHODS_decl) = variable_length_type;
3536 UOBJC_INSTANCE_METHODS_decl = 0;
3540 generate_protocol_list (i_or_p)
3543 static tree cast_type = 0;
3544 tree initlist, decl_specs, sc_spec;
3545 tree refs_decl, expr_decl, lproto, e, plist;
3548 if (TREE_CODE (i_or_p) == CLASS_INTERFACE_TYPE
3549 || TREE_CODE (i_or_p) == CATEGORY_INTERFACE_TYPE)
3550 plist = CLASS_PROTOCOL_LIST (i_or_p);
3551 else if (TREE_CODE (i_or_p) == PROTOCOL_INTERFACE_TYPE)
3552 plist = PROTOCOL_LIST (i_or_p);
3560 (build_tree_list (NULLT,
3561 xref_tag (RECORD_TYPE,
3562 get_identifier (UTAG_PROTOCOL))),
3563 build1 (INDIRECT_REF, NULLT, NULLT)));
3566 for (lproto = plist; lproto; lproto = TREE_CHAIN (lproto))
3567 if (TREE_CODE (TREE_VALUE (lproto)) == PROTOCOL_INTERFACE_TYPE
3568 && PROTOCOL_FORWARD_DECL (TREE_VALUE (lproto)))
3571 /* build initializer */
3572 initlist = tree_cons (NULLT, build_int_2 (0, 0), NULLT);
3574 e = build_int_2 (size, 0);
3575 TREE_TYPE (e) = cast_type;
3576 initlist = tree_cons (NULLT, e, initlist);
3578 for (lproto = plist; lproto; lproto = TREE_CHAIN (lproto))
3580 tree pval = TREE_VALUE (lproto);
3582 if (TREE_CODE (pval) == PROTOCOL_INTERFACE_TYPE
3583 && PROTOCOL_FORWARD_DECL (pval))
3585 e = build_unary_op (ADDR_EXPR, PROTOCOL_FORWARD_DECL (pval), 0);
3586 initlist = tree_cons (NULLT, e, initlist);
3590 /* static struct objc_protocol *refs[n]; */
3592 sc_spec = tree_cons (NULLT, ridpointers[(int) RID_STATIC], NULLT);
3593 decl_specs = tree_cons (NULLT, xref_tag (RECORD_TYPE,
3594 get_identifier (UTAG_PROTOCOL)),
3597 if (TREE_CODE (i_or_p) == PROTOCOL_INTERFACE_TYPE)
3598 expr_decl = build_nt (ARRAY_REF,
3599 synth_id_with_class_suffix ("_OBJC_PROTOCOL_REFS",
3601 build_int_2 (size + 2, 0));
3602 else if (TREE_CODE (i_or_p) == CLASS_INTERFACE_TYPE)
3603 expr_decl = build_nt (ARRAY_REF,
3604 synth_id_with_class_suffix ("_OBJC_CLASS_PROTOCOLS",
3606 build_int_2 (size + 2, 0));
3607 else if (TREE_CODE (i_or_p) == CATEGORY_INTERFACE_TYPE)
3608 expr_decl = build_nt (ARRAY_REF,
3609 synth_id_with_class_suffix ("_OBJC_CATEGORY_PROTOCOLS",
3611 build_int_2 (size + 2, 0));
3613 expr_decl = build1 (INDIRECT_REF, NULLT, expr_decl);
3615 refs_decl = start_decl (expr_decl, decl_specs, 1);
3616 end_temporary_allocation ();
3618 finish_decl (refs_decl, build_constructor (TREE_TYPE (refs_decl),
3619 nreverse (initlist)),
3626 build_category_initializer (type, cat_name, class_name,
3627 instance_methods, class_methods, protocol_list)
3631 tree instance_methods;
3635 tree initlist = NULLT, expr;
3637 initlist = tree_cons (NULLT, cat_name, initlist);
3638 initlist = tree_cons (NULLT, class_name, initlist);
3640 if (!instance_methods)
3641 initlist = tree_cons (NULLT, build_int_2 (0, 0), initlist);
3644 expr = build_unary_op (ADDR_EXPR, instance_methods, 0);
3645 initlist = tree_cons (NULLT, expr, initlist);
3648 initlist = tree_cons (NULLT, build_int_2 (0, 0), initlist);
3651 expr = build_unary_op (ADDR_EXPR, class_methods, 0);
3652 initlist = tree_cons (NULLT, expr, initlist);
3655 /* protocol_list = */
3657 initlist = tree_cons (NULLT, build_int_2 (0, 0), initlist);
3660 static tree cast_type2;
3666 (build_tree_list (NULLT,
3667 xref_tag (RECORD_TYPE,
3668 get_identifier (UTAG_PROTOCOL))),
3669 build1 (INDIRECT_REF, NULLT,
3670 build1 (INDIRECT_REF, NULLT, NULLT))));
3672 expr = build_unary_op (ADDR_EXPR, protocol_list, 0);
3673 TREE_TYPE (expr) = cast_type2;
3674 initlist = tree_cons (NULLT, expr, initlist);
3677 return build_constructor (type, nreverse (initlist));
3680 /* struct objc_class {
3681 struct objc_class *isa;
3682 struct objc_class *super_class;
3687 struct objc_ivar_list *ivars;
3688 struct objc_method_list *methods;
3689 if (flag_next_runtime)
3690 struct objc_cache *cache;
3692 struct sarray *dtable;
3693 struct objc_class *subclass_list;
3694 struct objc_class *sibling_class;
3696 struct objc_protocol_list *protocols;
3700 build_shared_structure_initializer (type, isa, super, name, size, status,
3701 dispatch_table, ivar_list, protocol_list)
3708 tree dispatch_table;
3712 tree initlist = NULLT, expr;
3715 initlist = tree_cons (NULLT, isa, initlist);
3718 initlist = tree_cons (NULLT, super, initlist);
3721 initlist = tree_cons (NULLT, default_conversion (name), initlist);
3724 initlist = tree_cons (NULLT, build_int_2 (0, 0), initlist);
3727 initlist = tree_cons (NULLT, build_int_2 (status, 0), initlist);
3729 /* instance_size = */
3730 initlist = tree_cons (NULLT, size, initlist);
3732 /* objc_ivar_list = */
3734 initlist = tree_cons (NULLT, build_int_2 (0, 0), initlist);
3737 expr = build_unary_op (ADDR_EXPR, ivar_list, 0);
3738 initlist = tree_cons (NULLT, expr, initlist);
3741 /* objc_method_list = */
3742 if (!dispatch_table)
3743 initlist = tree_cons (NULLT, build_int_2 (0, 0), initlist);
3746 expr = build_unary_op (ADDR_EXPR, dispatch_table, 0);
3747 initlist = tree_cons (NULLT, expr, initlist);
3750 if (flag_next_runtime)
3751 /* method_cache = */
3752 initlist = tree_cons (NULLT, build_int_2 (0, 0), initlist);
3756 initlist = tree_cons (NULLT, build_int_2 (0, 0), initlist);
3758 /* subclass_list = */
3759 initlist = tree_cons (NULLT, build_int_2 (0, 0), initlist);
3761 /* sibling_class = */
3762 initlist = tree_cons (NULLT, build_int_2 (0, 0), initlist);
3765 /* protocol_list = */
3766 if (! protocol_list)
3767 initlist = tree_cons (NULLT, build_int_2 (0, 0), initlist);
3770 static tree cast_type2;
3776 (build_tree_list (NULLT,
3777 xref_tag (RECORD_TYPE,
3778 get_identifier (UTAG_PROTOCOL))),
3779 build1 (INDIRECT_REF, NULLT,
3780 build1 (INDIRECT_REF, NULLT, NULLT))));
3782 expr = build_unary_op (ADDR_EXPR, protocol_list, 0);
3783 TREE_TYPE (expr) = cast_type2;
3784 initlist = tree_cons (NULLT, expr, initlist);
3787 return build_constructor (type, nreverse (initlist));
3790 /* static struct objc_category _OBJC_CATEGORY_<name> = { ... }; */
3792 generate_category (cat)
3795 tree sc_spec, decl_specs, decl;
3796 tree initlist, cat_name_expr, class_name_expr;
3797 tree protocol_decl, category;
3799 add_class_reference (CLASS_NAME (cat));
3800 cat_name_expr = add_objc_string (CLASS_SUPER_NAME (cat), class_names);
3802 class_name_expr = add_objc_string (CLASS_NAME (cat), class_names);
3804 category = CLASS_CATEGORY_LIST (implementation_template);
3806 /* find the category interface from the class it is associated with */
3809 if (CLASS_SUPER_NAME (cat) == CLASS_SUPER_NAME (category))
3811 category = CLASS_CATEGORY_LIST (category);
3814 if (category && CLASS_PROTOCOL_LIST (category))
3816 generate_protocol_references (CLASS_PROTOCOL_LIST (category));
3817 protocol_decl = generate_protocol_list (category);
3822 sc_spec = tree_cons (NULLT, ridpointers[(int) RID_STATIC], NULLT);
3823 decl_specs = tree_cons (NULLT, objc_category_template, sc_spec);
3825 decl = start_decl (synth_id_with_class_suffix ("_OBJC_CATEGORY",
3826 implementation_context),
3828 end_temporary_allocation ();
3830 initlist = build_category_initializer (TREE_TYPE (decl),
3831 cat_name_expr, class_name_expr,
3832 UOBJC_INSTANCE_METHODS_decl,
3833 UOBJC_CLASS_METHODS_decl,
3836 TREE_USED (decl) = 1;
3837 finish_decl (decl, initlist, NULLT);
3840 /* static struct objc_class _OBJC_METACLASS_Foo={ ... };
3841 static struct objc_class _OBJC_CLASS_Foo={ ... }; */
3844 generate_shared_structures ()
3846 tree sc_spec, decl_specs, decl;
3847 tree name_expr, super_expr, root_expr;
3848 tree my_root_id = NULLT, my_super_id = NULLT;
3849 tree cast_type, initlist, protocol_decl;
3851 my_super_id = CLASS_SUPER_NAME (implementation_template);
3854 add_class_reference (my_super_id);
3856 /* Compute "my_root_id" - this is required for code generation.
3857 the "isa" for all meta class structures points to the root of
3858 the inheritance hierarchy (e.g. "__Object")... */
3859 my_root_id = my_super_id;
3862 tree my_root_int = lookup_interface (my_root_id);
3864 if (my_root_int && CLASS_SUPER_NAME (my_root_int))
3865 my_root_id = CLASS_SUPER_NAME (my_root_int);
3871 else /* no super class */
3873 my_root_id = CLASS_NAME (implementation_template);
3877 = groktypename (build_tree_list (build_tree_list (NULLT,
3878 objc_class_template),
3879 build1 (INDIRECT_REF, NULLT, NULLT)));
3881 name_expr = add_objc_string (CLASS_NAME (implementation_template),
3884 /* install class `isa' and `super' pointers at runtime */
3887 super_expr = add_objc_string (my_super_id, class_names);
3888 super_expr = build_c_cast (cast_type, super_expr); /* cast! */
3891 super_expr = build_int_2 (0, 0);
3893 root_expr = add_objc_string (my_root_id, class_names);
3894 root_expr = build_c_cast (cast_type, root_expr); /* cast! */
3896 if (CLASS_PROTOCOL_LIST (implementation_template))
3898 generate_protocol_references (CLASS_PROTOCOL_LIST (implementation_template));
3899 protocol_decl = generate_protocol_list (implementation_template);
3904 /* static struct objc_class _OBJC_METACLASS_Foo = { ... }; */
3906 sc_spec = build_tree_list (NULLT, ridpointers[(int) RID_STATIC]);
3907 decl_specs = tree_cons (NULLT, objc_class_template, sc_spec);
3909 decl = start_decl (DECL_NAME (UOBJC_METACLASS_decl), decl_specs, 1);
3910 end_temporary_allocation ();
3913 = build_shared_structure_initializer
3915 root_expr, super_expr, name_expr,
3916 build_int_2 ((TREE_INT_CST_LOW (TYPE_SIZE (objc_class_template))
3920 UOBJC_CLASS_METHODS_decl,
3921 UOBJC_CLASS_VARIABLES_decl,
3924 finish_decl (decl, initlist, NULLT);
3926 /* static struct objc_class _OBJC_CLASS_Foo={ ... }; */
3928 decl = start_decl (DECL_NAME (UOBJC_CLASS_decl), decl_specs, 1);
3929 end_temporary_allocation ();
3932 = build_shared_structure_initializer
3934 build_unary_op (ADDR_EXPR, UOBJC_METACLASS_decl, 0),
3935 super_expr, name_expr,
3936 build_int_2 ((TREE_INT_CST_LOW (TYPE_SIZE (CLASS_STATIC_TEMPLATE (implementation_template)))
3940 UOBJC_INSTANCE_METHODS_decl,
3941 UOBJC_INSTANCE_VARIABLES_decl,
3944 finish_decl (decl, initlist, NULLT);
3948 synth_id_with_class_suffix (preamble, ctxt)
3953 if (TREE_CODE (ctxt) == CLASS_IMPLEMENTATION_TYPE
3954 || TREE_CODE (ctxt) == CLASS_INTERFACE_TYPE)
3957 = IDENTIFIER_POINTER (CLASS_NAME (implementation_context));
3958 string = (char *) alloca (strlen (preamble) + strlen (class_name) + 3);
3959 sprintf (string, "%s_%s", preamble,
3960 IDENTIFIER_POINTER (CLASS_NAME (ctxt)));
3962 else if (TREE_CODE (ctxt) == CATEGORY_IMPLEMENTATION_TYPE
3963 || TREE_CODE (ctxt) == CATEGORY_INTERFACE_TYPE)
3965 /* we have a category */
3967 = IDENTIFIER_POINTER (CLASS_NAME (implementation_context));
3968 char *class_super_name
3969 = IDENTIFIER_POINTER (CLASS_SUPER_NAME (implementation_context));
3970 string = (char *) alloca (strlen (preamble)
3971 + strlen (class_name)
3972 + strlen (class_super_name)
3974 sprintf (string, "%s_%s_%s", preamble, class_name, class_super_name);
3976 else if (TREE_CODE (ctxt) == PROTOCOL_INTERFACE_TYPE)
3978 char *protocol_name = IDENTIFIER_POINTER (PROTOCOL_NAME (ctxt));
3979 string = (char *) alloca (strlen (preamble) + strlen (protocol_name) + 3);
3980 sprintf (string, "%s_%s", preamble, protocol_name);
3982 return get_identifier (string);
3986 is_objc_type_qualifier (node)
3989 return (TREE_CODE (node) == IDENTIFIER_NODE
3990 && (node == ridpointers [(int) RID_CONST]
3991 || node == ridpointers [(int) RID_VOLATILE]
3992 || node == ridpointers [(int) RID_IN]
3993 || node == ridpointers [(int) RID_OUT]
3994 || node == ridpointers [(int) RID_INOUT]
3995 || node == ridpointers [(int) RID_BYCOPY]
3996 || node == ridpointers [(int) RID_ONEWAY]));
3999 /* If type is empty or only type qualifiers are present, add default
4000 type of id (otherwise grokdeclarator will default to int). */
4003 adjust_type_for_id_default (type)
4006 tree declspecs, chain;
4009 return build_tree_list (build_tree_list (NULLT, objc_object_reference),
4010 build1 (INDIRECT_REF, NULLT, NULLT));
4012 declspecs = TREE_PURPOSE (type);
4014 /* Determine if a typespec is present. */
4015 for (chain = declspecs;
4017 chain = TREE_CHAIN (chain))
4019 if (!is_objc_type_qualifier (TREE_VALUE (chain)))
4023 return build_tree_list (tree_cons (NULLT, objc_object_reference, declspecs),
4024 build1 (INDIRECT_REF, NULLT, NULLT));
4029 selector ':' '(' typename ')' identifier
4032 transform an Objective-C keyword argument into
4033 the C equivalent parameter declarator.
4035 in: key_name, an "identifier_node" (optional).
4036 arg_type, a "tree_list" (optional).
4037 arg_name, an "identifier_node".
4039 note: it would be really nice to strongly type the preceding
4040 arguments in the function prototype; however, then i
4041 could not use the "accessor" macros defined in "tree.h".
4043 out: an instance of "keyword_decl". */
4046 build_keyword_decl (key_name, arg_type, arg_name)
4053 /* if no type is specified, default to "id" */
4054 arg_type = adjust_type_for_id_default (arg_type);
4056 keyword_decl = make_node (KEYWORD_DECL);
4058 TREE_TYPE (keyword_decl) = arg_type;
4059 KEYWORD_ARG_NAME (keyword_decl) = arg_name;
4060 KEYWORD_KEY_NAME (keyword_decl) = key_name;
4062 return keyword_decl;
4065 /* Given a chain of keyword_decl's, synthesize the full keyword selector. */
4067 build_keyword_selector (selector)
4071 tree key_chain, key_name;
4074 for (key_chain = selector; key_chain; key_chain = TREE_CHAIN (key_chain))
4076 if (TREE_CODE (selector) == KEYWORD_DECL)
4077 key_name = KEYWORD_KEY_NAME (key_chain);
4078 else if (TREE_CODE (selector) == TREE_LIST)
4079 key_name = TREE_PURPOSE (key_chain);
4082 len += IDENTIFIER_LENGTH (key_name) + 1;
4083 else /* just a ':' arg */
4086 buf = (char *)alloca (len + 1);
4087 bzero (buf, len + 1);
4089 for (key_chain = selector; key_chain; key_chain = TREE_CHAIN (key_chain))
4091 if (TREE_CODE (selector) == KEYWORD_DECL)
4092 key_name = KEYWORD_KEY_NAME (key_chain);
4093 else if (TREE_CODE (selector) == TREE_LIST)
4094 key_name = TREE_PURPOSE (key_chain);
4097 strcat (buf, IDENTIFIER_POINTER (key_name));
4100 return get_identifier (buf);
4103 /* used for declarations and definitions */
4106 build_method_decl (code, ret_type, selector, add_args)
4107 enum tree_code code;
4114 /* if no type is specified, default to "id" */
4115 ret_type = adjust_type_for_id_default (ret_type);
4117 method_decl = make_node (code);
4118 TREE_TYPE (method_decl) = ret_type;
4120 /* If we have a keyword selector, create an identifier_node that
4121 represents the full selector name (`:' included)... */
4122 if (TREE_CODE (selector) == KEYWORD_DECL)
4124 METHOD_SEL_NAME (method_decl) = build_keyword_selector (selector);
4125 METHOD_SEL_ARGS (method_decl) = selector;
4126 METHOD_ADD_ARGS (method_decl) = add_args;
4130 METHOD_SEL_NAME (method_decl) = selector;
4131 METHOD_SEL_ARGS (method_decl) = NULLT;
4132 METHOD_ADD_ARGS (method_decl) = NULLT;
4138 #define METHOD_DEF 0
4139 #define METHOD_REF 1
4141 /* Used by `build_message_expr' and `comp_method_types'. Return an
4142 argument list for method METH. CONTEXT is either METHOD_DEF or
4143 METHOD_REF, saying whether we are trying to define a method or call
4144 one. SUPERFLAG says this is for a send to super; this makes a
4145 difference for the NeXT calling sequence in which the lookup and
4146 the method call are done together. */
4149 get_arg_type_list (meth, context, superflag)
4157 if (flag_next_runtime && superflag)
4158 arglist = build_tree_list (NULLT, super_type);
4159 else if (context == METHOD_DEF)
4160 arglist = build_tree_list (NULLT, TREE_TYPE (self_decl));
4162 arglist = build_tree_list (NULLT, id_type);
4164 /* selector type - will eventually change to `int' */
4165 chainon (arglist, build_tree_list (NULLT, selector_type));
4167 /* build a list of argument types */
4168 for (akey = METHOD_SEL_ARGS (meth); akey; akey = TREE_CHAIN (akey))
4170 tree arg_decl = groktypename_in_parm_context (TREE_TYPE (akey));
4171 chainon (arglist, build_tree_list (NULLT, TREE_TYPE (arg_decl)));
4174 if (METHOD_ADD_ARGS (meth) == (tree)1)
4175 /* We have a `, ...' immediately following the selector,
4176 finalize the arglist...simulate get_parm_info (0). */
4178 else if (METHOD_ADD_ARGS (meth))
4180 /* we have a variable length selector */
4181 tree add_arg_list = TREE_CHAIN (METHOD_ADD_ARGS (meth));
4182 chainon (arglist, add_arg_list);
4185 /* finalize the arglist...simulate get_parm_info (1) */
4186 chainon (arglist, build_tree_list (NULLT, void_type_node));
4192 check_duplicates (hsh)
4203 /* we have two methods with the same name and different types */
4205 char type = (TREE_CODE (meth) == INSTANCE_METHOD_DECL) ? '-' : '+';
4207 warning ("multiple declarations for method `%s'",
4208 IDENTIFIER_POINTER (METHOD_SEL_NAME (meth)));
4210 warn_with_method ("using", type, meth);
4211 for (loop = hsh->list; loop; loop = loop->next)
4212 warn_with_method ("also found", type, loop->value);
4218 /* If RECEIVER is a class reference, return the identifier node for the
4219 referenced class. RECEIVER is created by get_class_reference, so we
4220 check the exact form created depending on which runtimes are used. */
4223 receiver_is_class_object (receiver)
4226 tree chain, exp, arg;
4227 if (flag_next_runtime)
4229 /* The receiver is a variable created by build_class_reference_decl. */
4230 if (TREE_CODE (receiver) == VAR_DECL
4231 && TREE_TYPE (receiver) == objc_class_type)
4232 /* Look up the identifier. */
4233 for (chain = cls_ref_chain; chain; chain = TREE_CHAIN (chain))
4234 if (TREE_PURPOSE (chain) == receiver)
4235 return TREE_VALUE (chain);
4239 /* The receiver is a function call that returns an id. Check if
4240 it is a call to objc_getClass, if so, pick up the class name. */
4241 if ((exp = TREE_OPERAND (receiver, 0))
4242 && TREE_CODE (exp) == ADDR_EXPR
4243 && (exp = TREE_OPERAND (exp, 0))
4244 && TREE_CODE (exp) == FUNCTION_DECL
4245 && exp == objc_get_class_decl
4246 /* we have a call to objc_getClass! */
4247 && (arg = TREE_OPERAND (receiver, 1))
4248 && TREE_CODE (arg) == TREE_LIST
4249 && (arg = TREE_VALUE (arg)))
4252 if (TREE_CODE (arg) == ADDR_EXPR
4253 && (arg = TREE_OPERAND (arg, 0))
4254 && TREE_CODE (arg) == STRING_CST)
4255 /* finally, we have the class name */
4256 return get_identifier (TREE_STRING_POINTER (arg));
4262 /* If we are currently building a message expr, this holds
4263 the identifier of the selector of the message. This is
4264 used when printing warnings about argument mismatches. */
4266 static tree building_objc_message_expr = 0;
4269 maybe_building_objc_message_expr ()
4271 return building_objc_message_expr;
4274 /* Construct an expression for sending a message.
4275 MESS has the object to send to in TREE_PURPOSE
4276 and the argument list (including selector) in TREE_VALUE.
4278 (*(<abstract_decl>(*)())_msg)(receiver, selTransTbl[n], ...);
4279 (*(<abstract_decl>(*)())_msgSuper)(receiver, selTransTbl[n], ...); */
4282 build_message_expr (mess)
4285 tree receiver = TREE_PURPOSE (mess);
4286 tree selector, self_object;
4287 tree rtype, sel_name;
4288 tree args = TREE_VALUE (mess);
4289 tree method_params = NULLT;
4290 tree method_prototype = NULLT;
4292 int statically_typed = 0, statically_allocated = 0;
4293 tree class_ident = 0;
4295 /* 1 if this is sending to the superclass. */
4298 if (!doing_objc_thang)
4301 if (TREE_CODE (receiver) == ERROR_MARK)
4302 return error_mark_node;
4304 /* determine receiver type */
4305 rtype = TREE_TYPE (receiver);
4306 super = IS_SUPER (rtype);
4310 if (TREE_STATIC_TEMPLATE (rtype))
4311 statically_allocated = 1;
4312 else if (TREE_CODE (rtype) == POINTER_TYPE
4313 && TREE_STATIC_TEMPLATE (TREE_TYPE (rtype)))
4314 statically_typed = 1;
4315 else if ((flag_next_runtime
4316 || (TREE_CODE (receiver) == CALL_EXPR && IS_ID (rtype)))
4317 && (class_ident = receiver_is_class_object (receiver)))
4319 else if (! IS_ID (rtype)
4320 /* Allow any type that matches objc_class_type. */
4321 && ! comptypes (rtype, objc_class_type))
4323 bzero (errbuf, BUFSIZE);
4324 warning ("invalid receiver type `%s'",
4325 gen_declaration (rtype, errbuf));
4327 if (statically_allocated)
4328 receiver = build_unary_op (ADDR_EXPR, receiver, 0);
4330 /* Don't evaluate the receiver twice. */
4331 receiver = save_expr (receiver);
4332 self_object = receiver;
4335 /* If sending to `super', use current self as the object. */
4336 self_object = self_decl;
4338 /* Obtain the full selector name. */
4340 if (TREE_CODE (args) == IDENTIFIER_NODE)
4341 /* a unary selector */
4343 else if (TREE_CODE (args) == TREE_LIST)
4344 sel_name = build_keyword_selector (args);
4346 /* Build the parameters list for looking up the method.
4347 These are the object itself and the selector. */
4349 selector = build_selector_reference (sel_name);
4351 /* Build the parameter list to give to the method. */
4353 method_params = NULLT;
4354 if (TREE_CODE (args) == TREE_LIST)
4356 tree chain = args, prev = NULLT;
4358 /* We have a keyword selector--check for comma expressions. */
4361 tree element = TREE_VALUE (chain);
4363 /* We have a comma expression, must collapse... */
4364 if (TREE_CODE (element) == TREE_LIST)
4367 TREE_CHAIN (prev) = element;
4372 chain = TREE_CHAIN (chain);
4374 method_params = args;
4377 /* Determine operation return type. */
4379 if (IS_SUPER (rtype))
4383 if (CLASS_SUPER_NAME (implementation_template))
4385 iface = lookup_interface (CLASS_SUPER_NAME (implementation_template));
4387 if (TREE_CODE (method_context) == INSTANCE_METHOD_DECL)
4388 method_prototype = lookup_instance_method_static (iface, sel_name);
4390 method_prototype = lookup_class_method_static (iface, sel_name);
4392 if (iface && !method_prototype)
4393 warning ("`%s' does not respond to `%s'",
4394 IDENTIFIER_POINTER (CLASS_SUPER_NAME (implementation_template)),
4395 IDENTIFIER_POINTER (sel_name));
4399 error ("no super class declared in interface for `%s'",
4400 IDENTIFIER_POINTER (CLASS_NAME (implementation_template)));
4401 return error_mark_node;
4405 else if (statically_allocated)
4407 tree ctype = TREE_TYPE (rtype);
4408 tree iface = lookup_interface (TYPE_NAME (rtype));
4411 method_prototype = lookup_instance_method_static (iface, sel_name);
4414 if (! method_prototype && TYPE_PROTOCOL_LIST (ctype))
4416 = lookup_method_in_protocol_list (TYPE_PROTOCOL_LIST (ctype),
4419 if (!method_prototype)
4420 warning ("`%s' does not respond to `%s'",
4421 IDENTIFIER_POINTER (TYPE_NAME (rtype)),
4422 IDENTIFIER_POINTER (sel_name));
4424 else if (statically_typed)
4426 tree ctype = TREE_TYPE (rtype);
4428 /* `self' is now statically_typed...all methods should be visible
4429 within the context of the implementation... */
4430 if (implementation_context
4431 && CLASS_NAME (implementation_context) == TYPE_NAME (ctype))
4433 method_prototype = lookup_instance_method_static (implementation_template, sel_name);
4436 if (! method_prototype && TYPE_PROTOCOL_LIST (ctype))
4438 = lookup_method_in_protocol_list (TYPE_PROTOCOL_LIST (ctype),
4441 if (! method_prototype
4442 && implementation_template != implementation_context)
4443 /* the method is not published in the interface...check locally */
4445 = lookup_method (CLASS_NST_METHODS (implementation_context),
4452 if ((iface = lookup_interface (TYPE_NAME (ctype))))
4453 method_prototype = lookup_instance_method_static (iface, sel_name);
4455 if (! method_prototype)
4457 tree protocol_list = TYPE_PROTOCOL_LIST (ctype);
4460 = lookup_method_in_protocol_list (protocol_list, sel_name, 0);
4464 if (!method_prototype)
4465 warning ("`%s' does not respond to `%s'",
4466 IDENTIFIER_POINTER (TYPE_NAME (ctype)),
4467 IDENTIFIER_POINTER (sel_name));
4469 else if (class_ident)
4471 if (implementation_context
4472 && CLASS_NAME (implementation_context) == class_ident)
4475 = lookup_class_method_static (implementation_template, sel_name);
4477 if (!method_prototype
4478 && implementation_template != implementation_context)
4479 /* the method is not published in the interface...check locally */
4481 = lookup_method (CLASS_CLS_METHODS (implementation_context),
4488 if ((iface = lookup_interface (class_ident)))
4489 method_prototype = lookup_class_method_static (iface, sel_name);
4492 if (!method_prototype)
4494 warning ("cannot find class (factory) method.");
4495 warning ("return type for `%s' defaults to id",
4496 IDENTIFIER_POINTER (sel_name));
4499 else if (IS_PROTOCOL_QUALIFIED_ID (rtype))
4501 /* An anonymous object that has been qualified with a protocol. */
4503 tree protocol_list = TYPE_PROTOCOL_LIST (rtype);
4505 method_prototype = lookup_method_in_protocol_list (protocol_list,
4508 if (!method_prototype)
4512 warning ("method `%s' not implemented by protocol.",
4513 IDENTIFIER_POINTER (sel_name));
4515 /* try and find the method signiture in the global pools! */
4517 if (!(hsh = hash_lookup (nst_method_hash_list, sel_name)))
4518 hsh = hash_lookup (cls_method_hash_list, sel_name);
4520 if (!(method_prototype = check_duplicates (hsh)))
4521 warning ("return type defaults to id");
4528 /* we think we have an instance...loophole: extern id Object; */
4529 hsh = hash_lookup (nst_method_hash_list, sel_name);
4531 /* for various loopholes...like sending messages to self in a
4532 factory context... */
4533 hsh = hash_lookup (cls_method_hash_list, sel_name);
4535 method_prototype = check_duplicates (hsh);
4536 if (!method_prototype)
4538 warning ("cannot find method.");
4539 warning ("return type for `%s' defaults to id",
4540 IDENTIFIER_POINTER (sel_name));
4544 /* Save the selector name for printing error messages. */
4545 building_objc_message_expr = sel_name;
4547 retval = build_objc_method_call (super, method_prototype,
4548 receiver, self_object,
4549 selector, method_params);
4551 building_objc_message_expr = 0;
4556 /* Build a tree expression to send OBJECT the operation SELECTOR,
4557 looking up the method on object LOOKUP_OBJECT (often same as OBJECT),
4558 assuming the method has prototype METHOD_PROTOTYPE.
4559 (That is an INSTANCE_METHOD_DECL or CLASS_METHOD_DECL.)
4560 Use METHOD_PARAMS as list of args to pass to the method.
4561 If SUPER_FLAG is nonzero, we look up the superclass's method. */
4564 build_objc_method_call (super_flag, method_prototype, lookup_object, object,
4565 selector, method_params)
4567 tree method_prototype, lookup_object, object, selector, method_params;
4569 tree sender = (super_flag ? umsg_super_decl : umsg_decl);
4570 tree rcv_p = (super_flag
4571 ? build_pointer_type (xref_tag (RECORD_TYPE,
4572 get_identifier (TAG_SUPER)))
4575 if (flag_next_runtime)
4577 if (! method_prototype)
4579 method_params = tree_cons (NULLT, lookup_object,
4580 tree_cons (NULLT, selector,
4582 assemble_external (sender);
4583 return build_function_call (sender, method_params);
4587 /* This is a real kludge, but it is used only for the Next.
4588 Clobber the data type of SENDER temporarily to accept
4589 all the arguments for this operation, and to return
4590 whatever this operation returns. */
4591 tree arglist = NULLT;
4594 /* Save the proper contents of SENDER's data type. */
4595 tree savarg = TYPE_ARG_TYPES (TREE_TYPE (sender));
4596 tree savret = TREE_TYPE (TREE_TYPE (sender));
4598 /* Install this method's argument types. */
4599 arglist = get_arg_type_list (method_prototype, METHOD_REF,
4601 TYPE_ARG_TYPES (TREE_TYPE (sender)) = arglist;
4603 /* Install this method's return type. */
4604 TREE_TYPE (TREE_TYPE (sender))
4605 = groktypename (TREE_TYPE (method_prototype));
4607 /* Call SENDER with all the parameters. This will do type
4608 checking using the arg types for this method. */
4609 method_params = tree_cons (NULLT, lookup_object,
4610 tree_cons (NULLT, selector,
4612 assemble_external (sender);
4613 retval = build_function_call (sender, method_params);
4615 /* Restore SENDER's return/argument types. */
4616 TYPE_ARG_TYPES (TREE_TYPE (sender)) = savarg;
4617 TREE_TYPE (TREE_TYPE (sender)) = savret;
4623 /* This is the portable way.
4624 First call the lookup function to get a pointer to the method,
4625 then cast the pointer, then call it with the method arguments. */
4628 /* Avoid trouble since we may evaluate each of these twice. */
4629 object = save_expr (object);
4630 selector = save_expr (selector);
4632 lookup_object = build_c_cast (rcv_p, lookup_object); /* cast! */
4634 assemble_external (sender);
4636 = build_function_call (sender,
4637 tree_cons (NULLT, lookup_object,
4638 tree_cons (NULLT, selector, NULLT)));
4640 /* If we have a method prototype, construct the data type this
4641 method needs, and cast what we got from SENDER into a pointer
4643 if (method_prototype)
4645 tree arglist = get_arg_type_list (method_prototype, METHOD_REF,
4647 tree valtype = groktypename (TREE_TYPE (method_prototype));
4648 tree fake_function_type = build_function_type (valtype, arglist);
4649 TREE_TYPE (method) = build_pointer_type (fake_function_type);
4653 = build_pointer_type (build_function_type (ptr_type_node, NULLT));
4655 /* Pass the object to the method. */
4656 assemble_external (method);
4657 return build_function_call (method,
4658 tree_cons (NULLT, object,
4659 tree_cons (NULLT, selector,
4665 build_protocol_reference (p)
4668 tree decl, ident, ptype;
4669 struct obstack *save_current_obstack = current_obstack;
4670 struct obstack *save_rtl_obstack = rtl_obstack;
4672 rtl_obstack = current_obstack = &permanent_obstack;
4674 /* extern struct objc_protocol _OBJC_PROTOCOL_<mumble>; */
4676 ident = synth_id_with_class_suffix ("_OBJC_PROTOCOL", p);
4678 = groktypename (build_tree_list (build_tree_list (NULLT,
4679 objc_protocol_template),
4682 if (IDENTIFIER_GLOBAL_VALUE (ident))
4683 decl = IDENTIFIER_GLOBAL_VALUE (ident); /* Set by pushdecl. */
4686 decl = build_decl (VAR_DECL, ident, ptype);
4687 DECL_EXTERNAL (decl) = 1;
4688 TREE_PUBLIC (decl) = 1;
4689 TREE_USED (decl) = 1;
4691 /* usually called from `rest_of_decl_compilation' */
4692 make_decl_rtl (decl, 0, 1);
4693 /* our `extended/custom' pushdecl in c-decl.c */
4694 pushdecl_top_level (decl);
4696 current_obstack = save_current_obstack;
4697 rtl_obstack = save_rtl_obstack;
4699 PROTOCOL_FORWARD_DECL (p) = decl;
4703 build_protocol_expr (protoname)
4709 if (!doing_objc_thang)
4712 p = lookup_protocol (protoname);
4716 error ("Cannot find protocol declaration for `%s'",
4717 IDENTIFIER_POINTER (protoname));
4718 return error_mark_node;
4721 if (!PROTOCOL_FORWARD_DECL (p))
4722 build_protocol_reference (p);
4724 expr = build_unary_op (ADDR_EXPR, PROTOCOL_FORWARD_DECL (p), 0);
4726 TREE_TYPE (expr) = protocol_type;
4732 build_selector_expr (selnamelist)
4737 if (!doing_objc_thang)
4740 /* obtain the full selector name */
4741 if (TREE_CODE (selnamelist) == IDENTIFIER_NODE)
4742 /* a unary selector */
4743 selname = selnamelist;
4744 else if (TREE_CODE (selnamelist) == TREE_LIST)
4745 selname = build_keyword_selector (selnamelist);
4747 return build_selector_reference (selname);
4751 build_encode_expr (type)
4757 if (!doing_objc_thang)
4760 encode_type (type, obstack_object_size (&util_obstack),
4761 OBJC_ENCODE_INLINE_DEFS);
4762 obstack_1grow (&util_obstack, 0); /* null terminate string */
4763 string = obstack_finish (&util_obstack);
4765 /* synthesize a string that represents the encoded struct/union */
4766 result = my_build_string (strlen (string) + 1, string);
4767 obstack_free (&util_obstack, util_firstobj);
4772 build_ivar_reference (id)
4775 if (TREE_CODE (method_context) == CLASS_METHOD_DECL)
4777 /* Historically, a class method that produced objects (factory
4778 method) would assign `self' to the instance that it
4779 allocated. This would effectively turn the class method into
4780 an instance method. Following this assignment, the instance
4781 variables could be accessed. That practice, while safe,
4782 violates the simple rule that a class method should not refer
4783 to an instance variable. It's better to catch the cases
4784 where this is done unknowingly than to support the above
4786 warning ("instance variable `%s' accessed in class method",
4787 IDENTIFIER_POINTER (id));
4788 TREE_TYPE (self_decl) = instance_type; /* cast */
4791 return build_component_ref (build_indirect_ref (self_decl, "->"), id);
4794 #define HASH_ALLOC_LIST_SIZE 170
4795 #define ATTR_ALLOC_LIST_SIZE 170
4796 #define SIZEHASHTABLE 257
4799 #define HASHFUNCTION(key) ((HOST_WIDE_INT) key & 0x7fffffff)
4804 nst_method_hash_list = (hash *)xmalloc (SIZEHASHTABLE * sizeof (hash));
4805 cls_method_hash_list = (hash *)xmalloc (SIZEHASHTABLE * sizeof (hash));
4807 if (!nst_method_hash_list || !cls_method_hash_list)
4808 perror ("unable to allocate space in objc-tree.c");
4813 for (i = 0; i < SIZEHASHTABLE; i++)
4815 nst_method_hash_list[i] = 0;
4816 cls_method_hash_list[i] = 0;
4822 hash_enter (hashlist, method)
4826 static hash hash_alloc_list = 0;
4827 static int hash_alloc_index = 0;
4829 int slot = HASHFUNCTION (METHOD_SEL_NAME (method)) % SIZEHASHTABLE;
4831 if (! hash_alloc_list || hash_alloc_index >= HASH_ALLOC_LIST_SIZE)
4833 hash_alloc_index = 0;
4834 hash_alloc_list = (hash) xmalloc (sizeof (struct hashed_entry)
4835 * HASH_ALLOC_LIST_SIZE);
4836 if (! hash_alloc_list)
4837 perror ("unable to allocate in objc-tree.c");
4839 obj = &hash_alloc_list[hash_alloc_index++];
4841 obj->next = hashlist[slot];
4844 hashlist[slot] = obj; /* append to front */
4848 hash_lookup (hashlist, sel_name)
4854 target = hashlist[HASHFUNCTION (sel_name) % SIZEHASHTABLE];
4858 if (sel_name == METHOD_SEL_NAME (target->key))
4861 target = target->next;
4867 hash_add_attr (entry, value)
4871 static attr attr_alloc_list = 0;
4872 static int attr_alloc_index = 0;
4875 if (! attr_alloc_list || attr_alloc_index >= ATTR_ALLOC_LIST_SIZE)
4877 attr_alloc_index = 0;
4878 attr_alloc_list = (attr) xmalloc (sizeof (struct hashed_attribute)
4879 * ATTR_ALLOC_LIST_SIZE);
4880 if (! attr_alloc_list)
4881 perror ("unable to allocate in objc-tree.c");
4883 obj = &attr_alloc_list[attr_alloc_index++];
4884 obj->next = entry->list;
4887 entry->list = obj; /* append to front */
4891 lookup_method (mchain, method)
4897 if (TREE_CODE (method) == IDENTIFIER_NODE)
4900 key = METHOD_SEL_NAME (method);
4904 if (METHOD_SEL_NAME (mchain) == key)
4906 mchain = TREE_CHAIN (mchain);
4912 lookup_instance_method_static (interface, ident)
4916 tree inter = interface;
4917 tree chain = CLASS_NST_METHODS (inter);
4922 if ((meth = lookup_method (chain, ident)))
4925 if (CLASS_CATEGORY_LIST (inter))
4927 tree category = CLASS_CATEGORY_LIST (inter);
4928 chain = CLASS_NST_METHODS (category);
4932 if ((meth = lookup_method (chain, ident)))
4936 /* Check for instance methods in protocols in categories. */
4937 if (CLASS_PROTOCOL_LIST (category))
4939 if ((meth = (lookup_method_in_protocol_list
4940 (CLASS_PROTOCOL_LIST (category), ident, 0))))
4944 if ((category = CLASS_CATEGORY_LIST (category)))
4945 chain = CLASS_NST_METHODS (category);
4950 if (CLASS_PROTOCOL_LIST (inter))
4952 if ((meth = (lookup_method_in_protocol_list
4953 (CLASS_PROTOCOL_LIST (inter), ident, 0))))
4957 if ((inter = lookup_interface (CLASS_SUPER_NAME (inter))))
4958 chain = CLASS_NST_METHODS (inter);
4966 lookup_class_method_static (interface, ident)
4970 tree inter = interface;
4971 tree chain = CLASS_CLS_METHODS (inter);
4973 tree root_inter = NULLT;
4977 if ((meth = lookup_method (chain, ident)))
4980 if (CLASS_CATEGORY_LIST (inter))
4982 tree category = CLASS_CATEGORY_LIST (inter);
4983 chain = CLASS_CLS_METHODS (category);
4987 if ((meth = lookup_method (chain, ident)))
4991 /* Check for class methods in protocols in categories. */
4992 if (CLASS_PROTOCOL_LIST (category))
4994 if ((meth = (lookup_method_in_protocol_list
4995 (CLASS_PROTOCOL_LIST (category), ident, 1))))
4999 if ((category = CLASS_CATEGORY_LIST (category)))
5000 chain = CLASS_CLS_METHODS (category);
5006 /* Check for class methods in protocols. */
5007 if (CLASS_PROTOCOL_LIST (inter))
5009 if ((meth = (lookup_method_in_protocol_list
5010 (CLASS_PROTOCOL_LIST (inter), ident, 1))))
5015 if ((inter = lookup_interface (CLASS_SUPER_NAME (inter))))
5016 chain = CLASS_CLS_METHODS (inter);
5021 /* Simulate wrap around. */
5022 return lookup_instance_method_static (root_inter, ident);
5026 add_class_method (class, method)
5033 /* We will have allocated the method parameter declarations on the
5034 maybepermanent_obstack. Need to make sure they stick around! */
5037 if (!(mth = lookup_method (CLASS_CLS_METHODS (class), method)))
5039 /* put method on list in reverse order */
5040 TREE_CHAIN (method) = CLASS_CLS_METHODS (class);
5041 CLASS_CLS_METHODS (class) = method;
5045 if (TREE_CODE (class) == CLASS_IMPLEMENTATION_TYPE)
5046 error ("duplicate definition of class method `%s'.",
5047 IDENTIFIER_POINTER (METHOD_SEL_NAME (mth)));
5050 /* check types, if different complain */
5051 if (!comp_proto_with_proto (method, mth))
5052 error ("duplicate declaration of class method `%s'.",
5053 IDENTIFIER_POINTER (METHOD_SEL_NAME (mth)));
5057 if (!(hsh = hash_lookup (cls_method_hash_list, METHOD_SEL_NAME (method))))
5059 /* install on a global chain */
5060 hash_enter (cls_method_hash_list, method);
5064 /* check types, if different add to a list */
5065 if (!comp_proto_with_proto (method, hsh->key))
5066 hash_add_attr (hsh, method);
5072 add_instance_method (class, method)
5079 /* We will have allocated the method parameter declarations on the
5080 maybepermanent_obstack. Need to make sure they stick around! */
5083 if (!(mth = lookup_method (CLASS_NST_METHODS (class), method)))
5085 /* put method on list in reverse order */
5086 TREE_CHAIN (method) = CLASS_NST_METHODS (class);
5087 CLASS_NST_METHODS (class) = method;
5091 if (TREE_CODE (class) == CLASS_IMPLEMENTATION_TYPE)
5092 error ("duplicate definition of instance method `%s'.",
5093 IDENTIFIER_POINTER (METHOD_SEL_NAME (mth)));
5096 /* check types, if different complain */
5097 if (!comp_proto_with_proto (method, mth))
5098 error ("duplicate declaration of instance method `%s'.",
5099 IDENTIFIER_POINTER (METHOD_SEL_NAME (mth)));
5103 if (!(hsh = hash_lookup (nst_method_hash_list, METHOD_SEL_NAME (method))))
5105 /* install on a global chain */
5106 hash_enter (nst_method_hash_list, method);
5110 /* check types, if different add to a list */
5111 if (!comp_proto_with_proto (method, hsh->key))
5112 hash_add_attr (hsh, method);
5121 /* put interfaces on list in reverse order */
5122 TREE_CHAIN (class) = interface_chain;
5123 interface_chain = class;
5124 return interface_chain;
5128 add_category (class, category)
5132 /* put categories on list in reverse order */
5134 tree cat = CLASS_CATEGORY_LIST (class);
5137 if (CLASS_SUPER_NAME (cat) == CLASS_SUPER_NAME (category))
5138 warning ("duplicate interface declaration for category `%s(%s)'",
5139 IDENTIFIER_POINTER (CLASS_NAME (class)),
5140 IDENTIFIER_POINTER (CLASS_SUPER_NAME (category)));
5141 cat = CLASS_CATEGORY_LIST (cat);
5144 CLASS_CATEGORY_LIST (category) = CLASS_CATEGORY_LIST (class);
5145 CLASS_CATEGORY_LIST (class) = category;
5148 /* Called after parsing each instance variable declaration. Necessary to
5149 preserve typedefs and implement public/private...
5151 PUBLIC is 1 for public, 0 for protected, and 2 for private. */
5154 add_instance_variable (class, public, declarator, declspecs, width)
5161 tree field_decl, raw_decl;
5163 raw_decl = build_tree_list (declspecs /*purpose*/, declarator/*value*/);
5165 if (CLASS_RAW_IVARS (class))
5166 chainon (CLASS_RAW_IVARS (class), raw_decl);
5168 CLASS_RAW_IVARS (class) = raw_decl;
5170 field_decl = grokfield (input_filename, lineno,
5171 declarator, declspecs, width);
5173 /* overload the public attribute, it is not used for FIELD_DECL's */
5177 TREE_PUBLIC (field_decl) = 0;
5178 TREE_PRIVATE (field_decl) = 0;
5179 TREE_PROTECTED (field_decl) = 1;
5183 TREE_PUBLIC (field_decl) = 1;
5184 TREE_PRIVATE (field_decl) = 0;
5185 TREE_PROTECTED (field_decl) = 0;
5189 TREE_PUBLIC (field_decl) = 0;
5190 TREE_PRIVATE (field_decl) = 1;
5191 TREE_PROTECTED (field_decl) = 0;
5196 if (CLASS_IVARS (class))
5197 chainon (CLASS_IVARS (class), field_decl);
5199 CLASS_IVARS (class) = field_decl;
5205 is_ivar (decl_chain, ident)
5209 for ( ; decl_chain; decl_chain = TREE_CHAIN (decl_chain))
5210 if (DECL_NAME (decl_chain) == ident)
5215 /* True if the ivar is private and we are not in its implementation. */
5221 if (TREE_PRIVATE (decl)
5222 && ! is_ivar (CLASS_IVARS (implementation_template), DECL_NAME (decl)))
5224 error ("instance variable `%s' is declared private",
5225 IDENTIFIER_POINTER (DECL_NAME (decl)));
5232 /* we have an instance variable reference, check to see if it is public...*/
5235 is_public (expr, identifier)
5239 tree basetype = TREE_TYPE (expr);
5240 enum tree_code code = TREE_CODE (basetype);
5243 if (code == RECORD_TYPE)
5245 if (TREE_STATIC_TEMPLATE (basetype))
5247 if (!lookup_interface (TYPE_NAME (basetype)))
5249 error ("Cannot find interface declaration for `%s'",
5250 IDENTIFIER_POINTER (TYPE_NAME (basetype)));
5254 if ((decl = is_ivar (TYPE_FIELDS (basetype), identifier)))
5256 if (TREE_PUBLIC (decl))
5259 /* important difference between the Stepstone translator:
5260 all instance variables should be public within the context
5261 of the implementation. */
5262 if (implementation_context
5263 && (((TREE_CODE (implementation_context)
5264 == CLASS_IMPLEMENTATION_TYPE)
5265 || (TREE_CODE (implementation_context)
5266 == CATEGORY_IMPLEMENTATION_TYPE))
5267 && (CLASS_NAME (implementation_context)
5268 == TYPE_NAME (basetype))))
5269 return ! is_private (decl);
5271 error ("instance variable `%s' is declared %s",
5272 IDENTIFIER_POINTER (identifier),
5273 TREE_PRIVATE (decl) ? "private" : "protected");
5277 else if (implementation_context && (basetype == objc_object_reference))
5279 TREE_TYPE (expr) = uprivate_record;
5280 warning ("static access to object of type `id'");
5286 /* implement @defs (<classname>) within struct bodies. */
5289 get_class_ivars (interface)
5292 if (!doing_objc_thang)
5295 return build_ivar_chain (interface, 1);
5298 /* make sure all entries in "chain" are also in "list" */
5301 check_methods (chain, list, mtype)
5310 if (!lookup_method (list, chain))
5314 if (TREE_CODE (implementation_context) == CLASS_IMPLEMENTATION_TYPE)
5315 warning ("incomplete implementation of class `%s'",
5316 IDENTIFIER_POINTER (CLASS_NAME (implementation_context)));
5317 else if (TREE_CODE (implementation_context) == CATEGORY_IMPLEMENTATION_TYPE)
5318 warning ("incomplete implementation of category `%s'",
5319 IDENTIFIER_POINTER (CLASS_SUPER_NAME (implementation_context)));
5322 warning ("method definition for `%c%s' not found",
5323 mtype, IDENTIFIER_POINTER (METHOD_SEL_NAME (chain)));
5325 chain = TREE_CHAIN (chain);
5331 conforms_to_protocol (class, protocol)
5337 tree p = CLASS_PROTOCOL_LIST (class);
5338 while (p && TREE_VALUE (p) != TREE_VALUE (protocol))
5342 tree super = (CLASS_SUPER_NAME (class)
5343 ? lookup_interface (CLASS_SUPER_NAME (class))
5345 int tmp = super ? conforms_to_protocol (super, protocol) : 0;
5349 protocol = TREE_CHAIN (protocol);
5354 /* Make sure all methods in CHAIN are accessible as MTYPE methods in
5355 CONTEXT. This is one of two mechanisms to check protocol integrity
5359 check_methods_accessible (chain, context, mtype)
5361 tree context; /* implementation_context */
5366 tree base_context = context;
5370 context = base_context;
5374 list = CLASS_CLS_METHODS (context);
5376 list = CLASS_NST_METHODS (context);
5378 if (lookup_method (list, chain))
5381 else if (TREE_CODE (context) == CLASS_IMPLEMENTATION_TYPE
5382 || TREE_CODE (context) == CLASS_INTERFACE_TYPE)
5383 context = (CLASS_SUPER_NAME (context)
5384 ? lookup_interface (CLASS_SUPER_NAME (context))
5387 else if (TREE_CODE (context) == CATEGORY_IMPLEMENTATION_TYPE
5388 || TREE_CODE (context) == CATEGORY_INTERFACE_TYPE)
5389 context = (CLASS_NAME (context)
5390 ? lookup_interface (CLASS_NAME (context))
5396 if (context == NULL_TREE)
5400 if (TREE_CODE (implementation_context)
5401 == CLASS_IMPLEMENTATION_TYPE)
5402 warning ("incomplete implementation of class `%s'",
5404 (CLASS_NAME (implementation_context)));
5405 else if (TREE_CODE (implementation_context)
5406 == CATEGORY_IMPLEMENTATION_TYPE)
5407 warning ("incomplete implementation of category `%s'",
5409 (CLASS_SUPER_NAME (implementation_context)));
5412 warning ("method definition for `%c%s' not found",
5413 mtype, IDENTIFIER_POINTER (METHOD_SEL_NAME (chain)));
5416 chain = TREE_CHAIN (chain); /* next method... */
5422 check_protocols (proto_list, type, name)
5427 for ( ; proto_list; proto_list = TREE_CHAIN (proto_list))
5429 tree p = TREE_VALUE (proto_list);
5431 if (TREE_CODE (p) == PROTOCOL_INTERFACE_TYPE)
5435 /* Ensure that all protocols have bodies! */
5436 if (flag_warn_protocol) {
5437 f1 = check_methods (PROTOCOL_CLS_METHODS (p),
5438 CLASS_CLS_METHODS (implementation_context),
5440 f2 = check_methods (PROTOCOL_NST_METHODS (p),
5441 CLASS_NST_METHODS (implementation_context),
5444 f1 = check_methods_accessible (PROTOCOL_CLS_METHODS (p),
5445 implementation_context,
5447 f2 = check_methods_accessible (PROTOCOL_NST_METHODS (p),
5448 implementation_context,
5453 warning ("%s `%s' does not fully implement the `%s' protocol",
5454 type, name, IDENTIFIER_POINTER (PROTOCOL_NAME (p)));
5458 ; /* an identifier...if we could not find a protocol. */
5460 /* Check protocols recursively. */
5461 if (PROTOCOL_LIST (p))
5464 = lookup_interface (CLASS_SUPER_NAME (implementation_template));
5465 if (! conforms_to_protocol (super_class, PROTOCOL_LIST (p)))
5466 check_protocols (PROTOCOL_LIST (p), type, name);
5471 /* Make sure that the class CLASS_NAME is defined
5472 CODE says which kind of thing CLASS_NAME ought to be.
5473 It can be CLASS_INTERFACE_TYPE, CLASS_IMPLEMENTATION_TYPE,
5474 CATEGORY_INTERFACE_TYPE, or CATEGORY_IMPLEMENTATION_TYPE.
5476 If CODE is CLASS_INTERFACE_TYPE, we also do a push_obstacks_nochange
5477 whose matching pop is in continue_class. */
5480 start_class (code, class_name, super_name, protocol_list)
5481 enum tree_code code;
5488 if (code == CLASS_INTERFACE_TYPE)
5490 push_obstacks_nochange ();
5491 end_temporary_allocation ();
5494 if (!doing_objc_thang)
5497 class = make_node (code);
5498 TYPE_BINFO (class) = make_tree_vec (5);
5500 CLASS_NAME (class) = class_name;
5501 CLASS_SUPER_NAME (class) = super_name;
5502 CLASS_CLS_METHODS (class) = NULL_TREE;
5504 if (! is_class_name (class_name) && (decl = lookup_name (class_name)))
5506 error ("`%s' redeclared as different kind of symbol",
5507 IDENTIFIER_POINTER (class_name));
5508 error_with_decl (decl, "previous declaration of `%s'");
5511 if (code == CLASS_IMPLEMENTATION_TYPE)
5514 static tree implemented_classes = 0;
5515 tree chain = implemented_classes;
5516 for (chain = implemented_classes; chain; chain = TREE_CHAIN (chain))
5517 if (TREE_VALUE (chain) == class_name)
5519 error ("reimplementation of class `%s'",
5520 IDENTIFIER_POINTER (class_name));
5521 return error_mark_node;
5523 implemented_classes = perm_tree_cons (NULLT, class_name,
5524 implemented_classes);
5527 /* pre-build the following entities - for speed/convenience. */
5529 self_id = get_identifier ("self");
5531 ucmd_id = get_identifier ("_cmd");
5533 if (!objc_super_template)
5534 objc_super_template = build_super_template ();
5536 method_slot = 0; /* reset for multiple classes per file */
5538 implementation_context = class;
5540 /* lookup the interface for this implementation. */
5542 if (!(implementation_template = lookup_interface (class_name)))
5544 warning ("Cannot find interface declaration for `%s'",
5545 IDENTIFIER_POINTER (class_name));
5546 add_class (implementation_template = implementation_context);
5549 /* if a super class has been specified in the implementation,
5550 insure it conforms to the one specified in the interface */
5553 && (super_name != CLASS_SUPER_NAME (implementation_template)))
5555 tree previous_name = CLASS_SUPER_NAME (implementation_template);
5556 char *name = previous_name ? IDENTIFIER_POINTER (previous_name) : "";
5557 error ("conflicting super class name `%s'",
5558 IDENTIFIER_POINTER (super_name));
5559 error ("previous declaration of `%s'", name);
5561 else if (! super_name)
5563 CLASS_SUPER_NAME (implementation_context)
5564 = CLASS_SUPER_NAME (implementation_template);
5567 else if (code == CLASS_INTERFACE_TYPE)
5569 if (lookup_interface (class_name))
5570 warning ("duplicate interface declaration for class `%s'",
5571 IDENTIFIER_POINTER (class_name));
5576 CLASS_PROTOCOL_LIST (class)
5577 = lookup_and_install_protocols (protocol_list);
5579 else if (code == CATEGORY_INTERFACE_TYPE)
5581 tree class_category_is_assoc_with;
5583 /* for a category, class_name is really the name of the class that
5584 the following set of methods will be associated with...we must
5585 find the interface so that can derive the objects template */
5587 if (!(class_category_is_assoc_with = lookup_interface (class_name)))
5589 error ("Cannot find interface declaration for `%s'",
5590 IDENTIFIER_POINTER (class_name));
5594 add_category (class_category_is_assoc_with, class);
5597 CLASS_PROTOCOL_LIST (class)
5598 = lookup_and_install_protocols (protocol_list);
5600 else if (code == CATEGORY_IMPLEMENTATION_TYPE)
5602 /* pre-build the following entities - for speed/convenience. */
5604 self_id = get_identifier ("self");
5606 ucmd_id = get_identifier ("_cmd");
5608 if (!objc_super_template)
5609 objc_super_template = build_super_template ();
5611 method_slot = 0; /* reset for multiple classes per file */
5613 implementation_context = class;
5615 /* for a category, class_name is really the name of the class that
5616 the following set of methods will be associated with...we must
5617 find the interface so that can derive the objects template */
5619 if (!(implementation_template = lookup_interface (class_name)))
5621 error ("Cannot find interface declaration for `%s'",
5622 IDENTIFIER_POINTER (class_name));
5630 continue_class (class)
5633 if (TREE_CODE (class) == CLASS_IMPLEMENTATION_TYPE
5634 || TREE_CODE (class) == CATEGORY_IMPLEMENTATION_TYPE)
5636 struct imp_entry *imp_entry;
5639 /* check consistency of the instance variables. */
5641 if (CLASS_IVARS (class))
5642 check_ivars (implementation_template, class);
5644 /* code generation */
5646 ivar_context = build_private_template (implementation_template);
5648 if (!objc_class_template)
5649 build_class_template ();
5651 if (!(imp_entry = (struct imp_entry *) xmalloc (sizeof (struct imp_entry))))
5652 perror ("unable to allocate in objc-tree.c");
5654 imp_entry->next = imp_list;
5655 imp_entry->imp_context = class;
5656 imp_entry->imp_template = implementation_template;
5658 synth_forward_declarations ();
5659 imp_entry->class_decl = UOBJC_CLASS_decl;
5660 imp_entry->meta_decl = UOBJC_METACLASS_decl;
5662 /* append to front and increment count */
5663 imp_list = imp_entry;
5664 if (TREE_CODE (class) == CLASS_IMPLEMENTATION_TYPE)
5669 return ivar_context;
5671 else if (TREE_CODE (class) == CLASS_INTERFACE_TYPE)
5673 tree record = xref_tag (RECORD_TYPE, CLASS_NAME (class));
5675 if (!TYPE_FIELDS (record))
5677 finish_struct (record, build_ivar_chain (class, 0));
5678 CLASS_STATIC_TEMPLATE (class) = record;
5680 /* mark this record as a class template - for static typing */
5681 TREE_STATIC_TEMPLATE (record) = 1;
5686 return error_mark_node;
5689 /* This is called once we see the "@end" in an interface/implementation. */
5692 finish_class (class)
5695 if (TREE_CODE (class) == CLASS_IMPLEMENTATION_TYPE)
5697 /* all code generation is done in finish_objc */
5699 if (implementation_template != implementation_context)
5701 /* ensure that all method listed in the interface contain bodies! */
5702 check_methods (CLASS_CLS_METHODS (implementation_template),
5703 CLASS_CLS_METHODS (implementation_context), '+');
5704 check_methods (CLASS_NST_METHODS (implementation_template),
5705 CLASS_NST_METHODS (implementation_context), '-');
5707 if (CLASS_PROTOCOL_LIST (implementation_template))
5708 check_protocols (CLASS_PROTOCOL_LIST (implementation_template),
5710 IDENTIFIER_POINTER (CLASS_NAME (implementation_context)));
5713 else if (TREE_CODE (class) == CATEGORY_IMPLEMENTATION_TYPE)
5715 tree category = CLASS_CATEGORY_LIST (implementation_template);
5717 /* find the category interface from the class it is associated with */
5720 if (CLASS_SUPER_NAME (class) == CLASS_SUPER_NAME (category))
5722 category = CLASS_CATEGORY_LIST (category);
5727 /* ensure that all method listed in the interface contain bodies! */
5728 check_methods (CLASS_CLS_METHODS (category),
5729 CLASS_CLS_METHODS (implementation_context), '+');
5730 check_methods (CLASS_NST_METHODS (category),
5731 CLASS_NST_METHODS (implementation_context), '-');
5733 if (CLASS_PROTOCOL_LIST (category))
5734 check_protocols (CLASS_PROTOCOL_LIST (category),
5736 IDENTIFIER_POINTER (CLASS_SUPER_NAME (implementation_context)));
5739 else if (TREE_CODE (class) == CLASS_INTERFACE_TYPE)
5742 char *class_name = IDENTIFIER_POINTER (CLASS_NAME (class));
5743 char *string = (char *) alloca (strlen (class_name) + 3);
5745 /* extern struct objc_object *_<my_name>; */
5747 sprintf (string, "_%s", class_name);
5749 decl_specs = build_tree_list (NULLT, ridpointers[(int) RID_EXTERN]);
5750 decl_specs = tree_cons (NULLT, objc_object_reference, decl_specs);
5751 define_decl (build1 (INDIRECT_REF, NULLT, get_identifier (string)),
5757 add_protocol (protocol)
5760 /* put protocol on list in reverse order */
5761 TREE_CHAIN (protocol) = protocol_chain;
5762 protocol_chain = protocol;
5763 return protocol_chain;
5767 lookup_protocol (ident)
5772 for (chain = protocol_chain; chain; chain = TREE_CHAIN (chain))
5774 if (ident == PROTOCOL_NAME (chain))
5781 start_protocol (code, name, list)
5782 enum tree_code code;
5788 if (!doing_objc_thang)
5791 /* This is as good a place as any. Need to invoke push_tag_toplevel. */
5792 if (!objc_protocol_template)
5793 objc_protocol_template = build_protocol_template ();
5795 protocol = make_node (code);
5796 TYPE_BINFO (protocol) = make_tree_vec (2);
5798 PROTOCOL_NAME (protocol) = name;
5799 PROTOCOL_LIST (protocol) = list;
5801 lookup_and_install_protocols (list);
5803 if (lookup_protocol (name))
5804 warning ("duplicate declaration for protocol `%s'",
5805 IDENTIFIER_POINTER (name));
5807 add_protocol (protocol);
5809 PROTOCOL_FORWARD_DECL (protocol) = NULL_TREE;
5815 finish_protocol (protocol)
5821 /* "Encode" a data type into a string, which grows in util_obstack.
5822 ??? What is the FORMAT? Someone please document this! */
5825 encode_type_qualifiers (declspecs)
5830 for (spec = declspecs; spec; spec = TREE_CHAIN (spec))
5832 if (ridpointers[(int) RID_CONST] == TREE_VALUE (spec))
5833 obstack_1grow (&util_obstack, 'r');
5834 else if (ridpointers[(int) RID_IN] == TREE_VALUE (spec))
5835 obstack_1grow (&util_obstack, 'n');
5836 else if (ridpointers[(int) RID_INOUT] == TREE_VALUE (spec))
5837 obstack_1grow (&util_obstack, 'N');
5838 else if (ridpointers[(int) RID_OUT] == TREE_VALUE (spec))
5839 obstack_1grow (&util_obstack, 'o');
5840 else if (ridpointers[(int) RID_BYCOPY] == TREE_VALUE (spec))
5841 obstack_1grow (&util_obstack, 'O');
5842 else if (ridpointers[(int) RID_ONEWAY] == TREE_VALUE (spec))
5843 obstack_1grow (&util_obstack, 'V');
5847 /* Encode a pointer type. */
5850 encode_pointer (type, curtype, format)
5855 tree pointer_to = TREE_TYPE (type);
5857 if (TREE_CODE (pointer_to) == RECORD_TYPE)
5859 if (TYPE_NAME (pointer_to)
5860 && TREE_CODE (TYPE_NAME (pointer_to)) == IDENTIFIER_NODE)
5862 char *name = IDENTIFIER_POINTER (TYPE_NAME (pointer_to));
5864 if (strcmp (name, TAG_OBJECT) == 0) /* '@' */
5866 obstack_1grow (&util_obstack, '@');
5869 else if (TREE_STATIC_TEMPLATE (pointer_to))
5871 if (generating_instance_variables)
5873 obstack_1grow (&util_obstack, '@');
5874 obstack_1grow (&util_obstack, '"');
5875 obstack_grow (&util_obstack, name, strlen (name));
5876 obstack_1grow (&util_obstack, '"');
5881 obstack_1grow (&util_obstack, '@');
5885 else if (strcmp (name, TAG_CLASS) == 0) /* '#' */
5887 obstack_1grow (&util_obstack, '#');
5890 #ifndef OBJC_INT_SELECTORS
5891 else if (strcmp (name, TAG_SELECTOR) == 0) /* ':' */
5893 obstack_1grow (&util_obstack, ':');
5896 #endif /* OBJC_INT_SELECTORS */
5899 else if (TREE_CODE (pointer_to) == INTEGER_TYPE
5900 && TYPE_MODE (pointer_to) == QImode)
5902 obstack_1grow (&util_obstack, '*');
5906 /* we have a type that does not get special treatment... */
5908 /* NeXT extension */
5909 obstack_1grow (&util_obstack, '^');
5910 encode_type (pointer_to, curtype, format);
5914 encode_array (type, curtype, format)
5919 tree an_int_cst = TYPE_SIZE (type);
5920 tree array_of = TREE_TYPE (type);
5923 /* An incomplete array is treated like a pointer. */
5924 if (an_int_cst == NULL)
5926 /* split for obvious reasons. North-Keys 30 Mar 1991 */
5927 encode_pointer (type, curtype, format);
5931 sprintf (buffer, "[%d",
5932 (TREE_INT_CST_LOW (an_int_cst)
5933 / TREE_INT_CST_LOW (TYPE_SIZE (array_of))));
5934 obstack_grow (&util_obstack, buffer, strlen (buffer));
5935 encode_type (array_of, curtype, format);
5936 obstack_1grow (&util_obstack, ']');
5941 encode_aggregate (type, curtype, format)
5946 enum tree_code code = TREE_CODE (type);
5952 if (obstack_object_size (&util_obstack) > 0
5953 && *(obstack_next_free (&util_obstack) - 1) == '^')
5955 tree name = TYPE_NAME (type);
5957 /* we have a reference - this is a NeXT extension */
5959 if (obstack_object_size (&util_obstack) - curtype == 1
5960 && format == OBJC_ENCODE_INLINE_DEFS)
5962 /* output format of struct for first level only! */
5964 tree fields = TYPE_FIELDS (type);
5966 if (name && TREE_CODE (name) == IDENTIFIER_NODE)
5968 obstack_1grow (&util_obstack, '{');
5969 obstack_grow (&util_obstack,
5970 IDENTIFIER_POINTER (name),
5971 strlen (IDENTIFIER_POINTER (name)));
5972 obstack_1grow (&util_obstack, '=');
5975 obstack_grow (&util_obstack, "{?=", 3);
5977 for ( ; fields; fields = TREE_CHAIN (fields))
5978 encode_field_decl (fields, curtype, format);
5979 obstack_1grow (&util_obstack, '}');
5981 else if (name && TREE_CODE (name) == IDENTIFIER_NODE)
5983 obstack_1grow (&util_obstack, '{');
5984 obstack_grow (&util_obstack,
5985 IDENTIFIER_POINTER (name),
5986 strlen (IDENTIFIER_POINTER (name)));
5987 obstack_1grow (&util_obstack, '}');
5989 else /* we have an untagged structure or a typedef */
5990 obstack_grow (&util_obstack, "{?}", 3);
5994 tree name = TYPE_NAME (type);
5995 tree fields = TYPE_FIELDS (type);
5997 if (format == OBJC_ENCODE_INLINE_DEFS
5998 || generating_instance_variables)
6000 obstack_1grow (&util_obstack, '{');
6001 if (name && TREE_CODE (name) == IDENTIFIER_NODE)
6002 obstack_grow (&util_obstack,
6003 IDENTIFIER_POINTER (name),
6004 strlen (IDENTIFIER_POINTER (name)));
6006 obstack_1grow (&util_obstack, '?');
6008 obstack_1grow (&util_obstack, '=');
6010 for (; fields; fields = TREE_CHAIN (fields))
6012 if (generating_instance_variables)
6014 tree fname = DECL_NAME (fields);
6016 obstack_1grow (&util_obstack, '"');
6017 if (fname && TREE_CODE (fname) == IDENTIFIER_NODE)
6019 obstack_grow (&util_obstack,
6020 IDENTIFIER_POINTER (fname),
6021 strlen (IDENTIFIER_POINTER (fname)));
6023 obstack_1grow (&util_obstack, '"');
6025 encode_field_decl (fields, curtype, format);
6027 obstack_1grow (&util_obstack, '}');
6031 obstack_1grow (&util_obstack, '{');
6032 if (name && TREE_CODE (name) == IDENTIFIER_NODE)
6033 obstack_grow (&util_obstack,
6034 IDENTIFIER_POINTER (name),
6035 strlen (IDENTIFIER_POINTER (name)));
6036 else /* we have an untagged structure or a typedef */
6037 obstack_1grow (&util_obstack, '?');
6038 obstack_1grow (&util_obstack, '}');
6045 if (*obstack_next_free (&util_obstack) == '^'
6046 || format != OBJC_ENCODE_INLINE_DEFS)
6048 /* we have a reference - this is a NeXT extension--
6049 or we don't want the details. */
6050 if (TYPE_NAME (type)
6051 && TREE_CODE (TYPE_NAME (type)) == IDENTIFIER_NODE)
6053 obstack_1grow (&util_obstack, '(');
6054 obstack_grow (&util_obstack,
6055 IDENTIFIER_POINTER (TYPE_NAME (type)),
6056 strlen (IDENTIFIER_POINTER (TYPE_NAME (type))));
6057 obstack_1grow (&util_obstack, ')');
6059 else /* we have an untagged structure or a typedef */
6060 obstack_grow (&util_obstack, "(?)", 3);
6064 tree fields = TYPE_FIELDS (type);
6065 obstack_1grow (&util_obstack, '(');
6066 for ( ; fields; fields = TREE_CHAIN (fields))
6067 encode_field_decl (fields, curtype, format);
6068 obstack_1grow (&util_obstack, ')');
6074 obstack_1grow (&util_obstack, 'i');
6079 /* Support bitfields, the current version of Objective-C does not support
6080 them. the string will consist of one or more "b:n"'s where n is an
6081 integer describing the width of the bitfield. Currently, classes in
6082 the kit implement a method "-(char *)describeBitfieldStruct:" that
6083 simulates this...if they do not implement this method, the archiver
6084 assumes the bitfield is 16 bits wide (padded if necessary) and packed
6085 according to the GNU compiler. After looking at the "kit", it appears
6086 that all classes currently rely on this default behavior, rather than
6087 hand generating this string (which is tedious). */
6090 encode_bitfield (width, format)
6095 sprintf (buffer, "b%d", width);
6096 obstack_grow (&util_obstack, buffer, strlen (buffer));
6099 /* FORMAT will be OBJC_ENCODE_INLINE_DEFS or OBJC_ENCODE_DONT_INLINE_DEFS. */
6102 encode_type (type, curtype, format)
6107 enum tree_code code = TREE_CODE (type);
6109 if (code == INTEGER_TYPE)
6111 if (TREE_INT_CST_LOW (TYPE_MIN_VALUE (type)) == 0
6112 && TREE_INT_CST_HIGH (TYPE_MIN_VALUE (type)) == 0)
6114 /* unsigned integer types */
6116 if (TYPE_MODE (type) == QImode) /* 'C' */
6117 obstack_1grow (&util_obstack, 'C');
6118 else if (TYPE_MODE (type) == HImode) /* 'S' */
6119 obstack_1grow (&util_obstack, 'S');
6120 else if (TYPE_MODE (type) == SImode)
6122 if (type == long_unsigned_type_node)
6123 obstack_1grow (&util_obstack, 'L'); /* 'L' */
6125 obstack_1grow (&util_obstack, 'I'); /* 'I' */
6127 else if (TYPE_MODE (type) == DImode) /* 'Q' */
6128 obstack_1grow (&util_obstack, 'Q');
6130 else /* signed integer types */
6132 if (TYPE_MODE (type) == QImode) /* 'c' */
6133 obstack_1grow (&util_obstack, 'c');
6134 else if (TYPE_MODE (type) == HImode) /* 's' */
6135 obstack_1grow (&util_obstack, 's');
6136 else if (TYPE_MODE (type) == SImode) /* 'i' */
6138 if (type == long_integer_type_node)
6139 obstack_1grow (&util_obstack, 'l'); /* 'l' */
6141 obstack_1grow (&util_obstack, 'i'); /* 'i' */
6143 else if (TYPE_MODE (type) == DImode) /* 'q' */
6144 obstack_1grow (&util_obstack, 'q');
6147 else if (code == REAL_TYPE)
6149 /* floating point types */
6151 if (TYPE_MODE (type) == SFmode) /* 'f' */
6152 obstack_1grow (&util_obstack, 'f');
6153 else if (TYPE_MODE (type) == DFmode
6154 || TYPE_MODE (type) == TFmode) /* 'd' */
6155 obstack_1grow (&util_obstack, 'd');
6158 else if (code == VOID_TYPE) /* 'v' */
6159 obstack_1grow (&util_obstack, 'v');
6161 else if (code == ARRAY_TYPE)
6162 encode_array (type, curtype, format);
6164 else if (code == POINTER_TYPE)
6165 encode_pointer (type, curtype, format);
6167 else if (code == RECORD_TYPE || code == UNION_TYPE || code == ENUMERAL_TYPE)
6168 encode_aggregate (type, curtype, format);
6170 else if (code == FUNCTION_TYPE) /* '?' */
6171 obstack_1grow (&util_obstack, '?');
6175 encode_field_decl (field_decl, curtype, format)
6182 /* If this field is obviously a bitfield, or is a bitfield that has been
6183 clobbered to look like a ordinary integer mode, go ahead and generate
6184 the bitfield typing information. */
6185 type = TREE_TYPE (field_decl);
6186 if (DECL_BIT_FIELD (field_decl))
6187 encode_bitfield (DECL_FIELD_SIZE (field_decl), format);
6188 else if (TREE_CODE (TYPE_SIZE (type)) == INTEGER_CST
6189 && DECL_FIELD_SIZE (field_decl)
6190 && TYPE_MODE (type) > DECL_MODE (field_decl))
6191 encode_bitfield (DECL_FIELD_SIZE (field_decl), format);
6193 encode_type (TREE_TYPE (field_decl), curtype, format);
6197 expr_last (complex_expr)
6203 while ((next = TREE_OPERAND (complex_expr, 0)))
6204 complex_expr = next;
6205 return complex_expr;
6208 /* The selector of the current method,
6209 or NULL if we aren't compiling a method. */
6212 maybe_objc_method_name (decl)
6216 return METHOD_SEL_NAME (method_context);
6221 /* Transform a method definition into a function definition as follows:
6222 - synthesize the first two arguments, "self" and "_cmd". */
6225 start_method_def (method)
6230 /* Required to implement _msgSuper. */
6231 method_context = method;
6232 UOBJC_SUPER_decl = NULLT;
6234 pushlevel (0); /* Must be called BEFORE start_function. */
6236 /* Generate prototype declarations for arguments..."new-style". */
6238 if (TREE_CODE (method_context) == INSTANCE_METHOD_DECL)
6239 decl_specs = build_tree_list (NULLT, uprivate_record);
6241 /* really a `struct objc_class *'...however we allow people to
6242 assign to self...which changes its type midstream. */
6243 decl_specs = build_tree_list (NULLT, objc_object_reference);
6245 push_parm_decl (build_tree_list (decl_specs,
6246 build1 (INDIRECT_REF, NULLT, self_id)));
6248 #ifdef OBJC_INT_SELECTORS
6249 decl_specs = build_tree_list (NULLT, ridpointers[(int) RID_UNSIGNED]);
6250 decl_specs = tree_cons (NULLT, ridpointers[(int) RID_INT], decl_specs);
6251 push_parm_decl (build_tree_list (decl_specs, ucmd_id));
6252 #else /* not OBJC_INT_SELECTORS */
6253 decl_specs = build_tree_list (NULLT,
6254 xref_tag (RECORD_TYPE,
6255 get_identifier (TAG_SELECTOR)));
6256 push_parm_decl (build_tree_list (decl_specs,
6257 build1 (INDIRECT_REF, NULLT, ucmd_id)));
6258 #endif /* not OBJC_INT_SELECTORS */
6260 /* generate argument declarations if a keyword_decl */
6261 if (METHOD_SEL_ARGS (method))
6263 tree arglist = METHOD_SEL_ARGS (method);
6266 tree arg_spec = TREE_PURPOSE (TREE_TYPE (arglist));
6267 tree arg_decl = TREE_VALUE (TREE_TYPE (arglist));
6271 tree last_expr = expr_last (arg_decl);
6273 /* unite the abstract decl with its name */
6274 TREE_OPERAND (last_expr, 0) = KEYWORD_ARG_NAME (arglist);
6275 push_parm_decl (build_tree_list (arg_spec, arg_decl));
6276 /* unhook...restore the abstract declarator */
6277 TREE_OPERAND (last_expr, 0) = NULLT;
6280 push_parm_decl (build_tree_list (arg_spec,
6281 KEYWORD_ARG_NAME (arglist)));
6283 arglist = TREE_CHAIN (arglist);
6288 if (METHOD_ADD_ARGS (method) > (tree)1)
6290 /* we have a variable length selector - in "prototype" format */
6291 tree akey = TREE_PURPOSE (METHOD_ADD_ARGS (method));
6294 /* This must be done prior to calling pushdecl. pushdecl is
6295 going to change our chain on us. */
6296 tree nextkey = TREE_CHAIN (akey);
6304 warn_with_method (message, mtype, method)
6309 if (count_error (1) == 0)
6312 report_error_function (DECL_SOURCE_FILE (method));
6314 fprintf (stderr, "%s:%d: warning: ",
6315 DECL_SOURCE_FILE (method), DECL_SOURCE_LINE (method));
6316 bzero (errbuf, BUFSIZE);
6317 fprintf (stderr, "%s `%c%s'\n",
6318 message, mtype, gen_method_decl (method, errbuf));
6321 /* return 1 if `method' is consistent with `proto' */
6324 comp_method_with_proto (method, proto)
6327 static tree function_type = 0;
6329 /* create a function_type node once */
6332 struct obstack *ambient_obstack = current_obstack;
6334 current_obstack = &permanent_obstack;
6335 function_type = make_node (FUNCTION_TYPE);
6336 current_obstack = ambient_obstack;
6339 /* Install argument types - normally set by build_function_type. */
6340 TYPE_ARG_TYPES (function_type) = get_arg_type_list (proto, METHOD_DEF, 0);
6342 /* install return type */
6343 TREE_TYPE (function_type) = groktypename (TREE_TYPE (proto));
6345 return comptypes (TREE_TYPE (METHOD_DEFINITION (method)), function_type);
6348 /* return 1 if `proto1' is consistent with `proto2' */
6351 comp_proto_with_proto (proto1, proto2)
6352 tree proto1, proto2;
6354 static tree function_type1 = 0, function_type2 = 0;
6356 /* create a couple function_type node's once */
6357 if (!function_type1)
6359 struct obstack *ambient_obstack = current_obstack;
6361 current_obstack = &permanent_obstack;
6362 function_type1 = make_node (FUNCTION_TYPE);
6363 function_type2 = make_node (FUNCTION_TYPE);
6364 current_obstack = ambient_obstack;
6367 /* Install argument types - normally set by build_function_type. */
6368 TYPE_ARG_TYPES (function_type1) = get_arg_type_list (proto1, METHOD_REF, 0);
6369 TYPE_ARG_TYPES (function_type2) = get_arg_type_list (proto2, METHOD_REF, 0);
6371 /* install return type */
6372 TREE_TYPE (function_type1) = groktypename (TREE_TYPE (proto1));
6373 TREE_TYPE (function_type2) = groktypename (TREE_TYPE (proto2));
6375 return comptypes (function_type1, function_type2);
6378 /* - generate an identifier for the function. the format is "_n_cls",
6379 where 1 <= n <= nMethods, and cls is the name the implementation we
6381 - install the return type from the method declaration.
6382 - if we have a prototype, check for type consistency. */
6385 really_start_method (method, parmlist)
6386 tree method, parmlist;
6388 tree sc_spec, ret_spec, ret_decl, decl_specs;
6389 tree method_decl, method_id;
6390 char *buf, *sel_name, *class_name, *cat_name;
6392 /* synth the storage class & assemble the return type */
6393 sc_spec = tree_cons (NULLT, ridpointers[(int) RID_STATIC], NULLT);
6394 ret_spec = TREE_PURPOSE (TREE_TYPE (method));
6395 decl_specs = chainon (sc_spec, ret_spec);
6397 sel_name = IDENTIFIER_POINTER (METHOD_SEL_NAME (method));
6398 class_name = IDENTIFIER_POINTER (CLASS_NAME (implementation_context));
6399 cat_name = ((TREE_CODE (implementation_context)
6400 == CLASS_IMPLEMENTATION_TYPE)
6402 : IDENTIFIER_POINTER (CLASS_SUPER_NAME (implementation_context)));
6404 /* Make sure this is big enough for any plausible method label. */
6405 buf = (char *) alloca (50 + strlen (sel_name) + strlen (class_name)
6406 + (cat_name ? strlen (cat_name) : 0));
6408 OBJC_GEN_METHOD_LABEL (buf, TREE_CODE (method) == INSTANCE_METHOD_DECL,
6409 class_name, cat_name, sel_name, method_slot);
6411 method_id = get_identifier (buf);
6413 method_decl = build_nt (CALL_EXPR, method_id, parmlist, NULLT);
6415 /* check the declarator portion of the return type for the method */
6416 if ((ret_decl = TREE_VALUE (TREE_TYPE (method))))
6418 /* unite the complex decl (specified in the abstract decl) with the
6419 function decl just synthesized..(int *), (int (*)()), (int (*)[]). */
6420 tree save_expr = expr_last (ret_decl);
6422 TREE_OPERAND (save_expr, 0) = method_decl;
6423 method_decl = ret_decl;
6424 /* fool the parser into thinking it is starting a function */
6425 start_function (decl_specs, method_decl, 0);
6426 /* unhook...this has the effect of restoring the abstract declarator */
6427 TREE_OPERAND (save_expr, 0) = NULLT;
6431 TREE_VALUE (TREE_TYPE (method)) = method_decl;
6432 /* fool the parser into thinking it is starting a function */
6433 start_function (decl_specs, method_decl, 0);
6434 /* unhook...this has the effect of restoring the abstract declarator */
6435 TREE_VALUE (TREE_TYPE (method)) = NULLT;
6438 METHOD_DEFINITION (method) = current_function_decl;
6440 /* Check consistency...start_function, pushdecl, duplicate_decls. */
6442 if (implementation_template != implementation_context)
6446 if (TREE_CODE (method) == INSTANCE_METHOD_DECL)
6447 proto = lookup_instance_method_static (implementation_template,
6448 METHOD_SEL_NAME (method));
6450 proto = lookup_class_method_static (implementation_template,
6451 METHOD_SEL_NAME (method));
6453 if (proto && ! comp_method_with_proto (method, proto))
6455 char type = (TREE_CODE (method) == INSTANCE_METHOD_DECL ? '-' : '+');
6457 warn_with_method ("conflicting types for", type, method);
6458 warn_with_method ("previous declaration of", type, proto);
6463 /* The following routine is always called...this "architecture" is to
6464 accommodate "old-style" variable length selectors.
6466 - a:a b:b // prototype ; id c; id d; // old-style. */
6469 continue_method_def ()
6473 if (METHOD_ADD_ARGS (method_context) == (tree)1)
6474 /* We have a `, ...' immediately following the selector. */
6475 parmlist = get_parm_info (0);
6477 parmlist = get_parm_info (1); /* place a `void_at_end' */
6479 /* Set self_decl from the first argument...this global is used by
6480 build_ivar_reference calling build_indirect_ref. */
6481 self_decl = TREE_PURPOSE (parmlist);
6483 poplevel (0, 0, 0); /* must be called BEFORE start_function. */
6485 really_start_method (method_context, parmlist);
6487 store_parm_decls (); /* must be called AFTER start_function. */
6490 /* Called by the parser, from the `pushlevel' production. */
6495 if (!UOBJC_SUPER_decl)
6497 UOBJC_SUPER_decl = start_decl (get_identifier (UTAG_SUPER),
6498 build_tree_list (NULLT,
6499 objc_super_template),
6502 finish_decl (UOBJC_SUPER_decl, NULLT, NULLT);
6504 /* this prevents `unused variable' warnings when compiling with -Wall. */
6505 DECL_IN_SYSTEM_HEADER (UOBJC_SUPER_decl) = 1;
6509 /* _n_Method (id self, SEL sel, ...)
6511 struct objc_super _S;
6512 _msgSuper ((_S.self = self, _S.class = _cls, &_S), ...);
6516 get_super_receiver ()
6520 tree super_expr, super_expr_list;
6522 /* set receiver to self */
6523 super_expr = build_component_ref (UOBJC_SUPER_decl, self_id);
6524 super_expr = build_modify_expr (super_expr, NOP_EXPR, self_decl);
6525 super_expr_list = build_tree_list (NULLT, super_expr);
6527 /* set class to begin searching */
6528 super_expr = build_component_ref (UOBJC_SUPER_decl,
6529 get_identifier ("class"));
6531 if (TREE_CODE (implementation_context) == CLASS_IMPLEMENTATION_TYPE)
6533 /* [_cls, __cls]Super are "pre-built" in
6534 synth_forward_declarations. */
6536 super_expr = build_modify_expr (super_expr, NOP_EXPR,
6537 ((TREE_CODE (method_context)
6538 == INSTANCE_METHOD_DECL)
6540 : uucls_super_ref));
6542 else /* we have a category... */
6544 tree super_name = CLASS_SUPER_NAME (implementation_template);
6547 if (!super_name) /* Barf if super used in a category of Object. */
6549 error ("no super class declared in interface for `%s'",
6550 IDENTIFIER_POINTER (CLASS_NAME (implementation_template)));
6551 return error_mark_node;
6554 if (flag_next_runtime)
6556 super_class = get_class_reference (super_name);
6557 if (TREE_CODE (method_context) == CLASS_METHOD_DECL)
6559 = build_component_ref (build_indirect_ref (super_class, "->"),
6560 get_identifier ("isa"));
6564 add_class_reference (super_name);
6565 super_class = (TREE_CODE (method_context) == INSTANCE_METHOD_DECL
6566 ? objc_get_class_decl : objc_get_meta_class_decl);
6567 assemble_external (super_class);
6569 = build_function_call
6571 build_tree_list (NULLT,
6572 my_build_string (IDENTIFIER_LENGTH (super_name) + 1,
6573 IDENTIFIER_POINTER (super_name))));
6577 TREE_TYPE (super_class) = TREE_TYPE (ucls_super_ref);
6578 super_expr = build_modify_expr (super_expr, NOP_EXPR, super_class);
6580 chainon (super_expr_list, build_tree_list (NULL_TREE, super_expr));
6582 super_expr = build_unary_op (ADDR_EXPR, UOBJC_SUPER_decl, 0);
6583 chainon (super_expr_list, build_tree_list (NULL_TREE, super_expr));
6585 return build_compound_expr (super_expr_list);
6589 error ("[super ...] must appear in a method context");
6590 return error_mark_node;
6595 encode_method_def (func_decl)
6600 int max_parm_end = 0;
6605 encode_type (TREE_TYPE (TREE_TYPE (func_decl)),
6606 obstack_object_size (&util_obstack),
6607 OBJC_ENCODE_INLINE_DEFS);
6609 for (parms = DECL_ARGUMENTS (func_decl); parms;
6610 parms = TREE_CHAIN (parms))
6612 int parm_end = (forwarding_offset (parms)
6613 + (TREE_INT_CST_LOW (TYPE_SIZE (TREE_TYPE (parms)))
6616 if (!offset_is_register && parm_end > max_parm_end)
6617 max_parm_end = parm_end;
6620 stack_size = max_parm_end - OBJC_FORWARDING_MIN_OFFSET;
6622 sprintf (buffer, "%d", stack_size);
6623 obstack_grow (&util_obstack, buffer, strlen (buffer));
6625 /* argument types */
6626 for (parms = DECL_ARGUMENTS (func_decl); parms;
6627 parms = TREE_CHAIN (parms))
6630 encode_type (TREE_TYPE (parms),
6631 obstack_object_size (&util_obstack),
6632 OBJC_ENCODE_INLINE_DEFS);
6634 /* compute offset */
6635 sprintf (buffer, "%d", forwarding_offset (parms));
6637 /* indicate register */
6638 if (offset_is_register)
6639 obstack_1grow (&util_obstack, '+');
6641 obstack_grow (&util_obstack, buffer, strlen (buffer));
6644 obstack_1grow (&util_obstack, 0); /* null terminate string */
6645 result = get_identifier (obstack_finish (&util_obstack));
6646 obstack_free (&util_obstack, util_firstobj);
6651 finish_method_def ()
6653 METHOD_ENCODING (method_context) = encode_method_def (current_function_decl);
6655 finish_function (0);
6657 /* this must be done AFTER finish_function, since the optimizer may
6658 find "may be used before set" errors. */
6659 method_context = NULLT; /* required to implement _msgSuper. */
6663 lang_report_error_function (decl)
6668 fprintf (stderr, "In method `%s'\n",
6669 IDENTIFIER_POINTER (METHOD_SEL_NAME (method_context)));
6677 is_complex_decl (type)
6680 return (TREE_CODE (type) == ARRAY_TYPE
6681 || TREE_CODE (type) == FUNCTION_TYPE
6682 || (TREE_CODE (type) == POINTER_TYPE && ! IS_ID (type)));
6686 /* Code to convert a decl node into text for a declaration in C. */
6688 static char tmpbuf[256];
6691 adorn_decl (decl, str)
6695 enum tree_code code = TREE_CODE (decl);
6697 if (code == ARRAY_REF)
6699 tree an_int_cst = TREE_OPERAND (decl, 1);
6701 if (an_int_cst && TREE_CODE (an_int_cst) == INTEGER_CST)
6702 sprintf (str + strlen (str), "[%d]", TREE_INT_CST_LOW (an_int_cst));
6706 else if (code == ARRAY_TYPE)
6708 tree an_int_cst = TYPE_SIZE (decl);
6709 tree array_of = TREE_TYPE (decl);
6711 if (an_int_cst && TREE_CODE (an_int_cst) == INTEGER_TYPE)
6712 sprintf (str + strlen (str), "[%d]",
6713 (TREE_INT_CST_LOW (an_int_cst)
6714 / TREE_INT_CST_LOW (TYPE_SIZE (array_of))));
6718 else if (code == CALL_EXPR)
6720 tree chain = TREE_PURPOSE (TREE_OPERAND (decl, 1));
6725 gen_declaration (chain, str);
6726 chain = TREE_CHAIN (chain);
6732 else if (code == FUNCTION_TYPE)
6734 tree chain = TYPE_ARG_TYPES (decl); /* a list of types */
6737 while (chain && TREE_VALUE (chain) != void_type_node)
6739 gen_declaration (TREE_VALUE (chain), str);
6740 chain = TREE_CHAIN (chain);
6741 if (chain && TREE_VALUE (chain) != void_type_node)
6746 else if (code == INDIRECT_REF)
6748 strcpy (tmpbuf, "*");
6749 if (TREE_TYPE (decl) && TREE_CODE (TREE_TYPE (decl)) == TREE_LIST)
6753 for (chain = nreverse (copy_list (TREE_TYPE (decl)));
6755 chain = TREE_CHAIN (chain))
6757 if (TREE_CODE (TREE_VALUE (chain)) == IDENTIFIER_NODE)
6759 strcat (tmpbuf, " ");
6760 strcat (tmpbuf, IDENTIFIER_POINTER (TREE_VALUE (chain)));
6764 strcat (tmpbuf, " ");
6766 strcat (tmpbuf, str);
6767 strcpy (str, tmpbuf);
6769 else if (code == POINTER_TYPE)
6771 strcpy (tmpbuf, "*");
6772 if (TREE_READONLY (decl) || TYPE_VOLATILE (decl))
6774 if (TREE_READONLY (decl))
6775 strcat (tmpbuf, " const");
6776 if (TYPE_VOLATILE (decl))
6777 strcat (tmpbuf, " volatile");
6779 strcat (tmpbuf, " ");
6781 strcat (tmpbuf, str);
6782 strcpy (str, tmpbuf);
6787 gen_declarator (decl, buf, name)
6794 enum tree_code code = TREE_CODE (decl);
6804 op = TREE_OPERAND (decl, 0);
6806 /* we have a pointer to a function or array...(*)(), (*)[] */
6807 if ((code == ARRAY_REF || code == CALL_EXPR)
6808 && op && TREE_CODE (op) == INDIRECT_REF)
6811 str = gen_declarator (op, buf, name);
6815 strcpy (tmpbuf, "(");
6816 strcat (tmpbuf, str);
6817 strcat (tmpbuf, ")");
6818 strcpy (str, tmpbuf);
6821 adorn_decl (decl, str);
6830 /* this clause is done iteratively...rather than recursively */
6833 op = (is_complex_decl (TREE_TYPE (decl))
6834 ? TREE_TYPE (decl) : NULLT);
6836 adorn_decl (decl, str);
6838 /* we have a pointer to a function or array...(*)(), (*)[] */
6839 if (code == POINTER_TYPE
6840 && op && (TREE_CODE (op) == FUNCTION_TYPE
6841 || TREE_CODE (op) == ARRAY_TYPE))
6843 strcpy (tmpbuf, "(");
6844 strcat (tmpbuf, str);
6845 strcat (tmpbuf, ")");
6846 strcpy (str, tmpbuf);
6849 decl = (is_complex_decl (TREE_TYPE (decl))
6850 ? TREE_TYPE (decl) : NULLT);
6852 while (decl && (code = TREE_CODE (decl)));
6856 case IDENTIFIER_NODE:
6857 /* will only happen if we are processing a "raw" expr-decl. */
6858 strcpy (buf, IDENTIFIER_POINTER (decl));
6864 else /* we have an abstract declarator or a _DECL node */
6872 gen_declspecs (declspecs, buf, raw)
6881 for (chain = nreverse (copy_list (declspecs));
6882 chain; chain = TREE_CHAIN (chain))
6884 tree aspec = TREE_VALUE (chain);
6886 if (TREE_CODE (aspec) == IDENTIFIER_NODE)
6887 strcat (buf, IDENTIFIER_POINTER (aspec));
6888 else if (TREE_CODE (aspec) == RECORD_TYPE)
6890 if (TYPE_NAME (aspec))
6892 tree protocol_list = TYPE_PROTOCOL_LIST (aspec);
6894 if (! TREE_STATIC_TEMPLATE (aspec))
6895 strcat (buf, "struct ");
6896 strcat (buf, IDENTIFIER_POINTER (TYPE_NAME (aspec)));
6901 tree chain = protocol_list;
6906 strcat (buf, IDENTIFIER_POINTER (PROTOCOL_NAME (TREE_VALUE (chain))));
6907 chain = TREE_CHAIN (chain);
6915 strcat (buf, "untagged struct");
6917 else if (TREE_CODE (aspec) == UNION_TYPE)
6919 if (TYPE_NAME (aspec))
6921 if (! TREE_STATIC_TEMPLATE (aspec))
6922 strcat (buf, "union ");
6923 strcat (buf, IDENTIFIER_POINTER (TYPE_NAME (aspec)));
6926 strcat (buf, "untagged union");
6928 else if (TREE_CODE (aspec) == ENUMERAL_TYPE)
6930 if (TYPE_NAME (aspec))
6932 if (! TREE_STATIC_TEMPLATE (aspec))
6933 strcat (buf, "enum ");
6934 strcat (buf, IDENTIFIER_POINTER (TYPE_NAME (aspec)));
6937 strcat (buf, "untagged enum");
6939 else if (TREE_CODE (aspec) == TYPE_DECL && DECL_NAME (aspec))
6941 strcat (buf, IDENTIFIER_POINTER (DECL_NAME (aspec)));
6944 else if (IS_ID (aspec))
6946 tree protocol_list = TYPE_PROTOCOL_LIST (aspec);
6951 tree chain = protocol_list;
6956 strcat (buf, IDENTIFIER_POINTER (PROTOCOL_NAME (TREE_VALUE (chain))));
6957 chain = TREE_CHAIN (chain);
6964 if (TREE_CHAIN (chain))
6970 /* type qualifiers */
6972 if (TREE_READONLY (declspecs))
6973 strcat (buf, "const ");
6974 if (TYPE_VOLATILE (declspecs))
6975 strcat (buf, "volatile ");
6977 switch (TREE_CODE (declspecs))
6979 /* type specifiers */
6981 case INTEGER_TYPE: /* signed integer types */
6982 declspecs = TYPE_MAIN_VARIANT (declspecs);
6984 if (declspecs == short_integer_type_node) /* 's' */
6985 strcat (buf, "short int ");
6986 else if (declspecs == integer_type_node) /* 'i' */
6987 strcat (buf, "int ");
6988 else if (declspecs == long_integer_type_node) /* 'l' */
6989 strcat (buf, "long int ");
6990 else if (declspecs == long_long_integer_type_node) /* 'l' */
6991 strcat (buf, "long long int ");
6992 else if (declspecs == signed_char_type_node /* 'c' */
6993 || declspecs == char_type_node)
6994 strcat (buf, "char ");
6996 /* unsigned integer types */
6998 else if (declspecs == short_unsigned_type_node) /* 'S' */
6999 strcat (buf, "unsigned short ");
7000 else if (declspecs == unsigned_type_node) /* 'I' */
7001 strcat (buf, "unsigned int ");
7002 else if (declspecs == long_unsigned_type_node) /* 'L' */
7003 strcat (buf, "unsigned long ");
7004 else if (declspecs == long_long_unsigned_type_node) /* 'L' */
7005 strcat (buf, "unsigned long long ");
7006 else if (declspecs == unsigned_char_type_node) /* 'C' */
7007 strcat (buf, "unsigned char ");
7010 case REAL_TYPE: /* floating point types */
7011 declspecs = TYPE_MAIN_VARIANT (declspecs);
7013 if (declspecs == float_type_node) /* 'f' */
7014 strcat (buf, "float ");
7015 else if (declspecs == double_type_node) /* 'd' */
7016 strcat (buf, "double ");
7017 else if (declspecs == long_double_type_node) /* 'd' */
7018 strcat (buf, "long double ");
7022 if (TYPE_NAME (declspecs)
7023 && TREE_CODE (TYPE_NAME (declspecs)) == IDENTIFIER_NODE)
7025 tree protocol_list = TYPE_PROTOCOL_LIST (declspecs);
7027 if (! TREE_STATIC_TEMPLATE (declspecs))
7028 strcat (buf, "struct ");
7029 strcat (buf, IDENTIFIER_POINTER (TYPE_NAME (declspecs)));
7033 tree chain = protocol_list;
7038 strcat (buf, IDENTIFIER_POINTER (PROTOCOL_NAME (TREE_VALUE (chain))));
7039 chain = TREE_CHAIN (chain);
7047 strcat (buf, "untagged struct");
7053 if (TYPE_NAME (declspecs)
7054 && TREE_CODE (TYPE_NAME (declspecs)) == IDENTIFIER_NODE)
7056 strcat (buf, "union ");
7057 strcat (buf, IDENTIFIER_POINTER (TYPE_NAME (declspecs)));
7061 strcat (buf, "untagged union ");
7065 if (TYPE_NAME (declspecs)
7066 && TREE_CODE (TYPE_NAME (declspecs)) == IDENTIFIER_NODE)
7068 strcat (buf, "enum ");
7069 strcat (buf, IDENTIFIER_POINTER (TYPE_NAME (declspecs)));
7073 strcat (buf, "untagged enum ");
7077 strcat (buf, "void ");
7083 tree protocol_list = TYPE_PROTOCOL_LIST (declspecs);
7088 tree chain = protocol_list;
7093 strcat (buf, IDENTIFIER_POINTER (PROTOCOL_NAME (TREE_VALUE (chain))));
7094 chain = TREE_CHAIN (chain);
7106 gen_declaration (atype_or_adecl, buf)
7107 tree atype_or_adecl;
7112 if (TREE_CODE (atype_or_adecl) == TREE_LIST)
7114 tree declspecs; /* "identifier_node", "record_type" */
7115 tree declarator; /* "array_ref", "indirect_ref", "call_expr"... */
7117 /* we have a "raw", abstract declarator (typename) */
7118 declarator = TREE_VALUE (atype_or_adecl);
7119 declspecs = TREE_PURPOSE (atype_or_adecl);
7121 gen_declspecs (declspecs, buf, 1);
7125 strcat (buf, gen_declarator (declarator, declbuf, ""));
7131 tree declspecs; /* "integer_type", "real_type", "record_type"... */
7132 tree declarator; /* "array_type", "function_type", "pointer_type". */
7134 if (TREE_CODE (atype_or_adecl) == FIELD_DECL
7135 || TREE_CODE (atype_or_adecl) == PARM_DECL
7136 || TREE_CODE (atype_or_adecl) == FUNCTION_DECL)
7137 atype = TREE_TYPE (atype_or_adecl);
7139 atype = atype_or_adecl; /* assume we have a *_type node */
7141 if (is_complex_decl (atype))
7145 /* get the declaration specifier...it is at the end of the list */
7146 declarator = chain = atype;
7148 chain = TREE_TYPE (chain); /* not TREE_CHAIN (chain); */
7149 while (is_complex_decl (chain));
7158 gen_declspecs (declspecs, buf, 0);
7160 if (TREE_CODE (atype_or_adecl) == FIELD_DECL
7161 || TREE_CODE (atype_or_adecl) == PARM_DECL
7162 || TREE_CODE (atype_or_adecl) == FUNCTION_DECL)
7164 char *decl_name = (DECL_NAME (atype_or_adecl)
7165 ? IDENTIFIER_POINTER (DECL_NAME (atype_or_adecl))
7171 strcat (buf, gen_declarator (declarator, declbuf, decl_name));
7173 else if (decl_name[0])
7176 strcat (buf, decl_name);
7179 else if (declarator)
7182 strcat (buf, gen_declarator (declarator, declbuf, ""));
7188 #define RAW_TYPESPEC(meth) (TREE_VALUE (TREE_PURPOSE (TREE_TYPE (meth))))
7191 gen_method_decl (method, buf)
7197 if (RAW_TYPESPEC (method) != objc_object_reference)
7200 gen_declaration (TREE_TYPE (method), buf);
7204 chain = METHOD_SEL_ARGS (method);
7206 { /* we have a chain of keyword_decls */
7209 if (KEYWORD_KEY_NAME (chain))
7210 strcat (buf, IDENTIFIER_POINTER (KEYWORD_KEY_NAME (chain)));
7213 if (RAW_TYPESPEC (chain) != objc_object_reference)
7216 gen_declaration (TREE_TYPE (chain), buf);
7219 strcat (buf, IDENTIFIER_POINTER (KEYWORD_ARG_NAME (chain)));
7220 if ((chain = TREE_CHAIN (chain)))
7225 if (METHOD_ADD_ARGS (method) == (tree)1)
7226 strcat (buf, ", ...");
7227 else if (METHOD_ADD_ARGS (method))
7229 /* we have a tree list node as generate by get_parm_info. */
7230 chain = TREE_PURPOSE (METHOD_ADD_ARGS (method));
7231 /* know we have a chain of parm_decls */
7235 gen_declaration (chain, buf);
7236 chain = TREE_CHAIN (chain);
7240 else /* we have a unary selector */
7241 strcat (buf, IDENTIFIER_POINTER (METHOD_SEL_NAME (method)));
7249 dump_interface (fp, chain)
7253 char *buf = (char *)xmalloc (256);
7254 char *my_name = IDENTIFIER_POINTER (CLASS_NAME (chain));
7255 tree ivar_decls = CLASS_RAW_IVARS (chain);
7256 tree nst_methods = CLASS_NST_METHODS (chain);
7257 tree cls_methods = CLASS_CLS_METHODS (chain);
7259 fprintf (fp, "\n@interface %s", my_name);
7261 if (CLASS_SUPER_NAME (chain))
7263 char *super_name = IDENTIFIER_POINTER (CLASS_SUPER_NAME (chain));
7264 fprintf (fp, " : %s\n", super_name);
7271 fprintf (fp, "{\n");
7275 fprintf (fp, "\t%s;\n", gen_declaration (ivar_decls, buf));
7276 ivar_decls = TREE_CHAIN (ivar_decls);
7279 fprintf (fp, "}\n");
7285 fprintf (fp, "- %s;\n", gen_method_decl (nst_methods, buf));
7286 nst_methods = TREE_CHAIN (nst_methods);
7292 fprintf (fp, "+ %s;\n", gen_method_decl (cls_methods, buf));
7293 cls_methods = TREE_CHAIN (cls_methods);
7295 fprintf (fp, "\n@end");
7301 /* Add the special tree codes of Objective C to the tables. */
7303 #define LAST_CODE LAST_AND_UNUSED_TREE_CODE
7305 gcc_obstack_init (&util_obstack);
7306 util_firstobj = (char *) obstack_finish (&util_obstack);
7309 = (char **) xrealloc (tree_code_type,
7310 sizeof (char *) * LAST_OBJC_TREE_CODE);
7312 = (int *) xrealloc (tree_code_length,
7313 sizeof (int) * LAST_OBJC_TREE_CODE);
7315 = (char **) xrealloc (tree_code_name,
7316 sizeof (char *) * LAST_OBJC_TREE_CODE);
7317 bcopy (objc_tree_code_type,
7318 tree_code_type + (int) LAST_CODE,
7319 (((int) LAST_OBJC_TREE_CODE - (int) LAST_CODE)
7320 * sizeof (char *)));
7321 bcopy (objc_tree_code_length,
7322 tree_code_length + (int) LAST_CODE,
7323 (((int) LAST_OBJC_TREE_CODE - (int) LAST_CODE)
7325 bcopy (objc_tree_code_name,
7326 tree_code_name + (int) LAST_CODE,
7327 (((int) LAST_OBJC_TREE_CODE - (int) LAST_CODE)
7328 * sizeof (char *)));
7330 errbuf = (char *)xmalloc (BUFSIZE);
7332 synth_module_prologue ();
7338 struct imp_entry *impent;
7340 /* The internally generated initializers appear to have missing braces.
7341 Don't warn about this. */
7342 int save_warn_missing_braces = warn_missing_braces;
7343 warn_missing_braces = 0;
7345 generate_forward_declaration_to_string_table ();
7347 #ifdef OBJC_PROLOGUE
7351 if (implementation_context || class_names_chain
7352 || meth_var_names_chain || meth_var_types_chain || sel_ref_chain)
7353 generate_objc_symtab_decl ();
7355 for (impent = imp_list; impent; impent = impent->next)
7357 implementation_context = impent->imp_context;
7358 implementation_template = impent->imp_template;
7360 UOBJC_CLASS_decl = impent->class_decl;
7361 UOBJC_METACLASS_decl = impent->meta_decl;
7363 if (TREE_CODE (implementation_context) == CLASS_IMPLEMENTATION_TYPE)
7365 /* all of the following reference the string pool... */
7366 generate_ivar_lists ();
7367 generate_dispatch_tables ();
7368 generate_shared_structures ();
7372 generate_dispatch_tables ();
7373 generate_category (implementation_context);
7377 /* If we are using an array of selectors, we must always
7378 finish up the array decl even if no selectors were used. */
7379 if (! flag_next_runtime || sel_ref_chain)
7380 build_selector_translation_table ();
7383 generate_protocols ();
7385 if (implementation_context || class_names_chain
7386 || meth_var_names_chain || meth_var_types_chain || sel_ref_chain)
7388 /* Arrange for Objc data structures to be initialized at run time. */
7389 char *init_name = build_module_descriptor ();
7391 assemble_constructor (init_name);
7394 /* dump the class references...this forces the appropriate classes
7395 to be linked into the executable image, preserving unix archive
7396 semantics...this can be removed when we move to a more dynamically
7397 linked environment. */
7398 for (chain = cls_ref_chain; chain; chain = TREE_CHAIN (chain))
7400 handle_class_ref (chain);
7401 if (TREE_PURPOSE (chain))
7402 generate_classref_translation_entry (chain);
7405 for (impent = imp_list; impent; impent = impent->next)
7406 handle_impent (impent);
7408 /* dump the string table last */
7410 generate_strings ();
7412 if (flag_gen_declaration)
7414 add_class (implementation_context);
7415 dump_interface (gen_declaration_file, implementation_context);
7423 /* Run through the selector hash tables and print a warning for any
7424 selector which has multiple methods. */
7426 for (slot = 0; slot < SIZEHASHTABLE; slot++)
7427 for (hsh = cls_method_hash_list[slot]; hsh; hsh = hsh->next)
7430 tree meth = hsh->key;
7431 char type = (TREE_CODE (meth) == INSTANCE_METHOD_DECL
7435 warning ("potential selector conflict for method `%s'",
7436 IDENTIFIER_POINTER (METHOD_SEL_NAME (meth)));
7437 warn_with_method ("found", type, meth);
7438 for (loop = hsh->list; loop; loop = loop->next)
7439 warn_with_method ("found", type, loop->value);
7442 for (slot = 0; slot < SIZEHASHTABLE; slot++)
7443 for (hsh = nst_method_hash_list[slot]; hsh; hsh = hsh->next)
7446 tree meth = hsh->key;
7447 char type = (TREE_CODE (meth) == INSTANCE_METHOD_DECL
7451 warning ("potential selector conflict for method `%s'",
7452 IDENTIFIER_POINTER (METHOD_SEL_NAME (meth)));
7453 warn_with_method ("found", type, meth);
7454 for (loop = hsh->list; loop; loop = loop->next)
7455 warn_with_method ("found", type, loop->value);
7459 warn_missing_braces = save_warn_missing_braces;
7462 /* Subroutines of finish_objc. */
7465 generate_classref_translation_entry (chain)
7468 tree expr, name, decl_specs, decl, sc_spec;
7471 type = TREE_TYPE (TREE_PURPOSE (chain));
7473 expr = add_objc_string (TREE_VALUE (chain), class_names);
7474 expr = build_c_cast (type, expr); /* cast! */
7476 name = DECL_NAME (TREE_PURPOSE (chain));
7478 sc_spec = build_tree_list (NULLT, ridpointers[(int) RID_STATIC]);
7480 /* static struct objc_class * _OBJC_CLASS_REFERENCES_n = ...; */
7481 decl_specs = tree_cons (NULLT, type, sc_spec);
7483 /* the `decl' that is returned from start_decl is the one that we
7484 forward declared in `build_class_reference'. */
7485 decl = start_decl (name, decl_specs, 1);
7486 end_temporary_allocation ();
7487 finish_decl (decl, expr, NULLT);
7492 handle_class_ref (chain)
7495 char *name = IDENTIFIER_POINTER (TREE_VALUE (chain));
7496 if (! flag_next_runtime)
7499 char *string = (char *) alloca (strlen (name) + 30);
7502 sprintf (string, "%sobjc_class_name_%s",
7503 (flag_next_runtime ? "." : "__"), name);
7505 /* Make a decl for this name, so we can use its address in a tree. */
7506 decl = build_decl (VAR_DECL, get_identifier (string), char_type_node);
7507 DECL_EXTERNAL (decl) = 1;
7508 TREE_PUBLIC (decl) = 1;
7511 rest_of_decl_compilation (decl, 0, 0, 0);
7513 /* Make following constant read-only (why not)? */
7514 readonly_data_section ();
7516 exp = build1 (ADDR_EXPR, string_type_node, decl);
7518 /* Align the section properly. */
7519 assemble_constant_align (exp);
7521 /* Inform the assembler about this new external thing. */
7522 assemble_external (decl);
7524 /* Output a constant to reference this address. */
7525 output_constant (exp, int_size_in_bytes (string_type_node));
7529 /* This overreliance on our assembler (i.e. lack of portability)
7530 should be dealt with at some point. The GNU strategy (above)
7531 won't work either, but it is a start. */
7532 char *string = (char *) alloca (strlen (name) + 30);
7533 sprintf (string, ".reference .objc_class_name_%s", name);
7534 assemble_asm (my_build_string (strlen (string) + 1, string));
7539 handle_impent (impent)
7540 struct imp_entry *impent;
7542 implementation_context = impent->imp_context;
7543 implementation_template = impent->imp_template;
7545 if (TREE_CODE (impent->imp_context) == CLASS_IMPLEMENTATION_TYPE)
7547 char *class_name = IDENTIFIER_POINTER (CLASS_NAME (impent->imp_context));
7548 char *string = (char *) alloca (strlen (class_name) + 30);
7550 if (flag_next_runtime)
7552 /* Grossly unportable.
7553 People should know better than to assume
7554 such things about assembler syntax! */
7555 sprintf (string, ".objc_class_name_%s=0", class_name);
7556 assemble_asm (my_build_string (strlen (string) + 1, string));
7558 sprintf (string, ".globl .objc_class_name_%s", class_name);
7559 assemble_asm (my_build_string (strlen (string) + 1, string));
7563 sprintf (string, "%sobjc_class_name_%s",
7564 (flag_next_runtime ? "." : "__"), class_name);
7565 assemble_global (string);
7566 assemble_label (string);
7569 else if (TREE_CODE (impent->imp_context) == CATEGORY_IMPLEMENTATION_TYPE)
7571 char *class_name = IDENTIFIER_POINTER (CLASS_NAME (impent->imp_context));
7572 char *class_super_name
7573 = IDENTIFIER_POINTER (CLASS_SUPER_NAME (impent->imp_context));
7574 char *string = (char *) alloca (strlen (class_name)
7575 + strlen (class_super_name) + 30);
7577 /* Do the same for categories. Even though no references to these
7578 symbols are generated automatically by the compiler, it gives
7579 you a handle to pull them into an archive by hand. */
7580 if (flag_next_runtime)
7582 /* Grossly unportable. */
7583 sprintf (string, ".objc_category_name_%s_%s=0",
7584 class_name, class_super_name);
7585 assemble_asm (my_build_string (strlen (string) + 1, string));
7587 sprintf (string, ".globl .objc_category_name_%s_%s",
7588 class_name, class_super_name);
7589 assemble_asm (my_build_string (strlen (string) + 1, string));
7593 sprintf (string, "%sobjc_category_name_%s_%s",
7594 (flag_next_runtime ? "." : "__"),
7595 class_name, class_super_name);
7596 assemble_global (string);
7597 assemble_label (string);
7608 char *buf = (char *)xmalloc (256);
7610 { /* dump function prototypes */
7611 tree loop = UOBJC_MODULES_decl;
7613 fprintf (fp, "\n\nfunction prototypes:\n");
7616 if (TREE_CODE (loop) == FUNCTION_DECL && DECL_INITIAL (loop))
7618 /* we have a function definition - generate prototype */
7619 bzero (errbuf, BUFSIZE);
7620 gen_declaration (loop, errbuf);
7621 fprintf (fp, "%s;\n", errbuf);
7623 loop = TREE_CHAIN (loop);
7626 { /* dump global chains */
7628 int i, index = 0, offset = 0;
7631 for (i = 0; i < SIZEHASHTABLE; i++)
7633 if (hashlist = nst_method_hash_list[i])
7635 fprintf (fp, "\n\nnst_method_hash_list[%d]:\n", i);
7639 fprintf (fp, "-%s;\n", gen_method_decl (hashlist->key, buf));
7640 hashlist = hashlist->next;
7645 for (i = 0; i < SIZEHASHTABLE; i++)
7647 if (hashlist = cls_method_hash_list[i])
7649 fprintf (fp, "\n\ncls_method_hash_list[%d]:\n", i);
7653 fprintf (fp, "-%s;\n", gen_method_decl (hashlist->key, buf));
7654 hashlist = hashlist->next;
7659 fprintf (fp, "\nsel_refdef_chain:\n");
7660 for (loop = sel_refdef_chain; loop; loop = TREE_CHAIN (loop))
7662 fprintf (fp, "(index: %4d offset: %4d) %s\n", index, offset,
7663 IDENTIFIER_POINTER (TREE_VALUE (loop)));
7665 /* add one for the '\0' character */
7666 offset += IDENTIFIER_LENGTH (TREE_VALUE (loop)) + 1;
7668 fprintf (fp, "\n (max_selector_index: %4d.\n", max_selector_index);
7674 print_lang_statistics ()