1 /* Implement classes and message passing for Objective C.
2 Copyright (C) 1992, 1993, 1994, 1995, 1997 Free Software Foundation, Inc.
3 Contributed by Steve Naroff.
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, 59 Temple Place - Suite 330,
20 Boston, MA 02111-1307, USA. */
22 /* Purpose: This module implements the Objective-C 4.0 language.
24 compatibility issues (with the Stepstone translator):
26 - does not recognize the following 3.3 constructs.
27 @requires, @classes, @messages, = (...)
28 - methods with variable arguments must conform to ANSI standard.
29 - tagged structure definitions that appear in BOTH the interface
30 and implementation are not allowed.
31 - public/private: all instance variables are public within the
32 context of the implementation...I consider this to be a bug in
34 - statically allocated objects are not supported. the user will
35 receive an error if this service is requested.
37 code generation `options':
39 - OBJC_INT_SELECTORS */
54 /* This is the default way of generating a method name. */
55 /* I am not sure it is really correct.
56 Perhaps there's a danger that it will make name conflicts
57 if method names contain underscores. -- rms. */
58 #ifndef OBJC_GEN_METHOD_LABEL
59 #define OBJC_GEN_METHOD_LABEL(BUF, IS_INST, CLASS_NAME, CAT_NAME, SEL_NAME, NUM) \
62 sprintf ((BUF), "_%s_%s_%s_%s", \
63 ((IS_INST) ? "i" : "c"), \
65 ((CAT_NAME)? (CAT_NAME) : ""), \
67 for (temp = (BUF); *temp; temp++) \
68 if (*temp == ':') *temp = '_'; \
72 /* These need specifying. */
73 #ifndef OBJC_FORWARDING_STACK_OFFSET
74 #define OBJC_FORWARDING_STACK_OFFSET 0
77 #ifndef OBJC_FORWARDING_MIN_OFFSET
78 #define OBJC_FORWARDING_MIN_OFFSET 0
81 /* Define the special tree codes that we use. */
83 /* Table indexed by tree code giving a string containing a character
84 classifying the tree code. Possibilities are
85 t, d, s, c, r, <, 1 and 2. See objc-tree.def for details. */
87 #define DEFTREECODE(SYM, NAME, TYPE, LENGTH) TYPE,
89 char objc_tree_code_type[] = {
91 #include "objc-tree.def"
95 /* Table indexed by tree code giving number of expression
96 operands beyond the fixed part of the node structure.
97 Not used for types or decls. */
99 #define DEFTREECODE(SYM, NAME, TYPE, LENGTH) LENGTH,
101 int objc_tree_code_length[] = {
103 #include "objc-tree.def"
107 /* Names of tree components.
108 Used for printing out the tree and error messages. */
109 #define DEFTREECODE(SYM, NAME, TYPE, LEN) NAME,
111 char *objc_tree_code_name[] = {
113 #include "objc-tree.def"
117 /* Set up for use of obstacks. */
121 #define obstack_chunk_alloc xmalloc
122 #define obstack_chunk_free free
124 /* This obstack is used to accumulate the encoding of a data type. */
125 static struct obstack util_obstack;
126 /* This points to the beginning of obstack contents,
127 so we can free the whole contents. */
130 /* List of classes with list of their static instances. */
131 static tree objc_static_instances = NULL_TREE;
133 /* The declaration of the array administrating the static instances. */
134 static tree static_instances_decl = NULL_TREE;
136 /* for encode_method_def */
140 #define OBJC_VERSION (flag_next_runtime ? 5 : 8)
141 #define PROTOCOL_VERSION 2
143 #define OBJC_ENCODE_INLINE_DEFS 0
144 #define OBJC_ENCODE_DONT_INLINE_DEFS 1
146 /*** Private Interface (procedures) ***/
148 /* Used by compile_file. */
150 static void init_objc PROTO((void));
151 static void finish_objc PROTO((void));
153 /* Code generation. */
155 static void synth_module_prologue PROTO((void));
156 static tree build_constructor PROTO((tree, tree));
157 static char *build_module_descriptor PROTO((void));
158 static tree init_module_descriptor PROTO((tree));
159 static tree build_objc_method_call PROTO((int, tree, tree,
161 static void generate_strings PROTO((void));
162 static tree get_proto_encoding PROTO((tree));
163 static void build_selector_translation_table PROTO((void));
164 static tree build_ivar_chain PROTO((tree, int));
166 static tree objc_add_static_instance PROTO((tree, tree));
168 static tree build_ivar_template PROTO((void));
169 static tree build_method_template PROTO((void));
170 static tree build_private_template PROTO((tree));
171 static void build_class_template PROTO((void));
172 static void build_selector_template PROTO((void));
173 static void build_category_template PROTO((void));
174 static tree build_super_template PROTO((void));
175 static tree build_category_initializer PROTO((tree, tree, tree,
177 static tree build_protocol_initializer PROTO((tree, tree, tree,
180 static void synth_forward_declarations PROTO((void));
181 static void generate_ivar_lists PROTO((void));
182 static void generate_dispatch_tables PROTO((void));
183 static void generate_shared_structures PROTO((void));
184 static tree generate_protocol_list PROTO((tree));
185 static void generate_forward_declaration_to_string_table PROTO((void));
186 static void build_protocol_reference PROTO((tree));
188 static tree init_selector PROTO((int));
189 static tree build_keyword_selector PROTO((tree));
190 static tree synth_id_with_class_suffix PROTO((char *, tree));
192 static void generate_static_references PROTO((void));
193 static int check_methods_accessible PROTO((tree, tree,
195 static void encode_aggregate_within PROTO((tree, int, int,
198 /* We handle printing method names ourselves for ObjC */
199 extern char *(*decl_printable_name) ();
201 /* Misc. bookkeeping */
203 typedef struct hashed_entry *hash;
204 typedef struct hashed_attribute *attr;
206 struct hashed_attribute
218 static void hash_init PROTO((void));
219 static void hash_enter PROTO((hash *, tree));
220 static hash hash_lookup PROTO((hash *, tree));
221 static void hash_add_attr PROTO((hash, tree));
222 static tree lookup_method PROTO((tree, tree));
223 static tree lookup_instance_method_static PROTO((tree, tree));
224 static tree lookup_class_method_static PROTO((tree, tree));
225 static tree add_class PROTO((tree));
226 static void add_category PROTO((tree, tree));
230 class_names, /* class, category, protocol, module names */
231 meth_var_names, /* method and variable names */
232 meth_var_types /* method and variable type descriptors */
235 static tree add_objc_string PROTO((tree,
236 enum string_section));
237 static tree get_objc_string_decl PROTO((tree,
238 enum string_section));
239 static tree build_objc_string_decl PROTO((tree,
240 enum string_section));
241 static tree build_selector_reference_decl PROTO((tree));
243 /* Protocol additions. */
245 static tree add_protocol PROTO((tree));
246 static tree lookup_protocol PROTO((tree));
247 static tree lookup_and_install_protocols PROTO((tree));
251 static void encode_type_qualifiers PROTO((tree));
252 static void encode_pointer PROTO((tree, int, int));
253 static void encode_array PROTO((tree, int, int));
254 static void encode_aggregate PROTO((tree, int, int));
255 static void encode_bitfield PROTO((int, int));
256 static void encode_type PROTO((tree, int, int));
257 static void encode_field_decl PROTO((tree, int, int));
259 static void really_start_method PROTO((tree, tree));
260 static int comp_method_with_proto PROTO((tree, tree));
261 static int comp_proto_with_proto PROTO((tree, tree));
262 static tree get_arg_type_list PROTO((tree, int, int));
263 static tree expr_last PROTO((tree));
265 /* Utilities for debugging and error diagnostics. */
267 static void warn_with_method PROTO((char *, int, tree));
268 static void error_with_ivar PROTO((char *, tree, tree));
269 static char *gen_method_decl PROTO((tree, char *));
270 static char *gen_declaration PROTO((tree, char *));
271 static char *gen_declarator PROTO((tree, char *, char *));
272 static int is_complex_decl PROTO((tree));
273 static void adorn_decl PROTO((tree, char *));
274 static void dump_interface PROTO((FILE *, tree));
276 /* Everything else. */
278 static void objc_fatal PROTO((void));
279 static tree define_decl PROTO((tree, tree));
280 static tree lookup_method_in_protocol_list PROTO((tree, tree, int));
281 static tree lookup_protocol_in_reflist PROTO((tree, tree));
282 static tree create_builtin_decl PROTO((enum tree_code,
284 static tree my_build_string PROTO((int, char *));
285 static void build_objc_symtab_template PROTO((void));
286 static tree init_def_list PROTO((tree));
287 static tree init_objc_symtab PROTO((tree));
288 static void forward_declare_categories PROTO((void));
289 static void generate_objc_symtab_decl PROTO((void));
290 static tree build_selector PROTO((tree));
291 static tree build_msg_pool_reference PROTO((int));
292 static tree build_typed_selector_reference PROTO((tree, tree));
293 static tree build_selector_reference PROTO((tree));
294 static tree build_class_reference_decl PROTO((tree));
295 static void add_class_reference PROTO((tree));
296 static tree objc_copy_list PROTO((tree, tree *));
297 static tree build_protocol_template PROTO((void));
298 static tree build_descriptor_table_initializer PROTO((tree, tree));
299 static tree build_method_prototype_list_template PROTO((tree, int));
300 static tree build_method_prototype_template PROTO((void));
301 static int forwarding_offset PROTO((tree));
302 static tree encode_method_prototype PROTO((tree, tree));
303 static tree generate_descriptor_table PROTO((tree, char *, int, tree, tree));
304 static void generate_method_descriptors PROTO((tree));
305 static tree build_tmp_function_decl PROTO((void));
306 static void hack_method_prototype PROTO((tree, tree));
307 static void generate_protocol_references PROTO((tree));
308 static void generate_protocols PROTO((void));
309 static void check_ivars PROTO((tree, tree));
310 static tree build_ivar_list_template PROTO((tree, int));
311 static tree build_method_list_template PROTO((tree, int));
312 static tree build_ivar_list_initializer PROTO((tree, tree));
313 static tree generate_ivars_list PROTO((tree, char *,
315 static tree build_dispatch_table_initializer PROTO((tree, tree));
316 static tree generate_dispatch_table PROTO((tree, char *,
318 static tree build_shared_structure_initializer PROTO((tree, tree, tree, tree,
319 tree, int, tree, tree,
321 static void generate_category PROTO((tree));
322 static int is_objc_type_qualifier PROTO((tree));
323 static tree adjust_type_for_id_default PROTO((tree));
324 static tree check_duplicates PROTO((hash));
325 static tree receiver_is_class_object PROTO((tree));
326 static int check_methods PROTO((tree, tree, int));
327 static int conforms_to_protocol PROTO((tree, tree));
328 static void check_protocols PROTO((tree, char *, char *));
329 static tree encode_method_def PROTO((tree));
330 static void gen_declspecs PROTO((tree, char *, int));
331 static void generate_classref_translation_entry PROTO((tree));
332 static void handle_class_ref PROTO((tree));
334 /*** Private Interface (data) ***/
336 /* Reserved tag definitions. */
339 #define TAG_OBJECT "objc_object"
340 #define TAG_CLASS "objc_class"
341 #define TAG_SUPER "objc_super"
342 #define TAG_SELECTOR "objc_selector"
344 #define UTAG_CLASS "_objc_class"
345 #define UTAG_IVAR "_objc_ivar"
346 #define UTAG_IVAR_LIST "_objc_ivar_list"
347 #define UTAG_METHOD "_objc_method"
348 #define UTAG_METHOD_LIST "_objc_method_list"
349 #define UTAG_CATEGORY "_objc_category"
350 #define UTAG_MODULE "_objc_module"
351 #define UTAG_STATICS "_objc_statics"
352 #define UTAG_SYMTAB "_objc_symtab"
353 #define UTAG_SUPER "_objc_super"
354 #define UTAG_SELECTOR "_objc_selector"
356 #define UTAG_PROTOCOL "_objc_protocol"
357 #define UTAG_PROTOCOL_LIST "_objc_protocol_list"
358 #define UTAG_METHOD_PROTOTYPE "_objc_method_prototype"
359 #define UTAG_METHOD_PROTOTYPE_LIST "_objc__method_prototype_list"
361 #define STRING_OBJECT_CLASS_NAME "NXConstantString"
362 #define PROTOCOL_OBJECT_CLASS_NAME "Protocol"
364 static char *TAG_GETCLASS;
365 static char *TAG_GETMETACLASS;
366 static char *TAG_MSGSEND;
367 static char *TAG_MSGSENDSUPER;
368 static char *TAG_EXECCLASS;
370 /* Set by `continue_class' and checked by `is_public'. */
372 #define TREE_STATIC_TEMPLATE(record_type) (TREE_PUBLIC (record_type))
373 #define TYPED_OBJECT(type) \
374 (TREE_CODE (type) == RECORD_TYPE && TREE_STATIC_TEMPLATE (type))
376 /* Some commonly used instances of "identifier_node". */
378 static tree self_id, ucmd_id;
379 static tree unused_list;
381 static tree self_decl, umsg_decl, umsg_super_decl;
382 static tree objc_get_class_decl, objc_get_meta_class_decl;
384 static tree super_type, selector_type, id_type, objc_class_type;
385 static tree instance_type, protocol_type;
387 /* Type checking macros. */
389 #define IS_ID(TYPE) \
390 (TYPE_MAIN_VARIANT (TYPE) == TYPE_MAIN_VARIANT (id_type))
391 #define IS_PROTOCOL_QUALIFIED_ID(TYPE) \
392 (IS_ID (TYPE) && TYPE_PROTOCOL_LIST (TYPE))
393 #define IS_SUPER(TYPE) \
394 (super_type && TYPE_MAIN_VARIANT (TYPE) == TYPE_MAIN_VARIANT (super_type))
396 static tree class_chain = NULL_TREE;
397 static tree alias_chain = NULL_TREE;
398 static tree interface_chain = NULL_TREE;
399 static tree protocol_chain = NULL_TREE;
401 /* Chains to manage selectors that are referenced and defined in the
404 static tree cls_ref_chain = NULL_TREE; /* Classes referenced. */
405 static tree sel_ref_chain = NULL_TREE; /* Selectors referenced. */
407 /* Chains to manage uniquing of strings. */
409 static tree class_names_chain = NULL_TREE;
410 static tree meth_var_names_chain = NULL_TREE;
411 static tree meth_var_types_chain = NULL_TREE;
413 /* Hash tables to manage the global pool of method prototypes. */
415 static hash *nst_method_hash_list = 0;
416 static hash *cls_method_hash_list = 0;
418 /* Backend data declarations. */
420 static tree UOBJC_SYMBOLS_decl;
421 static tree UOBJC_INSTANCE_VARIABLES_decl, UOBJC_CLASS_VARIABLES_decl;
422 static tree UOBJC_INSTANCE_METHODS_decl, UOBJC_CLASS_METHODS_decl;
423 static tree UOBJC_CLASS_decl, UOBJC_METACLASS_decl;
424 static tree UOBJC_SELECTOR_TABLE_decl;
425 static tree UOBJC_MODULES_decl;
426 static tree UOBJC_STRINGS_decl;
428 /* The following are used when compiling a class implementation.
429 implementation_template will normally be an interface, however if
430 none exists this will be equal to implementation_context...it is
431 set in start_class. */
433 static tree implementation_context = NULL_TREE;
434 static tree implementation_template = NULL_TREE;
438 struct imp_entry *next;
441 tree class_decl; /* _OBJC_CLASS_<my_name>; */
442 tree meta_decl; /* _OBJC_METACLASS_<my_name>; */
445 static void handle_impent PROTO((struct imp_entry *));
447 static struct imp_entry *imp_list = 0;
448 static int imp_count = 0; /* `@implementation' */
449 static int cat_count = 0; /* `@category' */
451 static tree objc_class_template, objc_category_template, uprivate_record;
452 static tree objc_protocol_template, objc_selector_template;
453 static tree ucls_super_ref, uucls_super_ref;
455 static tree objc_method_template, objc_ivar_template;
456 static tree objc_symtab_template, objc_module_template;
457 static tree objc_super_template, objc_object_reference;
459 static tree objc_object_id, objc_class_id, objc_id_id;
460 static tree constant_string_id;
461 static tree constant_string_type;
462 static tree UOBJC_SUPER_decl;
464 static tree method_context = NULL_TREE;
465 static int method_slot = 0; /* Used by start_method_def, */
469 static char *errbuf; /* Buffer for error diagnostics */
471 /* Data imported from tree.c. */
473 extern enum debug_info_type write_symbols;
475 /* Data imported from toplev.c. */
477 extern char *dump_base_name;
479 /* Generate code for GNU or NeXT runtime environment. */
481 #ifdef NEXT_OBJC_RUNTIME
482 int flag_next_runtime = 1;
484 int flag_next_runtime = 0;
487 int flag_typed_selectors;
489 /* Open and close the file for outputting class declarations, if requested. */
491 int flag_gen_declaration = 0;
493 FILE *gen_declaration_file;
495 /* Warn if multiple methods are seen for the same selector, but with
496 different argument types. */
498 int warn_selector = 0;
500 /* Warn if methods required by a protocol are not implemented in the
501 class adopting it. When turned off, methods inherited to that
502 class are also considered implemented */
504 int flag_warn_protocol = 1;
506 /* Tells "encode_pointer/encode_aggregate" whether we are generating
507 type descriptors for instance variables (as opposed to methods).
508 Type descriptors for instance variables contain more information
509 than methods (for static typing and embedded structures). This
510 was added to support features being planned for dbkit2. */
512 static int generating_instance_variables = 0;
514 /* Tells the compiler that this is a special run. Do not perform
515 any compiling, instead we are to test some platform dependent
516 features and output a C header file with appropriate definitions. */
518 static int print_struct_values = 0;
520 /* Some platforms pass small structures through registers versus through
521 an invisible pointer. Determine at what size structure is the
522 transition point between the two possibilities. */
525 generate_struct_by_value_array ()
528 tree field_decl, field_decl_chain;
530 int aggregate_in_mem[32];
533 /* Presumbaly no platform passes 32 byte structures in a register. */
534 for (i = 1; i < 32; i++)
538 /* Create an unnamed struct that has `i' character components */
539 type = start_struct (RECORD_TYPE, NULL_TREE);
541 strcpy (buffer, "c1");
542 field_decl = create_builtin_decl (FIELD_DECL,
545 field_decl_chain = field_decl;
547 for (j = 1; j < i; j++)
549 sprintf (buffer, "c%d", j + 1);
550 field_decl = create_builtin_decl (FIELD_DECL,
553 chainon (field_decl_chain, field_decl);
555 finish_struct (type, field_decl_chain, NULL_TREE);
557 aggregate_in_mem[i] = aggregate_value_p (type);
558 if (!aggregate_in_mem[i])
562 /* We found some structures that are returned in registers instead of memory
563 so output the necessary data. */
566 for (i = 31; i >= 0; i--)
567 if (!aggregate_in_mem[i])
569 printf ("#define OBJC_MAX_STRUCT_BY_VALUE %d\n\n", i);
571 /* The first member of the structure is always 0 because we don't handle
572 structures with 0 members */
573 printf ("static int struct_forward_array[] = {\n 0");
575 for (j = 1; j <= i; j++)
576 printf (", %d", aggregate_in_mem[j]);
587 /* The beginning of the file is a new line; check for #.
588 With luck, we discover the real source file's name from that
589 and put it in input_filename. */
590 ungetc (check_newline (), finput);
593 /* The line number can be -1 if we had -g3 and the input file
594 had a directive specifying line 0. But we want predefined
595 functions to have a line number of 0, not -1. */
599 /* If gen_declaration desired, open the output file. */
600 if (flag_gen_declaration)
602 int dump_base_name_length = strlen (dump_base_name);
603 register char *dumpname = (char *) xmalloc (dump_base_name_length + 7);
604 strcpy (dumpname, dump_base_name);
605 strcat (dumpname, ".decl");
606 gen_declaration_file = fopen (dumpname, "w");
607 if (gen_declaration_file == 0)
608 pfatal_with_name (dumpname);
611 if (flag_next_runtime)
613 TAG_GETCLASS = "objc_getClass";
614 TAG_GETMETACLASS = "objc_getMetaClass";
615 TAG_MSGSEND = "objc_msgSend";
616 TAG_MSGSENDSUPER = "objc_msgSendSuper";
617 TAG_EXECCLASS = "__objc_execClass";
621 TAG_GETCLASS = "objc_get_class";
622 TAG_GETMETACLASS = "objc_get_meta_class";
623 TAG_MSGSEND = "objc_msg_lookup";
624 TAG_MSGSENDSUPER = "objc_msg_lookup_super";
625 TAG_EXECCLASS = "__objc_exec_class";
626 flag_typed_selectors = 1;
629 if (doing_objc_thang)
632 if (print_struct_values)
633 generate_struct_by_value_array ();
639 fatal ("Objective-C text in C source file");
645 if (doing_objc_thang)
646 finish_objc (); /* Objective-C finalization */
648 if (gen_declaration_file)
649 fclose (gen_declaration_file);
664 lang_decode_option (p)
667 if (!strcmp (p, "-lang-objc"))
668 doing_objc_thang = 1;
669 else if (!strcmp (p, "-gen-decls"))
670 flag_gen_declaration = 1;
671 else if (!strcmp (p, "-Wselector"))
673 else if (!strcmp (p, "-Wno-selector"))
675 else if (!strcmp (p, "-Wprotocol"))
676 flag_warn_protocol = 1;
677 else if (!strcmp (p, "-Wno-protocol"))
678 flag_warn_protocol = 0;
679 else if (!strcmp (p, "-fgnu-runtime"))
680 flag_next_runtime = 0;
681 else if (!strcmp (p, "-fno-next-runtime"))
682 flag_next_runtime = 0;
683 else if (!strcmp (p, "-fno-gnu-runtime"))
684 flag_next_runtime = 1;
685 else if (!strcmp (p, "-fnext-runtime"))
686 flag_next_runtime = 1;
687 else if (!strcmp (p, "-print-objc-runtime-info"))
688 print_struct_values = 1;
690 return c_decode_option (p);
696 define_decl (declarator, declspecs)
700 tree decl = start_decl (declarator, declspecs, 0, NULL_TREE, NULL_TREE);
701 finish_decl (decl, NULL_TREE, NULL_TREE);
705 /* Return 1 if LHS and RHS are compatible types for assignment or
706 various other operations. Return 0 if they are incompatible, and
707 return -1 if we choose to not decide. When the operation is
708 REFLEXIVE, check for compatibility in either direction.
710 For statically typed objects, an assignment of the form `a' = `b'
714 `a' and `b' are the same class type, or
715 `a' and `b' are of class types A and B such that B is a descendant of A. */
718 maybe_objc_comptypes (lhs, rhs, reflexive)
722 if (doing_objc_thang)
723 return objc_comptypes (lhs, rhs, reflexive);
728 lookup_method_in_protocol_list (rproto_list, sel_name, class_meth)
736 for (rproto = rproto_list; rproto; rproto = TREE_CHAIN (rproto))
738 p = TREE_VALUE (rproto);
740 if (TREE_CODE (p) == PROTOCOL_INTERFACE_TYPE)
742 if ((fnd = lookup_method (class_meth
743 ? PROTOCOL_CLS_METHODS (p)
744 : PROTOCOL_NST_METHODS (p), sel_name)))
746 else if (PROTOCOL_LIST (p))
747 fnd = lookup_method_in_protocol_list (PROTOCOL_LIST (p),
748 sel_name, class_meth);
751 ; /* An identifier...if we could not find a protocol. */
761 lookup_protocol_in_reflist (rproto_list, lproto)
767 /* Make sure the protocol is support by the object on the rhs. */
768 if (TREE_CODE (lproto) == PROTOCOL_INTERFACE_TYPE)
771 for (rproto = rproto_list; rproto; rproto = TREE_CHAIN (rproto))
773 p = TREE_VALUE (rproto);
775 if (TREE_CODE (p) == PROTOCOL_INTERFACE_TYPE)
780 else if (PROTOCOL_LIST (p))
781 fnd = lookup_protocol_in_reflist (PROTOCOL_LIST (p), lproto);
789 ; /* An identifier...if we could not find a protocol. */
794 /* Return 1 if LHS and RHS are compatible types for assignment
795 or various other operations. Return 0 if they are incompatible,
796 and return -1 if we choose to not decide. When the operation
797 is REFLEXIVE, check for compatibility in either direction. */
800 objc_comptypes (lhs, rhs, reflexive)
805 /* New clause for protocols. */
807 if (TREE_CODE (lhs) == POINTER_TYPE
808 && TREE_CODE (TREE_TYPE (lhs)) == RECORD_TYPE
809 && TREE_CODE (rhs) == POINTER_TYPE
810 && TREE_CODE (TREE_TYPE (rhs)) == RECORD_TYPE)
812 int lhs_is_proto = IS_PROTOCOL_QUALIFIED_ID (lhs);
813 int rhs_is_proto = IS_PROTOCOL_QUALIFIED_ID (rhs);
817 tree lproto, lproto_list = TYPE_PROTOCOL_LIST (lhs);
818 tree rproto, rproto_list;
823 rproto_list = TYPE_PROTOCOL_LIST (rhs);
825 /* Make sure the protocol is supported by the object
827 for (lproto = lproto_list; lproto; lproto = TREE_CHAIN (lproto))
829 p = TREE_VALUE (lproto);
830 rproto = lookup_protocol_in_reflist (rproto_list, p);
833 warning ("object does not conform to the `%s' protocol",
834 IDENTIFIER_POINTER (PROTOCOL_NAME (p)));
837 else if (TYPED_OBJECT (TREE_TYPE (rhs)))
839 tree rname = TYPE_NAME (TREE_TYPE (rhs));
842 /* Make sure the protocol is supported by the object
844 for (lproto = lproto_list; lproto; lproto = TREE_CHAIN (lproto))
846 p = TREE_VALUE (lproto);
848 rinter = lookup_interface (rname);
850 while (rinter && !rproto)
854 rproto_list = CLASS_PROTOCOL_LIST (rinter);
855 rproto = lookup_protocol_in_reflist (rproto_list, p);
857 /* Check for protocols adopted by categories. */
858 cat = CLASS_CATEGORY_LIST (rinter);
859 while (cat && !rproto)
861 rproto_list = CLASS_PROTOCOL_LIST (cat);
862 rproto = lookup_protocol_in_reflist (rproto_list, p);
864 cat = CLASS_CATEGORY_LIST (cat);
867 rinter = lookup_interface (CLASS_SUPER_NAME (rinter));
871 warning ("class `%s' does not implement the `%s' protocol",
872 IDENTIFIER_POINTER (TYPE_NAME (TREE_TYPE (rhs))),
873 IDENTIFIER_POINTER (PROTOCOL_NAME (p)));
877 /* May change...based on whether there was any mismatch */
880 else if (rhs_is_proto)
881 /* Lhs is not a protocol...warn if it is statically typed */
882 return (TYPED_OBJECT (TREE_TYPE (lhs)) != 0);
885 /* Defer to comptypes .*/
889 else if (TREE_CODE (lhs) == RECORD_TYPE && TREE_CODE (rhs) == RECORD_TYPE)
890 ; /* Fall thru. This is the case we have been handling all along */
892 /* Defer to comptypes. */
895 /* `id' = `<class> *', `<class> *' = `id' */
897 if ((TYPE_NAME (lhs) == objc_object_id && TYPED_OBJECT (rhs))
898 || (TYPE_NAME (rhs) == objc_object_id && TYPED_OBJECT (lhs)))
901 /* `id' = `Class', `Class' = `id' */
903 else if ((TYPE_NAME (lhs) == objc_object_id
904 && TYPE_NAME (rhs) == objc_class_id)
905 || (TYPE_NAME (lhs) == objc_class_id
906 && TYPE_NAME (rhs) == objc_object_id))
909 /* `<class> *' = `<class> *' */
911 else if (TYPED_OBJECT (lhs) && TYPED_OBJECT (rhs))
913 tree lname = TYPE_NAME (lhs);
914 tree rname = TYPE_NAME (rhs);
920 /* If the left hand side is a super class of the right hand side,
922 for (inter = lookup_interface (rname); inter;
923 inter = lookup_interface (CLASS_SUPER_NAME (inter)))
924 if (lname == CLASS_SUPER_NAME (inter))
927 /* Allow the reverse when reflexive. */
929 for (inter = lookup_interface (lname); inter;
930 inter = lookup_interface (CLASS_SUPER_NAME (inter)))
931 if (rname == CLASS_SUPER_NAME (inter))
937 /* Defer to comptypes. */
941 /* Called from c-decl.c before all calls to rest_of_decl_compilation. */
944 objc_check_decl (decl)
947 tree type = TREE_TYPE (decl);
949 if (TREE_CODE (type) == RECORD_TYPE
950 && TREE_STATIC_TEMPLATE (type)
951 && type != constant_string_type)
953 error_with_decl (decl, "`%s' cannot be statically allocated");
954 fatal ("statically allocated objects not supported");
959 maybe_objc_check_decl (decl)
962 if (doing_objc_thang)
963 objc_check_decl (decl);
966 /* Implement static typing. At this point, we know we have an interface. */
969 get_static_reference (interface, protocols)
973 tree type = xref_tag (RECORD_TYPE, interface);
977 tree t, m = TYPE_MAIN_VARIANT (type);
979 push_obstacks_nochange ();
980 end_temporary_allocation ();
981 t = copy_node (type);
982 TYPE_BINFO (t) = make_tree_vec (2);
985 /* Add this type to the chain of variants of TYPE. */
986 TYPE_NEXT_VARIANT (t) = TYPE_NEXT_VARIANT (m);
987 TYPE_NEXT_VARIANT (m) = t;
989 /* Look up protocols and install in lang specific list. */
990 TYPE_PROTOCOL_LIST (t) = lookup_and_install_protocols (protocols);
992 /* This forces a new pointer type to be created later
993 (in build_pointer_type)...so that the new template
994 we just created will actually be used...what a hack! */
995 if (TYPE_POINTER_TO (t))
996 TYPE_POINTER_TO (t) = 0;
1005 get_object_reference (protocols)
1008 tree type_decl = lookup_name (objc_id_id);
1011 if (type_decl && TREE_CODE (type_decl) == TYPE_DECL)
1013 type = TREE_TYPE (type_decl);
1014 if (TYPE_MAIN_VARIANT (type) != id_type)
1015 warning ("Unexpected type for `id' (%s)",
1016 gen_declaration (type, errbuf));
1019 fatal ("Undefined type `id', please import <objc/objc.h>");
1021 /* This clause creates a new pointer type that is qualified with
1022 the protocol specification...this info is used later to do more
1023 elaborate type checking. */
1027 tree t, m = TYPE_MAIN_VARIANT (type);
1029 push_obstacks_nochange ();
1030 end_temporary_allocation ();
1031 t = copy_node (type);
1032 TYPE_BINFO (t) = make_tree_vec (2);
1035 /* Add this type to the chain of variants of TYPE. */
1036 TYPE_NEXT_VARIANT (t) = TYPE_NEXT_VARIANT (m);
1037 TYPE_NEXT_VARIANT (m) = t;
1039 /* Look up protocols...and install in lang specific list */
1040 TYPE_PROTOCOL_LIST (t) = lookup_and_install_protocols (protocols);
1042 /* This forces a new pointer type to be created later
1043 (in build_pointer_type)...so that the new template
1044 we just created will actually be used...what a hack! */
1045 if (TYPE_POINTER_TO (t))
1046 TYPE_POINTER_TO (t) = NULL;
1054 lookup_and_install_protocols (protocols)
1059 tree return_value = protocols;
1061 for (proto = protocols; proto; proto = TREE_CHAIN (proto))
1063 tree ident = TREE_VALUE (proto);
1064 tree p = lookup_protocol (ident);
1068 error ("Cannot find protocol declaration for `%s'",
1069 IDENTIFIER_POINTER (ident));
1071 TREE_CHAIN (prev) = TREE_CHAIN (proto);
1073 return_value = TREE_CHAIN (proto);
1077 /* Replace identifier with actual protocol node. */
1078 TREE_VALUE (proto) = p;
1083 return return_value;
1086 /* Create and push a decl for a built-in external variable or field NAME.
1088 TYPE is its data type. */
1091 create_builtin_decl (code, type, name)
1092 enum tree_code code;
1096 tree decl = build_decl (code, get_identifier (name), type);
1098 if (code == VAR_DECL)
1100 TREE_STATIC (decl) = 1;
1101 make_decl_rtl (decl, 0, 1);
1105 DECL_ARTIFICIAL (decl) = 1;
1109 /* Purpose: "play" parser, creating/installing representations
1110 of the declarations that are required by Objective-C.
1114 type_spec--------->sc_spec
1115 (tree_list) (tree_list)
1118 identifier_node identifier_node */
1121 synth_module_prologue ()
1126 /* Defined in `objc.h' */
1127 objc_object_id = get_identifier (TAG_OBJECT);
1129 objc_object_reference = xref_tag (RECORD_TYPE, objc_object_id);
1131 id_type = build_pointer_type (objc_object_reference);
1133 objc_id_id = get_identifier (TYPE_ID);
1134 objc_class_id = get_identifier (TAG_CLASS);
1136 objc_class_type = build_pointer_type (xref_tag (RECORD_TYPE, objc_class_id));
1137 protocol_type = build_pointer_type (xref_tag (RECORD_TYPE,
1138 get_identifier (PROTOCOL_OBJECT_CLASS_NAME)));
1140 /* Declare type of selector-objects that represent an operation name. */
1142 #ifdef OBJC_INT_SELECTORS
1143 /* `unsigned int' */
1144 selector_type = unsigned_type_node;
1146 /* `struct objc_selector *' */
1148 = build_pointer_type (xref_tag (RECORD_TYPE,
1149 get_identifier (TAG_SELECTOR)));
1150 #endif /* not OBJC_INT_SELECTORS */
1152 /* Forward declare type, or else the prototype for msgSendSuper will
1155 super_p = build_pointer_type (xref_tag (RECORD_TYPE,
1156 get_identifier (TAG_SUPER)));
1159 /* id objc_msgSend (id, SEL, ...); */
1162 = build_function_type (id_type,
1163 tree_cons (NULL_TREE, id_type,
1164 tree_cons (NULL_TREE, selector_type,
1167 if (! flag_next_runtime)
1169 umsg_decl = build_decl (FUNCTION_DECL,
1170 get_identifier (TAG_MSGSEND), temp_type);
1171 DECL_EXTERNAL (umsg_decl) = 1;
1172 TREE_PUBLIC (umsg_decl) = 1;
1173 DECL_INLINE (umsg_decl) = 1;
1174 DECL_ARTIFICIAL (umsg_decl) = 1;
1176 if (flag_traditional && TAG_MSGSEND[0] != '_')
1177 DECL_BUILT_IN_NONANSI (umsg_decl) = 1;
1179 make_decl_rtl (umsg_decl, NULL_PTR, 1);
1180 pushdecl (umsg_decl);
1183 umsg_decl = builtin_function (TAG_MSGSEND, temp_type, NOT_BUILT_IN, 0);
1185 /* id objc_msgSendSuper (struct objc_super *, SEL, ...); */
1188 = build_function_type (id_type,
1189 tree_cons (NULL_TREE, super_p,
1190 tree_cons (NULL_TREE, selector_type,
1193 umsg_super_decl = builtin_function (TAG_MSGSENDSUPER,
1194 temp_type, NOT_BUILT_IN, 0);
1196 /* id objc_getClass (const char *); */
1198 temp_type = build_function_type (id_type,
1199 tree_cons (NULL_TREE,
1200 const_string_type_node,
1201 tree_cons (NULL_TREE, void_type_node,
1205 = builtin_function (TAG_GETCLASS, temp_type, NOT_BUILT_IN, 0);
1207 /* id objc_getMetaClass (const char *); */
1209 objc_get_meta_class_decl
1210 = builtin_function (TAG_GETMETACLASS, temp_type, NOT_BUILT_IN, 0);
1212 /* static SEL _OBJC_SELECTOR_TABLE[]; */
1214 if (! flag_next_runtime)
1216 if (flag_typed_selectors)
1218 /* Suppress outputting debug symbols, because
1219 dbxout_init hasn'r been called yet. */
1220 enum debug_info_type save_write_symbols = write_symbols;
1221 write_symbols = NO_DEBUG;
1223 build_selector_template ();
1224 temp_type = build_array_type (objc_selector_template, NULL_TREE);
1226 write_symbols = save_write_symbols;
1229 temp_type = build_array_type (selector_type, NULL_TREE);
1231 layout_type (temp_type);
1232 UOBJC_SELECTOR_TABLE_decl
1233 = create_builtin_decl (VAR_DECL, temp_type,
1234 "_OBJC_SELECTOR_TABLE");
1236 /* Avoid warning when not sending messages. */
1237 TREE_USED (UOBJC_SELECTOR_TABLE_decl) = 1;
1240 generate_forward_declaration_to_string_table ();
1242 /* Forward declare constant_string_id and constant_string_type. */
1243 constant_string_id = get_identifier (STRING_OBJECT_CLASS_NAME);
1244 constant_string_type = xref_tag (RECORD_TYPE, constant_string_id);
1247 /* Custom build_string which sets TREE_TYPE! */
1250 my_build_string (len, str)
1255 tree a_string = build_string (len, str);
1257 /* Some code from combine_strings, which is local to c-parse.y. */
1258 if (TREE_TYPE (a_string) == int_array_type_node)
1261 TREE_TYPE (a_string)
1262 = build_array_type (wide_flag ? integer_type_node : char_type_node,
1263 build_index_type (build_int_2 (len - 1, 0)));
1265 TREE_CONSTANT (a_string) = 1; /* Puts string in the readonly segment */
1266 TREE_STATIC (a_string) = 1;
1271 /* Return a newly constructed OBJC_STRING_CST node whose value is
1272 the LEN characters at STR.
1273 The TREE_TYPE is not initialized. */
1276 build_objc_string (len, str)
1280 tree s = build_string (len, str);
1282 TREE_SET_CODE (s, OBJC_STRING_CST);
1286 /* Given a chain of OBJC_STRING_CST's, build a static instance of
1287 NXConstanString which points at the concatenation of those strings.
1288 We place the string object in the __string_objects section of the
1289 __OBJC segment. The Objective-C runtime will initialize the isa
1290 pointers of the string objects to point at the NXConstandString class
1294 build_objc_string_object (strings)
1297 tree string, initlist, constructor;
1300 if (!doing_objc_thang)
1303 if (lookup_interface (constant_string_id) == NULL_TREE)
1305 error ("Cannot find interface declaration for `%s'",
1306 IDENTIFIER_POINTER (constant_string_id));
1307 return error_mark_node;
1310 add_class_reference (constant_string_id);
1312 /* Combine_strings will work for OBJC_STRING_CST's too. */
1313 string = combine_strings (strings);
1314 TREE_SET_CODE (string, STRING_CST);
1315 length = TREE_STRING_LENGTH (string) - 1;
1317 if (! flag_next_runtime)
1319 push_obstacks_nochange ();
1320 end_temporary_allocation ();
1321 if (! TREE_PERMANENT (strings))
1322 string = my_build_string (length + 1,
1323 TREE_STRING_POINTER (string));
1326 /* & ((NXConstantString) {0, string, length}) */
1328 initlist = build_tree_list (NULL_TREE, build_int_2 (0, 0));
1330 = tree_cons (NULL_TREE, copy_node (build_unary_op (ADDR_EXPR, string, 1)),
1332 initlist = tree_cons (NULL_TREE, build_int_2 (length, 0), initlist);
1333 constructor = build_constructor (constant_string_type, nreverse (initlist));
1335 if (!flag_next_runtime)
1338 = objc_add_static_instance (constructor, constant_string_type);
1342 return (build_unary_op (ADDR_EXPR, constructor, 1));
1345 /* Declare a static instance of CLASS_DECL initialized by CONSTRUCTOR. */
1348 objc_add_static_instance (constructor, class_decl)
1349 tree constructor, class_decl;
1351 static int num_static_inst;
1352 tree *chain, decl, decl_spec, decl_expr;
1355 push_obstacks_nochange ();
1356 end_temporary_allocation ();
1358 /* Find the list of static instances for the CLASS_DECL. Create one if
1360 for (chain = &objc_static_instances;
1361 *chain && TREE_VALUE (*chain) != class_decl;
1362 chain = &TREE_CHAIN (*chain));
1365 *chain = tree_cons (NULL_TREE, class_decl, NULL_TREE);
1366 add_objc_string (TYPE_NAME (class_decl), class_names);
1369 sprintf (buf, "_OBJC_INSTANCE_%d", num_static_inst++);
1370 decl = build_decl (VAR_DECL, get_identifier (buf), class_decl);
1371 DECL_COMMON (decl) = 1;
1372 TREE_STATIC (decl) = 1;
1373 DECL_ARTIFICIAL (decl) = 1;
1374 pushdecl_top_level (decl);
1375 rest_of_decl_compilation (decl, 0, 1, 0);
1377 /* Do this here so it gets output later instead of possibly
1378 inside something else we are writing. */
1379 DECL_INITIAL (decl) = constructor;
1381 /* Add the DECL to the head of this CLASS' list. */
1382 TREE_PURPOSE (*chain) = tree_cons (NULL_TREE, decl, TREE_PURPOSE (*chain));
1388 /* Build a static constant CONSTRUCTOR
1389 with type TYPE and elements ELTS. */
1392 build_constructor (type, elts)
1395 tree constructor = build (CONSTRUCTOR, type, NULL_TREE, elts);
1397 TREE_CONSTANT (constructor) = 1;
1398 TREE_STATIC (constructor) = 1;
1399 TREE_READONLY (constructor) = 1;
1404 /* Take care of defining and initializing _OBJC_SYMBOLS. */
1406 /* Predefine the following data type:
1414 void *defs[cls_def_cnt + cat_def_cnt];
1418 build_objc_symtab_template ()
1420 tree field_decl, field_decl_chain, index;
1422 objc_symtab_template
1423 = start_struct (RECORD_TYPE, get_identifier (UTAG_SYMTAB));
1425 /* long sel_ref_cnt; */
1427 field_decl = create_builtin_decl (FIELD_DECL,
1428 long_integer_type_node,
1430 field_decl_chain = field_decl;
1434 field_decl = create_builtin_decl (FIELD_DECL,
1435 build_pointer_type (selector_type),
1437 chainon (field_decl_chain, field_decl);
1439 /* short cls_def_cnt; */
1441 field_decl = create_builtin_decl (FIELD_DECL,
1442 short_integer_type_node,
1444 chainon (field_decl_chain, field_decl);
1446 /* short cat_def_cnt; */
1448 field_decl = create_builtin_decl (FIELD_DECL,
1449 short_integer_type_node,
1451 chainon (field_decl_chain, field_decl);
1453 /* void *defs[cls_def_cnt + cat_def_cnt]; */
1455 if (!flag_next_runtime)
1456 index = build_index_type (build_int_2 (imp_count + cat_count, 0));
1458 index = build_index_type (build_int_2 (imp_count + cat_count - 1,
1459 imp_count == 0 && cat_count == 0
1461 field_decl = create_builtin_decl (FIELD_DECL,
1462 build_array_type (ptr_type_node, index),
1464 chainon (field_decl_chain, field_decl);
1466 finish_struct (objc_symtab_template, field_decl_chain, NULL_TREE);
1469 /* Create the initial value for the `defs' field of _objc_symtab.
1470 This is a CONSTRUCTOR. */
1473 init_def_list (type)
1476 tree expr, initlist = NULL_TREE;
1477 struct imp_entry *impent;
1480 for (impent = imp_list; impent; impent = impent->next)
1482 if (TREE_CODE (impent->imp_context) == CLASS_IMPLEMENTATION_TYPE)
1484 expr = build_unary_op (ADDR_EXPR, impent->class_decl, 0);
1485 initlist = tree_cons (NULL_TREE, expr, initlist);
1490 for (impent = imp_list; impent; impent = impent->next)
1492 if (TREE_CODE (impent->imp_context) == CATEGORY_IMPLEMENTATION_TYPE)
1494 expr = build_unary_op (ADDR_EXPR, impent->class_decl, 0);
1495 initlist = tree_cons (NULL_TREE, expr, initlist);
1499 if (!flag_next_runtime)
1501 /* statics = { ..., _OBJC_STATIC_INSTANCES, ... } */
1504 if (static_instances_decl)
1505 expr = build_unary_op (ADDR_EXPR, static_instances_decl, 0);
1507 expr = build_int_2 (0, 0);
1509 initlist = tree_cons (NULL_TREE, expr, initlist);
1512 return build_constructor (type, nreverse (initlist));
1515 /* Construct the initial value for all of _objc_symtab. */
1518 init_objc_symtab (type)
1523 /* sel_ref_cnt = { ..., 5, ... } */
1525 initlist = build_tree_list (NULL_TREE, build_int_2 (0, 0));
1527 /* refs = { ..., _OBJC_SELECTOR_TABLE, ... } */
1529 if (flag_next_runtime || ! sel_ref_chain)
1530 initlist = tree_cons (NULL_TREE, build_int_2 (0, 0), initlist);
1532 initlist = tree_cons (NULL_TREE,
1533 build_unary_op (ADDR_EXPR,
1534 UOBJC_SELECTOR_TABLE_decl, 1),
1537 /* cls_def_cnt = { ..., 5, ... } */
1539 initlist = tree_cons (NULL_TREE, build_int_2 (imp_count, 0), initlist);
1541 /* cat_def_cnt = { ..., 5, ... } */
1543 initlist = tree_cons (NULL_TREE, build_int_2 (cat_count, 0), initlist);
1545 /* cls_def = { ..., { &Foo, &Bar, ...}, ... } */
1547 if (imp_count || cat_count || static_instances_decl)
1550 tree field = TYPE_FIELDS (type);
1551 field = TREE_CHAIN (TREE_CHAIN (TREE_CHAIN (TREE_CHAIN (field))));
1553 initlist = tree_cons (NULL_TREE, init_def_list (TREE_TYPE (field)),
1557 return build_constructor (type, nreverse (initlist));
1560 /* Push forward-declarations of all the categories
1561 so that init_def_list can use them in a CONSTRUCTOR. */
1564 forward_declare_categories ()
1566 struct imp_entry *impent;
1567 tree sav = implementation_context;
1569 for (impent = imp_list; impent; impent = impent->next)
1571 if (TREE_CODE (impent->imp_context) == CATEGORY_IMPLEMENTATION_TYPE)
1573 /* Set an invisible arg to synth_id_with_class_suffix. */
1574 implementation_context = impent->imp_context;
1576 = create_builtin_decl (VAR_DECL, objc_category_template,
1577 IDENTIFIER_POINTER (synth_id_with_class_suffix ("_OBJC_CATEGORY", implementation_context)));
1580 implementation_context = sav;
1583 /* Create the declaration of _OBJC_SYMBOLS, with type `strict _objc_symtab'
1584 and initialized appropriately. */
1587 generate_objc_symtab_decl ()
1591 if (!objc_category_template)
1592 build_category_template ();
1594 /* forward declare categories */
1596 forward_declare_categories ();
1598 if (!objc_symtab_template)
1599 build_objc_symtab_template ();
1601 sc_spec = build_tree_list (NULL_TREE, ridpointers[(int) RID_STATIC]);
1603 UOBJC_SYMBOLS_decl = start_decl (get_identifier ("_OBJC_SYMBOLS"),
1604 tree_cons (NULL_TREE,
1605 objc_symtab_template, sc_spec),
1607 NULL_TREE, NULL_TREE);
1609 TREE_USED (UOBJC_SYMBOLS_decl) = 1;
1610 DECL_IGNORED_P (UOBJC_SYMBOLS_decl) = 1;
1611 DECL_ARTIFICIAL (UOBJC_SYMBOLS_decl) = 1;
1612 finish_decl (UOBJC_SYMBOLS_decl,
1613 init_objc_symtab (TREE_TYPE (UOBJC_SYMBOLS_decl)),
1618 init_module_descriptor (type)
1621 tree initlist, expr;
1623 /* version = { 1, ... } */
1625 expr = build_int_2 (OBJC_VERSION, 0);
1626 initlist = build_tree_list (NULL_TREE, expr);
1628 /* size = { ..., sizeof (struct objc_module), ... } */
1630 expr = size_in_bytes (objc_module_template);
1631 initlist = tree_cons (NULL_TREE, expr, initlist);
1633 /* name = { ..., "foo.m", ... } */
1635 expr = add_objc_string (get_identifier (input_filename), class_names);
1636 initlist = tree_cons (NULL_TREE, expr, initlist);
1638 /* symtab = { ..., _OBJC_SYMBOLS, ... } */
1640 if (UOBJC_SYMBOLS_decl)
1641 expr = build_unary_op (ADDR_EXPR, UOBJC_SYMBOLS_decl, 0);
1643 expr = build_int_2 (0, 0);
1644 initlist = tree_cons (NULL_TREE, expr, initlist);
1646 return build_constructor (type, nreverse (initlist));
1649 /* Write out the data structures to describe Objective C classes defined.
1650 If appropriate, compile and output a setup function to initialize them.
1651 Return a string which is the name of a function to call to initialize
1652 the Objective C data structures for this file (and perhaps for other files
1655 struct objc_module { ... } _OBJC_MODULE = { ... }; */
1658 build_module_descriptor ()
1660 tree decl_specs, field_decl, field_decl_chain;
1662 objc_module_template
1663 = start_struct (RECORD_TYPE, get_identifier (UTAG_MODULE));
1667 decl_specs = build_tree_list (NULL_TREE, ridpointers[(int) RID_LONG]);
1668 field_decl = get_identifier ("version");
1670 = grokfield (input_filename, lineno, field_decl, decl_specs, NULL_TREE);
1671 field_decl_chain = field_decl;
1675 decl_specs = build_tree_list (NULL_TREE, ridpointers[(int) RID_LONG]);
1676 field_decl = get_identifier ("size");
1678 = grokfield (input_filename, lineno, field_decl, decl_specs, NULL_TREE);
1679 chainon (field_decl_chain, field_decl);
1683 decl_specs = build_tree_list (NULL_TREE, ridpointers[(int) RID_CHAR]);
1684 field_decl = build1 (INDIRECT_REF, NULL_TREE, get_identifier ("name"));
1686 = grokfield (input_filename, lineno, field_decl, decl_specs, NULL_TREE);
1687 chainon (field_decl_chain, field_decl);
1689 /* struct objc_symtab *symtab; */
1691 decl_specs = get_identifier (UTAG_SYMTAB);
1692 decl_specs = build_tree_list (NULL_TREE, xref_tag (RECORD_TYPE, decl_specs));
1693 field_decl = build1 (INDIRECT_REF, NULL_TREE, get_identifier ("symtab"));
1695 = grokfield (input_filename, lineno, field_decl, decl_specs, NULL_TREE);
1696 chainon (field_decl_chain, field_decl);
1698 finish_struct (objc_module_template, field_decl_chain, NULL_TREE);
1700 /* Create an instance of "objc_module". */
1702 decl_specs = tree_cons (NULL_TREE, objc_module_template,
1703 build_tree_list (NULL_TREE,
1704 ridpointers[(int) RID_STATIC]));
1706 UOBJC_MODULES_decl = start_decl (get_identifier ("_OBJC_MODULES"),
1707 decl_specs, 1, NULL_TREE, NULL_TREE);
1709 DECL_ARTIFICIAL (UOBJC_MODULES_decl) = 1;
1710 DECL_IGNORED_P (UOBJC_MODULES_decl) = 1;
1711 finish_decl (UOBJC_MODULES_decl,
1712 init_module_descriptor (TREE_TYPE (UOBJC_MODULES_decl)),
1715 /* Mark the decl to avoid "defined but not used" warning. */
1716 DECL_IN_SYSTEM_HEADER (UOBJC_MODULES_decl) = 1;
1718 /* Generate a constructor call for the module descriptor.
1719 This code was generated by reading the grammar rules
1720 of c-parse.in; Therefore, it may not be the most efficient
1721 way of generating the requisite code. */
1723 if (flag_next_runtime)
1727 tree parms, function_decl, decelerator, void_list_node;
1729 tree init_function_name = get_file_function_name ('I');
1731 /* Declare void __objc_execClass (void *); */
1733 void_list_node = build_tree_list (NULL_TREE, void_type_node);
1735 = build_function_type (void_type_node,
1736 tree_cons (NULL_TREE, ptr_type_node,
1738 function_decl = build_decl (FUNCTION_DECL,
1739 get_identifier (TAG_EXECCLASS),
1741 DECL_EXTERNAL (function_decl) = 1;
1742 DECL_ARTIFICIAL (function_decl) = 1;
1743 TREE_PUBLIC (function_decl) = 1;
1745 pushdecl (function_decl);
1746 rest_of_decl_compilation (function_decl, 0, 0, 0);
1749 = build_tree_list (NULL_TREE,
1750 build_unary_op (ADDR_EXPR, UOBJC_MODULES_decl, 0));
1751 decelerator = build_function_call (function_decl, parms);
1753 /* void _GLOBAL_$I$<gnyf> () {objc_execClass (&L_OBJC_MODULES);} */
1755 start_function (void_list_node,
1756 build_parse_node (CALL_EXPR, init_function_name,
1757 /* This has the format of the output
1758 of get_parm_info. */
1759 tree_cons (NULL_TREE, NULL_TREE,
1762 NULL_TREE, NULL_TREE, 0);
1763 #if 0 /* This should be turned back on later
1764 for the systems where collect is not needed. */
1765 /* Make these functions nonglobal
1766 so each file can use the same name. */
1767 TREE_PUBLIC (current_function_decl) = 0;
1769 TREE_USED (current_function_decl) = 1;
1770 store_parm_decls ();
1772 assemble_external (function_decl);
1773 c_expand_expr_stmt (decelerator);
1775 TREE_PUBLIC (current_function_decl) = 1;
1777 function_decl = current_function_decl;
1778 finish_function (0);
1780 /* Return the name of the constructor function. */
1781 return XSTR (XEXP (DECL_RTL (function_decl), 0), 0);
1785 /* extern const char _OBJC_STRINGS[]; */
1788 generate_forward_declaration_to_string_table ()
1790 tree sc_spec, decl_specs, expr_decl;
1792 sc_spec = tree_cons (NULL_TREE, ridpointers[(int) RID_EXTERN], NULL_TREE);
1793 decl_specs = tree_cons (NULL_TREE, ridpointers[(int) RID_CHAR], sc_spec);
1796 = build_nt (ARRAY_REF, get_identifier ("_OBJC_STRINGS"), NULL_TREE);
1798 UOBJC_STRINGS_decl = define_decl (expr_decl, decl_specs);
1801 /* Return the DECL of the string IDENT in the SECTION. */
1804 get_objc_string_decl (ident, section)
1806 enum string_section section;
1810 if (section == class_names)
1811 chain = class_names_chain;
1812 else if (section == meth_var_names)
1813 chain = meth_var_names_chain;
1814 else if (section == meth_var_types)
1815 chain = meth_var_types_chain;
1817 for (; chain != 0; chain = TREE_VALUE (chain))
1818 if (TREE_VALUE (chain) == ident)
1819 return (TREE_PURPOSE (chain));
1825 /* Output references to all statically allocated objects. Return the DECL
1826 for the array built. */
1829 generate_static_references ()
1831 tree decls = NULL_TREE, ident, decl_spec, expr_decl, expr = NULL_TREE;
1832 tree class_name, class, decl, instance, idecl, initlist;
1833 tree cl_chain, in_chain, type;
1834 int num_inst, num_class;
1837 if (flag_next_runtime)
1840 for (cl_chain = objc_static_instances, num_class = 0;
1841 cl_chain; cl_chain = TREE_CHAIN (cl_chain), num_class++)
1843 for (num_inst = 0, in_chain = TREE_PURPOSE (cl_chain);
1844 in_chain; num_inst++, in_chain = TREE_CHAIN (in_chain));
1846 sprintf (buf, "_OBJC_STATIC_INSTANCES_%d", num_class);
1847 ident = get_identifier (buf);
1849 expr_decl = build_nt (ARRAY_REF, ident, NULL_TREE);
1850 decl_spec = tree_cons (NULL_TREE, build_pointer_type (void_type_node),
1851 build_tree_list (NULL_TREE,
1852 ridpointers[(int) RID_STATIC]));
1853 decl = start_decl (expr_decl, decl_spec, 1, NULL_TREE, NULL_TREE);
1854 DECL_CONTEXT (decl) = 0;
1855 DECL_ARTIFICIAL (decl) = 1;
1857 /* Output {class_name, ...}. */
1858 class = TREE_VALUE (cl_chain);
1859 class_name = get_objc_string_decl (TYPE_NAME (class), class_names);
1860 initlist = build_tree_list (NULL_TREE,
1861 build_unary_op (ADDR_EXPR, class_name, 1));
1863 /* Output {..., instance, ...}. */
1864 for (in_chain = TREE_PURPOSE (cl_chain);
1865 in_chain; in_chain = TREE_CHAIN (in_chain))
1867 expr = build_unary_op (ADDR_EXPR, TREE_VALUE (in_chain), 1);
1868 initlist = tree_cons (NULL_TREE, expr, initlist);
1871 /* Output {..., NULL}. */
1872 initlist = tree_cons (NULL_TREE, build_int_2 (0, 0), initlist);
1874 expr = build_constructor (TREE_TYPE (decl), nreverse (initlist));
1875 finish_decl (decl, expr, NULL_TREE);
1876 TREE_USED (decl) = 1;
1878 type = build_array_type (build_pointer_type (void_type_node), 0);
1879 decl = build_decl (VAR_DECL, ident, type);
1880 make_decl_rtl (decl, 0, 1);
1881 TREE_USED (decl) = 1;
1883 = tree_cons (NULL_TREE, build_unary_op (ADDR_EXPR, decl, 1), decls);
1886 decls = tree_cons (NULL_TREE, build_int_2 (0, 0), decls);
1887 ident = get_identifier ("_OBJC_STATIC_INSTANCES");
1888 expr_decl = build_nt (ARRAY_REF, ident, NULL_TREE);
1889 decl_spec = tree_cons (NULL_TREE, build_pointer_type (void_type_node),
1890 build_tree_list (NULL_TREE,
1891 ridpointers[(int) RID_STATIC]));
1892 static_instances_decl
1893 = start_decl (expr_decl, decl_spec, 1, NULL_TREE, NULL_TREE);
1894 TREE_USED (static_instances_decl) = 1;
1895 DECL_CONTEXT (static_instances_decl) = 0;
1896 DECL_ARTIFICIAL (static_instances_decl) = 1;
1897 end_temporary_allocation ();
1898 expr = build_constructor (TREE_TYPE (static_instances_decl),
1900 finish_decl (static_instances_decl, expr, NULL_TREE);
1903 /* Output all strings. */
1908 tree sc_spec, decl_specs, expr_decl;
1909 tree chain, string_expr;
1912 for (chain = class_names_chain; chain; chain = TREE_CHAIN (chain))
1914 string = TREE_VALUE (chain);
1915 decl = TREE_PURPOSE (chain);
1917 = tree_cons (NULL_TREE, ridpointers[(int) RID_STATIC], NULL_TREE);
1918 decl_specs = tree_cons (NULL_TREE, ridpointers[(int) RID_CHAR], sc_spec);
1919 expr_decl = build_nt (ARRAY_REF, DECL_NAME (decl), NULL_TREE);
1920 decl = start_decl (expr_decl, decl_specs, 1, NULL_TREE, NULL_TREE);
1921 end_temporary_allocation ();
1922 string_expr = my_build_string (IDENTIFIER_LENGTH (string) + 1,
1923 IDENTIFIER_POINTER (string));
1924 finish_decl (decl, string_expr, NULL_TREE);
1927 for (chain = meth_var_names_chain; chain; chain = TREE_CHAIN (chain))
1929 string = TREE_VALUE (chain);
1930 decl = TREE_PURPOSE (chain);
1932 = tree_cons (NULL_TREE, ridpointers[(int) RID_STATIC], NULL_TREE);
1933 decl_specs = tree_cons (NULL_TREE, ridpointers[(int) RID_CHAR], sc_spec);
1934 expr_decl = build_nt (ARRAY_REF, DECL_NAME (decl), NULL_TREE);
1935 decl = start_decl (expr_decl, decl_specs, 1, NULL_TREE, NULL_TREE);
1936 string_expr = my_build_string (IDENTIFIER_LENGTH (string) + 1,
1937 IDENTIFIER_POINTER (string));
1938 finish_decl (decl, string_expr, NULL_TREE);
1941 for (chain = meth_var_types_chain; chain; chain = TREE_CHAIN (chain))
1943 string = TREE_VALUE (chain);
1944 decl = TREE_PURPOSE (chain);
1946 = tree_cons (NULL_TREE, ridpointers[(int) RID_STATIC], NULL_TREE);
1947 decl_specs = tree_cons (NULL_TREE, ridpointers[(int) RID_CHAR], sc_spec);
1948 expr_decl = build_nt (ARRAY_REF, DECL_NAME (decl), NULL_TREE);
1949 decl = start_decl (expr_decl, decl_specs, 1, NULL_TREE, NULL_TREE);
1950 string_expr = my_build_string (IDENTIFIER_LENGTH (string) + 1,
1951 IDENTIFIER_POINTER (string));
1952 finish_decl (decl, string_expr, NULL_TREE);
1957 build_selector_reference_decl (name)
1964 sprintf (buf, "_OBJC_SELECTOR_REFERENCES_%d", idx++);
1966 push_obstacks_nochange ();
1967 end_temporary_allocation ();
1969 ident = get_identifier (buf);
1971 decl = build_decl (VAR_DECL, ident, selector_type);
1972 DECL_EXTERNAL (decl) = 1;
1973 TREE_PUBLIC (decl) = 1;
1974 TREE_USED (decl) = 1;
1975 TREE_READONLY (decl) = 1;
1976 DECL_ARTIFICIAL (decl) = 1;
1977 DECL_CONTEXT (decl) = 0;
1979 make_decl_rtl (decl, 0, 1);
1980 pushdecl_top_level (decl);
1987 /* Just a handy wrapper for add_objc_string. */
1990 build_selector (ident)
1993 tree expr = add_objc_string (ident, meth_var_names);
1994 if (flag_typed_selectors)
1997 return build_c_cast (selector_type, expr); /* cast! */
2000 /* Synthesize the following expr: (char *)&_OBJC_STRINGS[<offset>]
2001 The cast stops the compiler from issuing the following message:
2002 grok.m: warning: initialization of non-const * pointer from const *
2003 grok.m: warning: initialization between incompatible pointer types. */
2006 build_msg_pool_reference (offset)
2009 tree expr = build_int_2 (offset, 0);
2012 expr = build_array_ref (UOBJC_STRINGS_decl, expr);
2013 expr = build_unary_op (ADDR_EXPR, expr, 0);
2015 cast = build_tree_list (build_tree_list (NULL_TREE,
2016 ridpointers[(int) RID_CHAR]),
2017 build1 (INDIRECT_REF, NULL_TREE, NULL_TREE));
2018 TREE_TYPE (expr) = groktypename (cast);
2023 init_selector (offset)
2026 tree expr = build_msg_pool_reference (offset);
2027 TREE_TYPE (expr) = selector_type;
2032 build_selector_translation_table ()
2034 tree sc_spec, decl_specs;
2035 tree chain, initlist = NULL_TREE;
2037 tree decl, var_decl, name;
2039 /* The corresponding pop_obstacks is in finish_decl,
2040 called at the end of this function. */
2041 if (! flag_next_runtime)
2042 push_obstacks_nochange ();
2044 for (chain = sel_ref_chain; chain; chain = TREE_CHAIN (chain))
2048 expr = build_selector (TREE_VALUE (chain));
2050 if (flag_next_runtime)
2052 name = DECL_NAME (TREE_PURPOSE (chain));
2054 sc_spec = build_tree_list (NULL_TREE, ridpointers[(int) RID_STATIC]);
2056 /* static SEL _OBJC_SELECTOR_REFERENCES_n = ...; */
2057 decl_specs = tree_cons (NULL_TREE, selector_type, sc_spec);
2061 /* The `decl' that is returned from start_decl is the one that we
2062 forward declared in `build_selector_reference' */
2063 decl = start_decl (var_decl, decl_specs, 1, NULL_TREE, NULL_TREE);
2066 /* add one for the '\0' character */
2067 offset += IDENTIFIER_LENGTH (TREE_VALUE (chain)) + 1;
2069 if (flag_next_runtime)
2070 finish_decl (decl, expr, NULL_TREE);
2073 if (flag_typed_selectors)
2075 tree eltlist = NULL_TREE;
2076 tree encoding = get_proto_encoding (TREE_PURPOSE (chain));
2077 eltlist = tree_cons (NULL_TREE, expr, NULL_TREE);
2078 eltlist = tree_cons (NULL_TREE, encoding, eltlist);
2079 expr = build_constructor (objc_selector_template,
2080 nreverse (eltlist));
2082 initlist = tree_cons (NULL_TREE, expr, initlist);
2087 if (! flag_next_runtime)
2089 /* Cause the variable and its initial value to be actually output. */
2090 DECL_EXTERNAL (UOBJC_SELECTOR_TABLE_decl) = 0;
2091 TREE_STATIC (UOBJC_SELECTOR_TABLE_decl) = 1;
2092 /* NULL terminate the list and fix the decl for output. */
2093 initlist = tree_cons (NULL_TREE, build_int_2 (0, 0), initlist);
2094 DECL_INITIAL (UOBJC_SELECTOR_TABLE_decl) = (tree) 1;
2095 initlist = build_constructor (TREE_TYPE (UOBJC_SELECTOR_TABLE_decl),
2096 nreverse (initlist));
2097 finish_decl (UOBJC_SELECTOR_TABLE_decl, initlist, NULL_TREE);
2098 current_function_decl = NULL_TREE;
2103 get_proto_encoding (proto)
2111 if (! METHOD_ENCODING (proto))
2113 tmp_decl = build_tmp_function_decl ();
2114 hack_method_prototype (proto, tmp_decl);
2115 encoding = encode_method_prototype (proto, tmp_decl);
2116 METHOD_ENCODING (proto) = encoding;
2119 encoding = METHOD_ENCODING (proto);
2121 return add_objc_string (encoding, meth_var_types);
2124 return build_int_2 (0, 0);
2127 /* sel_ref_chain is a list whose "value" fields will be instances of
2128 identifier_node that represent the selector. */
2131 build_typed_selector_reference (ident, proto)
2134 tree *chain = &sel_ref_chain;
2140 if (TREE_PURPOSE (*chain) == ident && TREE_VALUE (*chain) == proto)
2141 goto return_at_index;
2144 chain = &TREE_CHAIN (*chain);
2147 *chain = perm_tree_cons (proto, ident, NULL_TREE);
2150 expr = build_unary_op (ADDR_EXPR,
2151 build_array_ref (UOBJC_SELECTOR_TABLE_decl,
2152 build_int_2 (index, 0)),
2154 return build_c_cast (selector_type, expr);
2158 build_selector_reference (ident)
2161 tree *chain = &sel_ref_chain;
2167 if (TREE_VALUE (*chain) == ident)
2168 return (flag_next_runtime
2169 ? TREE_PURPOSE (*chain)
2170 : build_array_ref (UOBJC_SELECTOR_TABLE_decl,
2171 build_int_2 (index, 0)));
2174 chain = &TREE_CHAIN (*chain);
2177 expr = build_selector_reference_decl (ident);
2179 *chain = perm_tree_cons (expr, ident, NULL_TREE);
2181 return (flag_next_runtime
2183 : build_array_ref (UOBJC_SELECTOR_TABLE_decl,
2184 build_int_2 (index, 0)));
2188 build_class_reference_decl (name)
2195 sprintf (buf, "_OBJC_CLASS_REFERENCES_%d", idx++);
2197 push_obstacks_nochange ();
2198 end_temporary_allocation ();
2200 ident = get_identifier (buf);
2202 decl = build_decl (VAR_DECL, ident, objc_class_type);
2203 DECL_EXTERNAL (decl) = 1;
2204 TREE_PUBLIC (decl) = 1;
2205 TREE_USED (decl) = 1;
2206 TREE_READONLY (decl) = 1;
2207 DECL_CONTEXT (decl) = 0;
2208 DECL_ARTIFICIAL (decl) = 1;
2210 make_decl_rtl (decl, 0, 1);
2211 pushdecl_top_level (decl);
2218 /* Create a class reference, but don't create a variable to reference
2222 add_class_reference (ident)
2227 if ((chain = cls_ref_chain))
2232 if (ident == TREE_VALUE (chain))
2236 chain = TREE_CHAIN (chain);
2240 /* Append to the end of the list */
2241 TREE_CHAIN (tail) = perm_tree_cons (NULL_TREE, ident, NULL_TREE);
2244 cls_ref_chain = perm_tree_cons (NULL_TREE, ident, NULL_TREE);
2247 /* Get a class reference, creating it if necessary. Also create the
2248 reference variable. */
2251 get_class_reference (ident)
2254 if (flag_next_runtime)
2259 for (chain = &cls_ref_chain; *chain; chain = &TREE_CHAIN (*chain))
2260 if (TREE_VALUE (*chain) == ident)
2262 if (! TREE_PURPOSE (*chain))
2263 TREE_PURPOSE (*chain) = build_class_reference_decl (ident);
2265 return TREE_PURPOSE (*chain);
2268 decl = build_class_reference_decl (ident);
2269 *chain = perm_tree_cons (decl, ident, NULL_TREE);
2276 add_class_reference (ident);
2278 params = build_tree_list (NULL_TREE,
2279 my_build_string (IDENTIFIER_LENGTH (ident) + 1,
2280 IDENTIFIER_POINTER (ident)));
2282 assemble_external (objc_get_class_decl);
2283 return build_function_call (objc_get_class_decl, params);
2287 /* SEL_REFDEF_CHAIN is a list whose "value" fields will be instances
2288 of identifier_node that represent the selector. It returns the
2289 offset of the selector from the beginning of the _OBJC_STRINGS
2290 pool. This offset is typically used by init_selector during code
2293 For each string section we have a chain which maps identifier nodes
2294 to decls for the strings. */
2297 add_objc_string (ident, section)
2299 enum string_section section;
2303 if (section == class_names)
2304 chain = &class_names_chain;
2305 else if (section == meth_var_names)
2306 chain = &meth_var_names_chain;
2307 else if (section == meth_var_types)
2308 chain = &meth_var_types_chain;
2312 if (TREE_VALUE (*chain) == ident)
2313 return build_unary_op (ADDR_EXPR, TREE_PURPOSE (*chain), 1);
2315 chain = &TREE_CHAIN (*chain);
2318 decl = build_objc_string_decl (ident, section);
2320 *chain = perm_tree_cons (decl, ident, NULL_TREE);
2322 return build_unary_op (ADDR_EXPR, decl, 1);
2326 build_objc_string_decl (name, section)
2328 enum string_section section;
2332 static int class_names_idx = 0;
2333 static int meth_var_names_idx = 0;
2334 static int meth_var_types_idx = 0;
2336 if (section == class_names)
2337 sprintf (buf, "_OBJC_CLASS_NAME_%d", class_names_idx++);
2338 else if (section == meth_var_names)
2339 sprintf (buf, "_OBJC_METH_VAR_NAME_%d", meth_var_names_idx++);
2340 else if (section == meth_var_types)
2341 sprintf (buf, "_OBJC_METH_VAR_TYPE_%d", meth_var_types_idx++);
2343 push_obstacks_nochange ();
2344 end_temporary_allocation ();
2345 ident = get_identifier (buf);
2347 decl = build_decl (VAR_DECL, ident, build_array_type (char_type_node, 0));
2348 DECL_EXTERNAL (decl) = 1;
2349 TREE_PUBLIC (decl) = 1;
2350 TREE_USED (decl) = 1;
2351 TREE_READONLY (decl) = 1;
2352 TREE_CONSTANT (decl) = 1;
2353 DECL_CONTEXT (decl) = 0;
2354 DECL_ARTIFICIAL (decl) = 1;
2356 make_decl_rtl (decl, 0, 1);
2357 pushdecl_top_level (decl);
2366 objc_declare_alias (alias_ident, class_ident)
2370 if (!doing_objc_thang)
2373 if (is_class_name (class_ident) != class_ident)
2374 warning ("Cannot find class `%s'", IDENTIFIER_POINTER (class_ident));
2375 else if (is_class_name (alias_ident))
2376 warning ("Class `%s' already exists", IDENTIFIER_POINTER (alias_ident));
2378 alias_chain = tree_cons (class_ident, alias_ident, alias_chain);
2382 objc_declare_class (ident_list)
2387 if (!doing_objc_thang)
2390 for (list = ident_list; list; list = TREE_CHAIN (list))
2392 tree ident = TREE_VALUE (list);
2395 if ((decl = lookup_name (ident)))
2397 error ("`%s' redeclared as different kind of symbol",
2398 IDENTIFIER_POINTER (ident));
2399 error_with_decl (decl, "previous declaration of `%s'");
2402 if (! is_class_name (ident))
2404 tree record = xref_tag (RECORD_TYPE, ident);
2405 TREE_STATIC_TEMPLATE (record) = 1;
2406 class_chain = tree_cons (NULL_TREE, ident, class_chain);
2412 is_class_name (ident)
2417 if (lookup_interface (ident))
2420 for (chain = class_chain; chain; chain = TREE_CHAIN (chain))
2422 if (ident == TREE_VALUE (chain))
2426 for (chain = alias_chain; chain; chain = TREE_CHAIN (chain))
2428 if (ident == TREE_VALUE (chain))
2429 return TREE_PURPOSE (chain);
2436 lookup_interface (ident)
2441 for (chain = interface_chain; chain; chain = TREE_CHAIN (chain))
2443 if (ident == CLASS_NAME (chain))
2450 objc_copy_list (list, head)
2454 tree newlist = NULL_TREE, tail = NULL_TREE;
2458 tail = copy_node (list);
2460 /* The following statement fixes a bug when inheriting instance
2461 variables that are declared to be bitfields. finish_struct
2462 expects to find the width of the bitfield in DECL_INITIAL,
2463 which it nulls out after processing the decl of the super
2464 class...rather than change the way finish_struct works (which
2465 is risky), I create the situation it expects...s.naroff
2468 if (DECL_BIT_FIELD (tail) && DECL_INITIAL (tail) == 0)
2469 DECL_INITIAL (tail) = build_int_2 (DECL_FIELD_SIZE (tail), 0);
2471 newlist = chainon (newlist, tail);
2472 list = TREE_CHAIN (list);
2479 /* Used by: build_private_template, get_class_ivars, and
2480 continue_class. COPY is 1 when called from @defs. In this case
2481 copy all fields. Otherwise don't copy leaf ivars since we rely on
2482 them being side-effected exactly once by finish_struct. */
2485 build_ivar_chain (interface, copy)
2489 tree my_name, super_name, ivar_chain;
2491 my_name = CLASS_NAME (interface);
2492 super_name = CLASS_SUPER_NAME (interface);
2494 /* Possibly copy leaf ivars. */
2496 objc_copy_list (CLASS_IVARS (interface), &ivar_chain);
2498 ivar_chain = CLASS_IVARS (interface);
2503 tree super_interface = lookup_interface (super_name);
2505 if (!super_interface)
2507 /* fatal did not work with 2 args...should fix */
2508 error ("Cannot find interface declaration for `%s', superclass of `%s'",
2509 IDENTIFIER_POINTER (super_name),
2510 IDENTIFIER_POINTER (my_name));
2511 exit (FATAL_EXIT_CODE);
2514 if (super_interface == interface)
2516 fatal ("Circular inheritance in interface declaration for `%s'",
2517 IDENTIFIER_POINTER (super_name));
2520 interface = super_interface;
2521 my_name = CLASS_NAME (interface);
2522 super_name = CLASS_SUPER_NAME (interface);
2524 op1 = CLASS_IVARS (interface);
2527 tree head, tail = objc_copy_list (op1, &head);
2529 /* Prepend super class ivars...make a copy of the list, we
2530 do not want to alter the original. */
2531 TREE_CHAIN (tail) = ivar_chain;
2538 /* struct <classname> {
2539 struct objc_class *isa;
2544 build_private_template (class)
2549 if (CLASS_STATIC_TEMPLATE (class))
2551 uprivate_record = CLASS_STATIC_TEMPLATE (class);
2552 ivar_context = TYPE_FIELDS (CLASS_STATIC_TEMPLATE (class));
2556 uprivate_record = start_struct (RECORD_TYPE, CLASS_NAME (class));
2558 ivar_context = build_ivar_chain (class, 0);
2560 finish_struct (uprivate_record, ivar_context, NULL_TREE);
2562 CLASS_STATIC_TEMPLATE (class) = uprivate_record;
2564 /* mark this record as class template - for class type checking */
2565 TREE_STATIC_TEMPLATE (uprivate_record) = 1;
2569 = groktypename (build_tree_list (build_tree_list (NULL_TREE,
2571 build1 (INDIRECT_REF, NULL_TREE,
2574 return ivar_context;
2577 /* Begin code generation for protocols... */
2579 /* struct objc_protocol {
2580 char *protocol_name;
2581 struct objc_protocol **protocol_list;
2582 struct objc_method_desc *instance_methods;
2583 struct objc_method_desc *class_methods;
2587 build_protocol_template ()
2589 tree decl_specs, field_decl, field_decl_chain;
2592 template = start_struct (RECORD_TYPE, get_identifier (UTAG_PROTOCOL));
2594 /* struct objc_class *isa; */
2596 decl_specs = build_tree_list (NULL_TREE, xref_tag (RECORD_TYPE,
2597 get_identifier (UTAG_CLASS)));
2598 field_decl = build1 (INDIRECT_REF, NULL_TREE, get_identifier ("isa"));
2600 = grokfield (input_filename, lineno, field_decl, decl_specs, NULL_TREE);
2601 field_decl_chain = field_decl;
2603 /* char *protocol_name; */
2605 decl_specs = build_tree_list (NULL_TREE, ridpointers[(int) RID_CHAR]);
2607 = build1 (INDIRECT_REF, NULL_TREE, get_identifier ("protocol_name"));
2609 = grokfield (input_filename, lineno, field_decl, decl_specs, NULL_TREE);
2610 chainon (field_decl_chain, field_decl);
2612 /* struct objc_protocol **protocol_list; */
2614 decl_specs = build_tree_list (NULL_TREE, template);
2616 = build1 (INDIRECT_REF, NULL_TREE, get_identifier ("protocol_list"));
2617 field_decl = build1 (INDIRECT_REF, NULL_TREE, field_decl);
2619 = grokfield (input_filename, lineno, field_decl, decl_specs, NULL_TREE);
2620 chainon (field_decl_chain, field_decl);
2622 /* struct objc_method_list *instance_methods; */
2625 = build_tree_list (NULL_TREE,
2626 xref_tag (RECORD_TYPE,
2627 get_identifier (UTAG_METHOD_PROTOTYPE_LIST)));
2629 = build1 (INDIRECT_REF, NULL_TREE, get_identifier ("instance_methods"));
2631 = grokfield (input_filename, lineno, field_decl, decl_specs, NULL_TREE);
2632 chainon (field_decl_chain, field_decl);
2634 /* struct objc_method_list *class_methods; */
2637 = build_tree_list (NULL_TREE,
2638 xref_tag (RECORD_TYPE,
2639 get_identifier (UTAG_METHOD_PROTOTYPE_LIST)));
2641 = build1 (INDIRECT_REF, NULL_TREE, get_identifier ("class_methods"));
2643 = grokfield (input_filename, lineno, field_decl, decl_specs, NULL_TREE);
2644 chainon (field_decl_chain, field_decl);
2646 return finish_struct (template, field_decl_chain, NULL_TREE);
2650 build_descriptor_table_initializer (type, entries)
2654 tree initlist = NULL_TREE;
2658 tree eltlist = NULL_TREE;
2661 = tree_cons (NULL_TREE,
2662 build_selector (METHOD_SEL_NAME (entries)), NULL_TREE);
2664 = tree_cons (NULL_TREE,
2665 add_objc_string (METHOD_ENCODING (entries),
2670 = tree_cons (NULL_TREE,
2671 build_constructor (type, nreverse (eltlist)), initlist);
2673 entries = TREE_CHAIN (entries);
2677 return build_constructor (build_array_type (type, 0), nreverse (initlist));
2680 /* struct objc_method_prototype_list {
2682 struct objc_method_prototype {
2689 build_method_prototype_list_template (list_type, size)
2693 tree objc_ivar_list_record;
2694 tree decl_specs, field_decl, field_decl_chain;
2696 /* Generate an unnamed struct definition. */
2698 objc_ivar_list_record = start_struct (RECORD_TYPE, NULL_TREE);
2700 /* int method_count; */
2702 decl_specs = build_tree_list (NULL_TREE, ridpointers[(int) RID_INT]);
2703 field_decl = get_identifier ("method_count");
2706 = grokfield (input_filename, lineno, field_decl, decl_specs, NULL_TREE);
2707 field_decl_chain = field_decl;
2709 /* struct objc_method method_list[]; */
2711 decl_specs = build_tree_list (NULL_TREE, list_type);
2712 field_decl = build_nt (ARRAY_REF, get_identifier ("method_list"),
2713 build_int_2 (size, 0));
2716 = grokfield (input_filename, lineno, field_decl, decl_specs, NULL_TREE);
2717 chainon (field_decl_chain, field_decl);
2719 finish_struct (objc_ivar_list_record, field_decl_chain, NULL_TREE);
2721 return objc_ivar_list_record;
2725 build_method_prototype_template ()
2728 tree decl_specs, field_decl, field_decl_chain;
2731 = start_struct (RECORD_TYPE, get_identifier (UTAG_METHOD_PROTOTYPE));
2733 #ifdef OBJC_INT_SELECTORS
2734 /* unsigned int _cmd; */
2736 = tree_cons (NULL_TREE, ridpointers[(int) RID_UNSIGNED], NULL_TREE);
2737 decl_specs = tree_cons (NULL_TREE, ridpointers[(int) RID_INT], decl_specs);
2738 field_decl = get_identifier ("_cmd");
2739 #else /* OBJC_INT_SELECTORS */
2740 /* struct objc_selector *_cmd; */
2741 decl_specs = tree_cons (NULL_TREE, xref_tag (RECORD_TYPE,
2742 get_identifier (TAG_SELECTOR)), NULL_TREE);
2743 field_decl = build1 (INDIRECT_REF, NULL_TREE, get_identifier ("_cmd"));
2744 #endif /* OBJC_INT_SELECTORS */
2747 = grokfield (input_filename, lineno, field_decl, decl_specs, NULL_TREE);
2748 field_decl_chain = field_decl;
2750 decl_specs = tree_cons (NULL_TREE, ridpointers[(int) RID_CHAR], NULL_TREE);
2752 = build1 (INDIRECT_REF, NULL_TREE, get_identifier ("method_types"));
2754 = grokfield (input_filename, lineno, field_decl, decl_specs, NULL_TREE);
2755 chainon (field_decl_chain, field_decl);
2757 finish_struct (proto_record, field_decl_chain, NULL_TREE);
2759 return proto_record;
2762 /* True if last call to forwarding_offset yielded a register offset. */
2763 static int offset_is_register;
2766 forwarding_offset (parm)
2769 int offset_in_bytes;
2771 if (GET_CODE (DECL_INCOMING_RTL (parm)) == MEM)
2773 rtx addr = XEXP (DECL_INCOMING_RTL (parm), 0);
2775 /* ??? Here we assume that the parm address is indexed
2776 off the frame pointer or arg pointer.
2777 If that is not true, we produce meaningless results,
2778 but do not crash. */
2779 if (GET_CODE (addr) == PLUS
2780 && GET_CODE (XEXP (addr, 1)) == CONST_INT)
2781 offset_in_bytes = INTVAL (XEXP (addr, 1));
2783 offset_in_bytes = 0;
2785 offset_in_bytes += OBJC_FORWARDING_STACK_OFFSET;
2786 offset_is_register = 0;
2788 else if (GET_CODE (DECL_INCOMING_RTL (parm)) == REG)
2790 int regno = REGNO (DECL_INCOMING_RTL (parm));
2791 offset_in_bytes = apply_args_register_offset (regno);
2792 offset_is_register = 1;
2797 /* This is the case where the parm is passed as an int or double
2798 and it is converted to a char, short or float and stored back
2799 in the parmlist. In this case, describe the parm
2800 with the variable's declared type, and adjust the address
2801 if the least significant bytes (which we are using) are not
2803 if (BYTES_BIG_ENDIAN && TREE_TYPE (parm) != DECL_ARG_TYPE (parm))
2804 offset_in_bytes += (GET_MODE_SIZE (TYPE_MODE (DECL_ARG_TYPE (parm)))
2805 - GET_MODE_SIZE (GET_MODE (DECL_RTL (parm))));
2807 return offset_in_bytes;
2811 encode_method_prototype (method_decl, func_decl)
2818 int max_parm_end = 0;
2822 /* ONEWAY and BYCOPY, for remote object are the only method qualifiers. */
2823 encode_type_qualifiers (TREE_PURPOSE (TREE_TYPE (method_decl)));
2826 encode_type (TREE_TYPE (TREE_TYPE (func_decl)),
2827 obstack_object_size (&util_obstack),
2828 OBJC_ENCODE_INLINE_DEFS);
2831 for (parms = DECL_ARGUMENTS (func_decl); parms;
2832 parms = TREE_CHAIN (parms))
2834 int parm_end = (forwarding_offset (parms)
2835 + (TREE_INT_CST_LOW (TYPE_SIZE (TREE_TYPE (parms)))
2838 if (!offset_is_register && max_parm_end < parm_end)
2839 max_parm_end = parm_end;
2842 stack_size = max_parm_end - OBJC_FORWARDING_MIN_OFFSET;
2844 sprintf (buf, "%d", stack_size);
2845 obstack_grow (&util_obstack, buf, strlen (buf));
2847 user_args = METHOD_SEL_ARGS (method_decl);
2849 /* Argument types. */
2850 for (parms = DECL_ARGUMENTS (func_decl), i = 0; parms;
2851 parms = TREE_CHAIN (parms), i++)
2853 /* Process argument qualifiers for user supplied arguments. */
2856 encode_type_qualifiers (TREE_PURPOSE (TREE_TYPE (user_args)));
2857 user_args = TREE_CHAIN (user_args);
2861 encode_type (TREE_TYPE (parms),
2862 obstack_object_size (&util_obstack),
2863 OBJC_ENCODE_INLINE_DEFS);
2865 /* Compute offset. */
2866 sprintf (buf, "%d", forwarding_offset (parms));
2868 /* Indicate register. */
2869 if (offset_is_register)
2870 obstack_1grow (&util_obstack, '+');
2872 obstack_grow (&util_obstack, buf, strlen (buf));
2875 obstack_1grow (&util_obstack, '\0');
2876 result = get_identifier (obstack_finish (&util_obstack));
2877 obstack_free (&util_obstack, util_firstobj);
2882 generate_descriptor_table (type, name, size, list, proto)
2889 tree sc_spec, decl_specs, decl, initlist;
2891 sc_spec = tree_cons (NULL_TREE, ridpointers[(int) RID_STATIC], NULL_TREE);
2892 decl_specs = tree_cons (NULL_TREE, type, sc_spec);
2894 decl = start_decl (synth_id_with_class_suffix (name, proto),
2895 decl_specs, 1, NULL_TREE, NULL_TREE);
2897 initlist = build_tree_list (NULL_TREE, build_int_2 (size, 0));
2898 initlist = tree_cons (NULL_TREE, list, initlist);
2900 finish_decl (decl, build_constructor (type, nreverse (initlist)),
2907 generate_method_descriptors (protocol) /* generate_dispatch_tables */
2910 static tree objc_method_prototype_template;
2911 tree initlist, chain, method_list_template;
2912 tree cast, variable_length_type;
2915 if (!objc_method_prototype_template)
2916 objc_method_prototype_template = build_method_prototype_template ();
2918 cast = build_tree_list (build_tree_list (NULL_TREE, xref_tag (RECORD_TYPE,
2919 get_identifier (UTAG_METHOD_PROTOTYPE_LIST))),
2921 variable_length_type = groktypename (cast);
2923 chain = PROTOCOL_CLS_METHODS (protocol);
2926 size = list_length (chain);
2928 method_list_template
2929 = build_method_prototype_list_template (objc_method_prototype_template,
2933 = build_descriptor_table_initializer (objc_method_prototype_template,
2936 UOBJC_CLASS_METHODS_decl
2937 = generate_descriptor_table (method_list_template,
2938 "_OBJC_PROTOCOL_CLASS_METHODS",
2939 size, initlist, protocol);
2940 TREE_TYPE (UOBJC_CLASS_METHODS_decl) = variable_length_type;
2943 UOBJC_CLASS_METHODS_decl = 0;
2945 chain = PROTOCOL_NST_METHODS (protocol);
2948 size = list_length (chain);
2950 method_list_template
2951 = build_method_prototype_list_template (objc_method_prototype_template,
2954 = build_descriptor_table_initializer (objc_method_prototype_template,
2957 UOBJC_INSTANCE_METHODS_decl
2958 = generate_descriptor_table (method_list_template,
2959 "_OBJC_PROTOCOL_INSTANCE_METHODS",
2960 size, initlist, protocol);
2961 TREE_TYPE (UOBJC_INSTANCE_METHODS_decl) = variable_length_type;
2964 UOBJC_INSTANCE_METHODS_decl = 0;
2968 build_tmp_function_decl ()
2970 tree decl_specs, expr_decl, parms;
2974 /* struct objc_object *objc_xxx (id, SEL, ...); */
2976 decl_specs = build_tree_list (NULL_TREE, objc_object_reference);
2977 push_parm_decl (build_tree_list
2978 (build_tree_list (decl_specs,
2979 build1 (INDIRECT_REF, NULL_TREE,
2981 build_tree_list (NULL_TREE, NULL_TREE)));
2983 decl_specs = build_tree_list (NULL_TREE, xref_tag (RECORD_TYPE,
2984 get_identifier (TAG_SELECTOR)));
2985 expr_decl = build1 (INDIRECT_REF, NULL_TREE, NULL_TREE);
2987 push_parm_decl (build_tree_list (build_tree_list (decl_specs, expr_decl),
2988 build_tree_list (NULL_TREE, NULL_TREE)));
2989 parms = get_parm_info (0);
2992 decl_specs = build_tree_list (NULL_TREE, objc_object_reference);
2993 sprintf (buffer, "__objc_tmp_%x", xxx++);
2994 expr_decl = build_nt (CALL_EXPR, get_identifier (buffer), parms, NULL_TREE);
2995 expr_decl = build1 (INDIRECT_REF, NULL_TREE, expr_decl);
2997 return define_decl (expr_decl, decl_specs);
3001 hack_method_prototype (nst_methods, tmp_decl)
3008 /* Hack to avoid problem with static typing of self arg. */
3009 TREE_SET_CODE (nst_methods, CLASS_METHOD_DECL);
3010 start_method_def (nst_methods);
3011 TREE_SET_CODE (nst_methods, INSTANCE_METHOD_DECL);
3013 if (METHOD_ADD_ARGS (nst_methods) == (tree) 1)
3014 parms = get_parm_info (0); /* we have a `, ...' */
3016 parms = get_parm_info (1); /* place a `void_at_end' */
3018 poplevel (0, 0, 0); /* Must be called BEFORE start_function. */
3020 /* Usually called from store_parm_decls -> init_function_start. */
3022 DECL_ARGUMENTS (tmp_decl) = TREE_PURPOSE (parms);
3023 current_function_decl = tmp_decl;
3026 /* Code taken from start_function. */
3027 tree restype = TREE_TYPE (TREE_TYPE (tmp_decl));
3028 /* Promote the value to int before returning it. */
3029 if (TREE_CODE (restype) == INTEGER_TYPE
3030 && TYPE_PRECISION (restype) < TYPE_PRECISION (integer_type_node))
3031 restype = integer_type_node;
3032 DECL_RESULT (tmp_decl) = build_decl (RESULT_DECL, 0, restype);
3035 for (parm = DECL_ARGUMENTS (tmp_decl); parm; parm = TREE_CHAIN (parm))
3036 DECL_CONTEXT (parm) = tmp_decl;
3038 init_function_start (tmp_decl, "objc-act", 0);
3040 /* Typically called from expand_function_start for function definitions. */
3041 assign_parms (tmp_decl, 0);
3043 /* install return type */
3044 TREE_TYPE (TREE_TYPE (tmp_decl)) = groktypename (TREE_TYPE (nst_methods));
3049 generate_protocol_references (plist)
3054 /* Forward declare protocols referenced. */
3055 for (lproto = plist; lproto; lproto = TREE_CHAIN (lproto))
3057 tree proto = TREE_VALUE (lproto);
3059 if (TREE_CODE (proto) == PROTOCOL_INTERFACE_TYPE
3060 && PROTOCOL_NAME (proto))
3062 if (! PROTOCOL_FORWARD_DECL (proto))
3063 build_protocol_reference (proto);
3065 if (PROTOCOL_LIST (proto))
3066 generate_protocol_references (PROTOCOL_LIST (proto));
3072 generate_protocols ()
3074 tree p, tmp_decl, encoding;
3075 tree sc_spec, decl_specs, decl;
3076 tree initlist, protocol_name_expr, refs_decl, refs_expr;
3077 tree cast_type2 = 0;
3079 tmp_decl = build_tmp_function_decl ();
3081 if (! objc_protocol_template)
3082 objc_protocol_template = build_protocol_template ();
3084 /* If a protocol was directly referenced, pull in indirect references. */
3085 for (p = protocol_chain; p; p = TREE_CHAIN (p))
3086 if (PROTOCOL_FORWARD_DECL (p) && PROTOCOL_LIST (p))
3087 generate_protocol_references (PROTOCOL_LIST (p));
3089 for (p = protocol_chain; p; p = TREE_CHAIN (p))
3091 tree nst_methods = PROTOCOL_NST_METHODS (p);
3092 tree cls_methods = PROTOCOL_CLS_METHODS (p);
3094 /* If protocol wasn't referenced, don't generate any code. */
3095 if (! PROTOCOL_FORWARD_DECL (p))
3098 /* Make sure we link in the Protocol class. */
3099 add_class_reference (get_identifier (PROTOCOL_OBJECT_CLASS_NAME));
3103 if (! METHOD_ENCODING (nst_methods))
3105 hack_method_prototype (nst_methods, tmp_decl);
3106 encoding = encode_method_prototype (nst_methods, tmp_decl);
3107 METHOD_ENCODING (nst_methods) = encoding;
3109 nst_methods = TREE_CHAIN (nst_methods);
3114 if (! METHOD_ENCODING (cls_methods))
3116 hack_method_prototype (cls_methods, tmp_decl);
3117 encoding = encode_method_prototype (cls_methods, tmp_decl);
3118 METHOD_ENCODING (cls_methods) = encoding;
3121 cls_methods = TREE_CHAIN (cls_methods);
3123 generate_method_descriptors (p);
3125 if (PROTOCOL_LIST (p))
3126 refs_decl = generate_protocol_list (p);
3130 /* static struct objc_protocol _OBJC_PROTOCOL_<mumble>; */
3132 sc_spec = tree_cons (NULL_TREE, ridpointers[(int) RID_STATIC],
3134 decl_specs = tree_cons (NULL_TREE, objc_protocol_template, sc_spec);
3136 decl = start_decl (synth_id_with_class_suffix ("_OBJC_PROTOCOL", p),
3137 decl_specs, 1, NULL_TREE, NULL_TREE);
3139 protocol_name_expr = add_objc_string (PROTOCOL_NAME (p), class_names);
3146 (build_tree_list (build_tree_list (NULL_TREE,
3147 objc_protocol_template),
3148 build1 (INDIRECT_REF, NULL_TREE,
3149 build1 (INDIRECT_REF, NULL_TREE,
3152 refs_expr = build_unary_op (ADDR_EXPR, refs_decl, 0);
3153 TREE_TYPE (refs_expr) = cast_type2;
3156 refs_expr = build_int_2 (0, 0);
3158 /* UOBJC_INSTANCE_METHODS_decl/UOBJC_CLASS_METHODS_decl are set
3159 by generate_method_descriptors, which is called above. */
3160 initlist = build_protocol_initializer (TREE_TYPE (decl),
3161 protocol_name_expr, refs_expr,
3162 UOBJC_INSTANCE_METHODS_decl,
3163 UOBJC_CLASS_METHODS_decl);
3164 finish_decl (decl, initlist, NULL_TREE);
3166 /* Mark the decl as used to avoid "defined but not used" warning. */
3167 TREE_USED (decl) = 1;
3172 build_protocol_initializer (type, protocol_name, protocol_list,
3173 instance_methods, class_methods)
3177 tree instance_methods;
3180 tree initlist = NULL_TREE, expr;
3181 static tree cast_type = 0;
3187 (build_tree_list (NULL_TREE,
3188 xref_tag (RECORD_TYPE,
3189 get_identifier (UTAG_CLASS))),
3190 build1 (INDIRECT_REF, NULL_TREE, NULL_TREE)));
3192 /* Filling the "isa" in with one allows the runtime system to
3193 detect that the version change...should remove before final release. */
3195 expr = build_int_2 (PROTOCOL_VERSION, 0);
3196 TREE_TYPE (expr) = cast_type;
3197 initlist = tree_cons (NULL_TREE, expr, initlist);
3198 initlist = tree_cons (NULL_TREE, protocol_name, initlist);
3199 initlist = tree_cons (NULL_TREE, protocol_list, initlist);
3201 if (!instance_methods)
3202 initlist = tree_cons (NULL_TREE, build_int_2 (0, 0), initlist);
3205 expr = build_unary_op (ADDR_EXPR, instance_methods, 0);
3206 initlist = tree_cons (NULL_TREE, expr, initlist);
3210 initlist = tree_cons (NULL_TREE, build_int_2 (0, 0), initlist);
3213 expr = build_unary_op (ADDR_EXPR, class_methods, 0);
3214 initlist = tree_cons (NULL_TREE, expr, initlist);
3217 return build_constructor (type, nreverse (initlist));
3220 /* struct objc_category {
3221 char *category_name;
3223 struct objc_method_list *instance_methods;
3224 struct objc_method_list *class_methods;
3225 struct objc_protocol_list *protocols;
3229 build_category_template ()
3231 tree decl_specs, field_decl, field_decl_chain;
3233 objc_category_template = start_struct (RECORD_TYPE,
3234 get_identifier (UTAG_CATEGORY));
3235 /* char *category_name; */
3237 decl_specs = build_tree_list (NULL_TREE, ridpointers[(int) RID_CHAR]);
3239 = build1 (INDIRECT_REF, NULL_TREE, get_identifier ("category_name"));
3241 = grokfield (input_filename, lineno, field_decl, decl_specs, NULL_TREE);
3242 field_decl_chain = field_decl;
3244 /* char *class_name; */
3246 decl_specs = build_tree_list (NULL_TREE, ridpointers[(int) RID_CHAR]);
3247 field_decl = build1 (INDIRECT_REF, NULL_TREE, get_identifier ("class_name"));
3249 = grokfield (input_filename, lineno, field_decl, decl_specs, NULL_TREE);
3250 chainon (field_decl_chain, field_decl);
3252 /* struct objc_method_list *instance_methods; */
3254 decl_specs = build_tree_list (NULL_TREE,
3255 xref_tag (RECORD_TYPE,
3256 get_identifier (UTAG_METHOD_LIST)));
3258 = build1 (INDIRECT_REF, NULL_TREE, get_identifier ("instance_methods"));
3260 = grokfield (input_filename, lineno, field_decl, decl_specs, NULL_TREE);
3261 chainon (field_decl_chain, field_decl);
3263 /* struct objc_method_list *class_methods; */
3265 decl_specs = build_tree_list (NULL_TREE,
3266 xref_tag (RECORD_TYPE,
3267 get_identifier (UTAG_METHOD_LIST)));
3269 = build1 (INDIRECT_REF, NULL_TREE, get_identifier ("class_methods"));
3271 = grokfield (input_filename, lineno, field_decl, decl_specs, NULL_TREE);
3272 chainon (field_decl_chain, field_decl);
3274 /* struct objc_protocol **protocol_list; */
3276 decl_specs = build_tree_list (NULL_TREE,
3277 xref_tag (RECORD_TYPE,
3278 get_identifier (UTAG_PROTOCOL)));
3280 = build1 (INDIRECT_REF, NULL_TREE, get_identifier ("protocol_list"));
3281 field_decl = build1 (INDIRECT_REF, NULL_TREE, field_decl);
3283 = grokfield (input_filename, lineno, field_decl, decl_specs, NULL_TREE);
3284 chainon (field_decl_chain, field_decl);
3286 finish_struct (objc_category_template, field_decl_chain, NULL_TREE);
3289 /* struct objc_selector {
3295 build_selector_template ()
3298 tree decl_specs, field_decl, field_decl_chain;
3300 objc_selector_template
3301 = start_struct (RECORD_TYPE, get_identifier (UTAG_SELECTOR));
3305 decl_specs = build_tree_list (NULL_TREE, ridpointers[(int) RID_VOID]);
3306 field_decl = build1 (INDIRECT_REF, NULL_TREE, get_identifier ("sel_id"));
3308 = grokfield (input_filename, lineno, field_decl, decl_specs, NULL_TREE);
3309 field_decl_chain = field_decl;
3311 /* char *sel_type; */
3313 decl_specs = build_tree_list (NULL_TREE, ridpointers[(int) RID_CHAR]);
3314 field_decl = build1 (INDIRECT_REF, NULL_TREE, get_identifier ("sel_type"));
3316 = grokfield (input_filename, lineno, field_decl, decl_specs, NULL_TREE);
3317 chainon (field_decl_chain, field_decl);
3319 finish_struct (objc_selector_template, field_decl_chain, NULL_TREE);
3322 /* struct objc_class {
3323 struct objc_class *isa;
3324 struct objc_class *super_class;
3329 struct objc_ivar_list *ivars;
3330 struct objc_method_list *methods;
3331 if (flag_next_runtime)
3332 struct objc_cache *cache;
3334 struct sarray *dtable;
3335 struct objc_class *subclass_list;
3336 struct objc_class *sibling_class;
3338 struct objc_protocol_list *protocols;
3342 build_class_template ()
3344 tree decl_specs, field_decl, field_decl_chain;
3347 = start_struct (RECORD_TYPE, get_identifier (UTAG_CLASS));
3349 /* struct objc_class *isa; */
3351 decl_specs = build_tree_list (NULL_TREE, objc_class_template);
3352 field_decl = build1 (INDIRECT_REF, NULL_TREE, get_identifier ("isa"));
3354 = grokfield (input_filename, lineno, field_decl, decl_specs, NULL_TREE);
3355 field_decl_chain = field_decl;
3357 /* struct objc_class *super_class; */
3359 decl_specs = build_tree_list (NULL_TREE, objc_class_template);
3361 = build1 (INDIRECT_REF, NULL_TREE, get_identifier ("super_class"));
3363 = grokfield (input_filename, lineno, field_decl, decl_specs, NULL_TREE);
3364 chainon (field_decl_chain, field_decl);
3368 decl_specs = build_tree_list (NULL_TREE, ridpointers[(int) RID_CHAR]);
3369 field_decl = build1 (INDIRECT_REF, NULL_TREE, get_identifier ("name"));
3371 = grokfield (input_filename, lineno, field_decl, decl_specs, NULL_TREE);
3372 chainon (field_decl_chain, field_decl);
3376 decl_specs = build_tree_list (NULL_TREE, ridpointers[(int) RID_LONG]);
3377 field_decl = get_identifier ("version");
3379 = grokfield (input_filename, lineno, field_decl, decl_specs, NULL_TREE);
3380 chainon (field_decl_chain, field_decl);
3384 decl_specs = build_tree_list (NULL_TREE, ridpointers[(int) RID_LONG]);
3385 field_decl = get_identifier ("info");
3387 = grokfield (input_filename, lineno, field_decl, decl_specs, NULL_TREE);
3388 chainon (field_decl_chain, field_decl);
3390 /* long instance_size; */
3392 decl_specs = build_tree_list (NULL_TREE, ridpointers[(int) RID_LONG]);
3393 field_decl = get_identifier ("instance_size");
3395 = grokfield (input_filename, lineno, field_decl, decl_specs, NULL_TREE);
3396 chainon (field_decl_chain, field_decl);
3398 /* struct objc_ivar_list *ivars; */
3400 decl_specs = build_tree_list (NULL_TREE,
3401 xref_tag (RECORD_TYPE,
3402 get_identifier (UTAG_IVAR_LIST)));
3403 field_decl = build1 (INDIRECT_REF, NULL_TREE, get_identifier ("ivars"));
3405 = grokfield (input_filename, lineno, field_decl, decl_specs, NULL_TREE);
3406 chainon (field_decl_chain, field_decl);
3408 /* struct objc_method_list *methods; */
3410 decl_specs = build_tree_list (NULL_TREE,
3411 xref_tag (RECORD_TYPE,
3412 get_identifier (UTAG_METHOD_LIST)));
3413 field_decl = build1 (INDIRECT_REF, NULL_TREE, get_identifier ("methods"));
3415 = grokfield (input_filename, lineno, field_decl, decl_specs, NULL_TREE);
3416 chainon (field_decl_chain, field_decl);
3418 if (flag_next_runtime)
3420 /* struct objc_cache *cache; */
3422 decl_specs = build_tree_list (NULL_TREE,
3423 xref_tag (RECORD_TYPE,
3424 get_identifier ("objc_cache")));
3425 field_decl = build1 (INDIRECT_REF, NULL_TREE, get_identifier ("cache"));
3426 field_decl = grokfield (input_filename, lineno, field_decl,
3427 decl_specs, NULL_TREE);
3428 chainon (field_decl_chain, field_decl);
3432 /* struct sarray *dtable; */
3434 decl_specs = build_tree_list (NULL_TREE,
3435 xref_tag (RECORD_TYPE,
3436 get_identifier ("sarray")));
3437 field_decl = build1 (INDIRECT_REF, NULL_TREE, get_identifier ("dtable"));
3438 field_decl = grokfield (input_filename, lineno, field_decl,
3439 decl_specs, NULL_TREE);
3440 chainon (field_decl_chain, field_decl);
3442 /* struct objc_class *subclass_list; */
3444 decl_specs = build_tree_list (NULL_TREE, objc_class_template);
3446 = build1 (INDIRECT_REF, NULL_TREE, get_identifier ("subclass_list"));
3447 field_decl = grokfield (input_filename, lineno, field_decl,
3448 decl_specs, NULL_TREE);
3449 chainon (field_decl_chain, field_decl);
3451 /* struct objc_class *sibling_class; */
3453 decl_specs = build_tree_list (NULL_TREE, objc_class_template);
3455 = build1 (INDIRECT_REF, NULL_TREE, get_identifier ("sibling_class"));
3456 field_decl = grokfield (input_filename, lineno, field_decl,
3457 decl_specs, NULL_TREE);
3458 chainon (field_decl_chain, field_decl);
3461 /* struct objc_protocol **protocol_list; */
3463 decl_specs = build_tree_list (NULL_TREE,
3464 xref_tag (RECORD_TYPE,
3465 get_identifier (UTAG_PROTOCOL)));
3467 = build1 (INDIRECT_REF, NULL_TREE, get_identifier ("protocol_list"));
3469 = build1 (INDIRECT_REF, NULL_TREE, field_decl);
3470 field_decl = grokfield (input_filename, lineno, field_decl,
3471 decl_specs, NULL_TREE);
3472 chainon (field_decl_chain, field_decl);
3475 finish_struct (objc_class_template, field_decl_chain, NULL_TREE);
3478 /* Generate appropriate forward declarations for an implementation. */
3481 synth_forward_declarations ()
3483 tree sc_spec, decl_specs, an_id;
3485 /* extern struct objc_class _OBJC_CLASS_<my_name>; */
3487 an_id = synth_id_with_class_suffix ("_OBJC_CLASS", implementation_context);
3489 sc_spec = build_tree_list (NULL_TREE, ridpointers[(int) RID_EXTERN]);
3490 decl_specs = tree_cons (NULL_TREE, objc_class_template, sc_spec);
3491 UOBJC_CLASS_decl = define_decl (an_id, decl_specs);
3492 TREE_USED (UOBJC_CLASS_decl) = 1;
3493 DECL_ARTIFICIAL (UOBJC_CLASS_decl) = 1;
3495 /* extern struct objc_class _OBJC_METACLASS_<my_name>; */
3497 an_id = synth_id_with_class_suffix ("_OBJC_METACLASS",
3498 implementation_context);
3500 UOBJC_METACLASS_decl = define_decl (an_id, decl_specs);
3501 TREE_USED (UOBJC_METACLASS_decl) = 1;
3502 DECL_ARTIFICIAL(UOBJC_METACLASS_decl) = 1;
3504 /* Pre-build the following entities - for speed/convenience. */
3506 an_id = get_identifier ("super_class");
3507 ucls_super_ref = build_component_ref (UOBJC_CLASS_decl, an_id);
3508 uucls_super_ref = build_component_ref (UOBJC_METACLASS_decl, an_id);
3512 error_with_ivar (message, decl, rawdecl)
3519 report_error_function (DECL_SOURCE_FILE (decl));
3521 fprintf (stderr, "%s:%d: ",
3522 DECL_SOURCE_FILE (decl), DECL_SOURCE_LINE (decl));
3523 bzero (errbuf, BUFSIZE);
3524 fprintf (stderr, "%s `%s'\n", message, gen_declaration (rawdecl, errbuf));
3527 #define USERTYPE(t) \
3528 (TREE_CODE (t) == RECORD_TYPE || TREE_CODE (t) == UNION_TYPE \
3529 || TREE_CODE (t) == ENUMERAL_TYPE)
3532 check_ivars (inter, imp)
3536 tree intdecls = CLASS_IVARS (inter);
3537 tree impdecls = CLASS_IVARS (imp);
3538 tree rawintdecls = CLASS_RAW_IVARS (inter);
3539 tree rawimpdecls = CLASS_RAW_IVARS (imp);
3545 if (intdecls == 0 && impdecls == 0)
3547 if (intdecls == 0 || impdecls == 0)
3549 error ("inconsistent instance variable specification");
3553 t1 = TREE_TYPE (intdecls); t2 = TREE_TYPE (impdecls);
3555 if (!comptypes (t1, t2))
3557 if (DECL_NAME (intdecls) == DECL_NAME (impdecls))
3559 error_with_ivar ("conflicting instance variable type",
3560 impdecls, rawimpdecls);
3561 error_with_ivar ("previous declaration of",
3562 intdecls, rawintdecls);
3564 else /* both the type and the name don't match */
3566 error ("inconsistent instance variable specification");
3571 else if (DECL_NAME (intdecls) != DECL_NAME (impdecls))
3573 error_with_ivar ("conflicting instance variable name",
3574 impdecls, rawimpdecls);
3575 error_with_ivar ("previous declaration of",
3576 intdecls, rawintdecls);
3579 intdecls = TREE_CHAIN (intdecls);
3580 impdecls = TREE_CHAIN (impdecls);
3581 rawintdecls = TREE_CHAIN (rawintdecls);
3582 rawimpdecls = TREE_CHAIN (rawimpdecls);
3586 /* Set super_type to the data type node for struct objc_super *,
3587 first defining struct objc_super itself.
3588 This needs to be done just once per compilation. */
3591 build_super_template ()
3593 tree record, decl_specs, field_decl, field_decl_chain;
3595 record = start_struct (RECORD_TYPE, get_identifier (UTAG_SUPER));
3597 /* struct objc_object *self; */
3599 decl_specs = build_tree_list (NULL_TREE, objc_object_reference);
3600 field_decl = get_identifier ("self");
3601 field_decl = build1 (INDIRECT_REF, NULL_TREE, field_decl);
3602 field_decl = grokfield (input_filename, lineno,
3603 field_decl, decl_specs, NULL_TREE);
3604 field_decl_chain = field_decl;
3606 /* struct objc_class *class; */
3608 decl_specs = get_identifier (UTAG_CLASS);
3609 decl_specs = build_tree_list (NULL_TREE, xref_tag (RECORD_TYPE, decl_specs));
3610 field_decl = build1 (INDIRECT_REF, NULL_TREE, get_identifier ("class"));
3612 field_decl = grokfield (input_filename, lineno,
3613 field_decl, decl_specs, NULL_TREE);
3614 chainon (field_decl_chain, field_decl);
3616 finish_struct (record, field_decl_chain, NULL_TREE);
3618 /* `struct objc_super *' */
3619 super_type = groktypename (build_tree_list (build_tree_list (NULL_TREE,
3621 build1 (INDIRECT_REF,
3622 NULL_TREE, NULL_TREE)));
3626 /* struct objc_ivar {
3633 build_ivar_template ()
3635 tree objc_ivar_id, objc_ivar_record;
3636 tree decl_specs, field_decl, field_decl_chain;
3638 objc_ivar_id = get_identifier (UTAG_IVAR);
3639 objc_ivar_record = start_struct (RECORD_TYPE, objc_ivar_id);
3641 /* char *ivar_name; */
3643 decl_specs = build_tree_list (NULL_TREE, ridpointers[(int) RID_CHAR]);
3644 field_decl = build1 (INDIRECT_REF, NULL_TREE, get_identifier ("ivar_name"));
3646 field_decl = grokfield (input_filename, lineno, field_decl,
3647 decl_specs, NULL_TREE);
3648 field_decl_chain = field_decl;
3650 /* char *ivar_type; */
3652 decl_specs = build_tree_list (NULL_TREE, ridpointers[(int) RID_CHAR]);
3653 field_decl = build1 (INDIRECT_REF, NULL_TREE, get_identifier ("ivar_type"));
3655 field_decl = grokfield (input_filename, lineno, field_decl,
3656 decl_specs, NULL_TREE);
3657 chainon (field_decl_chain, field_decl);
3659 /* int ivar_offset; */
3661 decl_specs = build_tree_list (NULL_TREE, ridpointers[(int) RID_INT]);
3662 field_decl = get_identifier ("ivar_offset");
3664 field_decl = grokfield (input_filename, lineno, field_decl,
3665 decl_specs, NULL_TREE);
3666 chainon (field_decl_chain, field_decl);
3668 finish_struct (objc_ivar_record, field_decl_chain, NULL_TREE);
3670 return objc_ivar_record;
3675 struct objc_ivar ivar_list[ivar_count];
3679 build_ivar_list_template (list_type, size)
3683 tree objc_ivar_list_record;
3684 tree decl_specs, field_decl, field_decl_chain;
3686 objc_ivar_list_record = start_struct (RECORD_TYPE, NULL_TREE);
3688 /* int ivar_count; */
3690 decl_specs = build_tree_list (NULL_TREE, ridpointers[(int) RID_INT]);
3691 field_decl = get_identifier ("ivar_count");
3693 field_decl = grokfield (input_filename, lineno, field_decl,
3694 decl_specs, NULL_TREE);
3695 field_decl_chain = field_decl;
3697 /* struct objc_ivar ivar_list[]; */
3699 decl_specs = build_tree_list (NULL_TREE, list_type);
3700 field_decl = build_nt (ARRAY_REF, get_identifier ("ivar_list"),
3701 build_int_2 (size, 0));
3703 field_decl = grokfield (input_filename, lineno,
3704 field_decl, decl_specs, NULL_TREE);
3705 chainon (field_decl_chain, field_decl);
3707 finish_struct (objc_ivar_list_record, field_decl_chain, NULL_TREE);
3709 return objc_ivar_list_record;
3715 struct objc_method method_list[method_count];
3719 build_method_list_template (list_type, size)
3723 tree objc_ivar_list_record;
3724 tree decl_specs, field_decl, field_decl_chain;
3726 objc_ivar_list_record = start_struct (RECORD_TYPE, NULL_TREE);
3728 /* int method_next; */
3733 xref_tag (RECORD_TYPE,
3734 get_identifier (UTAG_METHOD_PROTOTYPE_LIST)));
3736 = build1 (INDIRECT_REF, NULL_TREE, get_identifier ("method_next"));
3737 field_decl = grokfield (input_filename, lineno, field_decl,
3738 decl_specs, NULL_TREE);
3739 field_decl_chain = field_decl;
3741 /* int method_count; */
3743 decl_specs = build_tree_list (NULL_TREE, ridpointers[(int) RID_INT]);
3744 field_decl = get_identifier ("method_count");
3746 field_decl = grokfield (input_filename, lineno,
3747 field_decl, decl_specs, NULL_TREE);
3748 chainon (field_decl_chain, field_decl);
3750 /* struct objc_method method_list[]; */
3752 decl_specs = build_tree_list (NULL_TREE, list_type);
3753 field_decl = build_nt (ARRAY_REF, get_identifier ("method_list"),
3754 build_int_2 (size, 0));
3756 field_decl = grokfield (input_filename, lineno,
3757 field_decl, decl_specs, NULL_TREE);
3758 chainon (field_decl_chain, field_decl);
3760 finish_struct (objc_ivar_list_record, field_decl_chain, NULL_TREE);
3762 return objc_ivar_list_record;
3766 build_ivar_list_initializer (type, field_decl)
3770 tree initlist = NULL_TREE;
3774 tree ivar = NULL_TREE;
3777 if (DECL_NAME (field_decl))
3778 ivar = tree_cons (NULL_TREE,
3779 add_objc_string (DECL_NAME (field_decl),
3783 /* Unnamed bit-field ivar (yuck). */
3784 ivar = tree_cons (NULL_TREE, build_int_2 (0, 0), ivar);
3787 encode_field_decl (field_decl,
3788 obstack_object_size (&util_obstack),
3789 OBJC_ENCODE_DONT_INLINE_DEFS);
3791 /* Null terminate string. */
3792 obstack_1grow (&util_obstack, 0);
3796 add_objc_string (get_identifier (obstack_finish (&util_obstack)),
3799 obstack_free (&util_obstack, util_firstobj);
3805 build_int_2 ((TREE_INT_CST_LOW (DECL_FIELD_BITPOS (field_decl))
3810 initlist = tree_cons (NULL_TREE,
3811 build_constructor (type, nreverse (ivar)),
3814 field_decl = TREE_CHAIN (field_decl);
3818 return build_constructor (build_array_type (type, 0), nreverse (initlist));
3822 generate_ivars_list (type, name, size, list)
3828 tree sc_spec, decl_specs, decl, initlist;
3830 sc_spec = tree_cons (NULL_TREE, ridpointers[(int) RID_STATIC], NULL_TREE);
3831 decl_specs = tree_cons (NULL_TREE, type, sc_spec);
3833 decl = start_decl (synth_id_with_class_suffix (name, implementation_context),
3834 decl_specs, 1, NULL_TREE, NULL_TREE);
3836 initlist = build_tree_list (NULL_TREE, build_int_2 (size, 0));
3837 initlist = tree_cons (NULL_TREE, list, initlist);
3840 build_constructor (TREE_TYPE (decl), nreverse (initlist)),
3847 generate_ivar_lists ()
3849 tree initlist, ivar_list_template, chain;
3850 tree cast, variable_length_type;
3853 generating_instance_variables = 1;
3855 if (!objc_ivar_template)
3856 objc_ivar_template = build_ivar_template ();
3860 (build_tree_list (NULL_TREE, xref_tag (RECORD_TYPE,
3861 get_identifier (UTAG_IVAR_LIST))),
3863 variable_length_type = groktypename (cast);
3865 /* Only generate class variables for the root of the inheritance
3866 hierarchy since these will be the same for every class. */
3868 if (CLASS_SUPER_NAME (implementation_template) == NULL_TREE
3869 && (chain = TYPE_FIELDS (objc_class_template)))
3871 size = list_length (chain);
3873 ivar_list_template = build_ivar_list_template (objc_ivar_template, size);
3874 initlist = build_ivar_list_initializer (objc_ivar_template, chain);
3876 UOBJC_CLASS_VARIABLES_decl
3877 = generate_ivars_list (ivar_list_template, "_OBJC_CLASS_VARIABLES",
3879 TREE_TYPE (UOBJC_CLASS_VARIABLES_decl) = variable_length_type;
3882 UOBJC_CLASS_VARIABLES_decl = 0;
3884 chain = CLASS_IVARS (implementation_template);
3887 size = list_length (chain);
3888 ivar_list_template = build_ivar_list_template (objc_ivar_template, size);
3889 initlist = build_ivar_list_initializer (objc_ivar_template, chain);
3891 UOBJC_INSTANCE_VARIABLES_decl
3892 = generate_ivars_list (ivar_list_template, "_OBJC_INSTANCE_VARIABLES",
3894 TREE_TYPE (UOBJC_INSTANCE_VARIABLES_decl) = variable_length_type;
3897 UOBJC_INSTANCE_VARIABLES_decl = 0;
3899 generating_instance_variables = 0;
3903 build_dispatch_table_initializer (type, entries)
3907 tree initlist = NULL_TREE;
3911 tree elemlist = NULL_TREE;
3913 elemlist = tree_cons (NULL_TREE,
3914 build_selector (METHOD_SEL_NAME (entries)),
3917 elemlist = tree_cons (NULL_TREE,
3918 add_objc_string (METHOD_ENCODING (entries),
3922 elemlist = tree_cons (NULL_TREE,
3923 build_unary_op (ADDR_EXPR,
3924 METHOD_DEFINITION (entries), 1),
3927 initlist = tree_cons (NULL_TREE,
3928 build_constructor (type, nreverse (elemlist)),
3931 entries = TREE_CHAIN (entries);
3935 return build_constructor (build_array_type (type, 0), nreverse (initlist));
3938 /* To accomplish method prototyping without generating all kinds of
3939 inane warnings, the definition of the dispatch table entries were
3942 struct objc_method { SEL _cmd; ...; id (*_imp)(); };
3944 struct objc_method { SEL _cmd; ...; void *_imp; }; */
3947 build_method_template ()
3950 tree decl_specs, field_decl, field_decl_chain;
3952 _SLT_record = start_struct (RECORD_TYPE, get_identifier (UTAG_METHOD));
3954 #ifdef OBJC_INT_SELECTORS
3955 /* unsigned int _cmd; */
3956 decl_specs = tree_cons (NULL_TREE, ridpointers[(int) RID_UNSIGNED],
3958 decl_specs = tree_cons (NULL_TREE, ridpointers[(int) RID_INT], decl_specs);
3959 field_decl = get_identifier ("_cmd");
3960 #else /* not OBJC_INT_SELECTORS */
3961 /* struct objc_selector *_cmd; */
3962 decl_specs = tree_cons (NULL_TREE,
3963 xref_tag (RECORD_TYPE,
3964 get_identifier (TAG_SELECTOR)),
3966 field_decl = build1 (INDIRECT_REF, NULL_TREE, get_identifier ("_cmd"));
3967 #endif /* not OBJC_INT_SELECTORS */
3969 field_decl = grokfield (input_filename, lineno, field_decl,
3970 decl_specs, NULL_TREE);
3971 field_decl_chain = field_decl;
3973 decl_specs = tree_cons (NULL_TREE, ridpointers[(int) RID_CHAR], NULL_TREE);
3974 field_decl = build1 (INDIRECT_REF, NULL_TREE,
3975 get_identifier ("method_types"));
3976 field_decl = grokfield (input_filename, lineno, field_decl,
3977 decl_specs, NULL_TREE);
3978 chainon (field_decl_chain, field_decl);
3982 decl_specs = tree_cons (NULL_TREE, ridpointers[(int) RID_VOID], NULL_TREE);
3983 field_decl = build1 (INDIRECT_REF, NULL_TREE, get_identifier ("_imp"));
3984 field_decl = grokfield (input_filename, lineno, field_decl,
3985 decl_specs, NULL_TREE);
3986 chainon (field_decl_chain, field_decl);
3988 finish_struct (_SLT_record, field_decl_chain, NULL_TREE);
3995 generate_dispatch_table (type, name, size, list)
4001 tree sc_spec, decl_specs, decl, initlist;
4003 sc_spec = tree_cons (NULL_TREE, ridpointers[(int) RID_STATIC], NULL_TREE);
4004 decl_specs = tree_cons (NULL_TREE, type, sc_spec);
4006 decl = start_decl (synth_id_with_class_suffix (name, implementation_context),
4007 decl_specs, 1, NULL_TREE, NULL_TREE);
4009 initlist = build_tree_list (NULL_TREE, build_int_2 (0, 0));
4010 initlist = tree_cons (NULL_TREE, build_int_2 (size, 0), initlist);
4011 initlist = tree_cons (NULL_TREE, list, initlist);
4014 build_constructor (TREE_TYPE (decl), nreverse (initlist)),
4021 generate_dispatch_tables ()
4023 tree initlist, chain, method_list_template;
4024 tree cast, variable_length_type;
4027 if (!objc_method_template)
4028 objc_method_template = build_method_template ();
4032 (build_tree_list (NULL_TREE,
4033 xref_tag (RECORD_TYPE,
4034 get_identifier (UTAG_METHOD_LIST))),
4037 variable_length_type = groktypename (cast);
4039 chain = CLASS_CLS_METHODS (implementation_context);
4042 size = list_length (chain);
4044 method_list_template
4045 = build_method_list_template (objc_method_template, size);
4047 = build_dispatch_table_initializer (objc_method_template, chain);
4049 UOBJC_CLASS_METHODS_decl
4050 = generate_dispatch_table (method_list_template,
4051 ((TREE_CODE (implementation_context)
4052 == CLASS_IMPLEMENTATION_TYPE)
4053 ? "_OBJC_CLASS_METHODS"
4054 : "_OBJC_CATEGORY_CLASS_METHODS"),
4056 TREE_TYPE (UOBJC_CLASS_METHODS_decl) = variable_length_type;
4059 UOBJC_CLASS_METHODS_decl = 0;
4061 chain = CLASS_NST_METHODS (implementation_context);
4064 size = list_length (chain);
4066 method_list_template
4067 = build_method_list_template (objc_method_template, size);
4069 = build_dispatch_table_initializer (objc_method_template, chain);
4071 if (TREE_CODE (implementation_context) == CLASS_IMPLEMENTATION_TYPE)
4072 UOBJC_INSTANCE_METHODS_decl
4073 = generate_dispatch_table (method_list_template,
4074 "_OBJC_INSTANCE_METHODS",
4077 /* We have a category. */
4078 UOBJC_INSTANCE_METHODS_decl
4079 = generate_dispatch_table (method_list_template,
4080 "_OBJC_CATEGORY_INSTANCE_METHODS",
4082 TREE_TYPE (UOBJC_INSTANCE_METHODS_decl) = variable_length_type;
4085 UOBJC_INSTANCE_METHODS_decl = 0;
4089 generate_protocol_list (i_or_p)
4092 static tree cast_type = 0;
4093 tree initlist, decl_specs, sc_spec;
4094 tree refs_decl, expr_decl, lproto, e, plist;
4097 if (TREE_CODE (i_or_p) == CLASS_INTERFACE_TYPE
4098 || TREE_CODE (i_or_p) == CATEGORY_INTERFACE_TYPE)
4099 plist = CLASS_PROTOCOL_LIST (i_or_p);
4100 else if (TREE_CODE (i_or_p) == PROTOCOL_INTERFACE_TYPE)
4101 plist = PROTOCOL_LIST (i_or_p);
4109 (build_tree_list (NULL_TREE,
4110 xref_tag (RECORD_TYPE,
4111 get_identifier (UTAG_PROTOCOL))),
4112 build1 (INDIRECT_REF, NULL_TREE, NULL_TREE)));
4115 for (lproto = plist; lproto; lproto = TREE_CHAIN (lproto))
4116 if (TREE_CODE (TREE_VALUE (lproto)) == PROTOCOL_INTERFACE_TYPE
4117 && PROTOCOL_FORWARD_DECL (TREE_VALUE (lproto)))
4120 /* Build initializer. */
4121 initlist = tree_cons (NULL_TREE, build_int_2 (0, 0), NULL_TREE);
4123 e = build_int_2 (size, 0);
4124 TREE_TYPE (e) = cast_type;
4125 initlist = tree_cons (NULL_TREE, e, initlist);
4127 for (lproto = plist; lproto; lproto = TREE_CHAIN (lproto))
4129 tree pval = TREE_VALUE (lproto);
4131 if (TREE_CODE (pval) == PROTOCOL_INTERFACE_TYPE
4132 && PROTOCOL_FORWARD_DECL (pval))
4134 e = build_unary_op (ADDR_EXPR, PROTOCOL_FORWARD_DECL (pval), 0);
4135 initlist = tree_cons (NULL_TREE, e, initlist);
4139 /* static struct objc_protocol *refs[n]; */
4141 sc_spec = tree_cons (NULL_TREE, ridpointers[(int) RID_STATIC], NULL_TREE);
4142 decl_specs = tree_cons (NULL_TREE, xref_tag (RECORD_TYPE,
4143 get_identifier (UTAG_PROTOCOL)),
4146 if (TREE_CODE (i_or_p) == PROTOCOL_INTERFACE_TYPE)
4147 expr_decl = build_nt (ARRAY_REF,
4148 synth_id_with_class_suffix ("_OBJC_PROTOCOL_REFS",
4150 build_int_2 (size + 2, 0));
4151 else if (TREE_CODE (i_or_p) == CLASS_INTERFACE_TYPE)
4152 expr_decl = build_nt (ARRAY_REF,
4153 synth_id_with_class_suffix ("_OBJC_CLASS_PROTOCOLS",
4155 build_int_2 (size + 2, 0));
4156 else if (TREE_CODE (i_or_p) == CATEGORY_INTERFACE_TYPE)
4158 = build_nt (ARRAY_REF,
4159 synth_id_with_class_suffix ("_OBJC_CATEGORY_PROTOCOLS",
4161 build_int_2 (size + 2, 0));
4163 expr_decl = build1 (INDIRECT_REF, NULL_TREE, expr_decl);
4165 refs_decl = start_decl (expr_decl, decl_specs, 1, NULL_TREE, NULL_TREE);
4167 finish_decl (refs_decl, build_constructor (TREE_TYPE (refs_decl),
4168 nreverse (initlist)),
4175 build_category_initializer (type, cat_name, class_name,
4176 instance_methods, class_methods, protocol_list)
4180 tree instance_methods;
4184 tree initlist = NULL_TREE, expr;
4186 initlist = tree_cons (NULL_TREE, cat_name, initlist);
4187 initlist = tree_cons (NULL_TREE, class_name, initlist);
4189 if (!instance_methods)
4190 initlist = tree_cons (NULL_TREE, build_int_2 (0, 0), initlist);
4193 expr = build_unary_op (ADDR_EXPR, instance_methods, 0);
4194 initlist = tree_cons (NULL_TREE, expr, initlist);
4197 initlist = tree_cons (NULL_TREE, build_int_2 (0, 0), initlist);
4200 expr = build_unary_op (ADDR_EXPR, class_methods, 0);
4201 initlist = tree_cons (NULL_TREE, expr, initlist);
4204 /* protocol_list = */
4206 initlist = tree_cons (NULL_TREE, build_int_2 (0, 0), initlist);
4209 static tree cast_type2;
4215 (build_tree_list (NULL_TREE,
4216 xref_tag (RECORD_TYPE,
4217 get_identifier (UTAG_PROTOCOL))),
4218 build1 (INDIRECT_REF, NULL_TREE,
4219 build1 (INDIRECT_REF, NULL_TREE, NULL_TREE))));
4221 expr = build_unary_op (ADDR_EXPR, protocol_list, 0);
4222 TREE_TYPE (expr) = cast_type2;
4223 initlist = tree_cons (NULL_TREE, expr, initlist);
4226 return build_constructor (type, nreverse (initlist));
4229 /* struct objc_class {
4230 struct objc_class *isa;
4231 struct objc_class *super_class;
4236 struct objc_ivar_list *ivars;
4237 struct objc_method_list *methods;
4238 if (flag_next_runtime)
4239 struct objc_cache *cache;
4241 struct sarray *dtable;
4242 struct objc_class *subclass_list;
4243 struct objc_class *sibling_class;
4245 struct objc_protocol_list *protocols;
4249 build_shared_structure_initializer (type, isa, super, name, size, status,
4250 dispatch_table, ivar_list, protocol_list)
4257 tree dispatch_table;
4261 tree initlist = NULL_TREE, expr;
4264 initlist = tree_cons (NULL_TREE, isa, initlist);
4267 initlist = tree_cons (NULL_TREE, super, initlist);
4270 initlist = tree_cons (NULL_TREE, default_conversion (name), initlist);
4273 initlist = tree_cons (NULL_TREE, build_int_2 (0, 0), initlist);
4276 initlist = tree_cons (NULL_TREE, build_int_2 (status, 0), initlist);
4278 /* instance_size = */
4279 initlist = tree_cons (NULL_TREE, size, initlist);
4281 /* objc_ivar_list = */
4283 initlist = tree_cons (NULL_TREE, build_int_2 (0, 0), initlist);
4286 expr = build_unary_op (ADDR_EXPR, ivar_list, 0);
4287 initlist = tree_cons (NULL_TREE, expr, initlist);
4290 /* objc_method_list = */
4291 if (!dispatch_table)
4292 initlist = tree_cons (NULL_TREE, build_int_2 (0, 0), initlist);
4295 expr = build_unary_op (ADDR_EXPR, dispatch_table, 0);
4296 initlist = tree_cons (NULL_TREE, expr, initlist);
4299 if (flag_next_runtime)
4300 /* method_cache = */
4301 initlist = tree_cons (NULL_TREE, build_int_2 (0, 0), initlist);
4305 initlist = tree_cons (NULL_TREE, build_int_2 (0, 0), initlist);
4307 /* subclass_list = */
4308 initlist = tree_cons (NULL_TREE, build_int_2 (0, 0), initlist);
4310 /* sibling_class = */
4311 initlist = tree_cons (NULL_TREE, build_int_2 (0, 0), initlist);
4314 /* protocol_list = */
4315 if (! protocol_list)
4316 initlist = tree_cons (NULL_TREE, build_int_2 (0, 0), initlist);
4319 static tree cast_type2;
4325 (build_tree_list (NULL_TREE,
4326 xref_tag (RECORD_TYPE,
4327 get_identifier (UTAG_PROTOCOL))),
4328 build1 (INDIRECT_REF, NULL_TREE,
4329 build1 (INDIRECT_REF, NULL_TREE, NULL_TREE))));
4331 expr = build_unary_op (ADDR_EXPR, protocol_list, 0);
4332 TREE_TYPE (expr) = cast_type2;
4333 initlist = tree_cons (NULL_TREE, expr, initlist);
4336 return build_constructor (type, nreverse (initlist));
4339 /* static struct objc_category _OBJC_CATEGORY_<name> = { ... }; */
4342 generate_category (cat)
4345 tree sc_spec, decl_specs, decl;
4346 tree initlist, cat_name_expr, class_name_expr;
4347 tree protocol_decl, category;
4349 add_class_reference (CLASS_NAME (cat));
4350 cat_name_expr = add_objc_string (CLASS_SUPER_NAME (cat), class_names);
4352 class_name_expr = add_objc_string (CLASS_NAME (cat), class_names);
4354 category = CLASS_CATEGORY_LIST (implementation_template);
4356 /* find the category interface from the class it is associated with */
4359 if (CLASS_SUPER_NAME (cat) == CLASS_SUPER_NAME (category))
4361 category = CLASS_CATEGORY_LIST (category);
4364 if (category && CLASS_PROTOCOL_LIST (category))
4366 generate_protocol_references (CLASS_PROTOCOL_LIST (category));
4367 protocol_decl = generate_protocol_list (category);
4372 sc_spec = tree_cons (NULL_TREE, ridpointers[(int) RID_STATIC], NULL_TREE);
4373 decl_specs = tree_cons (NULL_TREE, objc_category_template, sc_spec);
4375 decl = start_decl (synth_id_with_class_suffix ("_OBJC_CATEGORY",
4376 implementation_context),
4377 decl_specs, 1, NULL_TREE, NULL_TREE);
4379 initlist = build_category_initializer (TREE_TYPE (decl),
4380 cat_name_expr, class_name_expr,
4381 UOBJC_INSTANCE_METHODS_decl,
4382 UOBJC_CLASS_METHODS_decl,
4385 TREE_USED (decl) = 1;
4386 finish_decl (decl, initlist, NULL_TREE);
4389 /* static struct objc_class _OBJC_METACLASS_Foo={ ... };
4390 static struct objc_class _OBJC_CLASS_Foo={ ... }; */
4393 generate_shared_structures ()
4395 tree sc_spec, decl_specs, decl;
4396 tree name_expr, super_expr, root_expr;
4397 tree my_root_id = NULL_TREE, my_super_id = NULL_TREE;
4398 tree cast_type, initlist, protocol_decl;
4400 my_super_id = CLASS_SUPER_NAME (implementation_template);
4403 add_class_reference (my_super_id);
4405 /* Compute "my_root_id" - this is required for code generation.
4406 the "isa" for all meta class structures points to the root of
4407 the inheritance hierarchy (e.g. "__Object")... */
4408 my_root_id = my_super_id;
4411 tree my_root_int = lookup_interface (my_root_id);
4413 if (my_root_int && CLASS_SUPER_NAME (my_root_int))
4414 my_root_id = CLASS_SUPER_NAME (my_root_int);
4421 /* No super class. */
4422 my_root_id = CLASS_NAME (implementation_template);
4425 = groktypename (build_tree_list (build_tree_list (NULL_TREE,
4426 objc_class_template),
4427 build1 (INDIRECT_REF,
4428 NULL_TREE, NULL_TREE)));
4430 name_expr = add_objc_string (CLASS_NAME (implementation_template),
4433 /* Install class `isa' and `super' pointers at runtime. */
4436 super_expr = add_objc_string (my_super_id, class_names);
4437 super_expr = build_c_cast (cast_type, super_expr); /* cast! */
4440 super_expr = build_int_2 (0, 0);
4442 root_expr = add_objc_string (my_root_id, class_names);
4443 root_expr = build_c_cast (cast_type, root_expr); /* cast! */
4445 if (CLASS_PROTOCOL_LIST (implementation_template))
4447 generate_protocol_references
4448 (CLASS_PROTOCOL_LIST (implementation_template));
4449 protocol_decl = generate_protocol_list (implementation_template);
4454 /* static struct objc_class _OBJC_METACLASS_Foo = { ... }; */
4456 sc_spec = build_tree_list (NULL_TREE, ridpointers[(int) RID_STATIC]);
4457 decl_specs = tree_cons (NULL_TREE, objc_class_template, sc_spec);
4459 decl = start_decl (DECL_NAME (UOBJC_METACLASS_decl), decl_specs, 1,
4460 NULL_TREE, NULL_TREE);
4463 = build_shared_structure_initializer
4465 root_expr, super_expr, name_expr,
4466 build_int_2 ((TREE_INT_CST_LOW (TYPE_SIZE (objc_class_template))
4470 UOBJC_CLASS_METHODS_decl,
4471 UOBJC_CLASS_VARIABLES_decl,
4474 finish_decl (decl, initlist, NULL_TREE);
4476 /* static struct objc_class _OBJC_CLASS_Foo={ ... }; */
4478 decl = start_decl (DECL_NAME (UOBJC_CLASS_decl), decl_specs, 1,
4479 NULL_TREE, NULL_TREE);
4482 = build_shared_structure_initializer
4484 build_unary_op (ADDR_EXPR, UOBJC_METACLASS_decl, 0),
4485 super_expr, name_expr,
4488 (TYPE_SIZE (CLASS_STATIC_TEMPLATE (implementation_template)))
4492 UOBJC_INSTANCE_METHODS_decl,
4493 UOBJC_INSTANCE_VARIABLES_decl,
4496 finish_decl (decl, initlist, NULL_TREE);
4500 synth_id_with_class_suffix (preamble, ctxt)
4505 if (TREE_CODE (ctxt) == CLASS_IMPLEMENTATION_TYPE
4506 || TREE_CODE (ctxt) == CLASS_INTERFACE_TYPE)
4509 = IDENTIFIER_POINTER (CLASS_NAME (implementation_context));
4510 string = (char *) alloca (strlen (preamble) + strlen (class_name) + 3);
4511 sprintf (string, "%s_%s", preamble,
4512 IDENTIFIER_POINTER (CLASS_NAME (ctxt)));
4514 else if (TREE_CODE (ctxt) == CATEGORY_IMPLEMENTATION_TYPE
4515 || TREE_CODE (ctxt) == CATEGORY_INTERFACE_TYPE)
4517 /* We have a category. */
4519 = IDENTIFIER_POINTER (CLASS_NAME (implementation_context));
4520 char *class_super_name
4521 = IDENTIFIER_POINTER (CLASS_SUPER_NAME (implementation_context));
4522 string = (char *) alloca (strlen (preamble)
4523 + strlen (class_name)
4524 + strlen (class_super_name)
4526 sprintf (string, "%s_%s_%s", preamble, class_name, class_super_name);
4528 else if (TREE_CODE (ctxt) == PROTOCOL_INTERFACE_TYPE)
4530 char *protocol_name = IDENTIFIER_POINTER (PROTOCOL_NAME (ctxt));
4532 = (char *) alloca (strlen (preamble) + strlen (protocol_name) + 3);
4533 sprintf (string, "%s_%s", preamble, protocol_name);
4535 return get_identifier (string);
4539 is_objc_type_qualifier (node)
4542 return (TREE_CODE (node) == IDENTIFIER_NODE
4543 && (node == ridpointers [(int) RID_CONST]
4544 || node == ridpointers [(int) RID_VOLATILE]
4545 || node == ridpointers [(int) RID_IN]
4546 || node == ridpointers [(int) RID_OUT]
4547 || node == ridpointers [(int) RID_INOUT]
4548 || node == ridpointers [(int) RID_BYCOPY]
4549 || node == ridpointers [(int) RID_ONEWAY]));
4552 /* If type is empty or only type qualifiers are present, add default
4553 type of id (otherwise grokdeclarator will default to int). */
4556 adjust_type_for_id_default (type)
4559 tree declspecs, chain;
4562 return build_tree_list (build_tree_list (NULL_TREE, objc_object_reference),
4563 build1 (INDIRECT_REF, NULL_TREE, NULL_TREE));
4565 declspecs = TREE_PURPOSE (type);
4567 /* Determine if a typespec is present. */
4568 for (chain = declspecs;
4570 chain = TREE_CHAIN (chain))
4572 if (!is_objc_type_qualifier (TREE_VALUE (chain)))
4576 return build_tree_list (tree_cons (NULL_TREE, objc_object_reference,
4578 build1 (INDIRECT_REF, NULL_TREE, NULL_TREE));
4583 selector ':' '(' typename ')' identifier
4586 Transform an Objective-C keyword argument into
4587 the C equivalent parameter declarator.
4589 In: key_name, an "identifier_node" (optional).
4590 arg_type, a "tree_list" (optional).
4591 arg_name, an "identifier_node".
4593 Note: It would be really nice to strongly type the preceding
4594 arguments in the function prototype; however, then I
4595 could not use the "accessor" macros defined in "tree.h".
4597 Out: an instance of "keyword_decl". */
4600 build_keyword_decl (key_name, arg_type, arg_name)
4607 /* If no type is specified, default to "id". */
4608 arg_type = adjust_type_for_id_default (arg_type);
4610 keyword_decl = make_node (KEYWORD_DECL);
4612 TREE_TYPE (keyword_decl) = arg_type;
4613 KEYWORD_ARG_NAME (keyword_decl) = arg_name;
4614 KEYWORD_KEY_NAME (keyword_decl) = key_name;
4616 return keyword_decl;
4619 /* Given a chain of keyword_decl's, synthesize the full keyword selector. */
4622 build_keyword_selector (selector)
4626 tree key_chain, key_name;
4629 for (key_chain = selector; key_chain; key_chain = TREE_CHAIN (key_chain))
4631 if (TREE_CODE (selector) == KEYWORD_DECL)
4632 key_name = KEYWORD_KEY_NAME (key_chain);
4633 else if (TREE_CODE (selector) == TREE_LIST)
4634 key_name = TREE_PURPOSE (key_chain);
4637 len += IDENTIFIER_LENGTH (key_name) + 1;
4639 /* Just a ':' arg. */
4643 buf = (char *)alloca (len + 1);
4644 bzero (buf, len + 1);
4646 for (key_chain = selector; key_chain; key_chain = TREE_CHAIN (key_chain))
4648 if (TREE_CODE (selector) == KEYWORD_DECL)
4649 key_name = KEYWORD_KEY_NAME (key_chain);
4650 else if (TREE_CODE (selector) == TREE_LIST)
4651 key_name = TREE_PURPOSE (key_chain);
4654 strcat (buf, IDENTIFIER_POINTER (key_name));
4658 return get_identifier (buf);
4661 /* Used for declarations and definitions. */
4664 build_method_decl (code, ret_type, selector, add_args)
4665 enum tree_code code;
4672 /* If no type is specified, default to "id". */
4673 ret_type = adjust_type_for_id_default (ret_type);
4675 method_decl = make_node (code);
4676 TREE_TYPE (method_decl) = ret_type;
4678 /* If we have a keyword selector, create an identifier_node that
4679 represents the full selector name (`:' included)... */
4680 if (TREE_CODE (selector) == KEYWORD_DECL)
4682 METHOD_SEL_NAME (method_decl) = build_keyword_selector (selector);
4683 METHOD_SEL_ARGS (method_decl) = selector;
4684 METHOD_ADD_ARGS (method_decl) = add_args;
4688 METHOD_SEL_NAME (method_decl) = selector;
4689 METHOD_SEL_ARGS (method_decl) = NULL_TREE;
4690 METHOD_ADD_ARGS (method_decl) = NULL_TREE;
4696 #define METHOD_DEF 0
4697 #define METHOD_REF 1
4699 /* Used by `build_message_expr' and `comp_method_types'. Return an
4700 argument list for method METH. CONTEXT is either METHOD_DEF or
4701 METHOD_REF, saying whether we are trying to define a method or call
4702 one. SUPERFLAG says this is for a send to super; this makes a
4703 difference for the NeXT calling sequence in which the lookup and
4704 the method call are done together. */
4707 get_arg_type_list (meth, context, superflag)
4714 /* Receiver type. */
4715 if (flag_next_runtime && superflag)
4716 arglist = build_tree_list (NULL_TREE, super_type);
4717 else if (context == METHOD_DEF)
4718 arglist = build_tree_list (NULL_TREE, TREE_TYPE (self_decl));
4720 arglist = build_tree_list (NULL_TREE, id_type);
4722 /* Selector type - will eventually change to `int'. */
4723 chainon (arglist, build_tree_list (NULL_TREE, selector_type));
4725 /* Build a list of argument types. */
4726 for (akey = METHOD_SEL_ARGS (meth); akey; akey = TREE_CHAIN (akey))
4728 tree arg_decl = groktypename_in_parm_context (TREE_TYPE (akey));
4729 chainon (arglist, build_tree_list (NULL_TREE, TREE_TYPE (arg_decl)));
4732 if (METHOD_ADD_ARGS (meth) == (tree)1)
4733 /* We have a `, ...' immediately following the selector,
4734 finalize the arglist...simulate get_parm_info (0). */
4736 else if (METHOD_ADD_ARGS (meth))
4738 /* we have a variable length selector */
4739 tree add_arg_list = TREE_CHAIN (METHOD_ADD_ARGS (meth));
4740 chainon (arglist, add_arg_list);
4743 /* finalize the arglist...simulate get_parm_info (1) */
4744 chainon (arglist, build_tree_list (NULL_TREE, void_type_node));
4750 check_duplicates (hsh)
4753 tree meth = NULL_TREE;
4761 /* We have two methods with the same name and different types. */
4763 char type = (TREE_CODE (meth) == INSTANCE_METHOD_DECL) ? '-' : '+';
4765 warning ("multiple declarations for method `%s'",
4766 IDENTIFIER_POINTER (METHOD_SEL_NAME (meth)));
4768 warn_with_method ("using", type, meth);
4769 for (loop = hsh->list; loop; loop = loop->next)
4770 warn_with_method ("also found", type, loop->value);
4776 /* If RECEIVER is a class reference, return the identifier node for the
4777 referenced class. RECEIVER is created by get_class_reference, so we
4778 check the exact form created depending on which runtimes are used. */
4781 receiver_is_class_object (receiver)
4784 tree chain, exp, arg;
4785 if (flag_next_runtime)
4787 /* The receiver is a variable created by build_class_reference_decl. */
4788 if (TREE_CODE (receiver) == VAR_DECL
4789 && TREE_TYPE (receiver) == objc_class_type)
4790 /* Look up the identifier. */
4791 for (chain = cls_ref_chain; chain; chain = TREE_CHAIN (chain))
4792 if (TREE_PURPOSE (chain) == receiver)
4793 return TREE_VALUE (chain);
4797 /* The receiver is a function call that returns an id. Check if
4798 it is a call to objc_getClass, if so, pick up the class name. */
4799 if ((exp = TREE_OPERAND (receiver, 0))
4800 && TREE_CODE (exp) == ADDR_EXPR
4801 && (exp = TREE_OPERAND (exp, 0))
4802 && TREE_CODE (exp) == FUNCTION_DECL
4803 && exp == objc_get_class_decl
4804 /* we have a call to objc_getClass! */
4805 && (arg = TREE_OPERAND (receiver, 1))
4806 && TREE_CODE (arg) == TREE_LIST
4807 && (arg = TREE_VALUE (arg)))
4810 if (TREE_CODE (arg) == ADDR_EXPR
4811 && (arg = TREE_OPERAND (arg, 0))
4812 && TREE_CODE (arg) == STRING_CST)
4813 /* Finally, we have the class name. */
4814 return get_identifier (TREE_STRING_POINTER (arg));
4820 /* If we are currently building a message expr, this holds
4821 the identifier of the selector of the message. This is
4822 used when printing warnings about argument mismatches. */
4824 static tree building_objc_message_expr = 0;
4827 maybe_building_objc_message_expr ()
4829 return building_objc_message_expr;
4832 /* Construct an expression for sending a message.
4833 MESS has the object to send to in TREE_PURPOSE
4834 and the argument list (including selector) in TREE_VALUE.
4836 (*(<abstract_decl>(*)())_msg)(receiver, selTransTbl[n], ...);
4837 (*(<abstract_decl>(*)())_msgSuper)(receiver, selTransTbl[n], ...); */
4840 build_message_expr (mess)
4843 tree receiver = TREE_PURPOSE (mess);
4844 tree selector, self_object;
4845 tree rtype, sel_name;
4846 tree args = TREE_VALUE (mess);
4847 tree method_params = NULL_TREE;
4848 tree method_prototype = NULL_TREE;
4850 int statically_typed = 0, statically_allocated = 0;
4851 tree class_ident = 0;
4853 /* 1 if this is sending to the superclass. */
4856 if (!doing_objc_thang)
4859 if (TREE_CODE (receiver) == ERROR_MARK)
4860 return error_mark_node;
4862 /* Determine receiver type. */
4863 rtype = TREE_TYPE (receiver);
4864 super = IS_SUPER (rtype);
4868 if (TREE_STATIC_TEMPLATE (rtype))
4869 statically_allocated = 1;
4870 else if (TREE_CODE (rtype) == POINTER_TYPE
4871 && TREE_STATIC_TEMPLATE (TREE_TYPE (rtype)))
4872 statically_typed = 1;
4873 else if ((flag_next_runtime
4874 || (TREE_CODE (receiver) == CALL_EXPR && IS_ID (rtype)))
4875 && (class_ident = receiver_is_class_object (receiver)))
4877 else if (! IS_ID (rtype)
4878 /* Allow any type that matches objc_class_type. */
4879 && ! comptypes (rtype, objc_class_type))
4881 bzero (errbuf, BUFSIZE);
4882 warning ("invalid receiver type `%s'",
4883 gen_declaration (rtype, errbuf));
4886 if (statically_allocated)
4887 receiver = build_unary_op (ADDR_EXPR, receiver, 0);
4889 /* Don't evaluate the receiver twice. */
4890 receiver = save_expr (receiver);
4891 self_object = receiver;
4894 /* If sending to `super', use current self as the object. */
4895 self_object = self_decl;
4897 /* Obtain the full selector name. */
4899 if (TREE_CODE (args) == IDENTIFIER_NODE)
4900 /* A unary selector. */
4902 else if (TREE_CODE (args) == TREE_LIST)
4903 sel_name = build_keyword_selector (args);
4905 /* Build the parameter list to give to the method. */
4907 method_params = NULL_TREE;
4908 if (TREE_CODE (args) == TREE_LIST)
4910 tree chain = args, prev = NULL_TREE;
4912 /* We have a keyword selector--check for comma expressions. */
4915 tree element = TREE_VALUE (chain);
4917 /* We have a comma expression, must collapse... */
4918 if (TREE_CODE (element) == TREE_LIST)
4921 TREE_CHAIN (prev) = element;
4926 chain = TREE_CHAIN (chain);
4928 method_params = args;
4931 /* Determine operation return type. */
4933 if (IS_SUPER (rtype))
4937 if (CLASS_SUPER_NAME (implementation_template))
4940 = lookup_interface (CLASS_SUPER_NAME (implementation_template));
4942 if (TREE_CODE (method_context) == INSTANCE_METHOD_DECL)
4943 method_prototype = lookup_instance_method_static (iface, sel_name);
4945 method_prototype = lookup_class_method_static (iface, sel_name);
4947 if (iface && !method_prototype)
4948 warning ("`%s' does not respond to `%s'",
4949 IDENTIFIER_POINTER (CLASS_SUPER_NAME (implementation_template)),
4950 IDENTIFIER_POINTER (sel_name));
4954 error ("no super class declared in interface for `%s'",
4955 IDENTIFIER_POINTER (CLASS_NAME (implementation_template)));
4956 return error_mark_node;
4960 else if (statically_allocated)
4962 tree ctype = TREE_TYPE (rtype);
4963 tree iface = lookup_interface (TYPE_NAME (rtype));
4966 method_prototype = lookup_instance_method_static (iface, sel_name);
4968 if (! method_prototype && TYPE_PROTOCOL_LIST (ctype))
4970 = lookup_method_in_protocol_list (TYPE_PROTOCOL_LIST (ctype),
4973 if (!method_prototype)
4974 warning ("`%s' does not respond to `%s'",
4975 IDENTIFIER_POINTER (TYPE_NAME (rtype)),
4976 IDENTIFIER_POINTER (sel_name));
4978 else if (statically_typed)
4980 tree ctype = TREE_TYPE (rtype);
4982 /* `self' is now statically_typed. All methods should be visible
4983 within the context of the implementation. */
4984 if (implementation_context
4985 && CLASS_NAME (implementation_context) == TYPE_NAME (ctype))
4988 = lookup_instance_method_static (implementation_template,
4991 if (! method_prototype && TYPE_PROTOCOL_LIST (ctype))
4993 = lookup_method_in_protocol_list (TYPE_PROTOCOL_LIST (ctype),
4996 if (! method_prototype
4997 && implementation_template != implementation_context)
4998 /* The method is not published in the interface. Check
5001 = lookup_method (CLASS_NST_METHODS (implementation_context),
5008 if ((iface = lookup_interface (TYPE_NAME (ctype))))
5009 method_prototype = lookup_instance_method_static (iface, sel_name);
5011 if (! method_prototype)
5013 tree protocol_list = TYPE_PROTOCOL_LIST (ctype);
5016 = lookup_method_in_protocol_list (protocol_list,
5021 if (!method_prototype)
5022 warning ("`%s' does not respond to `%s'",
5023 IDENTIFIER_POINTER (TYPE_NAME (ctype)),
5024 IDENTIFIER_POINTER (sel_name));
5026 else if (class_ident)
5028 if (implementation_context
5029 && CLASS_NAME (implementation_context) == class_ident)
5032 = lookup_class_method_static (implementation_template, sel_name);
5034 if (!method_prototype
5035 && implementation_template != implementation_context)
5036 /* The method is not published in the interface. Check
5039 = lookup_method (CLASS_CLS_METHODS (implementation_context),
5046 if ((iface = lookup_interface (class_ident)))
5047 method_prototype = lookup_class_method_static (iface, sel_name);
5050 if (!method_prototype)
5052 warning ("cannot find class (factory) method.");
5053 warning ("return type for `%s' defaults to id",
5054 IDENTIFIER_POINTER (sel_name));
5057 else if (IS_PROTOCOL_QUALIFIED_ID (rtype))
5059 /* An anonymous object that has been qualified with a protocol. */
5061 tree protocol_list = TYPE_PROTOCOL_LIST (rtype);
5063 method_prototype = lookup_method_in_protocol_list (protocol_list,
5066 if (!method_prototype)
5070 warning ("method `%s' not implemented by protocol.",
5071 IDENTIFIER_POINTER (sel_name));
5073 /* Try and find the method signature in the global pools. */
5075 if (!(hsh = hash_lookup (nst_method_hash_list, sel_name)))
5076 hsh = hash_lookup (cls_method_hash_list, sel_name);
5078 if (!(method_prototype = check_duplicates (hsh)))
5079 warning ("return type defaults to id");
5086 /* We think we have an instance...loophole: extern id Object; */
5087 hsh = hash_lookup (nst_method_hash_list, sel_name);
5089 /* For various loopholes, like sending messages to self in a
5091 hsh = hash_lookup (cls_method_hash_list, sel_name);
5093 method_prototype = check_duplicates (hsh);
5094 if (!method_prototype)
5096 warning ("cannot find method.");
5097 warning ("return type for `%s' defaults to id",
5098 IDENTIFIER_POINTER (sel_name));
5102 /* Save the selector name for printing error messages. */
5103 building_objc_message_expr = sel_name;
5105 /* Build the parameters list for looking up the method.
5106 These are the object itself and the selector. */
5108 if (flag_typed_selectors)
5109 selector = build_typed_selector_reference (sel_name, method_prototype);
5111 selector = build_selector_reference (sel_name);
5113 retval = build_objc_method_call (super, method_prototype,
5114 receiver, self_object,
5115 selector, method_params);
5117 building_objc_message_expr = 0;
5122 /* Build a tree expression to send OBJECT the operation SELECTOR,
5123 looking up the method on object LOOKUP_OBJECT (often same as OBJECT),
5124 assuming the method has prototype METHOD_PROTOTYPE.
5125 (That is an INSTANCE_METHOD_DECL or CLASS_METHOD_DECL.)
5126 Use METHOD_PARAMS as list of args to pass to the method.
5127 If SUPER_FLAG is nonzero, we look up the superclass's method. */
5130 build_objc_method_call (super_flag, method_prototype, lookup_object, object,
5131 selector, method_params)
5133 tree method_prototype, lookup_object, object, selector, method_params;
5135 tree sender = (super_flag ? umsg_super_decl : umsg_decl);
5136 tree rcv_p = (super_flag
5137 ? build_pointer_type (xref_tag (RECORD_TYPE,
5138 get_identifier (TAG_SUPER)))
5141 if (flag_next_runtime)
5143 if (! method_prototype)
5145 method_params = tree_cons (NULL_TREE, lookup_object,
5146 tree_cons (NULL_TREE, selector,
5148 assemble_external (sender);
5149 return build_function_call (sender, method_params);
5153 /* This is a real kludge, but it is used only for the Next.
5154 Clobber the data type of SENDER temporarily to accept
5155 all the arguments for this operation, and to return
5156 whatever this operation returns. */
5157 tree arglist = NULL_TREE;
5160 /* Save the proper contents of SENDER's data type. */
5161 tree savarg = TYPE_ARG_TYPES (TREE_TYPE (sender));
5162 tree savret = TREE_TYPE (TREE_TYPE (sender));
5164 /* Install this method's argument types. */
5165 arglist = get_arg_type_list (method_prototype, METHOD_REF,
5167 TYPE_ARG_TYPES (TREE_TYPE (sender)) = arglist;
5169 /* Install this method's return type. */
5170 TREE_TYPE (TREE_TYPE (sender))
5171 = groktypename (TREE_TYPE (method_prototype));
5173 /* Call SENDER with all the parameters. This will do type
5174 checking using the arg types for this method. */
5175 method_params = tree_cons (NULL_TREE, lookup_object,
5176 tree_cons (NULL_TREE, selector,
5178 assemble_external (sender);
5179 retval = build_function_call (sender, method_params);
5181 /* Restore SENDER's return/argument types. */
5182 TYPE_ARG_TYPES (TREE_TYPE (sender)) = savarg;
5183 TREE_TYPE (TREE_TYPE (sender)) = savret;
5189 /* This is the portable way.
5190 First call the lookup function to get a pointer to the method,
5191 then cast the pointer, then call it with the method arguments. */
5194 /* Avoid trouble since we may evaluate each of these twice. */
5195 object = save_expr (object);
5196 selector = save_expr (selector);
5198 lookup_object = build_c_cast (rcv_p, lookup_object);
5200 assemble_external (sender);
5202 = build_function_call (sender,
5203 tree_cons (NULL_TREE, lookup_object,
5204 tree_cons (NULL_TREE, selector,
5207 /* If we have a method prototype, construct the data type this
5208 method needs, and cast what we got from SENDER into a pointer
5210 if (method_prototype)
5212 tree arglist = get_arg_type_list (method_prototype, METHOD_REF,
5214 tree valtype = groktypename (TREE_TYPE (method_prototype));
5215 tree fake_function_type = build_function_type (valtype, arglist);
5216 TREE_TYPE (method) = build_pointer_type (fake_function_type);
5220 = build_pointer_type (build_function_type (ptr_type_node, NULL_TREE));
5222 /* Pass the object to the method. */
5223 assemble_external (method);
5224 return build_function_call (method,
5225 tree_cons (NULL_TREE, object,
5226 tree_cons (NULL_TREE, selector,
5232 build_protocol_reference (p)
5235 tree decl, ident, ptype;
5237 push_obstacks_nochange ();
5238 end_temporary_allocation ();
5240 /* extern struct objc_protocol _OBJC_PROTOCOL_<mumble>; */
5242 ident = synth_id_with_class_suffix ("_OBJC_PROTOCOL", p);
5244 = groktypename (build_tree_list (build_tree_list (NULL_TREE,
5245 objc_protocol_template),
5248 if (IDENTIFIER_GLOBAL_VALUE (ident))
5249 decl = IDENTIFIER_GLOBAL_VALUE (ident); /* Set by pushdecl. */
5252 decl = build_decl (VAR_DECL, ident, ptype);
5253 DECL_EXTERNAL (decl) = 1;
5254 TREE_PUBLIC (decl) = 1;
5255 TREE_USED (decl) = 1;
5256 DECL_ARTIFICIAL (decl) = 1;
5258 make_decl_rtl (decl, 0, 1);
5259 pushdecl_top_level (decl);
5262 PROTOCOL_FORWARD_DECL (p) = decl;
5267 build_protocol_expr (protoname)
5273 if (!doing_objc_thang)
5276 p = lookup_protocol (protoname);
5280 error ("Cannot find protocol declaration for `%s'",
5281 IDENTIFIER_POINTER (protoname));
5282 return error_mark_node;
5285 if (!PROTOCOL_FORWARD_DECL (p))
5286 build_protocol_reference (p);
5288 expr = build_unary_op (ADDR_EXPR, PROTOCOL_FORWARD_DECL (p), 0);
5290 TREE_TYPE (expr) = protocol_type;
5296 build_selector_expr (selnamelist)
5301 if (!doing_objc_thang)
5304 /* Obtain the full selector name. */
5305 if (TREE_CODE (selnamelist) == IDENTIFIER_NODE)
5306 /* A unary selector. */
5307 selname = selnamelist;
5308 else if (TREE_CODE (selnamelist) == TREE_LIST)
5309 selname = build_keyword_selector (selnamelist);
5311 if (flag_typed_selectors)
5312 return build_typed_selector_reference (selname, 0);
5314 return build_selector_reference (selname);
5318 build_encode_expr (type)
5324 if (!doing_objc_thang)
5327 encode_type (type, obstack_object_size (&util_obstack),
5328 OBJC_ENCODE_INLINE_DEFS);
5329 obstack_1grow (&util_obstack, 0); /* null terminate string */
5330 string = obstack_finish (&util_obstack);
5332 /* Synthesize a string that represents the encoded struct/union. */
5333 result = my_build_string (strlen (string) + 1, string);
5334 obstack_free (&util_obstack, util_firstobj);
5339 build_ivar_reference (id)
5342 if (TREE_CODE (method_context) == CLASS_METHOD_DECL)
5344 /* Historically, a class method that produced objects (factory
5345 method) would assign `self' to the instance that it
5346 allocated. This would effectively turn the class method into
5347 an instance method. Following this assignment, the instance
5348 variables could be accessed. That practice, while safe,
5349 violates the simple rule that a class method should not refer
5350 to an instance variable. It's better to catch the cases
5351 where this is done unknowingly than to support the above
5353 warning ("instance variable `%s' accessed in class method",
5354 IDENTIFIER_POINTER (id));
5355 TREE_TYPE (self_decl) = instance_type; /* cast */
5358 return build_component_ref (build_indirect_ref (self_decl, "->"), id);
5361 #define HASH_ALLOC_LIST_SIZE 170
5362 #define ATTR_ALLOC_LIST_SIZE 170
5363 #define SIZEHASHTABLE 257
5366 #define HASHFUNCTION(key) ((HOST_WIDE_INT) key & 0x7fffffff)
5371 nst_method_hash_list = (hash *)xmalloc (SIZEHASHTABLE * sizeof (hash));
5372 cls_method_hash_list = (hash *)xmalloc (SIZEHASHTABLE * sizeof (hash));
5374 if (!nst_method_hash_list || !cls_method_hash_list)
5375 perror ("unable to allocate space in objc-tree.c");
5380 for (i = 0; i < SIZEHASHTABLE; i++)
5382 nst_method_hash_list[i] = 0;
5383 cls_method_hash_list[i] = 0;
5389 hash_enter (hashlist, method)
5393 static hash hash_alloc_list = 0;
5394 static int hash_alloc_index = 0;
5396 int slot = HASHFUNCTION (METHOD_SEL_NAME (method)) % SIZEHASHTABLE;
5398 if (! hash_alloc_list || hash_alloc_index >= HASH_ALLOC_LIST_SIZE)
5400 hash_alloc_index = 0;
5401 hash_alloc_list = (hash) xmalloc (sizeof (struct hashed_entry)
5402 * HASH_ALLOC_LIST_SIZE);
5403 if (! hash_alloc_list)
5404 perror ("unable to allocate in objc-tree.c");
5406 obj = &hash_alloc_list[hash_alloc_index++];
5408 obj->next = hashlist[slot];
5411 hashlist[slot] = obj; /* append to front */
5415 hash_lookup (hashlist, sel_name)
5421 target = hashlist[HASHFUNCTION (sel_name) % SIZEHASHTABLE];
5425 if (sel_name == METHOD_SEL_NAME (target->key))
5428 target = target->next;
5434 hash_add_attr (entry, value)
5438 static attr attr_alloc_list = 0;
5439 static int attr_alloc_index = 0;
5442 if (! attr_alloc_list || attr_alloc_index >= ATTR_ALLOC_LIST_SIZE)
5444 attr_alloc_index = 0;
5445 attr_alloc_list = (attr) xmalloc (sizeof (struct hashed_attribute)
5446 * ATTR_ALLOC_LIST_SIZE);
5447 if (! attr_alloc_list)
5448 perror ("unable to allocate in objc-tree.c");
5450 obj = &attr_alloc_list[attr_alloc_index++];
5451 obj->next = entry->list;
5454 entry->list = obj; /* append to front */
5458 lookup_method (mchain, method)
5464 if (TREE_CODE (method) == IDENTIFIER_NODE)
5467 key = METHOD_SEL_NAME (method);
5471 if (METHOD_SEL_NAME (mchain) == key)
5473 mchain = TREE_CHAIN (mchain);
5479 lookup_instance_method_static (interface, ident)
5483 tree inter = interface;
5484 tree chain = CLASS_NST_METHODS (inter);
5485 tree meth = NULL_TREE;
5489 if ((meth = lookup_method (chain, ident)))
5492 if (CLASS_CATEGORY_LIST (inter))
5494 tree category = CLASS_CATEGORY_LIST (inter);
5495 chain = CLASS_NST_METHODS (category);
5499 if ((meth = lookup_method (chain, ident)))
5502 /* Check for instance methods in protocols in categories. */
5503 if (CLASS_PROTOCOL_LIST (category))
5505 if ((meth = (lookup_method_in_protocol_list
5506 (CLASS_PROTOCOL_LIST (category), ident, 0))))
5510 if ((category = CLASS_CATEGORY_LIST (category)))
5511 chain = CLASS_NST_METHODS (category);
5516 if (CLASS_PROTOCOL_LIST (inter))
5518 if ((meth = (lookup_method_in_protocol_list
5519 (CLASS_PROTOCOL_LIST (inter), ident, 0))))
5523 if ((inter = lookup_interface (CLASS_SUPER_NAME (inter))))
5524 chain = CLASS_NST_METHODS (inter);
5532 lookup_class_method_static (interface, ident)
5536 tree inter = interface;
5537 tree chain = CLASS_CLS_METHODS (inter);
5538 tree meth = NULL_TREE;
5539 tree root_inter = NULL_TREE;
5543 if ((meth = lookup_method (chain, ident)))
5546 if (CLASS_CATEGORY_LIST (inter))
5548 tree category = CLASS_CATEGORY_LIST (inter);
5549 chain = CLASS_CLS_METHODS (category);
5553 if ((meth = lookup_method (chain, ident)))
5556 /* Check for class methods in protocols in categories. */
5557 if (CLASS_PROTOCOL_LIST (category))
5559 if ((meth = (lookup_method_in_protocol_list
5560 (CLASS_PROTOCOL_LIST (category), ident, 1))))
5564 if ((category = CLASS_CATEGORY_LIST (category)))
5565 chain = CLASS_CLS_METHODS (category);
5570 /* Check for class methods in protocols. */
5571 if (CLASS_PROTOCOL_LIST (inter))
5573 if ((meth = (lookup_method_in_protocol_list
5574 (CLASS_PROTOCOL_LIST (inter), ident, 1))))
5579 if ((inter = lookup_interface (CLASS_SUPER_NAME (inter))))
5580 chain = CLASS_CLS_METHODS (inter);
5584 /* Simulate wrap around. */
5585 return lookup_instance_method_static (root_inter, ident);
5589 add_class_method (class, method)
5596 /* We will have allocated the method parameter declarations on the
5597 maybepermanent_obstack. Need to make sure they stick around! */
5600 if (!(mth = lookup_method (CLASS_CLS_METHODS (class), method)))
5602 /* put method on list in reverse order */
5603 TREE_CHAIN (method) = CLASS_CLS_METHODS (class);
5604 CLASS_CLS_METHODS (class) = method;
5608 if (TREE_CODE (class) == CLASS_IMPLEMENTATION_TYPE)
5609 error ("duplicate definition of class method `%s'.",
5610 IDENTIFIER_POINTER (METHOD_SEL_NAME (mth)));
5613 /* Check types; if different, complain. */
5614 if (!comp_proto_with_proto (method, mth))
5615 error ("duplicate declaration of class method `%s'.",
5616 IDENTIFIER_POINTER (METHOD_SEL_NAME (mth)));
5620 if (!(hsh = hash_lookup (cls_method_hash_list, METHOD_SEL_NAME (method))))
5622 /* Install on a global chain. */
5623 hash_enter (cls_method_hash_list, method);
5627 /* Check types; if different, add to a list. */
5628 if (!comp_proto_with_proto (method, hsh->key))
5629 hash_add_attr (hsh, method);
5635 add_instance_method (class, method)
5642 /* We will have allocated the method parameter declarations on the
5643 maybepermanent_obstack. Need to make sure they stick around! */
5646 if (!(mth = lookup_method (CLASS_NST_METHODS (class), method)))
5648 /* Put method on list in reverse order. */
5649 TREE_CHAIN (method) = CLASS_NST_METHODS (class);
5650 CLASS_NST_METHODS (class) = method;
5654 if (TREE_CODE (class) == CLASS_IMPLEMENTATION_TYPE)
5655 error ("duplicate definition of instance method `%s'.",
5656 IDENTIFIER_POINTER (METHOD_SEL_NAME (mth)));
5659 /* Check types; if different, complain. */
5660 if (!comp_proto_with_proto (method, mth))
5661 error ("duplicate declaration of instance method `%s'.",
5662 IDENTIFIER_POINTER (METHOD_SEL_NAME (mth)));
5666 if (!(hsh = hash_lookup (nst_method_hash_list, METHOD_SEL_NAME (method))))
5668 /* Install on a global chain. */
5669 hash_enter (nst_method_hash_list, method);
5673 /* Check types; if different, add to a list. */
5674 if (!comp_proto_with_proto (method, hsh->key))
5675 hash_add_attr (hsh, method);
5684 /* Put interfaces on list in reverse order. */
5685 TREE_CHAIN (class) = interface_chain;
5686 interface_chain = class;
5687 return interface_chain;
5691 add_category (class, category)
5695 /* Put categories on list in reverse order. */
5696 tree cat = CLASS_CATEGORY_LIST (class);
5700 if (CLASS_SUPER_NAME (cat) == CLASS_SUPER_NAME (category))
5701 warning ("duplicate interface declaration for category `%s(%s)'",
5702 IDENTIFIER_POINTER (CLASS_NAME (class)),
5703 IDENTIFIER_POINTER (CLASS_SUPER_NAME (category)));
5704 cat = CLASS_CATEGORY_LIST (cat);
5707 CLASS_CATEGORY_LIST (category) = CLASS_CATEGORY_LIST (class);
5708 CLASS_CATEGORY_LIST (class) = category;
5711 /* Called after parsing each instance variable declaration. Necessary to
5712 preserve typedefs and implement public/private...
5714 PUBLIC is 1 for public, 0 for protected, and 2 for private. */
5717 add_instance_variable (class, public, declarator, declspecs, width)
5724 tree field_decl, raw_decl;
5726 raw_decl = build_tree_list (declspecs, declarator);
5728 if (CLASS_RAW_IVARS (class))
5729 chainon (CLASS_RAW_IVARS (class), raw_decl);
5731 CLASS_RAW_IVARS (class) = raw_decl;
5733 field_decl = grokfield (input_filename, lineno,
5734 declarator, declspecs, width);
5736 /* Overload the public attribute, it is not used for FIELD_DECLs. */
5740 TREE_PUBLIC (field_decl) = 0;
5741 TREE_PRIVATE (field_decl) = 0;
5742 TREE_PROTECTED (field_decl) = 1;
5746 TREE_PUBLIC (field_decl) = 1;
5747 TREE_PRIVATE (field_decl) = 0;
5748 TREE_PROTECTED (field_decl) = 0;
5752 TREE_PUBLIC (field_decl) = 0;
5753 TREE_PRIVATE (field_decl) = 1;
5754 TREE_PROTECTED (field_decl) = 0;
5759 if (CLASS_IVARS (class))
5760 chainon (CLASS_IVARS (class), field_decl);
5762 CLASS_IVARS (class) = field_decl;
5768 is_ivar (decl_chain, ident)
5772 for ( ; decl_chain; decl_chain = TREE_CHAIN (decl_chain))
5773 if (DECL_NAME (decl_chain) == ident)
5778 /* True if the ivar is private and we are not in its implementation. */
5784 if (TREE_PRIVATE (decl)
5785 && ! is_ivar (CLASS_IVARS (implementation_template), DECL_NAME (decl)))
5787 error ("instance variable `%s' is declared private",
5788 IDENTIFIER_POINTER (DECL_NAME (decl)));
5795 /* We have an instance variable reference;, check to see if it is public. */
5798 is_public (expr, identifier)
5802 tree basetype = TREE_TYPE (expr);
5803 enum tree_code code = TREE_CODE (basetype);
5806 if (code == RECORD_TYPE)
5808 if (TREE_STATIC_TEMPLATE (basetype))
5810 if (!lookup_interface (TYPE_NAME (basetype)))
5812 error ("Cannot find interface declaration for `%s'",
5813 IDENTIFIER_POINTER (TYPE_NAME (basetype)));
5817 if ((decl = is_ivar (TYPE_FIELDS (basetype), identifier)))
5819 if (TREE_PUBLIC (decl))
5822 /* Important difference between the Stepstone translator:
5823 all instance variables should be public within the context
5824 of the implementation. */
5825 if (implementation_context
5826 && (((TREE_CODE (implementation_context)
5827 == CLASS_IMPLEMENTATION_TYPE)
5828 || (TREE_CODE (implementation_context)
5829 == CATEGORY_IMPLEMENTATION_TYPE))
5830 && (CLASS_NAME (implementation_context)
5831 == TYPE_NAME (basetype))))
5832 return ! is_private (decl);
5834 error ("instance variable `%s' is declared %s",
5835 IDENTIFIER_POINTER (identifier),
5836 TREE_PRIVATE (decl) ? "private" : "protected");
5841 else if (implementation_context && (basetype == objc_object_reference))
5843 TREE_TYPE (expr) = uprivate_record;
5844 warning ("static access to object of type `id'");
5851 /* Implement @defs (<classname>) within struct bodies. */
5854 get_class_ivars (interface)
5857 if (!doing_objc_thang)
5860 return build_ivar_chain (interface, 1);
5863 /* Make sure all entries in CHAIN are also in LIST. */
5866 check_methods (chain, list, mtype)
5875 if (!lookup_method (list, chain))
5879 if (TREE_CODE (implementation_context)
5880 == CLASS_IMPLEMENTATION_TYPE)
5881 warning ("incomplete implementation of class `%s'",
5882 IDENTIFIER_POINTER (CLASS_NAME (implementation_context)));
5883 else if (TREE_CODE (implementation_context)
5884 == CATEGORY_IMPLEMENTATION_TYPE)
5885 warning ("incomplete implementation of category `%s'",
5886 IDENTIFIER_POINTER (CLASS_SUPER_NAME (implementation_context)));
5890 warning ("method definition for `%c%s' not found",
5891 mtype, IDENTIFIER_POINTER (METHOD_SEL_NAME (chain)));
5894 chain = TREE_CHAIN (chain);
5901 conforms_to_protocol (class, protocol)
5907 tree p = CLASS_PROTOCOL_LIST (class);
5909 while (p && TREE_VALUE (p) != TREE_VALUE (protocol))
5914 tree super = (CLASS_SUPER_NAME (class)
5915 ? lookup_interface (CLASS_SUPER_NAME (class))
5917 int tmp = super ? conforms_to_protocol (super, protocol) : 0;
5922 protocol = TREE_CHAIN (protocol);
5928 /* Make sure all methods in CHAIN are accessible as MTYPE methods in
5929 CONTEXT. This is one of two mechanisms to check protocol integrity. */
5932 check_methods_accessible (chain, context, mtype)
5939 tree base_context = context;
5943 context = base_context;
5947 list = CLASS_CLS_METHODS (context);
5949 list = CLASS_NST_METHODS (context);
5951 if (lookup_method (list, chain))
5954 else if (TREE_CODE (context) == CLASS_IMPLEMENTATION_TYPE
5955 || TREE_CODE (context) == CLASS_INTERFACE_TYPE)
5956 context = (CLASS_SUPER_NAME (context)
5957 ? lookup_interface (CLASS_SUPER_NAME (context))
5960 else if (TREE_CODE (context) == CATEGORY_IMPLEMENTATION_TYPE
5961 || TREE_CODE (context) == CATEGORY_INTERFACE_TYPE)
5962 context = (CLASS_NAME (context)
5963 ? lookup_interface (CLASS_NAME (context))
5969 if (context == NULL_TREE)
5973 if (TREE_CODE (implementation_context)
5974 == CLASS_IMPLEMENTATION_TYPE)
5975 warning ("incomplete implementation of class `%s'",
5977 (CLASS_NAME (implementation_context)));
5978 else if (TREE_CODE (implementation_context)
5979 == CATEGORY_IMPLEMENTATION_TYPE)
5980 warning ("incomplete implementation of category `%s'",
5982 (CLASS_SUPER_NAME (implementation_context)));
5985 warning ("method definition for `%c%s' not found",
5986 mtype, IDENTIFIER_POINTER (METHOD_SEL_NAME (chain)));
5989 chain = TREE_CHAIN (chain); /* next method... */
5995 check_protocols (proto_list, type, name)
6000 for ( ; proto_list; proto_list = TREE_CHAIN (proto_list))
6002 tree p = TREE_VALUE (proto_list);
6004 if (TREE_CODE (p) == PROTOCOL_INTERFACE_TYPE)
6008 /* Ensure that all protocols have bodies. */
6009 if (flag_warn_protocol) {
6010 f1 = check_methods (PROTOCOL_CLS_METHODS (p),
6011 CLASS_CLS_METHODS (implementation_context),
6013 f2 = check_methods (PROTOCOL_NST_METHODS (p),
6014 CLASS_NST_METHODS (implementation_context),
6017 f1 = check_methods_accessible (PROTOCOL_CLS_METHODS (p),
6018 implementation_context,
6020 f2 = check_methods_accessible (PROTOCOL_NST_METHODS (p),
6021 implementation_context,
6026 warning ("%s `%s' does not fully implement the `%s' protocol",
6027 type, name, IDENTIFIER_POINTER (PROTOCOL_NAME (p)));
6031 ; /* An identifier if we could not find a protocol. */
6033 /* Check protocols recursively. */
6034 if (PROTOCOL_LIST (p))
6037 = lookup_interface (CLASS_SUPER_NAME (implementation_template));
6038 if (! conforms_to_protocol (super_class, PROTOCOL_LIST (p)))
6039 check_protocols (PROTOCOL_LIST (p), type, name);
6044 /* Make sure that the class CLASS_NAME is defined
6045 CODE says which kind of thing CLASS_NAME ought to be.
6046 It can be CLASS_INTERFACE_TYPE, CLASS_IMPLEMENTATION_TYPE,
6047 CATEGORY_INTERFACE_TYPE, or CATEGORY_IMPLEMENTATION_TYPE.
6049 If CODE is CLASS_INTERFACE_TYPE, we also do a push_obstacks_nochange
6050 whose matching pop is in continue_class. */
6053 start_class (code, class_name, super_name, protocol_list)
6054 enum tree_code code;
6061 if (code == CLASS_INTERFACE_TYPE)
6063 push_obstacks_nochange ();
6064 end_temporary_allocation ();
6067 if (!doing_objc_thang)
6070 class = make_node (code);
6071 TYPE_BINFO (class) = make_tree_vec (5);
6073 CLASS_NAME (class) = class_name;
6074 CLASS_SUPER_NAME (class) = super_name;
6075 CLASS_CLS_METHODS (class) = NULL_TREE;
6077 if (! is_class_name (class_name) && (decl = lookup_name (class_name)))
6079 error ("`%s' redeclared as different kind of symbol",
6080 IDENTIFIER_POINTER (class_name));
6081 error_with_decl (decl, "previous declaration of `%s'");
6084 if (code == CLASS_IMPLEMENTATION_TYPE)
6087 static tree implemented_classes = 0;
6088 tree chain = implemented_classes;
6089 for (chain = implemented_classes; chain; chain = TREE_CHAIN (chain))
6090 if (TREE_VALUE (chain) == class_name)
6092 error ("reimplementation of class `%s'",
6093 IDENTIFIER_POINTER (class_name));
6094 return error_mark_node;
6096 implemented_classes = perm_tree_cons (NULL_TREE, class_name,
6097 implemented_classes);
6100 /* Pre-build the following entities - for speed/convenience. */
6102 self_id = get_identifier ("self");
6104 ucmd_id = get_identifier ("_cmd");
6107 = build_tree_list (get_identifier ("__unused__"), NULL_TREE);
6108 if (!objc_super_template)
6109 objc_super_template = build_super_template ();
6111 /* Reset for multiple classes per file. */
6114 implementation_context = class;
6116 /* Lookup the interface for this implementation. */
6118 if (!(implementation_template = lookup_interface (class_name)))
6120 warning ("Cannot find interface declaration for `%s'",
6121 IDENTIFIER_POINTER (class_name));
6122 add_class (implementation_template = implementation_context);
6125 /* If a super class has been specified in the implementation,
6126 insure it conforms to the one specified in the interface. */
6129 && (super_name != CLASS_SUPER_NAME (implementation_template)))
6131 tree previous_name = CLASS_SUPER_NAME (implementation_template);
6132 char *name = previous_name ? IDENTIFIER_POINTER (previous_name) : "";
6133 error ("conflicting super class name `%s'",
6134 IDENTIFIER_POINTER (super_name));
6135 error ("previous declaration of `%s'", name);
6138 else if (! super_name)
6140 CLASS_SUPER_NAME (implementation_context)
6141 = CLASS_SUPER_NAME (implementation_template);
6145 else if (code == CLASS_INTERFACE_TYPE)
6147 if (lookup_interface (class_name))
6148 warning ("duplicate interface declaration for class `%s'",
6149 IDENTIFIER_POINTER (class_name));
6154 CLASS_PROTOCOL_LIST (class)
6155 = lookup_and_install_protocols (protocol_list);
6158 else if (code == CATEGORY_INTERFACE_TYPE)
6160 tree class_category_is_assoc_with;
6162 /* For a category, class_name is really the name of the class that
6163 the following set of methods will be associated with. We must
6164 find the interface so that can derive the objects template. */
6166 if (!(class_category_is_assoc_with = lookup_interface (class_name)))
6168 error ("Cannot find interface declaration for `%s'",
6169 IDENTIFIER_POINTER (class_name));
6170 exit (FATAL_EXIT_CODE);
6173 add_category (class_category_is_assoc_with, class);
6176 CLASS_PROTOCOL_LIST (class)
6177 = lookup_and_install_protocols (protocol_list);
6180 else if (code == CATEGORY_IMPLEMENTATION_TYPE)
6182 /* Pre-build the following entities for speed/convenience. */
6184 self_id = get_identifier ("self");
6186 ucmd_id = get_identifier ("_cmd");
6189 = build_tree_list (get_identifier ("__unused__"), NULL_TREE);
6190 if (!objc_super_template)
6191 objc_super_template = build_super_template ();
6193 /* Reset for multiple classes per file. */
6196 implementation_context = class;
6198 /* For a category, class_name is really the name of the class that
6199 the following set of methods will be associated with. We must
6200 find the interface so that can derive the objects template. */
6202 if (!(implementation_template = lookup_interface (class_name)))
6204 error ("Cannot find interface declaration for `%s'",
6205 IDENTIFIER_POINTER (class_name));
6206 exit (FATAL_EXIT_CODE);
6213 continue_class (class)
6216 if (TREE_CODE (class) == CLASS_IMPLEMENTATION_TYPE
6217 || TREE_CODE (class) == CATEGORY_IMPLEMENTATION_TYPE)
6219 struct imp_entry *imp_entry;
6222 /* Check consistency of the instance variables. */
6224 if (CLASS_IVARS (class))
6225 check_ivars (implementation_template, class);
6227 /* code generation */
6229 ivar_context = build_private_template (implementation_template);
6231 if (!objc_class_template)
6232 build_class_template ();
6235 = (struct imp_entry *) xmalloc (sizeof (struct imp_entry))))
6236 perror ("unable to allocate in objc-tree.c");
6238 imp_entry->next = imp_list;
6239 imp_entry->imp_context = class;
6240 imp_entry->imp_template = implementation_template;
6242 synth_forward_declarations ();
6243 imp_entry->class_decl = UOBJC_CLASS_decl;
6244 imp_entry->meta_decl = UOBJC_METACLASS_decl;
6246 /* Append to front and increment count. */
6247 imp_list = imp_entry;
6248 if (TREE_CODE (class) == CLASS_IMPLEMENTATION_TYPE)
6253 return ivar_context;
6256 else if (TREE_CODE (class) == CLASS_INTERFACE_TYPE)
6258 tree record = xref_tag (RECORD_TYPE, CLASS_NAME (class));
6260 if (!TYPE_FIELDS (record))
6262 finish_struct (record, build_ivar_chain (class, 0), NULL_TREE);
6263 CLASS_STATIC_TEMPLATE (class) = record;
6265 /* Mark this record as a class template for static typing. */
6266 TREE_STATIC_TEMPLATE (record) = 1;
6273 return error_mark_node;
6276 /* This is called once we see the "@end" in an interface/implementation. */
6279 finish_class (class)
6282 if (TREE_CODE (class) == CLASS_IMPLEMENTATION_TYPE)
6284 /* All code generation is done in finish_objc. */
6286 if (implementation_template != implementation_context)
6288 /* Ensure that all method listed in the interface contain bodies. */
6289 check_methods (CLASS_CLS_METHODS (implementation_template),
6290 CLASS_CLS_METHODS (implementation_context), '+');
6291 check_methods (CLASS_NST_METHODS (implementation_template),
6292 CLASS_NST_METHODS (implementation_context), '-');
6294 if (CLASS_PROTOCOL_LIST (implementation_template))
6295 check_protocols (CLASS_PROTOCOL_LIST (implementation_template),
6297 IDENTIFIER_POINTER (CLASS_NAME (implementation_context)));
6301 else if (TREE_CODE (class) == CATEGORY_IMPLEMENTATION_TYPE)
6303 tree category = CLASS_CATEGORY_LIST (implementation_template);
6305 /* Find the category interface from the class it is associated with. */
6308 if (CLASS_SUPER_NAME (class) == CLASS_SUPER_NAME (category))
6310 category = CLASS_CATEGORY_LIST (category);
6315 /* Ensure all method listed in the interface contain bodies. */
6316 check_methods (CLASS_CLS_METHODS (category),
6317 CLASS_CLS_METHODS (implementation_context), '+');
6318 check_methods (CLASS_NST_METHODS (category),
6319 CLASS_NST_METHODS (implementation_context), '-');
6321 if (CLASS_PROTOCOL_LIST (category))
6322 check_protocols (CLASS_PROTOCOL_LIST (category),
6324 IDENTIFIER_POINTER (CLASS_SUPER_NAME (implementation_context)));
6328 else if (TREE_CODE (class) == CLASS_INTERFACE_TYPE)
6331 char *class_name = IDENTIFIER_POINTER (CLASS_NAME (class));
6332 char *string = (char *) alloca (strlen (class_name) + 3);
6334 /* extern struct objc_object *_<my_name>; */
6336 sprintf (string, "_%s", class_name);
6338 decl_specs = build_tree_list (NULL_TREE, ridpointers[(int) RID_EXTERN]);
6339 decl_specs = tree_cons (NULL_TREE, objc_object_reference, decl_specs);
6340 define_decl (build1 (INDIRECT_REF, NULL_TREE, get_identifier (string)),
6346 add_protocol (protocol)
6349 /* Put protocol on list in reverse order. */
6350 TREE_CHAIN (protocol) = protocol_chain;
6351 protocol_chain = protocol;
6352 return protocol_chain;
6356 lookup_protocol (ident)
6361 for (chain = protocol_chain; chain; chain = TREE_CHAIN (chain))
6363 if (ident == PROTOCOL_NAME (chain))
6371 start_protocol (code, name, list)
6372 enum tree_code code;
6378 if (!doing_objc_thang)
6381 /* This is as good a place as any. Need to invoke push_tag_toplevel. */
6382 if (!objc_protocol_template)
6383 objc_protocol_template = build_protocol_template ();
6385 protocol = make_node (code);
6386 TYPE_BINFO (protocol) = make_tree_vec (2);
6388 PROTOCOL_NAME (protocol) = name;
6389 PROTOCOL_LIST (protocol) = list;
6391 lookup_and_install_protocols (list);
6393 if (lookup_protocol (name))
6394 warning ("duplicate declaration for protocol `%s'",
6395 IDENTIFIER_POINTER (name));
6397 add_protocol (protocol);
6399 PROTOCOL_FORWARD_DECL (protocol) = NULL_TREE;
6405 finish_protocol (protocol)
6411 /* "Encode" a data type into a string, which grows in util_obstack.
6412 ??? What is the FORMAT? Someone please document this! */
6415 encode_type_qualifiers (declspecs)
6420 for (spec = declspecs; spec; spec = TREE_CHAIN (spec))
6422 if (ridpointers[(int) RID_CONST] == TREE_VALUE (spec))
6423 obstack_1grow (&util_obstack, 'r');
6424 else if (ridpointers[(int) RID_IN] == TREE_VALUE (spec))
6425 obstack_1grow (&util_obstack, 'n');
6426 else if (ridpointers[(int) RID_INOUT] == TREE_VALUE (spec))
6427 obstack_1grow (&util_obstack, 'N');
6428 else if (ridpointers[(int) RID_OUT] == TREE_VALUE (spec))
6429 obstack_1grow (&util_obstack, 'o');
6430 else if (ridpointers[(int) RID_BYCOPY] == TREE_VALUE (spec))
6431 obstack_1grow (&util_obstack, 'O');
6432 else if (ridpointers[(int) RID_ONEWAY] == TREE_VALUE (spec))
6433 obstack_1grow (&util_obstack, 'V');
6437 /* Encode a pointer type. */
6440 encode_pointer (type, curtype, format)
6445 tree pointer_to = TREE_TYPE (type);
6447 if (TREE_CODE (pointer_to) == RECORD_TYPE)
6449 if (TYPE_NAME (pointer_to)
6450 && TREE_CODE (TYPE_NAME (pointer_to)) == IDENTIFIER_NODE)
6452 char *name = IDENTIFIER_POINTER (TYPE_NAME (pointer_to));
6454 if (strcmp (name, TAG_OBJECT) == 0) /* '@' */
6456 obstack_1grow (&util_obstack, '@');
6459 else if (TREE_STATIC_TEMPLATE (pointer_to))
6461 if (generating_instance_variables)
6463 obstack_1grow (&util_obstack, '@');
6464 obstack_1grow (&util_obstack, '"');
6465 obstack_grow (&util_obstack, name, strlen (name));
6466 obstack_1grow (&util_obstack, '"');
6471 obstack_1grow (&util_obstack, '@');
6475 else if (strcmp (name, TAG_CLASS) == 0) /* '#' */
6477 obstack_1grow (&util_obstack, '#');
6480 #ifndef OBJC_INT_SELECTORS
6481 else if (strcmp (name, TAG_SELECTOR) == 0) /* ':' */
6483 obstack_1grow (&util_obstack, ':');
6486 #endif /* OBJC_INT_SELECTORS */
6489 else if (TREE_CODE (pointer_to) == INTEGER_TYPE
6490 && TYPE_MODE (pointer_to) == QImode)
6492 obstack_1grow (&util_obstack, '*');
6496 /* We have a type that does not get special treatment. */
6498 /* NeXT extension */
6499 obstack_1grow (&util_obstack, '^');
6500 encode_type (pointer_to, curtype, format);
6504 encode_array (type, curtype, format)
6509 tree an_int_cst = TYPE_SIZE (type);
6510 tree array_of = TREE_TYPE (type);
6513 /* An incomplete array is treated like a pointer. */
6514 if (an_int_cst == NULL)
6516 encode_pointer (type, curtype, format);
6520 sprintf (buffer, "[%d",
6521 (TREE_INT_CST_LOW (an_int_cst)
6522 / TREE_INT_CST_LOW (TYPE_SIZE (array_of))));
6524 obstack_grow (&util_obstack, buffer, strlen (buffer));
6525 encode_type (array_of, curtype, format);
6526 obstack_1grow (&util_obstack, ']');
6531 encode_aggregate_within (type, curtype, format, left, right)
6538 if (obstack_object_size (&util_obstack) > 0
6539 && *(obstack_next_free (&util_obstack) - 1) == '^')
6541 tree name = TYPE_NAME (type);
6543 /* we have a reference; this is a NeXT extension. */
6545 if (obstack_object_size (&util_obstack) - curtype == 1
6546 && format == OBJC_ENCODE_INLINE_DEFS)
6548 /* Output format of struct for first level only. */
6549 tree fields = TYPE_FIELDS (type);
6551 if (name && TREE_CODE (name) == IDENTIFIER_NODE)
6553 obstack_1grow (&util_obstack, left);
6554 obstack_grow (&util_obstack,
6555 IDENTIFIER_POINTER (name),
6556 strlen (IDENTIFIER_POINTER (name)));
6557 obstack_1grow (&util_obstack, '=');
6561 obstack_1grow (&util_obstack, left);
6562 obstack_grow (&util_obstack, "?=", 2);
6565 for ( ; fields; fields = TREE_CHAIN (fields))
6566 encode_field_decl (fields, curtype, format);
6568 obstack_1grow (&util_obstack, right);
6571 else if (name && TREE_CODE (name) == IDENTIFIER_NODE)
6573 obstack_1grow (&util_obstack, left);
6574 obstack_grow (&util_obstack,
6575 IDENTIFIER_POINTER (name),
6576 strlen (IDENTIFIER_POINTER (name)));
6577 obstack_1grow (&util_obstack, right);
6582 /* We have an untagged structure or a typedef. */
6583 obstack_1grow (&util_obstack, left);
6584 obstack_1grow (&util_obstack, '?');
6585 obstack_1grow (&util_obstack, right);
6591 tree name = TYPE_NAME (type);
6592 tree fields = TYPE_FIELDS (type);
6594 if (format == OBJC_ENCODE_INLINE_DEFS
6595 || generating_instance_variables)
6597 obstack_1grow (&util_obstack, left);
6598 if (name && TREE_CODE (name) == IDENTIFIER_NODE)
6599 obstack_grow (&util_obstack,
6600 IDENTIFIER_POINTER (name),
6601 strlen (IDENTIFIER_POINTER (name)));
6603 obstack_1grow (&util_obstack, '?');
6605 obstack_1grow (&util_obstack, '=');
6607 for (; fields; fields = TREE_CHAIN (fields))
6609 if (generating_instance_variables)
6611 tree fname = DECL_NAME (fields);
6613 obstack_1grow (&util_obstack, '"');
6614 if (fname && TREE_CODE (fname) == IDENTIFIER_NODE)
6616 obstack_grow (&util_obstack,
6617 IDENTIFIER_POINTER (fname),
6618 strlen (IDENTIFIER_POINTER (fname)));
6621 obstack_1grow (&util_obstack, '"');
6624 encode_field_decl (fields, curtype, format);
6627 obstack_1grow (&util_obstack, right);
6632 obstack_1grow (&util_obstack, left);
6633 if (name && TREE_CODE (name) == IDENTIFIER_NODE)
6634 obstack_grow (&util_obstack,
6635 IDENTIFIER_POINTER (name),
6636 strlen (IDENTIFIER_POINTER (name)));
6638 /* We have an untagged structure or a typedef. */
6639 obstack_1grow (&util_obstack, '?');
6641 obstack_1grow (&util_obstack, right);
6647 encode_aggregate (type, curtype, format)
6652 enum tree_code code = TREE_CODE (type);
6658 encode_aggregate_within(type, curtype, format, '{', '}');
6663 encode_aggregate_within(type, curtype, format, '(', ')');
6668 obstack_1grow (&util_obstack, 'i');
6673 /* Support bitfields. The current version of Objective-C does not support
6674 them. The string will consist of one or more "b:n"'s where n is an
6675 integer describing the width of the bitfield. Currently, classes in
6676 the kit implement a method "-(char *)describeBitfieldStruct:" that
6677 simulates this. If they do not implement this method, the archiver
6678 assumes the bitfield is 16 bits wide (padded if necessary) and packed
6679 according to the GNU compiler. After looking at the "kit", it appears
6680 that all classes currently rely on this default behavior, rather than
6681 hand generating this string (which is tedious). */
6684 encode_bitfield (width, format)
6689 sprintf (buffer, "b%d", width);
6690 obstack_grow (&util_obstack, buffer, strlen (buffer));
6693 /* FORMAT will be OBJC_ENCODE_INLINE_DEFS or OBJC_ENCODE_DONT_INLINE_DEFS. */
6696 encode_type (type, curtype, format)
6701 enum tree_code code = TREE_CODE (type);
6703 if (code == INTEGER_TYPE)
6705 if (TREE_INT_CST_LOW (TYPE_MIN_VALUE (type)) == 0
6706 && TREE_INT_CST_HIGH (TYPE_MIN_VALUE (type)) == 0)
6708 /* Unsigned integer types. */
6710 if (TYPE_MODE (type) == QImode)
6711 obstack_1grow (&util_obstack, 'C');
6712 else if (TYPE_MODE (type) == HImode)
6713 obstack_1grow (&util_obstack, 'S');
6714 else if (TYPE_MODE (type) == SImode)
6716 if (type == long_unsigned_type_node)
6717 obstack_1grow (&util_obstack, 'L');
6719 obstack_1grow (&util_obstack, 'I');
6721 else if (TYPE_MODE (type) == DImode)
6722 obstack_1grow (&util_obstack, 'Q');
6726 /* Signed integer types. */
6728 if (TYPE_MODE (type) == QImode)
6729 obstack_1grow (&util_obstack, 'c');
6730 else if (TYPE_MODE (type) == HImode)
6731 obstack_1grow (&util_obstack, 's');
6732 else if (TYPE_MODE (type) == SImode)
6734 if (type == long_integer_type_node)
6735 obstack_1grow (&util_obstack, 'l');
6737 obstack_1grow (&util_obstack, 'i');
6740 else if (TYPE_MODE (type) == DImode)
6741 obstack_1grow (&util_obstack, 'q');
6745 else if (code == REAL_TYPE)
6747 /* Floating point types. */
6749 if (TYPE_MODE (type) == SFmode)
6750 obstack_1grow (&util_obstack, 'f');
6751 else if (TYPE_MODE (type) == DFmode
6752 || TYPE_MODE (type) == TFmode)
6753 obstack_1grow (&util_obstack, 'd');
6756 else if (code == VOID_TYPE)
6757 obstack_1grow (&util_obstack, 'v');
6759 else if (code == ARRAY_TYPE)
6760 encode_array (type, curtype, format);
6762 else if (code == POINTER_TYPE)
6763 encode_pointer (type, curtype, format);
6765 else if (code == RECORD_TYPE || code == UNION_TYPE || code == ENUMERAL_TYPE)
6766 encode_aggregate (type, curtype, format);
6768 else if (code == FUNCTION_TYPE) /* '?' */
6769 obstack_1grow (&util_obstack, '?');
6773 encode_field_decl (field_decl, curtype, format)
6780 /* If this field is obviously a bitfield, or is a bitfield that has been
6781 clobbered to look like a ordinary integer mode, go ahead and generate
6782 the bitfield typing information. */
6783 type = TREE_TYPE (field_decl);
6784 if (DECL_BIT_FIELD (field_decl))
6785 encode_bitfield (DECL_FIELD_SIZE (field_decl), format);
6786 else if (TREE_CODE (TYPE_SIZE (type)) == INTEGER_CST
6787 && DECL_FIELD_SIZE (field_decl)
6788 && TYPE_MODE (type) > DECL_MODE (field_decl))
6789 encode_bitfield (DECL_FIELD_SIZE (field_decl), format);
6791 encode_type (TREE_TYPE (field_decl), curtype, format);
6795 expr_last (complex_expr)
6801 while ((next = TREE_OPERAND (complex_expr, 0)))
6802 complex_expr = next;
6804 return complex_expr;
6807 /* The selector of the current method,
6808 or NULL if we aren't compiling a method. */
6811 maybe_objc_method_name (decl)
6815 return METHOD_SEL_NAME (method_context);
6820 /* Transform a method definition into a function definition as follows:
6821 - synthesize the first two arguments, "self" and "_cmd". */
6824 start_method_def (method)
6829 /* Required to implement _msgSuper. */
6830 method_context = method;
6831 UOBJC_SUPER_decl = NULL_TREE;
6833 /* Must be called BEFORE start_function. */
6836 /* Generate prototype declarations for arguments..."new-style". */
6838 if (TREE_CODE (method_context) == INSTANCE_METHOD_DECL)
6839 decl_specs = build_tree_list (NULL_TREE, uprivate_record);
6841 /* Really a `struct objc_class *'. However, we allow people to
6842 assign to self, which changes its type midstream. */
6843 decl_specs = build_tree_list (NULL_TREE, objc_object_reference);
6845 push_parm_decl (build_tree_list
6846 (build_tree_list (decl_specs,
6847 build1 (INDIRECT_REF, NULL_TREE, self_id)),
6848 build_tree_list (unused_list, NULL_TREE)));
6850 #ifdef OBJC_INT_SELECTORS
6851 decl_specs = build_tree_list (NULL_TREE, ridpointers[(int) RID_UNSIGNED]);
6852 decl_specs = tree_cons (NULL_TREE, ridpointers[(int) RID_INT], decl_specs);
6853 push_parm_decl (build_tree_list (build_tree_list (decl_specs, ucmd_id),
6854 build_tree_list (unused_list, NULL_TREE)));
6855 #else /* not OBJC_INT_SELECTORS */
6856 decl_specs = build_tree_list (NULL_TREE,
6857 xref_tag (RECORD_TYPE,
6858 get_identifier (TAG_SELECTOR)));
6859 push_parm_decl (build_tree_list
6860 (build_tree_list (decl_specs,
6861 build1 (INDIRECT_REF, NULL_TREE, ucmd_id)),
6862 build_tree_list (unused_list, NULL_TREE)));
6863 #endif /* not OBJC_INT_SELECTORS */
6865 /* Generate argument declarations if a keyword_decl. */
6866 if (METHOD_SEL_ARGS (method))
6868 tree arglist = METHOD_SEL_ARGS (method);
6871 tree arg_spec = TREE_PURPOSE (TREE_TYPE (arglist));
6872 tree arg_decl = TREE_VALUE (TREE_TYPE (arglist));
6876 tree last_expr = expr_last (arg_decl);
6878 /* Unite the abstract decl with its name. */
6879 TREE_OPERAND (last_expr, 0) = KEYWORD_ARG_NAME (arglist);
6880 push_parm_decl (build_tree_list
6881 (build_tree_list (arg_spec, arg_decl),
6882 build_tree_list (NULL_TREE, NULL_TREE)));
6884 /* Unhook: restore the abstract declarator. */
6885 TREE_OPERAND (last_expr, 0) = NULL_TREE;
6889 push_parm_decl (build_tree_list
6890 (build_tree_list (arg_spec,
6891 KEYWORD_ARG_NAME (arglist)),
6892 build_tree_list (NULL_TREE, NULL_TREE)));
6894 arglist = TREE_CHAIN (arglist);
6899 if (METHOD_ADD_ARGS (method) > (tree)1)
6901 /* We have a variable length selector - in "prototype" format. */
6902 tree akey = TREE_PURPOSE (METHOD_ADD_ARGS (method));
6905 /* This must be done prior to calling pushdecl. pushdecl is
6906 going to change our chain on us. */
6907 tree nextkey = TREE_CHAIN (akey);
6915 warn_with_method (message, mtype, method)
6920 if (count_error (1) == 0)
6923 report_error_function (DECL_SOURCE_FILE (method));
6925 fprintf (stderr, "%s:%d: warning: ",
6926 DECL_SOURCE_FILE (method), DECL_SOURCE_LINE (method));
6927 bzero (errbuf, BUFSIZE);
6928 fprintf (stderr, "%s `%c%s'\n",
6929 message, mtype, gen_method_decl (method, errbuf));
6932 /* Return 1 if METHOD is consistent with PROTO. */
6935 comp_method_with_proto (method, proto)
6938 static tree function_type = 0;
6940 /* Create a function_type node once. */
6943 push_obstacks_nochange ();
6944 end_temporary_allocation ();
6945 function_type = make_node (FUNCTION_TYPE);
6949 /* Install argument types - normally set by build_function_type. */
6950 TYPE_ARG_TYPES (function_type) = get_arg_type_list (proto, METHOD_DEF, 0);
6952 /* install return type */
6953 TREE_TYPE (function_type) = groktypename (TREE_TYPE (proto));
6955 return comptypes (TREE_TYPE (METHOD_DEFINITION (method)), function_type);
6958 /* Return 1 if PROTO1 is consistent with PROTO2. */
6961 comp_proto_with_proto (proto1, proto2)
6962 tree proto1, proto2;
6964 static tree function_type1 = 0, function_type2 = 0;
6966 /* Create a couple function_type node's once. */
6967 if (!function_type1)
6969 push_obstacks_nochange ();
6970 end_temporary_allocation ();
6971 function_type1 = make_node (FUNCTION_TYPE);
6972 function_type2 = make_node (FUNCTION_TYPE);
6976 /* Install argument types; normally set by build_function_type. */
6977 TYPE_ARG_TYPES (function_type1) = get_arg_type_list (proto1, METHOD_REF, 0);
6978 TYPE_ARG_TYPES (function_type2) = get_arg_type_list (proto2, METHOD_REF, 0);
6980 /* Install return type. */
6981 TREE_TYPE (function_type1) = groktypename (TREE_TYPE (proto1));
6982 TREE_TYPE (function_type2) = groktypename (TREE_TYPE (proto2));
6984 return comptypes (function_type1, function_type2);
6987 /* - Generate an identifier for the function. the format is "_n_cls",
6988 where 1 <= n <= nMethods, and cls is the name the implementation we
6990 - Install the return type from the method declaration.
6991 - If we have a prototype, check for type consistency. */
6994 really_start_method (method, parmlist)
6995 tree method, parmlist;
6997 tree sc_spec, ret_spec, ret_decl, decl_specs;
6998 tree method_decl, method_id;
6999 char *buf, *sel_name, *class_name, *cat_name;
7001 /* Synth the storage class & assemble the return type. */
7002 sc_spec = tree_cons (NULL_TREE, ridpointers[(int) RID_STATIC], NULL_TREE);
7003 ret_spec = TREE_PURPOSE (TREE_TYPE (method));
7004 decl_specs = chainon (sc_spec, ret_spec);
7006 sel_name = IDENTIFIER_POINTER (METHOD_SEL_NAME (method));
7007 class_name = IDENTIFIER_POINTER (CLASS_NAME (implementation_context));
7008 cat_name = ((TREE_CODE (implementation_context)
7009 == CLASS_IMPLEMENTATION_TYPE)
7011 : IDENTIFIER_POINTER (CLASS_SUPER_NAME (implementation_context)));
7014 /* Make sure this is big enough for any plausible method label. */
7015 buf = (char *) alloca (50 + strlen (sel_name) + strlen (class_name)
7016 + (cat_name ? strlen (cat_name) : 0));
7018 OBJC_GEN_METHOD_LABEL (buf, TREE_CODE (method) == INSTANCE_METHOD_DECL,
7019 class_name, cat_name, sel_name, method_slot);
7021 method_id = get_identifier (buf);
7023 method_decl = build_nt (CALL_EXPR, method_id, parmlist, NULL_TREE);
7025 /* Check the declarator portion of the return type for the method. */
7026 if ((ret_decl = TREE_VALUE (TREE_TYPE (method))))
7028 /* Unite the complex decl (specified in the abstract decl) with the
7029 function decl just synthesized..(int *), (int (*)()), (int (*)[]). */
7030 tree save_expr = expr_last (ret_decl);
7032 TREE_OPERAND (save_expr, 0) = method_decl;
7033 method_decl = ret_decl;
7035 /* Fool the parser into thinking it is starting a function. */
7036 start_function (decl_specs, method_decl, NULL_TREE, NULL_TREE, 0);
7038 /* Unhook: this has the effect of restoring the abstract declarator. */
7039 TREE_OPERAND (save_expr, 0) = NULL_TREE;
7044 TREE_VALUE (TREE_TYPE (method)) = method_decl;
7046 /* Fool the parser into thinking it is starting a function. */
7047 start_function (decl_specs, method_decl, NULL_TREE, NULL_TREE, 0);
7049 /* Unhook: this has the effect of restoring the abstract declarator. */
7050 TREE_VALUE (TREE_TYPE (method)) = NULL_TREE;
7053 METHOD_DEFINITION (method) = current_function_decl;
7055 if (implementation_template != implementation_context)
7059 if (TREE_CODE (method) == INSTANCE_METHOD_DECL)
7060 proto = lookup_instance_method_static (implementation_template,
7061 METHOD_SEL_NAME (method));
7063 proto = lookup_class_method_static (implementation_template,
7064 METHOD_SEL_NAME (method));
7066 if (proto && ! comp_method_with_proto (method, proto))
7068 char type = (TREE_CODE (method) == INSTANCE_METHOD_DECL ? '-' : '+');
7070 warn_with_method ("conflicting types for", type, method);
7071 warn_with_method ("previous declaration of", type, proto);
7076 /* The following routine is always called...this "architecture" is to
7077 accommodate "old-style" variable length selectors.
7079 - a:a b:b // prototype ; id c; id d; // old-style. */
7082 continue_method_def ()
7086 if (METHOD_ADD_ARGS (method_context) == (tree)1)
7087 /* We have a `, ...' immediately following the selector. */
7088 parmlist = get_parm_info (0);
7090 parmlist = get_parm_info (1); /* place a `void_at_end' */
7092 /* Set self_decl from the first argument...this global is used by
7093 build_ivar_reference calling build_indirect_ref. */
7094 self_decl = TREE_PURPOSE (parmlist);
7097 really_start_method (method_context, parmlist);
7098 store_parm_decls ();
7101 /* Called by the parser, from the `pushlevel' production. */
7106 if (!UOBJC_SUPER_decl)
7108 UOBJC_SUPER_decl = start_decl (get_identifier (UTAG_SUPER),
7109 build_tree_list (NULL_TREE,
7110 objc_super_template),
7111 0, NULL_TREE, NULL_TREE);
7113 finish_decl (UOBJC_SUPER_decl, NULL_TREE, NULL_TREE);
7115 /* This prevents `unused variable' warnings when compiling with -Wall. */
7116 TREE_USED (UOBJC_SUPER_decl) = 1;
7117 DECL_ARTIFICIAL (UOBJC_SUPER_decl) = 1;
7121 /* _n_Method (id self, SEL sel, ...)
7123 struct objc_super _S;
7124 _msgSuper ((_S.self = self, _S.class = _cls, &_S), ...);
7128 get_super_receiver ()
7132 tree super_expr, super_expr_list;
7134 /* Set receiver to self. */
7135 super_expr = build_component_ref (UOBJC_SUPER_decl, self_id);
7136 super_expr = build_modify_expr (super_expr, NOP_EXPR, self_decl);
7137 super_expr_list = build_tree_list (NULL_TREE, super_expr);
7139 /* Set class to begin searching. */
7140 super_expr = build_component_ref (UOBJC_SUPER_decl,
7141 get_identifier ("class"));
7143 if (TREE_CODE (implementation_context) == CLASS_IMPLEMENTATION_TYPE)
7145 /* [_cls, __cls]Super are "pre-built" in
7146 synth_forward_declarations. */
7148 super_expr = build_modify_expr (super_expr, NOP_EXPR,
7149 ((TREE_CODE (method_context)
7150 == INSTANCE_METHOD_DECL)
7152 : uucls_super_ref));
7156 /* We have a category. */
7158 tree super_name = CLASS_SUPER_NAME (implementation_template);
7163 error ("no super class declared in interface for `%s'",
7164 IDENTIFIER_POINTER (CLASS_NAME (implementation_template)));
7165 return error_mark_node;
7168 if (flag_next_runtime)
7170 super_class = get_class_reference (super_name);
7171 if (TREE_CODE (method_context) == CLASS_METHOD_DECL)
7173 = build_component_ref (build_indirect_ref (super_class, "->"),
7174 get_identifier ("isa"));
7178 add_class_reference (super_name);
7179 super_class = (TREE_CODE (method_context) == INSTANCE_METHOD_DECL
7180 ? objc_get_class_decl : objc_get_meta_class_decl);
7181 assemble_external (super_class);
7183 = build_function_call
7187 my_build_string (IDENTIFIER_LENGTH (super_name) + 1,
7188 IDENTIFIER_POINTER (super_name))));
7191 TREE_TYPE (super_class) = TREE_TYPE (ucls_super_ref);
7192 super_expr = build_modify_expr (super_expr, NOP_EXPR, super_class);
7195 chainon (super_expr_list, build_tree_list (NULL_TREE, super_expr));
7197 super_expr = build_unary_op (ADDR_EXPR, UOBJC_SUPER_decl, 0);
7198 chainon (super_expr_list, build_tree_list (NULL_TREE, super_expr));
7200 return build_compound_expr (super_expr_list);
7204 error ("[super ...] must appear in a method context");
7205 return error_mark_node;
7210 encode_method_def (func_decl)
7215 int max_parm_end = 0;
7220 encode_type (TREE_TYPE (TREE_TYPE (func_decl)),
7221 obstack_object_size (&util_obstack),
7222 OBJC_ENCODE_INLINE_DEFS);
7225 for (parms = DECL_ARGUMENTS (func_decl); parms;
7226 parms = TREE_CHAIN (parms))
7228 int parm_end = (forwarding_offset (parms)
7229 + (TREE_INT_CST_LOW (TYPE_SIZE (TREE_TYPE (parms)))
7232 if (!offset_is_register && parm_end > max_parm_end)
7233 max_parm_end = parm_end;
7236 stack_size = max_parm_end - OBJC_FORWARDING_MIN_OFFSET;
7238 sprintf (buffer, "%d", stack_size);
7239 obstack_grow (&util_obstack, buffer, strlen (buffer));
7241 /* Argument types. */
7242 for (parms = DECL_ARGUMENTS (func_decl); parms;
7243 parms = TREE_CHAIN (parms))
7246 encode_type (TREE_TYPE (parms),
7247 obstack_object_size (&util_obstack),
7248 OBJC_ENCODE_INLINE_DEFS);
7250 /* Compute offset. */
7251 sprintf (buffer, "%d", forwarding_offset (parms));
7253 /* Indicate register. */
7254 if (offset_is_register)
7255 obstack_1grow (&util_obstack, '+');
7257 obstack_grow (&util_obstack, buffer, strlen (buffer));
7260 obstack_1grow (&util_obstack, 0);
7261 result = get_identifier (obstack_finish (&util_obstack));
7262 obstack_free (&util_obstack, util_firstobj);
7267 finish_method_def ()
7269 METHOD_ENCODING (method_context) = encode_method_def (current_function_decl);
7271 finish_function (0);
7273 /* Required to implement _msgSuper. This must be done AFTER finish_function,
7274 since the optimizer may find "may be used before set" errors. */
7275 method_context = NULL_TREE;
7280 lang_report_error_function (decl)
7285 fprintf (stderr, "In method `%s'\n",
7286 IDENTIFIER_POINTER (METHOD_SEL_NAME (method_context)));
7296 is_complex_decl (type)
7299 return (TREE_CODE (type) == ARRAY_TYPE
7300 || TREE_CODE (type) == FUNCTION_TYPE
7301 || (TREE_CODE (type) == POINTER_TYPE && ! IS_ID (type)));
7305 /* Code to convert a decl node into text for a declaration in C. */
7307 static char tmpbuf[256];
7310 adorn_decl (decl, str)
7314 enum tree_code code = TREE_CODE (decl);
7316 if (code == ARRAY_REF)
7318 tree an_int_cst = TREE_OPERAND (decl, 1);
7320 if (an_int_cst && TREE_CODE (an_int_cst) == INTEGER_CST)
7321 sprintf (str + strlen (str), "[%d]", TREE_INT_CST_LOW (an_int_cst));
7326 else if (code == ARRAY_TYPE)
7328 tree an_int_cst = TYPE_SIZE (decl);
7329 tree array_of = TREE_TYPE (decl);
7331 if (an_int_cst && TREE_CODE (an_int_cst) == INTEGER_TYPE)
7332 sprintf (str + strlen (str), "[%d]",
7333 (TREE_INT_CST_LOW (an_int_cst)
7334 / TREE_INT_CST_LOW (TYPE_SIZE (array_of))));
7339 else if (code == CALL_EXPR)
7341 tree chain = TREE_PURPOSE (TREE_OPERAND (decl, 1));
7346 gen_declaration (chain, str);
7347 chain = TREE_CHAIN (chain);
7354 else if (code == FUNCTION_TYPE)
7356 tree chain = TYPE_ARG_TYPES (decl);
7359 while (chain && TREE_VALUE (chain) != void_type_node)
7361 gen_declaration (TREE_VALUE (chain), str);
7362 chain = TREE_CHAIN (chain);
7363 if (chain && TREE_VALUE (chain) != void_type_node)
7369 else if (code == INDIRECT_REF)
7371 strcpy (tmpbuf, "*");
7372 if (TREE_TYPE (decl) && TREE_CODE (TREE_TYPE (decl)) == TREE_LIST)
7376 for (chain = nreverse (copy_list (TREE_TYPE (decl)));
7378 chain = TREE_CHAIN (chain))
7380 if (TREE_CODE (TREE_VALUE (chain)) == IDENTIFIER_NODE)
7382 strcat (tmpbuf, " ");
7383 strcat (tmpbuf, IDENTIFIER_POINTER (TREE_VALUE (chain)));
7387 strcat (tmpbuf, " ");
7389 strcat (tmpbuf, str);
7390 strcpy (str, tmpbuf);
7393 else if (code == POINTER_TYPE)
7395 strcpy (tmpbuf, "*");
7396 if (TREE_READONLY (decl) || TYPE_VOLATILE (decl))
7398 if (TREE_READONLY (decl))
7399 strcat (tmpbuf, " const");
7400 if (TYPE_VOLATILE (decl))
7401 strcat (tmpbuf, " volatile");
7403 strcat (tmpbuf, " ");
7405 strcat (tmpbuf, str);
7406 strcpy (str, tmpbuf);
7411 gen_declarator (decl, buf, name)
7418 enum tree_code code = TREE_CODE (decl);
7428 op = TREE_OPERAND (decl, 0);
7430 /* We have a pointer to a function or array...(*)(), (*)[] */
7431 if ((code == ARRAY_REF || code == CALL_EXPR)
7432 && op && TREE_CODE (op) == INDIRECT_REF)
7435 str = gen_declarator (op, buf, name);
7439 strcpy (tmpbuf, "(");
7440 strcat (tmpbuf, str);
7441 strcat (tmpbuf, ")");
7442 strcpy (str, tmpbuf);
7445 adorn_decl (decl, str);
7454 /* This clause is done iteratively rather than recursively. */
7457 op = (is_complex_decl (TREE_TYPE (decl))
7458 ? TREE_TYPE (decl) : NULL_TREE);
7460 adorn_decl (decl, str);
7462 /* We have a pointer to a function or array...(*)(), (*)[] */
7463 if (code == POINTER_TYPE
7464 && op && (TREE_CODE (op) == FUNCTION_TYPE
7465 || TREE_CODE (op) == ARRAY_TYPE))
7467 strcpy (tmpbuf, "(");
7468 strcat (tmpbuf, str);
7469 strcat (tmpbuf, ")");
7470 strcpy (str, tmpbuf);
7473 decl = (is_complex_decl (TREE_TYPE (decl))
7474 ? TREE_TYPE (decl) : NULL_TREE);
7477 while (decl && (code = TREE_CODE (decl)))
7482 case IDENTIFIER_NODE:
7483 /* Will only happen if we are processing a "raw" expr-decl. */
7484 strcpy (buf, IDENTIFIER_POINTER (decl));
7492 /* We have an abstract declarator or a _DECL node. */
7500 gen_declspecs (declspecs, buf, raw)
7509 for (chain = nreverse (copy_list (declspecs));
7510 chain; chain = TREE_CHAIN (chain))
7512 tree aspec = TREE_VALUE (chain);
7514 if (TREE_CODE (aspec) == IDENTIFIER_NODE)
7515 strcat (buf, IDENTIFIER_POINTER (aspec));
7516 else if (TREE_CODE (aspec) == RECORD_TYPE)
7518 if (TYPE_NAME (aspec))
7520 tree protocol_list = TYPE_PROTOCOL_LIST (aspec);
7522 if (! TREE_STATIC_TEMPLATE (aspec))
7523 strcat (buf, "struct ");
7524 strcat (buf, IDENTIFIER_POINTER (TYPE_NAME (aspec)));
7529 tree chain = protocol_list;
7536 (PROTOCOL_NAME (TREE_VALUE (chain))));
7537 chain = TREE_CHAIN (chain);
7546 strcat (buf, "untagged struct");
7549 else if (TREE_CODE (aspec) == UNION_TYPE)
7551 if (TYPE_NAME (aspec))
7553 if (! TREE_STATIC_TEMPLATE (aspec))
7554 strcat (buf, "union ");
7555 strcat (buf, IDENTIFIER_POINTER (TYPE_NAME (aspec)));
7558 strcat (buf, "untagged union");
7561 else if (TREE_CODE (aspec) == ENUMERAL_TYPE)
7563 if (TYPE_NAME (aspec))
7565 if (! TREE_STATIC_TEMPLATE (aspec))
7566 strcat (buf, "enum ");
7567 strcat (buf, IDENTIFIER_POINTER (TYPE_NAME (aspec)));
7570 strcat (buf, "untagged enum");
7573 else if (TREE_CODE (aspec) == TYPE_DECL && DECL_NAME (aspec))
7574 strcat (buf, IDENTIFIER_POINTER (DECL_NAME (aspec)));
7576 else if (IS_ID (aspec))
7578 tree protocol_list = TYPE_PROTOCOL_LIST (aspec);
7583 tree chain = protocol_list;
7590 (PROTOCOL_NAME (TREE_VALUE (chain))));
7591 chain = TREE_CHAIN (chain);
7598 if (TREE_CHAIN (chain))
7604 /* Type qualifiers. */
7605 if (TREE_READONLY (declspecs))
7606 strcat (buf, "const ");
7607 if (TYPE_VOLATILE (declspecs))
7608 strcat (buf, "volatile ");
7610 switch (TREE_CODE (declspecs))
7612 /* Type specifiers. */
7615 declspecs = TYPE_MAIN_VARIANT (declspecs);
7617 /* Signed integer types. */
7619 if (declspecs == short_integer_type_node)
7620 strcat (buf, "short int ");
7621 else if (declspecs == integer_type_node)
7622 strcat (buf, "int ");
7623 else if (declspecs == long_integer_type_node)
7624 strcat (buf, "long int ");
7625 else if (declspecs == long_long_integer_type_node)
7626 strcat (buf, "long long int ");
7627 else if (declspecs == signed_char_type_node
7628 || declspecs == char_type_node)
7629 strcat (buf, "char ");
7631 /* Unsigned integer types. */
7633 else if (declspecs == short_unsigned_type_node)
7634 strcat (buf, "unsigned short ");
7635 else if (declspecs == unsigned_type_node)
7636 strcat (buf, "unsigned int ");
7637 else if (declspecs == long_unsigned_type_node)
7638 strcat (buf, "unsigned long ");
7639 else if (declspecs == long_long_unsigned_type_node)
7640 strcat (buf, "unsigned long long ");
7641 else if (declspecs == unsigned_char_type_node)
7642 strcat (buf, "unsigned char ");
7646 declspecs = TYPE_MAIN_VARIANT (declspecs);
7648 if (declspecs == float_type_node)
7649 strcat (buf, "float ");
7650 else if (declspecs == double_type_node)
7651 strcat (buf, "double ");
7652 else if (declspecs == long_double_type_node)
7653 strcat (buf, "long double ");
7657 if (TYPE_NAME (declspecs)
7658 && TREE_CODE (TYPE_NAME (declspecs)) == IDENTIFIER_NODE)
7660 tree protocol_list = TYPE_PROTOCOL_LIST (declspecs);
7662 if (! TREE_STATIC_TEMPLATE (declspecs))
7663 strcat (buf, "struct ");
7664 strcat (buf, IDENTIFIER_POINTER (TYPE_NAME (declspecs)));
7668 tree chain = protocol_list;
7675 (PROTOCOL_NAME (TREE_VALUE (chain))));
7676 chain = TREE_CHAIN (chain);
7685 strcat (buf, "untagged struct");
7691 if (TYPE_NAME (declspecs)
7692 && TREE_CODE (TYPE_NAME (declspecs)) == IDENTIFIER_NODE)
7694 strcat (buf, "union ");
7695 strcat (buf, IDENTIFIER_POINTER (TYPE_NAME (declspecs)));
7700 strcat (buf, "untagged union ");
7704 if (TYPE_NAME (declspecs)
7705 && TREE_CODE (TYPE_NAME (declspecs)) == IDENTIFIER_NODE)
7707 strcat (buf, "enum ");
7708 strcat (buf, IDENTIFIER_POINTER (TYPE_NAME (declspecs)));
7713 strcat (buf, "untagged enum ");
7717 strcat (buf, "void ");
7722 tree protocol_list = TYPE_PROTOCOL_LIST (declspecs);
7727 tree chain = protocol_list;
7734 (PROTOCOL_NAME (TREE_VALUE (chain))));
7735 chain = TREE_CHAIN (chain);
7748 gen_declaration (atype_or_adecl, buf)
7749 tree atype_or_adecl;
7754 if (TREE_CODE (atype_or_adecl) == TREE_LIST)
7756 tree declspecs; /* "identifier_node", "record_type" */
7757 tree declarator; /* "array_ref", "indirect_ref", "call_expr"... */
7759 /* We have a "raw", abstract declarator (typename). */
7760 declarator = TREE_VALUE (atype_or_adecl);
7761 declspecs = TREE_PURPOSE (atype_or_adecl);
7763 gen_declspecs (declspecs, buf, 1);
7767 strcat (buf, gen_declarator (declarator, declbuf, ""));
7774 tree declspecs; /* "integer_type", "real_type", "record_type"... */
7775 tree declarator; /* "array_type", "function_type", "pointer_type". */
7777 if (TREE_CODE (atype_or_adecl) == FIELD_DECL
7778 || TREE_CODE (atype_or_adecl) == PARM_DECL
7779 || TREE_CODE (atype_or_adecl) == FUNCTION_DECL)
7780 atype = TREE_TYPE (atype_or_adecl);
7782 /* Assume we have a *_type node. */
7783 atype = atype_or_adecl;
7785 if (is_complex_decl (atype))
7789 /* Get the declaration specifier; it is at the end of the list. */
7790 declarator = chain = atype;
7792 chain = TREE_TYPE (chain); /* not TREE_CHAIN (chain); */
7793 while (is_complex_decl (chain));
7800 declarator = NULL_TREE;
7803 gen_declspecs (declspecs, buf, 0);
7805 if (TREE_CODE (atype_or_adecl) == FIELD_DECL
7806 || TREE_CODE (atype_or_adecl) == PARM_DECL
7807 || TREE_CODE (atype_or_adecl) == FUNCTION_DECL)
7809 char *decl_name = (DECL_NAME (atype_or_adecl)
7810 ? IDENTIFIER_POINTER (DECL_NAME (atype_or_adecl))
7816 strcat (buf, gen_declarator (declarator, declbuf, decl_name));
7819 else if (decl_name[0])
7822 strcat (buf, decl_name);
7825 else if (declarator)
7828 strcat (buf, gen_declarator (declarator, declbuf, ""));
7835 #define RAW_TYPESPEC(meth) (TREE_VALUE (TREE_PURPOSE (TREE_TYPE (meth))))
7838 gen_method_decl (method, buf)
7844 if (RAW_TYPESPEC (method) != objc_object_reference)
7847 gen_declaration (TREE_TYPE (method), buf);
7851 chain = METHOD_SEL_ARGS (method);
7854 /* We have a chain of keyword_decls. */
7857 if (KEYWORD_KEY_NAME (chain))
7858 strcat (buf, IDENTIFIER_POINTER (KEYWORD_KEY_NAME (chain)));
7861 if (RAW_TYPESPEC (chain) != objc_object_reference)
7864 gen_declaration (TREE_TYPE (chain), buf);
7868 strcat (buf, IDENTIFIER_POINTER (KEYWORD_ARG_NAME (chain)));
7869 if ((chain = TREE_CHAIN (chain)))
7874 if (METHOD_ADD_ARGS (method) == (tree)1)
7875 strcat (buf, ", ...");
7876 else if (METHOD_ADD_ARGS (method))
7878 /* We have a tree list node as generate by get_parm_info. */
7879 chain = TREE_PURPOSE (METHOD_ADD_ARGS (method));
7881 /* Know we have a chain of parm_decls. */
7885 gen_declaration (chain, buf);
7886 chain = TREE_CHAIN (chain);
7892 /* We have a unary selector. */
7893 strcat (buf, IDENTIFIER_POINTER (METHOD_SEL_NAME (method)));
7901 dump_interface (fp, chain)
7905 char *buf = (char *)xmalloc (256);
7906 char *my_name = IDENTIFIER_POINTER (CLASS_NAME (chain));
7907 tree ivar_decls = CLASS_RAW_IVARS (chain);
7908 tree nst_methods = CLASS_NST_METHODS (chain);
7909 tree cls_methods = CLASS_CLS_METHODS (chain);
7911 fprintf (fp, "\n@interface %s", my_name);
7913 if (CLASS_SUPER_NAME (chain))
7915 char *super_name = IDENTIFIER_POINTER (CLASS_SUPER_NAME (chain));
7916 fprintf (fp, " : %s\n", super_name);
7923 fprintf (fp, "{\n");
7927 fprintf (fp, "\t%s;\n", gen_declaration (ivar_decls, buf));
7928 ivar_decls = TREE_CHAIN (ivar_decls);
7931 fprintf (fp, "}\n");
7937 fprintf (fp, "- %s;\n", gen_method_decl (nst_methods, buf));
7938 nst_methods = TREE_CHAIN (nst_methods);
7944 fprintf (fp, "+ %s;\n", gen_method_decl (cls_methods, buf));
7945 cls_methods = TREE_CHAIN (cls_methods);
7947 fprintf (fp, "\n@end");
7950 /* Demangle function for Objective-C */
7952 objc_demangle (mangled)
7953 const char *mangled;
7955 char *demangled, *cp;
7957 if (mangled[0] == '_' &&
7958 (mangled[1] == 'i' || mangled[1] == 'c') &&
7961 cp = demangled = xmalloc(strlen(mangled) + 2);
7962 if (mangled[1] == 'i')
7963 *cp++ = '-'; /* for instance method */
7965 *cp++ = '+'; /* for class method */
7966 *cp++ = '['; /* opening left brace */
7967 strcpy(cp, mangled+3); /* tack on the rest of the mangled name */
7968 while (*cp && *cp == '_')
7969 cp++; /* skip any initial underbars in class name */
7970 cp = strchr(cp, '_'); /* find first non-initial underbar */
7973 free(demangled); /* not mangled name */
7976 if (cp[1] == '_') /* easy case: no category name */
7978 *cp++ = ' '; /* replace two '_' with one ' ' */
7979 strcpy(cp, mangled + (cp - demangled) + 2);
7983 *cp++ = '('; /* less easy case: category name */
7984 cp = strchr(cp, '_');
7987 free(demangled); /* not mangled name */
7991 *cp++ = ' '; /* overwriting 1st char of method name... */
7992 strcpy(cp, mangled + (cp - demangled)); /* get it back */
7994 while (*cp && *cp == '_')
7995 cp++; /* skip any initial underbars in method name */
7998 *cp = ':'; /* replace remaining '_' with ':' */
7999 *cp++ = ']'; /* closing right brace */
8000 *cp++ = 0; /* string terminator */
8004 return mangled; /* not an objc mangled name */
8008 objc_printable_name (decl, kind)
8012 return objc_demangle (IDENTIFIER_POINTER (DECL_NAME (decl)));
8018 /* Add the special tree codes of Objective C to the tables. */
8020 #define LAST_CODE LAST_AND_UNUSED_TREE_CODE
8022 gcc_obstack_init (&util_obstack);
8023 util_firstobj = (char *) obstack_finish (&util_obstack);
8025 bcopy (objc_tree_code_type,
8026 tree_code_type + (int) LAST_CODE,
8027 (int) LAST_OBJC_TREE_CODE - (int) LAST_CODE);
8028 bcopy ((char *) objc_tree_code_length,
8029 (char *) (tree_code_length + (int) LAST_CODE),
8030 (((int) LAST_OBJC_TREE_CODE - (int) LAST_CODE)
8032 bcopy ((char *) objc_tree_code_name,
8033 (char *) (tree_code_name + (int) LAST_CODE),
8034 (((int) LAST_OBJC_TREE_CODE - (int) LAST_CODE)
8035 * sizeof (char *)));
8037 errbuf = (char *)xmalloc (BUFSIZE);
8039 synth_module_prologue ();
8041 /* Change the default error function */
8042 decl_printable_name = (char* (*)()) objc_printable_name;
8048 struct imp_entry *impent;
8050 /* The internally generated initializers appear to have missing braces.
8051 Don't warn about this. */
8052 int save_warn_missing_braces = warn_missing_braces;
8053 warn_missing_braces = 0;
8055 generate_forward_declaration_to_string_table ();
8057 #ifdef OBJC_PROLOGUE
8061 /* Process the static instances here because initialization of objc_symtab
8063 if (objc_static_instances)
8064 generate_static_references ();
8066 if (implementation_context || class_names_chain
8067 || meth_var_names_chain || meth_var_types_chain || sel_ref_chain)
8068 generate_objc_symtab_decl ();
8070 for (impent = imp_list; impent; impent = impent->next)
8072 implementation_context = impent->imp_context;
8073 implementation_template = impent->imp_template;
8075 UOBJC_CLASS_decl = impent->class_decl;
8076 UOBJC_METACLASS_decl = impent->meta_decl;
8078 if (TREE_CODE (implementation_context) == CLASS_IMPLEMENTATION_TYPE)
8080 /* all of the following reference the string pool... */
8081 generate_ivar_lists ();
8082 generate_dispatch_tables ();
8083 generate_shared_structures ();
8087 generate_dispatch_tables ();
8088 generate_category (implementation_context);
8092 /* If we are using an array of selectors, we must always
8093 finish up the array decl even if no selectors were used. */
8094 if (! flag_next_runtime || sel_ref_chain)
8095 build_selector_translation_table ();
8098 generate_protocols ();
8100 if (implementation_context || class_names_chain || objc_static_instances
8101 || meth_var_names_chain || meth_var_types_chain || sel_ref_chain)
8103 /* Arrange for Objc data structures to be initialized at run time. */
8104 char *init_name = build_module_descriptor ();
8106 assemble_constructor (init_name);
8109 /* Dump the class references. This forces the appropriate classes
8110 to be linked into the executable image, preserving unix archive
8111 semantics. This can be removed when we move to a more dynamically
8112 linked environment. */
8114 for (chain = cls_ref_chain; chain; chain = TREE_CHAIN (chain))
8116 handle_class_ref (chain);
8117 if (TREE_PURPOSE (chain))
8118 generate_classref_translation_entry (chain);
8121 for (impent = imp_list; impent; impent = impent->next)
8122 handle_impent (impent);
8124 /* Dump the string table last. */
8126 generate_strings ();
8128 if (flag_gen_declaration)
8130 add_class (implementation_context);
8131 dump_interface (gen_declaration_file, implementation_context);
8139 /* Run through the selector hash tables and print a warning for any
8140 selector which has multiple methods. */
8142 for (slot = 0; slot < SIZEHASHTABLE; slot++)
8143 for (hsh = cls_method_hash_list[slot]; hsh; hsh = hsh->next)
8146 tree meth = hsh->key;
8147 char type = (TREE_CODE (meth) == INSTANCE_METHOD_DECL
8151 warning ("potential selector conflict for method `%s'",
8152 IDENTIFIER_POINTER (METHOD_SEL_NAME (meth)));
8153 warn_with_method ("found", type, meth);
8154 for (loop = hsh->list; loop; loop = loop->next)
8155 warn_with_method ("found", type, loop->value);
8158 for (slot = 0; slot < SIZEHASHTABLE; slot++)
8159 for (hsh = nst_method_hash_list[slot]; hsh; hsh = hsh->next)
8162 tree meth = hsh->key;
8163 char type = (TREE_CODE (meth) == INSTANCE_METHOD_DECL
8167 warning ("potential selector conflict for method `%s'",
8168 IDENTIFIER_POINTER (METHOD_SEL_NAME (meth)));
8169 warn_with_method ("found", type, meth);
8170 for (loop = hsh->list; loop; loop = loop->next)
8171 warn_with_method ("found", type, loop->value);
8175 warn_missing_braces = save_warn_missing_braces;
8178 /* Subroutines of finish_objc. */
8181 generate_classref_translation_entry (chain)
8184 tree expr, name, decl_specs, decl, sc_spec;
8187 type = TREE_TYPE (TREE_PURPOSE (chain));
8189 expr = add_objc_string (TREE_VALUE (chain), class_names);
8190 expr = build_c_cast (type, expr); /* cast! */
8192 name = DECL_NAME (TREE_PURPOSE (chain));
8194 sc_spec = build_tree_list (NULL_TREE, ridpointers[(int) RID_STATIC]);
8196 /* static struct objc_class * _OBJC_CLASS_REFERENCES_n = ...; */
8197 decl_specs = tree_cons (NULL_TREE, type, sc_spec);
8199 /* The decl that is returned from start_decl is the one that we
8200 forward declared in build_class_reference. */
8201 decl = start_decl (name, decl_specs, 1, NULL_TREE, NULL_TREE);
8202 finish_decl (decl, expr, NULL_TREE);
8207 handle_class_ref (chain)
8210 char *name = IDENTIFIER_POINTER (TREE_VALUE (chain));
8211 if (! flag_next_runtime)
8214 char *string = (char *) alloca (strlen (name) + 30);
8217 sprintf (string, "%sobjc_class_name_%s",
8218 (flag_next_runtime ? "." : "__"), name);
8220 /* Make a decl for this name, so we can use its address in a tree. */
8221 decl = build_decl (VAR_DECL, get_identifier (string), char_type_node);
8222 DECL_EXTERNAL (decl) = 1;
8223 TREE_PUBLIC (decl) = 1;
8226 rest_of_decl_compilation (decl, 0, 0, 0);
8228 /* Make following constant read-only (why not)? */
8229 readonly_data_section ();
8231 exp = build1 (ADDR_EXPR, string_type_node, decl);
8233 /* Align the section properly. */
8234 assemble_constant_align (exp);
8236 /* Inform the assembler about this new external thing. */
8237 assemble_external (decl);
8239 /* Output a constant to reference this address. */
8240 output_constant (exp, int_size_in_bytes (string_type_node));
8244 /* This overreliance on our assembler (i.e. lack of portability)
8245 should be dealt with at some point. The GNU strategy (above)
8246 won't work either, but it is a start. */
8247 char *string = (char *) alloca (strlen (name) + 30);
8248 sprintf (string, ".reference .objc_class_name_%s", name);
8249 assemble_asm (my_build_string (strlen (string) + 1, string));
8254 handle_impent (impent)
8255 struct imp_entry *impent;
8257 implementation_context = impent->imp_context;
8258 implementation_template = impent->imp_template;
8260 if (TREE_CODE (impent->imp_context) == CLASS_IMPLEMENTATION_TYPE)
8262 char *class_name = IDENTIFIER_POINTER (CLASS_NAME (impent->imp_context));
8263 char *string = (char *) alloca (strlen (class_name) + 30);
8265 if (flag_next_runtime)
8267 /* Grossly unportable.
8268 People should know better than to assume
8269 such things about assembler syntax! */
8270 sprintf (string, ".objc_class_name_%s=0", class_name);
8271 assemble_asm (my_build_string (strlen (string) + 1, string));
8273 sprintf (string, ".globl .objc_class_name_%s", class_name);
8274 assemble_asm (my_build_string (strlen (string) + 1, string));
8279 sprintf (string, "%sobjc_class_name_%s",
8280 (flag_next_runtime ? "." : "__"), class_name);
8281 assemble_global (string);
8282 assemble_label (string);
8286 else if (TREE_CODE (impent->imp_context) == CATEGORY_IMPLEMENTATION_TYPE)
8288 char *class_name = IDENTIFIER_POINTER (CLASS_NAME (impent->imp_context));
8289 char *class_super_name
8290 = IDENTIFIER_POINTER (CLASS_SUPER_NAME (impent->imp_context));
8291 char *string = (char *) alloca (strlen (class_name)
8292 + strlen (class_super_name) + 30);
8294 /* Do the same for categories. Even though no references to these
8295 symbols are generated automatically by the compiler, it gives
8296 you a handle to pull them into an archive by hand. */
8297 if (flag_next_runtime)
8299 /* Grossly unportable. */
8300 sprintf (string, ".objc_category_name_%s_%s=0",
8301 class_name, class_super_name);
8302 assemble_asm (my_build_string (strlen (string) + 1, string));
8304 sprintf (string, ".globl .objc_category_name_%s_%s",
8305 class_name, class_super_name);
8306 assemble_asm (my_build_string (strlen (string) + 1, string));
8311 sprintf (string, "%sobjc_category_name_%s_%s",
8312 (flag_next_runtime ? "." : "__"),
8313 class_name, class_super_name);
8314 assemble_global (string);
8315 assemble_label (string);
8326 char *buf = (char *)xmalloc (256);
8328 { /* dump function prototypes */
8329 tree loop = UOBJC_MODULES_decl;
8331 fprintf (fp, "\n\nfunction prototypes:\n");
8334 if (TREE_CODE (loop) == FUNCTION_DECL && DECL_INITIAL (loop))
8336 /* We have a function definition: generate prototype. */
8337 bzero (errbuf, BUFSIZE);
8338 gen_declaration (loop, errbuf);
8339 fprintf (fp, "%s;\n", errbuf);
8341 loop = TREE_CHAIN (loop);
8345 /* Dump global chains. */
8347 int i, index = 0, offset = 0;
8350 for (i = 0; i < SIZEHASHTABLE; i++)
8352 if (hashlist = nst_method_hash_list[i])
8354 fprintf (fp, "\n\nnst_method_hash_list[%d]:\n", i);
8358 fprintf (fp, "-%s;\n", gen_method_decl (hashlist->key, buf));
8359 hashlist = hashlist->next;
8365 for (i = 0; i < SIZEHASHTABLE; i++)
8367 if (hashlist = cls_method_hash_list[i])
8369 fprintf (fp, "\n\ncls_method_hash_list[%d]:\n", i);
8373 fprintf (fp, "-%s;\n", gen_method_decl (hashlist->key, buf));
8374 hashlist = hashlist->next;
8380 fprintf (fp, "\nsel_refdef_chain:\n");
8381 for (loop = sel_refdef_chain; loop; loop = TREE_CHAIN (loop))
8383 fprintf (fp, "(index: %4d offset: %4d) %s\n", index, offset,
8384 IDENTIFIER_POINTER (TREE_VALUE (loop)));
8386 /* add one for the '\0' character */
8387 offset += IDENTIFIER_LENGTH (TREE_VALUE (loop)) + 1;
8390 fprintf (fp, "\n (max_selector_index: %4d.\n", max_selector_index);
8396 print_lang_statistics ()